TS optimize, specifically MPEG2 speedup
This commit is contained in:
		
							parent
							
								
									df6862fb0a
								
							
						
					
					
						commit
						6e2e7d81b2
					
				
					 2 changed files with 54 additions and 61 deletions
				
			
		
							
								
								
									
										106
									
								
								lib/nal.cpp
									
										
									
									
									
								
							
							
						
						
									
										106
									
								
								lib/nal.cpp
									
										
									
									
									
								
							| 
						 | 
					@ -3,17 +3,17 @@
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#include <cstdlib>
 | 
					#include <cstdlib>
 | 
				
			||||||
#include <cstring>
 | 
					#include <cstring>
 | 
				
			||||||
#include <math.h>//for log
 | 
					#include <math.h> //for log
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "nal.h"
 | 
					 | 
				
			||||||
#include "bitstream.h"
 | 
					 | 
				
			||||||
#include "bitfields.h"
 | 
					#include "bitfields.h"
 | 
				
			||||||
 | 
					#include "bitstream.h"
 | 
				
			||||||
#include "defines.h"
 | 
					#include "defines.h"
 | 
				
			||||||
 | 
					#include "nal.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace nalu {
 | 
					namespace nalu{
 | 
				
			||||||
  std::deque<int> parseNalSizes(DTSC::Packet & pack){
 | 
					  std::deque<int> parseNalSizes(DTSC::Packet &pack){
 | 
				
			||||||
    std::deque<int> result;
 | 
					    std::deque<int> result;
 | 
				
			||||||
    char * data;
 | 
					    char *data;
 | 
				
			||||||
    unsigned int dataLen;
 | 
					    unsigned int dataLen;
 | 
				
			||||||
    pack.getString("data", data, dataLen);
 | 
					    pack.getString("data", data, dataLen);
 | 
				
			||||||
    int offset = 0;
 | 
					    int offset = 0;
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,7 @@ namespace nalu {
 | 
				
			||||||
    return result;
 | 
					    return result;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::string removeEmulationPrevention(const std::string & data) {
 | 
					  std::string removeEmulationPrevention(const std::string &data){
 | 
				
			||||||
    std::string result;
 | 
					    std::string result;
 | 
				
			||||||
    result.resize(data.size());
 | 
					    result.resize(data.size());
 | 
				
			||||||
    result[0] = data[0];
 | 
					    result[0] = data[0];
 | 
				
			||||||
| 
						 | 
					@ -33,76 +33,71 @@ namespace nalu {
 | 
				
			||||||
    unsigned int dataPtr = 2;
 | 
					    unsigned int dataPtr = 2;
 | 
				
			||||||
    unsigned int dataLen = data.size();
 | 
					    unsigned int dataLen = data.size();
 | 
				
			||||||
    unsigned int resPtr = 2;
 | 
					    unsigned int resPtr = 2;
 | 
				
			||||||
    while (dataPtr + 2 < dataLen) {
 | 
					    while (dataPtr + 2 < dataLen){
 | 
				
			||||||
      if (!data[dataPtr] && !data[dataPtr + 1] && data[dataPtr + 2] == 3){ //We have found an emulation prevention
 | 
					      if (!data[dataPtr] && !data[dataPtr + 1] &&
 | 
				
			||||||
 | 
					          data[dataPtr + 2] == 3){// We have found an emulation prevention
 | 
				
			||||||
        result[resPtr++] = data[dataPtr++];
 | 
					        result[resPtr++] = data[dataPtr++];
 | 
				
			||||||
        result[resPtr++] = data[dataPtr++];
 | 
					        result[resPtr++] = data[dataPtr++];
 | 
				
			||||||
        dataPtr++; //Skip the emulation prevention byte
 | 
					        dataPtr++; // Skip the emulation prevention byte
 | 
				
			||||||
      } else {
 | 
					      }else{
 | 
				
			||||||
        result[resPtr++] = data[dataPtr++];
 | 
					        result[resPtr++] = data[dataPtr++];
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (dataPtr < dataLen){
 | 
					    while (dataPtr < dataLen){result[resPtr++] = data[dataPtr++];}
 | 
				
			||||||
      result[resPtr++] = data[dataPtr++];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return result.substr(0, resPtr);
 | 
					    return result.substr(0, resPtr);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  unsigned long toAnnexB(const char * data, unsigned long dataSize, char *& result){
 | 
					  unsigned long toAnnexB(const char *data, unsigned long dataSize, char *&result){
 | 
				
			||||||
    //toAnnexB keeps the same size.
 | 
					    // toAnnexB keeps the same size.
 | 
				
			||||||
    if (!result){
 | 
					    if (!result){result = (char *)malloc(dataSize);}
 | 
				
			||||||
      result = (char *)malloc(dataSize);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    int offset = 0;
 | 
					    int offset = 0;
 | 
				
			||||||
    while (offset < dataSize){
 | 
					    while (offset < dataSize){
 | 
				
			||||||
      //Read unit size
 | 
					      // Read unit size
 | 
				
			||||||
      unsigned long unitSize = Bit::btohl(data + offset);
 | 
					      unsigned long unitSize = Bit::btohl(data + offset);
 | 
				
			||||||
      //Write annex b header
 | 
					      // Write annex b header
 | 
				
			||||||
      memset(result + offset, 0x00, 3);
 | 
					      memset(result + offset, 0x00, 3);
 | 
				
			||||||
      result[offset + 3] = 0x01;
 | 
					      result[offset + 3] = 0x01;
 | 
				
			||||||
      //Copy the nal unit
 | 
					      // Copy the nal unit
 | 
				
			||||||
      memcpy(result + offset + 4, data + offset + 4, unitSize);
 | 
					      memcpy(result + offset + 4, data + offset + 4, unitSize);
 | 
				
			||||||
      //Update the offset
 | 
					      // Update the offset
 | 
				
			||||||
      offset += 4 + unitSize;
 | 
					      offset += 4 + unitSize;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return dataSize;
 | 
					    return dataSize;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///Scans data for the last non-zero byte, returning a pointer to it.
 | 
					  /// Scans data for the last non-zero byte, returning a pointer to it.
 | 
				
			||||||
  const char* nalEndPosition(const char * data, uint32_t dataSize){
 | 
					  const char *nalEndPosition(const char *data, uint32_t dataSize){
 | 
				
			||||||
    while(dataSize > 0 && memcmp(data+dataSize-1, "\000",1) == 0 ){
 | 
					    while (dataSize && !data[dataSize - 1]){--dataSize;}
 | 
				
			||||||
      dataSize--;
 | 
					    return data + dataSize;
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return data+dataSize;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///Scan data for Annex B start code. Returns pointer to it when found, null otherwise.
 | 
					  /// Scan data for Annex B start code. Returns pointer to it when found, null otherwise.
 | 
				
			||||||
  const char * scanAnnexB(const char * data, uint32_t dataSize){
 | 
					  const char *scanAnnexB(const char *data, uint32_t dataSize){
 | 
				
			||||||
    char * offset = (char*)data;
 | 
					    char *offset = (char *)data;
 | 
				
			||||||
    const char * maxData = data + dataSize - 2;
 | 
					    const char *maxData = data + dataSize - 2;
 | 
				
			||||||
    while(offset < maxData){
 | 
					    while (offset < maxData){
 | 
				
			||||||
      if (offset[2] > 1){
 | 
					      if (offset[2] > 1){
 | 
				
			||||||
        //We have no zero in the third byte, so we need to skip at least 3 bytes forward
 | 
					        // We have no zero in the third byte, so we need to skip at least 3 bytes forward
 | 
				
			||||||
        offset += 3;
 | 
					        offset += 3;
 | 
				
			||||||
        continue;
 | 
					        continue;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (!offset[2]){
 | 
					      if (!offset[2]){
 | 
				
			||||||
        //We skip forward 1 or 2 bytes depending on contents of the second byte
 | 
					        // We COULD skip forward 1 or 2 bytes depending on contents of the second byte
 | 
				
			||||||
        offset += (offset[1]?2:1);
 | 
					        // offset += (offset[1]?2:1);
 | 
				
			||||||
 | 
					        //... but skipping a single byte (removing the 'if') is actually faster (benchmarked).
 | 
				
			||||||
 | 
					        ++offset;
 | 
				
			||||||
        continue;
 | 
					        continue;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (!offset[0] && !offset[1]){
 | 
					      if (!offset[0] && !offset[1]){return offset;}
 | 
				
			||||||
        return offset;
 | 
					      // We have no zero in the third byte, so we need to skip at least 3 bytes forward
 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      //We have no zero in the third byte, so we need to skip at least 3 bytes forward
 | 
					 | 
				
			||||||
      offset += 3;
 | 
					      offset += 3;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  unsigned long fromAnnexB(const char * data, unsigned long dataSize, char *& result){
 | 
					  unsigned long fromAnnexB(const char *data, unsigned long dataSize, char *&result){
 | 
				
			||||||
    const char * lastCheck = data + dataSize - 3;
 | 
					    const char *lastCheck = data + dataSize - 3;
 | 
				
			||||||
    if (!result){
 | 
					    if (!result){
 | 
				
			||||||
      FAIL_MSG("No output buffer given to FromAnnexB");
 | 
					      FAIL_MSG("No output buffer given to FromAnnexB");
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
| 
						 | 
					@ -110,26 +105,20 @@ namespace nalu {
 | 
				
			||||||
    int offset = 0;
 | 
					    int offset = 0;
 | 
				
			||||||
    int newOffset = 0;
 | 
					    int newOffset = 0;
 | 
				
			||||||
    while (offset < dataSize){
 | 
					    while (offset < dataSize){
 | 
				
			||||||
      const char * begin = data + offset;
 | 
					      const char *begin = data + offset;
 | 
				
			||||||
      while ( begin < lastCheck && !(!begin[0] && !begin[1] && begin[2] == 0x01)){
 | 
					      while (begin < lastCheck && !(!begin[0] && !begin[1] && begin[2] == 0x01)){
 | 
				
			||||||
        begin++;
 | 
					 | 
				
			||||||
        if (begin < lastCheck && begin[0]){
 | 
					 | 
				
			||||||
        begin++;
 | 
					        begin++;
 | 
				
			||||||
 | 
					        if (begin < lastCheck && begin[0]){begin++;}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      }
 | 
					      begin += 3; // Initialize begin after the first 0x000001 pattern.
 | 
				
			||||||
      begin += 3;//Initialize begin after the first 0x000001 pattern.
 | 
					 | 
				
			||||||
      if (begin > data + dataSize){
 | 
					      if (begin > data + dataSize){
 | 
				
			||||||
        offset = dataSize;
 | 
					        offset = dataSize;
 | 
				
			||||||
        continue;
 | 
					        continue;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      const char * end = (const char*)memmem(begin, dataSize - (begin - data), "\000\000\001", 3);
 | 
					      const char *end = (const char *)memmem(begin, dataSize - (begin - data), "\000\000\001", 3);
 | 
				
			||||||
      if (!end) {
 | 
					      if (!end){end = data + dataSize;}
 | 
				
			||||||
        end = data + dataSize;
 | 
					      // Check for 4-byte lead in's. Yes, we access -1 here
 | 
				
			||||||
      }
 | 
					      if (end > begin && (end - data) != dataSize && end[-1] == 0x00){end--;}
 | 
				
			||||||
      //Check for 4-byte lead in's. Yes, we access -1 here
 | 
					 | 
				
			||||||
      if (end > begin && (end - data) != dataSize && end[-1] == 0x00){
 | 
					 | 
				
			||||||
        end--;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      unsigned int nalSize = end - begin;
 | 
					      unsigned int nalSize = end - begin;
 | 
				
			||||||
      Bit::htobl(result + newOffset, nalSize);
 | 
					      Bit::htobl(result + newOffset, nalSize);
 | 
				
			||||||
      memcpy(result + newOffset + 4, begin, nalSize);
 | 
					      memcpy(result + newOffset + 4, begin, nalSize);
 | 
				
			||||||
| 
						 | 
					@ -139,4 +128,5 @@ namespace nalu {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return newOffset;
 | 
					    return newOffset;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}// namespace nalu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -132,8 +132,8 @@ namespace TS{
 | 
				
			||||||
    int tid = newPack.getPID();
 | 
					    int tid = newPack.getPID();
 | 
				
			||||||
    bool unitStart = newPack.getUnitStart();
 | 
					    bool unitStart = newPack.getUnitStart();
 | 
				
			||||||
    std::deque<Packet> & PS = pesStreams[tid];
 | 
					    std::deque<Packet> & PS = pesStreams[tid];
 | 
				
			||||||
    if ((pidToCodec.count(tid) || tid == 0 || newPack.isPMT()) &&
 | 
					    if ((unitStart || PS.size()) &&
 | 
				
			||||||
        (unitStart || PS.size())){
 | 
					        (tid == 0 || newPack.isPMT() || pidToCodec.count(tid))){
 | 
				
			||||||
      PS.push_back(newPack);
 | 
					      PS.push_back(newPack);
 | 
				
			||||||
      if (unitStart){
 | 
					      if (unitStart){
 | 
				
			||||||
        pesPositions[tid].push_back(bytePos);
 | 
					        pesPositions[tid].push_back(bytePos);
 | 
				
			||||||
| 
						 | 
					@ -667,13 +667,16 @@ namespace TS{
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      while (nextPtr < pesEnd){
 | 
					      uint32_t nalno = 0;
 | 
				
			||||||
 | 
					      //We only check the first 8 packets, because keys should always be near the front of a PES.
 | 
				
			||||||
 | 
					      while (nextPtr < pesEnd && nalno < 8){
 | 
				
			||||||
        if (!nextPtr){nextPtr = pesEnd;}
 | 
					        if (!nextPtr){nextPtr = pesEnd;}
 | 
				
			||||||
        //Calculate size of NAL unit, removing null bytes from the end
 | 
					        //Calculate size of NAL unit, removing null bytes from the end
 | 
				
			||||||
        nalSize = nalu::nalEndPosition(pesPayload, nextPtr - pesPayload) - pesPayload;
 | 
					        nalSize = nalu::nalEndPosition(pesPayload, nextPtr - pesPayload) - pesPayload;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Check if this is a keyframe
 | 
					        // Check if this is a keyframe
 | 
				
			||||||
        parseNal(tid, pesPayload, nextPtr, isKeyFrame);
 | 
					        parseNal(tid, pesPayload, nextPtr, isKeyFrame);
 | 
				
			||||||
 | 
					        ++nalno;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (((nextPtr - pesPayload) + 3) >= realPayloadSize){break;}//end of the loop
 | 
					        if (((nextPtr - pesPayload) + 3) >= realPayloadSize){break;}//end of the loop
 | 
				
			||||||
        realPayloadSize -= ((nextPtr - pesPayload) + 3); // decrease the total size
 | 
					        realPayloadSize -= ((nextPtr - pesPayload) + 3); // decrease the total size
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue