pleorasrc: fix handling of strides that aren't 32-bit aligned

For example, a Mono8 642x482 would have failed to work, as GStreamer
expects the stride to be a multiple of 4-bytes, that is 644 bytes in
this example, while Pleora doesn't do this alignment. This incurs a copy
unfortunately, and there might be a way with memory meta to avoid this,
however eventually most elements will need to have the data 4-byte
aligned.
This commit is contained in:
Joshua M. Doe 2019-08-29 14:56:18 -04:00
parent 64866758a2
commit e364cfe4d5
2 changed files with 36 additions and 11 deletions

View File

@ -804,8 +804,6 @@ static gboolean
gst_pleorasrc_start (GstBaseSrc * bsrc) gst_pleorasrc_start (GstBaseSrc * bsrc)
{ {
GstPleoraSrc *src = GST_PLEORA_SRC (bsrc); GstPleoraSrc *src = GST_PLEORA_SRC (bsrc);
guint32 width, height, bpp, stride;
GstVideoInfo vinfo;
PvResult pvRes; PvResult pvRes;
GST_DEBUG_OBJECT (src, "start"); GST_DEBUG_OBJECT (src, "start");
@ -953,7 +951,9 @@ gst_pleorasrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
gst_video_info_from_caps (&vinfo, caps); gst_video_info_from_caps (&vinfo, caps);
if (GST_VIDEO_INFO_FORMAT (&vinfo) != GST_VIDEO_FORMAT_UNKNOWN) { if (GST_VIDEO_INFO_FORMAT (&vinfo) != GST_VIDEO_FORMAT_UNKNOWN) {
src->height = GST_VIDEO_INFO_HEIGHT (&vinfo);
src->gst_stride = GST_VIDEO_INFO_COMP_STRIDE (&vinfo, 0); src->gst_stride = GST_VIDEO_INFO_COMP_STRIDE (&vinfo, 0);
src->pleora_stride = GST_VIDEO_INFO_WIDTH (&vinfo) * GST_VIDEO_INFO_COMP_PSTRIDE (&vinfo, 0);
} else { } else {
goto unsupported_caps; goto unsupported_caps;
} }
@ -1112,16 +1112,41 @@ gst_pleorasrc_create (GstPushSrc * psrc, GstBuffer ** buf)
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
gpointer data = pvimage->GetDataPointer ();
if (src->pleora_stride == src->gst_stride) {
VideoFrame *vf = g_new0 (VideoFrame, 1); VideoFrame *vf = g_new0 (VideoFrame, 1);
vf->src = src; vf->src = src;
vf->buffer = pvbuffer; vf->buffer = pvbuffer;
gpointer data = pvimage->GetDataPointer ();
gsize data_size = pvimage->GetImageSize (); gsize data_size = pvimage->GetImageSize ();
*buf = *buf =
gst_buffer_new_wrapped_full ((GstMemoryFlags) GST_MEMORY_FLAG_READONLY, gst_buffer_new_wrapped_full ((GstMemoryFlags) GST_MEMORY_FLAG_READONLY,
(gpointer) data, data_size, 0, data_size, vf, (gpointer) data, data_size, 0, data_size, vf,
(GDestroyNotify) pvbuffer_release); (GDestroyNotify) pvbuffer_release);
} else {
GstMapInfo minfo;
GST_LOG_OBJECT (src,
"Row stride not aligned, copying %d -> %d",
src->pleora_stride, src->gst_stride);
*buf = gst_buffer_new_and_alloc (src->height * src->gst_stride);
guint8 *s = (guint8*)data;
guint8 *d;
gst_buffer_map (*buf, &minfo, GST_MAP_WRITE);
d = minfo.data;
g_assert (minfo.size >= src->pleora_stride * src->height);
for (int i = 0; i < src->height; i++)
memcpy (d + i * src->gst_stride, s + i * src->pleora_stride,
src->pleora_stride);
gst_buffer_unmap (*buf, &minfo);
src->pipeline->ReleaseBuffer (pvbuffer);
}
clock = gst_element_get_clock (GST_ELEMENT (src)); clock = gst_element_get_clock (GST_ELEMENT (src));
clock_time = gst_clock_get_time (clock); clock_time = gst_clock_get_time (clock);
gst_object_unref (clock); gst_object_unref (clock);

View File

@ -62,7 +62,7 @@ struct _GstPleoraSrc
GstCaps *caps; GstCaps *caps;
gint height; gint height;
gint gst_stride; gint gst_stride;
gint bf_stride; gint pleora_stride;
gboolean stop_requested; gboolean stop_requested;
}; };