color: input colorspace auto-detection, HDR export tags, LGG/white balance nodes, more LUT formats, waveform parade
- media color primaries/transfer tags now flow from the FFmpeg probe through VideoParams into Footage::get_colorspace_to_use(); precedence is user override > media tags > project default - export nclc tags derive from the output colorspace (PQ/HLG/BT.2020, P3, sRGB, Rec.601, Rec.709) instead of hardcoded BT.709 - new OCIO Color Grading (Log) node (lift/gamma/gain) and White Balance node (kelvin temperature + tint, HDR-safe) - LUT whitelist extended to 9 OCIO-supported formats - waveform scope gains an RGB parade mode (GPU and software paths) - tests updated for the new colorspace precedence
This commit is contained in:
@@ -435,6 +435,8 @@ int fb_decoder_get_stream_info(const FBDecoder *decoder, FBStreamInfo *out)
|
||||
out->field_order = decoder->codec_ctx ? decoder->codec_ctx->field_order :
|
||||
AV_FIELD_UNKNOWN;
|
||||
out->color_range = par->color_range;
|
||||
out->color_primaries = par->color_primaries;
|
||||
out->color_trc = par->color_trc;
|
||||
out->sample_rate = par->sample_rate;
|
||||
out->sample_format = par->format;
|
||||
out->channel_layout_mask = fb::validate_stream_channel_layout_mask(s);
|
||||
|
||||
@@ -153,6 +153,9 @@ struct FBEncoder {
|
||||
int64_t video_buffer_size = 0;
|
||||
int video_threads = 0;
|
||||
int video_color_srgb = 0;
|
||||
int video_color_primaries = fb_color_primaries_unspec;
|
||||
int video_color_trc = fb_color_trc_unspec;
|
||||
int video_colorspace = fb_col_spc_unspec;
|
||||
std::vector<std::pair<std::string, std::string>> video_opts;
|
||||
|
||||
int audio_enabled = 0;
|
||||
@@ -251,6 +254,9 @@ FBEncoder *fb_encoder_create(const FBEncoderConfig *config)
|
||||
e->video_buffer_size = config->video_buffer_size;
|
||||
e->video_threads = config->video_threads;
|
||||
e->video_color_srgb = config->video_color_srgb;
|
||||
e->video_color_primaries = config->video_color_primaries;
|
||||
e->video_color_trc = config->video_color_trc;
|
||||
e->video_colorspace = config->video_colorspace;
|
||||
for (int i = 0; i < config->video_opt_count; i++) {
|
||||
if (config->video_opt_keys[i] && config->video_opt_values[i]) {
|
||||
e->video_opts.emplace_back(config->video_opt_keys[i],
|
||||
@@ -868,7 +874,14 @@ bool FBEncoder::initialize_stream(AVMediaType type, AVStream **stream_ptr,
|
||||
}
|
||||
|
||||
// nclc tags. See https://ffmpeg.org/doxygen/4.0/pixfmt_8h.html#ad384ee5a840bafd73daef08e6d9cafe7
|
||||
if (video_color_srgb) {
|
||||
if (video_color_primaries != fb_color_primaries_unspec) {
|
||||
// Explicit tags supplied (e.g. derived from the export colorspace)
|
||||
codec_ctx->color_primaries =
|
||||
static_cast<AVColorPrimaries>(video_color_primaries);
|
||||
codec_ctx->color_trc =
|
||||
static_cast<AVColorTransferCharacteristic>(video_color_trc);
|
||||
codec_ctx->colorspace = static_cast<AVColorSpace>(video_colorspace);
|
||||
} else if (video_color_srgb) {
|
||||
codec_ctx->color_primaries = AVCOL_PRI_BT709;
|
||||
codec_ctx->color_trc = AVCOL_TRC_IEC61966_2_1;
|
||||
codec_ctx->colorspace = AVCOL_SPC_BT709;
|
||||
|
||||
@@ -84,6 +84,21 @@ static_assert(fb_col_spc_smpt_e170_m == AVCOL_SPC_SMPTE170M, "colspace mismatch"
|
||||
static_assert(fb_col_spc_smpt_e240_m == AVCOL_SPC_SMPTE240M, "colspace mismatch");
|
||||
static_assert(fb_col_spc_b_t2020_ncl == AVCOL_SPC_BT2020_NCL, "colspace mismatch");
|
||||
|
||||
static_assert(fb_color_primaries_unspec == AVCOL_PRI_UNSPECIFIED, "primaries mismatch");
|
||||
static_assert(fb_color_primaries_bt709 == AVCOL_PRI_BT709, "primaries mismatch");
|
||||
static_assert(fb_color_primaries_bt470bg == AVCOL_PRI_BT470BG, "primaries mismatch");
|
||||
static_assert(fb_color_primaries_smpte170m == AVCOL_PRI_SMPTE170M, "primaries mismatch");
|
||||
static_assert(fb_color_primaries_bt2020 == AVCOL_PRI_BT2020, "primaries mismatch");
|
||||
static_assert(fb_color_primaries_smpte432 == AVCOL_PRI_SMPTE432, "primaries mismatch");
|
||||
|
||||
static_assert(fb_color_trc_unspec == AVCOL_TRC_UNSPECIFIED, "trc mismatch");
|
||||
static_assert(fb_color_trc_bt709 == AVCOL_TRC_BT709, "trc mismatch");
|
||||
static_assert(fb_color_trc_gamma28 == AVCOL_TRC_GAMMA28, "trc mismatch");
|
||||
static_assert(fb_color_trc_smpte170m == AVCOL_TRC_SMPTE170M, "trc mismatch");
|
||||
static_assert(fb_color_trc_srgb == AVCOL_TRC_IEC61966_2_1, "trc mismatch");
|
||||
static_assert(fb_color_trc_pq == AVCOL_TRC_SMPTE2084, "trc mismatch");
|
||||
static_assert(fb_color_trc_hlg == AVCOL_TRC_ARIB_STD_B67, "trc mismatch");
|
||||
|
||||
static_assert(fb_media_type_video == AVMEDIA_TYPE_VIDEO, "mediatype mismatch");
|
||||
static_assert(fb_media_type_audio == AVMEDIA_TYPE_AUDIO, "mediatype mismatch");
|
||||
static_assert(fb_media_type_data == AVMEDIA_TYPE_DATA, "mediatype mismatch");
|
||||
|
||||
@@ -48,6 +48,8 @@ void fill_stream_info(const AVStream *s, int has_decoder, FBStreamInfo *out)
|
||||
out->pixel_format = fb::pix_fmt_from_av(AVPixelFormat(par->format));
|
||||
out->field_order = fb_field_order_unknown;
|
||||
out->color_range = par->color_range;
|
||||
out->color_primaries = par->color_primaries;
|
||||
out->color_trc = par->color_trc;
|
||||
out->sample_rate = par->sample_rate;
|
||||
out->sample_format = par->format;
|
||||
out->channel_layout_mask = fb::validate_stream_channel_layout_mask(s);
|
||||
|
||||
Reference in New Issue
Block a user