热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何在AAC原始流中添加ADTS头并进行解码播放

本文介绍了如何在AAC原始流中添加ADTS头以便通过FFmpeg进行软解码或系统硬解码。我们将详细解释ADTS头的结构,并提供一个示例代码来演示如何动态生成ADTS头。

AAC原始流可以通过FFmpeg进行软解码或系统硬解码。为了简化处理,可以在流的前面添加ADTS头。ADTS头由7个字节组成,下面是生成ADTS头的示例代码,每次传递数据都以一个样本为单位:

uint8_t adts_header[7] = {0xff, 0xf9, 0x00, 0x00, 0x00, 0x1f, 0xfc};

// 设置AAC级别
switch (aac_level) {
    case AUDIO_AACM:
        adts_header[2] |= (0x00 <<6) & 0xc0;
        break;
    case AUDIO_AACL:
        adts_header[2] |= (0x01 <<6) & 0xc0;
        break;
    case AUDIO_AACS:
        adts_header[2] |= (0x02 <<6) & 0xc0;
        break;
    default: // 默认使用AACL
        adts_header[2] |= (0x01 <<6) & 0xc0;
        break;
}

// 设置采样率
switch (aac_sample_rate) {
    case SAMPLING_RATE_96000:
        adts_header[2] |= (0x00 <<2) & 0x3c;
        break;
    case SAMPLING_RATE_88200:
        adts_header[2] |= (0x01 <<2) & 0x3c;
        break;
    case SAMPLING_RATE_64000:
        adts_header[2] |= (0x02 <<2) & 0x3c;
        break;
    case SAMPLING_RATE_48000:
        adts_header[2] |= (0x03 <<2) & 0x3c;
        break;
    case SAMPLING_RATE_44100:
        adts_header[2] |= (0x04 <<2) & 0x3c;
        break;
    case SAMPLING_RATE_32000:
        adts_header[2] |= (0x05 <<2) & 0x3c;
        break;
    case SAMPLING_RATE_24000:
        adts_header[2] |= (0x06 <<2) & 0x3c;
        break;
    case SAMPLING_RATE_22050:
        adts_header[2] |= (0x07 <<2) & 0x3c;
        break;
    case SAMPLING_RATE_16000:
        adts_header[2] |= (0x08 <<2) & 0x3c;
        break;
    case SAMPLING_RATE_12000:
        adts_header[2] |= (0x09 <<2) & 0x3c;
        break;
    case SAMPLING_RATE_11025:
        adts_header[2] |= (0x0a <<2) & 0x3c;
        break;
    case SAMPLING_RATE_8000:
        adts_header[2] |= (0x0b <<2) & 0x3c;
        break;
    default: // 默认使用44100Hz
        adts_header[2] |= (0x04 <<2) & 0x3c;
        break;
}

// 设置声道数
switch (aac_channel_count) {
    case 1:
        adts_header[2] |= (0x01 >> 2) & 0x01;
        adts_header[3] |= (0x01 <<6) & 0xc0;
        break;
    case 2:
        adts_header[2] |= (0x02 >> 2) & 0x01;
        adts_header[3] |= (0x02 <<6) & 0xc0;
        break;
    case 3:
        adts_header[2] |= (0x03 >> 2) & 0x01;
        adts_header[3] |= (0x03 <<6) & 0xc0;
        break;
    case 4:
        adts_header[2] |= (0x04 >> 2) & 0x01;
        adts_header[3] |= (0x04 <<6) & 0xc0;
        break;
    case 5:
        adts_header[2] |= (0x05 >> 2) & 0x01;
        adts_header[3] |= (0x05 <<6) & 0xc0;
        break;
    case 6:
        adts_header[2] |= (0x06 >> 2) & 0x01;
        adts_header[3] |= (0x06 <<6) & 0xc0;
        break;
    case 8:
        adts_header[2] |= (0x07 >> 2) & 0x01;
        adts_header[3] |= (0x07 <<6) & 0xc0;
        break;
    default: // 默认使用2个声道
        adts_header[2] |= (0x02 >> 2) & 0x01;
        adts_header[3] |= (0x02 <<6) & 0xc0;
        break;
}

// 设置帧长度
adts_header[3] |= (aac_frame_length >> 11) & 0x03;
adts_header[4] = (aac_frame_length >> 3) & 0xff;
adts_header[5] |= ((aac_frame_length & 0x07) <<5);

通过上述代码,您可以根据实际的AAC流参数动态生成ADTS头,从而实现对AAC原始流的解码和播放。


推荐阅读
  • 本文详细介绍了 com.apollographql.apollo.api.internal.Optional 类中的 orNull() 方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 在iOS开发中,多线程技术的应用非常广泛,能够高效地执行多个调度任务。本文将重点介绍GCD(Grand Central Dispatch)在多线程开发中的应用,包括其函数和队列的实现细节。 ... [详细]
  • Java 中的控制流与作用域
    本文详细介绍了 Java 中的控制流语句,包括块作用域、if 语句、for 循环、while 循环、do-while 循环、switch 语句以及 break 和 continue 语句的使用方法。通过具体的代码示例,帮助读者更好地理解和应用这些控制流结构。 ... [详细]
  • 在运行于MS SQL Server 2005的.NET 2.0 Web应用中,我偶尔会遇到令人头疼的SQL死锁问题。过去,我们主要通过调整查询来解决这些问题,但这既耗时又不可靠。我希望能找到一种确定性的查询模式,确保从设计上彻底避免SQL死锁。 ... [详细]
  • 用C语言实现的科学计算器,支持2种常量,10种基本函数,Ans寄存器。相对来说拓展性应该是不错的,思路是首先化简复杂名称的函 ... [详细]
  • WPF项目学习.一
    WPF项目搭建版权声明:本文为博主初学经验,未经博主允许不得转载。一、前言记录在学习与制作WPF过程中遇到的解决方案。使用MVVM的优点是数据和视图分离,双向绑定,低耦合,可重用行 ... [详细]
  • 本文详细介绍了Linux系统中用于管理IPC(Inter-Process Communication)资源的两个重要命令:ipcs和ipcrm。通过这些命令,用户可以查看和删除系统中的消息队列、共享内存和信号量。 ... [详细]
  • 一、Tomcat安装后本身提供了一个server,端口配置默认是8080,对应目录为:..\Tomcat8.0\webapps二、Tomcat8.0配置多个端口,其实也就是给T ... [详细]
  • 我有一个从C项目编译的.o文件,该文件引用了名为init_static_pool ... [详细]
  • 为什么多数程序员难以成为架构师?
    探讨80%的程序员为何难以晋升为架构师,涉及技术深度、经验积累和综合能力等方面。本文将详细解析Tomcat的配置和服务组件,帮助读者理解其内部机制。 ... [详细]
  • com.sun.javadoc.PackageDoc.exceptions()方法的使用及代码示例 ... [详细]
  • 在分析Android的Audio系统时,我们对mpAudioPolicy->get_input进行了详细探讨,发现其背后涉及的机制相当复杂。本文将详细介绍这一过程及其背后的实现细节。 ... [详细]
  • 技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统
    技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统 ... [详细]
  • 如何将TS文件转换为M3U8直播流:HLS与M3U8格式详解
    在视频传输领域,MP4虽然常见,但在直播场景中直接使用MP4格式存在诸多问题。例如,MP4文件的头部信息(如ftyp、moov)较大,导致初始加载时间较长,影响用户体验。相比之下,HLS(HTTP Live Streaming)协议及其M3U8格式更具优势。HLS通过将视频切分成多个小片段,并生成一个M3U8播放列表文件,实现低延迟和高稳定性。本文详细介绍了如何将TS文件转换为M3U8直播流,包括技术原理和具体操作步骤,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 本文详细介绍了在 Android 7.1 系统中调整屏幕分辨率和默认音量设置的方法。针对系统默认音量过大的问题,提供了具体的步骤来降低系统、铃声、媒体和闹钟的默认音量,以提升用户体验。此外,还涵盖了如何通过系统设置或使用第三方工具来优化屏幕分辨率,确保设备显示效果更加清晰和流畅。 ... [详细]
author-avatar
星宿
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有