summaryrefslogtreecommitdiff
path: root/libTVaudio/audio/DDP_media_source.cpp (plain)
blob: 55769cd181d245a2bc5224c623bcf279b288bc3a
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 mMeta->setInt32(kKeyChannelCount, 2);
334 mMeta->setInt32(kKeySampleRate, 48000);
335}
336
337DDP_Media_Source::~DDP_Media_Source() {
338}
339
340int DDP_Media_Source::GetSampleRate() {
341 ALOGI("[DDP_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__);
342 return mSample_rate;
343}
344int DDP_Media_Source::GetChNum() {
345 ALOGI("[DDP_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__);
346 return mChNum;
347}
348
349int DDP_Media_Source::Get_Stop_ReadBuf_Flag() {
350 return mStop_ReadBuf_Flag;
351}
352
353int DDP_Media_Source::Set_Stop_ReadBuf_Flag(int Stop) {
354 //ALOGI("[DDP_Media_Source::%s: %d]\n",__FUNCTION__,__LINE__);
355 mStop_ReadBuf_Flag = Stop;
356 return 0;
357}
358
359sp<MetaData> DDP_Media_Source::getFormat() {
360 ALOGI("[DDP_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__);
361 return mMeta;
362}
363
364status_t DDP_Media_Source::start(__unused MetaData *params) {
365 ALOGI("[DDP_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__);
366 mGroup = new MediaBufferGroup;
367 mGroup->add_buffer(new MediaBuffer(4096));
368 mStarted = true;
369 return OK;
370}
371
372status_t DDP_Media_Source::stop() {
373 ALOGI("[DDP_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__);
374 delete mGroup;
375 mGroup = NULL;
376 mStarted = false;
377 return OK;
378}
379
380int DDP_Media_Source::MediaSourceRead_buffer(unsigned char *buffer, int size) {
381 int readcnt = -1;
382 int sleep_time = 0;
383 if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) {
384 ALOGI("[DDP_Media_Source::%s] ddp mediasource stop!\n ", __FUNCTION__);
385 return -1;
386 }
387 while ((readcnt < size) && (mStop_ReadBuf_Flag == 0)
388 && (decode_ThreadStopFlag == 0)) {
389 readcnt = buffer_read(&android_out_buffer, (char*) buffer, size);
390 if (readcnt < 0) {
391 sleep_time++;
392 usleep(1000); //1ms
393 }
394 if (sleep_time > 2000) { //wait for max 1s to get audio data
395 ALOGE("[%s] time out to read audio buffer data! wait for 2s\n ",
396 __FUNCTION__);
397 return -1;
398 }
399 }
400 return readcnt;
401}
402
403status_t DDP_Media_Source::read(MediaBuffer **out, __unused const ReadOptions *options) {
404 *out = NULL;
405 unsigned char ptr_head[PTR_HEAD_SIZE] = { 0 };
406 int readedbytes;
407 int SyncFlag = 0;
408
409 resync: mFrame_size = 0;
410 SyncFlag = 0;
411
412 if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) {
413 ALOGI("Stop Flag is set, stop read_buf [%s %d]", __FUNCTION__,
414 __LINE__);
415 return ERROR_END_OF_STREAM;
416 }
417
418 if (MediaSourceRead_buffer(&ptr_head[0], 6) < 6) {
419 readedbytes = 6;
420 ALOGI("WARNING:read %d bytes failed [%s %d]!\n", readedbytes,
421 __FUNCTION__, __LINE__);
422 return ERROR_END_OF_STREAM;
423 }
424
425 if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) {
426 ALOGI("Stop Flag is set, stop read_buf [%s %d]", __FUNCTION__,
427 __LINE__);
428 return ERROR_END_OF_STREAM;
429 }
430
431 while (!SyncFlag) {
432 int i;
433 for (i = 0; i <= 4; i++) {
434 if ((ptr_head[i] == 0x0b && ptr_head[i + 1] == 0x77)
435 || (ptr_head[i] == 0x77 && ptr_head[i + 1] == 0x0b)) {
436 memcpy(&ptr_head[0], &ptr_head[i], 6 - i);
437 if (MediaSourceRead_buffer(&ptr_head[6 - i], i) < i) {
438 readedbytes = i;
439 ALOGI("WARNING: read %d bytes failed [%s %d]!\n",
440 readedbytes, __FUNCTION__, __LINE__);
441 return ERROR_END_OF_STREAM;
442 }
443
444 if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) {
445 ALOGI("Stop Flag is set, stop read_buf [%s %d]",
446 __FUNCTION__, __LINE__);
447 return ERROR_END_OF_STREAM;
448 }
449 SyncFlag = 1;
450 break;
451 }
452 }
453
454 if (SyncFlag == 0) {
455 ptr_head[0] = ptr_head[5];
456 if (MediaSourceRead_buffer(&ptr_head[1], 5) < 5) {
457 readedbytes = 5;
458 ALOGI("WARNING: fpread_buffer read %d bytes failed [%s %d]!\n",
459 readedbytes, __FUNCTION__, __LINE__);
460 return ERROR_END_OF_STREAM;
461 }
462
463 if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) {
464 ALOGI("Stop Flag is set, stop read_buf [%s %d]", __FUNCTION__,
465 __LINE__);
466 return ERROR_END_OF_STREAM;
467 }
468 }
469 }
470 if (MediaSourceRead_buffer(&ptr_head[6], PTR_HEAD_SIZE - 6)
471 < (PTR_HEAD_SIZE - 6)) {
472 readedbytes = PTR_HEAD_SIZE - 6;
473 ALOGI("WARNING: fpread_buffer read %d bytes failed [%s %d]!\n",
474 readedbytes, __FUNCTION__, __LINE__);
475 return ERROR_END_OF_STREAM;
476 }
477
478 Get_Parameters(ptr_head, &mSample_rate, &mFrame_size, &mChNum);
479 if ((mFrame_size == 0) || (mFrame_size < PTR_HEAD_SIZE) || (mChNum == 0)
480 || (mSample_rate == 0)) {
481 goto resync;
482 }
483
484 MediaBuffer *buffer;
485 status_t err = mGroup->acquire_buffer(&buffer);
486 if (err != OK) {
487 return err;
488 }
489 memcpy((unsigned char*) (buffer->data()), ptr_head, PTR_HEAD_SIZE);
490 if (MediaSourceRead_buffer(
491 (unsigned char*) (buffer->data()) + PTR_HEAD_SIZE,
492 mFrame_size - PTR_HEAD_SIZE) != (mFrame_size - PTR_HEAD_SIZE)) {
493 ALOGI("[%s %d]stream read failed:bytes_req/%d\n", __FUNCTION__,
494 __LINE__, (mFrame_size - PTR_HEAD_SIZE));
495 buffer->release();
496 buffer = NULL;
497 return ERROR_END_OF_STREAM;
498 }
499
500 buffer->set_range(0, mFrame_size);
501 buffer->meta_data()->setInt64(kKeyTime, 0);
502 buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
503
504 *out = buffer;
505 return OK;
506}
507
508//-------------------------------OMX codec------------------------------------------------
509
510const char *MEDIA_MIMETYPE_AUDIO_AC3 = "audio/ac3";
511const char *MEDIA_MIMETYPE_AUDIO_EAC3 = "audio/eac3";
512Aml_OMX_Codec::Aml_OMX_Codec(void) {
513 ALOGI("[Aml_OMX_Codec::%s: %d],atype %d\n", __FUNCTION__, __LINE__,spdif_audio_type);
514 m_codec = NULL;
515 status_t m_OMXClientConnectStatus = m_OMXClient.connect();
516 lock_init();
517 locked();
518 buf_decode_offset = 0;
519 buf_decode_offset_pre = 0;
520 if (m_OMXClientConnectStatus != OK) {
521 ALOGE("Err:omx client connect error\n");
522 } else {
523 const char *mine_type = NULL;
524 if (spdif_audio_type == EAC3)
525 mine_type = MEDIA_MIMETYPE_AUDIO_EAC3;
526 else
527 mine_type = MEDIA_MIMETYPE_AUDIO_AC3;
528 m_OMXMediaSource = new DDP_Media_Source();
529 sp < MetaData > metadata = m_OMXMediaSource->getFormat();
530 metadata->setCString(kKeyMIMEType, mine_type);
531 m_codec = SimpleDecodingSource::Create(m_OMXMediaSource, 0, 0);
532
533 if (m_codec != NULL) {
534 ALOGI("OMXCodec::Create success %s %d \n", __FUNCTION__, __LINE__);
535 } else {
536 ALOGE("Err: OMXCodec::Create failed %s %d \n", __FUNCTION__,
537 __LINE__);
538 }
539 }
540 unlocked();
541}
542
543Aml_OMX_Codec::~Aml_OMX_Codec() {
544}
545
546status_t Aml_OMX_Codec::read(unsigned char *buf, unsigned *size, int *exit) {
547 MediaBuffer *srcBuffer;
548 status_t status;
549
550 if (m_codec == NULL) {
551 return -1;
552 }
553
554 m_OMXMediaSource->Set_Stop_ReadBuf_Flag(*exit);
555
556 if (*exit) {
557 ALOGI("NOTE:exit flag enabled! [%s %d] \n", __FUNCTION__, __LINE__);
558 *size = 0;
559 return OK;
560 }
561
562 status = m_codec->read(&srcBuffer, NULL);
563
564 if (srcBuffer == NULL) {
565 *size = 0;
566 return OK;
567 }
568
569 *size = srcBuffer->range_length();
570
571 if (status == OK && (*size != 0)) {
572 memcpy((unsigned char *) buf,
573 (unsigned char *) srcBuffer->data() + srcBuffer->range_offset(),
574 *size);
575 srcBuffer->set_range(srcBuffer->range_offset() + (*size),
576 srcBuffer->range_length() - (*size));
577 srcBuffer->meta_data()->findInt64(kKeyTime, &buf_decode_offset);
578 }
579
580 if (srcBuffer->range_length() == 0) {
581 srcBuffer->release();
582 srcBuffer = NULL;
583 }
584
585 return OK;
586}
587
588status_t Aml_OMX_Codec::start() {
589 ALOGI("[Aml_OMX_Codec::%s %d] enter!\n", __FUNCTION__, __LINE__);
590 status_t status;
591 if (m_codec != NULL)
592 status = m_codec->start();
593 else
594 ALOGE("m_codec==NULL, m_codec->pause() start! [%s %d] \n",
595 __FUNCTION__, __LINE__);
596
597 if (status != OK) {
598 ALOGE("Err:OMX client can't start OMX decoder! status=%d (0x%08x)\n",
599 (int) status, (int) status);
600 m_codec.clear();
601 }
602 return status;
603}
604
605void Aml_OMX_Codec::stop() {
606 ALOGI("[Aml_OMX_Codec::%s %d] enter!\n", __FUNCTION__, __LINE__);
607 if (m_codec != NULL) {
608 if (m_OMXMediaSource->Get_Stop_ReadBuf_Flag())
609 m_OMXMediaSource->Set_Stop_ReadBuf_Flag(1);
610 m_codec->pause();
611 m_codec->stop();
612 wp < MediaSource > tmp = m_codec;
613 m_codec.clear();
614 while (tmp.promote() != NULL) {
615 ALOGI("[Aml_OMX_Codec::%s %d]wait m_codec free OK!\n", __FUNCTION__,
616 __LINE__);
617 usleep(1000);
618 }
619 m_OMXClient.disconnect();
620 m_OMXMediaSource.clear();
621 } else
622 ALOGE("m_codec==NULL, m_codec->stop() failed! [%s %d] \n", __FUNCTION__,
623 __LINE__);
624}
625
626void Aml_OMX_Codec::pause() {
627 ALOGI("[Aml_OMX_Codec::%s %d] \n", __FUNCTION__, __LINE__);
628 if (m_codec != NULL)
629 m_codec->pause();
630 else
631 ALOGE("m_codec==NULL, m_codec->pause() failed! [%s %d] \n",
632 __FUNCTION__, __LINE__);
633}
634
635int Aml_OMX_Codec::GetDecBytes() {
636 int used_len = 0;
637 used_len = buf_decode_offset - buf_decode_offset_pre;
638 buf_decode_offset_pre = buf_decode_offset;
639 return used_len;
640}
641
642void Aml_OMX_Codec::lock_init() {
643 pthread_mutexattr_t attr;
644 pthread_mutexattr_init(&attr);
645 pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
646 pthread_mutex_init(&lock, &attr);
647 pthread_mutexattr_destroy(&attr);
648}
649void Aml_OMX_Codec::locked() {
650 pthread_mutex_lock (&lock);
651}
652void Aml_OMX_Codec::unlocked() {
653 pthread_mutex_unlock (&lock);
654}
655
656//--------------------------------OMX_Codec_local API-------------------------------------------------
657
658Aml_OMX_Codec *arm_omx_codec = NULL;
659
660void omx_codec_pause() {
661 if (arm_omx_codec != NULL) {
662 arm_omx_codec->locked();
663 arm_omx_codec->pause();
664 arm_omx_codec->unlocked();
665 } else
666 ALOGE("arm_omx_codec==NULL arm_omx_codec->pause failed! %s %d \n",
667 __FUNCTION__, __LINE__);
668}
669
670void omx_codec_read(unsigned char *buf, unsigned *size, int *exit) {
671 if (arm_omx_codec != NULL) {
672 arm_omx_codec->locked();
673 arm_omx_codec->read(buf, size, exit);
674 arm_omx_codec->unlocked();
675 } else
676 ALOGE("arm_omx_codec==NULL arm_omx_codec->read failed! %s %d \n",
677 __FUNCTION__, __LINE__);
678}
679
680int omx_codec_get_declen() {
681 int declen = 0;
682 if (arm_omx_codec != NULL) {
683 arm_omx_codec->locked();
684 declen = arm_omx_codec->GetDecBytes();
685 arm_omx_codec->unlocked();
686 } else {
687 ALOGI(
688 "NOTE:arm_omx_codec==NULL arm_omx_codec_get_declen() return 0! %s %d \n",
689 __FUNCTION__, __LINE__);
690 }
691 return declen;
692}
693
694int omx_codec_get_FS() {
695 if (arm_omx_codec != NULL) {
696 return arm_omx_codec->m_OMXMediaSource->GetSampleRate();
697
698 } else {
699 ALOGI(
700 "NOTE:arm_omx_codec==NULL arm_omx_codec_get_FS() return 0! %s %d \n",
701 __FUNCTION__, __LINE__);
702 return 0;
703 }
704}
705
706int omx_codec_get_Nch() {
707 if (arm_omx_codec != NULL) {
708 return arm_omx_codec->m_OMXMediaSource->GetChNum();
709 } else {
710 ALOGI(
711 "NOTE:arm_omx_codec==NULL arm_omx_codec_get_Nch() return 0! %s %d \n",
712 __FUNCTION__, __LINE__);
713 return 0;
714 }
715}
716
717//--------------------------------------Decoder ThreadLoop--------------------------------------------
718
719void *decode_threadloop(__unused void *args) {
720 unsigned int outlen = 0;
721 unsigned int outlen_raw = 0;
722 unsigned int outlen_pcm = 0;
723 int write_sucessed = 1;
724 int ret = 0;
725 char *tmp = NULL;
726 tmp = (char*)malloc(6144*4+6144+8);
727 if (tmp == NULL) {
728 ALOGE("malloc buffer failed\n");
729 return NULL;
730 }
731 ALOGI("[%s %d] enter!\n", __FUNCTION__, __LINE__);
732 while (decode_ThreadStopFlag == 0) {
733 if (write_sucessed == 1) {
734 outlen = 0;
735 outlen_raw = 0;
736 outlen_pcm = 0;
737 omx_codec_read((unsigned char*)tmp, &outlen, &(decode_ThreadStopFlag));
738 }
739 if (decode_ThreadStopFlag == 1) {
740 ALOGD("%s, exit threadloop! \n", __FUNCTION__);
741 break;
742 }
743 if (outlen > 8) {
744 memcpy(&outlen_pcm,tmp,4);
745 memcpy(&outlen_raw,tmp+4+outlen_pcm,4);
746 if (outlen_pcm > 0) {
747 //ALOGI("pcm data size %d\n",outlen_pcm);
748 ret = buffer_write(&DDP_out_buffer, tmp+4, outlen_pcm);
749 if (ret < 0) {
750 write_sucessed = 0;
751 usleep(10 * 1000); //10ms
752 } else {
753 write_sucessed = 1;
754 }
755 }
756 if (outlen_raw > 0) {
757 //ALOGI("raw data size %d\n",outlen_raw);
758 ret = buffer_write(&DD_out_buffer, tmp+4+outlen_pcm+4, outlen_raw);
759 if (ret < 0) {
760 //write_sucessed = 0;
761 //ALOGI("raw data write failed\n");
762 usleep(10 * 1000); //10ms
763 } else {
764 //write_sucessed = 1;
765 }
766 }
767 }
768 }
769 decode_ThreadExitFlag = 0;
770 if (tmp) {
771 free(tmp);
772 }
773 ALOGD("%s, exiting...\n", __FUNCTION__);
774 return NULL;
775}
776
777static int start_decode_thread_omx(void) {
778 pthread_attr_t attr;
779 struct sched_param param;
780 int ret = 0;
781
782 ALOGI("[%s %d] enter!\n", __FUNCTION__, __LINE__);
783 pthread_mutex_lock(&decode_dev_op_mutex);
784 pthread_attr_init(&attr);
785 pthread_attr_setschedpolicy(&attr, SCHED_RR);
786 param.sched_priority = sched_get_priority_max(SCHED_RR);
787 pthread_attr_setschedparam(&attr, &param);
788 decode_ThreadStopFlag = 0;
789 decode_ThreadExitFlag = 1;
790 ret = pthread_create(&decode_ThreadID, &attr, &decode_threadloop, NULL);
791 pthread_attr_destroy(&attr);
792 if (ret != 0) {
793 ALOGE("%s, Create thread fail!\n", __FUNCTION__);
794 pthread_mutex_unlock(&decode_dev_op_mutex);
795 return -1;
796 }
797 pthread_mutex_unlock(&decode_dev_op_mutex);
798 ALOGD("[%s] exiting...\n", __FUNCTION__);
799 return 0;
800}
801
802static int stop_decode_thread_omx(void) {
803 int i = 0, tmp_timeout_count = 1000;
804
805 ALOGI("[%s %d] enter!\n", __FUNCTION__, __LINE__);
806 pthread_mutex_lock(&decode_dev_op_mutex);
807
808 decode_ThreadStopFlag = 1;
809 while (1) {
810 if (decode_ThreadExitFlag == 0)
811 break;
812 if (i >= tmp_timeout_count)
813 break;
814 i++;
815 usleep(1000);
816 }
817 if (i >= tmp_timeout_count) {
818 ALOGE(
819 "%s, Timeout: we have try %d ms, but the aml audio thread's exec flag is still(%d)!!!\n",
820 __FUNCTION__, tmp_timeout_count, decode_ThreadExitFlag);
821 } else {
822 ALOGD("%s, kill decode thread success after try %d ms.\n", __FUNCTION__,
823 i);
824 }
825
826 pthread_join(decode_ThreadID, NULL);
827 decode_ThreadID = 0;
828
829 ALOGD("%s, aml audio close success.\n", __FUNCTION__);
830 pthread_mutex_unlock(&decode_dev_op_mutex);
831 return 0;
832}
833
834//-------------------------------------external OMX_codec_api-----------------------------------------
835extern "C" {
836int omx_codec_init(void) {
837 int ret = 0;
838 ALOGI("omx_codec_init!\n");
839#ifndef USE_SYS_WRITE_SERVICE
840 ret=property_set("media.libplayer.dtsopt0", "1");
841 ALOGI("property_set<media.libplayer.dtsopt0> ret/%d\n",ret);
842#else
843 amSystemWriteSetProperty("media.libplayer.dtsopt0", "1");
844#endif
845 arm_omx_codec = new android::Aml_OMX_Codec();
846 if (arm_omx_codec == NULL) {
847 ALOGE("Err:arm_omx_codec_init failed!\n");
848 return -1;
849 }
850
851 arm_omx_codec->locked();
852 ret = arm_omx_codec->start();
853 arm_omx_codec->unlocked();
854 if (ret < 0) {
855 goto Exit;
856 }
857
858 ret = start_decode_thread_omx();
859 if (ret == 0)
860 return 0;
861 Exit: arm_omx_codec->stop();
862 delete arm_omx_codec;
863 arm_omx_codec = NULL;
864 return -1;
865}
866
867void omx_codec_close(void) {
868 int ret = 0;
869#ifndef USE_SYS_WRITE_SERVICE
870 ret=property_set("media.libplayer.dtsopt0", "0");
871 ALOGI("property_set<media.libplayer.dtsopt0> ret/%d\n",ret);
872#else
873 amSystemWriteSetProperty("media.libplayer.dtsopt0", "0");
874#endif
875 if (arm_omx_codec == NULL) {
876 ALOGI(
877 "NOTE:arm_omx_codec==NULL arm_omx_codec_close() do nothing! %s %d \n",
878 __FUNCTION__, __LINE__);
879 return;
880 }
881 ALOGI("omx_codec_close!\n");
882 stop_decode_thread_omx();
883 arm_omx_codec->locked();
884 arm_omx_codec->stop();
885 arm_omx_codec->unlocked();
886 delete arm_omx_codec;
887 arm_omx_codec = NULL;
888 return;
889}
890
891}
892}
893
894