summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Schmidt <thaytan@noraisin.net>2017-03-14 03:00:49 +1100
committerJan Schmidt <thaytan@noraisin.net>2017-03-14 03:00:49 +1100
commit413f05269c8d28375f4c3b9e0adf14a274e161a6 (patch)
treecf2d45c3b5af6b058bf4be47f10eaeba7c2be2d2
parentf3a7bce4429e774d0ace1b2d72c29f73ae0a9673 (diff)
downloadgst-omx-413f05269c8d28375f4c3b9e0adf14a274e161a6.tar.gz
omxvideoenc: Add GST_OMX_HACK_HEIGHT_MULTIPLE_16 for Rpi
The Raspberry Pi encoder produces corrupt output unless the input height is a multiple of 16. Add a hack that adds zero padding when needed.
-rw-r--r--omx/gstomx.c4
-rw-r--r--omx/gstomx.h5
-rw-r--r--omx/gstomxvideoenc.c67
3 files changed, 47 insertions, 29 deletions
diff --git a/omx/gstomx.c b/omx/gstomx.c
index f9b41eb..214f618 100644
--- a/omx/gstomx.c
+++ b/omx/gstomx.c
@@ -2454,7 +2454,7 @@ gst_omx_command_to_string (OMX_COMMANDTYPE cmd)
}
#if defined(USE_OMX_TARGET_RPI)
-#define DEFAULT_HACKS (GST_OMX_HACK_NO_COMPONENT_ROLE)
+#define DEFAULT_HACKS (GST_OMX_HACK_NO_COMPONENT_ROLE | GST_OMX_HACK_HEIGHT_MULTIPLE_16)
#else
#define DEFAULT_HACKS (0)
#endif
@@ -2490,6 +2490,8 @@ gst_omx_parse_hacks (gchar ** hacks)
hacks_flags |= GST_OMX_HACK_NO_DISABLE_OUTPORT;
else if (g_str_equal (*hacks, "signals-premature-eos"))
hacks_flags |= GST_OMX_HACK_SIGNALS_PREMATURE_EOS;
+ else if (g_str_equal (*hacks, "height-multiple-16"))
+ hacks_flags |= GST_OMX_HACK_HEIGHT_MULTIPLE_16;
else
GST_WARNING ("Unknown hack: %s", *hacks);
hacks++;
diff --git a/omx/gstomx.h b/omx/gstomx.h
index 60a315b..cafed89 100644
--- a/omx/gstomx.h
+++ b/omx/gstomx.h
@@ -134,6 +134,11 @@ G_BEGIN_DECLS
*/
#define GST_OMX_HACK_NO_DISABLE_OUTPORT G_GUINT64_CONSTANT (0x0000000000000100)
+/* If the encoder requires input buffers that have a height
+ * which is a multiple of 16 pixels
+ */
+#define GST_OMX_HACK_HEIGHT_MULTIPLE_16 G_GUINT64_CONSTANT (0x0000000000000200)
+
typedef struct _GstOMXCore GstOMXCore;
typedef struct _GstOMXPort GstOMXPort;
typedef enum _GstOMXPortDirection GstOMXPortDirection;
diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c
index 6a027b8..111b213 100644
--- a/omx/gstomxvideoenc.c
+++ b/omx/gstomxvideoenc.c
@@ -1053,7 +1053,11 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
port_def.format.video.nStride = GST_ROUND_UP_4 (info->width); /* safe (?) default */
port_def.format.video.nFrameHeight = info->height;
- port_def.format.video.nSliceHeight = info->height;
+
+ if (klass->cdata.hacks & GST_OMX_HACK_HEIGHT_MULTIPLE_16)
+ port_def.format.video.nSliceHeight = GST_ROUND_UP_16 (info->height);
+ else
+ port_def.format.video.nSliceHeight = info->height;
switch (port_def.format.video.eColorFormat) {
case OMX_COLOR_FormatYUV420Planar:
@@ -1303,6 +1307,9 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf,
outbuf->omx_buf->nAllocLen - outbuf->omx_buf->nOffset) {
outbuf->omx_buf->nFilledLen = gst_buffer_get_size (inbuf);
+ GST_LOG_OBJECT (self, "Matched strides - direct copy %u bytes",
+ outbuf->omx_buf->nFilledLen);
+
gst_buffer_extract (inbuf, 0,
outbuf->omx_buf->pBuffer + outbuf->omx_buf->nOffset,
outbuf->omx_buf->nFilledLen);
@@ -1311,10 +1318,11 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf,
}
/* Different strides */
+ GST_LOG_OBJECT (self, "Mismatched strides - copying line-by-line");
switch (info->finfo->format) {
case GST_VIDEO_FORMAT_I420:{
- gint i, j, height, width;
+ gint i, j, height, width, dest_height;
guint8 *src, *dest;
gint src_stride, dest_stride;
@@ -1329,20 +1337,17 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf,
for (i = 0; i < 3; i++) {
if (i == 0) {
dest_stride = port_def->format.video.nStride;
- src_stride = GST_VIDEO_FRAME_COMP_STRIDE (&frame, 0);
-
- /* XXX: Try this if no stride was set */
- if (dest_stride == 0)
- dest_stride = src_stride;
+ dest_height = port_def->format.video.nSliceHeight;
} else {
dest_stride = port_def->format.video.nStride / 2;
- src_stride = GST_VIDEO_FRAME_COMP_STRIDE (&frame, 1);
-
- /* XXX: Try this if no stride was set */
- if (dest_stride == 0)
- dest_stride = src_stride;
+ dest_height = port_def->format.video.nSliceHeight / 2;
}
+ src_stride = GST_VIDEO_FRAME_COMP_STRIDE (&frame, i);
+ /* XXX: Try this if no stride was set */
+ if (dest_stride == 0)
+ dest_stride = src_stride;
+
dest = outbuf->omx_buf->pBuffer + outbuf->omx_buf->nOffset;
if (i > 0)
dest +=
@@ -1371,13 +1376,19 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf,
src += src_stride;
dest += dest_stride;
}
+ for (; j < dest_height; j++) {
+ memset (dest, 0, dest_stride);
+ outbuf->omx_buf->nFilledLen += dest_stride;
+ src += src_stride;
+ dest += dest_stride;
+ }
}
gst_video_frame_unmap (&frame);
ret = TRUE;
break;
}
case GST_VIDEO_FORMAT_NV12:{
- gint i, j, height, width;
+ gint i, j, height, width, dest_height;
guint8 *src, *dest;
gint src_stride, dest_stride;
@@ -1388,22 +1399,13 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf,
ret = FALSE;
break;
}
+ dest_stride = port_def->format.video.nStride;
for (i = 0; i < 2; i++) {
- if (i == 0) {
- dest_stride = port_def->format.video.nStride;
- src_stride = GST_VIDEO_FRAME_COMP_STRIDE (&frame, 0);
- /* XXX: Try this if no stride was set */
- if (dest_stride == 0)
- dest_stride = src_stride;
- } else {
- dest_stride = port_def->format.video.nStride;
- src_stride = GST_VIDEO_FRAME_COMP_STRIDE (&frame, 1);
-
- /* XXX: Try this if no stride was set */
- if (dest_stride == 0)
- dest_stride = src_stride;
- }
+ src_stride = GST_VIDEO_FRAME_COMP_STRIDE (&frame, i);
+ /* XXX: Try this if no stride was set */
+ if (dest_stride == 0)
+ dest_stride = src_stride;
dest = outbuf->omx_buf->pBuffer + outbuf->omx_buf->nOffset;
if (i == 1)
@@ -1411,6 +1413,10 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf,
port_def->format.video.nSliceHeight *
port_def->format.video.nStride;
+ if (i == 0)
+ dest_height = port_def->format.video.nSliceHeight;
+ else
+ dest_height = port_def->format.video.nSliceHeight / 2;
src = GST_VIDEO_FRAME_COMP_DATA (&frame, i);
height = GST_VIDEO_FRAME_COMP_HEIGHT (&frame, i);
width = GST_VIDEO_FRAME_COMP_WIDTH (&frame, i) * (i == 0 ? 1 : 2);
@@ -1429,7 +1435,12 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf,
src += src_stride;
dest += dest_stride;
}
-
+ for (; j < dest_height; j++) {
+ memset (dest, 0, dest_stride);
+ outbuf->omx_buf->nFilledLen += dest_stride;
+ src += src_stride;
+ dest += dest_stride;
+ }
}
gst_video_frame_unmap (&frame);
ret = TRUE;