CLion中avcodec_receive_frame()问题
1. 介绍
在提取音视频文件中音频的PCM数据时,使用avcodec_receive_frame()函数进行解码时,遇到了一些问题,代码在Visual Studio 2022中运行结果符合预期,但是在CLion中运行时,获取的AVFrame有错误,和VS中获得的结果不一样。
FFMpeg 5.1.2
2. 源码
Utils.h
#pragma once#define _CRT_SECURE_NO_WARNINGSextern "C" {
#include <libavutil/error.h>
}static char* wrap_av_err2str(int errnum) {static char str[256] = {0};return av_make_error_string(str, sizeof(str), errnum);
}
AudioDecoder2.h
#pragma onceextern "C"
{
#include "libavutil/log.h"
#include "libavutil/imgutils.h"
#include "libavutil/samplefmt.h"
#include "libavutil/timestamp.h"
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
};
#include "Utils.h"
#include <cinttypes>class AudioDecoder2
{
public:AudioDecoder2();AudioDecoder2(const char* src_filename, const char* dst_filename);~AudioDecoder2();int start();private:int ret;char src_filename[256];char dst_filename[256];FILE* dst_fd = NULL;AVFormatContext* ifmt_ctx = NULL;AVCodecContext* audio_dec_ctx = NULL;const AVCodec* audio_dec = NULL;AVStream* audio_stream = NULL;int audio_stream_index = -1;AVFrame* frame = NULL;AVPacket* packet = NULL;
};
AudioDecoder2.cpp
#include "AudioDecoder2.h"AudioDecoder2::AudioDecoder2(const char* src_filename, const char* dst_filename) {sscanf(src_filename, "%s", this->src_filename);sscanf(dst_filename, "%s", this->dst_filename);
}int AudioDecoder2::start() {// 设置日志输出级别av_log_set_level(AV_LOG_INFO);// 打开输入文件ret = avformat_open_input(&ifmt_ctx, src_filename, NULL, NULL);if (ret < 0){av_log(NULL, AV_LOG_ERROR, "Can't open source file:%s\n", wrap_av_err2str(ret));return -1;}// 读取一部分数据获得一些相关信息ret = avformat_find_stream_info(ifmt_ctx, NULL);if (ret < 0){av_log(NULL, AV_LOG_ERROR, "Failed to find stream information: %s\n", wrap_av_err2str(ret));return -1;}// 查找流audio_stream_index = -1;audio_stream_index = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);if (audio_stream_index < 0){av_log(NULL, AV_LOG_DEBUG, "Failed to find the best audio stream!\n");return AVERROR(EINVAL);}// 获取流audio_stream = ifmt_ctx->streams[audio_stream_index];// 通过数据流查找对应的解码器audio_dec = avcodec_find_decoder(audio_stream->codecpar->codec_id);if (audio_dec == NULL){av_log(NULL, AV_LOG_ERROR, "Failed to find codec.\n");return AVERROR(EINVAL);}// 创建解码器上下文audio_dec_ctx = avcodec_alloc_context3(audio_dec);if (audio_dec_ctx == NULL){av_log(NULL, AV_LOG_ERROR, "Failed to allocate the codec context.\n");return AVERROR(ENOMEM);}// 从输入流中拷贝对应的参数到解码器中ret = avcodec_parameters_to_context(audio_dec_ctx, audio_stream->codecpar);if (ret < 0){av_log(NULL, AV_LOG_ERROR, "Failed to copy codec parameters to decoder context.\n");return ret;}// 打开解码器ret = avcodec_open2(audio_dec_ctx, audio_dec, NULL);if (ret < 0){av_log(NULL, AV_LOG_ERROR, "Failed to open codec.\n");return ret;}// 创建输出文件dst_fd = fopen(dst_filename, "wb");if (!dst_fd){av_log(NULL, AV_LOG_ERROR, "Could not open destination file %s\n", dst_filename);return -1;}// 分配帧frame = av_frame_alloc();if (frame == NULL){av_log(NULL, AV_LOG_ERROR, "Failed to allocate frame.\n");return AVERROR(ENOMEM);}// 分配数据包packet = av_packet_alloc();if (packet == NULL){av_log(NULL, AV_LOG_ERROR, "Failed to allocate packet.\n");return AVERROR(ENOMEM);}// 读取音频流的数据包,并解码while (av_read_frame(ifmt_ctx, packet) >= 0){if (packet->stream_index == audio_stream_index){ret = avcodec_send_packet(audio_dec_ctx, packet);if (ret < 0){av_log(NULL, AV_LOG_ERROR, "Failed to decode packet.\n");return ret;}// 对数据进行解码输出while (ret >= 0){ret = avcodec_receive_frame(audio_dec_ctx, frame);if (ret < 0){if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)){break;}else{break;}}if (ret == 0){// 将内容输出到文件av_log(NULL, AV_LOG_INFO, "pts:%10" PRId64"\t packet size:%d\n",packet->pts, packet->size);size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample((enum AVSampleFormat)frame->format);fwrite(frame->extended_data[0], 1, unpadded_linesize, dst_fd);}av_frame_unref(frame);}}av_packet_unref(packet);}// 刷新解码器while (true){if (!(audio_dec->capabilities & AV_CODEC_CAP_DELAY)){return 0;}ret = avcodec_send_packet(audio_dec_ctx, packet);if (ret < 0){// av_log(NULL, AV_LOG_ERROR, "Failed to decode packet.\n");// return ret;break;}// 对数据进行解码输出while (ret >= 0){ret = avcodec_receive_frame(audio_dec_ctx, frame);if (ret < 0){if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)){break;}}// 将内容输出到文件size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample((enum AVSampleFormat)frame->format);fwrite(frame->extended_data[0], 1, unpadded_linesize, dst_fd);av_frame_unref(frame);}av_packet_unref(packet);}// 释放资源avcodec_free_context(&audio_dec_ctx);avformat_close_input(&ifmt_ctx);if (dst_fd){fclose(dst_fd);}av_packet_free(&packet);av_frame_free(&frame);return 0;
}
main.cpp
#include <iostream>
#include "AudioDecoder2.h"
using namespace std;int main(int argc, char** argv)
{char src_filename[20] = "ball_10s.mp4";char audio_dst_filename[20] = "ball_10s.pcm";AudioDecoder2* audioDecoder2 = new AudioDecoder2(src_filename, audio_dst_filename);audioDecoder2->start();return 0;
}
3. 问题
Visual Studio 2022调试结果

CLion中调试结果

相关文章:
CLion中avcodec_receive_frame()问题
1. 介绍 在提取音视频文件中音频的PCM数据时,使用avcodec_receive_frame()函数进行解码时,遇到了一些问题,代码在Visual Studio 2022中运行结果符合预期,但是在CLion中运行时,获取的AVFrame有错误,和VS中获…...
Linux安装操作(Mac版本)
Parallels Desktop的简介 Parallels Desktop是Mac平台上的虚拟机软件,也是Mac平台最好的虚拟机软件之一。它允许用户在Mac OS X系统上同时运行其他操作系统,例如Windows、Linux等。Parallels Desktop为Mac用户提供了使用其他操作系统和软件的便利性&…...
Linux(四)--包软件管理器与Linux上软件的下载示例
一.包软件管理器【yum和apt】 1.先来学习使用yum命令。yum:RPM包软件管理器,用于自动化安装配置Linux软件,并可以自动解决依赖问题。通过yum命令我们可以轻松实现软件的下载,查找,卸载与更新等管理软件的操作。 最常用…...
HTML <param> 标签
实例 向 HTML 代码添加一个对象: <object classid="clsid:F08DF954-8592-11D1-B16A-00C0F0283628" id="Slider1" width="100" height="50"><param name="BorderStyle" value="1" /><param nam…...
基于ARM+FPGA (STM32+ Cyclone 4)的滚动轴承状态监测系统
状态监测系统能够在故障早期及时发现机械设备的异常状态,避免故障的 进一步恶化造成不必要的损失,滚动轴承是机械设备的易损部件,本文对以滚动 轴承为研究对象的状态监测系统展开研究。现有的监测技术多采用定时上传监 测数据,…...
二、数据结构10:堆 模板题+算法模板(堆排序,模拟堆)
文章目录 算法模板堆题目代码模板堆的原理down操作理解:up操作理解建堆操作关于heap_swap中存的映射数组理解(模拟堆题目中用到) 模板题堆排序原题链接题目思路题解 模拟堆原题链接题目思路题解 算法模板 堆题目代码模板 // h[N]存储堆中的…...
W6100-EVB-PICO做DNS Client进行域名解析
前言 在上一章节中我们用W6100-EVB-PICO通过dhcp获取ip地址(网关,子网掩码,dns服务器)等信息,给我们的开发板配置网络信息,成功的接入网络中,那么本章将教大家如何让我们的开发板进行DNS域名解…...
【linux-网络】4层转发方法-iptable以及nginx
1.背景 有时候远程或者某些业务需要做转发就会用到iptables或者nginx,或者ss都可以 根据自己的情况去适配。 2.方法: 1)iptables -把linux内核转发功能打开 echo "net.ipv4.ip_forward1" >> /etc/sysctl.conf -出入转发…...
vue复制文案,复制图片,黏贴图片
vue 实现复制文案,复制图片,在微信聊天框,黏贴为图片 //安装 cnpm i clipboard-all //引用 import clipboard from clipboard-all<!-- row.url 图片路径 --><div ref"foo" class"hidden"><img :src"…...
Web应急思路
Web应急思路 找到webshell --> 确定攻击者IP --> 回溯攻击者操作 --> 梳理整个攻击过程 1.寻找webshell方法 1.文件内容中的恶意函数 2.web日志中的webshell特征 3.贴合web业务中的URL来分析web日志 4.源码版本管理对比,注重修改或新增的脚本文件 5.统计…...
shell脚本清理redis模糊匹配的多个key,并计算释放内存大小
#!/bin/bash# 定义Redis服务器地址和端口 REDIS_HOST"localhost" REDIS_PORT6380# 获取Redis当前内存使用量(以字节为单位) function get_redis_memory_usage() {redis-cli -h $REDIS_HOST -p $REDIS_PORT INFO memory | grep "used_memo…...
python-MySQL数据库建表语句(需要连接数据库)转存为Excel文档-工作小记
将create table XXXXXX 转为指定Excel文档。该脚本适用于数据库表结构本地文档记录 呈现效果 代码 # -*- coding:utf-8 -*- # Time : 2023/8/2 15:14 # Author: 水兵没月 # File : MySQL建表_2_excel.py import reimport mysql.connector import pandas as pd db 库名 mydb …...
iOS Block介绍
文章目录 一、Block定义二、block为什么用copy修饰三、block使用时的注意事项四、使用 block时什么情况会发生引用循环,如何解决?五、在block内如何修改block外部变量?六、__block与__weak的区别 一、Block定义 目的就是能够直接存储一个代码…...
小程序安全性加固:如何保护用户数据和防止恶意攻击
第一章:引言 在当今数字化时代,移动应用程序的使用已经成为人们日常生活中的重要组成部分。小程序作为一种轻量级的应用程序形式,受到了广泛的欢迎。然而,随着小程序的流行,安全性问题也日益凸显。用户数据泄露和恶意攻…...
Ubuntu的tar命令详解
在 Ubuntu 中压缩文件夹可以使用 tar 命令。tar 可以将多个文件或文件夹打成一个包,并可选是否进行压缩,最常用的压缩方式是 gzip 和 bzip2。 常用的 tar 命令参数如下: -c:创建新的 tar 包; -x:解压 tar…...
使用elementplus实现文本框的粘贴复制
需求: 文本框仅用于显示展示数据并且用户可以进行复制,并不会进行修改和编辑, 注意点: 1.首先且文本为多行。所以不能使用普通的el-input,这种一行超出就会隐藏了,如果多行超出行数也会隐藏(…...
计算机毕设 深度学习卫星遥感图像检测与识别 -opencv python 目标检测
文章目录 0 前言1 课题背景2 实现效果3 Yolov5算法4 数据处理和训练5 最后 0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长…...
devops(前端)
1.前言 前端的打包流程和后端的流程是一样的,只是打包的环境和制作的镜像有所不同,前端需要使用nodejs环境打包,镜像也是使用nginx镜像,因为用的是k8s的pod运行镜像,还需要使用configmap挂载nginx的配置,一…...
SpringBoot中MongoDB的使用
SpringBoot中MongoDB的使用 MongoDB 是最早热门非关系数据库的之一,使用也比较普遍,一般会用做离线数据分析来使用,放到内网的居 多。由于很多公司使用了云服务,服务器默认都开放了外网地址,导致前一阵子大批 MongoD…...
Spring学习之GOF的工厂模式
文章目录 工厂模式的三种形态简单工厂模式工厂方法模式抽象工厂模式(了解) 设计模式:一种可以杯冲覅利用的解决方案GoF(Gang of Four),中文名——四人组《Design Patterns: Elements of Reusable Object-Or…...
张量维度操控心法:从reshape到升维降维,吃透PyTorch形状操作的底层逻辑
✨ 张量维度操控心法:从reshape到升维降维,吃透PyTorch形状操作的底层逻辑🔐 张量形状操作的黄金法则:形状是视角,内容是本质🔧 reshape函数:零侵入的形状重塑神器核心原理与执行规则实操代码与…...
Python中CSV文件处理的常见累积错误及修正方案
在使用 Python 的 csv 模块处理学生成绩数据时,一个极易被忽视却影响结果准确性的典型问题是变量作用域与重用逻辑错误。如原始代码所示,grades [] 被定义在 for row in reader: 循环外部,导致每次迭代都将新学生的成绩追加到同一个列表中—…...
灵毓秀-牧神-造相Z-Turbo使用全攻略:从环境检查到作品输出
灵毓秀-牧神-造相Z-Turbo使用全攻略:从环境检查到作品输出 1. 镜像简介与核心功能 灵毓秀-牧神-造相Z-Turbo是一款基于Xinference部署的AI文生图模型服务,专门用于生成《牧神记》中灵毓秀角色的高质量图像。该镜像集成了Gradio交互界面,让用…...
告别底噪和电流声:DIY蓝牙音箱的音频电路避坑指南(从TPA2019布线到电源滤波)
蓝牙音箱DIY进阶指南:从电路设计到音质优化的全流程解析 在电子DIY领域,蓝牙音箱制作看似简单,但要实现专业级的音质表现却需要跨越诸多技术门槛。许多爱好者完成基础组装后,常会遇到底噪明显、高频失真或低频浑浊等问题——这往往…...
快速体验WAN2.2文生视频:ComfyUI预置工作流,2分钟生成测试视频
快速体验WAN2.2文生视频:ComfyUI预置工作流,2分钟生成测试视频 1. 为什么选择WAN2.2文生视频工作流 如果你正在寻找一个简单易用、效果出色的文生视频工具,WAN2.2文生视频工作流绝对值得一试。这个预置在ComfyUI中的工作流,让视…...
C++的std--allocator_traits分配器特性与自定义内存管理的适配
C标准库中的内存管理一直是个既基础又复杂的主题。std::allocator_traits作为C11引入的分配器特性模板,为自定义内存管理提供了统一的适配接口,让开发者能在不重写整套分配逻辑的情况下,灵活扩展内存管理策略。无论是实现高性能内存池&#x…...
解决Gradio share=True报错:手动下载并配置frpc_linux_amd64_v0.3文件的保姆级教程
解决Gradio shareTrue报错的完整实战指南:从手动配置frpc到深度优化 当你兴奋地准备向客户展示刚完成的Gradio应用时,却在终端看到红色的报错信息——shareTrue参数失效了。这种场景对开发者来说再熟悉不过:本地调试一切正常,但需…...
PN5180 ISO15693协议栈实现与嵌入式NFC开发指南
1. PN5180库深度解析:面向嵌入式工程师的NFC ISO15693协议栈实现指南NXP PN5180是业界领先的多协议NFC控制器,支持ISO/IEC 14443 A/B、ISO/IEC 15693、Felica及NFC Forum Type 1–5标签。其核心优势在于高集成度射频前端、可编程调制解调器及灵活的主机接…...
你的文件真的‘上传’了吗?聊聊阿里云盘‘秒传’背后的隐私与安全考量
你的文件真的“上传”了吗?揭秘秒传技术背后的隐私博弈 第一次在阿里云盘体验“秒传”功能时,那种近乎魔法的速度确实令人惊叹——几个GB的文件眨眼间就完成了“上传”。但惊喜之余,一个更根本的问题浮现出来:我的文件真的被上传了…...
Qwen3.5-4B助力Python爬虫:智能解析与数据清洗实战
Qwen3.5-4B助力Python爬虫:智能解析与数据清洗实战 1. 爬虫开发者的新困境 最近和几个做数据抓取的朋友聊天,发现大家普遍遇到一个头疼的问题:现在的网站越来越难爬了。以前写个正则表达式或者XPath就能搞定的事情,现在经常要面…...
