gpt4 book ai didi

c++ - 如何从 H264 中的 ffmpeg 读取 sei 未注册的用户数据?

转载 作者:行者123 更新时间:2023-12-04 22:47:56 62 4
gpt4 key购买 nike

首先,我通过 bsf 将 user_data 设置为 video。例如,

ffmpeg  -i dump.flv -c:v copy -bsf:v h264_metadata=sei_user_data='086f3693-b7b3-4f2c-9653-21492feee5b8+hello' dump_sei.flv
Ant然后我在h264编码后使用api通过ffmpeg读取sei unregistered_user_data,但我没有得到它。

// avcodec_send_packet
// avcodec_receive_frame
// ...

H264Context *h = m_pVidDecodeCtx->priv_data;
H264SEIContext sei = h->sei;
H264SEIUnregistered unregistered = sei.unregistered;
if (unregistered.buf_ref != NULL)
{
AVBufferRef *buf = *(unregistered.buf_ref);
if (buf != NULL && buf->buffer != NULL)
{
printf("sei data: %s\n", buf->buffer);
}
}
ffmpeg 的版本是 v4.4。

最佳答案

h264 sei.c 文件是一个伟大的宝藏,您可以在其中找到有关 SEI 的所有问题的答案。 (存在于 libavcodec 文件夹中)

      static int decode_registered_user_data_afd(H264SEIAFD *h, GetBitContext *gb, int size)
{
int flag;

if (size-- < 1)
return AVERROR_INVALIDDATA;
skip_bits(gb, 1); // 0
flag = get_bits(gb, 1); // active_format_flag
skip_bits(gb, 6); // reserved

if (flag) {
if (size-- < 1)
return AVERROR_INVALIDDATA;
skip_bits(gb, 4); // reserved
h->active_format_description = get_bits(gb, 4);
h->present = 1;
}

return 0;
}

static int decode_registered_user_data_closed_caption(H264SEIA53Caption *h,
GetBitContext *gb, void *logctx,
int size)
{
if (size < 3)
return AVERROR(EINVAL);

return ff_parse_a53_cc(&h->buf_ref, gb->buffer + get_bits_count(gb) / 8, size);
}

static int decode_registered_user_data(H264SEIContext *h, GetBitContext *gb,
void *logctx, int size)
{
int country_code, provider_code;

if (size < 3)
return AVERROR_INVALIDDATA;
size -= 3;

country_code = get_bits(gb, 8); // itu_t_t35_country_code
if (country_code == 0xFF) {
if (size < 1)
return AVERROR_INVALIDDATA;

skip_bits(gb, 8); // itu_t_t35_country_code_extension_byte
size--;
}

if (country_code != 0xB5) { // usa_country_code
av_log(logctx, AV_LOG_VERBOSE,
"Unsupported User Data Registered ITU-T T35 SEI message (country_code = %d)\n",
country_code);
return 0;
}

/* itu_t_t35_payload_byte follows */
provider_code = get_bits(gb, 16);

switch (provider_code) {
case 0x31: { // atsc_provider_code
uint32_t user_identifier;

if (size < 4)
return AVERROR_INVALIDDATA;
size -= 4;

user_identifier = get_bits_long(gb, 32);
switch (user_identifier) {
case MKBETAG('D', 'T', 'G', '1'): // afd_data
return decode_registered_user_data_afd(&h->afd, gb, size);
case MKBETAG('G', 'A', '9', '4'): // closed captions
return decode_registered_user_data_closed_caption(&h->a53_caption, gb,
logctx, size);
default:
av_log(logctx, AV_LOG_VERBOSE,
"Unsupported User Data Registered ITU-T T35 SEI message (atsc user_identifier = 0x%04x)\n",
user_identifier);
break;
}
break;
}
default:
av_log(logctx, AV_LOG_VERBOSE,
"Unsupported User Data Registered ITU-T T35 SEI message (provider_code = %d)\n",
provider_code);
break;
}

return 0;
}

static int decode_unregistered_user_data(H264SEIUnregistered *h, GetBitContext *gb,
void *logctx, int size)
{
uint8_t *user_data;
int e, build, i;
AVBufferRef *buf_ref, **tmp;

if (size < 16 || size >= INT_MAX - 1)
return AVERROR_INVALIDDATA;

tmp = av_realloc_array(h->buf_ref, h->nb_buf_ref + 1, sizeof(*h->buf_ref));
if (!tmp)
return AVERROR(ENOMEM);
h->buf_ref = tmp;

buf_ref = av_buffer_alloc(size + 1);
if (!buf_ref)
return AVERROR(ENOMEM);
user_data = buf_ref->data;

for (i = 0; i < size; i++)
user_data[i] = get_bits(gb, 8);

user_data[i] = 0;
buf_ref->size = size;
h->buf_ref[h->nb_buf_ref++] = buf_ref;

e = sscanf(user_data + 16, "x264 - core %d", &build);
if (e == 1 && build > 0)
h->x264_build = build;
if (e == 1 && build == 1 && !strncmp(user_data+16, "x264 - core 0000", 16))
h->x264_build = 67;

return 0;
}

关于c++ - 如何从 H264 中的 ffmpeg 读取 sei 未注册的用户数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67486521/

62 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com