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