code: Add GoPro CineForm to FFmpeg Encoders

This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2023-05-20 19:27:51 +02:00 committed by Xaymar
parent f66fabc5d4
commit ffb7a6c5d7
4 changed files with 147 additions and 0 deletions

View file

@ -293,6 +293,7 @@ set(${PREFIX}ENABLE_ENCODER_FFMPEG_AMF ${FEATURE_DEPRECATED} CACHE BOOL "Enable
set(${PREFIX}ENABLE_ENCODER_FFMPEG_NVENC ${FEATURE_STABLE} CACHE BOOL "Enable NVENC Encoder in FFmpeg.")
set(${PREFIX}ENABLE_ENCODER_FFMPEG_PRORES ${FEATURE_STABLE} CACHE BOOL "Enable ProRes Encoder in FFmpeg.")
set(${PREFIX}ENABLE_ENCODER_FFMPEG_DNXHR ${FEATURE_STABLE} CACHE BOOL "Enable DNXHR Encoder in FFmpeg.")
set(${PREFIX}ENABLE_ENCODER_FFMPEG_CFHD ${FEATURE_STABLE} CACHE BOOL "Enable CineForm Encoder in FFmpeg.")
## Filters
set(${PREFIX}ENABLE_FILTER_AUTOFRAMING ${FEATURE_EXPERIMENTAL} CACHE BOOL "Enable Auto-Framing Filter")
@ -476,6 +477,9 @@ function(feature_encoder_ffmpeg RESOLVE)
# DNxHR
is_feature_enabled(ENCODER_FFMPEG_DNXHR T_CHECK)
# CineForm
is_feature_enabled(ENCODER_FFMPEG_CFHD T_CHECK)
endif()
elseif(T_CHECK)
set(REQUIRE_FFMPEG ON PARENT_SCOPE)
@ -1202,6 +1206,18 @@ if(T_CHECK)
ENABLE_ENCODER_FFMPEG_DNXHR
)
endif()
# CineForm HD
is_feature_enabled(ENCODER_FFMPEG_CFHD T_CHECK)
if(T_CHECK)
list(APPEND PROJECT_PRIVATE_SOURCE
"source/encoders/ffmpeg/cfhd.hpp"
"source/encoders/ffmpeg/cfhd.cpp"
)
list(APPEND PROJECT_DEFINITIONS
ENABLE_ENCODER_FFMPEG_CFHD
)
endif()
endif()
# Filter/Auto-Framing

View file

@ -235,6 +235,22 @@ Encoder.FFmpeg.NVENC.Other.NonReferencePFrames="Non-reference P-Frames"
Encoder.FFmpeg.NVENC.Other.ReferenceFrames="Reference Frames"
Encoder.FFmpeg.NVENC.Other.LowDelayKeyFrameScale="Low Delay Key-Frame Scale"
# Encoder/FFmpeg/CFHD
Encoder.FFmpeg.CineForm.Quality="Quality"
Encoder.FFmpeg.CineForm.Quality.low="Low"
Encoder.FFmpeg.CineForm.Quality.low+="Low+"
Encoder.FFmpeg.CineForm.Quality.medium="Medium"
Encoder.FFmpeg.CineForm.Quality.medium+="Medium+"
Encoder.FFmpeg.CineForm.Quality.high="High"
Encoder.FFmpeg.CineForm.Quality.high+="High+"
Encoder.FFmpeg.CineForm.Quality.film1="Film 1"
Encoder.FFmpeg.CineForm.Quality.film1+="Film 1+"
Encoder.FFmpeg.CineForm.Quality.film1.5="Film 1.5"
Encoder.FFmpeg.CineForm.Quality.film2="Film 2"
Encoder.FFmpeg.CineForm.Quality.film2+="Film 2+"
Encoder.FFmpeg.CineForm.Quality.film3="Film 3"
Encoder.FFmpeg.CineForm.Quality.film3+="Film 3+"
# Blur
Blur.Type.Box="Box"
Blur.Type.BoxLinear="Box Linear"

View file

@ -0,0 +1,89 @@
// AUTOGENERATED COPYRIGHT HEADER START
// Copyright (C) 2023 Michael Fabian 'Xaymar' Dirks <info@xaymar.com>
// AUTOGENERATED COPYRIGHT HEADER END
// Copyright (C) 2020-2023 Michael Fabian 'Xaymar' Dirks <info@xaymar.com>
// Copyright (C) 2020 Daniel Molkentin <daniel@molkentin.de>
#include "cfhd.hpp"
#include "common.hpp"
#include "encoders/encoder-ffmpeg.hpp"
#include "ffmpeg/tools.hpp"
#include "handler.hpp"
#include "plugin.hpp"
#include "warning-disable.hpp"
#include <map>
#include <string>
#include <utility>
#include <vector>
extern "C" {
#include <libavutil/opt.h>
}
#include "warning-enable.hpp"
using namespace streamfx::encoder::ffmpeg;
struct strings {
struct quality {
static constexpr const char* ffmpeg = "quality";
static constexpr const char* obs = "Quality";
static constexpr const char* i18n = "Encoder.FFmpeg.CineForm.Quality";
};
};
cfhd::cfhd() : handler("cfhd") {}
bool cfhd::has_keyframes(ffmpeg_factory* factory)
{
return false;
}
void cfhd::properties(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props)
{
// Try and acquire a valid context.
std::shared_ptr<AVCodecContext> ctx;
if (instance) {
ctx = std::shared_ptr<AVCodecContext>(instance->get_avcodeccontext(), [](AVCodecContext*) {});
} else { // If we don't have a context, create a temporary one that is automatically freed.
ctx = std::shared_ptr<AVCodecContext>(avcodec_alloc_context3(factory->get_avcodec()), [](AVCodecContext* v) { avcodec_free_context(&v); });
if (!ctx->priv_data) {
return;
}
}
{ // Quality parameter
auto to_string = [](const char* v) {
char buffer[1024];
snprintf(buffer, sizeof(buffer), "%s.%s", strings::quality::i18n, v);
return D_TRANSLATE(buffer);
};
auto p = obs_properties_add_list(props, strings::quality::obs, D_TRANSLATE(strings::quality::i18n), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
streamfx::ffmpeg::tools::avoption_list_add_entries(ctx->priv_data, strings::quality::ffmpeg, [&p, &to_string](const AVOption* opt) {
// FFmpeg returns this list in the wrong order. We want to start at the lowest, and go to the highest.
// So simply always insert at the top, and this will reverse the list.
obs_property_list_insert_string(p, 0, to_string(opt->name), opt->name);
});
}
}
std::string cfhd::help(ffmpeg_factory* factory)
{
return "https://github.com/Xaymar/obs-StreamFX/wiki/Encoder-FFmpeg-GoPro-CineForm";
}
void cfhd::defaults(ffmpeg_factory* factory, obs_data_t* settings)
{
obs_data_set_string(settings, strings::quality::obs, "film3+");
}
void cfhd::migrate(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings, uint64_t version) {}
void cfhd::update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings)
{
if (const char* v = obs_data_get_string(settings, strings::quality::obs); v && (v[0] != '\0')) {
av_opt_set(instance->get_avcodeccontext()->priv_data, strings::quality::ffmpeg, v, AV_OPT_SEARCH_CHILDREN);
}
}
static cfhd handler = cfhd();

View file

@ -0,0 +1,26 @@
// AUTOGENERATED COPYRIGHT HEADER START
// Copyright (C) 2023 Michael Fabian 'Xaymar' Dirks <info@xaymar.com>
// AUTOGENERATED COPYRIGHT HEADER END
#pragma once
#include "handler.hpp"
namespace streamfx::encoder::ffmpeg {
class cfhd : public handler {
public:
cfhd();
virtual ~cfhd(){};
bool has_keyframes(ffmpeg_factory* factory) override;
std::string help(ffmpeg_factory* factory) override;
void defaults(ffmpeg_factory* factory, obs_data_t* settings) override;
void properties(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props) override;
void migrate(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings, uint64_t version) override;
void update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) override;
};
} // namespace streamfx::encoder::ffmpeg