ffmpeg aac s16 encode_audio.c

用ffmpeg库时,用代码对pcm内容采用aac编码进行压缩,出现如下错误。

[aac @ 000002bc5edc6e40] Format aac detected only with low score of 1, misdetection possible!
[aac @ 000002bc5edc8140] Error decoding AAC frame header.
[aac @ 000002bc5edc8140] More than one AAC RDB per ADTS frame is not implemented. Update your FFmpeg version to the newest one from Git. If the problem still occurs, it means that your file has a feature which has not been implemented.
[aac @ 000002bc5edc8140] Multiple frames in a packet.
[aac @ 000002bc5edc8140] Sample rate index in program config element does not match the sample rate index configured by the container.
[aac @ 000002bc5edc8140] Too large remapped id is not implemented. Update your FFmpeg version to the newest one from Git. If the problem still occurs, it means that your file has a feature which has not been implemented.
[aac @ 000002bc5edc8140] If you want to help, upload a sample of this file to https://streams.videolan.org/upload/ and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)
[aac @ 000002bc5edc8140] Sample rate index in program config element does not match the sample rate index configured by the container.
[aac @ 000002bc5edc8140] channel element 1.3 is not allocated
[aac @ 000002bc5edc8140] SBR was found before the first channel element.
[aac @ 000002bc5edc8140] channel element 3.6 is not allocated
[aac @ 000002bc5edc8140] channel element 2.12 is not allocated
[aac @ 000002bc5edc8140] Assuming an incorrectly encoded 7.1 channel layout instead of a spec-compliant 7.1(wide) layout, use -strict 1 to decode according to the specification instead.
[aac @ 000002bc5edc8140] channel element 3.12 is not allocated
[aac @ 000002bc5edc6e40] Packet corrupt (stream = 0, dts = NOPTS).
[aac @ 000002bc5edc8140] channel element 1.9 is not allocated
[aac @ 000002bc5edc6e40] Estimating duration from bitrate, this may be inaccurate
[aac @ 000002bc5edc6e40] Could not find codec parameters for stream 0 (Audio: aac (LTP), 3.0, fltp, 505 kb/s): unspecified sample rate
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options 

过程分析:

数据源是无压缩的pcm数据(cr:44100, cn=2(stereo) , format:s16 ) 。
同样的内容如果使用命令行进行压缩
ffmpeg -i E:/video/out.pcm -ar 44100 -b 128K -ac 2 -c:a aac_mf E:/video/out1.aac -y
进行压缩,发现能进行播放。
(ffmpeg中的aac不支持s16格式数据,aac_mf才支持,可以用ffmpeg -h encoder=aac 查看)

使用代码进行压缩出现上图右边的错误。测试代码是从ffmpeg/doc/example/encode_audio.c上进行更改的。
没有进入ffmpeg源码进行调试,只能从现有的结果进行分析,发现代码生成的内容大小是没有问题的,但是被ffmpeg错误解析。猜测应该是数据包头解析错误。但是因为之前没有做过aac编码,真是瞎子摸象,一句一句的修改测试,无果。

最后在网上找到一个能运行的demo才解决问题:FFmpeg简单使用:音频编码 ---- pcm转aac_avframe 音频 aac-CSDN博客 

最后发现原因是aac编码后的数据包写入文件时需要额外写入数据包头,而demo中的代码太简单,根本没有这个步骤,下面是代码示例:

static void get_adts_header(AVCodecContext *ctx, uint8_t *adts_header, int aac_length)
{uint8_t freq_idx = 0;    //0: 96000 Hz  3: 48000 Hz 4: 44100 Hzswitch (ctx->sample_rate) {case 96000: freq_idx = 0; break;case 88200: freq_idx = 1; break;case 64000: freq_idx = 2; break;case 48000: freq_idx = 3; break;case 44100: freq_idx = 4; break;case 32000: freq_idx = 5; break;case 24000: freq_idx = 6; break;case 22050: freq_idx = 7; break;case 16000: freq_idx = 8; break;case 12000: freq_idx = 9; break;case 11025: freq_idx = 10; break;case 8000: freq_idx = 11; break;case 7350: freq_idx = 12; break;default: freq_idx = 4; break;}uint8_t chanCfg = ctx->channels;uint32_t frame_length = aac_length + 7;adts_header[0] = 0xFF;adts_header[1] = 0xF1;adts_header[2] = ((ctx->profile) << 6) + (freq_idx << 2) + (chanCfg >> 2);adts_header[3] = (((chanCfg & 3) << 6) + (frame_length  >> 11));adts_header[4] = ((frame_length & 0x7FF) >> 3);adts_header[5] = (((frame_length & 7) << 5) + 0x1F);adts_header[6] = 0xFC;
}static void encode(AVCodecContext *ctx, AVFrame *frame, AVPacket *pkt,FILE *output)
{int ret;/* send the frame for encoding */ret = avcodec_send_frame(ctx, frame);if (ret < 0) {fprintf(stderr, "Error sending the frame to the encoder\n");exit(1);}/* read all the available output packets (in general there may be any* number of them */while (ret >= 0) {ret = avcodec_receive_packet(ctx, pkt);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)return;else if (ret < 0) {fprintf(stderr, "Error encoding audio frame\n");exit(1);}//额外写入包头uint8_t aac_header[7];get_adts_header(ctx, aac_header, pkt->size);size_t len = 0;len = fwrite(aac_header, 1, 7, output);if(len != 7) {fprintf(stderr, "fwrite aac_header failed\n");return -1;}//        printf("%d:%d\n",count++,pkt->pts);fwrite(pkt->data, 1, pkt->size, output);//av_packet_unref(pkt);}
}int main(int argc, char **argv)
{const char *filename;const AVCodec *codec;AVCodecContext *c= NULL;AVFrame *frame;AVPacket *pkt;int i, j, k, ret;FILE *f;uint16_t *samples;float t, tincr;filename="E:/video/out.aac";/* find the MP2 encoder *///codec = avcodec_find_encoder(AV_CODEC_ID_MP2);//codec = avcodec_find_encoder(AV_CODEC_ID_AAC);//printf("%s\n",avcodec_get_id( AV_CODEC_ID_AAC_LATM));codec = avcodec_find_encoder_by_name("aac_mf");if (!codec) {fprintf(stderr, "Codec not found\n");exit(1);}c = avcodec_alloc_context3(codec);if (!c) {fprintf(stderr, "Could not allocate audio codec context\n");exit(1);}/* put sample parameters */c->bit_rate = 64000;/* check that the encoder supports s16 pcm input */c->sample_fmt = AV_SAMPLE_FMT_S16;if (!check_sample_fmt(codec, c->sample_fmt)) {fprintf(stderr, "Encoder does not support sample format %s",av_get_sample_fmt_name(c->sample_fmt));exit(1);}//c->profile = FF_PROFILE_AAC_LOW;  c->bit_rate为0,c->profile设置才会有效/* select other audio parameters supported by the encoder */c->sample_rate    = select_sample_rate(codec);ret = select_channel_layout(codec, &c->ch_layout);if (ret < 0)exit(1);c->channels = c->ch_layout.nb_channels;//sample_rate(cr)=44100,表示1秒钟有44100个采样点。格式为s16 + stereo表示双通道,每通道16位(short) packed格式,(S16P 表示双通道通道16位planar格式)
//也就是一个采样点需要4个字节来保存。这里的frame_size 表示采样点个数。c->frame_size=512;//手动设置frame_size//	声音的timebase设置为采样率或其倍数,因为PTS是int64的。如果timebase刚好等于sample_rate,
//	那么更具pts计算公式 audio_pts = n*frame_size*timebase/sample_rate = n*frame_size
//	这样对时间的pts设置极为方便。c->time_base=av_make_q(c->sample_rate,1);//手动设置time_base,/* open it */if (avcodec_open2(c, codec, NULL) < 0) {fprintf(stderr, "Could not open codec\n");exit(1);}f = fopen(filename, "wb");if (!f) {fprintf(stderr, "Could not open %s\n", filename);exit(1);}/* packet for holding encoded output */pkt = av_packet_alloc();if (!pkt) {fprintf(stderr, "could not allocate the packet\n");exit(1);}/* frame containing input raw audio */frame = av_frame_alloc();if (!frame) {fprintf(stderr, "Could not allocate audio frame\n");exit(1);}frame->nb_samples     = c->frame_size;frame->format         = c->sample_fmt;ret = av_channel_layout_copy(&frame->ch_layout, &c->ch_layout);if (ret < 0)exit(1);frame->channels = c->channels;frame->pts = 0;   //初始化pts//音频的packed格式的数据,都存在data[0]中,并且是连续的;stereo planer格式才会将左右两个通道分开在data[0]和data[1]中存放,av_frame_get_buffer会为frame按照参数申请缓存。
//packed :LLRRLLRRLLRRLLRR
//planer :LLLLLLLL....RRRRRRRRR..../* allocate the data buffers */ret = av_frame_get_buffer(frame, 0);if (ret < 0) {fprintf(stderr, "Could not allocate audio data buffers\n");exit(1);}/* encode a single tone sound */t = 0;uint8_t *buffer = malloc(frame->nb_samples*frame->ch_layout.nb_channels*av_get_bytes_per_sample(frame->format));tincr = 2 * M_PI * 440.0 / c->sample_rate;for (i = 0; i < 200; i++) {/* make sure the frame is writable -- makes a copy if the encoder* kept a reference internally */ret = av_frame_make_writable(frame);if (ret < 0)exit(1);samples = (uint16_t*)buffer;for (j = 0; j < c->frame_size; j++) {samples[2*j] = (int)(sin(t) * 10000);for (k = 1; k < c->ch_layout.nb_channels; k++)samples[2*j + k] = samples[2*j];t += tincr;}ret = av_samples_fill_arrays(frame->data, frame->linesize,buffer, frame->channels,frame->nb_samples,frame->format, 0);frame->pts += frame->nb_samples;encode(c, frame, pkt, f);}/* flush the encoder */encode(c, NULL, pkt, f);free(buffer);fclose(f);av_frame_free(&frame);av_packet_free(&pkt);avcodec_free_context(&c);return 0;
}

7-5ADTS格式_哔哩哔哩_bilibili 

AAC ADTS格式分析&AAC编码(adts_header详解)_adts header-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/67906.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue.js组件开发,AI时代的前端新玩法

AI可不只是写写小说、聊聊天&#xff0c;现在它的触角已经伸到了程序员的代码世界里。特别是前端开发&#xff0c;很多人都在尝试用ChatGPT或者类似的AI工具来写代码&#xff0c;甚至直接生成Vue.js组件。有些人感叹&#xff0c;"写代码的时代是不是要结束了&#xff1f;&…

深度学习的原理和应用

一、深度学习的原理 深度学习是机器学习领域的一个重要分支&#xff0c;其原理基于多层神经网络结构和优化算法。以下是深度学习的核心原理&#xff1a; 多层神经网络结构&#xff1a;深度学习模型通常由多层神经元组成&#xff0c;这些神经元通过权重和偏置相互连接。输入数据…

mv指令详解

&#x1f3dd;️专栏&#xff1a;计算机操作系统 &#x1f305;主页&#xff1a;猫咪-9527-CSDN博客 “欲穷千里目&#xff0c;更上一层楼。会当凌绝顶&#xff0c;一览众山小。” 目录 基本语法 主要功能 常用选项详解 1. 移动文件或目录 2. 重命名文件或目录 3. -i&am…

vue3树形组件+封装+应用

文章目录 概要应用场景代码注释综合评价注意事项功能拓展代码说明概要 创建一个基于Vue 3的树形结构组件,用于展示具有层级关系的数据,并提供了节点展开/折叠、点击等交互功能。以下是对其应用场景、代码注释以及综合评价和注意事项的详细说明。 应用场景 这个组件适用于需…

5 分布式ID

这里讲一个比较常用的分布式防重复的ID生成策略&#xff0c;雪花算法 一个用户体量比较大的分布式系统必然伴随着分表分库&#xff0c;分机房部署&#xff0c;单体的部署方式肯定是承载不了这么大的体量。 雪花算法的结构说明 如下图所示: 雪花算法组成 从上图我们可以看…

怎么实现Redis的高可用?

大家好&#xff0c;我是锋哥。今天分享关于【怎么实现Redis的高可用&#xff1f;】面试题。希望对大家有帮助&#xff1b; 怎么实现Redis的高可用&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 为了实现 Redis 的高可用性&#xff0c;我们需要保证在发…

牛客网刷题 ——C语言初阶(6指针)——BC106 上三角矩阵判定

1. 题目描述——BC106 上三角矩阵判定 牛客网OJ题链接 描述 KiKi想知道一个n阶方矩是否为上三角矩阵&#xff0c;请帮他编程判定。上三角矩阵即主对角线以下的元素都为0的矩阵&#xff0c;主对角线为从矩阵的左上角至右下角的连线。 示例 输入&#xff1a; 3 1 2 3 0 4 5 0 0…

H266/VVC 帧内预测中 ISP 技术

帧内子划分 ISP ISP 技术是在 JVET-2002-v3 提案中详细介绍其原理&#xff0c;在 VTM8 中完整展示算法。ISP是线基内预测&#xff08;LIP&#xff09;模式的更新版本&#xff0c;它改善了原始方法在编码增益和复杂度之间的权衡&#xff0c;ISP 算法的核心原理就是利用较近的像…

了解npm:JavaScript包管理工具

在JavaScript的生态系统中&#xff0c;npm&#xff08;Node Package Manager&#xff09;无疑是一个举足轻重的存在。它不仅是Node.js的包管理器&#xff0c;更是前端开发不可或缺的一部分&#xff0c;为开发者提供了丰富的包资源、便捷的包管理以及强大的社区支持。本文将深入…

CNN Test Data

由于数据量过大&#xff0c;打不开了 搞一组小的吧。收工睡觉 https://download.csdn.net/download/spencer_tseng/90256048

自动化测试脚本实践:基于 Bash 的模块化测试框架

前言 在现代软件开发中&#xff0c;测试自动化是确保软件质量和稳定性的核心手段之一。随着开发周期的缩短和功能模块的增多&#xff0c;手动测试逐渐无法满足高效性和准确性的需求。因此&#xff0c;测试人员需要依赖自动化工具来提升测试效率&#xff0c;减少人为干预和错误。…

verilogHDL仿真详解

前言 Verilog HDL中提供了丰富的系统任务和系统函数&#xff0c;用于对仿真环境、文件操作、时间控制等进行操作。&#xff08;后续会进行补充&#xff09; 正文 一、verilogHDL仿真详解 timescale 1ns/1ps //时间单位为1ns&#xff0c;精度为1ps&#xff0c; //编译…

Nginx 配置支持 HTTPS 代理

个人博客地址&#xff1a;Nginx 配置支持 HTTPS 代理 | 一张假钞的真实世界 本文描述的是Nginx HTTPS反向代理的情况&#xff08;即后端服务是HTTP的&#xff09;。 使用openssl配置ssl证书 生成服务器端的私钥&#xff08;key 文件&#xff09;&#xff1a; # openssl gen…

协同过滤算法商品推荐系统|Java|SpringBoot|VUE|

【技术栈】 1⃣️&#xff1a;架构: B/S、MVC 2⃣️&#xff1a;系统环境&#xff1a;Windowsh/Mac 3⃣️&#xff1a;开发环境&#xff1a;IDEA、JDK1.8、Maven、Mysql5.7 4⃣️&#xff1a;技术栈&#xff1a;Java、Mysql、SpringBoot、Mybatis-Plus、VUE、jquery,html 5⃣️…

初学stm32 --- DMA直接存储器

目录 DMA介绍 STM32F1 DMA框图 DMA处理过程 DMA通道 DMA优先级 DMA相关寄存器介绍 F1 DMA通道x配置寄存器&#xff08;DMA_CCRx&#xff09; DMA中断状态寄存器&#xff08;DMA_ISR&#xff09; DMA中断标志清除寄存器&#xff08;DMA_IFCR&#xff09; DMA通道x传输…

数据通过canal 同步es,存在延迟问题,解决方案

当使用 Canal 同步数据到 Elasticsearch&#xff08;ES&#xff09;时&#xff0c;出现延迟问题通常源于多个因素&#xff0c;如 Canal 配置、网络延迟、ES 的负载和性能瓶颈等。以下是一些解决方案&#xff0c;帮助减少和解决延迟问题&#xff1a; 1. 优化 Canal 配置 Canal…

javafx 将项目打包为 Windows 的可执行文件exe

要将 JavaFX 项目打包为 .exe 文件&#xff0c;你可以使用一些工具将你的应用程序封装为 Windows 可执行文件。以下是两种常用的方法&#xff1a; 方法 1&#xff1a;使用 jpackage&#xff08;适用于 JDK 14 及更高版本&#xff09; jpackage 是 JDK 内置的工具&#xff0c;…

SQL进阶实战技巧:即时订单比例问题

目录 0 需求描述 1 数据准备 2 问题分析 3 小结 往期精彩 0 需求描述 订单配送中,如果期望配送日期和下单日期相同,称为即时订单,如果期望配送日期和下单日期不同,称为计划订单。 请从配送信息表(delivery_info)中求出每个用户的首单(用户的第一个订单)中即时订单…

Routine Load 导入问题处理指南

Routine Load 导入问题处理指南 在使用 Apache Doris 的 Routine Load 时&#xff0c;你是否曾经被各种奇奇怪怪的问题卡住&#xff1f;今天就来分享一些最常见的 Routine Load 问题&#xff0c;并提供相应的解决方案&#xff0c;让你快速应对&#xff0c;高效解决&#xff01;…

【面试题】技术场景 6、Java 生产环境 bug 排查

生产环境 bug 排查思路 分析日志&#xff1a;首先通过分析日志查看是否存在错误信息&#xff0c;利用之前讲过的 elk 及查看日志的命令缩小查找错误范围&#xff0c;方便定位问题。远程 debug 适用环境&#xff1a;一般公司正式生产环境不允许远程 debug&#xff0c;多在测试环…