Mercurial > libavcodec.hg
changeset 7532:c4de4b187b4f libavcodec
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
author | michael |
---|---|
date | Mon, 11 Aug 2008 02:21:33 +0000 |
parents | 63c782094e3a |
children | e61de3e409eb |
files | h264.c h264pred.c h264pred.h |
diffstat | 3 files changed, 62 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/h264.c Sun Aug 10 22:18:46 2008 +0000 +++ b/h264.c Mon Aug 11 02:21:33 2008 +0000 @@ -217,8 +217,27 @@ 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 @@ } } - 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 @@ } else if(status){ h->intra4x4_pred_mode_cache[scan8[0] + 8*i]= status; } + } } } @@ -601,8 +623,11 @@ } } - 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;
--- a/h264pred.c Sun Aug 10 22:18:46 2008 +0000 +++ b/h264pred.c Mon Aug 11 02:21:33 2008 +0000 @@ -690,6 +690,29 @@ } } +//the following 4 function should not be optimized! +static void pred8x8_mad_cow_dc_l0t(uint8_t *src, int stride){ + pred8x8_top_dc_c(src, stride); + pred4x4_dc_c(src, NULL, stride); +} + +static void pred8x8_mad_cow_dc_0lt(uint8_t *src, int stride){ + pred8x8_dc_c(src, stride); + pred4x4_top_dc_c(src, NULL, stride); +} + +static void pred8x8_mad_cow_dc_l00(uint8_t *src, int stride){ + pred8x8_left_dc_c(src, stride); + pred4x4_128_dc_c(src + 4*stride , NULL, stride); + pred4x4_128_dc_c(src + 4*stride + 4, NULL, stride); +} + +static void pred8x8_mad_cow_dc_0l0(uint8_t *src, int stride){ + pred8x8_left_dc_c(src, stride); + pred4x4_128_dc_c(src , NULL, stride); + pred4x4_128_dc_c(src + 4, NULL, stride); +} + static void pred8x8_dc_rv40_c(uint8_t *src, int stride){ int i; int dc0=0; @@ -1046,6 +1069,10 @@ h->pred8x8[DC_PRED8x8 ]= pred8x8_dc_c; h->pred8x8[LEFT_DC_PRED8x8]= pred8x8_left_dc_c; h->pred8x8[TOP_DC_PRED8x8 ]= pred8x8_top_dc_c; + h->pred8x8[ALZHEIMER_DC_L0T_PRED8x8 ]= pred8x8_mad_cow_dc_l0t; + h->pred8x8[ALZHEIMER_DC_0LT_PRED8x8 ]= pred8x8_mad_cow_dc_0lt; + h->pred8x8[ALZHEIMER_DC_L00_PRED8x8 ]= pred8x8_mad_cow_dc_l00; + h->pred8x8[ALZHEIMER_DC_0L0_PRED8x8 ]= pred8x8_mad_cow_dc_0l0; }else{ h->pred8x8[DC_PRED8x8 ]= pred8x8_dc_rv40_c; h->pred8x8[LEFT_DC_PRED8x8]= pred8x8_left_dc_rv40_c;
--- a/h264pred.h Sun Aug 10 22:18:46 2008 +0000 +++ b/h264pred.h Mon Aug 11 02:21:33 2008 +0000 @@ -60,6 +60,11 @@ #define LEFT_DC_PRED8x8 4 #define TOP_DC_PRED8x8 5 #define DC_128_PRED8x8 6 + +#define ALZHEIMER_DC_L0T_PRED8x8 7 +#define ALZHEIMER_DC_0LT_PRED8x8 8 +#define ALZHEIMER_DC_L00_PRED8x8 9 +#define ALZHEIMER_DC_0L0_PRED8x8 10 //@} /** @@ -68,7 +73,7 @@ typedef struct H264PredContext{ void (*pred4x4 [9+3+3])(uint8_t *src, uint8_t *topright, int stride);//FIXME move to dsp? void (*pred8x8l [9+3])(uint8_t *src, int topleft, int topright, int stride); - void (*pred8x8 [4+3])(uint8_t *src, int stride); + void (*pred8x8 [4+3+4])(uint8_t *src, int stride); void (*pred16x16[4+3])(uint8_t *src, int stride); }H264PredContext;