|
|
@ -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, |
|
|
|
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 mc_type) |
|
|
|
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); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (mc_type != -1) { |
|
|
|
av_assert0(offs >= 0 && ref_offs >= 0 && band->ref_buf); |
|
|
|
av_assert0(offs >= 0 && ref_offs >= 0 && band->ref_buf); |
|
|
|
av_assert0(buf_size - min_size >= offs); |
|
|
|
av_assert0(buf_size - min_size >= offs); |
|
|
|
av_assert0(buf_size - min_size - ref_size >= ref_offs); |
|
|
|
av_assert0(buf_size - min_size - ref_size >= ref_offs); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (mc_type2 == -1) { |
|
|
|
mc(band->buf + offs, band->ref_buf + ref_offs, band->pitch, mc_type); |
|
|
|
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, |
|
|
|
ivi_mc_func mc, ivi_mc_avg_func mc_avg, |
|
|
|
int *prev_dc, int is_intra, int mc_type, |
|
|
|
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 mbn, blk, num_blocks, blk_size, ret, is_intra; |
|
|
|
int mv_x = 0, mv_y = 0; |
|
|
|
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 */ |
|
|
@ -594,9 +630,13 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, |
|
|
|
if (blk_size == 8) { |
|
|
|
if (blk_size == 8) { |
|
|
|
mc_with_delta_func = ff_ivi_mc_8x8_delta; |
|
|
|
mc_with_delta_func = ff_ivi_mc_8x8_delta; |
|
|
|
mc_no_delta_func = ff_ivi_mc_8x8_no_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_with_delta_func = ff_ivi_mc_4x4_delta; |
|
|
|
mc_no_delta_func = ff_ivi_mc_4x4_no_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++) { |
|
|
@ -617,11 +657,20 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, |
|
|
|
if (!is_intra) { |
|
|
|
if (!is_intra) { |
|
|
|
mv_x = mb->mv_x; |
|
|
|
mv_x = mb->mv_x; |
|
|
|
mv_y = mb->mv_y; |
|
|
|
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); |
|
|
|
mc_type = ((mv_y & 1) << 1) | (mv_x & 1); |
|
|
|
|
|
|
|
mc_type2 = ((mv_y2 & 1) << 1) | (mv_x2 & 1); |
|
|
|
mv_x >>= 1; |
|
|
|
mv_x >>= 1; |
|
|
|
mv_y >>= 1; /* convert halfpel vectors into fullpel ones */ |
|
|
|
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_avg_with_delta_func, |
|
|
|
mc_type, quant, buf_offs, avctx); |
|
|
|
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, |
|
|
|
ret = ivi_mc(band, mc_no_delta_func, mc_avg_no_delta_func, |
|
|
|
mv_x, mv_y, mc_type); |
|
|
|
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, |
|
|
|
ret = ivi_mc(band, mc_no_delta_func, 0, offs, |
|
|
|
mv_x, mv_y, mc_type); |
|
|
|
mv_x, mv_y, 0, 0, mc_type, -1); |
|
|
|
if (ret < 0) |
|
|
|
if (ret < 0) |
|
|
|
return ret; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
@ -869,7 +937,13 @@ 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; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
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->ref_buf = band->bufs[ctx->ref_buf]; |
|
|
|
|
|
|
|
band->b_ref_buf = 0; |
|
|
|
|
|
|
|
} |
|
|
|
band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3); |
|
|
|
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); |
|
|
|