Various RTMP improvements.
This commit is contained in:
parent
60929d5014
commit
8c69afe18a
2 changed files with 20 additions and 15 deletions
|
@ -25,9 +25,9 @@ unsigned int RTMPStream::snd_cnt = 0;
|
||||||
timeval RTMPStream::lastrec;
|
timeval RTMPStream::lastrec;
|
||||||
|
|
||||||
/// Holds the last sent chunk for every msg_id.
|
/// Holds the last sent chunk for every msg_id.
|
||||||
std::map<unsigned int, RTMPStream::Chunk> RTMPStream::Chunk::lastsend;
|
std::map<unsigned int, RTMPStream::Chunk> RTMPStream::lastsend;
|
||||||
/// Holds the last received chunk for every msg_id.
|
/// Holds the last received chunk for every msg_id.
|
||||||
std::map<unsigned int, RTMPStream::Chunk> RTMPStream::Chunk::lastrecv;
|
std::map<unsigned int, RTMPStream::Chunk> RTMPStream::lastrecv;
|
||||||
|
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/dh.h>
|
#include <openssl/dh.h>
|
||||||
|
@ -274,10 +274,11 @@ bool ValidateClientScheme(uint8_t * pBuffer, uint8_t scheme){
|
||||||
std::string & RTMPStream::Chunk::Pack(){
|
std::string & RTMPStream::Chunk::Pack(){
|
||||||
static std::string output;
|
static std::string output;
|
||||||
output.clear();
|
output.clear();
|
||||||
|
bool allow_short = lastsend.count(cs_id);
|
||||||
RTMPStream::Chunk prev = lastsend[cs_id];
|
RTMPStream::Chunk prev = lastsend[cs_id];
|
||||||
unsigned int tmpi;
|
unsigned int tmpi;
|
||||||
unsigned char chtype = 0x00;
|
unsigned char chtype = 0x00;
|
||||||
if ((prev.msg_type_id > 0) && (prev.cs_id == cs_id)){
|
if (allow_short && (prev.cs_id == cs_id)){
|
||||||
if (msg_stream_id == prev.msg_stream_id){
|
if (msg_stream_id == prev.msg_stream_id){
|
||||||
chtype = 0x40; //do not send msg_stream_id
|
chtype = 0x40; //do not send msg_stream_id
|
||||||
if (len == prev.len){
|
if (len == prev.len){
|
||||||
|
@ -427,12 +428,12 @@ std::string & RTMPStream::SendMedia(FLV::Tag & tag){
|
||||||
//Adobe, if you're ever reading this... wtf? Seriously.
|
//Adobe, if you're ever reading this... wtf? Seriously.
|
||||||
ch.cs_id = 4;//((unsigned char)tag.data[0]);
|
ch.cs_id = 4;//((unsigned char)tag.data[0]);
|
||||||
ch.timestamp = tag.tagTime();
|
ch.timestamp = tag.tagTime();
|
||||||
ch.len = tag.len - 15;
|
|
||||||
ch.real_len = tag.len - 15;
|
|
||||||
ch.len_left = 0;
|
ch.len_left = 0;
|
||||||
ch.msg_type_id = (unsigned char)tag.data[0];
|
ch.msg_type_id = (unsigned char)tag.data[0];
|
||||||
ch.msg_stream_id = 1;
|
ch.msg_stream_id = 1;
|
||||||
ch.data = std::string(tag.data + 11, (size_t)(tag.len - 15));
|
ch.data = std::string(tag.data + 11, (size_t)(tag.len - 15));
|
||||||
|
ch.len = ch.data.size();
|
||||||
|
ch.real_len = ch.len;
|
||||||
return ch.Pack();
|
return ch.Pack();
|
||||||
} //SendMedia
|
} //SendMedia
|
||||||
|
|
||||||
|
@ -532,6 +533,7 @@ bool RTMPStream::Chunk::Parse(std::string & indata){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool allow_short = lastrecv.count(cs_id);
|
||||||
RTMPStream::Chunk prev = lastrecv[cs_id];
|
RTMPStream::Chunk prev = lastrecv[cs_id];
|
||||||
|
|
||||||
//process the rest of the header, for each chunk type
|
//process the rest of the header, for each chunk type
|
||||||
|
@ -554,7 +556,7 @@ bool RTMPStream::Chunk::Parse(std::string & indata){
|
||||||
break;
|
break;
|
||||||
case 0x40:
|
case 0x40:
|
||||||
if (indata.size() < i + 7) return false; //can't read whole header
|
if (indata.size() < i + 7) return false; //can't read whole header
|
||||||
if (prev.msg_type_id == 0){
|
if (!allow_short){
|
||||||
DEBUG_MSG(DLVL_WARN, "Warning: Header type 0x40 with no valid previous chunk!");
|
DEBUG_MSG(DLVL_WARN, "Warning: Header type 0x40 with no valid previous chunk!");
|
||||||
}
|
}
|
||||||
timestamp = indata[i++ ] * 256 * 256;
|
timestamp = indata[i++ ] * 256 * 256;
|
||||||
|
@ -572,7 +574,7 @@ bool RTMPStream::Chunk::Parse(std::string & indata){
|
||||||
break;
|
break;
|
||||||
case 0x80:
|
case 0x80:
|
||||||
if (indata.size() < i + 3) return false; //can't read whole header
|
if (indata.size() < i + 3) return false; //can't read whole header
|
||||||
if (prev.msg_type_id == 0){
|
if (!allow_short){
|
||||||
DEBUG_MSG(DLVL_WARN, "Warning: Header type 0x80 with no valid previous chunk!");
|
DEBUG_MSG(DLVL_WARN, "Warning: Header type 0x80 with no valid previous chunk!");
|
||||||
}
|
}
|
||||||
timestamp = indata[i++ ] * 256 * 256;
|
timestamp = indata[i++ ] * 256 * 256;
|
||||||
|
@ -587,7 +589,7 @@ bool RTMPStream::Chunk::Parse(std::string & indata){
|
||||||
msg_stream_id = prev.msg_stream_id;
|
msg_stream_id = prev.msg_stream_id;
|
||||||
break;
|
break;
|
||||||
case 0xC0:
|
case 0xC0:
|
||||||
if (prev.msg_type_id == 0){
|
if (!allow_short){
|
||||||
DEBUG_MSG(DLVL_WARN, "Warning: Header type 0xC0 with no valid previous chunk!");
|
DEBUG_MSG(DLVL_WARN, "Warning: Header type 0xC0 with no valid previous chunk!");
|
||||||
}
|
}
|
||||||
timestamp = prev.timestamp;
|
timestamp = prev.timestamp;
|
||||||
|
@ -806,10 +808,14 @@ bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer){
|
||||||
bool RTMPStream::doHandshake(){
|
bool RTMPStream::doHandshake(){
|
||||||
char Version;
|
char Version;
|
||||||
//Read C0
|
//Read C0
|
||||||
|
if (handshake_in.size() < 1537){
|
||||||
|
DEBUG_MSG(DLVL_FAIL, "Handshake wasn't filled properly (%lu/1537) - aborting!", handshake_in.size());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Version = RTMPStream::handshake_in[0];
|
Version = RTMPStream::handshake_in[0];
|
||||||
uint8_t * Client = (uint8_t *)RTMPStream::handshake_in.c_str() + 1;
|
uint8_t * Client = (uint8_t *)RTMPStream::handshake_in.data() + 1;
|
||||||
RTMPStream::handshake_out.resize(3073);
|
RTMPStream::handshake_out.resize(3073);
|
||||||
uint8_t * Server = (uint8_t *)RTMPStream::handshake_out.c_str() + 1;
|
uint8_t * Server = (uint8_t *)RTMPStream::handshake_out.data() + 1;
|
||||||
RTMPStream::rec_cnt += 1537;
|
RTMPStream::rec_cnt += 1537;
|
||||||
|
|
||||||
//Build S1 Packet
|
//Build S1 Packet
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace RTMPStream {
|
||||||
extern unsigned int snd_cnt; ///< Counter for total data sent, in bytes.
|
extern unsigned int snd_cnt; ///< Counter for total data sent, in bytes.
|
||||||
|
|
||||||
extern timeval lastrec; ///< Timestamp of last time data was received.
|
extern timeval lastrec; ///< Timestamp of last time data was received.
|
||||||
|
|
||||||
/// Holds a single RTMP chunk, either send or receive direction.
|
/// Holds a single RTMP chunk, either send or receive direction.
|
||||||
class Chunk{
|
class Chunk{
|
||||||
public:
|
public:
|
||||||
|
@ -46,13 +46,12 @@ namespace RTMPStream {
|
||||||
bool Parse(std::string & data);
|
bool Parse(std::string & data);
|
||||||
bool Parse(Socket::Buffer & data);
|
bool Parse(Socket::Buffer & data);
|
||||||
std::string & Pack();
|
std::string & Pack();
|
||||||
|
|
||||||
private:
|
|
||||||
static std::map<unsigned int, Chunk> lastsend;
|
|
||||||
static std::map<unsigned int, Chunk> lastrecv;
|
|
||||||
};
|
};
|
||||||
//RTMPStream::Chunk
|
//RTMPStream::Chunk
|
||||||
|
|
||||||
|
extern std::map<unsigned int, Chunk> lastsend;
|
||||||
|
extern std::map<unsigned int, Chunk> lastrecv;
|
||||||
|
|
||||||
std::string & SendChunk(unsigned int cs_id, unsigned char msg_type_id, unsigned int msg_stream_id, std::string data);
|
std::string & SendChunk(unsigned int cs_id, unsigned char msg_type_id, unsigned int msg_stream_id, std::string data);
|
||||||
std::string & SendMedia(unsigned char msg_type_id, unsigned char * data, int len, unsigned int ts);
|
std::string & SendMedia(unsigned char msg_type_id, unsigned char * data, int len, unsigned int ts);
|
||||||
std::string & SendMedia(FLV::Tag & tag);
|
std::string & SendMedia(FLV::Tag & tag);
|
||||||
|
|
Loading…
Add table
Reference in a new issue