diff options
author | Mike Melanson <mike@multimedia.cx> | 2005-05-06 04:19:17 +0000 |
---|---|---|
committer | Mike Melanson <mike@multimedia.cx> | 2005-05-06 04:19:17 +0000 |
commit | fd42eb6dec2d911a8480d7b30625b27aeb34ce6c (patch) | |
tree | d72cd780ca54c7816180c2bd717ed86444b4fcd9 /src/libffmpeg/libavcodec/h264.c | |
parent | 20f83e09f4e2588b5564be12967c56717a937716 (diff) | |
download | xine-lib-fd42eb6dec2d911a8480d7b30625b27aeb34ce6c.tar.gz xine-lib-fd42eb6dec2d911a8480d7b30625b27aeb34ce6c.tar.bz2 |
syncing to FFmpeg libavcodec build 4754
CVS patchset: 7522
CVS date: 2005/05/06 04:19:17
Diffstat (limited to 'src/libffmpeg/libavcodec/h264.c')
-rw-r--r-- | src/libffmpeg/libavcodec/h264.c | 365 |
1 files changed, 132 insertions, 233 deletions
diff --git a/src/libffmpeg/libavcodec/h264.c b/src/libffmpeg/libavcodec/h264.c index 39ee4c6a2..9048886bd 100644 --- a/src/libffmpeg/libavcodec/h264.c +++ b/src/libffmpeg/libavcodec/h264.c @@ -162,7 +162,7 @@ typedef struct H264Context{ int chroma_qp; //QPc - int prev_mb_skiped; //FIXME remove (IMHO not used) + int prev_mb_skipped; //FIXME remove (IMHO not used) //prediction stuff int chroma_pred_mode; @@ -209,8 +209,8 @@ typedef struct H264Context{ */ int block_offset[2*(16+8)]; - uint16_t *mb2b_xy; //FIXME are these 4 a good idea? - uint16_t *mb2b8_xy; + uint32_t *mb2b_xy; //FIXME are these 4 a good idea? + uint32_t *mb2b8_xy; int b_stride; //FIXME use s->b4_stride int b8_stride; @@ -227,7 +227,7 @@ typedef struct H264Context{ /** * current pps */ - PPS pps; //FIXME move tp Picture perhaps? (->no) do we need that? + PPS pps; //FIXME move to Picture perhaps? (->no) do we need that? int slice_num; uint8_t *slice_table_base; @@ -370,7 +370,7 @@ static inline void fill_rectangle(void *vp, int w, int h, int stride, uint32_t v stride *= size; assert((((int)vp)&(FFMIN(w, STRIDE_ALIGN)-1)) == 0); -//FIXME check what gcc generates for 64 bit on x86 and possible write a 32 bit ver of it +//FIXME check what gcc generates for 64 bit on x86 and possibly write a 32 bit ver of it if(w==2 && h==2){ *(uint16_t*)(p + 0)= *(uint16_t*)(p + stride)= size==4 ? val : val*0x0101; @@ -428,7 +428,13 @@ static inline void fill_caches(H264Context *h, int mb_type, int for_deblock){ int left_block[8]; int i; - //wow what a mess, why didnt they simplify the interlacing&intra stuff, i cant imagine that these complex rules are worth it + //FIXME deblocking can skip fill_caches much of the time with multiple slices too. + // the actual condition is whether we're on the edge of a slice, + // and even then the intra and nnz parts are unnecessary. + if(for_deblock && h->slice_num == 1) + return; + + //wow what a mess, why didn't they simplify the interlacing&intra stuff, i can't imagine that these complex rules are worth it top_xy = mb_xy - s->mb_stride; topleft_xy = top_xy - 1; @@ -662,10 +668,10 @@ static inline void fill_caches(H264Context *h, int mb_type, int for_deblock){ #if 1 //FIXME direct mb can skip much of this - if(IS_INTER(mb_type) || (IS_DIRECT(mb_type) && h->direct_spatial_mv_pred)){ + if(IS_INTER(mb_type) || IS_DIRECT(mb_type)){ int list; - for(list=0; list<2; list++){ - if(!USES_LIST(mb_type, list) && !IS_DIRECT(mb_type) && !for_deblock){ + for(list=0; list<1+(h->slice_type==B_TYPE); list++){ + if(!USES_LIST(mb_type, list) && !IS_DIRECT(mb_type) && !h->deblocking_filter){ /*if(!h->mv_cache_clean[list]){ memset(h->mv_cache [list], 0, 8*5*2*sizeof(int16_t)); //FIXME clean only input? clean at all? memset(h->ref_cache[list], PART_NOT_AVAILABLE, 8*5*sizeof(int8_t)); @@ -675,16 +681,6 @@ static inline void fill_caches(H264Context *h, int mb_type, int for_deblock){ } h->mv_cache_clean[list]= 0; - if(IS_INTER(topleft_type)){ - const int b_xy = h->mb2b_xy[topleft_xy] + 3 + 3*h->b_stride; - const int b8_xy= h->mb2b8_xy[topleft_xy] + 1 + h->b8_stride; - *(uint32_t*)h->mv_cache[list][scan8[0] - 1 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy]; - h->ref_cache[list][scan8[0] - 1 - 1*8]= s->current_picture.ref_index[list][b8_xy]; - }else{ - *(uint32_t*)h->mv_cache[list][scan8[0] - 1 - 1*8]= 0; - h->ref_cache[list][scan8[0] - 1 - 1*8]= topleft_type ? LIST_NOT_USED : PART_NOT_AVAILABLE; - } - if(IS_INTER(top_type)){ const int b_xy= h->mb2b_xy[top_xy] + 3*h->b_stride; const int b8_xy= h->mb2b8_xy[top_xy] + h->b8_stride; @@ -704,16 +700,6 @@ static inline void fill_caches(H264Context *h, int mb_type, int for_deblock){ *(uint32_t*)&h->ref_cache[list][scan8[0] + 0 - 1*8]= ((top_type ? LIST_NOT_USED : PART_NOT_AVAILABLE)&0xFF)*0x01010101; } - if(IS_INTER(topright_type)){ - const int b_xy= h->mb2b_xy[topright_xy] + 3*h->b_stride; - const int b8_xy= h->mb2b8_xy[topright_xy] + h->b8_stride; - *(uint32_t*)h->mv_cache[list][scan8[0] + 4 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy]; - h->ref_cache[list][scan8[0] + 4 - 1*8]= s->current_picture.ref_index[list][b8_xy]; - }else{ - *(uint32_t*)h->mv_cache [list][scan8[0] + 4 - 1*8]= 0; - h->ref_cache[list][scan8[0] + 4 - 1*8]= topright_type ? LIST_NOT_USED : PART_NOT_AVAILABLE; - } - //FIXME unify cleanup or sth if(IS_INTER(left_type[0])){ const int b_xy= h->mb2b_xy[left_xy[0]] + 3; @@ -743,17 +729,38 @@ static inline void fill_caches(H264Context *h, int mb_type, int for_deblock){ h->ref_cache[list][scan8[0] - 1 + 3*8]= left_type[0] ? LIST_NOT_USED : PART_NOT_AVAILABLE; } - if(for_deblock) + if(for_deblock || (IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred)) continue; + if(IS_INTER(topleft_type)){ + const int b_xy = h->mb2b_xy[topleft_xy] + 3 + 3*h->b_stride; + const int b8_xy= h->mb2b8_xy[topleft_xy] + 1 + h->b8_stride; + *(uint32_t*)h->mv_cache[list][scan8[0] - 1 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy]; + h->ref_cache[list][scan8[0] - 1 - 1*8]= s->current_picture.ref_index[list][b8_xy]; + }else{ + *(uint32_t*)h->mv_cache[list][scan8[0] - 1 - 1*8]= 0; + h->ref_cache[list][scan8[0] - 1 - 1*8]= topleft_type ? LIST_NOT_USED : PART_NOT_AVAILABLE; + } + + if(IS_INTER(topright_type)){ + const int b_xy= h->mb2b_xy[topright_xy] + 3*h->b_stride; + const int b8_xy= h->mb2b8_xy[topright_xy] + h->b8_stride; + *(uint32_t*)h->mv_cache[list][scan8[0] + 4 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy]; + h->ref_cache[list][scan8[0] + 4 - 1*8]= s->current_picture.ref_index[list][b8_xy]; + }else{ + *(uint32_t*)h->mv_cache [list][scan8[0] + 4 - 1*8]= 0; + h->ref_cache[list][scan8[0] + 4 - 1*8]= topright_type ? LIST_NOT_USED : PART_NOT_AVAILABLE; + } + + h->ref_cache[list][scan8[5 ]+1] = h->ref_cache[list][scan8[7 ]+1] = - h->ref_cache[list][scan8[13]+1] = //FIXME remove past 3 (init somewher else) + h->ref_cache[list][scan8[13]+1] = //FIXME remove past 3 (init somewhere else) h->ref_cache[list][scan8[4 ]] = h->ref_cache[list][scan8[12]] = PART_NOT_AVAILABLE; *(uint32_t*)h->mv_cache [list][scan8[5 ]+1]= *(uint32_t*)h->mv_cache [list][scan8[7 ]+1]= - *(uint32_t*)h->mv_cache [list][scan8[13]+1]= //FIXME remove past 3 (init somewher else) + *(uint32_t*)h->mv_cache [list][scan8[13]+1]= //FIXME remove past 3 (init somewhere else) *(uint32_t*)h->mv_cache [list][scan8[4 ]]= *(uint32_t*)h->mv_cache [list][scan8[12]]= 0; @@ -796,7 +803,7 @@ static inline void fill_caches(H264Context *h, int mb_type, int for_deblock){ } *(uint32_t*)h->mvd_cache [list][scan8[5 ]+1]= *(uint32_t*)h->mvd_cache [list][scan8[7 ]+1]= - *(uint32_t*)h->mvd_cache [list][scan8[13]+1]= //FIXME remove past 3 (init somewher else) + *(uint32_t*)h->mvd_cache [list][scan8[13]+1]= //FIXME remove past 3 (init somewhere else) *(uint32_t*)h->mvd_cache [list][scan8[4 ]]= *(uint32_t*)h->mvd_cache [list][scan8[12]]= 0; @@ -1356,7 +1363,7 @@ static inline void write_back_motion(H264Context *h, int mb_type){ for(list=0; list<2; list++){ int y; if(!USES_LIST(mb_type, list)){ - if(1){ //FIXME skip or never read if mb_type doesnt use it + if(1){ //FIXME skip or never read if mb_type doesn't use it for(y=0; y<4; y++){ *(uint64_t*)s->current_picture.motion_val[list][b_xy + 0 + y*h->b_stride]= *(uint64_t*)s->current_picture.motion_val[list][b_xy + 2 + y*h->b_stride]= 0; @@ -1404,7 +1411,7 @@ static inline void write_back_motion(H264Context *h, int mb_type){ * Decodes a network abstraction layer unit. * @param consumed is the number of bytes used as input * @param length is the length of the array - * @param dst_length is the number of decoded bytes FIXME here or a decode rbsp ttailing? + * @param dst_length is the number of decoded bytes FIXME here or a decode rbsp tailing? * @returns decoded bytes, might be src+1 if no escapes */ static uint8_t *decode_nal(H264Context *h, uint8_t *src, int *dst_length, int *consumed, int length){ @@ -1441,7 +1448,7 @@ static uint8_t *decode_nal(H264Context *h, uint8_t *src, int *dst_length, int *c h->rbsp_buffer= av_fast_realloc(h->rbsp_buffer, &h->rbsp_buffer_size, length); dst= h->rbsp_buffer; -//printf("deoding esc\n"); +//printf("decoding esc\n"); si=di=0; while(si<length){ //remove escapes (very rare 1:2^22) @@ -1729,7 +1736,7 @@ static void h264_diff_dct_c(DCTELEM *block, uint8_t *src1, uint8_t *src2, int st } #endif -//FIXME need to check that this doesnt overflow signed 32 bit for low qp, iam not sure, its very close +//FIXME need to check that this doesnt overflow signed 32 bit for low qp, i am not sure, it's very close //FIXME check that gcc inlines this (and optimizes intra & seperate_dc stuff away) static inline int quantize_c(DCTELEM *block, uint8_t *scantable, int qscale, int intra, int seperate_dc){ int i; @@ -2635,7 +2642,7 @@ static void free_tables(H264Context *h){ /** * allocates tables. - * needs widzh/height + * needs width/height */ static int alloc_tables(H264Context *h){ MpegEncContext * const s = &h->s; @@ -2660,8 +2667,8 @@ static int alloc_tables(H264Context *h){ memset(h->slice_table_base, -1, big_mb_num * sizeof(uint8_t)); h->slice_table= h->slice_table_base + s->mb_stride + 1; - CHECKED_ALLOCZ(h->mb2b_xy , big_mb_num * sizeof(uint16_t)); - CHECKED_ALLOCZ(h->mb2b8_xy , big_mb_num * sizeof(uint16_t)); + CHECKED_ALLOCZ(h->mb2b_xy , big_mb_num * sizeof(uint32_t)); + CHECKED_ALLOCZ(h->mb2b8_xy , big_mb_num * sizeof(uint32_t)); for(y=0; y<s->mb_height; y++){ for(x=0; x<s->mb_width; x++){ const int mb_xy= x + y*s->mb_stride; @@ -2760,7 +2767,7 @@ static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src src_cb -= uvlinesize; src_cr -= uvlinesize; - // There is two lines saved, the line above the the top macroblock of a pair, + // There are two lines saved, the line above the the top macroblock of a pair, // and the line above the bottom macroblock h->left_border[0]= h->top_borders[0][s->mb_x][15]; for(i=1; i<17; i++){ @@ -2832,7 +2839,7 @@ static inline void backup_pair_border(H264Context *h, uint8_t *src_y, uint8_t *s src_cb -= 2 * uvlinesize; src_cr -= 2 * uvlinesize; - // There is two lines saved, the line above the the top macroblock of a pair, + // There are two lines saved, the line above the the top macroblock of a pair, // and the line above the bottom macroblock h->left_border[0]= h->top_borders[0][s->mb_x][15]; h->left_border[1]= h->top_borders[1][s->mb_x][15]; @@ -3113,7 +3120,7 @@ static void hl_decode_mb(H264Context *h){ // top s->mb_y--; tprintf("call mbaff filter_mb mb_x:%d mb_y:%d pair_dest_y = %p, dest_y = %p\n", mb_x, mb_y, pair_dest_y, dest_y); - fill_caches(h, mb_type_top, 1); //FIXME dont fill stuff which isnt used by filter_mb + fill_caches(h, mb_type_top, 1); //FIXME don't fill stuff which isn't used by filter_mb filter_mb(h, mb_x, mb_y, pair_dest_y, pair_dest_cb, pair_dest_cr, linesize, uvlinesize); if (tmp != s->current_picture.data[1][384]) { tprintf("modified pixel 8,1 (1)\n"); @@ -3121,7 +3128,7 @@ static void hl_decode_mb(H264Context *h){ // bottom s->mb_y++; tprintf("call mbaff filter_mb\n"); - fill_caches(h, mb_type_bottom, 1); //FIXME dont fill stuff which isnt used by filter_mb + fill_caches(h, mb_type_bottom, 1); //FIXME don't fill stuff which isn't used by filter_mb filter_mb(h, mb_x, mb_y+1, dest_y, dest_cb, dest_cr, linesize, uvlinesize); if (tmp != s->current_picture.data[1][384]) { tprintf("modified pixel 8,1 (2)\n"); @@ -3129,7 +3136,7 @@ static void hl_decode_mb(H264Context *h){ } else { tprintf("call filter_mb\n"); backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize); - fill_caches(h, mb_type, 1); //FIXME dont fill stuff which isnt used by filter_mb + fill_caches(h, mb_type, 1); //FIXME don't fill stuff which isn't used by filter_mb filter_mb(h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize); } } @@ -3258,7 +3265,7 @@ static int decode_ref_pic_list_reordering(H264Context *h){ print_short_term(h); print_long_term(h); - if(h->slice_type==I_TYPE || h->slice_type==SI_TYPE) return 0; //FIXME move beofre func + if(h->slice_type==I_TYPE || h->slice_type==SI_TYPE) return 0; //FIXME move before func for(list=0; list<2; list++){ memcpy(h->ref_list[list], h->default_ref_list[list], sizeof(Picture)*h->ref_count[list]); @@ -3450,9 +3457,19 @@ static void idr(H264Context *h){ h->short_ref_count=0; } +/* forget old pics after a seek */ +static void flush_dpb(AVCodecContext *avctx){ + H264Context *h= avctx->priv_data; + int i; + for(i=0; i<16; i++) + h->delayed_pic[i]= NULL; + h->delayed_output_pic= NULL; + idr(h); +} + /** * - * @return the removed picture or NULL if an error occures + * @return the removed picture or NULL if an error occurs */ static Picture * remove_short(H264Context *h, int frame_num){ MpegEncContext * const s = &h->s; @@ -3477,7 +3494,7 @@ static Picture * remove_short(H264Context *h, int frame_num){ /** * - * @return the removed picture or NULL if an error occures + * @return the removed picture or NULL if an error occurs */ static Picture * remove_long(H264Context *h, int i){ Picture *pic; @@ -3782,7 +3799,7 @@ static int decode_slice_header(H264Context *h){ } h->slice_type= slice_type; - s->pict_type= h->slice_type; // to make a few old func happy, its wrong though + s->pict_type= h->slice_type; // to make a few old func happy, it's wrong though pps_id= get_ue_golomb(&s->gb); if(pps_id>255){ @@ -3831,8 +3848,7 @@ static int decode_slice_header(H264Context *h){ s->avctx->sample_aspect_ratio.den = 1; if(h->sps.timing_info_present_flag && h->sps.fixed_frame_rate_flag){ - s->avctx->frame_rate = h->sps.time_scale; - s->avctx->frame_rate_base = h->sps.num_units_in_tick; + s->avctx->time_base= (AVRational){h->sps.num_units_in_tick, h->sps.time_scale}; } } @@ -4075,7 +4091,7 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in level_code= prefix + get_bits(gb, 4); //part }else if(prefix==15){ level_code= (prefix<<suffix_length) + get_bits(gb, 12); //part - if(suffix_length==0) level_code+=15; //FIXME doesnt make (much)sense + if(suffix_length==0) level_code+=15; //FIXME doesn't make (much)sense }else{ av_log(h->s.avctx, AV_LOG_ERROR, "prefix too large at %d %d\n", s->mb_x, s->mb_y); return -1; @@ -4198,7 +4214,7 @@ static void decode_mb_skip(H264Context *h){ s->current_picture.mb_type[mb_xy]= mb_type|MB_TYPE_SKIP; s->current_picture.qscale_table[mb_xy]= s->qscale; h->slice_table[ mb_xy ]= h->slice_num; - h->prev_mb_skiped= 1; + h->prev_mb_skipped= 1; } /** @@ -4210,7 +4226,7 @@ static int decode_mb_cavlc(H264Context *h){ const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; int mb_type, partition_count, cbp; - s->dsp.clear_blocks(h->mb); //FIXME avoid if allready clear (move after skip handlong? + s->dsp.clear_blocks(h->mb); //FIXME avoid if already clear (move after skip handlong? tprintf("pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y); cbp = 0; /* avoid warning. FIXME: find a solution without slowing @@ -4225,12 +4241,12 @@ static int decode_mb_cavlc(H264Context *h){ } } if(h->mb_aff_frame){ - if ( ((s->mb_y&1) == 0) || h->prev_mb_skiped) + if ( ((s->mb_y&1) == 0) || h->prev_mb_skipped) h->mb_field_decoding_flag = get_bits1(&s->gb); }else h->mb_field_decoding_flag= (s->picture_structure!=PICT_FRAME); - h->prev_mb_skiped= 0; + h->prev_mb_skipped= 0; mb_type= get_ue_golomb(&s->gb); if(h->slice_type == B_TYPE){ @@ -4297,10 +4313,10 @@ decode_intra_mb: } } - // In deblocking, the quantiser is 0 + // In deblocking, the quantizer is 0 s->current_picture.qscale_table[mb_xy]= 0; h->chroma_qp = get_chroma_qp(h->pps.chroma_qp_index_offset, 0); - // All coeffs are presents + // All coeffs are present memset(h->non_zero_count[mb_xy], 16, 16); return 0; @@ -4566,7 +4582,7 @@ decode_intra_mb: h->chroma_qp= chroma_qp= get_chroma_qp(h->pps.chroma_qp_index_offset, s->qscale); if(IS_INTRA16x16(mb_type)){ if( decode_residual(h, h->intra_gb_ptr, h->mb, LUMA_DC_BLOCK_INDEX, dc_scan, s->qscale, 16) < 0){ - return -1; //FIXME continue if partotioned and other retirn -1 too + return -1; //FIXME continue if partitioned and other return -1 too } assert((cbp&15) == 0 || (cbp&15) == 15); @@ -5185,7 +5201,7 @@ static int decode_mb_cabac(H264Context *h) { const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; int mb_type, partition_count, cbp = 0; - s->dsp.clear_blocks(h->mb); //FIXME avoid if allready clear (move after skip handlong?) + s->dsp.clear_blocks(h->mb); //FIXME avoid if already clear (move after skip handlong?) tprintf("pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y); if( h->slice_type != I_TYPE && h->slice_type != SI_TYPE ) { @@ -5202,12 +5218,12 @@ static int decode_mb_cabac(H264Context *h) { } } if(h->mb_aff_frame){ - if ( ((s->mb_y&1) == 0) || h->prev_mb_skiped) + if ( ((s->mb_y&1) == 0) || h->prev_mb_skipped) h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h); }else h->mb_field_decoding_flag= (s->picture_structure!=PICT_FRAME); - h->prev_mb_skiped = 0; + h->prev_mb_skipped = 0; compute_mb_neighboors(h); if( ( mb_type = decode_cabac_mb_type( h ) ) < 0 ) { @@ -5280,13 +5296,13 @@ decode_intra_mb: ff_init_cabac_decoder(&h->cabac, ptr, h->cabac.bytestream_end - ptr); - // All blocks are presents + // All blocks are present h->cbp_table[mb_xy] = 0x1ef; h->chroma_pred_mode_table[mb_xy] = 0; - // In deblocking, the quantiser is 0 + // In deblocking, the quantizer is 0 s->current_picture.qscale_table[mb_xy]= 0; h->chroma_qp = get_chroma_qp(h->pps.chroma_qp_index_offset, 0); - // All coeffs are presents + // All coeffs are present memset(h->non_zero_count[mb_xy], 16, 16); return 0; } @@ -5617,48 +5633,15 @@ static void filter_mb_edgev( H264Context *h, uint8_t *pix, int stride, int bS[4] const int alpha = alpha_table[index_a]; const int beta = beta_table[clip( qp + h->slice_beta_offset, 0, 51 )]; - for( i = 0; i < 4; i++ ) { - if( bS[i] == 0 ) { - pix += 4 * stride; - continue; - } - - if( bS[i] < 4 ) { - const int tc0 = tc0_table[index_a][bS[i] - 1]; - /* 4px edge length */ - for( d = 0; d < 4; d++ ) { - const int p0 = pix[-1]; - const int p1 = pix[-2]; - const int p2 = pix[-3]; - const int q0 = pix[0]; - const int q1 = pix[1]; - const int q2 = pix[2]; - - if( ABS( p0 - q0 ) < alpha && - ABS( p1 - p0 ) < beta && - ABS( q1 - q0 ) < beta ) { - int tc = tc0; - int i_delta; - - if( ABS( p2 - p0 ) < beta ) { - pix[-2] = p1 + clip( ( p2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( p1 << 1 ) ) >> 1, -tc0, tc0 ); - tc++; - } - if( ABS( q2 - q0 ) < beta ) { - pix[1] = q1 + clip( ( q2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( q1 << 1 ) ) >> 1, -tc0, tc0 ); - tc++; - } - - i_delta = clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); - pix[-1] = clip_uint8( p0 + i_delta ); /* p0' */ - pix[0] = clip_uint8( q0 - i_delta ); /* q0' */ - tprintf("filter_mb_edgev i:%d d:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%d\n# bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x]\n", i, d, qp, index_a, alpha, beta, tc, bS[i], pix[-3], p1, p0, q0, q1, pix[2], pix[-2], pix[-1], pix[0], pix[1]); - } - pix += stride; - } - }else{ - /* 4px edge length */ - for( d = 0; d < 4; d++ ) { + if( bS[0] < 4 ) { + int tc[4]; + for(i=0; i<4; i++) + tc[i] = bS[i] ? tc0_table[index_a][bS[i] - 1] : -1; + h->s.dsp.h264_h_loop_filter_luma(pix, stride, alpha, beta, tc); + } else { + /* 16px edge length, because bS=4 is triggered by being at + * the edge of an intra MB, so all 4 bS are the same */ + for( d = 0; d < 16; d++ ) { const int p0 = pix[-1]; const int p1 = pix[-2]; const int p2 = pix[-3]; @@ -5703,7 +5686,6 @@ static void filter_mb_edgev( H264Context *h, uint8_t *pix, int stride, int bS[4] } pix += stride; } - } } } static void filter_mb_edgecv( H264Context *h, uint8_t *pix, int stride, int bS[4], int qp ) { @@ -5712,35 +5694,14 @@ static void filter_mb_edgecv( H264Context *h, uint8_t *pix, int stride, int bS[4 const int alpha = alpha_table[index_a]; const int beta = beta_table[clip( qp + h->slice_beta_offset, 0, 51 )]; - for( i = 0; i < 4; i++ ) { - if( bS[i] == 0 ) { - pix += 2 * stride; - continue; - } - - if( bS[i] < 4 ) { - const int tc = tc0_table[index_a][bS[i] - 1] + 1; - /* 2px edge length (because we use same bS than the one for luma) */ - for( d = 0; d < 2; d++ ){ - const int p0 = pix[-1]; - const int p1 = pix[-2]; - const int q0 = pix[0]; - const int q1 = pix[1]; - - if( ABS( p0 - q0 ) < alpha && - ABS( p1 - p0 ) < beta && - ABS( q1 - q0 ) < beta ) { - const int i_delta = clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); - - pix[-1] = clip_uint8( p0 + i_delta ); /* p0' */ - pix[0] = clip_uint8( q0 - i_delta ); /* q0' */ - tprintf("filter_mb_edgecv i:%d d:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%d\n# bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x]\n", i, d, qp, index_a, alpha, beta, tc, bS[i], pix[-3], p1, p0, q0, q1, pix[2], p1, pix[-1], pix[0], q1); - } - pix += stride; - } - }else{ - /* 2px edge length (because we use same bS than the one for luma) */ - for( d = 0; d < 2; d++ ){ + if( bS[0] < 4 ) { + int tc[4]; + for(i=0; i<4; i++) + tc[i] = bS[i] ? tc0_table[index_a][bS[i] - 1] + 1 : 0; + h->s.dsp.h264_h_loop_filter_chroma(pix, stride, alpha, beta, tc); + } else { + /* 8px edge length, see filter_mb_edgev */ + for( d = 0; d < 8; d++ ){ const int p0 = pix[-1]; const int p1 = pix[-2]; const int q0 = pix[0]; @@ -5756,7 +5717,6 @@ static void filter_mb_edgecv( H264Context *h, uint8_t *pix, int stride, int bS[4 } pix += stride; } - } } } @@ -5921,49 +5881,14 @@ static void filter_mb_edgeh( H264Context *h, uint8_t *pix, int stride, int bS[4] const int beta = beta_table[clip( qp + h->slice_beta_offset, 0, 51 )]; const int pix_next = stride; - for( i = 0; i < 4; i++ ) { - if( bS[i] == 0 ) { - pix += 4; - continue; - } - - if( bS[i] < 4 ) { - const int tc0 = tc0_table[index_a][bS[i] - 1]; - /* 4px edge length */ - for( d = 0; d < 4; d++ ) { - const int p0 = pix[-1*pix_next]; - const int p1 = pix[-2*pix_next]; - const int p2 = pix[-3*pix_next]; - const int q0 = pix[0]; - const int q1 = pix[1*pix_next]; - const int q2 = pix[2*pix_next]; - - if( ABS( p0 - q0 ) < alpha && - ABS( p1 - p0 ) < beta && - ABS( q1 - q0 ) < beta ) { - - int tc = tc0; - int i_delta; - - if( ABS( p2 - p0 ) < beta ) { - pix[-2*pix_next] = p1 + clip( ( p2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( p1 << 1 ) ) >> 1, -tc0, tc0 ); - tc++; - } - if( ABS( q2 - q0 ) < beta ) { - pix[pix_next] = q1 + clip( ( q2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( q1 << 1 ) ) >> 1, -tc0, tc0 ); - tc++; - } - - i_delta = clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); - pix[-pix_next] = clip_uint8( p0 + i_delta ); /* p0' */ - pix[0] = clip_uint8( q0 - i_delta ); /* q0' */ - tprintf("filter_mb_edgeh i:%d d:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%d\n# bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x]\n", i, d, qp, index_a, alpha, beta, tc, bS[i], p2, p1, p0, q0, q1, q2, pix[-2*pix_next], pix[-pix_next], pix[0], pix[pix_next]); - } - pix++; - } - }else{ - /* 4px edge length */ - for( d = 0; d < 4; d++ ) { + if( bS[0] < 4 ) { + int tc[4]; + for(i=0; i<4; i++) + tc[i] = bS[i] ? tc0_table[index_a][bS[i] - 1] : -1; + h->s.dsp.h264_v_loop_filter_luma(pix, stride, alpha, beta, tc); + } else { + /* 16px edge length, see filter_mb_edgev */ + for( d = 0; d < 16; d++ ) { const int p0 = pix[-1*pix_next]; const int p1 = pix[-2*pix_next]; const int p2 = pix[-3*pix_next]; @@ -6006,7 +5931,6 @@ static void filter_mb_edgeh( H264Context *h, uint8_t *pix, int stride, int bS[4] } pix++; } - } } } @@ -6017,37 +5941,14 @@ static void filter_mb_edgech( H264Context *h, uint8_t *pix, int stride, int bS[4 const int beta = beta_table[clip( qp + h->slice_beta_offset, 0, 51 )]; const int pix_next = stride; - for( i = 0; i < 4; i++ ) - { - if( bS[i] == 0 ) { - pix += 2; - continue; - } - - if( bS[i] < 4 ) { - int tc = tc0_table[index_a][bS[i] - 1] + 1; - /* 2px edge length (see deblocking_filter_edgecv) */ - for( d = 0; d < 2; d++ ) { - const int p0 = pix[-1*pix_next]; - const int p1 = pix[-2*pix_next]; - const int q0 = pix[0]; - const int q1 = pix[1*pix_next]; - - if( ABS( p0 - q0 ) < alpha && - ABS( p1 - p0 ) < beta && - ABS( q1 - q0 ) < beta ) { - - int i_delta = clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); - - pix[-pix_next] = clip_uint8( p0 + i_delta ); /* p0' */ - pix[0] = clip_uint8( q0 - i_delta ); /* q0' */ - tprintf("filter_mb_edgech i:%d d:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%d\n# bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x]\n", i, d, qp, index_a, alpha, beta, tc, bS[i], pix[-3*pix_next], p1, p0, q0, q1, pix[2*pix_next], pix[-2*pix_next], pix[-pix_next], pix[0], pix[pix_next]); - } - pix++; - } - }else{ - /* 2px edge length (see deblocking_filter_edgecv) */ - for( d = 0; d < 2; d++ ) { + if( bS[0] < 4 ) { + int tc[4]; + for(i=0; i<4; i++) + tc[i] = bS[i] ? tc0_table[index_a][bS[i] - 1] + 1 : 0; + h->s.dsp.h264_v_loop_filter_chroma(pix, stride, alpha, beta, tc); + } else { + /* 8px edge length, see filter_mb_edgev */ + for( d = 0; d < 8; d++ ) { const int p0 = pix[-1*pix_next]; const int p1 = pix[-2*pix_next]; const int q0 = pix[0]; @@ -6063,7 +5964,6 @@ static void filter_mb_edgech( H264Context *h, uint8_t *pix, int stride, int bS[4 } pix++; } - } } } @@ -6072,6 +5972,10 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 const int mb_xy= mb_x + mb_y*s->mb_stride; int first_vertical_edge_done = 0; int dir; + /* FIXME: A given frame may occupy more than one position in + * the reference list. So ref2frm should be populated with + * frame numbers, not indices. */ + static const int ref2frm[18] = {-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; if (h->mb_aff_frame // left mb is in picture @@ -6081,7 +5985,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 // and left mb is in the same slice if deblocking_filter == 2 && (h->deblocking_filter!=2 || h->slice_table[mb_xy-1] == h->slice_table[mb_xy])) { /* First vertical edge is different in MBAFF frames - * There are 8 differents bS to compute and 2 differents Qp + * There are 8 different bS to compute and 2 different Qp */ int bS[8]; int qp[2]; @@ -6103,13 +6007,10 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 h->non_zero_count_cache[bn_idx] != 0 ) { bS[i] = 2; } else { - /* FIXME: A given frame may occupy more than one position in - * the reference list. So we should compare the frame numbers, - * not the indices in the ref list. */ int l; bS[i] = 0; for( l = 0; l < 1 + (h->slice_type == B_TYPE); l++ ) { - if( h->ref_cache[l][b_idx] != h->ref_cache[l][bn_idx] || + if( ref2frm[h->ref_cache[l][b_idx]+2] != ref2frm[h->ref_cache[l][bn_idx]+2] || ABS( h->mv_cache[l][b_idx][0] - h->mv_cache[l][bn_idx][0] ) >= 4 || ABS( h->mv_cache[l][b_idx][1] - h->mv_cache[l][bn_idx][1] ) >= 4 ) { bS[i] = 1; @@ -6119,7 +6020,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 } } if(bS[0]+bS[1]+bS[2]+bS[3] != 0) { - // Do not use s->qscale as luma quantiser because it has not the same + // Do not use s->qscale as luma quantizer because it has not the same // value in IPCM macroblocks. qp[0] = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[h->left_mb_xy[0]] + 1 ) >> 1; chroma_qp[0] = ( get_chroma_qp( h->pps.chroma_qp_index_offset, s->current_picture.qscale_table[mb_xy] ) + @@ -6153,7 +6054,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 /* Calculate bS */ for( edge = start; edge < 4; edge++ ) { - /* mbn_xy: neighbour macroblock */ + /* mbn_xy: neighbor macroblock */ int mbn_xy = edge > 0 ? mb_xy : mbm_xy; int bS[4]; int qp; @@ -6180,7 +6081,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 assert(0); } /* Filter edge */ - // Do not use s->qscale as luma quantiser because it has not the same + // Do not use s->qscale as luma quantizer because it has not the same // value in IPCM macroblocks. qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbn_xy] + 1 ) >> 1; tprintf("filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize); @@ -6201,7 +6102,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 assert(0); } /* Filter edge */ - // Do not use s->qscale as luma quantiser because it has not the same + // Do not use s->qscale as luma quantizer because it has not the same // value in IPCM macroblocks. qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbn_xy] + 1 ) >> 1; tprintf("filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize); @@ -6242,13 +6143,10 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 } else { - /* FIXME: A given frame may occupy more than one position in - * the reference list. So we should compare the frame numbers, - * not the indices in the ref list. */ int l; bS[i] = 0; for( l = 0; l < 1 + (h->slice_type == B_TYPE); l++ ) { - if( h->ref_cache[l][b_idx] != h->ref_cache[l][bn_idx] || + if( ref2frm[h->ref_cache[l][b_idx]+2] != ref2frm[h->ref_cache[l][bn_idx]+2] || ABS( h->mv_cache[l][b_idx][0] - h->mv_cache[l][bn_idx][0] ) >= 4 || ABS( h->mv_cache[l][b_idx][1] - h->mv_cache[l][bn_idx][1] ) >= 4 ) { bS[i] = 1; @@ -6263,7 +6161,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 } /* Filter edge */ - // Do not use s->qscale as luma quantiser because it has not the same + // Do not use s->qscale as luma quantizer because it has not the same // value in IPCM macroblocks. qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbn_xy] + 1 ) >> 1; //tprintf("filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp, s->current_picture.qscale_table[mbn_xy]); @@ -6621,7 +6519,7 @@ static inline int decode_seq_parameter_set(H264Context *h){ 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 completly supported, this could look slightly wrong ...\n"); + av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...\n"); } }else{ sps->crop_left = @@ -6843,7 +6741,7 @@ static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){ switch(h->nal_unit_type){ case NAL_IDR_SLICE: - idr(h); //FIXME ensure we dont loose some frames if there is reordering + idr(h); //FIXME ensure we don't loose some frames if there is reordering case NAL_SLICE: init_get_bits(&s->gb, ptr, bit_length); h->intra_gb_ptr= @@ -6922,12 +6820,12 @@ static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){ } /** - * retunrs the number of bytes consumed for building the current frame + * returns the number of bytes consumed for building the current frame */ static int get_consumed_bytes(MpegEncContext *s, int pos, int buf_size){ if(s->flags&CODEC_FLAG_TRUNCATED){ pos -= s->parse_context.last_index; - if(pos<0) pos=0; // FIXME remove (uneeded?) + if(pos<0) pos=0; // FIXME remove (unneeded?) return pos; }else{ @@ -7015,7 +6913,7 @@ static int decode_frame(AVCodecContext *avctx, //FIXME do something with unavailable reference frames -// if(ret==FRAME_SKIPED) return get_consumed_bytes(s, buf_index, buf_size); +// if(ret==FRAME_SKIPPED) return get_consumed_bytes(s, buf_index, buf_size); if(!s->current_picture_ptr){ av_log(h->s.avctx, AV_LOG_DEBUG, "error, NO frame\n"); return -1; @@ -7320,6 +7218,7 @@ AVCodec h264_decoder = { decode_end, decode_frame, /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, + .flush= flush_dpb, }; AVCodecParser h264_parser = { |