summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Farnsworth <simon.farnsworth@onelan.co.uk>2015-01-21 18:29:22 +0000
committerNicolas Dufresne <nicolas.dufresne@collabora.com>2015-02-15 15:11:41 -0600
commitf3e8dcb9de4d546e7d80ccc1754ed13dd4e7ac81 (patch)
tree337dd90b01fad1f0dfed394b28768291edf53a22
parent7dc03df3ded9ce1edbb81d72fea0ceeba3252820 (diff)
mpeg2dec: Fix handling of stride
A pipeline like: gst-launch-1.0 filesrc location=file.ts ! tsdemux ! mpegvideoparse ! mpeg2dec ! vaapisink would look bad when file.ts contains 704x576 video, because vaapisink would give you buffers of stride 768, but libmpeg2 was not told about this and used a stride of 704. Tell libmpeg2 about the stride from downstream; in the process, teach it to reject buffer pools that don't meet libmpeg2's chroma stride requirements Signed-off-by: Simon Farnsworth <simon.farnsworth@onelan.co.uk>
-rw-r--r--ext/mpeg2dec/gstmpeg2dec.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/ext/mpeg2dec/gstmpeg2dec.c b/ext/mpeg2dec/gstmpeg2dec.c
index 28616c56..42549eb6 100644
--- a/ext/mpeg2dec/gstmpeg2dec.c
+++ b/ext/mpeg2dec/gstmpeg2dec.c
@@ -257,6 +257,11 @@ gst_mpeg2dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
GstAllocator *allocator;
GstAllocationParams params;
gboolean update_allocator;
+ GstBuffer *test_buffer;
+ GstVideoFrame vframe;
+ gint chroma_stride;
+ gboolean chroma_stride_acceptable;
+ gboolean pool_was_active;
/* Set allocation parameters to guarantee 16-byte aligned output buffers */
if (gst_query_get_n_allocation_params (query) > 0) {
@@ -311,6 +316,41 @@ gst_mpeg2dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
+ /* Confirm that stride is acceptable to libmpeg2 */
+ chroma_stride_acceptable = FALSE;
+ pool_was_active = gst_buffer_pool_is_active (pool);
+
+ if (!gst_buffer_pool_set_active (pool, TRUE))
+ goto pool_not_activated;
+
+ if (gst_buffer_pool_acquire_buffer (pool, &test_buffer, NULL) != GST_FLOW_OK)
+ goto buffer_not_acquired;
+
+ if (!gst_video_frame_map (&vframe, &dec->decoded_info, test_buffer,
+ GST_MAP_READ | GST_MAP_WRITE))
+ goto buffer_not_mapped;
+
+ if (GST_VIDEO_FRAME_N_PLANES (&vframe) != 3)
+ goto too_few_planes;
+
+ chroma_stride = GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 0) >> 1;
+ chroma_stride_acceptable =
+ GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 1) == chroma_stride &&
+ GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 2) == chroma_stride;
+
+too_few_planes:
+ gst_video_frame_unmap (&vframe);
+
+buffer_not_mapped:
+ g_object_unref (test_buffer);
+
+buffer_not_acquired:
+ gst_buffer_pool_set_active (pool, pool_was_active);
+
+pool_not_activated:
+ if (!chroma_stride_acceptable)
+ gst_query_set_nth_allocation_pool (query, 0, NULL, size, min, max);
+
gst_object_unref (pool);
gst_video_codec_state_unref (state);
@@ -553,6 +593,7 @@ gst_mpeg2dec_alloc_buffer (GstMpeg2dec * mpeg2dec, GstVideoCodecFrame * frame,
* ones we did */
mpeg2_set_buf (mpeg2dec->decoder, buf,
GINT_TO_POINTER (frame->system_frame_number + 1));
+ mpeg2_stride (mpeg2dec->decoder, GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 0));
gst_mpeg2dec_save_buffer (mpeg2dec, frame->system_frame_number, &vframe);
beach: