blob: d2e4e6e77cb80e99e673138fb3129c0e8437e0e9 [file] [log] [blame]
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +05301/*
2 * Copyright (C) 2011 The Android Open Source Project
3 * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
4 * Not a Contribution.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#include <errno.h>
20#include <stdarg.h>
21#include <sys/stat.h>
22#include <fcntl.h>
23#include <stdlib.h>
24#include <unistd.h>
25#include <dlfcn.h>
26#include <math.h>
27
28#define LOG_TAG "AudioBitstreamStateMachine"
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +053029#define LOG_NDEBUG 0
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +053030#define LOG_NDDEBUG 0
31#include <utils/Log.h>
32
33#include <cutils/properties.h>
34#include "audio_hw.h"
35#include "platform_api.h"
36#include <platform.h>
37// ----------------------------------------------------------------------------
38
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +053039/*
40Initialize all input and output pointers
41Allocate twice the max buffer size of input and output for sufficient buffering
42*/
43int audio_bitstream_init(struct audio_bitstream_sm *bstream, int buffering_factor)
44{
45 bstream->buffering_factor = buffering_factor;
46 bstream->buffering_factor_cnt = 0;
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +053047 bstream->inp_buf_size = SAMPLES_PER_CHANNEL *
48 MAX_INPUT_CHANNELS_SUPPORTED*
49 (bstream->buffering_factor+1);
50 bstream->inp_buf = (char *)malloc( bstream->inp_buf_size);
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +053051
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +053052 // multiplied by 2 to convert to bytes
53 if(bstream->inp_buf != NULL) {
54 bstream->inp_buf_curr_ptr = bstream->inp_buf;
55 bstream->inp_buf_write_ptr = bstream->inp_buf;
56 } else {
57 ALOGE("MS11 input buffer not allocated");
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +053058 bstream->inp_buf_size = 0;
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +053059 return 0;
60 }
61
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +053062 bstream->enc_out_buf_size = SAMPLES_PER_CHANNEL * MAX_INPUT_CHANNELS_SUPPORTED*
63 FACTOR_FOR_BUFFERING;
64 bstream->enc_out_buf =(char *)malloc(bstream->enc_out_buf_size);
65
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +053066 if(bstream->enc_out_buf) {
67 bstream->enc_out_buf_write_ptr = bstream->enc_out_buf;
68 } else {
69 ALOGE("MS11 Enc output buffer not allocated");
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +053070 bstream->enc_out_buf_size = 0;
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +053071 return 0;
72 }
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +053073 bstream->pcm_2_out_buf_size = SAMPLES_PER_CHANNEL*STEREO_CHANNELS *
74 FACTOR_FOR_BUFFERING;
75 bstream->pcm_2_out_buf =(char *)malloc(bstream->pcm_2_out_buf_size);
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +053076 if(bstream->pcm_2_out_buf) {
77 bstream->pcm_2_out_buf_write_ptr = bstream->pcm_2_out_buf;
78 } else {
79 ALOGE("MS11 PCM2Ch output buffer not allocated");
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +053080 bstream->pcm_2_out_buf_size = 0;
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +053081 return 0;
82 }
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +053083 bstream->pcm_mch_out_buf_size = SAMPLES_PER_CHANNEL * MAX_OUTPUT_CHANNELS_SUPPORTED *
84 FACTOR_FOR_BUFFERING;
85
86 bstream->pcm_mch_out_buf =(char *)malloc(bstream->pcm_mch_out_buf_size);
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +053087 if(bstream->pcm_mch_out_buf) {
88 bstream->pcm_mch_out_buf_write_ptr = bstream->pcm_mch_out_buf;
89 } else {
90 ALOGE("MS11 PCMMCh output buffer not allocated");
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +053091 bstream->pcm_mch_out_buf_size = 0;
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +053092 return 0;
93 }
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +053094 bstream->passt_out_buf_size =SAMPLES_PER_CHANNEL *
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +053095 MAX_INPUT_CHANNELS_SUPPORTED *
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +053096 FACTOR_FOR_BUFFERING;
97 bstream->passt_out_buf =(char *)malloc(bstream->passt_out_buf_size);
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +053098 if(bstream->passt_out_buf) {
99 bstream->passt_out_buf_write_ptr = bstream->passt_out_buf;
100 } else {
101 ALOGE("MS11 Enc output buffer not allocated");
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +0530102 bstream->passt_out_buf_size = 0;
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +0530103 return 0;
104 }
105 return 1;
106}
107
108/*
109Free the allocated memory
110*/
111int audio_bitstream_close(struct audio_bitstream_sm *bstream)
112{
113 if(bstream->inp_buf != NULL) {
114 free(bstream->inp_buf);
115 bstream->inp_buf = NULL;
116 }
117 if(bstream->enc_out_buf != NULL) {
118 free(bstream->enc_out_buf);
119 bstream->enc_out_buf = NULL;
120 }
121 if(bstream->pcm_2_out_buf != NULL) {
122 free(bstream->pcm_2_out_buf);
123 bstream->pcm_2_out_buf = NULL;
124 }
125 if(bstream->pcm_mch_out_buf != NULL) {
126 free(bstream->pcm_mch_out_buf);
127 bstream->pcm_mch_out_buf = NULL;
128 }
129 if(bstream->passt_out_buf != NULL) {
130 free(bstream->passt_out_buf);
131 bstream->passt_out_buf = NULL;
132 }
133 bstream->buffering_factor = 1;
134 bstream->buffering_factor_cnt = 0;
135 return 0;
136}
137
138/*
139Reset the buffer pointers to start for. This will be help in flush and close
140*/
141void audio_bitstream_reset_ptr( struct audio_bitstream_sm *bstream)
142{
143 bstream->inp_buf_curr_ptr = bstream->inp_buf_write_ptr = bstream->inp_buf;
144 bstream->enc_out_buf_write_ptr = bstream->enc_out_buf;
145 bstream->pcm_2_out_buf_write_ptr = bstream->pcm_2_out_buf;
146 bstream->pcm_mch_out_buf_write_ptr = bstream->pcm_mch_out_buf;
147 bstream->passt_out_buf_write_ptr = bstream->passt_out_buf;
148 bstream->buffering_factor_cnt = 0;
149}
150
151/*
152Reset the output buffer pointers to start for port reconfiguration
153*/
154void audio_bitstream_reset_output_bitstream_ptr(
155 struct audio_bitstream_sm *bstream)
156{
157 bstream->enc_out_buf_write_ptr = bstream->enc_out_buf;
158 bstream->pcm_2_out_buf_write_ptr = bstream->pcm_2_out_buf;
159 bstream->pcm_mch_out_buf_write_ptr = bstream->pcm_mch_out_buf;
160 bstream->passt_out_buf_write_ptr = bstream->passt_out_buf;
161}
162
163/*
164Copy the bitstream/pcm from Player to internal buffer.
165The incoming bitstream is appended to existing bitstream
166*/
167void audio_bitstream_copy_to_internal_buffer(
168 struct audio_bitstream_sm *bstream,
169 char *buf_ptr, size_t bytes)
170{
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +0530171 // flush the input buffer if input is not consumed
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +0530172 if( (bstream->inp_buf_write_ptr+bytes) > (bstream->inp_buf+bstream->inp_buf_size) ) {
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +0530173 ALOGE("Input bitstream is not consumed");
174 return;
175 }
176
177 memcpy(bstream->inp_buf_write_ptr, buf_ptr, bytes);
178 bstream->inp_buf_write_ptr += bytes;
179 if(bstream->buffering_factor_cnt < bstream->buffering_factor)
180 bstream->buffering_factor_cnt++;
181}
182
183/*
184Append zeros to the bitstream, so that the entire bitstream in ADIF is pushed
185out for decoding
186*/
187void audio_bitstream_append_silence_internal_buffer(
188 struct audio_bitstream_sm *bstream,
189 uint32_t bytes, unsigned char value)
190{
191 int32_t bufLen = SAMPLES_PER_CHANNEL*MAX_INPUT_CHANNELS_SUPPORTED*
192 (bstream->buffering_factor+1);
193 uint32_t i = 0;
194 if( (bstream->inp_buf_write_ptr+bytes) > (bstream->inp_buf+bufLen) ) {
195 bytes = bufLen + bstream->inp_buf - bstream->inp_buf_write_ptr;
196 }
197 for(i=0; i< bytes; i++)
198 *bstream->inp_buf_write_ptr++ = value;
199 if(bstream->buffering_factor_cnt < bstream->buffering_factor)
200 bstream->buffering_factor_cnt++;
201}
202
203/*
204Flags if sufficient bitstream is available to proceed to decode based on
205the threshold
206*/
207int audio_bitstream_sufficient_buffer_to_decode(
208 struct audio_bitstream_sm *bstream,
209 int min_bytes_to_decode)
210{
211 int proceed_decode = 0;
212 if( (bstream->inp_buf_write_ptr -\
213 bstream->inp_buf_curr_ptr) > min_bytes_to_decode)
214 proceed_decode = 1;
215 return proceed_decode;
216}
217
218/*
219Gets the start address of the bitstream buffer. This is used for start of decode
220*/
221char* audio_bitstream_get_input_buffer_ptr(
222 struct audio_bitstream_sm *bstream)
223{
224 return bstream->inp_buf_curr_ptr;
225}
226
227/*
228Gets the writePtr of the bitstream buffer. This is used for calculating length of
229bitstream
230*/
231char* audio_bitstream_get_input_buffer_write_ptr(
232 struct audio_bitstream_sm *bstream)
233{
234 return bstream->inp_buf_write_ptr;
235}
236
Dhananjay Kumar09cbbf02013-11-25 15:49:57 +0530237int audio_bitstream_set_input_buffer_ptr(
238 struct audio_bitstream_sm *bstream, int bytes)
239{
240 if(((bstream->inp_buf_curr_ptr + bytes) <=
241 (bstream->inp_buf + bstream->inp_buf_size)) &&
242 ((bstream->inp_buf_curr_ptr + bytes) >= bstream->inp_buf))
243
244 bstream->inp_buf_curr_ptr += bytes;
245 else {
246 ALOGE("Invalid input buffer size %d bytes", bytes);
247 return -EINVAL;
248 }
249
250 return 0;
251}
252
253int audio_bitstream_set_input_buffer_write_ptr(
254 struct audio_bitstream_sm *bstream, int bytes)
255{
256 if(((bstream->inp_buf_write_ptr + bytes) <=
257 (bstream->inp_buf + bstream->inp_buf_size)) &&
258 ((bstream->inp_buf_write_ptr + bytes) >= bstream->inp_buf))
259
260 bstream->inp_buf_write_ptr += bytes;
261 else {
262 ALOGE("Invalid input buffer size %d bytes", bytes);
263 return -EINVAL;
264 }
265
266 return 0;
267}
268
Dhananjay Kumar4e9a9032013-11-18 16:41:48 +0530269/*
270Get the output buffer start pointer to start rendering the pcm sampled to driver
271*/
272char* audio_bitstream_get_output_buffer_ptr(
273 struct audio_bitstream_sm *bstream,
274 int format)
275{
276 switch(format) {
277 case PCM_MCH_OUT:
278 return bstream->pcm_mch_out_buf;
279 case PCM_2CH_OUT:
280 return bstream->pcm_2_out_buf;
281 case COMPRESSED_OUT:
282 return bstream->enc_out_buf;
283 case TRANSCODE_OUT:
284 return bstream->passt_out_buf;
285 default:
286 return NULL;
287 }
288}
289
290/*
291Output the pointer from where the next PCM samples can be copied to buffer
292*/
293char* audio_bitstream_get_output_buffer_write_ptr(
294 struct audio_bitstream_sm *bstream,
295 int format)
296{
297 switch(format) {
298 case PCM_MCH_OUT:
299 return bstream->pcm_mch_out_buf_write_ptr;
300 case PCM_2CH_OUT:
301 return bstream->pcm_2_out_buf_write_ptr;
302 case COMPRESSED_OUT:
303 return bstream->enc_out_buf_write_ptr;
304 case TRANSCODE_OUT:
305 return bstream->passt_out_buf_write_ptr;
306 default:
307 return NULL;
308 }
309}
310
311/*
312Provides the bitstream size available in the internal buffer
313*/
314size_t audio_bitstream_get_size(struct audio_bitstream_sm *bstream)
315{
316 return (bstream->inp_buf_write_ptr-bstream->inp_buf_curr_ptr);
317}
318
319/*
320After decode, the residue bitstream in the buffer is moved to start, so as to
321avoid circularity constraints
322*/
323void audio_bitstream_copy_residue_to_start(
324 struct audio_bitstream_sm *bstream,
325 size_t bytes_consumed_in_decode)
326{
327 size_t remaining_curr_valid_bytes = bstream->inp_buf_write_ptr -
328 (bytes_consumed_in_decode+bstream->inp_buf_curr_ptr);
329 size_t remainingTotalBytes = bstream->inp_buf_write_ptr -
330 (bytes_consumed_in_decode+bstream->inp_buf);
331 if(bstream->buffering_factor_cnt == bstream->buffering_factor) {
332 memcpy(bstream->inp_buf, bstream->inp_buf+bytes_consumed_in_decode, remainingTotalBytes);
333 bstream->inp_buf_write_ptr = bstream->inp_buf+remainingTotalBytes;
334 bstream->inp_buf_curr_ptr = bstream->inp_buf_write_ptr-remaining_curr_valid_bytes;
335 } else {
336 bstream->inp_buf_curr_ptr += bytes_consumed_in_decode;
337 }
338}
339
340/*
341Remaing samples less than the one period size required for the pcm driver
342is moved to start of the buffer
343*/
344void audio_bitstream_copy_residue_output_start(
345 struct audio_bitstream_sm *bstream,
346 int format,
347 size_t samplesRendered)
348{
349 size_t remaining_bytes;
350 switch(format) {
351 case PCM_MCH_OUT:
352 remaining_bytes = bstream->pcm_mch_out_buf_write_ptr-\
353 (bstream->pcm_mch_out_buf+samplesRendered);
354 memcpy(bstream->pcm_mch_out_buf,
355 bstream->pcm_mch_out_buf+samplesRendered,
356 remaining_bytes);
357 bstream->pcm_mch_out_buf_write_ptr = \
358 bstream->pcm_mch_out_buf + remaining_bytes;
359 break;
360 case PCM_2CH_OUT:
361 remaining_bytes = bstream->pcm_2_out_buf_write_ptr-\
362 (bstream->pcm_2_out_buf+samplesRendered);
363 memcpy(bstream->pcm_2_out_buf,
364 bstream->pcm_2_out_buf+samplesRendered,
365 remaining_bytes);
366 bstream->pcm_2_out_buf_write_ptr = \
367 bstream->pcm_2_out_buf + remaining_bytes;
368 break;
369 case COMPRESSED_OUT:
370 remaining_bytes = bstream->enc_out_buf_write_ptr-\
371 (bstream->enc_out_buf+samplesRendered);
372 memcpy(bstream->enc_out_buf,
373 bstream->enc_out_buf+samplesRendered,
374 remaining_bytes);
375 bstream->enc_out_buf_write_ptr = \
376 bstream->enc_out_buf + remaining_bytes;
377 break;
378 case TRANSCODE_OUT:
379 remaining_bytes = bstream->passt_out_buf_write_ptr-\
380 (bstream->passt_out_buf+samplesRendered);
381 memcpy(bstream->passt_out_buf,
382 bstream->passt_out_buf+samplesRendered,
383 remaining_bytes);
384 bstream->passt_out_buf_write_ptr = \
385 bstream->passt_out_buf + remaining_bytes;
386 break;
387 default:
388 break;
389 }
390}
391
392/*
393The write pointer is updated after the incoming PCM samples are copied to the
394output buffer
395*/
396void audio_bitstream_set_output_buffer_write_ptr(
397 struct audio_bitstream_sm *bstream,
398 int format, size_t output_pcm_sample)
399{
400 int alloc_bytes;
401 switch(format) {
402 case PCM_MCH_OUT:
403 alloc_bytes = SAMPLES_PER_CHANNEL*\
404 MAX_OUTPUT_CHANNELS_SUPPORTED*FACTOR_FOR_BUFFERING;
405 if (bstream->pcm_mch_out_buf + alloc_bytes >\
406 bstream->pcm_mch_out_buf_write_ptr + output_pcm_sample)
407 bstream->pcm_mch_out_buf_write_ptr += output_pcm_sample;
408 break;
409 case PCM_2CH_OUT:
410 alloc_bytes = SAMPLES_PER_CHANNEL*STEREO_CHANNELS*FACTOR_FOR_BUFFERING;
411 if(bstream->pcm_2_out_buf + alloc_bytes > \
412 bstream->pcm_2_out_buf_write_ptr + output_pcm_sample)
413 bstream->pcm_2_out_buf_write_ptr += output_pcm_sample;
414 break;
415 case COMPRESSED_OUT:
416 alloc_bytes = SAMPLES_PER_CHANNEL*\
417 MAX_INPUT_CHANNELS_SUPPORTED*FACTOR_FOR_BUFFERING;
418 if (bstream->enc_out_buf + alloc_bytes > \
419 bstream->enc_out_buf_write_ptr + output_pcm_sample)
420 bstream->enc_out_buf_write_ptr += output_pcm_sample;
421 break;
422 case TRANSCODE_OUT:
423 alloc_bytes = SAMPLES_PER_CHANNEL*\
424 MAX_INPUT_CHANNELS_SUPPORTED*FACTOR_FOR_BUFFERING;
425 if (bstream->passt_out_buf + alloc_bytes > \
426 bstream->passt_out_buf_write_ptr + output_pcm_sample)
427 bstream->passt_out_buf_write_ptr += output_pcm_sample;
428 break;
429 default:
430 break;
431 }
432}
433
434/*
435Flags if sufficient samples are available to render to PCM driver
436*/
437int audio_bitstream_sufficient_sample_to_render(
438 struct audio_bitstream_sm *bstream,
439 int format, int mid_size_reqd)
440{
441 int status = 0;
442 char *buf_ptr = NULL, *buf_write_ptr = NULL;
443 switch(format) {
444 case PCM_MCH_OUT:
445 buf_ptr = bstream->pcm_mch_out_buf;
446 buf_write_ptr = bstream->pcm_mch_out_buf_write_ptr;
447 break;
448 case PCM_2CH_OUT:
449 buf_ptr = bstream->pcm_2_out_buf;
450 buf_write_ptr = bstream->pcm_2_out_buf_write_ptr;
451 break;
452 case COMPRESSED_OUT:
453 buf_ptr = bstream->enc_out_buf;
454 buf_write_ptr = bstream->enc_out_buf_write_ptr;
455 break;
456 case TRANSCODE_OUT:
457 buf_ptr = bstream->passt_out_buf;
458 buf_write_ptr = bstream->passt_out_buf_write_ptr;
459 break;
460 default:
461 break;
462 }
463 if( (buf_write_ptr-buf_ptr) >= mid_size_reqd )
464 status = 1;
465 return status;
466}
467
468void audio_bitstream_start_input_buffering_mode(
469 struct audio_bitstream_sm *bstream)
470{
471 bstream->buffering_factor_cnt = 0;
472}
473
474void audio_bitstream_stop_input_buffering_mode(
475 struct audio_bitstream_sm *bstream)
476{
477 size_t remaining_curr_valid_bytes = \
478 bstream->inp_buf_write_ptr - bstream->inp_buf_curr_ptr;
479 bstream->buffering_factor_cnt = bstream->buffering_factor;
480 memcpy(bstream->inp_buf,
481 bstream->inp_buf_curr_ptr,
482 remaining_curr_valid_bytes);
483 bstream->inp_buf_curr_ptr = bstream->inp_buf;
484 bstream->inp_buf_write_ptr = bstream->inp_buf + remaining_curr_valid_bytes;
485}