blob: d380ca32554e3b087d6b3c8a93a176c1b5099f11
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 | |
22 | extern "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" |
32 | namespace 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" |
43 | static Mutex mLock; |
44 | static Mutex mLock_raw; |
45 | //get default output sample rate which maybe changed by raw output |
46 | static int default_sr = 48000; |
47 | static int fill_audiotrack_zero = 0; |
48 | static int buffering_audio_data = 0; |
49 | static int skip_unnormal_discontinue = 0; |
50 | static int unnormal_discontinue = 0; |
51 | static int unnormal_discontinue1 = 0; |
52 | extern "C" int get_audio_decoder(void); |
53 | static 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 | |
63 | void 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) |
127 | static size_t old_frame_count = 0; |
128 | #else |
129 | static int old_frame_count = 0; |
130 | #endif |
131 | |
132 | void 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 | |
167 | void 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 | |
316 | static unsigned long long ttt = 0; |
317 | |
318 | static int resample = 0, last_resample = 0, resample_step = 0, last_step=0; |
319 | static int xxx; |
320 | static int diff_record[0x40], diff_wp = 0; |
321 | static int wfd_enable = 0, bytes_skipped = 0x7fffffff; |
322 | static int wfd_ds_thrdhold = 250; //audio pts delay threadhold for down sampling |
323 | static int wfd_us_thrdhold = 150;//audio pts delay threadhold for up sampling |
324 | |
325 | #if ANDROID_PLATFORM_SDK_VERSION >= 19 |
326 | static sp<AudioTrack> mpAudioTrack; |
327 | static sp<AudioTrack> mpAudioTrack_raw; |
328 | #endif |
329 | |
330 | struct 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 | |
338 | struct am_io_param { |
339 | int data; |
340 | int len; //buffer size; |
341 | struct buf_status status; |
342 | }; |
343 | |
344 | static int mix_lr_channel_enable=0; |
345 | static int pre_gain_enable=0; |
346 | static 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 | |
365 | static 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) |
373 | void 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 | //------------------------------------------------------------------------- |
594 | static 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 | }; |
633 | void 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 | |
708 | extern "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_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 | */ |
887 | extern "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 |
1121 | extern "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 | */ |
1161 | extern "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 | |
1206 | extern "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 | */ |
1230 | extern "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 | |
1263 | extern "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 | */ |
1286 | extern "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 |
1318 | extern "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 | */ |
1351 | extern "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 | */ |
1396 | extern "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 | */ |
1450 | extern "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 | */ |
1483 | extern "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 |
1503 | extern "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 | */ |
1537 | extern "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 | */ |
1565 | extern "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 | } |
1585 | extern "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 | |
1608 | extern "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 | */ |
1619 | extern "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 |