From 5c4a13b5a03e87a2d3fbf4490ec28b2e9eb8d466 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Sat, 15 May 2021 00:39:57 +0900 Subject: [PATCH] interlace: Fix too small buffer size error Even though input/output resolutions are identical there, default buffer size of progressive and interleaved formats could be different because we are rounding up height of all plane of interlaced frame to be multiple of two. Part-of: --- gst/interlace/gstinterlace.c | 39 +++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/gst/interlace/gstinterlace.c b/gst/interlace/gstinterlace.c index 5c7fc7e9d2..409de1b1eb 100644 --- a/gst/interlace/gstinterlace.c +++ b/gst/interlace/gstinterlace.c @@ -1059,15 +1059,16 @@ static void copy_fields (GstInterlace * interlace, GstBuffer * dest, GstBuffer * src, int field_index) { - GstVideoInfo *info = &interlace->info; + GstVideoInfo *in_info = &interlace->info; + GstVideoInfo *out_info = &interlace->out_info; gint i, j, n_planes; guint8 *d, *s; GstVideoFrame dframe, sframe; - if (!gst_video_frame_map (&dframe, info, dest, GST_MAP_WRITE)) + if (!gst_video_frame_map (&dframe, out_info, dest, GST_MAP_WRITE)) goto dest_map_failed; - if (!gst_video_frame_map (&sframe, info, src, GST_MAP_READ)) + if (!gst_video_frame_map (&sframe, in_info, src, GST_MAP_READ)) goto src_map_failed; n_planes = GST_VIDEO_FRAME_N_PLANES (&dframe); @@ -1282,6 +1283,8 @@ gst_interlace_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) GstBuffer *output_buffer, *output_buffer2 = NULL; guint n_output_fields; gboolean interlaced = FALSE; + GstVideoInfo *in_info = &interlace->info; + GstVideoInfo *out_info = &interlace->out_info; GST_DEBUG ("have %d fields, %d current, %d stored", num_fields, current_fields, interlace->stored_fields); @@ -1301,7 +1304,8 @@ gst_interlace_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) if (!output_buffer2) return GST_FLOW_ERROR; } else { - output_buffer = gst_buffer_new_and_alloc (gst_buffer_get_size (buffer)); + output_buffer = + gst_buffer_new_and_alloc (GST_VIDEO_INFO_SIZE (out_info)); /* take the first field from the stored frame */ copy_fields (interlace, output_buffer, interlace->stored_frame, interlace->field_index); @@ -1324,7 +1328,32 @@ gst_interlace_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) if (!output_buffer2) return GST_FLOW_ERROR; } else { - output_buffer = gst_buffer_copy (buffer); + GstVideoFrame dframe, sframe; + + output_buffer = + gst_buffer_new_and_alloc (GST_VIDEO_INFO_SIZE (out_info)); + + if (!gst_video_frame_map (&dframe, + out_info, output_buffer, GST_MAP_WRITE)) { + GST_ELEMENT_ERROR (interlace, CORE, FAILED, + ("Failed to write map buffer"), ("Failed to map output buffer")); + gst_buffer_unref (output_buffer); + gst_buffer_unref (buffer); + return GST_FLOW_ERROR; + } + + if (!gst_video_frame_map (&sframe, in_info, buffer, GST_MAP_READ)) { + GST_ELEMENT_ERROR (interlace, CORE, FAILED, + ("Failed to read map buffer"), ("Failed to map input buffer")); + gst_video_frame_unmap (&dframe); + gst_buffer_unref (output_buffer); + gst_buffer_unref (buffer); + return GST_FLOW_ERROR; + } + + gst_video_frame_copy (&dframe, &sframe); + gst_video_frame_unmap (&dframe); + gst_video_frame_unmap (&sframe); } if (num_fields >= 3 && interlace->allow_rff) {