diff options
author | Yao Wang <jiayaowang@gmail.com> | 2012-01-19 20:39:47 +0800 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-06-26 14:51:40 +0200 |
commit | e18b48c6fdfdc91fe56b1d1a1312b6d486d9fe43 (patch) | |
tree | 3ee66805b1214750c1646cef98d27e73ee858f1d /libavcodec | |
parent | 7e8fdf05e09a749ac74cf4b26797e44305a2b068 (diff) | |
download | ffmpeg-e18b48c6fdfdc91fe56b1d1a1312b6d486d9fe43.tar.gz |
avcodec/cavs: fix B_SUB_DIRECT col-MB is Intra MB case.
in this case current MB size is forced to 16x16 (AVS standard section 9.9.1)
Signed-off-by: Yao Wang <jiayaowang@gmail.com>
Fixes Ticket 1901
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/cavs.c | 2 | ||||
-rw-r--r-- | libavcodec/cavsdec.c | 32 |
2 files changed, 28 insertions, 6 deletions
diff --git a/libavcodec/cavs.c b/libavcodec/cavs.c index 7e162a8071..96acef2381 100644 --- a/libavcodec/cavs.c +++ b/libavcodec/cavs.c @@ -573,7 +573,7 @@ void ff_cavs_mv(AVSContext *h, enum cavs_mv_loc nP, enum cavs_mv_loc nC, mvP->ref = ref; mvP->dist = h->dist[mvP->ref]; - if (mvC->ref == NOT_AVAIL) + if (mvC->ref == NOT_AVAIL || (nP == MV_FWD_X3) || (nP == MV_BWD_X3 )) mvC = &h->mv[nP - 5]; // set to top-left (mvD) if (mode == MV_PRED_PSKIP && (mvA->ref == NOT_AVAIL || diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index 73a8044216..122deeb39b 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -805,6 +805,8 @@ static int decode_mb_b(AVSContext *h, enum cavs_mb mb_type) ff_cavs_mv(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_MEDIAN, BLK_16X16, 0); break; case B_8X8: +#define TMP_UNUSED_INX 7 + flags = 0; for (block = 0; block < 4; block++) sub_type[block] = get_bits(&h->gb, 2); for (block = 0; block < 4; block++) { @@ -812,11 +814,30 @@ static int decode_mb_b(AVSContext *h, enum cavs_mb mb_type) case B_SUB_DIRECT: if (!h->col_type_base[h->mbidx]) { /* intra MB at co-location, do in-plane prediction */ - ff_cavs_mv(h, mv_scan[block], mv_scan[block] - 3, - MV_PRED_BSKIP, BLK_8X8, 1); - ff_cavs_mv(h, mv_scan[block] + MV_BWD_OFFS, - mv_scan[block] - 3 + MV_BWD_OFFS, - MV_PRED_BSKIP, BLK_8X8, 0); + if(flags==0) { + // if col-MB is a Intra MB, current Block size is 16x16. + // AVS standard section 9.9.1 + if(block>0){ + h->mv[TMP_UNUSED_INX ] = h->mv[MV_FWD_X0 ]; + h->mv[TMP_UNUSED_INX + MV_BWD_OFFS] = h->mv[MV_FWD_X0 + MV_BWD_OFFS]; + } + ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, + MV_PRED_BSKIP, BLK_8X8, 1); + ff_cavs_mv(h, MV_FWD_X0+MV_BWD_OFFS, + MV_FWD_C2+MV_BWD_OFFS, + MV_PRED_BSKIP, BLK_8X8, 0); + if(block>0) { + flags = mv_scan[block]; + h->mv[flags ] = h->mv[MV_FWD_X0 ]; + h->mv[flags + MV_BWD_OFFS] = h->mv[MV_FWD_X0 + MV_BWD_OFFS]; + h->mv[MV_FWD_X0 ] = h->mv[TMP_UNUSED_INX ]; + h->mv[MV_FWD_X0 + MV_BWD_OFFS] = h->mv[TMP_UNUSED_INX + MV_BWD_OFFS]; + } else + flags = MV_FWD_X0; + } else { + h->mv[mv_scan[block] ] = h->mv[flags ]; + h->mv[mv_scan[block] + MV_BWD_OFFS] = h->mv[flags + MV_BWD_OFFS]; + } } else mv_pred_direct(h, &h->mv[mv_scan[block]], &h->col_mv[h->mbidx * 4 + block]); @@ -832,6 +853,7 @@ static int decode_mb_b(AVSContext *h, enum cavs_mb mb_type) break; } } +#undef TMP_UNUSED_INX for (block = 0; block < 4; block++) { if (sub_type[block] == B_SUB_BWD) ff_cavs_mv(h, mv_scan[block] + MV_BWD_OFFS, |