diff --git a/Connector_HTTP/main.cpp b/Connector_HTTP/main.cpp
index d2b97e1b..8d0bd18f 100644
--- a/Connector_HTTP/main.cpp
+++ b/Connector_HTTP/main.cpp
@@ -103,7 +103,6 @@ std::string BuildManifest( std::string MetaData, std::string MovieId, int Curren
Result += "streaming\n";
Result += "";
Result += base64_encode(temp->GenerateLiveBootstrap(1));
-// Result += "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";
Result += "\n";
Result += " Flash_FragBuffer;
FLV_Pack * tag = 0;
+ char * Video_Init_Data = 0;
+ int Video_Init_Len = 0;
+ char * Audio_Init_Data = 0;
+ int Audio_Init_Len = 0;
HTTPReader HTTP_R, HTTP_S;//HTTP Receiver en HTTP Sender.
int retval;
@@ -151,73 +154,62 @@ int mainHandler(int CONN_fd){
while (!socketError && !All_Hell_Broke_Loose){
//only parse input if available or not yet init'ed
- retval = epoll_wait(poller, events, 1, 1);
- if ((retval > 0) || !ready4data){
- if (HTTP_R.ReadSocket(CONN_fd)){
- handler = HANDLER_PROGRESSIVE;
- if ((HTTP_R.url.find("Seg") != std::string::npos) && (HTTP_R.url.find("Frag") != std::string::npos)){handler = HANDLER_FLASH;}
- if (HTTP_R.url.find("f4m") != std::string::npos){handler = HANDLER_FLASH;}
- if (HTTP_R.url == "/crossdomain.xml"){
- handler = HANDLER_NONE;
- HTTP_S.Clean();
- HTTP_S.SetHeader("Content-Type", "text/xml");
- HTTP_S.SetBody("");
- HTTP_S.SendResponse(CONN_fd, "200", "OK");//geen SetBody = unknown length! Dat willen we hier.
- #if DEBUG >= 3
- printf("Sending crossdomain.xml file\n");
- #endif
- }
- if(handler == HANDLER_FLASH){
- if (HTTP_R.url.find("f4m") == std::string::npos){
- Movie = HTTP_R.url.substr(1);
- Movie = Movie.substr(0,Movie.find("/"));
- Quality = HTTP_R.url.substr( HTTP_R.url.find("/",1)+1 );
- Quality = Quality.substr(0, Quality.find("Seg"));
- temp = HTTP_R.url.find("Seg") + 3;
- Segment = atoi( HTTP_R.url.substr(temp,HTTP_R.url.find("-",temp)-temp).c_str());
- temp = HTTP_R.url.find("Frag") + 4;
- ReqFragment = atoi( HTTP_R.url.substr(temp).c_str() );
- #if DEBUG >= 4
- /* strftime example */
- time_t rawtime;
- struct tm * timeinfo;
- char timebuffer [80];
- time ( &rawtime );
- timeinfo = localtime ( &rawtime );
- strftime (timebuffer,80,"%H:%M.%S.",timeinfo);
- fprintf(stderr, "< %s >\t", timebuffer );
- printf( "URL: %s\n", HTTP_R.url.c_str());
- printf( "Movie: %s, Quality: %s, Seg %d Frag %d\n", Movie.c_str(), Quality.c_str(), Segment, ReqFragment);
- #endif
- Flash_RequestPending++;
- }else{
- Movie = HTTP_R.url.substr(1);
- Movie = Movie.substr(0,Movie.find("/"));
- }
- streamname = "/tmp/shared_socket_";
- for (std::string::iterator i=Movie.end()-1; i>=Movie.begin(); --i){
- if (!isalpha(*i) && !isdigit(*i)){
- Movie.erase(i);
- }else{
- *i=tolower(*i);
- }//strip nonalphanumeric
- }
- streamname += Movie;
- ready4data = true;
- }//FLASH handler
- if (handler == HANDLER_PROGRESSIVE){
- //in het geval progressive nemen we aan dat de URL de streamname is, met .flv erachter
- streamname = HTTP_R.url.substr(0, HTTP_R.url.size()-4);//strip de .flv
- for (std::string::iterator i=streamname.end()-1; i>=streamname.begin(); --i){
- if (!isalpha(*i) && !isdigit(*i)){streamname.erase(i);}else{*i=tolower(*i);}//strip nonalphanumeric
- }
- streamname = "/tmp/shared_socket_" + streamname;//dit is dan onze shared_socket
- //normaal zouden we ook een position uitlezen uit de URL, maar bij LIVE streams is dat zinloos
- printf("Streamname: %s\n", streamname.c_str());
- ready4data = true;
- }//PROGRESSIVE handler
- HTTP_R.Clean(); //maak schoon na verwerken voor eventuele volgende requests...
+ if (HTTP_R.ReadSocket(CONN_fd)){
+ handler = HANDLER_PROGRESSIVE;
+ if ((HTTP_R.url.find("Seg") != std::string::npos) && (HTTP_R.url.find("Frag") != std::string::npos)){handler = HANDLER_FLASH;}
+ if (HTTP_R.url.find("f4m") != std::string::npos){handler = HANDLER_FLASH;}
+ if (HTTP_R.url == "/crossdomain.xml"){
+ handler = HANDLER_NONE;
+ HTTP_S.Clean();
+ HTTP_S.SetHeader("Content-Type", "text/xml");
+ HTTP_S.SetBody("");
+ HTTP_S.SendResponse(CONN_fd, "200", "OK");//geen SetBody = unknown length! Dat willen we hier.
+ #if DEBUG >= 3
+ printf("Sending crossdomain.xml file\n");
+ #endif
}
+ if(handler == HANDLER_FLASH){
+ if (HTTP_R.url.find("f4m") == std::string::npos){
+ Movie = HTTP_R.url.substr(1);
+ Movie = Movie.substr(0,Movie.find("/"));
+ Quality = HTTP_R.url.substr( HTTP_R.url.find("/",1)+1 );
+ Quality = Quality.substr(0, Quality.find("Seg"));
+ temp = HTTP_R.url.find("Seg") + 3;
+ Segment = atoi( HTTP_R.url.substr(temp,HTTP_R.url.find("-",temp)-temp).c_str());
+ temp = HTTP_R.url.find("Frag") + 4;
+ ReqFragment = atoi( HTTP_R.url.substr(temp).c_str() );
+ #if DEBUG >= 4
+ printf( "URL: %s\n", HTTP_R.url.c_str());
+ printf( "Movie: %s, Quality: %s, Seg %d Frag %d\n", Movie.c_str(), Quality.c_str(), Segment, ReqFragment);
+ #endif
+ Flash_RequestPending++;
+ }else{
+ Movie = HTTP_R.url.substr(1);
+ Movie = Movie.substr(0,Movie.find("/"));
+ }
+ streamname = "/tmp/shared_socket_";
+ for (std::string::iterator i=Movie.end()-1; i>=Movie.begin(); --i){
+ if (!isalpha(*i) && !isdigit(*i)){
+ Movie.erase(i);
+ }else{
+ *i=tolower(*i);
+ }//strip nonalphanumeric
+ }
+ streamname += Movie;
+ ready4data = true;
+ }//FLASH handler
+ if (handler == HANDLER_PROGRESSIVE){
+ //in het geval progressive nemen we aan dat de URL de streamname is, met .flv erachter
+ streamname = HTTP_R.url.substr(0, HTTP_R.url.size()-4);//strip de .flv
+ for (std::string::iterator i=streamname.end()-1; i>=streamname.begin(); --i){
+ if (!isalpha(*i) && !isdigit(*i)){streamname.erase(i);}else{*i=tolower(*i);}//strip nonalphanumeric
+ }
+ streamname = "/tmp/shared_socket_" + streamname;//dit is dan onze shared_socket
+ //normaal zouden we ook een position uitlezen uit de URL, maar bij LIVE streams is dat zinloos
+ printf("Streamname: %s\n", streamname.c_str());
+ ready4data = true;
+ }//PROGRESSIVE handler
+ HTTP_R.CleanForNext(); //maak schoon na verwerken voor eventuele volgende requests...
}
if (ready4data){
if (!inited){
@@ -246,14 +238,6 @@ int mainHandler(int CONN_fd){
HTTP_S.SendResponse(CONN_fd, "200", "OK");//schrijf de HTTP response header
Flash_RequestPending--;
#if DEBUG >= 3
- /* strftime example */
- time_t rawtime;
- struct tm * timeinfo;
- char timebuffer [80];
- time ( &rawtime );
- timeinfo = localtime ( &rawtime );
- strftime (timebuffer,80,"%H:%M.%S.",timeinfo);
- fprintf(stderr, "< %s >\t", timebuffer );
fprintf(stderr, "Sending a video fragment. %i left in buffer, %i requested\n", (int)Flash_FragBuffer.size(), Flash_RequestPending);
#endif
}
@@ -267,25 +251,40 @@ int mainHandler(int CONN_fd){
break;
case -1: break;//not ready yet
default:
- if (FLV_GetPacket(tag, ss)){//able to read a full packet?
+ if (FLV_GetPacket(tag, ss)){//able to read a full packet?f
if (handler == HANDLER_FLASH){
if(tag->data[0] != 0x12 ) {
- if (tag->isKeyframe){
- if (FlashBuf != ""){
- Flash_FragBuffer.push(FlashBuf);
+ if ((tag->isKeyframe) && (Video_Init_Data == 0)){
+ if (((tag->data[11] & 0x0f) == 7) && (tag->data[12] == 0)){
+ tag->data[4] = 0;//timestamp to zero
+ tag->data[5] = 0;//timestamp to zero
+ tag->data[6] = 0;//timestamp to zero
+ Video_Init_Data = (char*)malloc(tag->len);
+ Video_Init_Len = tag->len;
+ memcpy(Video_Init_Data, tag->data, tag->len);
+ }
+ }
+ if ((tag->data[0] == 0x08) && (Audio_Init_Data == 0)){
+ if (((tag->data[11] & 0xf0) >> 4) == 10){//aac packet
+ tag->data[4] = 0;//timestamp to zero
+ tag->data[5] = 0;//timestamp to zero
+ tag->data[6] = 0;//timestamp to zero
+ Audio_Init_Data = (char*)malloc(tag->len);
+ Audio_Init_Len = tag->len;
+ memcpy(Audio_Init_Data, tag->data, tag->len);
+ }
+ }
+ if (tag->isKeyframe){
+ if (FlashBuf != ""){
+ Flash_FragBuffer.push(FlashBuf);
#if DEBUG >= 4
- time_t rawtime;
- struct tm * timeinfo;
- char timebuffer [80];
- time ( &rawtime );
- timeinfo = localtime ( &rawtime );
- strftime (timebuffer,80,"%H:%M.%S.",timeinfo);
- fprintf(stderr, "< %s >\t", timebuffer );
- fprintf(stderr, "Received a fragment. Now %i in buffer.\n", (int)Flash_FragBuffer.size());
+ fprintf(stderr, "Received a fragment. Now %i in buffer.\n", (int)Flash_FragBuffer.size());
#endif
- }
- FlashBuf = "";
- }
+ }
+ FlashBuf.clear();
+ if (Video_Init_Len > 0) FlashBuf.append(Video_Init_Data, Video_Init_Len);
+ if (Audio_Init_Len > 0) FlashBuf.append(Audio_Init_Data, Audio_Init_Len);
+ }
FlashBuf.append(tag->data,tag->len);
} else {
FlashMeta = "";
@@ -319,6 +318,8 @@ int mainHandler(int CONN_fd){
}
}
close(CONN_fd);
+ if (Video_Init_Data){free(Video_Init_Data);}
+ if (Audio_Init_Data){free(Audio_Init_Data);}
if (inited) close(ss);
#if DEBUG >= 1
if (All_Hell_Broke_Loose){fprintf(stderr, "All Hell Broke Loose\n");}
diff --git a/HTTP_Box_Parser/Makefile b/HTTP_Box_Parser/Makefile
new file mode 100644
index 00000000..6dd89381
--- /dev/null
+++ b/HTTP_Box_Parser/Makefile
@@ -0,0 +1,19 @@
+SRC = main.cpp
+OBJ = $(SRC:.cpp=.o)
+OUT = Box_Parser
+INCLUDES =
+CCFLAGS = -Wall -Wextra -funsigned-char -g
+CC = $(CROSS)g++
+LD = $(CROSS)ld
+AR = $(CROSS)ar
+LIBS = -lssl -lcrypto
+.SUFFIXES: .cpp
+.PHONY: clean default
+default: $(OUT)
+.cpp.o:
+ $(CC) $(INCLUDES) $(CCFLAGS) -c $< -o $@
+$(OUT): $(OBJ)
+ $(CC) $(LIBS) -o $(OUT) $(OBJ)
+clean:
+ rm -rf $(OBJ) $(OUT) Makefile.bak *~
+
diff --git a/HTTP_Box_Parser/main.cpp b/HTTP_Box_Parser/main.cpp
new file mode 100644
index 00000000..1d06741e
--- /dev/null
+++ b/HTTP_Box_Parser/main.cpp
@@ -0,0 +1,46 @@
+#include
+#include
+#include
+#include "../util/http_parser.cpp"
+#include "../util/MP4/box_includes.h"
+#include "../util/flv_data.cpp"
+
+std::string tagType(FLV_Pack * F){
+ switch (F->data[0]){
+ case 0x09:
+ if (F->isKeyframe){
+ return "video keyframe";
+ }else{
+ return "video";
+ }
+ break;
+ case 0x08: return "audio"; break;
+ case 0x12: return "data"; break;
+ }
+ return "unknown";
+}
+
+int main( ) {
+ std::string temp;
+
+ HTTPReader H;
+ FLV_Pack * F = 0;
+ unsigned int P = 0;
+
+ while (H.ReadSocket(stdin) || H.CleanForNext()){
+ if (H.body.size() > 10000){
+ Box * TestBox = new Box((uint8_t*)H.body.c_str(), H.body.size());
+ TestBox->Parse();
+ P = 0;
+ while (TestBox->PayloadSize > P){
+ if (FLV_GetPacket(F, (char*)TestBox->Payload, TestBox->PayloadSize, P)){
+ std::cout << "Got a " << F->len << " bytes " << tagType(F) << " FLV tag." << std::endl;
+ }
+ }
+ delete TestBox;
+ }else{
+ std::cout << "Skipped too small fragment" << std::endl;
+ }
+ }
+
+}
diff --git a/util/MP4/box.cpp b/util/MP4/box.cpp
index be18b31e..46412680 100644
--- a/util/MP4/box.cpp
+++ b/util/MP4/box.cpp
@@ -46,7 +46,6 @@ class Box {
uint8_t * Payload;
BoxHeader header;
uint32_t PayloadSize;
- private:
};//Box Class
Box::Box() {
@@ -176,3 +175,225 @@ void Box::ResetPayload( ) {
Payload = NULL;
}
}
+
+void Box::Parse( std::string PrintOffset ) {
+ if( header.BoxType == 0x61627374 ) {
+ uint8_t Version = Payload[0];
+ uint32_t Flags = (Payload[1] << 16) + (Payload[2] << 8) + (Payload[3]); //uint24_t
+ uint32_t BootstrapInfoVersion = (Payload[4] << 24) + (Payload[5] << 16) +(Payload[6] << 8) + (Payload[7]);
+ uint8_t Profile = (Payload[8] >> 6); //uint2_t
+ uint8_t Live = (( Payload[8] >> 5 ) & 0x1); //uint1_t
+ uint8_t Update = (( Payload[8] >> 4 ) & 0x1); //uint1_t
+ uint8_t Reserved = ( Payload[8] & 0x4); //uint4_t
+ uint32_t Timescale = (Payload[9] << 24) + (Payload[10] << 16) +(Payload[11] << 8) + (Payload[12]);
+ uint32_t CurrentMediaTime_Upperhalf = (Payload[13] << 24) + (Payload[14] << 16) +(Payload[15] << 8) + (Payload[16]);
+ uint32_t CurrentMediaTime_Lowerhalf = (Payload[17] << 24) + (Payload[18] << 16) +(Payload[19] << 8) + (Payload[20]);
+ uint32_t SmpteTimeCodeOffset_Upperhalf = (Payload[21] << 24) + (Payload[22] << 16) +(Payload[23] << 8) + (Payload[24]);
+ uint32_t SmpteTimeCodeOffset_Lowerhalf = (Payload[25] << 24) + (Payload[26] << 16) +(Payload[27] << 8) + (Payload[28]);
+
+ std::string MovieIdentifier;
+ uint8_t ServerEntryCount = -1;
+ std::vector ServerEntryTable;
+ uint8_t QualityEntryCount = -1;
+ std::vector QualityEntryTable;
+ std::string DrmData;
+ std::string MetaData;
+ uint8_t SegmentRunTableCount = -1;
+ std::vector SegmentRunTableEntries;
+ uint8_t FragmentRunTableCount = -1;
+ std::vector FragmentRunTableEntries;
+
+ uint32_t CurrentOffset = 29;
+ uint32_t TempSize;
+ Box* TempBox;
+ std::string temp;
+ while( Payload[CurrentOffset] != '\0' ) { MovieIdentifier += Payload[CurrentOffset]; CurrentOffset ++; }
+ CurrentOffset ++;
+ ServerEntryCount = Payload[CurrentOffset];
+ CurrentOffset ++;
+ for( uint8_t i = 0; i < ServerEntryCount; i++ ) {
+ temp = "";
+ while( Payload[CurrentOffset] != '\0' ) { temp += Payload[CurrentOffset]; CurrentOffset ++; }
+ ServerEntryTable.push_back(temp);
+ CurrentOffset++;
+ }
+ QualityEntryCount = Payload[CurrentOffset];
+ CurrentOffset ++;
+ for( uint8_t i = 0; i < QualityEntryCount; i++ ) {
+ temp = "";
+ while( Payload[CurrentOffset] != '\0' ) { temp += Payload[CurrentOffset]; CurrentOffset ++; }
+ QualityEntryTable.push_back(temp);
+ CurrentOffset++;
+ }
+ while( Payload[CurrentOffset] != '\0' ) { DrmData += Payload[CurrentOffset]; CurrentOffset ++; }
+ CurrentOffset ++;
+ while( Payload[CurrentOffset] != '\0' ) { MetaData += Payload[CurrentOffset]; CurrentOffset ++; }
+ CurrentOffset ++;
+ SegmentRunTableCount = Payload[CurrentOffset];
+ CurrentOffset ++;
+ for( uint8_t i = 0; i < SegmentRunTableCount; i++ ) {
+ TempSize = (Payload[CurrentOffset] << 24) + (Payload[CurrentOffset+1]<< 16) + (Payload[CurrentOffset+2]<< 8) + (Payload[CurrentOffset+3]);
+ TempBox = new Box( &Payload[CurrentOffset], TempSize );
+ SegmentRunTableEntries.push_back(TempBox);
+ CurrentOffset += TempSize;
+ }
+ FragmentRunTableCount = Payload[CurrentOffset];
+ CurrentOffset ++;
+ for( uint8_t i = 0; i < FragmentRunTableCount; i++ ) {
+ TempSize = (Payload[CurrentOffset] << 24) + (Payload[CurrentOffset+1]<< 16) + (Payload[CurrentOffset+2]<< 8) + (Payload[CurrentOffset+3]);
+ TempBox = new Box( &Payload[CurrentOffset], TempSize );
+ FragmentRunTableEntries.push_back(TempBox);
+ CurrentOffset += TempSize;
+ }
+
+ std::cerr << "Box_ABST:\n";
+ std::cerr << PrintOffset << " Version: " << (int)Version << "\n";
+ std::cerr << PrintOffset << " Flags: " << (int)Flags << "\n";
+ std::cerr << PrintOffset << " BootstrapInfoVersion: " << (int)BootstrapInfoVersion << "\n";
+ std::cerr << PrintOffset << " Profile: " << (int)Profile << "\n";
+ std::cerr << PrintOffset << " Live: " << (int)Live << "\n";
+ std::cerr << PrintOffset << " Update: " << (int)Update << "\n";
+ std::cerr << PrintOffset << " Reserved: " << (int)Reserved << "\n";
+ std::cerr << PrintOffset << " Timescale: " << (int)Timescale << "\n";
+ std::cerr << PrintOffset << " CurrentMediaTime: " << (int)CurrentMediaTime_Upperhalf << " " << CurrentMediaTime_Lowerhalf << "\n";
+ std::cerr << PrintOffset << " SmpteTimeCodeOffset: " << (int)SmpteTimeCodeOffset_Upperhalf << " " << SmpteTimeCodeOffset_Lowerhalf << "\n";
+ std::cerr << PrintOffset << " MovieIdentifier: " << MovieIdentifier << "\n";
+ std::cerr << PrintOffset << " ServerEntryCount: " << (int)ServerEntryCount << "\n";
+ std::cerr << PrintOffset << " ServerEntryTable:\n";
+ for( uint32_t i = 0; i < ServerEntryTable.size( ); i++ ) {
+ std::cerr << PrintOffset << " " << i+1 << ": " << ServerEntryTable[i] << "\n";
+ }
+ std::cerr << PrintOffset << " QualityEntryCount: " << (int)QualityEntryCount << "\n";
+ std::cerr << PrintOffset << " QualityEntryTable:\n";
+ for( uint32_t i = 0; i < QualityEntryTable.size( ); i++ ) {
+ std::cerr << PrintOffset << " " << i+1 << ": " << QualityEntryTable[i] << "\n";
+ }
+ std::cerr << PrintOffset << " DrmData: " << DrmData << "\n";
+ std::cerr << PrintOffset << " MetaData: " << MetaData << "\n";
+ std::cerr << PrintOffset << " SegmentRunTableCount: " << (int)SegmentRunTableCount << "\n";
+ std::cerr << PrintOffset << " SegmentRunTableEntries:\n";
+ for( uint32_t i = 0; i < SegmentRunTableEntries.size( ); i++ ) {
+ std::cerr << PrintOffset << " " << i+1 << ": ";
+ SegmentRunTableEntries[i]->Parse( PrintOffset+" ");
+ }
+ std::cerr << PrintOffset << " FragmentRunTableCount: " << (int)FragmentRunTableCount << "\n";
+ std::cerr << PrintOffset << " FragmentRunTableEntries:\n";
+ for( uint32_t i = 0; i < FragmentRunTableEntries.size( ); i++ ) {
+ std::cerr << PrintOffset << " " << i+1 << ": ";
+ FragmentRunTableEntries[i]->Parse( PrintOffset+" ");
+ }
+
+ } else if ( header.BoxType == 0x61737274 ) {
+ uint8_t Version = Payload[0];
+ uint32_t Flags = (Payload[1] << 16) + (Payload[2] << 8) + (Payload[3]); //uint24_t
+ uint8_t QualityEntryCount;
+ std::vector QualitySegmentUrlModifiers;
+ uint32_t SegmentRunEntryCount;
+ std::vector< std::pair > SegmentRunEntryTable;
+
+ uint32_t CurrentOffset = 4;
+ std::string temp;
+ std::pair TempPair;
+ QualityEntryCount = Payload[CurrentOffset];
+ CurrentOffset ++;
+ for( uint8_t i = 0; i < QualityEntryCount; i++ ) {
+ temp = "";
+ while( Payload[CurrentOffset] != '\0' ) { temp += Payload[CurrentOffset]; CurrentOffset ++; }
+ QualitySegmentUrlModifiers.push_back(temp);
+ CurrentOffset++;
+ }
+ SegmentRunEntryCount = (Payload[CurrentOffset] << 24) + (Payload[CurrentOffset+1] << 16) + (Payload[CurrentOffset+2]) + (Payload[CurrentOffset+3]);
+ CurrentOffset +=4;
+ for( uint8_t i = 0; i < SegmentRunEntryCount; i++ ) {
+ TempPair.first = (Payload[CurrentOffset] << 24) + (Payload[CurrentOffset+1] << 16) + (Payload[CurrentOffset+2] << 8) + (Payload[CurrentOffset+3]);
+ CurrentOffset+=4;
+ TempPair.second = (Payload[CurrentOffset] << 24) + (Payload[CurrentOffset+1] << 16) + (Payload[CurrentOffset+2] << 8) + (Payload[CurrentOffset+3]);
+ CurrentOffset+=4;
+ SegmentRunEntryTable.push_back(TempPair);
+ }
+
+ std::cerr << "Box_ASRT:\n";
+ std::cerr << PrintOffset << " Version: " << (int)Version << "\n";
+ std::cerr << PrintOffset << " Flags: " << (int)Flags << "\n";
+ std::cerr << PrintOffset << " QualityEntryCount: " << (int)QualityEntryCount << "\n";
+ std::cerr << PrintOffset << " QualitySegmentUrlModifiers:\n";
+ for( uint32_t i = 0; i < QualitySegmentUrlModifiers.size( ); i++ ) {
+ std::cerr << PrintOffset << " " << i+1 << ": " << QualitySegmentUrlModifiers[i] << "\n";
+ }
+ std::cerr << PrintOffset << " SegmentRunEntryCount: " << (int)SegmentRunEntryCount << "\n";
+ std::cerr << PrintOffset << " SegmentRunEntryTable:\n";
+ for( uint32_t i = 0; i < SegmentRunEntryTable.size( ); i++ ) {
+ std::cerr << PrintOffset << " " << i+1 << ":\n";
+ std::cerr << PrintOffset << " FirstSegment: " << SegmentRunEntryTable[i].first << "\n";
+ std::cerr << PrintOffset << " FragmentsPerSegment: " << SegmentRunEntryTable[i].second << "\n";
+ }
+ } else if ( header.BoxType == 0x61667274 ) {
+ uint8_t Version = Payload[0];
+ uint32_t Flags = (Payload[1] << 16) + (Payload[2] << 8) + (Payload[3]); //uint24_t
+ uint32_t TimeScale = (Payload[4] << 24) + (Payload[5] << 16) + (Payload[6] << 8) + (Payload[7]);
+ uint8_t QualityEntryCount;
+ std::vector QualitySegmentUrlModifiers;
+ uint32_t FragmentRunEntryCount;
+ std::vector FragmentRunEntryTable;
+
+ uint32_t CurrentOffset = 8;
+ std::string temp;
+ afrt_fragmentrunentry TempEntry;
+ QualityEntryCount = Payload[CurrentOffset];
+ CurrentOffset ++;
+ for( uint8_t i = 0; i < QualityEntryCount; i++ ) {
+ temp = "";
+ while( Payload[CurrentOffset] != '\0' ) { temp += Payload[CurrentOffset]; CurrentOffset ++; }
+ QualitySegmentUrlModifiers.push_back(temp);
+ CurrentOffset++;
+ }
+ FragmentRunEntryCount = (Payload[CurrentOffset] << 24) + (Payload[CurrentOffset+1] << 16) + (Payload[CurrentOffset+2]) + (Payload[CurrentOffset+3]);
+ CurrentOffset +=4;
+ for( uint8_t i = 0; i < FragmentRunEntryCount; i ++ ) {
+ TempEntry.FirstFragment = (Payload[CurrentOffset] << 24) + (Payload[CurrentOffset+1] << 16) + (Payload[CurrentOffset+2]) + (Payload[CurrentOffset+3]);
+ CurrentOffset +=4;
+ TempEntry.FirstFragmentTimestamp_Upperhalf = (Payload[CurrentOffset] << 24) + (Payload[CurrentOffset+1] << 16) + (Payload[CurrentOffset+2]) + (Payload[CurrentOffset+3]);
+ CurrentOffset +=4;
+ TempEntry.FirstFragmentTimestamp = (Payload[CurrentOffset] << 24) + (Payload[CurrentOffset+1] << 16) + (Payload[CurrentOffset+2]) + (Payload[CurrentOffset+3]);
+ CurrentOffset +=4;
+ TempEntry.FragmentDuration = (Payload[CurrentOffset] << 24) + (Payload[CurrentOffset+1] << 16) + (Payload[CurrentOffset+2]) + (Payload[CurrentOffset+3]);
+ CurrentOffset +=4;
+ if( TempEntry.FragmentDuration == 0 ) {
+ TempEntry.DiscontinuityIndicator = Payload[CurrentOffset];
+ CurrentOffset++;
+ }
+ FragmentRunEntryTable.push_back(TempEntry);
+ }
+
+ std::cerr << "Box_AFRT:\n";
+ std::cerr << PrintOffset << " Version: " << (int)Version << "\n";
+ std::cerr << PrintOffset << " Flags: " << (int)Flags << "\n";
+ std::cerr << PrintOffset << " Timescale: " << (int)TimeScale << "\n";
+ std::cerr << PrintOffset << " QualityEntryCount: " << (int)QualityEntryCount << "\n";
+ std::cerr << PrintOffset << " QualitySegmentUrlModifiers:\n";
+ for( uint32_t i = 0; i < QualitySegmentUrlModifiers.size( ); i++ ) {
+ std::cerr << PrintOffset << " " << i+1 << ": " << QualitySegmentUrlModifiers[i] << "\n";
+ }
+ std::cerr << PrintOffset << " FragmentRunEntryCount: " << (int)FragmentRunEntryCount << "\n";
+ std::cerr << PrintOffset << " FragmentRunEntryTable:\n";
+ for( uint32_t i = 0; i < FragmentRunEntryTable.size( ); i++ ) {
+ std::cerr << PrintOffset << " " << i+1 << ":\n";
+ std::cerr << PrintOffset << " FirstFragment: " << FragmentRunEntryTable[i].FirstFragment << "\n";
+ std::cerr << PrintOffset << " FirstFragmentTimestamp: " << FragmentRunEntryTable[i].FirstFragmentTimestamp_Upperhalf << FragmentRunEntryTable[i].FirstFragmentTimestamp << "\n";
+ std::cerr << PrintOffset << " FragmentDuration: " << FragmentRunEntryTable[i].FragmentDuration << "\n";
+ if( FragmentRunEntryTable[i].FragmentDuration == 0 ) {
+ std::cerr << PrintOffset << " DiscontinuityIndicator: " << (int)FragmentRunEntryTable[i].DiscontinuityIndicator << "\n";
+ }
+ }
+ } else if ( header.BoxType == 0x6D646174 ) {
+ std::cerr << "mdat box containing " << PayloadSize << " bytes of payload" << std::endl;
+ } else {
+ std::cerr << "BoxType '"
+ << (char)(header.BoxType >> 24)
+ << (char)((header.BoxType << 8) >> 24)
+ << (char)((header.BoxType << 16) >> 24)
+ << (char)((header.BoxType << 24) >> 24)
+ << "' not yet implemented!\n";
+ }
+}
+
diff --git a/util/MP4/interface.cpp b/util/MP4/interface.cpp
index 8437913b..56b63040 100644
--- a/util/MP4/interface.cpp
+++ b/util/MP4/interface.cpp
@@ -547,13 +547,13 @@ std::string Interface::GenerateLiveBootstrap( uint32_t CurMediaTime ) {
afrt->SetUpdate(false);
afrt->SetTimeScale( 1000 );
afrt->AddQualityEntry( "" );
- afrt->AddFragmentRunEntry( 1, 1 , 4000 );
+ afrt->AddFragmentRunEntry( 1, 1 , 4000 ); //FirstFragment, FirstFragmentTimestamp,Fragment Duration in milliseconds
afrt->WriteContent( );
//SetUpASRT
asrt->SetUpdate(false);
asrt->AddQualityEntry( "" );
- asrt->AddSegmentRunEntry( 1, 199 );
+ asrt->AddSegmentRunEntry( 1, 199 );//1 Segment, 199 Fragments
asrt->WriteContent( );
//SetUpABST
@@ -562,9 +562,9 @@ std::string Interface::GenerateLiveBootstrap( uint32_t CurMediaTime ) {
abst->SetLive( true );
abst->SetUpdate( false );
abst->SetTimeScale( 1000 );
- abst->SetMediaTime( 596458 );
+ abst->SetMediaTime( CurMediaTime );
abst->SetSMPTE( 0 );
- abst->SetMovieIdentifier( "" );
+ abst->SetMovieIdentifier( "fifa" );
abst->SetDRM( "" );
abst->SetMetaData( "" );
abst->AddServerEntry( "" );
diff --git a/util/ddv_socket.cpp b/util/ddv_socket.cpp
index 0f26d36c..b1bd03e0 100644
--- a/util/ddv_socket.cpp
+++ b/util/ddv_socket.cpp
@@ -1,3 +1,4 @@
+#pragma once
#include
#include
#include
diff --git a/util/flv_data.cpp b/util/flv_data.cpp
new file mode 100644
index 00000000..28a18da4
--- /dev/null
+++ b/util/flv_data.cpp
@@ -0,0 +1,90 @@
+#include //for read()
+#include
+
+struct FLV_Pack {
+ int len;
+ int buf;
+ bool isKeyframe;
+ char * data;
+};//FLV_Pack
+
+char FLVHeader[13];
+bool All_Hell_Broke_Loose = false;
+
+//checks FLV Header for correctness
+//returns true if everything is alright, false otherwise
+bool FLV_Checkheader(char * header){
+ if (header[0] != 'F') return false;
+ if (header[1] != 'L') return false;
+ if (header[2] != 'V') return false;
+ if (header[8] != 0x09) return false;
+ if (header[9] != 0) return false;
+ if (header[10] != 0) return false;
+ if (header[11] != 0) return false;
+ if (header[12] != 0) return false;
+ return true;
+}//FLV_Checkheader
+
+//returns true if header is an FLV header
+bool FLV_Isheader(char * header){
+ if (header[0] != 'F') return false;
+ if (header[1] != 'L') return false;
+ if (header[2] != 'V') return false;
+ return true;
+}//FLV_Isheader
+
+bool ReadUntil(char * buffer, unsigned int count, unsigned int & sofar, char * D, unsigned int S, unsigned int & P){
+ if (sofar >= count){return true;}
+ int r = 0;
+ if (P+(count-sofar) > S){r = S-P;}else{r = count-sofar;}
+ memcpy(buffer+sofar, D+P, r);
+ P += r;
+ sofar += r;
+ if (sofar >= count){return true;}
+ return false;
+}
+
+//gets a packet, storing in given FLV_Pack pointer.
+//will assign pointer if null
+//resizes FLV_Pack data field bigger if data doesn't fit
+// (does not auto-shrink for speed!)
+bool FLV_GetPacket(FLV_Pack *& p, char * D, unsigned int S, unsigned int & P){
+ static bool done = true;
+ static unsigned int sofar = 0;
+ if (!p){p = (FLV_Pack*)calloc(1, sizeof(FLV_Pack));}
+ if (p->buf < 15){p->data = (char*)realloc(p->data, 15000000); p->buf = 15000000;}
+
+ if (done){
+ //read a header
+ if (ReadUntil(p->data, 11, sofar, D, S, P)){
+ //if its a correct FLV header, throw away and read tag header
+ if (FLV_Isheader(p->data)){
+ if (ReadUntil(p->data, 13, sofar, D, S, P)){
+ if (FLV_Checkheader(p->data)){
+ sofar = 0;
+ memcpy(FLVHeader, p->data, 13);
+ }else{All_Hell_Broke_Loose = true;}
+ }
+ }else{
+ //if a tag header, calculate length and read tag body
+ p->len = p->data[3] + 15;
+ p->len += (p->data[2] << 8);
+ p->len += (p->data[1] << 16);
+ //if (p->buf < p->len){p->data = (char*)realloc(p->data, p->len);p->buf = p->len;}
+ done = false;
+ }
+ }
+ }else{
+ //read tag body
+ if (ReadUntil(p->data, p->len, sofar, D, S, P)){
+ //calculate keyframeness, next time read header again, return true
+ p->isKeyframe = false;
+ if ((p->data[0] == 0x09) && (((p->data[11] & 0xf0) >> 4) == 1)){p->isKeyframe = true;}
+ done = true;
+ sofar = 0;
+ return true;
+ }
+ }
+ return false;
+}//FLV_GetPacket
+
diff --git a/util/http_parser.cpp b/util/http_parser.cpp
index 6f7d619f..36557fbd 100644
--- a/util/http_parser.cpp
+++ b/util/http_parser.cpp
@@ -1,10 +1,14 @@
+#pragma once
+#include "ddv_socket.cpp"
#include