X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fh264.c;h=f0abd6bc004fd59f2aa484afd17eebd865f8c428;hb=024bf79fe0c10ef855c4ea78041c83b9c815c78f;hp=147fa56a451f0d50f6546b422c459b474dfdd72b;hpb=cc51b28299a0e2e4c79d1c169c3edd0b80282bd8;p=ffmpeg diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 147fa56a451..f0abd6bc004 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -39,16 +39,10 @@ #include "vdpau_internal.h" #include "cabac.h" -#if ARCH_X86 -#include "x86/h264_i386.h" -#endif //#undef NDEBUG #include -static void svq3_luma_dc_dequant_idct_c(DCTELEM *block, int qp); -static void svq3_add_idct_c(uint8_t *dst, DCTELEM *block, int stride, int qp, int dc); - static const uint8_t rem6[52]={ 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, }; @@ -581,7 +575,7 @@ static void hl_motion(H264Context *h, uint8_t *dest_y, uint8_t *dest_cb, uint8_t if(IS_16X16(mb_type)){ mc_part(h, 0, 1, 8, 0, dest_y, dest_cb, dest_cr, 0, 0, qpix_put[0], chroma_put[0], qpix_avg[0], chroma_avg[0], - &weight_op[0], &weight_avg[0], + weight_op, weight_avg, IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1)); }else if(IS_16X8(mb_type)){ mc_part(h, 0, 0, 4, 8, dest_y, dest_cb, dest_cr, 0, 0, @@ -666,6 +660,7 @@ static void free_tables(H264Context *h){ av_freep(&h->non_zero_count); av_freep(&h->slice_table_base); h->slice_table= NULL; + av_freep(&h->list_counts); av_freep(&h->mb2b_xy); av_freep(&h->mb2b8_xy); @@ -756,7 +751,7 @@ int ff_h264_alloc_tables(H264Context *h){ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->intra4x4_pred_mode, big_mb_num * 8 * sizeof(uint8_t), fail) - FF_ALLOCZ_OR_GOTO(h->s.avctx, h->non_zero_count , big_mb_num * 16 * sizeof(uint8_t), fail) + FF_ALLOCZ_OR_GOTO(h->s.avctx, h->non_zero_count , big_mb_num * 32 * sizeof(uint8_t), fail) FF_ALLOCZ_OR_GOTO(h->s.avctx, h->slice_table_base , (big_mb_num+s->mb_stride) * sizeof(*h->slice_table_base), fail) FF_ALLOCZ_OR_GOTO(h->s.avctx, h->cbp_table, big_mb_num * sizeof(uint16_t), fail) @@ -764,6 +759,7 @@ int ff_h264_alloc_tables(H264Context *h){ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[0], 32*big_mb_num * sizeof(uint16_t), fail); FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[1], 32*big_mb_num * sizeof(uint16_t), fail); FF_ALLOCZ_OR_GOTO(h->s.avctx, h->direct_table, 32*big_mb_num * sizeof(uint8_t) , fail); + FF_ALLOCZ_OR_GOTO(h->s.avctx, h->list_counts, big_mb_num * sizeof(uint8_t), fail) memset(h->slice_table_base, -1, (big_mb_num+s->mb_stride) * sizeof(*h->slice_table_base)); h->slice_table= h->slice_table_base + s->mb_stride*2 + 1; @@ -806,6 +802,7 @@ static void clone_tables(H264Context *dst, H264Context *src){ dst->mvd_table[0] = src->mvd_table[0]; dst->mvd_table[1] = src->mvd_table[1]; dst->direct_table = src->direct_table; + dst->list_counts = src->list_counts; dst->s.obmc_scratchpad = NULL; ff_h264_pred_init(&dst->hpc, src->s.codec_id); @@ -876,6 +873,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx){ h->thread_context[0] = h; h->outputed_poc = INT_MIN; h->prev_poc_msb= 1<<16; + h->x264_build = -1; ff_h264_reset_sei(h); if(avctx->codec_id == CODEC_ID_H264){ if(avctx->ticks_per_frame == 1){ @@ -945,12 +943,8 @@ int ff_h264_frame_start(H264Context *h){ static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize, int simple){ MpegEncContext * const s = &h->s; - int i; - int step = 1; - int offset = 1; - int uvoffset= 1; + uint8_t *top_border; int top_idx = 1; - int skiplast= 0; src_y -= linesize; src_cb -= uvlinesize; @@ -958,82 +952,52 @@ static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src if(!simple && FRAME_MBAFF){ if(s->mb_y&1){ - offset = MB_MBAFF ? 1 : 17; - uvoffset= MB_MBAFF ? 1 : 9; if(!MB_MBAFF){ - *(uint64_t*)(h->top_borders[0][s->mb_x]+ 0)= *(uint64_t*)(src_y + 15*linesize); - *(uint64_t*)(h->top_borders[0][s->mb_x]+ 8)= *(uint64_t*)(src_y +8+15*linesize); + top_border = h->top_borders[0][s->mb_x]; + AV_COPY128(top_border, src_y + 15*linesize); if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - *(uint64_t*)(h->top_borders[0][s->mb_x]+16)= *(uint64_t*)(src_cb+7*uvlinesize); - *(uint64_t*)(h->top_borders[0][s->mb_x]+24)= *(uint64_t*)(src_cr+7*uvlinesize); + AV_COPY64(top_border+16, src_cb+7*uvlinesize); + AV_COPY64(top_border+24, src_cr+7*uvlinesize); } } - }else{ - if(!MB_MBAFF){ - h->left_border[0]= h->top_borders[0][s->mb_x][15]; - if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - h->left_border[34 ]= h->top_borders[0][s->mb_x][16+7 ]; - h->left_border[34+18]= h->top_borders[0][s->mb_x][16+8+7]; - } - skiplast= 1; - } - offset = - uvoffset= - top_idx = MB_MBAFF ? 0 : 1; - } - step= MB_MBAFF ? 2 : 1; + }else if(MB_MBAFF){ + top_idx = 0; + }else + return; } + top_border = h->top_borders[top_idx][s->mb_x]; // 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[offset]= h->top_borders[top_idx][s->mb_x][15]; - for(i=1; i<17 - skiplast; i++){ - h->left_border[offset+i*step]= src_y[15+i* linesize]; - } - - *(uint64_t*)(h->top_borders[top_idx][s->mb_x]+0)= *(uint64_t*)(src_y + 16*linesize); - *(uint64_t*)(h->top_borders[top_idx][s->mb_x]+8)= *(uint64_t*)(src_y +8+16*linesize); + AV_COPY128(top_border, src_y + 16*linesize); if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - h->left_border[uvoffset+34 ]= h->top_borders[top_idx][s->mb_x][16+7]; - h->left_border[uvoffset+34+18]= h->top_borders[top_idx][s->mb_x][24+7]; - for(i=1; i<9 - skiplast; i++){ - h->left_border[uvoffset+34 +i*step]= src_cb[7+i*uvlinesize]; - h->left_border[uvoffset+34+18+i*step]= src_cr[7+i*uvlinesize]; - } - *(uint64_t*)(h->top_borders[top_idx][s->mb_x]+16)= *(uint64_t*)(src_cb+8*uvlinesize); - *(uint64_t*)(h->top_borders[top_idx][s->mb_x]+24)= *(uint64_t*)(src_cr+8*uvlinesize); + AV_COPY64(top_border+16, src_cb+8*uvlinesize); + AV_COPY64(top_border+24, src_cr+8*uvlinesize); } } static inline void xchg_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize, int xchg, int simple){ MpegEncContext * const s = &h->s; - int temp8, i; - uint64_t temp64; int deblock_left; int deblock_top; int mb_xy; - int step = 1; - int offset = 1; - int uvoffset= 1; int top_idx = 1; + uint8_t *top_border_m1; + uint8_t *top_border; if(!simple && FRAME_MBAFF){ if(s->mb_y&1){ - offset = MB_MBAFF ? 1 : 17; - uvoffset= MB_MBAFF ? 1 : 9; + if(!MB_MBAFF) + return; }else{ - offset = - uvoffset= top_idx = MB_MBAFF ? 0 : 1; } - step= MB_MBAFF ? 2 : 1; } if(h->deblocking_filter == 2) { - mb_xy = h->mb_xy; - deblock_left = h->slice_table[mb_xy] == h->slice_table[mb_xy - 1]; - deblock_top = h->slice_table[mb_xy] == h->slice_table[h->top_mb_xy]; + deblock_left = h->left_type[0]; + deblock_top = h->top_type; } else { deblock_left = (s->mb_x > 0); deblock_top = (s->mb_y > !!MB_FIELD); @@ -1043,39 +1007,32 @@ static inline void xchg_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src_c src_cb -= uvlinesize + 1; src_cr -= uvlinesize + 1; -#define XCHG(a,b,t,xchg)\ -t= a;\ -if(xchg)\ - a= b;\ -b= t; + top_border_m1 = h->top_borders[top_idx][s->mb_x-1]; + top_border = h->top_borders[top_idx][s->mb_x]; - if(deblock_left){ - for(i = !deblock_top; i<16; i++){ - XCHG(h->left_border[offset+i*step], src_y [i* linesize], temp8, xchg); - } - XCHG(h->left_border[offset+i*step], src_y [i* linesize], temp8, 1); - } +#define XCHG(a,b,xchg)\ +if (xchg) AV_SWAP64(b,a);\ +else AV_COPY64(b,a); if(deblock_top){ - XCHG(*(uint64_t*)(h->top_borders[top_idx][s->mb_x]+0), *(uint64_t*)(src_y +1), temp64, xchg); - XCHG(*(uint64_t*)(h->top_borders[top_idx][s->mb_x]+8), *(uint64_t*)(src_y +9), temp64, 1); + if(deblock_left){ + XCHG(top_border_m1+8, src_y -7, 1); + } + XCHG(top_border+0, src_y +1, xchg); + XCHG(top_border+8, src_y +9, 1); if(s->mb_x+1 < s->mb_width){ - XCHG(*(uint64_t*)(h->top_borders[top_idx][s->mb_x+1]), *(uint64_t*)(src_y +17), temp64, 1); + XCHG(h->top_borders[top_idx][s->mb_x+1], src_y +17, 1); } } if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - if(deblock_left){ - for(i = !deblock_top; i<8; i++){ - XCHG(h->left_border[uvoffset+34 +i*step], src_cb[i*uvlinesize], temp8, xchg); - XCHG(h->left_border[uvoffset+34+18+i*step], src_cr[i*uvlinesize], temp8, xchg); - } - XCHG(h->left_border[uvoffset+34 +i*step], src_cb[i*uvlinesize], temp8, 1); - XCHG(h->left_border[uvoffset+34+18+i*step], src_cr[i*uvlinesize], temp8, 1); - } if(deblock_top){ - XCHG(*(uint64_t*)(h->top_borders[top_idx][s->mb_x]+16), *(uint64_t*)(src_cb+1), temp64, 1); - XCHG(*(uint64_t*)(h->top_borders[top_idx][s->mb_x]+24), *(uint64_t*)(src_cr+1), temp64, 1); + if(deblock_left){ + XCHG(top_border_m1+16, src_cb -7, 1); + XCHG(top_border_m1+24, src_cr -7, 1); + } + XCHG(top_border+16, src_cb+1, 1); + XCHG(top_border+24, src_cr+1, 1); } } } @@ -1103,6 +1060,8 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){ s->dsp.prefetch(dest_y + (s->mb_x&3)*4*s->linesize + 64, s->linesize, 4); s->dsp.prefetch(dest_cb + (s->mb_x&7)*s->uvlinesize + 64, dest_cr - dest_cb, 2); + h->list_counts[mb_xy]= h->list_count; + if (!simple && MB_FIELD) { linesize = h->mb_linesize = s->linesize * 2; uvlinesize = h->mb_uvlinesize = s->uvlinesize * 2; @@ -1217,7 +1176,7 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){ else idct_add (ptr, h->mb + i*16, linesize); }else - svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, 0); + ff_svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, 0); } } } @@ -1229,7 +1188,7 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){ if(!transform_bypass) h264_luma_dc_dequant_idct_c(h->mb, s->qscale, h->dequant4_coeff[0][s->qscale][0]); }else - svq3_luma_dc_dequant_idct_c(h->mb, s->qscale); + ff_svq3_luma_dc_dequant_idct_c(h->mb, s->qscale); } if(h->deblocking_filter) xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0, simple); @@ -1277,7 +1236,7 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){ for(i=0; i<16; i++){ if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){ //FIXME benchmark weird rule, & below uint8_t * const ptr= dest_y + block_offset[i]; - svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, IS_INTRA(mb_type) ? 1 : 0); + ff_svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, IS_INTRA(mb_type) ? 1 : 0); } } } @@ -1312,7 +1271,7 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){ for(i=16; i<16+8; i++){ if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){ uint8_t * const ptr= dest[(i&4)>>2] + block_offset[i]; - svq3_add_idct_c(ptr, h->mb + i*16, uvlinesize, ff_h264_chroma_qp[s->qscale + 12] - 12, 2); + ff_svq3_add_idct_c(ptr, h->mb + i*16, uvlinesize, ff_h264_chroma_qp[s->qscale + 12] - 12, 2); } } } @@ -1321,18 +1280,6 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){ } if(h->cbp || IS_INTRA(mb_type)) s->dsp.clear_blocks(h->mb); - - if(h->deblocking_filter) { - backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, simple); - fill_caches(h, mb_type, 1); //FIXME don't fill stuff which isn't used by filter_mb - h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.qscale_table[mb_xy]); - h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.qscale_table[mb_xy]); - if (!simple && FRAME_MBAFF) { - ff_h264_filter_mb (h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize); - } else { - ff_h264_filter_mb_fast(h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize); - } - } } /** @@ -1753,11 +1700,6 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ h->slice_type_nos= slice_type & 3; s->pict_type= h->slice_type; // to make a few old functions happy, it's wrong though - if (s->pict_type == FF_B_TYPE && s0->last_picture_ptr == NULL) { - av_log(h->s.avctx, AV_LOG_ERROR, - "B picture before any references, skipping\n"); - return -1; - } pps_id= get_ue_golomb(&s->gb); if(pps_id>=MAX_PPS_COUNT){ @@ -1820,11 +1762,11 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ } if(h->sps.timing_info_present_flag){ - s->avctx->time_base= (AVRational){h->sps.num_units_in_tick, h->sps.time_scale}; - if(h->x264_build > 0 && h->x264_build < 44) - s->avctx->time_base.den *= 2; + int64_t den= h->sps.time_scale; + if(h->x264_build < 44U) + den *= 2; av_reduce(&s->avctx->time_base.num, &s->avctx->time_base.den, - s->avctx->time_base.num, s->avctx->time_base.den, 1<<30); + h->sps.num_units_in_tick, den, 1<<30); } s->avctx->pix_fmt = s->avctx->get_format(s->avctx, s->avctx->codec->pix_fmts); s->avctx->hwaccel = ff_find_hwaccel(s->avctx->codec->id, s->avctx->pix_fmt); @@ -2071,8 +2013,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ } h->deblocking_filter = 1; - h->slice_alpha_c0_offset = 0; - h->slice_beta_offset = 0; + h->slice_alpha_c0_offset = 52; + h->slice_beta_offset = 52; if( h->pps.deblocking_filter_parameters_present ) { tmp= get_ue_golomb_31(&s->gb); if(tmp > 2){ @@ -2084,8 +2026,13 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ h->deblocking_filter^= 1; // 1<->0 if( h->deblocking_filter ) { - h->slice_alpha_c0_offset = get_se_golomb(&s->gb) << 1; - h->slice_beta_offset = get_se_golomb(&s->gb) << 1; + h->slice_alpha_c0_offset += get_se_golomb(&s->gb) << 1; + h->slice_beta_offset += get_se_golomb(&s->gb) << 1; + if( h->slice_alpha_c0_offset > 104U + || h->slice_beta_offset > 104U){ + av_log(s->avctx, AV_LOG_ERROR, "deblocking filter parameters %d %d out of range\n", h->slice_alpha_c0_offset, h->slice_beta_offset); + return -1; + } } } @@ -2110,6 +2057,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ return 1; // deblocking switched inside frame } } + h->qp_thresh= 15 + 52 - FFMIN(h->slice_alpha_c0_offset, h->slice_beta_offset) - FFMAX3(0, h->pps.chroma_qp_index_offset[0], h->pps.chroma_qp_index_offset[1]); #if 0 //FMO if( h->pps.num_slice_groups > 1 && h->pps.mb_slice_group_map_type >= 3 && h->pps.mb_slice_group_map_type <= 5) @@ -2123,16 +2071,35 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ } for(j=0; j<2; j++){ + int id_list[16]; int *ref2frm= h->ref2frm[h->slice_num&(MAX_SLICES-1)][j]; + for(i=0; i<16; i++){ + id_list[i]= 60; + if(h->ref_list[j][i].data[0]){ + int k; + uint8_t *base= h->ref_list[j][i].base[0]; + for(k=0; kshort_ref_count; k++) + if(h->short_ref[k]->base[0] == base){ + id_list[i]= k; + break; + } + for(k=0; klong_ref_count; k++) + if(h->long_ref[k] && h->long_ref[k]->base[0] == base){ + id_list[i]= h->short_ref_count + k; + break; + } + } + } + ref2frm[0]= ref2frm[1]= -1; for(i=0; i<16; i++) - ref2frm[i+2]= 4*h->ref_list[j][i].frame_num + ref2frm[i+2]= 4*id_list[i] +(h->ref_list[j][i].reference&3); ref2frm[18+0]= ref2frm[18+1]= -1; for(i=16; i<48; i++) - ref2frm[i+4]= 4*h->ref_list[j][i].frame_num + ref2frm[i+4]= 4*id_list[(i-16)>>1] +(h->ref_list[j][i].reference&3); } @@ -2151,7 +2118,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ s->current_picture_ptr->field_poc[0], s->current_picture_ptr->field_poc[1], h->ref_count[0], h->ref_count[1], s->qscale, - h->deblocking_filter, h->slice_alpha_c0_offset/2, h->slice_beta_offset/2, + h->deblocking_filter, h->slice_alpha_c0_offset/2-26, h->slice_beta_offset/2-26, h->use_weight, h->use_weight==1 && h->use_weight_chroma ? "c" : "", h->slice_type == FF_B_TYPE ? (h->direct_spatial_mv_pred ? "SPAT" : "TEMP") : "" @@ -2161,7 +2128,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ return 0; } -int ff_h264_get_slice_type(H264Context *h) +int ff_h264_get_slice_type(const H264Context *h) { switch (h->slice_type) { case FF_P_TYPE: return 0; @@ -2173,6 +2140,76 @@ int ff_h264_get_slice_type(H264Context *h) } } +static void loop_filter(H264Context *h){ + MpegEncContext * const s = &h->s; + uint8_t *dest_y, *dest_cb, *dest_cr; + int linesize, uvlinesize, mb_x, mb_y; + const int end_mb_y= s->mb_y + FRAME_MBAFF; + const int old_slice_type= h->slice_type; + + if(h->deblocking_filter) { + for(mb_x= 0; mb_xmb_width; mb_x++){ + for(mb_y=end_mb_y - FRAME_MBAFF; mb_y<= end_mb_y; mb_y++){ + int mb_xy, mb_type; + mb_xy = h->mb_xy = mb_x + mb_y*s->mb_stride; + h->slice_num= h->slice_table[mb_xy]; + mb_type= s->current_picture.mb_type[mb_xy]; + h->list_count= h->list_counts[mb_xy]; + + if(FRAME_MBAFF) + h->mb_mbaff = h->mb_field_decoding_flag = !!IS_INTERLACED(mb_type); + + s->mb_x= mb_x; + s->mb_y= mb_y; + dest_y = s->current_picture.data[0] + (mb_x + mb_y * s->linesize ) * 16; + dest_cb = s->current_picture.data[1] + (mb_x + mb_y * s->uvlinesize) * 8; + dest_cr = s->current_picture.data[2] + (mb_x + mb_y * s->uvlinesize) * 8; + //FIXME simplify above + + if (MB_FIELD) { + linesize = h->mb_linesize = s->linesize * 2; + uvlinesize = h->mb_uvlinesize = s->uvlinesize * 2; + if(mb_y&1){ //FIXME move out of this function? + dest_y -= s->linesize*15; + dest_cb-= s->uvlinesize*7; + dest_cr-= s->uvlinesize*7; + } + } else { + linesize = h->mb_linesize = s->linesize; + uvlinesize = h->mb_uvlinesize = s->uvlinesize; + } + backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0); + if(fill_filter_caches(h, mb_type)) + continue; + h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.qscale_table[mb_xy]); + h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.qscale_table[mb_xy]); + + if (FRAME_MBAFF) { + ff_h264_filter_mb (h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize); + } else { + ff_h264_filter_mb_fast(h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize); + } + } + } + } + h->slice_type= old_slice_type; + s->mb_x= 0; + s->mb_y= end_mb_y - FRAME_MBAFF; + h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale); + h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale); +} + +static void predict_field_decoding_flag(H264Context *h){ + MpegEncContext * const s = &h->s; + const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; + int mb_type = (h->slice_table[mb_xy-1] == h->slice_num) + ? s->current_picture.mb_type[mb_xy-1] + : (h->slice_table[mb_xy-s->mb_stride] == h->slice_num) + ? s->current_picture.mb_type[mb_xy-s->mb_stride] + : 0; + h->mb_mbaff = h->mb_field_decoding_flag = IS_INTERLACED(mb_type) ? 1 : 0; +} + static int decode_slice(struct AVCodecContext *avctx, void *arg){ H264Context *h = *(void**)arg; MpegEncContext * const s = &h->s; @@ -2184,8 +2221,6 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){ (CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY)); if( h->pps.cabac ) { - int i; - /* realign */ align_get_bits( &s->gb ); @@ -2215,6 +2250,10 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){ } eos = get_cabac_terminate( &h->cabac ); + if((s->workaround_bugs & FF_BUG_TRUNCATED) && h->cabac.bytestream > h->cabac.bytestream_end + 2){ + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask); + return 0; + } if( ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 2) { av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d, bytestream (%td)\n", s->mb_x, s->mb_y, h->cabac.bytestream_end - h->cabac.bytestream); ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask); @@ -2223,10 +2262,13 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){ if( ++s->mb_x >= s->mb_width ) { s->mb_x = 0; + loop_filter(h); ff_draw_horiz_band(s, 16*s->mb_y, 16); ++s->mb_y; if(FIELD_OR_MBAFF_PICTURE) { ++s->mb_y; + if(FRAME_MBAFF && s->mb_y < s->mb_height) + predict_field_decoding_flag(h); } } @@ -2260,10 +2302,13 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){ if(++s->mb_x >= s->mb_width){ s->mb_x=0; + loop_filter(h); ff_draw_horiz_band(s, 16*s->mb_y, 16); ++s->mb_y; if(FIELD_OR_MBAFF_PICTURE) { ++s->mb_y; + if(FRAME_MBAFF && s->mb_y < s->mb_height) + predict_field_decoding_flag(h); } if(s->mb_y >= s->mb_height){ tprintf(s->avctx, "slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits); @@ -2448,8 +2493,15 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ if (ptr==NULL || dst_length < 0){ return -1; } + i= buf_index + consumed; + if((s->workaround_bugs & FF_BUG_AUTODETECT) && i+3workaround_bugs |= FF_BUG_TRUNCATED; + + if(!(s->workaround_bugs & FF_BUG_TRUNCATED)){ while(ptr[dst_length - 1] == 0 && dst_length > 0) dst_length--; + } bit_length= !dst_length ? 0 : (8*dst_length - ff_h264_decode_rbsp_trailing(h, ptr + dst_length - 1)); if(s->avctx->debug&FF_DEBUG_STARTCODE){ @@ -2484,6 +2536,9 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ if((err = decode_slice_header(hx, h))) break; + avctx->profile = hx->sps.profile_idc; + avctx->level = hx->sps.level_idc; + if (s->avctx->hwaccel && h->current_slice == 1) { if (s->avctx->hwaccel->start_frame(s->avctx, NULL, 0) < 0) return -1; @@ -2517,6 +2572,9 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ if ((err = decode_slice_header(hx, h)) < 0) break; + avctx->profile = hx->sps.profile_idc; + avctx->level = hx->sps.level_idc; + hx->s.data_partitioning = 1; break;