29 void Flush(
uchar *Data,
int &Length,
int MaxLength);
50 int NewSize = (
length + Length) * 3 / 2;
64 if (Data &&
length > 0 && Length +
length <= MaxLength) {
80 void Flush(
int Pid,
uchar *Data,
int &Length,
int MaxLength);
85 for (
int i = 0; i <
MAXPID; i++)
91 for (
int i = 0; i <
MAXPID; i++)
112 bool FindHeader(uint32_t Code,
const char *Header);
118 void AdjGopTime(
int Offset,
int FramesPerSecond);
126 if (
TsPid(Data) == Vpid) {
127 Setup(Data, Length, Vpid);
138 esyslog(
"ERROR: %s header not found!", Header);
185 uchar Frame = ((Byte3 & 0x1F) << 1) | (Byte4 >> 7);
186 uchar Sec = ((Byte2 & 0x07) << 3) | (Byte3 >> 5);
187 uchar Min = ((Byte1 & 0x03) << 4) | (Byte2 >> 4);
188 uchar Hour = ((Byte1 & 0x7C) >> 2);
189 int GopTime = ((Hour * 60 + Min) * 60 + Sec) * FramesPerSecond + Frame;
193 GopTime += 24 * 60 * 60 * FramesPerSecond;
194 Frame = GopTime % FramesPerSecond;
195 GopTime = GopTime / FramesPerSecond;
197 GopTime = GopTime / 60;
199 GopTime = GopTime / 60;
201 SetByte((Byte1 & 0x80) | (Hour << 2) | (Min >> 4), Index1);
202 SetByte(((Min & 0x0F) << 4) | 0x08 | (Sec >> 3), Index2);
203 SetByte(((Sec & 0x07) << 3) | (Frame >> 1), Index3);
204 SetByte((Byte4 & 0x7F) | ((Frame & 0x01) << 7), Index4);
219 SetByte((Tref << 6) | (Byte2 & 0x3F), Index2);
250 bool LoadFrame(
int Index,
uchar *Buffer,
bool &Independent,
int &Length);
256 bool FixFrame(
uchar *Data,
int &Length,
bool Independent,
int Index,
bool CutIn,
bool CutOut);
257 bool ProcessSequence(
int LastEndIndex,
int BeginIndex,
int EndIndex,
int NextBeginIndex);
259 virtual void Action(
void);
267 :
cThread(
"video cutting", true)
301 esyslog(
"no editing sequences found for %s", FromFileName);
304 esyslog(
"no editing marks found for %s", FromFileName);
320 dsyslog(
"suspending cutter thread");
326 dsyslog(
"resuming cutter thread");
336 if (
fromIndex->
Get(Index, &FileNumber, &FileOffset, &Independent, &Length)) {
343 else if (len != Length)
345 return error == NULL;
379 if (!Buffer1 || !Buffer2)
384 if (
LoadFrame(Index1, Buffer1, Independent, Length1) &&
LoadFrame(Index2, Buffer2, Independent, Length2)) {
385 if (Length1 == Length2) {
387 for (
int i = 0; i < Length1; i++) {
388 if (Buffer1[i] != Buffer2[i]) {
404 bool Processed[
MAXPID] = {
false };
408 for (
int NumIndependentFrames = 0; NumIndependentFrames < 2; Index++) {
411 if (
LoadFrame(Index, Buffer, Independent, len)) {
413 NumIndependentFrames++;
419 int64_t d =
PtsDiff(LastPts, Pts);
423 NumIndependentFrames = 0;
424 Processed[Pid] =
true;
467 Mpeg2fixer.SetClosedGop();
476 bool DeletedFrame =
false;
477 bool GotVidPts =
false;
537 if (!DeletedFrame && !GotVidPts) {
548 bool SeamlessBegin = LastEndIndex >= 0 &&
FramesAreEqual(LastEndIndex, BeginIndex);
549 bool SeamlessEnd = NextBeginIndex >= 0 &&
FramesAreEqual(EndIndex, NextBeginIndex);
556 for (
int Index = BeginIndex;
Running() && Index < EndIndex; Index++) {
559 if (
LoadFrame(Index, Buffer, Independent, Length)) {
562 bool CutIn = !SeamlessBegin && Index == BeginIndex;
563 bool CutOut = !SeamlessEnd && Index == EndIndex - 1;
564 bool DeletedFrame =
false;
566 DeletedFrame =
FixFrame(Buffer, Length, Independent, Index, CutIn, CutOut);
582 error =
"safe_write";
607 int LastEndIndex = -1;
608 while (BeginMark &&
Running()) {
618 int NextBeginIndex = -1;
621 NextBeginIndex = NextBeginMark->Position();
623 if (!
ProcessSequence(LastEndIndex, BeginMark->Position(), EndIndex, NextBeginIndex))
627 LastEndIndex = EndIndex;
641 esyslog(
"no editing marks found!");
653 bool cCutter::Start(
const char *FileName,
const char *TargetFileName,
bool Overwrite)
668 if (!Overwrite && *evn && (access(*evn, F_OK) == 0) && !
Interface->
Confirm(
tr(
"File already exists - overwrite?"))) {
671 }
while (*evn && (access(*evn, F_OK) == 0));
676 char *s = strdup(*evn);
677 char *e = strrchr(s,
'.');
679 if (strcmp(e,
".rec") == 0) {
705 isyslog(
"editing process has been interrupted");
707 esyslog(
"ERROR: '%s' during editing process", Error);
748 #define CUTTINGCHECKINTERVAL 500 // ms between checks for the active cutting process
754 if (Recording.
Name()) {
764 fprintf(stderr,
"can't start editing process\n");
767 fprintf(stderr,
"'%s' has no editing sequences\n", FileName);
770 fprintf(stderr,
"'%s' has no editing marks\n", FileName);
773 fprintf(stderr,
"'%s' is not a recording\n", FileName);
776 fprintf(stderr,
"'%s' is not a directory\n", FileName);