java aac rtp封装_分享一段H264视频和AAC音频的RTP封包代码

1. H264视频的RTP封包

static int h264_parse(Track *tr, uint8_t *data, size_t len)

{

h264_priv *priv = tr->private_data;

//    double nal_time; // see page 9 and 7.4.1.2

size_t nalsize = 0, index = 0;

uint8_t *p, *q;

if (priv->is_avc) {

while (1) {

unsigned int i;

if(index >= len) break;

//get the nal size

nalsize = 0;

for(i = 0; i < priv->nal_length_size; i++)

nalsize = (nalsize << 8) | data[index++];

if(nalsize <= 1 || nalsize > len) {

if(nalsize == 1) {

index++;

continue;

} else {

fnc_log(FNC_LOG_VERBOSE, "[h264] AVC: nal size %d", nalsize);

break;

}

}

if (DEFAULT_MTU >= nalsize) {

mparser_buffer_write(tr,

tr->properties.pts,

tr->properties.dts,

tr->properties.frame_duration,

1,

data + index, nalsize);

fnc_log(FNC_LOG_VERBOSE, "[h264] single NAL");

} else {

// single NAL, to be fragmented, FU-A;

frag_fu_a(data + index, nalsize, DEFAULT_MTU, tr);

}

index += nalsize;

}

} else {

//seek to the first startcode

for (p = data; p

if (p[0] == 0 && p[1] == 0 && p[2] == 1) {

break;

}

}

if (p >= data + len) return ERR_PARSE;

while (1) {

//seek to the next startcode [0 0 1]

for (q = p; q

if (q[0] == 0 && q[1] == 0 && q[2] == 1) {

break;

}

}

if (q >= data + len) break;

if (DEFAULT_MTU >= q - p) {

fnc_log(FNC_LOG_VERBOSE, "[h264] Sending NAL %d",p[0]&0x1f);

mparser_buffer_write(tr,

tr->properties.pts,

tr->properties.dts,

tr->properties.frame_duration,

1,

p, q - p);

fnc_log(FNC_LOG_VERBOSE, "[h264] single NAL");

} else {

//FU-A

fnc_log(FNC_LOG_VERBOSE, "[h264] frags");

frag_fu_a(p, q - p, DEFAULT_MTU, tr);

}

p = q;

}

// last NAL

fnc_log(FNC_LOG_VERBOSE, "[h264] last NAL %d",p[0]&0x1f);

if (DEFAULT_MTU >= len - (p - data)) {

fnc_log(FNC_LOG_VERBOSE, "[h264] no frags");

mparser_buffer_write(tr,

tr->properties.pts,

tr->properties.dts,

tr->properties.frame_duration,

1,

p, len - (p - data));

} else {

//FU-A

fnc_log(FNC_LOG_VERBOSE, "[h264] frags");

frag_fu_a(p, len - (p - data), DEFAULT_MTU, tr);

}

}

fnc_log(FNC_LOG_VERBOSE, "[h264] Frame completed");

return ERR_NOERROR;

}

static int h264_parse(Track *tr, uint8_t *data, size_t len)

{

h264_priv *priv = tr->private_data;

//    double nal_time; // see page 9 and 7.4.1.2

size_t nalsize = 0, index = 0;

uint8_t *p, *q;

if (priv->is_avc) {

while (1) {

unsigned int i;

if(index >= len) break;

//get the nal size

nalsize = 0;

for(i = 0; i nal_length_size; i++)

nalsize = (nalsize <

if(nalsize <= 1 || nalsize > len) {

if(nalsize == 1) {

index++;

continue;

} else {

fnc_log(FNC_LOG_VERBOSE, "[h264] AVC: nal size %d", nalsize);

break;

}

}

if (DEFAULT_MTU >= nalsize) {

mparser_buffer_write(tr,

tr->properties.pts,

tr->properties.dts,

tr->properties.frame_duration,

1,

data + index, nalsize);

fnc_log(FNC_LOG_VERBOSE, "[h264] single NAL");

} else {

// single NAL, to be fragmented, FU-A;

frag_fu_a(data + index, nalsize, DEFAULT_MTU, tr);

}

index += nalsize;

}

} else {

//seek to the first startcode

for (p = data; p

if (p[0] == 0 && p[1] == 0 && p[2] == 1) {

break;

}

}

if (p >= data + len) return ERR_PARSE;

while (1) {

//seek to the next startcode [0 0 1]

for (q = p; q

if (q[0] == 0 && q[1] == 0 && q[2] == 1) {

break;

}

}

if (q >= data + len) break;

if (DEFAULT_MTU >= q - p) {

fnc_log(FNC_LOG_VERBOSE, "[h264] Sending NAL %d",p[0]&0x1f);

mparser_buffer_write(tr,

tr->properties.pts,

tr->properties.dts,

tr->properties.frame_duration,

1,

p, q - p);

fnc_log(FNC_LOG_VERBOSE, "[h264] single NAL");

} else {

//FU-A

fnc_log(FNC_LOG_VERBOSE, "[h264] frags");

frag_fu_a(p, q - p, DEFAULT_MTU, tr);

}

p = q;

}

// last NAL

fnc_log(FNC_LOG_VERBOSE, "[h264] last NAL %d",p[0]&0x1f);

if (DEFAULT_MTU >= len - (p - data)) {

fnc_log(FNC_LOG_VERBOSE, "[h264] no frags");

mparser_buffer_write(tr,

tr->properties.pts,

tr->properties.dts,

tr->properties.frame_duration,

1,

p, len - (p - data));

} else {

//FU-A

fnc_log(FNC_LOG_VERBOSE, "[h264] frags");

frag_fu_a(p, len - (p - data), DEFAULT_MTU, tr);

}

}

fnc_log(FNC_LOG_VERBOSE, "[h264] Frame completed");

return ERR_NOERROR;

}

2. AAC的RTP封包

static int aac_parse(Track *tr, uint8_t *data, size_t len)

{

//XXX handle the last packet on EOF

int off = 0;

uint32_t payload = DEFAULT_MTU - AU_HEADER_SIZE;

uint8_t *packet = g_malloc0(DEFAULT_MTU);

if(!packet) return ERR_ALLOC;

// trim away extradata

//    data += AAC_EXTRA;

//    len -= AAC_EXTRA;

packet[0] = 0x00;

packet[1] = 0x10;

packet[2] = (len & 0x1fe0) >> 5;

packet[3] = (len & 0x1f) << 3;

if (len > payload) {

while (len > payload) {

memcpy(packet + AU_HEADER_SIZE, data + off, payload);

mparser_buffer_write(tr,

tr->properties.pts,

tr->properties.dts,

tr->properties.frame_duration,

0,

packet, DEFAULT_MTU);

len -= payload;

off += payload;

}

}

memcpy(packet + AU_HEADER_SIZE, data + off, len);

mparser_buffer_write(tr,

tr->properties.pts,

tr->properties.dts,

tr->properties.frame_duration,

1,

packet, len + AU_HEADER_SIZE);

g_free(packet);

return ERR_NOERROR;

}

static int aac_parse(Track *tr, uint8_t *data, size_t len)

{

//XXX handle the last packet on EOF

int off = 0;

uint32_t payload = DEFAULT_MTU - AU_HEADER_SIZE;

uint8_t *packet = g_malloc0(DEFAULT_MTU);

if(!packet) return ERR_ALLOC;

// trim away extradata

//    data += AAC_EXTRA;

//    len -= AAC_EXTRA;

packet[0] = 0x00;

packet[1] = 0x10;

packet[2] = (len & 0x1fe0) >> 5;

packet[3] = (len & 0x1f) <

if (len > payload) {

while (len > payload) {

memcpy(packet + AU_HEADER_SIZE, data + off, payload);

mparser_buffer_write(tr,

tr->properties.pts,

tr->properties.dts,

tr->properties.frame_duration,

0,

packet, DEFAULT_MTU);

len -= payload;

off += payload;

}

}

memcpy(packet + AU_HEADER_SIZE, data + off, len);

mparser_buffer_write(tr,

tr->properties.pts,

tr->properties.dts,

tr->properties.frame_duration,

1,

packet, len + AU_HEADER_SIZE);

g_free(packet);

return ERR_NOERROR;

}

上面的变量 AU_HEADER_SIZE=4

/* au header

+---------------------------------------+

|     AU-size                           |

+---------------------------------------+

|     AU-Index / AU-Index-delta         |

+---------------------------------------+

|     CTS-flag                          |

+---------------------------------------+

|     CTS-delta                         |

+---------------------------------------+

|     DTS-flag                          |

+---------------------------------------+

|     DTS-delta                         |

+---------------------------------------+

|     RAP-flag                          |

+---------------------------------------+

|     Stream-state                      |

+---------------------------------------+

*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/426563.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

玩转oracle 11g(4):连接,文件操作,交互命令

1连接plsql开始学习 2 Oracle安装会自动的生成sys用户和system用户: &#xff08;1&#xff09; sys用户是超级用户&#xff0c;具有最高权限&#xff0c;具有sysdba角色&#xff0c;有create database的权限&#xff0c;该用户默认的密码是change_on_install &#xff08;2&a…

AT1984 Wide Swap

AT1984 Wide Swap 题意翻译 给出一个元素集合为\(\{1,2,\dots,N\}(1\leq N\leq 500,000)\)的排列\(P\)&#xff0c;当有\(i,j(1\leq i<j\leq N)\)满足\(j-i\geq K\)\((1\leq K\leq N-1)\)且\(|P_{i}-P{j}|1\)时&#xff0c;可以交换\(P_{i}\)和\(P_{j}\) 求&#xff1a;可能…

玩转oracle 11g(5):表空间的作用

表空间是oracle内部定义的一个概念,是为了统一oracle物理和逻辑 上的结构而专门建立的,从物理上来说,一个表空间是由具体的一个或多个磁盘上数 据文件构成的(至少1对1,可以1对多),从逻辑上来说一个表空间是由具体的一个或 多个用户模式下的表,索引等等里面的数据所构成的. 因此…

苹果4s有java系统版本_iphone4s用ios8卡吗?iPhone4s升级iOS8正式版手机体验

9月10日凌晨1点正式推出了iPhone6与iPhone6 Plus&#xff0c;与这两款新机一同来临的还有iOS 8正式版&#xff0c;在北京时间9月18日凌晨&#xff0c;苹果正式向用户推送了iOS 8正式版操作系统。iOS8系统在手机方面仅支持iPhone 4S及以上的设备&#xff0c;不少用户都担心iPhon…

软件——机器学习与Python,Python3的输出与输入

输出 用print()在括号中加上字符串&#xff0c;就可以向屏幕上输出指定的文字。比如输出hello, world&#xff0c;用代码实现如下&#xff1a; >>> print(hello, world)print()函数也可以接受多个字符串&#xff0c;用逗号“,”隔开&#xff0c;就可以连成一串输出&am…

玩转oracle 11g(6): oracle用户管理

oracle用户的管理 创建用户 概述&#xff1a;在oracle中要创建一个新的用户使用create user语句&#xff0c;一般是具有dba(数据库管理员)的权限才能使用。 create user 用户名 identified by 密码; (oracle有个毛病&#xff0c;密码必须以字母开头&#xff0c;如果以字母开头&…

玩转oracle 11g(7):导出导入数据库

oracle11g数据库导入导出&#xff1a; ①:传统方式——exp(导出)和(imp)导入&#xff1a; ②:数据泵方式——expdp导出和&#xff08;impdp&#xff09;导入; ③:第三方工具——PL/sql Develpoer; 一、什么是数据库导入导出&#xff1f; oracle11g数据库的导入/导出&#xff0c…

会php学java入门要多久_php8(java入门要多久)

PHP编程运算&#xff0c;如何得到3 4 7 8 11 12 15 16 19 20这个规律的数字 其实就是.arr []; for (i 3; i < 20;) { if (i % 2 ! 0) { arr.push(i)&#xff1b; // 相邻百两个度数字&#xff0c;比知如 3 4 arr.push(i 1); i 4&#xff1b; // 跳跃道至下专一个分属段 …

java学习(43):值参数传递

//值参数传递 class student02{ private int age; private int strong; public void addition(int age,int strong){ System.out.println(“年龄为”age); System.out.println(“体重为”strong); age12; strong13; } } public class test10 { public static void main(String…

CentOS 7 主机名bogon解决办法

转https://blog.csdn.net/qq_24221531/article/details/80334942一、修改linux主机的配置文件/etc/hostname 和 /etc/hosts&#xff0c;这种方式修改后系统重启依旧有效。1.修改/etc/hostname里面的主机名字。# vim /etc/hostname#localhost.localdomain//屏蔽这一行localhost/…

python get post请求_使用python封装get+post请求

VS2010编写WebService与在IIS的发布&lt&semi;之简单讲解&gt&semi;工具VS2010,window环境win7 一:Webservice的创建与方法查看调用 1.新建空web应用程序项目 2.新建web服务 3.自动生成 4.直接跑起来,可以看到有2个方法 5.点击H ...subversionyum install apr-ut…

java学习(44):引用参数传递

//引用参数传递 class test13 { public void seeBook(Book book){ System.out.println("我正在看书,信息如下 "); System.out.println(book.getTitle()); System.out.println(book.getPageSize()); book.setTitle(“三国演义”); book.setPageSize(5000); } } class…

Vector的使用详解

Java中 Vector的使用详解 Vector 可实现自动增长的对象数组。 java.util.vector提供了向量类(Vector)以实现类似动态数组的功能。 创建了一个向量类的对象后&#xff0c;可以往其中随意插入不同类的对象&#xff0c;即不需顾及类型也不需预先选定向量的容量&#xff0c;并可以方…

java加载sql2016_SQl Server 2016 with R.

我有下面的查询DECLARE speedmodel varbinary(max) (SELECT [model] FROM [dbo].[stopping_distance_models] WHERE model_name latest model);EXEC sp_execute_external_scriptlanguage NR, script Ncurrent_model new predicted.distance str(predicted.distance);Output…

java学习(45):无参无返回

/*如何定义 Java 中的方法 所谓方法&#xff0c;就是用来解决一类问题的代码的有序组合&#xff0c;是一个功能模块。 一般情况下&#xff0c;定义一个方法的语法是&#xff1a;访问修饰符 返回值类型 方法名(参数列表){方法体} 其中&#xff1a; 1、 访问修饰符&#xff1a;…

jQuery中map方法

jQuery的map方法可以遍历数组&#xff0c;也可以遍历伪数组 $(function(){var arr[1,2,34,]var fakeArray {length: 3,"0": "first","1": "second","2": "third"};$.map(arr,function(value,index){ //arr要遍…

java 内部thread_Java代码质量改进之:使用ThreadLocal维护线程内部变量

在上文中&#xff0c;《Java代码质量改进之&#xff1a;同步对象的选择》&#xff0c;我们提出了一个场景&#xff1a;火车站有3个售票窗口&#xff0c;同时在售一趟列车的100个座位。我们通过锁定一个靠谱的同步对象&#xff0c;完成了上面的功能。现在&#xff0c;让我们反过…

java学习(46):无参带返回

/*1、 如果方法的返回类型为 void &#xff0c;则方法中不能使用 return 返回值&#xff01; *2、 方法的返回值最多只能有一个&#xff0c;不能返回多个值 *3、 方法返回值的类型必须兼容&#xff0c;例如&#xff0c;如果返回值类型为 int &#xff0c;则不能返回 String 型值…

Luogu 4284 [SHOI2014]概率充电器

BZOJ 3566 树形$dp$ 概率期望。 每一个点的贡献都是$1$&#xff0c;在本题中期望就等于概率。 发现每一个点要通电会在下面三件事中至少发生一件&#xff1a; 1、它自己通电了。 2、它的父亲给它通电了。 3、它的儿子给它通电了。 那么我们设$f_i$表示它的父亲给它通电的概率&…

java 域的隐藏_Windows Server 2008R2\2012\2016使用域策略自定义隐藏指定驱动器

Windows Server 2008R2\2012\2016使用域策略自定义隐藏指定驱动器最近在做项目的时候需要对Win7客户端的部分驱动器进行隐藏&#xff0c;但域策略默认的隐藏选项不能满足需求&#xff0c;根据微软官方文档https://support.microsoft.com/zh-cn/help/231289/using-group-policy-…