2 * Copyright (C) 2014, Sebastian Dröge <sebastian@centricular.com>
3 * Copyright (C) 2014, LG Electronics, Inc. <jun.ji@lge.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation
8 * version 2.1 of the License.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #include "gstomxamrdec.h"
29 GST_DEBUG_CATEGORY_STATIC (gst_omx_amr_dec_debug_category);
30 #define GST_CAT_DEFAULT gst_omx_amr_dec_debug_category
33 static gboolean gst_omx_amr_dec_set_format (GstOMXAudioDec * dec,
34 GstOMXPort * port, GstCaps * caps);
35 static gboolean gst_omx_amr_dec_is_format_change (GstOMXAudioDec * dec,
36 GstOMXPort * port, GstCaps * caps);
37 static gint gst_omx_amr_dec_get_samples_per_frame (GstOMXAudioDec * dec,
39 static gboolean gst_omx_amr_dec_get_channel_positions (GstOMXAudioDec * dec,
40 GstOMXPort * port, GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS]);
42 /* class initialization */
45 GST_DEBUG_CATEGORY_INIT (gst_omx_amr_dec_debug_category, "omxamrdec", 0, \
46 "debug category for gst-omx amr audio decoder");
48 G_DEFINE_TYPE_WITH_CODE (GstOMXAMRDec, gst_omx_amr_dec,
49 GST_TYPE_OMX_AUDIO_DEC, DEBUG_INIT);
52 gst_omx_amr_dec_class_init (GstOMXAMRDecClass * klass)
54 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
55 GstOMXAudioDecClass *audiodec_class = GST_OMX_AUDIO_DEC_CLASS (klass);
57 audiodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_amr_dec_set_format);
58 audiodec_class->is_format_change =
59 GST_DEBUG_FUNCPTR (gst_omx_amr_dec_is_format_change);
60 audiodec_class->get_samples_per_frame =
61 GST_DEBUG_FUNCPTR (gst_omx_amr_dec_get_samples_per_frame);
62 audiodec_class->get_channel_positions =
63 GST_DEBUG_FUNCPTR (gst_omx_amr_dec_get_channel_positions);
65 audiodec_class->cdata.default_sink_template_caps =
66 "audio/AMR, rate=(int)8000, channels=(int)1; "
67 "audio/AMR-WB, rate=(int)16000, channels=(int)1";
69 gst_element_class_set_static_metadata (element_class,
70 "OpenMAX AMR Audio Decoder",
71 "Codec/Decoder/Audio/Hardware",
72 "Decode AMR audio streams",
73 "Sebastian Dröge <sebastian@centricular.com>");
75 gst_omx_set_default_role (&audiodec_class->cdata, "audio_decoder.amrnb");
79 gst_omx_amr_dec_init (GstOMXAMRDec * self)
85 gst_omx_amr_dec_set_format (GstOMXAudioDec * dec, GstOMXPort * port,
88 GstOMXAMRDec *self = GST_OMX_AMR_DEC (dec);
89 OMX_PARAM_PORTDEFINITIONTYPE port_def;
90 OMX_AUDIO_PARAM_AMRTYPE amr_param;
95 gst_omx_port_get_port_definition (port, &port_def);
96 port_def.format.audio.eEncoding = OMX_AUDIO_CodingAMR; /* not tested for AMRWB */
97 err = gst_omx_port_update_port_definition (port, &port_def);
98 if (err != OMX_ErrorNone) {
99 GST_ERROR_OBJECT (self,
100 "Failed to set AMR format on component: %s (0x%08x)",
101 gst_omx_error_to_string (err), err);
105 GST_OMX_INIT_STRUCT (&amr_param);
106 amr_param.nPortIndex = port->index;
109 gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioAmr,
111 if (err != OMX_ErrorNone) {
112 GST_ERROR_OBJECT (self,
113 "Failed to get AMR parameters from component: %s (0x%08x)",
114 gst_omx_error_to_string (err), err);
118 s = gst_caps_get_structure (caps, 0);
120 if (!gst_structure_get_int (s, "rate", &rate) ||
121 !gst_structure_get_int (s, "channels", &channels)) {
122 GST_ERROR_OBJECT (self, "Incomplete caps");
129 self->spf = 160; /* (8000/50) */
130 else if (rate == 16000)
131 self->spf = 320; /* (16000/50) */
133 amr_param.nChannels = channels;
134 amr_param.eAMRBandMode = 0; /*FIXME: It may require a specific value */
135 amr_param.eAMRDTXMode = 0;
136 amr_param.eAMRFrameFormat = 0;
139 gst_omx_component_set_parameter (dec->dec, OMX_IndexParamAudioAmr,
141 if (err != OMX_ErrorNone) {
142 GST_ERROR_OBJECT (self, "Error setting AMR parameters: %s (0x%08x)",
143 gst_omx_error_to_string (err), err);
151 gst_omx_amr_dec_is_format_change (GstOMXAudioDec * dec, GstOMXPort * port,
154 GstOMXAMRDec *self = GST_OMX_AMR_DEC (dec);
155 OMX_AUDIO_PARAM_AMRTYPE amr_param;
160 GST_OMX_INIT_STRUCT (&amr_param);
161 amr_param.nPortIndex = port->index;
164 gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioAmr,
166 if (err != OMX_ErrorNone) {
167 GST_ERROR_OBJECT (self,
168 "Failed to get AMR parameters from component: %s (0x%08x)",
169 gst_omx_error_to_string (err), err);
173 s = gst_caps_get_structure (caps, 0);
175 if (!gst_structure_get_int (s, "rate", &rate) ||
176 !gst_structure_get_int (s, "channels", &channels)) {
177 GST_ERROR_OBJECT (self, "Incomplete caps");
181 if (self->rate != rate)
184 if (amr_param.nChannels != channels)
191 gst_omx_amr_dec_get_samples_per_frame (GstOMXAudioDec * dec, GstOMXPort * port)
193 return GST_OMX_AMR_DEC (dec)->spf;
197 gst_omx_amr_dec_get_channel_positions (GstOMXAudioDec * dec,
198 GstOMXPort * port, GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS])
200 OMX_AUDIO_PARAM_PCMMODETYPE pcm_param;
203 GST_OMX_INIT_STRUCT (&pcm_param);
204 pcm_param.nPortIndex = port->index;
206 gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioPcm,
208 if (err != OMX_ErrorNone) {
209 GST_ERROR_OBJECT (dec, "Failed to get PCM parameters: %s (0x%08x)",
210 gst_omx_error_to_string (err), err);
215 g_return_val_if_fail (pcm_param.nChannels == 1, FALSE); /* AMR supports only mono */
217 position[0] = GST_AUDIO_CHANNEL_POSITION_MONO;