1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Fixed generating the index for recordings from channels that put a whole GOP into one payload unit; regenerating index file

This commit is contained in:
Klaus Schmidinger 2009-11-22 11:30:27 +01:00
parent 2db303d6f5
commit 8ffbea3788
33 changed files with 570 additions and 179 deletions

10
HISTORY
View File

@ -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.

View File

@ -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 !"

View File

@ -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: Vladimír Bárta <vladimir.barta@k2atmitec.cz>, Jiøí Dobrý <jdobry@centrum.cz>\n"
"Language-Team: Czech\n"
@ -925,6 +925,12 @@ msgstr "Kan
msgid "Low disk space!"
msgstr "Disk bude brzy zaplnìn!"
msgid "Regenerating index file"
msgstr ""
msgid "Index file regeneration complete"
msgstr ""
msgid "Can't shutdown - option '-s' not given!"
msgstr "Vypnutí není mo¾né - chybí volba '-s'!"

View File

@ -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!"

View File

@ -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 unmöglich - Option '-s' fehlt!"

View File

@ -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'!"

View File

@ -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 "
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 parámetro '-s'!"

View File

@ -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 "Kõvaketas täis!"
msgid "Regenerating index file"
msgstr ""
msgid "Index file regeneration complete"
msgstr ""
msgid "Can't shutdown - option '-s' not given!"
msgstr "Väljalülitamine ebaõnnestus - '-s' parameeter puudub!"

View File

@ -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 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!"

View File

@ -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 "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 "Arrêt impossible - option '-s' absente !"

View File

@ -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 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 "Ga¹enje nemoguæe - nedostaje opcija '-s'!"

View File

@ -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: István Füley <ifuley@tigercomp.ro>\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 leállítás nem lehetséges - Opció '-s' hiányzik!"

View File

@ -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!"

View File

@ -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'!"

View File

@ -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!"

View File

@ -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 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'!"

View File

@ -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
msgid "Low disk space!"
msgstr "Mało miejsca na dysku!"
msgid "Regenerating index file"
msgstr ""
msgid "Index file regeneration complete"
msgstr ""
msgid "Can't shutdown - option '-s' not given!"
msgstr "Nie można wyłączyć - nie podano opcji '-s'!"

View File

@ -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 "Espaço em disco reduzido!"
msgid "Regenerating index file"
msgstr ""
msgid "Index file regeneration complete"
msgstr ""
msgid "Can't shutdown - option '-s' not given!"
msgstr "Impossível desligar - falta a opção '-s'!"

View File

@ -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 (
msgid "Low disk space!"
msgstr "Spaþiul pe disc e foarte scãzut!"
msgid "Regenerating index file"
msgstr ""
msgid "Index file regeneration complete"
msgstr ""
msgid "Can't shutdown - option '-s' not given!"
msgstr "Nu pot închide - vezi opþiunea '-s'"

View File

@ -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'!"

View File

@ -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 "Kan
msgid "Low disk space!"
msgstr "Za chvíµku 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 mo¾né - chýba voµba '-s'!"
@ -1023,4 +1029,3 @@ msgstr "ktor
#, c-format
msgid "VDR will shut down in %s minutes"
msgstr "VDR sa vypne za %s minút"

View File

@ -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!"

View File

@ -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
msgid "Low disk space!"
msgstr "Lågt diskutrymme!"
msgid "Regenerating index file"
msgstr ""
msgid "Index file regeneration complete"
msgstr ""
msgid "Can't shutdown - option '-s' not given!"
msgstr "Kan inte avsluta, måste använda parameter '-s'"

View File

@ -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 Yolgeçen <oktay_73@yahoo.de>\n"
"Language-Team: Turkish\n"
@ -924,6 +924,12 @@ msgstr "Kanal ge
msgid "Low disk space!"
msgstr "Kayýt kapasitesi az!"
msgid "Regenerating index file"
msgstr ""
msgid "Index file regeneration complete"
msgstr ""
msgid "Can't shutdown - option '-s' not given!"
msgstr "Kapatýlamýyor - '-s' seçeneði verilmemiþ!"

View File

@ -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'!"

View File

@ -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' 不允许!"

View File

@ -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;

View File

@ -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

View File

@ -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 {

310
remux.c
View File

@ -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;

20
remux.h
View File

@ -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.

View File

@ -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) {

View File

@ -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.