summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJochen Dolze <vdr@dolze.de>2010-08-08 19:17:34 +0200
committerJochen Dolze <vdr@dolze.de>2010-08-08 19:17:34 +0200
commitade86712df523fc7c10545cfe450b59f39a71ba7 (patch)
treeaca2f66d1d8091b0d3be0921682f29432b22676b
parentfe701af3c1ebffea28edd89ec4fa97ea82c82cca (diff)
downloadvdr-plugin-markad-ade86712df523fc7c10545cfe450b59f39a71ba7.tar.gz
vdr-plugin-markad-ade86712df523fc7c10545cfe450b59f39a71ba7.tar.bz2
Fixed index repair for inded.vdr
-rw-r--r--command/Makefile2
-rw-r--r--command/demux.cpp115
-rw-r--r--command/demux.h7
-rw-r--r--command/markad-standalone.cpp65
-rw-r--r--command/marks.cpp38
-rw-r--r--command/marks.h1
-rw-r--r--command/queue.cpp9
-rw-r--r--command/queue.h1
-rw-r--r--command/vdr2pkt.cpp35
-rw-r--r--command/vdr2pkt.h29
10 files changed, 164 insertions, 138 deletions
diff --git a/command/Makefile b/command/Makefile
index 1656d77..e6e1f2f 100644
--- a/command/Makefile
+++ b/command/Makefile
@@ -28,7 +28,7 @@ INCLUDES += -I..
### The object files (add further files here):
-OBJS = markad-standalone.o decoder.o marks.o streaminfo.o video.o audio.o demux.o queue.o vdr2pkt.o ts2pkt.o pes2es.o
+OBJS = markad-standalone.o decoder.o marks.o streaminfo.o video.o audio.o demux.o queue.o ts2pkt.o pes2es.o
### The main target:
diff --git a/command/demux.cpp b/command/demux.cpp
index 76e6003..73bf110 100644
--- a/command/demux.cpp
+++ b/command/demux.cpp
@@ -10,18 +10,18 @@
cMarkAdDemux::cMarkAdDemux()
{
ts2pkt=NULL;
- vdr2pkt=NULL;
pes2audioes=NULL;
pes2videoes=NULL;
pause=false;
pause_retval=0;
- queue = new cMarkAdPaketQueue(NULL,376);
+ min_needed=0;
+ skip=0;
+ queue = new cMarkAdPaketQueue(NULL,2176);
}
cMarkAdDemux::~cMarkAdDemux()
{
if (ts2pkt) delete ts2pkt;
- if (vdr2pkt) delete vdr2pkt;
if (pes2audioes) delete pes2audioes;
if (pes2videoes) delete pes2videoes;
if (queue) delete queue;
@@ -30,7 +30,6 @@ cMarkAdDemux::~cMarkAdDemux()
void cMarkAdDemux::Clear()
{
if (ts2pkt) ts2pkt->Clear();
- if (vdr2pkt) vdr2pkt->Clear();
if (pes2audioes) pes2audioes->Clear();
if (pes2videoes) pes2videoes->Clear();
if (queue) queue->Clear();
@@ -42,29 +41,11 @@ void cMarkAdDemux::ProcessVDR(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt
*Pkt=NULL;
*PktLen=0;
- uchar *pkt;
- int pktlen;
-
- if (!vdr2pkt)
- {
- if ((Pid.Type==MARKAD_PIDTYPE_AUDIO_AC3) || (Pid.Type==MARKAD_PIDTYPE_AUDIO_MP2))
- {
- vdr2pkt= new cMarkAdVDR2Pkt("VDR2PKT audio");
- }
- else
- {
- vdr2pkt= new cMarkAdVDR2Pkt("VDR2PKT video");
- }
- }
- if (!vdr2pkt) return;
-
- vdr2pkt->Process(Pid,Data,Count,&pkt,&pktlen);
-
if ((Pid.Type==MARKAD_PIDTYPE_AUDIO_AC3) || (Pid.Type==MARKAD_PIDTYPE_AUDIO_MP2))
{
if (!pes2audioes) pes2audioes=new cMarkAdPES2ES("PES2ES audio");
if (!pes2audioes) return;
- pes2audioes->Process(Pid,pkt,pktlen,Pkt,PktLen);
+ pes2audioes->Process(Pid,Data,Count,Pkt,PktLen);
}
if ((Pid.Type==MARKAD_PIDTYPE_VIDEO_H262) || (Pid.Type==MARKAD_PIDTYPE_VIDEO_H264))
@@ -81,7 +62,7 @@ void cMarkAdDemux::ProcessVDR(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt
}
}
if (!pes2videoes) return;
- pes2videoes->Process(Pid,pkt,pktlen,Pkt,PktLen);
+ pes2videoes->Process(Pid,Data,Count,Pkt,PktLen);
}
return;
@@ -137,7 +118,51 @@ void cMarkAdDemux::ProcessTS(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt,
return;
}
-int cMarkAdDemux::Process(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt, int *PktLen)
+int cMarkAdDemux::GetMinNeeded(MarkAdPid Pid, uchar *Data, int Count, bool *Offcnt)
+{
+ if (Pid.Num>=0) return TS_SIZE;
+
+ uchar *qData=queue->Peek(6);
+ if (!qData)
+ {
+ int len=6-queue->Length();
+ int cnt=(Count>len) ? len : Count;
+ queue->Put(Data,cnt);
+ return -cnt;
+ }
+
+ int stream=qData[3] & 0xF0;
+
+ if ((qData[0]==0) && (qData[1]==0) && (qData[2]==1) && (stream>0xBC))
+ {
+ int needed=qData[4]*256+qData[5];
+
+ if (((Pid.Type==MARKAD_PIDTYPE_VIDEO_H262) ||
+ (Pid.Type==MARKAD_PIDTYPE_VIDEO_H264)) && (stream!=0xE0))
+ {
+ // ignore 6 header bytes from queue->Put above
+ queue->Clear();
+ if (Offcnt) *Offcnt=true;
+ return -needed;
+ }
+ if (((Pid.Type==MARKAD_PIDTYPE_AUDIO_AC3) ||
+ (Pid.Type==MARKAD_PIDTYPE_AUDIO_MP2)) && (stream!=0xC0))
+ {
+ // ignore 6 header bytes from queue->Put above
+ queue->Clear();
+ if (Offcnt) *Offcnt=true;
+ return -needed;
+ }
+
+ return needed+6;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+int cMarkAdDemux::Process(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt, int *PktLen, bool *Offcnt)
{
if ((!Data) && (!Count) && (!Pkt) || (!PktLen)) return -1;
@@ -148,11 +173,39 @@ int cMarkAdDemux::Process(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt, in
int inlen=0;
int retval=0;
+ if (Offcnt) *Offcnt=false;
+
if (!pause)
{
- int min_needed=TS_SIZE;
+ if (!min_needed)
+ {
+ if (skip)
+ {
+ int t_skip=skip;
+ skip=0;
+ if (Offcnt) *Offcnt=true;
+ return t_skip;
+ }
+
+ int t_min_needed=GetMinNeeded(Pid,Data,Count,Offcnt);
+ if (t_min_needed==0)
+ {
+ return -1;
+ }
+ if (t_min_needed<0)
+ {
+ if (-t_min_needed>Count)
+ {
+ skip=-t_min_needed-Count;
+ return Count;
+ }
+ return -t_min_needed;
+ }
+ min_needed=t_min_needed;
+ }
int needed=min_needed-queue->Length();
+
if (Count>needed)
{
queue->Put(Data,needed);
@@ -163,10 +216,13 @@ int cMarkAdDemux::Process(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt, in
queue->Put(Data,Count);
retval=Count;
}
- if (queue->Length()<min_needed) return Count;
-
- inlen=TS_SIZE;
+ if (queue->Length()<min_needed)
+ {
+ return Count;
+ }
+ inlen=min_needed;
in=queue->Get(&inlen);
+ min_needed=0;
}
if (Pid.Num>=0)
@@ -195,5 +251,6 @@ int cMarkAdDemux::Process(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt, in
pause=false;
}
+ if (Offcnt) *Offcnt=true;
return retval;
}
diff --git a/command/demux.h b/command/demux.h
index 589d082..7b70891 100644
--- a/command/demux.h
+++ b/command/demux.h
@@ -18,14 +18,12 @@
#include "global.h"
#include "queue.h"
-#include "vdr2pkt.h"
#include "ts2pkt.h"
#include "pes2es.h"
class cMarkAdDemux
{
private:
- cMarkAdVDR2Pkt *vdr2pkt;
cMarkAdTS2Pkt *ts2pkt;
cMarkAdPES2ES *pes2audioes;
cMarkAdPES2ES *pes2videoes;
@@ -33,14 +31,17 @@ private:
bool pause;
int pause_retval;
+ int min_needed;
+ int skip;
+ int GetMinNeeded(MarkAdPid Pid, uchar *Data, int Count, bool *Offcnt);
void ProcessTS(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt, int *PktLen);
void ProcessVDR(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt, int *PktLen);
public:
cMarkAdDemux();
~cMarkAdDemux();
void Clear();
- int Process(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt, int *PktLen);
+ int Process(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt, int *PktLen, bool *Offcnt);
};
#endif
diff --git a/command/markad-standalone.cpp b/command/markad-standalone.cpp
index 588170d..c0b7599 100644
--- a/command/markad-standalone.cpp
+++ b/command/markad-standalone.cpp
@@ -710,7 +710,8 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number)
int dataread;
dsyslog("processing file %05i",Number);
- uint64_t base=0;
+ uint64_t offset=0;
+ int offset_add=0;
while ((dataread=read(f,data,datalen))>0)
{
if (abort) break;
@@ -720,15 +721,17 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number)
{
uchar *pkt;
int pktlen;
+ bool offcnt=false;
uchar *tspkt = data;
int tslen = dataread;
while (tslen>0)
{
- int len=video_demux->Process(macontext.Info.VPid,tspkt,tslen,&pkt,&pktlen);
+ int len=video_demux->Process(macontext.Info.VPid,tspkt,tslen,&pkt,&pktlen,&offcnt);
if (len<0)
{
+ esyslog("Error demuxing video");
break;
}
else
@@ -738,17 +741,18 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number)
bool dRes=false;
if (streaminfo->FindVideoInfos(&macontext,pkt,pktlen))
{
- uint64_t offset=base+(dataread-tslen);
if (!framecnt)
{
isyslog("%s %i%c",(macontext.Video.Info.Height>576) ? "HDTV" : "SDTV",
macontext.Video.Info.Height,
macontext.Video.Info.Interlaced ? 'i' : 'p');
AddStartMark();
- offset=0;
}
- if (bGenIndex) marks.WriteIndex(Directory,isTS,offset,
- macontext.Video.Info.Pict_Type,Number);
+ if (bGenIndex)
+ {
+ marks.WriteIndex(Directory,isTS,offset,
+ macontext.Video.Info.Pict_Type,Number);
+ }
framecnt++;
if (macontext.Video.Info.Pict_Type==MA_I_TYPE)
@@ -775,6 +779,16 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number)
}
tspkt+=len;
tslen-=len;
+ if (!offcnt)
+ {
+ offset_add+=len;
+ }
+ else
+ {
+ offset+=offset_add;
+ offset+=len;
+ offset_add=0;
+ }
}
}
}
@@ -789,9 +803,10 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number)
while (tslen>0)
{
- int len=ac3_demux->Process(macontext.Info.DPid,tspkt,tslen,&pkt,&pktlen);
+ int len=ac3_demux->Process(macontext.Info.DPid,tspkt,tslen,&pkt,&pktlen,NULL);
if (len<0)
{
+ esyslog("Error demuxing ac3-audio");
break;
}
else
@@ -830,9 +845,10 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number)
while (tslen>0)
{
- int len=mp2_demux->Process(macontext.Info.APid,tspkt,tslen,&pkt,&pktlen);
+ int len=mp2_demux->Process(macontext.Info.APid,tspkt,tslen,&pkt,&pktlen,NULL);
if (len<0)
{
+ esyslog("Error demuxing mp2-audio");
break;
}
else
@@ -868,7 +884,6 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number)
if (f!=-1) close(f);
return false;
}
- base+=dataread;
}
close(f);
return true;
@@ -964,41 +979,37 @@ void cMarkAdStandalone::Process(const char *Directory)
usec+=1000000;
sec--;
}
+ marks.CloseIndex(Directory,isTS);
if (marks.Save(Directory,macontext.Video.Info.FramesPerSecond,isTS))
{
- marks.CloseIndex(Directory,isTS);
bool bIndexError=false;
if (marks.CheckIndex(Directory,isTS,&bIndexError))
{
if (bIndexError)
{
- if ((macontext.Info.VPid.Type==MARKAD_PIDTYPE_VIDEO_H264) && (!isTS))
- {
- esyslog("index doesn't match marks, sorry you're lost");
- }
- else
+ if (bGenIndex)
{
- if (bGenIndex)
+ if (RegenerateIndex())
{
- if (RegenerateIndex())
- {
- isyslog("recreated index");
- }
- else
- {
- esyslog("failed to recreate index");
- }
+ isyslog("recreated index");
}
else
{
- esyslog("index doesn't match marks%s",
- isTS ? ", sorry you're lost" :
- ", please run genindex");
+ esyslog("failed to recreate index");
}
}
+ else
+ {
+ esyslog("index doesn't match marks%s",
+ ((isTS) || ((macontext.Info.VPid.Type==
+ MARKAD_PIDTYPE_VIDEO_H264) && (!isTS))) ?
+ ", sorry you're lost" :
+ ", please run genindex");
+ }
}
}
}
+ if (bGenIndex) marks.RemoveGeneratedIndex(Directory,isTS);
SaveInfo(Directory);
diff --git a/command/marks.cpp b/command/marks.cpp
index 4afae07..df486c4 100644
--- a/command/marks.cpp
+++ b/command/marks.cpp
@@ -308,6 +308,15 @@ char *clMarks::IndexToHMSF(int Index, double FramesPerSecond)
return buf;
}
+void clMarks::RemoveGeneratedIndex(const char *Directory, bool isTS)
+{
+ char *ipath=NULL;
+ if (asprintf(&ipath,"%s/index%s.generated",Directory,isTS ? "" : ".vdr")==-1) return;
+ unlink(ipath);
+ free(ipath);
+ return;
+}
+
void clMarks::WriteIndex(const char *Directory, bool isTS, uint64_t Offset,
int FrameType, int Number)
{
@@ -318,6 +327,7 @@ void clMarks::WriteIndex(const char *Directory, bool isTS, uint64_t Offset,
indexfd=open(ipath,O_WRONLY|O_CREAT|O_TRUNC,0644);
free(ipath);
if (indexfd==-1) return;
+ Offset=0;
}
if (isTS)
{
@@ -326,7 +336,7 @@ void clMarks::WriteIndex(const char *Directory, bool isTS, uint64_t Offset,
IndexTS.reserved=0;
IndexTS.independent=(FrameType==1);
IndexTS.number=(uint16_t) Number;
- write(indexfd,&IndexTS,sizeof(IndexTS));
+ if (write(indexfd,&IndexTS,sizeof(IndexTS))!=sizeof(IndexTS)) return;
}
else
{
@@ -335,30 +345,30 @@ void clMarks::WriteIndex(const char *Directory, bool isTS, uint64_t Offset,
IndexVDR.type=(unsigned char) FrameType;
IndexVDR.number=(unsigned char) Number;
IndexVDR.reserved=0;
- write(indexfd,&IndexVDR,sizeof(IndexVDR));
+ if (write(indexfd,&IndexVDR,sizeof(IndexVDR))!=sizeof(IndexVDR)) return;
}
+ return;
}
void clMarks::CloseIndex(const char *Directory, bool isTS)
{
- if (indexfd!=-1)
+ if (indexfd==-1) return;
+
+ if (getuid()==0 || geteuid()!=0)
{
- if (getuid()==0 || geteuid()!=0)
+ // if we are root, set fileowner to owner of 001.vdr/00001.ts file
+ char *spath=NULL;
+ if (asprintf(&spath,"%s/%s",Directory,isTS ? "00001.ts" : "001.vdr")!=-1)
{
- // if we are root, set fileowner to owner of 001.vdr/00001.ts file
- char *spath=NULL;
- if (asprintf(&spath,"%s/%s",Directory,isTS ? "00001.ts" : "001.vdr")!=-1)
+ struct stat statbuf;
+ if (!stat(spath,&statbuf))
{
- struct stat statbuf;
- if (!stat(spath,&statbuf))
- {
- if (fchown(indexfd,statbuf.st_uid, statbuf.st_gid)) {};
- }
- free(spath);
+ if (fchown(indexfd,statbuf.st_uid, statbuf.st_gid)) {};
}
+ free(spath);
}
- close(indexfd);
}
+ close(indexfd);
indexfd=-1;
}
diff --git a/command/marks.h b/command/marks.h
index 6ffedad..80ba01f 100644
--- a/command/marks.h
+++ b/command/marks.h
@@ -112,6 +112,7 @@ public:
void WriteIndex(const char *Directory, bool isTS, uint64_t Offset,
int FrameType, int Number);
void CloseIndex(const char *Directory, bool isTS);
+ void RemoveGeneratedIndex(const char *Directory,bool isTS);
};
#endif
diff --git a/command/queue.cpp b/command/queue.cpp
index 3c9413c..81c0287 100644
--- a/command/queue.cpp
+++ b/command/queue.cpp
@@ -131,6 +131,15 @@ uchar *cMarkAdPaketQueue::Get(int *Size)
return ret;
}
+uchar *cMarkAdPaketQueue::Peek(int Size)
+{
+ if (!buffer) return NULL;
+ if (!Size) return NULL;
+ if (Length()<Size) return NULL;
+ uchar *ret=&buffer[outptr];
+ return ret;
+}
+
int cMarkAdPaketQueue::FindPktHeader(int Start, int *StreamSize,int *HeaderSize, bool LongStartCode)
{
if ((!StreamSize) || (!HeaderSize)) return -1;
diff --git a/command/queue.h b/command/queue.h
index a24014d..09257fd 100644
--- a/command/queue.h
+++ b/command/queue.h
@@ -140,6 +140,7 @@ public:
bool Inject(uchar *Data, int Size);
bool Put(uchar *Data, int Size);
uchar *Get(int *Size);
+ uchar *Peek(int Size);
#define MA_PACKET_PKT 0x10 // 0x00 0x00 0x01 (PES / H262)
#define MA_PACKET_H264 0x11 // 0x00 0x00 0x00 0x01 (H264)
diff --git a/command/vdr2pkt.cpp b/command/vdr2pkt.cpp
deleted file mode 100644
index c7f0ffd..0000000
--- a/command/vdr2pkt.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * vdr2pkt.cpp: A program for the Video Disk Recorder
- *
- * See the README file for copyright information and how to reach the author.
- *
- */
-
-#include "vdr2pkt.h"
-
-cMarkAdVDR2Pkt::cMarkAdVDR2Pkt(const char *QueueName, int QueueSize)
-{
- queue = new cMarkAdPaketQueue(QueueName,QueueSize);
-}
-
-cMarkAdVDR2Pkt::~cMarkAdVDR2Pkt()
-{
- if (queue) delete queue;
-}
-
-void cMarkAdVDR2Pkt::Clear()
-{
- if (queue) queue->Clear();
-}
-
-void cMarkAdVDR2Pkt::Process(MarkAdPid Pid, uchar *VDRData, int VDRSize, uchar **PktData, int *PktSize)
-{
- if ((!PktData) || (!PktSize) || (!queue)) return;
- *PktData=NULL;
- *PktSize=0;
- if (!Pid.Type) return;
-
- if (VDRData) queue->Put(VDRData,VDRSize);
- *PktData=queue->GetPacket(PktSize,MA_PACKET_PKT);
- return;
-}
diff --git a/command/vdr2pkt.h b/command/vdr2pkt.h
deleted file mode 100644
index f4f7630..0000000
--- a/command/vdr2pkt.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * vdr2pkt.h: A program for the Video Disk Recorder
- *
- * See the README file for copyright information and how to reach the author.
- *
- */
-
-#ifndef __vdr2pkt_h_
-#define __vdr2pkt_h_
-
-#ifndef uchar
-typedef unsigned char uchar;
-#endif
-
-#include "global.h"
-#include "queue.h"
-
-class cMarkAdVDR2Pkt
-{
-private:
- cMarkAdPaketQueue *queue;
-public:
- cMarkAdVDR2Pkt(const char *QueueName="VDR2PKT", int QueueSize=32768);
- ~cMarkAdVDR2Pkt();
- void Clear();
- void Process(MarkAdPid Pid,uchar *VDRData, int VDRSize, uchar **PktData, int *PktSize);
-};
-
-#endif