mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-22 10:23:47 +00:00
mfc: Add proper support for MFC decoder strides
This commit is contained in:
parent
94acf4189c
commit
52f8649586
4 changed files with 45 additions and 22 deletions
|
@ -321,6 +321,7 @@ gst_mfc_dec_dequeue_output (GstMFCDec * self)
|
||||||
struct mfc_buffer *mfc_outbuf = NULL;
|
struct mfc_buffer *mfc_outbuf = NULL;
|
||||||
gint width, height;
|
gint width, height;
|
||||||
gint crop_left, crop_top, crop_width, crop_height;
|
gint crop_left, crop_top, crop_width, crop_height;
|
||||||
|
gint src_ystride, src_uvstride;
|
||||||
GstVideoCodecState *state = NULL;
|
GstVideoCodecState *state = NULL;
|
||||||
gint64 deadline;
|
gint64 deadline;
|
||||||
Fimc *fimc = NULL;
|
Fimc *fimc = NULL;
|
||||||
|
@ -337,39 +338,47 @@ gst_mfc_dec_dequeue_output (GstMFCDec * self)
|
||||||
GST_DEBUG_OBJECT (self, "Dequeueing output");
|
GST_DEBUG_OBJECT (self, "Dequeueing output");
|
||||||
|
|
||||||
mfc_dec_get_output_size (self->context, &width, &height);
|
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,
|
mfc_dec_get_crop_size (self->context, &crop_left, &crop_top, &crop_width,
|
||||||
&crop_height);
|
&crop_height);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Have output buffer: width %d, height %d, "
|
GST_DEBUG_OBJECT (self, "Have output buffer: width %d, height %d, "
|
||||||
|
"Y stride %d, UV stride %d, "
|
||||||
"crop_left %d, crop_right %d, "
|
"crop_left %d, crop_right %d, "
|
||||||
"crop_width %d, crop_height %d", width, height,
|
"crop_width %d, crop_height %d", width, height, src_ystride,
|
||||||
crop_left, crop_top, crop_width, crop_height);
|
src_uvstride, crop_left, crop_top, crop_width, crop_height);
|
||||||
|
|
||||||
if (self->width != width || self->height != height ||
|
if (self->width != width || self->height != height ||
|
||||||
self->crop_left != self->crop_left || self->crop_top != crop_top ||
|
self->src_stride[0] != src_ystride
|
||||||
self->crop_width != crop_width || self->crop_height != crop_height) {
|
|| 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;
|
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->width = width;
|
||||||
self->height = height;
|
self->height = height;
|
||||||
self->crop_left = crop_left;
|
self->crop_left = crop_left;
|
||||||
self->crop_top = crop_top;
|
self->crop_top = crop_top;
|
||||||
self->crop_width = crop_width;
|
self->crop_width = crop_width;
|
||||||
self->crop_height = crop_height;
|
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));
|
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);
|
dst_ = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (&vframe, 0);
|
||||||
src_ = self->dst[0];
|
src_ = self->dst[0];
|
||||||
|
src_stride = self->dst_stride[0];
|
||||||
h = GST_VIDEO_FRAME_COMP_HEIGHT (&vframe, 0);
|
h = GST_VIDEO_FRAME_COMP_HEIGHT (&vframe, 0);
|
||||||
w = GST_VIDEO_FRAME_COMP_WIDTH (&vframe, 0);
|
w = GST_VIDEO_FRAME_COMP_WIDTH (&vframe, 0);
|
||||||
src_stride = self->stride[0];
|
|
||||||
dst_stride = GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 0);
|
dst_stride = GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 0);
|
||||||
for (i = 0; i < h; i++) {
|
for (i = 0; i < h; i++) {
|
||||||
memcpy (dst_, src_, w);
|
memcpy (dst_, src_, w);
|
||||||
|
@ -459,9 +468,9 @@ gst_mfc_dec_dequeue_output (GstMFCDec * self)
|
||||||
|
|
||||||
dst_ = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (&vframe, 1);
|
dst_ = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (&vframe, 1);
|
||||||
src_ = self->dst[1];
|
src_ = self->dst[1];
|
||||||
|
src_stride = self->dst_stride[1];
|
||||||
h = GST_VIDEO_FRAME_COMP_HEIGHT (&vframe, 1);
|
h = GST_VIDEO_FRAME_COMP_HEIGHT (&vframe, 1);
|
||||||
w = GST_VIDEO_FRAME_COMP_WIDTH (&vframe, 1);
|
w = GST_VIDEO_FRAME_COMP_WIDTH (&vframe, 1);
|
||||||
src_stride = self->stride[1];
|
|
||||||
dst_stride = GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 1);
|
dst_stride = GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 1);
|
||||||
for (i = 0; i < h; i++) {
|
for (i = 0; i < h; i++) {
|
||||||
memcpy (dst_, src_, w);
|
memcpy (dst_, src_, w);
|
||||||
|
@ -471,9 +480,9 @@ gst_mfc_dec_dequeue_output (GstMFCDec * self)
|
||||||
|
|
||||||
dst_ = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (&vframe, 2);
|
dst_ = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (&vframe, 2);
|
||||||
src_ = self->dst[2];
|
src_ = self->dst[2];
|
||||||
|
src_stride = self->dst_stride[2];
|
||||||
h = GST_VIDEO_FRAME_COMP_HEIGHT (&vframe, 2);
|
h = GST_VIDEO_FRAME_COMP_HEIGHT (&vframe, 2);
|
||||||
w = GST_VIDEO_FRAME_COMP_WIDTH (&vframe, 2);
|
w = GST_VIDEO_FRAME_COMP_WIDTH (&vframe, 2);
|
||||||
src_stride = self->stride[2];
|
|
||||||
dst_stride = GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 2);
|
dst_stride = GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 2);
|
||||||
for (i = 0; i < h; i++) {
|
for (i = 0; i < h; i++) {
|
||||||
memcpy (dst_, src_, w);
|
memcpy (dst_, src_, w);
|
||||||
|
|
|
@ -58,8 +58,10 @@ struct _GstMFCDec
|
||||||
gint width, height;
|
gint width, height;
|
||||||
gint crop_left, crop_top;
|
gint crop_left, crop_top;
|
||||||
gint crop_width, crop_height;
|
gint crop_width, crop_height;
|
||||||
|
int src_stride[3];
|
||||||
|
|
||||||
void *dst[3];
|
void *dst[3];
|
||||||
int stride[3];
|
int dst_stride[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstMFCDecClass
|
struct _GstMFCDecClass
|
||||||
|
|
|
@ -99,6 +99,7 @@ struct mfc_dec_context {
|
||||||
int w;
|
int w;
|
||||||
int h;
|
int h;
|
||||||
} crop_size;
|
} crop_size;
|
||||||
|
int output_stride[NUM_OUTPUT_PLANES];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mfc_buffer {
|
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)
|
static int get_output_format(struct mfc_dec_context *ctx)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
struct v4l2_format fmt = {
|
struct v4l2_format fmt = {
|
||||||
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
|
.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.w = fmt.fmt.pix_mp.width;
|
||||||
ctx->output_size.h = fmt.fmt.pix_mp.height;
|
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;
|
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;
|
*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,
|
void mfc_dec_get_crop_size(struct mfc_dec_context *ctx,
|
||||||
int *left, int *top, int *w, int *h)
|
int *left, int *top, int *w, int *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.
|
* 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_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*,
|
void mfc_dec_get_crop_size(struct mfc_dec_context*,
|
||||||
int *left, int *top, int *w, int *h);
|
int *left, int *top, int *w, int *h);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue