From 08385fe94425cb935f22dfa8cb399ac5589cbab0 Mon Sep 17 00:00:00 2001 From: Sebastian Dröge Date: Sun, 13 Jul 2014 22:15:18 +0200 Subject: omxaudiodec: Implement setting of fallback channel positions --- omx/gstomxaacdec.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++ omx/gstomxaudiodec.c | 8 +++++++ omx/gstomxaudiodec.h | 1 + omx/gstomxmp3dec.c | 37 ++++++++++++++++++++++++++++++ 4 files changed, 110 insertions(+) diff --git a/omx/gstomxaacdec.c b/omx/gstomxaacdec.c index 2422275..7d81269 100644 --- a/omx/gstomxaacdec.c +++ b/omx/gstomxaacdec.c @@ -35,6 +35,8 @@ static gboolean gst_omx_aac_dec_is_format_change (GstOMXAudioDec * dec, GstOMXPort * port, GstCaps * caps); static gint gst_omx_aac_dec_get_samples_per_frame (GstOMXAudioDec * dec, GstOMXPort * port); +static gboolean gst_omx_aac_dec_get_channel_positions (GstOMXAudioDec * dec, + GstOMXPort * port, GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS]); /* class initialization */ @@ -56,6 +58,8 @@ gst_omx_aac_dec_class_init (GstOMXAACDecClass * klass) GST_DEBUG_FUNCPTR (gst_omx_aac_dec_is_format_change); audiodec_class->get_samples_per_frame = GST_DEBUG_FUNCPTR (gst_omx_aac_dec_get_samples_per_frame); + audiodec_class->get_channel_positions = + GST_DEBUG_FUNCPTR (gst_omx_aac_dec_get_channel_positions); audiodec_class->cdata.default_sink_template_caps = "audio/mpeg, " "mpegversion=(int){2, 4}, " @@ -228,3 +232,63 @@ gst_omx_aac_dec_get_samples_per_frame (GstOMXAudioDec * dec, GstOMXPort * port) { return GST_OMX_AAC_DEC (dec)->spf; } + +static gboolean +gst_omx_aac_dec_get_channel_positions (GstOMXAudioDec * dec, + GstOMXPort * port, GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS]) +{ + OMX_AUDIO_PARAM_PCMMODETYPE pcm_param; + OMX_ERRORTYPE err; + + GST_OMX_INIT_STRUCT (&pcm_param); + pcm_param.nPortIndex = port->index; + err = + gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioPcm, + &pcm_param); + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (dec, "Failed to get PCM parameters: %s (0x%08x)", + gst_omx_error_to_string (err), err); + return FALSE; + } + + /* FIXME: Rather arbitrary values here, based on what we do in gstfaac.c */ + switch (pcm_param.nChannels) { + case 1: + position[0] = GST_AUDIO_CHANNEL_POSITION_MONO; + break; + case 2: + position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT; + position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT; + break; + case 3: + position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER; + position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT; + position[2] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT; + break; + case 4: + position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER; + position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT; + position[2] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT; + position[3] = GST_AUDIO_CHANNEL_POSITION_REAR_CENTER; + break; + case 5: + position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER; + position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT; + position[2] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT; + position[3] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT; + position[4] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT; + break; + case 6: + position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER; + position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT; + position[2] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT; + position[3] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT; + position[4] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT; + position[5] = GST_AUDIO_CHANNEL_POSITION_LFE1; + break; + default: + return FALSE; + } + + return TRUE; +} diff --git a/omx/gstomxaudiodec.c b/omx/gstomxaudiodec.c index ce79013..f894086 100644 --- a/omx/gstomxaudiodec.c +++ b/omx/gstomxaudiodec.c @@ -310,6 +310,7 @@ gst_omx_audio_dec_loop (GstOMXAudioDec * self) OMX_PARAM_PORTDEFINITIONTYPE port_def; OMX_AUDIO_PARAM_PCMMODETYPE pcm_param; GstAudioChannelPosition omx_position[OMX_AUDIO_MAXCHANNELS]; + GstOMXAudioDecClass *klass = GST_OMX_AUDIO_DEC_GET_CLASS (self); gint i; GST_DEBUG_OBJECT (self, "Port settings have changed, updating caps"); @@ -398,6 +399,13 @@ gst_omx_audio_dec_loop (GstOMXAudioDec * self) && omx_position[0] == GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER) omx_position[0] = GST_AUDIO_CHANNEL_POSITION_MONO; + if (omx_position[0] == GST_AUDIO_CHANNEL_POSITION_NONE + && klass->get_channel_positions) { + GST_WARNING_OBJECT (self, + "Failed to get a valid channel layout, trying fallback"); + klass->get_channel_positions (self, self->dec_out_port, omx_position); + } + memcpy (self->position, omx_position, sizeof (omx_position)); gst_audio_channel_positions_to_valid_order (self->position, pcm_param.nChannels); diff --git a/omx/gstomxaudiodec.h b/omx/gstomxaudiodec.h index e7d5a26..aa720d2 100644 --- a/omx/gstomxaudiodec.h +++ b/omx/gstomxaudiodec.h @@ -91,6 +91,7 @@ struct _GstOMXAudioDecClass gboolean (*is_format_change) (GstOMXAudioDec * self, GstOMXPort * port, GstCaps * caps); gboolean (*set_format) (GstOMXAudioDec * self, GstOMXPort * port, GstCaps * caps); gint (*get_samples_per_frame) (GstOMXAudioDec * self, GstOMXPort * port); + gboolean (*get_channel_positions) (GstOMXAudioDec * self, GstOMXPort * port, GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS]); }; GType gst_omx_audio_dec_get_type (void); diff --git a/omx/gstomxmp3dec.c b/omx/gstomxmp3dec.c index 3f84913..5a143d5 100644 --- a/omx/gstomxmp3dec.c +++ b/omx/gstomxmp3dec.c @@ -35,6 +35,8 @@ static gboolean gst_omx_mp3_dec_is_format_change (GstOMXAudioDec * dec, GstOMXPort * port, GstCaps * caps); static gint gst_omx_mp3_dec_get_samples_per_frame (GstOMXAudioDec * dec, GstOMXPort * port); +static gboolean gst_omx_mp3_dec_get_channel_positions (GstOMXAudioDec * dec, + GstOMXPort * port, GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS]); /* class initialization */ @@ -57,6 +59,8 @@ gst_omx_mp3_dec_class_init (GstOMXMP3DecClass * klass) GST_DEBUG_FUNCPTR (gst_omx_mp3_dec_is_format_change); audiodec_class->get_samples_per_frame = GST_DEBUG_FUNCPTR (gst_omx_mp3_dec_get_samples_per_frame); + audiodec_class->get_channel_positions = + GST_DEBUG_FUNCPTR (gst_omx_mp3_dec_get_channel_positions); audiodec_class->cdata.default_sink_template_caps = "audio/mpeg, " "mpegversion=(int)1, " @@ -207,3 +211,36 @@ gst_omx_mp3_dec_get_samples_per_frame (GstOMXAudioDec * dec, GstOMXPort * port) { return GST_OMX_MP3_DEC (dec)->spf; } + +static gboolean +gst_omx_mp3_dec_get_channel_positions (GstOMXAudioDec * dec, + GstOMXPort * port, GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS]) +{ + OMX_AUDIO_PARAM_PCMMODETYPE pcm_param; + OMX_ERRORTYPE err; + + GST_OMX_INIT_STRUCT (&pcm_param); + pcm_param.nPortIndex = port->index; + err = + gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioPcm, + &pcm_param); + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (dec, "Failed to get PCM parameters: %s (0x%08x)", + gst_omx_error_to_string (err), err); + return FALSE; + } + + switch (pcm_param.nChannels) { + case 1: + position[0] = GST_AUDIO_CHANNEL_POSITION_MONO; + break; + case 2: + position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT; + position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT; + break; + default: + return FALSE; + } + + return TRUE; +} -- cgit v1.2.3