AAC打包PS

news/2024/10/30 13:36:48/

        本程序实现通过UDP接受原始AAC数据,并且打包后通过UDP发送示例,里面主要介绍了AAC打包PS的关键流程,希望给到小伙伴们启示。

#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>

// 计算校验和
unsigned short checksum(const unsigned char *buf, int len) {
    unsigned int sum = 0;

    while (len > 1) {
        sum += (*buf << 8) | *(buf + 1);
        len -= 2;
        buf += 2;
    }

    if (len == 1) {
        sum += *buf << 8;
    }

    while (sum >> 16) {
        sum = (sum & 0xFFFF) + (sum >> 16);
    }

    return ~sum;
}

// 将AAC数据打包成PS流
int PackAAC(const unsigned char *aac_data, int aac_len, unsigned char *ps_buffer) {
    // 用于存放PES数据的buffer
    unsigned char pes_buffer[65536];

    // 初始化PES头部信息
    PESHeader pes_header = {0};
    pes_header.packet_start_code_prefix = 0x000001;
    pes_header.stream_id = 192;
    pes_header.PES_packet_length = htons(6 + aac_len);
    pes_header.PTS_DTS_flags = 0x80;
    pes_header.PTS = CalculatePTS();

    // 将PES头部信息写入到buffer中
    memcpy(pes_buffer, &pes_header, sizeof(pes_header));

    // 添加AAC数据到PES负载中
    memcpy(pes_buffer + sizeof(pes_header), "\x0f\xff\xf1", 3);
    memcpy(pes_buffer + sizeof(pes_header) + 3, aac_data, aac_len);

    // 计算PES校验和
    unsigned short pes_cksum = checksum(pes_buffer, sizeof(pes_header) + 3 + aac_len);

    // 初始化PS头部信息
    PSHeader ps_header = {0};
    ps_header.sync_byte = 0x47;
    ps_header.id = 0x40;
    ps_header.PES_start_flag = 1;
    ps_header.pid = htons(256); // TODO: 根据需求修改
    ps_header.transport_scrambling_control = 0;
    ps_header.adaptation_field_control = 1;
    ps_header.continuity_counter = continuity_counter++;

    // 将PS头部信息写入到buffer中
    memcpy(ps_buffer, &ps_header, sizeof(ps_header));

    // 添加PES数据到PS负载中
    memcpy(ps_buffer + sizeof(ps_header), &pes_header, sizeof(pes_header));
    memcpy(ps_buffer + sizeof(ps_header) + sizeof(pes_header), "\x0f\xff\xf1", 3);
    memcpy(ps_buffer + sizeof(ps_header) + sizeof(pes_header) + 3, aac_data, aac_len);
    *(ps_buffer + sizeof(ps_header) + sizeof(pes_header) + 3 + aac_len) = pes_cksum >> 8;
    *(ps_buffer + sizeof(ps_header) + sizeof(pes_header) + 3 + aac_len + 1) = pes_cksum & 0xff;

    return sizeof(ps_header) + sizeof(pes_header) + 3 + aac_len + 2;
}

int main() {
    // 初始化socket连接和PS流发送参数等信息
    int socket_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    struct sockaddr_in remote_addr = {0};
    remote_addr.sin_family = AF_INET;
    remote_addr.sin_port = htons(9000); // TODO: 根据需求修改
    remote_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // TODO: 根据需求修改

    unsigned char ps_buffer[65536];

    // 每次接收到AAC数据时,使用PackAAC函数将其打包成PS格式,并通过UDP发送到远程主机
    while (1) {
        unsigned char aac_data[2048]; // 假设每次接收到的AAC数据长度不超过2048字节
        int aac_len = recvfrom(socket_fd, aac_data, sizeof(aac_data), 0, NULL, NULL);
        int ps_len = PackAAC(aac_data, aac_len, ps_buffer);
        sendto(socket_fd, ps_buffer, ps_len, 0, (struct sockaddr *)&remote_addr, sizeof(remote_addr));
    }

    return 0;
}
 


http://www.ppmy.cn/news/83616.html

相关文章

利用KubeVela和KEDA实现自动化弹性伸缩的最佳实践

随着云计算技术的不断发展&#xff0c;应用系统的规模和复杂度都在不断增加&#xff0c;弹性伸缩能力已经成为现代应用系统必不可少的一部分。弹性伸缩能力是指应用系统能够在不影响服务质量的情况下&#xff0c;根据负载和资源使用情况进行自动调整&#xff0c;包括扩容和缩容…

真题详解(树的结点)-软件设计(八十四)

真题详解&#xff08;汇总&#xff09;-软件设计&#xff08;八十三)https://blog.csdn.net/ke1ying/article/details/130856130?spm1001.2014.3001.5501 COCOMOII估算不包括_____。 对象点 B.功能点 C.用例数 D.源代码行 答案&#xff1a;C 语法翻译是一种&#xff…

Conda、Git、pip设置代理教程 解决Torch not compiled with CUDA enabled问题

Conda设置代理 在使用Conda时&#xff0c;如果您需要通过代理访问网络资源&#xff0c;可以按照以下步骤配置代理&#xff1a; 打开终端并运行以下命令以设置HTTP代理&#xff1a; conda config --set proxy_servers.http http://<代理服务器>:<端口号> 请将“&…

文件包含的本质、预处理符号、# vs ##

何为头文件&#xff1f; 在C语言中&#xff0c;文件包含是一种常见的编程技术&#xff0c;它允许程序员在一个源文件中使用另一个源文件中的函数或变量。 文件包含通常使用#include预处理指令来实现。#include指令告诉预处理器将文件的内容插入到当前文件的指定位置中。 例如&a…

029:Mapbox GL绘制铁路黑白交替的线段

第029个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中加载数据显示铁路标识的那种黑白交替的线段。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共94行)相关API参考:专栏目标示例效果 配置方式 1)…

arthas使用分析

一 简介 Arthas 是一款线上监控诊断产品&#xff0c;通过全局视角实时查看应用 load、内存、gc、线程的状态信息&#xff0c;并能在不修改应用代码的情况下&#xff0c;对业务问题进行诊断&#xff0c;包括查看方法调用的出入参、异常&#xff0c;监测方法执行耗时&#xff0c…

【学习记录】大数据课程-学习十六周总结

4.2.4.外部表操作 在创建表的时候可以指定external关键字创建外部表,外部表对应的文件存储在location指定的hdfs目录下,向该目录添加新文件的同时&#xff0c;该表也会读取到该文件(当然文件格式必须跟表定义的一致)。 外部表因为是指定其他的hdfs路径的数据加载到表当中来&am…

Java15:枚举和注解

一&#xff1a;枚举&#xff1a; 1.枚举类的使用&#xff1a; 》枚举类的理解&#xff1a;类的对象只有有限个&#xff0c;确定的。我们称为枚举类 》当需要定义一组常量时&#xff0c;强烈建议使用枚举类 》如果枚举类中只有一个对象&#xff0c;则可以作为单列模式的方式…