diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 6272f6f781..0a01237113 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -152,7 +152,7 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h, H264SliceContext *sl) }; int i; - if (!(h->top_samples_available & 0x8000)) { + if (!(sl->top_samples_available & 0x8000)) { for (i = 0; i < 4; i++) { int status = top[sl->intra4x4_pred_mode_cache[scan8[0] + i]]; if (status < 0) { @@ -166,10 +166,10 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h, H264SliceContext *sl) } } - if ((h->left_samples_available & 0x8888) != 0x8888) { + if ((sl->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])) { + if (!(sl->left_samples_available & mask[i])) { int status = left[sl->intra4x4_pred_mode_cache[scan8[0] + 8 * i]]; if (status < 0) { av_log(h->avctx, AV_LOG_ERROR, @@ -189,7 +189,8 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h, H264SliceContext *sl) * Check if the top & left blocks are available if needed and * change the dc mode so it only uses the available blocks. */ -int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma) +int ff_h264_check_intra_pred_mode(H264Context *h, H264SliceContext *sl, + int mode, int is_chroma) { static const int8_t top[4] = { LEFT_DC_PRED8x8, 1, -1, -1 }; static const int8_t left[5] = { TOP_DC_PRED8x8, -1, 2, -1, DC_128_PRED8x8 }; @@ -201,7 +202,7 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma) return AVERROR_INVALIDDATA; } - if (!(h->top_samples_available & 0x8000)) { + if (!(sl->top_samples_available & 0x8000)) { mode = top[mode]; if (mode < 0) { av_log(h->avctx, AV_LOG_ERROR, @@ -211,7 +212,7 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma) } } - if ((h->left_samples_available & 0x8080) != 0x8080) { + if ((sl->left_samples_available & 0x8080) != 0x8080) { mode = left[mode]; if (mode < 0) { av_log(h->avctx, AV_LOG_ERROR, @@ -219,10 +220,10 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma) h->mb_x, h->mb_y); return AVERROR_INVALIDDATA; } - if (is_chroma && (h->left_samples_available & 0x8080)) { + if (is_chroma && (sl->left_samples_available & 0x8080)) { // mad cow disease mode, aka MBAFF + constrained_intra_pred mode = ALZHEIMER_DC_L0T_PRED8x8 + - (!(h->left_samples_available & 0x8000)) + + (!(sl->left_samples_available & 0x8000)) + 2 * (mode == DC_128_PRED8x8); } } diff --git a/libavcodec/h264.h b/libavcodec/h264.h index 3dd2a81261..54a69f40aa 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -373,6 +373,11 @@ typedef struct H264SliceContext { const uint8_t *left_block; int topleft_partition; + + unsigned int topleft_samples_available; + unsigned int top_samples_available; + unsigned int topright_samples_available; + unsigned int left_samples_available; } H264SliceContext; /** @@ -413,10 +418,6 @@ typedef struct H264Context { int8_t(*intra4x4_pred_mode); H264PredContext hpc; - unsigned int topleft_samples_available; - unsigned int top_samples_available; - unsigned int topright_samples_available; - unsigned int left_samples_available; uint8_t (*top_borders[2])[(16 * 3) * 2]; /** @@ -854,7 +855,8 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h, H264SliceContext *sl); * Check if the top & left blocks are available if needed & change the * dc mode so it only uses the available blocks. */ -int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma); +int ff_h264_check_intra_pred_mode(H264Context *h, H264SliceContext *sl, + int mode, int is_chroma); void ff_h264_hl_decode_mb(H264Context *h, H264SliceContext *sl); int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size); diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index 8b0bf1c9f5..831c5934e0 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -2064,14 +2064,14 @@ decode_intra_mb: write_back_intra_pred_mode(h, sl); if (ff_h264_check_intra4x4_pred_mode(h, sl) < 0 ) return -1; } else { - sl->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, sl->intra16x16_pred_mode, 0); + sl->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, sl, sl->intra16x16_pred_mode, 0); if (sl->intra16x16_pred_mode < 0) return -1; } if(decode_chroma){ h->chroma_pred_mode_table[mb_xy] = pred_mode = decode_cabac_mb_chroma_pre_mode(h, sl); - pred_mode= ff_h264_check_intra_pred_mode( h, pred_mode, 1 ); + pred_mode= ff_h264_check_intra_pred_mode(h, sl, pred_mode, 1 ); if( pred_mode < 0 ) return -1; sl->chroma_pred_mode = pred_mode; } else { diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c index ad299081cc..a08f8f4e1a 100644 --- a/libavcodec/h264_cavlc.c +++ b/libavcodec/h264_cavlc.c @@ -825,12 +825,12 @@ decode_intra_mb: if (ff_h264_check_intra4x4_pred_mode(h, sl) < 0) return -1; }else{ - sl->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, sl->intra16x16_pred_mode, 0); + sl->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, sl, sl->intra16x16_pred_mode, 0); if (sl->intra16x16_pred_mode < 0) return -1; } if(decode_chroma){ - pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&h->gb), 1); + pred_mode= ff_h264_check_intra_pred_mode(h, sl, get_ue_golomb_31(&h->gb), 1); if(pred_mode < 0) return -1; sl->chroma_pred_mode = pred_mode; diff --git a/libavcodec/h264_mb.c b/libavcodec/h264_mb.c index 568dd07c20..419bb481c0 100644 --- a/libavcodec/h264_mb.c +++ b/libavcodec/h264_mb.c @@ -637,12 +637,12 @@ static av_always_inline void hl_decode_mb_predict_luma(H264Context *h, h->hpc.pred8x8l_add[dir](ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize); } else h->hpc.pred8x8l_filter_add[dir](ptr, h->mb + (i * 16 + p * 256 << pixel_shift), - (h-> topleft_samples_available << i) & 0x8000, - (h->topright_samples_available << i) & 0x4000, linesize); + (sl-> topleft_samples_available << i) & 0x8000, + (sl->topright_samples_available << i) & 0x4000, linesize); } else { const int nnz = h->non_zero_count_cache[scan8[i + p * 16]]; - h->hpc.pred8x8l[dir](ptr, (h->topleft_samples_available << i) & 0x8000, - (h->topright_samples_available << i) & 0x4000, linesize); + h->hpc.pred8x8l[dir](ptr, (sl->topleft_samples_available << i) & 0x8000, + (sl->topright_samples_available << i) & 0x4000, linesize); if (nnz) { if (nnz == 1 && dctcoef_get(h->mb, pixel_shift, i * 16 + p * 256)) idct_dc_add(ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize); @@ -670,7 +670,7 @@ static av_always_inline void hl_decode_mb_predict_luma(H264Context *h, int nnz, tr; uint64_t tr_high; if (dir == DIAG_DOWN_LEFT_PRED || dir == VERT_LEFT_PRED) { - const int topright_avail = (h->topright_samples_available << i) & 0x8000; + const int topright_avail = (sl->topright_samples_available << i) & 0x8000; av_assert2(h->mb_y || linesize <= block_offset[i]); if (!topright_avail) { if (pixel_shift) { diff --git a/libavcodec/h264_mvpred.h b/libavcodec/h264_mvpred.h index d2ff7d9891..c92421d3b6 100644 --- a/libavcodec/h264_mvpred.h +++ b/libavcodec/h264_mvpred.h @@ -465,47 +465,47 @@ static void fill_decode_caches(H264Context *h, H264SliceContext *sl, int mb_type if (!IS_SKIP(mb_type)) { 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; + sl->topleft_samples_available = + sl->top_samples_available = + sl->left_samples_available = 0xFFFF; + sl->topright_samples_available = 0xEEEA; if (!(top_type & type_mask)) { - h->topleft_samples_available = 0xB3FF; - h->top_samples_available = 0x33FF; - h->topright_samples_available = 0x26EA; + sl->topleft_samples_available = 0xB3FF; + sl->top_samples_available = 0x33FF; + sl->topright_samples_available = 0x26EA; } if (IS_INTERLACED(mb_type) != IS_INTERLACED(left_type[LTOP])) { if (IS_INTERLACED(mb_type)) { if (!(left_type[LTOP] & type_mask)) { - h->topleft_samples_available &= 0xDFFF; - h->left_samples_available &= 0x5FFF; + sl->topleft_samples_available &= 0xDFFF; + sl->left_samples_available &= 0x5FFF; } if (!(left_type[LBOT] & type_mask)) { - h->topleft_samples_available &= 0xFF5F; - h->left_samples_available &= 0xFF5F; + sl->topleft_samples_available &= 0xFF5F; + sl->left_samples_available &= 0xFF5F; } } else { int left_typei = h->cur_pic.mb_type[left_xy[LTOP] + h->mb_stride]; av_assert2(left_xy[LTOP] == left_xy[LBOT]); if (!((left_typei & type_mask) && (left_type[LTOP] & type_mask))) { - h->topleft_samples_available &= 0xDF5F; - h->left_samples_available &= 0x5F5F; + sl->topleft_samples_available &= 0xDF5F; + sl->left_samples_available &= 0x5F5F; } } } else { if (!(left_type[LTOP] & type_mask)) { - h->topleft_samples_available &= 0xDF5F; - h->left_samples_available &= 0x5F5F; + sl->topleft_samples_available &= 0xDF5F; + sl->left_samples_available &= 0x5F5F; } } if (!(topleft_type & type_mask)) - h->topleft_samples_available &= 0x7FFF; + sl->topleft_samples_available &= 0x7FFF; if (!(topright_type & type_mask)) - h->topright_samples_available &= 0xFBFF; + sl->topright_samples_available &= 0xFBFF; if (IS_INTRA4x4(mb_type)) { if (IS_INTRA4x4(top_type)) { diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 08b244f393..754a3f72a0 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -497,9 +497,9 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) const int mb_xy = h->mb_xy; const int b_xy = 4 * h->mb_x + 4 * h->mb_y * h->b_stride; - h->top_samples_available = (h->mb_y == 0) ? 0x33FF : 0xFFFF; - h->left_samples_available = (h->mb_x == 0) ? 0x5F5F : 0xFFFF; - h->topright_samples_available = 0xFFFF; + sl->top_samples_available = (h->mb_y == 0) ? 0x33FF : 0xFFFF; + sl->left_samples_available = (h->mb_x == 0) ? 0x5F5F : 0xFFFF; + sl->topright_samples_available = 0xFFFF; if (mb_type == 0) { /* SKIP */ if (h->pict_type == AV_PICTURE_TYPE_P || @@ -610,7 +610,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) for (i = 0; i < 4; i++) sl->intra4x4_pred_mode_cache[scan8[0] - 1 + i * 8] = sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6 - i]; if (sl->intra4x4_pred_mode_cache[scan8[0] - 1] == -1) - h->left_samples_available = 0x5F5F; + sl->left_samples_available = 0x5F5F; } if (h->mb_y > 0) { sl->intra4x4_pred_mode_cache[4 + 8 * 0] = sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 0]; @@ -619,7 +619,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) sl->intra4x4_pred_mode_cache[7 + 8 * 0] = sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 3]; if (sl->intra4x4_pred_mode_cache[4 + 8 * 0] == -1) - h->top_samples_available = 0x33FF; + sl->top_samples_available = 0x33FF; } /* decode prediction codes for luma blocks */ @@ -653,14 +653,14 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) if (mb_type == 8) { ff_h264_check_intra4x4_pred_mode(h, sl); - h->top_samples_available = (h->mb_y == 0) ? 0x33FF : 0xFFFF; - h->left_samples_available = (h->mb_x == 0) ? 0x5F5F : 0xFFFF; + sl->top_samples_available = (h->mb_y == 0) ? 0x33FF : 0xFFFF; + sl->left_samples_available = (h->mb_x == 0) ? 0x5F5F : 0xFFFF; } else { for (i = 0; i < 4; i++) memset(&sl->intra4x4_pred_mode_cache[scan8[0] + 8 * i], DC_128_PRED, 4); - h->top_samples_available = 0x33FF; - h->left_samples_available = 0x5F5F; + sl->top_samples_available = 0x33FF; + sl->left_samples_available = 0x5F5F; } mb_type = MB_TYPE_INTRA4x4; @@ -668,7 +668,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) dir = i_mb_type_info[mb_type - 8].pred_mode; dir = (dir >> 1) ^ 3 * (dir & 1) ^ 1; - if ((sl->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, dir, 0)) < 0) { + if ((sl->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, sl, dir, 0)) < 0) { av_log(h->avctx, AV_LOG_ERROR, "ff_h264_check_intra_pred_mode < 0\n"); return sl->intra16x16_pred_mode; } @@ -772,7 +772,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) h->cur_pic.mb_type[mb_xy] = mb_type; if (IS_INTRA(mb_type)) - sl->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, DC_PRED8x8, 1); + sl->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, sl, DC_PRED8x8, 1); return 0; }