summaryrefslogtreecommitdiff
path: root/libTVaudio/audio/DDP_media_source.cpp (plain)
blob: 7de39b2cb2a6409c43a53a575cee6e5fee15e143
1#define LOG_TAG "DDP_Media_Source"
2
3#include <stdio.h>
4#include <stdarg.h>
5#include <string.h>
6#include <android/log.h>
7#include <cutils/properties.h>
8#include <pthread.h>
9
10//code here for sys write service
11#ifdef USE_SYS_WRITE_SERVICE
12#include <binder/Binder.h>
13#include <binder/IServiceManager.h>
14#include <utils/Atomic.h>
15#include <utils/Log.h>
16#include <utils/RefBase.h>
17#include <utils/String8.h>
18#include <utils/String16.h>
19#include <utils/threads.h>
20#include <unistd.h>
21#if ANDROID_PLATFORM_SDK_VERSION >= 21 //5.0
22#include <systemcontrol/ISystemControlService.h>
23#else
24#include <systemwrite/ISystemWriteService.h>
25#endif
26// code end
27#endif
28#include <media/stagefright/SimpleDecodingSource.h>
29
30#include "DDP_media_source.h"
31#include "aml_audio.h"
32extern struct circle_buffer android_out_buffer;
33extern struct circle_buffer DDP_out_buffer;
34extern struct circle_buffer DD_out_buffer;
35extern int spdif_audio_type;
36namespace android {
37
38
39#ifdef USE_SYS_WRITE_SERVICE
40//code here for system write service
41class DeathNotifier: public IBinder::DeathRecipient
42{
43 public:
44 DeathNotifier() {
45 }
46
47 void binderDied(__unused const wp<IBinder>& who) {
48 ALOGW("system_write died!");
49 }
50};
51
52
53#if ANDROID_PLATFORM_SDK_VERSION >= 21 //5.0
54//used ISystemControlService
55#define SYST_SERVICES_NAME "system_control"
56#else
57//used amSystemWriteService
58#define ISystemControlService ISystemWriteService
59#define SYST_SERVICES_NAME "system_write"
60#endif
61
62static sp<ISystemControlService> amSystemWriteService;
63static sp<DeathNotifier> amDeathNotifier;
64static Mutex amLock;
65static Mutex amgLock;
66
67const sp<ISystemControlService>& getSystemWriteService()
68{
69 Mutex::Autolock _l(amgLock);
70 if (amSystemWriteService.get() == 0) {
71 sp<IServiceManager> sm = defaultServiceManager();
72#if 0
73 sp<IBinder> binder;
74 do {
75 binder = sm->getService(String16("system_write"));
76 if (binder != 0)
77 break;
78 ALOGW("SystemWriteService not published, waiting...");
79 usleep(500000); // 0.5 s
80 } while(true);
81 if (amDeathNotifier == NULL) {
82 amDeathNotifier = new DeathNotifier();
83 }
84 binder->linkToDeath(amDeathNotifier);
85 amSystemWriteService = interface_cast<ISystemWriteService>(binder);
86#endif
87
88
89 amSystemWriteService = interface_cast<ISystemControlService>(sm->getService(String16(SYST_SERVICES_NAME)));
90
91 }
92 ALOGE_IF(amSystemWriteService==0, "no SystemWrite Service!?");
93
94 return amSystemWriteService;
95}
96void amSystemWriteSetProperty(const char* key, const char* value)
97{
98 const sp<ISystemControlService>& sws = getSystemWriteService();
99 if (sws != 0) {
100 sws->setProperty(String16(key), String16(value));
101 }
102}
103//code end for system write service
104#endif
105static DDPerr ddbs_init(DDPshort * buf, DDPshort bitptr, DDP_BSTRM *p_bstrm)
106{
107 p_bstrm->buf = buf;
108 p_bstrm->bitptr = bitptr;
109 p_bstrm->data = *buf;
110 return 0;
111}
112static DDPerr ddbs_unprj(DDP_BSTRM *p_bstrm, DDPshort *p_data, DDPshort numbits)
113{
114 DDPushort data;
115 *p_data = (DDPshort)((p_bstrm->data << p_bstrm->bitptr) & msktab[numbits]);
116 p_bstrm->bitptr += numbits;
117 if (p_bstrm->bitptr >= BITSPERWRD)
118 {
119 p_bstrm->buf++;
120 p_bstrm->data = *p_bstrm->buf;
121 p_bstrm->bitptr -= BITSPERWRD;
122 data = (DDPushort)p_bstrm->data;
123 *p_data |= ((data >> (numbits - p_bstrm->bitptr)) & msktab[numbits]);
124 }
125 *p_data = (DDPshort)((DDPushort)(*p_data) >> (BITSPERWRD - numbits));
126 return 0;
127}
128
129
130static int Get_DD_Parameters(void *buf, int *sample_rate, int *frame_size, int *ChNum)
131{
132 int numch=0;
133 DDP_BSTRM bstrm={NULL, 0, 0};
134 DDP_BSTRM *p_bstrm=&bstrm;
135 short tmp=0,acmod,lfeon,fscod,frmsizecod;
136 ddbs_init((short*)buf,0,p_bstrm);
137
138 ddbs_unprj(p_bstrm, &tmp, 16);
139 if (tmp!= SYNCWRD)
140 {
141 ALOGI("Invalid synchronization word");
142 return 0;
143 }
144 ddbs_unprj(p_bstrm, &tmp, 16);
145 ddbs_unprj(p_bstrm, &fscod, 2);
146 if (fscod == MAXFSCOD)
147 {
148 ALOGI("Invalid sampling rate code");
149 return 0;
150 }
151
152 if (fscod == 0) *sample_rate = 48000;
153 else if (fscod == 1) *sample_rate = 44100;
154 else if (fscod == 2) *sample_rate = 32000;
155
156 ddbs_unprj(p_bstrm, &frmsizecod, 6);
157 if (frmsizecod >= MAXDDDATARATE)
158 {
159 ALOGI("Invalid frame size code");
160 return 0;
161 }
162
163 *frame_size=2*frmsizetab[fscod][frmsizecod];
164
165 ddbs_unprj(p_bstrm, &tmp, 5);
166 if (!ISDD(tmp))
167 {
168 ALOGI("Unsupported bitstream id");
169 return 0;
170 }
171
172 ddbs_unprj(p_bstrm, &tmp, 3);
173 ddbs_unprj(p_bstrm, &acmod, 3);
174
175 if ((acmod!= MODE10) && (acmod& 0x1))
176 {
177 ddbs_unprj(p_bstrm, &tmp, 2);
178 }
179 if (acmod& 0x4)
180 {
181 ddbs_unprj(p_bstrm, &tmp, 2);
182 }
183
184 if (acmod == MODE20)
185 {
186 ddbs_unprj(p_bstrm,&tmp, 2);
187 }
188 ddbs_unprj(p_bstrm, &lfeon, 1);
189
190
191 numch = chanary[acmod];
192 if (0)
193 {
194 if (numch >= 3)
195 numch = 8;
196 else
197 numch = 2;
198 }else{
199 numch = 2;
200 }
201 *ChNum=numch;
202 //ALOGI("DEBUG:numch=%d sample_rate=%d %p [%s %d]",ChNum,sample_rate,this,__FUNCTION__,__LINE__);
203 return numch;
204}
205
206static int Get_DDP_Parameters(void *buf, int *sample_rate, int *frame_size,int *ChNum)
207{
208 int numch = 0;
209 DDP_BSTRM bstrm={NULL, 0, 0};
210 DDP_BSTRM *p_bstrm=&bstrm;
211 short tmp=0,acmod,lfeon,strmtyp;
212 ddbs_init((short*)buf,0,p_bstrm);
213 ddbs_unprj(p_bstrm, &tmp, 16);
214 if (tmp!= SYNCWRD) {
215 ALOGI("Invalid synchronization word");
216 return -1;
217 }
218
219 ddbs_unprj(p_bstrm, &strmtyp, 2);
220 ddbs_unprj(p_bstrm, &tmp, 3);
221 ddbs_unprj(p_bstrm, &tmp, 11);
222
223 *frame_size = 2 * (tmp + 1);
224 if (strmtyp != 0 && strmtyp != 2) {
225 return -1;
226 }
227 ddbs_unprj(p_bstrm, &tmp, 2);
228
229 if (tmp == 0x3) {
230 ALOGI("Half sample rate unsupported");
231 return -1;
232 } else {
233 if (tmp == 0)
234 *sample_rate = 48000;
235 else if (tmp == 1)
236 *sample_rate = 44100;
237 else if (tmp == 2)
238 *sample_rate = 32000;
239
240 ddbs_unprj(p_bstrm, &tmp, 2);
241 }
242 ddbs_unprj(p_bstrm, &acmod, 3);
243 ddbs_unprj(p_bstrm, &lfeon, 1);
244 numch = chanary[acmod];
245 numch = 2;
246 *ChNum = numch;
247 //ALOGI("DEBUG[%s %d]:numch=%d,sr=%d,frs=%d",__FUNCTION__,__LINE__,*ChNum,*sample_rate,*frame_size);
248 return 0;
249
250}
251
252static DDPerr ddbs_skip(DDP_BSTRM *p_bstrm, DDPshort numbits)
253{
254 p_bstrm->bitptr += numbits;
255 while (p_bstrm->bitptr >= BITSPERWRD)
256 {
257 p_bstrm->buf++;
258 p_bstrm->data = *p_bstrm->buf;
259 p_bstrm->bitptr -= BITSPERWRD;
260 }
261
262 return 0;
263}
264
265static DDPerr ddbs_getbsid(DDP_BSTRM *p_inbstrm, DDPshort *p_bsid)
266{
267 DDP_BSTRM bstrm;
268
269 ddbs_init(p_inbstrm->buf, p_inbstrm->bitptr, &bstrm);
270 ddbs_skip(&bstrm, BS_BITOFFSET);
271 ddbs_unprj(&bstrm, p_bsid, 5);
272 if (!ISDDP(*p_bsid) && !ISDD(*p_bsid))
273 {
274 ALOGI("Unsupported bitstream id");
275 }
276
277 return 0;
278}
279
280static int Get_Parameters(void *buf, int *sample_rate, int *frame_size,int *ChNum)
281 {
282 DDP_BSTRM bstrm={NULL, 0, 0};
283 DDP_BSTRM *p_bstrm=&bstrm;
284 DDPshort bsid;
285 int chnum = 0;
286 uint8_t ptr8[PTR_HEAD_SIZE];
287
288 memcpy(ptr8, buf, PTR_HEAD_SIZE);
289
290 //ALOGI("LZG->ptr_head:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x \n",
291 // ptr8[0],ptr8[1],ptr8[2], ptr8[3],ptr8[4],ptr8[5] );
292 if ((ptr8[0] == 0x0b) && (ptr8[1] == 0x77)) {
293 int i;
294 uint8_t tmp;
295 for (i = 0; i < PTR_HEAD_SIZE; i += 2) {
296 tmp = ptr8[i];
297 ptr8[i] = ptr8[i + 1];
298 ptr8[i + 1] = tmp;
299 }
300 }
301
302 ddbs_init((short*)ptr8,0,p_bstrm);
303 int ret = ddbs_getbsid(p_bstrm, &bsid);
304 if (ret < 0) {
305 return -1;
306 }
307
308 if (ISDDP(bsid)) {
309 Get_DDP_Parameters(ptr8, sample_rate, frame_size, ChNum);
310 }else if (ISDD(bsid)){
311 Get_DD_Parameters(ptr8, sample_rate, frame_size, ChNum);
312 }
313
314 return 0;
315}
316
317//----------------------------DDP Media Source----------------------------------------------
318
319static pthread_mutex_t decode_dev_op_mutex = PTHREAD_MUTEX_INITIALIZER;
320static int decode_ThreadExitFlag = 0; //0:exit from thread; 1:thread looping
321static int decode_ThreadStopFlag = 1; //0:start; 1: stop
322static pthread_t decode_ThreadID = 0;
323
324DDP_Media_Source::DDP_Media_Source(void) {
325 ALOGI("[%s: %d]\n", __FUNCTION__, __LINE__);
326 mStarted = false;
327 mMeta = new MetaData;
328 mGroup = NULL;
329 mSample_rate = 0;
330 mChNum = 0;
331 mFrame_size = 0;
332 mStop_ReadBuf_Flag = 0; //0:start 1:stop
333}
334
335DDP_Media_Source::~DDP_Media_Source() {
336}
337
338int DDP_Media_Source::GetSampleRate() {
339 ALOGI("[DDP_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__);
340 return mSample_rate;
341}
342int DDP_Media_Source::GetChNum() {
343 ALOGI("[DDP_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__);
344 return mChNum;
345}
346
347int DDP_Media_Source::Get_Stop_ReadBuf_Flag() {
348 return mStop_ReadBuf_Flag;
349}
350
351int DDP_Media_Source::Set_Stop_ReadBuf_Flag(int Stop) {
352 //ALOGI("[DDP_Media_Source::%s: %d]\n",__FUNCTION__,__LINE__);
353 mStop_ReadBuf_Flag = Stop;
354 return 0;
355}
356
357sp<MetaData> DDP_Media_Source::getFormat() {
358 ALOGI("[DDP_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__);
359 return mMeta;
360}
361
362status_t DDP_Media_Source::start(__unused MetaData *params) {
363 ALOGI("[DDP_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__);
364 mGroup = new MediaBufferGroup;
365 mGroup->add_buffer(new MediaBuffer(4096));
366 mStarted = true;
367 return OK;
368}
369
370status_t DDP_Media_Source::stop() {
371 ALOGI("[DDP_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__);
372 delete mGroup;
373 mGroup = NULL;
374 mStarted = false;
375 return OK;
376}
377
378int DDP_Media_Source::MediaSourceRead_buffer(unsigned char *buffer, int size) {
379 int readcnt = -1;
380 int sleep_time = 0;
381 if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) {
382 ALOGI("[DDP_Media_Source::%s] ddp mediasource stop!\n ", __FUNCTION__);
383 return -1;
384 }
385 while ((readcnt < size) && (mStop_ReadBuf_Flag == 0)
386 && (decode_ThreadStopFlag == 0)) {
387 readcnt = buffer_read(&android_out_buffer, (char*) buffer, size);
388 if (readcnt < 0) {
389 sleep_time++;
390 usleep(1000); //1ms
391 }
392 if (sleep_time > 2000) { //wait for max 1s to get audio data
393 ALOGE("[%s] time out to read audio buffer data! wait for 2s\n ",
394 __FUNCTION__);
395 return -1;
396 }
397 }
398 return readcnt;
399}
400
401status_t DDP_Media_Source::read(MediaBuffer **out, __unused const ReadOptions *options) {
402 *out = NULL;
403 unsigned char ptr_head[PTR_HEAD_SIZE] = { 0 };
404 int readedbytes;
405 int SyncFlag = 0;
406
407 resync: mFrame_size = 0;
408 SyncFlag = 0;
409
410 if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) {
411 ALOGI("Stop Flag is set, stop read_buf [%s %d]", __FUNCTION__,
412 __LINE__);
413 return ERROR_END_OF_STREAM;
414 }
415
416 if (MediaSourceRead_buffer(&ptr_head[0], 6) < 6) {
417 readedbytes = 6;
418 ALOGI("WARNING:read %d bytes failed [%s %d]!\n", readedbytes,
419 __FUNCTION__, __LINE__);
420 return ERROR_END_OF_STREAM;
421 }
422
423 if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) {
424 ALOGI("Stop Flag is set, stop read_buf [%s %d]", __FUNCTION__,
425 __LINE__);
426 return ERROR_END_OF_STREAM;
427 }
428
429 while (!SyncFlag) {
430 int i;
431 for (i = 0; i <= 4; i++) {
432 if ((ptr_head[i] == 0x0b && ptr_head[i + 1] == 0x77)
433 || (ptr_head[i] == 0x77 && ptr_head[i + 1] == 0x0b)) {
434 memcpy(&ptr_head[0], &ptr_head[i], 6 - i);
435 if (MediaSourceRead_buffer(&ptr_head[6 - i], i) < i) {
436 readedbytes = i;
437 ALOGI("WARNING: read %d bytes failed [%s %d]!\n",
438 readedbytes, __FUNCTION__, __LINE__);
439 return ERROR_END_OF_STREAM;
440 }
441
442 if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) {
443 ALOGI("Stop Flag is set, stop read_buf [%s %d]",
444 __FUNCTION__, __LINE__);
445 return ERROR_END_OF_STREAM;
446 }
447 SyncFlag = 1;
448 break;
449 }
450 }
451
452 if (SyncFlag == 0) {
453 ptr_head[0] = ptr_head[5];
454 if (MediaSourceRead_buffer(&ptr_head[1], 5) < 5) {
455 readedbytes = 5;
456 ALOGI("WARNING: fpread_buffer read %d bytes failed [%s %d]!\n",
457 readedbytes, __FUNCTION__, __LINE__);
458 return ERROR_END_OF_STREAM;
459 }
460
461 if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) {
462 ALOGI("Stop Flag is set, stop read_buf [%s %d]", __FUNCTION__,
463 __LINE__);
464 return ERROR_END_OF_STREAM;
465 }
466 }
467 }
468 if (MediaSourceRead_buffer(&ptr_head[6], PTR_HEAD_SIZE - 6)
469 < (PTR_HEAD_SIZE - 6)) {
470 readedbytes = PTR_HEAD_SIZE - 6;
471 ALOGI("WARNING: fpread_buffer read %d bytes failed [%s %d]!\n",
472 readedbytes, __FUNCTION__, __LINE__);
473 return ERROR_END_OF_STREAM;
474 }
475
476 Get_Parameters(ptr_head, &mSample_rate, &mFrame_size, &mChNum);
477 if ((mFrame_size == 0) || (mFrame_size < PTR_HEAD_SIZE) || (mChNum == 0)
478 || (mSample_rate == 0)) {
479 goto resync;
480 }
481
482 MediaBuffer *buffer;
483 status_t err = mGroup->acquire_buffer(&buffer);
484 if (err != OK) {
485 return err;
486 }
487 memcpy((unsigned char*) (buffer->data()), ptr_head, PTR_HEAD_SIZE);
488 if (MediaSourceRead_buffer(
489 (unsigned char*) (buffer->data()) + PTR_HEAD_SIZE,
490 mFrame_size - PTR_HEAD_SIZE) != (mFrame_size - PTR_HEAD_SIZE)) {
491 ALOGI("[%s %d]stream read failed:bytes_req/%d\n", __FUNCTION__,
492 __LINE__, (mFrame_size - PTR_HEAD_SIZE));
493 buffer->release();
494 buffer = NULL;
495 return ERROR_END_OF_STREAM;
496 }
497
498 buffer->set_range(0, mFrame_size);
499 buffer->meta_data()->setInt64(kKeyTime, 0);
500 buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
501
502 *out = buffer;
503 return OK;
504}
505
506//-------------------------------OMX codec------------------------------------------------
507
508const char *MEDIA_MIMETYPE_AUDIO_AC3 = "audio/ac3";
509const char *MEDIA_MIMETYPE_AUDIO_EAC3 = "audio/eac3";
510Aml_OMX_Codec::Aml_OMX_Codec(void) {
511 ALOGI("[Aml_OMX_Codec::%s: %d],atype %d\n", __FUNCTION__, __LINE__,spdif_audio_type);
512 m_codec = NULL;
513 status_t m_OMXClientConnectStatus = m_OMXClient.connect();
514 lock_init();
515 locked();
516 buf_decode_offset = 0;
517 buf_decode_offset_pre = 0;
518 if (m_OMXClientConnectStatus != OK) {
519 ALOGE("Err:omx client connect error\n");
520 } else {
521 const char *mine_type = NULL;
522 if (spdif_audio_type == EAC3)
523 mine_type = MEDIA_MIMETYPE_AUDIO_EAC3;
524 else
525 mine_type = MEDIA_MIMETYPE_AUDIO_AC3;
526 m_OMXMediaSource = new DDP_Media_Source();
527 sp < MetaData > metadata = m_OMXMediaSource->getFormat();
528 metadata->setCString(kKeyMIMEType, mine_type);
529 m_codec = SimpleDecodingSource::Create(m_OMXMediaSource, 0, 0);
530
531 if (m_codec != NULL) {
532 ALOGI("OMXCodec::Create success %s %d \n", __FUNCTION__, __LINE__);
533 } else {
534 ALOGE("Err: OMXCodec::Create failed %s %d \n", __FUNCTION__,
535 __LINE__);
536 }
537 }
538 unlocked();
539}
540
541Aml_OMX_Codec::~Aml_OMX_Codec() {
542}
543
544status_t Aml_OMX_Codec::read(unsigned char *buf, unsigned *size, int *exit) {
545 MediaBuffer *srcBuffer;
546 status_t status;
547
548 m_OMXMediaSource->Set_Stop_ReadBuf_Flag(*exit);
549
550 if (*exit) {
551 ALOGI("NOTE:exit flag enabled! [%s %d] \n", __FUNCTION__, __LINE__);
552 *size = 0;
553 return OK;
554 }
555
556 status = m_codec->read(&srcBuffer, NULL);
557
558 if (srcBuffer == NULL) {
559 *size = 0;
560 return OK;
561 }
562
563 *size = srcBuffer->range_length();
564
565 if (status == OK && (*size != 0)) {
566 memcpy((unsigned char *) buf,
567 (unsigned char *) srcBuffer->data() + srcBuffer->range_offset(),
568 *size);
569 srcBuffer->set_range(srcBuffer->range_offset() + (*size),
570 srcBuffer->range_length() - (*size));
571 srcBuffer->meta_data()->findInt64(kKeyTime, &buf_decode_offset);
572 }
573
574 if (srcBuffer->range_length() == 0) {
575 srcBuffer->release();
576 srcBuffer = NULL;
577 }
578
579 return OK;
580}
581
582status_t Aml_OMX_Codec::start() {
583 ALOGI("[Aml_OMX_Codec::%s %d] enter!\n", __FUNCTION__, __LINE__);
584 status_t status = m_codec->start();
585 if (status != OK) {
586 ALOGE("Err:OMX client can't start OMX decoder! status=%d (0x%08x)\n",
587 (int) status, (int) status);
588 m_codec.clear();
589 }
590 return status;
591}
592
593void Aml_OMX_Codec::stop() {
594 ALOGI("[Aml_OMX_Codec::%s %d] enter!\n", __FUNCTION__, __LINE__);
595 if (m_codec != NULL) {
596 if (m_OMXMediaSource->Get_Stop_ReadBuf_Flag())
597 m_OMXMediaSource->Set_Stop_ReadBuf_Flag(1);
598 m_codec->pause();
599 m_codec->stop();
600 wp < MediaSource > tmp = m_codec;
601 m_codec.clear();
602 while (tmp.promote() != NULL) {
603 ALOGI("[Aml_OMX_Codec::%s %d]wait m_codec free OK!\n", __FUNCTION__,
604 __LINE__);
605 usleep(1000);
606 }
607 m_OMXClient.disconnect();
608 m_OMXMediaSource.clear();
609 } else
610 ALOGE("m_codec==NULL, m_codec->stop() failed! [%s %d] \n", __FUNCTION__,
611 __LINE__);
612}
613
614void Aml_OMX_Codec::pause() {
615 ALOGI("[Aml_OMX_Codec::%s %d] \n", __FUNCTION__, __LINE__);
616 if (m_codec != NULL)
617 m_codec->pause();
618 else
619 ALOGE("m_codec==NULL, m_codec->pause() failed! [%s %d] \n",
620 __FUNCTION__, __LINE__);
621}
622
623int Aml_OMX_Codec::GetDecBytes() {
624 int used_len = 0;
625 used_len = buf_decode_offset - buf_decode_offset_pre;
626 buf_decode_offset_pre = buf_decode_offset;
627 return used_len;
628}
629
630void Aml_OMX_Codec::lock_init() {
631 pthread_mutexattr_t attr;
632 pthread_mutexattr_init(&attr);
633 pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
634 pthread_mutex_init(&lock, &attr);
635 pthread_mutexattr_destroy(&attr);
636}
637void Aml_OMX_Codec::locked() {
638 pthread_mutex_lock (&lock);
639}
640void Aml_OMX_Codec::unlocked() {
641 pthread_mutex_unlock (&lock);
642}
643
644//--------------------------------OMX_Codec_local API-------------------------------------------------
645
646Aml_OMX_Codec *arm_omx_codec = NULL;
647
648void omx_codec_pause() {
649 if (arm_omx_codec != NULL) {
650 arm_omx_codec->locked();
651 arm_omx_codec->pause();
652 arm_omx_codec->unlocked();
653 } else
654 ALOGE("arm_omx_codec==NULL arm_omx_codec->pause failed! %s %d \n",
655 __FUNCTION__, __LINE__);
656}
657
658void omx_codec_read(unsigned char *buf, unsigned *size, int *exit) {
659 if (arm_omx_codec != NULL) {
660 arm_omx_codec->locked();
661 arm_omx_codec->read(buf, size, exit);
662 arm_omx_codec->unlocked();
663 } else
664 ALOGE("arm_omx_codec==NULL arm_omx_codec->read failed! %s %d \n",
665 __FUNCTION__, __LINE__);
666}
667
668int omx_codec_get_declen() {
669 int declen = 0;
670 if (arm_omx_codec != NULL) {
671 arm_omx_codec->locked();
672 declen = arm_omx_codec->GetDecBytes();
673 arm_omx_codec->unlocked();
674 } else {
675 ALOGI(
676 "NOTE:arm_omx_codec==NULL arm_omx_codec_get_declen() return 0! %s %d \n",
677 __FUNCTION__, __LINE__);
678 }
679 return declen;
680}
681
682int omx_codec_get_FS() {
683 if (arm_omx_codec != NULL) {
684 return arm_omx_codec->m_OMXMediaSource->GetSampleRate();
685
686 } else {
687 ALOGI(
688 "NOTE:arm_omx_codec==NULL arm_omx_codec_get_FS() return 0! %s %d \n",
689 __FUNCTION__, __LINE__);
690 return 0;
691 }
692}
693
694int omx_codec_get_Nch() {
695 if (arm_omx_codec != NULL) {
696 return arm_omx_codec->m_OMXMediaSource->GetChNum();
697 } else {
698 ALOGI(
699 "NOTE:arm_omx_codec==NULL arm_omx_codec_get_Nch() return 0! %s %d \n",
700 __FUNCTION__, __LINE__);
701 return 0;
702 }
703}
704
705//--------------------------------------Decoder ThreadLoop--------------------------------------------
706
707void *decode_threadloop(__unused void *args) {
708 unsigned int outlen = 0;
709 unsigned int outlen_raw = 0;
710 unsigned int outlen_pcm = 0;
711 int write_sucessed = 1;
712 int ret = 0;
713 char *tmp = NULL;
714 tmp = (char*)malloc(6144*4+6144+8);
715 if (tmp == NULL) {
716 ALOGE("malloc buffer failed\n");
717 return NULL;
718 }
719 ALOGI("[%s %d] enter!\n", __FUNCTION__, __LINE__);
720 while (decode_ThreadStopFlag == 0) {
721 if (write_sucessed == 1) {
722 outlen = 0;
723 outlen_raw = 0;
724 outlen_pcm = 0;
725 omx_codec_read((unsigned char*)tmp, &outlen, &(decode_ThreadStopFlag));
726 }
727 if (decode_ThreadStopFlag == 1) {
728 ALOGD("%s, exit threadloop! \n", __FUNCTION__);
729 break;
730 }
731 if (outlen > 8) {
732 memcpy(&outlen_pcm,tmp,4);
733 memcpy(&outlen_raw,tmp+4+outlen_pcm,4);
734 if (outlen_pcm > 0) {
735 //ALOGI("pcm data size %d\n",outlen_pcm);
736 ret = buffer_write(&DDP_out_buffer, tmp+4, outlen_pcm);
737 if (ret < 0) {
738 write_sucessed = 0;
739 usleep(10 * 1000); //10ms
740 } else {
741 write_sucessed = 1;
742 }
743 }
744 if (outlen_raw > 0) {
745 //ALOGI("raw data size %d\n",outlen_raw);
746 ret = buffer_write(&DD_out_buffer, tmp+4+outlen_pcm+4, outlen_raw);
747 if (ret < 0) {
748 //write_sucessed = 0;
749 //ALOGI("raw data write failed\n");
750 usleep(10 * 1000); //10ms
751 } else {
752 //write_sucessed = 1;
753 }
754 }
755 }
756 }
757 decode_ThreadExitFlag = 0;
758 if (tmp) {
759 free(tmp);
760 }
761 ALOGD("%s, exiting...\n", __FUNCTION__);
762 return NULL;
763}
764
765static int start_decode_thread_omx(void) {
766 pthread_attr_t attr;
767 struct sched_param param;
768 int ret = 0;
769
770 ALOGI("[%s %d] enter!\n", __FUNCTION__, __LINE__);
771 pthread_mutex_lock(&decode_dev_op_mutex);
772 pthread_attr_init(&attr);
773 pthread_attr_setschedpolicy(&attr, SCHED_RR);
774 param.sched_priority = sched_get_priority_max(SCHED_RR);
775 pthread_attr_setschedparam(&attr, &param);
776 decode_ThreadStopFlag = 0;
777 decode_ThreadExitFlag = 1;
778 ret = pthread_create(&decode_ThreadID, &attr, &decode_threadloop, NULL);
779 pthread_attr_destroy(&attr);
780 if (ret != 0) {
781 ALOGE("%s, Create thread fail!\n", __FUNCTION__);
782 pthread_mutex_unlock(&decode_dev_op_mutex);
783 return -1;
784 }
785 pthread_mutex_unlock(&decode_dev_op_mutex);
786 ALOGD("[%s] exiting...\n", __FUNCTION__);
787 return 0;
788}
789
790static int stop_decode_thread_omx(void) {
791 int i = 0, tmp_timeout_count = 1000;
792
793 ALOGI("[%s %d] enter!\n", __FUNCTION__, __LINE__);
794 pthread_mutex_lock(&decode_dev_op_mutex);
795
796 decode_ThreadStopFlag = 1;
797 while (1) {
798 if (decode_ThreadExitFlag == 0)
799 break;
800 if (i >= tmp_timeout_count)
801 break;
802 i++;
803 usleep(1000);
804 }
805 if (i >= tmp_timeout_count) {
806 ALOGE(
807 "%s, Timeout: we have try %d ms, but the aml audio thread's exec flag is still(%d)!!!\n",
808 __FUNCTION__, tmp_timeout_count, decode_ThreadExitFlag);
809 } else {
810 ALOGD("%s, kill decode thread success after try %d ms.\n", __FUNCTION__,
811 i);
812 }
813
814 pthread_join(decode_ThreadID, NULL);
815 decode_ThreadID = 0;
816
817 ALOGD("%s, aml audio close success.\n", __FUNCTION__);
818 pthread_mutex_unlock(&decode_dev_op_mutex);
819 return 0;
820}
821
822//-------------------------------------external OMX_codec_api-----------------------------------------
823extern "C" {
824int omx_codec_init(void) {
825 int ret = 0;
826 ALOGI("omx_codec_init!\n");
827#ifndef USE_SYS_WRITE_SERVICE
828 ret=property_set("media.libplayer.dtsopt0", "1");
829 ALOGI("property_set<media.libplayer.dtsopt0> ret/%d\n",ret);
830#else
831 amSystemWriteSetProperty("media.libplayer.dtsopt0", "1");
832#endif
833 arm_omx_codec = new android::Aml_OMX_Codec();
834 if (arm_omx_codec == NULL) {
835 ALOGE("Err:arm_omx_codec_init failed!\n");
836 return -1;
837 }
838
839 arm_omx_codec->locked();
840 ret = arm_omx_codec->start();
841 arm_omx_codec->unlocked();
842 if (ret < 0) {
843 goto Exit;
844 }
845
846 ret = start_decode_thread_omx();
847 if (ret == 0)
848 return 0;
849 Exit: arm_omx_codec->stop();
850 delete arm_omx_codec;
851 arm_omx_codec = NULL;
852 return -1;
853}
854
855void omx_codec_close(void) {
856 int ret = 0;
857#ifndef USE_SYS_WRITE_SERVICE
858 ret=property_set("media.libplayer.dtsopt0", "0");
859 ALOGI("property_set<media.libplayer.dtsopt0> ret/%d\n",ret);
860#else
861 amSystemWriteSetProperty("media.libplayer.dtsopt0", "0");
862#endif
863 if (arm_omx_codec == NULL) {
864 ALOGI(
865 "NOTE:arm_omx_codec==NULL arm_omx_codec_close() do nothing! %s %d \n",
866 __FUNCTION__, __LINE__);
867 return;
868 }
869 ALOGI("omx_codec_close!\n");
870 stop_decode_thread_omx();
871 arm_omx_codec->locked();
872 arm_omx_codec->stop();
873 arm_omx_codec->unlocked();
874 delete arm_omx_codec;
875 arm_omx_codec = NULL;
876 return;
877}
878
879}
880}
881
882