use super::define;
use super::define::TagType;
use super::errors::TagParseError;
use byteorder::BigEndian;
use bytes::BytesMut;
use networkio::bytes_reader::BytesReader;
#[derive(Clone)]
pub struct Tag {
pub sound_format: u8,
pub sound_rate: u8,
pub sound_size: u8,
pub sound_type: u8,
aac_packet_type: u8,
pub frame_type: u8,
pub codec_id: u8,
pub avc_packet_type: u8,
pub composition_time: u32,
}
impl Tag {
pub fn defalut() -> Self {
Tag {
sound_format: 0,
sound_rate: 0,
sound_size: 0,
sound_type: 0,
aac_packet_type: 0,
frame_type: 0,
codec_id: 0,
avc_packet_type: 0,
composition_time: 0,
}
}
}
pub struct TagParser {
tag_type: TagType,
bytes_reader: BytesReader,
tag: Tag,
}
impl TagParser {
pub fn new(data: BytesMut, tag_type: TagType) -> Self {
Self {
tag_type,
bytes_reader: BytesReader::new(data),
tag: Tag::defalut(),
}
}
pub fn parse(&mut self) -> Result<Tag, TagParseError> {
match self.tag_type {
TagType::AUDIO => return self.parse_audio_tag_header(),
TagType::VIDEO => return self.parse_video_tag_header(),
}
}
fn parse_audio_tag_header(&mut self) -> Result<Tag, TagParseError> {
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;
match self.tag.sound_format {
define::sound_format::AAC => {
self.tag.aac_packet_type = self.bytes_reader.read_u8()?;
}
_ => {}
}
return Ok(self.tag.clone());
}
fn parse_video_tag_header(&mut self) -> Result<Tag, TagParseError> {
let flags = self.bytes_reader.read_u8()?;
self.tag.frame_type = flags >> 4;
self.tag.codec_id = flags & 0x0f;
if self.tag.frame_type == define::frame_type::INTER_FRAME
|| self.tag.frame_type == define::frame_type::KEY_FRAME
{
self.tag.avc_packet_type = self.bytes_reader.read_u8()?;
for _ in 0..3 {
self.tag.composition_time = self.bytes_reader.read_u32::<BigEndian>()?;
}
}
return Ok(self.tag.clone());
}
}