Some small DTSC and HTTP library fixes
This commit is contained in:
parent
bf8ddcb300
commit
224e3a3f0d
3 changed files with 95 additions and 17 deletions
26
lib/dtsc.h
26
lib/dtsc.h
|
@ -117,7 +117,7 @@ namespace DTSC {
|
||||||
packType getVersion() const;
|
packType getVersion() const;
|
||||||
void reInit(Socket::Connection & src);
|
void reInit(Socket::Connection & src);
|
||||||
void reInit(const char * data_, unsigned int len, bool noCopy = false);
|
void reInit(const char * data_, unsigned int len, bool noCopy = false);
|
||||||
void genericFill(long long packTime, long long packOffset, long long packTrack, const char * packData, long long packDataSize, long long packBytePos, bool isKeyframe);
|
void genericFill(long long packTime, long long packOffset, long long packTrack, const char * packData, long long packDataSize, uint64_t packBytePos, bool isKeyframe);
|
||||||
void getString(const char * identifier, char *& result, unsigned int & len) const;
|
void getString(const char * identifier, char *& result, unsigned int & len) const;
|
||||||
void getString(const char * identifier, std::string & result) const;
|
void getString(const char * identifier, std::string & result) const;
|
||||||
void getInt(const char * identifier, int & result) const;
|
void getInt(const char * identifier, int & result) const;
|
||||||
|
@ -261,7 +261,7 @@ namespace DTSC {
|
||||||
inline operator bool() const {
|
inline operator bool() const {
|
||||||
return (parts.size() && keySizes.size() && (keySizes.size() == keys.size()));
|
return (parts.size() && keySizes.size() && (keySizes.size() == keys.size()));
|
||||||
}
|
}
|
||||||
void update(long long packTime, long long packOffset, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size = 5000);
|
void update(long long packTime, long long packOffset, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size = 5000);
|
||||||
int getSendLen(bool skipDynamic = false);
|
int getSendLen(bool skipDynamic = false);
|
||||||
void send(Socket::Connection & conn, bool skipDynamic = false);
|
void send(Socket::Connection & conn, bool skipDynamic = false);
|
||||||
void writeTo(char *& p);
|
void writeTo(char *& p);
|
||||||
|
@ -273,7 +273,7 @@ namespace DTSC {
|
||||||
Key & getKey(unsigned int keyNum);
|
Key & getKey(unsigned int keyNum);
|
||||||
Fragment & getFrag(unsigned int fragNum);
|
Fragment & getFrag(unsigned int fragNum);
|
||||||
unsigned int timeToKeynum(unsigned int timestamp);
|
unsigned int timeToKeynum(unsigned int timestamp);
|
||||||
unsigned int timeToFragnum(unsigned int timestamp);
|
uint32_t timeToFragnum(uint64_t timestamp);
|
||||||
void reset();
|
void reset();
|
||||||
void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0);
|
void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0);
|
||||||
void finalize();
|
void finalize();
|
||||||
|
@ -318,9 +318,9 @@ namespace DTSC {
|
||||||
}
|
}
|
||||||
void reinit(const DTSC::Packet & source);
|
void reinit(const DTSC::Packet & source);
|
||||||
void update(DTSC::Packet & pack, unsigned long segment_size = 5000);
|
void update(DTSC::Packet & pack, unsigned long segment_size = 5000);
|
||||||
void updatePosOverride(DTSC::Packet & pack, unsigned long bpos);
|
void updatePosOverride(DTSC::Packet & pack, uint64_t bpos);
|
||||||
void update(JSON::Value & pack, unsigned long segment_size = 5000);
|
void update(JSON::Value & pack, unsigned long segment_size = 5000);
|
||||||
void update(long long packTime, long long packOffset, long long packTrack, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize = 0, unsigned long segment_size = 5000);
|
void update(long long packTime, long long packOffset, long long packTrack, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize = 0, unsigned long segment_size = 5000);
|
||||||
unsigned int getSendLen(bool skipDynamic = false, std::set<unsigned long> selectedTracks = std::set<unsigned long>());
|
unsigned int getSendLen(bool skipDynamic = false, std::set<unsigned long> selectedTracks = std::set<unsigned long>());
|
||||||
void send(Socket::Connection & conn, bool skipDynamic = false, std::set<unsigned long> selectedTracks = std::set<unsigned long>());
|
void send(Socket::Connection & conn, bool skipDynamic = false, std::set<unsigned long> selectedTracks = std::set<unsigned long>());
|
||||||
void writeTo(char * p);
|
void writeTo(char * p);
|
||||||
|
@ -340,6 +340,22 @@ namespace DTSC {
|
||||||
long long int bufferWindow;
|
long long int bufferWindow;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// An iterator helper for easily iterating over the parts in a Fragment.
|
||||||
|
class PartIter {
|
||||||
|
public:
|
||||||
|
PartIter(Track & Trk, Fragment & frag);
|
||||||
|
Part & operator*() const;///< Dereferences into a Value reference.
|
||||||
|
Part* operator->() const;///< Dereferences into a Value reference.
|
||||||
|
operator bool() const;///< True if not done iterating.
|
||||||
|
PartIter & operator++();///<Go to next iteration.
|
||||||
|
private:
|
||||||
|
uint32_t lastKey;
|
||||||
|
uint32_t currInKey;
|
||||||
|
Track * tRef;
|
||||||
|
std::deque<Part>::iterator pIt;
|
||||||
|
std::deque<Key>::iterator kIt;
|
||||||
|
};
|
||||||
|
|
||||||
/// A simple wrapper class that will open a file and allow easy reading/writing of DTSC data from/to it.
|
/// A simple wrapper class that will open a file and allow easy reading/writing of DTSC data from/to it.
|
||||||
class File {
|
class File {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -208,7 +208,7 @@ namespace DTSC {
|
||||||
|
|
||||||
/// Re-initializes this Packet to contain a generic DTSC packet with the given data fields.
|
/// Re-initializes this Packet to contain a generic DTSC packet with the given data fields.
|
||||||
/// When given a NULL pointer, the data is reserved and memset to 0
|
/// When given a NULL pointer, the data is reserved and memset to 0
|
||||||
void Packet::genericFill(long long packTime, long long packOffset, long long packTrack, const char * packData, long long packDataSize, long long packBytePos, bool isKeyframe){
|
void Packet::genericFill(long long packTime, long long packOffset, long long packTrack, const char * packData, long long packDataSize, uint64_t packBytePos, bool isKeyframe){
|
||||||
null();
|
null();
|
||||||
master = true;
|
master = true;
|
||||||
//time and trackID are part of the 20-byte header.
|
//time and trackID are part of the 20-byte header.
|
||||||
|
@ -1122,7 +1122,7 @@ namespace DTSC {
|
||||||
|
|
||||||
///\brief Updates a track and its metadata given new packet properties.
|
///\brief Updates a track and its metadata given new packet properties.
|
||||||
///Will also insert keyframes on non-video tracks, and creates fragments
|
///Will also insert keyframes on non-video tracks, and creates fragments
|
||||||
void Track::update(long long packTime, long long packOffset, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size) {
|
void Track::update(long long packTime, long long packOffset, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size) {
|
||||||
if ((unsigned long long)packTime < lastms) {
|
if ((unsigned long long)packTime < lastms) {
|
||||||
static bool warned = false;
|
static bool warned = false;
|
||||||
if (!warned){
|
if (!warned){
|
||||||
|
@ -1244,7 +1244,7 @@ namespace DTSC {
|
||||||
///\brief Returns a key given its number, or an empty key if the number is out of bounds
|
///\brief Returns a key given its number, or an empty key if the number is out of bounds
|
||||||
Key & Track::getKey(unsigned int keyNum) {
|
Key & Track::getKey(unsigned int keyNum) {
|
||||||
static Key empty;
|
static Key empty;
|
||||||
if (keyNum < keys[0].getNumber()) {
|
if (!keys.size() || keyNum < keys[0].getNumber()) {
|
||||||
return empty;
|
return empty;
|
||||||
}
|
}
|
||||||
if ((keyNum - keys[0].getNumber()) > keys.size()) {
|
if ((keyNum - keys[0].getNumber()) > keys.size()) {
|
||||||
|
@ -1266,11 +1266,13 @@ namespace DTSC {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets indice of the fragment containing timestamp, or last fragment if nowhere.
|
/// Gets indice of the fragment containing timestamp, or last fragment if nowhere.
|
||||||
unsigned int Track::timeToFragnum(unsigned int timestamp){
|
uint32_t Track::timeToFragnum(uint64_t timestamp){
|
||||||
for (unsigned int i = 0; i<fragments.size(); i++){
|
uint32_t i = 0;
|
||||||
if (timestamp <= getKey(fragments[i].getNumber()).getTime() + fragments[i].getDuration()){
|
for (std::deque<Fragment>::iterator it = fragments.begin(); it != fragments.end(); ++it){
|
||||||
|
if (timestamp < getKey(it->getNumber()).getTime() + it->getDuration()){
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
return fragments.size()-1;
|
return fragments.size()-1;
|
||||||
}
|
}
|
||||||
|
@ -1349,7 +1351,7 @@ namespace DTSC {
|
||||||
|
|
||||||
///\brief Updates a meta object given a JSON::Value
|
///\brief Updates a meta object given a JSON::Value
|
||||||
void Meta::update(JSON::Value & pack, unsigned long segment_size) {
|
void Meta::update(JSON::Value & pack, unsigned long segment_size) {
|
||||||
update(pack["time"].asInt(), pack.isMember("offset")?pack["offset"].asInt():0, pack["trackid"].asInt(), pack["data"].asStringRef().size(), pack.isMember("bpos")?pack["bpos"].asInt():-1, pack.isMember("keyframe"), pack.packedSize(), segment_size);
|
update(pack["time"].asInt(), pack.isMember("offset")?pack["offset"].asInt():0, pack["trackid"].asInt(), pack["data"].asStringRef().size(), pack.isMember("bpos")?pack["bpos"].asInt():0, pack.isMember("keyframe"), pack.packedSize(), segment_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Updates a meta object given a DTSC::Packet
|
///\brief Updates a meta object given a DTSC::Packet
|
||||||
|
@ -1357,18 +1359,18 @@ namespace DTSC {
|
||||||
char * data;
|
char * data;
|
||||||
unsigned int dataLen;
|
unsigned int dataLen;
|
||||||
pack.getString("data", data, dataLen);
|
pack.getString("data", data, dataLen);
|
||||||
update(pack.getTime(), pack.hasMember("offset")?pack.getInt("offset"):0, pack.getTrackId(), dataLen, pack.hasMember("bpos")?pack.getInt("bpos"):-1, pack.hasMember("keyframe"), pack.getDataLen(), segment_size);
|
update(pack.getTime(), pack.hasMember("offset")?pack.getInt("offset"):0, pack.getTrackId(), dataLen, pack.hasMember("bpos")?pack.getInt("bpos"):0, pack.hasMember("keyframe"), pack.getDataLen(), segment_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Updates a meta object given a DTSC::Packet with byte position override.
|
///\brief Updates a meta object given a DTSC::Packet with byte position override.
|
||||||
void Meta::updatePosOverride(DTSC::Packet & pack, unsigned long bpos) {
|
void Meta::updatePosOverride(DTSC::Packet & pack, uint64_t bpos) {
|
||||||
char * data;
|
char * data;
|
||||||
unsigned int dataLen;
|
unsigned int dataLen;
|
||||||
pack.getString("data", data, dataLen);
|
pack.getString("data", data, dataLen);
|
||||||
update(pack.getTime(), pack.hasMember("offset")?pack.getInt("offset"):0, pack.getTrackId(), dataLen, bpos, pack.hasMember("keyframe"), pack.getDataLen());
|
update(pack.getTime(), pack.hasMember("offset")?pack.getInt("offset"):0, pack.getTrackId(), dataLen, bpos, pack.hasMember("keyframe"), pack.getDataLen());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Meta::update(long long packTime, long long packOffset, long long packTrack, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size){
|
void Meta::update(long long packTime, long long packOffset, long long packTrack, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size){
|
||||||
if (!packSendSize){
|
if (!packSendSize){
|
||||||
//time and trackID are part of the 20-byte header.
|
//time and trackID are part of the 20-byte header.
|
||||||
//the container object adds 4 bytes (plus 2+namelen for each content, see below)
|
//the container object adds 4 bytes (plus 2+namelen for each content, see below)
|
||||||
|
@ -1378,7 +1380,10 @@ namespace DTSC {
|
||||||
//data adds packDataSize+5 bytes (string type) and 6 bytes (2+namelen)
|
//data adds packDataSize+5 bytes (string type) and 6 bytes (2+namelen)
|
||||||
packSendSize = 24 + (packOffset?17:0) + (packBytePos>=0?15:0) + (isKeyframe?19:0) + packDataSize+11;
|
packSendSize = 24 + (packOffset?17:0) + (packBytePos>=0?15:0) + (isKeyframe?19:0) + packDataSize+11;
|
||||||
}
|
}
|
||||||
vod = (packBytePos >= 0);
|
if (vod != (packBytePos > 0)){
|
||||||
|
INFO_MSG("Changing stream from %s to %s (bPos=%lld)", vod?"VoD":"live", (packBytePos >= 0)?"Vod":"live", packBytePos);
|
||||||
|
}
|
||||||
|
vod = (packBytePos > 0);
|
||||||
live = !vod;
|
live = !vod;
|
||||||
if (packTrack > 0 && tracks.count(packTrack)){
|
if (packTrack > 0 && tracks.count(packTrack)){
|
||||||
tracks[packTrack].update(packTime, packOffset, packDataSize, packBytePos, isKeyframe, packSendSize, segment_size);
|
tracks[packTrack].update(packTime, packOffset, packDataSize, packBytePos, isKeyframe, packSendSize, segment_size);
|
||||||
|
@ -1929,6 +1934,63 @@ namespace DTSC {
|
||||||
it->second.reset();
|
it->second.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PartIter::PartIter(Track & Trk, Fragment & frag){
|
||||||
|
tRef = &Trk;
|
||||||
|
pIt = tRef->parts.begin();
|
||||||
|
kIt = tRef->keys.begin();
|
||||||
|
uint32_t fragNum = frag.getNumber();
|
||||||
|
while (kIt->getNumber() < fragNum && kIt != tRef->keys.end()){
|
||||||
|
uint32_t kParts = kIt->getParts();
|
||||||
|
for (uint32_t pCount = 0; pCount < kParts && pIt != tRef->parts.end(); ++pCount){
|
||||||
|
++pIt;
|
||||||
|
}
|
||||||
|
++kIt;
|
||||||
|
}
|
||||||
|
if (kIt == tRef->keys.end()){tRef = 0;}
|
||||||
|
currInKey = 0;
|
||||||
|
lastKey = fragNum + frag.getLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Dereferences into a Value reference.
|
||||||
|
/// If invalid iterator, returns an empty reference and prints a warning message.
|
||||||
|
Part & PartIter::operator*() const{
|
||||||
|
if (tRef && pIt != tRef->parts.end()){
|
||||||
|
return *pIt;
|
||||||
|
}
|
||||||
|
static Part error;
|
||||||
|
WARN_MSG("Dereferenced invalid Part iterator");
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Dereferences into a Value reference.
|
||||||
|
/// If invalid iterator, returns an empty reference and prints a warning message.
|
||||||
|
Part* PartIter::operator->() const{
|
||||||
|
return &(operator*());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// True if not done iterating.
|
||||||
|
PartIter::operator bool() const{
|
||||||
|
return (tRef && pIt != tRef->parts.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
PartIter & PartIter::operator++(){
|
||||||
|
if (*this){
|
||||||
|
++pIt;
|
||||||
|
if (++currInKey >= kIt->getParts()){
|
||||||
|
currInKey = 0;
|
||||||
|
//check if we're done iterating - we assume done if past the last key or arrived past the fragment
|
||||||
|
if (++kIt == tRef->keys.end() || kIt->getNumber() >= lastKey){
|
||||||
|
tRef = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -696,7 +696,7 @@ void HTTP::Parser::Chunkify(const char * data, unsigned int size, Socket::Connec
|
||||||
if (sendingChunks) {
|
if (sendingChunks) {
|
||||||
//prepend the chunk size and \r\n
|
//prepend the chunk size and \r\n
|
||||||
if (!size){
|
if (!size){
|
||||||
conn.SendNow("0\r\n\r\n\r\n", 7);
|
conn.SendNow("0\r\n\r\n", 5);
|
||||||
}
|
}
|
||||||
size_t offset = 8;
|
size_t offset = 8;
|
||||||
unsigned int t_size = size;
|
unsigned int t_size = size;
|
||||||
|
|
Loading…
Add table
Reference in a new issue