diff options
author | Jochen Dolze <vdr@dolze.de> | 2010-10-21 00:44:14 +0200 |
---|---|---|
committer | Jochen Dolze <vdr@dolze.de> | 2010-10-21 00:44:14 +0200 |
commit | 8cf0800ad613a165c07424b84fd84b60b586c6f8 (patch) | |
tree | 5adb123ac54e2405f225ba13d4df85ade52b1a36 /command | |
parent | 0acaba790948b737a35293e5a9ac91be5de563b0 (diff) | |
download | vdr-plugin-markad-8cf0800ad613a165c07424b84fd84b60b586c6f8.tar.gz vdr-plugin-markad-8cf0800ad613a165c07424b84fd84b60b586c6f8.tar.bz2 |
Added letterbox detection
Improved audiochannel-/aspect-/borderchange detection
Diffstat (limited to 'command')
-rw-r--r-- | command/audio.cpp | 43 | ||||
-rw-r--r-- | command/global.h | 10 | ||||
-rw-r--r-- | command/markad-standalone.cpp | 99 | ||||
-rw-r--r-- | command/markad-standalone.h | 21 | ||||
-rw-r--r-- | command/video.cpp | 50 | ||||
-rw-r--r-- | command/video.h | 6 |
6 files changed, 140 insertions, 89 deletions
diff --git a/command/audio.cpp b/command/audio.cpp index bb1b63f..fe96594 100644 --- a/command/audio.cpp +++ b/command/audio.cpp @@ -149,34 +149,41 @@ MarkAdMark *cMarkAdAudio::Process(int FrameNumber, int FrameNumberNext) if (ChannelChange(macontext->Audio.Info.Channels,channels)) { - bool start=false; - if (macontext->Audio.Info.DolbyDigital51) - { - if (macontext->Audio.Info.Channels>2) start=true; - else start=false; - } - else - { - if (macontext->Audio.Info.Channels>2) start=false; - else start=true; - } + char *buf=(char *) calloc(1,256); + if (!buf) return NULL; - char *buf=NULL; - if (asprintf(&buf,"audio channel change from %i to %i (%i)%s", channels, - macontext->Audio.Info.Channels, - start ? FrameNumberNext : - framelast, start ? "*" : "")!=-1) + snprintf(buf,255,"audio channel change from %i to %i (", channels, + macontext->Audio.Info.Channels); + + if (macontext->Info.Channels) { - if (start) + if (macontext->Info.Channels==macontext->Audio.Info.Channels) { + char nbuf[20]; + snprintf(nbuf,sizeof(nbuf),"%i)*",FrameNumberNext); + nbuf[19]=0; + strcat(buf,nbuf); AddMark(MT_CHANNELSTART,FrameNumberNext,buf); + } else { + char nbuf[20]; + snprintf(nbuf,sizeof(nbuf),"%i)",framelast); + nbuf[19]=0; + strcat(buf,nbuf); AddMark(MT_CHANNELSTOP,framelast,buf); } - free(buf); } + else + { + char nbuf[20]; + snprintf(nbuf,sizeof(nbuf),"%i)?",FrameNumber); + nbuf[19]=0; + strcat(buf,nbuf); + AddMark(MT_CHANNELCHANGE,FrameNumber,buf); + } + free(buf); } channels=macontext->Audio.Info.Channels; diff --git a/command/global.h b/command/global.h index e7cc76c..30c5896 100644 --- a/command/global.h +++ b/command/global.h @@ -95,6 +95,13 @@ typedef struct MarkAdMark char *Comment; } MarkAdMark; +typedef struct MarkAdMarks +{ + static const int maxCount=4; + MarkAdMark Number[maxCount]; + int Count; +} MarkAdMarks; + typedef struct MarkAdAspectRatio { int Num; @@ -119,6 +126,7 @@ typedef struct MarkAdContext struct Info { int Length; // in seconds + int Channels; char *ChannelName; MarkAdAspectRatio AspectRatio; MarkAdPid VPid; @@ -157,7 +165,7 @@ typedef struct MarkAdContext { struct Info { - bool DolbyDigital51; + //bool DolbyDigital51; int Channels; // number of audio channels int SampleRate; } Info; diff --git a/command/markad-standalone.cpp b/command/markad-standalone.cpp index 75afb26..c756a31 100644 --- a/command/markad-standalone.cpp +++ b/command/markad-standalone.cpp @@ -178,22 +178,21 @@ int cOSDMessage::Send(const char *format, ...) void cMarkAdStandalone::CalculateStopPosition(int startframe, int delta) { - chkLEFT=0xFFFFFFF; - chkRIGHT=0xFFFFFFF; if (!macontext.Info.Length) return; if (!macontext.Video.Info.FramesPerSecond) return; + int len_in_frames=macontext.Info.Length*macontext.Video.Info.FramesPerSecond; + if (startframe) { - int len_in_frames=macontext.Info.Length*macontext.Video.Info.FramesPerSecond; iStop=-(startframe+len_in_frames); chkLEFT=startframe+delta+macontext.Video.Info.FramesPerSecond; chkRIGHT=startframe+(len_in_frames*2/3); } else { - chkLEFT=(int) ((macontext.Video.Info.FramesPerSecond*macontext.Info.Length)/3); - chkRIGHT=(int) ((macontext.Video.Info.FramesPerSecond*macontext.Info.Length)*2/3); + chkLEFT=(int) (len_in_frames*2/5); + chkRIGHT=(int) (len_in_frames*2/3); } } @@ -226,6 +225,7 @@ void cMarkAdStandalone::CheckStartStop(int frame, bool checkend) 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; @@ -245,16 +245,31 @@ void cMarkAdStandalone::CheckStartStop(int frame, bool checkend) { // use after_iStart newpos=after_iStart->position; + type=after_iStart->type; } if (delta_before<delta_after) { // 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) + { + 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); @@ -515,6 +530,7 @@ void cMarkAdStandalone::CheckInfoAspectRatio() macontext.Video.Options.IgnoreAspectRatio=true; setVideo169=true; setVideo43=false; + setVideo43LB=false; } if ((macontext.Info.AspectRatio.Num==4) && @@ -570,7 +586,7 @@ void cMarkAdStandalone::AddMark(MarkAdMark *Mark) { 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("aspect mark distance too short (%.1fs), deleting (%i,%i)",distance, prev->position,Mark->Position); marks.Del(prev); return; @@ -644,7 +660,7 @@ void cMarkAdStandalone::AddMark(MarkAdMark *Mark) if (macontext.Info.Length>0) { - if ((marks.Count(MT_BORDERCHANGE,0xF0)>=3) && (Mark->Position>chkLEFT) && + if ((Mark->Type==MT_BORDERSTART) && (Mark->Position>chkLEFT) && (Mark->Position<chkRIGHT) && (!macontext.Video.Options.IgnoreLogoDetection)) { if (Mark->Comment) @@ -659,7 +675,7 @@ void cMarkAdStandalone::AddMark(MarkAdMark *Mark) } bool deleteLogoBorder=false; - if ((marks.Count(MT_CHANNELCHANGE,0xF0)>=3) && (Mark->Position>chkLEFT) && + if (((Mark->Type & 0xF0)==MT_CHANNELCHANGE) && (Mark->Position>chkLEFT) && (Mark->Position<chkRIGHT) && (!macontext.Video.Options.IgnoreLogoDetection)) { if (!loggedAlready) @@ -681,14 +697,14 @@ void cMarkAdStandalone::AddMark(MarkAdMark *Mark) macontext.Video.Options.IgnoreAspectRatio=true; } } - macontext.Audio.Info.DolbyDigital51=true; + macontext.Info.Channels=6; setAudio51=true; setAudio20=false; reprocess=true; deleteLogoBorder=true; } - if ((marks.Count(MT_ASPECTCHANGE,0xF0)>=3) && (Mark->Position>chkLEFT) && + if ((Mark->Type==MT_ASPECTSTART) && (Mark->Position>chkLEFT) && (Mark->Position<chkRIGHT) && (!macontext.Video.Options.IgnoreLogoDetection)) { if (!loggedAlready) @@ -701,7 +717,7 @@ void cMarkAdStandalone::AddMark(MarkAdMark *Mark) } isyslog("aspectratio changes detected. logo/border detection disabled"); - if ((!macontext.Info.AspectRatio.Num) && ((Mark->Type & 0xF0)==MT_ASPECTCHANGE)) + if (!macontext.Info.AspectRatio.Num) { isyslog("assuming broadcast aspectratio is 4:3"); macontext.Info.AspectRatio.Num=4; @@ -709,6 +725,19 @@ void cMarkAdStandalone::AddMark(MarkAdMark *Mark) reprocess=true; setVideo43=true; } + else + { + if ((macontext.Info.AspectRatio.Num==4) && + (macontext.Info.AspectRatio.Den==3)) + { + if (marks.Count(MT_BORDERSTART)>0) + { + isyslog("assuming broadcast is in letterbox format"); + setVideo43LB=true; + setVideo43=false; + } + } + } deleteLogoBorder=true; } @@ -1166,7 +1195,6 @@ bool cMarkAdStandalone::ProcessFile(int Number) while ((dataread=read(f,data,datalen))>0) { if (abort) break; - MarkAdMark *mark=NULL; if ((video_demux) && (video) && (streaminfo)) { @@ -1243,9 +1271,15 @@ bool cMarkAdStandalone::ProcessFile(int Number) if ((framecnt-iframe)<=3) { //printf("VID %5i %s %x\n",lastiframe,Timestamp2HMS(lastiframetime),lastiframetime); - - mark=video->Process(lastiframe,iframe); - if (mark) AddMark(mark); + MarkAdMarks *vmarks; + 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! } } @@ -1295,8 +1329,9 @@ bool cMarkAdStandalone::ProcessFile(int Number) if (abs(audiotime-lastiframetime)<DELTATIME) { //printf("AC3 %5i %s %x\n",lastiframe,Timestamp2HMS(audiotime),audiotime); - mark=audio->Process(lastiframe,iframe); - if (mark) AddMark(mark); + MarkAdMark *amark; + amark=audio->Process(lastiframe,iframe); + if (amark) AddMark(amark); } } } @@ -1341,7 +1376,8 @@ bool cMarkAdStandalone::Reset(bool FirstPass) memset(&apkt,0,sizeof(apkt)); iStart=iStartCheck=iStop=iStopCheck=0; - chkLEFT=chkRIGHT=0; + chkLEFT=INT_MAX; + chkRIGHT=INT_MIN; if (FirstPass) { @@ -1370,7 +1406,7 @@ bool cMarkAdStandalone::Reset(bool FirstPass) bool cMarkAdStandalone::CheckDolbyDigital51() { - if (!macontext.Audio.Info.DolbyDigital51) return false; + if (macontext.Info.Channels!=6) return false; if (abort) return false; // Assumption: last mark must be MT_CHANNELSTOP and the position must be @@ -1388,7 +1424,7 @@ bool cMarkAdStandalone::CheckDolbyDigital51() bDecodeVideo=macontext.Config->DecodeVideo; setAudio20=true; setAudio51=false; - macontext.Audio.Info.DolbyDigital51=false; + macontext.Info.Channels=2; isyslog("%s DolbyDigital5.1 marks found", mark ? "not enough" : "no"); isyslog("restarting from scratch"); if ((ac3_demux) && (!macontext.Config->AC3Always)) @@ -1505,7 +1541,7 @@ void cMarkAdStandalone::Process() bool cMarkAdStandalone::SaveInfo() { - if ((!setVideo43) && (!setVideo169) && (!setAudio20) && (!setAudio51)) return true; + if ((!setVideo43) && (!setVideo169) && (!setAudio20) && (!setAudio51) && (!setVideo43LB)) return true; char *src,*dst; if (asprintf(&src,"%s/info%s",directory,isTS ? "" : ".vdr")==-1) return false; @@ -1531,6 +1567,7 @@ 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; @@ -1552,14 +1589,20 @@ bool cMarkAdStandalone::SaveInfo() switch (stream) { case 1: - if ((((type==1) || (type==5)) && (setVideo169)) || - (((type==2) || (type==3) || (type==6) || (type==7)) && (setVideo43))) + if ( (((type==1) || (type==5)) && ((setVideo169) || (setVideo43LB))) || + (((type==2) || (type==3) || (type==6) || (type==7)) && + ((setVideo43) || (setVideo43LB)))) { if (setVideo43) { if (fprintf(w,"X 1 01 %s 4:3\n",lang)<=0) err=true; setVideo43_done=true; } + if (setVideo43LB) + { + if (fprintf(w,"X 1 01 %s 4:3 LetterBox\n",lang)<=0) err=true; + setVideo43LB_done=true; + } if (setVideo169) { if (fprintf(w,"X 1 03 %s 16:9\n",lang)<=0) err=true; @@ -1620,6 +1663,10 @@ bool cMarkAdStandalone::SaveInfo() if (lang[0]==0) strcpy(lang,"und"); + if ((setVideo43LB) && (!setVideo43LB_done) && (!err)) + { + if (fprintf(w,"X 1 01 %s 4:3 LetterBox\n",lang)<=0) err=true; + } if ((setVideo43) && (!setVideo43_done) && (!err)) { if (fprintf(w,"X 1 01 %s 4:3\n",lang)<=0) err=true; @@ -1794,7 +1841,7 @@ bool cMarkAdStandalone::LoadInfo() if (strchr(descr,'5')) { bDecodeVideo=false; - macontext.Audio.Info.DolbyDigital51=true; + macontext.Info.Channels=6; macontext.Video.Options.IgnoreAspectRatio=true; isyslog("broadcast with DolbyDigital5.1, disabling video decoding"); if (macontext.Info.VPid.Type==MARKAD_PIDTYPE_VIDEO_H262) @@ -2150,6 +2197,7 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, const MarkAdConfig * setAudio51=false; setAudio20=false; setVideo43=false; + setVideo43LB=false; setVideo169=false; aspectChecked=false; @@ -2365,7 +2413,8 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, const MarkAdConfig * lastiframetime=0; iframetime=0; audiotime=0; - chkLEFT=chkRIGHT=0; + chkLEFT=INT_MAX; + chkRIGHT=INT_MIN; gettimeofday(&tv1,&tz); } diff --git a/command/markad-standalone.h b/command/markad-standalone.h index 87c86ca..bdbd0ff 100644 --- a/command/markad-standalone.h +++ b/command/markad-standalone.h @@ -208,16 +208,17 @@ unsigned Descriptor_Length: bool bIgnoreVideoInfo; bool bIgnoreTimerInfo; - int tStart; // pretimer in seconds - int iStart; // pretimer as index value - int iStartCheck; // check position for iStart - int iStop; // posttimer as index value - int iStopCheck; // check position for iStop - - bool setAudio51; // set audio to 5.1 in info - bool setAudio20; // set audio to 2.0 in info - bool setVideo43; // set video to 4:3 in info - bool setVideo169; // set video to 16:9 in info + int tStart; // pretimer in seconds + int iStart; // pretimer as index value + int iStartCheck; // check position for iStart + int iStop; // posttimer as index value + int iStopCheck; // check position for iStop + + bool setAudio51; // set audio to 5.1 in info + bool setAudio20; // set audio to 2.0 in info + bool setVideo43; // set video to 4:3 in info + bool setVideo43LB; // set video to 4:3 letterbox in info + bool setVideo169; // set video to 16:9 in info int nextPictType; diff --git a/command/video.cpp b/command/video.cpp index 6e58fb8..1211a3f 100644 --- a/command/video.cpp +++ b/command/video.cpp @@ -480,7 +480,7 @@ int cMarkAdBlackBordersHoriz::Process(int FrameNumber, int *BorderIFrame) if (!macontext->Video.Data.Valid) return 0; if (macontext->Video.Info.FramesPerSecond==0) return 0; // Assumption: If we have 4:3, we should have aspectratio-changes! - if (macontext->Video.Info.AspectRatio.Num==4) return 0; + //if (macontext->Video.Info.AspectRatio.Num==4) return 0; *BorderIFrame=0; int height=macontext->Video.Info.Height-OFFSET; @@ -762,9 +762,7 @@ cMarkAdVideo::cMarkAdVideo(MarkAdContext *maContext) { macontext=maContext; - mark.Comment=NULL; - mark.Position=0; - mark.Type=0; + memset(&marks,0,sizeof(marks)); hborder=new cMarkAdBlackBordersHoriz(maContext); logo = new cMarkAdLogo(maContext); @@ -774,7 +772,7 @@ cMarkAdVideo::cMarkAdVideo(MarkAdContext *maContext) cMarkAdVideo::~cMarkAdVideo() { - ResetMark(); + ResetMarks(); if (hborder) delete hborder; if (logo) delete logo; if (overlap) delete overlap; @@ -788,36 +786,23 @@ void cMarkAdVideo::Clear() if (logo) logo->Clear(); } -void cMarkAdVideo::ResetMark() +void cMarkAdVideo::ResetMarks() { - if (mark.Comment) free(mark.Comment); - mark.Comment=NULL; - mark.Position=0; - mark.Type=0; + for (int i=0; i<marks.maxCount; i++) + { + if (marks.Number[i].Comment) free(marks.Number[i].Comment); + } + memset(&marks,0,sizeof(marks)); } bool cMarkAdVideo::AddMark(int Type, int Position, const char *Comment) { if (!Comment) return false; - if (mark.Comment) - { - int oldlen=strlen(mark.Comment); - mark.Comment=(char *) realloc(mark.Comment,oldlen+10+strlen(Comment)); - if (!mark.Comment) - { - mark.Position=0; - return false; - } - strcat(mark.Comment," ["); - strcat(mark.Comment,Comment); - strcat(mark.Comment,"]"); - } - else - { - mark.Comment=strdup(Comment); - } - mark.Position=Position; - mark.Type=Type; + if (marks.Count>marks.maxCount) return false; + marks.Number[marks.Count].Comment=strdup(Comment); + marks.Number[marks.Count].Position=Position; + marks.Number[marks.Count].Type=Type; + marks.Count++; return true; } @@ -840,11 +825,11 @@ MarkAdPos *cMarkAdVideo::Process2ndPass(int FrameNumber, int Frames, bool Before return overlap->Process(FrameNumber, Frames, BeforeAd); } -MarkAdMark *cMarkAdVideo::Process(int FrameNumber, int FrameNumberNext) +MarkAdMarks *cMarkAdVideo::Process(int FrameNumber, int FrameNumberNext) { if ((!FrameNumber) && (!FrameNumberNext)) return NULL; - ResetMark(); + ResetMarks(); if (!macontext->Video.Options.IgnoreLogoDetection) { @@ -902,6 +887,7 @@ MarkAdMark *cMarkAdVideo::Process(int FrameNumber, int FrameNumberNext) if (AspectRatioChange(&macontext->Video.Info.AspectRatio,&aspectratio)) { char *buf=(char *) calloc(1,256); + if (!buf) return NULL; snprintf(buf,255,"aspect ratio change from %i:%i to %i:%i (", aspectratio.Num,aspectratio.Den, macontext->Video.Info.AspectRatio.Num, @@ -943,5 +929,5 @@ MarkAdMark *cMarkAdVideo::Process(int FrameNumber, int FrameNumberNext) aspectratio.Den=macontext->Video.Info.AspectRatio.Den; } framelast=FrameNumberNext; - return &mark; + return &marks; } diff --git a/command/video.h b/command/video.h index 36fdf5f..0d3a0a0 100644 --- a/command/video.h +++ b/command/video.h @@ -141,14 +141,14 @@ class cMarkAdVideo { private: MarkAdContext *macontext; - MarkAdMark mark; + MarkAdMarks marks; MarkAdAspectRatio aspectratio; cMarkAdBlackBordersHoriz *hborder; cMarkAdLogo *logo; cMarkAdOverlap *overlap; - void ResetMark(); + void ResetMarks(); bool AddMark(int Type, int Position, const char *Comment); bool AspectRatioChange(MarkAdAspectRatio *a, MarkAdAspectRatio *b); @@ -158,7 +158,7 @@ public: cMarkAdVideo(MarkAdContext *maContext); ~cMarkAdVideo(); MarkAdPos *Process2ndPass(int FrameNumber, int Frames, bool BeforeAd); - MarkAdMark *Process(int FrameNumber, int FrameNumberNext); + MarkAdMarks *Process(int FrameNumber, int FrameNumberNext); void Clear(); }; |