diff -Nru vdr-plugin-markad-ng-3.5.3/HISTORY vdr-plugin-markad-ng-3.6.0/HISTORY --- vdr-plugin-markad-ng-3.5.3/HISTORY 2024-04-16 07:00:03.000000000 +0000 +++ vdr-plugin-markad-ng-3.6.0/HISTORY 2024-04-20 11:58:26.000000000 +0000 @@ -1,6 +1,12 @@ VDR Plugin 'markad' Revision History ---------------------------------- +2024-04-20: Version 3.6.0 +- reduce build messages (thx to Mike838@www.vdr-portal.de) +- change minimum libavcodec version to 56.60.100 (FFmpeg 2.8.17) +- remove parameter 'ignore timer margins' +- some minor bug fixes and optimizations, see git + 2024-04-16: Version 3.5.3 - declare parameter 'ignore timer margins' as deprecated - fix crash in encoder at channel change diff -Nru vdr-plugin-markad-ng-3.5.3/INSTALL vdr-plugin-markad-ng-3.6.0/INSTALL --- vdr-plugin-markad-ng-3.5.3/INSTALL 2024-04-16 07:00:03.000000000 +0000 +++ vdr-plugin-markad-ng-3.6.0/INSTALL 2024-04-20 11:58:26.000000000 +0000 @@ -6,7 +6,7 @@ - git - pkgconf or pkg-config - vdr-dev (>= version 2.2) -- libavcodec-dev (>= 56.57.100 from FFmpeg 2.7.2) +- libavcodec-dev (>= 56.60.100 from FFmpeg 2.8.17) - libavformat-dev - libavfilter-dev - libswresample-dev diff -Nru vdr-plugin-markad-ng-3.5.3/command/Makefile vdr-plugin-markad-ng-3.6.0/command/Makefile --- vdr-plugin-markad-ng-3.5.3/command/Makefile 2024-04-16 07:00:03.000000000 +0000 +++ vdr-plugin-markad-ng-3.6.0/command/Makefile 2024-04-20 11:58:26.000000000 +0000 @@ -2,6 +2,13 @@ # Makefile for a Video Disk Recorder addon # +ifdef VERBOSE +Q = +else +Q = @ +endif +export Q + # use this, if you want to debug heap memory consumption # DEBUG_MEM_MARKAD=1 @@ -117,7 +124,8 @@ ### Implicit rules: %.o: %.cpp - $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $< + @echo CC $@ + $(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $< ### Dependencies: MAKEDEP = $(CXX) -MM -MG @@ -134,24 +142,29 @@ I18Npot = $(PODIR)/markad.pot %.mo: %.po - msgfmt -c -o $@ $< + @echo MO $@ + $(Q)msgfmt -c -o $@ $< $(I18Npot): $(wildcard *.cpp *.h) - xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --msgid-bugs-address='' -o $@ $^ + @echo GT $@ + $(Q)xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --msgid-bugs-address='' -o $@ $^ %.po: $(I18Npot) - msgmerge -U --no-wrap --no-location --backup=none -q $@ $< + @echo PO $@ + $(Q)msgmerge -U --no-wrap --no-location --backup=none -q $@ $< @touch $@ $(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/markad.mo: $(PODIR)/%.mo - install -D -m644 $< $@ + @echo IN $@ + $(Q)install -D -m644 $< $@ .PHONY: i18n i18n: $(I18Npot) ### Targets: markad: $(OBJS) - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ + @echo CC $@ + $(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ install-doc: diff -Nru vdr-plugin-markad-ng-3.5.3/command/criteria.cpp vdr-plugin-markad-ng-3.6.0/command/criteria.cpp --- vdr-plugin-markad-ng-3.5.3/command/criteria.cpp 2024-04-16 07:00:03.000000000 +0000 +++ vdr-plugin-markad-ng-3.6.0/command/criteria.cpp 2024-04-20 11:58:26.000000000 +0000 @@ -20,7 +20,6 @@ if (CompareChannelName(channelName, "Das_Erste", IGNORE_HD)) return true; if (CompareChannelName(channelName, "rbb", IGNORE_HD | IGNORE_CITY)) return true; - if (CompareChannelName(channelName, "tagesschau24", IGNORE_HD)) return true; if (CompareChannelName(channelName, "WDR", IGNORE_HD | IGNORE_CITY)) return true; if (CompareChannelName(channelName, "ZDF", IGNORE_HD)) return true; diff -Nru vdr-plugin-markad-ng-3.5.3/command/decoder.h vdr-plugin-markad-ng-3.6.0/command/decoder.h --- vdr-plugin-markad-ng-3.5.3/command/decoder.h 2024-04-16 07:00:03.000000000 +0000 +++ vdr-plugin-markad-ng-3.6.0/command/decoder.h 2024-04-20 11:58:26.000000000 +0000 @@ -50,14 +50,12 @@ // // #if LIBAVCODEC_VERSION_INT >= ((57<<16)+(107<<8)+100) ffmpeg 3.4.11 (Ubuntu 18.04, End of Life: April 2028) // #if LIBAVCODEC_VERSION_INT >= ((56<<16)+( 60<<8)+100) ffmpeg 2.8.17 (Ubuntu 16.04) End of Life: April 2026) -// #if LIBAVCODEC_VERSION_INT >= ((56<<16)+( 57<<8)+100) ffmpeg 2.7.2 (Ubuntu 14.04, End of Life: April 2024) -#define LIBAVCODEC_VERSION_DEPRECATED ((56<<16)+( 57<<8)+100) // oldest deprecated version, older is invalid +#define LIBAVCODEC_VERSION_DEPRECATED ((56<<16)+( 60<<8)+100) // oldest deprecated version, older is invalid // end of life markad ffmpeg versions (based on Ubuntu LTS has no support at all) // -// #if LIBAVCODEC_VERSION_INT >= ((56<<16)+( 26<<8)+100) ffmpeg 2 (Debian 8 Jessie) -// #if LIBAVCODEC_VERSION_INT >= ((56<<16)+( 1<<8)+ 0) ffmpeg 2.4 (Rasbian Jessie) +// #if LIBAVCODEC_VERSION_INT >= ((54<<16)+( 35<<8)+1) avconv 9.20 (Ubuntu 14.04, End of Life: April 2024) /** diff -Nru vdr-plugin-markad-ng-3.5.3/command/global.h vdr-plugin-markad-ng-3.6.0/command/global.h --- vdr-plugin-markad-ng-3.5.3/command/global.h 2024-04-16 07:00:03.000000000 +0000 +++ vdr-plugin-markad-ng-3.6.0/command/global.h 2024-04-20 11:58:26.000000000 +0000 @@ -147,9 +147,6 @@ //! int logoHeight; //!< height for logo extraction //!< - int ignoreInfo = 0; //!< true: ignore vdr info file
- //!< false: use data from vdr info file - //!< int threads; //!< number of threads for decoder and encoder //!< int astopoffs; //!< assumed stop offset in seconds diff -Nru vdr-plugin-markad-ng-3.5.3/command/markad-standalone.cpp vdr-plugin-markad-ng-3.6.0/command/markad-standalone.cpp --- vdr-plugin-markad-ng-3.5.3/command/markad-standalone.cpp 2024-04-16 07:00:03.000000000 +0000 +++ vdr-plugin-markad-ng-3.6.0/command/markad-standalone.cpp 2024-04-20 11:58:26.000000000 +0000 @@ -791,11 +791,13 @@ int logoStopSilenceStart = 1000 * (silenceStart->position - mark->position) / macontext.Video.Info.framesPerSecond; int silenceStartSilenceStop = 1000 * (silenceStop->position - silenceStart->position) / macontext.Video.Info.framesPerSecond; int silenceStopLogoStart = 1000 * (logoStartAfter->position - silenceStop->position) / macontext.Video.Info.framesPerSecond; - dsyslog("cMarkAdStandalone::HaveSilenceSeparator(): MT_LOGOSTART (%7d) -> %6ds -> MT_LOGOSTOP (%6d) -> %4dms -> MT_SOUNDSTOP (%6d) -> %4dms -> MT_SOUNDSTART (%6d) -> %5dms -> MT_LOGOSTART (%6d)", logoStartBefore->position, logoStartLogoStop, mark->position, logoStopSilenceStart, silenceStart->position, silenceStartSilenceStop, silenceStop->position, silenceStopLogoStart, logoStartAfter->position); + dsyslog("cMarkAdStandalone::HaveSilenceSeparator(): MT_LOGOSTART (%6d) -> %7ds -> MT_LOGOSTOP (%6d) -> %4dms -> MT_SOUNDSTOP (%6d) -> %4dms -> MT_SOUNDSTART (%6d) -> %5dms -> MT_LOGOSTART (%6d)", logoStartBefore->position, logoStartLogoStop, mark->position, logoStopSilenceStart, silenceStart->position, silenceStartSilenceStop, silenceStop->position, silenceStopLogoStart, logoStartAfter->position); // valid sequence // MT_LOGOSTOP ( 86346) -> 120ms -> MT_SOUNDSTOP ( 86349) -> 120ms -> MT_SOUNDSTART ( 86352) -> 4920ms -> MT_LOGOSTART ( 86475) // MT_LOGOSTOP ( 93602) -> 120ms -> MT_SOUNDSTOP ( 93605) -> 120ms -> MT_SOUNDSTART ( 93608) -> 40160ms -> MT_LOGOSTART ( 94612) -> VOXup // MT_LOGOSTART ( 16056) -> 1505140s -> MT_LOGOSTOP ( 91313) -> 140ms -> MT_SOUNDSTOP ( 91320) -> 180ms -> MT_SOUNDSTART ( 91329) -> 1920ms -> MT_LOGOSTART ( 91425) -> RTL Television +// MT_LOGOSTART ( 84526) -> 10400s -> MT_LOGOSTOP ( 84786) -> 160ms -> MT_SOUNDSTOP ( 84790) -> 80ms -> MT_SOUNDSTART ( 84792) -> 1920ms -> MT_LOGOSTART ( 84840) -> Pro7 MAXX +// MT_LOGOSTART ( 81870) -> 10400s -> MT_LOGOSTOP ( 82130) -> 0ms -> MT_SOUNDSTOP ( 82130) -> 320ms -> MT_SOUNDSTART ( 82138) -> 1840ms -> MT_LOGOSTART ( 82184) -> Pro7 MAXX // // invalid sequence // MT_LOGOSTOP ( 42715) -> 4840ms -> MT_SOUNDSTOP ( 42836) -> 360ms -> MT_SOUNDSTART ( 42845) -> 94760ms -> MT_LOGOSTART ( 45214) @@ -803,9 +805,9 @@ // MT_LOGOSTART ( 87985) -> 1400s -> MT_LOGOSTOP ( 88020) -> 4840ms -> MT_SOUNDSTOP ( 88141) -> 160ms -> MT_SOUNDSTART ( 88145) -> 8400ms -> MT_LOGOSTART ( 88355) -> DMAX // MT_LOGOSTART ( 82878) -> 81600s -> MT_LOGOSTOP ( 84918) -> 3880ms -> MT_SOUNDSTOP ( 85015) -> 120ms -> MT_SOUNDSTART ( 85018) -> 20120ms -> MT_LOGOSTART ( 85521) - if ((logoStartLogoStop > 1400) && - (logoStopSilenceStart <= 140) && - (silenceStartSilenceStop >= 120) && (silenceStartSilenceStop <= 180) && + if ((logoStartLogoStop >= 10400) && // possible end of info logo before + (logoStopSilenceStart <= 160) && // silence start short after end mark + (silenceStartSilenceStop >= 80) && (silenceStartSilenceStop <= 320) && (silenceStopLogoStart <= 40160)) { dsyslog("cMarkAdStandalone::HaveSilenceSeparator(): logo stop mark (%d): silence sequence is valid", mark->position); return true; @@ -904,7 +906,7 @@ } // check squence MT_LOGOSTOP -> MT_NOBLACKSTOP -> MT_NOBLACKSTART -> MT_LOGOSTART (mark) - blackStop = blackMarks.GetPrev(mark->position, MT_NOBLACKSTART); + blackStop = blackMarks.GetPrev(mark->position + 1, MT_NOBLACKSTART); if (blackStop) { // from above cMark *blackStart = blackMarks.GetPrev(blackStop->position, MT_NOBLACKSTOP); if (blackStart) { @@ -918,14 +920,17 @@ // MT_LOGOSTOP (6419)-> 40ms -> MT_NOBLACKSTOP (6420) -> 360ms -> MT_NOBLACKSTART (6429) -> 200ms -> MT_LOGOSTART (6434) // MT_LOGOSTOP (3536)-> 1680ms -> MT_NOBLACKSTOP (3578) -> 320ms -> MT_NOBLACKSTART (3586) -> 1800ms -> MT_LOGOSTART (3631) TELE 5, fade in logo // MT_LOGOSTOP (5887)-> 4880ms -> MT_NOBLACKSTOP (6009) -> 440ms -> MT_NOBLACKSTART (6020) -> 1040ms -> MT_LOGOSTART (6046) Kabel 1 Austria, separator picture before -// MT_LOGOSTOP (4860)-> 30040ms -> MT_NOBLACKSTOP (5611) -> 440ms -> MT_NOBLACKSTART (5622) -> 1040ms -> MT_LOGOSTART (5648) kabel eins, ad in frame without logo before +// MT_LOGOSTOP ( 7577)-> 7040ms -> MT_NOBLACKSTOP (7753) -> 40ms -> MT_NOBLACKSTART (7754) -> 0ms -> MT_LOGOSTART (7754) Comedy Central +// +// valid example (conflict) +// MT_LOGOSTOP (4860)-> 30040ms -> MT_NOBLACKSTOP (5611) -> 440ms -> MT_NOBLACKSTART (5622) -> 1040ms -> MT_LOGOSTART (5648) kabel eins, ad in frame without logo before (conflict) // MT_LOGOSTOP (5279)-> 124400ms -> MT_NOBLACKSTOP (8389) -> 40ms -> MT_NOBLACKSTART (8390) -> 2600ms -> MT_LOGOSTART (8455) Nickelodeon (conflict) // // invalid example // MT_LOGOSTOP ( 204)-> 28600ms -> MT_NOBLACKSTOP (1634) -> 40ms -> MT_NOBLACKSTART (1636) -> 1900ms -> MT_LOGOSTART (1731) // MT_LOGOSTOP ( 1032)-> 68600ms -> MT_NOBLACKSTOP (4462) -> 40ms -> MT_NOBLACKSTART (4464) -> 1820ms -> MT_LOGOSTART (4555) // MT_LOGOSTOP ( 4997)-> 25260ms -> MT_NOBLACKSTOP (6260) -> 60ms -> MT_NOBLACKSTART (6263) -> 1820ms -> MT_LOGOSTART (6354) - if ((diffLogoStopBlackStart < 30040) && (diffBlackStartBlackStop >= 320) && (diffBlackStopLogoStart <= 1800)) { + if ((diffLogoStopBlackStart <= 7040) && (diffBlackStartBlackStop >= 40) && (diffBlackStopLogoStart <= 1800)) { dsyslog("cMarkAdStandalone::HaveBlackSeparator(): black screen sequence is valid"); return true; } @@ -1060,11 +1065,15 @@ // channel without fade out logo // valid sequence: // MT_LOGOSTOP (81055) -> 0ms -> MT_NOBLACKSTOP (81055) -> 40ms -> MT_NOBLACKSTART (81056) -> 1680ms -> MT_LOGOSTART (81098) -> RTL2 +// MT_LOGOSTOP (84786) -> 120ms -> MT_NOBLACKSTOP (84789) -> 240ms -> MT_NOBLACKSTART (84795) -> 1800ms -> MT_LOGOSTART (84840) -> Pro7 MAXX +// MT_LOGOSTOP (86549) -> 80ms -> MT_NOBLACKSTOP (86551) -> 280ms -> MT_NOBLACKSTART (86558) -> 31800ms -> MT_LOGOSTART (87353) -> Pro7 MAXX +// MT_LOGOSTOP (82130) -> 80ms -> MT_NOBLACKSTOP (82132) -> 240ms -> MT_NOBLACKSTART (82138) -> 1840ms -> MT_LOGOSTART (82184) -> Pro7 MAXX +// MT_LOGOSTOP (78161) -> 80ms -> MT_NOBLACKSTOP (78163) -> 240ms -> MT_NOBLACKSTART (78169) -> 2800ms -> MT_LOGOSTART (78239) -> Pro7 MAXX // // invalid sequence: // MT_LOGOSTOP (81485) -> 4040ms -> MT_NOBLACKSTOP (81586) -> 160ms -> MT_NOBLACKSTART (81590) -> 95920ms -> MT_LOGOSTART (83988) -> RTLZWEI, sequence in preview if (!criteria.LogoFadeOut(macontext.Info.ChannelName) && - (diffLogoStopBlackStart < 4040) && (diffBlackStartBlackStop >= 40) && (diffBlackStopLogoStart <= 1680)) { + (diffLogoStopBlackStart <= 120) && (diffBlackStartBlackStop >= 40) && (diffBlackStopLogoStart <= 31800)) { dsyslog("cMarkAdStandalone::HaveBlackSeparator(): logo stop mark (%d): black screen sequence is valid", mark->position); return true; } @@ -1180,7 +1189,7 @@ LogSeparator(true); dsyslog("cMarkAdStandalone::CheckStop(): start check stop (%d)", frameCurrent); - char *indexToHMSF = marks.IndexToHMSF(iStopA); + char *indexToHMSF = marks.IndexToHMSF(iStopA, false); if (indexToHMSF) { ALLOC(strlen(indexToHMSF)+1, "indexToHMSF"); dsyslog("assumed stop position (%d) at %s", iStopA, indexToHMSF); @@ -1551,12 +1560,12 @@ free(indexToHMSFStart); } // get time of marks and log marks - indexToHMSFStop = marks.IndexToHMSF(stopPosition); + indexToHMSFStop = marks.IndexToHMSF(stopPosition, false); if (indexToHMSFStop) { ALLOC(strlen(indexToHMSFStop)+1, "indexToHMSF"); } - indexToHMSFStart = marks.IndexToHMSF(startPosition); + indexToHMSFStart = marks.IndexToHMSF(startPosition, false); if (indexToHMSFStart) { ALLOC(strlen(indexToHMSFStart)+1, "indexToHMSF"); } @@ -1746,7 +1755,7 @@ if (logoStart) { int diffLogoStart = (logoStart->position - iStartA) / macontext.Video.Info.framesPerSecond; dsyslog("cMarkAdStandalone::Check_CHANNELSTART(): found logo start mark (%d) %ds after assumed start", logoStart->position, diffLogoStart); - if ((diffLogoStart >= -1) && (diffLogoStart <= 1)) { + if ((diffLogoStart >= -1) && (diffLogoStart <= 17)) { // changed from 1 to 17 dsyslog("cMarkAdStandalone::Check_CHANNELSTART(): use logo start mark (%d) as start mark", logoStart->position); criteria.SetMarkTypeState(MT_CHANNELCHANGE, CRITERIA_USED); return logoStart; @@ -2114,7 +2123,9 @@ } else { // we have only start/stop vborder in start part, this is from broadcast before dsyslog("cMarkAdStandalone::Check_VBORDERSTART(): no vertical border start found after start (%d) and stop (%d)", vStart->position, vStop->position); - if ((vStart->position < IGNORE_AT_START) && (markDiff <= 140)) { // vbordet start/stop from previous broadcast + // example + // start vertical border at 0:01:04.80 -> stop vertical border at 0:06:25.92 (321s) is from broadcast before + if ((vStart->position < IGNORE_AT_START) || (markDiff <= 321)) { // vbordet start/stop from previous broadcast dsyslog("cMarkAdStandalone::Check_VBORDERSTART(): vertical border stop at (%d) %ds after vertical border start (%d) in start part found, this is from previous broadcast, delete marks", vStop->position, markDiff, vStart->position); criteria.SetMarkTypeState(MT_VBORDERCHANGE, CRITERIA_UNAVAILABLE); marks.Del(vStop); @@ -2214,7 +2225,7 @@ LogSeparator(true); dsyslog("cMarkAdStandalone::CheckStart(): checking start at frame (%d) check start planed at (%d)", frameCurrent, chkSTART); int maxStart = iStartA + (length * macontext.Video.Info.framesPerSecond / 2); // half of recording - char *indexToHMSFStart = marks.IndexToHMSF(iStartA); + char *indexToHMSFStart = marks.IndexToHMSF(iStartA, false); if (indexToHMSFStart) { ALLOC(strlen(indexToHMSFStart) + 1, "indexToHMSFStart"); dsyslog("cMarkAdStandalone::CheckStart(): assumed start frame %d at %s, max allowed start frame (%d)", iStartA, indexToHMSFStart, maxStart); @@ -3296,7 +3307,7 @@ char *comment = NULL; char *timeText = NULL; if (!isPause) { - char *indexToHMSF = marks.IndexToHMSF(vpsFrame); + char *indexToHMSF = marks.IndexToHMSF(vpsFrame, false); if (indexToHMSF) { ALLOC(strlen(indexToHMSF)+1, "indexToHMSF"); } @@ -3306,7 +3317,7 @@ mark = ((type == MT_START)) ? marks.GetNext(0, MT_START, 0x0F) : marks.GetPrev(INT_MAX, MT_STOP, 0x0F); } else { - char *indexToHMSF = marks.IndexToHMSF(vpsFrame); + char *indexToHMSF = marks.IndexToHMSF(vpsFrame, false); if (indexToHMSF) { ALLOC(strlen(indexToHMSF)+1, "indexToHMSF"); } @@ -3565,7 +3576,7 @@ sceneMarks.Add(mark->type, MT_UNDEFINED, MT_UNDEFINED, mark->position, NULL, inBroadCast); if (comment) { #ifdef DEBUG_WEAK_MARKS - char *indexToHMSF = marks.IndexToHMSF(mark->position); + char *indexToHMSF = marks.IndexToHMSF(mark->position, false); if (indexToHMSF) { ALLOC(strlen(indexToHMSF)+1, "indexToHMSF"); if (indexToHMSF) { @@ -3582,7 +3593,7 @@ case MT_SOUNDCHANGE: silenceMarks.Add(mark->type, MT_UNDEFINED, MT_UNDEFINED, mark->position, NULL, inBroadCast); if (comment) { - char *indexToHMSF = marks.IndexToHMSF(mark->position); + char *indexToHMSF = marks.IndexToHMSF(mark->position, false); if (indexToHMSF) { ALLOC(strlen(indexToHMSF)+1, "indexToHMSF"); dsyslog("cMarkAdStandalone::AddMark(): %s at %s", comment, indexToHMSF); @@ -3597,7 +3608,7 @@ case MT_BLACKCHANGE: blackMarks.Add(mark->type, MT_UNDEFINED, MT_UNDEFINED, mark->position, NULL, inBroadCast); if (comment) { - char *indexToHMSF = marks.IndexToHMSF(mark->position); + char *indexToHMSF = marks.IndexToHMSF(mark->position, false); if (indexToHMSF) { ALLOC(strlen(indexToHMSF)+1, "indexToHMSF"); dsyslog("cMarkAdStandalone::AddMark(): %s at %s", comment, indexToHMSF); @@ -3619,7 +3630,7 @@ if (mark->type == MT_RECORDINGSTART) { if (asprintf(&indexToHMSF, "00:00:00.00") == -1) esyslog("cMarkAdStandalone::AddMark(): asprintf failed"); // we have no index to get time for position 0 } - else indexToHMSF = marks.IndexToHMSF(mark->position); + else indexToHMSF = marks.IndexToHMSF(mark->position, false); if (indexToHMSF) { ALLOC(strlen(indexToHMSF)+1, "indexToHMSF"); if (comment) isyslog("%s at %s", comment, indexToHMSF); @@ -3832,7 +3843,7 @@ } // seek to start frame of overlap check - char *indexToHMSF = marks.IndexToHMSF(fRangeBegin); + char *indexToHMSF = marks.IndexToHMSF(fRangeBegin, false); if (indexToHMSF) { ALLOC(strlen(indexToHMSF)+1, "indexToHMSF"); dsyslog("cMarkAdStandalone::ProcessMarkOverlap(): start check %ds before start mark (%d) from frame (%d) at %s", OVERLAP_CHECK_BEFORE, (*mark1)->position, fRangeBegin, indexToHMSF); @@ -3893,7 +3904,7 @@ return false; } if (fRangeBegin < ptr_cDecoder->GetFrameNumber()) fRangeBegin = ptr_cDecoder->GetFrameNumber(); // on very short stop/start pairs we have no room to go before start mark - indexToHMSF = marks.IndexToHMSF(fRangeBegin); + indexToHMSF = marks.IndexToHMSF(fRangeBegin, false); if (indexToHMSF) { ALLOC(strlen(indexToHMSF)+1, "indexToHMSF"); dsyslog("cMarkAdStandalone::ProcessMarkOverlap(): seek forward to frame (%d) at %s before start mark (%d) and start overlap check", fRangeBegin, indexToHMSF, (*mark2)->position); @@ -3940,22 +3951,22 @@ int lengthBefore = 1000 * (overlapPos.similarBeforeEnd - overlapPos.similarBeforeStart + 1) / macontext.Video.Info.framesPerSecond; // include first and last int lengthAfter = 1000 * (overlapPos.similarAfterEnd - overlapPos.similarAfterStart + 1) / macontext.Video.Info.framesPerSecond; - char *indexToHMSFbeforeStart = marks.IndexToHMSF(overlapPos.similarBeforeStart); + char *indexToHMSFbeforeStart = marks.IndexToHMSF(overlapPos.similarBeforeStart, false); if (indexToHMSFbeforeStart) { ALLOC(strlen(indexToHMSFbeforeStart)+1, "indexToHMSFbeforeStart"); } - char *indexToHMSFbeforeEnd = marks.IndexToHMSF(overlapPos.similarBeforeEnd); + char *indexToHMSFbeforeEnd = marks.IndexToHMSF(overlapPos.similarBeforeEnd, false); if (indexToHMSFbeforeEnd) { ALLOC(strlen(indexToHMSFbeforeEnd)+1, "indexToHMSFbeforeEnd"); } - char *indexToHMSFafterStart = marks.IndexToHMSF(overlapPos.similarAfterStart); + char *indexToHMSFafterStart = marks.IndexToHMSF(overlapPos.similarAfterStart, false); if (indexToHMSFafterStart) { ALLOC(strlen(indexToHMSFafterStart)+1, "indexToHMSFafterStart"); } - char *indexToHMSFafterEnd = marks.IndexToHMSF(overlapPos.similarAfterEnd); + char *indexToHMSFafterEnd = marks.IndexToHMSF(overlapPos.similarAfterEnd, false); if (indexToHMSFafterEnd) { ALLOC(strlen(indexToHMSFafterEnd)+1, "indexToHMSFafterEnd"); } @@ -4274,7 +4285,7 @@ int searchStartPosition = markLogo->position - (30 * macontext.Video.Info.framesPerSecond); // introduction logos are usually 10s, somettimes longer, changed from 12 to 30 if (searchStartPosition < 0) searchStartPosition = 0; - char *indexToHMSFSearchStart = marks.IndexToHMSF(searchStartPosition); + char *indexToHMSFSearchStart = marks.IndexToHMSF(searchStartPosition, false); if (indexToHMSFSearchStart) { ALLOC(strlen(indexToHMSFSearchStart)+1, "indexToHMSFSearchStart"); } @@ -4298,7 +4309,7 @@ // check longer range to prevent to detect text as second logo // changed from 35 to 60 - char *indexToHMSFSearchEnd = marks.IndexToHMSF(searchEndPosition); + char *indexToHMSFSearchEnd = marks.IndexToHMSF(searchEndPosition, false); if (indexToHMSFSearchEnd) { ALLOC(strlen(indexToHMSFSearchEnd)+1, "indexToHMSFSearchEnd"); } @@ -4354,7 +4365,7 @@ int searchStartPosition = markLogo->position - (45 * macontext.Video.Info.framesPerSecond); // advertising in frame are usually 30s, changed from 35 to 45 // sometimes there is a closing credit in frame with logo before const char *indexToHMSFStopMark = marks.GetTime(markLogo); - char *indexToHMSFSearchPosition = marks.IndexToHMSF(searchStartPosition); + char *indexToHMSFSearchPosition = marks.IndexToHMSF(searchStartPosition, false); if (indexToHMSFSearchPosition) { ALLOC(strlen(indexToHMSFSearchPosition)+1, "indexToHMSF"); } @@ -4463,7 +4474,7 @@ if ((diffBefore >= 2020) && (diffBefore <= 3020) && (diffAfter <= 40)) diffBefore = INT_MAX; if (silenceBefore && criteria.LogoFadeOut(macontext.Info.ChannelName) && (lengthBefore >= 160)) maxBefore = 6840; - else maxBefore = 4299; + else maxBefore = 3999; break; case MT_CHANNELSTART: maxBefore = 1240; @@ -5087,16 +5098,12 @@ cMark *soundStopBefore = silenceMarks.GetPrev(soundStartBefore->position, MT_SOUNDSTOP); if (soundStopBefore) { lengthBefore = 1000 * (soundStartBefore->position - soundStopBefore->position) / macontext.Video.Info.framesPerSecond; - dsyslog("cMarkAdStandalone::SilenceOptimization(): start mark (%6d): silence from (%5d) to (%5d) %8dms before, length %4dms", mark->position, soundStopBefore->position, soundStartBefore->position, diffBefore, lengthBefore); - } - cMark *lowerStart = blackMarks.GetPrev(soundStartBefore->position, MT_NOLOWERBORDERSTOP); - if (lowerStart) { - cMark *lowerStop = blackMarks.GetNext(lowerStart->position, MT_NOLOWERBORDERSTART); - if (lowerStop) { - int diffBlackLowerBefore = 1000 * (soundStartBefore->position - lowerStop->position) / macontext.Video.Info.framesPerSecond; - dsyslog("cMarkAdStandalone::SilenceOptimization(): start mark (%6d): lower border before start (%d) end (%d), %dms before", mark->position, lowerStart->position, lowerStop->position, diffBlackLowerBefore); - if (diffBlackLowerBefore <= 80) lowerBefore = true; - } + bool blackBefore = false; + const cMark *black = blackMarks.GetAround(macontext.Video.Info.framesPerSecond, soundStopBefore->position, MT_BLACKCHANGE, 0xF0); + if (black) blackBefore = true; + const cMark *lower = blackMarks.GetAround(macontext.Video.Info.framesPerSecond, soundStopBefore->position, MT_LOWERBORDERCHANGE, 0xF0); + if (lower) blackBefore = true; + dsyslog("cMarkAdStandalone::SilenceOptimization(): start mark (%6d): silence from (%5d) to (%5d) %8dms before, length %4dms, black %d, lower %d", mark->position, soundStopBefore->position, soundStartBefore->position, diffBefore, lengthBefore, blackBefore, lowerBefore); } } if (soundStartAfter) { @@ -5104,7 +5111,13 @@ cMark *soundStopAfter = silenceMarks.GetPrev(soundStartAfter->position, MT_SOUNDSTOP); if (soundStopAfter) { lengthAfter = 1000 * (soundStartAfter->position - soundStopAfter->position) / macontext.Video.Info.framesPerSecond; - dsyslog("cMarkAdStandalone::SilenceOptimization(): start mark (%6d): silence from (%5d) to (%5d) %8dms after, length %4dms", mark->position, soundStopAfter->position, soundStartAfter->position, diffAfter, lengthAfter); + bool blackAfter = false; + const cMark *black = blackMarks.GetAround(macontext.Video.Info.framesPerSecond, soundStopAfter->position, MT_BLACKCHANGE, 0xF0); + if (black) blackAfter = true; + bool lowerAfter = false; + const cMark *lower = blackMarks.GetAround(macontext.Video.Info.framesPerSecond, soundStopAfter->position, MT_LOWERBORDERCHANGE, 0xF0); + if (lower) blackAfter = true; + dsyslog("cMarkAdStandalone::SilenceOptimization(): start mark (%6d): silence from (%5d) to (%5d) %8dms after, length %4dms, black %d, lower %d", mark->position, soundStopAfter->position, soundStartAfter->position, diffAfter, lengthAfter, blackAfter, lowerAfter); } } // try silence before start position @@ -5120,7 +5133,9 @@ case MT_LOGOSTART: if ((diffBefore >= 600) && (diffAfter <= 360)) diffBefore = INT_MAX; if ((diffBefore >= 2040) && (diffAfter <= 3460)) diffBefore = INT_MAX; - maxBefore = 4520; + + if (criteria.LogoFadeOut(macontext.Info.ChannelName)) maxBefore = 7340; + else maxBefore = 3999; break; case MT_MOVEDSTART: switch (mark->newType) { @@ -5213,6 +5228,7 @@ // log available marks bool moved = false; long int diffBefore = INT_MAX; + int lengthBefore = 0; int lengthAfter = 0; int diffAfter = INT_MAX; bool lowerBefore = false; @@ -5224,7 +5240,7 @@ diffBefore = 1000 * (mark->position - soundStopBefore->position) / macontext.Video.Info.framesPerSecond; soundStartBefore = silenceMarks.GetNext(soundStopBefore->position, MT_SOUNDSTART); if (soundStartBefore) { - int lengthBefore = 1000 * (soundStartBefore->position - soundStopBefore->position) / macontext.Video.Info.framesPerSecond; + lengthBefore = 1000 * (soundStartBefore->position - soundStopBefore->position) / macontext.Video.Info.framesPerSecond; dsyslog("cMarkAdStandalone::SilenceOptimization(): stop mark (%6d): silence from (%5d) to (%5d) %8ldms before, length %4dms", mark->position, soundStopBefore->position, soundStartBefore->position, diffBefore, lengthBefore); } // check lower border for silence before @@ -5271,6 +5287,9 @@ // rule 2: silence short before and far after else if ((diffBefore <= 5480) && (diffAfter >= 20600)) diffAfter = INT_MAX; + // rule 3: very long silence before, short silence after + else if ((diffBefore <= 31960) && (lengthBefore >= 3160) && (lengthAfter <= 340)) diffAfter = INT_MAX; + if (criteria.GoodVPS(macontext.Info.ChannelName)) maxAfter = 31479; else if ((lengthAfter > 160) && (lengthAfter <= 440)) maxAfter = 335480; // typical silene at broadcast end else if (lengthAfter >= 3000) maxAfter = 81920; // very long silence @@ -5322,8 +5341,8 @@ case MT_MOVEDSTOP: switch (mark->newType) { case MT_VPSSTOP: - if (lowerBefore) maxBefore = 57280; // lower border around sound stop - else maxBefore = 28279; // silence in broadcast 28280ms before VPS stop + if (lowerBefore) maxBefore = 57280; + else maxBefore = 31960; break; case MT_TYPECHANGESTOP: maxBefore = 6200; // changed from 5600 to 6200 @@ -5363,7 +5382,7 @@ mark = mark->Next(); } - // save marks +// save marks if (save) marks.Save(directory, &macontext, false); } @@ -5434,7 +5453,7 @@ if ((diffBefore >= 2160) && (diffAfter <= 320)) diffBefore = INT_MAX; // rule 2: long scene after VPS start, long static scene or closing credits from end of previous broadcast - else if ((diffBefore >= 40) && (diffBefore <= 2720) && (diffAfter > 1320) && (diffAfter <= 13440)) diffBefore = INT_MAX; + else if ((diffBefore >= 580) && (diffBefore <= 2720) && (diffAfter > 1320) && (diffAfter <= 13440)) diffBefore = INT_MAX; maxBefore = 2820; // changd from 580 to 2820 break; @@ -5586,8 +5605,8 @@ maxAfter = 2520; break; case MT_SOUNDSTOP: - // rule 1: silence end is short after last scene - if ((diffBefore <= 120) && (diffAfter >= 1600)) diffAfter = INT_MAX; + // rule 1: silence end is around last scene + if ((diffBefore <= 280) && (diffAfter >= 980)) diffAfter = INT_MAX; // rule 2: long static scene before sound stop is separator picture else if ((diffBefore >= 4360) && (diffBefore <= 5080) && (diffAfter >= 280) && (diffAfter <= 2120)) diffAfter = INT_MAX; @@ -6351,67 +6370,64 @@ macontext.Info.timerVPS = IsVPSTimer(); if ((length) && (startTime)) { - if (!bIgnoreTimerInfo) { - time_t rStart = GetRecordingStart(startTime, fileno(f)); - if (rStart) { - dsyslog("cMarkAdStandalone::LoadInfo(): recording start at %s", strtok(ctime(&rStart), "\n")); - dsyslog("cMarkAdStandalone::LoadInfo(): timer start at %s", strtok(ctime(&startTime), "\n")); - - // try VPS start event from markad.vps - macontext.Info.tStart = vps->GetStart(); // VPS start mark - if (macontext.Info.tStart >= 0) { - dsyslog("cMarkAdStandalone::LoadInfo(): VPS start event at offset: %5ds -> %d:%02d:%02dh", macontext.Info.tStart, macontext.Info.tStart / 3600, (macontext.Info.tStart % 3600) / 60, macontext.Info.tStart % 60); - int vpsStop = vps->GetStop(); - if (vpsStop > macontext.Info.tStart) { - dsyslog("cMarkAdStandalone::LoadInfo(): VPS stop event at offset: %5ds -> %d:%02d:%02dh", vpsStop, vpsStop / 3600, (vpsStop % 3600) / 60, vpsStop % 60); - dsyslog("cMarkAdStandalone::LoadInfo(): broadcast length from vdr info file: %5ds -> %d:%02d:%02dh", length, length / 3600, (length % 3600) / 60, length % 60); - int lengthVPS = vpsStop - macontext.Info.tStart; - int diff = lengthVPS - length; - dsyslog("cMarkAdStandalone::LoadInfo(): broadcast length from VPS events: %5ds -> %d:%02d:%02dh, %ds longer than length from vdr info file", lengthVPS, lengthVPS / 3600, (lengthVPS % 3600) / 60, length % 60, diff); - // changed from 506 to 298 - // changed from -570 to -620 - if ((diff >= 298) || (diff < -620)) { - dsyslog("cMarkAdStandalone::LoadInfo(): VPS stop event seems to be invalid, use length from vdr info file"); - vps->SetStop(-1); // set VPS stop event to invalid - } - else { - dsyslog("cMarkAdStandalone::LoadInfo(): VPS events seems to be valid, use length from VPS events"); - length = lengthVPS; - } + time_t rStart = GetRecordingStart(startTime, fileno(f)); + if (rStart) { + dsyslog("cMarkAdStandalone::LoadInfo(): recording start at %s", strtok(ctime(&rStart), "\n")); + dsyslog("cMarkAdStandalone::LoadInfo(): timer start at %s", strtok(ctime(&startTime), "\n")); + + // try VPS start event from markad.vps + macontext.Info.tStart = vps->GetStart(); // VPS start mark + if (macontext.Info.tStart >= 0) { + dsyslog("cMarkAdStandalone::LoadInfo(): VPS start event at offset: %5ds -> %d:%02d:%02dh", macontext.Info.tStart, macontext.Info.tStart / 3600, (macontext.Info.tStart % 3600) / 60, macontext.Info.tStart % 60); + int vpsStop = vps->GetStop(); + if (vpsStop > macontext.Info.tStart) { + dsyslog("cMarkAdStandalone::LoadInfo(): VPS stop event at offset: %5ds -> %d:%02d:%02dh", vpsStop, vpsStop / 3600, (vpsStop % 3600) / 60, vpsStop % 60); + dsyslog("cMarkAdStandalone::LoadInfo(): broadcast length from vdr info file: %5ds -> %d:%02d:%02dh", length, length / 3600, (length % 3600) / 60, length % 60); + int lengthVPS = vpsStop - macontext.Info.tStart; + int diff = lengthVPS - length; + dsyslog("cMarkAdStandalone::LoadInfo(): broadcast length from VPS events: %5ds -> %d:%02d:%02dh, %ds longer than length from vdr info file", lengthVPS, lengthVPS / 3600, (lengthVPS % 3600) / 60, length % 60, diff); + // invalid examples: + // -615 (accepted invalid VPS sequence, false stop, running after) + // changed from 506 to 298 + // changed from -620 to 615 + if ((diff >= 298) || (diff <= -615)) { + dsyslog("cMarkAdStandalone::LoadInfo(): VPS stop event seems to be invalid, use length from vdr info file"); + vps->SetStop(-1); // set VPS stop event to invalid } - } - if (macontext.Info.timerVPS) { // VPS controlled recording start, we guess assume broascast start 45s after recording start - isyslog("VPS controlled recording start"); - if (macontext.Info.tStart < 0) { - dsyslog("cMarkAdStandalone::LoadInfo(): no VPS start event found"); - macontext.Info.tStart = 45; + else { + dsyslog("cMarkAdStandalone::LoadInfo(): VPS events seems to be valid, use length from VPS events"); + length = lengthVPS; } } + } + if (macontext.Info.timerVPS) { // VPS controlled recording start, we guess assume broascast start 45s after recording start + isyslog("VPS controlled recording start"); + if (macontext.Info.tStart < 0) { + dsyslog("cMarkAdStandalone::LoadInfo(): no VPS start event found"); + macontext.Info.tStart = 45; + } + } - // try to get broadcast start offset from file infos + // try to get broadcast start offset from file infos + if (macontext.Info.tStart < 0) { + macontext.Info.tStart = static_cast (startTime - rStart); + if (macontext.Info.tStart > 60 * 60) { // more than 1h pre-timer make no sense, there must be a wrong directory time + isyslog("pre-time %is not valid, possible wrong directory time, set pre-timer to vdr default (2min)", macontext.Info.tStart); + macontext.Info.tStart = 120; + } if (macontext.Info.tStart < 0) { - macontext.Info.tStart = static_cast (startTime - rStart); - if (macontext.Info.tStart > 60 * 60) { // more than 1h pre-timer make no sense, there must be a wrong directory time - isyslog("pre-time %is not valid, possible wrong directory time, set pre-timer to vdr default (2min)", macontext.Info.tStart); - macontext.Info.tStart = 120; + if (length + macontext.Info.tStart > 0) { + startTime = rStart; + isyslog("missed broadcast start by %02d:%02d min, event length %5ds", -macontext.Info.tStart / 60, -macontext.Info.tStart % 60, length); + length += macontext.Info.tStart; + isyslog(" corrected length %5ds", length); } - if (macontext.Info.tStart < 0) { - if (length + macontext.Info.tStart > 0) { - startTime = rStart; - isyslog("missed broadcast start by %02d:%02d min, event length %5ds", -macontext.Info.tStart / 60, -macontext.Info.tStart % 60, length); - length += macontext.Info.tStart; - isyslog(" corrected length %5ds", length); - } - else { - isyslog("cannot determine broadcast start, assume VDR default pre timer of 120s"); - macontext.Info.tStart = 120; - } + else { + isyslog("cannot determine broadcast start, assume VDR default pre timer of 120s"); + macontext.Info.tStart = 120; } } } - else { - macontext.Info.tStart = 0; - } } else { macontext.Info.tStart = 0; @@ -6548,14 +6564,6 @@ macontext.Info.tStart = iStart = iStop = iStopA = 0; - if (config->ignoreInfo != 0) esyslog("parameter ignoreinfo is deprecated and will be removed in next version"); - if ((config->ignoreInfo & IGNORE_TIMERINFO) == IGNORE_TIMERINFO) { - bIgnoreTimerInfo = true; - } - else { - bIgnoreTimerInfo = false; - } - if (!config->noPid) { CreatePidfile(); if (abortNow) return; @@ -6620,9 +6628,6 @@ dsyslog("libavcodec config: %s",avcodec_configuration()); isyslog("on %s", directory); - if (bIgnoreTimerInfo) { - isyslog("timer info usage disabled by user"); - } if (config->before) sleep(10); char *tmpDir = strdup(directory); @@ -6647,7 +6652,6 @@ } if (strstr(recName, "/@")) { isyslog("live-recording, disabling pre-/post timer"); - bIgnoreTimerInfo = true; bLiveRecording = true; } else { @@ -6674,7 +6678,7 @@ ALLOC(sizeof(*vps), "vps"); if (!LoadInfo()) { - esyslog("failed loading info - logo %s%sdisabled", (config->logoExtraction != -1) ? "extraction" : "detection", bIgnoreTimerInfo ? " " : " and pre-/post-timer "); + esyslog("failed loading VDR info file"); macontext.Info.tStart = iStart = iStop = iStopA = 0; criteria.SetDetectionState(MT_LOGOCHANGE, false); } @@ -6740,6 +6744,8 @@ if (adQuote > 37) esyslog("advertisement quote: %d%% very high, marks can be wrong", adQuote); // changed from 34 to 37 else dsyslog("advertisement quote: %d%%", adQuote); } + // log match of VPS events + vps->LogMatch(macontext.Info.ChannelName, &marks); dsyslog("processing statistics: ----------------------------------------------------------------------"); time_t sec = endTime1.tv_sec - startTime1.tv_sec; @@ -6881,9 +6887,6 @@ "-d --disable=