[FFmpeg-devel] [PATCH v1 2/2] avcodec/h265_metadata_bsf: add option to insert a string as SEI unregistered user data
Limin Wang
lance.lmwang at gmail.com
Tue Dec 17 12:29:30 EET 2019
On Wed, Dec 11, 2019 at 11:02:04PM +0800, lance.lmwang at gmail.com wrote:
> From: Limin Wang <lance.lmwang at gmail.com>
>
> Signed-off-by: Limin Wang <lance.lmwang at gmail.com>
> ---
> doc/bitstream_filters.texi | 8 ++++++
> libavcodec/h265_metadata_bsf.c | 65 +++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 72 insertions(+), 1 deletion(-)
>
> diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi
> index 8fe5b3a..81b41d7 100644
> --- a/doc/bitstream_filters.texi
> +++ b/doc/bitstream_filters.texi
> @@ -376,6 +376,14 @@ The argument must be the name of a level (for example, @samp{5.1}), a
> or the special name @samp{auto} indicating that the filter should
> attempt to guess the level from the input stream properties.
>
> + at item sei_user_data
> +Insert a string as SEI unregistered user data. The argument must
> +be of the form @emph{UUID+string}, where the UUID is as a 32-character
> +(16 bytes) hexadecimal string possibly separated by hyphens, and the
> +string can be anything.
> +
> +For example, @samp{086f3693-b7b3-4f2c-9653-21492feee5b8+hello} will
> +insert the string ``hello'' associated with the given 32-bit UUID.
> @end table
Please use below patchset to check the result:
https://patchwork.ffmpeg.org/patch/16854/
>
> @section hevc_mp4toannexb
> diff --git a/libavcodec/h265_metadata_bsf.c b/libavcodec/h265_metadata_bsf.c
> index b3a1fda..f32ddf0 100644
> --- a/libavcodec/h265_metadata_bsf.c
> +++ b/libavcodec/h265_metadata_bsf.c
> @@ -16,6 +16,7 @@
> * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> */
>
> +#include "libavutil/avstring.h"
> #include "libavutil/common.h"
> #include "libavutil/opt.h"
>
> @@ -23,6 +24,7 @@
> #include "cbs.h"
> #include "cbs_h265.h"
> #include "hevc.h"
> +#include "hevc_sei.h"
> #include "h265_profile_level.h"
>
> enum {
> @@ -65,6 +67,8 @@ typedef struct H265MetadataContext {
> int crop_top;
> int crop_bottom;
>
> + const char *sei_user_data;
> +
> int level;
> int level_guess;
> int level_warned;
> @@ -340,7 +344,7 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
> {
> H265MetadataContext *ctx = bsf->priv_data;
> CodedBitstreamFragment *au = &ctx->access_unit;
> - int err, i;
> + int err, i, j, has_sps = 0, has_vps = 0;
>
> err = ff_bsf_get_packet_ref(bsf, pkt);
> if (err < 0)
> @@ -410,11 +414,67 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
> err = h265_metadata_update_vps(bsf, au->units[i].content);
> if (err < 0)
> goto fail;
> + has_vps = 1;
> }
> if (au->units[i].type == HEVC_NAL_SPS) {
> err = h265_metadata_update_sps(bsf, au->units[i].content);
> if (err < 0)
> goto fail;
> + has_sps = 1;
> + }
> + }
> +
> + // Only insert the SEI in access units containing SPSs or VPSs
> + if (ctx->sei_user_data && (has_sps || has_vps)) {
> + H265RawSEIPayload payload = {
> + .payload_type = HEVC_SEI_TYPE_USER_DATA_UNREGISTERED,
> + };
> + H265RawSEIUserDataUnregistered *udu =
> + &payload.payload.user_data_unregistered;
> +
> + for (i = j = 0; j < 32 && ctx->sei_user_data[i]; i++) {
> + int c, v;
> + c = ctx->sei_user_data[i];
> + if (c == '-') {
> + continue;
> + } else if (av_isxdigit(c)) {
> + c = av_tolower(c);
> + v = (c <= '9' ? c - '0' : c - 'a' + 10);
> + } else {
> + goto invalid_user_data;
> + }
> + if (i & 1)
> + udu->uuid_iso_iec_11578[j / 2] |= v;
> + else
> + udu->uuid_iso_iec_11578[j / 2] = v << 4;
> + ++j;
> + }
> + if (j == 32 && ctx->sei_user_data[i] == '+') {
> + size_t len = strlen(ctx->sei_user_data + i + 1);
> +
> + udu->data_ref = av_buffer_alloc(len + 1);
> + if (!udu->data_ref) {
> + err = AVERROR(ENOMEM);
> + goto fail;
> + }
> +
> + udu->data = udu->data_ref->data;
> + udu->data_length = len + 1;
> + memcpy(udu->data, ctx->sei_user_data + i + 1, len + 1);
> +
> + err = ff_cbs_h265_add_sei_prefix_message(ctx->cbc, au, &payload);
> + if (err < 0) {
> + av_log(bsf, AV_LOG_ERROR, "Failed to add user data SEI "
> + "message to access unit.\n");
> + goto fail;
> + }
> +
> + } else {
> +invalid_user_data:
> + av_log(bsf, AV_LOG_ERROR, "Invalid user data: "
> + "must be \"UUID+string\".\n");
> + err = AVERROR(EINVAL);
> + goto fail;
> }
> }
>
> @@ -547,6 +607,9 @@ static const AVOption h265_metadata_options[] = {
> OFFSET(crop_bottom), AV_OPT_TYPE_INT,
> { .i64 = -1 }, -1, HEVC_MAX_HEIGHT, FLAGS },
>
> + { "sei_user_data", "Insert SEI user data (UUID+string)",
> + OFFSET(sei_user_data), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS },
> +
> { "level", "Set level (tables A.6 and A.7)",
> OFFSET(level), AV_OPT_TYPE_INT,
> { .i64 = LEVEL_UNSET }, LEVEL_UNSET, 0xff, FLAGS, "level" },
> --
> 2.9.5
>
More information about the ffmpeg-devel
mailing list