diff options
-rw-r--r-- | demux.h | 5 | ||||
-rw-r--r-- | global.h | 2 | ||||
-rw-r--r-- | markad-standalone.cpp | 13 | ||||
-rw-r--r-- | video.cpp | 154 | ||||
-rw-r--r-- | video.h | 28 |
5 files changed, 113 insertions, 89 deletions
@@ -22,14 +22,9 @@ #include "ts2pkt.h" #include "pes2es.h" -#if 1 -#include <unistd.h> -#endif - class cMarkAdDemux { private: - int recvnumber; cMarkAdVDR2Pkt *vdr2pkt; cMarkAdTS2Pkt *ts2pkt; cMarkAdPES2ES *pes2audioes; @@ -29,6 +29,7 @@ typedef unsigned char uchar; #define MT_CHANNELSTOP 0x31 #define MT_LOGOSTART 0x40 #define MT_LOGOSTOP 0x41 +#define MT_BORDERCHANGE 0x50 #define MT_BORDERSTART 0x50 #define MT_BORDERSTOP 0x51 #define MT_SILENCECHANGE 0x60 @@ -84,6 +85,7 @@ typedef struct MarkAdContext struct Options { bool IgnoreAspectRatio; + bool IgnoreLogoDetection; } Options; struct Info diff --git a/markad-standalone.cpp b/markad-standalone.cpp index 1fc377c..a36565c 100644 --- a/markad-standalone.cpp +++ b/markad-standalone.cpp @@ -91,6 +91,15 @@ void cMarkAdStandalone::AddMark(MarkAdMark *Mark) if (!Mark) return; if (!Mark->Type) return; + if (((Mark->Type & 0xF0)==MT_BORDERCHANGE) && (Mark->Position>25000) && + (!macontext.Video.Options.IgnoreLogoDetection)) + { + isyslog("border change detected. logo detection disabled"); + macontext.Video.Options.IgnoreLogoDetection=true; + marks.Del(MT_LOGOSTART); + marks.Del(MT_LOGOSTOP); + } + if ((((Mark->Type & 0xF0)==MT_CHANNELCHANGE) || (Mark->Type==MT_ASPECTCHANGE)) && (Mark->Position>25000) && (bDecodeVideo)) { @@ -113,7 +122,7 @@ void cMarkAdStandalone::AddMark(MarkAdMark *Mark) if (TurnOff) { - isyslog("%s change detected. video decoding disabled", + isyslog("%s change detected. logo/border detection disabled", Mark->Type==MT_ASPECTCHANGE ? "aspectratio" : "audio channel"); bDecodeVideo=false; @@ -308,9 +317,9 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number) { if ((framecnt-lastiframe)<=3) { - //SaveFrame(lastiframe); // TODO: JUST FOR DEBUGGING! mark=video->Process(lastiframe); AddMark(mark); + //SaveFrame(lastiframe); // TODO: JUST FOR DEBUGGING! } } } @@ -402,99 +402,107 @@ cMarkAdBlackBordersHoriz::cMarkAdBlackBordersHoriz(MarkAdContext *maContext) { macontext=maContext; - borderstatus=false; + borderstatus=UNINITIALIZED; borderiframe=-1; - borderstarttime=0; -} - -void cMarkAdBlackBordersHoriz::SaveFrame(int LastIFrame) -{ - if (!macontext) return; - if (!macontext->Video.Data.Valid) return; - - if (macontext->Video.Data.PlaneLinesize[0]!=macontext->Video.Info.Width) return; - - FILE *pFile; - char szFilename[32]; - - // Open file - sprintf(szFilename, "frame%06d.pgm", LastIFrame); - pFile=fopen(szFilename, "wb"); - if (pFile==NULL) - return; - - // Write header - fprintf(pFile, "P5\n%d %d\n255\n", macontext->Video.Info.Width, - macontext->Video.Info.Width); - - // Write pixel data - fwrite(macontext->Video.Data.Plane[0],1,macontext->Video.Info.Width* - macontext->Video.Info.Height,pFile); - // Close file - fclose(pFile); } int cMarkAdBlackBordersHoriz::Process(int LastIFrame, int *BorderIFrame) { #define CHECKHEIGHT 20 #define BRIGHTNESS 20 +#define OFFSET 5 if (!macontext) return 0; if (!macontext->Video.Data.Valid) return 0; + if (macontext->Video.Info.FramesPerSecond==0) return 0; + *BorderIFrame=0; - *BorderIFrame=borderiframe; + int height=macontext->Video.Info.Height-OFFSET; - int x; + int start=(height-CHECKHEIGHT)*macontext->Video.Data.PlaneLinesize[0]; + int end=height*macontext->Video.Data.PlaneLinesize[0]; bool ftop=true,fbottom=true; + int val=0,cnt=0,xz=0; - // "fast" method - for (x=(macontext->Video.Info.Height-CHECKHEIGHT)*macontext->Video.Data.PlaneLinesize[0]; - x<macontext->Video.Info.Height*macontext->Video.Data.PlaneLinesize[0]; x++) + for (int x=start; x<end; x++) { - if (macontext->Video.Data.Plane[0][x]>BRIGHTNESS) fbottom=false; + if (xz<macontext->Video.Info.Width) + { + val+=macontext->Video.Data.Plane[0][x]; + macontext->Video.Data.Plane[0][x]=255; + + cnt++; + } + xz++; + if (xz>=macontext->Video.Data.PlaneLinesize[0]) xz=0; } + val/=cnt; + if (val>BRIGHTNESS) fbottom=false; if (fbottom) { - for (x=0; x<(macontext->Video.Data.PlaneLinesize[0]*CHECKHEIGHT); x++) + start=OFFSET*macontext->Video.Data.PlaneLinesize[0]; + end=macontext->Video.Data.PlaneLinesize[0]*(CHECKHEIGHT+OFFSET); + val=0; + cnt=0; + xz=0; + for (int x=start; x<end; x++) { - if (macontext->Video.Data.Plane[0][x]>BRIGHTNESS) ftop=false; + if (xz<macontext->Video.Info.Width) + { + val+=macontext->Video.Data.Plane[0][x]; + macontext->Video.Data.Plane[0][x]=255; + + cnt++; + } + xz++; + if (xz>=macontext->Video.Data.PlaneLinesize[0]) xz=0; } + val/=cnt; + if (val>BRIGHTNESS) ftop=false; } if ((fbottom) && (ftop)) { - if (!borderstatus) + if (borderiframe==-1) { - if (!borderstarttime) - { - borderiframe=LastIFrame; - borderstarttime=time(NULL); - borderstatus=false; - } - else + borderiframe=LastIFrame; + } + else + { + if (LastIFrame>(borderiframe+macontext->Video.Info.FramesPerSecond*60)) { - if ((time(NULL)>(borderstarttime+20))) + if (borderstatus==UNINITIALIZED) + { + borderstatus=BORDER; + } + if (borderstatus==NOBORDER) { - borderstatus=true; - return 1; // detected black border + *BorderIFrame=borderiframe; + borderstatus=BORDER; + return 1; // detected start of black border } } } } else { - if (borderstatus) + if (borderiframe!=-1) { - borderiframe=LastIFrame; - borderstarttime=0; - borderstatus=false; - return -1; + if (borderstatus==BORDER) + { + *BorderIFrame=LastIFrame; + borderstatus=NOBORDER; + borderiframe=-1; + return -1; // detected stop of black border + } + else + { + borderiframe=-1; + } } else { borderiframe=-1; - borderstarttime=0; - return 0; } } return 0; @@ -570,32 +578,34 @@ MarkAdMark *cMarkAdVideo::Process(int LastIFrame) ResetMark(); if (!LastIFrame) return NULL; - int logoiframe; - int lret=logo->Process(LastIFrame,&logoiframe); - if ((lret>=-1) && (lret!=0)) + if (!macontext->Video.Options.IgnoreLogoDetection) { - char *buf=NULL; - if (lret>0) + int logoiframe; + int lret=logo->Process(LastIFrame,&logoiframe); + if ((lret>=-1) && (lret!=0)) { - if (asprintf(&buf,"detected logo start (%i)",logoiframe)!=-1) + char *buf=NULL; + if (lret>0) { - isyslog(buf); - AddMark(MT_LOGOSTART,logoiframe,buf); - free(buf); + if (asprintf(&buf,"detected logo start (%i)",logoiframe)!=-1) + { + isyslog(buf); + AddMark(MT_LOGOSTART,logoiframe,buf); + free(buf); + } } - } - else - { - if (asprintf(&buf,"detected logo stop (%i)",logoiframe)!=-1) + else { - isyslog(buf); - AddMark(MT_LOGOSTOP,logoiframe,buf); - free(buf); + if (asprintf(&buf,"detected logo stop (%i)",logoiframe)!=-1) + { + isyslog(buf); + AddMark(MT_LOGOSTOP,logoiframe,buf); + free(buf); + } } } } - int borderiframe; int hret=hborder->Process(LastIFrame,&borderiframe); @@ -13,6 +13,7 @@ #include <string.h> #include <stdio.h> #include <stdlib.h> +#include <stdint.h> #include "global.h" extern "C" @@ -64,14 +65,14 @@ private: uchar sobel[MAXPIXEL]; // monochrome picture with edges (after sobel) uchar mask[MAXPIXEL]; // monochrome mask of logo uchar result[MAXPIXEL]; // result of sobel + mask - int rpixel; // black pixel in result - int mpixel; // black pixel in mask - int status; - int lastiframe; - int counter; - int corner; - MarkAdAspectRatio aspectratio; - bool valid; + int rpixel; // black pixel in result + int mpixel; // black pixel in mask + int status; // status = LOGO on, off, uninitialized + int lastiframe; // start/stop frame + int counter; // how many logo on, offs detected? + int corner; // which corner + MarkAdAspectRatio aspectratio; // aspectratio + bool valid; // logo mask valid? } area; int G[5][5]; @@ -91,10 +92,17 @@ public: class cMarkAdBlackBordersHoriz { private: + enum + { + ERROR=-3, + UNINITIALIZED=-2, + NOBORDER=-1, + NOCHANGE=0, + BORDER=1 + }; + int borderstatus; int borderiframe; - time_t borderstarttime; - void SaveFrame(int LastIFrame); MarkAdContext *macontext; public: cMarkAdBlackBordersHoriz(MarkAdContext *maContext); |