mfc: Add proper support for MFC decoder strides

This commit is contained in:
Sebastian Dröge 2012-12-24 12:18:23 +01:00
parent 94acf4189c
commit 52f8649586
4 changed files with 45 additions and 22 deletions

View 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;
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);

View 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

View 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)
{

View 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);