X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Findeo4.c;h=35f266ee1341ba45de510336eccd8838ee64b724;hb=369380e1c4c6fc9b0d9ff04ec23d46b252ba7110;hp=fccb74f80a0144a0f2ba2ca83cdc4ce362e7fea0;hpb=28dda8a691f1c723a4a9365ab85f9625f1330096;p=ffmpeg diff --git a/libavcodec/indeo4.c b/libavcodec/indeo4.c index fccb74f80a0..35f266ee134 100644 --- a/libavcodec/indeo4.c +++ b/libavcodec/indeo4.c @@ -34,19 +34,6 @@ #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 @@ -132,7 +119,7 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) } #if IVI4_STREAM_ANALYSER - if (ctx->frame_type == FRAMETYPE_BIDIR) + if (ctx->frame_type == IVI4_FRAMETYPE_BIDIR) ctx->has_b_frames = 1; #endif @@ -152,7 +139,7 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) 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; } @@ -207,7 +194,7 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) /* 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); @@ -293,6 +280,7 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, 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)) @@ -326,7 +314,7 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, 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) { @@ -369,13 +357,26 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, 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; } } @@ -448,7 +449,7 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, 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); @@ -461,9 +462,11 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, 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; } @@ -494,8 +497,8 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, 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); @@ -536,6 +539,24 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, 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; } } } @@ -562,38 +583,36 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, */ 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; } @@ -619,18 +638,27 @@ static av_cold int decode_init(AVCodecContext *avctx) 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, };