Remove FFmpeg::_packet.
authorCarl Hetherington <cth@carlh.net>
Mon, 1 Mar 2021 20:06:01 +0000 (21:06 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 2 Mar 2021 14:40:18 +0000 (15:40 +0100)
src/lib/examine_ffmpeg_subtitles_job.cc
src/lib/ffmpeg.h
src/lib/ffmpeg_decoder.cc
src/lib/ffmpeg_decoder.h
src/lib/ffmpeg_examiner.cc
src/lib/ffmpeg_examiner.h

index 90589eb2843c8794fc2b4c46daca4b53b41f234a..8c762d893bb311e9c47a6545d7fa60ee1820dcd7 100644 (file)
@@ -65,8 +65,11 @@ ExamineFFmpegSubtitlesJob::run ()
 {
        int64_t const len = _file_group.length ();
        while (true) {
-               int r = av_read_frame (_format_context, &_packet);
+               auto packet = av_packet_alloc ();
+               DCPOMATIC_ASSERT (packet);
+               int r = av_read_frame (_format_context, packet);
                if (r < 0) {
+                       av_packet_free (&packet);
                        break;
                }
 
@@ -76,10 +79,10 @@ ExamineFFmpegSubtitlesJob::run ()
                        set_progress_unknown ();
                }
 
-               if (_content->subtitle_stream() && _content->subtitle_stream()->uses_index(_format_context, _packet.stream_index) && _content->only_text()->use()) {
+               if (_content->subtitle_stream() && _content->subtitle_stream()->uses_index(_format_context, packet->stream_index) && _content->only_text()->use()) {
                        int got_subtitle;
                        AVSubtitle sub;
-                       if (avcodec_decode_subtitle2(subtitle_codec_context(), &sub, &got_subtitle, &_packet) >= 0 && got_subtitle) {
+                       if (avcodec_decode_subtitle2(subtitle_codec_context(), &sub, &got_subtitle, packet) >= 0 && got_subtitle) {
                                for (unsigned int i = 0; i < sub.num_rects; ++i) {
                                        AVSubtitleRect const * rect = sub.rects[i];
                                        if (rect->type == SUBTITLE_BITMAP) {
@@ -104,7 +107,7 @@ ExamineFFmpegSubtitlesJob::run ()
                        }
                }
 
-               av_packet_unref (&_packet);
+               av_packet_free (&packet);
        }
 
        set_progress (1);
index a9823007bd290928841ac05b0f868cd029976ae2..fac8a2d840b3960e8290e6ddec8448dd318e1721 100644 (file)
@@ -69,7 +69,6 @@ protected:
        FileGroup _file_group;
 
        AVFormatContext* _format_context;
-       AVPacket _packet;
        AVFrame* _frame;
 
        /** Index of video stream within AVFormatContext */
index b2bb1a46649b1594265a2e515fff96fe6a62e7c9..c91a2f2e75752c37327a1c1aabad420be0096cab 100644 (file)
@@ -110,15 +110,15 @@ FFmpegDecoder::flush ()
 {
        /* Get any remaining frames */
 
-       _packet.data = 0;
-       _packet.size = 0;
-
-       /* XXX: should we reset _packet.data and size after each *_decode_* call? */
-
-       while (video && decode_video_packet()) {}
+       AVPacket packet;
+       packet.data = nullptr;
+       packet.size = 0;
+       while (video && decode_video_packet(&packet)) {}
 
        if (audio) {
-               decode_audio_packet ();
+               packet.data = nullptr;
+               packet.size = 0;
+               decode_audio_packet (&packet);
        }
 
        /* Make sure all streams are the same length and round up to the next video frame */
@@ -162,7 +162,10 @@ FFmpegDecoder::flush ()
 bool
 FFmpegDecoder::pass ()
 {
-       int r = av_read_frame (_format_context, &_packet);
+       auto packet = av_packet_alloc();
+       DCPOMATIC_ASSERT (packet);
+
+       int r = av_read_frame (_format_context, packet);
 
        /* AVERROR_INVALIDDATA can apparently be returned sometimes even when av_read_frame
           has pretty-much succeeded (and hence generated data which should be processed).
@@ -176,22 +179,23 @@ FFmpegDecoder::pass ()
                        LOG_ERROR (N_("error on av_read_frame (%1) (%2)"), &buf[0], r);
                }
 
+               av_packet_free (&packet);
                flush ();
                return true;
        }
 
-       int const si = _packet.stream_index;
+       int const si = packet->stream_index;
        auto fc = _ffmpeg_content;
 
        if (_video_stream && si == _video_stream.get() && video && !video->ignore()) {
-               decode_video_packet ();
+               decode_video_packet (packet);
        } else if (fc->subtitle_stream() && fc->subtitle_stream()->uses_index(_format_context, si) && !only_text()->ignore()) {
-               decode_subtitle_packet ();
+               decode_subtitle_packet (packet);
        } else {
-               decode_audio_packet ();
+               decode_audio_packet (packet);
        }
 
-       av_packet_unref (&_packet);
+       av_packet_free (&packet);
        return false;
 }
 
@@ -494,20 +498,19 @@ FFmpegDecoder::process_audio_frame (shared_ptr<FFmpegAudioStream> stream, int st
 
 
 void
-FFmpegDecoder::decode_audio_packet ()
+FFmpegDecoder::decode_audio_packet (AVPacket* packet)
 {
-       /* Audio packets can contain multiple frames, so we may have to call avcodec_decode_audio4
-          several times.
-       */
-
-       AVPacket copy_packet = _packet;
-       int const stream_index = copy_packet.stream_index;
-
+       int const stream_index = packet->stream_index;
        auto stream = audio_stream_from_index (stream_index);
        if (!stream) {
                return;
        }
 
+       /* Audio packets can contain multiple frames, so we may have to call avcodec_decode_audio4
+          several times.  Make a simple copy so we can alter data and size.
+       */
+       AVPacket copy_packet = *packet;
+
        while (copy_packet.size > 0) {
                int frame_finished;
                DCPOMATIC_DISABLE_WARNINGS
@@ -540,13 +543,13 @@ FFmpegDecoder::decode_audio_packet ()
 
 
 bool
-FFmpegDecoder::decode_video_packet ()
+FFmpegDecoder::decode_video_packet (AVPacket* packet)
 {
        DCPOMATIC_ASSERT (_video_stream);
 
        int frame_finished;
 DCPOMATIC_DISABLE_WARNINGS
-       if (avcodec_decode_video2 (video_codec_context(), _frame, &frame_finished, &_packet) < 0 || !frame_finished) {
+       if (avcodec_decode_video2 (video_codec_context(), _frame, &frame_finished, packet) < 0 || !frame_finished) {
                return false;
        }
 DCPOMATIC_ENABLE_WARNINGS
@@ -594,11 +597,11 @@ DCPOMATIC_ENABLE_WARNINGS
 
 
 void
-FFmpegDecoder::decode_subtitle_packet ()
+FFmpegDecoder::decode_subtitle_packet (AVPacket* packet)
 {
        int got_subtitle;
        AVSubtitle sub;
-       if (avcodec_decode_subtitle2 (subtitle_codec_context(), &sub, &got_subtitle, &_packet) < 0 || !got_subtitle) {
+       if (avcodec_decode_subtitle2 (subtitle_codec_context(), &sub, &got_subtitle, packet) < 0 || !got_subtitle) {
                return;
        }
 
index 7a1fa40d249bff6d96746d08e6f2811f2f5517e8..58120da33cf3433f36cc79e04658f7589c30c6da 100644 (file)
@@ -60,9 +60,9 @@ private:
        std::shared_ptr<FFmpegAudioStream> audio_stream_from_index (int index) const;
        void process_audio_frame (std::shared_ptr<FFmpegAudioStream> stream, int stream_index, int64_t packet_pts);
 
-       bool decode_video_packet ();
-       void decode_audio_packet ();
-       void decode_subtitle_packet ();
+       bool decode_video_packet (AVPacket* packet);
+       void decode_audio_packet (AVPacket* packet);
+       void decode_subtitle_packet (AVPacket* packet);
 
        void decode_bitmap_subtitle (AVSubtitleRect const * rect, dcpomatic::ContentTime from);
        void decode_ass_subtitle (std::string ass, dcpomatic::ContentTime from);
index b07ee5d623d5421c151b6c9a5e01ad0b5c4082d0..a3e78b65ff4c1e9c07c6aa5ceca8dcf04514927d 100644 (file)
@@ -124,8 +124,11 @@ DCPOMATIC_DISABLE_WARNINGS
         */
        string temporal_reference;
        while (true) {
-               int r = av_read_frame (_format_context, &_packet);
+               auto packet = av_packet_alloc ();
+               DCPOMATIC_ASSERT (packet);
+               int r = av_read_frame (_format_context, packet);
                if (r < 0) {
+                       av_packet_free (&packet);
                        break;
                }
 
@@ -137,25 +140,25 @@ DCPOMATIC_DISABLE_WARNINGS
                        }
                }
 
-               auto context = _format_context->streams[_packet.stream_index]->codec;
+               auto context = _format_context->streams[packet->stream_index]->codec;
 DCPOMATIC_ENABLE_WARNINGS
 
-               if (_video_stream && _packet.stream_index == _video_stream.get()) {
-                       video_packet (context, temporal_reference);
+               if (_video_stream && packet->stream_index == _video_stream.get()) {
+                       video_packet (context, temporal_reference, packet);
                }
 
                bool got_all_audio = true;
 
                for (size_t i = 0; i < _audio_streams.size(); ++i) {
-                       if (_audio_streams[i]->uses_index (_format_context, _packet.stream_index)) {
-                               audio_packet (context, _audio_streams[i]);
+                       if (_audio_streams[i]->uses_index(_format_context, packet->stream_index)) {
+                               audio_packet (context, _audio_streams[i], packet);
                        }
                        if (!_audio_streams[i]->first_audio) {
                                got_all_audio = false;
                        }
                }
 
-               av_packet_unref (&_packet);
+               av_packet_free (&packet);
 
                if (_first_video && got_all_audio && temporal_reference.size() >= (PULLDOWN_CHECK_FRAMES * 2)) {
                        /* All done */
@@ -163,23 +166,24 @@ DCPOMATIC_ENABLE_WARNINGS
                }
        }
 
-       _packet.data = nullptr;
-       _packet.size = 0;
+       AVPacket packet;
+       packet.data = nullptr;
+       packet.size = 0;
        /* XXX: I'm not sure this makes any sense: how does _packet.stream_index get the right value here? */
 DCPOMATIC_DISABLE_WARNINGS
-       auto context = _format_context->streams[_packet.stream_index]->codec;
+       auto context = _format_context->streams[packet.stream_index]->codec;
 DCPOMATIC_ENABLE_WARNINGS
-       while (_video_stream && video_packet(context, temporal_reference)) {}
+       while (_video_stream && video_packet(context, temporal_reference, &packet)) {}
        for (size_t i = 0; i < _audio_streams.size(); ++i) {
-               if (_audio_streams[i]->uses_index (_format_context, _packet.stream_index)) {
-                       audio_packet (context, _audio_streams[i]);
+               if (_audio_streams[i]->uses_index(_format_context, packet.stream_index)) {
+                       audio_packet (context, _audio_streams[i], &packet);
                }
        }
 
        if (_video_stream) {
                /* This code taken from get_rotation() in ffmpeg:cmdutils.c */
-               AVStream* stream = _format_context->streams[*_video_stream];
-               AVDictionaryEntry* rotate_tag = av_dict_get (stream->metadata, "rotate", 0, 0);
+               auto stream = _format_context->streams[*_video_stream];
+               auto rotate_tag = av_dict_get (stream->metadata, "rotate", 0, 0);
                uint8_t* displaymatrix = av_stream_get_side_data (stream, AV_PKT_DATA_DISPLAYMATRIX, 0);
                _rotation = 0;
 
@@ -213,7 +217,7 @@ DCPOMATIC_ENABLE_WARNINGS
  *  @return true if some video was decoded, otherwise false.
  */
 bool
-FFmpegExaminer::video_packet (AVCodecContext* context, string& temporal_reference)
+FFmpegExaminer::video_packet (AVCodecContext* context, string& temporal_reference, AVPacket* packet)
 {
        DCPOMATIC_ASSERT (_video_stream);
 
@@ -223,7 +227,7 @@ FFmpegExaminer::video_packet (AVCodecContext* context, string& temporal_referenc
 
        int frame_finished;
 DCPOMATIC_DISABLE_WARNINGS
-       if (avcodec_decode_video2 (context, _frame, &frame_finished, &_packet) < 0 || !frame_finished) {
+       if (avcodec_decode_video2 (context, _frame, &frame_finished, packet) < 0 || !frame_finished) {
                return false;
        }
 DCPOMATIC_ENABLE_WARNINGS
@@ -246,7 +250,7 @@ DCPOMATIC_ENABLE_WARNINGS
 
 
 void
-FFmpegExaminer::audio_packet (AVCodecContext* context, shared_ptr<FFmpegAudioStream> stream)
+FFmpegExaminer::audio_packet (AVCodecContext* context, shared_ptr<FFmpegAudioStream> stream, AVPacket* packet)
 {
        if (stream->first_audio) {
                return;
@@ -254,7 +258,7 @@ FFmpegExaminer::audio_packet (AVCodecContext* context, shared_ptr<FFmpegAudioStr
 
        int frame_finished;
 DCPOMATIC_DISABLE_WARNINGS
-       if (avcodec_decode_audio4 (context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
+       if (avcodec_decode_audio4 (context, _frame, &frame_finished, packet) >= 0 && frame_finished) {
 DCPOMATIC_ENABLE_WARNINGS
                stream->first_audio = frame_time (stream->stream (_format_context));
        }
index 41f517724c1d626e631c16b05517b5aa313309cc..0884a6fb82df8548e21ece95c29de5093f9d8f10 100644 (file)
@@ -82,8 +82,8 @@ public:
        }
 
 private:
-       bool video_packet (AVCodecContext *, std::string& temporal_reference);
-       void audio_packet (AVCodecContext *, std::shared_ptr<FFmpegAudioStream>);
+       bool video_packet (AVCodecContext* context, std::string& temporal_reference, AVPacket* packet);
+       void audio_packet (AVCodecContext* context, std::shared_ptr<FFmpegAudioStream>, AVPacket* packet);
 
        std::string stream_name (AVStream* s) const;
        std::string subtitle_stream_name (AVStream* s) const;