avcodec_send_packet函数阻塞
用ffmpeg4.1.4开发一个播放器,解码过程如下,在每个函数前设置标志,测试发现程序阻塞在avcodec_send_packet函数。
while(true){av_read_frameavcodec_send_packetavcodec_receive_frameav_packet_unref
}
解释如下:
avcodec_send_packet 和 avcodec_receive_frame 的工作原理是,avcodec_send_packet 向解码器发送压缩数据包,而 avcodec_receive_frame 从解码器接收解码后的帧。解码器内部有一个缓冲区,用于存储解码过程中间的数据。如果缓冲区已满(即没有足够的空间来存储新的数据包),avcodec_send_packet 就会阻塞,直到有足够的空间。
我用的是处理器是rk3288,后台打印信息如下:
[h264_rkmpp @ 0xa5795e20] Received a frame.
[h264_rkmpp @ 0xa5795e20] Wrote 1615 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Received a frame.
[h264_rkmpp @ 0xa5795e20] Wrote 2107 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Received a frame.
[h264_rkmpp @ 0xa5795e20] Wrote 2064 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Received a frame.
[h264_rkmpp @ 0xa5795e20] Wrote 1504 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Received a frame.
[h264_rkmpp @ 0xa5795e20] Wrote 2588 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Received a frame.
[h264_rkmpp @ 0xa5795e20] Wrote 1642 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Received a frame.
[h264_rkmpp @ 0xa5795e20] Wrote 1721 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Received a frame.
[h264_rkmpp @ 0xa5795e20] Wrote 1437 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Wrote 2307 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Wrote 1427 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Wrote 1638 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Wrote 2303 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Wrote 1342 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Wrote 2193 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Wrote 1567 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Wrote 2247 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Wrote 1396 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Wrote 2375 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Wrote 1520 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Wrote 1663 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Wrote 2273 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Wrote 1288 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Wrote 2340 bytes to decoder
[h264_rkmpp @ 0xa5795e20] Wrote 1399 bytes to decoder
那avcodec_send_packe函数为什么会“get a frame”呢?源码如下,猜测是阻塞到这里
int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
{AVCodecInternal *avci = avctx->internal;int ret;if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec))return AVERROR(EINVAL);if (avctx->internal->draining)return AVERROR_EOF;if (avpkt && !avpkt->size && avpkt->data)return AVERROR(EINVAL);av_packet_unref(avci->buffer_pkt);if (avpkt && (avpkt->data || avpkt->side_data_elems)) {ret = av_packet_ref(avci->buffer_pkt, avpkt);if (ret < 0)return ret;}ret = av_bsf_send_packet(avci->filter.bsfs[0], avci->buffer_pkt);if (ret < 0) {av_packet_unref(avci->buffer_pkt);return ret;}if (!avci->buffer_frame->buf[0]) {ret = decode_receive_frame_internal(avctx, avci->buffer_frame);if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)return ret;}return 0;
}static int decode_simple_receive_frame(AVCodecContext *avctx, AVFrame *frame)
{int ret;while (!frame->buf[0]) {ret = decode_simple_internal(avctx, frame);if (ret < 0)return ret;}return 0;
}
解决方法:
1、在调用 avcodec_send_packet 之前,可以先调用 avcodec_receive_frame,即使你不确定是否有帧可以接收。这有助于清理缓冲区。
2、在while循环中等待avcodec_receive_frame
ret = avcodec_send_packet(codec_ctx, packet); while (ret >= 0) {AVFrame *frame = av_frame_alloc();if (!frame) {// 处理内存分配错误return AVERROR(ENOMEM);}ret = avcodec_receive_frame(codec_ctx, frame);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {// 没有更多帧可以接收,退出循环av_frame_free(&frame);break;} else if (ret < 0) {// 处理接收帧错误av_frame_free(&frame);return ret;}}
3、正常情况下向解码器发送一包数据会收到一个解码后的帧,因此增加一个检测机制,当多次发送数据包但没有收到解码帧后则重置解码器。
void reset_decoder(AVCodecContext* codecContext) {// 刷新解码器缓冲区avcodec_flush_buffers(codecContext);// 关闭解码器avcodec_close(codecContext);// 重新打开解码器if (avcodec_open2(codecContext, codecContext->codec, nullptr) < 0) {std::cerr << "Could not re-open codec" << std::endl;}
}
相关文章:
avcodec_send_packet函数阻塞
用ffmpeg4.1.4开发一个播放器,解码过程如下,在每个函数前设置标志,测试发现程序阻塞在avcodec_send_packet函数。 while(true){av_read_frameavcodec_send_packetavcodec_receive_frameav_packet_unref } 解释如下: avcodec_se…...
一个parquet-go例子
一个parquet-go例子 使用go读写parquet,使用到了框架github.com/xitongsys/parquet-go 代码: package mainimport ("log""time""github.com/xitongsys/parquet-go-source/local""github.com/xitongsys/parquet-go/parquet&qu…...
扩散模型笔记
长参数“T”决定了生成全噪声图像所需的步长。在本文中,该参数被设置为1000,这可能显得很大。我们真的需要为数据集中的每个原始图像创建1000个噪声图像吗?马尔可夫链方面被证明有助于解决这个问题。由于我们只需要上一步的图像来预测下一步,…...
上海-LM科技(面经)
上海-LM科技 hr电话面 个人简介 个人信息的询问 是否知道芋道框架 技术面 算法题 14. 最长公共前缀(写出来即可) 聊一下Docker Docker核心概念总结Docker实战 聊一下AOP Spring AOP详解 聊一下JWT JWT 基础概念详解JWT 身份认证优缺点分析 Spring…...
用 Echarts 画折线图
https://andi.cn/page/621503.html...
C++的map / multimap容器
一、介绍 在C的map / multimap容器中,所有的元素均是pair类型(有关pair类型可以参考我之前写的 《C的set / multiset容器》的3.2中有介绍到)。 每对pair的第一个元素被称为关键字key,第二个元素被称为值value。因此,ma…...
双向链表 -- 详细理解和实现
欢迎光顾我的homepage 前言 双向链表是一种带头双向循环的链表。在双向链表中,首先存在着一个头结点;其次每个节点有指向下一个节点的指针next 和指向上一个节点的指针prev ;…...
WebGIS面试题
文章目录 1. 前端1.1. 选择器的优先级1.2. CSS 中它的布局有哪些?1.3. CSS3 的新特性1.4. CSS 的两种盒子模型1.5. CSS 的伪元素选择器和伪类选择器有哪些?1.6. ES6 的新特性1.7. 谈谈你对 promise 的理解1.8. 简单说一下原型链1.9. 简单说一下深浅拷贝1…...
代码随想录算法训练营:21/60
非科班学习算法day21 | LeetCode669:修剪二叉搜索树 ,Leetcode108:将有序数组转换为二叉搜索树 ,Leetcode538:把二叉搜索树转换为累加树 介绍 包含LC的两道题目,还有相应概念的补充。 相关图解和更多版本: 代码随想录 (progra…...
数据结构——二叉树之c语言实现堆与堆排序
目录 前言: 1.二叉树的概念及结构 1.1 特殊的二叉树 1.2 二叉树的存储结构 1.顺序存储 2.链式存储 2. 二叉树的顺序结构及实现 2.1 堆的概念 编辑 2.2 堆的创建 3.堆的实现 3.1 堆的初始化和销毁 初始化: 销毁: 插入&…...
#数据结构 链表
单向链表 1. 概念 单向链表 单向循环链表 双向链表 双向循环链表 解决:长度固定的问题,插入和删除麻烦的问题 1、逻辑结构: 线性结构 2、存储结构: 链式存储 链表就是将 结点 用链串起来的线性表,链就是 结点 中的…...
单片机软件架构连载(4)-结构体
枚举、指针、结构体,我愿称为C语言"三板斧"。 用人话来讲,几乎所有c语言高阶编程,都离不开这这3个知识点的应用。 今天站在实际产品常用的角度,给大家讲一下结构体。 1.结构体概念 结构体可以用来构建更复杂的数据结…...
工厂方法模式在金融业务中的应用及其框架实现
引言 工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它定义了一个创建对象的接口,但由子类决定实例化哪一个类。工厂方法模式使得类的实例化延迟到子类。在金融业务中,工厂方法模式可以用于创建不同类型…...
python库(6):Pygments库
1 Pygments介绍 在软件开发和文档编写中,代码的可读性是至关重要的一环。无论是在博客文章、技术文档还是教程中,通过代码高亮可以使程序代码更加清晰和易于理解。而在Python世界中,Pygments库就是这样一个强大的工具,它能够将各…...
金斗云 HKMP智慧商业软件 任意用户创建漏洞复现
0x01 产品简介 金斗云智慧商业软件是一款功能强大、易于使用的智慧管理系统,通过智能化的管理工具,帮助企业实现高效经营、优化流程、降低成本,并提升客户体验。无论是珠宝门店、4S店还是其他零售、服务行业,金斗云都能提供量身定制的解决方案,助力企业实现数字化转型和智…...
前端JS特效第24集:jquery css3实现瀑布流照片墙特效
jquery css3实现瀑布流照片墙特效,先来看看效果: 部分核心的代码如下(全部代码在文章末尾): <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8" /> <title>jquerycss3实现瀑…...
区块链论文速读A会-ISSTA 2023(2/2)如何检测DeFi协议中的价格操纵漏洞
Conference:ACM SIGSOFT International Symposium on Software Testing and Analysis (ISSTA) CCF level:CCF A Categories:Software Engineering/System Software/Programming Languages Year:2023 第1~5篇区块链文章 请点击此…...
权力之望怎么下载客户端 权力之望一键下载
《权力之望》是一款由NX3 Games开发、Smilegate发行的多人在线动作MMORPG游戏。这款游戏最大的特点是高度的自由度和丰富的角色定制选项。我们在游戏中不仅可以自由更换武器,而且游戏还提供了54种能力和60多种职业选择,让我们可以根据自己的游戏风格和喜…...
Oracle PL/SQL 循环批量执行存储过程
1. 查询存储过程 根据数据字典USER_OBJECTS查询出所有存储过程。 2. 动态拼接字符串(参数等) 根据数据字典USER_ARGUMENTS动态拼接参数。 3. 动态执行 利用EXECUTE IMMEDIATE动态执行无名块。 4. 输出执行信息 利用DBMS_OUTPUT.PUT_LINE输出执行成功与…...
kafka 生产者
生产者 生产者负责创建消息,然后将其投递到Kafka中。 负载均衡 轮询策略。随机策略。按照 key 进行hash。 Kafka 的默认分区策略:如果指定了 key,key 相同的消息会发送到同一个分区(分区有序);如果没有…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
