X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fffmpeg%2Fproducer%2Futil%2Futil.cpp;h=d57b9b60da5a4aa60568587daebad2d1da780ef4;hb=726897adbf881d3b75f171fff24f2b917ba5f05a;hp=eb773c6c115f5818572bdee16ddd1072e409a4ba;hpb=cd1a44a41dd64c05de067ba728c285f001b66bf3;p=casparcg diff --git a/modules/ffmpeg/producer/util/util.cpp b/modules/ffmpeg/producer/util/util.cpp index eb773c6c1..d57b9b60d 100644 --- a/modules/ffmpeg/producer/util/util.cpp +++ b/modules/ffmpeg/producer/util/util.cpp @@ -27,6 +27,7 @@ #include "../tbb_avcodec.h" #include "../../ffmpeg_error.h" +#include "../../ffmpeg.h" #include #include @@ -487,18 +488,31 @@ spl::shared_ptr create_frame() { av_frame_free(&p); }); - avcodec_get_frame_defaults(frame.get()); return frame; } -std::shared_ptr flush() +std::shared_ptr flush_audio() { - static std::shared_ptr dummy(av_frame_alloc(), [](AVFrame* p) - { - av_frame_free(&p); - }); + static std::shared_ptr audio(new core::mutable_audio_buffer()); + return audio; +} + +std::shared_ptr empty_audio() +{ + static std::shared_ptr audio(new core::mutable_audio_buffer()); + return audio; +} + +std::shared_ptr flush_video() +{ + static auto video = create_frame(); + return video; +} - return dummy; +std::shared_ptr empty_video() +{ + static auto video = create_frame(); + return video; } spl::shared_ptr open_codec(AVFormatContext& context, enum AVMediaType type, int& index, bool single_threaded) @@ -771,6 +785,60 @@ std::int64_t create_channel_layout_bitmask(int num_channels) return static_cast(result); } +std::string to_string(const boost::rational& framerate) +{ + return boost::lexical_cast(framerate.numerator()) + + "/" + boost::lexical_cast(framerate.denominator()) + " (" + boost::lexical_cast(static_cast(framerate.numerator()) / static_cast(framerate.denominator())) + ") fps"; +} + +std::vector find_audio_cadence(const boost::rational& framerate) +{ + static std::map, std::vector> CADENCES_BY_FRAMERATE = [] + { + std::map, std::vector> result; + + for (core::video_format format : enum_constants()) + { + core::video_format_desc desc(format); + boost::rational format_rate(desc.time_scale, desc.duration); + + result.insert(std::make_pair(format_rate, desc.audio_cadence)); + } + + return result; + }(); + + auto exact_match = CADENCES_BY_FRAMERATE.find(framerate); + + if (exact_match != CADENCES_BY_FRAMERATE.end()) + return exact_match->second; + + boost::rational closest_framerate_diff = std::numeric_limits::max(); + boost::rational closest_framerate = 0; + + for (auto format_framerate : CADENCES_BY_FRAMERATE | boost::adaptors::map_keys) + { + auto diff = boost::abs(framerate - format_framerate); + + if (diff < closest_framerate_diff) + { + closest_framerate_diff = diff; + closest_framerate = format_framerate; + } + } + + if (is_logging_quiet_for_thread()) + CASPAR_LOG(debug) << "No exact audio cadence match found for framerate " << to_string(framerate) + << "\nClosest match is " << to_string(closest_framerate) + << "\nwhich is a " << to_string(closest_framerate_diff) << " difference."; + else + CASPAR_LOG(warning) << "No exact audio cadence match found for framerate " << to_string(framerate) + << "\nClosest match is " << to_string(closest_framerate) + << "\nwhich is a " << to_string(closest_framerate_diff) << " difference."; + + return CADENCES_BY_FRAMERATE[closest_framerate]; +} + // //void av_dup_frame(AVFrame* frame) //{