summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2014-07-13 22:15:18 +0200
committerSebastian Dröge <sebastian@centricular.com>2014-07-13 22:15:44 +0200
commit08385fe94425cb935f22dfa8cb399ac5589cbab0 (patch)
tree9158a65332bab8c765af8400b796ce3d8a786433
parent03cf0bc9a40c44e35add8c8a139cc0e954d29a6e (diff)
omxaudiodec: Implement setting of fallback channel positions
-rw-r--r--omx/gstomxaacdec.c64
-rw-r--r--omx/gstomxaudiodec.c8
-rw-r--r--omx/gstomxaudiodec.h1
-rw-r--r--omx/gstomxmp3dec.c37
4 files changed, 110 insertions, 0 deletions
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;
+}