blob: 0f4fd6bdbd6d16cf0c131feef449e377c325cfa0 [file] [log] [blame]
Ho-Eun Ryu0592b1b2009-10-16 15:26:16 +09001/*
Ho-Eun Ryud6e90a72009-10-28 19:45:35 +09002 * Copyright (c) 2009 Wind River Systems, Inc.
3 *
4 * The right to copy, distribute, modify, or otherwise make use
5 * of this software may be licensed only pursuant to the terms
6 * of an applicable Wind River license agreement.
Ho-Eun Ryu0592b1b2009-10-16 15:26:16 +09007 */
8
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +09009#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <unistd.h>
13
14#include <OMX_Core.h>
15
Ho-Eun Ryu4375deb2009-10-27 09:49:25 +090016#include <audio_parser.h>
17
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +090018#include <cmodule.h>
19#include <portaudio.h>
20#include <componentbase.h>
21
Ho-Eun Ryu52045a32009-10-21 18:10:33 +090022#include <pv_omxcore.h>
23
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +090024#ifdef __cplusplus
25extern "C" {
26#endif
27
28#include <mixaudio.h>
29#include <mixacpaac.h>
30#include <mixacpmp3.h>
31
32#ifdef __cplusplus
33} /* extern "C" */
34#endif
35
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +090036#include "sst.h"
37
Ho-Eun Ryu4375deb2009-10-27 09:49:25 +090038#define LOG_NDEBUG 1
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +090039
40#define LOG_TAG "mrst_sst"
41#include <log.h>
42
43/*
44 * constructor & destructor
45 */
46MrstSstComponent::MrstSstComponent()
47{
48 LOGV("%s(): enter\n", __func__);
49
50 LOGV("%s(),%d: exit (ret = void)\n", __func__, __LINE__);
51}
52
53MrstSstComponent::~MrstSstComponent()
54{
55 LOGV("%s(): enter\n", __func__);
56
57 LOGV("%s(),%d: exit (ret = void)\n", __func__, __LINE__);
58}
59
60/* end of constructor & destructor */
61
62/* core methods & helpers */
63OMX_ERRORTYPE MrstSstComponent::ComponentAllocatePorts(void)
64{
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +090065 PortBase **ports;
66
Ho-Eun Ryu4c6e9282009-10-28 09:13:48 +090067 OMX_U32 codec_port_index, pcm_port_index;
68 OMX_DIRTYPE codec_port_dir, pcm_port_dir;
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +090069
70 OMX_PORT_PARAM_TYPE portparam;
Ho-Eun Ryu4c6e9282009-10-28 09:13:48 +090071
72 bool isencoder;
73 const char *working_role;
74
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +090075 OMX_U32 i;
76 OMX_ERRORTYPE ret;
77
78 LOGV("%s(): enter\n", __func__);
79
80 ports = new PortBase *[NR_PORTS];
81 if (!ports)
82 return OMX_ErrorInsufficientResources;
Ho-Eun Ryu4c6e9282009-10-28 09:13:48 +090083
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +090084 this->nr_ports = NR_PORTS;
85 this->ports = ports;
86
Ho-Eun Ryu4c6e9282009-10-28 09:13:48 +090087 working_role = GetWorkingRole();
88 if (!strncmp(working_role, "audio_decoder", strlen("audio_decoder")))
89 isencoder = false;
90 else
91 isencoder = true;
92
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +090093 if (isencoder) {
94 pcm_port_index = INPORT_INDEX;
Ho-Eun Ryu4c6e9282009-10-28 09:13:48 +090095 codec_port_index = OUTPORT_INDEX;
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +090096 pcm_port_dir = OMX_DirInput;
Ho-Eun Ryu4c6e9282009-10-28 09:13:48 +090097 codec_port_dir = OMX_DirOutput;
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +090098 }
99 else {
Ho-Eun Ryu4c6e9282009-10-28 09:13:48 +0900100 codec_port_index = INPORT_INDEX;
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900101 pcm_port_index = OUTPORT_INDEX;
Ho-Eun Ryu4c6e9282009-10-28 09:13:48 +0900102 codec_port_dir = OMX_DirInput;
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900103 pcm_port_dir = OMX_DirOutput;
104 }
105
Ho-Eun Ryu4c6e9282009-10-28 09:13:48 +0900106 working_role = strpbrk(working_role, ".");
107 if (!working_role)
108 return OMX_ErrorUndefined;
109 working_role++;
110
111 if (!strcmp(working_role, "mp3")) {
112 ret = __AllocateMp3Port(codec_port_index, codec_port_dir);
113 coding_type = OMX_AUDIO_CodingMP3;
114 }
115 else if(!strcmp(working_role, "aac")) {
116 ret = __AllocateAacPort(codec_port_index, codec_port_dir);
117 coding_type = OMX_AUDIO_CodingAAC;
118 }
119 else
120 ret = OMX_ErrorUndefined;
121
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900122 if (ret != OMX_ErrorNone)
123 goto free_ports;
124
125 ret = __AllocatePcmPort(pcm_port_index, pcm_port_dir);
126 if (ret != OMX_ErrorNone)
Ho-Eun Ryu4c6e9282009-10-28 09:13:48 +0900127 goto free_codecport;
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900128
129 /* OMX_PORT_PARAM_TYPE */
130 memset(&portparam, 0, sizeof(portparam));
131 SetTypeHeader(&portparam, sizeof(portparam));
132 portparam.nPorts = NR_PORTS;
133 portparam.nStartPortNumber = INPORT_INDEX;
134
135 memcpy(&this->portparam, &portparam, sizeof(portparam));
136 /* end of OMX_PORT_PARAM_TYPE */
137
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900138 codec_mode = isencoder ? MIX_CODING_ENCODE : MIX_CODING_DECODE;
139
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900140 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, OMX_ErrorNone);
141 return OMX_ErrorNone;
142
Ho-Eun Ryu4c6e9282009-10-28 09:13:48 +0900143free_codecport:
144 delete ports[codec_port_index];
145 ports[codec_port_index] = NULL;
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900146
147free_ports:
Ho-Eun Ryu4c6e9282009-10-28 09:13:48 +0900148 coding_type = OMX_AUDIO_CodingUnused;
149
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900150 delete []ports;
Ho-Eun Ryu4c6e9282009-10-28 09:13:48 +0900151 ports = NULL;
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900152
Ho-Eun Ryu4c6e9282009-10-28 09:13:48 +0900153 this->ports = NULL;
154 this->nr_ports = 0;
Ho-Eun Ryuf796f982009-10-19 17:01:09 +0900155
156 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
157 return ret;
158}
159
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900160OMX_ERRORTYPE MrstSstComponent::__AllocateMp3Port(OMX_U32 port_index,
161 OMX_DIRTYPE dir)
162{
163 PortMp3 *mp3port;
164
165 OMX_PARAM_PORTDEFINITIONTYPE mp3portdefinition;
166 OMX_AUDIO_PARAM_MP3TYPE mp3portparam;
167 OMX_U32 i;
168
169 LOGV("%s(): enter\n", __func__);
170
171 ports[port_index] = new PortMp3;
172 if (!ports[port_index]) {
173 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
174 OMX_ErrorInsufficientResources);
175 return OMX_ErrorInsufficientResources;
176 }
177
178 mp3port = static_cast<PortMp3 *>(this->ports[port_index]);
179
180 /* MP3 - OMX_PARAM_PORTDEFINITIONTYPE */
181 memset(&mp3portdefinition, 0, sizeof(mp3portdefinition));
182 SetTypeHeader(&mp3portdefinition, sizeof(mp3portdefinition));
183 mp3portdefinition.nPortIndex = port_index;
184 mp3portdefinition.eDir = dir;
185 if (dir == OMX_DirInput) {
186 mp3portdefinition.nBufferCountActual = INPORT_MP3_ACTUAL_BUFFER_COUNT;
187 mp3portdefinition.nBufferCountMin = INPORT_MP3_MIN_BUFFER_COUNT;
188 mp3portdefinition.nBufferSize = INPORT_MP3_BUFFER_SIZE;
189 }
190 else {
191 mp3portdefinition.nBufferCountActual = OUTPORT_MP3_ACTUAL_BUFFER_COUNT;
192 mp3portdefinition.nBufferCountMin = OUTPORT_MP3_MIN_BUFFER_COUNT;
193 mp3portdefinition.nBufferSize = OUTPORT_MP3_BUFFER_SIZE;
194 }
195 mp3portdefinition.bEnabled = OMX_TRUE;
196 mp3portdefinition.bPopulated = OMX_FALSE;
197 mp3portdefinition.eDomain = OMX_PortDomainAudio;
Ho-Eun Ryucf8770a2009-10-30 17:10:55 +0900198 mp3portdefinition.format.audio.cMIMEType = (char *)"audio/mpeg";
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900199 mp3portdefinition.format.audio.pNativeRender = NULL;
200 mp3portdefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
201 mp3portdefinition.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
202 mp3portdefinition.bBuffersContiguous = OMX_FALSE;
203 mp3portdefinition.nBufferAlignment = 0;
204
205 mp3port->SetPortDefinition(&mp3portdefinition, true);
206
207 /* end of MP3 - OMX_PARAM_PORTDEFINITIONTYPE */
208
209 /* OMX_AUDIO_PARAM_MP3TYPE */
210 memset(&mp3portparam, 0, sizeof(mp3portparam));
211 SetTypeHeader(&mp3portparam, sizeof(mp3portparam));
212 mp3portparam.nPortIndex = port_index;
213 mp3portparam.nChannels = 2;
214 mp3portparam.nBitRate = 0;
215 mp3portparam.nSampleRate = 0;
216 mp3portparam.nAudioBandWidth = 0;
217 mp3portparam.eChannelMode = OMX_AUDIO_ChannelModeStereo;
218 mp3portparam.eFormat = OMX_AUDIO_MP3StreamFormatMP1Layer3;
219
220 mp3port->SetPortMp3Param(&mp3portparam, true);
221 /* end of OMX_AUDIO_PARAM_MP3TYPE */
222
223 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, OMX_ErrorNone);
224 return OMX_ErrorNone;
225}
226
Ho-Eun Ryuf796f982009-10-19 17:01:09 +0900227OMX_ERRORTYPE MrstSstComponent::__AllocateAacPort(OMX_U32 port_index,
228 OMX_DIRTYPE dir)
229{
230 PortAac *aacport;
231
232 OMX_PARAM_PORTDEFINITIONTYPE aacportdefinition;
233 OMX_AUDIO_PARAM_AACPROFILETYPE aacportparam;
234 OMX_U32 i;
235
236 LOGV("%s(): enter\n", __func__);
237
238 ports[port_index] = new PortAac;
239 if (!ports[port_index]) {
240 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
241 OMX_ErrorInsufficientResources);
242 return OMX_ErrorInsufficientResources;
243 }
244
245 aacport = static_cast<PortAac *>(this->ports[port_index]);
246
247 /* AAC - OMX_PARAM_PORTDEFINITIONTYPE */
248 memset(&aacportdefinition, 0, sizeof(aacportdefinition));
249 SetTypeHeader(&aacportdefinition, sizeof(aacportdefinition));
250 aacportdefinition.nPortIndex = port_index;
251 aacportdefinition.eDir = dir;
252 if (dir == OMX_DirInput) {
253 aacportdefinition.nBufferCountActual = INPORT_AAC_ACTUAL_BUFFER_COUNT;
254 aacportdefinition.nBufferCountMin = INPORT_AAC_MIN_BUFFER_COUNT;
255 aacportdefinition.nBufferSize = INPORT_AAC_BUFFER_SIZE;
256 }
257 else {
258 aacportdefinition.nBufferCountActual = OUTPORT_AAC_ACTUAL_BUFFER_COUNT;
259 aacportdefinition.nBufferCountMin = OUTPORT_AAC_MIN_BUFFER_COUNT;
260 aacportdefinition.nBufferSize = OUTPORT_AAC_BUFFER_SIZE;
261 }
262 aacportdefinition.bEnabled = OMX_TRUE;
263 aacportdefinition.bPopulated = OMX_FALSE;
264 aacportdefinition.eDomain = OMX_PortDomainAudio;
Ho-Eun Ryufe974a52009-10-28 15:25:33 +0900265 aacportdefinition.format.audio.cMIMEType = (char *)"audio/mp4";
Ho-Eun Ryuf796f982009-10-19 17:01:09 +0900266 aacportdefinition.format.audio.pNativeRender = NULL;
267 aacportdefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
268 aacportdefinition.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
269 aacportdefinition.bBuffersContiguous = OMX_FALSE;
270 aacportdefinition.nBufferAlignment = 0;
271
272 aacport->SetPortDefinition(&aacportdefinition, true);
273
274 /* end of AAC - OMX_PARAM_PORTDEFINITIONTYPE */
275
276 /* OMX_AUDIO_PARAM_AACPROFILETYPE */
277 memset(&aacportparam, 0, sizeof(aacportparam));
278 SetTypeHeader(&aacportparam, sizeof(aacportparam));
279 aacportparam.nPortIndex = port_index;
280 aacportparam.nChannels = 2;
281 aacportparam.nBitRate = 0;
282 aacportparam.nSampleRate = 0;
283 aacportparam.nAudioBandWidth = 0;
284 aacportparam.nFrameLength = 1024; /* default for LC */
285 aacportparam.nAACtools = OMX_AUDIO_AACToolNone;
286 aacportparam.nAACERtools = OMX_AUDIO_AACERNone;
287 aacportparam.eAACProfile = OMX_AUDIO_AACObjectLC;
288 aacportparam.eChannelMode = OMX_AUDIO_ChannelModeStereo;
289
290 aacport->SetPortAacParam(&aacportparam, true);
291 /* end of OMX_AUDIO_PARAM_AACPROFILETYPE */
292
293 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, OMX_ErrorNone);
294 return OMX_ErrorNone;
295}
296
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900297OMX_ERRORTYPE MrstSstComponent::__AllocatePcmPort(OMX_U32 port_index,
298 OMX_DIRTYPE dir)
299{
300 PortPcm *pcmport;
301
302 OMX_PARAM_PORTDEFINITIONTYPE pcmportdefinition;
303 OMX_AUDIO_PARAM_PCMMODETYPE pcmportparam;
304 OMX_U32 i;
305
306 LOGV("%s(): enter\n", __func__);
307
308 ports[port_index] = new PortPcm;
309 if (!ports[port_index]) {
310 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
311 OMX_ErrorInsufficientResources);
312 return OMX_ErrorInsufficientResources;
313 }
314 pcmport = static_cast<PortPcm *>(this->ports[port_index]);
315
316 /* PCM - OMX_PARAM_PORTDEFINITIONTYPE */
317 memset(&pcmportdefinition, 0, sizeof(pcmportdefinition));
318 SetTypeHeader(&pcmportdefinition, sizeof(pcmportdefinition));
319 pcmportdefinition.nPortIndex = port_index;
320 pcmportdefinition.eDir = dir;
321 if (dir == OMX_DirInput) {
322 pcmportdefinition.nBufferCountActual = INPORT_PCM_ACTUAL_BUFFER_COUNT;
323 pcmportdefinition.nBufferCountMin = INPORT_PCM_MIN_BUFFER_COUNT;
324 pcmportdefinition.nBufferSize = INPORT_PCM_BUFFER_SIZE;
325 }
326 else {
327 pcmportdefinition.nBufferCountActual = OUTPORT_PCM_ACTUAL_BUFFER_COUNT;
328 pcmportdefinition.nBufferCountMin = OUTPORT_PCM_MIN_BUFFER_COUNT;
329 pcmportdefinition.nBufferSize = OUTPORT_PCM_BUFFER_SIZE;
330 }
331 pcmportdefinition.bEnabled = OMX_TRUE;
332 pcmportdefinition.bPopulated = OMX_FALSE;
333 pcmportdefinition.eDomain = OMX_PortDomainAudio;
Ho-Eun Ryucf8770a2009-10-30 17:10:55 +0900334 pcmportdefinition.format.audio.cMIMEType = (char *)"raw";
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900335 pcmportdefinition.format.audio.pNativeRender = NULL;
336 pcmportdefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
337 pcmportdefinition.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
338 pcmportdefinition.bBuffersContiguous = OMX_FALSE;
339 pcmportdefinition.nBufferAlignment = 0;
340
341 pcmport->SetPortDefinition(&pcmportdefinition, true);
342 /* end of PCM - OMX_PARAM_PORTDEFINITIONTYPE */
343
344 /* OMX_AUDIO_PARAM_PCMMODETYPE */
345 memset(&pcmportparam, 0, sizeof(pcmportparam));
346 SetTypeHeader(&pcmportparam, sizeof(pcmportparam));
347 pcmportparam.nPortIndex = port_index;
348 pcmportparam.nChannels = 2;
349 pcmportparam.eNumData = OMX_NumericalDataUnsigned;
350 pcmportparam.eEndian = OMX_EndianLittle;
351 pcmportparam.bInterleaved = OMX_FALSE;
352 pcmportparam.nBitPerSample = 16;
353 pcmportparam.nSamplingRate = 44100;
354 pcmportparam.ePCMMode = OMX_AUDIO_PCMModeLinear;
355 pcmportparam.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
356 pcmportparam.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
357
358 pcmport->SetPortPcmParam(&pcmportparam, true);
359 /* end of OMX_AUDIO_PARAM_PCMMODETYPE */
360
361 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, OMX_ErrorNone);
362 return OMX_ErrorNone;
363}
364
365/* end of core methods & helpers */
366
367/*
368 * component methods & helpers
369 */
370/* Get/SetParameter */
371OMX_ERRORTYPE MrstSstComponent::ComponentGetParameter(
372 OMX_INDEXTYPE nParamIndex,
373 OMX_PTR pComponentParameterStructure)
374{
375 OMX_ERRORTYPE ret = OMX_ErrorNone;
376
377 LOGV("%s(): enter (index = 0x%08x)\n", __func__, nParamIndex);
378
379 switch (nParamIndex) {
380 case OMX_IndexParamAudioPortFormat: {
381 OMX_AUDIO_PARAM_PORTFORMATTYPE *p =
382 (OMX_AUDIO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure;
383 OMX_U32 index = p->nPortIndex;
384 PortAudio *port = NULL;
385
386 ret = CheckTypeHeader(p, sizeof(*p));
387 if (ret != OMX_ErrorNone) {
388 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
389 return ret;
390 }
391
392 if (index < nr_ports)
393 port = static_cast<PortAudio *>(ports[index]);
394
395 if (!port) {
396 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
397 OMX_ErrorBadPortIndex);
398 return OMX_ErrorBadPortIndex;
399 }
400
401 memcpy(p, port->GetPortAudioParam(), sizeof(*p));
402 break;
403 }
404 case OMX_IndexParamAudioPcm: {
405 OMX_AUDIO_PARAM_PCMMODETYPE *p =
406 (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
407 OMX_U32 index = p->nPortIndex;
408 PortPcm *port = NULL;
409
Ho-Eun Ryuf796f982009-10-19 17:01:09 +0900410 if (strcmp(GetWorkingRole(), "audio_decoder.mp3") &&
411 strcmp(GetWorkingRole(), "audio_decoder.aac")) {
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900412 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
413 OMX_ErrorUnsupportedIndex);
414 return OMX_ErrorUnsupportedIndex;
415 }
416
417 ret = CheckTypeHeader(p, sizeof(*p));
418 if (ret != OMX_ErrorNone) {
419 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
420 return ret;
421 }
422
423 if (index < nr_ports)
424 port = static_cast<PortPcm *>(ports[index]);
425
426 if (!port) {
427 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
428 OMX_ErrorBadPortIndex);
429 return OMX_ErrorBadPortIndex;
430 }
431
432 memcpy(p, port->GetPortPcmParam(), sizeof(*p));
433 break;
434 }
435 case OMX_IndexParamAudioMp3: {
436 OMX_AUDIO_PARAM_MP3TYPE *p =
437 (OMX_AUDIO_PARAM_MP3TYPE *)pComponentParameterStructure;
438 OMX_U32 index = p->nPortIndex;
439 PortMp3 *port = NULL;
440
441 if (strcmp(GetWorkingRole(), "audio_decoder.mp3")) {
442 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
443 OMX_ErrorUnsupportedIndex);
444 return OMX_ErrorUnsupportedIndex;
445 }
446
447 ret = CheckTypeHeader(p, sizeof(*p));
448 if (ret != OMX_ErrorNone) {
449 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
450 return ret;
451 }
452
453 if (index < nr_ports)
454 port = static_cast<PortMp3 *>(ports[index]);
455
456 if (!port) {
457 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
458 OMX_ErrorBadPortIndex);
459 return OMX_ErrorBadPortIndex;
460 }
461
462 memcpy(p, port->GetPortMp3Param(), sizeof(*p));
463 break;
464 }
Ho-Eun Ryuf796f982009-10-19 17:01:09 +0900465 case OMX_IndexParamAudioAac: {
466 OMX_AUDIO_PARAM_AACPROFILETYPE *p =
467 (OMX_AUDIO_PARAM_AACPROFILETYPE *)pComponentParameterStructure;
468 OMX_U32 index = p->nPortIndex;
469 PortAac *port = NULL;
470
471 if (strcmp(GetWorkingRole(), "audio_decoder.aac")) {
472 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
473 OMX_ErrorUnsupportedIndex);
474 return OMX_ErrorUnsupportedIndex;
475 }
476
477 ret = CheckTypeHeader(p, sizeof(*p));
478 if (ret != OMX_ErrorNone) {
479 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
480 return ret;
481 }
482
483 if (index < nr_ports)
484 port = static_cast<PortAac *>(ports[index]);
485
486 if (!port) {
487 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
488 OMX_ErrorBadPortIndex);
489 return OMX_ErrorBadPortIndex;
490 }
491
492 memcpy(p, port->GetPortAacParam(), sizeof(*p));
493 break;
494 }
Ho-Eun Ryu52045a32009-10-21 18:10:33 +0900495 case (OMX_INDEXTYPE) PV_OMX_COMPONENT_CAPABILITY_TYPE_INDEX: {
496 PV_OMXComponentCapabilityFlagsType *p =
497 (PV_OMXComponentCapabilityFlagsType *)pComponentParameterStructure;
498
499 p->iIsOMXComponentMultiThreaded = OMX_TRUE;
500 p->iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE;
501 p->iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE;
502 p->iOMXComponentSupportsMovableInputBuffers = OMX_TRUE;
503 p->iOMXComponentUsesNALStartCodes = OMX_TRUE;
504 p->iOMXComponentSupportsPartialFrames = OMX_FALSE;
505 p->iOMXComponentCanHandleIncompleteFrames = OMX_TRUE;
506 p->iOMXComponentUsesFullAVCFrames = OMX_FALSE;
507 break;
508 }
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900509 default:
510 ret = OMX_ErrorUnsupportedIndex;
511 } /* switch */
512
513 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
514 return ret;
515}
516
517OMX_ERRORTYPE MrstSstComponent::ComponentSetParameter(
518 OMX_INDEXTYPE nIndex,
519 OMX_PTR pComponentParameterStructure)
520{
521 OMX_ERRORTYPE ret = OMX_ErrorNone;
522
523 LOGV("%s(): enter (index = 0x%08x)\n", __func__, nIndex);
524
525 switch (nIndex) {
526 case OMX_IndexParamAudioPortFormat: {
527 OMX_AUDIO_PARAM_PORTFORMATTYPE *p =
528 (OMX_AUDIO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure;
529 OMX_U32 index = p->nPortIndex;
530 PortAudio *port = NULL;
531
532 ret = CheckTypeHeader(p, sizeof(*p));
533 if (ret != OMX_ErrorNone) {
534 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
535 return ret;
536 }
537
538 if (index < nr_ports)
539 port = static_cast<PortPcm *>(ports[index]);
540
541 if (!port) {
542 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
543 OMX_ErrorBadPortIndex);
544 return OMX_ErrorBadPortIndex;
545 }
546
547 if (port->IsEnabled()) {
548 OMX_STATETYPE state;
549
550 CBaseGetState((void *)GetComponentHandle(), &state);
551 if (state != OMX_StateLoaded &&
552 state != OMX_StateWaitForResources) {
553 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
554 OMX_ErrorIncorrectStateOperation);
555 return OMX_ErrorIncorrectStateOperation;
556 }
557 }
558
559 ret = port->SetPortAudioParam(p, false);
560 break;
561 }
562 case OMX_IndexParamAudioPcm: {
563 OMX_AUDIO_PARAM_PCMMODETYPE *p =
564 (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
565 OMX_U32 index = p->nPortIndex;
566 PortPcm *port = NULL;
567
Ho-Eun Ryuf796f982009-10-19 17:01:09 +0900568 if (strcmp(GetWorkingRole(), "audio_decoder.mp3") &&
569 strcmp(GetWorkingRole(), "audio_decoder.aac")) {
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900570 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
571 OMX_ErrorUnsupportedIndex);
572 return OMX_ErrorUnsupportedIndex;
573 }
574
575 ret = CheckTypeHeader(p, sizeof(*p));
576 if (ret != OMX_ErrorNone) {
577 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
578 return ret;
579 }
580
581 if (index < nr_ports)
582 port = static_cast<PortPcm *>(ports[index]);
583
584 if (!port) {
585 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
586 OMX_ErrorBadPortIndex);
587 return OMX_ErrorBadPortIndex;
588 }
589
590 if (port->IsEnabled()) {
591 OMX_STATETYPE state;
592
593 CBaseGetState((void *)GetComponentHandle(), &state);
594 if (state != OMX_StateLoaded &&
595 state != OMX_StateWaitForResources) {
596 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
597 OMX_ErrorIncorrectStateOperation);
598 return OMX_ErrorIncorrectStateOperation;
599 }
600 }
601
602 ret = port->SetPortPcmParam(p, false);
603 break;
604 }
605 case OMX_IndexParamAudioMp3: {
606 OMX_AUDIO_PARAM_MP3TYPE *p =
607 (OMX_AUDIO_PARAM_MP3TYPE *)pComponentParameterStructure;
608 OMX_U32 index = p->nPortIndex;
609 PortMp3 *port = NULL;
610
611 if (strcmp(GetWorkingRole(), "audio_decoder.mp3")) {
612 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
613 OMX_ErrorUnsupportedIndex);
614 return OMX_ErrorUnsupportedIndex;
615 }
616
617 ret = CheckTypeHeader(p, sizeof(*p));
618 if (ret != OMX_ErrorNone) {
619 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
620 return ret;
621 }
622
623 if (index < nr_ports)
624 port = static_cast<PortMp3 *>(ports[index]);
625
626 if (!port) {
627 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
628 OMX_ErrorBadPortIndex);
629 return OMX_ErrorBadPortIndex;
630 }
631
632 if (port->IsEnabled()) {
633 OMX_STATETYPE state;
634
635 CBaseGetState((void *)GetComponentHandle(), &state);
636 if (state != OMX_StateLoaded &&
637 state != OMX_StateWaitForResources) {
638 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
639 OMX_ErrorIncorrectStateOperation);
640 return OMX_ErrorIncorrectStateOperation;
641 }
642 }
643
644 ret = port->SetPortMp3Param(p, false);
645 break;
646 }
Ho-Eun Ryuf796f982009-10-19 17:01:09 +0900647 case OMX_IndexParamAudioAac: {
648 OMX_AUDIO_PARAM_AACPROFILETYPE *p =
649 (OMX_AUDIO_PARAM_AACPROFILETYPE *)pComponentParameterStructure;
650 OMX_U32 index = p->nPortIndex;
651 PortAac *port = NULL;
652
653 if (strcmp(GetWorkingRole(), "audio_decoder.aac")) {
654 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
655 OMX_ErrorUnsupportedIndex);
656 return OMX_ErrorUnsupportedIndex;
657 }
658
659 ret = CheckTypeHeader(p, sizeof(*p));
660 if (ret != OMX_ErrorNone) {
661 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
662 return ret;
663 }
664
665 if (index < nr_ports)
666 port = static_cast<PortAac *>(ports[index]);
667
668 if (!port) {
669 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
670 OMX_ErrorBadPortIndex);
671 return OMX_ErrorBadPortIndex;
672 }
673
674 if (port->IsEnabled()) {
675 OMX_STATETYPE state;
676
677 CBaseGetState((void *)GetComponentHandle(), &state);
678 if (state != OMX_StateLoaded &&
679 state != OMX_StateWaitForResources) {
680 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
681 OMX_ErrorIncorrectStateOperation);
682 return OMX_ErrorIncorrectStateOperation;
683 }
684 }
685
686 ret = port->SetPortAacParam(p, false);
687 break;
688 }
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900689 default:
690 ret = OMX_ErrorUnsupportedIndex;
691 } /* switch */
692
693 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
694 return ret;
695}
696
697/* Get/SetConfig */
698OMX_ERRORTYPE MrstSstComponent::ComponentGetConfig(
699 OMX_INDEXTYPE nIndex,
700 OMX_PTR pComponentConfigStructure)
701{
702 OMX_ERRORTYPE ret = OMX_ErrorUnsupportedIndex;
703 LOGV("%s(): enter\n", __func__);
704
705 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
706 return ret;
707}
708
709OMX_ERRORTYPE MrstSstComponent::ComponentSetConfig(
710 OMX_INDEXTYPE nParamIndex,
711 OMX_PTR pComponentConfigStructure)
712{
713 OMX_ERRORTYPE ret = OMX_ErrorUnsupportedIndex;
714 LOGV("%s(): enter\n", __func__);
715
716 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
717 return ret;
718}
719
720/* implement ComponentBase::Processor[*] */
721OMX_ERRORTYPE MrstSstComponent::ProcessorInit(void)
722{
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900723 MixAudio *mix;
724 MixAudioConfigParams *acp;
725 MixIOVec *mixio;
726 OMX_ERRORTYPE oret = OMX_ErrorNone;
727 MIX_RESULT mret;
728
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900729 LOGV("%s(): enter\n", __func__);
730
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900731 g_type_init();
732
733 /* set default parameters */
734 if (coding_type == OMX_AUDIO_CodingMP3)
735 acp = MIX_AUDIOCONFIGPARAMS(mix_acp_mp3_new());
736 else if (coding_type == OMX_AUDIO_CodingAAC)
737 acp = MIX_AUDIOCONFIGPARAMS(mix_acp_aac_new());
738 else {
739 LOGE("%s(),%d: exit, unkown role (ret == 0x%08x)\n",
740 __func__, __LINE__, OMX_ErrorInvalidState);
741 return OMX_ErrorInvalidState;
742 }
743
744 if (codec_mode == MIX_CODING_DECODE)
745 MIX_ACP_DECODEMODE(acp) = MIX_DECODE_DIRECTRENDER;
746 /*
747 else if (codec_mode == MIX_CODING_ENCODE)
748 ;
749 */
750
751 mret = mix_acp_set_streamname(acp, GetWorkingRole());
752 if (!MIX_SUCCEEDED(mret)) {
753 LOGE("%s(),%d: exit, mix_acp_set_streamname failed (ret == 0x%08x)",
754 __func__, __LINE__, mret);
755 mix_params_unref(MIX_PARAMS(acp));
756 return OMX_ErrorInvalidState;
757 }
758
759 mix = mix_audio_new();
760 mret = mix_audio_initialize(mix, codec_mode, NULL, NULL);
761 if (!(MIX_SUCCEEDED(mret))) {
762 LOGE("%s(),%d: exit, mix_audio_initialize failed (ret == 0x%08x)",
763 __func__, __LINE__, mret);
764 mix_params_unref(MIX_PARAMS(acp));
765 return OMX_ErrorInvalidState;
766 }
767
768 mixio = (MixIOVec *)malloc(sizeof(MixIOVec));
769 if (!mixio) {
770 LOGE("%s(),%d: exit, failed to allocate mbuffer (ret == 0x%08x)",
771 __func__, __LINE__, mret);
772 mix_params_unref(MIX_PARAMS(acp));
773 mix_audio_unref(mix);
774 return OMX_ErrorInvalidState;
775 }
776
777 this->mix = mix;
778 this->acp = acp;
779 this->mixio = mixio;
780
781 ibuffercount = 0;
782
783 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, oret);
784 return oret;
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900785}
786
787OMX_ERRORTYPE MrstSstComponent::ProcessorDeinit(void)
788{
789 OMX_ERRORTYPE ret = OMX_ErrorNone;
790 LOGV("%s(): enter\n", __func__);
791
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900792 mix_audio_stop_drop(mix);
793
794 mix_audio_deinitialize(mix);
795
796 mix_acp_unref(acp);
797 mix_audio_unref(mix);
798
799 free(mixio);
800
801 ibuffercount = 0;
802
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900803 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
804 return ret;
805}
806
807OMX_ERRORTYPE MrstSstComponent::ProcessorStart(void)
808{
809 OMX_ERRORTYPE ret = OMX_ErrorNone;
810 LOGV("%s(): enter\n", __func__);
811
812 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
813 return ret;
814}
815
816OMX_ERRORTYPE MrstSstComponent::ProcessorStop(void)
817{
818 OMX_ERRORTYPE ret = OMX_ErrorNone;
819 LOGV("%s(): enter\n", __func__);
820
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900821 mix_audio_stop_drop(mix);
822
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900823 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
824 return ret;
825}
826
827OMX_ERRORTYPE MrstSstComponent::ProcessorPause(void)
828{
829 OMX_ERRORTYPE ret = OMX_ErrorNone;
830 LOGV("%s(): enter\n", __func__);
831
Ho-Eun Ryu851416b2009-11-02 16:31:36 +0900832 //mix_audio_pause(mix);
Ho-Eun Ryu30801352009-10-30 17:07:47 +0900833
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900834 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
835 return ret;
836}
837
838OMX_ERRORTYPE MrstSstComponent::ProcessorResume(void)
839{
840 OMX_ERRORTYPE ret = OMX_ErrorNone;
841 LOGV("%s(): enter\n", __func__);
842
Ho-Eun Ryu851416b2009-11-02 16:31:36 +0900843 //mix_audio_resume(mix);
Ho-Eun Ryu30801352009-10-30 17:07:47 +0900844
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900845 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
846 return ret;
847}
848
849/* implement ComponentBase::ProcessorProcess */
850void MrstSstComponent::ProcessorProcess(
851 OMX_BUFFERHEADERTYPE **buffers,
852 bool *retain,
853 OMX_U32 nr_buffers)
854{
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900855 OMX_U32 outfilledlen = 0;
856 OMX_S64 outtimestamp = 0;
Ho-Eun Ryu4375deb2009-10-27 09:49:25 +0900857
858 MixStreamState mstream_state = MIX_STREAM_NULL;
859 MixState mstate;
860 bool acp_changed = false;
861
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900862 MIX_RESULT mret;
863
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900864 LOGV("%s(): enter\n", __func__);
865
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900866 if (!buffers[INPORT_INDEX]->nFilledLen) {
Ho-Eun Ryu4375deb2009-10-27 09:49:25 +0900867 LOGE("%s(),%d: exit, input buffer's nFilledLen is zero (ret = void)\n",
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900868 __func__, __LINE__);
869 return;
870 }
871
872 mixio->data = buffers[INPORT_INDEX]->pBuffer +
873 buffers[INPORT_INDEX]->nOffset;
874 mixio->size = buffers[INPORT_INDEX]->nFilledLen;
875
Ho-Eun Ryu4375deb2009-10-27 09:49:25 +0900876 if (coding_type == OMX_AUDIO_CodingMP3)
877 mret = ChangeAcpWithConfigHeader(mixio->data, &acp_changed);
Ho-Eun Ryu4375deb2009-10-27 09:49:25 +0900878 else if (coding_type == OMX_AUDIO_CodingAAC) {
Ho-Eun Ryufe974a52009-10-28 15:25:33 +0900879 if (buffers[INPORT_INDEX]->nFlags & OMX_BUFFERFLAG_CODECCONFIG)
880 mret = ChangeAcpWithConfigHeader(mixio->data, &acp_changed);
881 else
882 mret = MIX_RESULT_SUCCESS;
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900883 }
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900884 else {
Ho-Eun Ryuf69d3592009-10-28 09:23:34 +0900885 LOGE("%s(),%d: exit, unknown coding type (0x%08x)\n",
886 __func__, __LINE__, coding_type);
Ho-Eun Ryufe974a52009-10-28 15:25:33 +0900887 mret = MIX_RESULT_FAIL;
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900888 }
889
Ho-Eun Ryufe974a52009-10-28 15:25:33 +0900890 if (!MIX_SUCCEEDED(mret)) {
Ho-Eun Ryu4375deb2009-10-27 09:49:25 +0900891 LOGE("%s(),%d: exit, ret == 0x%08x\n", __func__, __LINE__, mret);
892 return;
893 }
894
895 mix_audio_get_state(mix, &mstate);
896 if (mstate == MIX_STATE_CONFIGURED)
897 mix_audio_get_stream_state(mix, &mstream_state);
898
899 if (acp_changed) {
900 if ((mstream_state != MIX_STREAM_NULL) &&
901 (mstream_state != MIX_STREAM_STOPPED))
902 mix_audio_stop_drain(mix);
903
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900904 mret = mix_audio_configure(mix, acp, NULL);
905 if (!MIX_SUCCEEDED(mret)) {
906 LOGE("%s(),%d: exit, mix_audio_configure failed (ret == 0x%08x)",
907 __func__, __LINE__, mret);
908 return;
909 }
Ho-Eun Ryu4375deb2009-10-27 09:49:25 +0900910 }
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900911
Ho-Eun Ryu4375deb2009-10-27 09:49:25 +0900912 mix_audio_get_stream_state(mix, &mstream_state);
913 if (mstream_state != MIX_STREAM_PLAYING) {
Ho-Eun Ryu851416b2009-11-02 16:31:36 +0900914 LOGV("%s(): mix current stream state = %d, call mix_audio_start\n",
915 __func__, mstream_state);
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900916 mret = mix_audio_start(mix);
917 if (!MIX_SUCCEEDED(mret)) {
918 LOGE("%s(),%d: faild to mix_audio_start (ret == 0x%08x)",
919 __func__, __LINE__, mret);
920 return;
921 }
922 }
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900923
924 if (codec_mode == MIX_CODING_DECODE) {
Ho-Eun Ryu851416b2009-11-02 16:31:36 +0900925 OMX_U64 consumed = 0;
926
Ho-Eun Ryufe974a52009-10-28 15:25:33 +0900927 if (buffers[INPORT_INDEX]->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
928 outfilledlen = 0;
929 outtimestamp = 0;
930 goto out;
931 }
932
Ho-Eun Ryu851416b2009-11-02 16:31:36 +0900933 mret = mix_audio_decode(mix,
934 (const MixIOVec *)mixio, 1, &consumed,
935 NULL, 0, NULL);
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900936 if (!MIX_SUCCEEDED(mret)) {
Ho-Eun Ryu851416b2009-11-02 16:31:36 +0900937 LOGE("%s(), %d: exit, mix_audio_decode failed (ret == 0x%08x)",
938 __func__, __LINE__, mret);
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900939 return;
940 }
941 mix_audio_get_timestamp(mix, (OMX_U64 *)&outtimestamp);
Ho-Eun Ryu851416b2009-11-02 16:31:36 +0900942
943 buffers[INPORT_INDEX]->nFilledLen -= (OMX_U32)consumed;
944 if (buffers[INPORT_INDEX]->nFilledLen) {
945 buffers[INPORT_INDEX]->nOffset += (OMX_U32)consumed;
946 retain[INPORT_INDEX] = true;
947
948 LOGD("%s(): input buffer NOT fully consumed %lu bytes consumed,"
949 "%lu bytes remained\n", __func__, (OMX_U32)consumed,
950 buffers[INPORT_INDEX]->nFilledLen);
951 }
952 else {
953 buffers[INPORT_INDEX]->nOffset = 0;
954 LOGV("%s(): %lu bytes fully consumed\n", __func__,
955 (OMX_U32)consumed);
956 }
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900957 }
958 /*
959 else {
960 ;
961 }
962 */
963
Ho-Eun Ryufe974a52009-10-28 15:25:33 +0900964out:
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900965 buffers[OUTPORT_INDEX]->nFilledLen = outfilledlen;
966 buffers[OUTPORT_INDEX]->nTimeStamp = outtimestamp;
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900967
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900968 LOGV("%s(),%d: exit (ret = void)\n", __func__, __LINE__);
969}
970
971/* end of implement ComponentBase::Processor[*] */
972
973/* end of component methods & helpers */
974
975/*
Ho-Eun Ryu4375deb2009-10-27 09:49:25 +0900976 * parser wrappers
977 */
978static inline MIX_RESULT __Mp3ChangeAcpWithConfigHeader(
979 MixAudioConfigParams *acp, const unsigned char *buffer, bool *acp_changed)
980{
981 int version, layer, crc, bitrate, samplingrate, channel,
982 mode_extension;
983 int ret;
984
985 if (!acp_changed)
986 return MIX_RESULT_FAIL;
987
988 ret = mp3_header_parse(buffer,
989 &version, &layer,
990 &crc, &bitrate,
991 &samplingrate, &channel,
992 &mode_extension);
993 if (ret)
994 return MIX_RESULT_FAIL;
995
996 if (version == MP3_HEADER_VERSION_1)
997 version = 1;
998 else if ((version == MP3_HEADER_VERSION_2) ||
999 (version == MP3_HEADER_VERSION_25))
1000 version = 2;
1001 else
1002 return MIX_RESULT_FAIL;
1003
1004 if (layer == MP3_HEADER_LAYER_1)
1005 layer = 1;
1006 else if (layer == MP3_HEADER_LAYER_2)
1007 layer = 2;
1008 else if (layer == MP3_HEADER_LAYER_3)
1009 layer = 3;
1010 else
1011 return MIX_RESULT_FAIL;
1012
1013
1014 if (crc == MP3_HEADER_CRC_PROTECTED)
1015 crc = 1;
1016 else if (crc == MP3_HEADER_NOT_PROTECTED)
1017 crc = 0;
1018 else
1019 return MIX_RESULT_FAIL;
1020
1021 if ((channel == MP3_HEADER_STEREO) ||
1022 (channel == MP3_HEADER_JOINT_STEREO) ||
1023 (channel == MP3_HEADER_DUAL_CHANNEL))
1024 channel = 2;
1025 else if (channel == MP3_HEADER_SINGLE_CHANNEL)
1026 channel = 1;
1027 else
1028 return MIX_RESULT_FAIL;
1029
1030 if (MIX_ACP_NUM_CHANNELS(acp) != channel) {
1031 LOGV("%s(): channel : %d != %d\n", __func__, MIX_ACP_NUM_CHANNELS(acp),
1032 channel);
1033
1034 MIX_ACP_NUM_CHANNELS(acp) = channel;
1035 *acp_changed = true;
1036 }
1037
1038 if (MIX_ACP_BITRATE(acp) != bitrate) {
1039 LOGV("%s(): channel : %d != %d\n", __func__, MIX_ACP_BITRATE(acp),
1040 bitrate);
1041
1042 MIX_ACP_BITRATE(acp) = bitrate;
1043 *acp_changed = true;
1044 }
1045
1046 if (MIX_ACP_SAMPLE_FREQ(acp) != samplingrate) {
1047 LOGV("%s(): samplingrate : %d != %d\n", __func__,
1048 MIX_ACP_SAMPLE_FREQ(acp), samplingrate);
1049
1050 MIX_ACP_SAMPLE_FREQ(acp) = samplingrate;
1051 *acp_changed = true;
1052 }
1053
1054 if (MIX_ACP_MP3_CRC(acp) != crc) {
1055 LOGV("%s(): crc : %d != %d\n", __func__, MIX_ACP_MP3_CRC(acp), crc);
1056
1057 MIX_ACP_MP3_CRC(acp) = crc;
1058 *acp_changed = true;
1059 }
1060
1061 if (MIX_ACP_MP3_MPEG_FORMAT(acp) != version) {
1062 LOGV("%s(): version : %d != %d\n", __func__,
1063 MIX_ACP_MP3_MPEG_FORMAT(acp), version);
1064
1065 MIX_ACP_MP3_MPEG_FORMAT(acp) = version;
1066 *acp_changed = true;
1067 }
1068
1069 if (MIX_ACP_MP3_MPEG_LAYER(acp) != layer) {
1070 LOGV("%s(): version : %d != %d\n", __func__,
1071 MIX_ACP_MP3_MPEG_LAYER(acp), layer);
1072
1073 MIX_ACP_MP3_MPEG_LAYER(acp) = layer;
1074 *acp_changed = true;
1075 }
1076
1077 if (*acp_changed) {
1078 LOGV("%s(): mp3 configration parameter has been chagned\n", __func__);
1079 LOGV("%s(): format : %d\n", __func__, MIX_ACP_MP3_MPEG_FORMAT(acp));
1080 LOGV("%s(): layer : %d\n", __func__, MIX_ACP_MP3_MPEG_LAYER(acp));
1081 LOGV("%s(): crc : %d\n", __func__, MIX_ACP_MP3_CRC(acp));
1082 LOGV("%s(): sampling rate : %d\n", __func__,
1083 MIX_ACP_SAMPLE_FREQ(acp));
1084 LOGV("%s(): bitrate : %d\n", __func__, MIX_ACP_BITRATE(acp));
1085 LOGV("%s(): channel : %d\n", __func__, MIX_ACP_NUM_CHANNELS(acp));
1086 }
1087
1088 return MIX_RESULT_SUCCESS;
1089}
1090
Ho-Eun Ryufe974a52009-10-28 15:25:33 +09001091static inline MIX_RESULT __AacChangeAcpWithConfigHeader(
1092 MixAudioConfigParams *acp, const unsigned char *buffer, bool *acp_changed)
1093{
1094 int aot, frequency, channel;
1095 int ret;
1096
1097 if (!acp_changed)
1098 return MIX_RESULT_FAIL;
1099
1100 ret = audio_specific_config_parse(buffer,
1101 &aot, &frequency, &channel);
1102 if (ret)
1103 return MIX_RESULT_FAIL;
1104
1105 if (aot < 1 || aot > 4)
1106 return MIX_RESULT_FAIL;
1107
1108 if (MIX_ACP_NUM_CHANNELS(acp) != channel) {
1109 LOGV("%s(): channel : %d != %d\n", __func__, MIX_ACP_NUM_CHANNELS(acp),
1110 channel);
1111
1112 MIX_ACP_NUM_CHANNELS(acp) = channel;
1113 *acp_changed = true;
1114 }
1115
1116 if (MIX_ACP_SAMPLE_FREQ(acp) != frequency) {
1117 LOGV("%s(): samplingrate : %d != %d\n", __func__,
1118 MIX_ACP_SAMPLE_FREQ(acp), frequency);
1119
1120 MIX_ACP_SAMPLE_FREQ(acp) = frequency;
1121 *acp_changed = true;
1122 }
1123
1124 /* 0:MPEG-2, 1:MPEG-4 */
1125 MIX_ACP_AAC_MPEG_FORMAT(acp) = 0;
1126 MIX_ACP_AAC_CRC(acp) = 0; /* 0:disabled, 1:enabled */
1127 MIX_ACP_AAC_AOT(acp) = aot; /* 1:Main, 2:LC, 3:SSR, 4:SBR */
1128 mix_acp_aac_set_bit_stream_format(MIX_AUDIOCONFIGPARAMSAAC(acp),
1129 MIX_AAC_BS_RAW);
1130 /* 0:Main, 1:LC, 2:SSR, 3:SBR */
1131 mix_acp_aac_set_aac_profile(MIX_AUDIOCONFIGPARAMSAAC(acp),
1132 (MixAACProfile)(aot - 1));
1133 /* 0:CBR, 1:VBR */
1134 mix_acp_aac_set_bit_rate_type(MIX_AUDIOCONFIGPARAMSAAC(acp),
1135 (MixACPBitrateType)0);
1136
1137 if (*acp_changed) {
1138 LOGV("%s(): audio configration parameter has been chagned\n",
1139 __func__);
1140 LOGV("%s(): aot : %d\n", __func__, MIX_ACP_AAC_AOT(acp));
1141 LOGV("%s(): frequency : %d\n", __func__, MIX_ACP_SAMPLE_FREQ(acp));
1142 LOGV("%s(): channel : %d\n", __func__, MIX_ACP_NUM_CHANNELS(acp));
1143 }
1144
1145 return MIX_RESULT_SUCCESS;
1146}
1147
Ho-Eun Ryu4375deb2009-10-27 09:49:25 +09001148MIX_RESULT MrstSstComponent::ChangeAcpWithConfigHeader(
1149 const unsigned char *buffer,
1150 bool *acp_changed)
1151{
1152 MIX_RESULT ret;
1153
1154 if (coding_type == OMX_AUDIO_CodingMP3)
1155 ret = __Mp3ChangeAcpWithConfigHeader(acp, buffer, acp_changed);
Ho-Eun Ryu4375deb2009-10-27 09:49:25 +09001156 else if (coding_type == OMX_AUDIO_CodingAAC)
1157 ret = __AacChangeAcpWithConfigHeader(acp, buffer, acp_changed);
Ho-Eun Ryu4375deb2009-10-27 09:49:25 +09001158 else
1159 return -1;
1160
1161 if (!MIX_SUCCEEDED(ret))
1162 return ret;
1163
1164 mix_acp_set_op_align(acp, MIX_ACP_OUTPUT_ALIGN_LSB);
1165 mix_acp_set_bps(acp, MIX_ACP_BPS_16);
1166
1167 return MIX_RESULT_SUCCESS;
1168}
1169
1170/* end of parser wrappers */
1171
1172/*
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +09001173 * CModule Interface
1174 */
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +09001175#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
1176
Ho-Eun Ryu50e10642009-10-29 12:15:15 +09001177static const char *g_name = (const char *)"OMX.Intel.Mrst.SST";
1178
1179static const char *g_roles[] =
1180{
1181 (const char *)"audio_decoder.mp3",
1182 (const char *)"audio_decoder.aac",
1183};
1184
1185OMX_ERRORTYPE wrs_omxil_cmodule_ops_instantiate(OMX_PTR *instance)
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +09001186{
1187 ComponentBase *cbase;
1188
1189 cbase = new MrstSstComponent;
1190 if (!cbase) {
1191 *instance = NULL;
1192 return OMX_ErrorInsufficientResources;
1193 }
1194
1195 *instance = cbase;
1196 return OMX_ErrorNone;
1197}
1198
Ho-Eun Ryu50e10642009-10-29 12:15:15 +09001199struct wrs_omxil_cmodule_ops_s cmodule_ops = {
1200 instantiate: wrs_omxil_cmodule_ops_instantiate,
1201};
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +09001202
Ho-Eun Ryu50e10642009-10-29 12:15:15 +09001203struct wrs_omxil_cmodule_s WRS_OMXIL_CMODULE_SYMBOL = {
1204 name: g_name,
1205 roles: &g_roles[0],
1206 nr_roles: ARRAY_SIZE(g_roles),
1207 ops: &cmodule_ops,
1208};