summaryrefslogtreecommitdiff
authorShuai Li <shuai.li@amlogic.com>2017-01-12 06:17:53 (GMT)
committer Frank Chen <frank.chen@amlogic.com>2017-02-27 08:20:50 (GMT)
commit30014c35d02c812ff3ec2fbbcf61905cd7500281 (patch)
treea402aa96304c2fb525d1215aed3a0d6baaefb41f
parent34d62d4d4e1de910e4d56b0dc2f8f0ff8fdb5910 (diff)
downloadaudio-30014c35d02c812ff3ec2fbbcf61905cd7500281.zip
audio-30014c35d02c812ff3ec2fbbcf61905cd7500281.tar.gz
audio-30014c35d02c812ff3ec2fbbcf61905cd7500281.tar.bz2
PD#138361: audio: enable HDMI dynamic profile and HWSYNC property
- fix profile get parameter bugs:"sup_formats=" - remove hwsync params in 'dev' - fix a/v sync issue after seek - fix compiling warnings - fix 6 CTS fails on AudioTrackSurroundTest Change-Id: Id00a15c0f17903e0f6530cf3b8a5a8c464f01708
Diffstat
-rw-r--r--Android.mk3
-rw-r--r--audio_hw.c531
-rw-r--r--audio_hw.h18
-rw-r--r--audio_hw_profile.c31
-rw-r--r--audio_hwsync.c29
-rw-r--r--audio_hwsync.h17
-rw-r--r--spdifenc_wrap.cpp26
7 files changed, 290 insertions, 365 deletions
diff --git a/Android.mk b/Android.mk
index 1337272..12cd68c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -31,7 +31,8 @@ ifeq ($(strip $(BOARD_ALSA_AUDIO)),tiny)
libTVaudio/audio/audio_effect_control.c \
audio_hw_utils.c \
audio_hwsync.c \
- //spdifenc_wrap.cpp
+ spdifenc_wrap.cpp \
+ audio_hw_profile.c
LOCAL_C_INCLUDES += \
external/tinyalsa/include \
system/media/audio_utils/include \
diff --git a/audio_hw.c b/audio_hw.c
index c666627..17f2459 100644
--- a/audio_hw.c
+++ b/audio_hw.c
@@ -15,7 +15,7 @@
*/
#define LOG_TAG "audio_hw_primary"
-//#define LOG_NALOGV 0
+//#define LOG_NDEBUG 0
//#define LOG_NALOGV_FUNCTION
#ifdef LOG_NALOGV_FUNCTION
#define LOGFUNC(...) ((void)0)
@@ -26,6 +26,7 @@
#include <errno.h>
#include <pthread.h>
#include <stdint.h>
+#include <inttypes.h>
#include <sys/time.h>
#include <stdlib.h>
#include <sys/stat.h>
@@ -49,12 +50,8 @@
#include "libTVaudio/audio/audio_effect_control.h"
#include "audio_hw.h"
#include "audio_hw_utils.h"
+#include "audio_hw_profile.h"
#include "spdifenc_wrap.h"
-//extern int spdifenc_write(const void *buffer, size_t numBytes);
-//extern uint64_t spdifenc_get_total();
-extern void aml_audio_hwsync_clear_status(struct aml_stream_out *out);
-extern int aml_audio_hwsync_find_frame(struct aml_stream_out *out,
- const void *in_buffer, size_t in_bytes, uint64_t *cur_pts, int *outsize);
/* ALSA cards for AML */
#define CARD_AMLOGIC_BOARD 0
@@ -90,14 +87,6 @@ static unsigned CAPTURE_PERIOD_SIZE = DEFAULT_CAPTURE_PERIOD_SIZE;
#define VX_NB_SAMPLING_RATE 8000
#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
-#define TSYNC_FIRSTAPTS "/sys/class/tsync/firstapts"
-#define TSYNC_PCRSCR "/sys/class/tsync/pts_pcrscr"
-#define TSYNC_EVENT "/sys/class/tsync/event"
-#define TSYNC_APTS "/sys/class/tsync/pts_audio"
-#define SYSTIME_CORRECTION_THRESHOLD (90000*10/100)
-#define APTS_DISCONTINUE_THRESHOLD_MIN (90000/1000*100)
-#define APTS_DISCONTINUE_THRESHOLD_MAX (5*90000)
-
static const struct pcm_config pcm_config_out = {
.channels = 2,
.rate = MM_FULL_POWER_SAMPLING_RATE,
@@ -130,10 +119,6 @@ static const struct pcm_config pcm_config_bt = {
.format = PCM_FORMAT_S16_LE,
};
-#define HW_SYNC_STATE_HEADER 0
-#define HW_SYNC_STATE_BODY 1
-#define HW_SYNC_STATE_RESYNC 2
-
static void select_output_device(struct aml_audio_device *adev);
static void select_input_device(struct aml_audio_device *adev);
static void select_devices(struct aml_audio_device *adev);
@@ -245,35 +230,6 @@ static int aml_hal_mixer_read(struct aml_hal_mixer *mixer, void *r_buf, uint siz
return size;
}
// aml audio hal mixer code end
-#if 0
-static inline bool hwsync_header_valid(uint8_t *header)
-{
- return (header[0] == 0x55) &&
- (header[1] == 0x55) &&
- (header[2] == 0x00) &&
- (header[3] == 0x01);
-}
-
-static inline uint64_t hwsync_header_get_pts(uint8_t *header)
-{
- return (((uint64_t)header[8]) << 56) |
- (((uint64_t)header[9]) << 48) |
- (((uint64_t)header[10]) << 40) |
- (((uint64_t)header[11]) << 32) |
- (((uint64_t)header[12]) << 24) |
- (((uint64_t)header[13]) << 16) |
- (((uint64_t)header[14]) << 8) |
- ((uint64_t)header[15]);
-}
-
-static inline uint32_t hwsync_header_get_size(uint8_t *header)
-{
- return (((uint32_t)header[4]) << 24) |
- (((uint32_t)header[5]) << 16) |
- (((uint32_t)header[6]) << 8) |
- ((uint32_t)header[7]);
-}
-#endif
static void select_devices(struct aml_audio_device *adev)
{
@@ -344,113 +300,6 @@ static void select_mode(struct aml_audio_device *adev)
return;
}
-static int get_aml_card(void)
-{
- int card = -1, err = 0;
- int fd = -1;
- unsigned fileSize = 512;
- char *read_buf = NULL, *pd = NULL;
- static const char *const SOUND_CARDS_PATH = "/proc/asound/cards";
- fd = open(SOUND_CARDS_PATH, O_RDONLY);
- if (fd < 0) {
- ALOGE("ERROR: failed to open config file %s error: %d\n", SOUND_CARDS_PATH, errno);
- close(fd);
- return -EINVAL;
- }
-
- read_buf = (char *)malloc(fileSize);
- if (!read_buf) {
- ALOGE("Failed to malloc read_buf");
- close(fd);
- return -ENOMEM;
- }
- memset(read_buf, 0x0, fileSize);
- err = read(fd, read_buf, fileSize);
- if (fd < 0) {
- ALOGE("ERROR: failed to read config file %s error: %d\n", SOUND_CARDS_PATH, errno);
- close(fd);
- return -EINVAL;
- }
- pd = strstr(read_buf, "AML");
- card = *(pd - 3) - '0';
-
-OUT:
- free(read_buf);
- close(fd);
- return card;
-}
-
-static int get_pcm_bt_port(void)
-{
- int port = -1, err = 0;
- int fd = -1;
- unsigned fileSize = 512;
- char *read_buf = NULL, *pd = NULL;
- static const char *const SOUND_PCM_PATH = "/proc/asound/pcm";
- fd = open(SOUND_PCM_PATH, O_RDONLY);
- if (fd < 0) {
- ALOGE("ERROR: failed to open config file %s error: %d\n", SOUND_PCM_PATH, errno);
- close(fd);
- return -EINVAL;
- }
-
- read_buf = (char *)malloc(fileSize);
- if (!read_buf) {
- ALOGE("Failed to malloc read_buf");
- close(fd);
- return -ENOMEM;
- }
- memset(read_buf, 0x0, fileSize);
- err = read(fd, read_buf, fileSize);
- if (fd < 0) {
- ALOGE("ERROR: failed to read config file %s error: %d\n", SOUND_PCM_PATH, errno);
- close(fd);
- return -EINVAL;
- }
- pd = strstr(read_buf, "pcm2bt-pcm");
- port = *(pd + 11) - '0';
-
-OUT:
- free(read_buf);
- close(fd);
- return port;
-}
-
-static int get_spdif_port()
-{
- int port = -1, err = 0;
- int fd = -1;
- unsigned fileSize = 512;
- char *read_buf = NULL, *pd = NULL;
- static const char *const SOUND_PCM_PATH = "/proc/asound/pcm";
- fd = open(SOUND_PCM_PATH, O_RDONLY);
- if (fd < 0) {
- ALOGE("ERROR: failed to open config file %s error: %d\n", SOUND_PCM_PATH, errno);
- close(fd);
- return -EINVAL;
- }
-
- read_buf = (char *)malloc(fileSize);
- if (!read_buf) {
- ALOGE("Failed to malloc read_buf");
- close(fd);
- return -ENOMEM;
- }
- memset(read_buf, 0x0, fileSize);
- err = read(fd, read_buf, fileSize);
- if (fd < 0) {
- ALOGE("ERROR: failed to read config file %s error: %d\n", SOUND_PCM_PATH, errno);
- close(fd);
- return -EINVAL;
- }
- pd = strstr(read_buf, "SPDIF");
- port = *(pd - 3) - '0';
-
-OUT:
- free(read_buf);
- close(fd);
- return port;
-}
/* must be called with hw device and output stream mutexes locked */
static int start_output_stream(struct aml_stream_out *out)
{
@@ -662,7 +511,6 @@ static int start_output_stream_direct(struct aml_stream_out *out)
out->spdif_enc_init_frame_write_sum = out->frame_write_sum;
}
out->codec_type = codec_type;
- out->bytes_write_total = 0;
if (out->hw_sync_mode == 1) {
LOGFUNC("start_output_stream with hw sync enable %p\n", out);
@@ -786,7 +634,7 @@ static int get_playback_delay(struct aml_stream_out *out,
struct echo_reference_buffer *buffer)
{
- size_t kernel_frames;
+ unsigned int kernel_frames;
int status;
status = pcm_get_htimestamp(out->pcm, &kernel_frames, &buffer->time_stamp);
if (status < 0) {
@@ -828,7 +676,8 @@ static size_t out_get_buffer_size(const struct audio_stream *stream)
{
struct aml_stream_out *out = (struct aml_stream_out *)stream;
- //LOGFUNC("%s(out->config.rate=%d)", __FUNCTION__, out->config.rate);
+ ALOGV("%s(out->config.rate=%d, format %x)", __FUNCTION__,
+ out->config.rate, out->hal_format);
/* take resampling into account and return the closest majoring
* multiple of 16 frames, as audioflinger expects audio buffers to
@@ -841,14 +690,14 @@ static size_t out_get_buffer_size(const struct audio_stream *stream)
if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
size = 4 * PERIOD_SIZE * PLAYBACK_PERIOD_COUNT;
} else {
- size = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE / 2;
+ size = PERIOD_SIZE;
}
break;
case AUDIO_FORMAT_E_AC3:
if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
size = 16 * PERIOD_SIZE * PLAYBACK_PERIOD_COUNT;
} else {
- size = PERIOD_SIZE; //2*PLAYBACK_PERIOD_COUNT*PERIOD_SIZE;
+ size = PLAYBACK_PERIOD_COUNT*PERIOD_SIZE; //PERIOD_SIZE;
}
break;
case AUDIO_FORMAT_DTS_HD:
@@ -985,6 +834,7 @@ static int do_output_standby_direct(struct aml_stream_out *out)
pcm_close(out->pcm);
out->pcm = NULL;
}
+ out->pause_status = false;
set_codec_type(TYPE_PCM);
/* clear the hdmitx channel config to default */
if (out->multich == 6) {
@@ -1024,6 +874,7 @@ static int out_standby_direct(struct audio_stream *stream)
pcm_close(out->pcm);
out->pcm = NULL;
}
+ out->pause_status = false;
set_codec_type(TYPE_PCM);
/* clear the hdmitx channel config to default */
if (out->multich == 6) {
@@ -1066,6 +917,10 @@ out_flush(struct audio_stream_out *stream)
standy_func(out);
out->frame_write_sum = 0;
out->last_frames_postion = 0;
+ out->spdif_enc_init_frame_write_sum = 0;
+ out->frame_skip_sum = 0;
+ out->skip_frame = 3;
+
exit:
pthread_mutex_unlock(&adev->lock);
pthread_mutex_unlock(&out->lock);
@@ -1238,10 +1093,11 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
if (ret >= 0) {
int hw_sync_id = atoi(value);
unsigned char sync_enable = (hw_sync_id == 12345678) ? 1 : 0;
+ audio_hwsync_t *hw_sync = &out->hwsync;
ALOGI("(%p)set hw_sync_id %d,%s hw sync mode\n",
out, hw_sync_id, sync_enable ? "enable" : "disable");
out->hw_sync_mode = sync_enable;
- out->first_apts_flag = false;
+ hw_sync->first_apts_flag = false;
pthread_mutex_lock(&adev->lock);
pthread_mutex_lock(&out->lock);
out->frame_write_sum = 0;
@@ -1265,26 +1121,82 @@ exit:
return ret;
}
-static char * out_get_parameters(const struct audio_stream *stream __unused, const char *keys __unused)
+static char *out_get_parameters(const struct audio_stream *stream, const char *keys)
{
+ char *cap = NULL;
+ char *para = NULL;
+ struct aml_stream_out *out = (struct aml_stream_out *) stream;
+ struct aml_audio_device *adev = out->dev;
+ ALOGI("out_get_parameters %s,out %p\n", keys, out);
+ if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
+ if (out->out_device & AUDIO_DEVICE_OUT_HDMI_ARC) {
+ cap = (char *)get_hdmi_arc_cap(adev->hdmi_arc_ad, HDMI_ARC_MAX_FORMAT, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES);
+ } else {
+ cap = (char *)get_hdmi_sink_cap(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES);
+ }
+ if (cap) {
+ para = strdup(cap);
+ free(cap);
+ } else {
+ para = strdup("");
+ }
+ ALOGI("%s\n", para);
+ return para;
+ } else if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
+ if (out->out_device & AUDIO_DEVICE_OUT_HDMI_ARC) {
+ cap = (char *)get_hdmi_arc_cap(adev->hdmi_arc_ad, HDMI_ARC_MAX_FORMAT, AUDIO_PARAMETER_STREAM_SUP_CHANNELS);
+ } else {
+ cap = (char *)get_hdmi_sink_cap(AUDIO_PARAMETER_STREAM_SUP_CHANNELS);
+ }
+ if (cap) {
+ para = strdup(cap);
+ free(cap);
+ } else {
+ para = strdup("");
+ }
+ ALOGI("%s\n", para);
+ return para;
+ } else if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
+ if (out->out_device & AUDIO_DEVICE_OUT_HDMI_ARC) {
+ cap = (char *)get_hdmi_arc_cap(adev->hdmi_arc_ad, HDMI_ARC_MAX_FORMAT, AUDIO_PARAMETER_STREAM_SUP_FORMATS);
+ } else {
+ cap = (char *)get_hdmi_sink_cap(AUDIO_PARAMETER_STREAM_SUP_FORMATS);
+ }
+ if (cap) {
+ para = strdup(cap);
+ free(cap);
+ } else {
+ para = strdup("");
+ }
+ ALOGI("%s\n", para);
+ return para;
+ }
return strdup("");
}
-static uint32_t out_get_latency(const struct audio_stream_out *stream)
+static uint32_t out_get_latency_frames(const struct audio_stream_out *stream)
{
const struct aml_stream_out *out = (const struct aml_stream_out *)stream;
- uint32_t whole_latency;
- int ret = 0;
snd_pcm_sframes_t frames = 0;
- whole_latency = (out->config.period_size * out->config.period_count * 1000) / out->config.rate;
+ uint32_t whole_latency_frames;
+ int ret = 0;
+
+ whole_latency_frames = out->config.period_size * out->config.period_count;
if (!out->pcm || !pcm_is_ready(out->pcm)) {
- return whole_latency;
+ return whole_latency_frames;
}
ret = pcm_ioctl(out->pcm, SNDRV_PCM_IOCTL_DELAY, &frames);
if (ret < 0) {
- return whole_latency;
+ return whole_latency_frames;
}
- return (frames * 1000) / out->config.rate/* (out->pcm->config.rate)*/;
+ return frames;
+}
+
+static uint32_t out_get_latency(const struct audio_stream_out *stream)
+{
+ const struct aml_stream_out *out = (const struct aml_stream_out *)stream;
+ snd_pcm_sframes_t frames = out_get_latency_frames(stream);
+ return (frames * 1000) / out->config.rate;
}
static int out_set_volume(struct audio_stream_out *stream, float left, float right)
@@ -1415,6 +1327,7 @@ static ssize_t out_write_legacy(struct audio_stream_out *stream, const void* buf
uint32_t latency_frames = 0;
int need_mix = 0;
short *mix_buf = NULL;
+ audio_hwsync_t *hw_sync = &out->hwsync;
unsigned char enable_dump = getprop_bool("media.audiohal.outdump");
// limit HAL mixer buffer level within 200ms
while ((adev->hwsync_output != NULL && adev->hwsync_output != out) &&
@@ -1478,9 +1391,9 @@ static ssize_t out_write_legacy(struct audio_stream_out *stream, const void* buf
}
if ((out->standby) && (out->hw_sync_mode == 1)) {
// todo: check timestamp header PTS discontinue for new sync point after seek
- out->first_apts_flag = false;
- out->hw_sync_state = HW_SYNC_STATE_HEADER;
- out->hw_sync_header_cnt = 0;
+ hw_sync->first_apts_flag = false;
+ hw_sync->hw_sync_state = HW_SYNC_STATE_HEADER;
+ hw_sync->hw_sync_header_cnt = 0;
}
#if 1
@@ -1497,20 +1410,20 @@ static ssize_t out_write_legacy(struct audio_stream_out *stream, const void* buf
char buf[64] = {0};
unsigned char *header;
- if (out->hw_sync_state == HW_SYNC_STATE_RESYNC) {
+ if (hw_sync->hw_sync_state == HW_SYNC_STATE_RESYNC) {
uint i = 0;
uint8_t *p = (uint8_t *)buffer;
while (i < bytes) {
if (hwsync_header_valid(p)) {
ALOGI("HWSYNC resync.%p", out);
- out->hw_sync_state = HW_SYNC_STATE_HEADER;
- out->hw_sync_header_cnt = 0;
- out->first_apts_flag = false;
+ hw_sync->hw_sync_state = HW_SYNC_STATE_HEADER;
+ hw_sync->hw_sync_header_cnt = 0;
+ hw_sync->first_apts_flag = false;
bytes -= i;
- buffer += i;
+ p += i;
in_frames = bytes / frame_size;
- ALOGI("in_frames = %d", in_frames);
- in_buffer = (int16_t *)buffer;
+ ALOGI("in_frames = %zu", in_frames);
+ in_buffer = (int16_t *)p;
break;
} else {
i += 4;
@@ -1518,7 +1431,7 @@ static ssize_t out_write_legacy(struct audio_stream_out *stream, const void* buf
}
}
- if (out->hw_sync_state == HW_SYNC_STATE_RESYNC) {
+ if (hw_sync->hw_sync_state == HW_SYNC_STATE_RESYNC) {
ALOGI("Keep searching for HWSYNC header.%p", out);
pthread_mutex_unlock(&adev->lock);
goto exit;
@@ -1622,62 +1535,64 @@ if (!(adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO)) {
} else {
if (out->hw_sync_mode) {
- int remain = out_frames * frame_size;
- uint8_t *p = buffer;
+ size_t remain = out_frames * frame_size;
+ uint8_t *p = (uint8_t *)buffer;
//ALOGI(" --- out_write %d, cache cnt = %d, body = %d, hw_sync_state = %d", out_frames * frame_size, out->body_align_cnt, out->hw_sync_body_cnt, out->hw_sync_state);
while (remain > 0) {
- if (out->hw_sync_state == HW_SYNC_STATE_HEADER) {
+ if (hw_sync->hw_sync_state == HW_SYNC_STATE_HEADER) {
//ALOGI("Add to header buffer [%d], 0x%x", out->hw_sync_header_cnt, *p);
- out->hw_sync_header[out->hw_sync_header_cnt++] = *p++;
+ out->hwsync.hw_sync_header[out->hwsync.hw_sync_header_cnt++] = *p++;
remain--;
- if (out->hw_sync_header_cnt == 16) {
- int64_t pts;
- if (!hwsync_header_valid(&out->hw_sync_header[0])) {
+ if (hw_sync->hw_sync_header_cnt == 16) {
+ uint64_t pts;
+ if (!hwsync_header_valid(&hw_sync->hw_sync_header[0])) {
ALOGE("hwsync header out of sync! Resync.");
- out->hw_sync_state = HW_SYNC_STATE_RESYNC;
+ hw_sync->hw_sync_state = HW_SYNC_STATE_RESYNC;
break;
}
- out->hw_sync_state = HW_SYNC_STATE_BODY;
- out->hw_sync_body_cnt = hwsync_header_get_size(&out->hw_sync_header[0]);
- out->body_align_cnt = 0;
- pts = hwsync_header_get_pts(&out->hw_sync_header[0]);
+ hw_sync->hw_sync_state = HW_SYNC_STATE_BODY;
+ hw_sync->hw_sync_body_cnt = hwsync_header_get_size(&hw_sync->hw_sync_header[0]);
+ hw_sync->body_align_cnt = 0;
+ pts = hwsync_header_get_pts(&hw_sync->hw_sync_header[0]);
pts = pts * 90 / 1000000;
#if 1
char buf[64] = {0};
- if (out->first_apts_flag == false) {
+ if (hw_sync->first_apts_flag == false) {
uint32_t apts_cal;
- ALOGI("HW SYNC new first APTS %lld,body size %d", pts, out->hw_sync_body_cnt);
- out->first_apts_flag = true;
- out->first_apts = pts;
+ ALOGI("HW SYNC new first APTS %zd,body size %zu", pts, hw_sync->hw_sync_body_cnt);
+ hw_sync->first_apts_flag = true;
+ hw_sync->first_apts = pts;
out->frame_write_sum = 0;
- out->last_apts_from_header = pts;
- sprintf(buf, "AUDIO_START:0x%llx", pts & 0xffffffff);
+ hw_sync->last_apts_from_header = pts;
+ sprintf(buf, "AUDIO_START:0x%"PRIx64"", pts & 0xffffffff);
ALOGI("tsync -> %s", buf);
if (sysfs_set_sysfs_str(TSYNC_EVENT, buf) == -1) {
ALOGE("set AUDIO_START failed \n");
}
} else {
- int64_t apts;
- uint32_t latency = out_get_latency(out) * 90;
+ uint64_t apts;
+ uint32_t latency = out_get_latency(stream) * 90;
apts = (uint64_t)out->frame_write_sum * 90000 / DEFAULT_OUT_SAMPLING_RATE;
- apts += out->first_apts;
+ apts += hw_sync->first_apts;
// check PTS discontinue, which may happen when audio track switching
// discontinue means PTS calculated based on first_apts and frame_write_sum
// does not match the timestamp of next audio samples
- apts -= latency;
- if (apts < 0) {
+ if (apts > latency) {
+ apts -= latency;
+ } else {
apts = 0;
}
+
// here we use acutal audio frame gap,not use the differece of caculated current apts with the current frame pts,
//as there is a offset of audio latency from alsa.
// handle audio gap 0.5~5 s
- unsigned two_frame_gap = (unsigned)llabs(out->last_apts_from_header - pts);
+ uint64_t two_frame_gap = pts_abs(hw_sync->last_apts_from_header, pts);
if (two_frame_gap > APTS_DISCONTINUE_THRESHOLD_MIN && two_frame_gap < APTS_DISCONTINUE_THRESHOLD_MAX) {
/* if (abs(pts -apts) > APTS_DISCONTINUE_THRESHOLD_MIN && abs(pts -apts) < APTS_DISCONTINUE_THRESHOLD_MAX) { */
- ALOGI("HW sync PTS discontinue, 0x%llx->0x%llx(from header) diff %d,last apts %llx(from header)",
- apts, pts, two_frame_gap, out->last_apts_from_header);
+ ALOGI("HW sync PTS discontinue, 0x%"PRIx64"->0x%"PRIx64"(from header) diff %"PRIx64",last apts %"PRIx64"(from header)",
+ apts, pts, two_frame_gap, hw_sync->last_apts_from_header);
//here handle the audio gap and insert zero to the alsa
uint insert_size = 0;
uint insert_size_total = 0;
@@ -1685,7 +1600,7 @@ if (!(adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO)) {
insert_size = two_frame_gap/*abs(pts -apts) */ / 90 * 48 * 4;
insert_size = insert_size & (~63);
insert_size_total = insert_size;
- ALOGI("audio gap %d ms ,need insert pcm size %d\n", two_frame_gap/*abs(pts -apts) */ / 90, insert_size);
+ ALOGI("audio gap %"PRIx64" ms ,need insert pcm size %d\n", two_frame_gap/*abs(pts -apts) */ / 90, insert_size);
char *insert_buf = (char*)malloc(8192);
if (insert_buf == NULL) {
ALOGE("malloc size failed \n");
@@ -1755,7 +1670,7 @@ if (!(adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO)) {
// do nothing
} else {
sprintf(buf, "0x%x", apts_cal);
- ALOGI("tsync -> reset pcrscr 0x%x -> 0x%x, diff %d ms,frame pts %llx,latency pts %d", pcr, apts_cal, (int)(apts_cal - pcr) / 90, pts, latency);
+ ALOGI("tsync -> reset pcrscr 0x%x -> 0x%x, diff %d ms,frame pts %"PRIx64",latency pts %d", pcr, apts_cal, (int)(apts_cal - pcr) / 90, pts, latency);
int ret_val = sysfs_set_sysfs_str(TSYNC_APTS, buf);
if (ret_val == -1) {
ALOGE("unable to open file %s,err: %s", TSYNC_APTS, strerror(errno));
@@ -1763,48 +1678,48 @@ if (!(adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO)) {
}
}
}
- out->last_apts_from_header = pts;
+ hw_sync->last_apts_from_header = pts;
}
#endif
//ALOGI("get header body_cnt = %d, pts = %lld", out->hw_sync_body_cnt, pts);
}
continue;
- } else if (out->hw_sync_state == HW_SYNC_STATE_BODY) {
+ } else if (hw_sync->hw_sync_state == HW_SYNC_STATE_BODY) {
uint align;
- uint m = (out->hw_sync_body_cnt < remain) ? out->hw_sync_body_cnt : remain;
+ uint m = (hw_sync->hw_sync_body_cnt < remain) ? hw_sync->hw_sync_body_cnt : remain;
//ALOGI("m = %d", m);
// process m bytes, upto end of hw_sync_body_cnt or end of remaining our_write bytes.
// within m bytes, there is no hw_sync header and all are body bytes.
- if (out->body_align_cnt) {
+ if (hw_sync->body_align_cnt) {
// clear fragment first for alignment limitation on ALSA driver, which
// requires each pcm_writing aligned at 16 frame boundaries
// assuming data are always PCM16 based, so aligned at 64 bytes unit.
- if ((m + out->body_align_cnt) < 64) {
+ if ((m + hw_sync->body_align_cnt) < 64) {
// merge only
- memcpy(&out->body_align[out->body_align_cnt], p, m);
+ memcpy(&hw_sync->body_align[hw_sync->body_align_cnt], p, m);
p += m;
remain -= m;
- out->body_align_cnt += m;
- out->hw_sync_body_cnt -= m;
- if (out->hw_sync_body_cnt == 0) {
+ hw_sync->body_align_cnt += m;
+ hw_sync->hw_sync_body_cnt -= m;
+ if (hw_sync->hw_sync_body_cnt == 0) {
// end of body, research for HW SYNC header
- out->hw_sync_state = HW_SYNC_STATE_HEADER;
- out->hw_sync_header_cnt = 0;
+ hw_sync->hw_sync_state = HW_SYNC_STATE_HEADER;
+ hw_sync->hw_sync_header_cnt = 0;
continue;
}
//ALOGI("align cache add %d, cnt = %d", remain, out->body_align_cnt);
break;
} else {
// merge-submit-continue
- memcpy(&out->body_align[out->body_align_cnt], p, 64 - out->body_align_cnt);
- p += 64 - out->body_align_cnt;
- remain -= 64 - out->body_align_cnt;
+ memcpy(&hw_sync->body_align[hw_sync->body_align_cnt], p, 64 - hw_sync->body_align_cnt);
+ p += 64 - hw_sync->body_align_cnt;
+ remain -= 64 - hw_sync->body_align_cnt;
//ALOGI("pcm_write 64, out remain %d", remain);
- short *w_buf = (short*)&out->body_align[0];
+ short *w_buf = (short*)&hw_sync->body_align[0];
if (need_mix) {
short mix_buf[32];
@@ -1841,11 +1756,11 @@ if (!(adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO)) {
ret = pcm_write(out->pcm, w_buf, 64);
pthread_mutex_unlock(&adev->pcm_write_lock);
out->frame_write_sum += 64 / frame_size;
- out->hw_sync_body_cnt -= 64 - out->body_align_cnt;
- out->body_align_cnt = 0;
- if (out->hw_sync_body_cnt == 0) {
- out->hw_sync_state = HW_SYNC_STATE_HEADER;
- out->hw_sync_header_cnt = 0;
+ hw_sync->hw_sync_body_cnt -= 64 - hw_sync->body_align_cnt;
+ hw_sync->body_align_cnt = 0;
+ if (hw_sync->hw_sync_body_cnt == 0) {
+ hw_sync->hw_sync_state = HW_SYNC_STATE_HEADER;
+ hw_sync->hw_sync_header_cnt = 0;
}
continue;
}
@@ -1901,25 +1816,25 @@ if (!(adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO)) {
remain -= m - align;
//ALOGI("pcm_write %d, remain %d", m - align, remain);
- out->hw_sync_body_cnt -= (m - align);
- if (out->hw_sync_body_cnt == 0) {
- out->hw_sync_state = HW_SYNC_STATE_HEADER;
- out->hw_sync_header_cnt = 0;
+ hw_sync->hw_sync_body_cnt -= (m - align);
+ if (hw_sync->hw_sync_body_cnt == 0) {
+ hw_sync->hw_sync_state = HW_SYNC_STATE_HEADER;
+ hw_sync->hw_sync_header_cnt = 0;
continue;
}
}
if (align) {
- memcpy(&out->body_align[0], p, align);
+ memcpy(&hw_sync->body_align[0], p, align);
p += align;
remain -= align;
- out->body_align_cnt = align;
+ hw_sync->body_align_cnt = align;
//ALOGI("align cache add %d, cnt = %d, remain = %d", align, out->body_align_cnt, remain);
- out->hw_sync_body_cnt -= align;
- if (out->hw_sync_body_cnt == 0) {
- out->hw_sync_state = HW_SYNC_STATE_HEADER;
- out->hw_sync_header_cnt = 0;
+ hw_sync->hw_sync_body_cnt -= align;
+ if (hw_sync->hw_sync_body_cnt == 0) {
+ hw_sync->hw_sync_state = HW_SYNC_STATE_HEADER;
+ hw_sync->hw_sync_header_cnt = 0;
continue;
}
}
@@ -1947,7 +1862,8 @@ if (!(adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO)) {
}
exit:
- latency_frames = out_get_latency(out) * out->config.rate / 1000;
+ clock_gettime(CLOCK_MONOTONIC, &out->timestamp);
+ latency_frames = out_get_latency_frames(stream);
if (out->frame_write_sum >= latency_frames) {
out->last_frames_postion = out->frame_write_sum - latency_frames;
} else {
@@ -2091,7 +2007,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
out->frame_write_sum += out_frames;
exit:
- latency_frames = out_get_latency(out) * out->config.rate / 1000;
+ latency_frames = out_get_latency(stream) * out->config.rate / 1000;
if (out->frame_write_sum >= latency_frames) {
out->last_frames_postion = out->frame_write_sum - latency_frames;
} else {
@@ -2131,24 +2047,24 @@ static ssize_t out_write_direct(struct audio_stream_out *stream, const void* buf
char prop[PROPERTY_VALUE_MAX];
int codec_type = out->codec_type;
int samesource_flag = 0;
- uint32_t latency_frames;
+ uint32_t latency_frames = 0;
uint64_t total_frame = 0;
- audio_hwsync_t *p_hwsync = &adev->hwsync;
+ audio_hwsync_t *hw_sync = &out->hwsync;
/* acquiring hw device mutex systematically is useful if a low priority thread is waiting
* on the output stream mutex - e.g. executing select_mode() while holding the hw device
* mutex
*/
- out->bytes_write_total += bytes;
- ALOGV("out %p,dev %p out_write total size %lld\n", out, adev, out->bytes_write_total);
+ ALOGV("out_write_direct:out %p,position %zu, out_write size %"PRIu64,
+ out, bytes, out->frame_write_sum);
pthread_mutex_lock(&adev->lock);
pthread_mutex_lock(&out->lock);
if (out->pause_status == true) {
pthread_mutex_unlock(&adev->lock);
pthread_mutex_unlock(&out->lock);
- ALOGI("call out_write when pause status,size %d,(%p)\n", bytes, out);
+ ALOGI("call out_write when pause status,size %zu,(%p)\n", bytes, out);
return 0;
}
- if ((out->standby) && adev->hw_sync_mode) {
+ if ((out->standby) && out->hw_sync_mode) {
/*
there are two types of raw data come to hdmi audio hal
1) compressed audio data without IEC61937 wrapped
@@ -2177,20 +2093,20 @@ static ssize_t out_write_direct(struct audio_stream_out *stream, const void* buf
}
}
void *write_buf = NULL;
- int hwsync_cost_bytes = 0;
- if (adev->hw_sync_mode == 1) {
- int64_t cur_pts = 0xffffffff;
+ size_t hwsync_cost_bytes = 0;
+ if (out->hw_sync_mode == 1) {
+ uint64_t cur_pts = 0xffffffff;
int outsize = 0;
char tempbuf[128];
- ALOGV("before aml_audio_hwsync_find_frame bytes %d\n", bytes);
+ ALOGV("before aml_audio_hwsync_find_frame bytes %zu\n", bytes);
hwsync_cost_bytes = aml_audio_hwsync_find_frame(out, buffer, bytes, &cur_pts, &outsize);
- ALOGV("after aml_audio_hwsync_find_frame bytes remain %d,cost %d,outsize %d,pts %llx\n",
+ ALOGV("after aml_audio_hwsync_find_frame bytes remain %zu,cost %zu,outsize %d,pts %"PRIx64"\n",
bytes - hwsync_cost_bytes, hwsync_cost_bytes, outsize, cur_pts);
//TODO,skip 3 frames after flush, to tmp fix seek pts discontinue issue.need dig more
// to find out why seek ppint pts frame is remained after flush.WTF.
if (out->skip_frame > 0) {
out->skip_frame--;
- ALOGI("skip pts@%llx,cur frame size %d,cost size %d\n", cur_pts, outsize, hwsync_cost_bytes);
+ ALOGI("skip pts@%"PRIx64",cur frame size %d,cost size %zu\n", cur_pts, outsize, hwsync_cost_bytes);
pthread_mutex_unlock(&adev->lock);
pthread_mutex_unlock(&out->lock);
return hwsync_cost_bytes;
@@ -2199,38 +2115,38 @@ static ssize_t out_write_direct(struct audio_stream_out *stream, const void* buf
// if we got the frame body,which means we get a complete frame.
//we take this frame pts as the first apts.
//this can fix the seek discontinue,we got a fake frame,which maybe cached before the seek
- if (p_hwsync->first_apts_flag == false) {
- p_hwsync->first_apts_flag = true;
- p_hwsync->first_apts = cur_pts;
- sprintf(tempbuf, "AUDIO_START:0x%llx", cur_pts & 0xffffffff);
+ if (hw_sync->first_apts_flag == false) {
+ hw_sync->first_apts_flag = true;
+ hw_sync->first_apts = cur_pts;
+ sprintf(tempbuf, "AUDIO_START:0x%"PRIx64"", cur_pts & 0xffffffff);
ALOGI("tsync -> %s,frame size %d", tempbuf, outsize);
if (sysfs_set_sysfs_str(TSYNC_EVENT, tempbuf) == -1) {
ALOGE("set AUDIO_START failed \n");
}
} else {
- long apts;
- unsigned long latency = out_get_latency(out) * 90;
+ uint64_t apts;
+ uint64_t latency = out_get_latency(stream) * 90;
// check PTS discontinue, which may happen when audio track switching
// discontinue means PTS calculated based on first_apts and frame_write_sum
// does not match the timestamp of next audio samples
if (cur_pts > latency) {
- apts = (unsigned long)cur_pts - latency;
+ apts = cur_pts - latency;
} else {
apts = 0;
}
if (0) { //abs(cur_pts -apts) > APTS_DISCONTINUE_THRESHOLD) {
- ALOGI("HW sync PTS discontinue, 0x%lx->0x%llx(from header) diff %llx,last apts %llx(from header)",
- apts, cur_pts, llabs(cur_pts - apts), p_hwsync->last_apts_from_header);
- p_hwsync->first_apts = cur_pts;
- sprintf(tempbuf, "AUDIO_TSTAMP_DISCONTINUITY:0x%llx", cur_pts);
+ ALOGI("HW sync PTS discontinue, 0x%"PRIx64"->0x%"PRIx64"(from header) diff %"PRIx64",last apts %"PRIx64"(from header)",
+ apts, cur_pts, pts_abs(cur_pts, apts), hw_sync->last_apts_from_header);
+ hw_sync->first_apts = cur_pts;
+ sprintf(tempbuf, "AUDIO_TSTAMP_DISCONTINUITY:0x%"PRIx64"", cur_pts);
if (sysfs_set_sysfs_str(TSYNC_EVENT, tempbuf) == -1) {
ALOGE("unable to open file %s,err: %s", TSYNC_EVENT, strerror(errno));
}
} else {
- long pcr = 0;
+ int pcr = 0;
if (get_sysfs_int16(TSYNC_PCRSCR, &pcr) == 0) {
uint32_t apts_cal = apts & 0xffffffff;
- if (abs(pcr - apts) < SYSTIME_CORRECTION_THRESHOLD) {
+ if (pts_abs(pcr, apts) < SYSTIME_CORRECTION_THRESHOLD) {
// do nothing
}
// limit the gap handle to 0.5~5 s.
@@ -2238,12 +2154,12 @@ static ssize_t out_write_direct(struct audio_stream_out *stream, const void* buf
int insert_size = 0;
int once_write_size = 0;
if (out->codec_type == TYPE_EAC3) {
- insert_size = abs(apts - pcr) / 90 * 48 * 4 * 4;
+ insert_size = pts_abs(apts, pcr) / 90 * 48 * 4 * 4;
} else {
- insert_size = abs(apts - pcr) / 90 * 48 * 4;
+ insert_size = pts_abs(apts, pcr) / 90 * 48 * 4;
}
insert_size = insert_size & (~63);
- ALOGI("audio gap %d ms ,need insert data %d\n", abs(apts - pcr) / 90, insert_size);
+ ALOGI("audio gap %"PRIx64" ms ,need insert data %d\n", pts_abs(apts, pcr) / 90, insert_size);
char *insert_buf = (char*)malloc(8192);
if (insert_buf == NULL) {
ALOGE("malloc size failed \n");
@@ -2268,15 +2184,15 @@ static ssize_t out_write_direct(struct audio_stream_out *stream, const void* buf
else if ((pcr - apts) > APTS_DISCONTINUE_THRESHOLD_MIN && (pcr - apts) < APTS_DISCONTINUE_THRESHOLD_MAX) {
//we assume one frame duration is 32 ms for DD+(6 blocks X 1536 frames,48K sample rate)
if (out->codec_type == TYPE_EAC3 && outsize > 0) {
- ALOGI("audio slow 0x%lx,skip frame @pts 0x%llx,pcr 0x%lx,cur apts 0x%lx\n", (pcr - apts), cur_pts, pcr, apts);
+ ALOGI("audio slow 0x%"PRIx64",skip frame @pts 0x%"PRIx64",pcr 0x%x,cur apts 0x%"PRIx64"\n", (pcr - apts), cur_pts, pcr, apts);
out->frame_skip_sum += 1536;
bytes = outsize;
pthread_mutex_unlock(&adev->lock);
goto exit;
}
} else {
- sprintf(tempbuf, "0x%lx", apts);
- ALOGI("tsync -> reset pcrscr 0x%lx -> 0x%lx, %s big,diff %d ms", pcr, apts, apts > pcr ? "apts" : "pcr", abs(apts - pcr) / 90);
+ sprintf(tempbuf, "0x%"PRIx64"", apts);
+ ALOGI("tsync -> reset pcrscr 0x%d -> 0x%"PRIx64", %s big,diff %"PRIx64" ms", pcr, apts, apts > (uint64_t)pcr ? "apts" : "pcr", pts_abs(apts, pcr) / 90);
#if 0
int ret_val = sysfs_set_sysfs_str(TSYNC_APTS, tempbuf);
if (ret_val == -1) {
@@ -2290,7 +2206,7 @@ static ssize_t out_write_direct(struct audio_stream_out *stream, const void* buf
}
if (outsize > 0) {
in_frames = outsize / frame_size;
- write_buf = p_hwsync->hw_sync_body_buf;
+ write_buf = hw_sync->hw_sync_body_buf;
} else {
bytes = hwsync_cost_bytes;
pthread_mutex_unlock(&adev->lock);
@@ -2306,7 +2222,7 @@ static ssize_t out_write_direct(struct audio_stream_out *stream, const void* buf
FILE *fp1 = fopen("/data/tmp/hdmi_audio_out.pcm", "a+");
if (fp1) {
int flen = fwrite((char *)buffer, 1, out_frames * frame_size, fp1);
- LOGFUNC("flen = %d---outlen=%d ", flen, out_frames * frame_size);
+ //LOGFUNC("flen = %d---outlen=%d ", flen, out_frames * frame_size);
fclose(fp1);
} else {
LOGFUNC("could not open file:/data/hdmi_audio_out.pcm");
@@ -2314,21 +2230,21 @@ static ssize_t out_write_direct(struct audio_stream_out *stream, const void* buf
}
if (codec_type_is_raw_data(out->codec_type) && !(out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)) {
//here to do IEC61937 pack
- ALOGV("IEC61937 write size %d,hw_sync_mode %d,flag %x\n", out_frames * frame_size, adev->hw_sync_mode, out->flags);
+ ALOGV("IEC61937 write size %zu,hw_sync_mode %d,flag %x\n", out_frames * frame_size, out->hw_sync_mode, out->flags);
if (out->codec_type > 0) {
// compressed audio DD/DD+
bytes = spdifenc_write((void *) buf, out_frames * frame_size);
//need return actual size of this burst write
- if (adev->hw_sync_mode == 1) {
+ if (out->hw_sync_mode == 1) {
bytes = hwsync_cost_bytes;
}
- ALOGV("spdifenc_write return %d\n", bytes);
+ ALOGV("spdifenc_write return %zu\n", bytes);
if (out->codec_type == TYPE_EAC3) {
out->frame_write_sum = spdifenc_get_total() / 16 + out->spdif_enc_init_frame_write_sum;
} else {
out->frame_write_sum = spdifenc_get_total() / 4 + out->spdif_enc_init_frame_write_sum;
}
- ALOGV("out %p,spdifenc_get_total() / 4 %lld\n", out, spdifenc_get_total() / 16);
+ ALOGV("out %p,out->frame_write_sum %"PRId64"\n", out, out->frame_write_sum);
}
goto exit;
}
@@ -2412,7 +2328,7 @@ static ssize_t out_write_direct(struct audio_stream_out *stream, const void* buf
pcm_stop(out->pcm);
}
#endif
- ALOGV("write size %d\n", out_frames * frame_size);
+ ALOGV("write size %zu\n", out_frames * frame_size);
ret = pcm_write(out->pcm, (void *) buf, out_frames * frame_size);
if (ret == 0) {
out->frame_write_sum += out_frames;
@@ -2421,17 +2337,20 @@ static ssize_t out_write_direct(struct audio_stream_out *stream, const void* buf
}
exit:
total_frame = out->frame_write_sum + out->frame_skip_sum;
- latency_frames = out_get_latency(out) * out->config.rate / 1000;
+ latency_frames = out_get_latency_frames(stream);
+ clock_gettime(CLOCK_MONOTONIC, &out->timestamp);
if (total_frame >= latency_frames) {
out->last_frames_postion = total_frame - latency_frames;
} else {
out->last_frames_postion = total_frame;
}
+ ALOGV("\nout %p,out->last_frames_postion %"PRId64", latency = %d\n", out, out->last_frames_postion, latency_frames);
pthread_mutex_unlock(&out->lock);
if (ret != 0) {
usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
out_get_sample_rate(&stream->common));
}
+
return bytes;
}
@@ -2454,7 +2373,7 @@ static int out_get_render_position(const struct audio_stream_out *stream,
*dsp_frames = (uint32_t)(dsp_frame_int64 & 0xffffffff);
if (out->last_dsp_frame > *dsp_frames) {
ALOGI("maybe uint32_t wraparound,print something,last %u,now %u", out->last_dsp_frame, *dsp_frames);
- ALOGI("wraparound,out_get_render_position return %u,playback time %llu ms,sr %d\n", *dsp_frames,
+ ALOGI("wraparound,out_get_render_position return %u,playback time %"PRIu64" ms,sr %d\n", *dsp_frames,
out->last_frames_postion * 1000 / out->raw_61937_frame_size / out->config.rate, out->config.rate);
}
@@ -2483,17 +2402,18 @@ static int out_get_next_write_timestamp(const struct audio_stream_out *stream __
static int out_get_presentation_position(const struct audio_stream_out *stream, uint64_t *frames, struct timespec *timestamp)
{
struct aml_stream_out *out = (struct aml_stream_out *)stream;
- if (frames != NULL) {
- *frames = out->last_frames_postion;
- }
- if (timestamp != NULL) {
- clock_gettime(CLOCK_MONOTONIC, timestamp);
+ if (!frames || !timestamp) {
+ return -EINVAL;
}
+
+ *frames = out->last_frames_postion;
+ *timestamp = out->timestamp;
+
if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
- *frames = out->last_frames_postion / out->raw_61937_frame_size;
+ *frames /= out->raw_61937_frame_size;
}
- ALOGV("out_get_presentation_position %lld\n", *frames);
+ ALOGV("out_get_presentation_position out %p %"PRIu64", sec = %ld, nanosec = %ld\n", out, *frames, timestamp->tv_sec, timestamp->tv_nsec);
return 0;
}
@@ -2739,7 +2659,7 @@ static void get_capture_delay(struct aml_stream_in *in,
struct echo_reference_buffer *buffer)
{
/* read frames available in kernel driver buffer */
- size_t kernel_frames;
+ uint kernel_frames;
struct timespec tstamp;
long buf_delay;
long rsmp_delay;
@@ -2785,8 +2705,8 @@ static int32_t update_echo_reference(struct aml_stream_in *in, size_t frames)
struct echo_reference_buffer b;
b.delay_ns = 0;
- ALOGV("update_echo_reference, frames = [%d], in->ref_frames_in = [%d], "
- "b.frame_count = [%d]", frames, in->ref_frames_in, frames - in->ref_frames_in);
+ ALOGV("update_echo_reference, frames = [%zu], in->ref_frames_in = [%zu], "
+ "b.frame_count = [%zu]", frames, in->ref_frames_in, frames - in->ref_frames_in);
if (in->ref_frames_in < frames) {
if (in->ref_buf_size < frames) {
in->ref_buf_size = frames;
@@ -2802,8 +2722,8 @@ static int32_t update_echo_reference(struct aml_stream_in *in, size_t frames)
if (in->echo_reference->read(in->echo_reference, &b) == 0) {
in->ref_frames_in += b.frame_count;
- ALOGV("update_echo_reference: in->ref_frames_in:[%d], "
- "in->ref_buf_size:[%d], frames:[%d], b.frame_count:[%d]",
+ ALOGV("update_echo_reference: in->ref_frames_in:[%zu], "
+ "in->ref_buf_size:[%zu], frames:[%zu], b.frame_count:[%zu]",
in->ref_frames_in, in->ref_buf_size, frames, b.frame_count);
}
} else {
@@ -2995,7 +2915,7 @@ static ssize_t process_frames(struct aml_stream_in *in, void* buffer, ssize_t fr
in->proc_buf = (int16_t *)realloc(in->proc_buf,
in->proc_buf_size *
in->config.channels * sizeof(int16_t));
- ALOGV("process_frames(): in->proc_buf %p size extended to %d frames",
+ ALOGV("process_frames(): in->proc_buf %p size extended to %zu frames",
in->proc_buf, in->proc_buf_size);
}
frames_rd = read_frames(in,
@@ -3212,7 +3132,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
bool direct = false;
int ret;
bool hwsync_lpcm = false;
- ALOGI("**enter %s(devices=0x%04x,format=%#x, ch=0x%04x, SR=%d, flags=0x%x)", __FUNCTION__, devices,
+ ALOGI("enter %s(devices=0x%04x,format=%#x, ch=0x%04x, SR=%d, flags=0x%x)", __FUNCTION__, devices,
config->format, config->channel_mask, config->sample_rate, flags);
out = (struct aml_stream_out *)calloc(1, sizeof(struct aml_stream_out));
@@ -3220,6 +3140,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
return -ENOMEM;
}
+ out->out_device = devices;
out->flags = flags;
if (getprop_bool("ro.platform.has.tvuimode")) {
out->is_tv_platform = 1;
@@ -3244,7 +3165,11 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
out->stream.common.get_format = out_get_format_direct;
out->stream.write = out_write_direct;
out->stream.common.standby = out_standby_direct;
- //out->config = pcm_config_out_direct;
+ if (config->format == AUDIO_FORMAT_DEFAULT) {
+ config->format = AUDIO_FORMAT_AC3;
+ }
+ /* set default pcm config for direct. */
+ out->config = pcm_config_out_direct;
out->hal_channel_mask = config->channel_mask;
if (config->sample_rate == 0) {
config->sample_rate = 48000;
@@ -3255,9 +3180,9 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
digital_codec = get_codec_type(config->format);
if (digital_codec == TYPE_EAC3) {
out->raw_61937_frame_size = 4;
- out->config.period_size = pcm_config_out.period_size * 2;
+ out->config.period_size = pcm_config_out_direct.period_size * 2;
} else if (digital_codec == TYPE_TRUE_HD || digital_codec == TYPE_DTS_HD) {
- out->config.period_size = pcm_config_out.period_size * 4 * 2;
+ out->config.period_size = pcm_config_out_direct.period_size * 4 * 2;
out->raw_61937_frame_size = 16;
}
else if (digital_codec == TYPE_AC3 || digital_codec == TYPE_DTS)
@@ -3273,10 +3198,13 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
ALOGI("for raw audio output,force alsa stereo output\n");
out->config.channels = 2;
out->multich = 2;
+ out->hal_channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ //config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
}
- } else if (flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) {
- // TODO: add hwsync write here
- //out->stream.write = out_write_hwsync;
+ } else {
+ // TODO: add other cases here
+ ALOGE("DO not support yet!!");
+ return -EINVAL;
}
out->stream.common.get_sample_rate = out_get_sample_rate;
@@ -3303,7 +3231,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
out->standby = true;
out->frame_write_sum = 0;
out->hw_sync_mode = false;
- out->first_apts_flag = false;
+ out->hwsync.first_apts_flag = false;
//out->hal_rate = out->config.rate;
if (0/*flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC*/) {
out->hw_sync_mode = true;
@@ -3441,6 +3369,9 @@ static char * adev_get_parameters(const struct audio_hw_device *dev __unused,
ALOGI("get hwsync id\n");
return strdup("hw_av_sync=12345678");
}
+ if (!strcmp(keys, AUDIO_PARAMETER_HW_AV_EAC3_SYNC)) {
+ return strdup("true");
+ }
return strdup("");
}
diff --git a/audio_hw.h b/audio_hw.h
index 83d3080..eb7bf8e 100644
--- a/audio_hw.h
+++ b/audio_hw.h
@@ -56,7 +56,7 @@ struct aml_hal_mixer {
};
#define MAX_STREAM_NUM 5
-
+#define HDMI_ARC_MAX_FORMAT 20
struct aml_audio_device {
struct audio_hw_device hw_device;
@@ -77,8 +77,7 @@ struct aml_audio_device {
struct aml_stream_out *hwsync_output;
struct aml_hal_mixer hal_mixer;
struct pcm *pcm;
- bool hw_sync_mode;
- audio_hwsync_t hwsync;
+ unsigned hdmi_arc_ad[HDMI_ARC_MAX_FORMAT];
};
struct aml_stream_out {
@@ -94,6 +93,7 @@ struct aml_stream_out {
/* samplerate exposed to AudioFlinger. */
unsigned int hal_rate;
audio_output_flags_t flags;
+ audio_devices_t out_device;
struct pcm *pcm;
struct resampler_itfe *resampler;
char *buffer;
@@ -108,15 +108,8 @@ struct aml_stream_out {
uint64_t frame_write_sum;
uint64_t frame_skip_sum;
uint64_t last_frames_postion;
- uint8_t hw_sync_header[16];
- int hw_sync_header_cnt;
- int hw_sync_state;
- int hw_sync_body_cnt;
uint64_t spdif_enc_init_frame_write_sum;
- uint64_t bytes_write_total;
int skip_frame;
- uint8_t body_align[64];
- uint8_t body_align_cnt;
int32_t *tmp_buffer_8ch;
int is_tv_platform;
void *audioeffect_tmp_buffer;
@@ -124,9 +117,6 @@ struct aml_stream_out {
int has_EQ_lib;
unsigned char pause_status;
bool hw_sync_mode;
- bool first_apts_flag;//flag to indicate set first apts
- uint64_t first_apts;
- int64_t last_apts_from_header;
int has_aml_IIR_lib;
float volume_l;
float volume_r;
@@ -135,6 +125,8 @@ struct aml_stream_out {
//we need divide more when we got 61937 audio package
int raw_61937_frame_size;//61937 frame size
unsigned last_dsp_frame;//recorded for wraparound print info
+ audio_hwsync_t hwsync;
+ struct timespec timestamp;
};
#define MAX_PREPROCESSORS 3 /* maximum one AGC + one NS + one AEC per input stream */
diff --git a/audio_hw_profile.c b/audio_hw_profile.c
index 0b30d3c..548435d 100644
--- a/audio_hw_profile.c
+++ b/audio_hw_profile.c
@@ -1,3 +1,4 @@
+#define LOG_TAG "audio_hw_profile"
#include <errno.h>
#include <pthread.h>
#include <stdint.h>
@@ -15,8 +16,6 @@
#include "audio_hw_utils.h"
-#define LOG_TAG "audio_hw_hdmi"
-
/*
type : 0 -> playback, 1 -> capture
*/
@@ -158,45 +157,45 @@ char* get_hdmi_sink_cap(const char *keys)
int nread = read(fd, infobuf, 1024);
/* check the format cap */
if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
- size += sprintf(aud_cap, "=%s|", "AUDIO_FORMAT_PCM_16_BIT");
+ size += sprintf(aud_cap, "sup_formats=%s", "AUDIO_FORMAT_PCM_16_BIT");
if (mystrstr(infobuf, "Dobly_Digital+")) {
- size += sprintf(aud_cap + size, "%s|", "AUDIO_FORMAT_E_AC3");
+ size += sprintf(aud_cap + size, "|%s", "AUDIO_FORMAT_E_AC3");
}
if (mystrstr(infobuf, "AC-3")) {
- size += sprintf(aud_cap + size, "%s|", "AUDIO_FORMAT_AC3");
+ size += sprintf(aud_cap + size, "|%s", "AUDIO_FORMAT_AC3");
}
if (mystrstr(infobuf, "DTS-HD")) {
- size += sprintf(aud_cap + size, "%s|", "AUDIO_FORMAT_DTS|AUDIO_FORMAT_DTSHD");
+ size += sprintf(aud_cap + size, "|%s", "AUDIO_FORMAT_DTS|AUDIO_FORMAT_DTSHD");
} else if (mystrstr(infobuf, "DTS")) {
- size += sprintf(aud_cap + size, "%s|", "AUDIO_FORMAT_DTS");
+ size += sprintf(aud_cap + size, "|%s", "AUDIO_FORMAT_DTS");
}
if (mystrstr(infobuf, "MAT")) {
- size += sprintf(aud_cap + size, "%s|", "AUDIO_FORMAT_TRUEHD");
+ size += sprintf(aud_cap + size, "|%s", "AUDIO_FORMAT_TRUEHD");
}
}
/*check the channel cap */
else if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
/* take the 2ch suppported as default */
- size += sprintf(aud_cap, "=%s|", "AUDIO_CHANNEL_OUT_STEREO");
+ size += sprintf(aud_cap, "sup_channels=%s", "AUDIO_CHANNEL_OUT_STEREO");
if (mystrstr(infobuf, "PCM, 8 ch")) {
- size += sprintf(aud_cap + size, "%s|", "AUDIO_CHANNEL_OUT_5POINT1|AUDIO_CHANNEL_OUT_7POINT1");
+ size += sprintf(aud_cap + size, "|%s", "AUDIO_CHANNEL_OUT_5POINT1|AUDIO_CHANNEL_OUT_7POINT1");
} else if (mystrstr(infobuf, "PCM, 6 ch")) {
- size += sprintf(aud_cap + size, "%s|", "AUDIO_CHANNEL_OUT_5POINT1");
+ size += sprintf(aud_cap + size, "|%s", "AUDIO_CHANNEL_OUT_5POINT1");
}
} else if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
/* take the 32/44.1/48 khz suppported as default */
- size += sprintf(aud_cap, "=%s|", "32000|44100|48000");
+ size += sprintf(aud_cap, "sup_sampling_rates=%s", "32000|44100|48000");
if (mystrstr(infobuf, "88.2")) {
- size += sprintf(aud_cap + size, "%s|", "88200");
+ size += sprintf(aud_cap + size, "|%s", "88200");
}
if (mystrstr(infobuf, "96")) {
- size += sprintf(aud_cap + size, "%s|", "96000");
+ size += sprintf(aud_cap + size, "|%s", "96000");
}
if (mystrstr(infobuf, "176.4")) {
- size += sprintf(aud_cap + size, "%s|", "176400");
+ size += sprintf(aud_cap + size, "|%s", "176400");
}
if (mystrstr(infobuf, "192")) {
- size += sprintf(aud_cap + size, "%s|", "192000");
+ size += sprintf(aud_cap + size, "|%s", "192000");
}
}
}
diff --git a/audio_hwsync.c b/audio_hwsync.c
index 12f4972..1116fab 100644
--- a/audio_hwsync.c
+++ b/audio_hwsync.c
@@ -2,6 +2,7 @@
#include <errno.h>
#include <pthread.h>
#include <stdint.h>
+#include <inttypes.h>
#include <sys/time.h>
#include <stdlib.h>
#include <sys/stat.h>
@@ -21,12 +22,12 @@
#include "audio_hwsync.h"
#include "audio_hw_utils.h"
#include "audio_hw.h"
-//#include "hdmi_audio_hw.h"
+
static uint32_t aml_hwsync_out_get_latency(const struct audio_stream_out *stream)
{
struct aml_stream_out *out = (struct aml_stream_out *)stream;
uint32_t whole_latency;
- uint32_t ret;
+ int ret;
snd_pcm_sframes_t frames = 0;
whole_latency = (out->config.period_size * out->config.period_count * 1000) / out->config.rate;
if (!out->pcm || !pcm_is_ready(out->pcm)) {
@@ -44,8 +45,7 @@ static uint32_t aml_hwsync_out_get_latency(const struct audio_stream_out *stream
void aml_audio_hwsync_clear_status(struct aml_stream_out *out)
{
- struct aml_audio_device *adev = out->dev;
- audio_hwsync_t *p_hwsync = &adev->hwsync;
+ audio_hwsync_t *p_hwsync = &out->hwsync;
p_hwsync->first_apts_flag = 0;
p_hwsync->hw_sync_state = HW_SYNC_STATE_HEADER;
p_hwsync->hw_sync_header_cnt = 0;
@@ -54,11 +54,10 @@ void aml_audio_hwsync_clear_status(struct aml_stream_out *out)
//return bytes cost from input,
int aml_audio_hwsync_find_frame(struct aml_stream_out *out, const void *in_buffer, size_t in_bytes, uint64_t *cur_pts, int *outsize)
{
- int remain = in_bytes;
- uint8_t *p = in_buffer;
- struct aml_audio_device *adev = out->dev;
- audio_hwsync_t *p_hwsync = &adev->hwsync;
- int time_diff = 0;
+ size_t remain = in_bytes;
+ uint8_t *p = (uint8_t *)in_buffer;
+ audio_hwsync_t *p_hwsync = &out->hwsync;
+ uint64_t time_diff = 0;
//ALOGI(" --- out_write %d, cache cnt = %d, body = %d, hw_sync_state = %d", out_frames * frame_size, out->body_align_cnt, out->hw_sync_body_cnt, out->hw_sync_state);
while (remain > 0) {
//if (p_hwsync->hw_sync_state == HW_SYNC_STATE_RESYNC) {
@@ -76,8 +75,8 @@ int aml_audio_hwsync_find_frame(struct aml_stream_out *out, const void *in_buff
p_hwsync->hw_sync_header_cnt--;
continue;
}
- if ((in_bytes-remain) > 16)
- ALOGI("got the frame sync header cost %d\n",in_bytes-remain);
+ if ((in_bytes-remain) > 16)
+ ALOGI("got the frame sync header cost %zu",in_bytes-remain);
p_hwsync->hw_sync_state = HW_SYNC_STATE_BODY;
p_hwsync->hw_sync_body_cnt = hwsync_header_get_size(&p_hwsync->hw_sync_header[0]);
p_hwsync->hw_sync_frame_size = p_hwsync->hw_sync_body_cnt;
@@ -86,12 +85,12 @@ int aml_audio_hwsync_find_frame(struct aml_stream_out *out, const void *in_buff
//memcpy(write_buf+write_pos,&p_hwsync->hw_sync_header[0],16);
//write_pos += 16;
pts = pts * 90 / 1000000;
- time_diff = (abs(pts - p_hwsync->last_apts_from_header)) / 90;
- ALOGV("pts %llx,frame len %d\n", pts, p_hwsync->hw_sync_body_cnt);
- ALOGV("last pts %llx,diff %d ms\n", p_hwsync->last_apts_from_header, time_diff);
+ time_diff = pts_abs(pts, p_hwsync->last_apts_from_header) / 90;
+ ALOGV("pts %"PRIx64",frame len %zu\n", pts, p_hwsync->hw_sync_body_cnt);
+ ALOGV("last pts %"PRIx64",diff %"PRIx64" ms\n", p_hwsync->last_apts_from_header, time_diff);
if (time_diff > 32) {
- ALOGI("pts time gap %d ms,last %llx,cur %llx\n", time_diff,
+ ALOGI("pts time gap %"PRIx64" ms,last %"PRIx64",cur %"PRIx64"\n", time_diff,
p_hwsync->last_apts_from_header, pts);
}
p_hwsync->last_apts_from_header = pts;
diff --git a/audio_hwsync.h b/audio_hwsync.h
index 491ab7e..99bf8ae 100644
--- a/audio_hwsync.h
+++ b/audio_hwsync.h
@@ -16,9 +16,9 @@
typedef struct audio_hwsync {
uint8_t hw_sync_header[16];
- int hw_sync_header_cnt;
+ size_t hw_sync_header_cnt;
int hw_sync_state;
- int hw_sync_body_cnt;
+ size_t hw_sync_body_cnt;
int hw_sync_frame_size;
uint8_t hw_sync_body_buf[4096];
uint8_t body_align[64];
@@ -55,4 +55,17 @@ static inline uint32_t hwsync_header_get_size(uint8_t *header)
((uint32_t)header[7]);
}
+static inline uint64_t pts_abs(uint64_t a, uint64_t b)
+{
+ if (a >= b)
+ return (a - b);
+ else
+ return (b - a);
+}
+
+struct aml_stream_out;
+
+void aml_audio_hwsync_clear_status(struct aml_stream_out *out);
+int aml_audio_hwsync_find_frame(struct aml_stream_out *out,
+ const void *in_buffer, size_t in_bytes, uint64_t *cur_pts, int *outsize);
#endif
diff --git a/spdifenc_wrap.cpp b/spdifenc_wrap.cpp
index 9eb9a8a..94878e0 100644
--- a/spdifenc_wrap.cpp
+++ b/spdifenc_wrap.cpp
@@ -11,22 +11,7 @@ extern "C"
{
#include "audio_hw_utils.h"
}
-#if 0
-static int
-getprop_bool(const char *path)
-{
- char buf[PROPERTY_VALUE_MAX];
- int ret = -1;
- ret = property_get(path, buf, NULL);
- if (ret > 0) {
- if (strcasecmp(buf, "true") == 0 || strcmp(buf, "1") == 0) {
- return 1;
- }
- }
- return 0;
-}
-#endif
-extern "C" int getprop_boll(const char *path);
+
namespace android
{
class MySPDIFEncoder : public SPDIFEncoder
@@ -38,7 +23,8 @@ public:
{};
virtual ssize_t writeOutput(const void* buffer, size_t bytes)
{
- ALOGV("write size %d \n", bytes);
+ int ret = -1;
+ ALOGV("write size %zu \n", bytes);
#if 1
if (getprop_bool("media.spdif.outdump")) {
FILE *fp1 = fopen("/data/tmp/hdmi_audio_out.spdif", "a+");
@@ -52,7 +38,11 @@ public:
}
#endif
mTotalBytes += bytes;
- return pcm_write(pcm_handle, buffer, bytes);
+ ret = pcm_write(pcm_handle, buffer, bytes);
+ if (ret)
+ return ret;
+
+ return bytes;
}
virtual uint64_t total_bytes()
{