aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Aimar <fenrir@videolan.org>2011-10-02 21:07:41 +0200
committerMichael Niedermayer <michaelni@gmx.at>2011-10-02 21:30:21 +0200
commitb89a0c9d7f4c4a23d709761033ad5e2f9c2881fa (patch)
tree557445112dbe2b5de2da7252d8012f63181e7a59
parentefedf09378e82cc75d56e881842c5bf14b2c9d05 (diff)
downloadffmpeg-b89a0c9d7f4c4a23d709761033ad5e2f9c2881fa.tar.gz
h264: fix intra 16x16 mode check when using mbaff and constrained_intra_pred.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at> (cherry picked from commit a4fd95b5d511384ed3ce388d8d20a16b1c4c0530)
-rw-r--r--libavcodec/h264.c26
-rw-r--r--libavcodec/h264.h7
-rw-r--r--libavcodec/h264_cabac.c4
-rw-r--r--libavcodec/h264_cavlc.c4
-rw-r--r--libavcodec/svq3.c4
5 files changed, 32 insertions, 13 deletions
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index dcca6bd73c..bab032b300 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -106,12 +106,9 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h){
}
return 0;
-} //FIXME cleanup like ff_h264_check_intra_pred_mode
+} //FIXME cleanup like check_intra_pred_mode
-/**
- * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks.
- */
-int ff_h264_check_intra_pred_mode(H264Context *h, int mode){
+static int check_intra_pred_mode(H264Context *h, int mode, int is_chroma){
MpegEncContext * const s = &h->s;
static const int8_t top [7]= {LEFT_DC_PRED8x8, 1,-1,-1};
static const int8_t left[7]= { TOP_DC_PRED8x8,-1, 2,-1,DC_128_PRED8x8};
@@ -131,7 +128,7 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode){
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
+ if(is_chroma && (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){
@@ -143,6 +140,23 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode){
return mode;
}
+/**
+ * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks.
+ */
+int ff_h264_check_intra16x16_pred_mode(H264Context *h, int mode)
+{
+ return check_intra_pred_mode(h, mode, 0);
+}
+
+/**
+ * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks.
+ */
+int ff_h264_check_intra_chroma_pred_mode(H264Context *h, int mode)
+{
+ return check_intra_pred_mode(h, mode, 1);
+}
+
+
const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, int *dst_length, int *consumed, int length){
int i, si, di;
uint8_t *dst;
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index 5b07f3775d..0a380e03c1 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -658,7 +658,12 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h);
/**
* 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 ff_h264_check_intra16x16_pred_mode(H264Context *h, int mode);
+
+/**
+ * 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_chroma_pred_mode(H264Context *h, int mode);
void ff_h264_write_back_intra_pred_mode(H264Context *h);
void ff_h264_hl_decode_mb(H264Context *h);
diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c
index 3975a61699..7aaecf3c2e 100644
--- a/libavcodec/h264_cabac.c
+++ b/libavcodec/h264_cabac.c
@@ -2003,14 +2003,14 @@ decode_intra_mb:
ff_h264_write_back_intra_pred_mode(h);
if( ff_h264_check_intra4x4_pred_mode(h) < 0 ) return -1;
} else {
- h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode( h, h->intra16x16_pred_mode );
+ h->intra16x16_pred_mode= ff_h264_check_intra16x16_pred_mode( h, h->intra16x16_pred_mode );
if( h->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 );
- pred_mode= ff_h264_check_intra_pred_mode( h, pred_mode );
+ pred_mode= ff_h264_check_intra_chroma_pred_mode( h, pred_mode );
if( pred_mode < 0 ) return -1;
h->chroma_pred_mode= pred_mode;
} else {
diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c
index 0ddc430661..92cae7fa93 100644
--- a/libavcodec/h264_cavlc.c
+++ b/libavcodec/h264_cavlc.c
@@ -735,12 +735,12 @@ decode_intra_mb:
if( ff_h264_check_intra4x4_pred_mode(h) < 0)
return -1;
}else{
- h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode(h, h->intra16x16_pred_mode);
+ h->intra16x16_pred_mode= ff_h264_check_intra16x16_pred_mode(h, h->intra16x16_pred_mode);
if(h->intra16x16_pred_mode < 0)
return -1;
}
if(decode_chroma){
- pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb));
+ pred_mode= ff_h264_check_intra_chroma_pred_mode(h, get_ue_golomb_31(&s->gb));
if(pred_mode < 0)
return -1;
h->chroma_pred_mode= pred_mode;
diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c
index e5c18c59c2..812ac962f2 100644
--- a/libavcodec/svq3.c
+++ b/libavcodec/svq3.c
@@ -612,7 +612,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
dir = i_mb_type_info[mb_type - 8].pred_mode;
dir = (dir >> 1) ^ 3*(dir & 1) ^ 1;
- if ((h->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, dir)) == -1){
+ if ((h->intra16x16_pred_mode = ff_h264_check_intra16x16_pred_mode(h, dir)) == -1){
av_log(h->s.avctx, AV_LOG_ERROR, "check_intra_pred_mode = -1\n");
return -1;
}
@@ -711,7 +711,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
s->current_picture.mb_type[mb_xy] = mb_type;
if (IS_INTRA(mb_type)) {
- h->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, DC_PRED8x8);
+ h->chroma_pred_mode = ff_h264_check_intra_chroma_pred_mode(h, DC_PRED8x8);
}
return 0;