Skip to content

Commit 476ddf2

Browse files
committed
implementation for parse_ref_pic_list_modification
1 parent a10e82d commit 476ddf2

File tree

2 files changed

+102
-5
lines changed

2 files changed

+102
-5
lines changed

src/h264/parser.rs

Lines changed: 87 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ use macroblock::{
2222
use nal::{NalHeader, NalUnitType};
2323
use pps::{PicParameterSet, SliceGroup, SliceGroupChangeType, SliceRect};
2424
use slice::{
25-
DeblockingFilterIdc, DecRefPicMarking, MemoryManagementControlOperation, Slice, SliceHeader,
26-
SliceType,
25+
DeblockingFilterIdc, DecRefPicMarking, MemoryManagementControlOperation,
26+
RefPicListModification, RefPicListModifications, Slice, SliceHeader, SliceType,
2727
};
2828
use sps::{FrameCrop, SequenceParameterSet, VuiParameters};
2929

@@ -462,6 +462,88 @@ pub fn parse_nal_header(input: &mut BitReader) -> ParseResult<NalHeader> {
462462
Ok(header)
463463
}
464464

465+
// Section 7.3.3.1 Reference picture list modification syntax
466+
pub fn parse_ref_pic_list_modification(
467+
input: &mut BitReader,
468+
slice_type: SliceType,
469+
) -> ParseResult<RefPicListModifications> {
470+
let mut modifications = RefPicListModifications::default();
471+
472+
if slice_type != SliceType::I && slice_type != SliceType::SI {
473+
let ref_pic_list_modification_flag_l0: bool;
474+
read_value!(input, ref_pic_list_modification_flag_l0, f);
475+
if ref_pic_list_modification_flag_l0 {
476+
loop {
477+
let modification_of_pic_nums_idc: u32;
478+
read_value!(input, modification_of_pic_nums_idc, ue);
479+
match modification_of_pic_nums_idc {
480+
0 => {
481+
let abs_diff_pic_num_minus1: u32;
482+
read_value!(input, abs_diff_pic_num_minus1, ue);
483+
modifications.list0.push(RefPicListModification::RemapShortTermNegative(
484+
abs_diff_pic_num_minus1,
485+
));
486+
}
487+
1 => {
488+
let abs_diff_pic_num_minus1: u32;
489+
read_value!(input, abs_diff_pic_num_minus1, ue);
490+
modifications.list0.push(RefPicListModification::RemapShortTermPositive(
491+
abs_diff_pic_num_minus1,
492+
));
493+
}
494+
2 => {
495+
let long_term_pic_num: u32;
496+
read_value!(input, long_term_pic_num, ue);
497+
modifications
498+
.list0
499+
.push(RefPicListModification::RemapLongTerm(long_term_pic_num));
500+
}
501+
3 => break,
502+
_ => return Err("Invalid modification_of_pic_nums_idc".to_string()),
503+
}
504+
}
505+
}
506+
}
507+
508+
if slice_type == SliceType::B {
509+
let ref_pic_list_modification_flag_l1: bool;
510+
read_value!(input, ref_pic_list_modification_flag_l1, f);
511+
if ref_pic_list_modification_flag_l1 {
512+
loop {
513+
let modification_of_pic_nums_idc: u32;
514+
read_value!(input, modification_of_pic_nums_idc, ue);
515+
match modification_of_pic_nums_idc {
516+
0 => {
517+
let abs_diff_pic_num_minus1: u32;
518+
read_value!(input, abs_diff_pic_num_minus1, ue);
519+
modifications.list1.push(RefPicListModification::RemapShortTermNegative(
520+
abs_diff_pic_num_minus1,
521+
));
522+
}
523+
1 => {
524+
let abs_diff_pic_num_minus1: u32;
525+
read_value!(input, abs_diff_pic_num_minus1, ue);
526+
modifications.list1.push(RefPicListModification::RemapShortTermPositive(
527+
abs_diff_pic_num_minus1,
528+
));
529+
}
530+
2 => {
531+
let long_term_pic_num: u32;
532+
read_value!(input, long_term_pic_num, ue);
533+
modifications
534+
.list1
535+
.push(RefPicListModification::RemapLongTerm(long_term_pic_num));
536+
}
537+
3 => break,
538+
_ => return Err("Invalid modification_of_pic_nums_idc".to_string()),
539+
}
540+
}
541+
}
542+
}
543+
544+
Ok(modifications)
545+
}
546+
465547
// Section 7.3.3.3 Decoded reference picture marking syntax
466548
pub fn parse_dec_ref_pic_marking(
467549
input: &mut BitReader,
@@ -619,6 +701,8 @@ pub fn parse_slice_header(
619701
}
620702
}
621703

704+
header.ref_pic_list_modification = parse_ref_pic_list_modification(input, header.slice_type)?;
705+
622706
if nal.nal_ref_idc != 0 {
623707
header.dec_ref_pic_marking = Some(parse_dec_ref_pic_marking(input, idr_pic_flag)?);
624708
}
@@ -788,8 +872,7 @@ pub fn parse_p_macroblock(
788872
assert!(num_mb_part <= partitions.len());
789873

790874
if mb_part_pred_mode != MbPredictionMode::Pred_L1 {
791-
if slice.header.num_ref_idx_l0_active_minus1 > 0
792-
{
875+
if slice.header.num_ref_idx_l0_active_minus1 > 0 {
793876
for i in 0..num_mb_part {
794877
read_value!(input, partitions[i].ref_idx_l0, ue, 8);
795878
}

src/h264/slice.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,20 @@ pub struct DecRefPicMarking {
6565
pub memory_management_operations: Vec<MemoryManagementControlOperation>,
6666
}
6767

68+
// Table 7-7 – modification_of_pic_nums_idc operations for modification of reference picture lists
69+
#[derive(Clone, Debug, PartialEq, Eq)]
70+
pub enum RefPicListModification {
71+
RemapShortTermNegative(u32), // abs_diff_pic_num_minus1
72+
RemapShortTermPositive(u32), // abs_diff_pic_num_minus1
73+
RemapLongTerm(u32), // long_term_pic_num
74+
}
75+
76+
#[derive(Clone, Debug, PartialEq, Eq, Default)]
77+
pub struct RefPicListModifications {
78+
pub list0: Vec<RefPicListModification>,
79+
pub list1: Vec<RefPicListModification>,
80+
}
81+
6882
// Section 7.4.3 Slice header semantics
6983
#[derive(Clone, Debug, PartialEq, Eq, Default)]
7084
pub struct SliceHeader {
@@ -89,7 +103,7 @@ pub struct SliceHeader {
89103
pub num_ref_idx_l1_active_minus1: u32,
90104

91105
// may become an enum rather than Option in future (for ref_pic_list_mvc_modification)
92-
//pub ref_pic_list_modification: Option<RefPicListModifications>,
106+
pub ref_pic_list_modification: RefPicListModifications,
93107
//pub pred_weight_table: Option<PredWeightTable>,
94108
pub dec_ref_pic_marking: Option<DecRefPicMarking>,
95109
//pub cabac_init_idc: Option<u32>,

0 commit comments

Comments
 (0)