summaryrefslogtreecommitdiff
path: root/command
diff options
context:
space:
mode:
Diffstat (limited to 'command')
-rw-r--r--command/Makefile2
-rw-r--r--command/global.h20
-rw-r--r--command/markad-standalone.cpp318
-rw-r--r--command/markad-standalone.h1
-rw-r--r--command/marks.cpp56
-rw-r--r--command/marks.h6
-rw-r--r--command/video.cpp8
7 files changed, 213 insertions, 198 deletions
diff --git a/command/Makefile b/command/Makefile
index efafc13..da4a04a 100644
--- a/command/Makefile
+++ b/command/Makefile
@@ -9,7 +9,7 @@ VERSION = $(shell grep 'static const char \*VERSION *=' ../version.h | awk '{ pr
### The C++ compiler and options:
CXX ?= g++
-CXXFLAGS ?= -g -O2 -Wall -Wextra -Woverloaded-virtual -Wno-parentheses
+CXXFLAGS ?= -g -rdynamic -O2 -Wall -Wextra -Woverloaded-virtual -Wno-parentheses
PKG-CONFIG ?= pkg-config
### Includes and Defines (add further entries here):
diff --git a/command/global.h b/command/global.h
index b1b2748..43e202c 100644
--- a/command/global.h
+++ b/command/global.h
@@ -22,23 +22,29 @@ typedef unsigned char uchar;
#define MA_SP_TYPE 6
#define MA_BI_TYPE 7
+#define MT_UNCERTAIN 0
+#define MT_START 1
+#define MT_STOP 2
+
#define MT_COMMON 0x10
+#define MT_COMMONSTART 0x11
+#define MT_COMMONSTOP 0x12
#define MT_ASPECTCHANGE 0x20
#define MT_ASPECTSTART 0x21
#define MT_ASPECTSTOP 0x22
#define MT_CHANNELCHANGE 0x30
-#define MT_CHANNELSTART 0x30
-#define MT_CHANNELSTOP 0x31
+#define MT_CHANNELSTART 0x31
+#define MT_CHANNELSTOP 0x32
#define MT_LOGOCHANGE 0x40
-#define MT_LOGOSTART 0x40
-#define MT_LOGOSTOP 0x41
+#define MT_LOGOSTART 0x41
+#define MT_LOGOSTOP 0x42
#define MT_BORDERCHANGE 0x50
-#define MT_BORDERSTART 0x50
-#define MT_BORDERSTOP 0x51
+#define MT_BORDERSTART 0x51
+#define MT_BORDERSTOP 0x52
#define MT_SILENCECHANGE 0x60
@@ -47,7 +53,7 @@ typedef unsigned char uchar;
typedef struct MarkAdMark
{
- int Type;
+ char Type;
int Position;
char *Comment;
} MarkAdMark;
diff --git a/command/markad-standalone.cpp b/command/markad-standalone.cpp
index 7780e46..f68a1f5 100644
--- a/command/markad-standalone.cpp
+++ b/command/markad-standalone.cpp
@@ -153,6 +153,37 @@ void cMarkAdStandalone::AddStartMark()
}
}
+void cMarkAdStandalone::CheckStartStop(int lastiframe)
+{
+ MarkAdMark mark;
+ char *buf;
+
+ if ((iStart<0) && (lastiframe>-iStart))
+ {
+ iStart=lastiframe;
+ if (asprintf(&buf,"assumed start of broadcast (%i)",iStart)!=-1)
+ {
+ mark.Type=MT_COMMONSTART;
+ mark.Position=iStart;
+ mark.Comment=buf;
+ AddMark(&mark);
+ free(buf);
+ }
+ }
+ if ((iStop<0) && (lastiframe>-iStop))
+ {
+ iStop=lastiframe;
+ if (asprintf(&buf,"assumed stop of broadcast (%i)",iStop)!=-1)
+ {
+ mark.Type=MT_COMMONSTOP;
+ mark.Position=iStop;
+ mark.Comment=buf;
+ AddMark(&mark);
+ free(buf);
+ }
+ }
+}
+
bool cMarkAdStandalone::CheckFirstMark()
{
if (marksAligned) return true;
@@ -161,19 +192,14 @@ bool cMarkAdStandalone::CheckFirstMark()
clMark *second=marks.GetNext(0);
if (!second) return false;
- if ((second->type==MT_LOGOSTART) || (second->type==MT_BORDERSTART) ||
- (second->type==MT_CHANNELSTART) || (second->type==MT_ASPECTSTART))
+ if ((second->type & 0xF)==MT_START)
{
clMark *first=marks.Get(0);
if (first) marks.Del(first);
marksAligned=true;
}
- if ((second->type==MT_LOGOSTOP) || (second->type==MT_BORDERSTOP) ||
- (second->type==MT_CHANNELSTOP) || (second->type==MT_ASPECTSTOP))
- {
- marksAligned=true;
- }
+ if ((second->type & 0xF)==MT_STOP) marksAligned=true;
// If we have an aspectchange, check the next aspectchange mark
// and the difference between
@@ -200,22 +226,101 @@ void cMarkAdStandalone::AddMark(MarkAdMark *Mark)
{
if (!Mark) return;
if (!Mark->Type) return;
+ if (!macontext.Video.Info.FramesPerSecond) return;
bool loggedAlready=false;
+ if ((iStart>0) || (iStop>0))
+ {
+ clMark *last=NULL;
+ int MINMARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*180);
+ if ((iStart>0) && (abs(Mark->Position-iStart)<=MINMARKDIFF) && ((Mark->Type & 0x0F)==MT_START))
+ {
+ last=marks.GetPrev(Mark->Position,MT_START,0xF);
+ if (!last) last=marks.GetPrev(Mark->Position,MT_ASPECTCHANGE);
+ if ((last) && (abs(last->position-iStart)>MINMARKDIFF)) last=NULL;
+ }
+
+ if ((iStop>0) && (abs(Mark->Position-iStop)<=MINMARKDIFF) && ((Mark->Type & 0x0F)==MT_STOP))
+ {
+ last=marks.GetPrev(Mark->Position,MT_STOP,0xF);
+ if (!last) last=marks.GetPrev(Mark->Position,MT_ASPECTCHANGE);
+ if ((last) && (abs(last->position-iStop)>MINMARKDIFF)) last=NULL;
+ }
+
+ if (last)
+ {
+ if (Mark->Comment) isyslog(Mark->Comment);
+ marksAligned=true;
+
+ if ((last->type & 0xF)==MT_START)
+ {
+ iStart=0;
+ }
+ else
+ {
+ iStop=0;
+ fastexit=true;
+ }
+
+ if ((last->type==MT_COMMONSTART) || (last->type==MT_COMMONSTOP))
+ {
+ isyslog("using this mark instead of assumed %s mark in \"short\" distance (%i->%i)",
+ (last->type==MT_COMMONSTART) ? "start" : "stop",
+ Mark->Position,last->position);
+
+ marks.Clear();
+ loggedAlready=true;
+ }
+ else
+ {
+ if (last->type==MT_ASPECTCHANGE)
+ {
+ isyslog("aspectratio change in \"short\" distance, deleting this mark (%i)",
+ Mark->Position);
+ }
+ else
+ {
+ isyslog("%s mark in \"short\" distance, deleting this mark (%i)",
+ ((last->type & 0xF)==MT_START) ? "start" : "stop",
+ Mark->Position);
+ }
+
+ if ((last->type & 0xF)==MT_START) marks.Clear(last->position);
+ return;
+ }
+ }
+ }
+
if (Mark->Type==MT_LOGOSTART)
{
// check if last mark is an aspectratio change
clMark *prev=marks.GetLast();
- if ((prev) && ((prev->type & 0xF0)==MT_ASPECTCHANGE))
+ if (prev)
{
- int MINMARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*5);
- if ((Mark->Position-prev->position)<MINMARKDIFF)
+ if ((prev->type & 0xF0)==MT_ASPECTCHANGE)
{
- if (Mark->Comment) isyslog(Mark->Comment);
- isyslog("aspectratio change in short distance, using this mark (%i->%i)",Mark->Position,prev->position);
- return;
+ int MINMARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*5);
+ if ((Mark->Position-prev->position)<MINMARKDIFF)
+ {
+ if (Mark->Comment) isyslog(Mark->Comment);
+ isyslog("aspectratio change in short distance, using this mark (%i->%i)",Mark->Position,prev->position);
+ return;
+ }
}
+
+ if ((prev->type & 0xF0)==MT_CHANNELSTART)
+ {
+ int MINMARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*5);
+ if ((Mark->Position-prev->position)<MINMARKDIFF)
+ {
+ if (Mark->Comment) isyslog(Mark->Comment);
+ isyslog("audiochannel change in short distance, using this mark (%i->%i)",Mark->Position,prev->position);
+ return;
+ }
+ }
+
+
}
}
@@ -255,7 +360,6 @@ void cMarkAdStandalone::AddMark(MarkAdMark *Mark)
if (macontext.Info.Length>0)
{
int MINPOS=(int) ((macontext.Video.Info.FramesPerSecond*macontext.Info.Length)/5);
- if (!MINPOS) MINPOS=25000; // fallback
if (((Mark->Type & 0xF0)==MT_BORDERCHANGE) && (Mark->Position>MINPOS) &&
(!macontext.Video.Options.IgnoreLogoDetection))
{
@@ -270,80 +374,29 @@ void cMarkAdStandalone::AddMark(MarkAdMark *Mark)
marks.Del(MT_LOGOSTOP);
}
+ MINPOS=(int) ((macontext.Video.Info.FramesPerSecond*macontext.Info.Length)/3);
if ((((Mark->Type & 0xF0)==MT_CHANNELCHANGE) || ((Mark->Type & 0xF0)==MT_ASPECTCHANGE)) &&
(Mark->Position>MINPOS) && (bDecodeVideo))
{
- bool TurnOff=true;
- if ((Mark->Type & 0xF0)==MT_ASPECTCHANGE)
- {
- if ((marks.Count(MT_ASPECTCHANGE)+marks.Count(MT_ASPECTSTART)+
- marks.Count(MT_ASPECTSTOP)) <3)
- {
- TurnOff=false;
- }
- }
- if ((Mark->Type & 0xF0)==MT_CHANNELCHANGE)
+ if (Mark->Comment)
{
- if ((marks.Count(MT_CHANNELSTART)+marks.Count(MT_CHANNELSTOP))<3)
- {
- TurnOff=false;
- }
+ isyslog(Mark->Comment);
+ loggedAlready=true;
}
+ isyslog("%s change detected. logo/border detection disabled",
+ (Mark->Type & 0xF0)==MT_ASPECTCHANGE ? "aspectratio" : "audio channel");
- if (TurnOff)
- {
- if (Mark->Comment)
- {
- isyslog(Mark->Comment);
- loggedAlready=true;
- }
- isyslog("%s change detected. logo/border detection disabled",
- (Mark->Type & 0xF0)==MT_ASPECTCHANGE ? "aspectratio" : "audio channel");
-
- bDecodeVideo=false;
- macontext.Video.Data.Valid=false;
- marks.Del(MT_LOGOSTART);
- marks.Del(MT_LOGOSTOP);
- marks.Del(MT_BORDERSTART);
- marks.Del(MT_BORDERSTOP);
- }
+ bDecodeVideo=false;
+ macontext.Video.Data.Valid=false;
+ marks.Del(MT_LOGOSTART);
+ marks.Del(MT_LOGOSTOP);
+ marks.Del(MT_BORDERSTART);
+ marks.Del(MT_BORDERSTOP);
}
}
CheckFirstMark();
- if (iStart>0)
- {
- if (abs(Mark->Position-iStart)<200*(macontext.Video.Info.FramesPerSecond))
- {
- if ((Mark->Type==MT_ASPECTSTART) || (Mark->Type==MT_LOGOSTART) ||
- (Mark->Type==MT_CHANNELSTART) || (Mark->Type==MT_ASPECTCHANGE))
- {
- if (Mark->Comment)
- {
- isyslog(Mark->Comment);
- loggedAlready=true;
- }
- isyslog("assuming start of broadcast (%i)",Mark->Position);
- marks.Clear(); // clear all other marks till now
- marksAligned=true;
- iStart=0;
- }
- }
- }
-
- if ((iStop>0) && (Mark->Position>tStop))
- {
- if (Mark->Comment)
- {
- isyslog(Mark->Comment);
- loggedAlready=true;
- }
- isyslog("assuming stop of broadcast (%i)",Mark->Position);
- fastexit=true;
- iStop=0;
- }
-
clMark *old=marks.Get(Mark->Position);
if (old)
{
@@ -361,33 +414,6 @@ void cMarkAdStandalone::AddMark(MarkAdMark *Mark)
}
}
-void cMarkAdStandalone::RateMarks()
-{
- if (macontext.Info.Length)
- {
- if ((marks.Count()>3) && (macontext.Info.Length>1800))
- {
- int logomarks=marks.Count(MT_LOGOSTART) + marks.Count(MT_LOGOSTOP);
- int audiomarks=marks.Count(MT_CHANNELSTART) + marks.Count(MT_CHANNELSTOP);
-
- // If we have logomarks or audiomarks get rid of the aspect changes,
- // cause if we have a recording with (>=3) aspect changes the
- // logomarks were already deleted in AddMark
- if ((logomarks) || (audiomarks))
- {
- marks.Del(MT_ASPECTCHANGE);
- marks.Del(MT_ASPECTSTART);
- marks.Del(MT_ASPECTSTOP);
- }
- }
- }
-
- // Check the first mark again
- CheckFirstMark();
-
- // TODO: more checks
-}
-
void cMarkAdStandalone::SaveFrame(int frame)
{
if (!macontext.Video.Info.Width) return;
@@ -522,14 +548,7 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number)
if (macontext.Video.Info.Pict_Type==MA_I_TYPE)
{
lastiframe=iframe;
- if ((iStart<0) && (lastiframe>-iStart))
- {
- iStart=lastiframe;
- }
- if ((iStop<0) && (lastiframe>-iStop))
- {
- iStop=lastiframe;
- }
+ CheckStartStop(lastiframe);
iframe=framecnt-1;
}
}
@@ -669,60 +688,18 @@ void cMarkAdStandalone::Process(const char *Directory)
if (!abort)
{
- if ((lastiframe) && (!fastexit))
+ if ((lastiframe) && (!fastexit) && (iStop<0))
{
- bool set=true;
char *buf;
- if ((marks.Count()<=1) && (iStart>0))
- {
- if (marks.Count()==1)
- {
- clMark *mark=marks.GetFirst();
- if (mark)
- {
- if (mark->position==0)
- {
- marks.Clear();
- }
- else
- {
- set=false;
- }
- }
- }
+ MarkAdMark tempmark;
+ tempmark.Type=MT_COMMON;
+ tempmark.Position=lastiframe;
- if (set)
- {
- if (asprintf(&buf,"assumed start of broadcast (%i)",iStart)!=-1)
- {
- isyslog(buf);
- marks.Add(MT_COMMON,iStart,buf);
- free(buf);
- }
- if (iStop>0)
- {
- if (asprintf(&buf,"assumed stop of broadcast (%i)",iStart)!=-1)
- {
- isyslog(buf);
- marks.Add(MT_COMMON,iStart,buf);
- free(buf);
- }
- }
- }
- }
- else
+ if (asprintf(&buf,"stop of recording (%i)",lastiframe)!=-1)
{
-
- MarkAdMark tempmark;
- tempmark.Type=MT_COMMON;
- tempmark.Position=lastiframe;
-
- if (asprintf(&buf,"stop of recording (%i)",lastiframe)!=-1)
- {
- tempmark.Comment=buf;
- AddMark(&tempmark);
- free(buf);
- }
+ tempmark.Comment=buf;
+ AddMark(&tempmark);
+ free(buf);
}
}
@@ -1133,7 +1110,13 @@ bool cMarkAdStandalone::RegenerateVDRIndex(const char *Directory)
struct stat statbuf;
if (stat(tmp,&statbuf)!=0) return false;
unlink(tmp);
- if (statbuf.st_size!=0) return false;
+ if (statbuf.st_size!=0)
+ {
+ if (asprintf(&oldfile,"%s/index.vdr.generated",Directory)==-1) return false;
+ unlink(oldfile);
+ free(oldfile);
+ return false;
+ }
}
// rename index.vdr.generated -> index.vdr
@@ -1564,11 +1547,11 @@ int usage()
" markad runs as a background-process\n"
" this will be automatically set if called with \"after\"\n"
"-d --disable=<option>\n"
- " <option> 1 = disable video 2 = disable audio\n"
- " 3 = disable video and audio\n"
+ " <option> 1 = disable video decoding, 2 = disable audio\n"
+ " decoding, 3 = disable video and audio decoding\n"
"-i --ignoreinfo=<info>\n"
" ignores hints from info(.vdr) file\n"
- " <info> 1 = ignore audio info 2 = ignore video info\n"
+ " <info> 1 = ignore audio info, 2 = ignore video info,\n"
" 4 = ignore timer info\n"
" (options can be added together, e.g. 5 = ignore\n"
" audio and timer info)\n"
@@ -2039,7 +2022,6 @@ int main(int argc, char *argv[])
// if bFork is given go in background
if ( bFork )
{
- (void)umask((mode_t)0011);
//close_files();
pid_t pid = fork();
if (pid < 0)
@@ -2113,6 +2095,8 @@ int main(int argc, char *argv[])
}
}
+ (void)umask((mode_t)0022);
+
int MaxPossibleFileDescriptors = getdtablesize();
for (int i = STDERR_FILENO + 1; i < MaxPossibleFileDescriptors; i++)
close(i); //close all dup'ed filedescriptors
diff --git a/command/markad-standalone.h b/command/markad-standalone.h
index 9f6954f..0f09b34 100644
--- a/command/markad-standalone.h
+++ b/command/markad-standalone.h
@@ -224,6 +224,7 @@ unsigned Descriptor_Length:
clMarks marks;
char *IndexToHMSF(int Index);
bool CheckFirstMark();
+ void CheckStartStop(int lastiframe);
void AddStartMark();
void AddMark(MarkAdMark *Mark);
void RateMarks();
diff --git a/command/marks.cpp b/command/marks.cpp
index d84fafd..6935175 100644
--- a/command/marks.cpp
+++ b/command/marks.cpp
@@ -64,17 +64,23 @@ void clMarks::Del(int Type)
}
}
-void clMarks::Clear()
+void clMarks::Clear(int Before)
{
clMark *next,*mark=first;
while (mark)
{
next=mark->Next();
- Del(mark);
+ if (mark->position<Before)
+ {
+ Del(mark);
+ }
mark=next;
}
- first=NULL;
- last=NULL;
+ if (Before==0x7FFFFFFF)
+ {
+ first=NULL;
+ last=NULL;
+ }
}
void clMarks::Del(clMark *Mark)
@@ -85,6 +91,14 @@ void clMarks::Del(clMark *Mark)
{
// we are the first mark
first=Mark->Next();
+ if (first)
+ {
+ first->SetPrev(NULL);
+ }
+ else
+ {
+ last=NULL;
+ }
}
else
{
@@ -118,28 +132,35 @@ clMark *clMarks::Get(int Position)
return mark;
}
-clMark *clMarks::GetPrev(int Position, int Type)
+clMark *clMarks::GetPrev(int Position, int Type, int Mask)
{
if (!first) return NULL; // no elements yet
+ // first advance
clMark *mark=first;
while (mark)
{
- if (Type==0xFF)
- {
- if (mark->position>=Position) break;
- }
- else
+ if (mark->position>=Position) break;
+ mark=mark->Next();
+ }
+ if (Type==0xFF)
+ {
+ if (mark) return mark->Prev();
+ return last;
+ }
+ else
+ {
+ if (!mark) mark=last;
+ while (mark)
{
- if ((mark->position>=Position) && (mark->type==Type)) break;
+ if ((mark->type & Mask)==Type) break;
+ mark=mark->Prev();
}
- mark=mark->Next();
+ return mark;
}
- if (mark) return mark->Prev();
- return last;
}
-clMark *clMarks::GetNext(int Position, int Type)
+clMark *clMarks::GetNext(int Position, int Type, int Mask)
{
if (!first) return NULL; // no elements yet
clMark *mark=first;
@@ -151,11 +172,12 @@ clMark *clMarks::GetNext(int Position, int Type)
}
else
{
- if ((mark->position>=Position) && (mark->type==Type)) break;
+ if ((mark->position>=Position) && ((mark->type & Mask)==Type)) break;
}
mark=mark->Next();
}
- return mark->Next();
+ if (mark) return mark->Next();
+ return NULL;
}
clMark *clMarks::Add(int Type, int Position,const char *Comment)
diff --git a/command/marks.h b/command/marks.h
index 8ea4a99..76c137d 100644
--- a/command/marks.h
+++ b/command/marks.h
@@ -98,12 +98,12 @@ public:
}
}
clMark *Add(int Type, int Position, const char *Comment = NULL);
- void Clear();
+ void Clear(int Before=0x7FFFFFFF);
void Del(clMark *Mark);
void Del(int Type);
clMark *Get(int Position);
- clMark *GetPrev(int Position,int Type=0xFF);
- clMark *GetNext(int Position,int Type=0xFF);
+ clMark *GetPrev(int Position,int Type=0xFF, int Mask=0xFF);
+ clMark *GetNext(int Position,int Type=0xFF, int Mask=0xFF);
clMark *GetFirst()
{
return first;
diff --git a/command/video.cpp b/command/video.cpp
index 5eae436..90a9c53 100644
--- a/command/video.cpp
+++ b/command/video.cpp
@@ -472,7 +472,8 @@ int cMarkAdBlackBordersHoriz::Process(int LastIFrame, int *BorderIFrame)
}
else
{
-#define MINSECS 420
+#define MINSECS 90
+//420
switch (borderstatus)
{
case UNINITIALIZED:
@@ -516,6 +517,7 @@ int cMarkAdBlackBordersHoriz::Process(int LastIFrame, int *BorderIFrame)
else
{
borderiframe=-1;
+ borderstatus=NOBORDER;
}
}
return 0;
@@ -623,7 +625,7 @@ MarkAdMark *cMarkAdVideo::Process(int LastIFrame)
if ((hret>0) && (borderiframe))
{
char *buf=NULL;
- if (asprintf(&buf,"detected start of horiz. borders (%i)",borderiframe)!=-1)
+ if (asprintf(&buf,"detected start of horiz. borders (%i [%i])",borderiframe,LastIFrame)!=-1)
{
AddMark(MT_BORDERSTART,borderiframe,buf);
free(buf);
@@ -633,7 +635,7 @@ MarkAdMark *cMarkAdVideo::Process(int LastIFrame)
if ((hret<0) && (borderiframe))
{
char *buf=NULL;
- if (asprintf(&buf,"detected stop of horiz. borders (%i)",borderiframe)!=-1)
+ if (asprintf(&buf,"detected stop of horiz. borders (%i [%i])",borderiframe,LastIFrame)!=-1)
{
AddMark(MT_BORDERSTOP,borderiframe,buf);
free(buf);