分享一段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<data + len - 3; 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<data+len-3;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 < 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<data + len - 3; 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<data+len-3;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) << 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;
- }
上面的变量 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 |
+---------------------------------------+
*/
分享一段H264视频和AAC音频的RTP封包代码的更多相关文章
- C#音视频网络流解码:H264视频和ACC音频
下面两种方式是直接翻译过来的,还有问题,比如指针的使用和值的传入.考虑C#和C++的差异,还是要抱着怀疑的态度去看待,不一定是对的. H264视频解码网络流: using FFmpeg.AutoGen ...
- 屏幕录制H.264视频,AAC音频,MP4复,LibRTMP现场活动
上周完成了一个屏幕录制节目,实时屏幕捕获.记录,视频H.264压缩,音频应用AAC压缩,复用MP4格公式,这使得计算机和ios设备上直接播放.支持HTML5的播放器都能够放,这是标准格式的优点.抓屏也 ...
- 基于RTP的H264视频数据打包解包类
from:http://blog.csdn.net/dengzikun/article/details/5807694 最近考虑使用RTP替换原有的高清视频传输协议,遂上网查找有关H264视频RTP打 ...
- 使用ffmpeg将BMP图片编码为x264视频文件,将H264视频保存为BMP图片,yuv视频文件保存为图片的代码
ffmpeg开源库,实现将bmp格式的图片编码成x264文件,并将编码好的H264文件解码保存为BMP文件. 实现将视频文件yuv格式保存的图片格式的測试,图像格式png,jpg, gif等等測试均O ...
- 采集音频和摄像头视频并实时H264编码及AAC编码[转]
0. 前言 我在前两篇文章中写了DirectShow捕获音视频然后生成avi,再进行264编码的方法.那种方法有一些局限性,不适合实时性质的应用,如:视频会议.视频聊天.视频监控等.本文所使用的技术, ...
- 采集音频和摄像头视频并实时H264编码及AAC编码
转自:http://www.cnblogs.com/haibindev/archive/2011/11/10/2244442.html 0. 前言 我在前两篇文章中写了DirectShow捕获音视频然 ...
- 分享一段视频关于SQL2014 Hekaton数据库的
分享一段视频关于SQL2014 Hekaton数据库的 Microsoft SQL Server In-Memory OLTP Project "Hekaton": App Dev ...
- 分享macOS平台好用的视频分割、合并视频、提取音频、分离音频、音频转码的工具CCVideo
CCVideo 是一款运行在macOS上可分割视频(可多段分割).合并视频.提取音频.分离音频.音频转码的工具,操作方便,只需简单几步,便可轻松完成. 下载地址
- 音视频编解码技术(二):AAC 音频编码技术
一.AAC编码概述 AAC是高级音频编码(Advanced Audio Coding)的缩写,出现于1997年,最初是基于MPEG-2的音频编码技术,目的是取代MP3格式.2000年,MPEG-4标准 ...
随机推荐
- .run文件安装
比如realplay.run 安装方法如下 chmod +x realplay.run ./realplay.run 然后他就会执行安装了,在过程中可能会要求你输入yes或no 安装完后就可以用了
- 牛顿迭代法实现平方根函数sqrt
转自利用牛顿迭代法自己写平方根函数sqrt 给定一个正数a,不用库函数求其平方根. 设其平方根为x,则有x2=a,即x2-a=0.设函数f(x)= x2-a,则可得图示红色的函数曲线.在曲线上任取一点 ...
- Memcache安全配置
Memcache安全配置 瞌睡龙 · 2014/01/20 17:59 0x00 Memcache简介 Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash ...
- PHP字符串函数之 strstr stristr strchr strrchr
strstr -- 查找字符串的首次出现,返回字符串从第一次出现的位置开始到该字符串的结尾或开始. stristr -- strstr 函数的忽略大小写版本 strchr -- strstr 函数的别 ...
- 【面试题013】在O(1)时间删除链表结点
[面试题013]在O(1)时间删除链表结点 我们要删除结点i,我们可以把结点i的下一个结点j的内容复制到结点i,然后呢把结点i的指针指向结点j的下一个结点.然后在删除结点j. 1.如果结点i位于链表 ...
- Javascript操作元素属性方法总结
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- ***iOS 项目的目录结构能看出你的开发经验
最近有师弟去面试iOS开发,他谈论到,面试官竟然问他怎么分目录结构的,而且还具体问到每个子目录的文件名. 目录结构确实很重要,面试官问他这些无疑是想窥探他的开发经验.清晰的目录结构,可让人一眼知道对应 ...
- C语言的字符测试函数
C语言的字符测试函数 isalnum, isalpha, isdigit, isxdigit, isblank, isspace, isascii, iscntrl, ispunct, isgraph ...
- Apache HTTP Server安装
http://blog.csdn.net/wqmain/article/details/8941759 很清楚,很详细,配置连行号都有.下载的时候直接点击链接即可.
- Android:改变Activity切换方式
overridePendingTransition(enterAnim, exitAnim); Intent intent =new Intent(this,item2.class); startAc ...