Ogg 2 DTSC nearly working
This commit is contained in:
		
							parent
							
								
									d72b1ebbbf
								
							
						
					
					
						commit
						a0a6e957a5
					
				
					 2 changed files with 102 additions and 49 deletions
				
			
		|  | @ -27,6 +27,9 @@ namespace Analysers{ | ||||||
|           if (memcmp("theora",oggPage.getFullPayload() + 1,6) == 0){ |           if (memcmp("theora",oggPage.getFullPayload() + 1,6) == 0){ | ||||||
|             sn2Codec[oggPage.getBitstreamSerialNumber()] = "theora"; |             sn2Codec[oggPage.getBitstreamSerialNumber()] = "theora"; | ||||||
|           } |           } | ||||||
|  |           if (memcmp("vorbis",oggPage.getFullPayload() + 1,6) == 0){ | ||||||
|  |             sn2Codec[oggPage.getBitstreamSerialNumber()] = "vorbis"; | ||||||
|  |           } | ||||||
|         } |         } | ||||||
|         oggPage.setInternalCodec(sn2Codec[oggPage.getBitstreamSerialNumber()]); |         oggPage.setInternalCodec(sn2Codec[oggPage.getBitstreamSerialNumber()]); | ||||||
|         std::cout << oggPage.toPrettyString() << std::endl; |         std::cout << oggPage.toPrettyString() << std::endl; | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ | ||||||
| #include <mist/dtsc.h> | #include <mist/dtsc.h> | ||||||
| #include <mist/ogg.h> | #include <mist/ogg.h> | ||||||
| #include <mist/theora.h> | #include <mist/theora.h> | ||||||
|  | #include <mist/vorbis.h> | ||||||
| #include <mist/config.h> | #include <mist/config.h> | ||||||
| #include <mist/json.h> | #include <mist/json.h> | ||||||
| 
 | 
 | ||||||
|  | @ -15,13 +16,14 @@ namespace Converters{ | ||||||
| 
 | 
 | ||||||
|   class oggTrack{ |   class oggTrack{ | ||||||
|     public: |     public: | ||||||
|       oggTrack() : lastTime() { } |       oggTrack() : lastTime(), parsedHeaders(false) { } | ||||||
|       codecType codec; |       codecType codec; | ||||||
|       std::string name; |       std::string name; | ||||||
|       long long unsigned int dtscID; |       long long unsigned int dtscID; | ||||||
|       long long unsigned int lastTime; |       long long unsigned int lastTime; | ||||||
|  |       bool parsedHeaders; | ||||||
|       //Codec specific elements
 |       //Codec specific elements
 | ||||||
|       theora::header idHeader; |       theora::header idHeader;//needed to determine keyframe
 | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   int OGG2DTSC(){ |   int OGG2DTSC(){ | ||||||
|  | @ -30,13 +32,16 @@ namespace Converters{ | ||||||
|     //netpacked
 |     //netpacked
 | ||||||
|     //Read all of std::cin to oggBuffer
 |     //Read all of std::cin to oggBuffer
 | ||||||
|      |      | ||||||
|     //while stream busy
 |  | ||||||
|     JSON::Value DTSCOut; |     JSON::Value DTSCOut; | ||||||
|     JSON::Value DTSCHeader; |     JSON::Value DTSCHeader; | ||||||
|     DTSCHeader.null(); |     DTSCHeader.null(); | ||||||
|     DTSCHeader["moreheader"] = 0ll; |     DTSCHeader["moreheader"] = 0ll; | ||||||
|     std::map<long unsigned int, oggTrack> trackData; |     std::map<long unsigned int, oggTrack> trackData; | ||||||
|     long long int lastTrackID = 1; |     long long int lastTrackID = 1; | ||||||
|  |     int headerSeen = 0;  | ||||||
|  |     bool headerWritten = false;//important bool, used for outputting the simple DTSC header.
 | ||||||
|  |     bool allStreamsSeen = false; //other important bool used for error checking the EOS.
 | ||||||
|  |     //while stream busy
 | ||||||
|     while (std::cin.good()){ |     while (std::cin.good()){ | ||||||
|       for (unsigned int i = 0; (i < 1024) && (std::cin.good()); i++){//buffering
 |       for (unsigned int i = 0; (i < 1024) && (std::cin.good()); i++){//buffering
 | ||||||
|         oggBuffer += std::cin.get(); |         oggBuffer += std::cin.get(); | ||||||
|  | @ -47,9 +52,13 @@ namespace Converters{ | ||||||
|         if (oggPage.typeBOS()){//defines a new track
 |         if (oggPage.typeBOS()){//defines a new track
 | ||||||
|           std::cerr << "Begin "<< sNum << std::endl; |           std::cerr << "Begin "<< sNum << std::endl; | ||||||
|           if (memcmp(oggPage.getFullPayload()+1, "theora", 6) == 0){ |           if (memcmp(oggPage.getFullPayload()+1, "theora", 6) == 0){ | ||||||
|  |             headerSeen += 1; | ||||||
|  |             headerWritten = false; | ||||||
|             trackData[sNum].codec = THEORA; |             trackData[sNum].codec = THEORA; | ||||||
|             std::cerr << "Snr " << sNum << "=theora" << std::endl; |             std::cerr << "Snr " << sNum << "=theora" << std::endl; | ||||||
|           }else if(memcmp(oggPage.getFullPayload()+1, "vorbis", 6) == 0){ |           }else if(memcmp(oggPage.getFullPayload()+1, "vorbis", 6) == 0){ | ||||||
|  |             headerSeen += 1; | ||||||
|  |             headerWritten = false; | ||||||
|             std::cerr << "Snr " << sNum << "=vorbis" << std::endl; |             std::cerr << "Snr " << sNum << "=vorbis" << std::endl; | ||||||
|             trackData[sNum].codec = VORBIS; |             trackData[sNum].codec = VORBIS; | ||||||
|           }else{ |           }else{ | ||||||
|  | @ -63,60 +72,101 @@ namespace Converters{ | ||||||
|         } |         } | ||||||
|         //if Serial number is available in mapping
 |         //if Serial number is available in mapping
 | ||||||
|         if(trackData.find(sNum)!=trackData.end()){ |         if(trackData.find(sNum)!=trackData.end()){ | ||||||
|           //switch on codec
 |           int offset = 0; | ||||||
|           switch(trackData[sNum].codec){ |           for (std::deque<unsigned int>::iterator it = oggPage.getSegmentTableDeque().begin(); it != oggPage.getSegmentTableDeque().end(); it++){ | ||||||
|             case THEORA:{ |             if (trackData[sNum].parsedHeaders){ | ||||||
|               int offset = 0; |               //todo output segment
 | ||||||
|               theora::header tHead; |               //output DTSC packet
 | ||||||
|               fprintf(stderr, "Parsing %d elements\n", oggPage.getSegmentTableDeque().size()); |               DTSCOut.null();//clearing DTSC buffer
 | ||||||
|               for (std::deque<unsigned int>::iterator it = oggPage.getSegmentTableDeque().begin(); it != oggPage.getSegmentTableDeque().end(); it++){ |               DTSCOut["trackid"] = (long long)trackData[sNum].dtscID; | ||||||
|                 fprintf(stderr, "Parsing Snr %u: element of length %d\n", sNum, (*it)); |               long long unsigned int temp = oggPage.getGranulePosition(); | ||||||
|                 if(tHead.read(oggPage.getFullPayload()+offset, (*it))){//if the current segment is a header part
 |               DTSCOut["time"] = (long long)trackData[sNum].lastTime ++; | ||||||
|                   std::cerr << "Theora Header Segment " << tHead.getHeaderType() << std::endl; |               DTSCOut["data"] = std::string(oggPage.getFullPayload()+offset, (*it)); //segment content put in JSON
 | ||||||
|                   //fillDTSC header
 |               if (trackData[sNum].codec == THEORA){ | ||||||
|                   switch(tHead.getHeaderType()){ |                 if (trackData[sNum].idHeader.parseGranuleLower(temp) == 0){ //granule mask equals zero when on keyframe
 | ||||||
|                     case 0:{ //identification header
 |                   DTSCOut["keyframe"] = 1; | ||||||
|                       trackData[sNum].idHeader = tHead; |                 }else{ | ||||||
|                       break; |                   DTSCOut["interframe"] = 1; | ||||||
|                     } |  | ||||||
|                     case 1: //comment header
 |  | ||||||
|                       break; |  | ||||||
|                     case 2:{ //setup header, also the point to start writing the header
 |  | ||||||
|                       std::cout << DTSCHeader.toNetPacked(); |  | ||||||
|                       break; |  | ||||||
|                     } |  | ||||||
|                   } |  | ||||||
|                 }else{//if the current segment is a movie part
 |  | ||||||
|                   //output DTSC packet
 |  | ||||||
|                   DTSCOut.null();//clearing DTSC buffer
 |  | ||||||
|                   DTSCOut["trackid"] = (long long)trackData[sNum].dtscID; |  | ||||||
|                   long long unsigned int temp = oggPage.getGranulePosition(); |  | ||||||
|                   DTSCOut["time"] = (long long)trackData[sNum].lastTime ++; |  | ||||||
|                   DTSCOut["data"] = std::string(oggPage.getFullPayload()+offset, (*it)); //segment content put in JSON
 |  | ||||||
|                   if (trackData[sNum].idHeader.parseGranuleLower(temp) == 0){ //granule mask equals zero when on keyframe
 |  | ||||||
|                     DTSCOut["keyframe"] = 1; |  | ||||||
|                   }else{ |  | ||||||
|                     DTSCOut["interframe"] = 1; |  | ||||||
|                   } |  | ||||||
|                   fprintf(stderr,"Outputting a packet of %d bytes\n", (*it)); |  | ||||||
|                   std::cout << DTSCOut.toNetPacked(); |  | ||||||
|                 } |                 } | ||||||
|                 offset += (*it); |  | ||||||
|               } |               } | ||||||
|               if (trackData[sNum].lastTime != (trackData[sNum].idHeader.parseGranuleUpper(oggPage.getGranulePosition()) + trackData[sNum].idHeader.parseGranuleLower(oggPage.getGranulePosition()))){ |               std::cout << DTSCOut.toNetPacked(); | ||||||
| 
 |             }else{ | ||||||
|  |               //switch on codec
 | ||||||
|  |               switch(trackData[sNum].codec){ | ||||||
|  |                 case THEORA:{ | ||||||
|  |                   theora::header tHead; | ||||||
|  |                   if(tHead.read(oggPage.getFullPayload()+offset, (*it))){//if the current segment is a Theora header part
 | ||||||
|  |                     std::cerr << "Theora Header Segment " << tHead.getHeaderType() << std::endl; | ||||||
|  |                     //fillDTSC header
 | ||||||
|  |                     switch(tHead.getHeaderType()){ | ||||||
|  |                       case 0:{ //identification header
 | ||||||
|  |                         std::cerr << "Theora ID header found" << std::endl; | ||||||
|  |                         trackData[sNum].idHeader = tHead; | ||||||
|  |                         DTSCHeader["tracks"][trackData[sNum].name]["height"] = (long long)tHead.getPICH(); | ||||||
|  |                         DTSCHeader["tracks"][trackData[sNum].name]["width"] = (long long)tHead.getPICW(); | ||||||
|  |                         DTSCHeader["tracks"][trackData[sNum].name]["theoraID"] = std::string(oggPage.getFullPayload()+offset, (*it)); | ||||||
|  |                         break; | ||||||
|  |                       } | ||||||
|  |                       case 1: //comment header
 | ||||||
|  |                         std::cerr << "Theora comment header found" << std::endl; | ||||||
|  |                         break; | ||||||
|  |                       case 2:{ //setup header, also the point to start writing the header
 | ||||||
|  |                         DTSCHeader["tracks"][trackData[sNum].name]["codec"] = "theora"; | ||||||
|  |                         DTSCHeader["tracks"][trackData[sNum].name]["trackid"] = (long long)trackData[sNum].dtscID; | ||||||
|  |                         DTSCHeader["tracks"][trackData[sNum].name]["type"] = "video"; | ||||||
|  |                         DTSCHeader["tracks"][trackData[sNum].name]["init"] = std::string(oggPage.getFullPayload()+offset, (*it)); | ||||||
|  |                         headerSeen --; | ||||||
|  |                         trackData[sNum].parsedHeaders = true; | ||||||
|  |                         break; | ||||||
|  |                       } | ||||||
|  |                     } | ||||||
|  |                   }else{//if the current segment is a movie part
 | ||||||
|  |                   } | ||||||
|  |                   break; | ||||||
|  |                 } | ||||||
|  |                 case VORBIS:{ | ||||||
|  |                   vorbis::header vHead; | ||||||
|  |                     if(vHead.read(oggPage.getFullPayload()+offset, (*it))){//if the current segment is a Theora header part
 | ||||||
|  |                       switch(vHead.getHeaderType()){ | ||||||
|  |                         case 1:{ | ||||||
|  |                           std::cerr << "Vorbis ID header" << std::endl; | ||||||
|  |                           DTSCHeader["tracks"][trackData[sNum].name]["channels"] = (long long)vHead.getAudioChannels(); | ||||||
|  |                           break; | ||||||
|  |                         } | ||||||
|  |                         case 5:{ | ||||||
|  |                           std::cerr << "Vorbis init header" << std::endl; | ||||||
|  |                           DTSCHeader["tracks"][trackData[sNum].name]["codec"] = "vorbis"; | ||||||
|  |                           DTSCHeader["tracks"][trackData[sNum].name]["trackid"] = (long long)trackData[sNum].dtscID; | ||||||
|  |                           DTSCHeader["tracks"][trackData[sNum].name]["type"] = "audio"; | ||||||
|  |                           DTSCHeader["tracks"][trackData[sNum].name]["init"] = std::string(oggPage.getFullPayload()+offset, (*it)); | ||||||
|  |                           headerSeen --; | ||||||
|  |                           trackData[sNum].parsedHeaders = true; | ||||||
|  |                           break; | ||||||
|  |                         } | ||||||
|  |                       } | ||||||
|  |                     }else{ | ||||||
|  |                       //buffer vorbis
 | ||||||
|  |                     } | ||||||
|  |                   break; | ||||||
|  |                 } | ||||||
|  |                 default: | ||||||
|  |                   std::cerr << "Can not handle this codec" << std::endl; | ||||||
|  |                   break; | ||||||
|               } |               } | ||||||
|               break; |  | ||||||
|             } |             } | ||||||
|             case VORBIS: |             offset += (*it); | ||||||
|               break; |  | ||||||
|             default: |  | ||||||
|               std::cerr << "Can not handle this codec" << std::endl; |  | ||||||
|               break; |  | ||||||
|           } |           } | ||||||
|  | 
 | ||||||
|         }else{ |         }else{ | ||||||
|           std::cerr <<"Error! Unknown bitstream number " << oggPage.getBitstreamSerialNumber() << std::endl; |           std::cerr <<"Error! Unknown bitstream number " << oggPage.getBitstreamSerialNumber() << std::endl; | ||||||
|         } |         } | ||||||
|  |         //write header here
 | ||||||
|  |         if (headerSeen == 0 && headerWritten == false){ | ||||||
|  |           std::cout << DTSCHeader.toNetPacked(); | ||||||
|  |           headerWritten = true; | ||||||
|  |         } | ||||||
|  |         //write section buffer
 | ||||||
|  |         //write section
 | ||||||
|         if (oggPage.typeEOS()){//ending page
 |         if (oggPage.typeEOS()){//ending page
 | ||||||
|           std::cerr << oggPage.getBitstreamSerialNumber() << "  ending" << std::endl; |           std::cerr << oggPage.getBitstreamSerialNumber() << "  ending" << std::endl; | ||||||
|           trackData.erase(sNum); |           trackData.erase(sNum); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Oswald Auguste de Bruin
						Oswald Auguste de Bruin