Signed-off-by: James Almer
---
libavcodec/avcodec.h | 2 +-
libavcodec/h2645_sei.c | 215 +
libavcodec/h2645_sei.h | 2 +
libavcodec/hevcdec.c | 4 +
libavcodec/pthread_frame.c | 11 ++
5 files changed, 141 insertions(+), 93 deletions(-)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 83dc487251..968009a192 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -2071,7 +2071,7 @@ typedef struct AVCodecContext {
* - encoding: may be set by user before calling avcodec_open2() for
* encoder configuration. Afterwards owned and freed by the
* encoder.
- * - decoding: unused
+ * - decoding: may be set by libavcodec in avcodec_open2().
*/
AVFrameSideData **decoded_side_data;
int nb_decoded_side_data;
diff --git a/libavcodec/h2645_sei.c b/libavcodec/h2645_sei.c
index afc103b69c..14a01c64d2 100644
--- a/libavcodec/h2645_sei.c
+++ b/libavcodec/h2645_sei.c
@@ -529,6 +529,120 @@ static int is_frame_packing_type_valid(SEIFpaType type,
enum AVCodecID codec_id)
type >= SEI_FPA_TYPE_SIDE_BY_SIDE;
}
+static int h2645_sei_to_side_data(AVCodecContext *avctx, H2645SEI *sei,
+ AVFrameSideData ***sd, int *nb_sd)
+{
+int ret;
+
+for (unsigned i = 0; i < sei->unregistered.nb_buf_ref; i++) {
+H2645SEIUnregistered *unreg = >unregistered;
+
+if (unreg->buf_ref[i]) {
+AVFrameSideData *entry = av_frame_side_data_add(sd, nb_sd,
+AV_FRAME_DATA_SEI_UNREGISTERED,
+>buf_ref[i], 0);
+if (!entry)
+av_buffer_unref(>buf_ref[i]);
+}
+}
+sei->unregistered.nb_buf_ref = 0;
+
+if (sei->ambient_viewing_environment.present) {
+H2645SEIAmbientViewingEnvironment *env =
+>ambient_viewing_environment;
+AVBufferRef *buf;
+size_t size;
+
+AVAmbientViewingEnvironment *dst_env =
+av_ambient_viewing_environment_alloc();
+if (!dst_env)
+return AVERROR(ENOMEM);
+
+buf = av_buffer_create((uint8_t *)dst_env, size, NULL, NULL, 0);
+if (!buf) {
+av_free(dst_env);
+return AVERROR(ENOMEM);
+}
+
+ret = ff_frame_new_side_data_from_buf_ext(avctx, sd, nb_sd,
+
AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT, );
+
+if (ret < 0)
+return ret;
+
+dst_env->ambient_illuminance = av_make_q(env->ambient_illuminance,
1);
+dst_env->ambient_light_x = av_make_q(env->ambient_light_x,
5);
+dst_env->ambient_light_y = av_make_q(env->ambient_light_y,
5);
+}
+
+if (sei->mastering_display.present) {
+// HEVC uses a g,b,r ordering, which we convert to a more natural r,g,b
+const int mapping[3] = {2, 0, 1};
+const int chroma_den = 5;
+const int luma_den = 1;
+int i;
+AVMasteringDisplayMetadata *metadata;
+
+ret = ff_decode_mastering_display_new_ext(avctx, sd, nb_sd, );
+if (ret < 0)
+return ret;
+
+if (metadata) {
+for (i = 0; i < 3; i++) {
+const int j = mapping[i];
+metadata->display_primaries[i][0].num =
sei->mastering_display.display_primaries[j][0];
+metadata->display_primaries[i][0].den = chroma_den;
+metadata->display_primaries[i][1].num =
sei->mastering_display.display_primaries[j][1];
+metadata->display_primaries[i][1].den = chroma_den;
+}
+metadata->white_point[0].num =
sei->mastering_display.white_point[0];
+metadata->white_point[0].den = chroma_den;
+metadata->white_point[1].num =
sei->mastering_display.white_point[1];
+metadata->white_point[1].den = chroma_den;
+
+metadata->max_luminance.num = sei->mastering_display.max_luminance;
+metadata->max_luminance.den = luma_den;
+metadata->min_luminance.num = sei->mastering_display.min_luminance;
+metadata->min_luminance.den = luma_den;
+metadata->has_luminance = 1;
+metadata->has_primaries = 1;
+
+av_log(avctx, AV_LOG_DEBUG, "Mastering Display Metadata:\n");
+av_log(avctx, AV_LOG_DEBUG,
+ "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f,
%5.4f)\n",
+ av_q2d(metadata->display_primaries[0][0]),
+ av_q2d(metadata->display_primaries[0][1]),
+ av_q2d(metadata->display_primaries[1][0]),
+ av_q2d(metadata->display_primaries[1][1]),
+ av_q2d(metadata->display_primaries[2][0]),
+ av_q2d(metadata->display_primaries[2][1]),
+ av_q2d(metadata->white_point[0]),