preprocessing nalu to apply bytestream formatting needed by decoder
This commit is contained in:
parent
d8e9d34a64
commit
4bcf6c797d
3 changed files with 56 additions and 4 deletions
|
@ -4,6 +4,7 @@ use std::io::Read;
|
||||||
|
|
||||||
use crate::util;
|
use crate::util;
|
||||||
use crate::demux::input;
|
use crate::demux::input;
|
||||||
|
use crate::demux::nalu;
|
||||||
|
|
||||||
enum FLVTagType {
|
enum FLVTagType {
|
||||||
Metadata,
|
Metadata,
|
||||||
|
@ -81,16 +82,16 @@ impl input::FileReader for FLVReader {
|
||||||
self.skip_init_header()?;
|
self.skip_init_header()?;
|
||||||
return self.read_metadata()
|
return self.read_metadata()
|
||||||
}
|
}
|
||||||
fn read_nalu(&mut self, _metadata: &util::Metadata) -> Result<util::NALUPacket, Box<dyn Error + Send + Sync>> {
|
fn read_nalu(&mut self, metadata: &util::Metadata) -> Result<util::NALUPacket, Box<dyn Error + Send + Sync>> {
|
||||||
let (packet_type, data) = self.read_packet()?;
|
let (packet_type, mut data) = self.read_packet()?;
|
||||||
return match packet_type {
|
return match packet_type {
|
||||||
FLVTagType::Audio => Ok(util::NALUPacket {
|
FLVTagType::Audio => Ok(util::NALUPacket {
|
||||||
packet_type: util::NALUPacketType::Audio,
|
packet_type: util::NALUPacketType::Audio,
|
||||||
packet_data: data,
|
packet_data: nalu::prepend_a_flv(data, &metadata),
|
||||||
}),
|
}),
|
||||||
FLVTagType::Video => Ok(util::NALUPacket {
|
FLVTagType::Video => Ok(util::NALUPacket {
|
||||||
packet_type: util::NALUPacketType::Video,
|
packet_type: util::NALUPacketType::Video,
|
||||||
packet_data: data,
|
packet_data: nalu::prepend_v_flv(data, &metadata),
|
||||||
}),
|
}),
|
||||||
_ => Err(Box::new(util::DemuxerError::FLVUnexpectedTag))
|
_ => Err(Box::new(util::DemuxerError::FLVUnexpectedTag))
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
mod input;
|
mod input;
|
||||||
mod flv;
|
mod flv;
|
||||||
|
mod nalu;
|
||||||
|
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
50
src/demux/nalu.rs
Normal file
50
src/demux/nalu.rs
Normal 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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue