]> git.sesse.net Git - nageru/blobdiff - image_input.cpp
Remove the last use of the AVStream::codec parameter.
[nageru] / image_input.cpp
index 121fa7bf3c6872c04e8b72e332e01486d5704aed..c9f74f8847c4b5f297c512de57c6d9eed1f7201f 100644 (file)
@@ -136,6 +136,11 @@ av_frame_alloc_unique()
                frame, av_frame_free_unique);
 }
 
+void avcodec_free_context_unique(AVCodecContext *codec_ctx)
+{
+       avcodec_free_context(&codec_ctx);
+}
+
 }  // namespace
 
 shared_ptr<const ImageInput::Image> ImageInput::load_image_raw(const string &pathname)
@@ -173,8 +178,15 @@ shared_ptr<const ImageInput::Image> ImageInput::load_image_raw(const string &pat
                return nullptr;
        }
 
-       AVCodecContext *codec_ctx = format_ctx->streams[stream_index]->codec;
-       AVCodec *codec = avcodec_find_decoder(codec_ctx->codec_id);
+       const AVCodecParameters *codecpar = format_ctx->streams[stream_index]->codecpar;
+       AVCodecContext *codec_ctx = avcodec_alloc_context3(nullptr);
+       unique_ptr<AVCodecContext, decltype(avcodec_free_context_unique)*> codec_ctx_free(
+               codec_ctx, avcodec_free_context_unique);
+       if (avcodec_parameters_to_context(codec_ctx, codecpar) < 0) {
+               fprintf(stderr, "%s: Cannot fill codec parameters\n", pathname.c_str());
+               return nullptr;
+       }
+       AVCodec *codec = avcodec_find_decoder(codecpar->codec_id);
        if (codec == nullptr) {
                fprintf(stderr, "%s: Cannot find decoder\n", pathname.c_str());
                return nullptr;
@@ -189,6 +201,7 @@ shared_ptr<const ImageInput::Image> ImageInput::load_image_raw(const string &pat
        // Read packets until we have a frame or there are none left.
        int frame_finished = 0;
        auto frame = av_frame_alloc_unique();
+       bool eof = false;
        do {
                AVPacket pkt;
                unique_ptr<AVPacket, decltype(av_packet_unref)*> pkt_cleanup(
@@ -196,29 +209,28 @@ shared_ptr<const ImageInput::Image> ImageInput::load_image_raw(const string &pat
                av_init_packet(&pkt);
                pkt.data = nullptr;
                pkt.size = 0;
-               if (av_read_frame(format_ctx.get(), &pkt) < 0) {
-                       break;
-               }
-               if (pkt.stream_index != stream_index) {
-                       continue;
+               if (av_read_frame(format_ctx.get(), &pkt) == 0) {
+                       if (pkt.stream_index != stream_index) {
+                               continue;
+                       }
+                       if (avcodec_send_packet(codec_ctx, &pkt) < 0) {
+                               fprintf(stderr, "%s: Cannot send packet to codec.\n", pathname.c_str());
+                               return nullptr;
+                       }
+               } else {
+                       eof = true;  // Or error, but ignore that for the time being.
                }
 
-               if (avcodec_decode_video2(codec_ctx, frame.get(), &frame_finished, &pkt) < 0) {
-                       fprintf(stderr, "%s: Cannot decode frame\n", pathname.c_str());
+               int err = avcodec_receive_frame(codec_ctx, frame.get());
+               if (err == 0) {
+                       frame_finished = true;
+                       break;
+               } else if (err != AVERROR(EAGAIN)) {
+                       fprintf(stderr, "%s: Cannot receive frame from codec.\n", pathname.c_str());
                        return nullptr;
                }
-       } while (!frame_finished);
+       } while (!eof);
 
-       // See if there's a cached frame for us.
-       if (!frame_finished) {
-               AVPacket pkt;
-               pkt.data = nullptr;
-               pkt.size = 0;
-               if (avcodec_decode_video2(codec_ctx, frame.get(), &frame_finished, &pkt) < 0) {
-                       fprintf(stderr, "%s: Cannot decode frame\n", pathname.c_str());
-                       return nullptr;
-               }
-       }
        if (!frame_finished) {
                fprintf(stderr, "%s: Decoder did not output frame.\n", pathname.c_str());
                return nullptr;