From 8ffbea3788d8c4cc1a83fbb8f3aae7f253cbaeef Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 22 Nov 2009 11:30:27 +0100 Subject: [PATCH] Fixed generating the index for recordings from channels that put a whole GOP into one payload unit; regenerating index file --- HISTORY | 10 +- po/ca_ES.po | 8 +- po/cs_CZ.po | 8 +- po/da_DK.po | 8 +- po/de_DE.po | 8 +- po/el_GR.po | 8 +- po/es_ES.po | 8 +- po/et_EE.po | 8 +- po/fi_FI.po | 8 +- po/fr_FR.po | 8 +- po/hr_HR.po | 8 +- po/hu_HU.po | 8 +- po/it_IT.po | 8 +- po/lt_LT.po | 8 +- po/nl_NL.po | 8 +- po/nn_NO.po | 8 +- po/pl_PL.po | 8 +- po/pt_PT.po | 8 +- po/ro_RO.po | 8 +- po/ru_RU.po | 8 +- po/sk_SK.po | 9 +- po/sl_SI.po | 8 +- po/sv_SE.po | 8 +- po/tr_TR.po | 8 +- po/uk_UA.po | 8 +- po/zh_CN.po | 8 +- recorder.c | 4 +- recording.c | 150 ++++++++++++++++++++++++- recording.h | 5 +- remux.c | 310 ++++++++++++++++++++++++++++----------------------- remux.h | 20 +++- ringbuffer.c | 45 +++++++- ringbuffer.h | 4 +- 33 files changed, 570 insertions(+), 179 deletions(-) diff --git a/HISTORY b/HISTORY index 633d3d35..699112a3 100644 --- a/HISTORY +++ b/HISTORY @@ -6157,7 +6157,7 @@ Video Disk Recorder Revision History Reinhard Nissl). - Implemented full handling of subtitling descriptors (thanks to Mikko Tuumanen). -2009-11-15: Version 1.7.10 +2009-11-22: Version 1.7.10 - Updated the Italian OSD texts (thanks to Diego Pierotto). - Fixed wrong bracketing in cChannel::SubtitlingType() etc. @@ -6180,3 +6180,11 @@ Video Disk Recorder Revision History - Fixed EntriesOnSameFileSystem() to avoid using f_fsid, which may be 0 (thanks to Frank Schmirler). - Fixed starting a recording at an I-frame. +- Fixed generating the index for recordings from channels that put a whole + GOP into one payload unit. +- The index file for TS recordings is now regenerated on-the-fly if a + recording is replayed that has no index. This can also be used to + re-create a broken index file by manually deleting the index file and then + replaying the recording (at least until the index file has been generated). +- The cRingBufferLinear::Read() function now returns -1 and sets errno to + EAGAIN if the buffer is already full. diff --git a/po/ca_ES.po b/po/ca_ES.po index b26e23e1..8915752e 100644 --- a/po/ca_ES.po +++ b/po/ca_ES.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2008-03-02 19:02+0100\n" "Last-Translator: Luca Olivetti \n" "Language-Team: Catalanian\n" @@ -927,6 +927,12 @@ msgstr "Canal bloquejat (gravant)!" msgid "Low disk space!" msgstr "Disc gaireb ple!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "No puc apagar, falta la opci -s !" diff --git a/po/cs_CZ.po b/po/cs_CZ.po index 054cd2b4..b32c293e 100644 --- a/po/cs_CZ.po +++ b/po/cs_CZ.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2008-02-28 15:00+0200\n" "Last-Translator: Vladimr Brta , Ji Dobr \n" "Language-Team: Czech\n" @@ -925,6 +925,12 @@ msgstr "Kan msgid "Low disk space!" msgstr "Disk bude brzy zaplnn!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Vypnut nen mon - chyb volba '-s'!" diff --git a/po/da_DK.po b/po/da_DK.po index 7c1a1d79..5bcf7769 100644 --- a/po/da_DK.po +++ b/po/da_DK.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2007-08-12 14:17+0200\n" "Last-Translator: Mogens Elneff \n" "Language-Team: Danish\n" @@ -924,6 +924,12 @@ msgstr "Kanal blokeret (optagelse i gang)" msgid "Low disk space!" msgstr "Kun lidt diskplads tilbage!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Kan ikke slukke - parameter '-s' ikke angivet!" diff --git a/po/de_DE.po b/po/de_DE.po index 67ecae2b..c6c875dd 100644 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2007-11-25 15:19+0200\n" "Last-Translator: Klaus Schmidinger \n" "Language-Team: German\n" @@ -924,6 +924,12 @@ msgstr "Kanal blockiert (zeichnet auf)!" msgid "Low disk space!" msgstr "Platte beinahe voll!" +msgid "Regenerating index file" +msgstr "Index-Datei wird regeneriert" + +msgid "Index file regeneration complete" +msgstr "Regenerierung der Index-Datei abgeschlossen" + msgid "Can't shutdown - option '-s' not given!" msgstr "Ausschalten unmglich - Option '-s' fehlt!" diff --git a/po/el_GR.po b/po/el_GR.po index b9b59eae..c89b6897 100644 --- a/po/el_GR.po +++ b/po/el_GR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2007-08-12 14:17+0200\n" "Last-Translator: Dimitrios Dimitrakos \n" "Language-Team: Greek\n" @@ -924,6 +924,12 @@ msgstr " msgid "Low disk space!" msgstr " !" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr " . '-s'!" diff --git a/po/es_ES.po b/po/es_ES.po index f3f515a0..6cc9cee6 100644 --- a/po/es_ES.po +++ b/po/es_ES.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2008-03-02 19:02+0100\n" "Last-Translator: Luca Olivetti \n" "Language-Team: Spanish\n" @@ -925,6 +925,12 @@ msgstr " msgid "Low disk space!" msgstr "Poco espacio en disco!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "No se puede apagar - falta el parmetro '-s'!" diff --git a/po/et_EE.po b/po/et_EE.po index 220857df..2823c742 100644 --- a/po/et_EE.po +++ b/po/et_EE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2007-08-12 14:17+0200\n" "Last-Translator: Arthur Konovalov \n" "Language-Team: Estonian\n" @@ -924,6 +924,12 @@ msgstr "Kanal lukus (salvestamine aktiivne)!" msgid "Low disk space!" msgstr "Kvaketas tis!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Vljallitamine ebannestus - '-s' parameeter puudub!" diff --git a/po/fi_FI.po b/po/fi_FI.po index a51580cc..9718e53f 100644 --- a/po/fi_FI.po +++ b/po/fi_FI.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2007-08-15 15:52+0200\n" "Last-Translator: Rolf Ahrenberg \n" "Language-Team: Finnish\n" @@ -927,6 +927,12 @@ msgstr "Kanava lukittu (tallennus k msgid "Low disk space!" msgstr "Tallennustila loppumassa!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Sammutus ei onnistu - '-s' parametri puuttuu!" diff --git a/po/fr_FR.po b/po/fr_FR.po index 0877c449..8f6778a6 100644 --- a/po/fr_FR.po +++ b/po/fr_FR.po @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2008-02-27 18:14+0100\n" "Last-Translator: Jean-Claude Repetto \n" "Language-Team: French\n" @@ -930,6 +930,12 @@ msgstr "Cha msgid "Low disk space!" msgstr "Disque presque plein !" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Arrt impossible - option '-s' absente !" diff --git a/po/hr_HR.po b/po/hr_HR.po index fffe8085..32976b85 100644 --- a/po/hr_HR.po +++ b/po/hr_HR.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2008-03-17 19:00+0100\n" "Last-Translator: Adrian Caval \n" "Language-Team: Croatian\n" @@ -926,6 +926,12 @@ msgstr "Program zaklju msgid "Low disk space!" msgstr "Malo prostora na disku!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Gaenje nemogue - nedostaje opcija '-s'!" diff --git a/po/hu_HU.po b/po/hu_HU.po index 4945d7f0..e3d2b70d 100644 --- a/po/hu_HU.po +++ b/po/hu_HU.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2007-12-01 21:42+0200\n" "Last-Translator: Istvn Fley \n" "Language-Team: Hungarian\n" @@ -927,6 +927,12 @@ msgstr "Az ad msgid "Low disk space!" msgstr "A merev lemez majdnem tele!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "A lellts nem lehetsges - Opci '-s' hinyzik!" diff --git a/po/it_IT.po b/po/it_IT.po index dc8919c4..9032a7c8 100644 --- a/po/it_IT.po +++ b/po/it_IT.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2009-08-29 11:16+0100\n" "Last-Translator: Diego Pierotto \n" "Language-Team: Italian\n" @@ -931,6 +931,12 @@ msgstr "Canale bloccato (in registrazione)!" msgid "Low disk space!" msgstr "Poco spazio su disco!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Impossibile spegnere - parametro '-s' non assegnato!" diff --git a/po/lt_LT.po b/po/lt_LT.po index 5404f7e7..c50a74b6 100644 --- a/po/lt_LT.po +++ b/po/lt_LT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.9\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-08-27 22:29+0300\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2009-10-17 14:19+0200\n" "Last-Translator: Valdemaras Pipiras \n" "Language-Team: Lithuanian\n" @@ -924,6 +924,12 @@ msgstr "Kanalas užblokuotas (įrašinėjama)!" msgid "Low disk space!" msgstr "Mažai vietos diske!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Sistemos negalima išjungti, nes starto metu nebuvo komandinėj eilutėj paduota savybė '-s'!" diff --git a/po/nl_NL.po b/po/nl_NL.po index 5fd84596..99a8f450 100644 --- a/po/nl_NL.po +++ b/po/nl_NL.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2008-02-26 17:20+0100\n" "Last-Translator: Johan Schuring \n" "Language-Team: Dutch\n" @@ -928,6 +928,12 @@ msgstr "Kanaal geblokkeerd (neemt op)!" msgid "Low disk space!" msgstr "Hardeschijf bijna vol!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Shutdown onmogelijk - Optie '-s' ontbreekt!" diff --git a/po/nn_NO.po b/po/nn_NO.po index 09513be8..070e974b 100644 --- a/po/nn_NO.po +++ b/po/nn_NO.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2007-08-12 14:17+0200\n" "Last-Translator: Truls Slevigen \n" "Language-Team: Norwegian\n" @@ -925,6 +925,12 @@ msgstr "Kanalen er l msgid "Low disk space!" msgstr "Lite ledig diskplass!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Kan ikke sl av - startet uten parameteret '-s'!" diff --git a/po/pl_PL.po b/po/pl_PL.po index 99dd6dc0..daca48f4 100644 --- a/po/pl_PL.po +++ b/po/pl_PL.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2008-03-09 12:59+0100\n" "Last-Translator: Michael Rakowski \n" "Language-Team: Polish\n" @@ -925,6 +925,12 @@ msgstr "Kana msgid "Low disk space!" msgstr "Mao miejsca na dysku!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Nie mona wyczy - nie podano opcji '-s'!" diff --git a/po/pt_PT.po b/po/pt_PT.po index a01d020f..cee93d7c 100644 --- a/po/pt_PT.po +++ b/po/pt_PT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2008-03-18 17:04+0100\n" "Last-Translator: anonymous\n" "Language-Team: Portuguese\n" @@ -924,6 +924,12 @@ msgstr "Canal bloqueado (a gravar)!" msgid "Low disk space!" msgstr "Espao em disco reduzido!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Impossvel desligar - falta a opo '-s'!" diff --git a/po/ro_RO.po b/po/ro_RO.po index aaf5e2b2..6059aa58 100644 --- a/po/ro_RO.po +++ b/po/ro_RO.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2008-02-25 00:39+0100\n" "Last-Translator: Lucian Muresan \n" "Language-Team: Romanian\n" @@ -927,6 +927,12 @@ msgstr "Canal blocat ( msgid "Low disk space!" msgstr "Spaiul pe disc e foarte sczut!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Nu pot nchide - vezi opiunea '-s'" diff --git a/po/ru_RU.po b/po/ru_RU.po index 9e73d416..3de70437 100644 --- a/po/ru_RU.po +++ b/po/ru_RU.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2008-12-15 14:37+0100\n" "Last-Translator: Oleg Roitburd \n" "Language-Team: Russian\n" @@ -925,6 +925,12 @@ msgstr " msgid "Low disk space!" msgstr " !" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr " - '-s'!" diff --git a/po/sk_SK.po b/po/sk_SK.po index e6375df0..8471140d 100644 --- a/po/sk_SK.po +++ b/po/sk_SK.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2009-09-30 12:50+0100\n" "Last-Translator: Milan Hrala \n" "Language-Team: Slovak\n" @@ -925,6 +925,12 @@ msgstr "Kan msgid "Low disk space!" msgstr "Za chvku bude pln disk!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Vypnutie nie je mon - chba voba '-s'!" @@ -1023,4 +1029,3 @@ msgstr "ktor #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR sa vypne za %s mint" - diff --git a/po/sl_SI.po b/po/sl_SI.po index 58316151..4f89ff77 100644 --- a/po/sl_SI.po +++ b/po/sl_SI.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2008-02-28 19:44+0100\n" "Last-Translator: Matjaz Thaler \n" "Language-Team: Slovenian\n" @@ -925,6 +925,12 @@ msgstr "Zaklenjen kanal (snemanje)!" msgid "Low disk space!" msgstr "Premalo prostora na disku!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Zaustavitev ni izvedljiva - opcija '-s' ni podana!" diff --git a/po/sv_SE.po b/po/sv_SE.po index 5fbefa8e..d368bb65 100644 --- a/po/sv_SE.po +++ b/po/sv_SE.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2008-03-12 18:25+0100\n" "Last-Translator: Magnus Andersson \n" "Language-Team: Swedish\n" @@ -927,6 +927,12 @@ msgstr "Kanalen msgid "Low disk space!" msgstr "Lgt diskutrymme!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Kan inte avsluta, mste anvnda parameter '-s'" diff --git a/po/tr_TR.po b/po/tr_TR.po index c6f38df9..39138d59 100644 --- a/po/tr_TR.po +++ b/po/tr_TR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-21 13:18+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2008-02-28 00:33+0100\n" "Last-Translator: Oktay Yolgeen \n" "Language-Team: Turkish\n" @@ -924,6 +924,12 @@ msgstr "Kanal ge msgid "Low disk space!" msgstr "Kayt kapasitesi az!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Kapatlamyor - '-s' seenei verilmemi!" diff --git a/po/uk_UA.po b/po/uk_UA.po index c35b24fc..6c2f58ab 100644 --- a/po/uk_UA.po +++ b/po/uk_UA.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.7\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-05-31 11:11+0200\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2009-05-31 13:17+0200\n" "Last-Translator: Yarema aka Knedlyk \n" "Language-Team: Ukrainian\n" @@ -924,6 +924,12 @@ msgstr "Канал заблоковано (йде запис)!" msgid "Low disk space!" msgstr "Недостатньо місця на диску!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "Виключенння неможливе - не задано параметр '-s'!" diff --git a/po/zh_CN.po b/po/zh_CN.po index 5291adb0..03bddab9 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-02-09 12:37+0800\n" +"POT-Creation-Date: 2009-11-22 12:28+0100\n" "PO-Revision-Date: 2009-09-23 23:50+0800\n" "Last-Translator: Nan Feng \n" "Language-Team: Chinese\n" @@ -927,6 +927,12 @@ msgstr "频道已经锁定 (录像)!" msgid "Low disk space!" msgstr "磁盘空间不足!" +msgid "Regenerating index file" +msgstr "" + +msgid "Index file regeneration complete" +msgstr "" + msgid "Can't shutdown - option '-s' not given!" msgstr "不能关机 - 操作 '-s' 不允许!" diff --git a/recorder.c b/recorder.c index a383feb3..145d0206 100644 --- a/recorder.c +++ b/recorder.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recorder.c 2.5 2009/11/15 15:27:08 kls Exp $ + * $Id: recorder.c 2.6 2009/11/21 15:58:12 kls Exp $ */ #include "recorder.h" @@ -30,7 +30,7 @@ cRecorder::cRecorder(const char *FileName, tChannelID ChannelID, int Priority, i SpinUpDisk(FileName); - ringBuffer = new cRingBufferLinear(RECORDERBUFSIZE, TS_SIZE * 2, true, "Recorder"); + ringBuffer = new cRingBufferLinear(RECORDERBUFSIZE, MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE, true, "Recorder"); ringBuffer->SetTimeouts(0, 100); cChannel *Channel = Channels.GetByChannelID(ChannelID); int Pid = VPid; diff --git a/recording.c b/recording.c index f3c2c5ab..ab94c32a 100644 --- a/recording.c +++ b/recording.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.c 2.17 2009/08/16 10:39:43 kls Exp $ + * $Id: recording.c 2.18 2009/11/22 11:20:53 kls Exp $ */ #include "recording.h" @@ -21,6 +21,7 @@ #include "i18n.h" #include "interface.h" #include "remux.h" +#include "ringbuffer.h" #include "skins.h" #include "tools.h" #include "videodir.h" @@ -1309,6 +1310,124 @@ void cRecordingUserCommand::InvokeCommand(const char *State, const char *Recordi } } +// --- cIndexFileGenerator --------------------------------------------------- + +#define IFG_BUFFER_SIZE KILOBYTE(100) + +class cIndexFileGenerator : public cThread { +private: + cString recordingName; +protected: + virtual void Action(void); +public: + cIndexFileGenerator(const char *RecordingName); + ~cIndexFileGenerator(); + }; + +cIndexFileGenerator::cIndexFileGenerator(const char *RecordingName) +:cThread("index file generator") +,recordingName(RecordingName) +{ + Start(); +} + +cIndexFileGenerator::~cIndexFileGenerator() +{ + Cancel(3); +} + +void cIndexFileGenerator::Action(void) +{ + bool IndexFileComplete = false; + bool Rewind = false; + cFileName FileName(recordingName, false); + cUnbufferedFile *ReplayFile = FileName.Open(); + cRingBufferLinear Buffer(IFG_BUFFER_SIZE, MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE); + cPatPmtParser PatPmtParser; + cFrameDetector FrameDetector; + cIndexFile IndexFile(recordingName, true); + int BufferChunks = KILOBYTE(1); // no need to read a lot at the beginning when parsing PAT/PMT + off_t FileSize = 0; + off_t FrameOffset = -1; + Skins.QueueMessage(mtInfo, tr("Regenerating index file")); + while (Running()) { + // Rewind input file: + if (Rewind) { + ReplayFile = FileName.SetOffset(1); + Buffer.Clear(); + Rewind = false; + } + // Process data: + int Length; + uchar *Data = Buffer.Get(Length); + if (Data) { + if (FrameDetector.Synced()) { + // Step 3 - generate the index: + if (TsPid(Data) == PATPID) + FrameOffset = FileSize; // the PAT/PMT is at the beginning of an I-frame + int Processed = FrameDetector.Analyze(Data, Length); + if (Processed > 0) { + if (FrameDetector.NewFrame()) { + IndexFile.Write(FrameDetector.IndependentFrame(), FileName.Number(), FrameOffset >= 0 ? FrameOffset : FileSize); + FrameOffset = -1; + } + FileSize += Processed; + Buffer.Del(Processed); + } + } + else if (PatPmtParser.Vpid()) { + // Step 2 - sync FrameDetector: + int Processed = FrameDetector.Analyze(Data, Length); + if (Processed > 0) { + if (FrameDetector.Synced()) { + // Synced FrameDetector, so rewind for actual processing: + FrameDetector.Reset(); + Rewind = true; + } + Buffer.Del(Processed); + } + } + else { + // Step 1 - parse PAT/PMT: + uchar *p = Data; + while (Length >= TS_SIZE) { + int Pid = TsPid(p); + if (Pid == 0) + PatPmtParser.ParsePat(p, TS_SIZE); + else if (Pid == PatPmtParser.PmtPid()) + PatPmtParser.ParsePmt(p, TS_SIZE); + Length -= TS_SIZE; + p += TS_SIZE; + if (PatPmtParser.Vpid()) { + // Found Vpid, so rewind to sync FrameDetector: + FrameDetector.SetPid(PatPmtParser.Vpid(), PatPmtParser.Vtype()); + BufferChunks = IFG_BUFFER_SIZE; + Rewind = true; + break; + } + } + Buffer.Del(p - Data); + } + } + // Read data: + else if (ReplayFile) { + int Result = Buffer.Read(ReplayFile, BufferChunks); + if (Result == 0) // EOF + ReplayFile = FileName.NextFile(); + } + // Recording has been processed: + else { + IndexFileComplete = true; + break; + } + } + // Delete the index file if the recording has not been processed entirely: + if (IndexFileComplete) + Skins.QueueMessage(mtInfo, tr("Index file regeneration complete")); + else + IndexFile.Delete(); +} + // --- cIndexFile ------------------------------------------------------------ #define INDEXFILESUFFIX "/index" @@ -1343,6 +1462,9 @@ struct tIndexTs { } }; +#define MAXWAITFORINDEXFILE 10 // max. time to wait for the regenerated index file (seconds) +#define INDEXFILECHECKINTERVAL 500 // ms between checks for existence of the regenerated index file + cIndexFile::cIndexFile(const char *FileName, bool Record, bool IsPesRecording) :resumeFile(FileName, IsPesRecording) { @@ -1352,6 +1474,7 @@ cIndexFile::cIndexFile(const char *FileName, bool Record, bool IsPesRecording) last = -1; index = NULL; isPesRecording = IsPesRecording; + indexFileGenerator = NULL; if (FileName) { const char *Suffix = isPesRecording ? INDEXFILESUFFIX ".vdr" : INDEXFILESUFFIX; fileName = MALLOC(char, strlen(FileName) + strlen(Suffix) + 1); @@ -1360,6 +1483,18 @@ cIndexFile::cIndexFile(const char *FileName, bool Record, bool IsPesRecording) char *pFileExt = fileName + strlen(fileName); strcpy(pFileExt, Suffix); int delta = 0; + if (!Record && access(fileName, R_OK) != 0) { + // Index file doesn't exist, so try to regenerate it: + if (!isPesRecording) { // sorry, can only do this for TS recordings + resumeFile.Delete(); // just in case + indexFileGenerator = new cIndexFileGenerator(FileName); + // Wait until the index file exists: + time_t tmax = time(NULL) + MAXWAITFORINDEXFILE; + do { + cCondWait::SleepMs(INDEXFILECHECKINTERVAL); // start with a sleep, to give it a head start + } while (access(fileName, R_OK) != 0 && time(NULL) < tmax); + } + } if (access(fileName, R_OK) == 0) { struct stat buf; if (stat(fileName, &buf) == 0) { @@ -1421,6 +1556,7 @@ cIndexFile::~cIndexFile() close(f); free(fileName); free(index); + delete indexFileGenerator; } void cIndexFile::ConvertFromPes(tIndexTs *IndexTs, int Count) @@ -1598,6 +1734,18 @@ bool cIndexFile::IsStillRecording() return f >= 0; } +void cIndexFile::Delete(void) +{ + if (fileName) { + dsyslog("deleting index file '%s'", fileName); + if (f >= 0) { + close(f); + f = -1; + } + unlink(fileName); + } +} + // --- cFileName ------------------------------------------------------------- #define MAXFILESPERRECORDINGPES 255 diff --git a/recording.h b/recording.h index a895a2d3..bc3479fe 100644 --- a/recording.h +++ b/recording.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.h 2.9 2009/08/16 10:45:00 kls Exp $ + * $Id: recording.h 2.10 2009/11/21 16:12:55 kls Exp $ */ #ifndef __RECORDING_H @@ -220,6 +220,7 @@ public: #define MAXVIDEOFILESIZEDEFAULT MAXVIDEOFILESIZEPES struct tIndexTs; +class cIndexFileGenerator; class cIndexFile { private: @@ -229,6 +230,7 @@ private: tIndexTs *index; bool isPesRecording; cResumeFile resumeFile; + cIndexFileGenerator *indexFileGenerator; cMutex mutex; void ConvertFromPes(tIndexTs *IndexTs, int Count); void ConvertToPes(tIndexTs *IndexTs, int Count); @@ -245,6 +247,7 @@ public: int GetResume(void) { return resumeFile.Read(); } bool StoreResume(int Index) { return resumeFile.Save(Index); } bool IsStillRecording(void); + void Delete(void); }; class cFileName { diff --git a/remux.c b/remux.c index 98f404f2..c5055b69 100644 --- a/remux.c +++ b/remux.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remux.c 2.28 2009/11/01 15:33:32 kls Exp $ + * $Id: remux.c 2.29 2009/11/22 11:23:27 kls Exp $ */ #include "remux.h" @@ -264,8 +264,8 @@ void cPatPmtGenerator::GeneratePat(void) uchar *p = pat; int i = 0; p[i++] = TS_SYNC_BYTE; // TS indicator - p[i++] = TS_PAYLOAD_START; // flags (3), pid hi (5) - p[i++] = 0x00; // pid lo + p[i++] = TS_PAYLOAD_START | (PATPID >> 8); // flags (3), pid hi (5) + p[i++] = PATPID & 0xFF; // pid lo p[i++] = 0x10; // flags (4), continuity counter (4) p[i++] = 0x00; // pointer field (payload unit start indicator is set) int PayloadStart = i; @@ -733,20 +733,20 @@ void PesDump(const char *Name, const u_char *Data, int Length) // --- cFrameDetector -------------------------------------------------------- +#define EMPTY_SCANNER (0xFFFFFFFF) + cFrameDetector::cFrameDetector(int Pid, int Type) { - pid = Pid; - type = Type; + SetPid(Pid, Type); synced = false; newFrame = independentFrame = false; numPtsValues = 0; numIFrames = 0; - isVideo = type == 0x01 || type == 0x02 || type == 0x1B; // MPEG 1, 2 or 4 frameDuration = 0; framesInPayloadUnit = framesPerPayloadUnit = 0; payloadUnitOfFrame = 0; scanning = false; - scanner = 0; + scanner = EMPTY_SCANNER; } static int CmpUint32(const void *p1, const void *p2) @@ -756,8 +756,24 @@ static int CmpUint32(const void *p1, const void *p2) return 0; } +void cFrameDetector::SetPid(int Pid, int Type) +{ + pid = Pid; + type = Type; + isVideo = type == 0x01 || type == 0x02 || type == 0x1B; // MPEG 1, 2 or 4 +} + +void cFrameDetector::Reset(void) +{ + newFrame = independentFrame = false; + payloadUnitOfFrame = 0; + scanning = false; + scanner = EMPTY_SCANNER; +} + int cFrameDetector::Analyze(const uchar *Data, int Length) { + int SeenPayloadStart = false; int Processed = 0; newFrame = independentFrame = false; while (Length >= TS_SIZE) { @@ -768,144 +784,156 @@ int cFrameDetector::Analyze(const uchar *Data, int Length) esyslog("ERROR: skipped %d bytes to sync on start of TS packet", Skipped); return Processed + Skipped; } - if (TsHasPayload(Data) && !TsIsScrambled(Data) && TsPid(Data) == pid) { - if (TsPayloadStart(Data)) { - if (synced && Processed) - return Processed; - if (Length < 2 * TS_SIZE) - return 0; // need more data, in case the frame type is stored in the second TS packet - if (!frameDuration) { - // frame duration unknown, so collect a sequence of PTS values: - if (numPtsValues < MaxPtsValues && numIFrames < 2) { // collect a sequence containing at least two I-frames - const uchar *Pes = Data + TsPayloadOffset(Data); - if (PesHasPts(Pes)) { - ptsValues[numPtsValues] = PesGetPts(Pes); - // check for rollover: - if (numPtsValues && ptsValues[numPtsValues - 1] > 0xF0000000 && ptsValues[numPtsValues] < 0x10000000) { - dbgframes("#"); - numPtsValues = 0; - numIFrames = 0; - } - else - numPtsValues++; - } - } - else { - // find the smallest PTS delta: - qsort(ptsValues, numPtsValues, sizeof(uint32_t), CmpUint32); - numPtsValues--; - for (int i = 0; i < numPtsValues; i++) - ptsValues[i] = ptsValues[i + 1] - ptsValues[i]; - qsort(ptsValues, numPtsValues, sizeof(uint32_t), CmpUint32); - uint32_t Delta = ptsValues[0]; - // determine frame info: - if (isVideo) { - if (Delta % 3600 == 0) - frameDuration = 3600; // PAL, 25 fps - else if (Delta % 3003 == 0) - frameDuration = 3003; // NTSC, 29.97 fps - else if (Delta == 1800) { - frameDuration = 3600; // PAL, 25 fps - framesPerPayloadUnit = -2; - } - else if (Delta == 1501) { - frameDuration = 3003; // NTSC, 29.97 fps - framesPerPayloadUnit = -2; - } - else { - frameDuration = 3600; // unknown, assuming 25 fps - dsyslog("unknown frame duration (%d), assuming 25 fps", Delta); - } - } - else // audio - frameDuration = Delta; // PTS of audio frames is always increasing - dbgframes("\nframe duration = %d FPS = %5.2f FPPU = %d\n", frameDuration, 90000.0 / frameDuration, framesPerPayloadUnit); - } - } - scanner = 0; - scanning = true; - } - if (scanning) { - int PayloadOffset = TsPayloadOffset(Data); + if (TsHasPayload(Data) && !TsIsScrambled(Data)) { + int Pid = TsPid(Data); + if (Pid == pid) { if (TsPayloadStart(Data)) { - PayloadOffset += PesPayloadOffset(Data + PayloadOffset); - if (!framesPerPayloadUnit) - framesPerPayloadUnit = framesInPayloadUnit; - if (DebugFrames && !synced) - dbgframes("/"); - } - for (int i = PayloadOffset; scanning && i < TS_SIZE; i++) { - scanner <<= 8; - scanner |= Data[i]; - switch (type) { - case 0x01: // MPEG 1 video - case 0x02: // MPEG 2 video - if (scanner == 0x00000100) { // Picture Start Code - newFrame = true; - independentFrame = ((Data[i + 2] >> 3) & 0x07) == 1; // I-Frame - if (synced) { - if (framesPerPayloadUnit <= 1) - scanning = false; - } - else { - framesInPayloadUnit++; - if (independentFrame) - numIFrames++; - dbgframes("%d ", (Data[i + 2] >> 3) & 0x07); - } - scanner = 0; - if (synced && Processed) - return Processed; - } - break; - case 0x1B: // MPEG 4 video - if (scanner == 0x00000109) { // Access Unit Delimiter - newFrame = true; - independentFrame = Data[i + 1] == 0x10; - if (synced) { - if (framesPerPayloadUnit < 0) { - payloadUnitOfFrame = (payloadUnitOfFrame + 1) % -framesPerPayloadUnit; - if (payloadUnitOfFrame != 0 && independentFrame) - payloadUnitOfFrame = 0; - if (payloadUnitOfFrame) - newFrame = false; - } - if (framesPerPayloadUnit <= 1) - scanning = false; - } - else { - framesInPayloadUnit++; - if (independentFrame) - numIFrames++; - dbgframes("%02X ", Data[i + 1]); - } - if (synced && Processed) - return Processed; - scanner = 0; - } - break; - case 0x04: // MPEG audio - case 0x06: // AC3 audio - newFrame = true; - independentFrame = true; - if (!synced) { - framesInPayloadUnit = 1; - if (TsPayloadStart(Data)) - numIFrames++; - } - scanning = false; - if (synced && Processed) - return Processed; - break; - default: esyslog("ERROR: unknown stream type %d (PID %d) in frame detector", type, pid); - pid = 0; // let's just ignore any further data + SeenPayloadStart = true; + if (synced && Processed) + return Processed; + if (Length < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE) + return 0; // need more data, in case the frame type is not stored in the first TS packet + if (!frameDuration) { + // frame duration unknown, so collect a sequence of PTS values: + if (numPtsValues < MaxPtsValues && numIFrames < 2) { // collect a sequence containing at least two I-frames + const uchar *Pes = Data + TsPayloadOffset(Data); + if (PesHasPts(Pes)) { + ptsValues[numPtsValues] = PesGetPts(Pes); + // check for rollover: + if (numPtsValues && ptsValues[numPtsValues - 1] > 0xF0000000 && ptsValues[numPtsValues] < 0x10000000) { + dbgframes("#"); + numPtsValues = 0; + numIFrames = 0; + } + else + numPtsValues++; + } + } + else { + // find the smallest PTS delta: + qsort(ptsValues, numPtsValues, sizeof(uint32_t), CmpUint32); + numPtsValues--; + for (int i = 0; i < numPtsValues; i++) + ptsValues[i] = ptsValues[i + 1] - ptsValues[i]; + qsort(ptsValues, numPtsValues, sizeof(uint32_t), CmpUint32); + uint32_t Delta = ptsValues[0]; + // determine frame info: + if (isVideo) { + if (Delta % 3600 == 0) + frameDuration = 3600; // PAL, 25 fps + else if (Delta % 3003 == 0) + frameDuration = 3003; // NTSC, 29.97 fps + else if (Delta == 1800) { + frameDuration = 3600; // PAL, 25 fps + framesPerPayloadUnit = -2; + } + else if (Delta == 1501) { + frameDuration = 3003; // NTSC, 29.97 fps + framesPerPayloadUnit = -2; + } + else { + frameDuration = 3600; // unknown, assuming 25 fps + dsyslog("unknown frame duration (%d), assuming 25 fps", Delta); + } + } + else // audio + frameDuration = Delta; // PTS of audio frames is always increasing + dbgframes("\nframe duration = %d FPS = %5.2f FPPU = %d\n", frameDuration, 90000.0 / frameDuration, framesPerPayloadUnit); + } + } + scanner = EMPTY_SCANNER; + scanning = true; + } + if (scanning) { + int PayloadOffset = TsPayloadOffset(Data); + if (TsPayloadStart(Data)) { + PayloadOffset += PesPayloadOffset(Data + PayloadOffset); + if (!framesPerPayloadUnit) + framesPerPayloadUnit = framesInPayloadUnit; + if (DebugFrames && !synced) + dbgframes("/"); + } + for (int i = PayloadOffset; scanning && i < TS_SIZE; i++) { + scanner <<= 8; + scanner |= Data[i]; + switch (type) { + case 0x01: // MPEG 1 video + case 0x02: // MPEG 2 video + if (scanner == 0x00000100) { // Picture Start Code + scanner = EMPTY_SCANNER; + if (synced && !SeenPayloadStart && Processed) + return Processed; // flush everything before this new frame + newFrame = true; + independentFrame = ((Data[i + 2] >> 3) & 0x07) == 1; // I-Frame + if (synced) { + if (framesPerPayloadUnit <= 1) + scanning = false; + } + else { + framesInPayloadUnit++; + if (independentFrame) + numIFrames++; + dbgframes("%d ", (Data[i + 2] >> 3) & 0x07); + } + if (synced) + return Processed + TS_SIZE; // flag this new frame + } + break; + case 0x1B: // MPEG 4 video + if (scanner == 0x00000109) { // Access Unit Delimiter + scanner = EMPTY_SCANNER; + if (synced && !SeenPayloadStart && Processed) + return Processed; // flush everything before this new frame + newFrame = true; + independentFrame = Data[i + 1] == 0x10; + if (synced) { + if (framesPerPayloadUnit < 0) { + payloadUnitOfFrame = (payloadUnitOfFrame + 1) % -framesPerPayloadUnit; + if (payloadUnitOfFrame != 0 && independentFrame) + payloadUnitOfFrame = 0; + if (payloadUnitOfFrame) + newFrame = false; + } + if (framesPerPayloadUnit <= 1) + scanning = false; + } + else { + framesInPayloadUnit++; + if (independentFrame) + numIFrames++; + dbgframes("%02X ", Data[i + 1]); + } + if (synced) + return Processed + TS_SIZE; // flag this new frame + } + break; + case 0x04: // MPEG audio + case 0x06: // AC3 audio + if (synced && Processed) + return Processed; + newFrame = true; + independentFrame = true; + if (!synced) { + framesInPayloadUnit = 1; + if (TsPayloadStart(Data)) + numIFrames++; + } + scanning = false; + break; + default: esyslog("ERROR: unknown stream type %d (PID %d) in frame detector", type, pid); + pid = 0; // let's just ignore any further data + } + } + if (!synced && frameDuration && independentFrame) { + synced = true; + dbgframes("*"); + Reset(); + return Processed + TS_SIZE; } - } - if (!synced && frameDuration && independentFrame) { - synced = true; - dbgframes("*"); } } + else if (Pid == PATPID && synced && Processed) + return Processed; // allow the caller to see any PAT packets } Data += TS_SIZE; Length -= TS_SIZE; diff --git a/remux.h b/remux.h index e6025fa5..ad099c6a 100644 --- a/remux.h +++ b/remux.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remux.h 2.19 2009/08/16 15:15:33 kls Exp $ + * $Id: remux.h 2.20 2009/11/21 15:55:34 kls Exp $ */ #ifndef __REMUX_H @@ -49,6 +49,7 @@ public: #define TS_ADAPT_TP_PRIVATE 0x02 #define TS_ADAPT_EXTENSION 0x01 +#define PATPID 0x0000 // PAT PID (constant 0) #define MAXPID 0x2000 // for arrays that use a PID as the index inline bool TsHasPayload(const uchar *p) @@ -238,8 +239,11 @@ public: ///< Returns the PMT pid as defined by the current PAT. ///< If no PAT has been received yet, -1 will be returned. int Vpid(void) { return vpid; } - ///< Returns the video pid as defined by the current PMT. + ///< Returns the video pid as defined by the current PMT, or 0 if no video + ///< pid has been detected, yet. int Vtype(void) { return vtype; } + ///< Returns the video stream type as defined by the current PMT, or 0 if no video + ///< stream type has been detected, yet. }; // TS to PES converter: @@ -299,6 +303,8 @@ void PesDump(const char *Name, const u_char *Data, int Length); // Frame detector: +#define MIN_TS_PACKETS_FOR_FRAME_DETECTOR 2 + class cFrameDetector { private: enum { MaxPtsValues = 150 }; @@ -320,7 +326,15 @@ private: bool scanning; uint32_t scanner; public: - cFrameDetector(int Pid, int Type); + cFrameDetector(int Pid = 0, int Type = 0); + ///< Sets up a frame detector for the given Pid and stream Type. + ///< If no Pid and Type is given, they need to be set by a separate + ///< call to SetPid(). + void SetPid(int Pid, int Type); + ///< Sets the Pid and stream Type to detect frames for. + void Reset(void); + ///< Resets any counters and flags used while syncing and prepares + ///< the frame detector for actual work. int Analyze(const uchar *Data, int Length); ///< Analyzes the TS packets pointed to by Data. Length is the number of ///< bytes Data points to, and must be a multiple of 188. diff --git a/ringbuffer.c b/ringbuffer.c index fd8123ec..1bdeaccc 100644 --- a/ringbuffer.c +++ b/ringbuffer.c @@ -7,7 +7,7 @@ * Parts of this file were inspired by the 'ringbuffy.c' from the * LinuxDVB driver (see linuxtv.org). * - * $Id: ringbuffer.c 2.2 2009/05/17 10:05:17 kls Exp $ + * $Id: ringbuffer.c 2.3 2009/11/22 11:14:36 kls Exp $ */ #include "ringbuffer.h" @@ -200,7 +200,7 @@ int cRingBufferLinear::Available(void) void cRingBufferLinear::Clear(void) { - tail = head; + tail = head = margin; #ifdef DEBUGRINGBUFFERS lastHead = head; lastTail = tail; @@ -217,7 +217,8 @@ int cRingBufferLinear::Read(int FileHandle, int Max) int free = (diff > 0) ? diff - 1 : Size() - head; if (Tail <= margin) free--; - int Count = 0; + int Count = -1; + errno = EAGAIN; if (free > 0) { if (0 < Max && Max < free) free = Max; @@ -247,6 +248,44 @@ int cRingBufferLinear::Read(int FileHandle, int Max) return Count; } +int cRingBufferLinear::Read(cUnbufferedFile *File, int Max) +{ + int Tail = tail; + int diff = Tail - head; + int free = (diff > 0) ? diff - 1 : Size() - head; + if (Tail <= margin) + free--; + int Count = -1; + errno = EAGAIN; + if (free > 0) { + if (0 < Max && Max < free) + free = Max; + Count = File->Read(buffer + head, free); + if (Count > 0) { + int Head = head + Count; + if (Head >= Size()) + Head = margin; + head = Head; + if (statistics) { + int fill = head - Tail; + if (fill < 0) + fill = Size() + fill; + else if (fill >= Size()) + fill = Size() - 1; + UpdatePercentage(fill); + } + } + } +#ifdef DEBUGRINGBUFFERS + lastHead = head; + lastPut = Count; +#endif + EnableGet(); + if (free == 0) + WaitForPut(); + return Count; +} + int cRingBufferLinear::Put(const uchar *Data, int Count) { if (Count > 0) { diff --git a/ringbuffer.h b/ringbuffer.h index fa9ccedf..9fe33771 100644 --- a/ringbuffer.h +++ b/ringbuffer.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: ringbuffer.h 2.1 2009/03/01 11:20:34 kls Exp $ + * $Id: ringbuffer.h 2.2 2009/11/21 15:55:34 kls Exp $ */ #ifndef __RINGBUFFER_H @@ -84,6 +84,8 @@ public: ///< Only one actual read() call is done. ///< \return Returns the number of bytes actually read and stored, or ///< an error value from the actual read() call. + int Read(cUnbufferedFile *File, int Max = 0); + ///< Like Read(int FileHandle, int Max), but reads fom a cUnbufferedFile). int Put(const uchar *Data, int Count); ///< Puts at most Count bytes of Data into the ring buffer. ///< \return Returns the number of bytes actually stored.