summaryrefslogtreecommitdiff
path: root/amadec/audio_out/android-out.cpp (plain)
blob: 222727d0d8ebc1b884eb620544479dfd0733056b
1/**
2 * \file android-out.cpp
3 * \brief Functions of Auduo output control for Android Platform
4 * \version 1.0.0
5 * \date 2011-03-08
6 */
7/* Copyright (C) 2007-2011, Amlogic Inc.
8 * All right reserved
9 *
10 */
11#include <utils/RefBase.h>
12#include <utils/KeyedVector.h>
13#include <utils/threads.h>
14#include <media/AudioSystem.h>
15#include <media/AudioTrack.h>
16#include <binder/IPCThreadState.h>
17#include <binder/ProcessState.h>
18#include <media/AudioParameter.h>
19#include <system/audio_policy.h>
20#include <cutils/properties.h>
21
22extern "C" {
23#include <audio-dec.h>
24#include <adec-pts-mgt.h>
25#include <log-print.h>
26#include "aml_resample.h"
27#include <audiodsp_update_format.h>
28#include <Amsysfsutils.h>
29#include <amthreadpool.h>
30}
31#include "adec-external-ctrl.h"
32namespace android
33{
34
35#if ANDROID_PLATFORM_SDK_VERSION >= 21
36//android 5.0 level= 20
37#define AUDIO_FORMAT_EAC3 AUDIO_FORMAT_E_AC3
38#endif
39#if ANDROID_PLATFORM_SDK_VERSION >= 23
40#define AUDIO_FORMAT_DTS_MASTER 0x0E000000UL
41#endif
42#define DOLBY_SYSTEM_CHANNEL "ds1.audio.multichannel.support"
43static Mutex mLock;
44static Mutex mLock_raw;
45//get default output sample rate which maybe changed by raw output
46static int default_sr = 48000;
47static int fill_audiotrack_zero = 0;
48static int buffering_audio_data = 0;
49static int skip_unnormal_discontinue = 0;
50static int unnormal_discontinue = 0;
51static int unnormal_discontinue1 = 0;
52extern "C" int get_audio_decoder(void);
53static int get_digitalraw_mode(void)
54{
55 return amsysfs_get_sysfs_int("/sys/class/audiodsp/digital_raw");
56}
57#define DTSETC_DECODE_VERSION_CORE 350
58#define DTSETC_DECODE_VERSION_M6_M8 380
59#define DTSHD_IEC958_PKTTYPE_CORE 0 //common feature for DTSETC_DECODE_VERSION 350/380,so set it to 0 by default
60#define DTSHD_IEC958_PKTTYPE_SINGLEI2S 1
61#define DTSHD_IEC958_PKTTYPE_FOURI2S 2
62
63void restore_system_samplerate(struct aml_audio_dec* audec)
64{
65#if defined(ANDROID_VERSION_JBMR2_UP)
66 unsigned int sr = 0;
67#else
68 int sr = 0;
69#endif
70 if( audec->format == ACODEC_FMT_TRUEHD ||
71 (audec->format==ACODEC_FMT_DTS && audec->VersionNum==DTSETC_DECODE_VERSION_M6_M8 && audec->DTSHDIEC958_FS>192000 && amsysfs_get_sysfs_int("/sys/class/audiodsp/digital_raw")==2))
72 {
73 ;//do nothing
74 }else if(audec->samplerate == 48000 || (audec->format != ACODEC_FMT_DTS && \
75 audec->format != ACODEC_FMT_AC3 && audec->format != ACODEC_FMT_EAC3 &&
76 audec->format != ACODEC_FMT_TRUEHD))
77 return ;
78 audio_io_handle_t handle = -1;
79//for mx, raw/pcm use the same audio hal
80#ifndef USE_ARM_AUDIO_DEC
81 handle = AudioSystem::getOutput(AUDIO_STREAM_MUSIC,
82 48000,
83 AUDIO_FORMAT_PCM_16_BIT,
84 AUDIO_CHANNEL_OUT_STEREO,
85#if defined(_VERSION_ICS)
86 AUDIO_POLICY_OUTPUT_FLAG_INDIRECT
87#else //JB...
88 AUDIO_OUTPUT_FLAG_PRIMARY
89#endif
90 );
91 if(handle > 0){
92 char str[64];
93 memset(str,0,sizeof(str));
94 sprintf(str,"sampling_rate=%d",default_sr);
95 AudioSystem::setParameters(handle, String8(str));
96 }
97#else
98//for M8, raw/pcm output use different HAL, so only check the raw output device
99 handle = AudioSystem::getOutput(AUDIO_STREAM_MUSIC,
100 48000,
101 AUDIO_FORMAT_AC3, //use AC3 as the format tag for all raw output
102 AUDIO_CHANNEL_OUT_STEREO,
103#if defined(_VERSION_ICS)
104 AUDIO_POLICY_OUTPUT_FLAG_INDIRECT
105#else //JB...
106 AUDIO_OUTPUT_FLAG_DIRECT
107#endif
108 );
109
110 if(handle > 0){
111 char str[64];
112 memset(str,0,sizeof(str));
113 sprintf(str,"sampling_rate=%d",default_sr);
114 AudioSystem::setParameters(handle, String8(str));
115#if ANDROID_PLATFORM_SDK_VERSION >= 22
116 AudioSystem::releaseOutput(handle, AUDIO_STREAM_DEFAULT, AUDIO_SESSION_OUTPUT_STAGE);
117#else
118 AudioSystem::releaseOutput(handle);
119#endif
120 }else{
121 adec_print("WARNIN: handle/%d resetore sysFs failed!\n",handle);
122 }
123#endif
124}
125
126#if defined(ANDROID_VERSION_JBMR2_UP)
127static size_t old_frame_count = 0;
128#else
129static int old_frame_count = 0;
130#endif
131
132void restore_system_framesize()
133{
134 if(old_frame_count == 0){
135 adec_print("frame size can't be zero !\n");
136 return;
137 }
138 adec_print("restore system frame size\n");
139 int sr = 0;
140 audio_io_handle_t handle = -1;
141 handle = AudioSystem::getOutput(AUDIO_STREAM_MUSIC,
142 48000,
143 AUDIO_FORMAT_PCM_16_BIT,
144 AUDIO_CHANNEL_OUT_STEREO,
145#if defined(_VERSION_ICS)
146 AUDIO_POLICY_OUTPUT_FLAG_INDIRECT
147#else //JB...
148 AUDIO_OUTPUT_FLAG_PRIMARY
149#endif
150 );
151 if(handle > 0){
152 char str[64];
153 int ret;
154 memset(str,0,sizeof(str));
155#if defined(ANDROID_VERSION_JBMR2_UP)
156 sprintf(str,"frame_count=%zd",old_frame_count);
157 ret = AudioSystem::setParameters(handle, String8(str));
158 adec_print("restore frame success: %zd\n", old_frame_count);
159#else
160 sprintf(str,"frame_count=%zd",old_frame_count);
161 ret = AudioSystem::setParameters(handle, String8(str));
162 adec_print("restore frame success: %zd\n", old_frame_count);
163#endif
164 }
165}
166
167void reset_system_samplerate(struct aml_audio_dec* audec)
168{
169 unsigned digital_raw = 0;
170 audio_io_handle_t handle = -1;
171 int dtsFS_88_96_Directout=0;
172 digital_raw = get_digitalraw_mode();
173 if(audec->format == ACODEC_FMT_DTS && audec->samplerate>48000 && !digital_raw)
174 {
175 char tmp[128]={0};
176 if(property_get("media.libplayer.88_96K", tmp, "0") > 0 && !strcmp(tmp, "1"))
177 dtsFS_88_96_Directout=1;
178 }
179 if(!audec || (!digital_raw && audec->channels!=8 && !dtsFS_88_96_Directout))
180 return;
181 /*
182 1)32k,44k dts
183 2) 32k,44k ac3
184 3)44.1k eac3 when hdmi passthrough
185 4)32k,44k eac3 when spdif pasthrough
186 */
187 adec_print("[%s %d]format %d,audec->samplerate%d DTSHDIEC958_FS/%d\n",__FUNCTION__,__LINE__,audec->format ,audec->samplerate,audec->DTSHDIEC958_FS );
188 int Samplerate=audec->samplerate;
189 int dts_raw_reset_sysFS=0;
190 if( (audec->format == ACODEC_FMT_DTS && digital_raw==1)
191 ||(audec->format == ACODEC_FMT_DTS && digital_raw==2 && audec->VersionNum!=DTSETC_DECODE_VERSION_M6_M8)
192 ||(audec->format == ACODEC_FMT_DTS && digital_raw==2 && audec->VersionNum==DTSETC_DECODE_VERSION_M6_M8 && audec->DTSHDIEC958_PktType==DTSHD_IEC958_PKTTYPE_CORE)
193 )
194 { //DTS raw_stream Directoutput
195 if(audec->samplerate%48000!=0)
196 dts_raw_reset_sysFS=1;
197 if(audec->samplerate==32000 || audec->samplerate==44100)
198 Samplerate=audec->samplerate;
199 else if(audec->samplerate==88200 || audec->samplerate==96000)
200 Samplerate=audec->samplerate/2;
201 else if(audec->samplerate==176400 || audec->samplerate==192000)
202 Samplerate=audec->samplerate/4;
203 else{
204 adec_print("[%s %d] Unvalid samplerate/%d for DTSCore Rawoutput\n",__FUNCTION__,__LINE__,audec->samplerate);
205 return;
206 }
207 }else if(audec->format == ACODEC_FMT_DTS && digital_raw==2 && audec->VersionNum==DTSETC_DECODE_VERSION_M6_M8 && audec->DTSHDIEC958_PktType==DTSHD_IEC958_PKTTYPE_SINGLEI2S){
208 //DTSHD SingleI2s raw_stream Directoutput
209 if(audec->DTSHDIEC958_FS==48000||audec->DTSHDIEC958_FS==44100)
210 {
211 Samplerate=audec->DTSHDIEC958_FS;
212 }else if(audec->DTSHDIEC958_FS==192000||audec->DTSHDIEC958_FS==1764000){
213 Samplerate =audec->DTSHDIEC958_FS/4;
214 }else{
215 adec_print("[%s %d] Unvalid DTSHDIEC958_FS/%d for DTSHD RawOutput\n",__FUNCTION__,__LINE__,audec->DTSHDIEC958_FS);
216 return;
217 }
218 if(Samplerate%48000!=0)
219 dts_raw_reset_sysFS=1;
220 }else if(audec->format==ACODEC_FMT_DTS && digital_raw==2&& audec->VersionNum==DTSETC_DECODE_VERSION_M6_M8&& audec->DTSHDIEC958_PktType==DTSHD_IEC958_PKTTYPE_FOURI2S){
221 //DTSLL FourI2s raw_stream Directoutput
222 if(audec->DTSHDIEC958_FS==192000||audec->DTSHDIEC958_FS==384000 || audec->DTSHDIEC958_FS==768000 ||
223 audec->DTSHDIEC958_FS==176400||audec->DTSHDIEC958_FS==352800 || audec->DTSHDIEC958_FS==705600)
224 {
225 Samplerate=audec->DTSHDIEC958_FS/4;
226 }else{
227 adec_print("[%s %d] Unvalid DTSHDIEC958_FS/%d for DTSLL RawOutput\n",__FUNCTION__,__LINE__,audec->DTSHDIEC958_FS);
228 return;
229 }
230 if(Samplerate!=48000)
231 dts_raw_reset_sysFS=1;
232 }else if(audec->format == ACODEC_FMT_DTS&& (audec->samplerate>48000|| (audec->channels==8&&audec->samplerate!=48000))){
233 //DTS HD_PCM(FS>48000) Directoutput/8ch DTS_PCM output
234 dts_raw_reset_sysFS=1;
235 Samplerate=audec->samplerate;
236 }else if(audec->format == ACODEC_FMT_TRUEHD && (digital_raw == 1 || digital_raw == 2)){
237 //Dobly TrueHD RawOutput
238 Samplerate = 192000;
239 }
240 if( (audec->format == ACODEC_FMT_AC3 && (audec->samplerate == 32000 || audec->samplerate == 44100))
241 ||(audec->format == ACODEC_FMT_EAC3 && digital_raw == 2 && audec->samplerate == 44100)
242 ||(audec->format == ACODEC_FMT_EAC3 && digital_raw == 1 && (audec->samplerate == 32000 || audec->samplerate == 44100))
243 || dts_raw_reset_sysFS
244 ||(audec->format == ACODEC_FMT_TRUEHD && (digital_raw == 1 || digital_raw == 2)/* &&
245 (audec->samplerate == 192000 || audec->samplerate == 96000)*/))
246
247 {
248 adec_print("[%s %d]Change AudioSysFS to/%d\n",__FUNCTION__,__LINE__,Samplerate);
249 int sr = 0;
250 if(/*sr*/48000 != Samplerate){
251#ifndef USE_ARM_AUDIO_DEC
252 handle = AudioSystem::getOutput(AUDIO_STREAM_MUSIC,
253 48000,
254 AUDIO_FORMAT_PCM_16_BIT,
255 AUDIO_CHANNEL_OUT_STEREO,
256#if defined(_VERSION_ICS)
257 AUDIO_POLICY_OUTPUT_FLAG_INDIRECT
258#else //JB...
259 AUDIO_OUTPUT_FLAG_PRIMARY
260#endif
261 );
262 if(handle > 0){
263 char str[64];
264 memset(str,0,sizeof(str));
265 sprintf(str,"sampling_rate=%d",audec->samplerate);
266 AudioSystem::setParameters(handle, String8(str));
267 }
268#else
269 //for M8, raw/pcm output use different HAL, so only check the raw output device
270 handle = AudioSystem::getOutput(AUDIO_STREAM_MUSIC,
271 48000,
272 AUDIO_FORMAT_AC3, //use AC3 as the format tag for all raw output
273 AUDIO_CHANNEL_OUT_STEREO,
274#if defined(_VERSION_ICS)
275 AUDIO_POLICY_OUTPUT_FLAG_INDIRECT
276#else //JB...
277 AUDIO_OUTPUT_FLAG_DIRECT
278#endif
279 );
280
281 if(handle > 0){
282 char str[64];
283 memset(str,0,sizeof(str));
284 sprintf(str,"sampling_rate=%d",Samplerate);
285 AudioSystem::setParameters(handle, String8(str));
286#if ANDROID_PLATFORM_SDK_VERSION >= 22
287 AudioSystem::releaseOutput(handle, AUDIO_STREAM_DEFAULT, AUDIO_SESSION_OUTPUT_STAGE);
288#else
289 AudioSystem::releaseOutput(handle);
290#endif
291 }else{
292 adec_print("WARNIN:handle/%d reset sysFs failed!\n",handle);
293 }
294#endif
295
296 }
297
298
299 }
300}
301
302/**
303 * \brief callback function invoked by android
304 * \param event type of event notified
305 * \param user pointer to context for use by the callback receiver
306 * \param info pointer to optional parameter according to event type
307 */
308
309#define AMSTREAM_IOC_MAGIC 'S'
310#define AMSTREAM_IOC_GET_LAST_CHECKIN_APTS _IOR(AMSTREAM_IOC_MAGIC, 0xa9, unsigned long)
311#define AMSTREAM_IOC_GET_LAST_CHECKIN_VPTS _IOR(AMSTREAM_IOC_MAGIC, 0xaa, unsigned long)
312#define AMSTREAM_IOC_GET_LAST_CHECKOUT_APTS _IOR(AMSTREAM_IOC_MAGIC, 0xab, unsigned long)
313#define AMSTREAM_IOC_GET_LAST_CHECKOUT_VPTS _IOR(AMSTREAM_IOC_MAGIC, 0xac, unsigned long)
314#define AMSTREAM_IOC_AB_STATUS _IOR(AMSTREAM_IOC_MAGIC, 0x09, int)
315
316static unsigned long long ttt = 0;
317
318static int resample = 0, last_resample = 0, resample_step = 0, last_step=0;
319static int xxx;
320static int diff_record[0x40], diff_wp = 0;
321static int wfd_enable = 0, bytes_skipped = 0x7fffffff;
322static int wfd_ds_thrdhold = 250; //audio pts delay threadhold for down sampling
323static int wfd_us_thrdhold = 150;//audio pts delay threadhold for up sampling
324
325#if ANDROID_PLATFORM_SDK_VERSION >= 19
326static sp<AudioTrack> mpAudioTrack;
327static sp<AudioTrack> mpAudioTrack_raw;
328#endif
329
330struct buf_status {
331 int size;
332 int data_len;
333 int free_len;
334 unsigned int read_pointer;
335 unsigned int write_pointer;
336};
337
338struct am_io_param {
339 int data;
340 int len; //buffer size;
341 struct buf_status status;
342};
343
344static int mix_lr_channel_enable=0;
345static int pre_gain_enable=0;
346static void momo2_mode_mix(short*buf, int nsamps, int channels)
347{
348 int i;
349 int step=4;//assume deffault pcm format: bitwidth/2bytes channels/2
350 short tmpL,tmpR;
351 int tmpSum;
352 short *p16tmp=(short*)buf;
353 if(channels!=2)
354 return;
355 for(i=0;i<nsamps;i+=2)
356 {
357 tmpSum=(p16tmp[i]*3/4)+(p16tmp[i+1]*3/4);
358 tmpSum=tmpSum>32767 ?32767 : tmpSum;
359 tmpSum=tmpSum<-32768?-32768: tmpSum;
360 p16tmp[i]=(tmpSum&0x0000ffff);
361 p16tmp[i+1]=(tmpSum&0x0000ffff);
362 }
363}
364
365static void apply_audio_pregain(void *buf, int size, float gain) {
366 int i;
367 short *sample = (short*)buf;
368 for (i = 0; i < size/sizeof(short); i++)
369 sample[i] = gain*sample[i];
370}
371
372#define RESAMPLE_THRESHOLD (30 * TIME_UNIT90K / 1000)
373void audioCallback(int event, void* user, void *info)
374{
375 int len, i;
376 unsigned last_checkin, last_checkout;
377 unsigned diff, diff_avr;
378 AudioTrack::Buffer *buffer = static_cast<AudioTrack::Buffer *>(info);
379 aml_audio_dec_t *audec = static_cast<aml_audio_dec_t *>(user);
380 audio_out_operations_t *out_ops = &audec->aout_ops;
381 dsp_operations_t *dsp_ops = &audec->adsp_ops;
382 unsigned long apts, pcrscr;
383 struct am_io_param am_io;
384
385 if (event != AudioTrack::EVENT_MORE_DATA) {
386 //adec_refresh_pts(audec);
387 adec_print(" ****************** audioCallback: event = %d g_bst->buf_level/%d g_bst_raw->buf_level/%d [-1:mean unknown] \n", event,audec->g_bst==NULL?-1:audec->g_bst->buf_level,audec->g_bst_raw==NULL?-1:audec->g_bst_raw->buf_level);
388 return;
389 }
390
391 if (buffer == NULL || buffer->size == 0) {
392 adec_print("audioCallback: Wrong buffer\n");
393 return;
394 }
395
396 if(wfd_enable){
397 ioctl(audec->adsp_ops.amstream_fd, AMSTREAM_IOC_GET_LAST_CHECKIN_APTS, &last_checkin);
398 last_checkout = dsp_ops->get_cur_pts(dsp_ops);
399 if(last_checkin < last_checkout){
400 diff = 0;
401 }else{
402 diff = (last_checkin-last_checkout)/90;
403 }
404
405 //ioctl(audec->adsp_ops.amstream_fd, AMSTREAM_IOC_GET_LAST_CHECKOUT_APTS, (int)&last_checkout);
406 }
407 if(wfd_enable){
408 // filtering
409 diff_record[diff_wp++] = diff;
410 diff_wp = diff_wp & 0x3f;
411
412 diff_avr = 0;
413 for (i=0;i<0x40;i++) diff_avr+=diff_record[i];
414 diff_avr = diff_avr / 0x40;
415
416 // if ((xxx++ % 30) == 0)
417 // adec_print("audioCallback start: request %d, in: %d, out: %d, diff: %d, filtered: %d",buffer->size, last_checkin/90, last_checkout/90, diff, diff_avr);
418 if(bytes_skipped == 0 && diff < 200){
419 if(dsp_ops->set_skip_bytes)
420 dsp_ops->set_skip_bytes(&audec->adsp_ops, 0x7fffffff);
421 bytes_skipped = 0x7fffffff;
422 }
423
424 if(diff >1000){ // too much data in audiobuffer,should be skipped
425 if(dsp_ops->set_skip_bytes)
426 dsp_ops->set_skip_bytes(&audec->adsp_ops, 0);
427 bytes_skipped = 0;
428 adec_print("skip more data: last_checkin[%d]-last_checkout[%d]=%d, diff=%d\n", last_checkin/90, last_checkout/90, (last_checkin-last_checkout)/90, diff);
429 }
430
431 if (diff_avr > /*220*/wfd_ds_thrdhold) {
432 resample = 1; resample_step = 2;
433 } else if (diff_avr</*180*/wfd_us_thrdhold) {
434 // once we see a single shot of low boundry we finish down-sampling
435 resample = 1; resample_step = -2;
436 }else if(resample && (diff_avr < 200)){
437 resample = 0;
438 }
439
440 if (last_resample != resample || last_step != resample_step) {
441 last_resample = resample;
442 last_step = resample_step;
443 adec_print("resample changed to %d, step=%d, diff = %d", resample, resample_step,diff_avr);
444 }
445 }
446#if 1
447 if (audec->tsync_mode == TSYNC_MODE_PCRMASTER && audec->pcrtsync_enable) {
448 if (audec->adis_flag <= 0) {
449 unsigned long apts, pcrscr;
450 int64_t apts64, pcrscr64;
451
452 apts64 = audec->apts64;
453 pcrscr64 = audec->pcrscr64;
454
455 if (apts64 && pcrscr64 && (abs(apts64 - pcrscr64) <= 90000*60*10)) {
456 ioctl(audec->adsp_ops.amstream_fd, AMSTREAM_IOC_AB_STATUS, (unsigned long)&am_io);
457 //adec_print("ab_level=%x, ab_rd_ptr=%x", am_io.status.data_len, am_io.status.read_pointer);
458
459 if (abs(apts64 - pcrscr64) >= 90000*30 && unnormal_discontinue < 400) { // avoid replay apts would be pause
460 unnormal_discontinue++;
461 skip_unnormal_discontinue = 0;
462 unnormal_discontinue1 = 0;
463 } else if (abs(apts64 - pcrscr64) < 90000*30 && abs(apts64 - pcrscr64) >= 90000*3 && unnormal_discontinue1 < 200) {
464 unnormal_discontinue1 ++;
465 unnormal_discontinue = 0;
466 skip_unnormal_discontinue = 0;
467 }
468 //if (((apts64 - pcrscr64) > (int64_t)(audec->fill_trackzero_thrsh)) ||((apts64 > pcrscr64) && (am_io.status.data_len < 0x200))) {
469 if ((apts64 - pcrscr64) > (int64_t)(audec->fill_trackzero_thrsh)) {
470 adec_print("[%s:%d] %d, thrsh:%d, apts64:%lld, pcrscr64:%lld, diff:%lld, lastapts:%lx, pcmsize:%d, abuffer_lv:0x%x\n",
471 __FUNCTION__, __LINE__, fill_audiotrack_zero, audec->fill_trackzero_thrsh,apts64, pcrscr64, apts64-pcrscr64,audec->adsp_ops.last_audio_pts,buffer->size, am_io.status.data_len);
472 if (skip_unnormal_discontinue++ > 10) {
473 memset((char*)(buffer->i16), 0, buffer->size);
474 if (!fill_audiotrack_zero) {
475 adec_pts_pause();
476 }
477 fill_audiotrack_zero = audec->fill_trackzero_thrsh/(20*90);
478 adec_print("[%s:%d] %d, thrsh:%d, apts64:%lld, pcrscr64:%lld, diff:%lld, lastapts:%lx, pcmsize:%d, abuffer_lv:0x%x\n",
479 __FUNCTION__, __LINE__, fill_audiotrack_zero, audec->fill_trackzero_thrsh,apts64, pcrscr64, apts64-pcrscr64,audec->adsp_ops.last_audio_pts,buffer->size, am_io.status.data_len);
480 return;
481 }
482 } else {
483 if (skip_unnormal_discontinue>0) {
484 adec_print("[%s:%d], skip_unnormal_discontinue:%d, fill_audiotrack_zero:%d, apts-pcr:%lld, ---------------------------\n",__FUNCTION__, __LINE__, skip_unnormal_discontinue,fill_audiotrack_zero,apts64 - pcrscr64);
485 skip_unnormal_discontinue = 0;
486 }
487 unnormal_discontinue = 0;
488 unnormal_discontinue1 = 0;
489 }
490 if ((fill_audiotrack_zero > 0) && ((apts64 - pcrscr64) > (int64_t)(70*TIME_UNIT90K/1000))) {
491 fill_audiotrack_zero--;
492
493 if (!fill_audiotrack_zero) {
494 adec_pts_resume();
495 skip_unnormal_discontinue = 0;
496 unnormal_discontinue = 0;
497 unnormal_discontinue1 = 0;
498 }
499
500 memset((char*)(buffer->i16), 0, buffer->size);
501 adec_print("## %d, %d, apts bigger than pcr, 2222 apts64:%lld, pcrscr64:%lld, diff:%lld, \n", fill_audiotrack_zero, buffering_audio_data, apts64, pcrscr64, apts64-pcrscr64);
502 return;
503 } else {
504 if (fill_audiotrack_zero > 0 && ((apts64 - pcrscr64) <= (int64_t)(70*TIME_UNIT90K/1000))
505 && ((apts64 - pcrscr64) > 0)) {
506 fill_audiotrack_zero = 0;
507 adec_pts_resume();
508 skip_unnormal_discontinue = 0;
509 unnormal_discontinue = 0;
510 unnormal_discontinue1 = 0;
511 adec_print("[%s:%d], fill enough! ---------------------------\n",__FUNCTION__, __LINE__);
512 }
513 }
514
515 if (audec->apts64 - audec->last_apts64 > RESAMPLE_THRESHOLD) {
516 int64_t diff_discontinue = abs(pcrscr64 - apts64);
517 if (diff_discontinue > (int64_t)(TIME_UNIT90K * 3)) {
518 adec_print("discontinue: #pcrmaster: %lld, %lld, %lld, %d,%d,--------\n", apts64, pcrscr64,
519 apts64 - pcrscr64, RESAMPLE_THRESHOLD, ((pcrscr64 - apts64) > (int64_t)(100 * TIME_UNIT90K / 1000)));
520 af_set_resample_type(RESAMPLE_TYPE_NONE);
521 } else if ((pcrscr64 - apts64) > (int64_t)RESAMPLE_THRESHOLD) {
522 af_set_resample_type(RESAMPLE_TYPE_DOWN);
523 adec_print("down: #pcrmaster enable:%d, %lld, %lld, %lld, --------\n", af_get_resample_enable_flag(),apts64,pcrscr64,pcrscr64-apts64);
524 } else if ((apts64 - pcrscr64) > (int64_t)RESAMPLE_THRESHOLD) {
525 af_set_resample_type(RESAMPLE_TYPE_UP);
526 adec_print("up: #pcrmaster enable:%d, %lld, %lld, %lld, --------\n", af_get_resample_enable_flag(), apts64,pcrscr64,apts64-pcrscr64);
527 } else {
528 adec_print("none: #pcrmaster: %lld, %lld, %lld, %d,%d,--------\n",
529 apts64,pcrscr64,apts64-pcrscr64,RESAMPLE_THRESHOLD,((pcrscr64 - apts64) > (int64_t)(100*TIME_UNIT90K/1000)));
530 af_set_resample_type(RESAMPLE_TYPE_NONE);
531 }
532 audec->last_apts64 = apts64;
533 }
534 }
535 } else {
536 audec->adis_flag--;
537 adec_print("[%s:%d], pcr:%llx, apts:%llx, tsync_pcr_dispoint:%llx, adis_flag:%d,-------------\n",__FUNCTION__, __LINE__,
538 audec->pcrscr64, audec->apts64, audec->tsync_pcr_dispoint,audec->adis_flag);
539 }
540 }
541#endif
542 if (audec->adsp_ops.dsp_on) {
543 int channels;
544 #if ANDROID_PLATFORM_SDK_VERSION >= 19
545 channels = mpAudioTrack->channelCount();
546 #elif defined(ANDROID_VERSION_JBMR2_UP)
547 AudioTrack *track = (AudioTrack *)out_ops->private_data;
548 channels = track->channelCount();
549 #else
550 channels = buffer->channelCount;
551 #endif
552 if (wfd_enable) {
553 af_resample_api((char*)(buffer->i16), (unsigned int*)&buffer->size, channels, audec, resample, resample_step);
554 } else if (audec->tsync_mode == TSYNC_MODE_PCRMASTER) {
555 af_pcrmaster_resample_api((char*)(buffer->i16), (unsigned int*)&buffer->size, channels, audec);
556 } else {
557 af_resample_api_normal((char*)(buffer->i16), (unsigned int*)&buffer->size, channels, audec);
558 }
559 if (!audec->pre_mute) {
560 if (audec->pre_gain_enable >= 0) {
561 pre_gain_enable = audec->pre_gain_enable;
562 }
563 if (pre_gain_enable) {
564 apply_audio_pregain(buffer->i16, buffer->size, audec->pre_gain);
565 }
566 if (audec->mix_lr_channel_enable >= 0)
567 mix_lr_channel_enable = audec->mix_lr_channel_enable;
568 if (mix_lr_channel_enable && channels == 2) {
569 momo2_mode_mix((short*)(buffer->i16), buffer->size/2,channels);
570 }
571 } else {
572 //mute the buffer by pre-mute flag on
573 memset(buffer->i16, 0, buffer->size);
574 }
575 } else {
576 adec_print("audioCallback: dsp not work!\n");
577 }
578
579
580 if(wfd_enable){
581 if (buffer->size==0) {
582 adec_print("no sample from DSP !!! in: %d, out: %d, diff: %d, filtered: %d", last_checkin/90, last_checkout/90, (last_checkin-last_checkout)/90, diff_avr);
583
584 ioctl(audec->adsp_ops.amstream_fd, AMSTREAM_IOC_AB_STATUS, (unsigned long)&am_io);
585 if (am_io.status.size > 0)
586 adec_print("ab_level=%x,ab_size=%x, alevel:%f, ab_rd_ptr=%x",
587 am_io.status.data_len, am_io.status.size, (float)(am_io.status.data_len)/(am_io.status.size), am_io.status.read_pointer);
588 }
589 }
590 return;
591}
592#ifdef USE_ARM_AUDIO_DEC
593//-------------------------------------------------------------------------
594static void i2s_iec958_sync_force(struct aml_audio_dec* audec,int bytes_readed_diff_allowd)
595{
596 int bytes_err= audec->raw_bytes_readed-audec->pcm_bytes_readed*audec->codec_type;
597 int bytes_cnt;
598 int len;
599 int goon_read_data_flag=1;
600 char tmp[2048];
601 int64_t tmp64;
602 #if 0
603 if(-bytes_err>bytes_readed_diff_allowd)
604 {
605 //958 is lower than i2s :so we discard data
606 bytes_err=-bytes_err;
607 int raw_size_discard=bytes_err-bytes_readed_diff_allowd;
608 bytes_cnt=0;
609 while(bytes_cnt<raw_size_discard && !audec->need_stop){
610 len=audec->adsp_ops.dsp_read_raw(&audec->adsp_ops,tmp,(raw_size_discard-bytes_cnt)>2048?2048:(raw_size_discard-bytes_cnt));
611 bytes_cnt+=len;
612 if (len=0)
613 break;
614 }
615 audec->raw_bytes_readed+=bytes_cnt;
616 }else if(bytes_err>bytes_readed_diff_allowd){
617 //958 is faster than i2s
618 int pcm_size_discard=(bytes_err-bytes_readed_diff_allowd)/audec->codec_type;
619 bytes_cnt=0;
620 while(bytes_cnt<pcm_size_discard && !audec->need_stop){
621 len=audec->adsp_ops.dsp_read(&audec->adsp_ops,tmp,(pcm_size_discard-bytes_cnt)>2048?2048:(pcm_size_discard-bytes_cnt));
622 bytes_cnt+=len;
623 if (len=0)
624 break;
625 }
626 audec->pcm_bytes_readed+=bytes_cnt;
627 }
628 #endif
629 tmp64=audec->pcm_bytes_readed>audec->raw_bytes_readed? audec->raw_bytes_readed:audec->pcm_bytes_readed;
630 audec->pcm_bytes_readed -=tmp64;
631 audec->raw_bytes_readed -=tmp64;
632};
633void audioCallback_raw(int event, void* user, void *info)
634{
635 int len;
636 AudioTrack::Buffer *buffer = static_cast<AudioTrack::Buffer *>(info);
637 aml_audio_dec_t *audec = static_cast<aml_audio_dec_t *>(user);
638 if (event != AudioTrack::EVENT_MORE_DATA) {
639 adec_print("[%s %d]audioCallback: event = %d \n",__FUNCTION__,__LINE__, event);
640 return;
641 }
642 if (buffer == NULL || buffer->size == 0) {
643 adec_print("[%s %d]audioCallback: Wrong buffer\n",__FUNCTION__,__LINE__);
644 return;
645 }
646
647 if(audec->i2s_iec958_sync_flag && audec->raw_bytes_readed< audec->i2s_iec958_sync_gate)
648 { char tmp[4096];
649 int readed_bytes=0;
650 int bytes_readed_diff=audec->raw_bytes_readed-audec->pcm_bytes_readed*audec->codec_type;
651 if(bytes_readed_diff==0){
652 //adec_print("NOTE: bytes_readed_diff/0 audec->pcm_bytes_readed/%d\n",audec->pcm_bytes_readed);
653 while(audec->pcm_bytes_readed==0 && !audec->need_stop){
654 amthreadpool_thread_usleep(2000);
655 }
656 adec_print("NOTE:i2s has started read pcm\n");
657 }
658
659 bytes_readed_diff=audec->raw_bytes_readed-audec->pcm_bytes_readed*audec->codec_type;
660 if(bytes_readed_diff>0){//iec958 was faster than i2s:
661 //adec_print("Iec958 faster than I2s: bytes_readed_diff/%d (SyncGate/%d RawBytesReaded/%lld PcmBytesReaded/%lld codec_type/%f)\n",
662 // bytes_readed_diff,audec->i2s_iec958_sync_gate,audec->raw_bytes_readed,audec->pcm_bytes_readed,audec->codec_type);
663 buffer->size /=8;
664 buffer->size-= (buffer->size%audec->raw_frame_size);
665 memset((char*)(buffer->i16),0,buffer->size);
666 return;
667 }else if(bytes_readed_diff<0){//iec958 was slower than i2s:
668 while((audec->raw_bytes_readed-audec->pcm_bytes_readed*audec->codec_type)<0 &&
669 (audec->raw_bytes_readed <audec->i2s_iec958_sync_gate) &&
670 !audec->need_stop
671 )
672 {
673 bytes_readed_diff=audec->pcm_bytes_readed*audec->codec_type-audec->raw_bytes_readed;
674 //adec_print("iec958 was slower than i2s:bytes_readed_diff/%d\n",-bytes_readed_diff);
675 while(bytes_readed_diff && !audec->need_stop){
676 readed_bytes=audec->adsp_ops.dsp_read_raw(&audec->adsp_ops,tmp,bytes_readed_diff>4096?4096: bytes_readed_diff);
677 audec->raw_bytes_readed+=readed_bytes;
678 bytes_readed_diff-=readed_bytes;
679 if(readed_bytes==0)
680 break;
681 }
682 }
683 //audec->i2s_iec958_sync_flag=0;
684 }
685 }
686
687 if (audec->adsp_ops.dsp_on) {
688 int bytes_cnt=0;
689 while(bytes_cnt<buffer->size && !audec->need_stop){
690 len=audec->adsp_ops.dsp_read_raw(&audec->adsp_ops, (char*)(buffer->i16)+bytes_cnt,buffer->size-bytes_cnt);
691 bytes_cnt+=len;
692 if (len == 0)
693 break;
694 }
695 buffer->size=bytes_cnt;
696 audec->raw_bytes_readed+=bytes_cnt;
697 } else {
698 adec_print("[%s %d]audioCallback: dsp not work!\n",__FUNCTION__,__LINE__);
699 }
700// memset raw data when start playback to walkround HDMI audio format changed noise for some kind of TV set
701 if(audec->format != ACODEC_FMT_TRUEHD ){
702 if(audec->raw_bytes_readed < 16*4*1024)
703 memset((char *)(buffer->i16),0,buffer->size);
704 }
705 return;
706}
707
708extern "C" int android_init_raw(struct aml_audio_dec* audec)
709{
710 Mutex::Autolock _l(mLock_raw);
711 adec_print("[%s %d]android raw_out init",__FUNCTION__,__LINE__);
712 status_t status;
713 AudioTrack *track;
714 audio_out_operations_t *out_ops = &audec->aout_ops;
715 int SampleRate=audec->samplerate;
716 out_ops->private_data_raw=NULL;
717 audio_format_t aformat = AUDIO_FORMAT_INVALID;
718 if((audec->format!=ACODEC_FMT_DTS) &&
719 (audec->format != ACODEC_FMT_AC3) &&
720 (audec->format != ACODEC_FMT_EAC3) &&
721 (audec->format != ACODEC_FMT_TRUEHD))
722 {
723 adec_print("[%s %d]NOTE: now just ACODEC_FMT_DTS_rawoutpu was support! ",__FUNCTION__,__LINE__);
724 return 0;
725 }else if(amsysfs_get_sysfs_int("/sys/class/audiodsp/digital_raw")==0){
726 adec_print("[%s %d]DIGITAL_RAW WAS DISABLE !",__FUNCTION__,__LINE__);
727 return 0;
728 }
729
730 if (audec->format == ACODEC_FMT_DTS)
731 aformat = AUDIO_FORMAT_DTS;
732 else if(audec->format == ACODEC_FMT_AC3)
733 aformat = AUDIO_FORMAT_AC3;
734 else if(audec->format == ACODEC_FMT_EAC3)
735 aformat = AUDIO_FORMAT_EAC3;
736 else if(audec->format == ACODEC_FMT_TRUEHD)
737 aformat = AUDIO_FORMAT_DOLBY_TRUEHD;
738
739 if(audec->format == ACODEC_FMT_TRUEHD){
740 audec->codec_type=16;
741 }
742
743 int dgraw = amsysfs_get_sysfs_int("/sys/class/audiodsp/digital_raw");
744 if (dgraw == 1 ) {
745 if((audec->format == ACODEC_FMT_AC3) ||
746 (audec->format == ACODEC_FMT_EAC3)){
747 /*if spdif pass through,force to DD otuput */
748 aformat = AUDIO_FORMAT_AC3;
749 audec->codec_type=1;
750 }else if(audec->format==ACODEC_FMT_DTS){
751 if(audec->samplerate==88200 || audec->samplerate==96000){
752 audec->codec_type=0.50;
753 SampleRate=audec->samplerate/2;
754 }else if(audec->samplerate==176400 || audec->samplerate==192000){
755 audec->codec_type=0.25;
756 SampleRate=audec->samplerate/4;
757 }else if(audec->samplerate==352800 || audec->samplerate==384000){
758 adec_print("[%s %d]NOTE:Current FS/%d was support! ",__FUNCTION__,__LINE__,audec->samplerate);
759 return 0;
760 }else{//audec->samplerate<=48000
761 audec->codec_type=1;
762 }
763 }
764 }else if(dgraw == 2 ){
765 if(audec->format == ACODEC_FMT_AC3){
766 audec->codec_type=1;
767 }else if(audec->format == ACODEC_FMT_EAC3){
768 audec->codec_type=4;
769 }else if(audec->format==ACODEC_FMT_DTS &&(audec->VersionNum!=DTSETC_DECODE_VERSION_M6_M8 ||audec->DTSHDIEC958_PktType==DTSHD_IEC958_PKTTYPE_CORE)){
770 if(audec->samplerate==88200 || audec->samplerate==96000){
771 audec->codec_type=0.50;
772 SampleRate=SampleRate/2;
773 }else if(audec->samplerate==176400 || audec->samplerate==192000){
774 audec->codec_type=0.25;
775 SampleRate=SampleRate/4;
776 }else if(audec->samplerate==352800 || audec->samplerate==384000){
777 adec_print("[%s %d]NOTE:Current FS/%d was support! ",__FUNCTION__,__LINE__,audec->samplerate);
778 return 0;
779 }else{//audec->samplerate<=48000
780 audec->codec_type=1;
781 }
782 }else if(audec->format==ACODEC_FMT_DTS && audec->VersionNum==DTSETC_DECODE_VERSION_M6_M8){
783 int unvalidpara=0;
784 if(audec->DTSHDIEC958_PktType==DTSHD_IEC958_PKTTYPE_SINGLEI2S){
785 if(audec->DTSHDIEC958_FS==48000||audec->DTSHDIEC958_FS==44100)
786 {
787 SampleRate=audec->DTSHDIEC958_FS;
788 }else if(audec->DTSHDIEC958_FS==192000||audec->DTSHDIEC958_FS==176400){// clock need Mutiple 4
789 SampleRate=audec->DTSHDIEC958_FS/4;
790 #if ANDROID_PLATFORM_SDK_VERSION >= 21//android 5.0
791 aformat = (audio_format_t)AUDIO_FORMAT_DTS_HD;
792 SampleRate=audec->DTSHDIEC958_FS;
793 #endif
794 }else{
795 unvalidpara=1;
796 }
797 }else if(audec->DTSHDIEC958_PktType==DTSHD_IEC958_PKTTYPE_FOURI2S){// clock need Mutiple 4
798 if(audec->DTSHDIEC958_FS==192000||audec->DTSHDIEC958_FS==384000 || audec->DTSHDIEC958_FS==768000 ||
799 audec->DTSHDIEC958_FS==176400||audec->DTSHDIEC958_FS==352800 || audec->DTSHDIEC958_FS==705600)
800 {
801 SampleRate=audec->DTSHDIEC958_FS/4;
802 #if ANDROID_PLATFORM_SDK_VERSION >= 21//android 5.0
803 aformat = (audio_format_t)AUDIO_FORMAT_DTS_MASTER;
804 SampleRate=audec->DTSHDIEC958_FS;
805 #endif
806 }else{
807 unvalidpara=2;
808 }
809 }else{
810 unvalidpara=3;
811 }
812 if(unvalidpara){
813 adec_print("[%s %d]NOTE:Unvalid Paras/%d for RawOutput:PCM_FS/%d IEC958_FS/%d PCMSamsInFrm/%d IEC958PktFrmSize/%d ",
814 __FUNCTION__,__LINE__,unvalidpara,audec->samplerate,audec->DTSHDIEC958_FS,audec->DTSHDPCM_SamsInFrmAtMaxSR,audec->DTSHDIEC958_PktFrmSize);
815 return 0;
816 }
817 audec->codec_type=audec->DTSHDIEC958_FS/audec->samplerate;
818 }
819 }
820
821 if(audec->format == ACODEC_FMT_TRUEHD){
822 SampleRate=192000;
823 }
824 adec_print("[%s %d]SampleRate used for init rawoutput:%d\n",__FUNCTION__,__LINE__,SampleRate);
825
826#if ANDROID_PLATFORM_SDK_VERSION < 19
827 track = new AudioTrack();
828 if (track == NULL) {
829 adec_print("[%s %d]AudioTrack_raw Create Failed!",__FUNCTION__,__LINE__);
830 return -1;
831 }
832#else
833 mpAudioTrack_raw = new AudioTrack();
834 track = mpAudioTrack_raw.get();
835#endif
836
837 audio_session_t SessionID = AUDIO_SESSION_NONE;//audec->SessionID;
838 adec_print("[%s %d]SessionID = %d audec->codec_type/%f audec->samplerate/%d",__FUNCTION__,__LINE__,SessionID,audec->codec_type,audec->samplerate);
839 int flags = AUDIO_OUTPUT_FLAG_DIRECT;
840//only defined from android M
841#if ANDROID_PLATFORM_SDK_VERSION >= 23
842 flags |= AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO;
843#endif
844 status = track->set(AUDIO_STREAM_MUSIC,
845 SampleRate,
846 aformat,
847 AUDIO_CHANNEL_OUT_STEREO,
848 0, // frameCount
849 (audio_output_flags_t)flags,
850 audioCallback_raw,
851 audec, // user when callback
852 0, // notificationFrames
853 0, // shared buffer
854 false, // threadCanCallJava
855 SessionID); // sessionId
856 if (status != NO_ERROR) {
857 adec_print("[%s %d]track->set returns %d",__FUNCTION__,__LINE__, status);
858 adec_print("[%s %d]audio out samplet %d",__FUNCTION__,__LINE__, audec->samplerate);
859 adec_print("[%s %d]audio out channels %d",__FUNCTION__,__LINE__, audec->channels);
860#if ANDROID_PLATFORM_SDK_VERSION < 19
861 delete track;
862 track = NULL;
863#else
864 track = NULL;
865 mpAudioTrack_raw.clear();
866#endif
867 out_ops->audio_out_raw_enable = 0;
868 out_ops->private_data_raw=NULL;
869 return -1;
870 }
871
872 out_ops->private_data_raw= (void *)track;
873
874 //1/10=0.1s=100ms
875 audec->raw_frame_size=audec->channels*(audec->adec_ops->bps>>3);
876 audec->max_bytes_readded_diff=audec->samplerate*audec->raw_frame_size*audec->codec_type/10;
877 audec->i2s_iec958_sync_gate=audec->samplerate*audec->raw_frame_size*audec->codec_type*0.4;//400ms
878 return 0;
879}
880#endif
881//-------------------------------------------------------------------------
882/**
883 * \brief output initialization
884 * \param audec pointer to audec
885 * \return 0 on success otherwise negative error code
886 */
887extern "C" int android_init(struct aml_audio_dec* audec)
888{
889 Mutex::Autolock _l(mLock);
890 status_t status;
891 AudioTrack *track;
892 audio_out_operations_t *out_ops = &audec->aout_ops;
893 char wfd_prop[PROPERTY_VALUE_MAX];
894 fill_audiotrack_zero = 0;
895 buffering_audio_data = 0;
896 skip_unnormal_discontinue = 0;
897 unnormal_discontinue = 0;
898 unnormal_discontinue1 = 0;
899 ttt = 0;
900 resample = 0;
901 last_resample = 0;
902 xxx = 0;
903 memset(&diff_record[0], 0, 0x40*sizeof(diff_record[0]));
904 diff_wp = 0;
905 if (get_audio_decoder() == AUDIO_ARC_DECODER) {
906 wfd_ds_thrdhold = 220;
907 wfd_us_thrdhold = 180;
908
909 }
910 else{
911 wfd_ds_thrdhold = 250;
912 wfd_us_thrdhold = 150;
913 }
914 adec_print("up/down sampling thread %d /%d ms \n",wfd_us_thrdhold,wfd_ds_thrdhold);
915 if(property_get("media.libplayer.wfd", wfd_prop, "0") > 0){
916 wfd_enable = (strcmp(wfd_prop, "1") == 0);
917 if(wfd_enable)
918 {
919 audio_io_handle_t handle = AudioSystem::getOutput(AUDIO_STREAM_MUSIC,
920 48000,
921 AUDIO_FORMAT_PCM_16_BIT,
922 AUDIO_CHANNEL_OUT_STEREO,
923#if defined(_VERSION_ICS)
924 AUDIO_POLICY_OUTPUT_FLAG_INDIRECT
925#else //JB...
926 AUDIO_OUTPUT_FLAG_PRIMARY
927#endif
928 );
929 if(handle > 0){
930 char str[64];
931 status_t ret;
932 memset(str,0,sizeof(str));
933 // backup old framecount
934#if ANDROID_PLATFORM_SDK_VERSION >= 21 //FIXME on 5.0
935 AudioSystem::getFrameCount(handle,&old_frame_count);
936#else
937 AudioSystem::getFrameCount(handle, AUDIO_STREAM_MUSIC, &old_frame_count);
938#endif
939
940 sprintf(str,"frame_count=%d",256);
941 ret = AudioSystem::setParameters(handle, String8(str));
942 if(ret != 0){
943 adec_print("change frame count failed: ret = %d\n", ret);
944 }
945 adec_print("wfd: %s", str);
946 }
947 }
948 }else{
949 wfd_enable = 0;
950 }
951
952 adec_get_tsync_info(&(audec->tsync_mode));
953 adec_print("wfd_enable = %d, tsync_mode=%d, ", wfd_enable, audec->tsync_mode);
954 //--------------------------------------------
955 //alwas effect in case:
956 //1: rawoutput==1 && format==ACODEC_FMT_AC3 && (FS==32000 ||FS = =44100)
957 //2: rawoutput==1 && format==ACODEC_FMT_EC3 && (FS==32000 ||FS = =44100)
958 //3: rawoutput==1 && format==ACODEC_FMT_DTS && (FS==32000 ||FS = =44100||FS = =88200||FS = =96000|| FS = =176400|| FS = =192000)
959 //4: rawoutput==2 && format==ACODEC_FMT_EC3 && FS==44100
960 //5: rawoutput==2 && format==ACODEC_FMT_DTS && (FS= =32000||FS = =44100||FS = =88200||FS = =96000|| FS = =176400|| FS = =192000)
961 //6: rawoutput==0 && format==ACODEC_FMT_AC3 && CH==8
962 //summary:always effect in case: rawoutput>0 && (format=ACODEC_FMT_DTS or ACODEC_FMT_AC3) or 8chPCM _output
963/*after 6.0,need not this code*/
964#if ANDROID_PLATFORM_SDK_VERSION < 23
965 reset_system_samplerate(audec);
966#endif
967 int user_raw_enable = amsysfs_get_sysfs_int("/sys/class/audiodsp/digital_raw");
968#ifdef USE_ARM_AUDIO_DEC
969 out_ops->audio_out_raw_enable = user_raw_enable && (audec->format == ACODEC_FMT_DTS ||
970 audec->format == ACODEC_FMT_AC3 ||
971 audec->format == ACODEC_FMT_EAC3||
972 (audec->format == ACODEC_FMT_TRUEHD && user_raw_enable == 2));
973 if(out_ops->audio_out_raw_enable)
974 android_init_raw(audec);
975#endif
976 //---------------------------
977 adec_print("[%s %d]android out init",__FUNCTION__,__LINE__);
978#if ANDROID_PLATFORM_SDK_VERSION < 19
979 track = new AudioTrack();
980 if (track == NULL) {
981 adec_print("[%s %d]AudioTrack Create Failed!",__FUNCTION__,__LINE__);
982 return -1;
983 }
984#else
985 mpAudioTrack = new AudioTrack();
986 track = mpAudioTrack.get();
987#endif
988
989 audio_session_t SessionID = audec->SessionID;
990 adec_print("[%s %d]SessionID = %d audec->dtshdll_flag/%d audec->channels/%d",__FUNCTION__,__LINE__,SessionID,audec->dtshdll_flag,audec->channels);
991#if defined(_VERSION_JB)
992 char tmp[128]={0};
993 int FS_88_96_enable=0;
994 if (property_get("media.libplayer.88_96K", tmp, "0") > 0 && !strcmp(tmp, "1")) {
995 FS_88_96_enable=1;
996 if (audec->format == ACODEC_FMT_DTS && audec->samplerate>48000 && !user_raw_enable)
997 {
998 adec_print("set digital_codec to AUDIO_FORMAT_DTS_PCM_88K_96K");
999 }
1000 }
1001 if( audec->channels == 8 ||
1002 (audec->format ==ACODEC_FMT_DTS && audec->samplerate>48000 && user_raw_enable==0 && FS_88_96_enable==1 )
1003 )
1004 { //8ch PCM: use direct output
1005 //DTS PCMoutput && FS>48000: use direct output
1006 audio_channel_mask_t ChMask;
1007 audio_output_flags_t Flag;
1008 audio_format_t aformat;
1009 memset(tmp,0,sizeof(tmp));
1010 if(audec->channels == 8){
1011 adec_print("create multi-channel track use DirectOutput\n");
1012 property_set(DOLBY_SYSTEM_CHANNEL,"true");
1013 property_get(DOLBY_SYSTEM_CHANNEL, tmp, "0");
1014 if(!strcmp(tmp, "true"))
1015 {
1016 adec_print("[%s %d]ds1.audio.multichannel.support set success!\n",__FUNCTION__,__LINE__);
1017 }else{
1018 adec_print("[%s %d]ds1.audio.multichannel.support set fail!\n",__FUNCTION__,__LINE__);
1019 }
1020 ChMask=AUDIO_CHANNEL_OUT_7POINT1;
1021 Flag=AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
1022 aformat=AUDIO_FORMAT_PCM_16_BIT;
1023 }else{
1024 adec_print("create HD-PCM(Fs/%d>48000)Direct Ouputtrack\n",audec->samplerate);
1025 ChMask=AUDIO_CHANNEL_OUT_STEREO;
1026 Flag =AUDIO_OUTPUT_FLAG_DIRECT;
1027//TODO
1028#if ANDROID_PLATFORM_SDK_VERSION < 23
1029 aformat = AUDIO_FORMAT_DTS;
1030#else
1031 aformat = AUDIO_FORMAT_PCM_16_BIT;
1032#endif
1033 }
1034 status = track->set(AUDIO_STREAM_MUSIC,
1035 audec->samplerate,
1036 aformat,
1037 ChMask,
1038 0, // frameCount
1039 Flag/*AUDIO_OUTPUT_FLAG_NONE*/, // flags
1040 audioCallback,
1041 audec, // user when callback
1042 0, // notificationFrames
1043 0, // shared buffer
1044 false, // threadCanCallJava
1045 SessionID); // sessionId
1046 }else{
1047//here calculate the min framecount and set the audiotrack
1048//refered to android_media_AudioTrack_get_min_buff_size
1049//return frameCount * channelCount * bytesPerSample;
1050 size_t frameCount = 0;
1051 status = AudioTrack::getMinFrameCount(&frameCount, AUDIO_STREAM_DEFAULT,audec->samplerate);
1052 if (status == NO_ERROR) {
1053 frameCount = audec->channels*2*frameCount;
1054 }
1055 else
1056 frameCount = 0;
1057
1058 status = track->set(AUDIO_STREAM_MUSIC,
1059 audec->samplerate,
1060 AUDIO_FORMAT_PCM_16_BIT,
1061 (audec->channels == 1) ? AUDIO_CHANNEL_OUT_MONO : AUDIO_CHANNEL_OUT_STEREO,
1062 frameCount, // frameCount
1063 AUDIO_OUTPUT_FLAG_NONE, // flags
1064 audioCallback,
1065 audec, // user when callback
1066 0, // notificationFrames
1067 0, // shared buffer
1068 false, // threadCanCallJava
1069 SessionID); // sessionId
1070 }
1071
1072#elif defined(_VERSION_ICS)
1073 status = track->set(AUDIO_STREAM_MUSIC,
1074 audec->samplerate,
1075 AUDIO_FORMAT_PCM_16_BIT,
1076 (audec->channels == 1) ? AUDIO_CHANNEL_OUT_MONO : AUDIO_CHANNEL_OUT_STEREO,
1077 0, // frameCount
1078 0, // flags
1079 audioCallback,
1080 audec, // user when callback
1081 0, // notificationFrames
1082 0, // shared buffer
1083 false, // threadCanCallJava
1084 SessionID); // sessionId
1085#else // GB or lower:
1086 status = track->set(AudioSystem::MUSIC,
1087 audec->samplerate,
1088 AudioSystem::PCM_16_BIT,
1089 (audec->channels == 1) ? AudioSystem::CHANNEL_OUT_MONO : AudioSystem::CHANNEL_OUT_STEREO,
1090 0, // frameCount
1091 0, // flags
1092 audioCallback,
1093 audec, // user when callback
1094 0, // notificationFrames
1095 0, // shared buffer
1096 SessionID);
1097#endif
1098
1099 if (status != NO_ERROR) {
1100 adec_print("[%s %d]track->set returns %d", __FUNCTION__,__LINE__,status);
1101 adec_print("[%s %d]audio out samplet %d" , __FUNCTION__,__LINE__, audec->samplerate);
1102 adec_print("[%s %d]audio out channels %d", __FUNCTION__,__LINE__,audec->channels);
1103#if ANDROID_PLATFORM_SDK_VERSION < 19
1104 delete track;
1105 track = NULL;
1106#else
1107 track = NULL;
1108 mpAudioTrack.clear();
1109#endif
1110 if(audec->channels == 8){
1111 property_set(DOLBY_SYSTEM_CHANNEL,"false");
1112 }
1113 return -1;
1114
1115 }
1116 af_resample_linear_init(audec);
1117 out_ops->private_data = (void *)track;
1118 return 0;
1119}
1120#ifdef USE_ARM_AUDIO_DEC
1121extern "C" int android_start_raw(struct aml_audio_dec* audec)
1122{
1123 Mutex::Autolock _l(mLock_raw);
1124 adec_print("[%s %d]android raw_out start",__FUNCTION__,__LINE__);
1125 status_t status;
1126 audio_out_operations_t *out_ops = &audec->aout_ops;
1127
1128#if ANDROID_PLATFORM_SDK_VERSION < 19
1129 AudioTrack *track = (AudioTrack *)out_ops->private_data_raw;
1130#else
1131 AudioTrack *track = mpAudioTrack_raw.get();
1132#endif
1133 if (track == 0) {
1134 adec_print("[%s %d]No track instance!\n",__FUNCTION__,__LINE__);
1135 return -1;
1136 }
1137
1138 status = track->initCheck();
1139 if (status != NO_ERROR) {
1140#if ANDROID_PLATFORM_SDK_VERSION < 19
1141 delete track;
1142#else
1143 mpAudioTrack_raw.clear();
1144#endif
1145 out_ops->private_data_raw= NULL;
1146 return -1;
1147 }
1148
1149 track->start();
1150 adec_print("[%s %d]AudioTrack_raw initCheck OK and started.",__FUNCTION__,__LINE__);
1151 return 0;
1152}
1153#endif
1154/**
1155 * \brief start output
1156 * \param audec pointer to audec
1157 * \return 0 on success otherwise negative error code
1158 *
1159 * Call android_start(), then the callback will start being called.
1160 */
1161extern "C" int android_start(struct aml_audio_dec* audec)
1162{
1163
1164 Mutex::Autolock _l(mLock);
1165 status_t status;
1166 audio_out_operations_t *out_ops = &audec->aout_ops;
1167#if ANDROID_PLATFORM_SDK_VERSION < 19
1168 AudioTrack *track = (AudioTrack *)out_ops->private_data;
1169#else
1170 AudioTrack *track = mpAudioTrack.get();
1171#endif
1172
1173
1174#ifdef USE_ARM_AUDIO_DEC
1175 i2s_iec958_sync_force(audec,0);
1176 if(out_ops->audio_out_raw_enable)
1177 android_start_raw(audec);
1178#endif
1179 adec_print("android out start");
1180 ttt = 0;
1181 resample = 0;
1182 last_resample = 0;
1183 xxx = 0;
1184 memset(&diff_record[0], 0, 0x40*sizeof(diff_record[0]));
1185 diff_wp = 0;
1186 if (track == 0) {
1187 adec_print("No track instance!\n");
1188 return -1;
1189 }
1190 status = track->initCheck();
1191 if (status != NO_ERROR) {
1192#if ANDROID_PLATFORM_SDK_VERSION < 19
1193 delete track;
1194#else
1195 mpAudioTrack.clear();
1196#endif
1197 out_ops->private_data = NULL;
1198 return -1;
1199 }
1200 track->start();
1201 adec_print("AudioTrack initCheck OK and started.");
1202
1203 return 0;
1204}
1205
1206extern "C" int android_pause_raw(struct aml_audio_dec* audec)
1207{
1208 Mutex::Autolock _l(mLock_raw);
1209 adec_print("[%s %d]android raw_out pause",__FUNCTION__,__LINE__);
1210 audio_out_operations_t *out_ops = &audec->aout_ops;
1211
1212#if ANDROID_PLATFORM_SDK_VERSION < 19
1213 AudioTrack *track = (AudioTrack *)out_ops->private_data_raw;
1214#else
1215 AudioTrack *track = mpAudioTrack_raw.get();
1216#endif
1217 if (track == 0) {
1218 adec_print("[%s %d]No track instance!\n",__FUNCTION__,__LINE__);
1219 return -1;
1220 }
1221 track->pause();
1222 return 0;
1223}
1224
1225/**
1226 * \brief pause output
1227 * \param audec pointer to audec
1228 * \return 0 on success otherwise negative error code
1229 */
1230extern "C" int android_pause(struct aml_audio_dec* audec)
1231{
1232
1233 Mutex::Autolock _l(mLock);
1234 audio_out_operations_t *out_ops = &audec->aout_ops;
1235#if ANDROID_PLATFORM_SDK_VERSION < 19
1236 AudioTrack *track = (AudioTrack *)out_ops->private_data;
1237#else
1238 AudioTrack *track = mpAudioTrack.get();
1239#endif
1240#ifdef USE_ARM_AUDIO_DEC
1241 if(out_ops->audio_out_raw_enable)
1242 android_pause_raw(audec);
1243#endif
1244 adec_print("android out pause");
1245
1246 if (track == 0) {
1247 adec_print("No track instance!\n");
1248 return -1;
1249 }
1250
1251 track->pause();
1252#ifdef USE_ARM_AUDIO_DEC
1253 adec_print("[%s %d] PRE_PAUSE:raw_bytes_readed/%lld pcm_bytes_readed/%lld delta/%lld\n",__FUNCTION__,__LINE__,
1254 audec->raw_bytes_readed,audec->pcm_bytes_readed,audec->pcm_bytes_readed-audec->raw_bytes_readed);
1255 i2s_iec958_sync_force(audec,0);
1256 adec_print("[%s %d] POST_PAUSE:raw_bytes_readed/%lld pcm_bytes_readed/%lld delta/%lld\n",__FUNCTION__,__LINE__,
1257 audec->raw_bytes_readed,audec->pcm_bytes_readed,audec->pcm_bytes_readed-audec->raw_bytes_readed);
1258 audec->i2s_iec958_sync_flag=1;
1259#endif
1260 return 0;
1261}
1262
1263extern "C" int android_resume_raw(struct aml_audio_dec* audec)
1264{
1265 Mutex::Autolock _l(mLock_raw);
1266 adec_print("[%s %d]android raw_out resume",__FUNCTION__,__LINE__);
1267
1268 audio_out_operations_t *out_ops = &audec->aout_ops;
1269#if ANDROID_PLATFORM_SDK_VERSION < 19
1270 AudioTrack *track = (AudioTrack *)out_ops->private_data_raw;
1271#else
1272 AudioTrack *track = mpAudioTrack_raw.get();
1273#endif
1274 if (track == 0) {
1275 adec_print("[%s %d]No track instance!\n",__FUNCTION__,__LINE__);
1276 return -1;
1277 }
1278 track->start();
1279 return 0;
1280}
1281/**
1282 * \brief resume output
1283 * \param audec pointer to audec
1284 * \return 0 on success otherwise negative error code
1285 */
1286extern "C" int android_resume(struct aml_audio_dec* audec)
1287{
1288
1289 Mutex::Autolock _l(mLock);
1290 audio_out_operations_t *out_ops = &audec->aout_ops;
1291#if ANDROID_PLATFORM_SDK_VERSION < 19
1292 AudioTrack *track = (AudioTrack *)out_ops->private_data;
1293#else
1294 AudioTrack *track = mpAudioTrack.get();
1295#endif
1296
1297#ifdef USE_ARM_AUDIO_DEC
1298 i2s_iec958_sync_force(audec,0);
1299 if(out_ops->audio_out_raw_enable)
1300 android_resume_raw(audec);
1301#endif
1302 adec_print("android out resume");
1303 ttt = 0;
1304 resample = 0;
1305 last_resample = 0;
1306 xxx = 0;
1307 memset(&diff_record[0], 0, 0x40*sizeof(diff_record[0]));
1308 diff_wp = 0;
1309 if (track == 0) {
1310 adec_print("No track instance!\n");
1311 return -1;
1312 }
1313 track->start();
1314
1315 return 0;
1316}
1317#ifdef USE_ARM_AUDIO_DEC
1318extern "C" int android_stop_raw(struct aml_audio_dec* audec)
1319{
1320 Mutex::Autolock _l(mLock_raw);
1321 adec_print("[%s %d]android raw_out stop",__FUNCTION__,__LINE__);
1322
1323 audio_out_operations_t *out_ops = &audec->aout_ops;
1324#if ANDROID_PLATFORM_SDK_VERSION < 19
1325 AudioTrack *track = (AudioTrack *)out_ops->private_data_raw;
1326#else
1327 AudioTrack *track = mpAudioTrack_raw.get();
1328#endif
1329
1330 if (track == 0){
1331 adec_print("[%s %d]No track instance!\n",__FUNCTION__,__LINE__);
1332 return -1;
1333 }
1334 track->stop();
1335 /* release AudioTrack */
1336#if ANDROID_PLATFORM_SDK_VERSION < 19
1337 delete track;
1338#else
1339 mpAudioTrack_raw.clear();
1340#endif
1341
1342 out_ops->private_data_raw= NULL;
1343 return 0;
1344}
1345#endif
1346/**
1347 * \brief stop output
1348 * \param audec pointer to audec
1349 * \return 0 on success otherwise negative error code
1350 */
1351extern "C" int android_stop(struct aml_audio_dec* audec)
1352{
1353 Mutex::Autolock _l(mLock);
1354 audio_out_operations_t *out_ops = &audec->aout_ops;
1355#if ANDROID_PLATFORM_SDK_VERSION < 19
1356 AudioTrack *track = (AudioTrack *)out_ops->private_data;
1357#else
1358 AudioTrack *track = mpAudioTrack.get();
1359#endif
1360#ifdef USE_ARM_AUDIO_DEC
1361 if(out_ops->audio_out_raw_enable)
1362 android_stop_raw(audec);
1363#endif
1364 adec_print("android out stop");
1365 if(audec->channels == 8){
1366 property_set(DOLBY_SYSTEM_CHANNEL,"false");
1367 }
1368 if (track == 0){
1369 adec_print("No track instance!\n");
1370 return -1;
1371 }
1372
1373 track->stop();
1374 /* release AudioTrack */
1375#if ANDROID_PLATFORM_SDK_VERSION < 19
1376 delete track;
1377#else
1378 mpAudioTrack.clear();
1379#endif
1380 out_ops->private_data = NULL;
1381/*after 6.0,not need this code*/
1382#if ANDROID_PLATFORM_SDK_VERSION < 23
1383 restore_system_samplerate(audec);
1384#endif
1385 if(wfd_enable){
1386 restore_system_framesize();
1387 }
1388 return 0;
1389}
1390
1391/**
1392 * \brief get output latency in ms
1393 * \param audec pointer to audec
1394 * \return output latency
1395 */
1396extern "C" unsigned long android_latency(struct aml_audio_dec* audec)
1397{
1398 unsigned long latency;
1399 audio_out_operations_t *out_ops = &audec->aout_ops;
1400
1401#if ANDROID_PLATFORM_SDK_VERSION < 19
1402 AudioTrack *track = (AudioTrack *)out_ops->private_data;
1403#else
1404 AudioTrack *track = mpAudioTrack.get();
1405#endif
1406 if (audec->use_get_out_posion && audec->aout_ops.get_out_position)
1407 return 0;
1408 if (track) {
1409 status_t s;
1410 int ret = -1;
1411 int64_t write_samples;
1412 int cache_samples;
1413 int delay_us, t_us;
1414 AudioTimestamp timestamp;
1415 s = track->getTimestamp(timestamp);
1416 if (s != NO_ERROR || timestamp.mPosition < 1) {
1417 /*
1418 timestamp.mPosition <= 0 we think audio not have start.
1419 the latency is not accurate
1420 */
1421 return 0;
1422 } else {
1423 struct timespec timenow;
1424 write_samples = audec->pcm_bytes_readed/(audec->channels * 2);
1425 cache_samples = write_samples - timestamp.mPosition;
1426 if (cache_samples < 0)
1427 cache_samples = 0;
1428 delay_us = 1000 * (cache_samples * 1000 / audec->samplerate);
1429 clock_gettime(CLOCK_MONOTONIC, &timenow);
1430 t_us = (timenow.tv_sec - timestamp.mTime.tv_sec) * 1000000LL +
1431 (timenow.tv_nsec- timestamp.mTime.tv_nsec)/1000;
1432 delay_us -=t_us;
1433 if (delay_us < 0)
1434 delay_us =0;
1435 return delay_us/1000;
1436 }
1437 }
1438 if (track) {
1439 latency = track->latency();
1440 return latency;
1441 }
1442 return 0;
1443}
1444
1445/**
1446 * \brief get output latency in ms
1447 * \param audec pointer to audec
1448 * \return output latency
1449 */
1450extern "C" int android_get_position(struct aml_audio_dec* audec,
1451 int64_t *position,
1452 int64_t *timeus)
1453{
1454 audio_out_operations_t *out_ops = &audec->aout_ops;
1455 AudioTimestamp timestamp;
1456 status_t s;
1457 int ret = -1 ;
1458#if ANDROID_PLATFORM_SDK_VERSION < 19
1459 AudioTrack *track = (AudioTrack *)out_ops->private_data;
1460#else
1461 AudioTrack *track = mpAudioTrack.get();
1462#endif
1463
1464 if (track) {
1465 s = track->getTimestamp(timestamp);
1466 if (s == NO_ERROR) {
1467 *position = timestamp.mPosition;
1468 *timeus = timestamp.mTime.tv_sec * 1000000LL + timestamp.mTime.tv_nsec / 1000;
1469 return 0;
1470 }
1471 }
1472 return ret;
1473}
1474
1475
1476#ifndef ANDROID_VERSION_JBMR2_UP
1477/**
1478 * \brief mute output
1479 * \param audec pointer to audec
1480 * \param en 1 = mute, 0 = unmute
1481 * \return 0 on success otherwise negative error code
1482 */
1483extern "C" int android_mute_raw(struct aml_audio_dec* audec, adec_bool_t en)
1484{
1485 Mutex::Autolock _l(mLock_raw);
1486 adec_print("[%s %d]android raw_out mute",__FUNCTION__,__LINE__);
1487
1488 audio_out_operations_t *out_ops = &audec->aout_ops;
1489#if ANDROID_PLATFORM_SDK_VERSION < 19
1490 AudioTrack *track = (AudioTrack *)out_ops->private_data_raw;
1491#else
1492 AudioTrack *track = mpAudioTrack_raw.get();
1493#endif
1494 if (track == 0) {
1495 adec_print("No track instance!\n");
1496 return -1;
1497 }
1498
1499 track->mute(en);
1500 return 0;
1501}
1502#endif
1503extern "C" int android_mute(struct aml_audio_dec* audec, adec_bool_t en)
1504{
1505 Mutex::Autolock _l(mLock);
1506 adec_print("android out mute");
1507
1508 audio_out_operations_t *out_ops = &audec->aout_ops;
1509#if ANDROID_PLATFORM_SDK_VERSION < 19
1510 AudioTrack *track = (AudioTrack *)out_ops->private_data;
1511#else
1512 AudioTrack *track = mpAudioTrack.get();
1513#endif
1514 if (!track) {
1515 adec_print("No track instance!\n");
1516 return -1;
1517 }
1518
1519#ifdef ANDROID_VERSION_JBMR2_UP
1520#else
1521 #ifdef USE_ARM_AUDIO_DEC
1522 if(out_ops->audio_out_raw_enable)
1523 android_mute_raw(audec,en);
1524 #endif
1525 track->mute(en);
1526#endif
1527
1528 return 0;
1529}
1530
1531/**
1532 * \brief set output volume
1533 * \param audec pointer to audec
1534 * \param vol volume value
1535 * \return 0 on success otherwise negative error code
1536 */
1537extern "C" int android_set_volume(struct aml_audio_dec* audec, float vol)
1538{
1539 Mutex::Autolock _l(mLock);
1540 adec_print("android set volume");
1541
1542 audio_out_operations_t *out_ops = &audec->aout_ops;
1543#if ANDROID_PLATFORM_SDK_VERSION < 19
1544 AudioTrack *track = (AudioTrack *)out_ops->private_data;
1545#else
1546 AudioTrack *track = mpAudioTrack.get();
1547#endif
1548 if (!track) {
1549 adec_print("No track instance!\n");
1550 return -1;
1551 }
1552
1553 track->setVolume(vol, vol);
1554
1555 return 0;
1556}
1557
1558/**
1559 * \brief set left/right output volume
1560 * \param audec pointer to audec
1561 * \param lvol refer to left volume value
1562 * \param rvol refer to right volume value
1563 * \return 0 on success otherwise negative error code
1564 */
1565extern "C" int android_set_lrvolume(struct aml_audio_dec* audec, float lvol,float rvol)
1566{
1567 Mutex::Autolock _l(mLock);
1568 adec_print("android set left and right volume separately");
1569
1570 audio_out_operations_t *out_ops = &audec->aout_ops;
1571#if ANDROID_PLATFORM_SDK_VERSION < 19
1572 AudioTrack *track = (AudioTrack *)out_ops->private_data;
1573#else
1574 AudioTrack *track = mpAudioTrack.get();
1575#endif
1576 if (!track) {
1577 adec_print("No track instance!\n");
1578 return -1;
1579 }
1580
1581 track->setVolume(lvol, rvol);
1582
1583 return 0;
1584}
1585extern "C" int android_set_track_rate(struct aml_audio_dec* audec,void *rate)
1586{
1587#if ANDROID_PLATFORM_SDK_VERSION >= 23
1588 Mutex::Autolock _l(mLock);
1589 adec_print("android_set_track_rate");
1590 struct AudioPlaybackRate Rate = *(struct AudioPlaybackRate*)rate;
1591 audio_out_operations_t *out_ops = &audec->aout_ops;
1592#if ANDROID_PLATFORM_SDK_VERSION < 19
1593 AudioTrack *track = (AudioTrack *)out_ops->private_data;
1594#else
1595 AudioTrack *track = mpAudioTrack.get();
1596#endif
1597 if (!track) {
1598 adec_print("No track instance!\n");
1599 return -1;
1600 }
1601
1602 track->setPlaybackRate(Rate);
1603 out_ops->track_rate = Rate.mSpeed;
1604#endif
1605 return 0;
1606}
1607
1608extern "C" void android_basic_init()
1609{
1610 Mutex::Autolock _l(mLock);
1611 adec_print("android basic init!");
1612 sp<ProcessState> proc(ProcessState::self());
1613}
1614
1615/**
1616 * \brief get output handle
1617 * \param audec pointer to audec
1618 */
1619extern "C" void get_output_func(struct aml_audio_dec* audec)
1620{
1621 audio_out_operations_t *out_ops = &audec->aout_ops;
1622
1623 out_ops->init = android_init;
1624 out_ops->start = android_start;
1625 out_ops->pause = android_pause;
1626 out_ops->resume = android_resume;
1627 out_ops->stop = android_stop;
1628 out_ops->latency = android_latency;
1629 out_ops->mute = android_mute;
1630 out_ops->set_volume = android_set_volume;
1631 out_ops->set_lrvolume = android_set_lrvolume;
1632 out_ops->set_track_rate = android_set_track_rate;
1633 out_ops->get_out_position = android_get_position;
1634 out_ops->audio_out_raw_enable = 1;
1635 /* default set a invalid value*/
1636 out_ops->track_rate = 8.8f;
1637}
1638
1639}
1640
1641