Re: [libav-devel] [PATCH 11/16] cbs_h264: Add utility functions to insert/delete SEI messages

2018-02-18 Thread Luca Barbato

On 11/02/2018 19:14, Mark Thompson wrote:

---
  libavcodec/cbs_h264.h  | 19 +++
  libavcodec/cbs_h2645.c | 89 ++
  2 files changed, 108 insertions(+)



Seems fine.

___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

[libav-devel] [PATCH 11/16] cbs_h264: Add utility functions to insert/delete SEI messages

2018-02-11 Thread Mark Thompson
---
 libavcodec/cbs_h264.h  | 19 +++
 libavcodec/cbs_h2645.c | 89 ++
 2 files changed, 108 insertions(+)

diff --git a/libavcodec/cbs_h264.h b/libavcodec/cbs_h264.h
index 14ea69ae2..8c17680bb 100644
--- a/libavcodec/cbs_h264.h
+++ b/libavcodec/cbs_h264.h
@@ -22,6 +22,7 @@
 #include 
 #include 
 
+#include "cbs.h"
 #include "cbs_h2645.h"
 #include "h264.h"
 
@@ -428,4 +429,22 @@ typedef struct CodedBitstreamH264Context {
 } CodedBitstreamH264Context;
 
 
+/**
+ * Add an SEI message to an access unit.
+ */
+int ff_cbs_h264_add_sei_message(CodedBitstreamContext *ctx,
+CodedBitstreamFragment *access_unit,
+const H264RawSEIPayload *payload);
+
+/**
+ * Delete an SEI message from an access unit.
+ *
+ * Deletes from nal_unit, which must be an SEI NAL unit.  If this is the
+ * last message in nal_unit, also deletes it from access_unit.
+ */
+int ff_cbs_h264_delete_sei_message(CodedBitstreamContext *ctx,
+   CodedBitstreamFragment *access_unit,
+   CodedBitstreamUnit *nal_unit,
+   int position);
+
 #endif /* AVCODEC_CBS_H264_H */
diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c
index c98bab998..7b2e1b532 100644
--- a/libavcodec/cbs_h2645.c
+++ b/libavcodec/cbs_h2645.c
@@ -1394,3 +1394,92 @@ const CodedBitstreamType ff_cbs_type_h265 = {
 
 .close = _h265_close,
 };
+
+int ff_cbs_h264_add_sei_message(CodedBitstreamContext *ctx,
+CodedBitstreamFragment *au,
+const H264RawSEIPayload *payload)
+{
+H264RawSEI *sei;
+CodedBitstreamUnit *nal = NULL;
+int err, i;
+
+// Find an existing SEI NAL unit to add to.
+for (i = 0; i < au->nb_units; i++) {
+if (au->units[i].type == H264_NAL_SEI) {
+nal = >units[i];
+break;
+}
+}
+if (nal) {
+sei = nal->content;
+
+} else {
+// Need to make a new SEI NAL unit.  Insert it before the first
+// slice data NAL unit; if no slice data, add at the end.
+AVBufferRef *sei_ref;
+
+sei_ref = av_buffer_allocz(sizeof(*sei));
+if (!sei_ref)
+return AVERROR(ENOMEM);
+sei = (H264RawSEI*)sei_ref->data;
+
+sei->nal_unit_header.nal_unit_type = H264_NAL_SEI;
+sei->nal_unit_header.nal_ref_idc   = 0;
+
+for (i = 0; i < au->nb_units; i++) {
+if (au->units[i].type == H264_NAL_SLICE ||
+au->units[i].type == H264_NAL_IDR_SLICE)
+break;
+}
+
+err = ff_cbs_insert_unit_content(ctx, au, i, H264_NAL_SEI,
+ sei, sei_ref);
+av_buffer_unref(_ref);
+if (err < 0)
+return err;
+}
+
+if (sei->payload_count >= H264_MAX_SEI_PAYLOADS) {
+av_log(ctx->log_ctx, AV_LOG_ERROR, "Too many payloads in "
+   "SEI NAL unit.\n");
+return AVERROR(EINVAL);
+}
+
+memcpy(>payload[sei->payload_count], payload, sizeof(*payload));
+++sei->payload_count;
+
+return 0;
+}
+
+int ff_cbs_h264_delete_sei_message(CodedBitstreamContext *ctx,
+   CodedBitstreamFragment *au,
+   CodedBitstreamUnit *nal,
+   int position)
+{
+H264RawSEI *sei = nal->content;
+
+av_assert0(nal->type == H264_NAL_SEI);
+av_assert0(position >= 0 && position < sei->payload_count);
+
+if (position == 0 && sei->payload_count == 1) {
+// Deleting NAL unit entirely.
+int i;
+
+for (i = 0; i < au->nb_units; i++) {
+if (>units[i] == nal)
+break;
+}
+av_assert0(i < au->nb_units && "NAL unit not in access unit.");
+
+return ff_cbs_delete_unit(ctx, au, i);
+} else {
+cbs_h264_free_sei_payload(>payload[position]);
+
+--sei->payload_count;
+memmove(sei->payload + position,
+sei->payload + position + 1,
+(sei->payload_count - position) * sizeof(*sei->payload));
+
+return 0;
+}
+}
-- 
2.15.1

___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel