Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
ffmpeg
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Stefan Westerfeld
ffmpeg
Commits
5cd3c83a
Commit
5cd3c83a
authored
Feb 14, 2022
by
Limin Wang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avcodec: support for CUVA HDR Vivid metadata
Signed-off-by:
Limin Wang
<
lance.lmwang@gmail.com
>
parent
188faab2
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
241 additions
and
3 deletions
+241
-3
Makefile
libavcodec/Makefile
+1
-1
dynamic_hdr_vivid.c
libavcodec/dynamic_hdr_vivid.c
+139
-0
dynamic_hdr_vivid.h
libavcodec/dynamic_hdr_vivid.h
+35
-0
hevc_sei.c
libavcodec/hevc_sei.c
+46
-2
hevc_sei.h
libavcodec/hevc_sei.h
+5
-0
hevcdec.c
libavcodec/hevcdec.c
+15
-0
No files found.
libavcodec/Makefile
View file @
5cd3c83a
...
...
@@ -96,7 +96,7 @@ OBJS-$(CONFIG_H264PARSE) += h264_parse.o h2645_parse.o h264_ps.o
OBJS-$(CONFIG_H264PRED)
+=
h264pred.o
OBJS-$(CONFIG_H264QPEL)
+=
h264qpel.o
OBJS-$(CONFIG_HEVCPARSE)
+=
hevc_parse.o
h2645_parse.o
hevc_ps.o
hevc_sei.o
hevc_data.o
\
dynamic_hdr10_plus.o
dynamic_hdr10_plus.o
dynamic_hdr_vivid.o
OBJS-$(CONFIG_HPELDSP)
+=
hpeldsp.o
OBJS-$(CONFIG_HUFFMAN)
+=
huffman.o
OBJS-$(CONFIG_HUFFYUVDSP)
+=
huffyuvdsp.o
...
...
libavcodec/dynamic_hdr_vivid.c
0 → 100644
View file @
5cd3c83a
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dynamic_hdr_vivid.h"
#include "get_bits.h"
static
const
int32_t
maxrgb_den
=
4095
;
static
const
int32_t
color_saturation_gain_den
=
128
;
static
const
int32_t
maximum_luminance_den
=
4095
;
static
const
int32_t
base_param_m_p_den
=
16383
;
static
const
int32_t
base_param_m_m_den
=
10
;
static
const
int32_t
base_param_m_a_den
=
1023
;
static
const
int32_t
base_param_m_b_den
=
1023
;
static
const
int32_t
base_param_m_n_den
=
10
;
static
const
int32_t
base_param_Delta_den
=
127
;
int
ff_parse_itu_t_t35_to_dynamic_hdr_vivid
(
AVDynamicHDRVivid
*
s
,
const
uint8_t
*
data
,
int
size
)
{
GetBitContext
gbc
,
*
gb
=
&
gbc
;
int
ret
;
if
(
!
s
)
return
AVERROR
(
ENOMEM
);
ret
=
init_get_bits8
(
gb
,
data
,
size
);
if
(
ret
<
0
)
return
ret
;
if
(
get_bits_left
(
gb
)
<
8
)
return
AVERROR_INVALIDDATA
;
s
->
system_start_code
=
get_bits
(
gb
,
8
);
if
(
s
->
system_start_code
==
0x01
)
{
s
->
num_windows
=
1
;
if
(
get_bits_left
(
gb
)
<
12
*
4
*
s
->
num_windows
)
return
AVERROR_INVALIDDATA
;
for
(
int
w
=
0
;
w
<
s
->
num_windows
;
w
++
)
{
AVHDRVividColorTransformParams
*
params
=
&
s
->
params
[
w
];
params
->
minimum_maxrgb
=
(
AVRational
){
get_bits
(
gb
,
12
),
maxrgb_den
};
params
->
average_maxrgb
=
(
AVRational
){
get_bits
(
gb
,
12
),
maxrgb_den
};
params
->
variance_maxrgb
=
(
AVRational
){
get_bits
(
gb
,
12
),
maxrgb_den
};
params
->
maximum_maxrgb
=
(
AVRational
){
get_bits
(
gb
,
12
),
maxrgb_den
};
}
if
(
get_bits_left
(
gb
)
<
2
*
s
->
num_windows
)
return
AVERROR_INVALIDDATA
;
for
(
int
w
=
0
;
w
<
s
->
num_windows
;
w
++
)
{
AVHDRVividColorTransformParams
*
params
=
&
s
->
params
[
w
];
params
->
tone_mapping_mode_flag
=
get_bits
(
gb
,
1
);
if
(
params
->
tone_mapping_mode_flag
)
{
if
(
get_bits_left
(
gb
)
<
1
)
return
AVERROR_INVALIDDATA
;
params
->
tone_mapping_param_num
=
get_bits
(
gb
,
1
)
+
1
;
for
(
int
i
=
0
;
i
<
params
->
tone_mapping_param_num
;
i
++
)
{
AVHDRVividColorToneMappingParams
*
tm_params
=
&
params
->
tm_params
[
i
];
if
(
get_bits_left
(
gb
)
<
13
)
return
AVERROR_INVALIDDATA
;
tm_params
->
targeted_system_display_maximum_luminance
=
(
AVRational
){
get_bits
(
gb
,
12
),
maximum_luminance_den
};
tm_params
->
base_enable_flag
=
get_bits
(
gb
,
1
);
if
(
tm_params
->
base_enable_flag
)
{
if
(
get_bits_left
(
gb
)
<
(
14
+
6
+
10
+
10
+
6
+
8
+
10
))
return
AVERROR_INVALIDDATA
;
tm_params
->
base_param_m_p
=
(
AVRational
){
get_bits
(
gb
,
14
),
base_param_m_p_den
};
tm_params
->
base_param_m_m
=
(
AVRational
){
get_bits
(
gb
,
6
),
base_param_m_m_den
};
tm_params
->
base_param_m_a
=
(
AVRational
){
get_bits
(
gb
,
10
),
base_param_m_a_den
};
tm_params
->
base_param_m_b
=
(
AVRational
){
get_bits
(
gb
,
10
),
base_param_m_b_den
};
tm_params
->
base_param_m_n
=
(
AVRational
){
get_bits
(
gb
,
6
),
base_param_m_n_den
};
tm_params
->
base_param_k1
=
get_bits
(
gb
,
2
);
tm_params
->
base_param_k2
=
get_bits
(
gb
,
2
);
tm_params
->
base_param_k3
=
get_bits
(
gb
,
4
);
tm_params
->
base_param_Delta_enable_mode
=
get_bits
(
gb
,
3
);
if
(
tm_params
->
base_param_Delta_enable_mode
==
2
||
tm_params
->
base_param_Delta_enable_mode
==
6
)
tm_params
->
base_param_Delta
=
(
AVRational
){
get_bits
(
gb
,
7
)
*
-
1
,
base_param_Delta_den
};
else
tm_params
->
base_param_Delta
=
(
AVRational
){
get_bits
(
gb
,
7
),
base_param_Delta_den
};
if
(
get_bits_left
(
gb
)
<
1
)
return
AVERROR_INVALIDDATA
;
tm_params
->
three_Spline_enable_flag
=
get_bits
(
gb
,
1
);
if
(
tm_params
->
three_Spline_enable_flag
)
{
if
(
get_bits_left
(
gb
)
<
1
+
tm_params
->
three_Spline_num
*
(
2
+
12
+
28
+
1
))
return
AVERROR_INVALIDDATA
;
tm_params
->
three_Spline_num
=
get_bits
(
gb
,
1
)
+
1
;
for
(
int
j
=
0
;
j
<
tm_params
->
three_Spline_num
;
j
++
)
{
tm_params
->
three_Spline_TH_mode
=
get_bits
(
gb
,
2
);
if
(
tm_params
->
three_Spline_TH_mode
==
0
||
tm_params
->
three_Spline_TH_mode
==
2
)
{
if
(
get_bits_left
(
gb
)
<
8
)
return
AVERROR_INVALIDDATA
;
tm_params
->
three_Spline_TH_enable_MB
=
(
AVRational
){
get_bits
(
gb
,
8
),
255
};
}
tm_params
->
three_Spline_TH_enable
=
(
AVRational
){
get_bits
(
gb
,
12
),
4095
};
tm_params
->
three_Spline_TH_Delta1
=
(
AVRational
){
get_bits
(
gb
,
10
),
1023
};
tm_params
->
three_Spline_TH_Delta2
=
(
AVRational
){
get_bits
(
gb
,
10
),
1023
};
tm_params
->
three_Spline_enable_Strength
=
(
AVRational
){
get_bits
(
gb
,
8
),
255
};
}
}
else
{
tm_params
->
three_Spline_num
=
1
;
tm_params
->
three_Spline_TH_mode
=
0
;
}
}
}
}
params
->
color_saturation_mapping_flag
=
get_bits
(
gb
,
1
);
if
(
params
->
color_saturation_mapping_flag
)
{
if
(
get_bits_left
(
gb
)
<
3
+
params
->
color_saturation_num
*
8
)
return
AVERROR_INVALIDDATA
;
params
->
color_saturation_num
=
get_bits
(
gb
,
3
);
for
(
int
i
=
0
;
i
<
params
->
color_saturation_num
;
i
++
)
{
params
->
color_saturation_gain
[
i
]
=
(
AVRational
){
get_bits
(
gb
,
8
),
color_saturation_gain_den
};
}
}
}
}
return
0
;
}
libavcodec/dynamic_hdr_vivid.h
0 → 100644
View file @
5cd3c83a
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_DYNAMIC_HDR_VIVID_H
#define AVCODEC_DYNAMIC_HDR_VIVID_H
#include "libavutil/hdr_dynamic_vivid_metadata.h"
/**
* Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRVivid).
* @param s A pointer containing the decoded AVDynamicHDRVivid structure.
* @param data The byte array containing the raw ITU-T T.35 data.
* @param size Size of the data array in bytes.
*
* @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
*/
int
ff_parse_itu_t_t35_to_dynamic_hdr_vivid
(
AVDynamicHDRVivid
*
s
,
const
uint8_t
*
data
,
int
size
);
#endif
/* AVCODEC_DYNAMIC_HDR_VIVID_H */
libavcodec/hevc_sei.c
View file @
5cd3c83a
...
...
@@ -24,6 +24,7 @@
#include "atsc_a53.h"
#include "dynamic_hdr10_plus.h"
#include "dynamic_hdr_vivid.h"
#include "golomb.h"
#include "hevc_ps.h"
#include "hevc_sei.h"
...
...
@@ -245,6 +246,34 @@ static int decode_registered_user_data_dynamic_hdr_plus(HEVCSEIDynamicHDRPlus *s
return
0
;
}
static
int
decode_registered_user_data_dynamic_hdr_vivid
(
HEVCSEIDynamicHDRVivid
*
s
,
GetBitContext
*
gb
,
int
size
)
{
size_t
meta_size
;
int
err
;
AVDynamicHDRVivid
*
metadata
=
av_dynamic_hdr_vivid_alloc
(
&
meta_size
);
if
(
!
metadata
)
return
AVERROR
(
ENOMEM
);
err
=
ff_parse_itu_t_t35_to_dynamic_hdr_vivid
(
metadata
,
gb
->
buffer
+
get_bits_count
(
gb
)
/
8
,
size
);
if
(
err
<
0
)
{
av_free
(
metadata
);
return
err
;
}
av_buffer_unref
(
&
s
->
info
);
s
->
info
=
av_buffer_create
((
uint8_t
*
)
metadata
,
meta_size
,
NULL
,
NULL
,
0
);
if
(
!
s
->
info
)
{
av_free
(
metadata
);
return
AVERROR
(
ENOMEM
);
}
skip_bits_long
(
gb
,
size
*
8
);
return
0
;
}
static
int
decode_nal_sei_user_data_registered_itu_t_t35
(
HEVCSEI
*
s
,
GetBitContext
*
gb
,
void
*
logctx
,
int
size
)
{
...
...
@@ -263,9 +292,9 @@ static int decode_nal_sei_user_data_registered_itu_t_t35(HEVCSEI *s, GetBitConte
size
--
;
}
if
(
country_code
!=
0xB5
)
{
// usa
_country_code
if
(
country_code
!=
0xB5
&&
country_code
!=
0x26
)
{
// usa_country_code and cn
_country_code
av_log
(
logctx
,
AV_LOG_VERBOSE
,
"Unsupported User Data Registered ITU-T T35 SEI message (country_code =
%d
)
\n
"
,
"Unsupported User Data Registered ITU-T T35 SEI message (country_code =
0x%x
)
\n
"
,
country_code
);
goto
end
;
}
...
...
@@ -273,6 +302,20 @@ static int decode_nal_sei_user_data_registered_itu_t_t35(HEVCSEI *s, GetBitConte
provider_code
=
get_bits
(
gb
,
16
);
switch
(
provider_code
)
{
case
0x04
:
{
// cuva_provider_code
const
uint16_t
cuva_provider_oriented_code
=
0x0005
;
uint16_t
provider_oriented_code
;
if
(
size
<
2
)
return
AVERROR_INVALIDDATA
;
size
-=
2
;
provider_oriented_code
=
get_bits
(
gb
,
16
);
if
(
provider_oriented_code
==
cuva_provider_oriented_code
)
{
return
decode_registered_user_data_dynamic_hdr_vivid
(
&
s
->
dynamic_hdr_vivid
,
gb
,
size
);
}
break
;
}
case
0x3C
:
{
// smpte_provider_code
// A/341 Amendment - 2094-40
const
uint16_t
smpte2094_40_provider_oriented_code
=
0x0001
;
...
...
@@ -559,4 +602,5 @@ void ff_hevc_reset_sei(HEVCSEI *s)
s
->
unregistered
.
nb_buf_ref
=
0
;
av_freep
(
&
s
->
unregistered
.
buf_ref
);
av_buffer_unref
(
&
s
->
dynamic_hdr_plus
.
info
);
av_buffer_unref
(
&
s
->
dynamic_hdr_vivid
.
info
);
}
libavcodec/hevc_sei.h
View file @
5cd3c83a
...
...
@@ -78,6 +78,10 @@ typedef struct HEVCSEIDynamicHDRPlus {
AVBufferRef
*
info
;
}
HEVCSEIDynamicHDRPlus
;
typedef
struct
HEVCSEIDynamicHDRVivid
{
AVBufferRef
*
info
;
}
HEVCSEIDynamicHDRVivid
;
typedef
struct
HEVCSEIContentLight
{
int
present
;
uint16_t
max_content_light_level
;
...
...
@@ -139,6 +143,7 @@ typedef struct HEVCSEI {
HEVCSEIUnregistered
unregistered
;
HEVCSEIMasteringDisplay
mastering_display
;
HEVCSEIDynamicHDRPlus
dynamic_hdr_plus
;
HEVCSEIDynamicHDRVivid
dynamic_hdr_vivid
;
HEVCSEIContentLight
content_light
;
int
active_seq_parameter_set_id
;
HEVCSEIAlternativeTransfer
alternative_transfer
;
...
...
libavcodec/hevcdec.c
View file @
5cd3c83a
...
...
@@ -2984,6 +2984,17 @@ static int set_side_data(HEVCContext *s)
if
((
ret
=
ff_dovi_attach_side_data
(
&
s
->
dovi_ctx
,
out
))
<
0
)
return
ret
;
if
(
s
->
sei
.
dynamic_hdr_vivid
.
info
)
{
AVBufferRef
*
info_ref
=
av_buffer_ref
(
s
->
sei
.
dynamic_hdr_vivid
.
info
);
if
(
!
info_ref
)
return
AVERROR
(
ENOMEM
);
if
(
!
av_frame_new_side_data_from_buf
(
out
,
AV_FRAME_DATA_DYNAMIC_HDR_VIVID
,
info_ref
))
{
av_buffer_unref
(
&
info_ref
);
return
AVERROR
(
ENOMEM
);
}
}
return
0
;
}
...
...
@@ -3777,6 +3788,10 @@ static int hevc_update_thread_context(AVCodecContext *dst,
if
(
ret
<
0
)
return
ret
;
ret
=
av_buffer_replace
(
&
s
->
sei
.
dynamic_hdr_vivid
.
info
,
s0
->
sei
.
dynamic_hdr_vivid
.
info
);
if
(
ret
<
0
)
return
ret
;
s
->
sei
.
frame_packing
=
s0
->
sei
.
frame_packing
;
s
->
sei
.
display_orientation
=
s0
->
sei
.
display_orientation
;
s
->
sei
.
mastering_display
=
s0
->
sei
.
mastering_display
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment