hal_play_test : Support for Playback through QAP
Add support for Playback of Dolby and DTS formats through QAP
Add KPI support, add support to disable dump.
Depends-on: 2002598
Change-Id: If29faaeca545ce7809008f747f1d04807b105e9a
diff --git a/configure.ac b/configure.ac
index da39527..978d235 100644
--- a/configure.ac
+++ b/configure.ac
@@ -114,6 +114,7 @@
AM_CONDITIONAL([AUDIO_HW_LOOPBACK], [test x$AUDIO_FEATURE_ENABLED_AUDIO_HW_LOOPBACK = xtrue])
AM_CONDITIONAL([AUDIO_PARSER], [test x$AUDIO_FEATURE_ENABLED_PARSER = xtrue])
AM_CONDITIONAL([DTSHD_PARSER], [test x$AUDIO_FEATURE_ENABLED_DTSHD_PARSER = xtrue])
+AM_CONDITIONAL([QAP], [test x$AUDIO_FEATURE_ENABLED_QAP = xtrue])
AC_CONFIG_FILES([ \
Makefile \
diff --git a/qahw_api/test/Makefile.am b/qahw_api/test/Makefile.am
index d87962b..b4bbea7 100644
--- a/qahw_api/test/Makefile.am
+++ b/qahw_api/test/Makefile.am
@@ -6,9 +6,19 @@
hal_play_test_SOURCES = qahw_playback_test.c \
qahw_effect_test.c
-hal_play_test_CPPFLAGS = $(PLAY_CPPFLAGS) $(PLAY_INCLUDES)
+
hal_play_test_LDADD = -lutils ../libqahw.la
+if QAP
+AM_CFLAGS = -DQAP
+AM_CFLAGS += -I ${WORKSPACE}/audio/mm-audio/qap_wrapper/inc/
+hal_play_test_SOURCES += qap_wrapper_extn.c
+hal_play_test_LDADD += -lqap_wrapper
+endif
+
+hal_play_test_CPPFLAGS = $(PLAY_CPPFLAGS) $(PLAY_INCLUDES)
+hal_play_test_CFLAGS = $(AM_CFLAGS)
+hal_play_test_CFLAGS = -DLINUX_ENABLED
bin_PROGRAMS += hal_rec_test
@@ -18,6 +28,7 @@
hal_rec_test_SOURCES = qahw_multi_record_test.c
hal_rec_test_CPPFLAGS = -Dstrlcat=g_strlcat $(GLIB_CFLAGS) -include glib.h
hal_rec_test_CPPFLAGS += $(REC_CPPFLAGS) $(REC_INCLUDES)
+hal_play_test_CFLAGS += $(AM_CFLAGS)
hal_rec_test_LDADD = -lutils ../libqahw.la $(GLIB_LIBS)
bin_PROGRAMS += trans_loopback_test
diff --git a/qahw_api/test/qahw_playback_test.c b/qahw_api/test/qahw_playback_test.c
index c27f920..2ead153 100644
--- a/qahw_api/test/qahw_playback_test.c
+++ b/qahw_api/test/qahw_playback_test.c
@@ -18,22 +18,7 @@
/* Test app to play audio at the HAL layer */
-#include <getopt.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <time.h>
-#include <signal.h>
-#include <cutils/str_parms.h>
-#include <tinyalsa/asoundlib.h>
-#include "qahw_api.h"
-#include "qahw_defs.h"
-#include "qahw_effect_api.h"
-#include "qahw_effect_test.h"
+#include "qahw_playback_test.h"
#define nullptr NULL
@@ -69,50 +54,10 @@
#define DTSHD_CHUNK_STREAM_KEYWORD "STRMDATA"
#define DTSHD_META_KEYWORD_SIZE 8 /*in bytes */
-static int get_wav_header_length (FILE* file_stream);
static ssize_t get_bytes_to_read(FILE* file, int filetype);
static void init_streams(void);
int pthread_cancel(pthread_t thread);
-
-enum {
- FILE_WAV = 1,
- FILE_MP3,
- FILE_AAC,
- FILE_AAC_ADTS,
- FILE_FLAC,
- FILE_ALAC,
- FILE_VORBIS,
- FILE_WMA,
- FILE_AC3,
- FILE_AAC_LATM,
- FILE_EAC3,
- FILE_EAC3_JOC,
- FILE_DTS,
- FILE_MP2,
- FILE_APTX,
- FILE_TRUEHD,
- FILE_IEC61937
-};
-
-typedef enum {
- USB_MODE_DEVICE,
- USB_MODE_HOST,
- USB_MODE_NONE
-} usb_mode_type_t;
-
-typedef enum {
- AAC_LC = 1,
- AAC_HE_V1,
- AAC_HE_V2
-} aac_format_type_t;
-
-typedef enum {
- WMA = 1,
- WMA_PRO,
- WMA_LOSSLESS
-} wma_format_type_t;
-
struct wav_header {
uint32_t riff_id;
uint32_t riff_sz;
@@ -129,18 +74,6 @@
uint32_t data_sz;
};
-struct audio_config_params {
- qahw_module_handle_t *qahw_mod_handle;
- audio_io_handle_t handle;
- audio_devices_t input_device;
- audio_config_t config;
- audio_input_flags_t flags;
- const char* kStreamName ;
- audio_source_t kInputSource;
- char *file_name;
- volatile bool thread_exit;
-};
-
struct proxy_data {
struct audio_config_params acp;
struct wav_header hdr;
@@ -162,42 +95,6 @@
uint32_t config_mask;
};
-typedef struct {
- qahw_module_handle_t *qahw_in_hal_handle;
- qahw_module_handle_t *qahw_out_hal_handle;
- audio_io_handle_t handle;
- char* filename;
- FILE* file_stream;
- int filetype;
- int stream_index;
- audio_devices_t output_device;
- audio_devices_t input_device;
- audio_config_t config;
- audio_output_flags_t flags;
- qahw_stream_handle_t* out_handle;
- qahw_stream_handle_t* in_handle;
- int channels;
- aac_format_type_t aac_fmt_type;
- wma_format_type_t wma_fmt_type;
- char *kvpair_values;
- bool flags_set;
- usb_mode_type_t usb_mode;
- int effect_index;
- int effect_preset_strength;
- bool drift_query;
- bool drift_correction;
- bool play_later;
- char *device_url;
- thread_func_t ethread_func;
- thread_data_t *ethread_data;
- cmd_data_t cmd_data;
- pthread_cond_t write_cond;
- pthread_mutex_t write_lock;
- pthread_cond_t drain_cond;
- pthread_mutex_t drain_lock;
- bool interactive_strm;
-}stream_config;
-
/* Lock for dual main usecase */
pthread_cond_t dual_main_cond;
pthread_mutex_t dual_main_lock;
@@ -211,13 +108,12 @@
FILE * log_file = NULL;
volatile bool stop_playback = false;
const char *log_filename = NULL;
-float vol_level = 0.01;
struct proxy_data proxy_params;
pthread_t playback_thread[MAX_PLAYBACK_STREAMS];
bool thread_active[MAX_PLAYBACK_STREAMS] = { false };
+bool qap_wrapper_session_active = false;
stream_config stream_param[MAX_PLAYBACK_STREAMS];
-bool kpi_mode;
bool event_trigger;
/*
@@ -1000,6 +896,7 @@
case AAC_LC:
case AAC_HE_V1:
case AAC_HE_V2:
+ case AAC_LOAS:
valid_format_type = true;
break;
default:
@@ -1171,6 +1068,7 @@
fprintf(log_file, "Does not support given filetype\n");
fprintf(stderr, "Does not support given filetype\n");
usage();
+ hal_test_qap_usage();
return;
}
stream_info->config.sample_rate = stream_info->config.offload_info.sample_rate;
@@ -1608,10 +1506,10 @@
printf(" -m --mode - usb operating mode(Device Mode is default)\n");
printf(" 0:Device Mode(host drives the stream and its params and so no need to give params as input)\n");
printf(" 1:Host Mode(user can give stream and stream params via a stream(SD card file) or setup loopback with given params\n");
- printf(" -O --output-ch-map - output channel map");
- printf(" -I --input-ch-map - input channel map");
- printf(" -M --mixer-coeffs - mixer coefficient matrix");
- printf(" -i --intr-strm - interactive stream indicator");
+ printf(" -O --output-ch-map - output channel map\n");
+ printf(" -I --input-ch-map - input channel map\n");
+ printf(" -M --mixer-coeffs - mixer coefficient matrix\n");
+ printf(" -i --intr-strm - interactive stream indicator\n");
printf(" -C --Device Config - Device Configuration params\n");
printf(" Params should be in the order defined in struct qahw_device_cfg_param. Order is: \n");
printf(" <sample_rate>, <channels>, <bit_width>, <format>, <device>, <channel_map[channels]>, <channel_allocation> \n");
@@ -1683,7 +1581,7 @@
printf(" ->Note:all the USB device commmands(above) should be accompanied with the host side commands\n\n");
}
-static int get_wav_header_length (FILE* file_stream)
+int get_wav_header_length (FILE* file_stream)
{
int subchunk_size = 0, wav_header_len = 0;
@@ -1800,7 +1698,7 @@
return file_read_size;
}
-static qahw_module_handle_t * load_hal(audio_devices_t dev) {
+qahw_module_handle_t * load_hal(audio_devices_t dev) {
qahw_module_handle_t *hal = NULL;
if ((AUDIO_DEVICE_IN_USB_DEVICE == dev) ||
@@ -1844,7 +1742,7 @@
* this function unloads all the loaded hal modules so this should be called
* after all the stream playback are concluded.
*/
-static int unload_hals() {
+int unload_hals() {
if (usb_hal_handle) {
fprintf(log_file,"\nUnLoading usb HAL\n");
@@ -1994,8 +1892,54 @@
token_string = NULL;
} else
return -EINVAL;
+}
+
+#ifdef QAP
+int start_playback_through_qap(char * kvp_string, int num_of_streams) {
+ stream_config *stream = NULL;
+ int rc = 0;
+ int i;
+
+ fprintf(stdout, "kvp_string %s and num_of_streams %d\n", kvp_string, num_of_streams);
+ for (i = 0; i < num_of_streams; i++) {
+ stream = &stream_param[i];
+ if (stream->filename) {
+ if ((stream->file_stream = fopen(stream->filename, "r"))== NULL) {
+ fprintf(log_file, "Cannot open audio file %s\n", stream->filename);
+ fprintf(stderr, "Cannot open audio file %s\n", stream->filename);
+ return -EINVAL;
+ }
+ }
+ get_file_format(stream);
+ fprintf(stdout, "Playing from:%s\n", stream->filename);
+ qap_module_handle_t qap_module_handle = NULL;
+ if (!qap_wrapper_session_active) {
+ rc = qap_wrapper_session_open(kvp_string, stream, num_of_streams);
+ if (rc != 0) {
+ fprintf(stderr, "Session Open failed\n");
+ return -EINVAL;
+ }
+ qap_wrapper_session_active = true;
+ }
+
+ if (qap_wrapper_session_active) {
+ stream->qap_module_handle = qap_wrapper_stream_open(stream);
+ if (stream->qap_module_handle == NULL) {
+ fprintf(stderr, "QAP Stream open Failed\n");
+ } else {
+ fprintf(stdout, "QAP module handle is %p and file name is %s\n", stream->qap_module_handle, stream->filename);
+ rc = pthread_create(&playback_thread[i], NULL, qap_wrapper_start_stream, (void *)&stream_param[i]);
+ if (rc) {
+ fprintf(stderr, "stream %d: failed to create thread\n", stream->stream_index);
+ return -EINVAL;
+ }
+ thread_active[i] = true;
+ }
+ }
+ }
return 0;
}
+#endif
int main(int argc, char* argv[]) {
char *ba = NULL;
@@ -2028,6 +1972,7 @@
init_streams();
int num_of_streams = 1;
+ char kvp_string[KV_PAIR_MAX_LENGTH] = {0};
struct option long_options[] = {
/* These options set a flag. */
@@ -2038,6 +1983,7 @@
{"channels", required_argument, 0, 'c'},
{"bitwidth", required_argument, 0, 'b'},
{"volume", required_argument, 0, 'v'},
+ {"enable-dump", required_argument, 0, 'V'},
{"log-file", required_argument, 0, 'l'},
{"dump-file", required_argument, 0, 'D'},
{"file-type", required_argument, 0, 't'},
@@ -2056,13 +2002,18 @@
{"mode", required_argument, 0, 'm'},
{"effect-preset", required_argument, 0, 'p'},
{"effect-strength", required_argument, 0, 'S'},
- {"device-config", required_argument, 0, 'C'},
- {"help", no_argument, 0, 'h'},
+#ifdef QAP
+ {"render-format", required_argument, 0, 'x'},
+ {"timestamp-file", required_argument, 0, 'y'},
+ {"framesize-file", required_argument, 0, 'z'},
+#endif
{"output-ch-map", required_argument, 0, 'O'},
{"input-ch-map", required_argument, 0, 'I'},
{"mixer-coeffs", required_argument, 0, 'M'},
{"num-out-ch", required_argument, 0, 'o'},
{"intr-strm", required_argument, 0, 'i'},
+ {"device-config", required_argument, 0, 'C'},
+ {"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
@@ -2085,7 +2036,11 @@
while ((opt = getopt_long(argc,
argv,
- "-f:r:c:b:d:s:v:l:t:a:w:k:PD:KF:Ee:A:u:m:S:C:p:qQhI:O:M:o:i:",
+#ifdef QAP
+ "-f:r:c:b:d:s:v:V:l:t:a:w:k:PD:KF:Ee:A:u:m:S:C:p::x:y:z:qQhI:O:M:o:i:h:",
+#else
+ "-f:r:c:b:d:s:v:V:l:t:a:w:k:PD:KF:Ee:A:u:m:S:C:p:qQhI:O:M:o:i:h:",
+#endif
long_options,
&option_index)) != -1) {
@@ -2116,6 +2071,9 @@
case 'v':
vol_level = atof(optarg);
break;
+ case 'V':
+ enable_dump = atof(optarg);
+ break;
case 'l':
log_filename = optarg;
if (strcasecmp(log_filename, "stdout") &&
@@ -2220,6 +2178,19 @@
break;
case 'o':
mm_params.num_output_channels = atoi(optarg);
+ break;
+#ifdef QAP
+ case 'x':
+ render_format = atoi(optarg);
+ break;
+ case 'y':
+ stream_param[i].timestamp_filename = optarg;
+ break;
+ case 'z':
+ stream_param[i].framesize_filename = optarg;
+ fprintf(stderr, "file name is %s\n", stream_param[i].framesize_filename);
+ break;
+#endif
case 'C':
fprintf(log_file, " In Device config \n");
fprintf(stderr, " In Device config \n");
@@ -2283,6 +2254,9 @@
break;
case 'h':
usage();
+#ifdef QAP
+ hal_test_qap_usage();
+#endif
return 0;
break;
@@ -2373,20 +2347,27 @@
}
+ if (is_qap_session_active(argc, argv, kvp_string)) {
+ rc = start_playback_through_qap(kvp_string, num_of_streams);
+ if (rc != 0) {
+ fprintf(stderr, "QAP playback failed\n");
+ }
+ goto exit;
+ }
for (i = 0; i < num_of_streams; i++) {
stream = &stream_param[i];
if ((kpi_mode == false) &&
(AUDIO_DEVICE_NONE == stream->input_device)){
- if (stream_param[PRIMARY_STREAM_INDEX].filename == nullptr) {
- fprintf(log_file, "Primary file name is must for non kpi-mode\n");
- fprintf(stderr, "Primary file name is must for non kpi-mode\n");
- goto exit;
- }
+ if (stream_param[PRIMARY_STREAM_INDEX].filename == nullptr) {
+ fprintf(log_file, "Primary file name is must for non kpi-mode\n");
+ fprintf(stderr, "Primary file name is must for non kpi-mode\n");
+ goto exit;
+ }
}
if (stream->output_device != AUDIO_DEVICE_NONE)
- if ((stream->qahw_out_hal_handle = load_hal(stream->output_device)) <= 0)
+ if ((stream->qahw_out_hal_handle = load_hal(stream->output_device)) <= 0)
goto exit;
if (stream->input_device != AUDIO_DEVICE_NONE)
@@ -2397,8 +2378,8 @@
(AUDIO_DEVICE_NONE != stream->input_device))
/*
* hal loopback at what params we need to probably detect.
- */
- if(detect_stream_params(stream) < 0)
+ */
+ if(detect_stream_params(stream) < 0)
goto exit;
if (stream->filename) {
@@ -2524,13 +2505,17 @@
fprintf(log_file, "QAHW_PARAM_CH_MIX_MATRIX_PARAMS could not be sent!\n");
}
}
+
}
exit:
-
for (i=0; i<MAX_PLAYBACK_STREAMS; i++) {
if(thread_active[i])
- pthread_join(playback_thread[i], NULL);
+ pthread_join(playback_thread[i], NULL);
+ }
+
+ if(qap_wrapper_session_active) {
+ qap_wrapper_session_close();
}
/*
diff --git a/qahw_api/test/qahw_playback_test.h b/qahw_api/test/qahw_playback_test.h
new file mode 100644
index 0000000..faf32ef
--- /dev/null
+++ b/qahw_api/test/qahw_playback_test.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2015 The Android Open Source Project *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef QAHW_PLAYBACK_TEST_H
+#define QAHW_PLAYBACK_TEST_H
+
+#include <getopt.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <signal.h>
+#include <cutils/str_parms.h>
+#include <tinyalsa/asoundlib.h>
+#include "qahw_api.h"
+#include "qahw_defs.h"
+#include "qahw_effect_api.h"
+#include "qahw_effect_test.h"
+
+#define MAX_STR_LEN 256
+typedef void* qap_module_handle_t;
+bool kpi_mode;
+bool enable_dump;
+float vol_level;
+uint8_t render_format;
+
+
+enum {
+ FILE_WAV = 1,
+ FILE_MP3,
+ FILE_AAC,
+ FILE_AAC_ADTS,
+ FILE_FLAC,
+ FILE_ALAC,
+ FILE_VORBIS,
+ FILE_WMA,
+ FILE_AC3,
+ FILE_AAC_LATM,
+ FILE_EAC3,
+ FILE_EAC3_JOC,
+ FILE_DTS,
+ FILE_MP2,
+ FILE_APTX,
+ FILE_TRUEHD,
+ FILE_IEC61937
+};
+
+typedef enum {
+ USB_MODE_DEVICE,
+ USB_MODE_HOST,
+ USB_MODE_NONE
+} usb_mode_type_t;
+
+typedef enum {
+ AAC_LC = 1,
+ AAC_HE_V1,
+ AAC_HE_V2,
+ AAC_LOAS
+} aac_format_type_t;
+
+typedef enum {
+ WMA = 1,
+ WMA_PRO,
+ WMA_LOSSLESS
+} wma_format_type_t;
+
+struct audio_config_params {
+ qahw_module_handle_t *qahw_mod_handle;
+ audio_io_handle_t handle;
+ audio_devices_t input_device;
+ audio_config_t config;
+ audio_input_flags_t flags;
+ const char* kStreamName ;
+ audio_source_t kInputSource;
+ char *file_name;
+ volatile bool thread_exit;
+};
+
+typedef struct {
+ qahw_module_handle_t *qahw_in_hal_handle;
+ qahw_module_handle_t *qahw_out_hal_handle;
+ audio_io_handle_t handle;
+ char* filename;
+ FILE* file_stream;
+ char* timestamp_filename;
+ FILE* timestamp_file_ptr;
+ char* framesize_filename;
+ FILE* framesize_file_ptr;
+ int filetype;
+ int stream_index;
+ audio_devices_t output_device;
+ audio_devices_t input_device;
+ audio_config_t config;
+ audio_output_flags_t flags;
+ qahw_stream_handle_t* out_handle;
+ qahw_stream_handle_t* in_handle;
+ int channels;
+ aac_format_type_t aac_fmt_type;
+ wma_format_type_t wma_fmt_type;
+ char *kvpair_values;
+ bool flags_set;
+ usb_mode_type_t usb_mode;
+ int effect_index;
+ int effect_preset_strength;
+ bool drift_query;
+ bool drift_correction;
+ bool play_later;
+ char *device_url;
+ thread_func_t ethread_func;
+ thread_data_t *ethread_data;
+ cmd_data_t cmd_data;
+ int bytes_to_read;
+ qap_module_handle_t qap_module_handle;
+ bool sec_input;
+ bool system_input;
+ pthread_cond_t write_cond;
+ pthread_mutex_t write_lock;
+ pthread_cond_t drain_cond;
+ pthread_mutex_t drain_lock;
+ bool interactive_strm;
+}stream_config;
+
+
+qahw_module_handle_t * load_hal(audio_devices_t dev);
+int unload_hals();
+int get_wav_header_length (FILE* file_stream);
+
+#ifndef QAP
+#define hal_test_qap_usage() (0)
+#define qap_wrapper_get_single_kvp(key, kv_pairs, status) (0)
+#define qap_wrapper_session_open(kv_pairs, stream_data, num_of_streams) (0)
+#define qap_wrapper_session_close() (0)
+#define qap_wrapper_stream_open(stream_data) (0)
+#define qap_wrapper_get_cmd_string_from_arg_array(argc, argv, status) (0)
+#define qap_wrapper_start_stream (stream_data) (0)
+#define is_qap_session_active(argc, argv, kvp_string) (0)
+#define start_playback_through_qap(kvp_string, num_of_streams) (0)
+#else
+void hal_test_qap_usage();
+char * qap_wrapper_get_single_kvp(const char *key, const char *kv_pairs, int *status);
+int qap_wrapper_session_open(char *kv_pairs, void* stream_data, int num_of_streams);
+int qap_wrapper_session_close();
+qap_module_handle_t qap_wrapper_stream_open(void* stream_data);
+char * qap_wrapper_get_cmd_string_from_arg_array(int argc, char * argv[], int *status);
+void *qap_wrapper_start_stream (void* stream_data);
+bool is_qap_session_active(int argc, char* argv[], char *kvp_string);
+int start_playback_through_qap(char * kvp_string, int num_of_streams);
+#endif
+#endif /* QAHW_PLAYBACK_TEST_H */
diff --git a/qahw_api/test/qap_wrapper_extn.c b/qahw_api/test/qap_wrapper_extn.c
new file mode 100644
index 0000000..58580dc
--- /dev/null
+++ b/qahw_api/test/qap_wrapper_extn.c
@@ -0,0 +1,1244 @@
+/*
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2015 The Android Open Source Project *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* Test app extension to exercise QAP (Non-tunnel Decode) */
+
+#include <ctype.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <cutils/properties.h>
+#include <cutils/list.h>
+#include <cutils/log.h>
+#include <cutils/str_parms.h>
+#include <system/audio.h>
+#include <qap_api.h>
+#include <qti_audio.h>
+#include "qahw_playback_test.h"
+
+#undef LOG_TAG
+#define LOG_TAG "HAL_TEST"
+#undef LOG_NDEBUG
+/*#define LOG_NDEBUG 0*/
+
+#if LINUX_ENABLED
+#define QAC_LIB_MS12 "/usr/lib/libdolby_ms12_wrapper.so"
+#define QAC_LIB_M8 "/usr/lib/libdts_m8_wrapper.so"
+#else
+#define QAC_LIB_MS12 "/system/lib/libdolby_ms12_wrapper.so"
+#define QAC_LIB_M8 "/system/lib/libdts_m8_wrapper.so"
+#endif
+
+#define SESSION_BLURAY 1
+#define SESSION_BROADCAST 2
+#define MAX_OUTPUT_CHANNELS 8
+#define FRAME_SIZE 2048*2
+#define MAX_BUFFER_SIZE 13000
+#define CONTIGUOUS_TIMESTAMP 0x7fffffff
+
+qap_lib_handle_t ms12_lib_handle = NULL;
+qap_lib_handle_t m8_lib_handle = NULL;
+qap_session_handle_t qap_session_handle = NULL;
+qahw_module_handle_t *qap_out_hal_handle = NULL;
+qahw_module_handle_t *qap_out_spk_handle = NULL;
+qahw_module_handle_t *qap_out_hdmi_handle = NULL;
+qahw_module_handle_t *qap_out_hp_handle = NULL;
+
+audio_io_handle_t qap_stream_out_spk_handle = 0x999;
+audio_io_handle_t qap_stream_out_mch_handle = 0x998;
+audio_io_handle_t qap_stream_out_hp_handle = 0x997;
+
+FILE *fp_output_writer_spk = NULL;
+FILE *fp_output_writer_hp = NULL;
+FILE *fp_output_writer_mch = NULL;
+FILE *fp_output_timestamp_file = NULL;
+unsigned char data_buf[MAX_BUFFER_SIZE];
+uint32_t output_device_id = 0;
+uint16_t input_streams_count = 0;
+
+bool hdmi_connected = false;
+bool play_through_bt = false;
+bool encode = false;
+bool dolby_formats = false;
+bool dts_formats = false;
+bool timestamp_mode = false;
+int data_write_count = 0;
+int data_callback_count = 0;
+
+pthread_t main_input_thread;
+pthread_attr_t main_input_thrd_attr;
+pthread_cond_t main_eos_cond;
+pthread_mutex_t main_eos_lock;
+pthread_cond_t sec_eos_cond;
+pthread_mutex_t sec_eos_lock;
+
+qap_session_outputs_config_t session_output_config;
+bool session_output_configured = false;
+clock_t tcold_start, tcold_stop;
+clock_t tcont_start, tcont_stop;
+bool has_system_input = false;
+char session_kv_pairs[256] = {0};
+
+static void qap_wrapper_measure_kpi_values(clock_t tcold_start, clock_t tcold_stop,
+ clock_t tcont_start, clock_t tcont_stop)
+{
+ double cold_time_latency, cont_time_latency;
+ cold_time_latency = ((double)(tcold_stop - tcold_start))/CLOCKS_PER_SEC;
+ cont_time_latency = ((double)(tcont_stop - tcont_start))/CLOCKS_PER_SEC;
+ fprintf(stdout, "cold time latency %lf ms and cont time latency %lf ms\n", cold_time_latency*1000, cont_time_latency*1000);
+}
+
+static void qap_wrapper_read_frame_size_from_file(qap_audio_buffer_t *buffer, FILE *fp_framesize)
+{
+ if (NULL != fp_framesize) {
+ char tempstr[100];
+ fgets(tempstr, sizeof(tempstr), fp_framesize);
+ buffer->common_params.size = atoi(tempstr);
+ }
+}
+
+static void read_bytes_timestamps_from_file(qap_audio_buffer_t *buffer, FILE *fp_timestamp, FILE *fp_input_file)
+{
+ if (NULL != fp_timestamp) {
+ char tempstr[100];
+ int seek_offset = 0;
+ fgets(tempstr, sizeof(tempstr), fp_timestamp);
+ printf("%s and tempstr is %s \n", __FUNCTION__, tempstr);
+ char * token = strtok(tempstr, ",");
+ if (token != NULL) {
+ buffer->common_params.size = atoi(token);
+ if(token!= NULL) {
+ token = strtok(NULL, ",");
+ if (token!= NULL) {
+ buffer->common_params.timestamp = atoi(token);
+ ALOGV("%s and timestamp to be pushed to queue is %lld", __FUNCTION__, buffer->common_params.timestamp);
+ }
+ token = strtok(NULL, ",");
+ if (token != NULL) {
+ seek_offset = atoi(token);
+ if (fp_input_file && seek_offset > 0)
+ fseek(fp_input_file, seek_offset, SEEK_CUR);
+ }
+ }
+ }
+ }
+}
+
+bool is_qap_session_active(int argc, char* argv[], char *kvp_string) {
+ char *qap_kvp = NULL;
+ char *cmd_str = NULL;
+ char *tmp_str = NULL;
+ int status = 0;
+ cmd_str = (char *)qap_wrapper_get_cmd_string_from_arg_array(argc, argv, &status);
+ if (status > 0) {
+ qap_kvp = qap_wrapper_get_single_kvp("qap", cmd_str, &status);
+ if (qap_kvp == NULL) {
+ return false;
+ }
+ strncpy(kvp_string, cmd_str, strlen(cmd_str));
+ if (cmd_str != NULL) {
+ free(cmd_str);
+ cmd_str = NULL;
+ }
+ }
+ return true;
+}
+
+#ifdef QAP
+char *qap_wrapper_get_single_kvp(const char *key, const char *kv_pairs, int *status)
+{
+ char *kvp = NULL;
+ char *tempstr = NULL;
+ char *token = NULL;
+ char *context1 = NULL;
+ char *context2 = NULL;
+ char *temp_kvp = NULL;
+ char *temp_key = NULL;
+
+ if (NULL == key || NULL == kv_pairs) {
+ *status = -EINVAL;
+ return NULL;
+ }
+ tempstr = strdup(kv_pairs);
+ token = strtok_r(tempstr, ";", &context1);
+ if (token != NULL) {
+ temp_kvp = strdup(token);
+ if (temp_kvp != NULL) {
+ temp_key = strtok_r(temp_kvp, "=", &context2);
+ if (!strncmp(key, temp_key, strlen(key))) {
+ kvp = malloc((strlen(token) + 1) * sizeof(char));
+ memset(kvp, 0, strlen(token) + 1);
+ strncat(kvp, token, strlen(token));
+ return kvp;
+ }
+ free(temp_kvp);
+ }
+ while (token != NULL) {
+ token = strtok_r(NULL, ";", &context1);
+ if (token != NULL) {
+ temp_kvp = strdup(token);
+ if (temp_kvp != NULL) {
+ temp_key = strtok_r(temp_kvp, "=", &context2);
+ if (!strncmp(key, temp_key, strlen(key))) {
+ kvp = malloc((strlen(token) + 1) * sizeof(char));
+ memset(kvp, 0, strlen(token) + 1);
+ strncat(kvp, token, strlen(token));
+ return kvp;
+ }
+ free(temp_kvp);
+ temp_kvp = NULL;
+ }
+ }
+ }
+ free(tempstr);
+ }
+ return NULL;
+}
+#endif
+
+int *qap_wrapper_get_int_value_array(const char *kvp, int *count, int *status __unused)
+{
+ char *tempstr1;
+ char *tempstr2;
+ char *l1;
+ char *l2 __unused;
+ char *ctx1;
+ char *ctx2 __unused;
+ int *val = NULL;
+ int i = 0;
+ char *s;
+ char *endstr;
+ int temp = 0;
+ char *jump;
+
+ *count = 0;
+ if (kvp == NULL) {
+ return NULL;
+ }
+ tempstr1 = strdup(kvp);
+ l1 = strtok_r(tempstr1, "=", &ctx1);
+ if (l1 != NULL) {
+ /* jump from key to value */
+ l1 = strtok_r(NULL, "=", &ctx1);
+ if (l1 != NULL) {
+ tempstr2 = strdup(l1);
+
+ s = tempstr2;
+ for (i=0; s[i]; s[i]==',' ? i++ : *s++);
+
+ temp = i;
+ val = malloc((i + 1)*sizeof(int));
+ i = 0;
+ val[i++] = strtol(tempstr2, &endstr, 0);
+
+ while (i <= temp) {
+ jump = endstr + 1;
+ val[i++] = strtol(jump, &endstr, 0);
+ }
+ free(tempstr2);
+ }
+ }
+ free(tempstr1);
+ *count = i;
+ return val;
+}
+
+char * qap_wrapper_get_cmd_string_from_arg_array(int argc, char * argv[], int *status)
+{
+ char * kvps;
+ int idx;
+ int has_key = 0;
+ int mem = 0;
+
+ fprintf(stdout, "%s %d in", __func__, __LINE__);
+ if (argc < 2 || NULL == argv) {
+ fprintf(stdout, "%s %d returning EINVAL\n", __func__, __LINE__);
+ *status = -EINVAL;
+ return NULL;
+ }
+
+ for (idx = 0; idx < argc; idx++) {
+ mem += (strlen(argv[idx]) + 2); /* Extra byte to insert delim ';' */
+ }
+
+ if (mem > 0)
+ kvps = malloc(mem * sizeof(char));
+ else {
+ *status = -EINVAL;
+ fprintf(stdout, "%s %d returning EINVAL\n", __func__, __LINE__);
+ return NULL;
+ }
+
+ if (NULL == kvps) {
+ *status = -ENOMEM;
+ fprintf(stdout, "%s %d returning EINVAL\n", __func__, __LINE__);
+ return NULL;
+ }
+
+ for (idx = 1; idx < argc; idx++) {
+ if (( argv[idx][0] == '-') &&
+ (argv[idx][1] < '0' || argv[idx][1] > '9')) {
+ if (has_key) {
+ strcat(kvps, ";");
+ has_key = 0;
+ }
+ strcat(kvps, argv[idx]+1);
+ strcat(kvps, "=");
+ has_key = 1;
+ } else if (has_key) {
+ strcat(kvps, argv[idx]);
+ strcat(kvps, ";");
+ has_key = 0;
+ } else {
+ *status = -EINVAL;
+ if (kvps != NULL) {
+ free(kvps);
+ kvps = NULL;
+ }
+ fprintf(stdout, "%s %d returning EINVAL\n", __func__, __LINE__);
+ return NULL;
+ }
+ }
+ *status = mem;
+ fprintf(stdout, "%s %d returning\n", __func__, __LINE__);
+ return kvps;
+}
+
+static int qap_wrapper_map_input_format(audio_format_t audio_format, qap_audio_format_t *format)
+{
+ if (audio_format == AUDIO_FORMAT_AC3) {
+ *format = QAP_AUDIO_FORMAT_AC3;
+ fprintf(stdout, "File Format is AC3!\n");
+ } else if (audio_format == AUDIO_FORMAT_E_AC3) {
+ *format = QAP_AUDIO_FORMAT_EAC3;
+ fprintf(stdout, "File Format is E_AC3!\n");
+ } else if ((audio_format == AUDIO_FORMAT_AAC_ADTS_LC) ||
+ (audio_format == AUDIO_FORMAT_AAC_ADTS_HE_V1) ||
+ (audio_format == AUDIO_FORMAT_AAC_ADTS_HE_V2) ||
+ (audio_format == AUDIO_FORMAT_AAC_LC) ||
+ (audio_format == AUDIO_FORMAT_AAC_HE_V1) ||
+ (audio_format == AUDIO_FORMAT_AAC_HE_V2) ||
+ (audio_format == AUDIO_FORMAT_AAC_LATM_LC) ||
+ (audio_format == AUDIO_FORMAT_AAC_LATM_HE_V1) ||
+ (audio_format == AUDIO_FORMAT_AAC_LATM_HE_V2)) {
+ *format = QAP_AUDIO_FORMAT_AAC_ADTS;
+ fprintf(stdout, "File Format is AAC!\n");
+ } else if (audio_format == AUDIO_FORMAT_DTS) {
+ *format = QAP_AUDIO_FORMAT_DTS;
+ fprintf(stdout, "File Format is DTS!\n");
+ } else if (audio_format == AUDIO_FORMAT_DTS_HD) {
+ *format = QAP_AUDIO_FORMAT_DTS_HD;
+ fprintf(stdout, "File Format is DTS_HD!\n");
+ } else if (audio_format == AUDIO_FORMAT_PCM_16_BIT) {
+ *format = QAP_AUDIO_FORMAT_PCM_16_BIT;
+ fprintf(stdout, "File Format is PCM_16!\n");
+ } else if (audio_format == AUDIO_FORMAT_PCM_32_BIT) {
+ *format = QAP_AUDIO_FORMAT_PCM_32_BIT;
+ fprintf(stdout, "File Format is PCM_32!\n");
+ } else if (audio_format == AUDIO_FORMAT_PCM_24_BIT_PACKED) {
+ *format = QAP_AUDIO_FORMAT_PCM_24_BIT_PACKED;
+ fprintf(stdout, "File Format is PCM_24!\n");
+ } else if ((audio_format == AUDIO_FORMAT_PCM_8_BIT) ||
+ (audio_format == AUDIO_FORMAT_PCM_8_24_BIT)) {
+ *format = QAP_AUDIO_FORMAT_PCM_8_24_BIT;
+ fprintf(stdout, "File Format is PCM_8_24!\n");
+ } else {
+ fprintf(stdout, "File Format not supported!\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+char *get_string_value(const char *kvp, int *status)
+{
+ char *tempstr1 = NULL;
+ char *tempstr2 = NULL;
+ char *l1;
+ char *ctx1;
+ if (kvp == NULL)
+ return NULL;
+ tempstr1 = strdup(kvp);
+ l1 = strtok_r(tempstr1, "=", &ctx1);
+ if (l1 != NULL) {
+ /* jump from key to value */
+ l1 = strtok_r(NULL, "=", &ctx1);
+ if (l1 != NULL)
+ tempstr2 = strdup(l1);
+ }
+ free(tempstr1);
+ return tempstr2;
+}
+
+int qap_wrapper_write_to_hal(qahw_stream_handle_t* out_handle, char *data, size_t bytes)
+{
+ ssize_t ret;
+ qahw_out_buffer_t out_buf;
+
+ memset(&out_buf,0, sizeof(qahw_out_buffer_t));
+ out_buf.buffer = data;
+ out_buf.bytes = bytes;
+
+ ret = qahw_out_write(out_handle, &out_buf);
+ if (ret < 0)
+ fprintf(stderr, "%s::%d: writing data to hal failed (ret = %zd)\n", __func__, __LINE__, ret);
+ else if (ret != bytes)
+ fprintf(stdout, "%s::%d provided bytes %zd, written bytes %d\n",__func__, __LINE__, bytes, ret);
+
+ return ret;
+}
+
+static void close_output_streams()
+{
+ int ret;
+ if (qap_out_hal_handle && qap_out_spk_handle) {
+ ret = qahw_out_standby(qap_out_spk_handle);
+ if (ret)
+ fprintf(stderr, "%s::%d: out standby failed %d \n", __func__, __LINE__, ret);
+ if (play_through_bt) {
+ fprintf(stdout, "%s::%d: disconnecting BT\n", __func__, __LINE__);
+ char param[100] = {0};
+ snprintf(param, sizeof(param), "%s=%d", "disconnect", AUDIO_DEVICE_OUT_BLUETOOTH_A2DP);
+ qahw_set_parameters(qap_out_hal_handle, param);
+ }
+ fprintf(stdout, "%s::%d: closing output stream\n", __func__, __LINE__);
+ ret = qahw_close_output_stream(qap_out_spk_handle);
+ if (ret)
+ fprintf(stderr, "%s::%d: could not close output stream, error - %d\n", __func__, __LINE__, ret);
+ qap_out_spk_handle = NULL;
+ }
+ if (qap_out_hal_handle && qap_out_hp_handle) {
+ ret = qahw_out_standby(qap_out_hp_handle);
+ if (ret)
+ fprintf(stderr, "%s::%d: out standby failed %d \n", __func__, __LINE__, ret);
+ fprintf(stdout, "%s::%d: closing output stream\n", __func__, __LINE__);
+ ret = qahw_close_output_stream(qap_out_hp_handle);
+ if (ret)
+ fprintf(stderr, "%s::%d: could not close output stream, error - %d\n", __func__, __LINE__, ret);
+ qap_out_hp_handle = NULL;
+ }
+ if (qap_out_hal_handle && qap_out_hdmi_handle) {
+ char param[100] = {0};
+ snprintf(param, sizeof(param), "%s=%d", "disconnect", AUDIO_DEVICE_OUT_HDMI);
+ ret = qahw_out_standby(qap_out_hdmi_handle);
+ if (ret)
+ fprintf(stderr, "%s::%d: out standby failed %d\n", __func__, __LINE__, ret);
+ qahw_set_parameters(qap_out_hal_handle, param);
+ fprintf(stdout, "%s::%d: closing output stream\n", __func__, __LINE__);
+ ret = qahw_close_output_stream(qap_out_hdmi_handle);
+ if (ret)
+ fprintf(stderr, "%s::%d: could not close output stream, error - %d\n", __func__, __LINE__, ret);
+ qap_out_hdmi_handle = NULL;
+ }
+}
+
+void qap_wrapper_session_callback(qap_session_handle_t session_handle __unused, void* priv_data __unused, qap_callback_event_t event_id, int size __unused, void *data)
+{
+ int ret = 0;
+ int bytes_written = 0;
+ int bytes_remaining = 0;
+ int offset = 0;
+ audio_output_flags_t flags;
+ flags = (AUDIO_OUTPUT_FLAG_NON_BLOCKING
+ | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD
+ | AUDIO_OUTPUT_FLAG_DIRECT);/*Need to add Main and Associated Flags during mixing case*/
+ ALOGV("%s %d Received event id %d\n", __func__, __LINE__, event_id);
+ switch (event_id) {
+ case QAP_CALLBACK_EVENT_EOS:
+ ALOGV("%s %d Received Main Input EOS", __func__, __LINE__);
+ pthread_mutex_lock(&main_eos_lock);
+ pthread_cond_signal(&main_eos_cond);
+ pthread_mutex_unlock(&main_eos_lock);
+
+ close_output_streams();
+ if (qap_out_hal_handle) {
+ unload_hals();
+ qap_out_hal_handle = NULL;
+ }
+ break;
+ case QAP_CALLBACK_EVENT_EOS_ASSOC:
+ case QAP_CALLBACK_EVENT_MAIN_2_EOS:
+ if (!has_system_input){
+ ALOGV("%s %d Received Secondary Input EOS", __func__, __LINE__);
+ pthread_mutex_lock(&sec_eos_lock);
+ pthread_cond_signal(&sec_eos_cond);
+ pthread_mutex_unlock(&sec_eos_lock);
+ }
+ break;
+ case QAP_CALLBACK_EVENT_ERROR:
+ break;
+ case QAP_CALLBACK_EVENT_SUCCESS:
+ break;
+ case QAP_CALLBACK_EVENT_METADATA:
+ case QAP_CALLBACK_EVENT_OUTPUT_CFG_CHANGE:
+ break;
+ case QAP_CALLBACK_EVENT_DATA:
+ if (data != NULL) {
+ if (kpi_mode) {
+ data_callback_count++;
+ if (data_callback_count == 1) {
+ tcold_stop = clock();
+ } else if (data_callback_count == 15) {
+ tcont_stop = clock();
+ qap_wrapper_measure_kpi_values(tcold_start, tcold_stop, tcont_start, tcont_stop);
+ }
+ }
+ qap_audio_buffer_t *buffer = (qap_audio_buffer_t *) data;
+ if (qap_out_hal_handle == NULL) {
+ fprintf(stdout, "%s::%d: device id %d\n",__func__, __LINE__, buffer->buffer_parms.output_buf_params.output_id);
+ qap_out_hal_handle = load_hal(buffer->buffer_parms.output_buf_params.output_id);
+ if (qap_out_hal_handle == NULL) {
+ fprintf(stderr, "Failed log load HAL\n");
+ return;
+ }
+ }
+
+ if (buffer && timestamp_mode) {
+ char ch[100] = {0};
+ if (fp_output_timestamp_file == NULL) {
+ fp_output_timestamp_file =
+ fopen("/sdcard/output_timestamp_file.txt","w");
+ if(fp_output_timestamp_file) {
+ fprintf(stdout, "output file :: "
+ "/sdcard/output_file_timestamp.txt"
+ " has been generated.");
+ }
+ }
+ if (fp_output_timestamp_file) {
+ sprintf(ch, "%d,%lld\n", buffer->common_params.size, buffer->common_params.timestamp);
+ fprintf(stdout, "%s: %s", __func__, ch);
+ ret = fwrite((char *)&ch, sizeof(char),
+ strlen(ch), fp_output_timestamp_file);
+ fflush(fp_output_timestamp_file);
+ }
+ }
+
+ if (buffer && buffer->common_params.data) {
+ if (buffer->buffer_parms.output_buf_params.output_id &
+ AUDIO_DEVICE_OUT_HDMI) {
+ if (enable_dump && fp_output_writer_mch == NULL) {
+ fp_output_writer_mch =
+ fopen("/sdcard/output_hdmi.dump","wb");
+ if (fp_output_writer_mch) {
+ fprintf(stdout, "output file :: "
+ "/sdcard/output_hdmi.dump"
+ " has been generated.\n");
+ } else {
+ fprintf(stderr, "Failed open hdmi dump file\n");
+ }
+ }
+ if (fp_output_writer_mch) {
+ ret = fwrite((unsigned char *)buffer->common_params.data, sizeof(unsigned char),
+ buffer->common_params.size, fp_output_writer_mch);
+ fflush(fp_output_writer_mch);
+ }
+ if (!hdmi_connected) {
+ char param[100] = {0};
+ snprintf(param, sizeof(param), "%s=%d", "connect", AUDIO_DEVICE_OUT_HDMI);
+ qahw_set_parameters(qap_out_hal_handle, param);
+ hdmi_connected = true;
+ }
+ if (hdmi_connected && qap_out_hdmi_handle == NULL) {
+ struct audio_config config;
+ audio_devices_t devices;
+ config.offload_info.version = AUDIO_INFO_INITIALIZER.version;
+ config.offload_info.size = AUDIO_INFO_INITIALIZER.size;
+ config.sample_rate = config.offload_info.sample_rate =
+ session_output_config.output_config->sample_rate;
+ if (session_output_config.output_config->bit_width == 24) {
+ config.format = config.offload_info.format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+ config.offload_info.bit_width = 24;
+ } else {
+ config.format = config.offload_info.format = AUDIO_FORMAT_PCM_16_BIT;
+ config.offload_info.bit_width = 16;
+ }
+
+ if (session_output_config.output_config->channels == 2) {
+ config.offload_info.channel_mask = config.channel_mask =
+ AUDIO_CHANNEL_OUT_STEREO;
+ } else {
+ config.offload_info.channel_mask = config.channel_mask =
+ audio_channel_out_mask_from_count(MAX_OUTPUT_CHANNELS);
+ }
+ devices = AUDIO_DEVICE_OUT_HDMI;
+
+ ret = qahw_open_output_stream(qap_out_hal_handle, qap_stream_out_mch_handle, devices,
+ flags, &config, &qap_out_hdmi_handle, "stream");
+
+ if (ret) {
+ fprintf(stdout, "%s:%d could not open output stream, error - %d \n", __func__, __LINE__, ret);
+ return;
+ }
+ ret = qahw_out_set_volume(qap_out_hdmi_handle, vol_level, vol_level);
+ if (ret < 0)
+ fprintf(stderr, "unable to set volume\n");
+ }
+ if (qap_out_hdmi_handle) {
+ bytes_written = qap_wrapper_write_to_hal(qap_out_hdmi_handle, buffer->common_params.data, buffer->common_params.size);
+ if (bytes_written == -1) {
+ fprintf(stderr, "%s::%d write failed in hal\n", __func__, __LINE__);
+ }
+ }
+ }
+ if (buffer->buffer_parms.output_buf_params.output_id & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
+ if (enable_dump && fp_output_writer_hp == NULL) {
+ fp_output_writer_hp =
+ fopen("/sdcard/output_hp.dump","wb");
+ if (fp_output_writer_hp) {
+ fprintf(stdout, "output file :: "
+ "/sdcard/output_hp.dump"
+ " has been generated.\n");
+ } else {
+ fprintf(stderr, "Failed open hp dump file\n");
+ }
+ }
+ if (fp_output_writer_hp) {
+ ret = fwrite((unsigned char *)buffer->common_params.data, sizeof(unsigned char),
+ buffer->common_params.size, fp_output_writer_hp);
+ fflush(fp_output_writer_hp);
+ }
+ if (qap_out_hp_handle == NULL) {
+ struct audio_config config;
+ audio_devices_t devices;
+ config.offload_info.version = AUDIO_INFO_INITIALIZER.version;
+ config.offload_info.size = AUDIO_INFO_INITIALIZER.size;
+ config.sample_rate = config.offload_info.sample_rate =
+ session_output_config.output_config->sample_rate;
+ if (session_output_config.output_config->bit_width == 24) {
+ config.format = config.offload_info.format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+ config.offload_info.bit_width = 24;
+ } else {
+ config.format = config.offload_info.format = AUDIO_FORMAT_PCM_16_BIT;
+ config.offload_info.bit_width = 16;
+ }
+
+ config.offload_info.channel_mask = config.channel_mask =
+ AUDIO_CHANNEL_OUT_STEREO;
+ devices = AUDIO_DEVICE_OUT_LINE;//ToDO - Need to change to AUDIO_DEVICE_OUT_WIRED_HEADPHONE
+
+ ret = qahw_open_output_stream(qap_out_hal_handle, qap_stream_out_hp_handle, devices,
+ flags, &config, &qap_out_hp_handle, "stream");
+
+ if (ret) {
+ fprintf(stderr, "%s:%d could not open output stream, error - %d \n", __func__, __LINE__, ret);
+ return;
+ }
+ ret = qahw_out_set_volume(qap_out_hp_handle, vol_level, vol_level);
+ if (ret < 0)
+ fprintf(stderr, "unable to set volume\n");
+ }
+ if (qap_out_hp_handle) {
+ bytes_written = qap_wrapper_write_to_hal(qap_out_hp_handle, buffer->common_params.data, buffer->common_params.size);
+ if (bytes_written == -1) {
+ fprintf(stderr, "%s::%d write failed in hal\n", __func__, __LINE__);
+ }
+ }
+ }
+ if (buffer->buffer_parms.output_buf_params.output_id & AUDIO_DEVICE_OUT_SPEAKER) {
+ if (enable_dump && fp_output_writer_spk == NULL) {
+ char ch[4] = {0};
+ fp_output_writer_spk =
+ fopen("/sdcard/output_speaker.dump","wb");
+ if (fp_output_writer_spk) {
+ fprintf(stdout, "output file :: "
+ "/sdcard/output_speaker.dump"
+ " has been generated.\n");
+ if (!dts_formats) {
+ ret = fwrite((unsigned char *)&ch, sizeof(unsigned char),
+ 4, fp_output_writer_spk);
+ }
+ } else {
+ fprintf(stderr, "Failed open speaker dump file\n");
+ }
+ }
+ if (fp_output_writer_spk) {
+ ret = fwrite((unsigned char *)buffer->common_params.data, sizeof(unsigned char),
+ buffer->common_params.size, fp_output_writer_spk);
+ fflush(fp_output_writer_spk);
+ }
+ if (qap_out_spk_handle == NULL) {
+ struct audio_config config;
+ audio_devices_t devices;
+ config.offload_info.version = AUDIO_INFO_INITIALIZER.version;
+ config.offload_info.size = AUDIO_INFO_INITIALIZER.size;
+ config.sample_rate = config.offload_info.sample_rate =
+ session_output_config.output_config->sample_rate;
+ if (session_output_config.output_config->bit_width == 24) {
+ config.format = config.offload_info.format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+ config.offload_info.bit_width = 24;
+ } else {
+ config.format = config.offload_info.format = AUDIO_FORMAT_PCM_16_BIT;
+ config.offload_info.bit_width = 16;
+ }
+
+ config.offload_info.channel_mask = config.channel_mask =
+ AUDIO_CHANNEL_OUT_STEREO;
+ if (play_through_bt) {
+ fprintf(stderr, "%s::%d: connecting BT\n", __func__, __LINE__);
+ char param[100] = {0};
+ snprintf(param, sizeof(param), "%s=%d", "connect", AUDIO_DEVICE_OUT_BLUETOOTH_A2DP);
+ qahw_set_parameters(qap_out_hal_handle, param);
+ devices = AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
+ } else {
+ devices = AUDIO_DEVICE_OUT_SPEAKER;
+ }
+ fprintf(stderr, "%s::%d: open output for device %d\n", __func__, __LINE__, devices);
+ ret = qahw_open_output_stream(qap_out_hal_handle, qap_stream_out_spk_handle, devices,
+ flags, &config, &qap_out_spk_handle, "stream");
+
+ if (ret) {
+ fprintf(stderr, "%s:%d could not open output stream, error - %d \n", __func__, __LINE__, ret);
+ return;
+ }
+ ret = qahw_out_set_volume(qap_out_spk_handle, vol_level, vol_level);
+ if (ret < 0)
+ fprintf(stderr, "unable to set volume\n");
+ }
+ if (qap_out_spk_handle) {
+ bytes_written = qap_wrapper_write_to_hal(qap_out_spk_handle, buffer->common_params.data, buffer->common_params.size);
+ if (bytes_written == -1) {
+ fprintf(stderr, "%s::%d write failed in hal\n", __func__, __LINE__);
+ }
+ }
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void qap_wrapper_is_dap_enabled(char *kv_pairs, int out_device_id) {
+ int status = 0;
+ int temp = 0;
+ char *dap_kvp = NULL;
+ int *dap_value = NULL;
+ int dap_enable = 0;
+
+ dap_kvp = qap_wrapper_get_single_kvp("dap_enable", kv_pairs, &status);
+ if (dap_kvp != NULL) {
+ dap_value = qap_wrapper_get_int_value_array(dap_kvp, &temp, &status);
+ if (dap_value != NULL)
+ dap_enable = dap_value[0];
+ if (dap_enable) {
+ fprintf(stdout, "dap enable %d and device id %d\n", dap_enable, out_device_id);
+ char *dev_kvp = NULL;
+ if (out_device_id == AUDIO_DEVICE_OUT_SPEAKER) {
+ dev_kvp = (char *) calloc(1, status + strlen("o_device=1; "));
+ if (dev_kvp != NULL) {
+ strcat(dev_kvp, "o_device=1;");
+ strcat(session_kv_pairs, dev_kvp);
+ fprintf(stdout, "session set params %s\n", session_kv_pairs);
+ free(dev_kvp);
+ dev_kvp = NULL;
+ }
+ } else if ((out_device_id == AUDIO_DEVICE_OUT_LINE)||
+ (out_device_id == AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) {
+ dev_kvp = (char *) calloc(1, status + strlen("o_device=2; "));
+ if (dev_kvp != NULL) {
+ strcat(dev_kvp, "o_device=2;");
+ strcat(session_kv_pairs, dev_kvp);
+ fprintf(stdout, "session set params %s\n", session_kv_pairs);
+ free(dev_kvp);
+ dev_kvp = NULL;
+ }
+ }
+ }
+ free(dap_kvp);
+ dap_kvp = NULL;
+ }
+}
+
+int qap_wrapper_session_open(char *kv_pairs, void* stream_data, int num_of_streams)
+{
+ int status = 0;
+ int ret = 0;
+ int i;
+ int temp = 0;
+ stream_config *stream = (stream_config *)stream_data;
+ char *session_type_kvp = NULL;
+ char *encode_kvp = NULL;
+ int *temp_val = NULL;
+ char *bitwidth_kvp = NULL;
+ uint8_t session_type = SESSION_BLURAY;
+
+ tcold_start = clock();
+ memset(&session_output_config, 0, sizeof(session_output_config));
+ strcpy(session_kv_pairs, kv_pairs);
+
+ session_type_kvp = qap_wrapper_get_single_kvp("broadcast", kv_pairs, &status);
+ if (session_type_kvp != NULL) {
+ session_type = SESSION_BROADCAST;
+ fprintf(stdout, "Session Type is Broadcast\n");
+ free(session_type_kvp);
+ session_type_kvp = NULL;
+ } else {
+ fprintf(stdout, "Session Type is Bluray\n");
+ }
+
+ if (session_type == SESSION_BLURAY) {
+ if ((stream->filetype == FILE_WAV) ||
+ (stream->filetype == FILE_AAC)) {
+ fprintf(stderr, "Format is not supported for BD usecase\n");
+ return -EINVAL;
+ }
+ if (num_of_streams > 1) {
+ fprintf(stderr, "Please specifiy proper session type\n");
+ return -EINVAL;
+ }
+ }
+
+ if (stream->filetype == FILE_DTS) {
+ m8_lib_handle = (qap_session_handle_t) qap_load_library(QAC_LIB_M8);
+ if (m8_lib_handle == NULL) {
+ fprintf(stdout, "Failed to load M8 library\n");
+ return -EINVAL;
+ }
+ fprintf(stdout, "loaded M8 library\n");
+ dts_formats = true;
+ } else if ((stream->filetype == FILE_AC3) ||
+ (stream->filetype == FILE_EAC3) ||
+ (stream->filetype == FILE_EAC3_JOC) ||
+ (stream->filetype == FILE_WAV) ||
+ (stream->filetype == FILE_AAC) ||
+ (stream->filetype == FILE_AAC_ADTS) ||
+ (stream->filetype == FILE_AAC_LATM)) {
+ ms12_lib_handle = (qap_session_handle_t) qap_load_library(QAC_LIB_MS12);
+ if (ms12_lib_handle == NULL) {
+ fprintf(stderr, "Failed to load MS12 library\n");
+ return -EINVAL;
+ }
+ dolby_formats = true;
+ }
+
+ qap_wrapper_is_dap_enabled(kv_pairs, stream->output_device);
+
+ encode_kvp = qap_wrapper_get_single_kvp("od", kv_pairs, &status);
+ if (encode_kvp != NULL) {
+ encode = true;
+ free(encode_kvp);
+ encode_kvp = NULL;
+ }
+
+ encode_kvp = qap_wrapper_get_single_kvp("odp", kv_pairs, &status);
+ if (encode_kvp != NULL) {
+ encode = true;
+ free(encode_kvp);
+ encode_kvp = NULL;
+ }
+
+ encode_kvp = qap_wrapper_get_single_kvp("odts", kv_pairs, &status);
+ if (encode_kvp != NULL) {
+ encode = true;
+ free(encode_kvp);
+ encode_kvp = NULL;
+ }
+
+ if (stream->filetype == FILE_DTS)
+ session_output_config.output_config->bit_width = 24;
+
+ bitwidth_kvp = qap_wrapper_get_single_kvp("bitwidth", kv_pairs, &status);
+ if (bitwidth_kvp != NULL) {
+ temp_val = qap_wrapper_get_int_value_array(bitwidth_kvp, &temp, &status);
+ if (temp_val != NULL) {
+ if (stream->filetype == FILE_DTS)
+ session_output_config.output_config->bit_width = temp_val[0];
+ free(temp_val);
+ temp_val = NULL;
+ }
+ free(bitwidth_kvp);
+ bitwidth_kvp = NULL;
+ }
+
+ if ((session_type == SESSION_BROADCAST) && dolby_formats) {
+ fprintf(stdout, "%s::%d Setting BROADCAST session for dolby formats\n", __func__, __LINE__);
+ qap_session_handle = (qap_session_handle_t) qap_session_open(QAP_SESSION_BROADCAST, ms12_lib_handle);
+ if (qap_session_handle == NULL)
+ return -EINVAL;
+ } else if ((session_type == SESSION_BROADCAST) && dts_formats) {
+ fprintf(stdout, "%s::%d Setting BROADCAST session for dts formats\n", __func__, __LINE__);
+ qap_session_handle = (qap_session_handle_t) qap_session_open(QAP_SESSION_BROADCAST, m8_lib_handle);
+ if (qap_session_handle == NULL)
+ return -EINVAL;
+ } else if (session_type == SESSION_BLURAY) {
+ fprintf(stdout, "%s::%d Setting BD session\n", __func__, __LINE__);
+ if (!encode && dolby_formats) {
+ fprintf(stdout, "%s::%d Setting BD session for decoding dolby formats\n", __func__, __LINE__);
+ qap_session_handle = (qap_session_handle_t) qap_session_open(QAP_SESSION_DECODE_ONLY, ms12_lib_handle);
+ if (qap_session_handle == NULL)
+ return -EINVAL;
+ } else if (!encode && dts_formats) {
+ fprintf(stdout, "%s::%d Setting BD session for decoding dts formats \n", __func__, __LINE__, qap_session_handle);
+ qap_session_handle = (qap_session_handle_t) qap_session_open(QAP_SESSION_DECODE_ONLY, m8_lib_handle);
+ if (qap_session_handle == NULL)
+ return -EINVAL;
+ } else if (encode && dolby_formats) {
+ fprintf(stdout, "%s::%d Setting BD session for encoding dolby formats \n", __func__, __LINE__, qap_session_handle);
+ qap_session_handle = (qap_session_handle_t) qap_session_open(QAP_SESSION_ENCODE_ONLY, ms12_lib_handle);
+ if (qap_session_handle == NULL)
+ return -EINVAL;
+ } else if (encode && dts_formats) {
+ fprintf(stdout, "%s::%d Setting BD session for encoding dts formats \n", __func__, __LINE__, qap_session_handle);
+ qap_session_handle = (qap_session_handle_t) qap_session_open(QAP_SESSION_ENCODE_ONLY, m8_lib_handle);
+ if (qap_session_handle == NULL)
+ return -EINVAL;
+ }
+ }
+
+ ret = qap_session_set_callback(qap_session_handle, &qap_wrapper_session_callback);
+ if (ret != QAP_STATUS_OK) {
+ fprintf(stderr, "!!!! Please specify appropriate Session\n");
+ return -EINVAL;
+ }
+
+ if (stream->filetype == FILE_DTS) {
+ ALOGV("Session set params %s", session_kv_pairs);
+ ret = qap_session_cmd(qap_session_handle, QAP_SESSION_CMD_SET_KVPAIRS, sizeof(session_kv_pairs), session_kv_pairs, NULL, NULL);
+ if (ret != QAP_STATUS_OK) {
+ fprintf(stderr, "Session set params failed\n");
+ return -EINVAL;
+ }
+ }
+
+ pthread_mutex_init(&main_eos_lock, (const pthread_mutexattr_t *)NULL);
+ pthread_mutex_init(&sec_eos_lock, (const pthread_mutexattr_t *)NULL);
+ pthread_cond_init(&main_eos_cond, (const pthread_condattr_t *) NULL);
+ pthread_cond_init(&sec_eos_cond, (const pthread_condattr_t *) NULL);
+ fprintf(stdout, "Session open returing success\n");
+ return 0;
+}
+
+int qap_wrapper_session_close ()
+{
+ ALOGD("closing QAP session");
+ qap_session_close(qap_session_handle);
+ qap_session_handle = NULL;
+}
+
+void *qap_wrapper_start_stream (void* stream_data)
+{
+ int ret = 0;
+ qap_audio_buffer_t *buffer;
+ int8_t first_read = 1;
+ int bytes_wanted;
+ int bytes_read;
+ int bytes_consumed = 0, status = 0;;
+ qap_module_handle_t qap_module_handle = NULL;
+ stream_config *stream_info = (stream_config *)stream_data;
+ FILE *fp_input = stream_info->file_stream;
+ int is_buffer_available = 0;
+ char *temp_str = NULL;
+ void *reply_data;
+ char* temp_ptr = NULL;
+ qap_audio_format_t format;
+
+ if (fp_input == NULL) {
+ fprintf(stderr, "Open File Failed for %s\n", stream_info->filename);
+ pthread_exit(0);
+ }
+ qap_module_handle = stream_info->qap_module_handle;
+ buffer = (qap_audio_buffer_t *) calloc(1, sizeof(qap_audio_buffer_t));
+ if (buffer == NULL) {
+ fprintf(stderr, "%s::%d: Memory Alloc Error\n", __func__, __LINE__);
+ pthread_exit(0);
+ }
+ buffer->common_params.data = calloc(1, FRAME_SIZE);
+ if (buffer->common_params.data == NULL) {
+ fprintf(stderr, "%s::%d: Memory Alloc Error\n", __func__, __LINE__);
+ pthread_exit(0);
+ if (NULL != buffer) {
+ free( buffer);
+ buffer = NULL;
+ }
+ }
+ buffer->buffer_parms.output_buf_params.output_id = output_device_id;
+ fprintf(stdout, "%s::%d: output device id %d\n",
+ __func__, __LINE__, buffer->buffer_parms.output_buf_params.output_id);
+
+ fprintf(stdout, "Opened Input File %s format %d handle %p\n", stream_info->filename, format, fp_input);
+
+ ret = qap_module_cmd(qap_module_handle, QAP_MODULE_CMD_START, sizeof(QAP_MODULE_CMD_START), NULL, NULL, NULL);
+ if (ret != QAP_STATUS_OK) {
+ fprintf(stderr, "START failed\n");
+ pthread_exit(0);
+ if (NULL != buffer && NULL != buffer->common_params.data) {
+ free( buffer->common_params.data);
+ buffer->common_params.data = NULL;
+ free( buffer);
+ buffer = NULL;
+ }
+ }
+
+ do {
+ if (stream_info->filetype == FILE_WAV) {
+ if (first_read) {
+ first_read = 0;
+ int wav_header_len = get_wav_header_length(stream_info->file_stream);
+ fseek(fp_input, wav_header_len, SEEK_SET);
+ }
+ }
+ buffer->buffer_parms.input_buf_params.flags = QAP_BUFFER_NO_TSTAMP;
+ buffer->common_params.timestamp = QAP_BUFFER_NO_TSTAMP;
+ buffer->common_params.size = stream_info->bytes_to_read;
+ if (kpi_mode) {
+ if (stream_info->framesize_filename != NULL) {
+ if (!stream_info->framesize_file_ptr) {
+ stream_info->framesize_file_ptr = fopen(stream_info->framesize_filename, "r");
+ if (!stream_info->framesize_file_ptr) {
+ fprintf(stderr, "Cannot open audio file %s\n", stream_info->framesize_filename);
+ goto exit;
+ }
+ }
+ qap_wrapper_read_frame_size_from_file(buffer, stream_info->framesize_file_ptr);
+ } else {
+ fprintf(stdout, "%s Could not found frame size file\n", __FUNCTION__);
+ goto exit;
+ }
+ }
+
+ if (stream_info->timestamp_filename != NULL) {
+ if (!stream_info->timestamp_file_ptr) {
+ stream_info->timestamp_file_ptr = fopen(stream_info->timestamp_filename, "r");
+ if (!stream_info->timestamp_file_ptr) {
+ fprintf(stderr, "Cannot open audio file %s\n", stream_info->filename);
+ goto exit;
+ }
+ }
+ read_bytes_timestamps_from_file(buffer, stream_info->timestamp_file_ptr, fp_input);
+ if (buffer->common_params.timestamp == CONTIGUOUS_TIMESTAMP)
+ buffer->buffer_parms.input_buf_params.flags = QAP_BUFFER_TSTAMP_CONTINUE;
+ else
+ buffer->buffer_parms.input_buf_params.flags = QAP_BUFFER_TSTAMP;
+ timestamp_mode = true;
+ }
+
+ bytes_wanted = buffer->common_params.size;
+ bytes_read = fread(data_buf, sizeof(unsigned char), bytes_wanted, fp_input);
+
+ buffer->common_params.offset = 0;
+ buffer->common_params.size = bytes_read;
+ memcpy(buffer->common_params.data, data_buf, bytes_read);
+ if (bytes_read <= 0) {
+ buffer->buffer_parms.input_buf_params.flags = QAP_BUFFER_EOS;
+ bytes_consumed = qap_module_process(qap_module_handle, buffer);
+ ret = qap_module_cmd(qap_module_handle, QAP_MODULE_CMD_STOP, sizeof(QAP_MODULE_CMD_STOP), NULL, NULL, NULL);
+ fprintf(stdout, "Stopped feeding input %s : %p\n", stream_info->filename, fp_input);
+ ALOGV("Stopped feeding input %s : %p", stream_info->filename, fp_input);
+ break;
+ }
+
+ reply_data = (char*) calloc(1, 100);
+ is_buffer_available = 0;
+ temp_ptr = buffer->common_params.data;
+ if (kpi_mode)
+ data_write_count++;
+ do {
+ if (kpi_mode) {
+ if (data_write_count == 16) {
+ tcont_start = clock();
+ } else if (data_write_count == 18) {
+ buffer->buffer_parms.input_buf_params.flags = QAP_BUFFER_EOS;
+ bytes_consumed = qap_module_process(qap_module_handle, buffer);
+ qap_module_cmd(qap_module_handle, QAP_MODULE_CMD_STOP, sizeof(QAP_MODULE_CMD_STOP), NULL, NULL, NULL);
+ goto wait_for_eos;
+ }
+ }
+ bytes_consumed = qap_module_process(qap_module_handle, buffer);
+ if (bytes_consumed > 0) {
+ buffer->common_params.data += bytes_consumed;
+ buffer->common_params.size -= bytes_consumed;
+ }
+ ALOGV("%s %d feeding Input of size %d and bytes_cosumed is %d",
+ __FUNCTION__, __LINE__,bytes_read, bytes_consumed);
+ if ((format == QAP_AUDIO_FORMAT_DTS) ||
+ (format == QAP_AUDIO_FORMAT_DTS_HD)) {
+ if (bytes_consumed < 0) {
+ while (!is_buffer_available) {
+ usleep(1000);
+ ret = qap_module_cmd(qap_module_handle, QAP_MODULE_CMD_GET_PARAM,
+ sizeof(QAP_MODULE_CMD_GET_PARAM), "buf_available", NULL, reply_data
+ );
+ if (reply_data)
+ temp_str = get_string_value(reply_data, &status);
+ if (temp_str) {
+ is_buffer_available = atoi(temp_str);
+ free(temp_str);
+ }
+ ALOGV("%s : %d, dts clip reply_data is %d buffer availabale is %d",
+ __FUNCTION__, __LINE__, reply_data, is_buffer_available);
+ }
+ }
+ }
+ } while (buffer->common_params.size > 0);
+ if (reply_data)
+ free(reply_data);
+ buffer->common_params.data = temp_ptr;
+ if (!(stream_info->system_input || stream_info->sec_input)) {
+ usleep(5000); //To swtich between main and secondary threads incase of dual input
+ }
+ } while (1);
+
+wait_for_eos:
+ if (stream_info->sec_input && !stream_info->aac_fmt_type) {
+ pthread_mutex_lock(&sec_eos_lock);
+ pthread_cond_wait(&sec_eos_cond, &sec_eos_lock);
+ pthread_mutex_unlock(&sec_eos_lock);
+ fprintf(stdout, "Received EOS event for secondary input\n");
+ ALOGV("Received EOS event for secondary input\n");
+ }
+ if (!(stream_info->system_input || stream_info->sec_input)){
+ pthread_mutex_lock(&main_eos_lock);
+ pthread_cond_wait(&main_eos_cond, &main_eos_lock);
+ pthread_mutex_unlock(&main_eos_lock);
+ fprintf(stdout, "Received EOS event for main input\n");
+ ALOGV("Received EOS event for main input\n");
+ }
+
+exit:
+ if (NULL != buffer && NULL != buffer->common_params.data) {
+ free( buffer->common_params.data);
+ buffer->common_params.data = NULL;
+ free( buffer);
+ buffer = NULL;
+ }
+ qap_module_deinit(qap_module_handle);
+ fprintf(stdout, "%s::%d , THREAD EXIT \n", __func__, __LINE__);
+ ALOGD("%s::%d , THREAD EXIT \n", __func__, __LINE__);
+ return NULL;
+}
+
+qap_module_handle_t qap_wrapper_stream_open(void* stream_data)
+{
+ qap_module_config_t *input_config = NULL;
+ int ret = 0;
+ int i = 0;
+ stream_config *stream_info = (stream_config *)stream_data;
+ qap_module_handle_t qap_module_handle = NULL;
+
+ input_config = (qap_module_config_t *) calloc(1, sizeof(qap_module_config_t));
+ if (input_config == NULL) {
+ fprintf(stderr, "%s::%d Memory Alloc Error\n", __func__, __LINE__);
+ return NULL;
+ }
+ input_config->sample_rate = stream_info->config.sample_rate;
+ input_config->channels = stream_info->channels;
+ input_config->bit_width = stream_info->config.offload_info.bit_width;
+
+ stream_info->bytes_to_read = 1024;
+ input_streams_count++;
+ if (input_streams_count == 2) {
+ if (stream_info->filetype == FILE_WAV) {
+ input_config->flags = QAP_MODULE_FLAG_SYSTEM_SOUND;
+ stream_info->system_input = true;
+ has_system_input = true;
+ ALOGV("%s::%d Set Secondary System Sound Flag", __func__, __LINE__);
+ } else if (stream_info->filetype != FILE_WAV) {
+ if (stream_info->flags & AUDIO_OUTPUT_FLAG_ASSOCIATED) {
+ ALOGV("%s::%d Set Secondary Assoc Input Flag", __func__, __LINE__);
+ input_config->flags = QAP_MODULE_FLAG_SECONDARY;
+ stream_info->sec_input = true;
+ } else {
+ ALOGV("%s::%d Set Secondary Main Input Flag", __func__, __LINE__);
+ input_config->flags = QAP_MODULE_FLAG_PRIMARY;
+ stream_info->sec_input = true;
+ }
+ }
+ stream_info->bytes_to_read = 2048;
+ } else {
+ if (stream_info->filetype == FILE_WAV) {
+ ALOGV("%s::%d Set Secondary System Sound Flag", __func__, __LINE__);
+ input_config->flags = QAP_MODULE_FLAG_SYSTEM_SOUND;
+ stream_info->system_input = true;
+ } else {
+ ALOGV("%s::%d Set Primary Main Input Flag", __func__, __LINE__);
+ input_config->flags = QAP_MODULE_FLAG_PRIMARY;
+ }
+ }
+
+ if (!encode)
+ input_config->module_type = QAP_MODULE_DECODER;
+ else
+ input_config->module_type = QAP_MODULE_ENCODER;
+
+ ret = qap_wrapper_map_input_format(stream_info->config.offload_info.format, &input_config->format);
+ if (ret == -EINVAL)
+ return NULL;
+
+ if (!session_output_configured) {
+ session_output_config.output_config->channels = input_config->channels;
+ session_output_config.output_config->sample_rate = input_config->sample_rate;
+ output_device_id = stream_info->output_device;
+ if (output_device_id == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) {
+ output_device_id = AUDIO_DEVICE_OUT_SPEAKER;
+ play_through_bt = true;
+ }
+ if (output_device_id == AUDIO_DEVICE_OUT_LINE) {
+ output_device_id = AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
+ }
+ session_output_config.output_config->id = output_device_id;
+ if (stream_info->filetype != FILE_DTS)
+ session_output_config.output_config->bit_width = input_config->bit_width;
+ session_output_config.output_config->is_interleaved = input_config->is_interleaved;
+ session_output_config.num_output = 1;
+
+ ret = qap_session_cmd(qap_session_handle, QAP_SESSION_CMD_SET_OUTPUTS, sizeof(session_output_config), &session_output_config, NULL, NULL);
+ if (ret != QAP_STATUS_OK) {
+ fprintf(stderr, "Output config failed\n");
+ return NULL;
+ }
+
+ if (stream_info->filetype != FILE_DTS) {
+ ALOGV("Session set params %s", session_kv_pairs);
+ ret = qap_session_cmd(qap_session_handle, QAP_SESSION_CMD_SET_KVPAIRS, sizeof(session_kv_pairs), session_kv_pairs, NULL, NULL);
+ if (ret != QAP_STATUS_OK) {
+ fprintf(stderr, "Session set params failed\n");
+ return NULL;
+ }
+ }
+ session_output_configured = true;
+ }
+
+ ret = qap_module_init(qap_session_handle, input_config, &qap_module_handle);
+ if (qap_module_handle == NULL) {
+ fprintf(stderr, "%s Module Handle is Null\n", __func__);
+ return NULL;
+ }
+
+ return qap_module_handle;
+
+}
+
+void hal_test_qap_usage() {
+ printf(" \n qap commands \n");
+ printf(" -qap - Enabling playback through QAP for nun tunnel decoding mode\n");
+ printf(" -bd - Enabling Broadcast Decode/Encode session through QAP\n");
+ printf(" -broadcast - Enabling playback through QAP for nun tunnel decoding mode\n");
+ printf(" -y --timestamp filename - Input timestamp file to be used to send timestamp and bytes to be read from main input file.\n");
+ printf(" -z --framesize filename - Input framesize file to be used to send bytes to be read from main input file.\n");
+ printf(" hal_play_test -qap -broadcast -f /data/5ch_dd_25fps_channeld_id.ac3 -t 9 -d 2 -v 0.01 -r 48000 -c 6 \n");
+ printf(" -> plays AC3 stream(-t = 9) on speaker device(-d = 2)\n");
+ printf(" -> 6 channels and 48000 sample rate\n\n");
+ printf(" -> using QAP with Broadcast session\n\n");
+ printf(" hal_play_test -qap -bd -f /data/200_48_16_ieq_mix_voice_40s.ec3 -t 11 -d 2 -v 0.01 -r 48000 -c 2 \n");
+ printf(" -> plays EAC3 stream(-t = 11) on speaker device(-d = 2)\n");
+ printf(" -> 2 channels and 48000 sample rate\n\n");
+ printf(" -> using QAP with Bluray session\n\n");
+}