搜索
bottom↓
回复: 8

VLC接收264 RTP流播放,视频播放不全。

[复制链接]

出0入0汤圆

发表于 2015-5-28 11:11:27 | 显示全部楼层 |阅读模式
刚开始学习264,参考论坛的资源 [工程应用] 按照RFC3984协议实现H264视频RTP打包(附源代码)http://www.chinavideo.org/forum. ... p;extra=&page=1” 和csdnLinux下H.264码流实时RTP打包与发送 [http://blog.csdn.net/jasonwang1002/article/details/12094419]这套代码。
1、源码在win32下正常运行,VLC播放也正常。
2、参考csdn示例移植到linux下之后,程序可以正常运行,但是vlc-2.0.10接受RTP显示数据不全。只能播放3/4左右的视频。
3、使用wireshark和tcpdump抓包监视了vlc的端口,显示数据包和win32下的数据是一致的。也就是说,264的rtp流是发送出去了,可是vlc没有正常播放出来。
4、这套代码移植到arm下,和Ubuntu下效果相同,也是视频显示不全。

环境:Ubuntu12.04
gcc-4.6.3
vlc-2.0.10

另外:用vlc直接播放.264文件是可以正常全部播放出来的。
不知道有人知道这是为什么么?

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2015-5-28 11:52:05 | 显示全部楼层
换个版本的VLC试试看

出0入0汤圆

发表于 2015-5-28 13:59:49 | 显示全部楼层
估计是你代码哪里出问题了 我用live555在ARM上做服务 VLC显示连续运行个把月了都没问题 是在局域网

出0入0汤圆

 楼主| 发表于 2015-5-28 14:38:58 | 显示全部楼层
菜包 发表于 2015-5-28 11:52
换个版本的VLC试试看

手动安装旧版本的vlc各种出错...
Ubuntu软件中心默认就是2.0.10

出0入0汤圆

 楼主| 发表于 2015-5-28 17:24:24 | 显示全部楼层
iqxt88 发表于 2015-5-28 13:59
估计是你代码哪里出问题了 我用live555在ARM上做服务 VLC显示连续运行个把月了都没问题 是在局域网 ...

代码我调试过,输出的NAL数据和win32下完整显示视频的数据是一致的。
  1. /*
  2. http://blog.csdn.net/jasonwang1002/article/details/12094419
  3. */

  4. // MPEG2RTP.h
  5. #include <stdio.h>
  6. #include <stdlib.h>

  7. #include <string.h>

  8. #include <sys/socket.h>

  9. //#include "mem.h"
  10. //

  11. #define PACKET_BUFFER_END            (unsigned int)0x00000000
  12. #define MAX_RTP_PKT_LENGTH     1400

  13. //#define DEST_IP               "192.168.1.110"
  14. #define DEST_IP                "202.112.157.24"
  15. #define DEST_PORT               24444

  16. #define H264                    96

  17. typedef int SOCKET;

  18. typedef struct
  19. {
  20.     /**//* byte 0 */
  21.     unsigned char csrc_len:4;        /**//* expect 0 */
  22.     unsigned char extension:1;        /**//* expect 1, see RTP_OP below */
  23.     unsigned char padding:1;        /**//* expect 0 */
  24.     unsigned char version:2;        /**//* expect 2 */
  25.     /**//* byte 1 */
  26.     unsigned char payload:7;        /**//* RTP_PAYLOAD_RTSP */
  27.     unsigned char marker:1;        /**//* expect 1 */
  28.     /**//* bytes 2, 3 */
  29.     unsigned short seq_no;
  30.     /**//* bytes 4-7 */
  31.     unsigned  long timestamp;
  32.     /**//* bytes 8-11 */
  33.     unsigned long ssrc;            /**//* stream number is used here. */
  34. } RTP_FIXED_HEADER;

  35. typedef struct {
  36.     //byte 0
  37.         unsigned char TYPE:5;
  38.     unsigned char NRI:2;
  39.         unsigned char F:1;

  40. } NALU_HEADER; /**//* 1 BYTES */

  41. typedef struct {
  42.     //byte 0
  43.     unsigned char TYPE:5;
  44.         unsigned char NRI:2;
  45.         unsigned char F:1;


  46. } FU_INDICATOR; /**//* 1 BYTES */

  47. typedef struct {
  48.     //byte 0
  49.     unsigned char TYPE:5;
  50.         unsigned char R:1;
  51.         unsigned char E:1;
  52.         unsigned char S:1;
  53. } FU_HEADER; /**//* 1 BYTES */




  54. //BOOL InitWinsock();
复制代码

  1. /*
  2. http://blog.csdn.net/jasonwang1002/article/details/12094419
  3. */

  4. // NALDecoder.cpp : Defines the entry point for the console application.
  5. //


  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <memory.h>
  10. #include "h264.h"

  11. //add this to 声明 inet_addr
  12. #include <arpa/inet.h>

  13. #include <sys/types.h>
  14. #include <sys/socket.h>
  15. #include <netinet/in.h>

  16. typedef struct
  17. {
  18.   int startcodeprefix_len;      //! 4 for parameter sets and first slice in picture, 3 for everything else (suggested)
  19.   unsigned len;                 //! Length of the NAL unit (Excluding the start code, which does not belong to the NALU)
  20.   unsigned max_size;            //! Nal Unit Buffer size
  21.   int forbidden_bit;            //! should be always FALSE
  22.   int nal_reference_idc;        //! NALU_PRIORITY_xxxx
  23.   int nal_unit_type;            //! NALU_TYPE_xxxx
  24.   char *buf;                    //! contains the first byte followed by the EBSP
  25.   unsigned short lost_packets;  //! true, if packet loss is detected
  26. } NALU_t;

  27. FILE *bits = NULL;                //!< the bit stream file
  28. static int FindStartCode2 (unsigned char *Buf);//查找开始字符0x000001
  29. static int FindStartCode3 (unsigned char *Buf);//查找开始字符0x00000001

  30. static void dumpnal (NALU_t *nal);
  31. //static bool flag = true;
  32. static int info2=0, info3=0;
  33. RTP_FIXED_HEADER        *rtp_hdr;

  34. NALU_HEADER                *nalu_hdr;
  35. FU_INDICATOR        *fu_ind;
  36. FU_HEADER                *fu_hdr;

  37. /*BOOL InitWinsock()
  38. {
  39.     int Error;
  40.     WORD VersionRequested;
  41.     WSADATA WsaData;
  42.     VersionRequested=MAKEWORD(2,2);
  43.     Error=WSAStartup(VersionRequested,&WsaData); //启动WinSock2
  44.     if(Error!=0)
  45.     {
  46.         return FALSE;
  47.     }
  48.     else
  49.     {
  50.         if(LOBYTE(WsaData.wVersion)!=2||HIBYTE(WsaData.wHighVersion)!=2)
  51.         {
  52.             WSACleanup();
  53.             return FALSE;
  54.         }

  55.     }
  56.     return TRUE;
  57. }*/

  58. //为NALU_t结构体分配内存空间
  59. NALU_t *AllocNALU(int buffersize)
  60. {
  61.   NALU_t *n;

  62.   if ((n = (NALU_t*)calloc (1, sizeof (NALU_t))) == NULL)
  63.   {
  64.           printf("AllocNALU: n");
  65.           exit(0);
  66.   }

  67.   n->max_size=buffersize;
  68.   /*
  69.   void *calloc(size_t n, size_t size);
  70. 功 能: 在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。

  71. calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。
  72.   */

  73.   if ((n->buf = (char*)calloc (buffersize, sizeof (char))) == NULL)
  74.   {
  75.     free (n);
  76.     printf ("AllocNALU: n->buf");
  77.         exit(0);
  78.   }

  79.   return n;
  80. }
  81. //释放
  82. void FreeNALU(NALU_t *n)
  83. {
  84.   if (n)
  85.   {
  86.     if (n->buf)
  87.     {
  88.       free(n->buf);
  89.       n->buf=NULL;
  90.     }
  91.     free (n);
  92.   }
  93. }

  94. void OpenBitstreamFile (char *fn)
  95. {
  96.   if (NULL == (bits=fopen(fn, "rb")))
  97.   {
  98.           printf("open file error\n");
  99.           exit(0);
  100.   }
  101. }
  102. //这个函数输入为一个NAL结构体,主要功能为得到一个完整的NALU并保存在NALU_t的buf中,获取他的长度,填充F,IDC,TYPE位。
  103. //并且返回两个开始字符之间间隔的字节数,即包含有前缀的NALU的长度
  104. int GetAnnexbNALU (NALU_t *nalu)
  105. {
  106.   int pos = 0;
  107.   int StartCodeFound, rewind;
  108.   unsigned char *Buf;

  109.   if ((Buf = (unsigned char*)calloc (nalu->max_size , sizeof(char))) == NULL)
  110.           printf ("GetAnnexbNALU: Could not allocate Buf memory\n");

  111.   nalu->startcodeprefix_len=3;//初始化码流序列的开始字符为3个字节

  112. /*fread是一个函数。从一个文件流中读数据,最多读取count个元素,每个元素size字节,如果调用成功返回实际读取到的元素个数,如果不成功或读到文件末尾返回 0。*/
  113.    if (3 != fread (Buf, 1, 3, bits))//从码流中读3个字节
  114.            {
  115.                 free(Buf);
  116.                 return 0;
  117.            }
  118.    info2 = FindStartCode2 (Buf);//判断是否为0x000001
  119.    if(info2 != 1)
  120.    {
  121.         //如果不是,再读一个字节
  122.     if(1 != fread(Buf+3, 1, 1, bits))//读一个字节
  123.                 {
  124.                  free(Buf);
  125.                  return 0;
  126.                 }
  127.     info3 = FindStartCode3 (Buf);//判断是否为0x00000001
  128.     if (info3 != 1)//如果不是,返回-1
  129.                 {
  130.                  free(Buf);
  131.                  return -1;
  132.                 }
  133.     else
  134.                 {
  135.                 //如果是0x00000001,得到开始前缀为4个字节
  136.                  pos = 4;
  137.                  nalu->startcodeprefix_len = 4;
  138.                 }
  139.    }

  140.    else
  141.            {
  142.            //如果是0x000001,得到开始前缀为3个字节
  143.                 nalu->startcodeprefix_len = 3;
  144.                 pos = 3;
  145.            }
  146.    //查找下一个开始字符的标志位
  147.    StartCodeFound = 0;
  148.    info2 = 0;
  149.    info3 = 0;

  150.   while (!StartCodeFound)
  151.   {
  152.       /*如果文件结束,则返回非0值,否则返回0,文件结束符只能被clearerr()清除。yy*/
  153.     if (feof (bits))//判断是否到了文件尾
  154.     {
  155.       nalu->len = (pos-1)-nalu->startcodeprefix_len;
  156.       /*void *memcpy(void *dest, const void *src, size_t n);
  157. 从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始yy*/
  158.       memcpy (nalu->buf, &Buf[nalu->startcodeprefix_len], nalu->len);
  159.       nalu->forbidden_bit = nalu->buf[0] & 0x80; //1 bit
  160.           nalu->nal_reference_idc = nalu->buf[0] & 0x60; // 2 bit
  161.           nalu->nal_unit_type = (nalu->buf[0]) & 0x1f;// 5 bit
  162.       free(Buf);
  163.       return pos-1;
  164.     }
  165.     Buf[pos++] = fgetc (bits);//读一个字节到BUF中
  166.     info3 = FindStartCode3(&Buf[pos-4]);//判断是否为0x00000001
  167.     if(info3 != 1)
  168.     info2 = FindStartCode2(&Buf[pos-3]);//判断是否为0x000001
  169.     StartCodeFound = (info2 == 1 || info3 == 1);
  170.   }

  171.   // Here, we have found another start code (and read length of startcode bytes more than we should
  172.   // have.  Hence, go back in the file

  173.   /*
  174.   (表达式)? x : y ;首先计算表达式的值,若为ture,则"(表达式)? x : y "返回x;否则返回y.yy
  175.   */
  176.   rewind = (info3 == 1)? -4 : -3;
  177. /*
  178. int fseek(FILE *stream, long offset, int fromwhere);函数设置文件指针stream的位置。
  179. 如果执行成功,stream将指向以fromwhere为基准,偏移offset(指针偏移量)个字节的位置,函数返回0。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置,函数返回一个非0值

  180. int fseek(FILE *stream, long offset, int fromwhere);
  181. 第一个参数file指针
  182. 第二个参数移动的偏移量
  183. 第三个参数移动到哪里
  184. 分别用3个宏
  185. SEEK_SET 既0 文件开头
  186. SEEK_CUR 既1 文件当前位置
  187. SEEK_END 既2 文件结尾
  188. 但不推荐用数字 最好用宏

  189. 简言之:
  190.   fseek(fp,100L,SEEK_SET);把fp指针移动到离文件开头100字节处;
  191.   fseek(fp,100L,SEEK_CUR);把fp指针移动到离文件当前位置100字节处;
  192.   fseek(fp,100L,SEEK_END);把fp指针退回到离文件结尾100字节处。
  193. 此函数常用来计算流的长度:
  194.     int filesize = fseek( fp, 0, SEEK_END );
  195.     fseek( fp, 0, SEEK_SET );

  196. */

  197.   if (0 != fseek (bits, rewind, SEEK_CUR))//把文件指针指向前一个NALU的末尾
  198.   {
  199.     free(Buf);
  200.         printf("GetAnnexbNALU: Cannot fseek in the bit stream file");
  201.   }

  202.   // Here the Start code, the complete NALU, and the next start code is in the Buf.
  203.   // The size of Buf is pos, pos+rewind are the number of bytes excluding the next
  204.   // start code, and (pos+rewind)-startcodeprefix_len is the size of the NALU excluding the start code

  205.   nalu->len = (pos+rewind)-nalu->startcodeprefix_len;
  206.   memcpy (nalu->buf, &Buf[nalu->startcodeprefix_len], nalu->len);//拷贝一个完整NALU,不拷贝起始前缀0x000001或0x00000001
  207.   nalu->forbidden_bit = nalu->buf[0] & 0x80; //1 bit
  208.   nalu->nal_reference_idc = nalu->buf[0] & 0x60; // 2 bit
  209.   nalu->nal_unit_type = (nalu->buf[0]) & 0x1f;// 5 bit
  210.   free(Buf);

  211.   return (pos+rewind);//返回两个开始字符之间间隔的字节数,即包含有前缀的NALU的长度
  212. }
  213. //输出NALU长度和TYPE
  214. void dump(NALU_t *n)
  215. {
  216.         if (!n)return;
  217.         //printf("a new nal:");
  218.         printf(" len: %d  ", n->len);
  219.         printf("nal_unit_type: %x\n", n->nal_unit_type);
  220.         //added by yy 输出NAL单元
  221.         dumpnal(n);
  222.         printf("\n");
  223. }

  224. int main(int argc, char* argv[])
  225. {
  226.         //FILE *stream;
  227.         //stream=fopen("Test.264", "wb");

  228.         OpenBitstreamFile("./video-264/test1.264");//打开264文件,并将文件指针赋给bits,在此修改文件名实现打开别的264文件。
  229.         NALU_t *n;
  230.         char* nalu_payload;
  231.         char sendbuf[1500];

  232.         unsigned short seq_num =0;
  233.     //printf("seq_num=%d\n",seq_num);//added by
  234.         int        bytes=0;
  235.         //InitWinsock(); //初始化套接字库
  236.         SOCKET    socket1;
  237.         struct sockaddr_in server;
  238.     int len =sizeof(server);
  239.         float framerate=30; // win下为15
  240.         unsigned int timestamp_increase=0,ts_current=0;
  241.         timestamp_increase=(unsigned int)(90000.0 / framerate); //+0.5);

  242.         server.sin_family=AF_INET;
  243.     server.sin_port=htons(DEST_PORT);
  244.     server.sin_addr.s_addr=inet_addr(DEST_IP);
  245.     socket1=socket(AF_INET,SOCK_DGRAM,0);
  246.     connect(socket1, (const struct sockaddr *)&server, len) ;//申请UDP套接字
  247.         n = AllocNALU(8000000);//为结构体nalu_t及其成员buf分配空间。返回值为指向nalu_t存储空间的指针
  248.         //added by yy
  249. //        int test=feof(bits);
  250.         while(!feof(bits))
  251.         {
  252.                 GetAnnexbNALU(n);//每执行一次,文件的指针指向本次找到的NALU的末尾,下一个位置即为下个NALU的起始码0x000001
  253.                 dump(n);//输出NALU长度和TYPE

  254.                 memset(sendbuf,0,1500);//清空sendbuf;此时会将上次的时间戳清空,因此需要ts_current来保存上次的时间戳值
  255.         //rtp固定包头,为12字节,该句将sendbuf[0]的地址赋给rtp_hdr,以后对rtp_hdr的写入操作将直接写入sendbuf。
  256.                 rtp_hdr =(RTP_FIXED_HEADER*)&sendbuf[0];
  257.                 //设置RTP HEADER,
  258.                 rtp_hdr->payload     = H264;  //负载类型号,
  259.                 rtp_hdr->version     = 2;  //版本号,此版本固定为2
  260.                 rtp_hdr->marker    = 0;   //标志位,由具体协议规定其值。
  261.         rtp_hdr->ssrc        = htonl(10);    //随机指定为10,并且在本RTP会话中全局唯一

  262.         //        当一个NALU小于1400字节的时候,采用一个单RTP包发送
  263.                 if(n->len<=1400)
  264.                 {
  265.                         //设置rtp M 位;
  266.                         rtp_hdr->marker=1;
  267.                         rtp_hdr->seq_no     = htons(seq_num ++); //序列号,每发送一个RTP包增1
  268.                         //设置NALU HEADER,并将这个HEADER填入sendbuf[12]
  269.                         nalu_hdr =(NALU_HEADER*)&sendbuf[12]; //将sendbuf[12]的地址赋给nalu_hdr,之后对nalu_hdr的写入就将写入sendbuf中;
  270.                         nalu_hdr->F=n->forbidden_bit;
  271.                         nalu_hdr->NRI=n->nal_reference_idc>>5;//有效数据在n->nal_reference_idc的第6,7位,需要右移5位才能将其值赋给nalu_hdr->NRI。
  272.                         nalu_hdr->TYPE=n->nal_unit_type;

  273.                         nalu_payload=&sendbuf[13];//同理将sendbuf[13]赋给nalu_payload
  274.                         memcpy(nalu_payload,n->buf+1,n->len-1);//去掉nalu头的nalu剩余内容写入sendbuf[13]开始的字符串。

  275.                         ts_current=ts_current+timestamp_increase;
  276.                         rtp_hdr->timestamp=htonl(ts_current);
  277.                         bytes=n->len + 13 ;                                                //获得sendbuf的长度,为nalu的长度(包含NALU头但除去起始前缀)加上rtp_header的固定长度12字节
  278.                         send( socket1, sendbuf, bytes, 0 );//发送rtp包
  279.                 //        printf("\nseq_no:%d\n",rtp_hdr->seq_no);

  280.                         //sleep(1);
  281.             //fwrite(sendbuf,bytes, 1, stream);
  282.                 }

  283.                 else if(n->len>1400)
  284.                 {
  285.                         //得到该nalu需要用多少长度为1400字节的RTP包来发送
  286.                         int k=0,l=0;
  287.                         k=n->len/1400;//需要k个1400字节的RTP包
  288.                         l=n->len%1400;//最后一个RTP包的需要装载的字节数
  289.                         int t=0;//用于指示当前发送的是第几个分片RTP包
  290.                         ts_current=ts_current+timestamp_increase;
  291.                         rtp_hdr->timestamp=htonl(ts_current);
  292.                         while(t<=k)
  293.                         {
  294.                                 rtp_hdr->seq_no = htons(seq_num ++); //序列号,每发送一个RTP包增1
  295.                                 if(!t)//发送一个需要分片的NALU的第一个分片,置FU HEADER的S位
  296.                                 {
  297.                                         //设置rtp M 位;
  298.                                         rtp_hdr->marker=0;
  299.                                         //设置FU INDICATOR,并将这个HEADER填入sendbuf[12]
  300.                                         fu_ind =(FU_INDICATOR*)&sendbuf[12]; //将sendbuf[12]的地址赋给fu_ind,之后对fu_ind的写入就将写入sendbuf中;
  301.                                         fu_ind->F=n->forbidden_bit;
  302.                                         fu_ind->NRI=n->nal_reference_idc>>5;
  303.                                         fu_ind->TYPE=28;

  304.                                         //设置FU HEADER,并将这个HEADER填入sendbuf[13]
  305.                                         fu_hdr =(FU_HEADER*)&sendbuf[13];
  306.                                         fu_hdr->E=0;
  307.                                         fu_hdr->R=0;
  308.                                         fu_hdr->S=1;
  309.                                         fu_hdr->TYPE=n->nal_unit_type;


  310.                                         nalu_payload=&sendbuf[14];//同理将sendbuf[14]赋给nalu_payload
  311.                                         memcpy(nalu_payload,n->buf+1,1400);//去掉NALU头

  312.                                         bytes=1400+14;                                                //获得sendbuf的长度,为nalu的长度(除去起始前缀和NALU头)加上rtp_header,fu_ind,fu_hdr的固定长度14字节
  313.                                         send( socket1, sendbuf, bytes, 0 );//发送rtp包
  314.                                 //        printf("\nseq_no:%d\n",rtp_hdr->seq_no);
  315. //fwrite(sendbuf,bytes, 1, stream);
  316.                                         //sleep(1);
  317.                                         t++;

  318.                                 }
  319.                                 //发送一个需要分片的NALU的非第一个分片,清零FU HEADER的S位,如果该分片是该NALU的最后一个分片,置FU HEADER的E位
  320.                                 else if(k==t)//发送的是最后一个分片,注意最后一个分片的长度可能超过1400字节(当l>1386时)。
  321.                                 {

  322.                                         //设置rtp M 位;当前传输的是最后一个分片时该位置1
  323.                                         rtp_hdr->marker=1;
  324.                                         //设置FU INDICATOR,并将这个HEADER填入sendbuf[12]
  325.                                         fu_ind =(FU_INDICATOR*)&sendbuf[12]; //将sendbuf[12]的地址赋给fu_ind,之后对fu_ind的写入就将写入sendbuf中;
  326.                                         fu_ind->F=n->forbidden_bit;
  327.                                         fu_ind->NRI=n->nal_reference_idc>>5;
  328.                                         fu_ind->TYPE=28;

  329.                                         //设置FU HEADER,并将这个HEADER填入sendbuf[13]
  330.                                         fu_hdr =(FU_HEADER*)&sendbuf[13];
  331.                                         fu_hdr->R=0;
  332.                                         fu_hdr->S=0;
  333.                                         fu_hdr->TYPE=n->nal_unit_type;
  334.                                         fu_hdr->E=1;

  335.                                         nalu_payload=&sendbuf[14];//同理将sendbuf[14]的地址赋给nalu_payload
  336.                                         memcpy(nalu_payload,n->buf+t*1400+1,l-1);//将nalu最后剩余的l-1(去掉了一个字节的NALU头)字节内容写入sendbuf[14]开始的字符串。
  337.                                         bytes=l-1+14;                //获得sendbuf的长度,为剩余nalu的长度l-1加上rtp_header,FU_INDICATOR,FU_HEADER三个包头共14字节
  338.                                         send( socket1, sendbuf, bytes, 0 );//发送rtp包
  339.                         //                printf("\nseq_no:%d\n",rtp_hdr->seq_no);
  340. //fwrite(sendbuf,bytes, 1, stream);
  341.                                         t++;
  342.                                          //sleep(1);
  343.                                 }
  344.                                 else if(t<k&&0!=t)
  345.                                 {
  346.                                         //设置rtp M 位;
  347.                                         rtp_hdr->marker=0;
  348.                                         //设置FU INDICATOR,并将这个HEADER填入sendbuf[12]
  349.                                         fu_ind =(FU_INDICATOR*)&sendbuf[12]; //将sendbuf[12]的地址赋给fu_ind,之后对fu_ind的写入就将写入sendbuf中;
  350.                                         fu_ind->F=n->forbidden_bit;
  351.                                         fu_ind->NRI=n->nal_reference_idc>>5;
  352.                                         fu_ind->TYPE=28;

  353.                                         //设置FU HEADER,并将这个HEADER填入sendbuf[13]
  354.                                         fu_hdr =(FU_HEADER*)&sendbuf[13];
  355.                                         //fu_hdr->E=0;
  356.                                         fu_hdr->R=0;
  357.                                         fu_hdr->S=0;
  358.                                         fu_hdr->E=0;
  359.                                         fu_hdr->TYPE=n->nal_unit_type;

  360.                                         nalu_payload=&sendbuf[14];//同理将sendbuf[14]的地址赋给nalu_payload
  361.                                         memcpy(nalu_payload,n->buf+t*1400+1,1400);//去掉起始前缀的nalu剩余内容写入sendbuf[14]开始的字符串。
  362.                                         bytes=1400+14;                                                //获得sendbuf的长度,为nalu的长度(除去原NALU头)加上rtp_header,fu_ind,fu_hdr的固定长度14字节
  363.                                         send( socket1, sendbuf, bytes, 0 );//发送rtp包
  364.                         //                printf("\nseq_no:%d\n",rtp_hdr->seq_no);
  365. //fwrite(sendbuf,bytes, 1, stream);
  366.                                         //sleep(1);
  367.                                         t++;
  368.                                 }
  369.                         }
  370.                 }
  371.         //usleep(40000);
  372.         }
  373.         FreeNALU(n);
  374.         return 0;
  375. }

  376. static int FindStartCode2 (unsigned char *Buf)
  377. {
  378. if(Buf[0]!=0 || Buf[1]!=0 || Buf[2] !=1) return 0; //判断是否为0x000001,如果是返回1
  379. else return 1;
  380. }

  381. static int FindStartCode3 (unsigned char *Buf)
  382. {
  383. if(Buf[0]!=0 || Buf[1]!=0 || Buf[2] !=0 || Buf[3] !=1) return 0;//判断是否为0x00000001,如果是返回1
  384. else return 1;
  385. }

  386. static void dumpnal (NALU_t *nal)
  387. {
  388.         // 打印前面 NAL个字节
  389.         int i;
  390.         for (i = 0; i < nal->len; i++) {
  391.                 printf( " %02x ", (unsigned char)nal->buf[i]);
  392.         }
  393. }
复制代码


出0入0汤圆

发表于 2015-6-11 14:21:13 | 显示全部楼层
你用Wireshark抓包对比下

出0入0汤圆

 楼主| 发表于 2015-6-12 16:30:37 | 显示全部楼层
iqxt88 发表于 2015-6-11 14:21
你用Wireshark抓包对比下

3、使用wireshark和tcpdump抓包监视了vlc的端口,显示数据包和win32下的数据是一致的。也就是说,264的rtp流是发送出去了,可是vlc没有正常播放出来。

抓了包的,数据和win32下完整播放的数据是一致的。

我想可能问题还是在vlc版本上,或者网络上。

出0入0汤圆

发表于 2015-6-14 12:10:33 | 显示全部楼层
你看下时间廖是否正常

出0入0汤圆

 楼主| 发表于 2015-7-27 10:00:48 | 显示全部楼层
iqxt88 发表于 2015-6-14 12:10
你看下时间廖是否正常

时间戳部分
<MTU,90000/fps
>MTC 分包之后,时间戳一致,seq_no递增。
这样设置的。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 01:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表