summaryrefslogtreecommitdiff
authorTreeHugger Robot <treehugger-gerrit@google.com>2018-11-22 00:20:01 (GMT)
committer Android Partner Code Review <android-gerrit-partner@google.com>2018-11-22 00:20:01 (GMT)
commitf4edd96577b42744933ae730fbb270b0db0ee38d (patch)
tree6653c1ee8c76c0f7bfaf96ec90e9dc905087bf07
parent9dedced00f9e52c50142ae27025d33b1a059406b (diff)
parentad45e3364bf69d6b476569b164c1b7ba0d733885 (diff)
downloadamlogic-q-amlogic.zip
amlogic-q-amlogic.tar.gz
amlogic-q-amlogic.tar.bz2
Merge changes Ife17cdca,I43e6fab9 into p-tv-dev
* changes: audio: calc timestamp using inport method [1/1] audio: Run VTS VtsHalAudioV2_0Target module,exist 834 failed cases[1/1]
Diffstat
-rw-r--r--audio/audio_hal/amlAudioMixer.c75
-rw-r--r--audio/audio_hal/amlAudioMixer.h5
-rw-r--r--audio/audio_hal/audio_hw.c22
-rw-r--r--audio/audio_hal/audio_hw.h2
-rw-r--r--audio/audio_hal/audio_port.h6
-rw-r--r--audio/audio_hal/sub_mixing_factory.c239
-rw-r--r--audio/audio_hal/sub_mixing_factory.h15
7 files changed, 247 insertions, 117 deletions
diff --git a/audio/audio_hal/amlAudioMixer.c b/audio/audio_hal/amlAudioMixer.c
index a6ea355..8dfb45d 100644
--- a/audio/audio_hal/amlAudioMixer.c
+++ b/audio/audio_hal/amlAudioMixer.c
@@ -104,8 +104,9 @@ int init_mixer_input_port(struct amlAudioMixer *audio_mixer,
size_t buf_frames = MIXER_IN_FRAME_COUNT;
struct input_port *port = NULL;
enum MIXER_INPUT_PORT port_index;
+ struct aml_stream_out *aml_out = notify_data;
- if (audio_mixer == NULL || config == NULL) {
+ if (audio_mixer == NULL || config == NULL || notify_data == NULL) {
ALOGE("%s(), NULL pointer", __func__);
return -EINVAL;
}
@@ -125,6 +126,10 @@ int init_mixer_input_port(struct amlAudioMixer *audio_mixer,
set_inport_hwsync(port);
set_port_meta_data_cbk(port, on_meta_data_cbk, meta_data);
}
+
+ port->initial_frames = aml_out->frame_write_sum;
+ ALOGI("%s(), port->initial_frames: %lld", __func__, port->initial_frames);
+
return 0;
}
@@ -371,6 +376,38 @@ static int mixer_output_write(struct amlAudioMixer *audio_mixer)
return 0;
}
+#define DEFAULT_KERNEL_FRAMES (DEFAULT_PLAYBACK_PERIOD_SIZE*DEFAULT_PLAYBACK_PERIOD_CNT)
+
+static int mixer_update_tstamp(struct amlAudioMixer *audio_mixer)
+{
+ struct output_port *out_port = audio_mixer->out_ports[MIXER_OUTPUT_PORT_PCM];
+ struct input_port *in_port = audio_mixer->in_ports[MIXER_INPUT_PORT_PCM_SYSTEM];
+ unsigned int avail;
+ //struct timespec *timestamp;
+
+ /*only deal with system audio */
+ if (in_port == NULL || out_port == NULL)
+ return 0;
+
+ if (pcm_get_htimestamp(out_port->pcm_handle, &avail, &in_port->timestamp) == 0) {
+ size_t kernel_buf_size = DEFAULT_KERNEL_FRAMES;
+ int64_t signed_frames = in_port->mix_consumed_frames - kernel_buf_size + avail;
+ if (signed_frames < 0) {
+ signed_frames = 0;
+ }
+ in_port->presentation_frames = in_port->initial_frames + signed_frames;
+ ALOGV("%s() present frames:%lld, initial %lld, consumed %lld, sec:%ld, nanosec:%ld",
+ __func__,
+ in_port->presentation_frames,
+ in_port->initial_frames,
+ in_port->mix_consumed_frames,
+ in_port->timestamp.tv_sec,
+ in_port->timestamp.tv_nsec);
+ }
+
+ return 0;
+}
+
static bool is_mixer_inports_ready(struct amlAudioMixer *audio_mixer)
{
enum MIXER_INPUT_PORT port_index = 0;
@@ -469,6 +506,7 @@ static int mixer_inports_read(struct amlAudioMixer *audio_mixer)
ALOGV("%s() ret %d, portIndex %d", __func__, ret, port_index);
if (ret == in_port->data_len_bytes) {
in_port->data_valid = 1;
+ in_port->mix_consumed_frames += in_port->data_buf_frame_cnt;
if (port_index == MIXER_INPUT_PORT_PCM_DIRECT) {
//state = mixer_get_inport_state(audio_mixer, port_index);
// we are in easing, when finished set to paused status
@@ -549,6 +587,7 @@ static int mixer_inports_read1(struct amlAudioMixer *audio_mixer)
fade_out = 1;
} else if (state == RESUMING) {
fade_in = 1;
+ aml_hwsync_set_tsync_resume();
} else if (state == STOPPED || state == PAUSED || state == FLUSHED) {
ALOGV("%s(), stopped, paused or flushed", __func__);
in_port->data_valid = 1;
@@ -584,10 +623,11 @@ static int mixer_inports_read1(struct amlAudioMixer *audio_mixer)
} else if (fade_in) {
ALOGI("%s(), resuming port index %d", __func__, port_index);
ALOGI("%s(), tsync resume audio", __func__);
- aml_hwsync_set_tsync_resume();
+ //aml_hwsync_set_tsync_resume();
audio_fade_func(in_port->data, ret, 1);
set_inport_state(in_port, ACTIVE);
}
+ in_port->mix_consumed_frames += in_port->data_buf_frame_cnt;
in_port->data_valid = 1;
ready = true;
@@ -1055,7 +1095,7 @@ static int mixer_do_mixing_16bit(struct amlAudioMixer *audio_mixer)
aml_audio_dump_audio_bitstreams("/data/audio/audiosyst.raw",
in_port_sys->data, in_port_sys->data_len_bytes);
}
- if (is_inport_hwsync(in_port_drct) && in_port_drct->bytes_to_insert < mixing_len_bytes) {
+ if (is_inport_hwsync(in_port_drct)) {
retrieve_hwsync_header(audio_mixer, in_port_drct, out_port);
}
@@ -1129,7 +1169,7 @@ static int mixer_do_mixing_16bit(struct amlAudioMixer *audio_mixer)
ALOGV("%s() direct_only, inport consumed %d",
__func__, get_inport_consumed_size(in_port_drct));
- if (is_inport_hwsync(in_port_drct) && in_port_drct->bytes_to_insert < mixing_len_bytes) {
+ if (is_inport_hwsync(in_port_drct)) {
retrieve_hwsync_header(audio_mixer, in_port_drct, out_port);
}
@@ -1275,8 +1315,10 @@ static void *mixer_32b_threadloop(void *data)
audio_mixer->last_write_time_us = now_in_us;
// audio patching should not in this write
// TODO: fix me, make compatible with source output
- if (!audio_mixer->adev->audio_patching)
+ if (!audio_mixer->adev->audio_patching) {
mixer_output_write(audio_mixer);
+ mixer_update_tstamp(audio_mixer);
+ }
audio_mixer->last_process_finished_ns = get_systime_ns();
}
@@ -1333,7 +1375,10 @@ static void *mixer_16b_threadloop(void *data)
// ALOGW("%s(), actual write time %lld, estimated %d", __func__,
// tpast_us, (audio_mixer->out_ports[port_index]->bytes_avail * 1000 / 48 /4));
audio_mixer->last_write_time_us = now_in_us;
- mixer_output_write(audio_mixer);
+ if (!audio_mixer->adev->audio_patching) {
+ mixer_output_write(audio_mixer);
+ mixer_update_tstamp(audio_mixer);
+ }
audio_mixer->last_process_finished_ns = get_systime_ns();
}
@@ -1483,3 +1528,21 @@ int64_t mixer_latency_frames(struct amlAudioMixer *audio_mixer)
*/
return MIXER_IN_FRAME_COUNT;
}
+
+int mixer_get_presentation_position(
+ struct amlAudioMixer *audio_mixer,
+ enum MIXER_INPUT_PORT port_index,
+ uint64_t *frames,
+ struct timespec *timestamp)
+{
+ struct input_port *port = audio_mixer->in_ports[port_index];
+
+ if (!port) {
+ ALOGE("%s(), NULL pointer", __func__);
+ return -EINVAL;
+ }
+
+ *frames = port->presentation_frames;
+ *timestamp = port->timestamp;
+ return 0;
+}
diff --git a/audio/audio_hal/amlAudioMixer.h b/audio/audio_hal/amlAudioMixer.h
index 204ab97..bb7acf5 100644
--- a/audio/audio_hal/amlAudioMixer.h
+++ b/audio/audio_hal/amlAudioMixer.h
@@ -88,6 +88,11 @@ uint32_t mixer_get_inport_latency_frames(struct amlAudioMixer *audio_mixer,
enum MIXER_INPUT_PORT port_index);
uint32_t mixer_get_outport_latency_frames(struct amlAudioMixer *audio_mixer);
int64_t mixer_latency_frames(struct amlAudioMixer *audio_mixer);
+int mixer_get_presentation_position(
+ struct amlAudioMixer *audio_mixer,
+ enum MIXER_INPUT_PORT port_index,
+ uint64_t *frames,
+ struct timespec *timestamp);
__END_DECLS
diff --git a/audio/audio_hal/audio_hw.c b/audio/audio_hal/audio_hw.c
index f633d2b..a0c4b02 100644
--- a/audio/audio_hal/audio_hw.c
+++ b/audio/audio_hal/audio_hw.c
@@ -1026,8 +1026,8 @@ static int out_set_parameters (struct audio_stream *stream, const char *kvpairs)
pthread_mutex_lock (&adev->lock);
pthread_mutex_lock (&out->lock);
if (!out->standby) {
- standy_func (out);
- startup_func (out);
+ //standy_func (out);
+ //startup_func (out);
out->standby = 0;
}
// set hal_rate to sr for passing VTS
@@ -5282,6 +5282,8 @@ ssize_t hw_write (struct audio_stream_out *stream
aml_out->pcm = getSubMixingPCMdev(adev->sm);
if (aml_out->pcm == NULL)
ALOGE("%s() get pcm handle failed", __func__);
+ else
+ ALOGI("%s(), pcm: %p", __func__, aml_out->pcm);
} else {
ret = aml_alsa_output_open(stream);
if (ret) {
@@ -5449,6 +5451,11 @@ ssize_t mixer_main_buffer_write (struct audio_stream_out *stream, const void *bu
#endif
pthread_mutex_unlock (&adev->lock);
}
+
+ if (aml_out->standby) {
+ ALOGI("%s(), unstandby -> standby", __func__);
+ aml_out->standby = false;
+ }
if (case_cnt > 2) {
ALOGE ("%s usemask %x,we do not support two direct stream output at the same time.TO CHECK CODE FLOW!!!!!!",__func__,adev->usecase_masks);
return return_bytes;
@@ -5793,12 +5800,17 @@ ssize_t mixer_aux_buffer_write (struct audio_stream_out *stream, const void *buf
if ((aml_out->status == STREAM_HW_WRITING) && hw_mix) {
ALOGI ("%s(), aux close\n", __func__);
- pthread_mutex_lock (&adev->alsa_pcm_lock);
- aml_alsa_output_close (stream);
- pthread_mutex_unlock (&adev->alsa_pcm_lock);
+ //pthread_mutex_lock (&adev->alsa_pcm_lock);
+ //aml_alsa_output_close (stream);
+ //pthread_mutex_unlock (&adev->alsa_pcm_lock);
aml_out->status = STREAM_MIXING;
}
+ if (aml_out->standby) {
+ ALOGI("%s(), unstandby -> standby", __func__);
+ aml_out->standby = false;
+ }
+
if (aml_out->status == STREAM_STANDBY) {
aml_out->status = STREAM_MIXING;
}
diff --git a/audio/audio_hal/audio_hw.h b/audio/audio_hal/audio_hw.h
index f15cf25..23b148e 100644
--- a/audio/audio_hal/audio_hw.h
+++ b/audio/audio_hal/audio_hw.h
@@ -47,6 +47,7 @@
*/
#define DEFAULT_PLAYBACK_PERIOD_SIZE 512
#define DEFAULT_CAPTURE_PERIOD_SIZE 512
+#define DEFAULT_PLAYBACK_PERIOD_CNT 6
/* number of ICE61937 format frames per period */
#define DEFAULT_IEC_SIZE 6144
@@ -417,6 +418,7 @@ struct aml_stream_out {
struct audio_stream_out stream;
/* see note below on mutex acquisition order */
pthread_mutex_t lock;
+ struct audio_config audioCfg;
/* config which set to ALSA device */
struct pcm_config config;
/* channel mask exposed to AudioFlinger. */
diff --git a/audio/audio_hal/audio_port.h b/audio/audio_hal/audio_port.h
index ace28cd..842b639 100644
--- a/audio/audio_hal/audio_port.h
+++ b/audio/audio_hal/audio_port.h
@@ -108,6 +108,12 @@ struct input_port {
struct listnode msg_list;
pthread_mutex_t msg_lock;
//nsecs_t last_write_nsec;
+ struct timespec timestamp;
+ /* get from out stream when init */
+ uint64_t initial_frames;
+ /* consumed by read after init */
+ uint64_t mix_consumed_frames;
+ uint64_t presentation_frames;
};
enum MIXER_OUTPUT_PORT {
diff --git a/audio/audio_hal/sub_mixing_factory.c b/audio/audio_hal/sub_mixing_factory.c
index f77f7d0..6cf2b75 100644
--- a/audio/audio_hal/sub_mixing_factory.c
+++ b/audio/audio_hal/sub_mixing_factory.c
@@ -14,12 +14,31 @@
#include "audio_hw_utils.h"
#include "hw_avsync_callbacks.h"
+static int on_notify_cbk(void *data);
+static int on_input_avail_cbk(void *data);
+static ssize_t out_write_subMixingPCM(struct audio_stream_out *stream,
+ const void *buffer,
+ size_t bytes);
+static int out_pause_subMixingPCM(struct audio_stream_out *stream);
+static int out_resume_subMixingPCM(struct audio_stream_out *stream);
+static int out_flush_subMixingPCM(struct audio_stream_out *stream);
+
struct pcm *getSubMixingPCMdev(struct subMixing *sm)
{
return sm->pcmDev;
}
-int initSubMixngOutput(
+static int startMixingThread(struct subMixing *sm)
+{
+ return pcm_mixer_thread_run(sm->mixerData);
+}
+
+static int exitMixingThread(struct subMixing *sm)
+{
+ return pcm_mixer_thread_exit(sm->mixerData);
+}
+
+static int initSubMixngOutput(
struct subMixing *sm,
struct audioCfg cfg,
struct aml_audio_device *adev)
@@ -36,7 +55,7 @@ int initSubMixngOutput(
pcm_cfg.channels = cfg.channelCnt;
pcm_cfg.rate = cfg.sampleRate;
pcm_cfg.period_size = DEFAULT_PLAYBACK_PERIOD_SIZE;
- pcm_cfg.period_count = 6;//4;
+ pcm_cfg.period_count = DEFAULT_PLAYBACK_PERIOD_CNT;
if (cfg.format == AUDIO_FORMAT_PCM_16_BIT)
pcm_cfg.format = PCM_FORMAT_S16_LE;
@@ -52,7 +71,7 @@ int initSubMixngOutput(
if ((pcm == NULL) || !pcm_is_ready(pcm)) {
ALOGE("cannot open pcm_out driver: %s", pcm_get_error(pcm));
pcm_close(pcm);
- return -EINVAL;
+ //return -EINVAL;
}
sm->pcmDev = pcm;
@@ -65,8 +84,10 @@ int initSubMixngOutput(
goto err;
}
sm->mixerData = amixer;
+ startMixingThread(sm);
} else if (sm->type == MIXER_MS12) {
//TODO
+ ALOGW("%s(), not support yet, in TODO list", __func__);
} else {
ALOGE("%s(), not support", __func__);
res = -EINVAL;
@@ -78,21 +99,25 @@ err:
return res;
};
-int releaseSubMixingOutput(struct subMixing *sm)
+static int releaseSubMixingOutput(struct subMixing *sm)
{
ALOGI("++%s()", __func__);
+ if (!sm) {
+ ALOGE("%s(), null pointer", __func__);
+ return -EINVAL;
+ }
+ exitMixingThread(sm);
freeAmlAudioMixer(sm->mixerData);
pcm_close(sm->pcmDev);
sm->pcmDev = NULL;
return 0;
}
-ssize_t aml_out_write_to_mixer(struct audio_stream_out *stream, const void* buffer,
+static ssize_t aml_out_write_to_mixer(struct audio_stream_out *stream, const void* buffer,
size_t bytes)
{
struct aml_stream_out *out = (struct aml_stream_out *)stream;
struct aml_audio_device *adev = out->dev;
- //struct aml_audio_mixer *audio_mixer = adev->audio_mixer;
struct subMixing *sm = adev->sm;
struct amlAudioMixer *audio_mixer = sm->mixerData;
const char *data = (char *)buffer;
@@ -144,7 +169,7 @@ ssize_t aml_out_write_to_mixer(struct audio_stream_out *stream, const void* buff
return written_total;
}
-int consume_meta_data(void *cookie,
+static int consume_meta_data(void *cookie,
uint32_t frame_size, int64_t pts, uint64_t offset)
{
struct aml_stream_out *out = (struct aml_stream_out *)cookie;
@@ -180,7 +205,7 @@ int consume_meta_data(void *cookie,
return 0;
}
-int consume_output_data(void *cookie, const void* buffer, size_t bytes)
+static int consume_output_data(void *cookie, const void* buffer, size_t bytes)
{
struct audio_stream_out *stream = (struct audio_stream_out *)cookie;
struct aml_stream_out *out = (struct aml_stream_out *)stream;
@@ -207,8 +232,7 @@ int consume_output_data(void *cookie, const void* buffer, size_t bytes)
ALOGE("%s(), written failed, %d", __func__, written);
goto exit;
}
- //if (mixer_get_inport_state(audio_mixer, out->port_index) == STOPPED)
- // mixer_set_inport_state(audio_mixer, out->port_index, ACTIVE);
+
clock_gettime(CLOCK_MONOTONIC, &new_tval);
us_since_last_write = (new_tval.tv_sec - out->timestamp.tv_sec) * 1000000 +
(new_tval.tv_nsec - out->timestamp.tv_nsec) / 1000;
@@ -265,6 +289,8 @@ static ssize_t out_write_hwsync_lpcm(struct audio_stream_out *stream, const void
size_t bytes)
{
struct aml_stream_out *out = (struct aml_stream_out *)stream;
+ struct aml_audio_device *adev = out->dev;
+ struct subMixing *sm = adev->sm;
size_t channel_count = audio_channel_count_from_out_mask(out->hal_channel_mask);
size_t frame_size = audio_bytes_per_frame(channel_count, out->hal_format);;
int written_total = 0;
@@ -278,10 +304,21 @@ static ssize_t out_write_hwsync_lpcm(struct audio_stream_out *stream, const void
}
if (out->standby) {
+ ALOGI("%s(), start hwsync lpcm stream: %p", __func__, out);
+ out->hwsync_extractor = new_hw_avsync_header_extractor(consume_meta_data,
+ consume_output_data, out);
+ out->first_pts_set = false;
+ pthread_mutex_init(&out->mdata_lock, NULL);
+ init_mixer_input_port(sm->mixerData, &out->audioCfg, out->flags,
+ on_notify_cbk, out, on_input_avail_cbk, out,
+ on_meta_data_cbk, out);
+ out->port_index = get_input_port_index(&out->audioCfg, out->flags);
+ ALOGI("%s(), hwsync port index = %d", __func__, out->port_index);
out->standby = false;
}
if (out->pause_status) {
- ALOGE("%s(), write in pause status!!", __func__);
+ ALOGW("%s(), write in pause status!!", __func__);
+ out->pause_status = false;
}
written_total = header_extractor_write(out->hwsync_extractor, buffer, bytes);
ALOGV("%s() bytes %d, out->last_frames_postion %lld frame_sum %lld",
@@ -324,7 +361,6 @@ static ssize_t out_write_system(struct audio_stream_out *stream, const void *buf
size_t frame_size = audio_bytes_per_frame(channel_count, out->hal_format);;
//uint64_t throttle_timeus = THROTLE_TIME_US;//aml_audio_get_throttle_timeus();
int64_t throttle_timeus = 0;//aml_audio_get_throttle_timeus(bytes);
- ALOGV("shuai ... %s", __func__);
if (bytes == 0) {
ALOGW("%s(), inval to write bytes 0", __func__);
@@ -421,7 +457,16 @@ static ssize_t out_write_direct_pcm(struct audio_stream_out *stream, const void
size_t remain = 0;
int frame_size = 4;
int64_t throttle_timeus = 0;//aml_audio_get_throttle_timeus(bytes);
- ALOGV("shuai ... %s", __func__);
+
+ if (out->standby) {
+ ALOGI("%s(), direct %p", __func__, out);
+ init_mixer_input_port(sm->mixerData, &out->audioCfg, out->flags,
+ on_notify_cbk, out, on_input_avail_cbk, out,
+ NULL, NULL);
+ out->port_index = get_input_port_index(&out->audioCfg, out->flags);
+ ALOGI("%s(), direct port index = %d", __func__, out->port_index);
+ out->standby = false;
+ }
if (bytes == 0) {
ALOGW("%s(), inval to write bytes 0", __func__);
@@ -504,7 +549,7 @@ exit:
return written;
}
-int on_notify_cbk(void *data)
+static int on_notify_cbk(void *data)
{
struct aml_stream_out *out = data;
ALOGD("%s(), line %d", __func__, __LINE__);
@@ -512,7 +557,7 @@ int on_notify_cbk(void *data)
return 0;
}
-int on_input_avail_cbk(void *data)
+static int on_input_avail_cbk(void *data)
{
struct aml_stream_out *out = data;
ALOGV("%s(), line %d", __func__, __LINE__);
@@ -561,7 +606,35 @@ static int out_get_presentation_position_subMixingPCM
return ret;
}
-int initSubMixingInputPcm(
+static int out_get_presentation_position_port(
+ const struct audio_stream_out *stream,
+ uint64_t *frames,
+ struct timespec *timestamp)
+{
+ struct aml_stream_out *out = (struct aml_stream_out *)stream;
+ struct aml_audio_device *adev = out->dev;
+ struct subMixing *sm = adev->sm;
+ struct amlAudioMixer *audio_mixer = sm->mixerData;
+ uint64_t frames_written_hw = out->last_frames_postion;
+ int ret = 0;
+
+ if (!frames || !timestamp) {
+ return -EINVAL;
+ }
+
+ if (!adev->audio_patching) {
+ ret = mixer_get_presentation_position(audio_mixer,
+ out->port_index,frames, timestamp);
+ } else {
+ *frames = frames_written_hw;
+ *timestamp = out->timestamp;
+ }
+ ALOGV("%s() out:%p frames:%"PRIu64", sec:%ld, nanosec:%ld\n",
+ __func__, out, *frames, timestamp->tv_sec, timestamp->tv_nsec);
+ return ret;
+}
+
+static int initSubMixingInputPcm(
struct audio_config *config,
struct aml_stream_out *out)
{
@@ -575,75 +648,32 @@ int initSubMixingInputPcm(
audio_is_linear_pcm(config->format) && channel_count <= 2);
ALOGI("++%s(), out %p, flags %#x, hwsync lpcm %d, out format %#x",
__func__, out, flags, hwsync_lpcm, sm->outputCfg.format);
+ out->audioCfg = *config;
out->stream.write = out_write_subMixingPCM;
out->stream.pause = out_pause_subMixingPCM;
out->stream.resume = out_resume_subMixingPCM;
out->stream.flush = out_flush_subMixingPCM;
out->stream.common.standby = out_standby_subMixingPCM;
if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
- ALOGI("%s(), primary out_write_system %p", __func__, out);
- //out->stream.write = out_write_system;
- init_mixer_input_port(sm->mixerData, config, flags,
- on_notify_cbk, out, on_input_avail_cbk, out,
- NULL, NULL);
-
- out->port_index = get_input_port_index(config, flags);
- ALOGI("%s(), primary port index = %d", __func__, out->port_index);
/* using subMixing clac function for system sound */
- out->stream.get_presentation_position = out_get_presentation_position_subMixingPCM;
- } else if (flags & AUDIO_OUTPUT_FLAG_DIRECT) {
- ALOGI("%s(), direct stream:", __func__);
- if (hwsync_lpcm) {
- ALOGI("%s(), primary out_write_hwsync_lpcm %p", __func__, out);
- //out->stream.write = out_write_hwsync_lpcm;
- out->hwsync_extractor = new_hw_avsync_header_extractor(consume_meta_data,
- consume_output_data, out);
- out->first_pts_set = false;
- pthread_mutex_init(&out->mdata_lock, NULL);
- list_init(&out->mdata_list);
- init_mixer_input_port(sm->mixerData, config, flags,
- on_notify_cbk, out, on_input_avail_cbk, out,
- on_meta_data_cbk, out);
- out->port_index = get_input_port_index(config, flags);
- ALOGI("%s(), hwsync port index = %d", __func__, out->port_index);
- } else {
- ALOGI("%s(), primary out_write_direct_pcm %p", __func__, out);
- //out->stream.write = out_write_direct_pcm;
- init_mixer_input_port(sm->mixerData, config, flags,
- on_notify_cbk, out, on_input_avail_cbk, out,
- NULL, NULL);
- out->port_index = get_input_port_index(config, flags);
- ALOGI("%s(), direct port index = %d", __func__, out->port_index);
- }
- } else {
- ALOGE("%s(), not supported flags %#x", __func__, flags);
- return -EINVAL;
+ //out->stream.get_presentation_position = out_get_presentation_position_subMixingPCM;
+ out->stream.get_presentation_position = out_get_presentation_position_port;
}
- if (!sm->cnt_stream_using_mixer) {
- pcm_mixer_thread_run(sm->mixerData);
- ALOGI("-%s mixer and thread start OK", __func__);
- }
- //TODO: move to sm
- sm->cnt_stream_using_mixer++;
- ALOGI("--%s(), cnt_stream_using_mixer %d",
- __func__, sm->cnt_stream_using_mixer);
+ list_init(&out->mdata_list);
return 0;
}
-int deleteSubMixingInputPcm(struct aml_stream_out *out)
+static int deleteSubMixingInputPcm(struct aml_stream_out *out)
{
struct aml_audio_device *adev = out->dev;
struct subMixing *sm = adev->sm;
struct amlAudioMixer *audio_mixer = sm->mixerData;
- sm->cnt_stream_using_mixer--;
ALOGI("%s(), cnt_stream_using_mixer %d",
__func__, sm->cnt_stream_using_mixer);
- delete_mixer_input_port(audio_mixer, out->port_index);
- if (!sm->cnt_stream_using_mixer) {
- pcm_mixer_thread_exit(sm->mixerData);
- }
+ //delete_mixer_input_port(audio_mixer, out->port_index);
+
return 0;
}
@@ -735,7 +765,7 @@ int sysWriteMS12(
}
#endif
/* mixing only support pcm 16&32 format now */
-int newSubMixingFactory(
+static int newSubMixingFactory(
struct subMixing **smixer,
enum MIXER_TYPE type,
struct audioCfg cfg,
@@ -788,7 +818,7 @@ exit:
return res;
};
-void deleteSubMixing(struct subMixing *sm)
+static void deleteSubMixing(struct subMixing *sm)
{
ALOGI("++%s()", __func__);
if (sm != NULL) {
@@ -919,7 +949,6 @@ ssize_t mixer_main_buffer_write_sm (struct audio_stream_out *stream, const void
int write_retry = 0;
audio_hwsync_t *hw_sync = &aml_out->hwsync;
- ALOGV("shuai ... %s", __func__);
if (adev->debug_flag) {
ALOGI("%s write in %zu!, format = 0x%x\n", __FUNCTION__, bytes, aml_out->hal_internal_format);
}
@@ -938,11 +967,11 @@ ssize_t mixer_main_buffer_write_sm (struct audio_stream_out *stream, const void
/* handle HWSYNC audio data*/
if (aml_out->hw_sync_mode) {
- ALOGV("shuai ... hwsync mode %s", __func__);
+ ALOGV("hwsync mode %s", __func__);
write_bytes = out_write_hwsync_lpcm(stream, buffer, bytes);
} else {
- ALOGV("shuai ... direct %s", __func__);
- write_bytes = aml_out_write_to_mixer(stream, buffer, bytes);
+ ALOGV("direct %s", __func__);
+ write_bytes = out_write_direct_pcm(stream, buffer, bytes);
if (write_bytes < 0) {
ALOGE("%s(), write failed, err = %d", __func__, write_bytes);
}
@@ -963,6 +992,7 @@ ssize_t mixer_aux_buffer_write_sm(struct audio_stream_out *stream, const void *b
{
struct aml_stream_out *aml_out = (struct aml_stream_out *) stream;
struct aml_audio_device *adev = aml_out->dev;
+ struct subMixing *sm = adev->sm;
int ret = 0;
size_t frame_size = audio_stream_out_frame_size(stream);
size_t in_frames = bytes / frame_size;
@@ -973,6 +1003,16 @@ ssize_t mixer_aux_buffer_write_sm(struct audio_stream_out *stream, const void *b
unsigned int alsa_latency_frame = 0;
ALOGV("++%s", __func__);
+ if (aml_out->standby) {
+ init_mixer_input_port(sm->mixerData, &aml_out->audioCfg, aml_out->flags,
+ on_notify_cbk, aml_out, on_input_avail_cbk, aml_out,
+ NULL, NULL);
+
+ aml_out->port_index = get_input_port_index(&aml_out->audioCfg, aml_out->flags);
+ ALOGI("%s(), primary %p port index = %d",
+ __func__, aml_out, aml_out->port_index);
+ aml_out->standby = false;
+ }
bytes_written = aml_out_write_to_mixer(stream, buffer, bytes);
if (bytes_written < 0) {
ALOGE("%s(), stream usecase: %s, write failed, err = %d",
@@ -1018,6 +1058,9 @@ int usecase_change_validate_l_sm(struct aml_stream_out *aml_out, bool is_standby
return 0;
}
+ ALOGI("++%s: dev usecase masks = %#x, out usecase_masks = %#x, out usecase %s",
+ __func__, aml_dev->usecase_masks, aml_out->dev_usecase_masks, usecase_to_str(aml_out->usecase));
+
/* check the usecase validation */
if (popcount(aml_dev->usecase_masks & 0xfffffffe) > 1) {
ALOGE("%s(), invalid usecase masks = %#x, out usecase %s!",
@@ -1062,7 +1105,7 @@ int usecase_change_validate_l_sm(struct aml_stream_out *aml_out, bool is_standby
}
/* out_write_submixing entrance: every write to submixing goes in here. */
-ssize_t out_write_subMixingPCM(struct audio_stream_out *stream,
+static ssize_t out_write_subMixingPCM(struct audio_stream_out *stream,
const void *buffer,
size_t bytes)
{
@@ -1108,9 +1151,11 @@ int out_standby_subMixingPCM(struct audio_stream *stream)
{
struct aml_stream_out *aml_out = (struct aml_stream_out *) stream;
struct aml_audio_device *adev = aml_out->dev;
+ struct subMixing *sm = adev->sm;
+ struct amlAudioMixer *audio_mixer = sm->mixerData;
ssize_t ret = 0;
- ALOGD("%s: out_stream(%p)", __func__, stream);
+ ALOGD("%s: out_stream(%p) usecase: %s", __func__, stream, usecase_to_str(aml_out->usecase));
/**
* deal with the device output changes
* pthread_mutex_lock(&aml_out->lock);
@@ -1118,12 +1163,18 @@ int out_standby_subMixingPCM(struct audio_stream *stream)
* pthread_mutex_unlock(&aml_out->lock);
*/
pthread_mutex_lock(&adev->lock);
+ if (aml_out->standby) {
+ goto exit;
+ }
+
ret = usecase_change_validate_l_sm(aml_out, true);
if (ret < 0) {
ALOGE("%s() failed", __func__);
goto exit;
}
aml_out->status = STREAM_STANDBY;
+ aml_out->standby = true;
+ delete_mixer_input_port(audio_mixer, aml_out->port_index);
if (adev->debug_flag > 1) {
ALOGI("-%s() ret %zd,%p %"PRIu64"\n", __func__, ret, stream, aml_out->total_write_size);
@@ -1134,15 +1185,16 @@ exit:
}
/* use standby instead of pause to fix background pcm playback */
-int out_pause_subMixingPCM(struct audio_stream_out *stream)
+static int out_pause_subMixingPCM(struct audio_stream_out *stream)
{
struct aml_stream_out *aml_out = (struct aml_stream_out *)stream;
struct aml_audio_device *aml_dev = aml_out->dev;
struct subMixing *sm = aml_dev->sm;
struct amlAudioMixer *audio_mixer = NULL;
- ALOGI("+%s(), standby %d, pause status %d, usecase: %s",
+ ALOGI("+%s(), stream %p, standby %d, pause status %d, usecase: %s",
__func__,
+ aml_out,
aml_out->standby,
aml_out->pause_status,
usecase_to_str(aml_out->usecase));
@@ -1164,7 +1216,7 @@ int out_pause_subMixingPCM(struct audio_stream_out *stream)
return 0;
}
-int out_resume_subMixingPCM(struct audio_stream_out *stream)
+static int out_resume_subMixingPCM(struct audio_stream_out *stream)
{
struct aml_stream_out *aml_out = (struct aml_stream_out *) stream;
struct aml_audio_device *aml_dev = aml_out->dev;
@@ -1176,7 +1228,7 @@ int out_resume_subMixingPCM(struct audio_stream_out *stream)
__func__, stream, aml_out->standby, aml_out->pause_status);
if (!aml_out->pause_status) {
ALOGW("%s(), steam not in pause status", __func__);
- //return INVALID_STATE;
+ return INVALID_STATE;
}
if (sm->type != MIXER_LPCM) {
@@ -1192,7 +1244,8 @@ int out_resume_subMixingPCM(struct audio_stream_out *stream)
return 0;
}
-int out_flush_subMixingPCM(struct audio_stream_out *stream)
+/* If supported, a stream should always succeed to flush */
+static int out_flush_subMixingPCM(struct audio_stream_out *stream)
{
struct aml_stream_out *aml_out = (struct aml_stream_out *) stream;
struct aml_audio_device *aml_dev = aml_out->dev;
@@ -1214,30 +1267,32 @@ int out_flush_subMixingPCM(struct audio_stream_out *stream)
aml_out->skip_frame = 3;
aml_out->input_bytes_size = 0;
//aml_out->pause_status = false;
- if (aml_out->pause_status || aml_out->standby) {
+ if (aml_out->pause_status) {
struct meta_data_list *mdata_list;
struct listnode *item;
//mixer_flush_inport(audio_mixer, out->port_index);
- pthread_mutex_lock(&aml_out->mdata_lock);
- while (!list_empty(&aml_out->mdata_list)) {
- item = list_head(&aml_out->mdata_list);
- mdata_list = node_to_item(item, struct meta_data_list, list);
- list_remove(&mdata_list->list);
- free(mdata_list);
+ if (aml_out->hw_sync_mode) {
+ pthread_mutex_lock(&aml_out->mdata_lock);
+ while (!list_empty(&aml_out->mdata_list)) {
+ item = list_head(&aml_out->mdata_list);
+ mdata_list = node_to_item(item, struct meta_data_list, list);
+ list_remove(item);
+ free(mdata_list);
+ }
+ pthread_mutex_unlock(&aml_out->mdata_lock);
}
- pthread_mutex_unlock(&aml_out->mdata_lock);
audio_mixer = sm->mixerData;
send_mixer_inport_message(audio_mixer, aml_out->port_index, MSG_FLUSH);
flush_hw_avsync_header_extractor(aml_out->hwsync_extractor);
//mixer_set_inport_state(audio_mixer, out->port_index, FLUSHING);
aml_out->last_frames_postion = 0;
aml_out->first_pts_set = false;
- aml_out->pause_status = false;
- aml_out->standby = true;
+ //aml_out->pause_status = false;
+ //aml_out->standby = true;
} else {
ALOGW("%s(), line %d. Need check this case!", __func__, __LINE__);
- return INVALID_STATE;
+ return 0;
}
ALOGI("-%s()", __func__);
@@ -1255,10 +1310,12 @@ int switchNormalStream(struct aml_stream_out *aml_out, bool on)
initSubMixingInputPcm(&aml_out->out_cfg, aml_out);
aml_out->stream.write = mixer_aux_buffer_write_sm;
aml_out->stream.common.standby = out_standby_subMixingPCM;
+ out_standby_subMixingPCM((struct audio_stream *)aml_out);
} else {
- aml_out->stream.write = out_write_new;
+ aml_out->stream.write = mixer_aux_buffer_write;
aml_out->stream.common.standby = out_standby_new;
deleteSubMixingInputPcm(aml_out);
+ out_standby_new((struct audio_stream *)aml_out);
}
return 0;
diff --git a/audio/audio_hal/sub_mixing_factory.h b/audio/audio_hal/sub_mixing_factory.h
index a539d89..b61b276 100644
--- a/audio/audio_hal/sub_mixing_factory.h
+++ b/audio/audio_hal/sub_mixing_factory.h
@@ -77,15 +77,6 @@ struct subMixing {
int cnt_stream_using_mixer;
};
-int mainWritePCM(struct subMixing *mixer, void *buf, size_t bytes);
-int sysWritePCM(struct subMixing *mixer, void *buf, size_t bytes);
-int newSubMixingFactory(
- struct subMixing **smixer,
- enum MIXER_TYPE type,
- struct audioCfg cfg,
- void *data);
-void deleteSubMixing(struct subMixing *sm);
-
int initHalSubMixing(struct subMixing **smixer,
enum MIXER_TYPE type,
struct aml_audio_device *adev,
@@ -96,13 +87,7 @@ int initSubMixingInput(struct aml_stream_out *out,
struct audio_config *config);
int deleteSubMixingInput(struct aml_stream_out *out);
int usecase_change_validate_l_sm(struct aml_stream_out *out, bool is_standby);
-ssize_t out_write_subMixingPCM(struct audio_stream_out *stream,
- const void *buffer,
- size_t bytes);
int out_standby_subMixingPCM(struct audio_stream *stream);
-int out_pause_subMixingPCM(struct audio_stream_out *stream);
-int out_resume_subMixingPCM(struct audio_stream_out *stream);
-int out_flush_subMixingPCM(struct audio_stream_out *stream);
int switchNormalStream(struct aml_stream_out *aml_out, bool on);
struct pcm *getSubMixingPCMdev(struct subMixing *sm);