summaryrefslogtreecommitdiff
path: root/command/markad-standalone.cpp
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 /command/markad-standalone.cpp
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
Diffstat (limited to 'command/markad-standalone.cpp')
-rw-r--r--command/markad-standalone.cpp250
1 files changed, 155 insertions, 95 deletions
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);