Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

util/libav: do not bail on MEL-only RPUs w/EL #286

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/include/libplacebo/utils/libav.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,18 @@ PL_DEPRECATED_IN(v7.343) PL_LIBAV_API void pl_frame_map_avdovi_metadata(
// values from the `AVDOVIMetadata`.
//
// Note: The `pl_dovi_metadata` must be allocated externally.
// Also, currently the metadata is only used if the `AVDOVIRpuDataHeader`
// `disable_residual_flag` field is not zero and can be checked before allocating.
// Currently, the metadata can only be mapped if FEL (full enhancement layer)
// is not used and this can be checked before allocating
// (see pl_can_map_avdovi_metadata()).
PL_LIBAV_API void pl_map_avdovi_metadata(struct pl_color_space *color,
struct pl_color_repr *repr,
struct pl_dovi_metadata *dovi,
const AVDOVIMetadata *metadata);

// Helper function to check if Dolby Vision metadata can be mapped.
// Returns true if the `AVDOVIRpuDataHeader` `disable_residual_flag` field is
// not zero or if the NLQ parameters are trivial.
PL_LIBAV_API bool pl_can_map_avdovi_metadata(const AVDOVIMetadata *metadata);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pl_map_avdovi_metadata could map more metadata, but without pl_dovi_metadata use. This could be pl_is_dovi_metadata_needed or something and pl_map_avdovi_metadata could take NULL if the former function returns false. This would allow to still make RPU values.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pl_map_avdovi_metadata could take NULL if the former function returns false. This would allow to still make RPU values.

Sorry, I don't follow — how? If we're talking about that av_dovi_find_level() block from your diff above, it still needs the AVDOVIMetadata *, no? Or are we talking about some hypothetical yet-unwritten code?

Copy link
Contributor

@kasper93 kasper93 Aug 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pl_map_avdovi_metadata(&color, &repr, NULL, &metadata); I'm talking about output parameter, when we decide not to use pl_dovi_metadata, but still populate max_pq and avg_pq. This is how pl_map_avframe_ex() works.

#endif

// Helper function to test if a pixfmt would be supported by the GPU.
Expand Down
44 changes: 40 additions & 4 deletions src/include/libplacebo/utils/libav_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -886,22 +886,58 @@ PL_LIBAV_API void pl_map_dovi_metadata(struct pl_dovi_metadata *out,
}
}

static bool pl_avdovi_nlq_is_trivial(const AVDOVIRpuDataHeader *header,
const AVDOVINLQParams *nlq)
{
return
nlq->nlq_offset == 0
&& nlq->vdr_in_max == (1ULL << header->coef_log2_denom)
&& nlq->linear_deadzone_slope == 0
&& nlq->linear_deadzone_threshold == 0
;
}

static bool pl_avdovi_mapping_nlq_is_trivial(const AVDOVIRpuDataHeader *header,
const AVDOVIDataMapping *mapping)
{
return
mapping->nlq_method_idc == AV_DOVI_NLQ_LINEAR_DZ
&& pl_avdovi_nlq_is_trivial(header, &mapping->nlq[0])
&& pl_avdovi_nlq_is_trivial(header, &mapping->nlq[1])
&& pl_avdovi_nlq_is_trivial(header, &mapping->nlq[2])
;
}

PL_LIBAV_API bool pl_can_map_avdovi_metadata(const AVDOVIMetadata *metadata)
{
const AVDOVIRpuDataHeader *header;
const AVDOVIDataMapping *mapping;

header = av_dovi_get_header(metadata);
if (header->disable_residual_flag)
return true;

mapping = av_dovi_get_mapping(metadata);
if (pl_avdovi_mapping_nlq_is_trivial(header, mapping))
return true;

return false;
}

PL_LIBAV_API void pl_map_avdovi_metadata(struct pl_color_space *color,
struct pl_color_repr *repr,
struct pl_dovi_metadata *dovi,
const AVDOVIMetadata *metadata)
{
const AVDOVIRpuDataHeader *header;
const AVDOVIColorMetadata *dovi_color;
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(59, 12, 100)
const AVDOVIDmData *dovi_ext;
#endif
if (!color || !repr || !dovi)
return;

header = av_dovi_get_header(metadata);
dovi_color = av_dovi_get_color(metadata);
if (header->disable_residual_flag) {
if (pl_can_map_avdovi_metadata(metadata)) {
dovi_color = av_dovi_get_color(metadata);
pl_map_dovi_metadata(dovi, metadata);

repr->dovi = dovi;
Expand Down