Skip to content

Commit

Permalink
ffmpeg_producer: implement scaling modes
Browse files Browse the repository at this point in the history
  • Loading branch information
dimitry-ishenko committed Sep 20, 2024
1 parent e41271e commit a3648df
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 12 deletions.
14 changes: 10 additions & 4 deletions src/modules/ffmpeg/producer/av_producer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,7 @@ struct AVProducer::Impl
std::string vfilter_;

int seekable_ = 2;
core::frame_geometry::scale_mode scale_mode_;
int64_t frame_count_ = 0;
bool frame_flush_ = true;
int64_t frame_time_ = AV_NOPTS_VALUE;
Expand Down Expand Up @@ -694,7 +695,8 @@ struct AVProducer::Impl
std::optional<int64_t> seek,
std::optional<int64_t> duration,
bool loop,
int seekable)
int seekable,
core::frame_geometry::scale_mode scale_mode)
: frame_factory_(frame_factory)
, format_desc_(format_desc)
, format_tb_({format_desc.duration, format_desc.time_scale * format_desc.field_count})
Expand All @@ -707,6 +709,7 @@ struct AVProducer::Impl
, afilter_(afilter)
, vfilter_(vfilter)
, seekable_(seekable)
, scale_mode_(scale_mode)
, video_executor_(L"video-executor")
, audio_executor_(L"audio-executor")
{
Expand Down Expand Up @@ -913,7 +916,8 @@ struct AVProducer::Impl
}

frame.frame = core::draw_frame(
make_frame(this, *frame_factory_, frame.video, frame.audio, get_color_space(frame.video)));
make_frame(this, *frame_factory_, frame.video, frame.audio, get_color_space(frame.video), scale_mode_)
);
frame.frame_count = frame_count_++;

graph_->set_value("decode-time", decode_timer.elapsed() * format_desc_.fps * 0.5);
Expand Down Expand Up @@ -1237,7 +1241,8 @@ AVProducer::AVProducer(std::shared_ptr<core::frame_factory> frame_factory,
std::optional<int64_t> seek,
std::optional<int64_t> duration,
std::optional<bool> loop,
int seekable)
int seekable,
core::frame_geometry::scale_mode scale_mode)
: impl_(new Impl(std::move(frame_factory),
std::move(format_desc),
std::move(name),
Expand All @@ -1248,7 +1253,8 @@ AVProducer::AVProducer(std::shared_ptr<core::frame_factory> frame_factory,
std::move(seek),
std::move(duration),
std::move(loop.value_or(false)),
seekable))
seekable,
scale_mode))
{
}

Expand Down
4 changes: 3 additions & 1 deletion src/modules/ffmpeg/producer/av_producer.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <core/frame/draw_frame.h>
#include <core/frame/frame_factory.h>
#include <core/frame/geometry.h>
#include <core/monitor/monitor.h>
#include <core/video_format.h>

Expand All @@ -24,7 +25,8 @@ class AVProducer
std::optional<int64_t> seek,
std::optional<int64_t> duration,
std::optional<bool> loop,
int seekable);
int seekable,
core::frame_geometry::scale_mode scale_mode);

core::draw_frame prev_frame(const core::video_field field);
core::draw_frame next_frame(const core::video_field field);
Expand Down
15 changes: 10 additions & 5 deletions src/modules/ffmpeg/producer/ffmpeg_producer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

#include <core/frame/draw_frame.h>
#include <core/frame/frame_factory.h>
#include <core/frame/geometry.h>
#include <core/producer/frame_producer.h>
#include <core/video_format.h>

Expand Down Expand Up @@ -73,7 +74,8 @@ struct ffmpeg_producer : public core::frame_producer
std::optional<int64_t> seek,
std::optional<int64_t> duration,
std::optional<bool> loop,
int seekable)
int seekable,
core::frame_geometry::scale_mode scale_mode)
: filename_(filename)
, frame_factory_(frame_factory)
, format_desc_(format_desc)
Expand All @@ -87,9 +89,9 @@ struct ffmpeg_producer : public core::frame_producer
seek,
duration,
loop,
seekable))
{
}
seekable,
scale_mode))
{ }

~ffmpeg_producer()
{
Expand Down Expand Up @@ -317,6 +319,8 @@ spl::shared_ptr<core::frame_producer> create_producer(const core::frame_producer

auto filter_str = get_param(L"FILTER", params, L"");

auto scale_mode = core::scale_mode_from_string(get_param(L"SCALE_MODE", params, L"STRETCH"));

boost::ireplace_all(filter_str, L"DEINTERLACE_BOB", L"YADIF=1:-1");
boost::ireplace_all(filter_str, L"DEINTERLACE_LQ", L"SEPARATEFIELDS");
boost::ireplace_all(filter_str, L"DEINTERLACE", L"YADIF=0:-1");
Expand Down Expand Up @@ -350,7 +354,8 @@ spl::shared_ptr<core::frame_producer> create_producer(const core::frame_producer
seek2,
duration,
loop,
seekable);
seekable,
scale_mode);
return core::create_destroy_proxy(std::move(producer));
} catch (...) {
CASPAR_LOG_CURRENT_EXCEPTION();
Expand Down
6 changes: 5 additions & 1 deletion src/modules/ffmpeg/util/av_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ core::mutable_frame make_frame(void* tag,
core::frame_factory& frame_factory,
std::shared_ptr<AVFrame> video,
std::shared_ptr<AVFrame> audio,
core::color_space color_space)
core::color_space color_space,
core::frame_geometry::scale_mode scale_mode)
{
std::vector<int> data_map; // TODO(perf) when using data_map, avoid uploading duplicate planes

Expand All @@ -57,6 +58,9 @@ core::mutable_frame make_frame(void* tag,
: core::pixel_format_desc(core::pixel_format::invalid);

auto frame = frame_factory.create_frame(tag, pix_desc);
if (scale_mode != core::frame_geometry::scale_mode::stretch) {
frame.geometry() = core::frame_geometry::get_default(scale_mode);
}

tbb::parallel_invoke(
[&]() {
Expand Down
4 changes: 3 additions & 1 deletion src/modules/ffmpeg/util/av_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <core/frame/frame.h>
#include <core/frame/frame_factory.h>
#include <core/frame/geometry.h>
#include <core/frame/pixel_format.h>
#include <core/video_format.h>

Expand Down Expand Up @@ -31,7 +32,8 @@ core::mutable_frame make_frame(void* tag,
core::frame_factory& frame_factory,
std::shared_ptr<AVFrame> video,
std::shared_ptr<AVFrame> audio,
core::color_space color_space = core::color_space::bt709);
core::color_space color_space = core::color_space::bt709,
core::frame_geometry::scale_mode = core::frame_geometry::scale_mode::stretch);

std::shared_ptr<AVFrame> make_av_video_frame(const core::const_frame& frame, const core::video_format_desc& format_des);
std::shared_ptr<AVFrame> make_av_audio_frame(const core::const_frame& frame, const core::video_format_desc& format_des);
Expand Down

0 comments on commit a3648df

Please sign in to comment.