]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/h264_ps.c
paf: prevent invalid write
[ffmpeg] / libavcodec / h264_ps.c
index 261e2d27190b04389c98774f20adf04c1c3dfe3b..cdc6b079b68698807e42c2a4fddf2ec629482f7e 100644 (file)
@@ -70,7 +70,7 @@ static const AVRational pixel_aspect[17]={
     QP(37,d), QP(37,d), QP(37,d), QP(38,d), QP(38,d), QP(38,d),\
     QP(39,d), QP(39,d), QP(39,d), QP(39,d)
 
-const uint8_t ff_h264_chroma_qp[5][QP_MAX_NUM+1] = {
+const uint8_t ff_h264_chroma_qp[7][QP_MAX_NUM+1] = {
     {
         CHROMA_QP_TABLE_END(8)
     },
@@ -96,6 +96,23 @@ const uint8_t ff_h264_chroma_qp[5][QP_MAX_NUM+1] = {
         18,19,20,21, 22, 23,
         CHROMA_QP_TABLE_END(12)
     },
+    {
+        0,  1, 2, 3,  4,  5,
+        6,  7, 8, 9, 10, 11,
+        12,13,14,15, 16, 17,
+        18,19,20,21, 22, 23,
+        24,25,26,27, 28, 29,
+        CHROMA_QP_TABLE_END(13)
+    },
+    {
+        0,  1, 2, 3,  4,  5,
+        6,  7, 8, 9, 10, 11,
+        12,13,14,15, 16, 17,
+        18,19,20,21, 22, 23,
+        24,25,26,27, 28, 29,
+        30,31,32,33, 34, 35,
+        CHROMA_QP_TABLE_END(14)
+    },
 };
 
 static const uint8_t default_scaling4[2][16]={
@@ -299,13 +316,11 @@ static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_s
         decode_scaling_list(h,scaling_matrix4[5],16,default_scaling4[1],scaling_matrix4[4]); // Inter, Cb
         if(is_sps || pps->transform_8x8_mode){
             decode_scaling_list(h,scaling_matrix8[0],64,default_scaling8[0],fallback[2]);  // Intra, Y
-            if(sps->chroma_format_idc == 3){
-                decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[0],scaling_matrix8[0]);  // Intra, Cr
-                decode_scaling_list(h,scaling_matrix8[2],64,default_scaling8[0],scaling_matrix8[1]);  // Intra, Cb
-            }
             decode_scaling_list(h,scaling_matrix8[3],64,default_scaling8[1],fallback[3]);  // Inter, Y
             if(sps->chroma_format_idc == 3){
+                decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[0],scaling_matrix8[0]);  // Intra, Cr
                 decode_scaling_list(h,scaling_matrix8[4],64,default_scaling8[1],scaling_matrix8[3]);  // Inter, Cr
+                decode_scaling_list(h,scaling_matrix8[2],64,default_scaling8[0],scaling_matrix8[1]);  // Intra, Cb
                 decode_scaling_list(h,scaling_matrix8[5],64,default_scaling8[1],scaling_matrix8[4]);  // Inter, Cb
             }
         }
@@ -324,7 +339,9 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){
     constraint_set_flags |= get_bits1(&s->gb) << 1;   //constraint_set1_flag
     constraint_set_flags |= get_bits1(&s->gb) << 2;   //constraint_set2_flag
     constraint_set_flags |= get_bits1(&s->gb) << 3;   //constraint_set3_flag
-    get_bits(&s->gb, 4); // reserved
+    constraint_set_flags |= get_bits1(&s->gb) << 4;   //constraint_set4_flag
+    constraint_set_flags |= get_bits1(&s->gb) << 5;   //constraint_set5_flag
+    get_bits(&s->gb, 2); // reserved
     level_idc= get_bits(&s->gb, 8);
     sps_id= get_ue_golomb_31(&s->gb);
 
@@ -347,17 +364,24 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){
     sps->scaling_matrix_present = 0;
     sps->colorspace = 2; //AVCOL_SPC_UNSPECIFIED
 
-    if(sps->profile_idc >= 100){ //high profile
+    if(sps->profile_idc == 100 || sps->profile_idc == 110 ||
+       sps->profile_idc == 122 || sps->profile_idc == 244 || sps->profile_idc ==  44 ||
+       sps->profile_idc ==  83 || sps->profile_idc ==  86 || sps->profile_idc == 118 ||
+       sps->profile_idc == 128 ) {
         sps->chroma_format_idc= get_ue_golomb_31(&s->gb);
         if (sps->chroma_format_idc > 3U) {
             av_log(h->s.avctx, AV_LOG_ERROR, "chroma_format_idc %d is illegal\n", sps->chroma_format_idc);
             goto fail;
         } else if(sps->chroma_format_idc == 3) {
             sps->residual_color_transform_flag = get_bits1(&s->gb);
+            if(sps->residual_color_transform_flag) {
+                av_log(h->s.avctx, AV_LOG_ERROR, "separate color planes are not supported\n");
+                goto fail;
+            }
         }
         sps->bit_depth_luma   = get_ue_golomb(&s->gb) + 8;
         sps->bit_depth_chroma = get_ue_golomb(&s->gb) + 8;
-        if (sps->bit_depth_luma > 12U || sps->bit_depth_chroma > 12U) {
+        if (sps->bit_depth_luma > 14U || sps->bit_depth_chroma > 14U) {
             av_log(h->s.avctx, AV_LOG_ERROR, "illegal bit depth value (%d, %d)\n",
                    sps->bit_depth_luma, sps->bit_depth_chroma);
             goto fail;
@@ -380,7 +404,12 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){
     sps->poc_type= get_ue_golomb_31(&s->gb);
 
     if(sps->poc_type == 0){ //FIXME #define
-        sps->log2_max_poc_lsb= get_ue_golomb(&s->gb) + 4;
+        unsigned t = get_ue_golomb(&s->gb);
+        if(t>12){
+            av_log(h->s.avctx, AV_LOG_ERROR, "log2_max_poc_lsb (%d) is out of range\n", t);
+            goto fail;
+        }
+        sps->log2_max_poc_lsb= t + 4;
     } else if(sps->poc_type == 1){//FIXME #define
         sps->delta_pic_order_always_zero_flag= get_bits1(&s->gb);
         sps->offset_for_non_ref_pic= get_se_golomb(&s->gb);
@@ -462,7 +491,8 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){
         sps->sar.den= 1;
 
     if(s->avctx->debug&FF_DEBUG_PICT_INFO){
-        av_log(h->s.avctx, AV_LOG_DEBUG, "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s %s %d/%d b%d\n",
+        static const char csp[4][5] = { "Gray", "420", "422", "444" };
+        av_log(h->s.avctx, AV_LOG_DEBUG, "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s %s %d/%d b%d reo:%d\n",
                sps_id, sps->profile_idc, sps->level_idc,
                sps->poc_type,
                sps->ref_frame_count,
@@ -472,10 +502,11 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){
                sps->crop_left, sps->crop_right,
                sps->crop_top, sps->crop_bottom,
                sps->vui_parameters_present_flag ? "VUI" : "",
-               ((const char*[]){"Gray","420","422","444"})[sps->chroma_format_idc],
+               csp[sps->chroma_format_idc],
                sps->timing_info_present_flag ? sps->num_units_in_tick : 0,
                sps->timing_info_present_flag ? sps->time_scale : 0,
-               sps->bit_depth_luma
+               sps->bit_depth_luma,
+               h->sps.bitstream_restriction_flag ? sps->num_reorder_frames : -1
                );
     }
 
@@ -522,8 +553,11 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){
     if(pps_id >= MAX_PPS_COUNT) {
         av_log(h->s.avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id);
         return -1;
-    } else if (h->sps.bit_depth_luma > 10) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "Unimplemented luma bit depth=%d (max=10)\n", h->sps.bit_depth_luma);
+    } else if (h->sps.bit_depth_luma > 14) {
+        av_log(h->s.avctx, AV_LOG_ERROR, "Invalid luma bit depth=%d\n", h->sps.bit_depth_luma);
+        return AVERROR_INVALIDDATA;
+    } else if (h->sps.bit_depth_luma == 11 || h->sps.bit_depth_luma == 13) {
+        av_log(h->s.avctx, AV_LOG_ERROR, "Unimplemented luma bit depth=%d\n", h->sps.bit_depth_luma);
         return AVERROR_PATCHWELCOME;
     }