diff --git a/gst-libs/gst/codecparsers/gsth264parser.c b/gst-libs/gst/codecparsers/gsth264parser.c index 4b7040997b..4c3df27e1b 100644 --- a/gst-libs/gst/codecparsers/gsth264parser.c +++ b/gst-libs/gst/codecparsers/gsth264parser.c @@ -743,60 +743,56 @@ error: } static gboolean -slice_parse_ref_pic_list_modification (GstH264SliceHdr * slice, NalReader * nr) +slice_parse_ref_pic_list_modification_1 (GstH264SliceHdr * slice, + NalReader * nr, guint list) { - GST_DEBUG ("parsing \"Reference picture list modification\""); + GstH264RefPicListModification *entries; + guint8 *ref_pic_list_modification_flag; + guint32 modification_of_pic_nums_idc; + guint i = 0; - if (!GST_H264_IS_I_SLICE (slice) && !GST_H264_IS_SI_SLICE (slice)) { - guint8 ref_pic_list_modification_flag_l0; - guint32 modification_of_pic_nums_idc; - - READ_UINT8 (nr, ref_pic_list_modification_flag_l0, 1); - if (ref_pic_list_modification_flag_l0) - do { - READ_UE (nr, modification_of_pic_nums_idc); - if (modification_of_pic_nums_idc == 0 - || modification_of_pic_nums_idc == 1) { - guint32 abs_diff_pic_num_minus1 G_GNUC_UNUSED; - - READ_UE_ALLOWED (nr, abs_diff_pic_num_minus1, 0, - slice->max_pic_num - 1); - } else if (modification_of_pic_nums_idc == 2) { - guint32 long_term_pic_num; - - READ_UE (nr, long_term_pic_num); - } - } while (modification_of_pic_nums_idc != 3); + if (list == 0) { + entries = slice->ref_pic_list_modification_l0; + ref_pic_list_modification_flag = &slice->ref_pic_list_modification_flag_l0; + } else { + entries = slice->ref_pic_list_modification_l1; + ref_pic_list_modification_flag = &slice->ref_pic_list_modification_flag_l1; } - if (GST_H264_IS_B_SLICE (slice)) { - guint8 ref_pic_list_modification_flag_l1; - guint32 modification_of_pic_nums_idc; - - READ_UINT8 (nr, ref_pic_list_modification_flag_l1, 1); - if (ref_pic_list_modification_flag_l1) - do { - READ_UE (nr, modification_of_pic_nums_idc); - if (modification_of_pic_nums_idc == 0 - || modification_of_pic_nums_idc == 1) { - guint32 abs_diff_num_minus1; - - READ_UE (nr, abs_diff_num_minus1); - } else if (modification_of_pic_nums_idc == 2) { - guint32 long_term_pic_num; - - READ_UE (nr, long_term_pic_num); - } - } while (modification_of_pic_nums_idc != 3); - } + READ_UINT8 (nr, *ref_pic_list_modification_flag, 1); + do { + READ_UE (nr, modification_of_pic_nums_idc); + if (modification_of_pic_nums_idc == 0 || modification_of_pic_nums_idc == 1) { + READ_UE_ALLOWED (nr, entries[i].value.abs_diff_pic_num_minus1, 0, + slice->max_pic_num - 1); + } else if (modification_of_pic_nums_idc == 2) { + READ_UE (nr, entries[i].value.long_term_pic_num); + } + } while (modification_of_pic_nums_idc != 3); return TRUE; error: - GST_WARNING ("error parsing \"Reference picture list modification\""); + GST_WARNING ("error parsing \"Reference picture list %u modification\"", + list); return FALSE; } +static gboolean +slice_parse_ref_pic_list_modification (GstH264SliceHdr * slice, NalReader * nr) +{ + if (!GST_H264_IS_I_SLICE (slice) && !GST_H264_IS_SI_SLICE (slice)) { + if (!slice_parse_ref_pic_list_modification_1 (slice, nr, 0)) + return FALSE; + } + + if (GST_H264_IS_B_SLICE (slice)) { + if (!slice_parse_ref_pic_list_modification_1 (slice, nr, 1)) + return FALSE; + } + return TRUE; +} + static gboolean gst_h264_slice_parse_dec_ref_pic_marking (GstH264SliceHdr * slice, GstH264NalUnit * nalu, NalReader * nr) diff --git a/gst-libs/gst/codecparsers/gsth264parser.h b/gst-libs/gst/codecparsers/gsth264parser.h index 2dfe2d7b63..4daf3e1717 100644 --- a/gst-libs/gst/codecparsers/gsth264parser.h +++ b/gst-libs/gst/codecparsers/gsth264parser.h @@ -168,24 +168,25 @@ typedef enum GST_H264_S_SI_SLICE = 9 } GstH264SliceType; -typedef struct _GstH264NalParser GstH264NalParser; +typedef struct _GstH264NalParser GstH264NalParser; -typedef struct _GstH264NalUnit GstH264NalUnit; +typedef struct _GstH264NalUnit GstH264NalUnit; -typedef struct _GstH264SPS GstH264SPS; -typedef struct _GstH264PPS GstH264PPS; -typedef struct _GstH264HRDParams GstH264HRDParams; -typedef struct _GstH264VUIParams GstH264VUIParams; +typedef struct _GstH264SPS GstH264SPS; +typedef struct _GstH264PPS GstH264PPS; +typedef struct _GstH264HRDParams GstH264HRDParams; +typedef struct _GstH264VUIParams GstH264VUIParams; -typedef struct _GstH264DecRefPicMarking GstH264DecRefPicMarking; -typedef struct _GstH264RefPicMarking GstH264RefPicMarking; -typedef struct _GstH264PredWeightTable GstH264PredWeightTable; -typedef struct _GstH264SliceHdr GstH264SliceHdr; +typedef struct _GstH264RefPicListModification GstH264RefPicListModification; +typedef struct _GstH264DecRefPicMarking GstH264DecRefPicMarking; +typedef struct _GstH264RefPicMarking GstH264RefPicMarking; +typedef struct _GstH264PredWeightTable GstH264PredWeightTable; +typedef struct _GstH264SliceHdr GstH264SliceHdr; -typedef struct _GstH264ClockTimestamp GstH264ClockTimestamp; -typedef struct _GstH264PicTiming GstH264PicTiming; -typedef struct _GstH264BufferingPeriod GstH264BufferingPeriod; -typedef struct _GstH264SEIMessage GstH264SEIMessage; +typedef struct _GstH264ClockTimestamp GstH264ClockTimestamp; +typedef struct _GstH264PicTiming GstH264PicTiming; +typedef struct _GstH264BufferingPeriod GstH264BufferingPeriod; +typedef struct _GstH264SEIMessage GstH264SEIMessage; /** * GstH264NalUnit: @@ -485,6 +486,18 @@ struct _GstH264PPS gboolean valid; }; +struct _GstH264RefPicListModification +{ + guint8 modification_of_pic_nums_idc; + union + { + /* if modification_of_pic_nums_idc == 0 || 1 */ + guint32 abs_diff_pic_num_minus1; + /* if modification_of_pic_nums_idc == 2 */ + guint32 long_term_pic_num; + } value; +}; + struct _GstH264PredWeightTable { guint8 luma_log2_weight_denom; @@ -559,6 +572,11 @@ struct _GstH264SliceHdr guint8 num_ref_idx_l0_active_minus1; guint8 num_ref_idx_l1_active_minus1; + guint8 ref_pic_list_modification_flag_l0; + GstH264RefPicListModification ref_pic_list_modification_l0[32]; + guint8 ref_pic_list_modification_flag_l1; + GstH264RefPicListModification ref_pic_list_modification_l1[32]; + GstH264PredWeightTable pred_weight_table; /* if nal_unit.ref_idc != 0 */ GstH264DecRefPicMarking dec_ref_pic_marking;