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

H264和AAC打包PS包代码

        段老师的干货时间又到咯,下面代码实现的是将 AAC 和 H264 数据打包成 PS 包的流程,其中包括了 PES 头、PSI 表头、MPEG-TS 头、AAC/H264 数据打包等多个步骤。此外,还包含 CRC32 校验等校验码的计算。需要注意的是,此代码示例仅供参考,具体实现需要根据实际需求进行调整和修改。

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

// 同步字节
const unsigned char SYNC_BYTE = 0x47;

int main() {
    ofstream out_file("output.ps", ios::out | ios::binary);
    vector<unsigned short> pid_list;

    // 打包 PAT(Program Association Table)
    PSITableHeader pat_header = {0};
    pat_header.m_table_id = 0x00;
    pat_header.m_section_syntax_indicator = true;
    pat_header.m_section_length = 13;
    out_file.write((const char*)&SYNC_BYTE, 1);
    out_file.write((const char*)&pat_header, sizeof(pat_header));

    unsigned short transport_stream_id = 1;
    unsigned short program_number = 1;
    unsigned short program_map_PID = 100;

    unsigned char section_number = 0;
    unsigned char last_section_number = 0;

    out_file.write((const char*)&transport_stream_id, 2);
    out_file.write((const char*)&section_number, 1);
    out_file.write((const char*)&last_section_number, 1);
    out_file.write((const char*)&program_number, 2);
    out_file.write("", 3);  // 预留为 "111"
    out_file.write((const char*)&program_map_PID, 2);
    out_file.write("", 4);  // 预留为 CRC32 校验码

    PATSection pat_section = {0};
    pat_section.m_program_number = program_number;
    pat_section.m_PID = program_map_PID;

    // 打包 PMT(Program Map Table)
    PSITableHeader pmt_header = {0};
    pmt_header.m_table_id = 0x02;
    pmt_header.m_section_syntax_indicator = true;
    pmt_header.m_section_length = 13;
    out_file.write((const char*)&SYNC_BYTE, 1);
    out_file.write((const char*)&pmt_header, sizeof(pmt_header));

    unsigned char pcr_pid = 100;
    unsigned char program_info_length = 0;

    section_number = 0;
    last_section_number = 0;

    out_file.write((const char*)&program_number, 2);
    out_file.write("", 3);  // 预留为 "111"
    out_file.write((const char*)&pcr_pid, 2);
    out_file.write("", 2);  // 预留为 "1111"
    out_file.write(&program_info_length, 1);

    PMTSection pmt_section = {0};
    pmt_section.m_program_number = program_number;
    pmt_section.m_program_map_PID = program_map_PID;
    pmt_section.m_stream_types.push_back(0x1B);  // 音频类型
    pmt_section.m_stream_types.push_back(0x1B);  // 视频类型
    pmt_section.m_elementary_PIDs.push_back(0xc0);  // 音频 PID
    pmt_section.m_elementary_PIDs.push_back(0xe0);  // 视频 PID

    // 按照顺序将 PES 包和 MPEG-TS 头打包成 PS 包
    const int AAC_PACKET_SIZE = 188 - sizeof(TSHeader);  // AAC 数据包大小
    const int H264_PACKET_SIZE = 188 - sizeof(TSHeader);  // H264 数据包大小
    unsigned char aac_packet[AAC_PACKET_SIZE];
    unsigned char h264_packet[H264_PACKET_SIZE];
    int aac_packet_len = 0, h264_packet_len = 0;

    ifstream aac_file("audio.aac", ios::in | ios::binary);
    ifstream h264_file("video.h264", ios::in | ios::binary);

    while (true) {
        // 处理 AAC 数据
        aac_file.read((char*)aac_packet, AAC_PACKET_SIZE);
        aac_packet_len = aac_file.gcount();

        if (aac_packet_len == 0) {
            break;
        }

        PackAACData(aac_packet, aac_packet_len, out_file);

        // 处理 H264 数据
        h264_file.read((char*)h264_packet, H264_PACKET_SIZE);
        h264_packet_len = h264_file.gcount();

        if (h264_packet_len == 0) {
            break;
        }

        PackH264Data(h264_packet, h264_packet_len, out_file, pid_list);
    }

    aac_file.close();
    h264_file.close();

    // 打包 PAT 表的 CRC32 校验码
    out_file.seekp(sizeof(SYNC_BYTE) + sizeof(pat_header) + pat_header.m_section_length - 4, ios::beg);
    unsigned int crc32 = 0xffffffff;

    for (int i = 0; i < sizeof(pat_section); i++) {
        crc32 ^= ((unsigned char*)(&pat_section))[i] << 24;

        for (int j = 0; j < 8; j++) {
            if (crc32 & 0x80000000) {
                crc32 = (crc32 << 1) ^ 0x04c11db7;
            } else {
                crc32 <<= 1;
            }
        }
    }

    crc32 = ~crc32;
    out_file.write((const char*)&crc32, 4);

    // 打包 PMT 表的 CRC32 校验码
    out_file.seekp(sizeof(SYNC_BYTE) + sizeof(pmt_header) + pmt_header.m_section_length - 4, ios::beg);
    crc32 = 0xffffffff;

    for (int i = 0; i < sizeof(pmt_section); i++) {
        crc32 ^= ((unsigned char*)(&pmt_section))[i] << 24;

        for (int j = 0; j < 8; j++) {
            if (crc32 & 0x80000000) {
                crc32 = (crc32 << 1) ^ 0x04c11db7;
            } else {
                crc32 <<= 1;
            }
        }
    }

    crc32 = ~crc32;
    out_file.write((const char*)&crc32, 4);

    // 打包 MPEG-TS 头和数据成 TS 包
    const int TS_PACKET_SIZE = 188;  // TS 数据包大小
    unsigned char ts_packet[TS_PACKET_SIZE];
    int ts_packet_len = 0;

    ifstream in_file("output.ps", ios::in | ios::binary);
    in_file.read((char*)ts_packet, 4);  // 跳过前面的 SYNC_BYTE 和 PAT 表头
    in_file.read((char*)ts_packet, TS_PACKET_SIZE);

    while (in_file.gcount() == TS_PACKET_SIZE) {
        ts_packet_len = TS_PACKET_SIZE;

        for (int i = 0; i < pid_list.size(); i++) {
            unsigned short pid = pid_list[i];

            if (ts_packet[1] >> 4 == 0x01 && (ts_packet[1] & 0x0f) == pid) {
                TSHeader* ts_header = (TSHeader*)ts_packet;
                ts_header->m_pid = program_map_PID;

                if (ts_header->m_adaptation_field_control == 0x02 || ts_header->m_adaptation_field_control == 0x03) {
                    int padding = TS_PACKET_SIZE - ts_packet_len - 1;
                    unsigned char* adaptation_field = ts_packet + ts_packet_len;
                    *adaptation_field++ = padding - 1;
                    memset(adaptation_field, 0xff, padding);
                    ts_packet_len += padding + 1;
                }

                out_file.write((const char*)ts_packet, ts_packet_len);
                break;
            }
        }

        in_file.read((char*)ts_packet, TS_PACKET_SIZE);
    }

    in_file.close();
    out_file.close();

    return 0;
}

相关文章:

H264和AAC打包PS包代码

段老师的干货时间又到咯&#xff0c;下面代码实现的是将 AAC 和 H264 数据打包成 PS 包的流程&#xff0c;其中包括了 PES 头、PSI 表头、MPEG-TS 头、AAC/H264 数据打包等多个步骤。此外&#xff0c;还包含 CRC32 校验等校验码的计算。需要注意的是&#xff0c;此代码示例仅供…...

Redis数据类型-ZSet

一. 概述 SortedSet又叫zset&#xff0c;它是Redis提供的特殊数据类型&#xff0c;是一种特殊的set类型&#xff0c;继承了set不可重复的特点&#xff0c;并在set基础上为每个值添加一个分数&#xff0c;用来实现值的有序排列。 二. 常用指令 明白它的特点后&#xff0c;接下来…...

国外各大学和学院对于ChatGPT使用立场总结

ChatGPT和生成式AI的快速普及对教育这个专业领域带来了威胁——全国各地的大学和学院都召开了紧急会议&#xff0c;讨论如何应对学生利用AI作弊的风险。 一部分学校和教授担心这项技术会成为学生在论文或其他写作作业和考试中寻求捷径的工具。而这种生成内容的方式往往能够绕开…...

我在VScode学Java(Java二维数组)

我的个人博客主页&#xff1a;如果\真能转义1️⃣说1️⃣的博客主页 关于Java基本语法学习---->可以参考我的这篇博客&#xff1a;(我在Vscode学Java) 接上回Java一维数组的介绍&#xff08;我在VScode学Java(Java一维数组&#xff09; &#xff09; 二维数组是Java中的一…...

HTML-iconfont动态图标SVG效果--阿里巴巴图标矢量库

给北大打工&#xff0c;实现官网首页动态图标效果_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Ys4y1c7oh/?spm_id_from333.1007.top_right_bar_window_default_collection.content.click&vd_source924f5dad6f2dcb0a3e5dca4604287ecd&#xff08;本篇笔记操作方法…...

C++17完整导引-模板特性之编译器的if语句

编译期if语句 if constexpr 编译期if语句使用编译期if语句编译期if的注意事项编译期if影响返回值类型即使在 *then* 部分返回也要考虑 *else* 部分编译期短路求值 其他编译期if的示例完美返回泛型值使用编译期if进行类型分发 带初始化的编译期if语句在模板之外使用编译期if参考…...

告别Excel,免费大数据分析与可视化工具,让你的论文图表“高大上”

数据分析工具很多&#xff0c;可以分为表格、数据库、BI工具、编程等四大工具。每个大类又有很多的工具&#xff0c;例如表格包括Excel、WPS、Google Sheets、Airtable等。编程工具包括Python和R。 搞科研几年了&#xff0c;笔者一直都是在使用Excel做数据分析和可视化&#xf…...

C++ 中的继承和多态

C 中的继承和多态 一、继承二、函数重载、隐藏、覆盖、重写1.函数重载&#xff08;Function Overload&#xff09;2.函数隐藏&#xff08;Function Hiding&#xff09;3.函数重写与函数覆盖&#xff08;Function Override&#xff09; 三、多态四、纯虚函数和抽象类五、多重继承…...

NestedFormer:用于脑肿瘤分割的嵌套模态感知Transformer

文章目录 NestedFormer: Nested Modality-AwareTransformer for Brain Tumor Segmentation摘要方法Global Poolformer EncoderNested Modality-Aware Feature AggregationModality-Sensitive Gating 实验结果 NestedFormer: Nested Modality-AwareTransformer for Brain Tumor …...

【SQLServer】sqlserver数据库导入oracle

将sqlserver数据库导入到oracle 实用工具&#xff1a; SQL Server Management Studio 15.0.18424.0 SQL Server 管理对象 (SMO) 16.100.47021.07eef34a564af48c5b0cf0d617a65fd77f06c3eb1 Microsoft Analysis Services 客户端工具 15.0.19750.0 Microsoft 数据访问组件 (MDAC) …...

【5.20】四、性能测试—性能测试工具

目录 4.5 性能测试工具 4.5.1 LoadRunner 4.5.2 JMeter 4.5 性能测试工具 性能测试是软件测试中一个很重要的分支&#xff0c;人们为了提高性能测试的效率&#xff0c;开发出了很多性能测试工具。一款好的测试工具可以极大地提高测试效率&#xff0c;为发现软件缺陷提供重要…...

朗诵素材-《少年正是读书时》(两角色主持朗诵)

少年正是读书时 1、少年正是读书时 男&#xff1a;我们生活在/古老的土地上 男&#xff1a;我们拥有/共同的梦想 女&#xff1a;那朗朗的书声/那浓浓的墨香 女&#xff1a;都在告诉我们 合&#xff1a;少年正是&#xff0f;读书时 2、为何要读书 男&#xff1a;养心&am…...

凭借这个笔记,拿下8家大厂offer....

如何拿到多家大厂的offer&#xff0c;没有过硬的实力&#xff0c;就需要不断的学习。 我是如何拿到&#xff0c;阿里&#xff0c;腾讯&#xff0c;百度等八家大厂的offer的&#xff0c;今天我就给大家来分享我的秘密武器&#xff0c;阿里大神整理的包括&#xff0c;测试基础&am…...

介绍一下全链路压测平台的相关内容

随着互联网技术的不断发展&#xff0c;越来越多的企业开始依赖互联网来实现业务的发展和增长。而对于这些企业而言&#xff0c;如何保证他们的业务在高并发、高负载的情况下依然能够正常运行&#xff0c;是非常重要的一个问题。为了解决这个问题&#xff0c;企业可以使用全链路…...

对于无效的数据,该如何处理

一、无效数据的来源&#xff1a; 在进行数据管理时&#xff0c;无效数据是非常常见的问题。 无效数据可能来自于数据采集、输入错误、数据处理或存储错误等方面。 这些无效数据会对结果造成严重的影响&#xff0c;因此需要及时发现和处理。 二、处理无效数据&#xff1a; …...

港联证券:机器人行业有望迎来整体性机会 六氟磷酸锂翻倍上涨

表示&#xff0c;当前AI调整的时间空间已接近13年水位&#xff0c;且调整的促发因素有望缓和&#xff0c;后续可积极一些。一方面&#xff0c;13年三次调整时间在40日以内、幅度在15%以内。当前AI调整已持续1个月、幅度在10%以上&#xff0c;时空已接近历史。另一方面&#xff…...

css 伪类选择器 结构伪类

css 伪类选择器 结构伪类 常用的&#xff1a; :first-child 所有兄弟元素中的第一个 :last-child 所有兄弟元素中的最后一个 :nth-child(n) 所有兄弟元素中的第n个 :first-of-type 所有同类型兄弟元素中的第一个 :last-of-type 所有同类型兄弟元素中的最后一个 :nth-of-type(…...

常用的表格检测识别方法-表格区域检测方法(上)

常用的表格检测识别方法 表格检测识别一般分为三个子任务&#xff1a;表格区域检测、表格结构识别和表格内容识别。本章将围绕这三个表格识别子任务&#xff0c;从传统方法、深度学习方法等方面&#xff0c;综述该领域国内国外的发展历史和最新进展&#xff0c;并提供几个先进…...

【运维知识进阶篇】集群架构-Rewrite重定向

Rewrite主要实现url地址重写&#xff0c;以及重定向&#xff0c;就是把传入web的请求重定向到其他url的过程。 分以下几种场景使用 1、地址跳转&#xff0c;用户访问一个URL&#xff0c;将其定向到另一个URL 2、协议跳转&#xff0c;用户通过http协议请求网站时&#xff0c;…...

JavaScript如何使用while循环

JavaScript 中的 while 循环是一种常用的循环结构&#xff0c;用于在满足一定条件时重复执行一段代码块。while 循环会先检查条件是否为真&#xff0c;如果为真&#xff0c;则执行循环体中的代码&#xff0c;然后再次检查条件。当条件变为假时&#xff0c;循环会结束。 while(…...

使用小龙虾来操作猿编程的遥控车沙

一、什么是 Q 饱和运算&#xff1f; 1. 核心痛点&#xff1a;普通运算的 “数值回绕” 普通算术运算&#xff08;如 ADD/SUB&#xff09;溢出时&#xff0c;数值会按补码规则 “回绕”&#xff0c;导致结果完全错误&#xff1a; 示例&#xff1a;int8_t 类型最大值 127 1 → 结…...

2025届学术党必备的十大AI论文平台实测分析

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 要使得文本的AIGC检出率能够有效降低&#xff0c;就得从语言风格、句法结构以及逻辑组织这三…...

Awesome AI for Science数据资源宝库:11亿DFT计算结果等顶级数据集指南 [特殊字符]

Awesome AI for Science数据资源宝库&#xff1a;11亿DFT计算结果等顶级数据集指南 &#x1f680; 【免费下载链接】awesome-ai4s AI for Science 论文解读合集&#xff08;持续更新ing&#xff09;&#xff0c;论文/数据集/教程下载&#xff1a;hyper.ai 项目地址: https://…...

Semantic Kernel 深度解析:微软的 Agent 开发框架

Semantic Kernel 深度解析:微软的 Agent 开发框架 摘要/引言 开门见山(Hook) 你有没有想过,像《钢铁侠》里贾维斯那样的通用智能助手,会不会在202X年就不再是科幻电影的专属?当我们打开手机的Siri、电脑的Cortana或者ChatGPT网页版,它们确实能回答问题、写邮件、甚至生…...

Ryujinx开源Switch模拟器:跨平台游戏体验的技术实现与优化指南

Ryujinx开源Switch模拟器&#xff1a;跨平台游戏体验的技术实现与优化指南 【免费下载链接】Ryujinx 用 C# 编写的实验性 Nintendo Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/ry/Ryujinx 在游戏硬件快速迭代的今天&#xff0c;玩家们常常面临一个困…...

探索黑苹果实战:零基础打造你的专属 macOS 系统

探索黑苹果实战&#xff1a;零基础打造你的专属 macOS 系统 【免费下载链接】Hackintosh 国光的黑苹果安装教程&#xff1a;手把手教你配置 OpenCore 项目地址: https://gitcode.com/gh_mirrors/hac/Hackintosh 核心价值&#xff1a;为什么选择开源黑苹果项目 你是否曾…...

d2s-editor:实现游戏存档可视化管理的开源工具解决方案

d2s-editor&#xff1a;实现游戏存档可视化管理的开源工具解决方案 【免费下载链接】d2s-editor 项目地址: https://gitcode.com/gh_mirrors/d2/d2s-editor d2s-editor是一款基于Vue.js开发的开源工具&#xff0c;专为游戏存档文件提供可视化编辑功能。作为一款轻量级W…...

Windows本地开发环境连接云端RWKV7-1.5B-G1A模型服务指南

Windows本地开发环境连接云端RWKV7-1.5B-G1A模型服务指南 1. 前言&#xff1a;为什么需要本地连接云端模型 对于Windows开发者来说&#xff0c;直接在本地运行大模型往往面临硬件资源不足的问题。RWKV7-1.5B-G1A作为一款性能优异的中等规模语言模型&#xff0c;在云端GPU服务…...

如何让你的Windows电脑重获新生?系统优化与个性化全攻略

如何让你的Windows电脑重获新生&#xff1f;系统优化与个性化全攻略 【免费下载链接】Winhance-zh_CN A Chinese version of Winhance. C# application designed to optimize and customize your Windows experience. 项目地址: https://gitcode.com/gh_mirrors/wi/Winhance-…...

零代码实现企业级打印模板设计:vue-plugin-hiprint全攻略

零代码实现企业级打印模板设计&#xff1a;vue-plugin-hiprint全攻略 【免费下载链接】vue-plugin-hiprint hiprint for Vue2/Vue3 ⚡打印、打印设计、可视化设计器、报表设计、元素编辑、可视化打印编辑 项目地址: https://gitcode.com/gh_mirrors/vu/vue-plugin-hiprint …...