From faad764c7f255f4c8bc8a910eed73dc2a8671675 Mon Sep 17 00:00:00 2001
From: CaiYuHan <240947104@qq.com>
Date: Thu, 23 Sep 2021 21:23:43 +0800
Subject: [PATCH] libavcodec/:Add the parsing procedure of SVC decoding
 function based on Temporal scalability for H.264/AVC

Signed-off-by: CaiYuHan <240947104@qq.com>
---
 libavcodec/h2645_parse.c |  33 +++++-
 libavcodec/h2645_parse.h |  13 +++
 libavcodec/h264_parser.c |  49 +++++++-
 libavcodec/h264_ps.c     |  51 +++++++++
 libavcodec/h264_ps.h     |  25 +++-
 libavcodec/h264_refs.c   |  40 ++++++-
 libavcodec/h264_slice.c  | 241 ++++++++++++++++++++++++++++++++++++++-
 libavcodec/h264dec.c     |  17 +++
 libavcodec/h264dec.h     |   6 +-
 9 files changed, 462 insertions(+), 13 deletions(-)
 mode change 100644 => 100755 libavcodec/h2645_parse.c
 mode change 100644 => 100755 libavcodec/h2645_parse.h
 mode change 100644 => 100755 libavcodec/h264_parser.c
 mode change 100644 => 100755 libavcodec/h264_ps.c
 mode change 100644 => 100755 libavcodec/h264_ps.h
 mode change 100644 => 100755 libavcodec/h264_refs.c
 mode change 100644 => 100755 libavcodec/h264_slice.c
 mode change 100644 => 100755 libavcodec/h264dec.c
 mode change 100644 => 100755 libavcodec/h264dec.h

diff --git a/libavcodec/h2645_parse.c b/libavcodec/h2645_parse.c
old mode 100644
new mode 100755
index 6fbe97a..2d13690
--- a/libavcodec/h2645_parse.c
+++ b/libavcodec/h2645_parse.c
@@ -319,7 +319,38 @@ static int h264_parse_nal_header(H2645NAL *nal, void *logctx)
 
     nal->ref_idc = get_bits(gb, 2);
     nal->type    = get_bits(gb, 5);
-
+#if TMP_SVC_DEC_H264
+    if(nal->type == H264_NAL_EXTEN_SLICE || nal->type == H264_NAL_DEPTH_EXTEN_SLICE)
+	{
+		nal->svc_ext_flag = get_bits1(gb);
+        if( nal->svc_ext_flag )
+        {
+            nal->idr_flag = get_bits1(gb);
+            nal->priority_id = get_bits(gb, 6);
+            nal->no_inter_layer_pred_flag = get_bits1(gb);
+            nal->dependency_id	= get_bits(gb, 3);
+            nal->quality_id = get_bits(gb, 4);
+            nal->itemporal_id = get_bits(gb, 3);
+            nal->use_ref_base_pic_flag = get_bits1(gb);
+            nal->discardable_flag = get_bits1(gb);
+            nal->output_flag = get_bits1(gb);
+            skip_bits(gb,2);
+        }
+        else
+        {
+            nal->idr_flag = -1;
+            nal->priority_id = -1;
+            nal->no_inter_layer_pred_flag = -1;
+            nal->dependency_id	= -1;
+            nal->quality_id = -1;
+            nal->itemporal_id = -1;
+            nal->use_ref_base_pic_flag = -1;
+            nal->discardable_flag = -1;
+            nal->output_flag = -1;
+            skip_bits(gb, 23);
+        }
+	}
+#endif
     av_log(logctx, AV_LOG_DEBUG,
            "nal_unit_type: %d(%s), nal_ref_idc: %d\n",
            nal->type, h264_nal_unit_name(nal->type), nal->ref_idc);
diff --git a/libavcodec/h2645_parse.h b/libavcodec/h2645_parse.h
old mode 100644
new mode 100755
index 3e47f86..6799bbb
--- a/libavcodec/h2645_parse.h
+++ b/libavcodec/h2645_parse.h
@@ -68,6 +68,19 @@ typedef struct H2645NAL {
      * H.264 only, nal_ref_idc
      */
     int ref_idc;
+#if TMP_SVC_DEC_H264
+    int svc_ext_flag;
+    int idr_flag;
+    int priority_id;
+    int no_inter_layer_pred_flag;
+    int dependency_id;
+    int quality_id;
+    int itemporal_id;
+    int use_ref_base_pic_flag;
+    int discardable_flag;
+    int output_flag;
+    int reserved_three_2bits;
+#endif
 } H2645NAL;
 
 typedef struct H2645RBSP {
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
old mode 100644
new mode 100755
index aacd44c..d7b3d12
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -108,14 +108,28 @@ static int h264_find_frame_end(H264ParseContext *p, const uint8_t *buf,
                 state >>= 1;           // 2->1, 1->0, 0->0
         } else if (state <= 5) {
             int nalu_type = buf[i] & 0x1F;
+#if TMP_SVC_DEC_H264
             if (nalu_type == H264_NAL_SEI || nalu_type == H264_NAL_SPS ||
-                nalu_type == H264_NAL_PPS || nalu_type == H264_NAL_AUD) {
+                nalu_type == H264_NAL_PPS || nalu_type == H264_NAL_AUD ||
+                nalu_type == H264_NAL_SUB_SPS)
+#else
+            if (nalu_type == H264_NAL_SEI || nalu_type == H264_NAL_SPS ||
+                nalu_type == H264_NAL_PPS || nalu_type == H264_NAL_AUD)
+#endif
+			{
                 if (pc->frame_start_found) {
                     i++;
                     goto found;
                 }
-            } else if (nalu_type == H264_NAL_SLICE || nalu_type == H264_NAL_DPA ||
-                       nalu_type == H264_NAL_IDR_SLICE) {
+            }
+#if TMP_SVC_DEC_H264
+            else if (nalu_type == H264_NAL_SLICE || nalu_type == H264_NAL_DPA ||
+                       nalu_type == H264_NAL_IDR_SLICE || nalu_type == H264_NAL_EXTEN_SLICE)
+#else
+			else if (nalu_type == H264_NAL_SLICE || nalu_type == H264_NAL_DPA ||
+                       nalu_type == H264_NAL_IDR_SLICE)
+#endif
+			{
                 state += 8;
                 continue;
             }
@@ -255,7 +269,9 @@ static inline int parse_nal_units(AVCodecParserContext *s,
     int q264 = buf_size >=4 && !memcmp("Q264", buf, 4);
     int field_poc[2];
     int ret;
-
+#if TMP_SVC_DEC_H264
+    int idr_svc;
+#endif
     /* set some sane default values */
     s->pict_type         = AV_PICTURE_TYPE_I;
     s->key_frame         = 0;
@@ -320,7 +336,30 @@ static inline int parse_nal_units(AVCodecParserContext *s,
         get_bits1(&nal.gb);
         nal.ref_idc = get_bits(&nal.gb, 2);
         nal.type    = get_bits(&nal.gb, 5);
-
+#if TMP_SVC_DEC_H264
+        if(nal.type == H264_NAL_EXTEN_SLICE || nal.type == H264_NAL_DEPTH_EXTEN_SLICE)
+        {
+            nal.svc_ext_flag = get_bits1(&nal.gb);
+            if(nal.svc_ext_flag)
+            	idr_svc = get_bits1(&nal.gb);
+            else
+            	idr_svc = get_bits1(&nal.gb);
+            if((nal.type == H264_NAL_EXTEN_SLICE && idr_svc == 1) ||
+               (nal.type == H264_NAL_DEPTH_EXTEN_SLICE && idr_svc == 0))
+            {
+            	nal.type = H264_NAL_IDR_SLICE;
+            }
+            else
+            {
+            	nal.type = H264_NAL_SLICE;
+            }
+            skip_bits(&nal.gb, 22);
+        }
+        else if(nal.type == H264_NAL_SUB_SPS)
+        {
+            nal.type = H264_NAL_SPS;
+        }
+#endif
         switch (nal.type) {
         case H264_NAL_SPS:
             ff_h264_decode_seq_parameter_set(&nal.gb, avctx, &p->ps, 0);
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c
old mode 100644
new mode 100755
index e21c2b5..8643055
--- a/libavcodec/h264_ps.c
+++ b/libavcodec/h264_ps.c
@@ -627,6 +627,10 @@ int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx,
     /* check if this is a repeat of an already parsed SPS, then keep the
      * original one.
      * otherwise drop all PPSes that depend on it */
+#if TMP_SVC_DEC_H264
+	ps->sps_id = sps_id;
+#endif
+
     if (ps->sps_list[sps_id] &&
         !memcmp(ps->sps_list[sps_id]->data, sps_buf->data, sps_buf->size)) {
         av_buffer_unref(&sps_buf);
@@ -641,7 +645,54 @@ fail:
     av_buffer_unref(&sps_buf);
     return AVERROR_INVALIDDATA;
 }
+#if TMP_SVC_DEC_H264
+void ff_h264_decode_sps_svc_ext(GetBitContext *gb, SPS *sps)
+{
+	int chromaArrayType = sps->chroma_format_idc;
+	sps->inter_layer_deblocking_filter_control_present_flag = get_bits1(gb);
+	sps->extended_spatial_scalability_idc = get_bits(gb, 2);
+	if (chromaArrayType == 1 || chromaArrayType == 2) {
+		sps->chroma_phase_x_plus1_flag = get_bits1(gb);
+	}
+	if (chromaArrayType == 1) {
+		sps->chroma_phase_y_plus1 = get_bits(gb, 2);
+	}
+	if (sps->extended_spatial_scalability_idc == 1) {
+		if (chromaArrayType > 0) {
+			sps->seq_ref_layer_chroma_phase_x_plus1_flag = get_bits1(gb);
+			sps->seq_ref_layer_chroma_phase_y_plus1 = get_bits(gb, 2);
+		}
+		sps->seq_scaled_ref_layer_left_offset = get_se_golomb(gb);
+		sps->seq_scaled_ref_layer_top_offset = get_se_golomb(gb);
+		sps->seq_scaled_ref_layer_right_offset = get_se_golomb(gb);
+		sps->seq_scaled_ref_layer_bottom_offset = get_se_golomb(gb);
+	}
+	sps->seq_tcoeff_level_prediction_flag = get_bits1(gb);
+	if (sps->seq_tcoeff_level_prediction_flag) {
+		sps->adaptive_tcoeff_level_prediction_flag = get_bits1(gb);
+	}
+	sps->slice_header_restriction_flag = get_bits1(gb);
+}
 
+int ff_h264_decode_subset_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx,
+                                     H264ParamSets *ps, int ignore_truncation)
+{
+	SPS *sps;
+	int ret;
+	ret = ff_h264_decode_seq_parameter_set(gb, avctx, ps, ignore_truncation);
+	if(ret < 0)
+		return -1;
+
+	sps = (SPS*)ps->sps_list[ps->sps_id]->data;
+
+	if (sps->profile_idc == 83 || sps->profile_idc == 86) {
+		ff_h264_decode_sps_svc_ext(gb, sps);
+		sps->svc_vui_parameters_present_flag = get_bits1(gb);
+	}
+
+	return 0;
+}
+#endif
 static void init_dequant8_coeff_table(PPS *pps, const SPS *sps)
 {
     int i, j, q, x;
diff --git a/libavcodec/h264_ps.h b/libavcodec/h264_ps.h
old mode 100644
new mode 100755
index 3f1ab72..a615224
--- a/libavcodec/h264_ps.h
+++ b/libavcodec/h264_ps.h
@@ -103,6 +103,22 @@ typedef struct SPS {
     int constraint_set_flags;             ///< constraint_set[0-3]_flag
     uint8_t data[4096];
     size_t data_size;
+#if TMP_SVC_DEC_H264
+	u_int8_t inter_layer_deblocking_filter_control_present_flag;
+	int extended_spatial_scalability_idc;
+	u_int8_t chroma_phase_x_plus1_flag;
+	int chroma_phase_y_plus1;
+	u_int8_t seq_ref_layer_chroma_phase_x_plus1_flag;
+	int seq_ref_layer_chroma_phase_y_plus1;
+	int seq_scaled_ref_layer_left_offset;
+	int seq_scaled_ref_layer_top_offset;
+	int seq_scaled_ref_layer_right_offset;
+	int seq_scaled_ref_layer_bottom_offset;
+	u_int8_t seq_tcoeff_level_prediction_flag;
+	u_int8_t adaptive_tcoeff_level_prediction_flag;
+	u_int8_t slice_header_restriction_flag;
+	u_int8_t svc_vui_parameters_present_flag;
+#endif
 } SPS;
 
 /**
@@ -148,7 +164,9 @@ typedef struct H264ParamSets {
     /* currently active parameters sets */
     const PPS *pps;
     const SPS *sps;
-
+#if TMP_SVC_DEC_H264
+	int sps_id;
+#endif
     int overread_warning_printed[2];
 } H264ParamSets;
 
@@ -158,6 +176,11 @@ typedef struct H264ParamSets {
 int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx,
                                      H264ParamSets *ps, int ignore_truncation);
 
+#if TMP_SVC_DEC_H264
+void ff_h264_decode_sps_svc_ext(GetBitContext *gb, SPS *sps);
+int ff_h264_decode_subset_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx,
+                                     H264ParamSets *ps, int ignore_truncation);
+#endif
 /**
  * Decode PPS
  */
diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c
old mode 100644
new mode 100755
index dae8bd2..d701d7b
--- a/libavcodec/h264_refs.c
+++ b/libavcodec/h264_refs.c
@@ -837,8 +837,12 @@ int ff_h264_decode_ref_pic_marking(H264SliceContext *sl, GetBitContext *gb,
     int i;
     MMCO *mmco = sl->mmco;
     int nb_mmco = 0;
-
-    if (nal->type == H264_NAL_IDR_SLICE) { // FIXME fields
+#if TMP_SVC_DEC_H264
+    if (nal->type == H264_NAL_IDR_SLICE || (nal->type == H264_NAL_EXTEN_SLICE && nal->svc_ext_flag == 1 && nal->idr_flag == 1))
+#else
+    if (nal->type == H264_NAL_IDR_SLICE)
+#endif
+	{ // FIXME fields
         skip_bits1(gb); // broken_link
         if (get_bits1(gb)) {
             mmco[0].opcode   = MMCO_LONG;
@@ -892,3 +896,35 @@ int ff_h264_decode_ref_pic_marking(H264SliceContext *sl, GetBitContext *gb,
 
     return 0;
 }
+#if TMP_SVC_DEC_H264
+int ff_h264_decode_ref_base_pic_marking(H264SliceContext *sl, GetBitContext *gb,
+                                   const H2645NAL *nal, void *logctx)
+{
+    int i;
+    MMCO *mmco = sl->mmco;
+    int nb_mmco = 0;
+
+    sl->explicit_ref_marking = get_bits1(gb);
+    if (sl->explicit_ref_marking) {
+        for (i = 0; i < MAX_MMCO_COUNT; i++) {
+            MMCOOpcode opcode = get_ue_golomb_31(gb);
+
+            if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_LONG2UNUSED ) {
+                unsigned int long_arg = get_ue_golomb_31(gb);
+            }
+
+            if (opcode > (unsigned) MMCO_LONG) {
+                av_log(logctx, AV_LOG_ERROR,
+                       "illegal memory management control operation %d\n",
+                       opcode);
+                return -1;
+            }
+            if (opcode == MMCO_END)
+                break;
+        }
+        nb_mmco = i;
+    }
+
+    return 0;
+}
+#endif
\ No newline at end of file
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
old mode 100644
new mode 100755
index 62f7a61..ac6b7df
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1946,7 +1946,227 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl,
 
     return 0;
 }
+#if TMP_SVC_DEC_H264
+static int h264_slice_header_in_scalable_ext_parse(const H264Context *h, H264SliceContext *sl,
+                                   const H2645NAL *nal)
+{
+    const SPS *sps;
+    const PPS *pps;
+    int ret;
+    unsigned int slice_type, tmp, i;
+    int field_pic_flag, bottom_field_flag;
+    int first_slice = sl == h->slice_ctx && !h->current_slice;
+    int picture_structure;
+    int base_pred_weight_table_flag;
+    int store_ref_base_pic_flag;
+
+    if (first_slice)
+        av_assert0(!h->setup_finished);
+
+    sl->first_mb_addr = get_ue_golomb_long(&sl->gb);
+
+    slice_type = get_ue_golomb_31(&sl->gb);
+    if (slice_type > 9) {
+        av_log(h->avctx, AV_LOG_ERROR,
+               "slice type %d too large at %d\n",
+               slice_type, sl->first_mb_addr);
+        return AVERROR_INVALIDDATA;
+    }
+    if (slice_type > 4) {
+        slice_type -= 5;
+        sl->slice_type_fixed = 1;
+    } else
+        sl->slice_type_fixed = 0;
+
+    slice_type         = ff_h264_golomb_to_pict_type[slice_type];
+    sl->slice_type     = slice_type;
+    sl->slice_type_nos = slice_type & 3;
+
+    if (nal->type  == H264_NAL_IDR_SLICE &&
+        sl->slice_type_nos != AV_PICTURE_TYPE_I) {
+        av_log(h->avctx, AV_LOG_ERROR, "A non-intra slice in an IDR NAL unit.\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    sl->pps_id = get_ue_golomb(&sl->gb);
+    if (sl->pps_id >= MAX_PPS_COUNT) {
+        av_log(h->avctx, AV_LOG_ERROR, "pps_id %u out of range\n", sl->pps_id);
+        return AVERROR_INVALIDDATA;
+    }
+    if (!h->ps.pps_list[sl->pps_id]) {
+        av_log(h->avctx, AV_LOG_ERROR,
+               "non-existing PPS %u referenced\n",
+               sl->pps_id);
+        return AVERROR_INVALIDDATA;
+    }
+    pps = (const PPS*)h->ps.pps_list[sl->pps_id]->data;
+
+    if (!h->ps.sps_list[pps->sps_id]) {
+        av_log(h->avctx, AV_LOG_ERROR,
+               "non-existing SPS %u referenced\n", pps->sps_id);
+        return AVERROR_INVALIDDATA;
+    }
+    sps = (const SPS*)h->ps.sps_list[pps->sps_id]->data;
+
+    sl->frame_num = get_bits(&sl->gb, sps->log2_max_frame_num);
+    if (!first_slice) {
+        if (h->poc.frame_num != sl->frame_num) {
+            av_log(h->avctx, AV_LOG_ERROR, "Frame num change from %d to %d\n",
+                   h->poc.frame_num, sl->frame_num);
+            return AVERROR_INVALIDDATA;
+        }
+    }
+
+    sl->mb_mbaff = 0;
+
+    if (sps->frame_mbs_only_flag) {
+        picture_structure = PICT_FRAME;
+    } else {
+        if (!sps->direct_8x8_inference_flag && slice_type == AV_PICTURE_TYPE_B) {
+            av_log(h->avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n");
+            return -1;
+        }
+        field_pic_flag = get_bits1(&sl->gb);
+        if (field_pic_flag) {
+            bottom_field_flag = get_bits1(&sl->gb);
+            picture_structure = PICT_TOP_FIELD + bottom_field_flag;
+        } else {
+            picture_structure = PICT_FRAME;
+        }
+    }
+    sl->picture_structure      = picture_structure;
+    sl->mb_field_decoding_flag = picture_structure != PICT_FRAME;
+
+    if (picture_structure == PICT_FRAME) {
+        sl->curr_pic_num = sl->frame_num;
+        sl->max_pic_num  = 1 << sps->log2_max_frame_num;
+    } else {
+        sl->curr_pic_num = 2 * sl->frame_num + 1;
+        sl->max_pic_num  = 1 << (sps->log2_max_frame_num + 1);
+    }
+
+	if(nal->idr_flag==1)
+        get_ue_golomb_long(&sl->gb);
+
+    if (sps->poc_type == 0) {
+        sl->poc_lsb = get_bits(&sl->gb, sps->log2_max_poc_lsb);
+
+        if (pps->pic_order_present == 1 && picture_structure == PICT_FRAME)
+            sl->delta_poc_bottom = get_se_golomb(&sl->gb);
+    }
+
+    if (sps->poc_type == 1 && !sps->delta_pic_order_always_zero_flag) {
+        sl->delta_poc[0] = get_se_golomb(&sl->gb);
+
+        if (pps->pic_order_present == 1 && picture_structure == PICT_FRAME)
+            sl->delta_poc[1] = get_se_golomb(&sl->gb);
+    }
+
+    sl->redundant_pic_count = 0;
+    if (pps->redundant_pic_cnt_present)
+        sl->redundant_pic_count = get_ue_golomb(&sl->gb);
 
+	if(nal->quality_id==0)
+	{
+		if (sl->slice_type_nos == AV_PICTURE_TYPE_B)
+			sl->direct_spatial_mv_pred = get_bits1(&sl->gb);
+
+		ret = ff_h264_parse_ref_count(&sl->list_count, sl->ref_count,
+									  &sl->gb, pps, sl->slice_type_nos,
+									  picture_structure, h->avctx);
+		if (ret < 0)
+			return ret;
+
+		if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {
+		   ret = ff_h264_decode_ref_pic_list_reordering(sl, h->avctx); //not need fix for svc
+		   if (ret < 0) {
+			   sl->ref_count[1] = sl->ref_count[0] = 0;
+			   return ret;
+		   }
+		}
+
+		sl->pwt.use_weight = 0;
+		for (i = 0; i < 2; i++) {
+			sl->pwt.luma_weight_flag[i]   = 0;
+			sl->pwt.chroma_weight_flag[i] = 0;
+		}
+		if ((pps->weighted_pred && sl->slice_type_nos == AV_PICTURE_TYPE_P) ||
+			(pps->weighted_bipred_idc == 1 &&
+			 sl->slice_type_nos == AV_PICTURE_TYPE_B))
+			{
+				if( !(nal->no_inter_layer_pred_flag))
+					base_pred_weight_table_flag = get_bits1(&sl->gb);//base_pred_weight_table_flag
+				if( nal->no_inter_layer_pred_flag || !base_pred_weight_table_flag)
+						ff_h264_pred_weight_table(&sl->gb, sps, sl->ref_count,
+                                  sl->slice_type_nos, &sl->pwt,
+                                  picture_structure, h->avctx);
+			}
+		sl->explicit_ref_marking = 0;
+		if (nal->ref_idc) {
+			ret = ff_h264_decode_ref_pic_marking(sl, &sl->gb, nal, h->avctx);
+			if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
+				return AVERROR_INVALIDDATA;
+			
+			if( !(sps->slice_header_restriction_flag))
+			{
+				store_ref_base_pic_flag = get_bits1(&sl->gb);//store_ref_base_pic_flag
+				if( (nal->use_ref_base_pic_flag || store_ref_base_pic_flag) && !(nal->idr_flag))
+					ff_h264_decode_ref_base_pic_marking(sl, &sl->gb, nal, h->avctx);
+			}
+		}
+	}
+
+    if (sl->slice_type_nos != AV_PICTURE_TYPE_I && pps->cabac) {
+        tmp = get_ue_golomb_31(&sl->gb);//cabac_init_idc
+        if (tmp > 2) {
+            av_log(h->avctx, AV_LOG_ERROR, "cabac_init_idc %u overflow\n", tmp);
+            return AVERROR_INVALIDDATA;
+        }
+        sl->cabac_init_idc = tmp;
+    }
+
+    sl->last_qscale_diff = 0;
+    tmp = pps->init_qp + get_se_golomb(&sl->gb);
+    if (tmp > 51 + 6 * (sps->bit_depth_luma - 8)) {
+        av_log(h->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);
+        return AVERROR_INVALIDDATA;
+    }
+    sl->qscale       = tmp;
+    sl->chroma_qp[0] = get_chroma_qp(pps, 0, sl->qscale);
+    sl->chroma_qp[1] = get_chroma_qp(pps, 1, sl->qscale);
+
+    sl->deblocking_filter     = 1;
+    sl->slice_alpha_c0_offset = 0;
+    sl->slice_beta_offset     = 0;
+    if (pps->deblocking_filter_parameters_present) {
+        tmp = get_ue_golomb_31(&sl->gb);
+        if (tmp > 2) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "deblocking_filter_idc %u out of range\n", tmp);
+            return AVERROR_INVALIDDATA;
+        }
+        sl->deblocking_filter = tmp;
+        if (sl->deblocking_filter < 2)
+            sl->deblocking_filter ^= 1;
+
+        if (sl->deblocking_filter) {
+            sl->slice_alpha_c0_offset = get_se_golomb(&sl->gb) * 2;
+            sl->slice_beta_offset     = get_se_golomb(&sl->gb) * 2;
+            if (sl->slice_alpha_c0_offset >  12 ||
+                sl->slice_alpha_c0_offset < -12 ||
+                sl->slice_beta_offset >  12     ||
+                sl->slice_beta_offset < -12) {
+                av_log(h->avctx, AV_LOG_ERROR,
+                       "deblocking filter parameters %d %d out of range\n",
+                       sl->slice_alpha_c0_offset, sl->slice_beta_offset);
+                return AVERROR_INVALIDDATA;
+            }
+        }
+    }
+
+    return 0;
+}
+#endif
 /* do all the per-slice initialization needed before we can start decoding the
  * actual MBs */
 static int h264_slice_init(H264Context *h, H264SliceContext *sl,
@@ -2085,15 +2305,21 @@ static int h264_slice_init(H264Context *h, H264SliceContext *sl,
     return 0;
 }
 
-int ff_h264_queue_decode_slice(H264Context *h, const H2645NAL *nal)
+int ff_h264_queue_decode_slice(H264Context *h, H2645NAL *nal)
 {
     H264SliceContext *sl = h->slice_ctx + h->nb_slice_ctx_queued;
     int first_slice = sl == h->slice_ctx && !h->current_slice;
     int ret;
 
     sl->gb = nal->gb;
-
+#if TMP_SVC_DEC_H264
+    if(nal->type == H264_NAL_EXTEN_SLICE && nal->svc_ext_flag == 1)
+		ret = h264_slice_header_in_scalable_ext_parse(h, sl, nal);
+	else
+		ret = h264_slice_header_parse(h, sl, nal);
+#else
     ret = h264_slice_header_parse(h, sl, nal);
+#endif
     if (ret < 0)
         return ret;
 
@@ -2102,7 +2328,16 @@ int ff_h264_queue_decode_slice(H264Context *h, const H2645NAL *nal)
         sl->ref_count[0] = sl->ref_count[1] = 0;
         return 0;
     }
-
+#if TMP_SVC_DEC_H264
+	if(nal->type == H264_NAL_EXTEN_SLICE && nal->svc_ext_flag == 1 && nal->idr_flag == 1)
+	{
+		nal->type = H264_NAL_IDR_SLICE;
+	}
+	else if (nal->type == H264_NAL_EXTEN_SLICE && nal->svc_ext_flag == 1 && nal->idr_flag == 0)
+	{
+		nal->type = H264_NAL_SLICE;
+	}
+#endif
     if (sl->first_mb_addr == 0 || !h->current_slice) {
         if (h->setup_finished) {
             av_log(h->avctx, AV_LOG_ERROR, "Too many fields\n");
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
old mode 100644
new mode 100755
index 47b9abb..ed3673a
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -605,6 +605,11 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
         err = 0;
         switch (nal->type) {
         case H264_NAL_IDR_SLICE:
+#if TMP_SVC_DEC_H264
+		case H264_NAL_EXTEN_SLICE:
+			if(nal->type == H264_NAL_EXTEN_SLICE && nal->idr_flag != 1)
+				goto svc_no_idr;
+#endif
             if ((nal->data[1] & 0xFC) == 0x98) {
                 av_log(h->avctx, AV_LOG_ERROR, "Invalid inter IDR frame\n");
                 h->next_outputed_poc = INT_MIN;
@@ -616,6 +621,9 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
             }
             idr_cleared = 1;
             h->has_recovery_point = 1;
+#if TMP_SVC_DEC_H264
+svc_no_idr:
+#endif
         case H264_NAL_SLICE:
             h->has_slice = 1;
 
@@ -681,6 +689,15 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
             ff_h264_decode_seq_parameter_set(&nal->gb, avctx, &h->ps, 1);
             break;
         }
+#if TMP_SVC_DEC_H264
+		case H264_NAL_SUB_SPS: {
+			GetBitContext tmp_gb = nal->gb;
+			ret = ff_h264_decode_subset_seq_parameter_set(&tmp_gb, avctx, &h->ps, 0);
+			if(ret < 0)
+				goto end;
+			break;
+		}
+#endif
         case H264_NAL_PPS:
             if (avctx->hwaccel && avctx->hwaccel->decode_params) {
                 ret = avctx->hwaccel->decode_params(avctx,
diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h
old mode 100644
new mode 100755
index b3677cd..8fc5cfd
--- a/libavcodec/h264dec.h
+++ b/libavcodec/h264dec.h
@@ -585,6 +585,10 @@ int ff_h264_execute_ref_pic_marking(H264Context *h);
 int ff_h264_decode_ref_pic_marking(H264SliceContext *sl, GetBitContext *gb,
                                    const H2645NAL *nal, void *logctx);
 
+#if TMP_SVC_DEC_H264
+int ff_h264_decode_ref_base_pic_marking(H264SliceContext *sl, GetBitContext *gb,
+                                   const H2645NAL *nal, void *logctx);
+#endif
 void ff_h264_hl_decode_mb(const H264Context *h, H264SliceContext *sl);
 void ff_h264_decode_init_vlc(void);
 
@@ -845,7 +849,7 @@ void ff_h264_draw_horiz_band(const H264Context *h, H264SliceContext *sl, int y,
  * Parse the slice header, starting a new field/frame if necessary. If any
  * slices are queued for the previous field, they are decoded.
  */
-int ff_h264_queue_decode_slice(H264Context *h, const H2645NAL *nal);
+int ff_h264_queue_decode_slice(H264Context *h, H2645NAL *nal);
 int ff_h264_execute_decode_slices(H264Context *h);
 int ff_h264_update_thread_context(AVCodecContext *dst,
                                   const AVCodecContext *src);
-- 
2.29.2

