///\brief Builds a bootstrap for use in HTTP Dynamic streaming.
  ///\param streamName The name of the stream.
  ///\param metadata The current metadata, used to generate the index.
  ///\param fragnum The index of the current fragment
  ///\return The generated bootstrap.
  std::string dynamicBootstrap(std::string & streamName, JSON::Value & metadata, int fragnum = 0){
    std::string empty;

    MP4::ASRT asrt;
    asrt.setUpdate(false);
    asrt.setVersion(1);
    //asrt.setQualityEntry(empty, 0);
    if (metadata.isMember("live")){
      asrt.setSegmentRun(1, 4294967295ul, 0);
    }else{
      asrt.setSegmentRun(1, metadata["keytime"].size(), 0);
    }

    MP4::AFRT afrt;
    afrt.setUpdate(false);
    afrt.setVersion(1);
    afrt.setTimeScale(1000);
    //afrt.setQualityEntry(empty, 0);
    MP4::afrt_runtable afrtrun;
    if (metadata.isMember("live")){
      // restrict data to last 2 fragments, unless an earlier fragment was expressly requested.
      int count = 0;
      unsigned int begin = std::max(0u, metadata["keynum"].size() - 3);
      while (begin > 0 && fragnum && metadata["keynum"][begin].asInt() > fragnum){
        begin--;
      }
      for (int i = begin; i < metadata["keynum"].size(); i++){
        afrtrun.firstFragment = metadata["keynum"][i].asInt();
        afrtrun.firstTimestamp = metadata["keytime"][i].asInt();
        afrtrun.duration = metadata["keylen"][i].asInt();
        afrt.setFragmentRun(afrtrun, count++);
      }
    }else{
      for (int i = 0; i < metadata["keynum"].size(); i++){
        afrtrun.firstFragment = metadata["keynum"][i].asInt();
        afrtrun.firstTimestamp = metadata["keytime"][i].asInt();
        afrtrun.duration = metadata["keylen"][i].asInt();
        afrt.setFragmentRun(afrtrun, i);
      }
    }

    MP4::ABST abst;
    abst.setVersion(1);
    abst.setBootstrapinfoVersion(1);
    abst.setProfile(0);
    abst.setUpdate(false);
    abst.setTimeScale(1000);
    abst.setLive(false);
    abst.setCurrentMediaTime(metadata["lastms"].asInt());
    abst.setSmpteTimeCodeOffset(0);
    abst.setMovieIdentifier(streamName);
    abst.setSegmentRunTable(asrt, 0);
    abst.setFragmentRunTable(afrt, 0);

#if DEBUG >= 8
    std::cout << "Sending bootstrap:" << std::endl << abst.toPrettyString(0) << std::endl;
#endif
    return std::string((char*)abst.asBox(), (int)abst.boxedSize());
  }
示例#2
0
 ///\brief Builds a bootstrap for use in HTTP Dynamic streaming.
 ///\param tid The track this bootstrap is generated for.
 ///\return The generated bootstrap.
 std::string OutHDS::dynamicBootstrap(int tid){
   updateMeta();
   std::string empty;
   
   MP4::ASRT asrt;
   asrt.setUpdate(false);
   asrt.setVersion(1);
   //asrt.setQualityEntry(empty, 0);
   if (myMeta.live){
     asrt.setSegmentRun(1, 4294967295ul, 0);
   }else{
     asrt.setSegmentRun(1, myMeta.tracks[tid].fragments.size(), 0);
   }
   
   MP4::AFRT afrt;
   afrt.setUpdate(false);
   afrt.setVersion(1);
   afrt.setTimeScale(1000);
   //afrt.setQualityEntry(empty, 0);
   MP4::afrt_runtable afrtrun;
   int i = 0;
   int j = 0;
   if (myMeta.tracks[tid].fragments.size()){
     std::deque<DTSC::Fragment>::iterator fragIt = myMeta.tracks[tid].fragments.begin();
     unsigned int firstTime = myMeta.tracks[tid].getKey(fragIt->getNumber()).getTime();
     while (fragIt != myMeta.tracks[tid].fragments.end()){
       if (myMeta.vod || fragIt->getDuration() > 0){
         afrtrun.firstFragment = myMeta.tracks[tid].missedFrags + j + 1;
         afrtrun.firstTimestamp = myMeta.tracks[tid].getKey(fragIt->getNumber()).getTime() - firstTime;
         if (fragIt->getDuration() > 0){
           afrtrun.duration = fragIt->getDuration();
         }else{
           afrtrun.duration = myMeta.tracks[tid].lastms - afrtrun.firstTimestamp;
         }
         afrt.setFragmentRun(afrtrun, i);
         ++i;
       }
       ++j;
       ++fragIt;
     }
   }
   
   MP4::ABST abst;
   abst.setVersion(1);
   abst.setBootstrapinfoVersion(1);
   abst.setProfile(0);
   abst.setUpdate(false);
   abst.setTimeScale(1000);
   abst.setLive(myMeta.live);
   abst.setCurrentMediaTime(myMeta.tracks[tid].lastms);
   abst.setSmpteTimeCodeOffset(0);
   abst.setMovieIdentifier(streamName);
   abst.setSegmentRunTable(asrt, 0);
   abst.setFragmentRunTable(afrt, 0);
   
   DEBUG_MSG(DLVL_VERYHIGH, "Sending bootstrap: %s", abst.toPrettyString(0).c_str());
   return std::string((char*)abst.asBox(), (int)abst.boxedSize());
 }
示例#3
0
/// Generates a bootstrap equal to the above file, then compares.
/// \returns Zero if they are equal (test success), other values otherwise.
int main(int argc, char ** argv) {
  std::string temp;

  MP4::ASRT asrt;
  asrt.setVersion(1);
  asrt.setQualityEntry(temp, 0);
  asrt.setSegmentRun(1, 199, 0);

  MP4::AFRT afrt;
  afrt.setVersion(1);
  afrt.setTimeScale(1000);
  afrt.setQualityEntry(temp, 0);
  MP4::afrt_runtable afrtrun;
  for (int i = 0; i < 198; i++){
    afrtrun.firstFragment = i+1;
    afrtrun.firstTimestamp = 3000*i;
    afrtrun.duration = 3000;
    afrt.setFragmentRun(afrtrun, i);
  }
  afrtrun.firstFragment = 199;
  afrtrun.firstTimestamp = 594000;
  afrtrun.duration = 2458;
  afrt.setFragmentRun(afrtrun, 198);

  MP4::ABST abst;
  abst.setVersion(1);
  abst.setBootstrapinfoVersion(1);
  abst.setProfile(0);
  abst.setLive(false);
  abst.setUpdate(false);
  abst.setTimeScale(1000);
  abst.setCurrentMediaTime(596458);
  abst.setSmpteTimeCodeOffset(0);
  abst.setMovieIdentifier(temp);
  abst.setServerEntry(temp, 0);
  abst.setQualityEntry(temp, 0);
  abst.setDrmData(temp);
  abst.setMetaData(temp);
  abst.setSegmentRunTable(asrt, 0);
  abst.setFragmentRunTable(afrt, 0);

  if (abst.boxedSize() != __data_len){return 42;}
  return memcmp(abst.asBox(), __data, __data_len);
}