diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-06-27 01:31:42 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-06-27 02:05:22 +0200 |
commit | 357168bcf63429e9472fb9fff1e1301f9514dca6 (patch) | |
tree | 04b94fe1d99e435cbe63d1b2ef06a728121f21e5 /libavcodec/ivi_common.c | |
parent | 826726b83fab660e45166bca476c4e91713c62aa (diff) | |
parent | 5ec6d152e26c570c0a16ec72c1f354db95708179 (diff) | |
download | ffmpeg-357168bcf63429e9472fb9fff1e1301f9514dca6.tar.gz |
Merge commit '5ec6d152e26c570c0a16ec72c1f354db95708179'
* commit '5ec6d152e26c570c0a16ec72c1f354db95708179':
indeo4: B-frames decoding
Conflicts:
libavcodec/ivi_common.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/ivi_common.c')
-rw-r--r-- | libavcodec/ivi_common.c | 132 |
1 files changed, 103 insertions, 29 deletions
diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index 754bfd5bad..379508123f 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -73,20 +73,43 @@ static VLC ivi_blk_vlc_tabs[8]; ///< static block Huffman tables typedef void (*ivi_mc_func) (int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); +typedef void (*ivi_mc_avg_func) (int16_t *buf, const int16_t *ref_buf1, + const int16_t *ref_buf2, + uint32_t pitch, int mc_type, int mc_type2); -static int ivi_mc(IVIBandDesc *band, ivi_mc_func mc, - int offs, int mv_x, int mv_y, int mc_type) +static int ivi_mc(IVIBandDesc *band, ivi_mc_func mc, ivi_mc_avg_func mc_avg, + int offs, int mv_x, int mv_y, int mv_x2, int mv_y2, + int mc_type, int mc_type2) { int ref_offs = offs + mv_y * band->pitch + mv_x; int buf_size = band->pitch * band->aheight; int min_size = band->pitch * (band->blk_size - 1) + band->blk_size; int ref_size = (mc_type > 1) * band->pitch + (mc_type & 1); - av_assert0(offs >= 0 && ref_offs >= 0 && band->ref_buf); - av_assert0(buf_size - min_size >= offs); - av_assert0(buf_size - min_size - ref_size >= ref_offs); + if (mc_type != -1) { + av_assert0(offs >= 0 && ref_offs >= 0 && band->ref_buf); + av_assert0(buf_size - min_size >= offs); + av_assert0(buf_size - min_size - ref_size >= ref_offs); + } - mc(band->buf + offs, band->ref_buf + ref_offs, band->pitch, mc_type); + if (mc_type2 == -1) { + mc(band->buf + offs, band->ref_buf + ref_offs, band->pitch, mc_type); + } else { + int ref_offs2 = offs + mv_y2 * band->pitch + mv_x2; + int ref_size2 = (mc_type2 > 1) * band->pitch + (mc_type2 & 1); + if (offs < 0 || ref_offs2 < 0 || !band->b_ref_buf) + return AVERROR_INVALIDDATA; + if (buf_size - min_size - ref_size2 < ref_offs2) + return AVERROR_INVALIDDATA; + + if (mc_type == -1) + mc(band->buf + offs, band->b_ref_buf + ref_offs2, + band->pitch, mc_type2); + else + mc_avg(band->buf + offs, band->ref_buf + ref_offs, + band->b_ref_buf + ref_offs2, band->pitch, + mc_type, mc_type2); + } return 0; } @@ -264,6 +287,7 @@ static av_cold void ivi_free_buffers(IVIPlaneDesc *planes) av_freep(&planes[p].bands[b].bufs[0]); av_freep(&planes[p].bands[b].bufs[1]); av_freep(&planes[p].bands[b].bufs[2]); + av_freep(&planes[p].bands[b].bufs[3]); if (planes[p].bands[b].blk_vlc.cust_tab.table) ff_free_vlc(&planes[p].bands[b].blk_vlc.cust_tab); @@ -276,7 +300,8 @@ static av_cold void ivi_free_buffers(IVIPlaneDesc *planes) } } -av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) +av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg, + int is_indeo4) { int p, b; uint32_t b_width, b_height, align_fac, width_aligned, @@ -339,6 +364,11 @@ av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) if (!band->bufs[2]) return AVERROR(ENOMEM); } + if (is_indeo4) { + band->bufs[3] = av_mallocz(buf_size); + if (!band->bufs[3]) + return AVERROR(ENOMEM); + } /* reset custom vlc */ planes[p].bands[0].blk_vlc.cust_desc.num_rows = 0; } @@ -469,8 +499,11 @@ static int ivi_dc_transform(IVIBandDesc *band, int *prev_dc, int buf_offs, } static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, - ivi_mc_func mc, int mv_x, int mv_y, - int *prev_dc, int is_intra, int mc_type, + ivi_mc_func mc, ivi_mc_avg_func mc_avg, + int mv_x, int mv_y, + int mv_x2, int mv_y2, + int *prev_dc, int is_intra, + int mc_type, int mc_type2, uint32_t quant, int offs, AVCodecContext *avctx) { @@ -560,7 +593,8 @@ static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, /* apply motion compensation */ if (!is_intra) - return ivi_mc(band, mc, offs, mv_x, mv_y, mc_type); + return ivi_mc(band, mc, mc_avg, offs, mv_x, mv_y, mv_x2, mv_y2, + mc_type, mc_type2); return 0; } @@ -578,12 +612,14 @@ static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile, AVCodecContext *avctx) { - int mbn, blk, num_blocks, blk_size, ret, is_intra, mc_type = 0; - int mv_x = 0, mv_y = 0; + int mbn, blk, num_blocks, blk_size, ret, is_intra; + int mc_type = 0, mc_type2 = -1; + int mv_x = 0, mv_y = 0, mv_x2 = 0, mv_y2 = 0; int32_t prev_dc; uint32_t cbp, quant, buf_offs; IVIMbInfo *mb; ivi_mc_func mc_with_delta_func, mc_no_delta_func; + ivi_mc_avg_func mc_avg_with_delta_func, mc_avg_no_delta_func; const uint8_t *scale_tab; /* init intra prediction for the DC coefficient */ @@ -592,11 +628,15 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, /* number of blocks per mb */ num_blocks = (band->mb_size != blk_size) ? 4 : 1; if (blk_size == 8) { - mc_with_delta_func = ff_ivi_mc_8x8_delta; - mc_no_delta_func = ff_ivi_mc_8x8_no_delta; + mc_with_delta_func = ff_ivi_mc_8x8_delta; + mc_no_delta_func = ff_ivi_mc_8x8_no_delta; + mc_avg_with_delta_func = ff_ivi_mc_avg_8x8_delta; + mc_avg_no_delta_func = ff_ivi_mc_avg_8x8_no_delta; } else { - mc_with_delta_func = ff_ivi_mc_4x4_delta; - mc_no_delta_func = ff_ivi_mc_4x4_no_delta; + mc_with_delta_func = ff_ivi_mc_4x4_delta; + mc_no_delta_func = ff_ivi_mc_4x4_no_delta; + mc_avg_with_delta_func = ff_ivi_mc_avg_4x4_delta; + mc_avg_no_delta_func = ff_ivi_mc_avg_4x4_no_delta; } for (mbn = 0, mb = tile->mbs; mbn < tile->num_MBs; mb++, mbn++) { @@ -615,13 +655,22 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, quant = scale_tab[quant]; if (!is_intra) { - mv_x = mb->mv_x; - mv_y = mb->mv_y; + mv_x = mb->mv_x; + mv_y = mb->mv_y; + mv_x2 = mb->b_mv_x; + mv_y2 = mb->b_mv_y; if (band->is_halfpel) { - mc_type = ((mv_y & 1) << 1) | (mv_x & 1); - mv_x >>= 1; - mv_y >>= 1; /* convert halfpel vectors into fullpel ones */ + mc_type = ((mv_y & 1) << 1) | (mv_x & 1); + mc_type2 = ((mv_y2 & 1) << 1) | (mv_x2 & 1); + mv_x >>= 1; + mv_y >>= 1; + mv_x2 >>= 1; + mv_y2 >>= 1; /* convert halfpel vectors into fullpel ones */ } + if (mb->type == 2) + mc_type = -1; + if (mb->type != 2 && mb->type != 3) + mc_type2 = -1; if (mb->type) { int dmv_x, dmv_y, cx, cy; @@ -637,6 +686,21 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, return AVERROR_INVALIDDATA; } } + if (mb->type == 2 || mb->type == 3) { + int dmv_x, dmv_y, cx, cy; + + dmv_x = mb->b_mv_x >> band->is_halfpel; + dmv_y = mb->b_mv_y >> band->is_halfpel; + cx = mb->b_mv_x & band->is_halfpel; + cy = mb->b_mv_y & band->is_halfpel; + + if (mb->xpos + dmv_x < 0 || + mb->xpos + dmv_x + band->mb_size + cx > band->pitch || + mb->ypos + dmv_y < 0 || + mb->ypos + dmv_y + band->mb_size + cy > band->aheight) { + return AVERROR_INVALIDDATA; + } + } } for (blk = 0; blk < num_blocks; blk++) { @@ -650,8 +714,11 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, if (cbp & 1) { /* block coded ? */ ret = ivi_decode_coded_blocks(gb, band, mc_with_delta_func, - mv_x, mv_y, &prev_dc, is_intra, - mc_type, quant, buf_offs, avctx); + mc_avg_with_delta_func, + mv_x, mv_y, mv_x2, mv_y2, + &prev_dc, is_intra, + mc_type, mc_type2, quant, + buf_offs, avctx); if (ret < 0) return ret; } else { @@ -663,8 +730,9 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, if (ret < 0) return ret; } else { - ret = ivi_mc(band, mc_no_delta_func, buf_offs, - mv_x, mv_y, mc_type); + ret = ivi_mc(band, mc_no_delta_func, mc_avg_no_delta_func, + buf_offs, mv_x, mv_y, mv_x2, mv_y2, + mc_type, mc_type2); if (ret < 0) return ret; } @@ -786,8 +854,8 @@ static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, for (blk = 0; blk < num_blocks; blk++) { /* adjust block position in the buffer according with its number */ offs = mb->buf_offs + band->blk_size * ((blk & 1) + !!(blk & 2) * band->pitch); - ret = ivi_mc(band, mc_no_delta_func, offs, - mv_x, mv_y, mc_type); + ret = ivi_mc(band, mc_no_delta_func, 0, offs, + mv_x, mv_y, 0, 0, mc_type, -1); if (ret < 0) return ret; } @@ -869,8 +937,14 @@ static int decode_band(IVI45DecContext *ctx, av_log(avctx, AV_LOG_ERROR, "Band buffer points to no data!\n"); return AVERROR_INVALIDDATA; } - band->ref_buf = band->bufs[ctx->ref_buf]; - band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3); + if (ctx->is_indeo4 && ctx->frame_type == IVI4_FRAMETYPE_BIDIR) { + band->ref_buf = band->bufs[ctx->b_ref_buf]; + band->b_ref_buf = band->bufs[ctx->ref_buf]; + } else { + band->ref_buf = band->bufs[ctx->ref_buf]; + band->b_ref_buf = 0; + } + band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3); result = ctx->decode_band_hdr(ctx, band, avctx); if (result) { |