#include // ffmpeg extern "C" { #include #include #include #include #include #include #include #include } int main(int argc, char** argv) { av_register_all(); int retcode = 0; int ret; // av context AVFormatContext* fmt_ctx = NULL; AVCodecContext* video_dec_ctx = NULL; int video_stream_idx = -1; AVCodec* video_dec = NULL; // av frame AVFrame* frame = NULL; int got_frame = 0; // open ret = avformat_open_input(&fmt_ctx, "a.gif", NULL, NULL); if (ret < 0) { retcode = -10; goto OUT; } // retrieve stream info ret = avformat_find_stream_info(fmt_ctx, NULL); if (ret < 0) { retcode = -11; goto OUT; } // find video stream video_stream_idx = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); if (video_stream_idx < 0) { retcode = -12; goto OUT; } // rotate info video_dec_ctx = fmt_ctx->streams[video_stream_idx]->codec; // find video decoder video_dec = avcodec_find_decoder(video_dec_ctx->codec_id); if (!video_dec) { retcode = -13; goto OUT; } // open video decoder ret = avcodec_open2(video_dec_ctx, video_dec, NULL); if (ret < 0) { retcode = -14; goto OUT; } // allocate av frame frame = av_frame_alloc(); if (!frame) { retcode = -100; goto OUT; } // initialize packet, set data to NULL, let the demuxer fill it AVPacket packet; AVPacket avpacket; av_init_packet(&packet); packet.data = NULL; packet.size = 0; // read frames while (av_read_frame(fmt_ctx, &packet) >= 0) { got_frame = 0; if (packet.stream_index != video_stream_idx) { continue; } avpacket = packet; while (avpacket.size > 0) { int earlyReturn = 0; if (packet.stream_index == video_stream_idx) { // decode frame ret = avcodec_decode_video2(video_dec_ctx, frame, &got_frame, &avpacket); printf("avpacket.size = %d avcodec_decode_video2 returns %d\n", avpacket.size, ret); if (ret < 0) { av_free_packet(&packet); retcode = -15; goto OUT; } } int nused = ret; if (!got_frame) { avpacket.data += nused; avpacket.size -= nused; continue; } avpacket.data += nused; avpacket.size -= nused; } av_free_packet(&packet); } // flush cached frames packet.data = NULL; packet.size = 0; while (got_frame) { got_frame = 0; if (packet.stream_index == video_stream_idx) { // decode frame ret = avcodec_decode_video2(video_dec_ctx, frame, &got_frame, &packet); printf("avpacket.size = %d avcodec_decode_video2 returns %d (cached)\n", avpacket.size, ret); if (ret < 0) { av_free_packet(&packet); retcode = -15; goto OUT; } } if (!got_frame) { break; } } OUT: if (frame) av_frame_free(&frame); if (video_dec_ctx) avcodec_close(video_dec_ctx); if (fmt_ctx) avformat_close_input(&fmt_ctx); return retcode; }