From 8465398c6d2a57bc30a07fb61353a7c8ba6db574 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 21 Oct 2001 18:00:00 +0200 Subject: =?UTF-8?q?Version=200.97=20-=20Implemented=20a=20lock=20file=20to?= =?UTF-8?q?=20prevent=20more=20than=20one=20instance=20of=20VDR=20from=20r?= =?UTF-8?q?emoving=20=20=20files=20from=20the=20video=20directory=20at=20t?= =?UTF-8?q?he=20same=20time.=20-=20The=20new=20setup=20parameter=20SplitEd?= =?UTF-8?q?itedFiles=20can=20be=20used=20to=20control=20whether=20or=20=20?= =?UTF-8?q?=20not=20the=20result=20of=20an=20editing=20process=20shall=20b?= =?UTF-8?q?e=20written=20into=20separate=20files.=20-=20Fixed=20handling?= =?UTF-8?q?=20repeat=20function=20when=20using=20LIRC=20(thanks=20to=20Mat?= =?UTF-8?q?thias=20Weingart).=20-=20The=20shutdown=20program=20(defined=20?= =?UTF-8?q?with=20the=20'-s'=20option)=20now=20also=20gets=20the=20channel?= =?UTF-8?q?=20=20=20number=20and=20recording=20title=20of=20the=20timer=20?= =?UTF-8?q?(see=20INSTALL).=20-=20New=20channel=20data=20for=20'Premiere?= =?UTF-8?q?=20One',=20'Premiere=20X-Action',=20'Fox=20Kids=20T=FCrkce'=20?= =?UTF-8?q?=20=20and=20'N24'=20(thanks=20to=20Andreas=20Share,=20Ulrich=20?= =?UTF-8?q?R=F6der,=20Uwe=20Scheffler=20and=20Simon=20=20=20Bauschulte).?= =?UTF-8?q?=20Note=20that=20if=20you=20are=20using=20the=20default=20'chan?= =?UTF-8?q?nels.conf'=20or=20=20=20'channels.conf.cable'=20files=20you=20m?= =?UTF-8?q?ay=20need=20to=20check=20any=20exiting=20timers=20to=20see=20?= =?UTF-8?q?=20=20whether=20they=20still=20use=20the=20correct=20channel=20?= =?UTF-8?q?number.=20-=20Fixed=20the=20"EPG=20bugfix"=20(sometimes=20had?= =?UTF-8?q?=20duplicate=20information=20in=20Subtitle=20and=20=20=20Extend?= =?UTF-8?q?ed=20Description).=20-=20Fixed=20checking=20for=20valid=20video?= =?UTF-8?q?=20device=20when=20setting=20the=20video=20mode.=20-=20The=20ex?= =?UTF-8?q?ternal=20command=20'sort'=20is=20no=20longer=20required.=20VDR?= =?UTF-8?q?=20now=20sorts=20the=20list=20of=20=20=20recordings=20itself,?= =?UTF-8?q?=20making=20sure=20that=20recordings=20that=20stem=20from=20rep?= =?UTF-8?q?eating=20timers=20=20=20are=20sorted=20chronologically.=20Sorti?= =?UTF-8?q?ng=20is=20done=20according=20to=20the=20setting=20of=20the=20?= =?UTF-8?q?=20=20current=20locale,=20so=20you=20may=20want=20to=20make=20s?= =?UTF-8?q?ure=20LC=5FCOLLATE=20is=20set=20to=20the=20desired=20=20=20valu?= =?UTF-8?q?e=20(see=20INSTALL).=20-=20Fixed=20handling=20'newline'=20chara?= =?UTF-8?q?cters=20in=20EPG=20texts=20(thanks=20to=20Rolf=20Hakenes=20for?= =?UTF-8?q?=20=20=20an=20improved=20version=20of=20his=20'libdtv').=20=20?= =?UTF-8?q?=20Newline=20characters=20are=20always=20mapped=20to=20a=20sing?= =?UTF-8?q?le=20"blank"=20in=20VDR,=20because=20they=20=20=20would=20other?= =?UTF-8?q?wise=20disturb=20the=20Title=20and=20Subtitle=20layout=20in=20t?= =?UTF-8?q?he=20channel=20display=20=20=20(where=20these=20are=20assumed?= =?UTF-8?q?=20to=20be=20single=20line=20texts)=20and=20would=20have=20to?= =?UTF-8?q?=20be=20=20=20specially=20handled=20in=20the=20'epg.data'=20fil?= =?UTF-8?q?e=20and=20the=20LSTE=20command=20in=20SVDRP.=20-=20Mapping=20`?= =?UTF-8?q?=20("backtick")=20characters=20in=20EPG=20texts=20to=20'=20(sin?= =?UTF-8?q?gle=20quote).=20-=20Fixed=20timers=20starting=20and=20ending=20?= =?UTF-8?q?at=20unexpected=20times.=20'localtime()'=20was=20not=20=20=20th?= =?UTF-8?q?read=20safe,=20now=20using=20localtime=5Fr().=20-=20Removed=20t?= =?UTF-8?q?he=20"system=20time=20seen..."=20message.=20-=20Fixed=20a=20bug?= =?UTF-8?q?=20in=20the=20replay=20mode=20display=20when=20pressing=20the?= =?UTF-8?q?=20Green=20or=20Yellow=20=20=20button=20while=20in=20trick=20mo?= =?UTF-8?q?de=20(thanks=20to=20Stefan=20Huelswitt)=20-=20Closing=20all=20o?= =?UTF-8?q?pen=20file=20descriptors=20when=20calling=20external=20programs?= =?UTF-8?q?.=20-=20The=20menu=20timeout=20now=20also=20works=20when=20pres?= =?UTF-8?q?sing=20the=20"Back"=20button=20during=20replay=20=20=20to=20ent?= =?UTF-8?q?er=20the=20"Recordings"=20menu.=20-=20Updated=20'channels.conf'?= =?UTF-8?q?=20for=20the=20"Bundesliga"=20channels=20of=20Premiere=20World?= =?UTF-8?q?=20=20=20(thanks=20to=20Helmut=20Sch=E4chner).=20-=20Fixed=20re?= =?UTF-8?q?ading=20timers.conf=20and=20channels.conf=20that=20contain=20bl?= =?UTF-8?q?anks=20after=20numeric=20=20=20values.=20-=20Fixed=20handling?= =?UTF-8?q?=20trick=20modes=20near=20the=20beginning=20and=20end=20of=20a?= =?UTF-8?q?=20recording.=20-=20Pressing=20the=20"Back"=20button=20while=20?= =?UTF-8?q?replaying=20a=20DVD=20now=20leads=20to=20the=20DVD=20menu.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dvbapi.c | 130 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 74 insertions(+), 56 deletions(-) (limited to 'dvbapi.c') diff --git a/dvbapi.c b/dvbapi.c index 8a6e691..786dff7 100644 --- a/dvbapi.c +++ b/dvbapi.c @@ -7,7 +7,7 @@ * DVD support initially written by Andreas Schultz * based on dvdplayer-0.5 by Matjaz Thaler * - * $Id: dvbapi.c 1.129 2001/09/23 13:44:27 kls Exp $ + * $Id: dvbapi.c 1.132 2001/10/21 13:36:27 kls Exp $ */ //#define DVDDEBUG 1 @@ -72,6 +72,9 @@ extern "C" { // is broken: #define MAXBROKENTIMEOUT 30 // seconds +// The maximum time to wait before giving up while catching up on an index file: +#define MAXINDEXCATCHUP 2 // seconds + #define CHECK(s) { if ((s) < 0) LOG_ERROR; } // used for 'ioctl()' calls #define FATALERRNO (errno != EAGAIN && errno != EINTR) @@ -108,14 +111,14 @@ private: int size, last; tIndex *index; cResumeFile resumeFile; - bool CatchUp(void); + bool CatchUp(int Index = -1); public: cIndexFile(const char *FileName, bool Record); ~cIndexFile(); bool Ok(void) { return index != NULL; } void Write(uchar PictureType, uchar FileNumber, int FileOffset); bool Get(int Index, uchar *FileNumber, int *FileOffset, uchar *PictureType = NULL, int *Length = NULL); - int GetNextIFrame(int Index, bool Forward, uchar *FileNumber = NULL, int *FileOffset = NULL, int *Length = NULL); + int GetNextIFrame(int Index, bool Forward, uchar *FileNumber = NULL, int *FileOffset = NULL, int *Length = NULL, bool StayOffEnd = false); int Get(uchar FileNumber, int FileOffset); int Last(void) { CatchUp(); return last; } int GetResume(void) { return resumeFile.Read(); } @@ -199,42 +202,48 @@ cIndexFile::~cIndexFile() delete fileName; } -bool cIndexFile::CatchUp(void) +bool cIndexFile::CatchUp(int Index) { if (index && f >= 0) { - struct stat buf; - if (fstat(f, &buf) == 0) { - int newLast = buf.st_size / sizeof(tIndex) - 1; - if (newLast > last) { - if (size <= newLast) { - size *= 2; - if (size <= newLast) - size = newLast + 1; - } - index = (tIndex *)realloc(index, size * sizeof(tIndex)); - if (index) { - int offset = (last + 1) * sizeof(tIndex); - int delta = (newLast - last) * sizeof(tIndex); - if (lseek(f, offset, SEEK_SET) == offset) { - if (safe_read(f, &index[last + 1], delta) != delta) { - esyslog(LOG_ERR, "ERROR: can't read from index"); - delete index; - index = NULL; - close(f); - f = -1; - } - last = newLast; - return true; - } - else - LOG_ERROR; - } - else - esyslog(LOG_ERR, "ERROR: can't realloc() index"); - } - } - else - LOG_ERROR; + for (int i = 0; i <= MAXINDEXCATCHUP && (Index < 0 || Index >= last); i++) { + struct stat buf; + if (fstat(f, &buf) == 0) { + int newLast = buf.st_size / sizeof(tIndex) - 1; + if (newLast > last) { + if (size <= newLast) { + size *= 2; + if (size <= newLast) + size = newLast + 1; + } + index = (tIndex *)realloc(index, size * sizeof(tIndex)); + if (index) { + int offset = (last + 1) * sizeof(tIndex); + int delta = (newLast - last) * sizeof(tIndex); + if (lseek(f, offset, SEEK_SET) == offset) { + if (safe_read(f, &index[last + 1], delta) != delta) { + esyslog(LOG_ERR, "ERROR: can't read from index"); + delete index; + index = NULL; + close(f); + f = -1; + break; + } + last = newLast; + } + else + LOG_ERROR; + } + else + esyslog(LOG_ERR, "ERROR: can't realloc() index"); + } + } + else + LOG_ERROR; + if (Index >= last) + sleep(1); + else + return true; + } } return false; } @@ -256,7 +265,7 @@ void cIndexFile::Write(uchar PictureType, uchar FileNumber, int FileOffset) bool cIndexFile::Get(int Index, uchar *FileNumber, int *FileOffset, uchar *PictureType, int *Length) { if (index) { - CatchUp(); + CatchUp(Index); if (Index >= 0 && Index <= last) { *FileNumber = index[Index].number; *FileOffset = index[Index].offset; @@ -276,7 +285,7 @@ bool cIndexFile::Get(int Index, uchar *FileNumber, int *FileOffset, uchar *Pictu return false; } -int cIndexFile::GetNextIFrame(int Index, bool Forward, uchar *FileNumber, int *FileOffset, int *Length) +int cIndexFile::GetNextIFrame(int Index, bool Forward, uchar *FileNumber, int *FileOffset, int *Length, bool StayOffEnd) { if (index) { if (Forward) @@ -284,7 +293,7 @@ int cIndexFile::GetNextIFrame(int Index, bool Forward, uchar *FileNumber, int *F int d = Forward ? 1 : -1; for (;;) { Index += d; - if (Index >= 0 && Index <= last) { + if (Index >= 0 && Index < last - ((Forward && StayOffEnd) ? 100 : 0)) { if (index[Index].type == I_FRAME) { if (FileNumber) *FileNumber = index[Index].number; @@ -1049,17 +1058,26 @@ void cReplayBuffer::Input(void) if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) { uchar FileNumber; int FileOffset, Length; - int Index = index->GetNextIFrame(readIndex, playDir == pdForward, &FileNumber, &FileOffset, &Length); + int Index = index->GetNextIFrame(readIndex, playDir == pdForward, &FileNumber, &FileOffset, &Length, true); if (Index >= 0) { if (!NextFile(FileNumber, FileOffset)) break; } else { - Play(); + // can't call Play() here, because those functions may only be + // called from the foreground thread - and we also don't need + // to empty the buffer here + CHECK(ioctl(audioDev, AUDIO_SET_AV_SYNC, true)); + CHECK(ioctl(videoDev, VIDEO_CONTINUE)); + playMode = pmPlay; + playDir = pdForward; continue; } readIndex = Index; r = ReadFrame(replayFile, b, Length, sizeof(b)); + // must call StripAudioPackets() here because the buffer is not emptied + // when falling back from "fast forward" to "play" (see above) + StripAudioPackets(b, r); } else if (index) { uchar FileNumber; @@ -1205,17 +1223,11 @@ void cReplayBuffer::SkipSeconds(int Seconds) Empty(true); int Index = writeIndex; if (Index >= 0) { - if (Seconds < 0) { - int sec = index->Last() / FRAMESPERSEC; - if (Seconds < -sec) - Seconds = -sec; - } - Index += Seconds * FRAMESPERSEC; - if (Index < 0) - Index = 1; // not '0', to allow GetNextIFrame() below to work! - uchar FileNumber; - int FileOffset; - readIndex = writeIndex = index->GetNextIFrame(Index, false, &FileNumber, &FileOffset) - 1; // Input() will first increment it! + Index = max(Index + Seconds * FRAMESPERSEC, 0); + if (Index > 0) + Index = index->GetNextIFrame(Index, false, NULL, NULL, NULL, true); + if (Index >= 0) + readIndex = writeIndex = Index - 1; // Input() will first increment it! } Empty(false); Play(); @@ -1250,9 +1262,9 @@ void cReplayBuffer::GetIndex(int &Current, int &Total, bool SnapToIFrame) { if (index) { if (playMode == pmStill) - Current = readIndex; + Current = max(readIndex, 0); else { - Current = writeIndex; + Current = max(writeIndex, 0); if (SnapToIFrame) { int i1 = index->GetNextIFrame(Current + 1, false); int i2 = index->GetNextIFrame(Current, true); @@ -2392,6 +2404,12 @@ void cCuttingBuffer::Action(void) Index = Mark->position; Mark = fromMarks.Next(Mark); CurrentFileNumber = 0; // triggers SetOffset before reading next frame + if (Setup.SplitEditedFiles) { + toFile = toFileName->NextFile(); + if (toFile < 0) + break; + FileSize = 0; + } } // the 'else' case (i.e. 'final end mark reached') is handled above // in 'Write one frame', so that the edited version will end right @@ -3163,7 +3181,7 @@ void cDvbApi::SetModeNormal(bool FromRecording) void cDvbApi::SetVideoFormat(videoFormat_t Format) { - if (fd_video) + if (fd_video >= 0) CHECK(ioctl(fd_video, VIDEO_SET_FORMAT, Format)); } -- cgit v1.2.3