summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJochen Dolze <vdr@dolze.de>2010-11-03 01:21:30 +0100
committerJochen Dolze <vdr@dolze.de>2010-11-03 01:21:30 +0100
commit3b606130ead038b4d5bc1b88bfd6e7430adacc4d (patch)
tree1a883bb36ada9f650f441f5c7fde4171f4afc81c
parent7e2fb0f884b2269c32cb42867346ec3917c7e480 (diff)
downloadvdr-plugin-markad-3b606130ead038b4d5bc1b88bfd6e7430adacc4d.tar.gz
vdr-plugin-markad-3b606130ead038b4d5bc1b88bfd6e7430adacc4d.tar.bz2
Got rid of iframetime, better broadcast start detection, dont change atime/mtime of info file anymore
-rw-r--r--command/audio.cpp3
-rw-r--r--command/global.h1
-rw-r--r--command/markad-standalone.cpp250
-rw-r--r--command/markad-standalone.h10
-rw-r--r--command/streaminfo.cpp25
-rw-r--r--command/streaminfo.h4
-rw-r--r--command/video.cpp2
7 files changed, 163 insertions, 132 deletions
diff --git a/command/audio.cpp b/command/audio.cpp
index fe96594..46fa57a 100644
--- a/command/audio.cpp
+++ b/command/audio.cpp
@@ -164,7 +164,6 @@ MarkAdMark *cMarkAdAudio::Process(int FrameNumber, int FrameNumberNext)
nbuf[19]=0;
strcat(buf,nbuf);
AddMark(MT_CHANNELSTART,FrameNumberNext,buf);
-
}
else
{
@@ -187,7 +186,7 @@ MarkAdMark *cMarkAdAudio::Process(int FrameNumber, int FrameNumberNext)
}
channels=macontext->Audio.Info.Channels;
- framelast=FrameNumberNext;
+ framelast=FrameNumber;
return &mark;
}
diff --git a/command/global.h b/command/global.h
index 30c5896..d9f2e12 100644
--- a/command/global.h
+++ b/command/global.h
@@ -165,7 +165,6 @@ typedef struct MarkAdContext
{
struct Info
{
- //bool DolbyDigital51;
int Channels; // number of audio channels
int SampleRate;
} Info;
diff --git a/command/markad-standalone.cpp b/command/markad-standalone.cpp
index adea80c..a9bfdb1 100644
--- a/command/markad-standalone.cpp
+++ b/command/markad-standalone.cpp
@@ -24,6 +24,8 @@
#include <locale.h>
#include <libintl.h>
#include <execinfo.h>
+#include <mntent.h>
+#include <utime.h>
#include <errno.h>
#include "markad-standalone.h"
@@ -198,19 +200,25 @@ void cMarkAdStandalone::CalculateStopPosition(int startframe, int delta)
void cMarkAdStandalone::AddStartMark()
{
- char *buf;
- if (asprintf(&buf,"start of recording (0)")!=-1)
+ if (tStart<2)
{
- marks.Add(MT_COMMONSTART,0,buf);
- isyslog("%s",buf);
- free(buf);
+ char *buf;
+ if (asprintf(&buf,"start of recording (0)")!=-1)
+ {
+ marks.Add(MT_COMMONSTART,0,buf);
+ isyslog("%s",buf);
+ free(buf);
+ }
}
-
if (tStart)
{
iStart=-(tStart*macontext.Video.Info.FramesPerSecond);
}
CalculateStopPosition(-iStart,macontext.Video.Info.FramesPerSecond*MAXRANGE);
+ if (tStart==1)
+ {
+ tStart=iStart=0;
+ }
}
void cMarkAdStandalone::CheckStartStop(int frame, bool checkend)
@@ -495,18 +503,25 @@ void cMarkAdStandalone::CheckFirstMark()
return;
}
-void cMarkAdStandalone::CheckInfoAspectRatio()
+void cMarkAdStandalone::CheckAspectRatio_and_AudioChannels()
{
if (aspectChecked) return;
- if (bIgnoreVideoInfo)
+ dsyslog("checking aspectratio and audio channels");
+
+ if (!macontext.Info.Channels)
{
- aspectChecked=true;
- return;
+ macontext.Info.Channels=macontext.Audio.Info.Channels;
+ if (macontext.Info.Channels==2) setAudio20=true;
+ if (macontext.Info.Channels==6)
+ {
+ isyslog("DolbyDigital5.1 audio detected. logo/border detection disabled");
+ bDecodeVideo=false;
+ setAudio51=true;
+ reprocess=true;
+ }
}
- dsyslog("checking aspectratio");
-
bool aSet=false;
if (!macontext.Info.AspectRatio.Num)
{
@@ -516,13 +531,16 @@ void cMarkAdStandalone::CheckInfoAspectRatio()
}
else
{
- if ((macontext.Info.AspectRatio.Num!=macontext.Video.Info.AspectRatio.Num) &&
- (macontext.Info.AspectRatio.Den!=macontext.Video.Info.AspectRatio.Den))
+ if (!bIgnoreVideoInfo)
{
- isyslog("aspectratio in info wrong %i:%i instead of %i:%i",
- macontext.Video.Info.AspectRatio.Num,macontext.Video.Info.AspectRatio.Den,
- macontext.Info.AspectRatio.Num,macontext.Info.AspectRatio.Den);
- aSet=true;
+ if ((macontext.Info.AspectRatio.Num!=macontext.Video.Info.AspectRatio.Num) &&
+ (macontext.Info.AspectRatio.Den!=macontext.Video.Info.AspectRatio.Den))
+ {
+ isyslog("aspectratio in info wrong %i:%i instead of %i:%i",
+ macontext.Video.Info.AspectRatio.Num,macontext.Video.Info.AspectRatio.Den,
+ macontext.Info.AspectRatio.Num,macontext.Info.AspectRatio.Den);
+ aSet=true;
+ }
}
}
@@ -534,11 +552,6 @@ void cMarkAdStandalone::CheckInfoAspectRatio()
if ((macontext.Info.AspectRatio.Num==16) &&
(macontext.Info.AspectRatio.Den==9))
{
- if (!macontext.Info.Channels)
- {
- macontext.Info.Channels=macontext.Audio.Info.Channels;
- if (macontext.Info.Channels==2) setAudio20=true;
- }
macontext.Video.Options.IgnoreAspectRatio=true;
setVideo169=true;
setVideo43=false;
@@ -804,6 +817,7 @@ void cMarkAdStandalone::CheckBroadcastLength()
int tframecnt=1;
int iIndexError;
marks.CheckIndex(directory,isTS,&tframecnt,&iIndexError);
+ if (iIndexError!=0) return;
macontext.Info.Length=tframecnt/macontext.Video.Info.FramesPerSecond;
isyslog("got broadcast length of %im from index",macontext.Info.Length/60);
reprocess=true;
@@ -983,7 +997,6 @@ bool cMarkAdStandalone::ProcessFile2ndPass(clMark **Mark1, clMark **Mark2,int Nu
if (macontext.Video.Info.Pict_Type==MA_I_TYPE)
{
lastiframe=iframe;
- lastiframetime=iframetime;
if (macontext.Info.VPid.Type==MARKAD_PIDTYPE_VIDEO_H264)
{
iframe=actframe;
@@ -992,7 +1005,6 @@ bool cMarkAdStandalone::ProcessFile2ndPass(clMark **Mark1, clMark **Mark2,int Nu
{
iframe=actframe-1;
}
- iframetime=vpkt.Timestamp;
dRes=true;
}
}
@@ -1090,7 +1102,10 @@ void cMarkAdStandalone::Process2ndPass()
if (!decoder) return;
if (!macontext.Video.Info.FramesPerSecond)
+ {
+ // TODO: Get Framerate from info
macontext.Video.Info.FramesPerSecond=25;
+ }
if (!marks.Count())
{
@@ -1159,19 +1174,6 @@ void cMarkAdStandalone::Process2ndPass()
}
}
-char *cMarkAdStandalone::Timestamp2HMS(unsigned int Timestamp)
-{
- double val=(double) Timestamp/90000;
- int h,m;
- double s_ns;
- h=(int) val/3600;
- m=(int) (val-(3600*h))/60;
- s_ns=val-(h*3600+m*60);
- static char buf[20];
- sprintf(buf,"%02d:%02d:%06.4f",h,m,s_ns);
- return (char *) &buf;
-}
-
bool cMarkAdStandalone::ProcessFile(int Number)
{
if (!directory) return false;
@@ -1230,9 +1232,10 @@ bool cMarkAdStandalone::ProcessFile(int Number)
{
if ((macontext.Video.Info.Height) && (!noticeHEADER))
{
- isyslog("%s %i%c",(macontext.Video.Info.Height>576) ? "HDTV" : "SDTV",
+ isyslog("%s %i%c%0.f",(macontext.Video.Info.Height>576) ? "HDTV" : "SDTV",
macontext.Video.Info.Height,
- macontext.Video.Info.Interlaced ? 'i' : 'p');
+ macontext.Video.Info.Interlaced ? 'i' : 'p',
+ macontext.Video.Info.FramesPerSecond);
noticeHEADER=true;
}
@@ -1244,9 +1247,7 @@ bool cMarkAdStandalone::ProcessFile(int Number)
if (macontext.Config->GenIndex)
{
- if ((macontext.Info.VPid.Type==MARKAD_PIDTYPE_VIDEO_H262) ||
- ((macontext.Info.VPid.Type==MARKAD_PIDTYPE_VIDEO_H264) &&
- (!macontext.Video.Info.Interlaced)))
+ if (macontext.Info.VPid.Type==MARKAD_PIDTYPE_VIDEO_H262)
{
nextPictType=macontext.Video.Info.Pict_Type;
}
@@ -1258,9 +1259,8 @@ bool cMarkAdStandalone::ProcessFile(int Number)
if (macontext.Video.Info.Pict_Type==MA_I_TYPE)
{
lastiframe=iframe;
- lastiframetime=iframetime;
CheckStartStop(lastiframe);
- if (lastiframe>chkLEFT) CheckInfoAspectRatio();
+ if (lastiframe>chkLEFT) CheckAspectRatio_and_AudioChannels();
if (macontext.Info.VPid.Type==MARKAD_PIDTYPE_VIDEO_H264)
{
@@ -1270,7 +1270,6 @@ bool cMarkAdStandalone::ProcessFile(int Number)
{
iframe=framecnt-1;
}
- iframetime=vpkt.Timestamp;
dRes=true;
}
}
@@ -1281,7 +1280,6 @@ bool cMarkAdStandalone::ProcessFile(int Number)
{
if ((framecnt-iframe)<=3)
{
- //printf("VID %5i %s %x\n",lastiframe,Timestamp2HMS(lastiframetime),lastiframetime);
MarkAdMarks *vmarks;
vmarks=video->Process(lastiframe,iframe);
if (vmarks)
@@ -1335,15 +1333,9 @@ bool cMarkAdStandalone::ProcessFile(int Number)
isyslog("found AC3%s",macontext.Config->AC3Always ? "*" : "");
noticeVDR_AC3=true;
}
- if (apkt.Timestamp) audiotime=apkt.Timestamp;
-
- if (abs(audiotime-lastiframetime)<DELTATIME)
- {
- //printf("AC3 %5i %s %x\n",lastiframe,Timestamp2HMS(audiotime),audiotime);
- MarkAdMark *amark;
- amark=audio->Process(lastiframe,iframe);
- if (amark) AddMark(amark);
- }
+ MarkAdMark *amark;
+ amark=audio->Process(lastiframe,iframe);
+ if (amark) AddMark(amark);
}
}
tspkt+=len;
@@ -1377,10 +1369,6 @@ bool cMarkAdStandalone::Reset(bool FirstPass)
lastiframe=0;
iframe=0;
- lastiframetime=0;
- iframetime=0;
- audiotime=0;
-
gotendmark=false;
memset(&vpkt,0,sizeof(vpkt));
@@ -1700,6 +1688,9 @@ bool cMarkAdStandalone::SaveInfo()
free(line);
}
fclose(w);
+ struct stat statbuf_r;
+ if (fstat(fileno(r),&statbuf_r)==-1) err=true;
+
fclose(r);
if (err)
{
@@ -1707,7 +1698,18 @@ bool cMarkAdStandalone::SaveInfo()
}
else
{
- if (rename(dst,src)==-1) err=true;
+ if (rename(dst,src)==-1)
+ {
+ err=true;
+ }
+ else
+ {
+ // preserve timestamps from old file
+ struct utimbuf oldtimes;
+ oldtimes.actime=statbuf_r.st_atime;
+ oldtimes.modtime=statbuf_r.st_mtime;
+ if (utime(src,&oldtimes)) {};
+ }
}
if ((getuid()==0 || geteuid()!=0) && (!err))
@@ -1730,42 +1732,82 @@ bool cMarkAdStandalone::SaveInfo()
return (err==false);
}
-bool cMarkAdStandalone::LoadInfo()
+time_t cMarkAdStandalone::GetBroadcastStartPES()
{
- char *buf;
- if (asprintf(&buf,"%s/info%s",directory,isTS ? "" : ".vdr")==-1) return false;
-
- FILE *f;
- f=fopen(buf,"r");
- free(buf);
- if (!f) return false;
+ // get broadcast start from atime of directory (if the volume is mounted with noatime)
+ // fallback to the time of the directory
+ struct mntent *ent;
+ FILE *mounts=setmntent(_PATH_MOUNTED,"r");
+ while ((ent=getmntent(mounts))!=NULL)
+ {
+ if (strstr(directory,ent->mnt_dir))
+ {
+ if (strstr(ent->mnt_opts,"noatime"))
+ {
+ struct stat statbuf;
+ if (stat(directory,&statbuf)!=-1)
+ {
+ endmntent(mounts);
+ isyslog("getting broadcast start from directory atime");
+ return statbuf.st_atime;
+ }
+ }
+ }
+ }
+ endmntent(mounts);
const char *timestr=strrchr(directory,'/');
if (timestr)
{
timestr++;
- if (!isdigit(*timestr)) timestr=directory;
+ if (isdigit(*timestr))
+ {
+ time_t now = time(NULL);
+ struct tm tm_r;
+ struct tm t = *localtime_r(&now, &tm_r); // init timezone
+ if (sscanf(timestr, "%4d-%02d-%02d.%02d%*c%02d", &t.tm_year, &t.tm_mon, &t.tm_mday,
+ &t.tm_hour, & t.tm_min)==5)
+ {
+ t.tm_year-=1900;
+ t.tm_mon--;
+ t.tm_sec=0;
+ t.tm_isdst=-1;
+ isyslog("getting broadcast start from timer");
+ return mktime(&t);
+ }
+ }
}
- else
+ return (time_t) 0;
+}
+
+time_t cMarkAdStandalone::GetBroadcastStart(time_t start, int fd)
+{
+ if (isTS)
{
- timestr=directory;
}
-
- time_t now = time(NULL);
- struct tm tm_r;
- struct tm t = *localtime_r(&now, &tm_r); // init timezone
- time_t rStart=0;
- if (sscanf(timestr, "%4d-%02d-%02d.%02d%*c%02d", &t.tm_year, &t.tm_mon, &t.tm_mday,
- &t.tm_hour, & t.tm_min)==5)
+ else
{
- t.tm_year-=1900;
- t.tm_mon--;
- t.tm_sec=0;
- t.tm_isdst=-1;
- rStart=mktime(&t);
+ /* with PES we can get the exact starttime only from
+ info.vdr (if its not changed afterwards) */
+ struct stat statbuf;
+ if (fstat(fd,&statbuf)==-1) return (time_t) 0;
+ if (fabs(difftime(start,statbuf.st_mtime))>14400) return (time_t) 0;
+ return statbuf.st_mtime;
}
+ return (time_t) 0;
+}
+
+bool cMarkAdStandalone::LoadInfo()
+{
+ char *buf;
+ if (asprintf(&buf,"%s/info%s",directory,isTS ? "" : ".vdr")==-1) return false;
+
+ FILE *f;
+ f=fopen(buf,"r");
+ free(buf);
+ if (!f) return false;
- long start=0;
+ time_t start=0;
char *line=NULL;
size_t length;
while (getline(&line,&length,f)!=-1)
@@ -1882,15 +1924,35 @@ bool cMarkAdStandalone::LoadInfo()
}
}
if (line) free(line);
- fclose(f);
- if ((macontext.Info.Length) && (!bIgnoreTimerInfo) && (start) && (rStart))
+ if ((macontext.Info.Length) && (!bIgnoreTimerInfo) && (start))
{
- tStart=start-rStart;
- if (tStart<0)
+ time_t rStart=GetBroadcastStart(start,fileno(f));
+ if (rStart)
+ {
+ if (rStart>start+macontext.Info.Length)
+ {
+ rStart=GetBroadcastStartPES();
+ }
+
+ tStart=(int) (start-rStart);
+ if (tStart<0)
+ {
+ if (macontext.Info.Length+tStart>0)
+ {
+ isyslog("broadcast start truncated by %im, length will be corrected",-tStart/60);
+ macontext.Info.Length+=tStart;
+ tStart=1;
+ }
+ else
+ {
+ esyslog("cannot determine broadcast start, disabling start/stop detection");
+ tStart=0;
+ }
+ }
+ }
+ else
{
- isyslog("broadcast start truncated by %im, length will be corrected",-tStart/60);
- macontext.Info.Length+=tStart;
tStart=0;
}
}
@@ -1898,6 +1960,7 @@ bool cMarkAdStandalone::LoadInfo()
{
tStart=0;
}
+ fclose(f);
if (!macontext.Info.Length)
{
@@ -2344,7 +2407,7 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, const MarkAdConfig *
}
}
- if (tStart) isyslog("pre-timer %im",tStart/60);
+ if (tStart>1) isyslog("pre-timer %im",tStart/60);
if (macontext.Info.Length) isyslog("broadcast length %im",macontext.Info.Length/60);
if (title[0])
@@ -2425,9 +2488,6 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, const MarkAdConfig *
framecnt2=0;
lastiframe=0;
iframe=0;
- lastiframetime=0;
- iframetime=0;
- audiotime=0;
chkLEFT=INT_MAX;
chkRIGHT=INT_MIN;
gettimeofday(&tv1,&tz);
diff --git a/command/markad-standalone.h b/command/markad-standalone.h
index bdbd0ff..f22310a 100644
--- a/command/markad-standalone.h
+++ b/command/markad-standalone.h
@@ -184,10 +184,6 @@ unsigned Descriptor_Length:
int lastiframe;
int iframe;
- unsigned int iframetime;
- unsigned int lastiframetime;
- unsigned int audiotime;
-
int framecnt;
int framecnt2; // 2nd pass
@@ -225,6 +221,8 @@ unsigned Descriptor_Length:
int chkLEFT;
int chkRIGHT;
+ time_t GetBroadcastStartPES();
+ time_t GetBroadcastStart(time_t start, int fd);
void CheckBroadcastLength();
bool CheckIndexGrowing();
char *indexFile;
@@ -242,7 +240,7 @@ unsigned Descriptor_Length:
void CheckLastMark();
bool CheckDolbyDigital51();
void CheckStartStop(int frame, bool checkend=false);
- void CheckInfoAspectRatio();
+ void CheckAspectRatio_and_AudioChannels();
void CheckLogoMarks(clMark *last=NULL);
void AddStartMark();
void AddMark(MarkAdMark *Mark);
@@ -257,8 +255,6 @@ unsigned Descriptor_Length:
bool RegenerateIndex();
bool ProcessFile2ndPass(clMark **Mark1, clMark **Mark2, int Number, off_t Offset, int Frame, int Frames);
bool ProcessFile(int Number);
-
- char *Timestamp2HMS(unsigned int Timestamp);
void ProcessFile();
public:
void SetAbort()
diff --git a/command/streaminfo.cpp b/command/streaminfo.cpp
index 94a044e..f12a6b8 100644
--- a/command/streaminfo.cpp
+++ b/command/streaminfo.cpp
@@ -10,16 +10,6 @@
#include "streaminfo.h"
-cMarkAdStreamInfo::cMarkAdStreamInfo()
-{
- Clear();
-}
-
-void cMarkAdStreamInfo::Clear()
-{
- H264skiptoggle=false;
-}
-
bool cMarkAdStreamInfo::FindAC3AudioInfos(MarkAdContext *maContext, uchar *espkt, int eslen)
{
#pragma pack(1)
@@ -139,19 +129,6 @@ bool cMarkAdStreamInfo::FindH264VideoInfos(MarkAdContext *maContext, uchar *pkt,
{
maContext->Video.Info.Pict_Type=0;
}
- if (!maContext->Video.Info.Interlaced)
- {
- // this is very crude, drop every second "frame"
- if (H264skiptoggle)
- {
- H264skiptoggle=false;
- return false;
- }
- else
- {
- H264skiptoggle=true;
- }
- }
return true;
}
@@ -275,7 +252,7 @@ bool cMarkAdStreamInfo::FindH264VideoInfos(MarkAdContext *maContext, uchar *pkt,
if (num_units_in_tick > 0)
{
frame_rate = time_scale / (2*num_units_in_tick);
- if (frame_mbs_only_flag) frame_rate/=2;
+ //if (frame_mbs_only_flag) frame_rate/=2;
}
bs.skipBit(); // fixed_frame_rate_flag
}
diff --git a/command/streaminfo.h b/command/streaminfo.h
index 4c4a957..92d15e4 100644
--- a/command/streaminfo.h
+++ b/command/streaminfo.h
@@ -28,13 +28,11 @@ private:
NAL_AUX_SLICE = 0x19 // Auxilary Slice
};
- bool H264skiptoggle;
int nalUnescape(uint8_t *dst, const uint8_t *src, int len);
bool FindH264VideoInfos(MarkAdContext *maContext, uchar *pkt, int len);
bool FindH262VideoInfos(MarkAdContext *maContext, uchar *pkt, int len);
public:
- cMarkAdStreamInfo();
- void Clear();
+ void Clear() {};
bool FindVideoInfos(MarkAdContext *maContext, uchar *pkt, int len);
bool FindAC3AudioInfos(MarkAdContext *maContext, uchar *espkt, int eslen);
};
diff --git a/command/video.cpp b/command/video.cpp
index e51bd51..8dc509c 100644
--- a/command/video.cpp
+++ b/command/video.cpp
@@ -644,6 +644,7 @@ bool cMarkAdOverlap::areSimilar(simpleHistogram &hist1, simpleHistogram &hist2)
{
similar+=abs(hist1[i]-hist2[i]);
}
+ //printf("%6i\n",similar);
if (similar<similarCutOff) return true;
return false;
}
@@ -658,6 +659,7 @@ MarkAdPos *cMarkAdOverlap::Detect()
{
for (int A=start; A<histcnt[AFTER]; A++)
{
+ //printf("%6i %6i ",histbuf[BEFORE][B].framenumber,histbuf[AFTER][A].framenumber);
bool simil=areSimilar(histbuf[BEFORE][B].histogram,histbuf[AFTER][A].histogram);
if (simil)
{