summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJochen Dolze <vdr@dolze.de>2010-11-22 22:08:27 +0100
committerJochen Dolze <vdr@dolze.de>2010-11-22 22:08:27 +0100
commit83de61beb75c5554ec5773f63840990584d5da57 (patch)
treed789573a77fd0c0fc0b287a073193b4087df2753
parent2e9d23ab5e3cc12ce58042afdc2d77d098fd498e (diff)
downloadvdr-plugin-markad-83de61beb75c5554ec5773f63840990584d5da57.tar.gz
vdr-plugin-markad-83de61beb75c5554ec5773f63840990584d5da57.tar.bz2
Added SeekPATPMT when there is no PAT/PMT on start of the TS-recording
Added info about nalu filler Made demuxer more fault tolerant
-rw-r--r--command/demux.cpp2
-rw-r--r--command/markad-standalone.cpp152
-rw-r--r--command/markad-standalone.h5
-rw-r--r--command/marks.cpp2
-rw-r--r--command/streaminfo.cpp9
5 files changed, 104 insertions, 66 deletions
diff --git a/command/demux.cpp b/command/demux.cpp
index c3580c5..752b300 100644
--- a/command/demux.cpp
+++ b/command/demux.cpp
@@ -207,7 +207,7 @@ int cMarkAdDemux::GetMinNeeded(MarkAdPid Pid, uchar *Data, int Count, bool *Offc
}
else
{
- return 0;
+ return -1; // skip one byte (maybe we get another header!)
}
}
diff --git a/command/markad-standalone.cpp b/command/markad-standalone.cpp
index 35527f0..e361306 100644
--- a/command/markad-standalone.cpp
+++ b/command/markad-standalone.cpp
@@ -1258,12 +1258,22 @@ bool cMarkAdStandalone::ProcessFile(int Number)
{
if (vpkt.Data)
{
+ if ((macontext.Info.VPid.Type==MARKAD_PIDTYPE_VIDEO_H264) && (!noticeFILLER))
+ {
+ if ((vpkt.Data[4] & 0x1F)==0x0C)
+ {
+ isyslog("H264 video stream with filler nalu");
+ noticeFILLER=true;
+ }
+ }
+
bool dRes=false;
if (streaminfo->FindVideoInfos(&macontext,vpkt.Data,vpkt.Length))
{
if ((macontext.Video.Info.Height) && (!noticeHEADER))
{
- isyslog("%s %i%c%0.f",(macontext.Video.Info.Height>576) ? "HDTV" : "SDTV",
+ isyslog("%s %ix%i%c%0.f",(macontext.Video.Info.Height>576) ? "HDTV" : "SDTV",
+ macontext.Video.Info.Width,
macontext.Video.Info.Height,
macontext.Video.Info.Interlaced ? 'i' : 'p',
macontext.Video.Info.FramesPerSecond);
@@ -1785,67 +1795,64 @@ bool cMarkAdStandalone::SaveInfo()
return (err==false);
}
-time_t cMarkAdStandalone::GetBroadcastStartPES()
+time_t cMarkAdStandalone::GetBroadcastStart(time_t start, int fd)
{
- // 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 (isTS)
{
- if (strstr(directory,ent->mnt_dir))
+ }
+ else
+ {
+ // get broadcast start from atime of directory (if the volume is mounted with noatime)
+ struct mntent *ent;
+ struct stat statbuf;
+ FILE *mounts=setmntent(_PATH_MOUNTED,"r");
+ while ((ent=getmntent(mounts))!=NULL)
{
- if (strstr(ent->mnt_opts,"noatime"))
+ if (strstr(directory,ent->mnt_dir))
{
- struct stat statbuf;
- if (stat(directory,&statbuf)!=-1)
+ if (strstr(ent->mnt_opts,"noatime"))
{
- endmntent(mounts);
- isyslog("getting broadcast start from directory atime");
- return statbuf.st_atime;
+ if (stat(directory,&statbuf)!=-1)
+ {
+ endmntent(mounts);
+ isyslog("getting broadcast start from directory atime");
+ return statbuf.st_atime;
+ }
}
}
}
- }
- endmntent(mounts);
+ endmntent(mounts);
- const char *timestr=strrchr(directory,'/');
- if (timestr)
- {
- timestr++;
- if (isdigit(*timestr))
+ // try to get from mtime
+ // (and hope info.vdr has not changed after the start of the recording)
+ if (fstat(fd,&statbuf)!=-1)
+ {
+ if (fabs(difftime(start,statbuf.st_mtime))<1800) return (time_t) statbuf.st_mtime;
+ }
+
+ // fallback to the timer -> worst time we can use!
+ const char *timestr=strrchr(directory,'/');
+ if (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)
+ timestr++;
+ if (isdigit(*timestr))
{
- t.tm_year-=1900;
- t.tm_mon--;
- t.tm_sec=0;
- t.tm_isdst=-1;
- isyslog("getting broadcast start from timer");
- return mktime(&t);
+ 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);
+ }
}
}
- }
- return (time_t) 0;
-}
-
-time_t cMarkAdStandalone::GetBroadcastStart(time_t start, int fd)
-{
- if (isTS)
- {
- }
- else
- {
- /* 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;
}
return (time_t) 0;
}
@@ -1919,6 +1926,11 @@ bool cMarkAdStandalone::LoadInfo()
{
macontext.Video.Info.FramesPerSecond=fps;
setFrameRate=false;
+ if (fps<40)
+ {
+ // assumption
+ macontext.Video.Info.Interlaced=true;
+ }
}
}
if (line[0]=='X')
@@ -1997,11 +2009,6 @@ bool cMarkAdStandalone::LoadInfo()
time_t rStart=GetBroadcastStart(startTime,fileno(f));
if (rStart)
{
- if (rStart>startTime+(time_t) length)
- {
- rStart=GetBroadcastStartPES();
- }
-
tStart=(int) (startTime-rStart);
if (tStart<0)
{
@@ -2117,15 +2124,46 @@ bool cMarkAdStandalone::CheckVDRHD()
return false;
}
-bool cMarkAdStandalone::CheckPATPMT()
+off_t cMarkAdStandalone::SeekPATPMT()
{
char *buf;
+ if (asprintf(&buf,"%s/00001.ts",directory)==-1) return (off_t) -1;
+
+ int fd=open(buf,O_RDONLY);
+ free(buf);
+ if (fd==-1) return (off_t) -1;
+ uchar peek_buf[188];
+ for (int i=0; i<5000; i++)
+ {
+ if (read(fd,peek_buf,sizeof(peek_buf))!=sizeof(peek_buf))
+ {
+ close(fd);
+ return (off_t) -1;
+ }
+ if ((peek_buf[0]==0x47) && (peek_buf[1]==0x40) && (peek_buf[2]==00))
+ {
+ off_t ret=lseek(fd,0,SEEK_CUR);
+ close(fd);
+ return ret-188;
+ }
+
+ }
+ close(fd);
+ return (off_t) -1;
+}
+
+bool cMarkAdStandalone::CheckPATPMT(off_t Offset)
+{
+ if (Offset==(off_t) -1) return false;
+ char *buf;
if (asprintf(&buf,"%s/00001.ts",directory)==-1) return false;
int fd=open(buf,O_RDONLY);
free(buf);
if (fd==-1) return false;
+ if (lseek(fd,Offset,SEEK_SET)==(off_t)-1) return false;
+
uchar patpmt_buf[564];
uchar *patpmt;
@@ -2350,7 +2388,7 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, const MarkAdConfig *
noticeVDR_MP2=false;
noticeVDR_AC3=false;
noticeHEADER=false;
-
+ noticeFILLER=false;
sleepcnt=0;
waittime=iwaittime=0;
@@ -2440,7 +2478,7 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, const MarkAdConfig *
if (isTS)
{
- if (!CheckPATPMT())
+ if (!CheckPATPMT(SeekPATPMT()))
{
esyslog("no PAT/PMT found -> cannot process");
abort=true;
diff --git a/command/markad-standalone.h b/command/markad-standalone.h
index 669b2f5..25d19bb 100644
--- a/command/markad-standalone.h
+++ b/command/markad-standalone.h
@@ -198,6 +198,7 @@ unsigned Descriptor_Length:
bool noticeVDR_MP2;
bool noticeVDR_AC3;
bool noticeHEADER;
+ bool noticeFILLER;
bool bDecodeVideo;
bool bDecodeAudio;
@@ -223,7 +224,6 @@ unsigned Descriptor_Length:
int chkLEFT;
int chkRIGHT;
- time_t GetBroadcastStartPES();
time_t GetBroadcastStart(time_t start, int fd);
void CheckBroadcastLength();
bool CheckIndexGrowing();
@@ -250,7 +250,8 @@ unsigned Descriptor_Length:
void ChangeMarks(clMark **Mark1, clMark **Mark2, MarkAdPos *NewPos);
bool CheckVDRHD();
- bool CheckPATPMT();
+ off_t SeekPATPMT();
+ bool CheckPATPMT(off_t Offset=0);
bool CheckTS();
bool LoadInfo();
bool SaveInfo();
diff --git a/command/marks.cpp b/command/marks.cpp
index 2ebef9f..130ff42 100644
--- a/command/marks.cpp
+++ b/command/marks.cpp
@@ -545,7 +545,7 @@ bool clMarks::CheckIndex(const char *Directory, bool isTS, int *FrameCnt, int *I
{
framecnt=statbuf.st_size/sizeof(struct tIndexVDR);
}
- if (framecnt!=*FrameCnt)
+ if (abs(framecnt-*FrameCnt)>2000)
{
*FrameCnt=framecnt;
*IndexError=IERR_TOOSHORT;
diff --git a/command/streaminfo.cpp b/command/streaminfo.cpp
index 4de2665..e52ca0b 100644
--- a/command/streaminfo.cpp
+++ b/command/streaminfo.cpp
@@ -120,7 +120,6 @@ bool cMarkAdStreamInfo::FindH264VideoInfos(MarkAdContext *maContext, uchar *pkt,
if (nalu==NAL_AUD)
{
- if (!maContext->Video.Info.Width) return false;
if (pkt[5]==0x10)
{
maContext->Video.Info.Pict_Type=MA_I_TYPE;
@@ -139,19 +138,19 @@ bool cMarkAdStreamInfo::FindH264VideoInfos(MarkAdContext *maContext, uchar *pkt,
int nal_len = nalUnescape(nal_data, pkt + 5, len - 5);
cBitStream bs(nal_data, nal_len);
- int profile_idc, pic_order_cnt_type, i, j;
-
uint32_t width=0;
uint32_t height=0;
uint32_t aspect_ratio_idc=0;
double frame_rate=0;
int sar_width=1,sar_height=1;
- profile_idc = bs.getU8(); // profile_idc
+ int profile_idc = bs.getU8(); // profile_idc
bs.skipBits(8); // constraint_setN_flags and reserved_zero_Nbits
bs.skipBits(8); // level_idc
bs.skipUeGolomb(); // seq_parameter_set_id
+ int i,j;
+
if ((profile_idc == 100) || (profile_idc == 110) || (profile_idc == 122) || (profile_idc == 244) ||
(profile_idc==44) || (profile_idc==83) || (profile_idc==86))
{
@@ -179,7 +178,7 @@ bool cMarkAdStreamInfo::FindH264VideoInfos(MarkAdContext *maContext, uchar *pkt,
}
// H264.log2_max_frame_num=bs.getUeGolomb()+4;
bs.skipUeGolomb(); // log2_max_frame_num_minus4
- pic_order_cnt_type = bs.getUeGolomb(); // pic_order_cnt_type
+ int pic_order_cnt_type = bs.getUeGolomb(); // pic_order_cnt_type
if (pic_order_cnt_type == 0)
bs.skipUeGolomb(); // log2_max_pic_order_cnt_lsb_minus4
else if (pic_order_cnt_type == 1)