当前位置: 首页 > news >正文

CLion中avcodec_receive_frame()问题

1. 介绍

在提取音视频文件中音频的PCM数据时,使用avcodec_receive_frame()函数进行解码时,遇到了一些问题,代码在Visual Studio 2022中运行结果符合预期,但是在CLion中运行时,获取的AVFrame有错误,和VS中获得的结果不一样。

FFMpeg 5.1.2

2. 源码

  1. 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);
}
  1. 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;
};
  1. 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;
}
  1. 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. 问题

  1. Visual Studio 2022调试结果

在这里插入图片描述

  1. CLion中调试结果

在这里插入图片描述

相关文章:

CLion中avcodec_receive_frame()问题

1. 介绍 在提取音视频文件中音频的PCM数据时&#xff0c;使用avcodec_receive_frame()函数进行解码时&#xff0c;遇到了一些问题&#xff0c;代码在Visual Studio 2022中运行结果符合预期&#xff0c;但是在CLion中运行时&#xff0c;获取的AVFrame有错误&#xff0c;和VS中获…...

Linux安装操作(Mac版本)

Parallels Desktop的简介 Parallels Desktop是Mac平台上的虚拟机软件&#xff0c;也是Mac平台最好的虚拟机软件之一。它允许用户在Mac OS X系统上同时运行其他操作系统&#xff0c;例如Windows、Linux等。Parallels Desktop为Mac用户提供了使用其他操作系统和软件的便利性&…...

Linux(四)--包软件管理器与Linux上软件的下载示例

一.包软件管理器【yum和apt】 1.先来学习使用yum命令。yum&#xff1a;RPM包软件管理器&#xff0c;用于自动化安装配置Linux软件&#xff0c;并可以自动解决依赖问题。通过yum命令我们可以轻松实现软件的下载&#xff0c;查找&#xff0c;卸载与更新等管理软件的操作。 最常用…...

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)的滚动轴承状态监测系统

状态监测系统能够在故障早期及时发现机械设备的异常状态&#xff0c;避免故障的 进一步恶化造成不必要的损失&#xff0c;滚动轴承是机械设备的易损部件&#xff0c;本文对以滚动 轴承为研究对象的状态监测系统展开研究。现有的监测技术多采用定时上传监 测数据&#xff0c;…...

二、数据结构10:堆 模板题+算法模板(堆排序,模拟堆)

文章目录 算法模板堆题目代码模板堆的原理down操作理解&#xff1a;up操作理解建堆操作关于heap_swap中存的映射数组理解&#xff08;模拟堆题目中用到&#xff09; 模板题堆排序原题链接题目思路题解 模拟堆原题链接题目思路题解 算法模板 堆题目代码模板 // h[N]存储堆中的…...

W6100-EVB-PICO做DNS Client进行域名解析

前言 在上一章节中我们用W6100-EVB-PICO通过dhcp获取ip地址&#xff08;网关&#xff0c;子网掩码&#xff0c;dns服务器&#xff09;等信息&#xff0c;给我们的开发板配置网络信息&#xff0c;成功的接入网络中&#xff0c;那么本章将教大家如何让我们的开发板进行DNS域名解…...

【linux-网络】4层转发方法-iptable以及nginx

1.背景 有时候远程或者某些业务需要做转发就会用到iptables或者nginx&#xff0c;或者ss都可以 根据自己的情况去适配。 2.方法&#xff1a; 1&#xff09;iptables -把linux内核转发功能打开 echo "net.ipv4.ip_forward1" >> /etc/sysctl.conf -出入转发…...

vue复制文案,复制图片,黏贴图片

vue 实现复制文案&#xff0c;复制图片&#xff0c;在微信聊天框&#xff0c;黏贴为图片 //安装 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.源码版本管理对比&#xff0c;注重修改或新增的脚本文件 5.统计…...

shell脚本清理redis模糊匹配的多个key,并计算释放内存大小

#!/bin/bash# 定义Redis服务器地址和端口 REDIS_HOST"localhost" REDIS_PORT6380# 获取Redis当前内存使用量&#xff08;以字节为单位&#xff09; 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时什么情况会发生引用循环&#xff0c;如何解决&#xff1f;五、在block内如何修改block外部变量&#xff1f;六、__block与__weak的区别 一、Block定义 目的就是能够直接存储一个代码…...

小程序安全性加固:如何保护用户数据和防止恶意攻击

第一章&#xff1a;引言 在当今数字化时代&#xff0c;移动应用程序的使用已经成为人们日常生活中的重要组成部分。小程序作为一种轻量级的应用程序形式&#xff0c;受到了广泛的欢迎。然而&#xff0c;随着小程序的流行&#xff0c;安全性问题也日益凸显。用户数据泄露和恶意攻…...

Ubuntu的tar命令详解

在 Ubuntu 中压缩文件夹可以使用 tar 命令。tar 可以将多个文件或文件夹打成一个包&#xff0c;并可选是否进行压缩&#xff0c;最常用的压缩方式是 gzip 和 bzip2。 常用的 tar 命令参数如下&#xff1a; -c&#xff1a;创建新的 tar 包&#xff1b; -x&#xff1a;解压 tar…...

使用elementplus实现文本框的粘贴复制

需求&#xff1a; 文本框仅用于显示展示数据并且用户可以进行复制&#xff0c;并不会进行修改和编辑&#xff0c; 注意点&#xff1a; 1.首先且文本为多行。所以不能使用普通的el-input&#xff0c;这种一行超出就会隐藏了&#xff0c;如果多行超出行数也会隐藏&#xff08;…...

计算机毕设 深度学习卫星遥感图像检测与识别 -opencv python 目标检测

文章目录 0 前言1 课题背景2 实现效果3 Yolov5算法4 数据处理和训练5 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长…...

devops(前端)

1.前言 前端的打包流程和后端的流程是一样的&#xff0c;只是打包的环境和制作的镜像有所不同&#xff0c;前端需要使用nodejs环境打包&#xff0c;镜像也是使用nginx镜像&#xff0c;因为用的是k8s的pod运行镜像&#xff0c;还需要使用configmap挂载nginx的配置&#xff0c;一…...

SpringBoot中MongoDB的使用

SpringBoot中MongoDB的使用 MongoDB 是最早热门非关系数据库的之一&#xff0c;使用也比较普遍&#xff0c;一般会用做离线数据分析来使用&#xff0c;放到内网的居 多。由于很多公司使用了云服务&#xff0c;服务器默认都开放了外网地址&#xff0c;导致前一阵子大批 MongoD…...

Spring学习之GOF的工厂模式

文章目录 工厂模式的三种形态简单工厂模式工厂方法模式抽象工厂模式&#xff08;了解&#xff09; 设计模式&#xff1a;一种可以杯冲覅利用的解决方案GoF&#xff08;Gang of Four&#xff09;&#xff0c;中文名——四人组《Design Patterns: Elements of Reusable Object-Or…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

Vue 模板语句的数据来源

&#x1f9e9; Vue 模板语句的数据来源&#xff1a;全方位解析 Vue 模板&#xff08;<template> 部分&#xff09;中的表达式、指令绑定&#xff08;如 v-bind, v-on&#xff09;和插值&#xff08;{{ }}&#xff09;都在一个特定的作用域内求值。这个作用域由当前 组件…...

Spring Security 认证流程——补充

一、认证流程概述 Spring Security 的认证流程基于 过滤器链&#xff08;Filter Chain&#xff09;&#xff0c;核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤&#xff1a; 用户提交登录请求拦…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...

论文阅读:Matting by Generation

今天介绍一篇关于 matting 抠图的文章&#xff0c;抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法&#xff0c;已经有很多的工作和这个任务相关。这两年 diffusion 模型很火&#xff0c;大家又开始用 diffusion 模型做各种 CV 任务了&am…...

Vue3 PC端 UI组件库我更推荐Naive UI

一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用&#xff0c;前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率&#xff0c;还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库&#xff08;Naive UI、Element …...