diff options
author | Jochen Dolze <vdr@dolze.de> | 2010-09-16 21:37:36 +0200 |
---|---|---|
committer | Jochen Dolze <vdr@dolze.de> | 2010-09-16 21:37:36 +0200 |
commit | 57df9917d4626d93323c7b0d2368fbf5d4748627 (patch) | |
tree | ebfe76fe280db47e223335266eab1bd34afa4226 /command/video.cpp | |
parent | 03fc6351fce571b5ff7454bdfad9d4a0f0fb7679 (diff) | |
download | vdr-plugin-markad-57df9917d4626d93323c7b0d2368fbf5d4748627.tar.gz vdr-plugin-markad-57df9917d4626d93323c7b0d2368fbf5d4748627.tar.bz2 |
Added second pass processing (overlap, audio silence detection)
Diffstat (limited to 'command/video.cpp')
-rw-r--r-- | command/video.cpp | 318 |
1 files changed, 260 insertions, 58 deletions
diff --git a/command/video.cpp b/command/video.cpp index 3072542..06a9bf3 100644 --- a/command/video.cpp +++ b/command/video.cpp @@ -110,13 +110,13 @@ int cMarkAdLogo::Load(char *directory, char *file) -void cMarkAdLogo::Save(int lastiframe, uchar *picture) +void cMarkAdLogo::Save(int framenumber, uchar *picture) { if (!macontext) return; char *buf=NULL; - if (asprintf(&buf,"%s/%06d-%s-A%i_%i.pgm","/tmp/",lastiframe, + if (asprintf(&buf,"%s/%06d-%s-A%i_%i.pgm","/tmp/",framenumber, macontext->Info.ChannelID, area.aspectratio.Num,area.aspectratio.Den)!=-1) { @@ -139,7 +139,7 @@ void cMarkAdLogo::Save(int lastiframe, uchar *picture) } } -int cMarkAdLogo::Detect(int lastiframe, int *logoiframe) +int cMarkAdLogo::Detect(int framenumber, int *logoframenumber) { // Detection is made with Sobel-Operator @@ -300,18 +300,18 @@ int cMarkAdLogo::Detect(int lastiframe, int *logoiframe) if (area.counter>=LOGO_VMAXCOUNT) { area.status=ret=LOGO; - *logoiframe=area.lastiframe; + *logoframenumber=area.framenumber; area.counter=0; } else { - if (!area.counter) area.lastiframe=lastiframe; + if (!area.counter) area.framenumber=framenumber; area.counter++; } } else { - area.lastiframe=lastiframe; + area.framenumber=framenumber; area.counter=0; } } @@ -323,7 +323,7 @@ int cMarkAdLogo::Detect(int lastiframe, int *logoiframe) if (area.counter>=LOGO_IMAXCOUNT) { area.status=ret=NOLOGO; - *logoiframe=area.lastiframe; + *logoframenumber=area.framenumber; area.counter=0; } else @@ -343,21 +343,21 @@ int cMarkAdLogo::Detect(int lastiframe, int *logoiframe) } #if 0 - printf("%5i %3i %4i %4i %i %i %i\n",lastiframe,SUMA,area.rpixel,area.mpixel, + printf("%5i %3i %4i %4i %i %i %i\n",framenumber,SUMA,area.rpixel,area.mpixel, (area.rpixel>=(area.mpixel*LOGO_VMARK)),(area.rpixel<(area.mpixel*LOGO_IMARK)), area.counter ); - Save(lastiframe,area.sobel); // TODO: JUST FOR DEBUGGING! + Save(framenumber,area.sobel); // TODO: JUST FOR DEBUGGING! #endif } else { - Save(lastiframe,area.sobel); + Save(framenumber,area.sobel); } } return ret; } -int cMarkAdLogo::Process(int LastIFrame, int *LogoIFrame) +int cMarkAdLogo::Process(int FrameNumber, int *LogoFrameNumber) { if (!macontext) return ERROR; if (!macontext->Video.Data.Valid) return ERROR; @@ -413,7 +413,7 @@ int cMarkAdLogo::Process(int LastIFrame, int *LogoIFrame) if (!area.valid) return ERROR; - return Detect(LastIFrame,LogoIFrame); + return Detect(FrameNumber,LogoFrameNumber); } cMarkAdBlackBordersHoriz::cMarkAdBlackBordersHoriz(MarkAdContext *maContext) @@ -426,10 +426,10 @@ cMarkAdBlackBordersHoriz::cMarkAdBlackBordersHoriz(MarkAdContext *maContext) void cMarkAdBlackBordersHoriz::Clear() { borderstatus=UNINITIALIZED; - borderiframe=-1; + borderframenumber=-1; } -int cMarkAdBlackBordersHoriz::Process(int LastIFrame, int *BorderIFrame) +int cMarkAdBlackBordersHoriz::Process(int FrameNumber, int *BorderIFrame) { #define CHECKHEIGHT 20 #define BRIGHTNESS 20 @@ -482,9 +482,9 @@ int cMarkAdBlackBordersHoriz::Process(int LastIFrame, int *BorderIFrame) if ((fbottom) && (ftop)) { - if (borderiframe==-1) + if (borderframenumber==-1) { - borderiframe=LastIFrame; + borderframenumber=FrameNumber; } else { @@ -492,52 +492,227 @@ int cMarkAdBlackBordersHoriz::Process(int LastIFrame, int *BorderIFrame) switch (borderstatus) { case UNINITIALIZED: - if (LastIFrame>(borderiframe+macontext->Video.Info.FramesPerSecond*MINSECS)) + if (FrameNumber>(borderframenumber+macontext->Video.Info.FramesPerSecond*MINSECS)) { borderstatus=BORDER; } break; case NOBORDER: - if (LastIFrame>(borderiframe+macontext->Video.Info.FramesPerSecond*MINSECS)) + if (FrameNumber>(borderframenumber+macontext->Video.Info.FramesPerSecond*MINSECS)) { - *BorderIFrame=borderiframe; + *BorderIFrame=borderframenumber; borderstatus=BORDER; return 1; // detected start of black border } break; case BORDER: - borderiframe=LastIFrame; + borderframenumber=FrameNumber; break; } } } else { - if (borderiframe!=-1) + if (borderframenumber!=-1) { if (borderstatus==BORDER) { - *BorderIFrame=borderiframe; + *BorderIFrame=borderframenumber; borderstatus=NOBORDER; - borderiframe=-1; + borderframenumber=-1; return -1; // detected stop of black border } else { - borderiframe=-1; + borderframenumber=-1; } } else { - borderiframe=-1; + borderframenumber=-1; borderstatus=NOBORDER; } } return 0; } +cMarkAdOverlap::cMarkAdOverlap(MarkAdContext *maContext) +{ + macontext=maContext; + + histbuf[BEFORE]=NULL; + histbuf[AFTER]=NULL; + result.CommentBefore=NULL; + result.CommentAfter=NULL; + Clear(); +} + +cMarkAdOverlap::~cMarkAdOverlap() +{ + Clear(); +} + +void cMarkAdOverlap::Clear() +{ + histcnt[BEFORE]=0; + histcnt[AFTER]=0; + histframes[BEFORE]=0; + histframes[AFTER]=0; + if (histbuf[BEFORE]) + { + delete[] histbuf[BEFORE]; + histbuf[BEFORE]=NULL; + } + if (histbuf[AFTER]) + { + delete[] histbuf[AFTER]; + histbuf[AFTER]=NULL; + } + if (result.CommentBefore) free(result.CommentBefore); + if (result.CommentAfter) free(result.CommentAfter); + memset(&result,0,sizeof(result)); + similarCutOff=0; + similarMaxCnt=0; + + lastframenumber=-1; +} + +void cMarkAdOverlap::getHistogram(simpleHistogram &dest) +{ + memset(dest,0,sizeof(simpleHistogram)); + for (int Y=0; Y<macontext->Video.Info.Height;Y++) + { + for (int X=0; X<macontext->Video.Info.Width;X++) + { + uchar val=macontext->Video.Data.Plane[0][X+(Y*macontext->Video.Data.PlaneLinesize[0])]; + dest[val]++; + } + } +} + +bool cMarkAdOverlap::areSimilar(simpleHistogram &hist1, simpleHistogram &hist2) +{ + int similar=0; + for (int i=0; i<256; i++) + { + similar+=abs(hist1[i]-hist2[i]); + } + if (similar<similarCutOff) return true; + return false; +} + +MarkAdPos *cMarkAdOverlap::Detect() +{ + int start=0,simcnt=0; + int tmpA=0,tmpB=0; + if (result.FrameNumberBefore==-1) return NULL; + result.FrameNumberBefore=-1; + for (int B=0; B<histcnt[BEFORE]; B++) + { + for (int A=start; A<histcnt[AFTER]; A++) + { + bool simil=areSimilar(histbuf[BEFORE][B].histogram,histbuf[AFTER][A].histogram); + if (simil) + { + tmpA=A; + tmpB=B; + start=A+1; + simcnt++; + break; + } + else + { + //if (simcnt) printf("%i %i %i\n",simcnt,histbuf[BEFORE][B].framenumber,histbuf[AFTER][A].framenumber); + + if (simcnt>similarMaxCnt) + { + result.FrameNumberBefore=histbuf[BEFORE][tmpB].framenumber; + result.FrameNumberAfter=histbuf[AFTER][tmpA].framenumber; + } + else + { + start=0; + } + simcnt=0; + } + } + } + if (result.FrameNumberBefore==-1) + { + if (simcnt>similarMaxCnt) + { + result.FrameNumberBefore=histbuf[BEFORE][tmpB].framenumber; + result.FrameNumberAfter=histbuf[AFTER][tmpA].framenumber; + } + else + { + return NULL; + } + } + + if (asprintf(&result.CommentBefore,"detected overlap before (%i)",result.FrameNumberBefore)==-1) + { + result.CommentBefore=NULL; + } + if (asprintf(&result.CommentAfter,"detected overlap after (%i)",result.FrameNumberAfter)==-1) + { + result.CommentAfter=NULL; + } + return &result; +} + +MarkAdPos *cMarkAdOverlap::Process(int FrameNumber, int Frames, bool BeforeAd) +{ + if ((lastframenumber>0) && (!similarMaxCnt)) + { + similarCutOff=50000; + similarMaxCnt=4; + } + + if (BeforeAd) + { + if ((histframes[BEFORE]) && (histcnt[BEFORE]>=histframes[BEFORE])) + { + if (result.FrameNumberBefore) + { + Clear(); + } + else + { + return NULL; + } + } + if (!histbuf[BEFORE]) + { + histframes[BEFORE]=Frames; + histbuf[BEFORE]=new histbuffer[Frames+1]; + } + getHistogram(histbuf[BEFORE][histcnt[BEFORE]].histogram); + histbuf[BEFORE][histcnt[BEFORE]].framenumber=FrameNumber; + histcnt[BEFORE]++; + } + else + { + if (!histbuf[AFTER]) + { + histframes[AFTER]=Frames; + histbuf[AFTER]=new histbuffer[Frames+1]; + } + + if (histcnt[AFTER]>=histframes[AFTER]-1) + { + if (result.FrameNumberBefore) return NULL; + return Detect(); + } + getHistogram(histbuf[AFTER][histcnt[AFTER]].histogram); + histbuf[AFTER][histcnt[AFTER]].framenumber=FrameNumber; + histcnt[AFTER]++; + } + lastframenumber=FrameNumber; + return NULL; +} cMarkAdVideo::cMarkAdVideo(MarkAdContext *maContext) { @@ -549,6 +724,7 @@ cMarkAdVideo::cMarkAdVideo(MarkAdContext *maContext) hborder=new cMarkAdBlackBordersHoriz(maContext); logo = new cMarkAdLogo(maContext); + overlap = NULL; Clear(); } @@ -557,6 +733,7 @@ cMarkAdVideo::~cMarkAdVideo() ResetMark(); if (hborder) delete hborder; if (logo) delete logo; + if (overlap) delete overlap; } void cMarkAdVideo::Clear() @@ -610,56 +787,68 @@ bool cMarkAdVideo::AspectRatioChange(MarkAdAspectRatio *a, MarkAdAspectRatio *b) } -MarkAdMark *cMarkAdVideo::Process(int LastIFrame) +MarkAdPos *cMarkAdVideo::Process2ndPass(int FrameNumber, int Frames, bool BeforeAd) +{ + if (!FrameNumber) return NULL; + if (!overlap) overlap=new cMarkAdOverlap(macontext); + if (!overlap) return NULL; + + return overlap->Process(FrameNumber, Frames, BeforeAd); +} + +MarkAdMark *cMarkAdVideo::Process(int FrameNumber, int FrameNumberNext) { + if ((!FrameNumber) && (!FrameNumberNext)) return NULL; + ResetMark(); - if (!LastIFrame) return NULL; if (!macontext->Video.Options.IgnoreLogoDetection) { - int logoiframe; - int lret=logo->Process(LastIFrame,&logoiframe); + int logoframenumber; + int lret=logo->Process(FrameNumber,&logoframenumber); if ((lret>=-1) && (lret!=0)) { char *buf=NULL; if (lret>0) { - if (asprintf(&buf,"detected logo start (%i)",logoiframe)!=-1) + if (asprintf(&buf,"detected logo start (%i)",logoframenumber)!=-1) { - AddMark(MT_LOGOSTART,logoiframe,buf); + AddMark(MT_LOGOSTART,logoframenumber,buf); free(buf); } } else { - if (asprintf(&buf,"detected logo stop (%i)",logoiframe)!=-1) + if (asprintf(&buf,"detected logo stop (%i)",logoframenumber)!=-1) { - AddMark(MT_LOGOSTOP,logoiframe,buf); + AddMark(MT_LOGOSTOP,logoframenumber,buf); free(buf); } } } } - int borderiframe; - int hret=hborder->Process(LastIFrame,&borderiframe); + int borderframenumber; + int hret=hborder->Process(FrameNumber,&borderframenumber); - if ((hret>0) && (borderiframe)) + if ((hret>0) && (borderframenumber)) { char *buf=NULL; - if (asprintf(&buf,"detected start of horiz. borders (%i [%i])",borderiframe,LastIFrame)!=-1) + if (asprintf(&buf,"detected start of horiz. borders (%i [%i])", + borderframenumber,FrameNumber)!=-1) { - AddMark(MT_BORDERSTART,borderiframe,buf); + AddMark(MT_BORDERSTART,borderframenumber,buf); free(buf); } } - if ((hret<0) && (borderiframe)) + if ((hret<0) && (borderframenumber)) { char *buf=NULL; - if (asprintf(&buf,"detected stop of horiz. borders (%i [%i])",borderiframe,LastIFrame)!=-1) + if (asprintf(&buf,"detected stop of horiz. borders (%i [%i])", + borderframenumber,FrameNumber)!=-1) { - AddMark(MT_BORDERSTOP,borderiframe,buf); + AddMark(MT_BORDERSTOP,borderframenumber,buf); free(buf); } } @@ -668,34 +857,47 @@ MarkAdMark *cMarkAdVideo::Process(int LastIFrame) { if (AspectRatioChange(&macontext->Video.Info.AspectRatio,&aspectratio)) { - char *buf=NULL; - if (asprintf(&buf,"aspect ratio change from %i:%i to %i:%i (%i)", - aspectratio.Num,aspectratio.Den, - macontext->Video.Info.AspectRatio.Num, - macontext->Video.Info.AspectRatio.Den,LastIFrame)!=-1) + char *buf=(char *) calloc(1,256); + snprintf(buf,255,"aspect ratio change from %i:%i to %i:%i (", + aspectratio.Num,aspectratio.Den, + macontext->Video.Info.AspectRatio.Num, + macontext->Video.Info.AspectRatio.Den); + + if ((macontext->Info.AspectRatio.Num) && (macontext->Info.AspectRatio.Den)) { - if ((macontext->Info.AspectRatio.Num) && (macontext->Info.AspectRatio.Den)) + if ((macontext->Video.Info.AspectRatio.Num==macontext->Info.AspectRatio.Num) && + (macontext->Video.Info.AspectRatio.Den==macontext->Info.AspectRatio.Den)) { - if ((macontext->Video.Info.AspectRatio.Num==macontext->Info.AspectRatio.Num) && - (macontext->Video.Info.AspectRatio.Den==macontext->Info.AspectRatio.Den)) - { - AddMark(MT_ASPECTSTART,LastIFrame,buf); - } - else - { - AddMark(MT_ASPECTSTOP,LastIFrame,buf); - } + char nbuf[20]; + snprintf(nbuf,sizeof(nbuf),"%i)",FrameNumberNext); + nbuf[19]=0; + strcat(buf,nbuf); + AddMark(MT_ASPECTSTART,FrameNumberNext,buf); } else { - AddMark(MT_ASPECTCHANGE,LastIFrame,buf); + char nbuf[20]; + snprintf(nbuf,sizeof(nbuf),"%i)",framelast); + nbuf[19]=0; + strcat(buf,nbuf); + AddMark(MT_ASPECTSTOP,framelast,buf); } - free(buf); } + else + { + char nbuf[20]; + snprintf(nbuf,sizeof(nbuf),"%i)",FrameNumber); + nbuf[19]=0; + strcat(buf,nbuf); + + AddMark(MT_ASPECTCHANGE,FrameNumber,buf); + } + free(buf); } aspectratio.Num=macontext->Video.Info.AspectRatio.Num; aspectratio.Den=macontext->Video.Info.AspectRatio.Den; } + framelast=FrameNumberNext; return &mark; } |