当前位置: 首页 > news >正文

FFmpeg 基本数据结构 AVCodecParser分析

1、AVCodecParser 结构分析

FFmpeg 中的 AVCodecParser。简单来说,AVCodecParser(解析器)是 FFmpeg 中用于从原始码流(raw bitstream)中识别和分离出完整帧(frames/packets)的组件。它的核心任务是解决 “帧边界检测” 问题。
其定义如下:

typedef struct AVCodecParser {int codec_ids[7]; /* several codec IDs are permitted */int priv_data_size;int (*parser_init)(AVCodecParserContext *s);/* This callback never returns an error, a negative value means that* the frame start was in a previous packet. */int (*parser_parse)(AVCodecParserContext *s,AVCodecContext *avctx,const uint8_t **poutbuf, int *poutbuf_size,const uint8_t *buf, int buf_size);void (*parser_close)(AVCodecParserContext *s);int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size);
} AVCodecParser;
  • codec_ids:该解析器支持的编解码器ID数组。一个解析器可以支持多种相关的编解码格式(如 H.264 和 H.265 的解析器可能相同)。数组以 AV_CODEC_ID_NONE (0) 结尾。
  • priv_data_size:该解析器所需的私有数据上下文的大小。FFmpeg 会为每个解析会话分配这块内存,用于存储解析状态(如部分帧的数据、临时变量等)。
  • parser_init:初始化解析器上下文的函数指针。负责初始化私有数据。
  • parser_parse: 核心解析函数。输入一段字节流,输出一个完整的帧(如果可能)。这是解析器的"大脑"。
  • parser_close:关闭解析器,释放私有数据等资源。
  • split:快速分割函数。一个可选的、更轻量级的函数,用于在某些情况下快速找到帧边界,而无需完整的解析逻辑。

2、AVCodecParser 工作流程

1.查找解析器:av_parser_init(codec_id)根据编解码器 ID(如 AV_CODEC_ID_H264)找到一个合适的解析器。
2.创建解析上下文:上一步已经完成。解析器会返回一个 AVCodecParserContext,它保存了解析过程中的状态。
3.循环解析:av_parser_parse2()输入:指向一块原始数据缓冲区的指针和它的长度。这个过程通常是循环的,你不断地从文件或网络中读取数据块(chunk)喂给解析器。输出:一个完整的 AVPacket(包含一帧数据)以及该帧在输入缓冲区中的消耗量。这个函数非常强大,它能处理输入数据不完整、帧被分到两个数据块中等复杂情况。
4.解码:将解析器输出的 AVPacket 送入解码器 (avcodec_send_packet)。
5. 清理:完成后用 av_parser_close() 释放解析上下文。

3、AVCodecParser 总结与核心要点

  • 核心功能:帧边界检测。将原始的、无结构的字节流切割成完整的压缩帧单元。
  • 主要应用场景:
    1. 处理裸流文件(如 .h264, .hevc, .aac)。
    2. 处理网络流,特别是当 TCP 数据包不能保证一个数据包就包含一整帧时。
    3. 在解码器内部被使用,作为解码前确保数据完整的一道工序。
  • 与解复用器的关系:它们是多媒体处理流水线中前后衔接的两个阶段。解复用器先工作,从容器中提取出原始码流;然后解析器再对原始码流进行精细分帧,最后交给解码器。

4、AVCodecParser 定义实例

const AVCodecParser ff_av1_parser = {.codec_ids      = { AV_CODEC_ID_AV1 },.priv_data_size = sizeof(AV1ParseContext),.parser_init    = av1_parser_init,.parser_close   = av1_parser_close,.parser_parse   = av1_parser_parse,
};

对于常见的封装格式(如 MP4、MKV、AVI),你通常不需要手动调用 av_parser_parse2。av_read_frame 已经为你处理好了从容器中读取并分帧的工作。

int av_read_frame(AVFormatContext *s, AVPacket *pkt){read_frame_internal()
}
static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) {parse_packet(s, pkt, st->index, 1);
}static int parse_packet(AVFormatContext *s, AVPacket *pkt,int stream_index, int flush)
{len = av_parser_parse2(sti->parser, sti->avctx,&out_pkt->data, &out_pkt->size, data, size,pkt->pts, pkt->dts, pkt->pos);
}int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx,uint8_t **poutbuf, int *poutbuf_size,const uint8_t *buf, int buf_size,int64_t pts, int64_t dts, int64_t pos)
{index = s->parser->parser_parse(s, avctx, (const uint8_t **) poutbuf,poutbuf_size, buf, buf_size);
}
http://www.dtcms.com/a/536824.html

相关文章:

  • celery知识点总结
  • langchain将用户问题转sql查询探索
  • compareAndSet怎么用
  • Skill Seeker——一站式自动化将文档网站、GitHub 仓库和 PDF 文件转换为可部署 AI 技能的深度解析
  • 浅谈 Agent 开发工具链演进历程
  • 帝国cms小说阅读网站模板果洛电子商务网站建设哪家快
  • 学校网站建设背景科技作品手工
  • SmartPLS下载安装教程(附安装包)SmartPLS 4.1保姆级图文教程
  • ECR扫描管理功能完整实现:提升云原生镜像安全管控效率
  • PySide6 Win10记事本从零到一——第二章 第一个窗口程序
  • 商务英语资源合集
  • Shell 变量
  • 基于vue的在线学习系统
  • 【题解】洛谷 P4291 [HAOI2008] 排名系统 [字符串 + 平衡树]
  • html5做网站好吗漳州做网站制作
  • 做网站从哪里找货源江门制作公司网站
  • 鸿蒙Flutter三方库适配指南-02.Flutter相关知识基础
  • 随机SVD:大规模矩阵分解的高效算法
  • mysql 数据库做异机定时器自动全库备份
  • ctf常用古典密码
  • 手机网站程序如何自己设计图片
  • 怎么看一个网站什么程序做的国外网站建设素材库
  • MongoDB的$sample是啥?
  • __金仓数据库平替MongoDB实战:从多模兼容到高可用落地__
  • 缓存相关,redis
  • 零基础如何准备蓝桥杯
  • 佛山 网站设计公司中山高端网站建设
  • 2.2.1.10 大数据方法论与实践指南-Kafka 使用规范
  • 培训班在哪个网站找网站建设注意事情
  • 企业的网站建设公司南阳做网站 汉狮公司