Skip to content
uupaa edited this page Sep 10, 2018 · 1 revision

IDR

IDR は リセット情報を含んだ I フレームです。 IDR フレームは他のフレームを参照しません。

シークは IDR フレーム単位で行われます。

  • u(n) で n が数値の場合は n bit 読み進め、結果をunsignedで返す事を意味しています。 u(1) は 1 bit を読み進めます。
  • u(n) で n が v の場合は、変数名毎に特殊なルールで読み込むビット数を决定する事を意味しています。
    • frame_num = u(v)
      • frame_num is used as an identifier for pictures and shall be represented by log2_max_frame_num_minus4 + 4 bits in the bitstream. frame_num is constrained as follows:
      • frame_num = u(v)SPS.log2_max_frame_num_minus4 + 4 から求める事ができます
    • pic_order_cnt_lsb = u(v)
      • pic_order_cnt_lsb specifies the picture order count modulo MaxPicOrderCntLsb for the top field of a coded frame or for a coded field. The length of the pic_order_cnt_lsb syntax element is log2_max_pic_order_cnt_lsb_minus4 + 4 bits. The value of the pic_order_cnt_lsb shall be in the range of 0 to MaxPicOrderCntLsb − 1, inclusive.
      • pic_order_cnt_lsb = u(v)SPS.log2_max_pic_order_cnt_lsb_minus4 + 4 から求める事ができます
    • slice_group_change_cycle = u(v)
      • The value of slice_group_change_cycle is represented in the bitstream by the following number of bits Ceil( Log2( PicSizeInMapUnits ÷ SliceGroupChangeRate + 1 ) )
      • slice_group_change_cycle = u(v)Math.ceil( Math.log2( PicSizeInMapUnits / SliceGroupChangeRate + 1 ) ) から求める事ができます
      • PicHeightInMapUnits = SPS.pic_height_in_map_units_minus1 + 1
      • PicSizeInMapUnits = PicWidthInMbs * PicHeightInMapUnits
      • PicWidthInMbs = SPS.pic_width_in_mbs_minus1 + 1
      • SliceGroupChangeRate = PPS.slice_group_change_rate_minus1 + 1

u(v) をデコードするには以下を参考に

slice_layer_without_partitioning_rbsp() {
    slice_header()
    slice_data() // all categories of slice_data( ) syntax
    rbsp_slice_trailing_bits()
}
slice_header() {
    first_mb_in_slice                       ue(v)
    slice_type                              ue(v)
    pic_parameter_set_id                    ue(v)
    if (separate_colour_plane_flag === 1) {
        colour_plane_id                     u(2)
    }
    frame_num                               u(v) // !!
    if (!frame_mbs_only_flag) {
        field_pic_flag                      u(1)
        if (field_pic_flag) {
            bottom_field_flag               u(1)
        }
    }
    if (IdrPicFlag) {
        idr_pic_id                          ue(v)
    }
    if (pic_order_cnt_type === 0) {
        pic_order_cnt_lsb                   u(v) // !!
        if (bottom_field_pic_order_in_frame_present_flag && !field_pic_flag) {
            delta_pic_order_cnt_bottom      se(v)
        }
    }
    if (pic_order_cnt_type === 1 && !delta_pic_order_always_zero_flag) {
        delta_pic_order_cnt[ 0 ]            se(v)
        if (bottom_field_pic_order_in_frame_present_flag && !field_pic_flag) {
            delta_pic_order_cnt[ 1 ]        se(v)
        }
    }
    if (redundant_pic_cnt_present_flag) {
        redundant_pic_cnt                           ue(v)
    }
    if (slice_type === B) {
        direct_spatial_mv_pred_flag                 u(1)
    }
    if (slice_type === P || slice_type === SP || slice_type === B) {
        num_ref_idx_active_override_flag            u(1)
        if (num_ref_idx_active_override_flag) {
            num_ref_idx_l0_active_minus1            ue(v)
            if (slice_type === B) {
                num_ref_idx_l1_active_minus1        ue(v)
            }
        }
    }
    if (nal_unit_type === 20) {
        ref_pic_list_mvc_modification() // specified in Annex H
    } else {
        ref_pic_list_modification()
    }
    if (( weighted_pred_flag && ( slice_type === P || slice_type === SP ) ) ||
        ( weighted_bipred_idc == 1 && slice_type == B ) ) {
        pred_weight_table()
    }
    if (nal_ref_idc !== 0) {
        dec_ref_pic_marking()
    }
    if (entropy_coding_mode_flag && slice_type !== I && slice_type !== SI) {
        cabac_init_idc                              ue(v)
    }
    slice_qp_delta                                  se(v)

    if (slice_type === SP || slice_type === SI) {
        if (slice_type === SP) {
            sp_for_switch_flag                      u(1)
        }
        slice_qs_delta                              se(v)
    }
    if (deblocking_filter_control_present_flag) {
        disable_deblocking_filter_idc               ue(v)
        if (disable_deblocking_filter_idc !== 1) {
            slice_alpha_c0_offset_div2              se(v)
            slice_beta_offset_div2                  se(v)
        }
    }
    if (num_slice_groups_minus1 > 0 &&
        slice_group_map_type >= 3 &&
        slice_group_map_type <= 5) {
        slice_group_change_cycle                    u(v) // !!
    }
}
slice_data() {
    if (entropy_coding_mode_flag) {
        while (!byte_aligned()) {
            cabac_alignment_one_bit                 f(1)
        }
    }
    CurrMbAddr = first_mb_in_slice * ( 1 + MbaffFrameFlag )
    moreDataFlag = 1
    prevMbSkipped = 0
    do {
        if (slice_type !== I && slice_type !== SI) {
            if (!entropy_coding_mode_flag) {
                mb_skip_run                         ue(v)
                prevMbSkipped = ( mb_skip_run > 0 )

                for (i=0; i<mb_skip_run; ++i) {
                    CurrMbAddr = NextMbAddress( CurrMbAddr )
                }
                if (mb_skip_run > 0) {
                    moreDataFlag = more_rbsp_data( )
                }
            } else {
                mb_skip_flag                        ae(v)
                moreDataFlag = !mb_skip_flag
            }
        }
        if (moreDataFlag) {
            if (MbaffFrameFlag && ( CurrMbAddr % 2 === 0 || ( CurrMbAddr % 2 === 1 && prevMbSkipped) ) ) {
                mb_field_decoding_flag              u(1) | ae(v)
            }
            macroblock_layer( )
        }
        if (!entropy_coding_mode_flag) {
            moreDataFlag = more_rbsp_data( )
        } else {
            if (slice_type !== I && slice_type !== SI) {
                prevMbSkipped = mb_skip_flag
            }
            if (MbaffFrameFlag && CurrMbAddr % 2 === 0 ) {
                moreDataFlag = 1
            } else {
                end_of_slice_flag                   ae(v)
                moreDataFlag = !end_of_slice_flag
            }
        }
        CurrMbAddr = NextMbAddress( CurrMbAddr )
    } while (moreDataFlag)
}
ref_pic_list_modification() {
    if (slice_type % 5 !== 2 && slice_type % 5 !== 4) {
        ref_pic_list_modification_flag_l0               u(1)
        if (ref_pic_list_modification_flag_l0 ) {
            do {
                modification_of_pic_nums_idc            ue(v)

                if (modification_of_pic_nums_idc === 0 ||
                    modification_of_pic_nums_idc === 1) {
                    abs_diff_pic_num_minus1             ue(v)
                } else if (modification_of_pic_nums_idc === 2) {
                    long_term_pic_num                   ue(v)
                }
            } while ( modification_of_pic_nums_idc !== 3 );
        }
    }
    if (slice_type % 5 === 1) {
        ref_pic_list_modification_flag_l1               u(1)
        if (ref_pic_list_modification_flag_l1) {
            do {
                modification_of_pic_nums_idc            ue(v)
                if (modification_of_pic_nums_idc === 0 ||
                    modification_of_pic_nums_idc === 1) {
                    abs_diff_pic_num_minus1             ue(v)
                } else if (modification_of_pic_nums_idc === 2) {
                    long_term_pic_num                   ue(v)
                }
            } while (modification_of_pic_nums_idc !== 3);
        }
    }
}
dec_ref_pic_marking() {
    if (IdrPicFlag) {
        no_output_of_prior_pics_flag                                u(1)
        long_term_reference_flag                                    u(1)
    } else {
        adaptive_ref_pic_marking_mode_flag                          u(1)
        if (adaptive_ref_pic_marking_mode_flag) {
            do {
                memory_management_control_operation                 ue(v)

                if (memory_management_control_operation === 1 ||
                    memory_management_control_operation === 3) {
                    difference_of_pic_nums_minus1                   ue(v)
                }
                if (memory_management_control_operation === 2) {
                    long_term_pic_num                               ue(v)
                }
                if (memory_management_control_operation === 3 ||
                    memory_management_control_operation === 6) {
                    long_term_frame_idx                             ue(v)
                }
                if (memory_management_control_operation === 4) {
                    max_long_term_frame_idx_plus1                   ue(v)
                }
            } while (memory_management_control_operation !== 0)
        }
    }
}
slice_data() {
    if (entropy_coding_mode_flag) {
        while ( !byte_aligned() ) {
            cabac_alignment_one_bit                         f(1)
        }
    }
    CurrMbAddr = first_mb_in_slice * ( 1 + MbaffFrameFlag )
    moreDataFlag = 1
    prevMbSkipped = 0
    do {
        if (slice_type != I && slice_type != SI) {
            if (!entropy_coding_mode_flag) {
                mb_skip_run                                 ue(v)
                prevMbSkipped = ( mb_skip_run > 0 )
                for (i = 0; i < mb_skip_run; ++i) {
                    CurrMbAddr = NextMbAddress( CurrMbAddr )
                }
                if ( mb_skip_run > 0 ) {
                    moreDataFlag = more_rbsp_data( )
                }
            } else {
                mb_skip_flag                                ae(v)
                moreDataFlag = !mb_skip_flag
            }
        }
        if (moreDataFlag) {
            if (MbaffFrameFlag && ( CurrMbAddr % 2 === 0 || ( CurrMbAddr % 2 === 1 && prevMbSkipped ) ) ) {
                mb_field_decoding_flag                  u(1) | ae(v)
            }
            macroblock_layer()
        }
        if (!entropy_coding_mode_flag) {
            moreDataFlag = more_rbsp_data()
        } else {
            if (slice_type != I && slice_type != SI) {
                prevMbSkipped = mb_skip_flag
            }
            if (MbaffFrameFlag && CurrMbAddr % 2 = = 0) {
                moreDataFlag = 1
            } else {
                end_of_slice_flag                   ae(v)
                moreDataFlag = !end_of_slice_flag
            }
        }
        CurrMbAddr = NextMbAddress( CurrMbAddr )
    } while (moreDataFlag);
}
macroblock_layer() {
}