summaryrefslogtreecommitdiff
path: root/amadec/adec_omx_brige.c (plain)
blob: 1ee68c2cd56870675470416b5a78b8164a317ac4
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <fcntl.h>
5#include <pthread.h>
6#include <sys/ioctl.h>
7#include <dlfcn.h>
8
9#include <audio-dec.h>
10#include <adec-pts-mgt.h>
11#include <adec_write.h>
12#include "adec_omx_brige.h"
13#include <amthreadpool.h>
14#include "Amsysfsutils.h"
15#include "amconfigutils.h"
16
17#define LOG_TAG "Adec_omx_bridge"
18#define adec_print(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
19#define SIZE_FOR_MX_BYPASS (48*1024) //about 0.25s for 48K_16bit
20
21int find_omx_lib(aml_audio_dec_t *audec)
22{
23 audio_decoder_operations_t *adec_ops = audec->adec_ops;
24 audec->StageFrightCodecEnableType = 0;
25 audec->parm_omx_codec_init = NULL;
26 audec->parm_omx_codec_read = NULL;
27 audec->parm_omx_codec_close = NULL;
28 audec->parm_omx_codec_start = NULL;
29 audec->parm_omx_codec_pause = NULL;
30 audec->parm_omx_codec_get_declen = NULL;
31 audec->parm_omx_codec_get_FS = NULL;
32 audec->parm_omx_codec_get_Nch = NULL;
33
34 if (audec->format == ACODEC_FMT_AC3) {
35#ifndef USE_ARM_AUDIO_DEC
36 audec->adec_ops->nOutBufSize = SIZE_FOR_MX_BYPASS;
37#endif
38 audec->StageFrightCodecEnableType = OMX_ENABLE_CODEC_AC3;
39 } else if (audec->format == ACODEC_FMT_EAC3) {
40#ifndef USE_ARM_AUDIO_DEC
41 audec->adec_ops->nOutBufSize = SIZE_FOR_MX_BYPASS;
42#endif
43 audec->StageFrightCodecEnableType = OMX_ENABLE_CODEC_EAC3;
44 } else if (audec->format == ACODEC_FMT_ALAC) {
45 audec->StageFrightCodecEnableType = OMX_ENABLE_CODEC_ALAC;
46 } else if (audec->format == ACODEC_FMT_MPEG || audec->format == ACODEC_FMT_MPEG1 || audec->format == ACODEC_FMT_MPEG2) {
47 if (0/*!am_getconfig_bool("media.libplayer.usemad")*/) {
48 audec->StageFrightCodecEnableType = OMX_ENABLE_CODEC_MPEG_LAYER_II; //mpeg1-3, new omx libmpg123
49 }
50 } else if (audec->format == ACODEC_FMT_WMA) {
51 audec->StageFrightCodecEnableType = OMX_ENABLE_CODEC_WMA;
52 } else if (audec->format == ACODEC_FMT_WMAPRO) {
53 audec->StageFrightCodecEnableType = OMX_ENABLE_CODEC_WMAPRO;
54 } else if (audec->format == ACODEC_FMT_DTS) {
55#ifndef USE_ARM_AUDIO_DEC
56 audec->adec_ops->nOutBufSize = SIZE_FOR_MX_BYPASS;
57#endif
58 audec->StageFrightCodecEnableType = OMX_ENABLE_CODEC_DTSHD;
59 } else if (audec->format == ACODEC_FMT_VORBIS) {
60 audec->StageFrightCodecEnableType = OMX_ENABLE_CODEC_VORBIS;
61 } else if (audec->format == ACODEC_FMT_TRUEHD) {
62 audec->StageFrightCodecEnableType = OMX_ENABLE_CODEC_TRUEHD;
63 } else if (audec->format == ACODEC_FMT_WMAVOI) {
64 audec->StageFrightCodecEnableType = OMX_ENABLE_CODEC_WMAVOI;
65 }
66
67 adec_print("%s %d audec->format=%d \n", __FUNCTION__, __LINE__, audec->format);
68
69 if (audec->StageFrightCodecEnableType) {
70 int *fd = NULL;
71 fd = dlopen("libamadec_omx_api.so", RTLD_NOW);
72 if (fd != NULL) {
73 audec->parm_omx_codec_init = dlsym(fd, "arm_omx_codec_init");
74 audec->parm_omx_codec_read = dlsym(fd, "arm_omx_codec_read");
75 audec->parm_omx_codec_close = dlsym(fd, "arm_omx_codec_close");
76 audec->parm_omx_codec_start = dlsym(fd, "arm_omx_codec_start");
77 audec->parm_omx_codec_pause = dlsym(fd, "arm_omx_codec_pause");
78 audec->parm_omx_codec_get_declen = dlsym(fd, "arm_omx_codec_get_declen");
79 audec->parm_omx_codec_get_FS = dlsym(fd, "arm_omx_codec_get_FS");
80 audec->parm_omx_codec_get_Nch = dlsym(fd, "arm_omx_codec_get_Nch");
81 } else {
82 adec_print("[NOTE]cant find libamadec_omx_api.so ,StageFrightCodecEnableType=0\n");
83 audec->StageFrightCodecEnableType = 0;
84 return 0;
85 }
86 }
87
88 if (audec->parm_omx_codec_init == NULL || audec->parm_omx_codec_read == NULL || audec->parm_omx_codec_close == NULL ||
89 audec->parm_omx_codec_start == NULL || audec->parm_omx_codec_pause == NULL || audec->parm_omx_codec_get_declen == NULL ||
90 audec->parm_omx_codec_get_FS == NULL || audec->parm_omx_codec_get_Nch == NULL
91 ) {
92 adec_print("[NOTE]load func_api in libamadec_omx_api.so faided, StageFrightCodecEnableType=0\n");
93 audec->StageFrightCodecEnableType = 0;
94 return 0;
95 }
96 adec_print("%s %d StageFrightCodecEnableType=%d \n", __FUNCTION__, __LINE__, audec->StageFrightCodecEnableType);
97 return audec->StageFrightCodecEnableType;
98}
99
100static char pcm_buf_tmp[AVCODEC_MAX_AUDIO_FRAME_SIZE];//max frame size out buf
101void omx_codec_Release();
102extern int read_buffer(unsigned char *buffer, int size);
103
104void *audio_decode_loop_omx(void *args)
105{
106 int ret;
107 aml_audio_dec_t *audec;
108 audio_out_operations_t *aout_ops;
109 audio_decoder_operations_t *adec_ops;
110
111 int nNextFrameSize = 0; //next read frame size
112 int nAudioFormat;
113 char *inbuf = NULL;//real buffer
114 int dlen = 0;//decode size one time
115 int outlen = 0;
116 char *outbuf = pcm_buf_tmp, *outbuf_raw;
117 int outlen_raw = 0;
118 int rawoutput_enable;
119 buffer_stream_t *g_bst, *g_bst_raw;
120 AudioInfo g_AudioInfo = {0};
121 adec_print("\n\naudio_decode_loop_omx start!\n");
122
123 audec = (aml_audio_dec_t *)args;
124 aout_ops = &audec->aout_ops;
125 adec_ops = audec->adec_ops;
126 memset(outbuf, 0, AVCODEC_MAX_AUDIO_FRAME_SIZE);
127 nAudioFormat = audec->format;
128 nNextFrameSize = adec_ops->nInBufSize;
129 g_bst = audec->g_bst;
130 g_bst_raw = audec->g_bst_raw;
131
132 rawoutput_enable = amsysfs_get_sysfs_int("/sys/class/audiodsp/digital_raw");
133 adec_print("rawoutput_enable/%d", rawoutput_enable);
134 if (rawoutput_enable == 1 && audec->StageFrightCodecEnableType == OMX_ENABLE_CODEC_TRUEHD) {
135 adec_print("truehd passthrough enable only when hdmi passthr\n");
136 rawoutput_enable = 0;
137 }
138 if (audec->parm_omx_codec_init && audec->parm_omx_codec_start) {
139 (*audec->parm_omx_codec_init)(audec, audec->StageFrightCodecEnableType, (void*)read_buffer, &audec->exit_decode_thread);
140 (*audec->parm_omx_codec_start)(audec);
141 } else {
142 audec->exit_decode_thread = 1;
143 adec_print("audio_decode_loop_omx start failed!");
144 }
145 audec->OmxFirstFrameDecoded = 0;
146 while (1) {
147exit_decode_loop:
148 if (audec->exit_decode_thread) { //detect quit condition
149 break;
150 }
151 outbuf = pcm_buf_tmp;
152 outlen = AVCODEC_MAX_AUDIO_FRAME_SIZE;
153 (*audec->parm_omx_codec_read)(audec, outbuf, &outlen, &audec->exit_decode_thread);
154
155 outlen_raw = 0;
156 if (audec->StageFrightCodecEnableType == OMX_ENABLE_CODEC_DTSHD ||
157 audec->StageFrightCodecEnableType == OMX_ENABLE_CODEC_TRUEHD) {
158 int outlen0 = outlen;
159 if (outlen > 8) {
160 memcpy(&outlen, outbuf, 4);
161 outbuf += 4;
162 if (outlen + 8 < outlen0) {
163 memcpy(&outlen_raw, outbuf + outlen, 4);
164 outbuf_raw = outbuf + outlen + 4;
165 }
166 } else {
167 outlen = 0;
168 }
169 } else if ((audec->StageFrightCodecEnableType == OMX_ENABLE_CODEC_AC3) ||
170 (audec->StageFrightCodecEnableType == OMX_ENABLE_CODEC_EAC3)) {
171 if (outlen > 8) {
172 memcpy(&outlen, outbuf, 4);
173 outbuf += 4;
174 memcpy(&outlen_raw, outbuf + outlen, 4);
175 outbuf_raw = outbuf + outlen + 4;
176 memset(outbuf + outlen, 0, 4);
177 } else {
178 outlen = 0;
179 }
180 }
181 if (outlen > 0) {
182 memset(&g_AudioInfo, 0, sizeof(AudioInfo));
183 g_AudioInfo.channels = (*audec->parm_omx_codec_get_Nch)(audec);
184 g_AudioInfo.samplerate = (*audec->parm_omx_codec_get_FS)(audec);
185 if (g_AudioInfo.channels != 0 && g_AudioInfo.samplerate != 0) {
186 if (!audec->OmxFirstFrameDecoded) {
187 g_bst->channels = audec->channels = g_AudioInfo.channels;
188 g_bst->samplerate = audec->samplerate = g_AudioInfo.samplerate;
189 audec->OmxFirstFrameDecoded = 1;
190 } else if (audec->OmxFirstFrameDecoded == 1) {
191 if ((g_AudioInfo.channels != g_bst->channels) || (g_AudioInfo.samplerate != g_bst->samplerate)) {
192 while (audec->format_changed_flag && !audec->exit_decode_thread) {
193 amthreadpool_thread_usleep(20000);
194 }
195 if (!audec->exit_decode_thread) {
196 adec_print("Info Changed: src:sample:%d channel:%d dest sample:%d channel:%d \n",
197 g_bst->samplerate, g_bst->channels, g_AudioInfo.samplerate, g_AudioInfo.channels);
198 g_bst->channels = g_AudioInfo.channels;
199 g_bst->samplerate = g_AudioInfo.samplerate;
200 aout_ops->pause(audec);
201 audec->format_changed_flag = 1;
202 }
203 }
204 }
205 }
206 }
207 if (outlen > 0) {
208 dlen = (*audec->parm_omx_codec_get_declen)(audec);
209 } else {
210 dlen = 0;
211 }
212 //write to the pcm buffer
213 audec->decode_offset += dlen;
214 audec->pcm_cache_size = outlen;
215
216 if (g_bst) {
217 int wlen = 0;
218 while (outlen && !audec->exit_decode_thread) {
219 if ((g_bst->buf_length - g_bst->buf_level) < outlen) {
220 amthreadpool_thread_usleep(20000);
221 continue;
222 }
223 wlen = write_pcm_buffer(outbuf, g_bst, outlen);
224 outlen -= wlen;
225 audec->pcm_cache_size -= wlen;
226 }
227
228 while (rawoutput_enable && !audec->exit_decode_thread && outlen_raw && aout_ops->audio_out_raw_enable) {
229 if (g_bst_raw->buf_length - g_bst_raw->buf_level < outlen_raw) {
230 amthreadpool_thread_usleep(20000);
231 continue;
232 }
233 wlen = write_pcm_buffer(outbuf_raw, g_bst_raw, outlen_raw);
234 outlen_raw -= wlen;
235 }
236 }
237 }
238
239 adec_print("[%s %d] has stepped out decodeloop \n", __FUNCTION__, __LINE__);
240 if (audec->StageFrightCodecEnableType && audec->parm_omx_codec_close) {
241 (*audec->parm_omx_codec_close)(audec);
242 }
243 adec_print("Exit audio_decode_loop_omx Thread finished!");
244 pthread_exit(NULL);
245 return NULL;
246}
247
248
249void start_decode_thread_omx(aml_audio_dec_t *audec)
250{
251 int ret;
252 pthread_t tid;
253 int wait_aout_ops_start_time = 0;
254
255 ret = amthreadpool_pthread_create(&tid, NULL, (void *)audio_decode_loop_omx, (void *)audec);
256 if (ret != 0) {
257 adec_print("Create <audio_decode_loop_omx> thread failed!\n");
258 return;
259 }
260 audec->sn_threadid = tid;
261 pthread_setname_np(tid, "AmadecDecodeLP");
262 adec_print("Create <audio_decode_loop_omx> thread success! tid = %d\n", tid);
263
264 while ((!audec->need_stop) && (!audec->OmxFirstFrameDecoded)) {
265 amthreadpool_thread_usleep(50);
266 wait_aout_ops_start_time++;
267 }
268 adec_print("[%s] start thread finished: <audec->OmxFirstFrameDecoded=%d> used time: %d*50(us)\n", __FUNCTION__, audec->OmxFirstFrameDecoded, wait_aout_ops_start_time);
269
270}
271
272
273void stop_decode_thread_omx(aml_audio_dec_t *audec)
274{
275 audec->exit_decode_thread = 1;
276 int ret = amthreadpool_pthread_join(audec->sn_threadid, NULL);
277 //audec->exit_decode_thread = 0;
278 audec->sn_threadid = -1;
279 audec->sn_getpackage_threadid = -1;
280}
281
282
283
284
285