From ca583fc6890fb63bb0c5364cbf9cc3cfb3cb613d Mon Sep 17 00:00:00 2001 From: HarlanC Date: Mon, 22 Jan 2024 19:26:10 +0800 Subject: [PATCH] aac asc generate --- library/container/flv/src/demuxer_tag.rs | 195 ------------------ library/container/flv/src/mpeg4_aac.rs | 60 +++--- .../streamhub/src/statistics/avstatistics.rs | 2 +- 3 files changed, 27 insertions(+), 230 deletions(-) delete mode 100644 library/container/flv/src/demuxer_tag.rs diff --git a/library/container/flv/src/demuxer_tag.rs b/library/container/flv/src/demuxer_tag.rs deleted file mode 100644 index ed2ffb11..00000000 --- a/library/container/flv/src/demuxer_tag.rs +++ /dev/null @@ -1,195 +0,0 @@ -use { - super::{define, errors::FlvDemuxerError}, - bytes::BytesMut, - bytesio::bytes_reader::BytesReader, -}; - -#[derive(Clone, Debug)] -pub struct AudioTagHeader { - /* - SoundFormat: UB[4] - 0 = Linear PCM, platform endian - 1 = ADPCM - 2 = MP3 - 3 = Linear PCM, little endian - 4 = Nellymoser 16-kHz mono - 5 = Nellymoser 8-kHz mono - 6 = Nellymoser - 7 = G.711 A-law logarithmic PCM - 8 = G.711 mu-law logarithmic PCM - 9 = reserved - 10 = AAC - 11 = Speex - 14 = MP3 8-Khz - 15 = Device-specific sound - Formats 7, 8, 14, and 15 are reserved for internal use - AAC is supported in Flash Player 9,0,115,0 and higher. - Speex is supported in Flash Player 10 and higher. - */ - pub sound_format: u8, - /* - SoundRate: UB[2] - Sampling rate - 0 = 5.5-kHz For AAC: always 3 - 1 = 11-kHz - 2 = 22-kHz - 3 = 44-kHz - */ - pub sound_rate: u8, - /* - SoundSize: UB[1] - 0 = snd8Bit - 1 = snd16Bit - Size of each sample. - This parameter only pertains to uncompressed formats. - Compressed formats always decode to 16 bits internally - */ - pub sound_size: u8, - /* - SoundType: UB[1] - 0 = sndMono - 1 = sndStereo - Mono or stereo sound For Nellymoser: always 0 - For AAC: always 1 - */ - pub sound_type: u8, - - /* - 0: AAC sequence header - 1: AAC raw - */ - pub aac_packet_type: u8, -} - -impl AudioTagHeader { - pub fn defalut() -> Self { - AudioTagHeader { - sound_format: 0, - sound_rate: 0, - sound_size: 0, - sound_type: 0, - aac_packet_type: 0, - } - } -} - -pub struct AudioTagHeaderDemuxer { - bytes_reader: BytesReader, - tag: AudioTagHeader, -} - -impl AudioTagHeaderDemuxer { - pub fn new(data: BytesMut) -> Self { - Self { - bytes_reader: BytesReader::new(data), - tag: AudioTagHeader::defalut(), - } - } - - pub fn parse_tag_header(&mut self) -> Result { - let flags = self.bytes_reader.read_u8()?; - - self.tag.sound_format = flags >> 4; - self.tag.sound_rate = (flags >> 2) & 0x03; - self.tag.sound_size = (flags >> 1) & 0x01; - self.tag.sound_type = flags & 0x01; - - if self.tag.sound_format == define::SoundFormat::AAC as u8 { - self.tag.aac_packet_type = self.bytes_reader.read_u8()?; - } - - Ok(self.tag.clone()) - } - - pub fn get_remaining_bytes(&mut self) -> BytesMut { - self.bytes_reader.extract_remaining_bytes() - } -} -#[derive(Clone)] -pub struct VideoTagHeader { - /* - 1: keyframe (for AVC, a seekable frame) - 2: inter frame (for AVC, a non- seekable frame) - 3: disposable inter frame (H.263 only) - 4: generated keyframe (reserved for server use only) - 5: video info/command frame - */ - pub frame_type: u8, - /* - 1: JPEG (currently unused) - 2: Sorenson H.263 - 3: Screen video - 4: On2 VP6 - 5: On2 VP6 with alpha channel - 6: Screen video version 2 - 7: AVC - 12: HEVC - */ - pub codec_id: u8, - /* - 0: AVC sequence header - 1: AVC NALU - 2: AVC end of sequence (lower level NALU sequence ender is not required or supported) - */ - pub avc_packet_type: u8, - pub composition_time: i32, -} - -impl VideoTagHeader { - pub fn defalut() -> Self { - VideoTagHeader { - frame_type: 0, - codec_id: 0, - avc_packet_type: 0, - composition_time: 0, - } - } -} - -pub struct VideoTagHeaderDemuxer { - bytes_reader: BytesReader, - tag: VideoTagHeader, -} - -impl VideoTagHeaderDemuxer { - pub fn new(data: BytesMut) -> Self { - Self { - bytes_reader: BytesReader::new(data), - tag: VideoTagHeader::defalut(), - } - } - - pub fn parse_tag_header(&mut self) -> Result { - let flags = self.bytes_reader.read_u8()?; - - self.tag.frame_type = flags >> 4; - self.tag.codec_id = flags & 0x0f; - - if self.tag.codec_id == define::AvcCodecId::H264 as u8 - || self.tag.codec_id == define::AvcCodecId::HEVC as u8 - { - self.tag.avc_packet_type = self.bytes_reader.read_u8()?; - self.tag.composition_time = 0; - - //bigend 3bytes - for _ in 0..3 { - let time = self.bytes_reader.read_u8()?; - //print!("==time0=={}\n", time); - //print!("==time1=={}\n", self.tag.composition_time); - self.tag.composition_time = (self.tag.composition_time << 8) + time as i32; - } - //transfer to signed i24 - if self.tag.composition_time & (1 << 23) != 0 { - let sign_extend_mask = 0xff_ff << 23; - // Sign extend the value - self.tag.composition_time = (self.tag.composition_time | sign_extend_mask) as i32 - } - } - - Ok(self.tag.clone()) - } - - pub fn get_remaining_bytes(&mut self) -> BytesMut { - self.bytes_reader.extract_remaining_bytes() - } -} diff --git a/library/container/flv/src/mpeg4_aac.rs b/library/container/flv/src/mpeg4_aac.rs index 4bb88d56..1c630a0e 100644 --- a/library/container/flv/src/mpeg4_aac.rs +++ b/library/container/flv/src/mpeg4_aac.rs @@ -12,9 +12,9 @@ const AAC_FREQUENCE: [u32; AAC_FREQUENCE_SIZE] = [ 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350, ]; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub struct Mpeg4Aac { - pub profile: u8, + pub object_type: u8, pub sampling_frequency_index: u8, pub channel_configuration: u8, @@ -26,26 +26,18 @@ pub struct Mpeg4Aac { pub npce: usize, } -impl Default for Mpeg4Aac { - fn default() -> Self { - Self::new() - } -} - impl Mpeg4Aac { - pub fn new() -> Self { - Self { - profile: 0, - sampling_frequency_index: 0, - channel_configuration: 0, - sampling_frequency: 0, - channels: 0, - sbr: 0, - ps: 0, - - pce: BytesMut::new(), - npce: 0, - } + // 11 90 + // 00010 0011 0010 000 + // 2 3 2 + //https://wiki.multimedia.cx/index.php?title=MPEG-4_Audio#Audio_Specific_Config + pub fn gen_audio_specific_config(&self) -> Result { + let mut writer = BytesWriter::default(); + writer.write_u8(self.object_type << 3 | (self.sampling_frequency_index >> 1))?; + writer.write_u8( + (self.sampling_frequency_index & 0x01) << 7 | (self.channel_configuration << 3), + )?; + Ok(writer.extract_current_bytes()) } } @@ -68,7 +60,7 @@ impl Mpeg4AacProcessor { bytes_reader: BytesReader::new(BytesMut::new()), bytes_writer: BytesWriter::new(), bits_reader: BitsReader::new(BytesReader::new(BytesMut::new())), - mpeg4_aac: Mpeg4Aac::new(), + mpeg4_aac: Mpeg4Aac::default(), } } @@ -78,9 +70,9 @@ impl Mpeg4AacProcessor { } pub fn audio_specific_config_load(&mut self) -> Result<&mut Self, MpegAacError> { - //11 88 56 E5 + //11 88 56 E5 let byte_0 = self.bytes_reader.read_u8()?; - self.mpeg4_aac.profile = (byte_0 >> 3) & 0x1F; + self.mpeg4_aac.object_type = (byte_0 >> 3) & 0x1F; let byte_1 = self.bytes_reader.read_u8()?; self.mpeg4_aac.sampling_frequency_index = ((byte_0 & 0x07) << 1) | ((byte_1 >> 7) & 0x01); @@ -108,7 +100,7 @@ impl Mpeg4AacProcessor { // self.bits_reader.extend_from_bytesmut(remain_bytes); self.bits_reader.extend_data(remain_bytes); - self.mpeg4_aac.profile = self.get_audio_object_type()?; + self.mpeg4_aac.object_type = self.get_audio_object_type()?; self.mpeg4_aac.sampling_frequency_index = self.get_sampling_frequency()?; self.mpeg4_aac.channel_configuration = self.bits_reader.read_n_bits(4)? as u8; @@ -116,17 +108,17 @@ impl Mpeg4AacProcessor { let mut extension_sampling_frequency_index: u8 = 0; let mut extension_channel_configuration: u8 = 0; - if self.mpeg4_aac.profile == 5 || self.mpeg4_aac.profile == 29 { + if self.mpeg4_aac.object_type == 5 || self.mpeg4_aac.object_type == 29 { extension_audio_object_type = 5; self.mpeg4_aac.sbr = 1; { - if self.mpeg4_aac.profile == 29 { + if self.mpeg4_aac.object_type == 29 { self.mpeg4_aac.ps = 1; } extension_sampling_frequency_index = self.get_sampling_frequency()?; - self.mpeg4_aac.profile = self.get_audio_object_type()?; + self.mpeg4_aac.object_type = self.get_audio_object_type()?; - if self.mpeg4_aac.profile == 22 { + if self.mpeg4_aac.object_type == 22 { extension_channel_configuration = self.bits_reader.read_n_bits(4)? as u8; } } @@ -136,7 +128,7 @@ impl Mpeg4AacProcessor { let ep_config: u64; - match self.mpeg4_aac.profile { + match self.mpeg4_aac.object_type { 1 | 2 | 3 | 4 | 5 | 6 | 7 | 17 | 19 | 20 | 21 | 22 | 23 => { self.ga_specific_config_load()?; } @@ -146,7 +138,7 @@ impl Mpeg4AacProcessor { _ => {} } - match self.mpeg4_aac.profile { + match self.mpeg4_aac.object_type { 17 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 39 => { ep_config = self.bits_reader.read_n_bits(2)?; @@ -251,12 +243,12 @@ impl Mpeg4AacProcessor { self.pce_load()?; } - if self.mpeg4_aac.profile == 6 || self.mpeg4_aac.profile == 20 { + if self.mpeg4_aac.object_type == 6 || self.mpeg4_aac.object_type == 20 { self.bits_reader.read_n_bits(3)?; } if extension_flag > 0 { - match self.mpeg4_aac.profile { + match self.mpeg4_aac.object_type { 22 => { self.bits_reader.read_n_bits(5)?; self.bits_reader.read_n_bits(11)?; @@ -410,7 +402,7 @@ impl Mpeg4AacProcessor { 0xF0 /* 12-syncword */ | (id << 3)/*1-ID*/| 0x01, /*1-protection_absent*/ )?; //1 - let profile = self.mpeg4_aac.profile; + let profile = self.mpeg4_aac.object_type; let sampling_frequency_index = self.mpeg4_aac.sampling_frequency_index; let channel_configuration = self.mpeg4_aac.channel_configuration; self.bytes_writer.write_u8( diff --git a/library/streamhub/src/statistics/avstatistics.rs b/library/streamhub/src/statistics/avstatistics.rs index e8ed7917..ba67e676 100644 --- a/library/streamhub/src/statistics/avstatistics.rs +++ b/library/streamhub/src/statistics/avstatistics.rs @@ -47,7 +47,7 @@ impl AvStatistics { pub async fn notify_audio_codec_info(&mut self, codec_info: &Mpeg4Aac) { let audio_info = &mut self.stream_statistics.lock().await.audio; - audio_info.profile = define::u8_2_aac_profile(codec_info.profile); + audio_info.profile = define::u8_2_aac_profile(codec_info.object_type); audio_info.samplerate = codec_info.sampling_frequency; audio_info.sound_format = SoundFormat::AAC; audio_info.channels = codec_info.channels;