コード例 #1
0
ファイル: genindex.c プロジェクト: suborb/reelvdr
void cGenIndex::Work(void)
{
  eof=error=pstart=false;
  memset(fileSize,0,sizeof(fileSize));

  if(rewrite) {
    writeFile=writeName->OpenWrite();
    if(writeFile<0) {
      printf("Failed to open output file(s)\n");
      return;
      }
    }

  replayFile=fileName->Open();
  readNo=fileName->FileNumber();
  fileSize[readNo]=fileName->FileSize();
  readOffset=0;

  fileNo=rewrite ? 1 : readNo;
  fileOffset=0;
  splitOffset=splitsize*MEGABYTE(1);
  sSize=0;

  if(replayFile>=0) {
    if(index->Open()) {
      int lastoff=0;
      while(!error && NextFile()) {
        int count=read(replayFile,buff,sizeof(buff));
        if(count<0) {
          printf("read vdr: %s\n",strerror(errno));
          return;
          }
        else if(count==0) {
          if(fileSize[readNo]!=readOffset)
            printf("file %d read/size mismatch\n",readNo);
          eof=true;
          continue;
          }
        else {
          readOffset+=count;

          if(!quiet && (readOffset<lastoff || readOffset>lastoff+KILOBYTE(256)) && fileSize[readNo]) {
            printf("offset %lld %d%%\r",readOffset,(int)(readOffset*100/fileSize[readNo])); fflush(stdout);
            lastoff=readOffset;
            }

          int used=Process(buff,count);
          if(used<0) {
            error=true;
            break;
            }
          if(count-used) printf("bummer, count!=0\n");
          }
        }
      if(!error && !quiet) Statistics();
      }
    }
  else printf("Failed to open input file(s)\n");
}
コード例 #2
0
ファイル: recorder.c プロジェクト: signal2noise/vdr-mirror
void cFileWriter::Action(void)
{
  time_t t = time(NULL);
  unsigned int skipped = 0;

  while (Running()) {
        int Count;
        uchar *p = remux->Get(Count, &pictureType, 1);

        while(skipped < 10 && (remux->SFmode() == SF_UNKNOWN || remux->TSmode() == rAuto)){ // TB: give remuxer a chance to detect the stream type
           skipped++;
           Count = 0;
           continue;
        }
	
        if (p && Count) {
//		esyslog("COUNT %i\n", Count);
           if (!Running() && pictureType == I_FRAME) // finish the recording before the next 'I' frame
              break;
           if (NextFile()) {
#if 1
              // Add PAT+PMT at every filestart and every MB
              if ((!fileSize || diffSize > PATPMT_DISTANCE) && remux->TSmode()==SF_H264) {
		      uchar patpmt[2*188];
		      int plen;
		      plen=remux->GetPATPMT(patpmt, 2*188);
		      if (plen) {
			      if (recordFile->Write(patpmt, plen) < 0) {
				      LOG_ERROR_STR(fileName->Name());
				      break;
			      }
			      fileSize+=plen;
		      }
		      diffSize=0;
	      }
#endif
              if (index && pictureType != NO_PICTURE)
                 index->Write(pictureType, fileName->Number(), fileSize);
              if (recordFile->Write(p, Count) < 0) {
                 LOG_ERROR_STR(fileName->Name());
                 break;
                 }
              fileSize += Count;
              diffSize += Count;
              remux->Del(Count);
              }
           else
              break;
           t = time(NULL);
           }
        else if (time(NULL) - t > MAXBROKENTIMEOUT) {
           esyslog("ERROR: video data stream broken");
           //cThread::EmergencyExit(true);
	   Skins.Message(mtError, tr("can't record - check your configuration"));
           t = time(NULL);
           }
        }
}
コード例 #3
0
ファイル: dvbplayer.c プロジェクト: Lexus34/tdt-arp
bool cDvbPlayer::NextFile(uint16_t FileNumber, off_t FileOffset)
{
  if (FileNumber > 0)
     replayFile = fileName->SetOffset(FileNumber, FileOffset);
  else if (replayFile && eof)
     replayFile = fileName->NextFile();
  eof = false;
  return replayFile != NULL;
}
コード例 #4
0
ファイル: genindex.c プロジェクト: suborb/reelvdr
bool cGenIndex::NextFile(void)
{
  if(replayFile>=0 && eof) {
    replayFile=fileName->NextFile();
    readNo=fileName->FileNumber();
    readOffset=0;
    fileSize[readNo]=fileName->FileSize();
    }
  eof=false;
  return replayFile>=0;
}
コード例 #5
0
ファイル: recorder.c プロジェクト: signal2noise/vdr-mirror
bool cFileWriter::NextFile(void)
{
  if (recordFile && pictureType == I_FRAME) { // every file shall start with an I_FRAME
     if (fileSize > MEGABYTE(Setup.MaxVideoFileSize) || RunningLowOnDiskSpace()) {
        recordFile = fileName->NextFile();
        fileSize = 0;
        }
     }
  return recordFile != NULL;
}
コード例 #6
0
ファイル: recorder.c プロジェクト: signal2noise/vdr-mirror
bool cFileWriter::RunningLowOnDiskSpace(void)
{
  if (time(NULL) > lastDiskSpaceCheck + DISKCHECKINTERVAL) {
     int Free = FreeDiskSpaceMB(fileName->Name());
     lastDiskSpaceCheck = time(NULL);
     if (Free < MINFREEDISKSPACE) {
        dsyslog("low disk space (%d MB, limit is %d MB)", Free, MINFREEDISKSPACE);
        return true;
        }
     }
  return false;
}
コード例 #7
0
ファイル: genindex.c プロジェクト: suborb/reelvdr
int cGenIndex::Output(const uchar *data, int len)
{
  if(rewrite && pstart && sSize>0) {
    if(!SafeWrite(writeFile,store,sSize)) {
      error=true;
      return -1;
      }
    sSize=0;
    }

  int ftype=0;
  if(scan) {
    const uchar *d=data;
    for(int i=len ; i>0 ; i--) {
      uchar c=*d++;
      if(skip>0) { skip--; continue; }
      // searching for sequence 00 00 01 00 xx PIC
      switch(state) {
        case 0:
        case 1:
        case 3:
          if(c==0x00) state++; else state=0;
          break;
        case 2:
          if(c==0x01) state++; 
          else if(c!=0x00) state=0;
          break;
        case 4:
          state++;
          break;
        case 5:
          ftype=(c>>3)&0x07;
          if(ftype<I_FRAME || ftype>B_FRAME) {
            printf("unknown picture type %d at %d\n",ftype,packetOffset);
            ftype=0;
            }
          scan=false; state=0; i=0;
          break;
        }
      }
    }

  if(rewrite) {
    if(scan && fileOffset>=splitOffset && (pstart || sSize)) {
      if(sSize+len>sizeof(store)) {
        printf("Oops! Packet buffer overflow\n");
        error=true;
        return -1;
        }
      memcpy(store+sSize,data,len);
      sSize+=len;
      }
    else {
      if(fileOffset>=splitOffset && sSize && ftype==I_FRAME) {
        writeFile=writeName->NextWriteFile();
        if(writeFile<0) {
          printf("Failed to open output file(s)\n");
          error=true;
          return -1;
          }
        packetNo=fileNo=writeName->FileNumber();
        packetOffset=0;
        fileOffset=sSize;
        }

      if(ftype>=I_FRAME) {
        index->Write(packetNo,packetOffset,ftype);
        }

      if(sSize>0) {
        if(!SafeWrite(writeFile,store,sSize)) {
          error=true;
          return -1;
          }
        sSize=0;
        }

      if(!SafeWrite(writeFile,data,len)) {
        error=true;
        return -1;
        }
      }
    }
  else {
    if(ftype>=I_FRAME) index->Write(packetNo,packetOffset,ftype);
    }

  Count(len);
  pstart=false;
  return len;
}
コード例 #8
0
ファイル: cutter.c プロジェクト: signal2noise/vdr-mirror
void cCuttingThread::Action(void)
{
  {
    sched_param tmp;
    tmp.sched_priority = CUTTER_PRIORITY;
    if(!pthread_setschedparam(pthread_self(), SCHED_OTHER, &tmp))
      printf("cCuttingThread::Action: cant set priority\n");
  }

  int bytes = 0;
  int __attribute__((unused)) burst_size = CUTTER_MAX_BANDWIDTH * CUTTER_TIMESLICE / 1000; // max bytes/timeslice 
  cTimeMs __attribute__((unused)) t;

  cMark *Mark = fromMarks.First();
  if (Mark) {
     fromFile = fromFileName->Open();
     toFile = toFileName->Open();
     if (!fromFile || !toFile)
        return;
     CheckTS(fromFile);
     fromFile->SetReadAhead(MEGABYTE(20));
     int Index = Mark->position;
     Mark = fromMarks.Next(Mark);
     int FileSize = 0;
     int CurrentFileNumber = 0;
     int LastIFrame = 0;
     toMarks.Add(0);
     toMarks.Save();
     uchar buffer[MAXFRAMESIZE];
     bool LastMark = false;
     bool cutIn = true;
     while (Running()) {
           uchar FileNumber;
           int FileOffset, Length;
           uchar PictureType;

           // Make sure there is enough disk space:

           AssertFreeDiskSpace(-1);

           // Read one frame:

           if (fromIndex->Get(Index++, &FileNumber, &FileOffset, &PictureType, &Length)) {
              if (FileNumber != CurrentFileNumber) {
                 fromFile = fromFileName->SetOffset(FileNumber, FileOffset);
                 fromFile->SetReadAhead(MEGABYTE(20));
                 CurrentFileNumber = FileNumber;
                 }
              if (fromFile) {
                 int len = ReadFrame(fromFile, buffer,  Length, sizeof(buffer));
                 if (len < 0) {
                    error = "ReadFrame";
                    break;
                    }
                 if (len != Length) {
                    CurrentFileNumber = 0; // this re-syncs in case the frame was larger than the buffer
                    Length = len;
                    }
                 }
              else {
                 error = "fromFile";
                 break;
                 }
              }
           else
              break;

           // Write one frame:

           if (PictureType == I_FRAME || PATPMT != NULL) { // every file shall start with an I_FRAME
              if (LastMark) // edited version shall end before next I-frame
                 break;
              if (FileSize == 0) {
                 if (PATPMT != NULL) {
                    if (toFile->Write(PATPMT, 2*TS_SIZE) < 0) // Add PATPMT to start of every file
                       break;
                    else
                       FileSize+=TS_SIZE*2;
                    }   
                 }
              else if (FileSize > MEGABYTE(Setup.MaxVideoFileSize)) {
                 toFile = toFileName->NextFile();
                 if (!toFile) {
                    error = "toFile 1";
                    break;
                    }
                 FileSize = 0;
                 if (PATPMT != NULL) {
                    if (toFile->Write(PATPMT, 2*TS_SIZE) < 0) // Add PATPMT to start of every file
                       break;
                    else
                       FileSize+=TS_SIZE*2;
                    }
                 }
              LastIFrame = 0;

              if (cutIn) {
                 cRemux::SetBrokenLink(buffer, Length);
                 cutIn = false;
                 }
              }
           if (toFile->Write(buffer, Length) < 0) {
              error = "safe_write";
              break;
              }
           if (!toIndex->Write(PictureType, toFileName->Number(), FileSize)) {
              error = "toIndex";
              break;
              }
           FileSize += Length;
           if (!LastIFrame)
              LastIFrame = toIndex->Last();

           // Check editing marks:

           if (Mark && Index >= Mark->position) {
              Mark = fromMarks.Next(Mark);
              toMarks.Add(LastIFrame);
              if (Mark)
                 toMarks.Add(toIndex->Last() + 1);
              toMarks.Save();
              if (Mark) {
                 Index = Mark->position;
                 Mark = fromMarks.Next(Mark);
                 CurrentFileNumber = 0; // triggers SetOffset before reading next frame
                 cutIn = true;
                 if (Setup.SplitEditedFiles) {
                    toFile = toFileName->NextFile();
                    if (!toFile) {
                       error = "toFile 2";
                       break;
                       }
                    FileSize = 0;
                    }
                 }
              else
                 LastMark = true;
              }

	   bytes += Length;
	   if(bytes >= burst_size) {
	     int elapsed = t.Elapsed();
	     int sleep = 0;
	     
#if CUTTER_REL_BANDWIDTH > 0 &&  CUTTER_REL_BANDWIDTH < 100
	     // stay under max. relative bandwidth

	     sleep = (elapsed * 100 / CUTTER_REL_BANDWIDTH) - elapsed;
	     //if(sleep<=0 && elapsed<=2) sleep = 1; 
	     //if(sleep) esyslog("cutter: relative bandwidth limit, sleep %d ms (chunk %dk / %dms)", sleep, burst_size/1024, CUTTER_TIMESLICE);
#endif
	     // stay under max. absolute bandwidth
	     if(elapsed < CUTTER_TIMESLICE) {
	       sleep = max(CUTTER_TIMESLICE - elapsed, sleep);
	       //if(sleep) esyslog("cutter: absolute bandwidth limit, sleep %d ms (chunk %dk / %dms)", sleep, burst_size/1024, CUTTER_TIMESLICE);
	     }

	     if(sleep>0)
	       cCondWait::SleepMs(sleep);
	     t.Set();
	     bytes = 0;
	   }

           }
     Recordings.TouchUpdate();
     }
  else
     esyslog("no editing marks found!");
}