Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH 0/5] Bitstream filter support for A/53 Closed Captions
@ 2023-02-04  0:41 ffmpegagent
  2023-02-04  0:41 ` [FFmpeg-devel] [PATCH 1/5] cbs: Add some common code for read/write of miscellaneous user data Mark Thompson
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: ffmpegagent @ 2023-02-04  0:41 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Aman Gupta Karmani

cc: Aman Karmani aman@tmm1.net cc: Eric Lindvall eric@5stops.com cc: Mark
Thompson sw@jkqxz.net cc: David Engel david@istwok.net cc: Scott Theisen
scott.the.elm@gmail.com cc: Miguel Borges de Freitas 92enen@gmail.com

/cc https://github.com/MythTV/mythtv/issues/364 /cc
https://github.com/xbmc/xbmc/pull/22605 /cc
https://github.com/xbmc/xbmc/pull/22603 /cc
https://github.com/xbmc/xbmc/pull/22333

Aman Karmani (3):
  avcodec/mpeg2_metadata_bsf: add support for a/53 closed captions
  avcodec/h264_metadata_bsf: add support for a/53 closed captions
  avcodec/h265_metadata_bsf: add support for a/53 closed captions

Eric Lindvall (1):
  cbs_sei: add ff_cbs_sei_delete_message helper

Mark Thompson (1):
  cbs: Add some common code for read/write of miscellaneous user data

 doc/bitstream_filters.texi            |  33 ++++
 libavcodec/Makefile                   |   6 +-
 libavcodec/cbs_misc.c                 | 217 ++++++++++++++++++++++++++
 libavcodec/cbs_misc.h                 | 109 +++++++++++++
 libavcodec/cbs_misc_syntax_template.c | 150 ++++++++++++++++++
 libavcodec/cbs_sei.c                  |  25 +++
 libavcodec/cbs_sei.h                  |   7 +
 libavcodec/h264_metadata_bsf.c        | 144 +++++++++++++++++
 libavcodec/h265_metadata_bsf.c        | 144 +++++++++++++++++
 libavcodec/mpeg2_metadata_bsf.c       |  80 ++++++++++
 10 files changed, 912 insertions(+), 3 deletions(-)
 create mode 100644 libavcodec/cbs_misc.c
 create mode 100644 libavcodec/cbs_misc.h
 create mode 100644 libavcodec/cbs_misc_syntax_template.c


base-commit: 9a820ec8b1e2323b70a1cebd204bf459bf7daa1a
Published-As: https://github.com/ffstaging/FFmpeg/releases/tag/pr-ffstaging-50%2Ftmm1%2Fcbs-misc-a53-v3-v1
Fetch-It-Via: git fetch https://github.com/ffstaging/FFmpeg pr-ffstaging-50/tmm1/cbs-misc-a53-v3-v1
Pull-Request: https://github.com/ffstaging/FFmpeg/pull/50
-- 
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [FFmpeg-devel] [PATCH 1/5] cbs: Add some common code for read/write of miscellaneous user data
  2023-02-04  0:41 [FFmpeg-devel] [PATCH 0/5] Bitstream filter support for A/53 Closed Captions ffmpegagent
@ 2023-02-04  0:41 ` Mark Thompson
  2023-02-04  0:41 ` [FFmpeg-devel] [PATCH 2/5] cbs_sei: add ff_cbs_sei_delete_message helper Eric Lindvall
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Mark Thompson @ 2023-02-04  0:41 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Mark Thompson, Aman Gupta Karmani

From: Mark Thompson <sw@jkqxz.net>

Supports closed captions, active format and bar data as defined by
SCTE 128 part 1 or A/53 part 4, suitable for use with both MPEG-2
and H.264.

Signed-off-by: Aman Karmani <aman@tmm1.net>
---
 libavcodec/cbs_misc.c                 | 217 ++++++++++++++++++++++++++
 libavcodec/cbs_misc.h                 | 109 +++++++++++++
 libavcodec/cbs_misc_syntax_template.c | 150 ++++++++++++++++++
 3 files changed, 476 insertions(+)
 create mode 100644 libavcodec/cbs_misc.c
 create mode 100644 libavcodec/cbs_misc.h
 create mode 100644 libavcodec/cbs_misc_syntax_template.c

diff --git a/libavcodec/cbs_misc.c b/libavcodec/cbs_misc.c
new file mode 100644
index 0000000000..d0ced562f5
--- /dev/null
+++ b/libavcodec/cbs_misc.c
@@ -0,0 +1,217 @@
+/*
+ * 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 "libavutil/attributes.h"
+#include "libavutil/avassert.h"
+
+#include "cbs.h"
+#include "cbs_internal.h"
+#include "cbs_misc.h"
+
+#define CHECK(call) do { \
+        err = (call); \
+        if (err < 0) \
+            return err; \
+    } while (0)
+
+#define FUNC_NAME(rw, codec, name) cbs_ ## codec ## _ ## rw ## _ ## name
+#define FUNC_MISC(rw, name) FUNC_NAME(rw, misc, name)
+#define FUNC(name) FUNC_MISC(READWRITE, name)
+
+
+#define READWRITE read
+#define RWContext GetBitContext
+
+#define xui(width, name, var) do { \
+        uint32_t value = 0; \
+        CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, NULL, \
+                                   &value, 0, MAX_UINT_BITS(width))); \
+        var = value; \
+    } while (0)
+
+#define ui(width, name) \
+        xui(width, name, current->name)
+
+#define fixed(width, name, expected) do { \
+        av_unused uint32_t value; \
+        CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, NULL, \
+                                   &value, expected, expected)); \
+    } while (0)
+
+#include "cbs_misc_syntax_template.c"
+
+#undef READWRITE
+#undef RWContext
+#undef xui
+#undef ui
+#undef fixed
+
+
+#define READWRITE write
+#define RWContext PutBitContext
+
+#define xui(width, name, var) do { \
+        CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, NULL, \
+                                    var, 0, MAX_UINT_BITS(width))); \
+    } while (0)
+
+#define ui(width, name) \
+        xui(width, name, current->name)
+
+#define fixed(width, name, value) do { \
+        CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, NULL, \
+                                    value, value, value)); \
+    } while (0)
+
+#include "cbs_misc_syntax_template.c"
+
+#undef READWRITE
+#undef RWContext
+#undef xui
+#undef ui
+#undef fixed
+
+
+int ff_cbs_read_a53_user_data(CodedBitstreamContext *ctx,
+                              A53UserData *data,
+                              const uint8_t *read_buffer, size_t length)
+{
+    GetBitContext gbc;
+    int err;
+
+    err = init_get_bits(&gbc, read_buffer, 8 * length);
+    if (err < 0)
+        return err;
+
+    return cbs_misc_read_a53_user_data(ctx, &gbc, data);
+}
+
+int ff_cbs_write_a53_user_data(CodedBitstreamContext *ctx,
+                               uint8_t *write_buffer, size_t *length,
+                               A53UserData *data)
+{
+    PutBitContext pbc;
+    int err;
+
+    init_put_bits(&pbc, write_buffer, *length);
+
+    err = cbs_misc_write_a53_user_data(ctx, &pbc, data);
+    if (err < 0) {
+        // Includes AVERROR(ENOSPC).
+        return err;
+    }
+
+    // That output must be aligned.
+    av_assert0(put_bits_count(&pbc) % 8 == 0);
+
+    *length = put_bits_count(&pbc) / 8;
+
+    flush_put_bits(&pbc);
+
+    return 0;
+}
+
+int ff_cbs_read_a53_cc_side_data(CodedBitstreamContext *ctx,
+                                 A53UserData *data,
+                                 const uint8_t *side_data,
+                                 size_t side_data_size)
+{
+    GetBitContext gbc;
+    CEA708CCData *cc;
+    int err, i, cc_count;
+
+    if (side_data_size % 3) {
+        av_log(ctx->log_ctx, AV_LOG_ERROR, "A53 CC side data length must "
+               "be a multiple of 3 (got %zu).\n", side_data_size);
+        return AVERROR(EINVAL);
+    }
+    cc_count = side_data_size / 3;
+    if (cc_count > 31) {
+        av_log(ctx->log_ctx, AV_LOG_ERROR, "A53 CC can only fit 31 packets "
+               "in a single user data block (got %d).\n", cc_count);
+        return AVERROR(EINVAL);
+    }
+
+    *data = (A53UserData) {
+        .user_identifier = A53_USER_IDENTIFIER_ATSC,
+
+        .atsc = {
+            .user_data_type_code = A53_USER_DATA_TYPE_CODE_CC_DATA,
+
+            .cc_data = {
+                .process_em_data_flag = 0,
+                .process_cc_data_flag = 1,
+                .additional_data_flag = 0,
+
+                .em_data = 0,
+
+                .cc_count = cc_count,
+            },
+        },
+    };
+    cc = &data->atsc.cc_data;
+
+    err = init_get_bits(&gbc, side_data, 8 * side_data_size);
+    if (err < 0)
+        return err;
+
+    for (i = 0; i < cc->cc_count; i++) {
+        err = cbs_misc_read_cea708_cc_data_packet(ctx, &gbc,
+                                                  &cc->cc_data_pkts[i]);
+        if (err < 0)
+            return err;
+    }
+
+    return 0;
+}
+
+int ff_cbs_write_a53_cc_side_data(CodedBitstreamContext *ctx,
+                                  uint8_t **side_data,
+                                  size_t *side_data_size,
+                                  A53UserData *data)
+{
+    PutBitContext pbc;
+    CEA708CCData *cc;
+    int err, i;
+
+    if (data->user_identifier != A53_USER_IDENTIFIER_ATSC ||
+        data->atsc.user_data_type_code != A53_USER_DATA_TYPE_CODE_CC_DATA)
+        return AVERROR(EINVAL);
+
+    cc = &data->atsc.cc_data;
+
+    err = av_reallocp(side_data, *side_data_size + 3 * cc->cc_count);
+    if (err < 0)
+        return err;
+
+    init_put_bits(&pbc, *side_data + *side_data_size, 3 * cc->cc_count);
+
+    for (i = 0; i < cc->cc_count; i++) {
+        err = cbs_misc_write_cea708_cc_data_packet(ctx, &pbc,
+                                                   &cc->cc_data_pkts[i]);
+        if (err < 0) {
+            av_freep(side_data);
+            return err;
+        }
+    }
+
+    flush_put_bits(&pbc);
+    *side_data_size += 3 * cc->cc_count;
+
+    return 0;
+}
diff --git a/libavcodec/cbs_misc.h b/libavcodec/cbs_misc.h
new file mode 100644
index 0000000000..0d7ab2c8e7
--- /dev/null
+++ b/libavcodec/cbs_misc.h
@@ -0,0 +1,109 @@
+/*
+ * 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_CBS_MISC_H
+#define AVCODEC_CBS_MISC_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "libavutil/common.h"
+
+
+enum {
+    A53_USER_IDENTIFIER_ATSC = MKBETAG('G', 'A', '9', '4'),
+    A53_USER_IDENTIFIER_AFD  = MKBETAG('D', 'T', 'G', '1'),
+};
+
+enum {
+    A53_USER_DATA_TYPE_CODE_CC_DATA  = 0x03,
+    A53_USER_DATA_TYPE_CODE_BAR_DATA = 0x06,
+};
+
+typedef struct A53BarData {
+    uint8_t top_bar_flag;
+    uint8_t bottom_bar_flag;
+    uint8_t left_bar_flag;
+    uint8_t right_bar_flag;
+
+    uint16_t line_number_end_of_top_bar;
+    uint16_t line_number_end_of_bottom_bar;
+    uint16_t line_number_end_of_left_bar;
+    uint16_t line_number_end_of_right_bar;
+} A53BarData;
+
+typedef struct CEA708CCDataPacket {
+    uint8_t cc_valid;
+    uint8_t cc_type;
+    uint8_t cc_data_1;
+    uint8_t cc_data_2;
+} CEA708CCDataPacket;
+
+typedef struct CEA708CCData {
+    uint8_t process_em_data_flag;
+    uint8_t process_cc_data_flag;
+    uint8_t additional_data_flag;
+
+    uint8_t em_data;
+
+    uint8_t cc_count;
+    CEA708CCDataPacket cc_data_pkts[31];
+} CEA708CCData;
+
+typedef struct A53ATSCUserData {
+    uint8_t user_data_type_code;
+    union {
+        CEA708CCData cc_data;
+        A53BarData bar_data;
+    };
+} A53ATSCUserData;
+
+typedef struct A53AFDData {
+    uint8_t active_format_flag;
+    uint8_t active_format;
+} A53AFDData;
+
+typedef struct A53UserData {
+    uint32_t user_identifier;
+    union {
+        A53ATSCUserData atsc;
+        A53AFDData afd;
+    };
+} A53UserData;
+
+
+int ff_cbs_read_a53_user_data(CodedBitstreamContext *ctx,
+                              A53UserData *data,
+                              const uint8_t *read_buffer, size_t length);
+
+int ff_cbs_write_a53_user_data(CodedBitstreamContext *ctx,
+                               uint8_t *write_buffer, size_t *length,
+                               A53UserData *data);
+
+int ff_cbs_read_a53_cc_side_data(CodedBitstreamContext *ctx,
+                                 A53UserData *data,
+                                 const uint8_t *side_data,
+                                 size_t side_data_size);
+
+int ff_cbs_write_a53_cc_side_data(CodedBitstreamContext *ctx,
+                                  uint8_t **side_data,
+                                  size_t *side_data_length,
+                                  A53UserData *data);
+
+
+#endif /* AVCODEC_CBS_MISC_H */
diff --git a/libavcodec/cbs_misc_syntax_template.c b/libavcodec/cbs_misc_syntax_template.c
new file mode 100644
index 0000000000..7b98c7cc85
--- /dev/null
+++ b/libavcodec/cbs_misc_syntax_template.c
@@ -0,0 +1,150 @@
+/*
+ * 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
+ */
+
+static int FUNC(a53_bar_data)(CodedBitstreamContext *ctx, RWContext *rw,
+                              A53BarData *current)
+{
+    int err;
+
+    ui(1, top_bar_flag);
+    ui(1, bottom_bar_flag);
+    ui(1, left_bar_flag);
+    ui(1, right_bar_flag);
+    fixed(4, reserved, 0xf);
+
+    if (current->top_bar_flag) {
+        fixed(2, one_bits, 3);
+        ui(14, line_number_end_of_top_bar);
+    }
+    if (current->bottom_bar_flag) {
+        fixed(2, one_bits, 3);
+        ui(14, line_number_end_of_bottom_bar);
+    }
+    if (current->left_bar_flag) {
+        fixed(2, one_bits, 3);
+        ui(14, line_number_end_of_left_bar);
+    }
+    if (current->right_bar_flag) {
+        fixed(2, one_bits, 3);
+        ui(14, line_number_end_of_right_bar);
+    }
+
+    return 0;
+}
+
+static int FUNC(cea708_cc_data_packet)(CodedBitstreamContext *ctx,
+                                       RWContext *rw,
+                                       CEA708CCDataPacket *current)
+{
+    int err;
+
+    fixed(5, marker_bits, 0x1f);
+    ui(1, cc_valid);
+    ui(2, cc_type);
+
+    ui(8, cc_data_1);
+    ui(8, cc_data_2);
+
+    return 0;
+}
+
+static int FUNC(cea708_cc_data)(CodedBitstreamContext *ctx, RWContext *rw,
+                                CEA708CCData *current)
+{
+    int err, i;
+
+    ui(1, process_em_data_flag);
+    ui(1, process_cc_data_flag);
+    ui(1, additional_data_flag);
+
+    ui(5, cc_count);
+
+    ui(8, em_data);
+
+    for (i = 0; i < current->cc_count; i++) {
+        CHECK(FUNC(cea708_cc_data_packet)(ctx, rw,
+                                          &current->cc_data_pkts[i]));
+    }
+
+    fixed(8, marker_bits, 0xff);
+
+    if (current->additional_data_flag) {
+        // Ignored.
+    }
+
+    return 0;
+}
+
+static int FUNC(a53_atsc_user_data)(CodedBitstreamContext *ctx, RWContext *rw,
+                                    A53ATSCUserData *current)
+{
+    int err;
+
+    ui(8, user_data_type_code);
+
+    switch (current->user_data_type_code) {
+    case A53_USER_DATA_TYPE_CODE_CC_DATA:
+        return FUNC(cea708_cc_data)(ctx, rw, &current->cc_data);
+    case A53_USER_DATA_TYPE_CODE_BAR_DATA:
+        return FUNC(a53_bar_data)(ctx, rw, &current->bar_data);
+    default:
+        av_log(ctx->log_ctx, AV_LOG_WARNING,
+               "Unknown ATSC user data found: type code %#02x.\n",
+               current->user_data_type_code);
+    }
+
+    return 0;
+}
+
+static int FUNC(a53_afd_data)(CodedBitstreamContext *ctx, RWContext *rw,
+                              A53AFDData *current)
+{
+    int err;
+
+    fixed(1, zero_bit, 0);
+    ui(1, active_format_flag);
+    fixed(6, alignment_bits, 1);
+
+    if (current->active_format_flag) {
+        fixed(4, reserved, 0xf);
+        ui(4, active_format);
+    }
+
+    return 0;
+}
+
+static int FUNC(a53_user_data)(CodedBitstreamContext *ctx, RWContext *rw,
+                               A53UserData *current)
+{
+    int err;
+
+    ui(32, user_identifier);
+
+    switch (current->user_identifier) {
+    case A53_USER_IDENTIFIER_ATSC:
+        return FUNC(a53_atsc_user_data)(ctx, rw, &current->atsc);
+    case A53_USER_IDENTIFIER_AFD:
+        return FUNC(a53_afd_data)(ctx, rw, &current->afd);
+    default:
+        av_log(ctx->log_ctx, AV_LOG_WARNING,
+               "Unknown registered user data found: identifier %#08x.\n",
+               current->user_identifier);
+    }
+
+    return 0;
+}
-- 
ffmpeg-codebot

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [FFmpeg-devel] [PATCH 2/5] cbs_sei: add ff_cbs_sei_delete_message helper
  2023-02-04  0:41 [FFmpeg-devel] [PATCH 0/5] Bitstream filter support for A/53 Closed Captions ffmpegagent
  2023-02-04  0:41 ` [FFmpeg-devel] [PATCH 1/5] cbs: Add some common code for read/write of miscellaneous user data Mark Thompson
@ 2023-02-04  0:41 ` Eric Lindvall
  2023-02-04  0:41 ` [FFmpeg-devel] [PATCH 3/5] avcodec/mpeg2_metadata_bsf: add support for a/53 closed captions Aman Karmani
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Eric Lindvall @ 2023-02-04  0:41 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Eric Lindvall, Aman Gupta Karmani

From: Eric Lindvall <eric@5stops.com>

Signed-off-by: Aman Karmani <aman@tmm1.net>
---
 libavcodec/cbs_sei.c | 25 +++++++++++++++++++++++++
 libavcodec/cbs_sei.h |  7 +++++++
 2 files changed, 32 insertions(+)

diff --git a/libavcodec/cbs_sei.c b/libavcodec/cbs_sei.c
index 50a513f592..1ea2bbc109 100644
--- a/libavcodec/cbs_sei.c
+++ b/libavcodec/cbs_sei.c
@@ -347,6 +347,31 @@ static void cbs_sei_delete_message(SEIRawMessageList *list,
     }
 }
 
+int ff_cbs_sei_delete_message(CodedBitstreamContext *ctx,
+                               CodedBitstreamFragment *au,
+                               SEIRawMessage *message)
+{
+    int err, i, j;
+
+    for (i = 0; i < au->nb_units; i++) {
+        CodedBitstreamUnit *unit = &au->units[i];
+        SEIRawMessageList *list;
+
+        err = cbs_sei_get_message_list(ctx, unit, &list);
+        if (err < 0)
+            continue;
+
+        for (j = 0; j < list->nb_messages; j++) {
+            if (message == &list->messages[j]) {
+                cbs_sei_delete_message(list, j);
+                return 0;
+            }
+        }
+    }
+
+    return AVERROR(ENOENT);
+}
+
 void ff_cbs_sei_delete_message_type(CodedBitstreamContext *ctx,
                                     CodedBitstreamFragment *au,
                                     uint32_t payload_type)
diff --git a/libavcodec/cbs_sei.h b/libavcodec/cbs_sei.h
index 1c327a4689..96bd116a53 100644
--- a/libavcodec/cbs_sei.h
+++ b/libavcodec/cbs_sei.h
@@ -202,4 +202,11 @@ void ff_cbs_sei_delete_message_type(CodedBitstreamContext *ctx,
                                     CodedBitstreamFragment *au,
                                     uint32_t payload_type);
 
+/**
+ * Delete a message from the access unit.
+ */
+int ff_cbs_sei_delete_message(CodedBitstreamContext *ctx,
+                              CodedBitstreamFragment *au,
+                              SEIRawMessage *message);
+
 #endif /* AVCODEC_CBS_SEI_H */
-- 
ffmpeg-codebot

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [FFmpeg-devel] [PATCH 3/5] avcodec/mpeg2_metadata_bsf: add support for a/53 closed captions
  2023-02-04  0:41 [FFmpeg-devel] [PATCH 0/5] Bitstream filter support for A/53 Closed Captions ffmpegagent
  2023-02-04  0:41 ` [FFmpeg-devel] [PATCH 1/5] cbs: Add some common code for read/write of miscellaneous user data Mark Thompson
  2023-02-04  0:41 ` [FFmpeg-devel] [PATCH 2/5] cbs_sei: add ff_cbs_sei_delete_message helper Eric Lindvall
@ 2023-02-04  0:41 ` Aman Karmani
  2023-02-04  0:41 ` [FFmpeg-devel] [PATCH 4/5] avcodec/h264_metadata_bsf: " Aman Karmani
  2023-02-04  0:41 ` [FFmpeg-devel] [PATCH 5/5] avcodec/h265_metadata_bsf: " Aman Karmani
  4 siblings, 0 replies; 6+ messages in thread
From: Aman Karmani @ 2023-02-04  0:41 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Aman Karmani

From: Aman Karmani <aman@tmm1.net>

Signed-off-by: Aman Karmani <aman@tmm1.net>
---
 doc/bitstream_filters.texi      | 11 +++++
 libavcodec/Makefile             |  2 +-
 libavcodec/mpeg2_metadata_bsf.c | 80 +++++++++++++++++++++++++++++++++
 3 files changed, 92 insertions(+), 1 deletion(-)

diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi
index c63c20370f..c036d37403 100644
--- a/doc/bitstream_filters.texi
+++ b/doc/bitstream_filters.texi
@@ -537,6 +537,17 @@ Decompress non-standard compressed MP3 audio headers.
 Modify metadata embedded in an MPEG-2 stream.
 
 @table @option
+@item a53_cc
+Insert or remove user data containing A/53 closed captions.
+
+@table @samp
+@item pass
+@item insert
+@item remove
+@end table
+
+Default is pass.
+
 @item display_aspect_ratio
 Set the display aspect ratio in the stream.
 
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 1fb963f820..2a36a31ff2 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1227,7 +1227,7 @@ OBJS-$(CONFIG_MPEG4_UNPACK_BFRAMES_BSF)   += mpeg4_unpack_bframes_bsf.o
 OBJS-$(CONFIG_MOV2TEXTSUB_BSF)            += movsub_bsf.o
 OBJS-$(CONFIG_MP3_HEADER_DECOMPRESS_BSF)  += mp3_header_decompress_bsf.o \
                                              mpegaudiotabs.o
-OBJS-$(CONFIG_MPEG2_METADATA_BSF)         += mpeg2_metadata_bsf.o
+OBJS-$(CONFIG_MPEG2_METADATA_BSF)         += mpeg2_metadata_bsf.o cbs_misc.o
 OBJS-$(CONFIG_NOISE_BSF)                  += noise_bsf.o
 OBJS-$(CONFIG_NULL_BSF)                   += null_bsf.o
 OBJS-$(CONFIG_OPUS_METADATA_BSF)          += opus_metadata_bsf.o
diff --git a/libavcodec/mpeg2_metadata_bsf.c b/libavcodec/mpeg2_metadata_bsf.c
index 1aa6e02791..888bace6b2 100644
--- a/libavcodec/mpeg2_metadata_bsf.c
+++ b/libavcodec/mpeg2_metadata_bsf.c
@@ -23,6 +23,7 @@
 #include "bsf_internal.h"
 #include "cbs.h"
 #include "cbs_bsf.h"
+#include "cbs_misc.h"
 #include "cbs_mpeg2.h"
 #include "mpeg12.h"
 
@@ -39,10 +40,79 @@ typedef struct MPEG2MetadataContext {
     int colour_primaries;
     int transfer_characteristics;
     int matrix_coefficients;
+    int a53_cc;
 
     int mpeg1_warned;
 } MPEG2MetadataContext;
 
+static int mpeg2_metadata_handle_a53_cc(AVBSFContext *bsf,
+                                          AVPacket *pkt,
+                                          CodedBitstreamFragment *frag)
+{
+    MPEG2MetadataContext *ctx = bsf->priv_data;
+    int err, i;
+    uint8_t *a53_side_data = NULL;
+    size_t a53_side_data_size = 0;
+
+    if (ctx->a53_cc == BSF_ELEMENT_REMOVE || ctx->a53_cc == BSF_ELEMENT_EXTRACT) {
+        for (i = 0; i < frag->nb_units; i++) {
+            MPEG2RawUserData *ud;
+            A53UserData a53_ud;
+
+            if (frag->units[i].type != MPEG2_START_USER_DATA)
+                continue;
+            ud = frag->units[i].content;
+
+            err = ff_cbs_read_a53_user_data(ctx->common.output, &a53_ud, ud->user_data,
+                                            ud->user_data_length);
+            if (err < 0) {
+                // Invalid or something completely different.
+                continue;
+            }
+            if (a53_ud.user_identifier != A53_USER_IDENTIFIER_ATSC ||
+                a53_ud.atsc.user_data_type_code !=
+                    A53_USER_DATA_TYPE_CODE_CC_DATA) {
+                // Valid but something else (e.g. AFD).
+                continue;
+            }
+
+            if (ctx->a53_cc == BSF_ELEMENT_REMOVE) {
+                ff_cbs_delete_unit(frag, i);
+                --i;
+                break;
+            } else if(ctx->a53_cc == BSF_ELEMENT_EXTRACT) {
+                err = ff_cbs_write_a53_cc_side_data(ctx->common.output,
+                                                    &a53_side_data,
+                                                    &a53_side_data_size,
+                                                    &a53_ud);
+                if (err < 0) {
+                    av_log(bsf, AV_LOG_ERROR, "Failed to write "
+                           "A/53 user data for packet side data.\n");
+                    goto fail;
+                }
+
+                if (a53_side_data) {
+                    err = av_packet_add_side_data(pkt, AV_PKT_DATA_A53_CC,
+                                                  a53_side_data, a53_side_data_size);
+                    if (err) {
+                        av_log(bsf, AV_LOG_ERROR, "Failed to attach extracted A/53 "
+                               "side data to packet.\n");
+                        goto fail;
+                    }
+                    a53_side_data = NULL;
+                }
+            }
+        }
+    }
+
+    err = 0;
+
+fail:
+    av_freep(&a53_side_data);
+
+    return err;
+}
+
 
 static int mpeg2_metadata_update_fragment(AVBSFContext *bsf,
                                           AVPacket *pkt,
@@ -54,6 +124,13 @@ static int mpeg2_metadata_update_fragment(AVBSFContext *bsf,
     MPEG2RawSequenceDisplayExtension *sde = NULL;
     int i, se_pos;
 
+    if (pkt && ctx->a53_cc != BSF_ELEMENT_PASS) {
+        int err;
+        err = mpeg2_metadata_handle_a53_cc(bsf, pkt, frag);
+        if (err < 0)
+            return err;
+    }
+
     for (i = 0; i < frag->nb_units; i++) {
         if (frag->units[i].type == MPEG2_START_SEQUENCE_HEADER) {
             sh = frag->units[i].content;
@@ -218,6 +295,9 @@ static const AVOption mpeg2_metadata_options[] = {
         OFFSET(matrix_coefficients), AV_OPT_TYPE_INT,
         { .i64 = -1 }, -1, 255, FLAGS },
 
+    BSF_ELEMENT_OPTIONS_PIRE("a53_cc",
+                             "A/53 Closed Captions in user data",
+                             a53_cc, FLAGS),
     { NULL }
 };
 
-- 
ffmpeg-codebot

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [FFmpeg-devel] [PATCH 4/5] avcodec/h264_metadata_bsf: add support for a/53 closed captions
  2023-02-04  0:41 [FFmpeg-devel] [PATCH 0/5] Bitstream filter support for A/53 Closed Captions ffmpegagent
                   ` (2 preceding siblings ...)
  2023-02-04  0:41 ` [FFmpeg-devel] [PATCH 3/5] avcodec/mpeg2_metadata_bsf: add support for a/53 closed captions Aman Karmani
@ 2023-02-04  0:41 ` Aman Karmani
  2023-02-04  0:41 ` [FFmpeg-devel] [PATCH 5/5] avcodec/h265_metadata_bsf: " Aman Karmani
  4 siblings, 0 replies; 6+ messages in thread
From: Aman Karmani @ 2023-02-04  0:41 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Aman Karmani

From: Aman Karmani <aman@tmm1.net>

Signed-off-by: Aman Karmani <aman@tmm1.net>
---
 doc/bitstream_filters.texi     |  11 +++
 libavcodec/Makefile            |   2 +-
 libavcodec/h264_metadata_bsf.c | 144 +++++++++++++++++++++++++++++++++
 3 files changed, 156 insertions(+), 1 deletion(-)

diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi
index c036d37403..3d97f66315 100644
--- a/doc/bitstream_filters.texi
+++ b/doc/bitstream_filters.texi
@@ -243,6 +243,17 @@ ffmpeg -i hapqa_inputfile.mov -c copy -bsf:v hapqa_extract=texture=alpha -tag:v
 Modify metadata embedded in an H.264 stream.
 
 @table @option
+@item a53_cc
+Insert or remove registered userdata SEI NAL units containing A/53 closed captions.
+
+@table @samp
+@item pass
+@item insert
+@item remove
+@end table
+
+Default is pass.
+
 @item aud
 Insert or remove AUD NAL units in all access units of the stream.
 
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 2a36a31ff2..9f97c9b5e5 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1212,7 +1212,7 @@ OBJS-$(CONFIG_EXTRACT_EXTRADATA_BSF)      += extract_extradata_bsf.o    \
                                              av1_parse.o h2645_parse.o
 OBJS-$(CONFIG_FILTER_UNITS_BSF)           += filter_units_bsf.o
 OBJS-$(CONFIG_H264_METADATA_BSF)          += h264_metadata_bsf.o h264_levels.o \
-                                             h2645data.o
+                                             h2645data.o cbs_misc.o
 OBJS-$(CONFIG_H264_MP4TOANNEXB_BSF)       += h264_mp4toannexb_bsf.o
 OBJS-$(CONFIG_H264_REDUNDANT_PPS_BSF)     += h264_redundant_pps_bsf.o
 OBJS-$(CONFIG_HAPQA_EXTRACT_BSF)          += hapqa_extract_bsf.o hap.o
diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c
index d318bf0cee..bbe74c3cee 100644
--- a/libavcodec/h264_metadata_bsf.c
+++ b/libavcodec/h264_metadata_bsf.c
@@ -26,6 +26,8 @@
 #include "cbs.h"
 #include "cbs_bsf.h"
 #include "cbs_h264.h"
+#include "cbs_misc.h"
+#include "cbs_sei.h"
 #include "h264.h"
 #include "h264_levels.h"
 #include "h264_sei.h"
@@ -81,6 +83,7 @@ typedef struct H264MetadataContext {
     H264RawSEIDisplayOrientation display_orientation_payload;
 
     int level;
+    int a53_cc;
 } H264MetadataContext;
 
 
@@ -463,6 +466,137 @@ static int h264_metadata_handle_display_orientation(AVBSFContext *bsf,
     return 0;
 }
 
+static int h264_metadata_handle_a53_cc(AVBSFContext *bsf, AVPacket *pkt,
+                                         CodedBitstreamFragment *au)
+{
+    H264MetadataContext *ctx = bsf->priv_data;
+    SEIRawMessage *message;
+    int err;
+
+    message = NULL;
+    while (ff_cbs_sei_find_message(ctx->common.output, au,
+                                   SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35,
+                                   &message) == 0) {
+        SEIRawUserDataRegistered *udr = message->payload;
+        A53UserData a53_ud;
+        uint8_t *a53_side_data = NULL;
+        size_t a53_side_data_size = 0;
+
+        if (udr->data_length < 2) {
+            // Too short to contain a provider code.
+            continue;
+        }
+
+        if (AV_RB16(udr->data) != 0x31) { // provider_code as atsc_provider_code
+            // Not ATSC.
+            continue;
+        }
+
+        // The first two bytes of the message is provider_code so we offset the data by that
+        err = ff_cbs_read_a53_user_data(ctx->common.output,
+                                        &a53_ud,
+                                        udr->data + 2,
+                                        udr->data_length - 2);
+        if (err < 0) {
+            // Invalid or something completely different.
+            continue;
+        }
+        if (a53_ud.user_identifier != A53_USER_IDENTIFIER_ATSC ||
+            a53_ud.atsc.user_data_type_code !=
+                A53_USER_DATA_TYPE_CODE_CC_DATA) {
+            // Valid but something else (e.g. AFD).
+            continue;
+        }
+
+        err = ff_cbs_write_a53_cc_side_data(ctx->common.output,
+                                            &a53_side_data,
+                                            &a53_side_data_size,
+                                            &a53_ud);
+        if (err < 0) {
+            av_log(bsf, AV_LOG_ERROR, "Failed to write "
+                    "A/53 user data for packet side data.\n");
+            return err;
+        }
+
+        if (a53_side_data) {
+            err = av_packet_add_side_data(pkt, AV_PKT_DATA_A53_CC,
+                                          a53_side_data, a53_side_data_size);
+            if (err) {
+                av_log(bsf, AV_LOG_ERROR, "Failed to attach extracted A/53 "
+                        "side data to packet.\n");
+                av_freep(&a53_side_data);
+                return err;
+            }
+
+            if (ctx->a53_cc == BSF_ELEMENT_REMOVE ||
+                ctx->a53_cc == BSF_ELEMENT_INSERT) {
+                ff_cbs_sei_delete_message(ctx->common.output, au, message);
+
+                // Reset iteration
+                message = NULL;
+            }
+        }
+    }
+
+    if (ctx->a53_cc == BSF_ELEMENT_INSERT) {
+        uint8_t *data;
+        size_t size;
+        int offset = 0;
+
+        data = av_packet_get_side_data(pkt, AV_PKT_DATA_A53_CC, &size);
+        while (size > 0) {
+            A53UserData a53_ud;
+            int rsize = FFMIN(93, size);
+
+            err = ff_cbs_read_a53_cc_side_data(ctx->common.output, &a53_ud,
+                                               data + offset, rsize);
+            offset += rsize;
+            size -= rsize;
+            if (err < 0) {
+                av_log(bsf, AV_LOG_WARNING, "Invalid A/53 closed captions "
+                       "in packet side data dropped.\n");
+            } else {
+                AVBufferRef *udr_buf = av_buffer_allocz(sizeof(SEIRawUserDataRegistered));
+                SEIRawUserDataRegistered *udr = (SEIRawUserDataRegistered*)udr_buf->data;
+                size_t size = 9 + 3 * a53_ud.atsc.cc_data.cc_count;
+
+                udr->data_ref = av_buffer_allocz(2 + size);
+                if (!udr->data_ref) {
+                    return AVERROR(ENOMEM);
+                }
+                udr->data = udr->data_ref->data;
+                udr->data_length = udr->data_ref->size;
+
+                udr->itu_t_t35_country_code = 0xB5; // usa_country_code
+                AV_WB16(udr->data, 0x31);           // provider_code as atsc_provider_code
+
+                err = ff_cbs_write_a53_user_data(ctx->common.output, udr->data + 2,
+                                                 &size, &a53_ud);
+                if (err < 0) {
+                    av_log(bsf, AV_LOG_ERROR, "Failed to write "
+                           "A/53 user data.\n");
+                    av_buffer_unref(&udr->data_ref);
+                    av_buffer_unref(&udr_buf);
+                    return err;
+                }
+
+                err = ff_cbs_sei_add_message(ctx->common.output, au, 1,
+                                             SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35,
+                                             udr, udr_buf);
+                if (err < 0) {
+                    av_log(bsf, AV_LOG_ERROR, "Failed to add A/53 user data "
+                           "SEI message to access unit.\n");
+                    av_buffer_unref(&udr->data_ref);
+                    av_buffer_unref(&udr_buf);
+                    return err;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
 static int h264_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt,
                                          CodedBitstreamFragment *au)
 {
@@ -533,6 +667,12 @@ static int h264_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt,
             return err;
     }
 
+    if (pkt && ctx->a53_cc != BSF_ELEMENT_PASS) {
+        err = h264_metadata_handle_a53_cc(bsf, pkt, au);
+        if (err < 0)
+            return err;
+    }
+
     if (pkt)
         ctx->done_first_au = 1;
 
@@ -696,6 +836,10 @@ static const AVOption h264_metadata_options[] = {
     { LEVEL("6.2", 62) },
 #undef LEVEL
 
+    BSF_ELEMENT_OPTIONS_PIRE("a53_cc",
+                             "A/53 Closed Captions in SEI NAL units",
+                             a53_cc, FLAGS),
+
     { NULL }
 };
 
-- 
ffmpeg-codebot

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [FFmpeg-devel] [PATCH 5/5] avcodec/h265_metadata_bsf: add support for a/53 closed captions
  2023-02-04  0:41 [FFmpeg-devel] [PATCH 0/5] Bitstream filter support for A/53 Closed Captions ffmpegagent
                   ` (3 preceding siblings ...)
  2023-02-04  0:41 ` [FFmpeg-devel] [PATCH 4/5] avcodec/h264_metadata_bsf: " Aman Karmani
@ 2023-02-04  0:41 ` Aman Karmani
  4 siblings, 0 replies; 6+ messages in thread
From: Aman Karmani @ 2023-02-04  0:41 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Aman Karmani

From: Aman Karmani <aman@tmm1.net>

Signed-off-by: Aman Karmani <aman@tmm1.net>
---
 doc/bitstream_filters.texi     |  11 +++
 libavcodec/Makefile            |   2 +-
 libavcodec/h265_metadata_bsf.c | 144 +++++++++++++++++++++++++++++++++
 3 files changed, 156 insertions(+), 1 deletion(-)

diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi
index 3d97f66315..57f8682d9f 100644
--- a/doc/bitstream_filters.texi
+++ b/doc/bitstream_filters.texi
@@ -398,6 +398,17 @@ confuse other transformations which require correct extradata.
 Modify metadata embedded in an HEVC stream.
 
 @table @option
+@item a53_cc
+Insert or remove registered userdata SEI NAL units containing A/53 closed captions.
+
+@table @samp
+@item pass
+@item insert
+@item remove
+@end table
+
+Default is pass.
+
 @item aud
 Insert or remove AUD NAL units in all access units of the stream.
 
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 9f97c9b5e5..156fd6215a 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1217,7 +1217,7 @@ OBJS-$(CONFIG_H264_MP4TOANNEXB_BSF)       += h264_mp4toannexb_bsf.o
 OBJS-$(CONFIG_H264_REDUNDANT_PPS_BSF)     += h264_redundant_pps_bsf.o
 OBJS-$(CONFIG_HAPQA_EXTRACT_BSF)          += hapqa_extract_bsf.o hap.o
 OBJS-$(CONFIG_HEVC_METADATA_BSF)          += h265_metadata_bsf.o h265_profile_level.o \
-                                             h2645data.o
+                                             h2645data.o cbs_misc.o
 OBJS-$(CONFIG_HEVC_MP4TOANNEXB_BSF)       += hevc_mp4toannexb_bsf.o
 OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF)        += imx_dump_header_bsf.o
 OBJS-$(CONFIG_MEDIA100_TO_MJPEGB_BSF)     += media100_to_mjpegb_bsf.o
diff --git a/libavcodec/h265_metadata_bsf.c b/libavcodec/h265_metadata_bsf.c
index 6787bd14a1..c3acbfb167 100644
--- a/libavcodec/h265_metadata_bsf.c
+++ b/libavcodec/h265_metadata_bsf.c
@@ -24,6 +24,8 @@
 #include "cbs.h"
 #include "cbs_bsf.h"
 #include "cbs_h265.h"
+#include "cbs_misc.h"
+#include "cbs_sei.h"
 #include "h2645data.h"
 #include "hevc.h"
 #include "h265_profile_level.h"
@@ -62,6 +64,7 @@ typedef struct H265MetadataContext {
     int level;
     int level_guess;
     int level_warned;
+    int a53_cc;
 } H265MetadataContext;
 
 
@@ -322,6 +325,137 @@ static int h265_metadata_update_sps(AVBSFContext *bsf,
     return 0;
 }
 
+static int h265_metadata_extract_a53_cc(AVBSFContext *bsf, AVPacket *pkt,
+                                         CodedBitstreamFragment *au)
+{
+    H265MetadataContext *ctx = bsf->priv_data;
+    SEIRawMessage *message;
+    int err;
+
+    message = NULL;
+    while (ff_cbs_sei_find_message(ctx->common.output, au,
+                                   SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35,
+                                   &message) == 0) {
+        SEIRawUserDataRegistered *udr = message->payload;
+        A53UserData a53_ud;
+        uint8_t *a53_side_data = NULL;
+        size_t a53_side_data_size = 0;
+
+        if (udr->data_length < 2) {
+            // Too short to contain a provider code.
+            continue;
+        }
+
+        if (AV_RB16(udr->data) != 0x31) { // provider_code as atsc_provider_code
+            // Not ATSC.
+            continue;
+        }
+
+        // The first two bytes of the message is provider_code
+        err = ff_cbs_read_a53_user_data(ctx->common.output,
+                                        &a53_ud,
+                                        udr->data + 2,
+                                        udr->data_length - 2);
+        if (err < 0) {
+            // Invalid or something completely different.
+            continue;
+        }
+        if (a53_ud.user_identifier != A53_USER_IDENTIFIER_ATSC ||
+            a53_ud.atsc.user_data_type_code !=
+                A53_USER_DATA_TYPE_CODE_CC_DATA) {
+            // Valid but something else (e.g. AFD).
+            continue;
+        }
+
+        err = ff_cbs_write_a53_cc_side_data(ctx->common.output,
+                                            &a53_side_data,
+                                            &a53_side_data_size,
+                                            &a53_ud);
+        if (err < 0) {
+            av_log(bsf, AV_LOG_ERROR, "Failed to write "
+                    "A/53 user data for packet side data.\n");
+            return err;
+        }
+
+        if (a53_side_data) {
+            err = av_packet_add_side_data(pkt, AV_PKT_DATA_A53_CC,
+                                          a53_side_data, a53_side_data_size);
+            if (err) {
+                av_log(bsf, AV_LOG_ERROR, "Failed to attach extracted A/53 "
+                        "side data to packet.\n");
+                av_freep(&a53_side_data);
+                return err;
+            }
+
+            if (ctx->a53_cc == BSF_ELEMENT_REMOVE ||
+                ctx->a53_cc == BSF_ELEMENT_INSERT) {
+                ff_cbs_sei_delete_message(ctx->common.output, au, message);
+
+                // Reset iteration
+                message = NULL;
+            }
+        }
+    }
+
+    if (ctx->a53_cc == BSF_ELEMENT_INSERT) {
+        uint8_t *data;
+        size_t size;
+        int offset = 0;
+
+        data = av_packet_get_side_data(pkt, AV_PKT_DATA_A53_CC, &size);
+        while (size > 0) {
+            A53UserData a53_ud;
+            int rsize = FFMIN(93, size);
+
+            err = ff_cbs_read_a53_cc_side_data(ctx->common.output, &a53_ud,
+                                               data + offset, rsize);
+            offset += rsize;
+            size -= rsize;
+            if (err < 0) {
+                av_log(bsf, AV_LOG_WARNING, "Invalid A/53 closed captions "
+                       "in packet side data dropped.\n");
+            } else {
+                AVBufferRef *udr_buf = av_buffer_allocz(sizeof(SEIRawUserDataRegistered));
+                SEIRawUserDataRegistered *udr = (SEIRawUserDataRegistered*)udr_buf->data;
+                size_t size = 9 + 3 * a53_ud.atsc.cc_data.cc_count;
+
+                udr->data_ref = av_buffer_allocz(2 + size);
+                if (!udr->data_ref) {
+                    return AVERROR(ENOMEM);
+                }
+                udr->data = udr->data_ref->data;
+                udr->data_length = udr->data_ref->size;
+
+                udr->itu_t_t35_country_code = 0xB5; // usa_country_code
+                AV_WB16(udr->data, 0x31);           // provider_code as atsc_provider_code
+
+                err = ff_cbs_write_a53_user_data(ctx->common.output, udr->data + 2,
+                                                 &size, &a53_ud);
+                if (err < 0) {
+                    av_log(bsf, AV_LOG_ERROR, "Failed to write "
+                           "A/53 user data.\n");
+                    av_buffer_unref(&udr->data_ref);
+                    av_buffer_unref(&udr_buf);
+                    return err;
+                }
+
+                err = ff_cbs_sei_add_message(ctx->common.output, au, 1,
+                                             SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35,
+                                             udr, udr_buf);
+                if (err < 0) {
+                    av_log(bsf, AV_LOG_ERROR, "Failed to add A/53 user data "
+                           "SEI message to access unit.\n");
+                    av_buffer_unref(&udr->data_ref);
+                    av_buffer_unref(&udr_buf);
+                    return err;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
 static int h265_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt,
                                          CodedBitstreamFragment *au)
 {
@@ -387,6 +521,12 @@ static int h265_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt,
         }
     }
 
+    if (pkt && ctx->a53_cc != BSF_ELEMENT_PASS) {
+        err = h265_metadata_extract_a53_cc(bsf, pkt, au);
+        if (err < 0)
+            return err;
+    }
+
     return 0;
 }
 
@@ -478,6 +618,10 @@ static const AVOption h265_metadata_options[] = {
     { LEVEL("8.5", 255) },
 #undef LEVEL
 
+    BSF_ELEMENT_OPTIONS_PIRE("a53_cc",
+                             "A/53 Closed Captions in SEI NAL units",
+                             a53_cc, FLAGS),
+
     { NULL }
 };
 
-- 
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-02-04  0:42 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-04  0:41 [FFmpeg-devel] [PATCH 0/5] Bitstream filter support for A/53 Closed Captions ffmpegagent
2023-02-04  0:41 ` [FFmpeg-devel] [PATCH 1/5] cbs: Add some common code for read/write of miscellaneous user data Mark Thompson
2023-02-04  0:41 ` [FFmpeg-devel] [PATCH 2/5] cbs_sei: add ff_cbs_sei_delete_message helper Eric Lindvall
2023-02-04  0:41 ` [FFmpeg-devel] [PATCH 3/5] avcodec/mpeg2_metadata_bsf: add support for a/53 closed captions Aman Karmani
2023-02-04  0:41 ` [FFmpeg-devel] [PATCH 4/5] avcodec/h264_metadata_bsf: " Aman Karmani
2023-02-04  0:41 ` [FFmpeg-devel] [PATCH 5/5] avcodec/h265_metadata_bsf: " Aman Karmani

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git