音视频入门基础:H.264专题(17)——FFmpeg源码获取H.264裸流文件信息(视频压缩编码格式、色彩格式、视频分辨率、帧率)的总流程

=================================================================

音视频入门基础:H.264专题系列文章:

音视频入门基础:H.264专题(1)------H.264官方文档下载

音视频入门基础:H.264专题(2)------使用FFmpeg命令生成H.264裸流文件

音视频入门基础:H.264专题(3)------EBSP, RBSP和SODB

音视频入门基础:H.264专题(4)------NALU Header:forbidden_zero_bit、nal_ref_idc、nal_unit_type简介

音视频入门基础:H.264专题(5)------FFmpeg源码中 解析NALU Header的函数分析

音视频入门基础:H.264专题(6)------FFmpeg源码:从H.264码流中提取NALU Header、EBSP、RBSP和SODB

音视频入门基础:H.264专题(7)------FFmpeg源码中 指数哥伦布编码的解码实现

音视频入门基础:H.264专题(8)------H.264官方文档的描述符

音视频入门基础:H.264专题(9)------SPS简介

音视频入门基础:H.264专题(10)------FFmpeg源码中,存放SPS属性的结构体和解码SPS的函数分析

音视频入门基础:H.264专题(11)------计算视频分辨率的公式

音视频入门基础:H.264专题(12)------FFmpeg源码中通过SPS属性计算视频分辨率的实现

音视频入门基础:H.264专题(13)------FFmpeg源码中通过SPS属性获取视频色彩格式的实现

音视频入门基础:H.264专题(14)------计算视频帧率的公式

音视频入门基础:H.264专题(15)------FFmpeg源码中通过SPS属性获取视频帧率的实现

音视频入门基础:H.264专题(16)------FFmpeg源码中,判断某文件是否为H.264裸流文件的实现

音视频入门基础:H.264专题(17)------FFmpeg源码获取H.264裸流文件信息(视频压缩编码格式、色彩格式、视频分辨率、帧率)的总流程

=================================================================

一、引言

本文对之前音视频入门基础H.264专题(1)到(16)中的内容进行一个总结。通过FFmpeg命令可以获取到AnnexB格式的H.264裸流文件的信息,包括视频压缩编码格式、色彩格式、视频分辨率、帧率:

二、FFmpeg源码获取H.264裸流文件信息的内部实现原理

(一)打开H.264裸流文件

执行命令:./ffmpeg -i output.h264时,FFmpeg内部会执行avformat_open_input函数,而该函数内部会调用avpriv_open函数,打开需要被解析的H.264裸流文件。

avpriv_open函数定义在FFmpeg源码(本文演示用的FFmpeg源码版本为5.0.3)的源文件libavutil/file_open.c中:

cpp 复制代码
int avpriv_open(const char *filename, int flags, ...)
{
    int fd;
    unsigned int mode = 0;
    va_list ap;

    va_start(ap, flags);
    if (flags & O_CREAT)
        mode = va_arg(ap, unsigned int);
    va_end(ap);

#ifdef O_CLOEXEC
    flags |= O_CLOEXEC;
#endif
#ifdef O_NOINHERIT
    flags |= O_NOINHERIT;
#endif

    fd = open(filename, flags, mode);
#if HAVE_FCNTL
    if (fd != -1) {
        if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
            av_log(NULL, AV_LOG_DEBUG, "Failed to set close on exec\n");
    }
#endif

    return fd;
}

可以看到avpriv_open函数内部通过系统调用 fd = open(filename, flags, mode) 打开需要被解析的H.264裸流文件,得到文件描述符fd。

(二)读取H.264裸流文件的数据

然后avformat_open_input函数内部会调用file_read函数读取H.264裸流文件的内容(二进制数据)。

file_read函数定义在FFmpeg源码的源文件libavformat/file.c中:

cpp 复制代码
static int file_read(URLContext *h, unsigned char *buf, int size)
{
    FileContext *c = h->priv_data;
    int ret;
    size = FFMIN(size, c->blocksize);
    ret = read(c->fd, buf, size);
    if (ret == 0 && c->follow)
        return AVERROR(EAGAIN);
    if (ret == 0)
        return AVERROR_EOF;
    return (ret == -1) ? AVERROR(errno) : ret;
}

可以看到file_read函数内部通过系统调用 ret = read(c->fd, buf, size)读取H.264裸流文件的内容,并将其保存到缓存区buf中。

(三)判断该文件是否为H.264裸流文件

然后avformat_open_input函数内部通过h264_probe函数判断该文件是否为AnnexB格式的H.264裸流文件。具体可以参考:《音视频入门基础:H.264专题(16)------FFmpeg源码中,判断某文件是否为H.264裸流文件的实现》。

(四)获取色彩格式、视频分辨率、帧率等信息

然后FFmpeg内部会调用avformat_find_stream_info函数,在该函数内部,首先通过ff_h264_decode_seq_parameter_set函数解码SPS,得到SPS中的属性(具体可以参考:《音视频入门基础:H.264专题(10)------FFmpeg源码中,存放SPS属性的结构体和解码SPS的函数分析》)。然后在parse_nal_units函数中,根据上述获取到的SPS中的属性,计算出色彩格式、视频分辨率和帧率(具体可以参考:《音视频入门基础:H.264专题(13)------FFmpeg源码中通过SPS属性获取视频色彩格式的实现》、《音视频入门基础:H.264专题(12)------FFmpeg源码中通过SPS属性计算视频分辨率的实现》、《音视频入门基础:H.264专题(15)------FFmpeg源码中通过SPS属性获取视频帧率的实现》。

相关推荐
归秋1425 小时前
多轨音频智能混音软件怎么选:从 demo 到更完整作品的 AI 后期工具思路
人工智能·音视频
小猴子爱上树8 小时前
跨马翻译:批量图片翻译与视频字幕、智能抠图一站式在线图片翻译工具
大数据·人工智能·python·音视频
每天死循环8 小时前
ComfyUI MiniMax H3文生视频(t2v)提示词教程:四段式写法+5秒768p实测(附模板和参数)
音视频·文生视频·comfyui·ai视频·minimax
企业数字化笔记10 小时前
视频像素分割怎么选?HSV 阈值、传统掩膜、语义分割和实例分割的效果与代价
opencv·音视频
Maynor99610 小时前
6张商品图→17秒带货短视频:开源12个Claude Skills,配音、字幕花字、BGM本地一条命令出片
ffmpeg·ai编程·claude·电商·agent skills
youdexiang10 小时前
AI 生成会议纪要好用吗?多款 APP 功能分析
java·人工智能·音视频
AI创界者11 小时前
【开源实战】MiniMax-H3 本地离线高自由度 ComfyUI 工作流搭建指南(含规则松绑与提示词映射)
人工智能·aigc·音视频
AIGC小尼11 小时前
8G 显存零基础本地部署 AI 漫剧全流程|ComfyUI+Wan2.2+FFmpeg 离线成片完整方案(含代码 / 指令 / 排坑)
人工智能·ffmpeg·php·comfyui·ai漫剧
hai31524754311 小时前
文本矩阵化拆解与视频矩阵化构建
线性代数·矩阵·音视频
昨日之日200611 小时前
Visual Enhancer:一键让模糊照片视频变清晰,升分辨率、插帧、转HDR,一键搞定素材修复
计算机视觉·音视频