예제 #1
0
 void TSOutput::fillPacket(const char * data, const size_t dataLen){
   
   if (!packData.getBytesFree()){
     ///\todo only resend the PAT/PMT for HLS
     if ( (sendRepeatingHeaders && packCounter % 42 == 0) || !packCounter){
       TS::Packet tmpPack;
       tmpPack.FromPointer(TS::PAT);
       tmpPack.setContinuityCounter(++contCounters[0]);
       sendTS(tmpPack.checkAndGetBuffer());
       sendTS(TS::createPMT(selectedTracks, myMeta, ++contCounters[4096]));
       packCounter += 2;
     }
     sendTS(packData.checkAndGetBuffer());
     packCounter ++;
     packData.clear();
   }
   
   if (!dataLen){return;}
   
   if (packData.getBytesFree() == 184){
     packData.clear();      
     packData.setPID(thisPacket.getTrackId());      
     packData.setContinuityCounter(++contCounters[packData.getPID()]);
     if (first[thisPacket.getTrackId()]){
       packData.setUnitStart(1);
       packData.setDiscontinuity(true);
       if (myMeta.tracks[thisPacket.getTrackId()].type == "video"){
         if (thisPacket.getInt("keyframe")){
           packData.setRandomAccess(1);
         }      
         packData.setPCR(thisPacket.getTime() * 27000);      
       }
       first[thisPacket.getTrackId()] = false;
     }
   }
   
   int tmp = packData.fillFree(data, dataLen);     
   if (tmp != dataLen){
     return fillPacket(data+tmp, dataLen-tmp);
   }
 }
예제 #2
0
 void TSOutput::fillPacket(char const * data, size_t dataLen, bool & firstPack, bool video, bool keyframe, uint32_t pkgPid, int & contPkg){
   do {
     if (!packData.getBytesFree()){
       if ( (sendRepeatingHeaders && packCounter % 42 == 0) || !packCounter){
         TS::Packet tmpPack;
         tmpPack.FromPointer(TS::PAT);
         tmpPack.setContinuityCounter(++contPAT);
         sendTS(tmpPack.checkAndGetBuffer());
         sendTS(TS::createPMT(selectedTracks, myMeta, ++contPMT));
         packCounter += 2;
       }
       sendTS(packData.checkAndGetBuffer());
       packCounter ++;
       packData.clear();
     }
     
     if (!dataLen){return;}
     
     if (packData.getBytesFree() == 184){
       packData.clear();
       packData.setPID(pkgPid);
       packData.setContinuityCounter(++contPkg);
       if (firstPack){
         packData.setUnitStart(1);
         if (video){
           if (keyframe){
             packData.setRandomAccess(true);
             packData.setESPriority(true);
           }      
           packData.setPCR(thisPacket.getTime() * 27000);      
         }
         firstPack = false;
       }
     }
     
     int tmp = packData.fillFree(data, dataLen);
     data += tmp;
     dataLen -= tmp;
   } while(dataLen);
 }
예제 #3
0
 void TSOutput::sendNext(){
   first[thisPacket.getTrackId()] = true;
   char * dataPointer = 0;
   unsigned int dataLen = 0;
   thisPacket.getString("data", dataPointer, dataLen); //data
   if (thisPacket.getTime() >= until){ //this if should only trigger for HLS       
     stop();
     wantRequest = true;
     parseData = false;
     sendTS("",0);      
     return;
   }
   std::string bs;
   //prepare bufferstring    
   if (myMeta.tracks[thisPacket.getTrackId()].type == "video"){      
     unsigned int extraSize = 0;      
     //dataPointer[4] & 0x1f is used to check if this should be done later: fillPacket("\000\000\000\001\011\360", 6);
     if (myMeta.tracks[thisPacket.getTrackId()].codec == "H264" && (dataPointer[4] & 0x1f) != 0x09){
       extraSize += 6;
     }
     if (thisPacket.getInt("keyframe")){
       if (myMeta.tracks[thisPacket.getTrackId()].codec == "H264"){
         if (!haveAvcc){
           avccbox.setPayload(myMeta.tracks[thisPacket.getTrackId()].init);
           haveAvcc = true;
         }
         bs = avccbox.asAnnexB();
         extraSize += bs.size();
       }
     }
     
     unsigned int watKunnenWeIn1Ding = 65490-13;
     unsigned int splitCount = (dataLen+extraSize) / watKunnenWeIn1Ding;
     unsigned int currPack = 0;
     unsigned int ThisNaluSize = 0;
     unsigned int i = 0;
     unsigned int nalLead = 0;
     
     while (currPack <= splitCount){
       unsigned int alreadySent = 0;
       long long unsigned int tempTime = thisPacket.getTime();
       if (appleCompat){tempTime -= ts_from;}
       bs = TS::Packet::getPESVideoLeadIn((currPack != splitCount ? watKunnenWeIn1Ding : dataLen+extraSize - currPack*watKunnenWeIn1Ding), tempTime * 90, thisPacket.getInt("offset") * 90, !currPack);
       fillPacket(bs.data(), bs.size());
       if (!currPack){
         if (myMeta.tracks[thisPacket.getTrackId()].codec == "H264" && (dataPointer[4] & 0x1f) != 0x09){
           //End of previous nal unit, if not already present
           fillPacket("\000\000\000\001\011\360", 6);
           alreadySent += 6;
         }
         if (thisPacket.getInt("keyframe")){
           if (myMeta.tracks[thisPacket.getTrackId()].codec == "H264"){
             bs = avccbox.asAnnexB();
             fillPacket(bs.data(), bs.size());
             alreadySent += bs.size();
           }
         }
       }
       while (i + 4 < (unsigned int)dataLen){
         if (nalLead){
           fillPacket("\000\000\000\001"+4-nalLead,nalLead);
           i += nalLead;
           alreadySent += nalLead;
           nalLead = 0;
         }
         if (!ThisNaluSize){
           ThisNaluSize = (dataPointer[i] << 24) + (dataPointer[i+1] << 16) + (dataPointer[i+2] << 8) + dataPointer[i+3];
           if (ThisNaluSize + i + 4 > (unsigned int)dataLen){
             DEBUG_MSG(DLVL_WARN, "Too big NALU detected (%u > %d) - skipping!", ThisNaluSize + i + 4, dataLen);
             break;
           }
           if (alreadySent + 4 > watKunnenWeIn1Ding){
             nalLead = 4 - (watKunnenWeIn1Ding-alreadySent);
             fillPacket("\000\000\000\001",watKunnenWeIn1Ding-alreadySent);
             i += watKunnenWeIn1Ding-alreadySent;
             alreadySent += watKunnenWeIn1Ding-alreadySent;
           }else{
             fillPacket("\000\000\000\001",4);
             alreadySent += 4;
             i += 4;
           }
         }
         if (alreadySent + ThisNaluSize > watKunnenWeIn1Ding){
           fillPacket(dataPointer+i,watKunnenWeIn1Ding-alreadySent);
           i += watKunnenWeIn1Ding-alreadySent;
           ThisNaluSize -= watKunnenWeIn1Ding-alreadySent;
           alreadySent += watKunnenWeIn1Ding-alreadySent;
         }else{
           fillPacket(dataPointer+i,ThisNaluSize);
           alreadySent += ThisNaluSize;
           i += ThisNaluSize;
           ThisNaluSize = 0;
         }          
         if (alreadySent == watKunnenWeIn1Ding){
           packData.addStuffing();
           fillPacket(0, 0);
           first[thisPacket.getTrackId()] = true;
           break;
         }
       }
       currPack++;
     }
   }else if (myMeta.tracks[thisPacket.getTrackId()].type == "audio"){
     long unsigned int tempLen = dataLen;
     if ( myMeta.tracks[thisPacket.getTrackId()].codec == "AAC"){
       tempLen += 7;
     }
     long long unsigned int tempTime;
     if (appleCompat){
       tempTime = 0;// myMeta.tracks[thisPacket.getTrackId()].rate / 1000;
     }else{
       tempTime = thisPacket.getTime() * 90;
     }
     bs = TS::Packet::getPESAudioLeadIn(tempLen, tempTime);// myMeta.tracks[thisPacket.getTrackId()].rate / 1000 );
     fillPacket(bs.data(), bs.size());
     if (myMeta.tracks[thisPacket.getTrackId()].codec == "AAC"){        
       bs = TS::getAudioHeader(dataLen, myMeta.tracks[thisPacket.getTrackId()].init);      
       fillPacket(bs.data(), bs.size());
     }
     fillPacket(dataPointer,dataLen);
   }
   if (packData.getBytesFree() < 184){
     packData.addStuffing();
     fillPacket(0, 0);
   }
 }