Skip to content

Commit

Permalink
Fixed FFmpegReader's color pipeline.
Browse files Browse the repository at this point in the history
Added tags for color_space, colorprimaries and color_trc.
  • Loading branch information
ggarra13 committed Mar 10, 2024
1 parent 4d96858 commit 678b6fd
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 9 deletions.
10 changes: 6 additions & 4 deletions lib/tlCore/Image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <tlCore/Assert.h>
#include <tlCore/Error.h>
#include <tlCore/String.h>
#include <tlCore/Locale.h>

#include <algorithm>
#include <array>
Expand Down Expand Up @@ -92,7 +93,10 @@ namespace tl
const std::array<math::Vector4f, static_cast<size_t>(YUVCoefficients::Count)> data =
{
math::Vector4f(1.79274, 2.1124, 0.213242, 0.532913),
math::Vector4f(1.67867, 2.14177, 0.187332, 0.650421)
// Is BT2020 right? These are the coeffs I got:
// math::Vector4f(1.4746, 2.0184, 1.5958, 0.0); // chatgpt3.5
// math::Vector4f(1.8556, 2.14101, 0.2124, 0.6301), // gemini
math::Vector4f(1.67867, 2.14177, 0.187332, 0.650421) // darby
};
return data[static_cast<size_t>(value)];
}
Expand Down Expand Up @@ -355,10 +359,8 @@ namespace tl
}
if (2 == split.size())
{
std::string savedLocale = std::setlocale(LC_NUMERIC, NULL);
std::setlocale(LC_NUMERIC, "C");
locale::SetAndRestore saved;
out.pixelAspectRatio = std::stof(split[1]);
std::setlocale(LC_NUMERIC, savedLocale.c_str());
}
split = string::split(split[0], 'x');
if (split.size() != 2)
Expand Down
38 changes: 35 additions & 3 deletions lib/tlIO/FFmpegReadVideo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,11 +347,12 @@ namespace tl
}
break;
}
if (_avCodecContext[_avStream]->color_range != AVCOL_RANGE_JPEG)
const auto params = _avCodecParameters[_avStream];
if (params->color_range != AVCOL_RANGE_JPEG)
{
_info.videoLevels = image::VideoLevels::LegalRange;
}
switch (_avCodecParameters[_avStream]->color_space)
switch (params->color_space)
{
case AVCOL_SPC_BT2020_NCL:
_info.yuvCoefficients = image::YUVCoefficients::BT2020;
Expand Down Expand Up @@ -456,6 +457,18 @@ namespace tl
_tags["Video Codec"] =
avcodec_get_name(_avCodecContext[_avStream]->codec_id);
}
{
_tags["Video Color Primaries"] =
av_color_primaries_name(params->color_primaries);
}
{
_tags["Video Color TRC"] =
av_color_transfer_name(params->color_trc);
}
{
_tags["Video Color Space"] =
av_color_space_name(params->color_space);
}
{
std::stringstream ss;
ss << _info.videoLevels;
Expand Down Expand Up @@ -599,6 +612,25 @@ namespace tl
{
throw std::runtime_error(string::Format("{0}: Cannot initialize sws context").arg(_fileName));
}

const auto params = _avCodecParameters[_avStream];
int in_full, out_full, brightness, contrast, saturation;
const int *inv_table, *table;

sws_getColorspaceDetails(
_swsContext, (int**)&inv_table, &in_full,
(int**)&table, &out_full, &brightness, &contrast,
&saturation);

inv_table = sws_getCoefficients(params->color_space);
table = sws_getCoefficients(AVCOL_SPC_BT709);

in_full = (params->color_range == AVCOL_RANGE_JPEG);
out_full = (params->color_range == AVCOL_RANGE_JPEG);

sws_setColorspaceDetails(
_swsContext, inv_table, in_full, table, out_full,
brightness, contrast, saturation);
}
}
}
Expand Down Expand Up @@ -851,7 +883,7 @@ namespace tl
w,
h,
1);

sws_scale(
_swsContext,
(uint8_t const* const*)_avFrame->data,
Expand Down
3 changes: 1 addition & 2 deletions lib/tlIO/FFmpegWrite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1421,8 +1421,7 @@ namespace tl
(int**)&table, &out_full, &brightness, &contrast,
&saturation);

inv_table =
parseYUVType("bt709", p.avCodecContext->colorspace);
inv_table = sws_getCoefficients(p.avCodecContext->colorspace);
table = parseYUVType("bt709", AVCOL_SPC_UNSPECIFIED);

// We use the full range, and we set -color_range to 2
Expand Down

0 comments on commit 678b6fd

Please sign in to comment.