FFMPEG学习【libavcodec】:发送/接收编码和解码API概述

深入解析FFmpeg libavcodec:编解码API实战指南 本文深入解析FFmpeg核心编解码库libavcodec,重点剖析其现代API `avcodec_send_packet()` 与 `avcodec_receive_frame()` 的使用方法。通过对比新旧API差异,详细阐述了基于状态机的编解码工作流、关键数据结构(AVCodecContext, AVPacket, AVFrame)以及实战中的初始化、多线程优化、硬件加速和内存管理等高级技巧,帮助开发者高效处理音视频数据。 阅读详情

avcodec_send_packet()/ avcodec_receive_frame()/ avcodec_send_frame()/ avcodec_receive_packet()函数提供了一个输入和输出的编码/解码API。


API与编码/解码和音频/视频非常相似,工作原理如下:

1、像往常一样设置和打开AVCodecContext。


2、发送有效输入:

 1)、对于解码,请调用avcodec_send_packet()以在AVPacket中给出解码器原始的压缩数据。

 2)、对于编码,请调用avcodec_send_frame()为编码器提供包含未压缩音频或视频的AVFrame。 在这两种情况下,建议对AVPackets和AVFrames进行重新计数,否则libavcodec可能必须复制输入数据。 (libavformat总是返回引用计数的AVPackets,av_frame_get_buffer()分配引用计数的AVFrames)


3、在循环中接收输出。 定期调用avcodec_receive _ *()函数并处理其输出:

 1)、对于解码,请调用avcodec_receive_frame()。 成功后,它将返回一个包含未压缩音频或视频数据的 AVFrame。

 2)、对于编码,请调用avcodec_receive_packet()。 一旦成功,它将返回带有压缩帧的AVPacket。 重复此呼叫,直到它返回AVERROR(EAGAIN)或错误。 AVERROR(EAGAIN)返回值意味着需要新的输入数据才能返回新的输出。 在这种情况下,继续发送输入。 对于每个输入帧/包,编解码器通常将返回1个输出帧/包,但也可以是0或大于1。


在解码或编码开始时,编解码器可能会接收多个输入帧/数据包而不返回帧,直到其内部缓冲区被填充为止。 如果您遵循上述步骤,这种情况是透明的。


理论上来说,发送输入可能会导致EAGAIN - 只有在没有收到所有输出的情况下才会发生。 您可以使用它来构建除上述建议之外的其他解码或编码循环。 例如,如果返回EAGAIN,您可以尝试在每次迭代中发送新的输入,并尝试接收输出。


结束流情况。 这些需要“刷新”(也称为排水)编解码器,因为编解码器可能在内部缓冲多个帧或数据包以实现性能或不必要(考虑B帧)。 处理如下:

1、发送NULL到avcodec_send_packet()(解码)或avcodec_send_frame()(编码)函数,而不是有效的输入。 这将进入排水模式。


2、在循环中调用avcodec_receive_frame()(解码)或avcodec_receive_packet()(编码),直到返回AVERROR_EOF。 除非您忘记进入排水模式,否则这些功能将不会返回AVERROR(EAGAIN)。


3、在再次解码之前,必须使用avcodec_flush_buffers()重新编码。


强烈建议您使用上述API。 但是也可以调用这个刚性模式之外的函数。 例如,您可以重复调用avcodec_send_packet(),而无需调用avcodec_receive_frame()。 在这种情况下,avcodec_send_packet()将成功,直到编解码器的内部缓冲区已经被填满(通常在初始输入后每个输出帧大小为1),然后使用AVERROR(EAGAIN)拒绝输入。 一旦它开始拒绝输入,你别无选择,只能读取至少一些输出。


并不是所有的编解码器都将遵循刚性和可预测的数据流; 唯一的保证是在一端的发送/接收呼叫上的AVERROR(EAGAIN)返回值意味着另一端的接收/发送呼叫将成功,或至少不会因AVERROR(EAGAIN)而失败。 一般来说,没有编解码器将允许输入或输出的无限制缓冲。


此API替代以下遗留功能:

1、avcodec_decode_video2()和avcodec_decode_audio4():使用avcodec_send_packet()将输入提供给解码器,然后使用avcodec_receive_frame()在每个数据包之后接收解码的帧。 与旧的视频解码API不同,多个帧可能来自一个数据包。 对于音频,通过部分解码数据包将输入数据包分割成帧变得对API用户是透明的。 您不需要将AVPacket馈送到API两次(除非它被AVERROR(EAGAIN)拒绝 - 然后没有从数据包中读取数据)。 另外,只需要发送一个刷新/排出数据包一次。


2、avcodec_encode_video2()/ avcodec_encode_audio2():使用avcodec_send_frame()将输入馈送到编码器,然后使用avcodec_receive_packet()接收编码数据包。 为avcodec_receive_packet()提供用户分配的缓冲区是不可能的。


3、新的API尚未处理字幕。


在同一AVCodecContext上混合新旧函数调用是不允许的,这将导致未定义的行为。


一些编解码器可能需要使用新的API; 使用旧的API会在调用它时返回一个错误。 所有编解码器都支持新的API。


编码解码器不允许返回发送和接收的AVERROR(EAGAIN)。这将是一个无效的状态,这可能会使编解码器用户进入无限循环。 API没有时间的概念:不可能试图做avcodec_send_packet()导致AVERROR(EAGAIN),但是1秒后重复的调用接受数据包(没有其他接收/刷新API调用涉及)。 API是一个严格的状态机,时间的流逝不应该影响它。某些与时间相关的行为在某些情况下仍然被认为是可接受的。但是绝对不能在任何时候同时发送/接收EAGAIN。还必须绝对避免当前状态“不稳定”,并且可以在发送/接收API之间“触发”允许进行。例如,在avcodec_send_packet()调用之后,它只是在AVAROR(EAGAIN)上返回AVERROR(EAGAIN)之后,编码解码器随机地决定它实际上想要消耗数据包而不是返回一个帧。

FFmpeg API 之 libavcodec库 libavformat 库负责封装和解封装,而 libavcodec 则用于解码和编码。 类型 AVPacket 表示编码后的数据,其中包含一个或多个编码后的帧数据。类型 AVFrame 表示解码后,或者说原始的帧数据。编码和解码在某种程度来说,就是两者之间的互相转换。 1、编解码概述 FFmpeg 提供的 encode/decode API 有如下四个函数 avcodec_send_packet () / avcodec_receive_frame () / avcodec_send_fram. 阅读详情

相关推荐

FFMPEG中libavcodec的软件架构是怎么样的?如何使用?

libavcodec`是FFmpeg项目中的核心库之一,它提供了一个开源的音视频编解码框架。`libavcodec`支持广泛的编解码器,可以处理几乎所有常见的音频和视频格式。它的软件架构设计为模块化,允许开发者根据需要选择和使用不同的编解码器。

bai915290475的博客 842

ffmpeg

除了内置的过滤器,libavfilter 还提供了接口供开发者自定义过滤器。开发者可以按照自己的需求编写自定义过滤器,实现特定的音视频处理算法。这样可以满足一些特殊需求,并将自定义过滤器与内置过滤器一同组成过滤器链进行处理。

123456789 1740

FFmpeg SDK API使用

FFmpeg 的基本组成 FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。它包括了领先的音/视频编码库libavcodec等。 libavformat:用于各种音视频封装格式的生成和解析,包括获取解码所需信息以生成解码上下文结构和读取音视频帧等功能; libavcodec:用于各种类型声音/图像编解码; libavutil:包含一些公共的工具函数; libswscale:用于视频场景比例缩放、色彩映射转换; libpostproc:用于后期效果处理; ..

李棚的优快云专栏 3501

基于 FFMPEG 的视频解码(libavcodec ,致敬雷霄骅)

基于 FFMPEG 的视频解码(libavcodec ,致敬雷霄骅) 本文参考了雷博士的博客: 最简单的基于FFMPEG+SDL的视频播放器:拆分-解码器和播放器 基本上雷博士这篇博客已经把这个问题讲的挺清楚了。但是 ffmpeg 新版本的 API 有变化,这篇博客的代码已经无法直接编译运行。所以我写了今天这篇博客,用 新的 API 实现了视频解码的功能。 雷博士的代码除了视频解码还有音频解码,同时还利用 SDL 把视频显示出来了。 我觉得作为初学者还是每次学习的内容不要太多。既然我们的重点是视频解码,那就

Ivan 的专栏 6276

15.FFmpeg学习笔记 - 解复用和解码(新的解码API)

本文代码对应的是13.FFmpeg学习笔记 - 解复用和解码(旧的解码API),用的是新的解码API。 #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libswscale/swscale.h> #include <libavutil/imguti...

周洪伟的博客 1096

FFMPEG之H.264视频解码

一 概括 FFMPEG 的libavcodec完成音视频编码或解码,H.264解码主要由H264.c实现,H.264.c 往下调用X264 实现编解码功能,H.264解码过程包含初始化/解码/关闭三个部分。 解码原理为: 将NAL 数据位流输入到H.264解码器中,熵解码模块解码后输出量化系数X;系数经过反量化和反变化得到残差数据R;解码器使用从码流中解析的头信息生成预测块Pred,然后把Pred与残差R求和得到数据块DF;每个块df通过去除块效应滤波得到解码图像的重建块F。 ...

陌上烟雨遥的博客 3546

libavcodec API函数详解

本文详细解析了libavcodec的核心API函数,重点介绍了编解码器查找、上下文管理、编解码操作等关键功能。文章强调了现代异步模型(Send/Receive API)的使用原则,包括引用计数内存管理、时间戳处理、硬件加速设置等核心概念。同时指出了过时API的替代方案,并总结了最佳实践,包括严格内存管理、时间戳处理、配置参数设置等注意事项。文章还提供了典型编解码工作流的伪代码示例,帮助开发者正确理解和使用这些API。

浩瀚之水的专栏 1389

FFmpeg实战:如何用libavcodec API实现视频转码(附完整代码示例)

本文详细介绍了如何直接使用FFmpeg的核心编解码库libavcodec API实现视频转码,提供了从核心数据结构解析到完整H.264转HEVC代码示例的实战指南。通过libavcodec API,开发者可以获得对转码流程的完全控制,实现实时处理与深度参数定制,从而超越命令行工具的局限性。

weixin_29190169的博客 340

libavcodec 编解码器查找与上下文管理 API函数详解

这篇文章详细解析了libavcodec中用于编解码器查找和上下文管理的核心API函数,包括查找编解码器、创建和配置上下文、初始化编解码器以及清理资源等关键操作。文章分为四个部分:编解码器查找API、编解码器上下文管理API、硬件加速相关上下文管理以及关键流程总结与最佳实践。重点介绍了avcodec_find_decoder/encoder、avcodec_alloc_context3、avcodec_open2等核心函数的使用方法和注意事项,并提供了硬件加速配置的具体流程。文章最后强调了检查返回值、正确管理

浩瀚之水的专栏 1281

FFmpeg 新旧API编码

使用libavcodec 编码Audio;使用libavcodec 编码Video;使用libavformat 合成/推流;我会先讲解使用旧AP Ilibavcodec编码Audio、Video的过程。然后再讲解使用新API编码Audio、Video的过程,通过前后的对比就可以很容易的知道直播SDK FFmpeg升级点在哪里?这里只是通过分析新旧API的使用来对比出我们直播SDK的更新点,同时也可以学习如何通过FFmpeg新旧API编码Audio、Video、Muxer。

yinshipin007的博客 485

FFmpeg libavcodec 深度剖析:编解码的心脏

libavcodec 是 FFmpeg 的编解码核心,管理数百种音视频编解码器的统一接口、多线程调度、硬件加速协商和比特流过滤。本文深度剖析其架构设计、核心数据结构、编解码流水线及多线程模型。

Chars 77

libavcodec编解码的核心机制剖析

摘要:本文系统介绍了FFmpeg中libavcodec的核心机制,重点分析了编解码过程中涉及的四个关键对象(AVCodec、AVCodecContext、AVPacket、AVFrame)及其相互关系。详细阐述了现代异步Send/Receive API的工作流程,包括解码和编码的数据处理机制,以及内存管理、时间戳处理、硬件加速和多线程等核心功能。特别强调了引用计数管理、时间基转换、错误处理等关键编程实践,为开发者提供了高效利用libavcodec进行音视频编解码开发的完整框架和最佳实践指南。

浩瀚之水的专栏 1456

医院网络设计(完整文档+思科拓扑图)

大家好,我是小华学长,一名计算机领域的博主。经过多年的学习和实践,我积累了丰富的计算机知识和经验,在这里我想与大家分享我的学习心得和技巧,帮助你成为更好的程序员。作为一名计算机博主,我一直专注于编程、算法、软件开发等领域,在这些方面积累了大量的经验。我相信分享是一种双赢的方式,通过分享,我可以帮助他人提升技术水平,同时也能够得到学习交流的机会。在我的文章中,你将会看到我对于各种编程语言、开发工具以及常见问题的解析和分析。我会结合自己的实际项目经验,为你提供实用的解决方案和优化技巧。

qq1325513482的博客 2万+

FFmpeg新旧API对比:libavcodec编码接口的演进与最佳实践

本文深入解析FFmpeg中libavcodec编解码API的演进历程,对比传统线性模式与现代状态机设计的差异。重点探讨新API如何通过显式状态管理、线程安全设计和多线程优化解决传统接口的局限性,并提供从旧API迁移的最佳实践和性能调优指南,帮助开发者高效处理多媒体数据。

weixin_30836759的博客 392

PnP 单目相机位姿估计(二):solvePnP利用二维码求解相机世界坐标

前言 原理简介 输入参数准备 1 objectPoints特征点世界坐标 2 imagePoints特征点在摄像头下的像素点坐标 3cameraMatrixdistCoeffs内参矩阵和畸变矩阵 相机世界坐标的求解 1求世界坐标中的点在相机坐标系下的坐标 2求相机在世界坐标中的坐标 3效果求解相机在世界坐标系下的坐标点 4求解代码1.前言  很多时候,当我们利用单目相机获取图像时,往往只能获取图像中

cocoaqin的博客 5万+

利用Spm12进行fMRI数据分析:从预处理到结果解读的完整指南

本文提供了利用SPM12进行fMRI数据分析的完整流程指南,涵盖从数据预处理、统计建模到结果解读的全过程。详细介绍了在MATLAB环境下使用SPM12图形界面完成头动矫正、空间标准化等关键步骤的操作方法与避坑技巧,帮助神经科学研究者和心理学研究者高效处理功能磁共振成像数据并产出可靠结果。

weixin_29079671的博客 452

libavcodec查找编解码器的核心函数

摘要:FFmpeg提供了4个核心函数用于查找编解码器:avcodec_find_decoder()和avcodec_find_encoder()通过编解码器ID查找默认实现,适合常规使用;avcodec_find_decoder_by_name()和avcodec_find_encoder_by_name()通过名称精确查找特定实现,常用于获取硬件加速编解码器或高质量软件编解码器。选择依据取决于是否需要控制具体实现(如硬件加速)或只需默认功能。所有找到的编解码器都需配合AVCodecContext使用。

浩瀚之水的专栏 887

LeGO-LOAM运行kitti数据集

文章目录1. kitti-lego-loam2. 改动3. 实验结果4. evo轨迹测评 1. kitti-lego-loam 链接:kitti-lego-loam kitti-lego-loam提供了将kitti序列转化成rosbag的代码,在kittibag中. 需要注意下数据文件的存放顺序,以00序列为例: datafolder          |____results          &

Zlp19970106的博客 8704

深入解析FFmpeg libavcodec:编解码API实战与性能优化

本文深入解析FFmpeg核心编解码库libavcodec,重点介绍了其现代API(如avcodec_send_packet/receive_frame)的实战应用。通过解码与编码的完整代码示例,详细阐述了从上下文初始化、数据处理循环到冲刷与资源管理的全流程,并探讨了多线程与硬件加速等关键性能优化策略,帮助开发者高效掌握音视频处理核心技术。

qsc901234的博客 182

芒果YOLOv12改进90:检测头篇之ShareSepHead:即插即用|原创新颖共享Sep检测头,更省参数量,更高效,打造新型YOLOv8检测器,精度高效涨点

芒果YOLOv12改进90:检测头篇之ShareSepHead:即插即用|原创新颖共享Sep检测头,更省参数量,更高效,打造新型YOLOv8检测器,精度高效涨点

包括YOLOv5、YOLOv7、YOLOv8等模型改进 344

【CASS精品教程】032:CASS11台阶画法案例大全

一、普通无边台阶 二、普通有边台阶 三、普通圆弧无边台阶 四、U型台阶 五、曲线U型台阶 六、L型台阶

智慧空间实验室 7465

FFmpeg 头文件完美翻译之 libavcodec 模块

众所周知,FFmpeg 的代码开发上手难度较高,源于官方提供的文档很少有包含代码教程相关的。要想熟练掌握 FFmpeg 的代码库开发,需要借助它的头文件,FFmpeg 把很多代码库教程都写在头文件里面。因此,熟读头文件的内容很重要,为此,我对 FFmpeg 6.x 版本的头文件进行了翻译,方便大家阅读理解。相信我,通读一遍头文件的注释后,你的 FFmpeg 的代码库开发技能将更上一层。本文适用于有 FFmpeg 代码库开发基础,但想深入熟练使用的同学。同时也可以参考我的Github 仓库,下载到本地慢慢品读

Leon_Chenl的博客 1902

binning模式下和normal模式下相同曝光参数相同场景加权亮度差异消除方案优化(一)

摘要:针对ISP参数设置中浮点权重系数需转换为整数的问题,提出整数邻域搜索方案。该方法在浮点最优解附近(±1/±2)进行局部搜索,通过逐阶微调找到误差最小的整数权重组合,避免直接取整导致的误差反弹(误差从0.8%降至0.35%)。方案结合范围约束(1~15)和单调性约束(暗端递减、亮端递增),兼顾计算效率(单图耗时<10ms)与硬件兼容性,显著优于暴力搜索和简单取整,满足工程落地需求。

大熊 97

音视频编解码学习: FFmpeg 的基础知识

FFmpeg 是一个集录制、转换、音/视频编码解码功能为一体的完整的开源解决方案;FFmpeg 的开发是基于 Linux 操作系统的,但是可以在大多数操作系统中编译和使用 FFmpeg 支持 MPEG、 DivX、MPEG4、AC3、DV、FLV 等40多种编码,AVI、MPEG、OGG、Matroska、ASF 等90多种解码

鸿蒙的技术博客 1926

2025_NIPS_RAGRouter: Learning to Route Queries to Multiple Retrieval-Augmented Language Models

该研究聚焦检索增强生成(RAG)场景下的大语言模型(LLM)路由问题,提出了首个RAG感知的路由框架RAGRouter。核心解决现有路由方法依赖静态参数知识、忽略检索文档动态影响的缺陷,通过融合文档嵌入、RAG能力嵌入与对比学习,捕捉RAG引发的模型知识表征变化,为每个查询-文档对选择最优LLM。实验覆盖5个知识密集型任务、15个开源/闭源LLM,验证了RAGRouter在性能上超越最佳单LLM和非RAG感知路由方法,且通过阈值机制实现低延迟约束下的性能-效率平衡。

UnknownBody_2的博客 272

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

上一篇: 位置和传感器:位置策略
下一篇: 位置和传感器:传感器概览
一世豁然
博客等级 码龄15年 1276粉丝 146原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值