]> git.sesse.net Git - nageru/blobdiff - nageru/ffmpeg_capture.cpp
Some random #include fixing.
[nageru] / nageru / ffmpeg_capture.cpp
index 9af4e833f76340bfa3b92717f78e3763fad02776..1a9a295cd28d988233821294116ebf9ff2f50abf 100644 (file)
@@ -36,7 +36,6 @@ extern "C" {
 #include "shared/ffmpeg_raii.h"
 #include "ffmpeg_util.h"
 #include "flags.h"
-#include "image_input.h"
 #include "ref_counted_frame.h"
 #include "shared/timebase.h"
 
@@ -50,6 +49,11 @@ using namespace bmusb;
 using namespace movit;
 using namespace Eigen;
 
+// Avoid deprecation warnings, but we don't want to drop FFmpeg 5.1 support just yet.
+#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 30, 100)
+#define pkt_duration duration
+#endif
+
 namespace {
 
 steady_clock::time_point compute_frame_start(int64_t frame_pts, int64_t pts_origin, const AVRational &video_timebase, const steady_clock::time_point &origin, double rate)
@@ -901,34 +905,31 @@ AVFrameWithDeleter FFmpegCapture::decode_frame(AVFormatContext *format_ctx, AVCo
        *audio_pts = -1;
        bool has_audio = false;
        do {
-               AVPacket pkt;
-               unique_ptr<AVPacket, decltype(av_packet_unref)*> pkt_cleanup(
-                       &pkt, av_packet_unref);
-               av_init_packet(&pkt);
-               pkt.data = nullptr;
-               pkt.size = 0;
-               if (av_read_frame(format_ctx, &pkt) == 0) {
-                       if (pkt.stream_index == audio_stream_index && audio_callback != nullptr) {
-                               audio_callback(&pkt, format_ctx->streams[audio_stream_index]->time_base);
+               AVPacketWithDeleter pkt = av_packet_alloc_unique();
+               pkt->data = nullptr;
+               pkt->size = 0;
+               if (av_read_frame(format_ctx, pkt.get()) == 0) {
+                       if (pkt->stream_index == audio_stream_index && audio_callback != nullptr) {
+                               audio_callback(pkt.get(), format_ctx->streams[audio_stream_index]->time_base);
                        }
-                       if (pkt.stream_index == video_stream_index && video_callback != nullptr) {
-                               video_callback(&pkt, format_ctx->streams[video_stream_index]->time_base);
+                       if (pkt->stream_index == video_stream_index && video_callback != nullptr) {
+                               video_callback(pkt.get(), format_ctx->streams[video_stream_index]->time_base);
                        }
-                       if (pkt.stream_index == video_stream_index && global_flags.transcode_video) {
-                               if (avcodec_send_packet(video_codec_ctx, &pkt) < 0) {
+                       if (pkt->stream_index == video_stream_index && global_flags.transcode_video) {
+                               if (avcodec_send_packet(video_codec_ctx, pkt.get()) < 0) {
                                        fprintf(stderr, "%s: Cannot send packet to video codec.\n", pathname.c_str());
                                        *error = true;
                                        return AVFrameWithDeleter(nullptr);
                                }
-                       } else if (pkt.stream_index == audio_stream_index && global_flags.transcode_audio) {
+                       } else if (pkt->stream_index == audio_stream_index && global_flags.transcode_audio) {
                                has_audio = true;
-                               if (avcodec_send_packet(audio_codec_ctx, &pkt) < 0) {
+                               if (avcodec_send_packet(audio_codec_ctx, pkt.get()) < 0) {
                                        fprintf(stderr, "%s: Cannot send packet to audio codec.\n", pathname.c_str());
                                        *error = true;
                                        return AVFrameWithDeleter(nullptr);
                                }
-                       } else if (pkt.stream_index == subtitle_stream_index) {
-                               last_subtitle = string(reinterpret_cast<const char *>(pkt.data), pkt.size);
+                       } else if (pkt->stream_index == subtitle_stream_index) {
+                               last_subtitle = string(reinterpret_cast<const char *>(pkt->data), pkt->size);
                                has_last_subtitle = true;
                        }
                } else {
@@ -1018,28 +1019,36 @@ void FFmpegCapture::convert_audio(const AVFrame *audio_avframe, FrameAllocator::
        }
        audio_format->num_channels = 2;
 
-       int64_t channel_layout = audio_avframe->channel_layout;
-       if (channel_layout == 0) {
-               channel_layout = av_get_default_channel_layout(audio_avframe->channels);
+       AVChannelLayout channel_layout = audio_avframe->ch_layout;
+       if (!av_channel_layout_check(&channel_layout) ||
+           channel_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
+               av_channel_layout_default(&channel_layout, audio_avframe->ch_layout.nb_channels);
        }
 
        if (resampler == nullptr ||
            audio_avframe->format != last_src_format ||
            dst_format != last_dst_format ||
-           channel_layout != last_channel_layout ||
+           av_channel_layout_compare(&channel_layout, &last_channel_layout) !=  0||
            audio_avframe->sample_rate != last_sample_rate) {
+               // TODO: When we get C++20, use AV_CHANNEL_LAYOUT_STEREO_DOWNMIX.
+               AVChannelLayout stereo_downmix;
+               stereo_downmix.order = AV_CHANNEL_ORDER_NATIVE;
+               stereo_downmix.nb_channels = 2;
+               stereo_downmix.u.mask = AV_CH_LAYOUT_STEREO_DOWNMIX;
+
                swr_free(&resampler);
-               resampler = swr_alloc_set_opts(nullptr,
-                                              /*out_ch_layout=*/AV_CH_LAYOUT_STEREO_DOWNMIX,
-                                              /*out_sample_fmt=*/dst_format,
-                                              /*out_sample_rate=*/OUTPUT_FREQUENCY,
-                                              /*in_ch_layout=*/channel_layout,
-                                              /*in_sample_fmt=*/AVSampleFormat(audio_avframe->format),
-                                              /*in_sample_rate=*/audio_avframe->sample_rate,
-                                              /*log_offset=*/0,
-                                              /*log_ctx=*/nullptr);
-
-               if (resampler == nullptr) {
+               resampler = nullptr;
+               int err = swr_alloc_set_opts2(&resampler,
+                                             /*out_ch_layout=*/&stereo_downmix,
+                                             /*out_sample_fmt=*/dst_format,
+                                             /*out_sample_rate=*/OUTPUT_FREQUENCY,
+                                             /*in_ch_layout=*/&channel_layout,
+                                             /*in_sample_fmt=*/AVSampleFormat(audio_avframe->format),
+                                             /*in_sample_rate=*/audio_avframe->sample_rate,
+                                             /*log_offset=*/0,
+                                             /*log_ctx=*/nullptr);
+
+               if (err != 0 || resampler == nullptr) {
                        fprintf(stderr, "Allocating resampler failed.\n");
                        abort();
                }