mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
omxvideodec: Negotiate video format with downstream and what the component claims to support
This commit is contained in:
parent
fa2dff1ad6
commit
3ba45aa0af
1 changed files with 130 additions and 2 deletions
|
@ -613,6 +613,8 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
|
||||||
default:
|
default:
|
||||||
GST_ERROR_OBJECT (self, "Unsupported color format: %d",
|
GST_ERROR_OBJECT (self, "Unsupported color format: %d",
|
||||||
port_def.format.video.eColorFormat);
|
port_def.format.video.eColorFormat);
|
||||||
|
if (buf)
|
||||||
|
gst_omx_port_release_buffer (self->out_port, buf);
|
||||||
goto caps_failed;
|
goto caps_failed;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -620,8 +622,8 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
|
||||||
state->width = port_def.format.video.nFrameWidth;
|
state->width = port_def.format.video.nFrameWidth;
|
||||||
state->height = port_def.format.video.nFrameHeight;
|
state->height = port_def.format.video.nFrameHeight;
|
||||||
|
|
||||||
/* FIXME XXX: Bellagio does not set this to something useful... */
|
/* Take framerate and pixel-aspect-ratio from sinkpad caps */
|
||||||
/* gst_util_double_to_fraction (port_def.format.video.xFramerate / ((gdouble) 0xffff), &state->fps_n, &state->fps_d); */
|
|
||||||
if (!gst_base_video_decoder_set_src_caps (GST_BASE_VIDEO_DECODER (self))) {
|
if (!gst_base_video_decoder_set_src_caps (GST_BASE_VIDEO_DECODER (self))) {
|
||||||
if (buf)
|
if (buf)
|
||||||
gst_omx_port_release_buffer (self->out_port, buf);
|
gst_omx_port_release_buffer (self->out_port, buf);
|
||||||
|
@ -708,12 +710,14 @@ component_error:
|
||||||
gst_pad_pause_task (GST_BASE_VIDEO_CODEC_SRC_PAD (self));
|
gst_pad_pause_task (GST_BASE_VIDEO_CODEC_SRC_PAD (self));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
flushing:
|
flushing:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (self, "Flushing -- stopping task");
|
GST_DEBUG_OBJECT (self, "Flushing -- stopping task");
|
||||||
gst_pad_pause_task (GST_BASE_VIDEO_CODEC_SRC_PAD (self));
|
gst_pad_pause_task (GST_BASE_VIDEO_CODEC_SRC_PAD (self));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
flow_error:
|
flow_error:
|
||||||
{
|
{
|
||||||
if (flow_ret == GST_FLOW_UNEXPECTED) {
|
if (flow_ret == GST_FLOW_UNEXPECTED) {
|
||||||
|
@ -733,6 +737,7 @@ flow_error:
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reconfigure_error:
|
reconfigure_error:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
|
GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
|
||||||
|
@ -742,6 +747,7 @@ reconfigure_error:
|
||||||
gst_pad_pause_task (GST_BASE_VIDEO_CODEC_SRC_PAD (self));
|
gst_pad_pause_task (GST_BASE_VIDEO_CODEC_SRC_PAD (self));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
invalid_buffer:
|
invalid_buffer:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
|
GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
|
||||||
|
@ -751,6 +757,7 @@ invalid_buffer:
|
||||||
gst_pad_pause_task (GST_BASE_VIDEO_CODEC_SRC_PAD (self));
|
gst_pad_pause_task (GST_BASE_VIDEO_CODEC_SRC_PAD (self));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
caps_failed:
|
caps_failed:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), ("Failed to set caps"));
|
GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), ("Failed to set caps"));
|
||||||
|
@ -798,6 +805,124 @@ gst_omx_video_dec_stop (GstBaseVideoDecoder * decoder)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_omx_video_dec_negotiate (GstOMXVideoDec * self)
|
||||||
|
{
|
||||||
|
GstOMXPort *port = self->out_port;
|
||||||
|
GstVideoState *state = &GST_BASE_VIDEO_CODEC (self)->state;
|
||||||
|
OMX_VIDEO_PARAM_PORTFORMATTYPE param;
|
||||||
|
OMX_ERRORTYPE err;
|
||||||
|
GstCaps *comp_supported_caps;
|
||||||
|
const GstCaps *templ_caps;
|
||||||
|
GstCaps *peer_caps, *intersection;
|
||||||
|
GstVideoFormat format;
|
||||||
|
gint old_index;
|
||||||
|
GstStructure *s;
|
||||||
|
guint32 fourcc;
|
||||||
|
|
||||||
|
templ_caps =
|
||||||
|
gst_pad_get_pad_template_caps (GST_BASE_VIDEO_CODEC_SRC_PAD (self));
|
||||||
|
peer_caps = gst_pad_peer_get_caps (GST_BASE_VIDEO_CODEC_SRC_PAD (self));
|
||||||
|
if (peer_caps) {
|
||||||
|
intersection = gst_caps_intersect (templ_caps, peer_caps);
|
||||||
|
gst_caps_unref (peer_caps);
|
||||||
|
} else {
|
||||||
|
intersection = gst_caps_copy (templ_caps);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_OMX_INIT_STRUCT (¶m);
|
||||||
|
param.nPortIndex = port->index;
|
||||||
|
param.nIndex = 0;
|
||||||
|
if (state->fps_n == 0)
|
||||||
|
param.xFramerate = 0;
|
||||||
|
else
|
||||||
|
param.xFramerate = (state->fps_n << 16) / (state->fps_d);
|
||||||
|
|
||||||
|
old_index = -1;
|
||||||
|
comp_supported_caps = gst_caps_new_empty ();
|
||||||
|
do {
|
||||||
|
err =
|
||||||
|
gst_omx_component_get_parameter (self->component,
|
||||||
|
OMX_IndexParamVideoPortFormat, ¶m);
|
||||||
|
|
||||||
|
/* FIXME: Workaround for Bellagio that simply always
|
||||||
|
* returns the same value regardless of nIndex and
|
||||||
|
* never returns OMX_ErrorNoMore
|
||||||
|
*/
|
||||||
|
if (old_index == param.nIndex)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (err == OMX_ErrorNone) {
|
||||||
|
switch (param.eColorFormat) {
|
||||||
|
case OMX_COLOR_FormatYUV420Planar:
|
||||||
|
gst_caps_append_structure (comp_supported_caps,
|
||||||
|
gst_structure_new ("video/x-raw-yuv",
|
||||||
|
"format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2',
|
||||||
|
'0'), NULL));
|
||||||
|
break;
|
||||||
|
case OMX_COLOR_FormatYUV420SemiPlanar:
|
||||||
|
gst_caps_append_structure (comp_supported_caps,
|
||||||
|
gst_structure_new ("video/x-raw-yuv",
|
||||||
|
"format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('N', 'V', '1',
|
||||||
|
'2'), NULL));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
old_index = param.nIndex++;
|
||||||
|
} while (err == OMX_ErrorNone);
|
||||||
|
|
||||||
|
if (!gst_caps_is_empty (comp_supported_caps)) {
|
||||||
|
GstCaps *tmp;
|
||||||
|
|
||||||
|
tmp = gst_caps_intersect (comp_supported_caps, intersection);
|
||||||
|
gst_caps_unref (intersection);
|
||||||
|
intersection = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gst_caps_is_empty (intersection)) {
|
||||||
|
GST_ERROR_OBJECT (self, "Empty caps");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_caps_truncate (intersection);
|
||||||
|
|
||||||
|
s = gst_caps_get_structure (intersection, 0);
|
||||||
|
if (!gst_structure_get_fourcc (s, "format", &fourcc) ||
|
||||||
|
(format =
|
||||||
|
gst_video_format_from_fourcc (fourcc)) == GST_VIDEO_FORMAT_UNKNOWN) {
|
||||||
|
GST_ERROR_OBJECT (self, "Invalid caps: %" GST_PTR_FORMAT, intersection);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
|
case GST_VIDEO_FORMAT_I420:
|
||||||
|
param.eColorFormat = OMX_COLOR_FormatYUV420Planar;
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_FORMAT_NV12:
|
||||||
|
param.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GST_ERROR_OBJECT (self, "Unknown color format: %u", format);
|
||||||
|
return FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset framerate, we only care about the color format here */
|
||||||
|
param.xFramerate = 0;
|
||||||
|
|
||||||
|
err =
|
||||||
|
gst_omx_component_set_parameter (self->component,
|
||||||
|
OMX_IndexParamVideoPortFormat, ¶m);
|
||||||
|
if (err != OMX_ErrorNone) {
|
||||||
|
GST_ERROR_OBJECT (self, "Failed to set video port format: %s (0x%08x)",
|
||||||
|
gst_omx_error_to_string (err), err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (err == OMX_ErrorNone);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_omx_video_dec_set_format (GstBaseVideoDecoder * decoder,
|
gst_omx_video_dec_set_format (GstBaseVideoDecoder * decoder,
|
||||||
GstVideoState * state)
|
GstVideoState * state)
|
||||||
|
@ -868,6 +993,9 @@ gst_omx_video_dec_set_format (GstBaseVideoDecoder * decoder,
|
||||||
|
|
||||||
gst_buffer_replace (&self->codec_data, state->codec_data);
|
gst_buffer_replace (&self->codec_data, state->codec_data);
|
||||||
|
|
||||||
|
if (!gst_omx_video_dec_negotiate (self))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (needs_disable) {
|
if (needs_disable) {
|
||||||
if (gst_omx_port_set_enabled (self->in_port, TRUE) != OMX_ErrorNone)
|
if (gst_omx_port_set_enabled (self->in_port, TRUE) != OMX_ErrorNone)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
Loading…
Reference in a new issue