-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
encoders/ffmpeg/dnxhr: Add Avid DNxHR Encoder based on FFmpeg
- Loading branch information
Showing
7 changed files
with
240 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
#include "dnxhr.hpp" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// FFMPEG based DNxHR Video Encoder Integration for OBS Studio | ||
// Copyright (c) 2022 Carsten Braun <[email protected]> | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in all | ||
// copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
// SOFTWARE. | ||
|
||
#pragma once | ||
#include "common.hpp" | ||
|
||
// Codec: DNxHR | ||
#define S_CODEC_DNXHR "Codec.DNxHR" | ||
#define S_CODEC_DNXHR_PROFILE "Codec.DNxHR.Profile" | ||
|
||
namespace streamfx::encoder::codec::dnxhr {} // namespace streamfx::encoder::codec::dnxhr |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
#include "dnxhd_handler.hpp" | ||
#include <array> | ||
#include "../codecs/dnxhr.hpp" | ||
#include "ffmpeg/tools.hpp" | ||
#include "plugin.hpp" | ||
|
||
extern "C" { | ||
#include <obs-module.h> | ||
} | ||
|
||
using namespace streamfx::encoder::ffmpeg::handler; | ||
using namespace streamfx::encoder::codec::dnxhr; | ||
|
||
void dnxhd_handler::adjust_info(ffmpeg_factory* fac, const AVCodec*, std::string&, std::string& name, std::string&) | ||
{ | ||
//Most people don't know what VC3 is and only know it as DNx. | ||
//Change name to make it easier to find. | ||
name = "Avid DNxHR (via FFmpeg)"; | ||
} | ||
|
||
void dnxhd_handler::override_colorformat(AVPixelFormat& target_format, obs_data_t* settings, const AVCodec* codec, | ||
AVCodecContext*) | ||
{ | ||
static const std::array<std::pair<const char*, AVPixelFormat>, static_cast<size_t>(5)> profile_to_format_map{ | ||
std::pair{"dnxhr_lb", AV_PIX_FMT_YUV422P}, std::pair{"dnxhr_sq", AV_PIX_FMT_YUV422P}, | ||
std::pair{"dnxhr_hq", AV_PIX_FMT_YUV422P}, std::pair{"dnxhr_hqx", AV_PIX_FMT_YUV422P10LE}, | ||
std::pair{"dnxhr_444", AV_PIX_FMT_YUV444P10LE}}; | ||
|
||
const char* selected_profile = obs_data_get_string(settings, S_CODEC_DNXHR_PROFILE); | ||
for (auto kv : profile_to_format_map) { | ||
if (strcmp(kv.first, selected_profile) == 0) { | ||
target_format = kv.second; | ||
return; | ||
} | ||
} | ||
|
||
//Fallback for (yet) unknown formats | ||
target_format = AV_PIX_FMT_YUV422P; | ||
} | ||
|
||
void dnxhd_handler::get_defaults(obs_data_t* settings, const AVCodec*, AVCodecContext*, bool) | ||
{ | ||
obs_data_set_default_string(settings, S_CODEC_DNXHR_PROFILE, "dnxhr_sq"); | ||
} | ||
|
||
bool dnxhd_handler::has_keyframe_support(ffmpeg_factory* instance) | ||
{ | ||
return false; | ||
} | ||
|
||
bool dnxhd_handler::has_pixel_format_support(ffmpeg_factory* instance) | ||
{ | ||
return false; | ||
} | ||
|
||
inline const char* dnx_profile_to_display_name(const char* profile) | ||
{ | ||
char buffer[1024]; | ||
snprintf(buffer, sizeof(buffer), "%s.%s\0", S_CODEC_DNXHR_PROFILE, profile); | ||
return D_TRANSLATE(buffer); | ||
} | ||
|
||
void dnxhd_handler::get_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context, bool) | ||
{ | ||
AVCodecContext* ctx = context; | ||
|
||
//Create dummy context if null was passed to the function | ||
if (!ctx) { | ||
ctx = avcodec_alloc_context3(codec); | ||
if (!ctx->priv_data) { | ||
avcodec_free_context(&ctx); | ||
return; | ||
} | ||
} | ||
auto p = obs_properties_add_list(props, S_CODEC_DNXHR_PROFILE, D_TRANSLATE(S_CODEC_DNXHR_PROFILE), | ||
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); | ||
|
||
streamfx::ffmpeg::tools::avoption_list_add_entries(ctx->priv_data, "profile", [&p](const AVOption* opt) { | ||
if (strcmp(opt->name, "dnxhd") == 0) { | ||
//Do not show DNxHD profile as it is outdated and should not be used. | ||
//It's also very picky about framerate and framesize combos, which makes it even less useful | ||
return; | ||
} | ||
|
||
//ffmpeg returns the profiles for DNxHR from highest to lowest. | ||
//Lowest to highest is what people usually expect. | ||
//Therefore, new entries will always be inserted at the top, effectively reversing the list | ||
obs_property_list_insert_string(p, 0, dnx_profile_to_display_name(opt->name), opt->name); | ||
}); | ||
|
||
//Free context if we created it here | ||
if (ctx && ctx != context) { | ||
avcodec_free_context(&ctx); | ||
} | ||
} | ||
|
||
void dnxhd_handler::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) | ||
{ | ||
const char* profile = obs_data_get_string(settings, S_CODEC_DNXHR_PROFILE); | ||
av_opt_set(context, "profile", profile, AV_OPT_SEARCH_CHILDREN); | ||
} | ||
|
||
void dnxhd_handler::log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) | ||
{ | ||
DLOG_INFO("[%s] Avid DNxHR:", codec->name); | ||
streamfx::ffmpeg::tools::print_av_option_string2(context, "profile", " Profile", | ||
[](int64_t v, std::string_view o) { return std::string(o); }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// FFMPEG based DNxHR Video Encoder Integration for OBS Studio | ||
// Copyright (c) 2022 Carsten Braun <[email protected]> | ||
// Copyright (c) 2019 Michael Fabian Dirks <[email protected]> | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in all | ||
// copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
// SOFTWARE. | ||
|
||
#pragma once | ||
#include "handler.hpp" | ||
|
||
extern "C" { | ||
#pragma warning(push) | ||
#pragma warning(disable : 4244) | ||
#include <libavcodec/avcodec.h> | ||
#pragma warning(pop) | ||
} | ||
|
||
namespace streamfx::encoder::ffmpeg::handler { | ||
class dnxhd_handler : public handler { | ||
public: | ||
virtual ~dnxhd_handler(){}; | ||
|
||
public /*factory*/: | ||
virtual void adjust_info(ffmpeg_factory* factory, const AVCodec* codec, std::string& id, std::string& name, | ||
std::string& codec_id); | ||
|
||
public /*factory*/: | ||
void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context, bool hw_encode) override; | ||
|
||
virtual std::string_view get_help_url(const AVCodec* codec) override | ||
{ | ||
return "https://github.com/Xaymar/obs-StreamFX/wiki/Encoder-FFmpeg-Avid-DNxHR"; | ||
}; | ||
|
||
public /*support tests*/: | ||
virtual bool has_keyframe_support(ffmpeg_factory* instance) override; | ||
|
||
public /*support tests*/: | ||
bool has_pixel_format_support(ffmpeg_factory* instance) override; | ||
|
||
public /*settings*/: | ||
void get_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context, | ||
bool hw_encode) override; | ||
|
||
void update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) override; | ||
|
||
void log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) override; | ||
|
||
public /*instance*/: | ||
void override_colorformat(AVPixelFormat& target_format, obs_data_t* settings, const AVCodec* codec, | ||
AVCodecContext* context) override; | ||
}; | ||
} // namespace streamfx::encoder::ffmpeg::handler |