summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJochen Dolze <vdr@dolze.de>2010-10-21 00:44:14 +0200
committerJochen Dolze <vdr@dolze.de>2010-10-21 00:44:14 +0200
commit8cf0800ad613a165c07424b84fd84b60b586c6f8 (patch)
tree5adb123ac54e2405f225ba13d4df85ade52b1a36
parent0acaba790948b737a35293e5a9ac91be5de563b0 (diff)
downloadvdr-plugin-markad-8cf0800ad613a165c07424b84fd84b60b586c6f8.tar.gz
vdr-plugin-markad-8cf0800ad613a165c07424b84fd84b60b586c6f8.tar.bz2
Added letterbox detection
Improved audiochannel-/aspect-/borderchange detection
-rw-r--r--command/audio.cpp43
-rw-r--r--command/global.h10
-rw-r--r--command/markad-standalone.cpp99
-rw-r--r--command/markad-standalone.h21
-rw-r--r--command/video.cpp50
-rw-r--r--command/video.h6
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();
};