blob: 99b9ddd8eea6a9308501c5768b4fe7e818464211 [file] [log] [blame]
Ho-Eun Ryu0592b1b2009-10-16 15:26:16 +09001/*
2 * Copyright (C) 2009 Wind River Systems
3 * Author: Keun-O Park <keun-o.park@windriver.com>
4 * Ho-Eun Ryu <ho-eun.ryu@windriver.com>
5 * Min-Su Kim <min-su.kim@windriver.com>
6 */
7
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +09008#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <unistd.h>
12
13#include <OMX_Core.h>
14
15#include <cmodule.h>
16#include <portaudio.h>
17#include <componentbase.h>
18
Ho-Eun Ryu52045a32009-10-21 18:10:33 +090019#include <pv_omxcore.h>
20
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +090021#ifdef __cplusplus
22extern "C" {
23#endif
24
25#include <mixaudio.h>
26#include <mixacpaac.h>
27#include <mixacpmp3.h>
28
29#ifdef __cplusplus
30} /* extern "C" */
31#endif
32
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +090033#include "sst.h"
34
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +090035#define LOG_NDEBUG 0
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +090036
37#define LOG_TAG "mrst_sst"
38#include <log.h>
39
40/*
41 * constructor & destructor
42 */
43MrstSstComponent::MrstSstComponent()
44{
45 LOGV("%s(): enter\n", __func__);
46
47 LOGV("%s(),%d: exit (ret = void)\n", __func__, __LINE__);
48}
49
50MrstSstComponent::~MrstSstComponent()
51{
52 LOGV("%s(): enter\n", __func__);
53
54 LOGV("%s(),%d: exit (ret = void)\n", __func__, __LINE__);
55}
56
57/* end of constructor & destructor */
58
59/* core methods & helpers */
60OMX_ERRORTYPE MrstSstComponent::ComponentAllocatePorts(void)
61{
62 OMX_ERRORTYPE ret = OMX_ErrorUndefined;
63
64 LOGV("%s(): enter\n", __func__);
65
66 if (!strcmp(GetWorkingRole(), "audio_decoder.mp3"))
67 ret = __AllocateMp3RolePorts(false);
Ho-Eun Ryuf796f982009-10-19 17:01:09 +090068 else if(!strcmp(GetWorkingRole(), "audio_decoder.aac"))
69 ret = __AllocateAacRolePorts(false);
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +090070
71 LOGV("%s(): exit (ret = 0x%08x)\n", __func__, ret);
72 return ret;
73}
74
75
76OMX_ERRORTYPE MrstSstComponent::__AllocateMp3RolePorts(bool isencoder)
77{
78 PortBase **ports;
79
80 OMX_U32 mp3_port_index, pcm_port_index;
81 OMX_DIRTYPE mp3_port_dir, pcm_port_dir;
82
83 OMX_PORT_PARAM_TYPE portparam;
84 OMX_U32 i;
85 OMX_ERRORTYPE ret;
86
87 LOGV("%s(): enter\n", __func__);
88
89 ports = new PortBase *[NR_PORTS];
90 if (!ports)
91 return OMX_ErrorInsufficientResources;
92 this->nr_ports = NR_PORTS;
93 this->ports = ports;
94
95 if (isencoder) {
96 pcm_port_index = INPORT_INDEX;
97 mp3_port_index = OUTPORT_INDEX;
98 pcm_port_dir = OMX_DirInput;
99 mp3_port_dir = OMX_DirOutput;
100 }
101 else {
102 mp3_port_index = INPORT_INDEX;
103 pcm_port_index = OUTPORT_INDEX;
104 mp3_port_dir = OMX_DirInput;
105 pcm_port_dir = OMX_DirOutput;
106 }
107
108 ret = __AllocateMp3Port(mp3_port_index, mp3_port_dir);
109 if (ret != OMX_ErrorNone)
110 goto free_ports;
111
112 ret = __AllocatePcmPort(pcm_port_index, pcm_port_dir);
113 if (ret != OMX_ErrorNone)
114 goto free_mp3port;
115
116 /* OMX_PORT_PARAM_TYPE */
117 memset(&portparam, 0, sizeof(portparam));
118 SetTypeHeader(&portparam, sizeof(portparam));
119 portparam.nPorts = NR_PORTS;
120 portparam.nStartPortNumber = INPORT_INDEX;
121
122 memcpy(&this->portparam, &portparam, sizeof(portparam));
123 /* end of OMX_PORT_PARAM_TYPE */
124
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900125 coding_type = OMX_AUDIO_CodingMP3;
126 codec_mode = isencoder ? MIX_CODING_ENCODE : MIX_CODING_DECODE;
127
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900128 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, OMX_ErrorNone);
129 return OMX_ErrorNone;
130
131free_mp3port:
132 delete ports[mp3_port_index];
133
134free_ports:
135 delete []ports;
136
137 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
138 return ret;
139}
140
Ho-Eun Ryuf796f982009-10-19 17:01:09 +0900141
142OMX_ERRORTYPE MrstSstComponent::__AllocateAacRolePorts(bool isencoder)
143{
144 PortBase **ports;
145
146 OMX_U32 aac_port_index, pcm_port_index;
147 OMX_DIRTYPE aac_port_dir, pcm_port_dir;
148
149 OMX_PORT_PARAM_TYPE portparam;
150 OMX_U32 i;
151 OMX_ERRORTYPE ret;
152
153 LOGV("%s(): enter\n", __func__);
154
155 ports = new PortBase *[NR_PORTS];
156 if (!ports)
157 return OMX_ErrorInsufficientResources;
158 this->nr_ports = NR_PORTS;
159 this->ports = ports;
160
161 if (isencoder) {
162 pcm_port_index = INPORT_INDEX;
163 aac_port_index = OUTPORT_INDEX;
164 pcm_port_dir = OMX_DirInput;
165 aac_port_dir = OMX_DirOutput;
166 }
167 else {
168 aac_port_index = INPORT_INDEX;
169 pcm_port_index = OUTPORT_INDEX;
170 aac_port_dir = OMX_DirInput;
171 pcm_port_dir = OMX_DirOutput;
172 }
173
174 ret = __AllocateAacPort(aac_port_index, aac_port_dir);
175 if (ret != OMX_ErrorNone)
176 goto free_ports;
177
178 ret = __AllocatePcmPort(pcm_port_index, pcm_port_dir);
179 if (ret != OMX_ErrorNone)
180 goto free_aacport;
181
182 /* OMX_PORT_PARAM_TYPE */
183 memset(&portparam, 0, sizeof(portparam));
184 SetTypeHeader(&portparam, sizeof(portparam));
185 portparam.nPorts = NR_PORTS;
186 portparam.nStartPortNumber = INPORT_INDEX;
187
188 memcpy(&this->portparam, &portparam, sizeof(portparam));
189 /* end of OMX_PORT_PARAM_TYPE */
190
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900191 coding_type = OMX_AUDIO_CodingAAC;
192 codec_mode = isencoder ? MIX_CODING_ENCODE : MIX_CODING_DECODE;
193
Ho-Eun Ryuf796f982009-10-19 17:01:09 +0900194 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, OMX_ErrorNone);
195 return OMX_ErrorNone;
196
197free_aacport:
198 delete ports[aac_port_index];
199
200free_ports:
201 delete []ports;
202
203 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
204 return ret;
205}
206
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900207OMX_ERRORTYPE MrstSstComponent::__AllocateMp3Port(OMX_U32 port_index,
208 OMX_DIRTYPE dir)
209{
210 PortMp3 *mp3port;
211
212 OMX_PARAM_PORTDEFINITIONTYPE mp3portdefinition;
213 OMX_AUDIO_PARAM_MP3TYPE mp3portparam;
214 OMX_U32 i;
215
216 LOGV("%s(): enter\n", __func__);
217
218 ports[port_index] = new PortMp3;
219 if (!ports[port_index]) {
220 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
221 OMX_ErrorInsufficientResources);
222 return OMX_ErrorInsufficientResources;
223 }
224
225 mp3port = static_cast<PortMp3 *>(this->ports[port_index]);
226
227 /* MP3 - OMX_PARAM_PORTDEFINITIONTYPE */
228 memset(&mp3portdefinition, 0, sizeof(mp3portdefinition));
229 SetTypeHeader(&mp3portdefinition, sizeof(mp3portdefinition));
230 mp3portdefinition.nPortIndex = port_index;
231 mp3portdefinition.eDir = dir;
232 if (dir == OMX_DirInput) {
233 mp3portdefinition.nBufferCountActual = INPORT_MP3_ACTUAL_BUFFER_COUNT;
234 mp3portdefinition.nBufferCountMin = INPORT_MP3_MIN_BUFFER_COUNT;
235 mp3portdefinition.nBufferSize = INPORT_MP3_BUFFER_SIZE;
236 }
237 else {
238 mp3portdefinition.nBufferCountActual = OUTPORT_MP3_ACTUAL_BUFFER_COUNT;
239 mp3portdefinition.nBufferCountMin = OUTPORT_MP3_MIN_BUFFER_COUNT;
240 mp3portdefinition.nBufferSize = OUTPORT_MP3_BUFFER_SIZE;
241 }
242 mp3portdefinition.bEnabled = OMX_TRUE;
243 mp3portdefinition.bPopulated = OMX_FALSE;
244 mp3portdefinition.eDomain = OMX_PortDomainAudio;
245 mp3portdefinition.format.audio.cMIMEType = "audio/mpeg";
246 mp3portdefinition.format.audio.pNativeRender = NULL;
247 mp3portdefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
248 mp3portdefinition.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
249 mp3portdefinition.bBuffersContiguous = OMX_FALSE;
250 mp3portdefinition.nBufferAlignment = 0;
251
252 mp3port->SetPortDefinition(&mp3portdefinition, true);
253
254 /* end of MP3 - OMX_PARAM_PORTDEFINITIONTYPE */
255
256 /* OMX_AUDIO_PARAM_MP3TYPE */
257 memset(&mp3portparam, 0, sizeof(mp3portparam));
258 SetTypeHeader(&mp3portparam, sizeof(mp3portparam));
259 mp3portparam.nPortIndex = port_index;
260 mp3portparam.nChannels = 2;
261 mp3portparam.nBitRate = 0;
262 mp3portparam.nSampleRate = 0;
263 mp3portparam.nAudioBandWidth = 0;
264 mp3portparam.eChannelMode = OMX_AUDIO_ChannelModeStereo;
265 mp3portparam.eFormat = OMX_AUDIO_MP3StreamFormatMP1Layer3;
266
267 mp3port->SetPortMp3Param(&mp3portparam, true);
268 /* end of OMX_AUDIO_PARAM_MP3TYPE */
269
270 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, OMX_ErrorNone);
271 return OMX_ErrorNone;
272}
273
Ho-Eun Ryuf796f982009-10-19 17:01:09 +0900274OMX_ERRORTYPE MrstSstComponent::__AllocateAacPort(OMX_U32 port_index,
275 OMX_DIRTYPE dir)
276{
277 PortAac *aacport;
278
279 OMX_PARAM_PORTDEFINITIONTYPE aacportdefinition;
280 OMX_AUDIO_PARAM_AACPROFILETYPE aacportparam;
281 OMX_U32 i;
282
283 LOGV("%s(): enter\n", __func__);
284
285 ports[port_index] = new PortAac;
286 if (!ports[port_index]) {
287 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
288 OMX_ErrorInsufficientResources);
289 return OMX_ErrorInsufficientResources;
290 }
291
292 aacport = static_cast<PortAac *>(this->ports[port_index]);
293
294 /* AAC - OMX_PARAM_PORTDEFINITIONTYPE */
295 memset(&aacportdefinition, 0, sizeof(aacportdefinition));
296 SetTypeHeader(&aacportdefinition, sizeof(aacportdefinition));
297 aacportdefinition.nPortIndex = port_index;
298 aacportdefinition.eDir = dir;
299 if (dir == OMX_DirInput) {
300 aacportdefinition.nBufferCountActual = INPORT_AAC_ACTUAL_BUFFER_COUNT;
301 aacportdefinition.nBufferCountMin = INPORT_AAC_MIN_BUFFER_COUNT;
302 aacportdefinition.nBufferSize = INPORT_AAC_BUFFER_SIZE;
303 }
304 else {
305 aacportdefinition.nBufferCountActual = OUTPORT_AAC_ACTUAL_BUFFER_COUNT;
306 aacportdefinition.nBufferCountMin = OUTPORT_AAC_MIN_BUFFER_COUNT;
307 aacportdefinition.nBufferSize = OUTPORT_AAC_BUFFER_SIZE;
308 }
309 aacportdefinition.bEnabled = OMX_TRUE;
310 aacportdefinition.bPopulated = OMX_FALSE;
311 aacportdefinition.eDomain = OMX_PortDomainAudio;
312 aacportdefinition.format.audio.cMIMEType = "audio/mpeg";
313 aacportdefinition.format.audio.pNativeRender = NULL;
314 aacportdefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
315 aacportdefinition.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
316 aacportdefinition.bBuffersContiguous = OMX_FALSE;
317 aacportdefinition.nBufferAlignment = 0;
318
319 aacport->SetPortDefinition(&aacportdefinition, true);
320
321 /* end of AAC - OMX_PARAM_PORTDEFINITIONTYPE */
322
323 /* OMX_AUDIO_PARAM_AACPROFILETYPE */
324 memset(&aacportparam, 0, sizeof(aacportparam));
325 SetTypeHeader(&aacportparam, sizeof(aacportparam));
326 aacportparam.nPortIndex = port_index;
327 aacportparam.nChannels = 2;
328 aacportparam.nBitRate = 0;
329 aacportparam.nSampleRate = 0;
330 aacportparam.nAudioBandWidth = 0;
331 aacportparam.nFrameLength = 1024; /* default for LC */
332 aacportparam.nAACtools = OMX_AUDIO_AACToolNone;
333 aacportparam.nAACERtools = OMX_AUDIO_AACERNone;
334 aacportparam.eAACProfile = OMX_AUDIO_AACObjectLC;
335 aacportparam.eChannelMode = OMX_AUDIO_ChannelModeStereo;
336
337 aacport->SetPortAacParam(&aacportparam, true);
338 /* end of OMX_AUDIO_PARAM_AACPROFILETYPE */
339
340 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, OMX_ErrorNone);
341 return OMX_ErrorNone;
342}
343
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900344OMX_ERRORTYPE MrstSstComponent::__AllocatePcmPort(OMX_U32 port_index,
345 OMX_DIRTYPE dir)
346{
347 PortPcm *pcmport;
348
349 OMX_PARAM_PORTDEFINITIONTYPE pcmportdefinition;
350 OMX_AUDIO_PARAM_PCMMODETYPE pcmportparam;
351 OMX_U32 i;
352
353 LOGV("%s(): enter\n", __func__);
354
355 ports[port_index] = new PortPcm;
356 if (!ports[port_index]) {
357 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
358 OMX_ErrorInsufficientResources);
359 return OMX_ErrorInsufficientResources;
360 }
361 pcmport = static_cast<PortPcm *>(this->ports[port_index]);
362
363 /* PCM - OMX_PARAM_PORTDEFINITIONTYPE */
364 memset(&pcmportdefinition, 0, sizeof(pcmportdefinition));
365 SetTypeHeader(&pcmportdefinition, sizeof(pcmportdefinition));
366 pcmportdefinition.nPortIndex = port_index;
367 pcmportdefinition.eDir = dir;
368 if (dir == OMX_DirInput) {
369 pcmportdefinition.nBufferCountActual = INPORT_PCM_ACTUAL_BUFFER_COUNT;
370 pcmportdefinition.nBufferCountMin = INPORT_PCM_MIN_BUFFER_COUNT;
371 pcmportdefinition.nBufferSize = INPORT_PCM_BUFFER_SIZE;
372 }
373 else {
374 pcmportdefinition.nBufferCountActual = OUTPORT_PCM_ACTUAL_BUFFER_COUNT;
375 pcmportdefinition.nBufferCountMin = OUTPORT_PCM_MIN_BUFFER_COUNT;
376 pcmportdefinition.nBufferSize = OUTPORT_PCM_BUFFER_SIZE;
377 }
378 pcmportdefinition.bEnabled = OMX_TRUE;
379 pcmportdefinition.bPopulated = OMX_FALSE;
380 pcmportdefinition.eDomain = OMX_PortDomainAudio;
381 pcmportdefinition.format.audio.cMIMEType = "raw";
382 pcmportdefinition.format.audio.pNativeRender = NULL;
383 pcmportdefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
384 pcmportdefinition.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
385 pcmportdefinition.bBuffersContiguous = OMX_FALSE;
386 pcmportdefinition.nBufferAlignment = 0;
387
388 pcmport->SetPortDefinition(&pcmportdefinition, true);
389 /* end of PCM - OMX_PARAM_PORTDEFINITIONTYPE */
390
391 /* OMX_AUDIO_PARAM_PCMMODETYPE */
392 memset(&pcmportparam, 0, sizeof(pcmportparam));
393 SetTypeHeader(&pcmportparam, sizeof(pcmportparam));
394 pcmportparam.nPortIndex = port_index;
395 pcmportparam.nChannels = 2;
396 pcmportparam.eNumData = OMX_NumericalDataUnsigned;
397 pcmportparam.eEndian = OMX_EndianLittle;
398 pcmportparam.bInterleaved = OMX_FALSE;
399 pcmportparam.nBitPerSample = 16;
400 pcmportparam.nSamplingRate = 44100;
401 pcmportparam.ePCMMode = OMX_AUDIO_PCMModeLinear;
402 pcmportparam.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
403 pcmportparam.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
404
405 pcmport->SetPortPcmParam(&pcmportparam, true);
406 /* end of OMX_AUDIO_PARAM_PCMMODETYPE */
407
408 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, OMX_ErrorNone);
409 return OMX_ErrorNone;
410}
411
412/* end of core methods & helpers */
413
414/*
415 * component methods & helpers
416 */
417/* Get/SetParameter */
418OMX_ERRORTYPE MrstSstComponent::ComponentGetParameter(
419 OMX_INDEXTYPE nParamIndex,
420 OMX_PTR pComponentParameterStructure)
421{
422 OMX_ERRORTYPE ret = OMX_ErrorNone;
423
424 LOGV("%s(): enter (index = 0x%08x)\n", __func__, nParamIndex);
425
426 switch (nParamIndex) {
427 case OMX_IndexParamAudioPortFormat: {
428 OMX_AUDIO_PARAM_PORTFORMATTYPE *p =
429 (OMX_AUDIO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure;
430 OMX_U32 index = p->nPortIndex;
431 PortAudio *port = NULL;
432
433 ret = CheckTypeHeader(p, sizeof(*p));
434 if (ret != OMX_ErrorNone) {
435 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
436 return ret;
437 }
438
439 if (index < nr_ports)
440 port = static_cast<PortAudio *>(ports[index]);
441
442 if (!port) {
443 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
444 OMX_ErrorBadPortIndex);
445 return OMX_ErrorBadPortIndex;
446 }
447
448 memcpy(p, port->GetPortAudioParam(), sizeof(*p));
449 break;
450 }
451 case OMX_IndexParamAudioPcm: {
452 OMX_AUDIO_PARAM_PCMMODETYPE *p =
453 (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
454 OMX_U32 index = p->nPortIndex;
455 PortPcm *port = NULL;
456
Ho-Eun Ryuf796f982009-10-19 17:01:09 +0900457 if (strcmp(GetWorkingRole(), "audio_decoder.mp3") &&
458 strcmp(GetWorkingRole(), "audio_decoder.aac")) {
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900459 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
460 OMX_ErrorUnsupportedIndex);
461 return OMX_ErrorUnsupportedIndex;
462 }
463
464 ret = CheckTypeHeader(p, sizeof(*p));
465 if (ret != OMX_ErrorNone) {
466 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
467 return ret;
468 }
469
470 if (index < nr_ports)
471 port = static_cast<PortPcm *>(ports[index]);
472
473 if (!port) {
474 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
475 OMX_ErrorBadPortIndex);
476 return OMX_ErrorBadPortIndex;
477 }
478
479 memcpy(p, port->GetPortPcmParam(), sizeof(*p));
480 break;
481 }
482 case OMX_IndexParamAudioMp3: {
483 OMX_AUDIO_PARAM_MP3TYPE *p =
484 (OMX_AUDIO_PARAM_MP3TYPE *)pComponentParameterStructure;
485 OMX_U32 index = p->nPortIndex;
486 PortMp3 *port = NULL;
487
488 if (strcmp(GetWorkingRole(), "audio_decoder.mp3")) {
489 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
490 OMX_ErrorUnsupportedIndex);
491 return OMX_ErrorUnsupportedIndex;
492 }
493
494 ret = CheckTypeHeader(p, sizeof(*p));
495 if (ret != OMX_ErrorNone) {
496 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
497 return ret;
498 }
499
500 if (index < nr_ports)
501 port = static_cast<PortMp3 *>(ports[index]);
502
503 if (!port) {
504 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
505 OMX_ErrorBadPortIndex);
506 return OMX_ErrorBadPortIndex;
507 }
508
509 memcpy(p, port->GetPortMp3Param(), sizeof(*p));
510 break;
511 }
Ho-Eun Ryuf796f982009-10-19 17:01:09 +0900512 case OMX_IndexParamAudioAac: {
513 OMX_AUDIO_PARAM_AACPROFILETYPE *p =
514 (OMX_AUDIO_PARAM_AACPROFILETYPE *)pComponentParameterStructure;
515 OMX_U32 index = p->nPortIndex;
516 PortAac *port = NULL;
517
518 if (strcmp(GetWorkingRole(), "audio_decoder.aac")) {
519 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
520 OMX_ErrorUnsupportedIndex);
521 return OMX_ErrorUnsupportedIndex;
522 }
523
524 ret = CheckTypeHeader(p, sizeof(*p));
525 if (ret != OMX_ErrorNone) {
526 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
527 return ret;
528 }
529
530 if (index < nr_ports)
531 port = static_cast<PortAac *>(ports[index]);
532
533 if (!port) {
534 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
535 OMX_ErrorBadPortIndex);
536 return OMX_ErrorBadPortIndex;
537 }
538
539 memcpy(p, port->GetPortAacParam(), sizeof(*p));
540 break;
541 }
Ho-Eun Ryu52045a32009-10-21 18:10:33 +0900542 case (OMX_INDEXTYPE) PV_OMX_COMPONENT_CAPABILITY_TYPE_INDEX: {
543 PV_OMXComponentCapabilityFlagsType *p =
544 (PV_OMXComponentCapabilityFlagsType *)pComponentParameterStructure;
545
546 p->iIsOMXComponentMultiThreaded = OMX_TRUE;
547 p->iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE;
548 p->iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE;
549 p->iOMXComponentSupportsMovableInputBuffers = OMX_TRUE;
550 p->iOMXComponentUsesNALStartCodes = OMX_TRUE;
551 p->iOMXComponentSupportsPartialFrames = OMX_FALSE;
552 p->iOMXComponentCanHandleIncompleteFrames = OMX_TRUE;
553 p->iOMXComponentUsesFullAVCFrames = OMX_FALSE;
554 break;
555 }
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900556 default:
557 ret = OMX_ErrorUnsupportedIndex;
558 } /* switch */
559
560 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
561 return ret;
562}
563
564OMX_ERRORTYPE MrstSstComponent::ComponentSetParameter(
565 OMX_INDEXTYPE nIndex,
566 OMX_PTR pComponentParameterStructure)
567{
568 OMX_ERRORTYPE ret = OMX_ErrorNone;
569
570 LOGV("%s(): enter (index = 0x%08x)\n", __func__, nIndex);
571
572 switch (nIndex) {
573 case OMX_IndexParamAudioPortFormat: {
574 OMX_AUDIO_PARAM_PORTFORMATTYPE *p =
575 (OMX_AUDIO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure;
576 OMX_U32 index = p->nPortIndex;
577 PortAudio *port = NULL;
578
579 ret = CheckTypeHeader(p, sizeof(*p));
580 if (ret != OMX_ErrorNone) {
581 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
582 return ret;
583 }
584
585 if (index < nr_ports)
586 port = static_cast<PortPcm *>(ports[index]);
587
588 if (!port) {
589 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
590 OMX_ErrorBadPortIndex);
591 return OMX_ErrorBadPortIndex;
592 }
593
594 if (port->IsEnabled()) {
595 OMX_STATETYPE state;
596
597 CBaseGetState((void *)GetComponentHandle(), &state);
598 if (state != OMX_StateLoaded &&
599 state != OMX_StateWaitForResources) {
600 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
601 OMX_ErrorIncorrectStateOperation);
602 return OMX_ErrorIncorrectStateOperation;
603 }
604 }
605
606 ret = port->SetPortAudioParam(p, false);
607 break;
608 }
609 case OMX_IndexParamAudioPcm: {
610 OMX_AUDIO_PARAM_PCMMODETYPE *p =
611 (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
612 OMX_U32 index = p->nPortIndex;
613 PortPcm *port = NULL;
614
Ho-Eun Ryuf796f982009-10-19 17:01:09 +0900615 if (strcmp(GetWorkingRole(), "audio_decoder.mp3") &&
616 strcmp(GetWorkingRole(), "audio_decoder.aac")) {
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900617 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
618 OMX_ErrorUnsupportedIndex);
619 return OMX_ErrorUnsupportedIndex;
620 }
621
622 ret = CheckTypeHeader(p, sizeof(*p));
623 if (ret != OMX_ErrorNone) {
624 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
625 return ret;
626 }
627
628 if (index < nr_ports)
629 port = static_cast<PortPcm *>(ports[index]);
630
631 if (!port) {
632 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
633 OMX_ErrorBadPortIndex);
634 return OMX_ErrorBadPortIndex;
635 }
636
637 if (port->IsEnabled()) {
638 OMX_STATETYPE state;
639
640 CBaseGetState((void *)GetComponentHandle(), &state);
641 if (state != OMX_StateLoaded &&
642 state != OMX_StateWaitForResources) {
643 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
644 OMX_ErrorIncorrectStateOperation);
645 return OMX_ErrorIncorrectStateOperation;
646 }
647 }
648
649 ret = port->SetPortPcmParam(p, false);
650 break;
651 }
652 case OMX_IndexParamAudioMp3: {
653 OMX_AUDIO_PARAM_MP3TYPE *p =
654 (OMX_AUDIO_PARAM_MP3TYPE *)pComponentParameterStructure;
655 OMX_U32 index = p->nPortIndex;
656 PortMp3 *port = NULL;
657
658 if (strcmp(GetWorkingRole(), "audio_decoder.mp3")) {
659 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
660 OMX_ErrorUnsupportedIndex);
661 return OMX_ErrorUnsupportedIndex;
662 }
663
664 ret = CheckTypeHeader(p, sizeof(*p));
665 if (ret != OMX_ErrorNone) {
666 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
667 return ret;
668 }
669
670 if (index < nr_ports)
671 port = static_cast<PortMp3 *>(ports[index]);
672
673 if (!port) {
674 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
675 OMX_ErrorBadPortIndex);
676 return OMX_ErrorBadPortIndex;
677 }
678
679 if (port->IsEnabled()) {
680 OMX_STATETYPE state;
681
682 CBaseGetState((void *)GetComponentHandle(), &state);
683 if (state != OMX_StateLoaded &&
684 state != OMX_StateWaitForResources) {
685 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
686 OMX_ErrorIncorrectStateOperation);
687 return OMX_ErrorIncorrectStateOperation;
688 }
689 }
690
691 ret = port->SetPortMp3Param(p, false);
692 break;
693 }
Ho-Eun Ryuf796f982009-10-19 17:01:09 +0900694 case OMX_IndexParamAudioAac: {
695 OMX_AUDIO_PARAM_AACPROFILETYPE *p =
696 (OMX_AUDIO_PARAM_AACPROFILETYPE *)pComponentParameterStructure;
697 OMX_U32 index = p->nPortIndex;
698 PortAac *port = NULL;
699
700 if (strcmp(GetWorkingRole(), "audio_decoder.aac")) {
701 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
702 OMX_ErrorUnsupportedIndex);
703 return OMX_ErrorUnsupportedIndex;
704 }
705
706 ret = CheckTypeHeader(p, sizeof(*p));
707 if (ret != OMX_ErrorNone) {
708 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
709 return ret;
710 }
711
712 if (index < nr_ports)
713 port = static_cast<PortAac *>(ports[index]);
714
715 if (!port) {
716 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
717 OMX_ErrorBadPortIndex);
718 return OMX_ErrorBadPortIndex;
719 }
720
721 if (port->IsEnabled()) {
722 OMX_STATETYPE state;
723
724 CBaseGetState((void *)GetComponentHandle(), &state);
725 if (state != OMX_StateLoaded &&
726 state != OMX_StateWaitForResources) {
727 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__,
728 OMX_ErrorIncorrectStateOperation);
729 return OMX_ErrorIncorrectStateOperation;
730 }
731 }
732
733 ret = port->SetPortAacParam(p, false);
734 break;
735 }
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900736 default:
737 ret = OMX_ErrorUnsupportedIndex;
738 } /* switch */
739
740 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
741 return ret;
742}
743
744/* Get/SetConfig */
745OMX_ERRORTYPE MrstSstComponent::ComponentGetConfig(
746 OMX_INDEXTYPE nIndex,
747 OMX_PTR pComponentConfigStructure)
748{
749 OMX_ERRORTYPE ret = OMX_ErrorUnsupportedIndex;
750 LOGV("%s(): enter\n", __func__);
751
752 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
753 return ret;
754}
755
756OMX_ERRORTYPE MrstSstComponent::ComponentSetConfig(
757 OMX_INDEXTYPE nParamIndex,
758 OMX_PTR pComponentConfigStructure)
759{
760 OMX_ERRORTYPE ret = OMX_ErrorUnsupportedIndex;
761 LOGV("%s(): enter\n", __func__);
762
763 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
764 return ret;
765}
766
767/* implement ComponentBase::Processor[*] */
768OMX_ERRORTYPE MrstSstComponent::ProcessorInit(void)
769{
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900770 MixAudio *mix;
771 MixAudioConfigParams *acp;
772 MixIOVec *mixio;
773 OMX_ERRORTYPE oret = OMX_ErrorNone;
774 MIX_RESULT mret;
775
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900776 LOGV("%s(): enter\n", __func__);
777
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900778 g_type_init();
779
780 /* set default parameters */
781 if (coding_type == OMX_AUDIO_CodingMP3)
782 acp = MIX_AUDIOCONFIGPARAMS(mix_acp_mp3_new());
783 else if (coding_type == OMX_AUDIO_CodingAAC)
784 acp = MIX_AUDIOCONFIGPARAMS(mix_acp_aac_new());
785 else {
786 LOGE("%s(),%d: exit, unkown role (ret == 0x%08x)\n",
787 __func__, __LINE__, OMX_ErrorInvalidState);
788 return OMX_ErrorInvalidState;
789 }
790
791 if (codec_mode == MIX_CODING_DECODE)
792 MIX_ACP_DECODEMODE(acp) = MIX_DECODE_DIRECTRENDER;
793 /*
794 else if (codec_mode == MIX_CODING_ENCODE)
795 ;
796 */
797
798 mret = mix_acp_set_streamname(acp, GetWorkingRole());
799 if (!MIX_SUCCEEDED(mret)) {
800 LOGE("%s(),%d: exit, mix_acp_set_streamname failed (ret == 0x%08x)",
801 __func__, __LINE__, mret);
802 mix_params_unref(MIX_PARAMS(acp));
803 return OMX_ErrorInvalidState;
804 }
805
806 mix = mix_audio_new();
807 mret = mix_audio_initialize(mix, codec_mode, NULL, NULL);
808 if (!(MIX_SUCCEEDED(mret))) {
809 LOGE("%s(),%d: exit, mix_audio_initialize failed (ret == 0x%08x)",
810 __func__, __LINE__, mret);
811 mix_params_unref(MIX_PARAMS(acp));
812 return OMX_ErrorInvalidState;
813 }
814
815 mixio = (MixIOVec *)malloc(sizeof(MixIOVec));
816 if (!mixio) {
817 LOGE("%s(),%d: exit, failed to allocate mbuffer (ret == 0x%08x)",
818 __func__, __LINE__, mret);
819 mix_params_unref(MIX_PARAMS(acp));
820 mix_audio_unref(mix);
821 return OMX_ErrorInvalidState;
822 }
823
824 this->mix = mix;
825 this->acp = acp;
826 this->mixio = mixio;
827
828 ibuffercount = 0;
829
830 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, oret);
831 return oret;
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900832}
833
834OMX_ERRORTYPE MrstSstComponent::ProcessorDeinit(void)
835{
836 OMX_ERRORTYPE ret = OMX_ErrorNone;
837 LOGV("%s(): enter\n", __func__);
838
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900839 mix_audio_stop_drop(mix);
840
841 mix_audio_deinitialize(mix);
842
843 mix_acp_unref(acp);
844 mix_audio_unref(mix);
845
846 free(mixio);
847
848 ibuffercount = 0;
849
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900850 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
851 return ret;
852}
853
854OMX_ERRORTYPE MrstSstComponent::ProcessorStart(void)
855{
856 OMX_ERRORTYPE ret = OMX_ErrorNone;
857 LOGV("%s(): enter\n", __func__);
858
859 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
860 return ret;
861}
862
863OMX_ERRORTYPE MrstSstComponent::ProcessorStop(void)
864{
865 OMX_ERRORTYPE ret = OMX_ErrorNone;
866 LOGV("%s(): enter\n", __func__);
867
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900868 mix_audio_stop_drop(mix);
869
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900870 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
871 return ret;
872}
873
874OMX_ERRORTYPE MrstSstComponent::ProcessorPause(void)
875{
876 OMX_ERRORTYPE ret = OMX_ErrorNone;
877 LOGV("%s(): enter\n", __func__);
878
879 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
880 return ret;
881}
882
883OMX_ERRORTYPE MrstSstComponent::ProcessorResume(void)
884{
885 OMX_ERRORTYPE ret = OMX_ErrorNone;
886 LOGV("%s(): enter\n", __func__);
887
888 LOGV("%s(),%d: exit (ret = 0x%08x)\n", __func__, __LINE__, ret);
889 return ret;
890}
891
892/* implement ComponentBase::ProcessorProcess */
893void MrstSstComponent::ProcessorProcess(
894 OMX_BUFFERHEADERTYPE **buffers,
895 bool *retain,
896 OMX_U32 nr_buffers)
897{
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900898 OMX_U32 outfilledlen = 0;
899 OMX_S64 outtimestamp = 0;
900 MIX_RESULT mret;
901
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900902 LOGV("%s(): enter\n", __func__);
903
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900904 if (!buffers[INPORT_INDEX]->nFilledLen) {
905 LOGE("%s(),%d: exit input buffer's nFilledLen is zero (ret = void)\n",
906 __func__, __LINE__);
907 return;
908 }
909
910 mixio->data = buffers[INPORT_INDEX]->pBuffer +
911 buffers[INPORT_INDEX]->nOffset;
912 mixio->size = buffers[INPORT_INDEX]->nFilledLen;
913
914 if (coding_type == OMX_AUDIO_CodingMP3) {
915 MIX_ACP_NUM_CHANNELS(acp) = 2;
916 MIX_ACP_BITRATE(acp) = 128000;
917 MIX_ACP_SAMPLE_FREQ(acp) = 44100;
918 mix_acp_set_op_align(acp, MIX_ACP_OUTPUT_ALIGN_LSB);
919 mix_acp_set_bps(acp, MIX_ACP_BPS_16);
920
921 MIX_ACP_MP3_CRC(acp) = 0;
922 MIX_ACP_MP3_MPEG_FORMAT(acp) = 1;
923 MIX_ACP_MP3_MPEG_LAYER(acp) = 3;
924 }
925 /*
926 else if (coding_type == OMX_AUDIO_CodingMP3) {
927 ;
928 }
929 */
930 else {
931 LOGE("%s(),%d: exit, unkown mix acp\n", __func__, __LINE__);
932 return;
933 }
934
935 if (!ibuffercount) {
936 mret = mix_audio_configure(mix, acp, NULL);
937 if (!MIX_SUCCEEDED(mret)) {
938 LOGE("%s(),%d: exit, mix_audio_configure failed (ret == 0x%08x)",
939 __func__, __LINE__, mret);
940 return;
941 }
942
943 mret = mix_audio_start(mix);
944 if (!MIX_SUCCEEDED(mret)) {
945 LOGE("%s(),%d: faild to mix_audio_start (ret == 0x%08x)",
946 __func__, __LINE__, mret);
947 return;
948 }
949 }
950 ibuffercount++;
951
952 if (codec_mode == MIX_CODING_DECODE) {
953 mret = mix_audio_decode(mix, (const MixIOVec *)mixio, 1, NULL, NULL);
954 if (!MIX_SUCCEEDED(mret)) {
955 LOGV("_decode returns fail. Error code:0x%08x", mret);
956 return;
957 }
958 mix_audio_get_timestamp(mix, (OMX_U64 *)&outtimestamp);
959 }
960 /*
961 else {
962 ;
963 }
964 */
965
966 buffers[OUTPORT_INDEX]->nFilledLen = outfilledlen;
967 buffers[OUTPORT_INDEX]->nTimeStamp = outtimestamp;
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900968
969 buffers[INPORT_INDEX]->nFilledLen = 0;
970
971 LOGV("%s(),%d: exit (ret = void)\n", __func__, __LINE__);
972}
973
974/* end of implement ComponentBase::Processor[*] */
975
976/* end of component methods & helpers */
977
978/*
979 * CModule Interface
980 */
981static const OMX_STRING g_roles[] =
982{
983 "audio_decoder.mp3",
Ho-Eun Ryue4e0bd82009-10-23 16:16:04 +0900984 //"audio_decoder.aac",
Ho-Eun Ryu2046ff92009-10-16 12:27:28 +0900985};
986
987static const OMX_STRING g_compname = "OMX.Intel.MrstSST";
988
989#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
990
991OMX_ERRORTYPE omx_component_module_instantiate(OMX_PTR *instance)
992{
993 ComponentBase *cbase;
994
995 cbase = new MrstSstComponent;
996 if (!cbase) {
997 *instance = NULL;
998 return OMX_ErrorInsufficientResources;
999 }
1000
1001 *instance = cbase;
1002 return OMX_ErrorNone;
1003}
1004
1005OMX_ERRORTYPE omx_component_module_query_name(OMX_STRING name, OMX_U32 len)
1006{
1007 if (!name)
1008 return OMX_ErrorBadParameter;
1009
1010 strncpy(name, g_compname, len);
1011 return OMX_ErrorNone;
1012}
1013
1014OMX_ERRORTYPE omx_component_module_query_roles(OMX_U32 *nr_roles,
1015 OMX_U8 **roles)
1016{
1017 return ComponentBase::QueryRolesHelper(ARRAY_SIZE(g_roles),
1018 (const OMX_U8 **)g_roles,
1019 nr_roles, roles);
1020}