mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-02-14 22:22:59 +02:00
Merge commit '5ec6d152e26c570c0a16ec72c1f354db95708179'
* commit '5ec6d152e26c570c0a16ec72c1f354db95708179': indeo4: B-frames decoding Conflicts: libavcodec/ivi_common.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
357168bcf6
@ -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;
|
is_prev_ref = 1;
|
||||||
ctx->dst_buf = ctx->buf_switch;
|
|
||||||
ctx->ref_buf = ctx->buf_switch ^ 1;
|
|
||||||
break;
|
|
||||||
case IVI4_FRAMETYPE_INTER_NOREF:
|
|
||||||
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;
|
is_ref = 1;
|
||||||
ctx->ref_buf = ctx->buf_switch ^ 1;
|
|
||||||
break;
|
|
||||||
case IVI4_FRAMETYPE_INTER_NOREF:
|
|
||||||
case IVI4_FRAMETYPE_NULL_FIRST:
|
|
||||||
case IVI4_FRAMETYPE_NULL_LAST:
|
|
||||||
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,
|
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);
|
||||||
|
|
||||||
av_assert0(offs >= 0 && ref_offs >= 0 && band->ref_buf);
|
if (mc_type != -1) {
|
||||||
av_assert0(buf_size - min_size >= offs);
|
av_assert0(offs >= 0 && ref_offs >= 0 && band->ref_buf);
|
||||||
av_assert0(buf_size - min_size - ref_size >= ref_offs);
|
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,
|
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 */
|
||||||
@ -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_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++) {
|
||||||
@ -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_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);
|
||||||
mv_x >>= 1;
|
mc_type2 = ((mv_y2 & 1) << 1) | (mv_x2 & 1);
|
||||||
mv_y >>= 1; /* convert halfpel vectors into fullpel ones */
|
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_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,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];
|
if (ctx->is_indeo4 && ctx->frame_type == IVI4_FRAMETYPE_BIDIR) {
|
||||||
band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3);
|
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,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] 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, \
|
static void ivi_mc_ ## size ##x## size ## suffix(int16_t *buf, \
|
||||||
uint32_t pitch, int mc_type) \
|
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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user