|
|
|
@ -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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|