int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { IVI45DecContext *ctx = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; int result, p, b; init_get_bits(&ctx->gb, buf, buf_size * 8); ctx->frame_data = buf; ctx->frame_size = buf_size; result = ctx->decode_pic_hdr(ctx, avctx); if (result) { av_log(avctx, AV_LOG_ERROR, "Error while decoding picture header: %d\n", result); return -1; } if (ctx->gop_invalid) return AVERROR_INVALIDDATA; if (ctx->gop_flags & IVI5_IS_PROTECTED) { av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n"); return -1; } ctx->switch_buffers(ctx); //{ START_TIMER; if (ctx->is_nonnull_frame(ctx)) { for (p = 0; p < 3; p++) { for (b = 0; b < ctx->planes[p].num_bands; b++) { result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx); if (result) { av_log(avctx, AV_LOG_ERROR, "Error while decoding band: %d, plane: %d\n", b, p); return -1; } } } } //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 == 0/*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"); } if (ctx->frame.data[0]) avctx->release_buffer(avctx, &ctx->frame); ctx->frame.reference = 0; if ((result = avctx->get_buffer(avctx, &ctx->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return result; } if (ctx->is_scalable) { if (avctx->codec_id == AV_CODEC_ID_INDEO4) ff_ivi_recompose_haar(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4); else ff_ivi_recompose53 (&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4); } else { ff_ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]); } ff_ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]); ff_ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]); *data_size = sizeof(AVFrame); *(AVFrame*)data = ctx->frame; return buf_size; }