Fixed bugs for debug session may 4 2012.

This commit is contained in:
Thulinma 2012-05-04 14:28:01 +02:00
parent ecbcf438de
commit 3ebfe1b693
9 changed files with 56 additions and 43 deletions

View file

@ -126,8 +126,10 @@ namespace Buffer{
lastPacketTime = now; lastPacketTime = now;
prevPacketTime = currPacketTime; prevPacketTime = currPacketTime;
currPacketTime = thisStream->getStream()->getTime(); currPacketTime = thisStream->getStream()->getTime();
thisStream->dropWriteLock(true);
}else{
thisStream->dropWriteLock(false);
} }
thisStream->dropWriteLock();
}else{ }else{
if (((currPacketTime - prevPacketTime) - (now - lastPacketTime)) > 999){ if (((currPacketTime - prevPacketTime) - (now - lastPacketTime)) > 999){
usleep(999000); usleep(999000);
@ -151,8 +153,10 @@ namespace Buffer{
thisStream->getWriteLock(); thisStream->getWriteLock();
if (thisStream->getStream()->parsePacket(inBuffer)){ if (thisStream->getStream()->parsePacket(inBuffer)){
thisStream->getStream()->outPacket(0); thisStream->getStream()->outPacket(0);
thisStream->dropWriteLock(true);
}else{
thisStream->dropWriteLock(false);
} }
thisStream->dropWriteLock();
} }
}else{ }else{
usleep(1000000); usleep(1000000);
@ -177,27 +181,19 @@ namespace Buffer{
return 1; return 1;
} }
std::string name = argv[1]; std::string name = argv[1];
bool ip_waiting = false;
std::string waiting_ip;
if (argc >= 4){
waiting_ip += argv[2];
ip_waiting = true;
}
SS = Socket::makeStream(name); SS = Socket::makeStream(name);
thisStream = Stream::get(); thisStream = Stream::get();
thisStream->setName(name); thisStream->setName(name);
if (ip_waiting){
thisStream->setWaitingIP(waiting_ip);
}
Socket::Connection incoming; Socket::Connection incoming;
Socket::Connection std_input(fileno(stdin)); Socket::Connection std_input(fileno(stdin));
tthread::thread StatsThread = tthread::thread(handleStats, 0); tthread::thread StatsThread = tthread::thread(handleStats, 0);
tthread::thread * StdinThread = 0; tthread::thread * StdinThread = 0;
if (!ip_waiting){ if (argc < 3){
StdinThread = new tthread::thread(handleStdin, 0); StdinThread = new tthread::thread(handleStdin, 0);
}else{ }else{
thisStream->setWaitingIP(argv[2]);
StdinThread = new tthread::thread(handlePushin, 0); StdinThread = new tthread::thread(handlePushin, 0);
} }

View file

@ -87,6 +87,7 @@ bool Buffer::Stream::checkWaitingIP(std::string ip){
if (ip == waiting_ip || ip == "::ffff:"+waiting_ip){ if (ip == waiting_ip || ip == "::ffff:"+waiting_ip){
return true; return true;
}else{ }else{
std::cout << ip << " != " << waiting_ip << std::endl;
return false; return false;
} }
} }
@ -165,12 +166,12 @@ void Buffer::Stream::getWriteLock(){
} }
/// Drops a previously gotten write lock. /// Drops a previously gotten write lock.
void Buffer::Stream::dropWriteLock(){ void Buffer::Stream::dropWriteLock(bool newpackets_available){
rw_mutex.lock(); rw_mutex.lock();
writers--; writers--;
rw_mutex.unlock(); rw_mutex.unlock();
rw_change.notify_all(); rw_change.notify_all();
moreData.notify_all(); if (newpackets_available){moreData.notify_all();}
} }
/// Blocks until reading is safe. /// Blocks until reading is safe.

View file

@ -34,7 +34,7 @@ namespace Buffer{
/// Blocks until writing is safe. /// Blocks until writing is safe.
void getWriteLock(); void getWriteLock();
/// Drops a previously gotten write lock. /// Drops a previously gotten write lock.
void dropWriteLock(); void dropWriteLock(bool newpackets_available);
/// Blocks until reading is safe. /// Blocks until reading is safe.
void getReadLock(); void getReadLock();
/// Drops a previously gotten read lock. /// Drops a previously gotten read lock.

View file

@ -45,10 +45,10 @@ int Connector_RTMP::Connector_RTMP(Socket::Connection conn){
//first timestamp set //first timestamp set
RTMPStream::firsttime = RTMPStream::getNowMS(); RTMPStream::firsttime = RTMPStream::getNowMS();
while (Socket.connected() && (RTMPStream::handshake_in.size() < 1537)){ RTMPStream::handshake_in.reserve(1537);
Socket.read(RTMPStream::handshake_in); Socket.read((char*)RTMPStream::handshake_in.c_str(), 1537);
}
RTMPStream::rec_cnt += 1537; RTMPStream::rec_cnt += 1537;
if (RTMPStream::doHandshake()){ if (RTMPStream::doHandshake()){
Socket.write(RTMPStream::handshake_out); Socket.write(RTMPStream::handshake_out);
Socket.read((char*)RTMPStream::handshake_in.c_str(), 1536); Socket.read((char*)RTMPStream::handshake_in.c_str(), 1536);
@ -64,9 +64,10 @@ int Connector_RTMP::Connector_RTMP(Socket::Connection conn){
} }
unsigned int lastStats = 0; unsigned int lastStats = 0;
conn.setBlocking(false);
while (Socket.connected()){ while (Socket.connected()){
sleep(10000);//sleep 10ms to prevent high CPU usage usleep(10000);//sleep 10ms to prevent high CPU usage
if (Socket.spool()){ if (Socket.spool()){
parseChunk(Socket.Received()); parseChunk(Socket.Received());
} }
@ -309,9 +310,11 @@ void Connector_RTMP::sendCommand(AMF::Object & amfreply, int messagetype, int st
}//sendCommand }//sendCommand
void Connector_RTMP::parseAMFCommand(AMF::Object & amfdata, int messagetype, int stream_id){ void Connector_RTMP::parseAMFCommand(AMF::Object & amfdata, int messagetype, int stream_id){
bool parsed = false;
#if DEBUG >= 4 #if DEBUG >= 4
amfdata.Print(); fprintf(stderr, "Received command: %s\n", amfdata.Print().c_str());
#endif
#if DEBUG >= 3
fprintf(stderr, "AMF0 command: %s\n", amfdata.getContentP(0)->StrValue().c_str());
#endif #endif
if (amfdata.getContentP(0)->StrValue() == "connect"){ if (amfdata.getContentP(0)->StrValue() == "connect"){
double objencoding = 0; double objencoding = 0;
@ -358,12 +361,12 @@ void Connector_RTMP::parseAMFCommand(AMF::Object & amfdata, int messagetype, int
#endif #endif
sendCommand(amfreply, messagetype, stream_id); sendCommand(amfreply, messagetype, stream_id);
//send onBWDone packet - no clue what it is, but real server sends it... //send onBWDone packet - no clue what it is, but real server sends it...
amfreply = AMF::Object("container", AMF::AMF0_DDV_CONTAINER); //amfreply = AMF::Object("container", AMF::AMF0_DDV_CONTAINER);
amfreply.addContent(AMF::Object("", "onBWDone"));//result //amfreply.addContent(AMF::Object("", "onBWDone"));//result
amfreply.addContent(amfdata.getContent(1));//same transaction ID //amfreply.addContent(amfdata.getContent(1));//same transaction ID
amfreply.addContent(AMF::Object("", (double)0, AMF::AMF0_NULL));//null //amfreply.addContent(AMF::Object("", (double)0, AMF::AMF0_NULL));//null
sendCommand(amfreply, messagetype, stream_id); //sendCommand(amfreply, messagetype, stream_id);
parsed = true; return;
}//connect }//connect
if (amfdata.getContentP(0)->StrValue() == "createStream"){ if (amfdata.getContentP(0)->StrValue() == "createStream"){
//send a _result reply //send a _result reply
@ -377,10 +380,11 @@ void Connector_RTMP::parseAMFCommand(AMF::Object & amfdata, int messagetype, int
#endif #endif
sendCommand(amfreply, messagetype, stream_id); sendCommand(amfreply, messagetype, stream_id);
Socket.write(RTMPStream::SendUSR(0, 1));//send UCM StreamBegin (0), stream 1 Socket.write(RTMPStream::SendUSR(0, 1));//send UCM StreamBegin (0), stream 1
parsed = true; return;
}//createStream }//createStream
if ((amfdata.getContentP(0)->StrValue() == "closeStream") || (amfdata.getContentP(0)->StrValue() == "deleteStream")){ if ((amfdata.getContentP(0)->StrValue() == "closeStream") || (amfdata.getContentP(0)->StrValue() == "deleteStream")){
if (SS.connected()){SS.close();} if (SS.connected()){SS.close();}
return;
} }
if ((amfdata.getContentP(0)->StrValue() == "getStreamLength") || (amfdata.getContentP(0)->StrValue() == "getMovLen")){ if ((amfdata.getContentP(0)->StrValue() == "getStreamLength") || (amfdata.getContentP(0)->StrValue() == "getMovLen")){
//send a _result reply //send a _result reply
@ -393,7 +397,7 @@ void Connector_RTMP::parseAMFCommand(AMF::Object & amfdata, int messagetype, int
amfreply.Print(); amfreply.Print();
#endif #endif
sendCommand(amfreply, messagetype, stream_id); sendCommand(amfreply, messagetype, stream_id);
parsed = true; return;
}//getStreamLength }//getStreamLength
if ((amfdata.getContentP(0)->StrValue() == "publish")){ if ((amfdata.getContentP(0)->StrValue() == "publish")){
if (amfdata.getContentP(3)){ if (amfdata.getContentP(3)){
@ -437,7 +441,7 @@ void Connector_RTMP::parseAMFCommand(AMF::Object & amfdata, int messagetype, int
amfreply.Print(); amfreply.Print();
#endif #endif
sendCommand(amfreply, messagetype, stream_id); sendCommand(amfreply, messagetype, stream_id);
parsed = true; return;
}//getStreamLength }//getStreamLength
if (amfdata.getContentP(0)->StrValue() == "checkBandwidth"){ if (amfdata.getContentP(0)->StrValue() == "checkBandwidth"){
//send a _result reply //send a _result reply
@ -450,7 +454,7 @@ void Connector_RTMP::parseAMFCommand(AMF::Object & amfdata, int messagetype, int
amfreply.Print(); amfreply.Print();
#endif #endif
sendCommand(amfreply, messagetype, stream_id); sendCommand(amfreply, messagetype, stream_id);
parsed = true; return;
}//checkBandwidth }//checkBandwidth
if ((amfdata.getContentP(0)->StrValue() == "play") || (amfdata.getContentP(0)->StrValue() == "play2")){ if ((amfdata.getContentP(0)->StrValue() == "play") || (amfdata.getContentP(0)->StrValue() == "play2")){
//send streambegin //send streambegin
@ -488,16 +492,12 @@ void Connector_RTMP::parseAMFCommand(AMF::Object & amfdata, int messagetype, int
RTMPStream::chunk_snd_max = 102400;//100KiB RTMPStream::chunk_snd_max = 102400;//100KiB
Socket.write(RTMPStream::SendCTL(1, RTMPStream::chunk_snd_max));//send chunk size max (msg 1) Socket.write(RTMPStream::SendCTL(1, RTMPStream::chunk_snd_max));//send chunk size max (msg 1)
Connector_RTMP::ready4data = true;//start sending video data! Connector_RTMP::ready4data = true;//start sending video data!
parsed = true; return;
}//createStream }//createStream
#if DEBUG >= 3
fprintf(stderr, "AMF0 command: %s\n", amfdata.getContentP(0)->StrValue().c_str()); #if DEBUG >= 2
fprintf(stderr, "AMF0 command not processed! :(\n");
#endif #endif
if (!parsed){
#if DEBUG >= 2
fprintf(stderr, "AMF0 command not processed! :(\n");
#endif
}
}//parseAMFCommand }//parseAMFCommand

View file

@ -1,4 +1,4 @@
SRC = main.cpp ../../util/amf.cpp ../../util/rtmpchunks.cpp ../../util/crypto.cpp ../../util/flv_tag.cpp ../../util/socket.cpp SRC = main.cpp ../../util/amf.cpp ../../util/rtmpchunks.cpp ../../util/crypto.cpp ../../util/flv_tag.cpp ../../util/socket.cpp ../../util/dtsc.cpp
OBJ = $(SRC:.cpp=.o) OBJ = $(SRC:.cpp=.o)
OUT = RTMP_Parser OUT = RTMP_Parser
INCLUDES = INCLUDES =

View file

@ -14,6 +14,7 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <string> #include <string>
#include <iostream>
#include "../../util/flv_tag.h" #include "../../util/flv_tag.h"
#include "../../util/amf.h" #include "../../util/amf.h"
#include "../../util/rtmpchunks.h" #include "../../util/rtmpchunks.h"
@ -149,10 +150,10 @@ int main(int argc, char ** argv){
next.data = next.data.substr(1); next.data = next.data.substr(1);
if (soort == 0){ if (soort == 0){
amfdata = AMF::parse(next.data); amfdata = AMF::parse(next.data);
amfdata.Print(); std::cerr << amfdata.Print() << std::endl;
}else{ }else{
amf3data = AMF::parse3(next.data); amf3data = AMF::parse3(next.data);
amf3data.Print(); std::cerr << amf3data.Print() << std::endl;
} }
} break; } break;
case 18:{ case 18:{
@ -170,7 +171,7 @@ int main(int argc, char ** argv){
case 20:{//AMF0 command message case 20:{//AMF0 command message
fprintf(stderr, "Received AFM0 command message:\n"); fprintf(stderr, "Received AFM0 command message:\n");
amfdata = AMF::parse(next.data); amfdata = AMF::parse(next.data);
amfdata.Print(); std::cerr << amfdata.Print() << std::endl;
} break; } break;
case 22: case 22:
fprintf(stderr, "Received aggregate message\n"); fprintf(stderr, "Received aggregate message\n");

View file

@ -102,6 +102,8 @@ bool DTSC::Stream::hasAudio(){
/// Returns a packed DTSC packet, ready to sent over the network. /// Returns a packed DTSC packet, ready to sent over the network.
std::string & DTSC::Stream::outPacket(unsigned int num){ std::string & DTSC::Stream::outPacket(unsigned int num){
static std::string emptystring;
if (num >= buffers.size()) return emptystring;
buffers[num].Pack(true); buffers[num].Pack(true);
return buffers[num].packed; return buffers[num].packed;
} }

View file

@ -40,6 +40,18 @@ Socket::Connection::Connection(){
Blocking = false; Blocking = false;
}//Socket::Connection basic constructor }//Socket::Connection basic constructor
/// Set this socket to be blocking (true) or nonblocking (false).
void Socket::Connection::setBlocking(bool blocking){
int flags = fcntl(sock, F_GETFL, 0);
if (!blocking){
flags |= O_NONBLOCK;
}else{
flags &= !O_NONBLOCK;
}
fcntl(sock, F_SETFL, flags);
}
/// Close connection. The internal socket is closed and then set to -1. /// Close connection. The internal socket is closed and then set to -1.
void Socket::Connection::close(){ void Socket::Connection::close(){
#if DEBUG >= 6 #if DEBUG >= 6

View file

@ -33,6 +33,7 @@ namespace Socket{
Connection(int sockNo); ///< Create a new base socket. Connection(int sockNo); ///< Create a new base socket.
Connection(std::string hostname, int port, bool nonblock); ///< Create a new TCP socket. Connection(std::string hostname, int port, bool nonblock); ///< Create a new TCP socket.
Connection(std::string adres, bool nonblock = false); ///< Create a new Unix Socket. Connection(std::string adres, bool nonblock = false); ///< Create a new Unix Socket.
void setBlocking(bool blocking); ///< Set this socket to be blocking (true) or nonblocking (false).
bool canRead(); ///< Calls poll() on the socket, checking if data is available. bool canRead(); ///< Calls poll() on the socket, checking if data is available.
bool canWrite(); ///< Calls poll() on the socket, checking if data can be written. bool canWrite(); ///< Calls poll() on the socket, checking if data can be written.
signed int ready(); ///< Returns the ready-state for this socket. signed int ready(); ///< Returns the ready-state for this socket.