#include "ivi_common.h"
#include "indeo4data.h"
-/**
- * Indeo 4 frame types.
- */
-enum {
- FRAMETYPE_INTRA = 0,
- FRAMETYPE_INTRA1 = 1, ///< intra frame with slightly different bitstream coding
- FRAMETYPE_INTER = 2, ///< non-droppable P-frame
- FRAMETYPE_BIDIR = 3, ///< bidirectional frame
- FRAMETYPE_INTER_NOREF = 4, ///< droppable P-frame
- FRAMETYPE_NULL_FIRST = 5, ///< empty frame with no data
- FRAMETYPE_NULL_LAST = 6 ///< empty frame with no data
-};
-
#define IVI4_PIC_SIZE_ESC 7
}
#if IVI4_STREAM_ANALYSER
- if (ctx->frame_type == FRAMETYPE_BIDIR)
+ if (ctx->frame_type == IVI4_FRAMETYPE_BIDIR)
ctx->has_b_frames = 1;
#endif
ctx->data_size = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 24) : 0;
/* null frames don't contain anything else so we just return */
- if (ctx->frame_type >= FRAMETYPE_NULL_FIRST) {
+ if (ctx->frame_type >= IVI4_FRAMETYPE_NULL_FIRST) {
av_dlog(avctx, "Null frame encountered!\n");
return 0;
}
/* check if picture layout was changed and reallocate buffers */
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");
ctx->pic_conf.luma_bands = 0;
return AVERROR(ENOMEM);
band->is_empty = get_bits1(&ctx->gb);
if (!band->is_empty) {
+ int old_blk_size = band->blk_size;
/* skip header size
* If header size is not given, header size is 4 bytes. */
if (get_bits1(&ctx->gb))
band->glob_quant = get_bits(&ctx->gb, 5);
- if (!get_bits1(&ctx->gb) || ctx->frame_type == FRAMETYPE_INTRA) {
+ if (!get_bits1(&ctx->gb) || ctx->frame_type == IVI4_FRAMETYPE_INTRA) {
transform_id = get_bits(&ctx->gb, 5);
if (transform_id >= FF_ARRAY_ELEMS(transforms) ||
!transforms[transform_id].inv_trans) {
band->scan = scan_index_to_tab[scan_indx];
band->quant_mat = get_bits(&ctx->gb, 5);
- if (band->quant_mat == 31) {
- av_log(avctx, AV_LOG_ERROR, "Custom quant matrix encountered!\n");
+ if (band->quant_mat >= FF_ARRAY_ELEMS(quant_index_to_tab)) {
+
+ if (band->quant_mat == 31)
+ av_log(avctx, AV_LOG_ERROR,
+ "Custom quant matrix encountered!\n");
+ else
+ avpriv_request_sample(avctx, "Quantization matrix %d",
+ band->quant_mat);
+ band->quant_mat = -1;
return AVERROR_INVALIDDATA;
}
- if (band->quant_mat >= FF_ARRAY_ELEMS(quant_index_to_tab)) {
- avpriv_request_sample(avctx, "Quantization matrix %d",
- band->quant_mat);
+ } else {
+ if (old_blk_size != band->blk_size) {
+ av_log(avctx, AV_LOG_ERROR,
+ "The band block size does not match the configuration "
+ "inherited\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (band->quant_mat < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid quant_mat inherited\n");
return AVERROR_INVALIDDATA;
}
}
offs = tile->ypos * band->pitch + tile->xpos;
blks_per_mb = band->mb_size != band->blk_size ? 4 : 1;
- mb_type_bits = ctx->frame_type == FRAMETYPE_BIDIR ? 2 : 1;
+ mb_type_bits = ctx->frame_type == IVI4_FRAMETYPE_BIDIR ? 2 : 1;
/* scale factor for motion vectors */
mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3);
mb->xpos = x;
mb->ypos = y;
mb->buf_offs = mb_offset;
+ mb->b_mv_x =
+ mb->b_mv_y = 0;
if (get_bits1(&ctx->gb)) {
- if (ctx->frame_type == FRAMETYPE_INTRA) {
+ if (ctx->frame_type == IVI4_FRAMETYPE_INTRA) {
av_log(avctx, AV_LOG_ERROR, "Empty macroblock in an INTRA picture!\n");
return AVERROR_INVALIDDATA;
}
if (!ref_mb)
return AVERROR_INVALIDDATA;
mb->type = ref_mb->type;
- } else if (ctx->frame_type == FRAMETYPE_INTRA ||
- ctx->frame_type == FRAMETYPE_INTRA1) {
+ } else if (ctx->frame_type == IVI4_FRAMETYPE_INTRA ||
+ ctx->frame_type == IVI4_FRAMETYPE_INTRA1) {
mb->type = 0; /* mb_type is always INTRA for intra-frames */
} else {
mb->type = get_bits(&ctx->gb, mb_type_bits);
mv_x += IVI_TOSIGNED(mv_delta);
mb->mv_x = mv_x;
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;
}
}
}
*/
static void switch_buffers(IVI45DecContext *ctx)
{
+ int is_prev_ref = 0, is_ref = 0;
+
switch (ctx->prev_frame_type) {
- case FRAMETYPE_INTRA:
- case FRAMETYPE_INTRA1:
- case FRAMETYPE_INTER:
- ctx->buf_switch ^= 1;
- ctx->dst_buf = ctx->buf_switch;
- ctx->ref_buf = ctx->buf_switch ^ 1;
- break;
- case FRAMETYPE_INTER_NOREF:
+ case IVI4_FRAMETYPE_INTRA:
+ case IVI4_FRAMETYPE_INTRA1:
+ case IVI4_FRAMETYPE_INTER:
+ is_prev_ref = 1;
break;
}
switch (ctx->frame_type) {
- case FRAMETYPE_INTRA:
- case FRAMETYPE_INTRA1:
- ctx->buf_switch = 0;
- /* FALLTHROUGH */
- case FRAMETYPE_INTER:
- ctx->dst_buf = ctx->buf_switch;
- ctx->ref_buf = ctx->buf_switch ^ 1;
- break;
- case FRAMETYPE_INTER_NOREF:
- case FRAMETYPE_NULL_FIRST:
- case FRAMETYPE_NULL_LAST:
+ case IVI4_FRAMETYPE_INTRA:
+ case IVI4_FRAMETYPE_INTRA1:
+ case IVI4_FRAMETYPE_INTER:
+ is_ref = 1;
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);
+ }
}
static int is_nonnull_frame(IVI45DecContext *ctx)
{
- return ctx->frame_type < FRAMETYPE_NULL_FIRST;
+ return ctx->frame_type < IVI4_FRAMETYPE_NULL_FIRST;
}
ctx->switch_buffers = switch_buffers;
ctx->is_nonnull_frame = is_nonnull_frame;
+ 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();
+ if (!ctx->p_frame)
+ return AVERROR(ENOMEM);
+
return 0;
}
AVCodec ff_indeo4_decoder = {
.name = "indeo4",
+ .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 4"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_INDEO4,
.priv_data_size = sizeof(IVI45DecContext),
.init = decode_init,
.close = ff_ivi_decode_close,
.decode = ff_ivi_decode_frame,
- .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 4"),
.capabilities = CODEC_CAP_DR1,
};