blob: 2a84c4552ed893a0c2ee1390191c6d38406cf603
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 "audiodsp_update_format.h" |
10 | #include "adec_omx_brige.h" |
11 | #include "adec_reg.h" |
12 | #include <adec-pts-mgt.h> |
13 | #include <adec_write.h> |
14 | #include "Amsysfsutils.h" |
15 | #include "amconfigutils.h" |
16 | |
17 | #include <audio-dec.h> |
18 | #include <amthreadpool.h> |
19 | #include <cutils/properties.h> |
20 | |
21 | extern int read_buffer(unsigned char *buffer, int size); |
22 | void *audio_decode_loop(void *args); |
23 | void *audio_dtsdecode_loop(void *args); |
24 | void *audio_getpackage_loop(void *args); |
25 | static int set_sysfs_int(const char *path, int val); |
26 | static void stop_decode_thread(aml_audio_dec_t *audec); |
27 | |
28 | /*audio decoder list structure*/ |
29 | typedef struct { |
30 | //enum CodecID codec_id; |
31 | int codec_id; |
32 | char name[64]; |
33 | } audio_lib_t; |
34 | |
35 | audio_lib_t audio_lib_list[] = { |
36 | {ACODEC_FMT_AAC, "libfaad.so"}, |
37 | {ACODEC_FMT_AAC_LATM, "libfaad.so"}, |
38 | {ACODEC_FMT_APE, "libape.so"}, |
39 | {ACODEC_FMT_MPEG, "libmad.so"}, |
40 | {ACODEC_FMT_MPEG2, "libmad.so"}, |
41 | {ACODEC_FMT_MPEG1, "libmad.so"}, |
42 | {ACODEC_FMT_FLAC, "libflac.so"}, |
43 | {ACODEC_FMT_COOK, "libcook.so"}, |
44 | {ACODEC_FMT_RAAC, "libraac.so"}, |
45 | {ACODEC_FMT_AMR, "libamr.so"}, |
46 | |
47 | {ACODEC_FMT_PCM_S16BE, "libpcm.so"}, |
48 | {ACODEC_FMT_PCM_S16LE, "libpcm.so"}, |
49 | {ACODEC_FMT_PCM_U8, "libpcm.so"}, |
50 | {ACODEC_FMT_PCM_BLURAY, "libpcm.so"}, |
51 | {ACODEC_FMT_WIFIDISPLAY, "libpcm.so"}, |
52 | {ACODEC_FMT_ALAW, "libpcm.so"}, |
53 | {ACODEC_FMT_MULAW, "libpcm.so"}, |
54 | {ACODEC_FMT_ADPCM, "libadpcm.so"}, |
55 | {ACODEC_FMT_DRA, "libdra.so"}, |
56 | 0 |
57 | } ; |
58 | |
59 | int find_audio_lib(aml_audio_dec_t *audec) |
60 | { |
61 | int i; |
62 | int num; |
63 | audio_lib_t *f; |
64 | |
65 | adec_print("[%s %d]audec->format/%d audec->codec_id/0x%x\n", __FUNCTION__, __LINE__, audec->format, audec->codec_id); |
66 | num = ARRAY_SIZE(audio_lib_list); |
67 | audio_decoder_operations_t *adec_ops = audec->adec_ops; |
68 | //------------------------- |
69 | if (find_omx_lib(audec)) { |
70 | return 0; |
71 | } |
72 | //----------------------- |
73 | for (i = 0; i < num; i++) { |
74 | f = &audio_lib_list[i]; |
75 | if (f->codec_id == audec->format) { |
76 | void *fd = dlopen(audio_lib_list[i].name, RTLD_NOW); |
77 | if (fd != 0) { |
78 | adec_ops->init = dlsym(fd, "audio_dec_init"); |
79 | adec_ops->decode = dlsym(fd, "audio_dec_decode"); |
80 | adec_ops->release = dlsym(fd, "audio_dec_release"); |
81 | adec_ops->getinfo = dlsym(fd, "audio_dec_getinfo"); |
82 | } else { |
83 | adec_print("cant find decoder lib\n"); |
84 | return -1; |
85 | } |
86 | return 0; |
87 | } |
88 | } |
89 | return -1; |
90 | } |
91 | |
92 | |
93 | audio_decoder_operations_t AudioArmDecoder = { |
94 | "FFmpegDecoder", |
95 | AUDIO_ARM_DECODER, |
96 | 0, |
97 | }; |
98 | static int FFmpegDecoderInit(audio_decoder_operations_t *adec_ops) |
99 | { |
100 | return 0; |
101 | } |
102 | static int FFmpegDecode(audio_decoder_operations_t *adec_ops, char *outbuf, int *outlen, char *inbuf, int inlen) |
103 | { |
104 | int ret; |
105 | return ret; |
106 | } |
107 | static int FFmpegDecoderRelease(audio_decoder_operations_t *adec_ops) |
108 | { |
109 | aml_audio_dec_t *audec = (aml_audio_dec_t *)(adec_ops->priv_data); |
110 | return 0; |
111 | } |
112 | audio_decoder_operations_t AudioFFmpegDecoder = { |
113 | .name = "FFmpegDecoder", |
114 | .nAudioDecoderType = AUDIO_FFMPEG_DECODER, |
115 | .init = FFmpegDecoderInit, |
116 | .decode = FFmpegDecode, |
117 | .release = FFmpegDecoderRelease, |
118 | .getinfo = NULL, |
119 | }; |
120 | |
121 | int package_list_free(aml_audio_dec_t * audec) |
122 | { |
123 | lp_lock(&(audec->pack_list.tslock)); |
124 | while (audec->pack_list.pack_num) { |
125 | struct package * p = audec->pack_list.first; |
126 | audec->pack_list.first = audec->pack_list.first->next; |
127 | free(p->data); |
128 | free(p); |
129 | audec->pack_list.pack_num--; |
130 | } |
131 | lp_unlock(&(audec->pack_list.tslock)); |
132 | return 0; |
133 | } |
134 | static int64_t gettime_ms(void) |
135 | { |
136 | struct timeval tv; |
137 | gettimeofday(&tv, NULL); |
138 | return (int64_t)tv.tv_sec * 1000 + tv.tv_usec/1000; |
139 | } |
140 | |
141 | |
142 | int package_list_init(aml_audio_dec_t * audec) |
143 | { |
144 | audec->pack_list.first = NULL; |
145 | audec->pack_list.pack_num = 0; |
146 | audec->pack_list.current = NULL; |
147 | lp_lock_init(&(audec->pack_list.tslock), NULL); |
148 | return 0; |
149 | } |
150 | |
151 | int package_add(aml_audio_dec_t * audec, char * data, int size) |
152 | { |
153 | lp_lock(&(audec->pack_list.tslock)); |
154 | if (audec->pack_list.pack_num == 4) { //enough |
155 | lp_unlock(&(audec->pack_list.tslock)); |
156 | return -2; |
157 | } |
158 | struct package *p = malloc(sizeof(struct package)); |
159 | if (!p) { //malloc failed |
160 | lp_unlock(&(audec->pack_list.tslock)); |
161 | return -1; |
162 | } |
163 | p->data = data; |
164 | p->size = size; |
165 | if (audec->pack_list.pack_num == 0) { //first package |
166 | audec->pack_list.first = p; |
167 | audec->pack_list.current = p; |
168 | audec->pack_list.pack_num = 1; |
169 | } else { |
170 | audec->pack_list.current->next = p; |
171 | audec->pack_list.current = p; |
172 | audec->pack_list.pack_num++; |
173 | } |
174 | lp_unlock(&(audec->pack_list.tslock)); |
175 | return 0; |
176 | } |
177 | |
178 | struct package * package_get(aml_audio_dec_t * audec) { |
179 | lp_lock(&(audec->pack_list.tslock)); |
180 | if (audec->pack_list.pack_num == 0) { |
181 | lp_unlock(&(audec->pack_list.tslock)); |
182 | return NULL; |
183 | } |
184 | struct package *p = audec->pack_list.first; |
185 | if (audec->pack_list.pack_num == 1) { |
186 | audec->pack_list.first = NULL; |
187 | audec->pack_list.pack_num = 0; |
188 | audec->pack_list.current = NULL; |
189 | } else if (audec->pack_list.pack_num > 1) { |
190 | audec->pack_list.first = audec->pack_list.first->next; |
191 | audec->pack_list.pack_num--; |
192 | } |
193 | lp_unlock(&(audec->pack_list.tslock)); |
194 | return p; |
195 | } |
196 | |
197 | |
198 | int armdec_stream_read(dsp_operations_t *dsp_ops, char *buffer, int size) |
199 | { |
200 | int read_size = 0; |
201 | aml_audio_dec_t *audec = (aml_audio_dec_t *)dsp_ops->audec; |
202 | read_size = read_pcm_buffer(buffer, audec->g_bst, size); |
203 | audec->out_len_after_last_valid_pts += read_size; |
204 | return read_size; |
205 | } |
206 | |
207 | int armdec_stream_read_raw(dsp_operations_t *dsp_ops, char *buffer, int size) |
208 | { |
209 | aml_audio_dec_t *audec = (aml_audio_dec_t *)dsp_ops->audec; |
210 | return read_pcm_buffer(buffer, audec->g_bst_raw, size); |
211 | } |
212 | unsigned long armdec_get_pts(dsp_operations_t *dsp_ops) |
213 | { |
214 | unsigned long val, offset; |
215 | unsigned long pts; |
216 | int data_width, channels, samplerate; |
217 | unsigned long long frame_nums ; |
218 | unsigned long delay_pts; |
219 | char value[PROPERTY_VALUE_MAX]; |
220 | aml_audio_dec_t *audec = (aml_audio_dec_t *)dsp_ops->audec; |
221 | audio_out_operations_t * aout_ops = &audec->aout_ops; |
222 | float track_speed = 1.0f; |
223 | if (aout_ops->track_rate != 8.8f) |
224 | track_speed = aout_ops->track_rate; |
225 | switch (audec->g_bst->data_width) { |
226 | case AV_SAMPLE_FMT_U8: |
227 | data_width = 8; |
228 | break; |
229 | case AV_SAMPLE_FMT_S16: |
230 | data_width = 16; |
231 | break; |
232 | case AV_SAMPLE_FMT_S32: |
233 | data_width = 32; |
234 | break; |
235 | default: |
236 | data_width = 16; |
237 | } |
238 | |
239 | int pts_delta = 0; |
240 | if ( property_get("media.libplayer.pts_delta",value,NULL) > 0) |
241 | { |
242 | pts_delta = atoi(value); |
243 | } |
244 | |
245 | channels = audec->g_bst->channels; |
246 | samplerate = audec->g_bst->samplerate; |
247 | if (!channels || !samplerate) { |
248 | adec_print("warning ::::zero channels %d, sample rate %d \n", channels, samplerate); |
249 | if (!samplerate) { |
250 | samplerate = 48000; |
251 | } |
252 | if (!channels) { |
253 | channels = 2; |
254 | } |
255 | } |
256 | offset = audec->decode_offset; |
257 | if (dsp_ops->dsp_file_fd >= 0) { |
258 | if (audec->g_bst->format != ACODEC_FMT_COOK && audec->g_bst->format != ACODEC_FMT_RAAC) { |
259 | //when first look up apts,set offset 0 |
260 | if (!audec->first_apts_lookup_over) { |
261 | offset = 0; |
262 | } |
263 | ioctl(dsp_ops->dsp_file_fd, AMSTREAM_IOC_APTS_LOOKUP, &offset); |
264 | } |
265 | //for cook/raac should wait to get first apts from decoder |
266 | else { |
267 | int wait_count = 10; |
268 | while (offset == 0xffffffff && wait_count-- > 0) { |
269 | amthreadpool_thread_usleep(10000); |
270 | } |
271 | offset = audec->decode_offset; |
272 | if (offset == 0xffffffff) { |
273 | adec_print(" cook/raac get apts 100 ms timeout \n"); |
274 | } |
275 | |
276 | } |
277 | } else { |
278 | adec_print("====abuf have not open!\n", val); |
279 | } |
280 | |
281 | if (am_getconfig_bool("media.arm.audio.apts_add")) { |
282 | offset = 0; |
283 | } |
284 | pts = offset; |
285 | if (!audec->first_apts_lookup_over) { |
286 | audec->last_valid_pts = pts; |
287 | audec->first_apts_lookup_over = 1; |
288 | return pts; |
289 | } |
290 | |
291 | if (audec->use_get_out_posion && audec->aout_ops.get_out_position) { |
292 | /*add by zz*/ |
293 | int64_t postion, time_us; |
294 | struct timespec timenow; |
295 | int ret; |
296 | ret = audec->aout_ops.get_out_position(audec, &postion, &time_us); |
297 | if (!ret) { |
298 | int decodered_samples; |
299 | int cache_samples; |
300 | int delay_us, t_us; |
301 | decodered_samples = audec->decode_pcm_offset * 8 /(channels * data_width); |
302 | cache_samples = decodered_samples - postion; |
303 | if (cache_samples < 0) |
304 | cache_samples = 0; |
305 | delay_us = 1000 * (cache_samples * 1000 / samplerate); |
306 | clock_gettime(CLOCK_MONOTONIC, &timenow); |
307 | t_us = timenow.tv_sec * 1000000LL + timenow.tv_nsec/1000 - time_us; |
308 | if (t_us > 0) |
309 | delay_us -= t_us; |
310 | if (delay_us < 0) |
311 | delay_us = 0; |
312 | delay_pts = delay_us * 90/1000; |
313 | if (pts == 0) { |
314 | int outsamples = postion - audec->last_out_postion ; |
315 | /*delay_us out samples after last refresh pts*/ |
316 | delay_us = 1000 * (outsamples * 1000 / samplerate); |
317 | delay_us = delay_us * track_speed; |
318 | if (delay_us < 0) |
319 | delay_us = 0; |
320 | pts = audec->last_valid_pts + delay_us * 90 /1000; |
321 | audec->last_valid_pts = pts; |
322 | pts += 90000 / 1000 * pts_delta; |
323 | audec->last_out_postion = postion; |
324 | audec->last_get_postion_time_us = time_us; |
325 | return pts; |
326 | } |
327 | audec->last_out_postion = postion; |
328 | audec->last_get_postion_time_us = time_us; |
329 | } else { |
330 | delay_pts = 0;/*audio track not ready? used buf_level add for pts*/ |
331 | } |
332 | } else { |
333 | delay_pts = 0; |
334 | } |
335 | if (delay_pts == 0) |
336 | { |
337 | if (pts == 0) { |
338 | if (audec->last_valid_pts) { |
339 | pts = audec->last_valid_pts; |
340 | } |
341 | frame_nums = (audec->out_len_after_last_valid_pts * 8 / (data_width * channels)); |
342 | pts += (frame_nums * 90000 / samplerate); |
343 | pts += 90000 / 1000 * pts_delta; |
344 | if (pts < 0) |
345 | pts = 0; |
346 | //adec_print("decode_offset:%d out_pcm:%d pts:%d \n",decode_offset,out_len_after_last_valid_pts,pts); |
347 | return pts; |
348 | } |
349 | { |
350 | int len = audec->g_bst->buf_level + audec->pcm_cache_size; |
351 | frame_nums = (len * 8 / (data_width * channels)); |
352 | delay_pts = (frame_nums * 90000 / samplerate); |
353 | } |
354 | } |
355 | delay_pts = delay_pts * track_speed; |
356 | if (pts > delay_pts) { |
357 | pts -= delay_pts; |
358 | } else { |
359 | pts = 0; |
360 | } |
361 | val = pts; |
362 | audec->last_valid_pts = pts; |
363 | audec->out_len_after_last_valid_pts = 0; |
364 | //adec_print("====get pts:%ld offset:%ld frame_num:%lld delay:%ld \n",val,decode_offset,frame_nums,delay_pts); |
365 | |
366 | val += 90000 / 1000 * pts_delta; // for a/v sync test,some times audio ahead video +28ms.so add +15ms to apts to ..... |
367 | if (val < 0) |
368 | val = 0; |
369 | return val; |
370 | } |
371 | |
372 | unsigned long armdec_get_pcrscr(dsp_operations_t *dsp_ops) |
373 | { |
374 | unsigned int val; |
375 | if (dsp_ops->dsp_file_fd < 0) { |
376 | adec_print("read error!! audiodsp have not opened\n"); |
377 | return -1; |
378 | } |
379 | ioctl(dsp_ops->dsp_file_fd, AMSTREAM_IOC_PCRSCR, &val); |
380 | return val; |
381 | } |
382 | unsigned long armdec_set_pts(dsp_operations_t *dsp_ops, unsigned long apts) |
383 | { |
384 | if (dsp_ops->dsp_file_fd < 0) { |
385 | adec_print("armdec_set_apts err!\n"); |
386 | return -1; |
387 | } |
388 | ioctl(dsp_ops->dsp_file_fd, AMSTREAM_IOC_SET_APTS, &apts); |
389 | return 0; |
390 | } |
391 | int armdec_set_skip_bytes(dsp_operations_t* dsp_ops, unsigned int bytes) |
392 | { |
393 | return 0; |
394 | } |
395 | static int set_sysfs_int(const char *path, int val) |
396 | { |
397 | return amsysfs_set_sysfs_int(path, val); |
398 | } |
399 | int get_decoder_status(void *p, struct adec_status *adec) |
400 | { |
401 | aml_audio_dec_t *audec = (aml_audio_dec_t *)p; |
402 | if (audec && audec->g_bst) { |
403 | adec->channels = audec->g_bst->channels; |
404 | adec->sample_rate = audec->g_bst->samplerate; |
405 | adec->resolution = audec->g_bst->data_width; |
406 | adec->error_count = audec->nDecodeErrCount; //need count |
407 | adec->status = (audec->state > INITTED) ? 1 : 0; |
408 | return 0; |
409 | } else { |
410 | return -1; |
411 | } |
412 | } |
413 | |
414 | /** |
415 | * \brief register audio decoder |
416 | * \param audec pointer to audec ,codec_type |
417 | * \return 0 on success otherwise -1 if an error occurred |
418 | */ |
419 | int RegisterDecode(aml_audio_dec_t *audec, int type) |
420 | { |
421 | switch (type) { |
422 | case AUDIO_ARM_DECODER: |
423 | memset(&AudioArmDecoder, 0, sizeof(audio_decoder_operations_t)); |
424 | audec->adec_ops = &AudioArmDecoder; |
425 | find_audio_lib(audec); |
426 | audec->adec_ops->priv_data = audec; |
427 | break; |
428 | case AUDIO_FFMPEG_DECODER: |
429 | audec->adec_ops = &AudioFFmpegDecoder; |
430 | audec->adec_ops->priv_data = audec; |
431 | break; |
432 | default: |
433 | audec->adec_ops = &AudioFFmpegDecoder; |
434 | audec->adec_ops->priv_data = audec; |
435 | break; |
436 | } |
437 | return 0; |
438 | } |
439 | |
440 | static int InBufferInit(aml_audio_dec_t *audec) |
441 | { |
442 | int ret = uio_init(audec); |
443 | if (ret < 0) { |
444 | adec_print("uio init error! \n"); |
445 | return -1; |
446 | } |
447 | return 0; |
448 | } |
449 | static int InBufferRelease(aml_audio_dec_t *audec) |
450 | { |
451 | // close(audec->fd_uio); |
452 | // audec->fd_uio=-1; |
453 | uio_deinit(audec); |
454 | return 0; |
455 | } |
456 | |
457 | |
458 | static int OutBufferInit(aml_audio_dec_t *audec) |
459 | { |
460 | audec->g_bst = malloc(sizeof(buffer_stream_t)); |
461 | if (!audec->g_bst) { |
462 | adec_print("[%s %d]g_bst malloc failed! \n", __FUNCTION__, __LINE__); |
463 | audec->g_bst = NULL; |
464 | return -1; |
465 | } else { |
466 | adec_print("[%s %d] audec->g_bst/%p", __FUNCTION__, __LINE__, audec->g_bst); |
467 | } |
468 | |
469 | memset(audec->g_bst, 0, sizeof(buffer_stream_t)); |
470 | |
471 | if (audec->adec_ops->nOutBufSize <= 0) { //set default if not set |
472 | audec->adec_ops->nOutBufSize = DEFAULT_PCM_BUFFER_SIZE; |
473 | } |
474 | |
475 | int ret = init_buff(audec->g_bst, audec->adec_ops->nOutBufSize); |
476 | if (ret == -1) { |
477 | adec_print("[%s %d]pcm buffer init failed !\n", __FUNCTION__, __LINE__); |
478 | return -1; |
479 | } |
480 | adec_print("[%s %d]pcm buffer init ok buf_size:%d\n", __FUNCTION__, __LINE__, audec->g_bst->buf_length); |
481 | |
482 | audec->g_bst->data_width = audec->data_width = AV_SAMPLE_FMT_S16; |
483 | |
484 | if (audec->channels > 0) { |
485 | audec->g_bst->channels = audec->channels; |
486 | } |
487 | if (audec->samplerate > 0) { |
488 | audec->g_bst->samplerate = audec->samplerate; |
489 | } |
490 | audec->g_bst->format = audec->format; |
491 | |
492 | return 0; |
493 | } |
494 | static int OutBufferInit_raw(aml_audio_dec_t *audec) |
495 | { |
496 | audec->g_bst_raw = malloc(sizeof(buffer_stream_t)); |
497 | if (!audec->g_bst_raw) { |
498 | adec_print("[%s %d]g_bst_raw malloc failed!\n", __FUNCTION__, __LINE__); |
499 | audec->g_bst_raw = NULL; |
500 | return -1; |
501 | } else { |
502 | adec_print("[%s %d] audec->audec->g_bst_raw/%p", __FUNCTION__, __LINE__, audec->g_bst_raw); |
503 | } |
504 | |
505 | if (audec->adec_ops->nOutBufSize <= 0) { //set default if not set |
506 | audec->adec_ops->nOutBufSize = DEFAULT_PCM_BUFFER_SIZE; |
507 | } |
508 | if ((audec->format == ACODEC_FMT_DTS || audec->format == ACODEC_FMT_TRUEHD) && amsysfs_get_sysfs_int("/sys/class/audiodsp/digital_raw") == 2) { |
509 | audec->adec_ops->nOutBufSize *= 2; |
510 | } |
511 | int ret = init_buff(audec->g_bst_raw, audec->adec_ops->nOutBufSize); |
512 | if (ret == -1) { |
513 | adec_print("[%s %d]raw_buf init failed !\n", __FUNCTION__, __LINE__); |
514 | return -1; |
515 | } |
516 | adec_print("[%s %d]raw buffer init ok buf_size/%d\n", __FUNCTION__, __LINE__, audec->g_bst_raw->buf_length); |
517 | |
518 | audec->g_bst_raw->data_width = audec->data_width = AV_SAMPLE_FMT_S16; |
519 | if (audec->channels > 0) { |
520 | audec->g_bst_raw->channels = audec->channels; |
521 | } else { |
522 | audec->g_bst_raw->channels = audec->channels = 2; |
523 | } |
524 | |
525 | if (audec->samplerate > 0) { |
526 | audec->g_bst_raw->samplerate = audec->samplerate; |
527 | } else { |
528 | audec->g_bst_raw->samplerate = audec->samplerate = 48000; |
529 | } |
530 | |
531 | return 0; |
532 | } |
533 | static int OutBufferRelease(aml_audio_dec_t *audec) |
534 | { |
535 | if (audec->g_bst) { |
536 | adec_print("[%s %d] audec->g_bst/%p", __FUNCTION__, __LINE__, audec->g_bst); |
537 | release_buffer(audec->g_bst); |
538 | audec->g_bst = NULL; |
539 | } |
540 | return 0; |
541 | } |
542 | |
543 | static int OutBufferRelease_raw(aml_audio_dec_t *audec) |
544 | { |
545 | if (audec->g_bst_raw) { |
546 | adec_print("[%s %d] audec->g_bst_raw/%p", __FUNCTION__, __LINE__, audec->g_bst_raw); |
547 | release_buffer(audec->g_bst_raw); |
548 | audec->g_bst_raw = NULL; |
549 | } |
550 | return 0; |
551 | } |
552 | |
553 | static int enable_raw_output(aml_audio_dec_t *audec) |
554 | { |
555 | int enable = 0; |
556 | enable = amsysfs_get_sysfs_int("/sys/class/audiodsp/digital_raw"); |
557 | if (enable) { |
558 | if (audec->format == ACODEC_FMT_AC3 || audec->format == ACODEC_FMT_EAC3 || audec->format == ACODEC_FMT_DTS || |
559 | audec->format == ACODEC_FMT_TRUEHD) { |
560 | return 1; |
561 | } |
562 | } |
563 | return 0; |
564 | } |
565 | static int audio_codec_init(aml_audio_dec_t *audec) |
566 | { |
567 | //reset static&global |
568 | audec->exit_decode_thread = 0; |
569 | audec->exit_decode_thread_success = 0; |
570 | audec->decode_offset = 0; |
571 | audec->decode_pcm_offset = 0; |
572 | audec->nDecodeErrCount = 0; |
573 | audec->g_bst = NULL; |
574 | audec->g_bst_raw = NULL; |
575 | audec->fd_uio = -1; |
576 | audec->last_valid_pts = 0; |
577 | audec->out_len_after_last_valid_pts = 0; |
578 | audec->pcm_cache_size = 0; |
579 | audec->sn_threadid = -1; |
580 | audec->sn_getpackage_threadid = -1; |
581 | audec->OmxFirstFrameDecoded = 0; |
582 | audec->use_get_out_posion = am_getconfig_bool_def("media.audio.pts.use_get_posion", 0); |
583 | package_list_init(audec); |
584 | while (0 != set_sysfs_int(DECODE_ERR_PATH, DECODE_NONE_ERR)) { |
585 | adec_print("[%s %d]set codec fatal failed ! \n", __FUNCTION__, __LINE__); |
586 | amthreadpool_thread_usleep(100000); |
587 | } |
588 | |
589 | adec_print("[%s %d]param:data_width:%d samplerate:%d channel:%d \n", |
590 | __FUNCTION__, __LINE__, audec->data_width, audec->samplerate, audec->channels); |
591 | |
592 | audec->data_width = AV_SAMPLE_FMT_S16; |
593 | if (audec->channels > 0) { |
594 | int NumChSave = audec->channels; |
595 | audec->channels = (audec->channels > 2 ? 2 : audec->channels); |
596 | audec->adec_ops->channels = audec->channels; |
597 | if (audec->format == ACODEC_FMT_PCM_S16BE || audec->format == ACODEC_FMT_PCM_S16LE || |
598 | audec->format == ACODEC_FMT_PCM_U8 || audec->format == ACODEC_FMT_PCM_BLURAY || |
599 | audec->format == ACODEC_FMT_WIFIDISPLAY || audec->format == ACODEC_FMT_ALAW || |
600 | audec->format == ACODEC_FMT_MULAW || audec->format == ACODEC_FMT_ADPCM) { |
601 | audec->adec_ops->channels = NumChSave; |
602 | } |
603 | } |
604 | //for raac/cook audio pts are updated from audio decoder,so set a invalid pts default. |
605 | else if (audec->format == ACODEC_FMT_RAAC || audec->format == ACODEC_FMT_COOK) { |
606 | audec->decode_offset = 0xffffffff; |
607 | } |
608 | if (audec->samplerate > 0) { |
609 | audec->adec_ops->samplerate = audec->samplerate; |
610 | } else { |
611 | // audec->adec_ops->samplerate=audec->samplerate=48000; |
612 | } |
613 | switch (audec->data_width) { |
614 | case AV_SAMPLE_FMT_U8: |
615 | audec->adec_ops->bps = 8; |
616 | break; |
617 | case AV_SAMPLE_FMT_S16: |
618 | audec->adec_ops->bps = 16; |
619 | break; |
620 | case AV_SAMPLE_FMT_S32: |
621 | audec->adec_ops->bps = 32; |
622 | break; |
623 | default: |
624 | audec->adec_ops->bps = 16; |
625 | } |
626 | adec_print("[%s %d]param_applied: bps:%d samplerate:%d channel:%d \n", |
627 | __FUNCTION__, __LINE__, audec->adec_ops->bps, audec->adec_ops->samplerate, audec->adec_ops->channels); |
628 | |
629 | audec->adec_ops->extradata_size = audec->extradata_size; |
630 | if (audec->extradata_size > 0) { |
631 | memcpy(audec->adec_ops->extradata, audec->extradata, audec->extradata_size); |
632 | } |
633 | |
634 | int ret = 0; |
635 | if (!audec->StageFrightCodecEnableType) { //1-decoder init |
636 | ret = audec->adec_ops->init(audec->adec_ops); |
637 | } |
638 | if (ret == -1) { |
639 | adec_print("[%s %d]adec_ops init err\n", __FUNCTION__, __LINE__); |
640 | goto err1; |
641 | } |
642 | |
643 | ret = OutBufferInit(audec); //2-pcm_buffer init |
644 | if (ret == -1) { |
645 | adec_print("[%s %d]out buffer init err\n", __FUNCTION__, __LINE__); |
646 | goto err2; |
647 | } |
648 | if (enable_raw_output(audec)) { |
649 | ret = OutBufferInit_raw(audec); |
650 | if (ret == -1) { |
651 | adec_print("[%s %d]out_raw buffer init err\n", __FUNCTION__, __LINE__); |
652 | OutBufferRelease_raw(audec); |
653 | goto err2; |
654 | } |
655 | } |
656 | ret = InBufferInit(audec); //3-init uio |
657 | if (ret == -1) { |
658 | adec_print("====in buffer init err \n"); |
659 | goto err3; |
660 | } |
661 | |
662 | //4-other init |
663 | audec->adsp_ops.dsp_on = 1; |
664 | audec->adsp_ops.dsp_read = armdec_stream_read; |
665 | audec->adsp_ops.get_cur_pts = armdec_get_pts; |
666 | audec->adsp_ops.get_cur_pcrscr = armdec_get_pcrscr; |
667 | audec->adsp_ops.set_cur_apts = armdec_set_pts; |
668 | audec->adsp_ops.set_skip_bytes = armdec_set_skip_bytes; |
669 | audec->adsp_ops.dsp_read_raw = armdec_stream_read_raw; |
670 | audec->pcm_bytes_readed = 0; |
671 | audec->raw_bytes_readed = 0; |
672 | audec->raw_frame_size = 0; |
673 | audec->pcm_frame_size = 0; |
674 | audec->i2s_iec958_sync_flag = 1; |
675 | audec->i2s_iec958_sync_gate = 0; |
676 | audec->codec_type = 0; |
677 | return 0; |
678 | |
679 | err1: |
680 | audec->adec_ops->release(audec->adec_ops); |
681 | return -1; |
682 | err2: |
683 | audec->adec_ops->release(audec->adec_ops); |
684 | OutBufferRelease(audec); |
685 | return -1; |
686 | err3: |
687 | audec->adec_ops->release(audec->adec_ops); |
688 | OutBufferRelease(audec); |
689 | InBufferRelease(audec); |
690 | OutBufferRelease_raw(audec); |
691 | return -1; |
692 | } |
693 | int audio_codec_release(aml_audio_dec_t *audec) |
694 | { |
695 | //1-decode thread quit |
696 | if (!audec->StageFrightCodecEnableType) { |
697 | stop_decode_thread(audec);//1-decode thread quit |
698 | audec->adec_ops->release(audec->adec_ops);//2-decoder release |
699 | } else { |
700 | stop_decode_thread_omx(audec); |
701 | } |
702 | |
703 | InBufferRelease(audec);//3-uio uninit |
704 | OutBufferRelease(audec);//4-outbufferrelease |
705 | OutBufferRelease_raw(audec); |
706 | audec->adsp_ops.dsp_on = -1;//5-other release |
707 | audec->adsp_ops.dsp_read = NULL; |
708 | audec->adsp_ops.get_cur_pts = NULL; |
709 | audec->adsp_ops.dsp_file_fd = -1; |
710 | |
711 | return 0; |
712 | } |
713 | |
714 | |
715 | static int audio_hardware_ctrl(hw_command_t cmd) |
716 | { |
717 | int fd; |
718 | fd = open(AUDIO_CTRL_DEVICE, O_RDONLY); |
719 | if (fd < 0) { |
720 | adec_print("Open Device %s Failed!", AUDIO_CTRL_DEVICE); |
721 | return -1; |
722 | } |
723 | |
724 | switch (cmd) { |
725 | case HW_CHANNELS_SWAP: |
726 | ioctl(fd, AMAUDIO_IOC_SET_CHANNEL_SWAP, 0); |
727 | break; |
728 | |
729 | case HW_LEFT_CHANNEL_MONO: |
730 | ioctl(fd, AMAUDIO_IOC_SET_LEFT_MONO, 0); |
731 | break; |
732 | |
733 | case HW_RIGHT_CHANNEL_MONO: |
734 | ioctl(fd, AMAUDIO_IOC_SET_RIGHT_MONO, 0); |
735 | break; |
736 | |
737 | case HW_STEREO_MODE: |
738 | ioctl(fd, AMAUDIO_IOC_SET_STEREO, 0); |
739 | break; |
740 | |
741 | default: |
742 | adec_print("Unknow Command %d!", cmd); |
743 | break; |
744 | |
745 | }; |
746 | |
747 | close(fd); |
748 | return 0; |
749 | } |
750 | |
751 | static int get_first_apts_flag(dsp_operations_t *dsp_ops) |
752 | { |
753 | int val; |
754 | if (dsp_ops->dsp_file_fd < 0) { |
755 | adec_print("[%s %d]read error!! audiodsp have not opened\n", __FUNCTION__, __LINE__); |
756 | return -1; |
757 | } |
758 | ioctl(dsp_ops->dsp_file_fd, GET_FIRST_APTS_FLAG, &val); |
759 | return val; |
760 | } |
761 | |
762 | |
763 | /** |
764 | * \brief start audio dec when receive START command. |
765 | * \param audec pointer to audec |
766 | */ |
767 | static int start_adec(aml_audio_dec_t *audec) |
768 | { |
769 | int ret; |
770 | audio_out_operations_t *aout_ops = &audec->aout_ops; |
771 | dsp_operations_t *dsp_ops = &audec->adsp_ops; |
772 | unsigned long vpts, apts; |
773 | int times = 0; |
774 | char buf[32]; |
775 | apts = vpts = 0; |
776 | audec->no_first_apts = 0; |
777 | audec->apts_start_flag = 0; |
778 | audec->first_apts = 0; |
779 | |
780 | char value[PROPERTY_VALUE_MAX] = {0}; |
781 | int wait_count = 100; |
782 | if (property_get("media.amadec.wait_count", value, NULL) > 0) { |
783 | wait_count = atoi(value); |
784 | } |
785 | adec_print("wait first apts count :%d \n", wait_count); |
786 | |
787 | if (audec->state == INITTED) { |
788 | //get info from the audiodsp == can get from amstreamer |
789 | while ((!get_first_apts_flag(dsp_ops)) && (!audec->need_stop) && (!audec->no_first_apts)) { |
790 | adec_print("wait first pts checkin complete !"); |
791 | if (amthreadpool_on_requare_exit(pthread_self())) { |
792 | adec_print("[%s:%d] quick interrupt \n", __FUNCTION__, __LINE__); |
793 | break; |
794 | } |
795 | times++; |
796 | if (times >= wait_count) { |
797 | amsysfs_get_sysfs_str(TSYNC_VPTS, buf, sizeof(buf));// read vpts |
798 | if (sscanf(buf, "0x%lx", &vpts) < 1) { |
799 | adec_print("unable to get vpts from: %s", buf); |
800 | return -1; |
801 | } |
802 | // save vpts to apts |
803 | if (vpts == 0) { // vpts invalid too |
804 | times = 0; // loop again |
805 | continue; |
806 | } |
807 | adec_print("## can't get first apts, save vpts to apts,vpts=%lx, \n", vpts); |
808 | sprintf(buf, "0x%lx", vpts); |
809 | amsysfs_set_sysfs_str(TSYNC_APTS, buf); |
810 | audec->no_first_apts = 1; |
811 | } |
812 | amthreadpool_thread_usleep(100000); |
813 | } |
814 | adec_print("get first apts ok, times:%d need_stop:%d auto_mute %d\n", times, audec->need_stop, audec->auto_mute); |
815 | if (audec->need_stop) { |
816 | return 0; |
817 | } |
818 | |
819 | /*start the the pts scr,...*/ |
820 | ret = adec_pts_start(audec); |
821 | if (audec->auto_mute) { |
822 | avsync_en(0); |
823 | adec_pts_pause(); |
824 | while ((!audec->need_stop) && track_switch_pts(audec)) { |
825 | amthreadpool_thread_usleep(1000); |
826 | } |
827 | avsync_en(1); |
828 | adec_pts_resume(); |
829 | audec->auto_mute = 0; |
830 | } |
831 | if (audec->tsync_mode == TSYNC_MODE_PCRMASTER) { |
832 | adec_print("[wcs-%s]-before audio track start,sleep 200ms\n",__FUNCTION__); |
833 | amthreadpool_thread_usleep(200 * 1000); //200ms |
834 | } |
835 | aout_ops->start(audec); |
836 | audec->state = ACTIVE; |
837 | } else { |
838 | adec_print("amadec status invalid, start adec failed \n"); |
839 | return -1; |
840 | } |
841 | |
842 | return 0; |
843 | } |
844 | |
845 | /** |
846 | * \brief pause audio dec when receive PAUSE command. |
847 | * \param audec pointer to audec |
848 | */ |
849 | static void pause_adec(aml_audio_dec_t *audec) |
850 | { |
851 | audio_out_operations_t *aout_ops = &audec->aout_ops; |
852 | if (audec->state == ACTIVE) { |
853 | audec->state = PAUSED; |
854 | adec_pts_pause(); |
855 | aout_ops->pause(audec); |
856 | } |
857 | } |
858 | |
859 | /** |
860 | * \brief resume audio dec when receive RESUME command. |
861 | * \param audec pointer to audec |
862 | */ |
863 | static void resume_adec(aml_audio_dec_t *audec) |
864 | { |
865 | audio_out_operations_t *aout_ops = &audec->aout_ops; |
866 | if (audec->state == PAUSED) { |
867 | audec->state = ACTIVE; |
868 | audec->refresh_pts_readytime_ms = gettime_ms() + |
869 | am_getconfig_int_def("media.amadec.wait_fresh_ms", 200); |
870 | aout_ops->resume(audec); |
871 | adec_pts_resume(); |
872 | } |
873 | } |
874 | |
875 | /** |
876 | * \brief stop audio dec when receive STOP command. |
877 | * \param audec pointer to audec |
878 | */ |
879 | static void stop_adec(aml_audio_dec_t *audec) |
880 | { |
881 | audio_out_operations_t *aout_ops = &audec->aout_ops; |
882 | adec_print("[%s %d]audec->state/%d\n", __FUNCTION__, __LINE__, audec->state); |
883 | if (audec->state > INITING) { |
884 | char buf[64]; |
885 | |
886 | audec->state = STOPPED; |
887 | aout_ops->mute(audec, 1); //mute output, some repeat sound in audioflinger after stop |
888 | aout_ops->stop(audec); |
889 | audio_codec_release(audec); |
890 | |
891 | sprintf(buf, "0x%lx", 0); |
892 | amsysfs_set_sysfs_str(TSYNC_FIRSTAPTS, buf); |
893 | } |
894 | } |
895 | |
896 | /** |
897 | * \brief release audio dec when receive RELEASE command. |
898 | * \param audec pointer to audec |
899 | */ |
900 | static void release_adec(aml_audio_dec_t *audec) |
901 | { |
902 | audec->state = TERMINATED; |
903 | } |
904 | |
905 | /** |
906 | * \brief mute audio dec when receive MUTE command. |
907 | * \param audec pointer to audec |
908 | * \param en 1 = mute, 0 = unmute |
909 | */ |
910 | static void mute_adec(aml_audio_dec_t *audec, int en) |
911 | { |
912 | audio_out_operations_t *aout_ops = &audec->aout_ops; |
913 | if (aout_ops->mute) { |
914 | adec_print("%s the output !\n", (en ? "mute" : "unmute")); |
915 | aout_ops->mute(audec, en); |
916 | audec->muted = en; |
917 | } |
918 | } |
919 | |
920 | /** |
921 | * \brief set volume to audio dec when receive SET_VOL command. |
922 | * \param audec pointer to audec |
923 | * \param vol volume value |
924 | */ |
925 | static void adec_set_volume(aml_audio_dec_t *audec, float vol) |
926 | { |
927 | audio_out_operations_t *aout_ops = &audec->aout_ops; |
928 | if (aout_ops->set_volume) { |
929 | adec_print("set audio volume! vol = %f\n", vol); |
930 | aout_ops->set_volume(audec, vol); |
931 | } |
932 | } |
933 | |
934 | /** |
935 | * \brief set volume to audio dec when receive SET_LRVOL command. |
936 | * \param audec pointer to audec |
937 | * \param lvol left channel volume value |
938 | * \param rvol right channel volume value |
939 | */ |
940 | static void adec_set_lrvolume(aml_audio_dec_t *audec, float lvol, float rvol) |
941 | { |
942 | audio_out_operations_t *aout_ops = &audec->aout_ops; |
943 | if (aout_ops->set_lrvolume) { |
944 | adec_print("set audio volume! left vol = %f,right vol:%f\n", lvol, rvol); |
945 | aout_ops->set_lrvolume(audec, lvol, rvol); |
946 | } |
947 | } |
948 | static void adec_flag_check(aml_audio_dec_t *audec) |
949 | { |
950 | audio_out_operations_t *aout_ops = &audec->aout_ops; |
951 | if (audec->auto_mute && (audec->state > INITTED)) { |
952 | aout_ops->pause(audec); |
953 | amthreadpool_thread_usleep(10000); |
954 | while ((!audec->need_stop) && track_switch_pts(audec)) { |
955 | amthreadpool_thread_usleep(1000); |
956 | } |
957 | aout_ops->resume(audec); |
958 | audec->auto_mute = 0; |
959 | } |
960 | } |
961 | |
962 | |
963 | static void start_decode_thread(aml_audio_dec_t *audec) |
964 | { |
965 | if (audec->state != INITTED) { |
966 | adec_print("decode not inited quit \n"); |
967 | return; |
968 | } |
969 | |
970 | pthread_t tid; |
971 | int ret = amthreadpool_pthread_create_name(&tid, NULL, (void *)audio_getpackage_loop, (void *)audec, "getpackagelp"); |
972 | audec->sn_getpackage_threadid = tid; |
973 | adec_print("[%s]Create get package thread success! tid = %d\n", __FUNCTION__, tid); |
974 | |
975 | ret = amthreadpool_pthread_create_name(&tid, NULL, (void *)audio_decode_loop, (void *)audec, "decodeloop"); |
976 | if (ret != 0) { |
977 | adec_print("[%s]Create ffmpeg decode thread failed!\n", __FUNCTION__); |
978 | return; |
979 | } |
980 | audec->sn_threadid = tid; |
981 | audec->audio_decoder_enabled = 0x1; |
982 | pthread_setname_np(tid, "AmadecDecodeLP"); |
983 | adec_print("[%s]Create ffmpeg decode thread success! tid = %d\n", __FUNCTION__, tid); |
984 | } |
985 | static void stop_decode_thread(aml_audio_dec_t *audec) |
986 | { |
987 | audec->exit_decode_thread = 1; |
988 | int ret = amthreadpool_pthread_join(audec->sn_threadid, NULL); |
989 | adec_print("[%s]decode thread exit success\n", __FUNCTION__); |
990 | ret = amthreadpool_pthread_join(audec->sn_getpackage_threadid, NULL); |
991 | adec_print("[%s]get package thread exit success\n", __FUNCTION__); |
992 | |
993 | audec->sn_threadid = -1; |
994 | audec->sn_getpackage_threadid = -1; |
995 | } |
996 | |
997 | /* --------------------------------------------------------------------------*/ |
998 | /** |
999 | * @brief getNextFrameSize Get next frame size |
1000 | * |
1001 | * @param[in] format audio format |
1002 | * |
1003 | * @return -1: no frame_size use default 0: need get again non_zero: success |
1004 | */ |
1005 | /* --------------------------------------------------------------------------*/ |
1006 | |
1007 | static int get_frame_size(aml_audio_dec_t *audec) |
1008 | { |
1009 | int frame_szie = 0; |
1010 | int ret = 0; |
1011 | int extra_data = 8; //? |
1012 | StartCode *start_code = &audec->start_code; |
1013 | |
1014 | if (start_code->status == 0 || start_code->status == 3) { |
1015 | memset(start_code, 0, sizeof(StartCode)); |
1016 | } |
1017 | /*ape case*/ |
1018 | if (audec->format == ACODEC_FMT_APE) { |
1019 | if (start_code->status == 0) { //have not get the sync data |
1020 | ret = read_buffer(start_code->buff, 4); |
1021 | if (ret <= 0) { |
1022 | return 0; |
1023 | } |
1024 | start_code->size = 4; |
1025 | start_code->status = 1; |
1026 | } |
1027 | |
1028 | if (start_code->status == 1) { //start find sync word |
1029 | if (start_code->size < 4) { |
1030 | ret = read_buffer(start_code->buff + start_code->size, 4 - start_code->size); |
1031 | if (ret <= 0) { |
1032 | return 0; |
1033 | } |
1034 | start_code->size = 4; |
1035 | } |
1036 | if (start_code->size == 4) { |
1037 | if ((start_code->buff[0] == 'A') && (start_code->buff[1] == 'P') && (start_code->buff[2] == 'T') && (start_code->buff[3] == 'S')) { |
1038 | start_code->size = 0; |
1039 | start_code->status = 2; //sync word found ,start find frame size |
1040 | } else { |
1041 | start_code->size = 3; |
1042 | start_code->buff[0] = start_code->buff[1]; |
1043 | start_code->buff[1] = start_code->buff[2]; |
1044 | start_code->buff[2] = start_code->buff[3]; |
1045 | return 0; |
1046 | } |
1047 | } |
1048 | |
1049 | } |
1050 | |
1051 | if (start_code->status == 2) { |
1052 | ret = read_buffer(start_code->buff, 4); |
1053 | if (ret <= 0) { |
1054 | return 0; |
1055 | } |
1056 | start_code->size = 4; |
1057 | frame_szie = start_code->buff[3] << 24 | start_code->buff[2] << 16 | start_code->buff[1] << 8 | start_code->buff[0] + extra_data; |
1058 | frame_szie = (frame_szie + 3) & (~3); |
1059 | start_code->status = 3; //found frame size |
1060 | return frame_szie; |
1061 | } |
1062 | } |
1063 | return -1; |
1064 | } |
1065 | // check if audio format info changed,if changed, apply new parameters to audio track |
1066 | static void check_audio_info_changed(aml_audio_dec_t *audec) |
1067 | { |
1068 | buffer_stream_t *g_bst = audec->g_bst; |
1069 | AudioInfo g_AudioInfo = {0}; |
1070 | int BufLevelAllowDoFmtChg = 0; |
1071 | audio_decoder_operations_t *adec_ops = audec->adec_ops; |
1072 | adec_ops->getinfo(audec->adec_ops, &g_AudioInfo); |
1073 | if (g_AudioInfo.channels != 0 && g_AudioInfo.samplerate != 0) { |
1074 | if ((g_AudioInfo.channels != g_bst->channels) || (g_AudioInfo.samplerate != g_bst->samplerate)) { |
1075 | // the first time we get sample rate/channel num info,we use that to set audio track. |
1076 | if (audec->channels == 0 || audec->samplerate == 0) { |
1077 | g_bst->channels = audec->channels = g_AudioInfo.channels; |
1078 | g_bst->samplerate = audec->samplerate = g_AudioInfo.samplerate; |
1079 | } else { |
1080 | //experienc value:0.2 Secs |
1081 | BufLevelAllowDoFmtChg = audec->samplerate * audec->channels * (audec->adec_ops->bps >> 3) / 5; |
1082 | while ((audec->format_changed_flag || g_bst->buf_level > BufLevelAllowDoFmtChg) && !audec->exit_decode_thread) { |
1083 | amthreadpool_thread_usleep(20000); |
1084 | } |
1085 | if (!audec->exit_decode_thread) { |
1086 | adec_print("[%s]Info Changed: src:sample:%d channel:%d dest sample:%d channel:%d PCMBufLevel:%d\n", |
1087 | __FUNCTION__, audec->samplerate, audec->channels, g_AudioInfo.samplerate, g_AudioInfo.channels, g_bst->buf_level); |
1088 | g_bst->channels = g_AudioInfo.channels; |
1089 | g_bst->samplerate = g_AudioInfo.samplerate; |
1090 | if (audec->state == ACTIVE) |
1091 | audec->aout_ops.pause(audec); |
1092 | audec->format_changed_flag = 1; |
1093 | } |
1094 | } |
1095 | } |
1096 | } |
1097 | } |
1098 | void *audio_getpackage_loop(void *args) |
1099 | { |
1100 | int ret; |
1101 | aml_audio_dec_t *audec; |
1102 | audio_decoder_operations_t *adec_ops; |
1103 | int nNextFrameSize = 0; //next read frame size |
1104 | int inlen = 0;//real data size in in_buf |
1105 | int nInBufferSize = 0; //full buffer size |
1106 | char *inbuf = NULL;//real buffer |
1107 | int rlen = 0;//read buffer ret size |
1108 | int nAudioFormat; |
1109 | unsigned wfd = 0; |
1110 | if (am_getconfig_bool("media.libplayer.wfd")) { |
1111 | wfd = 1; |
1112 | } |
1113 | |
1114 | adec_print("[%s]adec_getpackage_loop start!\n", __FUNCTION__); |
1115 | audec = (aml_audio_dec_t *)args; |
1116 | adec_ops = audec->adec_ops; |
1117 | nAudioFormat = audec->format; |
1118 | inlen = 0; |
1119 | nNextFrameSize = adec_ops->nInBufSize; |
1120 | while (1) { |
1121 | exit_decode_loop: |
1122 | if (audec->exit_decode_thread) { /*detect quit condition*/ |
1123 | if (inbuf) { |
1124 | free(inbuf); |
1125 | } |
1126 | package_list_free(audec); |
1127 | break; |
1128 | } |
1129 | |
1130 | nNextFrameSize = get_frame_size(audec); /*step 2 get read buffer size*/ |
1131 | if (nNextFrameSize == -1) { |
1132 | nNextFrameSize = adec_ops->nInBufSize; |
1133 | } else if (nNextFrameSize == 0) { |
1134 | amthreadpool_thread_usleep(1000); |
1135 | continue; |
1136 | } |
1137 | |
1138 | nInBufferSize = nNextFrameSize;/*step 3 read buffer*/ |
1139 | if (inbuf != NULL) { |
1140 | free(inbuf); |
1141 | inbuf = NULL; |
1142 | } |
1143 | inbuf = malloc(nInBufferSize); |
1144 | |
1145 | int nNextReadSize = nInBufferSize; |
1146 | int nRet = 0; |
1147 | int nReadErrCount = 0; |
1148 | int nCurrentReadCount = 0; |
1149 | int nReadSizePerTime = 1 * 1024; |
1150 | rlen = 0; |
1151 | int sleeptime = 0; |
1152 | while (nNextReadSize > 0 && !audec->exit_decode_thread) { |
1153 | if (nNextReadSize <= nReadSizePerTime) { |
1154 | nReadSizePerTime = nNextReadSize; |
1155 | } |
1156 | nRet = read_buffer(inbuf + rlen, nReadSizePerTime); //read 10K per time |
1157 | if (nRet <= 0) { |
1158 | sleeptime++; |
1159 | amthreadpool_thread_usleep(1000); |
1160 | continue; |
1161 | } |
1162 | rlen += nRet; |
1163 | nNextReadSize -= nRet; |
1164 | if (wfd && nAudioFormat == ACODEC_FMT_AAC) { |
1165 | if (rlen > 300) { |
1166 | break; |
1167 | } |
1168 | } |
1169 | } |
1170 | // adec_print(" read data %d,sleep time %d ms \n", rlen,sleeptime); |
1171 | |
1172 | sleeptime = 0; |
1173 | nCurrentReadCount = rlen; |
1174 | rlen += inlen; |
1175 | ret = -1; |
1176 | while ((ret = package_add(audec, inbuf, rlen)) && !audec->exit_decode_thread) { |
1177 | amthreadpool_thread_usleep(1000); |
1178 | } |
1179 | if (ret) { |
1180 | free(inbuf); |
1181 | } |
1182 | inbuf = NULL; |
1183 | } |
1184 | QUIT: |
1185 | adec_print("[%s]Exit adec_getpackage_loop Thread finished!", __FUNCTION__); |
1186 | pthread_exit(NULL); |
1187 | return NULL; |
1188 | } |
1189 | |
1190 | static char pcm_buf_tmp[AVCODEC_MAX_AUDIO_FRAME_SIZE];//max frame size out buf |
1191 | void *audio_decode_loop(void *args) |
1192 | { |
1193 | int ret; |
1194 | aml_audio_dec_t *audec; |
1195 | audio_out_operations_t *aout_ops; |
1196 | audio_decoder_operations_t *adec_ops; |
1197 | int nNextFrameSize = 0; //next read frame size |
1198 | int inlen = 0;//real data size in in_buf |
1199 | int nRestLen = 0; //left data after last decode |
1200 | int nInBufferSize = 0; //full buffer size |
1201 | //int nStartDecodePoint=0;//start decode point in in_buf |
1202 | char *inbuf = NULL;//real buffer |
1203 | int rlen = 0;//read buffer ret size |
1204 | char *pRestData = NULL; |
1205 | char *inbuf2; |
1206 | |
1207 | int dlen = 0;//decode size one time |
1208 | int declen = 0;//current decoded size |
1209 | int nCurrentReadCount = 0; |
1210 | int needdata = 0; |
1211 | char startcode[5]; |
1212 | int extra_data = 8; |
1213 | int nCodecID; |
1214 | int nAudioFormat; |
1215 | char *outbuf = pcm_buf_tmp; |
1216 | int outlen = 0; |
1217 | struct package *p_Package; |
1218 | buffer_stream_t *g_bst; |
1219 | AudioInfo g_AudioInfo; |
1220 | adec_print("[%s]adec_armdec_loop start!\n", __FUNCTION__); |
1221 | audec = (aml_audio_dec_t *)args; |
1222 | aout_ops = &audec->aout_ops; |
1223 | adec_ops = audec->adec_ops; |
1224 | memset(outbuf, 0, AVCODEC_MAX_AUDIO_FRAME_SIZE); |
1225 | g_bst = audec->g_bst; |
1226 | |
1227 | nAudioFormat = audec->format; |
1228 | g_bst->format = audec->format; |
1229 | inlen = 0; |
1230 | nNextFrameSize = adec_ops->nInBufSize; |
1231 | adec_ops->nAudioDecoderType = audec->format; |
1232 | while (1) { |
1233 | exit_decode_loop: |
1234 | |
1235 | if (audec->exit_decode_thread) { //detect quit condition |
1236 | if (inbuf) { |
1237 | free(inbuf); |
1238 | inbuf = NULL; |
1239 | } |
1240 | if (pRestData) { |
1241 | free(pRestData); |
1242 | pRestData = NULL; |
1243 | } |
1244 | audec->exit_decode_thread_success = 1; |
1245 | break; |
1246 | } |
1247 | //step 2 get read buffer size |
1248 | p_Package = package_get(audec); |
1249 | if (!p_Package) { |
1250 | amthreadpool_thread_usleep(1000); |
1251 | continue; |
1252 | } |
1253 | if (inbuf != NULL) { |
1254 | free(inbuf); |
1255 | inbuf = NULL; |
1256 | } |
1257 | |
1258 | if (inlen && pRestData) { |
1259 | rlen = p_Package->size + inlen; |
1260 | inbuf = malloc(rlen); |
1261 | memcpy(inbuf, pRestData, inlen); |
1262 | memcpy(inbuf + inlen, p_Package->data, p_Package->size); |
1263 | free(pRestData); |
1264 | free(p_Package->data); |
1265 | pRestData = NULL; |
1266 | p_Package->data = NULL; |
1267 | } else { |
1268 | rlen = p_Package->size; |
1269 | inbuf = p_Package->data; |
1270 | p_Package->data = NULL; |
1271 | } |
1272 | free(p_Package); |
1273 | p_Package = NULL; |
1274 | |
1275 | nCurrentReadCount = rlen; |
1276 | inlen = rlen; |
1277 | declen = 0; |
1278 | if (nCurrentReadCount > 0) { |
1279 | while (declen < rlen && !audec->exit_decode_thread) { |
1280 | outlen = AVCODEC_MAX_AUDIO_FRAME_SIZE; |
1281 | if (nAudioFormat == ACODEC_FMT_COOK || nAudioFormat == ACODEC_FMT_RAAC || nAudioFormat == ACODEC_FMT_AMR) { |
1282 | if (needdata > 0) { |
1283 | pRestData = malloc(inlen); |
1284 | if (pRestData) { |
1285 | memcpy(pRestData, (uint8_t *)(inbuf + declen), inlen); |
1286 | } |
1287 | needdata = 0; |
1288 | break; |
1289 | } |
1290 | } |
1291 | |
1292 | dlen = adec_ops->decode(audec->adec_ops, outbuf, &outlen, inbuf + declen, inlen); |
1293 | if (outlen > 0) { |
1294 | check_audio_info_changed(audec); |
1295 | } |
1296 | if (outlen > AVCODEC_MAX_AUDIO_FRAME_SIZE) { |
1297 | adec_print("!!!!!fatal error,out buffer overwriten,out len %d,actual %d", outlen, AVCODEC_MAX_AUDIO_FRAME_SIZE); |
1298 | } |
1299 | if (dlen <= 0) { |
1300 | |
1301 | if (nAudioFormat == ACODEC_FMT_APE) { |
1302 | inlen = 0; |
1303 | } else if (inlen > 0) { |
1304 | pRestData = malloc(inlen); |
1305 | if (pRestData) { |
1306 | memcpy(pRestData, (uint8_t *)(inbuf + declen), inlen); |
1307 | } |
1308 | } |
1309 | audec->nDecodeErrCount++;//decode failed, add err_count |
1310 | needdata = 0; |
1311 | break; |
1312 | } |
1313 | audec->nDecodeErrCount = 0; //decode success reset to 0 |
1314 | declen += dlen; |
1315 | inlen -= dlen; |
1316 | |
1317 | /* decoder input buffer not enough,need new data burst */ |
1318 | if (nAudioFormat == ACODEC_FMT_COOK || nAudioFormat == ACODEC_FMT_RAAC || nAudioFormat == ACODEC_FMT_AMR) { |
1319 | if (inlen <= declen) { |
1320 | needdata ++; |
1321 | } |
1322 | } |
1323 | // for aac decoder, if decoder cost es data but no pcm output,may need more data ,which is needed by frame resync |
1324 | else if (nAudioFormat == ACODEC_FMT_AAC_LATM || nAudioFormat == ACODEC_FMT_AAC) { |
1325 | if (outlen == 0 && inlen) { |
1326 | pRestData = malloc(inlen); |
1327 | if (pRestData) { |
1328 | memcpy(pRestData, (uint8_t *)(inbuf + declen), inlen); |
1329 | } |
1330 | audec->decode_offset += dlen; //update es offset for apts look up |
1331 | break; |
1332 | } |
1333 | } |
1334 | //write to the pcm buffer |
1335 | if (nAudioFormat == ACODEC_FMT_RAAC || nAudioFormat == ACODEC_FMT_COOK) { |
1336 | audec->decode_offset = audec->adec_ops->pts; |
1337 | } else { |
1338 | audec->decode_offset += dlen; |
1339 | } |
1340 | audec->decode_pcm_offset += outlen; |
1341 | audec->pcm_cache_size = outlen; |
1342 | if (g_bst) { |
1343 | int wlen = 0; |
1344 | while (outlen && !audec->exit_decode_thread) { |
1345 | if (g_bst->buf_length - g_bst->buf_level < outlen) { |
1346 | amthreadpool_thread_usleep(100000); |
1347 | continue; |
1348 | } |
1349 | wlen = write_pcm_buffer(outbuf, g_bst, outlen); |
1350 | outlen -= wlen; |
1351 | audec->pcm_cache_size -= wlen; |
1352 | } |
1353 | } |
1354 | } |
1355 | } else { |
1356 | amthreadpool_thread_usleep(1000); |
1357 | continue; |
1358 | } |
1359 | } |
1360 | |
1361 | adec_print("[%s]exit adec_armdec_loop Thread finished!", __FUNCTION__); |
1362 | pthread_exit(NULL); |
1363 | error: |
1364 | pthread_exit(NULL); |
1365 | return NULL; |
1366 | } |
1367 | |
1368 | void *adec_armdec_loop(void *args) |
1369 | { |
1370 | int ret; |
1371 | aml_audio_dec_t *audec; |
1372 | audio_out_operations_t *aout_ops; |
1373 | adec_cmd_t *msg = NULL; |
1374 | |
1375 | audec = (aml_audio_dec_t *)args; |
1376 | aout_ops = &audec->aout_ops; |
1377 | |
1378 | // codec init |
1379 | audec->state = INITING; |
1380 | while (1) { |
1381 | if (audec->need_stop) { |
1382 | goto MSG_LOOP; |
1383 | } |
1384 | |
1385 | ret = audio_codec_init(audec); |
1386 | if (ret == 0) { |
1387 | break; |
1388 | } |
1389 | usleep(10000); |
1390 | } |
1391 | audec->state = INITTED; |
1392 | |
1393 | //start decode thread |
1394 | while (1) { |
1395 | if (audec->need_stop) { |
1396 | //no need to call release, will do it in stop_adec |
1397 | goto MSG_LOOP; |
1398 | } |
1399 | if (audec->StageFrightCodecEnableType) { |
1400 | start_decode_thread_omx(audec); |
1401 | if (audec->OmxFirstFrameDecoded != 1) { // just one case, need_stop == 1 |
1402 | //usleep(10000); // no need |
1403 | continue; |
1404 | } |
1405 | } else { |
1406 | start_decode_thread(audec); |
1407 | } |
1408 | //ok |
1409 | break; |
1410 | } |
1411 | |
1412 | //aout init |
1413 | while (1) { |
1414 | if (audec->need_stop) { |
1415 | //no need to call release, will do it in stop_adec |
1416 | goto MSG_LOOP; |
1417 | } |
1418 | //wait the audio sr/ch ready to set audio track. |
1419 | adec_print("wait audio sr/channel begin \n"); |
1420 | while (((!audec->channels) || (!audec->samplerate)) && !audec->need_stop) { |
1421 | amthreadpool_thread_usleep(10000); |
1422 | } |
1423 | adec_print("wait audio sr/channel done \n"); |
1424 | ret = aout_ops->init(audec); |
1425 | if (ret) { |
1426 | adec_print("[%s %d]Audio out device init failed!", __FUNCTION__, __LINE__); |
1427 | amthreadpool_thread_usleep(10000); |
1428 | continue; |
1429 | } |
1430 | //ok |
1431 | break; |
1432 | } |
1433 | |
1434 | //wait first pts decoded |
1435 | start_adec(audec); |
1436 | |
1437 | MSG_LOOP: |
1438 | do { |
1439 | |
1440 | adec_reset_track(audec); |
1441 | adec_flag_check(audec); |
1442 | if (audec->state == ACTIVE) |
1443 | adec_refresh_pts(audec); |
1444 | msg = adec_get_message(audec); |
1445 | if (!msg) { |
1446 | amthreadpool_thread_usleep(10 * 1000); //if not wait,need changed to amthread usleep |
1447 | continue; |
1448 | } |
1449 | |
1450 | switch (msg->ctrl_cmd) { |
1451 | case CMD_START: |
1452 | |
1453 | adec_print("Receive START Command!\n"); |
1454 | //------------------------ |
1455 | if (!audec->StageFrightCodecEnableType) { |
1456 | start_decode_thread(audec); |
1457 | } |
1458 | //------------------------ |
1459 | start_adec(audec); |
1460 | break; |
1461 | |
1462 | case CMD_PAUSE: |
1463 | |
1464 | adec_print("Receive PAUSE Command!"); |
1465 | pause_adec(audec); |
1466 | break; |
1467 | |
1468 | case CMD_RESUME: |
1469 | |
1470 | adec_print("Receive RESUME Command!"); |
1471 | resume_adec(audec); |
1472 | break; |
1473 | |
1474 | case CMD_STOP: |
1475 | |
1476 | adec_print("Receive STOP Command!"); |
1477 | stop_adec(audec); |
1478 | break; |
1479 | |
1480 | case CMD_MUTE: |
1481 | |
1482 | adec_print("Receive Mute Command!"); |
1483 | if (msg->has_arg) { |
1484 | mute_adec(audec, msg->value.en); |
1485 | } |
1486 | break; |
1487 | |
1488 | case CMD_SET_VOL: |
1489 | |
1490 | adec_print("Receive Set Vol Command!"); |
1491 | if (msg->has_arg) { |
1492 | adec_set_volume(audec, msg->value.volume); |
1493 | } |
1494 | break; |
1495 | case CMD_SET_LRVOL: |
1496 | |
1497 | adec_print("Receive Set LRVol Command!"); |
1498 | if (msg->has_arg) { |
1499 | adec_set_lrvolume(audec, msg->value.volume, msg->value_ext.volume); |
1500 | } |
1501 | break; |
1502 | |
1503 | case CMD_CHANL_SWAP: |
1504 | |
1505 | adec_print("Receive Channels Swap Command!"); |
1506 | audio_hardware_ctrl(HW_CHANNELS_SWAP); |
1507 | break; |
1508 | |
1509 | case CMD_LEFT_MONO: |
1510 | |
1511 | adec_print("Receive Left Mono Command!"); |
1512 | audio_hardware_ctrl(HW_LEFT_CHANNEL_MONO); |
1513 | break; |
1514 | |
1515 | case CMD_RIGHT_MONO: |
1516 | |
1517 | adec_print("Receive Right Mono Command!"); |
1518 | audio_hardware_ctrl(HW_RIGHT_CHANNEL_MONO); |
1519 | break; |
1520 | |
1521 | case CMD_STEREO: |
1522 | |
1523 | adec_print("Receive Stereo Command!"); |
1524 | audio_hardware_ctrl(HW_STEREO_MODE); |
1525 | break; |
1526 | |
1527 | case CMD_RELEASE: |
1528 | |
1529 | adec_print("Receive RELEASE Command!"); |
1530 | release_adec(audec); |
1531 | break; |
1532 | |
1533 | default: |
1534 | adec_print("Unknow Command!"); |
1535 | break; |
1536 | |
1537 | } |
1538 | |
1539 | if (msg) { |
1540 | adec_message_free(msg); |
1541 | msg = NULL; |
1542 | } |
1543 | } while (audec->state != TERMINATED); |
1544 | |
1545 | adec_print("Exit Message Loop Thread!"); |
1546 | pthread_exit(NULL); |
1547 | return NULL; |
1548 | } |
1549 | |
1550 | |
1551 |