From 52f864958615588616a1f76cc495e4a3e9cc1c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 24 Dec 2012 12:18:23 +0100 Subject: [PATCH] mfc: Add proper support for MFC decoder strides --- sys/mfc/gstmfcdec.c | 51 ++++++++++++++++++------------- sys/mfc/gstmfcdec.h | 4 ++- sys/mfc/mfc_decoder/mfc_decoder.c | 11 +++++++ sys/mfc/mfc_decoder/mfc_decoder.h | 1 + 4 files changed, 45 insertions(+), 22 deletions(-) diff --git a/sys/mfc/gstmfcdec.c b/sys/mfc/gstmfcdec.c index 238637899f..40d20986ed 100644 --- a/sys/mfc/gstmfcdec.c +++ b/sys/mfc/gstmfcdec.c @@ -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; - if (fimc_set_src_format (fimc, FIMC_COLOR_FORMAT_YUV420SPT, width, height, - NULL, 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) - 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->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, + 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->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->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); diff --git a/sys/mfc/gstmfcdec.h b/sys/mfc/gstmfcdec.h index 773af49b8e..8ae0e9f84d 100644 --- a/sys/mfc/gstmfcdec.h +++ b/sys/mfc/gstmfcdec.h @@ -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 diff --git a/sys/mfc/mfc_decoder/mfc_decoder.c b/sys/mfc/mfc_decoder/mfc_decoder.c index 682373ef71..ac0e7cec36 100644 --- a/sys/mfc/mfc_decoder/mfc_decoder.c +++ b/sys/mfc/mfc_decoder/mfc_decoder.c @@ -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) { diff --git a/sys/mfc/mfc_decoder/mfc_decoder.h b/sys/mfc/mfc_decoder/mfc_decoder.h index 28425c61bd..88169cc484 100644 --- a/sys/mfc/mfc_decoder/mfc_decoder.h +++ b/sys/mfc/mfc_decoder/mfc_decoder.h @@ -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);