On Fri, May 30, 2014 at 7:38 AM, Anton Khirnov <[email protected]> wrote: > > > On Thu, 29 May 2014 13:44:34 +0200, Dirk Ausserhaus <[email protected]> > wrote: > > diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c > > index cf4df18..ef4df10 100644 > > --- a/libavcodec/ivi_common.c > > +++ b/libavcodec/ivi_common.c > > @@ -968,6 +968,21 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void > > *data, int *got_frame, > > if (ctx->gop_invalid) > > return AVERROR_INVALIDDATA; > > > > + if (avctx->codec_id == AV_CODEC_ID_INDEO4 && > > + ctx->frame_type == IVI4_FRAMETYPE_NULL_LAST) { > > + if (ctx->got_p_frame) { > > + if ((result = av_frame_ref(data, ctx->p_frame)) < 0) > > + return result; > > + av_frame_free(&ctx->p_frame); > > + ctx->p_frame = av_frame_alloc(); > > The above 4 lines should be replaced with av_frame_move_ref(data, > ctx->p_frame) > > The rest looks fine to me.
Here're the updated patches in case you've not committed them yet. P.S. I might look at I263 too. What are the samples with IP-frames there?
From 83d780ff2238d3af357d621e2602bb267e39574f Mon Sep 17 00:00:00 2001 From: Dirk Ausserhaus <[email protected]> Date: Thu, 29 May 2014 13:17:49 +0200 Subject: [PATCH 1/2] Move Indeo4 frametypes into common header. --- libavcodec/indeo4.c | 49 +++++++++++++++++----------------------------- libavcodec/ivi_common.c | 2 +- libavcodec/ivi_common.h | 13 ++++++++++++ 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/libavcodec/indeo4.c b/libavcodec/indeo4.c index 6a19955..ca81d62 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; } @@ -327,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) { @@ -462,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); @@ -477,7 +464,7 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, mb->buf_offs = mb_offset; 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; } @@ -508,8 +495,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); @@ -577,29 +564,29 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, static void switch_buffers(IVI45DecContext *ctx) { switch (ctx->prev_frame_type) { - case FRAMETYPE_INTRA: - case FRAMETYPE_INTRA1: - case FRAMETYPE_INTER: + case IVI4_FRAMETYPE_INTRA: + case IVI4_FRAMETYPE_INTRA1: + case IVI4_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_INTER_NOREF: break; } switch (ctx->frame_type) { - case FRAMETYPE_INTRA: - case FRAMETYPE_INTRA1: + case IVI4_FRAMETYPE_INTRA: + case IVI4_FRAMETYPE_INTRA1: ctx->buf_switch = 0; /* FALLTHROUGH */ - case FRAMETYPE_INTER: + case IVI4_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_INTER_NOREF: + case IVI4_FRAMETYPE_NULL_FIRST: + case IVI4_FRAMETYPE_NULL_LAST: break; } } @@ -607,7 +594,7 @@ static void switch_buffers(IVI45DecContext *ctx) static int is_nonnull_frame(IVI45DecContext *ctx) { - return ctx->frame_type < FRAMETYPE_NULL_FIRST; + return ctx->frame_type < IVI4_FRAMETYPE_NULL_FIRST; } diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index 923cd75..cf4df18 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -1011,7 +1011,7 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, * That's exactly the same Intel decoders do. */ if (avctx->codec_id == AV_CODEC_ID_INDEO4 && - ctx->frame_type == 0/*FRAMETYPE_INTRA*/) { + ctx->frame_type == IVI4_FRAMETYPE_INTRA) { while (get_bits(&ctx->gb, 8)); // skip version string skip_bits_long(&ctx->gb, 64); // skip padding, TODO: implement correct 8-bytes alignment if (get_bits_left(&ctx->gb) > 18 && show_bits(&ctx->gb, 18) == 0x3FFF8) diff --git a/libavcodec/ivi_common.h b/libavcodec/ivi_common.h index fb97c8d..584bf07 100644 --- a/libavcodec/ivi_common.h +++ b/libavcodec/ivi_common.h @@ -33,6 +33,19 @@ #include "get_bits.h" #include <stdint.h> +/** + * Indeo 4 frame types. + */ +enum { + IVI4_FRAMETYPE_INTRA = 0, + IVI4_FRAMETYPE_INTRA1 = 1, ///< intra frame with slightly different bitstream coding + IVI4_FRAMETYPE_INTER = 2, ///< non-droppable P-frame + IVI4_FRAMETYPE_BIDIR = 3, ///< bidirectional frame + IVI4_FRAMETYPE_INTER_NOREF = 4, ///< droppable P-frame + IVI4_FRAMETYPE_NULL_FIRST = 5, ///< empty frame with no data + IVI4_FRAMETYPE_NULL_LAST = 6 ///< empty frame with no data +}; + #define IVI_VLC_BITS 13 ///< max number of bits of the ivi's huffman codes #define IVI4_STREAM_ANALYSER 0 #define IVI5_IS_PROTECTED 0x20 -- 1.7.0.4
From 74f6fd3aa457f3847e43cd39ceaad1be8fefef5f Mon Sep 17 00:00:00 2001 From: Dirk Ausserhaus <[email protected]> Date: Thu, 29 May 2014 13:30:37 +0200 Subject: [PATCH 2/2] Decode both parts of Indeo4 IP frames --- libavcodec/indeo4.c | 4 +++ libavcodec/ivi_common.c | 48 ++++++++++++++++++++++++++++++++++------------ libavcodec/ivi_common.h | 3 ++ 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/libavcodec/indeo4.c b/libavcodec/indeo4.c index ca81d62..3e97221 100644 --- a/libavcodec/indeo4.c +++ b/libavcodec/indeo4.c @@ -620,6 +620,10 @@ static av_cold int decode_init(AVCodecContext *avctx) ctx->switch_buffers = switch_buffers; ctx->is_nonnull_frame = is_nonnull_frame; + ctx->p_frame = av_frame_alloc(); + if (!ctx->p_frame) + return AVERROR(ENOMEM); + return 0; } diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index cf4df18..6eb5b6c 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -968,6 +968,18 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (ctx->gop_invalid) return AVERROR_INVALIDDATA; + if (avctx->codec_id == AV_CODEC_ID_INDEO4 && + ctx->frame_type == IVI4_FRAMETYPE_NULL_LAST) { + if (ctx->got_p_frame) { + av_frame_move_ref(data, ctx->p_frame); + *got_frame = 1; + ctx->got_p_frame = 0; + } else { + *got_frame = 0; + } + return buf_size; + } + if (ctx->gop_flags & IVI5_IS_PROTECTED) { avpriv_report_missing_feature(avctx, "Password-protected clip!\n"); return AVERROR_PATCHWELCOME; @@ -1005,19 +1017,6 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, //STOP_TIMER("decode_planes"); } - /* If the bidirectional mode is enabled, next I and the following P - * frame will be sent together. Unfortunately the approach below seems - * to be the only way to handle the B-frames mode. - * That's exactly the same Intel decoders do. - */ - if (avctx->codec_id == AV_CODEC_ID_INDEO4 && - ctx->frame_type == IVI4_FRAMETYPE_INTRA) { - while (get_bits(&ctx->gb, 8)); // skip version string - skip_bits_long(&ctx->gb, 64); // skip padding, TODO: implement correct 8-bytes alignment - if (get_bits_left(&ctx->gb) > 18 && show_bits(&ctx->gb, 18) == 0x3FFF8) - av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n"); - } - result = ff_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height); if (result < 0) return result; @@ -1041,6 +1040,27 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, *got_frame = 1; + /* If the bidirectional mode is enabled, next I and the following P + * frame will be sent together. Unfortunately the approach below seems + * to be the only way to handle the B-frames mode. + * That's exactly the same Intel decoders do. + */ + if (avctx->codec_id == AV_CODEC_ID_INDEO4 && + ctx->frame_type == IVI4_FRAMETYPE_INTRA) { + int left; + + while (get_bits(&ctx->gb, 8)); // skip version string + left = get_bits_count(&ctx->gb) & 0x18; + skip_bits_long(&ctx->gb, 64 - left); + if (get_bits_left(&ctx->gb) > 18 && + show_bits_long(&ctx->gb, 21) == 0xBFFF8) { // syncheader + inter type + AVPacket pkt; + pkt.data = avpkt->data + (get_bits_count(&ctx->gb) >> 3); + pkt.size = get_bits_left(&ctx->gb) >> 3; + ff_ivi_decode_frame(avctx, ctx->p_frame, &ctx->got_p_frame, &pkt); + } + } + return buf_size; } @@ -1073,6 +1093,8 @@ av_cold int ff_ivi_decode_close(AVCodecContext *avctx) } #endif + av_frame_free(&ctx->p_frame); + return 0; } diff --git a/libavcodec/ivi_common.h b/libavcodec/ivi_common.h index 584bf07..604b549 100644 --- a/libavcodec/ivi_common.h +++ b/libavcodec/ivi_common.h @@ -260,6 +260,9 @@ typedef struct IVI45DecContext { int (*is_nonnull_frame)(struct IVI45DecContext *ctx); int gop_invalid; + + AVFrame *p_frame; + int got_p_frame; } IVI45DecContext; /** compare some properties of two pictures */ -- 1.7.0.4
_______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
