diff options
author | Thomas Günther <tom@toms-cafe.de> | 2009-07-17 00:58:49 +0200 |
---|---|---|
committer | Thomas Günther <tom@toms-cafe.de> | 2009-07-17 01:17:52 +0200 |
commit | 56ecb9dadf63f61d227c6b8acd05dcc1da17365f (patch) | |
tree | f1ff697bceb66877e08c18b55c897f875cc3e320 | |
parent | 97c5f35c27dc65f3bc2ee9fe338f7341d65f1446 (diff) | |
download | vdr-plugin-text2skin-56ecb9dadf63f61d227c6b8acd05dcc1da17365f.tar.gz vdr-plugin-text2skin-56ecb9dadf63f61d227c6b8acd05dcc1da17365f.tar.bz2 |
Adapted to new recording format and variable frame rate (VDR >= 1.7.3)
-rw-r--r-- | HISTORY | 2 | ||||
-rw-r--r-- | common.c | 78 | ||||
-rw-r--r-- | common.h | 10 | ||||
-rw-r--r-- | display.c | 42 | ||||
-rw-r--r-- | render.c | 2 | ||||
-rw-r--r-- | status.c | 10 | ||||
-rw-r--r-- | status.h | 3 |
7 files changed, 78 insertions, 69 deletions
@@ -93,6 +93,8 @@ ____-__-__: Version 1.3 - Compile internal image quantizing code only in Imlib2 builds. - Add support for building with GraphicsMagick. - Draw replay progress bar symmetrically +- Adapted to new recording format and variable frame rate (VDR >= 1.7.3 - + closes #150) 2009-06-01: Version 1.2 @@ -223,55 +223,29 @@ int GetRecordingSize(const char *FileName) return (rec) ? DirSizeMB(FileName) : 0; } -int GetRecordingLength(const char *FileName) +int GetRecordingLength(const char *FileName, double FramesPerSecond, bool IsPesRecording) { - // based on the enAIO-Patch for VDR - #define INDEXFILESUFFIX "/index.vdr" - +#define INDEXFILESUFFIX "/index" struct tIndex { int offset; uchar type; uchar number; short reserved; }; - tIndex *index; - char RecLength[21]; - char *filename = NULL; - int last = -1; - index = NULL; - if (FileName) { - filename = MALLOC(char, strlen(FileName) + strlen(INDEXFILESUFFIX) + 1); - if (filename) { - strcpy(filename, FileName); - char *pFileExt = filename + strlen(filename); - strcpy(pFileExt, INDEXFILESUFFIX); - int delta = 0; - if (access(filename, R_OK) == 0) { - struct stat buf; - if (stat(filename, &buf) == 0) { - delta = buf.st_size % sizeof(tIndex); - if (delta) { - delta = sizeof(tIndex) - delta; - esyslog("ERROR: invalid file size (%ld) in '%s'", (long)buf.st_size, filename); - } - last = (buf.st_size + delta) / sizeof(tIndex) - 1; - char hour[2], min[3]; - snprintf(RecLength, sizeof(RecLength), "%s", *IndexToHMSF(last, true)); - snprintf(hour, sizeof(hour), "%c", RecLength[0]); - snprintf(min, sizeof(min), "%c%c", RecLength[2], RecLength[3]); - return (atoi(hour) * 60) + atoi(min); - } - } - free(filename); - } - } - + struct stat buf; + cString fullname = cString::sprintf("%s%s", FileName, IsPesRecording ? INDEXFILESUFFIX ".vdr" : INDEXFILESUFFIX); + if (FileName && *fullname && access(fullname, R_OK) == 0 && stat(fullname, &buf) == 0) + return buf.st_size ? ((buf.st_size - 1) / sizeof(tIndex) + 1) / (60 * FramesPerSecond) : 0; return 0; } -int GetRecordingCuttedLength(const char *FileName) +int GetRecordingCuttedLength(const char *FileName, double FramesPerSecond, bool IsPesRecording) { cMarks marks; double length = 0; - int totalLength = GetRecordingLength(FileName); - const double diffIFrame = FRAMESPERSEC / 2; // approx. 1/2 sec. + int totalLength = GetRecordingLength(FileName, FramesPerSecond, IsPesRecording); + const double diffIFrame = FramesPerSecond / 2; // approx. 1/2 sec. +#if VDRVERSNUM >= 10703 + marks.Load(FileName, FramesPerSecond, IsPesRecording); +#else marks.Load(FileName); +#endif if (marks.Count()) { int start = 1; // first frame @@ -281,14 +255,14 @@ int GetRecordingCuttedLength(const char *FileName) if (isStart) start = m->position; else - length += (double)(m->position - start + 1 + diffIFrame) / (FRAMESPERSEC * 60); // [min] + length += (double)(m->position - start + 1 + diffIFrame) / (60 * FramesPerSecond); // [min] isStart = !isStart; } // if there is no end-mark the last segment goes to the end of the rec. if (!isStart) - length += totalLength - (double)(start - 1 - diffIFrame) / (FRAMESPERSEC * 60); // [min] + length += totalLength - (double)(start - 1 - diffIFrame) / (60 * FramesPerSecond); // [min] } // just to avoid, that the cutted length is bigger than the total length @@ -321,18 +295,27 @@ cxType TimeType(time_t Time, const std::string &Format) return false; } -cxType DurationType(uint Index, const std::string &Format) +cxType DurationType(uint Index, double FramesPerSecond, const std::string &Format) +{ + if (FramesPerSecond && Format.length() > 0) { + double Seconds = (Index + 0.5) / FramesPerSecond; + int Frame = int((Seconds - int(Seconds)) * FramesPerSecond) + 1; + return DurationType(int(Seconds), Format, Frame); + } + return int(Index); +} + +cxType DurationType(int Seconds, const std::string &Format, int Frame) { static char result[1000]; - if (Index > 0) { + if (Seconds >= 0) { if (Format.length() > 0) { uint update = 0; const char *ptr = Format.c_str(); char *res = result; enum { normal, format } state = normal; int n = 0; - int f = (Index % FRAMESPERSEC) + 1; - int s = (Index / FRAMESPERSEC); + int s = Seconds; int m = s / 60 % 60; int h = s / 3600; s %= 60; @@ -371,7 +354,8 @@ cxType DurationType(uint Index, const std::string &Format) break; case 'f': - n = snprintf(res, sizeof(result) - (res - result), "%d", f); + if (Frame) + n = snprintf(res, sizeof(result) - (res - result), "%02d", Frame); update = 1000; break; @@ -391,7 +375,7 @@ cxType DurationType(uint Index, const std::string &Format) r.SetUpdate(update); return r; } else - return (int)Index; + return Seconds; } return false; } @@ -11,9 +11,6 @@ #include <vdr/config.h> #include <vdr/epg.h> -// from recording.h (VDR <= 1.7.2) -#define FRAMESPERSEC 25 - #if defined(DEBUG) || defined(BENCH) # ifdef DEBUG # define Dprintf(x...) fprintf(stderr, x) @@ -58,11 +55,12 @@ bool GetFrontendHasLock(void); bool GetFrontendHasSignal(void); std::string AddExtInfoToDescription(const char *Title, const char *ShortText, const char *Description, const char *Aux = NULL, bool StripAux = false); int GetRecordingSize(const char *FileName); // [MB] -int GetRecordingLength(const char *FileName); // [min] -int GetRecordingCuttedLength(const char *FileName); // [min] +int GetRecordingLength(const char *FileName, double FramesPerSecond, bool IsPesRecording); // [min] +int GetRecordingCuttedLength(const char *FileName, double FramesPerSecond, bool IsPesRecording); // [min] cxType TimeType(time_t Time, const std::string &Format); -cxType DurationType(uint Index, const std::string &Format); +cxType DurationType(uint Index, double FramesPerSecond, const std::string &Format); +cxType DurationType(int Seconds, const std::string &Format, int Frame = 0); bool ParseVar(const char *Text, const char *Name, std::string &Value); bool ParseVar(const char *Text, const char *Name, tColor *Value); @@ -165,20 +165,20 @@ cxType cText2SkinDisplayChannel::GetTokenData(const txToken &Token) case tPresentProgress: return mPresent != NULL - ? (cxType)DurationType((time(NULL) - mPresent->StartTime()) * FRAMESPERSEC, + ? (cxType)DurationType(time(NULL) - mPresent->StartTime(), Token.Attrib.Text) : (cxType)false; case tPresentDuration: return mPresent != NULL - ? (cxType)DurationType(mPresent->Duration() * FRAMESPERSEC, Token.Attrib.Text) + ? (cxType)DurationType(mPresent->Duration(), Token.Attrib.Text) : (cxType)false; case tPresentRemaining: if (mPresent != NULL && time(NULL) - mPresent->StartTime() <= mPresent->Duration()) { - return (cxType)DurationType((mPresent->Duration() - (time(NULL) - mPresent->StartTime())) - * FRAMESPERSEC, Token.Attrib.Text); + return (cxType)DurationType(mPresent->Duration() - (time(NULL) - mPresent->StartTime()), + Token.Attrib.Text); } return false; @@ -214,7 +214,7 @@ cxType cText2SkinDisplayChannel::GetTokenData(const txToken &Token) case tFollowingDuration: return mFollowing != NULL - ? (cxType)DurationType(mFollowing->Duration() * FRAMESPERSEC, Token.Attrib.Text) + ? (cxType)DurationType(mFollowing->Duration(), Token.Attrib.Text) : (cxType)false; case tFollowingTitle: @@ -511,10 +511,14 @@ cxType cText2SkinDisplayReplay::GetTokenData(const txToken &Token) return mTitle; case tReplayPositionIndex: - return DurationType(mCurrent, Token.Attrib.Text); + return DurationType(mCurrent, + Text2SkinStatus.ReplayFramesPerSecond(), + Token.Attrib.Text); case tReplayDurationIndex: - return DurationType(mTotal, Token.Attrib.Text); + return DurationType(mTotal, + Text2SkinStatus.ReplayFramesPerSecond(), + Token.Attrib.Text); case tReplayPosition: return mPosition; @@ -523,7 +527,9 @@ cxType cText2SkinDisplayReplay::GetTokenData(const txToken &Token) return mDuration; case tReplayRemaining: - return DurationType(mTotal - mCurrent, Token.Attrib.Text); + return DurationType(mTotal - mCurrent, + Text2SkinStatus.ReplayFramesPerSecond(), + Token.Attrib.Text); case tReplayPrompt: return mPrompt; @@ -1060,19 +1066,19 @@ cxType cText2SkinDisplayMenu::GetTokenData(const txToken &Token) case tPresentProgress: return mEvent != NULL - ? (cxType)DurationType((time(NULL) - mEvent->StartTime()) * FRAMESPERSEC, + ? (cxType)DurationType(time(NULL) - mEvent->StartTime(), Token.Attrib.Text) : (cxType)false; case tPresentDuration: return mEvent != NULL - ? (cxType)DurationType(mEvent->Duration() * FRAMESPERSEC, Token.Attrib.Text) + ? (cxType)DurationType(mEvent->Duration(), Token.Attrib.Text) : (cxType)false; case tPresentRemaining: return mEvent != NULL - ? (cxType)DurationType((mEvent->Duration() - (time(NULL) - mEvent->StartTime())) - * FRAMESPERSEC, Token.Attrib.Text) + ? (cxType)DurationType(mEvent->Duration() - (time(NULL) - mEvent->StartTime()), + Token.Attrib.Text) : (cxType)false; case tPresentTitle: @@ -1330,12 +1336,20 @@ cxType cText2SkinDisplayMenu::GetTokenData(const txToken &Token) case tRecordingLength: return mRecording != NULL - ? (cxType)GetRecordingLength(mRecording->FileName()) +#if VDRVERSNUM >= 10703 + ? (cxType)GetRecordingLength(mRecording->FileName(), mRecording->FramesPerSecond(), mRecording->IsPesRecording()) +#else + ? (cxType)GetRecordingLength(mRecording->FileName(), FRAMESPERSEC, true) +#endif : (cxType)false; case tRecordingCuttedLength: return mRecording != NULL - ? (cxType)GetRecordingCuttedLength(mRecording->FileName()) +#if VDRVERSNUM >= 10703 + ? (cxType)GetRecordingCuttedLength(mRecording->FileName(), mRecording->FramesPerSecond(), mRecording->IsPesRecording()) +#else + ? (cxType)GetRecordingCuttedLength(mRecording->FileName(), FRAMESPERSEC, true) +#endif : (cxType)false; default: @@ -817,7 +817,7 @@ cxType cText2SkinRender::GetTokenData(const txToken &Token) VideoDiskSpace(&FreeMB); Dprintf("FreeMB: %d, attrib type is %d\n", FreeMB,Token.Attrib.Type); return Token.Attrib.Type == aString && Token.Attrib.Text.length() > 0 - ? (cxType)DurationType((int)(FreeMB * 60 * FRAMESPERSEC / MB_PER_MINUTE), + ? (cxType)DurationType(FreeMB * 60 / MB_PER_MINUTE, Token.Attrib.Text) : (cxType)FreeMB; } @@ -22,7 +22,8 @@ cText2SkinStatus::cText2SkinStatus(void): mRecordings(), mCurrentRecording(0), mNextRecording(0), - mLastLanguage(0) + mLastLanguage(0), + mReplayFramesPerSecond(0) { } @@ -84,6 +85,13 @@ void cText2SkinStatus::Replaying(const cControl* /*Control*/, const char *Name, mReplayIsShuffle = false; } +#if VDRVERSNUM >= 10703 + // Workaround: Control->FramesPerSecond() not possible because its not const + mReplayFramesPerSecond = mReplay != NULL ? mReplay->FramesPerSecond() : DEFAULTFRAMESPERSECOND; +#else + mReplayFramesPerSecond = FRAMESPERSEC; +#endif + if (mRender != NULL) { if (mReplayMode != oldMode) mRender->SetDirty(); @@ -71,6 +71,7 @@ private: uint mNextRecording; int mLastLanguage; int mTimerConflicts; + double mReplayFramesPerSecond; protected: virtual void Replaying(const cControl *Control, const char *Name, @@ -91,6 +92,8 @@ public: cxType GetTokenData(const txToken &Token); eReplayMode ReplayMode(void) const { return mReplayMode; } + + double ReplayFramesPerSecond(void) const { return mReplayFramesPerSecond; } }; extern cText2SkinStatus Text2SkinStatus; |