[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xine-cvslog
Subject:    [xine-cvs] =?utf-8?q?HG=3A_xine-lib-1=2E2=3A_xshm=3A_crop_support?=
From:       Torsten_Jager <t.jager () gmx ! de>
Date:       2012-07-03 19:25:49
Message-ID: b90a2a38df74fa8c5cac.1341343058 () hg ! debian ! org
[Download RAW message or body]

# HG changeset patch
# User Torsten Jager <t.jager@gmx.de>
# Date 1341343058 -10800
# Node ID b90a2a38df74fa8c5cacf30afa857e8cf783550b
# Branch  default
# Parent  9cdf07f4b49b55a04208be747f021f7df5b2ac28
xshm: crop support

diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c
--- a/src/video_out/video_out_xshm.c
+++ b/src/video_out/video_out_xshm.c
@@ -23,6 +23,8 @@
  * Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
  *
  * xine-specific code by Guenter Bartsch <bartscgr@studbox.uni-stuttgart.de>
+ *
+ * crop support added by Torsten Jager <t.jager@gmx.de>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -67,6 +69,7 @@
 #include <xine/xineutils.h>
 #include <xine/vo_scale.h>
 #include "x11osd.h"
+#include "xine_mmx.h"
 
 #define LOCK_DISPLAY(this) {if(this->lock_display) \
this->lock_display(this->user_data); \  else XLockDisplay(this->display);}
@@ -88,8 +91,15 @@
   yuv2rgb_t         *yuv2rgb; /* yuv2rgb converter set up for this frame */
   uint8_t           *rgb_dst;
 
+  int                state, offs0, offs1; /* crop helpers */
+  uint8_t            *crop_start, *crop_flush, *crop_stop;
 } xshm_frame_t;
 
+/* frame.state */
+#define FS_DONE  1
+#define FS_LATE  2
+#define FS_FLAGS 4
+
 typedef struct {
 
   vo_driver_t        vo_driver;
@@ -317,7 +327,8 @@
 
 static uint32_t xshm_get_capabilities (vo_driver_t *this_gen) {
   xshm_driver_t *this = (xshm_driver_t *) this_gen;
-  uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS | \
VO_CAP_CONTRAST | VO_CAP_SATURATION; +  uint32_t capabilities = VO_CAP_CROP | \
VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS +    | VO_CAP_CONTRAST | \
VO_CAP_SATURATION;  
   if( this->xoverlay )
     capabilities |= VO_CAP_UNSCALED_OVERLAY;
@@ -370,29 +381,175 @@
   frame->yuv2rgb->next_slice (frame->yuv2rgb, NULL);
 }
 
+static void xshm_frame_proc_setup (vo_frame_t *vo_img) {
+  xshm_frame_t  *frame = (xshm_frame_t *) vo_img ;
+  xshm_driver_t *this = (xshm_driver_t *) vo_img->driver;
+  int changed = 0, i;
+  int width, height, gui_width, gui_height;
+  double gui_pixel_aspect;
+
+  /* Aargh... libmpeg2 decoder calls frame->proc_slice directly, preferredly
+    while still in mmx mode. This will trash our floating point aspect ratio
+    calculations below. Switching back once per frame should not harm
+    performance too much. */
+#ifdef HAVE_MMX
+  emms ();
+#endif
+
+  if (!(frame->state & FS_LATE)) {
+    /* adjust cropping to what yuv2rgb can handle */
+    if (vo_img->format == XINE_IMGFMT_YV12) {
+      vo_img->crop_left &= ~7;
+      vo_img->crop_top &= ~1;
+    } else {
+      vo_img->crop_left &= ~3;
+    }
+    /* check for crop changes */
+    if ((vo_img->crop_left != frame->sc.crop_left)
+      || (vo_img->crop_top != frame->sc.crop_top)
+      || (vo_img->crop_right != frame->sc.crop_right)
+      || (vo_img->crop_bottom != frame->sc.crop_bottom)) {
+      frame->sc.crop_left = vo_img->crop_left;
+      frame->sc.crop_top = vo_img->crop_top;
+      frame->sc.crop_right = vo_img->crop_right;
+      frame->sc.crop_bottom = vo_img->crop_bottom;
+      changed = 1;
+    }
+  }
+
+  if (!(frame->state & FS_DONE))
+    changed = 1;
+
+  /* just deal with cropped part */
+  width  = frame->sc.delivered_width - frame->sc.crop_left - frame->sc.crop_right;
+  height = frame->sc.delivered_height - frame->sc.crop_top - frame->sc.crop_bottom;
+
+  if (frame->sc.delivered_ratio == 0.0) {
+    frame->sc.delivered_ratio = height ? (double)width / (double)height : 1.0;
+    changed = 1;
+  }
+  
+  /* ask gui what output size we'll have for this frame */
+  /* get the gui_pixel_aspect before calling xshm_compute_ideal_size() */
+  /* note: gui_width and gui_height may be bogus because we may have not yet */
+  /*       updated video_pixel_aspect (see _x_vo_scale_compute_ideal_size).  */
+  frame->sc.dest_size_cb (frame->sc.user_data, width, height,
+    frame->sc.video_pixel_aspect, &gui_width, &gui_height, &gui_pixel_aspect);
+
+  if (changed || (gui_pixel_aspect != frame->sc.gui_pixel_aspect)
+    || (this->sc.user_ratio != frame->sc.user_ratio)) {
+
+    frame->sc.gui_pixel_aspect   = gui_pixel_aspect;
+    frame->sc.user_ratio         = this->sc.user_ratio;
+
+    xshm_compute_ideal_size (this, frame);
+
+    /* now we have updated video_aspect_pixel we use the callback   */
+    /* again to obtain the correct gui_width and gui_height values. */
+    frame->sc.dest_size_cb (frame->sc.user_data, width, height,
+      frame->sc.video_pixel_aspect, &gui_width, &gui_height, &gui_pixel_aspect);
+
+    changed = 1;
+  }
+
+  if (changed || (frame->sc.gui_width != gui_width)
+    || (frame->sc.gui_height != gui_height)) {
+    int w = frame->sc.output_width, h = frame->sc.output_height;
+
+    frame->sc.gui_width  = gui_width;
+    frame->sc.gui_height = gui_height;
+
[... 240 lines omitted ...]
-
-    switch (flags) {
-    case VO_TOP_FIELD:
-    case VO_BOTTOM_FIELD:
-      frame->yuv2rgb->configure (frame->yuv2rgb,
-				 frame->sc.delivered_width,
-				 frame->sc.delivered_height,
-				 2*frame->vo_frame.pitches[0],
-				 2*frame->vo_frame.pitches[1],
-				 frame->sc.output_width,
-				 frame->sc.output_height,
-				 frame->image->bytes_per_line*2);
-      break;
-    case VO_BOTH_FIELDS:
-      frame->yuv2rgb->configure (frame->yuv2rgb,
-				 frame->sc.delivered_width,
-				 frame->sc.delivered_height,
-				 frame->vo_frame.pitches[0],
-				 frame->vo_frame.pitches[1],
-				 frame->sc.output_width,
-				 frame->sc.output_height,
-				 frame->image->bytes_per_line);
-      break;
-    }
+    /* defer the rest to xshm_frame_proc_setup () */
+    frame->state &= ~(FS_DONE | FS_LATE);
   }
 
-  xshm_frame_field ((vo_frame_t *)frame, flags);
+  if (!isnan (ratio) && (ratio < 1000.0) && (ratio > 0.001)
+    && (ratio != frame->sc.delivered_ratio)) {
+    frame->sc.delivered_ratio  = ratio;
+    frame->state &= ~FS_DONE;
+  }
+
+  if (flags != frame->flags) {
+    frame->flags = flags;
+    frame->state &= ~FS_FLAGS;
+  }
 }
 
 static void xshm_overlay_clut_yuv2rgb(xshm_driver_t  *this, vo_overlay_t *overlay,
@@ -652,6 +719,8 @@
 				vo_frame_t *frame_gen, vo_overlay_t *overlay) {
   xshm_driver_t  *this  = (xshm_driver_t *) this_gen;
   xshm_frame_t   *frame = (xshm_frame_t *) frame_gen;
+  int width = frame->sc.delivered_width - frame->sc.crop_left - \
frame->sc.crop_right; +  int height = frame->sc.delivered_height - frame->sc.crop_top \
- frame->sc.crop_bottom;  
   /* Alpha Blend here */
   if (overlay->rle) {
@@ -669,19 +738,19 @@
         case 16:
          _x_blend_rgb16 ((uint8_t *)frame->image->data, overlay,
 		      frame->sc.output_width, frame->sc.output_height,
-		      frame->sc.delivered_width, frame->sc.delivered_height,
+		      width, height,
                       &this->alphablend_extra_data);
          break;
         case 24:
          _x_blend_rgb24 ((uint8_t *)frame->image->data, overlay,
 		      frame->sc.output_width, frame->sc.output_height,
-		      frame->sc.delivered_width, frame->sc.delivered_height,
+		      width, height,
                       &this->alphablend_extra_data);
          break;
         case 32:
          _x_blend_rgb32 ((uint8_t *)frame->image->data, overlay,
 		      frame->sc.output_width, frame->sc.output_height,
-		      frame->sc.delivered_width, frame->sc.delivered_height,
+		      width, height,
                       &this->alphablend_extra_data);
          break;
         default:
@@ -724,6 +793,12 @@
     this->sc.delivered_height   = this->cur_frame->sc.delivered_height;
     this->sc.delivered_width    = this->cur_frame->sc.delivered_width;
     this->sc.video_pixel_aspect = this->cur_frame->sc.video_pixel_aspect;
+
+    this->sc.crop_left          = this->cur_frame->sc.crop_left;
+    this->sc.crop_right         = this->cur_frame->sc.crop_right;
+    this->sc.crop_top           = this->cur_frame->sc.crop_top;
+    this->sc.crop_bottom        = this->cur_frame->sc.crop_bottom;
+
     if( _x_vo_scale_redraw_needed( &this->sc ) ) {
 
       clean_output_area (this, this->cur_frame);
@@ -753,6 +828,12 @@
   this->sc.delivered_height   = frame->sc.delivered_height;
   this->sc.delivered_width    = frame->sc.delivered_width;
   this->sc.video_pixel_aspect = frame->sc.video_pixel_aspect;
+
+    this->sc.crop_left          = frame->sc.crop_left;
+    this->sc.crop_right         = frame->sc.crop_right;
+    this->sc.crop_top           = frame->sc.crop_top;
+    this->sc.crop_bottom        = frame->sc.crop_bottom;
+
   if( _x_vo_scale_redraw_needed( &this->sc ) ) {
 
     clean_output_area (this, frame);
@@ -795,6 +876,27 @@
   UNLOCK_DISPLAY(this);
 
   lprintf ("display frame done\n");
+
+  /* just in case somebody changes crop this late - take over for next time */
+  /* adjust cropping to what yuv2rgb can handle */
+  if (frame_gen->format == XINE_IMGFMT_YV12) {
+    frame_gen->crop_left &= ~7;
+    frame_gen->crop_top &= ~1;
+  } else {
+    frame_gen->crop_left &= ~3;
+  }
+  /* check for crop changes */
+  if ((frame_gen->crop_left != frame->sc.crop_left)
+    || (frame_gen->crop_top != frame->sc.crop_top)
+    || (frame_gen->crop_right != frame->sc.crop_right)
+    || (frame_gen->crop_bottom != frame->sc.crop_bottom)) {
+    frame->sc.crop_left = frame_gen->crop_left;
+    frame->sc.crop_top = frame_gen->crop_top;
+    frame->sc.crop_right = frame_gen->crop_right;
+    frame->sc.crop_bottom = frame_gen->crop_bottom;
+    frame->state &= ~FS_DONE;
+    frame->state |= FS_LATE;
+  }
 }
 
 static int xshm_get_property (vo_driver_t *this_gen, int property) {


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Xine-cvslog mailing list
Xine-cvslog@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/xine-cvslog


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic