blob: f3c107cd515e1b7437b435a6ecec6e4fd1e9c701
1 | #define LOG_TAG "DTSHD_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 "DTSHD_media_source.h" |
31 | #include "aml_audio.h" |
32 | extern struct circle_buffer android_out_buffer; |
33 | extern struct circle_buffer DDP_out_buffer; |
34 | extern struct circle_buffer DD_out_buffer; |
35 | extern int spdif_audio_type; |
36 | namespace android { |
37 | |
38 | #ifdef USE_SYS_WRITE_SERVICE |
39 | //code here for system write service |
40 | class DeathNotifier: public IBinder::DeathRecipient |
41 | { |
42 | public: |
43 | DeathNotifier() { |
44 | } |
45 | |
46 | void binderDied(__unused const wp<IBinder>& who) { |
47 | ALOGW("system_write died!"); |
48 | } |
49 | }; |
50 | |
51 | |
52 | #if ANDROID_PLATFORM_SDK_VERSION >= 21 //5.0 |
53 | //used ISystemControlService |
54 | #define SYST_SERVICES_NAME "system_control" |
55 | #else |
56 | //used amSystemWriteService |
57 | #define ISystemControlService ISystemWriteService |
58 | #define SYST_SERVICES_NAME "system_write" |
59 | #endif |
60 | |
61 | static sp<ISystemControlService> amSystemWriteService; |
62 | static sp<DeathNotifier> amDeathNotifier; |
63 | static Mutex amLock; |
64 | static Mutex amgLock; |
65 | |
66 | const sp<ISystemControlService>& getSystemWriteServiceDts() |
67 | { |
68 | Mutex::Autolock _l(amgLock); |
69 | if (amSystemWriteService.get() == 0) { |
70 | sp<IServiceManager> sm = defaultServiceManager(); |
71 | #if 0 |
72 | sp<IBinder> binder; |
73 | do { |
74 | binder = sm->getService(String16("system_write")); |
75 | if (binder != 0) |
76 | break; |
77 | ALOGW("SystemWriteService not published, waiting..."); |
78 | usleep(500000); // 0.5 s |
79 | } while(true); |
80 | if (amDeathNotifier == NULL) { |
81 | amDeathNotifier = new DeathNotifier(); |
82 | } |
83 | binder->linkToDeath(amDeathNotifier); |
84 | amSystemWriteService = interface_cast<ISystemWriteService>(binder); |
85 | #endif |
86 | |
87 | |
88 | amSystemWriteService = interface_cast<ISystemControlService>(sm->getService(String16(SYST_SERVICES_NAME))); |
89 | |
90 | } |
91 | ALOGE_IF(amSystemWriteService==0, "no SystemWrite Service!?"); |
92 | |
93 | return amSystemWriteService; |
94 | } |
95 | void amSystemWriteSetPropertyDts(const char* key, const char* value) |
96 | { |
97 | const sp<ISystemControlService>& sws = getSystemWriteServiceDts(); |
98 | if (sws != 0) { |
99 | sws->setProperty(String16(key), String16(value)); |
100 | } |
101 | } |
102 | //code end for system write service |
103 | #endif |
104 | |
105 | //----------------------------DTS Media Source---------------------------------------------- |
106 | |
107 | static pthread_mutex_t decode_dev_op_mutex = PTHREAD_MUTEX_INITIALIZER; |
108 | static int decode_ThreadExitFlag = 0; //0:exit from thread; 1:thread looping |
109 | static int decode_ThreadStopFlag = 1; //0:start; 1: stop |
110 | static pthread_t decode_ThreadID = 0; |
111 | |
112 | Dtshd_Media_Source::Dtshd_Media_Source(void) { |
113 | ALOGI("[%s: %d]\n", __FUNCTION__, __LINE__); |
114 | mStarted = false; |
115 | mMeta = new MetaData; |
116 | mGroup = NULL; |
117 | mSample_rate = 0; |
118 | mChNum = 0; |
119 | mFrame_size = 0; |
120 | mStop_ReadBuf_Flag = 0; //0:start 1:stop |
121 | |
122 | mDataSource=NULL; |
123 | mBytesReaded=0; |
124 | mCurrentTimeUs=0; |
125 | bytes_readed_sum_pre=0; |
126 | bytes_readed_sum=0; |
127 | |
128 | mMeta->setInt32(kKeyChannelCount, 2); |
129 | mMeta->setInt32(kKeySampleRate, 48000); |
130 | } |
131 | |
132 | Dtshd_Media_Source::~Dtshd_Media_Source() { |
133 | ALOGI("%s %d \n",__FUNCTION__,__LINE__); |
134 | if (mStarted) { |
135 | stop(); |
136 | } |
137 | } |
138 | |
139 | int Dtshd_Media_Source::GetSampleRate() { |
140 | ALOGI("[Dtshd_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__); |
141 | return mSample_rate; |
142 | } |
143 | int Dtshd_Media_Source::GetChNum() { |
144 | ALOGI("[Dtshd_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__); |
145 | return mChNum; |
146 | } |
147 | |
148 | int Dtshd_Media_Source::Get_Stop_ReadBuf_Flag() { |
149 | return mStop_ReadBuf_Flag; |
150 | } |
151 | |
152 | int Dtshd_Media_Source::Set_Stop_ReadBuf_Flag(int Stop) { |
153 | mStop_ReadBuf_Flag = Stop; |
154 | return 0; |
155 | } |
156 | |
157 | sp<MetaData> Dtshd_Media_Source::getFormat() { |
158 | ALOGI("[Dtshd_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__); |
159 | return mMeta; |
160 | } |
161 | |
162 | status_t Dtshd_Media_Source::start(__unused MetaData *params) { |
163 | ALOGI("[Dtshd_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__); |
164 | mGroup = new MediaBufferGroup; |
165 | mGroup->add_buffer(new MediaBuffer(4096*2)); |
166 | mStarted = true; |
167 | return OK; |
168 | } |
169 | |
170 | status_t Dtshd_Media_Source::stop() { |
171 | ALOGI("[Dtshd_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__); |
172 | delete mGroup; |
173 | mGroup = NULL; |
174 | mStarted = false; |
175 | return OK; |
176 | } |
177 | |
178 | int Dtshd_Media_Source::MediaSourceRead_buffer(unsigned char *buffer, int size) { |
179 | int readcnt = -1; |
180 | int sleep_time = 0; |
181 | if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) { |
182 | ALOGI("[Dtshd_Media_Source::%s] dtshd mediasource stop!\n ", __FUNCTION__); |
183 | return -1; |
184 | } |
185 | while ((readcnt < size) && (mStop_ReadBuf_Flag == 0) |
186 | && (decode_ThreadStopFlag == 0)) { |
187 | readcnt = buffer_read(&android_out_buffer, (char*) buffer, size); |
188 | //ALOGI("readcnt:%d,sleep_time:%d,size:%d",readcnt,sleep_time,size); |
189 | if (readcnt < 0) { |
190 | sleep_time++; |
191 | usleep(1000); //1ms |
192 | } |
193 | if (sleep_time > 2000) { //wait for max 1s to get audio data |
194 | ALOGE("[%s] time out to read audio buffer data! wait for 2s\n ", |
195 | __FUNCTION__); |
196 | return -1; |
197 | } |
198 | } |
199 | return readcnt; |
200 | } |
201 | status_t Dtshd_Media_Source::read(MediaBuffer **out, __unused const ReadOptions *options) { |
202 | *out = NULL; |
203 | unsigned char ptr_head[4] = { 0 }; |
204 | unsigned char ptr_head2[IEC61937_DTS_HEAD_PTR -4] = { 0 }; |
205 | int SyncFlag = 0; |
206 | int readedbytes = 0; |
207 | int i = 0 ; |
208 | if (MediaSourceRead_buffer(&ptr_head[0], 4) < 4) { |
209 | readedbytes = 4; |
210 | ALOGI("WARNING:read %d bytes failed [%s %d]!\n", readedbytes, |
211 | __FUNCTION__, __LINE__); |
212 | return ERROR_END_OF_STREAM; |
213 | } |
214 | |
215 | mFrame_size = 0; |
216 | SyncFlag = 0; |
217 | |
218 | if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) { |
219 | ALOGI("Stop Flag is set, stop read_buf [%s %d]", __FUNCTION__, |
220 | __LINE__); |
221 | return ERROR_END_OF_STREAM; |
222 | } |
223 | if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) { |
224 | ALOGI("Stop Flag is set, stop read_buf [%s %d]", __FUNCTION__, |
225 | __LINE__); |
226 | return ERROR_END_OF_STREAM; |
227 | } |
228 | while (!SyncFlag) { |
229 | int i =0; |
230 | //DTS_SYNCWORD_IEC61937 : 0xF8724E1F |
231 | if ((ptr_head[0] == 0x72 && ptr_head[ 1] == 0xf8 |
232 | &&ptr_head[2] == 0x1f && ptr_head[3] == 0x4e)|| |
233 | (ptr_head[0] == 0xf8 && ptr_head[1] == 0x72 |
234 | &&ptr_head[2] == 0x4e && ptr_head[3] == 0x1f)) { |
235 | |
236 | if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) { |
237 | ALOGI("Stop Flag is set, stop read_buf [%s %d]", |
238 | __FUNCTION__, __LINE__); |
239 | return ERROR_END_OF_STREAM; |
240 | } |
241 | SyncFlag = 1; |
242 | } |
243 | if (SyncFlag == 0) { |
244 | ptr_head[0] =ptr_head[1]; |
245 | ptr_head[1] =ptr_head[2]; |
246 | ptr_head[2] =ptr_head[3]; |
247 | if (MediaSourceRead_buffer(&ptr_head[3], 1) < 1) { |
248 | readedbytes = 1; |
249 | ALOGI("WARNING: read %d bytes failed [%s %d]!\n", |
250 | readedbytes, __FUNCTION__, __LINE__); |
251 | return ERROR_END_OF_STREAM; |
252 | } |
253 | |
254 | if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) { |
255 | ALOGI("Stop Flag is set, stop read_buf [%s %d]", __FUNCTION__, |
256 | __LINE__); |
257 | return ERROR_END_OF_STREAM; |
258 | } |
259 | } |
260 | } |
261 | if (MediaSourceRead_buffer(&ptr_head2[0], 4) < 4) { |
262 | readedbytes = 4; |
263 | ALOGI("WARNING:read %d bytes failed [%s %d]!\n", readedbytes, |
264 | __FUNCTION__, __LINE__); |
265 | return ERROR_END_OF_STREAM; |
266 | } |
267 | //memcpy(&mFrame_size,ptr_head2+IEC61937_DTS_HEAD_PTR-6,2); |
268 | //ALOGI("mFrame_size:%d",mFrame_size); |
269 | //memcpy(&mFrame_size,ptr_head2+IEC61937_DTS_HEAD_PTR-6,2); |
270 | //ado-no lib only pack dts core data |
271 | mFrame_size = (ptr_head2[2] | ptr_head2[3] << 8)/8; |
272 | //ALOGI("mFrame_size:%d",mFrame_size); |
273 | MediaBuffer *buffer; |
274 | int8_t tmp; |
275 | unsigned char *ptr; |
276 | status_t err = mGroup->acquire_buffer(&buffer); |
277 | if (err != OK) { |
278 | return err; |
279 | } |
280 | if (MediaSourceRead_buffer( |
281 | (unsigned char*) (buffer->data()), |
282 | mFrame_size) != mFrame_size ) { |
283 | ALOGI("[%s %d]stream read failed:bytes_req/%d\n", __FUNCTION__, |
284 | __LINE__, mFrame_size); |
285 | buffer->release(); |
286 | buffer = NULL; |
287 | return ERROR_END_OF_STREAM; |
288 | } |
289 | |
290 | ptr = (unsigned char *)buffer->data(); |
291 | for (i = 0;i < mFrame_size;i = i+2 ) { |
292 | tmp = ptr[i]; |
293 | ptr[i] = ptr[i+1]; |
294 | ptr[i+1] = tmp; |
295 | } |
296 | |
297 | buffer->set_range(0, mFrame_size); |
298 | buffer->meta_data()->setInt64(kKeyTime, 0); |
299 | buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); |
300 | |
301 | *out = buffer; |
302 | return OK; |
303 | } |
304 | |
305 | |
306 | //-------------------------------OMX codec------------------------------------------------ |
307 | |
308 | const char *MEDIA_MIMETYPE_AUDIO_DTS = "audio/dtshd"; |
309 | Aml_OMX_DtsCodec::Aml_OMX_DtsCodec(void) { |
310 | ALOGI("[Aml_OMX_DtsCodec::%s: %d],atype %d\n", __FUNCTION__, __LINE__,spdif_audio_type); |
311 | m_codec = NULL; |
312 | status_t m_OMXClientConnectStatus = m_OMXClient.connect(); |
313 | lock_init(); |
314 | locked(); |
315 | buf_decode_offset = 0; |
316 | buf_decode_offset_pre = 0; |
317 | if (m_OMXClientConnectStatus != OK) { |
318 | ALOGE("Err:omx client connect error\n"); |
319 | } else { |
320 | const char *mine_type = NULL; |
321 | if (spdif_audio_type == DTSHD || spdif_audio_type == DTS) |
322 | mine_type = MEDIA_MIMETYPE_AUDIO_DTS; |
323 | |
324 | m_OMXMediaSource = new Dtshd_Media_Source(); |
325 | sp < MetaData > metadata = m_OMXMediaSource->getFormat(); |
326 | metadata->setCString(kKeyMIMEType, mine_type); |
327 | m_codec = SimpleDecodingSource::Create(m_OMXMediaSource, 0, 0); |
328 | |
329 | if (m_codec != NULL) { |
330 | ALOGI("OMXCodec::Create success %s %d \n", __FUNCTION__, __LINE__); |
331 | } else { |
332 | ALOGE("Err: OMXCodec::Create failed %s %d \n", __FUNCTION__, |
333 | __LINE__); |
334 | } |
335 | } |
336 | unlocked(); |
337 | } |
338 | |
339 | Aml_OMX_DtsCodec::~Aml_OMX_DtsCodec() { |
340 | } |
341 | |
342 | status_t Aml_OMX_DtsCodec::read(unsigned char *buf, unsigned *size, int *exit) { |
343 | MediaBuffer *srcBuffer; |
344 | status_t status; |
345 | m_OMXMediaSource->Set_Stop_ReadBuf_Flag(*exit); |
346 | |
347 | if (m_codec == NULL) { |
348 | return -1; |
349 | } |
350 | |
351 | if (*exit) { |
352 | ALOGI("NOTE:exit flag enabled! [%s %d] \n", __FUNCTION__, __LINE__); |
353 | *size = 0; |
354 | return OK; |
355 | } |
356 | |
357 | status = m_codec->read(&srcBuffer, NULL); |
358 | |
359 | if (srcBuffer == NULL) { |
360 | *size = 0; |
361 | return OK; |
362 | } |
363 | |
364 | *size = srcBuffer->range_length(); |
365 | |
366 | if (status == OK && (*size != 0)) { |
367 | memcpy((unsigned char *) buf, |
368 | (unsigned char *) srcBuffer->data() + srcBuffer->range_offset(), |
369 | *size); |
370 | srcBuffer->set_range(srcBuffer->range_offset() + (*size), |
371 | srcBuffer->range_length() - (*size)); |
372 | srcBuffer->meta_data()->findInt64(kKeyTime, &buf_decode_offset); |
373 | } |
374 | |
375 | if (srcBuffer->range_length() == 0) { |
376 | srcBuffer->release(); |
377 | srcBuffer = NULL; |
378 | } |
379 | |
380 | return OK; |
381 | } |
382 | |
383 | status_t Aml_OMX_DtsCodec::start() { |
384 | ALOGI("[Aml_OMX_DtsCodec::%s %d] enter!\n", __FUNCTION__, __LINE__); |
385 | status_t status; |
386 | if (m_codec != NULL) |
387 | status = m_codec->start(); |
388 | else |
389 | ALOGE("m_codec==NULL, m_codec->pause() start! [%s %d] \n", |
390 | __FUNCTION__, __LINE__); |
391 | |
392 | if (status != OK) { |
393 | ALOGE("Err:OMX client can't start OMX decoder! status=%d (0x%08x)\n", |
394 | (int) status, (int) status); |
395 | m_codec.clear(); |
396 | } |
397 | return status; |
398 | } |
399 | |
400 | void Aml_OMX_DtsCodec::stop() { |
401 | ALOGI("[Aml_OMX_DtsCodec::%s %d] enter!\n", __FUNCTION__, __LINE__); |
402 | if (m_codec != NULL) { |
403 | if (m_OMXMediaSource->Get_Stop_ReadBuf_Flag()) |
404 | m_OMXMediaSource->Set_Stop_ReadBuf_Flag(1); |
405 | m_codec->pause(); |
406 | m_codec->stop(); |
407 | wp < MediaSource > tmp = m_codec; |
408 | m_codec.clear(); |
409 | while (tmp.promote() != NULL) { |
410 | ALOGI("[Aml_OMX_DtsCodec::%s %d]wait m_codec free OK!\n", __FUNCTION__, |
411 | __LINE__); |
412 | usleep(1000); |
413 | } |
414 | m_OMXClient.disconnect(); |
415 | m_OMXMediaSource.clear(); |
416 | } else |
417 | ALOGE("m_codec==NULL, m_codec->stop() failed! [%s %d] \n", __FUNCTION__, |
418 | __LINE__); |
419 | } |
420 | |
421 | void Aml_OMX_DtsCodec::pause() { |
422 | ALOGI("[Aml_OMX_DtsCodec::%s %d] \n", __FUNCTION__, __LINE__); |
423 | if (m_codec != NULL) |
424 | m_codec->pause(); |
425 | else |
426 | ALOGE("m_codec==NULL, m_codec->pause() failed! [%s %d] \n", |
427 | __FUNCTION__, __LINE__); |
428 | } |
429 | |
430 | int Aml_OMX_DtsCodec::GetDecBytes() { |
431 | int used_len = 0; |
432 | used_len = buf_decode_offset - buf_decode_offset_pre; |
433 | buf_decode_offset_pre = buf_decode_offset; |
434 | return used_len; |
435 | } |
436 | |
437 | void Aml_OMX_DtsCodec::lock_init() { |
438 | pthread_mutexattr_t attr; |
439 | pthread_mutexattr_init(&attr); |
440 | pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); |
441 | pthread_mutex_init(&lock, &attr); |
442 | pthread_mutexattr_destroy(&attr); |
443 | } |
444 | void Aml_OMX_DtsCodec::locked() { |
445 | pthread_mutex_lock (&lock); |
446 | } |
447 | void Aml_OMX_DtsCodec::unlocked() { |
448 | pthread_mutex_unlock (&lock); |
449 | } |
450 | |
451 | //--------------------------------OMX_Codec_local API------------------------------------------------- |
452 | |
453 | Aml_OMX_DtsCodec *arm_dts_omx_codec = NULL; |
454 | |
455 | void omx_dts_codec_pause() { |
456 | if (arm_dts_omx_codec != NULL) { |
457 | arm_dts_omx_codec->locked(); |
458 | arm_dts_omx_codec->pause(); |
459 | arm_dts_omx_codec->unlocked(); |
460 | } else |
461 | ALOGE("arm_dts_omx_codec==NULL arm_dts_omx_codec->pause failed! %s %d \n", |
462 | __FUNCTION__, __LINE__); |
463 | } |
464 | |
465 | void omx_dts_codec_read(unsigned char *buf, unsigned *size, int *exit) { |
466 | if (arm_dts_omx_codec != NULL) { |
467 | arm_dts_omx_codec->locked(); |
468 | arm_dts_omx_codec->read(buf, size, exit); |
469 | arm_dts_omx_codec->unlocked(); |
470 | } else |
471 | ALOGE("arm_dts_omx_codec==NULL arm_dts_omx_codec->read failed! %s %d \n", |
472 | __FUNCTION__, __LINE__); |
473 | } |
474 | |
475 | int omx_dts_codec_get_declen() { |
476 | int declen = 0; |
477 | if (arm_dts_omx_codec != NULL) { |
478 | arm_dts_omx_codec->locked(); |
479 | declen = arm_dts_omx_codec->GetDecBytes(); |
480 | arm_dts_omx_codec->unlocked(); |
481 | } else { |
482 | ALOGI( |
483 | "NOTE:arm_dts_omx_codec==NULL arm_dts_omx_codec_get_declen() return 0! %s %d \n", |
484 | __FUNCTION__, __LINE__); |
485 | } |
486 | return declen; |
487 | } |
488 | |
489 | int omx_dts_codec_get_FS() { |
490 | if (arm_dts_omx_codec != NULL) { |
491 | return arm_dts_omx_codec->m_OMXMediaSource->GetSampleRate(); |
492 | |
493 | } else { |
494 | ALOGI( |
495 | "NOTE:arm_dts_omx_codec==NULL arm_dts_omx_codec_get_FS() return 0! %s %d \n", |
496 | __FUNCTION__, __LINE__); |
497 | return 0; |
498 | } |
499 | } |
500 | |
501 | int omx_dts_codec_get_Nch() { |
502 | if (arm_dts_omx_codec != NULL) { |
503 | return arm_dts_omx_codec->m_OMXMediaSource->GetChNum(); |
504 | } else { |
505 | ALOGI( |
506 | "NOTE:arm_dts_omx_codec==NULL arm_dts_omx_codec_get_Nch() return 0! %s %d \n", |
507 | __FUNCTION__, __LINE__); |
508 | return 0; |
509 | } |
510 | } |
511 | |
512 | //--------------------------------------Decoder ThreadLoop-------------------------------------------- |
513 | |
514 | void *dts_decode_threadloop(__unused void *args) { |
515 | unsigned int outlen = 0; |
516 | unsigned int outlen_raw = 0; |
517 | unsigned int outlen_pcm = 0; |
518 | int write_sucessed = 1; |
519 | int ret = 0; |
520 | char *tmp = NULL; |
521 | tmp = (char*)malloc(6144*4+6144+8); |
522 | if (tmp == NULL) { |
523 | ALOGE("malloc buffer failed\n"); |
524 | return NULL; |
525 | } |
526 | ALOGI("[%s %d] enter!\n", __FUNCTION__, __LINE__); |
527 | while (decode_ThreadStopFlag == 0) { |
528 | if (write_sucessed == 1) { |
529 | outlen = 0; |
530 | outlen_raw = 0; |
531 | outlen_pcm = 0; |
532 | omx_dts_codec_read((unsigned char*)tmp, &outlen, &(decode_ThreadStopFlag)); |
533 | } |
534 | if (decode_ThreadStopFlag == 1) { |
535 | ALOGD("%s, exit threadloop! \n", __FUNCTION__); |
536 | break; |
537 | } |
538 | if (outlen > 8) { |
539 | memcpy(&outlen_pcm,tmp,4); |
540 | memcpy(&outlen_raw,tmp+4+outlen_pcm,4); |
541 | if (outlen_pcm > 0) { |
542 | ret = buffer_write(&DDP_out_buffer, tmp+4, outlen_pcm); |
543 | if (ret < 0) { |
544 | write_sucessed = 0; |
545 | usleep(10 * 1000); //10ms |
546 | } else { |
547 | write_sucessed = 1; |
548 | } |
549 | } |
550 | if (outlen_raw > 0) { |
551 | //ALOGI("raw data size %d\n",outlen_raw); |
552 | ret = buffer_write(&DD_out_buffer, tmp+4+outlen_pcm+4, outlen_raw); |
553 | if (ret < 0) { |
554 | write_sucessed = 0; |
555 | ALOGI("raw data write failed\n"); |
556 | usleep(10 * 1000); //10ms |
557 | } else { |
558 | #if 0 |
559 | FILE *fp1=fopen("/data/audio_raw.wav","a+"); |
560 | if (fp1) { |
561 | int flen=fwrite((char *)tmp+4+outlen_pcm+4,1,outlen_raw,fp1); |
562 | ALOGI("flen = %d---bytes_raw=%d ", flen, outlen_raw); |
563 | fclose(fp1); |
564 | }else{ |
565 | ALOGI("could not open file:audio_out.pcm"); |
566 | } |
567 | #endif |
568 | write_sucessed = 1; |
569 | } |
570 | } |
571 | } |
572 | } |
573 | decode_ThreadExitFlag = 0; |
574 | if (tmp) { |
575 | free(tmp); |
576 | } |
577 | ALOGD("%s, exiting...\n", __FUNCTION__); |
578 | return NULL; |
579 | } |
580 | |
581 | static int start_decode_thread_omx(void) { |
582 | pthread_attr_t attr; |
583 | struct sched_param param; |
584 | int ret = 0; |
585 | |
586 | ALOGI("[%s %d] enter!\n", __FUNCTION__, __LINE__); |
587 | pthread_mutex_lock(&decode_dev_op_mutex); |
588 | pthread_attr_init(&attr); |
589 | pthread_attr_setschedpolicy(&attr, SCHED_RR); |
590 | param.sched_priority = sched_get_priority_max(SCHED_RR); |
591 | pthread_attr_setschedparam(&attr, ¶m); |
592 | decode_ThreadStopFlag = 0; |
593 | decode_ThreadExitFlag = 1; |
594 | ret = pthread_create(&decode_ThreadID, &attr, &dts_decode_threadloop, NULL); |
595 | pthread_attr_destroy(&attr); |
596 | if (ret != 0) { |
597 | ALOGE("%s, Create thread fail!\n", __FUNCTION__); |
598 | pthread_mutex_unlock(&decode_dev_op_mutex); |
599 | return -1; |
600 | } |
601 | pthread_mutex_unlock(&decode_dev_op_mutex); |
602 | ALOGD("[%s] exiting...\n", __FUNCTION__); |
603 | return 0; |
604 | } |
605 | |
606 | static int stop_decode_thread_omx(void) { |
607 | int i = 0, tmp_timeout_count = 1000; |
608 | |
609 | ALOGI("[%s %d] enter!\n", __FUNCTION__, __LINE__); |
610 | pthread_mutex_lock(&decode_dev_op_mutex); |
611 | |
612 | decode_ThreadStopFlag = 1; |
613 | while (1) { |
614 | if (decode_ThreadExitFlag == 0) |
615 | break; |
616 | if (i >= tmp_timeout_count) |
617 | break; |
618 | i++; |
619 | usleep(1000); |
620 | } |
621 | if (i >= tmp_timeout_count) { |
622 | ALOGE( |
623 | "%s, Timeout: we have try %d ms, but the aml audio thread's exec flag is still(%d)!!!\n", |
624 | __FUNCTION__, tmp_timeout_count, decode_ThreadExitFlag); |
625 | } else { |
626 | ALOGD("%s, kill decode thread success after try %d ms.\n", __FUNCTION__, |
627 | i); |
628 | } |
629 | |
630 | pthread_join(decode_ThreadID, NULL); |
631 | decode_ThreadID = 0; |
632 | ALOGD("%s, aml audio close success.\n", __FUNCTION__); |
633 | pthread_mutex_unlock(&decode_dev_op_mutex); |
634 | return 0; |
635 | } |
636 | |
637 | //-------------------------------------external OMX_codec_api----------------------------------------- |
638 | extern "C" { |
639 | int omx_codec_dts_init(void) { |
640 | int ret = 0; |
641 | ALOGI("omx_codec_init!\n"); |
642 | #ifndef USE_SYS_WRITE_SERVICE |
643 | ret=property_set("media.libplayer.dtsopt0", "1"); |
644 | ALOGI("property_set<media.libplayer.dtsopt0> ret/%d\n",ret); |
645 | #else |
646 | amSystemWriteSetPropertyDts("media.libplayer.dtsopt0", "1"); |
647 | #endif |
648 | arm_dts_omx_codec = new android::Aml_OMX_DtsCodec(); |
649 | if (arm_dts_omx_codec == NULL) { |
650 | ALOGE("Err:arm_dts_omx_codec_init failed!\n"); |
651 | return -1; |
652 | } |
653 | |
654 | arm_dts_omx_codec->locked(); |
655 | ret = arm_dts_omx_codec->start(); |
656 | arm_dts_omx_codec->unlocked(); |
657 | if (ret < 0) { |
658 | goto Exit; |
659 | } |
660 | |
661 | ret = start_decode_thread_omx(); |
662 | if (ret == 0) |
663 | return 0; |
664 | Exit: arm_dts_omx_codec->stop(); |
665 | delete arm_dts_omx_codec; |
666 | arm_dts_omx_codec = NULL; |
667 | return -1; |
668 | } |
669 | |
670 | void omx_codec_dts_close(void) { |
671 | int ret = 0; |
672 | #ifndef USE_SYS_WRITE_SERVICE |
673 | ret=property_set("media.libplayer.dtsopt0", "0"); |
674 | ALOGI("property_set<media.libplayer.dtsopt0> ret/%d\n",ret); |
675 | #else |
676 | amSystemWriteSetPropertyDts("media.libplayer.dtsopt0", "0"); |
677 | #endif |
678 | if (arm_dts_omx_codec == NULL) { |
679 | ALOGI( |
680 | "NOTE:arm_dts_omx_codec==NULL arm_dts_omx_codec_close() do nothing! %s %d \n", |
681 | __FUNCTION__, __LINE__); |
682 | return; |
683 | } |
684 | ALOGI("omx_codec_close!\n"); |
685 | stop_decode_thread_omx(); |
686 | arm_dts_omx_codec->locked(); |
687 | arm_dts_omx_codec->stop(); |
688 | arm_dts_omx_codec->unlocked(); |
689 | delete arm_dts_omx_codec; |
690 | arm_dts_omx_codec = NULL; |
691 | return; |
692 | } |
693 | |
694 | } |
695 | } |
696 | |
697 |