diff options
Diffstat (limited to 'command')
-rw-r--r-- | command/Makefile | 2 | ||||
-rw-r--r-- | command/global.h | 20 | ||||
-rw-r--r-- | command/markad-standalone.cpp | 318 | ||||
-rw-r--r-- | command/markad-standalone.h | 1 | ||||
-rw-r--r-- | command/marks.cpp | 56 | ||||
-rw-r--r-- | command/marks.h | 6 | ||||
-rw-r--r-- | command/video.cpp | 8 |
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); |