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


推荐阅读
  • 本文介绍了一个项目中如何在Windows平台上实现多声道音频数据的采集,特别是针对DANTE音频接口的8路立体声音频通道。文章详细描述了使用Windows底层音频API进行音频采集的方法,并提供了一个具体的实现示例。 ... [详细]
  • 本文详细介绍了如何在 Java 中使用 com.badlogic.gdx.utils.JsonValue.iterator() 方法来遍历和解析 JSON 数据,并提供了多个实际应用中的代码示例。 ... [详细]
  • 本文详细介绍了如何构建一个高效的UI管理系统,集中处理UI页面的打开、关闭、层级管理和页面跳转等问题。通过UIManager统一管理外部切换逻辑,实现功能逻辑分散化和代码复用,支持多人协作开发。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • Scala 实现 UTF-8 编码属性文件读取与克隆
    本文介绍如何使用 Scala 以 UTF-8 编码方式读取属性文件,并实现属性文件的克隆功能。通过这种方式,可以确保配置文件在多线程环境下的一致性和高效性。 ... [详细]
  • 解决网站乱码问题的综合指南
    本文总结了导致网站乱码的常见原因,并提供了详细的解决方案,包括文件编码、HTML元标签设置、服务器响应头配置、数据库字符集调整以及PHP与MySQL交互时的编码处理。 ... [详细]
  • 本文将深入探讨如何在不依赖第三方库的情况下,使用 React 处理表单输入和验证。我们将介绍一种高效且灵活的方法,涵盖表单提交、输入验证及错误处理等关键功能。 ... [详细]
  • 本文介绍如何在SQL Server中对Name列进行排序,使特定值(如Default Deliverable Submission Notification)显示在结果集的顶部。 ... [详细]
  • 本文介绍了一种根据用户选择动态切换屏幕界面的方法,通过定义不同的选择块(Selection Block),实现灵活的用户交互体验。 ... [详细]
  • C语言基础入门:7个经典小程序助你快速掌握编程技巧
    本文精选了7个经典的C语言小程序,旨在帮助初学者快速掌握编程基础。通过这些程序的实践,你将更深入地理解C语言的核心概念和语法结构。 ... [详细]
  • 本文介绍了一种在 MySQL 客户端执行 NOW() 函数时出现时间偏差的问题,并详细描述了如何通过配置文件调整时区设置来解决该问题。演示场景中,假设当前北京时间为2023年2月17日19:31:37,而查询结果显示的时间比实际时间晚8小时。 ... [详细]
  • 使用lambda表达式排序Collections.sort(temp,(Stringa,Stringb)-{returnb.compareTo(a);});Collections ... [详细]
  • 本问题探讨了在特定条件下排列儿童队伍的方法数量。题目要求计算满足条件的队伍排列总数,并使用递推算法和大数处理技术来解决这一问题。 ... [详细]
  • 采用IKE方式建立IPsec安全隧道
    一、【组网和实验环境】按如上的接口ip先作配置,再作ipsec的相关配置,配置文本见文章最后本文实验采用的交换机是H3C模拟器,下载地址如 ... [详细]
  • FFPlay 字幕与LRC歌词播放指南
    本文详细介绍了不同媒体容器支持的字幕格式,以及如何使用FFPlay和FFMPEG进行字幕和LRC歌词的播放与转换。涵盖的内容包括字幕显示方法、字体配置、字幕流选择等。 ... [详细]
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社区 版权所有