diff --git a/src/buffer/buffer.cpp b/src/buffer/buffer.cpp index c847d412..d45298a9 100644 --- a/src/buffer/buffer.cpp +++ b/src/buffer/buffer.cpp @@ -50,6 +50,7 @@ namespace Buffer { ///\brief A function running in a thread to handle a new user connection. ///\param v_usr The user that is connected. void handleUser(void * v_usr){ + std::set newSelect; user * usr = (user*)v_usr; thisStream->addUser(usr); #if DEBUG >= 5 @@ -65,7 +66,7 @@ namespace Buffer { while (usr->S.connected()){ Util::sleep(5); //sleep 5ms - if ( !usr->myRing->playCount || !usr->Send()){ + if ( !usr->myRing->playCount || !usr->Send(newSelect)){ if (usr->myRing->updated){ Stream::get()->getReadLock(); usr->S.SendNow(Stream::get()->getStream()->metadata.toNetPacked()); @@ -110,21 +111,24 @@ namespace Buffer { thisStream->saveStats(usr->MyStr, usr->tmpStats); break; } + case 't': { + newSelect.clear(); + std::string tmp = usr->S.Received().get().substr(2); + while (tmp != ""){ + newSelect.insert(atoi(tmp.substr(0,tmp.find(' ')).c_str())); + if (tmp.find(' ') != std::string::npos){ + tmp.erase(0,tmp.find(' ')+1); + }else{ + tmp = ""; + } + } + break; + } case 's': { //second-seek unsigned int ms = JSON::Value(usr->S.Received().get().substr(2)).asInt(); usr->myRing->waiting = false; usr->myRing->starved = false; - usr->myRing->b = thisStream->getStream()->msSeek(ms); - if (usr->myRing->playCount > 0){ - usr->myRing->playCount = 0; - } - break; - } - case 'f': { //frame-seek - unsigned int frameno = JSON::Value(usr->S.Received().get().substr(2)).asInt(); - usr->myRing->waiting = false; - usr->myRing->starved = false; - usr->myRing->b = thisStream->getStream()->frameSeek(frameno); + usr->myRing->b = thisStream->getStream()->msSeek(ms, newSelect); if (usr->myRing->playCount > 0){ usr->myRing->playCount = 0; } @@ -176,7 +180,6 @@ namespace Buffer { if (((now - timeDiff) >= lastPacket) || (lastPacket - (now - timeDiff) > 15000)){ thisStream->getWriteLock(); if (thisStream->getStream()->parsePacket(inBuffer)){ - thisStream->getStream()->outPacket(0); lastPacket = thisStream->getStream()->getTime(); if ((now - timeDiff - lastPacket) > 15000 || (now - timeDiff - lastPacket < -15000)){ timeDiff = now - lastPacket; @@ -208,7 +211,6 @@ namespace Buffer { do{ thisStream->getWriteLock(); if (thisStream->getStream()->parsePacket(thisStream->getIPInput().Received())){ - thisStream->getStream()->outPacket(0); thisStream->dropWriteLock(true); packed_parsed = true; }else{ diff --git a/src/buffer/buffer_stream.cpp b/src/buffer/buffer_stream.cpp index 52f941e1..6335fdfb 100644 --- a/src/buffer/buffer_stream.cpp +++ b/src/buffer/buffer_stream.cpp @@ -178,13 +178,6 @@ namespace Buffer { ///\brief Drops a previously obtained write lock. ///\param newPacketsAvailable Whether new packets are available to update the index. void Stream::dropWriteLock(bool newPacketsAvailable){ - if (newPacketsAvailable){ - if (Strm->getPacket(0).isMember("keyframe")){ - stats_mutex.lock(); - Strm->updateHeaders(); - stats_mutex.unlock(); - } - } rw_mutex.lock(); writers--; rw_mutex.unlock(); diff --git a/src/buffer/buffer_user.cpp b/src/buffer/buffer_user.cpp index add7bb64..faac506d 100644 --- a/src/buffer/buffer_user.cpp +++ b/src/buffer/buffer_user.cpp @@ -68,7 +68,7 @@ namespace Buffer { ///\brief Try to send the current buffer. /// ///\return True if the send was succesful, false otherwise. - bool user::Send(){ + bool user::Send(std::set & allowedTracks){ if ( !myRing){ return false; } //no ring! @@ -105,11 +105,11 @@ namespace Buffer { if (doSend(Stream::get()->getStream()->outPacket(myRing->b).c_str(), Stream::get()->getStream()->outPacket(myRing->b).length())){ //switch to next buffer currsend = 0; - if (myRing->b <= 0){ + if (Stream::get()->getStream()->isNewest(myRing->b)){ myRing->waiting = true; return false; } //no next buffer? go in waiting mode. - myRing->b--; + myRing->b = Stream::get()->getStream()->getNext(myRing->b, allowedTracks); if (Stream::get()->getStream()->getPacket(myRing->b).isMember("keyframe") && myRing->playCount > 0){ myRing->playCount--; if ( !myRing->playCount){ diff --git a/src/buffer/buffer_user.h b/src/buffer/buffer_user.h index 7e252a42..0e41ea16 100644 --- a/src/buffer/buffer_user.h +++ b/src/buffer/buffer_user.h @@ -51,6 +51,6 @@ namespace Buffer { /// Has a side effect of dropping the connection if send will never complete. bool doSend(const char * ptr, int len); /// Try to send data to this user. Disconnects if any problems occur. - bool Send(); + bool Send(std::set & allowedTracks); }; } diff --git a/src/connectors/conn_http_dynamic.cpp b/src/connectors/conn_http_dynamic.cpp index 51555bad..24715622 100644 --- a/src/connectors/conn_http_dynamic.cpp +++ b/src/connectors/conn_http_dynamic.cpp @@ -212,10 +212,11 @@ namespace Connector_HTTP { printf("Quality: %s, Seg %d Frag %d\n", Quality.c_str(), Segment, ReqFragment); #endif if (Strm.metadata.isMember("live")){ - int seekable = Strm.canSeekFrame(ReqFragment); + /// \todo Convert to MS seeking + int seekable = -1;//Strm.canSeekFrame(ReqFragment); if (seekable == 0){ // iff the fragment in question is available, check if the next is available too - seekable = Strm.canSeekFrame(ReqFragment + 1); + //seekable = Strm.canSeekFrame(ReqFragment + 1); } if (seekable < 0){ HTTP_S.Clean(); @@ -283,17 +284,17 @@ namespace Connector_HTTP { //fill buffer with init data, if needed. if (Strm.metadata.isMember("audio") && Strm.metadata["audio"].isMember("init")){ tmp.DTSCAudioInit(Strm); - tmp.tagTime(Strm.getPacket(0)["time"].asInt()); + tmp.tagTime(Strm.getPacket()["time"].asInt()); FlashBuf.push_back(std::string(tmp.data, tmp.len)); FlashBufSize += tmp.len; } if (Strm.metadata.isMember("video") && Strm.metadata["video"].isMember("init")){ tmp.DTSCVideoInit(Strm); - tmp.tagTime(Strm.getPacket(0)["time"].asInt()); + tmp.tagTime(Strm.getPacket()["time"].asInt()); FlashBuf.push_back(std::string(tmp.data, tmp.len)); FlashBufSize += tmp.len; } - FlashBufTime = Strm.getPacket(0)["time"].asInt(); + FlashBufTime = Strm.getPacket()["time"].asInt(); } tmp.DTSCLoader(Strm); FlashBuf.push_back(std::string(tmp.data, tmp.len)); diff --git a/src/connectors/conn_http_live.cpp b/src/connectors/conn_http_live.cpp index d9fe2db3..2e44beab 100644 --- a/src/connectors/conn_http_live.cpp +++ b/src/connectors/conn_http_live.cpp @@ -165,7 +165,8 @@ namespace Connector_HTTP { temp = HTTP_R.url.find("_", temp) + 1; int frameCount = atoi(HTTP_R.url.substr(temp, HTTP_R.url.find(".ts", temp) - temp).c_str()); if (Strm.metadata.isMember("live")){ - int seekable = Strm.canSeekFrame(Segment); + /// \todo Update to MS seeking. + int seekable = Strm.canSeekms(Segment); if (seekable < 0){ HTTP_S.Clean(); HTTP_S.SetBody("The requested fragment is no longer kept in memory on the server and cannot be served.\n"); @@ -262,9 +263,9 @@ namespace Connector_HTTP { int PIDno = 0; char * ContCounter = 0; if (Strm.lastType() == DTSC::VIDEO){ - IsKeyFrame = Strm.getPacket(0).isMember("keyframe"); + IsKeyFrame = Strm.getPacket().isMember("keyframe"); if (IsKeyFrame){ - TimeStamp = (Strm.getPacket(0)["time"].asInt() * 27000); + TimeStamp = (Strm.getPacket()["time"].asInt() * 27000); } ToPack.append(avccbox.asAnnexB()); while (Strm.lastData().size()){ @@ -278,13 +279,13 @@ namespace Connector_HTTP { Strm.lastData().erase(0, ThisNaluSize + 4); } } - ToPack.prepend(TS::Packet::getPESVideoLeadIn(0ul, Strm.getPacket(0)["time"].asInt() * 90)); + ToPack.prepend(TS::Packet::getPESVideoLeadIn(0ul, Strm.getPacket()["time"].asInt() * 90)); PIDno = 0x100; ContCounter = &VideoCounter; }else if (Strm.lastType() == DTSC::AUDIO){ ToPack.append(TS::GetAudioHeader(Strm.lastData().size(), Strm.getTrackById(audioTrackID)["init"].asString())); ToPack.append(Strm.lastData()); - ToPack.prepend(TS::Packet::getPESAudioLeadIn(ToPack.bytes(1073741824ul), Strm.getPacket(0)["time"].asInt() * 90)); + ToPack.prepend(TS::Packet::getPESAudioLeadIn(ToPack.bytes(1073741824ul), Strm.getPacket()["time"].asInt() * 90)); PIDno = 0x101; ContCounter = &AudioCounter; } diff --git a/src/connectors/conn_ts.cpp b/src/connectors/conn_ts.cpp index b5c5a48f..8ee56154 100644 --- a/src/connectors/conn_ts.cpp +++ b/src/connectors/conn_ts.cpp @@ -82,9 +82,9 @@ namespace Connector_TS { int PIDno = 0; char * ContCounter = 0; if (Strm.lastType() == DTSC::VIDEO){ - IsKeyFrame = Strm.getPacket(0).isMember("keyframe"); + IsKeyFrame = Strm.getPacket().isMember("keyframe"); if (IsKeyFrame){ - TimeStamp = (Strm.getPacket(0)["time"].asInt() * 27000); + TimeStamp = (Strm.getPacket()["time"].asInt() * 27000); } ToPack.append(avccbox.asAnnexB()); while (Strm.lastData().size()){ @@ -98,13 +98,13 @@ namespace Connector_TS { Strm.lastData().erase(0, ThisNaluSize + 4); } } - ToPack.prepend(TS::Packet::getPESVideoLeadIn(0ul, Strm.getPacket(0)["time"].asInt() * 90)); + ToPack.prepend(TS::Packet::getPESVideoLeadIn(0ul, Strm.getPacket()["time"].asInt() * 90)); PIDno = 0x100; ContCounter = &VideoCounter; }else if (Strm.lastType() == DTSC::AUDIO){ ToPack.append(TS::GetAudioHeader(Strm.lastData().size(), Strm.metadata["audio"]["init"].asString())); ToPack.append(Strm.lastData()); - ToPack.prepend(TS::Packet::getPESAudioLeadIn(ToPack.bytes(1073741824ul), Strm.getPacket(0)["time"].asInt() * 90)); + ToPack.prepend(TS::Packet::getPESAudioLeadIn(ToPack.bytes(1073741824ul), Strm.getPacket()["time"].asInt() * 90)); PIDno = 0x101; ContCounter = &AudioCounter; } diff --git a/src/converters/dtsc2ts.cpp b/src/converters/dtsc2ts.cpp index 97a98a3d..d3fbad1b 100644 --- a/src/converters/dtsc2ts.cpp +++ b/src/converters/dtsc2ts.cpp @@ -63,9 +63,9 @@ namespace Converters { int PIDno = 0; char * ContCounter = 0; if (Strm.lastType() == DTSC::VIDEO){ - IsKeyFrame = Strm.getPacket(0).isMember("keyframe"); + IsKeyFrame = Strm.getPacket().isMember("keyframe"); if (IsKeyFrame){ - TimeStamp = (Strm.getPacket(0)["time"].asInt() * 27000); + TimeStamp = (Strm.getPacket()["time"].asInt() * 27000); } ToPack.append(avccbox.asAnnexB()); while (Strm.lastData().size()){ @@ -79,13 +79,13 @@ namespace Converters { Strm.lastData().erase(0, ThisNaluSize + 4); } } - ToPack.prepend(TS::Packet::getPESVideoLeadIn(0ul, Strm.getPacket(0)["time"].asInt() * 90)); + ToPack.prepend(TS::Packet::getPESVideoLeadIn(0ul, Strm.getPacket()["time"].asInt() * 90)); PIDno = 0x100; ContCounter = &VideoCounter; }else if (Strm.lastType() == DTSC::AUDIO){ ToPack.append(TS::GetAudioHeader(Strm.lastData().size(), Strm.metadata["audio"]["init"].asString())); ToPack.append(Strm.lastData()); - ToPack.prepend(TS::Packet::getPESAudioLeadIn(ToPack.bytes(1073741824ul), Strm.getPacket(0)["time"].asInt() * 90)); + ToPack.prepend(TS::Packet::getPESAudioLeadIn(ToPack.bytes(1073741824ul), Strm.getPacket()["time"].asInt() * 90)); PIDno = 0x101; ContCounter = &AudioCounter; }