WIP for RTSP support (GH-8)
This commit is contained in:
parent
cb51c11149
commit
abb6d27350
1 changed files with 57 additions and 4 deletions
|
@ -55,6 +55,7 @@ int RTSP_Handler( Socket::Connection conn ) {
|
||||||
jrtplib::RTPSessionParams VideoParams;
|
jrtplib::RTPSessionParams VideoParams;
|
||||||
jrtplib::RTPUDPv6TransmissionParams VideoTransParams;
|
jrtplib::RTPUDPv6TransmissionParams VideoTransParams;
|
||||||
std::string PreviousRequest = "";
|
std::string PreviousRequest = "";
|
||||||
|
std::string streamname;
|
||||||
Socket::Connection ss(-1);
|
Socket::Connection ss(-1);
|
||||||
HTTP::Parser HTTP_R, HTTP_S;
|
HTTP::Parser HTTP_R, HTTP_S;
|
||||||
//Some clients appear to expect a single request per connection. Don't know which ones.
|
//Some clients appear to expect a single request per connection. Don't know which ones.
|
||||||
|
@ -102,7 +103,7 @@ int RTSP_Handler( Socket::Connection conn ) {
|
||||||
"t=0 0\r\n" //time the session is active: start-time stop-time; "0 0"=permanent session
|
"t=0 0\r\n" //time the session is active: start-time stop-time; "0 0"=permanent session
|
||||||
"a=recvonly\r\n"//zero or more session attribute lines
|
"a=recvonly\r\n"//zero or more session attribute lines
|
||||||
"m=video 0 RTP/AVP 98\r\n"//media name and transport address: media port proto fmt ...
|
"m=video 0 RTP/AVP 98\r\n"//media name and transport address: media port proto fmt ...
|
||||||
"a=control:rtsp://localhost/fifa/video\r\n"//rfc2326 C.1.1, URL for aggregate control on session level
|
"a=control:" + HTTP_R.url + "\r\n"//rfc2326 C.1.1, URL for aggregate control on session level
|
||||||
"a=rtpmap:98 H264/90000\r\n"//rfc2326 C.1.3, dynamic payload type; see also http://tools.ietf.org/html/rfc1890#section-5
|
"a=rtpmap:98 H264/90000\r\n"//rfc2326 C.1.3, dynamic payload type; see also http://tools.ietf.org/html/rfc1890#section-5
|
||||||
"a=fmtp:98 packetization-mode=0"//codec-specific parameters
|
"a=fmtp:98 packetization-mode=0"//codec-specific parameters
|
||||||
"\r\n\r\n");//m=audio 0 RTP/AAP 96\r\na=control:rtsp://localhost/fifa/audio\r\na=rtpmap:96 mpeg4-generic/16000/2\r\n\r\n");
|
"\r\n\r\n");//m=audio 0 RTP/AAP 96\r\na=control:rtsp://localhost/fifa/audio\r\na=rtpmap:96 mpeg4-generic/16000/2\r\n\r\n");
|
||||||
|
@ -111,6 +112,7 @@ int RTSP_Handler( Socket::Connection conn ) {
|
||||||
conn.write( HTTP_S.BuildResponse( "200", "OK" ) );
|
conn.write( HTTP_S.BuildResponse( "200", "OK" ) );
|
||||||
}
|
}
|
||||||
} else if ( HTTP_R.method == "SETUP" ) {
|
} else if ( HTTP_R.method == "SETUP" ) {
|
||||||
|
bool setup_session = false;//whether a session should be setup or not
|
||||||
std::string temp = HTTP_R.GetHeader("Transport");
|
std::string temp = HTTP_R.GetHeader("Transport");
|
||||||
//Extract the random UTP pair for video data ( RTP/RTCP)
|
//Extract the random UTP pair for video data ( RTP/RTCP)
|
||||||
int ClientRTPLoc = temp.find( "client_port=" ) + 12;
|
int ClientRTPLoc = temp.find( "client_port=" ) + 12;
|
||||||
|
@ -121,6 +123,36 @@ int RTSP_Handler( Socket::Connection conn ) {
|
||||||
fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "459", "Aggregate Operation Not Allowed" ).c_str() );
|
fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "459", "Aggregate Operation Not Allowed" ).c_str() );
|
||||||
conn.write( HTTP_S.BuildResponse( "459", "Aggregate Operation Not Allowed" ) );
|
conn.write( HTTP_S.BuildResponse( "459", "Aggregate Operation Not Allowed" ) );
|
||||||
} else {
|
} else {
|
||||||
|
do{
|
||||||
|
if (!ss.connected()){
|
||||||
|
/// \todo Put stream name-to-file mapping in a separate util file or even class
|
||||||
|
streamname = std::string(HTTP_R.url.c_str());
|
||||||
|
unsigned int slash_pos = streamname.rfind('/');
|
||||||
|
if (slash_pos != std::string::npos) streamname.erase(0, slash_pos);
|
||||||
|
for (std::string::iterator i=streamname.begin(); i != streamname.end(); ++i){
|
||||||
|
if (*i == '?'){
|
||||||
|
streamname.erase(i, streamname.end());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!isalpha(*i) && !isdigit(*i) && *i != '_'){
|
||||||
|
streamname.erase(i);
|
||||||
|
--i;
|
||||||
|
}else{
|
||||||
|
*i = tolower(*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
streamname = "/tmp/shared_socket_" + streamname;
|
||||||
|
ss = Socket::Connection(streamname);
|
||||||
|
if (!ss.connected()){
|
||||||
|
streamname = "";
|
||||||
|
HTTP_R.BuildResponse("404", "Not Found");
|
||||||
|
break; //skip the session below
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setup_session = true;
|
||||||
|
}while(0);
|
||||||
|
}
|
||||||
|
if (setup_session) {
|
||||||
HTTP_S.SetHeader( "CSeq", HTTP_R.GetHeader( "CSeq" ).c_str() );
|
HTTP_S.SetHeader( "CSeq", HTTP_R.GetHeader( "CSeq" ).c_str() );
|
||||||
HTTP_S.SetHeader( "Session", time(NULL) );
|
HTTP_S.SetHeader( "Session", time(NULL) );
|
||||||
/// \todo Add support for audio
|
/// \todo Add support for audio
|
||||||
|
@ -216,13 +248,34 @@ int RTSP_Handler( Socket::Connection conn ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( PlayVideo ) {
|
if( PlayVideo ) {
|
||||||
/// \todo Select correct source. This should become the DTSC::DTMI or the DTSC::Stream, whatever seems more natural.
|
bool no_data_ignore = false;
|
||||||
std::string VideoBuf = ReadNALU( );
|
std::string VideoBuf;
|
||||||
if( VideoBuf == "" ) {
|
ss.canRead();
|
||||||
|
switch (ss.ready()) {
|
||||||
|
case -1:
|
||||||
|
std::cerr << "Buffer socket is disconnected\n";
|
||||||
|
break;
|
||||||
|
case 0://not ready
|
||||||
|
no_data_ignore = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
///\todo Make it work!
|
||||||
|
DTSC::Stream ds;
|
||||||
|
ss.spool();
|
||||||
|
if (ds.parsePacket(ss.Received())){
|
||||||
|
VideoBuf = ds.lastData();
|
||||||
|
}else{
|
||||||
|
std::cerr << "Failed to parse packet" << std::endl;
|
||||||
|
no_data_ignore = true;//perhaps corrupt?
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(no_data_ignore){}else if( VideoBuf == "" ) {
|
||||||
//videobuffer is empty, no more data.
|
//videobuffer is empty, no more data.
|
||||||
jrtplib::RTPTime delay = jrtplib::RTPTime(10.0);
|
jrtplib::RTPTime delay = jrtplib::RTPTime(10.0);
|
||||||
VideoSession.BYEDestroy(delay,"Out of data",11);
|
VideoSession.BYEDestroy(delay,"Out of data",11);
|
||||||
conn.close();
|
conn.close();
|
||||||
|
std::cerr << "Buffer empty - closing connection" << std::endl;
|
||||||
} else {
|
} else {
|
||||||
//Send a single NALU (H264 block) here.
|
//Send a single NALU (H264 block) here.
|
||||||
VideoSession.SendPacket( VideoBuf.c_str(), VideoBuf.size(), 98, false, ( 1.0 / 29.917 ) * 90000 );
|
VideoSession.SendPacket( VideoBuf.c_str(), VideoBuf.size(), 98, false, ( 1.0 / 29.917 ) * 90000 );
|
||||||
|
|
Loading…
Add table
Reference in a new issue