blob: c475a1e3b829c68c7a71eb2d10f675444b3297e8 [file] [log] [blame]
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301/* audio_stream_out.c
2 **
3 ** Copyright 2008-2009 Wind River Systems
4 ** Copyright (c) 2011-2013, The Linux Foundation. All rights reserved
5 ** Not a Contribution, Apache license notifications and license are retained
6 ** for attribution purposes only.
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License");
9 ** you may not use this file except in compliance with the License.
10 ** You may obtain a copy of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** Unless required by applicable law or agreed to in writing, software
15 ** distributed under the License is distributed on an "AS IS" BASIS,
16 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 ** See the License for the specific language governing permissions and
18 ** limitations under the License.
19 */
20
21#define LOG_TAG "audio_stream_out"
22/*#define LOG_NDEBUG 0*/
23/*#define VERY_VERY_VERBOSE_LOGGING*/
24#ifdef VERY_VERY_VERBOSE_LOGGING
25#define ALOGVV ALOGV
26#else
27#define ALOGVV(a...) do { } while(0)
28#endif
29
30#include <errno.h>
31#include <pthread.h>
32#include <stdint.h>
33#include <sys/time.h>
34#include <stdlib.h>
35#include <math.h>
36#include <dlfcn.h>
37#include <sys/resource.h>
38#include <sys/prctl.h>
39
40#include <cutils/log.h>
41#include <cutils/str_parms.h>
42#include <cutils/properties.h>
43#include <cutils/atomic.h>
44#include <cutils/sched_policy.h>
45
46#include <system/thread_defs.h>
47#include "audio_hw.h"
48#include "platform_api.h"
49#include <platform.h>
50
51#include "sound/compress_params.h"
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +053052#include "audio_bitstream_sm.h"
53
54//TODO: enable sw_decode if required
55#define USE_SWDECODE 0
56
57#if USE_SWDECODE
58#include "SoftMS11.h"
59#endif
Dhananjay Kumar01e921a2013-11-26 23:33:22 +053060
61#define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
62#define COMPRESS_OFFLOAD_NUM_FRAGMENTS 4
63/* ToDo: Check and update a proper value in msec */
64#define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 96
65#define COMPRESS_PLAYBACK_VOLUME_MAX 0x2000
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +053066#define STRING_LENGTH_OF_INTEGER 12
67
68static int send_offload_cmd_l(struct stream_out* out, int command);
69static int get_snd_codec_id(audio_format_t format);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +053070
71struct pcm_config pcm_config_deep_buffer = {
72 .channels = 2,
73 .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
74 .period_size = DEEP_BUFFER_OUTPUT_PERIOD_SIZE,
75 .period_count = DEEP_BUFFER_OUTPUT_PERIOD_COUNT,
76 .format = PCM_FORMAT_S16_LE,
77 .start_threshold = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
78 .stop_threshold = INT_MAX,
79 .avail_min = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
80};
81
82struct pcm_config pcm_config_low_latency = {
83 .channels = 2,
84 .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
85 .period_size = LOW_LATENCY_OUTPUT_PERIOD_SIZE,
86 .period_count = LOW_LATENCY_OUTPUT_PERIOD_COUNT,
87 .format = PCM_FORMAT_S16_LE,
88 .start_threshold = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
89 .stop_threshold = INT_MAX,
90 .avail_min = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
91};
92
93struct pcm_config pcm_config_hdmi_multi = {
94 .channels = HDMI_MULTI_DEFAULT_CHANNEL_COUNT, /* changed when the stream is opened */
95 .rate = DEFAULT_OUTPUT_SAMPLING_RATE, /* changed when the stream is opened */
96 .period_size = HDMI_MULTI_PERIOD_SIZE,
97 .period_count = HDMI_MULTI_PERIOD_COUNT,
98 .format = PCM_FORMAT_S16_LE,
99 .start_threshold = 0,
100 .stop_threshold = INT_MAX,
101 .avail_min = 0,
102};
103
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +0530104inline int nextMultiple(int n, int m) {
105 return ((n/m) + 1) * m;
106}
Dhananjay Kumar01e921a2013-11-26 23:33:22 +0530107
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +0530108/*******************************************************************************
109Description: check for MS11 supported formats
110*******************************************************************************/
111//TODO: enable sw_decode if required
112#if USE_SWDECODE
113int is_ms11_supported_fromats(int format)
114{
115 ALOGVV("is_ms11_supported_fromats");
116 int main_format = format & AUDIO_FORMAT_MAIN_MASK;
117 if(((main_format == AUDIO_FORMAT_AAC) ||
118 (main_format == AUDIO_FORMAT_HE_AAC_V1) ||
119 (main_format == AUDIO_FORMAT_HE_AAC_V2) ||
120 (main_format == AUDIO_FORMAT_AC3) ||
121 (main_format == AUDIO_FORMAT_AC3_PLUS) ||
122 (main_format == AUDIO_FORMAT_EAC3))) {
123 return 1;
124 } else {
125 return 0;
126 }
127}
128#endif
Dhananjay Kumar01e921a2013-11-26 23:33:22 +0530129
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +0530130/*******************************************************************************
131Description: check if ac3 can played as pass through without MS11 decoder
132*******************************************************************************/
133//TODO: enable sw_decode if required
134#if USE_SWDECODE
135int can_ac3_passthrough_without_ms11(struct stream_out *out, int format)
136{
137 ALOGVV("can_ac3_passthrough_without_ms11");
138 int main_format = format & AUDIO_FORMAT_MAIN_MASK;
139 if(main_format == AUDIO_FORMAT_AC3) {
140 if(((out->hdmi_format == COMPRESSED) ||
141 (out->hdmi_format == AUTO_DEVICE_FORMAT) ||
142 (out->hdmi_format == COMPRESSED_CONVERT_EAC3_AC3) ||
143 (out->hdmi_format == COMPRESSED_CONVERT_ANY_AC3)) &&
144 ((out->spdif_format == COMPRESSED) ||
145 (out->spdif_format == AUTO_DEVICE_FORMAT) ||
146 (out->spdif_format == COMPRESSED_CONVERT_EAC3_AC3) ||
147 (out->spdif_format == COMPRESSED_CONVERT_ANY_AC3))) {
148 return 1;
149 }
150 }
151 return 0;
152}
153#endif
154
155/*******************************************************************************
156Description: get levels of buffering, interms of number of buffers
157*******************************************************************************/
158int get_buffering_factor(struct stream_out *out)
159{
160 ALOGVV("get_buffering_factor");
161 if((out->format == AUDIO_FORMAT_PCM_16_BIT) ||
162 (out->format == AUDIO_FORMAT_PCM_24_BIT))
163 return 1;
164 else
165 return NUM_OF_PERIODS;
166}
167
168/*******************************************************************************
169Description: get the buffer size based on format and device format type
170*******************************************************************************/
171void get_fragment_size_and_format(struct stream_out *out, int routeFormat, int *fragment_size,
172 int *fragment_count, int *format)
173{
174 ALOGV("get_fragment_size_and_format");
175
176 int frame_size = 0;
177 *format = out->format;
178 *fragment_count = NUM_OF_PERIODS;
179 switch(out->format) {
180 case AUDIO_FORMAT_PCM_16_BIT:
181 frame_size = PCM_16_BITS_PER_SAMPLE * out->channels;
182 /*TODO: do we need below calculation */
183 *fragment_size = nextMultiple(((frame_size * out->sample_rate * TIME_PER_BUFFER)/1000) + MIN_SIZE_FOR_METADATA , frame_size * 32);
184 break;
185 case AUDIO_FORMAT_PCM_24_BIT:
186 frame_size = PCM_24_BITS_PER_SAMPLE * out->channels;
187 *fragment_size = nextMultiple(((frame_size * out->sample_rate * TIME_PER_BUFFER)/1000) + MIN_SIZE_FOR_METADATA, frame_size * 32);
188 break;
189 case AUDIO_FORMAT_AAC:
190 case AUDIO_FORMAT_HE_AAC_V1:
191 case AUDIO_FORMAT_HE_AAC_V2:
192 case AUDIO_FORMAT_AAC_ADIF:
193 case AUDIO_FORMAT_AC3:
194 case AUDIO_FORMAT_AC3_DM:
195 case AUDIO_FORMAT_EAC3:
196 case AUDIO_FORMAT_EAC3_DM:
197 if(routeFormat == ROUTE_UNCOMPRESSED_MCH) {
198 frame_size = PCM_16_BITS_PER_SAMPLE * out->channels;
199 *fragment_size = nextMultiple(AC3_PERIOD_SIZE * out->channels + MIN_SIZE_FOR_METADATA, frame_size * 32);
200 *format = AUDIO_FORMAT_PCM_16_BIT;
201 } else if(routeFormat == ROUTE_UNCOMPRESSED) {
202 frame_size = PCM_16_BITS_PER_SAMPLE * 2;
203 *fragment_size = nextMultiple(AC3_PERIOD_SIZE * 2 + MIN_SIZE_FOR_METADATA, frame_size * 32);
204 *format = AUDIO_FORMAT_PCM_16_BIT;
205 } else {
206 *fragment_size = PERIOD_SIZE_COMPR;
207 }
208 break;
209 case AUDIO_FORMAT_DTS:
210 case AUDIO_FORMAT_DTS_LBR:
211 case AUDIO_FORMAT_MP3:
212 case AUDIO_FORMAT_WMA:
213 case AUDIO_FORMAT_WMA_PRO:
214 case AUDIO_FORMAT_MP2:
215 *fragment_size = PERIOD_SIZE_COMPR;
216 break;
217 default:
218 *fragment_size = PERIOD_SIZE_COMPR;
219 *format = out->format;
220 }
221
222 /*TODO: remove this if fragement count needs to be decided based on the format*/
223 *fragment_count = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
224 fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
225
226 ALOGV("fragment_size: %d, fragment_count: %d", *fragment_size, *fragment_count);
227 return;
228}
229
230/*******************************************************************************
231Description: buffer length updated to player
232*******************************************************************************/
233int get_buffer_length(struct stream_out *out)
234{
235 /* TODO: Do we need below */
236 ALOGV("get_buffer_length");
237 int buffer_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
238 switch(out->format) {
239 case AUDIO_FORMAT_PCM_16_BIT:
240 buffer_size = ((PCM_16_BITS_PER_SAMPLE * out->channels * out->sample_rate * TIME_PER_BUFFER)/1000);
241 break;
242 case AUDIO_FORMAT_PCM_24_BIT:
243 buffer_size = ((PCM_24_BITS_PER_SAMPLE * out->channels * out->sample_rate * TIME_PER_BUFFER)/1000);
244 break;
245 case AUDIO_FORMAT_AAC:
246 case AUDIO_FORMAT_HE_AAC_V1:
247 case AUDIO_FORMAT_HE_AAC_V2:
248 case AUDIO_FORMAT_AAC_ADIF:
249 buffer_size = AAC_BLOCK_PER_CHANNEL_MS11 * out->channels;
250 break;
251 case AUDIO_FORMAT_AC3:
252 case AUDIO_FORMAT_AC3_DM:
253 case AUDIO_FORMAT_EAC3:
254 case AUDIO_FORMAT_EAC3_DM:
255 buffer_size = AC3_BUFFER_SIZE;
256 break;
257 case AUDIO_FORMAT_DTS:
258 case AUDIO_FORMAT_DTS_LBR:
259 case AUDIO_FORMAT_MP3:
260 case AUDIO_FORMAT_WMA:
261 case AUDIO_FORMAT_WMA_PRO:
262 case AUDIO_FORMAT_MP2:
263 buffer_size = COMPR_INPUT_BUFFER_SIZE;
264 break;
265 default:
266 buffer_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
267 }
268
269 /*TODO: remove this if fragement count needs to be decided based on the format*/
270 buffer_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
271 return buffer_size;
272}
273
274/* TODO: Uncomment this when enabling A2DP
275 TODO: add support for the 24 bit playback*/
276#if 0
277/*******************************************************************************
278Description: fix up devices for supporting A2DP playback
279*******************************************************************************/
280void fixUpDevicesForA2DPPlayback(struct stream_out *out)
281{
282 ALOGVV("fixUpDevicesForA2DPPlayback");
283 if(out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
284 out->route_audio_to_a2dp = 1;
285 out->devices &= ~AUDIO_DEVICE_OUT_ALL_A2DP;
286 //TODO: add spdif and proxy
287 //out->devices &= ~AUDIO_DEVICE_OUT_SPDIF;
288 //out->devices |= AudioSystem::DEVICE_OUT_PROXY;
289 }
290}
291#endif
292
293/*******************************************************************************
294Description: open temp buffer so that meta data mode can be updated properly
295*******************************************************************************/
296int open_temp_buf_for_metadata(struct stream_out *out)
297{
298 ALOGV("%s", __func__);
299 if (out->write_temp_buf == NULL) {
300 /*Max Period size which is exposed by the compr driver
301 The value needs to be modified when the period size is modified*/
302 out->write_temp_buf = (char *) malloc(PLAYBACK_MAX_PERIOD_SIZE);
303 if (out->write_temp_buf == NULL) {
304 ALOGE("Memory allocation of temp buffer to write pcm to driver failed");
305 return -EINVAL;
306 }
307 }
308 return 0;
309}
310
311/*******************************************************************************
312Description: get index of handle based on device handle device
313*******************************************************************************/
314struct alsa_handle * get_handle_based_on_devices(struct stream_out *out, int handleDevices)
315{
316 ALOGVV("get_handle_based_on_devices");
317 struct listnode *node;
318 struct alsa_handle *handle = NULL;
319
320 list_for_each(node, &out->session_list) {
321 handle = node_to_item(node, struct alsa_handle, list);
322 if(handle->devices & handleDevices)
323 break;
324 }
325 return handle;
326}
327
328void reset_out_parameters(struct stream_out *out) {
329
330 out->hdmi_format = UNCOMPRESSED;
331 out->spdif_format = UNCOMPRESSED;
332 out->decoder_type = UNCOMPRESSED ;
333 out->dec_conf_set = false;
334 out->min_bytes_req_to_dec = 0;
335 out->is_m11_file_mode = false;
336 out->dec_conf_bufLength = 0;
337 out->first_bitstrm_buf = false;
338 out->open_dec_route = false;
339 out->dec_format_devices = AUDIO_DEVICE_NONE;
340 out->open_dec_mch_route = false;
341 out->dec_mch_format_devices =AUDIO_DEVICE_NONE;
342 out->open_passt_route = false;
343 out->passt_format_devices = AUDIO_DEVICE_NONE;
344 out->sw_open_trans_route = false;
345 out->sw_trans_format_devices = AUDIO_DEVICE_NONE;
346 out->hw_open_trans_route =false ;
347 out->hw_trans_format_devices = AUDIO_DEVICE_NONE;
348 out->channel_status_set = false;
349 out->route_audio_to_a2dp = false;
350 out->is_ms11_file_playback_mode = false;
351 out->write_temp_buf = NULL;
352 return;
353}
354
355struct alsa_handle *get_alsa_handle() {
356
357 struct alsa_handle *handle;
358 handle = (struct alsa_handle *)calloc(1, sizeof(struct alsa_handle));
359 if(handle == NULL) {
360 ALOGE("%s calloc failed for handle", __func__);
361 } else {
362 ALOGE("%s handle is 0x%x", __func__,(uint32_t)handle);
363 }
364
365 return handle;
366}
367
368void free_alsa_handle(struct alsa_handle *handle) {
369
370 if(handle == NULL) {
371 ALOGE("%s Invalid handle", __func__);
372 }
373 free(handle);
374
375 return;
376}
377
378
379struct alsa_handle *get_handle_by_route_format(struct stream_out *out,
380 int route_format)
381{
382 struct listnode *node;
383 struct alsa_handle *handle = NULL;
384 ALOGV("%s",__func__);
385 list_for_each(node, &out->session_list) {
386 handle = node_to_item(node, struct alsa_handle, list);
387 if(handle->route_format & route_format) {
388 ALOGV("%s found handle %x",__func__,(uint32_t)handle);
389 break;
390 }
391 }
392
393 return handle;
394}
395
396/*******************************************************************************
397Description: get the format index
398*******************************************************************************/
399int get_format_index(int format)
400{
401 ALOGVV("get_format_index");
402 int idx = 0,i;
403 for(i=0; i<NUM_SUPPORTED_CODECS; i++) {
404 if(format == format_index[i][0]) {
405 idx = format_index[i][1];
406 break;
407 }
408 }
409 return idx;
410}
411
412int get_compress_available_space(struct alsa_handle *handle)
413{
414 uint32_t ret;
415 size_t avail = 0;
416 struct timespec tstamp;
417 ret = compress_get_hpointer(handle->compr,&avail, &tstamp);
418 if(ret!=0) {
419 ALOGE("cannot get available space\n");
420 } else
421 ret = (int)avail;
422 return ret;
423}
424
425
426/*******************************************************************************
427Description: validate if the decoder requires configuration to be set as first
428 buffer
429*******************************************************************************/
430int is_decoder_config_required(struct stream_out *out)
431{
432 ALOGVV("is_decoder_config_required");
433 int main_format = out->format & AUDIO_FORMAT_MAIN_MASK;
434 uint32_t i;
435 if(!out->is_ms11_file_playback_mode)
436 return 0;
437 for(i=0; i<sizeof(decodersRequireConfig)/sizeof(int); i++)
438 if(main_format == decodersRequireConfig[i])
439 return 1;
440 return 0;
441}
442
443/*******************************************************************************
444Description: query if input buffering mode require
445*******************************************************************************/
446int is_input_buffering_mode_reqd(struct stream_out *out)
447{
448 ALOGVV("is_input_buffering_mode_reqd");
449 if((out->decoder_type == SW_PASSTHROUGH) ||
450 (out->decoder_type == DSP_PASSTHROUGH))
451 return 1;
452 else
453 return 0;
454}
455
456
457
458/*******************************************************************************
459Description: update use case and routing flags
460*******************************************************************************/
461void update_decode_type_and_routing_states(struct stream_out *out)
462{
463 ALOGV("%s", __func__);
464
465 int format_index = get_format_index(out->format);
466 int decodeType, idx;
467
468 out->open_dec_route = false;
469 out->open_dec_mch_route = false;
470 out->open_passt_route = false;
471 out->sw_open_trans_route = false;
472 out->hw_open_trans_route = false;
473 out->dec_format_devices = out->devices;
474 out->dec_mch_format_devices = AUDIO_DEVICE_NONE;
475 out->passt_format_devices = AUDIO_DEVICE_NONE;
476 out->sw_trans_format_devices = AUDIO_DEVICE_NONE;
477 out->hw_trans_format_devices = AUDIO_DEVICE_NONE;
478 out->decoder_type = 0;
479
480//TODO: enable sw_decode if required
481#if USE_SWDECODE
482 if(is_ms11_supported_fromats(out->format))
483 out->use_ms11_decoder = true;
484#endif
485
486 ALOGV("format_index: %d devices %x", format_index,out->devices);
487 if(out->devices & AUDIO_DEVICE_OUT_SPDIF) {
488 decodeType = usecase_docode_hdmi_spdif[NUM_STATES_FOR_EACH_DEVICE_FMT*format_index]
489 [out->spdif_format];
490 ALOGV("SPDIF: decoderType: %d", decodeType);
491 out->decoder_type = decodeType;
492 for(idx=0; idx<NUM_DECODE_PATH; idx++) {
493 if(route_to_driver[idx][DECODER_TYPE_IDX] == decodeType) {
494 switch(route_to_driver[idx][ROUTE_FORMAT_IDX]) {
495 case ROUTE_UNCOMPRESSED:
496 ALOGVV("ROUTE_UNCOMPRESSED");
497 ALOGVV("SPDIF opened with stereo decode");
498 out->open_dec_route = true;
499 break;
500 case ROUTE_UNCOMPRESSED_MCH:
501 ALOGVV("ROUTE_UNCOMPRESSED_MCH");
502 ALOGVV("SPDIF opened with multichannel decode");
503 out->open_dec_mch_route = true;
504 out->dec_format_devices &= ~AUDIO_DEVICE_OUT_SPDIF;
505 out->dec_mch_format_devices |= AUDIO_DEVICE_OUT_SPDIF;
506 break;
507 case ROUTE_COMPRESSED:
508 ALOGVV("ROUTE_COMPRESSED");
509 out->open_passt_route = true;
510 out->dec_format_devices &= ~AUDIO_DEVICE_OUT_SPDIF;
511 out->passt_format_devices = AUDIO_DEVICE_OUT_SPDIF;
512 break;
513 case ROUTE_DSP_TRANSCODED_COMPRESSED:
514 ALOGVV("ROUTE_DSP_TRANSCODED_COMPRESSED");
515 out->hw_open_trans_route = true;
516 out->hw_trans_format_devices = AUDIO_DEVICE_OUT_SPDIF;
517 break;
518 case ROUTE_SW_TRANSCODED_COMPRESSED:
519 ALOGVV("ROUTE_SW_TRANSCODED_COMPRESSED");
520 out->sw_open_trans_route = true;
521 out->dec_format_devices &= ~AUDIO_DEVICE_OUT_SPDIF;
522 out->sw_trans_format_devices = AUDIO_DEVICE_OUT_SPDIF;
523 break;
524 default:
525 ALOGW("INVALID ROUTE for SPDIF, decoderType %d, routeFormat %d",
526 decodeType, route_to_driver[idx][ROUTE_FORMAT_IDX]);
527 break;
528 }
529 }
530 }
531 }
532 if(out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
533 decodeType = usecase_docode_hdmi_spdif[NUM_STATES_FOR_EACH_DEVICE_FMT*format_index]
534 [out->hdmi_format];
535 ALOGV("HDMI: decoderType: %d", decodeType);
536 out->decoder_type |= decodeType;
537 for(idx=0; idx<NUM_DECODE_PATH; idx++) {
538 if(route_to_driver[idx][DECODER_TYPE_IDX] == decodeType) {
539 switch(route_to_driver[idx][ROUTE_FORMAT_IDX]) {
540 case ROUTE_UNCOMPRESSED:
541 ALOGVV("ROUTE_UNCOMPRESSED");
542 ALOGVV("HDMI opened with stereo decode");
543 out->open_dec_route = true;
544 break;
545 case ROUTE_UNCOMPRESSED_MCH:
546 ALOGVV("ROUTE_UNCOMPRESSED_MCH");
547 ALOGVV("HDMI opened with multichannel decode");
548 out->open_dec_mch_route = true;
549 out->dec_format_devices &= ~AUDIO_DEVICE_OUT_AUX_DIGITAL;
550 out->dec_mch_format_devices |= AUDIO_DEVICE_OUT_AUX_DIGITAL;
551 break;
552 case ROUTE_COMPRESSED:
553 ALOGVV("ROUTE_COMPRESSED");
554 out->open_passt_route = true;
555 out->dec_format_devices &= ~AUDIO_DEVICE_OUT_AUX_DIGITAL;
556 out->passt_format_devices |= AUDIO_DEVICE_OUT_AUX_DIGITAL;
557 break;
558 case ROUTE_DSP_TRANSCODED_COMPRESSED:
559 ALOGVV("ROUTE_DSP_TRANSCODED_COMPRESSED");
560 out->hw_open_trans_route = true;
561 out->hw_trans_format_devices |= AUDIO_DEVICE_OUT_AUX_DIGITAL;
562 break;
563 case ROUTE_SW_TRANSCODED_COMPRESSED:
564 ALOGVV("ROUTE_SW_TRANSCODED_COMPRESSED");
565 out->sw_open_trans_route = true;
566 out->dec_format_devices &= ~AUDIO_DEVICE_OUT_AUX_DIGITAL;
567 out->sw_trans_format_devices |= AUDIO_DEVICE_OUT_AUX_DIGITAL;
568 break;
569 default:
570 ALOGW("INVALID ROUTE for HDMI, decoderType %d, routeFormat %d",
571 decodeType, route_to_driver[idx][ROUTE_FORMAT_IDX]);
572 break;
573 }
574 }
575 }
576 }
577 if(out->devices & ~(AUDIO_DEVICE_OUT_AUX_DIGITAL |
578 AUDIO_DEVICE_OUT_SPDIF)) {
579 decodeType = usecase_decode_format[NUM_STATES_FOR_EACH_DEVICE_FMT*format_index];
580 ALOGV("Other Devices: decoderType: %d", decodeType);
581 out->decoder_type |= decodeType;
582 for(idx=0; idx<NUM_DECODE_PATH; idx++) {
583 if(route_to_driver[idx][DECODER_TYPE_IDX] == decodeType) {
584 switch(route_to_driver[idx][ROUTE_FORMAT_IDX]) {
585 case ROUTE_UNCOMPRESSED:
586 ALOGVV("ROUTE_UNCOMPRESSED");
587 ALOGVV("Other Devices opened with stereo decode");
588 out->open_dec_route = true;
589 break;
590 case ROUTE_UNCOMPRESSED_MCH:
591 ALOGVV("ROUTE_UNCOMPRESSED_MCH");
592 ALOGVV("Other Devices opened with multichannel decode");
593 out->open_dec_mch_route = true;
594 out->dec_format_devices &= ~(out->devices &
595 ~(AUDIO_DEVICE_OUT_SPDIF |
596 AUDIO_DEVICE_OUT_AUX_DIGITAL));
597 out->dec_mch_format_devices |= (out->devices &
598 ~(AUDIO_DEVICE_OUT_SPDIF |
599 AUDIO_DEVICE_OUT_AUX_DIGITAL));
600 break;
601 default:
602 ALOGW("INVALID ROUTE for Other Devices, decoderType %d, routeFormat %d",
603 decodeType, route_to_driver[idx][ROUTE_FORMAT_IDX]);
604 break;
605 }
606 }
607 }
608 }
609}
610
611/*******************************************************************************
612Description: update handle states
613*******************************************************************************/
614int update_alsa_handle_state(struct stream_out *out)
615{
616 ALOGV("%s", __func__);
617
618 struct alsa_handle *handle = NULL;
619 struct listnode *node;
620
621 if(out->open_dec_route) {
622 if((handle = get_alsa_handle())== NULL)
623 goto error;
624 list_add_tail(&out->session_list, &handle->list);
625 handle->route_format = ROUTE_UNCOMPRESSED;
626 handle->devices = out->dec_format_devices;
627 handle->usecase = platform_get_usecase(USECASE_AUDIO_PLAYBACK_OFFLOAD);
628 handle->out = out;
629 handle->cmd_pending = false;
630 ALOGD("open_dec_route: routeformat: %d, devices: 0x%x: "
631 ,handle->route_format, handle->devices);
632 }
633 if(out->open_dec_mch_route) {
634 if((handle = get_alsa_handle())== NULL)
635 goto error;
636 list_add_tail(&out->session_list, &handle->list);
637 handle->route_format = ROUTE_UNCOMPRESSED_MCH;
638 handle->devices = out->dec_mch_format_devices;
639 handle->usecase = platform_get_usecase(USECASE_AUDIO_PLAYBACK_OFFLOAD);
640 handle->out = out;
641 handle->cmd_pending = false;
642 ALOGD("OpenMCHDecodeRoute: routeformat: %d, devices: 0x%x: "
643 ,handle->route_format, handle->devices);
644 }
645 if(out->open_passt_route) {
646 if((handle = get_alsa_handle())== NULL)
647 goto error;
648 list_add_tail(&out->session_list, &handle->list);
649 handle->route_format = ROUTE_COMPRESSED;
650 handle->devices = out->passt_format_devices;
651 handle->usecase = platform_get_usecase(USECASE_AUDIO_PLAYBACK_OFFLOAD);
652 handle->out = out;
653 handle->cmd_pending = false;
654 ALOGD("open_passt_route: routeformat: %d, devices: 0x%x: "
655 ,handle->route_format, handle->devices);
656 }
657 if(out->sw_open_trans_route) {
658 if((handle = get_alsa_handle())== NULL)
659 goto error;
660 handle->route_format = ROUTE_SW_TRANSCODED_COMPRESSED;
661 handle->devices = out->sw_trans_format_devices;
662 handle->usecase = platform_get_usecase(USECASE_AUDIO_PLAYBACK_OFFLOAD);
663 handle->out = out;
664 handle->cmd_pending = false;
665 ALOGD("OpenTranscodeRoute: routeformat: %d, devices: 0x%x: "
666 ,handle->route_format, handle->devices);
667 }
668 if(out->hw_open_trans_route) {
669 if((handle = get_alsa_handle())== NULL)
670 goto error;
671 handle->route_format = ROUTE_DSP_TRANSCODED_COMPRESSED;
672 handle->devices = out->hw_trans_format_devices;
673 handle->usecase = platform_get_usecase(USECASE_AUDIO_PLAYBACK_OFFLOAD);
674 handle->out = out;
675 handle->cmd_pending = false;
676 ALOGD("OpenTranscodeRoute: routeformat: %d, devices: 0x%x: "
677 ,handle->route_format, handle->devices);
678 }
679
680return 0;
681
682error:
683 list_for_each(node, &out->session_list) {
684 handle = node_to_item(node, struct alsa_handle, list);
685 free_alsa_handle(handle);
686 }
687
688 return -ENOMEM;
689}
690
691/*******************************************************************************
692Description: setup input path
693*******************************************************************************/
694int allocate_internal_buffers(struct stream_out *out)
695{
696 ALOGV("%s",__func__);
697 int ret = 0;
698 int main_format = out->format & AUDIO_FORMAT_MAIN_MASK;
699
700 /*
701 setup the bitstream state machine
702 */
703 out->bitstrm = ( struct audio_bitstream_sm *)calloc(1,
704 sizeof(struct audio_bitstream_sm));
705 if(!audio_bitstream_init(out->bitstrm, get_buffering_factor(out))) {
706 ALOGE("%s Unable to allocate bitstream buffering for MS11",__func__);
707 free(out->bitstrm);
708 out->bitstrm = NULL;
709 return -EINVAL;
710 }
711
712 if(is_input_buffering_mode_reqd(out))
713 audio_bitstream_start_input_buffering_mode(out->bitstrm);
714
715 /*
716 setup the buffering data required for decode to start
717 AAC_ADIF would require worst case frame size before decode starts
718 other decoder formats handles the partial data, hence threshold is zero.
719 */
720
721 if(main_format == AUDIO_FORMAT_AAC_ADIF)
722 out->min_bytes_req_to_dec = AAC_BLOCK_PER_CHANNEL_MS11*out->channels-1;
723 else
724 out->min_bytes_req_to_dec = 0;
725
726 ret = open_temp_buf_for_metadata(out);
727 if(ret < 0) {
728 free(out->bitstrm);
729 out->bitstrm = NULL;
730 }
731 out->buffer_size = get_buffer_length(out);
732
733 return ret;
734}
735
736/*******************************************************************************
737Description: setup input path
738*******************************************************************************/
739int free_internal_buffers(struct stream_out *out)
740{
741 if(out->bitstrm) {
742 free(out->bitstrm);
743 out->bitstrm = NULL;
744 }
745
746 if(out->write_temp_buf) {
747 free(out->write_temp_buf);
748 out->write_temp_buf = NULL;
749 }
750
751 if(out->dec_conf_buf) {
752 free(out->dec_conf_buf);
753 out->dec_conf_buf = NULL;
754 }
755 return 0;
756}
757
758/*******************************************************************************
759Description: open MS11 instance
760*******************************************************************************/
761//TODO: enable sw_decode if required
762#if USE_SWDECODE
763static int open_ms11_instance(struct stream_out *out)
764{
765 ALOGV("openMS11Instance");
766 int32_t formatMS11;
767 int main_format = out->format & AUDIO_FORMAT_MAIN_MASK;
768 out->ms11_decoder = get_soft_ms11();
769 if(!out->ms11_decoder) {
770 ALOGE("Could not resolve all symbols Required for MS11");
771 return -EINVAL;
772 }
773 /*
774 MS11 created
775 */
776 if(initialize_ms11_function_pointers(out->ms11_decoder) == false) {
777 ALOGE("Could not resolve all symbols Required for MS11");
778 free_soft_ms11(out->ms11_decoder);
779 return -EINVAL;
780 }
781 /*
782 update format
783 */
784 if((main_format == AUDIO_FORMAT_AC3) ||
785 (main_format == AUDIO_FORMAT_EAC3)) {
786 /*TODO: who wil setCOMPRESSED_CONVERT_AC3_ASSOC */
787 if (out->spdif_format == COMPRESSED_CONVERT_AC3_ASSOC)
788 formatMS11 = FORMAT_DOLBY_DIGITAL_PLUS_MAIN_ASSOC;
789 else
790 formatMS11 = FORMAT_DOLBY_DIGITAL_PLUS_MAIN;
791 } else
792 formatMS11 = FORMAT_DOLBY_PULSE_MAIN;
793 /*
794 set the use case to the MS11 decoder and open the stream for decoding
795 */
796 if(ms11_set_usecase_and_open_stream_with_mode(out->ms11_decoder,
797 formatMS11, out->channels, out->sample_rate,
798 out->is_m11_file_mode)) {
799 ALOGE("SetUseCaseAndOpen MS11 failed");
800 free_soft_ms11(out->ms11_decoder);
801 return EINVAL;
802 }
803 if(is_decoder_config_required(out) && out->dec_conf_buf && out->dec_conf_bufLength) {
804 if(ms11_set_aac_config(out->ms11_decoder, (unsigned char *)out->dec_conf_buf,
805 out->dec_conf_bufLength) == true) {
806 out->dec_conf_set = true;
807 }
808 }
809
810 return 0;
811}
812#endif
813/*******************************************************************************
814Description: copy input to internal buffer
815*******************************************************************************/
816void copy_bitstream_internal_buffer(struct audio_bitstream_sm *bitstrm,
817 char *buffer, size_t bytes)
818{
819 // copy bitstream to internal buffer
820 audio_bitstream_copy_to_internal_buffer(bitstrm, (char *)buffer, bytes);
821#ifdef DEBUG
822 dumpInputOutput(INPUT, buffer, bytes, 0);
823#endif
824}
825
826/*******************************************************************************
827Description: set decoder config
828*******************************************************************************/
829//TODO: enable sw_decode if required
830#if USE_SWDECODE
831int setDecodeConfig(struct stream_out *out, char *buffer, size_t bytes)
832{
833 ALOGV("%s ", __func__);
834
835 int main_format = out->format & AUDIO_FORMAT_MAIN_MASK;
836 if(!out->dec_conf_set) {
837 if(main_format == AUDIO_FORMAT_AAC ||
838 main_format == AUDIO_FORMAT_HE_AAC_V1 ||
839 main_format == AUDIO_FORMAT_AAC_ADIF ||
840 main_format == AUDIO_FORMAT_HE_AAC_V2) {
841 if(out->ms11_decoder != NULL) {
842 if(ms11_set_aac_config(out->ms11_decoder,(unsigned char *)buffer,
843 bytes) == false) {
844 ALOGE("AAC decoder config fail");
845 return 0;
846 }
847 }
848 }
849
850 out->dec_conf_bufLength = bytes;
851 if(out->dec_conf_buf)
852 free(out->dec_conf_buf);
853
854 out->dec_conf_buf = malloc(out->dec_conf_bufLength);
855 memcpy(out->dec_conf_buf,
856 buffer,
857 out->dec_conf_bufLength);
858 out->dec_conf_set = true;
859 }
860 out->dec_conf_set = true;
861 return bytes;
862}
863#endif
864
865//TODO: enable sw_decode if required
866#if USE_SWDECODE
867int validate_sw_free_space(struct stream_out* out, int bytes_consumed_in_decode, int *pcm_2ch_len,
868 int *pcm_mch_len, int *passthru_len, int *transcode_len, bool *wait_for_write_done) {
869
870 struct alsa_handle *handle = NULL;
871 char *bufPtr;
872 int copy_output_buffer_size;
873
874 *pcm_2ch_len = *pcm_mch_len = *passthru_len = *transcode_len = *wait_for_write_done = 0;
875
876 if(out->decoder_type & SW_DECODE) {
877 bufPtr = audio_bitstream_get_output_buffer_write_ptr(out->bitstrm,
878 PCM_2CH_OUT);
879 /*TODO: there is chance of illegale access if ms11 output exceeds bitstream
880 output buffer boudary */
881 copy_output_buffer_size = ms11_copy_output_from_ms11buf(out->ms11_decoder,
882 PCM_2CH_OUT,
883 bufPtr);
884 handle = get_handle_by_route_format(out, ROUTE_UNCOMPRESSED);
885 if(handle == NULL) {
886 ALOGE("%s Invalid handle", __func__);
887 return -EINVAL;
888 }
889 if(get_compress_available_space(handle) < copy_output_buffer_size) {
890 handle->cmd_pending = true;
891 *wait_for_write_done = true;
892 }
893 *pcm_2ch_len = copy_output_buffer_size;
894
895 }
896 if(out->decoder_type & SW_DECODE_MCH) {
897 bufPtr=audio_bitstream_get_output_buffer_write_ptr(out->bitstrm,
898 PCM_MCH_OUT);
899 copy_output_buffer_size = ms11_copy_output_from_ms11buf(out->ms11_decoder,
900 PCM_MCH_OUT,
901 bufPtr);
902 handle = get_handle_by_route_format(out, ROUTE_UNCOMPRESSED_MCH);
903 if(handle == NULL) {
904 ALOGE("%s Invalid handle", __func__);
905 return -EINVAL;
906 }
907
908 if(get_compress_available_space(handle) < copy_output_buffer_size) {
909 handle->cmd_pending = true;
910 *wait_for_write_done = true;
911 }
912 *pcm_mch_len = copy_output_buffer_size;
913 }
914 if(out->decoder_type & SW_PASSTHROUGH) {
915 bufPtr = audio_bitstream_get_output_buffer_write_ptr(out->bitstrm, COMPRESSED_OUT);
916 copy_output_buffer_size = bytes_consumed_in_decode;
917 memcpy(bufPtr, audio_bitstream_get_input_buffer_ptr(out->bitstrm), copy_output_buffer_size);
918
919 handle = get_handle_by_route_format(out, ROUTE_COMPRESSED);
920 if(handle == NULL) {
921 ALOGE("%s Invalid handle", __func__);
922 return -EINVAL;
923 }
924
925 if(get_compress_available_space(handle) < copy_output_buffer_size) {
926 handle->cmd_pending = true;
927 *wait_for_write_done = true;
928 }
929 *passthru_len = copy_output_buffer_size;
930 }
931 if(out->decoder_type & SW_TRANSCODE) {
932 bufPtr = audio_bitstream_get_output_buffer_write_ptr(out->bitstrm,
933 TRANSCODE_OUT);
934 copy_output_buffer_size = ms11_copy_output_from_ms11buf(out->bitstrm,
935 COMPRESSED_OUT,
936 bufPtr);
937 handle = get_handle_by_route_format(out, ROUTE_SW_TRANSCODED_COMPRESSED);
938 if(handle == NULL) {
939 ALOGE("%s Invalid handle", __func__);
940 return -EINVAL;
941 }
942 if(get_compress_available_space(handle) < copy_output_buffer_size) {
943 handle->cmd_pending = true;
944 *wait_for_write_done = true;
945 }
946 *transcode_len = copy_output_buffer_size;
947 }
948 return 0;
949}
950#endif
951
952int validate_hw_free_space(struct stream_out *out, int bytes_consumed_in_decode, int *pcm_2ch_len,
953 int *pcm_mch_len, int *passthru_len, int *transcode_len, bool *wait_for_write_done) {
954
955 struct alsa_handle *handle = NULL;
956 char *bufPtr;
957 int copy_output_buffer_size;
958 *pcm_2ch_len = *pcm_mch_len = *passthru_len = *transcode_len = *wait_for_write_done = 0;
959 if(out->decoder_type & DSP_DECODE) {
960 ALOGVV("DSP_DECODE");
961 bufPtr = audio_bitstream_get_output_buffer_write_ptr(out->bitstrm,
962 PCM_MCH_OUT);
963 copy_output_buffer_size = bytes_consumed_in_decode;
964 memcpy(bufPtr, audio_bitstream_get_input_buffer_ptr(out->bitstrm),
965 copy_output_buffer_size);
966 ALOGVV("%s bytes_consumed %d out bufPtr %x, pcm_mch_out_buf_size%d",
967 __func__,bytes_consumed_in_decode,bufPtr,
968 out->bitstrm->pcm_mch_out_buf_size);
969 handle = get_handle_by_route_format(out, ROUTE_UNCOMPRESSED);/*TODO: revisit */
970 if(handle == NULL) {
971 ALOGE("%s Invalid handle", __func__);
972 return -EINVAL;
973 }
974 if(get_compress_available_space(handle) < copy_output_buffer_size) {
975 handle->cmd_pending = true;
976 *wait_for_write_done = true;
977 /*reset input buffer pointer as flinger will resend the data back */
978 audio_bitstream_set_input_buffer_write_ptr(out->bitstrm,
979 -copy_output_buffer_size);
980 *pcm_mch_len = copy_output_buffer_size;
981 }
982 else
983 *pcm_mch_len = copy_output_buffer_size;
984 }
985 if(out->decoder_type & DSP_PASSTHROUGH) {
986 ALOGVV("DSP_PASSTHROUGH");
987 bufPtr = audio_bitstream_get_output_buffer_write_ptr(out->bitstrm, COMPRESSED_OUT);
988 copy_output_buffer_size = bytes_consumed_in_decode;
989 memcpy(bufPtr, audio_bitstream_get_input_buffer_ptr(out->bitstrm), copy_output_buffer_size);
990 handle = get_handle_by_route_format(out, ROUTE_COMPRESSED);
991 if(handle == NULL) {
992 ALOGE("%s Invalid handle", __func__);
993 return -EINVAL;
994 }
995 if(get_compress_available_space(handle) < copy_output_buffer_size) {
996 handle->cmd_pending = true;
997 *wait_for_write_done = true;
998 *passthru_len = copy_output_buffer_size;
999 /*reset input buffer pointer as flinger will resend the data back */
1000 audio_bitstream_set_input_buffer_ptr(out->bitstrm, -copy_output_buffer_size);
1001 }
1002 else
1003 *passthru_len = copy_output_buffer_size;
1004 }
1005 /*TODO: handle DSP Transcode usecase */
1006 return 0;
1007}
1008
1009int update_bitstrm_pointers(struct stream_out *out, int pcm_2ch_len,
1010 int pcm_mch_len, int passthru_len, int transcode_len) {
1011
1012 if(out->decoder_type & SW_DECODE) {
1013 audio_bitstream_set_output_buffer_write_ptr(out->bitstrm, PCM_2CH_OUT,
1014 pcm_2ch_len);
1015
1016 }
1017 if(out->decoder_type & SW_DECODE_MCH || out->decoder_type & DSP_DECODE) {
1018 audio_bitstream_set_output_buffer_write_ptr(out->bitstrm, PCM_MCH_OUT, pcm_mch_len);
1019 }
1020 if(out->decoder_type & SW_PASSTHROUGH || out->decoder_type & DSP_PASSTHROUGH) {
1021 audio_bitstream_set_output_buffer_write_ptr(out->bitstrm, COMPRESSED_OUT, passthru_len);
1022 }
1023 if(out->decoder_type & SW_TRANSCODE) {
1024 audio_bitstream_set_output_buffer_write_ptr(out->bitstrm,
1025 TRANSCODE_OUT,
1026 transcode_len);
1027 }
1028 return 0;
1029}
1030
1031/*TODO correct it */
1032static int configure_compr(struct stream_out *out,
1033 struct alsa_handle *handle) {
1034 handle->compr_config.codec = (struct snd_codec *)
1035 calloc(1, sizeof(struct snd_codec));
1036 handle->compr_config.codec->id =
1037 get_snd_codec_id(out->format); /*TODO: correct this based on format*/
1038 handle->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
1039 handle->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
1040 handle->compr_config.codec->sample_rate =
1041 compress_get_alsa_rate(out->sample_rate);
1042 handle->compr_config.codec->bit_rate = out->compr_config.codec->bit_rate;
1043 handle->compr_config.codec->ch_in =
1044 popcount(out->channel_mask);
1045 handle->compr_config.codec->ch_out = handle->compr_config.codec->ch_in;
Dhananjay Kumar5a553e42013-12-03 23:06:49 +05301046 handle->compr_config.codec->format = out->compr_config.codec->format;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301047 memcpy(&handle->compr_config.codec->options,
1048 &out->compr_config.codec->options,
1049 sizeof(union snd_codec_options));
1050 return 0;
1051}
1052
1053/*TODO: do we need to apply volume at the session open*/
1054static int set_compress_volume(struct alsa_handle *handle, int left, int right)
1055{
1056
1057 struct audio_device *adev = handle->out->dev;
1058 struct mixer_ctl *ctl;
1059 int volume[2];
1060
1061 char mixer_ctl_name[44]; // max length of name is 44 as defined
1062 char device_id[STRING_LENGTH_OF_INTEGER+1];
1063
1064 memset(mixer_ctl_name, 0, sizeof(mixer_ctl_name));
1065 strlcpy(mixer_ctl_name, "Compress Playback Volume", sizeof(mixer_ctl_name));
1066
1067 memset(device_id, 0, sizeof(device_id));
1068 snprintf(device_id, "%d", handle->device_id, sizeof(device_id));
1069
1070 strlcat(mixer_ctl_name, device_id, sizeof(mixer_ctl_name));
1071
1072 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1073 if (!ctl) {
1074 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1075 __func__, mixer_ctl_name);
1076 return -EINVAL;
1077 }
1078 volume[0] = (int)(left * COMPRESS_PLAYBACK_VOLUME_MAX);
1079 volume[1] = (int)(right * COMPRESS_PLAYBACK_VOLUME_MAX);
1080 mixer_ctl_set_array(ctl, volume, sizeof(volume)/sizeof(volume[0]));
1081
1082 return 0;
1083
1084}
1085
1086/*******************************************************************************
1087Description: software decode handling
1088*******************************************************************************/
1089//TODO: enable sw_decode if required
1090#if USE_SWDECODE
1091static int sw_decode(struct stream_out *out,
1092 char *buffer,
1093 size_t bytes,
1094 size_t *bytes_consumed,
1095 bool *continueDecode)
1096{
1097 /* bytes pending to be decoded in current buffer*/
1098 bool wait_for_write_done = false;
1099 int bytes_pending_for_decode = 0;
1100 /* bytes consumed in current write buffer */
1101 int total_bytes_consumed = 0;
1102 size_t copyBytesMS11 = 0;
1103 size_t bytes_consumed_in_decode = 0;
1104 size_t copy_output_buffer_size = 0;
1105 uint32_t outSampleRate = out->sample_rate;
1106 uint32_t outChannels = out->channels;
1107 char * bufPtr;
1108 int pcm_2ch_len, pcm_mch_len, passthru_len, transcode_len;
1109 struct alsa_handle *handle = NULL;
1110
1111 ALOGVV("sw Decode");
1112 // eos handling
1113 if(bytes == 0) {
1114 if(out->format == AUDIO_FORMAT_AAC_ADIF)
1115 audio_bitstream_append_silence_internal_buffer(out->bitstrm,
1116 out->min_bytes_req_to_dec,0x0);
1117 else
1118 return false;
1119 }
1120 /*
1121 check for sync word, if present then configure MS11 for fileplayback mode
1122 OFF. This is specifically done to handle Widevine usecase, in which the
1123 ADTS HEADER is not stripped off by the Widevine parser
1124 */
1125 if(out->first_bitstrm_buf == true) {
1126 uint16_t uData = (*((char *)buffer) << 8) + *((char *)buffer + 1) ;
1127 if(ADTS_HEADER_SYNC_RESULT == (uData & ADTS_HEADER_SYNC_MASK)) {
1128 ALOGD("Sync word found hence configure MS11 in file_playback Mode OFF");
1129 free_soft_ms11(out->ms11_decoder);
1130 out->is_m11_file_mode = false;
1131 open_ms11_instance(out);
1132 }
1133 out->first_bitstrm_buf = false;
1134 }
1135 //decode
1136 if(out->decoder_type == SW_PASSTHROUGH) {
1137 /*TODO: check if correct */
1138 bytes_consumed_in_decode = audio_bitstream_get_size(out->bitstrm);
1139 } else {
1140 if(audio_bitstream_sufficient_buffer_to_decode(out->bitstrm,
1141 out->min_bytes_req_to_dec) == true) {
1142 bufPtr = audio_bitstream_get_input_buffer_ptr(out->bitstrm);
1143 copyBytesMS11 = audio_bitstream_get_size(out->bitstrm);
1144 ms11_copy_bitstream_to_ms11_inpbuf(out->ms11_decoder, bufPtr,copyBytesMS11);
1145 bytes_consumed_in_decode = ms11_stream_decode(out->ms11_decoder,
1146 &outSampleRate, &outChannels);
1147 }
1148 }
1149
1150 if((out->sample_rate != outSampleRate) || (out->channels != outChannels)) {
1151 ALOGD("Change in sample rate. New sample rate: %d", outSampleRate);
1152 out->sample_rate = outSampleRate;
1153 out->channels = outChannels;
1154 handle = get_handle_by_route_format(out, ROUTE_UNCOMPRESSED);
1155 if(handle !=NULL) {
1156 configure_compr(out, handle);
1157 handle->compr = compress_open(SOUND_CARD, handle->device_id,
1158 COMPRESS_IN, &handle->compr_config);
1159 if (handle->compr && !is_compress_ready(handle->compr)) {
1160 ALOGE("%s: %s", __func__, compress_get_error(handle->compr));
1161 compress_close(handle->compr);
1162 handle->compr = NULL;
1163 }
1164 if (out->offload_callback)
1165 compress_nonblock(handle->compr, out->non_blocking);
1166
1167 set_compress_volume(handle, out->left_volume, out->right_volume);
1168 }
1169
1170 handle = get_handle_by_route_format(out, ROUTE_UNCOMPRESSED_MCH);
1171 if(handle !=NULL) {
1172 configure_compr(out, handle);
1173 handle->compr = compress_open(SOUND_CARD, handle->device_id,
1174 COMPRESS_IN, &handle->compr_config);
1175 if (handle->compr && !is_compress_ready(handle->compr)) {
1176 ALOGE("%s: %s", __func__, compress_get_error(handle->compr));
1177 compress_close(handle->compr);
1178 handle->compr = NULL;
1179 }
1180 if (out->offload_callback)
1181 compress_nonblock(handle->compr, out->non_blocking);
1182 set_compress_volume(handle, out->left_volume, out->right_volume);
1183 out->channel_status_set = false;
1184 }
1185 }
1186
1187
1188 validate_sw_free_space(out, bytes_consumed_in_decode, &pcm_2ch_len, &pcm_mch_len,
1189 &passthru_len, &transcode_len, &wait_for_write_done);
1190
1191 if(wait_for_write_done && out->non_blocking) {
1192 send_offload_cmd_l(out, OFFLOAD_CMD_WAIT_FOR_BUFFER);
1193 *continueDecode = false;
1194 *bytes_consumed = 0;
1195 return 0;
1196 } else {
1197 update_bitstrm_pointers(out, pcm_2ch_len, pcm_mch_len,
1198 passthru_len, transcode_len);
1199 audio_bitstream_copy_residue_to_start(out->bitstrm, bytes_consumed_in_decode);
1200 *bytes_consumed = bytes_consumed_in_decode;
1201 }
1202
1203 copy_output_buffer_size = pcm_2ch_len + pcm_mch_len + passthru_len + transcode_len;
1204 if(copy_output_buffer_size &&
1205 audio_bitstream_sufficient_buffer_to_decode(out->bitstrm, out->min_bytes_req_to_dec) == true) {
1206 *continueDecode = true;
1207 return 0;
1208 }
1209 return 0;
1210}
1211#endif
1212
1213/*******************************************************************************
1214Description: dsp decode handling
1215*******************************************************************************/
1216static bool dsp_decode(struct stream_out *out, char *buffer, size_t bytes,
1217 size_t *bytes_consumed, bool *continueDecode)
1218{
1219 char *bufPtr;
1220 size_t bytes_consumed_in_decode = 0;
1221
1222 bool wait_for_write_done = false;
1223 int pcm_2ch_len, pcm_mch_len, passthru_len, transcode_len;
1224
1225 ALOGVV("dsp_decode");
1226 // decode
1227 {
1228 bytes_consumed_in_decode = audio_bitstream_get_size(out->bitstrm);
1229 }
1230 // handle change in sample rate
1231 {
1232 }
1233 //TODO: check if the copy of the buffers can be avoided
1234 /* can be removed as its not required for dsp decode usecase */
1235 *continueDecode = false;
1236 validate_hw_free_space(out, bytes_consumed_in_decode, &pcm_2ch_len, &pcm_mch_len,
1237 &passthru_len, &transcode_len, &wait_for_write_done);
1238
1239 if(wait_for_write_done && out->non_blocking) {
1240 send_offload_cmd_l(out, OFFLOAD_CMD_WAIT_FOR_BUFFER);
1241 *bytes_consumed = 0;
1242 return 0;
1243 } else {
1244 update_bitstrm_pointers(out, pcm_2ch_len, pcm_mch_len,
1245 passthru_len, transcode_len);
1246 audio_bitstream_copy_residue_to_start(out->bitstrm, bytes_consumed_in_decode);
1247 *bytes_consumed = bytes_consumed_in_decode;
1248 ALOGV("%s bytes_consumed_in_decode =%d",__func__,bytes_consumed_in_decode);
1249 }
1250
1251 return 0;
1252}
1253
1254static bool decode(struct stream_out *out, char * buffer, size_t bytes,
1255 size_t *bytes_consumed, bool *continuedecode)
1256{
1257 ALOGV("decode");
1258 bool continueDecode = false;
1259 int ret = 0;
1260
1261 // TODO: enable software decode if required
1262 /*if (out->use_ms11_decoder) {
1263 ret = sw_decode(out, buffer, bytes,
1264 bytes_consumed, continuedecode);
1265
1266 // set channel status
1267 // Set the channel status after first frame decode/transcode
1268 //TODO: set the SPDIF channel status bits
1269 if(out->channel_status_set == false)
1270 setSpdifchannel_status(
1271 audio_bitstream_get_output_buffer_ptr(out->bitstrm, COMPRESSED_OUT),
1272 bytes, AUDIO_PARSER_CODEC_AC3);
1273
1274 } else */{
1275 ret = dsp_decode(out, buffer, bytes,
1276 bytes_consumed, continuedecode);
1277 // set channel status
1278 // Set the channel status after first frame decode/transcode
1279 //TODO: set the SPDIF channel status bits
1280/* if(out->channel_status_set == false)
1281 setSpdifchannel_status(
1282 audio_bitstream_get_output_buffer_ptr(out->bitstrm, COMPRESSED_OUT),
1283 bytes, AUDIO_PARSER_CODEC_DTS);
1284*/
1285 }
1286 return ret;
1287}
1288
1289/*******************************************************************************
1290Description: fixup sample rate and channel info based on format
1291*******************************************************************************/
1292void fixupSampleRateChannelModeMS11Formats(struct stream_out *out)
1293{
1294 ALOGV("fixupSampleRateChannelModeMS11Formats");
1295 int main_format = out->format & AUDIO_FORMAT_MAIN_MASK;
1296 int subFormat = out->format & AUDIO_FORMAT_SUB_MASK;
1297/*
1298NOTE: For AAC, the output of MS11 is 48000 for the sample rates greater than
1299 24000. The samples rates <= 24000 will be at their native sample rate
1300 For AC3, the PCM output is at its native sample rate if the decoding is
1301 single decode usecase for MS11.
1302*/
1303 if(main_format == AUDIO_FORMAT_AAC ||
1304 main_format == AUDIO_FORMAT_HE_AAC_V1 ||
1305 main_format == AUDIO_FORMAT_HE_AAC_V2 ||
1306 main_format == AUDIO_FORMAT_AAC_ADIF) {
1307 out->sample_rate = out->sample_rate > 24000 ? 48000 : out->sample_rate;
1308 out->channels = 6;
1309 } else if (main_format == AUDIO_FORMAT_AC3 ||
1310 main_format == AUDIO_FORMAT_EAC3) {
1311 /* transcode AC3/EAC3 44.1K to 48K AC3 for non dual-mono clips */
1312 if (out->sample_rate == 44100 &&
1313 (subFormat != AUDIO_FORMAT_DOLBY_SUB_DM) &&
1314 (out->spdif_format == COMPRESSED ||
1315 out->spdif_format == AUTO_DEVICE_FORMAT ||
1316 out->spdif_format == COMPRESSED_CONVERT_EAC3_AC3) &&
1317 (out->hdmi_format == UNCOMPRESSED ||
1318 out->hdmi_format == UNCOMPRESSED_MCH)) {
1319 out->sample_rate = 48000;
1320 out->spdif_format = COMPRESSED_CONVERT_AC3_ASSOC;
1321 } else if (out->sample_rate == 44100) {
1322 out->spdif_format = UNCOMPRESSED;
1323 }
1324 out->channels = 6;
1325 }
1326 ALOGD("ms11 format fixup: out->spdif_format %d, out->hdmi_format %d",
1327 out->spdif_format, out->hdmi_format);
1328}
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301329
1330static bool is_supported_format(audio_format_t format)
1331{
Dhananjay Kumar5a553e42013-12-03 23:06:49 +05301332 switch (format) {
1333 case AUDIO_FORMAT_PCM_16_BIT:
1334 case AUDIO_FORMAT_MP3:
1335 case AUDIO_FORMAT_AAC:
1336 case AUDIO_FORMAT_WMA:
1337 case AUDIO_FORMAT_WMA_PRO:
1338 case AUDIO_FORMAT_MP2:
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301339 return true;
Dhananjay Kumar5a553e42013-12-03 23:06:49 +05301340 default:
1341 ALOGE("%s: Unsupported audio format: %x", __func__, format);
1342 break;
1343 }
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301344
1345 return false;
1346}
1347
1348static int get_snd_codec_id(audio_format_t format)
1349{
1350 int id = 0;
1351
1352 switch (format) {
Dhananjay Kumar5a553e42013-12-03 23:06:49 +05301353 case AUDIO_FORMAT_PCM_16_BIT:
1354 id = SND_AUDIOCODEC_PCM;
1355 break;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301356 case AUDIO_FORMAT_MP3:
1357 id = SND_AUDIOCODEC_MP3;
1358 break;
1359 case AUDIO_FORMAT_AAC:
1360 id = SND_AUDIOCODEC_AAC;
1361 break;
Dhananjay Kumar5a553e42013-12-03 23:06:49 +05301362 case AUDIO_FORMAT_WMA:
1363 id = SND_AUDIOCODEC_WMA;
1364 break;
1365 case AUDIO_FORMAT_WMA_PRO:
1366 id = SND_AUDIOCODEC_WMA_PRO;
1367 break;
1368 case AUDIO_FORMAT_MP2:
1369 id = SND_AUDIOCODEC_MP2;
1370 break;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301371 default:
Dhananjay Kumar5a553e42013-12-03 23:06:49 +05301372 ALOGE("%s: Unsupported audio format %x", __func__, format);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301373 }
1374
1375 return id;
1376}
1377
1378/* must be called with hw device mutex locked */
1379static int read_hdmi_channel_masks(struct stream_out *out)
1380{
1381 int ret = 0;
1382 int channels = platform_edid_get_max_channels(out->dev->platform);
1383
1384 switch (channels) {
1385 /*
1386 * Do not handle stereo output in Multi-channel cases
1387 * Stereo case is handled in normal playback path
1388 */
1389 case 6:
1390 ALOGV("%s: HDMI supports 5.1", __func__);
1391 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1;
1392 break;
1393 case 8:
1394 ALOGV("%s: HDMI supports 5.1 and 7.1 channels", __func__);
1395 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1;
1396 out->supported_channel_masks[1] = AUDIO_CHANNEL_OUT_7POINT1;
1397 break;
1398 default:
1399 ALOGE("HDMI does not support multi channel playback");
1400 ret = -ENOSYS;
1401 break;
1402 }
1403 return ret;
1404}
1405
1406/* must be called with out->lock locked */
1407static int send_offload_cmd_l(struct stream_out* out, int command)
1408{
1409 struct offload_cmd *cmd = (struct offload_cmd *)calloc(1, sizeof(struct offload_cmd));
1410
1411 ALOGVV("%s %d", __func__, command);
1412
1413 cmd->cmd = command;
1414 list_add_tail(&out->offload_cmd_list, &cmd->node);
1415 pthread_cond_signal(&out->offload_cond);
1416 return 0;
1417}
1418
1419/* must be called iwth out->lock locked */
1420static void stop_compressed_output_l(struct stream_out *out)
1421{
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301422 struct listnode *node;
1423 struct alsa_handle *handle;
1424 bool is_compr_out = false;
1425
1426 ALOGV("%s", __func__);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301427 out->offload_state = OFFLOAD_STATE_IDLE;
1428 out->playback_started = 0;
1429 out->send_new_metadata = 1;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301430 list_for_each(node, &out->session_list) {
1431 handle = node_to_item(node, struct alsa_handle, list);
1432 if (handle->compr != NULL) {
1433 compress_stop(handle->compr);
1434 is_compr_out = true;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301435 }
1436 }
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301437 if (is_compr_out) {
1438 while (out->offload_thread_blocked)
1439 pthread_cond_wait(&out->cond, &out->lock);
1440 }
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301441}
1442
1443static void *offload_thread_loop(void *context)
1444{
1445 struct stream_out *out = (struct stream_out *) context;
1446 struct listnode *item;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301447 struct listnode *node;
1448 struct alsa_handle *handle;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301449
1450 out->offload_state = OFFLOAD_STATE_IDLE;
1451 out->playback_started = 0;
1452
1453 setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
1454 set_sched_policy(0, SP_FOREGROUND);
1455 prctl(PR_SET_NAME, (unsigned long)"Offload Callback", 0, 0, 0);
1456
1457 ALOGV("%s", __func__);
1458 pthread_mutex_lock(&out->lock);
1459 for (;;) {
1460 struct offload_cmd *cmd = NULL;
1461 stream_callback_event_t event;
1462 bool send_callback = false;
1463
1464 ALOGVV("%s offload_cmd_list %d out->offload_state %d",
1465 __func__, list_empty(&out->offload_cmd_list),
1466 out->offload_state);
1467 if (list_empty(&out->offload_cmd_list)) {
1468 ALOGV("%s SLEEPING", __func__);
1469 pthread_cond_wait(&out->offload_cond, &out->lock);
1470 ALOGV("%s RUNNING", __func__);
1471 continue;
1472 }
1473
1474 item = list_head(&out->offload_cmd_list);
1475 cmd = node_to_item(item, struct offload_cmd, node);
1476 list_remove(item);
1477
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301478 ALOGVV("%s STATE %d CMD %d",
1479 __func__, out->offload_state, cmd->cmd);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301480
1481 if (cmd->cmd == OFFLOAD_CMD_EXIT) {
1482 free(cmd);
1483 break;
1484 }
1485
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301486 if (list_empty(&out->session_list)) {
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301487 ALOGE("%s: Compress handle is NULL", __func__);
1488 pthread_cond_signal(&out->cond);
1489 continue;
1490 }
1491 out->offload_thread_blocked = true;
1492 pthread_mutex_unlock(&out->lock);
1493 send_callback = false;
1494 switch(cmd->cmd) {
1495 case OFFLOAD_CMD_WAIT_FOR_BUFFER:
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301496 list_for_each(node, &out->session_list) {
1497 handle = node_to_item(node, struct alsa_handle, list);
1498 if (handle->compr && handle->cmd_pending) {
1499 compress_wait(handle->compr, -1);
1500 handle->cmd_pending = false;
1501 }
1502 }
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301503 send_callback = true;
1504 event = STREAM_CBK_EVENT_WRITE_READY;
1505 break;
1506 case OFFLOAD_CMD_PARTIAL_DRAIN:
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301507 list_for_each(node, &out->session_list) {
1508 handle = node_to_item(node, struct alsa_handle, list);
1509 if (handle->compr) {
1510 compress_next_track(handle->compr);
1511 compress_partial_drain(handle->compr);
1512 }
1513 }
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301514 send_callback = true;
1515 event = STREAM_CBK_EVENT_DRAIN_READY;
1516 break;
1517 case OFFLOAD_CMD_DRAIN:
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301518 list_for_each(node, &out->session_list) {
1519 handle = node_to_item(node, struct alsa_handle, list);
1520 if (handle->compr) {
1521 compress_drain(handle->compr);
1522 }
1523 }
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301524 send_callback = true;
1525 event = STREAM_CBK_EVENT_DRAIN_READY;
1526 break;
1527 default:
1528 ALOGE("%s unknown command received: %d", __func__, cmd->cmd);
1529 break;
1530 }
1531 pthread_mutex_lock(&out->lock);
1532 out->offload_thread_blocked = false;
1533 pthread_cond_signal(&out->cond);
1534 if (send_callback) {
1535 out->offload_callback(event, NULL, out->offload_cookie);
1536 }
1537 free(cmd);
1538 }
1539
1540 pthread_cond_signal(&out->cond);
1541 while (!list_empty(&out->offload_cmd_list)) {
1542 item = list_head(&out->offload_cmd_list);
1543 list_remove(item);
1544 free(node_to_item(item, struct offload_cmd, node));
1545 }
1546 pthread_mutex_unlock(&out->lock);
1547
1548 return NULL;
1549}
1550
1551static int create_offload_callback_thread(struct stream_out *out)
1552{
1553 pthread_cond_init(&out->offload_cond, (const pthread_condattr_t *) NULL);
1554 list_init(&out->offload_cmd_list);
1555 pthread_create(&out->offload_thread, (const pthread_attr_t *) NULL,
1556 offload_thread_loop, out);
1557 return 0;
1558}
1559
1560static int destroy_offload_callback_thread(struct stream_out *out)
1561{
1562 pthread_mutex_lock(&out->lock);
1563 stop_compressed_output_l(out);
1564 send_offload_cmd_l(out, OFFLOAD_CMD_EXIT);
1565
1566 pthread_mutex_unlock(&out->lock);
1567 pthread_join(out->offload_thread, (void **) NULL);
1568 pthread_cond_destroy(&out->offload_cond);
1569
1570 return 0;
1571}
1572
1573static bool allow_hdmi_channel_config(struct audio_device *adev)
1574{
1575 struct listnode *node;
1576 struct audio_usecase *usecase;
1577 bool ret = true;
1578
1579 list_for_each(node, &adev->usecase_list) {
1580 usecase = node_to_item(node, struct audio_usecase, list);
1581 if (usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1582 /*
1583 * If voice call is already existing, do not proceed further to avoid
1584 * disabling/enabling both RX and TX devices, CSD calls, etc.
1585 * Once the voice call done, the HDMI channels can be configured to
1586 * max channels of remaining use cases.
1587 */
1588 if (usecase->id == USECASE_VOICE_CALL) {
1589 ALOGD("%s: voice call is active, no change in HDMI channels",
1590 __func__);
1591 ret = false;
1592 break;
1593 } else if (usecase->id == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
1594 ALOGD("%s: multi channel playback is active, "
1595 "no change in HDMI channels", __func__);
1596 ret = false;
1597 break;
1598 }
1599 }
1600 }
1601 return ret;
1602}
1603
1604static int check_and_set_hdmi_channels(struct audio_device *adev,
1605 unsigned int channels)
1606{
1607 struct listnode *node;
1608 struct audio_usecase *usecase;
1609
1610 /* Check if change in HDMI channel config is allowed */
1611 if (!allow_hdmi_channel_config(adev))
1612 return 0;
1613
1614 if (channels == adev->cur_hdmi_channels) {
1615 ALOGD("%s: Requested channels are same as current", __func__);
1616 return 0;
1617 }
1618
1619 platform_set_hdmi_channels(adev->platform, channels);
1620 adev->cur_hdmi_channels = channels;
1621
1622 /*
1623 * Deroute all the playback streams routed to HDMI so that
1624 * the back end is deactivated. Note that backend will not
1625 * be deactivated if any one stream is connected to it.
1626 */
1627 list_for_each(node, &adev->usecase_list) {
1628 usecase = node_to_item(node, struct audio_usecase, list);
1629 if (usecase->type == PCM_PLAYBACK &&
1630 usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1631 disable_audio_route(adev, usecase, true);
1632 }
1633 }
1634
1635 /*
1636 * Enable all the streams disabled above. Now the HDMI backend
1637 * will be activated with new channel configuration
1638 */
1639 list_for_each(node, &adev->usecase_list) {
1640 usecase = node_to_item(node, struct audio_usecase, list);
1641 if (usecase->type == PCM_PLAYBACK &&
1642 usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1643 enable_audio_route(adev, usecase, true);
1644 }
1645 }
1646
1647 return 0;
1648}
1649
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301650static int stop_output_stream(struct stream_out *out, struct alsa_handle *handle)
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301651{
1652 int i, ret = 0;
1653 struct audio_usecase *uc_info;
1654 struct audio_device *adev = out->dev;
1655
1656 ALOGV("%s: enter: usecase(%d: %s)", __func__,
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301657 handle->usecase, use_case_table[handle->usecase]);
1658 uc_info = get_usecase_from_list(adev, handle->usecase);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301659 if (uc_info == NULL) {
1660 ALOGE("%s: Could not find the usecase (%d) in the list",
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301661 __func__, handle->usecase);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301662 return -EINVAL;
1663 }
1664
1665 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD &&
1666 adev->visualizer_stop_output != NULL)
1667 adev->visualizer_stop_output(out->handle);
1668
1669 /* 1. Get and set stream specific mixer controls */
1670 disable_audio_route(adev, uc_info, true);
1671
1672 /* 2. Disable the rx device */
1673 disable_snd_device(adev, uc_info->out_snd_device, true);
1674
1675 list_remove(&uc_info->list);
1676 free(uc_info);
1677
1678 /* Must be called after removing the usecase from list */
1679 if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
1680 check_and_set_hdmi_channels(adev, DEFAULT_HDMI_OUT_CHANNELS);
1681
1682 ALOGV("%s: exit: status(%d)", __func__, ret);
1683 return ret;
1684}
1685
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301686int start_output_stream(struct stream_out *out, struct alsa_handle *handle)
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301687{
1688 int ret = 0;
1689 struct audio_usecase *uc_info;
1690 struct audio_device *adev = out->dev;
1691
1692 ALOGV("%s: enter: usecase(%d: %s) devices(%#x)",
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301693 __func__, handle->usecase, use_case_table[handle->usecase], handle->devices);
1694 handle->device_id = platform_get_pcm_device_id(handle->usecase, PCM_PLAYBACK);
1695 if (handle->device_id < 0) {
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301696 ALOGE("%s: Invalid PCM device id(%d) for the usecase(%d)",
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301697 __func__, handle->device_id, handle->usecase);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301698 ret = -EINVAL;
1699 goto error_config;
1700 }
1701
1702 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301703 uc_info->id = handle->usecase;
1704 uc_info->handle = handle;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301705 uc_info->type = PCM_PLAYBACK;
1706 uc_info->stream.out = out;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301707 uc_info->devices = handle->devices;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301708 uc_info->in_snd_device = SND_DEVICE_NONE;
1709 uc_info->out_snd_device = SND_DEVICE_NONE;
1710
1711 /* This must be called before adding this usecase to the list */
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301712 //if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
1713 // check_and_set_hdmi_channels(adev, out->config.channels);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301714
1715 list_add_tail(&adev->usecase_list, &uc_info->list);
1716
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301717 select_devices(adev, handle->usecase);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301718
1719 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301720 __func__, 0, handle->device_id);
1721 if (out->uc_strm_type != OFFLOAD_PLAYBACK_STREAM) {
1722 handle->compr = NULL;
1723 handle->pcm = pcm_open(SOUND_CARD, handle->device_id,
1724 PCM_OUT | PCM_MONOTONIC, &handle->config);
1725 if (handle->pcm && !pcm_is_ready(handle->pcm)) {
1726 ALOGE("%s: %s", __func__, pcm_get_error(handle->pcm));
1727 pcm_close(handle->pcm);
1728 handle->pcm = NULL;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301729 ret = -EIO;
1730 goto error_open;
1731 }
1732 } else {
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301733 handle->pcm = NULL;
1734 configure_compr(out, handle);
1735 handle->compr = compress_open(SOUND_CARD, handle->device_id,
1736 COMPRESS_IN, &handle->compr_config);
1737 if (handle->compr && !is_compress_ready(handle->compr)) {
1738 ALOGE("%s: %s", __func__, compress_get_error(handle->compr));
1739 compress_close(handle->compr);
1740 handle->compr = NULL;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301741 ret = -EIO;
1742 goto error_open;
1743 }
1744 if (out->offload_callback)
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301745 compress_nonblock(handle->compr, out->non_blocking);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301746
1747 if (adev->visualizer_start_output != NULL)
1748 adev->visualizer_start_output(out->handle);
1749 }
1750 ALOGV("%s: exit", __func__);
1751 return 0;
1752error_open:
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301753 stop_output_stream(out, handle);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301754error_config:
1755 return ret;
1756}
1757
1758static uint32_t out_get_sample_rate(const struct audio_stream *stream)
1759{
1760 struct stream_out *out = (struct stream_out *)stream;
1761
1762 return out->sample_rate;
1763}
1764
1765static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
1766{
1767 return -ENOSYS;
1768}
1769
1770static size_t out_get_buffer_size(const struct audio_stream *stream)
1771{
1772 struct stream_out *out = (struct stream_out *)stream;
1773
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301774 /*if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301775 return out->compr_config.fragment_size;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301776 */
1777 return (size_t)out->buffer_size;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301778
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301779 //return out->config.period_size * audio_stream_frame_size(stream);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301780}
1781
1782static uint32_t out_get_channels(const struct audio_stream *stream)
1783{
1784 struct stream_out *out = (struct stream_out *)stream;
1785
1786 return out->channel_mask;
1787}
1788
1789static audio_format_t out_get_format(const struct audio_stream *stream)
1790{
1791 struct stream_out *out = (struct stream_out *)stream;
1792
1793 return out->format;
1794}
1795
1796static int out_set_format(struct audio_stream *stream, audio_format_t format)
1797{
1798 return -ENOSYS;
1799}
1800
1801static int out_standby(struct audio_stream *stream)
1802{
1803 struct stream_out *out = (struct stream_out *)stream;
1804 struct audio_device *adev = out->dev;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301805 struct listnode *node;
1806 struct alsa_handle *handle;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301807
1808 ALOGV("%s: enter: usecase(%d: %s)", __func__,
1809 out->usecase, use_case_table[out->usecase]);
1810 if (out->usecase == USECASE_COMPRESS_VOIP_CALL) {
1811 /* Ignore standby in case of voip call because the voip output
1812 * stream is closed in adev_close_output_stream()
1813 */
1814 ALOGV("%s: Ignore Standby in VOIP call", __func__);
1815 return 0;
1816 }
1817
1818 pthread_mutex_lock(&out->lock);
1819 pthread_mutex_lock(&adev->lock);
1820 if (!out->standby) {
1821 out->standby = true;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301822 stop_compressed_output_l(out);
1823 out->gapless_mdata.encoder_delay = 0;
1824 out->gapless_mdata.encoder_padding = 0;
1825
1826 list_for_each(node, &out->session_list) {
1827 handle = node_to_item(node, struct alsa_handle, list);
1828 if (handle->compr != NULL) {
1829 compress_close(handle->compr);
1830 handle->compr = NULL;
1831 } else if (handle->pcm) {
1832 pcm_close(handle->pcm);
1833 handle->pcm = NULL;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301834 }
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301835 stop_output_stream(out, handle);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301836 }
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301837 }
1838 pthread_mutex_unlock(&adev->lock);
1839 pthread_mutex_unlock(&out->lock);
1840 ALOGV("%s: exit", __func__);
1841 return 0;
1842}
1843
1844static int out_dump(const struct audio_stream *stream, int fd)
1845{
1846 return 0;
1847}
1848
1849static int parse_compress_metadata(struct stream_out *out, struct str_parms *parms)
1850{
1851 int ret = 0;
1852 char value[32];
1853 struct compr_gapless_mdata tmp_mdata;
Dhananjay Kumar5a553e42013-12-03 23:06:49 +05301854 bool gapless_meta_set = true;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301855
1856 if (!out || !parms) {
1857 return -EINVAL;
1858 }
1859
1860 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES, value, sizeof(value));
1861 if (ret >= 0) {
1862 tmp_mdata.encoder_delay = atoi(value); //whats a good limit check?
1863 } else {
Dhananjay Kumar5a553e42013-12-03 23:06:49 +05301864 gapless_meta_set = false;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301865 }
1866
1867 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES, value, sizeof(value));
1868 if (ret >= 0) {
1869 tmp_mdata.encoder_padding = atoi(value);
1870 } else {
Dhananjay Kumar5a553e42013-12-03 23:06:49 +05301871 gapless_meta_set = false;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301872 }
1873
Dhananjay Kumar5a553e42013-12-03 23:06:49 +05301874 if (gapless_meta_set) {
1875 out->gapless_mdata = tmp_mdata;
1876 out->send_new_metadata = 1;
1877 ALOGV("%s new encoder delay %u and padding %u", __func__,
1878 out->gapless_mdata.encoder_delay, out->gapless_mdata.encoder_padding);
1879 }
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301880
Dhananjay Kumar5a553e42013-12-03 23:06:49 +05301881 if(out->format == AUDIO_FORMAT_WMA || out->format == AUDIO_FORMAT_WMA_PRO) {
1882 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_FORMAT_TAG, value, sizeof(value));
1883 if (ret >= 0) {
1884 out->compr_config.codec->format = atoi(value);
1885 }
1886 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BLOCK_ALIGN, value, sizeof(value));
1887 if (ret >= 0) {
1888 out->compr_config.codec->options.wma.super_block_align = atoi(value);
1889 }
1890 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BIT_PER_SAMPLE, value, sizeof(value));
1891 if (ret >= 0) {
1892 out->compr_config.codec->options.wma.bits_per_sample = atoi(value);
1893 }
1894 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_CHANNEL_MASK, value, sizeof(value));
1895 if (ret >= 0) {
1896 out->compr_config.codec->options.wma.channelmask = atoi(value);
1897 }
1898 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION, value, sizeof(value));
1899 if (ret >= 0) {
1900 out->compr_config.codec->options.wma.encodeopt = atoi(value);
1901 }
1902 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION1, value, sizeof(value));
1903 if (ret >= 0) {
1904 out->compr_config.codec->options.wma.encodeopt1 = atoi(value);
1905 }
1906 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION2, value, sizeof(value));
1907 if (ret >= 0) {
1908 out->compr_config.codec->options.wma.encodeopt2 = atoi(value);
1909 }
1910 ALOGV("WMA params: fmt %x, balgn %x, sr %d, chmsk %x, encop %x, op1 %x, op2 %x",
1911 out->compr_config.codec->format,
1912 out->compr_config.codec->options.wma.super_block_align,
1913 out->compr_config.codec->options.wma.bits_per_sample,
1914 out->compr_config.codec->options.wma.channelmask,
1915 out->compr_config.codec->options.wma.encodeopt,
1916 out->compr_config.codec->options.wma.encodeopt1,
1917 out->compr_config.codec->options.wma.encodeopt2);
1918 }
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301919 return 0;
1920}
1921
1922static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
1923{
1924 struct stream_out *out = (struct stream_out *)stream;
1925 struct audio_device *adev = out->dev;
1926 struct audio_usecase *usecase;
1927 struct listnode *node;
1928 struct str_parms *parms;
1929 char value[32];
1930 int ret, val = 0;
1931 bool select_new_device = false;
1932
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301933 ALOGD("%s: enter: kvpairs: %s", __func__, kvpairs);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05301934 parms = str_parms_create_str(kvpairs);
1935 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
1936 if (ret >= 0) {
1937 val = atoi(value);
1938 pthread_mutex_lock(&out->lock);
1939 pthread_mutex_lock(&adev->lock);
1940
1941 /*
1942 * When HDMI cable is unplugged the music playback is paused and
1943 * the policy manager sends routing=0. But the audioflinger
1944 * continues to write data until standby time (3sec).
1945 * As the HDMI core is turned off, the write gets blocked.
1946 * Avoid this by routing audio to speaker until standby.
1947 */
1948 if (out->devices == AUDIO_DEVICE_OUT_AUX_DIGITAL &&
1949 val == AUDIO_DEVICE_NONE) {
1950 val = AUDIO_DEVICE_OUT_SPEAKER;
1951 }
1952
1953 /*
1954 * select_devices() call below switches all the usecases on the same
1955 * backend to the new device. Refer to check_usecases_codec_backend() in
1956 * the select_devices(). But how do we undo this?
1957 *
1958 * For example, music playback is active on headset (deep-buffer usecase)
1959 * and if we go to ringtones and select a ringtone, low-latency usecase
1960 * will be started on headset+speaker. As we can't enable headset+speaker
1961 * and headset devices at the same time, select_devices() switches the music
1962 * playback to headset+speaker while starting low-lateny usecase for ringtone.
1963 * So when the ringtone playback is completed, how do we undo the same?
1964 *
1965 * We are relying on the out_set_parameters() call on deep-buffer output,
1966 * once the ringtone playback is ended.
1967 * NOTE: We should not check if the current devices are same as new devices.
1968 * Because select_devices() must be called to switch back the music
1969 * playback to headset.
1970 */
1971 if (val != 0) {
1972 out->devices = val;
1973
1974 if (!out->standby)
1975 select_devices(adev, out->usecase);
1976 }
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05301977//TODO:
1978//Get the device and device format mapping from the RoutingManager.
1979//Decide which streams need to be derouted and which need to opened/closed
1980//Update the respective device in each of the handles
1981#if 0
1982 if (out->uc_strm_type == OFFLOAD_PLAYBACK_STREAM) {
1983
1984 /* TODO get format form routing manager */
1985 update_decode_type_and_routing_states(out);
1986
1987 if(is_input_buffering_mode_reqd(out))
1988 audio_bitstream_start_input_buffering_mode(out->bitstrm);
1989 else
1990 audio_bitstream_stop_input_buffering_mode(out->bitstrm);
1991 /*
1992 For the runtime format change, close the device first to avoid any
1993 concurrent PCM + Compressed sessions on the same device.
1994 */
1995 close_handles_for_device_switch(out);
1996 if(!out->mopen_dec_route)
1997 handleCloseForDeviceSwitch(ROUTE_UNCOMPRESSED);
1998
1999 if(!out->mopen_dec_mch_route)
2000 handleCloseForDeviceSwitch(ROUTE_UNCOMPRESSED_MCH);
2001
2002 if(!out->mopen_passt_route)
2003 handleCloseForDeviceSwitch(ROUTE_COMPRESSED);
2004
2005 if(!msw_open_trans_route)
2006 handleCloseForDeviceSwitch(ROUTE_SW_TRANSCODED_COMPRESSED);
2007
2008 if(!mhw_open_trans_route)
2009 handleCloseForDeviceSwitch(ROUTE_DSP_TRANSCODED_COMPRESSED);
2010
2011 if(out->mopen_dec_route)
2012 handleSwitchAndOpenForDeviceSwitch(mdec_format_devices,
2013 ROUTE_UNCOMPRESSED);
2014 if(out->mopen_dec_mch_route)
2015 handleSwitchAndOpenForDeviceSwitch(mdec_mch_format_devices,
2016 ROUTE_UNCOMPRESSED_MCH);
2017 if(out->mopen_passt_route)
2018 handleSwitchAndOpenForDeviceSwitch(mpasst_format_devices,
2019 ROUTE_COMPRESSED);
2020 if(out->msw_open_trans_route)
2021 handleSwitchAndOpenForDeviceSwitch(msw_trans_format_devices,
2022 ROUTE_SW_TRANSCODED_COMPRESSED);
2023 if(out->mhw_open_trans_route)
2024 handleSwitchAndOpenForDeviceSwitch(mhw_trans_format_devices,
2025 ROUTE_DSP_TRANSCODED_COMPRESSED);
2026 }
2027#endif
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302028
2029 pthread_mutex_unlock(&adev->lock);
2030 pthread_mutex_unlock(&out->lock);
2031 }
2032
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302033 if (out->uc_strm_type == OFFLOAD_PLAYBACK_STREAM) {
Dhananjay Kumar5a553e42013-12-03 23:06:49 +05302034 ret = parse_compress_metadata(out, parms);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302035 }
2036
2037 str_parms_destroy(parms);
2038 ALOGV("%s: exit: code(%d)", __func__, ret);
2039 return ret;
2040}
2041
2042static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
2043{
2044 struct stream_out *out = (struct stream_out *)stream;
2045 struct str_parms *query = str_parms_create_str(keys);
2046 char *str;
2047 char value[256];
2048 struct str_parms *reply = str_parms_create();
2049 size_t i, j;
2050 int ret;
2051 bool first = true;
2052 ALOGV("%s: enter: keys - %s", __func__, keys);
2053 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
2054 if (ret >= 0) {
2055 value[0] = '\0';
2056 i = 0;
2057 while (out->supported_channel_masks[i] != 0) {
2058 for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
2059 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
2060 if (!first) {
2061 strlcat(value, "|", sizeof(value));
2062 }
2063 strlcat(value, out_channels_name_to_enum_table[j].name, sizeof(value));
2064 first = false;
2065 break;
2066 }
2067 }
2068 i++;
2069 }
2070 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
2071 str = str_parms_to_str(reply);
2072 }
2073 str_parms_destroy(query);
2074 str_parms_destroy(reply);
2075 ALOGV("%s: exit: returns - %s", __func__, str);
2076 return str;
2077}
2078
2079static uint32_t out_get_latency(const struct audio_stream_out *stream)
2080{
2081 struct stream_out *out = (struct stream_out *)stream;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302082 struct listnode *item;
2083 struct alsa_handle *handle;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302084
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302085 //TODO: decide based on the clip properties
2086 if (out->uc_strm_type == OFFLOAD_PLAYBACK_STREAM)
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302087 return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
2088
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302089 item = list_head(&out->session_list);
2090 handle = node_to_item(item, struct alsa_handle, list);
2091 if(!handle) {
2092 ALOGE("%s: error pcm handle NULL", __func__);
2093 return -EINVAL;
2094 }
2095
2096 return (handle->config.period_count * handle->config.period_size * 1000) /
2097 (handle->config.rate);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302098}
2099
2100static int out_set_volume(struct audio_stream_out *stream, float left,
2101 float right)
2102{
2103 struct stream_out *out = (struct stream_out *)stream;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302104 struct listnode *node;
2105 struct alsa_handle *handle;
2106 struct audio_device *adev = out->dev;
2107 int ret = -ENOSYS;
2108 ALOGV("%s", __func__);
2109 pthread_mutex_lock(&out->lock);
2110 list_for_each(node, &out->session_list) {
2111 handle = node_to_item(node, struct alsa_handle, list);
2112 if (handle->pcm && (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH)){
2113 /* only take left channel into account: the API is for stereo anyway */
2114 out->muted = (left == 0.0f);
2115 ret = 0;
2116 } else if (handle->compr) {
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302117
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302118 out->left_volume = left;
2119 out->right_volume = right;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302120
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302121 //ret = set_compress_volume(handle, left, right);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302122 }
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302123 }
2124 pthread_mutex_unlock(&out->lock);
2125
2126 return ret;
2127}
2128
2129static int write_data(struct stream_out *out, struct alsa_handle *handle,
2130 const void *buffer, int bytes) {
2131
2132 int ret = 0;
2133 if (out->uc_strm_type == OFFLOAD_PLAYBACK_STREAM) {
2134 ALOGV("%s: writing buffer (%d bytes) to compress device", __func__, bytes);
2135
2136 ret = compress_write(handle->compr, buffer, bytes);
2137 ALOGV("%s: writing buffer (%d bytes) to compress device returned %d",
2138 __func__, bytes, ret);
2139 /* TODO:disnable this if ms12 */
2140
2141 if (ret >= 0 && ret < (ssize_t)bytes) {
Aviral Guptafdb08f42013-12-21 00:33:47 -08002142 handle->cmd_pending = true;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302143 send_offload_cmd_l(out, OFFLOAD_CMD_WAIT_FOR_BUFFER);
2144 }
2145 return ret;
2146 } else {
2147 if (handle->pcm) {
2148 if (out->muted)
2149 memset((void *)buffer, 0, bytes);
2150 ALOGV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
2151 ret = pcm_write(handle->pcm, (void *)buffer, bytes);
2152 }
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302153 }
2154
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302155 if (ret != 0) {
2156 if ((handle && handle->pcm))
2157 ALOGE("%s: error %d - %s", __func__, ret, pcm_get_error(handle->pcm));
2158 out_standby(&out->stream.common);
2159 usleep(bytes * 1000000 / audio_stream_frame_size(&out->stream.common) /
2160 out_get_sample_rate(&out->stream.common));
2161 }
2162 return bytes;
2163}
2164
2165/*******************************************************************************
2166Description: render
2167*******************************************************************************/
2168size_t render_offload_data(struct stream_out *out, const void *buffer, size_t bytes)
2169{
2170 int ret =0;
2171 uint32_t renderedPcmBytes = 0;
2172 int fragment_size;
2173 uint32_t availableSize;
2174 int bytes_to_write = bytes;
2175 int renderType;
2176 /*int metadataLength = sizeof(out->output_meta_data);*/
2177 struct listnode *node;
2178 struct alsa_handle *handle;
2179
2180 ALOGV("%s", __func__);
2181
2182 list_for_each(node, &out->session_list) {
2183 handle = node_to_item(node, struct alsa_handle, list);
2184 if (out->send_new_metadata) {
2185 ALOGVV("send new gapless metadata");
2186 compress_set_gapless_metadata(handle->compr, &out->gapless_mdata);
2187 }
2188
2189 switch(handle->route_format) {
2190 case ROUTE_UNCOMPRESSED:
2191 ALOGVV("ROUTE_UNCOMPRESSED");
2192 renderType = PCM_2CH_OUT;
2193 break;
2194 case ROUTE_UNCOMPRESSED_MCH:
2195 ALOGVV("ROUTE_UNCOMPRESSED_MCH");
2196 renderType = PCM_MCH_OUT;
2197 break;
2198 case ROUTE_COMPRESSED:
2199 ALOGVV("ROUTE_COMPRESSED");
2200 renderType = COMPRESSED_OUT;
2201 break;
2202 case ROUTE_SW_TRANSCODED_COMPRESSED:
2203 ALOGVV("ROUTE_SW_TRANSCODED_COMPRESSED");
2204 renderType = TRANSCODE_OUT;
2205 break;
2206 case ROUTE_DSP_TRANSCODED_COMPRESSED:
2207 ALOGVV("ROUTE_DSP_TRANSCODED_COMPRESSED");
2208 continue;
2209 default:
2210 continue;
2211 };
2212
2213 fragment_size = handle->compr_config.fragment_size;
2214 /*TODO handle timestamp case */
2215#if USE_SWDECODE
2216 while(audio_bitstream_sufficient_sample_to_render(out->bitstrm,
2217 renderType, 1) == true) {
2218 availableSize = audio_bitstream_get_output_buffer_write_ptr(out->bitstrm, renderType) -
2219 audio_bitstream_get_output_buffer_ptr(out->bitstrm, renderType);
2220 buffer = audio_bitstream_get_output_buffer_ptr(out->bitstrm, renderType);
2221 bytes_to_write = availableSize;
2222
2223 TODO: meta data is only neded for TS mode
2224 out->output_meta_data.metadataLength = metadataLength;
2225 out->output_meta_data.bufferLength = (availableSize >=
2226 (fragment_size - metadataLength)) ?
2227 fragment_size - metadataLength :
2228 availableSize;
2229 bytes_to_write = metadataLength +out->output_meta_data.bufferLength;
2230 out->output_meta_data.timestamp = 0;
2231 memcpy(out->write_temp_buf, &out->output_meta_data, metadataLength);
2232 memcpy(out->write_temp_buf+metadataLength,
2233 audio_bitstream_get_output_buffer_ptr(out->bitstrm, renderType),
2234 out->output_meta_data.bufferLength);
2235 ret = write_data(out, handle, out->write_temp_buf, bytes_to_write);
2236#endif
2237
2238 ret = write_data(out, handle, buffer, bytes_to_write);
2239 ALOGD("write_data returned with %d", ret);
2240 if(ret < 0) {
2241 ALOGE("write_data returned ret < 0");
2242 return ret;
2243 } else {
2244 if (!out->playback_started) {
2245 compress_start(handle->compr);
2246 }
2247 /*TODO:Do we need this
2248 if(renderType == ROUTE_UNCOMPRESSED ||
2249 (renderType == ROUTE_UNCOMPRESSED_MCH && !out->open_dec_route)) {
2250 mFrameCount++;
2251 renderedPcmBytes += out->output_meta_data.bufferLength;
2252 }*/
2253 renderedPcmBytes += ret;
2254#if USE_SWDECODE
2255 /*iTODO: enable for MS11
2256 audio_bitstream_copy_residue_output_start(out->bitstrm, renderType,
2257 bytes_to_write);
2258 TODO:what if ret<bytes_to_write*/
2259#endif
2260 }
2261#if USE_SWDECODE
2262 }
2263#endif
2264 }
2265 out->playback_started = 1;
2266 out->offload_state = OFFLOAD_STATE_PLAYING;
2267 out->send_new_metadata = 0;
2268 return renderedPcmBytes;
2269}
2270
2271size_t render_pcm_data(struct stream_out *out, const void *buffer, size_t bytes)
2272{
2273 ALOGV("%s", __func__);
2274 size_t ret = 0;
2275 struct listnode *node;
2276 struct alsa_handle *handle;
2277 list_for_each(node, &out->session_list) {
2278 handle = node_to_item(node, struct alsa_handle, list);
2279 ALOGV("%s handle is 0x%x", __func__,(uint32_t)handle);
2280 ret = write_data(out, handle, buffer, bytes);
2281 }
2282 return ret;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302283}
2284
2285static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
2286 size_t bytes)
2287{
2288 struct stream_out *out = (struct stream_out *)stream;
2289 struct audio_device *adev = out->dev;
2290 ssize_t ret = 0;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302291 struct listnode *node;
2292 bool continueDecode;
2293 struct alsa_handle *handle;
2294 size_t bytes_consumed;
2295 size_t total_bytes_consumed = 0;
2296
2297 ALOGV("%s bytes =%d", __func__, bytes);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302298
2299 pthread_mutex_lock(&out->lock);
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302300
2301//TODO: handle a2dp
2302/* if (mRouteAudioToA2dp &&
2303 mA2dpUseCase == AudioHardwareALSA::USECASE_NONE) {
2304 a2dpRenderingControl(A2DP_RENDER_SETUP);
2305 }
2306*/
2307 /* TODO: meta data comes in set_parameter it will be passed in compre_open
2308 for all format exxce ms11 format
2309 and for ms11 it will be set sdecode fucntion while opneing ms11 instance
2310 hence below piece of code is no required*/
2311 /*
2312 if(!out->dec_conf_set && is_decoder_config_required(out)) {
2313 if (setDecodeConfig(out, (char *)buffer, bytes))
2314 ALOGD("decoder configuration set");
2315 }
2316 */
2317
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302318 if (out->standby) {
2319 out->standby = false;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302320 list_for_each(node, &out->session_list) {
2321 handle = node_to_item(node, struct alsa_handle, list);
2322 pthread_mutex_lock(&adev->lock);
2323 ret = start_output_stream(out, handle);
2324 pthread_mutex_unlock(&adev->lock);
2325 /* ToDo: If use case is compress offload should return 0 */
2326 if (ret != 0) {
2327 out->standby = true;
2328 goto exit;
2329 }
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302330 }
2331 }
2332
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302333 if (out->uc_strm_type == OFFLOAD_PLAYBACK_STREAM) {
2334#if USE_SWDECODE
2335 //TODO: Enable for MS11
2336 copy_bitstream_internal_buffer(out->bitstrm, (char *)buffer, bytes);
2337 //DO check if timestamp mode handle partial buffer
2338 do {
2339
2340 bytes_consumed = 0;
2341 ret = decode(out, (char *)buffer, bytes, &bytes_consumed, &continueDecode);
2342 if(ret < 0)
2343 goto exit;
2344 /*TODO: check for return size from write when ms11 is removed*/
2345 render_offload_data(out, continueDecode);
2346 total_bytes_consumed += bytes_consumed;
2347
2348 } while(continueDecode == true);
2349#endif
2350#if 0
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302351 ALOGVV("%s: writing buffer (%d bytes) to compress device", __func__, bytes);
2352 if (out->send_new_metadata) {
2353 ALOGVV("send new gapless metadata");
2354 compress_set_gapless_metadata(out->compr, &out->gapless_mdata);
2355 out->send_new_metadata = 0;
2356 }
2357
2358 ret = compress_write(out->compr, buffer, bytes);
2359 ALOGVV("%s: writing buffer (%d bytes) to compress device returned %d", __func__, bytes, ret);
2360 if (ret >= 0 && ret < (ssize_t)bytes) {
2361 send_offload_cmd_l(out, OFFLOAD_CMD_WAIT_FOR_BUFFER);
2362 }
2363 if (!out->playback_started) {
2364 compress_start(out->compr);
2365 out->playback_started = 1;
2366 out->offload_state = OFFLOAD_STATE_PLAYING;
2367 }
2368 pthread_mutex_unlock(&out->lock);
2369 return ret;
2370 } else {
2371 if (out->pcm) {
2372 if (out->muted)
2373 memset((void *)buffer, 0, bytes);
2374 ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
2375 ret = pcm_write(out->pcm, (void *)buffer, bytes);
2376 if (ret == 0)
2377 out->written += bytes / (out->config.channels * sizeof(short));
2378 }
2379 }
2380
2381exit:
2382 pthread_mutex_unlock(&out->lock);
2383
2384 if (ret != 0) {
2385 if (out->pcm)
2386 ALOGE("%s: error %d - %s", __func__, ret, pcm_get_error(out->pcm));
2387 out_standby(&out->stream.common);
2388 usleep(bytes * 1000000 / audio_stream_frame_size(&out->stream.common) /
2389 out_get_sample_rate(&out->stream.common));
2390 }
2391 return bytes;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302392#endif
2393 ret = render_offload_data(out, buffer, bytes);
2394 total_bytes_consumed = ret;
2395 } else {
2396 ret = render_pcm_data(out, buffer, bytes);
2397 total_bytes_consumed = ret;
2398 }
2399
2400exit:
2401 pthread_mutex_unlock(&out->lock);
2402 ALOGV("total_bytes_consumed %d",total_bytes_consumed);
2403 return total_bytes_consumed;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302404}
2405
2406static int out_get_render_position(const struct audio_stream_out *stream,
2407 uint32_t *dsp_frames)
2408{
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302409 struct listnode *node;
2410 struct alsa_handle *handle;
2411 struct stream_out *out = (struct stream_out *)stream;
2412 struct audio_device *adev = out->dev;
2413 *dsp_frames = 0;
2414 ALOGV("%s", __func__);
2415 pthread_mutex_lock(&out->lock);
2416 if ((out->uc_strm_type == OFFLOAD_PLAYBACK_STREAM) && (dsp_frames != NULL)) {
2417 list_for_each(node, &out->session_list) {
2418 handle = node_to_item(node, struct alsa_handle, list);
2419 if ((handle && handle->compr &&
2420 handle->route_format != ROUTE_DSP_TRANSCODED_COMPRESSED)){
2421 compress_get_tstamp(handle->compr, (unsigned long *)dsp_frames,
2422 &out->sample_rate);
2423 ALOGV("%s rendered frames %d sample_rate %d",
2424 __func__, *dsp_frames, out->sample_rate);
2425 }
2426 pthread_mutex_unlock(&out->lock);
2427 return 0;
2428 }
2429 }
2430 else {
2431 pthread_mutex_unlock(&out->lock);
2432 return -EINVAL;
2433 }
2434 return 0;
2435#if 0
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302436 struct stream_out *out = (struct stream_out *)stream;
2437 *dsp_frames = 0;
2438 if ((out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) && (dsp_frames != NULL)) {
2439 pthread_mutex_lock(&out->lock);
2440 if (out->compr != NULL) {
2441 compress_get_tstamp(out->compr, (unsigned long *)dsp_frames,
2442 &out->sample_rate);
2443 ALOGVV("%s rendered frames %d sample_rate %d",
2444 __func__, *dsp_frames, out->sample_rate);
2445 }
2446 pthread_mutex_unlock(&out->lock);
2447 return 0;
2448 } else
2449 return -EINVAL;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302450#endif
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302451}
2452
2453static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
2454{
2455 return 0;
2456}
2457
2458static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
2459{
2460 return 0;
2461}
2462
2463static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
2464 int64_t *timestamp)
2465{
2466 return -EINVAL;
2467}
2468
2469static int out_get_presentation_position(const struct audio_stream_out *stream,
2470 uint64_t *frames, struct timespec *timestamp)
2471{
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302472 struct listnode *node;
2473 struct alsa_handle *handle;
2474 struct stream_out *out = (struct stream_out *)stream;
2475 struct audio_device *adev = out->dev;
2476 *frames = 0;
2477 ALOGV("%s", __func__);
2478 pthread_mutex_lock(&out->lock);
2479 if ((frames != NULL)) {
2480 list_for_each(node, &out->session_list) {
2481 handle = node_to_item(node, struct alsa_handle, list);
2482 if ((handle && handle->compr &&
2483 handle->route_format != ROUTE_DSP_TRANSCODED_COMPRESSED)){
2484 compress_get_tstamp(handle->compr, (unsigned long *)frames,
2485 &out->sample_rate);
2486 clock_gettime(CLOCK_MONOTONIC, timestamp);
2487 ALOGV("%s rendered frames %d sample_rate %d",
2488 __func__, *frames, out->sample_rate);
2489 }
2490 else if (handle->pcm) {
2491 size_t avail;
2492 if (pcm_get_htimestamp(handle->pcm, &avail, timestamp) == 0) {
2493 size_t kernel_buffer_size = handle->config.period_size * handle->config.period_count;
2494 int64_t signed_frames = out->written - kernel_buffer_size + avail;
2495 // This adjustment accounts for buffering after app processor.
2496 // It is based on estimated DSP latency per use case, rather than exact.
2497 signed_frames -=
2498 (platform_render_latency(handle->usecase) * out->sample_rate / 1000000LL);
2499
2500 // It would be unusual for this value to be negative, but check just in case ...
2501 if (signed_frames >= 0) {
2502 *frames = signed_frames;
2503 }
2504 }
2505 }
2506
2507 }
2508 }
2509 pthread_mutex_unlock(&out->lock);
2510 return -EINVAL;
2511#if 0
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302512 struct stream_out *out = (struct stream_out *)stream;
2513 int ret = -1;
2514 unsigned long dsp_frames;
2515
2516 pthread_mutex_lock(&out->lock);
2517
2518 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2519 if (out->compr != NULL) {
2520 compress_get_tstamp(out->compr, &dsp_frames,
2521 &out->sample_rate);
2522 ALOGVV("%s rendered frames %ld sample_rate %d",
2523 __func__, dsp_frames, out->sample_rate);
2524 *frames = dsp_frames;
2525 ret = 0;
2526 /* this is the best we can do */
2527 clock_gettime(CLOCK_MONOTONIC, timestamp);
2528 }
2529 } else {
2530 if (out->pcm) {
2531 size_t avail;
2532 if (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0) {
2533 size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
2534 int64_t signed_frames = out->written - kernel_buffer_size + avail;
2535 // This adjustment accounts for buffering after app processor.
2536 // It is based on estimated DSP latency per use case, rather than exact.
2537 signed_frames -=
2538 (platform_render_latency(out->usecase) * out->sample_rate / 1000000LL);
2539
2540 // It would be unusual for this value to be negative, but check just in case ...
2541 if (signed_frames >= 0) {
2542 *frames = signed_frames;
2543 ret = 0;
2544 }
2545 }
2546 }
2547 }
2548
2549 pthread_mutex_unlock(&out->lock);
2550
2551 return ret;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302552#endif
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302553}
2554
2555static int out_set_callback(struct audio_stream_out *stream,
2556 stream_callback_t callback, void *cookie)
2557{
2558 struct stream_out *out = (struct stream_out *)stream;
2559
2560 ALOGV("%s", __func__);
2561 pthread_mutex_lock(&out->lock);
2562 out->offload_callback = callback;
2563 out->offload_cookie = cookie;
2564 pthread_mutex_unlock(&out->lock);
2565 return 0;
2566}
2567
2568static int out_pause(struct audio_stream_out* stream)
2569{
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302570 struct listnode *node;
2571 struct alsa_handle *handle;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302572 struct stream_out *out = (struct stream_out *)stream;
2573 int status = -ENOSYS;
2574 ALOGV("%s", __func__);
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302575 pthread_mutex_lock(&out->lock);
2576 list_for_each(node, &out->session_list) {
2577 handle = node_to_item(node, struct alsa_handle, list);
2578 if (handle->compr != NULL && out->offload_state ==
2579 OFFLOAD_STATE_PLAYING) {
2580 status = compress_pause(handle->compr);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302581 out->offload_state = OFFLOAD_STATE_PAUSED;
2582 }
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302583 }
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302584 pthread_mutex_unlock(&out->lock);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302585 return status;
2586}
2587
2588static int out_resume(struct audio_stream_out* stream)
2589{
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302590 struct listnode *node;
2591 struct alsa_handle *handle;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302592 struct stream_out *out = (struct stream_out *)stream;
2593 int status = -ENOSYS;
2594 ALOGV("%s", __func__);
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302595 pthread_mutex_lock(&out->lock);
2596 list_for_each(node, &out->session_list) {
2597 handle = node_to_item(node, struct alsa_handle, list);
2598 status = 0;
2599 if (handle->compr != NULL && out->offload_state ==
2600 OFFLOAD_STATE_PAUSED) {
2601 status = compress_resume(handle->compr);
2602 out->offload_state = OFFLOAD_STATE_PLAYING;
2603 }
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302604 }
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302605 pthread_mutex_unlock(&out->lock);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302606 return status;
2607}
2608
2609static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
2610{
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302611 struct listnode *node;
2612 struct alsa_handle *handle;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302613 struct stream_out *out = (struct stream_out *)stream;
2614 int status = -ENOSYS;
2615 ALOGV("%s", __func__);
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302616 pthread_mutex_lock(&out->lock);
2617 list_for_each(node, &out->session_list) {
2618 handle = node_to_item(node, struct alsa_handle, list);
2619 status = 0;
2620 if (handle->compr != NULL) {
2621 if (type == AUDIO_DRAIN_EARLY_NOTIFY)
2622 status = send_offload_cmd_l(out, OFFLOAD_CMD_PARTIAL_DRAIN);
2623 else
2624 status = send_offload_cmd_l(out, OFFLOAD_CMD_DRAIN);
2625 }
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302626 }
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302627 pthread_mutex_unlock(&out->lock);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302628 return status;
2629}
2630
2631static int out_flush(struct audio_stream_out* stream)
2632{
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302633 struct listnode *node;
2634 struct alsa_handle *handle;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302635 struct stream_out *out = (struct stream_out *)stream;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302636 int status = -ENOSYS;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302637 ALOGV("%s", __func__);
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302638 pthread_mutex_lock(&out->lock);
2639 list_for_each(node, &out->session_list) {
2640 handle = node_to_item(node, struct alsa_handle, list);
2641 status = 0;
2642 if (handle->compr != NULL) {
2643 stop_compressed_output_l(out);
2644 }
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302645 }
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302646 pthread_mutex_unlock(&out->lock);
2647 return status;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302648}
2649
2650int adev_open_output_stream(struct audio_hw_device *dev,
2651 audio_io_handle_t handle,
2652 audio_devices_t devices,
2653 audio_output_flags_t flags,
2654 struct audio_config *config,
2655 struct audio_stream_out **stream_out)
2656{
2657 struct audio_device *adev = (struct audio_device *)dev;
2658 struct stream_out *out;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302659 struct alsa_handle *device_handle = NULL;
2660 int i, ret, channels;
2661 struct listnode *item;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302662
2663 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
2664 __func__, config->sample_rate, config->channel_mask, devices, flags);
2665 *stream_out = NULL;
2666 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
2667
2668 if (devices == AUDIO_DEVICE_NONE)
2669 devices = AUDIO_DEVICE_OUT_SPEAKER;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302670 list_init(&out->session_list);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302671
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302672 reset_out_parameters(out);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302673 out->flags = flags;
2674 out->devices = devices;
2675 out->dev = adev;
2676 out->format = config->format;
2677 out->sample_rate = config->sample_rate;
2678 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2679 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302680 out->config = config;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302681 out->handle = handle;
2682
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302683//*TODO: get hdmi/spdif format/channels from routing manager and intialize out->spdif_format & out->hdmi_format*/
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302684 /* Init use case and pcm_config */
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302685 out->hdmi_format = UNCOMPRESSED;
2686 out->spdif_format = UNCOMPRESSED;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302687 out->stream.common.get_sample_rate = out_get_sample_rate;
2688 out->stream.common.set_sample_rate = out_set_sample_rate;
2689 out->stream.common.get_buffer_size = out_get_buffer_size;
2690 out->stream.common.get_channels = out_get_channels;
2691 out->stream.common.get_format = out_get_format;
2692 out->stream.common.set_format = out_set_format;
2693 out->stream.common.standby = out_standby;
2694 out->stream.common.dump = out_dump;
2695 out->stream.common.set_parameters = out_set_parameters;
2696 out->stream.common.get_parameters = out_get_parameters;
2697 out->stream.common.add_audio_effect = out_add_audio_effect;
2698 out->stream.common.remove_audio_effect = out_remove_audio_effect;
2699 out->stream.get_latency = out_get_latency;
2700 out->stream.set_volume = out_set_volume;
2701 out->stream.write = out_write;
2702 out->stream.get_render_position = out_get_render_position;
2703 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
2704 out->stream.get_presentation_position = out_get_presentation_position;
2705
2706 out->standby = 1;
2707 /* out->muted = false; by calloc() */
2708 /* out->written = 0; by calloc() */
2709
2710 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
2711 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
2712
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302713 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
2714 ALOGE("%s: Usecase is OFFLOAD", __func__);
2715 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
2716 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
2717 ALOGE("%s: Unsupported Offload information", __func__);
2718 ret = -EINVAL;
2719 goto error_open;
2720 }
2721
2722 if (!is_supported_format(config->offload_info.format)) {
2723 ALOGE("%s: Unsupported audio format", __func__);
2724 ret = -EINVAL;
2725 goto error_open;
2726 }
2727 out->compr_config.codec = (struct snd_codec *)
2728 calloc(1, sizeof(struct snd_codec));
2729 //Session/clip config.
2730 out->format = config->offload_info.format;
2731 out->sample_rate = config->offload_info.sample_rate;
2732 out->compr_config.codec->id =
2733 get_snd_codec_id(config->offload_info.format);
2734 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
2735 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
2736 out->compr_config.codec->sample_rate =
2737 compress_get_alsa_rate(config->offload_info.sample_rate);
2738 out->compr_config.codec->bit_rate =
2739 config->offload_info.bit_rate;
2740 out->compr_config.codec->ch_in =
2741 popcount(config->channel_mask);
2742 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
2743
2744 if (config->offload_info.channel_mask)
2745 out->channel_mask = config->offload_info.channel_mask;
2746 else if (config->channel_mask)
2747 out->channel_mask = config->channel_mask;
2748 out->uc_strm_type = OFFLOAD_PLAYBACK_STREAM;
2749
2750 //Initialize the handles
2751 /* ------------------------------------------------------------------------
2752 Update use decoder type and routing flags and corresponding states
2753 decoderType will cache the decode types such as decode/passthrough/transcode
2754 and in s/w or dsp. Besides, the states to open decode/passthrough/transcode
2755 handles with the corresponding devices and device formats are updated
2756 -------------------------------------------------------------------------*/
2757 update_decode_type_and_routing_states(out);
2758
2759 /* ------------------------------------------------------------------------
2760 Update rxHandle states
2761 Based on the states, we open the driver and store the handle at appropriate
2762 index
2763 -------------------------------------------------------------------------*/
2764 update_alsa_handle_state(out);
2765
2766 /* ------------------------------------------------------------------------
2767 setup routing
2768 -------------------------------------------------------------------------*/
2769 ret = allocate_internal_buffers(out);
2770 if(ret < 0) {
2771 ALOGE("%s:Error %d",__func__, ret);
2772 goto error_handle;
2773 }
2774
2775 //Callbacks
2776 out->stream.set_callback = out_set_callback;
2777 out->stream.pause = out_pause;
2778 out->stream.resume = out_resume;
2779 out->stream.drain = out_drain;
2780 out->stream.flush = out_flush;
2781
2782 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
2783 out->non_blocking = 1;
2784
2785 out->send_new_metadata = 1;
2786 create_offload_callback_thread(out);
2787 ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
2788 __func__, config->offload_info.version,
2789 config->offload_info.bit_rate);
2790 } else { //if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) {
2791 ALOGE("%s: Usecase is DEEP_BUFFER", __func__);
2792 if((device_handle = get_alsa_handle())== NULL)
2793 goto error_handle;
2794 list_add_tail(&out->session_list, &device_handle->list);
2795 device_handle->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
2796 device_handle->config = pcm_config_deep_buffer;
2797 device_handle->out = out;
2798 device_handle->cmd_pending = false;
2799 out->sample_rate = device_handle->config.rate;
2800 out->uc_strm_type = DEEP_BUFFER_PLAYBACK_STREAM;
2801 out->buffer_size = device_handle->config.period_size *
2802 audio_stream_frame_size(&out->stream.common);
2803 }/* else {
2804 if((device_handle = get_alsa_handle())== NULL)
2805 goto error_handle;
2806 list_add_tail(&out->session_list, &device_handle->list);
2807 device_handle->usecase = USECASE_AUDIO_PLAYBACK_LOW_LATENCY;
2808 device_handle->config = pcm_config_low_latency;
2809 device_handle->sample_rate = device_handle->config.rate;
2810 device_handle->out = out;
2811 device_handle->cmd_pending = false;
2812 out->uc_strm_type = LOW_LATENCY_PLAYBACK_STREAM;
2813 out->buffer_size = device_handle->config.period_size *
2814 audio_stream_frame_size(&out->stream.common);
2815 }*/
2816
2817 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
2818 ALOGE("%s: Usecase is primary ", __func__);
2819 if(adev->primary_output == NULL)
2820 adev->primary_output = out;
2821 else {
2822 ALOGE("%s: Primary output is already opened", __func__);
2823 ret = -EEXIST;
2824 goto error_open;
2825 }
2826 }
2827
2828 /* Check if this usecase is already existing */
2829 pthread_mutex_lock(&adev->lock);
2830 if (out->uc_strm_type != OFFLOAD_PLAYBACK_STREAM) {
2831 if (get_usecase_from_list(adev, device_handle->usecase) != NULL) {
2832 ALOGE("%s: Usecase (%d) is already present", __func__,
2833 device_handle->usecase);
2834 pthread_mutex_unlock(&adev->lock);
2835 ret = -EEXIST;
2836 goto error_open;
2837 }
2838 }
2839 pthread_mutex_unlock(&adev->lock);
2840
2841
2842 /* out->muted = false; by calloc() */
2843
2844
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302845 config->format = out->stream.common.get_format(&out->stream.common);
2846 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
2847 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
2848
2849 *stream_out = &out->stream;
2850 ALOGV("%s: exit", __func__);
2851 return 0;
2852
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302853error_handle:
2854 ret = -EINVAL;
2855 ALOGE("%s: exit: error handle %d", __func__, ret);
2856 while (!list_empty(&out->session_list)) {
2857 item = list_head(&out->session_list);
2858 list_remove(item);
2859 device_handle = node_to_item(item, struct alsa_handle, list);
2860 platform_free_usecase(device_handle->usecase);
2861 free_alsa_handle(device_handle);
2862 }
2863
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302864error_open:
2865 free(out);
2866 *stream_out = NULL;
2867 ALOGD("%s: exit: ret %d", __func__, ret);
2868 return ret;
2869}
2870
2871void adev_close_output_stream(struct audio_hw_device *dev,
2872 struct audio_stream_out *stream)
2873{
2874 struct stream_out *out = (struct stream_out *)stream;
2875 struct audio_device *adev = out->dev;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302876 struct listnode *item;
2877 struct alsa_handle *handle;
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302878
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302879 ALOGV("%s", __func__);
2880
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302881 out_standby(&stream->common);
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302882 if (out->uc_strm_type == OFFLOAD_PLAYBACK_STREAM) {
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302883 destroy_offload_callback_thread(out);
2884
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302885 while (!list_empty(&out->session_list)) {
2886 item = list_head(&out->session_list);
2887 list_remove(item);
2888 handle = node_to_item(item, struct alsa_handle, list);
2889 if(handle->compr_config.codec != NULL)
2890 free(handle->compr_config.codec);
2891 platform_free_usecase(handle->usecase);
2892 free_alsa_handle(handle);
2893 }
2894 free(out->compr_config.codec);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302895 }
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +05302896
2897 free_internal_buffers(out);
Dhananjay Kumar01e921a2013-11-26 23:33:22 +05302898 pthread_cond_destroy(&out->cond);
2899 pthread_mutex_destroy(&out->lock);
2900 free(stream);
2901 ALOGV("%s: exit", __func__);
2902}