diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2008-08-11 02:21:33 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2008-08-11 02:21:33 +0000 |
commit | d1d10e9125153d0000be34c78c92c54d59d38108 (patch) | |
tree | d73d40d98ae8acaa035d8bfbab06cb602fcb41b5 /libavcodec/h264.c | |
parent | 697c7cd44be1ecd351bc790fbcd3a46449d63f7d (diff) | |
download | ffmpeg-streaming-d1d10e9125153d0000be34c78c92c54d59d38108.zip ffmpeg-streaming-d1d10e9125153d0000be34c78c92c54d59d38108.tar.gz |
Support MBAFF + constrained intra prediction.
(no i would not have tried to implement this had i known what mess it is)
fixes at least:
CAMACI3_Sony_C
Originally committed as revision 14687 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/h264.c')
-rw-r--r-- | libavcodec/h264.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 619b618..b24e491 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -217,8 +217,27 @@ static void fill_caches(H264Context *h, int mb_type, int for_deblock){ 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(!IS_INTRA(left_type[0]) && (left_type[0]==0 || h->pps.constrained_intra_pred)){ + h->topleft_samples_available&= 0xDFFF; + h->left_samples_available&= 0x5FFF; + } + if(!IS_INTRA(left_type[1]) && (left_type[1]==0 || h->pps.constrained_intra_pred)){ + 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(!(IS_INTRA(left_typei) && IS_INTRA(left_type[0])) && (left_typei==0 || h->pps.constrained_intra_pred)){ + h->topleft_samples_available&= 0xDF5F; + h->left_samples_available&= 0x5F5F; + } + } + }else{ + if(!IS_INTRA(left_type[0]) && (left_type[0]==0 || h->pps.constrained_intra_pred)){ h->topleft_samples_available&= 0xDF5F; h->left_samples_available&= 0x5F5F; } @@ -565,8 +584,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); @@ -574,6 +595,7 @@ static inline int check_intra4x4_pred_mode(H264Context *h){ } else if(status){ h->intra4x4_pred_mode_cache[scan8[0] + 8*i]= status; } + } } } @@ -601,8 +623,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; |