Optimized metadata updating, added genericFill function to DTSC::Packet for efficient packet creation.
This commit is contained in:
parent
f059e2148c
commit
1798db4602
2 changed files with 101 additions and 100 deletions
|
@ -109,6 +109,7 @@ namespace DTSC {
|
||||||
operator bool() const;
|
operator bool() const;
|
||||||
packType getVersion() const;
|
packType getVersion() const;
|
||||||
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, char * packData, long long packDataSize, long long 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;
|
||||||
|
@ -295,8 +296,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(DTSC::Packet & pack);
|
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(JSON::Value & pack);
|
|
||||||
int getSendLen();
|
int getSendLen();
|
||||||
void send(Socket::Connection & conn);
|
void send(Socket::Connection & conn);
|
||||||
void writeTo(char *& p);
|
void writeTo(char *& p);
|
||||||
|
@ -340,8 +340,9 @@ namespace DTSC {
|
||||||
Meta(const readOnlyMeta & meta);
|
Meta(const readOnlyMeta & meta);
|
||||||
Meta(JSON::Value & meta);
|
Meta(JSON::Value & meta);
|
||||||
void reinit(const DTSC::Packet & source);
|
void reinit(const DTSC::Packet & source);
|
||||||
void update(DTSC::Packet & pack);
|
void update(DTSC::Packet & pack, unsigned long segment_size = 5000);
|
||||||
void update(JSON::Value & pack);
|
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);
|
||||||
unsigned int getSendLen();
|
unsigned int getSendLen();
|
||||||
void send(Socket::Connection & conn);
|
void send(Socket::Connection & conn);
|
||||||
void writeTo(char * p);
|
void writeTo(char * p);
|
||||||
|
|
190
lib/dtscmeta.cpp
190
lib/dtscmeta.cpp
|
@ -190,6 +190,61 @@ namespace DTSC {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Re-initializes this Packet to contain a generic DTSC packet with the given data fields.
|
||||||
|
void Packet::genericFill(long long packTime, long long packOffset, long long packTrack, char * packData, long long packDataSize, long long packBytePos, bool isKeyframe){
|
||||||
|
null();
|
||||||
|
master = true;
|
||||||
|
//time and trackID are part of the 20-byte header.
|
||||||
|
//the container object adds 4 bytes (plus 2+namelen for each content, see below)
|
||||||
|
//offset, if non-zero, adds 9 bytes (integer type) and 8 bytes (2+namelen)
|
||||||
|
//bpos, if >= 0, adds 9 bytes (integer type) and 6 bytes (2+namelen)
|
||||||
|
//keyframe, if true, adds 9 bytes (integer type) and 10 bytes (2+namelen)
|
||||||
|
//data adds packDataSize+5 bytes (string type) and 6 bytes (2+namelen)
|
||||||
|
unsigned int sendLen = 24 + (packOffset?17:0) + (packBytePos>=0?15:0) + (isKeyframe?19:0) + packDataSize+11;
|
||||||
|
resize(sendLen);
|
||||||
|
//set internal variables
|
||||||
|
version = DTSC_V2;
|
||||||
|
dataLen = sendLen;
|
||||||
|
//write the first 20 bytes
|
||||||
|
memcpy(data, "DTP2", 4);
|
||||||
|
unsigned int tmpLong = htonl(sendLen - 8);
|
||||||
|
memcpy(data+4, (char *)&tmpLong, 4);
|
||||||
|
tmpLong = htonl(packTrack);
|
||||||
|
memcpy(data+8, (char *)&tmpLong, 4);
|
||||||
|
tmpLong = htonl((int)(packTime >> 32));
|
||||||
|
memcpy(data+12, (char *)&tmpLong, 4);
|
||||||
|
tmpLong = htonl((int)(packTime & 0xFFFFFFFF));
|
||||||
|
memcpy(data+16, (char *)&tmpLong, 4);
|
||||||
|
data[20] = 0xE0;//start container object
|
||||||
|
unsigned int offset = 21;
|
||||||
|
if (packOffset){
|
||||||
|
memcpy(data+offset, "\000\006offset\001", 9);
|
||||||
|
tmpLong = htonl((int)(packOffset >> 32));
|
||||||
|
memcpy(data+offset+9, (char *)&tmpLong, 4);
|
||||||
|
tmpLong = htonl((int)(packOffset & 0xFFFFFFFF));
|
||||||
|
memcpy(data+offset+13, (char *)&tmpLong, 4);
|
||||||
|
offset += 17;
|
||||||
|
}
|
||||||
|
if (packBytePos){
|
||||||
|
memcpy(data+offset, "\000\004bpos\001", 7);
|
||||||
|
tmpLong = htonl((int)(packBytePos >> 32));
|
||||||
|
memcpy(data+offset+7, (char *)&tmpLong, 4);
|
||||||
|
tmpLong = htonl((int)(packBytePos & 0xFFFFFFFF));
|
||||||
|
memcpy(data+offset+11, (char *)&tmpLong, 4);
|
||||||
|
offset += 15;
|
||||||
|
}
|
||||||
|
if (isKeyframe){
|
||||||
|
memcpy(data+offset, "\000\010keyframe\001\000\000\000\000\000\000\000\001", 19);
|
||||||
|
offset += 19;
|
||||||
|
}
|
||||||
|
memcpy(data+offset, "\000\004data\002", 7);
|
||||||
|
tmpLong = htonl(packDataSize);
|
||||||
|
memcpy(data+offset+7, (char *)&tmpLong, 4);
|
||||||
|
memcpy(data+offset+11, packData, packDataSize);
|
||||||
|
//finish container with 0x0000EE
|
||||||
|
memcpy(data+offset+11+packDataSize, "\000\000\356", 3);
|
||||||
|
}
|
||||||
|
|
||||||
/// Helper function for skipping over whole DTSC parts
|
/// Helper function for skipping over whole DTSC parts
|
||||||
static char * skipDTSC(char * p, char * max) {
|
static char * skipDTSC(char * p, char * max) {
|
||||||
if (p + 1 >= max || p[0] == 0x00) {
|
if (p + 1 >= max || p[0] == 0x00) {
|
||||||
|
@ -1126,55 +1181,51 @@ namespace DTSC {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Updates a track and its metadata given a DTSC::Packet.
|
///\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(DTSC::Packet & pack) {
|
void Track::update(long long packTime, long long packOffset, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size) {
|
||||||
if (pack.getTime() < lastms) {
|
if (packTime < lastms) {
|
||||||
DEBUG_MSG(DLVL_WARN, "Received packets for track %d in wrong order (%d < %d) - ignoring!", (int)trackID, (int)pack.getTime(), (int)lastms);
|
DEBUG_MSG(DLVL_WARN, "Received packets for track %d in wrong order (%lld < %d) - ignoring!", (int)trackID, packTime, (int)lastms);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Part newPart;
|
Part newPart;
|
||||||
char * data;
|
newPart.setSize(packDataSize);
|
||||||
unsigned int dataLen;
|
newPart.setOffset(packOffset);
|
||||||
pack.getString("data", data, dataLen);
|
|
||||||
newPart.setSize(dataLen);
|
|
||||||
newPart.setOffset(pack.getInt("offset"));
|
|
||||||
if (parts.size()) {
|
if (parts.size()) {
|
||||||
parts[parts.size() - 1].setDuration(pack.getTime() - lastms);
|
parts[parts.size() - 1].setDuration(packTime - lastms);
|
||||||
newPart.setDuration(pack.getTime() - lastms);
|
newPart.setDuration(packTime - lastms);
|
||||||
} else {
|
} else {
|
||||||
newPart.setDuration(0);
|
newPart.setDuration(0);
|
||||||
}
|
}
|
||||||
parts.push_back(newPart);
|
parts.push_back(newPart);
|
||||||
lastms = pack.getTime();
|
lastms = packTime;
|
||||||
if (pack.getFlag("keyframe") || !keys.size() || (type != "video" && pack.getTime() >= AUDIO_KEY_INTERVAL && pack.getTime() - (unsigned long long)keys[keys.size() - 1].getTime() >= AUDIO_KEY_INTERVAL)){
|
if (isKeyframe || !keys.size() || (type != "video" && packTime >= AUDIO_KEY_INTERVAL && packTime - (unsigned long long)keys[keys.size() - 1].getTime() >= AUDIO_KEY_INTERVAL)){
|
||||||
Key newKey;
|
Key newKey;
|
||||||
newKey.setTime(pack.getTime());
|
newKey.setTime(packTime);
|
||||||
newKey.setParts(0);
|
newKey.setParts(0);
|
||||||
newKey.setLength(0);
|
newKey.setLength(0);
|
||||||
if (keys.size()) {
|
if (keys.size()) {
|
||||||
newKey.setNumber(keys[keys.size() - 1].getNumber() + 1);
|
newKey.setNumber(keys[keys.size() - 1].getNumber() + 1);
|
||||||
keys[keys.size() - 1].setLength(pack.getTime() - keys[keys.size() - 1].getTime());
|
keys[keys.size() - 1].setLength(packTime - keys[keys.size() - 1].getTime());
|
||||||
} else {
|
} else {
|
||||||
newKey.setNumber(1);
|
newKey.setNumber(1);
|
||||||
}
|
}
|
||||||
if (pack.hasMember("bpos")) { //For VoD
|
if (packBytePos >= 0) { //For VoD
|
||||||
newKey.setBpos(pack.getInt("bpos"));
|
newKey.setBpos(packBytePos);
|
||||||
} else {
|
} else {
|
||||||
newKey.setBpos(0);
|
newKey.setBpos(0);
|
||||||
}
|
}
|
||||||
keys.push_back(newKey);
|
keys.push_back(newKey);
|
||||||
keySizes.push_back(0);
|
keySizes.push_back(0);
|
||||||
firstms = keys[0].getTime();
|
firstms = keys[0].getTime();
|
||||||
if (!fragments.size() || (pack.getTime() > 5000 && pack.getTime() - 5000 >= (unsigned long long)getKey(fragments.rbegin()->getNumber()).getTime())) {
|
if (!fragments.size() || (packTime > segment_size && packTime - segment_size >= (unsigned long long)getKey(fragments.rbegin()->getNumber()).getTime())) {
|
||||||
//new fragment
|
//new fragment
|
||||||
Fragment newFrag;
|
Fragment newFrag;
|
||||||
newFrag.setDuration(0);
|
newFrag.setDuration(0);
|
||||||
newFrag.setLength(1);
|
newFrag.setLength(1);
|
||||||
newFrag.setNumber(keys[keys.size() - 1].getNumber());
|
newFrag.setNumber(keys[keys.size() - 1].getNumber());
|
||||||
if (fragments.size()) {
|
if (fragments.size()) {
|
||||||
fragments[fragments.size() - 1].setDuration(pack.getTime() - getKey(fragments[fragments.size() - 1].getNumber()).getTime());
|
fragments[fragments.size() - 1].setDuration(packTime - getKey(fragments[fragments.size() - 1].getNumber()).getTime());
|
||||||
if (!bps && fragments[fragments.size() - 1].getDuration() > 1000) {
|
if (!bps && fragments[fragments.size() - 1].getDuration() > 1000) {
|
||||||
bps = (fragments[fragments.size() - 1].getSize() * 1000) / fragments[fragments.size() - 1].getDuration();
|
bps = (fragments[fragments.size() - 1].getSize() * 1000) / fragments[fragments.size() - 1].getDuration();
|
||||||
}
|
}
|
||||||
|
@ -1188,71 +1239,8 @@ namespace DTSC {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
keys.rbegin()->setParts(keys.rbegin()->getParts() + 1);
|
keys.rbegin()->setParts(keys.rbegin()->getParts() + 1);
|
||||||
(*keySizes.rbegin()) += pack.getDataLen();
|
(*keySizes.rbegin()) += packSendSize;
|
||||||
fragments.rbegin()->setSize(fragments.rbegin()->getSize() + dataLen);
|
fragments.rbegin()->setSize(fragments.rbegin()->getSize() + packDataSize);
|
||||||
}
|
|
||||||
|
|
||||||
///\brief Updates a track and its metadata given a JSON::Value
|
|
||||||
///
|
|
||||||
///Will also insert keyframes on non-video tracks, and creates fragments
|
|
||||||
void Track::update(JSON::Value & pack) {
|
|
||||||
if ((unsigned long long)pack["time"].asInt() < lastms) {
|
|
||||||
DEBUG_MSG(DLVL_WARN, "Received packets for track %d in wrong order (%d < %d) - ignoring!", (int)trackID, (int)pack["time"].asInt(), (int)lastms);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Part newPart;
|
|
||||||
newPart.setSize(pack["data"].asStringRef().size());
|
|
||||||
newPart.setOffset(pack["offset"].asInt());
|
|
||||||
if (parts.size()) {
|
|
||||||
parts[parts.size() - 1].setDuration(pack["time"].asInt() - lastms);
|
|
||||||
newPart.setDuration(pack["time"].asInt() - lastms);
|
|
||||||
} else {
|
|
||||||
newPart.setDuration(0);
|
|
||||||
}
|
|
||||||
parts.push_back(newPart);
|
|
||||||
lastms = pack["time"].asInt();
|
|
||||||
if (pack.isMember("keyframe") || !keys.size() || (type != "video" && pack["time"].asInt() >= AUDIO_KEY_INTERVAL && pack["time"].asInt() - keys[keys.size() - 1].getTime() >= AUDIO_KEY_INTERVAL)) {
|
|
||||||
Key newKey;
|
|
||||||
newKey.setTime(pack["time"].asInt());
|
|
||||||
newKey.setParts(0);
|
|
||||||
newKey.setLength(0);
|
|
||||||
if (keys.size()) {
|
|
||||||
newKey.setNumber(keys[keys.size() - 1].getNumber() + 1);
|
|
||||||
keys[keys.size() - 1].setLength(pack["time"].asInt() - keys[keys.size() - 1].getTime());
|
|
||||||
} else {
|
|
||||||
newKey.setNumber(1);
|
|
||||||
}
|
|
||||||
if (pack.isMember("bpos")) { //For VoD
|
|
||||||
newKey.setBpos(pack["bpos"].asInt());
|
|
||||||
} else {
|
|
||||||
newKey.setBpos(0);
|
|
||||||
}
|
|
||||||
keys.push_back(newKey);
|
|
||||||
keySizes.push_back(0);
|
|
||||||
firstms = keys[0].getTime();
|
|
||||||
if (!fragments.size() || (pack["time"].asInt() > 5000 && pack["time"].asInt() - 5000 >= getKey(fragments.rbegin()->getNumber()).getTime())) {
|
|
||||||
//new fragment
|
|
||||||
Fragment newFrag;
|
|
||||||
newFrag.setDuration(0);
|
|
||||||
newFrag.setLength(1);
|
|
||||||
newFrag.setNumber(keys[keys.size() - 1].getNumber());
|
|
||||||
if (fragments.size()) {
|
|
||||||
fragments[fragments.size() - 1].setDuration(pack["time"].asInt() - getKey(fragments[fragments.size() - 1].getNumber()).getTime());
|
|
||||||
if (!bps && fragments[fragments.size() - 1].getDuration() > 1000) {
|
|
||||||
bps = (fragments[fragments.size() - 1].getSize() * 1000) / fragments[fragments.size() - 1].getDuration();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newFrag.setDuration(0);
|
|
||||||
newFrag.setSize(0);
|
|
||||||
fragments.push_back(newFrag);
|
|
||||||
} else {
|
|
||||||
Fragment & lastFrag = fragments[fragments.size() - 1];
|
|
||||||
lastFrag.setLength(lastFrag.getLength() + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
keys.rbegin()->setParts(keys.rbegin()->getParts() + 1);
|
|
||||||
keySizes[keySizes.size() - 1] += pack.packedSize();
|
|
||||||
fragments.rbegin()->setSize(fragments.rbegin()->getSize() + pack["data"].asStringRef().size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///\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
|
||||||
|
@ -1458,20 +1446,32 @@ 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) {
|
void Meta::update(JSON::Value & pack, unsigned long segment_size) {
|
||||||
vod = pack.isMember("bpos");
|
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);
|
||||||
live = !vod;
|
|
||||||
if (pack["trackid"].asInt() && tracks.count(pack["trackid"].asInt())) {
|
|
||||||
tracks[pack["trackid"].asInt()].update(pack);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Updates a meta object given a DTSC::Packet
|
///\brief Updates a meta object given a DTSC::Packet
|
||||||
void Meta::update(DTSC::Packet & pack) {
|
void Meta::update(DTSC::Packet & pack, unsigned long segment_size) {
|
||||||
vod = pack.hasMember("bpos");
|
char * data;
|
||||||
|
unsigned int 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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){
|
||||||
|
if (!packSendSize){
|
||||||
|
//time and trackID are part of the 20-byte header.
|
||||||
|
//the container object adds 4 bytes (plus 2+namelen for each content, see below)
|
||||||
|
//offset, if non-zero, adds 9 bytes (integer type) and 8 bytes (2+namelen)
|
||||||
|
//bpos, if >= 0, adds 9 bytes (integer type) and 6 bytes (2+namelen)
|
||||||
|
//keyframe, if true, adds 9 bytes (integer type) and 10 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;
|
||||||
|
}
|
||||||
|
vod = (packBytePos >= 0);
|
||||||
live = !vod;
|
live = !vod;
|
||||||
if (pack.getTrackId() && tracks.count(pack.getTrackId())) {
|
if (packTrack > 0 && tracks.count(packTrack)){
|
||||||
tracks[pack.getTrackId()].update(pack);
|
tracks[packTrack].update(packTime, packOffset, packDataSize, packBytePos, isKeyframe, packSendSize, segment_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue