LibMedia: Move CICP values from CodedFrame to Track
All our current demuxers have these constant for an entire track, so we don't need to get them for every frame we output.
This commit is contained in:
parent
22585db022
commit
634e5ff491
6 changed files with 31 additions and 34 deletions
|
|
@ -6,21 +6,15 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <LibMedia/Color/CodingIndependentCodePoints.h>
|
||||
|
||||
namespace Media {
|
||||
|
||||
class CodedVideoFrameData {
|
||||
public:
|
||||
CodedVideoFrameData(CodingIndependentCodePoints container_cicp)
|
||||
: m_container_cicp(container_cicp)
|
||||
CodedVideoFrameData()
|
||||
{
|
||||
}
|
||||
|
||||
CodingIndependentCodePoints container_cicp() const { return m_container_cicp; }
|
||||
|
||||
private:
|
||||
CodingIndependentCodePoints m_container_cicp;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ static Track track_from_track_entry(TrackEntry const& track_entry)
|
|||
track.set_video_data({
|
||||
.pixel_width = video_track->pixel_width,
|
||||
.pixel_height = video_track->pixel_height,
|
||||
.cicp = video_track->color_format.to_cicp(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -208,8 +209,7 @@ DecoderErrorOr<CodedFrame> MatroskaDemuxer::get_next_sample_for_track(Track cons
|
|||
auto flags = status.block->only_keyframes() ? FrameFlags::Keyframe : FrameFlags::None;
|
||||
auto aux_data = [&] -> CodedFrame::AuxiliaryData {
|
||||
if (track.type() == TrackType::Video) {
|
||||
auto cicp = MUST(m_reader.track_for_track_number(track.identifier()))->video_track()->color_format.to_cicp();
|
||||
return CodedVideoFrameData(cicp);
|
||||
return CodedVideoFrameData();
|
||||
}
|
||||
if (track.type() == TrackType::Audio) {
|
||||
return CodedAudioFrameData();
|
||||
|
|
|
|||
|
|
@ -147,9 +147,24 @@ DecoderErrorOr<Track> FFmpegDemuxer::get_track_for_stream_index(u32 stream_index
|
|||
Track track(type, stream_index, name, language);
|
||||
|
||||
if (type == TrackType::Video) {
|
||||
auto color_primaries = static_cast<ColorPrimaries>(stream.codecpar->color_primaries);
|
||||
auto transfer_characteristics = static_cast<TransferCharacteristics>(stream.codecpar->color_trc);
|
||||
auto matrix_coefficients = static_cast<MatrixCoefficients>(stream.codecpar->color_space);
|
||||
auto color_range = [stream] {
|
||||
switch (stream.codecpar->color_range) {
|
||||
case AVColorRange::AVCOL_RANGE_MPEG:
|
||||
return VideoFullRangeFlag::Studio;
|
||||
case AVColorRange::AVCOL_RANGE_JPEG:
|
||||
return VideoFullRangeFlag::Full;
|
||||
default:
|
||||
return VideoFullRangeFlag::Unspecified;
|
||||
}
|
||||
}();
|
||||
|
||||
track.set_video_data({
|
||||
.pixel_width = static_cast<u64>(stream.codecpar->width),
|
||||
.pixel_height = static_cast<u64>(stream.codecpar->height),
|
||||
.cicp = CodingIndependentCodePoints(color_primaries, transfer_characteristics, matrix_coefficients, color_range),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -242,20 +257,7 @@ DecoderErrorOr<CodedFrame> FFmpegDemuxer::get_next_sample_for_track(Track const&
|
|||
|
||||
auto auxiliary_data = [&]() -> CodedFrame::AuxiliaryData {
|
||||
if (track.type() == TrackType::Video) {
|
||||
auto color_primaries = static_cast<ColorPrimaries>(stream.codecpar->color_primaries);
|
||||
auto transfer_characteristics = static_cast<TransferCharacteristics>(stream.codecpar->color_trc);
|
||||
auto matrix_coefficients = static_cast<MatrixCoefficients>(stream.codecpar->color_space);
|
||||
auto color_range = [stream] {
|
||||
switch (stream.codecpar->color_range) {
|
||||
case AVColorRange::AVCOL_RANGE_MPEG:
|
||||
return VideoFullRangeFlag::Studio;
|
||||
case AVColorRange::AVCOL_RANGE_JPEG:
|
||||
return VideoFullRangeFlag::Full;
|
||||
default:
|
||||
return VideoFullRangeFlag::Unspecified;
|
||||
}
|
||||
}();
|
||||
return CodedVideoFrameData(CodingIndependentCodePoints(color_primaries, transfer_characteristics, matrix_coefficients, color_range));
|
||||
return CodedVideoFrameData();
|
||||
}
|
||||
if (track.type() == TrackType::Audio) {
|
||||
return CodedAudioFrameData();
|
||||
|
|
|
|||
|
|
@ -124,26 +124,25 @@ bool VideoDataProvider::ThreadData::should_thread_exit() const
|
|||
return m_exit;
|
||||
}
|
||||
|
||||
void VideoDataProvider::ThreadData::set_cicp_values(VideoFrame& frame, CodedFrame const& coded_frame)
|
||||
void VideoDataProvider::ThreadData::set_cicp_values(VideoFrame& frame)
|
||||
{
|
||||
// Convert the frame for display.
|
||||
auto& cicp = frame.cicp();
|
||||
auto container_cicp = coded_frame.auxiliary_data().get<CodedVideoFrameData>().container_cicp();
|
||||
cicp.adopt_specified_values(container_cicp);
|
||||
cicp.default_code_points_if_unspecified({ ColorPrimaries::BT709, TransferCharacteristics::BT709, MatrixCoefficients::BT709, VideoFullRangeFlag::Studio });
|
||||
auto& frame_cicp = frame.cicp();
|
||||
auto const& container_cicp = m_track.video_data().cicp;
|
||||
frame_cicp.adopt_specified_values(container_cicp);
|
||||
frame_cicp.default_code_points_if_unspecified({ ColorPrimaries::BT709, TransferCharacteristics::BT709, MatrixCoefficients::BT709, VideoFullRangeFlag::Studio });
|
||||
|
||||
// BT.470 M, B/G, BT.601, BT.709 and BT.2020 have a similar transfer function to sRGB, so other applications
|
||||
// (Chromium, VLC) forgo transfer characteristics conversion. We will emulate that behavior by
|
||||
// handling those as sRGB instead, which causes no transfer function change in the output,
|
||||
// unless display color management is later implemented.
|
||||
switch (cicp.transfer_characteristics()) {
|
||||
switch (frame_cicp.transfer_characteristics()) {
|
||||
case TransferCharacteristics::BT470BG:
|
||||
case TransferCharacteristics::BT470M:
|
||||
case TransferCharacteristics::BT601:
|
||||
case TransferCharacteristics::BT709:
|
||||
case TransferCharacteristics::BT2020BitDepth10:
|
||||
case TransferCharacteristics::BT2020BitDepth12:
|
||||
cicp.set_transfer_characteristics(TransferCharacteristics::SRGB);
|
||||
frame_cicp.set_transfer_characteristics(TransferCharacteristics::SRGB);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -304,7 +303,7 @@ bool VideoDataProvider::ThreadData::handle_seek()
|
|||
}
|
||||
|
||||
auto current_frame = frame_result.release_value();
|
||||
set_cicp_values(*current_frame, coded_frame);
|
||||
set_cicp_values(*current_frame);
|
||||
if (is_desired_decoded_frame(*current_frame)) {
|
||||
auto locker = take_lock();
|
||||
m_queue.clear();
|
||||
|
|
@ -383,7 +382,7 @@ void VideoDataProvider::ThreadData::push_data_and_decode_some_frames()
|
|||
}
|
||||
|
||||
auto frame = frame_result.release_value();
|
||||
set_cicp_values(*frame, coded_frame);
|
||||
set_cicp_values(*frame);
|
||||
auto bitmap_result = frame->to_bitmap();
|
||||
|
||||
if (bitmap_result.is_error()) {
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ private:
|
|||
void seek(AK::Duration timestamp, SeekMode, SeekCompletionHandler&&);
|
||||
|
||||
bool should_thread_exit() const;
|
||||
static void set_cicp_values(VideoFrame&, CodedFrame const&);
|
||||
void set_cicp_values(VideoFrame&);
|
||||
void queue_frame(TimedImage&&);
|
||||
bool handle_seek();
|
||||
template<typename T>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <AK/Types.h>
|
||||
#include <AK/Utf16String.h>
|
||||
#include <AK/Variant.h>
|
||||
#include <LibMedia/Color/CodingIndependentCodePoints.h>
|
||||
|
||||
namespace Media {
|
||||
|
||||
|
|
@ -26,6 +27,7 @@ class Track {
|
|||
struct VideoData {
|
||||
u64 pixel_width { 0 };
|
||||
u64 pixel_height { 0 };
|
||||
CodingIndependentCodePoints cicp;
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
|
|||
Loading…
Reference in a new issue