omx: Refactor querying of component supported caps into its own function

This commit is contained in:
Sebastian Dröge 2013-02-25 11:42:38 +01:00
parent 70368c31cd
commit 3e090dd83b
2 changed files with 117 additions and 129 deletions

View file

@ -853,28 +853,16 @@ video_negotiation_map_free (VideoNegotiationMap * m)
g_slice_free (VideoNegotiationMap, m); g_slice_free (VideoNegotiationMap, m);
} }
static gboolean static GList *
gst_omx_video_dec_negotiate (GstOMXVideoDec * self) gst_omx_video_dec_get_supported_colorformats (GstOMXVideoDec * self)
{ {
GstOMXPort *port = self->dec_out_port; GstOMXPort *port = self->dec_out_port;
GstVideoCodecState *state = self->input_state; GstVideoCodecState *state = self->input_state;
GstVideoInfo *info = &state->info; GstVideoInfo *info = &state->info;
OMX_VIDEO_PARAM_PORTFORMATTYPE param; OMX_VIDEO_PARAM_PORTFORMATTYPE param;
OMX_ERRORTYPE err; OMX_ERRORTYPE err;
GstCaps *comp_supported_caps; GList *negotiation_map = NULL;
GList *negotiation_map = NULL, *l;
GstCaps *intersection;
GstVideoFormat format;
gint old_index; gint old_index;
GstStructure *s;
const gchar *format_str;
GST_DEBUG_OBJECT (self, "Trying to negotiate a video format with downstream");
intersection = gst_pad_get_allowed_caps (GST_VIDEO_DECODER_SRC_PAD (self));
GST_DEBUG_OBJECT (self, "Allowed downstream caps: %" GST_PTR_FORMAT,
intersection);
GST_OMX_INIT_STRUCT (&param); GST_OMX_INIT_STRUCT (&param);
param.nPortIndex = port->index; param.nPortIndex = port->index;
@ -885,7 +873,6 @@ gst_omx_video_dec_negotiate (GstOMXVideoDec * self)
param.xFramerate = (info->fps_n << 16) / (info->fps_d); param.xFramerate = (info->fps_n << 16) / (info->fps_d);
old_index = -1; old_index = -1;
comp_supported_caps = gst_caps_new_empty ();
do { do {
VideoNegotiationMap *m; VideoNegotiationMap *m;
@ -904,34 +891,64 @@ gst_omx_video_dec_negotiate (GstOMXVideoDec * self)
switch (param.eColorFormat) { switch (param.eColorFormat) {
case OMX_COLOR_FormatYUV420Planar: case OMX_COLOR_FormatYUV420Planar:
case OMX_COLOR_FormatYUV420PackedPlanar: case OMX_COLOR_FormatYUV420PackedPlanar:
m = g_slice_new0 (VideoNegotiationMap); m = g_slice_new (VideoNegotiationMap);
m->format = GST_VIDEO_FORMAT_I420; m->format = GST_VIDEO_FORMAT_I420;
m->type = param.eColorFormat; m->type = param.eColorFormat;
negotiation_map = g_list_append (negotiation_map, m); negotiation_map = g_list_append (negotiation_map, m);
gst_caps_append_structure (comp_supported_caps,
gst_structure_new ("video/x-raw",
"format", G_TYPE_STRING, "I420", NULL));
GST_DEBUG_OBJECT (self, "Component supports I420 (%d) at index %d", GST_DEBUG_OBJECT (self, "Component supports I420 (%d) at index %d",
param.eColorFormat, param.nIndex); param.eColorFormat, param.nIndex);
break; break;
case OMX_COLOR_FormatYUV420SemiPlanar: case OMX_COLOR_FormatYUV420SemiPlanar:
m = g_slice_new0 (VideoNegotiationMap); m = g_slice_new (VideoNegotiationMap);
m->format = GST_VIDEO_FORMAT_NV12; m->format = GST_VIDEO_FORMAT_NV12;
m->type = param.eColorFormat; m->type = param.eColorFormat;
negotiation_map = g_list_append (negotiation_map, m); negotiation_map = g_list_append (negotiation_map, m);
gst_caps_append_structure (comp_supported_caps,
gst_structure_new ("video/x-raw",
"format", G_TYPE_STRING, "NV12", NULL));
GST_DEBUG_OBJECT (self, "Component supports NV12 (%d) at index %d", GST_DEBUG_OBJECT (self, "Component supports NV12 (%d) at index %d",
param.eColorFormat, param.nIndex); param.eColorFormat, param.nIndex);
break; break;
default: default:
GST_DEBUG_OBJECT (self,
"Component supports unsupported color format %d at index %d",
param.eColorFormat, param.nIndex);
break; break;
} }
} }
old_index = param.nIndex++; old_index = param.nIndex++;
} while (err == OMX_ErrorNone); } while (err == OMX_ErrorNone);
return negotiation_map;
}
static gboolean
gst_omx_video_dec_negotiate (GstOMXVideoDec * self)
{
OMX_VIDEO_PARAM_PORTFORMATTYPE param;
OMX_ERRORTYPE err;
GstCaps *comp_supported_caps;
GList *negotiation_map = NULL, *l;
GstCaps *intersection;
GstVideoFormat format;
GstStructure *s;
const gchar *format_str;
GST_DEBUG_OBJECT (self, "Trying to negotiate a video format with downstream");
intersection = gst_pad_get_allowed_caps (GST_VIDEO_DECODER_SRC_PAD (self));
GST_DEBUG_OBJECT (self, "Allowed downstream caps: %" GST_PTR_FORMAT,
intersection);
negotiation_map = gst_omx_video_dec_get_supported_colorformats (self);
comp_supported_caps = gst_caps_new_empty ();
for (l = negotiation_map; l; l = l->next) {
VideoNegotiationMap *map = l->data;
gst_caps_append_structure (comp_supported_caps,
gst_structure_new ("video/x-raw",
"format", G_TYPE_STRING,
gst_video_format_to_string (map->format), NULL));
}
if (!gst_caps_is_empty (comp_supported_caps)) { if (!gst_caps_is_empty (comp_supported_caps)) {
GstCaps *tmp; GstCaps *tmp;
@ -939,7 +956,6 @@ gst_omx_video_dec_negotiate (GstOMXVideoDec * self)
gst_caps_unref (intersection); gst_caps_unref (intersection);
intersection = tmp; intersection = tmp;
} }
gst_caps_unref (comp_supported_caps); gst_caps_unref (comp_supported_caps);
if (gst_caps_is_empty (intersection)) { if (gst_caps_is_empty (intersection)) {

View file

@ -940,6 +940,72 @@ video_negotiation_map_free (VideoNegotiationMap * m)
g_slice_free (VideoNegotiationMap, m); g_slice_free (VideoNegotiationMap, m);
} }
static GList *
gst_omx_video_enc_get_supported_colorformats (GstOMXVideoEnc * self)
{
GstOMXPort *port = self->enc_in_port;
GstVideoCodecState *state = self->input_state;
GstVideoInfo *info = &state->info;
OMX_VIDEO_PARAM_PORTFORMATTYPE param;
OMX_ERRORTYPE err;
GList *negotiation_map = NULL;
gint old_index;
GST_OMX_INIT_STRUCT (&param);
param.nPortIndex = port->index;
param.nIndex = 0;
if (info->fps_n == 0)
param.xFramerate = 0;
else
param.xFramerate = (info->fps_n << 16) / (info->fps_d);
old_index = -1;
do {
VideoNegotiationMap *m;
err =
gst_omx_component_get_parameter (self->enc,
OMX_IndexParamVideoPortFormat, &param);
/* 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 || err == OMX_ErrorNoMore) {
switch (param.eColorFormat) {
case OMX_COLOR_FormatYUV420Planar:
case OMX_COLOR_FormatYUV420PackedPlanar:
m = g_slice_new (VideoNegotiationMap);
m->format = GST_VIDEO_FORMAT_I420;
m->type = param.eColorFormat;
negotiation_map = g_list_append (negotiation_map, m);
GST_DEBUG_OBJECT (self, "Component supports I420 (%d) at index %d",
param.eColorFormat, param.nIndex);
break;
case OMX_COLOR_FormatYUV420SemiPlanar:
m = g_slice_new (VideoNegotiationMap);
m->format = GST_VIDEO_FORMAT_NV12;
m->type = param.eColorFormat;
negotiation_map = g_list_append (negotiation_map, m);
GST_DEBUG_OBJECT (self, "Component supports NV12 (%d) at index %d",
param.eColorFormat, param.nIndex);
break;
default:
GST_DEBUG_OBJECT (self,
"Component supports unsupported color format %d at index %d",
param.eColorFormat, param.nIndex);
break;
}
}
old_index = param.nIndex++;
} while (err == OMX_ErrorNone);
return negotiation_map;
}
static gboolean static gboolean
gst_omx_video_enc_set_format (GstVideoEncoder * encoder, gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
GstVideoCodecState * state) GstVideoCodecState * state)
@ -947,12 +1013,9 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
GstOMXVideoEnc *self; GstOMXVideoEnc *self;
GstOMXVideoEncClass *klass; GstOMXVideoEncClass *klass;
gboolean needs_disable = FALSE; gboolean needs_disable = FALSE;
OMX_ERRORTYPE err;
OMX_PARAM_PORTDEFINITIONTYPE port_def; OMX_PARAM_PORTDEFINITIONTYPE port_def;
OMX_VIDEO_PARAM_PORTFORMATTYPE param;
GstVideoInfo *info = &state->info; GstVideoInfo *info = &state->info;
GList *negotiation_map = NULL, *l; GList *negotiation_map = NULL, *l;
gint old_index;
self = GST_OMX_VIDEO_ENC (encoder); self = GST_OMX_VIDEO_ENC (encoder);
klass = GST_OMX_VIDEO_ENC_GET_CLASS (encoder); klass = GST_OMX_VIDEO_ENC_GET_CLASS (encoder);
@ -990,59 +1053,7 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
GST_DEBUG_OBJECT (self, "Encoder drained and disabled"); GST_DEBUG_OBJECT (self, "Encoder drained and disabled");
} }
GST_OMX_INIT_STRUCT (&param); negotiation_map = gst_omx_video_enc_get_supported_colorformats (self);
param.nPortIndex = self->enc_in_port->index;
param.nIndex = 0;
if (info->fps_n == 0) {
param.xFramerate = 0;
} else {
if (!(klass->cdata.hacks & GST_OMX_HACK_VIDEO_FRAMERATE_INTEGER))
param.xFramerate = (info->fps_n << 16) / (info->fps_d);
else
param.xFramerate = (info->fps_n) / (info->fps_d);
}
old_index = -1;
do {
VideoNegotiationMap *m;
err =
gst_omx_component_get_parameter (self->enc,
OMX_IndexParamVideoPortFormat, &param);
/* 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 || err == OMX_ErrorNoMore) {
switch (param.eColorFormat) {
case OMX_COLOR_FormatYUV420Planar:
case OMX_COLOR_FormatYUV420PackedPlanar:
m = g_slice_new0 (VideoNegotiationMap);
m->format = GST_VIDEO_FORMAT_I420;
m->type = param.eColorFormat;
negotiation_map = g_list_append (negotiation_map, m);
GST_DEBUG_OBJECT (self, "Component supports I420 (%d) at index %d",
param.eColorFormat, param.nIndex);
break;
case OMX_COLOR_FormatYUV420SemiPlanar:
m = g_slice_new0 (VideoNegotiationMap);
m->format = GST_VIDEO_FORMAT_NV12;
m->type = param.eColorFormat;
negotiation_map = g_list_append (negotiation_map, m);
GST_DEBUG_OBJECT (self, "Component supports NV12 (%d) at index %d",
param.eColorFormat, param.nIndex);
break;
default:
break;
}
}
old_index = param.nIndex++;
} while (err == OMX_ErrorNone);
if (!negotiation_map) { if (!negotiation_map) {
/* Fallback */ /* Fallback */
switch (info->finfo->format) { switch (info->finfo->format) {
@ -1646,61 +1657,22 @@ static GstCaps *
gst_omx_video_enc_getcaps (GstVideoEncoder * encoder, GstCaps * filter) gst_omx_video_enc_getcaps (GstVideoEncoder * encoder, GstCaps * filter)
{ {
GstOMXVideoEnc *self = GST_OMX_VIDEO_ENC (encoder); GstOMXVideoEnc *self = GST_OMX_VIDEO_ENC (encoder);
GstOMXVideoEncClass *klass = GST_OMX_VIDEO_ENC_GET_CLASS (self); GList *negotiation_map = NULL, *l;
GstOMXPort *port = self->enc_in_port;
OMX_VIDEO_PARAM_PORTFORMATTYPE param;
OMX_ERRORTYPE err;
GstCaps *comp_supported_caps; GstCaps *comp_supported_caps;
gint old_index;
if (!self->enc) if (!self->enc)
return gst_video_encoder_proxy_getcaps (encoder, NULL, filter); return gst_video_encoder_proxy_getcaps (encoder, NULL, filter);
GST_OMX_INIT_STRUCT (&param); negotiation_map = gst_omx_video_enc_get_supported_colorformats (self);
param.nPortIndex = port->index;
param.nIndex = 0;
if (!(klass->cdata.hacks & GST_OMX_HACK_VIDEO_FRAMERATE_INTEGER))
param.xFramerate = (25 << 16) / (1);
else
param.xFramerate = (25) / (1);
old_index = -1;
comp_supported_caps = gst_caps_new_empty (); comp_supported_caps = gst_caps_new_empty ();
do { for (l = negotiation_map; l; l = l->next) {
err = VideoNegotiationMap *map = l->data;
gst_omx_component_get_parameter (self->enc,
OMX_IndexParamVideoPortFormat, &param);
/* 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 || err == OMX_ErrorNoMore) {
switch (param.eColorFormat) {
case OMX_COLOR_FormatYUV420Planar:
case OMX_COLOR_FormatYUV420PackedPlanar:
gst_caps_append_structure (comp_supported_caps, gst_caps_append_structure (comp_supported_caps,
gst_structure_new ("video/x-raw", gst_structure_new ("video/x-raw",
"format", G_TYPE_STRING, "I420", NULL)); "format", G_TYPE_STRING,
GST_DEBUG_OBJECT (self, "Component supports I420 (%d) at index %d", gst_video_format_to_string (map->format), NULL));
param.eColorFormat, param.nIndex);
break;
case OMX_COLOR_FormatYUV420SemiPlanar:
gst_caps_append_structure (comp_supported_caps,
gst_structure_new ("video/x-raw",
"format", G_TYPE_STRING, "NV12", NULL));
GST_DEBUG_OBJECT (self, "Component supports NV12 (%d) at index %d",
param.eColorFormat, param.nIndex);
break;
default:
break;
} }
}
old_index = param.nIndex++;
} while (err == OMX_ErrorNone);
if (!gst_caps_is_empty (comp_supported_caps)) { if (!gst_caps_is_empty (comp_supported_caps)) {
GstCaps *ret = GstCaps *ret =