preprocessing nalu to apply bytestream formatting needed by decoder

This commit is contained in:
Muaz Ahmad 2023-10-10 14:42:08 +05:00
parent d8e9d34a64
commit 4bcf6c797d
3 changed files with 56 additions and 4 deletions

View file

@ -4,6 +4,7 @@ use std::io::Read;
use crate::util;
use crate::demux::input;
use crate::demux::nalu;
enum FLVTagType {
Metadata,
@ -81,16 +82,16 @@ impl input::FileReader for FLVReader {
self.skip_init_header()?;
return self.read_metadata()
}
fn read_nalu(&mut self, _metadata: &util::Metadata) -> Result<util::NALUPacket, Box<dyn Error + Send + Sync>> {
let (packet_type, data) = self.read_packet()?;
fn read_nalu(&mut self, metadata: &util::Metadata) -> Result<util::NALUPacket, Box<dyn Error + Send + Sync>> {
let (packet_type, mut data) = self.read_packet()?;
return match packet_type {
FLVTagType::Audio => Ok(util::NALUPacket {
packet_type: util::NALUPacketType::Audio,
packet_data: data,
packet_data: nalu::prepend_a_flv(data, &metadata),
}),
FLVTagType::Video => Ok(util::NALUPacket {
packet_type: util::NALUPacketType::Video,
packet_data: data,
packet_data: nalu::prepend_v_flv(data, &metadata),
}),
_ => Err(Box::new(util::DemuxerError::FLVUnexpectedTag))
};

View file

@ -1,5 +1,6 @@
mod input;
mod flv;
mod nalu;
use std::sync::mpsc;
use std::error::Error;

50
src/demux/nalu.rs Normal file
View file

@ -0,0 +1,50 @@
use crate::util;
pub fn prepend_v_flv(data: Vec<u8>, metadata: &util::Metadata) -> Vec<u8> {
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<u8>, metadata: &util::Metadata) -> Vec<u8> {
return data;
}
fn parse_avcc(mut data: Vec<u8>) -> (Vec<u8>, Vec<u8>) {
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::<Vec<u8>>();
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::<Vec<u8>>();
return (sps, pps);
}
fn preprocess_h264(mut data: Vec<u8>) -> Vec<u8> {
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]);
}
}
}