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; }
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!"); }