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

Zabbix在Ubuntu 22.04上的性能优化与监控实战:从基础安装到高级配置

本文详细介绍了在Ubuntu 22.04系统上部署和优化Zabbix监控系统的完整流程,从基础安装到高级配置。内容包括MySQL数据库设置、Zabbix服务器与Web前端优化、性能调优策略以及实战监控场景应用,帮助用户构建高效的企业级监控解决方案。

sss66的博客 895

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

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

weixin_30836759的博客 392

Diffix3D+复现

上下载模型,将其放在一个目录中,并将目录名填在demo代码中from_pretrained的cache_dir参数里。目录结构应该是"<PATH>/nvidia/difix/…给的requirements文件中pytorch和xformers的版本没有指定,这里测试过以下版本,可以成功运行。将readme中的demo代码新建一个python脚本复制进去,然后将脚本放在src目录中运行。如果遇到网络问题无法加载huggingface上的预训练模型,可以手动从。如果出现,以下错误重新。

NeverMakeIt的博客 1085

从多项式到神经网络:DPD算法演进史及其在RRU中的工程实现

本文系统梳理了数字预失真(DPD)算法从经典多项式模型、查表法到神经网络驱动的演进历程,并深入探讨了其在基站射频单元(RRU)中面临的硬件资源约束与工程实现挑战。文章为通信设备的技术决策者提供了算法选型、性能权衡及混合架构设计的实用评估框架,助力在性能、功耗与成本间找到最优平衡。

cherry的博客 1076

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

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

浩瀚之水的专栏 887

树莓派编译程序时遇到卡死的问题

使用树莓派编译程序的时候,我遇到了程序比较大,编译到某个文件的时候树莓派会死机,关机之后重启可以继续使用,但是编译到同一个地方树莓派又死机的问题。 这个问题出现的主要原因是我给树莓派安装的Ubuntu mate 16.04 系统默认设置的swap交换空间不够,而编译某些文件的时候需要较大的交换空间,树莓派的交换空间被用满所以树莓派看起来好像是死机了的样子。 解决方法,扩展Ubuntu的交换空间。 解决方法,扩展Ubu

一杯二锅头 1万+

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

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

qsc901234的博客 182

CF鼠标宏防封指南:手把手教你调校罗技G HUB压枪脚本的延迟与随机数

本文详细解析了如何通过罗技G HUB的Lua脚本功能调校鼠标宏,实现拟真操作体验。重点介绍了随机数应用、动态后坐力补偿和智能操作序列等高级技术,帮助玩家在不违反游戏规则的前提下提升操作精度。

weixin_26841957的博客 334

散户渡劫指南:从炼气期到化神期的量化之路

经常有人问我普通人怎么学习量化交易,我就在想怎么学了量化就不是普通人了吗,可能他的意思是类比修仙,量化素人如何修炼进阶,今天就将量化学习每个阶段均对标修仙境界的核心能力与心法要诀一一介绍,助你从“交易凡人”蜕变为“量化金仙”。

木头大左的博客 1338

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

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

Leon_Chenl的博客 1902

如何在 R 中执行 Kruskal-Wallis 检验

Kruskal-Wallis 检验用于确定三个或更多独立组的中位数之间是否存在统计学上的显着差异。它被认为是单向方差分析的非参数等效项。本教程介绍了如何在 R 中执行 Kruskal-Wallis 检验。示例:R 中的 Kruskal-Wallis 检验 假设研究人员想知道三种不同的肥料是否会导致不同水平的植物生长。他们随机选择 30 种不同的植物并将它们分成三组,每组 10 株,每组施用不同的肥料。在一个月结束时,他们测量每株植物的高度。使用以下步骤执行 Kruskal-Wallis 检验以确定三个组的中

Mrrunsen的博客 3798

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

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

鸿蒙的技术博客 1926

【AI大模型应用开发】【RAG评估】0. 综述:一文了解RAG评估方法、工具与指标

本文主要总结了当前比较流行的RAG评估方法和指标。当前AI技术的快速发展,RAG和RAG评估是当前比较有前景的发展方向,不断有新的评估工具和理论被提出,让我们持续跟进,了解这些工具和理论,从而在使用时知道如何选择。

同学小张的博客 6827

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

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

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值