static inline int decode_hrd_parameters(H264Context *h, SPS *sps){ MpegEncContext * const s = &h->s; int cpb_count, i; cpb_count = get_ue_golomb_31(&s->gb) + 1; if(cpb_count > 32U){ av_log(h->s.avctx, AV_LOG_ERROR, "cpb_count %d invalid\n", cpb_count); return -1; } get_bits(&s->gb, 4); /* bit_rate_scale */ get_bits(&s->gb, 4); /* cpb_size_scale */ for(i=0; i<cpb_count; i++){ get_ue_golomb(&s->gb); /* bit_rate_value_minus1 */ get_ue_golomb(&s->gb); /* cpb_size_value_minus1 */ get_bits1(&s->gb); /* cbr_flag */ } sps->initial_cpb_removal_delay_length = get_bits(&s->gb, 5) + 1; sps->cpb_removal_delay_length = get_bits(&s->gb, 5) + 1; sps->dpb_output_delay_length = get_bits(&s->gb, 5) + 1; sps->time_offset_length = get_bits(&s->gb, 5); sps->cpb_cnt = cpb_count; return 0; }
static int decode_frame_packing_arrangement(H264Context *h) { get_ue_golomb(&h->gb); // frame_packing_arrangement_id h->sei_frame_packing_present = !get_bits1(&h->gb); if (h->sei_frame_packing_present) { h->frame_packing_arrangement_type = get_bits(&h->gb, 7); h->quincunx_subsampling = get_bits1(&h->gb); h->content_interpretation_type = get_bits(&h->gb, 6); // the following skips: spatial_flipping_flag, frame0_flipped_flag, // field_views_flag, current_frame_is_frame0_flag, // frame0_self_contained_flag, frame1_self_contained_flag skip_bits(&h->gb, 6); if (!h->quincunx_subsampling && h->frame_packing_arrangement_type != 5) skip_bits(&h->gb, 16); // frame[01]_grid_position_[xy] skip_bits(&h->gb, 8); // frame_packing_arrangement_reserved_byte get_ue_golomb(&h->gb); // frame_packing_arrangement_repetition_period } skip_bits1(&h->gb); // frame_packing_arrangement_extension_flag return 0; }
static int decode_display_orientation(H264Context *h) { h->sei_display_orientation_present = !get_bits1(&h->gb); if (h->sei_display_orientation_present) { h->sei_hflip = get_bits1(&h->gb); // hor_flip h->sei_vflip = get_bits1(&h->gb); // ver_flip h->sei_anticlockwise_rotation = get_bits(&h->gb, 16); get_ue_golomb(&h->gb); // display_orientation_repetition_period skip_bits1(&h->gb); // display_orientation_extension_flag } return 0; }
void H264::parseNAL(uint8_t* buf, int size) { int off = find_startCode(buf, 0, size) + 4; int next_start = off; for(; next_start > 0; off = next_start + 4) { next_start = find_startCode(buf, off, size); int type = buf[off] & 0x1F; int id_off = (type == NAL_PPS) ? 1 : 4; if(type != NAL_SPS && type != NAL_PPS) continue; GetBitContext gb; init_get_bits(&gb, buf + off + id_off, 8*(size - off - id_off)); int id = get_ue_golomb(&gb); int nal_size = (next_start < 0) ? (size - off) : (next_start - off); switch(type) { case NAL_SPS: if(id >= MAX_SPS_COUNT) continue; free(m_sps.data); m_sps.data = (uint8_t*)av_malloc(nal_size+4); memcpy(m_sps.data, buf + off - 4, nal_size+4); m_sps.size = nal_size+4; log_debug("NAL_SPS (id=%d)", id); break; case NAL_PPS: if(id >= MAX_PPS_COUNT) continue; free(m_pps.data); m_pps.data = (uint8_t*)av_malloc(nal_size+4); memcpy(m_pps.data, buf + off - 4, nal_size+4); m_pps.size = nal_size+4; log_debug("NAL_PPS (id=%d)", id); break; } } }
static int decode_recovery_point(H264Context *h) { h->sei_recovery_frame_cnt = get_ue_golomb(&h->gb); /* 1b exact_match_flag, * 1b broken_link_flag, * 2b changing_slice_group_idc */ skip_bits(&h->gb, 4); if (h->avctx->debug & FF_DEBUG_PICT_INFO) av_log(h->avctx, AV_LOG_DEBUG, "sei_recovery_frame_cnt: %d\n", h->sei_recovery_frame_cnt); h->has_recovery_point = 1; return 0; }
static void decode_nal_sei_frame_packing_arrangement(HEVCContext *s) { GetBitContext *gb = &s->HEVClc->gb; get_ue_golomb(gb); // frame_packing_arrangement_id s->sei_frame_packing_present = !get_bits1(gb); if (s->sei_frame_packing_present) { s->frame_packing_arrangement_type = get_bits(gb, 7); s->quincunx_subsampling = get_bits1(gb); s->content_interpretation_type = get_bits(gb, 6); // the following skips spatial_flipping_flag frame0_flipped_flag // field_views_flag current_frame_is_frame0_flag // frame0_self_contained_flag frame1_self_contained_flag skip_bits(gb, 6); if (!s->quincunx_subsampling && s->frame_packing_arrangement_type != 5) skip_bits(gb, 16); // frame[01]_grid_position_[xy] skip_bits(gb, 8); // frame_packing_arrangement_reserved_byte skip_bits1(gb); // frame_packing_arrangement_persistance_flag } skip_bits1(gb); // upsampled_aspect_ratio_flag }
static void decode_nal_sei_frame_packing_arrangement(HEVCLocalContext *lc) { GetBitContext *gb = &lc->gb; int cancel, type, quincunx; get_ue_golomb(gb); // frame_packing_arrangement_id cancel = get_bits1(gb); // frame_packing_cancel_flag if (cancel == 0) { type = get_bits(gb, 7); // frame_packing_arrangement_type quincunx = get_bits1(gb); // quincunx_sampling_flag skip_bits(gb, 6); // content_interpretation_type // the following skips spatial_flipping_flag frame0_flipped_flag // field_views_flag current_frame_is_frame0_flag // frame0_self_contained_flag frame1_self_contained_flag skip_bits(gb, 6); if (quincunx == 0 && type != 5) skip_bits(gb, 16); // frame[01]_grid_position_[xy] skip_bits(gb, 8); // frame_packing_arrangement_reserved_byte skip_bits1(gb); // frame_packing_arrangement_persistance_flag } skip_bits1(gb); // upsampled_aspect_ratio_flag }
int ff_h264_decode_seq_parameter_set(H264Context *h){ MpegEncContext * const s = &h->s; int profile_idc, level_idc, constraint_set_flags = 0; unsigned int sps_id; int i; SPS *sps; profile_idc= get_bits(&s->gb, 8); constraint_set_flags |= get_bits1(&s->gb) << 0; //constraint_set0_flag 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 level_idc= get_bits(&s->gb, 8); sps_id= get_ue_golomb_31(&s->gb); if(sps_id >= MAX_SPS_COUNT) { av_log(h->s.avctx, AV_LOG_ERROR, "sps_id (%d) out of range\n", sps_id); return -1; } sps= av_mallocz(sizeof(SPS)); if(sps == NULL) return -1; sps->time_offset_length = 24; sps->profile_idc= profile_idc; sps->constraint_set_flags = constraint_set_flags; sps->level_idc= level_idc; sps->full_range = -1; memset(sps->scaling_matrix4, 16, sizeof(sps->scaling_matrix4)); memset(sps->scaling_matrix8, 16, sizeof(sps->scaling_matrix8)); sps->scaling_matrix_present = 0; sps->colorspace = 2; //AVCOL_SPC_UNSPECIFIED if(sps->profile_idc >= 100){ //high profile 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); } 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) { 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; } sps->transform_bypass = get_bits1(&s->gb); decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8); }else{ sps->chroma_format_idc= 1; sps->bit_depth_luma = 8; sps->bit_depth_chroma = 8; } sps->log2_max_frame_num= get_ue_golomb(&s->gb) + 4; if (sps->log2_max_frame_num < 4 || sps->log2_max_frame_num > 16) { av_log(h->s.avctx, AV_LOG_ERROR, "illegal log2_max_frame_num %d\n", sps->log2_max_frame_num); goto fail; } 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; } 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); sps->offset_for_top_to_bottom_field= get_se_golomb(&s->gb); sps->poc_cycle_length = get_ue_golomb(&s->gb); if((unsigned)sps->poc_cycle_length >= FF_ARRAY_ELEMS(sps->offset_for_ref_frame)){ av_log(h->s.avctx, AV_LOG_ERROR, "poc_cycle_length overflow %u\n", sps->poc_cycle_length); goto fail; } for(i=0; i<sps->poc_cycle_length; i++) sps->offset_for_ref_frame[i]= get_se_golomb(&s->gb); }else if(sps->poc_type != 2){ av_log(h->s.avctx, AV_LOG_ERROR, "illegal POC type %d\n", sps->poc_type); goto fail; } sps->ref_frame_count= get_ue_golomb_31(&s->gb); if(sps->ref_frame_count > MAX_PICTURE_COUNT-2 || sps->ref_frame_count > 16U){ av_log(h->s.avctx, AV_LOG_ERROR, "too many reference frames\n"); goto fail; } sps->gaps_in_frame_num_allowed_flag= get_bits1(&s->gb); sps->mb_width = get_ue_golomb(&s->gb) + 1; sps->mb_height= get_ue_golomb(&s->gb) + 1; if((unsigned)sps->mb_width >= INT_MAX/16 || (unsigned)sps->mb_height >= INT_MAX/16 || av_image_check_size(16*sps->mb_width, 16*sps->mb_height, 0, h->s.avctx)){ av_log(h->s.avctx, AV_LOG_ERROR, "mb_width/height overflow\n"); goto fail; } sps->frame_mbs_only_flag= get_bits1(&s->gb); if(!sps->frame_mbs_only_flag) sps->mb_aff= get_bits1(&s->gb); else sps->mb_aff= 0; sps->direct_8x8_inference_flag= get_bits1(&s->gb); #ifndef ALLOW_INTERLACE if(sps->mb_aff) av_log(h->s.avctx, AV_LOG_ERROR, "MBAFF support not included; enable it at compile-time.\n"); #endif sps->crop= get_bits1(&s->gb); if(sps->crop){ int crop_vertical_limit = sps->chroma_format_idc & 2 ? 16 : 8; int crop_horizontal_limit = sps->chroma_format_idc == 3 ? 16 : 8; sps->crop_left = get_ue_golomb(&s->gb); sps->crop_right = get_ue_golomb(&s->gb); sps->crop_top = get_ue_golomb(&s->gb); sps->crop_bottom= get_ue_golomb(&s->gb); if(sps->crop_left || sps->crop_top){ av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ... (left: %d, top: %d)\n", sps->crop_left, sps->crop_top); } if(sps->crop_right >= crop_horizontal_limit || sps->crop_bottom >= crop_vertical_limit){ av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not supported, cropping disabled (right: %d, bottom: %d)\n", sps->crop_right, sps->crop_bottom); /* It is very unlikely that partial cropping will make anybody happy. * Not cropping at all fixes for example playback of Sisvel 3D streams * in applications supporting Sisvel 3D. */ sps->crop_left = sps->crop_right = sps->crop_top = sps->crop_bottom= 0; } }else{ sps->crop_left = sps->crop_right = sps->crop_top = sps->crop_bottom= 0; } sps->vui_parameters_present_flag= get_bits1(&s->gb); if( sps->vui_parameters_present_flag ) if (decode_vui_parameters(h, sps) < 0) goto fail; if(!sps->sar.den) 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", sps_id, sps->profile_idc, sps->level_idc, sps->poc_type, sps->ref_frame_count, sps->mb_width, sps->mb_height, sps->frame_mbs_only_flag ? "FRM" : (sps->mb_aff ? "MB-AFF" : "PIC-AFF"), sps->direct_8x8_inference_flag ? "8B8" : "", 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],
int ff_h264_decode_ref_pic_list_reordering(H264Context *h, H264SliceContext *sl) { int list, index, pic_structure; print_short_term(h); print_long_term(h); h264_initialise_ref_list(h, sl); for (list = 0; list < sl->list_count; list++) { if (get_bits1(&sl->gb)) { // ref_pic_list_modification_flag_l[01] int pred = h->curr_pic_num; for (index = 0; ; index++) { unsigned int modification_of_pic_nums_idc = get_ue_golomb_31(&sl->gb); unsigned int pic_id; int i; H264Picture *ref = NULL; if (modification_of_pic_nums_idc == 3) break; if (index >= sl->ref_count[list]) { av_log(h->avctx, AV_LOG_ERROR, "reference count overflow\n"); return -1; } switch (modification_of_pic_nums_idc) { case 0: case 1: { const unsigned int abs_diff_pic_num = get_ue_golomb_long(&sl->gb) + 1; int frame_num; if (abs_diff_pic_num > h->max_pic_num) { av_log(h->avctx, AV_LOG_ERROR, "abs_diff_pic_num overflow\n"); return AVERROR_INVALIDDATA; } if (modification_of_pic_nums_idc == 0) pred -= abs_diff_pic_num; else pred += abs_diff_pic_num; pred &= h->max_pic_num - 1; frame_num = pic_num_extract(h, pred, &pic_structure); for (i = h->short_ref_count - 1; i >= 0; i--) { ref = h->short_ref[i]; assert(ref->reference); assert(!ref->long_ref); if (ref->frame_num == frame_num && (ref->reference & pic_structure)) break; } if (i >= 0) ref->pic_id = pred; break; } case 2: { int long_idx; pic_id = get_ue_golomb(&sl->gb); // long_term_pic_idx long_idx = pic_num_extract(h, pic_id, &pic_structure); if (long_idx > 31U) { av_log(h->avctx, AV_LOG_ERROR, "long_term_pic_idx overflow\n"); return AVERROR_INVALIDDATA; } ref = h->long_ref[long_idx]; assert(!(ref && !ref->reference)); if (ref && (ref->reference & pic_structure) && !mismatches_ref(h, ref)) { ref->pic_id = pic_id; assert(ref->long_ref); i = 0; } else { i = -1; } break; } default: av_log(h->avctx, AV_LOG_ERROR, "illegal modification_of_pic_nums_idc %u\n", modification_of_pic_nums_idc); return AVERROR_INVALIDDATA; } if (i < 0) { av_log(h->avctx, AV_LOG_ERROR, "reference picture missing during reorder\n"); memset(&sl->ref_list[list][index], 0, sizeof(sl->ref_list[0][0])); // FIXME } else { for (i = index; i + 1 < sl->ref_count[list]; i++) { if (sl->ref_list[list][i].parent && ref->long_ref == sl->ref_list[list][i].parent->long_ref && ref->pic_id == sl->ref_list[list][i].pic_id) break; } for (; i > index; i--) { sl->ref_list[list][i] = sl->ref_list[list][i - 1]; } ref_from_h264pic(&sl->ref_list[list][index], ref); if (FIELD_PICTURE(h)) { pic_as_field(&sl->ref_list[list][index], pic_structure); } } } } } for (list = 0; list < sl->list_count; list++) { for (index = 0; index < sl->ref_count[list]; index++) { if ( !sl->ref_list[list][index].parent || (!FIELD_PICTURE(h) && (sl->ref_list[list][index].reference&3) != 3)) { int i; av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref[list].poc); for (i = 0; i < FF_ARRAY_ELEMS(h->last_pocs); i++) h->last_pocs[i] = INT_MIN; if (h->default_ref[list].parent && !(!FIELD_PICTURE(h) && (h->default_ref[list].reference&3) != 3)) sl->ref_list[list][index] = h->default_ref[list]; else return -1; } av_assert0(av_buffer_get_ref_count(sl->ref_list[list][index].parent->f->buf[0]) > 0); } } return 0; }
int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ MpegEncContext * const s = &h->s; int list, index, pic_structure; print_short_term(h); print_long_term(h); for(list=0; list<h->list_count; list++){ memcpy(h->ref_list[list], h->default_ref_list[list], sizeof(Picture)*h->ref_count[list]); if(get_bits1(&s->gb)){ int pred= h->curr_pic_num; for(index=0; ; index++){ unsigned int reordering_of_pic_nums_idc= get_ue_golomb_31(&s->gb); unsigned int pic_id; int i; Picture *ref = NULL; if(reordering_of_pic_nums_idc==3) break; if(index >= h->ref_count[list]){ av_log(h->s.avctx, AV_LOG_ERROR, "reference count overflow\n"); return -1; } if(reordering_of_pic_nums_idc<3){ if(reordering_of_pic_nums_idc<2){ const unsigned int abs_diff_pic_num= get_ue_golomb(&s->gb) + 1; int frame_num; if(abs_diff_pic_num > h->max_pic_num){ av_log(h->s.avctx, AV_LOG_ERROR, "abs_diff_pic_num overflow\n"); return -1; } if(reordering_of_pic_nums_idc == 0) pred-= abs_diff_pic_num; else pred+= abs_diff_pic_num; pred &= h->max_pic_num - 1; frame_num = pic_num_extract(h, pred, &pic_structure); for(i= h->short_ref_count-1; i>=0; i--){ ref = h->short_ref[i]; assert(ref->reference); assert(!ref->long_ref); if( ref->frame_num == frame_num && (ref->reference & pic_structure) ) break; } if(i>=0) ref->pic_id= pred; }else{ int long_idx; pic_id= get_ue_golomb(&s->gb); //long_term_pic_idx long_idx= pic_num_extract(h, pic_id, &pic_structure); if(long_idx>31){ av_log(h->s.avctx, AV_LOG_ERROR, "long_term_pic_idx overflow\n"); return -1; } ref = h->long_ref[long_idx]; assert(!(ref && !ref->reference)); if(ref && (ref->reference & pic_structure)){ ref->pic_id= pic_id; assert(ref->long_ref); i=0; }else{ i=-1; } } if (i < 0) { av_log(h->s.avctx, AV_LOG_ERROR, "reference picture missing during reorder\n"); memset(&h->ref_list[list][index], 0, sizeof(Picture)); //FIXME } else { for(i=index; i+1<h->ref_count[list]; i++){ if(ref->long_ref == h->ref_list[list][i].long_ref && ref->pic_id == h->ref_list[list][i].pic_id) break; } for(; i > index; i--){ h->ref_list[list][i]= h->ref_list[list][i-1]; } h->ref_list[list][index]= *ref; if (FIELD_PICTURE){ pic_as_field(&h->ref_list[list][index], pic_structure); } } }else{ av_log(h->s.avctx, AV_LOG_ERROR, "illegal reordering_of_pic_nums_idc\n"); return -1; } } } } for(list=0; list<h->list_count; list++){ for(index= 0; index < h->ref_count[list]; index++){ if(!h->ref_list[list][index].data[0]){ av_log(h->s.avctx, AV_LOG_ERROR, "Missing reference picture\n"); if(h->default_ref_list[list][0].data[0]) h->ref_list[list][index]= h->default_ref_list[list][0]; else return -1; } } } return 0; }
int ff_h264_decode_ref_pic_list_reordering(H264Context *h) { int list, index, pic_structure, i; print_short_term(h); print_long_term(h); for (list = 0; list < h->list_count; list++) { for (i = 0; i < h->ref_count[list]; i++) COPY_PICTURE(&h->ref_list[list][i], &h->default_ref_list[list][i]); if (get_bits1(&h->gb)) { int pred = h->curr_pic_num; for (index = 0; ; index++) { unsigned int reordering_of_pic_nums_idc = get_ue_golomb_31(&h->gb); unsigned int pic_id; int i; Picture *ref = NULL; if (reordering_of_pic_nums_idc == 3) break; if (index >= h->ref_count[list]) { av_log(h->avctx, AV_LOG_ERROR, "reference count overflow\n"); return -1; } if (reordering_of_pic_nums_idc < 3) { if (reordering_of_pic_nums_idc < 2) { const unsigned int abs_diff_pic_num = get_ue_golomb(&h->gb) + 1; int frame_num; if (abs_diff_pic_num > h->max_pic_num) { av_log(h->avctx, AV_LOG_ERROR, "abs_diff_pic_num overflow\n"); return -1; } if (reordering_of_pic_nums_idc == 0) pred -= abs_diff_pic_num; else pred += abs_diff_pic_num; pred &= h->max_pic_num - 1; frame_num = pic_num_extract(h, pred, &pic_structure); for (i = h->short_ref_count - 1; i >= 0; i--) { ref = h->short_ref[i]; assert(ref->reference); assert(!ref->long_ref); if (ref->frame_num == frame_num && (ref->reference & pic_structure)) break; } if (i >= 0) ref->pic_id = pred; } else { int long_idx; pic_id = get_ue_golomb(&h->gb); //long_term_pic_idx long_idx = pic_num_extract(h, pic_id, &pic_structure); if (long_idx > 31) { av_log(h->avctx, AV_LOG_ERROR, "long_term_pic_idx overflow\n"); return -1; } ref = h->long_ref[long_idx]; assert(!(ref && !ref->reference)); if (ref && (ref->reference & pic_structure)) { ref->pic_id = pic_id; assert(ref->long_ref); i = 0; } else { i = -1; } } if (i < 0) { av_log(h->avctx, AV_LOG_ERROR, "reference picture missing during reorder\n"); memset(&h->ref_list[list][index], 0, sizeof(Picture)); //FIXME } else { for (i = index; i + 1 < h->ref_count[list]; i++) { if (ref->long_ref == h->ref_list[list][i].long_ref && ref->pic_id == h->ref_list[list][i].pic_id) break; } for (; i > index; i--) { COPY_PICTURE(&h->ref_list[list][i], &h->ref_list[list][i - 1]); } COPY_PICTURE(&h->ref_list[list][index], ref); if (FIELD_PICTURE(h)) { pic_as_field(&h->ref_list[list][index], pic_structure); } } } else { av_log(h->avctx, AV_LOG_ERROR, "illegal reordering_of_pic_nums_idc\n"); return -1; } } } } for (list = 0; list < h->list_count; list++) { for (index = 0; index < h->ref_count[list]; index++) { if ( !h->ref_list[list][index].f.buf[0] || (!FIELD_PICTURE(h) && (h->ref_list[list][index].reference&3) != 3)) { int i; av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref_list[list][0].poc); for (i = 0; i < FF_ARRAY_ELEMS(h->last_pocs); i++) h->last_pocs[i] = INT_MIN; if (h->default_ref_list[list][0].f.buf[0] && !(!FIELD_PICTURE(h) && (h->default_ref_list[list][0].reference&3) != 3)) COPY_PICTURE(&h->ref_list[list][index], &h->default_ref_list[list][0]); else return -1; } av_assert0(av_buffer_get_ref_count(h->ref_list[list][index].f.buf[0]) > 0); } } return 0; }
int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb) { MpegEncContext * const s = &h->s; int i; h->mmco_index= 0; if(h->nal_unit_type == NAL_IDR_SLICE) //FIXME fields { s->broken_link= get_bits1(gb) -1; if(get_bits1(gb)) { h->mmco[0].opcode= MMCO_LONG; h->mmco[0].long_arg= 0; h->mmco_index= 1; } } else { if(get_bits1(gb)) // adaptive_ref_pic_marking_mode_flag { for(i= 0; i<MAX_MMCO_COUNT; i++) { MMCOOpcode opcode= get_ue_golomb_31(gb); h->mmco[i].opcode= opcode; if(opcode==MMCO_SHORT2UNUSED || opcode==MMCO_SHORT2LONG) { h->mmco[i].short_pic_num= (h->curr_pic_num - get_ue_golomb(gb) - 1) & (h->max_pic_num - 1); /* if(h->mmco[i].short_pic_num >= h->short_ref_count || h->short_ref[ h->mmco[i].short_pic_num ] == NULL){ av_log(s->avctx, AV_LOG_ERROR, "illegal short ref in memory management control operation %d\n", mmco); return -1; }*/ } if(opcode==MMCO_SHORT2LONG || opcode==MMCO_LONG2UNUSED || opcode==MMCO_LONG || opcode==MMCO_SET_MAX_LONG) { unsigned int long_arg= get_ue_golomb_31(gb); if(long_arg >= 32 || (long_arg >= 16 && !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE))) { av_log(h->s.avctx, AV_LOG_ERROR, "illegal long ref in memory management control operation %d\n", opcode); return -1; } h->mmco[i].long_arg= long_arg; } if(opcode > (unsigned)MMCO_LONG) { av_log(h->s.avctx, AV_LOG_ERROR, "illegal memory management control operation %d\n", opcode); return -1; } if(opcode == MMCO_END) break; } h->mmco_index= i; } else { ff_generate_sliding_window_mmcos(h); } } return 0; }
/** \fn extractSPSInfo \brief Extract info from H264 SPS See 7.3.2.1 of 14496-10 */ uint8_t extractSPSInfo(uint8_t *data, uint32_t len, h264SpsInfo *info) { GetBitContext s; uint32_t profile,constraint,level,pic_order_cnt_type,w,h, mbh; uint8_t buf[len]; uint32_t outlen; uint32_t id,dum; outlen=unescapeH264(len,data,buf); init_get_bits( &s,buf, outlen*8); profile=get_bits(&s,8); constraint=get_bits(&s,8)>>5; level=get_bits(&s,8); id=get_ue_golomb(&s); // Seq parameter set id printf("[H264]Profile : %u, Level :%u, SPSid:%u\n",profile,level,id); if(profile>=100) // ?? Borrowed from H264.C/FFMPEG { printf("[H264]Warning : High profile\n"); if(get_ue_golomb(&s) == 3) //chroma_format_idc get_bits1(&s); //residual_color_transform_flag get_ue_golomb(&s); //bit_depth_luma_minus8 get_ue_golomb(&s); //bit_depth_chroma_minus8 get_bits1(&s); if (get_bits1(&s)) get_bits(&s, 8); } info->log2MaxFrameNumber = get_ue_golomb(&s); // log2_max_frame_num_minus4 printf("[H264]Log2maxFrame-4:%u\n",info->log2MaxFrameNumber); pic_order_cnt_type=get_ue_golomb(&s); printf("[H264]Pic Order Cnt Type:%u\n",pic_order_cnt_type); if(!pic_order_cnt_type) // pic_order_cnt_type { dum=get_ue_golomb(&s); //log2_max_pic_order_cnt_lsb_minus4 printf("[H264]Log2maxPix-4:%u\n",dum); } else { if(pic_order_cnt_type==1) { get_bits1(&s); //delta_pic_order_always_zero_flag get_se_golomb(&s); //offset_for_non_ref_pic get_se_golomb(&s); // offset_for_top_to_bottom_field int i=get_ue_golomb(&s); //num_ref_frames_in_pic_order_cnt_cycle for(int j=0; j<i; j++) { get_se_golomb(&s); } } else { printf("Error in SPS\n"); return 0; } } dum=get_ue_golomb(&s); //num_ref_frames printf("[H264] # of ref frames : %u\n",dum); get_bits1(&s); // gaps_in_frame_num_value_allowed_flag w = get_ue_golomb(&s) + 1; //pic_width_in_mbs_minus1 mbh = get_ue_golomb(&s) + 1; info->frameMbsOnlyFlag = get_bits1(&s); h = (2 - info->frameMbsOnlyFlag) * mbh; //pic_height_in_mbs_minus1 printf("[H264] Width in mb -1 :%d\n",w); printf("[H264] Height in mb -1 :%d\n", h); info->width = w * 16; info->height = h * 16; if (!info->frameMbsOnlyFlag) get_bits1(&s); get_bits1(&s); if(get_bits1(&s)) { get_ue_golomb(&s); get_ue_golomb(&s); get_ue_golomb(&s); get_ue_golomb(&s); } if(get_bits1(&s)) extractVUIInfo(&s, &(info->fps1000), &(info->darNum), &(info->darDen)); return 1; }
int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb){ MpegEncContext * const s = &h->s; int i; h->mmco_index= 0; if(h->nal_unit_type == NAL_IDR_SLICE){ //FIXME fields s->broken_link= get_bits1(gb) -1; if(get_bits1(gb)){ h->mmco[0].opcode= MMCO_LONG; h->mmco[0].long_arg= 0; h->mmco_index= 1; } }else{ if(get_bits1(gb)){ // adaptive_ref_pic_marking_mode_flag for(i= 0; i<MAX_MMCO_COUNT; i++) { MMCOOpcode opcode= get_ue_golomb_31(gb); h->mmco[i].opcode= opcode; if(opcode==MMCO_SHORT2UNUSED || opcode==MMCO_SHORT2LONG){ h->mmco[i].short_pic_num= (h->curr_pic_num - get_ue_golomb(gb) - 1) & (h->max_pic_num - 1); /* if(h->mmco[i].short_pic_num >= h->short_ref_count || h->short_ref[ h->mmco[i].short_pic_num ] == NULL){ av_log(s->avctx, AV_LOG_ERROR, "illegal short ref in memory management control operation %d\n", mmco); return -1; }*/ } if(opcode==MMCO_SHORT2LONG || opcode==MMCO_LONG2UNUSED || opcode==MMCO_LONG || opcode==MMCO_SET_MAX_LONG){ unsigned int long_arg= get_ue_golomb_31(gb); if(long_arg >= 32 || (long_arg >= 16 && !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE))){ av_log(h->s.avctx, AV_LOG_ERROR, "illegal long ref in memory management control operation %d\n", opcode); return -1; } h->mmco[i].long_arg= long_arg; } if(opcode > (unsigned)MMCO_LONG){ av_log(h->s.avctx, AV_LOG_ERROR, "illegal memory management control operation %d\n", opcode); return -1; } if(opcode == MMCO_END) break; } h->mmco_index= i; }else{ assert(h->long_ref_count + h->short_ref_count <= h->sps.ref_frame_count); if(h->short_ref_count && h->long_ref_count + h->short_ref_count == h->sps.ref_frame_count && !(FIELD_PICTURE && !s->first_field && s->current_picture_ptr->reference)) { h->mmco[0].opcode= MMCO_SHORT2UNUSED; h->mmco[0].short_pic_num= h->short_ref[ h->short_ref_count - 1 ]->frame_num; h->mmco_index= 1; if (FIELD_PICTURE) { h->mmco[0].short_pic_num *= 2; h->mmco[1].opcode= MMCO_SHORT2UNUSED; h->mmco[1].short_pic_num= h->mmco[0].short_pic_num + 1; h->mmco_index= 2; } } } } return 0; }
int ff_h264_pred_weight_table(GetBitContext *gb, const SPS *sps, const int *ref_count, int slice_type_nos, H264PredWeightTable *pwt, int picture_structure, void *logctx) { int list, i, j; int luma_def, chroma_def; pwt->use_weight = 0; pwt->use_weight_chroma = 0; pwt->luma_log2_weight_denom = get_ue_golomb(gb); if (pwt->luma_log2_weight_denom > 7U) { av_log(logctx, AV_LOG_ERROR, "luma_log2_weight_denom %d is out of range\n", pwt->luma_log2_weight_denom); pwt->luma_log2_weight_denom = 0; } luma_def = 1 << pwt->luma_log2_weight_denom; if (sps->chroma_format_idc) { pwt->chroma_log2_weight_denom = get_ue_golomb(gb); if (pwt->chroma_log2_weight_denom > 7U) { av_log(logctx, AV_LOG_ERROR, "chroma_log2_weight_denom %d is out of range\n", pwt->chroma_log2_weight_denom); pwt->chroma_log2_weight_denom = 0; } chroma_def = 1 << pwt->chroma_log2_weight_denom; } for (list = 0; list < 2; list++) { pwt->luma_weight_flag[list] = 0; pwt->chroma_weight_flag[list] = 0; for (i = 0; i < ref_count[list]; i++) { int luma_weight_flag, chroma_weight_flag; luma_weight_flag = get_bits1(gb); if (luma_weight_flag) { pwt->luma_weight[i][list][0] = get_se_golomb(gb); pwt->luma_weight[i][list][1] = get_se_golomb(gb); if ((int8_t)pwt->luma_weight[i][list][0] != pwt->luma_weight[i][list][0] || (int8_t)pwt->luma_weight[i][list][1] != pwt->luma_weight[i][list][1]) goto out_range_weight; if (pwt->luma_weight[i][list][0] != luma_def || pwt->luma_weight[i][list][1] != 0) { pwt->use_weight = 1; pwt->luma_weight_flag[list] = 1; } } else { pwt->luma_weight[i][list][0] = luma_def; pwt->luma_weight[i][list][1] = 0; } if (sps->chroma_format_idc) { chroma_weight_flag = get_bits1(gb); if (chroma_weight_flag) { int j; for (j = 0; j < 2; j++) { pwt->chroma_weight[i][list][j][0] = get_se_golomb(gb); pwt->chroma_weight[i][list][j][1] = get_se_golomb(gb); if ((int8_t)pwt->chroma_weight[i][list][j][0] != pwt->chroma_weight[i][list][j][0] || (int8_t)pwt->chroma_weight[i][list][j][1] != pwt->chroma_weight[i][list][j][1]) goto out_range_weight; if (pwt->chroma_weight[i][list][j][0] != chroma_def || pwt->chroma_weight[i][list][j][1] != 0) { pwt->use_weight_chroma = 1; pwt->chroma_weight_flag[list] = 1; } } } else { int j; for (j = 0; j < 2; j++) { pwt->chroma_weight[i][list][j][0] = chroma_def; pwt->chroma_weight[i][list][j][1] = 0; } } } // for MBAFF if (picture_structure == PICT_FRAME) { pwt->luma_weight[16 + 2 * i][list][0] = pwt->luma_weight[16 + 2 * i + 1][list][0] = pwt->luma_weight[i][list][0]; pwt->luma_weight[16 + 2 * i][list][1] = pwt->luma_weight[16 + 2 * i + 1][list][1] = pwt->luma_weight[i][list][1]; if (sps->chroma_format_idc) { for (j = 0; j < 2; j++) { pwt->chroma_weight[16 + 2 * i][list][j][0] = pwt->chroma_weight[16 + 2 * i + 1][list][j][0] = pwt->chroma_weight[i][list][j][0]; pwt->chroma_weight[16 + 2 * i][list][j][1] = pwt->chroma_weight[16 + 2 * i + 1][list][j][1] = pwt->chroma_weight[i][list][j][1]; } } } } if (slice_type_nos != AV_PICTURE_TYPE_B) break; } pwt->use_weight = pwt->use_weight || pwt->use_weight_chroma; return 0; out_range_weight: avpriv_request_sample(logctx, "Out of range weight\n"); return AVERROR_INVALIDDATA; }
static inline int decode_vui_parameters(H264Context *h, SPS *sps){ MpegEncContext * const s = &h->s; int aspect_ratio_info_present_flag; unsigned int aspect_ratio_idc; aspect_ratio_info_present_flag= get_bits1(&s->gb); if( aspect_ratio_info_present_flag ) { aspect_ratio_idc= get_bits(&s->gb, 8); if( aspect_ratio_idc == EXTENDED_SAR ) { sps->sar.num= get_bits(&s->gb, 16); sps->sar.den= get_bits(&s->gb, 16); }else if(aspect_ratio_idc < FF_ARRAY_ELEMS(pixel_aspect)){ sps->sar= pixel_aspect[aspect_ratio_idc]; }else{ av_log(h->s.avctx, AV_LOG_ERROR, "illegal aspect ratio\n"); return -1; } }else{ sps->sar.num= sps->sar.den= 0; } // s->avctx->aspect_ratio= sar_width*s->width / (float)(s->height*sar_height); if(get_bits1(&s->gb)){ /* overscan_info_present_flag */ get_bits1(&s->gb); /* overscan_appropriate_flag */ } sps->video_signal_type_present_flag = get_bits1(&s->gb); if(sps->video_signal_type_present_flag){ get_bits(&s->gb, 3); /* video_format */ sps->full_range = get_bits1(&s->gb); /* video_full_range_flag */ sps->colour_description_present_flag = get_bits1(&s->gb); if(sps->colour_description_present_flag){ sps->color_primaries = get_bits(&s->gb, 8); /* colour_primaries */ sps->color_trc = get_bits(&s->gb, 8); /* transfer_characteristics */ sps->colorspace = get_bits(&s->gb, 8); /* matrix_coefficients */ if (sps->color_primaries >= AVCOL_PRI_NB) sps->color_primaries = AVCOL_PRI_UNSPECIFIED; if (sps->color_trc >= AVCOL_TRC_NB) sps->color_trc = AVCOL_TRC_UNSPECIFIED; if (sps->colorspace >= AVCOL_SPC_NB) sps->colorspace = AVCOL_SPC_UNSPECIFIED; } } if(get_bits1(&s->gb)){ /* chroma_location_info_present_flag */ s->avctx->chroma_sample_location = get_ue_golomb(&s->gb)+1; /* chroma_sample_location_type_top_field */ get_ue_golomb(&s->gb); /* chroma_sample_location_type_bottom_field */ } sps->timing_info_present_flag = get_bits1(&s->gb); if(sps->timing_info_present_flag){ sps->num_units_in_tick = get_bits_long(&s->gb, 32); sps->time_scale = get_bits_long(&s->gb, 32); if(!sps->num_units_in_tick || !sps->time_scale){ av_log(h->s.avctx, AV_LOG_ERROR, "time_scale/num_units_in_tick invalid or unsupported (%d/%d)\n", sps->time_scale, sps->num_units_in_tick); return -1; } sps->fixed_frame_rate_flag = get_bits1(&s->gb); } sps->nal_hrd_parameters_present_flag = get_bits1(&s->gb); if(sps->nal_hrd_parameters_present_flag) if(decode_hrd_parameters(h, sps) < 0) return -1; sps->vcl_hrd_parameters_present_flag = get_bits1(&s->gb); if(sps->vcl_hrd_parameters_present_flag) if(decode_hrd_parameters(h, sps) < 0) return -1; if(sps->nal_hrd_parameters_present_flag || sps->vcl_hrd_parameters_present_flag) get_bits1(&s->gb); /* low_delay_hrd_flag */ sps->pic_struct_present_flag = get_bits1(&s->gb); sps->bitstream_restriction_flag = get_bits1(&s->gb); if(sps->bitstream_restriction_flag){ get_bits1(&s->gb); /* motion_vectors_over_pic_boundaries_flag */ get_ue_golomb(&s->gb); /* max_bytes_per_pic_denom */ get_ue_golomb(&s->gb); /* max_bits_per_mb_denom */ get_ue_golomb(&s->gb); /* log2_max_mv_length_horizontal */ get_ue_golomb(&s->gb); /* log2_max_mv_length_vertical */ sps->num_reorder_frames= get_ue_golomb(&s->gb); get_ue_golomb(&s->gb); /*max_dec_frame_buffering*/ if(s->gb.size_in_bits < get_bits_count(&s->gb)){ av_log(h->s.avctx, AV_LOG_ERROR, "Overread VUI by %d bits\n", get_bits_count(&s->gb) - s->gb.size_in_bits); sps->num_reorder_frames=0; sps->bitstream_restriction_flag= 0; } if(sps->num_reorder_frames > 16U /*max_dec_frame_buffering || max_dec_frame_buffering > 16*/){ av_log(h->s.avctx, AV_LOG_ERROR, "illegal num_reorder_frames %d\n", sps->num_reorder_frames); return -1; } } return 0; }
int ff_h264_decode_seq_parameter_set(H264Context *h){ MpegEncContext * const s = &h->s; int profile_idc, level_idc, constraint_set_flags = 0; unsigned int sps_id; int i, log2_max_frame_num_minus4; SPS *sps; profile_idc= get_bits(&s->gb, 8); constraint_set_flags |= get_bits1(&s->gb) << 0; //constraint_set0_flag 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 level_idc= get_bits(&s->gb, 8); sps_id= get_ue_golomb_31(&s->gb); if(sps_id >= MAX_SPS_COUNT) { av_log(h->s.avctx, AV_LOG_ERROR, "sps_id (%d) out of range\n", sps_id); return -1; } sps= av_mallocz(sizeof(SPS)); if(sps == NULL) return -1; sps->time_offset_length = 24; sps->profile_idc= profile_idc; sps->constraint_set_flags = constraint_set_flags; sps->level_idc= level_idc; memset(sps->scaling_matrix4, 16, sizeof(sps->scaling_matrix4)); memset(sps->scaling_matrix8, 16, sizeof(sps->scaling_matrix8)); sps->scaling_matrix_present = 0; 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->profile_idc == 144) { 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); } 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) { 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; } sps->transform_bypass = get_bits1(&s->gb); decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8); }else{ sps->chroma_format_idc= 1; sps->bit_depth_luma = 8; sps->bit_depth_chroma = 8; } log2_max_frame_num_minus4 = get_ue_golomb(&s->gb); if (log2_max_frame_num_minus4 < MIN_LOG2_MAX_FRAME_NUM - 4 || log2_max_frame_num_minus4 > MAX_LOG2_MAX_FRAME_NUM - 4) { av_log(h->s.avctx, AV_LOG_ERROR, "log2_max_frame_num_minus4 out of range (0-12): %d\n", log2_max_frame_num_minus4); return AVERROR_INVALIDDATA; } sps->log2_max_frame_num = log2_max_frame_num_minus4 + 4; 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; } 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); sps->offset_for_top_to_bottom_field= get_se_golomb(&s->gb); sps->poc_cycle_length = get_ue_golomb(&s->gb); if((unsigned)sps->poc_cycle_length >= FF_ARRAY_ELEMS(sps->offset_for_ref_frame)){ av_log(h->s.avctx, AV_LOG_ERROR, "poc_cycle_length overflow %u\n", sps->poc_cycle_length); goto fail; } for(i=0; i<sps->poc_cycle_length; i++) sps->offset_for_ref_frame[i]= get_se_golomb(&s->gb); }else if(sps->poc_type != 2){ av_log(h->s.avctx, AV_LOG_ERROR, "illegal POC type %d\n", sps->poc_type); goto fail; } sps->ref_frame_count= get_ue_golomb_31(&s->gb); if(sps->ref_frame_count > MAX_PICTURE_COUNT-2 || sps->ref_frame_count > 16U){ av_log(h->s.avctx, AV_LOG_ERROR, "too many reference frames\n"); goto fail; } sps->gaps_in_frame_num_allowed_flag= get_bits1(&s->gb); sps->mb_width = get_ue_golomb(&s->gb) + 1; sps->mb_height= get_ue_golomb(&s->gb) + 1; if((unsigned)sps->mb_width >= INT_MAX/16 || (unsigned)sps->mb_height >= INT_MAX/16 || av_image_check_size(16*sps->mb_width, 16*sps->mb_height, 0, h->s.avctx)){ av_log(h->s.avctx, AV_LOG_ERROR, "mb_width/height overflow\n"); goto fail; } sps->frame_mbs_only_flag= get_bits1(&s->gb); if(!sps->frame_mbs_only_flag) sps->mb_aff= get_bits1(&s->gb); else sps->mb_aff= 0; sps->direct_8x8_inference_flag= get_bits1(&s->gb); if(!sps->frame_mbs_only_flag && !sps->direct_8x8_inference_flag){ av_log(h->s.avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n"); goto fail; } #ifndef ALLOW_INTERLACE if(sps->mb_aff) av_log(h->s.avctx, AV_LOG_ERROR, "MBAFF support not included; enable it at compile-time.\n"); #endif sps->crop= get_bits1(&s->gb); if(sps->crop){ int crop_limit = sps->chroma_format_idc == 3 ? 16 : 8; sps->crop_left = get_ue_golomb(&s->gb); sps->crop_right = get_ue_golomb(&s->gb); sps->crop_top = get_ue_golomb(&s->gb); sps->crop_bottom= get_ue_golomb(&s->gb); if(sps->crop_left || sps->crop_top){ av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...\n"); } if(sps->crop_right >= crop_limit || sps->crop_bottom >= crop_limit){ av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not supported, this could look slightly wrong ...\n"); } }else{ sps->crop_left = sps->crop_right = sps->crop_top = sps->crop_bottom= 0; } sps->vui_parameters_present_flag= get_bits1(&s->gb); if( sps->vui_parameters_present_flag ) if (decode_vui_parameters(h, sps) < 0) goto fail; if(!sps->sar.den) 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", sps_id, sps->profile_idc, sps->level_idc, sps->poc_type, sps->ref_frame_count, sps->mb_width, sps->mb_height, sps->frame_mbs_only_flag ? "FRM" : (sps->mb_aff ? "MB-AFF" : "PIC-AFF"), sps->direct_8x8_inference_flag ? "8B8" : "", 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],
/** * ffdshow custom stuff (based on decode_nal_units) * Copyright (c) 2008-2012 Haruhiko Yamagata (except the parts copied from decode_nal_units) * * @param[out] recovery_frame_cnt. Valid only if GDR. * @return 0: no recovery point, 1:I-frame 2:Recovery Point SEI (GDR), 3:IDR, -1:error */ int avcodec_h264_search_recovery_point(AVCodecContext *avctx, const uint8_t *buf, int buf_size, int *recovery_frame_cnt) { H264Context *h; MpegEncContext *s; int buf_index = 0; int found = 0; // 0: no recovery point, 1:Recovery Point SEI (GDR), 2:IDR AVCodecContext *users_MpegEncContext_avctx; avctx = get_thread0_avctx(avctx); // Next frame will start on thread 0, and we want to store SPS and PPS in the context of thread 0. h = avctx->priv_data; h->is_avc = avcodec_h264_decode_init_is_avc(avctx); s = &h->s; users_MpegEncContext_avctx = s->avctx; // save it and write back before return. if (s->avctx == NULL) s->avctx = avctx; // Hack, this function can be used before decoding, so we can't expect everything initialized. h->nal_length_size = avctx->nal_length_size ? avctx->nal_length_size : 4; for(;;){ int consumed; int dst_length; int bit_length; const uint8_t *ptr; int i, nalsize = 0; if(h->is_avc) { if(buf_index >= buf_size) break; nalsize = 0; for(i = 0; i < h->nal_length_size; i++) nalsize = (nalsize << 8) | buf[buf_index++]; if(nalsize <= 1 || (nalsize+buf_index > buf_size)){ if(nalsize == 1){ buf_index++; continue; }else{ av_log(h->s.avctx, AV_LOG_ERROR, "AVC: nal size %d\n", nalsize); break; } } } else { // start code prefix search for(; buf_index + 3 < buf_size; buf_index++){ // This should always succeed in the first iteration. if(buf[buf_index] == 0 && buf[buf_index+1] == 0 && buf[buf_index+2] == 1) break; } if(buf_index+3 >= buf_size) break; buf_index+=3; } ptr= ff_h264_decode_nal(h, buf + buf_index, &dst_length, &consumed, h->is_avc ? nalsize : buf_size - buf_index); if (ptr==NULL || dst_length < 0){ found = -1; goto end; } while(ptr[dst_length - 1] == 0 && dst_length > 0) dst_length--; bit_length= !dst_length ? 0 : (8*dst_length - decode_rbsp_trailing(h, ptr + dst_length - 1)); if (h->is_avc && (nalsize != consumed)){ av_log(h->s.avctx, AV_LOG_ERROR, "AVC: Consumed only %d bytes instead of %d\n", consumed, nalsize); consumed= nalsize; } buf_index += consumed; switch(h->nal_unit_type){ case NAL_SEI: if (ptr[0] == 6/* Recovery Point SEI */){ init_get_bits(&s->gb, ptr, bit_length); ff_h264_decode_sei(h); if (found < 2) found = 2; break; } break; case NAL_SPS: init_get_bits(&s->gb, ptr, bit_length); ff_h264_decode_seq_parameter_set(h); if(s->flags& CODEC_FLAG_LOW_DELAY) s->low_delay=1; if(avctx->has_b_frames < 2) avctx->has_b_frames= !s->low_delay; break; case NAL_PPS: init_get_bits(&s->gb, ptr, bit_length); ff_h264_decode_picture_parameter_set(h, bit_length); break; case NAL_AUD: { int primary_pic_type; init_get_bits(&s->gb, ptr, bit_length); primary_pic_type = get_bits(&s->gb, 3); if (found == 0 && (primary_pic_type == 0 || primary_pic_type == 3)) // I-frame (all I/SI slices) found = 1; break; } case NAL_IDR_SLICE: case NAL_SLICE: case NAL_DPA: // decode part of slice header and find I frame init_get_bits(&s->gb, ptr, bit_length); int first_mb_in_slice = get_ue_golomb(&s->gb); unsigned int slice_type= get_ue_golomb(&s->gb); if (!is_I_slice(slice_type)) goto end; // at least one slice must start at the left top corner. // ASO should work, while FMO may not. FMO is not supported by current Libav anyway. if (first_mb_in_slice == 0) { if (h->nal_unit_type == NAL_IDR_SLICE) { found = 3; goto end; } else { if (found == 0) { found = 1; goto end; } } } break; case NAL_DPB: case NAL_DPC: case NAL_END_SEQUENCE: case NAL_END_STREAM: case NAL_FILLER_DATA: case NAL_SPS_EXT: case NAL_AUXILIARY_SLICE: break; default: av_log(avctx, AV_LOG_DEBUG, "Unknown NAL code: %d (%d bits)\n", h->nal_unit_type, bit_length); } } *recovery_frame_cnt = h->sei_recovery_frame_cnt; end: s->avctx = users_MpegEncContext_avctx; return found; }
int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb, int first_slice) { int i, ret; MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = mmco_temp; int mmco_index = 0; if (h->nal_unit_type == NAL_IDR_SLICE) { // FIXME fields skip_bits1(gb); // broken_link if (get_bits1(gb)) { mmco[0].opcode = MMCO_LONG; mmco[0].long_arg = 0; mmco_index = 1; } } else { if (get_bits1(gb)) { // adaptive_ref_pic_marking_mode_flag for (i = 0; i < MAX_MMCO_COUNT; i++) { MMCOOpcode opcode = get_ue_golomb_31(gb); mmco[i].opcode = opcode; if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG) { mmco[i].short_pic_num = (h->curr_pic_num - get_ue_golomb(gb) - 1) & (h->max_pic_num - 1); #if 0 if (mmco[i].short_pic_num >= h->short_ref_count || h->short_ref[ mmco[i].short_pic_num ] == NULL){ av_log(s->avctx, AV_LOG_ERROR, "illegal short ref in memory management control " "operation %d\n", mmco); return -1; } #endif } if (opcode == MMCO_SHORT2LONG || opcode == MMCO_LONG2UNUSED || opcode == MMCO_LONG || opcode == MMCO_SET_MAX_LONG) { unsigned int long_arg = get_ue_golomb_31(gb); if (long_arg >= 32 || (long_arg >= 16 && !(opcode == MMCO_SET_MAX_LONG && long_arg == 16) && !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE(h)))) { av_log(h->avctx, AV_LOG_ERROR, "illegal long ref in memory management control " "operation %d\n", opcode); return -1; } mmco[i].long_arg = long_arg; } if (opcode > (unsigned) MMCO_LONG) { av_log(h->avctx, AV_LOG_ERROR, "illegal memory management control operation %d\n", opcode); return -1; } if (opcode == MMCO_END) break; } mmco_index = i; } else { if (first_slice) { ret = ff_generate_sliding_window_mmcos(h, first_slice); if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE) return ret; } mmco_index = -1; } } if (first_slice && mmco_index != -1) { memcpy(h->mmco, mmco_temp, sizeof(h->mmco)); h->mmco_index = mmco_index; } else if (!first_slice && mmco_index >= 0 && (mmco_index != h->mmco_index || check_opcodes(h->mmco, mmco_temp, mmco_index))) { av_log(h->avctx, AV_LOG_ERROR, "Inconsistent MMCO state between slices [%d, %d]\n", mmco_index, h->mmco_index); return AVERROR_INVALIDDATA; } return 0; }
static int decode_recovery_point(H264Context *h){ h->sei_recovery_frame_cnt = get_ue_golomb(&h->gb); skip_bits(&h->gb, 4); /* 1b exact_match_flag, 1b broken_link_flag, 2b changing_slice_group_idc */ return 0; }
int ff_h264_pred_weight_table(GetBitContext *gb, const SPS *sps, const int *ref_count, int slice_type_nos, H264PredWeightTable *pwt) { int list, i; int luma_def, chroma_def; pwt->use_weight = 0; pwt->use_weight_chroma = 0; pwt->luma_log2_weight_denom = get_ue_golomb(gb); if (sps->chroma_format_idc) pwt->chroma_log2_weight_denom = get_ue_golomb(gb); if (pwt->luma_log2_weight_denom > 7U) { av_log(NULL, AV_LOG_ERROR, "luma_log2_weight_denom %d is out of range\n", pwt->luma_log2_weight_denom); pwt->luma_log2_weight_denom = 0; } if (pwt->chroma_log2_weight_denom > 7U) { av_log(NULL, AV_LOG_ERROR, "chroma_log2_weight_denom %d is out of range\n", pwt->chroma_log2_weight_denom); pwt->chroma_log2_weight_denom = 0; } luma_def = 1 << pwt->luma_log2_weight_denom; chroma_def = 1 << pwt->chroma_log2_weight_denom; for (list = 0; list < 2; list++) { pwt->luma_weight_flag[list] = 0; pwt->chroma_weight_flag[list] = 0; for (i = 0; i < ref_count[list]; i++) { int luma_weight_flag, chroma_weight_flag; luma_weight_flag = get_bits1(gb); if (luma_weight_flag) { pwt->luma_weight[i][list][0] = get_se_golomb(gb); pwt->luma_weight[i][list][1] = get_se_golomb(gb); if (pwt->luma_weight[i][list][0] != luma_def || pwt->luma_weight[i][list][1] != 0) { pwt->use_weight = 1; pwt->luma_weight_flag[list] = 1; } } else { pwt->luma_weight[i][list][0] = luma_def; pwt->luma_weight[i][list][1] = 0; } if (sps->chroma_format_idc) { chroma_weight_flag = get_bits1(gb); if (chroma_weight_flag) { int j; for (j = 0; j < 2; j++) { pwt->chroma_weight[i][list][j][0] = get_se_golomb(gb); pwt->chroma_weight[i][list][j][1] = get_se_golomb(gb); if (pwt->chroma_weight[i][list][j][0] != chroma_def || pwt->chroma_weight[i][list][j][1] != 0) { pwt->use_weight_chroma = 1; pwt->chroma_weight_flag[list] = 1; } } } else { int j; for (j = 0; j < 2; j++) { pwt->chroma_weight[i][list][j][0] = chroma_def; pwt->chroma_weight[i][list][j][1] = 0; } } } } if (slice_type_nos != AV_PICTURE_TYPE_B) break; } pwt->use_weight = pwt->use_weight || pwt->use_weight_chroma; return 0; }
int main(void) { int i, ret = 0; uint8_t *temp; PutBitContext pb; BitstreamContext bc; temp = av_malloc(SIZE); if (!temp) return 2; init_put_bits(&pb, temp, SIZE); for (i = 0; i < COUNT; i++) set_ue_golomb(&pb, i); flush_put_bits(&pb); bitstream_init8(&bc, temp, SIZE); for (i = 0; i < COUNT; i++) { int j, s = bitstream_peek(&bc, 25); j = get_ue_golomb(&bc); if (j != i) { fprintf(stderr, "get_ue_golomb: expected %d, got %d. bits: %7x\n", i, j, s); ret = 1; } } #define EXTEND(i) (i << 3 | i & 7) init_put_bits(&pb, temp, SIZE); for (i = 0; i < COUNT; i++) set_ue_golomb(&pb, EXTEND(i)); flush_put_bits(&pb); bitstream_init8(&bc, temp, SIZE); for (i = 0; i < COUNT; i++) { int j, s = bitstream_peek(&bc, 32); j = get_ue_golomb_long(&bc); if (j != EXTEND(i)) { fprintf(stderr, "get_ue_golomb_long: expected %d, got %d. " "bits: %8x\n", EXTEND(i), j, s); ret = 1; } } init_put_bits(&pb, temp, SIZE); for (i = 0; i < COUNT; i++) set_se_golomb(&pb, i - COUNT / 2); flush_put_bits(&pb); bitstream_init8(&bc, temp, SIZE); for (i = 0; i < COUNT; i++) { int j, s = bitstream_peek(&bc, 25); j = get_se_golomb(&bc); if (j != i - COUNT / 2) { fprintf(stderr, "get_se_golomb: expected %d, got %d. bits: %7x\n", i - COUNT / 2, j, s); ret = 1; } } av_free(temp); return ret; }