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…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
【Linux】自动化构建-Make/Makefile
前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具:make/makfile 1.背景 在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mak…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
C# winform教程(二)----checkbox
一、作用 提供一个用户选择或者不选的状态,这是一个可以多选的控件。 二、属性 其实功能大差不差,除了特殊的几个外,与button基本相同,所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...
