Mercurial > libavcodec.hg
comparison h264.c @ 8234:4a8f9bbc5e81 libavcodec
Allocate parameter sets sanely instead of using alloc_parameter_set().
Avoids ending up with half initialized parameter sets.
Fixes issue282.
author | michael |
---|---|
date | Mon, 01 Dec 2008 16:04:03 +0000 |
parents | 0df3402e6b41 |
children | 61b5b99f3b77 |
comparison
equal
deleted
inserted
replaced
8233:ababfa151ced | 8234:4a8f9bbc5e81 |
---|---|
6975 decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[1],fallback[3]); // Inter, Y | 6975 decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[1],fallback[3]); // Inter, Y |
6976 } | 6976 } |
6977 } | 6977 } |
6978 } | 6978 } |
6979 | 6979 |
6980 /** | |
6981 * Returns and optionally allocates SPS / PPS structures in the supplied array 'vec' | |
6982 */ | |
6983 static void * | |
6984 alloc_parameter_set(H264Context *h, void **vec, const unsigned int id, const unsigned int max, | |
6985 const size_t size, const char *name) | |
6986 { | |
6987 if(id>=max) { | |
6988 av_log(h->s.avctx, AV_LOG_ERROR, "%s_id (%d) out of range\n", name, id); | |
6989 return NULL; | |
6990 } | |
6991 | |
6992 if(!vec[id]) { | |
6993 vec[id] = av_mallocz(size); | |
6994 if(vec[id] == NULL) | |
6995 av_log(h->s.avctx, AV_LOG_ERROR, "cannot allocate memory for %s\n", name); | |
6996 } | |
6997 return vec[id]; | |
6998 } | |
6999 | |
7000 static inline int decode_seq_parameter_set(H264Context *h){ | 6980 static inline int decode_seq_parameter_set(H264Context *h){ |
7001 MpegEncContext * const s = &h->s; | 6981 MpegEncContext * const s = &h->s; |
7002 int profile_idc, level_idc; | 6982 int profile_idc, level_idc; |
7003 unsigned int sps_id, tmp, mb_width, mb_height; | 6983 unsigned int sps_id, tmp, mb_width, mb_height; |
7004 int i; | 6984 int i; |
7011 get_bits1(&s->gb); //constraint_set3_flag | 6991 get_bits1(&s->gb); //constraint_set3_flag |
7012 get_bits(&s->gb, 4); // reserved | 6992 get_bits(&s->gb, 4); // reserved |
7013 level_idc= get_bits(&s->gb, 8); | 6993 level_idc= get_bits(&s->gb, 8); |
7014 sps_id= get_ue_golomb(&s->gb); | 6994 sps_id= get_ue_golomb(&s->gb); |
7015 | 6995 |
7016 sps = alloc_parameter_set(h, (void **)h->sps_buffers, sps_id, MAX_SPS_COUNT, sizeof(SPS), "sps"); | 6996 if(sps_id >= MAX_SPS_COUNT) { |
6997 av_log(h->s.avctx, AV_LOG_ERROR, "sps_id (%d) out of range\n", sps_id); | |
6998 return -1; | |
6999 } | |
7000 sps= av_mallocz(sizeof(SPS)); | |
7017 if(sps == NULL) | 7001 if(sps == NULL) |
7018 return -1; | 7002 return -1; |
7019 | 7003 |
7020 sps->profile_idc= profile_idc; | 7004 sps->profile_idc= profile_idc; |
7021 sps->level_idc= level_idc; | 7005 sps->level_idc= level_idc; |
7047 sps->offset_for_top_to_bottom_field= get_se_golomb(&s->gb); | 7031 sps->offset_for_top_to_bottom_field= get_se_golomb(&s->gb); |
7048 tmp= get_ue_golomb(&s->gb); | 7032 tmp= get_ue_golomb(&s->gb); |
7049 | 7033 |
7050 if(tmp >= FF_ARRAY_ELEMS(sps->offset_for_ref_frame)){ | 7034 if(tmp >= FF_ARRAY_ELEMS(sps->offset_for_ref_frame)){ |
7051 av_log(h->s.avctx, AV_LOG_ERROR, "poc_cycle_length overflow %u\n", tmp); | 7035 av_log(h->s.avctx, AV_LOG_ERROR, "poc_cycle_length overflow %u\n", tmp); |
7052 return -1; | 7036 goto fail; |
7053 } | 7037 } |
7054 sps->poc_cycle_length= tmp; | 7038 sps->poc_cycle_length= tmp; |
7055 | 7039 |
7056 for(i=0; i<sps->poc_cycle_length; i++) | 7040 for(i=0; i<sps->poc_cycle_length; i++) |
7057 sps->offset_for_ref_frame[i]= get_se_golomb(&s->gb); | 7041 sps->offset_for_ref_frame[i]= get_se_golomb(&s->gb); |
7058 }else if(sps->poc_type != 2){ | 7042 }else if(sps->poc_type != 2){ |
7059 av_log(h->s.avctx, AV_LOG_ERROR, "illegal POC type %d\n", sps->poc_type); | 7043 av_log(h->s.avctx, AV_LOG_ERROR, "illegal POC type %d\n", sps->poc_type); |
7060 return -1; | 7044 goto fail; |
7061 } | 7045 } |
7062 | 7046 |
7063 tmp= get_ue_golomb(&s->gb); | 7047 tmp= get_ue_golomb(&s->gb); |
7064 if(tmp > MAX_PICTURE_COUNT-2 || tmp >= 32){ | 7048 if(tmp > MAX_PICTURE_COUNT-2 || tmp >= 32){ |
7065 av_log(h->s.avctx, AV_LOG_ERROR, "too many reference frames\n"); | 7049 av_log(h->s.avctx, AV_LOG_ERROR, "too many reference frames\n"); |
7066 return -1; | 7050 goto fail; |
7067 } | 7051 } |
7068 sps->ref_frame_count= tmp; | 7052 sps->ref_frame_count= tmp; |
7069 sps->gaps_in_frame_num_allowed_flag= get_bits1(&s->gb); | 7053 sps->gaps_in_frame_num_allowed_flag= get_bits1(&s->gb); |
7070 mb_width= get_ue_golomb(&s->gb) + 1; | 7054 mb_width= get_ue_golomb(&s->gb) + 1; |
7071 mb_height= get_ue_golomb(&s->gb) + 1; | 7055 mb_height= get_ue_golomb(&s->gb) + 1; |
7072 if(mb_width >= INT_MAX/16 || mb_height >= INT_MAX/16 || | 7056 if(mb_width >= INT_MAX/16 || mb_height >= INT_MAX/16 || |
7073 avcodec_check_dimensions(NULL, 16*mb_width, 16*mb_height)){ | 7057 avcodec_check_dimensions(NULL, 16*mb_width, 16*mb_height)){ |
7074 av_log(h->s.avctx, AV_LOG_ERROR, "mb_width/height overflow\n"); | 7058 av_log(h->s.avctx, AV_LOG_ERROR, "mb_width/height overflow\n"); |
7075 return -1; | 7059 goto fail; |
7076 } | 7060 } |
7077 sps->mb_width = mb_width; | 7061 sps->mb_width = mb_width; |
7078 sps->mb_height= mb_height; | 7062 sps->mb_height= mb_height; |
7079 | 7063 |
7080 sps->frame_mbs_only_flag= get_bits1(&s->gb); | 7064 sps->frame_mbs_only_flag= get_bits1(&s->gb); |
7124 sps->crop_top, sps->crop_bottom, | 7108 sps->crop_top, sps->crop_bottom, |
7125 sps->vui_parameters_present_flag ? "VUI" : "", | 7109 sps->vui_parameters_present_flag ? "VUI" : "", |
7126 ((const char*[]){"Gray","420","422","444"})[sps->chroma_format_idc] | 7110 ((const char*[]){"Gray","420","422","444"})[sps->chroma_format_idc] |
7127 ); | 7111 ); |
7128 } | 7112 } |
7113 av_free(h->sps_buffers[sps_id]); | |
7114 h->sps_buffers[sps_id]= sps; | |
7129 return 0; | 7115 return 0; |
7116 fail: | |
7117 av_free(sps); | |
7118 return -1; | |
7130 } | 7119 } |
7131 | 7120 |
7132 static void | 7121 static void |
7133 build_qp_table(PPS *pps, int t, int index) | 7122 build_qp_table(PPS *pps, int t, int index) |
7134 { | 7123 { |
7140 static inline int decode_picture_parameter_set(H264Context *h, int bit_length){ | 7129 static inline int decode_picture_parameter_set(H264Context *h, int bit_length){ |
7141 MpegEncContext * const s = &h->s; | 7130 MpegEncContext * const s = &h->s; |
7142 unsigned int tmp, pps_id= get_ue_golomb(&s->gb); | 7131 unsigned int tmp, pps_id= get_ue_golomb(&s->gb); |
7143 PPS *pps; | 7132 PPS *pps; |
7144 | 7133 |
7145 pps = alloc_parameter_set(h, (void **)h->pps_buffers, pps_id, MAX_PPS_COUNT, sizeof(PPS), "pps"); | 7134 if(pps_id >= MAX_PPS_COUNT) { |
7146 if(pps == NULL) | 7135 av_log(h->s.avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id); |
7147 return -1; | 7136 return -1; |
7137 } | |
7148 | 7138 |
7149 tmp= get_ue_golomb(&s->gb); | 7139 tmp= get_ue_golomb(&s->gb); |
7150 if(tmp>=MAX_SPS_COUNT || h->sps_buffers[tmp] == NULL){ | 7140 if(tmp>=MAX_SPS_COUNT || h->sps_buffers[tmp] == NULL){ |
7151 av_log(h->s.avctx, AV_LOG_ERROR, "sps_id out of range\n"); | 7141 av_log(h->s.avctx, AV_LOG_ERROR, "sps_id out of range\n"); |
7152 return -1; | 7142 return -1; |
7153 } | 7143 } |
7144 pps= av_mallocz(sizeof(PPS)); | |
7145 if(pps == NULL) | |
7146 return -1; | |
7154 pps->sps_id= tmp; | 7147 pps->sps_id= tmp; |
7155 | 7148 |
7156 pps->cabac= get_bits1(&s->gb); | 7149 pps->cabac= get_bits1(&s->gb); |
7157 pps->pic_order_present= get_bits1(&s->gb); | 7150 pps->pic_order_present= get_bits1(&s->gb); |
7158 pps->slice_group_count= get_ue_golomb(&s->gb) + 1; | 7151 pps->slice_group_count= get_ue_golomb(&s->gb) + 1; |
7196 pps->ref_count[0]= get_ue_golomb(&s->gb) + 1; | 7189 pps->ref_count[0]= get_ue_golomb(&s->gb) + 1; |
7197 pps->ref_count[1]= get_ue_golomb(&s->gb) + 1; | 7190 pps->ref_count[1]= get_ue_golomb(&s->gb) + 1; |
7198 if(pps->ref_count[0]-1 > 32-1 || pps->ref_count[1]-1 > 32-1){ | 7191 if(pps->ref_count[0]-1 > 32-1 || pps->ref_count[1]-1 > 32-1){ |
7199 av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow (pps)\n"); | 7192 av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow (pps)\n"); |
7200 pps->ref_count[0]= pps->ref_count[1]= 1; | 7193 pps->ref_count[0]= pps->ref_count[1]= 1; |
7201 return -1; | 7194 goto fail; |
7202 } | 7195 } |
7203 | 7196 |
7204 pps->weighted_pred= get_bits1(&s->gb); | 7197 pps->weighted_pred= get_bits1(&s->gb); |
7205 pps->weighted_bipred_idc= get_bits(&s->gb, 2); | 7198 pps->weighted_bipred_idc= get_bits(&s->gb, 2); |
7206 pps->init_qp= get_se_golomb(&s->gb) + 26; | 7199 pps->init_qp= get_se_golomb(&s->gb) + 26; |
7241 pps->redundant_pic_cnt_present ? "REDU" : "", | 7234 pps->redundant_pic_cnt_present ? "REDU" : "", |
7242 pps->transform_8x8_mode ? "8x8DCT" : "" | 7235 pps->transform_8x8_mode ? "8x8DCT" : "" |
7243 ); | 7236 ); |
7244 } | 7237 } |
7245 | 7238 |
7239 av_free(h->pps_buffers[pps_id]); | |
7240 h->pps_buffers[pps_id]= pps; | |
7246 return 0; | 7241 return 0; |
7242 fail: | |
7243 av_free(pps); | |
7244 return -1; | |
7247 } | 7245 } |
7248 | 7246 |
7249 /** | 7247 /** |
7250 * Call decode_slice() for each context. | 7248 * Call decode_slice() for each context. |
7251 * | 7249 * |