summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorBrad Hards <bradh@frogmouth.net>2021-08-06 19:16:33 +1000
committerDerek Buitenhuis <derek.buitenhuis@gmail.com>2021-10-18 13:13:53 +0100
commit7c08cad280a16b346c0a5e0efdfd8333ec54f095 (patch)
tree52973e2d800bb32c0dcdc58a2ee04981aefce1a6 /libavcodec
parentab792634197e364ca1bb194f9abe36836e42f12d (diff)
libavcodec/libx264: add user data unregistered SEI encoding
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 libx264. This patch adds support for user data unregistered SEI messages in accordance with ISO/IEC 14496-10:2020(E) section D.1.7 (syntax) and D.2.7 (semantics). This code is based on a similar change for libx265 (commit 1f58503013720700a5adfd72c708e6275aefc165). Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/libx264.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 0f886713e3..507fee39f2 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -32,6 +32,7 @@
#include "internal.h"
#include "packet_internal.h"
#include "atsc_a53.h"
+#include "sei.h"
#if defined(_MSC_VER)
#define X264_API_IMPORTS 1
@@ -114,6 +115,9 @@ typedef struct X264Context {
* encounter a frame with ROI side data.
*/
int roi_warned;
+
+ void *sei_data;
+ int sei_data_size;
} X264Context;
static void X264_log(void *p, int level, const char *fmt, va_list args)
@@ -317,6 +321,9 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
x4->pic.img.i_plane = avfmt2_num_planes(ctx->pix_fmt);
if (frame) {
+ x264_sei_t *sei = &x4->pic.extra_sei;
+ sei->num_payloads = 0;
+
for (i = 0; i < x4->pic.img.i_plane; i++) {
x4->pic.img.plane[i] = frame->data[i];
x4->pic.img.i_stride[i] = frame->linesize[i];
@@ -439,6 +446,27 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
}
}
}
+
+ for (int j = 0; j < frame->nb_side_data; j++) {
+ AVFrameSideData *side_data = frame->side_data[j];
+ void *tmp;
+ x264_sei_payload_t *sei_payload;
+ if (side_data->type != AV_FRAME_DATA_SEI_UNREGISTERED)
+ continue;
+ tmp = av_fast_realloc(x4->sei_data, &x4->sei_data_size, (sei->num_payloads + 1) * sizeof(*sei_payload));
+ if (!tmp) {
+ av_freep(&x4->pic.extra_sei.payloads);
+ av_freep(&x4->pic.prop.quant_offsets);
+ return AVERROR(ENOMEM);
+ }
+ x4->sei_data = tmp;
+ sei->payloads = x4->sei_data;
+ sei_payload = &sei->payloads[sei->num_payloads];
+ sei_payload->payload = side_data->data;
+ sei_payload->payload_size = side_data->size;
+ sei_payload->payload_type = SEI_TYPE_USER_DATA_UNREGISTERED;
+ sei->num_payloads++;
+ }
}
do {
@@ -505,6 +533,8 @@ static av_cold int X264_close(AVCodecContext *avctx)
x264_param_cleanup(&x4->params);
#endif
+ av_freep(&x4->sei_data);
+
if (x4->enc) {
x264_encoder_close(x4->enc);
x4->enc = NULL;