Bug 1319734 - parse h264 slice header. draft
authorAlastor Wu <alwu@mozilla.com>
Fri, 30 Dec 2016 11:57:19 +0800
changeset 454760 250ab410533a5c8ce2419efd760031a21f67e4f6
parent 454747 6f63f95e28ffc05c0d2f5ef6cd6e05905fe8ea5a
child 540797 7a46de102236b83e8a709f46265b47ee19e4a5f7
push id40027
push useralwu@mozilla.com
push dateFri, 30 Dec 2016 03:57:40 +0000
bugs1319734
milestone53.0a1
Bug 1319734 - parse h264 slice header. MozReview-Commit-ID: LtQLrDht6h4
media/libstagefright/binding/H264.cpp
media/libstagefright/binding/include/mp4_demuxer/H264.h
--- a/media/libstagefright/binding/H264.cpp
+++ b/media/libstagefright/binding/H264.cpp
@@ -891,16 +891,72 @@ H264::DecodePPS(const mozilla::MediaByte
 /* static */ bool
 H264::DecodeParametersSet(const mozilla::MediaByteBuffer* aExtraData,
                          H264ParametersSet& aDest)
 {
   return DecodeSPSDataSetFromExtraData(aExtraData, aDest.SPSes) &&
          DecodePPSDataSetFromExtraData(aExtraData, aDest.SPSes, aDest.PPSes);
 }
 
+/* static */ bool
+H264::DecodeSliceHeader(const mozilla::MediaRawData* aSample,
+                        const H264ParametersSet& aParameterSet,
+                        SliceHeader& aDest)
+{
+  if (!AnnexB::IsAVCC(aSample)) {
+    return false;
+  }
+
+  MOZ_ASSERT(aSample->Data());
+  const int nalLenSize = ((*aSample->mExtraData)[4] & 3) + 1;
+  BitReader br(aSample->Data(), aSample->Size());
+
+  aDest.first_mb_in_slice = br.ReadUE();
+  aDest.slice_type = br.ReadUE();
+  aDest.pic_parameter_set_id = br.ReadUE();
+
+  const PPSData& pps = aParameterSet.PPSes[aDest.pic_parameter_set_id];
+  const SPSData& sps = aParameterSet.SPSes[pps.seq_parameter_set_id];
+
+  if (sps.separate_colour_plane_flag) {
+    aDest.colour_plane_id = br.ReadBits(2);
+  }
+  aDest.frame_num = br.ReadBits(sps.log2_max_frame_num);
+  if (!sps.frame_mbs_only_flag) {
+    aDest.field_pic_flag = br.ReadBit();
+    if (aDest.field_pic_flag) {
+      aDest.bottom_field_flag = br.ReadBit();
+    }
+  }
+
+  if (GetFrameType(aSample) == FrameType::I_FRAME) {
+    aDest.idr_pic_id = br.ReadUE();
+  }
+
+  if (sps.pic_order_cnt_type == 0) {
+    aDest.pic_order_cnt_lsb = br.ReadBits(sps.log2_max_pic_order_cnt_lsb);
+    if (pps.bottom_field_pic_order_in_frame_present_flag &&
+        !aDest.field_pic_flag) {
+      aDest.delta_pic_order_cnt_bottom = br.ReadSE();
+    }
+  }
+
+  if (sps.pic_order_cnt_type == 1 && !sps.delta_pic_order_always_zero_flag) {
+    aDest.delta_pic_order_cnt[0] = br.ReadSE();
+    if (pps.bottom_field_pic_order_in_frame_present_flag &&
+        !aDest.field_pic_flag) {
+      aDest.delta_pic_order_cnt[1] = br.ReadSE();
+    }
+  }
+
+  // Since we don't need the all data from slice header, we just parse the
+  // data we want and stop parsing.
+  return true;
+}
+
 /* static */ uint32_t
 H264::ComputeMaxRefFrames(const mozilla::MediaByteBuffer* aExtraData)
 {
   uint32_t maxRefFrames = 4;
   // Retrieve video dimensions from H264 SPS NAL.
   SPSData spsdata;
   if (DecodeSPSFromExtraData(aExtraData, spsdata)) {
     // max_num_ref_frames determines the size of the sliding window
--- a/media/libstagefright/binding/include/mp4_demuxer/H264.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/H264.h
@@ -29,16 +29,31 @@ enum NAL_TYPES {
     H264_NAL_FILLER_DATA     = 12,
     H264_NAL_SPS_EXT         = 13,
     H264_NAL_PREFIX          = 14,
     H264_NAL_AUXILIARY_SLICE = 19,
     H264_NAL_SLICE_EXT       = 20,
     H264_NAL_SLICE_EXT_DVC   = 21,
 };
 
+enum SLICE_TYPES {
+  // The value from 5 to 9 means all other slices of the current coded picture
+  // shall have the same slice type.
+  H264_P_SLICE      = 0,
+  H264_B_SLICE      = 1,
+  H264_I_SLICE      = 2,
+  H264_SP_SLICE     = 3,
+  H264_SI_SLICE     = 4,
+  H264_ALL_P_SLICE  = 5,
+  H264_ALL_B_SLICE  = 6,
+  H264_ALL_I_SLICE  = 7,
+  H264_ALL_SP_SLICE = 8,
+  H264_ALL_SI_SLICE = 9,
+};
+
 class BitReader;
 
 struct SPSData
 {
   /* Decoded Members */
   /*
     pic_width is the decoded width according to:
     pic_width = ((pic_width_in_mbs_minus1 + 1) * 16)
@@ -585,16 +600,486 @@ struct PPSData
   int8_t second_chroma_qp_index_offset;
 
   uint8_t scaling_matrix4x4[6][16];
   uint8_t scaling_matrix8x8[6][64];
 
   PPSData();
 };
 
+struct ReferencePictureListModification
+{
+  /*
+    H264 decoding parameters according to ITU-T H.264 (T-REC-H.264-201402-I/en)
+    http://www.itu.int/rec/T-REC-H.264-201402-I/en
+    7.4.3.1 Reference picture list modification semantics
+    H.7.3.3.1.1 Reference picture list MVC modification syntax
+   */
+  /*
+    ref_pic_list_modification_flag_l0 equal to 1 specifies that the syntax
+    element modification_of_pic_nums_idc is present for specifying reference
+    picture list 0. ref_pic_list_modification_flag_l0 equal to 0 specifies that
+    this syntax element is not present.
+   */
+  bool ref_pic_list_modification_flag_l0;
+  bool ref_pic_list_modification_flag_l1;
+
+  /*
+    modification_of_pic_nums_idc together with abs_diff_pic_num_minus1 or
+    long_term_pic_num specifies which of the reference pictures are re-mapped.
+    The values of modification_of_pic_nums_idc are specified in Table 7-7.
+   */
+  uint8_t modification_of_pic_nums_idc;
+
+  /*
+    abs_diff_pic_num_minus1 plus 1 specifies the absolute difference between
+    the picture number of the picture being moved to the current index in the
+    list and the picture number prediction value. abs_diff_pic_num_minus1 shall
+    be in the range of 0 to MaxPicNum − 1.
+    The allowed values of abs_diff_pic_num_minus1 are further restricted as
+    specified in clause 8.2.4.3.1.
+   */
+  uint32_t abs_diff_pic_num_minus1;
+
+  /*
+    long_term_pic_num specifies the long-term picture number of the picture
+    being moved to the current index in the list. When decoding a coded frame,
+    long_term_pic_num shall be equal to a LongTermPicNum assigned to one of the
+    reference frames or complementary reference field pairs marked as "used for
+    long-term reference". When decoding a coded field, long_term_pic_num shall
+    be equal to a LongTermPicNum assigned to one of the reference fields marked
+    as "used for long- term reference".
+  */
+  uint32_t long_term_pic_num;
+
+  /*
+    abs_diff_view_idx_minus1 plus 1 specifies the absolute difference between
+    the reference view index to put to the current index in the reference
+    picture list and the prediction value of the reference view index.
+   */
+  uint32_t abs_diff_view_idx_minus1;
+};
+
+struct PredWeightTable {
+  /*
+    H264 decoding parameters according to ITU-T H.264 (T-REC-H.264-201402-I/en)
+    http://www.itu.int/rec/T-REC-H.264-201402-I/en
+    7.4.3.2 Prediction weight table semantics
+   */
+  /*
+    luma_log2_weight_denom is the base 2 logarithm of the denominator for all
+    luma weighting factors. The value of luma_log2_weight_denom shall be in the
+    range of 0 to 7, inclusive.
+   */
+  uint8_t luma_log2_weight_denom;
+
+  /*
+    chroma_log2_weight_denom is the base 2 logarithm of the denominator for all
+    chroma weighting factors. The value of chroma_log2_weight_denom shall be in
+    the range of 0 to 7, inclusive.
+   */
+  uint8_t chroma_log2_weight_denom;
+
+  /*
+    luma_weight_l0/l1_flag equal to 1 specifies that weighting factors for the
+    luma component of list 0 prediction are present. luma_weight_l0/l1_flag
+    equal to 0 specifies that these weighting factors are not present.
+   */
+  bool luma_weight_l0_flag;
+  bool luma_weight_l1_flag;
+
+  /*
+    luma_weight_l0[ i ] is the weighting factor applied to the luma prediction
+    value for list 0 prediction using RefPicList0[ i ]. When luma_weight_l0_flag
+    is equal to 1, the value of luma_weight_l0[ i ] shall be in the range of
+    −128 to 127, inclusive. When luma_weight_l0_flag is equal to 0,
+    luma_weight_l0[ i ] shall be inferred to be equal to 2luma_log2_weight_denom
+    for RefPicList0[ i ].
+   */
+  int16_t luma_weight_l0[32][2];
+  int16_t luma_weight_l1[32][2];
+
+  /*
+    luma_offset_l0[ i ] is the additive offset applied to the luma prediction
+    value for list 0 prediction using RefPicList0[ i ]. The value of
+    luma_offset_l0[ i ] shall be in the range of −128 to 127, inclusive. When
+    luma_weight_l0_flag is equal to 0, luma_offset_l0[ i ] shall be inferred as
+    equal to 0 for RefPicList0[ i ].
+   */
+  int16_t luma_offset_l0[32][2];
+  int16_t luma_offset_l1[32][2];
+
+  /*
+    chroma_weight_l0/l1_flag equal to 1 specifies that weighting factors for the
+    chroma prediction values of list 0 prediction are present.
+    chroma_weight_l0/l1_flag equal to 0 specifies that these weighting factors
+    are not present.
+   */
+  bool chroma_weight_l0_flag;
+  bool chroma_weight_l1_flag;
+
+  /*
+    chroma_weight_l0[ i ][ j ] is the weighting factor applied to the chroma
+    prediction values for list 0 prediction using RefPicList0[ i ] with j equal
+    to 0 for Cb and j equal to 1 for Cr. When chroma_weight_l0_flag is equal to
+    1, the value of chroma_weight_l0[ i ][ j ] shall be in the range of −128 to
+    127, inclusive.
+    When chroma_weight_l0_flag is equal to 0, chroma_weight_l0[ i ][ j ] shall
+    be inferred to be equal to 2chroma_log2_weight_denom for RefPicList0[ i ].
+   */
+  int16_t chroma_weight_l0[32][2];
+  int16_t chroma_weight_l1[32][2];
+
+  /*
+   chroma_offset_l0[ i ][ j ] is the additive offset applied to the chroma
+   prediction values for list 0 prediction using RefPicList0[ i ] with j equal
+   to 0 for Cb and j equal to 1 for Cr. The value of chroma_offset_l0[ i ][ j ]
+   shall be in the range of −128 to 127, inclusive. When chroma_weight_l0_flag
+   is equal to 0, chroma_offset_l0[ i ][ j ] shall be inferred to be equal to 0
+   for RefPicList0[ i ].
+   */
+  int16_t chroma_offset_l0[32][2];
+  int16_t chroma_offset_l1[32][2];
+};
+
+struct DecodedReferencePictureMarking
+{
+  /*
+    H264 decoding parameters according to ITU-T H.264 (T-REC-H.264-201402-I/en)
+    http://www.itu.int/rec/T-REC-H.264-201402-I/en
+    7.4.3.3 Decoded reference picture marking semantics
+   */
+  /*
+    no_output_of_prior_pics_flag specifies how the previously-decoded pictures
+    in the decoded picture buffer are treated after decoding of an IDR picture.
+    See Annex C.
+   */
+  bool no_output_of_prior_pics_flag;
+
+  /*
+    long_term_reference_flag equal to 0 specifies that the MaxLongTermFrameIdx
+    variable is set equal to "no long-term frame indices" and that the IDR
+    picture is marked as "used for short-term reference".
+    long_term_reference_flag equal to 1 specifies that the MaxLongTermFrameIdx
+    variable is set equal to 0 and that the current IDR picture is marked "used
+    for long-term reference" and is assigned LongTermFrameIdx equal to 0. When
+    max_num_ref_frames is equal to 0, long_term_reference_flag shall be equal
+    to 0.
+   */
+  bool long_term_reference_flag;
+
+  /*
+    adaptive_ref_pic_marking_mode_flag selects the reference picture marking
+    mode of the currently decoded picture as specified in Table7-8.
+   */
+  bool adaptive_ref_pic_marking_mode_flag;
+
+  /*
+    memory_management_control_operation specifies a control operation to be
+    applied to affect the reference picture marking.
+    The memory_management_control_operation syntax element is followed by data
+    necessary for the operation specified by the value of
+    memory_management_control_operation. The values and control operations
+    associated with memory_management_control_operation are specified in
+    Table 7-9.
+   */
+  uint8_t memory_management_control_operation;
+
+  /*
+    difference_of_pic_nums_minus1 is used (memory_management_control_operation
+    equal to 3 or 1) to assign a long- term frame index to a short-term
+    reference picture or to mark a short-term reference picture as "unused for
+    reference". When the associated memory_management_control_operation is
+    processed by the decoding process, the resulting picture number derived
+    from difference_of_pic_nums_minus1 shall be a picture number assigned to
+    one of the reference pictures marked as "used for reference" and not
+    previously assigned to a long-term frame index.
+   */
+  uint32_t difference_of_pic_nums_minus1;
+
+  /*
+    long_term_pic_num is used (with memory_management_control_operation equal
+    to 2) to mark a long-term reference picture as "unused for reference". When
+    the associated memory_management_control_operation is processed by the
+    decoding process, long_term_pic_num shall be equal to a long-term picture
+    number assigned to one of the reference pictures that is currently marked
+    as "used for long-term reference"
+   */
+  uint32_t long_term_pic_num;
+
+  /*
+    long_term_frame_idx is used (with memory_management_control_operation equal
+    to 3 or 6) to assign a long-term frame index to a picture. When the
+    associated memory_management_control_operation is processed by the decoding
+    process, the value of long_term_frame_idx shall be in the range of 0 to
+    MaxLongTermFrameIdx, inclusive.
+   */
+  uint32_t long_term_frame_idx;
+
+  /*
+    max_long_term_frame_idx_plus1 minus 1 specifies the maximum value of
+    long-term frame index allowed for long-term reference pictures (until
+    receipt of another value of max_long_term_frame_idx_plus1). The value of
+    max_long_term_frame_idx_plus1 shall be in the range of 0 to
+    max_num_ref_frames, inclusive.
+   */
+  uint32_t max_long_term_frame_idx_plus1;
+};
+
+struct SliceHeader
+{
+  /*
+    H264 decoding parameters according to ITU-T H.264 (T-REC-H.264-201402-I/en)
+    http://www.itu.int/rec/T-REC-H.264-201402-I/en
+    7.4.3 Slice header semantics
+   */
+  /*
+    first_mb_in_slice specifies the address of the first macroblock in the slice.
+   */
+  uint8_t first_mb_in_slice;
+
+  /*
+    slice_type specifies the coding type of the slice according to Table 7-6.
+   */
+  uint8_t slice_type;
+
+  /*
+    pic_parameter_set_id identifies the picture parameter set that is referred
+    to in the slice header. The value of pic_parameter_set_id shall be in the
+    range of 0 to 255, inclusive.
+   */
+  uint8_t pic_parameter_set_id;
+
+  /*
+    colour_plane_id specifies the colour plane associated with the current
+    slice RBSP when separate_colour_plane_flag is equal to 1. The value of
+    colour_plane_id shall be in the range of 0 to 2, inclusive. colour_plane_id
+    equal to 0, 1, and 2 correspond to the Y, Cb, and Cr planes, respectively.
+   */
+  uint8_t colour_plane_id : 2;
+
+  /*
+    frame_num is used as an identifier for pictures and shall be represented by
+    log2_max_frame_num_minus4 + 4 bits in the bitstream.
+   */
+  uint32_t frame_num;
+
+  bool field_pic_flag;
+  bool bottom_field_flag;
+
+  /*
+    idr_pic_id identifies an IDR picture when dependency_id is equal to the
+    maximum present value of dependency_id in the VCL NAL units of the current
+    coded picture. The value of idr_pic_id shall be in the range of 0 to 65535,
+    inclusive.
+
+    When two consecutive access units in decoding order are both IDR access
+    units, the value of idr_pic_id in the slices of the target dependency
+    representation in the primary coded pictures of the first such IDR access
+    unit shall differ from the idr_pic_id in the slices of the target dependency
+    representation in the primary coded pictures of the second such IDR access
+    unit.
+   */
+  uint16_t idr_pic_id;
+
+  /*
+    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.
+
+    The maximum value of MaxPicOrderCntLsb is 2^16.
+   */
+  uint16_t pic_order_cnt_lsb;
+
+  /*
+    delta_pic_order_cnt_bottom specifies the picture order count difference
+    between the bottom field and the top field of a coded frame as follows:
+
+    – If the current picture includes a memory_management_control_operation equal
+      to 5, the value of delta_pic_order_cnt_bottom shall be in the range of
+      ( 1 − MaxPicOrderCntLsb ) to 2^31 − 1, inclusive.
+    – Otherwise (the current picture does not include a
+      memory_management_control_operation equal to 5), the value of
+      delta_pic_order_cnt_bottom shall be in the range of −2^31 + 1 to 2^31 − 1,
+      inclusive.
+
+    When this syntax element is not present in the bitstream for the current
+    slice, it shall be inferred to be equal to 0.
+   */
+  int32_t delta_pic_order_cnt_bottom;
+
+  /*
+    delta_pic_order_cnt[0] specifies the picture order count difference from
+    the expected picture order count for the top field of a coded frame or for
+    a coded field as specified in clause 8.2.1.
+
+    The value of delta_pic_order_cnt[0] shall be in the range of −2^31 + 1 to
+    2^31 − 1, inclusive. When this syntax element is not present in the
+    bitstream for the current slice, it shall be inferred to be equal to 0.
+
+    delta_pic_order_cnt[1] specifies the picture order count difference from
+    the expected picture order count for the bottom field of a coded frame
+    specified in clause 8.2.1.
+
+    The value of delta_pic_order_cnt[1] shall be in the range of −2^31 + 1 to
+    2^31 − 1, inclusive. When this syntax element is not present in the
+    bitstream for the current slice, it shall be inferred to be equal to 0.
+   */
+  int32_t delta_pic_order_cnt[2];
+
+  /*
+    redundant_pic_cnt shall be equal to 0 for slices and slice data partitions
+    belonging to the primary coded picture. The value of redundant_pic_cnt
+    shall be greater than 0 for coded slices or coded slice data partitions of
+    a redundant coded picture. When redundant_pic_cnt is not present in the
+    bitstream, its value shall be inferred to be equal to 0. The value of
+    redundant_pic_cnt shall be in the range of 0 to 127, inclusive.
+   */
+  uint8_t redundant_pic_cnt;
+
+  /*
+    direct_spatial_mv_pred_flag specifies the method used in the decoding
+    process to derive motion vectors and reference indices for inter prediction.
+   */
+  bool direct_spatial_mv_pred_flag;
+
+  /*
+    num_ref_idx_active_override_flag equal to 1 specifies that the syntax
+    element num_ref_idx_l0_active_minus1 is present for P, SP, and B slices and
+    that the syntax element num_ref_idx_l1_active_minus1 is present for B slices.
+
+    num_ref_idx_active_override_flag equal to 0 specifies that the syntax
+    elements num_ref_idx_l0_active_minus1 and num_ref_idx_l1_active_minus1 are
+    not present.
+   */
+  bool num_ref_idx_active_override_flag;
+
+  /*
+    num_ref_idx_l0_active_minus1 specifies the maximum reference index for
+    reference picture list 0 that shall be used to decode the slice.
+    When the current slice is a P, SP, or B slice and num_ref_idx_l0_active_minus1
+    is not present, num_ref_idx_l0_active_minus1 shall be inferred to be equal
+    to num_ref_idx_l0_default_active_minus1.
+    If field_pic_flag is equal to 0, num_ref_idx_l0_active_minus1 shall be in
+    the range of 0 to 15, inclusive. Otherwise (field_pic_flag is equal to 1),
+    num_ref_idx_l0_active_minus1 shall be in the range of 0 to 31, inclusive
+  */
+  uint8_t num_ref_idx_l0_active_minus1;
+
+  /*
+    num_ref_idx_l1_active_minus1 specifies the maximum reference index for
+    reference picture list 1 that shall be used to decode the slice.
+    When the current slice is a B slice and num_ref_idx_l1_active_minus1 is not
+    present, num_ref_idx_l1_active_minus1 shall be inferred to be equal to
+    num_ref_idx_l1_default_active_minus1.
+    The range of num_ref_idx_l1_active_minus1 is constrained as specified in
+    the semantics for num_ref_idx_l0_active_minus1 with l0 and list 0 replaced
+    by l1 and list 1, respectively.
+   */
+  uint8_t num_ref_idx_l1_active_minus1;
+
+
+  PredWeightTable pwt;
+  ReferencePictureListModification rplm;
+  DecodedReferencePictureMarking drpm;
+
+  /*
+    specifies the index for determining the initialisation table used in the
+    initialisation process for context variables. The value of cabac_init_idc
+    shall be in the range of 0 to 2, inclusive.
+   */
+  uint8_t cabac_init_idc : 2;
+
+  /*
+    slice_qp_delta specifies the initial value of QPY to be used for all the
+    macroblocks in the slice until modified by the value of mb_qp_delta in the
+    macroblock layer. The initial QPY quantisation parameter for the slice is
+    computed as SliceQPY = 26 + pic_init_qp_minus26 + slice_qp_delta
+    The value of slice_qp_delta shall be limited such that SliceQPY is in the
+    range of −QpBdOffsetY to +51, inclusive.
+
+    QpBdOffsetY = 6 * bit_depth_luma_minus8, bit_depth_luma_minus8 shall be in
+    the range of 0 to 6, inclusive.
+   */
+  int8_t slice_qp_delta;
+
+  /*
+    sp_for_switch_flag specifies the decoding process to be used to decode P
+    macroblocks in an SP slice as follows:
+    – If sp_for_switch_flag is equal to 0, the P macroblocks in the SP slice
+      shall be decoded using the SP decoding process for non-switching pictures
+      as specified in clause 8.6.1.
+    – Otherwise (sp_for_switch_flag is equal to 1), the P macroblocks in the SP
+      slice shall be decoded using the SP and SI decoding process for switching
+      pictures as specified in clause 8.6.2.
+   */
+  bool sp_for_switch_flag;
+
+  /*
+    slice_qs_delta specifies the value of QSY for all the macroblocks in SP and
+    SI slices. The QSY quantisation parameter for the slice is computed as
+    QSY = 26 + pic_init_qs_minus26 + slice_qs_delta (7-31)
+    The value of slice_qs_delta shall be limited such that QSY is in the range
+    of 0 to 51, inclusive.
+   */
+  uint8_t slice_qs_delta;
+
+  /*
+    disable_deblocking_filter_idc specifies whether the operation of the
+    deblocking filter shall be disabled across some block edges of the slice
+    and specifies for which edges the filtering is disabled. When
+    disable_deblocking_filter_idc is not present in the slice header, the value
+    of disable_deblocking_filter_idc shall be inferred to be equal to 0.
+    The value of disable_deblocking_filter_idc shall be in the range of 0 to 2,
+    inclusive.
+   */
+  uint8_t disable_deblocking_filter_idc : 2;
+
+  /*
+    slice_alpha_c0_offset_div2 specifies the offset used in accessing the α and
+    tC0 deblocking filter tables for filtering operations controlled by the
+    macroblocks within the slice. From this value, the offset that shall be
+    applied when addressing these tables shall be computed as
+    FilterOffsetA = slice_alpha_c0_offset_div2 << 1 (7-32)
+    The value of slice_alpha_c0_offset_div2 shall be in the range of −6 to +6,
+    inclusive. When slice_alpha_c0_offset_div2 is not present in the slice
+    header, the value of slice_alpha_c0_offset_div2 shall be inferred to be
+    equal to 0.
+   */
+  int8_t slice_alpha_c0_offset_div2;
+
+  /*
+    slice_beta_offset_div2 specifies the offset used in accessing the β
+    deblocking filter table for filtering operations controlled by the
+    macroblocks within the slice. From this value, the offset that is applied
+    when addressing the β table of the deblocking filter shall be computed as
+    FilterOffsetB = slice_beta_offset_div2 << 1 (7-33)
+    The value of slice_beta_offset_div2 shall be in the range of −6 to +6,
+    inclusive. When slice_beta_offset_div2 is not present in the slice header
+    the value of slice_beta_offset_div2 shall be inferred to be equal to 0.
+   */
+  int8_t slice_beta_offset_div2;
+
+  /*
+    slice_group_change_cycle is used to derive the number of slice group map
+    units in slice group 0 when slice_group_map_type is equal to 3, 4, or 5, as
+    specified by
+    MapUnitsInSliceGroup0 = Min( slice_group_change_cycle * SliceGroupChangeRate,
+    PicSizeInMapUnits )
+
+    The value of slice_group_change_cycle is represented in the bitstream by
+    the following number of bits
+    Ceil( Log2( PicSizeInMapUnits   SliceGroupChangeRate + 1 ) )
+   */
+  uint32_t slice_group_change_cycle;
+};
+
 typedef AutoTArray<SPSData, MAX_SPS_COUNT> SPSDataSet;
 typedef AutoTArray<PPSData, MAX_PPS_COUNT> PPSDataSet;
 
 struct H264ParametersSet
 {
   SPSDataSet SPSes;
   PPSDataSet PPSes;
 };
@@ -614,16 +1099,20 @@ public:
   static bool EnsureSPSIsSane(SPSData& aSPS);
 
   static bool DecodeSPSFromExtraData(const mozilla::MediaByteBuffer* aExtraData,
                                      SPSData& aDest);
 
   static bool DecodeParametersSet(const mozilla::MediaByteBuffer* aExtraData,
                                   H264ParametersSet& aDest);
 
+  static bool DecodeSliceHeader(const mozilla::MediaRawData* aSample,
+                                const H264ParametersSet& aParameterSet,
+                                SliceHeader& aDest);
+
   // If the given aExtraData is valid, return the aExtraData.max_num_ref_frames
   // clamped to be in the range of [4, 16]; otherwise return 4.
   static uint32_t ComputeMaxRefFrames(
     const mozilla::MediaByteBuffer* aExtraData);
 
   enum class FrameType
   {
     I_FRAME,