X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fh264.c;h=6e163937026869038da8d5c13014f1d486b3afc8;hb=90d30402b41a557e726fbb79f0fc7d6fac237eee;hp=1e7eb90fde0620c9c4978d808ef02a3bc485284b;hpb=7d54ecc9cb2c5a3d5d8b7533a774009c63a3a3a2;p=ffmpeg diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 1e7eb90fde0..6e163937026 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -86,11 +86,11 @@ static av_always_inline uint32_t pack16to32(int a, int b){ #endif } -const uint8_t ff_rem6[52]={ +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, }; -const uint8_t ff_div6[52]={ +static const uint8_t div6[52]={ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, }; @@ -182,30 +182,19 @@ static void fill_caches(H264Context *h, int mb_type, int for_deblock){ left_type[0] = h->slice_table[left_xy[0] ] < 255 ? s->current_picture.mb_type[left_xy[0]] : 0; left_type[1] = h->slice_table[left_xy[1] ] < 255 ? s->current_picture.mb_type[left_xy[1]] : 0; - if(FRAME_MBAFF && !IS_INTRA(mb_type)){ + if(MB_MBAFF && !IS_INTRA(mb_type)){ int list; - int v = *(uint16_t*)&h->non_zero_count[mb_xy][14]; - for(i=0; i<16; i++) - h->non_zero_count_cache[scan8[i]] = (v>>i)&1; for(list=0; listlist_count; list++){ + //These values where changed for ease of performing MC, we need to change them back + //FIXME maybe we can make MC and loop filter use the same values or prevent + //the MC code from changing ref_cache and rather use a temporary array. if(USES_LIST(mb_type,list)){ - uint32_t *src = (uint32_t*)s->current_picture.motion_val[list][h->mb2b_xy[mb_xy]]; - uint32_t *dst = (uint32_t*)h->mv_cache[list][scan8[0]]; int8_t *ref = &s->current_picture.ref_index[list][h->mb2b8_xy[mb_xy]]; - for(i=0; i<4; i++, dst+=8, src+=h->b_stride){ - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - dst[3] = src[3]; - } *(uint32_t*)&h->ref_cache[list][scan8[ 0]] = - *(uint32_t*)&h->ref_cache[list][scan8[ 2]] = pack16to32(ref[0],ref[1])*0x0101; + *(uint32_t*)&h->ref_cache[list][scan8[ 2]] = (pack16to32(ref[0],ref[1])&0x00FF00FF)*0x0101; ref += h->b8_stride; *(uint32_t*)&h->ref_cache[list][scan8[ 8]] = - *(uint32_t*)&h->ref_cache[list][scan8[10]] = pack16to32(ref[0],ref[1])*0x0101; - }else{ - fill_rectangle(&h-> mv_cache[list][scan8[ 0]], 4, 4, 8, 0, 4); - fill_rectangle(&h->ref_cache[list][scan8[ 0]], 4, 4, 8, (uint8_t)LIST_NOT_USED, 1); + *(uint32_t*)&h->ref_cache[list][scan8[10]] = (pack16to32(ref[0],ref[1])&0x00FF00FF)*0x0101; } } } @@ -215,30 +204,49 @@ static void fill_caches(H264Context *h, int mb_type, int for_deblock){ topright_type= h->slice_table[topright_xy] == h->slice_num ? s->current_picture.mb_type[topright_xy]: 0; left_type[0] = h->slice_table[left_xy[0] ] == h->slice_num ? s->current_picture.mb_type[left_xy[0]] : 0; left_type[1] = h->slice_table[left_xy[1] ] == h->slice_num ? s->current_picture.mb_type[left_xy[1]] : 0; - } if(IS_INTRA(mb_type)){ + int type_mask= h->pps.constrained_intra_pred ? IS_INTRA(-1) : -1; h->topleft_samples_available= h->top_samples_available= h->left_samples_available= 0xFFFF; h->topright_samples_available= 0xEEEA; - if(!IS_INTRA(top_type) && (top_type==0 || h->pps.constrained_intra_pred)){ + if(!(top_type & type_mask)){ h->topleft_samples_available= 0xB3FF; h->top_samples_available= 0x33FF; h->topright_samples_available= 0x26EA; } - for(i=0; i<2; i++){ - if(!IS_INTRA(left_type[i]) && (left_type[i]==0 || h->pps.constrained_intra_pred)){ + if(IS_INTERLACED(mb_type) != IS_INTERLACED(left_type[0])){ + if(IS_INTERLACED(mb_type)){ + if(!(left_type[0] & type_mask)){ + h->topleft_samples_available&= 0xDFFF; + h->left_samples_available&= 0x5FFF; + } + if(!(left_type[1] & type_mask)){ + h->topleft_samples_available&= 0xFF5F; + h->left_samples_available&= 0xFF5F; + } + }else{ + int left_typei = h->slice_table[left_xy[0] + s->mb_stride ] == h->slice_num + ? s->current_picture.mb_type[left_xy[0] + s->mb_stride] : 0; + assert(left_xy[0] == left_xy[1]); + if(!((left_typei & type_mask) && (left_type[0] & type_mask))){ + h->topleft_samples_available&= 0xDF5F; + h->left_samples_available&= 0x5F5F; + } + } + }else{ + if(!(left_type[0] & type_mask)){ h->topleft_samples_available&= 0xDF5F; h->left_samples_available&= 0x5F5F; } } - if(!IS_INTRA(topleft_type) && (topleft_type==0 || h->pps.constrained_intra_pred)) + if(!(topleft_type & type_mask)) h->topleft_samples_available&= 0x7FFF; - if(!IS_INTRA(topright_type) && (topright_type==0 || h->pps.constrained_intra_pred)) + if(!(topright_type & type_mask)) h->topright_samples_available&= 0xFBFF; if(IS_INTRA4x4(mb_type)){ @@ -249,7 +257,7 @@ static void fill_caches(H264Context *h, int mb_type, int for_deblock){ h->intra4x4_pred_mode_cache[7+8*0]= h->intra4x4_pred_mode[top_xy][3]; }else{ int pred; - if(!top_type || (IS_INTER(top_type) && h->pps.constrained_intra_pred)) + if(!(top_type & type_mask)) pred= -1; else{ pred= 2; @@ -265,7 +273,7 @@ static void fill_caches(H264Context *h, int mb_type, int for_deblock){ h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= h->intra4x4_pred_mode[left_xy[i]][left_block[1+2*i]]; }else{ int pred; - if(!left_type[i] || (IS_INTER(left_type[i]) && h->pps.constrained_intra_pred)) + if(!(left_type[i] & type_mask)) pred= -1; else{ pred= 2; @@ -276,6 +284,7 @@ static void fill_caches(H264Context *h, int mb_type, int for_deblock){ } } } + } /* @@ -402,7 +411,7 @@ static void fill_caches(H264Context *h, int mb_type, int for_deblock){ } } - if((for_deblock || (IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred)) && !FRAME_MBAFF) + if(for_deblock || ((IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred) && !FRAME_MBAFF)) continue; if(USES_LIST(topleft_type, list)){ @@ -576,8 +585,10 @@ static inline int check_intra4x4_pred_mode(H264Context *h){ } } - if(!(h->left_samples_available&0x8000)){ + if((h->left_samples_available&0x8888)!=0x8888){ + static const int mask[4]={0x8000,0x2000,0x80,0x20}; for(i=0; i<4; i++){ + if(!(h->left_samples_available&mask[i])){ int status= left[ h->intra4x4_pred_mode_cache[scan8[0] + 8*i] ]; if(status<0){ av_log(h->s.avctx, AV_LOG_ERROR, "left block unavailable for requested intra4x4 mode %d at %d %d\n", status, s->mb_x, s->mb_y); @@ -585,6 +596,7 @@ static inline int check_intra4x4_pred_mode(H264Context *h){ } else if(status){ h->intra4x4_pred_mode_cache[scan8[0] + 8*i]= status; } + } } } @@ -612,8 +624,11 @@ static inline int check_intra_pred_mode(H264Context *h, int mode){ } } - if(!(h->left_samples_available&0x8000)){ + if((h->left_samples_available&0x8080) != 0x8080){ mode= left[ mode ]; + if(h->left_samples_available&0x8080){ //mad cow disease mode, aka MBAFF + constrained_intra_pred + mode= ALZHEIMER_DC_L0T_PRED8x8 + (!(h->left_samples_available&0x8000)) + 2*(mode == DC_128_PRED8x8); + } if(mode<0){ av_log(h->s.avctx, AV_LOG_ERROR, "left block unavailable for requested intra mode at %d %d\n", s->mb_x, s->mb_y); return -1; @@ -656,14 +671,6 @@ static inline void write_back_non_zero_count(H264Context *h){ h->non_zero_count[mb_xy][12]=h->non_zero_count_cache[1+8*5]; h->non_zero_count[mb_xy][11]=h->non_zero_count_cache[2+8*5]; h->non_zero_count[mb_xy][10]=h->non_zero_count_cache[2+8*4]; - - if(FRAME_MBAFF){ - // store all luma nnzs, for deblocking - int v = 0, i; - for(i=0; i<16; i++) - v += (!!h->non_zero_count_cache[scan8[i]]) << i; - *(uint16_t*)&h->non_zero_count[mb_xy][14] = v; - } } /** @@ -887,68 +894,96 @@ static inline void pred_pskip_motion(H264Context * const h, int * const mx, int return; } +static int get_scale_factor(H264Context * const h, int poc, int poc1, int i){ + int poc0 = h->ref_list[0][i].poc; + int td = av_clip(poc1 - poc0, -128, 127); + if(td == 0 || h->ref_list[0][i].long_ref){ + return 256; + }else{ + int tb = av_clip(poc - poc0, -128, 127); + int tx = (16384 + (FFABS(td) >> 1)) / td; + return av_clip((tb*tx + 32) >> 6, -1024, 1023); + } +} + static inline void direct_dist_scale_factor(H264Context * const h){ MpegEncContext * const s = &h->s; const int poc = h->s.current_picture_ptr->field_poc[ s->picture_structure == PICT_BOTTOM_FIELD ]; const int poc1 = h->ref_list[1][0].poc; - int i; + int i, field; + for(field=0; field<2; field++){ + const int poc = h->s.current_picture_ptr->field_poc[field]; + const int poc1 = h->ref_list[1][0].field_poc[field]; + for(i=0; i < 2*h->ref_count[0]; i++) + h->dist_scale_factor_field[field][i^field] = get_scale_factor(h, poc, poc1, i+16); + } + for(i=0; iref_count[0]; i++){ - int poc0 = h->ref_list[0][i].poc; - int td = av_clip(poc1 - poc0, -128, 127); - if(td == 0 || h->ref_list[0][i].long_ref){ - h->dist_scale_factor[i] = 256; - }else{ - int tb = av_clip(poc - poc0, -128, 127); - int tx = (16384 + (FFABS(td) >> 1)) / td; - h->dist_scale_factor[i] = av_clip((tb*tx + 32) >> 6, -1024, 1023); - } + h->dist_scale_factor[i] = get_scale_factor(h, poc, poc1, i); } - if(FRAME_MBAFF){ - for(i=0; iref_count[0]; i++){ - h->dist_scale_factor_field[2*i] = - h->dist_scale_factor_field[2*i+1] = h->dist_scale_factor[i]; +} + +static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field, int colfield, int mbafi){ + MpegEncContext * const s = &h->s; + Picture * const ref1 = &h->ref_list[1][0]; + int j, old_ref, rfield; + int start= mbafi ? 16 : 0; + int end = mbafi ? 16+2*h->ref_count[list] : h->ref_count[list]; + int interl= mbafi || s->picture_structure != PICT_FRAME; + + /* bogus; fills in for missing frames */ + memset(map[list], 0, sizeof(map[list])); + + for(rfield=0; rfield<2; rfield++){ + for(old_ref=0; old_refref_count[colfield][list]; old_ref++){ + int poc = ref1->ref_poc[colfield][list][old_ref]; + + if (!interl) + poc |= 3; + else if( interl && (poc&3) == 3) //FIXME store all MBAFF references so this isnt needed + poc= (poc&~3) + rfield + 1; + + for(j=start; jref_list[list][j].frame_num + (h->ref_list[list][j].reference&3) == poc){ + int cur_ref= mbafi ? (j-16)^field : j; + map[list][2*old_ref + (rfield^field) + 16] = cur_ref; + if(rfield == field) + map[list][old_ref] = cur_ref; + break; + } + } } } } + static inline void direct_ref_list_init(H264Context * const h){ MpegEncContext * const s = &h->s; Picture * const ref1 = &h->ref_list[1][0]; Picture * const cur = s->current_picture_ptr; - int list, i, j; - int sidx= s->picture_structure&1; - int ref1sidx= ref1->reference&1; + int list, j, field; + int sidx= (s->picture_structure&1)^1; + int ref1sidx= (ref1->reference&1)^1; + for(list=0; list<2; list++){ cur->ref_count[sidx][list] = h->ref_count[list]; for(j=0; jref_count[list]; j++) cur->ref_poc[sidx][list][j] = 4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3); } + if(s->picture_structure == PICT_FRAME){ - memcpy(cur->ref_count[0], cur->ref_count[1], sizeof(cur->ref_count[0])); - memcpy(cur->ref_poc [0], cur->ref_poc [1], sizeof(cur->ref_poc [0])); + memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0])); + memcpy(cur->ref_poc [1], cur->ref_poc [0], sizeof(cur->ref_poc [0])); } + + cur->mbaff= FRAME_MBAFF; + if(cur->pict_type != FF_B_TYPE || h->direct_spatial_mv_pred) return; + for(list=0; list<2; list++){ - for(i=0; iref_count[ref1sidx][list]; i++){ - int poc = ref1->ref_poc[ref1sidx][list][i]; - if(((poc&3) == 3) != (s->picture_structure == PICT_FRAME)) - poc= (poc&~3) + s->picture_structure; - h->map_col_to_list0[list][i] = 0; /* bogus; fills in for missing frames */ - for(j=0; jref_count[list]; j++) - if(4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3) == poc){ - h->map_col_to_list0[list][i] = j; - break; - } - } - } - if(FRAME_MBAFF){ - for(list=0; list<2; list++){ - for(i=0; iref_count[ref1sidx][list]; i++){ - j = h->map_col_to_list0[list][i]; - h->map_col_to_list0_field[list][2*i] = 2*j; - h->map_col_to_list0_field[list][2*i+1] = 2*j+1; - } - } + fill_colmap(h, h->map_col_to_list0, list, sidx, ref1sidx, 0); + for(field=0; field<2; field++) + fill_colmap(h, h->map_col_to_list0_field[field], list, field, field, 1); } } @@ -967,15 +1002,13 @@ static inline void pred_direct_motion(H264Context * const h, int *mb_type){ #define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16|MB_TYPE_INTRA4x4|MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM) if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL/FL - if(h->ref_list[1][0].reference == PICT_FRAME){ // AFL/AFR/FR/FL -> AFL - if(!IS_INTERLACED(*mb_type)){ // AFR/FR -> AFL - int cur_poc = s->current_picture_ptr->poc; - int *col_poc = h->ref_list[1]->field_poc; - int col_parity = FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_poc); - mb_xy= s->mb_x + ((s->mb_y&~1) + col_parity)*s->mb_stride; - b8_stride = 0; - } - }else if(!(s->picture_structure & h->ref_list[1][0].reference)){// FL -> FL & differ parity + if(!IS_INTERLACED(*mb_type)){ // AFR/FR -> AFL/FL + int cur_poc = s->current_picture_ptr->poc; + int *col_poc = h->ref_list[1]->field_poc; + int col_parity = FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_poc); + mb_xy= s->mb_x + ((s->mb_y&~1) + col_parity)*s->mb_stride; + b8_stride = 0; + }else if(!(s->picture_structure & h->ref_list[1][0].reference) && !h->ref_list[1][0].mbaff){// FL -> FL & differ parity int fieldoff= 2*(h->ref_list[1][0].reference)-3; mb_xy += s->mb_stride*fieldoff; } @@ -1133,12 +1166,12 @@ single_col: fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[1], 1); /* col_zero_flag */ - if(!IS_INTRA(mb_type_col[0]) && ( l1ref0[x8 + y8*h->b8_stride] == 0 - || (l1ref0[x8 + y8*h->b8_stride] < 0 && l1ref1[x8 + y8*h->b8_stride] == 0 + if(!IS_INTRA(mb_type_col[0]) && ( l1ref0[x8 + y8*b8_stride] == 0 + || (l1ref0[x8 + y8*b8_stride] < 0 && l1ref1[x8 + y8*b8_stride] == 0 && (h->x264_build>33 || !h->x264_build)))){ - const int16_t (*l1mv)[2]= l1ref0[x8 + y8*h->b8_stride] == 0 ? l1mv0 : l1mv1; + const int16_t (*l1mv)[2]= l1ref0[x8 + y8*b8_stride] == 0 ? l1mv0 : l1mv1; if(IS_SUB_8X8(sub_mb_type)){ - const int16_t *mv_col = l1mv[x8*3 + y8*3*h->b_stride]; + const int16_t *mv_col = l1mv[x8*3 + y8*3*b4_stride]; if(FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1){ if(ref[0] == 0) fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4); @@ -1147,7 +1180,7 @@ single_col: } }else for(i4=0; i4<4; i4++){ - const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*h->b_stride]; + const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*b4_stride]; if(FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1){ if(ref[0] == 0) *(uint32_t*)h->mv_cache[0][scan8[i8*4+i4]] = 0; @@ -1161,16 +1194,19 @@ single_col: }else{ /* direct temporal mv pred */ const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_list0[1]}; const int *dist_scale_factor = h->dist_scale_factor; + int ref_offset= 0; if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){ - map_col_to_list0[0] = h->map_col_to_list0_field[0]; - map_col_to_list0[1] = h->map_col_to_list0_field[1]; - dist_scale_factor = h->dist_scale_factor_field; + map_col_to_list0[0] = h->map_col_to_list0_field[s->mb_y&1][0]; + map_col_to_list0[1] = h->map_col_to_list0_field[s->mb_y&1][1]; + dist_scale_factor =h->dist_scale_factor_field[s->mb_y&1]; } + if(h->ref_list[1][0].mbaff && IS_INTERLACED(mb_type_col[0])) + ref_offset += 16; + if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){ /* FIXME assumes direct_8x8_inference == 1 */ int y_shift = 2*!IS_INTERLACED(*mb_type); - int ref_shift= FRAME_MBAFF ? y_shift : 1; for(i8=0; i8<4; i8++){ const int x8 = i8&1; @@ -1192,9 +1228,9 @@ single_col: ref0 = l1ref0[x8 + y8*b8_stride]; if(ref0 >= 0) - ref0 = map_col_to_list0[0][ref0*2>>ref_shift]; + ref0 = map_col_to_list0[0][ref0 + ref_offset]; else{ - ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride]*2>>ref_shift]; + ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride] + ref_offset]; l1mv= l1mv1; } scale = dist_scale_factor[ref0]; @@ -1221,8 +1257,8 @@ single_col: if(IS_INTRA(mb_type_col[0])){ ref=mv0=mv1=0; }else{ - const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][l1ref0[0]] - : map_col_to_list0[1][l1ref1[0]]; + const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][l1ref0[0] + ref_offset] + : map_col_to_list0[1][l1ref1[0] + ref_offset]; const int scale = dist_scale_factor[ref0]; const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0]; int mv_l0[2]; @@ -1253,25 +1289,25 @@ single_col: continue; } - ref0 = l1ref0[x8 + y8*h->b8_stride]; + ref0 = l1ref0[x8 + y8*b8_stride] + ref_offset; if(ref0 >= 0) ref0 = map_col_to_list0[0][ref0]; else{ - ref0 = map_col_to_list0[1][l1ref1[x8 + y8*h->b8_stride]]; + ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride] + ref_offset]; l1mv= l1mv1; } scale = dist_scale_factor[ref0]; fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); if(IS_SUB_8X8(sub_mb_type)){ - const int16_t *mv_col = l1mv[x8*3 + y8*3*h->b_stride]; + const int16_t *mv_col = l1mv[x8*3 + y8*3*b4_stride]; int mx = (scale * mv_col[0] + 128) >> 8; int my = (scale * mv_col[1] + 128) >> 8; fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mx,my), 4); fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mx-mv_col[0],my-mv_col[1]), 4); }else for(i4=0; i4<4; i4++){ - const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*h->b_stride]; + const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*b4_stride]; int16_t *mv_l0 = h->mv_cache[0][scan8[i8*4+i4]]; mv_l0[0] = (scale * mv_col[0] + 128) >> 8; mv_l0[1] = (scale * mv_col[1] + 128) >> 8; @@ -1998,12 +2034,6 @@ static void free_tables(H264Context *h){ av_freep(&h->mb2b_xy); av_freep(&h->mb2b8_xy); - for(i = 0; i < MAX_SPS_COUNT; i++) - av_freep(h->sps_buffers + i); - - for(i = 0; i < MAX_PPS_COUNT; i++) - av_freep(h->pps_buffers + i); - for(i = 0; i < h->s.avctx->thread_count; i++) { hx = h->thread_context[i]; if(!hx) continue; @@ -2026,8 +2056,8 @@ static void init_dequant8_coeff_table(H264Context *h){ } for(q=0; q<52; q++){ - int shift = ff_div6[q]; - int idx = ff_rem6[q]; + int shift = div6[q]; + int idx = rem6[q]; for(x=0; x<64; x++) h->dequant8_coeff[i][q][transpose ? (x>>3)|((x&7)<<3) : x] = ((uint32_t)dequant8_coeff_init[idx][ dequant8_coeff_init_scan[((x>>1)&12) | (x&3)] ] * @@ -2051,8 +2081,8 @@ static void init_dequant4_coeff_table(H264Context *h){ continue; for(q=0; q<52; q++){ - int shift = ff_div6[q] + 2; - int idx = ff_rem6[q]; + int shift = div6[q] + 2; + int idx = rem6[q]; for(x=0; x<16; x++) h->dequant4_coeff[i][q][transpose ? (x>>2)|((x<<2)&0xF) : x] = ((uint32_t)dequant4_coeff_init[idx][(x&1) + ((x>>2)&1)] * @@ -2208,6 +2238,7 @@ static av_cold int decode_init(AVCodecContext *avctx){ h->thread_context[0] = h; h->outputed_poc = INT_MIN; + h->prev_poc_msb= 1<<16; return 0; } @@ -2270,30 +2301,63 @@ static int 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; + int top_idx = 1; + int skiplast= 0; src_y -= linesize; src_cb -= uvlinesize; src_cr -= uvlinesize; + 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); + if(simple || !ENABLE_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); + } + } + }else{ + if(!MB_MBAFF){ + h->left_border[0]= h->top_borders[0][s->mb_x][15]; + if(simple || !ENABLE_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; + } + // 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++){ - h->left_border[i]= src_y[15+i* linesize]; + 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[0][s->mb_x]+0)= *(uint64_t*)(src_y + 16*linesize); - *(uint64_t*)(h->top_borders[0][s->mb_x]+8)= *(uint64_t*)(src_y +8+16*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); if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - h->left_border[17 ]= h->top_borders[0][s->mb_x][16+7]; - h->left_border[17+9]= h->top_borders[0][s->mb_x][24+7]; - for(i=1; i<9; i++){ - h->left_border[i+17 ]= src_cb[7+i*uvlinesize]; - h->left_border[i+17+9]= src_cr[7+i*uvlinesize]; + 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[0][s->mb_x]+16)= *(uint64_t*)(src_cb+8*uvlinesize); - *(uint64_t*)(h->top_borders[0][s->mb_x]+24)= *(uint64_t*)(src_cr+8*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); } } @@ -2304,6 +2368,22 @@ static inline void xchg_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src_c int deblock_left; int deblock_top; int mb_xy; + int step = 1; + int offset = 1; + int uvoffset= 1; + int top_idx = 1; + + if(!simple && FRAME_MBAFF){ + if(s->mb_y&1){ + offset = MB_MBAFF ? 1 : 17; + uvoffset= MB_MBAFF ? 1 : 9; + }else{ + offset = + uvoffset= + top_idx = MB_MBAFF ? 0 : 1; + } + step= MB_MBAFF ? 2 : 1; + } if(h->deblocking_filter == 2) { mb_xy = h->mb_xy; @@ -2311,7 +2391,7 @@ static inline void xchg_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src_c deblock_top = h->slice_table[mb_xy] == h->slice_table[h->top_mb_xy]; } else { deblock_left = (s->mb_x > 0); - deblock_top = (s->mb_y > 0); + deblock_top = (s->mb_y > !!MB_FIELD); } src_y -= linesize + 1; @@ -2325,118 +2405,32 @@ if(xchg)\ b= t; if(deblock_left){ - for(i = !deblock_top; i<17; i++){ - XCHG(h->left_border[i ], src_y [i* linesize], temp8, xchg); + 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); } if(deblock_top){ - XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+0), *(uint64_t*)(src_y +1), temp64, xchg); - XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+8), *(uint64_t*)(src_y +9), temp64, 1); + 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(s->mb_x+1 < s->mb_width){ - XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x+1]), *(uint64_t*)(src_y +17), temp64, 1); + XCHG(*(uint64_t*)(h->top_borders[top_idx][s->mb_x+1]), *(uint64_t*)(src_y +17), temp64, 1); } } if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ if(deblock_left){ - for(i = !deblock_top; i<9; i++){ - XCHG(h->left_border[i+17 ], src_cb[i*uvlinesize], temp8, xchg); - XCHG(h->left_border[i+17+9], src_cr[i*uvlinesize], temp8, xchg); + 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[0][s->mb_x]+16), *(uint64_t*)(src_cb+1), temp64, 1); - XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+24), *(uint64_t*)(src_cr+1), temp64, 1); - } - } -} - -static inline void backup_pair_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize){ - MpegEncContext * const s = &h->s; - int i; - - src_y -= 2 * linesize; - src_cb -= 2 * uvlinesize; - src_cr -= 2 * uvlinesize; - - // 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]; - for(i=2; i<34; i++){ - h->left_border[i]= src_y[15+i* linesize]; - } - - *(uint64_t*)(h->top_borders[0][s->mb_x]+0)= *(uint64_t*)(src_y + 32*linesize); - *(uint64_t*)(h->top_borders[0][s->mb_x]+8)= *(uint64_t*)(src_y +8+32*linesize); - *(uint64_t*)(h->top_borders[1][s->mb_x]+0)= *(uint64_t*)(src_y + 33*linesize); - *(uint64_t*)(h->top_borders[1][s->mb_x]+8)= *(uint64_t*)(src_y +8+33*linesize); - - if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - h->left_border[34 ]= h->top_borders[0][s->mb_x][16+7]; - h->left_border[34+ 1]= h->top_borders[1][s->mb_x][16+7]; - h->left_border[34+18 ]= h->top_borders[0][s->mb_x][24+7]; - h->left_border[34+18+1]= h->top_borders[1][s->mb_x][24+7]; - for(i=2; i<18; i++){ - h->left_border[i+34 ]= src_cb[7+i*uvlinesize]; - h->left_border[i+34+18]= src_cr[7+i*uvlinesize]; - } - *(uint64_t*)(h->top_borders[0][s->mb_x]+16)= *(uint64_t*)(src_cb+16*uvlinesize); - *(uint64_t*)(h->top_borders[0][s->mb_x]+24)= *(uint64_t*)(src_cr+16*uvlinesize); - *(uint64_t*)(h->top_borders[1][s->mb_x]+16)= *(uint64_t*)(src_cb+17*uvlinesize); - *(uint64_t*)(h->top_borders[1][s->mb_x]+24)= *(uint64_t*)(src_cr+17*uvlinesize); - } -} - -static inline void xchg_pair_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize, int xchg){ - MpegEncContext * const s = &h->s; - int temp8, i; - uint64_t temp64; - int deblock_left = (s->mb_x > 0); - int deblock_top = (s->mb_y > 1); - - tprintf(s->avctx, "xchg_pair_border: src_y:%p src_cb:%p src_cr:%p ls:%d uvls:%d\n", src_y, src_cb, src_cr, linesize, uvlinesize); - - src_y -= 2 * linesize + 1; - src_cb -= 2 * uvlinesize + 1; - src_cr -= 2 * uvlinesize + 1; - -#define XCHG(a,b,t,xchg)\ -t= a;\ -if(xchg)\ - a= b;\ -b= t; - - if(deblock_left){ - for(i = (!deblock_top)<<1; i<34; i++){ - XCHG(h->left_border[i ], src_y [i* linesize], temp8, xchg); - } - } - - if(deblock_top){ - XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+0), *(uint64_t*)(src_y +1), temp64, xchg); - XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+8), *(uint64_t*)(src_y +9), temp64, 1); - XCHG(*(uint64_t*)(h->top_borders[1][s->mb_x]+0), *(uint64_t*)(src_y +1 +linesize), temp64, xchg); - XCHG(*(uint64_t*)(h->top_borders[1][s->mb_x]+8), *(uint64_t*)(src_y +9 +linesize), temp64, 1); - if(s->mb_x+1 < s->mb_width){ - XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x+1]), *(uint64_t*)(src_y +17), temp64, 1); - XCHG(*(uint64_t*)(h->top_borders[1][s->mb_x+1]), *(uint64_t*)(src_y +17 +linesize), temp64, 1); - } - } - - if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - if(deblock_left){ - for(i = (!deblock_top) << 1; i<18; i++){ - XCHG(h->left_border[i+34 ], src_cb[i*uvlinesize], temp8, xchg); - XCHG(h->left_border[i+34+18], src_cr[i*uvlinesize], temp8, xchg); - } - } - if(deblock_top){ - XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+16), *(uint64_t*)(src_cb+1), temp64, 1); - XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+24), *(uint64_t*)(src_cr+1), temp64, 1); - XCHG(*(uint64_t*)(h->top_borders[1][s->mb_x]+16), *(uint64_t*)(src_cb+1 +uvlinesize), temp64, 1); - XCHG(*(uint64_t*)(h->top_borders[1][s->mb_x]+24), *(uint64_t*)(src_cr+1 +uvlinesize), temp64, 1); + 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); } } } @@ -2451,7 +2445,6 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){ int linesize, uvlinesize /*dct_offset*/; int i; int *block_offset = &h->block_offset[0]; - const unsigned int bottom = mb_y & 1; const int transform_bypass = (s->qscale == 0 && h->sps.transform_bypass), is_h264 = (simple || s->codec_id == CODEC_ID_H264); void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride); void (*idct_dc_add)(uint8_t *dst, DCTELEM *block, int stride); @@ -2482,7 +2475,6 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){ fill_rectangle(ref, 4, 4, 8, (16+*ref)^(s->mb_y&1), 1); }else{ for(i=0; i<16; i+=4){ - //FIXME can refs be smaller than 8x8 when !direct_8x8_inference ? int ref = h->ref_cache[list][scan8[i]]; if(ref >= 0) fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2, 8, (16+ref)^(s->mb_y&1), 1); @@ -2507,15 +2499,6 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){ idct_add = s->dsp.h264_idct_add; } - if(!simple && FRAME_MBAFF && h->deblocking_filter && IS_INTRA(mb_type) - && (!bottom || !IS_INTRA(s->current_picture.mb_type[mb_xy-s->mb_stride]))){ - int mbt_y = mb_y&~1; - uint8_t *top_y = s->current_picture.data[0] + (mbt_y * 16* s->linesize ) + mb_x * 16; - uint8_t *top_cb = s->current_picture.data[1] + (mbt_y * 8 * s->uvlinesize) + mb_x * 8; - uint8_t *top_cr = s->current_picture.data[2] + (mbt_y * 8 * s->uvlinesize) + mb_x * 8; - xchg_pair_border(h, top_y, top_cb, top_cr, s->linesize, s->uvlinesize, 1); - } - if (!simple && IS_INTRA_PCM(mb_type)) { for (i=0; i<16; i++) { memcpy(dest_y + i* linesize, h->mb + i*8, 16); @@ -2526,7 +2509,7 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){ } } else { if(IS_INTRA(mb_type)){ - if(h->deblocking_filter && (simple || !FRAME_MBAFF)) + if(h->deblocking_filter) xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 1, simple); if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ @@ -2589,7 +2572,7 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){ }else svq3_luma_dc_dequant_idct_c(h->mb, s->qscale); } - if(h->deblocking_filter && (simple || !FRAME_MBAFF)) + if(h->deblocking_filter) xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0, simple); }else if(is_h264){ hl_motion(h, dest_y, dest_cb, dest_cr, @@ -2658,44 +2641,13 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){ } } 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) { - //FIXME try deblocking one mb at a time? - // the reduction in load/storing mvs and such might outweigh the extra backup/xchg_border - const int mb_y = s->mb_y - 1; - uint8_t *pair_dest_y, *pair_dest_cb, *pair_dest_cr; - const int mb_xy= mb_x + mb_y*s->mb_stride; - const int mb_type_top = s->current_picture.mb_type[mb_xy]; - const int mb_type_bottom= s->current_picture.mb_type[mb_xy+s->mb_stride]; - if (!bottom) return; - pair_dest_y = s->current_picture.data[0] + (mb_y * 16* s->linesize ) + mb_x * 16; - pair_dest_cb = s->current_picture.data[1] + (mb_y * 8 * s->uvlinesize) + mb_x * 8; - pair_dest_cr = s->current_picture.data[2] + (mb_y * 8 * s->uvlinesize) + mb_x * 8; - - if(IS_INTRA(mb_type_top | mb_type_bottom)) - xchg_pair_border(h, pair_dest_y, pair_dest_cb, pair_dest_cr, s->linesize, s->uvlinesize, 0); - - backup_pair_border(h, pair_dest_y, pair_dest_cb, pair_dest_cr, s->linesize, s->uvlinesize); - // deblock a pair - // top - s->mb_y--; h->mb_xy -= s->mb_stride; - tprintf(h->s.avctx, "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 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]); - filter_mb(h, mb_x, mb_y, pair_dest_y, pair_dest_cb, pair_dest_cr, linesize, uvlinesize); - // bottom - s->mb_y++; h->mb_xy += s->mb_stride; - tprintf(h->s.avctx, "call mbaff filter_mb\n"); - fill_caches(h, mb_type_bottom, 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+s->mb_stride]); - h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.qscale_table[mb_xy+s->mb_stride]); - filter_mb(h, mb_x, mb_y+1, dest_y, dest_cb, dest_cr, linesize, uvlinesize); + filter_mb (h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize); } else { - tprintf(h->s.avctx, "call filter_mb\n"); - 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]); filter_mb_fast(h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize); } } @@ -2990,9 +2942,6 @@ static int decode_ref_pic_list_reordering(H264Context *h){ } } - if(h->slice_type_nos==FF_B_TYPE && !h->direct_spatial_mv_pred) - direct_dist_scale_factor(h); - direct_ref_list_init(h); return 0; } @@ -3006,10 +2955,12 @@ static void fill_mbaff_ref_list(H264Context *h){ for(j=0; j<3; j++) field[0].linesize[j] <<= 1; field[0].reference = PICT_TOP_FIELD; + field[0].poc= field[0].field_poc[0]; field[1] = field[0]; for(j=0; j<3; j++) field[1].data[j] += frame->linesize[j]; field[1].reference = PICT_BOTTOM_FIELD; + field[1].poc= field[1].field_poc[1]; h->luma_weight[list][16+2*i] = h->luma_weight[list][16+2*i+1] = h->luma_weight[list][i]; h->luma_offset[list][16+2*i] = h->luma_offset[list][16+2*i+1] = h->luma_offset[list][i]; @@ -3968,6 +3919,15 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ if(h->slice_type_nos!=FF_I_TYPE && decode_ref_pic_list_reordering(h) < 0) return -1; + if(h->slice_type_nos!=FF_I_TYPE){ + s->last_picture_ptr= &h->ref_list[0][0]; + ff_copy_picture(&s->last_picture, s->last_picture_ptr); + } + if(h->slice_type_nos==FF_B_TYPE){ + s->next_picture_ptr= &h->ref_list[1][0]; + ff_copy_picture(&s->next_picture, s->next_picture_ptr); + } + if( (h->pps.weighted_pred && h->slice_type_nos == FF_P_TYPE ) || (h->pps.weighted_bipred_idc==1 && h->slice_type_nos== FF_B_TYPE ) ) pred_weight_table(h); @@ -3982,6 +3942,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ if(FRAME_MBAFF) fill_mbaff_ref_list(h); + if(h->slice_type_nos==FF_B_TYPE && !h->direct_spatial_mv_pred) + direct_dist_scale_factor(h); + direct_ref_list_init(h); + if( h->slice_type_nos != FF_I_TYPE && h->pps.cabac ){ tmp = get_ue_golomb(&s->gb); if(tmp > 2){ @@ -4061,20 +4025,25 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ int *ref2frm= h->ref2frm[h->slice_num&15][j]; ref2frm[0]= ref2frm[1]= -1; - for(i=0; i<48; i++) + for(i=0; i<16; i++) ref2frm[i+2]= 4*h->ref_list[j][i].frame_num +(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 + +(h->ref_list[j][i].reference&3); } h->emu_edge_width= (s->flags&CODEC_FLAG_EMU_EDGE) ? 0 : 16; h->emu_edge_height= (FRAME_MBAFF || FIELD_PICTURE) ? 0 : h->emu_edge_width; if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(h->s.avctx, AV_LOG_DEBUG, "slice:%d %s mb:%d %c pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n", + av_log(h->s.avctx, AV_LOG_DEBUG, "slice:%d %s mb:%d %c%s%s pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n", h->slice_num, (s->picture_structure==PICT_FRAME ? "F" : s->picture_structure==PICT_TOP_FIELD ? "T" : "B"), first_mb_in_slice, - av_get_pict_type_char(h->slice_type), + av_get_pict_type_char(h->slice_type), h->slice_type_fixed ? " fix" : "", h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "", pps_id, h->frame_num, s->current_picture_ptr->field_poc[0], s->current_picture_ptr->field_poc[1], h->ref_count[0], h->ref_count[1], @@ -6417,8 +6386,10 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 if( IS_INTRA( s->current_picture.mb_type[mbn_xy] ) ) bS[i] = 4; else if( h->non_zero_count_cache[12+8*(i>>1)] != 0 || - /* FIXME: with 8x8dct + cavlc, should check cbp instead of nnz */ - h->non_zero_count[mbn_xy][MB_FIELD ? i&3 : (i>>2)+(mb_y&1)*2] ) + ((!h->pps.cabac && IS_8x8DCT(s->current_picture.mb_type[mbn_xy])) ? + (h->cbp_table[mbn_xy] & ((MB_FIELD ? (i&2) : (mb_y&1)) ? 8 : 2)) + : + h->non_zero_count[mbn_xy][MB_FIELD ? i&3 : (i>>2)+(mb_y&1)*2])) bS[i] = 2; else bS[i] = 1; @@ -6452,8 +6423,8 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 int edge; const int mbm_xy = dir == 0 ? mb_xy -1 : h->top_mb_xy; const int mbm_type = s->current_picture.mb_type[mbm_xy]; - int (*ref2frm) [48+2] = h->ref2frm[ h->slice_num &15 ]; - int (*ref2frmm)[48+2] = h->ref2frm[ h->slice_table[mbm_xy]&15 ]; + int (*ref2frm) [64] = h->ref2frm[ h->slice_num &15 ][0] + (MB_MBAFF ? 20 : 2); + int (*ref2frmm)[64] = h->ref2frm[ h->slice_table[mbm_xy]&15 ][0] + (MB_MBAFF ? 20 : 2); int start = h->slice_table[mbm_xy] == 255 ? 1 : 0; const int edges = (mb_type & (MB_TYPE_16x16|MB_TYPE_SKIP)) @@ -6522,7 +6493,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 /* mbn_xy: neighbor macroblock */ const int mbn_xy = edge > 0 ? mb_xy : mbm_xy; const int mbn_type = s->current_picture.mb_type[mbn_xy]; - int (*ref2frmn)[48+2] = edge > 0 ? ref2frm : ref2frmm; + int (*ref2frmn)[64] = edge > 0 ? ref2frm : ref2frmm; int16_t bS[4]; int qp; @@ -6562,7 +6533,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 int v = 0; for( l = 0; !v && l < 1 + (h->slice_type_nos == FF_B_TYPE); l++ ) { - v |= ref2frm[l][h->ref_cache[l][b_idx]+2] != ref2frmn[l][h->ref_cache[l][bn_idx]+2] || + v |= ref2frm[l][h->ref_cache[l][b_idx]] != ref2frmn[l][h->ref_cache[l][bn_idx]] || FFABS( h->mv_cache[l][b_idx][0] - h->mv_cache[l][bn_idx][0] ) >= 4 || FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[l][bn_idx][1] ) >= mvy_limit; } @@ -6571,7 +6542,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 v=0; for( l = 0; !v && l < 2; l++ ) { int ln= 1-l; - v |= ref2frm[l][h->ref_cache[l][b_idx]+2] != ref2frmn[ln][h->ref_cache[ln][bn_idx]+2] || + v |= ref2frm[l][h->ref_cache[l][b_idx]] != ref2frmn[ln][h->ref_cache[ln][bn_idx]] || FFABS( h->mv_cache[l][b_idx][0] - h->mv_cache[ln][bn_idx][0] ) >= 4 || FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[ln][bn_idx][1] ) >= mvy_limit; } @@ -6597,7 +6568,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 { bS[i] = 0; for( l = 0; l < 1 + (h->slice_type_nos == FF_B_TYPE); l++ ) { - if( ref2frm[l][h->ref_cache[l][b_idx]+2] != ref2frmn[l][h->ref_cache[l][bn_idx]+2] || + if( ref2frm[l][h->ref_cache[l][b_idx]] != ref2frmn[l][h->ref_cache[l][bn_idx]] || FFABS( h->mv_cache[l][b_idx][0] - h->mv_cache[l][bn_idx][0] ) >= 4 || FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[l][bn_idx][1] ) >= mvy_limit ) { bS[i] = 1; @@ -6609,7 +6580,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 bS[i] = 0; for( l = 0; l < 2; l++ ) { int ln= 1-l; - if( ref2frm[l][h->ref_cache[l][b_idx]+2] != ref2frmn[ln][h->ref_cache[ln][bn_idx]+2] || + if( ref2frm[l][h->ref_cache[l][b_idx]] != ref2frmn[ln][h->ref_cache[ln][bn_idx]] || FFABS( h->mv_cache[l][b_idx][0] - h->mv_cache[ln][bn_idx][0] ) >= 4 || FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[ln][bn_idx][1] ) >= mvy_limit ) { bS[i] = 1; @@ -7028,9 +6999,6 @@ static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_s decode_scaling_list(h,scaling_matrix8[0],64,default_scaling8[0],fallback[2]); // Intra, Y decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[1],fallback[3]); // Inter, Y } - } else if(fallback_sps) { - memcpy(scaling_matrix4, sps->scaling_matrix4, 6*16*sizeof(uint8_t)); - memcpy(scaling_matrix8, sps->scaling_matrix8, 2*64*sizeof(uint8_t)); } } @@ -7077,6 +7045,10 @@ static inline int decode_seq_parameter_set(H264Context *h){ sps->profile_idc= profile_idc; 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){ //high profile sps->chroma_format_idc= get_ue_golomb(&s->gb); if(sps->chroma_format_idc == 3) @@ -7086,7 +7058,6 @@ static inline int decode_seq_parameter_set(H264Context *h){ sps->transform_bypass = get_bits1(&s->gb); decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8); }else{ - sps->scaling_matrix_present = 0; sps->chroma_format_idc= 1; } @@ -7143,9 +7114,6 @@ static inline int decode_seq_parameter_set(H264Context *h){ if(sps->mb_aff) av_log(h->s.avctx, AV_LOG_ERROR, "MBAFF support not included; enable it at compile-time.\n"); #endif - if(!sps->direct_8x8_inference_flag && sps->mb_aff) - av_log(h->s.avctx, AV_LOG_ERROR, "MBAFF + !direct_8x8_inference is not implemented\n"); - sps->crop= get_bits1(&s->gb); if(sps->crop){ sps->crop_left = get_ue_golomb(&s->gb); @@ -7155,7 +7123,7 @@ static inline int decode_seq_parameter_set(H264Context *h){ 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 >= 8 || sps->crop_bottom >= (8>> !h->sps.frame_mbs_only_flag)){ + if(sps->crop_right >= 8 || sps->crop_bottom >= (8>> !sps->frame_mbs_only_flag)){ av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not supported, this could look slightly wrong ...\n"); } }else{ @@ -7269,8 +7237,8 @@ static inline int decode_picture_parameter_set(H264Context *h, int bit_length){ pps->transform_8x8_mode= 0; h->dequant_coeff_pps= -1; //contents of sps/pps can change even if id doesn't, so reinit - memset(pps->scaling_matrix4, 16, 6*16*sizeof(uint8_t)); - memset(pps->scaling_matrix8, 16, 2*64*sizeof(uint8_t)); + memcpy(pps->scaling_matrix4, h->sps_buffers[pps->sps_id]->scaling_matrix4, sizeof(pps->scaling_matrix4)); + memcpy(pps->scaling_matrix8, h->sps_buffers[pps->sps_id]->scaling_matrix8, sizeof(pps->scaling_matrix8)); if(get_bits_count(&s->gb) < bit_length){ pps->transform_8x8_mode= get_bits1(&s->gb); @@ -7320,7 +7288,7 @@ static void execute_decode_slices(H264Context *h, int context_count){ } else { for(i = 1; i < context_count; i++) { hx = h->thread_context[i]; - hx->s.error_resilience = avctx->error_resilience; + hx->s.error_recognition = avctx->error_recognition; hx->s.error_count = 0; } @@ -7554,7 +7522,7 @@ static int decode_frame(AVCodecContext *avctx, //FIXME factorize this with the output code below out = h->delayed_pic[0]; out_idx = 0; - for(i=1; h->delayed_pic[i] && h->delayed_pic[i]->poc; i++) + for(i=1; h->delayed_pic[i] && (h->delayed_pic[i]->poc && !h->delayed_pic[i]->key_frame); i++) if(h->delayed_pic[i]->poc < out->poc){ out = h->delayed_pic[i]; out_idx = i; @@ -7612,9 +7580,10 @@ static int decode_frame(AVCodecContext *avctx, h->got_avcC = 1; } - if(avctx->frame_number==0 && !h->is_avc && s->avctx->extradata_size){ + if(!h->got_avcC && !h->is_avc && s->avctx->extradata_size){ if(decode_nal_units(h, s->avctx->extradata, s->avctx->extradata_size) < 0) return -1; + h->got_avcC = 1; } buf_index=decode_nal_units(h, buf, buf_size); @@ -7698,12 +7667,12 @@ static int decode_frame(AVCodecContext *avctx, out = h->delayed_pic[0]; out_idx = 0; - for(i=1; h->delayed_pic[i] && h->delayed_pic[i]->poc; i++) + for(i=1; h->delayed_pic[i] && (h->delayed_pic[i]->poc && !h->delayed_pic[i]->key_frame); i++) if(h->delayed_pic[i]->poc < out->poc){ out = h->delayed_pic[i]; out_idx = i; } - cross_idr = !h->delayed_pic[0]->poc || !!h->delayed_pic[i]; + cross_idr = !h->delayed_pic[0]->poc || !!h->delayed_pic[i] || h->delayed_pic[0]->key_frame; out_of_order = !cross_idr && out->poc < h->outputed_poc; @@ -7945,10 +7914,18 @@ static av_cold int decode_end(AVCodecContext *avctx) { H264Context *h = avctx->priv_data; MpegEncContext *s = &h->s; + int i; av_freep(&h->rbsp_buffer[0]); av_freep(&h->rbsp_buffer[1]); free_tables(h); //FIXME cleanup init stuff perhaps + + for(i = 0; i < MAX_SPS_COUNT; i++) + av_freep(h->sps_buffers + i); + + for(i = 0; i < MAX_PPS_COUNT; i++) + av_freep(h->pps_buffers + i); + MPV_common_end(s); // memset(h, 0, sizeof(H264Context));