首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何在H264中从ffmpeg中读取sei未注册用户数据?

在H.264编码的视频流中,SEI(Supplemental Enhancement Information)是一种附加信息,它可以包含各种类型的数据,比如未注册用户数据(Unregistered User Data)。在FFmpeg中读取SEI未注册用户数据通常涉及以下几个步骤:

基础概念

  • H.264编码:一种广泛使用的视频压缩标准。
  • SEI:在H.264编码的视频流中,用于传输非标准信息的帧内数据。
  • 未注册用户数据:SEI中的一种类型,可以包含任何类型的数据,通常由特定的应用程序定义。

相关优势

  • 灵活性:允许开发者自定义视频流中的附加信息。
  • 兼容性:即使在不支持SEI的设备上,视频流仍然可以正常播放。

类型

  • 标准SEI消息:由标准定义的消息类型。
  • 未注册用户数据:由应用程序自定义的数据。

应用场景

  • 版权信息嵌入:在视频中嵌入版权信息。
  • 定制播放控制:传递播放器特定的控制指令。
  • 元数据分析:嵌入视频的元数据,用于后续分析。

如何读取SEI未注册用户数据

FFmpeg提供了一个API来解析视频流中的SEI信息。以下是一个简单的示例代码,展示如何从H.264视频流中读取未注册用户数据:

代码语言:txt
复制
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>

void process_sei(AVCodecContext *avctx, const uint8_t *buf, int size) {
    const uint8_t *sei = buf;
    while (sei < buf + size) {
        int payload_type = 0;
        int last_payload_type_size = 0;
        int payload_size = 0;

        // 解析SEI头
        if (sei + 1 > buf + size)
            break;
        payload_type = sei[0];
        last_payload_type_size = sei[1];
        payload_size = last_payload_type_size >> 4;
        sei += 2;

        // 如果是未注册用户数据
        if (payload_type == 5) {
            // 处理未注册用户数据
            printf("Unregistered User Data: ");
            for (int i = 0; i < payload_size; i++) {
                printf("%02x ", sei[i]);
            }
            printf("\n");
        }

        // 移动到下一个SEI单元
        sei += payload_size + last_payload_type_size & 0x0F;
    }
}

int main(int argc, char **argv) {
    AVFormatContext *fmt_ctx = NULL;
    AVCodecContext *codec_ctx = NULL;
    const AVCodec *codec = NULL;

    av_register_all();

    if (avformat_open_input(&fmt_ctx, "input.mp4", NULL, NULL) < 0) {
        fprintf(stderr, "Could not open input file\n");
        return -1;
    }

    if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
        fprintf(stderr, "Failed to retrieve input stream information\n");
        return -1;
    }

    int video_stream_index = -1;
    for (int i = 0; i < fmt_ctx->nb_streams; i++) {
        if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            video_stream_index = i;
            break;
        }
    }

    if (video_stream_index == -1) {
        fprintf(stderr, "Could not find video stream in the input, aborting\n");
        return -1;
    }

    codec = avcodec_find_decoder(fmt_ctx->streams[video_stream_index]->codecpar->codec_id);
    if (!codec) {
        fprintf(stderr, "Codec not found\n");
        return -1;
    }

    codec_ctx = avcodec_alloc_context3(codec);
    if (!codec_ctx) {
        fprintf(stderr, "Could not allocate video codec context\n");
        return -1;
    }

    if (avcodec_parameters_to_context(codec_ctx, fmt_ctx->streams[video_stream_index]->codecpar) < 0) {
        fprintf(stderr, "Failed to copy codec parameters to decoder context\n");
        return -1;
    }

    if (avcodec_open2(codec_ctx, codec, NULL) < 0) {
        fprintf(stderr, "Could not open codec\n");
        return -1;
    }

    AVPacket pkt;
    av_init_packet(&pkt);
    pkt.data = NULL;
    pkt.size = 0;

    while (av_read_frame(fmt_ctx, &pkt) >= 0) {
        if (pkt.stream_index == video_stream_index) {
            int ret;
            AVFrame *frame = av_frame_alloc();
            if (!frame) {
                fprintf(stderr, "Could not allocate video frame\n");
                return -1;
            }

            ret = avcodec_send_packet(codec_ctx, &pkt);
            if (ret < 0) {
                fprintf(stderr, "Error sending a packet for decoding\n");
                return -1;
            }

            while (ret >= 0) {
                ret = avcodec_receive_frame(codec_ctx, frame);
                if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
                    break;
                else if (ret < 0) {
                    fprintf(stderr, "Error during decoding\n");
                    return -1;
                }

                // 处理SEI信息
                process_sei(codec_ctx, frame->data[5], frame->linesize[5]);
            }

            av_frame_free(&frame);
        }
        av_packet_unref(&pkt);
    }

    avcodec_free_context(&codec_ctx);
    avformat_close_input(&fmt_ctx);

    return 0;
}

参考链接

常见问题及解决方法

  1. SEI数据未正确解析:确保你的解析逻辑与SEI数据的结构相匹配。
  2. 内存泄漏:确保在使用完AVFrame和AVPacket后释放它们。
  3. 编码格式不支持:确保输入的视频文件是H.264编码的。

通过上述步骤和代码示例,你应该能够在FFmpeg中成功读取H.264视频流中的SEI未注册用户数据。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

FFmpeg入门到精通:SEI那些事

本文是“FFmpeg入门到精通”系列的第三篇,由金山云供稿,并授权LiveVideoStack发布。此前两篇为FFmpeg代码导读——基础篇和FFmpeg代码导读——HEVC在RTMP的扩展。...解析SEI FFmpeg读取和解码NAL unit,都有相同的逻辑处理SEI读取或者解码数据时,会调用下面函数进行码流的解码,其中buf包含具体的二进制流,buf_size是当前码流长度。...语法标准,在解析了SEI payload type和length后,对未注册用户数据的提取,跳过了uuid的分析,只尝试提取了x264的build信息。...data数据取出NAL unit type,如果是SEI且是用户未注册数据类型(payload type值为5),则可以参考SEI语法继续读取UUID和其后传递的字符串。...本文主要对H.264码流涉及用户未注册数据SEI进行了分析。

99710

FFmpeg入门到精通:SEI那些事

下面示例命令添加了类型为未注册用户数据SEI,其中uuid为"086f3693-b7b3-4f2c-9653-21492feee5b8",payload内容为"hello": ....解析SEI FFmpeg读取和解码NAL unit,都有相同的逻辑处理SEI读取或者解码数据时,会调用下面函数进行码流的解码,其中buf包含具体的二进制流,buf_size是当前码流长度。...语法标准,在解析了SEI payload type和length后,对未注册用户数据的提取,跳过了uuid的分析,只尝试提取了x264的build信息。...data数据取出NAL unit type,如果是SEI且是用户未注册数据类型(payload type值为5),则可以参考SEI语法继续读取UUID和其后传递的字符串。...本文主要对H.264码流涉及用户未注册数据SEI进行了分析。

1.5K10
  • 视频智能分析视频上云服务平台EasyCVR如何在FFmpeg插入SEI信息集成AI智能分析?

    视频上云服务EasyCVR已经开发集成了海康SDK、Ehome协议等私有协议,目前其他的协议也在拓展当中,有兴趣的用户可以看一下我们的Ehome协议开发过程(Ehome协议调用流程介绍)。 ?...EasyCVR目前正在研发AI智能分析集成功能,将智能分析结果插入视频流成为我们首要解决的问题,我们使用了FFmpeg插入SEI信息流程。...插入时遵循SPS+PPS+SEI+IDR 的顺序 Ffmpeg h264_metadata_bsf.c ? ?...以上代码完整解释了SEI规范,其中"H264_SEI_TYPE_USER_DATA_UNREGISTERED"值为5,对应的即是未注册用户信息。...在解析"ffmpeg"工具输入过程,将"+“号前面的字符串转换成二进制写入uuid,”+"后内容使用字符串写入payload。 二、码流随机插入SEI,如下: ?

    2.1K21

    H264解码输出yuv文件

    解码过程与编码过程类似,编码过程是先初始化编码器,然后编码器输出buf读出h264文件头数据,写入输出文件,然后开始不断地将一帧帧NV12格式的图像写入到编码器的输入buf,启动编码,编码器输出buf...,启动解码,解码器输出buf读取NV12格式的数据,然后转换成YUV420p格式写入到输出文件。...与编码过程读取一帧帧NV12格式的图像数据不同,因为NV12格式每一帧长度是一样的。而H264格式文件每一段NALU的长度不是固定的,这就需要在读取文件做判断。...首先是读取文件的头部,SPS/PPS/SEI数据单元开始读,遇到SLICE/SLICE_IDR数据单元时停止,将读到的数据写入到解码器的输入buf,然后初始化解码器。...第一部分是文件读入数据到fbuf缓冲区,并使缓冲区数据保持一半空间存有数据

    1.1K20

    H264系列--码流组成和分层结构

    Android FFmpeg专题结构 H264码流结构 无论是解析视频文件或这通过网络传输, 其实都是一串字节序列. H264码流就是按照一定的规则组织排列的字节串....直观理解的角度 按照大到小分为: 视频序列, 图像帧, 片,宏块,子块 ?...66.png 码流功能的角度 码流功能的角度可以分为两层:NAL层和VCL层 NAL网络提取层:负责以网络所要求的恰当的方式对数据进行打包和传送 VCL视频编码层:包括核心压缩引擎和块,宏块和片的语法级别定义...前面提到的一帧图像(I帧, P帧, B帧)就是一个NALU单元, NALU单元除了代表图像外还能包含其他类型的数据,PPS和SPS, 详细的内容在下节列出来....6:SEI,英文全称Supplemental Enhancement Information,翻译为“补充增强信息”,提供了向视频码流中加入额外信息的方法。

    1.5K30

    H264和H265的nalu介绍

    本篇介绍 本篇介绍下H264H264的编码格式,包括avcc,annexb,以及转换方法。annexb 用于实时流的场景,avcc用于多媒体文件,mp4,mkv等场景。...H264编码过程的3种数据: SODB(string of data byte),数据比特流,最原始的编码数据,也就是VCL数据,没有附加其他数据。...如果NAL数据也有0x00000001数据,那么就会出现误判,因此需要添加仿校验字节,如果编码器发现连续2个字节为0,那么就会添加0x03,在解码的时候再把0x03去掉。...,包括一个图像所有的Slice的相关信息,如图像类型,序列号,标识符,可选的序列标识符,熵编码模式选择标识,片组数目,初始化编码参数,去方块滤波系数调整标识等 数据分割: 组成片的编码数据存放在3个独立的数据分割...找一个mp4 文件,执行下面命令 ffmpeg -i test.mp4 -codec copy -bsf: h264_mp4toannexb -f h264 out.h264 这时候就可以看到对应的annexb

    2.5K10

    如何使用FFmpeg将AVI转换为MP4(有损转换和无损转换)

    ▲扫描图中二维码或点击阅读原文▲ 了解音视频技术大会更多信息 FFmpeg Easy-Tech #021# 在本篇文章,我们将学习如何使用FFmpeg把视频AVI格式转换为MP4格式(在重新/...音频和视频压缩过程的输出被打包进一个被称为容器(Formats)的格式,而打开容器以及读取音频和视频的方式也有明确的规则和指南。容器有不同的格式, MP4、AVI、WebM、MKV等。...转换过程重新编码是好是坏? 这要看你是想直接复制视频并只改变容器格式(AVI转换为MP4)还是确实想要重新编码视频并更改视频质量、大小等。...这是因为FFmpeg只是复制AVI文件的视频和音频,并未重新编码,并将它们放入MP4容器。 因为视频并没有重新编码,所以你可以认为这种AVI到MP4的转换是无损转换。...我建议你下载静态版本(除非你正计划使用FFmpeg开发软件并需要共享库)。 2、如何在MacOS安装FFmpeg

    8.2K50

    RTSPRTMP直播系统中使用SEI传输用户自定义数据方案讨论

    在直播系统,除了直播音视频之外,有时候还想从主播端发布文本信息等,这些信息可以不通过视频传输通道发送给用户播放端,但如果传输的数据想和视频保持精准同步,那最好的办法就是这些信息和视频数据打包在一起传输..., 通过h264 sei方式就可以把数据放入h264 Access Unit传输。...H264 SEI 基本知识介绍: SEI 全称: Supplemental Enhancement Information SEI Nal Unit Type: 6 SEI...Unit可以包含多个SEI消息,每个SEI消息都有一个payloadType,目前h264规定payloadType为5时,sei_playload可以使用户自定义数据, 那么我们就可以利用它来传输数据...第二个是兼容性很好,如果播放端不支持自定义SEI数据解析,把SEI数据丢给H264解码器,解码器只是忽略掉,并不影响正常播放. 上述操作也可以用VLC来播放,播放正常,只是不显示SEI消息而已。

    2.5K20

    SkeyePlayer源码解析系列之支持H265

    , // 39 Prefix SEI NAL_UNIT_SEI_SUFFIX, // 40 Suffix SEI NAL_UNIT_RESERVED...要多样化,判断也不限制于一种类型; 同时,测试发现,实际H265帧数据的VPS=0x40 , SPS=0x42, PPS=0x44, 通过换算,我们不难得出: NALtype*2 = 实际的流的NaLType...等对H265的定义是对“H265”子串做的字串格式组合,而新版的FFMPEG使用的自定义的顺序定义的枚举类型,所以在使用过程可能出现对应不上的情况,比如,在libSkeyeRTSPClient库对H265...的定义为:#define Skeye_SDK_VIDEO_CODEC_H265 0x48323635 /* 1211250229 */ 而FFMPEG定义H265(HEVC)格式为174,SkeyePlayer...四、H265格式视频写MP4 这里接着之前SkeyePlayer系列的写MP4篇讲,将H265封装MP4; 1> 解析H265的头,或者VPS,SPS和PPS H265帧取出NAL头在上文已经作过讲解这里就不做过多赘述

    1.1K20

    ffmpeg解析MP4封装的avc1编码问题「建议收藏」

    0、问题   遇到的问题:使用ffmpeg直接读取avc1编码的mp4视频,将读取到的帧写下来(H264码流),播放失败。   ...原因: ffmpeg解码获取的AVPacket只包含视频压缩数据,并没有包含相关的解码信息(比如:h264的sps,pps头信息),这些解码信息包括编码的profile,level,图像的宽和高,deblock...因为读取出来的数据不带PPS/SPS、起始码这三种信息。 必须添加上后才能播放。...,PPS在ffmpeg   H.264码流的SPS和pps信息存储在AVCidecContext结构体的extradata,添加这些信息需要使用ffmpeg名称为”h264_mp4toannexb”.../ 《4》、https://cloud.tencent.com/developer/article/1333501 《5》、sps/pps数据结构 《6》、avc1余h264区别 版权声明:本文内容由互联网用户自发贡献

    2.4K90

    音视频开发之旅(56) -H264AVC基本结构

    VCL 数据即编码处理的输出,它表示被压缩编码后的视频数据序列。 在VCL 数据传输或存储之前,这些编码的VCL 数据,先被映射或封装进NAL 单元。...提取视频 保留编码格式:ffmpeg -i test.mp4 -vcodec copy -an test_copy.h264 强制格式:ffmpeg -i test.mp4 -vcodec libx264...其中 包含图像数据的unit属于VCL NAL units; SPS、PPS、和SEI 属于Non-VCL NAL Units; 下面我们分别看下 我们的h264截图中的 06、67、68代表什么意思?...分片数据则是宏块,这里就是我们要找的存储像素(YUV)数据的地方 什么是宏块 宏块是视频信息的主要承载者,因为它包含着每一个像素的亮度和色度信息。...视频解码最主要的工作则是提供高效的方式码流获得宏块的像素阵列。 组成部分:一个宏块由一个16×16亮度像素和附加的一个8×8 Cb和一个 8×8 Cr 彩色像素块组成。

    92700

    网友对嵌入式音视频开发的疑惑和解答!

    海思平台支持多种音视频开发技术,H264/H265硬件编解码技术、支持多路ISP图像处理、支持HDR10高动态技术标准等、最高支持8K分辨率等,支持音频采集、编码等技术,这些功能都使得开发者更加开发者在音视频开发上面游刃有余...RV1126的强大功能在于提供了一系列丰富的API进行音视频数据的采集、编码、裁剪,并可以在底层驱动来外接其他SENSOR接口,MIPI摄像头、HDMI接口等等。...四、个人如何在工作中学习音视频技术: 关于学习音视频技术这块,其实每个人都有自己的一些学习的方法。但是就我个人而言,最重要的一点就是要养成看源码(最好是FFMPEG源代码)的好习惯。...我后面也在网络CSDN上面也找寻了许多关于FFMPEG推流的代码,但我发现他们都是基于文件读取的方式(包括读取摄像头/dev/video0节点)进行推流,并没有根据通过读取任意数据流进行推流的代码。...我们许多不懂的地方都可以在FFMPEG源代码里面找到答案,所以我希望在后续学习,大家能够多多看源代码进行学习。

    76320

    FFmpeg代码架构

    Context是持有的上下文,是数据链路传递过程的持有数据的对象。 其实这是FFmpeg在运用面向对象的思想来编程。XxxxContext可以看做是C语言“类”的实现。...AVFormatContext持有的是传递过程数据,这些数据在整个传递路径上都存在,或者都可以复用,AVInputFormat/AVOutputFormat包含的是动作,包含着如何解析得到的这些数据...av_read_frame() 读取媒体文件每一帧数据,这是未解码之前的帧 avformat_write_header() 写入输出文件的媒体头部信息 av_interleaved_write_frame...的Parser 解析器 Parser,将输入流转换为帧的数据包 由于解码器的输入是一个完整的帧数据包,而无论是网络传输还是文件读取,一般都是固定的buffer来读取的,而不是安装格式的帧大小来读取,所以我们需要解析器...H264格式的帧数据定义。

    1.7K20

    在LinuxMacWindows上配置FFmpeg开源音频工具,轻松完成视频转码、音频混合等操作 - 雨月空间站

    简介 “FFmpeg”这个项目单词的“FF”指的是“Fast Forward(快速前进),而“mpeg”指的是“Moving picture expert group”。...这个时候,我们可以使用FFmpeg来抽离音频,: # 抽离Mintimate.mov的音频为Mintimate.acc音频 ffmpeg -i Mintimate.mov -vn -y -acodec...所以,本文章,主要讲解如何在Linux/Mac/Windows上配置FFmepg。...同样我们下载预编译版本的FFmpegFFmpeg第三方macOS x86/arm64预编译版本 我们下载最新版本: 下载后,解压并重命名放到我们熟悉的地址,:/Users/mintimate...,压缩和质量角度来说很不错;如果加了字幕还要质量,选择h264吧。

    3.9K30

    音视频八股文(8)-- h264 AnnexB

    压缩率 B > P > I H264编码结构解析 H264除了实现了对视频的压缩处理之外,为了⽅便⽹络传输,提供了对应的视频编码和分⽚策略;类似于⽹络数据封装成IP帧,在H264将其称为组(GOP,...解复⽤后,MP4⽂件读取出来的packet是不带startcode,但TS⽂件读取出来的packet带了startcode) 解析NALU 每个NAL单元是⼀个⼀定语法元素的可变⻓字节字符串,包括包含⼀...,SPS和PPS以及其它信息被封装在container,每⼀个frame前⾯4个字节是这个frame的⻓度 很多解码器只⽀持annexb这种模式,因此需要将mp4做转换:在ffmpeg⽤h264_mp4toannexb_filter...H.264的I帧,B帧和P帧 在H264的图像以序列为单位进⾏组织,⼀个序列是⼀段图像编码后的数据流,以I帧开始,到下⼀个I帧结束。...在接收端根据运动⽮量I帧找出P帧“某点”的预测值并与差值相加以得到P帧“某点”样值,⽽可得到完整的P帧。 P帧特点: 1. P帧是I帧后⾯相隔1~2帧的编码帧; 2.

    53710

    音视频八股文(8)-- h264 AnnexB

    对于视频⽂件来说,视频由单张图⽚帧所组成,⽐每秒25帧,但是图⽚帧的像素块之间存在相似性,因此视频帧图像可以进⾏图像压缩;H264采⽤了16*16的分块⼤⼩对,视频帧图像进⾏相似⽐较和压缩编码。...压缩率 B > P > IH264编码结构解析H264除了实现了对视频的压缩处理之外,为了⽅便⽹络传输,提供了对应的视频编码和分⽚策略;类似于⽹络数据封装成IP帧,在H264将其称为组(GOP, group...和PPS以及其它信息被封装在container,每⼀个frame前⾯4个字节是这个frame的⻓度很多解码器只⽀持annexb这种模式,因此需要将mp4做转换:在ffmpeg⽤h264_mp4toannexb_filter...H.264的I帧,B帧和P帧在H264的图像以序列为单位进⾏组织,⼀个序列是⼀段图像编码后的数据流,以I帧开始,到下⼀个I帧结束。...在接收端根据运动⽮量I帧找出P帧“某点”的预测值并与差值相加以得到P帧“某点”样值,⽽可得到完整的P帧。

    51510

    H264之NALU解析

    一、H264简介: H.2641999年开始,到2003年形成草案,最后在2007年定稿有待核实。...148.315 / 0.125 = 1186.523 对于视频⽂件来说,视频由单张图⽚帧所组成,⽐每秒25帧,但是图⽚帧的像素块之间存在 相似性,因此视频帧图像可以进⾏图像压缩;H264采⽤了16...在接收端根据运动⽮量I帧找出P帧“某点”的预测值并与差值 相加以得到P帧“某点”样值,⽽可得到完整的P帧。它的特点: P帧是I帧后⾯相隔1~2帧的编码帧。...四、H264编码结构解析: H264除了对视频压缩处理之外,为了方便网络传输,提供了对应的视频编码和分片策略;类似网络数据封装成IP帧,在H264将其称为组(GOP,gruop of pictures...很多解码器只⽀持annexb这种模式,因此需要将mp4做转换:在ffmpeg⽤ h264_mp4toannexb_filter可以做转换 实现如下: const AVBitStreamFilter

    2K10
    领券