audio: qahw: Fix for incorrect frame issue for DTS passthrough
-For DTS stream, only send data till STREAM DATA chunk as DSP can't parse other chunks. -For .cpt stream send all the bytes. Change-Id: I561e3c76b1611dd351eb2aaa5741f022af767b17
This commit is contained in:
parent
1eb3a35790
commit
fcd412a67b
|
@ -64,7 +64,12 @@
|
|||
|
||||
#define DEFAULT_PRESET_STRENGTH -1
|
||||
|
||||
#define DTSHD_CHUNK_HEADER_KEYWORD "DTSHDHDR"
|
||||
#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);
|
||||
|
||||
|
@ -652,6 +657,21 @@ void *start_stream_playback (void* stream_data)
|
|||
pthread_t drift_query_thread;
|
||||
struct drift_data drift_params;
|
||||
|
||||
int offset = 0;
|
||||
bool is_offload = params->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
|
||||
size_t bytes_wanted = 0;
|
||||
size_t write_length = 0;
|
||||
size_t bytes_remaining = 0;
|
||||
size_t bytes_written = 0;
|
||||
|
||||
size_t bytes_read = 0;
|
||||
char *data_ptr = NULL;
|
||||
bool exit = false;
|
||||
bool read_complete_file = true;
|
||||
ssize_t bytes_to_read = 0;
|
||||
int32_t latency;
|
||||
|
||||
|
||||
memset(&drift_params, 0, sizeof(struct drift_data));
|
||||
|
||||
fprintf(log_file, "stream %d: play_later %d \n", params->stream_index, params->play_later);
|
||||
|
@ -710,22 +730,13 @@ void *start_stream_playback (void* stream_data)
|
|||
}
|
||||
fprintf(log_file, "stream %d: kvpairs are set\n", params->stream_index);
|
||||
break;
|
||||
default:
|
||||
case FILE_DTS:
|
||||
read_complete_file = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
bool is_offload = params->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
|
||||
size_t bytes_wanted = 0;
|
||||
size_t write_length = 0;
|
||||
size_t bytes_remaining = 0;
|
||||
size_t bytes_written = 0;
|
||||
size_t bytes_read = 0;
|
||||
char *data_ptr = NULL;
|
||||
bool exit = false;
|
||||
int32_t latency;
|
||||
|
||||
|
||||
if (is_offload) {
|
||||
fprintf(log_file, "stream %d: set callback for offload stream for playback usecase\n", params->stream_index);
|
||||
qahw_out_set_callback(params->out_handle, async_callback, params);
|
||||
|
@ -835,28 +846,37 @@ void *start_stream_playback (void* stream_data)
|
|||
if (event_trigger == true)
|
||||
tigger_event(params->out_handle);
|
||||
|
||||
bytes_to_read = get_bytes_to_read(params->file_stream, params->filetype);
|
||||
if (bytes_to_read <= 0)
|
||||
read_complete_file = true;
|
||||
|
||||
while (!exit && !stop_playback) {
|
||||
if (!bytes_remaining) {
|
||||
fprintf(log_file, "\nstream %d: reading bytes %zd\n", params->stream_index, bytes_wanted);
|
||||
bytes_read = read_bytes(params, data_ptr, bytes_wanted);
|
||||
fprintf(log_file, "stream %d: read bytes %zd\n", params->stream_index, bytes_read);
|
||||
if (bytes_read <= 0) {
|
||||
if (is_eof(params)) {
|
||||
fprintf(log_file, "stream %d: end of file\n", params->stream_index);
|
||||
if (is_offload) {
|
||||
pthread_mutex_lock(¶ms->drain_lock);
|
||||
qahw_out_drain(params->out_handle, QAHW_DRAIN_ALL);
|
||||
pthread_cond_wait(¶ms->drain_cond, ¶ms->drain_lock);
|
||||
fprintf(log_file, "stream %d: out of compress drain\n", params->stream_index);
|
||||
pthread_mutex_unlock(¶ms->drain_lock);
|
||||
}
|
||||
/* Caution: Below ADL log shouldnt be altered without notifying automation APT since
|
||||
* it used for automation testing
|
||||
*/
|
||||
fprintf(log_file, "ADL: stream %d: playback completed successfully\n", params->stream_index);
|
||||
if ((!read_complete_file && (bytes_to_read <= 0)) || (bytes_read <= 0)) {
|
||||
fprintf(log_file, "stream %d: end of file\n", params->stream_index);
|
||||
if (is_offload) {
|
||||
pthread_mutex_lock(¶ms->drain_lock);
|
||||
qahw_out_drain(params->out_handle, QAHW_DRAIN_ALL);
|
||||
pthread_cond_wait(¶ms->drain_cond, ¶ms->drain_lock);
|
||||
fprintf(log_file, "stream %d: out of compress drain\n", params->stream_index);
|
||||
pthread_mutex_unlock(¶ms->drain_lock);
|
||||
}
|
||||
/*
|
||||
* Caution: Below ADL log shouldnt be altered without notifying
|
||||
* automation APT since it used for automation testing
|
||||
*/
|
||||
fprintf(log_file, "ADL: stream %d: playback completed successfully\n", params->stream_index);
|
||||
exit = true;
|
||||
continue;
|
||||
} else {
|
||||
if (!read_complete_file) {
|
||||
bytes_to_read -= bytes_read;
|
||||
if ((bytes_to_read > 0) && (bytes_to_read < bytes_wanted))
|
||||
bytes_wanted = bytes_to_read;
|
||||
}
|
||||
}
|
||||
bytes_remaining = write_length = bytes_read;
|
||||
}
|
||||
|
@ -864,6 +884,9 @@ void *start_stream_playback (void* stream_data)
|
|||
offset = write_length - bytes_remaining;
|
||||
fprintf(log_file, "stream %d: writing to hal %zd bytes, offset %d, write length %zd\n",
|
||||
params->stream_index, bytes_remaining, offset, write_length);
|
||||
|
||||
|
||||
bytes_written = bytes_remaining;
|
||||
bytes_written = write_to_hal(params->out_handle, data_ptr+offset, bytes_remaining, params);
|
||||
if (bytes_written < 0) {
|
||||
fprintf(stderr, "write failed %d", bytes_written);
|
||||
|
@ -877,6 +900,7 @@ void *start_stream_playback (void* stream_data)
|
|||
params->stream_index, bytes_written, bytes_remaining, latency);
|
||||
}
|
||||
|
||||
|
||||
if (params->ethread_data != nullptr) {
|
||||
fprintf(log_file, "stream %d: un-loading effects\n", params->stream_index);
|
||||
// disable effect
|
||||
|
@ -1657,6 +1681,104 @@ static int get_wav_header_length (FILE* file_stream)
|
|||
return wav_header_len;
|
||||
}
|
||||
|
||||
/* convert big-endian to little-endian */
|
||||
uint64_t convert_BE_to_LE( uint64_t in)
|
||||
{
|
||||
uint64_t out;
|
||||
char *p_in = (char *) ∈
|
||||
char *p_out = (char *) &out;
|
||||
p_out[0] = p_in[7];
|
||||
p_out[1] = p_in[6];
|
||||
p_out[2] = p_in[5];
|
||||
p_out[3] = p_in[4];
|
||||
p_out[4] = p_in[3];
|
||||
p_out[5] = p_in[2];
|
||||
p_out[6] = p_in[1];
|
||||
p_out[7] = p_in[0];
|
||||
return out;
|
||||
}
|
||||
|
||||
static ssize_t get_bytes_to_read(FILE* file, int file_type)
|
||||
{
|
||||
char keyword[DTSHD_META_KEYWORD_SIZE + 1];
|
||||
bool is_dtshd_stream =false;
|
||||
uint64_t read_chunk_size = 0;
|
||||
uint64_t chunk_size = 0;
|
||||
ssize_t file_read_size = -1;
|
||||
ssize_t header_read_size = -1;
|
||||
long int pos;
|
||||
int ret = 0;
|
||||
|
||||
if (file_type == FILE_DTS) {
|
||||
|
||||
//first locate the ASCII header "DTSHDHDR"identifier
|
||||
while (!feof(file) && (header_read_size < 1024) &
|
||||
(fread(&keyword, sizeof(char), DTSHD_META_KEYWORD_SIZE, file)
|
||||
== DTSHD_META_KEYWORD_SIZE)) {
|
||||
//update the number of bytes was read for identifying the header
|
||||
header_read_size = ftell(file);
|
||||
|
||||
if (strncmp(keyword, DTSHD_CHUNK_HEADER_KEYWORD,
|
||||
DTSHD_META_KEYWORD_SIZE) == 0) {
|
||||
// read the 8-byte size field
|
||||
if (fread(&read_chunk_size, sizeof(char),
|
||||
DTSHD_META_KEYWORD_SIZE, file) == DTSHD_META_KEYWORD_SIZE) {
|
||||
is_dtshd_stream = true;
|
||||
chunk_size = convert_BE_to_LE(read_chunk_size);
|
||||
pos = ftell(file);
|
||||
fseek(file, chunk_size, SEEK_CUR);
|
||||
fprintf(stderr,"DTS header chunk offset:%lu and chunk_size:%llu \n",
|
||||
pos, chunk_size);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
printf(" file read error \n");
|
||||
break;
|
||||
} //end reading chunk size
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_dtshd_stream) {
|
||||
fprintf(stderr, "raw dts hd stream");
|
||||
fseek(file, 0, SEEK_SET);
|
||||
return file_read_size;
|
||||
}
|
||||
/* parsing each chunk data */
|
||||
while (!feof(file) &&
|
||||
fread(&keyword, sizeof(uint8_t), DTSHD_META_KEYWORD_SIZE, file)
|
||||
== DTSHD_META_KEYWORD_SIZE) {
|
||||
/* check for the stream audio data */
|
||||
ret = strncmp(keyword,
|
||||
DTSHD_CHUNK_STREAM_KEYWORD,
|
||||
DTSHD_META_KEYWORD_SIZE);
|
||||
if (!ret) {
|
||||
ret = fread(&read_chunk_size, 1, DTSHD_META_KEYWORD_SIZE, file);
|
||||
chunk_size = convert_BE_to_LE(read_chunk_size);
|
||||
if (ret != DTSHD_META_KEYWORD_SIZE) {
|
||||
fprintf(stderr,"%s %d file read error ret %\n",
|
||||
__func__, __LINE__, ret);
|
||||
file_read_size = -EINVAL;
|
||||
break;
|
||||
}
|
||||
file_read_size = chunk_size;
|
||||
fprintf(stderr, "DTS read_chunk_size %llu and file_read_size: %zd\n",
|
||||
chunk_size,
|
||||
file_read_size);
|
||||
break;
|
||||
} else {
|
||||
fprintf(log_file, "Identified chunk of %c %c %c %c %c %c %c %c \n",
|
||||
keyword[0], keyword[1], keyword[2], keyword[3],
|
||||
keyword[4], keyword[5], keyword[6], keyword[7] );
|
||||
ret = fread(&read_chunk_size, 1, DTSHD_META_KEYWORD_SIZE, file);
|
||||
pos = ftell(file);
|
||||
chunk_size = convert_BE_to_LE(read_chunk_size);
|
||||
fseek(file, chunk_size, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
}
|
||||
return file_read_size;
|
||||
}
|
||||
|
||||
static qahw_module_handle_t * load_hal(audio_devices_t dev) {
|
||||
qahw_module_handle_t *hal = NULL;
|
||||
|
||||
|
|
Loading…
Reference in New Issue