diff options
author | Jochen Dolze <vdr@dolze.de> | 2010-08-08 19:17:34 +0200 |
---|---|---|
committer | Jochen Dolze <vdr@dolze.de> | 2010-08-08 19:17:34 +0200 |
commit | ade86712df523fc7c10545cfe450b59f39a71ba7 (patch) | |
tree | aca2f66d1d8091b0d3be0921682f29432b22676b | |
parent | fe701af3c1ebffea28edd89ec4fa97ea82c82cca (diff) | |
download | vdr-plugin-markad-ade86712df523fc7c10545cfe450b59f39a71ba7.tar.gz vdr-plugin-markad-ade86712df523fc7c10545cfe450b59f39a71ba7.tar.bz2 |
Fixed index repair for inded.vdr
-rw-r--r-- | command/Makefile | 2 | ||||
-rw-r--r-- | command/demux.cpp | 115 | ||||
-rw-r--r-- | command/demux.h | 7 | ||||
-rw-r--r-- | command/markad-standalone.cpp | 65 | ||||
-rw-r--r-- | command/marks.cpp | 38 | ||||
-rw-r--r-- | command/marks.h | 1 | ||||
-rw-r--r-- | command/queue.cpp | 9 | ||||
-rw-r--r-- | command/queue.h | 1 | ||||
-rw-r--r-- | command/vdr2pkt.cpp | 35 | ||||
-rw-r--r-- | command/vdr2pkt.h | 29 |
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 |