diff options
Diffstat (limited to 'command/video.cpp')
-rw-r--r-- | command/video.cpp | 312 |
1 files changed, 148 insertions, 164 deletions
diff --git a/command/video.cpp b/command/video.cpp index cf5f649..be2cb5c 100644 --- a/command/video.cpp +++ b/command/video.cpp @@ -47,13 +47,13 @@ cMarkAdLogo::cMarkAdLogo(MarkAdContext *maContext) if (maContext->Info.VPid.Type==MARKAD_PIDTYPE_VIDEO_H264) { - LOGOWIDTH=LOGO_DEFHDWIDTH; LOGOHEIGHT=LOGO_DEFHDHEIGHT; + LOGOWIDTH=LOGO_DEFHDWIDTH; } else { - LOGOWIDTH=LOGO_DEFWIDTH; LOGOHEIGHT=LOGO_DEFHEIGHT; + LOGOWIDTH=LOGO_DEFWIDTH; } pixfmt_info=false; @@ -63,7 +63,7 @@ cMarkAdLogo::cMarkAdLogo(MarkAdContext *maContext) void cMarkAdLogo::Clear() { memset(&area,0,sizeof(area)); - area.status=UNINITIALIZED; + area.status=LOGO_UNINITIALIZED; } int cMarkAdLogo::Load(const char *directory, char *file, int plane) @@ -105,7 +105,11 @@ int cMarkAdLogo::Load(const char *directory, char *file, int plane) return -2; } - if (fread(&area.mask[plane],1,width*height,pFile)!=(size_t) (width*height)) return -2; + if (fread(&area.mask[plane],1,width*height,pFile)!=(size_t) (width*height)) + { + fclose(pFile); + return -2; + } if (!area.mpixel[plane]) { @@ -218,8 +222,9 @@ int cMarkAdLogo::SobelPlane(int plane) return 0; } - int boundary=15; + int boundary=6; int cutval=127; + //int cutval=60; int width=LOGOWIDTH; if (plane>0) @@ -327,36 +332,36 @@ int cMarkAdLogo::Detect(int framenumber, int *logoframenumber) mpixel+=area.mpixel[plane]; } } - if (extract) return NOCHANGE; - if (!processed) return ERROR; + if (extract) return LOGO_NOCHANGE; + if (!processed) return LOGO_ERROR; if (processed==1) { - if ((area.intensity>100) || (area.status!=LOGO) && - (area.intensity>180)) return NOCHANGE; + if ((area.intensity>100) || (area.status!=LOGO_VISIBLE) && + (area.intensity>180)) return LOGO_NOCHANGE; } - int ret=NOCHANGE; - if (area.status==UNINITIALIZED) + int ret=LOGO_NOCHANGE; + if (area.status==LOGO_UNINITIALIZED) { // Initialize - if (rpixel>(mpixel*LOGO_VMARK)) + if (rpixel>=(mpixel*LOGO_VMARK)) { - area.status=LOGO; + area.status=ret=LOGO_VISIBLE; } else { - area.status=NOLOGO; + area.status=LOGO_INVISIBLE; } } if (rpixel>=(mpixel*LOGO_VMARK)) { - if (area.status==NOLOGO) + if (area.status==LOGO_INVISIBLE) { if (area.counter>=LOGO_VMAXCOUNT) { - area.status=ret=LOGO; + area.status=ret=LOGO_VISIBLE; *logoframenumber=area.framenumber; area.counter=0; } @@ -375,11 +380,11 @@ int cMarkAdLogo::Detect(int framenumber, int *logoframenumber) if (rpixel<(mpixel*LOGO_IMARK)) { - if (area.status==LOGO) + if (area.status==LOGO_VISIBLE) { if (area.counter>=LOGO_IMAXCOUNT) { - area.status=ret=NOLOGO; + area.status=ret=LOGO_INVISIBLE; *logoframenumber=area.framenumber; area.counter=0; } @@ -404,12 +409,16 @@ int cMarkAdLogo::Detect(int framenumber, int *logoframenumber) int cMarkAdLogo::Process(int FrameNumber, int *LogoFrameNumber) { - if (!macontext) return ERROR; - if (!macontext->Video.Data.Valid) return ERROR; - if (!macontext->Video.Info.Width) return ERROR; - if (!macontext->Video.Info.Height) return ERROR; - if (!macontext->Config->logoDirectory[0]) return ERROR; - if (!macontext->Info.ChannelName) return ERROR; + if (!macontext) return LOGO_ERROR; + if (!macontext->Video.Data.Valid) + { + area.status=LOGO_UNINITIALIZED; + return LOGO_ERROR; + } + if (!macontext->Video.Info.Width) return LOGO_ERROR; + if (!macontext->Video.Info.Height) return LOGO_ERROR; + if (!macontext->Config->logoDirectory[0]) return LOGO_ERROR; + if (!macontext->Info.ChannelName) return LOGO_ERROR; if (macontext->Config->logoExtraction==-1) { @@ -469,7 +478,7 @@ cMarkAdBlackBordersHoriz::cMarkAdBlackBordersHoriz(MarkAdContext *maContext) void cMarkAdBlackBordersHoriz::Clear() { - borderstatus=UNINITIALIZED; + borderstatus=HBORDER_UNINITIALIZED; borderframenumber=-1; } @@ -537,23 +546,23 @@ int cMarkAdBlackBordersHoriz::Process(int FrameNumber, int *BorderIFrame) #define MINSECS 240 switch (borderstatus) { - case UNINITIALIZED: + case HBORDER_UNINITIALIZED: if (FrameNumber>(borderframenumber+macontext->Video.Info.FramesPerSecond*MINSECS)) { - borderstatus=BORDER; + borderstatus=HBORDER_VISIBLE; } break; - case NOBORDER: + case HBORDER_INVISIBLE: if (FrameNumber>(borderframenumber+macontext->Video.Info.FramesPerSecond*MINSECS)) { *BorderIFrame=borderframenumber; - borderstatus=BORDER; + borderstatus=HBORDER_VISIBLE; return 1; // detected start of black border } break; - case BORDER: + case HBORDER_VISIBLE: borderframenumber=FrameNumber; break; } @@ -563,10 +572,10 @@ int cMarkAdBlackBordersHoriz::Process(int FrameNumber, int *BorderIFrame) { if (borderframenumber!=-1) { - if (borderstatus==BORDER) + if (borderstatus==HBORDER_VISIBLE) { *BorderIFrame=borderframenumber; - borderstatus=NOBORDER; + borderstatus=HBORDER_INVISIBLE; borderframenumber=-1; return -1; // detected stop of black border } @@ -578,7 +587,7 @@ int cMarkAdBlackBordersHoriz::Process(int FrameNumber, int *BorderIFrame) else { borderframenumber=-1; - borderstatus=NOBORDER; + borderstatus=HBORDER_INVISIBLE; } } return 0; @@ -588,10 +597,8 @@ cMarkAdOverlap::cMarkAdOverlap(MarkAdContext *maContext) { macontext=maContext; - histbuf[BEFORE]=NULL; - histbuf[AFTER]=NULL; - result.CommentBefore=NULL; - result.CommentAfter=NULL; + histbuf[OV_BEFORE]=NULL; + histbuf[OV_AFTER]=NULL; Clear(); } @@ -602,22 +609,20 @@ cMarkAdOverlap::~cMarkAdOverlap() void cMarkAdOverlap::Clear() { - histcnt[BEFORE]=0; - histcnt[AFTER]=0; - histframes[BEFORE]=0; - histframes[AFTER]=0; - if (histbuf[BEFORE]) + histcnt[OV_BEFORE]=0; + histcnt[OV_AFTER]=0; + histframes[OV_BEFORE]=0; + histframes[OV_AFTER]=0; + if (histbuf[OV_BEFORE]) { - delete[] histbuf[BEFORE]; - histbuf[BEFORE]=NULL; + delete[] histbuf[OV_BEFORE]; + histbuf[OV_BEFORE]=NULL; } - if (histbuf[AFTER]) + if (histbuf[OV_AFTER]) { - delete[] histbuf[AFTER]; - histbuf[AFTER]=NULL; + delete[] histbuf[OV_AFTER]; + histbuf[OV_AFTER]=NULL; } - if (result.CommentBefore) free(result.CommentBefore); - if (result.CommentAfter) free(result.CommentAfter); memset(&result,0,sizeof(result)); similarCutOff=0; similarMaxCnt=0; @@ -656,12 +661,12 @@ MarkAdPos *cMarkAdOverlap::Detect() int tmpA=0,tmpB=0; if (result.FrameNumberBefore==-1) return NULL; result.FrameNumberBefore=-1; - for (int B=0; B<histcnt[BEFORE]; B++) + for (int B=0; B<histcnt[OV_BEFORE]; B++) { - for (int A=start; A<histcnt[AFTER]; A++) + for (int A=start; A<histcnt[OV_AFTER]; A++) { - //printf("%6i %6i ",histbuf[BEFORE][B].framenumber,histbuf[AFTER][A].framenumber); - bool simil=areSimilar(histbuf[BEFORE][B].histogram,histbuf[AFTER][A].histogram); + //printf("%6i %6i ",histbuf[OV_BEFORE][B].framenumber,histbuf[OV_AFTER][A].framenumber); + bool simil=areSimilar(histbuf[OV_BEFORE][B].histogram,histbuf[OV_AFTER][A].histogram); if (simil) { tmpA=A; @@ -675,15 +680,15 @@ MarkAdPos *cMarkAdOverlap::Detect() } else { - //if (simcnt) printf("%i %i %i\n",simcnt,histbuf[BEFORE][B].framenumber,histbuf[AFTER][A].framenumber); + //if (simcnt) printf("simcnt=%i\n",simcnt); if (simcnt>similarMaxCnt) { - if ((histbuf[BEFORE][tmpB].framenumber>result.FrameNumberBefore) && - (histbuf[AFTER][tmpA].framenumber>result.FrameNumberAfter)) + if ((histbuf[OV_BEFORE][tmpB].framenumber>result.FrameNumberBefore) && + (histbuf[OV_AFTER][tmpA].framenumber>result.FrameNumberAfter)) { - result.FrameNumberBefore=histbuf[BEFORE][tmpB].framenumber; - result.FrameNumberAfter=histbuf[AFTER][tmpA].framenumber; + result.FrameNumberBefore=histbuf[OV_BEFORE][tmpB].framenumber; + result.FrameNumberAfter=histbuf[OV_AFTER][tmpA].framenumber; } } else @@ -698,23 +703,14 @@ MarkAdPos *cMarkAdOverlap::Detect() { if (simcnt>similarMaxCnt) { - result.FrameNumberBefore=histbuf[BEFORE][tmpB].framenumber; - result.FrameNumberAfter=histbuf[AFTER][tmpA].framenumber; + result.FrameNumberBefore=histbuf[OV_BEFORE][tmpB].framenumber; + result.FrameNumberAfter=histbuf[OV_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; } @@ -722,13 +718,13 @@ MarkAdPos *cMarkAdOverlap::Process(int FrameNumber, int Frames, bool BeforeAd) { if ((lastframenumber>0) && (!similarMaxCnt)) { - similarCutOff=60000; // lower is harder! + similarCutOff=50000; // lower is harder! similarMaxCnt=4; } if (BeforeAd) { - if ((histframes[BEFORE]) && (histcnt[BEFORE]>=histframes[BEFORE])) + if ((histframes[OV_BEFORE]) && (histcnt[OV_BEFORE]>=histframes[OV_BEFORE])) { if (result.FrameNumberBefore) { @@ -739,31 +735,31 @@ MarkAdPos *cMarkAdOverlap::Process(int FrameNumber, int Frames, bool BeforeAd) return NULL; } } - if (!histbuf[BEFORE]) + if (!histbuf[OV_BEFORE]) { - histframes[BEFORE]=Frames; - histbuf[BEFORE]=new histbuffer[Frames+1]; + histframes[OV_BEFORE]=Frames; + histbuf[OV_BEFORE]=new histbuffer[Frames+1]; } - getHistogram(histbuf[BEFORE][histcnt[BEFORE]].histogram); - histbuf[BEFORE][histcnt[BEFORE]].framenumber=FrameNumber; - histcnt[BEFORE]++; + getHistogram(histbuf[OV_BEFORE][histcnt[OV_BEFORE]].histogram); + histbuf[OV_BEFORE][histcnt[OV_BEFORE]].framenumber=FrameNumber; + histcnt[OV_BEFORE]++; } else { - if (!histbuf[AFTER]) + if (!histbuf[OV_AFTER]) { - histframes[AFTER]=Frames; - histbuf[AFTER]=new histbuffer[Frames+1]; + histframes[OV_AFTER]=Frames; + histbuf[OV_AFTER]=new histbuffer[Frames+1]; } - if (histcnt[AFTER]>=histframes[AFTER]-1) + if (histcnt[OV_AFTER]>=histframes[OV_AFTER]-1) { if (result.FrameNumberBefore) return NULL; return Detect(); } - getHistogram(histbuf[AFTER][histcnt[AFTER]].histogram); - histbuf[AFTER][histcnt[AFTER]].framenumber=FrameNumber; - histcnt[AFTER]++; + getHistogram(histbuf[OV_AFTER][histcnt[OV_AFTER]].histogram); + histbuf[OV_AFTER][histcnt[OV_AFTER]].framenumber=FrameNumber; + histcnt[OV_AFTER]++; } lastframenumber=FrameNumber; return NULL; @@ -783,7 +779,7 @@ cMarkAdVideo::cMarkAdVideo(MarkAdContext *maContext) cMarkAdVideo::~cMarkAdVideo() { - ResetMarks(); + resetmarks(); if (hborder) delete hborder; if (logo) delete logo; if (overlap) delete overlap; @@ -793,41 +789,57 @@ void cMarkAdVideo::Clear() { aspectratio.Num=0; aspectratio.Den=0; + framelast=0; + framebeforelast=0; if (hborder) hborder->Clear(); if (logo) logo->Clear(); } -void cMarkAdVideo::ResetMarks() +void cMarkAdVideo::resetmarks() { - 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) +bool cMarkAdVideo::addmark(int type, int position, MarkAdAspectRatio *before, + MarkAdAspectRatio *after) { - if (!Comment) return false; 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; + if (before) + { + marks.Number[marks.Count].AspectRatioBefore.Num=before->Num; + marks.Number[marks.Count].AspectRatioBefore.Den=before->Den; + } + if (after) + { + marks.Number[marks.Count].AspectRatioAfter.Num=after->Num; + marks.Number[marks.Count].AspectRatioAfter.Den=after->Den; + } + marks.Number[marks.Count].Position=position; + marks.Number[marks.Count].Type=type; marks.Count++; return true; } -bool cMarkAdVideo::AspectRatioChange(MarkAdAspectRatio *a, MarkAdAspectRatio *b) +bool cMarkAdVideo::aspectratiochange(MarkAdAspectRatio &a, MarkAdAspectRatio &b, bool &start) { - if ((!a) || (!b)) return false; - - if (a->Num==0 || a->Den==0 || b->Num==0 || b->Den==0) return false; - if ((a->Num!=b->Num) && (a->Den!=b->Den)) return true; + start=false; + if (a.Num==0 || a.Den==0 || b.Num==0 || b.Den==0) + { + if (((a.Num==4) || (b.Num==4)) && ((a.Den==3) || (b.Den==3))) + { + start=true; + } + else + { + return false; + } + } + if ((a.Num!=b.Num) && (a.Den!=b.Den)) return true; return false; } -MarkAdPos *cMarkAdVideo::Process2ndPass(int FrameNumber, int Frames, bool BeforeAd) +MarkAdPos *cMarkAdVideo::ProcessOverlap(int FrameNumber, int Frames, bool BeforeAd) { if (!FrameNumber) return NULL; if (!overlap) overlap=new cMarkAdOverlap(macontext); @@ -840,7 +852,7 @@ MarkAdMarks *cMarkAdVideo::Process(int FrameNumber, int FrameNumberNext) { if ((!FrameNumber) && (!FrameNumberNext)) return NULL; - ResetMarks(); + resetmarks(); if (!macontext->Video.Options.IgnoreLogoDetection) { @@ -848,97 +860,69 @@ MarkAdMarks *cMarkAdVideo::Process(int FrameNumber, int FrameNumberNext) int lret=logo->Process(FrameNumber,&logoframenumber); if ((lret>=-1) && (lret!=0)) { - char *buf=NULL; if (lret>0) { - if (asprintf(&buf,"detected logo start (%i)",logoframenumber)!=-1) - { - AddMark(MT_LOGOSTART,logoframenumber,buf); - free(buf); - } + addmark(MT_LOGOSTART,logoframenumber); } else { - if (asprintf(&buf,"detected logo stop (%i)",logoframenumber)!=-1) - { - AddMark(MT_LOGOSTOP,logoframenumber,buf); - free(buf); - } + addmark(MT_LOGOSTOP,logoframenumber); } } } + else + { + logo->SetStatusUninitialized(); + } - int borderframenumber; - int hret=hborder->Process(FrameNumber,&borderframenumber); + int hborderframenumber; + int hret=hborder->Process(FrameNumber,&hborderframenumber); - if ((hret>0) && (borderframenumber)) + if ((hret>0) && (hborderframenumber)) { - char *buf=NULL; - if (asprintf(&buf,"detected start of horiz. borders (%i [%i])", - borderframenumber,FrameNumber)!=-1) - { - AddMark(MT_BORDERSTART,borderframenumber,buf); - free(buf); - } + addmark(MT_HBORDERSTART,hborderframenumber); } - if ((hret<0) && (borderframenumber)) + if ((hret<0) && (hborderframenumber)) { - char *buf=NULL; - if (asprintf(&buf,"detected stop of horiz. borders (%i [%i])", - borderframenumber,FrameNumber)!=-1) - { - AddMark(MT_BORDERSTOP,borderframenumber,buf); - free(buf); - } + addmark(MT_HBORDERSTOP,hborderframenumber); } if (!macontext->Video.Options.IgnoreAspectRatio) { - if (AspectRatioChange(&macontext->Video.Info.AspectRatio,&aspectratio)) + bool start; + if (aspectratiochange(macontext->Video.Info.AspectRatio,aspectratio,start)) { - 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, - macontext->Video.Info.AspectRatio.Den); + if ((logo->Status()==LOGO_VISIBLE) && (!start)) + { + addmark(MT_LOGOSTOP,framebeforelast); + logo->SetStatusLogoInvisible(); + } - if ((macontext->Info.AspectRatio.Num) && (macontext->Info.AspectRatio.Den)) + if ((macontext->Video.Info.AspectRatio.Num==4) && + (macontext->Video.Info.AspectRatio.Den==3)) { - if ((macontext->Video.Info.AspectRatio.Num==macontext->Info.AspectRatio.Num) && - (macontext->Video.Info.AspectRatio.Den==macontext->Info.AspectRatio.Den)) - { - char nbuf[20]; - snprintf(nbuf,sizeof(nbuf),"%i)*",FrameNumberNext); - nbuf[19]=0; - strcat(buf,nbuf); - AddMark(MT_ASPECTSTART,FrameNumberNext,buf); - } - else - { - char nbuf[20]; - snprintf(nbuf,sizeof(nbuf),"%i)",framelast); - nbuf[19]=0; - strcat(buf,nbuf); - AddMark(MT_ASPECTSTOP,framelast,buf); - } + addmark(MT_ASPECTSTART,start ? FrameNumber : FrameNumberNext, + &aspectratio,&macontext->Video.Info.AspectRatio); } else { - char nbuf[20]; - snprintf(nbuf,sizeof(nbuf),"%i)?",FrameNumber); - nbuf[19]=0; - strcat(buf,nbuf); - - AddMark(MT_ASPECTCHANGE,FrameNumber,buf); + addmark(MT_ASPECTSTOP,framelast,&aspectratio, + &macontext->Video.Info.AspectRatio); } - free(buf); } aspectratio.Num=macontext->Video.Info.AspectRatio.Num; aspectratio.Den=macontext->Video.Info.AspectRatio.Den; } framelast=FrameNumberNext; - return &marks; + framebeforelast=FrameNumber; + if (marks.Count) + { + return &marks; + } + else + { + return NULL; + } } |