1 use crate::{ 2 flv_tag_header::{AudioTagHeader, VideoTagHeader}, 3 Unmarshal, 4 }; 5 6 use { 7 super::{ 8 define::{aac_packet_type, avc_packet_type, tag_type, AvcCodecId, FlvData, SoundFormat}, 9 errors::FlvDemuxerError, 10 mpeg4_aac::Mpeg4AacProcessor, 11 mpeg4_avc::Mpeg4AvcProcessor, 12 }, 13 byteorder::BigEndian, 14 bytes::BytesMut, 15 bytesio::bytes_reader::BytesReader, 16 }; 17 18 /* 19 ** Flv Struct ** 20 +-------------------------------------------------------------------------------+ 21 | FLV header(9 bytes) | FLV body | 22 +-------------------------------------------------------------------------------+ 23 | | PreviousTagSize0(4 bytes)| Tag1|PreviousTagSize1|Tag2|... 24 +-------------------------------------------------------------------------------+ 25 26 *** Flv Tag *** 27 +-------------------------------------------------------------------------------------------------------------------------------+ 28 | Tag1 | 29 +-------------------------------------------------------------------------------------------------------------------------------+ 30 | Tag Header | Tag Data | 31 +-------------------------------------------------------------------------------------------------------------------------------+ 32 | Tag Type(1 byte) | Data Size(3 bytes) | Timestamp(3 bytes dts) | Timestamp Extended(1 byte) | Stream ID(3 bytes) | Tag Data | 33 +-------------------------------------------------------------------------------------------------------------------------------+ 34 35 36 The Tag Data contains 37 - video tag data 38 - audio tag data 39 40 **** Video Tag **** 41 +-------------------------------------------------+ 42 | Tag Data (Video Tag) | 43 +-------------------------------------------------+ 44 | FrameType(4 bits) | CodecID(4 bits) | Video Data| 45 +-------------------------------------------------+ 46 47 The contents of Video Data depends on the codecID: 48 2: H263VIDEOPACKET 49 3: SCREENVIDEOPACKET 50 4: VP6FLVVIDEOPACKET 51 5: VP6FLVALPHAVIDEOPACKET 52 6: SCREENV2VIDEOPACKET 53 7: AVCVIDEOPACKE 54 55 When the codecid equals 7, the Video Data's struct is as follows: 56 57 +------------------------------------------------------------+ 58 | Video Data (codecID == 7) | 59 +------------------------------------------------------------+ 60 | AVCPacketType(1 byte) | CompositionTime(3 bytes) | Payload | 61 +------------------------------------------------------------+ 62 63 **** Audio Tag **** 64 +----------------------------------------------------------------------------------------+ 65 | Tag Data (Audio Tag) | 66 +----------------------------------------------------------------------------------------+ 67 | SoundFormat(4 bits) | SoundRate(2 bits) | SoundSize(1 bit) | SoundType(1 bit)| Payload | 68 +----------------------------------------------------------------------------------------+ 69 70 reference: https://www.cnblogs.com/chyingp/p/flv-getting-started.html 71 */ 72 73 #[derive(Default)] 74 pub struct FlvDemuxerAudioData { 75 pub has_data: bool, 76 pub sound_format: u8, 77 pub dts: i64, 78 pub pts: i64, 79 pub data: BytesMut, 80 } 81 82 impl FlvDemuxerAudioData { new() -> Self83 pub fn new() -> Self { 84 Self { 85 has_data: false, 86 sound_format: 0, 87 dts: 0, 88 pts: 0, 89 data: BytesMut::new(), 90 } 91 } 92 } 93 #[derive(Default)] 94 pub struct FlvDemuxerVideoData { 95 pub frame_type: u8, 96 pub codec_id: u8, 97 pub dts: i64, 98 pub pts: i64, 99 pub data: BytesMut, 100 } 101 102 impl FlvDemuxerVideoData { new() -> Self103 pub fn new() -> Self { 104 Self { 105 codec_id: 0, 106 dts: 0, 107 pts: 0, 108 frame_type: 0, 109 data: BytesMut::new(), 110 } 111 } 112 } 113 114 #[derive(Default)] 115 pub struct FlvVideoTagDemuxer { 116 avc_processor: Mpeg4AvcProcessor, 117 } 118 119 impl FlvVideoTagDemuxer { new() -> Self120 pub fn new() -> Self { 121 Self { 122 avc_processor: Mpeg4AvcProcessor::new(), 123 } 124 } demux( &mut self, timestamp: u32, data: BytesMut, ) -> Result<Option<FlvDemuxerVideoData>, FlvDemuxerError>125 pub fn demux( 126 &mut self, 127 timestamp: u32, 128 data: BytesMut, 129 ) -> Result<Option<FlvDemuxerVideoData>, FlvDemuxerError> { 130 let mut reader = BytesReader::new(data); 131 132 let tag_header = VideoTagHeader::unmarshal(&mut reader)?; 133 if tag_header.codec_id == AvcCodecId::H264 as u8 { 134 match tag_header.avc_packet_type { 135 avc_packet_type::AVC_SEQHDR => { 136 self.avc_processor 137 .decoder_configuration_record_load(&mut reader)?; 138 139 return Ok(None); 140 } 141 avc_packet_type::AVC_NALU => { 142 let data = self.avc_processor.h264_mp4toannexb(&mut reader)?; 143 144 let video_data = FlvDemuxerVideoData { 145 codec_id: AvcCodecId::H264 as u8, 146 pts: timestamp as i64 + tag_header.composition_time as i64, 147 dts: timestamp as i64, 148 frame_type: tag_header.frame_type, 149 data, 150 }; 151 //print!("flv demux video payload length {}\n", video_data.data.len()); 152 return Ok(Some(video_data)); 153 } 154 _ => {} 155 } 156 } 157 158 Ok(None) 159 } 160 } 161 162 #[derive(Default)] 163 pub struct FlvAudioTagDemuxer { 164 aac_processor: Mpeg4AacProcessor, 165 } 166 167 impl FlvAudioTagDemuxer { new() -> Self168 pub fn new() -> Self { 169 Self { 170 aac_processor: Mpeg4AacProcessor::new(), 171 } 172 } 173 demux( &mut self, timestamp: u32, data: BytesMut, ) -> Result<FlvDemuxerAudioData, FlvDemuxerError>174 pub fn demux( 175 &mut self, 176 timestamp: u32, 177 data: BytesMut, 178 ) -> Result<FlvDemuxerAudioData, FlvDemuxerError> { 179 let mut reader = BytesReader::new(data); 180 181 let tag_header = AudioTagHeader::unmarshal(&mut reader)?; 182 self.aac_processor 183 .extend_data(reader.extract_remaining_bytes()); 184 185 if tag_header.sound_format == SoundFormat::AAC as u8 { 186 match tag_header.aac_packet_type { 187 aac_packet_type::AAC_SEQHDR => { 188 self.aac_processor.audio_specific_config_load()?; 189 return Ok(FlvDemuxerAudioData::new()); 190 } 191 aac_packet_type::AAC_RAW => { 192 self.aac_processor.adts_save()?; 193 194 let audio_data = FlvDemuxerAudioData { 195 has_data: true, 196 sound_format: tag_header.sound_format, 197 pts: timestamp as i64, 198 dts: timestamp as i64, 199 data: self.aac_processor.bytes_writer.extract_current_bytes(), 200 }; 201 //print!("flv demux audio payload length {}\n", audio_data.data.len()); 202 return Ok(audio_data); 203 } 204 _ => {} 205 } 206 } 207 208 Ok(FlvDemuxerAudioData::new()) 209 } 210 } 211 212 pub struct FlvDemuxer { 213 bytes_reader: BytesReader, 214 } 215 216 impl FlvDemuxer { new(data: BytesMut) -> Self217 pub fn new(data: BytesMut) -> Self { 218 Self { 219 bytes_reader: BytesReader::new(data), 220 } 221 } 222 read_flv_header(&mut self) -> Result<(), FlvDemuxerError>223 pub fn read_flv_header(&mut self) -> Result<(), FlvDemuxerError> { 224 /*flv header*/ 225 self.bytes_reader.read_bytes(9)?; 226 Ok(()) 227 } 228 read_flv_tag(&mut self) -> Result<Option<FlvData>, FlvDemuxerError>229 pub fn read_flv_tag(&mut self) -> Result<Option<FlvData>, FlvDemuxerError> { 230 /*previous_tag_size*/ 231 self.bytes_reader.read_u32::<BigEndian>()?; 232 233 /*tag type*/ 234 let tag_type = self.bytes_reader.read_u8()?; 235 /*data size*/ 236 let data_size = self.bytes_reader.read_u24::<BigEndian>()?; 237 /*timestamp*/ 238 let timestamp = self.bytes_reader.read_u24::<BigEndian>()?; 239 /*timestamp extended*/ 240 let timestamp_ext = self.bytes_reader.read_u8()?; 241 /*stream id*/ 242 self.bytes_reader.read_u24::<BigEndian>()?; 243 244 let dts: u32 = (timestamp & 0xffffff) | ((timestamp_ext as u32) << 24); 245 246 /*data*/ 247 let body = self.bytes_reader.read_bytes(data_size as usize)?; 248 249 match tag_type { 250 tag_type::VIDEO => { 251 return Ok(Some(FlvData::Video { 252 timestamp: dts, 253 data: body, 254 })); 255 } 256 tag_type::AUDIO => { 257 return Ok(Some(FlvData::Audio { 258 timestamp: dts, 259 data: body, 260 })); 261 } 262 263 _ => {} 264 } 265 266 Ok(None) 267 } 268 } 269