From ceccf878fb19bbed09269b7a087f907d3ab5726e Mon Sep 17 00:00:00 2001 From: Helge Norberg Date: Mon, 14 Dec 2015 18:16:15 +0100 Subject: [PATCH] Fixed file_nb_frames bug when video stream length is not available. Needs testing. --- modules/ffmpeg/ffmpeg.cpp | 9 ++++-- modules/ffmpeg/producer/ffmpeg_producer.cpp | 32 ++++++++++++++++----- modules/ffmpeg/producer/ffmpeg_producer.h | 10 +++++-- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/modules/ffmpeg/ffmpeg.cpp b/modules/ffmpeg/ffmpeg.cpp index ff7fa5419..d3796f242 100644 --- a/modules/ffmpeg/ffmpeg.cpp +++ b/modules/ffmpeg/ffmpeg.cpp @@ -39,6 +39,7 @@ #include #include +#include #include @@ -289,15 +290,17 @@ void init(core::module_dependencies dependencies) av_register_all(); avformat_network_init(); avcodec_register_all(); + + auto info_repo = dependencies.media_info_repo; dependencies.consumer_registry->register_consumer_factory(L"FFMpeg Consumer", create_consumer, describe_consumer); dependencies.consumer_registry->register_consumer_factory(L"Streaming Consumer", create_streaming_consumer, describe_streaming_consumer); dependencies.consumer_registry->register_preconfigured_consumer_factory(L"file", create_preconfigured_consumer); dependencies.consumer_registry->register_preconfigured_consumer_factory(L"stream", create_preconfigured_streaming_consumer); - dependencies.producer_registry->register_producer_factory(L"FFmpeg Producer", create_producer, describe_producer); - dependencies.producer_registry->register_thumbnail_producer_factory(create_thumbnail_producer); + dependencies.producer_registry->register_producer_factory(L"FFmpeg Producer", boost::bind(&create_producer, _1, _2, info_repo), describe_producer); + dependencies.producer_registry->register_thumbnail_producer_factory(boost::bind(&create_thumbnail_producer, _1, _2, info_repo)); - dependencies.media_info_repo->register_extractor( + info_repo->register_extractor( [](const std::wstring& file, const std::wstring& extension, core::media_info& info) -> bool { auto quiet_logging = temporary_enable_quiet_logging_for_thread(true); diff --git a/modules/ffmpeg/producer/ffmpeg_producer.cpp b/modules/ffmpeg/producer/ffmpeg_producer.cpp index a6b41e07a..aed7a41dc 100644 --- a/modules/ffmpeg/producer/ffmpeg_producer.cpp +++ b/modules/ffmpeg/producer/ffmpeg_producer.cpp @@ -49,6 +49,8 @@ #include #include #include +#include +#include #include #include @@ -107,6 +109,7 @@ struct ffmpeg_producer : public core::frame_producer_base const double fps_ = read_fps(input_.context(), format_desc_.fps); const uint32_t start_; const bool thumbnail_mode_; + const boost::optional info_; std::unique_ptr video_decoder_; std::unique_ptr audio_decoder_; @@ -127,14 +130,15 @@ public: bool loop, uint32_t start, uint32_t length, - bool thumbnail_mode) + bool thumbnail_mode, + boost::optional info) : filename_(filename) , frame_factory_(frame_factory) , format_desc_(format_desc) , input_(graph_, filename_, loop, start, length, thumbnail_mode) - , fps_(read_fps(input_.context(), format_desc_.fps)) , start_(start) , thumbnail_mode_(thumbnail_mode) + , info_(info) { graph_->set_color("frame-time", diagnostics::color(0.1f, 1.0f, 0.1f)); graph_->set_color("underflow", diagnostics::color(0.6f, 0.3f, 0.9f)); @@ -328,6 +332,10 @@ public: uint32_t file_nb_frames() const { uint32_t file_nb_frames = 0; + + if (info_) + file_nb_frames = static_cast(info_->duration); + file_nb_frames = std::max(file_nb_frames, video_decoder_ ? video_decoder_->nb_frames() : 0); file_nb_frames = std::max(file_nb_frames, audio_decoder_ ? audio_decoder_->nb_frames() : 0); return file_nb_frames; @@ -542,8 +550,11 @@ void describe_producer(core::help_sink& sink, const core::help_repository& repo) sink.example(L">> CALL 1-10 LENGTH 50"); } -spl::shared_ptr create_producer(const core::frame_producer_dependencies& dependencies, const std::vector& params) -{ +spl::shared_ptr create_producer( + const core::frame_producer_dependencies& dependencies, + const std::vector& params, + const spl::shared_ptr& info_repo) +{ auto filename = probe_stem(env::media_folder() + L"/" + params.at(0), false); if(filename.empty()) @@ -555,6 +566,7 @@ spl::shared_ptr create_producer(const core::frame_producer auto filter_str = get_param(L"FILTER", params, L""); auto channel_layout = get_param(L"CHANNEL_LAYOUT", params, L""); bool thumbnail_mode = false; + auto info = info_repo->get(filename); return create_destroy_proxy(spl::make_shared_ptr(std::make_shared( dependencies.frame_factory, @@ -565,10 +577,14 @@ spl::shared_ptr create_producer(const core::frame_producer loop, start, length, - thumbnail_mode))); + thumbnail_mode, + info))); } -spl::shared_ptr create_thumbnail_producer(const core::frame_producer_dependencies& dependencies, const std::vector& params) +spl::shared_ptr create_thumbnail_producer( + const core::frame_producer_dependencies& dependencies, + const std::vector& params, + const spl::shared_ptr& info_repo) { auto quiet_logging = temporary_enable_quiet_logging_for_thread(true); auto filename = probe_stem(env::media_folder() + L"/" + params.at(0), true); @@ -582,6 +598,7 @@ spl::shared_ptr create_thumbnail_producer(const core::fram auto filter_str = L""; auto channel_layout = L""; bool thumbnail_mode = true; + auto info = info_repo->get(filename); return spl::make_shared_ptr(std::make_shared( dependencies.frame_factory, @@ -592,7 +609,8 @@ spl::shared_ptr create_thumbnail_producer(const core::fram loop, start, length, - thumbnail_mode)); + thumbnail_mode, + info)); } }} diff --git a/modules/ffmpeg/producer/ffmpeg_producer.h b/modules/ffmpeg/producer/ffmpeg_producer.h index 77580085a..a197be16b 100644 --- a/modules/ffmpeg/producer/ffmpeg_producer.h +++ b/modules/ffmpeg/producer/ffmpeg_producer.h @@ -31,7 +31,13 @@ namespace caspar { namespace ffmpeg { void describe_producer(core::help_sink& sink, const core::help_repository& repo); -spl::shared_ptr create_producer(const core::frame_producer_dependencies& dependencies, const std::vector& params); -spl::shared_ptr create_thumbnail_producer(const core::frame_producer_dependencies& dependencies, const std::vector& params); +spl::shared_ptr create_producer( + const core::frame_producer_dependencies& dependencies, + const std::vector& params, + const spl::shared_ptr& info_repo); +spl::shared_ptr create_thumbnail_producer( + const core::frame_producer_dependencies& dependencies, + const std::vector& params, + const spl::shared_ptr& info_repo); }} \ No newline at end of file -- 2.39.2