Files
TAIXIN/sdk/lib/video/miniMP4/adts.c

148 lines
6.1 KiB
C
Raw Permalink Normal View History

/**
* @file adts.c
* @brief
* @author licaibiao
* @version 1.0
* @date 2023-12-06
*
* @copyright Copyright (c) 2023-2030 liwen01 Technology Co., Ltd
*
*/
#include "adts.h"
#include <math.h>
void set_fixed_header(adts_fixed_header *header) {
header->syncword = 0xFF;// 代表着一个帧的开始
header->id = 1;// MPEG Version: 0 for MPEG-4, 1 for MPEG-2
header->layer = 0;// always 00
header->protection_absent = 1;// 表示是否误码校验
header->profile = 1;// 表示使用哪个级别的AAC, 有些芯片只支持AAC LC.
header->sampling_frequency_index = 0xb;// 表示使用的采样率的下标
header->private_bit = 0;
header->channel_configuration = 1;// 表示声道数
header->original_copy = 0;
header->home = 0;
}
void set_variable_header(adts_variable_header *header, const int aac_raw_data_length) {
header->copyright_identification_bit = 0;
header->copyright_identification_start = 0;
header->aac_frame_length = aac_raw_data_length + 7;
header->adts_buffer_fullness = 0x7f;
header->number_of_raw_data_blocks_in_frame = 0;
}
void get_fixed_header(const unsigned char buff[7], adts_fixed_header *header) {
unsigned long long adts = 0;
const unsigned char *p = buff;
adts |= *p ++; adts <<= 8;
adts |= *p ++; adts <<= 8;
adts |= *p ++; adts <<= 8;
adts |= *p ++; adts <<= 8;
adts |= *p ++; adts <<= 8;
adts |= *p ++; adts <<= 8;
adts |= *p ++;
header->syncword = (adts >> 44);
header->id = (adts >> 43) & 0x01;
header->layer = (adts >> 41) & 0x03;
header->protection_absent = (adts >> 40) & 0x01;
header->profile = (adts >> 38) & 0x03;
header->sampling_frequency_index = (adts >> 34) & 0x0f;
header->private_bit = (adts >> 33) & 0x01;
header->channel_configuration = (adts >> 30) & 0x07;
header->original_copy = (adts >> 29) & 0x01;
header->home = (adts >> 28) & 0x01;
}
void get_variable_header(const unsigned char buff[7], adts_variable_header *header) {
unsigned long long adts = 0;
adts = buff[0]; adts <<= 8;
adts |= buff[1]; adts <<= 8;
adts |= buff[2]; adts <<= 8;
adts |= buff[3]; adts <<= 8;
adts |= buff[4]; adts <<= 8;
adts |= buff[5]; adts <<= 8;
adts |= buff[6];
header->copyright_identification_bit = (adts >> 27) & 0x01;
header->copyright_identification_start = (adts >> 26) & 0x01;
header->aac_frame_length = (adts >> 13) & ((int)pow(2, 14) - 1);
header->adts_buffer_fullness = (adts >> 2) & ((int)pow(2, 11) - 1);
header->number_of_raw_data_blocks_in_frame = adts & 0x03;
}
void convert_adts_header2int64(const adts_fixed_header *fixed_header, const adts_variable_header *variable_header, uint64_t *header) {
uint64_t ret_value = 0;
ret_value = ((fixed_header->syncword<<4) | 0x0F);
ret_value <<= 1;
ret_value |= fixed_header->id;
ret_value <<= 2;
ret_value |= fixed_header->layer;
ret_value <<= 1;
ret_value |= (fixed_header->protection_absent) & 0x01;
ret_value <<= 2;
ret_value |= fixed_header->profile;
ret_value <<= 4;
ret_value |= (fixed_header->sampling_frequency_index) & 0x0f;
ret_value <<= 1;
ret_value |= (fixed_header->private_bit) & 0x01;
ret_value <<= 3;
ret_value |= (fixed_header->channel_configuration) & 0x07;
ret_value <<= 1;
ret_value |= (fixed_header->original_copy) & 0x01;
ret_value <<= 1;
ret_value |= (fixed_header->home) & 0x01;
ret_value <<= 1;
ret_value |= (variable_header->copyright_identification_bit) & 0x01;
ret_value <<= 1;
ret_value |= (variable_header->copyright_identification_start) & 0x01;
ret_value <<= 13;
ret_value |= (variable_header->aac_frame_length) & ((int)pow(2, 13) - 1);
ret_value <<= 11;
ret_value |= ((variable_header->adts_buffer_fullness<<4) | 0x0F ) & ((int)pow(2, 11) - 1);
ret_value <<= 2;
ret_value |= (variable_header->number_of_raw_data_blocks_in_frame) & ((int)pow(2, 2) - 1);
*header = ret_value;
}
void convert_adts_header2char(const adts_fixed_header *fixed_header, const adts_variable_header *variable_header, unsigned char buffer[7]) {
uint64_t value = 0;
convert_adts_header2int64(fixed_header, variable_header, &value);
buffer[0] = (value >> 48) & 0xff;
buffer[1] = (value >> 40) & 0xff;
buffer[2] = (value >> 32) & 0xff;
buffer[3] = (value >> 24) & 0xff;
buffer[4] = (value >> 16) & 0xff;
buffer[5] = (value >> 8) & 0xff;
buffer[6] = (value) & 0xff;
}
void aac_dsi_to_adts(uint8_t *dsi, uint8_t *adts, uint32_t aac_data_length)
{
uint8_t audio_object_type = (dsi[0] >> 3) & 0x1F;
uint8_t profile = audio_object_type - 1;
uint8_t samplerate_index = ((dsi[0] & 0x07) << 1) | (dsi[1] >> 7);
uint8_t channels = (dsi[1] >> 3) & 0x0F;
;uint32_t frame_length = aac_data_length + 7;
adts[0] = 0xFF; //syncword hight 8 bits
adts[1] = 0xF0; //syncword low 4 bits
adts[1] |= (0x01 << 3); //ID 0:MPEG-4,1:MPEG-2
adts[1] |= (0x00 << 1); //layer:00
adts[1] |= (0x01 & 0x1); //1:no CRC,0:is CRC
adts[2] = (profile << 6); //profile 0x01:AAC-LC
adts[2] |= (samplerate_index << 2);
adts[2] |= (0x00 << 1); //private_bit (0)
adts[2] |= (channels & 0x4) >> 2;
adts[3] = (channels & 0x3) << 6;
adts[3] |= (frame_length >> 11); //frame_length bits12-bits13
adts[4] = (frame_length >> 3) & 0xFF; //frame_length bits4-bits11
adts[5] = (frame_length & 0x07) << 5; //frame_length low 3 bits first
adts[5] |= (0x7FF >> 6) & 0x1F; //adts_buffer_fullness high 5 bits
adts[6] = (0x7FF & 0x3F) << 2; //adts_buffer_fullness low 6 bits
adts[6] |= (0x00); //number_of_raw_data_blocks_in_frame (0)
}