diff options
Diffstat (limited to 'video.cpp')
-rw-r--r-- | video.cpp | 141 |
1 files changed, 136 insertions, 5 deletions
@@ -8,6 +8,133 @@ #include "video.h" +cMarkAdLogo::cMarkAdLogo(int RecvNumber, MarkAdContext *maContext) +{ + macontext=maContext; + + // 3x3 GX Sobel mask + GX[0][0] = -1; + GX[0][1] = 0; + GX[0][2] = 1; + GX[1][0] = -2; // 2 + GX[1][1] = 0; + GX[1][2] = 2; // 2 + GX[2][0] = -1; + GX[2][1] = 0; + GX[2][2] = 1; + + // 3x3 GY Sobel mask + GY[0][0] = 1; + GY[0][1] = 2; // 2 + GY[0][2] = 1; + GY[1][0] = 0; + GY[1][1] = 0; + GY[1][2] = 0; + GY[2][0] = -1; + GY[2][1] = -2; //2 + GY[2][2] = -1; + + plane=NULL; + first=true; +} + +cMarkAdLogo::~cMarkAdLogo() +{ + if (plane) free(plane); +} + +void cMarkAdLogo::SaveFrame(int LastIFrame) +{ + if (!macontext) return; + if (!macontext->Video.Info.Width) return; + if (!plane) 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,LOGOHEIGHT); + + // Write pixel data + fwrite(plane,1,macontext->Video.Info.Width*LOGOHEIGHT,pFile); + // Close file + fclose(pFile); + + dsyslog("markad saved frame %i",LastIFrame); + if (LastIFrame>750) abort(); +} + +int cMarkAdLogo::Process(int LastIFrame) +{ + if (!macontext) return 0; + if (!macontext->Video.Info.Width) return 0; + if (!macontext->Video.Data.Valid) return 0; + + if (!plane) + { + plane=(uchar *) malloc(LOGOHEIGHT*macontext->Video.Info.Width); + if (!plane) return 0; + } + + int SUM; + int sumX,sumY; + + for (int Y=0; Y<=LOGOHEIGHT-1; Y++) + { + for (int X=0; X<=macontext->Video.Info.Width-1; X++) + { + sumX=0; + sumY=0; + + // image boundaries + if (Y==0 || Y==LOGOHEIGHT-1) + SUM=0; + else if (X==0 || X==macontext->Video.Info.Width-1) + SUM=0; + // convolution starts here + else + { + // X Gradient approximation + for (int I=-1; I<=1; I++) + { + for (int J=-1; J<=1; J++) + { + sumX=sumX+ (int) ((*(macontext->Video.Data.Plane[0]+X+I+ + (Y+J)*macontext->Video.Info.Width))*GX[I+1][J+1]); + } + } + + // Y Gradient approximation + for (int I=-1; I<=1; I++) + { + for (int J=-1; J<=1; J++) + { + sumY=sumY+ (int) ((*(macontext->Video.Data.Plane[0]+X+I+ + (Y+J)*macontext->Video.Info.Width))*GY[I+1][J+1]); + } + } + + // Gradient Magnitude approximation + SUM = abs(sumX) + abs(sumY); + } + + if (SUM>=127) SUM=255; + if (SUM<127) SUM=0; + + plane[X+Y*macontext->Video.Info.Width]=255-(uchar) (SUM); + } + } + //SaveFrame(LastIFrame); + + return 0; +} + cMarkAdBlackBordersHoriz::cMarkAdBlackBordersHoriz(int RecvNumber, MarkAdContext *maContext) { macontext=maContext; @@ -50,7 +177,7 @@ int cMarkAdBlackBordersHoriz::Process(int LastIFrame, int *BorderIFrame) #define BRIGHTNESS 20 if (!macontext) return 0; if (!macontext->Video.Data.Valid) return 0; -return 0; + return 0; *BorderIFrame=borderiframe; @@ -160,12 +287,14 @@ cMarkAdVideo::cMarkAdVideo(int RecvNumber,MarkAdContext *maContext) mark.Position=0; hborder=new cMarkAdBlackBordersHoriz(RecvNumber,maContext); + logo = new cMarkAdLogo(RecvNumber,maContext); } cMarkAdVideo::~cMarkAdVideo() { ResetMark(); - delete hborder; + if (hborder) delete hborder; + if (logo) delete logo; } void cMarkAdVideo::ResetMark() @@ -215,6 +344,8 @@ MarkAdMark *cMarkAdVideo::Process(int LastIFrame) ResetMark(); if (!LastIFrame) return NULL; + logo->Process(LastIFrame); + if (macontext->State.ContentStarted) { int borderiframe; @@ -247,9 +378,9 @@ MarkAdMark *cMarkAdVideo::Process(int LastIFrame) { 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) + aspectratio.Num,aspectratio.Den, + macontext->Video.Info.AspectRatio.Num, + macontext->Video.Info.AspectRatio.Den,LastIFrame)!=-1) { isyslog("markad [%i]: %s",recvnumber, buf); AddMark(LastIFrame,buf); |