Skip to content

Commit c7999b7

Browse files
committed
fix: support building against ffmpeg 7.0
1 parent 7eb501f commit c7999b7

File tree

10 files changed

+127
-25
lines changed

10 files changed

+127
-25
lines changed

src/modules/bluefish/producer/bluefish_producer.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ struct bluefish_producer
451451
src_video->interlaced_frame = !is_progressive;
452452
src_video->top_field_first = height != 486;
453453
src_video->key_frame = 1;
454-
src_video->display_picture_number = frames_captured;
454+
//src_video->display_picture_number = frames_captured;
455455
src_video->pts = capture_ts;
456456

457457
void* video_bytes = reserved_frames_.front()->image_data();
@@ -461,8 +461,12 @@ struct bluefish_producer
461461
}
462462

463463
// Audio
464-
src_audio->format = AV_SAMPLE_FMT_S32;
465-
src_audio->channels = format_desc_.audio_channels;
464+
src_audio->format = AV_SAMPLE_FMT_S32;
465+
#if FFMPEG_NEW_CHANNEL_LAYOUT
466+
av_channel_layout_default(&src_audio->ch_layout, format_desc_.audio_channels);
467+
#else
468+
src_audio->channels = format_desc_.audio_channels;
469+
#endif
466470
src_audio->sample_rate = format_desc_.audio_sample_rate;
467471
src_audio->nb_samples = 0;
468472
int samples_decoded = 0;
@@ -480,15 +484,15 @@ struct bluefish_producer
480484
card_type,
481485
reinterpret_cast<unsigned int*>(hanc_buffer),
482486
reinterpret_cast<unsigned int*>(&decoded_audio_bytes_[0]),
483-
src_audio->channels);
487+
format_desc_.audio_channels);
484488

485489
audio_bytes = reinterpret_cast<int32_t*>(&decoded_audio_bytes_[0]);
486490

487-
samples_decoded = no_extracted_pcm_samples / src_audio->channels;
491+
samples_decoded = no_extracted_pcm_samples / format_desc_.audio_channels;
488492
src_audio->nb_samples = samples_decoded;
489493
src_audio->data[0] = reinterpret_cast<uint8_t*>(audio_bytes);
490494
src_audio->linesize[0] =
491-
src_audio->nb_samples * src_audio->channels *
495+
src_audio->nb_samples * format_desc_.audio_channels *
492496
av_get_bytes_per_sample(static_cast<AVSampleFormat>(src_audio->format));
493497
src_audio->pts = capture_ts;
494498
}
@@ -504,7 +508,7 @@ struct bluefish_producer
504508
auto audio_bytes = reinterpret_cast<uint8_t*>(&decoded_audio_bytes_[0]);
505509
if (audio_bytes) {
506510
src_audio->nb_samples = remainaing_audio_samples_;
507-
int bytes_left = remainaing_audio_samples_ * 4 * src_audio->channels;
511+
int bytes_left = remainaing_audio_samples_ * 4 * format_desc_.audio_channels;
508512
src_audio->data[0] = audio_bytes + bytes_left;
509513
src_audio->linesize[0] = bytes_left;
510514
remainaing_audio_samples_ = 0;

src/modules/decklink/producer/decklink_producer.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ struct Filter
204204

205205
auto args = (boost::format("time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=%#x") % 1 %
206206
format_desc.audio_sample_rate % format_desc.audio_sample_rate % AV_SAMPLE_FMT_S32 %
207-
av_get_default_channel_layout(format_desc.audio_channels))
207+
ffmpeg::get_channel_layout_mask_for_channels(format_desc.audio_channels))
208208
.str();
209209
auto name = (boost::format("in_%d") % 0).str();
210210

@@ -237,12 +237,23 @@ struct Filter
237237
#pragma warning(push)
238238
#pragma warning(disable : 4245)
239239
#endif
240+
240241
AVSampleFormat sample_fmts[] = {AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE};
241-
int64_t channel_layouts[] = {av_get_default_channel_layout(format_desc.audio_channels), 0};
242242
int sample_rates[] = {format_desc.audio_sample_rate, 0};
243243
FF(av_opt_set_int_list(sink, "sample_fmts", sample_fmts, -1, AV_OPT_SEARCH_CHILDREN));
244-
FF(av_opt_set_int_list(sink, "channel_layouts", channel_layouts, 0, AV_OPT_SEARCH_CHILDREN));
245244
FF(av_opt_set_int_list(sink, "sample_rates", sample_rates, 0, AV_OPT_SEARCH_CHILDREN));
245+
246+
#if FFMPEG_NEW_CHANNEL_LAYOUT
247+
AVChannelLayout channel_layout = AV_CHANNEL_LAYOUT_STEREO;
248+
av_channel_layout_default(&channel_layout, format_desc.audio_channels);
249+
250+
FF(av_opt_set_chlayout(sink, "ch_layouts", &channel_layout, AV_OPT_SEARCH_CHILDREN));
251+
av_channel_layout_uninit(&channel_layout);
252+
#else
253+
int64_t channel_layouts[] = {av_get_default_channel_layout(format_desc.audio_channels), 0};
254+
FF(av_opt_set_int_list(sink, "channel_layouts", channel_layouts, 0, AV_OPT_SEARCH_CHILDREN));
255+
#endif
256+
246257
#ifdef _MSC_VER
247258
#pragma warning(pop)
248259
#endif
@@ -585,7 +596,11 @@ class decklink_producer : public IDeckLinkInputCallback
585596
if (audio) {
586597
auto src = std::shared_ptr<AVFrame>(av_frame_alloc(), [](AVFrame* ptr) { av_frame_free(&ptr); });
587598
src->format = AV_SAMPLE_FMT_S32;
599+
#if FFMPEG_NEW_CHANNEL_LAYOUT
600+
av_channel_layout_default(&src->ch_layout, format_desc_.audio_channels);
601+
#else
588602
src->channels = format_desc_.audio_channels;
603+
#endif
589604
src->sample_rate = format_desc_.audio_sample_rate;
590605

591606
void* audio_bytes = nullptr;
@@ -594,7 +609,7 @@ class decklink_producer : public IDeckLinkInputCallback
594609
src = std::shared_ptr<AVFrame>(src.get(), [src, audio](AVFrame* ptr) { audio->Release(); });
595610
src->nb_samples = audio->GetSampleFrameCount();
596611
src->data[0] = reinterpret_cast<uint8_t*>(audio_bytes);
597-
src->linesize[0] = src->nb_samples * src->channels *
612+
src->linesize[0] = src->nb_samples * format_desc_.audio_channels *
598613
av_get_bytes_per_sample(static_cast<AVSampleFormat>(src->format));
599614

600615
if (SUCCEEDED(audio->GetPacketTime(&in_audio_pts, format_desc_.audio_sample_rate))) {

src/modules/ffmpeg/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ set(HEADERS
1818
producer/ffmpeg_producer.h
1919
consumer/ffmpeg_consumer.h
2020

21+
defines.h
2122
ffmpeg.h
2223
StdAfx.h
2324
)

src/modules/ffmpeg/consumer/ffmpeg_consumer.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ struct Stream
192192
} else if (codec->type == AVMEDIA_TYPE_AUDIO) {
193193
auto args = (boost::format("time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=%#x") % 1 %
194194
format_desc.audio_sample_rate % format_desc.audio_sample_rate % AV_SAMPLE_FMT_S32 %
195-
av_get_default_channel_layout(format_desc.audio_channels))
195+
get_channel_layout_mask_for_channels(format_desc.audio_channels))
196196
.str();
197197
auto name = (boost::format("in_%d") % 0).str();
198198

@@ -229,8 +229,15 @@ struct Stream
229229
#endif
230230
// TODO codec->profiles
231231
FF(av_opt_set_int_list(sink, "sample_fmts", codec->sample_fmts, -1, AV_OPT_SEARCH_CHILDREN));
232-
FF(av_opt_set_int_list(sink, "channel_layouts", codec->channel_layouts, 0, AV_OPT_SEARCH_CHILDREN));
233232
FF(av_opt_set_int_list(sink, "sample_rates", codec->supported_samplerates, 0, AV_OPT_SEARCH_CHILDREN));
233+
234+
#if FFMPEG_NEW_CHANNEL_LAYOUT
235+
// TODO: need to translate codec->ch_layouts into something that can be passed via av_opt_set_*
236+
// FF(av_opt_set_chlayout(sink, "ch_layouts", codec->ch_layouts, AV_OPT_SEARCH_CHILDREN));
237+
#else
238+
FF(av_opt_set_int_list(sink, "channel_layouts", codec->channel_layouts, 0, AV_OPT_SEARCH_CHILDREN));
239+
#endif
240+
234241
#ifdef _MSC_VER
235242
#pragma warning(pop)
236243
#endif
@@ -283,15 +290,21 @@ struct Stream
283290

284291
enc->sample_fmt = static_cast<AVSampleFormat>(av_buffersink_get_format(sink));
285292
enc->sample_rate = av_buffersink_get_sample_rate(sink);
293+
enc->time_base = st->time_base;
294+
295+
#if FFMPEG_NEW_CHANNEL_LAYOUT
296+
FF(av_buffersink_get_ch_layout(sink, &enc->ch_layout));
297+
#else
286298
enc->channels = av_buffersink_get_channels(sink);
287299
enc->channel_layout = av_buffersink_get_channel_layout(sink);
288-
enc->time_base = st->time_base;
289300

290301
if (!enc->channels) {
291302
enc->channels = av_get_channel_layout_nb_channels(enc->channel_layout);
292303
} else if (!enc->channel_layout) {
293304
enc->channel_layout = av_get_default_channel_layout(enc->channels);
294305
}
306+
#endif
307+
295308
} else {
296309
// TODO
297310
}

src/modules/ffmpeg/defines.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#pragma once
2+
3+
#include <libavcodec/version.h>
4+
5+
#define FFMPEG_NEW_CHANNEL_LAYOUT LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(60, 0, 0)

src/modules/ffmpeg/producer/av_producer.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,14 @@ class Decoder
127127
ctx->framerate = av_guess_frame_rate(nullptr, stream, nullptr);
128128
ctx->sample_aspect_ratio = av_guess_sample_aspect_ratio(nullptr, stream, nullptr);
129129
} else if (ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
130+
#if !(FFMPEG_NEW_CHANNEL_LAYOUT)
130131
if (!ctx->channel_layout && ctx->channels) {
131132
ctx->channel_layout = av_get_default_channel_layout(ctx->channels);
132133
}
133134
if (!ctx->channels && ctx->channel_layout) {
134135
ctx->channels = av_get_channel_layout_nb_channels(ctx->channel_layout);
135136
}
137+
#endif
136138
}
137139

138140
if (codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) {
@@ -178,7 +180,11 @@ class Decoder
178180
// TODO (fix) is this always best?
179181
av_frame->pts = av_frame->best_effort_timestamp;
180182

183+
#if LIBAVUTIL_VERSION_MAJOR < 58
181184
auto duration_pts = av_frame->pkt_duration;
185+
#else
186+
auto duration_pts = av_frame->duration;
187+
#endif
182188
if (duration_pts <= 0) {
183189
if (ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
184190
const auto ticks = av_stream_get_parser(st) ? av_stream_get_parser(st)->repeat_pict + 1
@@ -313,7 +319,12 @@ struct Filter
313319
AVRational tb = {1, format_desc.audio_sample_rate};
314320
for (auto n = 0U; n < input->nb_streams; ++n) {
315321
const auto st = input->streams[n];
316-
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->channels > 0) {
322+
#if FFMPEG_NEW_CHANNEL_LAYOUT
323+
const auto codec_channels = st->codecpar->ch_layout.nb_channels;
324+
#else
325+
const auto codec_channels = st->codecpar->channels;
326+
#endif
327+
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && codec_channels > 0) {
317328
tb = {1, st->codecpar->sample_rate};
318329
break;
319330
}
@@ -364,7 +375,12 @@ struct Filter
364375
for (auto n = 0U; n < input->nb_streams; ++n) {
365376
const auto st = input->streams[n];
366377

367-
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->channels == 0) {
378+
#if FFMPEG_NEW_CHANNEL_LAYOUT
379+
const auto codec_channels = st->codecpar->ch_layout.nb_channels;
380+
#else
381+
const auto codec_channels = st->codecpar->channels;
382+
#endif
383+
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && codec_channels == 0) {
368384
continue;
369385
}
370386

@@ -468,9 +484,16 @@ struct Filter
468484
FF(avfilter_link(source, 0, cur->filter_ctx, cur->pad_idx));
469485
sources.emplace(index, source);
470486
} else if (st->codec_type == AVMEDIA_TYPE_AUDIO) {
487+
#if FFMPEG_NEW_CHANNEL_LAYOUT
488+
char channel_layout[128];
489+
FF(av_channel_layout_describe(&st->ch_layout, channel_layout, sizeof(channel_layout)));
490+
#else
491+
const auto channel_layout = st->channel_layout;
492+
#endif
493+
471494
auto args = (boost::format("time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=%#x") %
472495
st->pkt_timebase.num % st->pkt_timebase.den % st->sample_rate %
473-
av_get_sample_fmt_name(st->sample_fmt) % st->channel_layout)
496+
av_get_sample_fmt_name(st->sample_fmt) % channel_layout)
474497
.str();
475498
auto name = (boost::format("in_%d") % index).str();
476499

@@ -523,8 +546,7 @@ struct Filter
523546
const AVSampleFormat sample_fmts[] = {AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE};
524547
FF(av_opt_set_int_list(sink, "sample_fmts", sample_fmts, -1, AV_OPT_SEARCH_CHILDREN));
525548

526-
const int channel_counts[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, -1};
527-
FF(av_opt_set_int_list(sink, "channel_counts", channel_counts, -1, AV_OPT_SEARCH_CHILDREN));
549+
FF(av_opt_set_int(sink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN));
528550

529551
const int sample_rates[] = {format_desc.audio_sample_rate, -1};
530552
FF(av_opt_set_int_list(sink, "sample_rates", sample_rates, -1, AV_OPT_SEARCH_CHILDREN));

src/modules/ffmpeg/util/av_util.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,13 @@ core::mutable_frame make_frame(void* tag,
7272
const int channel_count = 16;
7373
frame.audio_data() = std::vector<int32_t>(audio->nb_samples * channel_count, 0);
7474

75-
if (audio->channels == channel_count) {
75+
#if FFMPEG_NEW_CHANNEL_LAYOUT
76+
auto source_channel_count = audio->ch_layout.nb_channels;
77+
#else
78+
auto source_channel_count = audio->channels;
79+
#endif
80+
81+
if (source_channel_count == channel_count) {
7682
std::memcpy(frame.audio_data().data(),
7783
reinterpret_cast<int32_t*>(audio->data[0]),
7884
sizeof(int32_t) * channel_count * audio->nb_samples);
@@ -82,8 +88,8 @@ core::mutable_frame make_frame(void* tag,
8288
auto dst = frame.audio_data().data();
8389
auto src = reinterpret_cast<int32_t*>(audio->data[0]);
8490
for (auto i = 0; i < audio->nb_samples; i++) {
85-
for (auto j = 0; j < std::min(channel_count, audio->channels); ++j) {
86-
dst[i * channel_count + j] = src[i * audio->channels + j];
91+
for (auto j = 0; j < std::min(channel_count, source_channel_count); ++j) {
92+
dst[i * channel_count + j] = src[i * source_channel_count + j];
8793
}
8894
}
8995
}
@@ -291,11 +297,15 @@ std::shared_ptr<AVFrame> make_av_audio_frame(const core::const_frame& frame, con
291297
const auto& buffer = frame.audio_data();
292298

293299
// TODO (fix) Use sample_format_desc.
300+
#if FFMPEG_NEW_CHANNEL_LAYOUT
301+
av_channel_layout_default(&av_frame->ch_layout, format_desc.audio_channels);
302+
#else
294303
av_frame->channels = format_desc.audio_channels;
295304
av_frame->channel_layout = av_get_default_channel_layout(av_frame->channels);
305+
#endif
296306
av_frame->sample_rate = format_desc.audio_sample_rate;
297307
av_frame->format = AV_SAMPLE_FMT_S32;
298-
av_frame->nb_samples = static_cast<int>(buffer.size() / av_frame->channels);
308+
av_frame->nb_samples = static_cast<int>(buffer.size() / format_desc.audio_channels);
299309
FF(av_frame_get_buffer(av_frame.get(), 32));
300310
std::memcpy(av_frame->data[0], buffer.data(), buffer.size() * sizeof(buffer.data()[0]));
301311

@@ -330,4 +340,18 @@ std::map<std::string, std::string> to_map(AVDictionary** dict)
330340
return map;
331341
}
332342

343+
344+
uint64_t get_channel_layout_mask_for_channels(int channel_count) {
345+
#if FFMPEG_NEW_CHANNEL_LAYOUT
346+
AVChannelLayout layout = AV_CHANNEL_LAYOUT_STEREO;
347+
av_channel_layout_default(&layout, channel_count);
348+
uint64_t channel_layout = layout.u.mask;
349+
av_channel_layout_uninit(&layout);
350+
351+
return channel_layout;
352+
#else
353+
return av_get_default_channel_layout(channel_count);
354+
#endif
355+
}
356+
333357
}} // namespace caspar::ffmpeg

src/modules/ffmpeg/util/av_util.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <memory>
1010
#include <vector>
1111

12+
#include "../defines.h"
13+
1214
struct AVFrame;
1315
struct AVPacket;
1416
struct AVFilterContext;
@@ -33,4 +35,6 @@ std::shared_ptr<AVFrame> make_av_audio_frame(const core::const_frame& frame, con
3335
AVDictionary* to_dict(std::map<std::string, std::string>&& map);
3436
std::map<std::string, std::string> to_map(AVDictionary** dict);
3537

38+
uint64_t get_channel_layout_mask_for_channels(int channel_count);
39+
3640
}} // namespace caspar::ffmpeg

src/modules/newtek/producer/newtek_ndi_producer.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,11 @@ struct newtek_ndi_producer : public core::frame_producer
206206
if (audio_frame.p_data != nullptr) {
207207
audio_frame_32s.reference_level = 0;
208208
ndi_lib_->util_audio_to_interleaved_32s_v2(&audio_frame, &audio_frame_32s);
209-
a_frame->channels = audio_frame_32s.no_channels;
209+
#if FFMPEG_NEW_CHANNEL_LAYOUT
210+
av_channel_layout_default(&a_frame->ch_layout, audio_frame_32s.no_channels);
211+
#else
212+
a_frame->channels = audio_frame_32s.no_channels;
213+
#endif
210214
a_frame->sample_rate = audio_frame_32s.sample_rate;
211215
a_frame->nb_samples = audio_frame_32s.no_samples;
212216
a_frame->data[0] = reinterpret_cast<uint8_t*>(audio_frame_32s.p_data);

src/modules/oal/consumer/oal_consumer.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
#include <core/frame/frame.h>
3636
#include <core/video_format.h>
3737

38+
#include <modules/ffmpeg/defines.h>
39+
3840
#include <boost/algorithm/string/erase.hpp>
3941
#include <boost/algorithm/string/predicate.hpp>
4042
#include <boost/property_tree/ptree.hpp>
@@ -249,8 +251,12 @@ struct oal_consumer : public core::frame_consumer
249251
auto dst = std::shared_ptr<AVFrame>(av_frame_alloc(), [](AVFrame* ptr) { av_frame_free(&ptr); });
250252
dst->format = AV_SAMPLE_FMT_S16;
251253
dst->sample_rate = format_desc_.audio_sample_rate;
254+
#if FFMPEG_NEW_CHANNEL_LAYOUT
255+
av_channel_layout_default(&dst->ch_layout, 2);
256+
#else
252257
dst->channels = 2;
253258
dst->channel_layout = av_get_default_channel_layout(dst->channels);
259+
#endif
254260
dst->nb_samples = duration_;
255261
if (av_frame_get_buffer(dst.get(), 32) < 0) {
256262
// TODO FF error
@@ -277,9 +283,13 @@ struct oal_consumer : public core::frame_consumer
277283
auto src = std::shared_ptr<AVFrame>(av_frame_alloc(), [](AVFrame* ptr) { av_frame_free(&ptr); });
278284
src->format = AV_SAMPLE_FMT_S32;
279285
src->sample_rate = format_desc_.audio_sample_rate;
286+
#if FFMPEG_NEW_CHANNEL_LAYOUT
287+
av_channel_layout_default(&src->ch_layout, format_desc_.audio_channels);
288+
#else
280289
src->channels = format_desc_.audio_channels;
281290
src->channel_layout = av_get_default_channel_layout(src->channels);
282-
src->nb_samples = static_cast<int>(frame.audio_data().size() / src->channels);
291+
#endif
292+
src->nb_samples = static_cast<int>(frame.audio_data().size() / format_desc_.audio_channels);
283293
src->extended_data[0] = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(frame.audio_data().data()));
284294
src->linesize[0] = static_cast<int>(frame.audio_data().size() * sizeof(int32_t));
285295

0 commit comments

Comments
 (0)