热门标签 | 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原始流的解码和播放。


推荐阅读
  • 本文详细介绍了如何构建一个高效的UI管理系统,集中处理UI页面的打开、关闭、层级管理和页面跳转等问题。通过UIManager统一管理外部切换逻辑,实现功能逻辑分散化和代码复用,支持多人协作开发。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 本文介绍如何使用Objective-C结合dispatch库进行并发编程,以提高素数计数任务的效率。通过对比纯C代码与引入并发机制后的代码,展示dispatch库的强大功能。 ... [详细]
  • 主要用了2个类来实现的,话不多说,直接看运行结果,然后在奉上源代码1.Index.javaimportjava.awt.Color;im ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • moment 国际化设置中文语言 (全局) 及使用示例 ... [详细]
  • Scala 实现 UTF-8 编码属性文件读取与克隆
    本文介绍如何使用 Scala 以 UTF-8 编码方式读取属性文件,并实现属性文件的克隆功能。通过这种方式,可以确保配置文件在多线程环境下的一致性和高效性。 ... [详细]
  • 使用GDI的一些AIP函数我们可以轻易的绘制出简 ... [详细]
  • 本文详细介绍了 JavaScript 中的条件判断(if-else 和 switch)以及循环控制(for、while 和 do-while)。我们将探讨这些结构的基本语法、使用场景及注意事项,并补充一些实用技巧。 ... [详细]
  • 解决网站乱码问题的综合指南
    本文总结了导致网站乱码的常见原因,并提供了详细的解决方案,包括文件编码、HTML元标签设置、服务器响应头配置、数据库字符集调整以及PHP与MySQL交互时的编码处理。 ... [详细]
  • 本文将深入探讨如何在不依赖第三方库的情况下,使用 React 处理表单输入和验证。我们将介绍一种高效且灵活的方法,涵盖表单提交、输入验证及错误处理等关键功能。 ... [详细]
  • 本文介绍如何在SQL Server中对Name列进行排序,使特定值(如Default Deliverable Submission Notification)显示在结果集的顶部。 ... [详细]
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社区 版权所有