[ANNOUNCE] vdr-xine-0.7.10 plugin

Message ID 4E9345985C%linux@youmustbejoking.demon.co.uk
State New
Headers

Commit Message

Darren Salt Dec. 10, 2006, 11:36 p.m. UTC
  
  

Patch

diff -urNad xine-lib-vdr-1.1.3~/src/post/planar/expand.c xine-lib-vdr-1.1.3/src/post/planar/expand.c
--- xine-lib-vdr-1.1.3~/src/post/planar/expand.c	2006-12-10 21:50:18.000000000 +0000
+++ xine-lib-vdr-1.1.3/src/post/planar/expand.c	2006-12-10 21:53:21.883834541 +0000
@@ -27,6 +27,7 @@ 
  *
  */
 
+#include <math.h>
 #include "xine_internal.h"
 #include "post.h"
 
@@ -68,6 +69,8 @@ 
 typedef struct expand_parameters_s {
   int enable_automatic_shift;
   int overlay_y_offset;
+  int afd_mode;
+  int afd_shoot_protect;
   double aspect;
   int centre_cut_out_mode;
 } expand_parameters_t;
@@ -77,6 +80,10 @@ 
   "enable automatic overlay shifting")
 PARAM_ITEM(POST_PARAM_TYPE_INT, overlay_y_offset, NULL, -500, 500, 0,
   "manually shift the overlay vertically")
+PARAM_ITEM(POST_PARAM_TYPE_BOOL, afd_mode, NULL, 0, 1, 0,
+  "use AFD information if available")
+PARAM_ITEM(POST_PARAM_TYPE_BOOL, afd_shoot_protect, NULL, 0, 1, 0,
+  "enable shoot&protect (intended for 4:3 display)")
 PARAM_ITEM(POST_PARAM_TYPE_DOUBLE, aspect, NULL, 1.0, 3.5, 0,
   "target aspect ratio")
 PARAM_ITEM(POST_PARAM_TYPE_BOOL, centre_cut_out_mode, NULL, 0, 1, 0,
@@ -90,10 +97,17 @@ 
   
   int                      enable_automatic_shift;
   int                      overlay_y_offset;
+  int                      afd_mode;
+  int                      afd_shoot_protect;
   double                   aspect;
   int                      top_bar_height;
   int                      centre_cut_out_mode;
   int                      cropping_active;
+  double                   stream_ratio, afd_ratio;
+  double                   prev_ratio;
+  int                      prev_afd;
+  int                      prev_shoot_protect;
+  int                      crop_x, crop_y;
 } post_expand_t;
 
 /* plugin class functions */
@@ -165,9 +179,13 @@ 
   
   this->enable_automatic_shift = 0;
   this->overlay_y_offset       = 0;
+  this->afd_mode               = 1;
+  this->afd_shoot_protect      = 0;
   this->aspect                 = 4.0 / 3.0;
   this->centre_cut_out_mode    = 0;
   this->cropping_active        = 0;
+  this->crop_x = this->crop_y  = 0;
+  this->prev_shoot_protect     = -1; /* won't happen */
   
   port = _x_post_intercept_video_port(&this->post, video_target[0], &input, &output);
   port->new_port.get_frame     = expand_get_frame;
@@ -228,6 +246,8 @@ 
 
   this->enable_automatic_shift = param->enable_automatic_shift;
   this->overlay_y_offset       = param->overlay_y_offset;
+  this->afd_mode               = param->afd_mode;
+  this->afd_shoot_protect      = param->afd_shoot_protect;
   this->aspect                 = param->aspect;
   this->centre_cut_out_mode    = param->centre_cut_out_mode;
 
@@ -241,6 +261,8 @@ 
   
   param->enable_automatic_shift = this->enable_automatic_shift;
   param->overlay_y_offset       = this->overlay_y_offset;
+  param->afd_mode               = this->afd_mode;
+  param->afd_shoot_protect      = this->afd_shoot_protect;
   param->aspect                 = this->aspect;
   param->centre_cut_out_mode    = this->centre_cut_out_mode;
   
@@ -292,13 +314,181 @@ 
 }
 
 
+/* Mode matrix:
+ *        4:3  16:9
+ * Crop
+ * Nocrop
+ */
+
+static inline int approx_eq (double a, double b)
+{
+  return fabs (a - b) < 1.0/64.0;
+}
+
+static int translate_ratio(double ratio)
+{
+  if (approx_eq (ratio, 4.0/3.0))
+    return 4;
+  if (approx_eq (ratio, 16.0/9.0))
+    return 16;
+/*
+  if (approx_eq (ratio, 14.0/9.0))
+    return 14;
+*/
+  return 0;
+}
+
+static int expand_afd(vo_frame_t *frame, xine_stream_t *stream)
+{
+  int afd = _x_stream_info_get_public(stream, XINE_STREAM_INFO_VIDEO_AFD);
+  post_video_port_t *port = (post_video_port_t *)frame->port;
+  post_expand_t *this = (post_expand_t *)port->post;
+  int ratio = translate_ratio (frame->ratio);
+
+  if (afd == this->prev_afd && frame->ratio == this->prev_ratio &&
+      this->afd_shoot_protect == this->prev_shoot_protect)
+    goto unchanged;
+
+  this->prev_afd = afd;
+  this->prev_ratio = frame->ratio;
+
+  this->crop_x = 0;
+  this->crop_y = 0;
+  this->afd_ratio = 0;
+  this->cropping_active = 0;
+
+  if (!ratio)
+    goto unchanged;
+
+  switch (afd)
+  {
+  case XINE_VIDEO_AFD_NOT_PRESENT:
+  case XINE_VIDEO_AFD_SAME_AS_FRAME:
+  case XINE_VIDEO_AFD_RESERVED_12:
+    /* nothing to do */
+    break;
+
+  case XINE_VIDEO_AFD_4_3_CENTRE:
+    /* if stream is 16:9, crop it to 4:3 (3/4 width) */
+    if (ratio == 16)
+    {
+      this->crop_x = frame->width / 8;
+      this->crop_y = 0;
+      this->afd_ratio = 4.0 / 3.0;
+      this->cropping_active = 1;
+    }
+    break;
+
+  case XINE_VIDEO_AFD_16_9_CENTRE:
+    /* if stream is 4:3, crop it to 16:9 (3/4 height) */
+    if (ratio == 4)
+    {
+      this->crop_x = 0;
+      this->crop_y = frame->height / 8;
+      this->afd_ratio = 16.0 / 9.0;
+      this->cropping_active = 1;
+    }
+    break;
+
+  case XINE_VIDEO_AFD_14_9_CENTRE:
+    /* video is 14:9 - always crop */
+    if (ratio == 4)
+    {
+      /* crop top & bottom (6/7 height) */
+      this->crop_x = 0;
+      this->crop_y = frame->height / 14;
+    }
+    else /* ratio == 16 */
+    {
+      /* crop sides (7/8 width) */
+      this->crop_x = frame->width / 16;
+      this->crop_y = 0;
+    }
+    this->afd_ratio = 14.0 / 9.0;
+    this->cropping_active = 1;
+    break;
+
+  case XINE_VIDEO_AFD_4_3_PROTECT_14_9:
+    /* optional cropping from 4:3 to 14:9 */
+    this->crop_x = 0;
+    if (this->afd_shoot_protect)
+    {
+      this->crop_y = frame->height / 14;
+      this->afd_ratio = 14.0 / 9.0;
+    }
+    else
+    {
+      this->crop_y = 0;
+      this->afd_ratio = 4.0 / 3.0;
+    }
+    this->cropping_active = 1;
+    break;
+
+  case XINE_VIDEO_AFD_16_9_PROTECT_14_9:
+    /* optional cropping from 16:9 to 14:9 */
+    if (this->afd_shoot_protect)
+    {
+      this->crop_x = frame->width / 16;
+      this->afd_ratio = 14.0 / 9.0;
+    }
+    else
+    {
+      this->crop_x = 0;
+      this->afd_ratio = 16.0 / 9.0;
+    }
+    this->crop_y = 0;
+    this->cropping_active = 1;
+    break;
+
+  case XINE_VIDEO_AFD_16_9_PROTECT_4_3:
+    /* optional cropping from 16:9 to 14:9 */
+    if (this->afd_shoot_protect)
+    {
+      this->crop_x = frame->width / 8;
+      this->afd_ratio = 4.0 / 3.0;
+    }
+    else
+    {
+      this->crop_x = 0;
+      this->afd_ratio = 16.0 / 9.0;
+    }
+    this->crop_y = 0;
+    this->cropping_active = 1;
+    break;
+
+  default:
+    /* unknown or reserved values; do nothing */
+    break;
+  }
+
+  /* DEBUG - development */
+  (printf) ("AFD %d, stream = %d, using = %d, crop %dÃ?%d\n", afd,
+	    translate_ratio (frame->ratio),
+	    translate_ratio (this->afd_ratio),
+	    this->crop_x, this->crop_y);
+
+unchanged:
+  frame->crop_left   += this->crop_x;
+  frame->crop_right  += this->crop_x;
+  frame->crop_top    += this->crop_y;
+  frame->crop_bottom += this->crop_y;
+
+printf ("crop â?%d â??%d â??%d â??%d\n", frame->crop_left, frame->crop_right, frame->crop_top, frame->crop_bottom);
+
+  return this->cropping_active;
+}
+
+
 static int expand_draw(vo_frame_t *frame, xine_stream_t *stream)
 {
   post_video_port_t *port = (post_video_port_t *)frame->port;
   post_expand_t     *this = (post_expand_t *)port->post;
   int                skip;
 
-  if (this->centre_cut_out_mode && !frame->bad_frame)
+  if (!frame->bad_frame && this->afd_mode && expand_afd (frame, stream))
+    goto done;
+
+  if (!frame->bad_frame && this->centre_cut_out_mode)
   {
     /* expected area of inner 4:3 image */
     int centre_width = frame->width * (9 * 4) / (16 * 3);
@@ -331,6 +521,8 @@ 
     }
   }
 
+  done:
+
   frame->ratio = this->aspect;
   _x_post_frame_copy_down(frame, frame->next);
   skip = frame->next->draw(frame->next, stream);
@@ -355,13 +547,25 @@ 
   if (ratio <= 0.0) ratio = (double)width / (double)height;
   
   /* Calculate height of expanded frame */
-  new_height = (double)height * ratio / this->aspect;
+  new_height = this->afd_mode ? height : ((double)height * ratio / this->aspect);
   new_height = (new_height + 1) & ~1;
   top_bar_height = (new_height - height) / 2;
   top_bar_height = (top_bar_height + 1) & ~1;
   
   this->top_bar_height = top_bar_height;
 
+  if (this->afd_mode &&
+      (format == XINE_IMGFMT_YV12 || format == XINE_IMGFMT_YUY2))
+  {
+    frame = port->original_port->get_frame
+              (port->original_port, width, height,
+               this->afd_ratio ? this->afd_ratio : ratio, format, flags);
+    _x_post_inc_usage(port);
+    this->stream_ratio = frame->ratio = ratio;
+    frame = _x_post_intercept_video_frame(frame, port);
+    return frame;
+  }
+
   if (new_height > height &&
       (format == XINE_IMGFMT_YV12 || format == XINE_IMGFMT_YUY2)) {
     frame = port->original_port->get_frame(port->original_port,
@@ -423,13 +627,12 @@ 
 {
   post_expand_t         *this = (post_expand_t *)port->post;
 
-  if (this->centre_cut_out_mode && this->cropping_active) return 0;
+  if ((this->centre_cut_out_mode | this->afd_mode) && this->cropping_active)
+    return 0;
   
   /* we always intercept overlay manager */
   return 1;
 }
-
-
 static int32_t expand_overlay_add_event(video_overlay_manager_t *this_gen, void *event_gen)
 {
   video_overlay_event_t *event = (video_overlay_event_t *)event_gen;