use oxideav_h264::decoder::{Decoder, Event};
fn main() {
let path = std::env::args()
.nth(1)
.expect("usage: dump_headers <annexb.264> [max]");
let max: usize = std::env::args()
.nth(2)
.and_then(|s| s.parse().ok())
.unwrap_or(usize::MAX);
let stream = std::fs::read(&path).expect("read stream");
let mut dec = Decoder::new();
let mut n = 0usize;
for ev in dec.process_annex_b(&stream) {
match ev {
Ok(Event::SpsStored(id)) => println!("SPS id={id}"),
Ok(Event::PpsStored(id)) => println!("PPS id={id}"),
Ok(Event::Slice {
nal_unit_type,
nal_ref_idc,
header: h,
sps,
pps,
..
}) => {
if h.first_mb_in_slice == 0 {
n += 1;
if n > max {
break;
}
}
let structure = if h.field_pic_flag {
if h.bottom_field_flag {
"FLD-bot"
} else {
"FLD-top"
}
} else if sps.mb_adaptive_frame_field_flag {
"AFRM"
} else {
"FRM"
};
println!(
"pic#{:3} nal={} ref_idc={} {:7} type={:?} frame_num={} poc_lsb={} first_mb={} dsmvp={} nref=({},{}) wp={}/{} has_wt={}",
n - 1,
nal_unit_type,
nal_ref_idc,
structure,
h.slice_type,
h.frame_num,
h.pic_order_cnt_lsb,
h.first_mb_in_slice,
u8::from(h.direct_spatial_mv_pred_flag),
h.num_ref_idx_l0_active_minus1 + 1,
h.num_ref_idx_l1_active_minus1 + 1,
u8::from(pps.weighted_pred_flag),
pps.weighted_bipred_idc,
h.pred_weight_table.is_some(),
);
}
Ok(_) => {}
Err(e) => println!("ERR: {e:?}"),
}
}
}