omxvideodec: New hack for QCOM to recreate the component instead of reconfiguring it on caps changes

This commit is contained in:
Sebastian Dröge 2011-09-27 14:15:06 +02:00
parent a7f77e22a4
commit 792cdb7d1f
3 changed files with 47 additions and 4 deletions

View file

@ -1898,6 +1898,8 @@ gst_omx_parse_hacks (gchar ** hacks)
hacks_flags |= GST_OMX_HACK_SYNCFRAME_FLAG_NOT_USED; hacks_flags |= GST_OMX_HACK_SYNCFRAME_FLAG_NOT_USED;
else if (g_str_equal (*hacks, "no-noffset-reset")) else if (g_str_equal (*hacks, "no-noffset-reset"))
hacks_flags |= GST_OMX_HACK_NO_NOFFSET_RESET; hacks_flags |= GST_OMX_HACK_NO_NOFFSET_RESET;
else if (g_str_equal (*hacks, "no-component-reconfigure"))
hacks_flags |= GST_OMX_HACK_NO_COMPONENT_RECONFIGURE;
else else
GST_WARNING ("Unknown hack: %s", *hacks); GST_WARNING ("Unknown hack: %s", *hacks);
hacks++; hacks++;

View file

@ -59,6 +59,10 @@ G_BEGIN_DECLS
* Happens with Qualcomm's OpenMAX implementation. * Happens with Qualcomm's OpenMAX implementation.
*/ */
#define GST_OMX_HACK_NO_NOFFSET_RESET G_GUINT64_CONSTANT (0x0000000000000010) #define GST_OMX_HACK_NO_NOFFSET_RESET G_GUINT64_CONSTANT (0x0000000000000010)
/* If the component needs to be re-created if the caps change.
* Happens with Qualcomm's OpenMAX implementation.
*/
#define GST_OMX_HACK_NO_COMPONENT_RECONFIGURE G_GUINT64_CONSTANT (0x0000000000000020)
typedef struct _GstOMXCore GstOMXCore; typedef struct _GstOMXCore GstOMXCore;

View file

@ -250,6 +250,8 @@ gst_omx_video_dec_open (GstOMXVideoDec * self)
{ {
GstOMXVideoDecClass *klass = GST_OMX_VIDEO_DEC_GET_CLASS (self); GstOMXVideoDecClass *klass = GST_OMX_VIDEO_DEC_GET_CLASS (self);
GST_DEBUG_OBJECT (self, "Opening decoder");
self->component = self->component =
gst_omx_component_new (GST_OBJECT_CAST (self), klass->core_name, gst_omx_component_new (GST_OBJECT_CAST (self), klass->core_name,
klass->component_name, klass->component_role, klass->hacks); klass->component_name, klass->component_role, klass->hacks);
@ -270,6 +272,8 @@ gst_omx_video_dec_open (GstOMXVideoDec * self)
if (!self->in_port || !self->out_port) if (!self->in_port || !self->out_port)
return FALSE; return FALSE;
GST_DEBUG_OBJECT (self, "Opened decoder");
return TRUE; return TRUE;
} }
@ -278,6 +282,8 @@ gst_omx_video_dec_close (GstOMXVideoDec * self)
{ {
OMX_STATETYPE state; OMX_STATETYPE state;
GST_DEBUG_OBJECT (self, "Closing decoder");
state = gst_omx_component_get_state (self->component, 0); state = gst_omx_component_get_state (self->component, 0);
if (state > OMX_StateLoaded || state == OMX_StateInvalid) { if (state > OMX_StateLoaded || state == OMX_StateInvalid) {
gst_omx_component_set_state (self->component, OMX_StateLoaded); gst_omx_component_set_state (self->component, OMX_StateLoaded);
@ -293,6 +299,10 @@ gst_omx_video_dec_close (GstOMXVideoDec * self)
gst_omx_component_free (self->component); gst_omx_component_free (self->component);
self->component = NULL; self->component = NULL;
self->started = FALSE;
GST_DEBUG_OBJECT (self, "Closed decoder");
return TRUE; return TRUE;
} }
@ -790,6 +800,8 @@ gst_omx_video_dec_stop (GstBaseVideoDecoder * decoder)
self = GST_OMX_VIDEO_DEC (decoder); self = GST_OMX_VIDEO_DEC (decoder);
GST_DEBUG_OBJECT (self, "Stopping decoder");
gst_pad_stop_task (GST_BASE_VIDEO_CODEC_SRC_PAD (decoder)); gst_pad_stop_task (GST_BASE_VIDEO_CODEC_SRC_PAD (decoder));
if (gst_omx_component_get_state (self->component, 0) > OMX_StateIdle) if (gst_omx_component_get_state (self->component, 0) > OMX_StateIdle)
@ -802,6 +814,8 @@ gst_omx_video_dec_stop (GstBaseVideoDecoder * decoder)
gst_buffer_replace (&self->codec_data, NULL); gst_buffer_replace (&self->codec_data, NULL);
GST_DEBUG_OBJECT (self, "Stopped decoder");
return TRUE; return TRUE;
} }
@ -965,11 +979,32 @@ gst_omx_video_dec_set_format (GstBaseVideoDecoder * decoder,
"Already running and caps did not change the format"); "Already running and caps did not change the format");
return TRUE; return TRUE;
} }
if (needs_disable && is_format_change) { if (needs_disable && is_format_change) {
if (gst_omx_port_manual_reconfigure (self->in_port, TRUE) != OMX_ErrorNone) if (klass->hacks & GST_OMX_HACK_NO_COMPONENT_RECONFIGURE) {
return FALSE; GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (self);
if (gst_omx_port_set_enabled (self->in_port, FALSE) != OMX_ErrorNone) gst_omx_video_dec_stop (GST_BASE_VIDEO_DECODER (self));
return FALSE; gst_omx_video_dec_close (self);
/* FIXME: Workaround for
* https://bugzilla.gnome.org/show_bug.cgi?id=654529
*/
g_list_foreach (GST_BASE_VIDEO_CODEC (self)->frames,
(GFunc) gst_base_video_codec_free_frame, NULL);
g_list_free (GST_BASE_VIDEO_CODEC (self)->frames);
GST_BASE_VIDEO_CODEC (self)->frames = NULL;
GST_BASE_VIDEO_CODEC_STREAM_LOCK (self);
if (!gst_omx_video_dec_open (self))
return FALSE;
needs_disable = FALSE;
} else {
if (gst_omx_port_manual_reconfigure (self->in_port,
TRUE) != OMX_ErrorNone)
return FALSE;
if (gst_omx_port_set_enabled (self->in_port, FALSE) != OMX_ErrorNone)
return FALSE;
}
} }
port_def.format.video.nFrameWidth = state->width; port_def.format.video.nFrameWidth = state->width;
@ -1078,6 +1113,8 @@ gst_omx_video_dec_reset (GstBaseVideoDecoder * decoder)
gst_pad_start_task (GST_BASE_VIDEO_CODEC_SRC_PAD (self), gst_pad_start_task (GST_BASE_VIDEO_CODEC_SRC_PAD (self),
(GstTaskFunction) gst_omx_video_dec_loop, decoder); (GstTaskFunction) gst_omx_video_dec_loop, decoder);
GST_DEBUG_OBJECT (self, "Reset decoder");
return TRUE; return TRUE;
} }