Go VLC plays the. 264 file sent by RTP package

Source: Internet
Author: User
Tags fread rewind htons

VLC plays the. 264 file sent by RTP package

1, to have a server that sends RTP packets of 264 files;

The specific code is as follows:

Rtp.h

#include <WinSock2.h> #pragma comment (lib, "Ws2_32.lib") #define PACKET_BUFFER_END (unsigned int) 0x0000000 0 #define MAX_RTP_PKT_LENGTH 1400 #define DEST_IP "172.18.191.194" #define Dest_port 554#        Define H264-typedef struct {/**//* byte 0 */unsigned char csrc_len:4;        /**//* expect 0 */unsigned char extension:1;        /**//* expect 1, see rtp_op below */unsigned char padding:1;        /**//* expect 0 */unsigned char version:2;        /**//* expect 2 *//**//* byte 1 */unsigned char payload:7;        /**//* RTP_PAYLOAD_RTSP */unsigned char marker:1;              /**//* expect 1 *//**//* bytes 2, 3 */unsigned short seq_no;          /**//* bytes 4-7 */unsigned long timestamp;            /**//* bytes 8-11 */unsigned long ssrc; /**//* stream number is used here.  */} Rtp_fixed_header;  typedef struct {//byte 0 unsigned char type:5;  unsigned char nri:2;      unsigned char f:1; } Nalu_header;  /**//* 1 BYTES */typedef struct {//byte 0 unsigned char type:5;   unsigned char nri:2;      unsigned char f:1; } Fu_indicator;  /**//* 1 BYTES */typedef struct {//byte 0 unsigned char type:5;  unsigned char r:1;  unsigned char e:1;      unsigned char s:1; } Fu_header;   /**//* 1 BYTES */

Rtp.cpp

#include "rtp.h" #include <stdio.h>file * bits = NULL; !< the bit stream file static int FindStartCode2 (unsigned char *buf);//Find start character 0x000001 static int FindStartCode3 (U  nsigned char *buf);//Find start character 0x00000001//static bool flag = true;  static int info2=0, info3=0;  Rtp_fixed_header *rtp_hdr;  Nalu_header *nalu_hdr;  Fu_indicator *fu_ind; Fu_header *fu_hdr;      typedef struct {int startcodeprefix_len; //!                 4 for parameter sets and first slice in picture, 3 for everything else (suggested) unsigned len; //!            Length of the NAL unit (excluding the start code, which does not belong to the Nalu) unsigned max_size; //!            Nal Unit Buffer size int forbidden_bit; //!        Should is always FALSE int nal_reference_idc; //!            nalu_priority_xxxx int nal_unit_type; //!                    Nalu_type_xxxx Char *buf; //!  Contains the first byte followed by the EBSP unsigned short lost_packets; //!  True if packet loss is detected} nalu_t; BOOL Initwinsock () {int Error; WORD versionrequested; Wsadata Wsadata; Versionrequested=makeword (2,2); Error=wsastartup (Versionrequested,&wsadata); Start WinSock2 if (error!=0) {return FALSE;} else {if (Lobyte (wsadata.wversion)!=2| | Hibyte (wsadata.whighversion)!=2) {wsacleanup (); return FALSE;}} return TRUE;  }//allocates memory space for nalu_t struct nalu_t *allocnalu (int buffersize) {nalu_t *n;  if (n = (nalu_t*) calloc (1, sizeof (nalu_t)) = = = NULL) {printf ("allocnalu:n");  Exit (0);  } n->max_size=buffersize;  if (N->buf = (char*) calloc (buffersize, sizeof (char)) = = = NULL) {free (n);  printf ("Allocnalu:n->buf");  Exit (0);  } return N;  }//Releases void Freenalu (nalu_t *n) {if (n) {if (n->buf) {free (N-&GT;BUF);  n->buf=null;  } free (n);  }}//This function is entered as a NAL structure, the main function is to get a complete nalu and save it in nalu_t buf, get his length, fill the f,idc,type bit.  and returns the number of bytes between the two start characters, that is, the length of the nalu containing the prefix int getannexbnalu (nalu_t *nalu) {int pos = 0; int StartcodeFound, Rewind;  unsigned char *buf; if (Buf = (unsigned char*) calloc (nalu->max_size, sizeof (char)) = = NULL) printf ("Getannexbnalu:could not Allocat  E Buf memory\n ");  The start character of the nalu->startcodeprefix_len=3;//initialization stream sequence is 3 bytes if (3! = Fread (Buf, 1, 3, BITS))//Read 3 bytes {free (BUF) from the bitstream;  return 0; } Info2 = FindStartCode2 (BUF);//Determine if 0x000001 if (info2! = 1) {//if not, read one more byte if (1! = Fread (buf+3, 1, 1, BITS))//read one  bytes {free (BUF);  return 0;  } Info3 = FindStartCode3 (BUF);//Determine if 0x00000001 if (Info3! = 1)//If not, return-1 {free (BUF);  return-1;  } else {//If it is 0x00000001, get a start prefix of 4 bytes pos = 4;  Nalu->startcodeprefix_len = 4;  }} else {//If it is 0x000001, get start prefix is 3 bytes Nalu->startcodeprefix_len = 3;  pos = 3;  }//Find the next start character's flag bit startcodefound = 0;  Info2 = 0;  Info3 = 0; while (!  Startcodefound) {if (feof (BITS))//Determines whether to the end of the file {Nalu->len = (pos-1)-nalu->startcodeprefix_len;       memcpy (Nalu->buf, &buf[nalu->startcodeprefix_len], Nalu->len); NaLu->forbidden_bit = nalu->buf[0] & 0x80; 1 bit NALU-&GT;NAL_REFERENCE_IDC = nalu->buf[0] & 0x60;  2 bit Nalu->nal_unit_type = (nalu->buf[0]) & 0x1f;//5 bit free (BUF);  return pos-1; } buf[pos++] = fgetc (bits);//Read a byte to Buf Info3 = FindStartCode3 (&buf[pos-4]);//Determine if it is 0x00000001 if (info3! = 1) Info  2 = FindStartCode2 (&buf[pos-3]);//Determine whether it is 0x000001 startcodefound = (Info2 = = 1 | | info3 = 1);  }//Here, we had found another start code (and read length of Startcode bytes more than we should//has. Hence, go back in the file Rewind = (Info3 = = 1)?  -4:-3;  if (0! = fseek (Bits, rewind, seek_cur))//The file pointer points to the end of the previous Nalu {free (BUF);  printf ("Getannexbnalu:cannot fseek in the bit stream file");    }//Here's the start code, the complete Nalu, and the next start code are in the Buf. The size of Buf is POS, Pos+rewind is the number of bytes excluding the next/Start code, and (Pos+rewind)-startcod Eprefix_len is the size of the Nalu excLuding the start code Nalu->len = (pos+rewind)-nalu->startcodeprefix_len; memcpy (Nalu->buf, &buf[nalu->startcodeprefix_len], nalu->len);//Copy a complete Nalu, Do not copy the starting prefix 0x000001 or 0x00000001 nalu->forbidden_bit = nalu->buf[0] & 0x80; 1 bit NALU-&GT;NAL_REFERENCE_IDC = nalu->buf[0] & 0x60;  2 bit Nalu->nal_unit_type = (nalu->buf[0]) & 0x1f;//5 bit free (BUF);  return (pos+rewind);//Returns the number of bytes between the two start characters, which is the length of the nalu containing the prefix}//output Nalu length and type void dump (nalu_t *n) {if (!n) return;  printf ("A new nal:");  printf ("Len:%d", N->len);  printf ("Nal_unit_type:%x\n", N->nal_unit_type);  } int main (int argc, char* argv[]) {nalu_t * n;    char* Nalu_payload; Char sendbuf[1500];  unsigned short seq_num = 0;  int bytes=0;  SOCKET socket1;struct sockaddr_in server;  int len =sizeof (server);  float framerate=25;  unsigned int timestamp_increase=0,ts_current=0; timestamp_increase= (unsigned int) (90000.0/framerate);  +0.5); Bits=fopen ("my.h264","RB"); Initwinsock ();  Initialize the socket font server.sin_family=af_inet;            Server.sin_port=htons (Dest_port);   SERVER.SIN_ADDR.S_ADDR=INET_ADDR (DEST_IP);  Socket1=socket (af_inet,sock_dgram,0); Connect (Socket1, (const struct sockaddr *) &server, len);//request UDP Socket n = Allocnalu (8000000);//Allocate space for struct nalu_t and its member buf.  The return value is a pointer to nalu_t storage space while (!feof (bits)) {Getannexbnalu (n);//each time the file pointer points to the end of the Nalu found, the next position is the starting code for the next Nalu 0x000001 Dump (n);//output Nalu length and type memset (sendbuf,0,1500);//empty sendbuf; the last timestamp is emptied, so ts_current is required to save the last timestamp value//RTP fixed header, 12 bytes  , the sentence assigns the address of sendbuf[0] to RTP_HDR, and subsequent writes to RTP_HDR are written directly to SendBuf.   RTP_HDR = (rtp_fixed_header*) &sendbuf[0];  Set RTP HEADER, rtp_hdr->payload = H264;  Load type number, rtp_hdr->version = 2;   Version number, this version is fixed to 2 rtp_hdr->marker = 0;  The value of the symbol, specified by the specific agreement.    RTP_HDR-&GT;SSRC = htonl (10); Randomly specified as 10, and globally unique in this RTP session//When a NALU is less than 1400 bytes, a single RTP packet is sent with an if (n->len<=1400) {//Set RTP M bit; rtp_hdr->mark  Er=1; Rtp_hdr->seq_no = htons (seq_num + +); Serial number, each sending a RTP packet 1//Set Nalu header, and fill this header into sendbuf[12] Nalu_hdr = (nalu_header*) &sendbuf[12];  The address of the sendbuf[12] is assigned to NALU_HDR, and the write to Nalu_hdr is then written to SendBuf; nalu_hdr->f=n->forbidden_bit; nalu_hdr->nri=n->nal_reference_idc>>5;//valid data in the 6th, 7 bits of N-&GT;NAL_REFERENCE_IDC, need to move 5 bits to the right to assign its value to nalu_hdr-  >nri.  nalu_hdr->type=n->nal_unit_type; nalu_payload=&sendbuf[13];//Sendbuf[13] Assigned to Nalu_payload memcpy (nalu_payload,n->buf+1,n->len-1);//  The string that nalu the remaining content of the Nalu header is written to sendbuf[13].  Ts_current=ts_current+timestamp_increase;  Rtp_hdr->timestamp=htonl (ts_current);                      Bytes=n->len + 13;  Get the length of the sendbuf, for the length of the Nalu (including the Nalu header but remove the starting prefix) plus the fixed length of Rtp_header 12 bytes Send (socket1, sendbuf, Bytes, 0);//Send RTP packet//sleep (1);   Fwrite (sendbuf,bytes, 1, stream);  } else if (n->len>1400) {///To get the Nalu to send an int k=0,l=0 with a length of 1400 bytes of RTP packets; k=n->len/1400;//requires k 1400 bytes of RTP packet l=n->len%1400;//the last RTP packet needs to load the number of bytes int t=0;//is used to indicate that the current send is the first few shard RTP packets ts_current= Ts_cuRrent+timestamp_increase;  Rtp_hdr->timestamp=htonl (ts_current);   while (t<=k) {rtp_hdr->seq_no = htons (seq_num + +);//serial number, each sending one RTP packet increased by 1 if (!t)//Send a Shard to the first shard of Nalu, the s bit of the FU header {  Set RTP M bit; rtp_hdr->marker=0; Set the FU INDICATOR and fill this header in sendbuf[12] Fu_ind = (fu_indicator*) &sendbuf[12];  The address of the sendbuf[12] is assigned to Fu_ind, and the write to Fu_ind is then written to SendBuf; fu_ind->f=n->forbidden_bit;  fu_ind->nri=n->nal_reference_idc>>5;  fu_ind->type=28;  Set the FU header and fill in the header with sendbuf[13] Fu_hdr = (fu_header*) &sendbuf[13];  fu_hdr->e=0;  fu_hdr->r=0;  fu_hdr->s=1;  fu_hdr->type=n->nal_unit_type;  nalu_payload=&sendbuf[14];//Sendbuf[14] Assigned to Nalu_payload memcpy (nalu_payload,n->buf+1,1400);//Remove Nalu Head                      bytes=1400+14;  Get the length of the sendbuf, for the length of the Nalu (except the starting prefix and Nalu header) plus the fixed length of Rtp_header,fu_ind,fu_hdr 14 bytes Send (socket1, sendbuf, Bytes, 0);//Send RTP Packets  Fwrite (sendbuf,bytes, 1, stream);  Sleep (1);  t++; }//Send a non-first shard of the nalu that needs to be fragmented, clear 0 Fu header sBit, if the Shard is the last shard of the Nalu, the e-bit of the FU header (k==t)//Sends the last Shard, note that the last Shard may be longer than 1400 bytes (when l>1386).  {//Set RTP M bit; the last Shard is currently transmitted when the position is 1 rtp_hdr->marker=1; Set the FU INDICATOR and fill this header in sendbuf[12] Fu_ind = (fu_indicator*) &sendbuf[12];  The address of the sendbuf[12] is assigned to Fu_ind, and the write to Fu_ind is then written to SendBuf; fu_ind->f=n->forbidden_bit;  fu_ind->nri=n->nal_reference_idc>>5;  fu_ind->type=28;  Set the FU header and fill in the header with sendbuf[13] Fu_hdr = (fu_header*) &sendbuf[13];  fu_hdr->r=0;  fu_hdr->s=0;  fu_hdr->type=n->nal_unit_type;  fu_hdr->e=1; nalu_payload=&sendbuf[14];//the same sendbuf[14] address assigned to Nalu_payload memcpy (NALU_PAYLOAD,N-&GT;BUF+T*1400+1,L-1);//  A string that Nalu the last remaining l-1 (minus the Nalu header of a byte) to the beginning of the byte content written to sendbuf[14].       bytes=l-1+14;  Get the length of the sendbuf, the length of the remaining Nalu l-1 plus rtp_header,fu_indicator,fu_header three headers total 14 bytes Send (socket1, sendbuf, Bytes, 0);//Send RTP Packets  Fwrite (sendbuf,bytes, 1, stream);  t++;  Sleep (1);  } else if (t<k&&0!=t) {//Set RTP M bit; rtp_hdr->marker=0; //Set Fu INDICATOR, and fill this header in sendbuf[12] Fu_ind = (fu_indicator*) &sendbuf[12];  The address of the sendbuf[12] is assigned to Fu_ind, and the write to Fu_ind is then written to SendBuf; fu_ind->f=n->forbidden_bit;  fu_ind->nri=n->nal_reference_idc>>5;  fu_ind->type=28;  Set the FU header and fill in the header with sendbuf[13] Fu_hdr = (fu_header*) &sendbuf[13];  fu_hdr->e=0;  fu_hdr->r=0;  fu_hdr->s=0;  fu_hdr->e=0;  fu_hdr->type=n->nal_unit_type; nalu_payload=&sendbuf[14];//the same sendbuf[14] address assigned to Nalu_payload memcpy (nalu_payload,n->buf+t*1400+1,1400);//  The string that starts with the Nalu remaining content of the starting prefix written to sendbuf[14] is removed.                      bytes=1400+14; Get the length of the sendbuf, for the length of the Nalu (except the original NALU header) plus the fixed length of Rtp_header,fu_ind,fu_hdr 14 bytes Send (socket1, sendbuf, Bytes, 0);//Send RTP packet//  Fwrite (sendbuf,bytes, 1, stream);  Sleep (1);  t++;  }}}//usleep (40000);      } freenalu (n);  return 0; } static int FindStartCode2 (unsigned char *buf) {if (buf[0]!=0 | | buf[1]!=0 | | BUF[2]!=1) return 0;  Determine if it is 0x000001, if it returns 1 else return 1; } Static INT FindStartCode3 (unsigned char *buf) {if (buf[0]!=0 | | buf[1]!=0 | | BUF[2]!=0 | |  BUF[3]!=1) return 0;//determine if it is 0x00000001, if return 1 else return 1;   }

2, download VLC;

3, make the following settings:
1> setting W.SDP
A, open Vlc->media->open network stream
b,-->network->rtp://@192.168.1.101:1234
C,-->file->add...w.sdp->play
Here to talk about the SDP file, the SDP file when VLC playback is required files, here is necessary, otherwise it is not playable, W.SDP file is actually just a few words, here I post it out:

M=video 1234 RTP/AVP 96//96 is the dynamic net load model means that the load type is not deterministic, to be determined by other means a=rtpmap:96 H264 a=framerate:15 c=in IP4 192.168.0.30

The above 1234 and 192.168.1.101 are RTP ports and IP

2〉 Click the VLC play button
3〉 the server that is sent by the RTP package that runs the 264 file again
4〉 a moment to see VLC playing video.

Reference:

1,VLC playback of. 264 files sent by RTP packaging

http://blog.csdn.net/liuzongming1988/article/details/8292455

Go VLC plays the. 264 file sent by RTP package

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.