summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2009-11-22 11:30:27 +0100
committerKlaus Schmidinger <vdr@tvdr.de>2009-11-22 11:30:27 +0100
commit8ffbea3788d8c4cc1a83fbb8f3aae7f253cbaeef (patch)
tree25195cf9a30a26520d7b9fef16719a588f5bc3c6
parent2db303d6f50ad7452eaff13ee2c9213de89a13c1 (diff)
downloadvdr-8ffbea3788d8c4cc1a83fbb8f3aae7f253cbaeef.tar.gz
vdr-8ffbea3788d8c4cc1a83fbb8f3aae7f253cbaeef.tar.bz2
Fixed generating the index for recordings from channels that put a whole GOP into one payload unit; regenerating index file
-rw-r--r--HISTORY10
-rw-r--r--po/ca_ES.po8
-rw-r--r--po/cs_CZ.po8
-rw-r--r--po/da_DK.po8
-rw-r--r--po/de_DE.po8
-rw-r--r--po/el_GR.po8
-rw-r--r--po/es_ES.po8
-rw-r--r--po/et_EE.po8
-rw-r--r--po/fi_FI.po8
-rw-r--r--po/fr_FR.po8
-rw-r--r--po/hr_HR.po8
-rw-r--r--po/hu_HU.po8
-rw-r--r--po/it_IT.po8
-rw-r--r--po/lt_LT.po8
-rw-r--r--po/nl_NL.po8
-rw-r--r--po/nn_NO.po8
-rw-r--r--po/pl_PL.po8
-rw-r--r--po/pt_PT.po8
-rw-r--r--po/ro_RO.po8
-rw-r--r--po/ru_RU.po8
-rw-r--r--po/sk_SK.po9
-rw-r--r--po/sl_SI.po8
-rw-r--r--po/sv_SE.po8
-rw-r--r--po/tr_TR.po8
-rw-r--r--po/uk_UA.po8
-rw-r--r--po/zh_CN.po8
-rw-r--r--recorder.c4
-rw-r--r--recording.c150
-rw-r--r--recording.h5
-rw-r--r--remux.c286
-rw-r--r--remux.h20
-rw-r--r--ringbuffer.c45
-rw-r--r--ringbuffer.h4
33 files changed, 558 insertions, 167 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: <vdr-bugs@tvdr.de>\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 <luca@ventoso.org>\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: <vdr-bugs@tvdr.de>\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 <vladimir.barta@k2atmitec.cz>, Ji Dobr <jdobry@centrum.cz>\n"
"Language-Team: Czech\n"
@@ -925,6 +925,12 @@ msgstr "Kanl je blokovan (nahrv se)!"
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: <vdr-bugs@tvdr.de>\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 <mogens@elneff.dk>\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: <vdr-bugs@tvdr.de>\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 <kls@tvdr.de>\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: <vdr-bugs@tvdr.de>\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 <mail@dimitrios.de>\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: <vdr-bugs@tvdr.de>\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 <luca@ventoso.org>\n"
"Language-Team: Spanish\n"
@@ -925,6 +925,12 @@ msgstr "Canal bloqueado (grabando)!"
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: <vdr-bugs@tvdr.de>\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 <kasjas@hot.ee>\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: <vdr-bugs@tvdr.de>\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 <rahrenbe@cc.hut.fi>\n"
"Language-Team: Finnish\n"
@@ -927,6 +927,12 @@ msgstr "Kanava lukittu (tallennus kynniss)!"
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: <vdr-bugs@tvdr.de>\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 <jc@repetto.org>\n"
"Language-Team: French\n"
@@ -930,6 +930,12 @@ msgstr "Chane verrouille (enregistrement en cours) !"
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: <vdr-bugs@tvdr.de>\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 <anrxc@sysphere.org>\n"
"Language-Team: Croatian\n"
@@ -926,6 +926,12 @@ msgstr "Program zakljuan (snimanje)!"
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: <vdr-bugs@tvdr.de>\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 <ifuley@tigercomp.ro>\n"
"Language-Team: Hungarian\n"
@@ -927,6 +927,12 @@ msgstr "Az ad blokkolva (felvtel)!"
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: <vdr-bugs@tvdr.de>\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 <vdr-italian@tiscali.it>\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: <vdr-bugs@tvdr.de>\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 <varas@ambernet.lt>\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: <vdr-bugs@tvdr.de>\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 <johan.schuring@vetteblei.nl>\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: <vdr-bugs@tvdr.de>\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 <truls@slevigen.no>\n"
"Language-Team: Norwegian\n"
@@ -925,6 +925,12 @@ msgstr "Kanalen er lst (opptak)!"
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: <vdr-bugs@tvdr.de>\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 <mrak@gmx.de>\n"
"Language-Team: Polish\n"
@@ -925,6 +925,12 @@ msgstr "Kana zablokowany (trwa nagrywanie)!"
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: <vdr-bugs@tvdr.de>\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: <vdr-bugs@tvdr.de>\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 <lucianm@users.sourceforge.net>\n"
"Language-Team: Romanian\n"
@@ -927,6 +927,12 @@ msgstr "Canal blocat (nregistrare)!"
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: <vdr-bugs@tvdr.de>\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 <oleg@roitburd.de>\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: <vdr-bugs@tvdr.de>\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 <hrala.milan@gmail.com>\n"
"Language-Team: Slovak\n"
@@ -925,6 +925,12 @@ msgstr "Kanl je zamknut (nahrva sa)!"
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 "ktorkovek klvesa zru retart"
#, 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: <vdr-bugs@tvdr.de>\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 <matjaz.thaler@guest.arnes.si>\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: <vdr-bugs@tvdr.de>\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 <svankan@bahnhof.se>\n"
"Language-Team: Swedish\n"
@@ -927,6 +927,12 @@ msgstr "Kanalen r lst (inspelning pgr)!"
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: <vdr-bugs@tvdr.de>\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 <oktay_73@yahoo.de>\n"
"Language-Team: Turkish\n"
@@ -924,6 +924,12 @@ msgstr "Kanal geersiz (kayt ediliyor)!"
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: <vdr-bugs@tvdr.de>\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 <yupadmin@gmail.com>\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: <vdr-bugs@tvdr.de>\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 <nfgx@21cn.com>\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;
+ if (TsHasPayload(Data) && !TsIsScrambled(Data)) {
+ int Pid = TsPid(Data);
+ if (Pid == pid) {
+ if (TsPayloadStart(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
- 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 {
+ // 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);
}
- 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;
}
- scanner = 0;
- 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
- newFrame = true;
- independentFrame = ((Data[i + 2] >> 3) & 0x07) == 1; // I-Frame
- if (synced) {
- if (framesPerPayloadUnit <= 1)
- scanning = false;
+ 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
}
- else {
- framesInPayloadUnit++;
- if (independentFrame)
- numIFrames++;
- dbgframes("%d ", (Data[i + 2] >> 3) & 0x07);
+ 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
}
- scanner = 0;
+ break;
+ case 0x04: // MPEG audio
+ case 0x06: // AC3 audio
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)
+ independentFrame = true;
+ if (!synced) {
+ framesInPayloadUnit = 1;
+ if (TsPayloadStart(Data))
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
+ 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.