/*
 *  lxdvdrip.c, abgeleitet aus lsdvd.c aus dem "vamps" b-czw. "AcidRip" Paket
 *
 *  DVD Rippen&brennen
 *  
 *  lsdvd liest die Struktur einer DVD aus. Diese Informationen werden in diesem 
 *  Programm benutzt zur Auswertung des laengsten Titels, des Requantisierungsfaktors
 *  und der Audiospuren.
 *
 *  lxdvdrip -h zeigt alle Parameter an.
 *
 *  Copyright (C) 2003  EFF (lsdvd as Base), Stefan Becker (lxdvdrip), Jean Luc Damnet (French Translation)
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation;
 *
 *  2003 by Chris Phillips
 *  2003-04-19  Cleanups get_title_name, added dvdtime2msec, added helper macros,
 *              output info structures in form of a Perl module, by Henk Vergonet.
 *  01.01.2004: Stefan Becker, Anpassung an Trackbestimmung fuer Faktorberechnung Requantisierung.
 *              abgeleitet aus lsdvd aus dem vamps-Paket
 *  02.01.2004: Stefan Becker, Parameter "-h" listet Aufrufparameter auf
 *  03.01.2004: Stefan Becker, umgewandelt in dvdripper, ohne Umwandlung per XML
 *  17.01.2004: Stefan Becker, umgewandelt fuer "StreamDVD" statt "vamps" zum Rippen,tccat Parameter gleich
 *  18.01.2004: Stefan Becker, Aufruf StreamDVD ueber "-f" in dvdauthor eingebettet, Tmp-Pfad als Parameter entfaellt
 *  18.01.2004: Stefan Becker, Faktormethode 2 auch fuer englischen Audiotrack freischalten, F1 als Default mit Audi Tracks
 *  20.01.2004: Stefan Becker, Erweiterungen: dts als Default, da bessere Qualitaet als ac3.
 *                                            Wenn kein Track gesetzt, laengsten Track berechnen.
 *                                            VOB-Vorschau per Mplayer.
 *                                            growisofs zum Brennen starten.
 *                                            alternativ brennen mit cdrecord-prodvd.
 *  21.01.2004: Stefan Becker, Erweiterungen: Parameterdatei /etc/lxdvdrip.conf.
 *                                            Kommandozeilen-Parameter: Reihenfolge beliebig, per "-par=wert".
 *                                            Bei 2 ac3 Spuren den mit groesster Kanalzahl waehlen.
 *  21.01.2004: Stefan Becker, --help zeigt Hilfe an, Umlaute entfernt, Faktor < 1 auf 1 setzen,
 *                             wahlweise deutsche oder englische Texte fuer Ausgaben und Hilfe.
 *                             ac3-Default-Audio-Track Format waehlen.
 *                             Statt Faktormethode jetzt einen echten Faktor angeben, ohne Angabe wird Faktor berechnet.
 *  22.01.2004: Stefan Becker, Projekt umbenannt in lxdvdrip
 *                             Bitrate AC3 jetzt 384, DTS=768
 *  23.01.2004: Stefan Becker, Parameter Audio Default, Inhalt rippen nach dvdauthor anzeigen.
 *                             Rippen auch per tccat / vamps
 *  24.01.2004: Stefan Becker, Warten aufs Einlegen des Rohlings abschaltbar. Wiederholung Brennen bei Fehlschlag.
 *                             Faktor durch vamps-Testtip berechnen (-f=-1)
 *                             Mehrere Kapitel testrippen, wenn eines fehlschlaegt.
 *                             Traditionelle mplayer Methode zum Rippen (-st=mplayer)
 *                             Paramter -tmp=... fuer TEMP-Dateien bei Mplayer-Rip.
 *  25.01.2004: Stefan Becker, Dateien am Ende loeschen (-d=1).
 *                             mplex alternativ zu tcmplex einbinden (-mp=mplex).
 *                             Mitte Hilfstext Enter fuer Seite 2 druecken.
 *                             Mit "-a=4,xy" andere Sprache fuer Audiotrack als deutsch und englisch
 *  26.01.2004: Stefan Becker, Bei vamps zur Faktorberechnung Videogroesse neu setzen, bei Faktor < 1 1 als min (0.21)
 *  27.01.2004: Stefan Becker, Compiler Warnings fixed, Filegroesse mit "stat" berechnen.
 *  28.01.2004: Stefan Becker, Debuglevel, um Meldungen zu unterdruecken
 *  31.01.2004: Stefan Becker, auch transcode als streamtool (-st=transcode) (0.30)
 *  31.01.2004: Stefan Becker, Parameterdatei jetzt mit Kommentaren (0.31)
 *  31.01.2004: Stefan Becker, Version mit "-v" ausgeben (0.32)
 *  01.02.2004: Stefan Becker, Auch das Filmverzeichnis loeschen (0.33)
 *  03.02.2004: Stefan Becker, Bei mplayer-Rip DVD-Device richtig setzen (0.34)
 *  06.02.2004, Stefan Becker, freien Festplattenplatz berechnen (0.35)
 *  08.02.2004, Stefan Becker, Chapter-Struktur an DVD-Author uebergeben (0.40)
 *  08.02.2004, Stefan Becker, Bei mplayer / transcode und Faktor 1 kein tcrequant (0.41)
 *  09.02.2004, Stefan Becker, Bei growisofs/mkisofs Volume-Label setzen laut Titel der DVD.
 *                             Mit Parameter "-lab=" kann Titel gesetzt werden von aussen.
 *  09.02.2004, Stefan Becker, Chapter Unterteilung abschaltbar (-chap=0)
 *  09.02.2004, Stefan Becker, Bei ac3/2 Kanal Bitrate auf 128 statt 244 gesetzt (0.42)
 *                             2 % auf Faktor als Sicherheit aufschlagen
 *  10.02.2004, Stefan Becker, Untertitel per "-s" an dvdauthor uebergeben
 *  11.02.2004, Stefan Becker, Auch bei transcode/mplayer 2 Audiotracks deutsch/englisch rippen (0.50)
 *                             Bei vamps ueber dvdunauthor auslesen, Patch fuer dvdauthor
 *  13.02.2004, Stefan Becker, dvdbackup einbinden fuer eigene Rohlinge (0.60)
 *                             Abfrage auf freien Plattenplatz abschaltbar (-free=)
 *                             Audiotracks frei waehlbar (-a=5) inkl. Auflistung
 *  14.02.2004, Stefan Becker, Bei Fehler von "dvdauthor -T" die Authorisierung wiederholen (0.61)
 *                             Teste, ob "VIDEO_TS" da und schalte bei Fehler um auf "video_ts"
 *  15.02.2004, Stefan Becker, Am Ende Dateien nur loeschen wenn Brennen OK (0.62)
 *                             Speed und Key fuer cdrecord-prodvd setzen 
 *                             cdrecord-prodvd on the fly
 *  16.02.2004, Stefan Becker, Optimierung der transcode Methode mit parallelen Pipes (0.70 pre)
 *                             Transcode Parallel fuer CBR-DVDs.
 *                             Parameter "-S 0" bei mplex angehaengt, sonst Abbruch bei 2 GB.
 *  17.02.2004, Stefan Becker, "palette.txt" fuer Untertitel auslesen.
 *                             Auch bei transcode/mplayer die Untertitel auslesen mit spuumux/spumux.
 *  18.02.2004, Stefan Becker, spuunmux ueber dvdunauthor.
 *                             Sprachauswahl "a=5" auf "a=l" fuer Liste umgestellt.
 *                             Option "u=l" zur Auswahl von Untertiteln.
 *                             Warnung, wenn bei mplayer/transcode anderes Format als ac3 ausgewaehlt.
 *                             Mit dvdbackup-Funktionen Groesse der DVD bestimmen.
 *                             DVDs kleiner als 4,7 GB mit dvdbackup sichern (Vorschlag).
 *  19.02.2004, Stefan Becker, bei Transcode frei Audiowahl freischalten. 
 *  19.02.2004, Stefan Becker, Fehler bei mplex bei Transcode mit Auditrackmethode a=l behoben (0.70 pre2)
 *  20.02.2004, Stefan Becker, Fehler bei Audiomethode a=l und unbekannter Sprache behoben (0.70 pre3)
 *  20.02.2004, Stefan Becker, Anzeige Dateigroesse beim ls des Inhalts geaendert (0.70 pre4)
 *  21.02.2004, Stefan Becker, 1:1 Kopiermodus per vamps/dvdbackup
 *  21.02.2004, Stefan Becker, beim 1:1 Modus nachher noch "dvdauthor -T" aufrufen, um die Hauptifo neu 
 *                             zu erzeugen, noetig, damit mkisofs geht. (0.70 pre 5) 
 *  21.02.2004, Stefan Becker, 1:1 Kopiermodus wieder entfernt, geht nicht. Finalversion (0.70)
 *  21.02.2004, Stefan Becker, bei transcode/mplayer Umstellung auf "dvdauthor ... -f 'mplex ... |'" (0.71)
 *  22.02.2004, Stefan Becker, Zuordnung tcmplex an Kommandozeile korrigiert (-mp=tcmplex)
 *                             Neuer Parameter "-cbr=".
 *                             Bei mplayer/transcode Files am Ende nicht loeschen, wenn Fehlschlag dvdauthor.
 *                             Nur bis zum vorletzten Kapitel die Kapitelliste fuellen.
 *                             Wenn dvdunauthor nicht gefunden, nehme tccat bei vamps.
 *  22.02.2004, Stefan Becker, Neuer Parameter "-file=" fuer Ausgabe in Datei statt dvdauthor+Brennen (0.72)
 *  24.02.2004, Stefan Becker, Methode transcode / mplex / dvdauthor per Pipes (0.80 pre 1)
 *                             vamps-Methode entfernt.
 *                             Bei transcode/mplayer Untertitel jetzt mit subtitleripper statt spumux rippen.
 *  25.02.2004, Stefan Becker, Fehler bei Auswahl streamtool als Kommandozeilenparameter behoben (0.80 pre 2)
 *  26.02.2004, Stefan Becker, Programmnamen als Parameter, jeweils mit Pfad moeglich.
 *  28.02.2004, Stefan Becker, Testrippen von vamps auf tccat/tcextract umgestellt.
 *                             Ueberpruefung der eingesetzten Programme.
 *                             Aenderungen aus Patch von apogoda integriert (0.80 pre 3).
 *                             Aenderungen: Handling von Temp-Dateien.
 *                             Untertitel automatisch per Sprache waehlen (-u=de).
 *  29.02.2004, Stefan Becker, mpeg1 Audio Streams mit transcode (0.80 pre 4)
 *  01.03.2004, Stefan Becker, Bugfixes fuer gcc 2.95 (0.80 pre 5)
 *  02.03.2004, Stefan Becker, Noch ein Bugfix fuer gcc 2.95 (0.80)
 *                             Parameter "dvdcompat=" fuer growisofs (0.90 pre 1)
 *  03.03.2004, Stefan Becker, Faktor berechnen mit streamanalyze
 *  04.03.2004, Stefan Becker, Audiomethode 5: lpcm Audiostreams mit transcode kopieren
 *                                             bei mpeg1 Audio 192 KBPS als Bitrate einstellen
 *                                             lpcm und mpeg1 Audiostreams mit Transcode parallel
 *  06.03.2004, Stefan Becker, mpeg1 auf neutral "mpeg"-Audio geaendert (0.90 pre 2)
 *                             Korrektur Auiostream-IDs bei streamanalyze, streamdvd
 *                             Patch von S. Lichtenhagen (Korrektur Meldungen, growisofs Aufruf) (0.90 pre 3)   
 *                             Parameter "-sc=" Palette fuer subtitle2pm
 *                             mpeg- und lpcm Audiostreams auch mit streamdvd (0.90 pre 4)
 *                             Kein Abbruch bei tcmplex bei tc parallel, sondern automatisch korrekte Wahl einstellen.
 *                             Bei streamanalyze Sicherheitsreserve bei mplayer/transcode.
 *                             Fix bei Untertitel (0x%x statt 0x%ld). Ausgabepufferung stdout abgeschaltet.
 *                             Bei dvdbackup Verzeichnis AUDIO_TS manuell anlegen.
 *  16.03.2004, Stefan Becker, Bei Berechnung freier Speicherplatz Ergebnis ausgeben. (0.90)
 *                             1:1 Kopie DVD groesser 4.7 GB per dvdunauthor/vamps
 *  22.03.2004, Stefan Becker, Fehler bei Setzen des DVD-Namen geaendert (0.91)
 *                             dvdbackup mit "-n" aufrufen.
 *  31.03.2004, Stefan Becker, Untertitel wieder mit spuunmux, da inzwischen performant (1.00 pre 1)
 *  02.04.2004, Stefan Becker, Untertitel auch bei transcode parallel
 *  03.04.2004, Stefan Becker, Untertitel bei trans_par optimiert (1.00 pre 2)
 *                             DVD auswerfen nach Rippen
 *  04.04.2004, Stefan Becker, DVD RW formatieren vor dem Brennen (1.00 pre 3)
 *  07.04.2004, Stefan Becker, Bei dvdcopy mit vamps und Faktor kleiner 1 vamps weglassen (1.00 pre 4)
 *                             2. Untertitelspur bei Transcode seriell, mplayer, streamanalyze, 
 *                             streamdvd
 *                             und bei transcode parallel (1.00)
 *  15.04.2004, Stefan Becker, bei allen transcode Methoden mplayer fuer dts-Audio (1.01)
 *  16.04.2004, Stefan Becker, mplayer fuer alle Audiocodecs freischalten (bisher nur ac3)
 *  27.04.2004, Stefan Becker, Hilfe formatiert (1.02)
 *                             Berechnung Groesse: Wenn kein Titleset, nicht berechnen (sonst Absturz)  
 *  05.05.2004, Jean-Luc Damnet, Franzoesische Uebersetzung
 *  09.05.2004, Stefan Becker, Videoangaben (PAL, Aspect Ratio, Aufloesung) auslesen und an
 *                             dvdauthor uebergeben
 *  28.05.2004, Stefan Becker, Transcode Testrip mit tcmplex Korrekturfaktor (1.05)
 *  13.06.2004, Stefan Becker, ~/.lxdvdrip.conf (1.06)
 *                             szTmpDir bei Testrippen nutzen
 *  19.06.2004, Stefan Becker, zusaetzliche Meldung auf englisch, franzoesisch, wenn Configfile fehlt (1.10-pre1)
 *                             Volume-ID auch an mkisofs uebergeben.
 *                             Extra-Parameter fuer mkisofs.
 *                             szTmpDir fuer Untertitel nutzen (1.10-pre2).
 *  05.07.2004, Stefan Becker, Untertitel bei streamdvd disabled (1.10-pre3)
 *  12.07.2004, Stefan Becker, Startwert Kapitel 0=00:00:00.000 (1.10-pre4)
 *  18.07.2004, Stefan Becker, Vob-Player: mit DVD Struktur starten (1.10-pre5)
 *  01.08.2004, Stefan Becker, sprintf-Aufrufe korrigiert (1.10-pre6)
 *                             spu(un)mux-Aufruf korrigiert (pre7)
 *                             Verzeichnis bei freier Speicherplatz berechnen (pre8) 
 *  04.08.2004, Stefan Becker, Chapter-List per tcprobe (pre 9)
 *                             alte Berechnung wieder aktiviert
 *  06.08.2004, Stefan Becker, Speicherplatzcheck: Vor Check Filmverzeichnis anlegen (pre10)
 *  07.08.2004, Stefan Becker, Titel aus Liste auswaehlen (-t=l) (pre11)
 *  11.08.2004, Stefan Becker, FreeBSD Make (fopen64) (1.10 final)
 *  21.08.2004, Stefan Becker, Wenn kein Audio- oder Untertiteltrack nach Defaulteinstellung, 
 *                             Umschaltung auf manuelle Auswahl statt Abbruch (1.20-pre1)
 *  03.09.2004, Stefan Becker, Parameterstring fuer cdrecord-prodvd (burn_param=) (1.20-pre2)
 *                             dvdauthor-Aufruf korrigiert (dvdauthor -t, t vorne, 1.20-pre3)
 *                             Maximalen DVD-Titel abspielen bei Vorschau (1.20-pre4)
 *                             Warnhinweis, wenn bereits Dateien im Filmverzeichnis vohanden sind. Dateien loeschen.
 *  04.09.2004, Stefan Becker, Bei mplayer als Streamtool auch mit mplayer die Untertitel lesen (1.20-pre5)
 *                             Bei Transcode Parallel / Untertitel warten auf Ende mplex/spuunmux.
 *  05.09.2004, Stefan Becker, warten auf Ende spunmux auf fork()/wait(0) umgstellt (1.20-pre6)
 *  08.09.2004, Stefan Becker, Brenngeschwindigkeit als Kommandozeilenparameter (1.20-pre7)
 *  10.09.2004, Stefan Becker, Im copy-Modus > 4.7 GB Titlesets beibehalten.
 *                             Parameter fuer Previewplayer in Configfile (vob_param="")
 *  13.09.2004, Stefan Becker, Mehrere Titel kopieren (-st=partcopy, lPackMethode=6) (1.20-pre8)
 *  16.09.2004, Stefan Becker, => 1.20
 *  17.09.2004, Stefan Becker, Test auf die Titeldateien VIDE_TS.BUP/IFO, sonst DVD-Struktur unvollstaendig
 *                            => 1.30-pre1
 *  19.09.2004, Stefan Becker, Daten zu Titel(sets) im Copymodus aus den internen Datenstrukturen statt tcprobe
 *                             Zugriffe ueber getenv: Bufferoverflow verhindern
 *  20.09.2004, Stefan Becker, an weiteren Stellen Check auf Bufferoverflow (1.30-pre2)
 *  24.09.2004, Stefan Becker, partcopy: Laenge der VOBS per mpgtx ermitteln (1.30-pre3)
 *  26.09.2004, Stefan Becker, Bei -chap im Copymode Kapitel ausblenden. Cells aus dvdauthor.xml ueberlesen.
 *  03.10.2004, Stefan Becker, High-Quality Copy (-hq=1/2) (1.30-pre4)
 *  15.10.2004, Stefan Becker, Zahleneingabe fuer Titelauswahl toleranter (input_zahlen(), 1.31)
 *  16.10.2004, Stefan Becker, Option "file=" fest in Configfile (1.40-pre1)
 *  17.10.2004, Stefan Becker, Integration dvdwizard
 *  17.10.2004, Stefan Becker, Komandozeielnparameter "-dw=0" schaltet dvdwizard ein/aus (1.40-pre2)
 *                             dvdwizard optional ohne Bilder.
 *  17.10.2004, voidmain,      Patch fuer Zugriff auf ISOs groesser 8 GB.
 *  17.10.2004, Stefan Becker, dvdwizard bei trans_par Modus (1.40-pre3)
 *  19.10.2004, Stefan Becker, dvdwizard mit Untertiteloptionen und Palettefile (1.40-pre4)
 *  21.10.2004, Stefan Becker, dvdwizard/partcpy, mit "TT" alle Titel markieren  (1.40-pre5)
 *  23.10.2004, Stefan Becker, copy und dvdwizard (1.40-pre6)
 *  24.10.2004, Stefan Becker, max. 9 Titel bei copy-Modus / dvdwizard (1.40-pre7)
 *  26.10.2004, Stefan Becker, wait(0) auf fork auch bei Untertitel/trans_par/Datei (1.40-pre8)
 *  27.10.2004, Stefan Becker, Bild fuer dvdwizard leer initialisiert (1.40-pre9)
 *  29.10.2004, Stefan Becker, dvdwizard/copy Modus/Audiotracks, Kommandouebergabe dvdwizard mit "2>&1" (1.40-pre10)
 *                             mkstemp durch mktemp ersetzt wegen Problemen mit dvdwizard (1.40-pre10-2)
 *  31.10.2004, Stefan Becker, dvdwizard an transcode 0.6.13 angepasst (Screenshots), 
 *                             vlc als Previewplayer mit DVD-Struktur
 *                             dvdwizard ohne Aufloeseung und Aspect Ratio starten (1.40-pre11)
 *              Stefan Becker, transcode/dts nach Patch freigeschaltet (1.40-pre12)
 *                             Anpassung an dvdwizard 0.4.2
 *                             mktemp/unlink entfernt und durch feste Dateinamen ersetzt.
 *  06.11.2004, Stefan Becker, lpcm immer als pcm an dvdauthor (1.40-pre13)
 *  13.11.2004, Stefan Becker, Titel editieren bei partcopy (1.40)
 *  24.11.2004, Stefan Becker, transcode/parallel: Pipenamen bei mpeg Audio korrigiert (1.41)
 *                             lpcm und mpeg1 per transcode in mpeg2 Audio umwandeln
 *                             Copymodus auf dvdauthor-XML-File umgestellt
 *  04.12.2004, Stefan Becker, Patch von jj teilweise eingespielt, palette/copymode ueberarbeitet
 *  16.01.2005, Stefan Becker, bfr/mbuffer alternativ zu buffer bei trans_par (1.42)
 *  26.01.2005, Ulrich Spoerlein, FreeBSD Patch
 *  31.01.2005, Stefan Becker&Ulrich Spoerlein: Fix Free BSD Compiler Warnings
 *              Stefan Becker, Palette/NTSC
 *  01.02.2005, Stefan Becker, Quelle neu formatiert mit indent, Header lxdvdrip.h
 *  09.02.2005, Stefan Becker, Absturz bei dvdbackup behoben (1.42-pre4)
 *                             lang_code char(3) wegen strcpy 
 *  15.02.2005, Stefan Becker, mbuffer Parameter geaendert wegen Subtitle-Problemen (1.42 final)
 *  17.02.2005, Stefan Becker, mkisofs/nur ISO Image erzeugen
 *  22.02.2005, Stefan Becker, HQ-Modus, ac3-springen zum Sync Word (lxac3scan) (1.43-pre1)
 *                             Palettenausgabe an pointer pgc->palette gebunden
 *  24.02.2005, Stefan Becker, Parameter "lxac3scan_name" (1.43-pre2)
 *                             Syntaxanpassungen dvdauthor 0.6.12 (dvdunauthor)
 *  26.02.2005, Stefan Becker, weitere Anpassungen dvdauthor 0.6.12 (1.43-pre3)
 *  05.03.2005, Stefan Becker, weitere Anpassungen dvdauthor 0.6.12 (1.43-pre4)
 *  10.03.2005, Stefan Becker, "~" durch Homedir ersetzen (1.43-pre5)
 *  14.03.2005, Stefan Becker, Kapitel/partcopy an neue Syntax dvdauthor>= 0.6.12 angepasst
 *  28.03.2005, Stefan Becker, Forced Subtitles (lxdvdrip -u=l) (1.43-pre6)
 *  29.03.2005, Stefan Becker, Alle Forced Tracks, egal wieviele Forced Titles (1.43-pre7)
 *  05.04.2005, Stefan Becker, Palette enabled bei Pointer, war wieder auf PalDVD geaendert 
 *  09.04.2005, Stefan Becker, Transcode Testrip mit mplex und lxac3scan (1.43-final)
 *  22.04.2005, Stefan Becker, ISO-Image mit Volume-ID (1.44)
 *  02.05.2005, Christian Nolte+Stefan Becker, Patch fuer libdvdread/UDFFindFile (1.45)
 *  03.05.2005, Stefan Becker, Ueberpruefung Datei oeffnen bei /tmp (1.45)
 *  05.05.2005, Stefan Becker, fopen_warnung, mplex mit "-M" Parameter
 *  08.05.2005, Stefan Becker, temp-Dateien in szTmpDir anlegen und nicht in /tmp (1.46)
 *  11.05.2005, Stefan Becker, Filmverzeichnis um Projektnamen erweitert
 *  15.05.2005, Stefan Becker, vobcopy als dvdbackup-Option
 *  16.05.2005, Stefan Becker, Sound abspielen nach Rippen und Brennen
 *  21.05.2005, Stefan Becker, Multi-Angle Support fuer tccat (Patch von Michael Lipka)
 *  31.05.2005, Stefan Becker, "playsound"-Parameter in Configfile.
 *  10.06.2005, Stefan Becker, DVD auswerfen nach growisofs (1.47)
 *  25.06.2005, Stefan Becker, Bei Fehlschlag streamanalyze Faktor intern berechnen
 *  07.07.2005, Stefan Becker, Bugfix: Chapter leer bei dvdwizard Aufrufen mit nur einem Kapitel
 *  19.11.2005, Stefan Becker, Header <stdint.h> include (1.50)
 *  27.11.2005, Stefan Becker, Streamdvd durch vamps ersetzt (vamps ab 0.98) (lPackMethode == 1)
 *  03.12.2005, Stefan Becker, VTS+PGC bei vamps statt Titel-Nr./1 setzen
 *                             Mehrfachbackup
 *  10.12.2005, Stefan Becker, streamanalyze fest eingebunden als Funktion/Modul
 *  17.12.2005, Stefan Becker, vamps => vamps_lxdvdrip (Umbenennung)
 *  21.12.2005, Stefan Becker, Videoangaben bei Vamps ins XML-File (1.51)
 *  22.12.2005, Stefan Becker, Anzahl Audio Tracks per tcprobe bestimmen, tccat mit Streaming (-P)
 *  23.12.2005, Stefan Becker, Testrip mit buffer-Befehl, wenn vorhanden. tcmplex als Default.
 *  24.12.2005, Stefan Becker, Testrip per vamps, wenn vamps Streamtool ist. 
 *  26.12.2005, Stefan Becker, Bugfix: lpcm bei vamps als pcm an dvdauthor uebergeben.
 *  28.12.2005, Stefan Becker, Vamps/Kein Abbruch bei unbekannter Stream-ID, 
 *                             alle Untertitel per "-u=a", Endesound nach jeder Kopie.
 *  31.12.2005, Stefan Becker, Vamps/Copy: preserve Track-IDs (-u / -p Parameter) (1.52)
 *  04.01.2006, Stefan Becker, Dummy-Untertitel mit "type=0" ausblenden
 *  19.02.2006, Stefan Becker, vamps 0.99/play_cell ignoriert Lesefehler
 *  04.03.2006, Stefan Becker, vamps 0.99.1/gap ignore, Start im Temp-Dir, Vamps<=>Multi Angle Support
 *  20.03.2006, Stefan Becker, Maintitle inkl. Menues (-st=vamps_menu) (1.60)
 *  26.03.2006, Stefan Becker, Kaffeine und Totem als Previewplayer mit DVD-Struktur
 *  26.03.2006, Stefan Becker, Parameter multicopy=0/1
 *  28.03.2006, Stefan Becker, Kleinere Checks
 *  01.04.2006, Stefan Becker, Vamps: Nutze "-E faktor -S Groesse"  fuer genauere Groesse,
injection_files
 *  14.04.2006, Stefan Becker, Zwischenstand bei vamps/File ausgeben
 *                             Parameter "groesse_dvd in Configfile.
 *  24.04.2006, Stefan Becker, dvd_device um Working Dir erweitern, wenn kein Device (1.61)
 *  04.05.2006, Stefan Becker, DVDFileStat fuer Inhaltsverzeichnis
 *  06.08.2006, Stefan Becker, dvdwizard 0.50 Anpassungen (1.62)
 *                             Vor Brennen UNMOUNT
 *                             Statistik Bytes gerippt/gesamt bei Vamps optimiert
 *                             Pruefen auf Tracks mit tcprobe abschaltbar (-check=)
 *  20.10.2006, Stefan Becker, Aenderungen aus dvd95 uebernommen, Bugfix dvdwizard/eigene Bilder (1.70)
 *  25.10.2006, Stefan Becker, nice-level
 *  29.10.2006, Stefan Becker, lies_wort => Einlesen Configdatei ueberarbeitet
 *  13.01.2007, Stefan Becker, Umstellung cdrecord-prodvd => cdrecord
 *  17.02.2007, Stefan Becker, vlc_par- und vlc-Modus mit Transcode.
 *                             Bei "-check=0" auch "streamanalyze" abschalten, bei Transcode auch den Testripp
 *  13.01.2008, Stefan Becker, Aktualisierung vamps_menu dvd95.131p2
 *  23.03.2008, Stefan Becker, 32 Bit Compile (INT_MAX), Pfad lxdvdrip.wav
 *
 */

#define VERSION "1.71"



#include <stdlib.h>
#include <stdint.h>

#include <dvdread/dvd_reader.h>
#include <dvdread/ifo_read.h>
#include <dvdread/ifo_print.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/wait.h>

#ifndef __FreeBSD__
#include <sys/statfs.h>
#endif

#ifndef __FreeBSD__
#define __USE_LARGEFILE64	// sonst Warning wegen fopen64
#endif
#include <stdio.h>
#include <unistd.h>


// Fullbackup
#include "const.h"
#include "dvdbackup.h"		// Fullbackup inkl. Menue
#include "ac.h"			// tc_memcpy()


// Spezifische Includes fuer lxdvdrip
// Typedefs und Prototypen
#include "lxdvdrip.h"

// Faktor in Kommandozeile gesetzt, merken für Modus vamps_menu
double dFaktorKommandozeile=0;


// Datei oeffnen mit Warnung, wenn nicht erfolgreich
FILE *
fopen_warnung (char *szFileName, char *szRechte, long lSprache)
{
  FILE *fp;
  fp = fopen (szFileName, szRechte);
  if (fp == NULL)
    {
      switch (lSprache)
	{
	case 0:
	  printf ("\nKein Zugriff auf Datei '%s' moeglich.\n"
		  "Bitte Rechte ueberpruefen, eventuell Datei loeschen als root.\n",
		  szFileName);
	  break;
	case 1:
	  printf ("\nNo Access on File '%s'.\n"
		  "Please check Rights or delete the File as root.\n",
		  szFileName);
	  break;
	case 2:
	  printf ("\nFichier '%s' inaccessible.\n"
		  "Vérifiez les permissions ou effacez le fichier depuis root.\n",
		  szFileName);
	  break;
	}
      exit (0);
    }
  return fp;
}

// Input Buffer leeren
void
eatToNL (FILE * inputStream)
{
  int c;
  /* Eat till (& including) the next newline */
  while ((c = getc (inputStream)) != EOF)
    if (c == '\n')
      break;
}


// Eingabe einer Zahl (wird benoetigt fuer Auswahl Titel / Audiotracks
void
input_zahlen (long *lZahl1, long *lZahl2, long lMaximum)
{
  char szInput[128];
  long lOK = 0;
  *lZahl1 = 0;
  if (lZahl2)
    *lZahl2 = 0;
  while (!lOK)
    {
      int i, j;
      char szNeuerString[128];
      // Eingabe
      scanf ("%127s", szInput);
      eatToNL (stdin);
      if (strlen (szInput))
	{
	  // Alles ausser Ziffern oder Komma bei 2 Zahlen herausnehmen
	  j = 0;
	  for (i = 0; i < strlen (szInput); i++)
	    {
	      if ((szInput[i] >= '0' && szInput[i] <= '9')
		  || (szInput[i] == ','))
		{
		  szNeuerString[j] = szInput[i];
		  j++;
		}
	    }
	  if (j > 0)
	    {
	      szNeuerString[j] = 0;
	      // Zerlegen in 2 Zahlen
	      if (!strstr (szNeuerString, ","))
		{
		  *lZahl1 = atol (szNeuerString);
		  if (lZahl2)
		    *lZahl2 = 0;
		}
	      else
		{
		  strcpy (szInput, "");
		  for (i = 0; i < strlen (szNeuerString); i++)
		    {
		      if (szNeuerString[i] != ',')
			strncat (szInput, &szNeuerString[i], 1);
		      else
			{
			  *lZahl1 = atol (szInput);
			  if (lZahl2)
			    *lZahl2 = atol (&szNeuerString[i + 1]);
			  break;
			}
		    }
		}
	      // Zahl 1: min 0, Maximum
	      lOK = 1;
	      if (*lZahl1 < 0 || *lZahl1 > lMaximum)
		lOK = 0;
	      if (lZahl2)
		{
		  if (*lZahl2 < 0 || *lZahl2 > lMaximum)
		    lOK = 0;
		  if (*lZahl1 < 0)
		    lOK = 0;
		}
	    }
	}
    }
}


// Test, ob noch Reste vom letzten Rip im Filmverzeichnis
void
checkLastRip (char *szFilmVerzeichnis, long lSprache)
{
  int bGefunden = 0;
  long anzTitel;
  for (anzTitel = 99; anzTitel > 0; anzTitel--)
    {
      char szVOB[1024];
      FILE *fTmp = NULL;
      sprintf (szVOB, "%s/VIDEO_TS/VTS_%02ld_1.VOB", szFilmVerzeichnis,
	       anzTitel);
      fTmp = fopen (szVOB, "r");
      if (fTmp != NULL)
	{
	  bGefunden = 1;
	  break;
	}
    }
  if (bGefunden)
    {
      char cContinue = ' ';
      char szBefehl[256];
      switch (lSprache)
	{
	case 0:
	  printf ("\nVorsicht, Dateien im Temp-Verzeichnis '%s' vorhanden!\n",
		  szFilmVerzeichnis);
	  break;
	case 1:
	  printf ("\nThere are Files in the Temp-Dir '%s'!\n",
		  szFilmVerzeichnis);
	  break;
	case 2:
	  printf
	    ("\nnIl y a des fichiers dans le répertoire temporaire '%s'!\n",
	     szFilmVerzeichnis);
	  break;
	}
      switch (lSprache)
	{
	case 0:
	  printf ("\nc=Abbruch, l=loeschen, w=weiter: ");
	  break;
	case 1:
	  printf ("\nc=cancel, d=delete, w=continue: ");
	  break;
	case 2:
	  printf
	    ("\nc=cesser l'extraction, d=détruire ces fichiers, autre caractère=continuer: ");
	  break;
	}
      scanf ("%1c", &cContinue);
      // Datein im Temp-Verzeichnis loeschen
      if (cContinue == 'd' || cContinue == 'D' || cContinue == 'l'
	  || cContinue == 'L')
	{
	  sprintf (szBefehl, "rmdir %s/AUDIO_TS", szFilmVerzeichnis);
	  printf ("%s\n", szBefehl);
	  system (szBefehl);
	  sprintf (szBefehl, "rm %s/VIDEO_TS/*", szFilmVerzeichnis);
	  printf ("%s\n", szBefehl);
	  system (szBefehl);
	  sprintf (szBefehl, "rmdir %s/VIDEO_TS", szFilmVerzeichnis);
	  printf ("%s\n", szBefehl);
	  system (szBefehl);
	}
      // beenden
      if (cContinue == 'c' || cContinue == 'C')
	{
	  exit (0);
	}
      // weiter gehts
      eatToNL (stdin);
    }
}


// Test, ob das gewuenschte Programm vorhanden ist.
long
check_program (char *szProgram, long lSprache, long lMeldung)
{
  struct stat tmpStat;
  long bGefunden = 0;
  printf ("Test %s", szProgram);
  // Wenn kein Pfad gesetzt, dann im gesamten Pfad suchen
  if (!strstr (szProgram, "/"))
    {
      char szPfad[4096];
      int i;
      char szVerzeichnis[4096];
      long lLaenge;
      lLaenge = strlen (getenv ("PATH"));
      if (lLaenge > (sizeof (szPfad) - 1))
	lLaenge = sizeof (szPfad) - 1;
      strncpy (szPfad, getenv ("PATH"), lLaenge);
      szPfad[lLaenge] = 0;
      strcpy (szVerzeichnis, "");
      for (i = 0; i < strlen (szPfad); i++)
	{
	  if (szPfad[i] == ':')
	    {
	      strcat (szVerzeichnis, "/");
	      strcat (szVerzeichnis, szProgram);
	      if (stat (szVerzeichnis, &tmpStat) == 0)
		{
		  bGefunden = 1;
		  break;
		}
	      strcpy (szVerzeichnis, "");
	    }
	  else
	    {
	      sprintf (szVerzeichnis + strlen (szVerzeichnis), "%c",
		       szPfad[i]);
	    }
	}
      if (bGefunden == 0)
	{
	  strcat (szVerzeichnis, "/");
	  strcat (szVerzeichnis, szProgram);
	  if (stat (szVerzeichnis, &tmpStat) == 0)
	    {
	      bGefunden = 1;
	    }
	}
    }
  else
    {
      if (stat (szProgram, &tmpStat) == 0)
	{
	  bGefunden = 1;
	}
    }

  // Meldung ausgeben?
  if (lMeldung == 0)
    {
      printf ("\n");
      return bGefunden;
    }

  // Wenn nicht gefunden, Abbruch
  if (bGefunden == 0)
    {
      char szWeiter;
      switch (lSprache)
	{
	case 0:
	  {
	    printf (": nicht gefunden!\n");
	    printf ("i=ignorieren, sonst Abbruch:");
	    break;
	  }
	case 1:
	  {
	    printf (": Program not found\n");
	    printf ("i=ignore, else cancel:");
	    break;
	  }
	case 2:
	  {
	    printf (": Programme introuvable\n");
	    printf ("i=ignorer, sinon annuler:");
	    break;
	  }
	}
      scanf ("%1c", &szWeiter);
      if (szWeiter != 'i')
	{
	  switch (lSprache)
	    {
	    case 0:
	      printf ("\nlxdvdrip wird beendet!\n");
	      break;
	    case 1:
	      printf ("\nlxdvdrip is canceled!\n");
	      break;
	    case 2:
	      printf ("\nlxdvdrip est annulé !\n");
	      break;
	    }
	  exit (0);
	}
      eatToNL (stdin);
    }
  else
    {
      printf (": OK\n");
    }
  return bGefunden;
}


// Berechnet Groessen der VOB-Dateien
long long
calculate_filesize (char *szVerzeichnis, char *szVideoTS, char *szVobTS,
		    char *szVtsTS)
{
  long long FileSize = 0;
  int i;
  for (i = 1; i < 1000; i++)
    {
      struct stat tmpStat;
      char filename[255];
      sprintf (filename, "%s/%s/%s_01_%d.%s", szVerzeichnis, szVideoTS,
	       szVtsTS, i, szVobTS);
      if (stat (filename, &tmpStat) != 0)	// keine weitere Datei vorhanden
	{
	  break;
	}
      FileSize += tmpStat.st_size;
    }
  return FileSize;
}


// Gibt die Groesse einer Datei zurueck, ohne die stat Beschraenkung auf < 2 GB
long long
filesize64 (char *szFileName, char *szTmpDir)
{
#ifdef __FreeBSD__
  struct stat buf;

  if (stat (szFileName, &buf) < 0)
    return 0LL;

  return buf.st_size;
#else
  FILE *fp;
  long long lSize;
  char szBuffer[128];
  char szTempl[128];
  sprintf (szTempl, "%s/groesse.lxdvdrip", szTmpDir);
  fp = (FILE *) fopen64 (szFileName, "rb");
  if (!fp)
    {
      return (long long) 0;
    }
  fclose (fp);
  sprintf (szBuffer, "du -b %s > %s", szFileName, szTempl);
  system (szBuffer);
  fp = fopen (szTempl, "rb");
  fscanf (fp, "%s", szBuffer);
  fclose (fp);
  sprintf (szTempl, "rm %s/groesse.lxdvdrip", szTmpDir);
  system (szTempl);
  lSize = atoll (szBuffer);
  return lSize;
#endif
}

// Berechnet freien Festplattenplatz
long long
calculate_discfree (char *szPfad, long lSprache, char *szTmpDir)
{
#ifdef __FreeBSD__
  struct statfs buf;
  long long lGroesse = 0;

  if (statfs (szPfad, &buf) < 0)
    return 0;

  lGroesse = (long long) buf.f_bavail * (long long) buf.f_bsize;

  switch (lSprache)
    {
    case 0:
      printf ("Frei in %s: %lld Bytes\n", szPfad, lGroesse);
      break;
    case 1:
      printf ("Free in %s: %lld Bytes\n", szPfad, lGroesse);
      break;
    case 2:
      printf ("Espace libre sur %s: %lld octets\n", szPfad, lGroesse);
      break;
    }
  return lGroesse;
#else
  char szTempl[128];
  char szBefehl[1024];
  long long lGroesse = 0;
  sprintf (szTempl, "%s/lxdf.lxdvdrip", szTmpDir);
  sprintf (szBefehl, "stat -f %s -c ", szPfad);
  strcat (szBefehl, "'%a %s' > ");
  strcat (szBefehl, szTempl);
  if (system (szBefehl) == 0)
    {
      FILE *fTmp;
      long long lFrei;
      long long lBlockGroesse;
      fTmp = fopen (szTempl, "r");
      if (fTmp)
	{
	  fscanf (fTmp, "%lld %lld", &lFrei, &lBlockGroesse);
	  fclose (fTmp);
	  lGroesse = lFrei * lBlockGroesse;
	}
      sprintf (szBefehl, "rm %s", szTempl);
      system (szBefehl);
      switch (lSprache)
	{
	case 0:
	  printf ("Frei in %s: %lld Bytes\n", szPfad, lGroesse);
	  break;
	case 1:
	  printf ("Free in %s: %lld Bytes\n", szPfad, lGroesse);
	  break;
	case 2:
	  printf ("Espace libre sur %s: %lld octets\n", szPfad, lGroesse);
	  break;
	}
    }
  return lGroesse;
#endif
}


// Findet Device-ID eines Verzeichnisses
dev_t
device_number (char *szPfad)
{
  dev_t lDevice = 0;
  struct stat buf;
  if (stat (szPfad, &buf) < 0)
    return lDevice;

  return (buf.st_dev);
}



// Funktion aus lsdvd uebernommen
// berechnet Zeit fuer Chapterunterteilung
int
millisekunden (dvd_time_t * dt)
{
  double fps = frames_per_s[(dt->frame_u & 0xc0) >> 6];
  long ms;
  ms = (((dt->hour & 0xf0) >> 3) * 5 + (dt->hour & 0x0f)) * 3600000;
  ms += (((dt->minute & 0xf0) >> 3) * 5 + (dt->minute & 0x0f)) * 60000;
  ms += (((dt->second & 0xf0) >> 3) * 5 + (dt->second & 0x0f)) * 1000;

  if (fps > 0)
    ms +=
      (((dt->frame_u & 0x30) >> 3) * 5 + (dt->frame_u & 0x0f)) * 1000.0 / fps;

  return ms;
}

/*
 *  The following method is based on code from vobcopy, by Robos, with thanks.
 */

int
get_title_name (const char *dvd_device, char *title, long lSprache)
{
  FILE *filehandle = 0;
  int i;

  if (!(filehandle = fopen (dvd_device, "r")))
    {
      switch (lSprache)
	{
	case 0:
	  fprintf (stderr, "Kann von DVD-Device %s nicht lesen!\n",
		   dvd_device);
	  break;
	case 1:
	  fprintf (stderr, "Couldn't open %s for title!\n", dvd_device);
	  break;
	case 2:
	  fprintf (stderr, "Lecture impossible depuis %s !\n", dvd_device);
	  break;
	}
      strcpy (title, "unknown");
      return -1;
    }

  if (fseek (filehandle, 32808, SEEK_SET))
    {
      fclose (filehandle);
      switch (lSprache)
	{
	case 0:
	  fprintf (stderr, "Konnte nicht auf DVD-Device %s suchen!\n",
		   dvd_device);
	  break;
	case 1:
	  fprintf (stderr, "Couldn't seek in %s for title!\n", dvd_device);
	  break;
	case 2:
	  fprintf (stderr, "Recherche dans %s impossible !\n", dvd_device);
	  break;
	}
      strcpy (title, "unknown");
      return -1;
    }

  if (32 != (i = fread (title, 1, 32, filehandle)))
    {
      fclose (filehandle);
      switch (lSprache)
	{
	case 0:
	  fprintf (stderr, "Konnte nicht genuegend Bytes lesen!\n");
	  break;
	case 1:
	  fprintf (stderr, "Couldn't read enough bytes for title!\n");
	  break;
	case 2:
	  fprintf (stderr, "Lecture incomplète pour ce titre !\n");
	  break;
	}
      strcpy (title, "unknown");
      return -1;
    }

  fclose (filehandle);

  title[32] = '\0';
  while (i-- > 2)
    if (title[i] == ' ')
      title[i] = '\0';
  return 0;
}

char *
lang_name (char *code)
{
  int k = 0;
  while (memcmp (language[k].code, code, 2) && language[k].name[0])
    {
      k++;
    }
  return language[k].name;
}


// Funktionen aus dvdbackup zur Bestimmung der Groesse der DVD
void
DVDFreeTitleSetInfo (title_set_info_t * title_set_info)
{
  free (title_set_info->title_set);
  free (title_set_info);
}

void
DVDFreeTitlesInfo (titles_info_t * titles_info)
{
  free (titles_info->titles);
  free (titles_info);
}

/* Version 0.95 as Minimum */
#ifndef DVDREAD_VERSION
#define DVDREAD_VERSION 905
#endif

/* Since Version 0.96 another approach */
#if (DVDREAD_VERSION>905)
#define NEWLIBDVDREAD
#endif

#ifndef NEWLIBDVDREAD       /* <= 0.95 */
const int max_size_one_vob = 1073565696;
#endif

/*
 Version 0.2, Stefan Becker
 Calculates Size of DVD Files
 It replaces UDFFindFile
 Parameter 3/Filetype
 returns Filesize in Bytes
 Version 0.3: DVDFileStat integrated
*/
long long SizeOfDVDFile(dvd_reader_t * _dvd, int title, int vob_nr, int filetype)
{
  long long size = 0;

#ifndef NEWLIBDVDREAD    /* <= 0.95 */

  dvd_file_t *_dvdfile = NULL;

  if ((_dvdfile = DVDOpenFile (_dvd, title, filetype)) != NULL)
  {
    size = DVDFileSize (_dvdfile);  // Count Sectors
    DVDCloseFile (_dvdfile);
  }

  return size*2048; /* 1 Sector=2048 Bytes */

#else                   /* >= 0.96 */
  typedef struct {
    __off64_t size;          /**< Total size of file in bytes */
    int nr_parts;           /**< Number of file parts */
    __off64_t parts_size[9]; /**< Size of each part in bytes */
  } dvd_stat_t_lxdvdrip;

  dvd_stat_t_lxdvdrip statbuf;

  if ( DVDFileStat(_dvd, title, filetype, (void*)&statbuf) != -1 )
  {
    if (filetype != DVD_READ_TITLE_VOBS) /* Nur eine Datei */
    {
      size = statbuf.size/2048;
    } else                               /* Mehrere VOBS */
    {
      if (vob_nr <= statbuf.nr_parts)
      {
        size = statbuf.parts_size[vob_nr-1]/2048;
      }
    }
  }

  return size;
#endif
}

title_set_info_t *DVDGetFileSet(dvd_reader_t * _dvd) {

	/* title interation */
	int title_sets, counter, i;


	/* DVD Video files */
	char	filename[256];
	int	size;

        int     verbose=0;

	/*DVD ifo handler*/
	ifo_handle_t * 	vmg_ifo=NULL;

	/* The Title Set Info struct*/
	title_set_info_t * title_set_info;

	/*  Open main info file */
	vmg_ifo = ifoOpen( _dvd, 0 );
	if( !vmg_ifo ) {
        	fprintf( stderr, "Can't open VMG info.\n" );
        	return (0);
    	}


	title_sets = vmg_ifo->vmgi_mat->vmg_nr_of_title_sets;

	/* Close the VMG ifo file we got all the info we need */
        ifoClose(vmg_ifo);

	/* Todo fix malloc check */
	title_set_info = (title_set_info_t *)malloc(sizeof(title_set_info_t));
	title_set_info->title_set = (title_set_t *)malloc((title_sets + 1)* sizeof(title_set_t));

	title_set_info->number_of_title_sets = title_sets;


	/* Find VIDEO_TS.IFO is present - must be present since we did a ifo open 0*/

	sprintf(filename,"/VIDEO_TS/VIDEO_TS.IFO");

        size = (int)SizeOfDVDFile(_dvd, 0, 0, DVD_READ_INFO_FILE);
	if ( size > 0 ) {
		title_set_info->title_set[0].size_ifo = size;
	} else {
		DVDFreeTitleSetInfo(title_set_info);
		return(0);
	}



	/* Find VIDEO_TS.VOB if present*/

	sprintf(filename,"/VIDEO_TS/VIDEO_TS.VOB");

        size = (int)SizeOfDVDFile(_dvd, 0, 0, DVD_READ_MENU_VOBS);
	if ( size > 0 ) {
		title_set_info->title_set[0].size_menu = size;
	} else {
		title_set_info->title_set[0].size_menu = 0 ;
	}

	/* Find VIDEO_TS.BUP if present */

	sprintf(filename,"/VIDEO_TS/VIDEO_TS.BUP");

        size = (int)SizeOfDVDFile(_dvd, 0, 0, DVD_READ_INFO_BACKUP_FILE);
	if ( size > 0 ) {
		title_set_info->title_set[0].size_bup = size;
	} else {
		DVDFreeTitleSetInfo(title_set_info);
		return(0);
	}

	if (title_set_info->title_set[0].size_ifo != title_set_info->title_set[0].size_bup) {
		fprintf(stderr,"BUP and IFO size not the same be warened!\n");
	}


	/* Take care of the titles which we don't have in VMG */

	title_set_info->title_set[0].number_of_vob_files = 0;
	title_set_info->title_set[0].size_vob[0] = 0;


	if ( verbose > 0 ){
		fprintf(stderr,"\n\n\nFile sizes for Title set 0 VIDEO_TS.XXX\n");
		fprintf(stderr,"IFO = %d, MENU_VOB = %d, BUP = %d\n",title_set_info->title_set[0].size_ifo, title_set_info->title_set[0].size_menu, title_set_info->title_set[0].size_bup );

	}


	if ( title_sets >= 1 ) {
 		for (counter=0; counter < title_sets; counter++ ){

			if ( verbose > 1 ){
				fprintf(stderr,"At top of loop\n");
			}


			sprintf(filename,"/VIDEO_TS/VTS_%02i_0.IFO",counter + 1);

                        size = (int)SizeOfDVDFile(_dvd, counter + 1, 0,
                                                  DVD_READ_INFO_FILE);
	                if ( size > 0 ) {
				title_set_info->title_set[counter + 1].size_ifo = size;
			} else {
				DVDFreeTitleSetInfo(title_set_info);
				return(0);
			}

			if ( verbose > 1 ){
				fprintf(stderr,"After opening files\n");
			}


			/* Find VTS_XX_0.VOB if present*/

			sprintf(filename,"/VIDEO_TS/VTS_%02i_0.VOB", counter + 1);

                        size = (int)SizeOfDVDFile(_dvd, counter + 1, 0,
                                                  DVD_READ_MENU_VOBS);
	                if ( size > 0 ) {
				title_set_info->title_set[counter + 1].size_menu = size;
			} else {
				title_set_info->title_set[counter + 1].size_menu = 0 ;
			}


			if ( verbose > 1 ){
				fprintf(stderr,"After Menu VOB check\n");
			}


			/* Find all VTS_XX_[1 to 9].VOB files if they are present*/
                        /* 0.2 Stefan Becker: This Function give Size of all */
                        /* VOB-Files from One Title-Set. So the size must be */
                        /* divided by max size of 1 file (1024 MB) to get the*/
                        /* number of files.                                  */
                        /* 0.3 Stefan Becker, Approach from Version 0.96     */
                        /*                    libdvdread integrated          */

#ifndef NEWLIBDVDREAD   /* <= Version 0.95 */
                        long long size_all_vobs=0;
                        size_all_vobs = SizeOfDVDFile(_dvd, counter + 1, 0,
                                                      DVD_READ_TITLE_VOBS);
                        i = 0;
                        do 
                        {
                          /* Length max 1073565696 Bytes */
                          if (size_all_vobs > (long long)max_size_one_vob)
                            size = (int)max_size_one_vob;
                          else
                            size = (int)size_all_vobs;
			  title_set_info->title_set[counter + 1].size_vob[i] = 
                            size;
                          i++; 
                          size_all_vobs -= (long long)max_size_one_vob;
                          if (i==10)
                          {
                            printf ("To much VOB-Files, Cancel!\n");
                            exit (0);
                          }
                        }
                        while (size_all_vobs > (long long)0);
			title_set_info->title_set[counter +1].
                           number_of_vob_files = i;

#else                   /* >= 0.96 */
                        for (i=0; i<9; i++)
                        {
                          size = SizeOfDVDFile(_dvd, counter + 1, i+1,
                                                      DVD_READ_TITLE_VOBS);
                          if (size <= 0) break;
			  title_set_info->title_set[counter + 1].size_vob[i] = 
                            size;
			  title_set_info->title_set[counter +1].
                            number_of_vob_files = i+1;
                        } 
#endif

			if ( verbose > 1 ){
				fprintf(stderr,"After Menu Title VOB check\n");
			}


			sprintf(filename,"/VIDEO_TS/VTS_%02i_0.BUP", counter + 1);

                        size = (int)SizeOfDVDFile(_dvd, counter + 1, 0, 
                                                  DVD_READ_INFO_BACKUP_FILE);
	                if ( size > 0 ) {
				title_set_info->title_set[counter +1].size_bup = size;
			} else {
				DVDFreeTitleSetInfo(title_set_info);
				return(0);
			}

			if (title_set_info->title_set[counter +1].size_ifo != title_set_info->title_set[counter + 1].size_bup) {
				fprintf(stderr,"BUP and IFO size for fileset %d is not the same be warened!\n", counter + 1);
			}



			if ( verbose > 1 ){
				fprintf(stderr,"After Menu Title BUP check\n");
			}


			if ( verbose > 0 ) {
				fprintf(stderr,"\n\n\nFile sizes for Title set %d i.e.VTS_%02d_X.XXX\n", counter + 1, counter + 1);
				fprintf(stderr,"IFO: %d, MENU: %d\n", title_set_info->title_set[counter +1].size_ifo, title_set_info->title_set[counter +1].size_menu);
				for (i = 0; i < title_set_info->title_set[counter + 1].number_of_vob_files ; i++) {
					fprintf(stderr, "VOB %d is %d\n", i + 1, title_set_info->title_set[counter + 1].size_vob[i]);
				}
				fprintf(stderr,"BUP: %d\n",title_set_info->title_set[counter +1].size_bup);
			}

			if ( verbose > 1 ){
				fprintf(stderr,"Bottom of loop \n");
			}
		}

        }

	/* Return the info */
	return(title_set_info);


}



// dvdwizard starten
// macht aus einem VOB-File eine DVD inkl. Menue
void
dvd_wizard (char *szNiceRip, char *dvdwizard_name, char *szDVDWizardVideoAngaben,
	    char *szTitel,
	    char *szHintergrundBild,
	    char *szChapter,
	    char *szAudio1, char *szAudio2,
	    char *szDVDDir,
	    char *szVobFile,
	    long lDelete, char *szUntertitelOptionen, char *szPaletteFile,
            long lSprache)
{
  char szBefehl[8192];
  long lRC;
  char szNameDerDVD[128];
  char szBildOption[128];
  char szPalette[128];
  char szMenuSprache[10];

  // Wenn keine Bilder uebergeben, erzeugt dvdwizard selbstaendig einen Hintergrund
  strcpy (szBildOption, "");
  if (strlen (szHintergrundBild))
    sprintf (szBildOption, "-b %s", szHintergrundBild);

  // Es werden maximal 24 Zeichen angezeigt.
  strcpy (szNameDerDVD, szTitel);
  if (strlen (szNameDerDVD) > 24)
    szNameDerDVD[24] = 0;

  // Palettefile ?
  strcpy (szPalette, "");
  if (strlen (szPaletteFile))
    sprintf (szPalette, "-P %s", szPaletteFile);

  // Mehr als ein Kapitel ? Wenn nur das Startkapitel, dann leeren.
  // Das Leerzeichen ist ein Komma, daher nur ein Kapitel, wenn kein Komma.
  if (!strstr (szChapter, ","))
    strcpy (szChapter, "");

  // Sprache fuer Menues abhaengig von Programmsprache
  switch (lSprache)
  {
    case 0: strcpy (szMenuSprache, "DE"); break;
    case 1: strcpy (szMenuSprache, "EN"); break;
    case 2: strcpy (szMenuSprache, "FR"); break;
  }

  sprintf (szBefehl, "%s %s -T %s %s %s -o %s -N PAL %s %s ",
	   szNiceRip, dvdwizard_name, szNameDerDVD, 
           szBildOption,
	   szChapter, szDVDDir, szPalette, szDVDWizardVideoAngaben);

  // Audiotracks
  if (strlen (szAudio1))
    {
      strcat (szBefehl, " -a ");
      strcat (szBefehl, szAudio1);
      if (strlen (szAudio2))
	{
	  strcat (szBefehl, ",");
	  strcat (szBefehl, szAudio2);
	}
    }
  strcat (szBefehl, " ");
  // Untertitel
  strcat (szBefehl, szUntertitelOptionen);
  strcat (szBefehl, " ");
  // VOB-File
  strcat (szBefehl, szVobFile);
  printf ("%s\n", szBefehl);
  lRC = system (szBefehl);
  if (lRC == 0 && lDelete > 0)	// erfolgreich, VOB-File loeschen
    {
      sprintf (szBefehl, "rm %s", szVobFile);
      printf ("%s\n", szBefehl);
      system (szBefehl);
    }
  if (lRC == 0)			// Logfile nur bei Erfolg loeschen
    {
      system ("rm dvdwizard.log");
    }
  // Restliche Dateien vom dvdwizard entsorgen
  system ("rm dvdwizard.cmd");
  system ("rm dvdwizard.xml");
  system ("rm -rf cpics");
  system ("rm -rf vmgm");
  system ("rm -rf vtsm");
  system ("rm -rf dvdwizard_*");
}


// Homeverzeichnis: Platzhalter "~" durch vollen Pfad ersetzen
void
insertHomeDir (char *szDir)
{
  char szTmpDir[4096];
  if (strstr (szDir, "~"))
    {
      int i, j = 0;
      szTmpDir[0] = 0;
      for (i = 0; i < strlen (szDir); i++)
	{
	  if (szDir[i] == '~')
	    {
	      strcat (szTmpDir, getenv ("HOME"));
	      j = strlen (szTmpDir);
	    }
	  else
	    {
	      szTmpDir[j] = szDir[i];
	      j++;
	      szTmpDir[j] = 0;
	    }
	}
    }
  else
    {
      // kein Platzhalter, komplett uebernehmen   
      strcpy (szTmpDir, szDir);
    }
  strcpy (szDir, szTmpDir);
}


// Sound abspielen
void
play_sound_if_ready (char * lxdvdrip_wav_name)
{
  long lRC;
  lRC = system ("which playwave > /dev/null");
  if (lRC == 0)
    {
      char szBefehl[1024];
      sprintf (szBefehl, "playwave -r 8000 %s", lxdvdrip_wav_name);
      system (szBefehl);
    }
  else
    {
      lRC = system ("which mplayer > /dev/null");
      if (lRC == 0)
	{
          char szBefehl[1024];
          sprintf (szBefehl, "mplayer %s", lxdvdrip_wav_name);
          system (szBefehl);
	}
    }
}


// DVD vor dem Brennen unmounten 
// Problem: DVD-RW ist gemountet durch Automounter
void unmount_dvd (char * szDevice, char * szTmpDir)
{
  char szBefehl[1024];
  char szTmpFile[1024];

  if (!strstr (szDevice, "/dev")) return;

  printf ("Unmount DVD\n");

  sprintf (szTmpFile, "%s/tmp_mount_dvd", szTmpDir);

  // Mountliste anzeigen, Brenndevice suchen
  sprintf (szBefehl, "mount | grep %s > %s",
                     szDevice, szTmpFile);
  printf ("%s\n", szBefehl);
  system (szBefehl);  

  // Dateigroesse > 0 => gemountet
  long long lGroesse=filesize64 (szTmpFile, szTmpDir);
  if (lGroesse > 0)
  {
    sprintf (szBefehl, "umount %s", szDevice);
    printf ("%s\n", szBefehl);
    system (szBefehl);  
  }

  sprintf (szBefehl, "rm %s", szTmpFile);
  printf ("%s\n", szBefehl);
  system (szBefehl);  
}


// Lies ein Wort aus der Configdatei
// Returncodes: 1 = OK, 2=OK&&EOL, 3=OK&&EOF, 0=EOF
int lies_wort (FILE* f, char* szWort)
{
  int c;
  char szZeichen[2];
  // Uebergabewort leeren
  strcpy (szWort, "");
  szZeichen[1] = 0;
  // Lies bis zum naechsten "richtigen" Zeichen
  for (;;)
  {
    c = fgetc (f);
    if (c==EOF) return 0;
    if (c != 32 && c != 10 && c != 13)	// Erstes richtiges Zeichen, also kein Blank und kein Zeilenende
    {
      szZeichen[0] = c;
      strcpy (szWort, szZeichen);
      break;
    }
  }
  for (;;)
  {
    c = fgetc (f);
    if (c==EOF) 
      return 3; // OK&&EOF
    if (c == 32)	 // Beginn des naechsten Wortes
      return 1; // OK
    if (c == 10 || c == 13)  
      return 2; // OK&&EOL 
    szZeichen[0] = c;
    strcat (szWort, szZeichen);
  }
}


// Hauptfunktion
int
main (int argc, char *argv[])
{
  char title[33];
  dvd_reader_t *dvd;
  ifo_handle_t *ifo_zero, **ifo;
  pgcit_t *vts_pgcit;
  vtsi_mat_t *vtsi_mat;
  vmgi_mat_t *vmgi_mat;
  audio_attr_t *audio_attr;
  video_attr_t *video_attr;
  subp_attr_t *subp_attr;
  pgc_t *pgc;
  int i, j, titles, cell, vts_ttn, title_set_nr;
  char lang_code[3];
  char dvd_device[1024];
  int has_title = 0, ret = 0;
  int max_length = 0, max_track = 0;
  struct stat dvd_stat;
  int opt_a = 0, opt_c = 0, opt_n = 0, opt_p = 0, opt_q = 0, opt_s =
    0, opt_t = 0, opt_d = 0, opt_vts = 0;
  long lAnzahlSekunden = 0;
  long lAnzahlSektoren = 0;
  long lAnzahlKapitel = 0;

  long lAudioTrackInput1 = 0;	// freie Eingabe der Audiotracks
  long lAudioTrackInput2 = 0;
  char szSpracheInput1[128];
  char szSpracheInput2[128];
  char szFormatInput1[128];
  char szFormatInput2[128];
  long long lLaengeInput1;
  long long lLaengeInput2;

  long lAnzahlAudioStreams = 0;
  long lAudioTrackDeutsch = 0;
  long long lPlatzAudio = 0;
  long long lPlatzVideo = 0;
  long long lPlatzAudioDeutsch = 0;
  long long lPlatzAudioEnglisch = 0;
  char szAudioFormatDeutsch[128];
  long lAnzahlChannelDeutsch = 0;
  long lAudioTrackEnglisch = 0;
  char szAudioFormatEnglisch[128];
  long lAnzahlChannelEnglisch = 0;
  long lAnzahlAudioTracks;
  char szAudioFormatAllgemein[128];
  char szZusatzSprache[10];
  char szZusatzAudioFormat[128];
  long lZusatzAudioTrack = 0;
  long long lZusatzPlatzAudio = 0;
  long lZusatzAnzahlChannel;
  long lSprachAuswahl = 0;
  double dFaktor;
  char szFilmVerzeichnis[1024];
  char szAltesFilmVerzeichnis[1024];
  char szRipTracks[128];
  char szBefehl[8192];
  char szBefehl2[8192];
  char szDVDBrenner[512];
  char szVOBPlayer[255];
  char szVideoAngaben[255];
  long lMitVideoAngaben;
  long lBrennProgramm = 0;	// Kein Brennen
  long lWaitBurn = 1;		// Sicherheitsabfrage fuers Warten auf Rohling
  long lMulticopy = 0;          // Mehr als eine Kopie?
  long lPackMethode;
  long lUseVLC = 0;
  long lMenues;
  long lPartcopyAllesMarkieren;
  long lSprache = 0;		// deutsch
  long lShowHelp = 0;		// keine Hilfe anzeigen
  long lAudioDefault;
  long lLoeschen;
  long lHighQuality;
  char szHQChapters[255];
  char szTmpDir[255];
  long lMultiplexer;
  long long lGroesseDVDBytes;
  long long lGroesseDVDBytesMaximal;
  long lDebugLevel = 0;		// moeglichst wenige Meldungen
  char szConfigVersion[128];
  char szChapterString[2048];
  char szChapterFile[128];
  char szDVDName[128];
  char szDVDNameOverwrite[128];
  long lMitKapiteln;
  long lPALDvd = 0;
  char szMkisofsParam[1024];
  char szBurnParam[1024];
  char szPreviewParam[1024];

  char szUntertitelOptionen[1024];
  char szUntertitelSprache1[128];
  char szUntertitelSprache2[128];
  char szPaletteFile[128];
  long lPaletteVorhanden = 0;
  char szPaletteOptions[128];
  long lUntertitel = 0;
  long lUntertitel2 = 0;
  char szUntertitelSprache[128];

  long lTestFree;
  long lDVDSpeed;
  long lRWFormat;

  // Auflistung der verwendeten Programme
  char dvdauthor_name[128];
  char play_cell_name[128];
  char vlc_name[128];
  char buffer_name[128];
  char tccat_name[128];
  char tcextract_name[128];
  char tcrequant_name[128];
  char mplayer_name[128];
  char mplex_name[128];
  char tcmplex_name[128];
  char spumux_name[128];
  char spuunmux_name[128];
  char dvdbackup_name[128];
  char dvdunauthor_name[128];
  char vamps_name[128];
  char tcprobe_name[128];
  char mkisofs_name[128];
  char cdrecord_name[128];
  char growisofs_name[128];
  char eject_name[128];
  char dvdformat_name[128];
  char mpgtx_name[128];
  char transcode_name[128];
  char lxac3scan_name[128];
  char nice_name[128];
  char lxdvdrip_wav_name[1024];
  long lEject;
  long lAnzahlZellen = 0;
  long angle_cell_array[100];
  long long sector_cell_array[100];
  long lOptimiereFaktor=0;
  long lTestZelle;
  long lVTS = 0;
  long lPGC = 0;

  char szOutputFile[256];	// Ausgabe in Datei statt Brennen

  long lTestKapitel = 0;	// Testkapitel rippen
  long lSektorenTestkapitel = 0;
  long lSektorenTestzelle = 0;

  FILE *fConf;
  char szVideoTS[128];
  char szAudioTS[128];
  char szVobTS[128];
  char szVtsTS[128];
  long long lGroesseDVDGesamt = 0;
  long long lGroesseVOBS = 0;
  title_set_info_t *title_set_info = NULL;
  long lGebrannt = 0;
  long dvdcompat = 0;

  char szAngle[128];		// Rip Angle= (Winkel)
  long lAngle;

  char dvdwizard_name[128];
  char dvdwizard_bild[128];
  long lDVDWizard;
  char szDVDWizardVideoAngaben[128];

  long lPlaySound = 0;

  long lPruefen = 1; // Check Inhalt vorm Rippen mit tcprobe

  long lAnzahlUntertitel = 0;
  char szUntertitelListe[100][3];
  long lUntertitelListe[100];

  // Testlaeufe, einige Befehle werden dann u. a. nicht ausgefuehrt
  long lTestlauf = 0;

  // Nice-Level
  char szNiceRip[128], szNiceBurn[128];
  strcpy (szNiceRip, "");
  strcpy (szNiceBurn, "");

  program_name = argv[0];

  // Fuer tc_memcpy()
  ac_mmtest ();
  tc_memcpy_init (0, ac_mmflag ());

  // Verwendete Programme setzen, werden mit Daten aus Konfig ueberschrieben
  strcpy (dvdauthor_name, "dvdauthor");
  strcpy (buffer_name, "buffer");
  strcpy (tccat_name, "tccat");
  strcpy (tcextract_name, "tcextract");
  strcpy (tcrequant_name, "tcrequant");
  strcpy (vlc_name, "vlc");
  strcpy (mplayer_name, "mplayer");
  strcpy (mplex_name, "mplex");
  strcpy (tcmplex_name, "tcmplex");
  strcpy (spumux_name, "spumux");
  strcpy (spuunmux_name, "spuunmux");
  strcpy (dvdbackup_name, "dvdbackup");
  strcpy (dvdunauthor_name, "dvdunauthor");
  strcpy (play_cell_name, "play_cell_lxdvdrip");
  strcpy (vamps_name, "vamps_lxdvdrip");
  strcpy (tcprobe_name, "tcprobe");
  strcpy (mkisofs_name, "mkisofs");
  strcpy (cdrecord_name, "cdrecord");
  strcpy (growisofs_name, "growisofs");
  strcpy (eject_name, "eject");
  strcpy (dvdformat_name, "dvd+rw-format");
  strcpy (mpgtx_name, "mpgtx");
  strcpy (transcode_name, "transcode");
  strcpy (lxac3scan_name, "lxac3scan");
  strcpy (nice_name, "nice");
  strcpy (lxdvdrip_wav_name, "/usr/local/share/lxdvdrip.wav");

  // Gesucht werden Infos zu Audio, Kapiteln und Untertiteln
  opt_a = 1;			// Audio
  opt_c = 1;			// Chapters
  opt_s = 1;			// Zum Auslesen der Untertiteloptionen

  // Programmparameter voreinstellen
  strcpy (dvd_device, "/dev/dvd");	// Default-Device Leser
  opt_t = 0;			// laengsten Track selbst bestimmen
  opt_vts = 0;
  strcpy (szDVDBrenner, "/dev/scd0");	// Device fuer DVD-Brenner
  lSprachAuswahl = 1;		// Standard=deutsch
  strcpy (szFilmVerzeichnis, "/tmp/film-dvd");	// Ablage der gerippten Daten
  lUntertitel = 0;		// Standard ohne Untertitel
  strcpy (szVOBPlayer, "mplayer");	// keine VOB-Vorschau
  lBrennProgramm = 1;		// Brennen per growisofs
  dFaktor = 0;			// selbst ausrechnen
  lPackMethode = 1;		// Vamps als Default
  lMenues = 0;			// Ohne Menues als Default.
  lPartcopyAllesMarkieren = 0;	// Sonderfall partcopy, siehe Kommentar unten
  lAudioDefault = 0;		// immer den ersten passenden Track waehlen
  strcpy (szTmpDir, "/tmp");	// Verzeichnis fuer Dateiablage bei mplayer-Rip
  lLoeschen = 1;		// am Ende alle VOBS loeschen
  lMultiplexer = 1;		// tcmplex als Default
  strcpy (szZusatzSprache, "");	// per Default keine andere Sprache als deutsch und englisch)
  strcpy (szConfigVersion, "");
  strcpy (szChapterString, "");	// Chapter Unterteilung bestimmen
  strcpy (szChapterFile, "");	// Chapter per tcprobe
  strcpy (szDVDName, "");	// DVD-Name, wird spaeter bestimmt
  strcpy (szDVDNameOverwrite, "");	// Falls dieser Name ueberschrieben werden soll
  lMitKapiteln = 1;		// Inkl. Kapitelunterteilung vom Original
  strcpy (szUntertitelOptionen, "");	// ohne Untertitel-Optionen
  strcpy (szUntertitelSprache, "");	// ohne festgelegte Untertitel per Sprache
  lTestFree = 1;		// Testen auf freien Plattenplatz
  lDVDSpeed = 0;		// Speed fuers Brennen
  strcpy (szOutputFile, "");	// Als Standard keine Ausgabe in Datei
  lEject = 0;			// DVD nach Rippen nicht auswerfen
  lRWFormat = 0;		// RWs nicht formatieren vor dem Brennen
  strcpy (szVideoAngaben, "");	// Standard: ohne Videoangaben an dvdauthor
  lMitVideoAngaben = 0;
  strcpy (szMkisofsParam, "");	// Keine Extra-Parameter fuer mkisofs
  strcpy (szBurnParam, "");	// Keine Zusatz-Parameter fuer cdrecord
  strcpy (szPreviewParam, "");	// Keine Zusatz-Parameter fuer Preview
  lHighQuality = 0;		// Normal DVD 9 => 5
  strcpy (szHQChapters, "");	// Kapitel von-bis im High Quality Modus
  strcpy (dvdwizard_name, "dvdwizard");	// DVD wizard fuer Menues
  strcpy (dvdwizard_bild, "");	// Hintergrund-Bild fuer dvdwizard
  lDVDWizard = 0;		// dvdwizard einschalten
  strcpy (szDVDWizardVideoAngaben, "");
  strcpy (szPaletteFile, "");
  strcpy (szAngle, "");		// im Normalfall ohne Angle
  lAngle = 0;

  // Folgende Definitionen, um Compiler Warnings zu fixen (zu gross fuer long)
  lGroesseDVDBytes = (long long) 460000000 *10;
  lGroesseDVDBytesMaximal = (long long) 470000000 *10;

  // Pufferung stdout ausschalten, besser wegen Umlenkung Ausgabe in eine Logdatei.
  setvbuf (stdout, (char *) NULL, _IONBF, 0);

  // Auslesen der Parameter aus einer Datei
  // Zuerst lokal versuchen
  j = strlen (getenv ("HOME"));
  if (j > 7000)
    j = 7000;
  strncpy (szBefehl, getenv ("HOME"), j);
  szBefehl[j] = 0;
  strcat (szBefehl, "/.lxdvdrip.conf");
  fConf = fopen (szBefehl, "r");
  if (!fConf)
    {
      // Ausgabe in allen 3 Sprachen, weil Sprache noch nicht eingestellt ist (steht in Parameterdatei)
      printf
	("DE: Keine Datei ~/.lxdvdrip.conf vorhanden, verwende /etc/lxdvdrip.conf!\n\n");
      printf
	("EN: File ~/.lxdvdrip.conf not found, will use /etc/lxdvdrip.conf!\n\n");
      printf
	("FR: Fichier ~/.lxdvdrip.conf pas trouvé, utilisera /etc/lxdvdrip.conf!\n\n");
      fConf = fopen ("/etc/lxdvdrip.conf", "r");
    }
  if (!fConf)
    {
      printf
	("DE: Keine Datei /etc/lxdvdrip.conf bzw. ~/.lxdvdrip.conf vorhanden, verwende Standardeinstellungen!\n\n");
      printf
	("EN: Neither /etc/lxdvdrip.conf nor ~/.lxdvdrip.conf was found, will use standard parameters!\n\n");
      printf
	("FR: Aucun fichier /etc/lxdvdrip.conf ni ~/.lxdvdrip.conf n'a été trouvé, utilisera les paramètres par défaut!\n\n");
    }
  else
    {
      char szParameter[1024];
      char szDummy[1024];
      int rcLiesWort;
      while ((rcLiesWort=lies_wort (fConf, szParameter)) != 0)
	{
	  // Kommentarzeilen ueberlesen
	  if (szParameter[0] == '#' && rcLiesWort == 2) continue; // Wort ging bereits bis Zeilenende
	  if (szParameter[0] == '#')
	    {
	      int c;
	      for (;;)
		{
		  c = fgetc (fConf);
		  if (c == 10 || c == 13)	// Zeilenende => Abbruch
		    break;
		}
	      continue;
	    }
	  if (strncmp (szParameter, "version=", 8) == 0)
	    {
	      strcpy (szConfigVersion, &szParameter[8]);
	      continue;
	    }
	  if (strncmp (szParameter, "titel=", 6) == 0)
	    {
	      if (szParameter[6] == 'l' || szParameter[6] == 'L')
		{
		  opt_t = -1;
		}
	      else
		{
		  strcpy (szDummy, &szParameter[6]);
		  opt_t = atol (szDummy);
		}
	      continue;
	    }
	  if (strncmp (szParameter, "audio=", 6) == 0)
	    {
	      strncpy (szDummy, &szParameter[6], 1);
	      szDummy[1] = 0;
	      if (strcmp (szDummy, "l") == 0)
		strcpy (szDummy, "5");	// Auswahl per Liste
	      lSprachAuswahl = atol (szDummy);
	      if (lSprachAuswahl == 4)
		{
		  strcpy (szZusatzSprache, &szParameter[8]);
		}
	      continue;
	    }
	  if (strncmp (szParameter, "untertitel=", 11) == 0)
	    {
	      strcpy (szDummy, &szParameter[11]);
	      if ((strlen (szDummy) == 2) && (szDummy[0] < '0' || szDummy[0] > '9'))	// Sprache
		{
		  strcpy (szUntertitelSprache, szDummy);
		  lUntertitel = -2;
		}
	      else
		{
		  if (szDummy[0] == 'l')
		    lUntertitel = -1;	// Auwahl per Liste
		  else if (szDummy[0] == 'f')
		    lUntertitel = -3;	// Forced alle rippen
		  else if (szDummy[0] == 'a')
		    lUntertitel = -4;	// alle rippen
		  else
		    lUntertitel = atol (szDummy);
		}
	      continue;
	    }
	  if (strncmp (szParameter, "faktor=", 7) == 0)
	    {
	      strcpy (szDummy, &szParameter[7]);
	      dFaktor = atof (szDummy);
	      // Falls Faktor gesetzt, diesen Wert speichern für Modus vamps_menu
	      if (dFaktor > 0.01) dFaktorKommandozeile=dFaktor;
	      continue;
	    }
	  if (strncmp (szParameter, "dvdleser=", 9) == 0)
	    {
	      strcpy (dvd_device, &szParameter[9]);
	      continue;
	    }
	  if (strncmp (szParameter, "dvdbrenner=", 11) == 0)
	    {
	      strcpy (szDVDBrenner, &szParameter[11]);
	      continue;
	    }
	  if (strncmp (szParameter, "filmverzeichnis=", 16) == 0)
	    {
	      strcpy (szFilmVerzeichnis, &szParameter[16]);
	      continue;
	    }
	  if (strncmp (szParameter, "file=", 5) == 0)
	    {
	      if (szParameter[5] == '0')
		{
		  strcpy (szOutputFile, "");	// Option ist ausgeschaltet
		}
	      else
		{
		  if (szParameter[5] == '0')
		    {
		      strcpy (szOutputFile, "1");	// Option ist eingeschaltet
		    }
		  else
		    {
		      strcpy (szOutputFile, &szParameter[5]);	// Option ein, Name der Datei fest
		    }
		}
	      continue;
	    }
	  if (strncmp (szParameter, "brennprogramm=", 14) == 0)
	    {
	      strcpy (szDummy, &szParameter[14]);
	      lBrennProgramm = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "multicopy=", 10) == 0)
	    {
	      strcpy (szDummy, &szParameter[10]);
	      lMulticopy = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "chapter=", 8) == 0)
	    {
	      strcpy (szDummy, &szParameter[8]);
	      lMitKapiteln = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "vobplayer=", 10) == 0)
	    {
	      strcpy (szVOBPlayer, &szParameter[10]);
	      continue;
	    }
	  if (strncmp (szParameter, "language=", 9) == 0)
	    {
	      if (strcmp (&szParameter[9], "de") == 0)
		lSprache = 0;
	      if (strcmp (&szParameter[9], "en") == 0)
		lSprache = 1;
	      if (strcmp (&szParameter[9], "fr") == 0)
		lSprache = 2;
	      continue;
	    }
	  if (strncmp (szParameter, "streamtool=", 11) == 0)
	    {
              lMenues = 0;
              lUseVLC = 0;
	      if (strcmp (&szParameter[11], "vamps") == 0)
		lPackMethode = 1;
	      if (strcmp (&szParameter[11], "vamps_menu") == 0)
		{
		  lPackMethode = 1;
		  lMenues = 1;
		}
	      if (strcmp (&szParameter[11], "trans_par") == 0)
		lPackMethode = 2;
	      if (strcmp (&szParameter[11], "vlc_par") == 0)
              {
		lPackMethode = 2;
                lUseVLC = 1;
              } 
	      if (strcmp (&szParameter[11], "mplayer") == 0)
		lPackMethode = 3;
	      if (strcmp (&szParameter[11], "transcode") == 0)
		lPackMethode = 4;
	      if (strcmp (&szParameter[11], "vlc") == 0)
              {
		lPackMethode = 4;
                lUseVLC = 1;
              } 
	      if (strcmp (&szParameter[11], "copy") == 0)
		lPackMethode = 5;
	      if (strcmp (&szParameter[11], "partcopy") == 0)
		lPackMethode = 6;
	      continue;
	    }
	  if (strncmp (szParameter, "audio-default=", 14) == 0)
	    {
	      strcpy (szDummy, &szParameter[14]);
	      lAudioDefault = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "videoformat=", 12) == 0)
	    {
	      strcpy (szDummy, &szParameter[12]);
	      lMitVideoAngaben = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "free=", 5) == 0)
	    {
	      strcpy (szDummy, &szParameter[5]);
	      lTestFree = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "wait-burn=", 10) == 0)
	    {
	      strcpy (szDummy, &szParameter[10]);
	      lWaitBurn = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "tmp=", 4) == 0)
	    {
	      strcpy (szTmpDir, &szParameter[4]);
	      continue;
	    }
	  if (strncmp (szParameter, "delete=", 7) == 0)
	    {
	      strcpy (szDummy, &szParameter[7]);
	      lLoeschen = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "mplex=", 6) == 0)
	    {
	      if (strcmp (&szParameter[6], "tcmplex") == 0)
		lMultiplexer = 1;
	      if (strcmp (&szParameter[6], "mplex") == 0)
		lMultiplexer = 2;
	      continue;
	    }
	  if (strncmp (szParameter, "speed=", 6) == 0)
	    {
	      if (strlen (szParameter) > 6)
		{
		  strcpy (szDummy, &szParameter[6]);
		  lDVDSpeed = atol (szDummy);
		}
	      continue;
	    }
	  if (strncmp (szParameter, "dvdcompat=", 10) == 0)
	    {
	      if (strlen (szParameter) > 10)
		{
		  strcpy (szDummy, &szParameter[10]);
		  dvdcompat = atol (szDummy);
		}
	      continue;
	    }
	  if (strncmp (szParameter, "groesse_dvd=", 12) == 0)
	    {
	      if (strlen (szParameter) > 12)
		{
		  strcpy (szDummy, &szParameter[12]);
		  lGroesseDVDBytes = atoll (szDummy);
		}
	      continue;
	    }
	  if (strncmp (szParameter, "dvdwizard_name=", 15) == 0)
	    {
	      if (strlen (szParameter) > 15)
		{
		  strcpy (dvdwizard_name, &szParameter[15]);
		}
	      continue;
	    }
	  if (strncmp (szParameter, "dvdwizard_bild=", 16) == 0)
	    {
	      if (strlen (szParameter) > 16)
		{
		  strcpy (dvdwizard_bild, &szParameter[16]);
		}
	      continue;
	    }
	  if (strncmp (szParameter, "dvdwizard=", 10) == 0)
	    {
	      if (strlen (szParameter) > 10)
		{
		  lDVDWizard = atol (&szParameter[10]);
		}
	      continue;
	    }
	  if (strstr (szParameter, "dvdauthor_name="))
	    {
	      strcpy (dvdauthor_name, &szParameter[15]);
	      continue;
	    }
	  if (strstr (szParameter, "play_cell_name="))
	    {
	      strcpy (play_cell_name, &szParameter[15]);
	      continue;
	    }
	  if (strstr (szParameter, "vlc_name="))
	    {
	      strcpy (vlc_name, &szParameter[9]);
	      continue;
	    }
	  if (strstr (szParameter, "buffer_name="))
	    {
	      strcpy (buffer_name, &szParameter[12]);
	      continue;
	    }
	  if (strstr (szParameter, "tccat_name="))
	    {
	      strcpy (tccat_name, &szParameter[11]);
	      continue;
	    }
	  if (strstr (szParameter, "tcextract_name="))
	    {
	      strcpy (tcextract_name, &szParameter[15]);
	      continue;
	    }
	  if (strstr (szParameter, "tcrequant_name="))
	    {
	      strcpy (tcrequant_name, &szParameter[15]);
	      continue;
	    }
	  if (strstr (szParameter, "mplayer_name="))
	    {
	      strcpy (mplayer_name, &szParameter[13]);
	      continue;
	    }
	  if (strncmp (szParameter, "mplex_name=", 11) == 0)
	    {
	      strcpy (mplex_name, &szParameter[11]);
	      continue;
	    }
	  if (strstr (szParameter, "tcmplex_name="))
	    {
	      strcpy (tcmplex_name, &szParameter[13]);
	      continue;
	    }
	  if (strstr (szParameter, "spumux_name="))
	    {
	      strcpy (spumux_name, &szParameter[12]);
	      continue;
	    }
	  if (strstr (szParameter, "spuunmux_name="))
	    {
	      strcpy (spuunmux_name, &szParameter[14]);
	      continue;
	    }
	  if (strstr (szParameter, "dvdbackup_name="))
	    {
	      strcpy (dvdbackup_name, &szParameter[15]);
	      continue;
	    }
	  if (strstr (szParameter, "dvdunauthor_name="))
	    {
	      strcpy (dvdunauthor_name, &szParameter[17]);
	      continue;
	    }
	  if (strstr (szParameter, "vamps_name="))
	    {
	      strcpy (vamps_name, &szParameter[11]);
	      continue;
	    }
	  if (strstr (szParameter, "tcprobe_name="))
	    {
	      strcpy (tcprobe_name, &szParameter[13]);
	      continue;
	    }
	  if (strstr (szParameter, "mkisofs_name="))
	    {
	      strcpy (mkisofs_name, &szParameter[13]);
	      continue;
	    }
	  if (strstr (szParameter, "cdrecord_name="))
	    {
	      strcpy (cdrecord_name, &szParameter[14]);
	      continue;
	    }
	  if (strstr (szParameter, "growisofs_name="))
	    {
	      strcpy (growisofs_name, &szParameter[15]);
	      continue;
	    }
	  if (strstr (szParameter, "eject_name="))
	    {
	      strcpy (eject_name, &szParameter[11]);
	      continue;
	    }
	  if (strstr (szParameter, "mpgtx_name="))
	    {
	      strcpy (mpgtx_name, &szParameter[11]);
	      continue;
	    }
	  if (strstr (szParameter, "transcode_name="))
	    {
	      strcpy (transcode_name, &szParameter[15]);
	      continue;
	    }
	  if (strstr (szParameter, "lxac3scan_name="))
	    {
	      strcpy (lxac3scan_name, &szParameter[15]);
	      continue;
	    }
	  if (strstr (szParameter, "nice_name="))
	    {
	      strcpy (nice_name, &szParameter[10]);
	      continue;
	    }
	  if (strstr (szParameter, "lxdvdrip_wav_name="))
	    {
	      strcpy (lxdvdrip_wav_name, &szParameter[18]);
	      continue;
	    }
	  if (strstr (szParameter, "eject="))
	    {
	      strcpy (szDummy, &szParameter[6]);
	      lEject = atol (szDummy);
	      continue;
	    }
	  if (strstr (szParameter, "playsound="))
	    {
	      strcpy (szDummy, &szParameter[10]);
	      lPlaySound = atol (szDummy);
	      continue;
	    }
	  if (strstr (szParameter, "dvd+rw-format="))
	    {
	      strcpy (dvdformat_name, &szParameter[14]);
	      continue;
	    }
	  if (strstr (szParameter, "nice_rip="))
	    {
	      strcpy (szNiceRip, &szParameter[9]);
              if (strstr (szNiceRip, "off"))
                strcpy (szNiceRip, "");
              else
                sprintf (szNiceRip, "%s", &szParameter[9]);
	      continue;
	    }
	  if (strstr (szParameter, "nice_burn="))
	    {
	      strcpy (szNiceBurn, &szParameter[10]);
              if (strstr (szNiceBurn, "off"))
                strcpy (szNiceBurn, "");
              else
                sprintf (szNiceBurn, "%s", &szParameter[10]);
	      continue;
	    }
	  if (strstr (szParameter, "rw-format="))
	    {
	      strcpy (szDummy, &szParameter[10]);

	      lRWFormat = atol (szDummy);
	      continue;
	    }
	  if (strstr (szParameter, "mkisofs_param="))
	    {
	      // Ueberlesen des ersten Zeichens, weil Hochkomma
	      char cTmpChar;
	      strcpy (szMkisofsParam, &szParameter[14]);
	      if (szMkisofsParam[0] == '"' && szMkisofsParam[1] == '"')	// leer? dann ignorieren und wieder leer setzen
		{
		  strcpy (szMkisofsParam, "");
		  continue;
		}
	      szMkisofsParam[0] = ' ';	// erstes Hochkomma abschneiden
	      if (szMkisofsParam[strlen (szMkisofsParam) - 1] == '"')	// " zum Abschluss => String ist vollstaendig
		{
		  szMkisofsParam[strlen (szMkisofsParam) - 1] = ' ';
		  continue;
		}
	      strcat (szMkisofsParam, " ");	// 1 Blank anhaengen
	      // Jetzt Zeichen fuer Zeichen lesen, bis das abschliessende Hochkomma kommt
	      for (;;)
		{
		  fscanf (fConf, "%c", &cTmpChar);
		  if (cTmpChar == '"')
		    break;
		  sprintf (szMkisofsParam + strlen (szMkisofsParam), "%c",
			   cTmpChar);
		  if (strlen (szBurnParam) == (sizeof (szBurnParam) - 1))
		    break;	// wg. Bufferoverflow
		}
	      continue;
	    }
	  if (strstr (szParameter, "burn_param="))
	    {
	      // Ueberlesen des ersten Zeichens, weil Hochkomma
	      char cTmpChar;
	      strcpy (szBurnParam, &szParameter[11]);
	      if (szBurnParam[0] == '"' && szBurnParam[1] == '"')	// leer? dann ignorieren und wieder leer setzen
		{
		  strcpy (szBurnParam, "");
		  continue;
		}
	      szBurnParam[0] = ' ';	// erstes Hochkomma abschneiden
	      if (szBurnParam[strlen (szBurnParam) - 1] == '"')	// " zum Abschluss => String ist vollstaendig
		{
		  szBurnParam[strlen (szBurnParam) - 1] = ' ';
		  continue;
		}
	      strcat (szBurnParam, " ");	// 1 Blank anhaengen
	      // Jetzt Zeichen fuer Zeichen lesen, bis das abschliessende Hochkomma kommt
	      for (;;)
		{
		  fscanf (fConf, "%c", &cTmpChar);
		  if (cTmpChar == '"')
		    break;
		  sprintf (szBurnParam + strlen (szBurnParam), "%c",
			   cTmpChar);
		  if (strlen (szBurnParam) == (sizeof (szBurnParam) - 1))
		    break;	// wg. Bufferoverflow
		}
	      continue;
	    }
	  if (strstr (szParameter, "vobplay_param="))
	    {
	      // Ueberlesen des ersten Zeichens, weil Hochkomma
	      char cTmpChar;
	      strcpy (szPreviewParam, &szParameter[14]);
	      if (szPreviewParam[0] == '"' && szPreviewParam[1] == '"')	// leer? dann ignorieren und wieder leer setzen
		{
		  strcpy (szPreviewParam, "");
		  continue;
		}
	      szPreviewParam[0] = ' ';	// erstes Hochkomma abschneiden
	      if (szPreviewParam[strlen (szPreviewParam) - 1] == '"')	// " zum Abschluss => String ist vollstaendig
		{
		  szPreviewParam[strlen (szPreviewParam) - 1] = ' ';
		  continue;
		}
	      strcat (szPreviewParam, " ");	// 1 Blank anhaengen
	      // Jetzt Zeichen fuer Zeichen lesen, bis das abschliessende Hochkomma kommt
	      for (;;)
		{
		  fscanf (fConf, "%c", &cTmpChar);
		  if (cTmpChar == '"')
		    break;
		  sprintf (szPreviewParam + strlen (szPreviewParam), "%c",
			   cTmpChar);
		  if (strlen (szBurnParam) == (sizeof (szBurnParam) - 1))
		    break;	// wg. Bufferoverflow
		}
	      continue;
	    }
          if (rcLiesWort == 3) break; // nach Wort kam Zeilenende
	}
      fclose (fConf);
    }

    // Nice zusammensetzen
    if (strlen (szNiceRip))
    {
      char szTmpNice[128];
      strcpy (szTmpNice, szNiceRip);
      sprintf (szNiceRip, "%s -%s ", nice_name, szTmpNice);
    }
    if (strlen (szNiceBurn))
    {
      char szTmpNice[128];
      strcpy (szTmpNice, szNiceBurn);
      sprintf (szNiceBurn, "%s -%s ", nice_name, szTmpNice);
    }
    if (strlen (szNiceRip) || strlen (szNiceBurn))
    {
      check_program (nice_name, lSprache, 1);
    }

  // Einstellungen koennen per Kommandozeile ueberschrieben werden
  if (argc >= 2)
    {
      char szDummy[255];
      char szParameter[255];
      long lParam;
      for (lParam = 2; lParam <= argc; lParam++)
	{
	  j = strlen (argv[lParam - 1]);
	  if (j > (sizeof (szParameter) - 1))
	    j = sizeof (szParameter) - 1;
	  strncpy (szParameter, argv[lParam - 1], j);	// wegen Bufferoverflow
	  szParameter[j] = 0;
	  if (strncmp (szParameter, "-t=", 3) == 0)
	    {
	      if (szParameter[3] == 'l' || szParameter[3] == 'L')
		{
		  opt_t = -1;
		}
	      else
		{
		  strcpy (szDummy, &szParameter[3]);
		  opt_t = atol (szDummy);
		}
	      continue;
	    }
	  if (strncmp (szParameter, "-a=", 3) == 0)
	    {
	      strcpy (szZusatzSprache, "");
	      strncpy (szDummy, &szParameter[3], 1);
	      szDummy[1] = 0;
	      if (strcmp (szDummy, "l") == 0)
		strcpy (szDummy, "5");	// Auswahl per Liste
	      lSprachAuswahl = atol (szDummy);
	      if (lSprachAuswahl == 4)
		{
		  strcpy (szZusatzSprache, &szParameter[5]);
		}
	      continue;
	    }
	  if (strncmp (szParameter, "-u=", 3) == 0)
	    {
	      strcpy (szDummy, &szParameter[3]);
	      if ((strlen (szDummy) == 2) && (szDummy[0] < '0' || szDummy[0] > '9'))	// Sprache
		{
		  strcpy (szUntertitelSprache, szDummy);
		  lUntertitel = -2;
		}
	      else
		{
		  if (szDummy[0] == 'l')
		    lUntertitel = -1;	// Auwahl per Liste
		  else if (szDummy[0] == 'f')
		    lUntertitel = -3;	// Forced alle rippen
		  else if (szDummy[0] == 'a')
		    lUntertitel = -4;	// alle rippen
		  else
		    lUntertitel = atol (szDummy);
		}
	      continue;
	    }
	  if (strncmp (szParameter, "-f=", 3) == 0)
	    {
	      strcpy (szDummy, &szParameter[3]);
	      dFaktor = atof (szDummy);
	      // Falls Faktor gesetzt, diesen Wert speichern für Modus vamps_menu
	      if (dFaktor > 0.01) dFaktorKommandozeile=dFaktor;
	      continue;
	    }
	  if (strncmp (szParameter, "-dl=", 4) == 0)
	    {
	      strcpy (dvd_device, &szParameter[4]);
	      continue;
	    }
	  if (strncmp (szParameter, "-db=", 4) == 0)
	    {
	      strcpy (szDVDBrenner, &szParameter[4]);
	      continue;
	    }
	  if (strncmp (szParameter, "-file=", 6) == 0)
	    {
	      if (szParameter[6] == '0')
		{
		  strcpy (szOutputFile, "");	// Option ist ausgeschaltet
		}
	      else
		{
		  strcpy (szOutputFile, &szParameter[6]);
		}
	      continue;
	    }
	  if (strncmp (szParameter, "-fv=", 4) == 0)
	    {
	      strcpy (szFilmVerzeichnis, &szParameter[4]);
	      continue;
	    }
	  if (strncmp (szParameter, "-bp=", 4) == 0)
	    {
	      strcpy (szDummy, &szParameter[4]);
	      lBrennProgramm = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "-mc=", 4) == 0)
	    {
	      strcpy (szDummy, &szParameter[4]);
	      lMulticopy = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "-chap=", 6) == 0)
	    {
	      strcpy (szDummy, &szParameter[6]);
	      lMitKapiteln = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "-dw=", 4) == 0)
	    {
	      strcpy (szDummy, &szParameter[4]);
	      lDVDWizard = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "-vp=", 4) == 0)
	    {
	      strcpy (szVOBPlayer, &szParameter[4]);
	      continue;
	    }
	  if (strncmp (szParameter, "-lang=", 6) == 0)
	    {
	      if (strcmp (&szParameter[6], "de") == 0)
		lSprache = 0;
	      if (strcmp (&szParameter[6], "en") == 0)
		lSprache = 1;
	      if (strcmp (&szParameter[6], "fr") == 0)
		lSprache = 2;
	      continue;
	    }
	  if (strncmp (szParameter, "-ad=", 4) == 0)
	    {
	      strcpy (szDummy, &szParameter[4]);
	      lAudioDefault = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "-free=", 6) == 0)
	    {
	      strcpy (szDummy, &szParameter[6]);
	      lTestFree = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "-st=", 4) == 0)
	    {
              lUseVLC = 0;
              lMenues = 0;
	      if (strcmp (&szParameter[4], "vamps") == 0)
		lPackMethode = 1;
	      if (strcmp (&szParameter[4], "vamps_menu") == 0)
		{
		  lPackMethode = 1;
		  lMenues = 1;
		}
	      if (strcmp (&szParameter[4], "trans_par") == 0)
		lPackMethode = 2;
	      if (strcmp (&szParameter[4], "vlc_par") == 0)
              {
		lPackMethode = 2;
                lUseVLC = 1;
              } 
	      if (strcmp (&szParameter[4], "mplayer") == 0)
		lPackMethode = 3;
	      if (strcmp (&szParameter[4], "transcode") == 0)
		lPackMethode = 4;
	      if (strcmp (&szParameter[4], "vlc") == 0)
              {
		lPackMethode = 4;
                lUseVLC = 1;
              } 
	      if (strcmp (&szParameter[4], "copy") == 0)
		lPackMethode = 5;
	      if (strcmp (&szParameter[4], "partcopy") == 0)
		lPackMethode = 6;
	      continue;
	    }
	  if (strncmp (szParameter, "-wb=", 4) == 0)
	    {
	      strcpy (szDummy, &szParameter[4]);
	      lWaitBurn = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "-tmp=", 5) == 0)
	    {
	      strcpy (szTmpDir, &szParameter[5]);
	      continue;
	    }
	  if (strncmp (szParameter, "-d=", 3) == 0)
	    {
	      strcpy (szDummy, &szParameter[3]);
	      lLoeschen = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "-format=", 8) == 0)
	    {
	      strcpy (szDummy, &szParameter[8]);
	      lRWFormat = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "-vf=", 4) == 0)
	    {
	      strcpy (szDummy, &szParameter[4]);
	      lMitVideoAngaben = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "-mp=", 4) == 0)
	    {
	      if (strcmp (&szParameter[4], "tcmplex") == 0)
		lMultiplexer = 1;
	      if (strcmp (&szParameter[4], "mplex") == 0)
		lMultiplexer = 2;
	      continue;
	    }
	  if (strncmp (szParameter, "-lab=", 5) == 0)	// Volume-ID / Label
	    {
	      strcpy (szDVDNameOverwrite, &szParameter[5]);
	      continue;
	    }
	  if (strncmp (szParameter, "-sp=", 4) == 0)
	    {
	      if (strlen (szParameter) > 4)
		{
		  strcpy (szDummy, &szParameter[4]);
		  lDVDSpeed = atol (szDummy);
		}
	      continue;
	    }
	  if (strncmp (szParameter, "-hq=", 4) == 0)	// High Quality Modus 
	    {
	      if (strlen (szParameter) > 4)
		{
		  strcpy (szDummy, &szParameter[4]);
		  lHighQuality = atol (szDummy);
		}
	      continue;
	    }
	  if (strncmp (szParameter, "-angle=", 7) == 0)	// Rip Angle 
	    {
	      if (strlen (szParameter) > 7)
		{
		  strcpy (szDummy, &szParameter[7]);
		  lAngle = atol (szDummy);
		}
	      continue;
	    }
	  if (strncmp (szParameter, "-debug=", 7) == 0)
	    {
	      strcpy (szDummy, &szParameter[7]);
	      lDebugLevel = atol (szDummy);
	      continue;
	    }
	  if (strncmp (szParameter, "-check=", 7) == 0)
	    {
	      strcpy (szDummy, &szParameter[7]);
	      lPruefen = atol (szDummy);
	      continue;
	    }
	  if (strcmp (szParameter, "-h") == 0 ||
	      strcmp (szParameter, "--help") == 0)
	    {
	      lShowHelp = 1;
	      continue;
	    }
	  if (strcmp (szParameter, "-v") == 0 ||
	      strcmp (szParameter, "--version") == 0)
	    {
	      switch (lSprache)
		{
		case 0:
		  {
		    printf
		      ("\nlxdvdrip Version %s.\n\nHilfe mit 'lxdvdrip -h'\n",
		       VERSION);
		    if (strlen (szConfigVersion))
		      printf ("Version von /etc/lxdvdrip.conf: %s\n",
			      szConfigVersion);
		    printf ("\nVerwendete Programme:\n\n");
		    break;
		  }
		case 1:
		  {
		    printf
		      ("\nlxdvdrip Version %s.\n\nHelp with 'lxdvdrip -h'\n",
		       VERSION);
		    if (strlen (szConfigVersion))
		      printf ("Version from /etc/lxdvdrip.conf: %s\n",
			      szConfigVersion);
		    printf ("\nInstalled programs:\n\n");
		    break;
		  }

		case 2:
		  {
		    printf
		      ("\nlxdvdrip version %s.\n\nAide par 'lxdvdrip -h'\n",
		       VERSION);
		    if (strlen (szConfigVersion))
		      printf ("Version de /etc/lxdvdrip.conf: %s\n",
			      szConfigVersion);
		    printf ("\nProgrammes installés:\n\n");
		    break;
		  }
		}
	      printf ("%s\n", dvdauthor_name);
	      printf ("%s\n", vlc_name);
	      printf ("%s\n", buffer_name);
	      printf ("%s\n", tccat_name);
	      printf ("%s\n", tcextract_name);
	      printf ("%s\n", tcrequant_name);
	      printf ("%s\n", mplayer_name);
	      printf ("%s\n", mplex_name);
	      printf ("%s\n", tcmplex_name);
	      printf ("%s\n", spumux_name);
	      printf ("%s\n", spuunmux_name);
	      printf ("%s\n", dvdbackup_name);
	      printf ("%s\n", dvdunauthor_name);
	      printf ("%s\n", play_cell_name);
	      printf ("%s\n", vamps_name);
	      printf ("%s\n", tcprobe_name);
	      printf ("%s\n", mkisofs_name);
	      printf ("%s\n", cdrecord_name);
	      printf ("%s\n", growisofs_name);
	      printf ("%s\n", dvdformat_name);
	      printf ("%s\n", mpgtx_name);
	      printf ("%s\n", transcode_name);
	      printf ("%s\n", lxac3scan_name);
	      printf ("%s\n", dvdauthor_name);
	      printf ("%s\n\n", eject_name);
	      return 0;
	    }
	  // Parameter ist nicht zu verarbeiten, Abbruch
	  switch (lSprache)
	    {
	    case 0:
	      printf
		("\nDer Parameter '%s' ist unbekannt, bitte ueberpruefen!\n\n",
		 szParameter);
	      break;
	    case 1:
	      printf ("\nThe parameter '%s' is unknown!\n\n", szParameter);
	      break;
	    case 2:
	      printf ("\nOption '%s' inconnue !\n\n", szParameter);
	      break;
	    }
	  return 0;
	}
    }

  // Wenn Pruefen abgeschaltet ist, auch bei Transcode den Testripp ausschalten
  if (lPruefen == 0 &&                                              // Pruefen ausgeschaltet
     (lUseVLC == 0 && (lPackMethode >= 2 && lPackMethode <= 4)) &&  // Transcode ohne vlc
      dFaktor < 0                                                   // Testrip
     )
  {
    dFaktor = 0;  // Berechnen mit lxdvdrip-Methode
  }
  // bei VLC immer einen Testrip, außer Faktor > 0, also von aussen gesetzt
  if (lUseVLC > 0 && dFaktor == 0) // nimm VLC, berechne Faktor
  {
    dFaktor = -1;  // Testrip mit vlc
  }

  // Hilfe anzeigen ?
  if (lShowHelp)
    {
      switch (lSprache)
	{
	case 0:		// Hilfe auf deutsch
	  {
	    printf ("Hilfe zu lxdvdrip %s\n", VERSION);
	    printf ("======================\n\n");
	    printf ("Aufruf: lxdvdrip [-parameter=wert]\n\n");
	    printf
	      ("Es muessen nur Parameter angegeben werden, die anders gesetzt sind als Standard\n");
	    printf ("oder in der config-Datei (/etc/lxdvdrip.conf).\n");
	    printf
	      ("Die Voreinstellung steht in Klammern hintern jedem Parameter.\n\n");
	    printf
	      ("-st=Streamtool       : vamps, mplayer, transcode, trans_par (Transcode\n");
	    printf
	      ("                       parallel), vlc, vlc_par, copy, partcopy (Titel waehlen) (-st=trans_par)\n");
	    printf
	      ("-mp=mplex            : Multiplexer, nur bei -st=mplayer beruecksichtigt,\n");
	    printf
	      ("                       alternativ mplex auswaehlbaer bei Problemen mit tcmplex\n");
	    printf ("                       (-mp=tcmplex)\n");
	    printf
	      ("-tmp=Verzeichnis     : Verzeichnis fuer temp-Dateien beim Rippen mit mplayer\n");
	    printf ("                       (-tmp=/tmp)\n");
	    printf
	      ("-t=TitelNr           : Nr des zu rippenden Titels, bestimmen mit \"lsdvd\", in\n");
	    printf
	      ("                       der Regel der laengste Titel, 0=laengster Titel wird\n");
	    printf
	      ("                       berechnet, l=Auswahl aus Liste (-t=0)\n");
	    printf
	      ("-hq=x                : High Quality Backup, DVD auf 2 Rohlinge verteilen,\n");
	    printf
	      ("                       -hq=1=>1. Haelfte, -hq=2=>2. Haelfte (-hq=0)\n");
	    printf ("\nSeite 2: Enter druecken");
	    eatToNL (stdin);
	    printf
	      ("-vf=x                : dvdauthor mit -v (Video Format) (0=nein,1=ja) (-vf=0)\n");
	    printf
	      ("-a=Sprachauswahl     : -a=1: nur deutsch, -a=2: nur englisch, -a=3: deutsch+\n");
	    printf
	      ("                       englisch, -a=4,xy in Sprache xy (z. B. it fuer\n");
	    printf
	      ("                       italienisch), -a=l fuer freie Audiotrackauswahl per Liste\n");
	    printf ("                       (-a=1)\n");
	    printf
	      ("-ad=AudioDefault     : 0=erster passender Track in Sprache, 1=AC3 mit 6 Kanal\n");
	    printf
	      ("                       vor AC3/2, 2=DTS zuerst (-ad=0)\n");
	    printf
	      ("-lab=VolumeID        : Name der DVD (Volume-ID/Label)\n");
	    printf
	      ("-chap=Mit Kapiteln   : 0=ohne Kapitel, 1=mit Kapiteln (-chap=1)\n");
	    printf
	      ("-u=Untertitel-Nr     : Nr des zu rippenden Untertitels (Infos ueber lsdvd),\n");
	    printf
	      ("                       0=ohne Untertitel, l=Anzeige Liste&auswaehlen, alternativ\n");
	    printf
	      ("                       Sprache, z. B. \"-u=de\", f=\"Forced\" Untertitel, a=alle (-u=0)\n");
	    printf
	      ("-fv=Film_Verzeichnis : Verzeichnis, wo die gerippten Daten abgelegt werden\n");
	    printf ("                       (-fv=/tmp/film-dvd)\n");
	    printf
	      ("-f=Faktor            : Faktor wird selbst berechnet im Normalfall, hier kann\n");
	    printf
	      ("                       jedoch auch ein anderer Wert gesetzt werden, bei \"-f=-1\"\n");
	    printf
	      ("                       erfolgt Testrip eines Kapitels (-f=0)\n");
	    printf
	      ("-dl=DVD-Device       : Device-Name des DVD-Leselaufwerkes (-dl=/dev/dvd)\n");
	    printf
	      ("-db=Brenner-Device   : Device fuer Brenner (-db=/dev/scd0)\n");
	    printf ("\nSeite 3: Enter druecken");
	    eatToNL (stdin);
	    printf
	      ("-bp=Brenn-Programm   : 1=growisofs, 2=cdrecord, 3=cdrecord on the\n");
	    printf
	      ("                       fly, 4=ISO-Image per mkisofs,5=ISO-\n");
	    printf
	      ("                       Image mit Volume-ID als Name,0=kein Brennen (-bp=1)\n");
            printf ("-mc=x                : Mehrere Kopien (1=ja, 0=nein) (-mc=0)\n");
	    printf ("-sp=x                : Brenngeschwindigkeit (-sp=0)\n");
	    printf
	      ("-format=             : 1=RW formatieren, 0=RW nicht formatieren (-format=0)\n");
	    printf
	      ("-wb=Frage vor Brennen: Sicherheitsabfrage, Rohling einlegen vor Brennen \n");
	    printf ("                       (1=ja, 0=nein) (-wb=1)\n");
	    printf
	      ("-vp=VOB-Player       : Medienplayer fuer Vorschau, off=keine Vorschau\n");
	    printf ("                       (-vp=mplayer)\n");
	    printf
	      ("-lang=en             : Umschalten auf englische Sprache\n");
	    printf
	      ("-d=loeschen          : Am Ende Film-Verzeichnis loeschen (0=nein, 1=ja) (-d=1)\n");
	    printf
	      ("-free=Testen?        : Pruefe auf freien Plattenplatz vorm Rippen (0=nein, 1=ja)\n");
	    printf ("                       (-free=1)\n");
            printf
	      ("-check=Trackcheck?   : Pruefe auf Audiotracks mit tcprobe (0=nein, 1=ja) (-check=1)\n");
	    printf
	      ("-file=Ausgabedatei   : Statt dvdauthor+Brennen Ergebnis als Datei, z. B.\n");
	    printf
	      ("                       \"-file=/tmp/dvd.vob\", -file=0=>Option aus\n");
	    printf
	      ("-dw=x                : 1=dvdwizard ein, 0=dvdwizard aus (0)\n");
	    printf ("-angle=x             : Winkel x rippen (0)\n");
	    printf
	      ("-h                   : Diese Hilfe zeigen (ebenso --help)\n");
	    printf
	      ("-v                   : Version ausgeben (ebenso --version)\n");
	    printf ("Beispiel: # lxdvdrip -t=1\n");
	    printf
	      ("Falls jeweils 2 Audiospuren fuer eine Sprache vorhanden sind (Bsp: deutsch)\n");
	    printf
	      ("in ac3 und dts, wird als Standard die dts-Spur genommen, da Qualitaet besser\n");
	    printf
	      ("(Option: -ad=2). Bei 2 AC3-Spuren wird die mit der hoeheren Kanalzahl verwendet\n");
	    printf ("(Option -ad=1).\n");
	    break;
	  }
	case 1:		// english Help Text
	  {
	    printf ("lxdvdrip %s Help\n", VERSION);
	    printf ("==================\n\n");
	    printf ("Start Program: lxdvdrip [-parameter=value]\n\n");
	    printf
	      ("You need only to give those parameters with different values as defined in the\n");
	    printf ("config-file (/etc/lxdvdrip.conf).\n");
	    printf
	      ("The default values are printed in brackets () behind the parameters.\n\n");
	    printf
	      ("-st=Streamtool       : vamps, mplayer, transcode, trans_par (Transcode\n");
	    printf
	      ("                       parallel), vlc, vlc_par, copy, partcopy (Select Titles) (-st=trans_par)\n");
	    printf
	      ("-mp=mplex            : Multiplexer, only with -st=mplayer, use mplex instead of\n");
	    printf
	      ("                       tcmplex when having problems with tcmplex (-mp=tcmplex)\n");
	    printf
	      ("-tmp=Directory       : Directory for temporary files for ripping with mplayer\n");
	    printf ("                       (-tmp=/tmp)\n");
	    printf
	      ("-t=TitleNr           : Nr of the ripping title, \"lsdvd\" shows all titles, \n");
	    printf
	      ("                       normally the longest title, 0=longest title will be \n");
	    printf
	      ("                       calculated by lxdvdrip, l=select from list (-t=0)\n");
	    printf
	      ("-hq=x                : High Quality Backup, copy 1 DVD-9 => 2 DVD-5,\n");
	    printf
	      ("                       -hq=1=>1. Part, -hq=2=>2. Part (-hq=0)\n");
	    printf ("\nPage 2: Please press Enter\n");
	    eatToNL (stdin);
	    printf
	      ("-vf=x                : dvdauthor with -v (Video Format) (0=no,1=yes) (-vf=0)\n");
	    printf
	      ("-a=Audio language    : -a=1: german only, -a=2: english only, -a=3: german+\n");
	    printf
	      ("                       english, -a=4,xy in language xy, i. E. -a=4,f for french\n");
	    printf
	      ("                       -a=l for list with free selection of audiotracks (-a=1)\n");
	    printf
	      ("-ad=AudioDefault     : 0=first track in chosen language, 1=AC3 with 6 channels \n");
	    printf
	      ("                       preferred to AC3/2, 2=DTS first (-ad=0)\n");
	    printf ("-lab=VolumeID        : Name of DVD (Volume-ID/Label)\n");
	    printf
	      ("-chap=chapter        : 0=without chapters, 1=with chapters (-chap=1)\n");
	    printf
	      ("-u=Subpicture-Nr.    : Nr of the ripping Subpicture-Track (infos with lsdvd), \n");
	    printf
	      ("                       0=without subtitles, l=shows list&input, alternative\n");
	    printf
	      ("                       language, i. E. \"-u=de\", f=\"Forced\" subtitles, a=all (-u=0)\n");
	    printf
	      ("-fv=Film-Directory   : Directory for the ripping files (-fv=/tmp/film-dvd)\n");
	    printf
	      ("-f=Factor            : Normally factor for requant will be calculated, but you \n");
	    printf
	      ("                       can overwrite the factor with your value, with \"-f=-1\"\n");
	    printf
	      ("                       lxdvdrip makes a testrip of one chapter to calculate \n");
	    printf ("                       factor (-f=0)\n");
	    printf
	      ("-dl=DVD-Device       : Device-Name of DVD-Reader (-dl=/dev/dvd)\n");
	    printf
	      ("-db=Burner-Device    : Device of the Burner (-db=/dev/scd0)\n");
	    printf
	      ("-bp=Burn-Program     : 1=growisofs, 2=cdrecord, 3=cdrecord on the fly,\n");
	    printf
	      ("                       4=ISO-Image/mkisofs,5=ISO with VolumeID,0=no Burning (-bp=1)\n");
            printf ("-mc=x                : Multi Copies (1=yes, 0=no) (-mc=0)\n");
	    printf ("\nPage 3: Please press Enter\n");
	    eatToNL (stdin);
	    printf ("-sp=x                : burning Speed (-sp=0)\n");
	    printf
	      ("-wb=Wait for Burn    : Program asks you for DVD-R before burning (1=yes, 0=no)\n");
	    printf ("                       (-wb=1)\n");
	    printf ("-format=             : 1=RW format, 0=no (-format=0)\n");
	    printf
	      ("-vp=VOB-Player       : player for VOB-preview, off=no preview (-vp=mplayer)\n");
	    printf
	      ("-lang=en             : Program in english (Default german)\n");
	    printf
	      ("-d=delete            : Delete VOB-Files after burning (0=no, 1=yes) (-d=1)\n");
	    printf
	      ("-free=check          : Check for free disk space before ripping (0=no, 1=yes)\n");
	    printf ("                       (-free=1)\n");
            printf
	      ("-check=Trackcheck?   : Check for Audiotracks with tcprobe (0=no, 1=yes) (-check=1)\n");
	    printf
	      ("-file=Outputfile     : Instead of dvdauthor+growisofs write result in a file, \n");
	    printf
	      ("                       i. E. \"-file=/tmp/dvd.vob\", -file=0=>Option off\n");
	    printf
	      ("-dw=x                : 1=dvdwizard on, 0=dvdwizard off (0)\n");
	    printf ("-angle=x             : rip Angle x (0)\n");
	    printf ("-h                   : Show this help (--help)\n");
	    printf ("-v                   : Show version (--version)\n");
	    printf ("Example: # lxdvdrip -t=1\n");
	    printf
	      ("If there are 2 audio tracks in the same language, lxdvdrip takes the dts-track\n");
	    printf
	      ("as default (better quality, option to use: -ad=2). If there are 2 AC3-tracks,\n");
	    printf
	      ("lxdvdrip takes that one with the highest number of channels (Option -ad=1).\n");
	    break;
	  }
	case 2:		// aide en français
	  {
	    printf ("aide pour lxdvdrip %s\n", VERSION);
	    printf ("=====================\n\n");
	    printf ("Syntaxe: lxdvdrip [-option=valeur]\n\n");
	    printf
	      ("Vous ne devez spécifier que les options qui diffèrent de la valeur par défaut\n");
	    printf
	      ("spécifiée dans le fichier de configuration (/etc/lxdvdrip.conf).\n");
	    printf
	      ("Si aucune valeur n'est spécifiée, ni dans la ligne de commande ni dans le fichier de configuration\n");
	    printf
	      ("c'est la valeur donnée ici entre parenthèse qui est utilisée.\n\n");
	    printf
	      ("-st=extracteur       : vamps, mplayer, transcode, trans_par (Transcode\n");
	    printf
	      ("                       parallèle), vlc, vlc_par, copy, partcopy (Choix de titres) (-st=trans_par)\n");
	    printf
	      ("-mp=multiplexeur     : uniquement si -st=mplayer, utilisez mplex au lieu de\n");
	    printf
	      ("                       tcmplex si celui-ci pose problème (-mp=tcmplex)\n");
	    printf
	      ("-tmp=répertoire      : stockage des fichiers temporaires pour mplayer\n");
	    printf ("                       (-tmp=/tmp)\n");
	    printf
	      ("-t=numéro_titre      : numéro du titre à extraire, \"lsdvd\" pour les afficher, \n");
	    printf
	      ("                       mettez 0 pour choisir automatiquement le plus long\n");
	    printf
	      ("                       qui est le plus souvent celui voulu,\n");
	    printf
	      ("                       l=pour choisir titre dans la liste des titres du DVD (-t=0)\n");
	    printf
	      ("-hq=x                : Copie Haute Qualité, copie 1 DVD-9 => 2 DVD-5,\n");
	    printf
	      ("                       -hq=1=>1ère partie, -hq=2=>2ème partie (-hq=0)\n");
	    printf ("\nEntrée pour continuer\n");
	    eatToNL (stdin);
	    printf
	      ("-vf=x                : dvdauthor avec -v (Video Format) (0=non,1=avec) (-vf=0)\n");
	    printf
	      ("-a=langue audio      : -a=1: allemand, -a=2: anglais, -a=3: allemand+\n");
	    printf
	      ("                       anglais, -a=4,xy prendre la langue xy, p.ex. -a=4,fr pour français\n");
	    printf
	      ("                       -a=l pour choisir parmi les langues disponibles sur le DVD (-a=1)\n");
	    printf
	      ("-ad=format audio     : 0=première piste dans cette langue, 1=AC3 avec le plus de\n");
	    printf
	      ("                       canaux possible, 2=DTS si possible (-ad=0)\n");
	    printf ("-lab=IDvolume        : label (VolumeID) du DVD\n");
	    printf
	      ("-chap=chapitrage     : 0=sans chapitrage, 1=avec chapitrage (-chap=1)\n");
	    printf
	      ("-u=piste S/T         : numéro de piste de Sous-Titres (voir avec \"lsdvd\"), \n");
	    printf
	      ("                       0=pas de S/T, l=choisir dans la liste des S/T, ou indiquer la\n");
	    printf
	      ("                       langue, p.ex. \"-u=de\", f=\"Forced\" Sous-Titres, a=Toutes (-u=0)\n");
	    printf
	      ("-fv=répertoire       : répertoire d'extraction (-fv=/tmp/film-dvd)\n");
	    printf
	      ("-f=Facteur           : le facteur de requantification est normalement calculé,\n");
	    printf
	      ("                       mais vous pouvez aussi forcer une valeur,\n");
	    printf
	      ("                       ou entrer \"-f=-1\" pour faire un test sur un chapitre (-f=0)\n");
	    printf
	      ("-dl=lecteur DVD      : nom du lecteur de DVD (-dl=/dev/dvd)\n");
	    printf
	      ("-db=graveur DVD      : nom du graveur de DVD (-db=/dev/scd0)\n");
	    printf
	      ("-bp=prog. de gravure : 1=growisofs, 2=cdrecord, 3=cdrecord à la volée\n");
	    printf
	      ("                       4=ISO-Image/mkisofs, 5=ISO-Image/Volume-ID, 0=ne pas graver (-bp=1)\n");
	    printf
	      ("-mc=x                : Multi Copies (1=oui, 0=non) (-mc=0)\n");
	    printf ("\nEntrée pour continuer\n");
	    eatToNL (stdin);
	    printf ("-sp=x                : Vitesse de gravure (-sp=0)\n");
	    printf
	      ("-wb=attente gravure  : attendre confirmation de l'utilisateur avant gravure (1=oui, 0=non)\n");
	    printf ("                       (-wb=1)\n");
	    printf
	      ("-format=formater     : pour les RW, 1=formater avant gravure, 0=non (-format=0)\n");
	    printf
	      ("-vp=prog.visu        : programme pour prévisualiser les VOB, off=pas de prévisu (-vp=mplayer)\n");
	    printf
	      ("-lang=interface      : langue d'interface (fr, en, de) (-lang=de)\n");
	    printf
	      ("-d=effacer           : effacer les fichiers VOB après gravure (0=non, 1=oui) (-d=1)\n");
	    printf
	      ("-free=vérifier       : vérifier l'espace disque avant extraction (0=non, 1=oui)\n");
	    printf ("                       (-free=1)\n");
            printf
	      ("-check=vérifier audio: vérifier Audiotracks avec tcprobe (0=non, 1=oui) (-check=1)\n");
	    printf
	      ("-file=fichier        : ne pas graver, mettre l'image résultante dans un fichier, \n");
	    printf
	      ("                       p.ex. \"-file=/tmp/dvd.vob\", -file=0=>non fichier\n");
	    printf ("-dw=x                : dvdwizard? 0=non, 1=oui (0)\n");
	    printf ("-angle=x             : rip Angle x (0)\n");
	    printf
	      ("-h                   : afficher ce texte (aussi --help)\n");
	    printf
	      ("-v                   : afficher la version (aussi --version)\n");
	    printf ("Example: # lxdvdrip -t=1\n");
	    printf ("Note sur l'option -ad:\n");
	    printf
	      ("   S'il y a 2 pistes audio dans la même langue et que l'on a spécifié \"-ad=2\",\n");
	    printf
	      ("on utilise par défaut la piste au format dts (meilleure qualité). \n");
	    printf
	      ("   S'il y a 2 pistes au format AC3 et que l'on a spécifié \"-ad=1\",\n");
	    printf
	      ("on utilise celle dont le nombre de canaux est le plus élevé\n");
	    printf
	      ("   La valeur par défaut est \"-ad=0\" qui utilise la première piste du langage voulu.\n");
	    break;
	  }
	}
      return 0;
    }

  // Eventuelle Platzhalter fuers Homedir ersetzen
  insertHomeDir (szFilmVerzeichnis);
  insertHomeDir (szTmpDir);

  // Wenn mit Menues, alle Untertitel mitrippen
  if (lPackMethode == 1 && lMenues>0) 
  {
    lUntertitel = -4;
  }

  switch (lSprache)
    {
    case 0:
      {
	printf ("Das Programm startet mit folgenden Einstellungen:\n\n");
	printf ("Sprache:       %ld (0=deutsch,1=englisch,2=franzoesisch)\n",
		lSprache);
	printf
	  ("Streamtool:    %ld (1=vamps, vamps_menu, 2=transcode/vlc parallel, 3=mplayer, 4=transcode/vlc, 5=copy, 6=partcopy)\n",
	   lPackMethode);
	printf ("Multiplexer:   %ld (1=tcmplex, 2=mplex)\n", lMultiplexer);
	printf ("Tmp-Dir:       %s\n", szTmpDir);
	printf ("Titel:         %ld (0=laengsten Titel selbst bestimmen)\n",
		(long) opt_t);
	if (lAngle > 0)
	  printf ("Winkel:        %ld\n", lAngle);
	printf
	  ("Audio-Track:   %ld/%s (1=deutsch, 2=englisch, 3=deutsch+englisch, 4=extra Sprache waehlen, 5=Tracks eingeben)\n",
	   lSprachAuswahl, szZusatzSprache);
	printf
	  ("AudioDefault:  %ld (0=erster passender Track in Sprache, 1=AC3 mit 6 Kanal vor AC3/2, 2=DTS zuerst)\n",
	   lAudioDefault);
	if (!strlen (szUntertitelSprache))
	  printf
	    ("Untertitel:    %ld (Titel-Nr, 0=keine Untertitel, -1=Liste, -3=Forced, -4=alle)\n",
	     lUntertitel);
	else
	  printf ("Untertitel:    %s\n", szUntertitelSprache);
	printf
	  ("Kapitel:       %ld (0=nein, 1=ja, per lxdvdrip, 2=mit tcprobe bestimmen)\n",
	   lMitKapiteln);
	printf
	  ("Verzeichnis:   %s (Verzeichnis fuer Film, z. B. /tmp/film-dvd)\n",
	   szFilmVerzeichnis);
	printf ("Files loeschen:%ld (0=nein, 1=ja)\n", lLoeschen);
	printf ("Faktor:        %f\n", dFaktor);
	printf ("DVD-Leser:     %s (Device-Name)\n", dvd_device);
	if (!strlen (szOutputFile))
	  {
	    printf ("DVD-Brenner:   %s (Device-Name)\n", szDVDBrenner);
	    printf
	      ("Brennprogramm: %ld (1=growisofs,2=cdrecord,3=cdrecord on the fly, 4=mkisofs,5=mkisofs/VolumeID,0=aus)\n",
	       lBrennProgramm);
	    printf ("RW formatieren:%ld (0=nein, 1=ja)\n", lRWFormat);
	    printf ("Warte auf DVDR:%ld (1=ja, 0=nein)\n", lWaitBurn);
	    printf
	      ("VOB-Player:    %s (Name des Players fuer Vorschau, Standard mplayer, off=keine Vorschau)\n",
	       szVOBPlayer);
	    printf ("DVDSpeed:      %ld\n", lDVDSpeed);
	  }
	else
	  {
	    printf ("Ausgabe in Datei: %s\n", szOutputFile);
	  }
	if (lDebugLevel)
	  {
	    printf ("Debug-Level:   %ld\n", lDebugLevel);
	  }
	break;
      }
    case 1:
      {
	printf ("Starting with these settings:\n\n");
	printf ("Language       %ld (0=german,1=english,2=french)\n",
		lSprache);
	printf
	  ("Streamtool:    %ld (1=vamps, vamps_menu, 2=transcode/vlc parallel, 3=mplayer,4=transcode/vlc, 5=copy, 6=partcopy)\n",
	   lPackMethode);
	printf ("Multiplexer:   %ld (1=tcmplex, 2=mplex)\n", lMultiplexer);
	printf ("Tmp-Dir:       %s\n", szTmpDir);
	printf ("Title:         %ld (0=calculate longest title)\n",
		(long) opt_t);
	if (lAngle > 0)
	  printf ("Angle:         %ld\n", lAngle);
	printf
	  ("Audio-Track:   %ld/%s (1=german, 2=english, 3=german+english, 4=select other language, 5=input title Nr.)\n",
	   lSprachAuswahl, szZusatzSprache);
	printf
	  ("AudioDefault:  %ld (0=first track in chosen language, 1=AC3 with 6 channels preferred to AC3/2, 2=DTS first)\n",
	   lAudioDefault);
	if (!strlen (szUntertitelSprache))
	  printf
	    ("Subpicture:    %ld (Subpicture-Track-No, 0=no subpictures, -1=list, -3=Forced, -4=all)\n",
	     lUntertitel);
	else
	  printf ("Subpicture:    %s\n", szUntertitelSprache);
	printf
	  ("Chapter:       %ld (0=no, 1=yes, with lxdvdrip, 2=yes, with tcprobe)\n",
	   lMitKapiteln);
	printf
	  ("Directory:     %s (Directory for film, i. e. /tmp/film-dvd)\n",
	   szFilmVerzeichnis);
	printf ("Files delete:  %ld (0=no, 1=yes)\n", lLoeschen);
	printf ("Factor:        %f\n", dFaktor);
	printf ("DVD-Reader:    %s (Device-Name)\n", dvd_device);
	if (!strlen (szOutputFile))
	  {
	    printf ("DVD-Burner:    %s (Device-Name)\n", szDVDBrenner);
	    printf
	      ("Burn-Prog:     %ld (1=growisofs,2=cdrecord,3=cdrecord on the fly,4=mkisofs,5=mkisofs/VolumeID,0=off)\n",
	       lBrennProgramm);
	    printf ("RW format:     %ld (0=no, 1=yes)\n", lRWFormat);
	    printf ("Wait for DVDR: %ld (1=yes, 0=no)\n", lWaitBurn);
	    printf
	      ("VOB-Player:    %s (Name of player for preview, default: mplayer, off=no preview)\n",
	       szVOBPlayer);
	    printf ("DVDSpeed:      %ld\n", lDVDSpeed);
	  }
	else
	  {
	    printf ("Result in a File: %s\n", szOutputFile);
	  }
	if (lDebugLevel)
	  {
	    printf ("Debug-Level:   %ld\n", lDebugLevel);
	  }
	break;
      }
    case 2:
      {
	printf ("Lancement avec les options suivantes :\n\n");
	printf ("Langue:        %ld (0=german,1=english,2=français)\n",
		lSprache);
	printf
	  ("Extracteur:    %ld (1=vamps, vamps_menu, 2=transcode/vlc parallèle, 3=mplayer,4=transcode/vlc, 5=copy, 6=partcopy)\n",
	   lPackMethode);
	printf ("Multiplexeur:  %ld (1=tcmplex, 2=mplex)\n", lMultiplexer);
	printf ("Rép.temp:      %s\n", szTmpDir);
	printf ("Titre:         %ld (0=choisir le plus long)\n",
		(long) opt_t);
	if (lAngle > 0)
	  printf ("Angle:         %ld\n", lAngle);
	printf
	  ("Piste Audio:   %ld/%s (1=allemand, 2=anglais, 3=allemand+anglais, 4=autre langue, 5=numéro piste)\n",
	   lSprachAuswahl, szZusatzSprache);
	printf
	  ("Format Audio:  %ld (0=première piste dans la langue, 1=AC3 avec 6 cx de préférence, 2=DTS de préférence)\n",
	   lAudioDefault);
	if (!strlen (szUntertitelSprache))
	  printf
	    ("Sous-Titres:   %ld (Numéro piste, 0=pas de S/T, -1=choix dans liste, -3=Forced, -4=Toutes)\n",
	     lUntertitel);
	else
	  printf ("Sous-Titres:   %s\n", szUntertitelSprache);
	printf
	  ("Chapitrage:    %ld (0=non, 1=oui, avec lxdvdrip, 2=oui, avec tcprobe)\n",
	   lMitKapiteln);
	printf
	  ("Répertoire:    %s (Répertoire d'extraction, p.ex. /tmp/film-dvd)\n",
	   szFilmVerzeichnis);
	printf ("Effacement:    %ld (0=non, 1=oui)\n", lLoeschen);
	printf ("Facteur:       %f\n", dFaktor);
	printf ("Lecteur DVD:   %s (Nom du lecteur)\n", dvd_device);
	if (!strlen (szOutputFile))
	  {
	    printf ("Graveur DVD:   %s (Nom du graveur)\n", szDVDBrenner);
	    printf
	      ("Prog.gravure:  %ld (1=growisofs,2=cdrecord,3=cdrecord à la volée,4=mkisofs,5=mkisofs/VolumeID,0=ne pas graver)\n",
	       lBrennProgramm);
	    printf ("Formater RW:   %ld (0=non, 1=oui)\n", lRWFormat);
	    printf ("Attente DVDR:  %ld (1=oui, 0=non)\n", lWaitBurn);
	    printf
	      ("Visu VOB par:  %s (Nom du programme, défaut: mplayer, off=pas de prévisu)\n",
	       szVOBPlayer);
	    printf ("Vitesse gravure:   %ld\n", lDVDSpeed);
	  }
	else
	  {
	    printf ("Sortie en fichier: %s\n", szOutputFile);
	  }
	if (lDebugLevel)
	  {
	    printf ("Niveau de débogage:   %ld\n", lDebugLevel);
	  }
	break;
      }
    }

  // Bei dvdwizard wird File Option eingeschaltet
  if (lDVDWizard && !strlen (szOutputFile))
    {
      strcpy (szOutputFile, "1");	// Dateiname wird spaeter gesetzt
    }

  if (strlen (szOutputFile)
      && ( ((lPackMethode == 5 || lPackMethode == 6) && !lDVDWizard) ||
           (lPackMethode == 1 && lMenues == 1) ) )
    {
      switch (lSprache)
	{
	case 0:
	  printf
	    ("\nAusgabe in Datei/dvdwizard nicht bei menu, copy oder partcopy!\n");
	  break;
	case 1:
	  printf ("\nOutput to file/dvdwizard not with menu, copy or partcopy!\n");
	  break;
	case 2:
	  printf
	    ("\nSortie vers fichier/dvdwizard incompatible avec menu, copy ou partcopy!\n");
	  break;
	}
      return 0;
    }

  // TCMPLEX kann nicht pipen, daher nicht bei Transcode Parallel
  if (lMultiplexer == 1 && lPackMethode == 2)
    {
      switch (lSprache)
	{
	case 0:
	  printf
	    ("\ntcmplex nicht bei transcode parallel, verwende mplex!\n");
	  break;
	case 1:
	  printf ("\ntcmplex not with transcode parallel, using mplex!\n");
	  break;
	case 2:
	  printf
	    ("\ntcmplex incompatible avec transcode parallèle, utilisera mplex!\n");
	  break;
	}
      lMultiplexer = 2;
    }


  // Forced Untertitel nur bei Transcode Parallel
  if (lPackMethode != 2 && lUntertitel == -3)
    {
      switch (lSprache)
	{
	case 0:
	  printf ("\n\"Forced\" Untertitel nur bei Transcode parallel!\n");
	  break;
	case 1:
	  printf ("\n\"Forced\" Subpictures only with Transcode parallel!\n");
	  break;
	case 2:
	  printf ("\n\"Forced\" Sous-Titres: transcode parallèle!\n");
	  break;
	}
      return 0;
    }

  // Alle Untertitel nur bei Vamps
  if (lPackMethode != 1 && lUntertitel == -4)
    {
      switch (lSprache)
	{
	case 0:
	  printf ("\nAlle Untertitel nur bei Vamps!\n");
	  break;
	case 1:
	  printf ("\nAll Subpictures only with Vamps!\n");
	  break;
	case 2:
	  printf ("\nToutes Sous-Titres: Vamps!\n");
	  break;
	}
      return 0;
    }

  if (lHighQuality && (lPackMethode >= 5 || lMenues > 0 || lUseVLC))
    {
      switch (lSprache)
	{
	case 0:
	  printf ("\nHigh Quality Backup nicht im VLC-, Copy- und Menue-Modus!\n");
	  break;
	case 1:
	  printf ("\nHigh Quality Backup not in VLC-, Copy- and Menu-Mode!\n");
	  break;
	case 2:
	  printf ("\nCopie Haute Qualité non disponible en mode VLC, Copie e Menu!\n");
	  break;
	}
      return 0;
    }

  // Genug freier Speicherplatz im Fimverzeichnis ?
  // Basisverzeichnis fuer Dateiablage bilden
  if (lTestFree)
    {
      char szMainDir[1024];
      long lFrei = 1;
      szMainDir[0] = 0;
      switch (lSprache)
	{
	case 0:
	  printf ("\nPruefe auf freien Plattenplatz: ...\n");
	  break;
	case 1:
	  printf ("\nChecking free disk space: ...\n");
	  break;
	case 2:
	  printf ("\nVérification de l'espace disque: ...\n");
	  break;
	}
      strcpy (szMainDir, szFilmVerzeichnis);
      // Film-Verzeichnis zuvor anlegen, wenn nicht da, laeuft die Speicherplatzabfrage nicht
      sprintf (szBefehl, "mkdir %s > /dev/null", szMainDir);
      system (szBefehl);
      if (calculate_discfree (szMainDir, lSprache, szTmpDir) <
	  lGroesseDVDBytesMaximal)
	{
	  char cContinue = ' ';
	  lFrei = 0;
	  switch (lSprache)
	    {
	    case 0:
	      printf
		("Zuwenig freier Speicherplatz im Verzeichnis %s zum Backup der DVD! (Weiter mit 'j')\n",
		 szMainDir);
	      break;
	    case 1:
	      printf
		("Not enough free disk space in %s to backup the DVD! (Continue with 'y')\n",
		 szMainDir);
	      break;
	    case 2:
	      printf
		("Espace libre insuffisant sur %s pour y copier le DVD ! ('o' pour continuer)\n",
		 szMainDir);
	      break;
	    }
	  scanf ("%1c", &cContinue);
	  if (cContinue != 'y' && cContinue != 'j' && cContinue != 'o')
	    {
	      return 0;
	    }
	  eatToNL (stdin);
	}

      // Bei Packmethode 3 (mplayer), 4 (transcode) muss der doppelte Platz frei sein
      if (lPackMethode == 3 || lPackMethode == 4)
	{
	  long long lFaktor = 1;
	  // TmpDir und FilmDir im gleichen Verzeichnis, dann muss doppelt freier Platz sein
	  if (device_number (szMainDir) == device_number (szTmpDir))
	    {
	      lFaktor = 2;
	    }
	  if (calculate_discfree (szTmpDir, lSprache, szTmpDir) <
	      (lGroesseDVDBytesMaximal * lFaktor))
	    {
	      char cContinue = ' ';
	      lFrei = 0;
	      switch (lSprache)
		{
		case 0:
		  printf
		    ("Zuwenig freier Speicherplatz im Verzeichnis %s zum Backup der DVD! (Weiter mit 'j')\n",
		     szTmpDir);
		  break;
		case 1:
		  printf
		    ("Not enough free disk space in %s to backup the DVD! (Continue with 'y')\n",
		     szTmpDir);
		  break;
		case 2:
		  printf
		    ("Espace libre insuffisant sur %s pour y copier le DVD ! ('o' pour continuer)\n",
		     szTmpDir);
		  break;
		}
	      scanf ("%1c", &cContinue);
	      if (cContinue != 'y' && cContinue != 'j' && cContinue != 'o')
		{
		  return 0;
		}
	      eatToNL (stdin);
	    }
	}
      if (lFrei)
	{
	  printf ("Test OK\n");
	}
    }

  if (strstr (dvd_device, "/dev"))	// Test nicht fuer FILES, sonst Probleme bei ISOs
    {
      ret = stat (dvd_device, &dvd_stat);
      if (ret < 0)
	{
	  fprintf (stderr, "Can't find device %s\n", dvd_device);
	  return 1;
	}
    }

  // Kein voller Pfad ?
  if (dvd_device[0] == '.' || 
      (dvd_device[0] != '/' && dvd_device[0] < '0' && dvd_device[0] > '9')
     )
  {
    // Working Directory anhaengen
    char szTempDevice[1024];
    getcwd (szTempDevice, 1024);
    strcat (szTempDevice, "/");
    strcat (szTempDevice, dvd_device);
    strcpy (dvd_device, szTempDevice);
  }

  dvd = DVDOpen (dvd_device);
  if (!dvd)
    {
      fprintf (stderr, "Can't open disc %s!\n", dvd_device);
      return 2;
    }
  ifo_zero = ifoOpen (dvd, 0);
  if (!ifo_zero)
    {
      fprintf (stderr, "Can't open main ifo!\n");
      return 3;
    }

  ifo =
    (ifo_handle_t **) malloc ((ifo_zero->vts_atrt->nr_of_vtss + 1) *
			      sizeof (ifo_handle_t *));

  for (i = 1; i <= ifo_zero->vts_atrt->nr_of_vtss; i++)
    {
      ifo[i] = ifoOpen (dvd, i);
      if (!ifo[i])
	{
	  fprintf (stderr, "Can't open ifo %d!\n", i);
	  return 4;
	}
    }

  // Programm im TMPDIR ausfuehren
  chdir (szTmpDir);

  titles = ifo_zero->tt_srpt->nr_of_srpts;

  if (opt_t > titles)
    {
      fprintf (stderr, "Only %d titles on this disc!", titles);
      return 5;
    }

  has_title = get_title_name (dvd_device, title, lSprache);

  vmgi_mat = ifo_zero->vmgi_mat;

  if (opt_p)
    {
      START;
      DEF ("device", "'%s'", dvd_device);
      DEF ("title", "'%s'", has_title ? "unknown" : title);
      DEF ("vmg_id", "'%.12s'", vmgi_mat->vmg_identifier);
      DEF ("provider_id", "'%.32s'", vmgi_mat->provider_identifier);

      ARRAY ("track");
    }
  else
    {
      printf ("Disc Title: %s\n", has_title ? "unknown" : title);
      // Titel uebernehmen fuers Image, wird dann der DVD-Titel am Player
      if (has_title == 0 && !strlen (szDVDName))
	{
	  strcpy (szDVDName, title);
	}
    }

  // Outputfile setzen, falls Option 1
  if (strlen (szOutputFile) && szOutputFile[0] == '1')
    {
      sprintf (szOutputFile, "%s/%s.vob", szTmpDir, szDVDName);
    }

  // Fragment aus dvdbackup, Inhalt der Original DVD auflisten
  title_set_info = DVDGetFileSet (dvd);
  if (title_set_info)
    {
      fprintf (stdout, "File Structure DVD\n");
      fprintf (stdout, "VIDEO_TS/\n");
      fprintf (stdout, "\tVIDEO_TS.IFO\t%i\n",
	       title_set_info->title_set[0].size_ifo * 2048);

      lGroesseDVDGesamt +=
	(long long) title_set_info->title_set[0].size_ifo * 2048;
      if (title_set_info->title_set[0].size_menu != 0)
	{
	  fprintf (stdout, "\tVIDEO_TS.VOB\t%i\n",
		   title_set_info->title_set[0].size_menu * 2048);
	  lGroesseDVDGesamt +=
	    (long long) title_set_info->title_set[0].size_menu * 2048;
	}
      fprintf (stdout, "\tVIDEO_TS.BUP\t%i\n",
	       title_set_info->title_set[0].size_bup * 2048);
      lGroesseDVDGesamt +=
	(long long) title_set_info->title_set[0].size_bup * 2048;
      for (i = 0; i < title_set_info->number_of_title_sets; i++)
	{
	  fprintf (stdout, "\tVTS_%02i_0.IFO\t%i\n", i + 1,
		   title_set_info->title_set[i + 1].size_ifo * 2048);
	  lGroesseDVDGesamt +=
	    (long long) title_set_info->title_set[i + 1].size_ifo * 2048;
	  if (title_set_info->title_set[i + 1].size_menu != 0)
	    {
	      fprintf (stdout, "\tVTS_%02i_0.VOB\t%i\n", i + 1,
		       title_set_info->title_set[i + 1].size_menu * 2048);
	      lGroesseDVDGesamt +=
		(long long) title_set_info->title_set[i + 1].size_menu * 2048;
	    }
	  if (title_set_info->title_set[i + 1].number_of_vob_files != 0)
	    {
	      int f;
	      for (f = 0;
		   f < title_set_info->title_set[i + 1].number_of_vob_files;
		   f++)
		{
		  fprintf (stdout, "\tVTS_%02i_%i.VOB\t%lld\n", i + 1, f + 1,
			   (long long) title_set_info->title_set[i +
								 1].
			   size_vob[f] * (long long) 2048);
		  lGroesseDVDGesamt +=
		    (long long) title_set_info->title_set[i +
							  1].size_vob[f] *
		    (long long) 2048;
		  lGroesseVOBS +=
		    (long long) title_set_info->title_set[i +
							  1].size_vob[f] *
		    (long long) 2048;
		}
	    }
	  fprintf (stdout, "\tVTS_%02i_0.BUP\t%i\n", i + 1,
		   title_set_info->title_set[i + 1].size_bup * 2048);
	  lGroesseDVDGesamt +=
	    (long long) title_set_info->title_set[i + 1].size_bup * 2048;
	}
      DVDFreeTitleSetInfo (title_set_info);

      switch (lSprache)
	{
	case 0:
	  printf ("\n\nGesamtgroesse der DVD: %lld Bytes (VOBs: %lld)\n",
		  lGroesseDVDGesamt, lGroesseVOBS);
	  break;
	case 1:
	  printf ("\n\nTotal size: %lld Bytes (VOBs: %lld)\n",
		  lGroesseDVDGesamt, lGroesseVOBS);
	  break;
	case 2:
	  printf ("\n\nTaille totale: %lld Octets (VOBs: %lld)\n",
		  lGroesseDVDGesamt, lGroesseVOBS);
	  break;
	}
    }
  else
    {
      // Struktur nicht zu lesen, vermutlich Rippen von Festplatte. Daher 5 GB als Groesse
      lGroesseDVDGesamt = 50 * (long long) 100000000;
    }

  // Wenn DVD kleiner als 4,7 GB, erfolgt Kopie ueber DVD Backup
  if ((lGroesseDVDGesamt < lGroesseDVDBytesMaximal) && (lPackMethode != 5))
    {
      char szPacken[128];
      switch (lSprache)
	{
	case 0:
	  printf
	    ("\nDie DVD passt auf einen Rohling, soll dvdbackup zum Rippen verwendet werden (j/n) ?\n\n");
	  break;
	case 1:
	  printf
	    ("\nThe DVD is smaller than a DVD-R, use dvdbackup to read DVD (y/n) ?\n\n");
	  break;
	case 2:
	  printf
	    ("\nCe DVD est plus petit qu'un DVD-R, utiliser dvdbackup pour une lecture simple (o/n) ?\n\n");
	  break;
	}
      scanf ("%127s", szPacken);
      eatToNL (stdin);
      if (szPacken[0] == 'j' || szPacken[0] == 'y' || szPacken[0] == 'o')
	{
	  lPackMethode = 5;	// dvdbackup
	}
    }

  if (lPackMethode >= 5)	// DVD-Backup
    {
      // PAL-DVD ?
      vtsi_mat = ifo[ifo_zero->tt_srpt->title[0].title_set_nr]->vtsi_mat;
      vts_pgcit = ifo[ifo_zero->tt_srpt->title[0].title_set_nr]->vts_pgcit;
      video_attr = &vtsi_mat->vts_video_attr;
      if (strcmp (video_format[video_attr->video_format], "PAL") == 0)
	{
	  lPALDvd = 1;
	  if (lDebugLevel)
	    printf ("PAL DVD!\n");
	}
      else
	{
	  if (lDebugLevel)
	    printf ("NTSC DVD!\n");
	}
      lUntertitel = 1;
      for (j = 0; j < titles; j++)
	{
	  long k;
	  vtsi_mat = ifo[ifo_zero->tt_srpt->title[j].title_set_nr]->vtsi_mat;
	  vts_pgcit =
	    ifo[ifo_zero->tt_srpt->title[j].title_set_nr]->vts_pgcit;
	  video_attr = &vtsi_mat->vts_video_attr;
	  vts_ttn = ifo_zero->tt_srpt->title[j].vts_ttn;
	  vmgi_mat = ifo_zero->vmgi_mat;
	  title_set_nr = ifo_zero->tt_srpt->title[j].title_set_nr;
	  pgc =
	    vts_pgcit->pgci_srp[ifo[title_set_nr]->vts_ptt_srpt->
				title[vts_ttn - 1].ptt[0].pgcn - 1].pgc;
	  if (j == 0 && pgc->palette)	// Daten zur Palette => Untertitel
	    {
	      FILE *fp;
	      sprintf (szPaletteFile, "%s/palette.txt", szTmpDir);
	      fp = fopen_warnung (szPaletteFile, "w", lSprache);
	      for (i = 0; i < 16; i++)
		fprintf (fp, "%06x\n", pgc->palette[i]);
	      fclose (fp);
	      lPaletteVorhanden = 1;
	    }
	  dvdStruktur[j].titelSet = title_set_nr;
	  dvdStruktur[j].titel = j + 1;
	  dvdStruktur[j].audioTracks = vtsi_mat->nr_of_vts_audio_streams;
	  for (k = 0; k < MAX_AUDIO_TRACK; k++)
	    {
	      if (k >= dvdStruktur[j].audioTracks)
		dvdStruktur[j].audioMap.audioTracks[k] = 0;
	      else
		dvdStruktur[j].audioMap.audioTracks[k] = k + 1;
	    }
	  dvdStruktur[j].untertitelTracks = vtsi_mat->nr_of_vts_subp_streams;
	  for (k = 0; k < MAX_SUB_TRACK; k++)
	    {
	      if (k >= dvdStruktur[j].untertitelTracks)
		dvdStruktur[j].subMap.subTracks[k] = 0;
	      else
		dvdStruktur[j].subMap.subTracks[k] = k + 1;
	    }
	  // Sprachen der Audiostreams setzen fuer DVD-Author
	  strcpy (dvdStruktur[j].szAudio, "");
	  for (k = 0; k < dvdStruktur[j].audioTracks; k++)
	    {
	      if (k == 0)
		strcat (dvdStruktur[j].szAudio, "-a ");
	      else
		strcat (dvdStruktur[j].szAudio, ",");
	      audio_attr = &vtsi_mat->vts_audio_attr[k];
	      sprintf (lang_code, "%c%c", audio_attr->lang_code >> 8,
		       audio_attr->lang_code & 0xff);
	      // Simuliere englisch, wenn nicht gefunden
	      if (!strlen (lang_code) || lang_code[0] == ' ')
		strcpy (lang_code, "xx");
	      strcat (dvdStruktur[j].szAudio, lang_code);
	    }
	  // Sprachen der Untertitelstreams setzen fuer DVD-Author
	  strcpy (dvdStruktur[j].szUntertitel, "");
	  for (k = 0; k < dvdStruktur[j].untertitelTracks; k++)
	    {
	      if (k == 0)
		strcat (dvdStruktur[j].szUntertitel, "-s ");
	      else
		strcat (dvdStruktur[j].szUntertitel, ",");
	      subp_attr = &vtsi_mat->vts_subp_attr[k];
	      sprintf (lang_code, "%c%c", subp_attr->lang_code >> 8,
		       subp_attr->lang_code & 0xff);
	      // Simuliere englisch, wenn nicht gefunden
	      if (!strlen (lang_code) || lang_code[0] == ' ')
		strcpy (lang_code, "xx");
	      strcat (dvdStruktur[j].szUntertitel, lang_code);
	    }
	  // Zusaetzliche Angaben zum Videoformat ?
	  strcpy (dvdStruktur[j].szVideoAngaben, "");
	  if (lMitVideoAngaben > 0 || lDVDWizard)
	    {
	      strcpy (dvdStruktur[j].szVideoDVDWizard, "-N ");
	      strcpy (dvdStruktur[j].szVideoAngaben, "-v ");
	      if (strcmp (video_format[video_attr->video_format], "PAL") == 0)
		{
		  strcat (dvdStruktur[j].szVideoAngaben, "pal");
		  strcat (dvdStruktur[j].szVideoDVDWizard, "PAL");
		}
	      else
		{
		  strcat (dvdStruktur[j].szVideoAngaben, "ntsc");
		  strcat (dvdStruktur[j].szVideoDVDWizard, "NTSC");
		}
	      if (lMitVideoAngaben > 0)
		{
		  strcpy (dvdStruktur[j].szTitelVideo, "");
		  strcat (dvdStruktur[j].szVideoAngaben, "+");
		  if (strcmp
		      (aspect_ratio[video_attr->display_aspect_ratio],
		       "16/9") == 0)
		    {
		      strcat (dvdStruktur[j].szVideoAngaben, "16:9");
		      if (strcmp
			  (permitted_df[video_attr->permitted_df],
			   "Letterbox") == 0
			  || strcmp (permitted_df[video_attr->permitted_df],
				     "?") == 0)
			{
			  strcat (dvdStruktur[j].szVideoAngaben,
				  "+nopanscan");
			  strcat (dvdStruktur[j].szTitelVideo,
				  " -ws NOPANSCAN");
			}
		    }
		  else
		    {
		      strcat (dvdStruktur[j].szVideoAngaben, "4:3");
		    }
		}
	      strcat (dvdStruktur[j].szVideoAngaben, "+");
	      strcat (dvdStruktur[j].szVideoAngaben,
		      video_width[video_attr->picture_size]);
	      strcat (dvdStruktur[j].szVideoAngaben, "x");
	      strcat (dvdStruktur[j].szVideoAngaben,
		      video_height[video_attr->video_format]);
	    }
	}
      ifoClose (ifo_zero);
      DVDClose (dvd);
      strcpy (szVideoTS, "VIDEO_TS");
      strcpy (szAudioTS, "AUDIO_TS");
      strcpy (szVobTS, "VOB");
      strcpy (szVtsTS, "VTS");
    }
  else
    {

      // Berechne den laengsten Track
      for (j = 0; j < titles; j++)
	{
	  vtsi_mat = ifo[ifo_zero->tt_srpt->title[j].title_set_nr]->vtsi_mat;
	  vts_pgcit =
	    ifo[ifo_zero->tt_srpt->title[j].title_set_nr]->vts_pgcit;
	  video_attr = &vtsi_mat->vts_video_attr;
	  vts_ttn = ifo_zero->tt_srpt->title[j].vts_ttn;
	  vmgi_mat = ifo_zero->vmgi_mat;
	  title_set_nr = ifo_zero->tt_srpt->title[j].title_set_nr;
	  pgc =
	    vts_pgcit->pgci_srp[ifo[title_set_nr]->vts_ptt_srpt->
				title[vts_ttn - 1].ptt[0].pgcn - 1].pgc;

	  if (dvdtime2msec (&pgc->playback_time) > max_length)
	    {
	      max_length = dvdtime2msec (&pgc->playback_time);
	      max_track = j + 1;
	    }
	}

      // Titel aus Liste auswaehlen
      if (opt_t < 0)
	{
	  long lTitel;
	  printf ("\n");
	  switch (lSprache)
	    {
	    case 0:
	      printf ("Titelauswahl:\n\n");
	      break;
	    case 1:
	      printf ("Title-Selection:\n\n");
	      break;
	    case 2:
	      printf ("Choisissez Titre:\n\n");
	      break;
	    }
	  for (j = 0; j < titles; j++)
	    {
	      if (ifo[ifo_zero->tt_srpt->title[j].title_set_nr]->vtsi_mat)
		{

		  vtsi_mat =
		    ifo[ifo_zero->tt_srpt->title[j].title_set_nr]->vtsi_mat;
		  vts_pgcit =
		    ifo[ifo_zero->tt_srpt->title[j].title_set_nr]->vts_pgcit;
		  video_attr = &vtsi_mat->vts_video_attr;
		  vts_ttn = ifo_zero->tt_srpt->title[j].vts_ttn;
		  vmgi_mat = ifo_zero->vmgi_mat;
		  title_set_nr = ifo_zero->tt_srpt->title[j].title_set_nr;
		  //pgc = vts_pgcit->pgci_srp[ifo_zero->tt_srpt->title[j].vts_ttn - 1].pgc;
		  //printf ("this pgcn = %i", ifo[title_set_nr]->vts_ptt_srpt->title[vts_ttn - 1].ptt[0].pgcn - 1);
		  pgc =
		    vts_pgcit->pgci_srp[ifo[title_set_nr]->vts_ptt_srpt->
					title[vts_ttn - 1].ptt[0].pgcn -
					1].pgc;
		  switch (lSprache)
		    {
		    case 0:	// deutsch
		      printf
			("Titel:%02d, VTS:%02d, Laenge:%02x:%02x:%02x, Kapitel:%02d, "
			 "Audiotracks:%02d, Untertitel:%02d\n", j + 1,
			 ifo_zero->tt_srpt->title[j].title_set_nr,
			 pgc->playback_time.hour, pgc->playback_time.minute,
			 pgc->playback_time.second,
			 ifo_zero->tt_srpt->title[j].nr_of_ptts,
			 vtsi_mat->nr_of_vts_audio_streams,
			 vtsi_mat->nr_of_vts_subp_streams);
		      break;
		    case 1:	// englisch
		      printf
			("Title:%02d, VTS:%02d, Length:%02x:%02x:%02x, Chapters:%02d, "
			 "Audio streams:%02d, Subpictures:%02d\n", j + 1,
			 ifo_zero->tt_srpt->title[j].title_set_nr,
			 pgc->playback_time.hour, pgc->playback_time.minute,
			 pgc->playback_time.second,
			 ifo_zero->tt_srpt->title[j].nr_of_ptts,
			 vtsi_mat->nr_of_vts_audio_streams,
			 vtsi_mat->nr_of_vts_subp_streams);
		      break;
		    case 2:	// franzoesisch
		      printf
			("Titre:%02d, VTS:%02d, Long:%02x:%02x:%02x, Chapitrage:%02d, "
			 "Langue:%02d, Sous-Titres:%02d\n", j + 1,
			 ifo_zero->tt_srpt->title[j].title_set_nr,
			 pgc->playback_time.hour, pgc->playback_time.minute,
			 pgc->playback_time.second,
			 ifo_zero->tt_srpt->title[j].nr_of_ptts,
			 vtsi_mat->nr_of_vts_audio_streams,
			 vtsi_mat->nr_of_vts_subp_streams);
		      break;
		    }
		}
	    }
	  switch (lSprache)
	    {
	    case 0:
	      printf ("\nTitel?\n");
	      break;
	    case 1:
	      printf ("\nTitle?\n");
	      break;
	    case 2:
	      printf ("\nTitre\n");
	      break;
	    }
	  // Eingabe
	  input_zahlen (&lTitel, NULL, titles);
	  opt_t = (int) lTitel;
	  // Umsetzen auf Autoselektion bei Ueber/Unterschreitung
	  if (opt_t > titles || opt_t < 0)
	    opt_t = 0;
	  // Mehrere Winkel ?
	  if (opt_t)
	    if (ifo_zero->tt_srpt->title[opt_t - 1].nr_of_angles > 1)
	      {
		switch (lSprache)
		  {
		  case 0:
		    printf ("\nWinkel (1-%ld)?\n",
			    ifo_zero->tt_srpt->title[opt_t - 1].nr_of_angles);
		    break;
		  case 1:
		  case 2:
		    printf ("\nAngle (1-%ld)?\n",
			    ifo_zero->tt_srpt->title[opt_t - 1].nr_of_angles);
		    break;
		  }
		input_zahlen (&lAngle, NULL,
			      ifo_zero->tt_srpt->title[opt_t -
						       1].nr_of_angles);
	      }
	  printf ("\n");
	}

      // Wenn Titel nicht per Parameter gesetzt, verwende den laengsten Titel
      if (!opt_t)
	{
	  opt_t = max_track;
	}

      // PAL-DVD ?
      vtsi_mat =
	ifo[ifo_zero->tt_srpt->title[opt_t - 1].title_set_nr]->vtsi_mat;
      vts_pgcit =
	ifo[ifo_zero->tt_srpt->title[opt_t - 1].title_set_nr]->vts_pgcit;
      video_attr = &vtsi_mat->vts_video_attr;
      if (strcmp (video_format[video_attr->video_format], "PAL") == 0)
	{
	  lPALDvd = 1;
	  if (lDebugLevel)
	    printf ("PAL DVD!\n");
	}
      else
	{
	  if (lDebugLevel)
	    printf ("NTSC DVD!\n");
	}

      // Videoangaben auslesen zum Titel
      strcpy (szDVDWizardVideoAngaben, "");
      if (lMitVideoAngaben > 0)
	{
	  if (strcmp
	      (aspect_ratio[video_attr->display_aspect_ratio],
	       "16/9") == 0)
	    {
	      if (strcmp
		  (permitted_df[video_attr->permitted_df],
		   "Letterbox") == 0
		  || strcmp (permitted_df[video_attr->permitted_df],
			     "?") == 0)
		{
		  strcat (szDVDWizardVideoAngaben, " -WS ");
		  strcat (szDVDWizardVideoAngaben, "NOPANSCAN");
		}
	    }
	}

      // Title-Set-Nr. zum Titel speichern
      opt_vts = ifo_zero->tt_srpt->title[opt_t - 1].title_set_nr;

      // Angaben zum Format auslesen
      // Diese Angaben koennen optional an dvdauthor weitergegeben werden
      strcpy (szVideoAngaben, "");	// Standard: ohne Videoangaben an dvdauthor
      if (lMitVideoAngaben > 0)
	{
	  vtsi_mat =
	    ifo[ifo_zero->tt_srpt->title[opt_t - 1].title_set_nr]->vtsi_mat;
	  vts_pgcit =
	    ifo[ifo_zero->tt_srpt->title[opt_t - 1].title_set_nr]->vts_pgcit;
	  video_attr = &vtsi_mat->vts_video_attr;
	  if (lPackMethode != 1)	// Transcode, mplayer
	    {
	      strcpy (szVideoAngaben, "-v ");
	      if (strcmp (video_format[video_attr->video_format], "PAL") == 0)
		strcat (szVideoAngaben, "pal");
	      else
		strcat (szVideoAngaben, "ntsc");
	      strcat (szVideoAngaben, "+");
	      if (strcmp
		  (aspect_ratio[video_attr->display_aspect_ratio],
		   "16/9") == 0)
		{
		  strcat (szVideoAngaben, "16:9");
		  if (strcmp
		      (permitted_df[video_attr->permitted_df],
		       "Letterbox") == 0
		      || strcmp (permitted_df[video_attr->permitted_df],
				 "?") == 0)
		    {
		      strcat (szVideoAngaben, "+nopanscan");
		    }
		}
	      else
		{
		  strcat (szVideoAngaben, "4:3");
		}
	      strcat (szVideoAngaben, "+");
	      strcat (szVideoAngaben, video_width[video_attr->picture_size]);
	      strcat (szVideoAngaben, "x");
	      strcat (szVideoAngaben, video_height[video_attr->video_format]);
	    }
	  else
	    {			// vamps als Streamtool, XML-Format
	      strcpy (szVideoAngaben, "<video format=\"");
	      if (strcmp (video_format[video_attr->video_format], "PAL") == 0)
		strcat (szVideoAngaben, "pal\"");
	      else
		strcat (szVideoAngaben, "ntsc\"");
	      if (strcmp
		  (aspect_ratio[video_attr->display_aspect_ratio],
		   "16/9") == 0)
		{
		  strcat (szVideoAngaben, " aspect=\"16:9\"");
		  if (strcmp
		      (permitted_df[video_attr->permitted_df],
		       "Letterbox") == 0
		      || strcmp (permitted_df[video_attr->permitted_df],
				 "?") == 0)
		    {
		      strcat (szVideoAngaben, " widescreen=\"nopanscan\"");
		    }
		}
	      else
		{
		  strcat (szVideoAngaben, " aspect=\"4:3\"");
		}
	      strcat (szVideoAngaben, " resolution=\"");
	      strcat (szVideoAngaben, video_width[video_attr->picture_size]);
	      strcat (szVideoAngaben, "x");
	      strcat (szVideoAngaben, video_height[video_attr->video_format]);
	      strcat (szVideoAngaben, "\" />");
	    }
	}

      for (j = 0; j < titles; j++)
	{

	  if (opt_t == j + 1 || opt_t == 0)
	    {
	      // GENERAL
	      if (ifo[ifo_zero->tt_srpt->title[j].title_set_nr]->vtsi_mat)
		{

		  vtsi_mat =
		    ifo[ifo_zero->tt_srpt->title[j].title_set_nr]->vtsi_mat;
		  vts_pgcit =
		    ifo[ifo_zero->tt_srpt->title[j].title_set_nr]->vts_pgcit;
		  video_attr = &vtsi_mat->vts_video_attr;
		  vts_ttn = ifo_zero->tt_srpt->title[j].vts_ttn;
		  vmgi_mat = ifo_zero->vmgi_mat;
		  title_set_nr = ifo_zero->tt_srpt->title[j].title_set_nr;
		  //pgc = vts_pgcit->pgci_srp[ifo_zero->tt_srpt->title[j].vts_ttn - 1].pgc;
		  //printf ("this pgcn = %i", ifo[title_set_nr]->vts_ptt_srpt->title[vts_ttn - 1].ptt[0].pgcn - 1);
		  pgc =
		    vts_pgcit->pgci_srp[ifo[title_set_nr]->vts_ptt_srpt->
					title[vts_ttn - 1].ptt[0].pgcn -
					1].pgc;

		  if (opt_p)
		    {
		      HASH ("");
		      DEF ("ix", "%d", j + 1);
		      DEF ("length", "%.3f",
			   dvdtime2msec (&pgc->playback_time) / 1000.0);
		      DEF ("vts_id", "'%.12s'", vtsi_mat->vts_identifier);
		    }
		  else
		    {
		      char szTmp[128];
		      lAnzahlSekunden = 0;
		      if (lDebugLevel)
			printf ("Title: %02d, Length: %02x:%02x:%02x ", j + 1,
				pgc->playback_time.hour,
				pgc->playback_time.minute,
				pgc->playback_time.second);
		      // Zeit ist in Hex gespeichert, hier umrechnen
		      sprintf (szTmp, "%02x", pgc->playback_time.hour);
		      lAnzahlSekunden += atol (szTmp) * 3600;
		      sprintf (szTmp, "%02x", pgc->playback_time.minute);
		      lAnzahlSekunden += atol (szTmp) * 60;
		      sprintf (szTmp, "%02x", pgc->playback_time.second);
		      lAnzahlSekunden += atol (szTmp);
		    }

		  if (!opt_q && !opt_p)
		    {
		      if (lDebugLevel)
			printf ("Chapters: %02d, Cells: %02d, ",
				ifo_zero->tt_srpt->title[j].nr_of_ptts,
				pgc->nr_of_cells);
		      lAnzahlKapitel = ifo_zero->tt_srpt->title[j].nr_of_ptts;
		      if (lDebugLevel)
			printf ("Audio streams: %02d, Subpictures: %02d",
				vtsi_mat->nr_of_vts_audio_streams,
				vtsi_mat->nr_of_vts_subp_streams);
		      lAnzahlAudioStreams = vtsi_mat->nr_of_vts_audio_streams;
		    }

		  if (!opt_p)
		    {
		      if (lDebugLevel)
			printf ("\n");
		    }

		  // Anzahl der Zellen festhalten
		  lAnzahlZellen = pgc->nr_of_cells;
		  // Abhaengig vom Winkel ein Arry mit den entsprechenden 
		  // Zellen zusammenstellen
		  {
		    int next_cell = 0, cur_cell, max_cells = 0;
		    int angle = lAngle - 1;
                    long lSektorenGesamt=0;
                    long long lGroesseKomplett=0;
		    if (lDebugLevel > 0)
		      printf ("Anzahl Zellen gesamt: %ld\n", lAnzahlZellen);
		    for (; next_cell < lAnzahlZellen;)
		      {
			cur_cell = next_cell;
			/* Check if we're entering an angle block. */
			if (pgc->cell_playback[cur_cell].block_type ==
			    BLOCK_TYPE_ANGLE_BLOCK)
			  {
			    int i;
			    cur_cell += angle;
			    for (i = 0;; ++i)
			      {
				if (pgc->cell_playback[cur_cell + i].
				    block_mode == BLOCK_MODE_LAST_CELL)
				  {
				    next_cell = cur_cell + i + 1;
				    break;
				  }
			      }
			  }
			else
			  {
			    next_cell = cur_cell + 1;
			  }
       	                int sectors = pgc->cell_playback[next_cell].last_sector -
				      pgc->cell_playback[next_cell].first_sector + 1;

			angle_cell_array[max_cells] = next_cell;
			sector_cell_array[max_cells] = 
                                      pgc->cell_playback[next_cell-1].last_sector -
				      pgc->cell_playback[next_cell-1].first_sector + 1;
                        lSektorenGesamt += sector_cell_array[max_cells];
		        if (lDebugLevel > 0)
                        {
			  printf ("Zelle %ld / Sektoren %lld\n", 
                             angle_cell_array[max_cells], sector_cell_array[max_cells]);
                        }
			max_cells++;
		      }
		    lAnzahlZellen = max_cells;
                    // Faktor setzen, Vamps wird spaeter mit Filesize gestartet
                    lOptimiereFaktor = 0;
                    if (lHighQuality == 0 && dFaktor <= 0 )
                    {
                      lOptimiereFaktor = 1;  
                      if (lPackMethode == 1)
                      {
                        dFaktor = (double)((long long)lSektorenGesamt*2048) /
                                  (double)lGroesseDVDBytes;
                      }
                      for (i=1; i<=lAnzahlZellen; i++)
                      {
                        sector_cell_array[i-1] = (long long)
                                                 (sector_cell_array[i-1]*2048);
                        lGroesseKomplett += sector_cell_array[i-1];                         
                      }
                    }
		    if (lDebugLevel > 0)
                    {
		      printf ("Anzahl Zellen fuer Angle: %ld\n",
			      lAnzahlZellen);
                      if (lHighQuality == 0 && dFaktor <= 0)
                      {
  		        printf ("Sektoren Gesamt: %ld\n",
			        lSektorenGesamt);
		        printf ("Faktor: %lf\n",
			        dFaktor);
                        for (i=1; i<=lAnzahlZellen; i++)
                        {
                          lGroesseKomplett += sector_cell_array[i-1];                         
		          printf ("Zelle %ld / Groesse Bytes %lld\n",
			          i, sector_cell_array[i-1]);
                        }
		        printf ("Groesse Bytes Gesamt nach Shrinken: %lld\n",
			        lGroesseKomplett);
                      }
                    }
		  }
		  lTestZelle = ((lAnzahlZellen + 1) / 2) + 1;
		  // In welchem VTS bzw. PGC ist der Titel (Werte fuer vamps)
		  lVTS = ifo_zero->tt_srpt->title[j].title_set_nr;
		  lPGC = ifo_zero->tt_srpt->title[j].vts_ttn;

		  // Bei Untertiteln die Palette der DVD in eine Datei schreiben,
		  // wird spaeter an dvdauthor weitergegeben
		  strcpy (szPaletteOptions, "");
		  if (pgc->palette)
		    {
		      FILE *fp;
		      if (lDebugLevel)
			printf ("Create Palette-File: Start\n");
		      sprintf (szPaletteFile, "%s/palette.txt", szTmpDir);
		      fp = fopen_warnung (szPaletteFile, "w", lSprache);
		      for (i = 0; i < 16; i++)
			{
			  fprintf (fp, "%06x\n", pgc->palette[i]);
			  if (lDebugLevel)
			    printf ("%i, %06x\n", i, pgc->palette[i]);
			}
		      fclose (fp);
		      lPaletteVorhanden = 1;
		      sprintf (szPaletteOptions, " -p %s ", szPaletteFile);
		      if (lDebugLevel)
			printf ("Create Palette-File: End\n");
		    }

		  // ANGLES
		  if (opt_n)
		    {
		      if (opt_p)
			{
			  DEF ("angles", "%d",
			       ifo_zero->tt_srpt->title[j].nr_of_angles);
			}
		      else
			{
			  if (lDebugLevel)
			    printf ("\tNumber of angles: %d\n",
				    ifo_zero->tt_srpt->title[j].nr_of_angles);
			}
		    }

		  // AUDIO
		  if (opt_a)
		    {
		      // Anzahl Audio Tracks per TCCAT und tcprobe feststellen
		      // Die Infos aus libdvdread stimmen nicht immer, also neu berechnen
                      // Bei VLC statt tccat auch vlc nehmen
		      if ( ( (lUseVLC == 0 && check_program (tccat_name, lSprache, 0)) ||
                             (lUseVLC >  0 && check_program (vlc_name, lSprache, 0))
                           )
			  && check_program (tcprobe_name, lSprache, 0)
                          && lPruefen > 0)
			{
			  char szWort[1024], szTemp[1024];
			  FILE *fp;
			  long lAnzahlAudio = 0;
			  sprintf (szTemp, "%s/tcprobeaudio.tmp", szTmpDir);
                          if (lUseVLC == 0)
                          {
			    sprintf (szBefehl,
				     "%s %s -i %s -T %ld -P | %s -d 0 -H 100 > %s 2>&1",
				     szNiceRip, tccat_name, dvd_device, opt_t,
				     tcprobe_name, szTemp);
			    printf ("%s\n", szBefehl);
			    system (szBefehl);
                          } else
                          {
                            // vlc und tcprobe muessen getrennt sein, sonst keine Rueckkehr
                            long lTestKapitel=(lAnzahlKapitel/2+1);
                            sprintf (szBefehl, "%s %s dvdsimple:%s@%ld:%ld-%ld:%ld --intf dummy --sout-all --no-spu "
                                               "--sout '#standard{access=file,mux=ps,dst=%s/vlctestrip.vob}' vlc:quit",
                                     szNiceRip, vlc_name, dvd_device, 
                                     opt_t, lTestKapitel,
                                     opt_t, lTestKapitel,
                                     szTmpDir);
			    printf ("%s\n", szBefehl);
			    system (szBefehl);
                            // Hat der Testrip funktioniert? 
                            sprintf (szBefehl, "%s/vlctestrip.vob", szTmpDir);
                            if (filesize64 (szBefehl, szTmpDir) < (long long)1000)
                            {
                              switch (lSprache)
                              {
                                case 0:
                                  printf ("\n\nFalscher Titel (%ld), bitte mit "
                                          "'lxdvdrip -t=l' anderen Titel waehlen!\n",
                                          opt_t);
                                          break;
                                case 1:
                                  printf ("\n\nNo Video in this title (%ld), please choose with "
                                          "'lxdvdrip -t=l' another title!\n",
                                          opt_t);
                                          break;
                                case 2:
                                  printf ("\n\nTitre avec non video! "
                                          "Choisir Titre dans List 'lxdvdrip -t=l'!\n",
                                          opt_t);
                                          break;
                              }
                              exit (0);
                            }
                            sprintf (szBefehl, "cat %s/vlctestrip.vob | %s -d 0 -H 100 > %s 2>&1", 
                                               szTmpDir, tcprobe_name, szTemp);
			    printf ("%s\n", szBefehl);
			    system (szBefehl);
                            sprintf (szBefehl, "rm %s/vlctestrip.vob", szTmpDir);
			    printf ("%s\n", szBefehl);
			    system (szBefehl);
                          }
			  fp = fopen (szTemp, "r");
			  while (fscanf (fp, "%s\n", szWort) != EOF)
			    {
			      if (strstr (szWort, "audio"))
				{
				  fscanf (fp, "%s\n", szWort);
				  if (strstr (szWort, "track:"))
				    lAnzahlAudio++;
				}
			    }
                          fclose (fp);
			  // Tracks gefunden, Anzahl setzen
			  if (lAnzahlAudio > 0)
			    vtsi_mat->nr_of_vts_audio_streams = lAnzahlAudio;
			  sprintf (szBefehl, "rm %s", szTemp);
			  system (szBefehl);
                          // Ohne Audiospur, nicht zu rippen
                          if (lAnzahlAudio == 0)
                          { 
                            switch (lSprache)
                            {
                              case 0:
                                printf ("\n\nFalscher Titel (%ld), bitte mit "
                                        "'lxdvdrip -t=l' anderen Titel waehlen!\n",
                                        opt_t);
                                        break;
                              case 1:
                                printf ("\n\nNo Video in this title (%ld), please choose with "
                                        "'lxdvdrip -t=l' another title!\n",
                                        opt_t);
                                        break;
                              case 2:
                                printf ("\n\nTitre avec non video! "
                                        "Choisir Titre dans List 'lxdvdrip=l'!\n",
                                        opt_t);
                                        break;
                            }
                            exit (0);
                          }
			}
		      if (opt_p)
			{
			  ARRAY ("audio");
			  for (i = 0; i < vtsi_mat->nr_of_vts_audio_streams;
			       i++)
			    {
			      audio_attr = &vtsi_mat->vts_audio_attr[i];
			      sprintf (lang_code, "%c%c",
				       audio_attr->lang_code >> 8,
				       audio_attr->lang_code & 0xff);
			      if (!lang_code[0])
				{
				  strcpy (lang_code, "xx");
				}
			      HASH ("");
			      DEF ("ix", "%d", i + 1);
			      DEF ("langcode", "'%s'", lang_code);
			      DEF ("language", "'%s'", lang_name (lang_code));
			      DEF ("format", "'%s'",
				   audio_format[audio_attr->audio_format]);
			      DEF ("frequency", "%s",
				   sample_freq[audio_attr->sample_frequency]);
			      DEF ("quantization", "'%s'",
				   quantization[audio_attr->quantization]);
			      DEF ("channels", "%d",
				   audio_attr->channels + 1);
			      DEF ("ap_mode", "%d",
				   audio_attr->application_mode);
			      DEF ("content", "'%s'",
				   audio_type[audio_attr->lang_extension]);
			      RETURN;
			    }
			  RETURN;
			}
		      else
			{
			  // Auswahl Audiotracks nach Voreinstellung
			  if (lSprachAuswahl <= 4)
			    {
			      for (i = 0;
				   i < vtsi_mat->nr_of_vts_audio_streams; i++)
				{
				  audio_attr = &vtsi_mat->vts_audio_attr[i];
				  sprintf (lang_code, "%c%c",
					   audio_attr->lang_code >> 8,
					   audio_attr->lang_code & 0xff);
				  if (!lang_code[0])
				    {
				      strcpy (lang_code, "xx");
				    }
				  if (lDebugLevel)
				    printf
				      ("\tAudio: %d, Language: %s - %s, ",
				       i + 1, lang_code,
				       lang_name (lang_code));
				  if (lDebugLevel)
				    printf ("Format: %s, ",
					    audio_format[audio_attr->
							 audio_format]);
				  if (lDebugLevel)
				    printf ("Frequency: %s, ",
					    sample_freq[audio_attr->
							sample_frequency]);
				  if (lDebugLevel)
				    printf ("Quantization: %s, ",
					    quantization[audio_attr->
							 quantization]);
				  if (lDebugLevel)
				    printf ("Channels: %d, AP: %d, ",
					    audio_attr->channels + 1,
					    audio_attr->application_mode);
				  if (lDebugLevel)
				    printf ("Content: %s",
					    audio_type[audio_attr->
						       lang_extension]);
				  if (lDebugLevel)
				    printf ("\n");
				  if (strcmp
				      (audio_format[audio_attr->audio_format],
				       "ac3") == 0)
				    {
				      long lAudioKBPS;
				      // Falls die gezogene Audiospur weniger Kanaele hat, jetzt diese auswaehlen.
				      // Ebenso bei bereits gewaehltem DTS-Track, aber dts ausgeschaltet.
				      if ((lAudioTrackDeutsch
					   && strcmp (lang_code, "de") == 0
					   && lAnzahlChannelDeutsch <
					   (audio_attr->channels + 1)
					   && lAudioDefault == 1)
					  || (lAudioDefault == 0
					      && strcmp (szAudioFormatDeutsch,
							 "dts") == 0))
					{
					  lAudioTrackDeutsch = 0;	// wird mit folgenden Abfragen neu gesetzt
					}
				      if ((lAudioTrackEnglisch
					   && strcmp (lang_code, "en") == 0
					   && lAnzahlChannelEnglisch <
					   (audio_attr->channels + 1)
					   && lAudioDefault == 1)
					  || (lAudioDefault == 0
					      &&
					      strcmp (szAudioFormatEnglisch,
						      "dts") == 0))
					{
					  lAudioTrackEnglisch = 0;	// wird mit folgenden Abfragen neu gesetzt
					}
				      if (lSprachAuswahl == 4)
					{
					  if ((lZusatzAudioTrack
					       && strcmp (lang_code,
							  szZusatzSprache) ==
					       0
					       && lZusatzAnzahlChannel <
					       (audio_attr->channels + 1)
					       && lAudioDefault == 1)
					      || (lAudioDefault == 0
						  &&
						  strcmp (szZusatzAudioFormat,
							  "dts") == 0))
					    {
					      lZusatzAudioTrack = 0;	// wird mit folgenden Abfragen neu gesetzt
					    }
					}
				      if ((audio_attr->channels + 1) == 2)
					lAudioKBPS = 128;
				      else
					lAudioKBPS = 384;
				      lPlatzAudio +=
					(lAudioKBPS / 8 * lAnzahlSekunden *
					 1000);
				      if (lDebugLevel)
					printf
					  ("Groesse Audio Track %d: %ld\n", i,
					   lAudioKBPS / 8 * lAnzahlSekunden *
					   1000);
				      if (!lAudioTrackDeutsch
					  && strcmp (lang_code, "de") == 0)
					{
					  lPlatzAudioDeutsch =
					    lAudioKBPS / 8 * lAnzahlSekunden *
					    1000;
					}
				      if (!lAudioTrackEnglisch
					  && strcmp (lang_code, "en") == 0)
					{
					  lPlatzAudioEnglisch =
					    lAudioKBPS / 8 * lAnzahlSekunden *
					    1000;
					}
				      if (lSprachAuswahl == 4
					  && !lZusatzAudioTrack
					  && strcmp (lang_code,
						     szZusatzSprache) == 0)
					{
					  lZusatzPlatzAudio =
					    lAudioKBPS / 8 * lAnzahlSekunden *
					    1000;
					}
				    }
				  if (strcmp
				      (audio_format[audio_attr->audio_format],
				       "dts") == 0)
				    {
				      long lAudioKBPS = 768;	//1509;
				      // dts hat in der Regel bessere Qualitaet als ac3, daher dts
				      // bevorzugen.
				      if (lAudioTrackDeutsch
					  && strcmp (lang_code, "de") == 0
					  && lAudioDefault == 2)
					{
					  lAudioTrackDeutsch = 0;	// wird mit folgenden Abfragen neu gesetzt
					}
				      if (lAudioTrackEnglisch
					  && strcmp (lang_code, "en") == 0
					  && lAudioDefault == 2)
					{
					  lAudioTrackEnglisch = 0;	// wird mit folgenden Abfragen neu gesetzt
					}
				      if (lSprachAuswahl == 4
					  && lZusatzAudioTrack
					  && strcmp (lang_code,
						     szZusatzSprache) == 0
					  && lAudioDefault == 2)
					{
					  lZusatzAudioTrack = 0;	// wird mit folgenden Abfragen neu gesetzt
					}
				      lPlatzAudio +=
					(lAudioKBPS / 8 * lAnzahlSekunden *
					 1000);
				      if (lDebugLevel)
					printf
					  ("Groesse Audio Track %d: %ld\n", i,
					   lAudioKBPS / 8 * lAnzahlSekunden *
					   1000);
				      if (!lAudioTrackDeutsch
					  && strcmp (lang_code, "de") == 0)
					{
					  lPlatzAudioDeutsch =
					    lAudioKBPS / 8 * lAnzahlSekunden *
					    1000;
					}
				      if (!lAudioTrackEnglisch
					  && strcmp (lang_code, "en") == 0)
					{
					  lPlatzAudioEnglisch =
					    lAudioKBPS / 8 * lAnzahlSekunden *
					    1000;
					}
				      if (lSprachAuswahl == 4
					  && !lZusatzAudioTrack
					  && strcmp (lang_code,
						     szZusatzSprache) == 0)
					{
					  lZusatzPlatzAudio =
					    lAudioKBPS / 8 * lAnzahlSekunden *
					    1000;
					}
				    }
				  if (!lAudioTrackDeutsch
				      && strcmp (lang_code, "de") == 0)
				    {
				      lAudioTrackDeutsch = i + 1;
				      strcpy (szAudioFormatDeutsch,
					      audio_format[audio_attr->
							   audio_format]);
				      lAnzahlChannelDeutsch =
					audio_attr->channels + 1;
				    }
				  if (!lAudioTrackEnglisch
				      && strcmp (lang_code, "en") == 0)
				    {
				      lAudioTrackEnglisch = i + 1;
				      strcpy (szAudioFormatEnglisch,
					      audio_format[audio_attr->
							   audio_format]);
				      lAnzahlChannelEnglisch =
					audio_attr->channels + 1;
				    }
				  if (lSprachAuswahl == 4
				      && !lZusatzAudioTrack
				      && strcmp (lang_code,
						 szZusatzSprache) == 0)
				    {
				      lZusatzAudioTrack = i + 1;
				      strcpy (szZusatzAudioFormat,
					      audio_format[audio_attr->
							   audio_format]);
				      lZusatzAnzahlChannel =
					audio_attr->channels + 1;
				    }
				  lAnzahlAudioTracks = i + 1;
				  strcpy (szAudioFormatAllgemein,
					  audio_format[audio_attr->
						       audio_format]);
				}
			      // Ueberpruefe, ob Track nach Voreinstellung gefunden.
			      // Wenn nicht gefunden, dann umschalten auf manuelle Auswahl.
			      if (!lAudioTrackDeutsch
				  && (lSprachAuswahl == 1
				      || lSprachAuswahl == 3))
				{
				  switch (lSprache)
				    {
				    case 0:
				      printf
					("\nKein deutscher Audiotrack!\n");
				      break;
				    case 1:
				      printf ("\nNo german audiotrack!\n");
				      break;
				    case 2:
				      printf
					("\nPas de piste audio en allemand !\n");
				      break;
				    }
				  lSprachAuswahl = 5;	// stattdessen manuell waehlen
				}
			      if (!lAudioTrackEnglisch
				  && (lSprachAuswahl == 2
				      || lSprachAuswahl == 3))
				{
				  switch (lSprache)
				    {
				    case 0:
				      printf
					("\nKein englischer Audiotrack!\n");
				      break;
				    case 1:
				      printf ("\nNo english audiotrack!\n");
				      break;
				    case 2:
				      printf
					("\nPas de piste audio en anglais !\n");
				      break;
				    }
				  lSprachAuswahl = 5;	// stattdessen manuell waehlen
				}
			      if (!lZusatzAudioTrack && lSprachAuswahl == 4)
				{
				  switch (lSprache)
				    {
				    case 0:
				      printf
					("\nKein Audiotrack in gewaehlter Sprache '%s'!\n",
					 szZusatzSprache);
				      break;
				    case 1:
				      printf
					("\nNo audiotrack in selected language '%s'!\n",
					 szZusatzSprache);
				      break;
				    case 2:
				      printf
					("\nPas de piste audio dans la langue demandée '%s'!\n",
					 szZusatzSprache);
				      break;
				    }
				  lSprachAuswahl = 5;	// stattdessen manuell waehlen
				}
			    }
			  // Freie Auswahl der Audiotracks vorschalten
			  if (lSprachAuswahl == 5)
			    {
			      switch (lSprache)
				{
				case 0:
				  printf
				    ("\nAuswahl von bis zu 2 Audiotracks:\n\n");
				  break;
				case 1:
				  printf ("\nSelect 1 or 2 audiotracks:\n\n");
				  break;
				case 2:
				  printf
				    ("\nChoisissez 1 ou 2 pistes audio:\n\n");
				  break;
				}
			      for (i = 0;
				   i < vtsi_mat->nr_of_vts_audio_streams; i++)
				{
				  audio_attr = &vtsi_mat->vts_audio_attr[i];
				  sprintf (lang_code, "%c%c",
					   audio_attr->lang_code >> 8,
					   audio_attr->lang_code & 0xff);
				  if (!lang_code[0])
				    {
				      strcpy (lang_code, "xx");
				    }
				  switch (lSprache)
				    {
				    case 0:
				      printf
					("Track-Nr: %d, Sprache: %s, Format: %s, Kanaele: %d\n",
					 i + 1, lang_code,
					 audio_format[audio_attr->
						      audio_format],
					 audio_attr->channels + 1);
				      break;
				    case 1:
				      printf
					("Track-No: %d, Language: %s, Format: %s, Channels: %d\n",
					 i + 1, lang_code,
					 audio_format[audio_attr->
						      audio_format],
					 audio_attr->channels + 1);
				      break;
				    case 2:
				      printf
					("Piste-No: %d, Langue: %s, Format: %s, Canaux: %d\n",
					 i + 1, lang_code,
					 audio_format[audio_attr->
						      audio_format],
					 audio_attr->channels + 1);
				      break;
				    }
				}
			      // Track-Nr eingeben
			      switch (lSprache)
				{
				case 0:
				  printf
				    ("\nWelche Tracks? Bsp: Fuer Track 1 und 3 muss \"1,3\" eingegeben werden !\n");
				  break;
				case 1:
				  printf
				    ("\nWhich tracks? I. E.: For track 1 and 3 you have to enter \"1,3\" !\n");
				  break;
				case 2:
				  printf
				    ("\nPistes ? Par exemple pour les pistes 1 et 3 entrez \"1,3\"\n");
				  break;
				}
			      input_zahlen (&lAudioTrackInput1,
					    &lAudioTrackInput2,
					    vtsi_mat->
					    nr_of_vts_audio_streams);
			      switch (lSprache)
				{
				case 0:
				  printf
				    ("\nGewaehlte Audiotracks: %ld / %ld\n",
				     lAudioTrackInput1, lAudioTrackInput2);
				  break;
				case 1:
				  printf
				    ("\nSelected audiotracks: %ld / %ld\n",
				     lAudioTrackInput1, lAudioTrackInput2);
				  break;
				case 2:
				  printf
				    ("\nPistes audio choisies : %ld / %ld\n",
				     lAudioTrackInput1, lAudioTrackInput2);
				  break;
				}
			      // Kein Track gewaehlt
			      if (lAudioTrackInput1 == 0
				  && lAudioTrackInput2 == 0)
				{
				  switch (lSprache)
				    {
				    case 0:
				      printf
					("\nKeine Audiotracks ausgewaehlt!\n");
				      break;
				    case 1:
				      printf ("\nNo audiotracks selected!\n");
				      break;
				    case 2:
				      printf
					("\nAucune piste audio choisie !\n");
				      break;
				    }
				  ifoClose (ifo_zero);
				  DVDClose (dvd);
				  return 0;
				}
			      // Track-Nr groesser als Nr. auf der DVD
			      if (lAudioTrackInput1 >
				  vtsi_mat->nr_of_vts_audio_streams
				  || lAudioTrackInput2 >
				  vtsi_mat->nr_of_vts_audio_streams)
				{
				  switch (lSprache)
				    {
				    case 0:
				      printf
					("\nNur %d Audiotracks auf der DVD!\n",
					 vtsi_mat->nr_of_vts_audio_streams);
				      break;
				    case 1:
				      printf
					("\nOnly %d audiotracks on the DVD!\n",
					 vtsi_mat->nr_of_vts_audio_streams);
				      break;
				    case 2:
				      printf
					("\nIl n'y a que %d pistes sur ce DVD !\n",
					 vtsi_mat->nr_of_vts_audio_streams);
				      break;
				    }
				  ifoClose (ifo_zero);
				  DVDClose (dvd);
				  return 0;
				}
			      lLaengeInput1 = 0;
			      lLaengeInput2 = 0;
			      strcpy (szFormatInput1, "ac3");
			      strcpy (szFormatInput2, "ac3");
			      // Nochmals lesen und anhand der gewaehlten Nr. die Daten setzen
			      for (i = 0;
				   i < vtsi_mat->nr_of_vts_audio_streams; i++)
				{
				  char szLanguage[128];
				  long long lLaengeInput;
				  audio_attr = &vtsi_mat->vts_audio_attr[i];
				  sprintf (szLanguage, "%c%c",
					   audio_attr->lang_code >> 8,
					   audio_attr->lang_code & 0xff);
				  if (!szLanguage[0])
				    {
				      strcpy (szLanguage, "xx");
				    }
				  // Ueber Bitrate Groesse in Bytes berechnen
				  if (strstr
				      (audio_format[audio_attr->audio_format],
				       "ac3"))
				    {
				      if ((audio_attr->channels + 1) == 2)
					lLaengeInput = 128;
				      else
					lLaengeInput = 384;
				    }
				  else
				    {
				      if (strstr
					  (audio_format
					   [audio_attr->audio_format],
					   "mpeg"))
					{
					  lLaengeInput = 192;	// mpeg1 hat 192 kbps
					}
				      else
					{
					  lLaengeInput = 768;	// sonst dts Groesse als Default
					}
				    }
				  lLaengeInput =
				    lLaengeInput / 8 * lAnzahlSekunden * 1000;
				  lPlatzAudio += lLaengeInput;
				  if ((i + 1) == lAudioTrackInput1)
				    {
				      strcpy (szFormatInput1,
					      audio_format[audio_attr->
							   audio_format]);
				      strcpy (szSpracheInput1, szLanguage);
				      lLaengeInput1 = lLaengeInput;
				      printf
					("Groesse Audiotrack %ld: %lld Bytes\n",
					 lAudioTrackInput1, lLaengeInput1);
				    }
				  if ((i + 1) == lAudioTrackInput2)
				    {
				      strcpy (szFormatInput2,
					      audio_format[audio_attr->
							   audio_format]);
				      strcpy (szSpracheInput2, szLanguage);
				      lLaengeInput2 = lLaengeInput;
				      printf
					("Groesse Audiotrack %ld: %lld Bytes\n",
					 lAudioTrackInput2, lLaengeInput2);
				    }
				}
			    }
			}
		    }

		  // CHAPTERS
		  cell = 0;
		  if (opt_c)
		    {
		      if (opt_p)
			{
			  unsigned long total_sectors = 0;
			  ARRAY ("chapter");
			  for (i = 0; i < pgc->nr_of_programs; i++)
			    {
			      int ms = 0;
			      int next = pgc->program_map[i + 1];
			      unsigned long sectors = 0;
			      if (i == pgc->nr_of_programs - 1)
				next = pgc->nr_of_cells + 1;
			      while (cell < next - 1)
				{
				  ms =
				    ms +
				    dvdtime2msec (&pgc->cell_playback[cell].
						  playback_time);
				  sectors +=
				    pgc->cell_playback[cell].last_sector -
				    pgc->cell_playback[cell].first_sector + 1;
				  cell++;
				}
			      total_sectors += sectors;
			      HASH ("");
			      DEF ("ix", "%d", i + 1);
			      DEF ("length", "%.3f", ms / 1000.0);
			      DEF ("startcell", "%d", pgc->program_map[i]);
			      DEF ("sectors", "%lu", sectors);
			      RETURN;
			    }
			  RETURN;
			  DEF ("sectors", "%lu", total_sectors);
			}
		      else
			{
			  // High-Qualitymodus: berechne Kapitel in der Mitte
			  long lStartWithChapter = 0;
			  long lStopByChapter = pgc->nr_of_programs;
			  long bFirst = 0;
			  long long lMilliSekunden = 0;
			  if ((lPackMethode == 2 || lPackMethode == 4) && !lUseVLC)// Standard fuer Kapitel bei Transcode
			    {
			      strcpy (szHQChapters, "-1");
			    }
			  if (lHighQuality)
			    {
			      long lSpielDauer = 0;
			      cell = 0;
			      for (i = 0; i < pgc->nr_of_programs; i++)
				{
				  int next = pgc->program_map[i + 1];
				  if (i == pgc->nr_of_programs - 1)
				    next = pgc->nr_of_cells + 1;
				  while (cell < next - 1)
				    {
				      lSpielDauer +=
					(millisekunden
					 (&pgc->cell_playback[cell].
					  playback_time) / 1000);
				      cell++;
				    }
				  if ((lSpielDauer * 2) >= lAnzahlSekunden)
				    {
				      if (lHighQuality == 1)	// 1. Haelfte der DVD
					{
					  lStartWithChapter = 0;	// Startkapitel
					  lStopByChapter = i + 1;	// Endkapitel  
                                          if (lUseVLC == 0) 
 					    sprintf (szHQChapters, "%d-%d", 1, i + 1);
                                          else
 					    sprintf (szHQChapters, ":%d-%ld:%d", 1, opt_t, i + 1);
					}
				      else	// 2. Haelfte der DVD
					{
					  lStartWithChapter = i + 1;	// Startkapitel
					  lStopByChapter = pgc->nr_of_programs;	// Endkapitel
                                          if (lUseVLC == 0)
					    sprintf (szHQChapters, "%d-%d", i + 2, pgc->nr_of_programs);
                                          else
					    sprintf (szHQChapters, ":%d-%ld:%d", i + 2, opt_t, pgc->nr_of_programs);
					}
				      strcpy (szBefehl, szHQChapters);
				      switch (lPackMethode)
					{
					case 1:	// vamps
					  break;
					case 2:	// Transcode (parallel=2, seriell=4)
					case 4:
					  // bereits korrekt
					  break;
					case 3:	// mplayer
					  sprintf (szHQChapters,
						   "-chapter %s", szBefehl);
					  break;
					}
				      break;
				    }
				}
			    }
			  // Anzahl Sektoren berechnen
			  cell = 0;
			  lAnzahlSektoren = 0;
			  lTestKapitel = ((pgc->nr_of_programs + 1) / 2) + 1;
			  for (i = 0; i < pgc->nr_of_programs; i++)
			    {
			      unsigned long sectors = 0;
			      int next = pgc->program_map[i + 1];
			      if (i == pgc->nr_of_programs - 1)
				next = pgc->nr_of_cells + 1;
			      while (cell < next - 1)
				{
				  sectors +=
				    pgc->cell_playback[cell].last_sector -
				    pgc->cell_playback[cell].first_sector + 1;
				  cell++;
				  // Sektoren der Testzelle
				  if (cell == lTestZelle)
				    lSektorenTestzelle = sectors;
				}
			      lAnzahlSektoren += sectors;
			      // Kapitelanzahl des Testkapitels setzen
			      if ((i + 1) == lTestKapitel)
				lSektorenTestkapitel = sectors;
			    }
			  // Kapitelstring zusammensetzen
			  strcpy (szChapterString, "-c 00:00:00.000");
			  cell = 0;
			  for (i = lStartWithChapter; i < lStopByChapter; i++)
			    {
			      int second = 0, minute = 0, hour = 0, tmp;
			      char hex[20];
			      int next = pgc->program_map[i + 1];
			      // Bei HQ im zweiten Durchlauf Zeit der vorherigen Kapitel abziehen
			      if (!bFirst && lStartWithChapter > 0)
				{
				  cell = pgc->program_map[i] - 1;
				}
			      bFirst = 1;
			      if (i == pgc->nr_of_programs - 1)
				next = pgc->nr_of_cells + 1;
			      while (cell < next - 1)
				{
				  lMilliSekunden +=
				    millisekunden (&pgc->cell_playback[cell].
						   playback_time);
				  sprintf (hex, "%02x",
					   pgc->cell_playback[cell].
					   playback_time.second);
				  tmp = second + atoi (hex);
				  minute = minute + (tmp / 60);
				  second = tmp % 60;
				  sprintf (hex, "%02x",
					   pgc->cell_playback[cell].
					   playback_time.minute);
				  tmp = minute + atoi (hex);
				  hour = hour + (tmp / 60);
				  minute = tmp % 60;
				  cell++;
				}
			      if (lDebugLevel)
				printf
				  ("\tChapter: %02d, Length: %02d:%02d:%02d, Start Cell: %02d\n",
				   i + 1, hour, minute, second,
				   pgc->program_map[i]);
			      // Das letzte Kapitel muss nicht mehr angegeben werden,
			      // da jeweils Startzeit
			      if (i < (lStopByChapter - 1))
				{
				  char szDummy[128];
				  sprintf (szDummy,
					   ",%02lld:%02lld:%02lld.%03lld",
					   lMilliSekunden / 3600000,
					   (lMilliSekunden / 60000) % 60,
					   (lMilliSekunden / 1000) % 60,
					   lMilliSekunden % 1000);
				  strcat (szChapterString, szDummy);
				}
			    }
			  if (lDebugLevel)
			    printf ("\tTotal sectors: %ld\n",
				    lAnzahlSektoren);
			}
		    }
		  // CELLS
		  if (opt_d)
		    {
		      if (opt_p)
			{
			  ARRAY ("cell");
			  for (i = 0; i < pgc->nr_of_cells; i++)
			    {
			      HASH ("");
			      DEF ("ix", "%d", i + 1);
			      DEF ("length", "%.3f",
				   dvdtime2msec (&pgc->cell_playback[i].
						 playback_time) / 1000.0);
			      RETURN;
			    }
			  RETURN;
			}
		      else
			{
			  for (i = 0; i < pgc->nr_of_cells; i++)
			    {
			      if (lDebugLevel)
				printf
				  ("\tCell: %02d, Length: %02x:%02x:%02x\n",
				   i + 1,
				   pgc->cell_playback[i].playback_time.hour,
				   pgc->cell_playback[i].playback_time.minute,
				   pgc->cell_playback[i].playback_time.
				   second);
			    }
			}
		    }

		  // SUBTITLES
		  if (opt_s)
		    {
		      if (opt_p)
			{
			  ARRAY ("subp");
			  for (i = 0; i < vtsi_mat->nr_of_vts_subp_streams;
			       i++)
			    {
			      subp_attr = &vtsi_mat->vts_subp_attr[i];
			      sprintf (lang_code, "%c%c",
				       subp_attr->lang_code >> 8,
				       subp_attr->lang_code & 0xff);
			      if (!lang_code[0])
				{
				  strcpy (lang_code, "xx");
				}

			      HASH ("");
			      DEF ("ix", "%d", i + 1);
			      DEF ("langcode", "'%s'", lang_code);
			      DEF ("language", "'%s'", lang_name (lang_code));
			      DEF ("content", "'%s'",
				   subp_type[subp_attr->lang_extension]);
			      RETURN;
			    }
			  RETURN;
			}
		      else
			{
			  // Gibt es ueberhaupt Untertitel ?
			  if (lUntertitel != 0
			      && vtsi_mat->nr_of_vts_subp_streams == 0)
			    {
			      switch (lSprache)
				{
				case 0:
				  printf ("\nKeine Untertitel!\n");
				  break;
				case 1:
				  printf ("\nNo subpicture tracks!\n");
				  break;
				case 2:
				  printf ("\nPas de piste S/T!\n");
				  break;
				}
			      lUntertitel = 0;	// deaktivieren
			    }
			  if (lUntertitel == -2)	// Auswahl ueber Sprache
			    {
			      for (i = 0;
				   i < vtsi_mat->nr_of_vts_subp_streams; i++)
				{
				  subp_attr = &vtsi_mat->vts_subp_attr[i];
				  // Dummys ueberspringen
				  if (subp_attr->type == 0)
				    continue;
				  sprintf (lang_code, "%c%c",
					   subp_attr->lang_code >> 8,
					   subp_attr->lang_code & 0xff);
				  if (!lang_code[0])
				    {
				      strcpy (lang_code, "xx");
				    }
				  if (strcmp (szUntertitelSprache, lang_code)
				      == 0)
				    {
				      lUntertitel = i + 1;
				      break;
				    }
				}
			      // Wenn kein Untertitel in Sprache laut Einstellung gefunden,
			      // umschalten auf manuelle Auswahl
			      if (lUntertitel == -2)
				{
				  switch (lSprache)
				    {
				    case 0:
				      printf
					("\nKein Untertitel in gewaehlter Sprache '%s'!\n",
					 szUntertitelSprache);
				      break;
				    case 1:
				      printf
					("\nNo subpicture track in selected language '%s'!\n",
					 szUntertitelSprache);
				      break;
				    case 2:
				      printf
					("\nPas de piste S/T dans la langue demandée '%s'!\n",
					 szUntertitelSprache);
				      break;
				    }
				  lUntertitel = -1;	// stattdessen manuell waehlen
				}
			    }
			  if (lUntertitel == -4)	// Alle, speichern in interner Struktur
			    {
			      lAnzahlUntertitel = 0;
			      for (i = 0;
				   i < vtsi_mat->nr_of_vts_subp_streams; i++)
				{
				  subp_attr = &vtsi_mat->vts_subp_attr[i];
				  sprintf (lang_code, "%c%c",
					   subp_attr->lang_code >> 8,
					   subp_attr->lang_code & 0xff);
				  if (!lang_code[0])
				    {
				      strcpy (lang_code, "xx");
				    }
				  if (subp_attr->type > 0)
				    {
				      strcpy (szUntertitelListe
					      [lAnzahlUntertitel], lang_code);
				      lUntertitelListe[lAnzahlUntertitel] =
					i + 1;
				      lAnzahlUntertitel++;
				    }
				}
			    }
			  if (lUntertitel == -1)	// Untertitel anzeigen
			    {
			      long lZaehler = 0;
			      switch (lSprache)
				{
				case 0:
				  printf
				    ("\nListe der verfuegbaren Untertitel:\n\n");
				  break;
				case 1:
				  printf
				    ("\nList of available subpicture tracks:\n\n");
				  break;
				case 2:
				  printf
				    ("\nListe des pistes S/T disponibles :\n\n");
				  break;
				}
			      for (i = 0;
				   i < vtsi_mat->nr_of_vts_subp_streams; i++)
				{
				  subp_attr = &vtsi_mat->vts_subp_attr[i];
				  // Dummy-Untertitel ueberspringen
				  if (subp_attr->type == 0)
				    continue;
				  sprintf (lang_code, "%c%c",
					   subp_attr->lang_code >> 8,
					   subp_attr->lang_code & 0xff);
				  if (!lang_code[0])
				    {
				      strcpy (lang_code, "xx");
				    }
				  switch (lSprache)
				    {
				    case 0:
				      {
					printf
					  ("\tUntertitel: %02d, Sprache: %s - %s, ",
					   i + 1, lang_code,
					   lang_name (lang_code));
					printf ("Inhalt: %s",
						subp_type[subp_attr->
							  lang_extension]);
					break;
				      }
				    case 1:
				      {
					printf
					  ("\tSubtitle: %02d, Language: %s - %s, ",
					   i + 1, lang_code,
					   lang_name (lang_code));
					printf ("Content: %s",
						subp_type[subp_attr->
							  lang_extension]);
					break;
				      }
				    case 2:
				      {
					printf
					  ("\tS/T : %02d, Langue: %s - %s, ",
					   i + 1, lang_code,
					   lang_name (lang_code));
					printf ("Contenu : %s",
						subp_type[subp_attr->
							  lang_extension]);
					break;
				      }
				    }
				  printf ("\n");
				  lZaehler++;
				  if (lZaehler == 15)	// Max 15. Zeilen, dann naechste Seite
				    {
				      printf ("=> Enter\n");
				      eatToNL (stdin);
				      lZaehler = 0;
				    }
				}
			      // Track-Nr eingeben
			      switch (lSprache)
				{
				case 0:
				  printf
				    ("\nWelche Tracks? Bsp: Fuer Track 1 und 3 muss \"1,3\" eingegeben werden !\n");
				  break;
				case 1:
				  printf
				    ("\nWhich tracks? I. E.: For track 1 and 3 you have to enter \"1,3\" !\n");
				  break;
				case 2:
				  printf
				    ("\nPistes ? Par exemple pour les pistes 1 et 3 entrez \"1,3\"\n");
				  break;
				}
			      input_zahlen (&lUntertitel, &lUntertitel2,
					    vtsi_mat->nr_of_vts_subp_streams);
			    }
			  for (i = 0; i < vtsi_mat->nr_of_vts_subp_streams;
			       i++)
			    {
			      subp_attr = &vtsi_mat->vts_subp_attr[i];
			      sprintf (lang_code, "%c%c",
				       subp_attr->lang_code >> 8,
				       subp_attr->lang_code & 0xff);
			      if (!lang_code[0])
				{
				  strcpy (lang_code, "xx");
				}
			      if (lDebugLevel)
				printf
				  ("\tSubtitle: %02d, Language: %s - %s, ",
				   i + 1, lang_code, lang_name (lang_code));
			      if (lDebugLevel)
				printf ("Content: %s",
					subp_type[subp_attr->lang_extension]);
			      if (lDebugLevel)
				printf ("\n");
			      // Untertitel fuer DVD-Author zusammensetzen
			      if (lUntertitel && (i == (lUntertitel - 1)))
				{
				  sprintf (szUntertitelOptionen, "-s %s",
					   lang_code);
				  sprintf (szUntertitelSprache1, "%s",
					   lang_code);
				  szUntertitelSprache1[2] = 0;
				}
			    }
			  if (lUntertitel2)
			    {
			      for (i = 0;
				   i < vtsi_mat->nr_of_vts_subp_streams; i++)
				{
				  subp_attr = &vtsi_mat->vts_subp_attr[i];
				  sprintf (lang_code, "%c%c",
					   subp_attr->lang_code >> 8,
					   subp_attr->lang_code & 0xff);
				  if (!lang_code[0])
				    {
				      strcpy (lang_code, "xx");
				    }
				  if (lDebugLevel)
				    printf
				      ("\tSubtitle: %02d, Language: %s - %s, ",
				       i + 1, lang_code,
				       lang_name (lang_code));
				  if (lDebugLevel)
				    printf ("Content: %s",
					    subp_type[subp_attr->
						      lang_extension]);
				  if (lDebugLevel)
				    printf ("\n");
				  // Untertitel fuer DVD-Author zusammensetzen
				  if (lUntertitel2
				      && (i == (lUntertitel2 - 1)))
				    {
				      sprintf (szUntertitelOptionen +
					       strlen (szUntertitelOptionen),
					       ",%s", lang_code);
				      sprintf (szUntertitelSprache2, "%s",
					       lang_code);
				      szUntertitelSprache2[2] = 0;
				    }
				}
			    }
			  switch (lSprache)
			    {
			    case 0:
			      printf ("\nUntertitel-Track-Nr: %ld/%ld/%s\n",
				      lUntertitel, lUntertitel2,
				      szUntertitelOptionen);
			      break;
			    case 1:
			      printf ("\nSubpicture-Track-No: %ld/%ld/%s\n",
				      lUntertitel, lUntertitel2,
				      szUntertitelOptionen);
			      break;
			    case 2:
			      printf ("\nPiste S/T No: %ld/%ld/%s\n",
				      lUntertitel, lUntertitel2,
				      szUntertitelOptionen);
			      break;
			    }
			}
		    }
		  RETURN;
		}
	      if (!opt_p && (opt_a || opt_c || opt_p || opt_s || opt_n))
		if (lDebugLevel)
		  printf ("\n");
	    }
	}
      RETURN;
      if (!opt_t)
	{
	  if (opt_p)
	    {
	      DEF ("longest_track", "%d", max_track);
	    }
	  else
	    {
	      if (lDebugLevel)
		printf ("Longest track: %d\n", max_track);
	    }
	}

      // Groesserer Winkel gewaehlt als Angles im Titel?
      if (ifo_zero->tt_srpt->title[opt_t - 1].nr_of_angles < lAngle
	  && lAngle > 0)
	{
	  switch (lSprache)
	    {
	    case 0:
	      printf ("Nur %ld Angles (Winkel) auf der DVD vorhanden!\n",
		      ifo_zero->tt_srpt->title[opt_t - 1].nr_of_angles);
	      break;
	    case 1:
	      printf ("Only %ld Angles on DVD!\n",
		      ifo_zero->tt_srpt->title[opt_t - 1].nr_of_angles);
	      break;
	    case 2:
	      printf ("Seulement %ld Angles!\n",
		      ifo_zero->tt_srpt->title[opt_t - 1].nr_of_angles);
	      break;
	    }
	  return 0;
	}

      // Winkel (Angle) Parameter
      if (lAngle > 0)
	{
	  switch (lPackMethode)
	    {
	    case 2:		// vlc, Transcode parallel
	    case 4:		// vlc, Transcode
              if (lUseVLC > 0)
	        sprintf (szAngle, " --dvdnav-angle=%ld ", lAngle);
              else
	        sprintf (szAngle, ",%ld", lAngle);
	      break;
	    case 3:		// mplayer
	      sprintf (szAngle, " -dvdangle %ld ", lAngle);
	      break;
	    default:
	      break;
	    }
	}

      for (i = 1; i <= ifo_zero->vts_atrt->nr_of_vtss; i++)
	{
	  ifoClose (ifo[i]);
	}
      ifoClose (ifo_zero);
      DVDClose (dvd);


      if (dFaktor > 0 || lPackMethode >= 5)
	{
	  lPlatzVideo = ((long long) lAnzahlSektoren * (long long) 2048);	//wegen Anzeige unten
	}

      // Testrip eines Kapitel mit tccat/tcextract, um den Faktor zu bestimmen (-f=-1)
      if (dFaktor < 0)
	{
	  lPlatzVideo =
	    ((long long) 2 * (long long) lAnzahlSektoren) /
	    ((long long) 1024);
	  if (lPlatzVideo <= 4380)	// KB je DVD 
	    {
	      dFaktor = 1;	// keine Requantisierung
	      lPlatzVideo = ((long long) lAnzahlSektoren * (long long) 2048);	//wegen Anzeige unten
	      switch (lSprache)
		{
		case 0:
		  printf
		    ("Testrip unnoetig, Groesse DVD kleiner als 4380 MB, nehme Faktor 1.0!\n");
		  break;
		case 1:
		  printf
		    ("Testrip unnecessary, DVD < 4380 MB, Factor 1.0!\n");
		  break;
		case 2:
		  printf ("Test inutile, DVD < 4380 MB, Facteur 1.0 !\n");
		  break;
		}
	    }
	  else
	    {
	      if (dFaktor == -1 && lPackMethode == 1)	// Testrip mit vamps
		{
		  long lAudioSpur;
		  long long lTestVideo = 0;
		  long long lTestAudio = 0;
		  long long lTestGesamt = 0;
		  struct stat tmpStat;
		  switch (lSprache)
		    {
		    case 0:
		      printf ("Faktorberechnung mit playcell/vamps\n\n");
		      break;
		    case 1:
		      printf
			("Calculation of requant factor with playcell/vamps\n\n");
		      break;
		    case 2:
		      printf
			("Facteur de requant calculé par playcell/vamps\n\n");
		      break;
		    }
		  // Tests auf Programme
		  check_program (play_cell_name, lSprache, 1);
		  check_program (vamps_name, lSprache, 1);
		  // Fifo-Queues anlegen
		  sprintf (szBefehl, "mkfifo %s/vid.fifo", szTmpDir);
		  system (szBefehl);
		  sprintf (szBefehl, "mkfifo %s/komplett.fifo", szTmpDir);
		  system (szBefehl);
		  // Nur Video extrahieren
		  sprintf (szBefehl, "cat %s/vid.fifo | %s > %s/ofile.m2v &",
			   szTmpDir, vamps_name, szTmpDir);
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		  sleep (1);
		  // Gesamt inkl. Audio
		  sprintf (szBefehl, "cat %s/komplett.fifo | %s -a ",
			   szTmpDir, vamps_name);
		  switch (lSprachAuswahl)
		    {
		    case 1:
		      lAudioSpur = lAudioTrackDeutsch;
		      break;
		    case 2:
		      lAudioSpur = lAudioTrackEnglisch;
		      break;
		    case 3:
		      lAudioSpur = lAudioTrackDeutsch;
		      break;
		    case 4:
		      lAudioSpur = lZusatzAudioTrack;
		      break;
		    case 5:
		      lAudioSpur = lAudioTrackInput1;
		      break;
		    }
		  sprintf (szBefehl + strlen (szBefehl), "%ld", lAudioSpur);
		  if (lSprachAuswahl == 3 ||	// 2. Audiospur englisch zusaetzlich rippen
		      (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
		    {
		      if (lSprachAuswahl == 3)
			lAudioSpur = lAudioTrackEnglisch;
		      else
			lAudioSpur = lAudioTrackInput2;
		      sprintf (szBefehl + strlen (szBefehl), ",%ld",
			       lAudioSpur);
		    }
		  sprintf (szBefehl + strlen (szBefehl), " > %s/ofile.vob &",
			   szTmpDir);
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		  sleep (1);
		  // Testkapitel rippen und verteilen auf Queues
		  sprintf (szBefehl,
			   "%s %s -r 2 -i -g %s %ld %ld %ld | tee %s/vid.fifo %s/komplett.fifo > /dev/null",
			   szNiceRip, play_cell_name, dvd_device, lVTS, lPGC,
			   angle_cell_array[lTestZelle - 1], szTmpDir,
			   szTmpDir);
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		  sleep (5);
		  // Einzelne Dateien berechnen
		  sprintf (szBefehl, "%s/ofile.vob", szTmpDir);
		  if (stat (szBefehl, &tmpStat) == 0)
		    {
		      lTestGesamt = tmpStat.st_size;
		    }
		  sprintf (szBefehl, "%s/ofile.m2v", szTmpDir);
		  if (stat (szBefehl, &tmpStat) == 0)
		    {
		      lTestVideo = tmpStat.st_size;
		    }
		  lTestAudio = lTestGesamt - lTestVideo;
		  // Nur berechnen, wenn Dateigroesse jeweils mehr als 0
		  if (lTestGesamt && lTestVideo && lTestGesamt > lTestVideo)
		    {
		      // Umrechnen auf Gesamtfilm 
		      lTestVideo =
			lTestVideo * (long long) lAnzahlSektoren /
			(long long) lSektorenTestzelle;
		      lTestAudio =
			lTestAudio * (long long) lAnzahlSektoren /
			(long long) lSektorenTestzelle;
		      switch (lSprache)
			{
			case 0:
			  {
			    printf ("Groesse Videotrack in Bytes:  %lld\n",
				    lTestVideo);
			    printf ("Groesse Audiotracks in Bytes: %lld\n",
				    lTestAudio);
			    break;
			  }
			case 1:
			  {
			    printf ("Video size in Bytes:  %lld\n",
				    lTestVideo);
			    printf ("Audio size in Bytes: %lld\n",
				    lTestAudio);
			    break;
			  }
			case 2:
			  {
			    printf ("Taille video en octets :  %lld\n",
				    lTestVideo);
			    printf ("Taille audio en octets : %lld\n",
				    lTestAudio);
			    break;
			  }
			}
		      dFaktor =
			(double) lTestVideo / (double) (lGroesseDVDBytes -
							lTestAudio);
		      if (lUntertitel > 0)
			dFaktor = dFaktor + (dFaktor / (double) 100);	// 1 % Reserve bei Untertiteln
		      if (lAnzahlUntertitel > 0)	// alle Untertitel
			dFaktor += ((dFaktor / (double) 100) * (double) 2);	// 2 % extra
		      if (dFaktor < 1)
			dFaktor = 1;
		      switch (lSprache)
			{
			case 0:
			  printf ("Ergebnis Testrip: Faktor: %f\n", dFaktor);
			  break;
			case 1:
			  printf ("Result of testrip: factor: %f\n", dFaktor);
			  break;
			case 2:
			  printf ("Résultat du test : facteur: %f\n",
				  dFaktor);
			  break;
			}
		    }
		  else
		    {
		      // Testrip hat nicht funktioniert, also mit Faktor 0 neu setzen
		      switch (lSprache)
			{
			case 0:
			  printf
			    ("\nTestrip fehlgeschlagen, Faktor wird berechnet!\n");
			  break;
			case 1:
			  printf
			    ("\nTestrip failed, factor will be calculated!\n");
			  break;
			case 2:
			  printf
			    ("\nLe test a échoué, le facteur sera calculé !\n");
			  break;
			}
		      dFaktor = 0;
		    }
		  lPlatzVideo = ((long long) lAnzahlSektoren * (long long) 2048);	//wegen Anzeige unten
		  // Fifo-Queues wieder loeschen
		  sprintf (szBefehl, "rm %s/vid.fifo", szTmpDir);
		  system (szBefehl);
		  sprintf (szBefehl, "rm %s/komplett.fifo", szTmpDir);
		  system (szBefehl);
		  // Temp-Dateien loeschen 
		  sprintf (szBefehl, "rm %s/ofile.m2v", szTmpDir);
		  system (szBefehl);
		  sprintf (szBefehl, "rm %s/ofile.vob", szTmpDir);
		  system (szBefehl);
		}
	      if (dFaktor == -1 && lPackMethode != 1)	// Testrip mit Transcode
		{
		  char szAudioFormat1[12];
		  char szAudioFormat2[12];
		  char szAc3scan[128];
		  char szBufferBefehl[1024];
		  long lAudioSpur;
		  long long lTestVideo = 0;
		  long long lTestAudio = 0;
		  long long lTestGesamt = 0;
		  struct stat tmpStat;
		  switch (lSprache)
		    {
		    case 0:
		      printf ("Faktorberechnung mit Transcode\n\n");
		      break;
		    case 1:
		      printf
			("Calculation of requant factor with transcode\n\n");
		      break;
		    case 2:
		      printf
			("Facteur de requant calculé par transcode\n\n");
		      break;
		    }
		  // Tests auf Programme
                  if (lUseVLC > 0)
		    check_program (vlc_name, lSprache, 1);
                  else
		    check_program (tccat_name, lSprache, 1);
		  check_program (tcextract_name, lSprache, 1);
		  // Buffer verwenden
		  if (check_program (buffer_name, lSprache, 0))
		    {
		      // Befehl fuer Buffer-Programm zusammensetzen
		      if (strstr (buffer_name, "bfr"))
			{
			  sprintf (szBufferBefehl, "%s 2>/dev/null <", buffer_name);	// nehme bfr
			}
		      else
			{
			  if (strstr (buffer_name, "mbuffer"))
			    sprintf (szBufferBefehl, "%s -s 64k -q -i", buffer_name);	// nehme mbuffer
			  else
			    sprintf (szBufferBefehl, "%s -s 64k -m 16m -i", buffer_name);	// nehme buffer
			}
		    }
		  else
		    {
		      sprintf (szBufferBefehl, "cat");	// Buffer ist nicht installiert
		    }
		  if (lMultiplexer == 1)
		    check_program (tcmplex_name, lSprache, 1);
		  else
		    check_program (mplex_name, lSprache, 1);
		  switch (lSprache)
		    {
		    case 0:
		      {
			printf ("\nTestrip Kapitel %ld\n", lTestKapitel);
			printf
			  ("Anzahl Sektoren gesamt: %ld / Sektoren Testkapitel: %ld\n",
			   lAnzahlSektoren, lSektorenTestkapitel);
			break;
		      }
		    case 1:
		      {
			printf ("\nTest Chapter %ld\n", lTestKapitel);
			printf
			  ("Total sector count: %ld / Test chapter size: %ld\n",
			   lAnzahlSektoren, lSektorenTestkapitel);
			break;
		      }
		    case 2:
		      {
			printf ("\nChapitre test %ld\n", lTestKapitel);
			printf
			  ("Taille totale en secteurs: %ld / taille du chapitre test: %ld\n",
			   lAnzahlSektoren, lSektorenTestkapitel);
			break;
		      }
		    }
		  // Nun mit Transcode per Pipes das Kapitel rippen
		  // Videospur
		  sprintf (szBefehl, "mkfifo %s/vid.fifo", szTmpDir);
		  system (szBefehl);
		  sprintf (szBefehl,
			   "%s %s/vid.fifo | %s -t vob -x mpeg2 > %s/ofile.m2v &",
			   szBufferBefehl, szTmpDir, tcextract_name,
			   szTmpDir);
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		  sleep (1);
		  // Audiospur 1
		  sprintf (szBefehl, "mkfifo %s/aud1.fifo", szTmpDir);
		  system (szBefehl);
		  switch (lSprachAuswahl)
		    {
		    case 1:
		      lAudioSpur = lAudioTrackDeutsch;
		      strcpy (szAudioFormat1, szAudioFormatDeutsch);
		      break;
		    case 2:
		      lAudioSpur = lAudioTrackEnglisch;
		      strcpy (szAudioFormat1, szAudioFormatEnglisch);
		      break;
		    case 3:
		      lAudioSpur = lAudioTrackDeutsch;
		      strcpy (szAudioFormat1, szAudioFormatDeutsch);
		      break;
		    case 4:
		      lAudioSpur = lZusatzAudioTrack;
		      strcpy (szAudioFormat1, szZusatzAudioFormat);
		      break;
		    case 5:
		      lAudioSpur = lAudioTrackInput1;
		      strcpy (szAudioFormat1, szFormatInput1);
		      break;
		    }
		  if (strstr (szAudioFormat1, "pcm"))
		    strcpy (szAudioFormat1, "pcm");
		  if (strstr (szAudioFormat1, "mpeg"))
		    strcpy (szAudioFormat1, "mp3");
		  if (strstr (szAudioFormat1, "ac3")
		      && !check_program (tcmplex_name, lSprache, 0))
		    sprintf (szAc3scan, " | %s ", lxac3scan_name);
		  else
		    strcpy (szAc3scan, "");
		  lAudioSpur--;	// tcextrcat beginnt mit Spur 0
                  // DTS muss nochmals ueber vlc laufen.
                  // Ausnahme: Nur ein Audiotrack.
                  // Dann erfolgt unten die Vorauswahl des Audiotracks
                  if (lUseVLC > 0 && strstr (szAudioFormat1, "dts") &&
		      (lSprachAuswahl == 3 ||
		       (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
                     )
                  {
		    sprintf (szBefehl,
                          "%s %s/aud1.fifo | "
                          "%s /dev/stdin --intf dummy --no-video "
                          "--audio-track %ld "
                          "--sout '#standard{access=file,mux=ps,dst=/dev/stdout}' "
                          "vlc:quit "
                          "| %s -t vob -x %s > "
                          "%s/ofile.%s &",
			  szBufferBefehl, szTmpDir, 
			  vlc_name, lAudioSpur, 
                          tcextract_name, szAudioFormat1, szTmpDir,
			  szAudioFormat1);
                  } else
                  {
                    // VLC, nur eine Audiospur, nur eine Spur im Stream!
                    if (lUseVLC > 0 && 
		        !(lSprachAuswahl == 3 ||
		         (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
                       )
		      sprintf (szBefehl,
			   "%s %s/aud1.fifo "
                           "| %s -t vob -x %s -a 0 %s > %s/ofile.%s &",
			   szBufferBefehl, szTmpDir, tcextract_name,
			   szAudioFormat1, szAc3scan, szTmpDir,
			   szAudioFormat1);
                    else 
		      sprintf (szBefehl,
			   "%s %s/aud1.fifo "
                           "| %s -t vob -x %s -a %ld %s > %s/ofile.%s &",
			   szBufferBefehl, szTmpDir, tcextract_name,
			   szAudioFormat1, lAudioSpur, szAc3scan, szTmpDir,
			   szAudioFormat1);
                  }
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		  sleep (1);
		  if (lSprachAuswahl == 3 ||	// 2. Audiospur englisch zusaetzlich rippen
		      (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
		    {
		      sprintf (szBefehl, "mkfifo %s/aud2.fifo", szTmpDir);
		      system (szBefehl);
		      if (lSprachAuswahl == 3)
			{
			  lAudioSpur = lAudioTrackEnglisch;
			  strcpy (szAudioFormat2, szAudioFormatEnglisch);
			}
		      else
			{
			  lAudioSpur = lAudioTrackInput2;
			  strcpy (szAudioFormat2, szFormatInput2);
			}
		      if (strstr (szAudioFormat2, "pcm"))
			strcpy (szAudioFormat2, "pcm");
		      if (strstr (szAudioFormat2, "mpeg"))
			strcpy (szAudioFormat2, "mp3");
		      if (strstr (szAudioFormat2, "ac3")
			  && !check_program (tcmplex_name, lSprache, 0))
			sprintf (szAc3scan, " | %s ", lxac3scan_name);
		      else
			strcpy (szAc3scan, "");
		      lAudioSpur--;	// tcextrcat beginnt mit Spur 0
                      // DTS muss nochmals ueber vlc laufen
                      if (lUseVLC > 0 && strstr (szAudioFormat2, "dts"))
                      {
		        sprintf (szBefehl,
                          "%s %s/aud2.fifo | "
                          "%s /dev/stdin --intf dummy --no-video "
                          "--audio-track %ld "
                          "--sout '#standard{access=file,mux=ps,dst=/dev/stdout}' "
                          "vlc:quit "
                          "| %s -t vob -x %s > "
                          "%s/ofile.%s &",
			  szBufferBefehl, szTmpDir, 
			  vlc_name, lAudioSpur, 
                          tcextract_name, szAudioFormat2, szTmpDir,
			  szAudioFormat2);
                      } else
                      {
		        sprintf (szBefehl,
			       "%s %s/aud2.fifo | %s -t vob -x %s -a %ld %s > %s/ofile_2.%s &",
			       szBufferBefehl, szTmpDir, tcextract_name,
			       szAudioFormat2, lAudioSpur, szAc3scan,
			       szTmpDir, szAudioFormat2);
                      }
		      printf ("%s\n", szBefehl);
		      system (szBefehl);
		      sleep (1);
                      if (lUseVLC > 0)
                      {
		        sprintf (szBefehl,
                               "%s %s dvdsimple:%s@%ld:%ld%s --intf dummy --sout-all --no-spu --sout '#standard{access=file,mux=ps,dst=/dev/stdout}' vlc:quit "
                               " | tee %s/aud1.fifo %s/aud2.fifo %s/vid.fifo > /dev/null",
			       szNiceRip, vlc_name, dvd_device, (long) opt_t,
			       lTestKapitel, szAngle, szTmpDir, szTmpDir,
			       szTmpDir);
                      } else
                      {
		        sprintf (szBefehl,
			       "%s %s -i %s -T %ld,%ld%s -P | tee %s/aud1.fifo %s/aud2.fifo %s/vid.fifo > /dev/null",
			       szNiceRip, tccat_name, dvd_device, (long) opt_t,
			       lTestKapitel, szAngle, szTmpDir, szTmpDir,
			       szTmpDir);
                      }
		    }
		  else
		    {
                      // Zweig fuer einen Audiotrack
                      if (lUseVLC > 0)
                      {
		        sprintf (szBefehl,
                               "%s %s dvdsimple:%s@%ld:%ld%s --intf dummy "
                               "--audio-track %ld "
                               "--sout '#standard{access=file,mux=ps,"
                               "dst=/dev/stdout}' vlc:quit "
                               " | tee %s/aud1.fifo %s/vid.fifo > /dev/null",
			       szNiceRip, vlc_name, dvd_device, (long) opt_t,
			       lTestKapitel, szAngle, lAudioSpur,
                               szTmpDir, szTmpDir);
                      } else
                      {
		        sprintf (szBefehl,
			       "%s %s -i %s -T %ld,%ld%s -P | tee %s/aud1.fifo %s/vid.fifo > /dev/null",
			       szNiceRip, tccat_name, dvd_device, (long) opt_t,
			       lTestKapitel, szAngle, szTmpDir, szTmpDir);
                      }
		    }
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		  system ("sleep 5");
		  // Pipes wieder loeschen
		  sprintf (szBefehl, "rm %s/vid.fifo", szTmpDir);
		  system (szBefehl);
		  sprintf (szBefehl, "rm %s/aud1.fifo", szTmpDir);
		  system (szBefehl);
		  if ((lSprachAuswahl == 3)
		      || (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
		    {
		      sprintf (szBefehl, "rm %s/aud2.fifo", szTmpDir);
		      system (szBefehl);
		    }
		  // Jetzt multiplexen / tcmplex als Default
		  if (lMultiplexer == 1
		      || check_program (tcmplex_name, lSprache, 0))
		    {
		      sprintf (szBefehl,
			       "%s %s -m d -o %s/ofile.vob -i %s/ofile.m2v -p %s/ofile.%s",
			       szNiceRip, tcmplex_name, szTmpDir, szTmpDir, szTmpDir,
			       szAudioFormat1);
		      if ((lSprachAuswahl == 3)
			  || (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
			{
			  strcat (szBefehl, " -s ");
			  strcat (szBefehl, szTmpDir);
			  strcat (szBefehl, "/ofile_2.");
			  strcat (szBefehl, szAudioFormat2);
			}
		    }
		  else
		    {
		      sprintf (szBefehl,
			       "%s %s -f 8 -S 0 -M -o %s/ofile.vob %s/ofile.m2v %s/ofile.%s",
			       szNiceRip, mplex_name, szTmpDir, szTmpDir,
			       szTmpDir, szAudioFormat1);
		      if ((lSprachAuswahl == 3)
			  || (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
			{
			  strcat (szBefehl, " ");
			  strcat (szBefehl, szTmpDir);
			  strcat (szBefehl, "/ofile_2.");
			  strcat (szBefehl, szAudioFormat2);
			}
		    }
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		  // Groessenberechnung
		  // Einzelne Dateien berechnen
		  sprintf (szBefehl, "%s/ofile.vob", szTmpDir);
		  if (stat (szBefehl, &tmpStat) == 0)
		    {
		      lTestGesamt = tmpStat.st_size;
		    }
		  sprintf (szBefehl, "%s/ofile.m2v", szTmpDir);
		  if (stat (szBefehl, &tmpStat) == 0)
		    {
		      lTestVideo = tmpStat.st_size;
		    }
		  sprintf (szBefehl, "%s/ofile.%s", szTmpDir, szAudioFormat1);
		  if (stat (szBefehl, &tmpStat) == 0)
		    {
		      lTestAudio += tmpStat.st_size;
		    }
		  sprintf (szBefehl, "%s/ofile_2.%s", szTmpDir,
			   szAudioFormat2);
		  if (stat (szBefehl, &tmpStat) == 0)
		    {
		      lTestAudio += tmpStat.st_size;
		    }
		  if (lTestAudio > 0 && lTestVideo > 0)
		    {
		      double dKorrektur =
			(double) lTestGesamt / (double) (lTestVideo +
							 lTestAudio);
		      // Umrechnen auf Gesamtfilm 
		      lTestVideo =
			lTestVideo * (long long) lAnzahlSektoren /
			(long long) lSektorenTestkapitel;
		      lTestAudio =
			lTestAudio * (long long) lAnzahlSektoren /
			(long long) lSektorenTestkapitel;
		      switch (lSprache)
			{
			case 0:
			  {
			    printf ("Groesse Videotrack in Bytes:  %lld\n",
				    lTestVideo);
			    printf ("Groesse Audiotracks in Bytes: %lld\n",
				    lTestAudio);
			    break;
			  }
			case 1:
			  {
			    printf ("Video size in Bytes:  %lld\n",
				    lTestVideo);
			    printf ("Audio size in Bytes: %lld\n",
				    lTestAudio);
			    break;
			  }
			case 2:
			  {
			    printf ("Taille video en octets :  %lld\n",
				    lTestVideo);
			    printf ("Taille audio en octets : %lld\n",
				    lTestAudio);
			    break;
			  }
			}
		      dFaktor =
			(double) lTestVideo / (double) (lGroesseDVDBytes -
							lTestAudio);
		      if (dKorrektur > 0)
			{
			  dFaktor = dFaktor * dKorrektur;	// Korrektur um mplex-Faktor
			}
		      else
			{
			  dFaktor = dFaktor + (dFaktor / (double) 100 * (double) 3);	// 3 % Reserve allgemein
			}
		      if (lUntertitel != 0)
			dFaktor = dFaktor + (dFaktor / (double) 100);	// 1 % Reserve bei Untertiteln
		      dFaktor = dFaktor + (dFaktor / (double) 200);	// 0.5 % Overhead fuer dvdauthor
		      if (dFaktor < 1)
			dFaktor = 1;
		      switch (lSprache)
			{
			case 0:
			  printf ("Ergebnis Testrip: Faktor: %f\n", dFaktor);
			  break;
			case 1:
			  printf ("Result of testrip: factor: %f\n", dFaktor);
			  break;
			case 2:
			  printf ("Résultat du test : facteur: %f\n",
				  dFaktor);
			  break;
			}
		    }
		  else
		    {
		      // Testrip hat nicht funktioniert, also mit Faktor 0 neu setzen
		      switch (lSprache)
			{
			case 0:
			  printf
			    ("\nTestrip fehlgeschlagen, Faktor wird berechnet!\n");
			  break;
			case 1:
			  printf
			    ("\nTestrip failed, factor will be calculated!\n");
			  break;
			case 2:
			  printf
			    ("\nLe test a échoué, le facteur sera calculé !\n");
			  break;
			}
		      dFaktor = 0;
		    }
		  lPlatzVideo = ((long long) lAnzahlSektoren * (long long) 2048);	//wegen Anzeige unten
		  // Und nun auch noch alle TMP-Dateien loeschen
		  sprintf (szBefehl, "rm %s/ofile.vob", szTmpDir);
		  system (szBefehl);
		  sprintf (szBefehl, "rm %s/ofile.m2v", szTmpDir);
		  system (szBefehl);
		  sprintf (szBefehl, "rm %s/ofile.%s", szTmpDir,
			   szAudioFormat1);
		  system (szBefehl);
		  if ((lSprachAuswahl == 3) ||
		      (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
		    {
		      sprintf (szBefehl, "rm %s/ofile_2.%s", szTmpDir,
			       szAudioFormat2);
		      system (szBefehl);
		    }
		}
	    }
	}

      if (lPackMethode < 5 && dFaktor == 0)
	{
	  // Faktor Berechnung Stefan Becker          
	  // Platz fuer Video in Bytes
	  lPlatzVideo = ((long long) lAnzahlSektoren * (long long) 2048);
	  if (lPlatzVideo <= lGroesseDVDBytes)
	    dFaktor = 1;	// keine Requantisierung
	  else
	    {
	      // Code aus Streamanalyze uebernommen
              if (lPruefen > 0) // Eventuell Zugriff probelmatisch, darum bei Abschaltung der Pruefung 
              {                 // die lxdvdrip-Methode nehmen
	      char szAudioFormat1[12];
	      char szAudioFormat2[12];
	      long lAudioSpur;
	      switch (lSprache)
		{
		case 0:
		  printf ("Faktorberechnung mit streamanalyze\n\n");
		  break;
		case 1:
		  printf
		    ("Calculation of requant factor with streamanalyze\n\n");
		  break;
		case 2:
		  printf
		    ("Calcul du facteur de requant par streamanalyze\n\n");
		  break;
		}
	      // zu rippende Tracks festlegen, 
	      // 0xe0=1. Videospur
	      sprintf (szRipTracks, "0xe0");
	      // >= 0x80 Audiospur ac3
	      // >= 0x88 dts
	      // >= 0xA0 LPCM
	      // >= 0xC0 MPEG1/2
	      switch (lSprachAuswahl)
		{
		case 1:
		  lAudioSpur = lAudioTrackDeutsch;
		  strcpy (szAudioFormat1, szAudioFormatDeutsch);
		  break;
		case 2:
		  lAudioSpur = lAudioTrackEnglisch;
		  strcpy (szAudioFormat1, szAudioFormatEnglisch);
		  break;
		case 3:
		  lAudioSpur = lAudioTrackDeutsch;
		  strcpy (szAudioFormat1, szAudioFormatDeutsch);
		  break;
		case 4:
		  lAudioSpur = lZusatzAudioTrack;
		  strcpy (szAudioFormat1, szZusatzAudioFormat);
		  break;
		case 5:
		  lAudioSpur = lAudioTrackInput1;
		  strcpy (szAudioFormat1, szFormatInput1);
		  break;
		}
	      lAudioSpur--;
	      if (strstr (szAudioFormat1, "ac3"))
		{
		  lAudioSpur += 0x80;
		}
	      if (strstr (szAudioFormat1, "dts"))
		{
		  lAudioSpur += 0x88;
		}
	      if (strstr (szAudioFormat1, "lpcm"))
		{
		  lAudioSpur += 0xa0;
		}
	      if (strstr (szAudioFormat1, "mpeg"))
		{
		  lAudioSpur += 0xc0;
		}
	      sprintf (szRipTracks + strlen (szRipTracks), ",0x%lx",
		       lAudioSpur);
	      if (lSprachAuswahl == 3 ||	// 2. Audiospur englisch zusaetzlich rippen
		  (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
		{
		  if (lSprachAuswahl == 3)
		    {
		      lAudioSpur = lAudioTrackEnglisch;
		      strcpy (szAudioFormat2, szAudioFormatEnglisch);
		    }
		  else
		    {
		      lAudioSpur = lAudioTrackInput2;
		      strcpy (szAudioFormat2, szFormatInput2);
		    }
		  lAudioSpur--;	// tcextrcat beginnt mit Spur 0
		  if (strstr (szAudioFormat2, "ac3"))
		    {
		      lAudioSpur += 0x80;
		    }
		  if (strstr (szAudioFormat2, "dts"))
		    {
		      lAudioSpur += 0x88;
		    }
		  if (strstr (szAudioFormat2, "lpcm"))
		    {
		      lAudioSpur += 0xa0;
		    }
		  if (strstr (szAudioFormat2, "mpeg"))
		    {
		      lAudioSpur += 0xc0;
		    }
		  sprintf (szRipTracks + strlen (szRipTracks), ",0x%lx",
			   lAudioSpur);
		}
	      // Mit Untertiteltrack (0=ohne)
	      if (lUntertitel > 0 && strlen (szRipTracks))
		{
		  long lUntertitelSpur = lUntertitel - 1 + 0x20;
		  sprintf (szRipTracks + strlen (szRipTracks), ",0x%lx",
			   lUntertitelSpur);
		}
	      if (lUntertitel2 > 0 && strlen (szRipTracks))
		{
		  long lUntertitelSpur = lUntertitel2 - 1 + 0x20;
		  sprintf (szRipTracks + strlen (szRipTracks), ",0x%lx",
			   lUntertitelSpur);
		}
	      dFaktor = stream_faktor (dvd_device, opt_t, szRipTracks);
	      // Im Bereich kleiner 1 Minimum 1 nehmen
	      if (dFaktor > 0 && dFaktor < 1)
		dFaktor = 1;
	      // Wenn Faktor zu gross brechnet, neu berechnen mit lxdvdrip-Methode
	      if (dFaktor > 10)
		dFaktor = 0;
	      // Sicherheitsreserve
	      if (dFaktor > 1)
		{
		  dFaktor += ((dFaktor / (double) 100) * (double) 2);
		  if (lUntertitel > 0)
		    dFaktor += ((dFaktor / (double) 100));
		  if (lAnzahlUntertitel > 0)	// alle Untertitel
		    dFaktor += ((dFaktor / (double) 100) * (double) 2);	// 2 % extra
		}
              }
	      lPlatzVideo = ((long long) lAnzahlSektoren * (long long) 2048);	//wegen Anzeige unten
// Streamanalyze war nicht erfolgreich, lxdvdrip-Methode
	      if (dFaktor == 0)
		{
		  switch (lSprachAuswahl)
		    {
		    case 1:
		      dFaktor =
			(double) (lPlatzVideo -
				  lPlatzAudio) / (double) (lGroesseDVDBytes -
							   lPlatzAudioDeutsch);
		      break;
		    case 2:
		      dFaktor =
			(double) (lPlatzVideo -
				  lPlatzAudio) / (double) (lGroesseDVDBytes -
							   lPlatzAudioEnglisch);
		      break;
		    case 3:
		      dFaktor =
			(double) (lPlatzVideo -
				  lPlatzAudio) / (double) (lGroesseDVDBytes -
							   lPlatzAudioDeutsch
							   -
							   lPlatzAudioEnglisch);
		      break;
		    case 4:
		      dFaktor =
			(double) (lPlatzVideo -
				  lPlatzAudio) / (double) (lGroesseDVDBytes -
							   lZusatzPlatzAudio);
		      break;
		    case 5:
		      dFaktor =
			(double) (lPlatzVideo -
				  lPlatzAudio) / (double) (lGroesseDVDBytes -
							   lLaengeInput1 -
							   lLaengeInput2);
		      break;
		    }
		  // 3 % aufschlagen zur Sicherheit
		  dFaktor = dFaktor + (dFaktor / (double) 100 * (double) 3);
		  // Bei Untertiteln ein zusaetzliches Prozent Sicherheit
		  if (lUntertitel > 0)
		    {
		      dFaktor = dFaktor + (dFaktor / (double) 100);
		    }
		  if (lAnzahlUntertitel > 0)	// alle Untertitel
		    dFaktor += ((dFaktor / (double) 100) * (double) 2);	// 2 % extra
		  // Und ein Prozent Sicherheit bei 2 Audiospuren
		  if (lSprachAuswahl == 3 ||	// 2. Audiospur englisch zusaetzlich rippen
		      (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
		    {
		      dFaktor = dFaktor + (dFaktor / (double) 100);
		    }
		}
	      switch (lSprache)
		{
		case 0:
		  printf
		    ("\nFaktor wird mit Abzug Audio Tracks berechnet !\n");
		  break;
		case 1:
		  printf
		    ("\nFactor will be calculated with substraction of audio tracks!\n");
		  break;
		case 2:
		  printf
		    ("\nLe facteur sera calculé avec soustraction des pistes audio !\n");
		  break;
		}
	    }
	}

      // Faktor unter 1 macht keinen Sinn
      if (dFaktor < 1)
	{
	  switch (lSprache)
	    {
	    case 0:
	      printf ("Faktor %f wird auf 1 gesetzt!\n", dFaktor);
	      break;
	    case 1:
	      printf ("Factor %f forced to 1!\n", dFaktor);
	      break;
	    case 2:
	      printf ("Facteur %f forcé à 1 !\n", dFaktor);
	      break;
	    }
	  dFaktor = 1;
	}

      // Faktor bei High Quality-Modus immer 1
      if (lHighQuality && dFaktor <= 1)
	{
	  switch (lSprache)
	    {
	    case 0:
	      printf
		("\nHigh Quality Backup unnoetig, da eine DVD-5 ausreichend!\n");
	      break;
	    case 1:
	      printf
		("\nHigh Quality Backup not needed, because one DVD-5 is enough!\n");
	      break;
	    case 2:
	      printf
		("\nCopie Haute Qualité inutile, un seul DVD-5 est suffisant!\n");
	      break;
	    }
	  return 0;
	}
      // Ansonsten immer 1 bei High Quality als Faktor
      if (lHighQuality)
	dFaktor = 1;

      switch (lSprache)
	{
	case 0:
	  {
	    printf ("\n");
	    printf ("Laengster Titel:        %d\n", max_track);
	    printf ("\n");
	    printf ("Infos zu Titel:         %d\n", opt_t);
	    printf ("\n");
	    printf ("Anzahl Sektoren:        %ld (%lld Bytes)\n",
		    lAnzahlSektoren, lPlatzVideo);
	    printf ("Spieldauer in Sekunden: %ld\n", lAnzahlSekunden);
	    printf ("Anzahl Kapitel:         %ld\n", lAnzahlKapitel);
	    printf ("Anzahl Audio Streams:   %ld\n", lAnzahlAudioStreams);
	    if (lSprachAuswahl == 4)
	      {
		printf ("Audio Track '%s':       %ld (%lld Bytes)\n",
			szZusatzSprache, lZusatzAudioTrack,
			lZusatzPlatzAudio);
	      }
	    else
	      {
		if (lSprachAuswahl == 5)
		  {
		    printf ("Audio Track 1 (%s):     %ld (%lld Bytes)\n",
			    szSpracheInput1, lAudioTrackInput1,
			    lLaengeInput1);
		    printf ("Audio Track 2 (%s):     %ld (%lld Bytes)\n",
			    szSpracheInput2, lAudioTrackInput2,
			    lLaengeInput2);
		  }
		else
		  {
		    printf ("Audio Track deutsch:    %ld (%lld Bytes)\n",
			    lAudioTrackDeutsch, lPlatzAudioDeutsch);
		    printf ("Audio Track Englisch:   %ld (%lld Bytes)\n",
			    lAudioTrackEnglisch, lPlatzAudioEnglisch);
		  }
	      }
	    printf ("Groesse AudioStreams:   %lld\n", lPlatzAudio);
	    printf ("Groesse Video Stream:   %lld\n",
		    lPlatzVideo - lPlatzAudio);
	    printf ("Requantsierungsfaktor:  %f\n\n\n", dFaktor);
	    break;
	  }
	case 1:
	  {
	    printf ("\n");
	    printf ("Longest title:          %d\n", max_track);
	    printf ("\n");
	    printf ("Infos for title:         %d\n", opt_t);
	    printf ("\n");
	    printf ("No of sectors:          %ld (%lld bytes)\n",
		    lAnzahlSektoren, lPlatzVideo);
	    printf ("Length of film in seconds: %ld\n", lAnzahlSekunden);
	    printf ("No of chapters:         %ld\n", lAnzahlKapitel);
	    printf ("No of audio streams:    %ld\n", lAnzahlAudioStreams);
	    if (lSprachAuswahl == 4)
	      {
		printf ("Audio track '%s':       %ld (%lld bytes)\n",
			szZusatzSprache, lZusatzAudioTrack,
			lZusatzPlatzAudio);
	      }
	    else
	      {
		if (lSprachAuswahl == 5)
		  {
		    printf ("Audio track 1 (%s):     %ld (%lld bytes)\n",
			    szSpracheInput1, lAudioTrackInput1,
			    lLaengeInput1);
		    printf ("Audio Track 2 (%s):     %ld (%lld bytes)\n",
			    szSpracheInput2, lAudioTrackInput2,
			    lLaengeInput2);
		  }
		else
		  {
		    printf ("Audio Track german:     %ld (%lld bytes)\n",
			    lAudioTrackDeutsch, lPlatzAudioDeutsch);
		    printf ("Audio Track english:    %ld (%lld bytes)\n",
			    lAudioTrackEnglisch, lPlatzAudioEnglisch);
		  }
	      }
	    printf ("Size of audio streams:   %lld\n", lPlatzAudio);
	    printf ("Size of video:          %lld\n", lPlatzVideo);
	    printf ("Requant-Factor:         %f\n\n\n", dFaktor);
	    break;
	  }
	case 2:
	  {
	    printf ("\n");
	    printf ("Titre le plus long:      %d\n", max_track);
	    printf ("\n");
	    printf ("Infos pour le titre:     %d\n", opt_t);
	    printf ("\n");
	    printf ("Nb de secteurs:         %ld (%lld octets)\n",
		    lAnzahlSektoren, lPlatzVideo);
	    printf ("Durée du film en secondes: %ld\n", lAnzahlSekunden);
	    printf ("Nb de chapitres:        %ld\n", lAnzahlKapitel);
	    printf ("Nb de flux audio:       %ld\n", lAnzahlAudioStreams);
	    if (lSprachAuswahl == 4)
	      {
		printf ("Piste audio '%s':       %ld (%lld octets)\n",
			szZusatzSprache, lZusatzAudioTrack,
			lZusatzPlatzAudio);
	      }
	    else
	      {
		if (lSprachAuswahl == 5)
		  {
		    printf ("Piste audio 1 (%s):     %ld (%lld octets)\n",
			    szSpracheInput1, lAudioTrackInput1,
			    lLaengeInput1);
		    printf ("Piste audio 2 (%s):     %ld (%lld octets)\n",
			    szSpracheInput2, lAudioTrackInput2,
			    lLaengeInput2);
		  }
		else
		  {
		    printf ("Piste audio allemande:  %ld (%lld octets)\n",
			    lAudioTrackDeutsch, lPlatzAudioDeutsch);
		    printf ("Piste audio anglaise:   %ld (%lld bytes)\n",
			    lAudioTrackEnglisch, lPlatzAudioEnglisch);
		  }
	      }
	    printf ("Taille des flux audio:  %lld\n", lPlatzAudio);
	    printf ("Taille video:           %lld\n", lPlatzVideo);
	    printf ("Facteur de requant:     %f\n\n\n", dFaktor);
	    break;
	  }
	}
      // Kapitelunterteilung uebernehmen ?
      if (!lMitKapiteln)
	{
	  strcpy (szChapterString, "");	// ohne Kapitel
	}
      // Chapter mit tcprobe uebernehmen
      // Liste wird formatiert in Datei geschrieben und per cat and dvdauthor uebergeben
      // Grund: wegen Free BSD
      if (lMitKapiteln == 2)
	{
	  // Tests auf Programme
	  check_program (tcprobe_name, lSprache, 1);
	  sprintf (szChapterFile, "%s/chapter.lxdvdrip", szTmpDir);
	  sprintf (szBefehl,
		   "tcprobe -i %s -T %ld -H 10 2>&1 | egrep \"\\[Chapter ..\\] \" |"
		   "  cut -d \" \" -f 4 | perl -pi -e 's/\\n/,/' "
		   "| perl -pi -e 's/,$//' >%s", dvd_device, (long) opt_t,
		   szChapterFile);
	  printf ("%s\n", szBefehl);
	  system (szBefehl);
	  sprintf (szChapterString, "-c `cat %s`", szChapterFile);
	}

      // Projektnamen an das Filmverzeichnis anhaengen
      strcpy (szAltesFilmVerzeichnis, szFilmVerzeichnis);
      if (strlen (szDVDName))
	{
	  if (szFilmVerzeichnis[strlen (szFilmVerzeichnis) - 1] != '/')
	    {
	      strcat (szFilmVerzeichnis, "/");
	    }
	  strcat (szFilmVerzeichnis, szDVDName);
	  if (lHighQuality == 1)
	    strcat (szFilmVerzeichnis, "_1");
	  if (lHighQuality == 2)
	    strcat (szFilmVerzeichnis, "_2");
	}

      // Test, ob Datei im Rip-Verzeichnis vorhanden
      checkLastRip (szFilmVerzeichnis, lSprache);

      // DVD rippen mit vamps (dvdauthor per XML)
      if (lPackMethode == 1)
	{
	  // Backup inkl. Menue
	  if (lMenues > 0)
	    {
	      // Backup inkl. Menue
	      // Audio- und Untertitelspuren
	      AudioMap_t audioMap;
	      SubMap_t subMap;
	      long lAudioSpur1 = 0, lAudioSpur2 = 0;
	      int k;
	      // Audiospuren setzen
	      for (k = 0; k < MAX_AUDIO_TRACK; k++)
		{
		  audioMap.audioTracks[k] = 0;
		}
	      switch (lSprachAuswahl)
		{
		case 1:
		  lAudioSpur1 = lAudioTrackDeutsch;
		  break;
		case 2:
		  lAudioSpur1 = lAudioTrackEnglisch;
		  break;
		case 3:
		  lAudioSpur1 = lAudioTrackDeutsch;
		  lAudioSpur2 = lAudioTrackEnglisch;
		  break;
		case 4:
		  lAudioSpur1 = lZusatzAudioTrack;
		  break;
		case 5:
		  lAudioSpur1 = lAudioTrackInput1;
		  if (lAudioTrackInput2 > 0)
		    {
		      lAudioSpur2 = lAudioTrackInput2;
		    }
		  break;
		}
	      audioMap.audioTracks[0] = lAudioSpur1;
	      audioMap.audioTracks[1] = lAudioSpur2;
	      // Untertitel setzen
	      for (k = 0; k < MAX_SUB_TRACK; k++)
		{
		  subMap.subTracks[k] = 0;
		}
	      // 1 oder 2 Untertitel
	      if (lUntertitel > 0)
		{
		  subMap.subTracks[0] = lUntertitel;
		  if (lUntertitel2 > 0)
		    {
		      subMap.subTracks[1] = lUntertitel2;
		    }
		}
	      // Alle Untertitel (ausser "xx") kopieren
	      if (lAnzahlUntertitel > 0)
		{
		  for (k = 0; k < lAnzahlUntertitel; k++)
		    {
		      subMap.subTracks[k] = k + 1;
		    }
		}
	      // DVD-Name ist Pflicht
	      if (!strlen (szDVDName))
		strcpy (szDVDName, "DVD");
	      // Backup Main-VTS
	      FullBackupDvd (opt_vts - 1, &audioMap, &subMap, dFaktor, szDVDName,
                             dvd_device, szAltesFilmVerzeichnis, "", 
                             1, 0	// (1=Faktorneuberechnung , 0=kein Fullbackup)
		            );
	    }
	  else
	    {
	      char szAudioFormat1[128], szAudioFormat2[128];
	      char szAudioLanguage1[10], szAudioLanguage2[10];
              char szDebugVamps[128];
              char szInjectionFile[256];
	      long lAudioSpur1 = 0, lAudioSpur2 =
		0, lAktuelleZelle, lZelleVon, lZelleBis;
	      char szVampsBefehl[1024];
	      FILE *fXML;
	      char szXML[256];
              long long lGesamtGroesse=0;
              long long lGroesseGerippt=0;
	      // Tests auf Programme
	      check_program (dvdauthor_name, lSprache, 1);
	      check_program (vamps_name, lSprache, 1);
	      check_program (play_cell_name, lSprache, 1);
	      // Oeffne XML-File
	      sprintf (szXML, "%s/dvdauthor.xml", szTmpDir);
	      fXML = fopen_warnung (szXML, "w", lSprache);
	      // XML Datei mit Basisverzeichnis beginnen
	      fprintf (fXML, "<dvdauthor dest=\"%s\">\n", szFilmVerzeichnis);
	      fprintf (fXML, "<titleset>\n");
	      fprintf (fXML, "<titles>\n");
	      if (strlen (szVideoAngaben))
		fprintf (fXML, "%s\n", szVideoAngaben);
	      // Sprachauswahl / Audiotracks zusammensetzen
	      // >= 0x80 Audiospur ac3
	      // >= 0x88 dts
	      // >= 0xA0 LPCM
	      // >= 0xC0 MPEG1/2
	      strcpy (szAudioLanguage1, "");
	      strcpy (szAudioLanguage2, "");
	      switch (lSprachAuswahl)
		{
		case 1:
		  lAudioSpur1 = lAudioTrackDeutsch;
		  strcpy (szAudioFormat1, szAudioFormatDeutsch);
		  strcpy (szAudioLanguage1, "de");
		  break;
		case 2:
		  lAudioSpur1 = lAudioTrackEnglisch;
		  strcpy (szAudioFormat1, szAudioFormatEnglisch);
		  strcpy (szAudioLanguage1, "en");
		  break;
		case 3:
		  lAudioSpur1 = lAudioTrackDeutsch;
		  strcpy (szAudioFormat1, szAudioFormatDeutsch);
		  strcpy (szAudioLanguage1, "de");
		  lAudioSpur2 = lAudioTrackEnglisch;
		  strcpy (szAudioFormat2, szAudioFormatEnglisch);
		  strcpy (szAudioLanguage2, "en");
		  break;
		case 4:
		  lAudioSpur1 = lZusatzAudioTrack;
		  strcpy (szAudioFormat1, szZusatzAudioFormat);
		  strcpy (szAudioLanguage1, szZusatzSprache);
		  break;
		case 5:
		  lAudioSpur1 = lAudioTrackInput1;
		  strcpy (szAudioFormat1, szFormatInput1);
		  strcpy (szAudioLanguage1, szSpracheInput1);
		  if (lAudioTrackInput2 > 0)
		    {
		      lAudioSpur2 = lAudioTrackInput2;
		      strcpy (szAudioFormat2, szFormatInput2);
		      strcpy (szAudioLanguage2, szSpracheInput2);
		    }
		  break;
		}
	      // Vamps-Befehl zusammensetzen
              strcpy (szDebugVamps, "");
              if (lDebugLevel > 0)
              {
                strcpy (szDebugVamps, "-v -v");
              }
              sprintf (szInjectionFile, "%s/vapinj.%d", szTmpDir, getpid());
              if (lOptimiereFaktor)
              {
 	        sprintf (szVampsBefehl, "%s %s -i %s -E %f -a %ld",
		         vamps_name, szDebugVamps, szInjectionFile, dFaktor, lAudioSpur1);
              } else
              {
 	        sprintf (szVampsBefehl, "%s %s -i %s -e %f -a %ld",
		         vamps_name, szDebugVamps, szInjectionFile, dFaktor, lAudioSpur1);
              }
	      // Audioformate fuer DVD-AUTHOR
	      // LPCM als PCM, MPEG als MP2 an DVDAUTHOR uebergeben
	      if (strstr (szAudioFormat1, "pcm"))
		strcpy (szAudioFormat1, "pcm");
	      if (strstr (szAudioFormat1, "mpeg"))
		strcpy (szAudioFormat1, "mp2");
	      if (strstr (szAudioFormat2, "pcm"))
		strcpy (szAudioFormat2, "pcm");
	      if (strstr (szAudioFormat2, "mpeg"))
		strcpy (szAudioFormat2, "mp2");
	      // Audio-Zeilen in XML
	      fprintf (fXML,
		       "<audio format=\"%s\" quant=\"drc\" lang=\"%s\"/>\n",
		       szAudioFormat1, szAudioLanguage1);
	      if (lAudioSpur2 > 0)
		{
		  fprintf (fXML,
			   "<audio format=\"%s\" quant=\"drc\" lang=\"%s\"/>\n",
			   szAudioFormat2, szAudioLanguage2);
		  sprintf (szVampsBefehl + strlen (szVampsBefehl), ",%ld",
			   lAudioSpur2);
		}
	      if (lUntertitel > 0)
		{
		  fprintf (fXML, "<subpicture lang=\"%s\"/>\n",
			   szUntertitelSprache1);
		  sprintf (szVampsBefehl + strlen (szVampsBefehl), " -s %ld",
			   lUntertitel);
		  if (lUntertitel2 > 0)
		    {
		      fprintf (fXML, "<subpicture lang=\"%s\"/>\n",
			       szUntertitelSprache2);
		      sprintf (szVampsBefehl + strlen (szVampsBefehl), ",%ld",
			       lUntertitel2);
		    }
		}
	      if (lAnzahlUntertitel > 0)	// Alle Untertitel (ausser "xx") kopieren
		{
		  long lFirst = 0;
		  for (i = 0; i < lAnzahlUntertitel; i++)
		    {
		      fprintf (fXML, "<subpicture lang=\"%s\"/>\n",
			       szUntertitelListe[i]);
		      lFirst++;
		      if (lFirst == 1)
			{
			  // Parameter -u erhaelt die Track-IDs (preserve subpictures)
			  sprintf (szVampsBefehl + strlen (szVampsBefehl),
				   " -s %ld", lUntertitelListe[i]);
			  sprintf (szUntertitelOptionen, "-s %s", szUntertitelListe[i]);	// dvdwizard
			}
		      else
			{
			  sprintf (szVampsBefehl + strlen (szVampsBefehl),
				   ",%ld", lUntertitelListe[i]);
			  sprintf (szUntertitelOptionen, ",%s", szUntertitelListe[i]);	// dvdwizard
			}
		    }
		}
	      // Palettefile
	      fprintf (fXML, "<pgc palette=\"%s\">\n", szPaletteFile);
	      // Falls Ausgabe in eine Datei, diese zuvor loeschen
	      if (strlen (szOutputFile))	// Ausgabe in eine VOB-Datei
		{
		  sprintf (szBefehl, "rm %s", szOutputFile);
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		}
	      // Je Zelle einmal Vamps
	      lZelleVon = 1;
	      lZelleBis = lAnzahlZellen;
	      if (lHighQuality == 1)
		lZelleBis = (long) (lAnzahlZellen / 2);
	      if (lHighQuality == 2)
		lZelleVon = (long) ((lAnzahlZellen / 2) + 1);
              // Gesamtgroesse berechnen
	      for (lAktuelleZelle = lZelleVon; lAktuelleZelle <= lZelleBis;
		   lAktuelleZelle++)
	      {
                lGesamtGroesse += sector_cell_array[lAktuelleZelle - 1];
              }
	      for (lAktuelleZelle = lZelleVon; lAktuelleZelle <= lZelleBis;
		   lAktuelleZelle++)
		{
                  if (lOptimiereFaktor > 0)
                  {
		    fprintf (fXML,
			     "<vob file=\"%s %s -r 2 -i -g %s %ld %ld %ld | %s -S %lld |\"/>\n",
			     szNiceRip, play_cell_name, dvd_device, lVTS, lPGC,
			     angle_cell_array[lAktuelleZelle - 1],
			     szVampsBefehl, sector_cell_array[lAktuelleZelle - 1]);
		    if (strlen (szOutputFile))	// Ausgabe in eine VOB-Datei
		    {
                      char szLogAusgabe[256]; 
		      sprintf (szBefehl,
			       "%s %s -r 2 -i -g %s %ld %ld %ld | %s -S %lld >> %s",
			       szNiceRip, play_cell_name, dvd_device, lVTS, lPGC,
			       angle_cell_array[lAktuelleZelle - 1],
			       szVampsBefehl, sector_cell_array[lAktuelleZelle - 1],
                               szOutputFile);
		      printf ("%s\n", szBefehl);
                      lGroesseGerippt += (long long)((double)sector_cell_array[lAktuelleZelle - 1] / dFaktor);
                      if (lAktuelleZelle == lZelleBis) // letztes Kapitel ?
                      {
                        // Setze Zielergebnis=Erwartet
                        lGroesseGerippt = (long long)((double)lGesamtGroesse / dFaktor);
                      }
                      switch (lSprache)
                      {
                        case 0:
                          sprintf (szLogAusgabe, "\nZelle: %ld / %ld, "
                                                 "Groesse: %lld / %lld Bytes\n",
                               lAktuelleZelle, lZelleBis,
                               lGroesseGerippt,
                               (long long)((double)lGesamtGroesse / dFaktor));
                          break;
                        case 1:
                          sprintf (szLogAusgabe, "\nCell: %ld / %ld, "
                                                 "Size: %lld / %lld Bytes\n",
                               lAktuelleZelle, lZelleBis,
                               lGroesseGerippt,
                               (long long)((double)lGesamtGroesse / dFaktor));
                          break;
                        case 2:
                          sprintf (szLogAusgabe, "\nCellule: %ld / %ld, "
                                                 "Dimension: %lld / %lld Bytes\n",
                               lAktuelleZelle, lZelleBis,
                               lGroesseGerippt,
                               (long long)((double)lGesamtGroesse / dFaktor));
                          break;
                      }
		      printf ("%s\n", szLogAusgabe);
		      system (szBefehl);
		    }
                  } else
                  {
		    fprintf (fXML,
			     "<vob file=\"%s %s -r 2 -i -g %s %ld %ld %ld | %s |\"/>\n",
			     szNiceRip, play_cell_name, dvd_device, lVTS, lPGC,
			     angle_cell_array[lAktuelleZelle - 1],
			     szVampsBefehl);
		    if (strlen (szOutputFile))	// Ausgabe in eine VOB-Datei
		    {
                      char szLogAusgabe[256]; 
		      sprintf (szBefehl,
			       "%s %s -r 2 -i -g %s %ld %ld %ld | %s >> %s",
			       szNiceRip, play_cell_name, dvd_device, lVTS, lPGC,
			       angle_cell_array[lAktuelleZelle - 1],
			       szVampsBefehl,
                               szOutputFile);
		      printf ("%s\n", szBefehl);
                      lGroesseGerippt += (long long)((double)sector_cell_array[lAktuelleZelle - 1] / dFaktor);
                      if (lAktuelleZelle == lZelleBis) // letztes Kapitel ?
                      {
                        // Setze Zielergebnis=Erwartet
                        lGroesseGerippt = (long long)((double)lGesamtGroesse / dFaktor);
                      }
                      switch (lSprache)
                      {
                        case 0:
                          sprintf (szLogAusgabe, "\nZelle: %ld / %ld, "
                                                 "Groesse: %lld / %lld Bytes\n",
                               lAktuelleZelle, lZelleBis,
                               lGroesseGerippt,
                               (long long)((double)lGesamtGroesse / dFaktor));
                          break;
                        case 1:
                          sprintf (szLogAusgabe, "\nCell: %ld / %ld, "
                                                 "Size: %lld / %lld Bytes\n",
                               lAktuelleZelle, lZelleBis,
                               lGroesseGerippt,
                               (long long)((double)lGesamtGroesse / dFaktor));
                          break;
                        case 2:
                          sprintf (szLogAusgabe, "\nCellule: %ld / %ld, "
                                                 "Dimension: %lld / %lld Bytes\n",
                               lAktuelleZelle, lZelleBis,
                               lGroesseGerippt,
                               (long long)((double)lGesamtGroesse / dFaktor));
                          break;
                      }
		      printf ("%s\n", szLogAusgabe);
		      system (szBefehl);
		    }
                  }
		}
	      // XML abschliessen         
	      fprintf (fXML, "</pgc>\n");
	      fprintf (fXML, "</titles>\n");
	      fprintf (fXML, "</titleset>\n");
	      fprintf (fXML, "</dvdauthor>\n");
	      fclose (fXML);
	      // DVD Athor mit der XML-Datei aufrufen
	      if (!strlen (szOutputFile))
		{
		  sprintf (szBefehl, "%s %s -x %s/dvdauthor.xml", 
                                     szNiceRip, dvdauthor_name, szTmpDir);
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		}
	      // XML-File loeschen
	      sprintf (szBefehl, "rm %s/dvdauthor.xml", szTmpDir);
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      // Injection-File loeschen
	      sprintf (szBefehl, "rm %s", szInjectionFile);
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      // DVD-Wizard starten ?
	      if (lDVDWizard)
		{
		  // Name von aussen setzbar
		  if (strlen (szDVDNameOverwrite))
		    strcpy (szDVDName, szDVDNameOverwrite);
		  // DVD-Wizard starten
		  dvd_wizard (szNiceRip, dvdwizard_name, szDVDWizardVideoAngaben,
			      szDVDName, dvdwizard_bild,
			      szChapterString, szAudioLanguage1,
			      szAudioLanguage2, szFilmVerzeichnis,
			      szOutputFile, lLoeschen, szUntertitelOptionen,
			      szPaletteFile, lSprache);
		}
	      // Palette loeschen und Ende bei Datei
	      if (strlen (szOutputFile) && !lDVDWizard)
		{
		  // DVD auswerfen ?
		  if (lEject)
		    {
		      sprintf (szBefehl, "%s %s", eject_name, dvd_device);
		      printf ("%s\n", szBefehl);
		      system (szBefehl);
		    }
		  if (lPlaySound > 0)
		    play_sound_if_ready (lxdvdrip_wav_name);
		  switch (lSprache)
		    {
		    case 0:
		      printf ("\nFertig!\n");
		      break;
		    case 1:
		      printf ("\nReady!\n");
		      break;
		    case 2:
		      printf ("\nPrêt !\n");
		      break;
		    }
		  if (filesize64 (szPaletteFile, szTmpDir) > 0)
		    {
		      sprintf (szBefehl, "rm %s", szPaletteFile);
		      system (szBefehl);
		    }
		  return 0;
		}
	    }
	}

      // DVD rippen mit der Methode transcode parallel
      // Ersatz fuer vamps-Methode ab lxdvdrip-Version 0.80
      if (lPackMethode == 2)
	{
	  long lAudioSpur1, lAudioSpur2;
	  char szAudioFormat1[128];
	  char szAudioFormat2[128];
	  char szBufferBefehl[128];
	  char szAudioFormatTranscode1[12], szAudioFormatTranscode2[12];
	  char szPipeUntertitel[128];
	  char szPipeMPEG[2048];
	  long lForcedSubs = 0, lTotalSubs = 0;
          long lVLCAudioTrack1=0;
          strcpy (szPipeUntertitel, "");
	  // Tests auf Programme
	  check_program (dvdauthor_name, lSprache, 1);
          if (lUseVLC > 0)
  	    check_program (vlc_name, lSprache, 1);
          else
  	    check_program (tccat_name, lSprache, 1);
	  check_program (tcextract_name, lSprache, 1);
	  if (lDVDWizard > 0)
	    check_program (dvdwizard_name, lSprache, 1);
	  if (lUntertitel != 0)
	    {
	      check_program (spumux_name, lSprache, 1);
	      check_program (spuunmux_name, lSprache, 1);
	    }
	  if (dFaktor > 1)
	    check_program (tcrequant_name, lSprache, 1);
	  check_program (mplex_name, lSprache, 1);
	  check_program (buffer_name, lSprache, 1);
	  // Befehl fuer Buffer-Programm zusammensetzen
	  if (strstr (buffer_name, "bfr"))
	    {
	      sprintf (szBufferBefehl, "%s 2>/dev/null <", buffer_name);	// nehme bfr
	    }
	  else
	    {
	      if (strstr (buffer_name, "mbuffer"))
		sprintf (szBufferBefehl, "%s -s 64k -t -m 16M -q -i", buffer_name);	// nehme mbuffer
	      else
		sprintf (szBufferBefehl, "%s -s 64k -m 16m -i", buffer_name);	// nehme buffer
	    }
	  // Behandlung von Forced Subtitles
	  printf ("Wert Untertitel: %ld\n", lUntertitel);
	  if (lUntertitel == -3)
	    {
	      FILE *fTmp;
	      char szTrack[256];
	      long lSubpicTrackNr;
	      char szSubPicTmpFile[128];
	      sprintf (szSubPicTmpFile, "%s/subpic.tmp", szTmpDir);
	      strcpy (szUntertitelOptionen, "");
	      switch (lSprache)
		{
		case 0:
		  printf ("\"Forced\" Untertitel rippen\n");
		  break;
		case 1:
		  printf ("rip \"Forced\" Subtitles\n");
		  break;
		case 2:
		  printf ("\"Forced\" Sous-Titres\n");
		  break;
		}
	      // Inhalt der DVD nach Untertiteln durchsuchen
	      sprintf (szBefehl, "%s %s -i %s -T %ld 2>&1 | grep subtitle > %s",
		       szNiceRip, tcprobe_name, dvd_device, (long) opt_t,
		       szSubPicTmpFile);
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      // Inhalt der Datei auslesen mit Sprachen der Untertitel
	      if (filesize64 (szSubPicTmpFile, szTmpDir) > 0)
		{
		  char szSpuUnMuxTmp[128];
		  fTmp = fopen (szSubPicTmpFile, "r");
		  lSubpicTrackNr = 0;
		  while (fscanf (fTmp, "%s", szTrack) != EOF)
		    {
		      fscanf (fTmp, "%s", szTrack);
		      fscanf (fTmp, "%s", szTrack);
		      strncpy (szTrack, &szTrack[4], 2);
		      szTrack[2] = 0;
		      // Info ausgeben
		      printf ("Track-Nr. %ld, %s\n", lSubpicTrackNr, szTrack);
		      // Anlegen der Pipes
		      sprintf (szBefehl, "mkfifo %s/foo_%ld.sub", szTmpDir,
			       lSubpicTrackNr);
		      printf ("%s\n", szBefehl);
		      system (szBefehl);
		      // Spumux-Befehl
		      sprintf (szBefehl,
			       "%s %s/foo_%ld.sub | %s -o %s/dvd_%ld -s %ld %s /dev/stdin &",
			       szBufferBefehl, szTmpDir, lSubpicTrackNr,
			       spuunmux_name, szTmpDir, lSubpicTrackNr,
			       lSubpicTrackNr, szPaletteOptions);
		      printf ("%s\n", szBefehl);
		      system (szBefehl);
		      lSubpicTrackNr++;
		    }
		  lTotalSubs = lSubpicTrackNr;
		  fclose (fTmp);
		  // DVD auslesen
                  if (lUseVLC > 0)
		    sprintf (szBefehl,
		             "%s %s dvdsimple:%s@%ld%s%s --intf dummy --sout-all --sout "
                             "'#standard{access=file,mux=ps,dst=/dev/stdout}' vlc:quit "  
			     " | tee ",
			     szNiceRip, vlc_name, dvd_device, (long) opt_t, szHQChapters,
			     szAngle);
                  else
		    sprintf (szBefehl,
			     "%s %s -i %s -T %ld,%s%s -P | tee ",
			     szNiceRip, tccat_name, dvd_device, (long) opt_t, szHQChapters,
			     szAngle);
		  for (i = 0; i < lSubpicTrackNr; i++)
		    {
		      sprintf (szTrack, " %s/foo_%ld.sub ", szTmpDir, i);
		      strcat (szBefehl, szTrack);
		    }
		  strcat (szBefehl, " > /dev/null");
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		  // Warten auf das Ende von allen spuunmux-Instanzen
		  sprintf (szSpuUnMuxTmp, "%s/spuunmux.tmp", szTmpDir);
		  for (;;)
		    {
		      sleep (1);
		      sprintf (szBefehl, "ps -A | grep spuunmux > %s",
			       szSpuUnMuxTmp);
		      printf ("%s\n", szBefehl);
		      system (szBefehl);
		      // Bei Groesse 0 ist alles zu Ende
		      if (filesize64 (szSpuUnMuxTmp, szTmpDir) ==
			  (long long) 0)
			break;
		    }
		  sprintf (szBefehl, "rm %s", szSpuUnMuxTmp);
		  system (szBefehl);
		  // Bestimmen, ob ein Track forced ist.
		  lForcedSubs = 0;
		  for (i = 0; i < lSubpicTrackNr; i++)
		    {
		      long lTrackForced = 0;
		      long lZeilenEnde = 0;
		      long lForcedPic = 0;
		      sprintf (szBefehl, "%s/dvd_%ld.xml", szTmpDir, i);
		      fTmp = fopen (szBefehl, "r");
		      if (!fTmp)
			continue;
		      while (fscanf (fTmp, "%s", szTrack) != EOF)
			{
			  // Zaehle forced Pics und Zeilenende des Tracks
			  if (strstr (szTrack, "force")
			      && strstr (szTrack, "yes"))
			    lForcedPic++;
			  if (strstr (szTrack, "/>"))
			    lZeilenEnde++;
			}
		      fclose (fTmp);
		      if (lForcedPic > 0)
			{
			  lTrackForced = 1;
			  lForcedSubs++;
			}
		      printf
			("Track %ld: Forced Pics: %ld / Forced Tracks: %ld\n",
			 i, lForcedPic, lForcedSubs);
		      // Loeschen, wenn dieser Track nicht forced
		      if (!lTrackForced)
			{
			  sprintf (szBefehl, "rm %s/dvd_%ld*", szTmpDir, i);
			  system (szBefehl);
			}
		      else
			{
			  // String mit den Untertitelsprachen zusammensetzen
			  fTmp = fopen (szSubPicTmpFile, "r");
			  for (j = 0; j <= i; j++)
			    {
			      fscanf (fTmp, "%s", szTrack);
			      fscanf (fTmp, "%s", szTrack);
			      fscanf (fTmp, "%s", szTrack);
			    }
			  fclose (fTmp);
			  strncpy (szTrack, &szTrack[4], 2);
			  szTrack[2] = 0;
			  if (!strlen (szUntertitelOptionen))
			    {
			      sprintf (szUntertitelOptionen, "-s %s",
				       szTrack);
			    }
			  else
			    {
			      strcat (szUntertitelOptionen, ",");
			      strcat (szUntertitelOptionen, szTrack);
			    }
			}
		    }
		  printf ("Forced All: %s\n", szUntertitelOptionen);
		  // Am Ende wieder alles entsorgen
		  sprintf (szBefehl, "rm %s/foo_*sub", szTmpDir);	// Fifos je Untertitel
		  system (szBefehl);
		}
	      // Am Ende wieder alles entsorgen
	      sprintf (szBefehl, "rm %s", szSubPicTmpFile);
	      system (szBefehl);	// temp-File mit Untertiteln
	      // Modus zurueckschalten, wenn keine Forced Subs enthalten
	      if (lForcedSubs == 0)
		{
		  lUntertitel = 0;
		}
	    }
	  // 1. Audiotrack: Format und TrackNr bestimmen
	  switch (lSprachAuswahl)
	    {
	    case 1:
	      lAudioSpur1 = lAudioTrackDeutsch;
	      strcpy (szAudioFormat1, szAudioFormatDeutsch);
	      break;
	    case 2:
	      lAudioSpur1 = lAudioTrackEnglisch;
	      strcpy (szAudioFormat1, szAudioFormatEnglisch);
	      break;
	    case 3:
	      lAudioSpur1 = lAudioTrackDeutsch;
	      strcpy (szAudioFormat1, szAudioFormatDeutsch);
	      break;
	    case 4:
	      lAudioSpur1 = lZusatzAudioTrack;
	      strcpy (szAudioFormat1, szZusatzAudioFormat);
	      break;
	    case 5:
	      lAudioSpur1 = lAudioTrackInput1;
	      strcpy (szAudioFormat1, szFormatInput1);
	      break;
	    }
	  strcpy (szAudioFormatTranscode1, szAudioFormat1);
	  // mpeg2 als mp3 auslesen
	  if (strstr (szAudioFormat1, "mpeg2"))
	    {
	      strcpy (szAudioFormatTranscode1, "mp3");
	    }
	  // mpeg1 Audio ist bei Transcode mp3
	  if (strstr (szAudioFormat1, "mpeg1"))
	    {
	      strcpy (szAudioFormat1, "mpeg2");
	    }
	  // lpcm wird von Transcode als pcm gerippt und in mpeg2 umgewandelt, sonst nur rauschen
	  if (strstr (szAudioFormat1, "lpcm"))
	    {
	      strcpy (szAudioFormatTranscode1, "pcm");
	      strcpy (szAudioFormat1, "mpeg2");
	    }
	  lAudioSpur1--;	// tcextrcat beginnt mit Spur 0
	  // 2. Audiotrack: Format und TrackNr bestimmen
	  if (lSprachAuswahl == 3 ||	// 2. Audiospur englisch zusaetzlich rippen
	      (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
	    {
	      if (lSprachAuswahl == 3)
		{
		  lAudioSpur2 = lAudioTrackEnglisch;
		  strcpy (szAudioFormat2, szAudioFormatEnglisch);
		}
	      else
		{
		  lAudioSpur2 = lAudioTrackInput2;
		  strcpy (szAudioFormat2, szFormatInput2);
		}
	      strcpy (szAudioFormatTranscode2, szAudioFormat2);
	      // mpeg2 als mp3 auslesen
	      if (strstr (szAudioFormat2, "mpeg2"))
		{
		  strcpy (szAudioFormatTranscode2, "mp3");
		}
	      // mpeg1 Audio ist bei Transcode mp3
	      if (strstr (szAudioFormat2, "mpeg1"))
		{
		  strcpy (szAudioFormat2, "mpeg2");
		}
	      // lpcm wird von Transcode als pcm gerippt und in mpeg2 umgewandelt, sonst nur rauschen
	      if (strstr (szAudioFormat2, "lpcm"))
		{
		  strcpy (szAudioFormatTranscode2, "pcm");
		  strcpy (szAudioFormat2, "mpeg2");
		}
	      lAudioSpur2--;	// tcextrcat beginnt mit Spur 0
	    }
	  // Pipes anlegen
	  sprintf (szBefehl, "mkfifo %s/foo.s1", szTmpDir);
	  system (szBefehl);
	  sprintf (szBefehl, "mkfifo %s/foo.s2", szTmpDir);
	  system (szBefehl);
	  sprintf (szBefehl, "mkfifo %s/foo.%s", szTmpDir, szAudioFormat1);
	  system (szBefehl);
	  sprintf (szBefehl, "mkfifo %s/foo.m2v", szTmpDir);
	  system (szBefehl);
	  if (lUntertitel > 0)	// Pipe fuer Untertitel
	    {
              long lErsterUntertitel=lUntertitel - 1;
              // Bei VLC und nur einmal Audio/Sub wird der
              // Subtrack bereits beim Rippen voreingestellt.
              if (lUseVLC > 0 &&
                  lUntertitel2 == 0 &&             // nur ein Sub
                  !(lSprachAuswahl == 3 ||         // nur ein Audio
	            (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
                 )
                lErsterUntertitel=0;
	      sprintf (szBefehl, "mkfifo %s/foo.sub", szTmpDir);
	      system (szBefehl);
	      sprintf (szBefehl,
		       "%s %s/foo.sub | %s -o %s/dvd -s %ld %s /dev/stdin",
		       szBufferBefehl, szTmpDir, spuunmux_name, szTmpDir,
		       lErsterUntertitel, szPaletteOptions);
	      printf ("%s\n", szBefehl);
	      // Parallel ausfuehren
	      // fork erzeugt eine 2. Instanz. Im unteren Bereich wird dann mit "wait(0)" gewartet, bis spuunmux zu Ende,
	      // damit die XML-Datei auch wirklich vollstaendig ist.
	      if (fork () == 0)
		{
		  system (szBefehl);
		  return 0;
		}
	      system ("sleep 1");
	      sprintf (szPipeUntertitel, "%s/foo.sub", szTmpDir);
	      if (lUntertitel2 > 0)
		{
		  sprintf (szBefehl, "mkfifo %s/foo.sub2", szTmpDir);
		  system (szBefehl);
		  sprintf (szBefehl,
			   "%s %s/foo.sub2 | %s -o %s/dvd2 -s %ld %s /dev/stdin",
			   szBufferBefehl, szTmpDir, spuunmux_name, szTmpDir,
			   lUntertitel2 - 1, szPaletteOptions);
		  printf ("%s\n", szBefehl);
		  // Parallel ausfuehren
		  if (fork () == 0)
		    {
		      system (szBefehl);
		      return 0;
		    }
		  system ("sleep 1");
		  sprintf (szPipeUntertitel, "%s/foo.sub %s/foo.sub2",
			   szTmpDir, szTmpDir);
		}
	      if (strlen (szOutputFile))
		strcpy (szPipeMPEG, szOutputFile);	// echte Datei
	      else
		sprintf (szPipeMPEG, "%s/film-neu.vob", szTmpDir);
	    }
	  else
	    {
	      strcpy (szPipeUntertitel, "");
	      // Ausgabe in eine Datei ? Dann echte Datei angeben, keine Pipe
	      if (strlen (szOutputFile))
		{
		  strcpy (szPipeMPEG, szOutputFile);	// echte Datei
		}
	      else
		{
		  // Gibt es Forced Subs ?
		  if (lForcedSubs == 0)
		    {
		      sprintf (szPipeMPEG, "%s/foo.mpeg", szTmpDir);	// Pipe fuer dvdauthor
		      sprintf (szBefehl, "mkfifo %s/foo.mpeg", szTmpDir);
		      system (szBefehl);
		    }
		  else
		    {
		      sprintf (szPipeMPEG, "%s/film-neu.vob", szTmpDir);	// Erst File rippen
		    }
		}
	    }
	  if (lSprachAuswahl == 3 ||	// 2. Audiospur englisch zusaetzlich rippen
	      (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
	    {
	      sprintf (szBefehl, "mkfifo %s/foo.s3", szTmpDir);
	      system (szBefehl);
	      sprintf (szBefehl, "mkfifo %s/foo_a2.%s", szTmpDir,
		       szAudioFormat2);
	      system (szBefehl);
	      sprintf (szBefehl,
		       "%s -f 8 -o %s %s/foo.m2v %s/foo.%s %s/foo_a2.%s -S 0 -M &",
		       mplex_name, szPipeMPEG, szTmpDir, szTmpDir,
		       szAudioFormat1, szTmpDir, szAudioFormat2);
	    }
	  else
	    {
	      sprintf (szBefehl,
		       "%s -f 8 -o %s %s/foo.m2v %s/foo.%s -S 0 -M &",
		       mplex_name, szPipeMPEG, szTmpDir, szTmpDir,
		       szAudioFormat1);
	    }
	  printf ("%s\n", szBefehl);
	  system (szBefehl);
	  system ("sleep 1");
	  // Videostream (tcrequant nur bei Faktor > 1 noetig)
	  if (dFaktor > 1)
	    sprintf (szBefehl,
		     "%s %s/foo.s1 | %s -t vob -x mpeg2 | %s -f %f > %s/foo.m2v &",
		     szBufferBefehl, szTmpDir, tcextract_name, tcrequant_name,
		     dFaktor, szTmpDir);
	  else
	    sprintf (szBefehl,
		     "%s %s/foo.s1 | %s -t vob -x mpeg2 > %s/foo.m2v &",
		     szBufferBefehl, szTmpDir, tcextract_name, szTmpDir);
	  printf ("%s\n", szBefehl);
	  system (szBefehl);
	  system ("sleep 1");
          // VLC ohne Untertitel / nur ein Audiotrack
          if (lUseVLC > 0 && 
              !(lSprachAuswahl == 3 ||
	        (lSprachAuswahl == 5 && lAudioTrackInput2 > 0)) &&
              (lUntertitel2 == 0)
             )
          {
            lVLCAudioTrack1 = lAudioSpur1;
            lAudioSpur1 = 0;
          }
	  if (strcmp (szAudioFormatTranscode1, "pcm") == 0)
	    {
	      // pcm als mpeg2 umwandeln
	      sprintf (szBefehl, "%s %s/foo.s2 | %s -t vob -x %s -a %ld | "
		       "%s -x null,raw -y null,mp2enc -i /dev/stdin "
		       "-E 48000 -b 192 --ext none,none -m %s/foo.%s &",
		       szBufferBefehl, szTmpDir, tcextract_name,
		       szAudioFormatTranscode1, lAudioSpur1, transcode_name,
		       szTmpDir, szAudioFormat1);
	    }
	  else
	    {
	      if (strstr (szAudioFormatTranscode1, "mpeg1"))
		{
		  // mpeg 1 als mpeg2 umwandeln
		  strcpy (szAudioFormatTranscode1, "mp3");
		  sprintf (szBefehl,
			   "%s %s/foo.s2 | %s -t vob -x %s -a %ld | "
			   "%s -x null,auto -y null,mp2enc -i /dev/stdin "
			   "-E 48000 -b 192 --ext none,none -m %s/foo.%s &",
			   szBufferBefehl, szTmpDir, tcextract_name,
			   szAudioFormatTranscode1, lAudioSpur1,
			   transcode_name, szTmpDir, szAudioFormat1);
		}
	      else
		{
                  // dts / vlc muss nochmal ueber vlc laufen
                  // Ausnahme: Nur ein Audiotrack / keine Untertitel.
                  // Dann erfolgt unten die Vorauswahl des Audiotracks
                  if (lUseVLC > 0 && strstr (szAudioFormat1, "dts") &&
		      ( lSprachAuswahl == 3 ||
		        (lSprachAuswahl == 5 && lAudioTrackInput2 > 0) ||
                        (lUntertitel2 > 0)
                      ) 
                     )
                  {
  		    sprintf (szBefehl,
                          "%s %s/foo.s2 | "
                          "%s /dev/stdin --intf dummy --no-video "
                          "--audio-track %ld "
                          "--sout '#standard{access=file,mux=ps,dst=/dev/stdout}' "
                          "vlc:quit "
                          "| %s -t vob -x %s > %s/foo.%s &",
			  szBufferBefehl, szTmpDir, 
			  vlc_name, lAudioSpur1, tcextract_name,
			  szAudioFormatTranscode1, 
			  szTmpDir, szAudioFormat1);
                  } else
                  {
		    // Bei ac3 springen bis zum "sync word"
		    // Ist aber nur noetig bei HQ-Modus-Part2, weil dann der 
		    // ac3 Stream zerrissen wird
		    char szAudioScan[128];
		    strcpy (szAudioScan, "");
		    if (strstr (szAudioFormat1, "ac3") && lHighQuality == 2)
		    {
		      sprintf (szAudioScan, " | %s ", lxac3scan_name);
		    }
	            sprintf (szBefehl,
			   "%s %s/foo.s2 "
                           "| %s -t vob -x %s -a %ld %s > %s/foo.%s &",
			   szBufferBefehl, szTmpDir, tcextract_name,
			   szAudioFormatTranscode1, lAudioSpur1,
			   szAudioScan, szTmpDir, szAudioFormat1);
                  }
		}
	    }
	  printf ("%s\n", szBefehl);
	  system (szBefehl);
	  system ("sleep 1");
	  // 2. Audiotrack
	  if (lSprachAuswahl == 3 ||	// 2. Audiospur englisch zusaetzlich rippen
	      (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
	    {
	      if (strcmp (szAudioFormatTranscode2, "pcm") == 0)
		{
		  // pcm als mpeg2 umwandeln
		  sprintf (szBefehl,
			   "%s %s/foo.s3 | %s -t vob -x %s -a %ld | "
			   "%s -x null,raw -y null,mp2enc -i /dev/stdin "
			   "-E 48000 -b 192 --ext none,none -m %s/foo_a2.%s &",
			   szBufferBefehl, szTmpDir, tcextract_name,
			   szAudioFormatTranscode2, lAudioSpur2,
			   transcode_name, szTmpDir, szAudioFormat2);
		}
	      else
		{
		  if (strstr (szAudioFormatTranscode2, "mpeg1"))
		    {
		      // mpeg 1 als mpeg2 umwandeln
		      strcpy (szAudioFormatTranscode2, "mp3");
		      sprintf (szBefehl,
			       "%s %s/foo.s3 | %s -t vob -x %s -a %ld | "
			       "%s -x null,auto -y null,mp2enc -i /dev/stdin "
			       "-E 48000 -b 192 --ext none,none -m %s/foo_a2.%s &",
			       szBufferBefehl, szTmpDir, tcextract_name,
			       szAudioFormatTranscode2, lAudioSpur2,
			       transcode_name, szTmpDir, szAudioFormat2);
		    }
		  else
		    {
                      // dts / vlc muss nochmal ueber vlc laufen
                      if (lUseVLC > 0 && strstr (szAudioFormat2, "dts"))
                      {
  		        sprintf (szBefehl,
                          "%s %s/foo.s3 | "
                          "%s /dev/stdin --intf dummy --no-video "
                          "--audio-track %ld "
                          "--sout '#standard{access=file,mux=ps,dst=/dev/stdout}' "
                          "vlc:quit "
                          "| %s -t vob -x %s > %s/foo_a2.%s &",
			  szBufferBefehl, szTmpDir, 
			  vlc_name, lAudioSpur2, tcextract_name,
			  szAudioFormatTranscode2, 
			  szTmpDir, szAudioFormat2);
                      } else
                      {
		        // Bei ac3 springen bis zum "sync word"
		        // Ist aber nur noetig bei HQ-Modus-Part2, weil dann der 
		        // ac3 Stream zerrissen wird
		        char szAudioScan[128];
		        strcpy (szAudioScan, "");
		        if (strstr (szAudioFormat2, "ac3") && lHighQuality == 2)
			{
			  sprintf (szAudioScan, " | %s ", lxac3scan_name);
			}
		        // ac3, dts, mpeg2 Audio
		        sprintf (szBefehl,
			       "%s %s/foo.s3 | %s -t vob -x %s -a %ld %s > %s/foo_a2.%s &",
			       szBufferBefehl, szTmpDir, tcextract_name,
			       szAudioFormatTranscode2, lAudioSpur2,
			       szAudioScan, szTmpDir, szAudioFormat2);
                      }
		    }
		}
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      system ("sleep 1");
	      // DVD auslesen
              if (lUseVLC > 0)
              {
                char szNoSPU[20];
                if (!strlen(szPipeUntertitel))
                  strcpy (szNoSPU, " --no-spu ");
                else
                  strcpy (szNoSPU, "");
	        sprintf (szBefehl,
		         "%s %s dvdsimple:%s@%ld%s%s --intf dummy --sout-all %s --sout '#standard{access=file,mux=ps,dst=/dev/stdout}' vlc:quit "  
                         " | tee %s/foo.s1 %s/foo.s2 %s/foo.s3 %s >/dev/null",
		         szNiceRip, vlc_name, dvd_device, (long) opt_t, szHQChapters,
		         szAngle, szNoSPU, szTmpDir, szTmpDir, szTmpDir,
		         szPipeUntertitel);
              } else
	        sprintf (szBefehl,
		         "%s %s -i %s -T %ld,%s%s -P | tee %s/foo.s1 %s/foo.s2 %s/foo.s3 %s >/dev/null",
		         szNiceRip, tccat_name, dvd_device, (long) opt_t, szHQChapters,
		         szAngle, szTmpDir, szTmpDir, szTmpDir,
		         szPipeUntertitel);
	    }
	  else
	    {
	      // DVD auslesen, Zweig fuer eine Audiospur
              if (lUseVLC > 0)
              {
                // dts / vlc muss nochmal ueber vlc laufen.
                // Ausnahme: Nur ein Audiotrack / max 1 Untertitel.
                // Dann erfolgt oben direkt tcextract, hier 
                // wird nur ein Audiotrack gerippt.
                if (lUntertitel2 == 0)
                {
                  char szSPU[128];
                  strcpy (szSPU, "");
                  if (lUntertitel > 0)
                  {
                    sprintf (szSPU, "--sout-spu --sub-track %ld",
                                    lUntertitel-1);
                  }
	          sprintf (szBefehl,
		         "%s %s dvdsimple:%s@%ld%s%s --intf dummy "
                         "--audio-track %ld %s "
                         "--sout '#standard{access=file,mux=ps,dst=/dev/stdout}' "
                         "vlc:quit "  
		         " | tee %s/foo.s1 %s/foo.s2 %s >/dev/null",
		         szNiceRip, vlc_name, dvd_device, (long) opt_t,
                         szHQChapters, szAngle, lVLCAudioTrack1, szSPU,
                         szTmpDir, szTmpDir, szPipeUntertitel);
                } else
                {
	          sprintf (szBefehl,
		         "%s %s dvdsimple:%s@%ld%s%s --intf dummy --sout-all "
                         "--sout '#standard{access=file,mux=ps,dst=/dev/stdout}' "
                         "vlc:quit "  
		         " | tee %s/foo.s1 %s/foo.s2 %s >/dev/null",
		         szNiceRip, vlc_name, dvd_device, (long) opt_t,
                         szHQChapters,
		         szAngle, szTmpDir, szTmpDir, szPipeUntertitel);
                }
              } else
              {
	        sprintf (szBefehl,
		         "%s %s -i %s -T %ld,%s%s -P | tee %s/foo.s1 %s/foo.s2 %s >/dev/null",
		         szNiceRip, tccat_name, dvd_device, (long) opt_t, szHQChapters,
		         szAngle, szTmpDir, szTmpDir, szPipeUntertitel);
              }
	    }
	  // ohne Untertitel tccat parallel und alles in dvdauthor eingebettet,
	  // mit Untertitel erfolgt Zwischenschritt
	  // Bei Ausgabe in eine Datei keine Weitergabe an dvdauthor, sondern Datei erstellen 
	  // durch mplex.
	  if (lUntertitel == 0 && !strlen (szOutputFile))
	    {
	      strcat (szBefehl, " &");
	    }
	  printf ("%s\n", szBefehl);
	  system (szBefehl);
	  // Gibt es Forced Subs ? Dann reinmuxen
	  if (lForcedSubs > 0 && !strlen (szOutputFile))
	    {
	      long lTrackNr = 0;
	      for (i = 0; i < lTotalSubs; i++)
		{
		  sprintf (szBefehl, "%s/dvd_%ld.xml", szTmpDir, i);
		  if (filesize64 (szBefehl, szTmpDir) > 0)
		    {
		      if (!lTrackNr)
			{
			  sprintf (szPipeMPEG,
				   "-f '%s -m dvd -s %ld %s/dvd_%ld.xml < %s/film-neu.vob > /dev/stdout |",
				   spumux_name, lTrackNr, szTmpDir, i,
				   szTmpDir);
			}
		      else
			{
			  sprintf (szPipeMPEG + strlen (szPipeMPEG),
				   "%s -m dvd -s %ld %s/dvd_%ld.xml < /dev/stdin > /dev/stdout |",
				   spumux_name, lTrackNr, szTmpDir, i);
			}
		      lTrackNr++;
		    }
		}
	      strcat (szPipeMPEG, "'");
	    }
	  if (!strlen (szOutputFile))	// Normale Methode parallel an dvdauthor
	    {
	      system ("sleep 1");
	      // Untertitel ins VOB muxen
	      if (lUntertitel > 0)
		{
		  // Etwas warten, bis obige Programme fertig sind
		  // spuunmux wird mit fork gestartet, auf dessen Ende wartet dann das folgende wait.
		  // Erst dann ist spuunmux zu Ende und damit die XML-Datei fertig.
		  wait (0);
		  if (lUntertitel2 > 0)
		    wait (0);
		  // spumux zum multiplexen der Untertitel
		  if (lUntertitel2 == 0)
		    sprintf (szPipeMPEG,
			     "-f '%s -m dvd -s 0 %s/dvd.xml < %s/film-neu.vob > /dev/stdout |'",
			     spumux_name, szTmpDir, szTmpDir);
		  else
		    sprintf (szPipeMPEG,
			     "-f '%s -m dvd -s 0 %s/dvd.xml < %s/film-neu.vob > /dev/stdout | "
			     "%s -m dvd -s 1 %s/dvd2.xml < /dev/stdin > /dev/stdout |'",
			     spumux_name, szTmpDir, szTmpDir, spumux_name,
			     szTmpDir);
		}
	      // LPCM als MPEG2 (mp2) an DVDAUTHOR uebergeben, Umwandlung oben per transcode
	      if (strstr (szAudioFormatDeutsch, "pcm"))
		strcpy (szAudioFormatDeutsch, "mp2");
	      if (strstr (szAudioFormatEnglisch, "pcm"))
		strcpy (szAudioFormatEnglisch, "mp2");
	      if (strstr (szZusatzAudioFormat, "pcm"))
		strcpy (szZusatzAudioFormat, "mp2");
	      // mpeg1 Audio als (mp2) uebergeben
	      if (strstr (szAudioFormatDeutsch, "mpeg"))
		strcpy (szAudioFormatDeutsch, "mp2");
	      if (strstr (szAudioFormatEnglisch, "mpeg"))
		strcpy (szAudioFormatEnglisch, "mp2");
	      if (strstr (szZusatzAudioFormat, "mpeg"))
		strcpy (szZusatzAudioFormat, "mp2");
	      // Befehl dvdauthor fuer Bildung des DVD-Titels zusammensetzen
	      switch (lSprachAuswahl)
		{
		case 1:
		  sprintf (szBefehl, "%s %s -t -a %s+de ", szNiceRip, dvdauthor_name,
			   szAudioFormatDeutsch);
		  break;
		case 2:
		  sprintf (szBefehl, "%s %s -t -a %s+en ", szNiceRip, dvdauthor_name,
			   szAudioFormatEnglisch);
		  break;
		case 3:
		  sprintf (szBefehl, "%s %s -t -a %s+de,%s+en ", szNiceRip, dvdauthor_name,
			   szAudioFormatDeutsch, szAudioFormatEnglisch);
		  break;
		case 4:
		  sprintf (szBefehl, "%s %s -t -a %s+%s ", szNiceRip, dvdauthor_name,
			   szZusatzAudioFormat, szZusatzSprache);
		  break;
		case 5:
		  if (strstr (szFormatInput1, "mp3") ||
		      strstr (szAudioFormat1, "pcm") ||
		      strstr (szAudioFormat1, "mpeg"))
		    {
		      strcpy (szFormatInput1, "mp2");
		    }
		  if (strstr (szFormatInput2, "mp3") ||
		      strstr (szAudioFormat2, "pcm") ||
		      strstr (szAudioFormat2, "mpeg"))
		    {
		      strcpy (szFormatInput2, "mp2");
		    }
		  sprintf (szBefehl, "%s %s -t -a %s+%s", szNiceRip, dvdauthor_name,
			   szFormatInput1, szSpracheInput1);
		  if (lAudioTrackInput2 > 0)
		    {
		      strcat (szBefehl, ",");
		      strcat (szBefehl, szFormatInput2);
		      strcat (szBefehl, "+");
		      strcat (szBefehl, szSpracheInput2);
		    }
		  strcat (szBefehl, " ");
		  break;
		default:
		  sprintf (szBefehl, "%s %s -t -a %s+de ", szNiceRip, dvdauthor_name,
			   szAudioFormatDeutsch);
		  break;
		}
	      sprintf (szBefehl + strlen (szBefehl), " %s %s %s %s -o %s %s",
		       szChapterString, szVideoAngaben, szPaletteOptions,
		       szUntertitelOptionen, szFilmVerzeichnis, szPipeMPEG);
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	    }
	  // Alle Pipes wieder loeschen
	  sprintf (szBefehl, "rm %s/foo.s1", szTmpDir);
	  system (szBefehl);
	  sprintf (szBefehl, "rm %s/foo.s2", szTmpDir);
	  system (szBefehl);
	  sprintf (szBefehl, "rm %s/foo.%s", szTmpDir, szAudioFormat1);
	  system (szBefehl);
	  sprintf (szBefehl, "rm %s/foo.m2v", szTmpDir);
	  system (szBefehl);
	  if (lSprachAuswahl == 3 ||	// 2. Audiospur englisch zusaetzlich rippen
	      (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
	    {
	      sprintf (szBefehl, "rm %s/foo.s3", szTmpDir);
	      system (szBefehl);
	      sprintf (szBefehl, "rm %s/foo_a2.%s", szTmpDir, szAudioFormat2);
	      system (szBefehl);
	    }
	  // Ausgabe in Datei und Untertitel
	  // Dann Untertitel multiplexen
	  if (strlen (szOutputFile) && lUntertitel != 0)	// Datei statt Brennen ?
	    {
	      if (lUntertitel > 0)
		{
		  // warten auf Prozessende
		  wait (0);
		  if (lUntertitel2 > 0)
		    wait (0);
		  // 1 Sekunde pauschal warten
		  system ("sleep 1");
		}
	      // Datei zunaechst umbenennen
	      sprintf (szBefehl, "mv %s %s/dummy_mux.vob", szOutputFile,
		       szTmpDir);
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      if (lUntertitel > 0)
		{
		  // Die Untertitel multiplexen
		  if (lUntertitel2 == 0)
		    sprintf (szBefehl,
			     "%s %s -m dvd -s 0 %s/dvd.xml < %s/dummy_mux.vob > %s",
			     szNiceRip, spumux_name, szTmpDir, szTmpDir, szOutputFile);
		  else
		    sprintf (szBefehl,
			     "%s %s -m dvd -s 0 %s/dvd.xml < %s/dummy_mux.vob > /dev/stdout | "
			     "%s -m dvd -s 1 %s/dvd2.xml < /dev/stdin > %s",
			     szNiceRip, spumux_name, szTmpDir, szTmpDir, spumux_name,
			     szTmpDir, szOutputFile);
		}
	      else
		{
		  long lTrackNr = 0;
		  for (i = 0; i < lTotalSubs; i++)
		    {
		      char szTmp[128];
		      sprintf (szTmp, "%s/dvd_%ld.xml", szTmpDir, i);
		      if (filesize64 (szTmp, szTmpDir) > 0)
			{
			  if (!lTrackNr)
			    {
			      sprintf (szBefehl,
				       "%s %s -m dvd -s %ld %s/dvd_%ld.xml < %s/dummy_mux.vob",
				       szNiceRip, spumux_name, lTrackNr, szTmpDir, i,
				       szTmpDir);
			    }
			  else
			    {
			      sprintf (szBefehl + strlen (szBefehl),
				       " > /dev/stdout | %s -m dvd -s %ld %s/dvd_%ld.xml < /dev/stdin",
				       spumux_name, lTrackNr, szTmpDir, i);
			    }
			  lTrackNr++;
			}
		    }
		  sprintf (szBefehl + strlen (szBefehl), " > %s",
			   szOutputFile);
		}
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      // Temporaere Datei zuletzt loeschen
	      sprintf (szBefehl, "rm %s/dummy_mux.vob", szTmpDir);
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	    }
	  // Dateien loeschen vom Rippen der Untertitel
	  if (lUntertitel != 0)	// Pipe fuer Untertitel
	    {
	      if (lUntertitel > 0)
		{
		  sprintf (szBefehl, "rm %s/foo.sub", szTmpDir);
		  system (szBefehl);
		}
	      if (lUntertitel2 > 0)
		{
		  sprintf (szBefehl, "rm %s/foo.sub2", szTmpDir);
		  system (szBefehl);
		}
	      // Ausserdem das XML-Script und die pngs loeschen
	      sprintf (szBefehl, "rm %s/dvd*.xml", szTmpDir);
	      system (szBefehl);
	      sprintf (szBefehl, "rm %s/dvd*.png", szTmpDir);
	      system (szBefehl);
	      // Dummy-Datei zuletzt loeschen
	      if (!strlen (szOutputFile))
		{
		  sprintf (szBefehl, "rm %s/film-neu.vob", szTmpDir);
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		}
	    }
	  else
	    {
	      if (!strlen (szOutputFile))
		{
		  sprintf (szBefehl, "rm %s", szPipeMPEG);
		  system (szBefehl);
		}
	    }
	  // DVDwizard starten ?
	  if (lDVDWizard)
	    {
	      char szAudio1[10], szAudio2[10];
	      strcpy (szAudio1, "");
	      strcpy (szAudio2, "");
	      switch (lSprachAuswahl)
		{
		case 1:
		  strcpy (szAudio1, "de");
		  break;
		case 2:
		  strcpy (szAudio1, "en");
		  break;
		case 3:
		  strcpy (szAudio1, "de");
		  strcpy (szAudio2, "en");
		  break;
		case 4:
		  strcpy (szAudio1, szZusatzSprache);
		  break;
		case 5:
		  strcpy (szAudio1, szSpracheInput1);
		  strcpy (szAudio2, szSpracheInput2);
		  break;
		}
	      // Name von aussen setzbar
	      if (strlen (szDVDNameOverwrite))
		strcpy (szDVDName, szDVDNameOverwrite);
	      // DVD-Wizard starten
	      dvd_wizard (szNiceRip, dvdwizard_name, szDVDWizardVideoAngaben, szDVDName,
			  dvdwizard_bild,
			  szChapterString,
			  szAudio1, szAudio2,
			  szFilmVerzeichnis,
			  szOutputFile, lLoeschen, szUntertitelOptionen,
			  szPaletteFile, lSprache);
	    }
	  // Ausgabe in Datei, aber kein Wizard => DVD auswerfen und Ende
	  if (strlen (szOutputFile) && !lDVDWizard)
	    {
	      // DVD auswerfen ?
	      if (lEject)
		{
		  sprintf (szBefehl, "%s %s", eject_name, dvd_device);
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		}
	      if (lPlaySound > 0)
		play_sound_if_ready (lxdvdrip_wav_name);
	      switch (lSprache)
		{
		case 0:
		  printf ("\nFertig!\n");
		  break;
		case 1:
		  printf ("\nReady!\n");
		  break;
		case 2:
		  printf ("\nPrêt !\n");
		  break;
		}
	      if (filesize64 (szPaletteFile, szTmpDir) > 0)
		{
		  sprintf (szBefehl, "rm %s", szPaletteFile);
		  system (szBefehl);
		}
	      return 0;
	    }
	}

      // Rippen per mplayer oder transcode (ab mplex sind beide Bloecke gleich)
      if (lPackMethode == 3 || lPackMethode == 4)
	{
	  char szAudioFormat1[128];
	  char szAudioFormat2[128];
	  char szMplexAusgabe[128];
	  char szVOBQuelle[1028];
	  long lRC;
	  // Tests auf Programme
	  check_program (dvdauthor_name, lSprache, 1);
	  if (lDVDWizard > 0)
	    check_program (dvdwizard_name, lSprache, 1);
	  if (lPackMethode == 3)
	    check_program (mplayer_name, lSprache, 1);
	  else
          {
            if (lUseVLC > 0)
	      check_program (vlc_name, lSprache, 1);
            else
	      check_program (tccat_name, lSprache, 1);
          }
	  check_program (tcextract_name, lSprache, 1);
	  if (dFaktor > 1)
	    check_program (tcrequant_name, lSprache, 1);
	  if (lMultiplexer == 1)
	    check_program (tcmplex_name, lSprache, 1);
	  else
	    check_program (mplex_name, lSprache, 1);
	  if (lUntertitel > 0)
	    {
	      check_program (spuunmux_name, lSprache, 1);
	      check_program (spumux_name, lSprache, 1);
	    }
	  // Tmp-Dir: muss immer ein "/" angehaengt haben
	  if (szTmpDir[strlen (szTmpDir) - 1] != '/')
	    strcat (szTmpDir, "/");
	  if (lPackMethode == 3)
	    {
	      long lAudioSpur;
	      char szAudioScan[128];
	      // Videospur
	      // Bei Faktor = 1 ohne tcrequant, Zeit ist unnoetig
	      if (dFaktor > 1)
		sprintf (szBefehl,
			 "%s %s -dvd-device %s dvd://%ld %s -dumpstream -dumpfile /dev/stdout | %s -t vob -a 0 -x mpeg2 | %s -f %f > %sofile.m2v",
			 szNiceRip, mplayer_name, dvd_device, (long) opt_t, szAngle,
			 tcextract_name, tcrequant_name, dFaktor, szTmpDir);
	      else
		sprintf (szBefehl,
			 "%s %s -dvd-device %s dvd://%ld %s %s -dumpstream -dumpfile /dev/stdout | %s -t vob -a 0 -x mpeg2 > %sofile.m2v",
			 szNiceRip, mplayer_name, dvd_device, (long) opt_t, szHQChapters,
			 szAngle, tcextract_name, szTmpDir);
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      // Audiospur
	      switch (lSprachAuswahl)
		{
		case 1:
		  lAudioSpur = lAudioTrackDeutsch;
		  strcpy (szAudioFormat1, szAudioFormatDeutsch);
		  break;
		case 2:
		  lAudioSpur = lAudioTrackEnglisch;
		  strcpy (szAudioFormat1, szAudioFormatEnglisch);
		  break;
		case 3:
		  lAudioSpur = lAudioTrackDeutsch;
		  strcpy (szAudioFormat1, szAudioFormatDeutsch);
		  break;
		case 4:
		  lAudioSpur = lZusatzAudioTrack;
		  strcpy (szAudioFormat1, szZusatzAudioFormat);
		  break;
		case 5:
		  lAudioSpur = lAudioTrackInput1;
		  if (!strstr (szFormatInput1, "mpeg"))
		    strcpy (szAudioFormat1, szFormatInput1);
		  else
		    strcpy (szAudioFormat1, "mp3");
		  break;
		}
	      lAudioSpur--;
	      // Umrechnen auf Track-ID, da ueber Parameter -aid erforderlich
	      if (strstr (szAudioFormat1, "ac3"))
		{
		  lAudioSpur += 0x80;
		}
	      if (strstr (szAudioFormat1, "dts"))
		{
		  lAudioSpur += 0x88;
		}
	      if (strstr (szAudioFormat1, "lpcm"))
		{
		  lAudioSpur += 0xa0;
		}
	      if (strstr (szAudioFormat1, "mp"))
		{
		  lAudioSpur += 0xc0;
		}
	      // Bei ac3 springen bis zum "sync word"
	      // Ist aber nur noetig bei HQ-Modus-Part2, weil dann der 
	      // ac3 Stream zerrissen wird
	      strcpy (szAudioScan, "");
	      if (strstr (szAudioFormat1, "ac3") && lHighQuality == 2)
		{
		  sprintf (szAudioScan, " /dev/stdout | %s > ",
			   lxac3scan_name);
		}
	      sprintf (szBefehl,
		       "%s %s -dvd-device %s dvd://%ld %s %s -aid %ld -dumpaudio -dumpfile %s %sofile.%s",
		       szNiceRip, mplayer_name, dvd_device, (long) opt_t, szHQChapters,
		       szAngle, lAudioSpur, szAudioScan, szTmpDir,
		       szAudioFormat1);
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      if (lSprachAuswahl == 3 ||	// 2. Audiospur englisch zusaetzlich rippen
		  (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
		{
		  if (lSprachAuswahl == 3)
		    {
		      lAudioSpur = lAudioTrackEnglisch;
		      strcpy (szAudioFormat2, szAudioFormatEnglisch);
		    }
		  else
		    {
		      lAudioSpur = lAudioTrackInput2;
		      if (!strstr (szFormatInput2, "mpeg"))
			strcpy (szAudioFormat2, szFormatInput2);
		      else
			strcpy (szAudioFormat2, "mp3");
		    }
		  lAudioSpur--;	// tcextrcat beginnt mit Spur 0
		  // Umrechnen auf Track-ID, da ueber Parameter -aid erforderlich
		  if (strstr (szAudioFormat2, "ac3"))
		    {
		      lAudioSpur += 0x80;
		    }
		  if (strstr (szAudioFormat2, "dts"))
		    {
		      lAudioSpur += 0x88;
		    }
		  if (strstr (szAudioFormat2, "lpcm"))
		    {
		      lAudioSpur += 0xa0;
		    }
		  if (strstr (szAudioFormat2, "mp"))
		    {
		      lAudioSpur += 0xc0;
		    }
		  // Bei ac3 springen bis zum "sync word"
		  // Ist aber nur noetig bei HQ-Modus-Part2, weil dann der 
		  // ac3 Stream zerrissen wird
		  strcpy (szAudioScan, "");
		  if (strstr (szAudioFormat2, "ac3") && lHighQuality == 2)
		    {
		      sprintf (szAudioScan, " /dev/stdout | %s > ",
			       lxac3scan_name);
		    }
		  sprintf (szBefehl,
			   "%s %s -dvd-device %s dvd://%ld %s %s -aid %ld -dumpaudio -dumpfile %s %sofile_2.%s",
			   szNiceRip, mplayer_name, dvd_device, (long) opt_t,
			   szHQChapters, szAngle, lAudioSpur, szAudioScan,
			   szTmpDir, szAudioFormat2);
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		}
	    }
	  else
	    {			// transcode seriell
	      char szAudioFormatTranscode[12];
	      long lAudioSpur;
	      // Videospur
	      // Bei Faktor = 1 ohne tcrequant, Zeit ist unnoetig
              if (lUseVLC > 0)
              { 
	        if (dFaktor > 1)
		  sprintf (szBefehl,
		           "%s %s dvdsimple:%s@%ld%s%s --intf dummy --no-audio --sout '#standard{access=file,mux=ps,dst=/dev/stdout}' vlc:quit "  
                           " | %s -t vob -x mpeg2 | %s -f %f > %sofile.m2v",
			   szNiceRip, vlc_name, dvd_device, (long) opt_t, szHQChapters,
			   szAngle, tcextract_name, tcrequant_name, dFaktor,
			   szTmpDir);
	        else
		  sprintf (szBefehl,
		           "%s %s dvdsimple:%s@%ld%s%s --intf dummy --no-audio --sout '#standard{access=file,mux=ps,dst=/dev/stdout}' vlc:quit "  
                           " | %s -t vob -x mpeg2 > %sofile.m2v",
			   szNiceRip, vlc_name, dvd_device, (long) opt_t, szHQChapters,
			   szAngle, tcextract_name, szTmpDir);
              } else
              {
	        if (dFaktor > 1)
		  sprintf (szBefehl,
		  	   "%s %s -i %s -T%ld,%s%s -P | %s -t vob -x mpeg2 | %s -f %f > %sofile.m2v",
			   szNiceRip, tccat_name, dvd_device, (long) opt_t, szHQChapters,
			   szAngle, tcextract_name, tcrequant_name, dFaktor,
			   szTmpDir);
	        else
		  sprintf (szBefehl,
		 	   "%s %s -i %s -T%ld,%s%s -P | %s -t vob -x mpeg2 > %sofile.m2v",
			   szNiceRip, tccat_name, dvd_device, (long) opt_t, szHQChapters,
			   szAngle, tcextract_name, szTmpDir);
              }
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      switch (lSprachAuswahl)
		{
		case 1:
		  lAudioSpur = lAudioTrackDeutsch;
		  strcpy (szAudioFormat1, szAudioFormatDeutsch);
		  break;
		case 2:
		  lAudioSpur = lAudioTrackEnglisch;
		  strcpy (szAudioFormat1, szAudioFormatEnglisch);
		  break;
		case 3:
		  lAudioSpur = lAudioTrackDeutsch;
		  strcpy (szAudioFormat1, szAudioFormatDeutsch);
		  break;
		case 4:
		  lAudioSpur = lZusatzAudioTrack;
		  strcpy (szAudioFormat1, szZusatzAudioFormat);
		  break;
		case 5:
		  lAudioSpur = lAudioTrackInput1;
		  strcpy (szAudioFormat1, szFormatInput1);
		  break;
		}
	      // lpcm wird von Transcode als pcm gerippt
	      strcpy (szAudioFormatTranscode, szAudioFormat1);
	      lAudioSpur--;	// tcextrcat beginnt mit Spur 0
	      if (strstr (szAudioFormat1, "pcm"))
		{
		  // pcm als mpeg2 umwandeln
		  strcpy (szAudioFormat1, "mpeg2");
		  strcpy (szAudioFormatTranscode, "pcm");
                  if (lUseVLC > 0)
                  {
                    sprintf (szBefehl,
		           "%s %s dvdsimple:%s@%ld%s%s --audio-track %ld --no-video "
                           "--intf dummy --sout '#standard{access=file,mux=ps,dst=/dev/stdout}' vlc:quit "  
			   " | %s -t vob -x %s | "
			   "%s -x null,raw -y null,mp2enc -i /dev/stdin "
			   "-E 48000 -b 192 --ext none,none -m %sofile.%s",
			   szNiceRip, vlc_name, dvd_device, (long) opt_t, szHQChapters,
			   szAngle, lAudioSpur, tcextract_name, szAudioFormatTranscode,
			   transcode_name, szTmpDir,
			   szAudioFormat1);

		  } else
                  {
                    sprintf (szBefehl,
			   "%s %s -i %s -T%ld,%s%s -P | %s -t vob -x %s -a %ld | "
			   "%s -x null,raw -y null,mp2enc -i /dev/stdin "
			   "-E 48000 -b 192 --ext none,none -m %sofile.%s",
			   szNiceRip, tccat_name, dvd_device, (long) opt_t, szHQChapters,
			   szAngle, tcextract_name, szAudioFormatTranscode,
			   lAudioSpur, transcode_name, szTmpDir,
			   szAudioFormat1);
                  }
		}
	      else
		{
		  if (strstr (szAudioFormat1, "mpeg1"))
		    {
		      // mpeg 1 als mpeg2 umwandeln
		      strcpy (szAudioFormat1, "mpeg2");
		      strcpy (szAudioFormatTranscode, "mp3");
                      if (lUseVLC > 0) 
                      {
		        sprintf (szBefehl,
		               "%s %s dvdsimple:%s@%ld%s%s --audio-track %ld --no-video "
                               "--intf dummy --sout '#standard{access=file,mux=ps,dst=/dev/stdout}' vlc:quit "  
                               " | %s -t vob -x %s | "
			       "%s -x null,auto -y null,mp2enc -i /dev/stdin "
			       "-E 48000 -b 192 --ext none,none -m %sofile.%s",
			       szNiceRip, vlc_name, dvd_device, (long) opt_t, szHQChapters,
			       szAngle, lAudioSpur, tcextract_name,
			       szAudioFormatTranscode, 
			       transcode_name, szTmpDir, szAudioFormat1);
                      } else
                      {
		        sprintf (szBefehl,
			       "%s %s -i %s -T%ld,%s%s -P | %s -t vob -x %s -a %ld | "
			       "%s -x null,auto -y null,mp2enc -i /dev/stdin "
			       "-E 48000 -b 192 --ext none,none -m %sofile.%s",
			       szNiceRip, tccat_name, dvd_device, (long) opt_t,
			       szHQChapters, szAngle, tcextract_name,
			       szAudioFormatTranscode, lAudioSpur,
			       transcode_name, szTmpDir, szAudioFormat1);
                      }
		    }
		  else
		    {
		      // Bei ac3 springen bis zum "sync word"
		      // Ist aber nur noetig bei HQ-Modus-Part2, weil dann der 
		      // ac3 Stream zerrissen wird
		      char szAudioScan[128];
		      strcpy (szAudioScan, "");
		      if (strstr (szAudioFormat1, "ac3") && lHighQuality == 2)
			{
			  sprintf (szAudioScan, " | %s ", lxac3scan_name);
			}
		      // ac3, dts, mpeg2 Audio
		      if (strstr (szAudioFormat1, "mpeg2"))
			strcpy (szAudioFormatTranscode, "mp3");
                      if (lUseVLC > 0)
                      {
  		        sprintf (szBefehl,
		               "%s %s dvdsimple:%s@%ld%s%s --audio-track %ld --no-video "
                               "--intf dummy --sout '#standard{access=file,mux=ps,dst=/dev/stdout}' vlc:quit "  
                               " | %s -t vob -x %s %s > %sofile.%s",
			       szNiceRip, vlc_name, dvd_device, (long) opt_t, szHQChapters,
			       szAngle, lAudioSpur, tcextract_name,
			       szAudioFormatTranscode, 
			       szAudioScan, szTmpDir, szAudioFormat1);
                      } else
                      {
  		        sprintf (szBefehl,
			       "%s %s -i %s -T%ld,%s%s -P | %s -t vob -x %s -a %ld %s > %sofile.%s",
			       szNiceRip, tccat_name, dvd_device, (long) opt_t,
			       szHQChapters, szAngle, tcextract_name,
			       szAudioFormatTranscode, lAudioSpur,
			       szAudioScan, szTmpDir, szAudioFormat1);
                      }
		    }
		}
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      if (lSprachAuswahl == 3 ||	// 2. Audiospur englisch zusaetzlich rippen
		  (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
		{
		  if (lSprachAuswahl == 3)
		    {
		      lAudioSpur = lAudioTrackEnglisch;
		      strcpy (szAudioFormat2, szAudioFormatEnglisch);
		    }
		  else
		    {
		      lAudioSpur = lAudioTrackInput2;
		      strcpy (szAudioFormat2, szFormatInput2);
		    }
		  lAudioSpur--;	// tcextrcat beginnt mit Spur 0
		  if (strstr (szAudioFormat2, "pcm"))
		    {
		      // pcm als mpeg2 umwandeln
		      strcpy (szAudioFormat2, "mpeg2");
		      strcpy (szAudioFormatTranscode, "pcm");
                      if (lUseVLC > 0)
                      {
		        sprintf (szBefehl,
		               "%s %s dvdsimple:%s@%ld%s%s --audio-track %ld --no-video "
                               "--intf dummy --sout '#standard{access=file,mux=ps,dst=/dev/stdout}' vlc:quit "  
			       " | %s -t vob -x %s | "
			       "%s -x null,raw -y null,mp2enc -i /dev/stdin "
			       "-E 48000 -b 192 --ext none,none -m %sofile_2.%s",
			       szNiceRip, vlc_name, dvd_device, (long) opt_t, szHQChapters,
			       szAngle, lAudioSpur, tcextract_name,
			       szAudioFormatTranscode, 
			       transcode_name, szTmpDir, szAudioFormat2);
                      } else
                      {
		        sprintf (szBefehl,
			       "%s %s -i %s -T%ld,%s%s -P | %s -t vob -x %s -a %ld | "
			       "%s -x null,raw -y null,mp2enc -i /dev/stdin "
			       "-E 48000 -b 192 --ext none,none -m %sofile_2.%s",
			       szNiceRip, tccat_name, dvd_device, (long) opt_t,
			       szHQChapters, szAngle, tcextract_name,
			       szAudioFormatTranscode, lAudioSpur,
			       transcode_name, szTmpDir, szAudioFormat2);
                      }
		    }
		  else
		    {
		      if (strstr (szAudioFormat2, "mpeg1"))
			{
			  // mpeg 1 als mpeg2 umwandeln
			  strcpy (szAudioFormat2, "mpeg2");
			  strcpy (szAudioFormatTranscode, "mp3");
                          if (lUseVLC > 0)
                          {
			    sprintf (szBefehl,
		                   "%s %s dvdsimple:%s@%ld%s%s --audio-track %ld --no-video "
                                   "--intf dummy --sout '#standard{access=file,mux=ps,dst=/dev/stdout}' vlc:quit "  
                                   " | %s -t vob -x %s | "
				   "%s -x null,auto -y null,mp2enc -i /dev/stdin "
				   "-E 48000 -b 192 --ext none,none -m %sofile_2.%s",
				   szNiceRip, vlc_name, dvd_device, (long) opt_t, szHQChapters,
				   szAngle, lAudioSpur, tcextract_name,
				   szAudioFormatTranscode, 
				   transcode_name, szTmpDir, szAudioFormat2);
                          } else
                          {
			    sprintf (szBefehl,
				   "%s %s -i %s -T%ld,%s%s -P | %s -t vob -x %s -a %ld | "
				   "%s -x null,auto -y null,mp2enc -i /dev/stdin "
				   "-E 48000 -b 192 --ext none,none -m %sofile_2.%s",
				   szNiceRip, tccat_name, dvd_device, (long) opt_t,
				   szHQChapters, szAngle, tcextract_name,
				   szAudioFormatTranscode, lAudioSpur,
				   transcode_name, szTmpDir, szAudioFormat2);
                          }
			}
		      else
			{
			  // Bei ac3 springen bis zum "sync word"
			  // Ist aber nur noetig bei HQ-Modus-Part2, weil dann der 
			  // ac3 Stream zerrissen wird
			  char szAudioScan[128];
			  strcpy (szAudioScan, "");
			  if (strstr (szAudioFormat2, "ac3")
			      && lHighQuality == 2)
			    {
			      sprintf (szAudioScan, " | %s ", lxac3scan_name);
			    }
			  // ac3, dts, mpeg2 Audio
			  if (strstr (szAudioFormat2, "mpeg2"))
			    strcpy (szAudioFormatTranscode, "mp3");
                          if (lUseVLC > 0)
                          { 
			    sprintf (szBefehl,
		                   "%s %s dvdsimple:%s@%ld%s%s --audio-track %ld --no-video "
                                   "--intf dummy --sout '#standard{access=file,mux=ps,dst=/dev/stdout}' vlc:quit "
                                   " | %s -t vob -x %s %s > %sofile_2.%s",
				   szNiceRip, vlc_name, dvd_device, (long) opt_t, szHQChapters,
				   szAngle, lAudioSpur, tcextract_name,
				   szAudioFormatTranscode, 
				   szAudioScan, szTmpDir, szAudioFormat2);
                          } else
                          {
			    sprintf (szBefehl,
				   "%s %s -i %s -T%ld,%s%s -P | %s -t vob -x %s -a %ld %s > %sofile_2.%s",
				   szNiceRip, tccat_name, dvd_device, (long) opt_t,
				   szHQChapters, szAngle, tcextract_name,
				   szAudioFormatTranscode, lAudioSpur,
				   szAudioScan, szTmpDir, szAudioFormat2);
                          }
			}
		    }
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		}
	    }
	  // Wenn ohne Untertitel, dann "dvdauthor -f 'mplex |'"
	  if (lUntertitel)
	    sprintf (szMplexAusgabe, "%sfilm-neu.vob", szTmpDir);
	  else
	    {
	      if (strlen (szOutputFile))
		strcpy (szMplexAusgabe, szOutputFile);
	      else
		strcpy (szMplexAusgabe, "/dev/stdout");
	    }
	  // Multiplexer ist auswaehlbaer
	  if (lMultiplexer == 1)
	    {
	      // 2 Audio-Spuren
	      if ((lSprachAuswahl == 3) ||	// deutsch und englisch
		  (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
		{
		  sprintf (szBefehl,
			   "%s %s -i %sofile.m2v -p %sofile.%s -s %sofile_2.%s -m d -o %s",
			   szNiceRip, tcmplex_name, szTmpDir, szTmpDir, szAudioFormat1,
			   szTmpDir, szAudioFormat2, szMplexAusgabe);
		}
	      else
		{
		  sprintf (szBefehl,
			   "%s %s -i %sofile.m2v -p %sofile.%s -m d -o %s",
			   szNiceRip, tcmplex_name, szTmpDir, szTmpDir, szAudioFormat1,
			   szMplexAusgabe);
		}
	    }
	  else
	    {
	      // 2 Audio-Spuren
	      if ((lSprachAuswahl == 3) ||	// deutsch und englisch
		  (lSprachAuswahl == 5 && lAudioTrackInput2 > 0))
		{
		  sprintf (szBefehl,
			   "%s %s -f 8 -o %s %sofile.m2v %sofile.%s %sofile_2.%s -S 0 -M ",
			   szNiceRip, mplex_name, szMplexAusgabe, szTmpDir, szTmpDir,
			   szAudioFormat1, szTmpDir, szAudioFormat2);
		}
	      else
		{
		  sprintf (szBefehl,
			   "%s %s -f 8 -o %s %sofile.m2v %sofile.%s -S 0 -M ",
			   szNiceRip, mplex_name, szMplexAusgabe, szTmpDir, szTmpDir,
			   szAudioFormat1);
		}
	    }
	  // Bei Untertiteln erst multiplexen
	  // Untertitel mit spuunmux auslesen und mit spumux hinzufuegen
	  if (lUntertitel)
	    {
	      printf ("%s\n", szBefehl);
	      lRC = system (szBefehl);
	      if (lRC == 0)	// mplex meldet OK, dann Loeschen
		{
		  sprintf (szBefehl, "rm %sofile*", szTmpDir);	// sonst erst nach dvdauthor loeschen
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		}
	      // Untertitel auslesen
	      // tccat liest DVD, 
	      // spuunmux erzeugt die pngs und die xml-Datei fuer Spumux.
	      if (lPackMethode == 3)
		{
		  // Mplayer
		  sprintf (szBefehl,
			   "%s %s -dvd-device %s dvd://%ld %s %s -dumpstream -dumpfile /dev/stdout | %s -o %sdvd -s %ld %s /dev/stdin",
			   szNiceRip, mplayer_name, dvd_device, (long) opt_t,
			   szHQChapters, szAngle, spuunmux_name, szTmpDir,
			   lUntertitel - 1, szPaletteOptions);
		}
	      else
		{
		  // Transcode mit tccat
                  if (lUseVLC)
                  {
		    sprintf (szBefehl,
                           "%s %s dvdsimple:%s@%ld%s%s --intf dummy "
                           "--sout-spu --sub-track %ld "
                           "--sout '#standard{access=file,mux=ps,dst=/dev/stdout}' "
                           " vlc:quit "
                           " | %s -o %sdvd -s 0 %s /dev/stdin",
			   szNiceRip, vlc_name, dvd_device, (long) opt_t,
                           szHQChapters, szAngle, lUntertitel - 1,
                           spuunmux_name, szTmpDir, szPaletteOptions);
                  } else
                  {
		    sprintf (szBefehl,
			   "%s %s -i %s -T%ld,%s%s -P | %s -o %sdvd -s %ld %s /dev/stdin",
			   szNiceRip, tccat_name, dvd_device, (long) opt_t, szHQChapters,
			   szAngle, spuunmux_name, szTmpDir, lUntertitel - 1,
			   szPaletteOptions);
                  }
		}
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      // Untertitel wieder ins MPEG multiplexen
	      sprintf (szBefehl, "mv %sfilm-neu.vob %sdummy.mpeg", szTmpDir,
		       szTmpDir);
	      system (szBefehl);
	      sprintf (szBefehl,
		       "%s %s -m dvd -s 0 %sdvd.xml < %sdummy.mpeg > %sfilm-neu.vob",
		       szNiceRip, spumux_name, szTmpDir, szTmpDir, szTmpDir);
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      // Alte Datei ohne Untertitel wieder loeschen
	      sprintf (szBefehl, "rm %sdummy.mpeg", szTmpDir);
	      system (szBefehl);
	      // Ausserdem das XML-Script und die pngs loeschen
	      sprintf (szBefehl, "rm %sdvd*.xml", szTmpDir);
	      system (szBefehl);
	      sprintf (szBefehl, "rm %sdvd*.png", szTmpDir);
	      system (szBefehl);
	      // 2. Untertitelspur, gleicher Durchlauf
	      if (lUntertitel2)
		{
		  // Untertitel auslesen
		  // tccat liest DVD, 
		  // spuunmux erzeugt die pngs und die xml-Datei fuer Spumux.
		  if (lPackMethode == 3)
		    {
		      // Mplayer
		      sprintf (szBefehl,
			       "%s %s -dvd-device %s dvd://%ld %s %s -dumpstream -dumpfile /dev/stdout | %s -o %sdvd -s %ld %s /dev/stdin",
			       szNiceRip, mplayer_name, dvd_device, (long) opt_t,
			       szHQChapters, szAngle, spuunmux_name, szTmpDir,
			       lUntertitel2 - 1, szPaletteOptions);
		    }
		  else
		    {
		      // Transcode mit tccat
                      if (lUseVLC > 0)
                      {
		        sprintf (szBefehl,
                                 "%s %s dvdsimple:%s@%ld%s%s --intf dummy "
                                 "--sout-spu --sub-track %ld "
                                 "--sout '#standard{access=file,mux=ps,dst=/dev/stdout}' "
                                 " vlc:quit "
                                 " | %s -o %sdvd -s 0 %s /dev/stdin",
			         szNiceRip, vlc_name, dvd_device, 
                                 (long) opt_t, szHQChapters, szAngle,
                                 lUntertitel2 - 1, spuunmux_name, szTmpDir,
			         szPaletteOptions);
                      } else
                      {
		        sprintf (szBefehl,
			         "%s %s -i %s -T%ld,%s%s -P | %s -o %sdvd -s %ld %s /dev/stdin",
			         szNiceRip, tccat_name, dvd_device, (long) opt_t,
			         szHQChapters, szAngle, spuunmux_name, szTmpDir,
			         lUntertitel2 - 1, szPaletteOptions);
                      }
		    }
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		  // Untertitel wieder ins MPEG multiplexen
		  sprintf (szBefehl, "mv %sfilm-neu.vob %sdummy.mpeg",
			   szTmpDir, szTmpDir);
		  system (szBefehl);
		  sprintf (szBefehl,
			   "%s %s -m dvd -s 1 %sdvd.xml < %sdummy.mpeg > %sfilm-neu.vob",
			   szNiceRip, spumux_name, szTmpDir, szTmpDir, szTmpDir);
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		  // Alte Datei ohne Untertitel wieder loeschen
		  sprintf (szBefehl, "rm %sdummy.mpeg", szTmpDir);
		  system (szBefehl);
		  // Ausserdem das XML-Script und die pngs loeschen
		  sprintf (szBefehl, "rm %sdvd*.xml", szTmpDir);
		  system (szBefehl);
		  sprintf (szBefehl, "rm %sdvd*.png", szTmpDir);
		  system (szBefehl);
		}
	      sprintf (szVOBQuelle, "%sfilm-neu.vob", szTmpDir);
	    }
	  else
	    {
	      sprintf (szVOBQuelle, "-f ' %s |'", szBefehl);
	    }
	  if (strlen (szOutputFile))	// Datei statt Brennen ?
	    {
	      if (!lUntertitel)	// mplex-Befehl ausfuehren
		{
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		  sprintf (szBefehl, "rm %sofile*", szTmpDir);	// sonst erst nach dvdauthor loeschen
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		}
	      else
		{		// Datei ist nach spumux fertig, move zu Ausgabedatei
		  sprintf (szBefehl, "mv %sfilm-neu.vob %s", szTmpDir,
			   szOutputFile);
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		}
	      // DVDwizard starten ?
	      if (lDVDWizard)
		{
		  char szAudio1[10], szAudio2[10];
		  strcpy (szAudio1, "");
		  strcpy (szAudio2, "");
		  switch (lSprachAuswahl)
		    {
		    case 1:
		      strcpy (szAudio1, "de");
		      break;
		    case 2:
		      strcpy (szAudio1, "en");
		      break;
		    case 3:
		      strcpy (szAudio1, "de");
		      strcpy (szAudio2, "en");
		      break;
		    case 4:
		      strcpy (szAudio1, szZusatzSprache);
		      break;
		    case 5:
		      strcpy (szAudio1, szSpracheInput1);
		      strcpy (szAudio2, szSpracheInput2);
		      break;
		    }
		  // Name von aussen setzbar
		  if (strlen (szDVDNameOverwrite))
		    strcpy (szDVDName, szDVDNameOverwrite);
		  // DVD-Wizard starten
		  dvd_wizard (szNiceRip, dvdwizard_name, szDVDWizardVideoAngaben,
			      szDVDName, dvdwizard_bild,
			      szChapterString, szAudio1, szAudio2,
			      szFilmVerzeichnis, szOutputFile, lLoeschen,
			      szUntertitelOptionen, szPaletteFile, lSprache);
		}
	      else
		{
		  // DVD auswerfen ?
		  if (lEject)
		    {
		      sprintf (szBefehl, "%s %s", eject_name, dvd_device);
		      printf ("%s\n", szBefehl);
		      system (szBefehl);
		    }
		  if (lPlaySound > 0)
		    play_sound_if_ready (lxdvdrip_wav_name);
		  switch (lSprache)
		    {
		    case 0:
		      printf ("\nFertig!\n");
		      break;
		    case 1:
		      printf ("\nReady!\n");
		      break;
		    case 2:
		      printf ("\nPrêt !\n");
		      break;
		    }
		  // Palettendatei loeschen
		  if (filesize64 (szPaletteFile, szTmpDir) > 0)
		    {
		      sprintf (szBefehl, "rm %s", szPaletteFile);
		      system (szBefehl);
		    }
		  return 0;
		}
	    }
	  // LPCM als PCM an DVDAUTHOR uebergeben
	  if (strstr (szAudioFormat1, "pcm"))
	    strcpy (szAudioFormat1, "pcm");
	  if (strstr (szAudioFormat2, "pcm"))
	    strcpy (szAudioFormat2, "pcm");
	  // mpeg Audio als mp2 uebergeben
	  if (strstr (szAudioFormat1, "mp"))
	    strcpy (szAudioFormat1, "mp2");
	  if (strstr (szAudioFormat2, "mp"))
	    strcpy (szAudioFormat2, "mp2");
	  if (lSprachAuswahl == 1)
	    {
	      sprintf (szBefehl, "%s %s -t %s %s %s %s -a %s+de -o %s %s",
		       szNiceRip, dvdauthor_name, szUntertitelOptionen, szVideoAngaben,
		       szPaletteOptions, szChapterString, szAudioFormat1,
		       szFilmVerzeichnis, szVOBQuelle);
	    }
	  if (lSprachAuswahl == 2)
	    {
	      sprintf (szBefehl, "%s %s -t %s %s %s %s -a %s+en -o %s %s",
		       szNiceRip, dvdauthor_name, szUntertitelOptionen, szVideoAngaben,
		       szPaletteOptions, szChapterString, szAudioFormat1,
		       szFilmVerzeichnis, szVOBQuelle);
	    }
	  if (lSprachAuswahl == 3)
	    {
	      sprintf (szBefehl, "%s %s -t %s %s %s %s -a %s+de,%s+en -o %s %s",
		       szNiceRip, dvdauthor_name, szUntertitelOptionen, szVideoAngaben,
		       szPaletteOptions, szChapterString, szAudioFormat1,
		       szAudioFormat2, szFilmVerzeichnis, szVOBQuelle);
	    }
	  if (lSprachAuswahl == 4)
	    {
	      sprintf (szBefehl, "%s %s -t %s %s %s %s -a %s+%s -o %s %s",
		       szNiceRip, dvdauthor_name, szUntertitelOptionen, szVideoAngaben,
		       szPaletteOptions, szChapterString, szAudioFormat1,
		       szZusatzSprache, szFilmVerzeichnis, szVOBQuelle);
	    }
	  if (lSprachAuswahl == 5)
	    {
	      if (lAudioTrackInput2 == 0)
		{
		  sprintf (szBefehl, "%s %s -t %s %s %s %s -a %s+%s -o %s %s",
			   szNiceRip, dvdauthor_name, szUntertitelOptionen,
			   szVideoAngaben, szPaletteOptions, szChapterString,
			   szAudioFormat1, szSpracheInput1, szFilmVerzeichnis,
			   szVOBQuelle);
		}
	      else
		{
		  sprintf (szBefehl,
			   "%s %s -t %s %s %s %s -a %s+%s,%s+%s -o %s %s",
			   szNiceRip, dvdauthor_name, szUntertitelOptionen,
			   szVideoAngaben, szPaletteOptions, szChapterString,
			   szAudioFormat1, szSpracheInput1, szAudioFormat2,
			   szSpracheInput2, szFilmVerzeichnis, szVOBQuelle);
		}
	    }
	  if (!lDVDWizard)
	    {
	      printf ("%s\n", szBefehl);
	      lRC = system (szBefehl);
	      if (lRC == 0)	// dvdauthor meldet OK, dann Loeschen
		{
		  if (!lUntertitel)
		    sprintf (szBefehl, "rm %sofile*", szTmpDir);
		  else
		    sprintf (szBefehl, "rm %sfilm-neu.vob", szTmpDir);
		  system (szBefehl);
		}
	      else
		{
		  switch (lSprache)
		    {
		    case 0:
		      printf
			("DVD-Author meldet Fehler, Dateien werden daher nicht geloescht!\n");
		      break;
		    case 1:
		      printf
			("DVD-Author gives an error, so files will not be deleted!\n");
		      break;
		    case 2:
		      printf
			("DVD-Author signale une erreur, les fichiers ne seront pas effacés !\n");
		      break;
		    }
		}
	    }
	}


      // DVD-Author erzeugt IFOs
      if (lPackMethode < 5 && !lDVDWizard && !lMenues)	// nicht bei dvdbackup
	{
	  // Test, ob Unterverzeichnis "VIDEO_TS" existiert
	  struct stat tmpStat;
	  char filename[255];
	  long lRC;
	  strcpy (szVideoTS, "VIDEO_TS");
	  strcpy (szAudioTS, "AUDIO_TS");
	  strcpy (szVobTS, "VOB");
	  strcpy (szVtsTS, "VTS");
	  sprintf (filename, "%s/%s", szFilmVerzeichnis, szVideoTS);
	  if (stat (filename, &tmpStat) != 0)	// keine weitere Datei vorhanden
	    {
	      // VIDEO_TS nicht da, versuche video_ts stattdessen
	      sprintf (filename, "%s/video_ts", szFilmVerzeichnis);
	      if (stat (filename, &tmpStat) != 0)	// keine weitere Datei vorhanden
		{
		  // Auch das nicht gefunden, Hinweis
		  switch (lSprache)
		    {
		    case 0:
		      printf
			("\nVideoverzeichnis 'VIDEO_TS' nicht gefunden!\n");
		      break;
		    case 1:
		      printf ("\nDirectory 'VIDEO_TS' not found!\n");
		      break;
		    case 2:
		      printf
			("\nLe répertoire 'VIDEO_TS' est introuvable !\n");
		      break;
		    }
		}
	      else
		{
		  // video_ts existiert, daher alles auf Kleinschrift umschalten
		  strcpy (szVideoTS, "video_ts");
		  strcpy (szAudioTS, "audio_ts");
		  strcpy (szVobTS, "vob");
		  strcpy (szVtsTS, "vts");
		  switch (lSprache)
		    {
		    case 0:
		      printf
			("\nVideoverzeichnis 'VIDEO_TS' nicht gefunden, nehme 'video_ts'!\n");
		      break;
		    case 1:
		      printf
			("\nDirectory 'VIDEO_TS' not found, using 'video_ts'!\n");
		      break;
		    case 2:
		      printf
			("\nRépertoire 'VIDEO_TS' introuvable, utilisera 'video_ts'!\n");
		      break;
		    }
		}
	    }
	  sprintf (szBefehl, "%s %s -T -o %s", szNiceRip, dvdauthor_name,
		   szFilmVerzeichnis);
	  printf ("%s\n", szBefehl);
	  lRC = system (szBefehl);
	  if (lRC != 0)
	    {
	      char cNeuerVersuch;
	      switch (lSprache)
		{
		case 0:
		  printf
		    ("'dvdauthor -T' meldet Fehler, erneute Authorisierung versuchen? (j=Ja)\n");
		  break;
		case 1:
		  printf
		    ("'dvdauthor -T' gives an error. Try a new authorisation? (y=Yes)\n");
		  break;
		case 2:
		  printf
		    ("'dvdauthor -T' signale une erreur. Recommencer ? (o=Oui)\n");
		  break;
		}
	      scanf ("%1c", &cNeuerVersuch);
	      if (cNeuerVersuch == 'j' || cNeuerVersuch == 'y'
		  || cNeuerVersuch == 'o')
		{
		  char szTracks[128];
		  switch (lSprachAuswahl)
		    {
		    case 1:
		      sprintf (szTracks, "-a %s+de", szAudioFormatDeutsch);
		      break;
		    case 2:
		      sprintf (szTracks, "-a %s+en", szAudioFormatEnglisch);
		      break;
		    case 3:
		      sprintf (szTracks, "-a %s+de,%s+en",
			       szAudioFormatDeutsch, szAudioFormatEnglisch);
		      break;
		    case 4:
		      sprintf (szTracks, "-a %s+%s", szZusatzAudioFormat,
			       szZusatzSprache);
		      break;
		    case 5:
		      sprintf (szTracks, "-a %s+%s", szFormatInput1,
			       szSpracheInput1);
		      if (lAudioTrackInput2 > 0)
			{
			  strcat (szTracks, ",");
			  strcat (szTracks, szFormatInput2);
			  strcat (szTracks, "+");
			  strcat (szTracks, szSpracheInput2);
			}
		      break;
		    }
		  sprintf (szBefehl, "%s %s -t %s %s %s %s -o %s %s/%s/*%s",
			   szNiceRip, dvdauthor_name, szChapterString, szTracks,
			   szUntertitelOptionen, szPaletteOptions,
			   szFilmVerzeichnis, szFilmVerzeichnis, szVideoTS,
			   szVobTS);
		  printf ("%s\n", szBefehl);
		  lRC = system (szBefehl);
		  sprintf (szBefehl, "%s %s -T -o %s", szNiceRip, dvdauthor_name,
			   szFilmVerzeichnis);
		  printf ("%s\n", szBefehl);
		  lRC = system (szBefehl);
		}
	      eatToNL (stdin);	// Eingabepuffer leeren
	    }
	}

    }				// else Umschaltung auf dvdbackup

  // Copymodus mit dvdwizard behandeln wie partcopy, ort aber alles automatisch markieren
  if ((lPackMethode == 5) &&	// Copymode
      lDVDWizard &&		// dvdwizard eingeschaltet
      (lGroesseDVDGesamt > lGroesseDVDBytesMaximal)	// groesser als 1 Rohling
    )
    {
      lPackMethode = 6;		// partcopy
      lPartcopyAllesMarkieren = 1;	// alles automatisch markieren
    }

  // DVD mit dvdbackup auslesen
  // Fuer einfaches Rippen von bereits kopierten DVDs ohne 
  // dvdauthor, requant etc.
  if (lPackMethode == 5)	// dvdbackup
    {
      long lGemountet = 0;
      char szTempFilmVerzeichnis[1024];
      // Wenn DVD kleiner als 4.7 GB, dann Backup ueber dvdbackup
      if (lGroesseDVDGesamt <= lGroesseDVDBytesMaximal)
	{
	  switch (lSprache)
	    {
	    case 0:
	      printf ("DVD kleiner als 4.7 GB, Backup mit dvdbackup!\n");
	      break;
	    case 1:
	      printf ("DVD <= 4.7 GB, Backup with dvdbackup!\n");
	      break;
	    case 2:
	      printf
		("Ce DVD contient moins de 4.7Go, copie par dvdbackup !\n");
	      break;
	    }
	  check_program (dvdbackup_name, lSprache, 1);
	  if (!strstr (dvdbackup_name, "vobcopy"))
	    {
	      // DVD-Backup
	      sprintf (szBefehl, "%s %s -i %s -o %s -M",
		       szNiceRip, dvdbackup_name, dvd_device, szFilmVerzeichnis);
	      if (strlen (szDVDName))
		{
		  strcat (szBefehl, " -n");
		  strcat (szBefehl, szDVDName);
		}
	    }
	  else
	    {
	      FILE *fTmp;
	      char szTmp[256];
	      char szMountDir[256];
	      // Ist Leselaufwerk in der mtab?
	      szMountDir[0] = 0;
	      fTmp = fopen ("/etc/mtab", "r");
	      if (fTmp)
		{
		  while (fscanf (fTmp, "%255s\n", szTmp) != EOF)
		    {
		      if (strstr (szTmp, dvd_device))	// DVD-Leser gefunden
			{
			  fscanf (fTmp, "%255s\n", szMountDir);
			  break;
			}
		    }
		  fclose (fTmp);
		}
	      // wenn nicht gefunden, manuell mounten
	      if (!strlen (szMountDir))
		{
		  // temp-Mountverzeichnis anlegen
		  sprintf (szBefehl, "mkdir %s/manmount.lxdvdrip", szTmpDir);
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		  // Mounten
		  sprintf (szBefehl, "mount %s %s/manmount.lxdvdrip",
			   dvd_device, szTmpDir);
		  printf ("%s\n", szBefehl);
		  if (system (szBefehl) != 0)
		    {
		      switch (lSprache)
			{
			case 0:
			  printf ("\nBitte %s zuvor als root mounten!\n",
				  dvd_device);
			  break;
			case 1:
			  printf ("\nPlease mount %s manually as root!\n",
				  dvd_device);
			  break;
			case 2:
			  printf
			    ("\nVous devez monter %s manuellement sous root!\n",
			     dvd_device);
			  break;
			}
		      exit (0);	// Mountfehler
		    }
		  lGemountet = 1;
		  sprintf (szMountDir, "%s/manmount.lxdvdrip", szTmpDir);
		}
	      // Vobcopy
	      sprintf (szBefehl, "%s %s -i %s -o %s -m -f -l",
		       szNiceRip, dvdbackup_name, szMountDir, szFilmVerzeichnis);
	    }
          // Test, ob Datei im Rip-Verzeichnis vorhanden
	  sprintf (szTempFilmVerzeichnis, "%s/%s", szFilmVerzeichnis, szDVDName);
          checkLastRip (szTempFilmVerzeichnis, lSprache);
          // Rippen ausfuehren
	  printf ("%s\n", szBefehl);
	  system (szBefehl);
	  if (lGemountet == 1)	// wieder unmounten
	    {
	      // unmount
	      sprintf (szBefehl, "umount %s/manmount.lxdvdrip", szTmpDir);
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      // temp-Mountverzeichnis anlegen
	      sprintf (szBefehl, "rmdir %s/manmount.lxdvdrip", szTmpDir);
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      lGemountet = 0;
	    }
	  // Fuer folgende Befehle wird das Volume-Label der DVD ans Filmverzeichnis 
	  // angehaengt.
	  strcpy (szAltesFilmVerzeichnis, szFilmVerzeichnis);
	  if (szFilmVerzeichnis[strlen (szFilmVerzeichnis) - 1] != '/')
	    strcat (szFilmVerzeichnis, "/");
	  strcat (szFilmVerzeichnis, szDVDName);
	  // Verzeichnis AUDIO_TS anlegen
	  sprintf (szBefehl, "mkdir %s/AUDIO_TS -m 0777", szFilmVerzeichnis);
	  printf ("%s\n", szBefehl);
	  system (szBefehl);
	}
      else
	{
	  int titelNr, vobNr;
	  char szFileName[128];
	  long long lGroesseVOBs = 0;
	  FILE *fp1, *fp2;
	  char szWort[512], szVorherigesWort[512];
	  switch (lSprache)
	    {
	    case 0:
	      printf
		("DVD groesser als 4.7 GB, Backup mit dvdunauthor/vamps!\n");
	      break;
	    case 1:
	      printf ("DVD > 4.7 GB, Backup with dvdunauthor/vamps!\n");
	      break;
	    case 2:
	      printf
		("Ce DVD contient plus de 4.7Go, copie par dvdunauthor/vamps !\n");
	      break;
	    }
	  check_program (dvdauthor_name, lSprache, 1);
	  check_program (dvdunauthor_name, lSprache, 1);
	  check_program (vamps_name, lSprache, 1);
	  check_program (tcprobe_name, lSprache, 1);
          // Test, ob Datei im Rip-Verzeichnis vorhanden
          checkLastRip (szFilmVerzeichnis, lSprache);
	  // Auslesen der DVD mit dvdunauthor
	  sprintf (szBefehl, "%s %s %s", szNiceRip, dvdunauthor_name, dvd_device);
	  printf ("%s\n", szBefehl);
	  if (!lTestlauf)
	    system (szBefehl);	// dvdunauthor nur Normallauf, nicht bei Test
	  // Nun wird bestimmt, welche Dateien mit welchem Faktor verkleinert werden muessen
	  for (titelNr = 1; titelNr <= 99; titelNr++)
	    {
	      long long lSize;
	      sprintf (szFileName, "vob_%02d_001t.vob", titelNr);	// <= dvdauthor 0.6.11
	      lSize = filesize64 (szFileName, szTmpDir);
	      if (lSize == 0)
		{
		  sprintf (szFileName, "vob_%02dt_001.vob", titelNr);	// >= dvdauthor 0.6.12
		  lSize = filesize64 (szFileName, szTmpDir);
		  if (lSize == 0)
		    {
		      continue;
		    }
		}
	      printf ("%s, %lld\n", szFileName, lSize);
	      lGroesseVOBs += lSize;
	      for (vobNr = 2; vobNr <= 99; vobNr++)
		{
		  sprintf (szFileName, "vob_%02d_%03dt.vob", titelNr, vobNr);	// <= dvdauthor 0.6.11
		  lSize = filesize64 (szFileName, szTmpDir);
		  if (lSize == 0)
		    {
		      sprintf (szFileName, "vob_%02dt_%03d.vob", titelNr, vobNr);	// >= dvdauthor 0.6.12
		      lSize = filesize64 (szFileName, szTmpDir);
		      if (lSize == 0)
			{
			  break;
			}
		    }
		  printf ("%s, %lld\n", szFileName, lSize);
		  lGroesseVOBs += lSize;
		}
	    }
	  if (dFaktor <= 0)	// Nicht umsetzen, wenn von aussen gesetzt
	    {
	      dFaktor = (double) lGroesseVOBs / (double) lGroesseDVDBytes;
	    }
	  // Faktor auf Basis 4.6 GB berechnen, etwas Reserve
	  switch (lSprache)
	    {
	    case 0:
	      {
		printf ("Groesse Titelsets: %lld Bytes\n", lGroesseVOBs);
		printf ("Faktor fuer vamps: %f\n", dFaktor);
		break;
	      }
	    case 1:
	      {
		printf ("Title-sets: %lld Bytes\n", lGroesseVOBs);
		printf ("Factor for vamps: %f\n", dFaktor);
		break;
	      }
	    case 2:
	      {
		printf ("Taille des titres : %lld Octets\n", lGroesseVOBs);
		printf ("Facteur pour vamps: %f\n", dFaktor);
		break;
	      }
	    }
	  // Nun die Dateien vampsen
	  for (titelNr = 1; titelNr <= 99; titelNr++)
	    {
	      long long lSize;
	      char szDVDAuthor_Befehl[8192];
	      strcpy (szDVDAuthor_Befehl, "");
	      for (vobNr = 1; vobNr <= 99; vobNr++)
		{
		  FILE *fp;
		  char szTemp[128];
                  char szInjectionFile[256];
		  long lAnzahlAudioTracks = 0;
		  long lAnzahlUntertitel = 0;
		  long lVideoEnthalten = 0;
		  char szAudioSprachen[256], szUntertitelSprachen[256];
		  sprintf (szTemp, "%s/vobinhalt.lxdvdrip", szTmpDir);
		  strcpy (szAudioSprachen, "");
		  strcpy (szUntertitelSprachen, "");
		  strcpy (szVideoAngaben, "");
		  sprintf (szFileName, "vob_%02d_%03dt.vob", titelNr, vobNr);	// <= dvdauthor 0.6.11
		  lSize = filesize64 (szFileName, szTmpDir);
		  if (lSize == 0)
		    {
		      sprintf (szFileName, "vob_%02dt_%03d.vob", titelNr, vobNr);	// >= dvdauthor 0.6.12
		      lSize = filesize64 (szFileName, szTmpDir);
		      if (lSize == 0)
			{
			  break;
			}
		    }
		  // Versuche, aus interner Datenstruktur Anzahl Audio und Untertitel zu bestimmen.
		  // Suche den x.ten Titleset, innerhalb des xt.ten Titelsets dann den entsprechenden Titel
		  for (j = 0; j < titles; j++)
		    {
		      if (dvdStruktur[j].titelSet == titelNr)
			{
			  // Alle Titel im Titleset sind gleich, daher Einstellung vom ersten nehmen
			  lAnzahlUntertitel = dvdStruktur[j].untertitelTracks;
			  lAnzahlAudioTracks = dvdStruktur[j].audioTracks;
			  if (vobNr == 1)	// Nur beim ersten Track die Optionen setzen
			    {
			      strcpy (szAudioSprachen,
				      dvdStruktur[j].szAudio);
			      strcpy (szUntertitelSprachen,
				      dvdStruktur[j].szUntertitel);
			      strcpy (szVideoAngaben,
				      dvdStruktur[j].szVideoAngaben);
			    }
			  lVideoEnthalten = 1;
			  break;
			}
		    }
		  // Inhalt der Datei mit tcprobe bestimmen, wenn intern nicht gefunden
		  if (!lVideoEnthalten)
		    {
		      sprintf (szBefehl, "%s %s -i %s -H 100 > %s 2>&1",
			       szNiceRip, tcprobe_name, szFileName, szTemp);
		      printf ("%s\n", szBefehl);
		      system (szBefehl);
		      fp = fopen (szTemp, "r");
		      while (fscanf (fp, "%s\n", szWort) != EOF)
			{
			  // Videospur enthalten ?
			  if (!lVideoEnthalten && strstr (szWort, "frame"))
			    {
			      fscanf (fp, "%s\n", szWort);
			      if (strstr (szWort, "rate:"))
				{
				  lVideoEnthalten = 1;
				}
			      continue;
			    }
			  // Anzahl Audiotracks
			  if (strstr (szWort, "audio"))
			    {
			      fscanf (fp, "%s\n", szWort);
			      if (strstr (szWort, "track:"))
				{
				  lAnzahlAudioTracks++;
				}
			      continue;
			    }
			  // Anzahl Untertitel
			  if (strstr (szWort, "detected"))
			    {
			      char szAnzahl[256];
			      fscanf (fp, "%s\n", szAnzahl);
			      fscanf (fp, "%s\n", szWort);
			      if (strstr (szWort, "subtitle(s)"))
				{
				  szAnzahl[0] = '0';
				  szAnzahl[strlen (szAnzahl) - 1] = 0;
				  lAnzahlUntertitel = atol (szAnzahl);
				}
			      continue;
			    }
			}
		      fclose (fp);
		      sprintf (szBefehl, "rm %s", szTemp);
		      system (szBefehl);
		    }
		  switch (lSprache)
		    {
		    case 0:
		      printf
			("Video: %ld, Audio-Tracks: %ld, Untertitel: %ld\n",
			 lVideoEnthalten, lAnzahlAudioTracks,
			 lAnzahlUntertitel);
		      break;
		    case 1:
		      printf
			("Video: %ld, Audio-Tracks: %ld, Subpictures: %ld\n",
			 lVideoEnthalten, lAnzahlAudioTracks,
			 lAnzahlUntertitel);
		      break;
		    case 2:
		      printf
			("Video: %ld, Pistes audio: %ld, Sous-Titres: %ld\n",
			 lVideoEnthalten, lAnzahlAudioTracks,
			 lAnzahlUntertitel);
		      break;
		    }
		  if (lTestlauf)
		    continue;	// kein vampsen beim Test
		  if (lVideoEnthalten)
		    {
		      // Verkleinern der Titel-VOBS per Vamps
		      if (dFaktor > 1)
			{
                          // Zielgroesse ermitteln
                          long long lZielGroesse=lSize;
			  // Datei verkleinern
			  // Zunaechst umkopieren
			  sprintf (szBefehl, "mv %s dummy.vob", szFileName);
			  printf ("%s\n", szBefehl);
			  system (szBefehl);
			  // vamps-Befehl zusammensetzen 
                          sprintf (szInjectionFile, "%s/vapinj.%d", szTmpDir, getpid());
           		  sprintf (szBefehl, "%s cat dummy.vob | %s -i %s -E %f -S %lld ",
				   szNiceRip, vamps_name, szInjectionFile, dFaktor, lZielGroesse);
			  // Audio
			  if (lAnzahlAudioTracks)
			    {
			      for (j = 1; j <= lAnzahlAudioTracks; j++)
				{
				  if (j == 1)
                                    // Parameter -p erhaelt die Track-IDs (preserve audio)
				    sprintf (szBefehl + strlen (szBefehl),
					     " -p -a %d", j);
				  else
				    sprintf (szBefehl + strlen (szBefehl),
					     ",%d", j);
				}
			    }
			  // Untertitel
			  if (lAnzahlUntertitel)
			    {
			      for (j = 1; j <= lAnzahlUntertitel; j++)
				{
				  if (j == 1)
                                    // Parameter -u erhaelt die Track-IDs (preserve subpictures)
				    sprintf (szBefehl + strlen (szBefehl),
					     " -u -s %d", j);
				  else
				    sprintf (szBefehl + strlen (szBefehl),
					     ",%d", j);
				}
			    }
			  sprintf (szBefehl + strlen (szBefehl), " > %s",
				   szFileName);
			  printf ("%s\n", szBefehl);
			  system (szBefehl);
			  // Temp-Datei loeschen
			  sprintf (szBefehl, "rm dummy.vob");
			  printf ("%s\n", szBefehl);
			  system (szBefehl);
	                  // Injection-File loeschen
     	                  sprintf (szBefehl, "rm %s", szInjectionFile);
	                  printf ("%s\n", szBefehl);
	                  system (szBefehl);
			}
		    }
		}
	    }
	  // XML-Datei umkopieren
	  sprintf (szBefehl, "mv dvdauthor.xml dummy.xml");
	  printf ("%s\n", szBefehl);
	  system (szBefehl);
	  // Neue XML-Datei anlegen
	  // added progress message to avoid confusing the user with the 
	  // impression that the dvdauthor 
	  // input xml file is removed before even invoking dvdauthor --JJ
	  switch (lSprache)
	    {
	    case 0:
	      printf ("Neue XML-Datei anlegen\n");
	      break;
	    case 1:
	      printf ("Writing new XML file\n");
	      break;
	    case 2:
	      printf ("Fournir nouveau XML Fichier\n");
	      break;
	    }
	  // Alle Menues Buttons etc. werden entfernt, da es eh nicht funktioniert
	  fp1 = fopen_warnung ("dvdauthor.xml", "w", lSprache);
	  fprintf (fp1, "<?xml version=\"1.0\"?>\n<dvdauthor>\n");
	  fp2 = fopen ("dummy.xml", "r");
	  strcpy (szVorherigesWort, "");
	  while (fscanf (fp2, "%s\n", szWort) != EOF)
	    {
	      if (strstr (szWort, "<titleset>"))
		fprintf (fp1, "<titleset>\n");
	      if (strstr (szWort, "<titles>"))	// Titelsektor beginnt
		{
		  long lFirstPGC = 0;	// fuer Palette
		  long lTagBegonnen = 0;	// Kennzeichen, ob Tag gestartet ist
		  fprintf (fp1, "<titles>\n");
		  while (fscanf (fp2, "%s\n", szWort) != EOF)
		    {
		      // Wenn noch kein <pgc> Block, dann pgc mit Palettefile erstellen
		      if (lFirstPGC == 0 && strstr (szWort, "<pgc>")
			  && lPaletteVorhanden)
			{
			  fprintf (fp1,
				   "<pgc palette=\"%s/palette.txt\">\n",
				   szTmpDir);
			  lFirstPGC = 1;
			  continue;
			}
		      if (strstr (szWort, "</titles>"))
			break;	// Titleset zu Ende
		      // Einige Tags werden aktuell von dvdauthor noch nicht verarbeitet
		      // und auch fuer eine Kopie ohne Menue nicht benoetigt
		      if ((strstr (szWort, "<audio")
			   || strstr (szWort, "<subpicture"))
			  && !(strstr (szWort, "<audio/>")
			       || strstr (szWort, "<subpicture/>")))
			{
			  char szNaechstesWort[512];
			  fscanf (fp2, "%s\n", szNaechstesWort);
			  if (strstr (szNaechstesWort, "present=") ||
			      strstr (szNaechstesWort, "id="))
			    continue;	// Tag ueberspringen
			  else
			    {
			      // zusammenhaengen und dann ausgeben
			      strcat (szWort, " ");
			      strcat (szWort, szNaechstesWort);
			    }
			}
		      if (strstr (szWort, "<pre>")
			  || strstr (szWort, "<post>"))
			{
			  for (;;)	// lesen, bis Tag zu Ende ist
			    {
			      fscanf (fp2, "%s\n", szWort);
			      if (strstr (szWort, "</pre>")
				  || strstr (szWort, "</post>"))
				break;
			    }
			  continue;	// Tag ueberspringen
			}
		      if (strstr (szWort, "<buttons"))
			{
			  for (;;)	// lesen, bis Tag zu Ende ist
			    {
			      fscanf (fp2, "%s\n", szWort);
			      if (strstr (szWort, "/buttons>"))
				break;
			    }
			  continue;	// Tag ueberspringen
			}
		      if (strstr (szWort, "interleave")
			  && strstr (szWort, "<"))
			{
			  continue;	// Tag ueberspringen
			}
		      if (strstr (szWort, "<with"))
			{
			  for (;;)	// lesen, bis Tag zu Ende ist
			    {
			      fscanf (fp2, "%s\n", szWort);
			      if (strstr (szWort, "/>"))
				break;
			    }
			  continue;	// Tag ueberspringen
			}
		      if (strstr (szWort, "content="))
			{
			  if (strstr (szWort, "/>"))
			    {
			      fprintf (fp1, "/>\n");
			      lTagBegonnen = 0;	// Tag zu Ende
			    }
			  continue;	// Tag ueberspringen
			}
		      if (strstr (szWort, "next=")
			  || strstr (szWort, "prev="))
			{
			  if (strstr (szWort, ">"))
			    {
			      fprintf (fp1, ">\n");
			      lTagBegonnen = 0;	// Tag zu Ende
			    }
			  continue;	// Tag ueberspringen
			}
		      if (strstr (szWort, "<"))
			{
			  lTagBegonnen = 1;	// Tag beginnt
			}
		      // Wort ignorieren, wenn kein Tag-Beginn-Zeichen und kein Tag in Arbeit
		      if (!strstr (szWort, "<") && !lTagBegonnen)
			{
			  continue;
			}
		      if (strstr (szWort, "widescreen")
			  && strstr (szWort, ">")
			  && (strstr (szWort, "nopanscan")
			      || strstr (szWort, "noletterbox"))
			  && !strstr (szVorherigesWort, "aspect"))
			{
			  fprintf (fp1, " aspect=\"16:9\"");
			}
		      fprintf (fp1, " %s", szWort);
		      strcpy (szVorherigesWort, szWort);
		      if (strstr (szWort, ">"))
			{
			  fprintf (fp1, "\n");	// Zeile zu Ende
			  lTagBegonnen = 0;	// Tag zu Ende
			}
		    }
		  fprintf (fp1, "</titles>\n");
		  fprintf (fp1, "</titleset>\n");
		}
	    }
	  fprintf (fp1, "</dvdauthor>");
	  fclose (fp1);
	  fclose (fp2);
	  // XML-Datei bearbeiten
	  sprintf (szBefehl, "%s %s -o %s -x dvdauthor.xml",
		   szNiceRip, dvdauthor_name, szFilmVerzeichnis);
	  printf ("%s\n", szBefehl);
	  system (szBefehl);
	  // IFOs erzeugen
	  sprintf (szBefehl, "%s %s -T -o %s", szNiceRip, dvdauthor_name,
		   szFilmVerzeichnis);
	  printf ("%s\n", szBefehl);
	  system (szBefehl);
	  // Zuletzt alle ueberfluessigen Dateien loeschen
	  // added a check for the delete flag --JJ
	  if (lLoeschen > 0)
	    {
	      sprintf (szBefehl, "rm vob_*.vob");
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      sprintf (szBefehl, "rm dvdauthor.xml");
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      sprintf (szBefehl, "rm dummy.xml");
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	    }
        }
    }

  // Einzelne Titel kopieren
  // lxdvdrip -st=partcopy
  if (lPackMethode == 6)
    {
      int titelNr, vobNr;
      char szFileName[256];
      long lAnzTitel = 0;
      long lBrennen = 0;
      char szAktion[32];
      long lAusgewaehlt = 0;
      long long lGroesseGewaehlt;
      char *szDVDWizardBefehl;
      long lTitelNr;
      char szInjectionFile[256];
      // Inhalt der DVD speichern in Struktur/Array
      typedef struct _inhalt
      {
	long lTitelSet;
	long lNr;
	char szFileName[256];
	long lKopieren;
	long long lGroesse;
	long lAnzahlUntertitel;
	long lAnzahlAudioTracks;
	char szChapterString[1024];
	char szAudio[256];
	char szUntertitel[256];
	char szVideoAngaben[128];
	char szTitelVideo[128];
	long lAnzahlKapitel;
	char szLaufzeit[256];
	char szTitelName[256];
      } inhalt;
      inhalt inhaltDVD[200];
      // Test, ob Datei im Rip-Verzeichnis vorhanden
      checkLastRip (szFilmVerzeichnis, lSprache);
      check_program (dvdauthor_name, lSprache, 1);
      check_program (dvdunauthor_name, lSprache, 1);
      check_program (vamps_name, lSprache, 1);
      check_program (tcprobe_name, lSprache, 1);
      if (lDVDWizard)
	check_program (dvdwizard_name, lSprache, 1);
      // Auslesen der DVD mit dvdunauthor
      switch (lSprache)
	{
	case 0:
	  printf ("\nBitte warten, die DVD wird vollstaendig ausgelesen!\n");
	  break;
	case 1:
	  printf ("\nPlease wait, the DVD must be copied to Harddisc!\n\n");
	  break;
	case 2:
	  printf
	    ("\nVeuillez patienter pendant la lecture du DVD sur le disque dur...\n\n");
	  break;
	}
      sprintf (szBefehl, "%s %s %s", szNiceRip, dvdunauthor_name, dvd_device);
      printf ("%s\n", szBefehl);
      if (!lTestlauf)
	{
	  system (szBefehl);	// dvdunauthor nur Normallauf, nicht bei Test
	  sleep (10);
	}
      // Analyse mit tcprobe
      switch (lSprache)
	{
	case 0:
	  printf ("\nBitte warten, die Titeldateien werden analysiert!\n");
	  break;
	case 1:
	  printf ("\nPlease wait, the Titlefiles will be analysed!\n\n");
	  break;
	case 2:
	  printf ("\nVeuillez patienter pendant l'analyse des titres!\n\n");
	  break;
	}
      // Alle Titeldateien in ein Array kopieren mit vollstaendigen Angaben
      for (titelNr = 1; titelNr <= 99; titelNr++)
	{
	  long long lSize;
	  for (vobNr = 1; vobNr <= 99; vobNr++)
	    {
	      char szTemp[128];
	      char szWort[256];
	      FILE *fp;
	      long lGefunden = 0;
	      sprintf (szTemp, "%s/vobinhalt.lxdvdrip", szTmpDir);
	      sprintf (szFileName, "vob_%02d_%03dt.vob", titelNr, vobNr);	// dvdauthor bis 0.6.11
	      lSize = filesize64 (szFileName, szTmpDir);
	      if (lSize == 0)
		{
		  sprintf (szFileName, "vob_%02dt_%03d.vob", titelNr, vobNr);	// ab 0.6.12
		  lSize = filesize64 (szFileName, szTmpDir);
		  if (lSize == 0)
		    {
		      break;
		    }
		}
	      // Inhalt bestimmen.
	      // Verwende die internen Datenstrukturen.
	      // Suche den x.ten Titleset, innerhalb des xt.ten Titelsets dann den entsprechenden Titel
	      for (j = 0; j < titles; j++)
		{
		  if (dvdStruktur[j].titelSet == titelNr)
		    {
		      // Alle Titel im Titleset sind gleich, daher Einstellung vom ersten nehmen
		      inhaltDVD[lAnzTitel].lAnzahlUntertitel =
			dvdStruktur[j].untertitelTracks;
		      inhaltDVD[lAnzTitel].lAnzahlAudioTracks =
			dvdStruktur[j].audioTracks;
		      strcpy (inhaltDVD[lAnzTitel].szAudio,
			      dvdStruktur[j].szAudio);
		      strcpy (inhaltDVD[lAnzTitel].szUntertitel,
			      dvdStruktur[j].szUntertitel);
		      strcpy (inhaltDVD[lAnzTitel].szVideoAngaben,
			      dvdStruktur[j].szVideoAngaben);
		      strcpy (inhaltDVD[lAnzTitel].szTitelVideo,
			      dvdStruktur[j].szTitelVideo);
		      lGefunden = 1;
		      break;
		    }
		}
	      // Groesse bestimmen
	      strcpy (inhaltDVD[lAnzTitel].szLaufzeit, "");
	      sprintf (szBefehl, "%s %s -i %s > %s 2>&1", 
                       szNiceRip, mpgtx_name, szFileName,
		       szTemp);
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      fp = fopen (szTemp, "r");
	      if (fp)
		{
		  while (fscanf (fp, "%s\n", szWort) != EOF)
		    {
		      if (strcmp (szWort, "Duration:") == 0)	// Stelle Laenge gefunden, naechstes Wort ist die Laenge
			{
			  fscanf (fp, "%s\n",
				  inhaltDVD[lAnzTitel].szLaufzeit);
			  break;
			}
		    }
		  fclose (fp);
		  sprintf (szBefehl, "rm %s", szTemp);
		  system (szBefehl);
		}
	      // Nicht gefunden, versuche tcprobe
	      if (!lGefunden)
		{
		  // Inhalt der Datei mit tcprobe bestimmen
		  inhaltDVD[lAnzTitel].lAnzahlUntertitel = 0;
		  inhaltDVD[lAnzTitel].lAnzahlAudioTracks = 0;
		  strcpy (inhaltDVD[lAnzTitel].szAudio, "");
		  strcpy (inhaltDVD[lAnzTitel].szUntertitel, "");
		  strcpy (inhaltDVD[lAnzTitel].szVideoAngaben, "");
		  sprintf (szBefehl, "%s %s -i %s -H 100 > %s 2>&1",
			   szNiceRip, tcprobe_name, szFileName, szTemp);
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		  fp = fopen (szTemp, "r");
		  while (fscanf (fp, "%s\n", szWort) != EOF)
		    {
		      // Anzahl Audiotracks
		      if (strstr (szWort, "audio"))
			{
			  fscanf (fp, "%s\n", szWort);
			  if (strstr (szWort, "track:"))
			    {
			      inhaltDVD[lAnzTitel].lAnzahlAudioTracks++;
			    }
			  continue;
			}
		      // Anzahl Untertitel
		      if (strstr (szWort, "detected"))
			{
			  char szAnzahl[256];
			  fscanf (fp, "%s\n", szAnzahl);
			  fscanf (fp, "%s\n", szWort);
			  if (strstr (szWort, "subtitle(s)"))
			    {
			      szAnzahl[0] = '0';
			      szAnzahl[strlen (szAnzahl) - 1] = 0;
			      inhaltDVD[lAnzTitel].lAnzahlUntertitel =
				atol (szAnzahl);
			    }
			  continue;
			}
		    }
		  fclose (fp);
		  sprintf (szBefehl, "rm %s", szTemp);
		  system (szBefehl);
		}
	      // Kapitel auslesen
	      strcpy (inhaltDVD[lAnzTitel].szChapterString, "");
	      inhaltDVD[lAnzTitel].lAnzahlKapitel = 1;
	      if (lMitKapiteln)
		{
		  fp = fopen ("dvdauthor.xml", "r");
		  if (fp)
		    {
		      while (fscanf (fp, "%s\n", szWort) != EOF)
			{
			  // Eventuell doppelt (Titleset aus mehreren Titeln)
			  if (strlen (inhaltDVD[lAnzTitel].szChapterString)
			      && strstr (szWort, "</pgc>"))
			    break;
			  // Suche alle Stellen mit dem Dateinamen
			  if (strstr (szWort, szFileName) ||	// ist enthalten!
			      (strlen (inhaltDVD[lAnzTitel].szChapterString)
			       && strstr (szWort, "<cell")))
			    {
			      char szNextWort[128];
			      // Naechste Wort ist "<cell" => ueberlesen
			      if (!strstr (szWort, "<cell"))
				fscanf (fp, "%s\n", szWort);
			      // Und dann kommt die Zeit "start="...."
			      fscanf (fp, "%s\n", szWort);
			      strncpy (szWort, &szWort[7], 11);
			      szWort[11] = 0;
			      // Lies naechstes Wort
			      fscanf (fp, "%s\n", szNextWort);
			      if (!strstr (szNextWort, "chapter=\"1"))	// Ist noch kein Kapitel
				{
				  if (strstr (szNextWort, ">"))	// Zeile zu Ende, kein Kapitel
				    continue;
				  fscanf (fp, "%s\n", szNextWort);
				  // Wenn das folgende Wort nicht chapter enthaelt, ist es nur eine Zelle
				  if (!strstr (szNextWort, "chapter=\"1"))
				    continue;
				}
			      // Anhaengen
			      if (!strlen
				  (inhaltDVD[lAnzTitel].szChapterString))
				sprintf (inhaltDVD[lAnzTitel].szChapterString,
					 "-c %s", szWort);
			      else
				{
				  sprintf (inhaltDVD[lAnzTitel].
					   szChapterString +
					   strlen (inhaltDVD[lAnzTitel].
						   szChapterString), ",%s",
					   szWort);
				  inhaltDVD[lAnzTitel].lAnzahlKapitel++;
				}
			    }
			}
		      fclose (fp);
		    }
		}
	      if (lTestlauf)
		printf ("%ld: Kapitel %ld, %s\n", lAnzTitel,
			inhaltDVD[lAnzTitel].lAnzahlKapitel,
			inhaltDVD[lAnzTitel].szChapterString);
	      // Daten zum Titel speichern
	      inhaltDVD[lAnzTitel].lTitelSet = titelNr;
	      inhaltDVD[lAnzTitel].lNr = titelNr;
	      inhaltDVD[lAnzTitel].lGroesse = lSize;
	      inhaltDVD[lAnzTitel].lKopieren = 0;
	      // Copymodus mit dvdwizard => umschalten auf partcopy und alles markieren
	      if (lPartcopyAllesMarkieren > 0)
		inhaltDVD[lAnzTitel].lKopieren = 1;
	      strcpy (inhaltDVD[lAnzTitel].szFileName, szFileName);
	      // Titelname auf Default setzen, wird spaeter fuer dvdwizard gebraucht
	      switch (lSprache)
		{
		case 0:
		  sprintf (inhaltDVD[lAnzTitel].szTitelName, "Titel_%ld",
			   lAnzTitel + 1);
		  break;
		case 1:
		  sprintf (inhaltDVD[lAnzTitel].szTitelName, "Title_%ld",
			   lAnzTitel + 1);
		  break;
		case 2:
		  sprintf (inhaltDVD[lAnzTitel].szTitelName, "Titre_%ld",
			   lAnzTitel + 1);
		  break;
		}
	      lAnzTitel++;
	    }
	}
      // Ueberhaupt Titel vorhanden ?
      if (!lAnzTitel)
	{
	  switch (lSprache)
	    {
	    case 0:
	      printf ("\n\nDie DVD enthaelt keine Titel!\n\n");
	      break;
	    case 1:
	      printf ("\n\nThis DVD contains no Titles!\n\n");
	      break;
	    case 2:
	      printf ("\n\nCe DVD ne contient aucun titre!\n\n");
	      break;
	    }
	  return 0;
	}
      // dvdwizard kann maximal 9 Titel
      if (lAnzTitel > 9 && lDVDWizard)
	{
	  switch (lSprache)
	    {
	    case 0:
	      printf ("\nMax. 9 Titel mit dvdwizard!\n");
	      break;
	    case 1:
	      printf ("\nMax. 9 Titles with dvdwizard!\n");
	      break;
	    case 2:
	      printf ("\nMax. 9 Titres avec dvdwizard!\n");
	      break;
	    }
	}
      // Auswaehlen, Preview, Brennen starten
      while (!lBrennen)
	{
	  int i;
	  switch (lSprache)
	    {
	    case 0:
	      printf ("\nInhalt der DVD:\n\n");
	      break;
	    case 1:
	      printf ("\nTitles of DVD:\n\n");
	      break;
	    case 2:
	      printf ("\nTitres sur ce DVD:\n\n");
	      break;
	    }
	  for (i = 0; i < lAnzTitel; i++)
	    {
	      char szBrennen = ' ';
	      if (inhaltDVD[i].lKopieren > 0)
		szBrennen = '*';
	      switch (lSprache)
		{
		case 0:
		  printf
		    ("%c Nr: %d, Groesse: %lld, Audio/Untertitel/Kapitel: %ld/%ld/%ld %s\n",
		     szBrennen, i + 1, inhaltDVD[i].lGroesse,
		     inhaltDVD[i].lAnzahlAudioTracks,
		     inhaltDVD[i].lAnzahlUntertitel,
		     inhaltDVD[i].lAnzahlKapitel, inhaltDVD[i].szLaufzeit);
		  break;
		case 1:
		  printf
		    ("%c Nr: %d, Size: %lld, Audio/Subtitle/Chapter: %ld/%ld/%ld %s\n",
		     szBrennen, i + 1, inhaltDVD[i].lGroesse,
		     inhaltDVD[i].lAnzahlAudioTracks,
		     inhaltDVD[i].lAnzahlUntertitel,
		     inhaltDVD[i].lAnzahlKapitel, inhaltDVD[i].szLaufzeit);
		  break;
		case 2:
		  printf
		    ("%c Num: %d, Taille: %lld, Audio/Sous-Titres/Chapitres: %ld/%ld/%ld %s\n",
		     szBrennen, i + 1, inhaltDVD[i].lGroesse,
		     inhaltDVD[i].lAnzahlAudioTracks,
		     inhaltDVD[i].lAnzahlUntertitel,
		     inhaltDVD[i].lAnzahlKapitel, inhaltDVD[i].szLaufzeit);
		  break;
		}
	      if (lDVDWizard)	// bei dvdwizard den Titel anzeigen
		{
		  switch (lSprache)
		    {
		    case 0:
		      printf ("   Titel: %s\n", inhaltDVD[i].szTitelName);
		      break;
		    case 1:
		      printf ("   Title: %s\n", inhaltDVD[i].szTitelName);
		      break;
		    case 2:
		      printf ("   Titre: %s\n", inhaltDVD[i].szTitelName);
		      break;
		    }
		}
	    }
	  switch (lSprache)
	    {
	    case 0:
	      printf ("\n");
	      printf ("Titel waehlen: 't'+Nr., z. B. 't1' waehlt Nr. 1\n");
	      printf ("               'ta': Alle Titel\n");
	      if (lDVDWizard)	// Titel editieren
		{
		  printf
		    ("Name editieren: 'ne'+Nr.+'-'+Name, z. B. 'ne1-XYZ' setzt Name des ersten Titels auf 'XYZ'\n");
		}
	      printf ("Vorschau: 'v'+Nr., z. B. 'v1' spielt Nr. 1 an\n");
	      printf ("Brennen: 'b'\n");
	      printf ("\nEingabe: \n");
	      break;
	    case 1:
	      printf ("\n");
	      printf ("Select Title: 't'+No., i. E. 't1' selects No. 1\n");
	      printf ("               'ta': All Titles\n");
	      if (lDVDWizard)	// Titel editieren
		{
		  printf
		    ("Edit Name: 'ne'+Nr.+'-'+Name, i. E. 'ne1-XYZ' set Name of first Title to 'XYZ'\n");
		}
	      printf ("Preview: 'p'+No., i. E. 'p1' plays No. 1\n");
	      printf ("Burn: 'b'\n");
	      printf ("\nInput: \n");
	      break;
	    case 2:
	      printf ("\n");
	      printf ("Choix titre: 't'+No, p.ex. 't1' choisit le N° 1\n");
	      printf ("               'tt': Toutes Titres\n");
	      if (lDVDWizard)	// Titel editieren
		{
		  printf
		    ("éditer Nom: 'ne'+No+'-'+Nom, p.ex. 'ne1-XYZ' remplace Nom de 1. titre 'XYZ'\n");
		}
	      printf ("Prévisu: 'p'+No, p.ex. 'p1' montre le N° 1\n");
	      printf ("Graver: 'b'\n");
	      printf ("\nSaisie: \n");
	      break;
	    }
	  // Titel auswaehlen
	  scanf ("%31s", szAktion);
	  eatToNL (stdin);
	  if (szAktion[0] == 'b' || szAktion[0] == 'B')	// Auswahl beenden, Brennen
	    {
	      lBrennen = 1;
	      break;
	    }
	  if (strncmp (szAktion, "ne", 2) == 0)	// Namen editieren
	    {
	      char szNummer[128];
	      szNummer[0] = szAktion[2];	// Max 2 Stellen
	      if (szAktion[3] >= '0' && szAktion[3] <= '9')
		{
		  szNummer[1] = szAktion[3];
		  szNummer[2] = 0;
		  strcpy (inhaltDVD[atol (szNummer) - 1].szTitelName,
			  &szAktion[5]);
		}
	      else
		{
		  szNummer[2] = 0;
		  strcpy (inhaltDVD[atol (szNummer) - 1].szTitelName,
			  &szAktion[4]);
		}
	      continue;
	    }
	  if (strncmp (szAktion, "tt", 2) == 0 || strncmp (szAktion, "ta", 2) == 0)	// Alle Titel markieren
	    {
	      for (i = 0; i < lAnzTitel; i++)
		{
		  inhaltDVD[i].lKopieren = 1;
		}
	      continue;
	    }
	  if (szAktion[0] == 't' || szAktion[0] == 'T')	// Titel (ab)waehlen
	    {
	      long lNr = atol (&szAktion[1]) - 1;
	      if (inhaltDVD[lNr].lKopieren > 0)
		inhaltDVD[lNr].lKopieren = 0;
	      else
		inhaltDVD[lNr].lKopieren = 1;
	      continue;
	    }
	  if (szAktion[0] == 'v' || szAktion[0] == 'V' || szAktion[0] == 'p' || szAktion[0] == 'P')	// Vorschau
	    {
	      long lNr = atol (&szAktion[1]) - 1;
	      if (!strlen (szVOBPlayer))
		strcpy (szVOBPlayer, "mplayer");
	      sprintf (szBefehl, "%s %s %s", szVOBPlayer, szPreviewParam,
		       inhaltDVD[lNr].szFileName);
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	      continue;
	    }
	}
      // Wieviele Titel ausgewaehlt ?
      // Ausserdem die Gesamtgroesse bestimmen
      lGroesseGewaehlt = 0;
      for (i = 0; i < lAnzTitel; i++)
	{
	  if (inhaltDVD[i].lKopieren == 1)
	    {
	      lAusgewaehlt++;
	      lGroesseGewaehlt += inhaltDVD[i].lGroesse;
	    }
	  else
	    {
	      // Ueberfluessiges loeschen, schafft Platz
	      sprintf (szBefehl, "rm %s", inhaltDVD[i].szFileName);
	      printf ("%s\n", szBefehl);
	      system (szBefehl);
	    }
	}
      // Auswahl ist Pflicht, sonst Abbruch
      if (!lAusgewaehlt)
	{
	  switch (lSprache)
	    {
	    case 0:
	      printf ("\n\nKeine Titel ausgewaehlt!\n");
	      break;
	    case 1:
	      printf ("\n\nNo Title selected!\n");
	      break;
	    case 2:
	      printf ("\n\nAucun titre choisi!\n");
	      break;
	    }
	  return 0;
	}
      // dvdwizard kann maximal 9 Titel
      if (lAusgewaehlt > 9 && lDVDWizard)
	{
	  switch (lSprache)
	    {
	    case 0:
	      printf ("\nMax. 9 Titel mit dvdwizard!\n");
	      break;
	    case 1:
	      printf ("\nMax. 9 Titles with dvdwizard!\n");
	      break;
	    case 2:
	      printf ("\nMax. 9 Titres avec dvdwizard!\n");
	      break;
	    }
	  return 0;
	}
      // Statusanzeige
      if (dFaktor <= 0)		// Nicht umsetzen, wenn von aussen gesetzt
	{
	  dFaktor = (double) lGroesseGewaehlt / (double) lGroesseDVDBytes;
	}
      // Bei dvdwizard etwas Reserve wegen der Kapitel
      if (lDVDWizard)
	dFaktor = dFaktor + (dFaktor / 100.00);
      if (dFaktor < 1)
	dFaktor = 1;
      // Faktor auf Basis 4.6 GB berechnen, etwas Reserve
      switch (lSprache)
	{
	case 0:
	  {
	    printf ("Groesse Titelsets: %lld Bytes\n", lGroesseGewaehlt);
	    printf ("Faktor fuer vamps: %f\n", dFaktor);
	    break;
	  }
	case 1:
	  {
	    printf ("Title-sets: %lld Bytes\n", lGroesseGewaehlt);
	    printf ("Factor for vamps: %f\n", dFaktor);
	    break;
	  }
	case 2:
	  {
	    printf ("Taille des titres : %lld Octets\n", lGroesseGewaehlt);
	    printf ("Facteur pour vamps: %f\n", dFaktor);
	    break;
	  }
	}
      // Beginn des dvdwizards-Befehl
      if (lDVDWizard)
	{
	  // dynamisch erzeugen und Befehl zusammensetzen
	  szDVDWizardBefehl = (char *) malloc (32000);
	  // Name von aussen setzbar
	  if (strlen (szDVDNameOverwrite))
	    strcpy (szDVDName, szDVDNameOverwrite);
	  if (strlen (szDVDName) > 24)
	    szDVDName[24] = 0;
	  // Basisbefehl, Titel werden einzeln angehaengt  
	  sprintf (szDVDWizardBefehl, "%s %s -o %s -T %s --audio-seq -P %s %s ",
		   szNiceRip, dvdwizard_name, szFilmVerzeichnis, szDVDName,
		   szPaletteFile, dvdStruktur[0].szVideoDVDWizard);
	}
      // Die ausgewaehlten Dateien vampsen und in DVD-Struktur bringen
      lTitelNr = 0;
      for (i = 0; i < lAnzTitel; i++)
	{
	  if (inhaltDVD[i].lKopieren == 1)
	    {
	      if (lDVDWizard)	// dvdwizard einsetzen
		{
		  char szTitelName[18];
		  char szBildOption[128];
		  // Datei verkleinern ?
		  if (dFaktor > 1)
		    {
                      // Zielgroesse ermitteln
                      long long lZielGroesse = filesize64(inhaltDVD[i].szFileName, szTmpDir);
		      // Datei kopieren
		      sprintf (szBefehl, "mv %s %s/dummy.vob",
			       inhaltDVD[i].szFileName, szTmpDir);
		      printf ("%s\n", szBefehl);
		      system (szBefehl);
		      // vamps-Befehl zusammensetzen
                      sprintf (szInjectionFile, "%s/vapinj.%d", szTmpDir, getpid());
		      sprintf (szBefehl, "%s cat %s/dummy.vob | %s -i %s -E %f -S %lld ",
			       szNiceRip, szTmpDir, vamps_name, szInjectionFile, dFaktor, lZielGroesse);
		      // Audio
		      if (inhaltDVD[i].lAnzahlAudioTracks)
			{
			  for (j = 1; j <= inhaltDVD[i].lAnzahlAudioTracks;
			       j++)
			    {
			      if (j == 1)
				// Parameter -p erhaelt die Track-IDs (preserve audio)
				sprintf (szBefehl + strlen (szBefehl),
					 " -p -a %d", j);
			      else
				sprintf (szBefehl + strlen (szBefehl), ",%d",
					 j);
			    }
			}
		      // Untertitel
		      if (inhaltDVD[i].lAnzahlUntertitel)
			{
			  for (j = 1; j <= inhaltDVD[i].lAnzahlUntertitel;
			       j++)
			    {
			      if (j == 1)
				// Parameter -u erhaelt die Track-IDs (preserve subpictures)
				sprintf (szBefehl + strlen (szBefehl),
					 " -u -s %d", j);
			      else
				sprintf (szBefehl + strlen (szBefehl), ",%d",
					 j);
			    }
			}
		      sprintf (szBefehl + strlen (szBefehl), " > %s",
			       inhaltDVD[i].szFileName);
		      printf ("%s\n", szBefehl);
		      system (szBefehl);
		      sprintf (szBefehl, "rm %s/dummy.vob", szTmpDir);
		      printf ("%s\n", szBefehl);
		      system (szBefehl);
                      // Injection-File loeschen
     	              sprintf (szBefehl, "rm %s", szInjectionFile);
	              printf ("%s\n", szBefehl);
	              system (szBefehl);
		    }
		  // Name des Titlesets bilden
		  lTitelNr++;
		  // Titelname uebernehmen
		  sprintf (szTitelName, "'%s'", inhaltDVD[i].szTitelName);
		  strcpy (szBildOption, "");
		  if (strlen (dvdwizard_bild))
		    {
		      sprintf (szBildOption, " -b %s ", dvdwizard_bild);
		    }
		  // Mehr als ein Kapitel ? Wenn nur das Startkapitel, dann leeren.
		  // Das Leerzeichen ist ein Komma, daher nur ein Kapitel, wenn kein Komma.
		  if (!strstr (inhaltDVD[i].szChapterString, ","))
		    strcpy (inhaltDVD[i].szChapterString, "");
		  // Titel anhaengen
		  sprintf (szDVDWizardBefehl + strlen (szDVDWizardBefehl),
			   " -t %s %s %s %s %s %s %s ",
			   szTitelName, inhaltDVD[i].szChapterString,
			   inhaltDVD[i].szAudio, inhaltDVD[i].szUntertitel,
			   szBildOption, inhaltDVD[i].szTitelVideo,
			   inhaltDVD[i].szFileName);
		}
	      else		// normales partcopy direkt ueber dvdauthor  
		{
		  // Verkleinern in dvdauthor eingebettet
		  if (dFaktor > 1)
		    {
                      // Zielgroesse ermitteln
                      long long lZielGroesse = filesize64(inhaltDVD[i].szFileName, szTmpDir);
                      sprintf (szInjectionFile, "%s/vapinj.%d", szTmpDir, getpid());
		      sprintf (szBefehl,
			       "%s %s -t %s %s %s %s -p %s -o %s -f 'cat %s | %s -i %s -E %f -S %lld ",
			       szNiceRip, dvdauthor_name, inhaltDVD[i].szChapterString,
			       inhaltDVD[i].szAudio,
			       inhaltDVD[i].szUntertitel,
			       inhaltDVD[i].szVideoAngaben, szPaletteFile,
			       szFilmVerzeichnis, inhaltDVD[i].szFileName,
			       vamps_name, szInjectionFile, dFaktor, lZielGroesse);
		      // Audio
		      if (inhaltDVD[i].lAnzahlAudioTracks)
			{
			  for (j = 1; j <= inhaltDVD[i].lAnzahlAudioTracks;
			       j++)
			    {
			      if (j == 1)
				// Parameter -p erhaelt die Track-IDs (preserve audio)
				sprintf (szBefehl + strlen (szBefehl),
					 " -p -a %d", j);
			      else
				sprintf (szBefehl + strlen (szBefehl), ",%d",
					 j);
			    }
			}
		      // Untertitel
		      if (inhaltDVD[i].lAnzahlUntertitel)
			{
			  for (j = 1; j <= inhaltDVD[i].lAnzahlUntertitel;
			       j++)
			    {
			      if (j == 1)
				// Parameter -u erhaelt die Track-IDs (preserve subpictures)
				sprintf (szBefehl + strlen (szBefehl),
					 " -u -s %d", j);
			      else
				sprintf (szBefehl + strlen (szBefehl), ",%d",
					 j);
			    }
			}
		      sprintf (szBefehl + strlen (szBefehl), " |'");
		    }
		  else
		    {
		      // Faktor <= 1, vamps nicht noetig
		      sprintf (szBefehl, "%s %s -t %s %s %s %s -p %s -o %s %s",
			       szNiceRip, dvdauthor_name, inhaltDVD[i].szChapterString,
			       inhaltDVD[i].szAudio,
			       inhaltDVD[i].szUntertitel,
			       inhaltDVD[i].szVideoAngaben, szPaletteFile,
			       szFilmVerzeichnis, inhaltDVD[i].szFileName);
		    }
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		  // Datei jetzt loeschen, schafft Platz
		  sprintf (szBefehl, "rm %s", inhaltDVD[i].szFileName);
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
                  // Injection-File loeschen
                  if (dFaktor > 1)
                  {
   	            sprintf (szBefehl, "rm %s", szInjectionFile);
	            printf ("%s\n", szBefehl);
	            system (szBefehl);
                  }
		}
	    }
	}
      if (lDVDWizard)		// Struktur ueber dvdwizard erstellen
	{
	  // dvdwizard ausfuehren
	  long lRC;
	  printf ("%s\n", szDVDWizardBefehl);
	  lRC = system (szDVDWizardBefehl);
	  free (szDVDWizardBefehl);
	  if (lRC == 0)		// Logfile nur bei Erfolg loeschen
	    {
	      system ("rm dvdwizard.log");
	    }
	  // Restliche Dateien vom dvdwizard entsorgen
	  system ("rm dvdwizard.cmd");
	  system ("rm dvdwizard.xml");
	  for (i = 0; i < lTitelNr; i++)
	    {
	      sprintf (szBefehl, "rm cpics/VTS%d/chapter*jpg > /dev/null",
		       i + 1);
	      system (szBefehl);
	      sprintf (szBefehl, "rmdir cpics/VTS%d > /dev/null", i + 1);
	      system (szBefehl);
	    }
	  system ("rmdir cpics");
	  system ("rm vtsm/vtsm*mpg");
	  system ("rmdir vtsm");
	  // Dateien loeschen  
	  for (i = 0; i < lAnzTitel; i++)
	    {
	      if (inhaltDVD[i].lKopieren == 1)
		{
		  sprintf (szBefehl, "rm %s", inhaltDVD[i].szFileName);
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		}
	    }
	}
      else
	{
	  // IFOs erzeugen
	  sprintf (szBefehl, "%s %s -T -o %s", szNiceRip, dvdauthor_name,
		   szFilmVerzeichnis);
	  printf ("%s\n", szBefehl);
	  system (szBefehl);
	}
      // Zuletzt alle ueberfluessigen Dateien loeschen
      sprintf (szBefehl, "rm vob_*.vob");
      printf ("%s\n", szBefehl);
      system (szBefehl);
      sprintf (szBefehl, "rm dvdauthor.xml");
      printf ("%s\n", szBefehl);
      system (szBefehl);
    }

  // DVD auswerfen ?
  if (lEject)
    {
      sprintf (szBefehl, "%s %s", eject_name, dvd_device);
      printf ("%s\n", szBefehl);
      system (szBefehl);
    }

  // Inhalt anzeigen
  switch (lSprache)
    {
    case 0:
      printf ("\nFolgende Dateien befinden sich im Video-Verzeichnis:\n");
      break;
    case 1:
      printf ("\nFiles in Video-Directory:\n");
      break;
    case 2:
      printf ("\nFichiers dans le répertoire video :\n");
      break;
    }

  sprintf (szBefehl, "ls -C -s -h %s/%s/*", szFilmVerzeichnis, szVideoTS);
  printf ("%s\n", szBefehl);
  system (szBefehl);

  if (calculate_filesize (szFilmVerzeichnis, szVideoTS, szVobTS, szVtsTS) >=
      lGroesseDVDBytesMaximal)
    {
      switch (lSprache)
	{
	case 0:
	  printf
	    ("\nWarnung, Gesamtgroesse aller VOB-Files eventuell zu gross! Bitte kontrollieren!\n\n");
	  break;
	case 1:
	  printf
	    ("\nWarning, total size of all VOB-files possibly too big! Please check!\n\n");
	  break;
	case 2:
	  printf
	    ("\nAttention, la taille totale des fichiers VOB semble trop grande ! Vérifiez !\n\n");
	  break;
	}
    }

  if (lPlaySound > 0)
    play_sound_if_ready (lxdvdrip_wav_name);

  // VOBS per Mplayer anzeigen zur Kontrolle
  if (strlen (szVOBPlayer) && !strstr (szVOBPlayer, "off"))
    {
      char cMplayer;
      long lMaxTitel = 1;
      int anzTitel;
      // Bestimme die maximale Titel-Nr
      if (lPackMethode < 5 && !lMenues)	// nicht im Kopiermodus
	{
	  for (anzTitel = 99; anzTitel > 0; anzTitel--)
	    {
	      char szVOB[1024];
	      FILE *fTmp = NULL;
	      sprintf (szVOB, "%s/VIDEO_TS/VTS_%02d_1.VOB", szFilmVerzeichnis,
		       anzTitel);
	      fTmp = fopen (szVOB, "r");
	      if (fTmp != NULL)
		{
		  lMaxTitel = anzTitel;
		  break;
		}
	    }
	}
      // Bei Menuekopie der gewaehlte Titel
      if (lMenues > 0)
      {
        lMaxTitel = opt_t; 
      }
      switch (lSprache)
	{
	case 0:
	  printf
	    ("\n\nStart Anzeige per %s, bitte Enter druecken (C=Cancel):\n",
	     szVOBPlayer);
	  break;
	case 1:
	  printf
	    ("\n\nTo start preview with %s, please press Enter (C=Cancel):\n",
	     szVOBPlayer);
	  break;
	case 2:
	  printf
	    ("\n\nPour prévisualiser par %s, appuyez sur Entrée (C=Continuer sans prévisu):\n",
	     szVOBPlayer);
	  break;
	}
      scanf ("%1c", &cMplayer);
      if (cMplayer != 'c')
	{
	  check_program (szVOBPlayer, lSprache, 1);
	  if (strstr (szVOBPlayer, "mplayer"))
	    {
	      sprintf (szBefehl, "%s %s -dvd-device %s dvd://%ld",
		       szVOBPlayer, szPreviewParam, szFilmVerzeichnis,
		       lMaxTitel);
	    }
	  else if (strstr (szVOBPlayer, "ogle"))
	    {
	      sprintf (szBefehl, "%s %s %s", szVOBPlayer, szPreviewParam,
		       szFilmVerzeichnis);
	    }
	  else if (strstr (szVOBPlayer, "xine") || 
                   strstr (szVOBPlayer, "kaffeine") || 
                   strstr (szVOBPlayer, "totem"))
	    {
	      sprintf (szBefehl, "%s %s dvd:%s/", szVOBPlayer, szPreviewParam,
		       szFilmVerzeichnis);
	    }
	  else if (strstr (szVOBPlayer, "vlc"))
	    {
	      sprintf (szBefehl, "%s %s dvd://%s", szVOBPlayer,
		       szPreviewParam, szFilmVerzeichnis);
	    }
	  else
	    {
	      sprintf (szBefehl, "%s %s %s/%s/*%s", szVOBPlayer,
		       szPreviewParam, szFilmVerzeichnis, szVideoTS, szVobTS);
	    }
	  printf ("%s\n", szBefehl);
	  system (szBefehl);
	  switch (lSprache)
	    {
	    case 0:
	      printf ("\nNach Ausfuehrung %s Enter druecken...\n",
		      szVOBPlayer);
	      break;
	    case 1:
	      printf ("\nAfter preview with %s please press Enter...\n",
		      szVOBPlayer);
	      break;
	    case 2:
	      printf
		("\nAppuyez sur Entrée à la fin de la prévisu par %s...\n",
		 szVOBPlayer);
	      break;
	    }
	}
      eatToNL (stdin);		// Eingabepuffer leeren
    }

  // DVD brennen
  if (lBrennProgramm > 0)
    {
      char cBurn = ' ';
      FILE *fTmp;
      long lVollstaendig = 0;
      // Test, ob Struktur vollstaendig ist?
      // Dazu gehoeren die IFO- und BUP-Dateien (=dvdauthor -T)
      sprintf (szBefehl, "%s/VIDEO_TS/VIDEO_TS.BUP", szFilmVerzeichnis);
      fTmp = fopen (szBefehl, "r");
      if (fTmp)
	{
	  lVollstaendig++;
	  fclose (fTmp);
	}
      sprintf (szBefehl, "%s/VIDEO_TS/VIDEO_TS.IFO", szFilmVerzeichnis);
      fTmp = fopen (szBefehl, "r");
      if (fTmp)
	{
	  lVollstaendig++;
	  fclose (fTmp);
	}
      if (lVollstaendig < 2)
	{
	  switch (lSprache)
	    {
	    case 0:
	      printf
		("\n\nDVD-Struktur ist unvollstaendig, es wird nicht gebrannt!\n");
	      break;
	    case 1:
	      printf
		("\n\nDVD-Structure is not complete! Burning is canceled!\n");
	      break;
	    case 2:
	      printf
		("\n\nStructure DVD incomplète, la gravure est annulée!\n");
	      break;
	    }
	  return 0;
	}
      // Struktur scheint vollstaendig zu sein, daher Brennen.
      // Warten auf Einlegen des Rohlings ?
      if (lWaitBurn > 0 && lBrennProgramm < 4)
	{
	  switch (lSprache)
	    {
	    case 0:
	      printf
		("\n\nBitte Rohling einlegen, Enter druecken (C=Cancel):\n");
	      break;
	    case 1:
	      printf
		("\n\nPlease insert DVD-R, then press Enter (C=Cancel):\n");
	      break;
	    case 2:
	      printf
		("\n\nInsérez votre DVD-R, puis Entrée (C=Continuer sans graver):\n");
	      break;
	    }
	  scanf ("%1c", &cBurn);
	}
      if (cBurn != 'c')
	{
	  int lLaengeName;
	  char szFormatBefehl[1024];
	  // RW formatieren ?
	  if (lRWFormat && lBrennProgramm < 4)	// nicht bei mkisofs
	    {
	      if (lBrennProgramm == 1)	// Brennen mit growisofs
		{
		  check_program (dvdformat_name, lSprache, 1);
		  sprintf (szFormatBefehl, "%s %s -format -force %s ",
			   szNiceBurn, dvdformat_name, szDVDBrenner);
		}
	      else		// Brennen mit cdrecord
		{
		  char szSpeed[20];
		  check_program (cdrecord_name, lSprache, 1);
		  if (lDVDSpeed > 0)
		    sprintf (szSpeed, "speed=%ld", lDVDSpeed);
		  else
		    strcpy (szSpeed, "");
		  sprintf (szFormatBefehl, "%s %s dev=%s -format -force %s",
			   szNiceBurn, cdrecord_name, szDVDBrenner, szSpeed);
		}
	    }
	  // Titel der DVD setzen
	  // DVDROM als Standard
	  if (!strlen (szDVDNameOverwrite))
	    strcpy (szDVDNameOverwrite, szDVDName);
	  if (!strlen (szDVDNameOverwrite))
	    strcpy (szDVDNameOverwrite, "DVD_VIDEO");
	  // Blanks durch "_" ersetzen
	  for (lLaengeName = 0;
	       lLaengeName <= (strlen (szDVDNameOverwrite) - 1);
	       lLaengeName++)
	    if (szDVDNameOverwrite[lLaengeName] == ' ')
	      szDVDNameOverwrite[lLaengeName] = '_';
	  if (lBrennProgramm == 1)
	    {
	      char szSpeed[20];
	      char szDVDCompat[20];
	      // Geschwindigkeit explizit angeben?
	      if (lDVDSpeed > 0)
		sprintf (szSpeed, "-speed=%ld", lDVDSpeed);
	      else
		strcpy (szSpeed, "");
	      // Parameter DVD-Compat?
	      if (dvdcompat > 0)
		strcpy (szDVDCompat, "-dvd-compat");
	      else
		strcpy (szDVDCompat, "");
	      check_program (growisofs_name, lSprache, 1);
	      // Growisofs
	      sprintf (szBefehl, "%s %s %s %s %s -Z %s -V %s %s -dvd-video %s",
		       szNiceBurn, growisofs_name, szBurnParam, szSpeed, szDVDCompat,
		       szDVDBrenner, szDVDNameOverwrite, szMkisofsParam,
		       szFilmVerzeichnis);
	      for (;;)
		{
		  long lRC;
                  // Wenn gemountet durch Automounter, wieder unmounten
                  // ansonsten haeufig Probleme durch belegtes Device
                  unmount_dvd (szDVDBrenner, szTmpDir);
		  if (lRWFormat > 0 && lBrennProgramm < 4)	// Formatieren vor dem Brennen
		    {
		      switch (lSprache)
			{
			case 0:
			  printf
			    ("\nBitte warten, DVD RW wird formatiert ...\n\n");
			  break;
			case 1:
			  printf ("\nPlease wait, format DVD RW ...\n\n");
			  break;
			case 2:
			  printf ("\nPatientez, formatage du DVD RW ...\n\n");
			  break;
			}
		      printf ("%s\n", szFormatBefehl);
		      system (szFormatBefehl);
		    }
		  printf ("%s\n", szBefehl);
		  lRC = system (szBefehl);
		  if (lPlaySound > 0)
		    play_sound_if_ready (lxdvdrip_wav_name);
		  if (lRC != 0)
		    {
		      char cNochmal = ' ';
		      switch (lSprache)
			{
			case 0:
			  printf
			    ("Brennen fehlgeschlagen, neuer Versuch ... (c=cancel)\n");
			  break;
			case 1:
			  printf ("Burning failed, new try ... (c=cancel)\n");
			  break;
			case 2:
			  printf
			    ("Erreur de gravure, nouvel essai ... (c=c'est pas la peine)\n");
			  break;
			}
		      scanf ("%1c", &cNochmal);
		      if (cNochmal == 'c')
			{
			  break;
			}
		    }
		  else
		    {
		      char cNochmal = ' ';
		      // DVD auswerfen ?
		      if (lEject)
			{
			  char szEjectBefehl[1024];
			  sprintf (szEjectBefehl, "%s %s", eject_name,
				   szDVDBrenner);
			  printf ("%s\n", szEjectBefehl);
			  system (szEjectBefehl);
			}
		      lGebrannt = 1;
		      // Nicht warten auf Rohling, also auch nur eine Kopie
		      if (lWaitBurn == 0 || lMulticopy == 0)
			break;
		      // Naechster Versuch
		      switch (lSprache)
			{
			case 0:
			  printf ("Naechstes Backup ... (c=cancel)\n");
			  break;
			case 1:
			  printf ("Next Backup ... (c=cancel)\n");
			  break;
			case 2:
			  printf
			    ("Prochain Backup ... (c=c'est pas la peine)\n");
			  break;
			}
		      scanf ("%1c", &cNochmal);
		      if (cNochmal == 'c')
			{
			  break;
			}
		    }
		}
	    }
	  else
	    {
	      char szSpeed[128];
	      char szTemp[128];
	      long lRCmkisofs = 0;
	      if (lBrennProgramm != 5)
		{
		  sprintf (szTemp, "%s/dvdrip.img", szTmpDir);
		}
	      else
		{
		  sprintf (szTemp, "%s/%s.img", szTmpDir, szDVDNameOverwrite);
		}
	      check_program (mkisofs_name, lSprache, 1);
	      if (lBrennProgramm < 4)
		{
		  check_program (cdrecord_name, lSprache, 1);
		}
	      // Mkisofs + cdrecord
	      // Geschwindigkeit explizit angeben?
	      if (lDVDSpeed > 0)
		sprintf (szSpeed, "speed=%ld", lDVDSpeed);
	      else
		strcpy (szSpeed, "");
	      if (lBrennProgramm == 2 || lBrennProgramm >= 4)	// erst mkisofs, dann cdrecord, aber in 2 Befehlen
		{
		  sprintf (szBefehl, "%s %s -dvd-video -V %s %s -o %s %s",
			   szNiceBurn, mkisofs_name, szDVDNameOverwrite, szMkisofsParam,
			   szTemp, szFilmVerzeichnis);
		  printf ("%s\n", szBefehl);
		  lRCmkisofs = system (szBefehl);
		  if (lBrennProgramm >= 4)
		    {
		      lGebrannt = 1;	// ausser mkisofs kein weiterer Befehl mehr
		      if (lPlaySound > 0)
			play_sound_if_ready (lxdvdrip_wav_name);
		    }
		  else
		    sprintf (szBefehl, "%s %s -v dev=%s %s %s -eject %s",
			     szNiceBurn, cdrecord_name, szDVDBrenner, szSpeed,
			     szBurnParam, szTemp);
		}
	      else
		{		// mkisofs | cdrecord (on the fly)
		  long lSektoren = 0;
		  FILE *fp;
		  // Anzahl Sektoren muss bestimmt werden, ohne geht on the fly nicht
		  char szImgeSizeFile[128];
		  sprintf (szImgeSizeFile, "%s/imgsize.lxdvdrip", szTmpDir);
		  sprintf (szBefehl,
			   "%s %s -dvd-video -print-size %s 2>&1 | tail -n1 | sed -e 's/^.*\\ =\\ //' > %s",
			   szNiceBurn, mkisofs_name, szFilmVerzeichnis, szImgeSizeFile);
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		  // Anzahl Sektoren aus der Datei auslesen
		  fp = fopen (szImgeSizeFile, "r");
		  fscanf (fp, "%ld\n", &lSektoren);
		  fclose (fp);
		  switch (lSprache)
		    {
		    case 0:
		      printf ("Anzahl Sektoren ISO Image On The Fly: %ld\n",
			      lSektoren);
		      break;
		    case 1:
		      printf ("No. of sectors ISO image on the fly: %ld\n",
			      lSektoren);
		      break;
		    case 2:
		      printf
			("Nb. de secteurs dans l'image ISO à la volée: %ld\n",
			 lSektoren);
		      break;
		    }
		  // Datei mit Anzahl Sektoren wieder loeschen
		  sprintf (szBefehl, "rm %s", szImgeSizeFile);
		  system (szBefehl);
		  // Brennbefehl zusammemsetzen
		  sprintf (szBefehl,
			   "%s %s -dvd-video -V %s %s %s | %s -v dev=%s %s %s -eject tsize=%lds -",
			   szNiceBurn, mkisofs_name, szDVDNameOverwrite, szMkisofsParam,
			   szFilmVerzeichnis, cdrecord_name,
			   szDVDBrenner, szSpeed, szBurnParam, lSektoren);

		}
	      if (lRCmkisofs == 0 && lBrennProgramm < 4)	// Nur bei mkisofs OK
		{
		  for (;;)
		    {
		      long lRC;
                      // Wenn gemountet durch Automounter, wieder unmounten
                      // ansonsten haeufig Probleme durch belegtes Device
                      unmount_dvd (szDVDBrenner, szTmpDir);
		      if (lRWFormat > 0 && lBrennProgramm < 4)	// Formatieren vor dem Brennen
			{
			  switch (lSprache)
			    {
			    case 0:
			      printf
				("\nBitte warten, DVD RW wird formatiert ...\n\n");
			      break;
			    case 1:
			      printf ("\nPlease wait, format DVD RW ...\n\n");
			      break;
			    case 2:
			      printf
				("\nPatientez, formatage du DVD RW ...\n\n");
			      break;
			    }
			  printf ("%s\n", szFormatBefehl);
			  system (szFormatBefehl);
			}
		      printf ("%s\n", szBefehl);
		      lRC = system (szBefehl);
		      if (lPlaySound > 0)
			play_sound_if_ready (lxdvdrip_wav_name);
		      if (lRC != 0)
			{
			  char cNochmal = ' ';
			  switch (lSprache)
			    {
			    case 0:
			      printf
				("Brennen fehlgeschlagen, neuer Versuch ... (c=cancel)\n");
			      break;
			    case 1:
			      printf
				("Burning failed, new try ... (c=cancel)\n");
			      break;
			    case 2:
			      printf
				("Erreur de gravure, nouvel essai ... (c=c'est pas la peine)\n");
			      break;
			    }
			  scanf ("%1c", &cNochmal);
			  if (cNochmal == 'c')
			    {
			      break;
			    }
			}
		      else
			{
			  char cNochmal = ' ';
			  lGebrannt = 1;
			  // Nicht warten auf Rohling, also auch nur eine Kopie
			  if (lWaitBurn == 0 || lMulticopy == 0)
			    break;
			  // Naechster Versuch
			  switch (lSprache)
			    {
			    case 0:
			      printf ("Naechstes Backup ... (c=cancel)\n");
			      break;
			    case 1:
			      printf ("Next Backup ... (c=cancel)\n");
			      break;
			    case 2:
			      printf
				("Prochain Backup ... (c=c'est pas la peine)\n");
			      break;
			    }
			  scanf ("%1c", &cNochmal);
			  if (cNochmal == 'c')
			    {
			      break;
			    }
			}
		    }
		}
	      // Datei wieder loeschen
	      if (lBrennProgramm == 2)	// nicht noetig bei "on the fly"
		{
		  sprintf (szBefehl, "rm %s", szTemp);
		  printf ("%s\n", szBefehl);
		  system (szBefehl);
		}
	    }
	}
    }

  // Dateien sollten nicht geloescht werden, wenn Fehlermeldungen beim Brennen
  if (lLoeschen > 0 && lGebrannt == 0)
    {
      switch (lSprache)
	{
	case 0:
	  printf ("\nDateien werden nicht geloescht, weil nicht gebrannt!\n");
	  break;
	case 1:
	  printf ("\nNot deleting files, because burning failed!\n");
	  break;
	case 2:
	  printf
	    ("\nFichiers NON effacés, en raison de l'erreur de gravure !\n");
	  break;
	}
      lLoeschen = 0;
    }

  // Filmverzeichnis entsorgen
  if (lLoeschen > 0)
    {
      switch (lSprache)
	{
	case 0:
	  printf ("\n\nBitte warten, Files loeschen!\n\n");
	  break;
	case 1:
	  printf ("\n\nPlease wait, deleting all temporary files!\n\n");
	  break;
	case 2:
	  printf ("\n\nPatientez, effacement des fichiers temporaires !\n\n");
	  break;
	}
      if (!strlen (szVideoTS))
      {
	strcpy (szVideoTS, "VIDEO_TS");
	strcpy (szAudioTS, "AUDIO_TS");
      }
      if (szFilmVerzeichnis[strlen (szFilmVerzeichnis) - 1] != '/')
	strcat (szFilmVerzeichnis, "/");
      sprintf (szBefehl, "rmdir %s%s", szFilmVerzeichnis, szAudioTS);
      printf ("%s\n", szBefehl);
      system (szBefehl);
      sprintf (szBefehl, "rm %s%s/*", szFilmVerzeichnis, szVideoTS);
      printf ("%s\n", szBefehl);
      system (szBefehl);
      sprintf (szBefehl, "rmdir %s%s", szFilmVerzeichnis, szVideoTS);
      printf ("%s\n", szBefehl);
      system (szBefehl);
      // bei dvdbackup zusaetzlich das Unterverzeichnis loeschen laut DVD Volume
      // und dann vorheriges Verzeichnis wieder einstellen.
      if (lPackMethode == 5 && lGroesseDVDGesamt <= lGroesseDVDBytesMaximal)
	{
	  sprintf (szBefehl, "rmdir %s", szFilmVerzeichnis);
	  printf ("%s\n", szBefehl);
	  system (szBefehl);
	  strcpy (szFilmVerzeichnis, szAltesFilmVerzeichnis);
	  if (szFilmVerzeichnis[strlen (szFilmVerzeichnis) - 1] != '/')
	    strcat (szFilmVerzeichnis, "/");
	}
      // Jetzt das Basisverzeichnis loeschen
      // Zuerst das angehaengte "/" loeschen
      szFilmVerzeichnis[strlen (szFilmVerzeichnis) - 1] = 0;
      // Nicht aus Versehen ein Systemverzeichnis loeschen
      if (strcmp (szFilmVerzeichnis, "/bin") != 0 &&
	  strcmp (szFilmVerzeichnis, "/boot") != 0 &&
	  strcmp (szFilmVerzeichnis, "/dev") != 0 &&
	  strcmp (szFilmVerzeichnis, "/etc") != 0 &&
	  strcmp (szFilmVerzeichnis, "/home") != 0 &&
	  strcmp (szFilmVerzeichnis, "/initrd") != 0 &&
	  strcmp (szFilmVerzeichnis, "/lib") != 0 &&
	  strcmp (szFilmVerzeichnis, "/media") != 0 &&
	  strcmp (szFilmVerzeichnis, "/misc") != 0 &&
	  strcmp (szFilmVerzeichnis, "/mnt") != 0 &&
	  strcmp (szFilmVerzeichnis, "/opt") != 0 &&
	  strcmp (szFilmVerzeichnis, "/proc") != 0 &&
	  strcmp (szFilmVerzeichnis, "/root") != 0 &&
	  strcmp (szFilmVerzeichnis, "/sbin") != 0 &&
	  strcmp (szFilmVerzeichnis, "/tmp") != 0 &&
	  strcmp (szFilmVerzeichnis, "/usr") != 0 &&
	  strcmp (szFilmVerzeichnis, "/windows") != 0 &&
	  strcmp (szFilmVerzeichnis, "/var") != 0)
	{
	  sprintf (szBefehl, "rmdir %s", szFilmVerzeichnis);
	  printf ("%s\n", szBefehl);
	  system (szBefehl);
	}
    }

  // Datei mit Palette wieder loeschen
  if (lPaletteVorhanden == 1)
    {
      sprintf (szBefehl, "rm %s", szPaletteFile);
      system (szBefehl);
    }

  // Chapterdatei loeschen
  if (strlen (szChapterFile))
    {
      sprintf (szBefehl, "rm %s", szChapterFile);
      system (szBefehl);
    }

  if (lGebrannt > 0)
    {
      switch (lSprache)
	{
	case 0:
	  printf
	    ("\n\nFertig! Viel Spass beim Anschauen der Sicherheitskopie!\n\n");
	  break;
	case 1:
	  printf ("\n\nReady! Have fun with your backup safety copy!\n\n");
	  break;
	case 2:
	  printf
	    ("\n\nTerminé ! Vous avez maintenant une sauvegarde de sécurité !\n\n");
	  break;
	}
    }
  else
    {
      switch (lSprache)
	{
	case 0:
	  printf ("\n\nEs wurde keine Sicherheitskopie angefertigt !\n\n");
	  break;
	case 1:
	  printf ("\n\nThe backup safety copy isn't completed !\n\n");
	  break;
	case 2:
	  printf ("\n\nSauvegarde de sécurité NON faite !\n\n");
	  break;
	}
    }

  STOP;
  return 0;
}
