/* * 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; }