avcodec/indeo4: Decode both parts of IP frames
Fixes part of Ticket845 av_frame_move_ref() idea by Anton Khirnov Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
d24673a2c8
commit
8bfb4d72dd
@ -663,6 +663,10 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
|||||||
ctx->switch_buffers = switch_buffers;
|
ctx->switch_buffers = switch_buffers;
|
||||||
ctx->is_nonnull_frame = is_nonnull_frame;
|
ctx->is_nonnull_frame = is_nonnull_frame;
|
||||||
|
|
||||||
|
ctx->p_frame = av_frame_alloc();
|
||||||
|
if (!ctx->p_frame)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -997,6 +997,18 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
|
|||||||
if (ctx->gop_invalid)
|
if (ctx->gop_invalid)
|
||||||
return AVERROR_INVALIDDATA;
|
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) {
|
if (ctx->gop_flags & IVI5_IS_PROTECTED) {
|
||||||
avpriv_report_missing_feature(avctx, "Password-protected clip!\n");
|
avpriv_report_missing_feature(avctx, "Password-protected clip!\n");
|
||||||
return AVERROR_PATCHWELCOME;
|
return AVERROR_PATCHWELCOME;
|
||||||
@ -1038,24 +1050,6 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
|
|||||||
|
|
||||||
//STOP_TIMER("decode_planes"); }
|
//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) {
|
|
||||||
// skip version string
|
|
||||||
while (get_bits(&ctx->gb, 8)) {
|
|
||||||
if (get_bits_left(&ctx->gb) < 8)
|
|
||||||
return AVERROR_INVALIDDATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ctx->is_nonnull_frame(ctx))
|
if (!ctx->is_nonnull_frame(ctx))
|
||||||
return buf_size;
|
return buf_size;
|
||||||
|
|
||||||
@ -1080,6 +1074,31 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
|
|||||||
|
|
||||||
*got_frame = 1;
|
*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;
|
||||||
|
|
||||||
|
// skip version string
|
||||||
|
while (get_bits(&ctx->gb, 8)) {
|
||||||
|
if (get_bits_left(&ctx->gb) < 8)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
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;
|
return buf_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1112,6 +1131,8 @@ av_cold int ff_ivi_decode_close(AVCodecContext *avctx)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
av_frame_free(&ctx->p_frame);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,6 +262,9 @@ typedef struct IVI45DecContext {
|
|||||||
|
|
||||||
int gop_invalid;
|
int gop_invalid;
|
||||||
int buf_invalid[3];
|
int buf_invalid[3];
|
||||||
|
|
||||||
|
AVFrame *p_frame;
|
||||||
|
int got_p_frame;
|
||||||
} IVI45DecContext;
|
} IVI45DecContext;
|
||||||
|
|
||||||
/** compare some properties of two pictures */
|
/** compare some properties of two pictures */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user