Added initial DTSCv2 support
This commit is contained in:
parent
a7de3bf08f
commit
2c343b9db6
3 changed files with 147 additions and 9 deletions
108
lib/dtsc.cpp
108
lib/dtsc.cpp
|
@ -7,6 +7,7 @@
|
||||||
#include <arpa/inet.h> //for htonl/ntohl
|
#include <arpa/inet.h> //for htonl/ntohl
|
||||||
char DTSC::Magic_Header[] = "DTSC";
|
char DTSC::Magic_Header[] = "DTSC";
|
||||||
char DTSC::Magic_Packet[] = "DTPD";
|
char DTSC::Magic_Packet[] = "DTPD";
|
||||||
|
char DTSC::Magic_Packet2[] = "DTP2";
|
||||||
|
|
||||||
/// Initializes a DTSC::Stream with only one packet buffer.
|
/// Initializes a DTSC::Stream with only one packet buffer.
|
||||||
DTSC::Stream::Stream(){
|
DTSC::Stream::Stream(){
|
||||||
|
@ -92,6 +93,49 @@ bool DTSC::Stream::parsePacket(std::string & buffer){
|
||||||
syncing = false;
|
syncing = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (memcmp(buffer.c_str(), DTSC::Magic_Packet2, 4) == 0){
|
||||||
|
len = ntohl(((uint32_t *)buffer.c_str())[1]);
|
||||||
|
if (buffer.length() < len + 20){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
buffers.push_front(JSON::Value());
|
||||||
|
unsigned int i = 0;
|
||||||
|
long long int tmpTrackID = ntohl(((int*)(buffer.c_str() + 8))[0]);
|
||||||
|
long long int tmpTime = ntohl(((int*)(buffer.c_str() + 12))[0]);
|
||||||
|
tmpTime << 32;
|
||||||
|
tmpTime += ntohl(((int*)(buffer.c_str() + 16))[0]);
|
||||||
|
buffers.front() = JSON::fromDTMI((unsigned char*)buffer.c_str() + 20, len, i);
|
||||||
|
buffers.front()["time"] = tmpTime;
|
||||||
|
buffers.front()["trackid"] = tmpTrackID;
|
||||||
|
datapointertype = INVALID;
|
||||||
|
if (buffers.front().isMember("data")){
|
||||||
|
datapointer = &(buffers.front()["data"].strVal);
|
||||||
|
}else{
|
||||||
|
datapointer = 0;
|
||||||
|
}
|
||||||
|
if (buffers.front().isMember("datatype")){
|
||||||
|
std::string tmp = buffers.front()["datatype"].asString();
|
||||||
|
if (tmp == "video"){
|
||||||
|
datapointertype = VIDEO;
|
||||||
|
}
|
||||||
|
if (tmp == "audio"){
|
||||||
|
datapointertype = AUDIO;
|
||||||
|
}
|
||||||
|
if (tmp == "meta"){
|
||||||
|
datapointertype = META;
|
||||||
|
}
|
||||||
|
if (tmp == "pause_marker"){
|
||||||
|
datapointertype = PAUSEMARK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer.erase(0, len + 20);
|
||||||
|
while (buffers.size() > buffercount){
|
||||||
|
buffers.pop_back();
|
||||||
|
}
|
||||||
|
advanceRings();
|
||||||
|
syncing = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#if DEBUG >= 2
|
#if DEBUG >= 2
|
||||||
if (!syncing){
|
if (!syncing){
|
||||||
std::cerr << "Error: Invalid DTMI data detected - re-syncing" << std::endl;
|
std::cerr << "Error: Invalid DTMI data detected - re-syncing" << std::endl;
|
||||||
|
@ -99,11 +143,16 @@ bool DTSC::Stream::parsePacket(std::string & buffer){
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
size_t magic_search = buffer.find(Magic_Packet);
|
size_t magic_search = buffer.find(Magic_Packet);
|
||||||
|
size_t magic_search2 = buffer.find(Magic_Packet2);
|
||||||
|
if (magic_search2 == std::string::npos){
|
||||||
if (magic_search == std::string::npos){
|
if (magic_search == std::string::npos){
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
}else{
|
}else{
|
||||||
buffer.erase(0, magic_search);
|
buffer.erase(0, magic_search);
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
buffer.erase(0, magic_search2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -169,6 +218,49 @@ bool DTSC::Stream::parsePacket(Socket::Buffer & buffer){
|
||||||
syncing = false;
|
syncing = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (memcmp(header_bytes.c_str(), DTSC::Magic_Packet2, 4) == 0){
|
||||||
|
len = ntohl(((uint32_t *)header_bytes.c_str())[1]);
|
||||||
|
if ( !buffer.available(len + 20)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
buffers.push_front(JSON::Value());
|
||||||
|
unsigned int i = 0;
|
||||||
|
std::string wholepacket = buffer.remove(len + 20);
|
||||||
|
long long int tmpTrackID = ntohl(((int*)(wholepacket.c_str() + 8))[0]);
|
||||||
|
long long int tmpTime = ntohl(((int*)(wholepacket.c_str() + 12))[0]);
|
||||||
|
tmpTime << 32;
|
||||||
|
tmpTime += ntohl(((int*)(wholepacket.c_str() + 16))[0]);
|
||||||
|
buffers.front() = JSON::fromDTMI((unsigned char*)wholepacket.c_str() + 20, len, i);
|
||||||
|
buffers.front()["time"] = tmpTime;
|
||||||
|
buffers.front()["trackid"] = tmpTrackID;
|
||||||
|
datapointertype = INVALID;
|
||||||
|
if (buffers.front().isMember("data")){
|
||||||
|
datapointer = &(buffers.front()["data"].strVal);
|
||||||
|
}else{
|
||||||
|
datapointer = 0;
|
||||||
|
}
|
||||||
|
if (buffers.front().isMember("datatype")){
|
||||||
|
std::string tmp = buffers.front()["datatype"].asString();
|
||||||
|
if (tmp == "video"){
|
||||||
|
datapointertype = VIDEO;
|
||||||
|
}
|
||||||
|
if (tmp == "audio"){
|
||||||
|
datapointertype = AUDIO;
|
||||||
|
}
|
||||||
|
if (tmp == "meta"){
|
||||||
|
datapointertype = META;
|
||||||
|
}
|
||||||
|
if (tmp == "pause_marker"){
|
||||||
|
datapointertype = PAUSEMARK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (buffers.size() > buffercount){
|
||||||
|
buffers.pop_back();
|
||||||
|
}
|
||||||
|
advanceRings();
|
||||||
|
syncing = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#if DEBUG >= 2
|
#if DEBUG >= 2
|
||||||
if (!syncing){
|
if (!syncing){
|
||||||
std::cerr << "Error: Invalid DTMI data detected - syncing" << std::endl;
|
std::cerr << "Error: Invalid DTMI data detected - syncing" << std::endl;
|
||||||
|
@ -648,8 +740,15 @@ void DTSC::File::seekNext(){
|
||||||
jsonbuffer = metadata;
|
jsonbuffer = metadata;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (memcmp(buffer, DTSC::Magic_Packet, 4) != 0){
|
long long unsigned int version = 0;
|
||||||
fprintf(stderr, "Invalid header - %.4s != %.4s\n", buffer, DTSC::Magic_Packet);
|
if (memcmp(buffer, DTSC::Magic_Packet, 4) == 0){
|
||||||
|
version = 1;
|
||||||
|
}
|
||||||
|
if (memcmp(buffer, DTSC::Magic_Packet2, 4) == 0){
|
||||||
|
version = 2;
|
||||||
|
}
|
||||||
|
if (version == 0){
|
||||||
|
fprintf(stderr, "Invalid header - %.4s != %.4s\n", buffer, DTSC::Magic_Packet2);
|
||||||
strbuffer = "";
|
strbuffer = "";
|
||||||
jsonbuffer.null();
|
jsonbuffer.null();
|
||||||
return;
|
return;
|
||||||
|
@ -661,7 +760,7 @@ void DTSC::File::seekNext(){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint32_t * ubuffer = (uint32_t *)buffer;
|
uint32_t * ubuffer = (uint32_t *)buffer;
|
||||||
long packSize = ntohl(ubuffer[0]);
|
long packSize = ntohl(ubuffer[0]) + (version == 2 ? 12 : 0);
|
||||||
strbuffer.resize(packSize);
|
strbuffer.resize(packSize);
|
||||||
if (fread((void*)strbuffer.c_str(), packSize, 1, F) != 1){
|
if (fread((void*)strbuffer.c_str(), packSize, 1, F) != 1){
|
||||||
fprintf(stderr, "Could not read packet\n");
|
fprintf(stderr, "Could not read packet\n");
|
||||||
|
@ -669,6 +768,9 @@ void DTSC::File::seekNext(){
|
||||||
jsonbuffer.null();
|
jsonbuffer.null();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (version == 2){
|
||||||
|
strbuffer.erase(0,12);
|
||||||
|
}
|
||||||
jsonbuffer = JSON::fromDTMI(strbuffer);
|
jsonbuffer = JSON::fromDTMI(strbuffer);
|
||||||
if (jsonbuffer.isMember("keyframe")){
|
if (jsonbuffer.isMember("keyframe")){
|
||||||
if (frames[currframe] != lastreadpos){
|
if (frames[currframe] != lastreadpos){
|
||||||
|
|
|
@ -62,6 +62,7 @@ namespace DTSC {
|
||||||
|
|
||||||
extern char Magic_Header[]; ///< The magic bytes for a DTSC header
|
extern char Magic_Header[]; ///< The magic bytes for a DTSC header
|
||||||
extern char Magic_Packet[]; ///< The magic bytes for a DTSC packet
|
extern char Magic_Packet[]; ///< The magic bytes for a DTSC packet
|
||||||
|
extern char Magic_Packet2[]; ///< The magic bytes for a DTSC packet version 2
|
||||||
|
|
||||||
/// 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{
|
||||||
|
|
39
lib/json.cpp
39
lib/json.cpp
|
@ -475,19 +475,54 @@ void JSON::Value::netPrepare(){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::string packed = toPacked();
|
std::string packed = toPacked();
|
||||||
strVal.resize(packed.size() + 8);
|
|
||||||
//insert proper header for this type of data
|
//insert proper header for this type of data
|
||||||
|
int packID = -1;
|
||||||
|
long long unsigned int time = objVal["time"].asInt();
|
||||||
|
std::string dataType = objVal["datatype"].asString();
|
||||||
if (isMember("datatype")){
|
if (isMember("datatype")){
|
||||||
memcpy((void*)strVal.c_str(), "DTPD", 4);
|
if (isMember("trackid")){
|
||||||
|
packID = objVal["trackid"].asInt();
|
||||||
}else{
|
}else{
|
||||||
|
if (objVal["datatype"].asString() == "video"){
|
||||||
|
packID = 1;
|
||||||
|
}
|
||||||
|
if (objVal["datatype"].asString() == "audio"){
|
||||||
|
packID = 2;
|
||||||
|
}
|
||||||
|
if (objVal["datatype"].asString() == "meta"){
|
||||||
|
packID = 3;
|
||||||
|
}
|
||||||
|
if (packID == -1){
|
||||||
|
packID = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removeMember("time");
|
||||||
|
removeMember("datatype");
|
||||||
|
packed = toPacked();
|
||||||
|
objVal["time"] = (long long int)time;
|
||||||
|
objVal["datatype"] = dataType;
|
||||||
|
strVal.resize(packed.size() + 20);
|
||||||
|
memcpy((void*)strVal.c_str(), "DTP2", 4);
|
||||||
|
}else{
|
||||||
|
strVal.resize(packed.size() + 8);
|
||||||
memcpy((void*)strVal.c_str(), "DTSC", 4);
|
memcpy((void*)strVal.c_str(), "DTSC", 4);
|
||||||
}
|
}
|
||||||
//insert the packet length at bytes 4-7
|
//insert the packet length at bytes 4-7
|
||||||
unsigned int size = htonl(packed.size());
|
unsigned int size = htonl(packed.size());
|
||||||
memcpy((void*)(strVal.c_str() + 4), (void*) &size, 4);
|
memcpy((void*)(strVal.c_str() + 4), (void*) &size, 4);
|
||||||
//copy the rest of the string
|
//copy the rest of the string
|
||||||
|
if (packID != -1){
|
||||||
|
packID = htonl((int)packID);
|
||||||
|
memcpy((void*)(strVal.c_str() + 8), (void*) &packID, 4);
|
||||||
|
int tmpHalf = htonl((int)(time >> 32));
|
||||||
|
memcpy((void*)(strVal.c_str() + 12), (void*) &tmpHalf, 4);
|
||||||
|
tmpHalf = htonl((int)(time & 0xFFFFFFFF));
|
||||||
|
memcpy((void*)(strVal.c_str() + 16), (void*) &tmpHalf, 4);
|
||||||
|
memcpy((void*)(strVal.c_str() + 20), packed.c_str(), packed.size());
|
||||||
|
}else{
|
||||||
memcpy((void*)(strVal.c_str() + 8), packed.c_str(), packed.size());
|
memcpy((void*)(strVal.c_str() + 8), packed.c_str(), packed.size());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Packs any object-type JSON::Value to a std::string for transfer over the network, including proper DTMI header.
|
/// Packs any object-type JSON::Value to a std::string for transfer over the network, including proper DTMI header.
|
||||||
/// Non-object-types will print an error to stderr and return an empty string.
|
/// Non-object-types will print an error to stderr and return an empty string.
|
||||||
|
|
Loading…
Add table
Reference in a new issue