From 2c541554076cc8a72e7145d4da30389ca763f32f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 3 Feb 2013 11:10:05 +0100 Subject: h264: deMpegEncContextize Most of the changes are just trivial are just trivial replacements of fields from MpegEncContext with equivalent fields in H264Context. Everything in h264* other than h264.c are those trivial changes. The nontrivial parts are: 1) extracting a simplified version of the frame management code from mpegvideo.c. We don't need last/next_picture anymore, since h264 uses its own more complex system already and those were set only to appease the mpegvideo parts. 2) some tables that need to be allocated/freed in appropriate places. 3) hwaccels -- mostly trivial replacements. for dxva, the draw_horiz_band() call is moved from ff_dxva2_common_end_frame() to per-codec end_frame() callbacks, because it's now different for h264 and MpegEncContext-based decoders. 4) svq3 -- it does not use h264 complex reference system, so I just added some very simplistic frame management instead and dropped the use of ff_h264_frame_start(). Because of this I also had to move some initialization code to svq3. Additional fixes for chroma format and bit depth changes by Janne Grunau Signed-off-by: Anton Khirnov --- libavcodec/h264_refs.c | 138 +++++++++++++++++++++++-------------------------- 1 file changed, 64 insertions(+), 74 deletions(-) (limited to 'libavcodec/h264_refs.c') diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index 0e4bd76931..f855bcb377 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -106,7 +106,6 @@ static int add_sorted(Picture **sorted, Picture **src, int len, int limit, int d } int ff_h264_fill_default_ref_list(H264Context *h){ - MpegEncContext * const s = &h->s; int i, len; if(h->slice_type_nos==AV_PICTURE_TYPE_B){ @@ -115,16 +114,16 @@ int ff_h264_fill_default_ref_list(H264Context *h){ int lens[2]; if(FIELD_PICTURE) - cur_poc= s->current_picture_ptr->field_poc[ s->picture_structure == PICT_BOTTOM_FIELD ]; + cur_poc= h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD]; else - cur_poc= s->current_picture_ptr->poc; + cur_poc= h->cur_pic_ptr->poc; for(list= 0; list<2; list++){ len= add_sorted(sorted , h->short_ref, h->short_ref_count, cur_poc, 1^list); len+=add_sorted(sorted+len, h->short_ref, h->short_ref_count, cur_poc, 0^list); assert(len<=32); - len= build_def_list(h->default_ref_list[list] , sorted , len, 0, s->picture_structure); - len+=build_def_list(h->default_ref_list[list]+len, h->long_ref, 16 , 1, s->picture_structure); + len= build_def_list(h->default_ref_list[list] , sorted , len, 0, h->picture_structure); + len+=build_def_list(h->default_ref_list[list]+len, h->long_ref, 16 , 1, h->picture_structure); assert(len<=32); if(len < h->ref_count[list]) @@ -138,19 +137,19 @@ int ff_h264_fill_default_ref_list(H264Context *h){ FFSWAP(Picture, h->default_ref_list[1][0], h->default_ref_list[1][1]); } }else{ - len = build_def_list(h->default_ref_list[0] , h->short_ref, h->short_ref_count, 0, s->picture_structure); - len+= build_def_list(h->default_ref_list[0]+len, h-> long_ref, 16 , 1, s->picture_structure); + len = build_def_list(h->default_ref_list[0] , h->short_ref, h->short_ref_count, 0, h->picture_structure); + len+= build_def_list(h->default_ref_list[0]+len, h-> long_ref, 16 , 1, h->picture_structure); assert(len <= 32); if(len < h->ref_count[0]) memset(&h->default_ref_list[0][len], 0, sizeof(Picture)*(h->ref_count[0] - len)); } #ifdef TRACE for (i=0; iref_count[0]; i++) { - tprintf(h->s.avctx, "List0: %s fn:%d 0x%p\n", (h->default_ref_list[0][i].long_ref ? "LT" : "ST"), h->default_ref_list[0][i].pic_id, h->default_ref_list[0][i].f.data[0]); + tprintf(h->avctx, "List0: %s fn:%d 0x%p\n", (h->default_ref_list[0][i].long_ref ? "LT" : "ST"), h->default_ref_list[0][i].pic_id, h->default_ref_list[0][i].f.data[0]); } if(h->slice_type_nos==AV_PICTURE_TYPE_B){ for (i=0; iref_count[1]; i++) { - tprintf(h->s.avctx, "List1: %s fn:%d 0x%p\n", (h->default_ref_list[1][i].long_ref ? "LT" : "ST"), h->default_ref_list[1][i].pic_id, h->default_ref_list[1][i].f.data[0]); + tprintf(h->avctx, "List1: %s fn:%d 0x%p\n", (h->default_ref_list[1][i].long_ref ? "LT" : "ST"), h->default_ref_list[1][i].pic_id, h->default_ref_list[1][i].f.data[0]); } } #endif @@ -171,9 +170,7 @@ static void print_long_term(H264Context *h); * described by pic_num */ static int pic_num_extract(H264Context *h, int pic_num, int *structure){ - MpegEncContext * const s = &h->s; - - *structure = s->picture_structure; + *structure = h->picture_structure; if(FIELD_PICTURE){ if (!(pic_num & 1)) /* opposite field */ @@ -185,7 +182,6 @@ static int pic_num_extract(H264Context *h, int pic_num, int *structure){ } int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ - MpegEncContext * const s = &h->s; int list, index, pic_structure; print_short_term(h); @@ -194,11 +190,11 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ for(list=0; listlist_count; list++){ memcpy(h->ref_list[list], h->default_ref_list[list], sizeof(Picture)*h->ref_count[list]); - if(get_bits1(&s->gb)){ + 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(&s->gb); + unsigned int reordering_of_pic_nums_idc= get_ue_golomb_31(&h->gb); unsigned int pic_id; int i; Picture *ref = NULL; @@ -207,17 +203,17 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ break; if(index >= h->ref_count[list]){ - av_log(h->s.avctx, AV_LOG_ERROR, "reference count overflow\n"); + 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(&s->gb) + 1; + 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->s.avctx, AV_LOG_ERROR, "abs_diff_pic_num overflow\n"); + av_log(h->avctx, AV_LOG_ERROR, "abs_diff_pic_num overflow\n"); return -1; } @@ -241,12 +237,12 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ ref->pic_id= pred; }else{ int long_idx; - pic_id= get_ue_golomb(&s->gb); //long_term_pic_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->s.avctx, AV_LOG_ERROR, "long_term_pic_idx overflow\n"); + av_log(h->avctx, AV_LOG_ERROR, "long_term_pic_idx overflow\n"); return -1; } ref = h->long_ref[long_idx]; @@ -261,7 +257,7 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ } if (i < 0) { - av_log(h->s.avctx, AV_LOG_ERROR, "reference picture missing during reorder\n"); + 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+1ref_count[list]; i++){ @@ -277,7 +273,7 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ } } }else{ - av_log(h->s.avctx, AV_LOG_ERROR, "illegal reordering_of_pic_nums_idc\n"); + av_log(h->avctx, AV_LOG_ERROR, "illegal reordering_of_pic_nums_idc\n"); return -1; } } @@ -286,7 +282,7 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ for(list=0; listlist_count; list++){ for(index= 0; index < h->ref_count[list]; index++){ if (!h->ref_list[list][index].f.data[0]) { - av_log(h->s.avctx, AV_LOG_ERROR, "Missing reference picture\n"); + av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture\n"); if (h->default_ref_list[list][0].f.data[0]) h->ref_list[list][index]= h->default_ref_list[list][0]; else @@ -359,13 +355,12 @@ static inline int unreference_pic(H264Context *h, Picture *pic, int refmask){ * frame number is found */ static Picture * find_short(H264Context *h, int frame_num, int *idx){ - MpegEncContext * const s = &h->s; int i; for(i=0; ishort_ref_count; i++){ Picture *pic= h->short_ref[i]; - if(s->avctx->debug&FF_DEBUG_MMCO) - av_log(h->s.avctx, AV_LOG_DEBUG, "%d %d %p\n", i, pic->frame_num, pic); + if(h->avctx->debug&FF_DEBUG_MMCO) + av_log(h->avctx, AV_LOG_DEBUG, "%d %d %p\n", i, pic->frame_num, pic); if(pic->frame_num == frame_num) { *idx = i; return pic; @@ -392,12 +387,11 @@ static void remove_short_at_index(H264Context *h, int i){ * @return the removed picture or NULL if an error occurs */ static Picture * remove_short(H264Context *h, int frame_num, int ref_mask){ - MpegEncContext * const s = &h->s; Picture *pic; int i; - if(s->avctx->debug&FF_DEBUG_MMCO) - av_log(h->s.avctx, AV_LOG_DEBUG, "remove short %d count %d\n", frame_num, h->short_ref_count); + if(h->avctx->debug&FF_DEBUG_MMCO) + av_log(h->avctx, AV_LOG_DEBUG, "remove short %d count %d\n", frame_num, h->short_ref_count); pic = find_short(h, frame_num, &i); if (pic){ @@ -449,11 +443,11 @@ void ff_h264_remove_all_refs(H264Context *h){ */ static void print_short_term(H264Context *h) { uint32_t i; - if(h->s.avctx->debug&FF_DEBUG_MMCO) { - av_log(h->s.avctx, AV_LOG_DEBUG, "short term list:\n"); + if(h->avctx->debug&FF_DEBUG_MMCO) { + av_log(h->avctx, AV_LOG_DEBUG, "short term list:\n"); for(i=0; ishort_ref_count; i++){ Picture *pic= h->short_ref[i]; - av_log(h->s.avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n", + av_log(h->avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n", i, pic->frame_num, pic->poc, pic->f.data[0]); } } @@ -464,12 +458,12 @@ static void print_short_term(H264Context *h) { */ static void print_long_term(H264Context *h) { uint32_t i; - if(h->s.avctx->debug&FF_DEBUG_MMCO) { - av_log(h->s.avctx, AV_LOG_DEBUG, "long term list:\n"); + if(h->avctx->debug&FF_DEBUG_MMCO) { + av_log(h->avctx, AV_LOG_DEBUG, "long term list:\n"); for(i = 0; i < 16; i++){ Picture *pic= h->long_ref[i]; if (pic) { - av_log(h->s.avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n", + av_log(h->avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n", i, pic->frame_num, pic->poc, pic->f.data[0]); } } @@ -490,7 +484,6 @@ static int check_opcodes(MMCO *mmco1, MMCO *mmco2, int n_mmcos) int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice) { - MpegEncContext * const s = &h->s; MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp; int mmco_index = 0, i; @@ -498,8 +491,7 @@ int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice) 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->f.reference)) { + !(FIELD_PICTURE && !h->first_field && h->cur_pic_ptr->f.reference)) { mmco[0].opcode = MMCO_SHORT2UNUSED; mmco[0].short_pic_num = h->short_ref[h->short_ref_count - 1]->frame_num; mmco_index = 1; @@ -516,7 +508,7 @@ int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice) } else if (!first_slice && mmco_index >= 0 && (mmco_index != h->mmco_index || (i = check_opcodes(h->mmco, mmco_temp, mmco_index)))) { - av_log(h->s.avctx, AV_LOG_ERROR, + av_log(h->avctx, AV_LOG_ERROR, "Inconsistent MMCO state between slices [%d, %d, %d]\n", mmco_index, h->mmco_index, i); return AVERROR_INVALIDDATA; @@ -525,18 +517,17 @@ int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice) } int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ - MpegEncContext * const s = &h->s; int i, av_uninit(j); int current_ref_assigned=0, err=0; Picture *av_uninit(pic); - if((s->avctx->debug&FF_DEBUG_MMCO) && mmco_count==0) - av_log(h->s.avctx, AV_LOG_DEBUG, "no mmco here\n"); + if((h->avctx->debug&FF_DEBUG_MMCO) && mmco_count==0) + av_log(h->avctx, AV_LOG_DEBUG, "no mmco here\n"); for(i=0; iavctx->debug&FF_DEBUG_MMCO) - av_log(h->s.avctx, AV_LOG_DEBUG, "mmco:%d %d %d\n", h->mmco[i].opcode, h->mmco[i].short_pic_num, h->mmco[i].long_arg); + if(h->avctx->debug&FF_DEBUG_MMCO) + av_log(h->avctx, AV_LOG_DEBUG, "mmco:%d %d %d\n", h->mmco[i].opcode, h->mmco[i].short_pic_num, h->mmco[i].long_arg); if( mmco[i].opcode == MMCO_SHORT2UNUSED || mmco[i].opcode == MMCO_SHORT2LONG){ @@ -545,7 +536,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ if(!pic){ if(mmco[i].opcode != MMCO_SHORT2LONG || !h->long_ref[mmco[i].long_arg] || h->long_ref[mmco[i].long_arg]->frame_num != frame_num) { - av_log(h->s.avctx, AV_LOG_ERROR, "mmco: unref short failure\n"); + av_log(h->avctx, AV_LOG_ERROR, "mmco: unref short failure\n"); err = AVERROR_INVALIDDATA; } continue; @@ -554,8 +545,8 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ switch(mmco[i].opcode){ case MMCO_SHORT2UNUSED: - if(s->avctx->debug&FF_DEBUG_MMCO) - av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: unref short %d count %d\n", h->mmco[i].short_pic_num, h->short_ref_count); + if(h->avctx->debug&FF_DEBUG_MMCO) + av_log(h->avctx, AV_LOG_DEBUG, "mmco: unref short %d count %d\n", h->mmco[i].short_pic_num, h->short_ref_count); remove_short(h, frame_num, structure ^ PICT_FRAME); break; case MMCO_SHORT2LONG: @@ -574,8 +565,8 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ pic = h->long_ref[j]; if (pic) { remove_long(h, j, structure ^ PICT_FRAME); - } else if(s->avctx->debug&FF_DEBUG_MMCO) - av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: unref long failure\n"); + } else if(h->avctx->debug&FF_DEBUG_MMCO) + av_log(h->avctx, AV_LOG_DEBUG, "mmco: unref long failure\n"); break; case MMCO_LONG: // Comment below left from previous code as it is an interresting note. @@ -586,15 +577,15 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ * and mark this field valid. */ - if (h->long_ref[mmco[i].long_arg] != s->current_picture_ptr) { + if (h->long_ref[mmco[i].long_arg] != h->cur_pic_ptr) { remove_long(h, mmco[i].long_arg, 0); - h->long_ref[ mmco[i].long_arg ]= s->current_picture_ptr; + h->long_ref[ mmco[i].long_arg ]= h->cur_pic_ptr; h->long_ref[ mmco[i].long_arg ]->long_ref=1; h->long_ref_count++; } - s->current_picture_ptr->f.reference |= s->picture_structure; + h->cur_pic_ptr->f.reference |= h->picture_structure; current_ref_assigned=1; break; case MMCO_SET_MAX_LONG: @@ -612,9 +603,9 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ remove_long(h, j, 0); } h->frame_num= - s->current_picture_ptr->frame_num= 0; + h->cur_pic_ptr->frame_num= 0; h->mmco_reset = 1; - s->current_picture_ptr->mmco_reset=1; + h->cur_pic_ptr->mmco_reset=1; break; default: assert(0); } @@ -627,39 +618,39 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ * in long_ref; trying to put it on the short list here is an * error in the encoded bit stream (ref: 7.4.3.3, NOTE 2 and 3). */ - if (h->short_ref_count && h->short_ref[0] == s->current_picture_ptr) { + if (h->short_ref_count && h->short_ref[0] == h->cur_pic_ptr) { /* Just mark the second field valid */ - s->current_picture_ptr->f.reference = PICT_FRAME; - } else if (s->current_picture_ptr->long_ref) { - av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term reference " - "assignment for second field " - "in complementary field pair " - "(first field is long term)\n"); + h->cur_pic_ptr->f.reference = PICT_FRAME; + } else if (h->cur_pic_ptr->long_ref) { + av_log(h->avctx, AV_LOG_ERROR, "illegal short term reference " + "assignment for second field " + "in complementary field pair " + "(first field is long term)\n"); err = AVERROR_INVALIDDATA; } else { - pic= remove_short(h, s->current_picture_ptr->frame_num, 0); + pic= remove_short(h, h->cur_pic_ptr->frame_num, 0); if(pic){ - av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n"); + av_log(h->avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n"); err = AVERROR_INVALIDDATA; } if(h->short_ref_count) memmove(&h->short_ref[1], &h->short_ref[0], h->short_ref_count*sizeof(Picture*)); - h->short_ref[0]= s->current_picture_ptr; + h->short_ref[0]= h->cur_pic_ptr; h->short_ref_count++; - s->current_picture_ptr->f.reference |= s->picture_structure; + h->cur_pic_ptr->f.reference |= h->picture_structure; } } if (h->long_ref_count + h->short_ref_count - - (h->short_ref[0] == s->current_picture_ptr) > h->sps.ref_frame_count){ + (h->short_ref[0] == h->cur_pic_ptr) > h->sps.ref_frame_count){ /* We have too many reference frames, probably due to corrupted * stream. Need to discard one frame. Prevents overrun of the * short_ref and long_ref buffers. */ - av_log(h->s.avctx, AV_LOG_ERROR, + av_log(h->avctx, AV_LOG_ERROR, "number of reference frames (%d+%d) exceeds max (%d; probably " "corrupt input), discarding one\n", h->long_ref_count, h->short_ref_count, h->sps.ref_frame_count); @@ -680,19 +671,18 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ print_short_term(h); print_long_term(h); - return (h->s.avctx->err_recognition & AV_EF_EXPLODE) ? err : 0; + return (h->avctx->err_recognition & AV_EF_EXPLODE) ? err : 0; } int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb, int first_slice) { - MpegEncContext * const s = &h->s; int i, ret; MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp; int mmco_index = 0; if (h->nal_unit_type == NAL_IDR_SLICE){ // FIXME fields - s->broken_link = get_bits1(gb) - 1; + skip_bits1(gb); // broken_link if (get_bits1(gb)){ mmco[0].opcode = MMCO_LONG; mmco[0].long_arg = 0; @@ -725,7 +715,7 @@ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb, (long_arg >= 16 && !(opcode == MMCO_SET_MAX_LONG && long_arg == 16) && !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE))){ - av_log(h->s.avctx, AV_LOG_ERROR, + av_log(h->avctx, AV_LOG_ERROR, "illegal long ref in memory management control " "operation %d\n", opcode); return -1; @@ -734,7 +724,7 @@ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb, } if (opcode > (unsigned) MMCO_LONG){ - av_log(h->s.avctx, AV_LOG_ERROR, + av_log(h->avctx, AV_LOG_ERROR, "illegal memory management control operation %d\n", opcode); return -1; @@ -746,7 +736,7 @@ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb, } else { if (first_slice) { ret = ff_generate_sliding_window_mmcos(h, first_slice); - if (ret < 0 && s->avctx->err_recognition & AV_EF_EXPLODE) + if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE) return ret; } mmco_index = -1; @@ -758,7 +748,7 @@ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb, } else if (!first_slice && mmco_index >= 0 && (mmco_index != h->mmco_index || (i = check_opcodes(h->mmco, mmco_temp, mmco_index)))) { - av_log(h->s.avctx, AV_LOG_ERROR, + av_log(h->avctx, AV_LOG_ERROR, "Inconsistent MMCO state between slices [%d, %d, %d]\n", mmco_index, h->mmco_index, i); return AVERROR_INVALIDDATA; -- cgit v1.2.3