Skip to content

Commit

Permalink
saving sps, pps and demuxed_data in segment
Browse files Browse the repository at this point in the history
  • Loading branch information
akshay-v9 committed Jun 13, 2023
1 parent ec97d7d commit 3d71340
Showing 1 changed file with 82 additions and 34 deletions.
116 changes: 82 additions & 34 deletions src/parser.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::io::Read;

Check warning on line 1 in src/parser.rs

View workflow job for this annotation

GitHub Actions / Lint 📎

unused import: `std::io::Read`

warning: unused import: `std::io::Read` --> src/parser.rs:1:5 | 1 | use std::io::Read; | ^^^^^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default

#[derive(Clone, Copy)]
pub enum HeaderCode {
Delimiter = 0x09,
Expand Down Expand Up @@ -30,7 +32,7 @@ impl HeaderCode {

enum VideoFrameType {
KeyFrame,
IFrame,
DeltaFrame,
}

enum ParseState {
Expand All @@ -50,7 +52,6 @@ pub struct DemuxedSegment {

pub struct NALParser {
state: ParseState,

Check warning on line 54 in src/parser.rs

View workflow job for this annotation

GitHub Actions / Lint 📎

field is never read: `state`

warning: field is never read: `state` --> src/parser.rs:54:5 | 54 | state: ParseState, | ^^^^^^^^^^^^^^^^^
active_segment: DemuxedSegment,
raw_data: Option<Vec<u8>>,
segments: Option<Vec<DemuxedSegment>>,
sei_found: bool,
Expand All @@ -60,12 +61,6 @@ impl NALParser {
pub fn new() -> Self {
return NALParser {
state: ParseState::Sps,
active_segment: DemuxedSegment {
sps: None,
pps: None,
frame_type: VideoFrameType::KeyFrame,
frame_payload: None,
},
raw_data: None,
segments: Some(Vec::new()),
sei_found: false,
Expand All @@ -87,66 +82,91 @@ impl NALParser {
let sps_header_index = NALParser::index_of_payload(vec,
HeaderCode::delimiter_length(),
HeaderCode::Sps);
if sps_header_index.0.is_some() { // key frame
let mut active_segment: DemuxedSegment;
if sps_header_index.start_index.is_some() { // key frame
active_segment = DemuxedSegment {
sps: None,
pps: None,
frame_type: VideoFrameType::KeyFrame,
frame_payload: None,
};
let pps_header_index = NALParser::index_of_payload(vec,
sps_header_index.1.unwrap_or_else(|| 0),
sps_header_index.end_index.unwrap(),
HeaderCode::Pps,);
if let Some(pps_end_index) = pps_header_index.1 {
Self::print(pps_header_index, HeaderCode::Sps);
if let Some(pps_end_index) = pps_header_index.end_index {
active_segment.sps = get_header_payload(&pps_header_index, &vec);
Self::print(&pps_header_index, HeaderCode::Sps);
let header = if self.sei_found == true { HeaderCode::KeyFrame } else { HeaderCode::Sei };
let sei_or_key_frame_index = NALParser::index_of_payload(vec,
pps_end_index, header);
let key_frame_header_end_index: usize;

if self.sei_found == false {
if let Some(sei_or_key_frame_end_index) = sei_or_key_frame_index.1 {
Self::print(sei_or_key_frame_index, HeaderCode::Pps);

if let Some(sei_or_key_frame_end_index) = sei_or_key_frame_index.end_index {

Check warning on line 106 in src/parser.rs

View workflow job for this annotation

GitHub Actions / Lint 📎

unused variable: `sei_or_key_frame_end_index`

warning: unused variable: `sei_or_key_frame_end_index` --> src/parser.rs:106:37 | 106 | if let Some(sei_or_key_frame_end_index) = sei_or_key_frame_index.end_index { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_sei_or_key_frame_end_index` | = note: `#[warn(unused_variables)]` on by default
active_segment.pps = get_header_payload(&sei_or_key_frame_index, &vec);
Self::print(&sei_or_key_frame_index, HeaderCode::Pps);
}
let key_frame_index = NALParser::index_of_payload(vec,
sei_or_key_frame_index.1.unwrap_or_else(|| 0),
sei_or_key_frame_index.end_index.unwrap_or_else(|| 0),
HeaderCode::KeyFrame);
key_frame_header_end_index = key_frame_index.1.unwrap_or_else(|| 0);
key_frame_header_end_index = key_frame_index.end_index.unwrap_or_else(|| 0);
} else {
key_frame_header_end_index = sei_or_key_frame_index.1.unwrap_or_else(|| 0);
Self::print(sei_or_key_frame_index, HeaderCode::Pps);
active_segment.pps = get_header_payload(&sei_or_key_frame_index, &vec);
key_frame_header_end_index = sei_or_key_frame_index.end_index.unwrap_or_else(|| 0);
Self::print(&sei_or_key_frame_index, HeaderCode::Pps);
}
self.sei_found = true;

if let Some(key_frame_data) = &self.raw_data {
println!("Packet :KeyFrame Payload size {}", key_frame_data.len() - key_frame_header_end_index)
active_segment.frame_payload = Some(vec[key_frame_header_end_index..key_frame_data.len()].to_vec());
println!("Packet :KeyFrame Payload size {}", key_frame_data.len() - key_frame_header_end_index);
}
}
} else { // delta frame
active_segment = DemuxedSegment {
sps: None,
pps: None,
frame_type: VideoFrameType::DeltaFrame,
frame_payload: None,
};

let header_size = HeaderCode::iframe_header_prefix_byte_count();
if let Some(keyFrameData) = &self.raw_data {
println!("delta frame size {}", keyFrameData.len() - header_size);
if let Some(delta_frame_data) = &self.raw_data {
active_segment.frame_payload = Some(vec[header_size..delta_frame_data.len()].to_vec());
println!("delta frame size {}", delta_frame_data.len() - header_size);
}
}
if let Some(ref mut demux_segments) = self.segments {
demux_segments.push(active_segment);
} else {
self.segments = Some(vec![active_segment]);
}
}
}

fn print(index: (Option<usize>, Option<usize>, Option<usize>), header_code: HeaderCode) {
fn print(indices: &HeaderIndices, header_code: HeaderCode) {
let header = match header_code {
HeaderCode::Delimiter => "Delimiter",
HeaderCode::Sps => "SPS",
HeaderCode::Pps => "PPS",
HeaderCode::KeyFrame => "KEYFRAME",
HeaderCode::Sei => "IFRAME",
};
println!("Packet :{} Payload size {}", header, (index.0.unwrap_or_else(|| 0)
- index.2.unwrap_or_else(|| 0)))
println!("Packet :{} Payload size {}", header, (indices.start_index.unwrap_or_else(|| 0)
- indices.prev_header_end.unwrap_or_else(|| 0)))
}

// Return value is Header start , Header end, Previous Header End
fn index_of_payload(data_stream: &[u8], start_index: usize, header_coder: HeaderCode) -> (Option<usize>, Option<usize>, Option<usize>) {
fn index_of_payload(data_stream: &[u8], start_index: usize, header_coder: HeaderCode) -> HeaderIndices {
match header_coder.header_prefix_byte_count() {
3 => Self::index_of_three_byte_nal_unit(start_index, header_coder, data_stream),
4 => Self::index_of_four_byte_nal_unit(start_index, header_coder, data_stream),
_ => (None, None, None)
_ => HeaderIndices::new(None, None, None)
}
}

pub fn index_of_four_byte_nal_unit(start_index: usize, header_code: HeaderCode, data_stream: &[u8]) -> (Option<usize>, Option<usize>, Option<usize>) {
pub fn index_of_four_byte_nal_unit(start_index: usize, header_code: HeaderCode, data_stream: &[u8]) -> HeaderIndices {
let start = start_index;
let mut iterator = start_index;
while iterator < (data_stream.len() - header_code.header_prefix_byte_count()) {
Expand All @@ -159,16 +179,16 @@ impl NALParser {
let contains = (byte_zero | byte_one | byte_two | byte_three) == 1 && byte_four == (header_code as u8);
if contains {
if Some(start).unwrap() == Some(iterator).unwrap() {
return (Some(iterator), Some(iterator + 4), None);
return HeaderIndices::new(Some(iterator), Some(iterator + 4), None);
}
return (Some(iterator), Some(iterator + 4), Some(start));
return HeaderIndices::new(Some(iterator), Some(iterator + 4), Some(start));
}
iterator = iterator + 1;
}
return (None, None, None);
return HeaderIndices::new(None, None, None);
}

pub fn index_of_three_byte_nal_unit(start_index: usize, header_code: HeaderCode, data_stream: &[u8]) -> (Option<usize>, Option<usize>, Option<usize>) {
pub fn index_of_three_byte_nal_unit(start_index: usize, header_code: HeaderCode, data_stream: &[u8]) -> HeaderIndices {
let start = start_index;
let mut iterator = start_index;
while iterator < (data_stream.len() - header_code.header_prefix_byte_count()) {
Expand All @@ -180,12 +200,40 @@ impl NALParser {
let contains = (byte_zero | byte_one | byte_two) == 1 && byte_three == header_code as u8;
if contains {
if Some(start).unwrap_or_else(|| 0) == Some(iterator).unwrap_or_else(|| 0) {
return (Some(iterator), Some(iterator + 3), None);
return HeaderIndices::new(Some(iterator), Some(iterator + 3), None )
}
return (Some(iterator), Some(iterator + 3), Some(start));
return HeaderIndices::new(Some(iterator), Some(iterator + 3), Some(start));
}
iterator = iterator + 1;
}
return (None, None, None);
return HeaderIndices::new(None, None, None);
}
}

pub struct HeaderIndices {
start_index : Option<usize>,
end_index : Option<usize>,
prev_header_end : Option<usize>,
}

impl HeaderIndices {
pub fn new(
start_index: Option<usize>,
end_index: Option<usize>,
prev_header_end_index: Option<usize>
) -> HeaderIndices {
HeaderIndices {
start_index,
end_index,
prev_header_end: prev_header_end_index,
}
}
}

pub fn get_header_payload(next_header_indices: &HeaderIndices, vec: &Vec<u8>) -> Option<Vec<u8>> {
if next_header_indices.start_index.is_some() && next_header_indices.prev_header_end.is_some() {
let slice = &vec[next_header_indices.prev_header_end.unwrap()..next_header_indices.start_index.unwrap()];
return Some(slice.to_vec())
}
None
}

0 comments on commit 3d71340

Please sign in to comment.