blob: 952ba6dedce8d58e82d37bfae49cd9926d3c71c2
1 | /* |
2 | interface to call OMX codec |
3 | */ |
4 | |
5 | #include <media/stagefright/MediaBuffer.h> |
6 | #include <media/stagefright/SimpleDecodingSource.h> |
7 | #include "../adec_omx_brige.h" |
8 | #include "adec_omx.h" |
9 | #include "audio_mediasource.h" |
10 | #include "DDP_mediasource.h" |
11 | #include "ALAC_mediasource.h" |
12 | #include "MP3_mediasource.h" |
13 | #include "ASF_mediasource.h" |
14 | #include "DTSHD_mediasource.h" |
15 | #include "Vorbis_mediasource.h" |
16 | #include "THD_mediasource.h" |
17 | #include <android/log.h> |
18 | #include <stdio.h> |
19 | #include <stdarg.h> |
20 | #include <string.h> |
21 | #include <cutils/properties.h> |
22 | #include <Amsysfsutils.h> |
23 | #include <media/IOMX.h> |
24 | #define LOG_TAG "Adec_OMX" |
25 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) |
26 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) |
27 | |
28 | namespace android { |
29 | |
30 | //##################################################### |
31 | |
32 | AmlOMXCodec::AmlOMXCodec(int codec_type,void *read_buffer,int *exit,aml_audio_dec_t *audec) |
33 | { |
34 | m_codec=NULL; |
35 | status_t m_OMXClientConnectStatus=m_OMXClient.connect(); |
36 | lock_init(); |
37 | locked(); |
38 | buf_decode_offset=0; |
39 | buf_decode_offset_pre=0; |
40 | if(m_OMXClientConnectStatus != OK){ |
41 | LOGE("Err:omx client connect error\n"); |
42 | }else{ |
43 | const char *mine_type=NULL; |
44 | audec->data_width=AV_SAMPLE_FMT_S16; |
45 | omx_codec_type=0; |
46 | if(audec->channels>0){ |
47 | audec->channels=(audec->channels>2? 2:audec->channels); |
48 | audec->adec_ops->channels=audec->channels; |
49 | }else |
50 | audec->adec_ops->channels=audec->channels=2; |
51 | |
52 | if(audec->samplerate>0) |
53 | audec->adec_ops->samplerate=audec->samplerate; |
54 | else |
55 | audec->adec_ops->samplerate=audec->samplerate=48000; |
56 | |
57 | LOGI("Data_width:%d Samplerate:%d Channel:%d \n",audec->data_width,audec->samplerate,audec->channels); |
58 | |
59 | if(codec_type==OMX_ENABLE_CODEC_AC3) |
60 | { |
61 | mine_type=MEDIA_MIMETYPE_AUDIO_AC3; |
62 | m_OMXMediaSource = new DDP_MediaSource(read_buffer); |
63 | } |
64 | else if(codec_type==OMX_ENABLE_CODEC_EAC3) |
65 | { |
66 | mine_type=MEDIA_MIMETYPE_AUDIO_EC3; |
67 | m_OMXMediaSource = new DDP_MediaSource(read_buffer); |
68 | } |
69 | else if(codec_type==OMX_ENABLE_CODEC_ALAC) |
70 | { |
71 | mine_type=MEDIA_MIMETYPE_AUDIO_ALAC; |
72 | m_OMXMediaSource = new ALAC_MediaSource(read_buffer,audec); |
73 | } |
74 | else if(codec_type==OMX_ENABLE_CODEC_MPEG_LAYER_II) |
75 | { |
76 | mine_type=MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II; |
77 | //mine_type=MEDIA_MIMETYPE_AUDIO_MPEG; |
78 | m_OMXMediaSource = new MP3_MediaSource(read_buffer,audec,exit); |
79 | }else if(codec_type==OMX_ENABLE_CODEC_WMA){ |
80 | mine_type=MEDIA_MIMETYPE_AUDIO_WMA; |
81 | m_OMXMediaSource = new Asf_MediaSource(read_buffer,audec); |
82 | }else if(codec_type==OMX_ENABLE_CODEC_WMAPRO){ |
83 | mine_type=MEDIA_MIMETYPE_AUDIO_WMAPRO; |
84 | m_OMXMediaSource = new Asf_MediaSource(read_buffer,audec); |
85 | }else if(codec_type==OMX_ENABLE_CODEC_DTSHD){ |
86 | mine_type=MEDIA_MIMETYPE_AUDIO_DTSHD; |
87 | m_OMXMediaSource = new Dtshd_MediaSource(read_buffer); |
88 | }else if(codec_type==OMX_ENABLE_CODEC_VORBIS){ |
89 | mine_type=MEDIA_MIMETYPE_AUDIO_VORBIS; |
90 | m_OMXMediaSource=new Vorbis_MediaSource(read_buffer,audec); |
91 | }else if(codec_type == OMX_ENABLE_CODEC_TRUEHD){ |
92 | mine_type = MEDIA_MIMETYPE_AUDIO_TRUEHD; |
93 | m_OMXMediaSource = new THD_MediaSource(read_buffer); |
94 | }else if(codec_type==OMX_ENABLE_CODEC_WMAVOI){ |
95 | mine_type=MEDIA_MIMETYPE_AUDIO_FFMPEG; |
96 | m_OMXMediaSource = new Asf_MediaSource(read_buffer,audec); |
97 | } |
98 | omx_codec_type=codec_type; |
99 | LOGI("mine_type=%s %s %d \n",mine_type,__FUNCTION__,__LINE__); |
100 | |
101 | m_OMXMediaSource->Set_pStop_ReadBuf_Flag(exit); |
102 | |
103 | sp<MetaData> metadata = m_OMXMediaSource->getFormat(); |
104 | metadata->setCString(kKeyMIMEType,mine_type); |
105 | |
106 | m_codec = SimpleDecodingSource::Create( |
107 | m_OMXMediaSource, |
108 | 0, |
109 | 0); |
110 | |
111 | if (m_codec != NULL) |
112 | { |
113 | LOGI("OMXCodec::Create success %s %d \n",__FUNCTION__,__LINE__); |
114 | }else{ |
115 | LOGE("Err: OMXCodec::Create failed %s %d \n",__FUNCTION__,__LINE__); |
116 | } |
117 | } |
118 | unlocked(); |
119 | } |
120 | |
121 | |
122 | AmlOMXCodec::~AmlOMXCodec() |
123 | { |
124 | |
125 | m_OMXMediaSource=NULL; |
126 | m_codec=NULL; |
127 | } |
128 | |
129 | |
130 | status_t AmlOMXCodec::read(unsigned char *buf,unsigned *size,int *exit) |
131 | { |
132 | if (m_codec == NULL) { |
133 | LOGE("m_codec==NULL %s %d failed!\n",__FUNCTION__,__LINE__); |
134 | return !OK; |
135 | } |
136 | MediaBuffer *srcBuffer; |
137 | status_t status; |
138 | m_OMXMediaSource->Set_pStop_ReadBuf_Flag(exit); |
139 | |
140 | if(*exit) |
141 | { |
142 | LOGI("NOTE:exit flag enabled! [%s %d] \n",__FUNCTION__,__LINE__); |
143 | *size=0; |
144 | return OK; |
145 | } |
146 | |
147 | status= m_codec->read(&srcBuffer,NULL); |
148 | |
149 | if(srcBuffer==NULL) |
150 | { |
151 | if (status == INFO_FORMAT_CHANGED) { |
152 | ALOGI("format changed \n"); |
153 | } |
154 | *size=0; |
155 | return OK; |
156 | } |
157 | if(*size>srcBuffer->range_length()) //surpose buf is large enough |
158 | *size=srcBuffer->range_length(); |
159 | if(status == OK && (*size!=0) ){ |
160 | memcpy(buf, (void*)((unsigned long)srcBuffer->data() + srcBuffer->range_offset()), *size); |
161 | srcBuffer->set_range(srcBuffer->range_offset() + (*size),srcBuffer->range_length() - (*size)); |
162 | srcBuffer->meta_data()->findInt64(kKeyTime, &buf_decode_offset); |
163 | } |
164 | |
165 | if (srcBuffer->range_length() == 0) { |
166 | srcBuffer->release(); |
167 | srcBuffer = NULL; |
168 | } |
169 | return OK; |
170 | } |
171 | |
172 | status_t AmlOMXCodec::start(aml_audio_dec_t *audec) |
173 | { |
174 | LOGI("[%s %d] \n",__FUNCTION__,__LINE__); |
175 | if (m_codec == NULL) { |
176 | LOGE("m_codec==NULL %s %d failed!\n",__FUNCTION__,__LINE__); |
177 | return !OK; |
178 | } |
179 | status_t status = m_codec->start(); |
180 | if(omx_codec_type==OMX_ENABLE_CODEC_AC3 ||omx_codec_type==OMX_ENABLE_CODEC_EAC3 \ |
181 | || omx_codec_type==OMX_ENABLE_CODEC_DTSHD || omx_codec_type== OMX_ENABLE_CODEC_TRUEHD){ |
182 | android::sp<android::MetaData> output_format=m_codec->getFormat(); |
183 | int enable_flag = 0; |
184 | output_format->findInt32(android::kKeyAudioFlag, &enable_flag); |
185 | LOGI("dts/dolby audio enable flag %d \n",enable_flag); |
186 | audec->audio_decoder_enabled = enable_flag; |
187 | } |
188 | if (status != OK) |
189 | { |
190 | LOGE("Err:OMX client can't start OMX decoder?! status=%d (0x%08x)\n", (int)status, (int)status); |
191 | m_codec = NULL; |
192 | } |
193 | return status; |
194 | } |
195 | |
196 | void AmlOMXCodec::stop() |
197 | { |
198 | LOGI("[%s %d] enter \n",__FUNCTION__,__LINE__); |
199 | if(m_codec != NULL){ |
200 | if(m_OMXMediaSource->Get_pStop_ReadBuf_Flag()) |
201 | *m_OMXMediaSource->Get_pStop_ReadBuf_Flag()=1; |
202 | m_codec->pause(); |
203 | m_codec->stop(); |
204 | wp<MediaSource> tmp = m_codec; |
205 | m_codec.clear(); |
206 | while (tmp.promote() != NULL) { |
207 | LOGI("[%s %d]wait m_codec free OK!\n",__FUNCTION__,__LINE__); |
208 | usleep(1000); |
209 | } |
210 | |
211 | //m_OMXMediaSource->stop();//stop in omxcodec |
212 | m_OMXClient.disconnect(); |
213 | m_OMXMediaSource=NULL; |
214 | m_codec=NULL; |
215 | }else |
216 | LOGE("m_codec==NULL m_codec->stop() failed! %s %d \n",__FUNCTION__,__LINE__); |
217 | } |
218 | |
219 | void AmlOMXCodec::pause() |
220 | { |
221 | LOGI("[%s %d] \n",__FUNCTION__,__LINE__); |
222 | if(m_codec != NULL) |
223 | m_codec->pause(); |
224 | else |
225 | LOGE("m_codec==NULL m_codec->pause() failed! %s %d \n",__FUNCTION__,__LINE__); |
226 | } |
227 | |
228 | int AmlOMXCodec::GetDecBytes() |
229 | { |
230 | int used_len=0; |
231 | |
232 | if (omx_codec_type == OMX_ENABLE_CODEC_AC3 || omx_codec_type == OMX_ENABLE_CODEC_EAC3) |
233 | { |
234 | used_len += m_OMXMediaSource->GetReadedBytes(); |
235 | } |
236 | |
237 | if(omx_codec_type==OMX_ENABLE_CODEC_AC3 ||omx_codec_type==OMX_ENABLE_CODEC_EAC3|| omx_codec_type==OMX_ENABLE_CODEC_DTSHD) |
238 | { |
239 | used_len += (buf_decode_offset - buf_decode_offset_pre); |
240 | buf_decode_offset_pre=buf_decode_offset; |
241 | return used_len; |
242 | }else{ |
243 | return m_OMXMediaSource->GetReadedBytes(); |
244 | } |
245 | } |
246 | |
247 | void AmlOMXCodec::lock_init() |
248 | { |
249 | pthread_mutexattr_t attr; |
250 | pthread_mutexattr_init(&attr); |
251 | pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); |
252 | pthread_mutex_init(&lock, &attr); |
253 | pthread_mutexattr_destroy(&attr); |
254 | } |
255 | void AmlOMXCodec::locked() |
256 | { |
257 | pthread_mutex_lock(&lock); |
258 | } |
259 | void AmlOMXCodec::unlocked() |
260 | { |
261 | pthread_mutex_unlock(&lock); |
262 | } |
263 | |
264 | }; // namespace android |
265 | |
266 | //##################################################### |
267 | extern "C" |
268 | { |
269 | |
270 | android::AmlOMXCodec *arm_omx_codec=NULL; |
271 | |
272 | void arm_omx_codec_init(aml_audio_dec_t *audec,int codec_type,void *readbuffer,int *exit) |
273 | { |
274 | char value[128]={0}; |
275 | int ret=0; |
276 | android::AmlOMXCodec *arm_omx_codec=NULL; |
277 | amsysfs_write_prop("media.libplayer.dtsopt0", "1"); |
278 | LOGI("property_set<media.libplayer.dtsopt0> ret/%d\n",ret); |
279 | arm_omx_codec=new android::AmlOMXCodec(codec_type,readbuffer,exit,audec); |
280 | if(arm_omx_codec==NULL){ |
281 | property_set("media.libplayer.dtsopt0", "0"); |
282 | LOGE("Err:arm_omx_codec_init failed\n"); |
283 | } |
284 | if(property_get("media.libplayer.dtsopt0",value,NULL) > 0) |
285 | { |
286 | LOGI("[%s %d] media.libplayer.dtsopt0/%s \n",__FUNCTION__,__LINE__,value); |
287 | }else{ |
288 | LOGE("[%s %d] property_set<media.libplayer.dtsopt0> failed\n",__FUNCTION__,__LINE__); |
289 | } |
290 | LOGI("[%s %d] arm_omx_codec=%p \n",__FUNCTION__,__LINE__,arm_omx_codec); |
291 | audec->arm_omx_codec=arm_omx_codec; |
292 | } |
293 | |
294 | void arm_omx_codec_start(aml_audio_dec_t *audec) |
295 | { |
296 | android::AmlOMXCodec *arm_omx_codec=(android::AmlOMXCodec *)(audec->arm_omx_codec); |
297 | if(arm_omx_codec!=NULL){ |
298 | arm_omx_codec->locked(); |
299 | arm_omx_codec->start(audec); |
300 | arm_omx_codec->unlocked(); |
301 | }else |
302 | LOGE("arm_omx_codec==NULL arm_omx_codec->start failed! %s %d \n",__FUNCTION__,__LINE__); |
303 | } |
304 | |
305 | void arm_omx_codec_pause(aml_audio_dec_t *audec) |
306 | { |
307 | android::AmlOMXCodec *arm_omx_codec=(android::AmlOMXCodec *)(audec->arm_omx_codec); |
308 | if(arm_omx_codec!=NULL){ |
309 | arm_omx_codec->locked(); |
310 | arm_omx_codec->pause(); |
311 | arm_omx_codec->unlocked(); |
312 | }else |
313 | LOGE("arm_omx_codec==NULL arm_omx_codec->pause failed! %s %d \n",__FUNCTION__,__LINE__); |
314 | } |
315 | |
316 | void arm_omx_codec_read(aml_audio_dec_t *audec,unsigned char *buf,unsigned *size,int *exit) |
317 | { |
318 | android::AmlOMXCodec *arm_omx_codec=(android::AmlOMXCodec *)(audec->arm_omx_codec); |
319 | if(arm_omx_codec!=NULL){ |
320 | arm_omx_codec->locked(); |
321 | arm_omx_codec->read(buf,size,exit); |
322 | arm_omx_codec->unlocked(); |
323 | }else |
324 | LOGE("arm_omx_codec==NULL arm_omx_codec->read failed! %s %d \n",__FUNCTION__,__LINE__); |
325 | } |
326 | |
327 | void arm_omx_codec_close(aml_audio_dec_t *audec) |
328 | { |
329 | int ret=0; |
330 | char value[128]={0}; |
331 | android::AmlOMXCodec *arm_omx_codec=(android::AmlOMXCodec *)(audec->arm_omx_codec); |
332 | amsysfs_write_prop("media.libplayer.dtsopt0", "0"); |
333 | LOGI("property_set<media.libplayer.dtsopt0> ret/%d\n",ret); |
334 | if(arm_omx_codec!=NULL){ |
335 | arm_omx_codec->locked(); |
336 | arm_omx_codec->stop(); |
337 | arm_omx_codec->unlocked(); |
338 | delete arm_omx_codec; |
339 | arm_omx_codec=NULL; |
340 | }else{ |
341 | LOGI("NOTE:arm_omx_codec==NULL arm_omx_codec_close() do nothing! %s %d \n",__FUNCTION__,__LINE__); |
342 | } |
343 | if(property_get("media.libplayer.dtsopt0",value,NULL) > 0) |
344 | { |
345 | LOGI("[%s %d] media.libplayer.dtsopt0/%s \n",__FUNCTION__,__LINE__,value); |
346 | }else{ |
347 | LOGE("[%s %d] property_set<media.libplayer.dtsopt0> failed\n",__FUNCTION__,__LINE__); |
348 | } |
349 | } |
350 | |
351 | int arm_omx_codec_get_declen(aml_audio_dec_t *audec) |
352 | { |
353 | int declen=0; |
354 | android::AmlOMXCodec *arm_omx_codec=(android::AmlOMXCodec *)(audec->arm_omx_codec); |
355 | if(arm_omx_codec!=NULL){ |
356 | arm_omx_codec->locked(); |
357 | declen=arm_omx_codec->GetDecBytes(); |
358 | arm_omx_codec->unlocked(); |
359 | }else{ |
360 | LOGI("NOTE:arm_omx_codec==NULL arm_omx_codec_get_declen() return 0! %s %d \n",__FUNCTION__,__LINE__); |
361 | } |
362 | |
363 | return declen; |
364 | |
365 | } |
366 | |
367 | #define DTSETC_DECODE_VERSION_CORE 350 |
368 | #define DTSETC_DECODE_VERSION_M6_M8 380 |
369 | int arm_omx_codec_get_FS(aml_audio_dec_t *audec) |
370 | { |
371 | android::AmlOMXCodec *arm_omx_codec=(android::AmlOMXCodec *)(audec->arm_omx_codec); |
372 | if(arm_omx_codec!=NULL){ |
373 | arm_omx_codec->locked(); |
374 | if(arm_omx_codec->omx_codec_type==OMX_ENABLE_CODEC_DTSHD){ |
375 | int sampleRate=0; |
376 | android::sp<android::MetaData> output_format=arm_omx_codec->m_codec->getFormat(); |
377 | output_format->findInt32(android::kKeySampleRate, &sampleRate); |
378 | if (audec->VersionNum == -1 || (audec->VersionNum == DTSETC_DECODE_VERSION_M6_M8 && audec->DTSHDIEC958_FS == 0) ) |
379 | { |
380 | output_format->findInt32(android::kKeyDtsDecoderVer,&audec->VersionNum); |
381 | output_format->findInt32(android::kKeyDts958Fs,&audec->DTSHDIEC958_FS); |
382 | output_format->findInt32(android::kKeyDts958PktSize,&audec->DTSHDIEC958_PktFrmSize); |
383 | output_format->findInt32(android::kKeyDts958PktType,&audec->DTSHDIEC958_PktType); |
384 | output_format->findInt32(android::kKeyDtsPcmSampsInFrmMaxFs,&audec->DTSHDPCM_SamsInFrmAtMaxSR); |
385 | } |
386 | arm_omx_codec->unlocked(); |
387 | arm_omx_codec->m_OMXMediaSource->SetSampleRate(sampleRate); |
388 | return sampleRate; |
389 | }else{ |
390 | arm_omx_codec->unlocked(); |
391 | return arm_omx_codec->m_OMXMediaSource->GetSampleRate(); |
392 | } |
393 | }else{ |
394 | LOGI("NOTE:arm_omx_codec==NULL arm_omx_codec_get_FS() return 0! %s %d \n",__FUNCTION__,__LINE__); |
395 | return 0; |
396 | } |
397 | } |
398 | |
399 | int arm_omx_codec_get_Nch(aml_audio_dec_t *audec) |
400 | { |
401 | android::AmlOMXCodec *arm_omx_codec=(android::AmlOMXCodec *)(audec->arm_omx_codec); |
402 | if(arm_omx_codec!=NULL){ |
403 | arm_omx_codec->locked(); |
404 | if(arm_omx_codec->omx_codec_type==OMX_ENABLE_CODEC_DTSHD){ |
405 | int numChannels=0; |
406 | android::sp<android::MetaData> output_format=arm_omx_codec->m_codec->getFormat(); |
407 | output_format->findInt32(android::kKeyChannelCount, &numChannels); |
408 | arm_omx_codec->unlocked(); |
409 | return numChannels; |
410 | }else{ |
411 | arm_omx_codec->unlocked(); |
412 | audec->adec_ops->NchOriginal =arm_omx_codec->m_OMXMediaSource->GetChNumOriginal(); |
413 | return arm_omx_codec->m_OMXMediaSource->GetChNum(); |
414 | } |
415 | }else{ |
416 | LOGI("NOTE:arm_omx_codec==NULL arm_omx_codec_get_Nch() return 0! %s %d \n",__FUNCTION__,__LINE__); |
417 | return 0; |
418 | } |
419 | } |
420 | |
421 | |
422 | } // namespace android |
423 |