mfc: Add proper support for MFC decoder strides
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Mon, 24 Dec 2012 11:18:23 +0000 (12:18 +0100)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Mon, 31 Dec 2012 14:59:06 +0000 (15:59 +0100)
sys/mfc/gstmfcdec.c
sys/mfc/gstmfcdec.h
sys/mfc/mfc_decoder/mfc_decoder.c
sys/mfc/mfc_decoder/mfc_decoder.h

index 2386378..40d2098 100644 (file)
@@ -321,6 +321,7 @@ gst_mfc_dec_dequeue_output (GstMFCDec * self)
   struct mfc_buffer *mfc_outbuf = NULL;
   gint width, height;
   gint crop_left, crop_top, crop_width, crop_height;
+  gint src_ystride, src_uvstride;
   GstVideoCodecState *state = NULL;
   gint64 deadline;
   Fimc *fimc = NULL;
@@ -337,39 +338,47 @@ gst_mfc_dec_dequeue_output (GstMFCDec * self)
     GST_DEBUG_OBJECT (self, "Dequeueing output");
 
     mfc_dec_get_output_size (self->context, &width, &height);
+    mfc_dec_get_output_stride (self->context, &src_ystride, &src_uvstride);
     mfc_dec_get_crop_size (self->context, &crop_left, &crop_top, &crop_width,
         &crop_height);
 
     GST_DEBUG_OBJECT (self, "Have output buffer: width %d, height %d, "
+        "Y stride %d, UV stride %d, "
         "crop_left %d, crop_right %d, "
-        "crop_width %d, crop_height %d", width, height,
-        crop_left, crop_top, crop_width, crop_height);
+        "crop_width %d, crop_height %d", width, height, src_ystride,
+        src_uvstride, crop_left, crop_top, crop_width, crop_height);
 
     if (self->width != width || self->height != height ||
-        self->crop_left != self->crop_left || self->crop_top != crop_top ||
-        self->crop_width != crop_width || self->crop_height != crop_height) {
+        self->src_stride[0] != src_ystride
+        || self->src_stride[1] != src_uvstride
+        || self->crop_left != self->crop_left || self->crop_top != crop_top
+        || self->crop_width != crop_width || self->crop_height != crop_height) {
       fimc = self->fimc;
 
+      self->width = width;
+      self->height = height;
+      self->crop_left = crop_left;
+      self->crop_top = crop_top;
+      self->crop_width = crop_width;
+      self->crop_height = crop_height;
+      self->src_stride[0] = src_ystride;
+      self->src_stride[1] = src_uvstride;
+      self->src_stride[2] = 0;
+
       if (fimc_set_src_format (fimc, FIMC_COLOR_FORMAT_YUV420SPT, width, height,
-              NULL, crop_left, crop_top, crop_width, crop_height) < 0)
+              self->src_stride, crop_left, crop_top, crop_width,
+              crop_height) < 0)
         goto fimc_src_error;
 
       if (fimc_set_dst_format_direct (fimc, FIMC_COLOR_FORMAT_YUV420P, width,
               height, crop_left, crop_top, crop_width, crop_height, self->dst,
-              self->stride) < 0)
+              self->dst_stride) < 0)
         goto fimc_dst_error;
 
       GST_DEBUG_OBJECT (self,
           "Got direct output buffer: %p [%d], %p [%d], %p [%d]", self->dst[0],
-          self->stride[0], self->dst[1], self->stride[1], self->dst[2],
-          self->stride[2]);
-
-      self->width = width;
-      self->height = height;
-      self->crop_left = crop_left;
-      self->crop_top = crop_top;
-      self->crop_width = crop_width;
-      self->crop_height = crop_height;
+          self->dst_stride[0], self->dst[1], self->dst_stride[1], self->dst[2],
+          self->dst_stride[2]);
     }
 
     state = gst_video_decoder_get_output_state (GST_VIDEO_DECODER (self));
@@ -447,9 +456,9 @@ gst_mfc_dec_dequeue_output (GstMFCDec * self)
 
       dst_ = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (&vframe, 0);
       src_ = self->dst[0];
+      src_stride = self->dst_stride[0];
       h = GST_VIDEO_FRAME_COMP_HEIGHT (&vframe, 0);
       w = GST_VIDEO_FRAME_COMP_WIDTH (&vframe, 0);
-      src_stride = self->stride[0];
       dst_stride = GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 0);
       for (i = 0; i < h; i++) {
         memcpy (dst_, src_, w);
@@ -459,9 +468,9 @@ gst_mfc_dec_dequeue_output (GstMFCDec * self)
 
       dst_ = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (&vframe, 1);
       src_ = self->dst[1];
+      src_stride = self->dst_stride[1];
       h = GST_VIDEO_FRAME_COMP_HEIGHT (&vframe, 1);
       w = GST_VIDEO_FRAME_COMP_WIDTH (&vframe, 1);
-      src_stride = self->stride[1];
       dst_stride = GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 1);
       for (i = 0; i < h; i++) {
         memcpy (dst_, src_, w);
@@ -471,9 +480,9 @@ gst_mfc_dec_dequeue_output (GstMFCDec * self)
 
       dst_ = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (&vframe, 2);
       src_ = self->dst[2];
+      src_stride = self->dst_stride[2];
       h = GST_VIDEO_FRAME_COMP_HEIGHT (&vframe, 2);
       w = GST_VIDEO_FRAME_COMP_WIDTH (&vframe, 2);
-      src_stride = self->stride[2];
       dst_stride = GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 2);
       for (i = 0; i < h; i++) {
         memcpy (dst_, src_, w);
index 773af49..8ae0e9f 100644 (file)
@@ -58,8 +58,10 @@ struct _GstMFCDec
   gint width, height;
   gint crop_left, crop_top;
   gint crop_width, crop_height;
+  int src_stride[3];
+
   void *dst[3];
-  int stride[3];
+  int dst_stride[3];
 };
 
 struct _GstMFCDecClass
index 682373e..ac0e7ce 100644 (file)
@@ -99,6 +99,7 @@ struct mfc_dec_context {
         int w;
         int h;
     } crop_size;
+    int output_stride[NUM_OUTPUT_PLANES];
 };
 
 struct mfc_buffer {
@@ -310,6 +311,7 @@ struct mfc_dec_context* mfc_dec_create(unsigned int codec, int num_input_buffers
 
 static int get_output_format(struct mfc_dec_context *ctx)
 {
+    int i;
     struct v4l2_format fmt = {
         .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
     };
@@ -322,6 +324,9 @@ static int get_output_format(struct mfc_dec_context *ctx)
     ctx->output_size.w = fmt.fmt.pix_mp.width;
     ctx->output_size.h = fmt.fmt.pix_mp.height;
 
+    for (i = 0; i < NUM_OUTPUT_PLANES; i++)
+      ctx->output_stride[i] = fmt.fmt.pix_mp.plane_fmt[i].bytesperline;
+
     return 0;
 }
 
@@ -399,6 +404,12 @@ void mfc_dec_get_output_size(struct mfc_dec_context *ctx, int *w, int *h)
     *h = ctx->output_size.h;
 }
 
+void mfc_dec_get_output_stride(struct mfc_dec_context *ctx, int *ystride, int *uvstride)
+{
+    *ystride = ctx->output_stride[0];
+    *uvstride = ctx->output_stride[1];
+}
+
 void mfc_dec_get_crop_size(struct mfc_dec_context *ctx,
                            int *left, int *top, int *w, int *h)
 {
index 28425c6..88169cc 100644 (file)
@@ -132,6 +132,7 @@ int mfc_dec_set_codec(struct mfc_dec_context*, enum mfc_codec_type codec);
  * Returns: Zero for success, negative value on failure.
  */
 void mfc_dec_get_output_size(struct mfc_dec_context*, int *w, int *h);
+void mfc_dec_get_output_stride(struct mfc_dec_context*, int *ystride, int *uvstride);
 void mfc_dec_get_crop_size(struct mfc_dec_context*,
                            int *left, int *top, int *w, int *h);