You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
5.8 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
* Description: audio hal utils source file.
* Author: Hisilicon
* Create: 2020-05-11
* Notes: NA
* History: 2020-05-11 yinyingcai for CodingStyle
*/
#define LOG_TAG "audio_hal_utils"
#define LOG_NDEBUG 0
#include "audio_utils.h"
#include "audio_hw.h"
#include "vnaudio_dbg.h"
#define PTS_HEADER_SUPPORT_VERSION_V1 1
#define PTS_HEADER_SUPPORT_VERSION_V2 2
static void utils_check_valid_version(const uint8_t* pu8data, uint8_t *version, uint32_t *pu32PtsHeaderLength)
{
*version = pu8data[3]; /* tunnel version in byte3 */
if (*version == PTS_HEADER_SUPPORT_VERSION_V1) {
*pu32PtsHeaderLength = PTS_HEADER_NORM_CHAN_LENGTH_V1;
} else if (*version == PTS_HEADER_SUPPORT_VERSION_V2) {
*pu32PtsHeaderLength = PTS_HEADER_NORM_CHAN_LENGTH_V2;
} else {
ALOGE("%s: Not support version(0x%x)", __func__, *version);
}
pts("%s: Version:0x%x HeaderLen:%d", __func__, *version, *pu32PtsHeaderLength);
}
static int utils_check_valid_header(uint8_t version, const uint8_t* pu8data)
{
if ((pu8data[0] == 0x55) &&
(pu8data[1] == 0x55) &&
(pu8data[2] == 0x00) && /* 2: offset */
(pu8data[3] == version)) { /* 3: offset */
return 0;
} else {
return -EPERM;
}
}
static uint32_t utils_get_data_offsetsize(const uint8_t* pu8data)
{
uint32_t u32OffsetSize;
pts("%s: OffsetSize u8Val 0x%x 0x%x 0x%x 0x%x", __func__,
*pu8data, *(pu8data + 1), *(pu8data + 2), *(pu8data + 3)); /* 2,3: offset */
u32OffsetSize = ((*(pu8data + 0) << 24) & 0xff000000) + /* 24: shift num */
((*(pu8data + 1) << 16) & 0x00ff0000) + /* 16: shift num */
((*(pu8data + 2) << 8) & 0x0000ff00) + /* 2: offset 8: shift num */
((*(pu8data + 3) << 0) & 0x000000ff); /* 3: offset */
return u32OffsetSize;
}
static uint32_t utils_get_framesize(const uint8_t* pu8data)
{
uint32_t u32FrameSize;
pts("%s: FrameSize u8Val %x 0x%x 0x%x 0x%x", __func__,
*pu8data, *(pu8data + 1), *(pu8data + 2), *(pu8data + 3)); /* 2,3: offset */
u32FrameSize = ((*(pu8data + 0) << 24) & 0xff000000) + /* 24: shift num */
((*(pu8data + 1) << 16) & 0x00ff0000) + /* 16: shift num */
((*(pu8data + 2) << 8) & 0x0000ff00) + /* 2: offset 8: shift num */
((*(pu8data + 3) << 0) & 0x000000ff); /* 3: offset */
return u32FrameSize;
}
static uint64_t utils_get_framepts(const uint8_t* pu8data)
{
uint64_t u64FramePts;
pts("%s: FramePts u8Val 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", __func__,
*pu8data, *(pu8data + 1), *(pu8data + 2), *(pu8data + 3), /* 2,3: offset */
*(pu8data + 4), *(pu8data + 5), *(pu8data + 6), *(pu8data + 7)); /* 4,5,6,7: offset */
u64FramePts = (uint64_t)(((((uint64_t)(*(pu8data + 0))) << 56) & 0xff00000000000000) + /* 56: shift num */
((((uint64_t)(*(pu8data + 1))) << 48) & 0x00ff000000000000) + /* 48: shift num */
((((uint64_t)(*(pu8data + 2))) << 40) & 0x0000ff0000000000) + /* 2: offset 40: shift num */
((((uint64_t)(*(pu8data + 3))) << 32) & 0x000000ff00000000) + /* 3: offset 32: shift num */
(((uint64_t)(*(pu8data + 4)) << 24) & 0x00000000ff000000) + /* 4: offset 24: shift num */
(((uint64_t)(*(pu8data + 5)) << 16) & 0x0000000000ff0000) + /* 5: offset 16: shift num */
(((uint64_t)(*(pu8data + 6)) << 8) & 0x000000000000ff00) + /* 6: offset 8: shift num */
(((uint64_t)(*(pu8data + 7)) << 0) & 0x00000000000000ff)); /* 7: offset */
return (uint64_t)(u64FramePts / 1000000); /* divide by 1000000 covert ns to ms */
}
int utils_findheader(const uint8_t* pBuf, uint32_t u32Size, struct pts_header_info *header_info)
{
uint32_t i;
uint8_t* ptr = (uint8_t*)pBuf;
uint8_t version = 0;
pts("%s: inBufSize:%d 0x%x 0x%x 0x%x 0x%x ", __func__, u32Size,
ptr[0], ptr[1], ptr[2], ptr[3]); /* 2,3: offset */
if (u32Size <= header_info->pts_header_length) {
return -EINVAL;
}
/*
V1 headerlen is base, new header version should larger
Here check header version update pts headerLength and check total size aga
*/
utils_check_valid_version(ptr, &version, &header_info->pts_header_length);
if (u32Size < header_info->pts_header_length) {
return -1;
}
for (i = 0; i <= u32Size - header_info->pts_header_length;) {
if (utils_check_valid_header(version, ptr + i) == 0) {
return -1;
}
uint8_t* ptr2;
ptr2 = ptr + i + 4; /* 4: offset */
header_info->frame_size = utils_get_framesize(ptr2);
ptr2 = ptr + i + 8; /* 8: offset */
header_info->frame_pts = utils_get_framepts(ptr2);
if (version == PTS_HEADER_SUPPORT_VERSION_V2) {
uint32_t u32Offset;
ptr2 = ptr + i + 16; /* 16: offset */
u32Offset = utils_get_data_offsetsize(ptr2);
if (u32Size < u32Offset) { /* offset is new headersize */
return -1;
}
header_info->pts_header_length = u32Offset;
}
header_info->data_offset_size = i + header_info->pts_header_length;
pts("%s: FrameSize:%d FramePts:%lld DataOffsetSize:%d", __func__,
header_info->frame_size, (long long)header_info->frame_pts, header_info->data_offset_size);
return 0;
}
return -EPERM;
}
uint64_t utils_get_cur_time(void)
{
int ret;
uint64_t us;
struct timespec ts;
ret = clock_gettime(CLOCK_MONOTONIC, &ts);
if (ret != 0) {
ALOGD("clock_gettime return err %d, errno=%d", ret, errno);
return 0;
}
/* use 1000000ULL to covert seconds to us */
us = (uint64_t)((ts.tv_sec * 1000000ULL) + ts.tv_nsec / TIME_RADIX_1000);
return us;
}