summaryrefslogtreecommitdiff
path: root/amadec/adec-wfd.c (plain)
blob: c1faf4da0166040ce7926b3945d974fc6477982c
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 <adec-pts-mgt.h>
10#include <adec_write.h>
11#include <adec_omx_brige.h>
12#include <Amsysfsutils.h>
13#include <audio-dec.h>
14#include <cutils/properties.h>
15#include <amthreadpool.h>
16#include "audiodsp_update_format.h"
17
18typedef struct {
19 int codec_id;
20 char name[64];
21} audio_lib_t;
22
23typedef int (*fn_pcm_output_init)(int sr, int ch);
24typedef int (*fn_pcm_output_write)(char *buf, unsigned size);
25typedef int (*fn_pcm_output_uninit)();
26typedef int (*fn_pcm_output_latency)();
27
28
29typedef void (*fn_audio_set_exit_flag)();
30
31
32static audio_lib_t wfd_audio_lib_list[] = {
33 {ACODEC_FMT_WIFIDISPLAY, "libpcm_wfd.so"},
34 {ACODEC_FMT_AAC, "libaac_helix.so"},
35 0
36} ;
37static audio_decoder_operations_t WFDAudioDecoder = {
38 "WFDDecoder",
39 AUDIO_ARM_DECODER,
40 0,
41};
42
43static fn_pcm_output_init wfd_out_init = NULL;
44static fn_pcm_output_write wfd_out_write = NULL;
45static fn_pcm_output_uninit wfd_out_uninit = NULL;
46static fn_pcm_output_latency wfd_out_latency = NULL;
47
48
49static fn_audio_set_exit_flag wfd_adec_exit = NULL;
50static void *dec_mLibHandle = NULL;
51static void *out_mLibHandle = NULL;
52static void *audio_wfd_decode_loop(void *args);
53static void stop_wfd_decode_thread(aml_audio_dec_t *audec);
54static int wfd_register_audio_lib(aml_audio_dec_t *audec)
55{
56 int i;
57 int num;
58 audio_lib_t *f;
59 adec_print("wfd audec->format %d,audec->codec_id %x", audec->format, audec->codec_id);
60 num = ARRAY_SIZE(wfd_audio_lib_list);
61 audio_decoder_operations_t *adec_ops = audec->adec_ops;
62 for (i = 0; i < num; i++) {
63 f = &wfd_audio_lib_list[i];
64 if (f->codec_id == audec->format) {
65 dec_mLibHandle = dlopen(wfd_audio_lib_list[i].name, RTLD_NOW);
66 if (dec_mLibHandle) {
67 adec_ops->init = dlsym(dec_mLibHandle, "audio_dec_init");
68 adec_ops->decode = dlsym(dec_mLibHandle, "audio_dec_decode");
69 adec_ops->release = dlsym(dec_mLibHandle, "audio_dec_release");
70 adec_ops->getinfo = dlsym(dec_mLibHandle, "audio_dec_getinfo");
71 wfd_adec_exit = dlsym(dec_mLibHandle, "audio_set_exit_flag");
72 if (!adec_ops->init || !adec_ops->decode || !adec_ops->release || !adec_ops->getinfo || !wfd_adec_exit) {
73 adec_print("in %s,decode func not implemented %p %p %p %p \n", wfd_audio_lib_list[i].name, \
74 adec_ops->init, adec_ops->decode, adec_ops->release, adec_ops->getinfo);
75 goto error;
76 }
77 } else {
78 adec_print("wfd cant find decoder lib\n");
79 goto error;
80 }
81 return 0;
82 }
83 }
84error:
85 if (dec_mLibHandle) {
86 dlclose(dec_mLibHandle);
87 }
88 dec_mLibHandle = NULL;
89 return -1;
90}
91static int wfd_register_output_lib(aml_audio_dec_t *audec)
92{
93 out_mLibHandle = dlopen("libamadec_wfd_out.so", RTLD_NOW);
94 if (out_mLibHandle) {
95 wfd_out_init = dlsym(out_mLibHandle, "pcm_output_init");
96 wfd_out_write = dlsym(out_mLibHandle, "pcm_output_write");
97 wfd_out_uninit = dlsym(out_mLibHandle, "pcm_output_uninit");
98 wfd_out_latency = dlsym(out_mLibHandle, "pcm_output_latency");
99
100 if (!wfd_out_init || !wfd_out_write || !wfd_out_uninit || !wfd_out_latency) {
101 adec_print("wfd load output lib api failed\n");
102 goto error;
103 }
104 } else {
105 goto error;
106 }
107 return 0;
108error:
109 if (out_mLibHandle) {
110 dlclose(out_mLibHandle);
111 }
112 out_mLibHandle = NULL;
113 return -1;
114
115
116}
117static void wfd_unregister_lib()
118{
119 if (out_mLibHandle) {
120 dlclose(out_mLibHandle);
121 }
122 out_mLibHandle = NULL;
123 if (dec_mLibHandle) {
124 dlclose(dec_mLibHandle);
125 }
126 dec_mLibHandle = NULL;
127}
128extern int read_buffer(unsigned char *buffer, int size);
129
130
131static int wfd_dec_pcm_read(dsp_operations_t *dsp_ops, char *buffer, int len)
132{
133 return 0;
134}
135static unsigned long wfd_dec_get_pts(dsp_operations_t *dsp_ops)
136{
137 unsigned long val, offset;
138 unsigned long pts;
139 int data_width, channels, samplerate;
140 unsigned long long frame_nums ;
141 unsigned long delay_pts;
142 samplerate = 48000;
143 aml_audio_dec_t *audec = (aml_audio_dec_t *)dsp_ops->audec;
144 offset = audec->decode_offset;
145
146 if (dsp_ops->dsp_file_fd >= 0) {
147 ioctl(dsp_ops->dsp_file_fd, AMSTREAM_IOC_APTS_LOOKUP, &offset);
148 } else {
149 adec_print("====abuf have not open!\n", val);
150 }
151 pts = offset;
152 if (pts == 0) {
153 if (audec->last_valid_pts) {
154 pts = audec->last_valid_pts;
155 }
156 frame_nums = (audec->out_len_after_last_valid_pts * 8 / (16 * 2));
157 adec_print("decode_offset:%d out_pcm:%d pts:%d \n", audec->decode_offset, audec->out_len_after_last_valid_pts, pts);
158 pts += (frame_nums * 90000 / samplerate);
159 return pts;
160 }
161 audec->last_valid_pts = pts;
162 audec->out_len_after_last_valid_pts = 0;
163 return pts;
164}
165
166static unsigned long wfd_dec_get_pcrscr(dsp_operations_t *dsp_ops)
167{
168 unsigned long val;
169 if (dsp_ops->dsp_file_fd < 0) {
170 adec_print("read error!! audiodsp have not opened\n");
171 return -1;
172 }
173 ioctl(dsp_ops->dsp_file_fd, AMSTREAM_IOC_PCRSCR, &val);
174 return val;
175}
176unsigned long wfd_dec_set_pts(dsp_operations_t *dsp_ops, unsigned long apts)
177{
178 if (dsp_ops->dsp_file_fd < 0) {
179 adec_print("armdec_set_apts err!\n");
180 return -1;
181 }
182 ioctl(dsp_ops->dsp_file_fd, AMSTREAM_IOC_SET_APTS, &apts);
183 return 0;
184}
185static int wfd_dec_set_skip_bytes(dsp_operations_t* dsp_ops, unsigned int bytes)
186{
187 return 0;
188}
189static int set_sysfs_int(const char *path, int val)
190{
191 return amsysfs_set_sysfs_int(path, val);
192}
193
194
195static int wfd_audio_codec_release(aml_audio_dec_t *audec)
196{
197 if (wfd_adec_exit) {
198 wfd_adec_exit();
199 }
200 stop_wfd_decode_thread(audec);
201 if (wfd_out_uninit) {
202 wfd_out_uninit();
203 }
204 audec->adec_ops->release(audec->adec_ops);
205 wfd_unregister_lib();
206 adec_print("wfd audio_codec_release done\n");
207 return 0;
208}
209
210
211static int get_first_apts_flag(dsp_operations_t *dsp_ops)
212{
213 int val;
214 if (dsp_ops->dsp_file_fd < 0) {
215 adec_print("[%s %d]read error!! audiodsp have not opened\n", __FUNCTION__, __LINE__);
216 return -1;
217 }
218 ioctl(dsp_ops->dsp_file_fd, GET_FIRST_APTS_FLAG, &val);
219 return val;
220}
221
222
223/**
224 * \brief start audio dec when receive START command.
225 * \param audec pointer to audec
226 */
227static void start_adec(aml_audio_dec_t *audec)
228{
229 int ret;
230 audio_out_operations_t *aout_ops = &audec->aout_ops;
231 dsp_operations_t *dsp_ops = &audec->adsp_ops;
232 unsigned long vpts, apts;
233 int times = 0;
234 char buf[32];
235 apts = vpts = 0;
236 audec->no_first_apts = 0;
237
238 if (audec->state == INITTED) {
239 audec->state = ACTIVE;
240 //get info from the audiodsp == can get from amstreamer
241 while ((!get_first_apts_flag(dsp_ops)) && (!audec->need_stop) && (!audec->no_first_apts)) {
242 adec_print("wait first pts checkin complete !");
243 times++;
244 if (times >= 5) {
245 amsysfs_get_sysfs_str(TSYNC_VPTS, buf, sizeof(buf));// read vpts
246 if (sscanf(buf, "0x%lx", &vpts) < 1) {
247 adec_print("unable to get vpts from: %s", buf);
248 return;
249 }
250 // save vpts to apts
251 adec_print("## can't get first apts, save vpts to apts,vpts=%lx, \n", vpts);
252 sprintf(buf, "0x%lx", vpts);
253 amsysfs_set_sysfs_str(TSYNC_APTS, buf);
254 audec->no_first_apts = 1;
255 }
256 amthreadpool_thread_usleep(100000);
257 }
258
259 /*start the the pts scr,...*/
260 ret = adec_pts_start(audec);
261 if (audec->auto_mute) {
262 avsync_en(0);
263 adec_pts_pause();
264 while ((!audec->need_stop) && track_switch_pts(audec)) {
265 amthreadpool_thread_usleep(1000);
266 }
267 avsync_en(1);
268 adec_pts_resume();
269 audec->auto_mute = 0;
270 }
271#ifdef OUT_USE_AUDIOTRACK
272 aout_ops->start(audec);
273#endif
274 }
275}
276
277/**
278 * \brief pause audio dec when receive PAUSE command.
279 * \param audec pointer to audec
280 */
281static void pause_adec(aml_audio_dec_t *audec)
282{
283 audio_out_operations_t *aout_ops = &audec->aout_ops;
284 if (audec->state == ACTIVE) {
285 audec->state = PAUSED;
286 adec_pts_pause();
287#ifdef OUT_USE_AUDIOTRACK
288 aout_ops->pause(audec);
289#endif
290 }
291}
292
293/**
294 * \brief resume audio dec when receive RESUME command.
295 * \param audec pointer to audec
296 */
297static void resume_adec(aml_audio_dec_t *audec)
298{
299 audio_out_operations_t *aout_ops = &audec->aout_ops;
300 if (audec->state == PAUSED) {
301 audec->state = ACTIVE;
302#ifdef OUT_USE_AUDIOTRACK
303 aout_ops->resume(audec);
304#endif
305 adec_pts_resume();
306 }
307}
308
309/**
310 * \brief stop audio dec when receive STOP command.
311 * \param audec pointer to audec
312 */
313static void stop_adec(aml_audio_dec_t *audec)
314{
315 audio_out_operations_t *aout_ops = &audec->aout_ops;
316 adec_print("[%s %d]audec->state/%d\n", __FUNCTION__, __LINE__, audec->state);
317 if (audec->state > INITING) {
318 audec->state = STOPPED;
319#ifdef OUT_USE_AUDIOTRACK
320 aout_ops->mute(audec, 1); //mute output, some repeat sound in audioflinger after stop
321 aout_ops->stop(audec);
322#endif
323 wfd_audio_codec_release(audec);
324 }
325}
326
327/**
328 * \brief release audio dec when receive RELEASE command.
329 * \param audec pointer to audec
330 */
331static void release_adec(aml_audio_dec_t *audec)
332{
333 audec->state = TERMINATED;
334}
335
336/**
337 * \brief mute audio dec when receive MUTE command.
338 * \param audec pointer to audec
339 * \param en 1 = mute, 0 = unmute
340 */
341static void mute_adec(aml_audio_dec_t *audec, int en)
342{
343#ifdef OUT_USE_AUDIOTRACK
344 audio_out_operations_t *aout_ops = &audec->aout_ops;
345 if (aout_ops->mute) {
346 adec_print("%s the output !\n", (en ? "mute" : "unmute"));
347 aout_ops->mute(audec, en);
348 audec->muted = en;
349 }
350#endif
351}
352
353/**
354 * \brief set volume to audio dec when receive SET_VOL command.
355 * \param audec pointer to audec
356 * \param vol volume value
357 */
358static void adec_set_volume(aml_audio_dec_t *audec, float vol)
359{
360#ifdef OUT_USE_AUDIOTRACK
361 audio_out_operations_t *aout_ops = &audec->aout_ops;
362 if (aout_ops->set_volume) {
363 adec_print("set audio volume! vol = %f\n", vol);
364 aout_ops->set_volume(audec, vol);
365 }
366#endif
367}
368
369/**
370 * \brief set volume to audio dec when receive SET_LRVOL command.
371 * \param audec pointer to audec
372 * \param lvol left channel volume value
373 * \param rvol right channel volume value
374 */
375static void adec_set_lrvolume(aml_audio_dec_t *audec, float lvol, float rvol)
376{
377#ifdef OUT_USE_AUDIOTRACK
378 audio_out_operations_t *aout_ops = &audec->aout_ops;
379 if (aout_ops->set_lrvolume) {
380 adec_print("set audio volume! left vol = %f,right vol:%f\n", lvol, rvol);
381 aout_ops->set_lrvolume(audec, lvol, rvol);
382 }
383#endif
384}
385static void adec_flag_check(aml_audio_dec_t *audec)
386{
387 audio_out_operations_t *aout_ops = &audec->aout_ops;
388 if (audec->auto_mute && (audec->state > INITTED)) {
389 aout_ops->pause(audec);
390 amthreadpool_thread_usleep(10000);
391 while ((!audec->need_stop) && track_switch_pts(audec)) {
392 amthreadpool_thread_usleep(1000);
393 }
394#ifdef OUT_USE_AUDIOTRACK
395 aout_ops->resume(audec);
396#endif
397 audec->auto_mute = 0;
398 }
399}
400
401
402static void start_wfd_decode_thread(aml_audio_dec_t *audec)
403{
404 int ret = -1;
405 if (audec->state != INITTED) {
406 adec_print("decode not inited quit \n");
407 return;
408 }
409 pthread_t tid;
410 ret = amthreadpool_pthread_create(&tid, NULL, (void *)audio_wfd_decode_loop, (void *)audec);
411 if (ret != 0) {
412 adec_print("[%s]Create ffmpeg decode thread failed!\n", __FUNCTION__);
413 return;
414 }
415 audec->sn_threadid = tid;
416 pthread_setname_np(tid, "AmadecDecodeWFD");
417 adec_print("[%s]Create WFD audio decode thread success! tid = %d\n", __FUNCTION__, tid);
418}
419static void stop_wfd_decode_thread(aml_audio_dec_t *audec)
420{
421 adec_print("enter stop_wfd_decode_thread \n");
422 audec->exit_decode_thread = 1;
423 int ret = amthreadpool_pthread_join(audec->sn_threadid, NULL);
424 adec_print("[%s]wfd decode thread exit success\n", __FUNCTION__);
425 audec->exit_decode_thread = 0;
426 audec->sn_threadid = -1;
427
428}
429
430static int wfd_audio_codec_init(aml_audio_dec_t *audec)
431{
432 int ret = 0;
433 audec->exit_decode_thread = 0;
434 audec->fd_uio = -1;
435 audec->sn_threadid = -1;
436 audec->adsp_ops.dsp_on = 1;
437 //TODO : get the actual sample rate /channel num
438 audec->data_width = AV_SAMPLE_FMT_S16;
439 audec->channels = 2;
440 audec->samplerate = 48000;
441
442 audec->adsp_ops.dsp_read = wfd_dec_pcm_read;
443 audec->adsp_ops.get_cur_pts = wfd_dec_get_pts;
444 audec->adsp_ops.get_cur_pcrscr = wfd_dec_get_pcrscr;
445 audec->adsp_ops.set_cur_apts = wfd_dec_set_pts;
446 audec->adsp_ops.set_skip_bytes = wfd_dec_set_skip_bytes;
447 audec->adsp_ops.dsp_read_raw = NULL;
448 while (0 != set_sysfs_int(DECODE_ERR_PATH, DECODE_NONE_ERR)) {
449 adec_print("[%s %d]set codec fatal failed ! \n", __FUNCTION__, __LINE__);
450 amthreadpool_thread_usleep(100000);
451 }
452 /*
453 //enable uio interface
454 ret = uio_init(audec);
455 if (ret < 0) {
456 adec_print("wfd uio init error! \n");
457 return -1;
458 }
459 */
460 // register decoder lib
461 memset(&WFDAudioDecoder, 0, sizeof(audio_decoder_operations_t));
462 audec->adec_ops = &WFDAudioDecoder;
463 audec->adec_ops->priv_data = audec;
464 if (wfd_register_audio_lib(audec)) {
465 adec_print("wfd register decoder failed \n");
466 return -1;
467 }
468 if (wfd_register_output_lib(audec)) {
469 adec_print("wfd register output failed \n");
470 return -1;
471 }
472 // output init,not init here as we should get the sr/ch info when decode one frame
473#if 0
474 if (wfd_out_init()) {
475 adec_print("wfd init pcm output device failed\n");
476 return -1;
477 }
478#endif
479 ret = audec->adec_ops->init(audec->adec_ops);
480 if (ret) {
481 adec_print("wfd audio decoder init failed \n");
482 goto error1;
483 }
484
485
486 adec_print("wfd audio_codec_init ok \n");
487 return 0;
488error1:
489 wfd_out_uninit();
490 return -1;
491
492}
493#define RESAMPLE_FRAMES 128
494static short date_temp[1024 * 4 * 2];
495
496static void audio_resample_api(char* buffer, unsigned int *size, int Chnum, int enable, int delta)
497{
498 short *pbuf;
499 int resample_enable;
500 int resample_type;
501 int resample_delta;
502 int frame_read;
503 int num_sample = 0;
504 int i, j, k, h;
505 int request = *size;
506 int dsp_read = 0;
507 static int last_resample_enable = 0;
508 pbuf = (short*)date_temp;
509 unsigned index = 0;
510 float mPhaseFraction;
511 float phaseIncrement ;
512 float mPhaseFraction1;
513 unsigned in_sr;
514 unsigned out_sr;
515 short *input;
516 short *output;
517 unsigned frames = 0;
518 in_sr = (RESAMPLE_FRAMES - 1);
519 out_sr = (RESAMPLE_FRAMES - delta - 1);
520 phaseIncrement = (float)in_sr / out_sr;
521 resample_enable = enable;
522 resample_delta = delta;
523
524 if (last_resample_enable != resample_enable) {
525 adec_print("resample changed: %s\n", resample_enable ? "Enabled" : "Disabled");
526 last_resample_enable = resample_enable;
527 }
528
529 if (resample_enable && resample_delta && *size >= RESAMPLE_FRAMES * sizeof(short)*Chnum) {
530 //adec_print("resample start ... %d, step=%d\n", *size, resample_delta);
531 if (resample_delta < 0) {
532 // *size = *size*RESAMPLE_FRAMES/(RESAMPLE_FRAMES-resample_delta);
533 }
534 memcpy(pbuf, buffer, *size);
535 frame_read = *size / (sizeof(short) * Chnum); //dsp_pcm_read(audec, pbuf, *size); // return mono sample number
536 dsp_read += frame_read;
537 k = 0;
538 while (frame_read >= RESAMPLE_FRAMES) {
539 mPhaseFraction = 0;
540 mPhaseFraction1 = 0;
541 index = 0;
542 input = (short*)pbuf + frames * Chnum;
543 output = (short*)buffer + k * Chnum;
544 for (j = 0; j < RESAMPLE_FRAMES - resample_delta; j++) {
545 output[2 * j] = input[index * 2] + (short)((input[(index + 1) * 2] - input[index * 2]) * mPhaseFraction1);
546 output[2 * j + 1] = input[index * 2 + 1] + (short)((input[(index + 1) * 2 + 1] - input[index * 2 + 1]) * mPhaseFraction1);
547 mPhaseFraction += phaseIncrement;
548 index = mPhaseFraction;
549 mPhaseFraction1 = mPhaseFraction - index;
550 k++;
551 }
552 frames += RESAMPLE_FRAMES;
553 frame_read -= RESAMPLE_FRAMES;
554 }
555 if (frame_read > 0) {
556 memcpy((short*)buffer + k * Chnum, (short*)pbuf + frames * Chnum, frame_read * sizeof(short)* Chnum);
557 k += frame_read;
558 }
559
560
561 num_sample = k * sizeof(short) * Chnum;
562 *size = k * sizeof(short) * Chnum;
563 }
564 // adec_print("resample size from %d to %d, original %d\n", request, *size, dsp_read);
565}
566
567static int skip_thred = 400;
568static int up_thred = 100;
569static int dn_thred = 200;
570static int dn_resample_delta = 2;
571static int up_resample_delta = -4;
572static void set_wfd_pcm_thredhold()
573{
574
575 char value[PROPERTY_VALUE_MAX];
576 if (property_get("media.wfd.skip", value, NULL) > 0) {
577 skip_thred = atoi(value);
578 }
579 if (property_get("media.wfd.up", value, NULL) > 0) {
580 up_thred = atoi(value);
581 }
582 if (property_get("media.wfd.dn", value, NULL) > 0) {
583 dn_thred = atoi(value);
584 }
585 if (property_get("media.wfd.dn_delta", value, NULL) > 0) {
586 dn_resample_delta = atoi(value);
587 }
588 if (property_get("media.wfd.up_delta", value, NULL) > 0) {
589 up_resample_delta = atoi(value);
590 }
591}
592void *audio_wfd_decode_loop(void *args)
593{
594 int ret;
595 aml_audio_dec_t *audec;
596 audio_out_operations_t *aout_ops;
597 audio_decoder_operations_t *adec_ops;
598 short outbuf[2048];
599 int outlen = 0;
600 int write_size = 0;
601 int in_latency = 0;
602 int out_latency = 0;
603 int total_latency = 0;
604 int out_init_flag = 0;
605 char value[PROPERTY_VALUE_MAX];
606 unsigned char debug_latency = 0;
607 adec_print("audio_wfd_decode_loop start!\n");
608 audec = (aml_audio_dec_t *)args;
609 aout_ops = &audec->aout_ops;
610 adec_ops = audec->adec_ops;
611 if (property_get("media.wfd.debug_latency", value, NULL) > 0) {
612 debug_latency = atoi(value);
613 }
614 while (!audec->exit_decode_thread) {
615 outlen = 0;
616 // adec_refresh_pts(audec);
617 set_wfd_pcm_thredhold();
618 audec->decode_offset = adec_ops->decode(adec_ops, outbuf, &outlen, (char*)&in_latency, 0);
619
620 if (outlen > 0) {
621 if (!out_init_flag) {
622 if (wfd_out_init(adec_ops->samplerate, adec_ops->channels)) {
623 adec_print("wfd init pcm output device failed\n");
624 continue;
625 }
626 out_init_flag = 1;
627 }
628 out_latency = wfd_out_latency();
629 if (out_latency < 0) {
630 out_latency = 0;
631 }
632 total_latency = in_latency + out_latency;
633 audec->out_len_after_last_valid_pts += outlen;
634 if (debug_latency) {
635 adec_print("latency in %d ms,out %d ms.total %d ms\n", in_latency, out_latency, total_latency);
636 if (total_latency < 150) {
637 if (property_get("sys.pkginfo", value, NULL) > 0) {
638 adec_print("latency pkg info %s \n", value);
639 }
640 }
641 }
642 if (total_latency > skip_thred) {
643 if (debug_latency) {
644 adec_print(" total latency %d ms ,skip bytes %d \n", total_latency, outlen);
645 }
646 outlen = 0;
647 } else if (total_latency > dn_thred) {
648 audio_resample_api(outbuf, &outlen, 2, 1, dn_resample_delta);
649 } else if (total_latency < up_thred) {
650 audio_resample_api(outbuf, &outlen, 2, 1, up_resample_delta);
651 }
652 if (debug_latency) {
653 adec_print("wfd dec out %d byts pcm \n", outlen);
654 }
655 write_size = wfd_out_write(outbuf, outlen);
656 }
657 //TODO decode function
658 }
659 adec_print("exit audio_wfd_decode_loop Thread finished!\n");
660 pthread_exit(NULL);
661error:
662 pthread_exit(NULL);
663 return NULL;
664}
665
666
667/*
668 WFD audio decoder control thread
669*/
670void *adec_wfddec_msg_loop(void *args)
671{
672 int ret;
673 aml_audio_dec_t *audec;
674 audio_out_operations_t *aout_ops;
675 adec_cmd_t *msg = NULL;
676 audec = (aml_audio_dec_t *)args;
677 aout_ops = &audec->aout_ops;
678 adec_print("adec_wfddec_loop in \n");
679 while (!audec->need_stop) {
680 audec->state = INITING;
681 ret = wfd_audio_codec_init(audec);
682 if (ret == 0) {
683 {
684#ifdef OUT_USE_AUDIOTRACK
685 ret = aout_ops->init(audec);
686 if (ret) {
687 adec_print("WFD Audio out device init failed!\n");
688 wfd_audio_codec_release(audec);
689 continue;
690 }
691#endif
692 audec->state = INITTED;
693 start_wfd_decode_thread(audec);
694 start_adec(audec);
695 }
696 break;
697 }
698
699 if (!audec->need_stop) {
700 amthreadpool_thread_usleep(100000);
701 }
702 }
703
704 do {
705
706 adec_reset_track(audec);
707 adec_flag_check(audec);
708 msg = adec_get_message(audec);
709 if (!msg) {
710 amthreadpool_thread_usleep(100000);
711 continue;
712 }
713
714 switch (msg->ctrl_cmd) {
715 case CMD_START:
716
717 adec_print("Receive START Command!\n");
718 start_wfd_decode_thread(audec);
719 start_adec(audec);
720 break;
721
722 case CMD_PAUSE:
723
724 adec_print("Receive PAUSE Command!");
725 pause_adec(audec);
726 break;
727
728 case CMD_RESUME:
729
730 adec_print("Receive RESUME Command!");
731 resume_adec(audec);
732 break;
733
734 case CMD_STOP:
735
736 adec_print("Receive STOP Command!");
737 stop_adec(audec);
738 break;
739
740 case CMD_MUTE:
741
742 adec_print("Receive Mute Command!");
743 if (msg->has_arg) {
744 mute_adec(audec, msg->value.en);
745 }
746 break;
747
748 case CMD_SET_VOL:
749
750 adec_print("Receive Set Vol Command!");
751 if (msg->has_arg) {
752 adec_set_volume(audec, msg->value.volume);
753 }
754 break;
755 case CMD_SET_LRVOL:
756
757 adec_print("Receive Set LRVol Command!");
758 if (msg->has_arg) {
759 adec_set_lrvolume(audec, msg->value.volume, msg->value_ext.volume);
760 }
761 break;
762#if 0
763 case CMD_CHANL_SWAP:
764
765 adec_print("Receive Channels Swap Command!");
766 audio_hardware_ctrl(HW_CHANNELS_SWAP);
767 break;
768
769 case CMD_LEFT_MONO:
770
771 adec_print("Receive Left Mono Command!");
772 audio_hardware_ctrl(HW_LEFT_CHANNEL_MONO);
773 break;
774
775 case CMD_RIGHT_MONO:
776
777 adec_print("Receive Right Mono Command!");
778 audio_hardware_ctrl(HW_RIGHT_CHANNEL_MONO);
779 break;
780
781 case CMD_STEREO:
782
783 adec_print("Receive Stereo Command!");
784 audio_hardware_ctrl(HW_STEREO_MODE);
785 break;
786#endif
787 case CMD_RELEASE:
788
789 adec_print("Receive RELEASE Command!");
790 release_adec(audec);
791 break;
792
793 default:
794 adec_print("Unknow Command!");
795 break;
796
797 }
798
799 if (msg) {
800 adec_message_free(msg);
801 msg = NULL;
802 }
803 } while (audec->state != TERMINATED);
804
805 adec_print("Exit adec_wfddec_msg_loop!");
806 pthread_exit(NULL);
807 return NULL;
808}
809
810
811
812