diff mbox series

[FFmpeg-devel,v2] libavcodec/libx265: add user data unregistered SEI encoding

Message ID 20210712082436.8807-1-bradh@frogmouth.net
State New
Headers show
Series [FFmpeg-devel,v2] libavcodec/libx265: add user data unregistered SEI encoding
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Brad Hards July 12, 2021, 8:24 a.m. UTC
MISB ST 0604 and ST 2101 require user data unregistered SEI messages
(precision timestamps and sensor identifiers) to be included. That
currently isn't supported for libx265. This patch adds support
for user data unregistered SEI messages in accordance with
ISO/IEC 23008-2:2020 Section D.2.7

The design is based on nvenc, with support finished up at
57de80673cb
---
 libavcodec/libx265.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

Comments

Derek Buitenhuis July 13, 2021, 1:10 p.m. UTC | #1
On 7/12/2021 9:24 AM, Brad Hards wrote:
> MISB ST 0604 and ST 2101 require user data unregistered SEI messages
> (precision timestamps and sensor identifiers) to be included. That
> currently isn't supported for libx265. This patch adds support
> for user data unregistered SEI messages in accordance with
> ISO/IEC 23008-2:2020 Section D.2.7
> 
> The design is based on nvenc, with support finished up at
> 57de80673cb
> ---
>  libavcodec/libx265.c | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)

Should be OK.

- Derek
diff mbox series

Patch

diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c
index 90658d3d9e..9395120471 100644
--- a/libavcodec/libx265.c
+++ b/libavcodec/libx265.c
@@ -35,6 +35,7 @@ 
 #include "encode.h"
 #include "internal.h"
 #include "packet_internal.h"
+#include "sei.h"
 
 typedef struct libx265Context {
     const AVClass *class;
@@ -51,6 +52,9 @@  typedef struct libx265Context {
     char *profile;
     AVDictionary *x265_opts;
 
+    void *sei_data;
+    int sei_data_size;
+
     /**
      * If the encoder does not support ROI then warn the first time we
      * encounter a frame with ROI side data.
@@ -78,6 +82,7 @@  static av_cold int libx265_encode_close(AVCodecContext *avctx)
     libx265Context *ctx = avctx->priv_data;
 
     ctx->api->param_free(ctx->params);
+    av_freep(&ctx->sei_data);
 
     if (ctx->encoder)
         ctx->api->encoder_close(ctx->encoder);
@@ -489,6 +494,8 @@  static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     ctx->api->picture_init(ctx->params, &x265pic);
 
     if (pic) {
+        x265_sei *sei = &x265pic.userSEI;
+        sei->numPayloads = 0;
         for (i = 0; i < 3; i++) {
            x265pic.planes[i] = pic->data[i];
            x265pic.stride[i] = pic->linesize[i];
@@ -516,6 +523,32 @@  static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 
             memcpy(x265pic.userData, &pic->reordered_opaque, sizeof(pic->reordered_opaque));
         }
+
+        for (i = 0; i < pic->nb_side_data; i++) {
+            AVFrameSideData *side_data = pic->side_data[i];
+            void *tmp;
+            x265_sei_payload *sei_payload;
+
+            if (side_data->type != AV_FRAME_DATA_SEI_UNREGISTERED)
+                continue;
+
+            tmp = av_fast_realloc(ctx->sei_data,
+                                  &ctx->sei_data_size,
+                                  (sei->numPayloads + 1) * sizeof(*sei_payload));
+            if (!tmp) {
+                av_freep(&x265pic.userData);
+                av_freep(&x265pic.quantOffsets);
+                return AVERROR(ENOMEM);
+            }
+            ctx->sei_data = tmp;
+            sei->payloads = ctx->sei_data;
+            sei_payload = &sei->payloads[sei->numPayloads];
+            sei_payload->payload = side_data->data;
+            sei_payload->payloadSize = side_data->size;
+            /* Equal to libx265 USER_DATA_UNREGISTERED */
+            sei_payload->payloadType = SEI_TYPE_USER_DATA_UNREGISTERED;
+            sei->numPayloads++;
+        }
     }
 
     ret = ctx->api->encoder_encode(ctx->encoder, &nal, &nnal,