diff --git a/src/demux/nalu.rs b/src/demux/nalu.rs deleted file mode 100644 index 5a0c143..0000000 --- a/src/demux/nalu.rs +++ /dev/null @@ -1,50 +0,0 @@ -use crate::util; - -pub fn prepend_v_flv(data: Vec, metadata: &util::Metadata) -> Vec { - match metadata.video.codec { - Some(util::VideoCodec::H264) => preprocess_h264(data), - None => panic!("not possible for codec to be None by this point") - } -} - -pub fn prepend_a_flv(data: Vec, metadata: &util::Metadata) -> Vec { - return data; -} - -fn parse_avcc(mut data: Vec) -> (Vec, Vec) { - data.drain(..6); - let mut buff = [0u8; 2]; - buff.copy_from_slice(data.drain(..2).as_slice()); - let sps_len = u16::from_be_bytes(buff) as usize; - let sps = data.drain(..sps_len).collect::>(); - data.drain(..1); - let mut buff = [0u8; 2]; - buff.copy_from_slice(data.drain(..2).as_slice()); - let pps_len = u16::from_be_bytes(buff) as usize; - let pps = data.drain(..pps_len).collect::>(); - return (sps, pps); -} - -fn preprocess_h264(mut data: Vec) -> Vec { - let mut nalu = vec![0u8, 0u8, 0u8, 1u8]; - if data[1] == 0 { - data.drain(..5); - let (mut sps, mut pps) = parse_avcc(data); - nalu.append(&mut sps); - nalu.append(&mut vec![0u8, 0u8, 0u8, 1u8]); - nalu.append(&mut pps); - return nalu; - } else if data[1] == 2 { - return vec![0u8; 0]; - } else { - data.drain(..5); - loop { - let mut buff = [0u8; 4]; - buff.copy_from_slice(data.drain(..4).as_slice()); - let nalu_len = u32::from_be_bytes(buff) as usize; - nalu.extend_from_slice(data.drain(..nalu_len).as_slice()); - if data.len() <= 4 {return nalu} - nalu.append(&mut vec![0u8, 0u8, 0u8, 1u8]); - } - } -} diff --git a/src/demux/nalu_flv.rs b/src/demux/nalu_flv.rs new file mode 100644 index 0000000..883bcf1 --- /dev/null +++ b/src/demux/nalu_flv.rs @@ -0,0 +1,99 @@ +use crate::util; + +pub fn prepend_v(data: Vec, metadata: &util::Metadata) -> Vec { + match metadata.video.codec { + Some(util::VideoCodec::H264) => preprocess_h264(data), + None => panic!("not possible for codec to be None by this point") + } +} + +pub fn prepend_a(data: Vec, metadata: &util::Metadata) -> Vec { + match metadata.audio.codec { + Some(util::AudioCodec::AAC) => preprocess_aac(data, metadata), + None => panic!("not possible for codec to be None by this point") + } +} + +fn parse_avcc(mut data: Vec) -> (Vec, Vec) { + data.drain(..6); + let mut buff = [0u8; 2]; + buff.copy_from_slice(data.drain(..2).as_slice()); + let sps_len = u16::from_be_bytes(buff) as usize; + let sps = data.drain(..sps_len).collect::>(); + data.drain(..1); + let mut buff = [0u8; 2]; + buff.copy_from_slice(data.drain(..2).as_slice()); + let pps_len = u16::from_be_bytes(buff) as usize; + let pps = data.drain(..pps_len).collect::>(); + return (sps, pps); +} + +fn preprocess_h264(mut data: Vec) -> Vec { + let mut nalu = vec![0u8, 0u8, 0u8, 1u8]; + match data[1] { + 0 => { + data.drain(..5); + let (mut sps, mut pps) = parse_avcc(data); + nalu.append(&mut sps); + nalu.append(&mut vec![0u8, 0u8, 0u8, 1u8]); + nalu.append(&mut pps); + return nalu; + }, + 2 => {return vec![0u8; 0];}, + 1 => { + data.drain(..5); + loop { + let mut buff = [0u8; 4]; + buff.copy_from_slice(data.drain(..4).as_slice()); + let nalu_len = u32::from_be_bytes(buff) as usize; + nalu.extend_from_slice(data.drain(..nalu_len).as_slice()); + if data.len() <= 4 {return nalu} + nalu.append(&mut vec![0u8, 0u8, 0u8, 1u8]); + } + }, + _ => {panic!("cannot be any other value")} + } +} + +fn make_adts_head(metadata: &util::Metadata, data_len: usize) -> Vec { + let aot_idx = 1u8; + let frame_len = (data_len + 7) as u16; + let samplerate_idx: u8 = match metadata.audio.samplerate { + 96000 => 0, + 88200 => 1, + 64000 => 2, + 48000 => 3, + 44100 => 4, + 32000 => 5, + 24000 => 6, + 22050 => 7, + 16000 => 8, + 12000 => 9, + 11025 => 10, + 8000 => 11, + 7350 => 12, + _ => {panic!("invalid samplerate")} + }; + let chan_conf_idx = metadata.audio.channels; + let mut head = vec![0xffu8, 0xf1u8, 0u8, 0u8, 0u8, 0u8, 0xfcu8]; + head[2] = (aot_idx << 6) | (samplerate_idx << 2) | (chan_conf_idx >> 2); + head[3] = ((chan_conf_idx & 0x3) << 6) | ((frame_len >> 11) as u8); + head[4] = ((frame_len >> 3) & 0xff) as u8; + head[5] = (((frame_len << 5) & 0xff) as u8) | 0x1f; + return head +} + +fn preprocess_aac(mut data: Vec, metadata: &util::Metadata) -> Vec { + match data[1] { + 0 => { + return vec![0u8; 0]; + }, + 1 => { + data.drain(..2); + let mut nalu = make_adts_head(metadata, data.len()); + nalu.append(&mut data); + return nalu; + }, + _ => {panic!("cannot be any other value")} + } +}