diff options
Diffstat (limited to 'command/markad-standalone.cpp')
-rw-r--r-- | command/markad-standalone.cpp | 1364 |
1 files changed, 451 insertions, 913 deletions
diff --git a/command/markad-standalone.cpp b/command/markad-standalone.cpp index cccbf0f..f99ae92 100644 --- a/command/markad-standalone.cpp +++ b/command/markad-standalone.cpp @@ -26,6 +26,8 @@ #include <execinfo.h> #include <mntent.h> #include <utime.h> +#include <math.h> +#include <limits.h> #include <errno.h> #include "markad-standalone.h" @@ -179,625 +181,326 @@ int cOSDMessage::Send(const char *format, ...) return 0; } -void cMarkAdStandalone::CalculateStopPosition(int startframe, int delta) +void cMarkAdStandalone::CalculateCheckPositions(int startframe) { if (!length) return; + if (!startframe) return; if (!macontext.Video.Info.FramesPerSecond) return; - int len_in_frames=length*macontext.Video.Info.FramesPerSecond; + int delta=macontext.Video.Info.FramesPerSecond*MAXRANGE; + int len_in_frames=macontext.Video.Info.FramesPerSecond*length; - if (startframe) - { - iStop=-(startframe+len_in_frames); - chkLEFT=startframe+delta+macontext.Video.Info.FramesPerSecond; - chkRIGHT=startframe+(len_in_frames*2/3); - } - else - { - chkLEFT=(int) (len_in_frames*2/5); - chkRIGHT=(int) (len_in_frames*2/3); - } + iStart=-startframe; + iStop=-(startframe+len_in_frames); + chkSTART=-iStart+delta; + chkSTOP=-iStop+(3*delta); } -void cMarkAdStandalone::AddStartMark() +void cMarkAdStandalone::CheckStop() { - if (tStart<2) - { - char *buf; - if (asprintf(&buf,"start of recording (0)")!=-1) - { - marks.Add(MT_COMMONSTART,0,buf); - isyslog("%s",buf); - free(buf); - } - } - if (tStart) + dsyslog("checking stop"); + int delta=macontext.Video.Info.FramesPerSecond*MAXRANGE; + clMark *end=marks.GetAround(delta,iStop,MT_STOP,0x0F); + + if (end) { - iStart=-(tStart*macontext.Video.Info.FramesPerSecond); + marks.DelTill(end->position,false); + isyslog("using mark on position %i as stop mark",end->position); } - CalculateStopPosition(-iStart,macontext.Video.Info.FramesPerSecond*MAXRANGE); - if (tStart==1) + else { - tStart=iStart=0; + //fallback, shouldn't be reached + MarkAdMark mark; + memset(&mark,0,sizeof(mark)); + mark.Position=iStop; + mark.Type=MT_ASSUMEDSTOP; + AddMark(&mark); + marks.DelTill(iStop,false); } + iStop=0; + gotendmark=true; } -void cMarkAdStandalone::CheckStartStop(int frame, bool checkend) +void cMarkAdStandalone::CheckStart() { - MarkAdMark mark; - char *buf; + dsyslog("checking start"); + clMark *begin=NULL; - if ((iStartCheck>0) && (frame>=iStartCheck)) + if ((macontext.Info.Channels) && (macontext.Audio.Info.Channels) && + (macontext.Info.Channels!=macontext.Audio.Info.Channels)) { - // check if we have a start mark which is near iStart - clMark *before_iStart=marks.GetPrev(iStart,MT_START,0xF); - clMark *after_iStart=marks.GetNext(iStart,MT_START,0xF); - - int MAXMARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*MAXRANGE); - int type=0; - int newpos=0; - int delta_before=MAXMARKDIFF; - int delta_after=MAXMARKDIFF; - - if (before_iStart) - { - delta_before=abs(iStart-before_iStart->position); - if (delta_before>MAXMARKDIFF) delta_before=MAXMARKDIFF; - } - if (after_iStart) + char as[20]; + switch (macontext.Info.Channels) { - delta_after=abs(after_iStart->position-iStart); - if (delta_after>MAXMARKDIFF) delta_after=MAXMARKDIFF; - } - - if (delta_before>delta_after) - { - // use after_iStart - newpos=after_iStart->position; - type=after_iStart->type; + case 1: + strcpy(as,"mono"); + break; + case 2: + strcpy(as,"stereo"); + break; + case 6: + strcpy(as,"dd5.1"); + break; + default: + strcpy(as,"??"); + break; } - - if (delta_before<delta_after) + char ad[20]; + switch (macontext.Audio.Info.Channels) { - // use before_iStart - newpos=before_iStart->position; - type=before_iStart->type; - } - - if (newpos) - { - if (type==MT_BORDERSTART) - { - // check if we have an MT_ASPECTCHANGE in low distance - clMark *aspectmark=marks.GetPrev(newpos,MT_ASPECTSTART); - if (!aspectmark) aspectmark=marks.GetNext(newpos,MT_ASPECTSTART); - if (aspectmark) - { - int MAXMARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*20); - if (abs(newpos-aspectmark->position)<=MAXMARKDIFF) - { - newpos=aspectmark->position; - } - } - } - isyslog("using this mark instead of assumed start mark (%i->%i)", - newpos,iStart); - marks.Del(iStart); - marks.DelTill(newpos); - CalculateStopPosition(newpos,frame-newpos); + case 1: + strcpy(ad,"mono"); + break; + case 2: + strcpy(ad,"stereo"); + break; + case 6: + strcpy(ad,"dd5.1"); + break; + default: + strcpy(ad,"??"); + break; } - iStart=0; - iStartCheck=0; + isyslog("audio description in info (%s) wrong, we have %s",as,ad); } - if ((iStopCheck>0) && ((frame>=iStopCheck) || (checkend))) + macontext.Info.Channels=macontext.Audio.Info.Channels; + if (macontext.Info.Channels==6) { - // check if we have a stop mark which is near iStop - clMark *before_iStop=marks.GetPrev(iStop,MT_STOP,0xF); - clMark *after_iStop=marks.GetNext(iStop,MT_STOP,0xF); - - int MAXMARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*MAXRANGE); - int newpos=0; - int delta_before=MAXMARKDIFF; - int delta_after=MAXMARKDIFF; - - if (before_iStop) - { - delta_before=abs(iStop-before_iStop->position); - if (delta_before>MAXMARKDIFF) delta_before=MAXMARKDIFF; - } - if (after_iStop) - { - delta_after=abs(after_iStop->position-iStop); - if (delta_after>MAXMARKDIFF) delta_after=MAXMARKDIFF; - } - - if (delta_before>delta_after) - { - // use after_iStop - newpos=after_iStop->position; - } - - if (delta_before<delta_after) - { - // use before_iStop - newpos=before_iStop->position; - } - - if (newpos) - { - isyslog("using this mark instead of assumed stop mark (%i->%i)", - newpos,iStop); - marks.Del(iStop); - marks.DelTill(newpos,false); - } - else - { - marks.DelTill(iStop,false); - } + isyslog("DolbyDigital5.1 audio detected. logo/border/aspect detection disabled"); bDecodeVideo=false; - gotendmark=true; - iStop=0; - iStopCheck=0; - } - - if ((iStart<0) && (frame>-iStart)) - { - iStart=frame; - if (asprintf(&buf,"assumed start of broadcast (%i)",iStart)!=-1) - { - mark.Type=MT_ASSUMEDSTART; - mark.Position=iStart; - mark.Comment=buf; - AddMark(&mark); - free(buf); - } - - int MARKDIFF=length/6; - if (MARKDIFF>MAXRANGE) MARKDIFF=MAXRANGE; - MARKDIFF=(int) (MARKDIFF*macontext.Video.Info.FramesPerSecond); - iStartCheck=iStart+MARKDIFF; - CalculateStopPosition(iStart,MARKDIFF); + macontext.Video.Options.IgnoreAspectRatio=true; + macontext.Video.Options.IgnoreLogoDetection=true; + marks.Del(MT_ASPECTSTART); + marks.Del(MT_ASPECTSTOP); + // start mark must be around istart + begin=marks.GetAround(INT_MAX,iStart,MT_CHANNELSTART); } - if ((iStop<0) && (lastiframe>-iStop)) + else { - iStop=frame; - if (asprintf(&buf,"assumed stop of broadcast (%i)",iStop)!=-1) - { - mark.Type=MT_ASSUMEDSTOP; - mark.Position=iStop; - mark.Comment=buf; - AddMark(&mark); - free(buf); - } - - int MARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*MAXRANGE); - clMark *before_iStop=marks.GetPrev(iStart,MT_STOP,0xF); - if (before_iStop) + if (macontext.Info.DPid.Num) { - int tmpdiff=abs(iStop-before_iStop->position); - if (tmpdiff<MARKDIFF) MARKDIFF=tmpdiff; + if (macontext.Info.Channels) + isyslog("broadcast with %i audio channels, disabling AC3 decoding",macontext.Info.Channels); + macontext.Info.DPid.Num=0; + demux->DisableDPid(); } - iStopCheck=iStop+MARKDIFF; } -} -void cMarkAdStandalone::CheckLogoMarks(clMark *last) -{ - clMark *mark=marks.GetFirst(); - while (mark) + if ((macontext.Info.AspectRatio.Num) && ((macontext.Info.AspectRatio.Num!= + macontext.Video.Info.AspectRatio.Num) || (macontext.Info.AspectRatio.Den!= + macontext.Video.Info.AspectRatio.Den))) { - if ((mark->type==MT_LOGOSTOP) && mark->Next() && mark->Next()->type==MT_LOGOSTART) - { - int MARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*55); - if (abs(mark->Next()->position-mark->position)<=MARKDIFF) - { - double distance=(mark->Next()->position-mark->position)/ - macontext.Video.Info.FramesPerSecond; - isyslog("logo distance too short (%.1fs), deleting (%i,%i)",distance, - mark->position,mark->Next()->position); - clMark *tmp=mark; - mark=mark->Next()->Next(); - marks.Del(tmp->Next()); - marks.Del(tmp); - continue; - } - } - mark=mark->Next(); - if ((last) && (mark==last)) return; + isyslog("video aspect description in info (%i:%i) wrong", + macontext.Info.AspectRatio.Num, + macontext.Info.AspectRatio.Den); } -} -void cMarkAdStandalone::CheckLastMark() -{ - if (marks.Count()<=2) return; // just two marks -> do nothing - clMark *last=marks.GetLast(); - if (!last) return; + macontext.Info.AspectRatio.Num=macontext.Video.Info.AspectRatio.Num; + macontext.Info.AspectRatio.Den=macontext.Video.Info.AspectRatio.Den; - clMark *nexttolast=last->Prev(); - if (!nexttolast) return; + isyslog("aspectratio of %i:%i detected. %s", + macontext.Video.Info.AspectRatio.Num, + macontext.Video.Info.AspectRatio.Den, + ((macontext.Video.Info.AspectRatio.Num==4) && + (macontext.Video.Info.AspectRatio.Den==3)) ? + "logo/border detection disabled" : ""); - if ((last->type & 0xF)==(nexttolast->type & 0xF)) + if ((macontext.Video.Info.AspectRatio.Num==4) && + (macontext.Video.Info.AspectRatio.Den==3)) { - isyslog("removing double stop mark (%i)",last->position); - marks.Del(last); - return; - } -} - -void cMarkAdStandalone::CheckFirstMark() -{ - if (marksAligned) return; - clMark *first=marks.GetFirst(); - if (!first) return; - - // Check the second mark - clMark *second=first->Next(); - if (!second) return; - - if ((marks.Count(MT_BORDERCHANGE,0xF0)>0) && (marks.Count(MT_ASPECTCHANGE,0xF0)>0)) - { - // wait till its clear, if we use ASPECT or BORDER - return; - } - - if ((second->type & 0xF)==MT_START) - { - bool delsec=false; - clMark *third=second->Next(); - if (third) - { - if ((third->type & 0xF)==MT_START) delsec=true; - } - if (delsec) - { - isyslog("removing double start marks (%i,%i)",first->position,second->position); - marks.Del(second); - } - else - { - isyslog("removing double start mark (%i)",first->position); - } - marks.Del(first); - marksAligned=true; - first=marks.GetFirst(); - if (first) - { - CalculateStopPosition(first->position,macontext.Video.Info.FramesPerSecond*MAXRANGE); - } - return; - } - - if ((second->type & 0xF)==MT_STOP) - { - marksAligned=true; - return; + bDecodeVideo=false; + macontext.Video.Options.IgnoreLogoDetection=true; + marks.Del(MT_CHANNELSTART); + marks.Del(MT_CHANNELSTOP); + // start mark must be around iStart + begin=marks.GetAround(macontext.Video.Info.FramesPerSecond*(MAXRANGE*4),iStart,MT_ASPECTSTART); } - // If we have an aspectchange, check the next aspectchange mark - // and the difference between - if ((second->type==MT_ASPECTCHANGE) && (length)) + if (!bDecodeVideo) { - clMark *next=marks.GetNext(second->position,MT_ASPECTCHANGE); - if (next) - { - int maxlen=length*(13*60)/(90*60); // max 13 minutes ads on 90 minutes program - if (maxlen>(13*60)) maxlen=(13*60); // maximum ad block = 13 minutes - int MAXPOSDIFF=(int) (macontext.Video.Info.FramesPerSecond*maxlen); - if ((next->position-second->position)>MAXPOSDIFF) - { - clMark *first=marks.GetFirst(); - if (first) - { - isyslog("removing unaligned start mark (%i)",first->position); - marks.Del(first); - marksAligned=true; - return; - } - } - } + macontext.Video.Data.Valid=false; + marks.Del(MT_LOGOSTART); + marks.Del(MT_LOGOSTOP); + marks.Del(MT_HBORDERSTART); + marks.Del(MT_HBORDERSTOP); + marks.Del(MT_VBORDERSTART); + marks.Del(MT_VBORDERSTOP); } - return; -} - -void cMarkAdStandalone::CheckAspectRatio_and_AudioChannels() -{ - if (aspectChecked) return; - dsyslog("checking aspectratio and audio channels"); - - if (!macontext.Info.Channels) + if (!begin) { - macontext.Info.Channels=macontext.Audio.Info.Channels; - if (macontext.Info.Channels==2) setAudio20=true; - if (macontext.Info.Channels==6) - { - isyslog("DolbyDigital5.1 audio detected. logo/border detection disabled"); - bDecodeVideo=false; - setAudio20=false; - setAudio51=true; - reprocess=true; - } + begin=marks.GetAround(macontext.Video.Info.FramesPerSecond*(MAXRANGE*2),iStart,MT_START,0x0F); } - - bool aSet=false; - if (!macontext.Info.AspectRatio.Num) + if (begin) { - isyslog("assuming aspectratio of %i:%i", - macontext.Video.Info.AspectRatio.Num,macontext.Video.Info.AspectRatio.Den); - aSet=true; + marks.DelTill(begin->position); + CalculateCheckPositions(begin->position); + isyslog("using mark on position %i as start mark",begin->position); } else { - if (!bIgnoreVideoInfo) - { - if ((macontext.Info.AspectRatio.Num!=macontext.Video.Info.AspectRatio.Num) && - (macontext.Info.AspectRatio.Den!=macontext.Video.Info.AspectRatio.Den)) - { - isyslog("aspectratio in info wrong %i:%i instead of %i:%i", - macontext.Video.Info.AspectRatio.Num,macontext.Video.Info.AspectRatio.Den, - macontext.Info.AspectRatio.Num,macontext.Info.AspectRatio.Den); - aSet=true; - } - } - } - - if (aSet) - { - macontext.Info.AspectRatio.Num=macontext.Video.Info.AspectRatio.Num; - macontext.Info.AspectRatio.Den=macontext.Video.Info.AspectRatio.Den; - - if ((macontext.Info.AspectRatio.Num==16) && - (macontext.Info.AspectRatio.Den==9)) - { - macontext.Video.Options.IgnoreAspectRatio=true; - setVideo169=true; - setVideo43=false; - setVideo43LB=false; - } - - if ((macontext.Info.AspectRatio.Num==4) && - (macontext.Info.AspectRatio.Den==3)) - { - setVideo43=true; - setVideo169=false; - } - reprocess=true; + //fallback, shouldn't be reached + MarkAdMark mark; + memset(&mark,0,sizeof(mark)); + mark.Position=iStart; + mark.Type=MT_ASSUMEDSTART; + AddMark(&mark); + marks.DelTill(iStart); + CalculateCheckPositions(iStart); } - - aspectChecked=true; + iStart=0; return; } void cMarkAdStandalone::AddMark(MarkAdMark *Mark) { - if (gotendmark) return; if (!Mark) return; if (!Mark->Type) return; - if (!macontext.Video.Info.FramesPerSecond) return; - - bool loggedAlready=false; + if (gotendmark) return; - if (Mark->Type==MT_ASPECTSTOP) + char *comment=NULL; + switch (Mark->Type) { - // check if last mark is an stop mark in short distance - clMark *prev=marks.GetLast(); - if (prev) + case MT_ASSUMEDSTART: + if (asprintf(&comment,"assuming start (%i)",Mark->Position)==-1) comment=NULL; + break; + case MT_ASSUMEDSTOP: + if (asprintf(&comment,"assuming stop (%i)",Mark->Position)==-1) comment=NULL; + break; + case MT_LOGOSTART: + if (asprintf(&comment,"detected logo start (%i)*",Mark->Position)==-1) comment=NULL; + break; + case MT_LOGOSTOP: + if (asprintf(&comment,"detected logo stop (%i)",Mark->Position)==-1) comment=NULL; + break; + case MT_HBORDERSTART: + if (asprintf(&comment,"detected start of horiz. borders (%i)*", + Mark->Position)==-1) comment=NULL; + break; + case MT_HBORDERSTOP: + if (asprintf(&comment,"detected stop of horiz. borders (%i)", + Mark->Position)==-1) comment=NULL; + break; + case MT_VBORDERSTART: + if (asprintf(&comment,"detected start of vert. borders (%i)*", + Mark->Position)==-1) comment=NULL; + break; + case MT_VBORDERSTOP: + if (asprintf(&comment,"detected stop of vert. borders (%i)", + Mark->Position)==-1) comment=NULL; + break; + case MT_ASPECTSTART: + if (!Mark->AspectRatioBefore.Num) { - if ((prev->type & 0xF)==MT_STOP) - { - int MARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*15); - if ((Mark->Position-prev->position)<MARKDIFF) - { - if (Mark->Comment) isyslog("%s",Mark->Comment); - isyslog("double stop mark in short distance, deleting this mark (%i)",prev->position); - marks.Del(prev); - loggedAlready=true; - } - } - if (prev->type==MT_ASPECTSTART) - { - int MARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*240); - if ((Mark->Position-prev->position)<MARKDIFF) - { - if (Mark->Comment) isyslog("%s",Mark->Comment); - double distance=(Mark->Position-prev->position)/macontext.Video.Info.FramesPerSecond; - isyslog("aspect mark distance too short (%.1fs), deleting (%i,%i)",distance, - prev->position,Mark->Position); - marks.Del(prev); - return; - } - } + if (asprintf(&comment,"aspectratio start with %i:%i (%i)*", + Mark->AspectRatioAfter.Num,Mark->AspectRatioAfter.Den, + Mark->Position)==-1) comment=NULL; } - } - - if (Mark->Type==MT_CHANNELSTART) - { - clMark *prev=marks.GetPrev(Mark->Position,MT_CHANNELSTOP); - if (prev) + else { - int MARKDIFF=(int) macontext.Video.Info.FramesPerSecond; - if ((Mark->Position-prev->position)<MARKDIFF) - { - if (Mark->Comment) isyslog("%s",Mark->Comment); - double distance=(Mark->Position-prev->position)/macontext.Video.Info.FramesPerSecond; - isyslog("channel distance too short (%.1fs), deleting (%i,%i)",distance, - prev->position,Mark->Position); - marks.Del(prev); - return; - } + if (asprintf(&comment,"aspectratio change from %i:%i to %i:%i (%i)*", + Mark->AspectRatioBefore.Num,Mark->AspectRatioBefore.Den, + Mark->AspectRatioAfter.Num,Mark->AspectRatioAfter.Den, + Mark->Position)==-1) comment=NULL; } + break; + case MT_ASPECTSTOP: + if (asprintf(&comment,"aspectratio change from %i:%i to %i:%i (%i)", + Mark->AspectRatioBefore.Num,Mark->AspectRatioBefore.Den, + Mark->AspectRatioAfter.Num,Mark->AspectRatioAfter.Den, + Mark->Position)==-1) comment=NULL; + break; + case MT_CHANNELSTART: + if (asprintf(&comment,"audio channel change from %i to %i (%i)*", + Mark->ChannelsBefore,Mark->ChannelsAfter, + Mark->Position)==-1) comment=NULL; + break; + case MT_CHANNELSTOP: + if (asprintf(&comment,"audio channel change from %i to %i (%i)", + Mark->ChannelsBefore,Mark->ChannelsAfter, + Mark->Position)==-1) comment=NULL; + break; } - clMark *old=marks.Get(Mark->Position); - if ((old) && (((old->type & 0xF0)==MT_ASPECTCHANGE) || ((old->type & 0xF0)==MT_CHANNELCHANGE))) - { - // Aspect- / Channelchange wins over Logo/Border - return; - } + if (comment) isyslog("%s",comment); - if (Mark->Type==MT_LOGOSTOP) + if ((Mark->Type & 0x0F)==MT_STOP) { - // check if last mark is an audiochannel stop - clMark *prev=marks.GetLast(); - if ((prev) && (prev->type==MT_CHANNELSTOP)) + clMark *prev=marks.GetPrev(Mark->Position,(Mark->Type & 0xF0)|MT_START); + if (prev) { - int MARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*15); - if ((Mark->Position-prev->position)<MARKDIFF) + int MARKDIFF; + if ((Mark->Type & 0xF0)==MT_LOGOCHANGE) { - if (Mark->Comment) isyslog("%s",Mark->Comment); - isyslog("audiochannel change in short distance, using this mark (%i->%i)",Mark->Position,prev->position); - return; + MARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*240); + } + else + { + MARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*10); } - } - - prev=marks.GetPrev(Mark->Position,MT_LOGOSTART); - if (prev) - { - int MARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*240); if ((Mark->Position-prev->position)<MARKDIFF) { - if (Mark->Comment) isyslog("%s",Mark->Comment); double distance=(Mark->Position-prev->position)/macontext.Video.Info.FramesPerSecond; - isyslog("logo distance too short (%.1fs), deleting (%i,%i)",distance, + isyslog("mark distance too short (%.1fs), deleting %i,%i",distance, prev->position,Mark->Position); + if ((prev->type & 0x0F)==MT_START) inBroadCast=false; marks.Del(prev); return; } } } - if (Mark->Type==MT_LOGOSTART) + clMark *prev=marks.GetLast(); + if (prev) { - // check if last mark is an aspectratio change - clMark *prev=marks.GetLast(); - if (prev) + if ((Mark->Type==MT_LOGOSTART) && (!iStart)) { - if ((prev->type & 0xF0)==MT_ASPECTCHANGE) + if (prev->type==MT_LOGOSTOP) { - int MARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*5); + int MARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*30); if ((Mark->Position-prev->position)<MARKDIFF) { - if (Mark->Comment) isyslog("%s",Mark->Comment); - isyslog("aspectratio change in short distance, deleting this mark (%i)", - Mark->Position); - return; - } - } - - if (prev->type==MT_CHANNELSTART) - { - int MARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*5); - if ((Mark->Position-prev->position)<MARKDIFF) - { - if (Mark->Comment) isyslog("%s",Mark->Comment); - isyslog("audiochannel change in short distance, deleting this mark (%i)", - Mark->Position); + double distance=(Mark->Position-prev->position)/macontext.Video.Info.FramesPerSecond; + isyslog("mark distance too short (%.1fs), deleting %i,%i",distance, + prev->position,Mark->Position); + if ((prev->type & 0x0F)==MT_START) inBroadCast=false; + marks.Del(prev); return; } } } - } - if (length>0) - { - if ((Mark->Type==MT_BORDERSTART) && (Mark->Position>chkLEFT) && - (Mark->Position<chkRIGHT) && (!macontext.Video.Options.IgnoreLogoDetection)) + if ((prev->type & 0x0F)==(Mark->Type & 0x0F)) { - if (Mark->Comment) + int MARKDIFF=(int) (macontext.Video.Info.FramesPerSecond*30); + int diff=abs(Mark->Position-prev->position); + if (diff<MARKDIFF) { - isyslog("%s",Mark->Comment); - loggedAlready=true; - } - isyslog("border changes detected. logo detection disabled"); - macontext.Video.Options.IgnoreLogoDetection=true; - marks.Del((uchar) MT_LOGOSTART); - marks.Del((uchar) MT_LOGOSTOP); - } - - bool deleteLogoBorder=false; - if (((Mark->Type & 0xF0)==MT_CHANNELCHANGE) && (Mark->Position>chkLEFT) && - (Mark->Position<chkRIGHT) && (macontext.Info.Channels!=6)) - { - if (!loggedAlready) - { - if (Mark->Comment) - { - isyslog("%s",Mark->Comment); - loggedAlready=true; - } - } - isyslog("audio channel changes detected. logo/border detection disabled"); - if (macontext.Info.VPid.Type==MARKAD_PIDTYPE_VIDEO_H262) - { - if (!macontext.Info.AspectRatio.Num) + if (prev->type>Mark->Type) { - isyslog("assuming broadcast aspectratio is 16:9"); - macontext.Info.AspectRatio.Num=16; - macontext.Info.AspectRatio.Den=9; - macontext.Video.Options.IgnoreAspectRatio=true; - } - } - macontext.Info.Channels=6; - setAudio51=true; - setAudio20=false; - reprocess=true; - deleteLogoBorder=true; - } - - if (((Mark->Type & 0xF0)==MT_ASPECTCHANGE) && (Mark->Position>chkLEFT) && - (Mark->Position<chkRIGHT) && (!macontext.Video.Options.IgnoreLogoDetection)) - { - if (!loggedAlready) - { - if (Mark->Comment) - { - isyslog("%s",Mark->Comment); - loggedAlready=true; + isyslog("previous mark (%i) stronger than actual mark, deleting %i", + prev->position, Mark->Position); + return; } - } - isyslog("aspectratio changes detected. logo/border detection disabled"); - - if (!macontext.Info.AspectRatio.Num) - { - isyslog("assuming broadcast aspectratio is 4:3"); - macontext.Info.AspectRatio.Num=4; - macontext.Info.AspectRatio.Den=3; - reprocess=true; - setVideo43=true; - } - else - { - if ((macontext.Info.AspectRatio.Num==4) && - (macontext.Info.AspectRatio.Den==3)) + else { - if (marks.Count(MT_BORDERSTART)>0) - { - isyslog("assuming broadcast is in letterbox format"); - setVideo43LB=true; - setVideo43=false; - } + isyslog("actual mark stronger then previous mark, deleting %i",prev->position); + marks.Del(prev); } } - deleteLogoBorder=true; - } - - if (deleteLogoBorder) - { - bDecodeVideo=false; - macontext.Video.Options.IgnoreLogoDetection=true; - macontext.Video.Data.Valid=false; - marks.Del((uchar) MT_LOGOSTART); - marks.Del((uchar) MT_LOGOSTOP); - marks.Del((uchar) MT_BORDERSTART); - marks.Del((uchar) MT_BORDERSTOP); } } - if (Mark->Position>chkLEFT) CheckFirstMark(); - if (marksAligned) CheckLogoMarks(marks.GetLast()); - if ((Mark->Comment) && (!loggedAlready)) isyslog("%s",Mark->Comment); - marks.Add(Mark->Type,Mark->Position,Mark->Comment); + if ((Mark->Type & 0x0F)==MT_START) + { + inBroadCast=true; + } + else + { + inBroadCast=false; + } + marks.Add(Mark->Type,Mark->Position,comment); } void cMarkAdStandalone::SaveFrame(int frame) @@ -825,21 +528,7 @@ void cMarkAdStandalone::SaveFrame(int frame) fclose(pFile); } -void cMarkAdStandalone::CheckBroadcastLength() -{ - if (length) return; - if (!macontext.Video.Info.FramesPerSecond) return; - /* get broadcastlength from length of indexFile */ - int tframecnt=1; - int iIndexError; - marks.CheckIndex(directory,isTS,&tframecnt,&iIndexError); - if (iIndexError!=0) return; - length=tframecnt/macontext.Video.Info.FramesPerSecond; - isyslog("got broadcast length of %im from index",length/60); - reprocess=true; -} - -bool cMarkAdStandalone::CheckIndexGrowing() +void cMarkAdStandalone::CheckIndexGrowing() { // Here we check if the index is more // advanced than our framecounter. @@ -848,15 +537,15 @@ bool cMarkAdStandalone::CheckIndexGrowing() #define WAITTIME 15 - if (!indexFile) return false; - if (macontext.Config->logoExtraction!=-1) return false; - if (sleepcnt>=2) return false; // we already slept too much + if (!indexFile) return; + if (macontext.Config->logoExtraction!=-1) return; + if (sleepcnt>=2) return; // we already slept too much bool notenough=true; do { struct stat statbuf; - if (stat(indexFile,&statbuf)==-1) return false; + if (stat(indexFile,&statbuf)==-1) return; int maxframes=statbuf.st_size/8; if (maxframes<(framecnt+200)) @@ -868,7 +557,7 @@ bool cMarkAdStandalone::CheckIndexGrowing() if (time(NULL)>(startTime+(time_t) length)) { // "old" recording - return false; + return; } else { @@ -880,13 +569,13 @@ bool cMarkAdStandalone::CheckIndexGrowing() else { // "old" recording - return false; + return; } } marks.Save(directory,macontext.Video.Info.FramesPerSecond,isTS); sleep(WAITTIME); // now we sleep and hopefully the index will grow waittime+=WAITTIME; - if (errno==EINTR) return false; + if (errno==EINTR) return; sleepcnt++; if (sleepcnt>=2) { @@ -907,8 +596,7 @@ bool cMarkAdStandalone::CheckIndexGrowing() } } while (notenough); - if (!sleepcnt) return true; - else return false; + return; } void cMarkAdStandalone::ChangeMarks(clMark **Mark1, clMark **Mark2, MarkAdPos *NewPos) @@ -920,17 +608,25 @@ void cMarkAdStandalone::ChangeMarks(clMark **Mark1, clMark **Mark2, MarkAdPos *N if ((*Mark1)->position!=NewPos->FrameNumberBefore) { + char *buf=NULL; + if (asprintf(&buf,"overlap before %i, moved to %i",(*Mark1)->position, + NewPos->FrameNumberBefore)==-1) return; + isyslog("%s",buf); marks.Del(*Mark1); - *Mark1=marks.Add(MT_MOVED,NewPos->FrameNumberBefore,NewPos->CommentBefore); + *Mark1=marks.Add(MT_MOVED,NewPos->FrameNumberBefore,buf); + free(buf); save=true; } - if (NewPos->CommentBefore) isyslog("%s",NewPos->CommentBefore); if (Mark2 && (*Mark2) && (*Mark2)->position!=NewPos->FrameNumberAfter) { + char *buf=NULL; + if (asprintf(&buf,"overlap after %i, moved to %i",(*Mark2)->position, + NewPos->FrameNumberAfter)==-1) return; + isyslog("%s",buf); marks.Del(*Mark2); - *Mark2=marks.Add(MT_MOVED,NewPos->FrameNumberAfter,NewPos->CommentAfter); - if (NewPos->CommentAfter) isyslog("%s",NewPos->CommentAfter); + *Mark2=marks.Add(MT_MOVED,NewPos->FrameNumberAfter,buf); + free(buf); save=true; } if (save) marks.Save(directory,macontext.Video.Info.FramesPerSecond,isTS,true); @@ -950,12 +646,12 @@ bool cMarkAdStandalone::ProcessFile2ndPass(clMark **Mark1, clMark **Mark2,int Nu if (Mark1 && Mark2) { if (!(*Mark1) || !(*Mark2)) return false; - if (*Mark1==*Mark2) pn=1; - if (*Mark1!=*Mark2) pn=3; + if (*Mark1==*Mark2) pn=mSTART; + if (*Mark1!=*Mark2) pn=mAFTER; } else { - pn=2; + pn=mBEFORE; } if (!Reset(false)) @@ -992,13 +688,20 @@ bool cMarkAdStandalone::ProcessFile2ndPass(clMark **Mark1, clMark **Mark2,int Nu if (f==-1) return false; int dataread; - if (pn==1) + if (pn==mSTART) { dsyslog("processing file %05i (start mark)",Number); } else { - dsyslog("processing file %05i %s",Number,(pn==3) ? "(after mark)" : "(before mark)"); + if (pn==mBEFORE) + { + dsyslog("processing file %05i (before mark %i)",Number,(*Mark1)->position); + } + else + { + dsyslog("processing file %05i (after mark %i)",Number,(*Mark2)->position); + } } if (lseek(f,Offset,SEEK_SET)!=Offset) @@ -1007,32 +710,30 @@ bool cMarkAdStandalone::ProcessFile2ndPass(clMark **Mark1, clMark **Mark2,int Nu return false; } - uint64_t offset=Offset; - int offset_add=0; while ((dataread=read(f,data,datalen))>0) { if (abort) break; - if ((video_demux) && (video) && (decoder) && (streaminfo)) + if ((demux) && (video) && (decoder) && (streaminfo)) { uchar *tspkt = data; int tslen = dataread; while (tslen>0) { - int len=video_demux->Process(macontext.Info.VPid,tspkt,tslen,&vpkt); + int len=demux->Process(tspkt,tslen,&pkt); if (len<0) { - esyslog("error demuxing video"); + esyslog("error demuxing file"); abort=true; break; } else { - if (vpkt.Data) + if ((pkt.Data) && ((pkt.Type & PACKET_MASK)==PACKET_VIDEO)) { bool dRes=false; - if (streaminfo->FindVideoInfos(&macontext,vpkt.Data,vpkt.Length)) + if (streaminfo->FindVideoInfos(&macontext,pkt.Data,pkt.Length)) { actframe++; framecnt2++; @@ -1051,16 +752,15 @@ bool cMarkAdStandalone::ProcessFile2ndPass(clMark **Mark1, clMark **Mark2,int Nu dRes=true; } } - if (pn>1) dRes=decoder->DecodeVideo(&macontext,vpkt.Data,vpkt.Length); + if (pn>mSTART) dRes=decoder->DecodeVideo(&macontext,pkt.Data,pkt.Length); if (dRes) { if ((actframe-iframe)<=3) { - if (pn>1) pos=video->Process2ndPass(lastiframe,Frames,(pn==2)); - //SaveFrame(lastiframe); + if (pn>mSTART) pos=video->ProcessOverlap(lastiframe,Frames,(pn==mBEFORE)); framecounter++; } - if ((pos) && (pn==3)) + if ((pos) && (pn==mAFTER)) { // found overlap ChangeMarks(Mark1,Mark2,pos); @@ -1071,54 +771,10 @@ bool cMarkAdStandalone::ProcessFile2ndPass(clMark **Mark1, clMark **Mark2,int Nu } tspkt+=len; tslen-=len; - if (!vpkt.Offcnt) - { - offset_add+=len; - } - else - { - offset+=offset_add; - offset+=len; - offset_add=0; - } } } } -#if 0 - if ((mp2_demux) && (audio) && (pn!=3)) - { - uchar *tspkt = data; - int tslen = dataread; - while (tslen>0) - { - int len=mp2_demux->Process(macontext.Info.APid,tspkt,tslen,&apkt); - if (len<0) - { - esyslog("error demuxing mp2-audio"); - break; - } - else - { - if (apkt.Data) - { - if (apkt.Timestamp) audiotime=apkt.Timestamp; - - if (abs(audiotime-lastiframetime)<DELTATIME) - { - if (decoder->DecodeMP2(&macontext,apkt.Data,apkt.length)) - { - pos=audio->Process2ndPass(iframe); - if (pos) ChangeMarks(Mark1,NULL,pos); - } - } - } - tspkt+=len; - tslen-=len; - } - } - } -#endif if (abort) { close(f); @@ -1161,24 +817,7 @@ void cMarkAdStandalone::Process2ndPass() bool infoheader=false; clMark *p1=NULL,*p2=NULL; -#if 0 - p1=marks.GetFirst(); - if (!p1) return; - if (p1->position>0) - { - isyslog("2nd pass"); - infoheader=true; - off_t offset; - int number,frame,iframes; - int frange=macontext.Video.Info.FramesPerSecond*120; - - if (marks.ReadIndex(directory,isTS,p1->position-(frange/10),frange,&number,&offset,&frame,&iframes)) - { - ProcessFile2ndPass(&p1,&p1,number,offset,frame,iframes); - } - } -#endif - if (marks.Count()<4) return; // here we cannot do much + if (marks.Count()<4) return; // we cannot do much without marks p1=marks.GetFirst(); if (!p1) return; @@ -1196,24 +835,22 @@ void cMarkAdStandalone::Process2ndPass() off_t offset; int number,frame,iframes; int frange=macontext.Video.Info.FramesPerSecond*120; // 40s + 80s - int overlap=macontext.Video.Info.FramesPerSecond*10; // 10s - if (((p1->type & 0xF0)==MT_ASPECTCHANGE) || (p1->type==0)) - { - dsyslog("ignoring additional overlap"); - overlap=0; - } - - if (marks.ReadIndex(directory,isTS,p1->position-frange,frange+overlap,&number,&offset,&frame,&iframes)) + if (marks.ReadIndex(directory,isTS,p1->position-frange,frange,&number,&offset,&frame,&iframes)) { if (!ProcessFile2ndPass(&p1,NULL,number,offset,frame,iframes)) break; frange=macontext.Video.Info.FramesPerSecond*320; // 160s + 160s - if (marks.ReadIndex(directory,isTS,p2->position-overlap,frange+overlap,&number,&offset,&frame,&iframes)) + if (marks.ReadIndex(directory,isTS,p2->position,frange,&number,&offset,&frame,&iframes)) { if (!ProcessFile2ndPass(&p1,&p2,number,offset,frame,iframes)) break; } } + else + { + esyslog("error reading index"); + return; + } p1=p2->Next(); if (p1) @@ -1232,7 +869,7 @@ bool cMarkAdStandalone::ProcessFile(int Number) if (!directory) return false; if (!Number) return false; - if (!CheckIndexGrowing()) CheckBroadcastLength(); + CheckIndexGrowing(); if (abort) return false; @@ -1256,154 +893,123 @@ bool cMarkAdStandalone::ProcessFile(int Number) int dataread; dsyslog("processing file %05i",Number); - uint64_t offset=0; - int offset_add=0; + demux->NewFile(); while ((dataread=read(f,data,datalen))>0) { if (abort) break; - - if ((video_demux) && (video) && (streaminfo)) + if ((demux) && (video) && (streaminfo)) { uchar *tspkt = data; int tslen = dataread; - while (tslen>0) { - int len=video_demux->Process(macontext.Info.VPid,tspkt,tslen,&vpkt); + int len=demux->Process(tspkt,tslen,&pkt); if (len<0) { - esyslog("error demuxing video"); + esyslog("error demuxing"); abort=true; break; } else { - if (vpkt.Data) + if (pkt.Data) { - if ((macontext.Info.VPid.Type==MARKAD_PIDTYPE_VIDEO_H264) && (!noticeFILLER)) + if ((pkt.Type & PACKET_MASK)==PACKET_VIDEO) { - if ((vpkt.Data[4] & 0x1F)==0x0C) + bool dRes=false; + if (streaminfo->FindVideoInfos(&macontext,pkt.Data,pkt.Length)) { - isyslog("H264 video stream with filler nalu"); - noticeFILLER=true; - } - } + if ((macontext.Video.Info.Height) && (!noticeHEADER)) + { + isyslog("%s %ix%i%c%0.f",(macontext.Video.Info.Height>576) ? "HDTV" : "SDTV", + macontext.Video.Info.Width, + macontext.Video.Info.Height, + macontext.Video.Info.Interlaced ? 'i' : 'p', + macontext.Video.Info.FramesPerSecond); + noticeHEADER=true; + } - bool dRes=false; - if (streaminfo->FindVideoInfos(&macontext,vpkt.Data,vpkt.Length)) - { - if ((macontext.Video.Info.Height) && (!noticeHEADER)) - { - isyslog("%s %ix%i%c%0.f",(macontext.Video.Info.Height>576) ? "HDTV" : "SDTV", - macontext.Video.Info.Width, - macontext.Video.Info.Height, - macontext.Video.Info.Interlaced ? 'i' : 'p', - macontext.Video.Info.FramesPerSecond); - noticeHEADER=true; - } + if (!framecnt) + { + CalculateCheckPositions(tStart*macontext.Video.Info.FramesPerSecond); + } - if (!framecnt) - { - AddStartMark(); - } + if (macontext.Config->GenIndex) + { + marks.WriteIndex(directory,isTS,demux->Offset(),macontext.Video.Info.Pict_Type,Number); + } + framecnt++; - if (macontext.Config->GenIndex) - { - marks.WriteIndex(directory,isTS,offset,macontext.Video.Info.Pict_Type,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; + if (iStart>0) + { + if ((inBroadCast) && (lastiframe>chkSTART)) CheckStart(); + } + if (iStop>0) + { + if (lastiframe>chkSTOP) CheckStop(); + } + iframe=framecnt-1; + dRes=true; + } } - framecnt++; - if (macontext.Video.Info.Pict_Type==MA_I_TYPE) + if ((decoder) && (bDecodeVideo)) + dRes=decoder->DecodeVideo(&macontext,pkt.Data,pkt.Length); + if (dRes) { - lastiframe=iframe; - CheckStartStop(lastiframe); - if (lastiframe>chkLEFT) CheckAspectRatio_and_AudioChannels(); - iframe=framecnt-1; - dRes=true; + if ((framecnt-iframe)<=3) + { + MarkAdMarks *vmarks=video->Process(lastiframe,iframe); + if (vmarks) + { + for (int i=0; i<vmarks->Count; i++) + { + AddMark(&vmarks->Number[i]); + } + } + //SaveFrame(lastiframe); // TODO: JUST FOR DEBUGGING! + } } } - if ((decoder) && (bDecodeVideo)) - dRes=decoder->DecodeVideo(&macontext,vpkt.Data,vpkt.Length); - if (dRes) + if ((pkt.Type & PACKET_MASK)==PACKET_AC3) { - if ((framecnt-iframe)<=3) + if (streaminfo->FindAC3AudioInfos(&macontext,pkt.Data,pkt.Length)) { - MarkAdMarks *vmarks; - vmarks=video->Process(lastiframe,iframe); - if (vmarks) + if ((!isTS) && (!noticeVDR_AC3)) + { + isyslog("found AC3"); + noticeVDR_AC3=true; + } + if ((framecnt-iframe)<=3) { - for (int i=0; i<vmarks->Count; i++) + MarkAdMark *amark=audio->Process(lastiframe,iframe); + if (amark) { - AddMark(&vmarks->Number[i]); + AddMark(amark); } } - //SaveFrame(lastiframe); // TODO: JUST FOR DEBUGGING! } } } - if (vpkt.Skipped) - { - errcnt+=vpkt.Skipped; - } - tspkt+=len; - tslen-=len; - if (!vpkt.Offcnt) - { - offset_add+=len; - } - else - { - offset+=offset_add; - offset+=len; - offset_add=0; - } - } - } - } - if ((ac3_demux) && (streaminfo) && (audio)) - { - uchar *tspkt = data; - int tslen = dataread; - - while (tslen>0) - { - int len=ac3_demux->Process(macontext.Info.DPid,tspkt,tslen,&apkt); - if (len<0) - { - esyslog("error demuxing ac3-audio"); - break; - } - else - { - if (apkt.Data) - { - if (streaminfo->FindAC3AudioInfos(&macontext,apkt.Data,apkt.Length)) - { - if ((!isTS) && (!noticeVDR_AC3)) - { - isyslog("found AC3"); - noticeVDR_AC3=true; - } - MarkAdMark *amark; - amark=audio->Process(lastiframe,iframe); - if (amark) AddMark(amark); - } - } tspkt+=len; tslen-=len; } } } - - if (((gotendmark) && (!macontext.Config->GenIndex)) || (reprocess)) + if ((gotendmark) && (!macontext.Config->GenIndex)) { if (f!=-1) close(f); return true; } - if (!CheckIndexGrowing()) CheckBroadcastLength(); + CheckIndexGrowing(); if (abort) { if (f!=-1) close(f); @@ -1417,23 +1023,18 @@ bool cMarkAdStandalone::ProcessFile(int Number) bool cMarkAdStandalone::Reset(bool FirstPass) { bool ret=true; - reprocess=false; if (FirstPass) framecnt=0; lastiframe=0; iframe=0; gotendmark=false; - memset(&vpkt,0,sizeof(vpkt)); - memset(&apkt,0,sizeof(apkt)); + memset(&pkt,0,sizeof(pkt)); - iStart=iStartCheck=iStop=iStopCheck=0; - chkLEFT=INT_MAX; - chkRIGHT=INT_MIN; + chkSTART=chkSTOP=INT_MAX; if (FirstPass) { - marksAligned=false; marks.DelAll(); marks.CloseIndex(directory,isTS); } @@ -1448,9 +1049,7 @@ bool cMarkAdStandalone::Reset(bool FirstPass) ret=decoder->Clear(); } if (streaminfo) streaminfo->Clear(); - if (video_demux) video_demux->Clear(); - if (ac3_demux) ac3_demux->Clear(); - if (mp2_demux) mp2_demux->Clear(); + if (demux) demux->Clear(); if (video) video->Clear(); if (audio) audio->Clear(); return ret; @@ -1463,39 +1062,22 @@ void cMarkAdStandalone::ProcessFile() if (abort) break; if (!ProcessFile(i)) break; if ((gotendmark) && (!macontext.Config->GenIndex)) break; - if (reprocess) - { - isyslog("restarting from scratch"); - i=0; - Reset(); - } } if (!abort) { if (lastiframe) { - CheckStartStop(lastiframe,true); - - if ((!gotendmark) && ((iStop<0) || (!tStart))) + if ((inBroadCast) && (!gotendmark)) { - char *buf; MarkAdMark tempmark; - tempmark.Type=MT_COMMONSTOP; + tempmark.Type=MT_ASSUMEDSTOP; tempmark.Position=lastiframe; - - if (asprintf(&buf,"stop of recording (%i)",lastiframe)!=-1) - { - tempmark.Comment=buf; - AddMark(&tempmark); - free(buf); - } + AddMark(&tempmark); } } - - CheckLastMark(); - CheckLogoMarks(); } + skipped=demux->Skipped(); } void cMarkAdStandalone::Process() @@ -1581,8 +1163,7 @@ bool cMarkAdStandalone::SetFileUID(char *File) bool cMarkAdStandalone::SaveInfo() { - if ((!setVideo43) && (!setVideo169) && (!setAudio20) && (!setAudio51) && (!setVideo43LB)) return true; - + isyslog("writing info file"); char *src,*dst; if (asprintf(&src,"%s/info%s",directory,isTS ? "" : ".vdr")==-1) return false; @@ -1594,7 +1175,6 @@ bool cMarkAdStandalone::SaveInfo() FILE *r,*w; r=fopen(src,"r"); - w=fopen(dst,"w+"); if ((!r) || (!w)) @@ -1608,12 +1188,6 @@ bool cMarkAdStandalone::SaveInfo() char *lline=NULL; size_t length=0; - bool setVideo43LB_done=false; - bool setVideo43_done=false; - bool setVideo169_done=false; - bool setAudio20_done=false; - bool setAudio51_done=false; - char lang[4]=""; int component_type_add=0; @@ -1653,47 +1227,46 @@ bool cMarkAdStandalone::SaveInfo() case 5: if (stream==stream_content) { - if ( (((type==1) || (type==5)) && (setVideo169)) || - (((type==3) || (type==7)) && ((setVideo43) || (setVideo43LB)))) + if ((macontext.Info.AspectRatio.Num==4) && (macontext.Info.AspectRatio.Den==3)) { - if (setVideo43) - { - if (fprintf(w,"X %i %02i %s 4:3\n",stream_content, - component_type_43+component_type_add,lang)<=0) err=true; - setVideo43_done=true; - } - if (setVideo43LB) - { - if (fprintf(w,"X %i %02i %s 4:3 LetterBox\n",stream_content, - component_type_43+component_type_add,lang)<=0) err=true; - setVideo43_done=true; - setVideo43LB_done=true; - } - if (setVideo169) - { - if (fprintf(w,"X %i %02i %s 16:9\n",stream_content, - component_type_169+component_type_add,lang)<=0) err=true; - setVideo169_done=true; - } + if (fprintf(w,"X %i %02i %s 4:3\n",stream_content, + component_type_43+component_type_add,lang)<=0) err=true; + macontext.Info.AspectRatio.Num=0; + macontext.Info.AspectRatio.Den=0; + } + else if ((macontext.Info.AspectRatio.Num==16) && (macontext.Info.AspectRatio.Den==9)) + { + if (fprintf(w,"X %i %02i %s 16:9\n",stream_content, + component_type_169+component_type_add,lang)<=0) err=true; + macontext.Info.AspectRatio.Num=0; + macontext.Info.AspectRatio.Den=0; } else { if (fprintf(w,"%s",line)<=0) err=true; } } + else + { + if (fprintf(w,"%s",line)<=0) err=true; + } break; case 2: - if ((type==5) && ((setAudio51) || (setAudio20))) + if (type==5) { - if (setAudio51) + if (macontext.Info.Channels==6) { if (fprintf(w,"X 2 05 %s Dolby Digital 5.1\n",lang)<=0) err=true; - setAudio51_done=true; + macontext.Info.Channels=0; } - if (setAudio20) + else if (macontext.Info.Channels==2) { if (fprintf(w,"X 2 05 %s Dolby Digital 2.0\n",lang)<=0) err=true; - setAudio20_done=true; + macontext.Info.Channels=0; + } + else + { + if (fprintf(w,"%s",line)<=0) err=true; } } else @@ -1733,28 +1306,23 @@ bool cMarkAdStandalone::SaveInfo() if (stream_content) { - if ((setVideo43LB) && (!setVideo43LB_done) && (!err)) - { - if (fprintf(w,"X %i %02i %s 4:3 LetterBox\n",stream_content, - component_type_43+component_type_add,lang)<=0) err=true; - } - if ((setVideo43) && (!setVideo43_done) && (!err)) + if ((macontext.Info.AspectRatio.Num==4) && (macontext.Info.AspectRatio.Den==3) && (!err)) { if (fprintf(w,"X %i %02i %s 4:3\n",stream_content, component_type_43+component_type_add,lang)<=0) err=true; } - if ((setVideo169) && (!setVideo169_done) && (!err)) + if ((macontext.Info.AspectRatio.Num==16) && (macontext.Info.AspectRatio.Den==9) && (!err)) { if (fprintf(w,"X %i %02i %s 16:9\n",stream_content, component_type_169+component_type_add,lang)<=0) err=true; } } - if ((setAudio20) && (!setAudio20_done) && (!err)) + if ((macontext.Info.Channels==2) && (!err)) { if (fprintf(w,"X 2 05 %s Dolby Digital 2.0\n",lang)<=0) err=true; } - if ((setAudio51) && (!setAudio51_done) && (!err)) + if ((macontext.Info.Channels==6) && (!err)) { if (fprintf(w,"X 2 05 %s Dolby Digital 5.1\n",lang)<=0) err=true; } @@ -1800,23 +1368,36 @@ time_t cMarkAdStandalone::GetBroadcastStart(time_t start, int fd) struct mntent *ent; struct stat statbuf; FILE *mounts=setmntent(_PATH_MOUNTED,"r"); + int mlen=0; + int oldmlen=0; + bool useatime=false; while ((ent=getmntent(mounts))!=NULL) { if (strstr(directory,ent->mnt_dir)) { - if (strstr(ent->mnt_opts,"noatime")) + mlen=strlen(ent->mnt_dir); + if (mlen>oldmlen) { - if (stat(directory,&statbuf)!=-1) + if (strstr(ent->mnt_opts,"noatime")) { - endmntent(mounts); - isyslog("getting broadcast start from directory atime"); - return statbuf.st_atime; + useatime=true; + } + else + { + useatime=false; } } + oldmlen=mlen; } } endmntent(mounts); + if ((useatime) && (stat(directory,&statbuf)!=-1)) + { + isyslog("getting broadcast start from directory atime"); + return statbuf.st_atime; + } + // try to get from mtime // (and hope info.vdr has not changed after the start of the recording) if (fstat(fd,&statbuf)!=-1) @@ -1930,7 +1511,7 @@ bool cMarkAdStandalone::LoadInfo() int result=sscanf(line,"%*c %i %i %250c",&stream,&type,(char *) &descr); if ((result!=0) && (result!=EOF)) { - if (((stream==1) || (stream==5)) && (!bIgnoreVideoInfo)) + if ((stream==1) || (stream==5)) { if ((type!=1) && (type!=5) && (type!=9) && (type!=13)) { @@ -1946,26 +1527,22 @@ bool cMarkAdStandalone::LoadInfo() } } - if ((stream==2) && (!bIgnoreAudioInfo)) + if (stream==2) { if (type==5) { // if we have DolbyDigital 2.0 disable AC3 if (strchr(descr,'2')) { - isyslog("broadcast with DolbyDigital2.0, disabling AC3 decoding"); - macontext.Info.DPid.Num=0; + isyslog("broadcast with DolbyDigital2.0 (from info)"); macontext.Info.Channels=2; } - else - // if we have DolbyDigital 5.1 disable video decoding - if (strchr(descr,'5')) - { - bDecodeVideo=false; - macontext.Info.Channels=6; - macontext.Video.Options.IgnoreAspectRatio=true; - isyslog("broadcast with DolbyDigital5.1, disabling video decoding"); - } + // if we have DolbyDigital 5.1 disable video decoding + if (strchr(descr,'5')) + { + isyslog("broadcast with DolbyDigital5.1 (from info)"); + macontext.Info.Channels=6; + } } } } @@ -2011,8 +1588,6 @@ bool cMarkAdStandalone::LoadInfo() esyslog("cannot read broadcast length from info, marks can be wrong!"); macontext.Info.AspectRatio.Num=0; macontext.Info.AspectRatio.Den=0; - bIgnoreAudioInfo=true; - bIgnoreVideoInfo=true; bDecodeVideo=macontext.Config->DecodeVideo; macontext.Video.Options.IgnoreAspectRatio=false; } @@ -2131,7 +1706,11 @@ bool cMarkAdStandalone::CheckPATPMT(off_t Offset) free(buf); if (fd==-1) return false; - if (lseek(fd,Offset,SEEK_SET)==(off_t)-1) return false; + if (lseek(fd,Offset,SEEK_SET)==(off_t)-1) + { + close(fd); + return false; + } uchar patpmt_buf[564]; uchar *patpmt; @@ -2324,39 +1903,27 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, const MarkAdConfig * directory=Directory; abort=false; gotendmark=false; - reprocess=false; indexFile=NULL; streaminfo=NULL; - video_demux=NULL; - ac3_demux=NULL; - mp2_demux=NULL; + demux=NULL; decoder=NULL; video=NULL; audio=NULL; osd=NULL; - memset(&vpkt,0,sizeof(vpkt)); - memset(&apkt,0,sizeof(apkt)); - - setAudio51=false; - setAudio20=false; - setVideo43=false; - setVideo43LB=false; - setVideo169=false; - aspectChecked=false; + memset(&pkt,0,sizeof(pkt)); noticeVDR_MP2=false; noticeVDR_AC3=false; noticeHEADER=false; noticeFILLER=false; - errcnt=0; + skipped=0; sleepcnt=0; waittime=iwaittime=0; duplicate=false; - marksAligned=false; title[0]=0; memset(&macontext,0,sizeof(macontext)); @@ -2365,25 +1932,7 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, const MarkAdConfig * bDecodeVideo=config->DecodeVideo; bDecodeAudio=config->DecodeAudio; - tStart=iStart=iStop=iStartCheck=iStopCheck=0; - - if ((config->ignoreInfo & IGNORE_VIDEOINFO)==IGNORE_VIDEOINFO) - { - bIgnoreVideoInfo=true; - } - else - { - bIgnoreVideoInfo=false; - } - - if ((config->ignoreInfo & IGNORE_AUDIOINFO)==IGNORE_AUDIOINFO) - { - bIgnoreAudioInfo=true; - } - else - { - bIgnoreAudioInfo=false; - } + tStart=iStart=iStop=0; if ((config->ignoreInfo & IGNORE_TIMERINFO)==IGNORE_TIMERINFO) { @@ -2408,14 +1957,6 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, const MarkAdConfig * { isyslog("video decoding disabled by user"); } - if (bIgnoreAudioInfo) - { - isyslog("audio info usage disabled by user"); - } - if (bIgnoreVideoInfo) - { - isyslog("video info usage disabled by user"); - } if (bIgnoreTimerInfo) { isyslog("timer info usage disabled by user"); @@ -2425,8 +1966,6 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, const MarkAdConfig * { // just to be sure extraction works bDecodeVideo=true; - bIgnoreAudioInfo=true; - bIgnoreVideoInfo=true; } if (!config->NoPid) @@ -2465,6 +2004,7 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, const MarkAdConfig * } if (asprintf(&indexFile,"%s/index.vdr",Directory)==-1) indexFile=NULL; } + macontext.Info.APid.Num=0; // till now we do just nothing with stereo-sound if (!LoadInfo()) { @@ -2473,7 +2013,7 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, const MarkAdConfig * esyslog("failed loading info - logo %s%sdisabled", (config->logoExtraction!=-1) ? "extraction" : "detection", bIgnoreTimerInfo ? " " : " and pre-/post-timer "); - tStart=0; + tStart=iStart=iStop=0; } } @@ -2505,42 +2045,33 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, const MarkAdConfig * { if (isTS) { - dsyslog("using %s-video (0x%04x)", + dsyslog("found %s-video (0x%04x)", macontext.Info.VPid.Type==MARKAD_PIDTYPE_VIDEO_H264 ? "H264": "H262", macontext.Info.VPid.Num); } else { - dsyslog("using %s-video", + dsyslog("found %s-video", macontext.Info.VPid.Type==MARKAD_PIDTYPE_VIDEO_H264 ? "H264": "H262"); } - video_demux = new cMarkAdDemux(); + demux=new cDemux(macontext.Info.VPid.Num,macontext.Info.DPid.Num,macontext.Info.APid.Num, + macontext.Info.VPid.Type==MARKAD_PIDTYPE_VIDEO_H264,true); } else { - video_demux=NULL; + demux=NULL; } if (macontext.Info.APid.Num) { if (macontext.Info.APid.Num!=-1) - dsyslog("using MP2 (0x%04x)",macontext.Info.APid.Num); - mp2_demux = new cMarkAdDemux(); - } - else - { - mp2_demux=NULL; + dsyslog("found MP2 (0x%04x)",macontext.Info.APid.Num); } if (macontext.Info.DPid.Num) { if (macontext.Info.DPid.Num!=-1) - dsyslog("using AC3 (0x%04x)",macontext.Info.DPid.Num); - ac3_demux = new cMarkAdDemux(); - } - else - { - ac3_demux=NULL; + dsyslog("found AC3 (0x%04x)",macontext.Info.DPid.Num); } if (!abort) @@ -2551,15 +2082,14 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, const MarkAdConfig * audio = new cMarkAdAudio(&macontext); streaminfo = new cMarkAdStreamInfo; if (macontext.Info.ChannelName) - dsyslog("channel %s",macontext.Info.ChannelName); + isyslog("channel %s",macontext.Info.ChannelName); } framecnt=0; framecnt2=0; lastiframe=0; iframe=0; - chkLEFT=INT_MAX; - chkRIGHT=INT_MIN; + chkSTART=chkSTOP=INT_MAX; gettimeofday(&tv1,&tz); } @@ -2567,9 +2097,9 @@ cMarkAdStandalone::~cMarkAdStandalone() { if ((!abort) && (!duplicate)) { - if (errcnt>20) + if (skipped) { - isyslog("skipped %i bytes in video stream",errcnt); + isyslog("skipped %i bytes",skipped); } gettimeofday(&tv2,&tz); @@ -2606,9 +2136,7 @@ cMarkAdStandalone::~cMarkAdStandalone() if (macontext.Info.ChannelName) free(macontext.Info.ChannelName); if (indexFile) free(indexFile); - if (video_demux) delete video_demux; - if (ac3_demux) delete ac3_demux; - if (mp2_demux) delete mp2_demux; + if (demux) delete demux; if (decoder) delete decoder; if (video) delete video; if (audio) delete audio; @@ -2642,10 +2170,7 @@ int usage(int svdrpport) " 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" - " 4 = ignore timer info\n" - " (options can be added together, e.g. 5 = ignore\n" - " audio and timer info)\n" + " <info> 4 = ignore timer info\n" "-l --logocachedir\n" " directory where logos stored, default /var/lib/markad\n" "-p --priority=<priority>\n" @@ -2655,7 +2180,7 @@ int usage(int svdrpport) " io priority of markad when running in background\n" " <class> 1 = realtime, <level> from 0..7, default 4\n" " 2 = besteffort, <level> from 0..7, default 4\n" - " 3 = idle\n" + " 3 = idle (default)\n" "-v --verbose\n" " increments loglevel by one, can be given multiple times\n" "-B --backupmarks\n" @@ -2681,8 +2206,13 @@ int usage(int svdrpport) " (default is the number of cpus)\n" "-V --version\n" " print version-info and exit\n" + " --loglevel=<level>\n" + " sets loglevel to the specified value\n" + " <level> 1=error 2=info 3=debug 4=trace\n" " --markfile=<markfilename>\n" " set a different markfile-name\n" + " --nopid\n" + " disables creation of markad.pid file in recdir\n" " --online[=1|2] (default is 1)\n" " start markad immediately when called with \"before\" as cmd\n" " if online is 1, markad starts online for live-recordings\n" @@ -2766,8 +2296,8 @@ int main(int argc, char *argv[]) bool bAfter=false,bEdited=false; bool bFork=false,bNice=false,bImmediateCall=false; int niceLevel = 19; - int ioprio_class=2; - int ioprio=4; + int ioprio_class=3; + int ioprio=7; char *tok,*str; int ntok; int online=0; @@ -2780,6 +2310,7 @@ int main(int argc, char *argv[]) // set defaults config.DecodeVideo=true; config.DecodeAudio=true; + config.SaveInfo=false; config.logoExtraction=-1; config.logoWidth=-1; config.logoHeight=-1; @@ -2834,7 +2365,7 @@ int main(int argc, char *argv[]) {"backupmarks", 0, 0, 'B'}, {"scenechangedetection", 0, 0, 'C'}, {"genindex",0, 0, 'G'}, - {"saveinfo",0,0,'I'}, + {"saveinfo",0, 0, 'I'}, {"extractlogo", 1, 0, 'L'}, {"OSD",0,0,'O' }, {"log2rec",0,0,'R'}, @@ -2845,7 +2376,7 @@ int main(int argc, char *argv[]) {0, 0, 0, 0} }; - c = getopt_long (argc, argv, "abcd:i:jl:nop:r:s:vBCGL:ORST:V", + c = getopt_long (argc, argv, "abcd:i:jl:nop:r:s:vBCGIL:ORST:V", long_options, &option_index); if (c == -1) break; @@ -2890,7 +2421,7 @@ int main(int argc, char *argv[]) case 'i': // --ignoreinfo config.ignoreInfo=atoi(optarg); - if ((config.ignoreInfo<0) || (config.ignoreInfo>255)) + if ((config.ignoreInfo<1) || (config.ignoreInfo>255)) { fprintf(stderr, "markad: invalid ignoreinfo option: %s\n", optarg); return 2; @@ -3071,7 +2602,14 @@ int main(int argc, char *argv[]) break; case 4: // --online - online=atoi(optarg); + if (optarg) + { + online=atoi(optarg); + } + else + { + online=1; + } if ((online!=1) && (online!=2)) { fprintf(stderr, "markad: invalid online value: %s\n", optarg); |