1. H264视频的RTP封包

  1. static int h264_parse(Track *tr, uint8_t *data, size_t len)
  2. {
  3. h264_priv *priv = tr->private_data;
  4. //    double nal_time; // see page 9 and 7.4.1.2
  5. size_t nalsize = 0, index = 0;
  6. uint8_t *p, *q;
  7. if (priv->is_avc) {
  8. while (1) {
  9. unsigned int i;
  10. if(index >= len) break;
  11. //get the nal size
  12. nalsize = 0;
  13. for(i = 0; i < priv->nal_length_size; i++)
  14. nalsize = (nalsize << 8) | data[index++];
  15. if(nalsize <= 1 || nalsize > len) {
  16. if(nalsize == 1) {
  17. index++;
  18. continue;
  19. } else {
  20. fnc_log(FNC_LOG_VERBOSE, "[h264] AVC: nal size %d", nalsize);
  21. break;
  22. }
  23. }
  24. if (DEFAULT_MTU >= nalsize) {
  25. mparser_buffer_write(tr,
  26. tr->properties.pts,
  27. tr->properties.dts,
  28. tr->properties.frame_duration,
  29. 1,
  30. data + index, nalsize);
  31. fnc_log(FNC_LOG_VERBOSE, "[h264] single NAL");
  32. } else {
  33. // single NAL, to be fragmented, FU-A;
  34. frag_fu_a(data + index, nalsize, DEFAULT_MTU, tr);
  35. }
  36. index += nalsize;
  37. }
  38. } else {
  39. //seek to the first startcode
  40. for (p = data; p<data + len - 3; p++) {
  41. if (p[0] == 0 && p[1] == 0 && p[2] == 1) {
  42. break;
  43. }
  44. }
  45. if (p >= data + len) return ERR_PARSE;
  46. while (1) {
  47. //seek to the next startcode [0 0 1]
  48. for (q = p; q<data+len-3;q++) {
  49. if (q[0] == 0 && q[1] == 0 && q[2] == 1) {
  50. break;
  51. }
  52. }
  53. if (q >= data + len) break;
  54. if (DEFAULT_MTU >= q - p) {
  55. fnc_log(FNC_LOG_VERBOSE, "[h264] Sending NAL %d",p[0]&0x1f);
  56. mparser_buffer_write(tr,
  57. tr->properties.pts,
  58. tr->properties.dts,
  59. tr->properties.frame_duration,
  60. 1,
  61. p, q - p);
  62. fnc_log(FNC_LOG_VERBOSE, "[h264] single NAL");
  63. } else {
  64. //FU-A
  65. fnc_log(FNC_LOG_VERBOSE, "[h264] frags");
  66. frag_fu_a(p, q - p, DEFAULT_MTU, tr);
  67. }
  68. p = q;
  69. }
  70. // last NAL
  71. fnc_log(FNC_LOG_VERBOSE, "[h264] last NAL %d",p[0]&0x1f);
  72. if (DEFAULT_MTU >= len - (p - data)) {
  73. fnc_log(FNC_LOG_VERBOSE, "[h264] no frags");
  74. mparser_buffer_write(tr,
  75. tr->properties.pts,
  76. tr->properties.dts,
  77. tr->properties.frame_duration,
  78. 1,
  79. p, len - (p - data));
  80. } else {
  81. //FU-A
  82. fnc_log(FNC_LOG_VERBOSE, "[h264] frags");
  83. frag_fu_a(p, len - (p - data), DEFAULT_MTU, tr);
  84. }
  85. }
  86. fnc_log(FNC_LOG_VERBOSE, "[h264] Frame completed");
  87. return ERR_NOERROR;
  88. }
  1. static int h264_parse(Track *tr, uint8_t *data, size_t len)
  2. {
  3. h264_priv *priv = tr->private_data;
  4. //    double nal_time; // see page 9 and 7.4.1.2
  5. size_t nalsize = 0, index = 0;
  6. uint8_t *p, *q;
  7. if (priv->is_avc) {
  8. while (1) {
  9. unsigned int i;
  10. if(index >= len) break;
  11. //get the nal size
  12. nalsize = 0;
  13. for(i = 0; i < priv->nal_length_size; i++)
  14. nalsize = (nalsize << 8) | data[index++];
  15. if(nalsize <= 1 || nalsize > len) {
  16. if(nalsize == 1) {
  17. index++;
  18. continue;
  19. } else {
  20. fnc_log(FNC_LOG_VERBOSE, "[h264] AVC: nal size %d", nalsize);
  21. break;
  22. }
  23. }
  24. if (DEFAULT_MTU >= nalsize) {
  25. mparser_buffer_write(tr,
  26. tr->properties.pts,
  27. tr->properties.dts,
  28. tr->properties.frame_duration,
  29. 1,
  30. data + index, nalsize);
  31. fnc_log(FNC_LOG_VERBOSE, "[h264] single NAL");
  32. } else {
  33. // single NAL, to be fragmented, FU-A;
  34. frag_fu_a(data + index, nalsize, DEFAULT_MTU, tr);
  35. }
  36. index += nalsize;
  37. }
  38. } else {
  39. //seek to the first startcode
  40. for (p = data; p<data + len - 3; p++) {
  41. if (p[0] == 0 && p[1] == 0 && p[2] == 1) {
  42. break;
  43. }
  44. }
  45. if (p >= data + len) return ERR_PARSE;
  46. while (1) {
  47. //seek to the next startcode [0 0 1]
  48. for (q = p; q<data+len-3;q++) {
  49. if (q[0] == 0 && q[1] == 0 && q[2] == 1) {
  50. break;
  51. }
  52. }
  53. if (q >= data + len) break;
  54. if (DEFAULT_MTU >= q - p) {
  55. fnc_log(FNC_LOG_VERBOSE, "[h264] Sending NAL %d",p[0]&0x1f);
  56. mparser_buffer_write(tr,
  57. tr->properties.pts,
  58. tr->properties.dts,
  59. tr->properties.frame_duration,
  60. 1,
  61. p, q - p);
  62. fnc_log(FNC_LOG_VERBOSE, "[h264] single NAL");
  63. } else {
  64. //FU-A
  65. fnc_log(FNC_LOG_VERBOSE, "[h264] frags");
  66. frag_fu_a(p, q - p, DEFAULT_MTU, tr);
  67. }
  68. p = q;
  69. }
  70. // last NAL
  71. fnc_log(FNC_LOG_VERBOSE, "[h264] last NAL %d",p[0]&0x1f);
  72. if (DEFAULT_MTU >= len - (p - data)) {
  73. fnc_log(FNC_LOG_VERBOSE, "[h264] no frags");
  74. mparser_buffer_write(tr,
  75. tr->properties.pts,
  76. tr->properties.dts,
  77. tr->properties.frame_duration,
  78. 1,
  79. p, len - (p - data));
  80. } else {
  81. //FU-A
  82. fnc_log(FNC_LOG_VERBOSE, "[h264] frags");
  83. frag_fu_a(p, len - (p - data), DEFAULT_MTU, tr);
  84. }
  85. }
  86. fnc_log(FNC_LOG_VERBOSE, "[h264] Frame completed");
  87. return ERR_NOERROR;
  88. }

2. AAC的RTP封包

  1. static int aac_parse(Track *tr, uint8_t *data, size_t len)
  2. {
  3. //XXX handle the last packet on EOF
  4. int off = 0;
  5. uint32_t payload = DEFAULT_MTU - AU_HEADER_SIZE;
  6. uint8_t *packet = g_malloc0(DEFAULT_MTU);
  7. if(!packet) return ERR_ALLOC;
  8. // trim away extradata
  9. //    data += AAC_EXTRA;
  10. //    len -= AAC_EXTRA;
  11. packet[0] = 0x00;
  12. packet[1] = 0x10;
  13. packet[2] = (len & 0x1fe0) >> 5;
  14. packet[3] = (len & 0x1f) << 3;
  15. if (len > payload) {
  16. while (len > payload) {
  17. memcpy(packet + AU_HEADER_SIZE, data + off, payload);
  18. mparser_buffer_write(tr,
  19. tr->properties.pts,
  20. tr->properties.dts,
  21. tr->properties.frame_duration,
  22. 0,
  23. packet, DEFAULT_MTU);
  24. len -= payload;
  25. off += payload;
  26. }
  27. }
  28. memcpy(packet + AU_HEADER_SIZE, data + off, len);
  29. mparser_buffer_write(tr,
  30. tr->properties.pts,
  31. tr->properties.dts,
  32. tr->properties.frame_duration,
  33. 1,
  34. packet, len + AU_HEADER_SIZE);
  35. g_free(packet);
  36. return ERR_NOERROR;
  37. }
  1. static int aac_parse(Track *tr, uint8_t *data, size_t len)
  2. {
  3. //XXX handle the last packet on EOF
  4. int off = 0;
  5. uint32_t payload = DEFAULT_MTU - AU_HEADER_SIZE;
  6. uint8_t *packet = g_malloc0(DEFAULT_MTU);
  7. if(!packet) return ERR_ALLOC;
  8. // trim away extradata
  9. //    data += AAC_EXTRA;
  10. //    len -= AAC_EXTRA;
  11. packet[0] = 0x00;
  12. packet[1] = 0x10;
  13. packet[2] = (len & 0x1fe0) >> 5;
  14. packet[3] = (len & 0x1f) << 3;
  15. if (len > payload) {
  16. while (len > payload) {
  17. memcpy(packet + AU_HEADER_SIZE, data + off, payload);
  18. mparser_buffer_write(tr,
  19. tr->properties.pts,
  20. tr->properties.dts,
  21. tr->properties.frame_duration,
  22. 0,
  23. packet, DEFAULT_MTU);
  24. len -= payload;
  25. off += payload;
  26. }
  27. }
  28. memcpy(packet + AU_HEADER_SIZE, data + off, len);
  29. mparser_buffer_write(tr,
  30. tr->properties.pts,
  31. tr->properties.dts,
  32. tr->properties.frame_duration,
  33. 1,
  34. packet, len + AU_HEADER_SIZE);
  35. g_free(packet);
  36. return ERR_NOERROR;
  37. }

上面的变量 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封包代码的更多相关文章

  1. C#音视频网络流解码:H264视频和ACC音频

    下面两种方式是直接翻译过来的,还有问题,比如指针的使用和值的传入.考虑C#和C++的差异,还是要抱着怀疑的态度去看待,不一定是对的. H264视频解码网络流: using FFmpeg.AutoGen ...

  2. 屏幕录制H.264视频,AAC音频,MP4复,LibRTMP现场活动

    上周完成了一个屏幕录制节目,实时屏幕捕获.记录,视频H.264压缩,音频应用AAC压缩,复用MP4格公式,这使得计算机和ios设备上直接播放.支持HTML5的播放器都能够放,这是标准格式的优点.抓屏也 ...

  3. 基于RTP的H264视频数据打包解包类

    from:http://blog.csdn.net/dengzikun/article/details/5807694 最近考虑使用RTP替换原有的高清视频传输协议,遂上网查找有关H264视频RTP打 ...

  4. 使用ffmpeg将BMP图片编码为x264视频文件,将H264视频保存为BMP图片,yuv视频文件保存为图片的代码

    ffmpeg开源库,实现将bmp格式的图片编码成x264文件,并将编码好的H264文件解码保存为BMP文件. 实现将视频文件yuv格式保存的图片格式的測试,图像格式png,jpg, gif等等測试均O ...

  5. 采集音频和摄像头视频并实时H264编码及AAC编码[转]

    0. 前言 我在前两篇文章中写了DirectShow捕获音视频然后生成avi,再进行264编码的方法.那种方法有一些局限性,不适合实时性质的应用,如:视频会议.视频聊天.视频监控等.本文所使用的技术, ...

  6. 采集音频和摄像头视频并实时H264编码及AAC编码

    转自:http://www.cnblogs.com/haibindev/archive/2011/11/10/2244442.html 0. 前言 我在前两篇文章中写了DirectShow捕获音视频然 ...

  7. 分享一段视频关于SQL2014 Hekaton数据库的

    分享一段视频关于SQL2014 Hekaton数据库的 Microsoft SQL Server In-Memory OLTP Project "Hekaton": App Dev ...

  8. 分享macOS平台好用的视频分割、合并视频、提取音频、分离音频、音频转码的工具CCVideo

    CCVideo 是一款运行在macOS上可分割视频(可多段分割).合并视频.提取音频.分离音频.音频转码的工具,操作方便,只需简单几步,便可轻松完成. 下载地址

  9. 音视频编解码技术(二):AAC 音频编码技术

    一.AAC编码概述 AAC是高级音频编码(Advanced Audio Coding)的缩写,出现于1997年,最初是基于MPEG-2的音频编码技术,目的是取代MP3格式.2000年,MPEG-4标准 ...

随机推荐

  1. Python性能分析指南

    http://www.admin10000.com/document/2861.html 尽管并非每个你写的Python程序都需要严格的性能分析,但了解一下Python的生态系统中很多优秀的在你需要做 ...

  2. Javascript表格中搜索

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  3. [转] 浅析HTTP协议

    浅析HTTP协议 来源:http://www.cnblogs.com/gpcuster/archive/2009/05/25/1488749.html HTTP协议是什么? 简单来说,就是一个基于应用 ...

  4. 在AngularJS中学习javascript的new function意义及this作用域的生成过程

    慢慢入门吧,不着急. 至少知道了controller和service的分工. new function时,隐含有用this指向function的prototype之意. 这样,两个JAVASCRIPT ...

  5. Win7 64 安装Visual Studio 2010和SQL Server 2008 R2

    1. 在MSDN,我告诉你下载安装文件,VS 2010 不论32位还是64位都是同一个文件,cn_visual_studio_2010_ultimate_x86_dvd_532347.iso.SQL下 ...

  6. lintcode : 二叉树的层次遍历

    题目 二叉树的层次遍历 给出一棵二叉树,返回其节点值的层次遍历(逐层从左往右访问) 样例 给一棵二叉树 {3,9,20,#,#,15,7} : 3 / \ 9 20 / \ 15 7 返回他的分层遍历 ...

  7. Java学习笔记之:Java的数据类型

    一.介绍 变量就是申请内存来存储值.也就是说,当创建变量的时候,需要在内存中申请空间. 内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据. Java语言提供了八种基本类型 ...

  8. 解决不安装VC运行库(VC2005,VC2008),程序运行出错的方法

    因为VS2005以后程序采用了manifest的生成方式,所以发布的时候要和运行库一起发布.但是我们平时开发和发布的时候如果都要客户安装运行库,那就不太方便了.你可以Microsoft下载:http: ...

  9. Java入门到精通——基础篇之多线程实现简单的PV操作的进程同步

    Java入门到精通——基础篇之多线程实现简单的PV操作的进程同步 一.概述     PV操作是对信号量进行的操作.     进程同步是指在并发进程之间存在一种制约关系,一个进程的执行依赖另一个进程的消 ...

  10. Java API —— Random类

    1.Random类概述         此类用于产生随机数         如果用相同的种子创建两个 Random 实例,则对每个实例进行相同的方法调用序列,它们将生成并返回相同的数字序列. 2.构造 ...