diff options
-rw-r--r-- | audio.cpp | 9 | ||||
-rw-r--r-- | audio.h | 2 | ||||
-rw-r--r-- | decoder.cpp | 6 | ||||
-rw-r--r-- | global.h | 8 | ||||
-rw-r--r-- | markad-standalone.cpp | 71 | ||||
-rw-r--r-- | markad-standalone.h | 2 | ||||
-rw-r--r-- | marks.cpp | 181 | ||||
-rw-r--r-- | marks.h | 24 | ||||
-rw-r--r-- | video.cpp | 15 | ||||
-rw-r--r-- | video.h | 2 |
10 files changed, 160 insertions, 160 deletions
@@ -13,6 +13,7 @@ cMarkAdAudio::cMarkAdAudio(MarkAdContext *maContext) macontext=maContext; mark.Comment=NULL; mark.Position=0; + mark.Type=0; channels=0; #if 0 lastiframe_gain=-ANALYZEFRAMES; @@ -30,9 +31,10 @@ void cMarkAdAudio::ResetMark() if (mark.Comment) free(mark.Comment); mark.Comment=NULL; mark.Position=0; + mark.Type=0; } -bool cMarkAdAudio::AddMark(int Position, const char *Comment) +bool cMarkAdAudio::AddMark(int Type, int Position, const char *Comment) { if (!Comment) return false; if (mark.Comment) @@ -53,6 +55,7 @@ bool cMarkAdAudio::AddMark(int Position, const char *Comment) mark.Comment=strdup(Comment); } mark.Position=Position; + mark.Type=Type; return true; } @@ -152,7 +155,7 @@ MarkAdMark *cMarkAdAudio::Process(int LastIFrame) if (asprintf(&buf,"audio channel silence detecion (%i)",lastiframe)!=-1) { isyslog(buf); - AddMark(lastiframe,buf); + AddMark(MT_SILENCECHANGE,lastiframe,buf); free(buf); } } @@ -165,7 +168,7 @@ MarkAdMark *cMarkAdAudio::Process(int LastIFrame) macontext->Audio.Info.Channels,lastiframe)!=-1) { isyslog(buf); - AddMark(lastiframe,buf); + AddMark(MT_CHANNELCHANGE,lastiframe,buf); free(buf); } } @@ -24,7 +24,7 @@ private: MarkAdMark mark; void ResetMark(); - bool AddMark(int Position, const char *Comment); + bool AddMark(int Type, int Position, const char *Comment); #define CUT_VAL 10 #define MIN_LOWVALS 3 diff --git a/decoder.cpp b/decoder.cpp index a8c8c07..6187084 100644 --- a/decoder.cpp +++ b/decoder.cpp @@ -278,6 +278,7 @@ cMarkAdDecoder::~cMarkAdDecoder() bool cMarkAdDecoder::DecodeMP2(MarkAdContext *maContext, uchar *espkt, int eslen) { if (!mp2_context) return false; + maContext->Audio.Data.Valid=false; AVPacket avpkt; #if LIBAVCODEC_VERSION_INT >= ((52<<16)+(25<<8)+0) av_init_packet(&avpkt); @@ -332,6 +333,7 @@ bool cMarkAdDecoder::SetAudioInfos(MarkAdContext *maContext, AVCodecContext *Aud bool cMarkAdDecoder::DecodeAC3(MarkAdContext *maContext, uchar *espkt, int eslen) { if (!ac3_context) return false; + maContext->Audio.Data.Valid=false; AVPacket avpkt; #if LIBAVCODEC_VERSION_INT >= ((52<<16)+(25<<8)+0) av_init_packet(&avpkt); @@ -380,13 +382,13 @@ void cMarkAdDecoder::PAR2DAR(AVRational a, AVRational *erg) bool cMarkAdDecoder::SetVideoInfos(MarkAdContext *maContext,AVCodecContext *Video_Context, AVFrame *Video_Frame) { if ((!maContext) || (!Video_Context) || (!Video_Frame)) return false; - maContext->Video.Data.Valid=false; for (int i=0; i<4; i++) { if (Video_Frame->data[i]) { maContext->Video.Data.Plane[i]=Video_Frame->data[i]; maContext->Video.Data.PlaneLinesize[i]=Video_Frame->linesize[i]; + maContext->Video.Data.Valid=true; } } maContext->Video.Info.Height=Video_Context->height; @@ -398,13 +400,13 @@ bool cMarkAdDecoder::SetVideoInfos(MarkAdContext *maContext,AVCodecContext *Vide maContext->Video.Info.AspectRatio.Num=dar.num; maContext->Video.Info.AspectRatio.Den=dar.den; - maContext->Video.Data.Valid=true; return true; } bool cMarkAdDecoder::DecodeVideo(MarkAdContext *maContext,uchar *pkt, int plen) { if (!video_context) return false; + maContext->Video.Data.Valid=false; if ((video_context->codec_id==CODEC_ID_H264) && (!video_context->skip_frame)) { @@ -22,8 +22,16 @@ typedef unsigned char uchar; #define MA_SP_TYPE 6 #define MA_BI_TYPE 7 +#define MT_COMMON 0x10 +#define MT_ASPECTCHANGE 0x20 +#define MT_CHANNELCHANGE 0x30 +#define MT_LOGOCHANGE 0x40 +#define MT_BORDERCHANGE 0x50 +#define MT_SILENCECHANGE 0x60 + typedef struct MarkAdMark { + int Type; int Position; char *Comment; } MarkAdMark; diff --git a/markad-standalone.cpp b/markad-standalone.cpp index f6b85d6..0530131 100644 --- a/markad-standalone.cpp +++ b/markad-standalone.cpp @@ -36,29 +36,34 @@ void syslog_with_tid(int priority, const char *format, ...) void cMarkAdStandalone::AddStartMark() { - if (!marks.Count()) - { - char *buf; - if (asprintf(&buf,"start of recording (0)")!=-1) - { - marks.Add(0,buf); - isyslog(buf); - free(buf); - } - } - else + char *buf; + if (asprintf(&buf,"start of recording (0)")!=-1) { - marksAligned=true; + marks.Add(MT_COMMON,0,buf); + isyslog(buf); + free(buf); } } void cMarkAdStandalone::AddMark(MarkAdMark *Mark) { if (!Mark) return; - if (Mark->Position<1) return; + if (!Mark->Type) return; - marks.Add(Mark->Position,Mark->Comment); + if (((Mark->Type==MT_CHANNELCHANGE) || (Mark->Type==MT_CHANNELCHANGE)) && + (Mark->Position>25000) && (bDecodeVideo)) + { + isyslog("%s change detected. video decoding disabled", + Mark->Type==MT_CHANNELCHANGE ? "audio channel" : "aspectratio"); + bDecodeVideo=false; + macontext.Video.Data.Valid=false; + marks.Del(MT_LOGOCHANGE); + marks.Del(MT_BORDERCHANGE); + } + marks.Add(Mark->Type,Mark->Position,Mark->Comment); + +#if 0 if (!marksAligned) { clMark *prevmark=marks.GetPrev(Mark->Position); @@ -81,7 +86,7 @@ void cMarkAdStandalone::AddMark(MarkAdMark *Mark) marksAligned=true; } } - +#endif } void cMarkAdStandalone::RateMarks() @@ -113,7 +118,7 @@ void cMarkAdStandalone::SaveFrame(int frame) fclose(pFile); } -void cMarkAdStandalone::CheckIndex() +void cMarkAdStandalone::CheckIndex(const char *Directory) { // Here we check the indexfile // if we have an index we check if the @@ -135,7 +140,8 @@ void cMarkAdStandalone::CheckIndex() int maxframes=statbuf.st_size/8; if (maxframes<(framecnt+200)) { - if ((difftime(time(NULL),statbuf.st_mtime))>120) return; // "old" file + if ((difftime(time(NULL),statbuf.st_mtime))>=10) return; // "old" file + marks.Save(Directory,macontext.Video.Info.FramesPerSecond,isTS); sleep(WAITTIME); // now we sleep and hopefully the index will grow waittime+=WAITTIME; if (errno==EINTR) return; @@ -161,7 +167,7 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number) if (!Directory) return false; if (!Number) return false; - CheckIndex(); + CheckIndex(Directory); if (abort) return false; int datalen=385024; @@ -215,14 +221,7 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number) isyslog("%s %i%c",(macontext.Video.Info.Height>576) ? "HDTV" : "SDTV", macontext.Video.Info.Height, macontext.Video.Info.Interlaced ? 'i' : 'p'); - if (!marks.Load(Directory,macontext.Video.Info.FramesPerSecond,isTS)) - { - AddStartMark(); - } - else - { - marksAligned=true; - } + AddStartMark(); } //printf("%05i( %c )\n",framecnt,frametypes[macontext.Video.Info.Pict_Type]); framecnt++; @@ -327,7 +326,7 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number) } } - CheckIndex(); + CheckIndex(Directory); if (abort) { if (f!=-1) close(f); @@ -347,6 +346,8 @@ void cMarkAdStandalone::Process(const char *Directory) gettimeofday(&tv1,&tz); + if (bBackupMarks) marks.Backup(Directory,isTS); + for (int i=1; i<=MaxFiles; i++) { if (abort) break; @@ -386,13 +387,16 @@ void cMarkAdStandalone::Process(const char *Directory) sec--; } - bool bIndexError; - if (marks.Save(Directory,macontext.Video.Info.FramesPerSecond,isTS,bBackupMarks,&bIndexError)) + if (marks.Save(Directory,macontext.Video.Info.FramesPerSecond,isTS)) { - if (bIndexError) + bool bIndexError; + if (marks.CheckIndex(Directory,isTS,&bIndexError)) { - esyslog("index doesn't match marks%s", - isTS ? ", please report this" : ", please run genindex"); + if (bIndexError) + { + esyslog("index doesn't match marks%s", + isTS ? ", please report this" : ", please run genindex"); + } } } @@ -401,7 +405,7 @@ void cMarkAdStandalone::Process(const char *Directory) if (etime>0) ftime=framecnt/etime; if (macontext.Video.Info.FramesPerSecond>0) ptime=ftime/macontext.Video.Info.FramesPerSecond; - isyslog("elapsed time %.2fs, %i frames, %.1f fps, %.1f pps", + isyslog("processed time %.2fs, %i frames, %.1f fps, %.1f pps", etime,framecnt,ftime,ptime); } @@ -841,7 +845,6 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, bool BackupMarks, in streaminfo=NULL; } - marksAligned=false; framecnt=0; lastiframe=0; } diff --git a/markad-standalone.h b/markad-standalone.h index 99ad0ac..08c6e3d 100644 --- a/markad-standalone.h +++ b/markad-standalone.h @@ -169,7 +169,7 @@ unsigned Descriptor_Length: bool bIgnoreAudioInfo; bool bIgnoreVideoInfo; - void CheckIndex(); + void CheckIndex(const char *Directory); char *indexFile; int sleepcnt; @@ -7,8 +7,9 @@ #include "marks.h" -clMark::clMark(int Position, const char *Comment) +clMark::clMark(int Type, int Position, const char *Comment) { + type=Type; position=Position; if (Comment) { @@ -41,12 +42,31 @@ clMarks::~clMarks() } +void clMarks::Del(int Type) +{ + if (!first) return; // no elements yet + + clMark *next,*mark=first; + while (mark) + { + next=mark->Next(); + if (mark->type==Type) Del(mark); + mark=next; + } +} + void clMarks::Del(clMark *Mark) { if (!Mark) return; - if (Mark->Next()) + + if (first==Mark) { - if (Mark->Prev()) + // we are the first mark + first=Mark->Next(); + } + else + { + if (Mark->Next() && (Mark->Prev())) { // there is a next and prev object Mark->Prev()->SetNext(Mark->Next()); @@ -54,16 +74,10 @@ void clMarks::Del(clMark *Mark) } else { - // just a next, so we are number 1 - Mark->Next()->SetPrev(NULL); - first=Mark->Next(); + // we are the last + Mark->Prev()->SetNext(NULL); } } - else - { - // we are the last - first=NULL; - } delete Mark; count--; } @@ -107,7 +121,7 @@ clMark *clMarks::GetNext(int Position) return mark->Next(); } -clMark *clMarks::Add(int Position,const char *Comment) +clMark *clMarks::Add(int Type, int Position,const char *Comment) { clMark *newmark; if ((newmark=Get(Position))) @@ -120,7 +134,7 @@ clMark *clMarks::Add(int Position,const char *Comment) return newmark; } - newmark=new clMark(Position,Comment); + newmark=new clMark(Type, Position,Comment); if (!newmark) return NULL; if (!first) @@ -182,52 +196,6 @@ clMark *clMarks::Add(int Position,const char *Comment) return NULL; } -bool clMarks::Load(const char *Directory,double FrameRate, bool isTS) -{ - char *fpath=NULL; - if (asprintf(&fpath,"%s/%s%s",Directory,filename,isTS ? "" : ".vdr")==-1) return false; - - FILE *mf; - mf=fopen(fpath,"r"); - free(fpath); - if (!mf) return false; - - char *line=NULL; - size_t length; - int h, m, s, f; - - while (getline(&line,&length,mf)!=-1) - { - char descr[256]=""; - f=1; - int n=sscanf(line,"%d:%d:%d.%d %80c",&h, &m, &s, &f,(char *) &descr); - if (n==1) - { - Add(h); - } - if (n>=3) - { - int pos=int(round((h*3600+m*60+s)*FrameRate))+f-1; - if (n<=4) - { - Add(pos); - } - else - { - char *lf=strchr(descr,10); - if (lf) *lf=0; - char *cr=strchr(descr,13); - if (cr) *cr=0; - Add(pos,descr); - } - } - } - if (line) free(line); - fclose(mf); - - return true; -} - char *clMarks::IndexToHMSF(int Index, double FramesPerSecond) { if (FramesPerSecond==0.0) return NULL; @@ -242,66 +210,82 @@ char *clMarks::IndexToHMSF(int Index, double FramesPerSecond) return buf; } -bool clMarks::CheckIndex(int FileDescriptor, int Index, bool isTS) +bool clMarks::CheckIndex(const char *Directory, bool isTS, bool *IndexError) { - // return true on error - if (FileDescriptor==-1) return true; - if (Index<0) return true; - - if (isTS) + if (!IndexError) return false; + if (!first) { - off_t offset = Index * sizeof(struct tIndexTS); - if (lseek(FileDescriptor,offset,SEEK_SET)!=offset) return true; - struct tIndexTS IndexTS; - if (read(FileDescriptor,&IndexTS,sizeof(IndexTS))!=sizeof(IndexTS)) return true; - if (IndexTS.independent) return false; + *IndexError=false; + return true; } - else + char *ipath=NULL; + if (asprintf(&ipath,"%s/index%s",Directory,isTS ? "" : ".vdr")==-1) return false; + + int fd=open(ipath,O_RDONLY); + free(ipath); + if (fd==-1) return false; + + clMark *mark=first; + while (mark) { - off_t offset = Index * sizeof(struct tIndexVDR); - if (lseek(FileDescriptor,offset,SEEK_SET)!=offset) return true; - struct tIndexVDR IndexVDR; - if (read(FileDescriptor,&IndexVDR,sizeof(IndexVDR))!=sizeof(IndexVDR)) return true; - if (IndexVDR.type==1) return false; + if (isTS) + { + off_t offset = mark->position * sizeof(struct tIndexTS); + if (lseek(fd,offset,SEEK_SET)!=offset) return true; + struct tIndexTS IndexTS; + if (read(fd,&IndexTS,sizeof(IndexTS))!=sizeof(IndexTS)) return true; + if (IndexTS.independent) return false; + } + else + { + off_t offset = mark->position * sizeof(struct tIndexVDR); + if (lseek(fd,offset,SEEK_SET)!=offset) return true; + struct tIndexVDR IndexVDR; + if (read(fd,&IndexVDR,sizeof(IndexVDR))!=sizeof(IndexVDR)) return true; + if (IndexVDR.type==1) return false; + } + mark=mark->Next(); } + return true; } -bool clMarks::Save(const char *Directory, double FrameRate, bool isTS, bool Backup, bool *IndexError) +bool clMarks::Backup(const char *Directory, bool isTS) { - if (IndexError) *IndexError=false; - if (!first) return false; - char *fpath=NULL; if (asprintf(&fpath,"%s/%s%s",Directory,filename,isTS ? "" : ".vdr")==-1) return false; - char *ipath=NULL; - if (asprintf(&ipath,"%s/index%s",Directory,isTS ? "" : ".vdr")==-1) ipath=NULL; - - if (Backup) + // make backup of old marks, filename convention taken from noad + char *bpath=NULL; + if (asprintf(&bpath,"%s/%s0%s",Directory,filename,isTS ? "" : ".vdr")==-1) { - // make backup of old marks, filename convention taken from noad - char *bpath=NULL; - if (asprintf(&bpath,"%s/%s0%s",Directory,filename,isTS ? "" : ".vdr")!=-1) - { - rename(fpath,bpath); - free(bpath); - } + free(fpath); + return false; } + int ret=rename(fpath,bpath); + free(bpath); + free(fpath); + return (ret==0); +} + +bool clMarks::Save(const char *Directory, double FrameRate, bool isTS) +{ + if (!first) return false; + if (savedcount==count) return false; + + char *fpath=NULL; + if (asprintf(&fpath,"%s/%s%s",Directory,filename,isTS ? "" : ".vdr")==-1) return false; + FILE *mf; mf=fopen(fpath,"w+"); if (!mf) { free(fpath); - if (ipath) free(ipath); return false; } - int fd=-1; - if (ipath) fd=open(ipath,O_RDONLY); - clMark *mark=first; while (mark) { @@ -310,17 +294,10 @@ bool clMarks::Save(const char *Directory, double FrameRate, bool isTS, bool Back { fprintf(mf,"%s %s\n",buf,mark->comment ? mark->comment : ""); free(buf); - if ((IndexError) && (fd!=-1)) - { - *IndexError=CheckIndex(fd,mark->position,isTS); - } } mark=mark->Next(); } fclose(mf); - free(ipath); - - if (fd!=-1) close(fd); if (getuid()==0 || geteuid()!=0) { @@ -23,9 +23,10 @@ private: clMark *next; clMark *prev; public: + int type; int position; char *comment; - clMark(int Position = 0, const char *Comment = NULL); + clMark(int Type=0, int Position = 0, const char *Comment = NULL); ~clMark(); clMark *Next() { @@ -76,19 +77,20 @@ uint16_t number: char filename[1024]; clMark *first; char *IndexToHMSF(int Index, double FramesPerSecond); - bool CheckIndex(int FileDescriptor, int Index, bool isTS); int count; + int savedcount; public: + clMarks() + { + strcpy(filename,"marks"); + first=NULL; + savedcount=0; + } ~clMarks(); int Count() { return count; } - clMarks() - { - strcpy(filename,"marks"); - first=NULL; - }; void SetFileName(const char *FileName) { if (FileName) @@ -97,13 +99,15 @@ public: filename[sizeof(filename)-1]=0; } } - clMark *Add(int Position, const char *Comment = NULL); + clMark *Add(int Type, int Position, const char *Comment = NULL); void Del(clMark *Mark); + void Del(int Type); clMark *Get(int Position); clMark *GetPrev(int Position); clMark *GetNext(int Position); - bool Load(const char *Directory, double FrameRate, bool isTS); - bool Save(const char *Directory, double FrameRate, bool isTS, bool Backup, bool *IndexError); + bool Backup(const char *Directory, bool isTS); + bool Save(const char *Directory, double FrameRate, bool isTS); + bool CheckIndex(const char *Directory, bool isTS, bool *IndexError); }; #endif @@ -493,6 +493,7 @@ cMarkAdVideo::cMarkAdVideo(MarkAdContext *maContext) aspectratio.Den=0; mark.Comment=NULL; mark.Position=0; + mark.Type=0; hborder=new cMarkAdBlackBordersHoriz(maContext); logo = new cMarkAdLogo(maContext); @@ -510,9 +511,10 @@ void cMarkAdVideo::ResetMark() if (mark.Comment) free(mark.Comment); mark.Comment=NULL; mark.Position=0; + mark.Type=0; } -bool cMarkAdVideo::AddMark(int Position, const char *Comment) +bool cMarkAdVideo::AddMark(int Type, int Position, const char *Comment) { if (!Comment) return false; if (mark.Comment) @@ -533,6 +535,7 @@ bool cMarkAdVideo::AddMark(int Position, const char *Comment) mark.Comment=strdup(Comment); } mark.Position=Position; + mark.Type=Type; return true; } @@ -561,7 +564,7 @@ MarkAdMark *cMarkAdVideo::Process(int LastIFrame) if (asprintf(&buf,"detected logo start (%i)",logoiframe)!=-1) { isyslog(buf); - AddMark(logoiframe,buf); + AddMark(MT_LOGOCHANGE,logoiframe,buf); free(buf); } } @@ -570,7 +573,7 @@ MarkAdMark *cMarkAdVideo::Process(int LastIFrame) if (asprintf(&buf,"detected logo stop (%i)",logoiframe)!=-1) { isyslog(buf); - AddMark(logoiframe,buf); + AddMark(MT_LOGOCHANGE,logoiframe,buf); free(buf); } } @@ -586,7 +589,7 @@ MarkAdMark *cMarkAdVideo::Process(int LastIFrame) if (asprintf(&buf,"detected start of horiz. borders (%i)",borderiframe)!=-1) { isyslog(buf); - AddMark(borderiframe,buf); + AddMark(MT_BORDERCHANGE,borderiframe,buf); free(buf); } } @@ -597,7 +600,7 @@ MarkAdMark *cMarkAdVideo::Process(int LastIFrame) if (asprintf(&buf,"detected stop of horiz. borders (%i)",borderiframe)!=-1) { isyslog(buf); - AddMark(borderiframe,buf); + AddMark(MT_BORDERCHANGE,borderiframe,buf); free(buf); } } @@ -613,7 +616,7 @@ MarkAdMark *cMarkAdVideo::Process(int LastIFrame) macontext->Video.Info.AspectRatio.Den,LastIFrame)!=-1) { isyslog(buf); - AddMark(LastIFrame,buf); + AddMark(MT_ASPECTCHANGE,LastIFrame,buf); free(buf); } } @@ -102,7 +102,7 @@ private: cMarkAdLogo *logo; void ResetMark(); - bool AddMark(int Position, const char *Comment); + bool AddMark(int Type, int Position, const char *Comment); bool AspectRatioChange(MarkAdAspectRatio *a, MarkAdAspectRatio *b); void SetTimerMarks(int LastIFrame); |