Prior to the introduction of their own direct use of RTP to send and receive H.264 data, so that there is a problem is the RTP protocol parameters need to be a bit of their own to fill, so it is not conducive to send or convenient to receive. The Jrtplib library just solves this problem, and it also provides a lot of RTCP information query interface, so it is convenient to realize real-time flow control.
In this article, we will introduce h264 through the Jrtplib library to achieve real-time delivery and reception. Sent by the sender, according to the coding habit, we are accustomed to the entire frame of data to be encoded on a single frame of data sent. Similar to this, at the receiving end, we also like the whole frame of the data received complete before decoding and so on processing. However, this poses a problem, our network Maximum transmission unit Mut is generally 1400 bytes, and we do H.264 data encoding, many data frames will be larger than 1400 frames, so need to separate several packets to send, in the reception, the need to separate packets to synthesize a data frame.
Indicate:
The following code is the simplest program written on my computer.
Send End ip:192.168.0.5
Receiving End ip:192.168.0.6
Send port: 6666
Receive Port: 6664
Note Some points:
(1) Jrtplib cannot use cardinality ports and cardinality ports are used to establish RTCP
(2) The default mut for Jrtplib settings is 1400, but the actual packet data can not be sent 1400 bytes, because it also has TCP header data
Receive.c
/*============================================================================= * FileName:receive.cpp * Desc:reveive H.264 from RTP server * Author:licaibiao * lastchange:2017-04-22 * ===================== ========================================================*/#include <jrtplib3/rtpsession.h> #include < jrtplib3/rtpudpv4transmitter.h> #include <jrtplib3/rtpipv4address.h> #include <jrtplib3/ rtpsessionparams.h> #include <jrtplib3/rtperrors.h> #include <jrtplib3/rtplibraryversion.h> #include <jrtplib3/rtppacket.h> #include <stdlib.h> #include <stdio.h> #include <iostream> #include
<string> using namespace Jrtplib; void checkerror (int rtperr) {if (Rtperr < 0) {std::cout << "ERROR:" << rtpgeterrorstring (Rtperr)
;< Std::endl;
Exit (-1);
int main (void) {rtpsession sess;
uint16_t portbase = 6664;
int status;
bool done = false; Rtpudpv4transmissIonparams Transparams;
Rtpsessionparams Sessparams; Sessparams.
Setowntimestampunit (1.0/10.0); Sessparams.
Setacceptownpackets (TRUE); Transparams.
Setportbase (portbase); Status = Sess.
Create (Sessparams,&transparams);
CheckError (status); Sess.
Begindataaccess ();
Rtptime delay (0.001);
Rtptime starttime = Rtptime::currenttime ();
FILE *FD;
size_t Len;
uint8_t *loaddata;
Rtppacket *pack;
uint8_t buff[1024*100] = {0};
int pos = 0;
FD = fopen ("./test_recv.h264", "wb+"); while (!done) {status = Sess.
Poll ();
CheckError (status); if (Sess. Gotofirstsourcewithdata ()) {do {a while (pack = Sess.
Getnextpacket ())!= NULL) {loaddata = Pack->getpayloaddata ();
Len = Pack->getpayloadlength (); if (pack->getpayloadtype () = =)//h264 {if (Pack->hasmarker ())//The last packet {memcpy (
&buff[pos],loaddata,len);
Fwrite (Buff, 1, Pos+len, FD);
pos = 0;
} else {memcpy (&buff[pos],loaddata,len);
pos = pos + len; }}else {printf ("!!! Getpayloadtype =%d!!!!
\ n ", Pack->getpayloadtype ()); } sess.
Deletepacket (Pack); } while (Sess.
Gotonextsourcewithdata ());
} rtptime::wait (delay);
Rtptime t = rtptime::currenttime ();
T-= starttime;
if (T > rtptime (40.0)) done = true;
} fclose (FD); Sess.
Enddataaccess ();
Delay = rtptime (10.0); Sess.
Byedestroy (delay,0,0);
return 0;
}
Send-side program sender
/*============================================================================= * FileName:sender.cpp * Desc:sending H.264 data to client * Author:licaibiao * lastchange:2017-04-22 * ==================== =========================================================*/#include <jrtplib3/rtpsession.h> #include < jrtplib3/rtpudpv4transmitter.h> #include <jrtplib3/rtpipv4address.h> #include <jrtplib3/ rtpsessionparams.h> #include <jrtplib3/rtperrors.h> #include <jrtplib3/rtplibraryversion.h> #include
<stdlib.h> #include <stdio.h> #include <iostream> #include <string> using namespace jrtplib; #define MAXLEN (rtp_defaultpacketsize-100) void checkerror (int rtperr) {if (Rtperr < 0) {std::cout << "Erro
R: "<< rtpgeterrorstring (rtperr) << Std::endl;
Exit (-1);
} class Myrtpsession:public rtpsession{public:myrtpsession (void); ~myrtpsession (VoiD);
void Sendh264nalu (rtpsession* sess,uint8_t* m_h264buf,int buflen);
Protected:};
Myrtpsession::myrtpsession (void) {} myrtpsession::~myrtpsession (void) {} int main (void) {int i;
int num;
int status;
Rtpsession Sess;
Myrtpsession Sender;
uint16_t portbase = 6666;
uint16_t destport = 6664;
uint8_t destip[]={192,168,0,6};
Rtpudpv4transmissionparams Transparams;
Rtpsessionparams Sessparams; /* Set h264 param * * sessparams. SETUSEPREDEFINEDSSRC (TRUE); Set up to use predefined ssrc sessparams. Setowntimestampunit (1.0/9000.0); /* Set Sampling interval * * sessparams. Setacceptownpackets (TRUE); Receive the packet transparams that you sent.
Setportbase (portbase); Status = Sess.
Create (Sessparams,&transparams);
CheckError (status);
Rtpipv4address addr (destip,destport); Status = Sess.
Adddestination (addr);
CheckError (status); Sess. Setdefaulttimestampincrement (3600);/* Set Timestamp increase interval * * Sess.
Setdefaultpayloadtype (96); Sess. SetdefaultmaRK (TRUE);
FILE *FD;
int pos = 0;
int header_flag = 0;
uint8_t buff[1024*100] = {0};
FD = fopen ("./test.h264", "RB");
Fread (Buff, 1, 4, FD);
if ((buff[0]==0) && (buff[1]==0) && (buff[2]==0) && (buff[3]==1)) {header_flag = 1;
pos = 4;
}else{header_flag = 0;
pos = 3;
while ((Feof (FD) ==0)) {buff[pos++] = fgetc (FD); if (Header_flag = 1) {//00 if (buff[pos-1]==1) && (buff[pos-2]==0) && (buff[pos-3]==0) &A mp;& (buff[pos-4]==0)) {sender.
Sendh264nalu (&sess, buff,pos-4);
Buff[0] = 0x00;
BUFF[1] = 0x00;
BUFF[2] = 0x00;
BUFF[3] = 0x01;
pos = 4;
Rtptime::wait (0.03);
} else{if ((buff[pos-1]==1) && (buff[pos-2]==0) && (buff[pos-3]==0)) { Sender. Sendh264nalu (&sess, Buff, pos-3);
Buff[0] = 0x00;
BUFF[1] = 0x00;
BUFF[3] = 0x01;
pos = 3;
Rtptime::wait (0.03); }} if (pos!= 0) {sender.
Sendh264nalu (&sess,buff,pos);
} fclose (FD);
printf ("End of the read\n"); Sess.
Byedestroy (Rtptime (10,0), 0,0);
return 0;
}
In the above code, the implementation of the void Sendh264nalu (rtpsession* sess,uint8_t* m_h264buf,int buflen) function is removed
The complete code can be downloaded here: Linux uses Jrtplib to send and receive H.264 video files