[Matroska-cvs] [matroska] r1270 - in trunk/DvdMenuXtractor: .
Resources libdvdread libdvdread/dvdread libdvdread/src
libdvdread/win32 mpegparser vobparser vobparser/iso
robux4 at matroska.org
robux4 at matroska.org
Sun Jan 28 17:49:11 CET 2007
Author: robux4
Date: 2007-01-28 19:48:11 +0300 (Sun, 28 Jan 2007)
New Revision: 1270
Added:
trunk/DvdMenuXtractor/DvdMenuXtractor.proj
trunk/DvdMenuXtractor/Resources/
trunk/DvdMenuXtractor/Resources/back.png
trunk/DvdMenuXtractor/Resources/dmx.png
trunk/DvdMenuXtractor/Resources/error.png
trunk/DvdMenuXtractor/Resources/log.png
trunk/DvdMenuXtractor/Resources/next.png
trunk/DvdMenuXtractor/Resources/quit.png
trunk/DvdMenuXtractor/Resources/warning.png
trunk/DvdMenuXtractor/chaptermanager.cpp
trunk/DvdMenuXtractor/chaptermanager.h
trunk/DvdMenuXtractor/config.h
trunk/DvdMenuXtractor/dmx.cpp
trunk/DvdMenuXtractor/dmx.h
trunk/DvdMenuXtractor/dmx.ico
trunk/DvdMenuXtractor/dmx.rc
trunk/DvdMenuXtractor/dmxconsole.cpp
trunk/DvdMenuXtractor/dmxconsole.h
trunk/DvdMenuXtractor/dmxlogwidget.cpp
trunk/DvdMenuXtractor/dmxlogwidget.h
trunk/DvdMenuXtractor/dmxlogwidget.ui
trunk/DvdMenuXtractor/dmxselectionitem.cpp
trunk/DvdMenuXtractor/dmxselectionitem.h
trunk/DvdMenuXtractor/dmxselectiontree.cpp
trunk/DvdMenuXtractor/dmxselectiontree.h
trunk/DvdMenuXtractor/dmxwizard.cpp
trunk/DvdMenuXtractor/dmxwizard.h
trunk/DvdMenuXtractor/dmxwizard.qrc
trunk/DvdMenuXtractor/dmxwizard.ui
trunk/DvdMenuXtractor/libdvdread/dvdread/cmd_print.c
trunk/DvdMenuXtractor/libdvdread/dvdread/cmd_print.h
trunk/DvdMenuXtractor/libdvdread/dvdread/dvdread.proj
trunk/DvdMenuXtractor/libdvdread/libdvdread.proj
trunk/DvdMenuXtractor/libdvdread/src/filestat.c
trunk/DvdMenuXtractor/libdvdread/src/src.proj
trunk/DvdMenuXtractor/libdvdread/win32/posix.h
trunk/DvdMenuXtractor/libdvdread/win32/stdint.h
trunk/DvdMenuXtractor/libdvdread/win32/win32.proj
trunk/DvdMenuXtractor/logtextedit.cpp
trunk/DvdMenuXtractor/logtextedit.h
trunk/DvdMenuXtractor/main.cpp
trunk/DvdMenuXtractor/mpegparser/mpegparser.proj
trunk/DvdMenuXtractor/outputreader.cpp
trunk/DvdMenuXtractor/outputreader.h
trunk/DvdMenuXtractor/selectiontreeitem.cpp
trunk/DvdMenuXtractor/selectiontreeitem.h
trunk/DvdMenuXtractor/selectiontreesubitem.cpp
trunk/DvdMenuXtractor/selectiontreesubitem.h
trunk/DvdMenuXtractor/utilities.cpp
trunk/DvdMenuXtractor/utilities.h
trunk/DvdMenuXtractor/vobparser/
trunk/DvdMenuXtractor/vobparser/IFOContent.cpp
trunk/DvdMenuXtractor/vobparser/IFOContent.h
trunk/DvdMenuXtractor/vobparser/IFOFile.cpp
trunk/DvdMenuXtractor/vobparser/IFOFile.h
trunk/DvdMenuXtractor/vobparser/VobParser.cpp
trunk/DvdMenuXtractor/vobparser/VobParser.h
trunk/DvdMenuXtractor/vobparser/iso/
trunk/DvdMenuXtractor/vobparser/iso/iso-639.def
trunk/DvdMenuXtractor/vobparser/iso/iso_lang.c
trunk/DvdMenuXtractor/vobparser/iso/iso_lang.h
trunk/DvdMenuXtractor/vobparser/vobparser.proj
Removed:
trunk/DvdMenuXtractor/A52Decoder.cpp
trunk/DvdMenuXtractor/A52Decoder.h
trunk/DvdMenuXtractor/DvdMenuXtractor.bkl
trunk/DvdMenuXtractor/DvdMenuXtractor.cfg
trunk/DvdMenuXtractor/DvdMenuXtractor.cpp
trunk/DvdMenuXtractor/DvdMenuXtractor.dsp
trunk/DvdMenuXtractor/DvdMenuXtractor.dsw
trunk/DvdMenuXtractor/DvdMenuXtractor.h
trunk/DvdMenuXtractor/DvdMenuXtractor.ini
trunk/DvdMenuXtractor/DvdMenuXtractor.rc
trunk/DvdMenuXtractor/DvdMenuXtractor.sln
trunk/DvdMenuXtractor/DvdMenuXtractor.vcproj
trunk/DvdMenuXtractor/IFOFile.cpp
trunk/DvdMenuXtractor/IFOFile.h
trunk/DvdMenuXtractor/MPEG2Decoder.cpp
trunk/DvdMenuXtractor/MPEG2Decoder.h
trunk/DvdMenuXtractor/Makefile
trunk/DvdMenuXtractor/MyWizard.cpp
trunk/DvdMenuXtractor/MyWizard.h
trunk/DvdMenuXtractor/README.txt
trunk/DvdMenuXtractor/VobParser.cpp
trunk/DvdMenuXtractor/VobParser.h
trunk/DvdMenuXtractor/base64.cpp
trunk/DvdMenuXtractor/base64.h
trunk/DvdMenuXtractor/iso/
trunk/DvdMenuXtractor/libdvdread/libdvdread.bkl
trunk/DvdMenuXtractor/libdvdread/win32/libdvdread.vcproj
trunk/DvdMenuXtractor/makefile.vc
trunk/DvdMenuXtractor/resource/
trunk/DvdMenuXtractor/win32/
Modified:
trunk/DvdMenuXtractor/
trunk/DvdMenuXtractor/libdvdread/dvdread/bswap.h
trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_input.c
trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_input.h
trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_reader.c
trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_reader.h
trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_udf.c
trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_udf.h
trunk/DvdMenuXtractor/libdvdread/dvdread/dvdread_internal.h
trunk/DvdMenuXtractor/libdvdread/dvdread/ifo_print.c
trunk/DvdMenuXtractor/libdvdread/dvdread/ifo_read.c
trunk/DvdMenuXtractor/libdvdread/dvdread/ifo_types.h
trunk/DvdMenuXtractor/libdvdread/dvdread/nav_print.c
trunk/DvdMenuXtractor/libdvdread/dvdread/nav_read.c
trunk/DvdMenuXtractor/libdvdread/dvdread/nav_types.h
trunk/DvdMenuXtractor/libdvdread/src/disc_id.c
trunk/DvdMenuXtractor/libdvdread/src/ifo_dump.c
trunk/DvdMenuXtractor/libdvdread/src/play_title.c
trunk/DvdMenuXtractor/libdvdread/src/title_info.c
trunk/DvdMenuXtractor/libdvdread/win32/config.h
trunk/DvdMenuXtractor/libdvdread/win32/dirent.c
trunk/DvdMenuXtractor/libdvdread/win32/gtchar.h
trunk/DvdMenuXtractor/libdvdread/win32/inttypes.h
trunk/DvdMenuXtractor/mpegparser/Types.h
Log:
introducting the new DvdMenuXtractor, based on Qt4 and using coremake
Property changes on: trunk/DvdMenuXtractor
___________________________________________________________________
Name: svn:ignore
- build
+ build
stderr.txt
stdout.txt
Name: svn:externals
+ coremake https://svn.matroska.org/svn/misc/coremake
Deleted: trunk/DvdMenuXtractor/A52Decoder.cpp
Deleted: trunk/DvdMenuXtractor/A52Decoder.h
Deleted: trunk/DvdMenuXtractor/DvdMenuXtractor.bkl
Deleted: trunk/DvdMenuXtractor/DvdMenuXtractor.cfg
Deleted: trunk/DvdMenuXtractor/DvdMenuXtractor.cpp
Deleted: trunk/DvdMenuXtractor/DvdMenuXtractor.dsp
Deleted: trunk/DvdMenuXtractor/DvdMenuXtractor.dsw
Deleted: trunk/DvdMenuXtractor/DvdMenuXtractor.h
Deleted: trunk/DvdMenuXtractor/DvdMenuXtractor.ini
Added: trunk/DvdMenuXtractor/DvdMenuXtractor.proj
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/DvdMenuXtractor.proj 2007-01-22 11:21:16 UTC (r=
ev 1269)
+++ trunk/DvdMenuXtractor/DvdMenuXtractor.proj 2007-01-28 16:48:11 UTC (r=
ev 1270)
@@ -0,0 +1,91 @@
+CONFIG_FILE config.h
+PLATFORM_FILES coremake
+
+WORKSPACE dmx
+{
+ USE DvdMenuXtractor
+}
+
+#include "*/*.proj"
+
+CON DvdMenuXtractor
+{
+ USE dvdread
+ USE vobparser
+ USE mpegparser
+
+ INCLUDE "$(QTDIR)/include/QtCore"
+ INCLUDE "$(QTDIR)/include/QtGui"
+ INCLUDE "$(QTDIR)/include/QtXml"
+ INCLUDE "$(QTDIR)/include"
+ INCLUDE(COMPILER_MSVC) libdvdread/win32
+ INCLUDE libdvdread
+ =20
+ DEFINE(QT_NO_DEBUG) QT_NO_DEBUG_STREAM
+ =20
+ LIBS_RELEASE(COMPILER_MSVC) qtmain.lib
+ LIBS_RELEASE(COMPILER_MSVC && CONFIG_STATIC) QtCore.lib
+ LIBS_RELEASE(COMPILER_MSVC && CONFIG_STATIC) QtGui.lib
+ LIBS_RELEASE(COMPILER_MSVC && CONFIG_STATIC) QtNetwork.lib
+ LIBS_RELEASE(COMPILER_MSVC && CONFIG_STATIC) QtXml.lib
+ LIBS_RELEASE(COMPILER_MSVC && !CONFIG_STATIC) QtCore4.lib
+ LIBS_RELEASE(COMPILER_MSVC && !CONFIG_STATIC) QtGui4.lib
+ LIBS_RELEASE(COMPILER_MSVC && !CONFIG_STATIC) QtNetwork4.lib
+ LIBS_RELEASE(COMPILER_MSVC && !CONFIG_STATIC) QtXml4.lib
+ LIBS_DEBUG(COMPILER_MSVC) qtmaind.lib
+ LIBS_DEBUG(COMPILER_MSVC && CONFIG_STATIC) QtCored.lib
+ LIBS_DEBUG(COMPILER_MSVC && CONFIG_STATIC) QtGuid.lib
+ LIBS_DEBUG(COMPILER_MSVC && CONFIG_STATIC) QtNetworkd.lib
+ LIBS_DEBUG(COMPILER_MSVC && CONFIG_STATIC) QtXmld.lib
+ LIBS_DEBUG(COMPILER_MSVC && !CONFIG_STATIC) QtCored4.lib
+ LIBS_DEBUG(COMPILER_MSVC && !CONFIG_STATIC) QtGuid4.lib
+ LIBS_DEBUG(COMPILER_MSVC && !CONFIG_STATIC) QtNetworkd4.lib
+ LIBS_DEBUG(COMPILER_MSVC && !CONFIG_STATIC) QtXml4.lib
+ LIBS(COMPILER_GCC) qtmain
+ LIBS(COMPILER_GCC && CONFIG_STATIC) QtNetwork
+ LIBS(COMPILER_GCC && CONFIG_STATIC) QtGui
+ LIBS(COMPILER_GCC && CONFIG_STATIC) QtCore
+ LIBS(COMPILER_GCC && CONFIG_STATIC) QtXml
+ LIBS(COMPILER_GCC && !CONFIG_STATIC) QtNetwork4
+ LIBS(COMPILER_GCC && !CONFIG_STATIC) QtGui4
+ LIBS(COMPILER_GCC && !CONFIG_STATIC) QtCore4
+ LIBS(COMPILER_GCC && !CONFIG_STATIC) QtXml4
+ LIBS(TARGET_WIN) imm32.lib
+ LIBS(TARGET_WIN) winmm.lib
+ LIBS(TARGET_WIN) ws2_32.lib
+
+ LIBINCLUDE "$(QTDIR)/lib"
+
+ SOURCE chaptermanager.cpp
+ SOURCE dmx.cpp
+ SOURCE dmxconsole.cpp
+ SOURCE dmxlogwidget.cpp
+ SOURCE dmxselectionitem.cpp
+ SOURCE dmxselectiontree.cpp
+ SOURCE dmxwizard.cpp
+ SOURCE logtextedit.cpp
+ SOURCE main.cpp
+ SOURCE outputreader.cpp
+ SOURCE selectiontreeitem.cpp
+ SOURCE selectiontreesubitem.cpp
+ SOURCE utilities.cpp
+ SOURCE(TARGET_WIN) dmx.rc
+
+ HEADER chaptermanager.h
+ HEADER_QT4 dmx.h
+ HEADER dmxconsole.h
+ HEADER_QT4 dmxlogwidget.h
+ HEADER dmxselectionitem.h
+ HEADER_QT4 dmxselectiontree.h
+ HEADER_QT4 dmxwizard.h
+ HEADER_QT4 logtextedit.h
+ HEADER_QT4 outputreader.h
+ HEADER selectiontreeitem.h
+ HEADER selectiontreesubitem.h
+ HEADER utilities.h
+ =20
+ UI_FORM_QT4 dmxlogwidget.ui
+ UI_FORM_QT4 dmxwizard.ui
+ =20
+ RESOURCE_QT4 dmxwizard.qrc
+}
Deleted: trunk/DvdMenuXtractor/DvdMenuXtractor.rc
Deleted: trunk/DvdMenuXtractor/DvdMenuXtractor.sln
Deleted: trunk/DvdMenuXtractor/DvdMenuXtractor.vcproj
Deleted: trunk/DvdMenuXtractor/IFOFile.cpp
Deleted: trunk/DvdMenuXtractor/IFOFile.h
Deleted: trunk/DvdMenuXtractor/MPEG2Decoder.cpp
Deleted: trunk/DvdMenuXtractor/MPEG2Decoder.h
Deleted: trunk/DvdMenuXtractor/Makefile
Deleted: trunk/DvdMenuXtractor/MyWizard.cpp
Deleted: trunk/DvdMenuXtractor/MyWizard.h
Deleted: trunk/DvdMenuXtractor/README.txt
Added: trunk/DvdMenuXtractor/Resources/back.png
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
(Binary files differ)
Property changes on: trunk/DvdMenuXtractor/Resources/back.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/DvdMenuXtractor/Resources/dmx.png
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
(Binary files differ)
Property changes on: trunk/DvdMenuXtractor/Resources/dmx.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/DvdMenuXtractor/Resources/error.png
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
(Binary files differ)
Property changes on: trunk/DvdMenuXtractor/Resources/error.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/DvdMenuXtractor/Resources/log.png
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
(Binary files differ)
Property changes on: trunk/DvdMenuXtractor/Resources/log.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/DvdMenuXtractor/Resources/next.png
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
(Binary files differ)
Property changes on: trunk/DvdMenuXtractor/Resources/next.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/DvdMenuXtractor/Resources/quit.png
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
(Binary files differ)
Property changes on: trunk/DvdMenuXtractor/Resources/quit.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/DvdMenuXtractor/Resources/warning.png
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
(Binary files differ)
Property changes on: trunk/DvdMenuXtractor/Resources/warning.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Deleted: trunk/DvdMenuXtractor/VobParser.cpp
Deleted: trunk/DvdMenuXtractor/VobParser.h
Deleted: trunk/DvdMenuXtractor/base64.cpp
Deleted: trunk/DvdMenuXtractor/base64.h
Added: trunk/DvdMenuXtractor/chaptermanager.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/chaptermanager.cpp 2007-01-22 11:21:16 UTC (rev=
1269)
+++ trunk/DvdMenuXtractor/chaptermanager.cpp 2007-01-28 16:48:11 UTC (rev=
1270)
@@ -0,0 +1,689 @@
+#include "chaptermanager.h"
+#include "utilities.h"
+
+#include <QtXml>
+
+QString ChapterManager::INFO_SUFFIX ("_info.xml");
+QString ChapterManager::CHAPTER_SUFFIX ("_menu.xml");
+
+bool ChapterManager::generateScript(const IFOFile& ifoFile, const QStrin=
g& filename, uint16_t title, const QString& editionUID) const
+{
+ static unsigned char _PrivateVTS[] =3D {0x30, 0x80, 0x00, 0x00};
+ static unsigned char _PrivateTT[] =3D {0x28, 0x00, 0x00, 0x00};
+ uint64_t start_timeH =3D uint64_t(-1);
+
+ generateInfoScript(filename, title, editionUID);
+
+ // create document
+ QDomDocument document;
+
+ // specify processing info
+ document.appendChild(document.createProcessingInstruction("xml", "versi=
on=3D\"1.0\" encoding=3D\"UTF-8\" standalone=3D\"no\""));
+ document.appendChild(document.implementation().createDocumentType("Chap=
ters", QString::null, "matroskachapters.dtd"));
+
+ // create comments
+ document.appendChild(document.createComment("Created with " + Utilities=
::APPLICATION_NAME + " " + Utilities::APPLICATION_VERSION));
+
+ // create the root element
+ QDomNode root =3D document.createElement("Chapters");
+ document.appendChild(root);
+
+ // VTS content
+ QDomElement editionEntryElement =3D document.createElement("EditionEntr=
y");
+ root.appendChild(editionEntryElement);
+=09
+ editionEntryElement.appendChild(CreateDOMElement(document, "EditionUID"=
, editionUID));
+ editionEntryElement.appendChild(CreateDOMElement(document, "EditionFlag=
Ordered", "1"));
+ editionEntryElement.appendChild(document.createComment("Video Title Set=
"));
+
+ QDomElement chapterAtomElement =3D document.createElement("ChapterAtom"=
);
+ editionEntryElement.appendChild(chapterAtomElement);
+
+ QString _myUIDa =3D Utilities::CreateUID();
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterUID",=
_myUIDa));
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterFlagH=
idden", "1"));
+=09
+ _PrivateVTS[2] =3D title >> 8;
+ _PrivateVTS[3] =3D title & 0xFF;
+ AddCodecPrivateData(document, chapterAtomElement, _PrivateVTS, 4);
+
+ QDomNode chapterAtomParentElement =3D chapterAtomElement;
+
+ if (ifoFile.VtsTitles(title) && ifoFile.VtsPGCs(title))
+ {
+ for (int i =3D 0; i < ifoFile.VtsTitles(title)->nr_of_srpts; i++)
+ {
+ uint64_t start_time =3D uint64_t(-1), found_time;
+ =09
+ chapterAtomParentElement.appendChild(document.createComment(QString("=
Title TTU_%1").arg(i + 1)));
+ QDomElement chapterAtomElement =3D document.createElement("ChapterAto=
m");
+ chapterAtomParentElement.appendChild(chapterAtomElement);
+ =09
+ QString _myUIDa =3D Utilities::CreateUID();
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterUID=
", _myUIDa));
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterFla=
gHidden", "1"));
+
+ // get the Title -> VTS+TTN map
+ const tt_srpt_t *p_map =3D ifoFile.TitleMap();
+
+ if ( p_map !=3D NULL )
+ {
+ for (int j=3D0; j<p_map->nr_of_srpts; j++)
+ {
+ if ( ( p_map->title[j].title_set_nr =3D=3D title ) && ( p_map->titl=
e[j].vts_ttn =3D=3D i+1 ) )
+ {
+ _PrivateTT[1] =3D (j+1) >> 8; // Title#
+ _PrivateTT[2] =3D (j+1) & 0xFF;
+ _PrivateTT[3] =3D i+1; // VTS_TTN#
+ AddCodecPrivateData(document, chapterAtomElement, _PrivateTT, 4);
+ break;
+ }
+ }
+ }
+
+ // add the PGC that match this PTT
+ for (int k =3D 0; k < ifoFile.VtsPGCs(title)->nr_of_pgci_srp; k++)
+ {
+ if ((ifoFile.VtsPGCs(title)->pgci_srp[k].entry_id & 0x7F) =3D=3D i+1=
)
+ {
+ found_time =3D AddPGC(document, chapterAtomElement,=20
+ ifoFile.VtsPGCs(title)->pgci_srp[k].pgc, k, 0, ifoFile.CellsList(t=
itle, false), &ifoFile.VtsTitles(title)->title[i], i+1);
+ =09
+ if (start_time > found_time)
+ start_time =3D found_time;
+ }
+ }
+
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterTim=
eStart", Utilities::FormatTime(start_time)));
+
+ if (start_timeH > start_time)
+ start_timeH =3D start_time;
+ }
+ }
+
+ if (start_timeH =3D=3D uint64_t(-1))
+ start_timeH =3D 0;
+
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterTimeS=
tart", Utilities::FormatTime(start_timeH)));
+=09
+ QString output =3D document.toString(INDENT_COUNT);
+
+ // TODO: not a good approach
+ output.replace("-->", "-->\n");
+
+ // chapter file
+ QFile chapterFile (filename + CHAPTER_SUFFIX);
+ if (!chapterFile.open(QIODevice::WriteOnly | QIODevice::Text))
+ throw;
+
+ chapterFile.write(output.toUtf8());
+ chapterFile.close();
+
+ return true;
+}
+
+bool ChapterManager::generateMenuScript(const IFOFile& ifoFile, const QS=
tring& filename, uint16_t title, const QString& editionUID) const
+{
+ static unsigned char _PrivateFP[] =3D {0x30, 0x00, 0x00, 0x00};
+ static unsigned char _PrivateVM[] =3D {0x30, 0xC0, 0x00, 0x00};
+ static unsigned char _PrivateVTS[] =3D {0x30, 0x40, 0x00, 0x00};
+
+ // generate info script
+ generateInfoScript(filename, title, editionUID);
+
+ // create document
+ QDomDocument document;
+
+ // specify processing info
+ document.appendChild(document.createProcessingInstruction("xml", "versi=
on=3D\"1.0\" encoding=3D\"UTF-8\" standalone=3D\"no\""));
+ document.appendChild(document.implementation().createDocumentType("Chap=
ters", QString::null, "matroskachapters.dtd"));
+
+ // create comments
+ document.appendChild(document.createComment("Created with " + Utilities=
::APPLICATION_NAME + " " + Utilities::APPLICATION_VERSION));
+
+ // create the root element
+ QDomNode parentElement =3D document.createElement("Chapters");
+ document.appendChild(parentElement);
+
+ // create Edition Entry Element and add to root
+ QDomElement currentElement =3D document.createElement("EditionEntry");
+ parentElement.appendChild(currentElement);
+=09
+ // use Edition Entry Element as parent
+ parentElement =3D currentElement;
+
+ // add EditionUID and EDitionFlagOrdered elements
+ parentElement.appendChild(CreateDOMElement(document, "EditionUID", edit=
ionUID));
+ parentElement.appendChild(CreateDOMElement(document, "EditionFlagOrdere=
d", "1"));
+
+ // Write the first play PGC
+ if (title =3D=3D 0 && ifoFile.FirstPlayPGC())
+ {
+ // add comment to Edition Entry Element
+ parentElement.appendChild(document.createComment("First Play PGC"));
+
+ // add Chapter Atom
+ QDomElement chapterAtomElement =3D document.createElement("ChapterAtom=
");
+ parentElement.appendChild(chapterAtomElement);
+
+ // create and set UID
+ QString _myUID =3D Utilities::CreateUID();
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterUID"=
, _myUID));
+
+ // the First Play PGC has no cell and no time
+ AddChapterTime(document, chapterAtomElement, 0, 0);
+
+ // display the UID for the lazy rippers
+ chapterAtomElement.appendChild(document.createComment("Enter your text=
here"));
+
+ // add Chapter Display Element
+ currentElement =3D document.createElement("ChapterDisplay");
+ currentElement.appendChild(CreateDOMElement(document, "ChapterString",=
"First Play PGC " + _myUID));
+ chapterAtomElement.appendChild(currentElement);
+
+ // add Chapter Process Element
+ currentElement =3D document.createElement("ChapterProcess");
+ AddCodecPrivateData(document, currentElement, _PrivateFP, 4, false);
+ chapterAtomElement.appendChild(currentElement);
+
+ // PGC commands
+ AddPGCCommands(document, currentElement, ifoFile.FirstPlayPGC()->comma=
nd_tbl);
+ }
+
+ // Write the Video Title Set
+ if (ifoFile.LanguageUnits(title) && ifoFile.LanguageUnits(title)->nr_of=
_lus)
+ {
+ // VTS Menu
+ if ( title =3D=3D 0 )
+ parentElement.appendChild(document.createComment("Video Manager"));
+ else
+ parentElement.appendChild(document.createComment("Video Title Set"));
+
+ // add another Chapter Atom element
+ currentElement =3D document.createElement("ChapterAtom");
+ parentElement.appendChild(currentElement);
+
+ QString _myUIDa =3D Utilities::CreateUID();
+ currentElement.appendChild(CreateDOMElement(document, "ChapterUID", _m=
yUIDa));
+ currentElement.appendChild(CreateDOMElement(document, "ChapterFlagHidd=
en", "1"));
+
+ if ( title !=3D 0 )
+ {
+ _PrivateVTS[2] =3D title >> 8;
+ _PrivateVTS[3] =3D title & 0xFF;
+ AddCodecPrivateData(document, currentElement, _PrivateVTS, 4);
+ }
+ else
+ {
+ _PrivateVM[2] =3D 0;
+ _PrivateVM[3] =3D 0;
+ AddCodecPrivateData(document, currentElement, _PrivateVM, 4);
+ }
+
+ uint64_t start_time =3D HandleLanguageUnit(document, currentElement, i=
foFile, title);
+
+ currentElement.appendChild(CreateDOMElement(document, "ChapterTimeStar=
t", Utilities::FormatTime(start_time)));
+ }
+
+ // get document string representation
+ QString output =3D document.toString(INDENT_COUNT);
+
+ // TODO: not a good approach
+ output.replace("-->", "-->\n");
+
+ // chapter file
+ QFile chapterFile(filename + CHAPTER_SUFFIX);
+ if (!chapterFile.open(QIODevice::WriteOnly | QIODevice::Text))
+ throw;
+=09
+ // write to the chpater file
+ chapterFile.write(output.toUtf8());
+ chapterFile.close();
+
+ return true;
+}
+
+void ChapterManager::generateInfoScript(const QString &filename, uint16_=
t title, const QString &editionUID) const
+{
+ // create document
+ QDomDocument document;
+
+ // specify xml version, encoding and DocType
+ document.appendChild(document.createProcessingInstruction("xml", "versi=
on=3D\"1.0\" encoding=3D\"UTF-8\" standalone=3D\"no\""));
+ document.appendChild(document.implementation().createDocumentType("Chap=
ters", QString::null, "matroskainfos.dtd"));
+
+ // add root element
+ QDomNode parentElement =3D document.createElement("Info");
+ document.appendChild(parentElement);
+
+ // add Segment Family Element
+ QDomElement currentElement =3D CreateDOMElement(document, "SegmentFamil=
y", Utilities::EncodeHex(familyUID, 16));
+ currentElement.setAttribute("format", "hex");
+ parentElement.appendChild(currentElement);
+
+ // add Chapter Translate Element
+ currentElement =3D document.createElement("ChapterTranslate");
+ currentElement.appendChild(CreateDOMElement(document, "ChapterTranslate=
EditionUID", editionUID));
+ currentElement.appendChild(CreateDOMElement(document, "ChapterTranslate=
Codec", "1"));
+=09
+ QDomElement chapterTranslateIDElement =3D CreateDOMElement(document, "C=
hapterTranslateID", QString("%1 00").arg(title, 2, 16, QChar('0')));
+ chapterTranslateIDElement.setAttribute("format", "hex");
+ currentElement.appendChild(chapterTranslateIDElement);
+
+ parentElement.appendChild(currentElement);
+
+ // get document string representation
+ QString output =3D document.toString(INDENT_COUNT);
+=09
+ // segment file
+ QFile segementFile(filename + INFO_SUFFIX);
+ if (!segementFile.open(QIODevice::WriteOnly | QIODevice::Text))
+ throw;
+=09
+ segementFile.write(output.toUtf8());
+ segementFile.close();
+}
+
+QDomElement ChapterManager::CreateDOMElement(QDomDocument &document, con=
st QString &elementName, const QString &content)
+{
+ QDomElement element =3D document.createElement(elementName);
+ element.appendChild(document.createTextNode(content));
+
+ return element;
+}
+
+void ChapterManager::AddChapterTime(QDomDocument& document, QDomNode& pa=
rent, uint64_t start_time, uint64_t end_time)
+{
+ parent.appendChild(CreateDOMElement(document, "ChapterTimeStart", Utili=
ties::FormatTime(start_time)));
+ parent.appendChild(CreateDOMElement(document, "ChapterTimeEnd", Utiliti=
es::FormatTime(end_time)));
+}
+
+void ChapterManager::AddCodecPrivateData(QDomDocument& document, QDomNod=
e& parent, const unsigned char *buffer, unsigned int size, bool createCha=
pterProcessElement /*=3D true*/)
+{
+ QDomNode node =3D parent;
+
+ if (createChapterProcessElement)
+ {
+ QDomElement chapterProcessElement =3D document.createElement("ChapterP=
rocess");
+ parent.appendChild(chapterProcessElement);
+ node =3D chapterProcessElement;
+ }
+
+ node.appendChild(CreateDOMElement(document, "ChapterProcessCodecID", "1=
"));
+
+ QDomElement chapterProcessPrivateElement =3D CreateDOMElement(document,=
"ChapterProcessPrivate", Utilities::EncodeHex(buffer, size));
+ chapterProcessPrivateElement.setAttribute("format", "hex");
+ node.appendChild(chapterProcessPrivateElement);
+}
+
+void ChapterManager::AddPGCCommands(QDomDocument& document, QDomNode& pa=
rent, const pgc_command_tbl_t * command_tbl)
+{
+ if (command_tbl)
+ {
+ unsigned char *_buf =3D (unsigned char*) malloc(1 + command_tbl->nr_of=
_pre * 8);
+
+ // Pre-commands
+ if (command_tbl->nr_of_pre)
+ {
+ parent.appendChild(document.createComment("Pre commands"));
+
+ QDomElement chapterCommandElement =3D document.createElement("Chapter=
ProcessCommand");
+ parent.appendChild(chapterCommandElement);
+
+ QDomElement chapterProcessTimeElement =3D document.createElement("Cha=
pterProcessTime");
+ chapterProcessTimeElement.appendChild(document.createTextNode("1"));
+ chapterCommandElement.appendChild(chapterProcessTimeElement);
+
+ _buf[0] =3D command_tbl->nr_of_pre;
+ memcpy(&_buf[1], command_tbl->pre_cmds, command_tbl->nr_of_pre * 8);
+
+ QDomElement chapterProcessDataElement =3D CreateDOMElement(document, =
"ChapterProcessData", Utilities::EncodeHex(_buf, 1 + command_tbl->nr_of_p=
re * 8));
+ chapterProcessDataElement.setAttribute("format", "hex");
+ chapterCommandElement.appendChild(chapterProcessDataElement);
+ }
+
+ // Cell commands
+ if (command_tbl->nr_of_cell)
+ {
+ parent.appendChild(document.createComment("Cell commands"));
+
+ QDomElement chapterCommandElement =3D document.createElement("Chapter=
ProcessCommand");
+ parent.appendChild(chapterCommandElement);
+
+ QDomElement chapterProcessTimeElement =3D document.createElement("Cha=
pterProcessTime");
+ chapterProcessTimeElement.appendChild(document.createTextNode("0"));
+ chapterCommandElement.appendChild(chapterProcessTimeElement);
+
+ _buf =3D (unsigned char*) realloc(_buf, 1 + command_tbl->nr_of_cell *=
8);
+ _buf[0] =3D command_tbl->nr_of_cell;
+ memcpy(&_buf[1], command_tbl->cell_cmds, command_tbl->nr_of_cell * 8)=
;
+
+ QDomElement chapterProcessDataElement =3D CreateDOMElement(document, =
"ChapterProcessData", Utilities::EncodeHex(_buf, 1 + command_tbl->nr_of_c=
ell * 8));
+ chapterProcessDataElement.setAttribute("format", "hex");
+ chapterCommandElement.appendChild(chapterProcessDataElement);
+ }
+
+ // Post commands
+ if (command_tbl->nr_of_post)
+ {
+ parent.appendChild(document.createComment("Post commands"));
+
+ QDomElement chapterCommandElement =3D document.createElement("Chapter=
ProcessCommand");
+ parent.appendChild(chapterCommandElement);
+
+ QDomElement chapterProcessTimeElement =3D document.createElement("Cha=
pterProcessTime");
+ chapterProcessTimeElement.appendChild(document.createTextNode("2"));
+ chapterCommandElement.appendChild(chapterProcessTimeElement);
+
+ _buf =3D (unsigned char*) realloc(_buf, 1+command_tbl->nr_of_post * 8=
);
+ _buf[0] =3D command_tbl->nr_of_post;
+ memcpy(&_buf[1], command_tbl->post_cmds, command_tbl->nr_of_post * 8)=
;
+
+ QDomElement chapterProcessDataElement =3D CreateDOMElement(document, =
"ChapterProcessData", Utilities::EncodeHex(_buf, 1 + command_tbl->nr_of_p=
ost * 8));
+ chapterProcessDataElement.setAttribute("format", "hex");
+ chapterCommandElement.appendChild(chapterProcessDataElement);
+ }
+
+ free(_buf);
+ }
+}
+
+uint64_t ChapterManager::HandleLanguageUnit(QDomDocument& document, QDom=
Node& parent, const IFOFile& _ifo, int title)
+{
+ static unsigned char _PrivateLU[] =3D {0x2A, 0x00, 0x00, 0x00};
+ uint64_t start_time =3D uint64_t(-1), found_time;
+
+ QDomElement chapterAtomElement;
+ QDomElement chapterDisplayElement;
+ QDomElement chapterStringElement;
+ QDomElement chapterTimeStartElement;
+
+ for (int i =3D 0 ;i < _ifo.LanguageUnits(title)->nr_of_lus; i++)
+ {
+ parent.appendChild(document.createComment("Language Units"));
+
+ chapterAtomElement =3D document.createElement("ChapterAtom");
+ parent.appendChild(chapterAtomElement);
+
+ // the Language Unit for a given language
+ const pgci_lu_t &_LU =3D _ifo.LanguageUnits(title)->lu[i];
+ _PrivateLU[1] =3D _LU.lang_code >> 8;
+ _PrivateLU[2] =3D _LU.lang_code & 0xFF;
+ _PrivateLU[3] =3D _LU.lang_extension;
+
+ chapterAtomElement.appendChild(document.createComment("Language: " + Q=
String(_LU.lang_code >> 8) + QString(_LU.lang_code & 0xFF)));=09
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterUID"=
, Utilities::CreateUID()));
+
+ AddCodecPrivateData(document, chapterAtomElement, _PrivateLU, 4);
+
+ // display the UID for the lazy rippers
+ chapterAtomElement.appendChild(document.createComment("Enter your text=
here"));
+
+ chapterDisplayElement =3D document.createElement("ChapterDisplay");
+ chapterAtomElement.appendChild(chapterDisplayElement);
+
+ chapterStringElement =3D document.createElement("ChapterString");
+ chapterStringElement.appendChild(document.createTextNode("Language Uni=
t for " + QString(_LU.lang_code >> 8) + QString(_LU.lang_code & 0xFF) ));
+ chapterDisplayElement.appendChild(chapterStringElement);
+
+ if (_LU.pgcit)
+ {
+ for (int j =3D 0; j < _LU.pgcit->nr_of_pgci_srp; j++)
+ {
+ const pgci_srp_t &_PGC_SRP =3D _LU.pgcit->pgci_srp[j];
+
+ found_time =3D AddPGC(document, chapterAtomElement, _PGC_SRP.pgc, j,=
_PGC_SRP.entry_id, _ifo.CellsList(title, true), NULL, 0);
+
+ if (start_time > found_time)
+ start_time =3D found_time;
+ }
+ }
+
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterTime=
Start", Utilities::FormatTime(start_time)));
+ }
+
+ return start_time;
+}
+
+
+uint64_t ChapterManager::AddPGC(QDomDocument& document, QDomNode& parent=
, const pgc_t * pgc, uint16_t pgc_num, unsigned char pgc_type, const Cell=
sListType & cell_list, const ttu_t * ptts, int title)
+{
+ static unsigned char _PrivatePGC[] =3D {0x20, 0x00, 0x00, 0x00, 0x00, 0=
x00, 0x00, 0x00};
+ uint64_t start_time =3D uint64_t(-1), found_time;
+
+ parent.appendChild(document.createComment(QString("PGC PGC_%1 type %2")=
.arg(pgc_num+1).arg(GetPGCType(pgc_type))));
+
+ QDomElement chapterAtomElement =3D document.createElement("ChapterAtom"=
);
+ parent.appendChild(chapterAtomElement);
+
+ QString _myUID =3D Utilities::CreateUID();
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterUID",=
_myUID));
+
+ // display the UID for the lazy rippers
+ if (ptts =3D=3D NULL)
+ {
+ chapterAtomElement.appendChild(document.createComment("Enter your text=
here"));
+
+ QDomElement chapterDisplayElement =3D document.createElement("ChapterD=
isplay");
+ chapterDisplayElement.appendChild(CreateDOMElement(document, "ChapterS=
tring", "PGC type " + GetPGCType(pgc_type)));
+ chapterAtomElement.appendChild(chapterDisplayElement);
+ }
+ else
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterFlag=
Hidden", "1"));
+
+ // PGC commands
+ QDomElement chapterProcessElement =3D document.createElement("ChapterPr=
ocess");
+ chapterAtomElement.appendChild(chapterProcessElement);
+
+ _PrivatePGC[1] =3D (pgc_num+1) >> 8;
+ _PrivatePGC[2] =3D (pgc_num+1) & 0xFF;
+ _PrivatePGC[3] =3D pgc_type;
+ _PrivatePGC[4] =3D ((uint8_t*) &pgc->prohibited_ops)[0];
+ _PrivatePGC[5] =3D ((uint8_t*) &pgc->prohibited_ops)[1];
+ _PrivatePGC[6] =3D ((uint8_t*) &pgc->prohibited_ops)[2];
+ _PrivatePGC[7] =3D ((uint8_t*) &pgc->prohibited_ops)[3];
+
+ AddCodecPrivateData(document, chapterProcessElement, _PrivatePGC, 8, fa=
lse);
+ AddPGCCommands(document, chapterProcessElement, pgc->command_tbl);
+
+ // Handle the Programs/Cells in the PGC
+ for (int i=3D0; i< pgc->nr_of_programs; i++)
+ {
+ found_time =3D AddProgram(document, chapterAtomElement, pgc, _myUID, i=
, cell_list, pgc_num, ptts, title);
+
+ if (start_time > found_time)
+ start_time =3D found_time;
+ }
+
+ if (start_time =3D=3D uint64_t(-1))
+ start_time =3D 0;
+
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterTimeS=
tart", Utilities::FormatTime(start_time)));
+
+ return start_time;
+}
+
+
+QString ChapterManager::GetPGCType(unsigned char entry_id)
+{
+ QString result ("0x%1 =3D ");
+ result =3D result.arg(entry_id, 2, 16, QChar('0'));
+
+ if (entry_id & 0x80)
+ result +=3D "Entry + ";
+
+ switch (entry_id & ~0x80)
+ {
+ case 2:
+ result +=3D "Title-Menu";
+ break;
+ case 3:
+ result +=3D "Root Menu";
+ break;
+ case 4:
+ result +=3D "Subpicture Menu";
+ break;
+ case 5:
+ result +=3D "Audio Menu";
+ break;
+ case 6:
+ result +=3D "Angle Menu";
+ break;
+ case 7:
+ result +=3D "Chapter Menu";
+ break;
+ default:
+ result +=3D "Basic PGC";
+ break;
+ }
+
+ return result;
+}
+
+
+uint64_t ChapterManager::AddProgram(QDomDocument& document, QDomNode& pa=
rent, const pgc_t *pgc, const QString& PgcUID, int program_number, const =
CellsListType& cell_list, int16_t pgc_num, const ttu_t *ptts, int title)
+{
+ static unsigned char _PrivatePTT[] =3D {0x10, 0x00};
+ static unsigned char _PrivatePG[] =3D {0x18, 0x00, 0x00};
+ static unsigned char _PrivateCN[] =3D {0x08, 0x00, 0x00, 0x00, 0x00};
+
+ uint64_t start_time =3D uint64_t(-1), end_time =3D 0;
+
+ // for this program
+ int entry_cell_num =3D pgc->program_map[program_number];
+ int program_last_cell_num =3D pgc->nr_of_cells;
+ int next_program_entry_cell_num;
+ if (program_number+1 =3D=3D pgc->nr_of_programs)
+ next_program_entry_cell_num =3D program_last_cell_num+1;
+ else
+ next_program_entry_cell_num =3D pgc->program_map[program_number+1];
+
+ parent.appendChild(document.createComment("Program PGN#" + QString("%1"=
).arg(program_number + 1) + " in this PGC"));
+
+ QDomElement chapterAtomElement =3D document.createElement("ChapterAtom"=
);
+ parent.appendChild(chapterAtomElement);
+
+ QString _myUID =3D Utilities::CreateUID();
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterUID",=
_myUID));
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterFlagH=
idden", "1"));
+
+ _PrivatePG[1] =3D (program_number+1) >> 8;
+ _PrivatePG[2] =3D (program_number+1) & 0xFF;
+ AddCodecPrivateData(document, chapterAtomElement, _PrivatePG, 3);
+
+ if (ptts !=3D NULL)
+ {
+ // find all PTT corresponding to this PGC/PG number
+ for (uint16_t pppt_nr =3D 0; pppt_nr < ptts->nr_of_ptts; pppt_nr++)
+ {
+ // use the start timecode of the first cell
+ const cell_position_t & position =3D pgc->cell_position[entry_cell_nu=
m-1];
+ const CellListElem * cell_elt =3D cell_list.at(position);
+ // TODO: make this test optional (create chapters even without the co=
ntent)
+ if (cell_elt =3D=3D NULL || !cell_elt->found)
+ continue;
+ =09
+ start_time =3D cell_elt->start_time;
+
+ QDomElement chapterAtomParent =3D chapterAtomElement;
+
+ if (ptts->ptt[pppt_nr].pgcn =3D=3D pgc_num+1 && ptts->ptt[pppt_nr].pg=
n =3D=3D program_number+1)
+ {
+ chapterAtomElement.appendChild(document.createComment(QString("Chapt=
er PTT#%1 [%2.%3]").arg(QString::number(pppt_nr+1)).arg(pgc_num+1, 2, 10,=
QChar('0')).arg(program_number+1, 2, 10, QChar('0'))));
+ =09
+ chapterAtomElement =3D document.createElement("ChapterAtom");
+ chapterAtomParent.appendChild(chapterAtomElement);
+
+ chapterAtomElement.appendChild(document.createComment("Enter your te=
xt here"));
+
+ QDomElement chapterDisplayElement =3D document.createElement("Chapte=
rDisplay");
+ chapterDisplayElement.appendChild(CreateDOMElement(document, "Chapte=
rString", QString("Your Name Here For Chapter #%1.%2").arg(QString::numbe=
r(title), QString::number(pppt_nr + 1))));
+ chapterAtomElement.appendChild(chapterDisplayElement);
+
+ QString _myUID =3D Utilities::CreateUID();
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterUI=
D", _myUID));
+
+ _PrivatePTT[1] =3D pppt_nr+1;
+ AddCodecPrivateData(document, chapterAtomElement, _PrivatePTT, 2);
+
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterTi=
meStart", Utilities::FormatTime(start_time)));
+ }
+
+ chapterAtomElement =3D chapterAtomParent;
+ }
+ }
+
+ QDomElement parentChapterAtom =3D chapterAtomElement;
+
+ for (int cell_num =3D entry_cell_num; cell_num<next_program_entry_cell_=
num; cell_num++)
+ {
+ // Output cells
+ const cell_position_t & position =3D pgc->cell_position[cell_num-1];
+ const cell_playback_t & cell =3D pgc->cell_playback[cell_num-1];
+
+ if (cell.block_mode !=3D 0 && cell.block_mode !=3D 3)
+ continue;
+
+ const CellListElem * cell_elt =3D cell_list.at(position);
+ // TODO: make this test optional (create chapters even without the con=
tent)
+ if (cell_elt =3D=3D NULL || !cell_elt->found)
+ continue;
+
+ QString prefix =3D QString("Program %1 Cell CN#%2 ").arg( (cell_num =3D=
=3D entry_cell_num) ? "Entry" : "", QString::number(cell_num));
+ QString middle =3D QString("[%1.%2]").arg(cell_elt->vobid, 2, 10, QCha=
r('0')).arg(cell_elt->cellid);
+ QString suffix =3D QString(" (%1 angles)").arg(cell_num - entry_cell_n=
um + 1);
+
+ if (cell.block_mode) // multi-angle
+ parentChapterAtom.appendChild(document.createComment(prefix + middle =
+ suffix));
+ else
+ parentChapterAtom.appendChild(document.createComment(prefix + middle)=
);
+
+ QDomElement chapterAtomElement =3D document.createElement("ChapterAtom=
");
+ parentChapterAtom.appendChild(chapterAtomElement);
+
+ QString _myUID =3D Utilities::CreateUID();
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterUID"=
, _myUID));
+ chapterAtomElement.appendChild(CreateDOMElement(document, "ChapterFlag=
Hidden", "1"));
+
+ _PrivateCN[1] =3D (position.vob_id_nr) >> 8;
+ _PrivateCN[2] =3D (position.vob_id_nr) & 0xFF;
+ _PrivateCN[3] =3D position.cell_nr;
+ _PrivateCN[4] =3D cell_num - entry_cell_num + 1; // Number of angles
+ AddCodecPrivateData(document, chapterAtomElement, _PrivateCN, 5);
+
+ if (cell.still_time =3D=3D 0xFF) {
+ chapterAtomElement.appendChild(document.createComment("Infinite loop =
Still Cell"));
+
+ // output an additional tag to specify this is cell should loop infin=
itely
+ // post-process command, jump to timecode "st_time"
+ QDomElement chapterProcessElement =3D document.createElement("Chapter=
Process");
+ chapterProcessElement.appendChild(CreateDOMElement(document, "Chapter=
ProcessCodecID", "0"));
+ chapterProcessElement.appendChild(document.createComment("Post comman=
d: replay this cell"));
+ chapterAtomElement.appendChild(chapterProcessElement);
+
+ QDomElement chapterProcessCommand =3D document.createElement("Chapter=
ProcessCommand");
+ chapterProcessCommand.appendChild(CreateDOMElement(document, "Chapter=
ProcessTime", "2"));
+ chapterProcessElement.appendChild(chapterProcessCommand);
+
+ QDomElement chapterProcessDataElement =3D CreateDOMElement(document, =
"ChapterProcessData", "GotoAndPlay(" + PgcUID + ");" );
+ chapterProcessDataElement.setAttribute("format", "ascii");
+ chapterProcessCommand.appendChild(chapterProcessDataElement);
+ } else if (cell.still_time !=3D 0)
+ chapterAtomElement.appendChild(document.createComment(QString("Still =
cell (%1s)").arg(cell.still_time)));
+
+ AddChapterTime(document, chapterAtomElement, cell_elt->start_time, cel=
l_elt->start_time + cell_elt->duration);
+
+ if (end_time < cell_elt->start_time + cell_elt->duration)
+ end_time =3D cell_elt->start_time + cell_elt->duration;
+
+ if (start_time > cell_elt->start_time)
+ start_time =3D cell_elt->start_time;
+ }
+
+ if (start_time =3D=3D uint64_t(-1))
+ start_time =3D 0; // unknown
+
+ parentChapterAtom.appendChild(CreateDOMElement(document, "ChapterTimeSt=
art", Utilities::FormatTime(start_time)));
+
+ return start_time;
+}
\ No newline at end of file
Added: trunk/DvdMenuXtractor/chaptermanager.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/chaptermanager.h 2007-01-22 11:21:16 UTC (rev 1=
269)
+++ trunk/DvdMenuXtractor/chaptermanager.h 2007-01-28 16:48:11 UTC (rev 1=
270)
@@ -0,0 +1,40 @@
+#ifndef CHAPTER_MANAGER_H
+#define CHAPTER_MANAGER_H
+
+#include <QString>
+#include "vobparser/IFOFile.h"
+
+class QDomNode;
+class QDomElement;
+class QDomDocument;
+
+class ChapterManager
+{
+public:
+ ChapterManager(unsigned xmlIdentCount)
+ : INDENT_COUNT(xmlIdentCount)
+ {
+ }
+ bool generateScript(const IFOFile& ifoFile, const QString& filename, ui=
nt16_t title, const QString& editionUID) const;
+ bool generateMenuScript(const IFOFile& ifoFile, const QString& filename=
, uint16_t title, const QString& editionUID) const;
+
+ static QString INFO_SUFFIX;
+ static QString CHAPTER_SUFFIX;
+
+private:
+ void generateInfoScript(const QString& filename, uint16_t title, const =
QString& editionUID) const;
+=09
+ static QDomElement CreateDOMElement(QDomDocument& document, const QStri=
ng& elementName, const QString& content);
+ static void AddChapterTime(QDomDocument& document, QDomNode& parent, ui=
nt64_t start_time, uint64_t end_time);
+ static void AddCodecPrivateData(QDomDocument& document, QDomNode& paren=
t, const unsigned char *buffer, unsigned int size, bool createChapterProc=
essElement =3D true);
+ static void AddPGCCommands(QDomDocument& document, QDomNode& parent, co=
nst pgc_command_tbl_t * command_tbl);
+ static uint64_t AddProgram(QDomDocument& document, QDomNode& parent, co=
nst pgc_t *pgc, const QString& PgcUID, int program_number, const CellsLis=
tType& cell_list, int16_t pgc_num, const ttu_t *ptts, int title);
+ static uint64_t AddPGC(QDomDocument& document, QDomNode& parent, const =
pgc_t * pgc, uint16_t pgc_num, unsigned char pgc_type, const CellsListTyp=
e & cell_list, const ttu_t * ptts, int title);
+ static QString GetPGCType(unsigned char entry_id);
+ static uint64_t HandleLanguageUnit(QDomDocument& document, QDomNode& pa=
rent, const IFOFile& _ifo, int title);
+
+ uint8_t familyUID[16];
+ unsigned INDENT_COUNT;
+};
+
+#endif //CHAPTER_MANAGER_H
\ No newline at end of file
Added: trunk/DvdMenuXtractor/config.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/config.h 2007-01-22 11:21:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/config.h 2007-01-28 16:48:11 UTC (rev 1270)
@@ -0,0 +1,31 @@
+#define CONFIG_STATIC
+//#define CONFIG_UNICODE not because dvdread is not unicode safe
+//#define CONFIG_MULTITHREAD
+//#define CONFIG_MSVCRT
+
+//-----------
+// failsafes
+
+#if !defined(ARM) || defined(TARGET_SYMBIAN)
+#undef CONFIG_WMMX
+#endif
+
+#if !defined(IX86) || defined(TARGET_SYMBIAN)
+#undef CONFIG_MMX
+#endif
+
+#if !defined(CONFIG_UNICODE) && (defined(TARGET_WINCE) || defined(TARGET=
_SYMBIAN))
+#define CONFIG_UNICODE
+#endif
+
+#if defined(CONFIG_MULTITHREAD) && (defined(TARGET_SYMBIAN) || defined(T=
ARGET_PALMOS))
+#undef CONFIG_MULTITHREAD
+#endif
+
+#if defined(CONFIG_UNICODE) && (defined(TARGET_PALMOS) || defined(TARGET=
_LINUX))
+#undef CONFIG_UNICODE
+#endif
+
+#if !defined(CONFIG_STATIC) && defined(TARGET_PALMOS) && defined(IX86)
+#define CONFIG_STATIC
+#endif
Added: trunk/DvdMenuXtractor/dmx.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/dmx.cpp 2007-01-22 11:21:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/dmx.cpp 2007-01-28 16:48:11 UTC (rev 1270)
@@ -0,0 +1,486 @@
+#include "dmx.h"
+#include "utilities.h"
+#include "chaptermanager.h"
+
+#include <QDir>
+#include <QTime>
+#include <QMutexLocker>
+
+DMX::DMX(bool consoleMode)
+ : ifoFile_(0), needsAbort_(false), consoleMode_(consoleMode)
+{
+}
+
+DMX::~DMX()
+{
+ abort();
+
+ QMutex mutex;
+ mutex.lock();
+ delete ifoFile_;
+ ifoFile_ =3D 0;
+ mutex.unlock();
+}
+
+void DMX::abort()
+{
+ QMutex mutex;
+ mutex.lock();
+ needsAbort_ =3D true;
+ mutex.unlock();
+
+ wait();
+}
+
+void DMX::processTitle(int16_t title, int index)
+{
+ const QString editionUID =3D Utilities::CreateUID();
+
+ unsigned stepIndex =3D 0;
+ bool menu =3D ((index < 0) && !title) || ((index >=3D 0) && selection_[=
index].isMenu());
+ VobParser *aVobParser =3D 0;
+ QString str;
+ QString text =3D "Step %1 of 2: %3...";
+
+ do
+ {
+ printf("Treating Title %d %s VOB file(s)\n", title, menu ? "Menu" : ""=
);
+
+ stepIndex =3D 1;
+
+ str =3D text.arg(stepIndex++).arg("Building VOB map");
+ =09
+ if (consoleMode_)
+ printf(qPrintable(str + '\n'));
+ else
+ emit stepChanged(str);
+
+ aVobParser =3D buildVobParser(title, menu);
+
+ str =3D text.arg(stepIndex++).arg("Splitting and demuxing");
+ =09
+ if (consoleMode_)
+ printf(qPrintable(str + '\n'));
+ else
+ emit stepChanged(str);
+ =09
+ demux(aVobParser, index, editionUID, title, menu);
+
+ delete aVobParser;
+ =09
+ menu =3D !menu && ((index < 0) || selection_[index].isMenu());
+ } while (menu && !needsAbort_);
+}
+
+bool DMX::setExtractionParameters(const QString& sourcePath, const QStri=
ng& destinationPath, const QString& toolsPath, const SelectionType& selec=
tedItems)
+{
+ QMutex mutex;
+ QMutexLocker locker (&mutex);
+
+ // set selection
+ selection_ =3D selectedItems;
+
+ // check if require directories exist
+ if (!QFile::exists(sourcePath))
+ {
+ fprintf(stderr, "Input folder '%s' doesn't exist\n", qPrintable(source=
Path));
+ return false;
+ }
+
+ // set source path
+ sourcePath_ =3D sourcePath;
+
+ if (!QFile::exists(toolsPath))
+ {
+ fprintf(stderr, "Tools folder '%s' doesn't exist\n", qPrintable(toolsP=
ath));
+ return false;
+ }
+
+ // set "mkvmerge.exe" path
+ toolsPath_ =3D toolsPath;
+
+ // try to create output
+ if (!QFile::exists(destinationPath))
+ {
+ if (!QDir().mkpath(destinationPath))
+ {
+ fprintf(stderr,"Cannot create output folder: '%s'\n", qPrintable(dest=
inationPath));
+ return false;
+ }
+ else
+ printf("Successfully created output folder: '%s'\n", qPrintable(desti=
nationPath));
+ }
+
+ // set output path
+ destinationPath_ =3D destinationPath;
+
+ return true;
+}
+
+void DMX::run()
+{
+ // try to open input file
+ if (!sourcePath_.size() || !loadIFOFile(sourcePath_))
+ return;
+
+ QMutex mutex;
+ mutex.lock();
+ needsAbort_ =3D false;
+ mutex.unlock();
+
+ if (selection_.size()) // if selection is available
+ {
+ for (size_t index =3D 0; index < selection_.size(); ++index)
+ {
+ int16_t title =3D selection_[index].title();
+ =09
+ if (title >=3D 0)
+ processTitle(title, index);
+ }
+ }=20
+ else // if no selection is available, process all titles
+ {
+ for (int16_t title =3D 0; title <=3D ifoFile_->NumberOfTitles(); ++tit=
le)
+ processTitle(title, -1);
+ }
+}
+
+IFOFile* DMX::OpenIFOFile(const QString& path)
+{
+ IFOFile *file =3D 0;
+ QDir info (path);
+=09
+ try
+ {
+ file =3D new IFOFile(info.absolutePath());
+ }
+ catch(IFOException&)
+ {
+ // TODO : More verbose
+ fprintf(stderr, "Couldn't use input directory as DVD source\n");
+ return 0;
+ }
+
+ return file;
+}
+
+bool DMX::loadIFOFile(const QString& path)
+{
+ QMutex mutex;
+ QMutexLocker locker (&mutex);
+=09
+ // reset last file
+ delete ifoFile_;
+ ifoFile_ =3D OpenIFOFile(path);
+
+ if (ifoFile_ =3D=3D 0)
+ return false;
+
+ return true;
+}
+
+VobParser* DMX::buildVobParser(int16_t title, bool menu)
+{
+ VobParser* parser =3D 0;
+ if (consoleMode_)
+ printf("0%%");
+ else
+ emit progressChanged(0);
+=09
+ try=20
+ {
+ parser =3D new VobParser(qPrintable(sourcePath_), title, menu);
+ } catch (...)
+ {
+ if (consoleMode_)
+ printf("\r\r");
+ =09
+ printf("No VOB file(s) found in %s for Title %d\n", qPrintable(sourceP=
ath_), title);
+ }
+
+ if (consoleMode_)
+ printf("\r\r100%%\n");
+ else
+ emit progressChanged(100);
+=09
+ return parser;
+}
+
+void DMX::demuxAudioTrack(int16_t title, bool isMenu, const AudioTrackLi=
st& _audioTracks, size_t _stream, CompositeDemuxWriter& demuxer, const QS=
tring& filename)
+{
+ if (_stream < 0 || _stream >=3D _audioTracks.size())
+ return;
+
+ static const QString muxArgumentsFormat(" --track-name 0:\"aud-%1\" --l=
anguage 0:%2 --timecodes 0:\"%3_%4.tmc\" \"%3.%4\"");
+
+ const audio_attr_t *_attr =3D _audioTracks[_stream];
+ // get the possible ID for this track for this Cell/PGC
+ uint8_t _ID =3D ifoFile_->GetAudioId(_stream, title, isMenu);
+
+ Writer *_muxer =3D 0;
+=09
+ // if (_attr->lang_code =3D=3D 0)
+ QString lang ("und");
+ QString langSuffix (QString("_%1_un").arg(_ID));
+=09
+ if (_attr->lang_code !=3D 0)
+ {
+ lang =3D QString("%1%2").arg(QString(_attr->lang_code >> 8), QString(_=
attr->lang_code & 0xFF));
+ langSuffix =3D QString("_%1_%2%3").arg(QString::number(_ID), QString(_=
attr->lang_code >> 8), QString(_attr->lang_code & 0xFF));
+ }
+
+ QString muxArguments;
+ QString fullPrefix (destinationPath_ + QDir::separator() + filename + l=
angSuffix);
+
+ switch (_audioTracks[_stream]->audio_format)
+ {
+ case 0:
+ muxArguments =3D muxArgumentsFormat.arg(filename + langSuffix, lang, f=
ullPrefix, "ac3");
+ =09
+ _muxer =3D new AC3DemuxWriter(fullPrefix.toAscii().constData(), 0x80 +=
_ID);
+ if (!demuxer.AddDemuxer(SUBSTREAM_AC3_LOW + _ID, _muxer, muxArguments)=
)
+ delete _muxer;
+ break;
+
+ case 2:
+ case 3:
+ muxArguments =3D muxArgumentsFormat.arg(filename + langSuffix, lang, f=
ullPrefix, "mpa");
+ =09
+ _muxer =3D new MPADemuxWriter(fullPrefix.toAscii().data(), 0xC0 + _ID)=
;
+ if (!demuxer.AddDemuxer(AUDIO_STREAM + _ID, _muxer, muxArguments))
+ delete _muxer;
+ break;
+
+ case 4:
+ // TODO possibly other LPCM formats ?
+ muxArguments =3D muxArgumentsFormat.arg(filename + langSuffix, lang, f=
ullPrefix, "wav");
+ =09
+ _muxer =3D new LPCMDemuxWriter(fullPrefix.toAscii().data(), 0xA0 + _ID=
, 48000, 16, 2);
+ if (!demuxer.AddDemuxer(SUBSTREAM_PCM_LOW + _ID, _muxer, muxArguments)=
)
+ delete _muxer;
+ break;
+
+ case 6:
+ muxArguments =3D muxArgumentsFormat.arg(filename + langSuffix, lang, f=
ullPrefix, "dts");
+ =09
+ _muxer =3D new DTSDemuxWriter(fullPrefix.toAscii().data(), 0x88 + _ID)=
;
+ if (!demuxer.AddDemuxer(SUBSTREAM_DTS_LOW + _ID, _muxer, muxArguments)=
)
+ delete _muxer;
+ break;
+
+ default:
+ fprintf(stderr, "Unknown Audio Format: %d\n", _attr->audio_format);
+ }
+}
+
+void DMX::demuxSubtitleTrack(int16_t title, bool isMenu, const SubtitleT=
rackList& _subTracks, size_t _stream, CompositeDemuxWriter& demuxer, con=
st QString& filename, const uint32_t *_palette, uint16_t _width, uint16_t=
_height)
+{
+ if (_stream < 0 || _stream >=3D _subTracks.size())
+ return;
+
+ static const QString subMuxArgumentsFormat(" --track-name 0:\"sub-%1\" =
--language 0:%2 \"%3\"");
+
+ const subp_attr_t *_attr =3D 0;
+ const QString prefix =3D destinationPath_ + QDir::separator() + filenam=
e;
+
+ // get the possible IDs for this track for this Cell/PGC
+ IdArray _IDs =3D ifoFile_->GetSubsId(_stream, title, isMenu);
+
+ Writer * _muxer =3D 0;
+ QString lang, langSuffix;
+=09
+ for (IdArray::size_type _IDidx=3D0; _IDidx < _IDs.size(); ++_IDidx)
+ {
+ _attr =3D _subTracks[_stream];
+ =09
+ // if (_attr->lang_code =3D=3D 0)
+ lang =3D "und";
+ langSuffix =3D QString("_%1_un").arg(_IDs.at(_IDidx));
+
+ if (_attr->lang_code !=3D 0)
+ {
+ lang =3D QString("%1%2 \"").arg(QString(_attr->lang_code >> 8), QStri=
ng(_attr->lang_code & 0xFF));
+ langSuffix =3D QString("_%1_%2%3").arg(QString::number(_IDs.at(_IDidx=
)), QString(_attr->lang_code >> 8), QString(_attr->lang_code & 0xFF)); =09
+ }
+
+ _muxer =3D new SubDemuxWriter(QString(prefix + langSuffix).toAscii().d=
ata(), 0x20 + _IDs.at(_IDidx), _width, _height, _palette, _attr->lang_cod=
e, _attr->lang_extension =3D=3D 9);
+ if (!demuxer.AddDemuxer(SUBSTREAM_SUB_LOW + _IDs.at(_IDidx), _muxer, s=
ubMuxArgumentsFormat.arg(filename + langSuffix, lang, prefix + langSuffix=
+ ".idx")))
+ delete _muxer;
+ }
+}
+
+void DMX::demux(VobParser *aVobParser, int selectionIndex, const QString=
&editionUID, int16_t title, bool menu)
+{
+ // get list of all cells
+ const CellsListType *CellsList =3D ifoFile_->GetCellsList(title, menu);
+=09
+ if (!CellsList)
+ return;
+
+ static const QString demuxArguments (" --track-name 0:\"video\" --timec=
odes 0:\"%1_m2v.tmc\" \"%1.m2v\"");
+ static const QString btnMuxArgumentsFormat(" --track-name 0:\"btn-%1\" =
--timecodes 0:\"%2_btn.tmc\" \"%2.btn\"");
+=09
+ try
+ {
+ QString filename;
+ QString muxCommand;
+
+ // init filename
+ if (title =3D=3D 0)
+ filename =3D "VMG";
+ else
+ filename =3D QString("VTS%1%2").arg(menu ? "M" : "").arg(title, 2, 10=
, QChar('0'));
+
+ const QString prefix =3D destinationPath_ + QDir::separator() + filena=
me;
+
+ if (aVobParser !=3D 0)
+ {
+ aVobParser->Reset();
+
+ const AudioTrackList & _audioTracks =3D ifoFile_->AudioTracks(title, =
menu);
+ const SubtitleTrackList & _subTracks =3D ifoFile_->SubsTracks(title, =
menu);
+ =09
+ double _fps =3D 0;
+ uint16_t _width =3D 0, _height =3D 0;
+ =09
+ ifoFile_->VideoSize(title, menu, _width, _height, _fps);
+ const uint32_t * _palette =3D ifoFile_->GetPalette(title, menu);
+
+ uint32_t cell =3D 0;
+ CompositeDemuxWriter &demuxer =3D aVobParser->GetDemuxer();
+
+ //emit progressChanged(CellsList->count());
+
+ demuxer.Reset();
+ printf("Processing %s\n", qPrintable(filename));
+
+ if ((selectionIndex < 0) || (selection_[selectionIndex].isVideoEnable=
d()))
+ {
+ Writer *_muxer =3D new VideoDemuxWriter(prefix.toAscii().constData()=
, _fps);
+ if (!demuxer.AddDemuxer(VIDEO_STREAM, _muxer, demuxArguments.arg(pre=
fix)))
+ delete _muxer;
+ }
+
+ size_t _stream =3D 0;
+
+ QString lang;
+ QString langSuffix;
+
+ // decide which audio streams to process
+ if (_audioTracks.size())
+ {
+ if (selectionIndex > -1)
+ {
+ const std::vector<size_t>& selectedAudioTracks =3D selection_[selec=
tionIndex].audioTracks();
+ =09
+ for (size_t index =3D 0; index < selectedAudioTracks.size(); ++inde=
x)
+ {
+ _stream =3D selectedAudioTracks[index];
+ demuxAudioTrack(title, menu, _audioTracks, _stream, demuxer, file=
name);
+ }
+ }
+ else
+ {
+ for (_stream =3D 0; _stream < _audioTracks.size(); ++_stream)
+ demuxAudioTrack(title, menu, _audioTracks, _stream, demuxer, filen=
ame);
+ }
+ }
+
+ // process subtitle streams
+ if (_subTracks.size())
+ {
+ if (selectionIndex > -1)
+ {
+ const std::vector<size_t>& selectedSubTracks =3D selection_[selecti=
onIndex].subtitleTracks();
+
+ for (size_t index =3D 0; index < selectedSubTracks.size(); ++index)
+ {
+ _stream =3D selectedSubTracks[index];
+ demuxSubtitleTrack(title, menu, _subTracks, _stream, demuxer, fil=
ename, _palette, _width, _height);
+ }
+ }
+ else
+ {
+ for (_stream =3D 0; _stream < _subTracks.size(); ++_stream)
+ demuxSubtitleTrack(title, menu, _subTracks, _stream, demuxer, file=
name, _palette, _width, _height);
+ }
+
+ // create a possible button demuxer too
+ Writer *_muxer =3D new BtnDemuxWriter(prefix.toAscii().data(), _widt=
h, _height);
+ if (!demuxer.AddDemuxer(SUBSTREAM_PCI, _muxer, btnMuxArgumentsFormat=
.arg(filename, prefix)))
+ delete _muxer;
+ }
+
+ if (consoleMode_)
+ printf("0%%");
+ else
+ emit progressChanged(0);
+ =09
+ const uint32_t maximum =3D aVobParser->GetPacketCount();
+ =09
+ while(aVobParser->ParseNextPacket(*CellsList) && !needsAbort_)
+ {
+ if (consoleMode_)
+ printf("\r\r\r%d%%", aVobParser->GetPacketIndex() * 100 / maximum);
+ else
+ emit progressChanged(aVobParser->GetPacketIndex() * 100 / maximum);
+ }
+ printf("\n");
+
+ // create the command line using the list of used files
+ // always put video first
+ if (demuxer.FileExists(VIDEO_STREAM))
+ muxCommand +=3D demuxer.GetString(VIDEO_STREAM);
+
+ for (_stream =3D 0; _stream < 256; _stream++)
+ {
+ if (_stream =3D=3D VIDEO_STREAM)
+ continue;
+ =09
+ if (demuxer.FileExists(_stream))
+ muxCommand +=3D demuxer.GetString(_stream);
+ }
+ }
+
+ CellsListType *CellsListDone =3D (CellsListType *)CellsList;
+ CellsListDone->arrange();
+
+ bool addChapters =3D false;
+ ChapterManager chapterEditor(2 /*indent count*/);
+
+ if (menu)
+ addChapters =3D chapterEditor.generateMenuScript(*ifoFile_, prefix, t=
itle, editionUID);
+ else
+ addChapters =3D chapterEditor.generateScript(*ifoFile_, prefix, title=
, editionUID);
+
+ if (addChapters)
+ {
+ muxCommand +=3D " --chapters \"" + prefix + ChapterManager::CHAPTER_S=
UFFIX + "\"";
+ muxCommand +=3D " --segmentinfo \"" + prefix + ChapterManager::INFO_S=
UFFIX + "\"";
+ }
+
+#if defined(WIN32)
+ muxCommand.insert(0, "\"" + toolsPath_ + "\\mkvmerge\" -o \"" + prefix=
+ ".mkv\"");
+#else
+ muxCommand.insert(0, toolsPath_ + "/mkvmerge -o \"" + prefix + ".mkv\"=
");
+#endif
+
+ QFile muxBatchFile(prefix + "_" + QTime::currentTime().toString("hh_mm=
_ss") + ".bat");
+
+ if (!muxBatchFile.open( QIODevice::WriteOnly | QIODevice::Text ))
+ fprintf(stderr, "Could not create batch file\n");
+ =09
+#if !defined(WIN32)
+ QString shellString ("#!/bin/sh\n\n");
+ muxBatchFile.write(shellString.toAscii());
+#endif
+ muxBatchFile.write(muxCommand.toAscii());
+ muxBatchFile.close();
+
+ printf("Done demuxing %s\n", qPrintable(filename));
+ }
+ catch(VobParserException e)
+ {
+ fprintf(stderr, "Vob Parser Exception Occurred: %s\n", e.m_message);
+ }
+}
Added: trunk/DvdMenuXtractor/dmx.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/dmx.h 2007-01-22 11:21:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/dmx.h 2007-01-28 16:48:11 UTC (rev 1270)
@@ -0,0 +1,54 @@
+#ifndef DMX_H
+#define DMX_H
+
+#include <vector>
+#include <QThread>
+#include "dmxselectionitem.h"
+#include "vobparser/IFOFile.h"
+
+class DMX : public QThread
+{
+ Q_OBJECT
+
+public:
+ typedef std::vector<DMXSelectionItem> SelectionType;
+
+ DMX(bool consoleMode =3D false);
+ ~DMX();
+
+ static IFOFile* OpenIFOFile(const QString& path);
+ bool setExtractionParameters(const QString& sourcePath, const QString& =
destinationPath, const QString& toolsPath, const SelectionType& selection=
);
+=09
+signals:
+ // Signal is emitted when the current step progress is changed
+ void progressChanged(int);
+
+ // Signal is emitted when the step is changed
+ void stepChanged(const QString&);
+
+public slots:
+ void abort();
+
+protected:
+ void run();
+
+private:
+ IFOFile *ifoFile_;
+ bool consoleMode_;
+ QString toolsPath_;
+ QString sourcePath_;
+ QString destinationPath_;
+ SelectionType selection_;
+ volatile bool needsAbort_;
+=09
+ bool loadIFOFile(const QString& path);
+ void processTitle(int16_t title, int index);
+
+ VobParser* buildVobParser(int16_t title, bool isMenu);
+=09
+ void demux(VobParser* aVobParser, int selectionIndex, const QString& ed=
itionUID, int16_t title, bool isMenu);
+ void demuxAudioTrack(int16_t title, bool isMenu, const AudioTrackList& =
_audioTracks, size_t _stream, CompositeDemuxWriter& demuxer, const QStrin=
g& filename);
+ void demuxSubtitleTrack(int16_t title, bool isMenu, const SubtitleTrack=
List& _subTracks, size_t _stream, CompositeDemuxWriter& demuxer, const Q=
String& filename, const uint32_t *_palette, uint16_t _width, uint16_t _he=
ight);
+};
+
+#endif // DMX_H
Added: trunk/DvdMenuXtractor/dmx.ico
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
(Binary files differ)
Property changes on: trunk/DvdMenuXtractor/dmx.ico
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/DvdMenuXtractor/dmx.rc
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/dmx.rc 2007-01-22 11:21:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/dmx.rc 2007-01-28 16:48:11 UTC (rev 1270)
@@ -0,0 +1,2 @@
+IDI_ICON1 ICON DISCARDABLE "dmx.ico"
+
Added: trunk/DvdMenuXtractor/dmxconsole.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/dmxconsole.cpp 2007-01-22 11:21:16 UTC (rev 126=
9)
+++ trunk/DvdMenuXtractor/dmxconsole.cpp 2007-01-28 16:48:11 UTC (rev 127=
0)
@@ -0,0 +1,121 @@
+#include <iostream>
+
+#include "utilities.h"
+#include "dmxconsole.h"
+
+DMXConsole::~DMXConsole()
+{
+}
+
+DMXConsole::DMXConsole(char *arguments[], int argumentCount)
+{
+ ready_ =3D true;
+
+ if ((argumentCount !=3D 7) && (argumentCount !=3D 9))
+ {
+ ShowUsage();
+ ready_ =3D false;
+ return;
+ }
+
+ QString argument;
+=09
+ for (int i =3D 1; i < argumentCount; ++i)
+ {
+ argument =3D arguments[i];
+
+ if (argument =3D=3D "-h")
+ {
+ ShowUsage();
+ ready_ =3D false;
+ return;
+ }
+ else if (argument =3D=3D "-i")
+ sourcePath_ =3D arguments[++i];
+ else if (argument =3D=3D "-o")
+ destinationPath_ =3D arguments[++i];
+ else if (argument =3D=3D "-t")
+ toolsPath_ =3D arguments[++i];
+ else if (argument =3D=3D "-s")
+ selectionItems_ =3D generateSelectionItems(QString(arguments[++i]));
+ else
+ {
+ std::cout << "ERROR: Unknown option was specified" << std::endl;
+ DMXConsole::ShowUsage();
+ ready_ =3D false;
+ return;
+ }
+ }
+}
+
+DMX::SelectionType DMXConsole::generateSelectionItems(const QString& sel=
ectionString)
+{
+ QString item;
+ QStringList subItems;
+ DMX::SelectionType selectionItems;
+
+ // split string using ";" as delimeter into selection item string
+ QStringList items =3D selectionString.split(";");
+
+ // procfess each substring
+ for (int index =3D 0; index < items.size(); ++index)
+ {
+ item =3D items.at(index);
+
+ // split subitems into smaller parts using "," as delimeter
+ subItems =3D item.split(",");
+
+ // now check if we have all the components
+ if (subItems.size() =3D=3D ITEM_COUNT)
+ {
+ DMXSelectionItem item(subItems.at(TITLE_INDEX).toInt(),=20
+ subItems.at(MENU_INDEX).toInt(),
+ subItems.at(VIDEO_INDEX).toInt());
+
+ // add audio tracks
+ QStringList trackList =3D extractTrackNumbers(subItems.at(1));
+ foreach (QString trackStr, trackList)
+ item.addAudioTrack(trackStr.toUInt());
+
+ // add subtitle tracks
+ trackList =3D extractTrackNumbers(subItems.at(2));
+ foreach (QString trackStr, trackList)
+ item.addSubtitleTrack(trackStr.toUInt());
+
+ selectionItems.push_back(item);
+ }
+ else
+ fprintf(stderr, "WARNING: Incorrect selection item at index %d was fo=
und\n", index);
+ }
+
+ return selectionItems;
+}
+
+QStringList DMXConsole::extractTrackNumbers(const QString& trackNumberSt=
ring)
+{
+ if ( trackNumberString.size() <=3D 2 )
+ return QStringList();
+
+ return trackNumberString.mid(1, trackNumberString.size() - 1).split(","=
);
+}
+
+void DMXConsole::extract()
+{
+ if (ready_)
+ {
+ DMX extractor (true);
+ extractor.setExtractionParameters(sourcePath_, destinationPath_, tools=
Path_, selectionItems_);
+ extractor.start();
+ extractor.wait();
+ }
+}
+
+void DMXConsole::ShowUsage()
+{
+ std::cout << "USAGE: DvdMenuExtractor [<options>]\n\n"
+ << " Show usage: -h\n"
+ << " Specify folders: -i <dir> -o <dir> -t <dir>\n"
+ << " Specify selection: -s title, extractMenu, extractVideo, {audi=
oTracks}, {subTracks};..."
+ << std::endl;
+}
+
Added: trunk/DvdMenuXtractor/dmxconsole.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/dmxconsole.h 2007-01-22 11:21:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/dmxconsole.h 2007-01-28 16:48:11 UTC (rev 1270)
@@ -0,0 +1,30 @@
+#ifndef DMXCONSOLE_H
+#define DMXCONSOLE_H
+
+#include "dmx.h"
+
+class DMXConsole
+{
+public:
+ DMXConsole(char *arguments[], int argumentCount);
+ ~DMXConsole();
+
+ void extract();
+
+ static void ShowUsage();
+
+private:
+ bool ready_;
+ QString toolsPath_;
+ QString sourcePath_;
+ QString destinationPath_;
+ DMX::SelectionType selectionItems_;
+
+ enum {TITLE_INDEX =3D 0, MENU_INDEX, VIDEO_INDEX,
+ AUDIO_TRACKS_INDEX, SUBTITLE_TRACKS_INDEX, ITEM_COUNT};
+=09
+ QStringList extractTrackNumbers(const QString& trackNumberString);
+ DMX::SelectionType generateSelectionItems(const QString& selectionStrin=
g);
+};
+
+#endif // DMXCONSOLE_H
Added: trunk/DvdMenuXtractor/dmxlogwidget.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/dmxlogwidget.cpp 2007-01-22 11:21:16 UTC (rev 1=
269)
+++ trunk/DvdMenuXtractor/dmxlogwidget.cpp 2007-01-28 16:48:11 UTC (rev 1=
270)
@@ -0,0 +1,47 @@
+#include <QFile>
+#include <QCloseEvent>
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QTextStream>
+
+#include "dmxlogwidget.h"
+
+DMXLogWidget::DMXLogWidget(QWidget *parent)
+ : QWidget(0)
+{
+ ui.setupUi(this);
+ setWindowFlags(windowFlags() | Qt::Tool);
+
+ //setup slots
+ connect(ui.saveButton, SIGNAL(clicked()), this, SLOT(saveButtonClicked(=
)));
+}
+
+DMXLogWidget::~DMXLogWidget()
+{
+
+}
+
+void DMXLogWidget::closeEvent(QCloseEvent *event)
+{
+ emit closed();
+ event->accept();
+}
+
+void DMXLogWidget::saveButtonClicked()
+{
+ QString filename =3D QFileDialog::getSaveFileName(this, "Save as...");
+
+ if (filename.size())
+ {
+ QFile output (filename);
+ if (!output.open(QIODevice::WriteOnly | QIODevice::Text))
+ {
+ QMessageBox::critical(this, "Error", "Could not open file for writing=
");
+ return;
+ }
+
+ QTextStream out (&output);
+ out << ui.textEdit->toPlainText();
+ }
+}
+
Added: trunk/DvdMenuXtractor/dmxlogwidget.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/dmxlogwidget.h 2007-01-22 11:21:16 UTC (rev 126=
9)
+++ trunk/DvdMenuXtractor/dmxlogwidget.h 2007-01-28 16:48:11 UTC (rev 127=
0)
@@ -0,0 +1,28 @@
+#ifndef DMXLOGWIDGET_H
+#define DMXLOGWIDGET_H
+
+#include <QWidget>
+#include "ui_dmxlogwidget.h"
+
+class DMXLogWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ DMXLogWidget(QWidget *parent =3D 0);
+ ~DMXLogWidget();
+
+signals:
+ void closed();
+
+protected:
+ virtual void closeEvent(QCloseEvent *event);
+
+private slots:
+ void saveButtonClicked();
+
+private:
+ Ui::DMXLogWidgetClass ui;
+};
+
+#endif // DMXLOGWIDGET_H
Added: trunk/DvdMenuXtractor/dmxlogwidget.ui
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/dmxlogwidget.ui 2007-01-22 11:21:16 UTC (rev 12=
69)
+++ trunk/DvdMenuXtractor/dmxlogwidget.ui 2007-01-28 16:48:11 UTC (rev 12=
70)
@@ -0,0 +1,118 @@
+<ui version=3D"4.0" >
+ <class>DMXLogWidgetClass</class>
+ <widget class=3D"QWidget" name=3D"DMXLogWidgetClass" >
+ <property name=3D"geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>468</width>
+ <height>213</height>
+ </rect>
+ </property>
+ <property name=3D"windowTitle" >
+ <string>Log</string>
+ </property>
+ <layout class=3D"QVBoxLayout" >
+ <property name=3D"margin" >
+ <number>9</number>
+ </property>
+ <property name=3D"spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class=3D"LogTextEdit" name=3D"textEdit" >
+ <property name=3D"readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class=3D"QHBoxLayout" >
+ <property name=3D"margin" >
+ <number>0</number>
+ </property>
+ <property name=3D"spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class=3D"QPushButton" name=3D"clearButton" >
+ <property name=3D"text" >
+ <string>C&lear</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class=3D"QPushButton" name=3D"saveButton" >
+ <property name=3D"text" >
+ <string>&Save</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name=3D"orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name=3D"sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class=3D"QPushButton" name=3D"closeButton" >
+ <property name=3D"text" >
+ <string>&Close</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing=3D"6" margin=3D"11" />
+ <customwidgets>
+ <customwidget>
+ <class>LogTextEdit</class>
+ <extends>QTextEdit</extends>
+ <header>logtextedit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>clearButton</sender>
+ <signal>clicked()</signal>
+ <receiver>textEdit</receiver>
+ <slot>clear()</slot>
+ <hints>
+ <hint type=3D"sourcelabel" >
+ <x>62</x>
+ <y>202</y>
+ </hint>
+ <hint type=3D"destinationlabel" >
+ <x>39</x>
+ <y>169</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>closeButton</sender>
+ <signal>clicked()</signal>
+ <receiver>DMXLogWidgetClass</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type=3D"sourcelabel" >
+ <x>410</x>
+ <y>192</y>
+ </hint>
+ <hint type=3D"destinationlabel" >
+ <x>312</x>
+ <y>178</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
Added: trunk/DvdMenuXtractor/dmxselectionitem.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/dmxselectionitem.cpp 2007-01-22 11:21:16 UTC (r=
ev 1269)
+++ trunk/DvdMenuXtractor/dmxselectionitem.cpp 2007-01-28 16:48:11 UTC (r=
ev 1270)
@@ -0,0 +1,71 @@
+#include <algorithm>
+#include "dmxselectionitem.h"
+
+DMXSelectionItem::DMXSelectionItem(int16_t title, bool isMenu, bool enab=
leVideo =3D 1)
+ : title_(title), menu_(isMenu), videoEnabled_(enableVideo)
+{
+ // override for VMG
+ if (!title)
+ menu_ =3D true;
+}
+
+DMXSelectionItem::~DMXSelectionItem()
+{
+}
+
+int16_t DMXSelectionItem::title() const
+{
+ return title_;
+}
+
+bool DMXSelectionItem::isMenu() const
+{
+ return menu_;
+}
+
+bool DMXSelectionItem::isVideoEnabled() const
+{
+ return videoEnabled_;
+}
+
+const DMXSelectionItem::TracksContainerType& DMXSelectionItem::audioTrac=
ks() const
+{
+ return audioTracks_;
+}
+
+const DMXSelectionItem::TracksContainerType& DMXSelectionItem::subtitleT=
racks() const
+{
+ return subtitleTracks_;
+}
+
+void DMXSelectionItem::disableVideo()
+{
+ videoEnabled_ =3D false;
+}
+
+bool DMXSelectionItem::addAudioTrack(size_t trackIndex)
+{
+ // check if audio track was already selected
+ if (std::count(audioTracks_.begin(), audioTracks_.end(), trackIndex) =3D=
=3D 0)
+ {
+ audioTracks_.push_back(trackIndex);
+ return true;
+ }
+
+ return false;
+}
+
+bool DMXSelectionItem::addSubtitleTrack(size_t trackIndex)
+{
+ // check if audio track was already selected
+ if (std::count(subtitleTracks_.begin(), subtitleTracks_.end(), trackInd=
ex) =3D=3D 0)
+ {
+ subtitleTracks_.push_back(trackIndex);
+ return true;
+ }
+
+ return false;
+}
+
+
+
Added: trunk/DvdMenuXtractor/dmxselectionitem.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/dmxselectionitem.h 2007-01-22 11:21:16 UTC (rev=
1269)
+++ trunk/DvdMenuXtractor/dmxselectionitem.h 2007-01-28 16:48:11 UTC (rev=
1270)
@@ -0,0 +1,38 @@
+#ifndef DMX_SELECTION_ITEM
+#define DMX_SELECTION_ITEM
+
+#include <vector>
+#include <stdint.h>
+
+// Denotes each selected title
+class DMXSelectionItem
+{
+public:
+
+ typedef std::vector<size_t> TracksContainerType;
+
+ DMXSelectionItem(int16_t title, bool isMenu, bool enableVideo);
+ ~DMXSelectionItem();
+
+ // Getters
+ bool isMenu() const;
+ int16_t title() const;
+ bool isVideoEnabled() const;
+ const TracksContainerType& audioTracks() const;
+ const TracksContainerType& subtitleTracks() const;
+
+ void disableVideo();
+ bool addAudioTrack(size_t trackIndex);
+ bool addSubtitleTrack(size_t trackIndex);
+
+private:
+ int16_t title_;
+ bool menu_;
+ bool videoEnabled_;
+
+ TracksContainerType audioTracks_;
+ TracksContainerType subtitleTracks_;
+};
+
+
+#endif // DMX_SELECTION_ITEM
\ No newline at end of file
Added: trunk/DvdMenuXtractor/dmxselectiontree.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/dmxselectiontree.cpp 2007-01-22 11:21:16 UTC (r=
ev 1269)
+++ trunk/DvdMenuXtractor/dmxselectiontree.cpp 2007-01-28 16:48:11 UTC (r=
ev 1270)
@@ -0,0 +1,136 @@
+#include "dmxselectiontree.h"
+#include "selectiontreeitem.h"
+#include "selectiontreesubitem.h"
+
+DMXSelectionTree::DMXSelectionTree(QWidget *parent)
+: QTreeWidget(parent), ifoFile_(0)
+{
+ setColumnCount(1);
+ setHeaderLabels(QStringList("DVD"));
+ setAlternatingRowColors(true);
+}
+
+DMXSelectionTree::~DMXSelectionTree()
+{
+ delete ifoFile_;
+ ifoFile_ =3D 0;
+}
+
+bool DMXSelectionTree::loadIFOFile(const QString &path)
+{
+ clear();
+ setHeaderLabels(QStringList(QString("DVD - %1").arg(path)));
+
+ // reset last file
+ delete ifoFile_;
+ ifoFile_ =3D DMX::OpenIFOFile(path);
+
+ if (ifoFile_ =3D=3D 0)
+ return false;
+
+ bool menu =3D false;
+ SelectionTreeItem *item =3D 0;
+ SelectionTreeSubItem *subItem =3D 0;
+ QTreeWidgetItem *videoStreamItem =3D 0;
+ QTreeWidgetItem *audioTrackItem =3D 0;
+ QTreeWidgetItem *subtitleTrackItem =3D 0;
+
+ for (int16_t title =3D 0; title <=3D ifoFile_->NumberOfTitles(); ++titl=
e)
+ {
+ menu =3D !title;
+
+ do
+ {
+ item =3D new SelectionTreeItem(this, title, menu);
+
+ // add video stream item
+ videoStreamItem =3D new QTreeWidgetItem(item, QStringList("Video Stre=
am"));
+ videoStreamItem->setFlags(videoStreamItem->flags() | Qt::ItemIsTrista=
te);
+ videoStreamItem->setCheckState(0, Qt::Checked);
+
+ // get audio tracks
+ const AudioTrackList& audioTracks =3D ifoFile_->AudioTracks(title, me=
nu);
+
+ if (audioTracks.size())
+ {
+ audioTrackItem =3D new QTreeWidgetItem(item, QStringList("Audio Trac=
ks"));
+ audioTrackItem->setFlags(audioTrackItem->flags() | Qt::ItemIsTristat=
e);
+ audioTrackItem->setCheckState(0, Qt::Checked);
+
+ for (size_t index =3D 0; index < audioTracks.size(); ++index)
+ subItem =3D new SelectionTreeSubItem(audioTrackItem, *item, index, =
SelectionTreeSubItem::AUDIO_TRACK);
+ }
+ =09
+ // get subtitle tracks
+ const SubtitleTrackList& subTracks =3D ifoFile_->SubsTracks(title, me=
nu);
+
+ if (subTracks.size())
+ {
+ subtitleTrackItem =3D new QTreeWidgetItem(item, QStringList("Subtitl=
e Tracks"));
+ subtitleTrackItem->setFlags(subtitleTrackItem->flags() | Qt::ItemIsT=
ristate);
+ subtitleTrackItem->setCheckState(0, Qt::Checked);
+
+ for (size_t index =3D 0; index < subTracks.size(); ++index)
+ subItem =3D new SelectionTreeSubItem(subtitleTrackItem, *item, inde=
x, SelectionTreeSubItem::SUBTITLE_TRACK);
+ }
+ =09
+ menu =3D !menu;
+ } while (menu);
+ }
+
+ return true;
+}
+
+DMX::SelectionType DMXSelectionTree::getSelection() const
+{
+ DMX::SelectionType selection;
+ QTreeWidgetItem *trackListItem =3D 0;
+
+ for (int index =3D 0; index < topLevelItemCount(); ++index)
+ {
+ // if processing title item
+ if ( SelectionTreeItem *item =3D dynamic_cast<SelectionTreeItem*>(topL=
evelItem(index)) )
+ {
+ // if the title item is (partially) checked
+ if (item->checkState(0) !=3D Qt::Unchecked)
+ {
+ // create selection item instance
+ DMXSelectionItem selectionItem(item->title(), item->isMenuItem(), tr=
ue);
+
+ // check if video stream is selected
+ if ((item->childCount() > 0) && (item->child(0)->checkState(0) =3D=3D=
Qt::Unchecked))
+ selectionItem.disableVideo();
+
+ for (int index =3D 0; index < item->childCount(); ++index)
+ {
+ trackListItem =3D item->child(index);
+
+ // check if track list item is checked
+ if (item->checkState(0) !=3D Qt::Unchecked)
+ {
+ for (int index =3D 0; index < trackListItem->childCount(); ++index=
)
+ {
+ // process track subitem
+ if (SelectionTreeSubItem *subItem =3D dynamic_cast<SelectionTreeS=
ubItem*>(trackListItem->child(index)))
+ {
+ // if sub item is checked
+ if (subItem->checkState(0) =3D=3D Qt::Checked)
+ {
+ if (subItem->type() =3D=3D SelectionTreeSubItem::AUDIO_TRACK)
+ selectionItem.addAudioTrack(subItem->index());
+
+ if (subItem->type() =3D=3D SelectionTreeSubItem::SUBTITLE_TRACK=
)
+ selectionItem.addSubtitleTrack(subItem->index());
+ }
+ }
+ }
+ }
+ }
+
+ selection.push_back(selectionItem);
+ }
+ }
+ }
+
+ return selection;
+}
\ No newline at end of file
Added: trunk/DvdMenuXtractor/dmxselectiontree.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/dmxselectiontree.h 2007-01-22 11:21:16 UTC (rev=
1269)
+++ trunk/DvdMenuXtractor/dmxselectiontree.h 2007-01-28 16:48:11 UTC (rev=
1270)
@@ -0,0 +1,22 @@
+#ifndef DMX_SELECTIONTREE_H
+#define DMX_SELECTIONTREE_H
+
+#include "dmx.h"
+#include <QTreeWidget>
+
+class DMXSelectionTree : public QTreeWidget
+{
+ Q_OBJECT
+
+public:
+ DMXSelectionTree(QWidget *parent);
+ ~DMXSelectionTree();
+
+ DMX::SelectionType getSelection() const;
+ bool loadIFOFile(const QString& path);
+
+private:
+ IFOFile *ifoFile_;
+};
+
+#endif // DMX_SELECTIONTREE_H
Added: trunk/DvdMenuXtractor/dmxwizard.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/dmxwizard.cpp 2007-01-22 11:21:16 UTC (rev 1269=
)
+++ trunk/DvdMenuXtractor/dmxwizard.cpp 2007-01-28 16:48:11 UTC (rev 1270=
)
@@ -0,0 +1,247 @@
+#include <QSettings>
+#include <QDirModel>
+#include <QFileDialog>
+#include <QCloseEvent>
+
+#include "dmxwizard.h"
+
+DMXWizard::DMXWizard(QWidget *parent)
+ : QDialog(parent), logWidget_(this)
+{
+ ui.setupUi(this);
+
+ setupSlots();
+ loadSettings();
+
+ // set first page
+ ui.stackedWidget->setCurrentIndex(SETTINGS_PAGE_INDEX);
+ ui.infoLabel->setText(tr("Welcome to DVD Menu Extraction Wizard!\nThe W=
izard will guide You through the extraction process"));
+}
+
+DMXWizard::~DMXWizard()
+{
+ storeSettings();
+}
+void DMXWizard::pathEditTextChanged(const QString& path)
+{
+ bool ready =3D true;
+
+ // set default styles
+ QPalette palette =3D ui.dvdPathEdit->palette();
+ palette.setColor(QPalette::Base, Qt::white);
+ ui.dvdPathEdit->setPalette(palette);
+ ui.toolsPathEdit->setPalette(palette);
+ ui.outputPathEdit->setPalette(palette);
+
+ // hide all message and image labels
+ ui.errorInfoLabel->clear();
+ ui.warningInfoLabel->clear();
+ ui.errorImageLabel->hide();
+ ui.warningImageLabel->hide();
+
+ // set background to "red" if incorrect paths are specified
+ // and show corresponding message
+ if (!QFile::exists(ui.dvdPathEdit->text()))
+ {=09
+ palette.setColor(QPalette::Base, Qt::red);
+ ui.dvdPathEdit->setPalette(palette);
+ ready =3D false;
+ }
+
+ if (!QFile::exists(ui.toolsPathEdit->text()))
+ {=09
+ palette.setColor(QPalette::Base, Qt::red);
+ ui.toolsPathEdit->setPalette(palette);
+ ready =3D false;
+ }
+
+ if (!ui.outputPathEdit->text().size())
+ {
+ palette.setColor(QPalette::Base, Qt::red);
+ ui.outputPathEdit->setPalette(palette);
+ ready =3D false;
+ }
+ else if (QFile::exists(ui.outputPathEdit->text())) // just a warning in=
case the output folder exists
+ {
+ palette.setColor(QPalette::Base, Qt::yellow);
+ ui.outputPathEdit->setPalette(palette);
+ =09
+ ui.warningImageLabel->show();
+ ui.warningInfoLabel->setText(tr("Specified path already exists"));
+ }
+
+ // show error info if needed
+ if (!ready)
+ {
+ ui.errorImageLabel->show();
+ ui.errorInfoLabel->setText(tr("Missing or incorrect path was specified=
"));
+ }
+
+ ui.nextButton->setEnabled(ready);
+}
+
+void DMXWizard::browseButtonClicked()
+{
+ QString directory =3D QFileDialog::getExistingDirectory(this, "Select d=
irectory...");
+
+ if (!directory.size())
+ return;
+
+ if (QPushButton *senderObject =3D dynamic_cast<QPushButton*>(sender()))
+ {
+ if (senderObject =3D=3D ui.dvdBrowseButton)
+ {
+ if (!(directory.endsWith('/') || directory.endsWith('\\')))
+ directory.append('/');
+
+ ui.dvdPathEdit->setText(directory);
+ }
+ else if (senderObject =3D=3D ui.outputBrowseButton)
+ ui.outputPathEdit->setText(directory);
+ else if (senderObject =3D=3D ui.toolsBrowseButton)
+ ui.toolsPathEdit->setText(directory);
+ }
+}
+
+void DMXWizard::loadSettings()
+{
+ QSettings settings ("DMX", "MatroskaTeam");
+ ui.dvdPathEdit->setText(settings.value("Wizard/DVDPath").toString());
+ ui.outputPathEdit->setText(settings.value("Wizard/OutputPath").toString=
());
+ ui.toolsPathEdit->setText(settings.value("Wizard/ToolsPath").toString()=
);
+}
+
+void DMXWizard::storeSettings()
+{
+ QSettings settings ("DMX", "MatroskaTeam");
+ settings.setValue("Wizard/DVDPath", ui.dvdPathEdit->text());
+ settings.setValue("Wizard/OutputPath", ui.outputPathEdit->text());
+ settings.setValue("Wizard/ToolsPath", ui.toolsPathEdit->text());
+}
+
+void DMXWizard::setupSlots()
+{
+ // setup slots for buttons
+ connect(ui.backButton, SIGNAL(clicked()), this, SLOT(backButtonClicked(=
)));
+ connect(ui.nextButton, SIGNAL(clicked()), this, SLOT(nextButtonClicked(=
)));
+ connect(ui.stopButton, SIGNAL(clicked()), &dmx, SLOT(abort()));
+ connect(ui.dvdBrowseButton, SIGNAL(clicked()), this, SLOT(browseButtonC=
licked()));
+ connect(ui.outputBrowseButton, SIGNAL(clicked()), this, SLOT(browseButt=
onClicked()));
+ connect(ui.toolsBrowseButton, SIGNAL(clicked()), this, SLOT(browseButto=
nClicked()));
+
+ // setup slots for edits
+ connect(ui.dvdPathEdit, SIGNAL(textChanged(const QString&)), this, SLOT=
(pathEditTextChanged(const QString&)));
+ connect(ui.outputPathEdit, SIGNAL(textChanged(const QString&)), this, S=
LOT(pathEditTextChanged(const QString&)));
+ connect(ui.toolsPathEdit, SIGNAL(textChanged(const QString&)), this, SL=
OT(pathEditTextChanged(const QString&)));
+
+ // setup log widget
+ connect(ui.logButton, SIGNAL(toggled(bool)), &logWidget_, SLOT(setVisib=
le(bool)));
+ connect(&logWidget_, SIGNAL(closed()), ui.logButton, SLOT(toggle()));
+
+ // setup slots for extraction
+ connect(&dmx, SIGNAL(finished()), this, SLOT(extractionFinished()));
+ connect(&dmx, SIGNAL(progressChanged(int)), ui.progressBar, SLOT(setVal=
ue(int)));
+ connect(&dmx, SIGNAL(stepChanged(const QString&)), this, SLOT(extractio=
nStepChanged(const QString&)));
+}
+
+void DMXWizard::nextButtonClicked()
+{
+ if (ui.stackedWidget->currentIndex() =3D=3D SETTINGS_PAGE_INDEX)
+ {
+ // try to load DVD IFO
+ if (!ui.selectionTree->loadIFOFile(ui.dvdPathEdit->text()))
+ ui.nextButton->setEnabled(false);
+
+ // set button states
+ ui.backButton->setEnabled(true);
+
+ // turn to the "selection page"
+ ui.stackedWidget->setCurrentIndex(SELECTION_PAGE_INDEX);
+ }
+ else if (ui.stackedWidget->currentIndex() =3D=3D SELECTION_PAGE_INDEX)
+ {
+ ui.nextButton->setEnabled(false);
+
+ // turn to the "extraction page"
+ ui.stackedWidget->setCurrentIndex(EXTRACTION_PAGE_INDEX);
+
+ // get selection
+ DMX::SelectionType selection =3D ui.selectionTree->getSelection();
+ if (selection.size())
+ {
+ // unhide
+ ui.stopButton->show();
+ ui.progressBar->show();
+
+ // set button states
+ ui.backButton->setEnabled(false);
+ ui.stopButton->setEnabled(true);
+
+ ui.progressInfoLabel->setText(tr("Please wait...\nYou can stop the pr=
ocess at any moment by clicking the \"Stop\" button."));
+
+ dmx.setExtractionParameters(ui.dvdPathEdit->text(), ui.outputPathEdit=
->text(),
+ ui.toolsPathEdit->text(), ui.selectionTree->getSelection());
+
+ dmx.start();
+ }
+ else // nothing was selected
+ {
+ ui.stopButton->hide();
+ ui.progressBar->hide();
+ ui.progressInfoLabel->clear();
+
+ ui.stepInfoLabel->setText(tr("Nothing was selected, nothing to do..."=
));
+ =09
+ ui.backButton->setEnabled(true);
+ ui.stopButton->setEnabled(false);
+ }
+ }
+}
+
+void DMXWizard::backButtonClicked()
+{
+ // if going back from the "selection page"
+ if (ui.stackedWidget->currentIndex() =3D=3D SELECTION_PAGE_INDEX)
+ {
+ // set button states
+ ui.backButton->setEnabled(false);
+ ui.nextButton->setEnabled(true);
+
+ ui.stackedWidget->setCurrentIndex(SETTINGS_PAGE_INDEX);
+ }
+ else if (ui.stackedWidget->currentIndex() =3D=3D EXTRACTION_PAGE_INDEX)
+ {
+ // set button states
+ ui.backButton->setEnabled(true);
+ ui.nextButton->setEnabled(true);
+
+ ui.stackedWidget->setCurrentIndex(SELECTION_PAGE_INDEX);
+ }
+}
+
+void DMXWizard::extractionFinished()
+{
+ // set button states
+ ui.backButton->setEnabled(true);
+ ui.stopButton->setEnabled(false);
+
+ // chage text
+ ui.stepInfoLabel->setText("Extraction finished!");
+}
+
+void DMXWizard::extractionStepChanged(const QString &text)
+{
+ ui.stepInfoLabel->setText(text);
+=09
+ // send the message to the log
+ printf(qPrintable(text + '\n'));
+}
+
+void DMXWizard::closeEvent(QCloseEvent *evt)
+{
+ // stop extraction if in progress before quitting
+ if (dmx.isRunning())
+ dmx.abort();
+
+ evt->accept();
+}
\ No newline at end of file
Added: trunk/DvdMenuXtractor/dmxwizard.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/dmxwizard.h 2007-01-22 11:21:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/dmxwizard.h 2007-01-28 16:48:11 UTC (rev 1270)
@@ -0,0 +1,40 @@
+#ifndef DMXWIZARD_H
+#define DMXWIZARD_H
+
+#include <QDialog>
+#include "ui_dmxwizard.h"
+#include "dmxlogwidget.h"
+
+class DMXWizard : public QDialog
+{
+ Q_OBJECT
+
+public:
+ DMXWizard(QWidget *parent =3D 0);
+ ~DMXWizard();
+
+protected:
+ void closeEvent(QCloseEvent* evt);
+
+private slots:
+ void backButtonClicked();
+ void nextButtonClicked();
+ void browseButtonClicked();
+ void extractionFinished();
+ void pathEditTextChanged(const QString& path);
+ void extractionStepChanged(const QString& text);
+
+private:
+ Ui::DMXWizardClass ui;
+=09
+ DMX dmx;
+ DMXLogWidget logWidget_;
+
+ enum {SETTINGS_PAGE_INDEX =3D 0, SELECTION_PAGE_INDEX, EXTRACTION_PAGE_=
INDEX};
+
+ void setupSlots();
+ void loadSettings();
+ void storeSettings();
+};
+
+#endif // DMXWIZARD_H
Added: trunk/DvdMenuXtractor/dmxwizard.qrc
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/dmxwizard.qrc 2007-01-22 11:21:16 UTC (rev 1269=
)
+++ trunk/DvdMenuXtractor/dmxwizard.qrc 2007-01-28 16:48:11 UTC (rev 1270=
)
@@ -0,0 +1,11 @@
+<RCC>
+ <qresource prefix=3D"/DMXWizard" >
+ <file>Resources/back.png</file>
+ <file>Resources/dmx.png</file>
+ <file>Resources/error.png</file>
+ <file>Resources/log.png</file>
+ <file>Resources/next.png</file>
+ <file>Resources/quit.png</file>
+ <file>Resources/warning.png</file>
+ </qresource>
+</RCC>
Added: trunk/DvdMenuXtractor/dmxwizard.ui
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/dmxwizard.ui 2007-01-22 11:21:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/dmxwizard.ui 2007-01-28 16:48:11 UTC (rev 1270)
@@ -0,0 +1,514 @@
+<ui version=3D"4.0" >
+ <class>DMXWizardClass</class>
+ <widget class=3D"QDialog" name=3D"DMXWizardClass" >
+ <property name=3D"geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>500</width>
+ <height>416</height>
+ </rect>
+ </property>
+ <property name=3D"windowTitle" >
+ <string>DMXWizard</string>
+ </property>
+ <layout class=3D"QVBoxLayout" >
+ <property name=3D"margin" >
+ <number>9</number>
+ </property>
+ <property name=3D"spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class=3D"QFrame" name=3D"frame" >
+ <property name=3D"frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name=3D"frameShadow" >
+ <enum>QFrame::Plain</enum>
+ </property>
+ <layout class=3D"QHBoxLayout" >
+ <property name=3D"margin" >
+ <number>9</number>
+ </property>
+ <property name=3D"spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class=3D"QLabel" name=3D"imageLabel" >
+ <property name=3D"minimumSize" >
+ <size>
+ <width>64</width>
+ <height>64</height>
+ </size>
+ </property>
+ <property name=3D"maximumSize" >
+ <size>
+ <width>64</width>
+ <height>64</height>
+ </size>
+ </property>
+ <property name=3D"text" >
+ <string/>
+ </property>
+ <property name=3D"pixmap" >
+ <pixmap resource=3D"dmxwizard.qrc" >:/DMXWizard/Resources/dmx.p=
ng</pixmap>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class=3D"QLabel" name=3D"infoLabel" >
+ <property name=3D"alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class=3D"QStackedWidget" name=3D"stackedWidget" >
+ <property name=3D"currentIndex" >
+ <number>1</number>
+ </property>
+ <widget class=3D"QWidget" name=3D"settingsPage" >
+ <layout class=3D"QGridLayout" >
+ <property name=3D"margin" >
+ <number>9</number>
+ </property>
+ <property name=3D"spacing" >
+ <number>6</number>
+ </property>
+ <item row=3D"3" column=3D"0" >
+ <widget class=3D"QLabel" name=3D"label_2" >
+ <property name=3D"text" >
+ <string>Output path</string>
+ </property>
+ <property name=3D"buddy" >
+ <cstring>outputPathEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row=3D"4" column=3D"1" >
+ <widget class=3D"QLineEdit" name=3D"toolsPathEdit" />
+ </item>
+ <item row=3D"3" column=3D"1" >
+ <widget class=3D"QLineEdit" name=3D"outputPathEdit" />
+ </item>
+ <item row=3D"3" column=3D"2" >
+ <widget class=3D"QPushButton" name=3D"outputBrowseButton" >
+ <property name=3D"text" >
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row=3D"2" column=3D"1" >
+ <widget class=3D"QLineEdit" name=3D"dvdPathEdit" />
+ </item>
+ <item row=3D"1" column=3D"1" >
+ <spacer>
+ <property name=3D"orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name=3D"sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row=3D"4" column=3D"2" >
+ <widget class=3D"QPushButton" name=3D"toolsBrowseButton" >
+ <property name=3D"text" >
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row=3D"2" column=3D"0" >
+ <widget class=3D"QLabel" name=3D"label" >
+ <property name=3D"text" >
+ <string>DVD path</string>
+ </property>
+ <property name=3D"buddy" >
+ <cstring>dvdPathEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row=3D"5" column=3D"1" >
+ <layout class=3D"QHBoxLayout" >
+ <property name=3D"margin" >
+ <number>0</number>
+ </property>
+ <property name=3D"spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class=3D"QLabel" name=3D"errorImageLabel" >
+ <property name=3D"maximumSize" >
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name=3D"pixmap" >
+ <pixmap resource=3D"dmxwizard.qrc" >:/DMXWizard/Resources/er=
ror.png</pixmap>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class=3D"QLabel" name=3D"errorInfoLabel" >
+ <property name=3D"sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name=3D"minimumSize" >
+ <size>
+ <width>0</width>
+ <height>24</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row=3D"6" column=3D"1" >
+ <layout class=3D"QHBoxLayout" >
+ <property name=3D"margin" >
+ <number>0</number>
+ </property>
+ <property name=3D"spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class=3D"QLabel" name=3D"warningImageLabel" >
+ <property name=3D"maximumSize" >
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name=3D"pixmap" >
+ <pixmap resource=3D"dmxwizard.qrc" >:/DMXWizard/Resources/wa=
rning.png</pixmap>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class=3D"QLabel" name=3D"warningInfoLabel" >
+ <property name=3D"sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name=3D"minimumSize" >
+ <size>
+ <width>0</width>
+ <height>24</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row=3D"2" column=3D"2" >
+ <widget class=3D"QPushButton" name=3D"dvdBrowseButton" >
+ <property name=3D"text" >
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row=3D"7" column=3D"1" >
+ <spacer>
+ <property name=3D"orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name=3D"sizeHint" >
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row=3D"4" column=3D"0" >
+ <widget class=3D"QLabel" name=3D"label_3" >
+ <property name=3D"text" >
+ <string>Tools path</string>
+ </property>
+ <property name=3D"buddy" >
+ <cstring>toolsPathEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row=3D"0" column=3D"1" >
+ <widget class=3D"QLabel" name=3D"label_5" >
+ <property name=3D"text" >
+ <string>Please specify the required paths and click "Next" but=
ton</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class=3D"QWidget" name=3D"selectionPage" >
+ <layout class=3D"QVBoxLayout" >
+ <property name=3D"margin" >
+ <number>9</number>
+ </property>
+ <property name=3D"spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class=3D"QLabel" name=3D"label_4" >
+ <property name=3D"text" >
+ <string>Please select which tracks and subtracks you want to e=
xtract and press "Next" button</string>
+ </property>
+ <property name=3D"buddy" >
+ <cstring>selectionTree</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class=3D"DMXSelectionTree" name=3D"selectionTree" />
+ </item>
+ </layout>
+ </widget>
+ <widget class=3D"QWidget" name=3D"extractionPage" >
+ <layout class=3D"QVBoxLayout" >
+ <property name=3D"margin" >
+ <number>9</number>
+ </property>
+ <property name=3D"spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class=3D"QLabel" name=3D"progressInfoLabel" >
+ <property name=3D"text" >
+ <string>Please wait...
+You can stop the process at any moment by clicking the "Stop" button.</s=
tring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name=3D"orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name=3D"sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class=3D"QLabel" name=3D"stepInfoLabel" >
+ <property name=3D"text" >
+ <string>Step</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class=3D"QProgressBar" name=3D"progressBar" >
+ <property name=3D"value" >
+ <number>0</number>
+ </property>
+ <property name=3D"orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class=3D"QHBoxLayout" >
+ <property name=3D"margin" >
+ <number>0</number>
+ </property>
+ <property name=3D"spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name=3D"orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name=3D"sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class=3D"QPushButton" name=3D"stopButton" >
+ <property name=3D"enabled" >
+ <bool>false</bool>
+ </property>
+ <property name=3D"text" >
+ <string>S&top</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer>
+ <property name=3D"orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name=3D"sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <layout class=3D"QHBoxLayout" >
+ <property name=3D"margin" >
+ <number>0</number>
+ </property>
+ <property name=3D"spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class=3D"QPushButton" name=3D"logButton" >
+ <property name=3D"text" >
+ <string>&Show Log</string>
+ </property>
+ <property name=3D"icon" >
+ <iconset resource=3D"dmxwizard.qrc" >:/DMXWizard/Resources/log.p=
ng</iconset>
+ </property>
+ <property name=3D"checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name=3D"orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name=3D"sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name=3D"sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class=3D"QPushButton" name=3D"backButton" >
+ <property name=3D"enabled" >
+ <bool>false</bool>
+ </property>
+ <property name=3D"text" >
+ <string>&Back</string>
+ </property>
+ <property name=3D"icon" >
+ <iconset resource=3D"dmxwizard.qrc" >:/DMXWizard/Resources/back.=
png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class=3D"QPushButton" name=3D"nextButton" >
+ <property name=3D"enabled" >
+ <bool>false</bool>
+ </property>
+ <property name=3D"text" >
+ <string>&Next</string>
+ </property>
+ <property name=3D"icon" >
+ <iconset resource=3D"dmxwizard.qrc" >:/DMXWizard/Resources/next.=
png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name=3D"orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name=3D"sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name=3D"sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class=3D"QPushButton" name=3D"quitButton" >
+ <property name=3D"text" >
+ <string>&Quit</string>
+ </property>
+ <property name=3D"icon" >
+ <iconset resource=3D"dmxwizard.qrc" >:/DMXWizard/Resources/quit.=
png</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing=3D"6" margin=3D"11" />
+ <customwidgets>
+ <customwidget>
+ <class>DMXSelectionTree</class>
+ <extends>QTreeWidget</extends>
+ <header>dmxselectiontree.h</header>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>dvdPathEdit</tabstop>
+ <tabstop>dvdBrowseButton</tabstop>
+ <tabstop>outputPathEdit</tabstop>
+ <tabstop>outputBrowseButton</tabstop>
+ <tabstop>toolsPathEdit</tabstop>
+ <tabstop>toolsBrowseButton</tabstop>
+ <tabstop>logButton</tabstop>
+ <tabstop>backButton</tabstop>
+ <tabstop>nextButton</tabstop>
+ <tabstop>quitButton</tabstop>
+ <tabstop>selectionTree</tabstop>
+ <tabstop>stopButton</tabstop>
+ </tabstops>
+ <resources>
+ <include location=3D"dmxwizard.qrc" />
+ </resources>
+ <connections>
+ <connection>
+ <sender>quitButton</sender>
+ <signal>clicked()</signal>
+ <receiver>DMXWizardClass</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type=3D"sourcelabel" >
+ <x>489</x>
+ <y>380</y>
+ </hint>
+ <hint type=3D"destinationlabel" >
+ <x>479</x>
+ <y>260</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
Modified: trunk/DvdMenuXtractor/libdvdread/dvdread/bswap.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/dvdread/bswap.h 2007-01-22 11:21:16 =
UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/dvdread/bswap.h 2007-01-28 16:48:11 =
UTC (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
#ifndef BSWAP_H_INCLUDED
#define BSWAP_H_INCLUDED
=20
@@ -20,8 +21,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 U=
SA
*/
=20
-#include <config.h>
-
#if defined(WORDS_BIGENDIAN)
/* All bigendian systems are fine, just ignore the swaps. */ =20
#define B2N_16(x) (void)(x)
@@ -57,40 +56,69 @@
#include <sys/endian.h>
#define B2N_16(x) x =3D be16toh(x)
#define B2N_32(x) x =3D be32toh(x)
+#if __FreeBSD_version >=3D 500000
#define B2N_64(x) x =3D be64toh(x)
+#else
+#define B2N_64(x) \
+ x =3D ((((x) & 0xff00000000000000) >> 56) | \
+ (((x) & 0x00ff000000000000) >> 40) | \
+ (((x) & 0x0000ff0000000000) >> 24) | \
+ (((x) & 0x000000ff00000000) >> 8) | \
+ (((x) & 0x00000000ff000000) << 8) | \
+ (((x) & 0x0000000000ff0000) << 24) | \
+ (((x) & 0x000000000000ff00) << 40) | \
+ (((x) & 0x00000000000000ff) << 56))
+#endif /* _FreeBSD_version >=3D 500000 */
=20
+#elif defined(__DragonFly__)
+#include <sys/endian.h>
+#define B2N_16(x) x =3D be16toh(x)
+#define B2N_32(x) x =3D be32toh(x)
+#define B2N_64(x) x =3D be64toh(x)
+
+
+#elif defined(__APPLE__) || defined(__DARWIN__)
+#include <libkern/OSByteOrder.h>
+#define B2N_16(x) x =3D OSSwapBigToHostConstInt16(x)
+#define B2N_32(x) x =3D OSSwapBigToHostConstInt32(x)
+#define B2N_64(x) x =3D OSSwapBigToHostConstInt64(x)
+
+#else
+#if defined(__FreeBSD__) || defined(__sun) || defined(__bsdi__) || defin=
ed(WIN32) || defined(__BEOS__) || defined(__INTERIX)
+/* These systems don't have swap macros */
+#else
+/* If there isn't a header provided with your system with this functiona=
lity
+ * add the relevant || define( ) to the list above.
+ */
+#warning "You should add endian swap macros for your system"
+#endif
+
/* This is a slow but portable implementation, it has multiple evaluatio=
n=20
* problems so beware.
* Old FreeBSD's and Solaris don't have <byteswap.h> or any other such=20
* functionality!=20
*/
=20
-#elif defined(__FreeBSD__) || defined(__sun) || defined(__bsdi__) || def=
ined(WIN32) || defined( __BEOS__ )
-#define B2N_16(x) \
- x =3D ((((x) & 0xff00) >> 8) | \
- (((x) & 0x00ff) << 8))
-#define B2N_32(x) \
- x =3D ((((x) & 0xff000000) >> 24) | \
- (((x) & 0x00ff0000) >> 8) | \
- (((x) & 0x0000ff00) << 8) | \
- (((x) & 0x000000ff) << 24))
-#define B2N_64(x) \
- x =3D ((((x) & 0xff00000000000000) >> 56) | \
- (((x) & 0x00ff000000000000) >> 40) | \
- (((x) & 0x0000ff0000000000) >> 24) | \
- (((x) & 0x000000ff00000000) >> 8) | \
- (((x) & 0x00000000ff000000) << 8) | \
- (((x) & 0x0000000000ff0000) << 24) | \
- (((x) & 0x000000000000ff00) << 40) | \
- (((x) & 0x00000000000000ff) << 56))
-
-#else
+#define B2N_16(x) \
+ x =3D ((((x) & 0xff00) >> 8) | \
+ (((x) & 0x00ff) << 8))
+#define B2N_32(x) \
+ x =3D ((((x) & 0xff000000) >> 24) | \
+ (((x) & 0x00ff0000) >> 8) | \
+ (((x) & 0x0000ff00) << 8) | \
+ (((x) & 0x000000ff) << 24))
+#define B2N_64(x) \
+ x =3D ((((x) & 0xff00000000000000) >> 56) | \
+ (((x) & 0x00ff000000000000) >> 40) | \
+ (((x) & 0x0000ff0000000000) >> 24) | \
+ (((x) & 0x000000ff00000000) >> 8) | \
+ (((x) & 0x00000000ff000000) << 8) | \
+ (((x) & 0x0000000000ff0000) << 24) | \
+ (((x) & 0x000000000000ff00) << 40) | \
+ (((x) & 0x00000000000000ff) << 56))
=20
-/* If there isn't a header provided with your system with this functiona=
lity
- * add the relevant || define( ) to the portable implementation above.
- */
-#error "You need to add endian swap macros for you're system"
=20
+
#endif
=20
#endif /* WORDS_BIGENDIAN */
Added: trunk/DvdMenuXtractor/libdvdread/dvdread/cmd_print.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/dvdread/cmd_print.c 2007-01-22 11:21=
:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/dvdread/cmd_print.c 2007-01-28 16:48=
:11 UTC (rev 1270)
@@ -0,0 +1,550 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 2000, 2001, 2002, 2003 Martin Norb=E4ck, H=E5kan Hjort
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,=20
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 =
USA
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <ctype.h>
+
+#if defined(HAVE_INTTYPES_H)
+#include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
+
+#include "cmd_print.h"
+
+
+typedef struct
+{
+ uint8_t bits[8];
+ uint8_t examined[8];
+} cmd_t;
+
+
+static const char *cmp_op_table[] =3D {
+ NULL, "&", "=3D=3D", "!=3D", ">=3D", ">", "<=3D", "<"
+};
+static const char *set_op_table[] =3D {
+ NULL, "=3D", "<->", "+=3D", "-=3D", "*=3D", "/=3D", "%=3D", "rnd", "&=3D=
", "|=3D", "^=3D"
+};
+
+static const char *link_table[] =3D {
+ "LinkNoLink", "LinkTopC", "LinkNextC", "LinkPrevC",
+ NULL, "LinkTopPG", "LinkNextPG", "LinkPrevPG",
+ NULL, "LinkTopPGC", "LinkNextPGC", "LinkPrevPGC",
+ "LinkGoUpPGC", "LinkTailPGC", NULL, NULL,
+ "RSM"
+};
+
+static const char *system_reg_table[] =3D {
+ "Menu Description Language Code",
+ "Audio Stream Number",
+ "Sub-picture Stream Number",
+ "Angle Number",
+ "Title Track Number",
+ "VTS Title Track Number",
+ "VTS PGC Number",
+ "PTT Number for One_Sequential_PGC_Title",
+ "Highlighted Button Number",
+ "Navigation Timer",
+ "Title PGC Number for Navigation Timer",
+ "Audio Mixing Mode for Karaoke",
+ "Country Code for Parental Management",
+ "Parental Level",
+ "Player Configurations for Video",
+ "Player Configurations for Audio",
+ "Initial Language Code for Audio",
+ "Initial Language Code Extension for Audio",
+ "Initial Language Code for Sub-picture",
+ "Initial Language Code Extension for Sub-picture",
+ "Player Regional Code",
+ "Reserved 21",
+ "Reserved 22",
+ "Reserved 23"
+};
+
+static const char *system_reg_abbr_table[] =3D {
+ NULL,
+ "ASTN",
+ "SPSTN",
+ "AGLN",
+ "TTN",
+ "VTS_TTN",
+ "TT_PGCN",
+ "PTTN",
+ "HL_BTNN",
+ "NVTMR",
+ "NV_PGCN",
+ NULL,
+ "CC_PLT",
+ "PLT",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+ =20
+
+
+static unsigned int bits(cmd_t *cmd, int byte, int bit, int count) {
+ unsigned int val =3D 0;
+ unsigned int bit_mask;
+ =20
+ while(count--) {
+ if(bit > 7) {
+ bit =3D 0;
+ byte++;
+ }
+ bit_mask =3D 0x01 << (7-bit);
+ val <<=3D 1;
+ if((cmd->bits[byte]) & bit_mask)
+ val |=3D 1;
+ cmd->examined[byte] |=3D bit_mask;
+ bit++;
+ }
+ return val;
+}
+
+
+static void print_system_reg(unsigned int reg) {
+ if(reg < sizeof(system_reg_abbr_table) / sizeof(char *))
+ fprintf(stdout, system_reg_table[reg]);
+ else
+ fprintf(stdout, " WARNING: Unknown system register ");
+}
+
+static void print_reg(unsigned int reg) {
+ if(reg & 0x80)
+ print_system_reg(reg & 0x7f);
+ else
+ if(reg < 16)
+ fprintf(stdout, "g[%u]", reg);
+ else
+ fprintf(stdout, " WARNING: Unknown general register ");
+}
+
+static void print_cmp_op(unsigned int op) {
+ if(op < sizeof(cmp_op_table) / sizeof(char *) && cmp_op_table[op] !=3D=
NULL)
+ fprintf(stdout, " %s ", cmp_op_table[op]);
+ else
+ fprintf(stdout, " WARNING: Unknown compare op ");
+}
+
+static void print_set_op(unsigned int op) {
+ if(op < sizeof(set_op_table) / sizeof(char *) && set_op_table[op] !=3D=
NULL)
+ fprintf(stdout, " %s ", set_op_table[op]);
+ else
+ fprintf(stdout, " WARNING: Unknown set op ");
+}
+
+static void print_reg_or_data(cmd_t *cmd, unsigned int immediate, int by=
te) {
+ if(immediate) {
+ int i =3D bits(cmd,byte,0,16);
+ =20
+ fprintf(stdout, "0x%x", i);
+ if(isprint(i & 0xff) && isprint((i>>8) & 0xff))
+ fprintf(stdout, " (\"%c%c\")", (char)((i>>8) & 0xff), (char)(i & 0=
xff));
+ } else {
+ print_reg(bits(cmd,byte + 1,0,8));
+ }
+}
+
+static void print_reg_or_data_2(cmd_t *cmd, unsigned int immediate, int =
byte) {
+ if(immediate)
+ fprintf(stdout, "0x%x", bits(cmd,byte,1,7));
+ else
+ fprintf(stdout, "g[%u]", bits(cmd,byte,4,4));
+}
+
+static void print_if_version_1(cmd_t *cmd) {
+ unsigned int op =3D bits(cmd,1,1,3);
+ =20
+ if(op) {
+ fprintf(stdout, "if (");
+ print_reg(bits(cmd,3,0,8));
+ print_cmp_op(op);
+ print_reg_or_data(cmd,bits(cmd,1,0,1), 4);
+ fprintf(stdout, ") ");
+ }
+}
+
+static void print_if_version_2(cmd_t *cmd) {
+ unsigned int op =3D bits(cmd,1,1,3);
+ =20
+ if(op) {
+ fprintf(stdout, "if (");
+ print_reg(bits(cmd,6,0,8));
+ print_cmp_op(op);
+ print_reg(bits(cmd,7,0,8));
+ fprintf(stdout, ") ");
+ }
+}
+
+static void print_if_version_3(cmd_t *cmd) {
+ unsigned int op =3D bits(cmd,1,1,3);
+ =20
+ if(op) {
+ fprintf(stdout, "if (");
+ print_reg(bits(cmd,2,0,8));
+ print_cmp_op(op);
+ print_reg_or_data(cmd,bits(cmd,1,0,1), 6);
+ fprintf(stdout, ") ");
+ }
+}
+
+static void print_if_version_4(cmd_t *cmd) {
+ unsigned int op =3D bits(cmd,1,1,3);
+ =20
+ if(op) {
+ fprintf(stdout, "if (");
+ print_reg(bits(cmd,1,4,4));
+ print_cmp_op(op);
+ print_reg_or_data(cmd,bits(cmd,1,0,1), 4);
+ fprintf(stdout, ") ");
+ }
+}
+
+static void print_if_version_5(cmd_t *cmd) {
+ unsigned int op =3D bits(cmd,1,1,3);
+ =20
+ if(op) {
+ fprintf(stdout, "if (");
+ print_reg(bits(cmd,4,0,8));
+ print_cmp_op(op);
+ print_reg(bits(cmd,5,0,8));
+ fprintf(stdout, ") ");
+ }
+}
+
+static void print_special_instruction(cmd_t *cmd) {
+ unsigned int op =3D bits(cmd,1,4,4);
+ =20
+ switch(op) {
+ case 0: // NOP
+ fprintf(stdout, "Nop");
+ break;
+ case 1: // Goto line
+ fprintf(stdout, "Goto %u", bits(cmd,7,0,8));
+ break;
+ case 2: // Break
+ fprintf(stdout, "Break");
+ break;
+ case 3: // Parental level
+ fprintf(stdout, "SetTmpPML %u, Goto %u",=20
+ bits(cmd,6,4,4), bits(cmd,7,0,8));
+ break;
+ default:
+ fprintf(stdout, "WARNING: Unknown special instruction (%u)",=20
+ bits(cmd,1,4,4));
+ }
+}
+
+static void print_linksub_instruction(cmd_t *cmd) {
+ unsigned int linkop =3D bits(cmd,7,3,5);
+ unsigned int button =3D bits(cmd,6,0,6);
+ =20
+ if(linkop < sizeof(link_table)/sizeof(char *) && link_table[linkop] !=3D=
NULL)
+ fprintf(stdout, "%s (button %u)", link_table[linkop], button);
+ else
+ fprintf(stdout, "WARNING: Unknown linksub instruction (%u)", linkop)=
;
+}
+
+static void print_link_instruction(cmd_t *cmd, int optional) {
+ unsigned int op =3D bits(cmd,1,4,4);
+ =20
+ if(optional && op)
+ fprintf(stdout, ", ");
+ =20
+ switch(op) {
+ case 0:
+ if(!optional)
+ fprintf(stdout, "WARNING: NOP (link)!");
+ break;
+ case 1:
+ print_linksub_instruction(cmd);
+ break;
+ case 4:
+ fprintf(stdout, "LinkPGCN %u", bits(cmd,6,1,15));
+ break;
+ case 5:
+ fprintf(stdout, "LinkPTT %u (button %u)",=20
+ bits(cmd,6,6,10), bits(cmd,6,0,6));
+ break;
+ case 6:
+ fprintf(stdout, "LinkPGN %u (button %u)",=20
+ bits(cmd,7,1,7), bits(cmd,6,0,6));
+ break;
+ case 7:
+ fprintf(stdout, "LinkCN %u (button %u)",=20
+ bits(cmd,7,0,8), bits(cmd,6,0,6));
+ break;
+ default:
+ fprintf(stdout, "WARNING: Unknown link instruction");
+ }
+}
+
+static void print_jump_instruction(cmd_t *cmd) {
+ switch(bits(cmd,1,4,4)) {
+ case 1:
+ fprintf(stdout, "Exit");
+ break;
+ case 2:
+ fprintf(stdout, "JumpTT %u", bits(cmd,5,1,7));
+ break;
+ case 3:
+ fprintf(stdout, "JumpVTS_TT %u", bits(cmd,5,1,7));
+ break;
+ case 5:
+ fprintf(stdout, "JumpVTS_PTT %u:%u", bits(cmd,5,1,7), bits(cmd,2,6,1=
0));
+ break;
+ case 6:
+ switch(bits(cmd,5,0,2)) {
+ case 0:
+ fprintf(stdout, "JumpSS FP");
+ break;
+ case 1:
+ fprintf(stdout, "JumpSS VMGM (menu %u)", bits(cmd,5,4,4));
+ break;
+ case 2:
+ fprintf(stdout, "JumpSS VTSM (vts %u, title %u, menu %u)",=20
+ bits(cmd,4,0,8), bits(cmd,3,0,8), bits(cmd,5,4,4));
+ break;
+ case 3:
+ fprintf(stdout, "JumpSS VMGM (pgc %u)", bits(cmd,2,1,15));
+ break;
+ }
+ break;
+ case 8:
+ switch(bits(cmd,5,0,2)) {
+ case 0:
+ fprintf(stdout, "CallSS FP (rsm_cell %u)",
+ bits(cmd,4,0,8));
+ break;
+ case 1:
+ fprintf(stdout, "CallSS VMGM (menu %u, rsm_cell %u)",
+ bits(cmd,5,4,4), bits(cmd,4,0,8));
+ break;
+ case 2:
+ fprintf(stdout, "CallSS VTSM (menu %u, rsm_cell %u)",
+ bits(cmd,5,4,4), bits(cmd,4,0,8));
+ break;
+ case 3:
+ fprintf(stdout, "CallSS VMGM (pgc %u, rsm_cell %u)",=20
+ bits(cmd,2,1,15), bits(cmd,4,0,8));
+ break;
+ }
+ break;
+ default:
+ fprintf(stdout, "WARNING: Unknown Jump/Call instruction");
+ }
+}
+
+static void print_system_set(cmd_t *cmd) {
+ int i;
+ =20
+ switch(bits(cmd,0,4,4)) {
+ case 1: // Set system reg 1 &| 2 &| 3 (Audio, Subp. Angle)
+ for(i =3D 1; i <=3D 3; i++) {
+ if(bits(cmd,2+i,0,1)) {
+ print_system_reg((unsigned int)i);
+ fprintf(stdout, " =3D ");
+ print_reg_or_data_2(cmd,bits(cmd,0,3,1), 2 + i);
+ fprintf(stdout, " ");
+ }
+ }
+ break;
+ case 2: // Set system reg 9 & 10 (Navigation timer, Title PGC number)
+ print_system_reg(9);
+ fprintf(stdout, " =3D ");
+ print_reg_or_data(cmd,bits(cmd,0,3,1), 2);
+ fprintf(stdout, " ");
+ print_system_reg(10);
+ fprintf(stdout, " =3D %u", bits(cmd,5,0,8)); // ??
+ break;
+ case 3: // Mode: Counter / Register + Set
+ fprintf(stdout, "SetMode ");
+ if(bits(cmd,5,0,1))
+ fprintf(stdout, "Counter ");
+ else
+ fprintf(stdout, "Register ");
+ print_reg(bits(cmd,5,4,4));
+ print_set_op(0x1); // '=3D'
+ print_reg_or_data(cmd,bits(cmd,0,3,1), 2);
+ break;
+ case 6: // Set system reg 8 (Highlighted button)
+ print_system_reg(8);
+ if(bits(cmd,0,3,1)) // immediate
+ fprintf(stdout, " =3D 0x%x (button no %u)",=20
+ bits(cmd,4,0,16), bits(cmd,4,0,6));
+ else
+ fprintf(stdout, " =3D g[%u]", bits(cmd,5,4,4));
+ break;
+ default:
+ fprintf(stdout, "WARNING: Unknown system set instruction (%u)",=20
+ bits(cmd,0,4,4));
+ }
+}
+
+static void print_set_version_1(cmd_t *cmd) {
+ unsigned int set_op =3D bits(cmd,0,4,4);
+ =20
+ if(set_op) {
+ print_reg(bits(cmd,3,0,8));
+ print_set_op(set_op);
+ print_reg_or_data(cmd,bits(cmd,0,3,1), 4);
+ } else {
+ fprintf(stdout, "NOP");
+ }
+}
+
+static void print_set_version_2(cmd_t *cmd) {
+ unsigned int set_op =3D bits(cmd,0,4,4);
+ =20
+ if(set_op) {
+ print_reg(bits(cmd,1,4,4));
+ print_set_op(set_op);
+ print_reg_or_data(cmd,bits(cmd,0,3,1), 2);
+ } else {
+ fprintf(stdout, "NOP");
+ }
+}
+
+static void print_set_version_3(cmd_t *cmd) {
+ unsigned int set_op =3D bits(cmd,0,4,4);
+ =20
+ if(set_op) {
+ print_reg(bits(cmd,1,4,4));
+ print_set_op(set_op);
+ if(bits(cmd,0,3,1)) { // print_reg_or_data
+ unsigned int i =3D bits(cmd,2,0,16);
+ =20
+ fprintf(stdout, "0x%x", i);
+ if(isprint(i & 0xff) && isprint((i>>8) & 0xff))
+ fprintf(stdout, " (\"%c%c\")",=20
+ (char)((i>>8) & 0xff), (char)(i & 0xff));
+ } else {
+ print_reg(bits(cmd,2,0,8));
+ }
+ } else {
+ fprintf(stdout, "NOP");
+ }
+}
+
+static void print_command(cmd_t *cmd) {
+ switch(bits(cmd,0,0,3)) { /* three first bits */
+ case 0: // Special instructions
+ print_if_version_1(cmd);
+ print_special_instruction(cmd);
+ break;
+ case 1: // Jump/Call or Link instructions
+ if(bits(cmd,0,3,1)) {
+ print_if_version_2(cmd);
+ print_jump_instruction(cmd);
+ } else {
+ print_if_version_1(cmd);
+ print_link_instruction(cmd,0); // must be pressent
+ }
+ break;
+ case 2: // Set System Parameters instructions
+ print_if_version_2(cmd);
+ print_system_set(cmd);
+ print_link_instruction(cmd,1); // either 'if' or 'link'
+ break;
+ case 3: // Set General Parameters instructions
+ print_if_version_3(cmd);
+ print_set_version_1(cmd);
+ print_link_instruction(cmd,1); // either 'if' or 'link'
+ break;
+ case 4: // Set, Compare -> LinkSub instructions
+ print_set_version_2(cmd);
+ fprintf(stdout, ", ");
+ print_if_version_4(cmd);
+ print_linksub_instruction(cmd);
+ break;
+ case 5: // Compare -> (Set and LinkSub) instructions
+ if(bits(cmd,0,3,1))
+ print_if_version_5(cmd);
+ else
+ print_if_version_1(cmd);
+ fprintf(stdout, "{ ");
+ print_set_version_3(cmd);
+ fprintf(stdout, ", ");
+ print_linksub_instruction(cmd);
+ fprintf(stdout, " }");
+ break;
+ case 6: // Compare -> Set, always LinkSub instructions
+ if(bits(cmd,0,3,1))
+ print_if_version_5(cmd);
+ else
+ print_if_version_1(cmd);
+ fprintf(stdout, "{ ");
+ print_set_version_3(cmd);
+ fprintf(stdout, " } ");
+ print_linksub_instruction(cmd);
+ break;
+ default:
+ fprintf(stdout, "WARNING: Unknown instruction type (%i)",=20
+ bits(cmd,0,0,3));
+ }
+}
+
+void cmdPrint_mnemonic(vm_cmd_t *command) {
+ int i, extra_bits;
+ cmd_t cmd;
+ =20
+ for(i =3D 0; i < 8; i++) {
+ cmd.bits[i] =3D command->bytes[i];
+ cmd.examined[i] =3D 0;
+ }
+
+ print_command(&cmd);
+ =20
+ // Check if there still are bits set that were not examined
+ extra_bits =3D 0;
+ for(i =3D 0; i < 8; i++)
+ if(cmd.bits[i] & ~ cmd.examined[i]) {
+ extra_bits =3D 1;
+ break;
+ }
+ if(extra_bits) {
+ fprintf(stdout, " [WARNING, unknown bits:");
+ for(i =3D 0; i < 8; i++)
+ fprintf(stdout, " %02x", cmd.bits[i] & ~ cmd.examined[i]);
+ fprintf(stdout, "]");
+ }
+}
+
+void cmdPrint_CMD(int row, vm_cmd_t *command) {
+ int i;
+
+ fprintf(stdout, "(%03d) ", row + 1);
+ for(i =3D 0; i < 8; i++)
+ fprintf(stdout, "%02x ", command->bytes[i]);
+ fprintf(stdout, "| ");
+
+ cmdPrint_mnemonic(command);
+ fprintf(stdout, "\n");
+}
Added: trunk/DvdMenuXtractor/libdvdread/dvdread/cmd_print.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/dvdread/cmd_print.h 2007-01-22 11:21=
:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/dvdread/cmd_print.h 2007-01-28 16:48=
:11 UTC (rev 1270)
@@ -0,0 +1,51 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
+#ifndef CMD_PRINT_H_INCLUDED
+#define CMD_PRINT_H_INCLUDED
+
+/*
+ * Copyright (C) 2000, 2001, 2002, 2003 Martin Norb=E4ck, H=E5kan Hjort
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,=20
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 =
USA
+ */
+
+#include <dvdread/ifo_types.h>
+
+/**
+ * Pretty printing of the DVD commands (vm instructions).
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ =20
+/**
+ * Prints a text representation of the commands to stdout.
+ *
+ * @param command Pointer to the DVD command to be printed.
+ */
+void cmdPrint_mnemonic(vm_cmd_t *command);
+ =20
+/**
+ * Prints row, then a hex dump of the command followed by the text
+ * representation of the commands, as given by cmdPrint_mnemonic to
+ * stdout.
+ *
+ * @param command Pointer to the DVD command to be printed. */
+void cmdPrint_CMD(int row, vm_cmd_t *command);
+
+#ifdef __cplusplus
+};
+#endif
+#endif /* CMD_PRINT_H_INCLUDED */
Modified: trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_input.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_input.c 2007-01-22 11:21=
:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_input.c 2007-01-28 16:48=
:11 UTC (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2002 Samuel Hocevar <sam at zoy.org>,
* H=E5kan Hjort <d95hjort at dtek.chalmers.se>
@@ -19,22 +20,38 @@
=20
#include "config.h"
=20
+#if defined(WIN32)
+#include "posix.h"
+#endif
#include <stdio.h>
#include <stdlib.h>
-#include <fcntl.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
+#define __USE_GNU /* to get O_DIRECT in linux */
+#include <fcntl.h>
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
#endif
=20
+#if defined(WIN32)
+#include <io.h> // for open(), close(), etc..
+#include <share.h>
+#endif
+
#include "dvd_reader.h"
#include "dvd_input.h"
=20
+#include "dvdread_internal.h"
+
/* The function pointers that is the exported interface of this file. */
dvd_input_t (*dvdinput_open) (const char *);
int (*dvdinput_close) (dvd_input_t);
int (*dvdinput_seek) (dvd_input_t, int);
int (*dvdinput_title) (dvd_input_t, int);=20
+/**
+ * pointer must be aligned to 2048 bytes
+ * if reading from a raw/O_DIRECT file
+ */
int (*dvdinput_read) (dvd_input_t, void *, int, int);
+
char * (*dvdinput_error) (dvd_input_t);
=20
#ifdef HAVE_DVDCSS_DVDCSS_H
@@ -45,11 +62,11 @@
#define DVDcss_seek dvdcss_seek
#define DVDcss_title dvdcss_title
#define DVDcss_read dvdcss_read
-#define DVDcss_error dvdcss_error
-#else
-/* dlopening libdvdcss */
-#ifdef HAVE_DLFCN_H
-#include <dlfcn.h>
+#define DVDcss_error dvdcss_error
+#else=20
+/* dlopening libdvdcss */
+#if defined(HAVE_DLFCN_H)
+#include <dlfcn.h>
#endif
typedef struct dvdcss_s *dvdcss_handle;
static dvdcss_handle (*DVDcss_open) (const char *);
@@ -70,10 +87,6 @@
};
=20
=20
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
/**
* initialize and open a DVD device or file.
*/
@@ -84,16 +97,15 @@
/* Allocate the handle structure */
dev =3D (dvd_input_t) malloc(sizeof(struct dvd_input_s));
if(dev =3D=3D NULL) {
- LOG_ERROR( stderr, "libdvdread: Could not allocate memory.\n");
+ /* malloc has set errno to ENOMEM */
return NULL;
}
=20
/* Really open it with libdvdcss */
dev->dvdcss =3D DVDcss_open(target);
if(dev->dvdcss =3D=3D 0) {
- LOG_ERROR( stderr, "libdvdread: Could not open %s with libdvdcss.\n"=
, target);
free(dev);
- return NULL;
+ dev =3D NULL;
}
=20
return dev;
@@ -149,29 +161,45 @@
return 0;
}
=20
+/* Need to use O_BINARY for WIN32 */
+#ifndef O_BINARY
+#ifdef _O_BINARY
+#define O_BINARY _O_BINARY
+#else
+#define O_BINARY 0
+#endif
+#endif
=20
-
-
-
-
/**
* initialize and open a DVD device or file.
*/
static dvd_input_t file_open(const char *target)
{
dvd_input_t dev;
+ char *use_odirect;
+ int oflags;
=20
+ oflags =3D O_RDONLY | O_BINARY;
+ use_odirect =3D getenv("DVDREAD_USE_DIRECT");
+ if(use_odirect) {
+#ifndef O_DIRECT
+#define O_DIRECT 0
+#endif
+ oflags |=3D O_DIRECT;
+ }
/* Allocate the library structure */
dev =3D (dvd_input_t) malloc(sizeof(struct dvd_input_s));
if(dev =3D=3D NULL) {
- LOG_ERROR( stderr, "libdvdread: Could not allocate memory.\n");
return NULL;
}
=20
/* Open the device */
- dev->fd =3D open(target, O_RDONLY|O_BINARY);
+#if defined(_CRT_NONSTDC_DEPRECATE)
+ dev->fd =3D _open(target, oflags);
+#else
+ dev->fd =3D open(target, oflags);
+#endif
if(dev->fd < 0) {
- perror("libdvdread: Could not open input");
free(dev);
return NULL;
}
@@ -193,11 +221,15 @@
*/
static int file_seek(dvd_input_t dev, int blocks)
{
- off_t pos;
+ off_t pos =3D (off_t)blocks * (off_t)DVD_VIDEO_LB_LEN;
=20
- pos =3D lseek(dev->fd, (off_t)blocks * (off_t)DVD_VIDEO_LB_LEN, SEEK_S=
ET);
+#if defined(_CRT_NONSTDC_DEPRECATE)
+ pos =3D _lseek(dev->fd, pos, SEEK_SET);
+#else
+ pos =3D lseek(dev->fd, pos, SEEK_SET);
+#endif
if(pos < 0) {
- return pos;
+ return pos;
}
/* assert pos % DVD_VIDEO_LB_LEN =3D=3D 0 */
return (int) (pos / DVD_VIDEO_LB_LEN);
@@ -218,12 +250,17 @@
{
size_t len;
ssize_t ret;
- =20
+ unsigned char *buf =3D buffer;
+
len =3D (size_t)blocks * DVD_VIDEO_LB_LEN;
=20
while(len > 0) {
=20
- ret =3D read(dev->fd, buffer, len);
+#if defined(_CRT_NONSTDC_DEPRECATE)
+ ret =3D _read(dev->fd, buf, len);
+#else
+ ret =3D read(dev->fd, buf, len);
+#endif
=20
if(ret < 0) {
/* One of the reads failed, too bad. We won't even bother
@@ -234,14 +271,19 @@
=20
if(ret =3D=3D 0) {
/* Nothing more to read. Return the whole blocks, if any, that we=
got.
- and adjust the file possition back to the previous block boundary. */
+ and adjust the file possition back to the previous block bounda=
ry. */
size_t bytes =3D (size_t)blocks * DVD_VIDEO_LB_LEN - len;
- off_t over_read =3D -(bytes % DVD_VIDEO_LB_LEN);
- /*off_t pos =3D*/ lseek(dev->fd, over_read, SEEK_CUR);
+ off_t over_read =3D (unsigned)-(bytes % DVD_VIDEO_LB_LEN);
+#if defined(_CRT_NONSTDC_DEPRECATE)
+ /*off_t pos =3D*/ _lseek(dev->fd, over_read, SEEK_CUR);
+#else
+ /*off_t pos =3D*/ lseek(dev->fd, over_read, SEEK_CUR);
+#endif
/* should have pos % 2048 =3D=3D 0 */
return (int) (bytes / DVD_VIDEO_LB_LEN);
}
=20
+ buf+=3Dret;
len -=3D ret;
}
=20
@@ -255,7 +297,12 @@
{
int ret;
=20
+#if defined(_CRT_NONSTDC_DEPRECATE)
+ ret =3D _close(dev->fd);
+#else
ret =3D close(dev->fd);
+#endif
+ =20
=20
if(ret < 0)
return ret;
@@ -264,20 +311,52 @@
=20
return 0;
}
-
-#if !defined(WIN32)
-typedef void *HMODULE;
-#endif
=20
-static HMODULE dvdcss_library =3D NULL;
=20
+static void *dvdcss_library =3D NULL;
+static int dvdcss_library_init =3D 0;
+
/**
+ * Free any objects allocated by dvdinput_setup.
+ * Should only be called when libdvdread is not to be used any more.
+ * Closes dlopened libraries.
+ */
+void dvdinput_free(void)
+{
+#ifdef HAVE_DVDCSS_DVDCSS_H
+ /* linked statically, nothing to free */
+ return;
+#else
+ if(dvdcss_library) {
+ dlclose(dvdcss_library);
+ dvdcss_library =3D NULL;
+ }
+ dvdcss_library_init =3D 0;
+ return;
+#endif
+}
+
+
+/**
* Setup read functions with either libdvdcss or minimal DVD access.
*/
int dvdinput_setup(void)
{
char **dvdcss_version =3D NULL;
+ int verbose;
=20
+ /* dlopening libdvdcss */
+ if(dvdcss_library_init) {
+ /* libdvdcss is already dlopened, function ptrs set */
+ if(dvdcss_library) {
+ return 1; /* css available */
+ } else {
+ return 0; /* css not available */
+ }
+ }
+
+ verbose =3D get_verbose();
+ =20
#ifdef HAVE_DVDCSS_DVDCSS_H
/* linking to libdvdcss */
dvdcss_library =3D &dvdcss_library; /* Give it some value !=3D NULL *=
/
@@ -285,13 +364,12 @@
dvdcss_version =3D &dvdcss_interface_2;
=20
#else
- /* dlopening libdvdcss */
-#if defined(WIN32)
- dvdcss_library =3D LoadLibrary("libdvdcss.dll");
-#else /* !WIN32 */
+#if defined(WIN32)
+ dvdcss_library =3D LoadLibraryA("libdvdcss.dll");
+#else
dvdcss_library =3D dlopen("libdvdcss.so.2", RTLD_LAZY);
-#endif /* !WIN32 */
- =20
+#endif
+
if(dvdcss_library !=3D NULL) {
#if defined(__OpenBSD__) && !defined(__ELF__)
#define U_S "_"
@@ -314,31 +392,39 @@
dvdcss_version =3D (char **)dlsym(dvdcss_library, U_S "dvdcss_interf=
ace_2");
=20
if(dlsym(dvdcss_library, U_S "dvdcss_crack")) {
- LOG_ERROR( stderr,=20
- "libdvdread: Old (pre-0.0.2) version of libdvdcss found.\n"
- "libdvdread: You should get the latest version from "
- "http://www.videolan.org/\n" );
+ if(verbose >=3D 0) {
+ fprintf(stderr,=20
+ "libdvdread: Old (pre-0.0.2) version of libdvdcss found.=
\n"
+ "libdvdread: You should get the latest version from "
+ "http://www.videolan.org/\n" );
+ }
dlclose(dvdcss_library);
dvdcss_library =3D NULL;
} else if(!DVDcss_open || !DVDcss_close || !DVDcss_title || !DVDcss=
_seek
- || !DVDcss_read || !DVDcss_error || !dvdcss_version) {
- LOG_ERROR( stderr, "libdvdread: Missing symbols in libdvdcss.so.2,=
"
- "this shouldn't happen !\n");
+ || !DVDcss_read || !DVDcss_error || !dvdcss_version) {
+ if(verbose >=3D 0) {
+ fprintf(stderr, "libdvdread: Missing symbols in libdvdcss.so.2,=
"
+ "this shouldn't happen !\n");
+ }
dlclose(dvdcss_library);
+ dvdcss_library =3D NULL;
}
}
#endif /* HAVE_DVDCSS_DVDCSS_H */
+
+ dvdcss_library_init =3D 1;
=20
- if(dvdcss_library !=3D NULL) {
+ if(dvdcss_library) {
/*
- char *psz_method =3D getenv( "DVDCSS_METHOD" );
- char *psz_verbose =3D getenv( "DVDCSS_VERBOSE" );
- LOG_ERROR( stderr, "DVDCSS_METHOD %s\n", psz_method);
- LOG_ERROR( stderr, "DVDCSS_VERBOSE %s\n", psz_verbose);
+ char *psz_method =3D getenv( "DVDCSS_METHOD" );
+ char *psz_verbose =3D getenv( "DVDCSS_VERBOSE" );
+ fprintf(stderr, "DVDCSS_METHOD %s\n", psz_method);
+ fprintf(stderr, "DVDCSS_VERBOSE %s\n", psz_verbose);
*/
- LOG_ERROR( stderr, "libdvdread: Using libdvdcss version %s for DVD a=
ccess\n",
- *dvdcss_version);
- =20
+ if(verbose >=3D 1) {
+ fprintf(stderr, "libdvdread: Using libdvdcss version %s for DVD ac=
cess\n",
+ *dvdcss_version);
+ }
/* libdvdcss wrapper functions */
dvdinput_open =3D css_open;
dvdinput_close =3D css_close;
@@ -349,8 +435,9 @@
return 1;
=20
} else {
- LOG_ERROR( stderr, "libdvdread: Encrypted DVD support unavailable.\n=
");
-
+ if(verbose >=3D 1) {
+ fprintf(stderr, "libdvdread: Encrypted DVD support unavailable.\n"=
);
+ }
/* libdvdcss replacement functions */
dvdinput_open =3D file_open;
dvdinput_close =3D file_close;
@@ -361,13 +448,3 @@
return 0;
}
}
-
-/*
- clear the resources
-*/
-void dvdinput_unsetup()
-{
- if (dvdcss_library)
- dlclose(dvdcss_library);
-}
-
Modified: trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_input.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_input.h 2007-01-22 11:21=
:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_input.h 2007-01-28 16:48=
:11 UTC (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
#ifndef DVD_INPUT_H_INCLUDED
#define DVD_INPUT_H_INCLUDED
=20
@@ -40,12 +41,15 @@
extern char * (*dvdinput_error) (dvd_input_t);
=20
/**
+ * Free any objects allocated by dvdinput_setup.
+ * Should only be called when libdvdread is not to be used any more.
+ * Closes dlopened libraries.
+ */
+void dvdinput_free(void);
+
+/**
* Setup function accessed by dvd_reader.c. Returns 1 if there is CSS s=
upport.
*/
int dvdinput_setup(void);
-/**
- * Release all resources used
- */
-void dvdinput_unsetup(void);
=20
#endif /* DVD_INPUT_H_INCLUDED */
Modified: trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_reader.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_reader.c 2007-01-22 11:2=
1:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_reader.c 2007-01-28 16:4=
8:11 UTC (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2001, 2002, 2003 Billy Biggs <vektor at dumbterm.net>,
* H=E5kan Hjort <d95hjort at dtek.chalmers.=
se>,
@@ -20,9 +21,12 @@
=20
#include "config.h"
=20
+#if defined(WIN32)
+#include "posix.h"
+#endif
#include <sys/types.h>
#include <sys/stat.h>
-#ifdef HAVE_SYS_TIME_H
+#if !defined(WIN32)
#include <sys/time.h> /* For the timing of dvdcss_title crack. */
#endif
#include <fcntl.h>
@@ -30,13 +34,13 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
-#ifdef HAVE_UNISTD_H
+#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
#include <limits.h>
#include <dirent.h>
=20
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) =
|| defined(__bsdi__)|| defined(__DARWIN__)
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) =
|| defined(__bsdi__) || defined(__DARWIN__) || defined(__DragonFly__)
#define SYS_BSD 1
#endif
=20
@@ -48,53 +52,97 @@
#include <mntent.h>
#endif
=20
+#include "dvd_reader.h"
+#include "dvd_input.h"
#include "dvd_udf.h"
-#include "dvd_input.h"
-#include "dvd_reader.h"
#include "md5.h"
=20
+#include "dvdread_internal.h"
+
#define DEFAULT_UDF_CACHE_LEVEL 1
=20
struct dvd_reader_s {
- /* Basic information. */
- int isImageFile;
+ /* Basic information. */
+ int isImageFile;
=20
- /* Hack for keeping track of the css status.=20
- * 0: no css, 1: perhaps (need init of keys), 2: have done init */
- int css_state;
- int css_title; /* Last title that we have called dvdinpute_title for=
. */
+ /* Hack for keeping track of the css status.=20
+ * 0: no css, 1: perhaps (need init of keys), 2: have done init */
+ int css_state;
+ int css_title; /* Last title that we have called dvdinpute_title for. =
*/
=20
- /* Information required for an image file. */
- dvd_input_t dev;
+ /* Information required for an image file. */
+ dvd_input_t dev;
=20
- /* Information required for a directory path drive. */
- char *path_root;
+ /* Information required for a directory path drive. */
+ char *path_root;
=20
- /* Filesystem cache */
- int udfcache_level; /* 0 - turned off, 1 - on */
- void *udfcache;
+ /* Filesystem cache */
+ int udfcache_level; /* 0 - turned off, 1 - on */
+ void *udfcache;
+
+ /* block aligned malloc */
+ void *align;
+ =20
+ /* error message verbosity level */
+ int verbose;
};
=20
struct dvd_file_s {
- /* Basic information. */
- dvd_reader_t *dvd;
+ /* Basic information. */
+ dvd_reader_t *dvd;
=20
- /* Hack for selecting the right css title. */
- int css_title;
+ /* Hack for selecting the right css title. */
+ int css_title;
=20
- /* Information required for an image file. */
- uint32_t lb_start;
- uint32_t seek_pos;
+ /* Information required for an image file. */
+ uint32_t lb_start;
+ uint32_t seek_pos;
=20
- /* Information required for a directory path drive. */
- size_t title_sizes[ 9 ];
- dvd_input_t title_devs[ 9 ];
+ /* Information required for a directory path drive. */
+ size_t title_sizes[ 9 ];
+ dvd_input_t title_devs[ 9 ];
=20
- /* Calculated at open-time, size in blocks. */
- ssize_t filesize;
+ /* Calculated at open-time, size in blocks. */
+ ssize_t filesize;
};
=20
+
+#define DVDREAD_VERBOSE_DEFAULT 0
+
+int get_verbose(void)
+{
+ char *dvdread_verbose;
+ int verbose;
+ =20
+ dvdread_verbose =3D getenv("DVDREAD_VERBOSE");
+ if(dvdread_verbose) {
+ verbose =3D (int)strtol(dvdread_verbose, NULL, 0);
+ } else {
+ verbose =3D DVDREAD_VERBOSE_DEFAULT;
+ }
+ return verbose;
+}
+
+int dvdread_verbose(dvd_reader_t *dvd)
+{
+ return dvd->verbose;
+}
+
+dvd_reader_t *device_of_file(dvd_file_t *file)
+{
+ return file->dvd;
+}
+
/**
+ * Returns the compiled version. (DVDREAD_VERSION as an int)
+ */
+int DVDVersion(void)
+{
+ return DVDREAD_VERSION;
+}
+
+
+/**
* Set the level of caching on udf
* level =3D 0 (no caching)
* level =3D 1 (caching filesystem info)
@@ -128,149 +176,213 @@
dev->udfcache =3D cache;
}
=20
+void *GetAlignHandle(dvd_reader_t *device)
+{
+ struct dvd_reader_s *dev =3D (struct dvd_reader_s *)device;
+ =20
+ return dev->align;
+}
=20
-#if defined(WIN32)
-#include <windows.h>
-# define GETTIME(v) v =3D GetTickCount ()
-# define TIMEDIFF(v) (v.end - v.start)
-#else /* !WIN32 */
-# define GETTIME(v) gettimeofday (&v, NULL)
-# define TIMEDIFF(v) (v.end.tv_sec - v.start.tv_sec)
-#endif /* !WIN32 */
+void SetAlignHandle(dvd_reader_t *device, void *align)
+{
+ struct dvd_reader_s *dev =3D (struct dvd_reader_s *)device;
=20
-struct TimeVal
+ dev->align =3D align;
+}
+
+#ifdef WIN32 /* replacement gettimeofday implementation */
+#include <sys/timeb.h>
+#include <winsock.h> // for timeval
+static int gettimeofday( struct timeval *tv, void *tz )
{
-#if defined(WIN32)
- DWORD start;
- DWORD end;
-#else /* !WIN32 */
- struct timeval start;
- struct timeval end;
-#endif /* !WIN32 */
-};
+ struct timeb t;
+ ftime( &t );
+ tv->tv_sec =3D (long)t.time;
+ tv->tv_usec =3D t.millitm * 1000;
+ return 0;
+}
+#endif
=20
=20
/* Loop over all titles and call dvdcss_title to crack the keys. */
static int initAllCSSKeys( dvd_reader_t *dvd )
{
- struct TimeVal all_time;
- struct TimeVal t_time;
- char filename[ MAX_UDF_FILE_NAME_LEN ];
- uint32_t start, len;
- int title;
-=09
- char *nokeys_str =3D getenv("DVDREAD_NOKEYS");
- if(nokeys_str !=3D NULL)
- return 0;
+ struct timeval all_s, all_e;
+ struct timeval t_s, t_e;
+ char filename[ MAX_UDF_FILE_NAME_LEN ];
+ uint32_t start, len;
+ int title;
+ =20
+ char *nokeys_str =3D getenv("DVDREAD_NOKEYS");
+ if(nokeys_str !=3D NULL)
+ return 0;
=20
- LOG_ERROR( stderr, "\n" );
- LOG_ERROR( stderr, "libdvdread: Attempting to retrieve all CSS keys\=
n" );
- LOG_ERROR( stderr, "libdvdread: This can take a _long_ time, "
- "please be patient\n\n" );
-=09
- GETTIME( all_time.start );
-=09
- for( title =3D 0; title < 100; title++ ) {
- GETTIME( t_time.start );
- if( title =3D=3D 0 ) {
- sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
- } else {
- sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, 0 );
- }
- start =3D UDFFindFile( dvd, filename, &len );
- if( start !=3D 0 && len !=3D 0 ) {
- /* Perform CSS key cracking for this title. */
- LOG_ERROR( stderr, "libdvdread: Get key for %s at 0x%08x\n",=20
- filename, start );
- if( dvdinput_title( dvd->dev, (int)start ) < 0 ) {
- LOG_ERROR( stderr, "libdvdread: Error cracking CSS key for %s (0x%08x)=
\n", filename, start);
- }
- GETTIME( t_time.end );
- LOG_ERROR( stderr, "libdvdread: Elapsed time %ld\n", =20
- (long int) TIMEDIFF(t_time) );
- }
- =20
- if( title =3D=3D 0 ) continue;
- =20
- GETTIME( t_time.start );
- sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, 1 );
- start =3D UDFFindFile( dvd, filename, &len );
- if( start =3D=3D 0 || len =3D=3D 0 ) break;
- =20
- /* Perform CSS key cracking for this title. */
- LOG_ERROR( stderr, "libdvdread: Get key for %s at 0x%08x\n",=20
- filename, start );
- if( dvdinput_title( dvd->dev, (int)start ) < 0 ) {
- LOG_ERROR( stderr, "libdvdread: Error cracking CSS key for %s (0x%0=
8x)!!\n", filename, start);
- }
- GETTIME( t_time.end );
- LOG_ERROR( stderr, "libdvdread: Elapsed time %ld\n", =20
- (long int) TIMEDIFF(t_time) );
+ if(dvd->verbose >=3D 1) {
+ fprintf( stderr, "\n" );
+ fprintf( stderr, "libdvdread: Attempting to retrieve all CSS keys\n"=
);
+ fprintf( stderr, "libdvdread: This can take a _long_ time, "
+ "please be patient\n\n" );
+ }
+ gettimeofday(&all_s, NULL);
+ =20
+ for( title =3D 0; title < 100; title++ ) {
+ gettimeofday( &t_s, NULL );
+ if( title =3D=3D 0 ) {
+ sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
+ } else {
+ sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, 0 );
}
- title--;
+ start =3D UDFFindFile( dvd, filename, &len );
+ if( start !=3D 0 && len !=3D 0 ) {
+ /* Perform CSS key cracking for this title. */
+ if(dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Get key for %s at 0x%08x\n",=20
+ filename, start );
+ }
+ if( dvdinput_title( dvd->dev, (int)start ) < 0 ) {
+ if(dvd->verbose >=3D 0) {
+ fprintf( stderr, "libdvdread: Error cracking CSS key for %s (0=
x%08x)\n", filename, start);
+ }
+ }
+ gettimeofday( &t_e, NULL );
+ if(dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Elapsed time %ld\n", =20
+ (long int) t_e.tv_sec - t_s.tv_sec );
+ }
+ }
+ =20
+ if( title =3D=3D 0 ) continue;
+ =20
+ gettimeofday( &t_s, NULL );
+ sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, 1 );
+ start =3D UDFFindFile( dvd, filename, &len );
+ if( start =3D=3D 0 || len =3D=3D 0 ) break;
+ =20
+ /* Perform CSS key cracking for this title. */
+ if(dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Get key for %s at 0x%08x\n",=20
+ filename, start );
+ }
+ if( dvdinput_title( dvd->dev, (int)start ) < 0 ) {
+ if(dvd->verbose >=3D 0) {
+ fprintf( stderr, "libdvdread: Error cracking CSS key for %s (0x%=
08x)!!\n", filename, start);
+ }
+ }
+ gettimeofday( &t_e, NULL );
+ if(dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Elapsed time %ld\n", =20
+ (long int) t_e.tv_sec - t_s.tv_sec );
+ }
+ }
+ title--;
=20
- LOG_ERROR( stderr, "libdvdread: Found %d VTS's\n", title );
- GETTIME( all_time.end );
- LOG_ERROR( stderr, "libdvdread: Elapsed time %ld\n", =20
- (long int) TIMEDIFF(all_time) );
- =20
- return 0;
+ if(dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Found %d VTS's\n", title );
+ }
+ gettimeofday(&all_e, NULL);
+ if(dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Elapsed time %ld\n", =20
+ (long int) all_e.tv_sec - all_s.tv_sec );
+ }
+ return 0;
}
=20
=20
=20
/**
* Open a DVD image or block device file.
+ * Checks if the root directory in the udf image file can be found.
+ * If not it assumes this isn't a valid udf image and returns NULL
*/
static dvd_reader_t *DVDOpenImageFile( const char *location, int have_cs=
s )
{
- dvd_reader_t *dvd;
- dvd_input_t dev;
- =20
- dev =3D dvdinput_open( location );
- if( !dev ) {
- LOG_ERROR( stderr, "libdvdread: Can't open %s for reading\n", location =
);
- return 0;
+ dvd_reader_t *dvd;
+ dvd_input_t dev;
+ int verbose;
+
+ verbose =3D get_verbose();
+
+ dev =3D dvdinput_open( location );
+ if( !dev ) {
+ if(verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Can't open '%s' for reading: %s\n",
+ location, strerror(errno));
}
+ return NULL;
+ }
=20
- dvd =3D (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) );
- if( !dvd ) return 0;
- dvd->isImageFile =3D 1;
- dvd->dev =3D dev;
- dvd->path_root =3D 0;
+ dvd =3D (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) );
+ if( !dvd ) {
+ int tmp_errno =3D errno;
+ dvdinput_close(dev);
+ errno =3D tmp_errno;
+ return NULL;
+ }
+ dvd->verbose =3D verbose;
+ dvd->isImageFile =3D 1;
+ dvd->dev =3D dev;
+ dvd->path_root =3D NULL;
=20
- dvd->udfcache_level =3D DEFAULT_UDF_CACHE_LEVEL;
- dvd->udfcache =3D NULL;
+ dvd->udfcache_level =3D DEFAULT_UDF_CACHE_LEVEL;
+ dvd->udfcache =3D NULL;
=20
- if( have_css ) {
- /* Only if DVDCSS_METHOD =3D title, a bit if it's disc or if
- * DVDCSS_METHOD =3D key but region missmatch. Unfortunaly we
- * don't have that information. */
+ dvd->align =3D NULL;
+
+ if( have_css ) {
+ /* Only if DVDCSS_METHOD =3D title, a bit if it's disc or if
+ * DVDCSS_METHOD =3D key but region missmatch. Unfortunaly we
+ * don't have that information. */
=20
- dvd->css_state =3D 1; /* Need key init. */
+ dvd->css_state =3D 1; /* Need key init. */
+ }
+ dvd->css_title =3D 0;
+ =20
+ /* sanity check, is it a valid UDF image, can we find the root dir */
+ if(!UDFFindFile(dvd, "/", NULL)) {
+ dvdinput_close(dvd->dev);
+ if(dvd->udfcache) {
+ FreeUDFCache(dvd, dvd->udfcache);
}
- dvd->css_title =3D 0;
- =20
- return dvd;
+ if(dvd->align) {
+ if(dvd->verbose >=3D 0) {
+ fprintf(stderr, "libdvdread: DVDOpenImageFile(): Memory leak in =
align functions 1\n");
+ }
+ }
+ free(dvd);
+ return NULL;
+ }
+ return dvd;
}
=20
static dvd_reader_t *DVDOpenPath( const char *path_root )
{
- dvd_reader_t *dvd;
+ dvd_reader_t *dvd;
=20
- dvd =3D (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) );
- if( !dvd ) return 0;
- dvd->isImageFile =3D 0;
- dvd->dev =3D 0;
- dvd->path_root =3D strdup( path_root );
+ dvd =3D (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) );
+ if( !dvd ) {
+ return NULL;
+ }
+ dvd->verbose =3D get_verbose();
+ dvd->isImageFile =3D 0;
+ dvd->dev =3D 0;
+#if defined(_CRT_NONSTDC_DEPRECATE)
+ dvd->path_root =3D _strdup( path_root );
+#else
+ dvd->path_root =3D strdup( path_root );
+#endif
+ if(!dvd->path_root) {
+ free(dvd);
+ return 0;
+ }
+ dvd->udfcache_level =3D DEFAULT_UDF_CACHE_LEVEL;
+ dvd->udfcache =3D NULL;
=20
- dvd->udfcache_level =3D DEFAULT_UDF_CACHE_LEVEL;
- dvd->udfcache =3D NULL;
- =20
- dvd->css_state =3D 0; /* Only used in the UDF path */
- dvd->css_title =3D 0; /* Only matters in the UDF path */
+ dvd->align =3D NULL;
=20
- return dvd;
+ dvd->css_state =3D 0; /* Only used in the UDF path */
+ dvd->css_title =3D 0; /* Only matters in the UDF path */
+
+ return dvd;
}
=20
#if defined(__sun)
@@ -279,254 +391,339 @@
/vol/rdsk/<name> */
static char *sun_block2char( const char *path )
{
- char *new_path;
+ char *new_path;
=20
- /* Must contain "/dsk/" */=20
- if( !strstr( path, "/dsk/" ) ) return (char *) strdup( path );
+ /* Must contain "/dsk/" */=20
+ if( !strstr( path, "/dsk/" ) ) return (char *) strdup( path );
=20
- /* Replace "/dsk/" with "/rdsk/" */
- new_path =3D malloc( strlen(path) + 2 );
- strcpy( new_path, path );
- strcpy( strstr( new_path, "/dsk/" ), "" );
- strcat( new_path, "/rdsk/" );
- strcat( new_path, strstr( path, "/dsk/" ) + strlen( "/dsk/" ) );
+ /* Replace "/dsk/" with "/rdsk/" */
+ new_path =3D malloc( strlen(path) + 2 );
+ strcpy( new_path, path );
+ strcpy( strstr( new_path, "/dsk/" ), "" );
+ strcat( new_path, "/rdsk/" );
+ strcat( new_path, strstr( path, "/dsk/" ) + strlen( "/dsk/" ) );
=20
- return new_path;
+ return new_path;
}
#endif
=20
#if defined(SYS_BSD)
/* FreeBSD /dev/(r)(a)cd0c (a is for atapi), recomended to _not_ use r
+ update: FreeBSD and DragonFly no longer uses the prefix so don't add =
it.
+
OpenBSD /dev/rcd0c, it needs to be the raw device
NetBSD /dev/rcd0[d|c|..] d for x86, c (for non x86), perhaps others
Darwin /dev/rdisk0, it needs to be the raw device
- BSD/OS /dev/sr0c (if not mounted) or /dev/rsr0c ('c' any letter will=
do) */
+ BSD/OS /dev/sr0c (if not mounted) or /dev/rsr0c ('c' any letter will=
do)
+ =20
+ returns a string allocated with strdup which should be free()'d when
+ no longer used.
+*/
static char *bsd_block2char( const char *path )
{
- char *new_path;
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+ return (char *) strdup( path );
+#else
+ char *new_path;
=20
- /* If it doesn't start with "/dev/" or does start with "/dev/r" exit=
*/=20
- if( !strncmp( path, "/dev/", 5 ) || strncmp( path, "/dev/r", 6 ) )=20
- return (char *) strdup( path );
+ /* If it doesn't start with "/dev/" or does start with "/dev/r" exit *=
/=20
+ if( strncmp( path, "/dev/", 5 ) || !strncmp( path, "/dev/r", 6 ) )=20
+ return (char *) strdup( path );
=20
- /* Replace "/dev/" with "/dev/r" */
- new_path =3D malloc( strlen(path) + 2 );
- strcpy( new_path, "/dev/r" );
- strcat( new_path, path + strlen( "/dev/" ) );
+ /* Replace "/dev/" with "/dev/r" */
+ new_path =3D malloc( strlen(path) + 2 );
+ strcpy( new_path, "/dev/r" );
+ strcat( new_path, path + strlen( "/dev/" ) );
=20
- return new_path;
+ return new_path;
+#endif /* __FreeBSD__ || __DragonFly__ */
}
#endif
=20
+
dvd_reader_t *DVDOpen( const char *path )
{
- struct stat fileinfo;
- int ret, have_css;
- char *dev_name =3D 0;
+ struct stat fileinfo;
+ int ret, have_css;
+ char *dev_name =3D NULL;
+ int internal_errno =3D 0;
+ int verbose;
=20
- if( path =3D=3D NULL )
- return 0;
+ if( path =3D=3D NULL ) {
+ errno =3D EINVAL;
+ return NULL;
+ }
+ =20
+ verbose =3D get_verbose();
=20
- ret =3D stat( path, &fileinfo );
- if( ret < 0 ) {
- /* If we can't stat the file, give up */
- LOG_ERROR( stderr, "libdvdread: Can't stat %s\n", path );
- perror("");
- return 0;
+#ifdef WIN32
+ /* Stat doesn't work on devices under mingwin/cygwin. */
+ //if( path[0] && path[1] =3D=3D ':' && path[2] =3D=3D '\0' )
+ // {
+ // /* Don't try to stat the file */
+ // fileinfo.st_mode =3D S_IFBLK;
+ // }
+ //else
+#endif
+ {
+ ret =3D stat( path, &fileinfo );
+ if( ret < 0 ) {
+ int tmp_errno =3D errno;
+ /* If we can't stat the file, give up */
+ if(verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Can't stat '%s': %s\n",
+ path, strerror(errno));
+ }
+ errno =3D tmp_errno;
+ return NULL;
+ }
}
=20
- /* Try to open libdvdcss or fall back to standard functions */
- have_css =3D dvdinput_setup();
+ /* Try to open libdvdcss or fall back to standard functions */
+ have_css =3D dvdinput_setup();
=20
- /* First check if this is a block/char device or a file*/
- if( S_ISBLK( fileinfo.st_mode ) ||=20
- S_ISCHR( fileinfo.st_mode ) ||=20
- S_ISREG( fileinfo.st_mode ) ) {
-
- /**
- * Block devices and regular files are assumed to be DVD-Video images.
- */
+ /* First check if this is a block/char device or a file*/
+ if( S_ISBLK( fileinfo.st_mode ) ||=20
+ S_ISCHR( fileinfo.st_mode ) ||=20
+ S_ISREG( fileinfo.st_mode ) ) {
+ /**
+ * Block devices and regular files are assumed to be DVD-Video image=
s.
+ */
+ dvd_reader_t *dvd =3D NULL;
#if defined(__sun)
- return DVDOpenImageFile( sun_block2char( path ), have_css );
+ dev_name =3D sun_block2char( path );
#elif defined(SYS_BSD)
- return DVDOpenImageFile( bsd_block2char( path ), have_css );
+ dev_name =3D bsd_block2char( path );
+#elif defined(_CRT_NONSTDC_DEPRECATE)
+ dev_name =3D _strdup( path );
#else
- return DVDOpenImageFile( path, have_css );
+ dev_name =3D strdup( path );
#endif
-
- } else if( S_ISDIR( fileinfo.st_mode ) ) {
- dvd_reader_t *auth_drive =3D 0;
- char *path_copy;
+ dvd =3D DVDOpenImageFile( dev_name, have_css );
+ free( dev_name );
+ =20
+ return dvd;
+ } else if( S_ISDIR( fileinfo.st_mode ) ) {
+ dvd_reader_t *auth_drive =3D 0;
+ char *path_copy;
#if defined(SYS_BSD)
- struct fstab* fe;
+ struct fstab* fe;
#elif defined(__sun) || defined(__linux__)
- FILE *mntfile;
+ FILE *mntfile;
#endif
=20
- /* XXX: We should scream real loud here. */
- if( !(path_copy =3D strdup( path ) ) ) return 0;
-
- /* Resolve any symlinks and get the absolut dir name. */
-#if !defined(WIN32)
- {
-#ifdef __BEOS__
- char *current_path;
-#endif
- char *new_path;
-#ifndef __BEOS__
- int cdir =3D open( ".", O_RDONLY );
- =20
- if( cdir >=3D 0 ) {
+ /* XXX: We should scream real loud here. */
+#if defined(_CRT_NONSTDC_DEPRECATE)
+ if( !(path_copy =3D _strdup( path ) ) ) return 0;
#else
- current_path =3D getcwd( NULL, PATH_MAX );
- if( current_path ) {
+ if( !(path_copy =3D strdup( path ) ) ) return 0;
#endif
- chdir( path_copy );
- new_path =3D getcwd( NULL, PATH_MAX );
-#ifndef __BEOS__
- fchdir( cdir );
- close( cdir );
-#else
- chdir( current_path );
-#endif
- if( new_path ) {
- free( path_copy );
- path_copy =3D new_path;
- }
- }
- }
-#endif
-=09
- /**
- * If we're being asked to open a directory, check if that directory
- * is the mountpoint for a DVD-ROM which we can use instead.
- */
=20
- if( strlen( path_copy ) > 1 ) {
-#if !defined(WIN32)
- if( path_copy[ strlen( path_copy ) - 1 ] =3D=3D '/' )=20
- path_copy[ strlen( path_copy ) - 1 ] =3D '\0';
-#else
- if( path_copy[ strlen( path_copy ) - 1 ] =3D=3D '\\' )=20
- path_copy[ strlen( path_copy ) - 1 ] =3D '\0';
+#ifndef WIN32 /* don't have fchdir, and getcwd( NULL, ... ) is strange *=
/
+ /* Resolve any symlinks and get the absolut dir name. */
+ {
+ char *new_path;
+ char *current_path;
+
+ current_path =3D malloc(PATH_MAX);
+ if(current_path) {
+ if(!getcwd(current_path, PATH_MAX)) {
+ free(current_path);
+ current_path =3D NULL;
+ }
+ }
+ if(current_path) {
+ chdir( path_copy );
+ new_path =3D malloc(PATH_MAX);
+ if(new_path) {
+ if(!getcwd(new_path, PATH_MAX )) {
+ free(new_path);
+ new_path =3D NULL;
+ }
+ }
+
+ chdir(current_path);
+ free(current_path);
+ if( new_path ) {
+ free( path_copy );
+ path_copy =3D new_path;
+ }
+ }
+ }
#endif
- }
+ =20
+ /**
+ * If we're being asked to open a directory, check if that directory
+ * is the mountpoint for a DVD-ROM which we can use instead.
+ */
=20
- if( strlen( path_copy ) > 9 ) {
- if( !strcasecmp( &(path_copy[ strlen( path_copy ) - 9 ]),=20
- "/video_ts" ) ) {
- path_copy[ strlen( path_copy ) - 9 ] =3D '\0';
- }
- }
+ if( strlen( path_copy ) > 1 ) {
+ if( path_copy[ strlen( path_copy ) - 1 ] =3D=3D '/' ) {
+ path_copy[ strlen( path_copy ) - 1 ] =3D '\0';
+ }
+ }
=20
+ if( strlen( path_copy ) >=3D 9 ) {
+ if( !strcasecmp( &(path_copy[ strlen( path_copy ) - 9 ]),=20
+ "/video_ts" ) ) {
+ path_copy[ strlen( path_copy ) - 9 ] =3D '\0';
+ if(path_copy[0] =3D=3D '\0') {
+ path_copy[0] =3D '/';
+ path_copy[1] =3D '\0';
+ }
+ }
+ }
+
#if defined(SYS_BSD)
- if( ( fe =3D getfsfile( path_copy ) ) ) {
- dev_name =3D bsd_block2char( fe->fs_spec );
- LOG_ERROR( stderr,=20
- "libdvdread: Attempting to use device %s"
- " mounted on %s for CSS authentication\n",
- dev_name,
- fe->fs_file );
- auth_drive =3D DVDOpenImageFile( dev_name, have_css );
- }
+ if( ( fe =3D getfsfile( path_copy ) ) ) {
+ dev_name =3D bsd_block2char( fe->fs_spec );
+ if(verbose >=3D 1) {
+ fprintf( stderr,
+ "libdvdread: Attempting to use device %s"
+ " mounted on %s%s\n",
+ dev_name,
+ fe->fs_file,
+ have_css ? " for CSS authentication" : "");
+ }
+ auth_drive =3D DVDOpenImageFile( dev_name, have_css );
+ if(!auth_drive) {
+ internal_errno =3D errno;
+ }
+ }
#elif defined(__sun)
- mntfile =3D fopen( MNTTAB, "r" );
- if( mntfile ) {
- struct mnttab mp;
- int res;
-
- while( ( res =3D getmntent( mntfile, &mp ) ) !=3D -1 ) {
- if( res =3D=3D 0 && !strcmp( mp.mnt_mountp, path_copy ) ) {
- dev_name =3D sun_block2char( mp.mnt_special );
- LOG_ERROR( stderr,=20
- "libdvdread: Attempting to use device %s"
- " mounted on %s for CSS authentication\n",
- dev_name,
- mp.mnt_mountp );
- auth_drive =3D DVDOpenImageFile( dev_name, have_css );
- break;
- }
- }
- fclose( mntfile );
- }
+ mntfile =3D fopen( MNTTAB, "r" );
+ if( mntfile ) {
+ struct mnttab mp;
+ int res;
+ =20
+ while( ( res =3D getmntent( mntfile, &mp ) ) !=3D -1 ) {
+ if( res =3D=3D 0 && !strcmp( mp.mnt_mountp, path_copy ) ) {
+ dev_name =3D sun_block2char( mp.mnt_special );
+ if(verbose >=3D 1) {
+ fprintf( stderr,=20
+ "libdvdread: Attempting to use device %s"
+ " mounted on %s%s\n",
+ dev_name,
+ mp.mnt_mountp,
+ have_css ? " for CSS authentication" : "");
+ }
+ auth_drive =3D DVDOpenImageFile( dev_name, have_css );
+ if(!auth_drive) {
+ internal_errno =3D errno;
+ }
+ break;
+ }
+ }
+ fclose( mntfile );
+ }
#elif defined(__linux__)
- mntfile =3D fopen( MOUNTED, "r" );
- if( mntfile ) {
- struct mntent *me;
+ mntfile =3D fopen( MOUNTED, "r" );
+ if( mntfile ) {
+ struct mntent *me;
=20
- while( ( me =3D getmntent( mntfile ) ) ) {
- if( !strcmp( me->mnt_dir, path_copy ) ) {
- LOG_ERROR( stderr,=20
- "libdvdread: Attempting to use device %s"
- " mounted on %s for CSS authentication\n",
- me->mnt_fsname,
- me->mnt_dir );
- auth_drive =3D DVDOpenImageFile( me->mnt_fsname, hav=
e_css );
- dev_name =3D strdup(me->mnt_fsname);
- break;
- }
- }
- fclose( mntfile );
- }
+ while( ( me =3D getmntent( mntfile ) ) ) {
+ if( !strcmp( me->mnt_dir, path_copy ) ) {
+ if(verbose >=3D 1) {
+ fprintf( stderr,=20
+ "libdvdread: Attempting to use device %s"
+ " mounted on %s%s\n",
+ me->mnt_fsname,
+ me->mnt_dir,
+ have_css ? " for CSS authentication" : "");
+ }
+ auth_drive =3D DVDOpenImageFile( me->mnt_fsname, have_css );
+ if(!auth_drive) {
+ internal_errno =3D errno;
+ }
+ dev_name =3D strdup(me->mnt_fsname);
+ break;
+ }
+ }
+ fclose( mntfile );
+ }
#endif
- if( !dev_name ) {
- LOG_ERROR( stderr, "libdvdread: Couldn't find device name.\n" );
- } else if( !auth_drive ) {
- LOG_ERROR( stderr, "libdvdread: Device %s inaccessible, "
- "CSS authentication not available.\n", dev_name );
- }
+ if( !dev_name ) {
+ if(verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Couldn't find device name.\n" );
+ }
+ } else if( !auth_drive ) {
+ if(verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Device %s inaccessible%s: %s\n",
+ dev_name,
+ have_css ? ", CSS authentication not available" : "",
+ strerror(internal_errno));
+ }
+ }
=20
- free( dev_name );
- free( path_copy );
+ free( dev_name );
+ free( path_copy );
=20
- /**
- * If we've opened a drive, just use that.
- */
- if( auth_drive ) return auth_drive;
-
- /**
- * Otherwise, we now try to open the directory tree instead.
- */
- return DVDOpenPath( path );
+ /**
+ * If we've opened a drive, just use that.
+ */
+ if( auth_drive ) {
+ return auth_drive;
}
+ /**
+ * Otherwise, we now try to open the directory tree instead.
+ */
+ return DVDOpenPath( path );
+ }
=20
- /* If it's none of the above, screw it. */
- LOG_ERROR( stderr, "libdvdread: Could not open %s\n", path );
- return 0;
+ /* If it's none of the above, screw it. */
+ if(verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Could not open %s\n", path );
+ }
+ return 0;
}
=20
void DVDClose( dvd_reader_t *dvd )
{
- if( dvd ) {
- if( dvd->dev ) dvdinput_close( dvd->dev );
- if( dvd->path_root ) free( dvd->path_root );
- if( dvd->udfcache ) FreeUDFCache( dvd->udfcache );
- free( dvd );
+ if( dvd ) {
+ if( dvd->dev ) dvdinput_close( dvd->dev );
+ if( dvd->path_root ) free( dvd->path_root );
+ if( dvd->udfcache ) FreeUDFCache( dvd, dvd->udfcache );
+ if(dvd->align) {
+ if(dvd->verbose >=3D 0) {
+ fprintf(stderr, "libdvdread: DVDClose(): Memory leak in align fu=
nctions\n");
+ }
}
- dvdinput_unsetup();
+
+ free( dvd );
+ }
}
=20
+void DVDInit(void)
+{
+ dvdinput_setup();
+}
+
+void DVDFinish(void)
+{
+ dvdinput_free();
+}
+
/**
* Open an unencrypted file on a DVD image file.
*/
static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *dvd, char *filename )
{
- uint32_t start, len;
- dvd_file_t *dvd_file;
+ uint32_t start, len;
+ dvd_file_t *dvd_file;
=20
- start =3D UDFFindFile( dvd, filename, &len );
- if( !start ) return 0;
+ start =3D UDFFindFile( dvd, filename, &len );
+ if( !start ) return 0;
=20
- dvd_file =3D (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
- if( !dvd_file ) return 0;
- dvd_file->dvd =3D dvd;
- dvd_file->lb_start =3D start;
- dvd_file->seek_pos =3D 0;
- memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
- memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
- dvd_file->filesize =3D len / DVD_VIDEO_LB_LEN;
+ dvd_file =3D (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
+ if( !dvd_file ) return 0;
+ dvd_file->dvd =3D dvd;
+ dvd_file->lb_start =3D start;
+ dvd_file->seek_pos =3D 0;
+ memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
+ memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
+ dvd_file->filesize =3D len / DVD_VIDEO_LB_LEN;
=20
- return dvd_file;
+ return dvd_file;
}
=20
/**
@@ -537,55 +734,54 @@
*/
static int findDirFile( const char *path, const char *file, char *filena=
me )=20
{
- DIR *dir;
- struct dirent *ent;
+ DIR *dir;
+ struct dirent *ent;
=20
- dir =3D opendir( path );
- if( !dir ) return -2;
+ dir =3D opendir( path );
+ if( !dir ) return -2;
=20
- while( ( ent =3D readdir( dir ) ) !=3D NULL ) {
- if( !strcasecmp( ent->d_name, file ) ) {
- sprintf( filename, "%s%s%s", path,
- ( ( path[ strlen( path ) - 1 ] =3D=3D '/' ) ? "" : =
"/" ),
- ent->d_name );
- closedir(dir);
- return 0;
- }
+ while( ( ent =3D readdir( dir ) ) !=3D NULL ) {
+ if( !strcasecmp( ent->d_name, file ) ) {
+ sprintf( filename, "%s%s%s", path,
+ ( ( path[ strlen( path ) - 1 ] =3D=3D '/' ) ? "" : "/" ),
+ ent->d_name );
+ closedir(dir);
+ return 0;
}
-
- closedir(dir);
- return -1;
+ }
+ closedir(dir);
+ return -1;
}
=20
static int findDVDFile( dvd_reader_t *dvd, const char *file, char *filen=
ame )
{
- char video_path[ PATH_MAX + 1 ];
- const char *nodirfile;
- int ret;
+ char video_path[ PATH_MAX + 1 ];
+ const char *nodirfile;
+ int ret;
=20
- /* Strip off the directory for our search */
- if( !strncasecmp( "/VIDEO_TS/", file, 10 ) ) {
- nodirfile =3D &(file[ 10 ]);
- } else {
- nodirfile =3D file;
- }
+ /* Strip off the directory for our search */
+ if( !strncasecmp( "/VIDEO_TS/", file, 10 ) ) {
+ nodirfile =3D &(file[ 10 ]);
+ } else {
+ nodirfile =3D file;
+ }
=20
- ret =3D findDirFile( dvd->path_root, nodirfile, filename );
+ ret =3D findDirFile( dvd->path_root, nodirfile, filename );
+ if( ret < 0 ) {
+ /* Try also with adding the path, just in case. */
+ sprintf( video_path, "%s/VIDEO_TS/", dvd->path_root );
+ ret =3D findDirFile( video_path, nodirfile, filename );
if( ret < 0 ) {
- /* Try also with adding the path, just in case. */
- sprintf( video_path, "%s/VIDEO_TS/", dvd->path_root );
- ret =3D findDirFile( video_path, nodirfile, filename );
- if( ret < 0 ) {
- /* Try with the path, but in lower case. */
- sprintf( video_path, "%s/video_ts/", dvd->path_root );
- ret =3D findDirFile( video_path, nodirfile, filename );
- if( ret < 0 ) {
- return 0;
- }
- }
+ /* Try with the path, but in lower case. */
+ sprintf( video_path, "%s/video_ts/", dvd->path_root );
+ ret =3D findDirFile( video_path, nodirfile, filename );
+ if( ret < 0 ) {
+ return 0;
+ }
}
+ }
=20
- return 1;
+ return 1;
}
=20
/**
@@ -593,510 +789,787 @@
*/
static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, char *filename )
{
- char full_path[ PATH_MAX + 1 ];
- dvd_file_t *dvd_file;
- struct stat fileinfo;
- dvd_input_t dev;
+ char full_path[ PATH_MAX + 1 ];
+ dvd_file_t *dvd_file;
+ struct stat fileinfo;
+ dvd_input_t dev;
=20
- /* Get the full path of the file. */
- if( !findDVDFile( dvd, filename, full_path ) ) return 0;
+ /* Get the full path of the file. */
+ if( !findDVDFile( dvd, filename, full_path ) ) return 0;
=20
- dev =3D dvdinput_open( full_path );
- if( !dev ) return 0;
+ dev =3D dvdinput_open( full_path );
+ if( !dev ) return 0;
=20
- dvd_file =3D (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
- if( !dvd_file ) return 0;
- dvd_file->dvd =3D dvd;
- dvd_file->lb_start =3D 0;
- dvd_file->seek_pos =3D 0;
- memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
- memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
- dvd_file->filesize =3D 0;
+ dvd_file =3D (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
+ if( !dvd_file ) return 0;
+ dvd_file->dvd =3D dvd;
+ dvd_file->lb_start =3D 0;
+ dvd_file->seek_pos =3D 0;
+ memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
+ memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
+ dvd_file->filesize =3D 0;
=20
- if( stat( full_path, &fileinfo ) < 0 ) {
- LOG_ERROR( stderr, "libdvdread: Can't stat() %s.\n", filename );
- free( dvd_file );
- return 0;
+ if( stat( full_path, &fileinfo ) < 0 ) {
+ if(dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
}
- dvd_file->title_sizes[ 0 ] =3D fileinfo.st_size / DVD_VIDEO_LB_LEN;
- dvd_file->title_devs[ 0 ] =3D dev;
- dvd_file->filesize =3D dvd_file->title_sizes[ 0 ];
+ free( dvd_file );
+ return 0;
+ }
+ dvd_file->title_sizes[ 0 ] =3D fileinfo.st_size / DVD_VIDEO_LB_LEN;
+ dvd_file->title_devs[ 0 ] =3D dev;
+ dvd_file->filesize =3D dvd_file->title_sizes[ 0 ];
=20
- return dvd_file;
+ return dvd_file;
}
=20
static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd, int title, int menu=
)
{
- char filename[ MAX_UDF_FILE_NAME_LEN ];
- uint32_t start, len;
- dvd_file_t *dvd_file;
+ char filename[ MAX_UDF_FILE_NAME_LEN ];
+ uint32_t start, len;
+ dvd_file_t *dvd_file;
=20
- if( title =3D=3D 0 ) {
- sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
- } else {
- sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 =
: 1 );
- }
- start =3D UDFFindFile( dvd, filename, &len );
- if( start =3D=3D 0 ) return 0;
+ if( title =3D=3D 0 ) {
+ sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
+ } else {
+ sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 =
);
+ }
+ start =3D UDFFindFile( dvd, filename, &len );
+ if( start =3D=3D 0 ) return 0;
=20
- dvd_file =3D (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
- if( !dvd_file ) return 0;
- dvd_file->dvd =3D dvd;
- /*Hack*/ dvd_file->css_title =3D title << 1 | menu;
- dvd_file->lb_start =3D start;
- dvd_file->seek_pos =3D 0;
- memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
- memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
- dvd_file->filesize =3D len / DVD_VIDEO_LB_LEN;
+ dvd_file =3D (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
+ if( !dvd_file ) return 0;
+ dvd_file->dvd =3D dvd;
+ /*Hack*/ dvd_file->css_title =3D title << 1 | menu;
+ dvd_file->lb_start =3D start;
+ dvd_file->seek_pos =3D 0;
+ memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
+ memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
+ dvd_file->filesize =3D len / DVD_VIDEO_LB_LEN;
=20
- /* Calculate the complete file size for every file in the VOBS */
- if( !menu ) {
- int cur;
+ /* Calculate the complete file size for every file in the VOBS */
+ if( !menu ) {
+ int cur;
=20
- for( cur =3D 2; cur < 10; cur++ ) {
- sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur )=
;
- if( !UDFFindFile( dvd, filename, &len ) ) break;
- dvd_file->filesize +=3D len / DVD_VIDEO_LB_LEN;
- }
+ for( cur =3D 2; cur < 10; cur++ ) {
+ sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur );
+ if( !UDFFindFile( dvd, filename, &len ) ) break;
+ dvd_file->filesize +=3D len / DVD_VIDEO_LB_LEN;
}
+ }
=20
- if( dvd->css_state =3D=3D 1 /* Need key init */ ) {
- initAllCSSKeys( dvd );
- dvd->css_state =3D 2;
- }
- /* =20
- if( dvdinput_title( dvd_file->dvd->dev, (int)start ) < 0 ) {
- LOG_ERROR( stderr, "libdvdread: Error cracking CSS key for %s\n"=
,
- filename );
- }
- */
+ if( dvd->css_state =3D=3D 1 /* Need key init */ ) {
+ initAllCSSKeys( dvd );
+ dvd->css_state =3D 2;
+ }
+ /* =20
+ if( dvdinput_title( dvd_file->dvd->dev, (int)start ) < 0 ) {
+ fprintf( stderr, "libdvdread: Error cracking CSS key for %s\n",
+ filename );
+ }
+ */
=20
- return dvd_file;
+ return dvd_file;
}
=20
static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, int title, int men=
u )
{
- char filename[ MAX_UDF_FILE_NAME_LEN ];
- char full_path[ PATH_MAX + 1 ];
- struct stat fileinfo;
- dvd_file_t *dvd_file;
- int i;
+ char filename[ MAX_UDF_FILE_NAME_LEN ];
+ char full_path[ PATH_MAX + 1 ];
+ struct stat fileinfo;
+ dvd_file_t *dvd_file;
+ int i;
=20
- dvd_file =3D (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
- if( !dvd_file ) return 0;
- dvd_file->dvd =3D dvd;
- /*Hack*/ dvd_file->css_title =3D title << 1 | menu;
- dvd_file->lb_start =3D 0;
- dvd_file->seek_pos =3D 0;
- memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
- memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
- dvd_file->filesize =3D 0;
+ dvd_file =3D (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
+ if( !dvd_file ) return 0;
+ dvd_file->dvd =3D dvd;
+ /*Hack*/ dvd_file->css_title =3D title << 1 | menu;
+ dvd_file->lb_start =3D 0;
+ dvd_file->seek_pos =3D 0;
+ memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
+ memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
+ dvd_file->filesize =3D 0;
=20
- if( menu ) {
- dvd_input_t dev;
+ if( menu ) {
+ dvd_input_t dev;
=20
- if( title =3D=3D 0 ) {
- sprintf( filename, "VIDEO_TS.VOB" );
- } else {
- sprintf( filename, "VTS_%02i_0.VOB", title );
- }
- if( !findDVDFile( dvd, filename, full_path ) ) {
- free( dvd_file );
- return 0;
- }
+ if( title =3D=3D 0 ) {
+ sprintf( filename, "VIDEO_TS.VOB" );
+ } else {
+ sprintf( filename, "VTS_%02i_0.VOB", title );
+ }
+ if( !findDVDFile( dvd, filename, full_path ) ) {
+ free( dvd_file );
+ return 0;
+ }
=20
- dev =3D dvdinput_open( full_path );
- if( dev =3D=3D NULL ) {
- free( dvd_file );
- return 0;
- }
+ dev =3D dvdinput_open( full_path );
+ if( dev =3D=3D NULL ) {
+ free( dvd_file );
+ return 0;
+ }
=20
- if( stat( full_path, &fileinfo ) < 0 ) {
- LOG_ERROR( stderr, "libdvdread: Can't stat() %s.\n", filenam=
e );
- free( dvd_file );
- return 0;
- }
- dvd_file->title_sizes[ 0 ] =3D fileinfo.st_size / DVD_VIDEO_LB_L=
EN;
- dvd_file->title_devs[ 0 ] =3D dev;
- dvdinput_title( dvd_file->title_devs[0], 0);
- dvd_file->filesize =3D dvd_file->title_sizes[ 0 ];
+ if( stat( full_path, &fileinfo ) < 0 ) {
+ if(dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
+ }
+ free( dvd_file );
+ return 0;
+ }
+ dvd_file->title_sizes[ 0 ] =3D fileinfo.st_size / DVD_VIDEO_LB_LEN;
+ dvd_file->title_devs[ 0 ] =3D dev;
+ dvdinput_title( dvd_file->title_devs[0], 0);
+ dvd_file->filesize =3D dvd_file->title_sizes[ 0 ];
=20
- } else {
- for( i =3D 0; i < 9; ++i ) {
+ } else {
+ for( i =3D 0; i < 9; ++i ) {
=20
- sprintf( filename, "VTS_%02i_%i.VOB", title, i + 1 );
- if( !findDVDFile( dvd, filename, full_path ) ) {
- break;
- }
+ sprintf( filename, "VTS_%02i_%i.VOB", title, i + 1 );
+ if( !findDVDFile( dvd, filename, full_path ) ) {
+ break;
+ }
=20
- if( stat( full_path, &fileinfo ) < 0 ) {
- LOG_ERROR( stderr, "libdvdread: Can't stat() %s.\n", fil=
ename );
- break;
- }
+ if( stat( full_path, &fileinfo ) < 0 ) {
+ if(dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
+ }
+ break;
+ }
=20
- dvd_file->title_sizes[ i ] =3D fileinfo.st_size / DVD_VIDEO_=
LB_LEN;
- dvd_file->title_devs[ i ] =3D dvdinput_open( full_path );
- dvdinput_title( dvd_file->title_devs[ i ], 0 );
- dvd_file->filesize +=3D dvd_file->title_sizes[ i ];
- }
- if( !dvd_file->title_devs[ 0 ] ) {
- free( dvd_file );
- return 0;
- }
+ dvd_file->title_sizes[ i ] =3D fileinfo.st_size / DVD_VIDEO_LB_LEN=
;
+ dvd_file->title_devs[ i ] =3D dvdinput_open( full_path );
+ dvdinput_title( dvd_file->title_devs[ i ], 0 );
+ dvd_file->filesize +=3D dvd_file->title_sizes[ i ];
}
+ if( !dvd_file->title_devs[ 0 ] ) {
+ free( dvd_file );
+ return 0;
+ }
+ }
=20
- return dvd_file;
+ return dvd_file;
}
=20
dvd_file_t *DVDOpenFile( dvd_reader_t *dvd, int titlenum,=20
- dvd_read_domain_t domain )
+ dvd_read_domain_t domain )
{
- char filename[ MAX_UDF_FILE_NAME_LEN ];
+ char filename[ MAX_UDF_FILE_NAME_LEN ];
=20
- /* Check arguments. */
- if( dvd =3D=3D NULL || titlenum < 0 )
- return NULL;
+ /* Check arguments. */
+ if( dvd =3D=3D NULL || titlenum < 0 ) {
+ errno =3D EINVAL;
+ return NULL;
+ }
=20
- switch( domain ) {
- case DVD_READ_INFO_FILE:
- if( titlenum =3D=3D 0 ) {
- sprintf( filename, "/VIDEO_TS/VIDEO_TS.IFO" );
- } else {
- sprintf( filename, "/VIDEO_TS/VTS_%02i_0.IFO", titlenum );
- }
- break;
- case DVD_READ_INFO_BACKUP_FILE:
- if( titlenum =3D=3D 0 ) {
- sprintf( filename, "/VIDEO_TS/VIDEO_TS.BUP" );
- } else {
- sprintf( filename, "/VIDEO_TS/VTS_%02i_0.BUP", titlenum );
- }
- break;
- case DVD_READ_MENU_VOBS:
- if( dvd->isImageFile ) {
- return DVDOpenVOBUDF( dvd, titlenum, 1 );
- } else {
- return DVDOpenVOBPath( dvd, titlenum, 1 );
- }
- break;
- case DVD_READ_TITLE_VOBS:
- if( titlenum =3D=3D 0 ) return 0;
- if( dvd->isImageFile ) {
- return DVDOpenVOBUDF( dvd, titlenum, 0 );
- } else {
- return DVDOpenVOBPath( dvd, titlenum, 0 );
- }
- break;
- default:
- LOG_ERROR( stderr, "libdvdread: Invalid domain for file open.\n"=
);
- return NULL;
+ switch( domain ) {
+ case DVD_READ_INFO_FILE:
+ if( titlenum =3D=3D 0 ) {
+ sprintf( filename, "/VIDEO_TS/VIDEO_TS.IFO" );
+ } else {
+ sprintf( filename, "/VIDEO_TS/VTS_%02i_0.IFO", titlenum );
}
- =20
+ break;
+ case DVD_READ_INFO_BACKUP_FILE:
+ if( titlenum =3D=3D 0 ) {
+ sprintf( filename, "/VIDEO_TS/VIDEO_TS.BUP" );
+ } else {
+ sprintf( filename, "/VIDEO_TS/VTS_%02i_0.BUP", titlenum );
+ }
+ break;
+ case DVD_READ_MENU_VOBS:
if( dvd->isImageFile ) {
- return DVDOpenFileUDF( dvd, filename );
+ return DVDOpenVOBUDF( dvd, titlenum, 1 );
} else {
- return DVDOpenFilePath( dvd, filename );
+ return DVDOpenVOBPath( dvd, titlenum, 1 );
}
+ break;
+ case DVD_READ_TITLE_VOBS:
+ if( titlenum =3D=3D 0 ) return 0;
+ if( dvd->isImageFile ) {
+ return DVDOpenVOBUDF( dvd, titlenum, 0 );
+ } else {
+ return DVDOpenVOBPath( dvd, titlenum, 0 );
+ }
+ break;
+ default:
+ if(dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Invalid domain for file open.\n" );
+ }
+ errno =3D EINVAL;
+ return NULL;
+ }
+ =20
+ if( dvd->isImageFile ) {
+ return DVDOpenFileUDF( dvd, filename );
+ } else {
+ return DVDOpenFilePath( dvd, filename );
+ }
}
=20
void DVDCloseFile( dvd_file_t *dvd_file )
{
- int i;
+ int i;
=20
- if( dvd_file ) {
- if( dvd_file->dvd->isImageFile ) {
- ;
- } else {
- for( i =3D 0; i < 9; ++i ) {
- if( dvd_file->title_devs[ i ] ) {
- dvdinput_close( dvd_file->title_devs[i] );
- }
- }
+ if( dvd_file ) {
+ if( dvd_file->dvd->isImageFile ) {
+ ;
+ } else {
+ for( i =3D 0; i < 9; ++i ) {
+ if( dvd_file->title_devs[ i ] ) {
+ dvdinput_close( dvd_file->title_devs[i] );
}
+ }
+ }
=20
- free( dvd_file );
- dvd_file =3D 0;
+ free( dvd_file );
+ dvd_file =3D 0;
+ }
+}
+
+static int DVDFileStatVOBUDF(dvd_reader_t *dvd, int title,=20
+ int menu, dvd_stat_t *statbuf)
+{
+ char filename[ MAX_UDF_FILE_NAME_LEN ];
+ uint32_t size;
+ off_t tot_size;
+ off_t parts_size[9];
+ int nr_parts =3D 0;
+ int n;
+=20
+ if( title =3D=3D 0 ) {
+ sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
+ } else {
+ sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 =
);
+ }
+ if(!UDFFindFile( dvd, filename, &size )) {
+ return -1;
+ }
+ tot_size =3D size;
+ nr_parts =3D 1;
+ parts_size[0] =3D size;
+
+ if( !menu ) {
+ int cur;
+
+ for( cur =3D 2; cur < 10; cur++ ) {
+ sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur );
+ if( !UDFFindFile( dvd, filename, &size ) ) {
+ break;
+ }
+ parts_size[nr_parts] =3D size;
+ tot_size +=3D size;
+ nr_parts++;
}
+ }
+ =20
+ statbuf->size =3D tot_size;
+ statbuf->nr_parts =3D nr_parts;
+ for(n =3D 0; n < nr_parts; n++) {
+ statbuf->parts_size[n] =3D parts_size[n];
+ }
+ return 0;
}
=20
-/* Internal, but used from dvd_udf.c */
+
+static int DVDFileStatVOBPath( dvd_reader_t *dvd, int title,
+ int menu, dvd_stat_t *statbuf )
+{
+ char filename[ MAX_UDF_FILE_NAME_LEN ];
+ char full_path[ PATH_MAX + 1 ];
+ struct stat fileinfo;
+ off_t tot_size;
+ off_t parts_size[9];
+ int nr_parts =3D 0;
+ int n;
+
+=20
+ =20
+ if( title =3D=3D 0 ) {
+ sprintf( filename, "VIDEO_TS.VOB" );
+ } else {
+ sprintf( filename, "VTS_%02d_%d.VOB", title, menu ? 0 : 1 );
+ }
+ if( !findDVDFile( dvd, filename, full_path ) ) {
+ return -1;
+ }
+ =20
+ if( stat( full_path, &fileinfo ) < 0 ) {
+ if(dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
+ }
+ return -1;
+ }
+ =20
+
+ tot_size =3D fileinfo.st_size;
+ nr_parts =3D 1;
+ parts_size[0] =3D fileinfo.st_size;
+
+ if( !menu ) {
+ int cur;
+ =20
+ for( cur =3D 2; cur < 10; cur++ ) {
+
+ sprintf( filename, "VTS_%02d_%d.VOB", title, cur );
+ if( !findDVDFile( dvd, filename, full_path ) ) {
+ break;
+ }
+
+ if( stat( full_path, &fileinfo ) < 0 ) {
+ if(dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
+ }
+ break;
+ }
+ =20
+ parts_size[nr_parts] =3D fileinfo.st_size;
+ tot_size +=3D parts_size[nr_parts];
+ nr_parts++;
+ }
+ }
+
+ statbuf->size =3D tot_size;
+ statbuf->nr_parts =3D nr_parts;
+ for(n =3D 0; n < nr_parts; n++) {
+ statbuf->parts_size[n] =3D parts_size[n];
+ }
+ return 0;
+}
+
+
+int DVDFileStat(dvd_reader_t *dvd, int titlenum,=20
+ dvd_read_domain_t domain, dvd_stat_t *statbuf)
+{
+ char filename[ MAX_UDF_FILE_NAME_LEN ];
+ char full_path[ PATH_MAX + 1 ];
+ struct stat fileinfo;
+ uint32_t size;
+
+ /* Check arguments. */
+ if( dvd =3D=3D NULL || titlenum < 0 ) {
+ errno =3D EINVAL;
+ return -1;
+ }
+
+ switch( domain ) {
+ case DVD_READ_INFO_FILE:
+ if( titlenum =3D=3D 0 ) {
+ sprintf( filename, "/VIDEO_TS/VIDEO_TS.IFO" );
+ } else {
+ sprintf( filename, "/VIDEO_TS/VTS_%02i_0.IFO", titlenum );
+ }
+ break;
+ case DVD_READ_INFO_BACKUP_FILE:
+ if( titlenum =3D=3D 0 ) {
+ sprintf( filename, "/VIDEO_TS/VIDEO_TS.BUP" );
+ } else {
+ sprintf( filename, "/VIDEO_TS/VTS_%02i_0.BUP", titlenum );
+ }
+ break;
+ case DVD_READ_MENU_VOBS:
+ if( dvd->isImageFile ) {
+ return DVDFileStatVOBUDF( dvd, titlenum, 1, statbuf );
+ } else {
+ return DVDFileStatVOBPath( dvd, titlenum, 1, statbuf );
+ }
+ break;
+ case DVD_READ_TITLE_VOBS:
+ if( titlenum =3D=3D 0 ) {
+ return -1;
+ }
+ if( dvd->isImageFile ) {
+ return DVDFileStatVOBUDF( dvd, titlenum, 0, statbuf );
+ } else {
+ return DVDFileStatVOBPath( dvd, titlenum, 0, statbuf );
+ }
+ break;
+ default:
+ if(dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Invalid domain for file stat.\n" );
+ }
+ errno =3D EINVAL;
+ return -1;
+ }
+ =20
+ if( dvd->isImageFile ) {
+ if( UDFFindFile( dvd, filename, &size ) ) {
+ statbuf->size =3D size;
+ statbuf->nr_parts =3D 1;
+ statbuf->parts_size[0] =3D size;
+ return 0;
+ }
+ } else {
+ if( findDVDFile( dvd, filename, full_path ) ) {
+ if( stat( full_path, &fileinfo ) < 0 ) {
+ if(dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
+ }
+ } else {
+ statbuf->size =3D fileinfo.st_size;
+ statbuf->nr_parts =3D 1;
+ statbuf->parts_size[0] =3D statbuf->size;
+ return 0;
+ }
+ }
+ }
+ return -1;
+}
+
+/**
+ * Internal, but used from dvd_udf.c=20
+ *
+ * @param device A read handle.
+ * @param lb_number Logical block number to start read from.
+ * @param block_count Number of logical blocks to read.
+ * @param data Pointer to buffer where read data should be stored.
+ * This buffer must be large enough to hold lb_number*2048 b=
ytes.
+ * The pointer must be aligned to the logical block size whe=
n
+ * reading from a raw/O_DIRECT device.
+ * @param encrypted 0 if no decryption shall be performed,
+ * 1 if decryption shall be performed
+ * @param return Returns number of blocks read on success, negative on e=
rror
+ */
int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number,
- size_t block_count, unsigned char *data,=20
- int encrypted )
+ size_t block_count, unsigned char *data,=20
+ int encrypted )
{
- int ret;
+ int ret;
=20
- if( !device->dev ) {
- LOG_ERROR( stderr, "libdvdread: Fatal error in block read.\n" );
- return 0;
- }
+ if( !device->dev ) {
+ if(device->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: Fatal error in block read.\n" );
+ }
+ return 0;
+ }
=20
- ret =3D dvdinput_seek( device->dev, (int) lb_number );
- if( ret !=3D (int) lb_number ) {
- LOG_ERROR( stderr, "libdvdread: Can't seek to block %u\n", lb_numb=
er );
- return 0;
- }
+ ret =3D dvdinput_seek( device->dev, (int) lb_number );
+ if( ret !=3D (int) lb_number ) {
+ if(device->verbose >=3D 1) {
+ fprintf( stderr,
+ "libdvdread: UDFReadBlocksRaw: Can't seek to block %u\n",
+ lb_number );
+ }
+ return 0;
+ }
=20
- return dvdinput_read( device->dev, (char *) data,=20
- (int) block_count, encrypted );
+ return dvdinput_read( device->dev, (char *) data,=20
+ (int) block_count, encrypted );
}
=20
-/* This is using a single input and starting from 'dvd_file->lb_start' o=
ffset.
+/**
+ * This is using a single input and starting from 'dvd_file->lb_start' o=
ffset.
*
* Reads 'block_count' blocks from 'dvd_file' at block offset 'offset'
* into the buffer located at 'data' and if 'encrypted' is set
* descramble the data if it's encrypted. Returning either an
- * negative error or the number of blocks read. */
+ * negative error or the number of blocks read.
+ *
+ * @param data Pointer to buffer where read data should be placed.
+ * This buffer must be large enough to hold block_count*2048=
bytes.
+ * The pointer must be aligned to 2048 bytes when reading fr=
om
+ * a raw/O_DIRECT device.
+ * @return Returns the number of blocks read on success or a negative er=
ror.
+ */
static int DVDReadBlocksUDF( dvd_file_t *dvd_file, uint32_t offset,
- size_t block_count, unsigned char *data,
- int encrypted )
+ size_t block_count, unsigned char *data,
+ int encrypted )
{
- return UDFReadBlocksRaw( dvd_file->dvd, dvd_file->lb_start + offset,
- block_count, data, encrypted );
+ return UDFReadBlocksRaw( dvd_file->dvd, dvd_file->lb_start + offset,
+ block_count, data, encrypted );
}
=20
-/* This is using possibly several inputs and starting from an offset of =
'0'.
- *
+/**
+ * This is using possibly several inputs and starting from an offset of =
'0'.
+ * data must be aligned to logical block size (2048 bytes) of the device
+ * for raw/O_DIRECT devices to work
* Reads 'block_count' blocks from 'dvd_file' at block offset 'offset'
* into the buffer located at 'data' and if 'encrypted' is set
* descramble the data if it's encrypted. Returning either an
- * negative error or the number of blocks read. */
+ * negative error or the number of blocks read.
+ *
+ * @param dvd_file A file read handle.
+ * @param offset Block offset from start of file.
+ * @return Returns number of blocks read on success, negative on error.
+ */
static int DVDReadBlocksPath( dvd_file_t *dvd_file, unsigned int offset,
- size_t block_count, unsigned char *data,
- int encrypted )
+ size_t block_count, unsigned char *data,
+ int encrypted )
{
- int i;
- int ret, ret2, off;
+ int i;
+ int ret, ret2, off;
=20
- ret =3D 0;
- ret2 =3D 0;
- for( i =3D 0; i < 9; ++i ) {
- if( !dvd_file->title_sizes[ i ] ) return 0; /* Past end of file */
+ ret =3D 0;
+ ret2 =3D 0;
+ for( i =3D 0; i < 9; ++i ) {
+ if( !dvd_file->title_sizes[ i ] ) return 0; /* Past end of file */
=20
- if( offset < dvd_file->title_sizes[ i ] ) {
- if( ( offset + block_count ) <=3D dvd_file->title_sizes[ i ]=
) {
- off =3D dvdinput_seek( dvd_file->title_devs[ i ], (int)offset );
- if( off < 0 || off !=3D (int)offset ) {
- LOG_ERROR( stderr, "libdvdread: Can't seek to block %d\n",=20
- offset );
- return off < 0 ? off : 0;
- }
- ret =3D dvdinput_read( dvd_file->title_devs[ i ], data,
- (int)block_count, encrypted );
- break;
- } else {
- size_t part1_size =3D dvd_file->title_sizes[ i ] - offse=
t;
- /* FIXME: Really needs to be a while loop.
- * (This is only true if you try and read >1GB at a time=
) */
- =09
- /* Read part 1 */
- off =3D dvdinput_seek( dvd_file->title_devs[ i ], (int)o=
ffset );
- if( off < 0 || off !=3D (int)offset ) {
- LOG_ERROR( stderr, "libdvdread: Can't seek to block %d\n",=20
- offset );
- return off < 0 ? off : 0;
- }
- ret =3D dvdinput_read( dvd_file->title_devs[ i ], data,
- (int)part1_size, encrypted );
- if( ret < 0 ) return ret;
- /* FIXME: This is wrong if i is the last file in the set.=20
- * also error from this read will not show in ret. */
- =09
- /* Does the next part exist? If not then return now. */
- if( !dvd_file->title_devs[ i + 1 ] ) return ret;
+ if( offset < dvd_file->title_sizes[ i ] ) {
+ if( ( offset + block_count ) <=3D dvd_file->title_sizes[ i ] ) {
+ off =3D dvdinput_seek( dvd_file->title_devs[ i ], (int)offset );
+ if( off < 0 || off !=3D (int)offset ) {
+ if(dvd_file->dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: DVDReadBlocksPath1: Can't seek=
to block %d\n",=20
+ offset );
+ }
+ return off < 0 ? off : 0;
+ }
+ ret =3D dvdinput_read( dvd_file->title_devs[ i ], data,
+ (int)block_count, encrypted );
+ break;
+ } else {
+ size_t part1_size =3D dvd_file->title_sizes[ i ] - offset;
+ /* FIXME: Really needs to be a while loop.
+ * (This is only true if you try and read >1GB at a time) */
+ =20
+ /* Read part 1 */
+ off =3D dvdinput_seek( dvd_file->title_devs[ i ], (int)offset );
+ if( off < 0 || off !=3D (int)offset ) {
+ if(dvd_file->dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: DVDReadBlocksPath2: Can't seek=
to block %d\n",=20
+ offset );
+ }
+ return off < 0 ? off : 0;
+ }
+ ret =3D dvdinput_read( dvd_file->title_devs[ i ], data,
+ (int)part1_size, encrypted );
+ if( ret < 0 ) return ret;
+ /* FIXME: This is wrong if i is the last file in the set.=20
+ * also error from this read will not show in ret. */
+ =20
+ /* Does the next part exist? If not then return now. */
+ if( !dvd_file->title_devs[ i + 1 ] ) return ret;
=20
- /* Read part 2 */
- off =3D dvdinput_seek( dvd_file->title_devs[ i + 1 ], 0 =
);
- if( off < 0 || off !=3D 0 ) {
- LOG_ERROR( stderr, "libdvdread: Can't seek to block %d\n",=20
- 0 );
- return off < 0 ? off : 0;
- }
- ret2 =3D dvdinput_read( dvd_file->title_devs[ i + 1 ],=20
- data + ( part1_size
- * (int64_t)DVD_VIDEO_LB_LEN ),
- (int)(block_count - part1_size),
- encrypted );
- if( ret2 < 0 ) return ret2;
- break;
- }
- } else {
- offset -=3D dvd_file->title_sizes[ i ];
+ /* Read part 2 */
+ off =3D dvdinput_seek( dvd_file->title_devs[ i + 1 ], 0 );
+ if( off < 0 || off !=3D 0 ) {
+ if(dvd_file->dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: DVDReadBlocksPath3: Can't seek=
to block %d\n", 0 );
+ }
+ return off < 0 ? off : 0;
}
+ ret2 =3D dvdinput_read( dvd_file->title_devs[ i + 1 ],=20
+ data + ( part1_size
+ * (int64_t)DVD_VIDEO_LB_LEN ),
+ (int)(block_count - part1_size),
+ encrypted );
+ if( ret2 < 0 ) return ret2;
+ break;
+ }
+ } else {
+ offset -=3D (unsigned int)dvd_file->title_sizes[ i ];
}
+ }
=20
- return ret + ret2;
+ return ret + ret2;
}
=20
-/* This is broken reading more than 2Gb at a time is ssize_t is 32-bit. =
*/
+/**
+ * This is broken reading more than 2Gb at a time if ssize_t is 32-bit.
+ */
ssize_t DVDReadBlocks( dvd_file_t *dvd_file, int offset,=20
- size_t block_count, unsigned char *data )
+ size_t block_count, unsigned char *data )
{
- int ret;
+ int ret;
=20
- /* Check arguments. */
- if( dvd_file =3D=3D NULL || offset < 0 || data =3D=3D NULL )
- return -1;
+ /* Check arguments. */
+ if( dvd_file =3D=3D NULL || offset < 0 || data =3D=3D NULL )
+ return -1;
=20
- /* Hack, and it will still fail for multiple opens in a threaded app=
! */
- if( dvd_file->dvd->css_title !=3D dvd_file->css_title ) {
- dvd_file->dvd->css_title =3D dvd_file->css_title;
- if( dvd_file->dvd->isImageFile ) {
- dvdinput_title( dvd_file->dvd->dev, (int)dvd_file->lb_start );
- }=20
- /* Here each vobu has it's own dvdcss handle, so no need to update=
=20
- else {
- dvdinput_title( dvd_file->title_devs[ 0 ], (int)dvd_file->lb_start );
- }*/
- }
- =20
+ /* Hack, and it will still fail for multiple opens in a threaded app !=
*/
+ if( dvd_file->dvd->css_title !=3D dvd_file->css_title ) {
+ dvd_file->dvd->css_title =3D dvd_file->css_title;
if( dvd_file->dvd->isImageFile ) {
- ret =3D DVDReadBlocksUDF( dvd_file, (uint32_t)offset,=20
- block_count, data, DVDINPUT_READ_DECRYPT );
- } else {
- ret =3D DVDReadBlocksPath( dvd_file, (unsigned int)offset,=20
- block_count, data, DVDINPUT_READ_DECRYPT );
- }
+ dvdinput_title( dvd_file->dvd->dev, (int)dvd_file->lb_start );
+ }=20
+ /* Here each vobu has it's own dvdcss handle, so no need to update=20
+ else {
+ dvdinput_title( dvd_file->title_devs[ 0 ], (int)dvd_file->lb_star=
t );
+ }*/
+ }
=20
- return (ssize_t)ret;
+ if( dvd_file->dvd->isImageFile ) {
+ ret =3D DVDReadBlocksUDF( dvd_file, (uint32_t)offset,=20
+ block_count, data, DVDINPUT_READ_DECRYPT );
+ } else {
+ ret =3D DVDReadBlocksPath( dvd_file, (unsigned int)offset,=20
+ block_count, data, DVDINPUT_READ_DECRYPT );
+ }
+ =20
+ return (ssize_t)ret;
}
=20
-int32_t DVDFileSeek( dvd_file_t *dvd_file, int32_t offset )
+int DVDFileSeek( dvd_file_t *dvd_file, int offset )
{
- /* Check arguments. */
- if( dvd_file =3D=3D NULL || offset < 0 )
- return -1;
+ /* Check arguments. */
+ if( dvd_file =3D=3D NULL || offset < 0 )
+ return -1;
=20
- if( offset > dvd_file->filesize * DVD_VIDEO_LB_LEN ) {
- return -1;
- }
- dvd_file->seek_pos =3D (uint32_t) offset;
- return offset;
+ if( offset > dvd_file->filesize * DVD_VIDEO_LB_LEN ) {
+ return -1;
+ }
+ dvd_file->seek_pos =3D (uint32_t) offset;
+ return offset;
}
=20
+#ifndef HAVE_UINTPTR_T
+#warning "Assuming that (unsigned long) can hold (void *)"
+typedef unsigned long uintptr_t;
+#endif
+
+#define DVD_ALIGN(ptr) (void *)((((uintptr_t)(ptr)) + (DVD_VIDEO_LB_LEN-=
1)) \
+ / DVD_VIDEO_LB_LEN * DVD_VIDEO_LB_LEN)
+
ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size=
)
{
- unsigned char *secbuf;
- unsigned int numsec, seek_sector, seek_byte;
- int ret;
+ unsigned char *secbuf_start;
+ unsigned char *secbuf; //must be aligned to 2048-bytes for raw/O_DIREC=
T
+ unsigned int numsec, seek_sector, seek_byte;
+ int ret;
=20
- /* Check arguments. */
- if( dvd_file =3D=3D NULL || data =3D=3D NULL )
- return -1;
+ /* Check arguments. */
+ if( dvd_file =3D=3D NULL || data =3D=3D NULL ) {
+ errno =3D EINVAL;
+ return -1;
+ }
+ seek_sector =3D dvd_file->seek_pos / DVD_VIDEO_LB_LEN;
+ seek_byte =3D dvd_file->seek_pos % DVD_VIDEO_LB_LEN;
=20
- seek_sector =3D dvd_file->seek_pos / DVD_VIDEO_LB_LEN;
- seek_byte =3D dvd_file->seek_pos % DVD_VIDEO_LB_LEN;
+ numsec =3D ( ( seek_byte + byte_size ) / DVD_VIDEO_LB_LEN ) +
+ ( ( ( seek_byte + byte_size ) % DVD_VIDEO_LB_LEN ) ? 1 : 0 );
=20
- numsec =3D ( ( seek_byte + byte_size ) / DVD_VIDEO_LB_LEN ) +
- ( ( ( seek_byte + byte_size ) % DVD_VIDEO_LB_LEN ) ? 1 : 0 );
- =20
- secbuf =3D (unsigned char *) malloc( numsec * DVD_VIDEO_LB_LEN );
- if( !secbuf ) {
- LOG_ERROR( stderr, "libdvdread: Can't allocate memory "=20
- "for file read!\n" );
- return 0;
- }
- =20
- if( dvd_file->dvd->isImageFile ) {
- ret =3D DVDReadBlocksUDF( dvd_file, (uint32_t) seek_sector,=20
- (size_t) numsec, secbuf, DVDINPUT_NOFLAGS );
- } else {
- ret =3D DVDReadBlocksPath( dvd_file, seek_sector,=20
- (size_t) numsec, secbuf, DVDINPUT_NOFLAGS );
- }
+ /* must align to 2048 bytes if we are reading from raw/O_DIRECT */
+ secbuf_start =3D (unsigned char *) malloc( (numsec+1) * DVD_VIDEO_LB_L=
EN );
+ if( !secbuf_start ) {
+ /* errno will be set to ENOMEM by malloc */
+ return -1;
+ }
=20
- if( ret !=3D (int) numsec ) {
- free( secbuf );
- return ret < 0 ? ret : 0;
- }
+ secbuf =3D DVD_ALIGN(secbuf_start);
=20
- memcpy( data, &(secbuf[ seek_byte ]), byte_size );
- free( secbuf );
+ if( dvd_file->dvd->isImageFile ) {
+ ret =3D DVDReadBlocksUDF( dvd_file, (uint32_t) seek_sector,=20
+ (size_t) numsec, secbuf, DVDINPUT_NOFLAGS );
+ } else {
+ ret =3D DVDReadBlocksPath( dvd_file, seek_sector,=20
+ (size_t) numsec, secbuf, DVDINPUT_NOFLAGS )=
;
+ }
=20
- dvd_file->seek_pos +=3D byte_size;
- return byte_size;
+ if( ret !=3D (int) numsec ) {
+ free( secbuf_start );
+ return ret < 0 ? ret : 0;
+ }
+
+ memcpy( data, &(secbuf[ seek_byte ]), byte_size );
+ free( secbuf_start );
+
+ dvd_file->seek_pos +=3D (unsigned int)byte_size;
+ return byte_size;
}
=20
ssize_t DVDFileSize( dvd_file_t *dvd_file )
{
- /* Check arguments. */
- if( dvd_file =3D=3D NULL )
- return -1;
+ /* Check arguments. */
+ if( dvd_file =3D=3D NULL )
+ return -1;
=20
- return dvd_file->filesize;
+ return dvd_file->filesize;
}
=20
int DVDDiscID( dvd_reader_t *dvd, unsigned char *discid )
{
- struct md5_ctx ctx;
- int title;
+ struct md5_ctx ctx;
+ int title;
+ int nr_of_files =3D 0;
+ int tmp_errno;
+ int nofiles_errno =3D ENOENT;
+ /* Check arguments. */
+ if( dvd =3D=3D NULL || discid =3D=3D NULL ) {
+ errno =3D EINVAL;
+ return -1;
+ }
+ /* Go through the first 10 IFO:s, in order,=20
+ * and md5sum them, i.e VIDEO_TS.IFO and VTS_0?_0.IFO */
+ md5_init_ctx( &ctx );
+ for( title =3D 0; title < 10; title++ ) {
+ dvd_file_t *dvd_file =3D DVDOpenFile( dvd, title, DVD_READ_INFO_FILE=
);
+ if( dvd_file !=3D NULL ) {
+ ssize_t bytes_read;
+ size_t file_size =3D dvd_file->filesize * DVD_VIDEO_LB_LEN;
+ char *buffer =3D malloc( file_size );
=20
- /* Check arguments. */
- if( dvd =3D=3D NULL || discid =3D=3D NULL )
- return 0;
- =20
- /* Go through the first 10 IFO:s, in order,=20
- * and md5sum them, i.e VIDEO_TS.IFO and VTS_0?_0.IFO */
- md5_init_ctx( &ctx );
- for( title =3D 0; title < 10; title++ ) {
- dvd_file_t *dvd_file =3D DVDOpenFile( dvd, title, DVD_READ_INFO_FILE );
- if( dvd_file !=3D NULL ) {
- ssize_t bytes_read;
- size_t file_size =3D dvd_file->filesize * DVD_VIDEO_LB_LEN;
- char *buffer =3D malloc( file_size );
- =20
- if( buffer =3D=3D NULL ) {
- LOG_ERROR( stderr, "libdvdread: DVDDiscId, failed to "
- "allocate memory for file read!\n" );
- return -1;
- }
- bytes_read =3D DVDReadBytes( dvd_file, buffer, file_size );
- if( bytes_read !=3D file_size ) {
- LOG_ERROR( stderr, "libdvdread: DVDDiscId read returned %d bytes"
- ", wanted %d\n", bytes_read, file_size );
- DVDCloseFile( dvd_file );
- return -1;
- }
- =20
- md5_process_bytes( buffer, file_size, &ctx );
- =20
- DVDCloseFile( dvd_file );
- free( buffer );
- }
+ nr_of_files++;
+
+ if( buffer =3D=3D NULL ) {
+ /* errno will be set to ENOMEM by malloc */
+ return -1;
+ }
+
+ bytes_read =3D DVDReadBytes( dvd_file, buffer, file_size );
+ if( bytes_read !=3D file_size ) {
+ tmp_errno =3D errno;
+ if(dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: DVDDiscId read returned %d bytes=
"
+ ", wanted %d\n", (int)bytes_read, (int)file_size );
+ }
+ free(buffer);
+ DVDCloseFile( dvd_file );
+ errno =3D tmp_errno;
+ return -1;
+ }
+ =20
+ md5_process_bytes( buffer, file_size, &ctx );
+ =20
+ DVDCloseFile( dvd_file );
+ free( buffer );
+ } else {
+ if(errno !=3D ENOENT) {
+ nofiles_errno =3D errno;
+ }
}
- md5_finish_ctx( &ctx, discid );
- =20
- return 0;
+ }
+ md5_finish_ctx( &ctx, discid );
+ if(nr_of_files =3D=3D 0) {
+ errno =3D nofiles_errno;
+ return -1;
+ }
+ return 0;
}
=20
=20
int DVDISOVolumeInfo( dvd_reader_t *dvd,
- char *volid, unsigned int volid_size,
- unsigned char *volsetid, unsigned int volsetid_size )
+ char *volid, unsigned int volid_size,
+ unsigned char *volsetid, unsigned int volsetid_siz=
e )
{
- unsigned char *buffer;
+ unsigned char *buffer; /* must be aligned to 2048 for raw/O_DIRECT */
+ unsigned char *buffer_start;=20
int ret;
=20
/* Check arguments. */
- if( dvd =3D=3D NULL )
- return 0;
+ if( dvd =3D=3D NULL ) {
+ errno =3D EINVAL;
+ return -1;
+ }
=20
if( dvd->dev =3D=3D NULL ) {
/* No block access, so no ISO... */
+ errno =3D EINVAL;
return -1;
}
=20
- buffer =3D malloc( DVD_VIDEO_LB_LEN );
- if( buffer =3D=3D NULL ) {
- LOG_ERROR( stderr, "libdvdread: DVDISOVolumeInfo, failed to "
- "allocate memory for file read!\n" );
+ buffer_start =3D malloc( 2 * DVD_VIDEO_LB_LEN );
+ if( buffer_start =3D=3D NULL ) {
return -1;
}
=20
+ buffer =3D DVD_ALIGN(buffer_start);
+ =20
ret =3D UDFReadBlocksRaw( dvd, 16, 1, buffer, 0 );
if( ret !=3D 1 ) {
- LOG_ERROR( stderr, "libdvdread: DVDISOVolumeInfo, failed to "
- "read ISO9660 Primary Volume Descriptor!\n" );
+ if(dvd->verbose >=3D 1) {
+ fprintf( stderr, "libdvdread: DVDISOVolumeInfo, failed to "
+ "read ISO9660 Primary Volume Descriptor!\n" );
+ }
+ free(buffer_start);
return -1;
}
=20
@@ -1104,7 +1577,7 @@
unsigned int n;
for(n =3D 0; n < 32; n++) {
if(buffer[40+n] =3D=3D 0x20) {
- break;
+ break;
}
}
=20
@@ -1122,13 +1595,15 @@
}
memcpy(volsetid, &buffer[190], volsetid_size);
}
+ free(buffer_start);
+
return 0;
}
=20
=20
int DVDUDFVolumeInfo( dvd_reader_t *dvd,
- char *volid, unsigned int volid_size,
- unsigned char *volsetid, unsigned int volsetid_size )
+ char *volid, unsigned int volid_size,
+ unsigned char *volsetid, unsigned int volsetid_siz=
e )
{
int ret;
/* Check arguments. */
Modified: trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_reader.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_reader.h 2007-01-22 11:2=
1:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_reader.h 2007-01-28 16:4=
8:11 UTC (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
#ifndef DVD_READER_H_INCLUDED
#define DVD_READER_H_INCLUDED
=20
@@ -20,9 +21,12 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 =
USA
*/
-
-#include <inttypes.h>
+
+#include <inttypes.h> // include local inttypes for WIN32
#include <sys/types.h>
+#ifdef _WIN32
+typedef SSIZE_T ssize_t;
+#endif
=20
/**
* The DVD access interface.
@@ -32,10 +36,11 @@
*/
=20
/**
- * The current version.
+ * The current version. (0.9.4 =3D> 904, 1.2.3 =3D> 10203)
*/
-#define DVDREAD_VERSION 904
+#define DVDREAD_VERSION 907
=20
+
/**
* The length of one Logical Block of a DVD.
*/
@@ -61,6 +66,12 @@
typedef struct dvd_file_s dvd_file_t;
=20
/**
+ * Returns the compiled version. (DVDREAD_VERSION as an int)
+ */
+int DVDVersion(void);
+
+
+/**
* Opens a block device of a DVD-ROM file, or an image file, or a direct=
ory
* name for a mounted DVD or HD copy of a DVD.
*
@@ -81,6 +92,10 @@
* @return If successful a a read handle is returned. Otherwise 0 is ret=
urned.
*
* dvd =3D DVDOpen(path);
+ *
+ * Threads: this function uses chdir() and getcwd().
+ * The current working directory is global to all threads,
+ * so using chdir/getcwd in another thread could give unexpected results=
.
*/
dvd_reader_t *DVDOpen( const char * );
=20
@@ -96,18 +111,83 @@
void DVDClose( dvd_reader_t * );
=20
/**
+ * Initializes libdvdread to be used with multithreading apps.
+ *
+ * You must call this function before using any other functions of libdv=
dread
+ * if you are going to use libdvdread in multiple threads in your progra=
m.
+ * If you are not using threads, or using libdvdread from just one threa=
d,
+ * you do not need to call this, but you are allowed to do so anyway.
*=20
+ * There are several restrictions on how you can use libdvdread in
+ * multithreading apps, see further documentation.
+ *
+ * If you have called DVDFinish() you need to call DVDInit again to use
+ * libdvdread in multiple threads.
+ *
+ * DVDInit(void);
*/
+void DVDInit(void);
+
+/**
+ * frees any dlopened objects.
+ *
+ * You must DVDClose all handles opened with DVDOpen before calling this=
.
+ * Use this function if you need to close the dlopened libs and any othe=
r
+ * objects that have been dynamically allocated by libdvdread.
+ *=20
+ * DVDFinish(void);
+ */
+void DVDFinish(void);
+
+/**
+ *=20
+ */
typedef enum {
DVD_READ_INFO_FILE, /**< VIDEO_TS.IFO or VTS_XX_0.IFO (title) =
*/
DVD_READ_INFO_BACKUP_FILE, /**< VIDEO_TS.BUP or VTS_XX_0.BUP (title) =
*/
DVD_READ_MENU_VOBS, /**< VIDEO_TS.VOB or VTS_XX_0.VOB (title) =
*/
DVD_READ_TITLE_VOBS /**< VTS_XX_[1-9].VOB (title). All files i=
n=20
- the title set are opened and read as a
- single file. */
+ the title set are opened and read as a
+ single file. */
} dvd_read_domain_t;
=20
/**
+ *
+ */
+typedef struct {
+ off_t size; /**< Total size of file in bytes */
+ int nr_parts; /**< Number of file parts */
+ off_t parts_size[9]; /**< Size of each part in bytes */
+} dvd_stat_t;
+
+/**
+ * Stats a file on the DVD given the title number and domain.
+ * The information about the file is stored in a dvd_stat_t
+ * which contains information about the size of the file and
+ * the number of parts in case of a multipart file and the respective
+ * sizes of the parts.
+ * A multipart file is for instance VTS_02_1.VOB, VTS_02_2.VOB, VTS_02_3=
.VOB
+ * The size of VTS_02_1.VOB will be stored in stat->parts_size[0],
+ * VTS_02_2.VOB in stat->parts_size[1], ...
+ * The total size (sum of all parts) is stored in stat->size and
+ * stat->nr_parts will hold the number of parts.
+ * Only DVD_READ_TITLE_VOBS (VTS_??_[1-9].VOB) can be multipart files.
+ *=20
+ * This function is only of use if you want to get the size of each file
+ * in the filesystem. These sizes are not needed to use any other
+ * functions in libdvdread.=20
+ *
+ * @param dvd A dvd read handle.
+ * @param titlenum Which Video Title Set should be used, VIDEO_TS is 0.
+ * @param domain Which domain.=20
+ * @param stat Pointer to where the result is stored.
+ * @return If successful 0, otherwise -1.
+ *
+ * int DVDFileStat(dvd, titlenum, domain, stat);
+ */
+int DVDFileStat(dvd_reader_t *, int, dvd_read_domain_t, dvd_stat_t *);
+ =20
+/**
* Opens a file on the DVD given the title number and domain.
*
* If the title number is 0, the video manager information is opened
@@ -142,6 +222,8 @@
* @param offset Block offset from the start of the file to start readin=
g at.
* @param block_count Number of block to read.
* @param data Pointer to a buffer to write the data into.
+ * It must be aligned to the logical block size of the devic=
e when
+ * reading from a raw/O_DIRECT device (2048 bytes for DVD)
* @return Returns number of blocks read on success, -1 on error.
*
* blocks_read =3D DVDReadBlocks(dvd_file, offset, block_count, data);
@@ -175,7 +257,7 @@
* bytes_read =3D DVDReadBytes(dvd_file, data, bytes);
*/
ssize_t DVDReadBytes( dvd_file_t *, void *, size_t );
-
+ =20
/**
* Returns the file size in blocks.
*
@@ -185,7 +267,7 @@
* blocks =3D DVDFileSize(dvd_file);
*/
ssize_t DVDFileSize( dvd_file_t * );
-
+ =20
/**
* Get a unique 128 bit disc ID.
* This is the MD5 sum of VIDEO_TS.IFO and the VTS_0?_0.IFO files
@@ -220,7 +302,7 @@
* @return 0 on success, -1 on error.
*/
int DVDUDFVolumeInfo( dvd_reader_t *, char *, unsigned int,
- unsigned char *, unsigned int );
+ unsigned char *, unsigned int );
=20
/**
* Get the ISO9660 VolumeIdentifier and VolumeSetIdentifier
@@ -244,7 +326,7 @@
* @return 0 on success, -1 on error.
*/
int DVDISOVolumeInfo( dvd_reader_t *, char *, unsigned int,
- unsigned char *, unsigned int );
+ unsigned char *, unsigned int );
=20
/**
* Sets the level of caching that is done when reading from a device
@@ -259,7 +341,7 @@
* @return The level of caching.
*/
int DVDUDFCacheLevel( dvd_reader_t *, int );
-
+ =20
#ifdef __cplusplus
};
#endif
Modified: trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_udf.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_udf.c 2007-01-22 11:21:1=
6 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_udf.c 2007-01-28 16:48:1=
1 UTC (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* This code is based on dvdudf by:
* Christian Wolff <scarabaeus at convergence.de>.
@@ -33,28 +34,181 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
+
+#if defined(WIN32)
+#include "posix.h"
#endif
#include <sys/types.h>
#include <sys/stat.h>
-#ifdef HAVE_UNISTD_H
+#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
+#include <errno.h>
+
+#if defined(HAVE_INTTYPES_H)
#include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
=20
#include "dvd_reader.h"
#include "dvd_udf.h"
+#include "dvdread_internal.h"
=20
+#ifndef EMEDIUMTYPE
+#define EMEDIUMTYPE ENOENT
+#endif
+
+#ifndef HAVE_UINTPTR_T
+#warning "Assuming that (unsigned long) can hold (void *)"
+typedef unsigned long uintptr_t;
+#endif
+
+#define DVD_ALIGN(ptr) (void *)((((uintptr_t)(ptr)) + (DVD_VIDEO_LB_LEN-=
1)) \
+ / DVD_VIDEO_LB_LEN * DVD_VIDEO_LB_LEN)
+
+typedef struct {
+ void *start;
+ void *aligned;
+} dvdalign_ptrs_t;
+
+typedef struct {
+ dvdalign_ptrs_t *ptrs;
+ uint32_t ptrs_in_use;
+ uint32_t ptrs_max;
+} dvdalign_t;
+
+extern void *GetAlignHandle(dvd_reader_t *device);
+extern void SetAlignHandle(dvd_reader_t *device, void *align);
+
+/**
+ * Allocates aligned memory (for use with reads from raw/O_DIRECT device=
s).
+ * This memory must be freed with dvdalign_free()
+ * The size of the memory that is allocate is num_lbs*2048 bytes.
+ * The memory will be suitably aligned for use with
+ * block reads from raw/O_DIRECT device.
+ * @param num_lbs Number of logical blocks (2048 bytes) to allocate.
+ * @return Returns pointer to allocated memory, or NULL on failure
+ * This isn't supposed to be fast/efficient, if that is needed
+ * this function should be rewritten to use posix_memalign or similar.
+ * It's just needed for aligning memory for small block reads from
+ * raw/O_DIRECT devices.=20
+ * We assume that 2048 is enough alignment for all systems at the moment=
.
+ * Not thread safe. Only use this from one thread.
+ * Depends on sizeof(unsigned long) being at least as large as sizeof(vo=
id *)
+ */
+static void *dvdalign_lbmalloc(dvd_reader_t *device, uint32_t num_lbs)
+{
+ void *m;
+ uint32_t n;
+ dvdalign_t *a;
+ =20
+ m =3D malloc((num_lbs+1)*DVD_VIDEO_LB_LEN);
+ if(m =3D=3D NULL) {
+ return m;
+ }
+ a =3D (dvdalign_t *)GetAlignHandle(device);
+ if(a =3D=3D NULL) {
+ a =3D malloc(sizeof(dvdalign_t));
+ if(a =3D=3D NULL) {
+ return a;
+ }
+ a->ptrs =3D NULL;
+ a->ptrs_in_use =3D 0;
+ a->ptrs_max =3D 0;
+ SetAlignHandle(device, (void *)a);
+ }
+ =20
+ if(a->ptrs_in_use >=3D a->ptrs_max) {
+ a->ptrs =3D realloc(a->ptrs, (a->ptrs_max+10)*sizeof(dvdalign_ptrs_t=
));
+ if(a->ptrs =3D=3D NULL) {
+ free(m);
+ return NULL;
+ }
+ a->ptrs_max+=3D10;
+ for(n =3D a->ptrs_in_use; n < a->ptrs_max; n++) {
+ a->ptrs[n].start =3D NULL;
+ a->ptrs[n].aligned =3D NULL;
+ }
+ n =3D a->ptrs_in_use;
+ } else {
+ for(n =3D 0; n < a->ptrs_max; n++) {
+ if(a->ptrs[n].start =3D=3D NULL) {
+ break;
+ }
+ }
+ }
+
+ a->ptrs[n].start =3D m;
+ a->ptrs[n].aligned =3D DVD_ALIGN(m);
+
+ a->ptrs_in_use++;
+
+ /* If this function starts to be used too much print a warning.
+ Either there is a memory leak somewhere or we need to rewrite this =
to
+ a more efficient version.
+ */
+ if(a->ptrs_in_use > 50) {
+ if(dvdread_verbose(device) >=3D 0) {
+ fprintf(stderr, "libdvdread: dvdalign_lbmalloc(), more allocs than=
supposed: %u\n", a->ptrs_in_use);
+ }
+ }
+
+ return a->ptrs[n].aligned;
+}
+
+/**
+ * Frees memory allocated with dvdalign_lbmemory()=20
+ * @param ptr Pointer to memory space to free
+ * Not thread safe.
+ */
+static void dvdalign_lbfree(dvd_reader_t *device, void *ptr)
+{
+ uint32_t n;
+ dvdalign_t *a;
+
+ a =3D (dvdalign_t *)GetAlignHandle(device);
+ if(a && a->ptrs) {
+ for(n =3D 0; n < a->ptrs_max; n++) {
+ if(a->ptrs[n].aligned =3D=3D ptr) {
+ free(a->ptrs[n].start);
+ a->ptrs[n].start =3D NULL;
+ a->ptrs[n].aligned =3D NULL;
+ a->ptrs_in_use--;
+ if(a->ptrs_in_use =3D=3D 0) {
+ free(a->ptrs);
+ a->ptrs =3D NULL;
+ a->ptrs_max =3D 0;
+ free(a);
+ a =3D NULL;
+ SetAlignHandle(device, (void *)a);
+ }
+ return;
+ }
+ }
+ }
+ if(dvdread_verbose(device) >=3D 0) {
+ fprintf(stderr, "libdvdread: dvdalign_lbfree(), error trying to free=
mem: %08lx (%u)\n", (unsigned long)ptr, a ? a->ptrs_in_use : 0);
+ }
+}
+
+
/* Private but located in/shared with dvd_reader.c */
extern int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number,
- size_t block_count, unsigned char *data,=20
- int encrypted );
+ size_t block_count, unsigned char *data,=20
+ int encrypted );
=20
-/* It's required to either fail or deliver all the blocks asked for. */
+/** @internal
+ * Its required to either fail or deliver all the blocks asked for.=20
+ *
+ * @param data Pointer to a buffer where data is returned. This must be =
large
+ * enough to hold lb_number*2048 bytes.
+ * It must be aligned to system specific (2048) logical blocks size wh=
en
+ * reading from raw/O_DIRECT device.
+ */
static int DVDReadLBUDF( dvd_reader_t *device, uint32_t lb_number,
- size_t block_count, unsigned char *data,=20
- int encrypted )
+ size_t block_count, unsigned char *data,=20
+ int encrypted )
{
int ret;
size_t count =3D block_count;
@@ -82,21 +236,21 @@
#endif
=20
struct Partition {
- int valid;
- char VolumeDesc[128];
- uint16_t Flags;
- uint16_t Number;
- char Contents[32];
- uint32_t AccessType;
- uint32_t Start;
- uint32_t Length;
+ int valid;
+ char VolumeDesc[128];
+ uint16_t Flags;
+ uint16_t Number;
+ char Contents[32];
+ uint32_t AccessType;
+ uint32_t Start;
+ uint32_t Length;
};
=20
struct AD {
- uint32_t Location;
- uint32_t Length;
- uint8_t Flags;
- uint16_t Partition;
+ uint32_t Location;
+ uint32_t Length;
+ uint8_t Flags;
+ uint16_t Partition;
};
=20
struct extent_ad {
@@ -147,12 +301,24 @@
extern void *GetUDFCacheHandle(dvd_reader_t *device);
extern void SetUDFCacheHandle(dvd_reader_t *device, void *cache);
=20
-void FreeUDFCache(void *cache)
+
+void FreeUDFCache(dvd_reader_t *device, void *cache)
{
+ int n;
+ =20
struct udf_cache *c =3D (struct udf_cache *)cache;
if(c =3D=3D NULL) {
return;
}
+
+ for(n =3D 0; n < c->lb_num; n++) {
+ if(c->lbs[n].data) {
+ /* free data */
+ dvdalign_lbfree(device, c->lbs[n].data);
+ }
+ }
+ c->lb_num =3D 0;
+
if(c->lbs) {
free(c->lbs);
}
@@ -164,7 +330,7 @@
=20
=20
static int GetUDFCache(dvd_reader_t *device, UDFCacheType type,
- uint32_t nr, void *data)
+ uint32_t nr, void *data)
{
int n;
struct udf_cache *c;
@@ -207,16 +373,16 @@
case LBUDFCache:
for(n =3D 0; n < c->lb_num; n++) {
if(c->lbs[n].lb =3D=3D nr) {
- *(uint8_t **)data =3D c->lbs[n].data;
- return 1;
+ *(uint8_t **)data =3D c->lbs[n].data;
+ return 1;
}
}
break;
case MapCache:
for(n =3D 0; n < c->map_num; n++) {
if(c->maps[n].lbn =3D=3D nr) {
- *(struct icbmap *)data =3D c->maps[n];
- return 1;
+ *(struct icbmap *)data =3D c->maps[n];
+ return 1;
}
}
break;
@@ -228,7 +394,7 @@
}
=20
static int SetUDFCache(dvd_reader_t *device, UDFCacheType type,
- uint32_t nr, void *data)
+ uint32_t nr, void *data)
{
int n;
struct udf_cache *c;
@@ -241,7 +407,7 @@
=20
if(c =3D=3D NULL) {
c =3D calloc(1, sizeof(struct udf_cache)); =20
- // LOG_ERROR( stderr, "calloc: %d\n", sizeof(struct udf_cache)); =
=20
+ // fprintf(stderr, "calloc: %d\n", sizeof(struct udf_cache)); =20
if(c =3D=3D NULL) {
return 0;
}
@@ -269,18 +435,18 @@
case LBUDFCache:
for(n =3D 0; n < c->lb_num; n++) {
if(c->lbs[n].lb =3D=3D nr) {
- /* replace with new data */
- c->lbs[n].data =3D *(uint8_t **)data;
- c->lbs[n].lb =3D nr;
- return 1;
+ /* replace with new data */
+ c->lbs[n].data =3D *(uint8_t **)data;
+ c->lbs[n].lb =3D nr;
+ return 1;
}
}
c->lb_num++;
c->lbs =3D realloc(c->lbs, c->lb_num * sizeof(struct lbudf));
/*
- LOG_ERROR( stderr, "realloc lb: %d * %d =3D %d\n",
- c->lb_num, sizeof(struct lbudf),
- c->lb_num * sizeof(struct lbudf));
+ fprintf(stderr, "realloc lb: %d * %d =3D %d\n",
+ c->lb_num, sizeof(struct lbudf),
+ c->lb_num * sizeof(struct lbudf));
*/
if(c->lbs =3D=3D NULL) {
c->lb_num =3D 0;
@@ -292,18 +458,18 @@
case MapCache:
for(n =3D 0; n < c->map_num; n++) {
if(c->maps[n].lbn =3D=3D nr) {
- /* replace with new data */
- c->maps[n] =3D *(struct icbmap *)data;
- c->maps[n].lbn =3D nr;
- return 1;
+ /* replace with new data */
+ c->maps[n] =3D *(struct icbmap *)data;
+ c->maps[n].lbn =3D nr;
+ return 1;
}
}
c->map_num++;
c->maps =3D realloc(c->maps, c->map_num * sizeof(struct icbmap));
/*
- LOG_ERROR( stderr, "realloc maps: %d * %d =3D %d\n",
- c->map_num, sizeof(struct icbmap),
- c->map_num * sizeof(struct icbmap));
+ fprintf(stderr, "realloc maps: %d * %d =3D %d\n",
+ c->map_num, sizeof(struct icbmap),
+ c->map_num * sizeof(struct icbmap));
*/
if(c->maps =3D=3D NULL) {
c->map_num =3D 0;
@@ -323,94 +489,94 @@
/* For direct data access, LSB first */
#define GETN1(p) ((uint8_t)data[p])
#define GETN2(p) ((uint16_t)data[p] | ((uint16_t)data[(p) + 1] << 8))
-#define GETN3(p) ((uint32_t)data[p] | ((uint32_t)data[(p) + 1] << 8) \
- | ((uint32_t)data[(p) + 2] << 16))
-#define GETN4(p) ((uint32_t)data[p] \
- | ((uint32_t)data[(p) + 1] << 8) \
- | ((uint32_t)data[(p) + 2] << 16) \
- | ((uint32_t)data[(p) + 3] << 24))
+#define GETN3(p) ((uint32_t)data[p] | ((uint32_t)data[(p) + 1] << 8) =
\
+ | ((uint32_t)data[(p) + 2] << 16))
+#define GETN4(p) ((uint32_t)data[p] \
+ | ((uint32_t)data[(p) + 1] << 8) \
+ | ((uint32_t)data[(p) + 2] << 16) \
+ | ((uint32_t)data[(p) + 3] << 24))
/* This is wrong with regard to endianess */
#define GETN(p, n, target) memcpy(target, &data[p], n)
=20
static int Unicodedecode( uint8_t *data, int len, char *target )=20
{
- int p =3D 1, i =3D 0;
+ int p =3D 1, i =3D 0;
=20
- if( ( data[ 0 ] =3D=3D 8 ) || ( data[ 0 ] =3D=3D 16 ) ) do {
- if( data[ 0 ] =3D=3D 16 ) p++; /* Ignore MSB of unicode16 */
- if( p < len ) {
- target[ i++ ] =3D data[ p++ ];
- }
- } while( p < len );
+ if( ( data[ 0 ] =3D=3D 8 ) || ( data[ 0 ] =3D=3D 16 ) ) do {
+ if( data[ 0 ] =3D=3D 16 ) p++; /* Ignore MSB of unicode16 */
+ if( p < len ) {
+ target[ i++ ] =3D data[ p++ ];
+ }
+ } while( p < len );
=20
- target[ i ] =3D '\0';
- return 0;
+ target[ i ] =3D '\0';
+ return 0;
}
=20
static int UDFDescriptor( uint8_t *data, uint16_t *TagID )=20
{
- *TagID =3D GETN2(0);
- // TODO: check CRC 'n stuff
- return 0;
+ *TagID =3D GETN2(0);
+ // TODO: check CRC 'n stuff
+ return 0;
}
=20
static int UDFExtentAD( uint8_t *data, uint32_t *Length, uint32_t *Locat=
ion )=20
{
- *Length =3D GETN4(0);
- *Location =3D GETN4(4);
- return 0;
+ *Length =3D GETN4(0);
+ *Location =3D GETN4(4);
+ return 0;
}
=20
static int UDFShortAD( uint8_t *data, struct AD *ad,=20
- struct Partition *partition )=20
+ struct Partition *partition )=20
{
- ad->Length =3D GETN4(0);
- ad->Flags =3D ad->Length >> 30;
- ad->Length &=3D 0x3FFFFFFF;
- ad->Location =3D GETN4(4);
- ad->Partition =3D partition->Number; // use number of current partit=
ion
- return 0;
+ ad->Length =3D GETN4(0);
+ ad->Flags =3D ad->Length >> 30;
+ ad->Length &=3D 0x3FFFFFFF;
+ ad->Location =3D GETN4(4);
+ ad->Partition =3D partition->Number; // use number of current partitio=
n
+ return 0;
}
=20
static int UDFLongAD( uint8_t *data, struct AD *ad )
{
- ad->Length =3D GETN4(0);
- ad->Flags =3D ad->Length >> 30;
- ad->Length &=3D 0x3FFFFFFF;
- ad->Location =3D GETN4(4);
- ad->Partition =3D GETN2(8);
- //GETN(10, 6, Use);
- return 0;
+ ad->Length =3D GETN4(0);
+ ad->Flags =3D ad->Length >> 30;
+ ad->Length &=3D 0x3FFFFFFF;
+ ad->Location =3D GETN4(4);
+ ad->Partition =3D GETN2(8);
+ //GETN(10, 6, Use);
+ return 0;
}
=20
static int UDFExtAD( uint8_t *data, struct AD *ad )
{
- ad->Length =3D GETN4(0);
- ad->Flags =3D ad->Length >> 30;
- ad->Length &=3D 0x3FFFFFFF;
- ad->Location =3D GETN4(12);
- ad->Partition =3D GETN2(16);
- //GETN(10, 6, Use);
- return 0;
+ ad->Length =3D GETN4(0);
+ ad->Flags =3D ad->Length >> 30;
+ ad->Length &=3D 0x3FFFFFFF;
+ ad->Location =3D GETN4(12);
+ ad->Partition =3D GETN2(16);
+ //GETN(10, 6, Use);
+ return 0;
}
=20
static int UDFICB( uint8_t *data, uint8_t *FileType, uint16_t *Flags )
{
- *FileType =3D GETN1(11);
- *Flags =3D GETN2(18);
- return 0;
+ *FileType =3D GETN1(11);
+ *Flags =3D GETN2(18);
+ return 0;
}
=20
=20
static int UDFPartition( uint8_t *data, uint16_t *Flags, uint16_t *Numbe=
r,
- char *Contents, uint32_t *Start, uint32_t *Length )
+ char *Contents, uint32_t *Start, uint32_t *Leng=
th )
{
- *Flags =3D GETN2(20);
- *Number =3D GETN2(22);
- GETN(24, 32, Contents);
- *Start =3D GETN4(188);
- *Length =3D GETN4(192);
- return 0;
+ *Flags =3D GETN2(20);
+ *Number =3D GETN2(22);
+ GETN(24, 32, Contents);
+ *Start =3D GETN4(188);
+ *Length =3D GETN4(192);
+ return 0;
}
=20
/**
@@ -419,66 +585,66 @@
*/
static int UDFLogVolume( uint8_t *data, char *VolumeDescriptor )
{
- uint32_t lbsize, MT_L, N_PM;
- Unicodedecode(&data[84], 128, VolumeDescriptor);
- lbsize =3D GETN4(212); // should be 2048
- MT_L =3D GETN4(264); // should be 6
- N_PM =3D GETN4(268); // should be 1
- if (lbsize !=3D DVD_VIDEO_LB_LEN) return 1;
- return 0;
+ uint32_t lbsize, MT_L, N_PM;
+ Unicodedecode(&data[84], 128, VolumeDescriptor);
+ lbsize =3D GETN4(212); // should be 2048
+ MT_L =3D GETN4(264); // should be 6
+ N_PM =3D GETN4(268); // should be 1
+ if (lbsize !=3D DVD_VIDEO_LB_LEN) return 1;
+ return 0;
}
=20
static int UDFFileEntry( uint8_t *data, uint8_t *FileType,=20
- struct Partition *partition, struct AD *ad )
+ struct Partition *partition, struct AD *ad )
{
- uint16_t flags;
- uint32_t L_EA, L_AD;
- unsigned int p;
+ uint16_t flags;
+ uint32_t L_EA, L_AD;
+ unsigned int p;
=20
- UDFICB( &data[ 16 ], FileType, &flags );
+ UDFICB( &data[ 16 ], FileType, &flags );
=20
- /* Init ad for an empty file (i.e. there isn't a AD, L_AD =3D=3D 0 )=
*/
- ad->Length =3D GETN4( 60 ); // Really 8 bytes a 56
- ad->Flags =3D 0;
- ad->Location =3D 0; // what should we put here?=20
- ad->Partition =3D partition->Number; // use number of current partit=
ion
+ /* Init ad for an empty file (i.e. there isn't a AD, L_AD =3D=3D 0 ) *=
/
+ ad->Length =3D GETN4( 60 ); // Really 8 bytes a 56
+ ad->Flags =3D 0;
+ ad->Location =3D 0; // what should we put here?=20
+ ad->Partition =3D partition->Number; // use number of current partitio=
n
=20
- L_EA =3D GETN4( 168 );
- L_AD =3D GETN4( 172 );
- p =3D 176 + L_EA;
- while( p < 176 + L_EA + L_AD ) {
- switch( flags & 0x0007 ) {
- case 0: UDFShortAD( &data[ p ], ad, partition ); p +=3D 8; =
break;
- case 1: UDFLongAD( &data[ p ], ad ); p +=3D 16; break;
- case 2: UDFExtAD( &data[ p ], ad ); p +=3D 20; break;
- case 3:
- switch( L_AD ) {
- case 8: UDFShortAD( &data[ p ], ad, partition ); br=
eak;
- case 16: UDFLongAD( &data[ p ], ad ); break;
- case 20: UDFExtAD( &data[ p ], ad ); break;
- }
- p +=3D L_AD;
- break;
- default:
- p +=3D L_AD; break;
- }
+ L_EA =3D GETN4( 168 );
+ L_AD =3D GETN4( 172 );
+ p =3D 176 + L_EA;
+ while( p < 176 + L_EA + L_AD ) {
+ switch( flags & 0x0007 ) {
+ case 0: UDFShortAD( &data[ p ], ad, partition ); p +=3D 8; break;
+ case 1: UDFLongAD( &data[ p ], ad ); p +=3D 16; break;
+ case 2: UDFExtAD( &data[ p ], ad ); p +=3D 20; break;
+ case 3:
+ switch( L_AD ) {
+ case 8: UDFShortAD( &data[ p ], ad, partition ); break;
+ case 16: UDFLongAD( &data[ p ], ad ); break;
+ case 20: UDFExtAD( &data[ p ], ad ); break;
+ }
+ p +=3D L_AD;
+ break;
+ default:
+ p +=3D L_AD; break;
}
- return 0;
+ }
+ return 0;
}
=20
static int UDFFileIdentifier( uint8_t *data, uint8_t *FileCharacteristic=
s,
- char *FileName, struct AD *FileICB )
+ char *FileName, struct AD *FileICB )
{
- uint8_t L_FI;
- uint16_t L_IU;
+ uint8_t L_FI;
+ uint16_t L_IU;
=20
- *FileCharacteristics =3D GETN1(18);
- L_FI =3D GETN1(19);
- UDFLongAD(&data[20], FileICB);
- L_IU =3D GETN2(36);
- if (L_FI) Unicodedecode(&data[38 + L_IU], L_FI, FileName);
- else FileName[0] =3D '\0';
- return 4 * ((38 + L_FI + L_IU + 3) / 4);
+ *FileCharacteristics =3D GETN1(18);
+ L_FI =3D GETN1(19);
+ UDFLongAD(&data[20], FileICB);
+ L_IU =3D GETN2(36);
+ if (L_FI) Unicodedecode(&data[38 + L_IU], L_FI, FileName);
+ else FileName[0] =3D '\0';
+ return 4 * ((38 + L_FI + L_IU + 3) / 4);
}
=20
/**
@@ -489,39 +655,46 @@
* return 1 on success, 0 on error;
*/
static int UDFMapICB( dvd_reader_t *device, struct AD ICB, uint8_t *File=
Type,
- struct Partition *partition, struct AD *File )=20
+ struct Partition *partition, struct AD *File )=20
{
- uint8_t LogBlock[DVD_VIDEO_LB_LEN];
- uint32_t lbnum;
- uint16_t TagID;
- struct icbmap tmpmap;
+ uint8_t *LogBlock;
+ uint32_t lbnum;
+ uint16_t TagID;
+ struct icbmap tmpmap;
=20
- lbnum =3D partition->Start + ICB.Location;
- tmpmap.lbn =3D lbnum;
- if(GetUDFCache(device, MapCache, lbnum, &tmpmap)) {
- *FileType =3D tmpmap.filetype;
- *File =3D tmpmap.file;
- return 1;
+ lbnum =3D partition->Start + ICB.Location;
+ tmpmap.lbn =3D lbnum;
+ if(GetUDFCache(device, MapCache, lbnum, &tmpmap)) {
+ *FileType =3D tmpmap.filetype;
+ *File =3D tmpmap.file;
+ return 1;
+ }
+
+ LogBlock =3D dvdalign_lbmalloc(device, 1);
+ if(!LogBlock) {
+ return 0;
+ }
+ =20
+ do {
+ if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <=3D 0 ) {
+ TagID =3D 0;
+ } else {
+ UDFDescriptor( LogBlock, &TagID );
}
=20
- do {
- if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <=3D 0 ) {
- TagID =3D 0;
- } else {
- UDFDescriptor( LogBlock, &TagID );
- }
-
- if( TagID =3D=3D 261 ) {
- UDFFileEntry( LogBlock, FileType, partition, File );
- tmpmap.file =3D *File;
- tmpmap.filetype =3D *FileType;
- SetUDFCache(device, MapCache, tmpmap.lbn, &tmpmap);
- return 1;
- };
- } while( ( lbnum <=3D partition->Start + ICB.Location + ( ICB.Length=
- 1 )
+ if( TagID =3D=3D 261 ) {
+ UDFFileEntry( LogBlock, FileType, partition, File );
+ tmpmap.file =3D *File;
+ tmpmap.filetype =3D *FileType;
+ SetUDFCache(device, MapCache, tmpmap.lbn, &tmpmap);
+ dvdalign_lbfree(device, LogBlock);
+ return 1;
+ };
+ } while( ( lbnum <=3D partition->Start + ICB.Location + ( ICB.Length -=
1 )
/ DVD_VIDEO_LB_LEN ) && ( TagID !=3D 261 ) );
=20
- return 0;
+ dvdalign_lbfree(device, LogBlock);
+ return 0;
}
=20
/**
@@ -532,121 +705,124 @@
*/
static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileNa=
me,
struct Partition *partition, struct AD *FileICB,
- int cache_file_info)=20
+ int cache_file_info)=20
{
- char filename[ MAX_UDF_FILE_NAME_LEN ];
- uint8_t directory[ 2 * DVD_VIDEO_LB_LEN ];
- uint32_t lbnum;
- uint16_t TagID;
- uint8_t filechar;
- unsigned int p;
- uint8_t *cached_dir =3D NULL;
- uint32_t dir_lba;
- struct AD tmpICB;
- int found =3D 0;
- int in_cache =3D 0;
+ char filename[ MAX_UDF_FILE_NAME_LEN ];
+ uint8_t *directory;
+ uint32_t lbnum;
+ uint16_t TagID;
+ uint8_t filechar;
+ unsigned int p;
+ uint8_t *cached_dir =3D NULL;
+ uint32_t dir_lba;
+ struct AD tmpICB;
+ int found =3D 0;
+ int in_cache =3D 0;
=20
- /* Scan dir for ICB of file */
- lbnum =3D partition->Start + Dir.Location;
+ /* Scan dir for ICB of file */
+ lbnum =3D partition->Start + Dir.Location;
=20
- if(DVDUDFCacheLevel(device, -1) > 0) {
- /* caching */
+ if(DVDUDFCacheLevel(device, -1) > 0) {
+ /* caching */
=20
- if(!GetUDFCache(device, LBUDFCache, lbnum, &cached_dir)) {
- dir_lba =3D (Dir.Length + DVD_VIDEO_LB_LEN) / DVD_VIDEO_LB_LEN;
- if((cached_dir =3D malloc(dir_lba * DVD_VIDEO_LB_LEN)) =3D=3D NULL) {
- return 0;
- }
- if( DVDReadLBUDF( device, lbnum, dir_lba, cached_dir, 0) <=3D 0 ) {
- free(cached_dir);
- cached_dir =3D NULL;
- }
- /*
- if(cached_dir) {
- LOG_ERROR( stderr, "malloc dir: %d\n",
- dir_lba * DVD_VIDEO_LB_LEN);
- }
- */
- SetUDFCache(device, LBUDFCache, lbnum, &cached_dir);
- } else {
- in_cache =3D 1;
+ if(!GetUDFCache(device, LBUDFCache, lbnum, &cached_dir)) {
+ dir_lba =3D (Dir.Length + DVD_VIDEO_LB_LEN) / DVD_VIDEO_LB_LEN;
+ if((cached_dir =3D dvdalign_lbmalloc(device, dir_lba)) =3D=3D NULL=
) {
+ return 0;
}
- =20
- if(cached_dir =3D=3D NULL) {
- return 0;
+ if( DVDReadLBUDF( device, lbnum, dir_lba, cached_dir, 0) <=3D 0 ) =
{
+ dvdalign_lbfree(device, cached_dir);
+ cached_dir =3D NULL;
}
+ SetUDFCache(device, LBUDFCache, lbnum, &cached_dir);
+ } else {
+ in_cache =3D 1;
+ }
=20
- p =3D 0;
+ if(cached_dir =3D=3D NULL) {
+ return 0;
+ }
=20
- while( p < Dir.Length ) {
- UDFDescriptor( &cached_dir[ p ], &TagID );
- if( TagID =3D=3D 257 ) {
- p +=3D UDFFileIdentifier( &cached_dir[ p ], &filechar,
- filename, &tmpICB );
- if(cache_file_info && !in_cache) {
- uint8_t tmpFiletype;
- struct AD tmpFile;
- =20
- if( !strcasecmp( FileName, filename ) ) {
- *FileICB =3D tmpICB;
- found =3D 1;
- =20
- }
- UDFMapICB(device, tmpICB, &tmpFiletype,
- partition, &tmpFile);
- } else {
- if( !strcasecmp( FileName, filename ) ) {
- *FileICB =3D tmpICB;
- return 1;
- }
- }
+ p =3D 0;
+ =20
+ while( p < Dir.Length ) {
+ UDFDescriptor( &cached_dir[ p ], &TagID );
+ if( TagID =3D=3D 257 ) {
+ p +=3D UDFFileIdentifier( &cached_dir[ p ], &filechar,
+ filename, &tmpICB );
+ if(cache_file_info && !in_cache) {
+ uint8_t tmpFiletype;
+ struct AD tmpFile;
+ =20
+ if( !strcasecmp( FileName, filename ) ) {
+ *FileICB =3D tmpICB;
+ found =3D 1;
+ =20
+ }
+ UDFMapICB(device, tmpICB, &tmpFiletype,
+ partition, &tmpFile);
} else {
- if(cache_file_info && (!in_cache) && found) {
- return 1;
- }
- return 0;
+ if( !strcasecmp( FileName, filename ) ) {
+ *FileICB =3D tmpICB;
+ return 1;
+ }
}
+ } else {
+ if(cache_file_info && (!in_cache) && found) {
+ return 1;
+ }
+ return 0;
}
- if(cache_file_info && (!in_cache) && found) {
- return 1;
- }
- return 0;
}
+ if(cache_file_info && (!in_cache) && found) {
+ return 1;
+ }
+ return 0;
+ }
=20
- if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <=3D 0 ) {
+ directory =3D dvdalign_lbmalloc(device, 2);
+ if(!directory) {
+ return 0;
+ }
+ if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <=3D 0 ) {
+ dvdalign_lbfree(device, directory);
+ return 0;
+ }
+
+ p =3D 0;
+ while( p < Dir.Length ) {
+ if( p > DVD_VIDEO_LB_LEN ) {
+ ++lbnum;
+ p -=3D DVD_VIDEO_LB_LEN;
+ Dir.Length -=3D DVD_VIDEO_LB_LEN;
+ if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <=3D 0 ) {
+ dvdalign_lbfree(device, directory);
return 0;
+ }
}
-
- p =3D 0;
- while( p < Dir.Length ) {
- if( p > DVD_VIDEO_LB_LEN ) {
- ++lbnum;
- p -=3D DVD_VIDEO_LB_LEN;
- Dir.Length -=3D DVD_VIDEO_LB_LEN;
- if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <=3D 0 ) =
{
- return 0;
- }
- }
- UDFDescriptor( &directory[ p ], &TagID );
- if( TagID =3D=3D 257 ) {
- p +=3D UDFFileIdentifier( &directory[ p ], &filechar,
- filename, FileICB );
- if( !strcasecmp( FileName, filename ) ) {
- return 1;
- }
- } else {
- return 0;
- }
+ UDFDescriptor( &directory[ p ], &TagID );
+ if( TagID =3D=3D 257 ) {
+ p +=3D UDFFileIdentifier( &directory[ p ], &filechar,
+ filename, FileICB );
+ if( !strcasecmp( FileName, filename ) ) {
+ dvdalign_lbfree(device, directory);
+ return 1;
+ }
+ } else {
+ dvdalign_lbfree(device, directory);
+ return 0;
}
+ }
=20
- return 0;
+ dvdalign_lbfree(device, directory);
+ return 0;
}
=20
=20
static int UDFGetAVDP( dvd_reader_t *device,
- struct avdp_t *avdp)
+ struct avdp_t *avdp)
{
- uint8_t Anchor[ DVD_VIDEO_LB_LEN ];
+ uint8_t *Anchor;
uint32_t lbnum, MVDS_location, MVDS_length;
uint16_t TagID;
uint32_t lastsector;
@@ -656,12 +832,16 @@
if(GetUDFCache(device, AVDPCache, 0, avdp)) {
return 1;
}
-
+ =20
/* Find Anchor */
lastsector =3D 0;
lbnum =3D 256; /* Try #1, prime anchor */
terminate =3D 0;
=20
+ Anchor =3D dvdalign_lbmalloc(device, 1);
+ if(!Anchor) {
+ return 0;
+ }
for(;;) {
if( DVDReadLBUDF( device, lbnum, 1, Anchor, 0 ) > 0 ) {
UDFDescriptor( Anchor, &TagID );
@@ -670,24 +850,29 @@
}
if (TagID !=3D 2) {
/* Not an anchor */
- if( terminate ) return 0; /* Final try failed */
+ if( terminate ) {
+ dvdalign_lbfree(device, Anchor);
+ errno =3D EMEDIUMTYPE;
+ return 0; /* Final try failed */
+ }=20
=20
if( lastsector ) {
-=09
- /* We already found the last sector. Try #3, alternative
- * backup anchor. If that fails, don't try again.
- */
- lbnum =3D lastsector;
- terminate =3D 1;
+ /* We already found the last sector. Try #3, alternative
+ * backup anchor. If that fails, don't try again.
+ */
+ lbnum =3D lastsector;
+ terminate =3D 1;
} else {
- /* TODO: Find last sector of the disc (this is optional). */
- if( lastsector ) {
- /* Try #2, backup anchor */
- lbnum =3D lastsector - 256;
- } else {
- /* Unable to find last sector */
- return 0;
- }
+ /* TODO: Find last sector of the disc (this is optional). */
+ if( lastsector ) {
+ /* Try #2, backup anchor */
+ lbnum =3D lastsector - 256;
+ } else {
+ /* Unable to find last sector */
+ dvdalign_lbfree(device, Anchor);
+ errno =3D EMEDIUMTYPE;
+ return 0;
+ }
}
} else {
/* It's an anchor! We can leave */
@@ -706,6 +891,7 @@
=20
SetUDFCache(device, AVDPCache, 0, avdp);
=20
+ dvdalign_lbfree(device, Anchor);
return 1;
}
=20
@@ -715,146 +901,173 @@
* part: structure to fill with the partition information
*/
static int UDFFindPartition( dvd_reader_t *device, int partnum,
- struct Partition *part )=20
+ struct Partition *part )=20
{
- uint8_t LogBlock[ DVD_VIDEO_LB_LEN ];
- uint32_t lbnum, MVDS_location, MVDS_length;
- uint16_t TagID;
- int i, volvalid;
- struct avdp_t avdp;
+ uint8_t *LogBlock;
+ uint32_t lbnum, MVDS_location, MVDS_length;
+ uint16_t TagID;
+ int i, volvalid;
+ struct avdp_t avdp;
=20
=20
- if(!UDFGetAVDP(device, &avdp)) {
- return 0;
- }
+ if(!UDFGetAVDP(device, &avdp)) {
+ return 0;
+ }
=20
- /* Main volume descriptor */
- MVDS_location =3D avdp.mvds.location;
- MVDS_length =3D avdp.mvds.length;
+ LogBlock =3D dvdalign_lbmalloc(device, 1);
+ if(!LogBlock) {
+ return 0;
+ }
+ /* Main volume descriptor */
+ MVDS_location =3D avdp.mvds.location;
+ MVDS_length =3D avdp.mvds.length;
=20
- part->valid =3D 0;
- volvalid =3D 0;
- part->VolumeDesc[ 0 ] =3D '\0';
- i =3D 1;
+ part->valid =3D 0;
+ volvalid =3D 0;
+ part->VolumeDesc[ 0 ] =3D '\0';
+ i =3D 1;
+ do {
+ /* Find Volume Descriptor */
+ lbnum =3D MVDS_location;
do {
- /* Find Volume Descriptor */
- lbnum =3D MVDS_location;
- do {
=20
- if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <=3D 0 )=
{
- TagID =3D 0;
- } else {
- UDFDescriptor( LogBlock, &TagID );
- }
+ if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <=3D 0 ) {
+ TagID =3D 0;
+ } else {
+ UDFDescriptor( LogBlock, &TagID );
+ }
=20
- if( ( TagID =3D=3D 5 ) && ( !part->valid ) ) {
- /* Partition Descriptor */
- UDFPartition( LogBlock, &part->Flags, &part->Number,
- part->Contents, &part->Start, &part->Lengt=
h );
- part->valid =3D ( partnum =3D=3D part->Number );
- } else if( ( TagID =3D=3D 6 ) && ( !volvalid ) ) {
- /* Logical Volume Descriptor */
- if( UDFLogVolume( LogBlock, part->VolumeDesc ) ) { =20
- /* TODO: sector size wrong! */
- } else {
- volvalid =3D 1;
- }
- }
+ if( ( TagID =3D=3D 5 ) && ( !part->valid ) ) {
+ /* Partition Descriptor */
+ UDFPartition( LogBlock, &part->Flags, &part->Number,
+ part->Contents, &part->Start, &part->Length );
+ part->valid =3D ( partnum =3D=3D part->Number );
+ } else if( ( TagID =3D=3D 6 ) && ( !volvalid ) ) {
+ /* Logical Volume Descriptor */
+ if( UDFLogVolume( LogBlock, part->VolumeDesc ) ) { =20
+ /* TODO: sector size wrong! */
+ } else {
+ volvalid =3D 1;
+ }
+ }
=20
- } while( ( lbnum <=3D MVDS_location + ( MVDS_length - 1 )
- / DVD_VIDEO_LB_LEN ) && ( TagID !=3D 8 )
- && ( ( !part->valid ) || ( !volvalid ) ) );
+ } while( ( lbnum <=3D MVDS_location + ( MVDS_length - 1 )
+ / DVD_VIDEO_LB_LEN ) && ( TagID !=3D 8 )
+ && ( ( !part->valid ) || ( !volvalid ) ) );
=20
- if( ( !part->valid) || ( !volvalid ) ) {
- /* Backup volume descriptor */
- MVDS_location =3D avdp.mvds.location;
- MVDS_length =3D avdp.mvds.length;
- }
- } while( i-- && ( ( !part->valid ) || ( !volvalid ) ) );
+ if( ( !part->valid) || ( !volvalid ) ) {
+ /* Backup volume descriptor */
+ MVDS_location =3D avdp.mvds.location;
+ MVDS_length =3D avdp.mvds.length;
+ }
+ } while( i-- && ( ( !part->valid ) || ( !volvalid ) ) );
=20
- /* We only care for the partition, not the volume */
- return part->valid;
+ dvdalign_lbfree(device, LogBlock);
+ /* We only care for the partition, not the volume */
+ return part->valid;
}
=20
uint32_t UDFFindFile( dvd_reader_t *device, char *filename,
- uint32_t *filesize )
+ uint32_t *filesize )
{
- uint8_t LogBlock[ DVD_VIDEO_LB_LEN ];
- uint32_t lbnum;
- uint16_t TagID;
- struct Partition partition;
- struct AD RootICB, File, ICB;
- char tokenline[ MAX_UDF_FILE_NAME_LEN ];
- char *token;
- uint8_t filetype;
-
+ uint8_t *LogBlock;
+ uint32_t lbnum;
+ uint16_t TagID;
+ struct Partition partition;
+ struct AD RootICB, File, ICB;
+ char tokenline[ MAX_UDF_FILE_NAME_LEN ];
+ char *token;
+ uint8_t filetype;
+ =20
+ if(filesize) {
*filesize =3D 0;
- tokenline[0] =3D '\0';
- strcat( tokenline, filename );
+ }
+ tokenline[0] =3D '\0';
+ strcat( tokenline, filename );
=20
=20
- if(!(GetUDFCache(device, PartitionCache, 0, &partition) &&
- GetUDFCache(device, RootICBCache, 0, &RootICB))) {
- /* Find partition, 0 is the standard location for DVD Video.*/
- if( !UDFFindPartition( device, 0, &partition ) ) return 0;
- SetUDFCache(device, PartitionCache, 0, &partition);
- =20
- /* Find root dir ICB */
- lbnum =3D partition.Start;
- do {
- if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <=3D 0 ) {
- TagID =3D 0;
- } else {
- UDFDescriptor( LogBlock, &TagID );
- }
+ if(!(GetUDFCache(device, PartitionCache, 0, &partition) &&
+ GetUDFCache(device, RootICBCache, 0, &RootICB))) {
+ /* Find partition, 0 is the standard location for DVD Video.*/
+ if( !UDFFindPartition( device, 0, &partition ) ) {
+ return 0;
+ }
+ SetUDFCache(device, PartitionCache, 0, &partition);
+ =20
+ LogBlock =3D dvdalign_lbmalloc(device, 1);
+ if(!LogBlock) {
+ return 0;
+ }
+ /* Find root dir ICB */
+ lbnum =3D partition.Start;
+ do {
+ if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <=3D 0 ) {
+ TagID =3D 0;
+ } else {
+ UDFDescriptor( LogBlock, &TagID );
+ }
=20
- /* File Set Descriptor */
- if( TagID =3D=3D 256 ) { // File Set Descriptor
- UDFLongAD( &LogBlock[ 400 ], &RootICB );
- }
+ /* File Set Descriptor */
+ if( TagID =3D=3D 256 ) { // File Set Descriptor
+ UDFLongAD( &LogBlock[ 400 ], &RootICB );
+ }
} while( ( lbnum < partition.Start + partition.Length )
&& ( TagID !=3D 8 ) && ( TagID !=3D 256 ) );
=20
+ dvdalign_lbfree(device, LogBlock);
+ =20
/* Sanity checks. */
- if( TagID !=3D 256 ) return 0;
- if( RootICB.Partition !=3D 0 ) return 0;
+ if( TagID !=3D 256 ) {
+ return 0;
+ }
+ if( RootICB.Partition !=3D 0 ) {
+ return 0;
+ }
SetUDFCache(device, RootICBCache, 0, &RootICB);
- }
+ }
=20
- /* Find root dir */
- if( !UDFMapICB( device, RootICB, &filetype, &partition, &File ) ) re=
turn 0;
- if( filetype !=3D 4 ) return 0; /* Root dir should be dir */
-
- {
- int cache_file_info =3D 0;
- /* Tokenize filepath */
- token =3D strtok(tokenline, "/");
+ /* Find root dir */
+ if( !UDFMapICB( device, RootICB, &filetype, &partition, &File ) ) {
+ return 0;
+ }
+ if( filetype !=3D 4 ) {
+ return 0; /* Root dir should be dir */
+ }
+ {
+ int cache_file_info =3D 0;
+ /* Tokenize filepath */
+ token =3D strtok(tokenline, "/");
+ =20
+ while( token !=3D NULL ) {
=20
- while( token !=3D NULL ) {
- =20
- if( !UDFScanDir( device, File, token, &partition, &ICB,
- cache_file_info)) {
- return 0;
- }
- if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) ) {
- return 0;
- }
- if(!strcmp(token, "VIDEO_TS")) {
- cache_file_info =3D 1;
- }
- token =3D strtok( NULL, "/" );
+ if( !UDFScanDir( device, File, token, &partition, &ICB,
+ cache_file_info)) {
+ return 0;
}
- }=20
+ if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) ) {
+ return 0;
+ }
+ if(!strcmp(token, "VIDEO_TS")) {
+ cache_file_info =3D 1;
+ }
+ token =3D strtok( NULL, "/" );
+ }
+ }=20
=20
- /* Sanity check. */
- if( File.Partition !=3D 0 ) return 0;
- =20
+ /* Sanity check. */
+ if( File.Partition !=3D 0 ) {
+ return 0;
+ }
+
+ if(filesize) {
*filesize =3D File.Length;
- /* Hack to not return partition.Start for empty files. */
- if( !File.Location )
- return 0;
- else
- return partition.Start + File.Location;
+ }
+ /* Hack to not return partition.Start for empty files. */
+ if( !File.Location ) {
+ return 0;
+ } else {
+ return partition.Start + File.Location;
+ }
}
=20
=20
@@ -863,10 +1076,11 @@
* Gets a Descriptor .
* Returns 1 if descriptor found, 0 on error.
* id, tagid of descriptor
- * bufsize, size of BlockBuf (must be >=3D DVD_VIDEO_LB_LEN).
+ * bufsize, size of BlockBuf (must be >=3D DVD_VIDEO_LB_LEN)
+ * and aligned for raw/O_DIRECT read.
*/
static int UDFGetDescriptor( dvd_reader_t *device, int id,
- uint8_t *descriptor, int bufsize)=20
+ uint8_t *descriptor, int bufsize)=20
{
uint32_t lbnum, MVDS_location, MVDS_length;
struct avdp_t avdp;
@@ -897,18 +1111,18 @@
do {
=20
if( DVDReadLBUDF( device, lbnum++, 1, descriptor, 0 ) <=3D 0 ) {
- TagID =3D 0;
+ TagID =3D 0;
} else {
- UDFDescriptor( descriptor, &TagID );
+ UDFDescriptor( descriptor, &TagID );
}
=20
if( (TagID =3D=3D id) && ( !desc_found ) ) {
- /* Descriptor */
- desc_found =3D 1;
+ /* Descriptor */
+ desc_found =3D 1;
}
} while( ( lbnum <=3D MVDS_location + ( MVDS_length - 1 )
- / DVD_VIDEO_LB_LEN ) && ( TagID !=3D 8 )
- && ( !desc_found) );
+ / DVD_VIDEO_LB_LEN ) && ( TagID !=3D 8 )
+ && ( !desc_found) );
=20
if( !desc_found ) {
/* Backup volume descriptor */
@@ -916,6 +1130,7 @@
MVDS_length =3D avdp.rvds.length;
}
} while( i-- && ( !desc_found ) );
+
=20
return desc_found;
}
@@ -923,20 +1138,27 @@
=20
static int UDFGetPVD(dvd_reader_t *device, struct pvd_t *pvd)
{
- uint8_t pvd_buf[DVD_VIDEO_LB_LEN];
+ uint8_t *pvd_buf;
=20
if(GetUDFCache(device, PVDCache, 0, pvd)) {
return 1;
}
-
- if(!UDFGetDescriptor( device, 1, pvd_buf, sizeof(pvd_buf))) {
+ =20
+ pvd_buf =3D dvdalign_lbmalloc(device, 1);
+ if(!pvd_buf) {
return 0;
}
+ if(!UDFGetDescriptor( device, 1, pvd_buf, 1*DVD_VIDEO_LB_LEN)) {
+ dvdalign_lbfree(device, pvd_buf);
+ return 0;
+ }
=20
memcpy(pvd->VolumeIdentifier, &pvd_buf[24], 32);
memcpy(pvd->VolumeSetIdentifier, &pvd_buf[72], 128);
SetUDFCache(device, PVDCache, 0, pvd);
=20
+ dvdalign_lbfree(device, pvd_buf);
+
return 1;
}
=20
@@ -947,7 +1169,7 @@
* returns the size of buffer needed for all data
*/
int UDFGetVolumeIdentifier(dvd_reader_t *device, char *volid,
- unsigned int volid_size)
+ unsigned int volid_size)
{
struct pvd_t pvd;
unsigned int volid_len;
@@ -980,7 +1202,7 @@
* or 0 on error
*/
int UDFGetVolumeSetIdentifier(dvd_reader_t *device, uint8_t *volsetid,
- unsigned int volsetid_size)
+ unsigned int volsetid_size)
{
struct pvd_t pvd;
=20
Modified: trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_udf.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_udf.h 2007-01-22 11:21:1=
6 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/dvdread/dvd_udf.h 2007-01-28 16:48:1=
1 UTC (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
#ifndef DVD_UDF_H_INCLUDED
#define DVD_UDF_H_INCLUDED
=20
@@ -31,7 +32,11 @@
* http://www.gnu.org/copyleft/gpl.html
*/
=20
+#if defined(HAVE_INTTYPES_H)
#include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
=20
#include "dvd_reader.h"
=20
@@ -45,14 +50,16 @@
* absolute pathname on the UDF filesystem, starting with '/'. For exam=
ple,
* '/VIDEO_TS/VTS_01_1.IFO'. On success, filesize will be set to the si=
ze of
* the file in bytes.
+ * This implementation relies on that the file size is less than 2^32
+ * A DVD file can at most be 2^30 (-2048 ?).
*/
uint32_t UDFFindFile( dvd_reader_t *device, char *filename, uint32_t *si=
ze );
-
-void FreeUDFCache(void *cache);
+ =20
+void FreeUDFCache(dvd_reader_t *device, void *cache);
int UDFGetVolumeIdentifier(dvd_reader_t *device,
- char *volid, unsigned int volid_size);
+ char *volid, unsigned int volid_size);
int UDFGetVolumeSetIdentifier(dvd_reader_t *device,
- uint8_t *volsetid, unsigned int volsetid_size);
+ uint8_t *volsetid, unsigned int volsetid_s=
ize);
#ifdef __cplusplus
};
#endif
Added: trunk/DvdMenuXtractor/libdvdread/dvdread/dvdread.proj
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/dvdread/dvdread.proj 2007-01-22 11:2=
1:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/dvdread/dvdread.proj 2007-01-28 16:4=
8:11 UTC (rev 1270)
@@ -0,0 +1,35 @@
+#include "*/*.proj"
+
+LIB dvdread
+{
+ USE(TARGET_WIN) c99msvc
+ USE(TARGET_WIN) posixmsvc
+ DEFINE STDC_HEADERS
+
+ SOURCE cmd_print.c
+ SOURCE dvd_input.c
+ SOURCE dvd_reader.c
+ SOURCE dvd_udf.c
+ SOURCE ifo_print.c
+ SOURCE ifo_read.c
+ SOURCE md5.c
+ SOURCE nav_print.c
+ SOURCE nav_read.c
+
+ HEADER bswap.h
+ HEADER cmd_print.h
+ HEADER dvd_input.h
+ HEADER dvd_reader.h
+ HEADER dvd_udf.h
+ HEADER dvdread_internal.h
+ HEADER ifo_print.h
+ HEADER ifo_read.h
+ HEADER ifo_types.h
+ HEADER md5.h
+ HEADER nav_print.h
+ HEADER nav_read.h
+ HEADER nav_types.h
+ =20
+ INCLUDE(TARGET_WIN) ../win32
+ INCLUDE ..
+}
Modified: trunk/DvdMenuXtractor/libdvdread/dvdread/dvdread_internal.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/dvdread/dvdread_internal.h 2007-01-2=
2 11:21:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/dvdread/dvdread_internal.h 2007-01-2=
8 16:48:11 UTC (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
#ifndef DVDREAD_INTERNAL_H
#define DVDREAD_INTERNAL_H
=20
@@ -2,9 +3,14 @@
=20
-#define CHECK_VALUE(arg) \
- if(!(arg)) { \
- fprintf(stderr, "\n*** libdvdread: CHECK_VALUE failed in %s:%i ***" \
- "\n*** for %s ***\n\n", \
- __FILE__, __LINE__, # arg ); \
- }
+#define CHECK_VALUE(arg) =
\
+ if(!(arg)) { =
\
+ fprintf(stderr, "\n*** libdvdread: CHECK_VALUE failed in %s:%i ***" =
\
+ "\n*** for %s ***\n\n", =
\
+ __FILE__, __LINE__, # arg ); =
\
+ }
=20
+
+int get_verbose(void);
+int dvdread_verbose(dvd_reader_t *dvd);
+dvd_reader_t *device_of_file(dvd_file_t *file);
+
#endif /* DVDREAD_INTERNAL_H */
Modified: trunk/DvdMenuXtractor/libdvdread/dvdread/ifo_print.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/dvdread/ifo_print.c 2007-01-22 11:21=
:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/dvdread/ifo_print.c 2007-01-28 16:48=
:11 UTC (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*=20
* Copyright (C) 2000, 2001, 2002, 2003
* Bj=F6rn Englund <d4bjorn at dtek.chalmers.se>,=20
@@ -21,22 +22,25 @@
#include "config.h"
=20
#include <stdio.h>
-#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
+#include <stdlib.h>
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
#endif
-#ifdef HAVE_STDARG_H
-#include <stdarg.h>
-#endif
-#include <inttypes.h>
#include <string.h>
#include <ctype.h>
=20
+#if defined(HAVE_INTTYPES_H)
+#include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
+
#include "ifo_types.h"
#include "ifo_read.h"
#include "ifo_print.h"
+#include "cmd_print.h"
#include "dvdread_internal.h"
-
+
/* Put this in some other file / package? It's used in nav_print too. *=
/
static void ifoPrint_time(dvd_time_t *dtime) {
const char *rate;
@@ -46,10 +50,10 @@
CHECK_VALUE((dtime->frame_u&0xf) < 0xa);
=20
printf("%02x:%02x:%02x.%02x",=20
- dtime->hour,
- dtime->minute,
- dtime->second,
- dtime->frame_u & 0x3f);
+ dtime->hour,
+ dtime->minute,
+ dtime->second,
+ dtime->frame_u & 0x3f);
switch((dtime->frame_u & 0xc0) >> 6) {
case 1:
rate =3D "25.00";
@@ -68,20 +72,6 @@
printf(" @ %s fps", rate);
}
=20
-/* Put this in some other file / package? It's used in nav_print too.
- Possibly also by the vm / navigator. */
-static void ifoPrint_CMD(int row, vm_cmd_t *command) {
- int i;
-
- printf("(%03d) ", row + 1);
- for(i=3D0;i<8;i++)
- printf("%02x ", command->bytes[i]);
- printf("| ");
-
- //vmcmd(command);
- printf("\n");
-}
-
static void ifoPrint_video_attributes(video_attr_t *attr) {
=20
/* The following test is shorter but not correct ISO C,
@@ -164,14 +154,14 @@
}
=20
switch(attr->bit_rate) {
- case 0:
- printf("Variable Bit Rate ");
- break;
- case 1:
- printf("Constant Bit Rate ");
- break;
- default:
- printf("(please send a bug report)");
+ case 0:
+ printf("Variable Bit Rate ");
+ break;
+ case 1:
+ printf("Constant Bit Rate ");
+ break;
+ default:
+ printf("(please send a bug report)");
}
=20
{
@@ -262,6 +252,9 @@
case 1:
printf("%c%c (%c) ", attr->lang_code>>8, attr->lang_code & 0xff,
attr->lang_extension ? attr->lang_extension : ' ');
+ if(attr->lang_extension) {
+ printf("(please send a bug report) lang_extension !=3D 0");
+ }
break;
default:
printf("(please send a bug report) ");
@@ -281,33 +274,65 @@
printf("(please send a bug report) ");
}
=20
- switch(attr->quantization) {
- case 0:
- printf("16bit ");
+ switch(attr->audio_format) {
+ case 0: //ac3
+ if(attr->quantization !=3D 3) {
+ printf("(please send a bug report) ac3 quant/drc not 3 (%d)",
+ attr->quantization);
+ }
break;
- case 1:
- printf("20bit ");
+ case 2: //mpeg 1 or mpeg 2 without extension stream
+ case 3: //mpeg 2 with extension stream
+ switch(attr->quantization) {
+ case 0: //no drc
+ printf("no drc ");
+ break;
+ case 1:
+ printf("drc ");
+ break;
+ default:
+ printf("(please send a bug report) mpeg reserved quant/drc (%d)",
+ attr->quantization);
+ break;
+ }
break;
- case 2:
- printf("24bit ");
+ case 4:
+ switch(attr->quantization) {
+ case 0:
+ printf("16bit ");
+ break;
+ case 1:
+ printf("20bit ");
+ break;
+ case 2:
+ printf("24bit ");
+ break;
+ case 3:
+ printf("(please send a bug report) lpcm reserved quant/drc (%d)",
+ attr->quantization);
+ break;
+ }
break;
- case 3:
- printf("drc ");
+ case 6: //dts
+ if(attr->quantization !=3D 3) {
+ printf("(please send a bug report) dts quant/drc not 3 (%d)",
+ attr->quantization);
+ }
break;
default:
- printf("(please send a bug report) ");
+ break;
}
- =20
+
switch(attr->sample_frequency) {
case 0:
printf("48kHz ");
break;
case 1:
- printf("??kHz ");
+ printf("96kHz ");
break;
default:
printf("sample_frequency %i (please send a bug report) ",=20
- attr->sample_frequency);
+ attr->sample_frequency);
}
=20
printf("%dCh ", attr->channels + 1);
@@ -383,15 +408,14 @@
printf("%02x%02x ", attr->lang_code >> 8, attr->lang_code & 0xff);
}
} else {
- printf("lang not specified ");
+ printf("lang not specified ");
}
=20
printf("%d ", attr->zero1);
printf("%d ", attr->zero2);
- printf("%d ", attr->code_extension);
+ printf("%d ", attr->lang_extension);
=20
- /* Is this correct? should it not be subp_code_ext here instead? */
- switch(attr->lang_extension) {
+ switch(attr->code_extension) {
case 0:
printf("Not specified ");
break;
@@ -522,8 +546,8 @@
printf("Last Sector of VMG: %08x\n", vmgi_mat->vmg_last_sector);
printf("Last Sector of VMGI: %08x\n", vmgi_mat->vmgi_last_sector);
printf("Specification version number: %01x.%01x\n",=20
- vmgi_mat->specification_version >> 4,=20
- vmgi_mat->specification_version & 0xf);
+ vmgi_mat->specification_version >> 4,=20
+ vmgi_mat->specification_version & 0xf);
/* Byte 2 of 'VMG Category' (00xx0000) is the Region Code */
printf("VMG Category: %08x\n", vmgi_mat->vmg_category);
printf("VMG Number of Volumes: %i\n", vmgi_mat->vmg_nr_of_volumes);
@@ -535,7 +559,7 @@
printf("%08x\n", (uint32_t)vmgi_mat->vmg_pos_code);
printf("End byte of VMGI_MAT: %08x\n", vmgi_mat->vmgi_last_byte);
printf("Start byte of First Play PGC FP PGC: %08x\n",=20
- vmgi_mat->first_play_pgc);
+ vmgi_mat->first_play_pgc);
printf("Start sector of VMGM_VOBS: %08x\n", vmgi_mat->vmgm_vobs);
printf("Start sector of TT_SRPT: %08x\n", vmgi_mat->tt_srpt);
printf("Start sector of VMGM_PGCI_UT: %08x\n", vmgi_mat->vmgm_pgci_ut)=
;
@@ -544,19 +568,19 @@
printf("Start sector of TXTDT_MG: %08x\n", vmgi_mat->txtdt_mgi);
printf("Start sector of VMGM_C_ADT: %08x\n", vmgi_mat->vmgm_c_adt);
printf("Start sector of VMGM_VOBU_ADMAP: %08x\n",=20
- vmgi_mat->vmgm_vobu_admap);
+ vmgi_mat->vmgm_vobu_admap);
printf("Video attributes of VMGM_VOBS: ");
ifoPrint_video_attributes(&vmgi_mat->vmgm_video_attr);
printf("\n");
printf("VMGM Number of Audio attributes: %i\n",=20
- vmgi_mat->nr_of_vmgm_audio_streams);
+ vmgi_mat->nr_of_vmgm_audio_streams);
if(vmgi_mat->nr_of_vmgm_audio_streams > 0) {
printf("\tstream %i status: ", 1);
ifoPrint_audio_attributes(&vmgi_mat->vmgm_audio_attr);
printf("\n");
}
printf("VMGM Number of Sub-picture attributes: %i\n",=20
- vmgi_mat->nr_of_vmgm_subp_streams);
+ vmgi_mat->nr_of_vmgm_subp_streams);
if(vmgi_mat->nr_of_vmgm_subp_streams > 0) {
printf("\tstream %2i status: ", 1);
ifoPrint_subp_attributes(&vmgi_mat->vmgm_subp_attr);
@@ -572,8 +596,8 @@
printf("Last Sector of VTS: %08x\n", vtsi_mat->vts_last_sector);
printf("Last Sector of VTSI: %08x\n", vtsi_mat->vtsi_last_sector);
printf("Specification version number: %01x.%01x\n",=20
- vtsi_mat->specification_version>>4,=20
- vtsi_mat->specification_version&0xf);
+ vtsi_mat->specification_version>>4,=20
+ vtsi_mat->specification_version&0xf);
printf("VTS Category: %08x\n", vtsi_mat->vts_category);
printf("End byte of VTSI_MAT: %08x\n", vtsi_mat->vtsi_last_byte);
printf("Start sector of VTSM_VOBS: %08x\n", vtsi_mat->vtsm_vobs);
@@ -592,7 +616,7 @@
printf("\n");
=20
printf("VTSM Number of Audio attributes: %i\n",=20
- vtsi_mat->nr_of_vtsm_audio_streams);
+ vtsi_mat->nr_of_vtsm_audio_streams);
if(vtsi_mat->nr_of_vtsm_audio_streams > 0) {
printf("\tstream %i status: ", 1);
ifoPrint_audio_attributes(&vtsi_mat->vtsm_audio_attr);
@@ -600,7 +624,7 @@
}
=20
printf("VTSM Number of Sub-picture attributes: %i\n",=20
- vtsi_mat->nr_of_vtsm_subp_streams);
+ vtsi_mat->nr_of_vtsm_subp_streams);
if(vtsi_mat->nr_of_vtsm_subp_streams > 0) {
printf("\tstream %2i status: ", 1);
ifoPrint_subp_attributes(&vtsi_mat->vtsm_subp_attr);
@@ -612,7 +636,7 @@
printf("\n");
=20
printf("VTS Number of Audio attributes: %i\n",=20
- vtsi_mat->nr_of_vts_audio_streams);
+ vtsi_mat->nr_of_vts_audio_streams);
for(i =3D 0; i < vtsi_mat->nr_of_vts_audio_streams; i++) {
printf("\tstream %i status: ", i);
ifoPrint_audio_attributes(&vtsi_mat->vts_audio_attr[i]);
@@ -620,7 +644,7 @@
}
=20
printf("VTS Number of Subpicture attributes: %i\n",=20
- vtsi_mat->nr_of_vts_subp_streams);
+ vtsi_mat->nr_of_vts_subp_streams);
for(i =3D 0; i < vtsi_mat->nr_of_vts_subp_streams; i++) {
printf("\tstream %2i status: ", i);
ifoPrint_subp_attributes(&vtsi_mat->vts_subp_attr[i]);
@@ -641,17 +665,17 @@
=20
printf("Number of Pre commands: %i\n", cmd_tbl->nr_of_pre);
for(i =3D 0; i < cmd_tbl->nr_of_pre; i++) {
- ifoPrint_CMD(i, &cmd_tbl->pre_cmds[i]);
+ cmdPrint_CMD(i, &cmd_tbl->pre_cmds[i]);
}
=20
printf("Number of Post commands: %i\n", cmd_tbl->nr_of_post);
for(i =3D 0; i < cmd_tbl->nr_of_post; i++) {
- ifoPrint_CMD(i, &cmd_tbl->post_cmds[i]);
+ cmdPrint_CMD(i, &cmd_tbl->post_cmds[i]);
}
=20
printf("Number of Cell commands: %i\n", cmd_tbl->nr_of_cell);
for(i =3D 0; i < cmd_tbl->nr_of_cell; i++) {
- ifoPrint_CMD(i, &cmd_tbl->cell_cmds[i]);
+ cmdPrint_CMD(i, &cmd_tbl->cell_cmds[i]);
}
}
=20
@@ -688,28 +712,28 @@
const char *s;
switch(cell_playback[i].block_mode) {
case 0:
- s =3D "not a"; break;
+ s =3D "not a"; break;
case 1:
- s =3D "the first"; break;
+ s =3D "the first"; break;
case 2:
default:
- s =3D ""; break;
+ s =3D ""; break;
case 3:
- s =3D "last"; break;
+ s =3D "last"; break;
}
printf("%s cell in the block ", s);
=20
switch(cell_playback[i].block_type) {
case 0:
- printf("not part of the block ");
- break;
+ printf("not part of the block ");
+ break;
case 1:
- printf("angle block ");
- break;
+ printf("angle block ");
+ break;
case 2:
case 3:
- printf("(send bug repport) ");
- break;
+ printf("(send bug repport) ");
+ break;
}
}
if(cell_playback[i].seamless_play)
@@ -729,11 +753,11 @@
printf("cell command %d", cell_playback[i].cell_cmd_nr);
=20
printf("\n\tStart sector: %08x\tFirst ILVU end sector: %08x\n",=20
- cell_playback[i].first_sector,=20
- cell_playback[i].first_ilvu_end_sector);
+ cell_playback[i].first_sector,=20
+ cell_playback[i].first_ilvu_end_sector);
printf("\tEnd sector: %08x\tLast VOBU start sector: %08x\n",=20
- cell_playback[i].last_sector,=20
- cell_playback[i].last_vobu_start_sector);
+ cell_playback[i].last_sector,=20
+ cell_playback[i].last_vobu_start_sector);
}
}
=20
@@ -747,7 +771,7 @@
=20
for(i=3D0;i<nr;i++) {
printf("Cell: %3i has VOB ID: %3i, Cell ID: %3i\n", i + 1,=20
- cell_position[i].vob_id_nr, cell_position[i].cell_nr);
+ cell_position[i].vob_id_nr, cell_position[i].cell_nr);
}
}
=20
@@ -755,6 +779,11 @@
void ifoPrint_PGC(pgc_t *pgc) {
int i;
=20
+ if(pgc =3D=3D NULL) {
+ printf("Error: No PGC present\n");
+ return;
+ }
+
printf("Number of Programs: %i\n", pgc->nr_of_programs);
printf("Number of Cells: %i\n", pgc->nr_of_cells);
/* Check that time is 0:0:0:0 also if nr_of_programs=3D=3D0 */
@@ -765,17 +794,17 @@
printf("Prohibited user operations: ");
ifoPrint_USER_OPS(&pgc->prohibited_ops);
=20
- for(i =3D 0; i < 8; i++) {
- if(pgc->audio_control[i] & 0x8000) { /* The 'is present' bit */
- printf("Audio stream %i control: %04x\n",=20
- i, pgc->audio_control[i]);
- }
+ for(i =3D 0; i < 8; i++) {
+ if(pgc->audio_control[i] & 0x8000) { /* The 'is present' bit */
+ printf("Audio stream %i control: %04x\n",=20
+ i, pgc->audio_control[i]);
}
+ }
=20
for(i =3D 0; i < 32; i++) {
if(pgc->subp_control[i] & 0x80000000) { /* The 'is present' bit */
printf("Subpicture stream %2i control: %08x\n",=20
- i, pgc->subp_control[i]);
+ i, pgc->subp_control[i]);
}
}
=20
@@ -810,36 +839,36 @@
int i;
=20
printf("Number of TitleTrack search pointers: %i\n",
- tt_srpt->nr_of_srpts);
+ tt_srpt->nr_of_srpts);
for(i=3D0;i<tt_srpt->nr_of_srpts;i++) {
printf("Title Track index %i\n", i + 1);
printf("\tTitle set number (VTS): %i",=20
- tt_srpt->title[i].title_set_nr);
+ tt_srpt->title[i].title_set_nr);
printf("\tVTS_TTN: %i\n", tt_srpt->title[i].vts_ttn);
printf("\tNumber of PTTs: %i\n", tt_srpt->title[i].nr_of_ptts);
printf("\tNumber of angles: %i\n",=20
- tt_srpt->title[i].nr_of_angles);
+ tt_srpt->title[i].nr_of_angles);
printf("\tTitle playback type: %s%s%s%s%s%s%s\n",
- tt_srpt->title[i].pb_ty.multi_or_random_pgc_title ?=20
- " One Random PGC Title or Multi PGC Title" :=20
- " One Sequential PGC Title",
- tt_srpt->title[i].pb_ty.jlc_exists_in_cell_cmd ?
- "" : ", No Link/Jump/Call exists in Cell command",
- tt_srpt->title[i].pb_ty.jlc_exists_in_prepost_cmd ?
- "" : ", No Link/Jump/Call exists in Pre- and/or Post-command",
- tt_srpt->title[i].pb_ty.jlc_exists_in_button_cmd ?
- "" : ", No Link/Jump/Call exists in Button command",
- tt_srpt->title[i].pb_ty.jlc_exists_in_tt_dom ?
- "" : ", No Link/Jump/Call exists in TT_DOM",
- tt_srpt->title[i].pb_ty.chapter_search_or_play ?
- ", UOP1 (TT_Play and PTT_Search) prohibited" : "",
- tt_srpt->title[i].pb_ty.title_or_time_play ?
- ", UOP0 (Time_Play and Time_Search) prohibited" : ""
- ); =20
+ tt_srpt->title[i].pb_ty.multi_or_random_pgc_title ?=20
+ " One Random PGC Title or Multi PGC Title" :=20
+ " One Sequential PGC Title",
+ tt_srpt->title[i].pb_ty.jlc_exists_in_cell_cmd ?
+ "" : ", No Link/Jump/Call exists in Cell command",
+ tt_srpt->title[i].pb_ty.jlc_exists_in_prepost_cmd ?
+ "" : ", No Link/Jump/Call exists in Pre- and/or Post-command"=
,
+ tt_srpt->title[i].pb_ty.jlc_exists_in_button_cmd ?
+ "" : ", No Link/Jump/Call exists in Button command",
+ tt_srpt->title[i].pb_ty.jlc_exists_in_tt_dom ?
+ "" : ", No Link/Jump/Call exists in TT_DOM",
+ tt_srpt->title[i].pb_ty.chapter_search_or_play ?
+ ", UOP1 (TT_Play and PTT_Search) prohibited" : "",
+ tt_srpt->title[i].pb_ty.title_or_time_play ?
+ ", UOP0 (Time_Play and Time_Search) prohibited" : ""
+ ); =20
printf("\tParental ID field: %04x\n",
- tt_srpt->title[i].parental_id);
+ tt_srpt->title[i].parental_id);
printf("\tTitle set starting sector %08x\n",=20
- tt_srpt->title[i].title_set_sector);
+ tt_srpt->title[i].title_set_sector);
}
}
=20
@@ -847,16 +876,16 @@
void ifoPrint_VTS_PTT_SRPT(vts_ptt_srpt_t *vts_ptt_srpt) {
int i, j;
printf(" nr_of_srpts %i last byte %i\n",=20
- vts_ptt_srpt->nr_of_srpts,=20
- vts_ptt_srpt->last_byte);
+ vts_ptt_srpt->nr_of_srpts,=20
+ vts_ptt_srpt->last_byte);
for(i=3D0;i<vts_ptt_srpt->nr_of_srpts;i++) {
printf("\nVTS_PTT number %d has a offset %d relative to VTS_PTT_SRPT=
\n",=20
- i + 1, vts_ptt_srpt->ttu_offset[i]);
+ i + 1, vts_ptt_srpt->ttu_offset[i]);
for(j=3D0;j<vts_ptt_srpt->title[i].nr_of_ptts;j++) {
printf("VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i\n",
- i + 1, j + 1,=20
- vts_ptt_srpt->title[i].ptt[j].pgcn,
- vts_ptt_srpt->title[i].ptt[j].pgn );
+ i + 1, j + 1,=20
+ vts_ptt_srpt->title[i].ptt[j].pgcn,
+ vts_ptt_srpt->title[i].ptt[j].pgn );
}
}
}
@@ -873,18 +902,18 @@
=20
printf("Start byte: %i\n", ptl_mait->countries[i].pf_ptl_mai_start_b=
yte);
printf("Parental Masks for country: %c%c\n",
- ptl_mait->countries[i].country_code >> 8,
- ptl_mait->countries[i].country_code & 0xff);
+ ptl_mait->countries[i].country_code >> 8,
+ ptl_mait->countries[i].country_code & 0xff);
=20
for(vts =3D 0; vts <=3D ptl_mait->nr_of_vtss; vts++) {
if( vts =3D=3D 0 ) {
- printf("VMG ");=20
+ printf("VMG ");=20
} else {
- printf("VTS %2d ", vts);
+ printf("VTS %2d ", vts);
}
for(level =3D 0; level < 8; level++) {
- printf("%d: %04x ", level,
- ptl_mait->countries[i].pf_ptl_mai[vts][level] );
+ printf("%d: %04x ", level,
+ ptl_mait->countries[i].pf_ptl_mai[vts][level] );
}
printf("\n");
}
@@ -907,9 +936,9 @@
for(j =3D 0; j < vts_tmapt->tmap[i].nr_of_entries; j++) {
unsigned int ac_time =3D timeunit * (j + 1);
printf("Time: %2i:%02i:%02i VOBU Sector: 0x%08x %s\n",=20
- ac_time / (60 * 60), (ac_time / 60) % 60, ac_time % 60,
- vts_tmapt->tmap[i].map_ent[j] & 0x7fffffff,
- (vts_tmapt->tmap[i].map_ent[j] >> 31) ? "discontinuity" : "");
+ ac_time / (60 * 60), (ac_time / 60) % 60, ac_time % 60,
+ vts_tmapt->tmap[i].map_ent[j] & 0x7fffffff,
+ (vts_tmapt->tmap[i].map_ent[j] >> 31) ? "discontinuity" : "=
");
}
}
}
@@ -919,14 +948,14 @@
=20
printf("Number of VOBs in this VOBS: %i\n", c_adt->nr_of_vobs);
//entries =3D c_adt->nr_of_vobs;
- entries =3D (c_adt->last_byte + 1 - C_ADT_SIZE)/sizeof(c_adt_t);
+ entries =3D (c_adt->last_byte + 1 - C_ADT_SIZE)/sizeof(cell_adr_t);
=20
for(i =3D 0; i < entries; i++) {
printf("VOB ID: %3i, Cell ID: %3i ",=20
- c_adt->cell_adr_table[i].vob_id, c_adt->cell_adr_table[i].cell_id);
+ c_adt->cell_adr_table[i].vob_id, c_adt->cell_adr_table[i].cel=
l_id);
printf("Sector (first): 0x%08x (last): 0x%08x\n",
- c_adt->cell_adr_table[i].start_sector,=20
- c_adt->cell_adr_table[i].last_sector);
+ c_adt->cell_adr_table[i].start_sector,=20
+ c_adt->cell_adr_table[i].last_sector);
}
}
=20
@@ -937,7 +966,7 @@
entries =3D (vobu_admap->last_byte + 1 - VOBU_ADMAP_SIZE)/4;
for(i =3D 0; i < entries; i++) {
printf("VOBU %5i First sector: 0x%08x\n", i + 1,
- vobu_admap->vobu_start_sectors[i]);
+ vobu_admap->vobu_start_sectors[i]);
}
}
=20
@@ -960,9 +989,9 @@
printf("Number of Menu Language Units (PGCI_LU): %3i\n", pgci_ut->nr_o=
f_lus);
for(i =3D 0; i < pgci_ut->nr_of_lus; i++) {
printf("\nMenu Language Code: %c%c (%c)\n",
- pgci_ut->lu[i].lang_code >> 8,
- pgci_ut->lu[i].lang_code & 0xff,
- pgci_ut->lu[i].lang_extension ? pgci_ut->lu[i].lang_extension :' ');
+ pgci_ut->lu[i].lang_code >> 8,
+ pgci_ut->lu[i].lang_code & 0xff,
+ pgci_ut->lu[i].lang_extension ? pgci_ut->lu[i].lang_extension=
:' ');
printf("Menu Existence: %02x\n", pgci_ut->lu[i].exists);
ifoPrint_PGCIT(pgci_ut->lu[i].pgcit);
}
@@ -978,14 +1007,14 @@
ifoPrint_video_attributes(&vts_attributes->vtsm_vobs_attr);
printf("\n");
printf("Number of Audio streams: %i\n",=20
- vts_attributes->nr_of_vtsm_audio_streams);
+ vts_attributes->nr_of_vtsm_audio_streams);
if(vts_attributes->nr_of_vtsm_audio_streams > 0) {
printf("\tstream %i attributes: ", 1);
ifoPrint_audio_attributes(&vts_attributes->vtsm_audio_attr);
printf("\n");
}
printf("Number of Subpicture streams: %i\n",=20
- vts_attributes->nr_of_vtsm_subp_streams);
+ vts_attributes->nr_of_vtsm_subp_streams);
if(vts_attributes->nr_of_vtsm_subp_streams > 0) {
printf("\tstream %2i attributes: ", 1);
ifoPrint_subp_attributes(&vts_attributes->vtsm_subp_attr);
@@ -996,7 +1025,7 @@
ifoPrint_video_attributes(&vts_attributes->vtstt_vobs_video_attr);
printf("\n");
printf("Number of Audio streams: %i\n",=20
- vts_attributes->nr_of_vtstt_audio_streams);
+ vts_attributes->nr_of_vtstt_audio_streams);
for(i =3D 0; i < vts_attributes->nr_of_vtstt_audio_streams; i++) {
printf("\tstream %i attributes: ", i);
ifoPrint_audio_attributes(&vts_attributes->vtstt_audio_attr[i]);
@@ -1004,7 +1033,7 @@
}
=20
printf("Number of Subpicture streams: %i\n",=20
- vts_attributes->nr_of_vtstt_subp_streams);
+ vts_attributes->nr_of_vtstt_subp_streams);
for(i =3D 0; i < vts_attributes->nr_of_vtstt_subp_streams; i++) {
printf("\tstream %2i attributes: ", i); =20
ifoPrint_subp_attributes(&vts_attributes->vtstt_subp_attr[i]);
@@ -1020,7 +1049,7 @@
for(i =3D 0; i < vts_atrt->nr_of_vtss; i++) {
printf("\nVideo Title Set %i\n", i + 1);
printf(" offset %d relative to VMG_VTS_ATRT\n",=20
- vts_atrt->vts_atrt_offsets[i]);
+ vts_atrt->vts_atrt_offsets[i]);
ifoPrint_VTS_ATTRIBUTES(&vts_atrt->vts[i]);
}
}
@@ -1031,7 +1060,9 @@
=20
ifohandle =3D ifoOpen(dvd, title);
if(!ifohandle) {
- LOG_ERROR( stderr, "Can't open info file for title %d\n", title );
+ if(dvdread_verbose(dvd) >=3D 0) {
+ fprintf(stderr, "Can't open info file for title %d\n", title);
+ }
return;
}
=20
@@ -1042,7 +1073,11 @@
ifoPrint_VMGI_MAT(ifohandle->vmgi_mat);
=20
printf("\nFirst Play PGC\n--------------\n");
- ifoPrint_PGC(ifohandle->first_play_pgc);
+ if(ifohandle->first_play_pgc) {
+ ifoPrint_PGC(ifohandle->first_play_pgc);
+ } else {
+ printf("No First Play PGC present\n");
+ }
=20
printf("\nTitle Track search pointer table\n");
printf( "------------------------------------------------\n");
Modified: trunk/DvdMenuXtractor/libdvdread/dvdread/ifo_read.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/dvdread/ifo_read.c 2007-01-22 11:21:=
16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/dvdread/ifo_read.c 2007-01-28 16:48:=
11 UTC (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2000, 2001, 2002, 2003
* Bj=F6rn Englund <d4bjorn at dtek.chalmers.se>,=20
@@ -22,8 +23,15 @@
=20
#include <stdio.h>
#include <stdlib.h>
+
+#if defined(HAVE_INTTYPES_H)
#include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
+
#include <string.h>
+#include <errno.h>
=20
#include "bswap.h"
#include "ifo_types.h"
@@ -36,19 +44,19 @@
#endif
=20
#ifndef NDEBUG
-#define CHECK_ZERO0(arg) \
- if(arg !=3D 0) { \
- LOG_ERROR( stderr, "*** Zero check failed in %s:%i\n for %s =3D 0=
x%x\n", \
- __FILE__, __LINE__, # arg, arg); \
+#define CHECK_ZERO0(arg) =
\
+ if(arg !=3D 0) { =
\
+ fprintf(stderr, "*** Zero check failed in %s:%i\n for %s =3D 0x%x=
\n", \
+ __FILE__, __LINE__, # arg, arg); =
\
}
-#define CHECK_ZERO(arg) \
- if(memcmp(my_friendly_zeros, &arg, sizeof(arg))) { \
- unsigned int i_CZ; \
- LOG_ERROR( stderr, "*** Zero check failed in %s:%i\n for %s =3D 0=
x", \
- __FILE__, __LINE__, # arg ); \
- for(i_CZ =3D 0; i_CZ < sizeof(arg); i_CZ++) \
- LOG_ERROR( stderr, "%02x", *((uint8_t *)&arg + i_CZ)); \
- LOG_ERROR( stderr, "\n"); \
+#define CHECK_ZERO(arg) =
\
+ if(memcmp(my_friendly_zeros, &arg, sizeof(arg))) { =
\
+ unsigned int i_CZ; =
\
+ fprintf(stderr, "*** Zero check failed in %s:%i\n for %s =3D 0x",=
\
+ __FILE__, __LINE__, # arg ); =
\
+ for(i_CZ =3D 0; i_CZ < sizeof(arg); i_CZ++) =
\
+ fprintf(stderr, "%02x", *((uint8_t *)&arg + i_CZ)); =
\
+ fprintf(stderr, "\n"); =
\
}
static const uint8_t my_friendly_zeros[2048];
#else
@@ -63,7 +71,7 @@
static int ifoRead_PGC(ifo_handle_t *ifofile, pgc_t *pgc, unsigned int o=
ffset);
static int ifoRead_PGC_COMMAND_TBL(ifo_handle_t *ifofile,=20
pgc_command_tbl_t *cmd_tbl,=20
- unsigned int offset);
+ unsigned int offset);
static int ifoRead_PGC_PROGRAM_MAP(ifo_handle_t *ifofile,=20
pgc_program_map_t *program_map,=20
unsigned int nr, unsigned int offset)=
;
@@ -80,7 +88,7 @@
unsigned int sector);
static int ifoRead_VOBU_ADMAP_internal(ifo_handle_t *ifofile,=20
vobu_admap_t *vobu_admap,=20
- unsigned int sector);
+ unsigned int sector);
static int ifoRead_PGCIT_internal(ifo_handle_t *ifofile, pgcit_t *pgcit,=
=20
unsigned int offset);
=20
@@ -88,6 +96,11 @@
static void ifoFree_PGC_COMMAND_TBL(pgc_command_tbl_t *cmd_tbl);
static void ifoFree_PGCIT_internal(pgcit_t *pgcit);
=20
+static ifo_handle_t *ifoOpen_File(ifo_handle_t *ifofile, int title,=20
+ char *suffix);
+static ifo_handle_t *ifoOpenVMGI_File(ifo_handle_t *ifofile, char *suffi=
x);
+static ifo_handle_t *ifoOpenVTSI_File(ifo_handle_t *ifofile, int title,
+ char *suffix);
=20
static inline int DVDFileSeek_( dvd_file_t *dvd_file, uint32_t offset ) =
{
return (DVDFileSeek(dvd_file, (int)offset) =3D=3D (int)offset);
@@ -99,21 +112,52 @@
=20
ifofile =3D (ifo_handle_t *)malloc(sizeof(ifo_handle_t));
if(!ifofile)
- return 0;
+ return NULL;
=20
memset(ifofile, 0, sizeof(ifo_handle_t));
=20
ifofile->file =3D DVDOpenFile(dvd, title, DVD_READ_INFO_FILE);
- if(!ifofile->file) /* Should really catch any error and try to fallbac=
k */
- ifofile->file =3D DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE)=
;
- if(!ifofile->file) {
+ if(!ifoOpen_File(ifofile, title, "IFO")) {
if(title) {
- LOG_ERROR( stderr, "libdvdread: Can't open file VTS_%02d_0.IFO.\n"=
, title);
+ if(dvdread_verbose(dvd) >=3D 1) {
+ fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.%s.\n",=20
+ title, "IFO");
+ }
} else {
- LOG_ERROR( stderr, "libdvdread: Can't open file VIDEO_TS.IFO.\n");
+ if(dvdread_verbose(dvd) >=3D 1) {
+ fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.%s.\n", "I=
FO");
+ }
}
+ /* lower functions free the pointer, reallocate */
+ ifofile =3D (ifo_handle_t *)malloc(sizeof(ifo_handle_t));
+ if(!ifofile)
+ return NULL;
+
+ memset(ifofile, 0, sizeof(ifo_handle_t));
+
+ ifofile->file =3D DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE)=
;
+ if(!ifoOpen_File(ifofile, title, "BUP")) {
+ if(title) {
+ if(dvdread_verbose(dvd) >=3D 1) {
+ fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.%s.\n"=
,=20
+ title, "BUP");
+ }
+ } else {
+ if(dvdread_verbose(dvd) >=3D 1) {
+ fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.%s.\n", =
"BUP");
+ }
+ }
+ return NULL;
+ }
+ }
+ return ifofile;
+}
+
+static ifo_handle_t *ifoOpen_File(ifo_handle_t *ifofile, int title,=20
+ char *suffix) {
+ if(!ifofile->file) {
free(ifofile);
- return 0;
+ return NULL;
}
=20
/* First check if this is a VMGI file. */
@@ -121,9 +165,12 @@
=20
/* These are both mandatory. */
if(!ifoRead_FP_PGC(ifofile) || !ifoRead_TT_SRPT(ifofile)) {
- LOG_ERROR( stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.IF=
O).\n");
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 0) {
+ fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.%s)=
.\n",
+ suffix);
+ }
ifoClose(ifofile);
- return 0;
+ return NULL;
}
=20
ifoRead_PGCI_UT(ifofile);
@@ -131,9 +178,12 @@
=20
/* This is also mandatory. */
if(!ifoRead_VTS_ATRT(ifofile)) {
- LOG_ERROR( stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.IF=
O).\n");
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 0) {
+ fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.%s)=
.\n",
+ suffix);
+ }
ifoClose(ifofile);
- return 0;
+ return NULL;
}
=20
ifoRead_TXTDT_MGI(ifofile);
@@ -146,36 +196,44 @@
if(ifoRead_VTS(ifofile)) {
=20
if(!ifoRead_VTS_PTT_SRPT(ifofile) || !ifoRead_PGCIT(ifofile)) {
- LOG_ERROR( stderr, "libdvdread: Invalid title IFO (VTS_%02d_0.IFO)=
.\n",
- title);
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 0) {
+ fprintf(stderr, "libdvdread: Invalid title IFO (VTS_%02d_0.%s).\=
n",
+ title, suffix);
+ }
ifoClose(ifofile);
- return 0;
+ return NULL;
}
=20
-
ifoRead_PGCI_UT(ifofile);
ifoRead_VTS_TMAPT(ifofile);
ifoRead_C_ADT(ifofile);
ifoRead_VOBU_ADMAP(ifofile);
=20
if(!ifoRead_TITLE_C_ADT(ifofile) || !ifoRead_TITLE_VOBU_ADMAP(ifofil=
e)) {
- LOG_ERROR( stderr, "libdvdread: Invalid title IFO (VTS_%02d_0.IFO)=
.\n",
- title);
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 0) {
+ fprintf(stderr, "libdvdread: Invalid title IFO (VTS_%02d_0.%s).\=
n",
+ title, suffix);
+ }
ifoClose(ifofile);
- return 0;
+ return NULL;
}
=20
return ifofile;
}
=20
if(title) {
- LOG_ERROR( stderr, "libdvdread: Invalid IFO for title %d (VTS_%02d_0=
.IFO).\n",
- title, title);
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 0) {
+ fprintf(stderr, "libdvdread: Invalid IFO for title %d (VTS_%02d_0.=
%s).\n",
+ title, title, suffix);
+ }
} else {
- LOG_ERROR( stderr, "libdvdread: Invalid IFO for VMGM (VIDEO_TS.IFO).=
\n");
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 0) {
+ fprintf(stderr, "libdvdread: Invalid IFO for VMGM (VIDEO_TS.%s).\n=
",=20
+ suffix);
+ }
}
ifoClose(ifofile);
- return 0;
+ return NULL;
}
=20
=20
@@ -184,25 +242,50 @@
=20
ifofile =3D (ifo_handle_t *)malloc(sizeof(ifo_handle_t));
if(!ifofile)
- return 0;
+ return NULL;
=20
memset(ifofile, 0, sizeof(ifo_handle_t));
=20
ifofile->file =3D DVDOpenFile(dvd, 0, DVD_READ_INFO_FILE);
- if(!ifofile->file) /* Should really catch any error and try to fallbac=
k */
+ if(!ifoOpenVMGI_File(ifofile, "IFO")) {
+ if(dvdread_verbose(dvd) >=3D 1) {
+ fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.IFO: %s\n",
+ strerror(errno));
+ }
+
+ /* lower functions free the pointer, reallocate */
+ ifofile =3D (ifo_handle_t *)malloc(sizeof(ifo_handle_t));
+ if(!ifofile)
+ return NULL;
+
+ memset(ifofile, 0, sizeof(ifo_handle_t));
+
ifofile->file =3D DVDOpenFile(dvd, 0, DVD_READ_INFO_BACKUP_FILE);
+ if(!ifoOpenVMGI_File(ifofile, "BUP"))
+ if(dvdread_verbose(dvd) >=3D 1) {
+ fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.BUP: %s\n"=
,
+ strerror(errno));
+ }
+ return NULL;
+ }
+ return ifofile;
+}
+
+static ifo_handle_t *ifoOpenVMGI_File(ifo_handle_t *ifofile, char *suffi=
x) {
if(!ifofile->file) {
- LOG_ERROR( stderr, "libdvdread: Can't open file VIDEO_TS.IFO.\n");
free(ifofile);
- return 0;
+ return NULL;
}
=20
if(ifoRead_VMG(ifofile))
return ifofile;
=20
- LOG_ERROR( stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.IFO).\=
n");
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 0) {
+ fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.%s).\n"=
,=20
+ suffix);
+ }
ifoClose(ifofile);
- return 0;
+ return NULL;
}
=20
=20
@@ -211,33 +294,57 @@
=20
ifofile =3D (ifo_handle_t *)malloc(sizeof(ifo_handle_t));
if(!ifofile)
- return 0;
+ return NULL;
=20
memset(ifofile, 0, sizeof(ifo_handle_t));
=20
if(title <=3D 0 || title > 99) {
- LOG_ERROR( stderr, "libdvdread: ifoOpenVTSI invalid title (%d).\n", =
title);
+ if(dvdread_verbose(dvd) >=3D 0) {
+ fprintf(stderr, "libdvdread: ifoOpenVTSI invalid title (%d).\n", t=
itle);
+ }
free(ifofile);
- return 0;
+ errno =3D EINVAL;
+ return NULL;
}
=20
ifofile->file =3D DVDOpenFile(dvd, title, DVD_READ_INFO_FILE);
- if(!ifofile->file) /* Should really catch any error and try to fallbac=
k */
+ if(!ifoOpenVTSI_File(ifofile, title, "IFO")) {
+ if(dvdread_verbose(dvd) >=3D 1) {
+ fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.%s.\n", ti=
tle, "IFO");
+ }
+ /* lower functions free the pointer, reallocate */
+ ifofile =3D (ifo_handle_t *)malloc(sizeof(ifo_handle_t));
+ if(!ifofile)
+ return NULL;
+
+ memset(ifofile, 0, sizeof(ifo_handle_t));
+
ifofile->file =3D DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE)=
;
+ if(!ifoOpenVTSI_File(ifofile, title, "BUP"))
+ if(dvdread_verbose(dvd) >=3D 1) {
+ fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.%s.\n", =
title, "BUP");
+ }
+ return NULL;
+ }
+ return ifofile;
+}
+
+static ifo_handle_t *ifoOpenVTSI_File(ifo_handle_t* ifofile, int title, =
char *suffix) {
if(!ifofile->file) {
- LOG_ERROR( stderr, "libdvdread: Can't open file VTS_%02d_0.IFO.\n", =
title);
free(ifofile);
- return 0;
+ return NULL;
}
=20
ifoRead_VTS(ifofile);
if(ifofile->vtsi_mat)
return ifofile;
=20
- LOG_ERROR( stderr, "libdvdread: Invalid IFO for title %d (VTS_%02d_0.I=
FO).\n",
- title, title);
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 0) {
+ fprintf(stderr, "libdvdread: Invalid IFO for title %d (VTS_%02d_0.%s=
).\n",
+ title, title, suffix);
+ }
ifoClose(ifofile);
- return 0;
+ return NULL;
}
=20
=20
@@ -341,12 +448,12 @@
CHECK_VALUE(vmgi_mat->vmg_nr_of_title_sets !=3D 0);
CHECK_VALUE(vmgi_mat->vmgi_last_byte >=3D 341);
CHECK_VALUE(vmgi_mat->vmgi_last_byte / DVD_BLOCK_LEN <=3D=20
- vmgi_mat->vmgi_last_sector);
+ vmgi_mat->vmgi_last_sector);
/* It seems that first_play_pgc is optional. */
CHECK_VALUE(vmgi_mat->first_play_pgc < vmgi_mat->vmgi_last_byte);
CHECK_VALUE(vmgi_mat->vmgm_vobs =3D=3D 0 ||=20
- (vmgi_mat->vmgm_vobs > vmgi_mat->vmgi_last_sector &&
- vmgi_mat->vmgm_vobs < vmgi_mat->vmg_last_sector));
+ (vmgi_mat->vmgm_vobs > vmgi_mat->vmgi_last_sector &&
+ vmgi_mat->vmgm_vobs < vmgi_mat->vmg_last_sector));
CHECK_VALUE(vmgi_mat->tt_srpt <=3D vmgi_mat->vmgi_last_sector);
CHECK_VALUE(vmgi_mat->vmgm_pgci_ut <=3D vmgi_mat->vmgi_last_sector);
CHECK_VALUE(vmgi_mat->ptl_mait <=3D vmgi_mat->vmgi_last_sector);
@@ -436,11 +543,11 @@
CHECK_VALUE(vtsi_mat->vtsi_last_sector*2 <=3D vtsi_mat->vts_last_secto=
r);
CHECK_VALUE(vtsi_mat->vtsi_last_byte/DVD_BLOCK_LEN <=3D vtsi_mat->vtsi=
_last_sector);
CHECK_VALUE(vtsi_mat->vtsm_vobs =3D=3D 0 ||=20
- (vtsi_mat->vtsm_vobs > vtsi_mat->vtsi_last_sector &&
- vtsi_mat->vtsm_vobs < vtsi_mat->vts_last_sector));
+ (vtsi_mat->vtsm_vobs > vtsi_mat->vtsi_last_sector &&
+ vtsi_mat->vtsm_vobs < vtsi_mat->vts_last_sector));
CHECK_VALUE(vtsi_mat->vtstt_vobs =3D=3D 0 ||=20
- (vtsi_mat->vtstt_vobs > vtsi_mat->vtsi_last_sector &&
- vtsi_mat->vtstt_vobs < vtsi_mat->vts_last_sector));
+ (vtsi_mat->vtstt_vobs > vtsi_mat->vtsi_last_sector &&
+ vtsi_mat->vtstt_vobs < vtsi_mat->vts_last_sector));
CHECK_VALUE(vtsi_mat->vts_ptt_srpt <=3D vtsi_mat->vtsi_last_sector);
CHECK_VALUE(vtsi_mat->vts_pgcit <=3D vtsi_mat->vtsi_last_sector);
CHECK_VALUE(vtsi_mat->vtsm_pgci_ut <=3D vtsi_mat->vtsi_last_sector);
@@ -476,10 +583,11 @@
=20
static int ifoRead_PGC_COMMAND_TBL(ifo_handle_t *ifofile,=20
pgc_command_tbl_t *cmd_tbl,=20
- unsigned int offset) {
- =20
+ unsigned int offset) {
+ unsigned int total;
+
memset(cmd_tbl, 0, sizeof(pgc_command_tbl_t));
- =20
+
if(!DVDFileSeek_(ifofile->file, offset))
return 0;
=20
@@ -489,9 +597,13 @@
B2N_16(cmd_tbl->nr_of_pre);
B2N_16(cmd_tbl->nr_of_post);
B2N_16(cmd_tbl->nr_of_cell);
+ B2N_16(cmd_tbl->last_byte);
+ =20
+ total =3D cmd_tbl->nr_of_pre + cmd_tbl->nr_of_post + cmd_tbl->nr_of_ce=
ll;
+ CHECK_VALUE(PGC_COMMAND_TBL_SIZE + total * COMMAND_DATA_SIZE=20
+ <=3D cmd_tbl->last_byte + 1U);
+ CHECK_VALUE(total <=3D 255);
=20
- CHECK_VALUE(cmd_tbl->nr_of_pre + cmd_tbl->nr_of_post + cmd_tbl->nr_of_=
cell<=3D 255);
- =20
if(cmd_tbl->nr_of_pre !=3D 0) {
unsigned int pre_cmds_size =3D cmd_tbl->nr_of_pre * COMMAND_DATA_SI=
ZE;
cmd_tbl->pre_cmds =3D (vm_cmd_t *)malloc(pre_cmds_size);
@@ -503,18 +615,18 @@
return 0;
}
}
- =20
+
if(cmd_tbl->nr_of_post !=3D 0) {
unsigned int post_cmds_size =3D cmd_tbl->nr_of_post * COMMAND_DATA_S=
IZE;
cmd_tbl->post_cmds =3D (vm_cmd_t *)malloc(post_cmds_size);
if(!cmd_tbl->post_cmds) {
if(cmd_tbl->pre_cmds)=20
- free(cmd_tbl->pre_cmds);
+ free(cmd_tbl->pre_cmds);
return 0;
}
if(!(DVDReadBytes(ifofile->file, cmd_tbl->post_cmds, post_cmds_size)=
)) {
if(cmd_tbl->pre_cmds)=20
- free(cmd_tbl->pre_cmds);
+ free(cmd_tbl->pre_cmds);
free(cmd_tbl->post_cmds);
return 0;
}
@@ -525,16 +637,16 @@
cmd_tbl->cell_cmds =3D (vm_cmd_t *)malloc(cell_cmds_size);
if(!cmd_tbl->cell_cmds) {
if(cmd_tbl->pre_cmds)
- free(cmd_tbl->pre_cmds);
+ free(cmd_tbl->pre_cmds);
if(cmd_tbl->post_cmds)
- free(cmd_tbl->post_cmds);
+ free(cmd_tbl->post_cmds);
return 0;
}
if(!(DVDReadBytes(ifofile->file, cmd_tbl->cell_cmds, cell_cmds_size)=
)) {
if(cmd_tbl->pre_cmds)=20
- free(cmd_tbl->pre_cmds);
+ free(cmd_tbl->pre_cmds);
if(cmd_tbl->post_cmds)=20
- free(cmd_tbl->post_cmds);
+ free(cmd_tbl->post_cmds);
free(cmd_tbl->cell_cmds);
return 0;
}
@@ -561,7 +673,7 @@
=20
static int ifoRead_PGC_PROGRAM_MAP(ifo_handle_t *ifofile,=20
pgc_program_map_t *program_map,=20
- unsigned int nr, unsigned int offset) {
+ unsigned int nr, unsigned int offset)=
{
unsigned int size =3D nr * sizeof(pgc_program_map_t);
=20
if(!DVDFileSeek_(ifofile->file, offset))
@@ -593,9 +705,9 @@
=20
/* Changed < to <=3D because this was false in the movie 'Pi'. */
CHECK_VALUE(cell_playback[i].last_vobu_start_sector <=3D=20
- cell_playback[i].last_sector);
+ cell_playback[i].last_sector);
CHECK_VALUE(cell_playback[i].first_sector <=3D=20
- cell_playback[i].last_vobu_start_sector);
+ cell_playback[i].last_vobu_start_sector);
}
=20
return 1;
@@ -685,6 +797,8 @@
}
=20
if(pgc->program_map_offset !=3D 0) {
+ if(pgc->nr_of_programs !=3D 0) {
+
pgc->program_map =3D malloc(pgc->nr_of_programs * sizeof(pgc_program=
_map_t));
if(!pgc->program_map) {
ifoFree_PGC_COMMAND_TBL(pgc->command_tbl);
@@ -696,43 +810,56 @@
free(pgc->program_map);
return 0;
}
+ } else {
+ pgc->program_map =3D NULL;
+ }
} else {
pgc->program_map =3D NULL;
}
=20
if(pgc->cell_playback_offset !=3D 0) {
+ if(pgc->nr_of_cells !=3D 0) {
+
pgc->cell_playback =3D malloc(pgc->nr_of_cells * sizeof(cell_playbac=
k_t));
if(!pgc->cell_playback) {
ifoFree_PGC_COMMAND_TBL(pgc->command_tbl);
if(pgc->program_map)
- free(pgc->program_map);
+ free(pgc->program_map);
return 0;
}
if(!ifoRead_CELL_PLAYBACK_TBL(ifofile, pgc->cell_playback,=20
- pgc->nr_of_cells,
+ pgc->nr_of_cells,
offset + pgc->cell_playback_offset)) {
ifoFree_PGC_COMMAND_TBL(pgc->command_tbl);
if(pgc->program_map)
- free(pgc->program_map);
+ free(pgc->program_map);
free(pgc->cell_playback);
return 0;
}
+ } else {
+ pgc->cell_playback =3D NULL;
+ }
} else {
pgc->cell_playback =3D NULL;
}
=20
if(pgc->cell_position_offset !=3D 0) {
+ if(pgc->nr_of_cells !=3D 0) {
+
pgc->cell_position =3D malloc(pgc->nr_of_cells * sizeof(cell_positio=
n_t));
if(!pgc->cell_position) {
ifoFree_PGC(pgc);
return 0;
}
if(!ifoRead_CELL_POSITION_TBL(ifofile, pgc->cell_position,=20
- pgc->nr_of_cells,
+ pgc->nr_of_cells,
offset + pgc->cell_position_offset)) {
ifoFree_PGC(pgc);
return 0;
}
+ } else {
+ pgc->cell_position =3D NULL;
+ }
} else {
pgc->cell_position =3D NULL;
}
@@ -793,7 +920,8 @@
=20
int ifoRead_TT_SRPT(ifo_handle_t *ifofile) {
tt_srpt_t *tt_srpt;
- int i, info_length;
+ int i;
+ unsigned info_length;
=20
if(!ifofile)
return 0;
@@ -814,7 +942,9 @@
ifofile->tt_srpt =3D tt_srpt;
=20
if(!(DVDReadBytes(ifofile->file, tt_srpt, TT_SRPT_SIZE))) {
- LOG_ERROR( stderr, "libdvdread: Unable to read read TT_SRPT.\n");
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 1) {
+ fprintf(stderr, "libdvdread: Unable to read read TT_SRPT.\n");
+ }
free(tt_srpt);
return 0;
}
@@ -831,7 +961,9 @@
return 0;
}
if(!(DVDReadBytes(ifofile->file, tt_srpt->title, info_length))) {
- LOG_ERROR( stderr, "libdvdread: Unable to read read TT_SRPT.\n");
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 1) {
+ fprintf(stderr, "libdvdread: Unable to read read TT_SRPT.\n");
+ }
ifoFree_TT_SRPT(ifofile);
return 0;
}
@@ -846,7 +978,7 @@
CHECK_ZERO(tt_srpt->zero_1);
CHECK_VALUE(tt_srpt->nr_of_srpts !=3D 0);
CHECK_VALUE(tt_srpt->nr_of_srpts < 100); // ??
- CHECK_VALUE((int)tt_srpt->nr_of_srpts * sizeof(title_info_t) <=3D info=
_length);
+ CHECK_VALUE(tt_srpt->nr_of_srpts * sizeof(title_info_t) <=3D info_leng=
th);
=20
for(i =3D 0; i < tt_srpt->nr_of_srpts; i++) {
CHECK_VALUE(tt_srpt->title[i].pb_ty.zero_1 =3D=3D 0);
@@ -868,7 +1000,7 @@
tt_srpt->nr_of_srpts * sizeof(title_info_t),=20
my_friendly_zeros,=20
info_length - tt_srpt->nr_of_srpts * sizeof(title_info_t))) =
{
- LOG_ERROR( stderr, "VMG_PTT_SRPT slack is !=3D 0, ");
+ fprintf(stderr, "VMG_PTT_SRPT slack is !=3D 0, ");
hexdump((uint8_t *)tt_srpt->title +=20
tt_srpt->nr_of_srpts * sizeof(title_info_t),=20
info_length - tt_srpt->nr_of_srpts * sizeof(title_info_t));
@@ -895,7 +1027,6 @@
vts_ptt_srpt_t *vts_ptt_srpt;
int info_length, i, j;
uint32_t *data;
- uint8_t *data_8;
=20
if(!ifofile)
return 0;
@@ -907,7 +1038,7 @@
return 0;
=20
if(!DVDFileSeek_(ifofile->file,
- ifofile->vtsi_mat->vts_ptt_srpt * DVD_BLOCK_LEN))
+ ifofile->vtsi_mat->vts_ptt_srpt * DVD_BLOCK_LEN))
return 0;
=20
vts_ptt_srpt =3D (vts_ptt_srpt_t *)malloc(sizeof(vts_ptt_srpt_t));
@@ -917,7 +1048,9 @@
ifofile->vts_ptt_srpt =3D vts_ptt_srpt;
=20
if(!(DVDReadBytes(ifofile->file, vts_ptt_srpt, VTS_PTT_SRPT_SIZE))) {
- LOG_ERROR( stderr, "libdvdread: Unable to read PTT search table.\n")=
;
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 1) {
+ fprintf(stderr, "libdvdread: Unable to read PTT search table.\n");
+ }
free(vts_ptt_srpt);
return 0;
}
@@ -938,7 +1071,9 @@
return 0;
}
if(!(DVDReadBytes(ifofile->file, data, info_length))) {
- LOG_ERROR( stderr, "libdvdread: Unable to read PTT search table.\n")=
;
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 1) {
+ fprintf(stderr, "libdvdread: Unable to read PTT search table.\n");
+ }
free(vts_ptt_srpt);
free(data);
ifofile->vts_ptt_srpt =3D 0;
@@ -988,11 +1123,10 @@
for(j =3D 0; j < vts_ptt_srpt->title[i].nr_of_ptts; j++) {
/* The assert placed here because of Magic Knight Rayearth Daybrea=
k */
CHECK_VALUE(data[i] + sizeof(ptt_info_t) <=3D vts_ptt_srpt->last_b=
yte + 1);
- data_8 =3D data;
vts_ptt_srpt->title[i].ptt[j].pgcn=20
- =3D *(uint16_t*)(&data_8[data[i] + 4*j - VTS_PTT_SRPT_SIZE]);
+ =3D *(uint16_t*)(((char *)data) + data[i] + 4*j - VTS_PTT_SRPT_S=
IZE);
vts_ptt_srpt->title[i].ptt[j].pgn=20
- =3D *(uint16_t*)(&data_8[data[i] + 4*j + 2 - VTS_PTT_SRPT_SIZE])=
;
+ =3D *(uint16_t*)(((char *)data) + data[i] + 4*j + 2 - VTS_PTT_SR=
PT_SIZE);
}
}
=20
@@ -1071,7 +1205,7 @@
CHECK_VALUE(ptl_mait->nr_of_vtss !=3D 0);
CHECK_VALUE(ptl_mait->nr_of_vtss < 100); // ?? =20
CHECK_VALUE(ptl_mait->nr_of_countries * PTL_MAIT_COUNTRY_SIZE=20
- <=3D ptl_mait->last_byte + 1 - PTL_MAIT_SIZE);
+ <=3D ptl_mait->last_byte + 1 - PTL_MAIT_SIZE);
=20
info_length =3D ptl_mait->nr_of_countries * sizeof(ptl_mait_country_t)=
;
ptl_mait->countries =3D (ptl_mait_country_t *)malloc(info_length);
@@ -1083,7 +1217,9 @@
=20
for(i =3D 0; i < ptl_mait->nr_of_countries; i++) {
if(!(DVDReadBytes(ifofile->file, &ptl_mait->countries[i], PTL_MAIT_C=
OUNTRY_SIZE))) {
- LOG_ERROR( stderr, "libdvdread: Unable to read PTL_MAIT.\n");
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 1) {
+ fprintf(stderr, "libdvdread: Unable to read PTL_MAIT.\n");
+ }
free(ptl_mait->countries);
free(ptl_mait);
ifofile->ptl_mait =3D 0;
@@ -1099,17 +1235,19 @@
for(i =3D 0; i < ptl_mait->nr_of_countries; i++) {
CHECK_ZERO(ptl_mait->countries[i].zero_1);
CHECK_ZERO(ptl_mait->countries[i].zero_2); =20
- CHECK_VALUE(ptl_mait->countries[i].pf_ptl_mai_start_byte
- + 8*2 * (ptl_mait->nr_of_vtss + 1) <=3D ptl_mait->last_byte + 1);
+ CHECK_VALUE(ptl_mait->countries[i].pf_ptl_mai_start_byte +
+ 16U * (ptl_mait->nr_of_vtss + 1) <=3D ptl_mait->last_byt=
e + 1U);
}
=20
for(i =3D 0; i < ptl_mait->nr_of_countries; i++) {
uint16_t *pf_temp;
=20
if(!DVDFileSeek_(ifofile->file,=20
- ifofile->vmgi_mat->ptl_mait * DVD_BLOCK_LEN
+ ifofile->vmgi_mat->ptl_mait * DVD_BLOCK_LEN
+ ptl_mait->countries[i].pf_ptl_mai_start_byte)) {
- LOG_ERROR( stderr, "libdvdread: Unable to seak PTL_MAIT table.\n")=
;
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 1) {
+ fprintf(stderr, "libdvdread: Unable to seak PTL_MAIT table.\n");
+ }
free(ptl_mait->countries);
free(ptl_mait);
return 0;
@@ -1118,30 +1256,32 @@
pf_temp =3D (uint16_t *)malloc(info_length);
if(!pf_temp) {
for(j =3D 0; j < i ; j++) {
- free(ptl_mait->countries[j].pf_ptl_mai);
+ free(ptl_mait->countries[j].pf_ptl_mai);
}
free(ptl_mait->countries);
free(ptl_mait);
return 0;
}
if(!(DVDReadBytes(ifofile->file, pf_temp, info_length))) {
- LOG_ERROR( stderr, "libdvdread: Unable to read PTL_MAIT table.\n"=
);
- free(pf_temp);
- for(j =3D 0; j < i ; j++) {
- free(ptl_mait->countries[j].pf_ptl_mai);
- }
- free(ptl_mait->countries);
- free(ptl_mait);
- return 0;
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 1) {
+ fprintf(stderr, "libdvdread: Unable to read PTL_MAIT table.\n");
+ }
+ free(pf_temp);
+ for(j =3D 0; j < i ; j++) {
+ free(ptl_mait->countries[j].pf_ptl_mai);
+ }
+ free(ptl_mait->countries);
+ free(ptl_mait);
+ return 0;
}
for (j =3D 0; j < ((ptl_mait->nr_of_vtss + 1) * 8); j++) {
- B2N_16(pf_temp[j]);
+ B2N_16(pf_temp[j]);
}
ptl_mait->countries[i].pf_ptl_mai =3D (pf_level_t *)malloc(info_leng=
th);
if(!ptl_mait->countries[i].pf_ptl_mai) {
free(pf_temp);
for(j =3D 0; j < i ; j++) {
- free(ptl_mait->countries[j].pf_ptl_mai);
+ free(ptl_mait->countries[j].pf_ptl_mai);
}
free(ptl_mait->countries);
free(ptl_mait);
@@ -1150,10 +1290,10 @@
{ /* Transpose the array so we can use C indexing. */
int level, vts;
for(level =3D 0; level < 8; level++) {
- for(vts =3D 0; vts <=3D ptl_mait->nr_of_vtss; vts++) {
- ptl_mait->countries[i].pf_ptl_mai[vts][level] =3D
- pf_temp[(7-level)*(ptl_mait->nr_of_vtss+1) + vts];
- }
+ for(vts =3D 0; vts <=3D ptl_mait->nr_of_vtss; vts++) {
+ ptl_mait->countries[i].pf_ptl_mai[vts][level] =3D
+ pf_temp[(7-level)*(ptl_mait->nr_of_vtss+1) + vts];
+ }
}
free(pf_temp);
}
@@ -1169,7 +1309,7 @@
=20
if(ifofile->ptl_mait) {
for(i =3D 0; i < ifofile->ptl_mait->nr_of_countries; i++) {
- free(ifofile->ptl_mait->countries[i].pf_ptl_mai);
+ free(ifofile->ptl_mait->countries[i].pf_ptl_mai);
}
free(ifofile->ptl_mait->countries);
free(ifofile->ptl_mait);
@@ -1190,9 +1330,9 @@
if(!ifofile->vtsi_mat)
return 0;
=20
- if(ifofile->vtsi_mat->vts_tmapt =3D=3D 0) { /* optional(?) */
+ /* Seems to be optional, at least when there are no OneSequencial Titl=
es */
+ if(ifofile->vtsi_mat->vts_tmapt =3D=3D 0) {
ifofile->vts_tmapt =3D NULL;
- fprintf(stderr,"Please send bug report - no VTS_TMAPT ?? \n");
return 1;
}
=20
@@ -1208,7 +1348,9 @@
ifofile->vts_tmapt =3D vts_tmapt;
=20
if(!(DVDReadBytes(ifofile->file, vts_tmapt, VTS_TMAPT_SIZE))) {
- LOG_ERROR( stderr, "libdvdread: Unable to read VTS_TMAPT.\n");
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 1) {
+ fprintf(stderr, "libdvdread: Unable to read VTS_TMAPT.\n");
+ }
free(vts_tmapt);
ifofile->vts_tmapt =3D NULL;
return 0;
@@ -1231,7 +1373,9 @@
vts_tmapt->tmap_offset =3D vts_tmap_srp;
=20
if(!(DVDReadBytes(ifofile->file, vts_tmap_srp, info_length))) {
- LOG_ERROR( stderr, "libdvdread: Unable to read VTS_TMAPT.\n");
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 1) {
+ fprintf(stderr, "libdvdread: Unable to read VTS_TMAPT.\n");
+ }
free(vts_tmap_srp);
free(vts_tmapt);
ifofile->vts_tmapt =3D NULL;
@@ -1239,7 +1383,7 @@
}
=20
for (i =3D 0; i < vts_tmapt->nr_of_tmaps; i++) {
- B2N_32(vts_tmap_srp[i]);=20
+ B2N_32(vts_tmap_srp[i]);=20
}
=20
=20
@@ -1262,7 +1406,9 @@
}
=20
if(!(DVDReadBytes(ifofile->file, &vts_tmapt->tmap[i], VTS_TMAP_SIZE)=
)) {
- LOG_ERROR( stderr, "libdvdread: Unable to read VTS_TMAP.\n");
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 1) {
+ fprintf(stderr, "libdvdread: Unable to read VTS_TMAP.\n");
+ }
ifoFree_VTS_TMAPT(ifofile);
return 0;
}
@@ -1284,7 +1430,9 @@
}
=20
if(!(DVDReadBytes(ifofile->file, vts_tmapt->tmap[i].map_ent, info_le=
ngth))) {
- LOG_ERROR( stderr, "libdvdread: Unable to read VTS_TMAP_ENT.\n");
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 1) {
+ fprintf(stderr, "libdvdread: Unable to read VTS_TMAP_ENT.\n");
+ }
ifoFree_VTS_TMAPT(ifofile);
return 0;
}
@@ -1305,7 +1453,7 @@
if(ifofile->vts_tmapt) { =20
for(i =3D 0; i < ifofile->vts_tmapt->nr_of_tmaps; i++)
if(ifofile->vts_tmapt->tmap[i].map_ent)
- free(ifofile->vts_tmapt->tmap[i].map_ent);
+ free(ifofile->vts_tmapt->tmap[i].map_ent);
free(ifofile->vts_tmapt->tmap);
free(ifofile->vts_tmapt->tmap_offset);
free(ifofile->vts_tmapt);
@@ -1395,7 +1543,9 @@
Enemy of the State region 2 (de) has Titles where nr_of_vobs field
is to high, they high ones are never referenced though. */
if(info_length / sizeof(cell_adr_t) < c_adt->nr_of_vobs) {
- LOG_ERROR( stderr, "libdvdread: *C_ADT nr_of_vobs > avaiable info en=
tries\n");
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 1) {
+ fprintf(stderr, "libdvdread: *C_ADT nr_of_vobs > avaiable info ent=
ries\n");
+ }
c_adt->nr_of_vobs =3D info_length / sizeof(cell_adr_t);
}
=20
@@ -1419,7 +1569,7 @@
CHECK_VALUE(c_adt->cell_adr_table[i].vob_id <=3D c_adt->nr_of_vobs);
CHECK_VALUE(c_adt->cell_adr_table[i].cell_id > 0);
CHECK_VALUE(c_adt->cell_adr_table[i].start_sector <=20
- c_adt->cell_adr_table[i].last_sector);
+ c_adt->cell_adr_table[i].last_sector);
}
=20
return 1;
@@ -1506,7 +1656,7 @@
=20
static int ifoRead_VOBU_ADMAP_internal(ifo_handle_t *ifofile,=20
vobu_admap_t *vobu_admap,=20
- unsigned int sector) {
+ unsigned int sector) {
unsigned int i;
int info_length;
=20
@@ -1530,7 +1680,7 @@
}
if(info_length &&=20
!(DVDReadBytes(ifofile->file,=20
- vobu_admap->vobu_start_sectors, info_length))) {
+ vobu_admap->vobu_start_sectors, info_length))) {
free(vobu_admap->vobu_start_sectors);
return 0;
}
@@ -1627,8 +1777,8 @@
}
ptr =3D data;
for(i =3D 0; i < pgcit->nr_of_pgci_srp; i++) {
- memcpy(&pgcit->pgci_srp[i], ptr, PGCI_LU_SIZE);
- ptr +=3D PGCI_LU_SIZE;
+ memcpy(&pgcit->pgci_srp[i], ptr, PGCI_SRP_SIZE);
+ ptr +=3D PGCI_SRP_SIZE;
B2N_16(pgcit->pgci_srp[i].ptl_id_mask);
B2N_32(pgcit->pgci_srp[i].pgc_start_byte);
CHECK_VALUE(pgcit->pgci_srp[i].unknown1 =3D=3D 0);
@@ -1646,6 +1796,8 @@
ifoFree_PGC(pgcit->pgci_srp[j].pgc);
free(pgcit->pgci_srp[j].pgc);
}
+ free(pgcit->pgci_srp);
+ pgcit->pgci_srp =3D NULL;
return 0;
}
if(!ifoRead_PGC(ifofile, pgcit->pgci_srp[i].pgc,=20
@@ -1656,6 +1808,7 @@
free(pgcit->pgci_srp[j].pgc);
}
free(pgcit->pgci_srp);
+ pgcit->pgci_srp =3D NULL;
return 0;
}
}
@@ -1666,10 +1819,10 @@
static void ifoFree_PGCIT_internal(pgcit_t *pgcit) {
if(pgcit) {
int i;
- for(i =3D 0; i < pgcit->nr_of_pgci_srp; i++) {
+ for(i =3D 0; i < pgcit->nr_of_pgci_srp; i++) {
ifoFree_PGC(pgcit->pgci_srp[i].pgc);
free(pgcit->pgci_srp[i].pgc);
- }
+ }
free(pgcit->pgci_srp);
}
}
@@ -1753,7 +1906,7 @@
free(data);
free(pgci_ut);
ifofile->pgci_ut =3D 0;
- return 0;
+ return 0;
}
ptr =3D data;
for(i =3D 0; i < pgci_ut->nr_of_lus; i++) {
@@ -1767,7 +1920,7 @@
for(i =3D 0; i < pgci_ut->nr_of_lus; i++) {
// Maybe this is only defined for v1.1 and later titles?
/* If the bits in 'lu[i].exists' are enumerated abcd efgh then:
- VTS_x_yy.IFO VIDEO_TS.IFO
+ VTS_x_yy.IFO VIDEO_TS.IFO
a =3D=3D 0x83 "Root" 0x82 "Title"
b =3D=3D 0x84 "Subpicture"
c =3D=3D 0x85 "Audio"
@@ -1917,7 +2070,7 @@
CHECK_VALUE(vts_atrt->nr_of_vtss !=3D 0);
CHECK_VALUE(vts_atrt->nr_of_vtss < 100); //??
CHECK_VALUE((uint32_t)vts_atrt->nr_of_vtss * (4 + VTS_ATTRIBUTES_MIN_S=
IZE) +=20
- VTS_ATRT_SIZE < vts_atrt->last_byte + 1);
+ VTS_ATRT_SIZE < vts_atrt->last_byte + 1);
=20
info_length =3D vts_atrt->nr_of_vtss * sizeof(uint32_t);
data =3D (uint32_t *)malloc(info_length);
@@ -1995,7 +2148,7 @@
return 1;
=20
if(!DVDFileSeek_(ifofile->file,=20
- ifofile->vmgi_mat->txtdt_mgi * DVD_BLOCK_LEN))
+ ifofile->vmgi_mat->txtdt_mgi * DVD_BLOCK_LEN))
return 0;
=20
txtdt_mgi =3D (txtdt_mgi_t *)malloc(sizeof(txtdt_mgi_t));
@@ -2005,13 +2158,15 @@
ifofile->txtdt_mgi =3D txtdt_mgi;
=20
if(!(DVDReadBytes(ifofile->file, txtdt_mgi, TXTDT_MGI_SIZE))) {
- LOG_ERROR( stderr, "libdvdread: Unable to read TXTDT_MGI.\n");
+ if(dvdread_verbose(device_of_file(ifofile->file)) >=3D 1) {
+ fprintf(stderr, "libdvdread: Unable to read TXTDT_MGI.\n");
+ }
free(txtdt_mgi);
ifofile->txtdt_mgi =3D 0;
return 0;
}
=20
- // LOG_ERROR( stderr, "-- Not done yet --\n");
+ // fprintf(stderr, "-- Not done yet --\n");
return 1;
}
=20
Modified: trunk/DvdMenuXtractor/libdvdread/dvdread/ifo_types.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/dvdread/ifo_types.h 2007-01-22 11:21=
:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/dvdread/ifo_types.h 2007-01-28 16:48=
:11 UTC (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
#ifndef IFO_TYPES_H_INCLUDED
#define IFO_TYPES_H_INCLUDED
=20
@@ -20,9 +21,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 =
USA
*/
=20
-#include <inttypes.h>
#include <dvdread/dvd_reader.h>
=20
+#if defined(__BEOS__)
+#if !defined(_INTTYPES_H_) && !defined(_INTTYPES_H) && !defined(_STDINT_=
H_) && !defined(_STDINT_H)
+#error "Must include <inttypes.h> or <stdint.h> before any libdvdread he=
ader."
+#endif
+#elif defined(WIN32) && !defined(HAVE_INTTYPES_H) && !defined(HAVE_STDIN=
T_H)
+#error "Must include <inttypes.h> or <stdint.h> before any libdvdread he=
ader."
+#elif !defined(WIN32) && (!defined(UINT8_MAX) || !defined(UINT16_MAX) ||=
!defined(INT32_MAX))
+#error "Must include <inttypes.h> or <stdint.h> before any libdvdread he=
ader."
+#endif
=20
#undef ATTRIBUTE_PACKED
#undef PRAGMA_PACK_BEGIN=20
@@ -68,41 +77,49 @@
typedef struct {
uint8_t bytes[8];
} ATTRIBUTE_PACKED vm_cmd_t;
-#define COMMAND_DATA_SIZE 8
+#define COMMAND_DATA_SIZE 8U
=20
+/* This typedefs are needed for MSVC compatiblity */
+/* Thanks robux ;) */
+#undef BITFIELD_TYPE
+#if defined(_MSC_VER)
+#define BITFIELD_TYPE char
+#else
+#define BITFIELD_TYPE int
+#endif
=20
/**
* Video Attributes.
*/
typedef struct {
#ifdef WORDS_BIGENDIAN
- unsigned char mpeg_version : 2;
- unsigned char video_format : 2;
- unsigned char display_aspect_ratio : 2;
- unsigned char permitted_df : 2;
+ unsigned BITFIELD_TYPE mpeg_version : 2;
+ unsigned BITFIELD_TYPE video_format : 2;
+ unsigned BITFIELD_TYPE display_aspect_ratio : 2;
+ unsigned BITFIELD_TYPE permitted_df : 2;
=20
- unsigned char line21_cc_1 : 1;
- unsigned char line21_cc_2 : 1;
- unsigned char unknown1 : 1;
- unsigned char bit_rate : 1;
+ unsigned BITFIELD_TYPE line21_cc_1 : 1;
+ unsigned BITFIELD_TYPE line21_cc_2 : 1;
+ unsigned BITFIELD_TYPE unknown1 : 1;
+ unsigned BITFIELD_TYPE bit_rate : 1;
=20
- unsigned char picture_size : 2;
- unsigned char letterboxed : 1;
- unsigned char film_mode : 1;
+ unsigned BITFIELD_TYPE picture_size : 2;
+ unsigned BITFIELD_TYPE letterboxed : 1;
+ unsigned BITFIELD_TYPE film_mode : 1;
#else
- unsigned char permitted_df : 2;
- unsigned char display_aspect_ratio : 2;
- unsigned char video_format : 2;
- unsigned char mpeg_version : 2;
+ unsigned BITFIELD_TYPE permitted_df : 2;
+ unsigned BITFIELD_TYPE display_aspect_ratio : 2;
+ unsigned BITFIELD_TYPE video_format : 2;
+ unsigned BITFIELD_TYPE mpeg_version : 2;
=20
- unsigned char film_mode : 1;
- unsigned char letterboxed : 1;
- unsigned char picture_size : 2;
+ unsigned BITFIELD_TYPE film_mode : 1;
+ unsigned BITFIELD_TYPE letterboxed : 1;
+ unsigned BITFIELD_TYPE picture_size : 2;
=20
- unsigned char bit_rate : 1;
- unsigned char unknown1 : 1;
- unsigned char line21_cc_2 : 1;
- unsigned char line21_cc_1 : 1;
+ unsigned BITFIELD_TYPE bit_rate : 1;
+ unsigned BITFIELD_TYPE unknown1 : 1;
+ unsigned BITFIELD_TYPE line21_cc_2 : 1;
+ unsigned BITFIELD_TYPE line21_cc_1 : 1;
#endif
} ATTRIBUTE_PACKED video_attr_t;
=20
@@ -111,58 +128,58 @@
*/
typedef struct {
#ifdef WORDS_BIGENDIAN
- unsigned char audio_format : 3;
- unsigned char multichannel_extension : 1;
- unsigned char lang_type : 2;
- unsigned char application_mode : 2;
+ unsigned BITFIELD_TYPE audio_format : 3;
+ unsigned BITFIELD_TYPE multichannel_extension : 1;
+ unsigned BITFIELD_TYPE lang_type : 2;
+ unsigned BITFIELD_TYPE application_mode : 2;
=20
- unsigned char quantization : 2;
- unsigned char sample_frequency : 2;
- unsigned char unknown1 : 1;
- unsigned char channels : 3;
+ unsigned BITFIELD_TYPE quantization : 2;
+ unsigned BITFIELD_TYPE sample_frequency : 2;
+ unsigned BITFIELD_TYPE unknown1 : 1;
+ unsigned BITFIELD_TYPE channels : 3;
#else
- unsigned char application_mode : 2;
- unsigned char lang_type : 2;
- unsigned char multichannel_extension : 1;
- unsigned char audio_format : 3;
+ unsigned BITFIELD_TYPE application_mode : 2;
+ unsigned BITFIELD_TYPE lang_type : 2;
+ unsigned BITFIELD_TYPE multichannel_extension : 1;
+ unsigned BITFIELD_TYPE audio_format : 3;
=20
- unsigned char channels : 3;
- unsigned char unknown1 : 1;
- unsigned char sample_frequency : 2;
- unsigned char quantization : 2;
+ unsigned BITFIELD_TYPE channels : 3;
+ unsigned BITFIELD_TYPE unknown1 : 1;
+ unsigned BITFIELD_TYPE sample_frequency : 2;
+ unsigned BITFIELD_TYPE quantization : 2;
#endif
uint16_t lang_code;
uint8_t lang_extension;
uint8_t code_extension;
uint8_t unknown3;
union {
- struct ATTRIBUTE_PACKED {
+ struct {
#ifdef WORDS_BIGENDIAN
- unsigned char unknown4 : 1;
- unsigned char channel_assignment : 3;
- unsigned char version : 2;
- unsigned char mc_intro : 1; /* probably 0: true, 1:false=
*/
- unsigned char mode : 1; /* Karaoke mode 0: solo 1: d=
uet */
+ unsigned BITFIELD_TYPE unknown4 : 1;
+ unsigned BITFIELD_TYPE channel_assignment : 3;
+ unsigned BITFIELD_TYPE version : 2;
+ unsigned BITFIELD_TYPE mc_intro : 1; /* probably 0: true=
, 1:false */
+ unsigned BITFIELD_TYPE mode : 1; /* Karaoke mode 0: =
solo 1: duet */
#else
- unsigned char mode : 1;
- unsigned char mc_intro : 1;
- unsigned char version : 2;
- unsigned char channel_assignment : 3;
- unsigned char unknown4 : 1;
+ unsigned BITFIELD_TYPE mode : 1;
+ unsigned BITFIELD_TYPE mc_intro : 1;
+ unsigned BITFIELD_TYPE version : 2;
+ unsigned BITFIELD_TYPE channel_assignment : 3;
+ unsigned BITFIELD_TYPE unknown4 : 1;
#endif
- } karaoke;
- struct ATTRIBUTE_PACKED {
+ } ATTRIBUTE_PACKED karaoke;
+ struct {
#ifdef WORDS_BIGENDIAN
- unsigned char unknown5 : 4;
- unsigned char dolby_encoded : 1; /* suitable for surround dec=
oding */
- unsigned char unknown6 : 3;
+ unsigned BITFIELD_TYPE unknown5 : 4;
+ unsigned BITFIELD_TYPE dolby_encoded : 1; /* suitable for sur=
round decoding */
+ unsigned BITFIELD_TYPE unknown6 : 3;
#else
- unsigned char unknown6 : 3;
- unsigned char dolby_encoded : 1;
- unsigned char unknown5 : 4;
+ unsigned BITFIELD_TYPE unknown6 : 3;
+ unsigned BITFIELD_TYPE dolby_encoded : 1;
+ unsigned BITFIELD_TYPE unknown5 : 4;
#endif
- } surround;
- } app_info;
+ } ATTRIBUTE_PACKED surround;
+ } ATTRIBUTE_PACKED app_info;
} ATTRIBUTE_PACKED audio_attr_t;
=20
=20
@@ -171,53 +188,53 @@
*/
typedef struct {
#ifdef WORDS_BIGENDIAN
- unsigned char zero1 : 7;
- unsigned char ach0_gme : 1;
+ unsigned BITFIELD_TYPE zero1 : 7;
+ unsigned BITFIELD_TYPE ach0_gme : 1;
=20
- unsigned char zero2 : 7;
- unsigned char ach1_gme : 1;
+ unsigned BITFIELD_TYPE zero2 : 7;
+ unsigned BITFIELD_TYPE ach1_gme : 1;
=20
- unsigned char zero3 : 4;
- unsigned char ach2_gv1e : 1;
- unsigned char ach2_gv2e : 1;
- unsigned char ach2_gm1e : 1;
- unsigned char ach2_gm2e : 1;
+ unsigned BITFIELD_TYPE zero3 : 4;
+ unsigned BITFIELD_TYPE ach2_gv1e : 1;
+ unsigned BITFIELD_TYPE ach2_gv2e : 1;
+ unsigned BITFIELD_TYPE ach2_gm1e : 1;
+ unsigned BITFIELD_TYPE ach2_gm2e : 1;
=20
- unsigned char zero4 : 4;
- unsigned char ach3_gv1e : 1;
- unsigned char ach3_gv2e : 1;
- unsigned char ach3_gmAe : 1;
- unsigned char ach3_se2e : 1;
+ unsigned BITFIELD_TYPE zero4 : 4;
+ unsigned BITFIELD_TYPE ach3_gv1e : 1;
+ unsigned BITFIELD_TYPE ach3_gv2e : 1;
+ unsigned BITFIELD_TYPE ach3_gmAe : 1;
+ unsigned BITFIELD_TYPE ach3_se2e : 1;
=20
- unsigned char zero5 : 4;
- unsigned char ach4_gv1e : 1;
- unsigned char ach4_gv2e : 1;
- unsigned char ach4_gmBe : 1;
- unsigned char ach4_seBe : 1;
+ unsigned BITFIELD_TYPE zero5 : 4;
+ unsigned BITFIELD_TYPE ach4_gv1e : 1;
+ unsigned BITFIELD_TYPE ach4_gv2e : 1;
+ unsigned BITFIELD_TYPE ach4_gmBe : 1;
+ unsigned BITFIELD_TYPE ach4_seBe : 1;
#else
- unsigned char ach0_gme : 1;
- unsigned char zero1 : 7;
+ unsigned BITFIELD_TYPE ach0_gme : 1;
+ unsigned BITFIELD_TYPE zero1 : 7;
=20
- unsigned char ach1_gme : 1;
- unsigned char zero2 : 7;
+ unsigned BITFIELD_TYPE ach1_gme : 1;
+ unsigned BITFIELD_TYPE zero2 : 7;
=20
- unsigned char ach2_gm2e : 1;
- unsigned char ach2_gm1e : 1;
- unsigned char ach2_gv2e : 1;
- unsigned char ach2_gv1e : 1;
- unsigned char zero3 : 4;
+ unsigned BITFIELD_TYPE ach2_gm2e : 1;
+ unsigned BITFIELD_TYPE ach2_gm1e : 1;
+ unsigned BITFIELD_TYPE ach2_gv2e : 1;
+ unsigned BITFIELD_TYPE ach2_gv1e : 1;
+ unsigned BITFIELD_TYPE zero3 : 4;
=20
- unsigned char ach3_se2e : 1;
- unsigned char ach3_gmAe : 1;
- unsigned char ach3_gv2e : 1;
- unsigned char ach3_gv1e : 1;
- unsigned char zero4 : 4;
+ unsigned BITFIELD_TYPE ach3_se2e : 1;
+ unsigned BITFIELD_TYPE ach3_gmAe : 1;
+ unsigned BITFIELD_TYPE ach3_gv2e : 1;
+ unsigned BITFIELD_TYPE ach3_gv1e : 1;
+ unsigned BITFIELD_TYPE zero4 : 4;
=20
- unsigned char ach4_seBe : 1;
- unsigned char ach4_gmBe : 1;
- unsigned char ach4_gv2e : 1;
- unsigned char ach4_gv1e : 1;
- unsigned char zero5 : 4;
+ unsigned BITFIELD_TYPE ach4_seBe : 1;
+ unsigned BITFIELD_TYPE ach4_gmBe : 1;
+ unsigned BITFIELD_TYPE ach4_gv2e : 1;
+ unsigned BITFIELD_TYPE ach4_gv1e : 1;
+ unsigned BITFIELD_TYPE zero5 : 4;
#endif
uint8_t zero6[19];
} ATTRIBUTE_PACKED multichannel_ext_t;
@@ -238,13 +255,13 @@
* lang extension: if type =3D=3D 1 contains the lang extension
*/
#ifdef WORDS_BIGENDIAN
- unsigned char code_mode : 3;
- unsigned char zero1 : 3;
- unsigned char type : 2;
+ unsigned BITFIELD_TYPE code_mode : 3;
+ unsigned BITFIELD_TYPE zero1 : 3;
+ unsigned BITFIELD_TYPE type : 2;
#else
- unsigned char type : 2;
- unsigned char zero1 : 3;
- unsigned char code_mode : 3;
+ unsigned BITFIELD_TYPE type : 2;
+ unsigned BITFIELD_TYPE zero1 : 3;
+ unsigned BITFIELD_TYPE code_mode : 3;
#endif
uint8_t zero2;
uint16_t lang_code;
@@ -261,12 +278,12 @@
uint16_t nr_of_pre;
uint16_t nr_of_post;
uint16_t nr_of_cell;
- uint16_t zero_1;
+ uint16_t last_byte;
vm_cmd_t *pre_cmds;
vm_cmd_t *post_cmds;
vm_cmd_t *cell_cmds;
} ATTRIBUTE_PACKED pgc_command_tbl_t;
-#define PGC_COMMAND_TBL_SIZE 8
+#define PGC_COMMAND_TBL_SIZE 8U
=20
/**
* PGC Program Map
@@ -278,27 +295,27 @@
*/
typedef struct {
#ifdef WORDS_BIGENDIAN
- unsigned char block_mode : 2;
- unsigned char block_type : 2;
- unsigned char seamless_play : 1;
- unsigned char interleaved : 1;
- unsigned char stc_discontinuity: 1;
- unsigned char seamless_angle : 1;
+ unsigned BITFIELD_TYPE block_mode : 2;
+ unsigned BITFIELD_TYPE block_type : 2;
+ unsigned BITFIELD_TYPE seamless_play : 1;
+ unsigned BITFIELD_TYPE interleaved : 1;
+ unsigned BITFIELD_TYPE stc_discontinuity: 1;
+ unsigned BITFIELD_TYPE seamless_angle : 1;
=20
- unsigned char playback_mode : 1; /**< When set, enter StillMode af=
ter each VOBU */
- unsigned char restricted : 1; /**< ?? drop out of fastforward? =
*/
- unsigned char unknown2 : 6;
+ unsigned BITFIELD_TYPE playback_mode : 1; /**< When set, enter Sti=
llMode after each VOBU */
+ unsigned BITFIELD_TYPE restricted : 1; /**< ?? drop out of fast=
forward? */
+ unsigned BITFIELD_TYPE unknown2 : 6;
#else
- unsigned char seamless_angle : 1;
- unsigned char stc_discontinuity: 1;
- unsigned char interleaved : 1;
- unsigned char seamless_play : 1;
- unsigned char block_type : 2;
- unsigned char block_mode : 2;
+ unsigned BITFIELD_TYPE seamless_angle : 1;
+ unsigned BITFIELD_TYPE stc_discontinuity: 1;
+ unsigned BITFIELD_TYPE interleaved : 1;
+ unsigned BITFIELD_TYPE seamless_play : 1;
+ unsigned BITFIELD_TYPE block_type : 2;
+ unsigned BITFIELD_TYPE block_mode : 2;
=20
- unsigned char unknown2 : 6;
- unsigned char restricted : 1;
- unsigned char playback_mode : 1;
+ unsigned BITFIELD_TYPE unknown2 : 6;
+ unsigned BITFIELD_TYPE restricted : 1;
+ unsigned BITFIELD_TYPE playback_mode : 1;
#endif
uint8_t still_time;
uint8_t cell_cmd_nr;
@@ -331,65 +348,65 @@
*/
typedef struct {
#ifdef WORDS_BIGENDIAN
- unsigned char zero : 7; /* 25-31 */
- unsigned char video_pres_mode_change : 1; /* 24 */
+ unsigned BITFIELD_TYPE zero : 7; /* 25-31 */
+ unsigned BITFIELD_TYPE video_pres_mode_change : 1; /* 24 */
=20
- unsigned char karaoke_audio_pres_mode_change : 1; /* 23 */
- unsigned char angle_change : 1;
- unsigned char subpic_stream_change : 1;
- unsigned char audio_stream_change : 1;
- unsigned char pause_on : 1;
- unsigned char still_off : 1;
- unsigned char button_select_or_activate : 1;
- unsigned char resume : 1; /* 16 */
+ unsigned BITFIELD_TYPE karaoke_audio_pres_mode_change : 1; /* 23 */
+ unsigned BITFIELD_TYPE angle_change : 1;
+ unsigned BITFIELD_TYPE subpic_stream_change : 1;
+ unsigned BITFIELD_TYPE audio_stream_change : 1;
+ unsigned BITFIELD_TYPE pause_on : 1;
+ unsigned BITFIELD_TYPE still_off : 1;
+ unsigned BITFIELD_TYPE button_select_or_activate : 1;
+ unsigned BITFIELD_TYPE resume : 1; /* 16 */
=20
- unsigned char chapter_menu_call : 1; /* 15 */
- unsigned char angle_menu_call : 1;
- unsigned char audio_menu_call : 1;
- unsigned char subpic_menu_call : 1;
- unsigned char root_menu_call : 1;
- unsigned char title_menu_call : 1;
- unsigned char backward_scan : 1;
- unsigned char forward_scan : 1; /* 8 */
+ unsigned BITFIELD_TYPE chapter_menu_call : 1; /* 15 */
+ unsigned BITFIELD_TYPE angle_menu_call : 1;
+ unsigned BITFIELD_TYPE audio_menu_call : 1;
+ unsigned BITFIELD_TYPE subpic_menu_call : 1;
+ unsigned BITFIELD_TYPE root_menu_call : 1;
+ unsigned BITFIELD_TYPE title_menu_call : 1;
+ unsigned BITFIELD_TYPE backward_scan : 1;
+ unsigned BITFIELD_TYPE forward_scan : 1; /* 8 */
=20
- unsigned char next_pg_search : 1; /* 7 */
- unsigned char prev_or_top_pg_search : 1;
- unsigned char time_or_chapter_search : 1;
- unsigned char go_up : 1;
- unsigned char stop : 1;
- unsigned char title_play : 1;
- unsigned char chapter_search_or_play : 1;
- unsigned char title_or_time_play : 1; /* 0 */
+ unsigned BITFIELD_TYPE next_pg_search : 1; /* 7 */
+ unsigned BITFIELD_TYPE prev_or_top_pg_search : 1;
+ unsigned BITFIELD_TYPE time_or_chapter_search : 1;
+ unsigned BITFIELD_TYPE go_up : 1;
+ unsigned BITFIELD_TYPE stop : 1;
+ unsigned BITFIELD_TYPE title_play : 1;
+ unsigned BITFIELD_TYPE chapter_search_or_play : 1;
+ unsigned BITFIELD_TYPE title_or_time_play : 1; /* 0 */
#else
- unsigned char video_pres_mode_change : 1; /* 24 */
- unsigned char zero : 7; /* 25-31 */
+ unsigned BITFIELD_TYPE video_pres_mode_change : 1; /* 24 */
+ unsigned BITFIELD_TYPE zero : 7; /* 25-31 */
=20
- unsigned char resume : 1; /* 16 */
- unsigned char button_select_or_activate : 1;
- unsigned char still_off : 1;
- unsigned char pause_on : 1;
- unsigned char audio_stream_change : 1;
- unsigned char subpic_stream_change : 1;
- unsigned char angle_change : 1;
- unsigned char karaoke_audio_pres_mode_change : 1; /* 23 */
+ unsigned BITFIELD_TYPE resume : 1; /* 16 */
+ unsigned BITFIELD_TYPE button_select_or_activate : 1;
+ unsigned BITFIELD_TYPE still_off : 1;
+ unsigned BITFIELD_TYPE pause_on : 1;
+ unsigned BITFIELD_TYPE audio_stream_change : 1;
+ unsigned BITFIELD_TYPE subpic_stream_change : 1;
+ unsigned BITFIELD_TYPE angle_change : 1;
+ unsigned BITFIELD_TYPE karaoke_audio_pres_mode_change : 1; /* 23 */
=20
- unsigned char forward_scan : 1; /* 8 */
- unsigned char backward_scan : 1;
- unsigned char title_menu_call : 1;
- unsigned char root_menu_call : 1;
- unsigned char subpic_menu_call : 1;
- unsigned char audio_menu_call : 1;
- unsigned char angle_menu_call : 1;
- unsigned char chapter_menu_call : 1; /* 15 */
+ unsigned BITFIELD_TYPE forward_scan : 1; /* 8 */
+ unsigned BITFIELD_TYPE backward_scan : 1;
+ unsigned BITFIELD_TYPE title_menu_call : 1;
+ unsigned BITFIELD_TYPE root_menu_call : 1;
+ unsigned BITFIELD_TYPE subpic_menu_call : 1;
+ unsigned BITFIELD_TYPE audio_menu_call : 1;
+ unsigned BITFIELD_TYPE angle_menu_call : 1;
+ unsigned BITFIELD_TYPE chapter_menu_call : 1; /* 15 */
=20
- unsigned char title_or_time_play : 1; /* 0 */
- unsigned char chapter_search_or_play : 1;
- unsigned char title_play : 1;
- unsigned char stop : 1;
- unsigned char go_up : 1;
- unsigned char time_or_chapter_search : 1;
- unsigned char prev_or_top_pg_search : 1;
- unsigned char next_pg_search : 1; /* 7 */
+ unsigned BITFIELD_TYPE title_or_time_play : 1; /* 0 */
+ unsigned BITFIELD_TYPE chapter_search_or_play : 1;
+ unsigned BITFIELD_TYPE title_play : 1;
+ unsigned BITFIELD_TYPE stop : 1;
+ unsigned BITFIELD_TYPE go_up : 1;
+ unsigned BITFIELD_TYPE time_or_chapter_search : 1;
+ unsigned BITFIELD_TYPE prev_or_top_pg_search : 1;
+ unsigned BITFIELD_TYPE next_pg_search : 1; /* 7 */
#endif
} ATTRIBUTE_PACKED user_ops_t;
=20
@@ -407,8 +424,8 @@
uint16_t next_pgc_nr;
uint16_t prev_pgc_nr;
uint16_t goup_pgc_nr;
+ uint8_t pg_playback_mode;
uint8_t still_time;
- uint8_t pg_playback_mode;
uint32_t palette[16]; /* New type struct {zero_1, Y, Cr, Cb} ? */
uint16_t command_tbl_offset;
uint16_t program_map_offset;
@@ -419,7 +436,7 @@
cell_playback_t *cell_playback;
cell_position_t *cell_position;
} ATTRIBUTE_PACKED pgc_t;
-#define PGC_SIZE 236
+#define PGC_SIZE 236U
=20
/**
* Program Chain Information Search Pointer.
@@ -427,19 +444,19 @@
typedef struct {
uint8_t entry_id;
#ifdef WORDS_BIGENDIAN
- unsigned char block_mode : 2;
- unsigned char block_type : 2;
- unsigned char unknown1 : 4;
+ unsigned BITFIELD_TYPE block_mode : 2;
+ unsigned BITFIELD_TYPE block_type : 2;
+ unsigned BITFIELD_TYPE unknown1 : 4;
#else
- unsigned char unknown1 : 4;
- unsigned char block_type : 2;
- unsigned char block_mode : 2;
+ unsigned BITFIELD_TYPE unknown1 : 4;
+ unsigned BITFIELD_TYPE block_type : 2;
+ unsigned BITFIELD_TYPE block_mode : 2;
#endif =20
uint16_t ptl_id_mask;
uint32_t pgc_start_byte;
pgc_t *pgc;
} ATTRIBUTE_PACKED pgci_srp_t;
-#define PGCI_SRP_SIZE 8
+#define PGCI_SRP_SIZE 8U
=20
/**
* Program Chain Information Table.
@@ -450,7 +467,7 @@
uint32_t last_byte;
pgci_srp_t *pgci_srp;
} ATTRIBUTE_PACKED pgcit_t;
-#define PGCIT_SIZE 8
+#define PGCIT_SIZE 8U
=20
/**
* Menu PGCI Language Unit.
@@ -462,7 +479,7 @@
uint32_t lang_start_byte;
pgcit_t *pgcit;
} ATTRIBUTE_PACKED pgci_lu_t;
-#define PGCI_LU_SIZE 8
+#define PGCI_LU_SIZE 8U
=20
/**
* Menu PGCI Unit Table.
@@ -473,7 +490,7 @@
uint32_t last_byte;
pgci_lu_t *lu;
} ATTRIBUTE_PACKED pgci_ut_t;
-#define PGCI_UT_SIZE 8
+#define PGCI_UT_SIZE 8U
=20
/**
* Cell Address Information.
@@ -495,7 +512,7 @@
uint32_t last_byte;
cell_adr_t *cell_adr_table; /* No explicit size given. */
} ATTRIBUTE_PACKED c_adt_t;
-#define C_ADT_SIZE 8
+#define C_ADT_SIZE 8U
=20
/**
* VOBU Address Map.
@@ -504,7 +521,7 @@
uint32_t last_byte;
uint32_t *vobu_start_sectors;
} ATTRIBUTE_PACKED vobu_admap_t;
-#define VOBU_ADMAP_SIZE 4
+#define VOBU_ADMAP_SIZE 4U
=20
=20
=20
@@ -560,23 +577,23 @@
=20
typedef struct {
#ifdef WORDS_BIGENDIAN
- unsigned char zero_1 : 1;
- unsigned char multi_or_random_pgc_title : 1; /* 0: one sequential pgc =
title */
- unsigned char jlc_exists_in_cell_cmd : 1;
- unsigned char jlc_exists_in_prepost_cmd : 1;
- unsigned char jlc_exists_in_button_cmd : 1;
- unsigned char jlc_exists_in_tt_dom : 1;
- unsigned char chapter_search_or_play : 1; /* UOP 1 */
- unsigned char title_or_time_play : 1; /* UOP 0 */
+ unsigned BITFIELD_TYPE zero_1 : 1;
+ unsigned BITFIELD_TYPE multi_or_random_pgc_title : 1; /* 0: one sequen=
tial pgc title */
+ unsigned BITFIELD_TYPE jlc_exists_in_cell_cmd : 1;
+ unsigned BITFIELD_TYPE jlc_exists_in_prepost_cmd : 1;
+ unsigned BITFIELD_TYPE jlc_exists_in_button_cmd : 1;
+ unsigned BITFIELD_TYPE jlc_exists_in_tt_dom : 1;
+ unsigned BITFIELD_TYPE chapter_search_or_play : 1; /* UOP 1 */
+ unsigned BITFIELD_TYPE title_or_time_play : 1; /* UOP 0 */
#else
- unsigned char title_or_time_play : 1;
- unsigned char chapter_search_or_play : 1;
- unsigned char jlc_exists_in_tt_dom : 1;
- unsigned char jlc_exists_in_button_cmd : 1;
- unsigned char jlc_exists_in_prepost_cmd : 1;
- unsigned char jlc_exists_in_cell_cmd : 1;
- unsigned char multi_or_random_pgc_title : 1;
- unsigned char zero_1 : 1;
+ unsigned BITFIELD_TYPE title_or_time_play : 1;
+ unsigned BITFIELD_TYPE chapter_search_or_play : 1;
+ unsigned BITFIELD_TYPE jlc_exists_in_tt_dom : 1;
+ unsigned BITFIELD_TYPE jlc_exists_in_button_cmd : 1;
+ unsigned BITFIELD_TYPE jlc_exists_in_prepost_cmd : 1;
+ unsigned BITFIELD_TYPE jlc_exists_in_cell_cmd : 1;
+ unsigned BITFIELD_TYPE multi_or_random_pgc_title : 1;
+ unsigned BITFIELD_TYPE zero_1 : 1;
#endif
} ATTRIBUTE_PACKED playback_type_t;
=20
@@ -602,7 +619,7 @@
uint32_t last_byte;
title_info_t *title;
} ATTRIBUTE_PACKED tt_srpt_t;
-#define TT_SRPT_SIZE 8
+#define TT_SRPT_SIZE 8U
=20
=20
/**
@@ -621,7 +638,7 @@
uint16_t zero_2;
pf_level_t *pf_ptl_mai; /* table of (nr_of_vtss + 1), video_ts is firs=
t */
} ATTRIBUTE_PACKED ptl_mait_country_t;
-#define PTL_MAIT_COUNTRY_SIZE 8
+#define PTL_MAIT_COUNTRY_SIZE 8U
=20
/**
* Parental Management Information Table.
@@ -632,7 +649,7 @@
uint32_t last_byte;
ptl_mait_country_t *countries;
} ATTRIBUTE_PACKED ptl_mait_t;
-#define PTL_MAIT_SIZE 8
+#define PTL_MAIT_SIZE 8U
=20
/**
* Video Title Set Attributes.
@@ -663,8 +680,8 @@
uint8_t nr_of_vtstt_subp_streams;
subp_attr_t vtstt_subp_attr[32];
} ATTRIBUTE_PACKED vts_attributes_t;
-#define VTS_ATTRIBUTES_SIZE 542
-#define VTS_ATTRIBUTES_MIN_SIZE 356
+#define VTS_ATTRIBUTES_SIZE 542U
+#define VTS_ATTRIBUTES_MIN_SIZE 356U
=20
/**
* Video Title Set Attribute Table.
@@ -676,7 +693,7 @@
vts_attributes_t *vts;
uint32_t *vts_atrt_offsets; /* offsets table for each vts_attributes *=
/
} ATTRIBUTE_PACKED vts_atrt_t;
-#define VTS_ATRT_SIZE 8
+#define VTS_ATRT_SIZE 8U
=20
/**
* Text Data. (Incomplete)
@@ -709,7 +726,7 @@
uint32_t txtdt_start_byte; /* prt, rel start of vmg_txtdt_mgi */
txtdt_t *txtdt;
} ATTRIBUTE_PACKED txtdt_lu_t;
-#define TXTDT_LU_SIZE 8
+#define TXTDT_LU_SIZE 8U
=20
/**
* Text Data Manager Information. (Incomplete)
@@ -720,7 +737,7 @@
uint32_t last_byte;
txtdt_lu_t *lu;
} ATTRIBUTE_PACKED txtdt_mgi_t;
-#define TXTDT_MGI_SIZE 20
+#define TXTDT_MGI_SIZE 20U
=20
=20
/**
@@ -812,7 +829,7 @@
ttu_t *title;
uint32_t *ttu_offset; /* offset table for each ttu */
} ATTRIBUTE_PACKED vts_ptt_srpt_t;
-#define VTS_PTT_SRPT_SIZE 8
+#define VTS_PTT_SRPT_SIZE 8U
=20
=20
/**
@@ -830,7 +847,7 @@
uint16_t nr_of_entries;
map_ent_t *map_ent;
} ATTRIBUTE_PACKED vts_tmap_t;
-#define VTS_TMAP_SIZE 4
+#define VTS_TMAP_SIZE 4U
=20
/**
* Time Map Table.
@@ -842,7 +859,7 @@
vts_tmap_t *tmap;
uint32_t *tmap_offset; /* offset table for each tmap */
} ATTRIBUTE_PACKED vts_tmapt_t;
-#define VTS_TMAPT_SIZE 8
+#define VTS_TMAPT_SIZE 8U
=20
=20
#if PRAGMA_PACK
Modified: trunk/DvdMenuXtractor/libdvdread/dvdread/nav_print.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/dvdread/nav_print.c 2007-01-22 11:21=
:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/dvdread/nav_print.c 2007-01-28 16:48=
:11 UTC (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2000, 2001, 2002, 2003 H=E5kan Hjort <d95hjort at dtek.cha=
lmers.se>
*
@@ -26,10 +27,16 @@
#include "config.h"
=20
#include <stdio.h>
+
+#if defined(HAVE_INTTYPES_H)
#include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
=20
#include "nav_types.h"
#include "nav_print.h"
+#include "cmd_print.h"
#include "dvdread_internal.h"
=20
static void print_time(dvd_time_t *dtime) {
@@ -40,10 +47,10 @@
CHECK_VALUE((dtime->frame_u&0xf) < 0xa);
=20
printf("%02x:%02x:%02x.%02x",=20
- dtime->hour,
- dtime->minute,
- dtime->second,
- dtime->frame_u & 0x3f);
+ dtime->hour,
+ dtime->minute,
+ dtime->second,
+ dtime->frame_u & 0x3f);
switch((dtime->frame_u & 0xc0) >> 6) {
case 1:
rate =3D "25.00";
@@ -96,7 +103,7 @@
for(i =3D 0; i < 9; i++)
if(nsml_agli->nsml_agl_dsta[i])
printf("nsml_agl_c%d_dsta 0x%08x\n", i + 1,=20
- nsml_agli->nsml_agl_dsta[i]);
+ nsml_agli->nsml_agl_dsta[i]);
}
=20
static void navPrint_HL_GI(hl_gi_t *hl_gi, int *btngr_ns, int *btn_ns) {
@@ -137,8 +144,8 @@
for(i =3D 0; i < 3; i++)
for(j =3D 0; j < 2; j++)
printf("btn_cqoli %d %s_coli: %08x\n",
- i, (j =3D=3D 0) ? "sl" : "ac",
- btn_colit->btn_coli[i][j]);
+ i, (j =3D=3D 0) ? "sl" : "ac",
+ btn_colit->btn_coli[i][j]);
}
=20
static void navPrint_BTNIT(btni_t *btni_table, int btngr_ns, int btn_ns)=
{
@@ -154,21 +161,21 @@
for(i =3D 0; i < btngr_ns; i++) {
for(j =3D 0; j < (36 / btngr_ns); j++) {
if(j < btn_ns) {
- btni_t *btni =3D &btni_table[(36 / btngr_ns) * i + j];
-=09
- printf("group %d btni %d: ", i+1, j+1);
- printf("btn_coln %d, auto_action_mode %d\n",
- btni->btn_coln, btni->auto_action_mode);
- printf("coords (%d, %d) .. (%d, %d)\n",
- btni->x_start, btni->y_start, btni->x_end, btni->y_end);
-=09
- printf("up %d, ", btni->up);
- printf("down %d, ", btni->down);
- printf("left %d, ", btni->left);
- printf("right %d\n", btni->right);
-=09
- /* ifoPrint_COMMAND(&btni->cmd); */
- printf("\n");
+ btni_t *btni =3D &btni_table[(36 / btngr_ns) * i + j];
+ =20
+ printf("group %d btni %d: ", i+1, j+1);
+ printf("btn_coln %d, auto_action_mode %d\n",
+ btni->btn_coln, btni->auto_action_mode);
+ printf("coords (%d, %d) .. (%d, %d)\n",
+ btni->x_start, btni->y_start, btni->x_end, btni->y_end);
+ =20
+ printf("up %d, ", btni->up);
+ printf("down %d, ", btni->down);
+ printf("left %d, ", btni->left);
+ printf("right %d\n", btni->right);
+ =20
+ cmdPrint_CMD(0, &btni->cmd);
+ printf("\n");
}
}
}
@@ -232,14 +239,14 @@
printf("sml_agli:\n");
for(i =3D 0; i < 9; i++) {
printf("agl_c%d address: 0x%08x size 0x%04x\n", i,
- sml_agli->data[i].address, sml_agli->data[i].size);
+ sml_agli->data[i].address, sml_agli->data[i].size);
}
}
=20
static void navPrint_VOBU_SRI(vobu_sri_t *vobu_sri) {
int i;
int stime[19] =3D { 240, 120, 60, 20, 15, 14, 13, 12, 11,=20
- 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
+ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
printf("vobu_sri:\n");
printf("Next VOBU with Video %08x\n", vobu_sri->next_video);
for(i =3D 0; i < 19; i++) {
Modified: trunk/DvdMenuXtractor/libdvdread/dvdread/nav_read.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/dvdread/nav_read.c 2007-01-22 11:21:=
16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/dvdread/nav_read.c 2007-01-28 16:48:=
11 UTC (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2000, 2001, 2002, 2003 H=E5kan Hjort <d95hjort at dtek.cha=
lmers.se>
*
@@ -20,7 +21,11 @@
=20
#include <stdio.h>
#include <string.h>
+#if defined(HAVE_INTTYPES_H)
#include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
=20
#include "bswap.h"
#include "nav_types.h"
@@ -28,7 +33,7 @@
#include "dvdread_internal.h"
=20
void navRead_PCI(pci_t *pci, unsigned char *buffer) {
- int i, j;
+ unsigned int i, j;
=20
CHECK_VALUE(sizeof(pci_t) =3D=3D PCI_BYTES - 1); // -1 for substream i=
d
=20
@@ -105,7 +110,7 @@
CHECK_VALUE(pci->hli.hl_gi.btngr_ns !=3D 0);=20
} else {
CHECK_VALUE((pci->hli.hl_gi.btn_ns !=3D 0 && pci->hli.hl_gi.btngr_ns=
!=3D 0)=20
- || (pci->hli.hl_gi.btn_ns =3D=3D 0 && pci->hli.hl_gi.btngr_ns =3D=3D=
0));
+ || (pci->hli.hl_gi.btn_ns =3D=3D 0 && pci->hli.hl_gi.btn=
gr_ns =3D=3D 0));
}
=20
/* pci hli btnit */
@@ -119,28 +124,28 @@
CHECK_VALUE(pci->hli.btnit[n].zero5 =3D=3D 0);
CHECK_VALUE(pci->hli.btnit[n].zero6 =3D=3D 0);
=20
- if (j < pci->hli.hl_gi.btn_ns) {=09
- CHECK_VALUE(pci->hli.btnit[n].x_start <=3D pci->hli.btnit[n].x_end);
- CHECK_VALUE(pci->hli.btnit[n].y_start <=3D pci->hli.btnit[n].y_end);
- CHECK_VALUE(pci->hli.btnit[n].up <=3D pci->hli.hl_gi.btn_ns);
- CHECK_VALUE(pci->hli.btnit[n].down <=3D pci->hli.hl_gi.btn_ns);
- CHECK_VALUE(pci->hli.btnit[n].left <=3D pci->hli.hl_gi.btn_ns);
- CHECK_VALUE(pci->hli.btnit[n].right <=3D pci->hli.hl_gi.btn_ns);
- //vmcmd_verify(pci->hli.btnit[n].cmd);
+ if (j < pci->hli.hl_gi.btn_ns) { =20
+ CHECK_VALUE(pci->hli.btnit[n].x_start <=3D pci->hli.btnit[n].x_e=
nd);
+ CHECK_VALUE(pci->hli.btnit[n].y_start <=3D pci->hli.btnit[n].y_e=
nd);
+ CHECK_VALUE(pci->hli.btnit[n].up <=3D pci->hli.hl_gi.btn_ns);
+ CHECK_VALUE(pci->hli.btnit[n].down <=3D pci->hli.hl_gi.btn_ns);
+ CHECK_VALUE(pci->hli.btnit[n].left <=3D pci->hli.hl_gi.btn_ns);
+ CHECK_VALUE(pci->hli.btnit[n].right <=3D pci->hli.hl_gi.btn_ns);
+ //vmcmd_verify(pci->hli.btnit[n].cmd);
} else {
- int k;
- CHECK_VALUE(pci->hli.btnit[n].btn_coln =3D=3D 0);
- CHECK_VALUE(pci->hli.btnit[n].auto_action_mode =3D=3D 0);
- CHECK_VALUE(pci->hli.btnit[n].x_start =3D=3D 0);
- CHECK_VALUE(pci->hli.btnit[n].y_start =3D=3D 0);
- CHECK_VALUE(pci->hli.btnit[n].x_end =3D=3D 0);
- CHECK_VALUE(pci->hli.btnit[n].y_end =3D=3D 0);
- CHECK_VALUE(pci->hli.btnit[n].up =3D=3D 0);
- CHECK_VALUE(pci->hli.btnit[n].down =3D=3D 0);
- CHECK_VALUE(pci->hli.btnit[n].left =3D=3D 0);
- CHECK_VALUE(pci->hli.btnit[n].right =3D=3D 0);
- for (k =3D 0; k < 8; k++)
- CHECK_VALUE(pci->hli.btnit[n].cmd.bytes[k] =3D=3D 0); //CHECK_ZERO?
+ int k;
+ CHECK_VALUE(pci->hli.btnit[n].btn_coln =3D=3D 0);
+ CHECK_VALUE(pci->hli.btnit[n].auto_action_mode =3D=3D 0);
+ CHECK_VALUE(pci->hli.btnit[n].x_start =3D=3D 0);
+ CHECK_VALUE(pci->hli.btnit[n].y_start =3D=3D 0);
+ CHECK_VALUE(pci->hli.btnit[n].x_end =3D=3D 0);
+ CHECK_VALUE(pci->hli.btnit[n].y_end =3D=3D 0);
+ CHECK_VALUE(pci->hli.btnit[n].up =3D=3D 0);
+ CHECK_VALUE(pci->hli.btnit[n].down =3D=3D 0);
+ CHECK_VALUE(pci->hli.btnit[n].left =3D=3D 0);
+ CHECK_VALUE(pci->hli.btnit[n].right =3D=3D 0);
+ for (k =3D 0; k < 8; k++)
+ CHECK_VALUE(pci->hli.btnit[n].cmd.bytes[k] =3D=3D 0); //CHECK_=
ZERO?
}
}
}
Modified: trunk/DvdMenuXtractor/libdvdread/dvdread/nav_types.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/dvdread/nav_types.h 2007-01-22 11:21=
:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/dvdread/nav_types.h 2007-01-28 16:48=
:11 UTC (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
#ifndef NAV_TYPES_H_INCLUDED
#define NAV_TYPES_H_INCLUDED
=20
@@ -29,10 +30,9 @@
* USA
*/
=20
-#include <inttypes.h>
#include <dvdread/ifo_types.h> /* only dvd_time_t, vm_cmd_t and user_ops=
_t */
+/* If it's ever removed add a uintX_t test. */
=20
-
#undef ATTRIBUTE_PACKED
#undef PRAGMA_PACK_BEGIN=20
#undef PRAGMA_PACK_END
@@ -103,23 +103,23 @@
uint32_t hli_e_ptm; /**< end ptm of hli */
uint32_t btn_se_e_ptm; /**< end ptm of button select */
#ifdef WORDS_BIGENDIAN
- unsigned char zero1 : 2; /**< reserved */
- unsigned char btngr_ns : 2; /**< number of button groups 1, 2 or=
3 with 36/18/12 buttons */
- unsigned char zero2 : 1; /**< reserved */
- unsigned char btngr1_dsp_ty : 3; /**< display type of subpic stream f=
or button group 1 */
- unsigned char zero3 : 1; /**< reserved */
- unsigned char btngr2_dsp_ty : 3; /**< display type of subpic stream f=
or button group 2 */
- unsigned char zero4 : 1; /**< reserved */
- unsigned char btngr3_dsp_ty : 3; /**< display type of subpic stream f=
or button group 3 */
+ unsigned int zero1 : 2; /**< reserved */
+ unsigned int btngr_ns : 2; /**< number of button groups 1, 2 or =
3 with 36/18/12 buttons */
+ unsigned int zero2 : 1; /**< reserved */
+ unsigned int btngr1_dsp_ty : 3; /**< display type of subpic stream fo=
r button group 1 */
+ unsigned int zero3 : 1; /**< reserved */
+ unsigned int btngr2_dsp_ty : 3; /**< display type of subpic stream fo=
r button group 2 */
+ unsigned int zero4 : 1; /**< reserved */
+ unsigned int btngr3_dsp_ty : 3; /**< display type of subpic stream fo=
r button group 3 */
#else
- unsigned char btngr1_dsp_ty : 3;
- unsigned char zero2 : 1;
- unsigned char btngr_ns : 2;
- unsigned char zero1 : 2;
- unsigned char btngr3_dsp_ty : 3;
- unsigned char zero4 : 1;
- unsigned char btngr2_dsp_ty : 3;
- unsigned char zero3 : 1;
+ unsigned int btngr1_dsp_ty : 3;
+ unsigned int zero2 : 1;
+ unsigned int btngr_ns : 2;
+ unsigned int zero1 : 2;
+ unsigned int btngr3_dsp_ty : 3;
+ unsigned int zero4 : 1;
+ unsigned int btngr2_dsp_ty : 3;
+ unsigned int zero3 : 1;
#endif
uint8_t btn_ofn; /**< button offset number range 0-255 */
uint8_t btn_ns; /**< number of valid buttons <=3D 36/18/12 (low =
6 bits) */ =20
@@ -166,10 +166,10 @@
=20
unsigned int zero4 : 2; /**< reserved */
unsigned int down : 6; /**< button index when pressing do=
wn */
- unsigned char zero5 : 2; /**< reserved */
- unsigned char left : 6; /**< button index when pressing l=
eft */
- unsigned char zero6 : 2; /**< reserved */
- unsigned char right : 6; /**< button index when pressing r=
ight */
+ unsigned int zero5 : 2; /**< reserved */
+ unsigned int left : 6; /**< button index when pressing le=
ft */
+ unsigned int zero6 : 2; /**< reserved */
+ unsigned int right : 6; /**< button index when pressing ri=
ght */
#else
unsigned int x_end : 10;
unsigned int zero1 : 2;
@@ -186,10 +186,10 @@
=20
unsigned int down : 6;
unsigned int zero4 : 2;
- unsigned char left : 6;
- unsigned char zero5 : 2;
- unsigned char right : 6;
- unsigned char zero6 : 2;
+ unsigned int left : 6;
+ unsigned int zero5 : 2;
+ unsigned int right : 6;
+ unsigned int zero6 : 2;
#endif
vm_cmd_t cmd;
} ATTRIBUTE_PACKED btni_t;
@@ -254,8 +254,8 @@
* Seamless Angle Infromation for one angle
*/
typedef struct {
- uint32_t address; /**< offset to next ILVU, high bit is before/after=
*/
- uint16_t size; /**< byte size of the ILVU pointed to by address *=
/
+ uint32_t address; /**< offset to next ILVU, high bit is before/after *=
/
+ uint16_t size; /**< byte size of the ILVU pointed to by address */
} ATTRIBUTE_PACKED sml_agl_data_t;
=20
/**
Deleted: trunk/DvdMenuXtractor/libdvdread/libdvdread.bkl
Added: trunk/DvdMenuXtractor/libdvdread/libdvdread.proj
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/libdvdread.proj 2007-01-22 11:21:16 =
UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/libdvdread.proj 2007-01-28 16:48:11 =
UTC (rev 1270)
@@ -0,0 +1,11 @@
+#include "*/*.proj"
+
+WORKSPACE dvdread
+{
+ USE dvdread
+ USE disc_id
+ USE filestat
+ USE ifo_dump
+ USE play_title
+ USE title_info
+}
Modified: trunk/DvdMenuXtractor/libdvdread/src/disc_id.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/src/disc_id.c 2007-01-22 11:21:16 UT=
C (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/src/disc_id.c 2007-01-28 16:48:11 UT=
C (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2000 Bj=F6rn Englund <d4bjorn at dtek.chalmers.se>,
* H=E5kan Hjort <d95hjort at dtek.chalmers.se>
@@ -17,16 +18,18 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
-
-#include "config.h"
=20
+#include "config.h"
+
#include <stdio.h>
-#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
+#include <stdlib.h>
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
#endif
+#include <errno.h>
+#include <string.h>
=20
-#include <dvdread/ifo_print.h>
+#include <dvdread/dvd_reader.h>
=20
static char *program_name;
=20
@@ -38,6 +41,7 @@
int main(int argc, char *argv[])
{
int i;
+ int err =3D 0;
unsigned char disc_id[16];
dvd_reader_t *dvd;
=20
@@ -49,21 +53,27 @@
}
=20
dvd =3D DVDOpen( argv[ 1 ] );
- if( !dvd ) {
- fprintf( stderr, "Can't open disc %s!\n", argv[ 1 ] );
- return -1;
- }
+ if( dvd ) {
+ if( DVDDiscID( dvd, disc_id ) =3D=3D 0) {
+ for(i =3D 0; i < 16; i++) {
+ printf( "%02x", disc_id[i] );
+ }
+ printf( "\n" );
+ } else {
+ fprintf( stderr, "Error getting disc id from disc '%s': %s\n",
+ argv[ 1 ], strerror(errno) );
+ =20
+ err =3D -1;
+ }
=20
- if( DVDDiscID( dvd, disc_id ) !=3D 0) {
- fprintf( stderr, "Error getting disc id from disc %s!\n", argv[ 1 ] =
);
- return -1;
+ DVDClose(dvd);
+ } else {
+ fprintf( stderr, "Can't open disc '%s': %s\n",
+ argv[ 1 ], strerror(errno) );
+ err =3D -1;
}
=20
- for(i =3D 0; i < 16; i++) {
- printf( "%02x", disc_id[i] );
- }
- printf( "\n" );
-
- return 0; =20
+ DVDFinish();
+ return err; =20
}
=20
Added: trunk/DvdMenuXtractor/libdvdread/src/filestat.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/src/filestat.c 2007-01-22 11:21:16 U=
TC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/src/filestat.c 2007-01-28 16:48:11 U=
TC (rev 1270)
@@ -0,0 +1,182 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 2006 Bj=F6rn Englund <d4bjorn at dtek.chalmers.se>
+ *=20
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+/*
+ * This program is a demo of the DVDFileStat() call.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <errno.h>
+#include <string.h>
+#if defined(HAVE_INTTYPES_H)
+#include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
+
+#include <dvdread/dvd_reader.h>
+#include <dvdread/ifo_read.h>
+
+static char *program_name;
+
+void usage(void)
+{
+ fprintf(stderr, "Usage: %s <dvd path>\n", program_name);
+}
+
+
+void print_stat(dvd_stat_t *buf)
+{
+ =20
+ printf("size: %lld", buf->size);
+ if(buf->nr_parts > 1) {
+ int n;
+ for(n =3D 0; n < buf->nr_parts; n++) {
+ printf(", [%lld]", buf->parts_size[n]);
+ }
+ }
+}
+
+void print_size(dvd_reader_t *dvd, int titlenum,=20
+ dvd_read_domain_t dom)=20
+{
+ dvd_stat_t buf;
+ char filename[256];
+ =20
+ if(titlenum =3D=3D 0) {
+ switch(dom) {
+ case DVD_READ_INFO_FILE:
+#if defined(_CRT_SECURE_NO_DEPRECAT)
+ sprintf(filename, "VIDEO_TS.IFO");
+#else
+ sprintf_s(filename, 256, "VIDEO_TS.IFO");
+#endif
+ break;
+ case DVD_READ_INFO_BACKUP_FILE:
+#if defined(_CRT_SECURE_NO_DEPRECAT)
+ sprintf(filename, "VIDEO_TS.BUP");
+#else
+ sprintf_s(filename, 256, "VIDEO_TS.BUP");
+#endif
+ break;
+ case DVD_READ_MENU_VOBS:
+ sprintf(filename, "VIDEO_TS.VOB");
+ break;
+ default:
+ sprintf(filename, "illegal");
+ }
+ } else {
+ switch(dom) {
+ case DVD_READ_INFO_FILE:
+ sprintf(filename, "VTS_%02d_0.IFO", titlenum);
+ break;
+ case DVD_READ_INFO_BACKUP_FILE:
+ sprintf(filename, "VTS_%02d_0.BUP", titlenum);
+ break;
+ case DVD_READ_MENU_VOBS:
+ sprintf(filename, "VTS_%02d_0.VOB", titlenum);
+ break;
+ case DVD_READ_TITLE_VOBS:
+ sprintf(filename, "VTS_%02d_[1-9].VOB", titlenum);
+ break;
+ default:
+ sprintf(filename, "illegal");
+ } =20
+ }
+
+ if(!DVDFileStat(dvd, titlenum, dom, &buf)) {
+ printf("\n%s: ", filename);
+ print_stat(&buf);
+ } else {
+ fprintf(stderr, "stat(%s): %s\n", filename, strerror(errno));
+ }
+}
+
+
+int main(int argc, char *argv[])
+{
+ //int i;
+ int err =3D 0;
+
+ dvd_reader_t *dvd;
+
+ program_name =3D argv[0];
+ =20
+ if(argc !=3D 2) {
+ usage();
+ return 1;
+ }
+
+ dvd =3D DVDOpen( argv[ 1 ] );
+
+ if( dvd ) {
+ ifo_handle_t *vmg_ifo;
+ int title_sets;
+ //dvd_stat_t buf;
+ int n;
+
+
+ vmg_ifo =3D ifoOpen( dvd, 0);
+ if(!vmg_ifo) {
+ return 1;
+ }
+
+ title_sets =3D vmg_ifo->vmgi_mat->vmg_nr_of_title_sets;
+ =20
+ ifoClose(vmg_ifo);
+
+ // VIDEO_TS.IFO
+ print_size(dvd, 0, DVD_READ_INFO_FILE);
+ // VIDEO_TS.VOB
+ print_size(dvd, 0, DVD_READ_MENU_VOBS);
+ // VIDEO_TS.BUP
+ print_size(dvd, 0, DVD_READ_INFO_BACKUP_FILE);
+
+ for(n =3D 0; n < title_sets; n++) {
+ // foreach titleset
+ // VTS_??_0.IFO
+ print_size(dvd, n+1, DVD_READ_INFO_FILE);
+ // VTS_??_0.VOB
+ print_size(dvd, n+1, DVD_READ_MENU_VOBS);
+ // VTS_??_[1-9].VOB
+ print_size(dvd, n+1, DVD_READ_TITLE_VOBS);
+ // VTS_??_0.BUP
+ print_size(dvd, n+1, DVD_READ_INFO_BACKUP_FILE);
+ }
+ printf("\n");
+ DVDClose(dvd);
+ } else {
+ fprintf( stderr, "Can't open disc '%s': %s\n",
+ argv[ 1 ], strerror(errno) );
+ err =3D -1;
+ }
+
+ DVDFinish();
+
+ return err; =20
+}
+
Modified: trunk/DvdMenuXtractor/libdvdread/src/ifo_dump.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/src/ifo_dump.c 2007-01-22 11:21:16 U=
TC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/src/ifo_dump.c 2007-01-28 16:48:11 U=
TC (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2000 Bj=F6rn Englund <d4bjorn at dtek.chalmers.se>,
* H=E5kan Hjort <d95hjort at dtek.chalmers.se>
@@ -17,15 +18,22 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
-
-#include "config.h"
=20
+#include "config.h"
+
#include <stdio.h>
#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
#endif
=20
+#if defined(HAVE_INTTYPES_H)
+#include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
+
+#include <dvdread/dvd_reader.h>
#include <dvdread/ifo_print.h>
=20
static char *program_name;
@@ -52,7 +60,9 @@
}
=20
ifoPrint( dvd, atoi( argv[ 2 ] ) );
+ DVDClose(dvd);
=20
+ DVDFinish(); //to keep memory checkers from complaining=20
return 0; =20
}
=20
Modified: trunk/DvdMenuXtractor/libdvdread/src/play_title.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/src/play_title.c 2007-01-22 11:21:16=
UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/src/play_title.c 2007-01-28 16:48:11=
UTC (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2001 Billy Biggs <vektor at dumbterm.net>.
*
@@ -16,10 +17,18 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
=20
+#include "config.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
=20
+#if defined(HAVE_INTTYPES_H)
+#include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
+
#include <dvdread/dvd_reader.h>
#include <dvdread/ifo_types.h>
#include <dvdread/ifo_read.h>
@@ -287,6 +296,7 @@
ifoClose( vmg_file );
DVDCloseFile( title );
DVDClose( dvd );
+ DVDFinish();
return 0;
}
=20
Added: trunk/DvdMenuXtractor/libdvdread/src/src.proj
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/src/src.proj 2007-01-22 11:21:16 UTC=
(rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/src/src.proj 2007-01-28 16:48:11 UTC=
(rev 1270)
@@ -0,0 +1,51 @@
+#include "*/*.proj"
+
+CON disc_id
+{
+ USE dvdread
+
+ SOURCE disc_id.c
+ =20
+ INCLUDE(TARGET_WIN) ../win32
+ INCLUDE ..
+}
+
+CON filestat
+{
+ USE dvdread
+
+ SOURCE filestat.c
+ =20
+ INCLUDE(TARGET_WIN) ../win32
+ INCLUDE ..
+}
+
+CON ifo_dump
+{
+ USE dvdread
+
+ SOURCE ifo_dump.c
+ =20
+ INCLUDE(TARGET_WIN) ../win32
+ INCLUDE ..
+}
+
+CON play_title
+{
+ USE dvdread
+
+ SOURCE play_title.c
+ =20
+ INCLUDE(TARGET_WIN) ../win32
+ INCLUDE ..
+}
+
+CON title_info
+{
+ USE dvdread
+
+ SOURCE title_info.c
+ =20
+ INCLUDE(TARGET_WIN) ../win32
+ INCLUDE ..
+}
Modified: trunk/DvdMenuXtractor/libdvdread/src/title_info.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/src/title_info.c 2007-01-22 11:21:16=
UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/src/title_info.c 2007-01-28 16:48:11=
UTC (rev 1270)
@@ -1,3 +1,4 @@
+/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2001 Billy Biggs <vektor at dumbterm.net>,
* H=E5kan Hjort <d95hjort at dtek.chalmers.se>
@@ -17,14 +18,20 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
=20
+#include "config.h"
+
#include <stdio.h>
=20
+#if defined(HAVE_INTTYPES_H)
+#include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
+
#include <dvdread/dvd_reader.h>
#include <dvdread/ifo_types.h>
#include <dvdread/ifo_read.h>
=20
-void myfprintf(FILE * f, const char * format, ...){}
-
int main( int argc, char **argv )
{
dvd_reader_t *dvd;
@@ -88,14 +95,10 @@
cur_pgc =3D vts_file->vts_pgcit->pgci_srp[ pgcnum - 1 ].pgc;
start_cell =3D cur_pgc->program_map[ pgn - 1 ] - 1;
=09
- printf( "\tChapter %3d [PGC %2d, PG %2d] starts at Cell %2d =
[sector %x-%x] Duration: %2d:%2d:%2d\n",
+ printf( "\tChapter %3d [PGC %2d, PG %2d] starts at Cell %2d =
[sector %x-%x]\n",
j, pgcnum, pgn, start_cell,
cur_pgc->cell_playback[ start_cell ].first_sector,
- cur_pgc->cell_playback[ start_cell ].last_sector,
- (unsigned int)cur_pgc->playback_time.hour,
- (unsigned int)cur_pgc->playback_time.minute,
- (unsigned int)cur_pgc->playback_time.second
- );
+ cur_pgc->cell_playback[ start_cell ].last_sector );
}
=20
ifoClose( vts_file );
@@ -103,6 +106,7 @@
=20
ifoClose( ifo_file );
DVDClose( dvd );
+ DVDFinish();
return 0;
}
=20
Modified: trunk/DvdMenuXtractor/libdvdread/win32/config.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/win32/config.h 2007-01-22 11:21:16 U=
TC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/win32/config.h 2007-01-28 16:48:11 U=
TC (rev 1270)
@@ -1,4 +1,4 @@
-/* config.h.in. Generated from configure.in by autoheader. */
+/* config.h. Generated manually from config.h.in */
=20
/* Define to 1 if you have the <byteswap.h> header file. */
#undef HAVE_BYTESWAP_H
@@ -10,27 +10,25 @@
#undef HAVE_DVDCSS_DVDCSS_H
=20
/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
+#define HAVE_INTTYPES_H 1
=20
/* Define to 1 if you have the <limits.h> header file. */
-#undef HAVE_LIMITS_H
-
-#define HAVE_MEMCPY 1
+#define HAVE_LIMITS_H 1
=20
/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
+#define HAVE_MEMORY_H 1
=20
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
=20
/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
+#define HAVE_STDLIB_H 1
=20
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
=20
/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
+#define HAVE_STRING_H 1
=20
/* Define to 1 if you have the <sys/bswap.h> header file. */
#undef HAVE_SYS_BSWAP_H
@@ -38,9 +36,6 @@
/* Define to 1 if you have the <sys/endian.h> header file. */
#undef HAVE_SYS_ENDIAN_H
=20
-/* Define to 1 if you have the <sys/ioctl.h> header file. */
-#undef HAVE_SYS_IOCTL_H
-
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
=20
@@ -50,44 +45,35 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
=20
+/* Define to 1 if the system has the type `uintptr_t'. */
+#define HAVE_UINTPTR_T 1
+
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
=20
/* Name of package */
-#undef PACKAGE
+#define PACKAGE libdvdread-1.9.7
=20
/* Define to the address where bug reports for this package should be se=
nt. */
#undef PACKAGE_BUGREPORT
=20
/* Define to the full name of this package. */
-#undef PACKAGE_NAME
+#define PACKAGE_NAME libdvdread
=20
/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
+#define PACKAGE_STRING libdvdread-1.9.7
=20
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
=20
/* Define to the version of this package. */
-#undef PACKAGE_VERSION
+#define PACKAGE_VERSION 1.9.7
=20
-/* The size of a `char', as computed by sizeof. */
-#undef SIZEOF_CHAR
-
-/* The size of a `int', as computed by sizeof. */
-#undef SIZEOF_INT
-
-/* The size of a `long long', as computed by sizeof. */
-#undef SIZEOF_LONG_LONG
-
-/* The size of a `short', as computed by sizeof. */
-#undef SIZEOF_SHORT
-
/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
+#define STDC_HEADERS 1
=20
/* Version number of package */
-#undef VERSION
+#define VERSION 1.9.7
=20
/* Define to 1 if your processor stores words with the most significant =
byte
first (like Motorola and SPARC, unlike Intel and VAX). */
@@ -97,19 +83,13 @@
#undef __DARWIN__
=20
/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
+//#undef const
=20
-/* Define as `__inline' if that's what the C compiler calls it, or to no=
thing
- if it is not supported. */
-#define inline
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. =
*/
+#ifndef __cplusplus
+#define inline __inline
+#endif
=20
/* Define to `unsigned' if <sys/types.h> does not define. */
-/* #undef size_t */
-
-#define _POSIX_ /* for PATH_MAX */
-#include <limits.h>
-#undef _POSIX_
-
-#ifndef LOG_ERROR
-#define LOG_ERROR fprintf
-#endif
+//#undef size_t
Modified: trunk/DvdMenuXtractor/libdvdread/win32/dirent.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/win32/dirent.c 2007-01-22 11:21:16 U=
TC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/win32/dirent.c 2007-01-28 16:48:11 U=
TC (rev 1270)
@@ -92,7 +92,7 @@
if (nd->dd_name[0] !=3D _T ('\0') &&
nd->dd_name[_tcslen (nd->dd_name) - 1] !=3D _T ('/') &&
nd->dd_name[_tcslen (nd->dd_name) - 1] !=3D _T ('\\')) {
- _tcscat (nd->dd_name, SLASH);
+ _tcscat_s (nd->dd_name, MAX_PATH, SLASH);
}
=20
/* Add on the search pattern */
Modified: trunk/DvdMenuXtractor/libdvdread/win32/gtchar.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/win32/gtchar.h 2007-01-22 11:21:16 U=
TC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/win32/gtchar.h 2007-01-28 16:48:11 U=
TC (rev 1270)
@@ -111,9 +111,11 @@
#define _ttoi _wtoi
#define _ttol _wtol
#define _tcscat wcscat
+#define _tcscat_s wcscat_s
#define _tcschr wcschr
#define _tcscmp wcscmp
#define _tcscpy wcscpy
+#define _tcscpy_s wcscpy_s
#define _tcscspn wcscspn
#define _tcslen wcslen
#define _tcsncat wcsncat
@@ -287,9 +289,11 @@
#define _ttoi atoi
#define _ttol atol
#define _tcscat strcat
+#define _tcscat_s strcat_s
#define _tcschr strchr
#define _tcscmp strcmp
#define _tcscpy strcpy
+#define _tcscpy_s strcpy_s
#define _tcscspn strcspn
#define _tcslen strlen
#define _tcsncat strncat
Modified: trunk/DvdMenuXtractor/libdvdread/win32/inttypes.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/win32/inttypes.h 2007-01-22 11:21:16=
UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/win32/inttypes.h 2007-01-28 16:48:11=
UTC (rev 1270)
@@ -1,44 +1,303 @@
-#ifndef _LOCAL_INTTYPES_H_
-#define _LOCAL_INTTYPES_H_
+// ISO C9x compliant inttypes.h for Miscrosoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124=20
+//=20
+// Copyright (c) 2006 Alexander Chemeris
+//=20
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions ar=
e met:
+//=20
+// 1. Redistributions of source code must retain the above copyright n=
otice,
+// this list of conditions and the following disclaimer.
+//=20
+// 2. Redistributions in binary form must reproduce the above copyrigh=
t
+// notice, this list of conditions and the following disclaimer in =
the
+// documentation and/or other materials provided with the distribut=
ion.
+//=20
+// 3. The name of the author may be used to endorse or promote product=
s
+// derived from this software without specific prior written permis=
sion.
+//=20
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR =
IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. =
IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL=
,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMI=
TED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PR=
OFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILI=
TY,=20
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE =
OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN I=
F
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//=20
+////////////////////////////////////////////////////////////////////////=
///////
=20
-
-#if defined(WIN32)
-#include <windows.h>
-
-typedef unsigned char uint8_t;
-typedef unsigned short int uint16_t;
-typedef unsigned int uint32_t;
-typedef unsigned __int64 uint64_t;
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
=20
-typedef unsigned int ssize_t;
-typedef __int64 int64_t;
-typedef int int32_t;
-typedef short int16_t;
+#ifndef _MSC_INTTYPES_H_ // [
+#define _MSC_INTTYPES_H_
=20
-#define strcasecmp(x,y) stricmp(x,y)
-#define strncasecmp(x,y,z) strnicmp(x,y,z)
+#if _MSC_VER > 1000
+#pragma once
+#endif
=20
-#ifndef S_ISREG
-#define S_ISREG(mode) (0)
+#include "stdint.h"
+
+#ifdef __cplusplus
+extern "C" {
#endif
-#ifndef S_ISDIR
-#define S_ISDIR(mode) ((mode)&_S_IFDIR)
-#endif
-#ifndef S_ISCHR
-#define S_ISCHR(mode) (0)
-#endif
-#ifndef S_ISSOCK
-#define S_ISSOCK(x) (0)
-#endif
-#ifndef S_ISBLK
-#define S_ISBLK(x) (0)
-#endif
=20
-#define dlclose(x) FreeLibrary(x)
-#define dlsym(x,y) GetProcAddress(x,y)
+// 7.8 Format conversion of integer types
=20
-#else /* !WIN32 */
-#include <inttypes.h>
-#endif /* !WIN32 */
+typedef struct {
+ intmax_t quot;
+ intmax_t rem;
+} imaxdiv_t;
=20
-#endif /* _LOCAL_INTTYPES_H_ */
+// 7.8.1 Macros for format specifiers
+
+// The fprintf macros for signed integers are:
+#define PRId8 "d"
+#define PRIi8 "i"
+#define PRIdLEAST8 "d"
+#define PRIiLEAST8 "i"
+#define PRIdFAST8 "d"
+#define PRIiFAST8 "i"
+
+#define PRId16 "hd"
+#define PRIi16 "hi"
+#define PRIdLEAST16 "hd"
+#define PRIiLEAST16 "hi"
+#define PRIdFAST16 "hd"
+#define PRIiFAST16 "hi"
+
+#define PRId32 "I32d"
+#define PRIi32 "I32i"
+#define PRIdLEAST32 "I32d"
+#define PRIiLEAST32 "I32i"
+#define PRIdFAST32 "I32d"
+#define PRIiFAST32 "I32i"
+
+#define PRId64 "I64d"
+#define PRIi64 "I64i"
+#define PRIdLEAST64 "I64d"
+#define PRIiLEAST64 "I64i"
+#define PRIdFAST64 "I64d"
+#define PRIiFAST64 "I64i"
+
+#define PRIdMAX "I64d"
+#define PRIiMAX "I64i"
+
+#define PRIdPTR "Id"
+#define PRIiPTR "Ii"
+
+// The fprintf macros for unsigned integers are:
+#define PRIo8 "o"
+#define PRIu8 "u"
+#define PRIx8 "x"
+#define PRIX8 "X"
+#define PRIoLEAST8 "o"
+#define PRIuLEAST8 "u"
+#define PRIxLEAST8 "x"
+#define PRIXLEAST8 "X"
+#define PRIoFAST8 "o"
+#define PRIuFAST8 "u"
+#define PRIxFAST8 "x"
+#define PRIXFAST8 "X"
+
+#define PRIo16 "ho"
+#define PRIu16 "hu"
+#define PRIx16 "hx"
+#define PRIX16 "hX"
+#define PRIoLEAST16 "ho"
+#define PRIuLEAST16 "hu"
+#define PRIxLEAST16 "hx"
+#define PRIXLEAST16 "hX"
+#define PRIoFAST16 "ho"
+#define PRIuFAST16 "hu"
+#define PRIxFAST16 "hx"
+#define PRIXFAST16 "hX"
+
+#define PRIo32 "I32o"
+#define PRIu32 "I32u"
+#define PRIx32 "I32x"
+#define PRIX32 "I32X"
+#define PRIoLEAST32 "I32o"
+#define PRIuLEAST32 "I32u"
+#define PRIxLEAST32 "I32x"
+#define PRIXLEAST32 "I32X"
+#define PRIoFAST32 "I32o"
+#define PRIuFAST32 "I32u"
+#define PRIxFAST32 "I32x"
+#define PRIXFAST32 "I32X"
+
+#define PRIo64 "I64o"
+#define PRIu64 "I64u"
+#define PRIx64 "I64x"
+#define PRIX64 "I64X"
+#define PRIoLEAST64 "I64o"
+#define PRIuLEAST64 "I64u"
+#define PRIxLEAST64 "I64x"
+#define PRIXLEAST64 "I64X"
+#define PRIoFAST64 "I64o"
+#define PRIuFAST64 "I64u"
+#define PRIxFAST64 "I64x"
+#define PRIXFAST64 "I64X"
+
+#define PRIoMAX "I64o"
+#define PRIuMAX "I64u"
+#define PRIxMAX "I64x"
+#define PRIXMAX "I64X"
+
+#define PRIoPTR "Io"
+#define PRIuPTR "Iu"
+#define PRIxPTR "Ix"
+#define PRIXPTR "IX"
+
+// The fscanf macros for signed integers are:
+#define SCNd8 "d"
+#define SCNi8 "i"
+#define SCNdLEAST8 "d"
+#define SCNiLEAST8 "i"
+#define SCNdFAST8 "d"
+#define SCNiFAST8 "i"
+
+#define SCNd16 "hd"
+#define SCNi16 "hi"
+#define SCNdLEAST16 "hd"
+#define SCNiLEAST16 "hi"
+#define SCNdFAST16 "hd"
+#define SCNiFAST16 "hi"
+
+#define SCNd32 "ld"
+#define SCNi32 "li"
+#define SCNdLEAST32 "ld"
+#define SCNiLEAST32 "li"
+#define SCNdFAST32 "ld"
+#define SCNiFAST32 "li"
+
+#define SCNd64 "I64d"
+#define SCNi64 "I64i"
+#define SCNdLEAST64 "I64d"
+#define SCNiLEAST64 "I64i"
+#define SCNdFAST64 "I64d"
+#define SCNiFAST64 "I64i"
+
+#define SCNdMAX "I64d"
+#define SCNiMAX "I64i"
+
+#ifdef _WIN64 // [
+# define SCNdPTR "I64d"
+# define SCNiPTR "I64i"
+#else // _WIN64 ][
+# define SCNdPTR "ld"
+# define SCNiPTR "li"
+#endif // _WIN64 ]
+
+// The fscanf macros for unsigned integers are:
+#define SCNo8 "o"
+#define SCNu8 "u"
+#define SCNx8 "x"
+#define SCNX8 "X"
+#define SCNoLEAST8 "o"
+#define SCNuLEAST8 "u"
+#define SCNxLEAST8 "x"
+#define SCNXLEAST8 "X"
+#define SCNoFAST8 "o"
+#define SCNuFAST8 "u"
+#define SCNxFAST8 "x"
+#define SCNXFAST8 "X"
+
+#define SCNo16 "ho"
+#define SCNu16 "hu"
+#define SCNx16 "hx"
+#define SCNX16 "hX"
+#define SCNoLEAST16 "ho"
+#define SCNuLEAST16 "hu"
+#define SCNxLEAST16 "hx"
+#define SCNXLEAST16 "hX"
+#define SCNoFAST16 "ho"
+#define SCNuFAST16 "hu"
+#define SCNxFAST16 "hx"
+#define SCNXFAST16 "hX"
+
+#define SCNo32 "lo"
+#define SCNu32 "lu"
+#define SCNx32 "lx"
+#define SCNX32 "lX"
+#define SCNoLEAST32 "lo"
+#define SCNuLEAST32 "lu"
+#define SCNxLEAST32 "lx"
+#define SCNXLEAST32 "lX"
+#define SCNoFAST32 "lo"
+#define SCNuFAST32 "lu"
+#define SCNxFAST32 "lx"
+#define SCNXFAST32 "lX"
+
+#define SCNo64 "I64o"
+#define SCNu64 "I64u"
+#define SCNx64 "I64x"
+#define SCNX64 "I64X"
+#define SCNoLEAST64 "I64o"
+#define SCNuLEAST64 "I64u"
+#define SCNxLEAST64 "I64x"
+#define SCNXLEAST64 "I64X"
+#define SCNoFAST64 "I64o"
+#define SCNuFAST64 "I64u"
+#define SCNxFAST64 "I64x"
+#define SCNXFAST64 "I64X"
+
+#define SCNoMAX "I64o"
+#define SCNuMAX "I64u"
+#define SCNxMAX "I64x"
+#define SCNXMAX "I64X"
+
+#ifdef _WIN64 // [
+# define SCNoPTR "I64o"
+# define SCNuPTR "I64u"
+# define SCNxPTR "I64x"
+# define SCNXPTR "I64X"
+#else // _WIN64 ][
+# define SCNoPTR "lo"
+# define SCNuPTR "lu"
+# define SCNxPTR "lx"
+# define SCNXPTR "lX"
+#endif // _WIN64 ]
+
+// 7.8.2 Functions for greatest-width integer types
+
+// 7.8.2.1 The imaxabs function
+#define imaxabs _abs64
+
+// 7.8.2.2 The imaxdiv function
+
+// This is modified version of div() function from Microsoft's div.c fou=
nd
+// in %MSVC.NET%\crt\src\div.c
+static _inline imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
+{
+ imaxdiv_t result;
+
+ result.quot =3D numer / denom;
+ result.rem =3D numer % denom;
+
+ if (numer < 0 && result.rem > 0) {
+ // did division wrong; must fix up
+ ++result.quot;
+ result.rem -=3D denom;
+ }
+
+ return result;
+}
+
+// 7.8.2.3 The strtoimax and strtoumax functions
+#define strtoimax _strtoi64
+#define strtoumax _strtoui64
+
+// 7.8.2.4 The wcstoimax and wcstoumax functions
+#define wcstoimax _wcstoi64
+#define wcstoumax _wcstoui64
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _MSC_INTTYPES_H_ ]
Deleted: trunk/DvdMenuXtractor/libdvdread/win32/libdvdread.vcproj
Added: trunk/DvdMenuXtractor/libdvdread/win32/posix.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/win32/posix.h 2007-01-22 11:21:16 UT=
C (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/win32/posix.h 2007-01-28 16:48:11 UT=
C (rev 1270)
@@ -0,0 +1,39 @@
+#ifndef _MSC_VER
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif
+
+#ifndef _MSC_POSIX_H_
+#define _MSC_POSIX_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <sys/stat.h>
+#ifndef S_ISREG
+#define S_ISREG(mode) (0)
+#endif
+#ifndef S_ISDIR
+#define S_ISDIR(mode) ((mode)&_S_IFDIR)
+#endif
+#ifndef S_ISCHR
+#define S_ISCHR(mode) (0)
+#endif
+#ifndef S_ISSOCK
+#define S_ISSOCK(x) (0)
+#endif
+#ifndef S_ISBLK
+#define S_ISBLK(x) (0)
+#endif
+
+#include <stdlib.h>
+#define strcasecmp(x,y) stricmp(x,y)
+#define strncasecmp(x,y,z) strnicmp(x,y,z)
+
+#define PATH_MAX _MAX_PATH
+
+#include <windows.h>
+#define dlclose(x) FreeLibrary(x)
+#define dlsym(x,y) GetProcAddress(x,y)
+
+#endif // _MSC_POSIX_H_
Added: trunk/DvdMenuXtractor/libdvdread/win32/stdint.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/win32/stdint.h 2007-01-22 11:21:16 U=
TC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/win32/stdint.h 2007-01-28 16:48:11 U=
TC (rev 1270)
@@ -0,0 +1,208 @@
+// ISO C9x compliant stdint.h for Miscrosoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124=20
+//=20
+// Copyright (c) 2006 Alexander Chemeris
+//=20
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions ar=
e met:
+//=20
+// 1. Redistributions of source code must retain the above copyright n=
otice,
+// this list of conditions and the following disclaimer.
+//=20
+// 2. Redistributions in binary form must reproduce the above copyrigh=
t
+// notice, this list of conditions and the following disclaimer in =
the
+// documentation and/or other materials provided with the distribut=
ion.
+//=20
+// 3. The name of the author may be used to endorse or promote product=
s
+// derived from this software without specific prior written permis=
sion.
+//=20
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR =
IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. =
IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL=
,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMI=
TED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PR=
OFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILI=
TY,=20
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE =
OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN I=
F
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//=20
+////////////////////////////////////////////////////////////////////////=
///////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <BaseTsd.h>
+#include <limits.h>
+#include <wchar.h>
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+typedef signed __int8 int8_t;
+typedef signed __int16 int16_t;
+typedef signed __int32 int32_t;
+typedef signed __int64 int64_t;
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+typedef uint8_t uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t int_fast8_t;
+typedef int16_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef int64_t int_fast64_t;
+typedef uint8_t uint_fast8_t;
+typedef uint16_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+typedef uint64_t uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+typedef INT_PTR intptr_t;
+typedef UINT_PTR uintptr_t;
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t intmax_t;
+typedef uint64_t uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See foo=
tnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN _I8_MIN
+#define INT8_MAX _I8_MAX
+#define INT16_MIN _I16_MIN
+#define INT16_MAX _I16_MAX
+#define INT32_MIN _I32_MIN
+#define INT32_MAX _I32_MAX
+#define INT64_MIN _I64_MIN
+#define INT64_MAX _I64_MAX
+#define UINT8_MAX _UI8_MAX
+#define UINT16_MAX _UI16_MAX
+#define UINT32_MAX _UI32_MAX
+#define UINT64_MAX _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MIN INT64_MIN
+#define INT_LEAST64_MAX INT64_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MIN INT16_MIN
+#define INT_FAST16_MAX INT16_MAX
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST32_MAX INT32_MAX
+#define INT_FAST64_MIN INT64_MIN
+#define INT_FAST64_MAX INT64_MAX
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX UINT16_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+# define INTPTR_MIN INT64_MIN
+# define INTPTR_MAX INT64_MAX
+# define UINTPTR_MAX UINT64_MAX
+#else // _WIN64 ][
+# define INTPTR_MIN INT32_MIN
+# define INTPTR_MAX INT32_MAX
+# define UINTPTR_MAX UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+# define PTRDIFF_MIN _I64_MIN
+# define PTRDIFF_MAX _I64_MAX
+#else // _WIN64 ][
+# define PTRDIFF_MIN _I32_MIN
+# define PTRDIFF_MAX _I32_MAX
+#endif // _WIN64 ]
+
+#define SIG_ATOMIC_MIN INT_MIN
+#define SIG_ATOMIC_MAX INT_MAX
+
+#ifndef SIZE_MAX // [
+# ifdef _WIN64 // [
+# define SIZE_MAX _UI64_MAX
+# else // _WIN64 ][
+# define SIZE_MAX _UI32_MAX
+# endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+# define WCHAR_MIN 0
+#endif // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+# define WCHAR_MAX _UI16_MAX
+#endif // WCHAR_MAX ]
+
+#define WINT_MIN 0
+#define WINT_MAX _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See =
footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val) val
+#define INT16_C(val) val
+#define INT32_C(val) val##L
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val) val
+#define UINT16_C(val) val
+#define UINT32_C(val) val##UL
+#define UINT64_C(val) val##Ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C INT64_C
+#define UINTMAX_C UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
Added: trunk/DvdMenuXtractor/libdvdread/win32/win32.proj
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/libdvdread/win32/win32.proj 2007-01-22 11:21:16=
UTC (rev 1269)
+++ trunk/DvdMenuXtractor/libdvdread/win32/win32.proj 2007-01-28 16:48:11=
UTC (rev 1270)
@@ -0,0 +1,16 @@
+#include "*/*.proj"
+
+GROUP posixmsvc
+{
+ SOURCE dirent.c
+
+ HEADER dirent.h
+ HEADER gtchar.h
+ HEADER posix.h
+}
+
+GROUP c99msvc
+{
+ HEADER inttypes.h
+ HEADER stdint.h
+}
Added: trunk/DvdMenuXtractor/logtextedit.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/logtextedit.cpp 2007-01-22 11:21:16 UTC (rev 12=
69)
+++ trunk/DvdMenuXtractor/logtextedit.cpp 2007-01-28 16:48:11 UTC (rev 12=
70)
@@ -0,0 +1,46 @@
+#include <QDate>
+#include <QFile>
+#include <QTextStream>
+#include "logtextedit.h"
+#include "outputreader.h"
+
+LogTextEdit::LogTextEdit(QWidget *parent)
+ : QTextEdit(parent), notifier_(OutputReader::instance())
+{
+ // set flags
+ setReadOnly(true);
+ setLineWrapMode(QTextEdit::NoWrap);
+
+ if (!notifier_.redirect())
+ {
+ setHtml("ERROR: Could not start output redirection");
+ notifier_.cancelRedirect();
+ return;
+ }
+
+ // setup slots
+ connect(¬ifier_, SIGNAL(readyReadStandardError()), this, SLOT(standa=
rdErrorReady()));
+ connect(¬ifier_, SIGNAL(readyReadStandardOutput()), this, SLOT(stand=
ardOutputReady()));
+}
+
+LogTextEdit::~LogTextEdit()
+{
+}
+
+void LogTextEdit::standardErrorReady()
+{
+ static const QString format("%1;%2 - WARNING: %3");
+=09
+ QString message =3D notifier_.readError();
+ foreach (QString line, message.split('\n', QString::SkipEmptyParts))
+ append(format.arg(QDate::currentDate().toString(), QTime::currentTime(=
).toString(), line));
+}
+
+void LogTextEdit::standardOutputReady()
+{
+ static const QString format("%1;%2: %3");
+
+ QString message =3D notifier_.readOutput();
+ foreach (QString line, message.split('\n', QString::SkipEmptyParts))
+ append(format.arg(QDate::currentDate().toString(), QTime::currentTime(=
).toString(), line));
+}
Added: trunk/DvdMenuXtractor/logtextedit.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/logtextedit.h 2007-01-22 11:21:16 UTC (rev 1269=
)
+++ trunk/DvdMenuXtractor/logtextedit.h 2007-01-28 16:48:11 UTC (rev 1270=
)
@@ -0,0 +1,25 @@
+#ifndef LOGTEXTEDIT_H
+#define LOGTEXTEDIT_H
+
+#include <QTextEdit>
+
+// forward declaration
+class OutputReader;
+
+class LogTextEdit : public QTextEdit
+{
+ Q_OBJECT
+
+public:
+ LogTextEdit(QWidget *parent);
+ ~LogTextEdit();
+
+private slots:
+ void standardErrorReady();
+ void standardOutputReady();
+
+private:
+ OutputReader& notifier_;
+};
+
+#endif // LOGTEXTEDIT_H
Added: trunk/DvdMenuXtractor/main.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/main.cpp 2007-01-22 11:21:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/main.cpp 2007-01-28 16:48:11 UTC (rev 1270)
@@ -0,0 +1,27 @@
+#include <string>
+#include <QtGui/QApplication>
+
+#include "dmxwizard.h"
+#include "dmxconsole.h"
+
+int main(int argc, char *argv[])
+{=09
+ bool useGui =3D (argc =3D=3D 1); // default mode is gui mode
+
+ if (!useGui)
+ {
+ DMXConsole console(argv, argc);
+ console.extract();
+ }
+ else
+ {
+ QApplication app(argc, argv);
+ DMXWizard wizard;
+ wizard.show();
+ app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
+
+ return app.exec();
+ }
+
+ return 0;
+}
Deleted: trunk/DvdMenuXtractor/makefile.vc
Modified: trunk/DvdMenuXtractor/mpegparser/Types.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/mpegparser/Types.h 2007-01-22 11:21:16 UTC (rev=
1269)
+++ trunk/DvdMenuXtractor/mpegparser/Types.h 2007-01-28 16:48:11 UTC (rev=
1270)
@@ -1,7 +1,7 @@
#ifndef __TYPES_H__
#define __TYPES_H__
=20
-#include <inttypes.h>
+#include <stdint.h>
=20
typedef int64_t MediaTime;
typedef uint8_t binary;
Added: trunk/DvdMenuXtractor/mpegparser/mpegparser.proj
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/mpegparser/mpegparser.proj 2007-01-22 11:21:16 =
UTC (rev 1269)
+++ trunk/DvdMenuXtractor/mpegparser/mpegparser.proj 2007-01-28 16:48:11 =
UTC (rev 1270)
@@ -0,0 +1,11 @@
+GROUP mpegparser
+{
+ SOURCE CircBuffer.cpp
+ SOURCE M2VParser.cpp
+ SOURCE MPEGVideoBuffer.cpp
+
+ HEADER CircBuffer.h
+ HEADER M2VParser.h
+ HEADER MPEGVideoBuffer.h
+ HEADER Types.h
+}
Added: trunk/DvdMenuXtractor/outputreader.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/outputreader.cpp 2007-01-22 11:21:16 UTC (rev 1=
269)
+++ trunk/DvdMenuXtractor/outputreader.cpp 2007-01-28 16:48:11 UTC (rev 1=
270)
@@ -0,0 +1,166 @@
+#include <io.h>
+#include <QDir>
+#include <fcntl.h>
+#include <fstream>
+#include <QWidget>
+#include <QTextStream>
+#include <QTimerEvent>
+#include "outputreader.h"
+
+OutputReader::OutputReader(QObject *parent /* =3D 0*/)
+ : QObject(parent), stderrStream(0), stdoutStream(0), redirecting_(fals=
e),
+ stderrFileName("stderr.txt"), stdoutFileName("stdout.txt")
+{
+}
+
+OutputReader::~OutputReader()
+{
+ if (redirecting_)
+ cancelRedirect();
+}
+
+void OutputReader::timerEvent(QTimerEvent *event)
+{
+ // if the event is intended for us
+ if ((event->timerId() =3D=3D timer.timerId()) && redirecting_)
+ {
+ QFile stdoutFile (stdoutFileName);
+ QFile stderrFile (stderrFileName);
+=09
+ static qint64 stderrFileSize =3D 0;
+ static qint64 stdoutFileSize =3D 0;
+
+ qint64 size =3D stderrFile.size();
+
+ if (size > stderrFileSize) // new data is available
+ {
+ stderrFileSize =3D size;
+ emit readyReadStandardError();
+ }
+
+ size =3D stdoutFile.size();
+
+ if (size > stdoutFileSize) // new data is available
+ {
+ stdoutFileSize =3D size;
+ emit readyReadStandardOutput();
+ }
+ }
+ else
+ QObject::timerEvent(event);
+}
+
+bool OutputReader::redirect()=20
+{
+ if (redirecting_)
+ return true;
+
+ // save old descriptors
+ stdout_desc =3D _dup(1);
+ stderr_desc =3D _dup(2);
+
+ if ((stdout_desc =3D=3D -1) || (stderr_desc =3D=3D -1))
+ return false;
+
+ // redirect stdout and stderr to corresponding files
+#if defined(_CRT_SECURE_NO_DEPRECATE)
+ stdoutStream =3D freopen(stdoutFileName.toAscii(), "wc", stdout);
+ stderrStream =3D freopen(stderrFileName.toAscii(), "wc", stderr);
+#else
+ freopen_s(&stdoutStream, stdoutFileName.toAscii(), "wc", stdout);
+ freopen_s(&stderrStream, stderrFileName.toAscii(), "wc", stderr);
+#endif
+
+ if ((stderrStream =3D=3D 0) || (stdoutStream =3D=3D 0))
+ return false;
+
+ // disable buffering
+ setvbuf(stdout, 0, _IONBF, 0);
+ setvbuf(stderr, 0, _IONBF, 0);
+
+ redirecting_ =3D true;
+
+ // start monitoring
+ timer.start(TIMEOUT, this);
+=09
+ return redirecting_;
+}
+
+bool OutputReader::cancelRedirect()
+{
+ // close streams
+ if (stderrStream !=3D 0)
+ fclose(stderrStream);
+=09
+ if (stdoutStream !=3D 0)
+ fclose(stdoutStream);
+
+ // set back standard file descriptors
+ if (( -1 =3D=3D _dup2(stdout_desc, 1))=20
+ ||( -1 =3D=3D _dup2(stderr_desc, 2)))
+ return false;
+
+ // stop monitoring
+ timer.stop();
+
+ stderrStream =3D 0;
+ stdoutStream =3D 0;
+
+ redirecting_ =3D false;
+
+ return true;
+}
+
+QString OutputReader::readOutput() const
+{
+ static std::ifstream::pos_type position =3D 0;
+=09
+ QString output;
+ std::string data;
+ std::ifstream stream (qPrintable(stdoutFileName));
+ if (stream.is_open())
+ {
+ if (stream.seekg(position).good())
+ do
+ {
+ position =3D stream.tellg();
+ if(getline(stream, data))
+ output.append(data.data()).append('\n');
+ else
+ break;
+ }
+ while (true);
+ }
+
+ return output;
+}
+
+QString OutputReader::readError() const
+{
+ static std::ifstream::pos_type position =3D 0;
+=09
+ QString error;
+ std::string data;
+ std::ifstream stream (qPrintable(stderrFileName));
+ if (stream.is_open())
+ {
+ if (stream.seekg(position).good())
+ do
+ {
+ position =3D stream.tellg();
+ if(getline(stream, data))
+ error.append(data.data()).append('\n');
+ else
+ break;
+ }
+ while (true);
+ }
+
+ return error;
+}
+
+OutputReader& OutputReader::instance()
+{
+ static OutputReader reader;
+ return reader;
+}
\ No newline at end of file
Added: trunk/DvdMenuXtractor/outputreader.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/outputreader.h 2007-01-22 11:21:16 UTC (rev 126=
9)
+++ trunk/DvdMenuXtractor/outputreader.h 2007-01-28 16:48:11 UTC (rev 127=
0)
@@ -0,0 +1,63 @@
+/**********************************************************/
+/* Description: Contains OutputReader class declaration */
+/**********************************************************/
+#ifndef OUTPUTREADER_H
+#define OUTPUTREADER_H
+
+#include <QObject>
+#include <QBasicTimer>
+
+class OutputReader : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ static OutputReader& instance();
+
+ /* Starts redirecting stdout and stderr to itself */
+ bool redirect();
+=09
+ /* Cancels redirecting stdout and stderr to itself */
+ bool cancelRedirect();
+
+ /* Reads stderr content, when available */
+ QString readError() const;
+=09
+ /* Reads stdout content, when available */
+ QString readOutput() const;
+
+signals:
+ /* These signals are emitted when stdout */
+ /* and/or stderr are ready to be read */
+ void readyReadStandardError();
+ void readyReadStandardOutput();
+
+protected:
+ void timerEvent(QTimerEvent *event);
+
+private:
+ static const int TIMEOUT =3D 1000;
+
+ bool redirecting_;
+
+ QString stdoutFileName; // file where stdout would be redirected
+ QString stderrFileName; // file where stderr would be redirected
+
+ int stdout_desc; // stdout descriptor before redirecting
+ int stderr_desc; // stderr descriptor before redirecting
+
+ FILE *stderrStream; // file stream for standard error
+ FILE *stdoutStream; // file stream for standard output
+
+ QBasicTimer timer; // Timer to watch for output change
+
+ // singleton pattern, no copying
+ OutputReader(const OutputReader&);
+ OutputReader& operator=3D (const OutputReader&);
+ OutputReader(QObject *parent =3D 0);
+ ~OutputReader();
+};
+
+
+#endif // OUTPUTREADER_H
Added: trunk/DvdMenuXtractor/selectiontreeitem.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/selectiontreeitem.cpp 2007-01-22 11:21:16 UTC (=
rev 1269)
+++ trunk/DvdMenuXtractor/selectiontreeitem.cpp 2007-01-28 16:48:11 UTC (=
rev 1270)
@@ -0,0 +1,41 @@
+#include <QTreeWidgetItem>
+#include "selectiontreeitem.h"
+
+SelectionTreeItem::SelectionTreeItem(QTreeWidget *parent, int16_t title,=
bool isMenuItem)
+ : QTreeWidgetItem(parent), title_(title), isMenuItem_(isMenuItem)
+{
+ static const QString vmgTitleFormat(QObject::tr("VMG"));
+ static const QString vtsTitleFormat(QObject::tr("Title %1"));
+ static const QString vtsmTitleFormat(QObject::tr("Title %1 Menu"));
+=09
+ if (isMenuItem && title)
+ setText(0, vtsmTitleFormat.arg(QString::number(title), 2, '0'));
+ else if (isMenuItem)
+ setText(0, vmgTitleFormat);
+ else
+ setText(0, vtsTitleFormat.arg(QString::number(title), 2, '0'));
+
+ setFlags(flags() | Qt::ItemIsTristate);
+ setCheckState(0, Qt::Checked);
+}
+
+SelectionTreeItem::SelectionTreeItem(const SelectionTreeItem &other)
+ : QTreeWidgetItem(other), title_(other.title_), isMenuItem_(other.isMen=
uItem_)
+{
+ setCheckState(0, other.checkState(0));
+}
+
+SelectionTreeItem::~SelectionTreeItem()
+{
+
+}
+
+bool SelectionTreeItem::isMenuItem() const
+{
+ return isMenuItem_;
+}
+
+int16_t SelectionTreeItem::title() const
+{
+ return title_;
+}
Added: trunk/DvdMenuXtractor/selectiontreeitem.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/selectiontreeitem.h 2007-01-22 11:21:16 UTC (re=
v 1269)
+++ trunk/DvdMenuXtractor/selectiontreeitem.h 2007-01-28 16:48:11 UTC (re=
v 1270)
@@ -0,0 +1,25 @@
+#ifndef SELECTIONTREEITEM_H
+#define SELECTIONTREEITEM_H
+
+#include <stdint.h>
+
+// forward declaration
+class QTreeWidgetItem;
+
+class SelectionTreeItem : public QTreeWidgetItem
+{
+public:
+
+ SelectionTreeItem(QTreeWidget *parent, int16_t title, bool isMenuItem)=
;
+ SelectionTreeItem(const SelectionTreeItem &other);
+ ~SelectionTreeItem();
+
+ int16_t title() const;
+ bool isMenuItem() const;
+
+private:
+ int16_t title_;
+ bool isMenuItem_;
+};
+
+#endif // SELECTIONTREEITEM_H
Added: trunk/DvdMenuXtractor/selectiontreesubitem.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/selectiontreesubitem.cpp 2007-01-22 11:21:16 UT=
C (rev 1269)
+++ trunk/DvdMenuXtractor/selectiontreesubitem.cpp 2007-01-28 16:48:11 UT=
C (rev 1270)
@@ -0,0 +1,42 @@
+#include <QTreeWidgetItem>
+#include "selectiontreesubitem.h"
+
+SelectionTreeSubItem::SelectionTreeSubItem(QTreeWidgetItem *parent, cons=
t SelectionTreeItem &titleItem, size_t index, SelectionTreeSubItem::SubIt=
emType type)
+ : QTreeWidgetItem(parent), titleItem_(titleItem), index_(index), type_(=
type)
+{
+ static const QString audioTrackTitleFormat ("Audio Track %1");
+ static const QString subTrackTitleFormat ("Subtitle Track %1");
+=09
+ if (type =3D=3D AUDIO_TRACK)
+ setText(0, audioTrackTitleFormat.arg(index));
+ else
+ setText(0, subTrackTitleFormat.arg(index));
+
+ setFlags(flags() | Qt::ItemIsTristate);
+ setCheckState(0, Qt::Checked);
+}
+
+SelectionTreeSubItem::SelectionTreeSubItem(const SelectionTreeSubItem &o=
ther)
+ : QTreeWidgetItem(other), titleItem_(other.titleItem_), index_(other.in=
dex_), type_(other.type_)
+{
+ setCheckState(0, other.checkState(0));
+}
+
+SelectionTreeSubItem::~SelectionTreeSubItem()
+{
+}
+
+size_t SelectionTreeSubItem::index() const
+{
+ return index_;
+}
+
+SelectionTreeSubItem::SubItemType SelectionTreeSubItem::type() const
+{
+ return type_;
+}
+
+const SelectionTreeItem& SelectionTreeSubItem::titleItem() const
+{
+ return titleItem_;
+}
Added: trunk/DvdMenuXtractor/selectiontreesubitem.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/selectiontreesubitem.h 2007-01-22 11:21:16 UTC =
(rev 1269)
+++ trunk/DvdMenuXtractor/selectiontreesubitem.h 2007-01-28 16:48:11 UTC =
(rev 1270)
@@ -0,0 +1,26 @@
+#ifndef SELECTION_TREE_SUB_ITEM_H
+#define SELECTION_TREE_SUB_ITEM_H
+
+// forward declaration
+class QTreeWidgetItem;
+class SelectionTreeItem;
+
+class SelectionTreeSubItem : public QTreeWidgetItem
+{
+public:
+ enum SubItemType { AUDIO_TRACK, SUBTITLE_TRACK };
+ SelectionTreeSubItem(QTreeWidgetItem *parent, const SelectionTreeItem& =
titleItem, size_t index, SubItemType type);
+ SelectionTreeSubItem(const SelectionTreeSubItem& other);
+ ~SelectionTreeSubItem();
+
+ size_t index() const;
+ SubItemType type() const;
+ const SelectionTreeItem& titleItem() const;
+
+private:
+ size_t index_;
+ SubItemType type_;
+ const SelectionTreeItem &titleItem_;
+};
+
+#endif // SELECTION_TREE_SUB_ITEM_H
\ No newline at end of file
Added: trunk/DvdMenuXtractor/utilities.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/utilities.cpp 2007-01-22 11:21:16 UTC (rev 1269=
)
+++ trunk/DvdMenuXtractor/utilities.cpp 2007-01-28 16:48:11 UTC (rev 1270=
)
@@ -0,0 +1,32 @@
+#include <iostream>
+#include "utilities.h"
+
+QString Utilities::CreateUID()
+{
+ return QString("%1").arg( uint32_t(rand() | (rand() << 16)) );
+}
+
+QString Utilities::FormatTime(uint64_t a_time)
+{
+ int hour, min, sec;
+ uint32_t nano;
+
+ nano =3D a_time % 1000000000;
+ a_time /=3D 1000000000;
+ sec =3D a_time % 60;
+ a_time /=3D 60;
+ min =3D a_time % 60;
+ hour =3D a_time / 60;
+
+ return QString("%1:%2:%3.%4").arg(hour, 2, 10, QChar('0')).arg(min, 2, =
10, QChar('0')).arg(sec, 2, 10, QChar('0')).arg(nano, 9, 10, QChar('0'));
+}
+
+QString Utilities::EncodeHex(const unsigned char *buffer, unsigned int s=
ize)
+{
+ QString result;
+
+ for (unsigned i =3D 0; i < size; ++i)
+ result +=3D QString("%1 ").arg(buffer[i], 2, 16, QChar('0'));
+
+ return result.trimmed();
+}
\ No newline at end of file
Added: trunk/DvdMenuXtractor/utilities.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/utilities.h 2007-01-22 11:21:16 UTC (rev 1269)
+++ trunk/DvdMenuXtractor/utilities.h 2007-01-28 16:48:11 UTC (rev 1270)
@@ -0,0 +1,17 @@
+#ifndef UTILITIES_H
+#define UTILITIES_H
+
+#include <QString>
+#include <stdint.h>
+
+namespace Utilities
+{
+ static const QString APPLICATION_NAME ("DVDMenuXtractor: DMX - a fai=
r-use tool");
+ static const QString APPLICATION_VERSION ("0.9.x");
+
+ QString CreateUID();
+ QString FormatTime(uint64_t a_time);
+ QString EncodeHex(const unsigned char *buffer, unsigned size);
+}
+
+#endif // UTILITIES_H
\ No newline at end of file
Added: trunk/DvdMenuXtractor/vobparser/IFOContent.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/vobparser/IFOContent.cpp 2007-01-22 11:21:16 UT=
C (rev 1269)
+++ trunk/DvdMenuXtractor/vobparser/IFOContent.cpp 2007-01-28 16:48:11 UT=
C (rev 1270)
@@ -0,0 +1,273 @@
+// ---------------------------------------------------------------------=
-------
+#include "IFOContent.h"
+// ---------------------------------------------------------------------=
-------
+// Macro to convert Binary Coded Decimal to Decimal
+#define BCD2D(__x__) (((__x__ & 0xf0) >> 4) * 10 + (__x__ & 0x0f))
+// ---------------------------------------------------------------------=
-------
+int dvdtime2frame(dvd_time_t* dtime, double & frame_dur)
+{
+ double frame_rate;
+ double result =3D 0.0;
+ assert((dtime->hour>>4) < 0xa && (dtime->hour&0xf) < 0xa);
+ assert((dtime->minute>>4) < 0x7 && (dtime->minute&0xf) < 0xa);
+ assert((dtime->second>>4) < 0x7 && (dtime->second&0xf) < 0xa);
+ assert((dtime->frame_u&0xf) < 0xa);
+
+ int hh, min, sec, ff;
+ hh =3D BCD2D(dtime->hour);
+ min =3D BCD2D(dtime->minute);
+ sec =3D BCD2D(dtime->second);
+ ff =3D BCD2D(dtime->frame_u & 0x3f);
+
+ frame_rate =3D ((dtime->frame_u & 0xc0) >> 6) =3D=3D 1 ? 25.0 : (30000.=
0/1001.0);
+ result =3D (((((hh * 60) + min) * 60) + sec) * frame_rate) + (ff & 0x3f=
);
+ frame_dur =3D 1000.0 / frame_rate;
+
+ return (int)result;
+}
+// ---------------------------------------------------------------------=
-------
+IFOContent::IFOContent(dvd_reader_t *dvdr, int16_t title)
+ :m_title(title)
+{
+ m_handle =3D ifoOpen(dvdr, title);
+ if (!m_handle)
+ throw IFOInvalidFileFormatException();
+
+ CellsHashType CellsHash;
+
+ if (title =3D=3D 0)
+ {
+ if (m_handle->vmgi_mat)
+ {
+ const vmgi_mat_t &vmgi_mat =3D *m_handle->vmgi_mat;
+ if (vmgi_mat.nr_of_vmgm_audio_streams)
+ m_langAudio.push_back(&vmgi_mat.vmgm_audio_attr);
+ if (vmgi_mat.nr_of_vmgm_subp_streams)
+ m_langSubs.push_back(&vmgi_mat.vmgm_subp_attr);
+ }
+
+ if (m_handle->pgci_ut && m_handle->menu_c_adt)
+ {
+ // add each cell in a list
+ // order this list according to vob ID, cell ID
+ // for each cell, find the duration (and start time) from all menu PG=
Cs
+ for(uint16_t i =3D 0; i < m_handle->pgci_ut->nr_of_lus; i++)
+ {
+ pgci_lu_t& lu =3D m_handle->pgci_ut->lu[i];
+ GetPGCCells(*lu.pgcit, *m_handle->menu_c_adt, &CellsHash);
+ }
+
+ // Transfer hash map to the list to be sorted
+ m_langCellsList.clear();
+ =09
+ for(CellsHashType::iterator it =3D CellsHash.begin(); it !=3D CellsHa=
sh.end(); ++it )
+ {
+ m_langCellsList.append(it.value());
+ }
+
+ m_langCellsList.arrange();
+ }
+ }
+ else
+ {
+ if (m_handle->vtsi_mat)
+ {
+ const vtsi_mat_t & vtsi_mat =3D *m_handle->vtsi_mat;
+ if (vtsi_mat.nr_of_vtsm_audio_streams)
+ m_langAudio.push_back(&vtsi_mat.vtsm_audio_attr);
+ if (vtsi_mat.nr_of_vtsm_subp_streams)
+ m_langSubs.push_back(&vtsi_mat.vtsm_subp_attr);
+
+ uint8_t _stream;
+ for (_stream=3D0; _stream < vtsi_mat.nr_of_vts_audio_streams; _stream=
++)
+ m_Audio.push_back(&vtsi_mat.vts_audio_attr[_stream]);
+ for (_stream=3D0; _stream < vtsi_mat.nr_of_vts_subp_streams; _stream+=
+)
+ m_Subs.push_back(&vtsi_mat.vts_subp_attr[_stream]);
+ }
+
+ // handle the list of menu cells with their ID and sectors
+ CellsHash.clear();
+ if (m_handle->pgci_ut && m_handle->menu_c_adt)
+ {
+ // add each cell in a list
+ // order this list according to vob ID, cell ID
+ // for each cell, find the duration (and start time) from all menu PG=
Cs
+ for(int i =3D 0; i < m_handle->pgci_ut->nr_of_lus; i++)
+ {
+ pgci_lu_t& lu =3D m_handle->pgci_ut->lu[i];
+ GetPGCCells(*lu.pgcit, *m_handle->menu_c_adt, &CellsHash);
+ }
+
+ // Transfer hash map to the list to be sorted
+ m_langCellsList.clear();
+ CellsHashType::iterator it;
+ for( it =3D CellsHash.begin(); it !=3D CellsHash.end(); ++it )
+ {
+ m_langCellsList.append(it.value());
+ }
+
+ m_langCellsList.arrange();
+ }
+
+ // handle the list of cells with their ID and sectors
+ CellsHash.clear();
+ if (m_handle->vts_pgcit && m_handle->vts_c_adt)
+ {
+ // add each cell in a list
+ // order this list according to vob ID, cell ID
+ // for each cell, find the duration (and start time) from all PGCs
+ GetPGCCells(*m_handle->vts_pgcit, *m_handle->vts_c_adt, &CellsHash);
+
+ // Transfer hash map to the list to be sorted
+ m_CellsList.clear();
+ =09
+ for(CellsHashType::iterator it =3D CellsHash.begin(); it !=3D CellsHa=
sh.end(); ++it )
+ {
+ m_CellsList.append(it.value());
+ }
+
+ m_CellsList.arrange();
+ }
+ }
+}
+// ---------------------------------------------------------------------=
-------
+void IFOContent::GetPGCCells(const pgcit_t & pgcit, const c_adt_t & adt,=
CellsHashType * CellsHash)
+{
+ CellListElem* cle;
+
+ for(int j=3D0; j < pgcit.nr_of_pgci_srp; j++)
+ {
+ pgci_srp_t& srp =3D pgcit.pgci_srp[j];
+ for(int k=3D0; k < srp.pgc->nr_of_cells; k++)
+ {
+ uint16_t vob_id =3D srp.pgc->cell_position[k].vob_id_nr;
+ uint8_t cell_id =3D srp.pgc->cell_position[k].cell_nr;
+
+ if (CellsHash->find(MAKE_CELLS_KEY(vob_id, cell_id)) =3D=3D CellsHash=
->end())
+ {
+ size_t cell_nr =3D adt.last_byte;
+ cell_nr -=3D 7;
+ cell_nr /=3D sizeof(cell_adr_t);
+ for (size_t l=3D0; l < cell_nr; l++)
+ {
+ if (adt.cell_adr_table[l].vob_id =3D=3D vob_id && adt.cell_adr_tabl=
e[l].cell_id =3D=3D cell_id)
+ {
+ cle =3D new CellListElem();
+ (*CellsHash)[MAKE_CELLS_KEY(vob_id, cell_id)] =3D cle;
+
+ cle->vobid =3D vob_id;
+ cle->cellid =3D cell_id;
+
+ cle->start_sector =3D adt.cell_adr_table[l].start_sector;
+ cle->last_sector =3D adt.cell_adr_table[l].last_sector;
+ cle->selected =3D true; // all cells selected for the moment
+ cle->found =3D false;
+ /* debug * / cle->found =3D true;*/
+
+ cle->nb_frames =3D dvdtime2frame(&srp.pgc->cell_playback[k].playba=
ck_time, cle->frame_dur);
+ cle->isStill =3D (srp.pgc->cell_playback[k].still_time > 0);
+ if (cle->isStill)
+ {
+ if (srp.pgc->cell_playback[k].still_time =3D=3D 0xFF) {
+ qWarning(QString("Still cell (%1.%2) detected with infinite dur=
ation !").arg(QString::number(vob_id), QString::number(cell_id)).toAscii(=
));
+ } else {
+ qWarning(QString("Still cell (%1.%2) detected. Assuming there i=
s just one frame.").arg(QString::number(vob_id), QString::number(cell_id)=
).toAscii());
+ cle->nb_frames =3D 1; // maybe not true ?
+ cle->frame_dur =3D srp.pgc->cell_playback[k].still_time * 1000.0=
/ cle->nb_frames;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+// ---------------------------------------------------------------------=
-------
+uint8_t IFOContent::FindAudioStream(uint8_t streamID, bool menu) const
+{
+ assert(m_handle !=3D NULL);
+ if (menu)
+ {
+ if (m_handle->pgci_ut)
+ {
+ for (int i=3D0; i<m_handle->pgci_ut->nr_of_lus; i++)
+ {
+ pgci_lu_t &_lu =3D m_handle->pgci_ut->lu[i];
+ for (int j=3D0; j < _lu.pgcit->nr_of_pgci_srp; j++)
+ {
+ pgc_t *_pgc =3D _lu.pgcit->pgci_srp[j].pgc;
+ if(_pgc->audio_control[streamID] & 0x8000) // if present
+ return (_pgc->audio_control[streamID] >> 8) & 0x7F;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (m_handle->vts_pgcit)
+ {
+ for (int j=3D0; j < m_handle->vts_pgcit->nr_of_pgci_srp; j++)
+ {
+ pgc_t *_pgc =3D m_handle->vts_pgcit->pgci_srp[j].pgc;
+ if(_pgc->audio_control[streamID] & 0x8000) // if present
+ return (_pgc->audio_control[streamID] >> 8) & 0x7F;
+ }
+ }
+ }
+ return streamID;
+}
+// ---------------------------------------------------------------------=
-------
+IdArray IFOContent::FindSubStream(uint8_t streamID, bool menu) const
+{
+ IdArray result;
+
+ assert(m_handle !=3D NULL);
+ if (menu)
+ {
+ if (m_handle->pgci_ut)
+ {
+ for (int i=3D0; i<m_handle->pgci_ut->nr_of_lus; i++)
+ {
+ pgci_lu_t &_lu =3D m_handle->pgci_ut->lu[i];
+ for (int j=3D0; j < _lu.pgcit->nr_of_pgci_srp; j++)
+ {
+ pgc_t *_pgc =3D _lu.pgcit->pgci_srp[j].pgc;
+ if(_pgc->subp_control[streamID] & 0x80000000) // if present
+ {
+ result.push_back( _pgc->subp_control[streamID] >> 24 & 0x7F);
+ if (_pgc->subp_control[streamID] & 0x007F0000)
+ result.push_back( _pgc->subp_control[streamID] >> 16 & 0x7F);
+ if (_pgc->subp_control[streamID] & 0x00007F00)
+ result.push_back( _pgc->subp_control[streamID] >> 8 & 0x7F);
+ if (_pgc->subp_control[streamID] & 0x0000007F)
+ result.push_back( _pgc->subp_control[streamID] >> 0 & 0x7F);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (m_handle->vts_pgcit)
+ {
+ for (int j=3D0; j < m_handle->vts_pgcit->nr_of_pgci_srp; j++)
+ {
+ pgc_t *_pgc =3D m_handle->vts_pgcit->pgci_srp[j].pgc;
+ if(_pgc->subp_control[streamID] & 0x80000000) // if present
+ {
+ result.push_back( _pgc->subp_control[streamID] >> 24 & 0x7F);
+ if (_pgc->subp_control[streamID] & 0x007F0000)
+ result.push_back( _pgc->subp_control[streamID] >> 16 & 0x7F);
+ if (_pgc->subp_control[streamID] & 0x00007F00)
+ result.push_back( _pgc->subp_control[streamID] >> 8 & 0x7F);
+ if (_pgc->subp_control[streamID] & 0x0000007F)
+ result.push_back( _pgc->subp_control[streamID] >> 0 & 0x7F);
+ }
+ }
+ }
+ }
+
+ return result;
+}
+// ---------------------------------------------------------------------=
-------
\ No newline at end of file
Added: trunk/DvdMenuXtractor/vobparser/IFOContent.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/vobparser/IFOContent.h 2007-01-22 11:21:16 UTC =
(rev 1269)
+++ trunk/DvdMenuXtractor/vobparser/IFOContent.h 2007-01-28 16:48:11 UTC =
(rev 1270)
@@ -0,0 +1,71 @@
+// ---------------------------------------------------------------------=
-------
+#ifndef _IFO_CONTENT_H_
+#define _IFO_CONTENT_H_
+// ---------------------------------------------------------------------=
-------
+#include <QHash>
+#include <vector>
+
+#include "VobParser.h"
+#include "dvdread/ifo_read.h"
+// ---------------------------------------------------------------------=
-------
+typedef std::vector<uint8_t> IdArray;
+
+typedef QHash<int, CellListElem *> CellsHashType;
+typedef std::vector<const audio_attr_t*> AudioTrackList;
+typedef std::vector<const subp_attr_t*> SubtitleTrackList;
+
+#define MAKE_CELLS_KEY(vob_id,cell_id) ((vob_id << 8) | cell_id)
+// ---------------------------------------------------------------------=
-------
+class IFOException { };
+class IFOFileIOException : public IFOException { };
+class IFOInvalidFileFormatException : public IFOException { };
+// ---------------------------------------------------------------------=
-------
+typedef QList<CellListElem*> CellsListBaseType;
+class CellsListType : public CellsListBaseType
+{
+public:
+ void arrange();
+ CellListElem* at(uint16_t vob_id, uint8_t cell_id) const;
+ const CellListElem* at(const cell_position_t & position) const;
+
+ // comperator for qSort()
+ static int cellListElemCompare(const CellListElem *arg1, const CellList=
Elem *arg2);
+};
+// ---------------------------------------------------------------------=
-------
+class IFOContent=20
+{
+public:
+ IFOContent(dvd_reader_t *dvdr, int16_t title);
+
+ ~IFOContent()
+ {
+ ifoClose(m_handle);
+ m_CellsList.clear();
+ m_langCellsList.clear();
+ }
+
+ ifo_handle_t& Handle()
+ {
+ assert(m_handle !=3D NULL);
+ return *m_handle;
+ }
+
+ IdArray FindSubStream(uint8_t streamID, bool menu) const;
+ uint8_t FindAudioStream(uint8_t streamID, bool menu) const;
+=09
+ void GetPGCCells(const pgcit_t & pgcit, const c_adt_t & adt, CellsHashT=
ype * CellsHash);
+
+ int16_t m_title;
+ AudioTrackList m_langAudio;
+ AudioTrackList m_Audio;
+ SubtitleTrackList m_langSubs;
+ SubtitleTrackList m_Subs;
+ CellsListType m_CellsList;
+ CellsListType m_langCellsList;
+
+protected:
+ ifo_handle_t *m_handle;
+};
+// ---------------------------------------------------------------------=
-------
+#endif
+// ---------------------------------------------------------------------=
-------
\ No newline at end of file
Added: trunk/DvdMenuXtractor/vobparser/IFOFile.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/vobparser/IFOFile.cpp 2007-01-22 11:21:16 UTC (=
rev 1269)
+++ trunk/DvdMenuXtractor/vobparser/IFOFile.cpp 2007-01-28 16:48:11 UTC (=
rev 1270)
@@ -0,0 +1,304 @@
+// ---------------------------------------------------------------------=
-------
+#include "IFOFile.h"
+#include "iso/iso_lang.h"
+#include "dvdread/ifo_print.h"
+// ---------------------------------------------------------------------=
-------
+IFOFile::IFOFile(const QString& filename)
+{=09
+ m_dvd =3D DVDOpen(qPrintable(filename));
+=09
+ if(!m_dvd) {
+ throw IFOInvalidFileFormatException();
+ }
+
+ try {
+ m_ifos.append(new IFOContent(m_dvd, 0)); =09
+ }
+ catch (...) {
+ qCritical("Cannot open VIDEO_TS.IFO.");
+ throw;
+ }
+
+ IFOContent *_ifo =3D m_ifos.getIfoContent(0);
+
+ if (_ifo && _ifo->Handle().vmgi_mat)
+ {
+ for (int i =3D 1; i <=3D _ifo->Handle().vmgi_mat->vmg_nr_of_title_sets=
; i++)
+ {
+ try {
+ m_ifos.append(new IFOContent(m_dvd,i));
+ }
+ catch (...) {
+ qCritical(QString("Cannot open VTS_%1_X.IFO").arg(i).toAscii());
+ }
+ }
+ }
+}
+// ---------------------------------------------------------------------=
-------
+IFOFile::~IFOFile()
+{
+ for (int i =3D 0; i < m_ifos.size(); i++)
+ delete m_ifos.at(i);
+=09
+ if (m_dvd)
+ {
+ DVDClose(m_dvd);
+ }
+}
+// ---------------------------------------------------------------------=
-------
+const pgc_t *IFOFile::FirstPlayPGC() const
+{
+ if (m_ifos.at(0))
+ return m_ifos.at(0)->Handle().first_play_pgc;
+ else
+ return NULL;
+}
+// ---------------------------------------------------------------------=
-------
+const tt_srpt_t *IFOFile::TitleMap() const
+{
+ if (m_ifos.at(0))
+ return m_ifos.at(0)->Handle().tt_srpt;
+ else
+ return NULL;
+}
+// ---------------------------------------------------------------------=
-------
+const pgci_ut_t *IFOFile::LanguageUnits(unsigned int title) const
+{
+ IFOContent *_ifo =3D m_ifos.getIfoContent(title);
+ if (_ifo)
+ {
+ return _ifo->Handle().pgci_ut;
+ }
+ =09
+ return NULL;
+}
+// ---------------------------------------------------------------------=
-------
+const vts_ptt_srpt_t *IFOFile::VtsTitles(unsigned int title) const
+{
+ IFOContent *_ifo =3D m_ifos.getIfoContent(title);
+ if (_ifo)
+ {
+ return _ifo->Handle().vts_ptt_srpt;
+ }
+ return NULL;
+}
+// ---------------------------------------------------------------------=
-------
+const pgcit_t *IFOFile::VtsPGCs(unsigned int title) const
+{
+ IFOContent *_ifo =3D m_ifos.getIfoContent(title);
+ if (_ifo)
+ {
+ return _ifo->Handle().vts_pgcit;
+ }
+ return NULL;
+}
+// ---------------------------------------------------------------------=
-------
+const int16_t IFOFile::NumberOfTitles() const
+{
+ if (m_ifos.count() && m_ifos.at(0)->Handle().vmgi_mat)
+ return m_ifos.at(0)->Handle().vmgi_mat->vmg_nr_of_title_sets;
+ return 0;
+}
+// ---------------------------------------------------------------------=
-------
+int CellsListType::cellListElemCompare(const CellListElem *arg1, const C=
ellListElem *arg2)
+{
+ const CellListElem* cle1 =3D arg1;
+ const CellListElem* cle2 =3D arg2;
+
+ return (cle1->vobid > cle2->vobid) ? 1 :
+ (cle1->vobid < cle2->vobid) ? -1 :
+ (cle1->cellid > cle2->cellid) ? 1 :=20
+ (cle1->cellid < cle2->cellid) ? -1 :
+ 0;
+}
+// ---------------------------------------------------------------------=
-------
+const CellsListType* IFOFile::GetCellsList(unsigned int title, bool menu=
)
+{
+ CellsHashType CellsHash;
+
+ IFOContent *ifoc =3D m_ifos.getIfoContent(title);
+ if (!ifoc)
+ return NULL;
+
+ if (menu)
+ return &ifoc->m_langCellsList;
+ else
+ return &ifoc->m_CellsList;
+}
+// ---------------------------------------------------------------------=
-------
+const AudioTrackList & IFOFile::AudioTracks(unsigned int title, bool men=
u) const
+{
+ IFOContent *_ifo =3D m_ifos.getIfoContent(title);
+ if (!_ifo)
+ throw;
+
+ if (menu)
+ return _ifo->m_langAudio;
+ else
+ return _ifo->m_Audio;
+}
+// ---------------------------------------------------------------------=
-------
+const SubtitleTrackList & IFOFile::SubsTracks(unsigned int title, bool m=
enu) const
+{
+ IFOContent *_ifo =3D m_ifos.getIfoContent(title);
+ if (!_ifo)
+ throw;
+
+ if (menu)
+ return _ifo->m_langSubs;
+ else
+ return _ifo->m_Subs;
+}
+// ---------------------------------------------------------------------=
-------
+const CellsListType & IFOFile::CellsList(unsigned int title, bool menu) =
const
+{
+ IFOContent *_ifo =3D m_ifos.getIfoContent(title);
+ if (!_ifo)
+ throw;
+
+ if (menu)
+ return _ifo->m_langCellsList;
+ else
+ return _ifo->m_CellsList;
+}
+// ---------------------------------------------------------------------=
-------
+bool IFOFile::VideoSize(unsigned int title, bool menu, uint16_t & width,=
uint16_t & height, double & fps) const
+{
+ IFOContent *_ifo =3D m_ifos.getIfoContent(title);
+ assert(_ifo !=3D NULL);
+ video_attr_t *_attr =3D NULL;
+ if (menu)
+ {
+ if (title =3D=3D 0)
+ {
+ if (_ifo->Handle().vmgi_mat)
+ {
+ _attr =3D &_ifo->Handle().vmgi_mat->vmgm_video_attr;
+ }
+ }
+ else
+ {
+ if (_ifo->Handle().vtsi_mat)
+ {
+ _attr =3D &_ifo->Handle().vtsi_mat->vtsm_video_attr;
+ }
+ }
+ }
+ else
+ {
+ if (_ifo->Handle().vtsi_mat)
+ {
+ _attr =3D &_ifo->Handle().vtsi_mat->vts_video_attr;
+ }
+ }
+
+ if (_attr !=3D NULL)
+ {
+ height =3D 480;
+ if(_attr->video_format !=3D 0) {
+ fps =3D 25.0;
+ height =3D 576;
+ } else {
+ fps =3D 30000.0/1001.0;
+ }
+ switch(_attr->picture_size) {
+ case 0:
+ width =3D 720;
+ break;
+ case 1:
+ width =3D 704;
+ break;
+ case 2:
+ width =3D 352;
+ break;
+ case 3:
+ width =3D 352;
+ height >>=3D 1;
+ break; =20
+ }
+ return true;
+ }
+ return false;
+}
+// ---------------------------------------------------------------------=
-------
+const uint32_t * IFOFile::GetPalette(unsigned int title, bool menu) cons=
t
+{
+ IFOContent *_ifo =3D m_ifos.getIfoContent(title);
+ assert(_ifo !=3D NULL);
+ video_attr_t *_attr =3D NULL;
+=09
+ if (menu)
+ return (_ifo->Handle().pgci_ut->lu->pgcit->pgci_srp->pgc->palette);
+ else
+ return (_ifo->Handle().vts_pgcit->pgci_srp->pgc->palette);
+
+ return NULL;
+}
+// ---------------------------------------------------------------------=
-------
+uint8_t IFOFile::GetAudioId(uint8_t streamID, uint8_t title, bool menu) =
const
+{
+ IFOContent *_ifo =3D m_ifos.getIfoContent(title);
+ if (!_ifo)
+ throw;
+
+ return _ifo->FindAudioStream(streamID, menu);
+}
+// ---------------------------------------------------------------------=
-------
+IdArray IFOFile::GetSubsId(uint8_t streamID, uint8_t title, bool menu) c=
onst
+{
+ IFOContent *_ifo =3D m_ifos.getIfoContent(title);
+ if (!_ifo)
+ throw;
+
+ return _ifo->FindSubStream(streamID, menu);
+}
+// ---------------------------------------------------------------------=
-------
+IFOContent * IfoHandleList::getIfoContent(int16_t title) const
+{
+ for (size_type _index =3D 0; _index < size(); _index++)
+ {
+ if (at(_index)->m_title =3D=3D title)
+ return at(_index);
+ }
+ return NULL;
+}
+// ---------------------------------------------------------------------=
-------
+const CellListElem* CellsListType::at(const cell_position_t & position) =
const
+{
+ return at(position.vob_id_nr, position.cell_nr);
+}
+// ---------------------------------------------------------------------=
-------
+CellListElem* CellsListType::at(uint16_t vob_id, uint8_t cell_id) const
+{
+ CellsListType::const_iterator node =3D begin();
+ while (node !=3D end())
+ {
+ CellListElem *cell =3D *node;
+ =09
+ if (cell->cellid =3D=3D cell_id && cell->vobid =3D=3D vob_id)
+ return cell;
+ =09
+ ++node;
+ }
+=09
+ return NULL;
+}
+// ---------------------------------------------------------------------=
-------
+void CellsListType::arrange()
+{
+ qSort(begin(), end(), &CellsListType::cellListElemCompare);
+
+ // make the timecodes continuous
+ int64_t timecode =3D 0;
+ CellsListType::const_iterator node =3D begin();
+ while (node !=3D end())
+ {
+ CellListElem *cell =3D *node;
+ cell->start_time =3D timecode;
+ cell->duration =3D int64_t(cell->frame_dur * cell->nb_frames * 1000000=
.0);
+ if (cell->found)
+ timecode +=3D cell->duration;
+ ++node;
+ }
+}
+// ---------------------------------------------------------------------=
-------
\ No newline at end of file
Added: trunk/DvdMenuXtractor/vobparser/IFOFile.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/vobparser/IFOFile.h 2007-01-22 11:21:16 UTC (re=
v 1269)
+++ trunk/DvdMenuXtractor/vobparser/IFOFile.h 2007-01-28 16:48:11 UTC (re=
v 1270)
@@ -0,0 +1,43 @@
+// ---------------------------------------------------------------------=
-------
+#ifndef _IFO_FILE_H_
+#define _IFO_FILE_H_
+// ---------------------------------------------------------------------=
-------
+#include <QStringList>
+
+#include "IfoContent.h"
+// ---------------------------------------------------------------------=
-------
+class IfoHandleList: public QList<IFOContent*>
+{
+public:
+ /// look for IfoContent corresponding to the title
+ IFOContent* getIfoContent(int16_t title) const;
+};
+// ---------------------------------------------------------------------=
-------
+class IFOFile =20
+{
+public:
+ IFOFile(const QString& filename);
+ const CellsListType* GetCellsList(unsigned int title, bool menu);
+ virtual ~IFOFile();
+ const pgc_t *FirstPlayPGC() const;
+ const tt_srpt_t *TitleMap() const;
+ const pgci_ut_t *LanguageUnits(unsigned int title) const;
+ const vts_ptt_srpt_t *VtsTitles(unsigned int title) const;
+ const pgcit_t *VtsPGCs(unsigned int title) const;
+ const int16_t NumberOfTitles() const;
+ const AudioTrackList & AudioTracks(unsigned int title, bool menu) const=
;
+ const SubtitleTrackList & SubsTracks(unsigned int title, bool menu) con=
st;
+ const CellsListType & CellsList(unsigned int title, bool menu) const;
+ bool VideoSize(unsigned int title, bool menu, uint16_t & width, uint16_=
t & height, double & fps) const;
+ const uint32_t * GetPalette(unsigned int title, bool menu) const;
+
+ uint8_t GetAudioId(uint8_t streamID, uint8_t title, bool menu) const;
+ IdArray GetSubsId(uint8_t streamID, uint8_t title, bool menu) const;
+
+private:
+ IfoHandleList m_ifos;
+ dvd_reader_t* m_dvd;
+};
+// ---------------------------------------------------------------------=
-------
+#endif
+// ---------------------------------------------------------------------=
-------
Added: trunk/DvdMenuXtractor/vobparser/VobParser.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/vobparser/VobParser.cpp 2007-01-22 11:21:16 UTC=
(rev 1269)
+++ trunk/DvdMenuXtractor/vobparser/VobParser.cpp 2007-01-28 16:48:11 UTC=
(rev 1270)
@@ -0,0 +1,1310 @@
+// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
+// VOBParser class
+// Copyright =A9 2002 : Christophe PARIS (christophe.paris at free.fr)
+// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
+
+#include <QFileInfo>
+
+#include "IFOFile.h"
+#include "VobParser.h"
+#include "iso/iso_lang.h"
+
+// ---------------------------------------------------------------------=
-------
+
+#define VOB_SLICE 0x00000100
+#define PACK_HEADER 0xBA
+#define SYSTEM_HEADER 0xBB
+#define PROGRAM_STREAM_MAP 0xBC
+#define PRIVATE_STREAM1 0xBD
+#define PADDING_STREAM 0xBE
+#define PRIVATE_STREAM2 0xBF
+#define CURRENT_OFFSET (m_pktindex * DVD_VIDEO_LB_LEN + m_index)
+
+#define INDENT_UNIT 2
+unsigned int indent_lvl =3D 0;
+inline void inc_lvl() { indent_lvl +=3D INDENT_UNIT; }
+inline void dec_lvl() { indent_lvl -=3D INDENT_UNIT; }
+void debug (const QString& str)
+{
+ QString debugStr (indent_lvl, ' ');
+ debugStr +=3D str;
+ qDebug(qPrintable(debugStr));
+}
+
+// ---------------------------------------------------------------------=
-------
+// CompositeDemuxWriter
+// ---------------------------------------------------------------------=
-------
+
+CompositeDemuxWriter::CompositeDemuxWriter()
+{
+ for (int i=3D0; i<256; i++)
+ m_muxers[i] =3D NULL;
+}
+
+CompositeDemuxWriter::~CompositeDemuxWriter()
+{
+ Reset();
+}
+
+bool CompositeDemuxWriter::AddDemuxer(uint8_t streamID, Writer * demuxer=
, QString& CommandLine)
+{
+ if (m_muxers[streamID] !=3D NULL)
+ return false;
+ m_muxers[streamID] =3D demuxer;
+ m_strings[streamID] =3D CommandLine;
+ return true;
+}
+
+void CompositeDemuxWriter::ProcessStream(int streamID, uint8_t* buff, ui=
nt32_t size, int32_t start_time, int32_t end_time, const QString& debug)
+{
+ if (m_muxers[streamID] !=3D NULL)
+ m_muxers[streamID]->ProcessStream(buff, size, start_time, end_time, de=
bug);
+}
+
+void CompositeDemuxWriter::Reset()
+{
+ for (int i=3D0; i<256; i++)
+ {
+ if (m_muxers[i] !=3D NULL)
+ {
+ delete m_muxers[i];
+ m_muxers[i] =3D NULL;
+ }
+ }
+}
+
+void CompositeDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t=
duration, const CellListElem *cell)
+{
+ for (int i=3D0; i<256; i++)
+ {
+ if (m_muxers[i] !=3D NULL)
+ {
+ m_muxers[i]->SetBoundary(start_timecode, duration, cell);
+ }
+ }
+}
+
+// ---------------------------------------------------------------------=
-------
+
+VobParser::VobParser(const char* dirname, int16_t title, bool menu)
+ :m_title(title)
+ ,m_dvdhandle(NULL)
+ ,m_stream(NULL)
+ ,m_language(menu)
+ ,m_bFirstPacket(true)
+{
+ m_pktcount =3D 0;
+
+ QFileInfo _tmpDirName(dirname);
+
+ // handle all parts of this title (VIDEO_TS.vob or VTS_XX_Y.vob)
+ m_dvdhandle =3D DVDOpen(qPrintable(_tmpDirName.canonicalPath()));
+
+ if (m_dvdhandle)
+ {
+ if (m_language)
+ m_stream =3D DVDOpenFile(m_dvdhandle, title, DVD_READ_MENU_VOBS);
+ else
+ m_stream =3D DVDOpenFile(m_dvdhandle, title, DVD_READ_TITLE_VOBS);
+ }
+
+ if(!m_stream)
+ {
+ throw VobParserFileNotFoundException(dirname);
+ }
+ else
+ {
+ m_pktcount =3D DVDFileSize(m_stream);
+ }
+
+ Reset();
+}
+
+// ---------------------------------------------------------------------=
-------
+
+VobParser::~VobParser()
+{
+ if (m_stream)
+ DVDCloseFile(m_stream);
+
+ if (m_dvdhandle)
+ DVDClose(m_dvdhandle);
+}
+
+// ---------------------------------------------------------------------=
-------
+
+uint32_t VobParser::GetPacketCount() const
+{
+ return m_pktcount;
+}
+
+// ---------------------------------------------------------------------=
-------
+
+uint32_t VobParser::GetPacketIndex() const
+{
+ return m_pktindex;
+}
+
+// ---------------------------------------------------------------------=
-------
+
+char* VobParser::GetCurrentPacketData() const
+{
+ return (char*)m_buff;
+}
+
+// ---------------------------------------------------------------------=
-------
+
+bool VobParser::ParseNextPacket(const CellsListType & Cells)
+{
+ if(GetNextPacket())
+ {=09
+ pktinfo.identifier =3D GetNext32Bits();
+ if((pktinfo.identifier & VOB_SLICE) !=3D VOB_SLICE || (pktinfo.identif=
ier & PACK_HEADER) !=3D PACK_HEADER)
+ {
+ // Invalid block start code
+ throw VobParserInvalidPacketException(CURRENT_OFFSET-4);
+ }
+ =09
+ ParseSCR(); // System Clock Reference
+
+ // Program Mux Rate (measured in units of 50 bytes/second)
+ pktinfo.program_mux_rate =3D (GetNext8Bits() << 14) |=20
+ (GetNext8Bits() << 6) | (GetNext8Bits() >> 2);
+
+ // Skip Pack stuffing length
+ int stuffing_nb =3D GetNext8Bits() & 0x07;
+ SkipNBytes(stuffing_nb);
+ =09
+ uint32_t _Header =3D GetNext32Bits();
+ int _StreamID;
+ if ((_Header & VOB_SLICE) =3D=3D VOB_SLICE)
+ {
+ _StreamID =3D _Header & 0xFF;
+ if (_StreamID =3D=3D SYSTEM_HEADER)
+ {
+ // skip the system header data
+ uint16_t _size =3D GetNext16Bits();
+ SkipNBytes(_size);
+
+ while (AvailablePacketData())
+ {
+ _Header =3D GetNext32Bits();
+ uint8_t _StreamId =3D _Header & 0xFF;
+ if (_StreamId =3D=3D PRIVATE_STREAM2)
+ {
+ debug("Navigation pack {\n");
+ inc_lvl();
+ debug(QString("SCR: %1.%2\n").arg(pktinfo.scr).arg(pktinfo.scr_ext=
));
+ debug(QString("Program mux rate: %1 (%2 bps)\n").arg(pktinfo.progr=
am_mux_rate).arg(pktinfo.program_mux_rate * 50 * 8));
+ ParseNavPacket();
+ dec_lvl();
+ debug("}\n");
+ }
+ else
+ {
+ // skip these data
+ uint16_t _size =3D GetNext16Bits();
+ SkipNBytes(_size);
+ }
+ }
+ if (IsNewCell()) {
+ CellListElem* cell =3D Cells.at(GetVobID(), GetCellID());
+
+ if (cell !=3D NULL)
+ {
+ cell->found =3D true;
+ if (m_dsi.nv_pck_scr =3D=3D 0)
+ m_pci_vob_timecode_offset =3D m_pci.vobu_s_ptm / 90;
+ m_demuxer.SetBoundary(m_pci.vobu_s_ptm/90 - m_pci_vob_timecode_off=
set, cell->nb_frames * cell->frame_dur, cell);
+ }
+ }
+ if (m_pci.btn_ns !=3D 0)
+ { // there are some buttons
+ uint32_t t3 =3D m_pci.vobu_s_ptm/90 - m_pci_vob_timecode_offset;
+ uint32_t t4 =3D m_pci.vobu_e_ptm/90 - m_pci_vob_timecode_offset;
+ m_demuxer.ProcessStream(SUBSTREAM_PCI, &m_buff[m_pci_position], m_p=
ci_size+2, t3, t4,=20
+ QString("# %1 -> %2 / %3 / %4 / %5 / %6 / off %7\n")
+ .arg(m_pci.vobu_s_ptm/90).arg(m_pci.vobu_e_ptm/90)
+ .arg(m_dsi.c_eltm, 0, 16).arg(m_pci.c_eltm, 0, 16)
+ .arg(t3).arg(t4).arg(m_pci_vob_timecode_offset));
+ =09
+ }
+ }
+ else if ((_StreamID & VIDEO_STREAM) =3D=3D VIDEO_STREAM)
+ {
+ debug("Video pack {}\n");
+ ParseVideoPacket();
+ }
+ else if ((_StreamID & AUDIO_STREAM) =3D=3D AUDIO_STREAM)
+ {
+ debug("Audio pack {}\n");
+ ParseAudioPacket(_StreamID);
+ }
+ else if (_StreamID =3D=3D PRIVATE_STREAM1)
+ {
+ debug("Private stream 1 pack {\n");
+ inc_lvl();
+ ParsePrivateStream1();
+ dec_lvl();
+ debug("}\n");
+ }
+ else
+ {
+ uint16_t _size =3D GetNext16Bits();
+ SkipNBytes(_size);
+ debug("Unknown slice type\n");
+ }
+
+ if (m_bFirstPacket && _StreamID !=3D SYSTEM_HEADER)
+ {
+ m_bFirstPacket =3D false;
+ m_startdts =3D pktinfo.dts;
+ m_startpts =3D pktinfo.pts;
+ }
+ }
+ else
+ {
+ debug("Unknown start code\n");
+ }
+ =09
+ m_pktindex++;
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
+
+// ---------------------------------------------------------------------=
-------
+
+bool VobParser::AvailablePacketData() const
+{
+ return (m_index < DVD_VIDEO_LB_LEN);
+}
+
+// ---------------------------------------------------------------------=
-------
+
+bool VobParser::GetNextPacket()
+{
+ m_index =3D 0;
+
+ return (DVDReadBlocks(m_stream, m_pktindex, 1, m_buff) =3D=3D 1);
+}
+
+// ---------------------------------------------------------------------=
-------
+
+uint32_t VobParser::GetNext32Bits()
+{
+ uint32_t result =3D 0;
+ result |=3D m_buff[m_index++];
+ result <<=3D 8;
+ result |=3D m_buff[m_index++];
+ result <<=3D 8;
+ result |=3D m_buff[m_index++];
+ result <<=3D 8;
+ result |=3D m_buff[m_index++];
+ return result;
+}
+
+// ---------------------------------------------------------------------=
-------
+
+uint16_t VobParser::GetNext16Bits()
+{
+ uint32_t result =3D 0;
+ result |=3D m_buff[m_index++];
+ result <<=3D 8;
+ result |=3D m_buff[m_index++];
+ return result;
+}
+
+// ---------------------------------------------------------------------=
-------
+
+uint8_t VobParser::GetNext8Bits()
+{
+ return m_buff[m_index++];
+}
+
+// ---------------------------------------------------------------------=
-------
+
+void VobParser::SkipNBytes(int n)
+{
+ m_index +=3D n;
+}
+
+// ---------------------------------------------------------------------=
-------
+
+void VobParser::ParseSCR()
+{
+
+/* From http://dvd.sourceforge.net/dvdinfo/packhdr.html
+
+ Byte 4 Byte 5
+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+
+ | 7| 6| 5| 4| 3| 2| 1| 0| | 7| 6| 5| 4| 3| 2| 1| 0|
+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+
+SCR bits |f0|f1|32|31|30|f1|29|28| |27|26|25|24|23|22|21|20|
+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+
+
+ Byte 6 Byte 7
+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+
+ | 7| 6| 5| 4| 3| 2| 1| 0| | 7| 6| 5| 4| 3| 2| 1| 0|
+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+
+SCR bits |19|18|17|16|15|f1|14|13| |12|11|10| 9| 8| 7| 6| 5|
+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+
+
+ Byte 8 Byte 9
+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+
+ | 7| 6| 5| 4| 3| 2| 1| 0| | 7| 6| 5| 4| 3| 2| 1| 0|
+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+
+SCR bits | 4| 3| 2| 1| 0|f1|e8|e7| |e6|e5|e4|e3|e2|f1|e0|c1|
+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+
+
+ fx =3D bit value fixed to x
+ ex =3D bit x of scr_ext
+*/
+
+ uint8_t byte4, byte5, byte6, byte7, byte8, byte9;
+ byte4 =3D GetNext8Bits(); byte5 =3D GetNext8Bits();
+ byte6 =3D GetNext8Bits(); byte7 =3D GetNext8Bits();
+ byte8 =3D GetNext8Bits(); byte9 =3D GetNext8Bits();
+
+ assert((byte4 & 0xc4) =3D=3D 0x44);
+ assert(byte6 & 0x04);
+ assert(byte8 & 0x04);
+ assert(byte9 & 0x01);
+ =09
+ uint64_t scr =3D 0;
+ scr |=3D ((((byte4 & 0x38) >> 1) | (byte4 & 0x03)) << 28);
+ scr |=3D (byte5 << 20);
+ scr |=3D ((((byte6 & 0xf8) >> 1) | (byte6 & 0x03)) << 13);
+ scr |=3D (byte7 << 5);
+ scr |=3D ((byte8 & 0xf8) >> 3);
+
+ uint16_t scr_ext =3D 0;
+ scr_ext |=3D ((byte8 & 0x03) << 7);
+ scr_ext |=3D ((byte9 & 0xfe) >> 1);
+
+ pktinfo.scr =3D scr;
+ pktinfo.scr_ext =3D scr_ext;
+}
+
+// ---------------------------------------------------------------------=
-------
+
+void VobParser::ParseNavPacket()
+{
+ uint32_t endStreamIndex =3D 0;
+ uint32_t position =3D m_index;
+ uint16_t length =3D GetNext16Bits();
+ endStreamIndex =3D m_index + length;
+ uint8_t substreamID =3D GetNext8Bits();
+=09
+ switch(substreamID)
+ {
+ case SUBSTREAM_PCI:
+ debug("PCI {\n");
+ inc_lvl();
+ ParsePCI();
+ m_pci_position =3D position-4; // keep the Private Stream 2 header
+ m_pci_size =3D length+4;
+ dec_lvl();
+ debug("}\n");
+ break;
+ case SUBSTREAM_DSI:
+ debug("DSI {\n");
+ inc_lvl();
+ ParseDSI();
+ dec_lvl();
+ debug("}\n");
+ break;
+ default:
+ debug(QString("ParseNavPacket: unknown substream id @LBA=3D%1\n").arg=
(m_pktindex));
+ }
+=09
+ m_index =3D endStreamIndex;
+}
+
+// ---------------------------------------------------------------------=
-------
+
+void VobParser::ParsePCI()
+{
+ int i,j;
+ uint8_t onebyte;
+
+ // PCI General Information
+ m_pci.nv_pck_lbn =3D GetNext32Bits();
+ m_pci.vobu_cat =3D GetNext16Bits();
+ m_pci.reserved1 =3D GetNext16Bits();
+ m_pci.vobu_uop_ctl =3D GetNext32Bits();
+ m_pci.vobu_s_ptm =3D GetNext32Bits();
+ m_pci.vobu_e_ptm =3D GetNext32Bits();
+ m_pci.vobu_se_e_ptm =3D GetNext32Bits();
+ m_pci.c_eltm =3D GetNext32Bits();
+ memcpy(m_pci.vobu_isrc, &m_buff[m_index],32*1);=09
+ SkipNBytes(32*1);
+
+ // Non Seamless Angle Information
+ memcpy(m_pci.nsml_agli_dsta, &m_buff[m_index], 9*4);
+ SkipNBytes(9*4);
+
+ // Highlight General Information=20
+ m_pci.hli_ss =3D GetNext16Bits();
+ m_pci.hli_s_ptm =3D GetNext32Bits();
+ m_pci.hli_e_ptm =3D GetNext32Bits();
+ m_pci.btn_sl_e_ptm =3D GetNext32Bits();
+ m_pci.btn_md =3D GetNext16Bits();
+ m_pci.btn_sn =3D GetNext8Bits();
+ m_pci.btn_ns =3D GetNext8Bits();
+ m_pci.nsl_btn_ns =3D GetNext8Bits();
+ m_pci.reserved1 =3D GetNext8Bits();
+ m_pci.fosl_btnn =3D GetNext8Bits();
+ m_pci.foac_btnn =3D GetNext8Bits();
+=09
+ // Button Color Information Table=20
+ for(i =3D 0; i < 3; i++)
+ for(j =3D 0; j < 2; j++)
+ m_pci.btn_coli[i][j] =3D GetNext32Bits();
+
+ // Button Information
+ for(i =3D 0; i < 36; i++)
+ {
+ onebyte =3D GetNext8Bits();
+ m_pci.btnit[i].btn_coln =3D (onebyte & 0xC0) >> 6;
+ m_pci.btnit[i].start_x =3D (onebyte & 0x3F) << 4;
+
+ onebyte =3D GetNext8Bits();
+ m_pci.btnit[i].start_x |=3D (onebyte & 0xF0) >> 4;
+ m_pci.btnit[i].end_x =3D (onebyte & 0x03) << 8;
+
+ onebyte =3D GetNext8Bits();
+ m_pci.btnit[i].end_x |=3D onebyte;
+
+ onebyte =3D GetNext8Bits();
+ m_pci.btnit[i].auto_action_flag =3D (onebyte & 0xC0) >> 6;
+ m_pci.btnit[i].start_y =3D (onebyte & 0x3F) << 4;
+ =09
+ onebyte =3D GetNext8Bits();
+ m_pci.btnit[i].start_y |=3D (onebyte & 0xF0) >> 4;
+ m_pci.btnit[i].end_y =3D (onebyte & 0x03) << 8;
+ =09
+ onebyte =3D GetNext8Bits();
+ m_pci.btnit[i].end_y |=3D onebyte;
+
+ m_pci.btnit[i].up =3D GetNext8Bits() & 0x3F;
+ m_pci.btnit[i].down =3D GetNext8Bits() & 0x3F;
+ m_pci.btnit[i].left =3D GetNext8Bits() & 0x3F;
+ m_pci.btnit[i].right =3D GetNext8Bits() & 0x3F;
+ =09
+ memcpy(m_pci.btnit[i].vm_cmd, &m_buff[m_index],8*1);
+ SkipNBytes(8*1);
+ }
+
+ debug(QString("nv_pck_lbn: %1\n").arg(m_pci.nv_pck_lbn));
+ debug(QString("vobu_cat: %1\n").arg(m_pci.vobu_cat));
+ debug(QString("reserved1: %1\n").arg(m_pci.reserved1));
+ debug(QString("vobu_uop_ctl: %1\n").arg(m_pci.vobu_uop_ctl));
+ debug(QString("vobu_s_ptm: %1\n").arg(m_pci.vobu_s_ptm));
+ debug(QString("vobu_e_ptm: %1\n").arg(m_pci.vobu_e_ptm));
+ debug(QString("vobu_se_e_ptm: %1\n").arg(m_pci.vobu_se_e_ptm));
+ debug(QString("e_eltm: %1\n").arg(m_pci.c_eltm));
+ debug(QString("vobu_isrc: ...\n").toAscii());
+ debug(QString("nsml_agli_dsta: ...\n").toAscii());
+ debug(QString("hli_ss: %1\n").arg(m_pci.hli_ss));
+}
+
+// ---------------------------------------------------------------------=
-------
+
+void VobParser::ParseDSI()
+{
+ m_dsi.nv_pck_scr =3D GetNext32Bits();
+ m_dsi.nv_pck_lbn =3D GetNext32Bits();
+ m_dsi.vobu_ea =3D GetNext32Bits();
+ m_dsi.vobu_1stref_ea =3D GetNext32Bits();
+ m_dsi.vobu_2ndref_ea =3D GetNext32Bits();
+ m_dsi.vobu_3rdref_ea =3D GetNext32Bits();
+ m_dsi.vobu_vob_idn =3D GetNext16Bits();
+ m_dsi.reserved =3D GetNext8Bits();
+ m_dsi.vobu_c_idn =3D GetNext8Bits();
+ m_dsi.c_eltm =3D GetNext32Bits();
+
+ debug(QString("nv_pck_scr: %1\n").arg(m_dsi.nv_pck_scr));
+ debug(QString("nv_pck_lbn: %1\n").arg(m_dsi.nv_pck_lbn));
+ debug(QString("vobu_ea: %1\n").arg(m_dsi.vobu_ea));
+ debug(QString("vobu_1stref_ea: %1\n").arg(m_dsi.vobu_1stref_ea));
+ debug(QString("vobu_2ndref_ea: %1\n").arg(m_dsi.vobu_2ndref_ea));
+ debug(QString("vobu_3rdref_ea: %1\n").arg(m_dsi.vobu_3rdref_ea));
+ debug(QString("vobu_vob_idn: %1\n").arg(m_dsi.vobu_vob_idn));
+ debug(QString("reserved: %1\n").arg(m_dsi.reserved));
+ debug(QString("vobu_c_idn: %1\n").arg(m_dsi.vobu_c_idn));
+ debug(QString("c_eltm: %1\n").arg(m_dsi.c_eltm));
+}
+
+// ---------------------------------------------------------------------=
-------
+
+uint8_t GetBit(uint32_t data, uint8_t n)
+{
+ return ((data >> n) & 0x01);
+}
+
+// ---------------------------------------------------------------------=
-------
+
+void VobParser::ParsePESHeaderDataContentFlag()
+{=09
+ uint8_t byte6 =3D GetNext8Bits();
+ assert((byte6 & 0xC0) =3D=3D 0x80);
+ pes_header_data_content.PES_scrambling_control =3D (byte6 & 0x30) >> 4;
+ pes_header_data_content.PES_priority =3D GetBit(byte6,3);
+ pes_header_data_content.data_alignment_indicator =3D GetBit(byte6,2);
+ pes_header_data_content.copyright =3D GetBit(byte6,1);
+ pes_header_data_content.original_or_copy =3D GetBit(byte6,0);
+
+ uint8_t byte7 =3D GetNext8Bits();
+ pes_header_data_content.PTS_flag =3D GetBit(byte7,7);
+ pes_header_data_content.DTS_flag =3D GetBit(byte7,6);
+ pes_header_data_content.ESCR_flag =3D GetBit(byte7,5);
+ pes_header_data_content.ES_rate_flag =3D GetBit(byte7,4);
+ pes_header_data_content.DSM_trick_mode_flag =3D GetBit(byte7,3);
+ pes_header_data_content.additionnal_copy_info_flag =3D GetBit(byte7,2);
+ pes_header_data_content.PES_CRC_flag =3D GetBit(byte7,1);
+ pes_header_data_content.PES_extension_flag =3D GetBit(byte7,0);
+=09
+ pes_header_data_content.PES_header_data_len =3D GetNext8Bits();
+}
+
+// ---------------------------------------------------------------------=
-------
+
+uint64_t VobParser::ParsePTS_DTS()
+{
+ // PTS and DTS have same format
+ uint64_t result =3D 0;
+
+ uint8_t byte0 =3D GetNext8Bits();
+ uint16_t word0 =3D GetNext16Bits();
+ uint16_t word1 =3D GetNext16Bits();
+
+ assert(word0 & 0x01);
+ assert(word1 & 0x01);
+
+ result |=3D (((byte0 & 0x0E) >> 1) << 30);
+ result |=3D ((word0 >> 1) << 15);
+ result |=3D (word1 >> 1);
+
+ return result;
+}
+
+// ---------------------------------------------------------------------=
-------
+
+void VobParser::ParsePESHeaderData()
+{
+ uint8_t bytesLeft =3D pes_header_data_content.PES_header_data_len;
+ if(pes_header_data_content.PTS_flag)
+ {
+ // PTS : Presentation Time Stamp
+ pktinfo.pts =3D ParsePTS_DTS();
+ bytesLeft -=3D 5;
+ if (m_bFirstPacket)
+ {
+ m_startpts =3D pktinfo.pts;
+ }
+ pktinfo.pts -=3D m_startpts;
+ }
+ if(pes_header_data_content.DTS_flag)
+ {
+ // DTS : Decoding Time Stamp
+ pktinfo.dts =3D ParsePTS_DTS();
+ bytesLeft -=3D 5;
+ if (m_bFirstPacket)
+ {
+ m_startdts =3D pktinfo.dts;
+ }
+ pktinfo.dts -=3D m_startdts;
+ }
+ m_bFirstPacket =3D false;
+
+ // Skip the rest
+ SkipNBytes(bytesLeft);
+}
+
+// ---------------------------------------------------------------------=
-------
+
+void VobParser::ParseVideoPacket()
+{
+ uint16_t length =3D GetNext16Bits();
+ ParsePESHeaderDataContentFlag();
+ ParsePESHeaderData();
+
+ m_demuxer.ProcessStream(VIDEO_STREAM, &m_buff[m_index],
+ length - 3 - pes_header_data_content.PES_header_data_len, pktinfo.dts/=
90, pktinfo.pts/90,
+ QString("DTS %1 PTS %2 - %3 %4\n").arg(m_startdts/90).arg(m_startpts/9=
0).arg(pktinfo.dts/90).arg(pktinfo.pts/90));
+}
+
+void VobParser::ParseAudioPacket(int StreamID)
+{
+ uint16_t length =3D GetNext16Bits();
+ ParsePESHeaderDataContentFlag();
+ ParsePESHeaderData();
+
+ m_demuxer.ProcessStream(StreamID, &m_buff[m_index],
+ length - 3 - pes_header_data_content.PES_header_data_len, pktinfo.pts/=
90, pktinfo.dts/90,
+ QString("DTS %1 PTS %2 - %3 %4\n").arg(m_startdts/90).arg(m_startpts/9=
0).arg(pktinfo.dts/90).arg(pktinfo.pts/90));
+}
+
+// ---------------------------------------------------------------------=
-------
+
+void VobParser::ParsePrivateStream1()
+{
+ uint16_t length =3D GetNext16Bits();=09
+ uint16_t dataStartIndex =3D m_index;
+ // PES : Packetized Elementary Stream
+ ParsePESHeaderDataContentFlag();
+ ParsePESHeaderData();
+ uint8_t substreamID =3D GetNext8Bits();
+
+ uint32_t t3 =3D m_pci.vobu_s_ptm/90 - m_pci_vob_timecode_offset;
+ uint32_t t4 =3D m_pci.vobu_e_ptm/90 - m_pci_vob_timecode_offset;
+ if(substreamID >=3D SUBSTREAM_SUB_LOW && substreamID < SUBSTREAM_SUB_HI=
GH)
+ {
+ debug(QString("Subtitles streamID =3D 0x%1\n").arg(substreamID, 0, 16)=
);
+
+ // .sub files the VobSub way (includes the whole packet)
+ m_demuxer.ProcessStream(substreamID, m_buff, DVD_VIDEO_LB_LEN, t3, t4,=
=20
+ QString("DTS %1 PTS %2 - %3 %4\n").arg(m_startdts/90).arg(m_startp=
ts/90).arg(pktinfo.dts/90).arg(pktinfo.pts/90));
+ }
+ else if(substreamID >=3D SUBSTREAM_AC3_LOW && substreamID < SUBSTREAM_A=
C3_HIGH)
+ {
+ debug(QString("AC3 streamID =3D 0x%1\n").arg(substreamID, 0, 16));
+
+ // Skip frame header number
+ SkipNBytes(1);
+ // Skip first access unit pointer
+ SkipNBytes(2);
+
+ uint16_t ac3DataLen =3D length - (m_index - dataStartIndex);
+ m_demuxer.ProcessStream(substreamID, &m_buff[m_index], ac3DataLen, t3,=
t4,=20
+ QString("DTS %1 PTS %2 - %3 %4\n").arg(m_startdts/90).arg(m_startp=
ts/90).arg(pktinfo.dts/90).arg(pktinfo.pts/90));
+ }
+ else if(substreamID >=3D SUBSTREAM_DTS_LOW && substreamID < SUBSTREAM_D=
TS_HIGH)
+ {
+ debug(QString("DTS streamID =3D 0x%1\n").arg(substreamID, 0, 16));
+ =09
+ // Skip frame header number
+ SkipNBytes(1);
+ // Skip first access unit pointer
+ SkipNBytes(2);
+
+ uint16_t ac3DataLen =3D length - (m_index - dataStartIndex);
+ m_demuxer.ProcessStream(substreamID, &m_buff[m_index], ac3DataLen, t3,=
t4,=20
+ QString("DTS %1 PTS %2 - %3 %4\n").arg(m_startdts/90).arg(m_startp=
ts/90).arg(pktinfo.dts/90).arg(pktinfo.pts/90));
+ }
+ else if(substreamID >=3D SUBSTREAM_PCM_LOW && substreamID < SUBSTREAM_P=
CM_HIGH)
+ {
+ debug(QString("LPCM streamID =3D 0x%1\n").arg(substreamID, 0, 16));
+
+ // Skip unknown data
+ SkipNBytes(6);
+
+ uint16_t ac3DataLen =3D length - (m_index - dataStartIndex);
+ m_demuxer.ProcessStream(substreamID, &m_buff[m_index], ac3DataLen, t3,=
t4,=20
+ QString("DTS %1 PTS %2 - %3 %4\n").arg(m_startdts/90).arg(m_startpts/=
90).arg(pktinfo.dts/90).arg(pktinfo.pts/90));
+ }
+ else
+ {
+ debug("Unknown\n");
+ }
+}
+
+// ---------------------------------------------------------------------=
-------
+
+void VobParser::Reset()
+{
+ memset(&m_dsi, 0, sizeof(m_dsi));
+ memset(&pktinfo, 0, sizeof(pktinfo));
+ memset(&pes_header_data_content, 0, sizeof(pes_header_data_content));
+ previous_vobid =3D -1;
+ previous_cellid =3D -1;
+ m_index =3D 0;
+ m_pktindex =3D 0;
+ DVDFileSeek(m_stream,0);
+}
+
+// ---------------------------------------------------------------------=
-------
+
+bool VobParser::IsNewCell()
+{
+ bool result =3D (GetVobID() !=3D previous_vobid ||
+ GetCellID() !=3D previous_cellid);
+=09
+ previous_vobid =3D GetVobID();
+ previous_cellid =3D GetCellID();
+ if (result)
+ m_bFirstPacket =3D true;
+
+ return result;
+}
+
+// ---------------------------------------------------------------------=
-------
+
+inline uint8_t VobParser::GetVobID() const
+{
+ return m_dsi.vobu_vob_idn;
+}
+
+// ---------------------------------------------------------------------=
-------
+
+inline uint8_t VobParser::GetCellID() const
+{
+ return m_dsi.vobu_c_idn;
+}
+
+// ---------------------------------------------------------------------=
-------
+
+uint32_t VobParser::GetCellSCR() const
+{
+ return m_dsi.nv_pck_scr;
+}
+
+// ---------------------------------------------------------------------=
-------
+=20
+void SubDemuxWriter::WriteTimecodeInfo(uint32_t start_time, uint32_t end=
_time, uint64_t filepos, const QString& debug)
+{
+ int i;
+
+ if (!m_TimecodeFile)
+ {
+ QString m_filename =3D m_Filename;
+ m_filename +=3D ".idx";
+ m_TimecodeFile =3D fopen(qPrintable(m_filename),"w");
+ fwrite("# VobSub index file, v7 (do not modify this line!)\n#\n", 1, 5=
3, m_TimecodeFile);
+ fwrite("# Settings\n\n# Original frame size\nsize: ", 1, 40, m_Timecod=
eFile);
+ fprintf(m_TimecodeFile, "%dx%d\n\n", m_width, m_height);
+ fwrite("# Origin, relative to the upper-left corner, can be overloaded=
by aligment\n"
+ "org: 0, 0\n\n"
+ "# Image scaling (hor,ver), origin is at the upper-left corner =
or at the alignment coord (x, y)\n"
+ "scale: 100%, 100%\n\n"
+ "# Alpha blending\n"
+ "alpha: 100%\n\n"
+ "# Smoothing for very blocky images (use OLD for no filtering)\=
n"
+ "smooth: OFF\n\n"
+ "# In millisecs\n"
+ "fadein/out: 50, 50\n\n"
+ "# Force subtitle placement relative to (org.x, org.y)\n"
+ "align: OFF at LEFT TOP\n\n"
+ "# For correcting non-progressive desync. (in millisecs or hh:m=
m:ss:ms)\n"
+ "# Note: Not effective in DirectVobSub, use \"delay: ... \" ins=
tead.\n"
+ "time offset: 0\n\n"
+ "# ON: displays only forced subtitles, OFF: shows everything\n"
+ "forced subs: OFF\n\n"
+ "# The original palette of the DVD\n"
+ "palette: ", 1, 692, m_TimecodeFile);
+ for (i=3D0; i<15; i++)
+ {
+ fprintf(m_TimecodeFile, "%06x, ", m_palette[i]);
+ }
+ fprintf(m_TimecodeFile, "%06x\n\n", m_palette[i]);
+ fwrite("# Custom colors (transp idxs and the four colors)\n"
+ "custom colors: OFF, tridx: 0000, colors: 000000, 000000, 00000=
0, 000000\n\n"
+ "# Language index in use\n"
+ "langidx: 0\n\n"
+ "id: ", 1, 163, m_TimecodeFile);
+ if (m_language)
+ fprintf(m_TimecodeFile, "%c%c", m_language >> 8, m_language);
+ else
+ fwrite("un", 1, 2, m_TimecodeFile);
+ fwrite(", index: 0\n"
+ "# Decomment next line to activate alternative name in DirectVo=
bSub / Windows Media Player 6.x\n"
+ "# alt: ", 1, 112, m_TimecodeFile);
+ fprintf(m_TimecodeFile, "%s\n\n", DecodeLanguage(m_language));
+ }
+ int32_t delay =3D start_time + m_start_timecode;
+ int millisecond =3D delay % 1000;
+ delay /=3D 1000;
+ int second =3D delay % 60;
+ delay /=3D 60;
+ int minute =3D delay % 60;
+ delay /=3D 60;
+ fprintf(m_TimecodeFile, "timestamp: %02d:%02d:%02d:%03d, filepos: %09x\=
n", delay,minute,second,millisecond,filepos);
+}
+
+void BtnDemuxWriter::WriteTimecodeInfo(uint32_t start_time, uint32_t end=
_time, uint64_t filepos, const QString& debug)
+{
+//static uint32_t time =3D0;
+ m_TimecodeFile =3D GetTimecodeFile();
+ if (start_time > m_last_end_timecode)
+ {
+ if (m_last_end_timecode > m_start_timecode)
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_start_timec=
ode) / 1000.0);
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_last_start_t=
imecode) / 1000.0);
+ fprintf(m_TimecodeFile, "gap,%lf\n", (start_time - m_last_end_timecode=
) / 1000.0);
+ m_start_timecode =3D start_time;
+ }
+//fwrite(debug.c_str(), debug.size(), 1, m_TimecodeFile);
+//fprintf(m_TimecodeFile, "# %d =3D> %d\n",time, time + end_time - start=
_time);
+//time +=3D end_time - start_time;
+ m_last_start_timecode =3D start_time;
+ m_last_end_timecode =3D end_time;
+}
+
+void DTSDemuxWriter::WriteTimecodeInfo(uint32_t start_time, uint32_t end=
_time, uint64_t filepos, const QString& debug)
+{
+ m_TimecodeFile =3D GetTimecodeFile();
+ if (start_time > m_last_end_timecode)
+ {
+ if (m_last_end_timecode > m_start_timecode)
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_start_timec=
ode) / 1000.0);
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_last_start_t=
imecode) / 1000.0);
+ fprintf(m_TimecodeFile, "gap,%lf\n", (start_time - m_last_end_timecode=
) / 1000.0);
+ m_start_timecode =3D start_time;
+ }
+ m_last_start_timecode =3D start_time;
+ m_last_end_timecode =3D end_time;
+}
+
+void LPCMDemuxWriter::WriteTimecodeInfo(uint32_t start_time, uint32_t en=
d_time, uint64_t filepos, const QString& debug)
+{
+ m_TimecodeFile =3D GetTimecodeFile();
+ if (start_time > m_last_end_timecode)
+ {
+ if (m_last_end_timecode > m_start_timecode)
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_start_timec=
ode) / 1000.0);
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_start_timeco=
de) / 1000.0);
+ fprintf(m_TimecodeFile, "gap,%lf\n", (start_time - m_last_end_timecode=
) / 1000.0);
+ m_start_timecode =3D start_time;
+ }
+ m_last_start_timecode =3D start_time;
+ m_last_end_timecode =3D end_time;
+}
+
+void MPADemuxWriter::WriteTimecodeInfo(uint32_t start_time, uint32_t end=
_time, uint64_t filepos, const QString& debug)
+{
+ m_TimecodeFile =3D GetTimecodeFile();
+}
+
+void AC3DemuxWriter::WriteTimecodeInfo(uint32_t start_time, uint32_t end=
_time, uint64_t filepos, const QString& debug)
+{
+ m_TimecodeFile =3D GetTimecodeFile();
+ if (start_time > m_last_end_timecode)
+ {
+ if (m_last_end_timecode > m_start_timecode)
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_start_timec=
ode) / 1000.0);
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_last_start_t=
imecode) / 1000.0);
+ fprintf(m_TimecodeFile, "gap,%lf\n", (start_time - m_last_end_timecode=
) / 1000.0);
+ m_start_timecode =3D start_time;
+ }
+ m_last_start_timecode =3D start_time;
+ m_last_end_timecode =3D end_time;
+}
+
+void VideoDemuxWriter::WriteTimecodeInfo(uint32_t start_time, uint32_t e=
nd_time, uint64_t filepos, const QString& debug)
+{
+ // TODO detect gaps in the stream
+}
+
+// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
+
+void VideoDemuxWriter::ProcessStream(uint8_t* buff, uint32_t size, uint3=
2_t start_time, uint32_t end_time, const QString& debug)
+{
+ if (m_parser =3D=3D NULL)
+ m_parser =3D new M2VParser;
+=09
+ m_parser->WriteData(buff, size);
+
+ MPEG2ParserState state =3D m_parser->GetState();
+
+ while (state =3D=3D MPV_PARSER_STATE_FRAME)=20
+ {
+ delete m_parser->ReadFrame();
+ state =3D m_parser->GetState();
+ }
+
+ Write(buff, size, start_time, end_time, debug);=20
+}
+
+void VideoDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t dur=
ation, const CellListElem *cell)
+{
+ if (m_parser !=3D NULL)
+ {
+ m_parser->SetEOS();
+
+ MPEG2ParserState state =3D m_parser->GetState();
+
+ while (state =3D=3D MPV_PARSER_STATE_FRAME)=20
+ {
+ MPEGFrame* current_frame =3D m_parser->ReadFrame();
+ if ((current_frame->timecode + current_frame->duration) / 1000000 > m=
_last_end_timecode)
+ {
+ m_last_start_timecode =3D current_frame->timecode / 1000000;
+ m_last_end_timecode =3D (current_frame->timecode + current_frame->du=
ration) / 1000000;
+ }
+ delete current_frame;
+
+ state =3D m_parser->GetState();
+ }
+ =09
+ delete m_parser;
+ }
+=09
+ m_parser =3D new M2VParser();
+
+ m_TimecodeFile =3D GetTimecodeFile();
+
+ if (m_end_timecode !=3D 0)
+ {
+ if (m_is_still) {
+ fwrite(" (Still)\n", 1, 9, m_TimecodeFile);
+ fprintf(m_TimecodeFile, "%lf,%lf\n", (m_end_timecode - m_start_timeco=
de) / 1000.0, 1000.0 / (m_end_timecode - m_start_timecode));
+ }
+ else if (m_last_end_timecode < m_end_timecode)
+ {
+ fprintf(m_TimecodeFile, "\n%lf\n", (m_last_end_timecode - m_start_tim=
ecode) / 1000.0);
+ fprintf(m_TimecodeFile, "gap,%lf\n", (m_end_timecode - m_last_end_tim=
ecode) / 1000.0);
+ }
+ else
+ {
+ if (m_last_end_timecode > m_end_timecode)
+ qWarning("There is more video that indicated in the cell.");
+ fprintf(m_TimecodeFile, "\n%lf\n", (m_last_end_timecode - m_start_tim=
ecode) / 1000.0);
+ }
+ }
+
+ m_start_timecode =3D start_timecode;
+ m_end_timecode =3D start_timecode + duration;
+ m_last_end_timecode =3D start_timecode;
+ m_is_still =3D cell->isStill;
+
+ fprintf(m_TimecodeFile, "\n# VOB %d Cell %d", cell->vobid, cell->cellid=
);
+}
+
+void AC3DemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t durat=
ion, const CellListElem *cell)
+{
+ m_TimecodeFile =3D GetTimecodeFile();
+
+ // handle ending of the previous cell
+ if (m_last_end_timecode < m_end_timecode)
+ {
+ if (m_last_end_timecode > m_start_timecode)
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_start_timec=
ode) / 1000.0);
+ fprintf(m_TimecodeFile, "gap,%lf\n", (m_end_timecode - m_last_end_time=
code) / 1000.0);
+ }
+ else
+ {
+ if (m_end_timecode !=3D 0)
+ {
+ if (m_last_end_timecode > m_end_timecode)
+ qWarning("There is more AC3 audio that indicated in the cell.");
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_start_timec=
ode) / 1000.0);
+ }
+ }
+
+ m_start_timecode =3D start_timecode;
+ m_end_timecode =3D start_timecode + duration;
+ m_last_end_timecode =3D start_timecode;
+ m_last_start_timecode =3D start_timecode;
+
+ fprintf(m_TimecodeFile, "\n# VOB %d Cell %d\n", cell->vobid, cell->cell=
id);
+}
+
+void DTSDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t durat=
ion, const CellListElem *cell)
+{
+ m_TimecodeFile =3D GetTimecodeFile();
+
+ // handle ending of the previous cell
+ if (m_last_end_timecode < m_end_timecode)
+ {
+ if (m_last_end_timecode > m_start_timecode)
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_start_timec=
ode) / 1000.0);
+ fprintf(m_TimecodeFile, "gap,%lf\n", (m_end_timecode - m_last_end_time=
code) / 1000.0);
+ }
+ else
+ {
+ if (m_end_timecode !=3D 0)
+ {
+ if (m_last_end_timecode > m_end_timecode)
+ qWarning("There is more DTS audio that indicated in the cell.");
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_start_timec=
ode) / 1000.0);
+ }
+ }
+
+ m_start_timecode =3D start_timecode;
+ m_end_timecode =3D start_timecode + duration;
+ m_last_end_timecode =3D start_timecode;
+ m_last_start_timecode =3D start_timecode;
+
+ fprintf(m_TimecodeFile, "\n# VOB %d Cell %d\n", cell->vobid, cell->cell=
id);
+}
+
+void LPCMDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t dura=
tion, const CellListElem *cell)
+{
+ m_TimecodeFile =3D GetTimecodeFile();
+
+ // handle ending of the previous cell
+ if (m_last_end_timecode < m_end_timecode)
+ {
+ if (m_last_end_timecode > m_start_timecode)
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_start_timec=
ode) / 1000.0);
+ fprintf(m_TimecodeFile, "gap,%lf\n", (m_end_timecode - m_last_end_time=
code) / 1000.0);
+ }
+ else
+ {
+ if (m_end_timecode !=3D 0)
+ {
+ if (m_last_end_timecode > m_end_timecode)
+ qWarning("There is more PCM audio that indicated in the cell.");
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_start_timec=
ode) / 1000.0);
+ }
+ }
+
+ m_start_timecode =3D start_timecode;
+ m_end_timecode =3D start_timecode + duration;
+ m_last_end_timecode =3D start_timecode;
+ m_last_start_timecode =3D start_timecode;
+
+ fprintf(m_TimecodeFile, "\n# VOB %d Cell %d\n", cell->vobid, cell->cell=
id);
+}
+
+void MPADemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t durat=
ion, const CellListElem *cell)
+{
+}
+
+void SubDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t durat=
ion, const CellListElem *cell)
+{
+ if (start_timecode =3D=3D 0)
+ m_start_timecode =3D m_end_timecode;
+ m_end_timecode +=3D duration;
+}
+
+void BtnDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t durat=
ion, const CellListElem *cell)
+{
+ m_TimecodeFile =3D GetTimecodeFile();
+
+ // handle ending of the previous cell
+ if (m_last_end_timecode < m_end_timecode)
+ {
+ if (m_last_end_timecode > m_start_timecode)
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_start_timec=
ode) / 1000.0);
+ fprintf(m_TimecodeFile, "gap,%lf\n", (m_end_timecode - m_last_end_time=
code) / 1000.0);
+ }
+ else
+ {
+ if (m_end_timecode !=3D 0)
+ {
+ if (m_last_end_timecode > m_end_timecode)
+ qWarning("There is more Button data that indicated in the cell.");
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_start_timec=
ode) / 1000.0);
+ }
+ }
+
+ m_start_timecode =3D start_timecode;
+ m_end_timecode =3D start_timecode + duration;
+ m_last_end_timecode =3D start_timecode;
+ m_last_start_timecode =3D start_timecode;
+
+ fprintf(m_TimecodeFile, "\n# VOB %d Cell %d\n", cell->vobid, cell->cell=
id);
+}
+
+VideoDemuxWriter::~VideoDemuxWriter()
+{
+ m_TimecodeFile =3D GetTimecodeFile();
+ if (m_parser !=3D NULL)
+ {
+ m_parser->SetEOS();
+
+ MPEG2ParserState state =3D m_parser->GetState();
+
+ while (state =3D=3D MPV_PARSER_STATE_FRAME)=20
+ {
+ MPEGFrame* current_frame =3D m_parser->ReadFrame();
+ if ((current_frame->timecode + current_frame->duration) / 1000000 > m=
_last_end_timecode)
+ {
+ m_last_start_timecode =3D current_frame->timecode / 1000000;
+ m_last_end_timecode =3D (current_frame->timecode + current_frame->du=
ration) / 1000000;
+ }
+ delete current_frame;
+
+ state =3D m_parser->GetState();
+ }
+ delete m_parser;
+ }
+
+
+ if (m_end_timecode !=3D 0)
+ {
+ if (m_is_still) {
+ fwrite(" (Still)\n", 1, 9, m_TimecodeFile);
+ fprintf(m_TimecodeFile, "%lf,%lf\n", (m_end_timecode - m_start_timeco=
de) / 1000.0, 1000.0 / (m_end_timecode - m_start_timecode));
+ }
+ else if (m_last_end_timecode < m_end_timecode)
+ {
+ fprintf(m_TimecodeFile, "\n%lf\n", (m_last_end_timecode - m_start_tim=
ecode) / 1000.0);
+ fprintf(m_TimecodeFile, "gap,%lf\n", (m_end_timecode - m_last_end_tim=
ecode) / 1000.0);
+ }
+ else
+ fprintf(m_TimecodeFile, "\n%lf\n", (m_end_timecode - m_start_timecode=
) / 1000.0);
+ }
+}
+
+AC3DemuxWriter::~AC3DemuxWriter()
+{
+ m_TimecodeFile =3D GetTimecodeFile();
+
+ // handle ending of the previous cell
+ if (m_last_end_timecode < m_end_timecode)
+ {
+ if (m_last_end_timecode > m_start_timecode)
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_start_timec=
ode) / 1000.0);
+ fprintf(m_TimecodeFile, "gap,%lf\n", (m_end_timecode - m_last_end_time=
code) / 1000.0);
+ }
+ else
+ {
+ if (m_end_timecode !=3D 0)
+ fprintf(m_TimecodeFile, "%lf\n", (m_end_timecode - m_start_timecode) =
/ 1000.0);
+ }
+}
+
+DTSDemuxWriter::~DTSDemuxWriter()
+{
+ m_TimecodeFile =3D GetTimecodeFile();
+
+ // handle ending of the previous cell
+ if (m_last_end_timecode < m_end_timecode)
+ {
+ if (m_last_end_timecode > m_start_timecode)
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_start_timec=
ode) / 1000.0);
+ fprintf(m_TimecodeFile, "gap,%lf\n", (m_end_timecode - m_last_end_time=
code) / 1000.0);
+ }
+ else
+ {
+ if (m_end_timecode !=3D 0)
+ fprintf(m_TimecodeFile, "%lf\n", (m_end_timecode - m_start_timecode) =
/ 1000.0);
+ }
+}
+
+LPCMDemuxWriter::~LPCMDemuxWriter()
+{
+ m_TimecodeFile =3D GetTimecodeFile();
+
+ // handle ending of the previous cell
+ if (m_last_end_timecode < m_end_timecode)
+ {
+ if (m_last_end_timecode > m_start_timecode)
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_start_timec=
ode) / 1000.0);
+ fprintf(m_TimecodeFile, "gap,%lf\n", (m_end_timecode - m_last_end_time=
code) / 1000.0);
+ }
+ else
+ {
+ if (m_end_timecode !=3D 0)
+ fprintf(m_TimecodeFile, "%lf\n", (m_end_timecode - m_start_timecode) =
/ 1000.0);
+ }
+}
+
+BtnDemuxWriter::~BtnDemuxWriter()
+{
+ m_TimecodeFile =3D GetTimecodeFile();
+
+ // handle ending of the previous cell
+ if (m_last_end_timecode < m_end_timecode)
+ {
+ if (m_last_end_timecode > m_start_timecode)
+ fprintf(m_TimecodeFile, "%lf\n", (m_last_end_timecode - m_start_timec=
ode) / 1000.0);
+ fprintf(m_TimecodeFile, "gap,%lf\n", (m_end_timecode - m_last_end_time=
code) / 1000.0);
+ }
+ else
+ {
+ if (m_end_timecode !=3D 0)
+ fprintf(m_TimecodeFile, "%lf\n", (m_end_timecode - m_start_timecode) =
/ 1000.0);
+ }
+}
+
+WavWriter::~WavWriter()
+{
+ if (m_file)
+ {
+ uint8_t _tinteger[4];
+
+ fseek(m_file, m_size_position2, SEEK_SET);
+ _tinteger[0] =3D m_size & 0xFF;
+ _tinteger[1] =3D (m_size >> 8) & 0xFF;
+ _tinteger[2] =3D (m_size >> 16) & 0xFF;
+ _tinteger[3] =3D (m_size >> 24) & 0xFF;
+ fwrite(_tinteger,4,1, m_file);
+ =09
+ m_size +=3D 36;
+ fseek(m_file, m_size_position1, SEEK_SET);
+ _tinteger[0] =3D m_size & 0xFF;
+ _tinteger[1] =3D (m_size >> 8) & 0xFF;
+ _tinteger[2] =3D (m_size >> 16) & 0xFF;
+ _tinteger[3] =3D (m_size >> 24) & 0xFF;
+ fwrite(_tinteger,4,1, m_file);
+ }
+}
+
+void WavWriter::Write(uint8_t* buff, uint32_t size, uint32_t start_time,=
uint32_t end_time, const QString& debug)
+{
+ if (m_bit_depth !=3D 16) // not supported
+ return;
+ if (m_file =3D=3D NULL)
+ {
+ uint8_t _tinteger[4];
+ m_file =3D OpenOuputFile();
+
+ // create the WAV header
+ // RIFF head
+ fwrite("RIFF",4,1, m_file);
+ m_size_position1 =3D ftell(m_file);
+ fwrite("0000",4,1, m_file);
+ fwrite("WAVE",4,1, m_file);
+ =09
+ // Format head
+ fwrite("fmt ",4,1, m_file);
+ _tinteger[0] =3D 16;
+ _tinteger[1] =3D 0;
+ _tinteger[2] =3D 0;
+ _tinteger[3] =3D 0;
+ fwrite(_tinteger,4,1, m_file);
+ =09
+ _tinteger[0] =3D 1;
+ fwrite(_tinteger,2,1, m_file); // PCM
+ =09
+ _tinteger[0] =3D m_channel_nb;
+ _tinteger[1] =3D 0;
+ fwrite(_tinteger,2,1, m_file); // Channels
+ =09
+ _tinteger[0] =3D m_sample_rate & 0xFF;
+ _tinteger[1] =3D (m_sample_rate >> 8) & 0xFF;
+ _tinteger[2] =3D (m_sample_rate >> 16) & 0xFF;
+ _tinteger[3] =3D (m_sample_rate >> 24) & 0xFF;
+ fwrite(_tinteger,4,1, m_file); // Sampling freq
+ =09
+ uint32_t _byte_rate =3D (m_sample_rate * m_channel_nb * m_bit_depth) >=
> 3;
+ _tinteger[0] =3D _byte_rate & 0xFF;
+ _tinteger[1] =3D (_byte_rate >> 8) & 0xFF;
+ _tinteger[2] =3D (_byte_rate >> 16) & 0xFF;
+ _tinteger[3] =3D (_byte_rate >> 24) & 0xFF;
+ fwrite(_tinteger,4,1, m_file); // Byte Rate
+ =09
+ uint16_t _block_align =3D (m_channel_nb * m_bit_depth) >> 3;
+ _tinteger[0] =3D _block_align & 0xFF;
+ _tinteger[1] =3D (_block_align >> 8) & 0xFF;
+ fwrite(_tinteger,2,1, m_file); // Block Align
+ =09
+ _tinteger[0] =3D m_bit_depth;
+ _tinteger[1] =3D 0;
+ fwrite(_tinteger,2,1, m_file); // Block Align
+ =09
+ // Data head
+ fwrite("data",4,1, m_file);
+ m_size_position2 =3D ftell(m_file);
+ fwrite("0000",4,1, m_file);
+ m_size =3D 0;
+ }
+ uint16_t _tmp;
+ for (size_t i=3D0; i < size; i+=3D2) {
+ _tmp =3D buff[i];
+ _tmp <<=3D 8;
+ _tmp +=3D buff[i+1];
+ buff[i] =3D _tmp & 0xFF;
+ buff[i+1] =3D _tmp >> 8;
+ }
+ Writer::Write(buff, size, start_time, end_time, debug);
+ m_size +=3D size;
+}
Added: trunk/DvdMenuXtractor/vobparser/VobParser.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/vobparser/VobParser.h 2007-01-22 11:21:16 UTC (=
rev 1269)
+++ trunk/DvdMenuXtractor/vobparser/VobParser.h 2007-01-28 16:48:11 UTC (=
rev 1270)
@@ -0,0 +1,621 @@
+// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
+// VOBParser class
+// Copyright =A9 2002 : Christophe PARIS (christophe.paris at free.fr)
+// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
+#ifndef _VOB_PARSER_H_
+#define _VOB_PARSER_H_
+// ---------------------------------------------------------------------=
-------
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdint.h>
+
+#define HAVE_INTTYPES_H
+#include "dvdread/ifo_read.h"
+#include "mpegparser/M2VParser.h"
+
+#include <QList>
+#include <QString>
+// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
+
+#define VIDEO_STREAM_TYPE 0x01
+#define AUDIO_STREAM_TYPE 0x02
+#define SUB_STREAM_TYPE 0x04
+
+#define AC3_STREAM_TYPE (AUDIO_STREAM_TYPE | 0x08)
+#define DTS_STREAM_TYPE (AUDIO_STREAM_TYPE | 0x10)
+#define PCM_STREAM_TYPE (AUDIO_STREAM_TYPE | 0x20)
+
+
+#define AUDIO_STREAM 0xC0
+#define VIDEO_STREAM 0xE0
+
+#define SUBSTREAM_PCI 0x00
+#define SUBSTREAM_DSI 0x01
+
+#define SUBSTREAM_SUB_LOW 0x20
+#define SUBSTREAM_SUB_HIGH (SUBSTREAM_SUB_LOW + 32)
+
+#define SUBSTREAM_AC3_LOW 0x80
+#define SUBSTREAM_AC3_HIGH (SUBSTREAM_AC3_LOW + 8)
+
+#define SUBSTREAM_DTS_LOW 0x88
+#define SUBSTREAM_DTS_HIGH (SUBSTREAM_DTS_LOW + 8)
+
+#define SUBSTREAM_PCM_LOW 0xA0
+#define SUBSTREAM_PCM_HIGH (SUBSTREAM_PCM_LOW + 8)
+
+// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
+// Type
+// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
+
+typedef struct=20
+{
+ unsigned int vobid;
+ unsigned int cellid;
+ unsigned int start_frame;
+ unsigned int end_frame;
+ unsigned int nb_frames;
+ uint32_t start_sector;
+ uint32_t last_sector;
+ double frame_dur;
+ uint64_t start_time;
+ uint64_t duration;
+ bool isStill;
+ bool selected;
+ bool found;
+ //ButtonsListType btt_list;
+} CellListElem;
+
+typedef struct {
+ uint16_t start_x; // Starting X position
+ uint16_t start_y; // Starting Y position
+ uint16_t end_x; // Ending X position
+ uint16_t end_y; // Ending Y position
+ uint8_t btn_coln; // Button color table number, 0=3Dnone
+ uint8_t auto_action_flag; // Auto Action flag 0=3Dno, 1=3Dyes
+ uint8_t up; // Button number to select if "Up" is pressed
+ uint8_t down; // Button number to select if "Down" is pressed
+ uint8_t left; // Button number to select if "Left" is pressed
+ uint8_t right; // Button number to select if "Right" is pressed
+ uint8_t vm_cmd[8]; // One vm command to be executed on "action" of t=
his button
+} btni;
+
+typedef struct {
+ uint32_t nv_pck_lbn : 32; // Logical Block Number (sector) of this blo=
ck
+ uint16_t vobu_cat : 16; // Flags, including APS (Analog Protection Sys=
tem)
+ uint16_t reserved1 : 16; // Reserved
+ uint32_t vobu_uop_ctl : 32; // bitmask for prohibited user operations
+ uint32_t vobu_s_ptm : 32; // Vobu Start Presentation Time (90KHz clk)
+ uint32_t vobu_e_ptm : 32; // Vobu End Presentation Time (PTM)
+ uint32_t vobu_se_e_ptm : 32; // End PTM of VOBU if Sequence_End_Code
+ uint32_t c_eltm : 32; // Cell elapsed time (BCD)
+ uint8_t vobu_isrc[32]; // International Standard Recording Code (roy=
alty management)
+ uint32_t nsml_agli_dsta[9]; // Non-seamless angle 1 relative offset to=
VOBU for CURRENT ILVU=20
+ uint16_t hli_ss; // Highlight status (lower 2 bits only)
+ uint32_t hli_s_ptm; // Highlight start time
+ uint32_t hli_e_ptm; // Highlight end time
+ uint32_t btn_sl_e_ptm; // Button selection end time (ignore user afte=
r this)
+ uint16_t btn_md; // 4 nibbles which describe the grouping of the but=
tons
+ uint8_t btn_sn; // Starting button number
+ uint8_t btn_ns; // Number of buttons
+ uint8_t nsl_btn_ns; // Number of numerically selected buttons
+ uint8_t reserved2; // Reserved
+ uint8_t fosl_btnn; // Force select button number
+ uint8_t foac_btnn; // Force action button number
+ uint32_t btn_coli[3][2]; // Selection and action color and contrast va=
lues
+ btni btnit[36];
+} nav_pci_gi;
+
+typedef struct {
+ uint32_t nv_pck_scr : 32; // System clock reference
+ uint32_t nv_pck_lbn : 32; // Logical Block Number (sector) of this blo=
ck
+ uint32_t vobu_ea : 32; // VOBU end address - relative offset to last s=
ector of VOBU
+ uint32_t vobu_1stref_ea : 32; // First reference frame end block, relat=
ive - used for fast playing
+ uint32_t vobu_2ndref_ea : 32; // Second reference frame end block, rela=
tive - used for fast playing
+ uint32_t vobu_3rdref_ea : 32; // Third reference frame end block, relat=
ive - used for fast playing
+ uint16_t vobu_vob_idn : 16; // VOB number
+ uint8_t reserved : 8; // Reserved
+ uint8_t vobu_c_idn : 8; // CELL number within VOB
+ uint32_t c_eltm : 32; // Cell elapsed time (BCD)
+} nav_dsi_gi;
+
+typedef struct {
+ uint8_t PES_scrambling_control : 2;
+ uint8_t PES_priority : 1;
+ uint8_t data_alignment_indicator : 1;
+ uint8_t copyright : 1;
+ uint8_t original_or_copy : 1;
+ uint8_t PTS_flag : 1;
+ uint8_t DTS_flag : 1;
+ uint8_t ESCR_flag : 1;
+ uint8_t ES_rate_flag : 1;
+ uint8_t DSM_trick_mode_flag : 1;
+ uint8_t additionnal_copy_info_flag : 1;
+ uint8_t PES_CRC_flag : 1;
+ uint8_t PES_extension_flag : 1;
+ uint8_t PES_header_data_len;
+} PES_header_data_content;
+
+typedef struct {
+ uint32_t identifier;
+ uint64_t scr;
+ uint16_t scr_ext;
+ uint32_t program_mux_rate;
+ int64_t pts;
+ int64_t dts;
+} packet_info;
+
+// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
+// Exception
+// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
+
+class Exception
+{
+public:
+ Exception() {}
+ Exception(const char* message)
+ {
+ strcpy(m_message, message);
+ }
+
+ char m_message[512];
+};
+
+class VobParserException : public Exception
+{
+public:
+ VobParserException() : Exception() {}
+ VobParserException(const char* message) : Exception(message) {}
+};
+
+class VobParserFileNotFoundException : public VobParserException
+{
+public:
+ VobParserFileNotFoundException(const char* filename)
+ {
+ sprintf(m_message,"File not found exception : %s", filename);
+ }
+};
+
+class VobParserInvalidPacketException : public VobParserException
+{
+public:
+ VobParserInvalidPacketException(int offset)
+ {
+ sprintf(m_message,"Invalid packet exception @LBA %d", offset);
+ }
+};
+
+// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
+// Demuxer class
+// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
+
+class Demuxer
+{
+public:
+ virtual ~Demuxer() {}
+ virtual void ProcessStream(uint8_t* buff, uint32_t size, uint32_t start=
_time, uint32_t end_time, const QString & debug) =3D 0;
+ virtual void SetBoundary(uint32_t start_timecode, uint32_t duration, co=
nst CellListElem *cell) =3D 0;
+};
+
+// ---------------------------------------------------------------------=
-------
+
+class Writer : public Demuxer
+{
+public:
+ Writer(const char* filenamePrefix, const char* extension, double fps)
+ :m_file(NULL)
+ ,m_TimecodeFile(NULL)
+ ,m_fps(fps)
+ {
+ m_Filename =3D filenamePrefix;
+ m_fileExtension =3D extension;
+ }
+
+ virtual ~Writer()
+ {
+ if(m_file)
+ {
+ fclose(m_file);
+ }
+ if (m_TimecodeFile)
+ fclose(m_TimecodeFile);
+ }
+
+ virtual void Write(uint8_t* buff, uint32_t size, uint32_t start_time, u=
int32_t end_time, const QString& debug)
+ {
+ m_file =3D OpenOuputFile();
+ WriteTimecodeInfo(start_time, end_time, ftell(m_file), debug);
+ fwrite(buff, 1, size, m_file);
+ }
+
+ bool FileExists() const {
+ return m_file !=3D NULL;
+ }
+
+protected:
+ inline FILE* GetTimecodeFile()
+ {
+ if (!m_TimecodeFile)
+ {
+ QString m_filename =3D m_Filename;
+ m_filename +=3D "_";
+ m_filename +=3D m_fileExtension;
+ m_filename +=3D ".tmc";
+ m_TimecodeFile =3D fopen(m_filename.toAscii().data(),"w");
+ fwrite("# timecode format v3\n", 1, 21, m_TimecodeFile);
+ fprintf(m_TimecodeFile, "assume %lf\n", m_fps);
+ }
+ return m_TimecodeFile;
+ }
+
+ inline FILE* OpenOuputFile()
+ {
+ if(!m_file)
+ {
+ QString m_filename =3D m_Filename;
+ m_filename +=3D ".";
+ m_filename +=3D m_fileExtension;
+ m_file =3D fopen(m_filename.toAscii().data(),"wb");
+ }
+ return m_file;
+ }
+
+ QString m_Filename;
+ QString m_fileExtension;
+ FILE* m_file;
+ FILE* m_TimecodeFile;
+ double m_fps;
+
+ virtual void WriteTimecodeInfo(uint32_t start_time, uint32_t end_time, =
uint64_t filepos, const QString& debug) =3D 0;
+};
+
+// ---------------------------------------------------------------------=
-------
+
+class VideoDemuxWriter : public Writer
+{
+public:
+ VideoDemuxWriter(const char* filenamePrefix, double fps)
+ :Writer(filenamePrefix,"m2v", fps)=20
+ ,m_end_timecode(0)
+ ,m_last_start_timecode(0)
+ ,m_last_end_timecode(0)
+ ,m_is_still(false)
+ ,m_parser(NULL)
+ {}
+ void ProcessStream(uint8_t* buff, uint32_t size, uint32_t start_time, u=
int32_t end_time, const QString& debug);
+ void SetBoundary(uint32_t start_timecode, uint32_t duration, const Cell=
ListElem *cell);
+ ~VideoDemuxWriter();
+protected:
+ void WriteTimecodeInfo(uint32_t start_time, uint32_t end_time, uint64_t=
filepos, const QString& debug);
+ uint32_t m_start_timecode;
+ uint32_t m_end_timecode;
+ uint32_t m_last_start_timecode;
+ uint32_t m_last_end_timecode;
+ bool m_is_still;
+
+ M2VParser * m_parser;
+};
+
+// ---------------------------------------------------------------------=
-------
+
+class AC3DemuxWriter : public Writer
+{
+public:
+ AC3DemuxWriter(const char* filenamePrefix, const uint8_t streamID)
+ :Writer(filenamePrefix, "ac3", 0.0)
+ ,m_streamID(streamID)
+ ,m_end_timecode(0)
+ ,m_last_start_timecode(0)
+ ,m_last_end_timecode(0)
+ {}
+ ~AC3DemuxWriter();
+ void ProcessStream(uint8_t* buff, uint32_t size, uint32_t start_time, u=
int32_t end_time, const QString& debug)
+ {
+ Write(buff,size, start_time, end_time, debug);
+ }
+ void SetBoundary(uint32_t start_timecode, uint32_t duration, const Cell=
ListElem *cell);
+private:
+ uint8_t m_streamID;
+protected:
+ void WriteTimecodeInfo(uint32_t start_time, uint32_t end_time, uint64_t=
filepos, const QString& debug);
+ uint32_t m_start_timecode;
+ uint32_t m_end_timecode;
+ uint32_t m_last_start_timecode;
+ uint32_t m_last_end_timecode;
+};
+
+// ---------------------------------------------------------------------=
-------
+
+class DTSDemuxWriter : public Writer
+{
+public:
+ DTSDemuxWriter(const char* filenamePrefix, const uint8_t streamID)
+ :Writer(filenamePrefix,"dts",0.0)
+ ,m_streamID(streamID)
+ ,m_end_timecode(0)
+ ,m_last_start_timecode(0)
+ ,m_last_end_timecode(0)
+ {}
+ ~DTSDemuxWriter();
+ void ProcessStream(uint8_t* buff, uint32_t size, uint32_t start_time, u=
int32_t end_time, const QString& debug)
+ {
+ Write(buff,size, start_time, end_time, debug);
+ }
+ void SetBoundary(uint32_t start_timecode, uint32_t duration, const Cell=
ListElem *cell);
+private:
+ uint8_t m_streamID;
+protected:
+ void WriteTimecodeInfo(uint32_t start_time, uint32_t end_time, uint64_t=
filepos, const QString& debug);
+ uint32_t m_start_timecode;
+ uint32_t m_end_timecode;
+ uint32_t m_last_start_timecode;
+ uint32_t m_last_end_timecode;
+};
+
+// ---------------------------------------------------------------------=
-------
+
+class WavWriter : public Writer
+{
+ public:
+ WavWriter(const char* filenamePrefix, double fps, uint32_t sample_rate=
, uint8_t bit_depth, uint8_t channel_nb)
+ :Writer(filenamePrefix, "wav", fps)
+ ,m_sample_rate(sample_rate)
+ ,m_bit_depth(bit_depth)
+ ,m_channel_nb(channel_nb)
+ {}
+ ~WavWriter();
+ void Write(uint8_t* buff, uint32_t size, uint32_t start_time, uint32_t=
end_time, const QString& debug);
+ protected:
+ uint32_t m_sample_rate;
+ uint8_t m_bit_depth, m_channel_nb;
+ size_t m_size_position1,m_size_position2, m_size;
+};
+
+class LPCMDemuxWriter : public WavWriter
+{
+public:
+ LPCMDemuxWriter(const char* filenamePrefix, const uint8_t streamID, uin=
t32_t sample_rate, uint8_t bit_depth, uint8_t channel_nb)
+ :WavWriter(filenamePrefix,0.0, sample_rate, bit_depth, channel_nb)
+ ,m_streamID(streamID)
+ ,m_end_timecode(0)
+ ,m_last_start_timecode(0)
+ ,m_last_end_timecode(0)
+ {}
+ ~LPCMDemuxWriter();
+ void ProcessStream(uint8_t* buff, uint32_t size, uint32_t start_time, u=
int32_t end_time, const QString& debug)
+ {
+ Write(buff,size, start_time, end_time, debug);
+ }
+ void SetBoundary(uint32_t start_timecode, uint32_t duration, const Cell=
ListElem *cell);
+private:
+ uint8_t m_streamID;
+protected:
+ void WriteTimecodeInfo(uint32_t start_time, uint32_t end_time, uint64_t=
filepos, const QString& debug);
+ uint32_t m_start_timecode;
+ uint32_t m_end_timecode;
+ uint32_t m_last_start_timecode;
+ uint32_t m_last_end_timecode;
+};
+
+// ---------------------------------------------------------------------=
-------
+
+class MPADemuxWriter : public Writer
+{
+public:
+ MPADemuxWriter(const char* filenamePrefix, const uint8_t streamID) :
+ Writer(filenamePrefix,"mpa",0.0), m_streamID(streamID) {}
+ void ProcessStream(uint8_t* buff, uint32_t size, uint32_t start_time, u=
int32_t end_time, const QString& debug)
+ {
+ Write(buff,size, start_time, end_time, debug);
+ }
+ void SetBoundary(uint32_t start_timecode, uint32_t duration, const Cell=
ListElem *cell);
+private:
+ uint8_t m_streamID;
+protected:
+ void WriteTimecodeInfo(uint32_t start_time, uint32_t end_time, uint64_t=
filepos, const QString& debug);
+};
+
+// ---------------------------------------------------------------------=
-------
+
+class SubDemuxWriter : public Writer
+{
+public:
+ SubDemuxWriter(const char* filenamePrefix, const uint8_t streamID, uint=
16_t width, uint16_t height, const uint32_t * palette, uint16_t language,=
bool forced)
+ :Writer(filenamePrefix, "sub",0.0)
+ ,m_width(width)
+ ,m_height(height)
+ ,m_forced(forced)
+ ,m_palette(palette)
+ ,m_language(language)
+ ,m_start_timecode(0)
+ ,m_end_timecode(0)
+ {}
+ void ProcessStream(uint8_t* buff, uint32_t size, uint32_t start_time, u=
int32_t end_time, const QString& debug)
+ {
+ Write(buff,size, start_time, end_time, debug);
+ }
+ void SetBoundary(uint32_t start_timecode, uint32_t duration, const Cell=
ListElem *cell);
+protected:
+ void WriteTimecodeInfo(uint32_t start_time, uint32_t end_time, uint64_t=
filepos, const QString& debug);
+private:
+ uint16_t m_width;
+ uint16_t m_height;
+ bool m_forced;
+ const uint32_t * m_palette;
+ uint16_t m_language;
+ uint32_t m_start_timecode;
+ uint32_t m_end_timecode;
+};
+
+// ---------------------------------------------------------------------=
-------
+
+class BtnDemuxWriter : public Writer
+{
+public:
+ BtnDemuxWriter(const char* filenamePrefix, uint16_t width, uint16_t hei=
ght)
+ :Writer(filenamePrefix, "btn",0.0)
+ ,m_width(width)
+ ,m_height(height)
+ ,m_end_timecode(0)
+ ,m_last_start_timecode(0)
+ ,m_last_end_timecode(0)
+ {}
+ void ProcessStream(uint8_t* buff, uint32_t size, uint32_t start_time, u=
int32_t end_time, const QString& debug)
+ {
+ if (!m_file) {
+ m_file =3D OpenOuputFile();
+ fwrite("butonDVD", 8, 1, m_file);
+ uint8_t _tmp[4];
+ // width & height
+ _tmp[0] =3D m_width >> 8;
+ _tmp[1] =3D m_width & 0xFF;
+ _tmp[2] =3D m_height >> 8;
+ _tmp[3] =3D m_height & 0xFF;
+ fwrite(_tmp, 4, 1, m_file);
+ // pad to 16 bytes
+ _tmp[0] =3D 0;
+ _tmp[1] =3D 0;
+ _tmp[2] =3D 0;
+ _tmp[3] =3D 0;
+ fwrite(_tmp, 4, 1, m_file);
+ }
+ Write(buff,size, start_time, end_time, debug);
+ }
+ void SetBoundary(uint32_t start_timecode, uint32_t duration, const Cell=
ListElem *cell);
+ ~BtnDemuxWriter();
+protected:
+ void WriteTimecodeInfo(uint32_t start_time, uint32_t end_time, uint64_t=
filepos, const QString& debug);
+ uint16_t m_width, m_height;
+ uint32_t m_start_timecode;
+ uint32_t m_end_timecode;
+ uint32_t m_last_start_timecode;
+ uint32_t m_last_end_timecode;
+};
+
+// ---------------------------------------------------------------------=
-------
+
+class CompositeDemuxWriter
+{
+public:
+ CompositeDemuxWriter();
+ ~CompositeDemuxWriter();
+ bool AddDemuxer(uint8_t streamID, Writer * demuxer, QString& CommandLin=
e);
+ void ProcessStream(int streamID, uint8_t* buff, uint32_t size, int32_t =
start_time, int32_t end_time, const QString& debug);
+ void Reset();
+ void SetBoundary(uint32_t start_timecode, uint32_t duration, const Cell=
ListElem *cell);
+
+ bool FileExists(uint8_t streamID) const {
+ return (m_muxers[streamID] !=3D NULL && m_muxers[streamID]->FileExists=
());
+ }
+
+ const QString& GetString(uint8_t streamID) const {
+ return m_strings[streamID];
+ }
+
+protected:
+ Writer * m_muxers[256];
+ QString m_strings[256];
+};
+
+// ---------------------------------------------------------------------=
-------
+
+struct stream_info_node
+{
+ uint8_t id;
+ uint32_t type;
+ stream_info_node* next;
+};
+
+
+// ---------------------------------------------------------------------=
-------
+
+typedef struct=20
+{
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+} ButtonListElem;
+
+typedef QList<ButtonListElem *> ButtonListType;
+
+
+// ---------------------------------------------------------------------=
-------
+
+// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
+// Main class
+// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
+
+class IFOFile;
+class CellsListType;
+
+class VobParser
+{
+public:
+ VobParser(const char* dirname, int16_t title, bool menu);
+ void Reset();
+ bool ParseNextPacket(const CellsListType & Cells);
+ uint32_t GetPacketCount() const;
+ uint32_t GetPacketIndex() const;
+ char* GetCurrentPacketData() const;
+ inline uint8_t GetVobID() const;
+ inline uint8_t GetCellID() const;
+ bool IsNewCell();
+ virtual ~VobParser();
+ inline CompositeDemuxWriter & GetDemuxer()
+ {
+ return m_demuxer;
+ }
+ uint32_t GetCellSCR() const;
+
+ nav_dsi_gi m_dsi;
+ nav_pci_gi m_pci;
+ packet_info pktinfo;
+ PES_header_data_content pes_header_data_content;
+protected:
+ void ParseNavPacket();
+ void ParseAudioPacket(int StreamID);
+ void ParseVideoPacket();
+ void ParsePrivateStream1();
+
+ void ParseSCR();
+ void ParsePCI();
+ void ParseDSI();
+ void ParsePESHeaderDataContentFlag();
+ void ParsePESHeaderData();
+ uint64_t ParsePTS_DTS();
+
+ // Buffer management
+ bool AvailablePacketData() const;
+ bool GetNextPacket();
+ uint32_t GetNext32Bits();
+ uint16_t GetNext16Bits();
+ uint8_t GetNext8Bits();
+ void SkipNBytes(int n);
+
+private:
+ int16_t m_title;
+ dvd_reader_t *m_dvdhandle;
+ dvd_file_t *m_stream;
+ bool m_language;
+ uint8_t m_buff[DVD_VIDEO_LB_LEN];
+ uint32_t m_index;
+ uint32_t m_pktindex;
+ uint32_t m_pktcount;
+ bool m_bFirstPacket;
+ int64_t m_startpts;
+ int64_t m_startdts;
+ uint16_t m_pci_position;
+ uint16_t m_pci_size;
+ uint32_t m_pci_vob_timecode_offset;
+=09
+ CompositeDemuxWriter m_demuxer;
+
+ int previous_vobid, previous_cellid;
+};
+
+// ---------------------------------------------------------------------=
-------
+#endif
+// ---------------------------------------------------------------------=
-------
Added: trunk/DvdMenuXtractor/vobparser/iso/iso-639.def
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/vobparser/iso/iso-639.def 2007-01-22 11:21:16 U=
TC (rev 1269)
+++ trunk/DvdMenuXtractor/vobparser/iso/iso-639.def 2007-01-28 16:48:11 U=
TC (rev 1270)
@@ -0,0 +1,173 @@
+/*
+ * Defines the languages codes and abbreviations according to ISO 639-[1=
2].
+ * This is used in iso_lang.cpp and is taken from the GNU glibc 2.2.5 ta=
rball.
+ * It has been partially completed with native language name.
+ *
+ * Format is: ("English name", 639-1-code, 639-2/T-code, 639-2/B-code)
+ * If you find something missing or wrong contact <bug-glibc at gnu.org>
+ */
+
+DEFINE_LANGUAGE_CODE ("Afar", "", aa, aar, aar)
+DEFINE_LANGUAGE_CODE ("Abkhazian", "", ab, abk, abk)
+DEFINE_LANGUAGE_CODE ("Afrikaans", "", af, afr, afr)
+DEFINE_LANGUAGE_CODE ("Albanian", "", sq, sqi, alb)
+DEFINE_LANGUAGE_CODE ("Amharic", "", am, amh, amh)
+DEFINE_LANGUAGE_CODE ("Arabic", "", ar, ara, ara)
+DEFINE_LANGUAGE_CODE ("Armenian", "", hy, hye, arm)
+DEFINE_LANGUAGE_CODE ("Assamese", "", as, asm, asm)
+DEFINE_LANGUAGE_CODE ("Avestan", "", ae, ave, ave)
+DEFINE_LANGUAGE_CODE ("Aymara", "", ay, aym, aym)
+DEFINE_LANGUAGE_CODE ("Azerbaijani", "", az, aze, aze)
+DEFINE_LANGUAGE_CODE ("Bashkir", "", ba, bak, bak)
+DEFINE_LANGUAGE_CODE ("Basque", "", eu, eus, baq)
+DEFINE_LANGUAGE_CODE ("Belarusian", "", be, bel, bel)
+DEFINE_LANGUAGE_CODE ("Bengali", "", bn, ben, ben)
+DEFINE_LANGUAGE_CODE ("Bihari", "", bh, bih, bih)
+DEFINE_LANGUAGE_CODE ("Bislama", "", bi, bis, bis)
+DEFINE_LANGUAGE_CODE ("Bosnian", "", bs, bos, bos)
+DEFINE_LANGUAGE_CODE ("Breton", "", br, bre, bre)
+DEFINE_LANGUAGE_CODE ("Bulgarian", "", bg, bul, bul)
+DEFINE_LANGUAGE_CODE ("Burmese", "", my, mya, bur)
+DEFINE_LANGUAGE_CODE ("Catalan", "", ca, cat, cat)
+DEFINE_LANGUAGE_CODE ("Chamorro", "", ch, cha, cha)
+DEFINE_LANGUAGE_CODE ("Chechen", "", ce, che, che)
+DEFINE_LANGUAGE_CODE ("Chinese", "", zh, zho, chi)
+DEFINE_LANGUAGE_CODE ("Church Slavic", "", cu, chu, chu)
+DEFINE_LANGUAGE_CODE ("Chuvash", "", cv, chv, chv)
+DEFINE_LANGUAGE_CODE ("Cornish", "", kw, cor, cor)
+DEFINE_LANGUAGE_CODE ("Corsican", "", co, cos, cos)
+DEFINE_LANGUAGE_CODE ("Czech", "", cs, ces, cze)
+DEFINE_LANGUAGE_CODE ("Danish", "Dansk", da, dan, dan)
+DEFINE_LANGUAGE_CODE ("Dutch", "Nederlands", nl, nld, dut)
+DEFINE_LANGUAGE_CODE ("Dzongkha", "", dz, dzo, dzo)
+DEFINE_LANGUAGE_CODE ("English", "English", en, eng, eng)
+DEFINE_LANGUAGE_CODE ("Esperanto", "", eo, epo, epo)
+DEFINE_LANGUAGE_CODE ("Estonian", "", et, est, est)
+DEFINE_LANGUAGE_CODE ("Faroese", "", fo, fao, fao)
+DEFINE_LANGUAGE_CODE ("Fijian", "", fj, fij, fij)
+DEFINE_LANGUAGE_CODE ("Finnish", "Suomi", fi, fin, fin)
+DEFINE_LANGUAGE_CODE ("French", "Francais", fr, fra, fre)
+DEFINE_LANGUAGE_CODE ("Frisian", "", fy, fry, fry)
+DEFINE_LANGUAGE_CODE ("Georgian", "", ka, kat, geo)
+DEFINE_LANGUAGE_CODE ("German", "Deutsch", de, deu, ger)
+DEFINE_LANGUAGE_CODE ("Gaelic (Scots)", "", gd, gla, gla)
+DEFINE_LANGUAGE_CODE ("Irish", "", ga, gle, gle)
+DEFINE_LANGUAGE_CODE ("Gallegan", "", gl, glg, glg)
+DEFINE_LANGUAGE_CODE ("Manx", "", gv, glv, glv)
+DEFINE_LANGUAGE_CODE ("Greek, Modern ()", "", el, gre, ell)
+DEFINE_LANGUAGE_CODE ("Guarani", "", gn, grn, grn)
+DEFINE_LANGUAGE_CODE ("Gujarati", "", gu, guj, guj)
+DEFINE_LANGUAGE_CODE ("Hebrew", "", he, heb, heb)
+DEFINE_LANGUAGE_CODE ("Herero", "", hz, her, her)
+DEFINE_LANGUAGE_CODE ("Hindi", "", hi, hin, hin)
+DEFINE_LANGUAGE_CODE ("Hiri Motu", "", ho, hmo, hmo)
+DEFINE_LANGUAGE_CODE ("Hungarian", "Magyar", hu, hun, hun)
+DEFINE_LANGUAGE_CODE ("Icelandic", "Islenska", is, isl, ice)
+DEFINE_LANGUAGE_CODE ("Inuktitut", "", iu, iku, iku)
+DEFINE_LANGUAGE_CODE ("Interlingue", "", ie, ile, ile)
+DEFINE_LANGUAGE_CODE ("Interlingua", "", ia, ina, ina)
+DEFINE_LANGUAGE_CODE ("Indonesian", "", id, ind, ind)
+DEFINE_LANGUAGE_CODE ("Inupiaq", "", ik, ipk, ipk)
+DEFINE_LANGUAGE_CODE ("Italian", "Italiano", it, ita, ita)
+DEFINE_LANGUAGE_CODE ("Javanese", "", jv, jaw, jav)
+DEFINE_LANGUAGE_CODE ("Japanese", "", ja, jpn, jpn)
+DEFINE_LANGUAGE_CODE ("Kalaallisut (Greenlandic)", "", kl, kal, kal)
+DEFINE_LANGUAGE_CODE ("Kannada", "", kn, kan, kan)
+DEFINE_LANGUAGE_CODE ("Kashmiri", "", ks, kas, kas)
+DEFINE_LANGUAGE_CODE ("Kazakh", "", kk, kaz, kaz)
+DEFINE_LANGUAGE_CODE ("Khmer", "", km, khm, khm)
+DEFINE_LANGUAGE_CODE ("Kikuyu", "", ki, kik, kik)
+DEFINE_LANGUAGE_CODE ("Kinyarwanda", "", rw, kin, kin)
+DEFINE_LANGUAGE_CODE ("Kirghiz", "", ky, kir, kir)
+DEFINE_LANGUAGE_CODE ("Komi", "", kv, kom, kom)
+DEFINE_LANGUAGE_CODE ("Korean", "", ko, kor, kor)
+DEFINE_LANGUAGE_CODE ("Kuanyama", "", kj, kua, kua)
+DEFINE_LANGUAGE_CODE ("Kurdish", "", ku, kur, kur)
+DEFINE_LANGUAGE_CODE ("Lao", "", lo, lao, lao)
+DEFINE_LANGUAGE_CODE ("Latin", "", la, lat, lat)
+DEFINE_LANGUAGE_CODE ("Latvian", "", lv, lav, lav)
+DEFINE_LANGUAGE_CODE ("Lingala", "", ln, lin, lin)
+DEFINE_LANGUAGE_CODE ("Lithuanian", "", lt, lit, lit)
+DEFINE_LANGUAGE_CODE ("Letzeburgesch", "", lb, ltz, ltz)
+DEFINE_LANGUAGE_CODE ("Macedonian", "", mk, mkd, mac)
+DEFINE_LANGUAGE_CODE ("Marshall", "", mh, mah, mah)
+DEFINE_LANGUAGE_CODE ("Malayalam", "", ml, mal, mal)
+DEFINE_LANGUAGE_CODE ("Maori", "", mi, mri, mao)
+DEFINE_LANGUAGE_CODE ("Marathi", "", mr, mar, mar)
+DEFINE_LANGUAGE_CODE ("Malay", "", ms, msa, may)
+DEFINE_LANGUAGE_CODE ("Malagasy", "", mg, mlg, mlg)
+DEFINE_LANGUAGE_CODE ("Maltese", "", mt, mlt, mlt)
+DEFINE_LANGUAGE_CODE ("Moldavian", "", mo, mol, mol)
+DEFINE_LANGUAGE_CODE ("Mongolian", "", mn, mon, mon)
+DEFINE_LANGUAGE_CODE ("Nauru", "", na, nau, nau)
+DEFINE_LANGUAGE_CODE ("Navajo", "", nv, nav, nav)
+DEFINE_LANGUAGE_CODE ("Ndebele, South", "", nr, nbl, nbl)
+DEFINE_LANGUAGE_CODE ("Ndebele, North", "", nd, nde, nde)
+DEFINE_LANGUAGE_CODE ("Ndonga", "", ng, ndo, ndo)
+DEFINE_LANGUAGE_CODE ("Nepali", "", ne, nep, nep)
+DEFINE_LANGUAGE_CODE ("Norwegian", "Norsk", no, nor, nor)
+DEFINE_LANGUAGE_CODE ("Norwegian Nynorsk", "", nn, nno, nno)
+DEFINE_LANGUAGE_CODE ("Norwegian Bokm=E5l", "", nb, nob, nob)
+DEFINE_LANGUAGE_CODE ("Chichewa; Nyanja", "", ny, nya, nya)
+DEFINE_LANGUAGE_CODE ("Occitan (post 1500); Proven=E7al", "", oc, oci, o=
ci)
+DEFINE_LANGUAGE_CODE ("Oriya", "", or, ori, ori)
+DEFINE_LANGUAGE_CODE ("Oromo", "", om, orm, orm)
+DEFINE_LANGUAGE_CODE ("Ossetian; Ossetic", "", os, oss, oss)
+DEFINE_LANGUAGE_CODE ("Panjabi", "", pa, pan, pan)
+DEFINE_LANGUAGE_CODE ("Persian", "", fa, fas, per)
+DEFINE_LANGUAGE_CODE ("Pali", "", pi, pli, pli)
+DEFINE_LANGUAGE_CODE ("Polish", "", pl, pol, pol)
+DEFINE_LANGUAGE_CODE ("Portuguese", "Portugues", pt, por, por)
+DEFINE_LANGUAGE_CODE ("Pushto", "", ps, pus, pus)
+DEFINE_LANGUAGE_CODE ("Quechua", "", qu, que, que)
+DEFINE_LANGUAGE_CODE ("Raeto-Romance", "", rm, roh, roh)
+DEFINE_LANGUAGE_CODE ("Romanian", "", ro, ron, rum)
+DEFINE_LANGUAGE_CODE ("Rundi", "", rn, run, run)
+DEFINE_LANGUAGE_CODE ("Russian", "", ru, rus, rus)
+DEFINE_LANGUAGE_CODE ("Sango", "", sg, sag, sag)
+DEFINE_LANGUAGE_CODE ("Sanskrit", "", sa, san, san)
+DEFINE_LANGUAGE_CODE ("Serbian", "", sr, srp, scc)
+DEFINE_LANGUAGE_CODE ("Croatian", "Hrvatski", hr, hrv, scr)
+DEFINE_LANGUAGE_CODE ("Sinhalese", "", si, sin, sin)
+DEFINE_LANGUAGE_CODE ("Slovak", "", sk, slk, slo)
+DEFINE_LANGUAGE_CODE ("Slovenian", "", sl, slv, slv)
+DEFINE_LANGUAGE_CODE ("Northern Sami", "", se, sme, sme)
+DEFINE_LANGUAGE_CODE ("Samoan", "", sm, smo, smo)
+DEFINE_LANGUAGE_CODE ("Shona", "", sn, sna, sna)
+DEFINE_LANGUAGE_CODE ("Sindhi", "", sd, snd, snd)
+DEFINE_LANGUAGE_CODE ("Somali", "", so, som, som)
+DEFINE_LANGUAGE_CODE ("Sotho, Southern", "", st, sot, sot)
+DEFINE_LANGUAGE_CODE ("Spanish", "Espanol", es, spa, spa)
+DEFINE_LANGUAGE_CODE ("Sardinian", "", sc, srd, srd)
+DEFINE_LANGUAGE_CODE ("Swati", "", ss, ssw, ssw)
+DEFINE_LANGUAGE_CODE ("Sundanese", "", su, sun, sun)
+DEFINE_LANGUAGE_CODE ("Swahili", "", sw, swa, swa)
+DEFINE_LANGUAGE_CODE ("Swedish", "Svenska", sv, swe, swe)
+DEFINE_LANGUAGE_CODE ("Tahitian", "", ty, tah, tah)
+DEFINE_LANGUAGE_CODE ("Tamil", "", ta, tam, tam)
+DEFINE_LANGUAGE_CODE ("Tatar", "", tt, tat, tat)
+DEFINE_LANGUAGE_CODE ("Telugu", "", te, tel, tel)
+DEFINE_LANGUAGE_CODE ("Tajik", "", tg, tgk, tgk)
+DEFINE_LANGUAGE_CODE ("Tagalog", "", tl, tgl, tgl)
+DEFINE_LANGUAGE_CODE ("Thai", "", th, tha, tha)
+DEFINE_LANGUAGE_CODE ("Tibetan", "", bo, bod, tib)
+DEFINE_LANGUAGE_CODE ("Tigrinya", "", ti, tir, tir)
+DEFINE_LANGUAGE_CODE ("Tonga (Tonga Islands)", "", to, ton, ton)
+DEFINE_LANGUAGE_CODE ("Tswana", "", tn, tsn, tsn)
+DEFINE_LANGUAGE_CODE ("Tsonga", "", ts, tso, tso)
+DEFINE_LANGUAGE_CODE ("Turkish", "", tr, tur, tur)
+DEFINE_LANGUAGE_CODE ("Turkmen", "", tk, tuk, tuk)
+DEFINE_LANGUAGE_CODE ("Twi", "", tw, twi, twi)
+DEFINE_LANGUAGE_CODE ("Uighur", "", ug, uig, uig)
+DEFINE_LANGUAGE_CODE ("Ukrainian", "", uk, ukr, ukr)
+DEFINE_LANGUAGE_CODE ("Urdu", "", ur, urd, urd)
+DEFINE_LANGUAGE_CODE ("Uzbek", "", uz, uzb, uzb)
+DEFINE_LANGUAGE_CODE ("Vietnamese", "", vi, vie, vie)
+DEFINE_LANGUAGE_CODE ("Volap=FCk", "", vo, vol, vol)
+DEFINE_LANGUAGE_CODE ("Welsh", "", cy, cym, wel)
+DEFINE_LANGUAGE_CODE ("Wolof", "", wo, wol, wol)
+DEFINE_LANGUAGE_CODE ("Xhosa", "", xh, xho, xho)
+DEFINE_LANGUAGE_CODE ("Yiddish", "", yi, yid, yid)
+DEFINE_LANGUAGE_CODE ("Yoruba", "", yo, yor, yor)
+DEFINE_LANGUAGE_CODE ("Zhuang", "", za, zha, zha)
+DEFINE_LANGUAGE_CODE ("Zulu", "", zu, zul, zul)
Added: trunk/DvdMenuXtractor/vobparser/iso/iso_lang.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/vobparser/iso/iso_lang.c 2007-01-22 11:21:16 UT=
C (rev 1269)
+++ trunk/DvdMenuXtractor/vobparser/iso/iso_lang.c 2007-01-28 16:48:11 UT=
C (rev 1270)
@@ -0,0 +1,113 @@
+/***********************************************************************=
******
+ * iso_lang.c: function to decode language code (in dvd or a52 for insta=
nce).
+ ***********************************************************************=
******
+ * Copyright (C) 1998-2001 VideoLAN
+ * $Id: iso_lang.c,v 1.6 2002/06/01 12:32:01 sam Exp $
+ *
+ * Author: St=E9phane Borel <stef at via.ecp.fr>
+ * Arnaud de Bossoreille de Ribou <bozo at via.ecp.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *=20
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA=
.
+ ***********************************************************************=
******/
+
+/***********************************************************************=
******
+ * Preamble
+ ***********************************************************************=
******/
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include "iso_lang.h"
+
+/***********************************************************************=
******
+ * Local tables
+ ***********************************************************************=
******/
+
+#define DEFINE_LANGUAGE_CODE(engName, nativeName, iso1, iso2T, iso2B) \
+ { engName, nativeName, #iso1, #iso2T, #iso2B },
+
+static const iso639_lang_t p_languages[] =3D
+{
+#include "iso-639.def"
+ { NULL, NULL, NULL, NULL, NULL }
+};
+
+static const iso639_lang_t unknown_language =3D
+ { "Unknown", "Unknown", "??", "???", "???" };
+
+/***********************************************************************=
******
+ * DecodeLanguage: gives the long language name from the two-letter
+ * ISO-639 code
+ ***********************************************************************=
******/
+const char * DecodeLanguage( uint16_t i_code )
+{
+ const iso639_lang_t * p_lang;
+ uint8_t psz_code[3];
+
+ if (i_code !=3D 0)
+ {
+ psz_code[0] =3D (uint8_t)(i_code >> 8);
+ psz_code[1] =3D (uint8_t)i_code;
+ psz_code[2] =3D '\0';
+
+ for( p_lang =3D p_languages; p_lang->psz_eng_name; p_lang++ )
+ {
+ if( !strncmp( p_lang->psz_iso639_1, psz_code, 2 ) )
+ {
+ if( *p_lang->psz_native_name )
+ {
+ return p_lang->psz_native_name;
+ }
+
+ return p_lang->psz_eng_name;
+ }
+ }
+ }
+
+ return "Unknown";
+}
+
+const iso639_lang_t * GetLang_1( const char * psz_code )
+{
+ const iso639_lang_t *p_lang;
+
+ for( p_lang =3D p_languages; p_lang->psz_eng_name; p_lang++ )
+ if( !strncmp( p_lang->psz_iso639_1, psz_code, 2 ) )
+ return p_lang;
+
+ return &unknown_language;
+}
+
+const iso639_lang_t * GetLang_2T( const char * psz_code )
+{
+ const iso639_lang_t *p_lang;
+ =20
+ for( p_lang =3D p_languages; p_lang->psz_eng_name; p_lang++ )
+ if( !strncmp( p_lang->psz_iso639_2T, psz_code, 3 ) )
+ return p_lang;
+
+ return &unknown_language;
+}
+
+const iso639_lang_t * GetLang_2B( const char * psz_code )
+{
+ const iso639_lang_t *p_lang;
+
+ for( p_lang =3D p_languages; p_lang->psz_eng_name; p_lang++ )
+ if( !strncmp( p_lang->psz_iso639_2B, psz_code, 3 ) )
+ return p_lang;
+
+ return &unknown_language;
+}
+
Added: trunk/DvdMenuXtractor/vobparser/iso/iso_lang.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/vobparser/iso/iso_lang.h 2007-01-22 11:21:16 UT=
C (rev 1269)
+++ trunk/DvdMenuXtractor/vobparser/iso/iso_lang.h 2007-01-28 16:48:11 UT=
C (rev 1270)
@@ -0,0 +1,51 @@
+/***********************************************************************=
******
+ * iso_lang.h: function to decode language code (in dvd or a52 for insta=
nce).
+ ***********************************************************************=
******
+ * Copyright (C) 1998-2001 VideoLAN
+ * $Id: iso_lang.h,v 1.5 2002/05/20 22:36:42 sam Exp $
+ *
+ * Author: St=E9phane Borel <stef at via.ecp.fr>
+ * Arnaud de Bossoreille de Ribou <bozo at via.ecp.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *=20
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA=
.
+ ***********************************************************************=
******/
+
+#ifndef _ISO_LANG_H_
+#define _ISO_LANG_H_
+
+struct iso639_lang_s
+{
+ char * psz_eng_name; /* Description in English */
+ char * psz_native_name; /* Description in native language */
+ char * psz_iso639_1; /* ISO-639-1 (2 characters) code */
+ char * psz_iso639_2T; /* ISO-639-2/T (3 characters) English co=
de */
+ char * psz_iso639_2B; /* ISO-639-2/B (3 characters) native cod=
e */
+};
+
+typedef struct iso639_lang_s iso639_lang_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const iso639_lang_t * GetLang_1( const char * psz_iso639_1 );
+const iso639_lang_t * GetLang_2T( const char * psz_iso639_2T );
+const iso639_lang_t * GetLang_2B( const char * psz_iso639_2B );
+const char * DecodeLanguage( uint16_t );
+
+#ifdef __cplusplus
+};
+#endif
+#endif // _ISO_LANG_H_
Added: trunk/DvdMenuXtractor/vobparser/vobparser.proj
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/DvdMenuXtractor/vobparser/vobparser.proj 2007-01-22 11:21:16 UT=
C (rev 1269)
+++ trunk/DvdMenuXtractor/vobparser/vobparser.proj 2007-01-28 16:48:11 UT=
C (rev 1270)
@@ -0,0 +1,14 @@
+GROUP vobparser
+{
+ SOURCE IFOContent.cpp
+ SOURCE IFOFile.cpp
+ SOURCE VobParser.cpp
+ SOURCE iso/iso_lang.c
+
+ HEADER IFOContent.h
+ HEADER IFOFile.h
+ HEADER VobParser.h
+ HEADER iso/iso_lang.h
+ =20
+ INCLUDE ..
+}
More information about the Matroska-cvs
mailing list