[FFmpeg-devel] [PATCH] Support HDR dynamic metadata (HDR10+) in HEVC decoder.

James Almer jamrial at gmail.com
Tue Jan 22 22:36:36 EET 2019


On 1/22/2019 4:50 PM, Rostislav Pehlivanov wrote:
> On Tue, 22 Jan 2019 at 18:01, Mohammad Izadi <moh.izadi at gmail.com> wrote:
>> diff --git a/libavcodec/hevc_sei.h b/libavcodec/hevc_sei.h
>> index 2fec00ace0..80c56b10bb 100644
>> --- a/libavcodec/hevc_sei.h
>> +++ b/libavcodec/hevc_sei.h
>> @@ -23,6 +23,7 @@
>>
>>  #include <stdint.h>
>>
>> +#include "libavutil/buffer.h"
>>  #include "get_bits.h"
>>
>>  /**
>> @@ -94,6 +95,10 @@ typedef struct HEVCSEIMasteringDisplay {
>>      uint32_t min_luminance;
>>  } HEVCSEIMasteringDisplay;
>>
>> +typedef struct HEVCSEIDynamicHDRPlus{
>> +    AVBufferRef *info;
>> +} HEVCSEIDynamicHDRPlus;
>> +
>>  typedef struct HEVCSEIContentLight {
>>      int present;
>>      uint16_t max_content_light_level;
>> @@ -109,6 +114,7 @@ typedef struct HEVCSEI {
>>      HEVCSEIPictureHash picture_hash;
>>      HEVCSEIFramePacking frame_packing;
>>      HEVCSEIDisplayOrientation display_orientation;
>> +    HEVCSEIDynamicHDRPlus dynamic_hdr_plus;
>>      HEVCSEIPictureTiming picture_timing;
>>      HEVCSEIA53Caption a53_caption;
>>      HEVCSEIMasteringDisplay mastering_display;
>> diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
>> index 10bf2563c0..a7ed26b9d9 100644
>> --- a/libavcodec/hevcdec.c
>> +++ b/libavcodec/hevcdec.c
>> @@ -28,6 +28,7 @@
>>  #include "libavutil/display.h"
>>  #include "libavutil/internal.h"
>>  #include "libavutil/mastering_display_metadata.h"
>> +#include "libavutil/hdr_dynamic_metadata.h"
>>  #include "libavutil/md5.h"
>>  #include "libavutil/opt.h"
>>  #include "libavutil/pixdesc.h"
>> @@ -2769,6 +2770,26 @@ static int set_side_data(HEVCContext *s)
>>          s->avctx->color_trc = out->color_trc =
>> s->sei.alternative_transfer.preferred_transfer_characteristics;
>>      }
>>
>> +    if (s->sei.dynamic_hdr_plus.info){
>> +        AVDynamicHDRPlus *metadata =
>> (AVDynamicHDRPlus*)s->sei.dynamic_hdr_plus.info->data;
>> +        // Convert coordinates to relative coordinate in [0, 1].
>> +        metadata->params[0].window_upper_left_corner_x.num  = 0;
>> +        metadata->params[0].window_upper_left_corner_y.num  = 0;
>> +        metadata->params[0].window_lower_right_corner_x.num =
>> out->width-1;
>> +        metadata->params[0].window_lower_right_corner_y.num =
>> out->height-1;
>> +        for (int w = 0; w < metadata->num_windows; w++) {
>> +            metadata->params[w].window_upper_left_corner_x.den =
>> out->width-1;
>> +            metadata->params[w].window_upper_left_corner_y.den =
>> out->height-1;
>> +            metadata->params[w].window_lower_right_corner_x.den =
>> out->width-1;
>> +            metadata->params[w].window_lower_right_corner_y.den =
>> out->height-1;
>> +        }
>>
> 
> Put spaces between all the variables you're subtracting one out of?

He can't edit the AVBufferRef stored in HEVCSEI for each frame as it
becomes non writable past the first reference.

> 
> 
> 
>> +        if (!av_frame_new_side_data_from_buf(out,
>> AV_FRAME_DATA_DYNAMIC_HDR_PLUS, s->sei.dynamic_hdr_plus.info)) {
>>
> 
> This is wrong, this takes ownership of the buffer, so by the time you apply
> it to the next frame it would have been free'd by the previous frame's
> unref.
> You need to call av_buffer_ref(s->sei.dynamic_hdr_plus.info) and put the
> new reference in av_frame_new_side_data_from_buf().
> You should also check if av_buffer_ref returned NULL in case of OOM.
> In case there's an error I don't think you should unref the s->
> sei.dynamic_hdr_plus.info buffer. It'll be freed during uninit, which the
> user will call if they think its necessary. That way the decoder state
> won't change.
> You should however return whatever av_frame_new_side_data_from_buf()
> returns. Just don't check it.

If this is meant to work through resolution changes, then he'll have to
call av_buffer_make_writable() for the new reference meant to be
attached as side data, either when it differs from the previous frame
(this needs code to keep track of dimension changes), or
unconditionally, in which case the benefit of reusing buffers will be lost.


More information about the ffmpeg-devel mailing list