* commit '5ec6d152e26c570c0a16ec72c1f354db95708179': indeo4: B-frames decoding Conflicts: libavcodec/ivi_common.c Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n2.3
| @@ -195,7 +195,7 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) | |||||
| /* check if picture layout was changed and reallocate buffers */ | /* check if picture layout was changed and reallocate buffers */ | ||||
| if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf)) { | if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf)) { | ||||
| if (ff_ivi_init_planes(ctx->planes, &pic_conf)) { | |||||
| if (ff_ivi_init_planes(ctx->planes, &pic_conf, 1)) { | |||||
| av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n"); | av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n"); | ||||
| ctx->pic_conf.luma_bands = 0; | ctx->pic_conf.luma_bands = 0; | ||||
| return AVERROR(ENOMEM); | return AVERROR(ENOMEM); | ||||
| @@ -494,6 +494,8 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, | |||||
| mb->xpos = x; | mb->xpos = x; | ||||
| mb->ypos = y; | mb->ypos = y; | ||||
| mb->buf_offs = mb_offset; | mb->buf_offs = mb_offset; | ||||
| mb->b_mv_x = | |||||
| mb->b_mv_y = 0; | |||||
| if (get_bits1(&ctx->gb)) { | if (get_bits1(&ctx->gb)) { | ||||
| if (ctx->frame_type == IVI4_FRAMETYPE_INTRA) { | if (ctx->frame_type == IVI4_FRAMETYPE_INTRA) { | ||||
| @@ -571,6 +573,24 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, | |||||
| mv_x += IVI_TOSIGNED(mv_delta); | mv_x += IVI_TOSIGNED(mv_delta); | ||||
| mb->mv_x = mv_x; | mb->mv_x = mv_x; | ||||
| mb->mv_y = mv_y; | mb->mv_y = mv_y; | ||||
| if (mb->type == 3) { | |||||
| mv_delta = get_vlc2(&ctx->gb, | |||||
| ctx->mb_vlc.tab->table, | |||||
| IVI_VLC_BITS, 1); | |||||
| mv_y += IVI_TOSIGNED(mv_delta); | |||||
| mv_delta = get_vlc2(&ctx->gb, | |||||
| ctx->mb_vlc.tab->table, | |||||
| IVI_VLC_BITS, 1); | |||||
| mv_x += IVI_TOSIGNED(mv_delta); | |||||
| mb->b_mv_x = -mv_x; | |||||
| mb->b_mv_y = -mv_y; | |||||
| } | |||||
| } | |||||
| if (mb->type == 2) { | |||||
| mb->b_mv_x = -mb->mv_x; | |||||
| mb->b_mv_y = -mb->mv_y; | |||||
| mb->mv_x = 0; | |||||
| mb->mv_y = 0; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -606,32 +626,30 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, | |||||
| */ | */ | ||||
| static void switch_buffers(IVI45DecContext *ctx) | static void switch_buffers(IVI45DecContext *ctx) | ||||
| { | { | ||||
| int is_prev_ref = 0, is_ref = 0; | |||||
| switch (ctx->prev_frame_type) { | switch (ctx->prev_frame_type) { | ||||
| case IVI4_FRAMETYPE_INTRA: | case IVI4_FRAMETYPE_INTRA: | ||||
| case IVI4_FRAMETYPE_INTRA1: | case IVI4_FRAMETYPE_INTRA1: | ||||
| case IVI4_FRAMETYPE_INTER: | case IVI4_FRAMETYPE_INTER: | ||||
| ctx->buf_switch ^= 1; | |||||
| ctx->dst_buf = ctx->buf_switch; | |||||
| ctx->ref_buf = ctx->buf_switch ^ 1; | |||||
| break; | |||||
| case IVI4_FRAMETYPE_INTER_NOREF: | |||||
| is_prev_ref = 1; | |||||
| break; | break; | ||||
| } | } | ||||
| switch (ctx->frame_type) { | switch (ctx->frame_type) { | ||||
| case IVI4_FRAMETYPE_INTRA: | case IVI4_FRAMETYPE_INTRA: | ||||
| case IVI4_FRAMETYPE_INTRA1: | case IVI4_FRAMETYPE_INTRA1: | ||||
| ctx->buf_switch = 0; | |||||
| /* FALLTHROUGH */ | |||||
| case IVI4_FRAMETYPE_INTER: | case IVI4_FRAMETYPE_INTER: | ||||
| ctx->dst_buf = ctx->buf_switch; | |||||
| ctx->ref_buf = ctx->buf_switch ^ 1; | |||||
| break; | |||||
| case IVI4_FRAMETYPE_INTER_NOREF: | |||||
| case IVI4_FRAMETYPE_NULL_FIRST: | |||||
| case IVI4_FRAMETYPE_NULL_LAST: | |||||
| is_ref = 1; | |||||
| break; | break; | ||||
| } | } | ||||
| if (is_prev_ref && is_ref) { | |||||
| FFSWAP(int, ctx->dst_buf, ctx->ref_buf); | |||||
| } else if (is_prev_ref) { | |||||
| FFSWAP(int, ctx->ref_buf, ctx->b_ref_buf); | |||||
| FFSWAP(int, ctx->dst_buf, ctx->ref_buf); | |||||
| } | |||||
| } | } | ||||
| @@ -665,6 +683,9 @@ static av_cold int decode_init(AVCodecContext *avctx) | |||||
| ctx->is_indeo4 = 1; | ctx->is_indeo4 = 1; | ||||
| ctx->dst_buf = 0; | |||||
| ctx->ref_buf = 1; | |||||
| ctx->b_ref_buf = 3; /* buffer 2 is used for scalability mode */ | |||||
| ctx->p_frame = av_frame_alloc(); | ctx->p_frame = av_frame_alloc(); | ||||
| if (!ctx->p_frame) | if (!ctx->p_frame) | ||||
| return AVERROR(ENOMEM); | return AVERROR(ENOMEM); | ||||
| @@ -113,7 +113,7 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) | |||||
| /* check if picture layout was changed and reallocate buffers */ | /* check if picture layout was changed and reallocate buffers */ | ||||
| if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf) || ctx->gop_invalid) { | if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf) || ctx->gop_invalid) { | ||||
| result = ff_ivi_init_planes(ctx->planes, &pic_conf); | |||||
| result = ff_ivi_init_planes(ctx->planes, &pic_conf, 0); | |||||
| if (result < 0) { | if (result < 0) { | ||||
| av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n"); | av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n"); | ||||
| return result; | return result; | ||||
| @@ -657,7 +657,7 @@ static av_cold int decode_init(AVCodecContext *avctx) | |||||
| ctx->pic_conf.tile_height = avctx->height; | ctx->pic_conf.tile_height = avctx->height; | ||||
| ctx->pic_conf.luma_bands = ctx->pic_conf.chroma_bands = 1; | ctx->pic_conf.luma_bands = ctx->pic_conf.chroma_bands = 1; | ||||
| result = ff_ivi_init_planes(ctx->planes, &ctx->pic_conf); | |||||
| result = ff_ivi_init_planes(ctx->planes, &ctx->pic_conf, 0); | |||||
| if (result) { | if (result) { | ||||
| av_log(avctx, AV_LOG_ERROR, "Couldn't allocate color planes!\n"); | av_log(avctx, AV_LOG_ERROR, "Couldn't allocate color planes!\n"); | ||||
| return AVERROR_INVALIDDATA; | return AVERROR_INVALIDDATA; | ||||
| @@ -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, | typedef void (*ivi_mc_func) (int16_t *buf, const int16_t *ref_buf, | ||||
| uint32_t pitch, int mc_type); | 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 ref_offs = offs + mv_y * band->pitch + mv_x; | ||||
| int buf_size = band->pitch * band->aheight; | int buf_size = band->pitch * band->aheight; | ||||
| int min_size = band->pitch * (band->blk_size - 1) + band->blk_size; | int min_size = band->pitch * (band->blk_size - 1) + band->blk_size; | ||||
| int ref_size = (mc_type > 1) * band->pitch + (mc_type & 1); | 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; | 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[0]); | ||||
| av_freep(&planes[p].bands[b].bufs[1]); | av_freep(&planes[p].bands[b].bufs[1]); | ||||
| av_freep(&planes[p].bands[b].bufs[2]); | 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) | if (planes[p].bands[b].blk_vlc.cust_tab.table) | ||||
| ff_free_vlc(&planes[p].bands[b].blk_vlc.cust_tab); | 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; | int p, b; | ||||
| uint32_t b_width, b_height, align_fac, width_aligned, | 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]) | if (!band->bufs[2]) | ||||
| return AVERROR(ENOMEM); | return AVERROR(ENOMEM); | ||||
| } | } | ||||
| if (is_indeo4) { | |||||
| band->bufs[3] = av_mallocz(buf_size); | |||||
| if (!band->bufs[3]) | |||||
| return AVERROR(ENOMEM); | |||||
| } | |||||
| /* reset custom vlc */ | /* reset custom vlc */ | ||||
| planes[p].bands[0].blk_vlc.cust_desc.num_rows = 0; | 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, | 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, | uint32_t quant, int offs, | ||||
| AVCodecContext *avctx) | AVCodecContext *avctx) | ||||
| { | { | ||||
| @@ -560,7 +593,8 @@ static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, | |||||
| /* apply motion compensation */ | /* apply motion compensation */ | ||||
| if (!is_intra) | 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; | 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, | static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, | ||||
| IVITile *tile, AVCodecContext *avctx) | 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; | int32_t prev_dc; | ||||
| uint32_t cbp, quant, buf_offs; | uint32_t cbp, quant, buf_offs; | ||||
| IVIMbInfo *mb; | IVIMbInfo *mb; | ||||
| ivi_mc_func mc_with_delta_func, mc_no_delta_func; | 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; | const uint8_t *scale_tab; | ||||
| /* init intra prediction for the DC coefficient */ | /* 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 */ | /* number of blocks per mb */ | ||||
| num_blocks = (band->mb_size != blk_size) ? 4 : 1; | num_blocks = (band->mb_size != blk_size) ? 4 : 1; | ||||
| if (blk_size == 8) { | 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 { | } 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++) { | 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]; | quant = scale_tab[quant]; | ||||
| if (!is_intra) { | 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) { | 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) { | if (mb->type) { | ||||
| int dmv_x, dmv_y, cx, cy; | int dmv_x, dmv_y, cx, cy; | ||||
| @@ -630,6 +679,21 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, | |||||
| cx = mb->mv_x & band->is_halfpel; | cx = mb->mv_x & band->is_halfpel; | ||||
| cy = mb->mv_y & band->is_halfpel; | cy = mb->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; | |||||
| } | |||||
| } | |||||
| 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 || | if (mb->xpos + dmv_x < 0 || | ||||
| mb->xpos + dmv_x + band->mb_size + cx > band->pitch || | mb->xpos + dmv_x + band->mb_size + cx > band->pitch || | ||||
| mb->ypos + dmv_y < 0 || | mb->ypos + dmv_y < 0 || | ||||
| @@ -650,8 +714,11 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, | |||||
| if (cbp & 1) { /* block coded ? */ | if (cbp & 1) { /* block coded ? */ | ||||
| ret = ivi_decode_coded_blocks(gb, band, mc_with_delta_func, | 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) | if (ret < 0) | ||||
| return ret; | return ret; | ||||
| } else { | } else { | ||||
| @@ -663,8 +730,9 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, | |||||
| if (ret < 0) | if (ret < 0) | ||||
| return ret; | return ret; | ||||
| } else { | } 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) | if (ret < 0) | ||||
| return ret; | return ret; | ||||
| } | } | ||||
| @@ -786,8 +854,8 @@ static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, | |||||
| for (blk = 0; blk < num_blocks; blk++) { | for (blk = 0; blk < num_blocks; blk++) { | ||||
| /* adjust block position in the buffer according with its number */ | /* adjust block position in the buffer according with its number */ | ||||
| offs = mb->buf_offs + band->blk_size * ((blk & 1) + !!(blk & 2) * band->pitch); | 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) | if (ret < 0) | ||||
| return ret; | 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"); | av_log(avctx, AV_LOG_ERROR, "Band buffer points to no data!\n"); | ||||
| return AVERROR_INVALIDDATA; | 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); | result = ctx->decode_band_hdr(ctx, band, avctx); | ||||
| if (result) { | if (result) { | ||||
| @@ -117,6 +117,8 @@ typedef struct IVIMbInfo { | |||||
| int8_t q_delta; ///< quant delta | int8_t q_delta; ///< quant delta | ||||
| int8_t mv_x; ///< motion vector (x component) | int8_t mv_x; ///< motion vector (x component) | ||||
| int8_t mv_y; ///< motion vector (y component) | int8_t mv_y; ///< motion vector (y component) | ||||
| int8_t b_mv_x; ///< second motion vector (x component) | |||||
| int8_t b_mv_y; ///< second motion vector (y component) | |||||
| } IVIMbInfo; | } IVIMbInfo; | ||||
| @@ -150,7 +152,8 @@ typedef struct IVIBandDesc { | |||||
| int data_size; ///< size of the band data | int data_size; ///< size of the band data | ||||
| int16_t *buf; ///< pointer to the output buffer for this band | int16_t *buf; ///< pointer to the output buffer for this band | ||||
| int16_t *ref_buf; ///< pointer to the reference frame buffer (for motion compensation) | int16_t *ref_buf; ///< pointer to the reference frame buffer (for motion compensation) | ||||
| int16_t *bufs[3]; ///< array of pointers to the band buffers | |||||
| int16_t *b_ref_buf; ///< pointer to the second reference frame buffer (for motion compensation) | |||||
| int16_t *bufs[4]; ///< array of pointers to the band buffers | |||||
| int pitch; ///< pitch associated with the buffers above | int pitch; ///< pitch associated with the buffers above | ||||
| int is_empty; ///< = 1 if this band doesn't contain any data | int is_empty; ///< = 1 if this band doesn't contain any data | ||||
| int mb_size; ///< macroblock size | int mb_size; ///< macroblock size | ||||
| @@ -232,6 +235,7 @@ typedef struct IVI45DecContext { | |||||
| int dst_buf; ///< buffer index for the currently decoded frame | int dst_buf; ///< buffer index for the currently decoded frame | ||||
| int ref_buf; ///< inter frame reference buffer index | int ref_buf; ///< inter frame reference buffer index | ||||
| int ref2_buf; ///< temporal storage for switching buffers | int ref2_buf; ///< temporal storage for switching buffers | ||||
| int b_ref_buf; ///< second reference frame buffer index | |||||
| IVIHuffTab mb_vlc; ///< current macroblock table descriptor | IVIHuffTab mb_vlc; ///< current macroblock table descriptor | ||||
| IVIHuffTab blk_vlc; ///< current block table descriptor | IVIHuffTab blk_vlc; ///< current block table descriptor | ||||
| @@ -261,7 +265,7 @@ typedef struct IVI45DecContext { | |||||
| int (*is_nonnull_frame)(struct IVI45DecContext *ctx); | int (*is_nonnull_frame)(struct IVI45DecContext *ctx); | ||||
| int gop_invalid; | int gop_invalid; | ||||
| int buf_invalid[3]; | |||||
| int buf_invalid[4]; | |||||
| int is_indeo4; | int is_indeo4; | ||||
| @@ -316,11 +320,13 @@ int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab, | |||||
| /** | /** | ||||
| * Initialize planes (prepares descriptors, allocates buffers etc). | * Initialize planes (prepares descriptors, allocates buffers etc). | ||||
| * | * | ||||
| * @param[in,out] planes pointer to the array of the plane descriptors | |||||
| * @param[in] cfg pointer to the ivi_pic_config structure describing picture layout | |||||
| * @param[in,out] planes pointer to the array of the plane descriptors | |||||
| * @param[in] cfg pointer to the ivi_pic_config structure describing picture layout | |||||
| * @param[in] is_indeo4 flag signalling if it is Indeo 4 or not | |||||
| * @return result code: 0 - OK | * @return result code: 0 - OK | ||||
| */ | */ | ||||
| int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg); | |||||
| int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg, | |||||
| int is_indeo4); | |||||
| /** | /** | ||||
| * Initialize tile and macroblock descriptors. | * Initialize tile and macroblock descriptors. | ||||
| @@ -772,39 +772,66 @@ void ff_ivi_put_dc_pixel_8x8(const int32_t *in, int16_t *out, uint32_t pitch, | |||||
| } | } | ||||
| #define IVI_MC_TEMPLATE(size, suffix, OP) \ | #define IVI_MC_TEMPLATE(size, suffix, OP) \ | ||||
| void ff_ivi_mc_ ## size ##x## size ## suffix (int16_t *buf, const int16_t *ref_buf, \ | |||||
| uint32_t pitch, int mc_type) \ | |||||
| static void ivi_mc_ ## size ##x## size ## suffix(int16_t *buf, \ | |||||
| uint32_t dpitch, \ | |||||
| const int16_t *ref_buf, \ | |||||
| uint32_t pitch, int mc_type) \ | |||||
| { \ | { \ | ||||
| int i, j; \ | int i, j; \ | ||||
| const int16_t *wptr; \ | const int16_t *wptr; \ | ||||
| \ | \ | ||||
| switch (mc_type) { \ | switch (mc_type) { \ | ||||
| case 0: /* fullpel (no interpolation) */ \ | case 0: /* fullpel (no interpolation) */ \ | ||||
| for (i = 0; i < size; i++, buf += pitch, ref_buf += pitch) { \ | |||||
| for (i = 0; i < size; i++, buf += dpitch, ref_buf += pitch) { \ | |||||
| for (j = 0; j < size; j++) {\ | for (j = 0; j < size; j++) {\ | ||||
| OP(buf[j], ref_buf[j]); \ | OP(buf[j], ref_buf[j]); \ | ||||
| } \ | } \ | ||||
| } \ | } \ | ||||
| break; \ | break; \ | ||||
| case 1: /* horizontal halfpel interpolation */ \ | case 1: /* horizontal halfpel interpolation */ \ | ||||
| for (i = 0; i < size; i++, buf += pitch, ref_buf += pitch) \ | |||||
| for (i = 0; i < size; i++, buf += dpitch, ref_buf += pitch) \ | |||||
| for (j = 0; j < size; j++) \ | for (j = 0; j < size; j++) \ | ||||
| OP(buf[j], (ref_buf[j] + ref_buf[j+1]) >> 1); \ | OP(buf[j], (ref_buf[j] + ref_buf[j+1]) >> 1); \ | ||||
| break; \ | break; \ | ||||
| case 2: /* vertical halfpel interpolation */ \ | case 2: /* vertical halfpel interpolation */ \ | ||||
| wptr = ref_buf + pitch; \ | wptr = ref_buf + pitch; \ | ||||
| for (i = 0; i < size; i++, buf += pitch, wptr += pitch, ref_buf += pitch) \ | |||||
| for (i = 0; i < size; i++, buf += dpitch, wptr += pitch, ref_buf += pitch) \ | |||||
| for (j = 0; j < size; j++) \ | for (j = 0; j < size; j++) \ | ||||
| OP(buf[j], (ref_buf[j] + wptr[j]) >> 1); \ | OP(buf[j], (ref_buf[j] + wptr[j]) >> 1); \ | ||||
| break; \ | break; \ | ||||
| case 3: /* vertical and horizontal halfpel interpolation */ \ | case 3: /* vertical and horizontal halfpel interpolation */ \ | ||||
| wptr = ref_buf + pitch; \ | wptr = ref_buf + pitch; \ | ||||
| for (i = 0; i < size; i++, buf += pitch, wptr += pitch, ref_buf += pitch) \ | |||||
| for (i = 0; i < size; i++, buf += dpitch, wptr += pitch, ref_buf += pitch) \ | |||||
| for (j = 0; j < size; j++) \ | for (j = 0; j < size; j++) \ | ||||
| OP(buf[j], (ref_buf[j] + ref_buf[j+1] + wptr[j] + wptr[j+1]) >> 2); \ | OP(buf[j], (ref_buf[j] + ref_buf[j+1] + wptr[j] + wptr[j+1]) >> 2); \ | ||||
| break; \ | break; \ | ||||
| } \ | } \ | ||||
| } \ | } \ | ||||
| \ | |||||
| void ff_ivi_mc_ ## size ##x## size ## suffix(int16_t *buf, const int16_t *ref_buf, \ | |||||
| uint32_t pitch, int mc_type) \ | |||||
| { \ | |||||
| ivi_mc_ ## size ##x## size ## suffix(buf, pitch, ref_buf, pitch, mc_type); \ | |||||
| } \ | |||||
| #define IVI_MC_AVG_TEMPLATE(size, suffix, OP) \ | |||||
| void ff_ivi_mc_avg_ ## size ##x## size ## suffix(int16_t *buf, \ | |||||
| const int16_t *ref_buf, \ | |||||
| const int16_t *ref_buf2, \ | |||||
| uint32_t pitch, \ | |||||
| int mc_type, int mc_type2) \ | |||||
| { \ | |||||
| int16_t tmp[size * size]; \ | |||||
| int i, j; \ | |||||
| \ | |||||
| ivi_mc_ ## size ##x## size ## _no_delta(tmp, size, ref_buf, pitch, mc_type); \ | |||||
| ivi_mc_ ## size ##x## size ## _delta(tmp, size, ref_buf2, pitch, mc_type2); \ | |||||
| for (i = 0; i < size; i++, buf += pitch) { \ | |||||
| for (j = 0; j < size; j++) {\ | |||||
| OP(buf[j], tmp[i * size + j] >> 1); \ | |||||
| } \ | |||||
| } \ | |||||
| } \ | |||||
| #define OP_PUT(a, b) (a) = (b) | #define OP_PUT(a, b) (a) = (b) | ||||
| #define OP_ADD(a, b) (a) += (b) | #define OP_ADD(a, b) (a) += (b) | ||||
| @@ -813,3 +840,7 @@ IVI_MC_TEMPLATE(8, _no_delta, OP_PUT) | |||||
| IVI_MC_TEMPLATE(8, _delta, OP_ADD) | IVI_MC_TEMPLATE(8, _delta, OP_ADD) | ||||
| IVI_MC_TEMPLATE(4, _no_delta, OP_PUT) | IVI_MC_TEMPLATE(4, _no_delta, OP_PUT) | ||||
| IVI_MC_TEMPLATE(4, _delta, OP_ADD) | IVI_MC_TEMPLATE(4, _delta, OP_ADD) | ||||
| IVI_MC_AVG_TEMPLATE(8, _no_delta, OP_PUT) | |||||
| IVI_MC_AVG_TEMPLATE(8, _delta, OP_ADD) | |||||
| IVI_MC_AVG_TEMPLATE(4, _no_delta, OP_PUT) | |||||
| IVI_MC_AVG_TEMPLATE(4, _delta, OP_ADD) | |||||
| @@ -295,4 +295,52 @@ void ff_ivi_mc_8x8_no_delta(int16_t *buf, const int16_t *ref_buf, uint32_t pitch | |||||
| */ | */ | ||||
| void ff_ivi_mc_4x4_no_delta(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); | void ff_ivi_mc_4x4_no_delta(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); | ||||
| /** | |||||
| * 8x8 block motion compensation with adding delta | |||||
| * | |||||
| * @param[in,out] buf pointer to the block in the current frame buffer containing delta | |||||
| * @param[in] ref_buf pointer to the corresponding block in the backward reference frame | |||||
| * @param[in] ref_buf2 pointer to the corresponding block in the forward reference frame | |||||
| * @param[in] pitch pitch for moving to the next y line | |||||
| * @param[in] mc_type interpolation type for backward reference | |||||
| * @param[in] mc_type2 interpolation type for forward reference | |||||
| */ | |||||
| void ff_ivi_mc_avg_8x8_delta(int16_t *buf, const int16_t *ref_buf, const int16_t *ref_buf2, uint32_t pitch, int mc_type, int mc_type2); | |||||
| /** | |||||
| * 4x4 block motion compensation with adding delta | |||||
| * | |||||
| * @param[in,out] buf pointer to the block in the current frame buffer containing delta | |||||
| * @param[in] ref_buf pointer to the corresponding block in the backward reference frame | |||||
| * @param[in] ref_buf2 pointer to the corresponding block in the forward reference frame | |||||
| * @param[in] pitch pitch for moving to the next y line | |||||
| * @param[in] mc_type interpolation type for backward reference | |||||
| * @param[in] mc_type2 interpolation type for forward reference | |||||
| */ | |||||
| void ff_ivi_mc_avg_4x4_delta(int16_t *buf, const int16_t *ref_buf, const int16_t *ref_buf2, uint32_t pitch, int mc_type, int mc_type2); | |||||
| /** | |||||
| * motion compensation without adding delta for B-frames | |||||
| * | |||||
| * @param[in,out] buf pointer to the block in the current frame receiving the result | |||||
| * @param[in] ref_buf pointer to the corresponding block in the backward reference frame | |||||
| * @param[in] ref_buf2 pointer to the corresponding block in the forward reference frame | |||||
| * @param[in] pitch pitch for moving to the next y line | |||||
| * @param[in] mc_type interpolation type for backward reference | |||||
| * @param[in] mc_type2 interpolation type for forward reference | |||||
| */ | |||||
| void ff_ivi_mc_avg_8x8_no_delta(int16_t *buf, const int16_t *ref_buf, const int16_t *ref_buf2, uint32_t pitch, int mc_type, int mc_type2); | |||||
| /** | |||||
| * 4x4 block motion compensation without adding delta for B-frames | |||||
| * | |||||
| * @param[in,out] buf pointer to the block in the current frame receiving the result | |||||
| * @param[in] ref_buf pointer to the corresponding block in the backward reference frame | |||||
| * @param[in] ref_buf2 pointer to the corresponding block in the forward reference frame | |||||
| * @param[in] pitch pitch for moving to the next y line | |||||
| * @param[in] mc_type interpolation type for backward reference | |||||
| * @param[in] mc_type2 interpolation type for forward reference | |||||
| */ | |||||
| void ff_ivi_mc_avg_4x4_no_delta(int16_t *buf, const int16_t *ref_buf, const int16_t *ref_buf2, uint32_t pitch, int mc_type, int mc_type2); | |||||
| #endif /* AVCODEC_IVI_DSP_H */ | #endif /* AVCODEC_IVI_DSP_H */ | ||||