Import Upstream version 6.0.1

This commit is contained in:
Lu zhiping 2022-06-27 15:33:21 +08:00
commit bf2f17dee9
85 changed files with 60349 additions and 0 deletions

7
AUTHORS Normal file
View File

@ -0,0 +1,7 @@
Daniel Caujolle-Bert <segfault@club-internet.fr>
Thomas Vander Stichele <thomas@apestaart.org>
Rich Wareham <richwareham@users.sourceforge.net>
Kees Cook <kees@outflux.net>
Michael Roitzsch <mroi@users.sourceforge.net>
Frantisek Dvorak <valtri@users.sourceforge.net>
Diego Elio Pettenò <flameeyes@flameeyes.eu>

340
COPYING Normal file
View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

189
ChangeLog Normal file
View File

@ -0,0 +1,189 @@
libdvdnav (6.0.1)
* improve random playback mode, to work-around broken discs
* fix divide-by-zerop issue in tmap search
* fix pthread on OS/2
libdvdnav (6.0.0)
* fix crashes on some DVD on describe_title call
* fix various crashes related to PGC validity
* fix compilation issues
* fix API return codes (and bump release)
libdvdnav (5.0.3)
* added dvdnav_open_stream to read from external read/seek callbacks
* fixed reading DVD label regression
libdvdnav (5.0.2)
* fixed 2 wrong asserts (LP #1236939, #570790)
* fixed 2 crashes (in dvdnav_get_position and dvdnav_get_position_in_title)
libdvdnav (5.0.1)
* removed assert on unknown VM commands, fixing playback of some DVDs
* fixed a double free in dvdnav_free_dup
* fixed an integer overflow, a data race condition and return inconsistency
libdvdnav (5.0.0)
* Android support
* fixed numerous crashes, assertions and corruptions
* rewrite of the build-system, including silent rules
* clean code, simplify and remove warnings
* fix compilation in C++ applications
* removal of remap .MAP files unused feature
* remove the dvdnavmini library
* fix compilation on OS/2 and Hurd
libdvdnav (4.2.1)
* fixed failed assertion on menu-less DVDs
* fixed playback issues on multi-angle DVDs
* fixed crash when playing a DVD from different region than currently set
in the DVD drive
* fixed segfaults when reading certain DVDs (including "Jack Reacher",
"Ghost Protocol", "Inside Man", "The Dictator" and "Tangled")
libdvdnav (4.2.0)
* OS/2 support
* added dvdnav_get_serial_string() function
* fixed ifo leak in dvdnav_describe_chapters()
* added dvdnav_get_video_resolution() to retrieve video resolution
* added dvdnav_program_play() & dvdnav_current_title_program() for
more reliable playback
* fixed deadlock between dvdnav_reset() and dvd_clear()
* fixed pthread_mutex_destroy macro for Win32
* fixed numerous assertion failures occuring when playing DVDs with
new "copy protection" schemes
* fixed forward seeks to always move forward
libdvdnav (4.1.3)
* an embarassing amount of fixes regarding potential memory and resource leaks
(patches contributed by Erik Hovland)
* added dvdread-config (dvdnav-config's younger brother)
* added pkg-config support
* split dvdread to a separate tree; now you need to check it out
and install it before building libdvdnav.
In order to configure libdvdnav We need the executable dvdread-config
somewhere in the PATH or explicitly specified to configure[2] with
--with-dvdread-config=~/bin/dvdread-config
libdvdnav (4.1.2)
* multiple build system fixes
* added dvdnav_describe_title_chapters(title) to get title and chapters
duration
libdvdnav (4.1.1)
* added dvdnav_audio_stream_channels() to return number of channels
* fixed dvdnav_time_search() in multi-angle dvds (but it still needs
improvements)
* added dvdnav_audio_stream_format() to identify the codec used
in audio streams
* starting DVD playback at specific title/part positions with
dvdnav_{title,part}_play() works again
* removed wrong SPU stream change event filter
(fixes unwanted subtitles in the trailer of "Girl, interrupted", RC2)
* fixed error "Expected NAV packet but none found." occuring sometimes
on resume from menu
libdvdnav (0.1.10)
* filter the symbols that we export.
* fix LinkNextC assertion failure (fixes LotR-SEE bonus disc image gallery)
* detect zero stilltime still cells inside PGCs, not only at the end
(fixes "Red Dragon" RC2 scene selection)
* PGC stills seem to work, assertion removed
* fix rare race condition after Exit commands
* fix wrong JumpSS_VTSM execution in German RC2 "Anatomie"
(fix ported from Ogle)
libdvdnav (0.1.9)
* libdvdnav does not depend on libdvdread any more. It has it's own version.
* fix some situations where an unlucky user could trigger assertions
libdvdnav (0.1.8)
* more timing info in cell change event struct
* documentation review
libdvdnav (0.1.7)
* fixed a bug in title jumping, where the title number would not be
converted from TTN to VTS_TTN properly
* some minor sanity checks added to prevent segfaults
libdvdnav (0.1.6) unstable; urgency=low
* new event DVDNAV_WAIT to fix consistency problems in applications with fifos
where libdvdnav is always a bit ahead in the stream, the event forces
the application to wait for its fifos to get empty
* correct HIGHLIGHT reporting when a button is activated
* method to try-run VM operations, now used for safer chapter skipping and menu jumps
* fixed detection of current PTT to not assume a 1:1 mapping between PTTs and PGs
* releasing stills when jumping to menu fixes some state inconsistencies
* do not assume PGs to be physically layed out in sequence on the disc
* optional PGC based seeking
* new event on cell changes for timing info
libdvdnav (0.1.5) unstable; urgency=low
* some bugfixes
* code cleanup
* build process polishing
* more sensible event order in get_next_block to ensure useful event delivery
* VOBU level resume
* fixed: seeking in a multiangle feature briefly showed the wrong angle
libdvdnav (0.1.4) unstable; urgency=low
* more read cache improvements
* minor fixes for some problematic DVDs
libdvdnav (0.1.3-1) unstable; urgency=low
* Zero-copy read cache.
* More support for alternative Menu languages.
-- Rich Wareham <richwareham@users.sourceforge.net> Fri, 2 Aug 2002 08:52:24 +0100
libdvdnav (0.1.2-1) unstable; urgency=low
* Read Cache changes. Recommended setting for read_cache is OFF.
Unless one's DVD drive has too small a buffer.
* Should work with xine 0.9.10 or above.
-- James Courtier-Dutton <jcdutton@users.sourceforge.net> Sun, 3 Jul 2002 15:30:00 +0000
libdvdnav (0.1.1-1) unstable; urgency=low
* New upstream version. (closes: #148495)
* Include TODO
* Fix config.h problem
* Threaded cache
-- Philipp Matthias Hahn <pmhahn@titan.lahn.de> Sat, 1 Jun 2002 17:47:59 +0200
libdvdnav (0.1.0-2) unstable; urgency=low
* Add manual page dvdnav-config.1
* Add bug-presubj on Daniel's request
* Get dvdnav.c:1.17 from CVS to fix angle support
* Merge patch from Jamie Wilkinson (#146699)
* Rerun automake to fix dependencies
* Ack NMU from siggi
* Fix include in examples/menus.c
-- Philipp Hahn <pmhahn@titan.lahn.de> Thu, 23 May 2002 09:41:15 +0200
libdvdnav (0.1.0-1.1) unstable; urgency=low
* Prepared for first 'real' release.
* Bug fixes
* Changes to allow apps to 'roll-their-own' dvdnav_get_next_block functions.
* NMU in order to get xine-dvdnav running again
- changed package name to libdvdnav0
(see patch from Jamie Wilkinson for a better solution)
-- Siggi Langauf <siggi@debian.org> Mon, 20 May 2002 15:57:40 +0200
libdvdnav (0.0.1-1) unstable; urgency=low
* Repackaged using dh-make.
-- Philipp Matthias Hahn <pmhahn@titan.lahn.de> Sun, 7 Apr 2002 16:29:35 +0200
libdvdnav (0.0.1) unstable; urgency=low
* Initial release.
* Split from xine-dvdnav
-- rjw57 <rjw57@hermes.cam.ac.uk> Tue, 12 Mar 2002 19:41:13 +0000

60
Makefile.am Normal file
View File

@ -0,0 +1,60 @@
ACLOCAL_AMFLAGS = -Im4
AM_CPPFLAGS = -I$(top_srcdir)/src $(THREAD_CFLAGS) $(DVDREAD_CFLAGS)
dist_doc_DATA = AUTHORS ChangeLog COPYING README TODO
EXTRA_DIST = msvc/ \
doc/doxy.conf \
doc/mainpage.cpp \
doc/tutorial.cpp \
doc/dvd_structures \
doc/library_layout
lib_LTLIBRARIES = libdvdnav.la
libdvdnav_la_SOURCES = \
src/dvdnav.c \
src/read_cache.c \
src/navigation.c \
src/highlight.c \
src/searching.c \
src/settings.c \
src/dvdnav_internal.h \
src/read_cache.h \
src/vm/decoder.c \
src/vm/decoder.h \
src/vm/vm.c \
src/vm/vm.h \
src/vm/play.c \
src/vm/play.h \
src/vm/getset.c \
src/vm/getset.h \
src/vm/vmget.c \
src/vm/vmcmd.c \
src/vm/vmcmd.h
libdvdnav_la_LDFLAGS = \
-version-info $(DVDNAV_LT_CURRENT):$(DVDNAV_LT_REVISION):$(DVDNAV_LT_AGE) \
-export-symbols-regex "^dvdnav"
libdvdnav_la_LIBADD = $(THREAD_LIBS) $(DVDREAD_LIBS)
pkgincludedir = $(includedir)/dvdnav
pkginclude_HEADERS = \
src/dvdnav/dvdnav.h \
src/dvdnav/dvdnav_events.h \
src/dvdnav/dvd_types.h
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = misc/dvdnav.pc
EXTRA_PROGRAMS = menus
menus_SOURCES = examples/menus.c
menus_LDADD = libdvdnav.la
docs: misc/doxy.conf
@if test x"$(DOXYGEN)" != "xno"; then \
cd misc && $(DOXYGEN) doxy.conf > /dev/null 2> /dev/null; \
fi

1095
Makefile.in Normal file

File diff suppressed because it is too large Load Diff

56
README Normal file
View File

@ -0,0 +1,56 @@
What is this all about?
-----------------------
libdvdnav is a library that allows easy use of sophisticated DVD navigation
features such as DVD menus, multiangle playback and even interactive DVD games.
All this functionality is provided through a simple API which provides the
DVD playback as a single logical stream of blocks, intermitted by special
dvdnav events to report certain conditions. The main usage of libdvdnav is a
loop regularly calling a function to get the next block, surrounded by
additional calls to tell the library of user interaction.
The whole DVD virtual machine and internal playback states are completely
encapsulated.
Where does it come from?
------------------------
This library was based on a lot of code and expertise from the Ogle project.
Ogle was the first DVD player who implemented free DVD navigation. The
libdvdnav developers wish to express their gratitude to the Ogle people
for all the valuable research work they have done.
Initially, the dvdnav code was part of a plugin to the xine media player
called xine-dvdnav. Later on, the DVD VM specific code was split
from xine-dvdnav and went into the first version of libdvdnav.
Then, it was forked, and forked again on MPlayer repositories.
libdvdnav and libdvdread were merged, and then split again.
This is now a new fork libdvdnav, that was created to overcome the lack of
responsiveness of the official development channel (once again).
This new fork will try to simplify, stabilize, fix the security issues and the
numerous crashes and maintain a correct player-agnostic library for DVD playback.
This fork will try to maintain correct authorship tracking, by using git and a
proper history.
How can I use it?
-----------------
libdvdnav is completely licensed under GPL. You may use it at wish within the
bounds of this license. See the file "COPYING" for a copy of the GPL.
Sources for documentation on libdvdnav are:
* the examples directory contains a simple program using libdvdnav
this one is well-commented and therefore a good starting point
* the public header dvdnav.h documents the API
* the public header dvdnav_events.h documents the dvdnav events
* doc/library_layout contains some info on the internal working of libdvdnav
Sources for documentation on DVD terminology, structure and surrounding concepts:
* doc/dvd_structures briefly explains DVD terms and organization
* a more detailed description of DVD structures is available at
http://www.mpucoder.com/dvd/
* the ifo_types.h and nav_types.h headers are also interesting if you
are already used to the sometimes cryptical abbreviations

11
TODO Normal file
View File

@ -0,0 +1,11 @@
* Support DVDs with errors on them. So we can recover from corrupt sectors in the .VOB. Also, handle corrupt .IFO files by using the backup .BUP files.
* Support Random and Shuffle Titles. Only sequencial Titles are currently supported.
* rework documentation
* implement restriction levels:
0 - execute everything as the app commands
1 - do some sensible sanity checking
2 - be more careful, when operations are prohibited (like not seeking/jumping in the presence of stills or cell commands)
3 - fully respect user prohibitions
* cleanup public API and fix libtool versioning
* Update decoder.c with some of the more rare commands. Update already done to vmcmd.c
* RELEASE! (maybe it's time for libdvdnav 0.5?)

1417
aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

348
compile Executable file
View File

@ -0,0 +1,348 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# 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, 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, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" "" $nl"
file_conv=
# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv/,$2, in
*,$file_conv,*)
;;
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
func_file_conv "$1"
if test -z "$lib_path"; then
lib_path=$file
else
lib_path="$lib_path;$file"
fi
linker_opts="$linker_opts -LIBPATH:$file"
}
# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
lib=$1
found=no
save_IFS=$IFS
IFS=';'
for dir in $lib_path $LIB
do
IFS=$save_IFS
if $shared && test -f "$dir/$lib.dll.lib"; then
found=yes
lib=$dir/$lib.dll.lib
break
fi
if test -f "$dir/$lib.lib"; then
found=yes
lib=$dir/$lib.lib
break
fi
if test -f "$dir/lib$lib.a"; then
found=yes
lib=$dir/lib$lib.a
break
fi
done
IFS=$save_IFS
if test "$found" != yes; then
lib=$lib.lib
fi
}
# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
# Assume a capable shell
lib_path=
shared=:
linker_opts=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
eat=1
case $2 in
*.o | *.[oO][bB][jJ])
func_file_conv "$2"
set x "$@" -Fo"$file"
shift
;;
*)
func_file_conv "$2"
set x "$@" -Fe"$file"
shift
;;
esac
;;
-I)
eat=1
func_file_conv "$2" mingw
set x "$@" -I"$file"
shift
;;
-I*)
func_file_conv "${1#-I}" mingw
set x "$@" -I"$file"
shift
;;
-l)
eat=1
func_cl_dashl "$2"
set x "$@" "$lib"
shift
;;
-l*)
func_cl_dashl "${1#-l}"
set x "$@" "$lib"
shift
;;
-L)
eat=1
func_cl_dashL "$2"
;;
-L*)
func_cl_dashL "${1#-L}"
;;
-static)
shared=false
;;
-Wl,*)
arg=${1#-Wl,}
save_ifs="$IFS"; IFS=','
for flag in $arg; do
IFS="$save_ifs"
linker_opts="$linker_opts $flag"
done
IFS="$save_ifs"
;;
-Xlinker)
eat=1
linker_opts="$linker_opts $2"
;;
-*)
set x "$@" "$1"
shift
;;
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
func_file_conv "$1"
set x "$@" -Tp"$file"
shift
;;
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
func_file_conv "$1" mingw
set x "$@" "$file"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -n "$linker_opts"; then
linker_opts="-link$linker_opts"
fi
exec "$@" $linker_opts
exit 1
}
eat=
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
ofile=
cfile=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
# So we strip '-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no '-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# '.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
# Create the lock directory.
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

1480
config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

90
config.h.in Normal file
View File

@ -0,0 +1,90 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
# undef WORDS_BIGENDIAN
# endif
#endif
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES

1801
config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

15819
configure vendored Executable file

File diff suppressed because it is too large Load Diff

127
configure.ac Normal file
View File

@ -0,0 +1,127 @@
dnl --------------------------------------------------------------
dnl Making releases: dvdnav_sub += 1; change DVDNAV_LT_* accordingly
dnl
dnl These are defined in m4 so they can be passed to AC_INIT
dnl --------------------------------------------------------------
m4_define([dvdnav_major], [6])
m4_define([dvdnav_minor], [0])
m4_define([dvdnav_sub], [1])
m4_define([dvdnav_pre], [])
AC_INIT([libdvdnav], [dvdnav_major.dvdnav_minor.dvdnav_sub[]dvdnav_pre])
AC_CONFIG_SRCDIR([src/dvdnav.c])
AC_PREREQ([2.53])
AC_CANONICAL_HOST
AM_INIT_AUTOMAKE([1.6 foreign dist-bzip2 no-dist-gzip subdir-objects])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
LT_INIT
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
DVDNAV_MAJOR="dvdnav_major"
DVDNAV_MINOR="dvdnav_minor"
DVDNAV_SUB="dvdnav_sub"
DVDNAV_PRE="dvdnav_pre"
AC_SUBST(DVDNAV_MAJOR)
AC_SUBST(DVDNAV_MINOR)
AC_SUBST(DVDNAV_SUB)
dnl The libtool version numbers (DVDNAV_LT_*); Don't even think about faking this!
dnl
dnl immediately before every release do:
dnl ===================================
dnl if (the interface is totally unchanged from previous release)
dnl DVDNAV_LT_REVISION ++;
dnl else { /* interfaces have been added, removed or changed */
dnl DVDNAV_LT_REVISION = 0;
dnl DVDNAV_LT_CURRENT ++;
dnl if (any interfaces have been _added_ since last release)
dnl AGE ++;
dnl if (any interfaces have been _removed_ or _incompatibly changed_)
dnl AGE = 0;
dnl }
dnl
dnl If you want to know more about what you are doing, here are some details:
dnl * DVDNAV_LT_CURRENT is the current API version
dnl * DVDNAV_LT_REVISION is an internal revision number which is increased when the API
dnl itself did not change
dnl * DVDNAV_LT_AGE is the number of previous API versions still supported by this library
dnl * libtool has its own numbering scheme, because local library numbering schemes
dnl are platform dependent
dnl * in Linux, the library will be named
dnl libname.so.(DVDNAV_LT_CURRENT - DVDNAV_LT_AGE).DVDNAV_LT_AGE.DVDNAV_LT_REVISION
DVDNAV_LT_CURRENT=6
DVDNAV_LT_AGE=2
DVDNAV_LT_REVISION=0
AC_SUBST(DVDNAV_LT_CURRENT)
AC_SUBST(DVDNAV_LT_AGE)
AC_SUBST(DVDNAV_LT_REVISION)
AC_PROG_CC
AC_SYS_LARGEFILE
AC_C_BIGENDIAN
AS_CASE([$host],
[*mingw32* | *cygwin*], [AC_CHECK_FUNCS(gettimeofday)])
dnl ---------------------------------------------
dnl threads
dnl ---------------------------------------------
case $host in
*-*-freebsd*)
THREAD_LIBS="-L/usr/local/lib -pthread"
THREAD_CFLAGS="-I/usr/local/include -D_THREAD_SAFE"
CFLAGS="$THREAD_CFLAGS $CFLAGS"
;;
*mingw32* | *cygwin*)
;;
*android*)
;;
*)
AC_CHECK_LIB(pthread, pthread_create,
[THREAD_LIBS="-lpthread"],
AC_MSG_ERROR(pthread needed))
;;
esac
AC_SUBST(THREAD_LIBS)
AC_SUBST(THREAD_CFLAGS)
PKG_CHECK_MODULES([DVDREAD], [dvdread >= 6.0.0])
dnl ---------------------------------------------
dnl Check for bitfield compiler flag
dnl ---------------------------------------------
CC_CHECK_CFLAG_APPEND([-mno-ms-bitfields])
dnl check for -Wall -Wextra support
CC_CHECK_CFLAG_APPEND([-Wall -Wsign-compare -Wextra])
dnl ---------------------------------------------
dnl Check for doxygen (dynamic documentation generator)
dnl ---------------------------------------------
AC_CHECK_PROG(DOXYGEN, doxygen, doxygen, no)
dnl ---------------------------------------------
dnl -no-undefined libtool flag
dnl
dnl This should be after all checks
dnl ---------------------------------------------
AS_CASE([$host_os],
[os2*], [LDFLAGS="$LDFLAGS -no-undefined"])
dnl ---------------------------------------------
dnl Output configuration files
dnl ---------------------------------------------
AC_OUTPUT([
Makefile
misc/dvdnav.pc
misc/libdvdnav.spec
])

791
depcomp Executable file
View File

@ -0,0 +1,791 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
# 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, 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, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by 'PROGRAMS ARGS'.
object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
# Get the directory component of the given path, and save it in the
# global variables '$dir'. Note that this directory component will
# be either empty or ending with a '/' character. This is deliberate.
set_dir_from ()
{
case $1 in
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
*) dir=;;
esac
}
# Get the suffix-stripped basename of the given path, and save it the
# global variable '$base'.
set_base_from ()
{
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
}
# If no dependency file was actually created by the compiler invocation,
# we still have to create a dummy depfile, to avoid errors with the
# Makefile "include basename.Plo" scheme.
make_dummy_depfile ()
{
echo "#dummy" > "$depfile"
}
# Factor out some common post-processing of the generated depfile.
# Requires the auxiliary global variable '$tmpdepfile' to be set.
aix_post_process_depfile ()
{
# If the compiler actually managed to produce a dependency file,
# post-process it.
if test -f "$tmpdepfile"; then
# Each line is of the form 'foo.o: dependency.h'.
# Do two passes, one to just change these to
# $object: dependency.h
# and one to simply output
# dependency.h:
# which is needed to avoid the deleted-header problem.
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
} > "$depfile"
rm -f "$tmpdepfile"
else
make_dummy_depfile
fi
}
# A tabulation character.
tab=' '
# A newline character.
nl='
'
# Character ranges might be problematic outside the C locale.
# These definitions help.
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
lower=abcdefghijklmnopqrstuvwxyz
digits=0123456789
alpha=${upper}${lower}
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Avoid interferences from the environment.
gccflag= dashmflag=
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
## (see the conditional assignment to $gccflag above).
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say). Also, it might not be
## supported by the other compilers which use the 'gcc' depmode.
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The second -e expression handles DOS-style file names with drive
# letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
| tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile"
;;
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
aix_post_process_depfile
;;
tcc)
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
# FIXME: That version still under development at the moment of writing.
# Make that this statement remains true also for stable, released
# versions.
# It will wrap lines (doesn't matter whether long or short) with a
# trailing '\', as in:
#
# foo.o : \
# foo.c \
# foo.h \
#
# It will put a trailing '\' even on the last line, and will use leading
# spaces rather than leading tabs (at least since its commit 0394caf7
# "Emit spaces for -MD").
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
# We have to change lines of the first kind to '$object: \'.
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
# And for each line of the second kind, we have to emit a 'dep.h:'
# dummy dependency, to avoid the deleted-header problem.
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
## The order of this option in the case statement is important, since the
## shell code in configure will try each of these formats in the order
## listed in this file. A plain '-MD' option would be understood by many
## compilers, so we must ensure this comes after the gcc and icc options.
pgcc)
# Portland's C compiler understands '-MD'.
# Will always output deps to 'file.d' where file is the root name of the
# source file under compilation, even if file resides in a subdirectory.
# The object file name does not affect the name of the '.d' file.
# pgcc 10.2 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using '\' :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
set_dir_from "$object"
# Use the source, not the object, to determine the base name, since
# that's sadly what pgcc will do too.
set_base_from "$source"
tmpdepfile=$base.d
# For projects that build the same source file twice into different object
# files, the pgcc approach of using the *source* file root name can cause
# problems in parallel builds. Use a locking strategy to avoid stomping on
# the same $tmpdepfile.
lockdir=$base.d-lock
trap "
echo '$0: caught signal, cleaning up...' >&2
rmdir '$lockdir'
exit 1
" 1 2 13 15
numtries=100
i=$numtries
while test $i -gt 0; do
# mkdir is a portable test-and-set.
if mkdir "$lockdir" 2>/dev/null; then
# This process acquired the lock.
"$@" -MD
stat=$?
# Release the lock.
rmdir "$lockdir"
break
else
# If the lock is being held by a different process, wait
# until the winning process is done or we timeout.
while test -d "$lockdir" && test $i -gt 0; do
sleep 1
i=`expr $i - 1`
done
fi
i=`expr $i - 1`
done
trap - 1 2 13 15
if test $i -le 0; then
echo "$0: failed to acquire lock after $numtries attempts" >&2
echo "$0: check lockdir '$lockdir'" >&2
exit 1
fi
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
# Libtool generates 2 separate objects for the 2 libraries. These
# two compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir$base.o.d # libtool 1.5
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
# Same post-processing that is required for AIX mode.
aix_post_process_depfile
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this sed invocation
# correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process the last invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed '1,2d' "$tmpdepfile" \
| tr ' ' "$nl" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E \
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
| sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

947
doc/doxy.conf Normal file
View File

@ -0,0 +1,947 @@
# Doxyfile 1.2.16
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project
#
# All text after a hash (#) is considered a comment and will be ignored
# The format is:
# TAG = value [value, ...]
# For lists items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (" ")
#---------------------------------------------------------------------------
# General configuration options
#---------------------------------------------------------------------------
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
PROJECT_NAME = libdvdnav
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER =
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY =
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# The default language is English, other supported languages are:
# Brazilian, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch,
# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Korean,
# Norwegian, Polish, Portuguese, Romanian, Russian, Slovak, Slovene,
# Spanish, Swedish and Ukrainian.
OUTPUT_LANGUAGE = English
# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
# documentation are documented, even if no documentation was available.
# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
EXTRACT_ALL = NO
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
# will be included in the documentation.
EXTRACT_PRIVATE = NO
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC = NO
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
# defined locally in source files will be included in the documentation.
# If set to NO only classes defined in header files are included.
EXTRACT_LOCAL_CLASSES = YES
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
# undocumented members of documented classes, files or namespaces.
# If set to NO (the default) these members will be included in the
# various overviews, but no documentation section is generated.
# This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy.
# If set to NO (the default) these class will be included in the various
# overviews. This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_CLASSES = NO
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
# the file and class documentation (similar to JavaDoc).
# Set to NO to disable this.
BRIEF_MEMBER_DESC = YES
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
# the brief description of a member or function before the detailed description.
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
REPEAT_BRIEF = YES
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# Doxygen will generate a detailed section even if there is only a brief
# description.
ALWAYS_DETAILED_SEC = NO
# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
# members of a class in the documentation of that class as if those members were
# ordinary class members. Constructors, destructors and assignment operators of
# the base classes will not be shown.
INLINE_INHERITED_MEMB = NO
# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.
FULL_PATH_NAMES = NO
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
# can be used to strip a user defined part of the path. Stripping is
# only done if one of the specified strings matches the left-hand part of
# the path. It is allowed to use relative paths in the argument list.
STRIP_FROM_PATH =
# The INTERNAL_DOCS tag determines if documentation
# that is typed after a \internal command is included. If the tag is set
# to NO (the default) then the documentation will be excluded.
# Set it to YES to include the internal documentation.
INTERNAL_DOCS = NO
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
STRIP_CODE_COMMENTS = YES
# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
# file names in lower case letters. If set to YES upper case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
# users are adviced to set this option to NO.
CASE_SENSE_NAMES = YES
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
# (but less readable) file names. This can be useful is your file systems
# doesn't support long names like on DOS, Mac, or CD-ROM.
SHORT_NAMES = NO
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
# will show members with their full class and namespace scopes in the
# documentation. If set to YES the scope will be hidden.
HIDE_SCOPE_NAMES = NO
# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
# will generate a verbatim copy of the header file for each class for
# which an include is specified. Set to NO to disable this.
VERBATIM_HEADERS = YES
# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
# will put list of the files that are included by a file in the documentation
# of that file.
SHOW_INCLUDE_FILES = YES
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
# comment as the brief description. If set to NO, the JavaDoc
# comments will behave just like the Qt-style comments (thus requiring an
# explict @brief command for a brief description.
JAVADOC_AUTOBRIEF = YES
# If the DETAILS_AT_TOP tag is set to YES then Doxygen
# will output the detailed description near the top, like JavaDoc.
# If set to NO, the detailed description appears after the member
# documentation.
DETAILS_AT_TOP = NO
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
# member inherits the documentation from any documented member that it
# reimplements.
INHERIT_DOCS = YES
# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
# is inserted in the documentation for inline members.
INLINE_INFO = YES
# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
# will sort the (detailed) documentation of file and class members
# alphabetically by member name. If set to NO the members will appear in
# declaration order.
SORT_MEMBER_DOCS = YES
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
# tag is set to YES, then doxygen will reuse the documentation of the first
# member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly.
DISTRIBUTE_GROUP_DOC = NO
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
# Doxygen uses this value to replace tabs by spaces in code fragments.
TAB_SIZE = 8
# The GENERATE_TODOLIST tag can be used to enable (YES) or
# disable (NO) the todo list. This list is created by putting \todo
# commands in the documentation.
GENERATE_TODOLIST = YES
# The GENERATE_TESTLIST tag can be used to enable (YES) or
# disable (NO) the test list. This list is created by putting \test
# commands in the documentation.
GENERATE_TESTLIST = YES
# The GENERATE_BUGLIST tag can be used to enable (YES) or
# disable (NO) the bug list. This list is created by putting \bug
# commands in the documentation.
GENERATE_BUGLIST = YES
# This tag can be used to specify a number of aliases that acts
# as commands in the documentation. An alias has the form "name=value".
# For example adding "sideeffect=\par Side Effects:\n" will allow you to
# put the command \sideeffect (or @sideeffect) in the documentation, which
# will result in a user defined paragraph with heading "Side Effects:".
# You can put \n's in the value part of an alias to insert newlines.
ALIASES =
# The ENABLED_SECTIONS tag can be used to enable conditional
# documentation sections, marked by \if sectionname ... \endif.
ENABLED_SECTIONS =
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
# the initial value of a variable or define consist of for it to appear in
# the documentation. If the initializer consists of more lines than specified
# here it will be hidden. Use a value of 0 to hide initializers completely.
# The appearance of the initializer of individual variables and defines in the
# documentation can be controlled using \showinitializer or \hideinitializer
# command in the documentation regardless of this setting.
MAX_INITIALIZER_LINES = 30
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C.
# For instance some of the names that are used will be different. The list
# of all members will be omitted, etc.
OPTIMIZE_OUTPUT_FOR_C = YES
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
# only. Doxygen will then generate output that is more tailored for Java.
# For instance namespaces will be presented as packages, qualified scopes
# will look different, etc.
OPTIMIZE_OUTPUT_JAVA = NO
# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
# at the bottom of the documentation of classes and structs. If set to YES the
# list will mention the files that were used to generate the documentation.
SHOW_USED_FILES = YES
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
# The QUIET tag can be used to turn on/off the messages that are generated
# by doxygen. Possible values are YES and NO. If left blank NO is used.
QUIET = NO
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated by doxygen. Possible values are YES and NO. If left blank
# NO is used.
WARNINGS = YES
# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
# automatically be disabled.
WARN_IF_UNDOCUMENTED = YES
# The WARN_FORMAT tag determines the format of the warning messages that
# doxygen can produce. The string should contain the $file, $line, and $text
# tags, which will be replaced by the file and line number from which the
# warning originated and the warning text.
WARN_FORMAT = "$file:$line: $text"
# The WARN_LOGFILE tag can be used to specify a file to which warning
# and error messages should be written. If left blank the output is written
# to stderr.
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
# The INPUT tag can be used to specify the files and/or directories that contain
# documented source files. You may enter file names like "myfile.cpp" or
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = .
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank the following patterns are tested:
# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
# *.h++ *.idl *.odl
FILE_PATTERNS =
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.
RECURSIVE = NO
# The EXCLUDE tag can be used to specify files and/or directories that should
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
EXCLUDE =
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
# that are symbolic links (a Unix filesystem feature) are excluded from the input.
EXCLUDE_SYMLINKS = NO
# If the value of the INPUT tag contains directories, you can use the
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
# certain files from those directories.
EXCLUDE_PATTERNS =
# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH = examples
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
EXAMPLE_PATTERNS =
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
# searched for input files to be used with the \include or \dontinclude
# commands irrespective of the value of the RECURSIVE tag.
# Possible values are YES and NO. If left blank NO is used.
EXAMPLE_RECURSIVE = NO
# The IMAGE_PATH tag can be used to specify one or more files or
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH =
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
# by executing (via popen()) the command <filter> <input-file>, where <filter>
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
# input file. Doxygen will then use the output that the filter program writes
# to standard output.
INPUT_FILTER =
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER) will be used to filter the input files when producing source
# files to browse.
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
# be generated. Documented entities will be cross-referenced with these sources.
SOURCE_BROWSER = NO
# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.
INLINE_SOURCES = NO
# If the REFERENCED_BY_RELATION tag is set to YES (the default)
# then for each documented function all documented
# functions referencing it will be listed.
REFERENCED_BY_RELATION = YES
# If the REFERENCES_RELATION tag is set to YES (the default)
# then for each documented function all documented entities
# called/used by that function will be listed.
REFERENCES_RELATION = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
# of all compounds will be generated. Enable this if the project
# contains a lot of classes, structs, unions or interfaces.
ALPHABETICAL_INDEX = NO
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all
# classes will be put under the same header in the alphabetical index.
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
# should be ignored while generating the index headers.
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.
GENERATE_HTML = YES
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
HTML_OUTPUT = html
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
# doxygen will generate files with .html extension.
HTML_FILE_EXTENSION = .html
# The HTML_HEADER tag can be used to specify a personal HTML header for
# each generated HTML page. If it is left blank doxygen will generate a
# standard header.
HTML_HEADER =
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
HTML_FOOTER =
# The HTML_STYLESHEET tag can be used to specify a user defined cascading
# style sheet that is used by each HTML page. It can be used to
# fine-tune the look of the HTML output. If the tag is left blank doxygen
# will generate a default style sheet
HTML_STYLESHEET =
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
HTML_ALIGN_MEMBERS = YES
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
# of the generated HTML documentation.
GENERATE_HTMLHELP = NO
# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
# controls if a separate .chi index file is generated (YES) or that
# it should be included in the master .chm file (NO).
GENERATE_CHI = NO
# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
# controls whether a binary table of contents is generated (YES) or a
# normal table of contents (NO) in the .chm file.
BINARY_TOC = NO
# The TOC_EXPAND flag can be set to YES to add extra items for group members
# to the contents of the Html help documentation and to the tree view.
TOC_EXPAND = NO
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
# top of each HTML page. The value NO (the default) enables the index and
# the value YES disables it.
DISABLE_INDEX = NO
# This tag can be used to set the number of enum values (range [1..20])
# that doxygen will group on one line in the generated HTML documentation.
ENUM_VALUES_PER_LINE = 4
# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
# generated containing a tree-like index structure (just like the one that
# is generated for HTML Help). For this to work a browser that supports
# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+,
# or Internet explorer 4.0+). Note that for large projects the tree generation
# can take a very long time. In such cases it is better to disable this feature.
# Windows users are probably better off using the HTML help feature.
GENERATE_TREEVIEW = NO
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
# used to set the initial width (in pixels) of the frame in which the tree
# is shown.
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
GENERATE_LATEX = YES
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `latex' will be used as the default path.
LATEX_OUTPUT = latex
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be invoked. If left blank `latex' will be used as the default command name.
LATEX_CMD_NAME = latex
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
# generate index for LaTeX. If left blank `makeindex' will be used as the
# default command name.
MAKEINDEX_CMD_NAME = makeindex
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
# LaTeX documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_LATEX = NO
# The PAPER_TYPE tag can be used to set the paper type that is used
# by the printer. Possible values are: a4, a4wide, letter, legal and
# executive. If left blank a4wide will be used.
PAPER_TYPE = a4wide
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
# packages that should be included in the LaTeX output.
EXTRA_PACKAGES =
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
# the generated latex document. The header should contain everything until
# the first chapter. If it is left blank doxygen will generate a
# standard header. Notice: only use this tag if you know what you are doing!
LATEX_HEADER =
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
# contain links (just like the HTML output) instead of page references
# This makes the output suitable for online browsing using a pdf viewer.
PDF_HYPERLINKS = NO
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
# plain latex in the generated Makefile. Set this option to YES to get a
# higher quality PDF documentation.
USE_PDFLATEX = NO
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
# command to the generated LaTeX files. This will instruct LaTeX to keep
# running if errors occur, instead of asking the user for help.
# This option is also used when generating formulas in HTML.
LATEX_BATCHMODE = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
# The RTF output is optimised for Word 97 and may not look very pretty with
# other RTF readers or editors.
GENERATE_RTF = NO
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `rtf' will be used as the default path.
RTF_OUTPUT = rtf
# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
# RTF documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_RTF = NO
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
# will contain hyperlink fields. The RTF file will
# contain links (just like the HTML output) instead of page references.
# This makes the output suitable for online browsing using WORD or other
# programs which support those fields.
# Note: wordpad (write) and others do not support links.
RTF_HYPERLINKS = NO
# Load stylesheet definitions from file. Syntax is similar to doxygen's
# config file, i.e. a series of assigments. You only have to provide
# replacements, missing definitions are set to their default value.
RTF_STYLESHEET_FILE =
# Set optional variables used in the generation of an rtf document.
# Syntax is similar to doxygen's config file.
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages
GENERATE_MAN = NO
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `man' will be used as the default path.
MAN_OUTPUT = man
# The MAN_EXTENSION tag determines the extension that is added to
# the generated man pages (default is the subroutine's section .3)
MAN_EXTENSION = .3
# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
# then it will generate one additional man file for each entity
# documented in the real man page(s). These additional files
# only source the real man page, but without them the man command
# would be unable to find the correct page. The default is NO.
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
# If the GENERATE_XML tag is set to YES Doxygen will
# generate an XML file that captures the structure of
# the code including all documentation. Note that this
# feature is still experimental and incomplete at the
# moment.
GENERATE_XML = NO
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
# generate an AutoGen Definitions (see autogen.sf.net) file
# that captures the structure of the code including all
# documentation. Note that this feature is still experimental
# and incomplete at the moment.
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
# evaluate all C-preprocessor directives found in the sources and include
# files.
ENABLE_PREPROCESSING = YES
# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
# names in the source code. If set to NO (the default) only conditional
# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.
MACRO_EXPANSION = NO
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_PREDEFINED tags.
EXPAND_ONLY_PREDEF = NO
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
# in the INCLUDE_PATH (see below) will be search if a #include is found.
SEARCH_INCLUDES = YES
# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by
# the preprocessor.
INCLUDE_PATH =
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
# directories. If left blank, the patterns specified with FILE_PATTERNS will
# be used.
INCLUDE_FILE_PATTERNS =
# The PREDEFINED tag can be used to specify one or more macro names that
# are defined before the preprocessor is started (similar to the -D option of
# gcc). The argument of the tag is a list of macros of the form: name
# or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed.
PREDEFINED =
# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
# The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition.
EXPAND_AS_DEFINED =
# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
# doxygen's preprocessor will remove all function-like macros that are alone
# on a line and do not end with a semicolon. Such function macros are typically
# used for boiler-plate code, and will confuse the parser if not removed.
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to external references
#---------------------------------------------------------------------------
# The TAGFILES tag can be used to specify one or more tagfiles.
TAGFILES =
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
# a tag file that is based on the input files it reads.
GENERATE_TAGFILE =
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
# in the class index. If set to NO only the inherited external classes
# will be listed.
ALLEXTERNALS = NO
# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
# in the modules index. If set to NO, only the current project's groups will
# be listed.
EXTERNAL_GROUPS = YES
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or
# super classes. Setting the tag to NO turns the diagrams off. Note that this
# option is superceded by the HAVE_DOT option below. This is only a fallback. It is
# recommended to install and use dot, since it yield more powerful graphs.
CLASS_DIAGRAMS = YES
# If set to YES, the inheritance and collaboration graphs will hide
# inheritance and usage relations if the target is undocumented
# or is not a class.
HIDE_UNDOC_RELATIONS = YES
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz, a graph visualization
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
# have no effect if this option is set to NO (the default)
HAVE_DOT = NO
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect inheritance relations. Setting this tag to YES will force the
# the CLASS_DIAGRAMS tag to NO.
CLASS_GRAPH = YES
# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect implementation dependencies (inheritance, containment, and
# class references variables) of the class with other documented classes.
COLLABORATION_GRAPH = YES
# If set to YES, the inheritance and collaboration graphs will show the
# relations between templates and their instances.
TEMPLATE_RELATIONS = YES
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
# tags are set to YES then doxygen will generate a graph for each documented
# file showing the direct and indirect include dependencies of the file with
# other documented files.
INCLUDE_GRAPH = YES
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
# documented header file showing the documented files that directly or
# indirectly include this file.
INCLUDED_BY_GRAPH = YES
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
# will graphical hierarchy of all classes instead of a textual one.
GRAPHICAL_HIERARCHY = YES
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot. Possible values are png, jpg, or gif
# If left blank png will be used.
DOT_IMAGE_FORMAT = png
# The tag DOT_PATH can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found on the path.
DOT_PATH =
# The DOTFILE_DIRS tag can be used to specify one or more directories that
# contain dot files that are included in the documentation (see the
# \dotfile command).
DOTFILE_DIRS =
# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_WIDTH = 1024
# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_HEIGHT = 1024
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
# generate a legend page explaining the meaning of the various boxes and
# arrows in the dot generated graphs.
GENERATE_LEGEND = YES
# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
# remove the intermedate dot files that are used to generate
# the various graphs.
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to the search engine
#---------------------------------------------------------------------------
# The SEARCHENGINE tag specifies whether or not a search engine should be
# used. If set to NO the values of all tags below this one will be ignored.
SEARCHENGINE = NO
# The CGI_NAME tag should be the name of the CGI script that
# starts the search engine (doxysearch) with the correct parameters.
# A script with this name will be generated by doxygen.
CGI_NAME = search.cgi
# The CGI_URL tag should be the absolute URL to the directory where the
# cgi binaries are located. See the documentation of your http daemon for
# details.
CGI_URL =
# The DOC_URL tag should be the absolute URL to the directory where the
# documentation is located. If left blank the absolute path to the
# documentation, with file:// prepended to it, will be used.
DOC_URL =
# The DOC_ABSPATH tag should be the absolute path to the directory where the
# documentation is located. If left blank the directory on the local machine
# will be used.
DOC_ABSPATH =
# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
# is installed.
BIN_ABSPATH = /usr/local/bin/
# The EXT_DOC_PATHS tag can be used to specify one or more paths to
# documentation generated for other projects. This allows doxysearch to search
# the documentation for these projects as well.
EXT_DOC_PATHS =

107
doc/dvd_structures Normal file
View File

@ -0,0 +1,107 @@
This is some rather basic information on the organizational structures of
a DVD. I collected this info over time from various sources, the most
valuable being an article in the German c't computer magazine.
Some of the info might be wrong according to the DVD standard (which I do
not know), but they are practically proven in libdvdnav.
Michael Roitzsch
0. storage structure
- sector
* smallest addressable unit on disc
* data is stored on disc with a Reed-Solomon error correction
- file
* the storage entity in the underlying filesystem (usually UDF)
* on DVD-Video, files are stored consecutively
1. MPEG stream structure
- blocks
* a file system driver (usually UDF) is needed to map the VOBS-local
block numbers to global disc sectors
- GOP (group of pictures)
* contains multiple sectors
* smallest self-contained MPEG unit
- VOBU (video object unit)
* contains multiple GOPs + audio and SPU blocks + NAV packet
* smallest unit in seek and resume operations, always starts with a
NAV packet used for menu button highlight and command information
and to detect PTS discontinuities
- ILVU (interleaved video unit)
* contains multiple VOBUs (ususally only one)
* blocking multiple VOBUs of multiple interleaved MPEG streams for
multiangle features
- VOB (video object)
* contains multiple ILVUs (usually quite a lot)
* each NAV packet has a CellID, so VOBs are divided into stream Cells
which do not necessarily correspond to the navigation Cells below
- VOBS (video object set)
* contains multiple VOBs (addressed by VOB_ID)
* a VOBS is the storage analogy to the playback domains below,
therefore, a VMGM_VOBS, a VTSM_VOBS and a VTS_VOBS exist
* all block addressing is done within the scope of the VOBS
2. navigational structure - logical playback control
- Cell
* smallest unit which is layed out in sequence
* points to a first and last VOBU (by sector)
* also points to the corresponding CellID and VOB_ID
* smallest unit to execute VM commands (cell_post commands)
* smallest unit accesible by VM commands (apart from LinkRSM)
- PG (program)
* points to a Cell
* usually the mapping between PG and Cells is 1:1, but not always
(multiple Cells inside one PG can occur when special VM commands
have to be executed in the middle of a PG, for example to switch
SPU channels or to provide a branching target for special
features that need access to parts of the movie)
* unit for user skip operations
* libdvdnav's default unit for seeking
- PGC (program chain)
* contains multiple programs and cells
* logical playback chain
* VM commands at start and stop (PGC_pre and PGC_post commands)
* might be used for seeking (see dvdnav_set_PGC_positioning())
3. title structure - high level navigation
- PTT (part of title track)
* points to a PG in a PGC
* usually what you select in a "chapter menu" are parts
* usually the mapping between PTT and PG is 1:1, but not always
(this is similar to the distinction between track and index marks
on audio CDs: PTT = track mark, PG = index mark)
- TT (title track)
* contains multiple PTTs
* logical partitioning of the content
(multiple episodes of a TV series on one DVD: one TT per episode)
* the display of DVD players show title and part number
- VTS (video title set)
* contains multiple TTs with a local numbering (to emphasize the
local scope of the number, these are also called VTS_TT)
* high level partitioning of the content (movie / bonus material)
* video, audio and spu attributes are common inside a whole VTS
4. domain structure - bringing it all together
- FP (first play)
* one special PGC in the VMGM domain run on start of the disc
- VMGM (video manager menu) - files video_ts.{vob,ifo,bup}
* the menu which allows you to select between title sets
* corresponds to the VMGM_VOBS (video_ts.vob) and
the VMGI (video_ts.ifo)
* contains sets of PGCs, differentiated by language
* contains a global table of TTs each pointing to a VTS and a local VTS_TT
* contains parental management information
* contains attribute lists for the VTS'es
* contains text data (?)
* contains a Cell and a VOBU lists with local sector info (for seeking)
- VTSM (video title set menu) - files vts_<vtsN>_0.{vob,ifo,bup}
* the menu which allows you to select between the TTs of a VTS
* corresponds to the VTSM_VOBS (vts_<vtsN>_0.vob) and
the VTSI (vts_<vtsN>_0.ifo)
* contains sets of PGCs, differentiated by language
* contains a Cell and a VOBU lists with local sector info (for seeking)
- VTS (video title set) - files vts_<vtsN>_[1-x].vob, vts_<vtsN>_0.{ifo,bup}
* regular playback domain
* corresponds to the VTS_VOBS (vts_<vtsN>_[1-x].vob) and
the VTSI (vts_<vtsN>_0.ifo)
* contains one VTS with its VTS_TTs and PGCs
* contains a time map (for time-based seeking)
* contains a Cell and a VOBU lists with local sector info (for seeking)
- STOP
* 'nuff said

53
doc/library_layout Normal file
View File

@ -0,0 +1,53 @@
This is information on what the various files in libdvdnav/src are for:
public API
----------
dvdnav.h main public header
dvdnav_events.h events returned by get_next_block()
dvd_types.h some additional convenience types, mostly unused yet
dvd_reader.h libdvdread API
ifo_types.h IFO structures translated into C
ifo_read.h reading and parsing of IFO structures
nav_types.h NAV structures translated into C
nav_read.h reading and parsing of NAV structures
nav_print.h print NAV structures in a human readable form
client interaction
------------------
dvdnav.c the big get_next_block() function and some basic housekeeping
dvdnav_internal.h internal structure of libdvdnav library handle
navigation.c basic Title/Part navigation
searching.c PGC/PG navigation and seeking, position reporting
highlight.c DVD menu highlight handling
settings.c libdvdnav customizing
remap.[ch] user defined reorganization of VOBU playback order
DVD virtual machine (subdirectory vm)
-------------------
vm.[ch] the logic surrounding the DVD VM
decoder.[ch] decodes and executes DVD VM commands
DVD reading (subdirectory dvdread, a modified copy of libdvdread)
-----------
dvd_reader.c reading data from DVD sources
dvd_udf.[ch] handles the UDF filesystem
dvd_input.[ch] lowlevel input abstraction, libdvdcss glue code
md5.[ch] md5 hashing to provide unique disc IDs
ifo_read.c reading and parsing of IFO structures
nav_read.c reading and parsing of NAV structures
nav_print.c output NAV structures in a human readable form
read_cache.[ch] caching
debugging and utilities
-----------------------
bswap.h endianness helper macros
dvdread_internal.h CHECK_VALUE() helper macro
vmcmd.[ch] print DVD VM commands and registers in a human readable form

51
doc/mainpage.cpp Normal file
View File

@ -0,0 +1,51 @@
/*!
\mainpage The libdvdnav Reference Documentation
\section intro Introduction
This reference is not maintained. See the README file for pointers on
current documentation.
This reference documentation is intended to both provide a comprehensive reference to
the <tt>libdvdnav</tt> DVD navigation library and a brief introduction to the library
for new users.
This documentation is automatically generated from the <tt>libdvdnav</tt> code so
should remain somewhat relevant but as always be wary that <tt>libdvdnav</tt>
is currently in heavy development and the API is not yet frozen.
\subsection feedback Feedback
All comments, error reports, additional information and criticism of all sorts
should be directed to <tt>dvd-devel@lists.sf.net</tt>.
\subsection disclaimer Disclaimer
No liability for the contents of this documents can be accepted. Use the concepts,
examples and other content at your own risk. Additionally, this is an early version,
with many possibilities for inaccuracies and errors.
As far as I know, all of the programmes mentioned here and example code quoted are
released under the GNU General Public License or the Lesser GNU Public License.
\subsection copyright Copyright information
This document is copyrighted &copy;2002 by Richard Wareham and the <tt>libdvdnav</tt>
project. It is distributed under the following terms:
- This document may be reproduced and distributed in whole or in part, in any medium
physical or electronic, as long as this copyright notice is retained on all copies.
Commercial redistribution is allowed and encouraged; however, the author would like
to be notified of any such distributions.
- All translations, derivative works, or aggregate works incorporating any parts of
this document must be covered under this copyright notice. That is, you may not produce
a derivative work from this manual and impose additional restrictions on its distribution.
\section sections Section
- A tutorial is in section \ref tutorial .
- A complete reference may be found in the <A HREF="modules.html">modules</a> section.
*/

253
doc/tutorial.cpp Normal file
View File

@ -0,0 +1,253 @@
/*! \page tutorial A libdvdnav Tutorial
The <tt>libdvdnav</tt> library provides a powerful API allowing your
programs to take advantage of the sophisticated navigation features
on DVDs.
\subsection wherenow Tutorial sections
- For an introduction to the navigation features of DVDs look in section
\ref dvdnavissues . This also provides an overview of the concepts
required to understand DVD navigation.
- For a step-by step walkthrough of a simple program look in
section \ref firstprog .
- FIXME: More sections :)
*/
/*! \page dvdnavissues An introduction to DVD navigation
The DVD format represents a radical departure from the traditional
form of video home-entertainment. Instead of just being a linear
programme which is watched from beginning to end like a novel
DVD allows the user to jump about at will (much like those
'Choose your own adventure' or 'Which Way' books which were
popular a while back).
Such features are usually referred to under the moniker
'interactive' by marketting people but you aren't in marketting
since you are reading the <tt>libdvdnav</tt> tutorial. We'll
assume you actually want to know precisely what DVD can do.
\subsection layout DVD logical layout
A DVD is logically structured into titles, chapters (also
known as 'parts'), cells and VOBUS, much like the
filesystem on your hard disc. The structure is heirachical.
A typical DVD might have the following structure:
\verbatim
.
|-- Title 1
| |-- Chapter 1
| | |-- Cell 1
| | | |-- VOBU 1
| | | |-- ...
| | | `-- VOBU n
| | |-- ...
| | `-- Cell n
| |-- ...
| `-- Chapter 2
| |-- Cell 1
| | |-- VOBU 1
| | |-- ...
| | `-- VOBU n
| |-- ...
| `-- Cell n
|-- ...
`-- Title m
|-- Chapter 1
| |-- Cell 1
| | |-- VOBU 1
| | |-- ...
| | `-- VOBU n
| |-- ...
| `-- Cell n
|-- ...
`-- Chapter 2
|-- Cell 1
| |-- VOBU 1
| |-- ...
| `-- VOBU n
|-- ...
`-- Cell n
\endverbatim
A DVD 'Title' is generally a logically distinct section of video. For example the main
feature film on a DVD might be Title 1, a behind-the-scenes documentary might be Title 2
and a selection of cast interviews might be Title 3. There can be up to 99 Titles on
any DVD.
A DVD 'Chapter' (somewhat confusingly referred to as a 'Part' in the parlence of
DVD authors) is generally a logical segment of a Title such as a scene in a film
or one interview in a set of cast interviews. There can be up to 999 Parts in
one Title.
A 'Cell' is a small segment of a Part. It is the smallest resolution at which
DVD navigation commands can act (e.g. 'Jump to Cell 3 of Part 4 of Title 2').
Typically one Part contains one Cell but on complex DVDs it may be useful to have
multiple Cells per Part.
A VOBU (<I>V</I>ideo <I>OB</I>ject <I>U</I>nit) is a small (typically a few
seconds) of video. It must be a self contained 'Group of Pictures' which
can be understood by the MPEG decoder. All seeking, jumping, etc is guaranteed
to occurr at a VOBU boundary so that the decoder need not be restarted and that
the location jumped to is always the start of a valid MPEG stream. For multiple-angle
DVDs VOBUs for each angle can be interleaved into one Interleaved Video Unit (ILVU).
In this case when the player get to the end of the VOBU for angle <i>n</i> instead of
jumping to the next VOBU the player will move forward to the VOBU for angle <i>n</i>
in the next ILVU.
This is summarised in the following diagram showing how the VOBUs are actually
laid out on disc.
\verbatim
,---------------------------. ,---------------------------.
| ILVU 1 | | ILVU m |
| ,--------. ,--------. | | ,--------. ,--------. |
| | VOBU 1 | ... | VOBU 1 | | ... | | VOBU m | ... | VOBU m | |
| |Angle 1 | |Angle n | | | |Angle 1 | |Angle n | |
| `--------' `--------' | | `--------' `--------' |
`---------------------------' `---------------------------'
\endverbatim
\subsection vm The DVD Virtual Machine
If the layout of the DVD were the only feature of the format the DVD
would only have a limited amount of interactivity, you could jump
around between Titles, Parts and Cells but not much else.
The feature most people associate with DVDs is its ability to
present the user with full-motion interactive menus. To provide
these features the DVD format includes a specification for a
DVD 'virtual machine'.
To a first order approximation x86 programs can only be run on
x86-based machines, PowerPC programs on PowerPC-based machines and so on.
Java, however, is an exception in that programs are compiled into
a special code which is designed for a 'Java Virtual Machine'.
Programmes exist which take this code and convert it into code which
can run on real processors.
Similarly the DVD virtual machine is a hypothetical processor
which has commands useful for DVD navigation (e.g. Jump to Title
4 or Jump to Cell 2) along with the ability to perform
simple arithmetic and save values in a number of special
variables (in processor speak, they are known as 'registers').
When a button is pressed on a DVD menu, a specified machine instruction
can be executed (e.g. to jump to a particular Title). Similarly
commands can be executed at the beginning and end of Cells and
Parts to, for example, return to the menu at the end of a film.
Return to the \ref tutorial.
*/
/*! \page firstprog A first libdvdnav program
\section compiling Compiling a libdvdnav program
Below is a simple <tt>libdvdnav</tt> program. Type/copy it and save it
into the file 'dvdtest.c'.
\verbatim
#include <stdio.h>
#include <dvdnav/dvdnav.h>
#include <dvdnav/dvdnav_events.h>
#include <sys/types.h>
int main(int argc, char **argv) {
dvdnav_t *dvdnav;
int finished, len, event;
uint8_t buf[2050];
/* Open the DVD */
dvdnav_open(&dvdnav, "/dev/dvd");
fprintf(stderr, "Reading...\n");
finished = 0;
while(!finished) {
int result = dvdnav_get_next_block(dvdnav, buf,
&event, &len);
if(result == DVDNAV_STATUS_ERR) {
fprintf(stderr, "Error getting next block (%s)\n",
dvdnav_err_to_string(dvdnav));
exit(1);
}
switch(event) {
case DVDNAV_BLOCK_OK:
/* Write output to stdout */
fwrite(buf, len, 1, stdout);
break;
case DVDNAV_STILL_FRAME:
{
fprintf(stderr, "Skipping still frame\n");
dvdnav_still_skip(dvdnav);
}
break;
case DVDNAV_STOP:
{
finished = 1;
}
default:
fprintf(stderr, "Unhandled event (%i)\n", event);
finished = 1;
break;
}
}
dvdnav_close(dvdnav);
return 0;
}
\endverbatim
If you have correctly installled <tt>libdvdnav</tt>, you should have the
command 'dvdnav-config' in your path. If so you can compile this program
with
\verbatim
gcc -o dvdtest dvdtest.c `dvdnav-config --cflags --libs`
\endverbatim
If all goes well, this should generate the 'dvdtest' program in your current working
directory. You can now start saving a MPEG 2 stream directly off your DVD
with
\verbatim
./dvdtest 2>error.log >out.mpeg
\endverbatim
If the command fails, check the error.log file for details.
\section walkthrorugh Line-by-line walk through
\verbatim
include <stdio.h>
include <dvdnav/dvdnav.h>
include <dvdnav/dvdnav_events.h>
include <sys/types.h>
\endverbatim
These lines include the necessary headers. Almost all <tt>libdvdnav</tt> programs
will only need to include the dvdnav.h and dvdnav_events.h header files from
the dvdnav directory.
\verbatim
dvdnav_open(&dvdnav, "/dev/dvd");
\endverbatim
The <tt>libdvdnav</tt> uses <tt>libdvdread</tt> for its DVD I/O. <tt>libdvdread</tt>
accesses the DVD-device directly so dvdnav_open() needs to be passed the location
of the DVD device. <tt>libdvdread</tt> can also open DVD images/mounted DVDs. Read
the <tt>libdvdread</tt> documentation for more information.
\verbatim
int result = dvdnav_get_next_block(dvdnav, buf,
&event, &len);
\endverbatim
Return to \ref tutorial.
*/

278
examples/menus.c Normal file
View File

@ -0,0 +1,278 @@
/*
* Copyright (C) 2003 by the libdvdnav project
*
* This file is part of libdvdnav, a DVD navigation library.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dvdnav/dvdnav.h>
/* shall we use libdvdnav's read ahead cache? */
#define DVD_READ_CACHE 1
/* which is the default language for menus/audio/subpictures? */
#define DVD_LANGUAGE "en"
#ifdef WIN32
#define S_IRWXG 0
#endif
int main(int argc, char **argv) {
dvdnav_t *dvdnav;
uint8_t mem[DVD_VIDEO_LB_LEN];
int finished = 0;
int output_fd = 0;
int dump = 0, tt_dump = 0;
if (argc < 2) {
printf("Specify DVD device.\n");
return 1;
}
/* open dvdnav handle */
printf("Opening DVD...\n");
if (dvdnav_open(&dvdnav, argv[1]) != DVDNAV_STATUS_OK) {
printf("Error on dvdnav_open\n");
return 1;
}
/* set read ahead cache usage */
if (dvdnav_set_readahead_flag(dvdnav, DVD_READ_CACHE) != DVDNAV_STATUS_OK) {
printf("Error on dvdnav_set_readahead_flag: %s\n", dvdnav_err_to_string(dvdnav));
return 2;
}
/* set the language */
if (dvdnav_menu_language_select(dvdnav, DVD_LANGUAGE) != DVDNAV_STATUS_OK ||
dvdnav_audio_language_select(dvdnav, DVD_LANGUAGE) != DVDNAV_STATUS_OK ||
dvdnav_spu_language_select(dvdnav, DVD_LANGUAGE) != DVDNAV_STATUS_OK) {
printf("Error on setting languages: %s\n", dvdnav_err_to_string(dvdnav));
return 2;
}
/* set the PGC positioning flag to have position information relatively to the
* whole feature instead of just relatively to the current chapter */
if (dvdnav_set_PGC_positioning_flag(dvdnav, 1) != DVDNAV_STATUS_OK) {
printf("Error on dvdnav_set_PGC_positioning_flag: %s\n", dvdnav_err_to_string(dvdnav));
return 2;
}
/* the read loop which regularly calls dvdnav_get_next_block
* and handles the returned events */
printf("Reading...\n");
while (!finished) {
int result, event, len;
uint8_t *buf = mem;
/* the main reading function */
#if DVD_READ_CACHE
result = dvdnav_get_next_cache_block(dvdnav, &buf, &event, &len);
#else
result = dvdnav_get_next_block(dvdnav, buf, &event, &len);
#endif
if (result == DVDNAV_STATUS_ERR) {
printf("Error getting next block: %s\n", dvdnav_err_to_string(dvdnav));
return 3;
}
switch (event) {
case DVDNAV_BLOCK_OK:
/* We have received a regular block of the currently playing MPEG stream.
* A real player application would now pass this block through demuxing
* and decoding. We simply write it to disc here. */
if (!output_fd) {
printf("Opening output...\n");
output_fd = open("libdvdnav.mpg", O_CREAT | O_WRONLY, S_IRWXU | S_IRWXG);
if (output_fd == -1) {
printf("Error opening output\n");
return 4;
}
}
if (dump || tt_dump)
write(output_fd, buf, len);
break;
case DVDNAV_NOP:
/* Nothing to do here. */
break;
case DVDNAV_STILL_FRAME:
/* We have reached a still frame. A real player application would wait
* the amount of time specified by the still's length while still handling
* user input to make menus and other interactive stills work.
* A length of 0xff means an indefinite still which has to be skipped
* indirectly by some user interaction. */
{
dvdnav_still_event_t *still_event = (dvdnav_still_event_t *)buf;
if (still_event->length < 0xff)
printf("Skipping %d seconds of still frame\n", still_event->length);
else
printf("Skipping indefinite length still frame\n");
dvdnav_still_skip(dvdnav);
}
break;
case DVDNAV_WAIT:
/* We have reached a point in DVD playback, where timing is critical.
* Player application with internal fifos can introduce state
* inconsistencies, because libdvdnav is always the fifo's length
* ahead in the stream compared to what the application sees.
* Such applications should wait until their fifos are empty
* when they receive this type of event. */
printf("Skipping wait condition\n");
dvdnav_wait_skip(dvdnav);
break;
case DVDNAV_SPU_CLUT_CHANGE:
/* Player applications should pass the new colour lookup table to their
* SPU decoder */
break;
case DVDNAV_SPU_STREAM_CHANGE:
/* Player applications should inform their SPU decoder to switch channels */
break;
case DVDNAV_AUDIO_STREAM_CHANGE:
/* Player applications should inform their audio decoder to switch channels */
break;
case DVDNAV_HIGHLIGHT:
/* Player applications should inform their overlay engine to highlight the
* given button */
{
dvdnav_highlight_event_t *highlight_event = (dvdnav_highlight_event_t *)buf;
printf("Selected button %d\n", highlight_event->buttonN);
}
break;
case DVDNAV_VTS_CHANGE:
/* Some status information like video aspect and video scale permissions do
* not change inside a VTS. Therefore this event can be used to query such
* information only when necessary and update the decoding/displaying
* accordingly. */
break;
case DVDNAV_CELL_CHANGE:
/* Some status information like the current Title and Part numbers do not
* change inside a cell. Therefore this event can be used to query such
* information only when necessary and update the decoding/displaying
* accordingly. */
{
int32_t tt = 0, ptt = 0;
uint32_t pos, len;
char input = '\0';
dvdnav_current_title_info(dvdnav, &tt, &ptt);
dvdnav_get_position(dvdnav, &pos, &len);
printf("Cell change: Title %d, Chapter %d\n", tt, ptt);
printf("At position %.0f%% inside the feature\n", 100 * (double)pos / (double)len);
dump = 0;
if (tt_dump && tt != tt_dump)
tt_dump = 0;
if (!dump && !tt_dump) {
fflush(stdin);
while ((input != 'a') && (input != 's') && (input != 'q') && (input != 't')) {
printf("(a)ppend cell to output\n(s)kip cell\nappend until end of (t)itle\n(q)uit\n");
scanf("%c", &input);
}
switch (input) {
case 'a':
dump = 1;
break;
case 't':
tt_dump = tt;
break;
case 'q':
finished = 1;
}
}
}
break;
case DVDNAV_NAV_PACKET:
/* A NAV packet provides PTS discontinuity information, angle linking information and
* button definitions for DVD menus. Angles are handled completely inside libdvdnav.
* For the menus to work, the NAV packet information has to be passed to the overlay
* engine of the player so that it knows the dimensions of the button areas. */
{
pci_t *pci;
/* Applications with fifos should not use these functions to retrieve NAV packets,
* they should implement their own NAV handling, because the packet you get from these
* functions will already be ahead in the stream which can cause state inconsistencies.
* Applications with fifos should therefore pass the NAV packet through the fifo
* and decoding pipeline just like any other data. */
pci = dvdnav_get_current_nav_pci(dvdnav);
dvdnav_get_current_nav_dsi(dvdnav);
if(pci->hli.hl_gi.btn_ns > 0) {
int button;
printf("Found %i DVD menu buttons...\n", pci->hli.hl_gi.btn_ns);
for (button = 0; button < pci->hli.hl_gi.btn_ns; button++) {
btni_t *btni = &(pci->hli.btnit[button]);
printf("Button %i top-left @ (%i,%i), bottom-right @ (%i,%i)\n",
button + 1, btni->x_start, btni->y_start,
btni->x_end, btni->y_end);
}
button = 0;
while ((button <= 0) || (button > pci->hli.hl_gi.btn_ns)) {
printf("Which button (1 to %i): ", pci->hli.hl_gi.btn_ns);
scanf("%i", &button);
}
printf("Selecting button %i...\n", button);
/* This is the point where applications with fifos have to hand in a NAV packet
* which has traveled through the fifos. See the notes above. */
dvdnav_button_select_and_activate(dvdnav, pci, button);
}
}
break;
case DVDNAV_HOP_CHANNEL:
/* This event is issued whenever a non-seamless operation has been executed.
* Applications with fifos should drop the fifos content to speed up responsiveness. */
break;
case DVDNAV_STOP:
/* Playback should end here. */
{
finished = 1;
}
break;
default:
printf("Unknown event (%i)\n", event);
finished = 1;
break;
}
#if DVD_READ_CACHE
dvdnav_free_cache_block(dvdnav, buf);
#endif
}
/* destroy dvdnav handle */
if (dvdnav_close(dvdnav) != DVDNAV_STATUS_OK) {
printf("Error on dvdnav_close: %s\n", dvdnav_err_to_string(dvdnav));
return 5;
}
close(output_fd);
return 0;
}

518
install-sh Executable file
View File

@ -0,0 +1,518 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2018-03-11.20; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
tab=' '
nl='
'
IFS=" $tab$nl"
# Set DOITPROG to "echo" to test this script.
doit=${DOITPROG-}
doit_exec=${doit:-exec}
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
is_target_a_directory=possibly
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t)
is_target_a_directory=always
dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) is_target_a_directory=never;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.
if test -n "$dir_arg"; then
if test -n "$dst_arg"; then
echo "$0: target directory not allowed when installing a directory." >&2
exit 1
fi
fi
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
if test $# -gt 1 || test "$is_target_a_directory" = always; then
if test ! -d "$dst_arg"; then
echo "$0: $dst_arg: Is not a directory." >&2
exit 1
fi
fi
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename.
if test -d "$dst"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dstbase=`basename "$src"`
case $dst in
*/) dst=$dst$dstbase;;
*) dst=$dst/$dstbase;;
esac
dstdir_status=0
else
dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi
fi
case $dstdir in
*/) dstdirslash=$dstdir;;
*) dstdirslash=$dstdir/;;
esac
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
# Note that $RANDOM variable is not portable (e.g. dash); Use it
# here however when possible just to lower collision chance.
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
# Because "mkdir -p" follows existing symlinks and we likely work
# directly in world-writeable /tmp, make sure that the '$tmpdir'
# directory is successfully created first before we actually test
# 'mkdir -p' feature.
if (umask $mkdir_umask &&
$mkdirprog $mkdir_mode "$tmpdir" &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
test_tmpdir="$tmpdir/a"
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
oIFS=$IFS
IFS=/
set -f
set fnord $dstdir
shift
set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=${dstdirslash}_inst.$$_
rmtmp=${dstdirslash}_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

11249
ltmain.sh Normal file

File diff suppressed because it is too large Load Diff

296
m4/attributes.m4 Normal file
View File

@ -0,0 +1,296 @@
dnl Macros to check the presence of generic (non-typed) symbols.
dnl Copyright (c) 2006-2007 Diego Pettenò <flameeyes@gmail.com>
dnl Copyright (c) 2006-2007 xine project
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2, or (at your option)
dnl any later version.
dnl
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
dnl 02110-1301, USA.
dnl
dnl As a special exception, the copyright owners of the
dnl macro gives unlimited permission to copy, distribute and modify the
dnl configure scripts that are the output of Autoconf when processing the
dnl Macro. You need not follow the terms of the GNU General Public
dnl License when using or distributing such scripts, even though portions
dnl of the text of the Macro appear in them. The GNU General Public
dnl License (GPL) does govern all other use of the material that
dnl constitutes the Autoconf Macro.
dnl
dnl This special exception to the GPL applies to versions of the
dnl Autoconf Macro released by this project. When you make and
dnl distribute a modified version of the Autoconf Macro, you may extend
dnl this special exception to the GPL to apply to your modified version as
dnl well.
dnl Check if the flag is supported by compiler
dnl CC_CHECK_CFLAGS_SILENT([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [
AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]),
[ac_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $1"
AC_LINK_IFELSE([AC_LANG_SOURCE([int main() { return 0; }])],
[eval "AS_TR_SH([cc_cv_cflags_$1])='yes'"],
[eval "AS_TR_SH([cc_cv_cflags_$1])='no'"])
CFLAGS="$ac_save_CFLAGS"
])
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
[$2], [$3])
])
dnl Check if the flag is supported by compiler (cacheable)
dnl CC_CHECK_CFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
AC_DEFUN([CC_CHECK_CFLAGS], [
AC_CACHE_CHECK([if $CC supports $1 flag],
AS_TR_SH([cc_cv_cflags_$1]),
CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here!
)
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
[$2], [$3])
])
dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found])
dnl Check for CFLAG and appends them to CFLAGS if supported
AC_DEFUN([CC_CHECK_CFLAG_APPEND], [
AC_CACHE_CHECK([if $CC supports $1 flag],
AS_TR_SH([cc_cv_cflags_$1]),
CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here!
)
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
[CFLAGS="$CFLAGS $1"; $2], [$3])
])
dnl CC_CHECK_CFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not])
AC_DEFUN([CC_CHECK_CFLAGS_APPEND], [
for flag in $1; do
CC_CHECK_CFLAG_APPEND($flag, [$2], [$3])
done
])
dnl Check if the flag is supported by linker (cacheable)
dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
AC_DEFUN([CC_CHECK_LDFLAGS], [
AC_CACHE_CHECK([if $CC supports $1 flag],
AS_TR_SH([cc_cv_ldflags_$1]),
[ac_save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS $1"
AC_LINK_IFELSE([AC_LANG_SOURCE([int main() { return 1; }])],
[eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"],
[eval "AS_TR_SH([cc_cv_ldflags_$1])="])
LDFLAGS="$ac_save_LDFLAGS"
])
AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes],
[$2], [$3])
])
dnl Check for a -Werror flag or equivalent. -Werror is the GCC
dnl and ICC flag that tells the compiler to treat all the warnings
dnl as fatal. We usually need this option to make sure that some
dnl constructs (like attributes) are not simply ignored.
dnl
dnl Other compilers don't support -Werror per se, but they support
dnl an equivalent flag:
dnl - Sun Studio compiler supports -errwarn=%all
AC_DEFUN([CC_CHECK_WERROR], [
AC_CACHE_CHECK(
[for $CC way to treat warnings as errors],
[cc_cv_werror],
[CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror],
[CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])])
])
])
AC_DEFUN([CC_CHECK_ATTRIBUTE], [
AC_REQUIRE([CC_CHECK_WERROR])
AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))],
AS_TR_SH([cc_cv_attribute_$1]),
[ac_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $cc_cv_werror"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])],
[eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"],
[eval "AS_TR_SH([cc_cv_attribute_$1])='no'"])
CFLAGS="$ac_save_CFLAGS"
])
AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes],
[AC_DEFINE(
AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1,
[Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))]
)
$4],
[$5])
])
AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [
CC_CHECK_ATTRIBUTE(
[constructor],,
[extern void foo();
void __attribute__((constructor)) ctor() { foo(); }],
[$1], [$2])
])
AC_DEFUN([CC_ATTRIBUTE_DESTRUCTOR], [
CC_CHECK_ATTRIBUTE(
[destructor],,
[extern void foo();
void __attribute__((destructor)) dtor() { foo(); }],
[$1], [$2])
])
AC_DEFUN([CC_ATTRIBUTE_FORMAT], [
CC_CHECK_ATTRIBUTE(
[format], [format(printf, n, n)],
[void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }],
[$1], [$2])
])
AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [
CC_CHECK_ATTRIBUTE(
[format_arg], [format_arg(printf)],
[char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }],
[$1], [$2])
])
AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [
CC_CHECK_ATTRIBUTE(
[visibility_$1], [visibility("$1")],
[void __attribute__((visibility("$1"))) $1_function() { }],
[$2], [$3])
])
AC_DEFUN([CC_ATTRIBUTE_NONNULL], [
CC_CHECK_ATTRIBUTE(
[nonnull], [nonnull()],
[void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }],
[$1], [$2])
])
AC_DEFUN([CC_ATTRIBUTE_UNUSED], [
CC_CHECK_ATTRIBUTE(
[unused], ,
[void some_function(void *foo, __attribute__((unused)) void *bar);],
[$1], [$2])
])
AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [
CC_CHECK_ATTRIBUTE(
[sentinel], ,
[void some_function(void *foo, ...) __attribute__((sentinel));],
[$1], [$2])
])
AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [
CC_CHECK_ATTRIBUTE(
[deprecated], ,
[void some_function(void *foo, ...) __attribute__((deprecated));],
[$1], [$2])
])
AC_DEFUN([CC_ATTRIBUTE_ALIAS], [
CC_CHECK_ATTRIBUTE(
[alias], [weak, alias],
[void other_function(void *foo) { }
void some_function(void *foo) __attribute__((weak, alias("other_function")));],
[$1], [$2])
])
AC_DEFUN([CC_ATTRIBUTE_MALLOC], [
CC_CHECK_ATTRIBUTE(
[malloc], ,
[void * __attribute__((malloc)) my_alloc(int n);],
[$1], [$2])
])
AC_DEFUN([CC_ATTRIBUTE_PACKED], [
CC_CHECK_ATTRIBUTE(
[packed], ,
[struct astructure { char a; int b; long c; void *d; } __attribute__((packed));
char assert@<:@(sizeof(struct astructure) == (sizeof(char)+sizeof(int)+sizeof(long)+sizeof(void*)))-1@:>@;],
[$1], [$2])
])
AC_DEFUN([CC_ATTRIBUTE_CONST], [
CC_CHECK_ATTRIBUTE(
[const], ,
[int __attribute__((const)) twopow(int n) { return 1 << n; } ],
[$1], [$2])
])
AC_DEFUN([CC_FLAG_VISIBILITY], [
AC_REQUIRE([CC_CHECK_WERROR])
AC_CACHE_CHECK([if $CC supports -fvisibility=hidden],
[cc_cv_flag_visibility],
[cc_flag_visibility_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $cc_cv_werror"
CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden],
cc_cv_flag_visibility='yes',
cc_cv_flag_visibility='no')
CFLAGS="$cc_flag_visibility_save_CFLAGS"])
AS_IF([test "x$cc_cv_flag_visibility" = "xyes"],
[AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1,
[Define this if the compiler supports the -fvisibility flag])
$1],
[$2])
])
AC_DEFUN([CC_FUNC_EXPECT], [
AC_REQUIRE([CC_CHECK_WERROR])
AC_CACHE_CHECK([if compiler has __builtin_expect function],
[cc_cv_func_expect],
[ac_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $cc_cv_werror"
AC_COMPILE_IFELSE(
[int some_function() {
int a = 3;
return (int)__builtin_expect(a, 3);
}],
[cc_cv_func_expect=yes],
[cc_cv_func_expect=no])
CFLAGS="$ac_save_CFLAGS"
])
AS_IF([test "x$cc_cv_func_expect" = "xyes"],
[AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1,
[Define this if the compiler supports __builtin_expect() function])
$1],
[$2])
])
AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [
AC_REQUIRE([CC_CHECK_WERROR])
AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported],
[cc_cv_attribute_aligned],
[ac_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $cc_cv_werror"
for cc_attribute_align_try in 64 32 16 8 4 2; do
AC_COMPILE_IFELSE([
int main() {
static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0;
return c;
}], [cc_cv_attribute_aligned=$cc_attribute_align_try; break])
done
CFLAGS="$ac_save_CFLAGS"
])
if test "x$cc_cv_attribute_aligned" != "x"; then
AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned],
[Define the highest alignment supported])
fi
])

8394
m4/libtool.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

437
m4/ltoptions.m4 vendored Normal file
View File

@ -0,0 +1,437 @@
# Helper functions for option handling. -*- Autoconf -*-
#
# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
# Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 8 ltoptions.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
# ------------------------------------------
m4_define([_LT_MANGLE_OPTION],
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
# ---------------------------------------
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
# saved as a flag.
m4_define([_LT_SET_OPTION],
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
_LT_MANGLE_DEFUN([$1], [$2]),
[m4_warning([Unknown $1 option '$2'])])[]dnl
])
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
# ------------------------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
m4_define([_LT_IF_OPTION],
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
# -------------------------------------------------------
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
# are set.
m4_define([_LT_UNLESS_OPTIONS],
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
[m4_define([$0_found])])])[]dnl
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
])[]dnl
])
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
# ----------------------------------------
# OPTION-LIST is a space-separated list of Libtool options associated
# with MACRO-NAME. If any OPTION has a matching handler declared with
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
# the unknown option and exit.
m4_defun([_LT_SET_OPTIONS],
[# Set options
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[_LT_SET_OPTION([$1], _LT_Option)])
m4_if([$1],[LT_INIT],[
dnl
dnl Simply set some default values (i.e off) if boolean options were not
dnl specified:
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
])
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
])
dnl
dnl If no reference was made to various pairs of opposing options, then
dnl we run the default mode handler for the pair. For example, if neither
dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
dnl archives by default:
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
[_LT_ENABLE_FAST_INSTALL])
_LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
[_LT_WITH_AIX_SONAME([aix])])
])
])# _LT_SET_OPTIONS
## --------------------------------- ##
## Macros to handle LT_INIT options. ##
## --------------------------------- ##
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
# -----------------------------------------
m4_define([_LT_MANGLE_DEFUN],
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
# -----------------------------------------------
m4_define([LT_OPTION_DEFINE],
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
])# LT_OPTION_DEFINE
# dlopen
# ------
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
])
AU_DEFUN([AC_LIBTOOL_DLOPEN],
[_LT_SET_OPTION([LT_INIT], [dlopen])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'dlopen' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
# win32-dll
# ---------
# Declare package support for building win32 dll's.
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
[enable_win32_dll=yes
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
;;
esac
test -z "$AS" && AS=as
_LT_DECL([], [AS], [1], [Assembler program])dnl
test -z "$DLLTOOL" && DLLTOOL=dlltool
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
test -z "$OBJDUMP" && OBJDUMP=objdump
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
])# win32-dll
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
_LT_SET_OPTION([LT_INIT], [win32-dll])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'win32-dll' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
# _LT_ENABLE_SHARED([DEFAULT])
# ----------------------------
# implement the --enable-shared flag, and supports the 'shared' and
# 'disable-shared' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_SHARED],
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([shared],
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_shared=yes ;;
no) enable_shared=no ;;
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
_LT_DECL([build_libtool_libs], [enable_shared], [0],
[Whether or not to build shared libraries])
])# _LT_ENABLE_SHARED
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
# Old names:
AC_DEFUN([AC_ENABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
])
AC_DEFUN([AC_DISABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], [disable-shared])
])
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
# _LT_ENABLE_STATIC([DEFAULT])
# ----------------------------
# implement the --enable-static flag, and support the 'static' and
# 'disable-static' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_STATIC],
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([static],
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_static=yes ;;
no) enable_static=no ;;
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
_LT_DECL([build_old_libs], [enable_static], [0],
[Whether or not to build static libraries])
])# _LT_ENABLE_STATIC
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
# Old names:
AC_DEFUN([AC_ENABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
])
AC_DEFUN([AC_DISABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], [disable-static])
])
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
# ----------------------------------
# implement the --enable-fast-install flag, and support the 'fast-install'
# and 'disable-fast-install' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_FAST_INSTALL],
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([fast-install],
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_fast_install=yes ;;
no) enable_fast_install=no ;;
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
_LT_DECL([fast_install], [enable_fast_install], [0],
[Whether or not to optimize for fast installation])dnl
])# _LT_ENABLE_FAST_INSTALL
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
# Old names:
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the 'fast-install' option into LT_INIT's first parameter.])
])
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the 'disable-fast-install' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
# _LT_WITH_AIX_SONAME([DEFAULT])
# ----------------------------------
# implement the --with-aix-soname flag, and support the `aix-soname=aix'
# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'.
m4_define([_LT_WITH_AIX_SONAME],
[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
shared_archive_member_spec=
case $host,$enable_shared in
power*-*-aix[[5-9]]*,yes)
AC_MSG_CHECKING([which variant of shared library versioning to provide])
AC_ARG_WITH([aix-soname],
[AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
[shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
[case $withval in
aix|svr4|both)
;;
*)
AC_MSG_ERROR([Unknown argument to --with-aix-soname])
;;
esac
lt_cv_with_aix_soname=$with_aix_soname],
[AC_CACHE_VAL([lt_cv_with_aix_soname],
[lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
with_aix_soname=$lt_cv_with_aix_soname])
AC_MSG_RESULT([$with_aix_soname])
if test aix != "$with_aix_soname"; then
# For the AIX way of multilib, we name the shared archive member
# based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
# and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
# Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
# the AIX toolchain works better with OBJECT_MODE set (default 32).
if test 64 = "${OBJECT_MODE-32}"; then
shared_archive_member_spec=shr_64
else
shared_archive_member_spec=shr
fi
fi
;;
*)
with_aix_soname=aix
;;
esac
_LT_DECL([], [shared_archive_member_spec], [0],
[Shared archive member basename, for filename based shared library versioning on AIX])dnl
])# _LT_WITH_AIX_SONAME
LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
# _LT_WITH_PIC([MODE])
# --------------------
# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
# LT_INIT options.
# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'.
m4_define([_LT_WITH_PIC],
[AC_ARG_WITH([pic],
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
[lt_p=${PACKAGE-default}
case $withval in
yes|no) pic_mode=$withval ;;
*)
pic_mode=default
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for lt_pkg in $withval; do
IFS=$lt_save_ifs
if test "X$lt_pkg" = "X$lt_p"; then
pic_mode=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[pic_mode=m4_default([$1], [default])])
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
])# _LT_WITH_PIC
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
# Old name:
AU_DEFUN([AC_LIBTOOL_PICMODE],
[_LT_SET_OPTION([LT_INIT], [pic-only])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'pic-only' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
## ----------------- ##
## LTDL_INIT Options ##
## ----------------- ##
m4_define([_LTDL_MODE], [])
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
[m4_define([_LTDL_MODE], [nonrecursive])])
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
[m4_define([_LTDL_MODE], [recursive])])
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
[m4_define([_LTDL_MODE], [subproject])])
m4_define([_LTDL_TYPE], [])
LT_OPTION_DEFINE([LTDL_INIT], [installable],
[m4_define([_LTDL_TYPE], [installable])])
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
[m4_define([_LTDL_TYPE], [convenience])])

124
m4/ltsugar.m4 vendored Normal file
View File

@ -0,0 +1,124 @@
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
# Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 6 ltsugar.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
# lt_join(SEP, ARG1, [ARG2...])
# -----------------------------
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
# associated separator.
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
# versions in m4sugar had bugs.
m4_define([lt_join],
[m4_if([$#], [1], [],
[$#], [2], [[$2]],
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
m4_define([_lt_join],
[m4_if([$#$2], [2], [],
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
# lt_car(LIST)
# lt_cdr(LIST)
# ------------
# Manipulate m4 lists.
# These macros are necessary as long as will still need to support
# Autoconf-2.59, which quotes differently.
m4_define([lt_car], [[$1]])
m4_define([lt_cdr],
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
[$#], 1, [],
[m4_dquote(m4_shift($@))])])
m4_define([lt_unquote], $1)
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
# ------------------------------------------
# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
# Note that neither SEPARATOR nor STRING are expanded; they are appended
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
# than defined and empty).
#
# This macro is needed until we can rely on Autoconf 2.62, since earlier
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
m4_define([lt_append],
[m4_define([$1],
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
# ----------------------------------------------------------
# Produce a SEP delimited list of all paired combinations of elements of
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
# has the form PREFIXmINFIXSUFFIXn.
# Needed until we can rely on m4_combine added in Autoconf 2.62.
m4_define([lt_combine],
[m4_if(m4_eval([$# > 3]), [1],
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
[[m4_foreach([_Lt_prefix], [$2],
[m4_foreach([_Lt_suffix],
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
# -----------------------------------------------------------------------
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
m4_define([lt_if_append_uniq],
[m4_ifdef([$1],
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
[lt_append([$1], [$2], [$3])$4],
[$5])],
[lt_append([$1], [$2], [$3])$4])])
# lt_dict_add(DICT, KEY, VALUE)
# -----------------------------
m4_define([lt_dict_add],
[m4_define([$1($2)], [$3])])
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
# --------------------------------------------
m4_define([lt_dict_add_subkey],
[m4_define([$1($2:$3)], [$4])])
# lt_dict_fetch(DICT, KEY, [SUBKEY])
# ----------------------------------
m4_define([lt_dict_fetch],
[m4_ifval([$3],
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
# -----------------------------------------------------------------
m4_define([lt_if_dict_fetch],
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
[$5],
[$6])])
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
# --------------------------------------------------------------
m4_define([lt_dict_filter],
[m4_if([$5], [], [],
[lt_join(m4_quote(m4_default([$4], [[, ]])),
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
])

23
m4/ltversion.m4 vendored Normal file
View File

@ -0,0 +1,23 @@
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# @configure_input@
# serial 4179 ltversion.m4
# This file is part of GNU Libtool
m4_define([LT_PACKAGE_VERSION], [2.4.6])
m4_define([LT_PACKAGE_REVISION], [2.4.6])
AC_DEFUN([LTVERSION_VERSION],
[macro_version='2.4.6'
macro_revision='2.4.6'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])

99
m4/lt~obsolete.m4 vendored Normal file
View File

@ -0,0 +1,99 @@
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
# Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 5 lt~obsolete.m4
# These exist entirely to fool aclocal when bootstrapping libtool.
#
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
# which have later been changed to m4_define as they aren't part of the
# exported API, or moved to Autoconf or Automake where they belong.
#
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
# using a macro with the same name in our local m4/libtool.m4 it'll
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
# and doesn't know about Autoconf macros at all.)
#
# So we provide this file, which has a silly filename so it's always
# included after everything else. This provides aclocal with the
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
# because those macros already exist, or will be overwritten later.
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
#
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
# Yes, that means every name once taken will need to remain here until
# we give up compatibility with versions before 1.7, at which point
# we need to keep only those names which we still refer to.
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])

12
misc/dvdnav.pc.in Normal file
View File

@ -0,0 +1,12 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libdvdnav
Description: DVD Navigation library
Version: @VERSION@
Requires.private: dvdread >= 4.1.2
Cflags: -I${includedir} @THREAD_CFLAGS@
Libs: -L${libdir} -ldvdnav @THREAD_LIBS@

50
misc/libdvdnav.spec.in Normal file
View File

@ -0,0 +1,50 @@
%define prefix @prefix@
%define name @PACKAGE_NAME@
%define ver @PACKAGE_VERSION@
%define rel 0
Name: %{name}
Summary: DVD Navigation library
Version: %{ver}
Release: %{rel}
Group: Development/Libraries
Copyright: GPL
Url: http://dvd.sourceforge.net/
Source: %{name}-%{version}.tar.gz
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root
%description
libdvdnav provides support to applications wishing to make use of advanced
DVD navigation features.
%prep
%setup
%build
CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix}
make
%install
rm -rf $RPM_BUILD_ROOT
make install-strip DESTDIR=$RPM_BUILD_ROOT
%clean
rm -r $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%doc AUTHORS ChangeLog COPYING INSTALL README
%{prefix}/bin/dvdnav-config
%{prefix}/lib/libdvdnav*.la
%{prefix}/lib/libdvdnav*.so.*
%{prefix}/lib/libdvdnav*.so
%{prefix}/include/dvdnav/*
@INSTALL_M4_TRUE@@ACLOCAL_DIR@/dvdnav.m4
%changelog
* Sun Mar 18 2002 Daniel Caujolle-Bert <f1rmb@users.sourceforge.net>
- Add missing files. Fix rpm generation.
* Tue Mar 12 2002 Rich Wareham <richwareham@users.sourceforge.net>
- Canabalisation to form libdvdnav spec file.
* Sun Sep 09 2001 Thomas Vander Stichele <thomas@apestaart.org>
- first spec file

215
missing Executable file
View File

@ -0,0 +1,215 @@
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# 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, 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, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try '$0 --help' for more information"
exit 1
fi
case $1 in
--is-lightweight)
# Used by our autoconf macros to check whether the available missing
# script is modern enough.
exit 0
;;
--run)
# Back-compat with the calling convention used by older automake.
shift
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
to PROGRAM being missing or too old.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
Supported PROGRAM values:
aclocal autoconf autoheader autom4te automake makeinfo
bison yacc flex lex help2man
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
'g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: unknown '$1' option"
echo 1>&2 "Try '$0 --help' for more information"
exit 1
;;
esac
# Run the given program, remember its exit status.
"$@"; st=$?
# If it succeeded, we are done.
test $st -eq 0 && exit 0
# Also exit now if we it failed (or wasn't found), and '--version' was
# passed; such an option is passed most likely to detect whether the
# program is present and works.
case $2 in --version|--help) exit $st;; esac
# Exit code 63 means version mismatch. This often happens when the user
# tries to use an ancient version of a tool on a file that requires a
# minimum version.
if test $st -eq 63; then
msg="probably too old"
elif test $st -eq 127; then
# Program was missing.
msg="missing on your system"
else
# Program was found and executed, but failed. Give up.
exit $st
fi
perl_URL=https://www.perl.org/
flex_URL=https://github.com/westes/flex
gnu_software_URL=https://www.gnu.org/software
program_details ()
{
case $1 in
aclocal|automake)
echo "The '$1' program is part of the GNU Automake package:"
echo "<$gnu_software_URL/automake>"
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/autoconf>"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
autoconf|autom4te|autoheader)
echo "The '$1' program is part of the GNU Autoconf package:"
echo "<$gnu_software_URL/autoconf/>"
echo "It also requires GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
esac
}
give_advice ()
{
# Normalize program name to check for.
normalized_program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
printf '%s\n' "'$1' is $msg."
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
case $normalized_program in
autoconf*)
echo "You should only need it if you modified 'configure.ac',"
echo "or m4 files included by it."
program_details 'autoconf'
;;
autoheader*)
echo "You should only need it if you modified 'acconfig.h' or"
echo "$configure_deps."
program_details 'autoheader'
;;
automake*)
echo "You should only need it if you modified 'Makefile.am' or"
echo "$configure_deps."
program_details 'automake'
;;
aclocal*)
echo "You should only need it if you modified 'acinclude.m4' or"
echo "$configure_deps."
program_details 'aclocal'
;;
autom4te*)
echo "You might have modified some maintainer files that require"
echo "the 'autom4te' program to be rebuilt."
program_details 'autom4te'
;;
bison*|yacc*)
echo "You should only need it if you modified a '.y' file."
echo "You may want to install the GNU Bison package:"
echo "<$gnu_software_URL/bison/>"
;;
lex*|flex*)
echo "You should only need it if you modified a '.l' file."
echo "You may want to install the Fast Lexical Analyzer package:"
echo "<$flex_URL>"
;;
help2man*)
echo "You should only need it if you modified a dependency" \
"of a man page."
echo "You may want to install the GNU Help2man package:"
echo "<$gnu_software_URL/help2man/>"
;;
makeinfo*)
echo "You should only need it if you modified a '.texi' file, or"
echo "any other file indirectly affecting the aspect of the manual."
echo "You might want to install the Texinfo package:"
echo "<$gnu_software_URL/texinfo/>"
echo "The spurious makeinfo call might also be the consequence of"
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
echo "want to install GNU make:"
echo "<$gnu_software_URL/make/>"
;;
*)
echo "You might have modified some files without having the proper"
echo "tools for further handling them. Check the 'README' file, it"
echo "often tells you about the needed prerequisites for installing"
echo "this package. You may also peek at any GNU archive site, in"
echo "case some other package contains this missing '$1' program."
;;
esac
}
give_advice "$1" | sed -e '1s/^/WARNING: /' \
-e '2,$s/^/ /' >&2
# Propagate the correct exit status (expected to be 127 for a program
# not found, 63 for a program that failed due to version mismatch).
exit $st
# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

56
msvc/msvc/config.h Normal file
View File

@ -0,0 +1,56 @@
/* config.h. Generated by hand. */
#ifndef LIBDVNAV_CONFIG_H
#define LIBDVNAV_CONFIG_H
#define HAVE_DLFCN_H 1
/* #undef HAVE_DVDCSS_DVDCSS_H*/
/* #undef HAVE_INTTYPES_H */
#define HAVE_MEMORY_H 1
/* #undef HAVE_STDINT_H */
#define HAVE_STDLIB_H 1
#define HAVE_STRINGS_H 1
#define HAVE_STRING_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_SYS_TYPES_H 1
/* #undef HAVE_UNISTD_H */
#define PACKAGE "libdvdread"
#define PACKAGE_BUGREPORT ""
#define PACKAGE_NAME ""
#define PACKAGE_STRING ""
#define PACKAGE_TARNAME ""
#define PACKAGE_VERSION ""
#define STDC_HEADERS 1
#define VERSION "1.2.6"
/* #undef WORDS_BIGENDIAN */
/* #undef __DARWIN__ */
/* #undef const */
#define inline __inline
/* #undef size_t */
#define ssize_t __int64
#ifndef PATH_MAX
#define PATH_MAX MAX_PATH
#endif
#define strcasecmp stricmp
#define strncasecmp strnicmp
#define S_ISDIR(m) ((m) & _S_IFDIR)
#define S_ISREG(m) ((m) & _S_IFREG)
#define S_ISBLK(m) 0
#define S_ISCHR(m) 0
/* Fallback types (very x86-centric, sorry) */
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef unsigned int uint32_t;
typedef signed int int32_t;
typedef unsigned __int64 uint64_t;
typedef signed __int64 int64_t;
typedef unsigned int uintptr_t;
#endif /* LIBDVNAV_CONFIG_H */

View File

@ -0,0 +1,8 @@
#include <string.h>
void bcopy(const void *IN, void *OUT, size_t N);
void bcopy(const void *IN, void *OUT, size_t N)
{
memcpy(OUT, IN, N);
}

View File

@ -0,0 +1,135 @@
/*
Implementation of POSIX directory browsing functions and types for Win32.
Kevlin Henney (mailto:kevlin@acm.org), March 1997.
Copyright Kevlin Henney, 1997. All rights reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose is hereby granted without fee, provided
that this copyright and permissions notice appear in all copies and
derivatives, and that no charge may be made for the software and its
documentation except to cover cost of distribution.
This software is supplied "as is" without express or implied warranty.
But that said, if there are any problems please get in touch.
*/
#include <dirent.h>
#include <errno.h>
#include <io.h>
#include <stdlib.h>
#include <string.h>
#ifndef DIR
struct DIR
{
long handle; /* -1 for failed rewind */
struct _finddata_t info;
struct dirent result; /* d_name null iff first time */
char *name; /* NTBS */
};
#endif
DIR *opendir(const char *name)
{
DIR *dir = 0;
if(name && name[0])
{
size_t base_length = strlen(name);
const char *all = /* the root directory is a special case... */
strchr("/\\", name[base_length - 1]) ? "*" : "/*";
if((dir = (DIR *) malloc(sizeof *dir)) != 0 &&
(dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0)
{
strcat(strcpy(dir->name, name), all);
if((dir->handle = _findfirst(dir->name, &dir->info)) != -1)
{
dir->result.d_name = 0;
}
else /* rollback */
{
free(dir->name);
free(dir);
dir = 0;
}
}
else /* rollback */
{
free(dir);
dir = 0;
errno = ENOMEM;
}
}
else
{
errno = EINVAL;
}
return dir;
}
int closedir(DIR *dir)
{
int result = -1;
if(dir)
{
if(dir->handle != -1)
{
result = _findclose(dir->handle);
}
free(dir->name);
free(dir);
}
if(result == -1) /* map all errors to EBADF */
{
errno = EBADF;
}
return result;
}
struct dirent *readdir(DIR *dir)
{
struct dirent *result = 0;
if(dir && dir->handle != -1)
{
if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1)
{
result = &dir->result;
result->d_name = dir->info.name;
}
}
else
{
errno = EBADF;
}
return result;
}
void rewinddir(DIR *dir)
{
if(dir && dir->handle != -1)
{
_findclose(dir->handle);
dir->handle = _findfirst(dir->name, &dir->info);
dir->result.d_name = 0;
}
else
{
errno = EBADF;
}
}

View File

@ -0,0 +1,32 @@
/*
Declaration of POSIX directory browsing functions and types for Win32.
Kevlin Henney (mailto:kevlin@acm.org), March 1997.
Copyright Kevlin Henney, 1997. All rights reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose is hereby granted without fee, provided
that this copyright and permissions notice appear in all copies and
derivatives, and that no charge may be made for the software and its
documentation except to cover cost of distribution.
*/
#ifndef DIRENT_INCLUDED
#define DIRENT_INCLUDED
typedef struct DIR DIR;
struct dirent
{
char *d_name;
};
DIR *opendir(const char *);
int closedir(DIR *);
struct dirent *readdir(DIR *);
void rewinddir(DIR *);
#endif

94
msvc/msvc/contrib/dlfcn.c Normal file
View File

@ -0,0 +1,94 @@
/*
* Adopted from Apache DSO code.
* Portions copyright Apache Software Foundation
*
* Structures and types used to implement dlopen, dlsym, etc.
* on Windows 95/NT.
*/
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include "dlfcn.h"
#include "os_types.h"
void *dlopen(const char *module_name, int mode)
{
UINT em;
HINSTANCE dsoh;
char path[MAX_PATH], *p;
/* Load the module...
* per PR2555, the LoadLibraryEx function is very picky about slashes.
* Debugging on NT 4 SP 6a reveals First Chance Exception within NTDLL.
* LoadLibrary in the MS PSDK also reveals that it -explicitly- states
* that backslashes must be used.
*
* Transpose '\' for '/' in the filename.
*/
(void)strncpy(path, module_name, MAX_PATH);
p = path;
while (p = strchr(p, '/'))
*p = '\\';
/* First assume the dso/dll's required by -this- dso are sitting in the
* same path or can be found in the usual places. Failing that, let's
* let that dso look in the apache root.
*/
em = SetErrorMode(SEM_FAILCRITICALERRORS);
dsoh = LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if (!dsoh)
{
SetLastError(0); // clear the last error
dsoh = LoadLibraryEx(path, NULL, 0);
}
SetErrorMode(em);
SetLastError(0); // clear the last error
return (void *)dsoh;
}
char *dlerror(void)
{
int len, nErrorCode;
static char errstr[120];
/* This is -not- threadsafe code, but it's about the best we can do.
* mostly a potential problem for isapi modules, since LoadModule
* errors are handled within a single config thread.
*/
if((nErrorCode = GetLastError()) == 0)
return((char *)0);
SetLastError(0); // clear the last error
len = snprintf(errstr, sizeof(errstr), "(%d) ", nErrorCode);
len += FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
nErrorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
(LPTSTR) errstr + len,
sizeof(errstr) - len,
NULL
);
/* FormatMessage may have appended a newline (\r\n). So remove it
* and use ": " instead like the Unix errors. The error may also
* end with a . before the return - if so, trash it.
*/
if (len > 1 && errstr[len-2] == '\r' && errstr[len-1] == '\n') {
if (len > 2 && errstr[len-3] == '.')
len--;
errstr[len-2] = ':';
errstr[len-1] = ' ';
}
return errstr;
}
int dlclose(void *handle)
{
return FreeLibrary(handle);
}
void *dlsym(void *handle, const char *name)
{
return GetProcAddress(handle, name);
}

1009
msvc/msvc/contrib/getopt.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,102 @@
/*
* Copyright (C) 2000-2001 the xine project
*
* This file is part of xine, a unix video player.
*
* xine 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.
*
* xine 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* WIN32 PORT,
* by Matthew Grooms <elon@altavista.com>
*
* timer.c - Missing unix timer functions
*
*/
#include "stdio.h"
#include "timer.h"
/*
this function returns somewhat
accurate unix time with the data
accurate to the first call to get
of day and the resolution accurate
to ~ miliseconds.
*/
static time_t startseconds = 0;
int gettimeofday( struct timeval *tp, struct timezone *tzp )
{
MMTIME mmtime;
// clock() returns time in miliseconds
if( !startseconds )
startseconds = time( 0 );
timeGetSystemTime( &mmtime, sizeof( mmtime ) );
tp->tv_sec = ( mmtime.u.ms / 1000 ) + startseconds;
tp->tv_usec = ( mmtime.u.ms % 1000 ) * 1000;
return 0;
};
/*
These functions are designed to mimick
a subset of itimer for use with the
alarm signal on win32. This is just
enough for xine to work.
*/
static HANDLE sigalarm = 0;
int setitimer( int which, struct itimerval * value, struct itimerval *ovalue )
{
long int miliseconds;
if( !sigalarm )
sigalarm = CreateEvent( 0, FALSE, TRUE, "SIGALARM" );
miliseconds = value->it_value.tv_usec / 1000;
timeSetEvent( miliseconds, 0, ( LPTIMECALLBACK ) sigalarm, 0, TIME_PERIODIC | TIME_CALLBACK_EVENT_PULSE );
return 0;
}
/*
Wait for sigalarm to wake the thread
*/
int pause( void )
{
WaitForSingleObject( sigalarm, INFINITE );
return 0;
}
int nanosleep( const struct timespec * rqtp, struct timespec * rmtp )
{
Sleep( rqtp->tv_nsec / 1000000 );
return 0;
}
unsigned int sleep( unsigned int seconds )
{
Sleep( seconds * 1000 );
return 0;
}

View File

@ -0,0 +1,39 @@
#include <time.h>
#include <winsock.h>
#include "pthread.h"
#ifndef _ITIMER_
#define _ITIMER_
#define ITIMER_REAL 0
#define ITIMER_VIRTUAL 1
// time reference
// ----------------------------------
//
// 1,000 milliseconds / sec
// 1,000,000 microseconds / sec
// 1,000,000,000 nanoseconds / sec
//
// timeval.time_sec = seconds
// timeval.time_usec = microseconds
struct itimerval
{
struct timeval it_interval; /* timer interval */
struct timeval it_value; /* current value */
};
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of dst correction */
};
int gettimeofday( struct timeval *tp, struct timezone *tzp );
int setitimer( int which, struct itimerval * value, struct itimerval *ovalue );
int pause( void );
unsigned int sleep( unsigned int seconds );
int nanosleep( const struct timespec *rqtp, struct timespec *rmtp );
#endif

110
msvc/msvc/ifo_dump.dsp Normal file
View File

@ -0,0 +1,110 @@
# Microsoft Developer Studio Project File - Name="ifo_dump" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=ifo_dump - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ifo_dump.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ifo_dump.mak" CFG="ifo_dump - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ifo_dump - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "ifo_dump - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "ifo_dump - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "ifo_dump - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "ifo_dump___Win32_Debug"
# PROP BASE Intermediate_Dir "ifo_dump___Win32_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug\ifo_dump"
# PROP Intermediate_Dir "Debug\ifo_dump"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "include" /I "." /I "include/pthreads" /I "install/include" /I ".." /I "../src" /I "contrib/timer" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "DVDNAV_COMPILE" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/bin/ifo_dump.exe" /pdbtype:sept
# SUBTRACT LINK32 /pdb:none
!ENDIF
# Begin Target
# Name "ifo_dump - Win32 Release"
# Name "ifo_dump - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\src\ifo_dump.c
# End Source File
# Begin Source File
SOURCE=..\src\ifo_print.c
# End Source File
# Begin Source File
SOURCE=..\src\vmcmd.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

18
msvc/msvc/include/dlfcn.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef __DLFCN_H__
# define __DLFCN_H__
extern void *dlopen (const char *file, int mode);
extern int dlclose (void *handle);
extern void *dlsym (void * handle, const char * name);
extern char *dlerror (void);
/* These don't mean anything on windows */
#define RTLD_NEXT ((void *) -1l)
#define RTLD_DEFAULT ((void *) 0)
#define RTLD_LAZY -1
#define RTLD_NOW -1
#define RTLD_BINDING_MASK -1
#define RTLD_NOLOAD -1
#define RTLD_GLOBAL -1
#endif /* __DLFCN_H__ */

View File

@ -0,0 +1,182 @@
/* !! DO NO EDIT THIS FILE, it is automatically generated */
/*
* Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net>
*
* This file is part of libdvdnav, a DVD navigation library.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef LIBDVDNAV_DVDNAV_INTERNAL_H
#define LIBDVDNAV_DVDNAV_INTERNAL_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include <string.h>
#include <pthread.h>
#undef WORDS_BIGENDIAN
#include "dvd_reader.h"
#include "ifo_read.h"
#include "ifo_types.h"
/* Uncomment for VM command tracing */
/* #define TRACE */
#include "decoder.h"
#include "dvdnav.h"
#include "vm.h"
#include "vmcmd.h"
/* where should libdvdnav write its messages (stdout/stderr) */
#define MSG_OUT stdout
/* Maximum length of an error string */
#define MAX_ERR_LEN 255
/* Use the POSIX PATH_MAX if available */
#ifdef PATH_MAX
#define MAX_PATH_LEN PATH_MAX
#else
#define MAX_PATH_LEN 255 /* Arbitrary */
#endif
#ifndef DVD_VIDEO_LB_LEN
#define DVD_VIDEO_LB_LEN 2048
#endif
typedef struct read_cache_s read_cache_t;
/*
* These are defined here because they are
* not in ifo_types.h, they maybe one day
*/
#ifndef audio_status_t
typedef struct {
#ifdef WORDS_BIGENDIAN
unsigned int available : 1;
unsigned int zero1 : 4;
unsigned int stream_number : 3;
uint8_t zero2;
#else
uint8_t zero2;
unsigned int stream_number : 3;
unsigned int zero1 : 4;
unsigned int available : 1;
#endif
} ATTRIBUTE_PACKED audio_status_t;
#endif
#ifndef spu_status_t
typedef struct {
#ifdef WORDS_BIGENDIAN
unsigned int available : 1;
unsigned int zero1 : 2;
unsigned int stream_number_4_3 : 5;
unsigned int zero2 : 3;
unsigned int stream_number_wide : 5;
unsigned int zero3 : 3;
unsigned int stream_number_letterbox : 5;
unsigned int zero4 : 3;
unsigned int stream_number_pan_scan : 5;
#else
unsigned int stream_number_pan_scan : 5;
unsigned int zero4 : 3;
unsigned int stream_number_letterbox : 5;
unsigned int zero3 : 3;
unsigned int stream_number_wide : 5;
unsigned int zero2 : 3;
unsigned int stream_number_4_3 : 5;
unsigned int zero1 : 2;
unsigned int available : 1;
#endif
} ATTRIBUTE_PACKED spu_status_t;
#endif
typedef struct dvdnav_vobu_s {
int32_t vobu_start; /* Logical Absolute. MAX needed is 0x300000 */
int32_t vobu_length;
int32_t blockN; /* Relative offset */
int32_t vobu_next; /* Relative offset */
} dvdnav_vobu_t;
/** The main DVDNAV type **/
struct dvdnav_s {
/* General data */
char path[MAX_PATH_LEN]; /* Path to DVD device/dir */
dvd_file_t *file; /* Currently opened file */
int open_vtsN; /* The domain and number of the... */
int open_domain; /* ..currently opened VOB */
/* Position data */
vm_position_t position_next;
vm_position_t position_current;
dvdnav_vobu_t vobu;
/* NAV data */
pci_t pci;
dsi_t dsi;
uint32_t last_cmd_nav_lbn; /* detects when a command is issued on an already left NAV */
/* Flags */
int skip_still; /* Set when skipping a still */
int sync_wait; /* applications should wait till they are in sync with us */
int sync_wait_skip; /* Set when skipping wait state */
int spu_clut_changed; /* The SPU CLUT changed */
int started; /* vm_start has been called? */
int use_read_ahead; /* 1 - use read-ahead cache, 0 - don't */
int pgc_based; /* positioning works PGC based instead of PG based */
/* VM */
vm_t *vm;
pthread_mutex_t vm_lock;
/* Read-ahead cache */
read_cache_t *cache;
/* Errors */
char err_str[MAX_ERR_LEN];
};
/** USEFUL MACROS **/
#ifdef __GNUC__
#define printerrf(format, args...) snprintf(this->err_str, MAX_ERR_LEN, format, ## args);
#else
#ifdef _MSC_VER
#define printerrf(str) snprintf(this->err_str, MAX_ERR_LEN, str);
#else
#define printerrf(...) snprintf(this->err_str, MAX_ERR_LEN, __VA_ARGS__);
#endif /* WIN32 */
#endif
#define printerr(str) strncpy(this->err_str, str, MAX_ERR_LEN);
/* Save my typing */
#define S_ERR DVDNAV_STATUS_ERR
#ifndef _MSC_VER
#define S_OK DVDNAV_STATUS_OK
#endif /* MSC_VER */
#endif /* LIBDVDNAV_DVDNAV_INTERNAL_H */

134
msvc/msvc/include/getopt.h Normal file
View File

@ -0,0 +1,134 @@
/* Declarations for getopt.
Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
This file is part of the GNU C Library. Its master source is NOT part of
the C library, however. The master source lives in /gd/gnu/lib.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Floor, Boston, MA 02110-1301 USA. */
#ifndef _GETOPT_H
#define _GETOPT_H 1
#ifdef __cplusplus
extern "C"
{
#endif
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int optind;
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
extern int opterr;
/* Set to an option character which was unrecognized. */
extern int optopt;
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
The field `has_arg' is:
no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
struct option
{
#if defined (__STDC__) && __STDC__
const char *name;
#else
char *name;
#endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
/* Names for the values of the `has_arg' field of `struct option'. */
#define no_argument 0
#define required_argument 1
#define optional_argument 2
#if defined (__STDC__) && __STDC__
#ifdef __GNU_LIBRARY__
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in stdlib.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern int getopt(int argc, char *const *argv, const char *shortopts);
#else /* not __GNU_LIBRARY__ */
extern int getopt();
#endif /* __GNU_LIBRARY__ */
extern int getopt_long(int argc, char *const *argv, const char *shortopts,
const struct option *longopts, int *longind);
extern int getopt_long_only(int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind);
/* Internal only. Users should not call this directly. */
extern int _getopt_internal(int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind,
int long_only);
#else /* not __STDC__ */
extern int getopt();
extern int getopt_long();
extern int getopt_long_only();
extern int _getopt_internal();
#endif /* __STDC__ */
#ifdef __cplusplus
}
#endif
#endif /* _GETOPT_H */

View File

@ -0,0 +1,32 @@
/*
* Copyright (C) 2000-2001 the xine project
*
* This file is part of xine, a unix video player.
*
* xine 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.
*
* xine 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* WIN32 PORT,
* by Matthew Grooms <elon@altavista.com>
*
* inttypes.h - Standard integer definitions.
*
*/
#ifndef _SYS_INTTYPES_H_
#define _SYS_INTTYPES_H_
#include <config.h>
#endif

View File

@ -0,0 +1,24 @@
#ifndef __OS_TYPES_H__
#define __OS_TYPES_H__
/*
* win32 types
* 04 Sept 2001 - Chris Wolf create.
*/
typedef unsigned char uint_8;
typedef unsigned short uint_16;
typedef unsigned int uint_32;
typedef signed char sint_32;
typedef signed short sint_16;
typedef signed int sint_8;
#define snprintf _snprintf
#define M_PI 3.14159265358979323846 /* pi */
#define DLLENTRY __declspec(dllexport)
// Temporarily hardcode this location
#define AO_PLUGIN_PATH "c:\\Program Files\\Common Files\\Xiphophorus\\ao"
#define SHARED_LIB_EXT ".dll"
#endif /* __OS_TYPES_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,89 @@
/*
* Module: sched.h
*
* Purpose:
* Provides an implementation of POSIX realtime extensions
* as defined in
*
* POSIX 1003.1b-1993 (POSIX.1b)
*
* Pthreads-win32 - POSIX Threads Library for Win32
* Copyright (C) 1998
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA.
*/
#ifndef _SCHED_H
#define _SCHED_H
#if defined(__MINGW32__) || defined(_UWIN)
/* For pid_t */
# include <sys/types.h>
/* Required by Unix 98 */
# include <time.h>
#else
typedef int pid_t;
#endif
/* Thread scheduling policies */
enum {
SCHED_OTHER = 0,
SCHED_FIFO,
SCHED_RR,
SCHED_MIN = SCHED_OTHER,
SCHED_MAX = SCHED_RR
};
struct sched_param {
int sched_priority;
};
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
int sched_yield (void);
int sched_get_priority_min (int policy);
int sched_get_priority_max (int policy);
int sched_setscheduler (pid_t pid, int policy);
int sched_getscheduler (pid_t pid);
/*
* Note that this macro returns ENOTSUP rather than
* ENOSYS as might be expected. However, returning ENOSYS
* should mean that sched_get_priority_{min,max} are
* not implemented as well as sched_rr_get_interval.
* This is not the case, since we just don't support
* round-robin scheduling. Therefore I have chosen to
* return the same value as sched_setscheduler when
* SCHED_RR is passed to it.
*/
#define sched_rr_get_interval(_pid, _interval) \
( errno = ENOTSUP, (int) -1 )
#ifdef __cplusplus
} /* End of extern "C" */
#endif /* __cplusplus */
#endif /* !_SCHED_H */

View File

@ -0,0 +1,28 @@
/*
* Copyright (C) 2000-2001 the xine project
*
* This file is part of xine, a unix video player.
*
* xine 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.
*
* xine 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* WIN32 PORT,
* by Matthew Grooms <elon@altavista.com>
*
* sys/time.h - There is no seperate sys/time.h for win32 so we simply
* include the standard time header as well as our xine
* timer functions.
*/
#include <time.h>

39
msvc/msvc/include/timer.h Normal file
View File

@ -0,0 +1,39 @@
#include <time.h>
#include <winsock.h>
#include "pthread.h"
#ifndef _ITIMER_
#define _ITIMER_
#define ITIMER_REAL 0
#define ITIMER_VIRTUAL 1
// time reference
// ----------------------------------
//
// 1,000 milliseconds / sec
// 1,000,000 microseconds / sec
// 1,000,000,000 nanoseconds / sec
//
// timeval.time_sec = seconds
// timeval.time_usec = microseconds
struct itimerval
{
struct timeval it_interval; /* timer interval */
struct timeval it_value; /* current value */
};
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of dst correction */
};
int gettimeofday( struct timeval *tp, struct timezone *tzp );
int setitimer( int which, struct itimerval * value, struct itimerval *ovalue );
int pause( void );
unsigned int sleep( unsigned int seconds );
int nanosleep( const struct timespec *rqtp, struct timespec *rmtp );
#endif

View File

@ -0,0 +1,69 @@
/*
* Copyright (C) 2000-2001 the xine project
*
* This file is part of xine, a unix video player.
*
* xine 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.
*
* xine 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* WIN32 PORT,
* by Matthew Grooms <elon@altavista.com>
*
* unistd.h - This is mostly a catch all header that maps standard unix
* libc calls to the equivelent win32 functions.
*
*/
#include <windows.h>
#include <malloc.h>
#include <errno.h>
#include <direct.h>
#include <config.h>
#ifndef _SYS_UNISTD_H_
#define _SYS_UNISTD_H_
#define inline __inline
#define mkdir( A, B ) _mkdir( A )
#define lstat stat
#ifndef S_ISDIR
#define S_ISDIR(A) ( S_IFDIR & A )
#endif
#define S_IXUSR S_IEXEC
#define S_IXGRP S_IEXEC
#define S_IXOTH S_IEXEC
#define M_PI 3.14159265358979323846 /* pi */
#define bzero( A, B ) memset( A, 0, B )
#ifndef strcasecmp
#define strcasecmp _stricmp
#endif
#ifndef strncasecmp
#define strncasecmp _strnicmp
#endif
#define snprintf _snprintf
#define vsnprintf _vsnprintf
// FIXME : I dont remember why this is here
#define readlink
#endif

7
msvc/msvc/install/README Normal file
View File

@ -0,0 +1,7 @@
MSVC Help
---------
In order to build using any application that requires libdvdnav using MSVC the
following directories (lib and include) must be copied to the msvc directory of
the particular application.

12
msvc/msvc/libdvdcss.def Normal file
View File

@ -0,0 +1,12 @@
;------------------------------------------------------------
; LIBDVDCSS DLL DEFINITIONS FILE
EXPORTS
dvdcss_interface_2
dvdcss_open
dvdcss_error
dvdcss_seek
dvdcss_read
dvdcss_close
dvdcss_title

139
msvc/msvc/libdvdcss.dsp Normal file
View File

@ -0,0 +1,139 @@
# Microsoft Developer Studio Project File - Name="libdvdcss" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=libdvdcss - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "libdvdcss.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "libdvdcss.mak" CFG="libdvdcss - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "libdvdcss - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "libdvdcss - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "libdvdcss - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_USRDLL" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "." /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_USRDLL" /D PATH_MAX=2048 /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /machine:IX86
# ADD LINK32 /machine:IX86
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Desc=Create libdvdcss Install
PostBuild_Cmds=scripts\libdvdcss_intstall.bat Release
# End Special Build Tool
!ELSEIF "$(CFG)" == "libdvdcss - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I "../libdvdcss/dvdcss" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_USRDLL" /D MAX_PATH=2048 /YX /FD /GZ ./ "../libdvdcss" /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /machine:IX86
# ADD LINK32 /dll /machine:IX86 /out:"Debug/bin/libdvdcss.dll"
# SUBTRACT LINK32 /pdb:none
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Desc=Create libdvdcss Install
PostBuild_Cmds=scripts\libdvdcss_intstall.bat Debug
# End Special Build Tool
!ENDIF
# Begin Target
# Name "libdvdcss - Win32 Release"
# Name "libdvdcss - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\libdvdcss\css.c
# End Source File
# Begin Source File
SOURCE=..\..\libdvdcss\device.c
# End Source File
# Begin Source File
SOURCE=..\..\libdvdcss\error.c
# End Source File
# Begin Source File
SOURCE=..\..\libdvdcss\ioctl.c
# End Source File
# Begin Source File
SOURCE=..\..\libdvdcss\libdvdcss.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "DLL Defs"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\libdvdcss.def
# End Source File
# End Group
# End Target
# End Project

82
msvc/msvc/libdvdnav.def Normal file
View File

@ -0,0 +1,82 @@
;------------------------------------------------------------
; LIBDVDNAV DLL DEFINITIONS FILE
EXPORTS
DVDOpen
DVDClose
DVDOpenFile
DVDCloseFile
DVDReadBlocks
navRead_DSI
navRead_PCI
ifoClose
ifoRead_VOBU_ADMAP
ifoRead_VTS_ATRT
ifoRead_PTL_MAIT
ifoRead_PGCI_UT
ifoRead_TT_SRPT
ifoRead_FP_PGC
ifoOpenVMGI
ifoRead_TITLE_VOBU_ADMAP
ifoRead_PGCIT
ifoRead_VTS_PTT_SRPT
ifoOpenVTSI
ifoPrint
dvdnav_set_readahead_flag
dvdnav_set_region_mask
dvdnav_spu_language_select
dvdnav_audio_language_select
dvdnav_menu_language_select
dvdnav_get_angle_info
dvdnav_current_title_info
dvdnav_title_play
dvdnav_part_play
dvdnav_get_number_of_titles
dvdnav_get_title_string
dvdnav_open
dvdnav_close
dvdnav_wait_skip
dvdnav_get_video_scale_permission
dvdnav_get_video_aspect
dvdnav_still_skip
dvdnav_err_to_string
dvdnav_get_next_cache_block
dvdnav_free_cache_block
dvdnav_get_position
dvdnav_sector_search
dvdnav_get_current_highlight
dvdnav_button_select_and_activate
dvdnav_right_button_select
dvdnav_left_button_select
dvdnav_lower_button_select
dvdnav_upper_button_select
dvdnav_mouse_select
dvdnav_button_select
dvdnav_mouse_activate
dvdnav_button_activate
dvdnav_angle_change
dvdnav_prev_pg_search
dvdnav_next_pg_search
dvdnav_menu_call
dvdnav_spu_stream_to_lang
dvdnav_get_spu_logical_stream
dvdnav_audio_stream_to_lang
dvdnav_get_audio_logical_stream
dvdnav_is_domain_vts
dvdnav_set_PGC_positioning_flag
dvdnav_get_number_of_parts
dvdnav_reset
;------------------------------------------------------------
; timer exports
gettimeofday
setitimer
pause
sleep
nanosleep

156
msvc/msvc/libdvdnav.dsp Normal file
View File

@ -0,0 +1,156 @@
# Microsoft Developer Studio Project File - Name="libdvdnav" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=libdvdnav - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "libdvdnav.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "libdvdnav.mak" CFG="libdvdnav - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "libdvdnav - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "libdvdnav - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "libdvdnav - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
LINK32=link.exe
# ADD BASE LINK32 /machine:IX86
# ADD LINK32 /machine:IX86
MTL=midl.exe
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\libdvdcss\src" /I "." /I "include" /I "contrib/dirent" /I "include/pthreads" /I "../../libdvdcss" /I ".." /I "../src" /I "../src/vm" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "DVDNAV_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"Release\libdvdnav\libdvdnav.lib"
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Desc=Create libdvdnav Install Files
PostBuild_Cmds=scripts\libdvdnav_install.bat Release
# End Special Build Tool
!ELSEIF "$(CFG)" == "libdvdnav - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
LINK32=link.exe
# ADD BASE LINK32 /machine:IX86
# ADD LINK32 /debug /machine:IX86 /out:"Debug/libdvdnav.lib" /implib:"Debug/libdvdnav.lib"
# SUBTRACT LINK32 /pdb:none /nodefaultlib
MTL=midl.exe
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "include" /I "contrib/dirent" /I "include/pthreads" /I "../../libdvdcss" /I "../src" /I "." /I ".." /I "../src/vm" /D "WIN32" /D "_DEBUG" /D "_LIB" /D "DVDNAV_COMPILE" /D "HAVE_CONFIG_H" /FR"Debug/libdvdnav/" /Fp"Debug/libdvdnav/libdvdnav.pch" /YX /Fo"Debug/libdvdnav/" /Fd"Debug/libdvdnav/" /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 libwin32utils.lib /nologo /out:"Debug\libdvdnav\libdvdnav.lib"
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Desc=Create libdvdnav Install Files
PostBuild_Cmds=scripts\libdvdnav_install.bat Debug
# End Special Build Tool
!ENDIF
# Begin Target
# Name "libdvdnav - Win32 Release"
# Name "libdvdnav - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\src\vm\decoder.c
# End Source File
# Begin Source File
SOURCE=..\src\dvdnav.c
# End Source File
# Begin Source File
SOURCE=..\src\highlight.c
# End Source File
# Begin Source File
SOURCE=..\src\navigation.c
# End Source File
# Begin Source File
SOURCE=..\src\read_cache.c
# End Source File
# Begin Source File
SOURCE=..\src\remap.c
# End Source File
# Begin Source File
SOURCE=..\src\searching.c
# End Source File
# Begin Source File
SOURCE=..\src\settings.c
# End Source File
# Begin Source File
SOURCE=..\src\vm\vm.c
# End Source File
# Begin Source File
SOURCE=..\src\vm\vmcmd.c
# End Source File
# End Group
# Begin Group "DLL Defs"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\libdvdnav.def
# End Source File
# End Group
# End Target
# End Project

101
msvc/msvc/libdvdnav.dsw Normal file
View File

@ -0,0 +1,101 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "ifo_dump"=.\ifo_dump.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name libdvdnav
End Project Dependency
}}}
###############################################################################
Project: "libdvdcss"=.\libdvdcss.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "libdvdnav"=.\libdvdnav.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name libwin32utils
End Project Dependency
}}}
###############################################################################
Project: "libwin32utils"=.\libwin32utils.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "play_title"=.\play_title.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name libdvdnav
End Project Dependency
}}}
###############################################################################
Project: "title_info"=.\title_info.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name libdvdnav
End Project Dependency
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

229
msvc/msvc/libwin32utils.def Normal file
View File

@ -0,0 +1,229 @@
;------------------------------------------------------------
; LIBWIN32UTILS DLL DEFINITIONS FILE
EXPORTS
;------------------------------------------------------------
; dirent exports
opendir
closedir
readdir
rewinddir
;------------------------------------------------------------
; pthread exports
;pthread_atfork
pthread_attr_destroy
pthread_attr_getdetachstate
pthread_attr_getinheritsched
pthread_attr_getschedparam
pthread_attr_getschedpolicy
pthread_attr_getscope
pthread_attr_getstackaddr
pthread_attr_getstacksize
pthread_attr_init
pthread_attr_setdetachstate
pthread_attr_setinheritsched
pthread_attr_setschedparam
pthread_attr_setschedpolicy
pthread_attr_setscope
pthread_attr_setstackaddr
pthread_attr_setstacksize
pthread_cancel
;
; These two are implemented as macros in pthread.h
;
;pthread_cleanup_pop
;pthread_cleanup_push
;
pthread_condattr_destroy
pthread_condattr_getpshared
pthread_condattr_init
pthread_condattr_setpshared
pthread_cond_broadcast
pthread_cond_destroy
pthread_cond_init
pthread_cond_signal
pthread_cond_timedwait
pthread_cond_wait
pthread_create
pthread_detach
pthread_equal
pthread_exit
pthread_getconcurrency
pthread_getschedparam
pthread_getspecific
pthread_join
pthread_key_create
pthread_key_delete
;pthread_kill
pthread_mutexattr_destroy
;pthread_mutexattr_getprioceiling
;pthread_mutexattr_getprotocol
pthread_mutexattr_getpshared
pthread_mutexattr_gettype
pthread_mutexattr_init
;pthread_mutexattr_setprioceiling
;pthread_mutexattr_setprotocol
pthread_mutexattr_setpshared
pthread_mutexattr_settype
pthread_mutexattr_destroy
pthread_mutex_init
pthread_mutex_destroy
pthread_mutex_lock
pthread_mutex_trylock
pthread_mutex_unlock
pthread_once
pthread_self
pthread_setcancelstate
pthread_setcanceltype
pthread_setconcurrency
pthread_setschedparam
pthread_setspecific
;pthread_sigmask
pthread_testcancel
;
; POSIX 1.b
;
sched_get_priority_min
sched_get_priority_max
sched_getscheduler
sched_setscheduler
sched_yield
sem_init
sem_destroy
sem_trywait
sem_wait
sem_post
sem_open
sem_close
sem_unlink
sem_getvalue
;
; This next one is a macro
;sched_rr_get_interval
;
;
; Read/Write Locks
;
pthread_rwlock_init
pthread_rwlock_destroy
pthread_rwlock_tryrdlock
pthread_rwlock_trywrlock
pthread_rwlock_rdlock
pthread_rwlock_wrlock
pthread_rwlock_unlock
;
; Spin locks
;
pthread_spin_init
pthread_spin_destroy
pthread_spin_lock
pthread_spin_unlock
pthread_spin_trylock
;
; Barriers
;
pthread_barrier_init
pthread_barrier_destroy
pthread_barrier_wait
pthread_barrierattr_init
pthread_barrierattr_destroy
pthread_barrierattr_getpshared
pthread_barrierattr_setpshared
;
; Non-portable/compatibility with other implementations
;
pthread_delay_np
pthread_mutexattr_getkind_np
pthread_mutexattr_setkind_np
;
; Non-portable local implementation only
;
pthread_getw32threadhandle_np
pthread_getprocessors_np
pthreadCancelableWait
pthreadCancelableTimedWait
;
; For use when linking statically
;
pthread_win32_process_attach_np
pthread_win32_process_detach_np
pthread_win32_thread_attach_np
pthread_win32_thread_detach_np
;
; Needed if !defined(_MSC_VER) && !defined(__cplusplus)
;
ptw32_push_cleanup
ptw32_pop_cleanup
;
; Not for use directly. Needed by macros in pthread.h
; to return internal SEH code.
;
ptw32_get_exception_services_code
;------------------------------------------------------------
; timer exports
adler32
compress
crc32
deflate
deflateCopy
deflateEnd
deflateInit2_
deflateInit_
deflateParams
deflateReset
deflateSetDictionary
gzclose
gzdopen
gzerror
gzflush
gzopen
gzread
gzwrite
inflate
inflateEnd
inflateInit2_
inflateInit_
inflateReset
inflateSetDictionary
inflateSync
uncompress
zlibVersion
gzprintf
gzputc
gzgetc
gzseek
gzrewind
gztell
gzeof
gzsetparams
zError
inflateSyncPoint
get_crc_table
compress2
gzputs
gzgets
;------------------------------------------------------------
; timer exports
gettimeofday
setitimer
pause
sleep
nanosleep
;------------------------------------------------------------
; other exports
bcopy
dlclose
dlsym
dlopen
dlerror
optind

136
msvc/msvc/libwin32utils.dsp Normal file
View File

@ -0,0 +1,136 @@
# Microsoft Developer Studio Project File - Name="libwin32utils" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=libwin32utils - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "libwin32utils.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "libwin32utils.mak" CFG="libwin32utils - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "libwin32utils - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "libwin32utils - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "libwin32utils - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release/libwin32utils"
# PROP Intermediate_Dir "Release/libwin32utils"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /machine:I386
# ADD LINK32 winmm.lib /nologo /machine:I386 /out:"Release/libwin32utils.lib"
MTL=midl.exe
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_LIB" /D "LIBWIN32UTILS_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "include" /I "contrib/dirent" /I "include/pthreads" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_LIB" /D "LIBWIN32UTILS_EXPORTS" /D "__CLEANUP_C" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD LIB32 /out:"libwin32utils.lib"
!ELSEIF "$(CFG)" == "libwin32utils - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug/libwin32utils"
# PROP Intermediate_Dir "Debug/libwin32utils"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /debug /machine:I386 /pdbtype:sept
# ADD LINK32 winmm.lib /nologo /debug /machine:I386 /out:"Debug/libwin32utils.lib" /pdbtype:sept
MTL=midl.exe
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_LIB" /D "LIBWIN32UTILS_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "include/pthreads" /I "include" /I "contrib/dirent" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_LIB" /D "LIBWIN32UTILS_EXPORTS" /D "__CLEANUP_C" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD LIB32 winmm.lib /out:"libwin32utils.lib"
!ENDIF
# Begin Target
# Name "libwin32utils - Win32 Release"
# Name "libwin32utils - Win32 Debug"
# Begin Group "Source Files ( dirent )"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\contrib\dirent\dirent.c
# End Source File
# End Group
# Begin Group "Source Files ( timer )"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\contrib\timer\timer.c
# End Source File
# End Group
# Begin Group "DLL Defs"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\libwin32utils.def
# End Source File
# End Group
# Begin Group "Source Files ( other )"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\contrib\bcopy.c
# End Source File
# Begin Source File
SOURCE=.\contrib\dlfcn.c
# End Source File
# Begin Source File
SOURCE=.\contrib\getopt.c
# End Source File
# End Group
# End Target
# End Project

101
msvc/msvc/play_title.dsp Normal file
View File

@ -0,0 +1,101 @@
# Microsoft Developer Studio Project File - Name="play_title" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=play_title - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "play_title.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "play_title.mak" CFG="play_title - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "play_title - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "play_title - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "play_title - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "play_title - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "play_title___Win32_Debug"
# PROP BASE Intermediate_Dir "play_title___Win32_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug\play_title"
# PROP Intermediate_Dir "Debug\play_title"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "include" /I "contrib/dirent" /I "../../libdvdcss" /I "install/include" /I "." /I ".." /I "../src" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/bin/play_title.exe" /pdbtype:sept
!ENDIF
# Begin Target
# Name "play_title - Win32 Release"
# Name "play_title - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\src\play_title.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@ -0,0 +1,8 @@
ECHO mkdir dll ...
rmdir /s install\dll
mkdir install\dll
ECHO libvdvcss dll ...
xcopy /Y %1\bin\libdvdcss.dll install\dll

View File

@ -0,0 +1,21 @@
ECHO mkdir install ...
rmdir /s install\include
rmdir /s install\lib
mkdir install\include\dvdnav
mkdir install\lib
ECHO includes ...
xcopy /Y ..\src\dvdnav.h install\include\dvdnav
xcopy /Y ..\src\dvdnav_events.h install\include\dvdnav
xcopy /Y ..\src\dvd_types.h install\include\dvdnav
xcopy /Y ..\src\dvdread\dvd_reader.h install\include\dvdnav
xcopy /Y ..\src\dvdread\nav_read.h install\include\dvdnav
xcopy /Y ..\src\dvdread\ifo_read.h install\include\dvdnav
xcopy /Y ..\src\dvdread\nav_print.h install\include\dvdnav
xcopy /Y ..\src\dvdread\ifo_print.h install\include\dvdnav
xcopy /Y ..\src\dvdread\ifo_types.h install\include\dvdnav
xcopy /Y ..\src\dvdread\nav_types.h install\include\dvdnav
ECHO lib ...
xcopy /Y %1\libdvdnav\libdvdnav.lib install\lib

101
msvc/msvc/title_info.dsp Normal file
View File

@ -0,0 +1,101 @@
# Microsoft Developer Studio Project File - Name="title_info" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=title_info - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "title_info.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "title_info.mak" CFG="title_info - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "title_info - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "title_info - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "title_info - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "title_info - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "title_info___Win32_Debug"
# PROP BASE Intermediate_Dir "title_info___Win32_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "title_info___Win32_Debug"
# PROP Intermediate_Dir "title_info___Win32_Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "include" /I "contrib/dirent" /I "../../libdvdcss" /I "install/include" /I "." /I ".." /I "../src" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"Debug/title_info/title_info.pch" /YX /Fo"Debug/title_info/" /Fd"Debug/title_info/" /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/bin/title_info.exe" /pdbtype:sept
!ENDIF
# Begin Target
# Name "title_info - Win32 Release"
# Name "title_info - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\src\title_info.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

1293
src/dvdnav.c Normal file

File diff suppressed because it is too large Load Diff

273
src/dvdnav/dvd_types.h Normal file
View File

@ -0,0 +1,273 @@
/*
* Copyright (C) 2000, 2001 Björn Englund, Håkan Hjort
*
* This file is part of libdvdnav, a DVD navigation library. It is a modified
* file originally part of the Ogle DVD player project.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Various useful structs and enums for DVDs.
*/
#ifndef LIBDVDNAV_DVD_TYPES_H
#define LIBDVDNAV_DVD_TYPES_H
#include <stdint.h>
/*
* DVD Menu ID
* (see dvdnav_menu_call())
*/
typedef enum {
/* When used in VTS domain, DVD_MENU_Escape behaves like DVD_MENU_Root,
* but from within a menu domain, DVD_MENU_Escape resumes playback. */
DVD_MENU_Escape = 0,
DVD_MENU_Title = 2,
DVD_MENU_Root = 3,
DVD_MENU_Subpicture = 4,
DVD_MENU_Audio = 5,
DVD_MENU_Angle = 6,
DVD_MENU_Part = 7
} DVDMenuID_t;
/* Domain */
typedef enum {
DVD_DOMAIN_FirstPlay = 1, /* First Play Domain */
DVD_DOMAIN_VTSTitle = 2, /* Video Title Set Domain */
DVD_DOMAIN_VMGM = 4, /* Video Manager Domain */
DVD_DOMAIN_VTSMenu = 8 /* Video Title Set Menu Domain */
} DVDDomain_t;
/*
* Structure containing info on highlight areas
* (see dvdnav_get_highlight_area())
*/
typedef struct {
uint32_t palette; /* The CLUT entries for the highlight palette
(4-bits per entry -> 4 entries) */
uint16_t sx,sy,ex,ey; /* The start/end x,y positions */
uint32_t pts; /* Highlight PTS to match with SPU */
/* button number for the SPU decoder/overlaying engine */
uint32_t buttonN;
} dvdnav_highlight_area_t;
/* The audio format */
typedef enum {
DVD_AUDIO_FORMAT_AC3 = 0,
DVD_AUDIO_FORMAT_UNKNOWN_1 = 1,
DVD_AUDIO_FORMAT_MPEG = 2,
DVD_AUDIO_FORMAT_MPEG2_EXT = 3,
DVD_AUDIO_FORMAT_LPCM = 4,
DVD_AUDIO_FORMAT_UNKNOWN_5 = 5,
DVD_AUDIO_FORMAT_DTS = 6,
DVD_AUDIO_FORMAT_SDDS = 7
} DVDAudioFormat_t;
/* the following types are currently unused */
#if 0
/* User operation permissions */
typedef enum {
UOP_FLAG_TitleOrTimePlay = 0x00000001,
UOP_FLAG_ChapterSearchOrPlay = 0x00000002,
UOP_FLAG_TitlePlay = 0x00000004,
UOP_FLAG_Stop = 0x00000008,
UOP_FLAG_GoUp = 0x00000010,
UOP_FLAG_TimeOrChapterSearch = 0x00000020,
UOP_FLAG_PrevOrTopPGSearch = 0x00000040,
UOP_FLAG_NextPGSearch = 0x00000080,
UOP_FLAG_ForwardScan = 0x00000100,
UOP_FLAG_BackwardScan = 0x00000200,
UOP_FLAG_TitleMenuCall = 0x00000400,
UOP_FLAG_RootMenuCall = 0x00000800,
UOP_FLAG_SubPicMenuCall = 0x00001000,
UOP_FLAG_AudioMenuCall = 0x00002000,
UOP_FLAG_AngleMenuCall = 0x00004000,
UOP_FLAG_ChapterMenuCall = 0x00008000,
UOP_FLAG_Resume = 0x00010000,
UOP_FLAG_ButtonSelectOrActivate = 0x00020000,
UOP_FLAG_StillOff = 0x00040000,
UOP_FLAG_PauseOn = 0x00080000,
UOP_FLAG_AudioStreamChange = 0x00100000,
UOP_FLAG_SubPicStreamChange = 0x00200000,
UOP_FLAG_AngleChange = 0x00400000,
UOP_FLAG_KaraokeAudioPresModeChange = 0x00800000,
UOP_FLAG_VideoPresModeChange = 0x01000000
} DVDUOP_t;
/* Parental Level */
typedef enum {
DVD_PARENTAL_LEVEL_1 = 1,
DVD_PARENTAL_LEVEL_2 = 2,
DVD_PARENTAL_LEVEL_3 = 3,
DVD_PARENTAL_LEVEL_4 = 4,
DVD_PARENTAL_LEVEL_5 = 5,
DVD_PARENTAL_LEVEL_6 = 6,
DVD_PARENTAL_LEVEL_7 = 7,
DVD_PARENTAL_LEVEL_8 = 8,
DVD_PARENTAL_LEVEL_None = 15
} DVDParentalLevel_t;
/* Language ID (ISO-639 language code) */
typedef uint16_t DVDLangID_t;
/* Country ID (ISO-3166 country code) */
typedef uint16_t DVDCountryID_t;
/* Register */
typedef uint16_t DVDRegister_t;
typedef enum {
DVDFalse = 0,
DVDTrue = 1
} DVDBool_t;
typedef DVDRegister_t DVDGPRMArray_t[16];
typedef DVDRegister_t DVDSPRMArray_t[24];
/* Navigation */
typedef int DVDStream_t;
typedef int DVDPTT_t;
typedef int DVDTitle_t;
/* Angle number (1-9 or default?) */
typedef int DVDAngle_t;
/* Timecode */
typedef struct {
uint8_t Hours;
uint8_t Minutes;
uint8_t Seconds;
uint8_t Frames;
} DVDTimecode_t;
/* Subpicture stream number (0-31,62,63) */
typedef int DVDSubpictureStream_t;
/* Audio stream number (0-7, 15(none)) */
typedef int DVDAudioStream_t;
/* The audio application mode */
typedef enum {
DVD_AUDIO_APP_MODE_None = 0,
DVD_AUDIO_APP_MODE_Karaoke = 1,
DVD_AUDIO_APP_MODE_Surround = 2,
DVD_AUDIO_APP_MODE_Other = 3
} DVDAudioAppMode_t;
/* Audio language extension */
typedef enum {
DVD_AUDIO_LANG_EXT_NotSpecified = 0,
DVD_AUDIO_LANG_EXT_NormalCaptions = 1,
DVD_AUDIO_LANG_EXT_VisuallyImpaired = 2,
DVD_AUDIO_LANG_EXT_DirectorsComments1 = 3,
DVD_AUDIO_LANG_EXT_DirectorsComments2 = 4
} DVDAudioLangExt_t;
/* Subpicture language extension */
typedef enum {
DVD_SUBPICTURE_LANG_EXT_NotSpecified = 0,
DVD_SUBPICTURE_LANG_EXT_NormalCaptions = 1,
DVD_SUBPICTURE_LANG_EXT_BigCaptions = 2,
DVD_SUBPICTURE_LANG_EXT_ChildrensCaptions = 3,
DVD_SUBPICTURE_LANG_EXT_NormalCC = 5,
DVD_SUBPICTURE_LANG_EXT_BigCC = 6,
DVD_SUBPICTURE_LANG_EXT_ChildrensCC = 7,
DVD_SUBPICTURE_LANG_EXT_Forced = 9,
DVD_SUBPICTURE_LANG_EXT_NormalDirectorsComments = 13,
DVD_SUBPICTURE_LANG_EXT_BigDirectorsComments = 14,
DVD_SUBPICTURE_LANG_EXT_ChildrensDirectorsComments = 15,
} DVDSubpictureLangExt_t;
/* Karaoke Downmix mode */
typedef enum {
DVD_KARAOKE_DOWNMIX_0to0 = 0x0001,
DVD_KARAOKE_DOWNMIX_1to0 = 0x0002,
DVD_KARAOKE_DOWNMIX_2to0 = 0x0004,
DVD_KARAOKE_DOWNMIX_3to0 = 0x0008,
DVD_KARAOKE_DOWNMIX_4to0 = 0x0010,
DVD_KARAOKE_DOWNMIX_Lto0 = 0x0020,
DVD_KARAOKE_DOWNMIX_Rto0 = 0x0040,
DVD_KARAOKE_DOWNMIX_0to1 = 0x0100,
DVD_KARAOKE_DOWNMIX_1to1 = 0x0200,
DVD_KARAOKE_DOWNMIX_2to1 = 0x0400,
DVD_KARAOKE_DOWNMIX_3to1 = 0x0800,
DVD_KARAOKE_DOWNMIX_4to1 = 0x1000,
DVD_KARAOKE_DOWNMIX_Lto1 = 0x2000,
DVD_KARAOKE_DOWNMIX_Rto1 = 0x4000
} DVDKaraokeDownmix_t;
typedef int DVDKaraokeDownmixMask_t;
/* Display mode */
typedef enum {
DVD_DISPLAY_MODE_ContentDefault = 0,
DVD_DISPLAY_MODE_16x9 = 1,
DVD_DISPLAY_MODE_4x3PanScan = 2,
DVD_DISPLAY_MODE_4x3Letterboxed = 3
} DVDDisplayMode_t;
/* Audio attributes */
typedef struct {
DVDAudioAppMode_t AppMode;
DVDAudioFormat_t AudioFormat;
DVDLangID_t Language;
DVDAudioLangExt_t LanguageExtension;
DVDBool_t HasMultichannelInfo;
DVDAudioSampleFreq_t SampleFrequency;
DVDAudioSampleQuant_t SampleQuantization;
DVDChannelNumber_t NumberOfChannels;
} DVDAudioAttributes_t;
typedef int DVDAudioSampleFreq_t;
typedef int DVDAudioSampleQuant_t;
typedef int DVDChannelNumber_t;
/* Subpicture attributes */
typedef enum {
DVD_SUBPICTURE_TYPE_NotSpecified = 0,
DVD_SUBPICTURE_TYPE_Language = 1,
DVD_SUBPICTURE_TYPE_Other = 2
} DVDSubpictureType_t;
typedef enum {
DVD_SUBPICTURE_CODING_RunLength = 0,
DVD_SUBPICTURE_CODING_Extended = 1,
DVD_SUBPICTURE_CODING_Other = 2
} DVDSubpictureCoding_t;
typedef struct {
DVDSubpictureType_t Type;
DVDSubpictureCoding_t CodingMode;
DVDLangID_t Language;
DVDSubpictureLangExt_t LanguageExtension;
} DVDSubpictureAttributes_t;
/* Video attributes */
typedef struct {
DVDBool_t PanscanPermitted;
DVDBool_t LetterboxPermitted;
int AspectX;
int AspectY;
int FrameRate;
int FrameHeight;
DVDVideoCompression_t Compression;
DVDBool_t Line21Field1InGop;
DVDBool_t Line21Field2InGop;
int more_to_come;
} DVDVideoAttributes_t;
typedef int DVDVideoCompression_t;
#endif
#endif /* LIBDVDNAV_DVD_TYPES_H */

707
src/dvdnav/dvdnav.h Normal file
View File

@ -0,0 +1,707 @@
/*
* Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net>
*
* This file is part of libdvdnav, a DVD navigation library.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* This is the main header file applications should include if they want
* to access dvdnav functionality.
*/
#ifndef LIBDVDNAV_DVDNAV_H
#define LIBDVDNAV_DVDNAV_H
#define DVDNAV_VERSION 50400
#ifdef __cplusplus
extern "C" {
#endif
#include <dvdnav/dvd_types.h>
#include <dvdread/dvd_reader.h>
#include <dvdread/nav_types.h>
#include <dvdread/ifo_types.h> /* For vm_cmd_t */
#include <dvdnav/dvdnav_events.h>
/*********************************************************************
* dvdnav data types *
*********************************************************************/
/*
* Opaque data-type can be viewed as a 'DVD handle'. You should get
* a pointer to a dvdnav_t from the dvdnav_open() function.
* Never call free() on the pointer, you have to give it back with
* dvdnav_close().
*/
typedef struct dvdnav_s dvdnav_t;
/* Status as reported by most of libdvdnav's functions */
typedef int32_t dvdnav_status_t;
typedef dvd_reader_stream_cb dvdnav_stream_cb;
/*
* Unless otherwise stated, all functions return DVDNAV_STATUS_OK if
* they succeeded, otherwise DVDNAV_STATUS_ERR is returned and the error may
* be obtained by calling dvdnav_err_to_string().
*/
#define DVDNAV_STATUS_ERR 0
#define DVDNAV_STATUS_OK 1
/*********************************************************************
* initialisation & housekeeping functions *
*********************************************************************/
/*
* These functions allow you to open a DVD device and associate it
* with a dvdnav_t.
*/
/*
* Attempts to open the DVD drive at the specified path or using external
* seek/read functions (dvdnav_open_stream) and pre-cache the CSS-keys.
* libdvdread is used to access the DVD, so any source supported by libdvdread
* can be given with "path" or "stream_cb". Currently, using dvdnav_open,
* libdvdread can access : DVD drives, DVD image files, DVD file-by-file
* copies. Using dvdnav_open_stream, libdvdread can access any kind of DVD
* storage via custom implementation of seek/read functions.
*
* The resulting dvdnav_t handle will be written to *dest.
*/
dvdnav_status_t dvdnav_open(dvdnav_t **dest, const char *path);
dvdnav_status_t
dvdnav_open_stream(dvdnav_t **dest, void *stream, dvdnav_stream_cb *stream_cb);
dvdnav_status_t dvdnav_dup(dvdnav_t **dest, dvdnav_t *src);
dvdnav_status_t dvdnav_free_dup(dvdnav_t * _this);
/*
* Closes a dvdnav_t previously opened with dvdnav_open(), freeing any
* memory associated with it.
*/
dvdnav_status_t dvdnav_close(dvdnav_t *self);
/*
* Resets the DVD virtual machine and cache buffers.
*/
dvdnav_status_t dvdnav_reset(dvdnav_t *self);
/*
* Fills a pointer with a value pointing to a string describing
* the path associated with an open dvdnav_t. It assigns *path to NULL
* on error.
*/
dvdnav_status_t dvdnav_path(dvdnav_t *self, const char **path);
/*
* Returns a human-readable string describing the last error.
*/
const char* dvdnav_err_to_string(dvdnav_t *self);
/*********************************************************************
* changing and reading DVD player characteristics *
*********************************************************************/
/*
* These functions allow you to manipulate the various global characteristics
* of the DVD playback engine.
*/
/*
* Sets the region mask (bit 0 set implies region 1, bit 1 set implies
* region 2, etc) of the virtual machine. Generally you will only need to set
* this if you are playing RCE discs which query the virtual machine as to its
* region setting.
*
* This has _nothing_ to do with the region setting of the DVD drive.
*/
dvdnav_status_t dvdnav_set_region_mask(dvdnav_t *self, int32_t region_mask);
/*
* Returns the region mask (bit 0 set implies region 1, bit 1 set implies
* region 2, etc) of the virtual machine.
*
* This has _nothing_ to do with the region setting of the DVD drive.
*/
dvdnav_status_t dvdnav_get_region_mask(dvdnav_t *self, int32_t *region_mask);
/*
* Specify whether read-ahead caching should be used. You may not want this if your
* decoding engine does its own buffering.
*
* The default read-ahead cache does not use an additional thread for the reading
* (see read_cache.c for a threaded cache, but note that this code is currently
* unmaintained). It prebuffers on VOBU level by reading ahead several buffers
* on every read request. The speed of this prebuffering has been optimized to
* also work on slow DVD drives.
*
* If in addition you want to prevent memcpy's to improve performance, have a look
* at dvdnav_get_next_cache_block().
*/
dvdnav_status_t dvdnav_set_readahead_flag(dvdnav_t *self, int32_t read_ahead_flag);
/*
* Query whether read-ahead caching/buffering will be used.
*/
dvdnav_status_t dvdnav_get_readahead_flag(dvdnav_t *self, int32_t *read_ahead_flag);
/*
* Specify whether the positioning works PGC or PG based.
* Programs (PGs) on DVDs are similar to Chapters and a program chain (PGC)
* usually covers a whole feature. This affects the behaviour of the
* functions dvdnav_get_position() and dvdnav_sector_search(). See there.
* Default is PG based positioning.
*/
dvdnav_status_t dvdnav_set_PGC_positioning_flag(dvdnav_t *self, int32_t pgc_based_flag);
/*
* Query whether positioning is PG or PGC based.
*/
dvdnav_status_t dvdnav_get_PGC_positioning_flag(dvdnav_t *self, int32_t *pgc_based_flag);
/*********************************************************************
* reading data *
*********************************************************************/
/*
* These functions are used to poll the playback engine and actually get data
* off the DVD.
*/
/*
* Attempts to get the next block off the DVD and copies it into the buffer 'buf'.
* If there is any special actions that may need to be performed, the value
* pointed to by 'event' gets set accordingly.
*
* If 'event' is DVDNAV_BLOCK_OK then 'buf' is filled with the next block
* (note that means it has to be at /least/ 2048 bytes big). 'len' is
* then set to 2048.
*
* Otherwise, buf is filled with an appropriate event structure and
* len is set to the length of that structure.
*
* See the dvdnav_events.h header for information on the various events.
*/
dvdnav_status_t dvdnav_get_next_block(dvdnav_t *self, uint8_t *buf,
int32_t *event, int32_t *len);
/*
* This basically does the same as dvdnav_get_next_block. The only difference is
* that it avoids a memcopy, when the requested block was found in the cache.
* In such a case (cache hit) this function will return a different pointer than
* the one handed in, pointing directly into the relevant block in the cache.
* Those pointers must _never_ be freed but instead returned to the library via
* dvdnav_free_cache_block().
*/
dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *self, uint8_t **buf,
int32_t *event, int32_t *len);
/*
* All buffers which came from the internal cache (when dvdnav_get_next_cache_block()
* returned a buffer different from the one handed in) have to be freed with this
* function. Although handing in other buffers not from the cache doesn't cause any harm.
*/
dvdnav_status_t dvdnav_free_cache_block(dvdnav_t *self, unsigned char *buf);
/*
* If we are currently in a still-frame this function skips it.
*
* See also the DVDNAV_STILL_FRAME event.
*/
dvdnav_status_t dvdnav_still_skip(dvdnav_t *self);
/*
* If we are currently in WAIT state, that is: the application is required to
* wait for its fifos to become empty, calling this signals libdvdnav that this
* is achieved and that it can continue.
*
* See also the DVDNAV_WAIT event.
*/
dvdnav_status_t dvdnav_wait_skip(dvdnav_t *self);
/*
* Returns the still time from the currently playing cell.
* The still time is given in seconds with 0xff meaning an indefinite still.
*
* This function can be used to detect still frames before they are reached.
* Some players might need this to prepare for a frame to be shown for a
* longer time than usual.
*/
uint32_t dvdnav_get_next_still_flag(dvdnav_t *self);
/*
* Stops playback. The next event obtained with one of the get_next_block
* functions will be a DVDNAV_STOP event.
*
* It is not required to call this before dvdnav_close().
*/
dvdnav_status_t dvdnav_stop(dvdnav_t *self);
/*********************************************************************
* title/part navigation *
*********************************************************************/
/*
* Returns the number of titles on the disk.
*/
dvdnav_status_t dvdnav_get_number_of_titles(dvdnav_t *self, int32_t *titles);
/*
* Returns the number of parts within the given title.
*/
dvdnav_status_t dvdnav_get_number_of_parts(dvdnav_t *self, int32_t title, int32_t *parts);
/*
* Plays the specified title of the DVD from its beginning (that is: part 1).
*/
dvdnav_status_t dvdnav_title_play(dvdnav_t *self, int32_t title);
/*
* Plays the specified title, starting from the specified part.
*/
dvdnav_status_t dvdnav_part_play(dvdnav_t *self, int32_t title, int32_t part);
/*
* Plays the specified title, starting from the specified program
*/
dvdnav_status_t dvdnav_program_play(dvdnav_t *self, int32_t title, int32_t pgcn, int32_t pgn);
/*
* Stores in *times an array (that the application *must* free) of
* dvdtimes corresponding to the chapter times for the chosen title.
* *duration will have the duration of the title
* The number of entries in *times is the result of the function.
* On error *times is NULL and the output is 0
*/
uint32_t dvdnav_describe_title_chapters(dvdnav_t *self, int32_t title, uint64_t **times, uint64_t *duration);
/*
* Play the specified amount of parts of the specified title of
* the DVD then STOP.
*
* Currently unimplemented!
*/
dvdnav_status_t dvdnav_part_play_auto_stop(dvdnav_t *self, int32_t title,
int32_t part, int32_t parts_to_play);
/*
* Play the specified title starting from the specified time.
*
* Currently unimplemented!
*/
dvdnav_status_t dvdnav_time_play(dvdnav_t *self, int32_t title,
uint64_t time);
/*
* Stop playing the current position and jump to the specified menu.
*
* See also DVDMenuID_t from libdvdread
*/
dvdnav_status_t dvdnav_menu_call(dvdnav_t *self, DVDMenuID_t menu);
/*
* Return the title number and part currently being played.
* A title of 0 indicates we are in a menu. In this case, part
* is set to the current menu's ID.
*/
dvdnav_status_t dvdnav_current_title_info(dvdnav_t *self, int32_t *title,
int32_t *part);
/*
* Return the title number, pgcn and pgn currently being played.
* A title of 0 indicates, we are in a menu.
*/
dvdnav_status_t dvdnav_current_title_program(dvdnav_t *self, int32_t *title,
int32_t *pgcn, int32_t *pgn);
/*
* Return the current position (in blocks) within the current
* title and the length (in blocks) of said title.
*
* Current implementation is wrong and likely to behave unpredictably!
* Use is discouraged!
*/
dvdnav_status_t dvdnav_get_position_in_title(dvdnav_t *self,
uint32_t *pos,
uint32_t *len);
/*
* This function is only available for compatibility reasons.
*
* Stop playing the current position and start playback of the current title
* from the specified part.
*/
dvdnav_status_t dvdnav_part_search(dvdnav_t *self, int32_t part);
/*********************************************************************
* program chain/program navigation *
*********************************************************************/
/*
* Stop playing the current position and start playback from the last
* VOBU boundary before the given sector. The sector number is not
* meant to be an absolute physical DVD sector, but a relative sector
* in the current program. This function cannot leave the current
* program and will fail if asked to do so.
*
* If program chain based positioning is enabled
* (see dvdnav_set_PGC_positioning_flag()), this will seek to the relative
* sector inside the current program chain.
*
* 'origin' can be one of SEEK_SET, SEEK_CUR, SEEK_END as defined in
* fcntl.h.
*/
dvdnav_status_t dvdnav_sector_search(dvdnav_t *self,
int64_t offset, int32_t origin);
/*
returns the current stream time in PTS ticks as reported by the IFO structures
divide it by 90000 to get the current play time in seconds
*/
int64_t dvdnav_get_current_time(dvdnav_t *self);
/*
* Stop playing the current position and start playback of the title
* from the specified timecode.
*
* Currently implemented using interpolation. That interpolation is slightly
* inaccurate.
*/
dvdnav_status_t dvdnav_time_search(dvdnav_t *self,
uint64_t time);
/*
* Stop playing current position and play the "GoUp"-program chain.
* (which generally leads to the title menu or a higher-level menu).
*/
dvdnav_status_t dvdnav_go_up(dvdnav_t *self);
/*
* Stop playing the current position and start playback at the
* previous program (if it exists).
*/
dvdnav_status_t dvdnav_prev_pg_search(dvdnav_t *self);
/*
* Stop playing the current position and start playback at the
* first program.
*/
dvdnav_status_t dvdnav_top_pg_search(dvdnav_t *self);
/*
* Stop playing the current position and start playback at the
* next program (if it exists).
*/
dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *self);
/*
* Return the current position (in blocks) within the current
* program and the length (in blocks) of current program.
*
* If program chain based positioning is enabled
* (see dvdnav_set_PGC_positioning_flag()), this will return the
* relative position in and the length of the current program chain.
*/
dvdnav_status_t dvdnav_get_position(dvdnav_t *self, uint32_t *pos,
uint32_t *len);
/*********************************************************************
* menu highlights *
*********************************************************************/
/*
* Most functions related to highlights take a NAV PCI packet as a parameter.
* While you can get such a packet from libdvdnav, this will result in
* errors for players with internal FIFOs because due to the FIFO length,
* libdvdnav will be ahead in the stream compared to what the user is
* seeing on screen. Therefore, player applications who have a NAV
* packet available, which is better in sync with the actual playback,
* should always pass this one to these functions.
*/
/*
* Get the currently highlighted button
* number (1..36) or 0 if no button is highlighted.
*/
dvdnav_status_t dvdnav_get_current_highlight(dvdnav_t *self, int32_t *button);
/*
* Returns the Presentation Control Information (PCI) structure associated
* with the current position.
*
* Read the general notes above.
* See also libdvdreads nav_types.h for definition of pci_t.
*/
pci_t* dvdnav_get_current_nav_pci(dvdnav_t *self);
/*
* Returns the DSI (data search information) structure associated
* with the current position.
*
* Read the general notes above.
* See also libdvdreads nav_types.h for definition of dsi_t.
*/
dsi_t* dvdnav_get_current_nav_dsi(dvdnav_t *self);
/*
* Get the area associated with a certain button.
*/
dvdnav_status_t dvdnav_get_highlight_area(pci_t *nav_pci , int32_t button, int32_t mode,
dvdnav_highlight_area_t *highlight);
/*
* Move button highlight around as suggested by function name (e.g. with arrow keys).
*/
dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *self, pci_t *pci);
dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *self, pci_t *pci);
dvdnav_status_t dvdnav_right_button_select(dvdnav_t *self, pci_t *pci);
dvdnav_status_t dvdnav_left_button_select(dvdnav_t *self, pci_t *pci);
/*
* Activate ("press") the currently highlighted button.
*/
dvdnav_status_t dvdnav_button_activate(dvdnav_t *self, pci_t *pci);
/*
* Highlight a specific button.
*/
dvdnav_status_t dvdnav_button_select(dvdnav_t *self, pci_t *pci, int32_t button);
/*
* Activate ("press") specified button.
*/
dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *self, pci_t *pci, int32_t button);
/*
* Activate ("press") a button and execute specified command.
*/
dvdnav_status_t dvdnav_button_activate_cmd(dvdnav_t *self, int32_t button, vm_cmd_t *cmd);
/*
* Select button at specified video frame coordinates.
*/
dvdnav_status_t dvdnav_mouse_select(dvdnav_t *self, pci_t *pci, int32_t x, int32_t y);
/*
* Activate ("press") button at specified video frame coordinates.
*/
dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *self, pci_t *pci, int32_t x, int32_t y);
/*********************************************************************
* languages *
*********************************************************************/
/*
* The language codes expected by these functions are two character
* codes as defined in ISO639.
*/
/*
* Set which menu language we should use per default.
*/
dvdnav_status_t dvdnav_menu_language_select(dvdnav_t *self,
char *code);
/*
* Set which audio language we should use per default.
*/
dvdnav_status_t dvdnav_audio_language_select(dvdnav_t *self,
char *code);
/*
* Set which spu language we should use per default.
*/
dvdnav_status_t dvdnav_spu_language_select(dvdnav_t *self,
char *code);
/*********************************************************************
* obtaining stream attributes *
*********************************************************************/
/*
* Return a string describing the title of the DVD.
* This is an ID string encoded on the disc by the author. In many cases
* this is a descriptive string such as `THE_MATRIX' but sometimes is singularly
* uninformative such as `PDVD-011421'. Some DVD authors even forget to set this,
* so you may also read the default of the authoring software they used, like
* `DVDVolume'.
*/
dvdnav_status_t dvdnav_get_title_string(dvdnav_t *self, const char **title_str);
/*
* Returns a string containing the serial number of the DVD.
* This has a max of 15 characters and should be more unique than the
* title string.
*/
dvdnav_status_t dvdnav_get_serial_string(dvdnav_t *self, const char **serial_str);
/*
* Get video aspect code.
* The aspect code does only change on VTS boundaries.
* See the DVDNAV_VTS_CHANGE event.
*
* 0 -- 4:3, 2 -- 16:9
*/
uint8_t dvdnav_get_video_aspect(dvdnav_t *self);
/*
* Get video resolution.
*/
dvdnav_status_t dvdnav_get_video_resolution(dvdnav_t *self, uint32_t *width, uint32_t *height);
/*
* Get video scaling permissions.
* The scaling permission does only change on VTS boundaries.
* See the DVDNAV_VTS_CHANGE event.
*
* bit0 set = deny letterboxing, bit1 set = deny pan&scan
*/
uint8_t dvdnav_get_video_scale_permission(dvdnav_t *self);
/*
* Converts a *logical* audio stream id into language code
* (returns 0xffff if no such stream).
*/
uint16_t dvdnav_audio_stream_to_lang(dvdnav_t *self, uint8_t stream);
/*
* Returns the format of *logical* audio stream 'stream'
* (returns 0xffff if no such stream).
*/
uint16_t dvdnav_audio_stream_format(dvdnav_t *self, uint8_t stream);
/*
* Returns number of channels in *logical* audio stream 'stream'
* (returns 0xffff if no such stream).
*/
uint16_t dvdnav_audio_stream_channels(dvdnav_t *self, uint8_t stream);
/*
* Converts a *logical* subpicture stream id into country code
* (returns 0xffff if no such stream).
*/
uint16_t dvdnav_spu_stream_to_lang(dvdnav_t *self, uint8_t stream);
/*
* Converts a *physical* (MPEG) audio stream id into a logical stream number.
*/
int8_t dvdnav_get_audio_logical_stream(dvdnav_t *self, uint8_t audio_num);
#define HAVE_GET_AUDIO_ATTR
/*
* Get audio attr
*/
dvdnav_status_t dvdnav_get_audio_attr(dvdnav_t *self, uint8_t audio_mum, audio_attr_t *audio_attr);
/*
* Converts a *physical* (MPEG) subpicture stream id into a logical stream number.
*/
int8_t dvdnav_get_spu_logical_stream(dvdnav_t *self, uint8_t subp_num);
#define HAVE_GET_SPU_ATTR
/*
* Get spu attr
*/
dvdnav_status_t dvdnav_get_spu_attr(dvdnav_t *self, uint8_t audio_mum, subp_attr_t *subp_attr);
/*
* Get active audio stream.
*/
int8_t dvdnav_get_active_audio_stream(dvdnav_t *self);
/*
* Get active spu stream.
*/
int8_t dvdnav_get_active_spu_stream(dvdnav_t *self);
/*
* Get the set of user operations that are currently prohibited.
* There are potentially new restrictions right after
* DVDNAV_CHANNEL_HOP and DVDNAV_NAV_PACKET.
*/
user_ops_t dvdnav_get_restrictions(dvdnav_t *self);
/*********************************************************************
* multiple angles *
*********************************************************************/
/*
* The libdvdnav library abstracts away the difference between seamless and
* non-seamless angles. From the point of view of the programmer you just set the
* angle number and all is well in the world. You will always see only the
* selected angle coming from the get_next_block functions.
*
* Note:
* It is quite possible that some tremendously strange DVD feature might change the
* angle number from under you. Generally you should always view the results from
* dvdnav_get_angle_info() as definitive only up to the next time you call
* dvdnav_get_next_block().
*/
/*
* Sets the current angle. If you try to follow a non existent angle
* the call fails.
*/
dvdnav_status_t dvdnav_angle_change(dvdnav_t *self, int32_t angle);
/*
* Returns the current angle and number of angles present.
*/
dvdnav_status_t dvdnav_get_angle_info(dvdnav_t *self, int32_t *current_angle,
int32_t *number_of_angles);
/*********************************************************************
* domain queries *
*********************************************************************/
/*
* Are we in the First Play domain?
*/
int8_t dvdnav_is_domain_fp(dvdnav_t *self);
/*
* Are we in the Video management Menu domain?
*/
int8_t dvdnav_is_domain_vmgm(dvdnav_t *self);
/*
* Are we in the Video Title Menu domain?
*/
int8_t dvdnav_is_domain_vtsm(dvdnav_t *self);
/*
* Are we in the Video Title Set domain?
*/
int8_t dvdnav_is_domain_vts(dvdnav_t *self);
#ifdef __cplusplus
}
#endif
#endif /* LIBDVDNAV_DVDNAV_H */

236
src/dvdnav/dvdnav_events.h Normal file
View File

@ -0,0 +1,236 @@
/*
* Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net>
*
* This file is part of libdvdnav, a DVD navigation library.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* This header defines events and event types
*/
#ifndef LIBDVDNAV_DVDNAV_EVENTS_H
#define LIBDVDNAV_DVDNAV_EVENTS_H
/*
* DVDNAV_BLOCK_OK
*
* A regular data block from the DVD has been returned.
* This one should be demuxed and decoded for playback.
*/
#define DVDNAV_BLOCK_OK 0
/*
* DVDNAV_NOP
*
* Just ignore this.
*/
#define DVDNAV_NOP 1
/*
* DVDNAV_STILL_FRAME
*
* We have reached a still frame. The player application should wait
* the amount of time specified by the still's length while still handling
* user input to make menus and other interactive stills work.
* The last delivered frame should be kept showing.
* Once the still has timed out, call dvdnav_skip_still().
* A length of 0xff means an infinite still which has to be skipped
* indirectly by some user interaction.
*/
#define DVDNAV_STILL_FRAME 2
typedef struct {
/* The length (in seconds) the still frame should be displayed for,
* or 0xff if infinite. */
int length;
} dvdnav_still_event_t;
/*
* DVDNAV_SPU_STREAM_CHANGE
*
* Inform the SPU decoding/overlaying engine to switch SPU channels.
*/
#define DVDNAV_SPU_STREAM_CHANGE 3
typedef struct {
/* The physical (MPEG) stream number for widescreen SPU display.
* Use this, if you blend the SPU on an anamorphic image before
* unsqueezing it. */
int physical_wide;
/* The physical (MPEG) stream number for letterboxed display.
* Use this, if you blend the SPU on an anamorphic image after
* unsqueezing it. */
int physical_letterbox;
/* The physical (MPEG) stream number for pan&scan display.
* Use this, if you blend the SPU on an anamorphic image after
* unsqueezing it the pan&scan way. */
int physical_pan_scan;
/* The logical (DVD) stream number. */
int logical;
} dvdnav_spu_stream_change_event_t;
/*
* DVDNAV_AUDIO_STREAM_CHANGE
*
* Inform the audio decoder to switch channels.
*/
#define DVDNAV_AUDIO_STREAM_CHANGE 4
typedef struct {
/* The physical (MPEG) stream number. */
int physical;
/* The logical (DVD) stream number. */
int logical;
} dvdnav_audio_stream_change_event_t;
/*
* DVDNAV_VTS_CHANGE
*
* Some status information like video aspect and video scale permissions do
* not change inside a VTS. Therefore this event can be used to query such
* information only when necessary and update the decoding/displaying
* accordingly.
*/
#define DVDNAV_VTS_CHANGE 5
typedef struct {
int old_vtsN; /* the old VTS number */
DVDDomain_t old_domain; /* the old domain */
int new_vtsN; /* the new VTS number */
DVDDomain_t new_domain; /* the new domain */
} dvdnav_vts_change_event_t;
/*
* DVDNAV_CELL_CHANGE
*
* Some status information like the current Title and Part numbers do not
* change inside a cell. Therefore this event can be used to query such
* information only when necessary and update the decoding/displaying
* accordingly.
* Some useful information for accurate time display is also reported
* together with this event.
*/
#define DVDNAV_CELL_CHANGE 6
typedef struct {
int cellN; /* the new cell number */
int pgN; /* the current program number */
int64_t cell_length; /* the length of the current cell in sectors */
int64_t pg_length; /* the length of the current program in sectors */
int64_t pgc_length; /* the length of the current program chain in PTS ticks */
int64_t cell_start; /* the start offset of the current cell relatively to the PGC in sectors */
int64_t pg_start; /* the start offset of the current PG relatively to the PGC in sectors */
} dvdnav_cell_change_event_t;
/*
* DVDNAV_NAV_PACKET
*
* NAV packets are useful for various purposes. They define the button
* highlight areas and VM commands of DVD menus, so they should in any
* case be sent to the SPU decoder/overlaying engine for the menus to work.
* NAV packets also provide a way to detect PTS discontinuities, because
* they carry the start and end PTS values for the current VOBU.
* (pci.vobu_s_ptm and pci.vobu_e_ptm) Whenever the start PTS of the
* current NAV does not match the end PTS of the previous NAV, a PTS
* discontinuity has occured.
* NAV packets can also be used for time display, because they are
* timestamped relatively to the current Cell.
*/
#define DVDNAV_NAV_PACKET 7
/*
* DVDNAV_STOP
*
* Applications should end playback here. A subsequent dvdnav_get_next_block()
* call will restart the VM from the beginning of the DVD.
*/
#define DVDNAV_STOP 8
/*
* DVDNAV_HIGHLIGHT
*
* The current button highlight changed. Inform the overlaying engine to
* highlight a different button. Please note, that at the moment only mode 1
* highlights are reported this way. That means, when the button highlight
* has been moved around by some function call, you will receive an event
* telling you the new button. But when a button gets activated, you have
* to handle the mode 2 highlighting (that is some different colour the
* button turns to on activation) in your application.
*/
#define DVDNAV_HIGHLIGHT 9
typedef struct {
/* highlight mode: 0 - hide, 1 - show, 2 - activate, currently always 1 */
int display;
/* FIXME: these fields are currently not set */
uint32_t palette; /* The CLUT entries for the highlight palette
(4-bits per entry -> 4 entries) */
uint16_t sx,sy,ex,ey; /* The start/end x,y positions */
uint32_t pts; /* Highlight PTS to match with SPU */
/* button number for the SPU decoder/overlaying engine */
uint32_t buttonN;
} dvdnav_highlight_event_t;
/*
* DVDNAV_SPU_CLUT_CHANGE
*
* Inform the SPU decoder/overlaying engine to update its colour lookup table.
* The CLUT is given as 16 uint32_t's in the buffer.
*/
#define DVDNAV_SPU_CLUT_CHANGE 10
/*
* DVDNAV_HOP_CHANNEL
*
* A non-seamless operation has been performed. Applications can drop all
* their internal fifo's content, which will speed up the response.
*/
#define DVDNAV_HOP_CHANNEL 12
/*
* DVDNAV_WAIT
*
* We have reached a point in DVD playback, where timing is critical.
* Player application with internal fifos can introduce state
* inconsistencies, because libdvdnav is always the fifo's length
* ahead in the stream compared to what the application sees.
* Such applications should wait until their fifos are empty
* when they receive this type of event.
* Once this is achieved, call dvdnav_skip_wait().
*/
#define DVDNAV_WAIT 13
#endif /* LIBDVDNAV_DVDNAV_EVENTS_H */

242
src/dvdnav_internal.h Normal file
View File

@ -0,0 +1,242 @@
/*
* Copyright (C) 2001-2004 Rich Wareham <richwareham@users.sourceforge.net>
*
* This file is part of libdvdnav, a DVD navigation library.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef LIBDVDNAV_DVDNAV_INTERNAL_H
#define LIBDVDNAV_DVDNAV_INTERNAL_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef WIN32
/* pthread_mutex_* wrapper for win32 */
#include <windows.h>
#include <process.h>
typedef CRITICAL_SECTION pthread_mutex_t;
#define pthread_mutex_init(a, b) InitializeCriticalSection(a)
#define pthread_mutex_lock(a) EnterCriticalSection(a)
#define pthread_mutex_unlock(a) LeaveCriticalSection(a)
#define pthread_mutex_destroy(a) DeleteCriticalSection(a)
#ifndef HAVE_GETTIMEOFDAY
/* replacement gettimeofday implementation */
#include <sys/timeb.h>
static inline int _private_gettimeofday( struct timeval *tv, void *tz )
{
struct timeb t;
ftime( &t );
tv->tv_sec = t.time;
tv->tv_usec = t.millitm * 1000;
return 0;
}
#define gettimeofday(TV, TZ) _private_gettimeofday((TV), (TZ))
#endif
#include <io.h> /* read() */
#define lseek64 _lseeki64
#else
#include <pthread.h>
#endif /* WIN32 */
#ifdef __ANDROID__
# undef lseek
# define lseek lseek64
# undef off_t
# define off_t off64_t
#endif
/* where should libdvdnav write its messages (stdout/stderr) */
#define MSG_OUT stderr
/* Maximum length of an error string */
#define MAX_ERR_LEN 255
#ifndef DVD_VIDEO_LB_LEN
#define DVD_VIDEO_LB_LEN 2048
#endif
typedef enum {
DSI_ILVU_PRE = 1 << 15, /* set during the last 3 VOBU preceeding an interleaved block. */
DSI_ILVU_BLOCK = 1 << 14, /* set for all VOBU in an interleaved block */
DSI_ILVU_FIRST = 1 << 13, /* set for the first VOBU for a given angle or scene within a ILVU, or the first VOBU in the preparation (PREU) sequence */
DSI_ILVU_LAST = 1 << 12, /* set for the last VOBU for a given angle or scene within a ILVU, or the last VOBU in the preparation (PREU) sequence */
DSI_ILVU_MASK = 0xf000
} DSI_ILVU;
typedef struct read_cache_s read_cache_t;
/*
* These are defined here because they are
* not in ifo_types.h, they maybe one day
*/
#ifndef audio_status_t
typedef struct {
#ifdef WORDS_BIGENDIAN
unsigned int available : 1;
unsigned int zero1 : 4;
unsigned int stream_number : 3;
uint8_t zero2;
#else
uint8_t zero2;
unsigned int stream_number : 3;
unsigned int zero1 : 4;
unsigned int available : 1;
#endif
} ATTRIBUTE_PACKED audio_status_t;
#endif
#ifndef spu_status_t
typedef struct {
#ifdef WORDS_BIGENDIAN
unsigned int available : 1;
unsigned int zero1 : 2;
unsigned int stream_number_4_3 : 5;
unsigned int zero2 : 3;
unsigned int stream_number_wide : 5;
unsigned int zero3 : 3;
unsigned int stream_number_letterbox : 5;
unsigned int zero4 : 3;
unsigned int stream_number_pan_scan : 5;
#else
unsigned int stream_number_pan_scan : 5;
unsigned int zero4 : 3;
unsigned int stream_number_letterbox : 5;
unsigned int zero3 : 3;
unsigned int stream_number_wide : 5;
unsigned int zero2 : 3;
unsigned int stream_number_4_3 : 5;
unsigned int zero1 : 2;
unsigned int available : 1;
#endif
} ATTRIBUTE_PACKED spu_status_t;
#endif
/*
* Describes a given time, and the closest sector, vobu and tmap index
*/
typedef struct {
uint64_t time;
uint32_t sector;
uint32_t vobu_idx;
int32_t tmap_idx;
} dvdnav_pos_data_t;
/*
* Encapsulates cell data
*/
typedef struct {
int32_t idx;
dvdnav_pos_data_t *bgn;
dvdnav_pos_data_t *end;
} dvdnav_cell_data_t;
/*
* Encapsulates common variables used by internal functions of jump_to_time
*/
typedef struct {
vobu_admap_t *admap;
int32_t admap_len;
vts_tmap_t *tmap;
int32_t tmap_len;
int32_t tmap_interval;
} dvdnav_jump_args_t;
/*
* Utility constants for jump_to_time
*/
#define TMAP_IDX_EDGE_BGN -1
#define TMAP_IDX_EDGE_END -2
#define JUMP_MODE_TIME_AFTER 1
#define JUMP_MODE_TIME_DEFAULT 0
#define JUMP_MODE_TIME_BEFORE -1
typedef struct dvdnav_vobu_s {
int32_t vobu_start; /* Logical Absolute. MAX needed is 0x300000 */
int32_t vobu_length;
int32_t blockN; /* Relative offset */
int32_t vobu_next; /* Relative offset */
} dvdnav_vobu_t;
/** The main DVDNAV type **/
struct dvdnav_s {
/* General data */
char *path; /* Path to DVD device/dir */
dvd_file_t *file; /* Currently opened file */
/* Position data */
vm_position_t position_next;
vm_position_t position_current;
dvdnav_vobu_t vobu;
/* NAV data */
pci_t pci;
dsi_t dsi;
uint32_t last_cmd_nav_lbn; /* detects when a command is issued on an already left NAV */
/* Flags */
int skip_still; /* Set when skipping a still */
int sync_wait; /* applications should wait till they are in sync with us */
int sync_wait_skip; /* Set when skipping wait state */
int spu_clut_changed; /* The SPU CLUT changed */
int started; /* vm_start has been called? */
int use_read_ahead; /* 1 - use read-ahead cache, 0 - don't */
int pgc_based; /* positioning works PGC based instead of PG based */
int cur_cell_time; /* time expired since the beginning of the current cell, read from the dsi */
/* VM */
vm_t *vm;
pthread_mutex_t vm_lock;
/* Read-ahead cache */
read_cache_t *cache;
/* Errors */
char err_str[MAX_ERR_LEN];
};
/** HELPER FUNCTIONS **/
/* converts a dvd_time_t to PTS ticks */
int64_t dvdnav_convert_time(dvd_time_t *time);
/** USEFUL MACROS **/
#ifdef __GNUC__
#define printerrf(format, args...) \
do { if (this) snprintf(this->err_str, MAX_ERR_LEN, format, ## args); } while (0)
#else
#ifdef _MSC_VER
#define printerrf(str) \
do { if (this) snprintf(this->err_str, MAX_ERR_LEN, str); } while (0)
#else
#define printerrf(...) \
do { if (this) snprintf(this->err_str, MAX_ERR_LEN, __VA_ARGS__); } while (0)
#endif /* WIN32 */
#endif
#define printerr(str) \
do { if (this) strncpy(this->err_str, str, MAX_ERR_LEN - 1); } while (0)
#endif /* LIBDVDNAV_DVDNAV_INTERNAL_H */

514
src/highlight.c Normal file
View File

@ -0,0 +1,514 @@
/*
* Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net>
*
* This file is part of libdvdnav, a DVD navigation library.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <assert.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <sys/time.h>
#include <dvdread/nav_types.h>
#include "dvdnav/dvdnav.h"
#include "vm/decoder.h"
#include "vm/vm.h"
#include "vm/vmcmd.h"
#include "dvdnav_internal.h"
/*
#define BUTTON_TESTING
*/
#ifdef BUTTON_TESTING
#include <dvdread/nav_print.h>
static void print_time(dvd_time_t *dtime) {
const char *rate;
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);
fprintf(MSG_OUT,"%02x:%02x:%02x.%02x",
dtime->hour,
dtime->minute,
dtime->second,
dtime->frame_u & 0x3f);
switch((dtime->frame_u & 0xc0) >> 6) {
case 1:
rate = "25.00";
break;
case 3:
rate = "29.97";
break;
default:
rate = "(please send a bug report)";
break;
}
fprintf(MSG_OUT," @ %s fps", rate);
}
static void nav_print_PCI_GI(pci_gi_t *pci_gi) {
int32_t i;
fprintf(MSG_OUT,"libdvdnav: pci_gi:\n");
fprintf(MSG_OUT,"libdvdnav: nv_pck_lbn 0x%08x\n", pci_gi->nv_pck_lbn);
fprintf(MSG_OUT,"libdvdnav: vobu_cat 0x%04x\n", pci_gi->vobu_cat);
fprintf(MSG_OUT,"libdvdnav: vobu_uop_ctl 0x%08x\n", *(uint32_t*)&pci_gi->vobu_uop_ctl);
fprintf(MSG_OUT,"libdvdnav: vobu_s_ptm 0x%08x\n", pci_gi->vobu_s_ptm);
fprintf(MSG_OUT,"libdvdnav: vobu_e_ptm 0x%08x\n", pci_gi->vobu_e_ptm);
fprintf(MSG_OUT,"libdvdnav: vobu_se_e_ptm 0x%08x\n", pci_gi->vobu_se_e_ptm);
fprintf(MSG_OUT,"libdvdnav: e_eltm ");
print_time(&pci_gi->e_eltm);
fprintf(MSG_OUT,"\n");
fprintf(MSG_OUT,"libdvdnav: vobu_isrc \"");
for(i = 0; i < 32; i++) {
char c = pci_gi->vobu_isrc[i];
if((c >= ' ') && (c <= '~'))
fprintf(MSG_OUT,"%c", c);
else
fprintf(MSG_OUT,".");
}
fprintf(MSG_OUT,"\"\n");
}
static void nav_print_NSML_AGLI(nsml_agli_t *nsml_agli) {
int32_t i, j = 0;
for(i = 0; i < 9; i++)
j |= nsml_agli->nsml_agl_dsta[i];
if(j == 0)
return;
fprintf(MSG_OUT,"libdvdnav: nsml_agli:\n");
for(i = 0; i < 9; i++)
if(nsml_agli->nsml_agl_dsta[i])
fprintf(MSG_OUT,"libdvdnav: nsml_agl_c%d_dsta 0x%08x\n", i + 1,
nsml_agli->nsml_agl_dsta[i]);
}
static void nav_print_HL_GI(hl_gi_t *hl_gi, int32_t *btngr_ns, int32_t *btn_ns) {
if((hl_gi->hli_ss & 0x03) == 0)
return;
fprintf(MSG_OUT,"libdvdnav: hl_gi:\n");
fprintf(MSG_OUT,"libdvdnav: hli_ss 0x%01x\n", hl_gi->hli_ss & 0x03);
fprintf(MSG_OUT,"libdvdnav: hli_s_ptm 0x%08x\n", hl_gi->hli_s_ptm);
fprintf(MSG_OUT,"libdvdnav: hli_e_ptm 0x%08x\n", hl_gi->hli_e_ptm);
fprintf(MSG_OUT,"libdvdnav: btn_se_e_ptm 0x%08x\n", hl_gi->btn_se_e_ptm);
*btngr_ns = hl_gi->btngr_ns;
fprintf(MSG_OUT,"libdvdnav: btngr_ns %d\n", hl_gi->btngr_ns);
fprintf(MSG_OUT,"libdvdnav: btngr%d_dsp_ty 0x%02x\n", 1, hl_gi->btngr1_dsp_ty);
fprintf(MSG_OUT,"libdvdnav: btngr%d_dsp_ty 0x%02x\n", 2, hl_gi->btngr2_dsp_ty);
fprintf(MSG_OUT,"libdvdnav: btngr%d_dsp_ty 0x%02x\n", 3, hl_gi->btngr3_dsp_ty);
fprintf(MSG_OUT,"libdvdnav: btn_ofn %d\n", hl_gi->btn_ofn);
*btn_ns = hl_gi->btn_ns;
fprintf(MSG_OUT,"libdvdnav: btn_ns %d\n", hl_gi->btn_ns);
fprintf(MSG_OUT,"libdvdnav: nsl_btn_ns %d\n", hl_gi->nsl_btn_ns);
fprintf(MSG_OUT,"libdvdnav: fosl_btnn %d\n", hl_gi->fosl_btnn);
fprintf(MSG_OUT,"libdvdnav: foac_btnn %d\n", hl_gi->foac_btnn);
}
static void nav_print_BTN_COLIT(btn_colit_t *btn_colit) {
int32_t i, j;
j = 0;
for(i = 0; i < 6; i++)
j |= btn_colit->btn_coli[i/2][i&1];
if(j == 0)
return;
fprintf(MSG_OUT,"libdvdnav: btn_colit:\n");
for(i = 0; i < 3; i++)
for(j = 0; j < 2; j++)
fprintf(MSG_OUT,"libdvdnav: btn_cqoli %d %s_coli: %08x\n",
i, (j == 0) ? "sl" : "ac",
btn_colit->btn_coli[i][j]);
}
static void nav_print_BTNIT(btni_t *btni_table, int32_t btngr_ns, int32_t btn_ns) {
int32_t i, j, k;
fprintf(MSG_OUT,"libdvdnav: btnit:\n");
fprintf(MSG_OUT,"libdvdnav: btngr_ns: %i\n", btngr_ns);
fprintf(MSG_OUT,"libdvdnav: btn_ns: %i\n", btn_ns);
if(btngr_ns == 0)
return;
for(i = 0; i < btngr_ns; i++) {
for(j = 0; j < (36 / btngr_ns); j++) {
if(j < btn_ns) {
btni_t *btni = &btni_table[(36 / btngr_ns) * i + j];
fprintf(MSG_OUT,"libdvdnav: group %d btni %d: ", i+1, j+1);
fprintf(MSG_OUT,"btn_coln %d, auto_action_mode %d\n",
btni->btn_coln, btni->auto_action_mode);
fprintf(MSG_OUT,"libdvdnav: coords (%d, %d) .. (%d, %d)\n",
btni->x_start, btni->y_start, btni->x_end, btni->y_end);
fprintf(MSG_OUT,"libdvdnav: up %d, ", btni->up);
fprintf(MSG_OUT,"down %d, ", btni->down);
fprintf(MSG_OUT,"left %d, ", btni->left);
fprintf(MSG_OUT,"right %d\n", btni->right);
for(k = 0; k < 8; k++) {
fprintf(MSG_OUT, "libdvdnav: %02x ", btni->cmd.bytes[k]);
}
fprintf(MSG_OUT, "| ");
#ifdef TRACE
vm_print_mnemonic(&btni->cmd);
#endif
fprintf(MSG_OUT, "\n");
}
}
}
}
static void nav_print_HLI(hli_t *hli) {
int32_t btngr_ns = 0, btn_ns = 0;
fprintf(MSG_OUT,"libdvdnav: hli:\n");
nav_print_HL_GI(&hli->hl_gi, & btngr_ns, & btn_ns);
nav_print_BTN_COLIT(&hli->btn_colit);
nav_print_BTNIT(hli->btnit, btngr_ns, btn_ns);
}
void nav_print_PCI(pci_t *pci) {
fprintf(MSG_OUT,"libdvdnav: pci packet:\n");
nav_print_PCI_GI(&pci->pci_gi);
nav_print_NSML_AGLI(&pci->nsml_agli);
nav_print_HLI(&pci->hli);
}
#endif
/* Highlighting API calls */
dvdnav_status_t dvdnav_get_current_highlight(dvdnav_t *this, int32_t *button) {
/* Simply return the appropriate value based on the SPRM */
if(((*button) = this->position_current.button) == -1)
(*button) = this->vm->state.HL_BTNN_REG >> 10;
return DVDNAV_STATUS_OK;
}
static btni_t *get_current_button(dvdnav_t *this, pci_t *pci) {
int32_t button = 0;
if(!pci->hli.hl_gi.hli_ss) {
printerr("Not in a menu.");
return NULL;
}
if(this->last_cmd_nav_lbn == pci->pci_gi.nv_pck_lbn) {
printerr("This NAV has already been left.");
return NULL;
}
button = this->vm->state.HL_BTNN_REG >> 10;
#ifdef BUTTON_TESTING
nav_print_PCI(pci);
#endif
return &(pci->hli.btnit[button-1]);
}
static dvdnav_status_t button_auto_action(dvdnav_t *this, pci_t *pci) {
btni_t *button_ptr;
if ((button_ptr = get_current_button(this, pci)) == NULL)
return DVDNAV_STATUS_ERR;
if (button_ptr->auto_action_mode)
return dvdnav_button_activate(this, pci);
return DVDNAV_STATUS_OK;
}
dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *this, pci_t *pci) {
btni_t *button_ptr;
if(!(button_ptr = get_current_button(this, pci)))
return DVDNAV_STATUS_ERR;
dvdnav_button_select(this, pci, button_ptr->up);
return button_auto_action(this, pci);
}
dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *this, pci_t *pci) {
btni_t *button_ptr;
if(!(button_ptr = get_current_button(this, pci)))
return DVDNAV_STATUS_ERR;
dvdnav_button_select(this, pci, button_ptr->down);
return button_auto_action(this, pci);
}
dvdnav_status_t dvdnav_right_button_select(dvdnav_t *this, pci_t *pci) {
btni_t *button_ptr;
if(!(button_ptr = get_current_button(this, pci)))
return DVDNAV_STATUS_ERR;
dvdnav_button_select(this, pci, button_ptr->right);
return button_auto_action(this, pci);
}
dvdnav_status_t dvdnav_left_button_select(dvdnav_t *this, pci_t *pci) {
btni_t *button_ptr;
if(!(button_ptr = get_current_button(this, pci)))
return DVDNAV_STATUS_ERR;
dvdnav_button_select(this, pci, button_ptr->left);
return button_auto_action(this, pci);
}
dvdnav_status_t dvdnav_get_highlight_area(pci_t *nav_pci , int32_t button, int32_t mode,
dvdnav_highlight_area_t *highlight) {
btni_t *button_ptr;
#ifdef BUTTON_TESTING
fprintf(MSG_OUT, "libdvdnav: Button get_highlight_area %i\n", button);
#endif
if(!nav_pci->hli.hl_gi.hli_ss)
return DVDNAV_STATUS_ERR;
if((button <= 0) || (button > nav_pci->hli.hl_gi.btn_ns))
return DVDNAV_STATUS_ERR;
button_ptr = &nav_pci->hli.btnit[button-1];
highlight->sx = button_ptr->x_start;
highlight->sy = button_ptr->y_start;
highlight->ex = button_ptr->x_end;
highlight->ey = button_ptr->y_end;
if(button_ptr->btn_coln != 0) {
highlight->palette = nav_pci->hli.btn_colit.btn_coli[button_ptr->btn_coln-1][mode];
} else {
highlight->palette = 0;
}
highlight->pts = nav_pci->hli.hl_gi.hli_s_ptm;
highlight->buttonN = button;
#ifdef BUTTON_TESTING
fprintf(MSG_OUT, "libdvdnav: highlight: Highlight area is (%u,%u)-(%u,%u), display = %i, button = %u\n",
button_ptr->x_start, button_ptr->y_start,
button_ptr->x_end, button_ptr->y_end,
1,
button);
#endif
return DVDNAV_STATUS_OK;
}
dvdnav_status_t dvdnav_button_activate(dvdnav_t *this, pci_t *pci) {
int32_t button;
btni_t *button_ptr = NULL;
if(!pci->hli.hl_gi.hli_ss) {
printerr("Not in a menu.");
return DVDNAV_STATUS_ERR;
}
if(this->last_cmd_nav_lbn == pci->pci_gi.nv_pck_lbn) {
printerr("This NAV has already been left.");
return DVDNAV_STATUS_ERR;
}
pthread_mutex_lock(&this->vm_lock);
if(!this->vm->state.pgc) {
printerr("No current PGC.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
button = this->vm->state.HL_BTNN_REG >> 10;
if((button <= 0) || (button > pci->hli.hl_gi.btn_ns)) {
/* Special code to handle still menus with no buttons.
* The navigation is expected to report to the application that a STILL is
* underway. In turn, the application is supposed to report to the user
* that the playback is paused. The user is then expected to undo the pause,
* ie: hit play. At that point, the navigation should release the still and
* go to the next Cell.
* Explanation by Mathieu Lacage <mathieu_lacage@realmagic.fr>
* Code added by jcdutton.
*/
if (this->position_current.still != 0) {
/* In still, but no buttons. */
vm_get_next_cell(this->vm);
this->position_current.still = 0;
this->sync_wait = 0;
this->last_cmd_nav_lbn = pci->pci_gi.nv_pck_lbn;
pthread_mutex_unlock(&this->vm_lock);
/* clear error message */
printerr("");
return DVDNAV_STATUS_OK;
}
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
if ((button_ptr = get_current_button(this, pci)) == NULL) {
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
/* Finally, make the VM execute the appropriate code and probably
* schedule a jump */
#ifdef BUTTON_TESTING
fprintf(MSG_OUT, "libdvdnav: Evaluating Button Activation commands.\n");
#endif
if(vm_exec_cmd(this->vm, &(button_ptr->cmd)) == 1) {
/* Command caused a jump */
this->vm->hop_channel++;
this->position_current.still = 0;
this->last_cmd_nav_lbn = pci->pci_gi.nv_pck_lbn;
}
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_OK;
}
dvdnav_status_t dvdnav_button_activate_cmd(dvdnav_t *this, int32_t button, vm_cmd_t *cmd)
{
pthread_mutex_lock(&this->vm_lock);
if(!this->vm->state.pgc) {
printerr("No current PGC.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
/* make the VM execute the appropriate code and probably
* schedule a jump */
#ifdef BUTTON_TESTING
fprintf(MSG_OUT, "libdvdnav: dvdnav_button_activate_cmd: Evaluating Button Activation commands.\n");
#endif
if(button > 0) {
this->vm->state.HL_BTNN_REG = (button << 10);
if(vm_exec_cmd(this->vm, cmd) == 1) {
/* Command caused a jump */
this->vm->hop_channel++;
}
}
/* Always remove still, because some still menus have no buttons. */
this->position_current.still = 0;
this->sync_wait = 0;
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_OK;
}
dvdnav_status_t dvdnav_button_select(dvdnav_t *this, pci_t *pci, int32_t button) {
if(!pci->hli.hl_gi.hli_ss) {
printerr("Not in a menu.");
return DVDNAV_STATUS_ERR;
}
if(this->last_cmd_nav_lbn == pci->pci_gi.nv_pck_lbn) {
printerr("This NAV has already been left.");
return DVDNAV_STATUS_ERR;
}
#ifdef BUTTON_TESTING
fprintf(MSG_OUT, "libdvdnav: Button select %i\n", button);
#endif
if((button <= 0) || (button > pci->hli.hl_gi.btn_ns)) {
printerr("Button does not exist.");
return DVDNAV_STATUS_ERR;
}
this->vm->state.HL_BTNN_REG = (button << 10);
this->position_current.button = -1; /* Force Highlight change */
return DVDNAV_STATUS_OK;
}
dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *this, pci_t *pci,
int32_t button) {
/* A trivial function */
if(dvdnav_button_select(this, pci, button) != DVDNAV_STATUS_ERR)
return dvdnav_button_activate(this, pci);
return DVDNAV_STATUS_ERR;
}
dvdnav_status_t dvdnav_mouse_select(dvdnav_t *this, pci_t *pci, int32_t x, int32_t y) {
int32_t button, cur_button;
int32_t best,dist,d;
int32_t mx,my,dx,dy;
if(!pci->hli.hl_gi.hli_ss) {
printerr("Not in a menu.");
return DVDNAV_STATUS_ERR;
}
if(this->last_cmd_nav_lbn == pci->pci_gi.nv_pck_lbn) {
printerr("This NAV has already been left.");
return DVDNAV_STATUS_ERR;
}
cur_button = this->vm->state.HL_BTNN_REG >> 10;
best = 0;
dist = 0x08000000; /* >> than (720*720)+(567*567); */
/* Loop through all buttons */
for(button = 1; button <= pci->hli.hl_gi.btn_ns; button++) {
btni_t *button_ptr = &(pci->hli.btnit[button-1]);
if((x >= button_ptr->x_start) && (x <= button_ptr->x_end) &&
(y >= button_ptr->y_start) && (y <= button_ptr->y_end)) {
mx = (button_ptr->x_start + button_ptr->x_end)/2;
my = (button_ptr->y_start + button_ptr->y_end)/2;
dx = mx - x;
dy = my - y;
d = (dx*dx) + (dy*dy);
/* If the mouse is within the button and the mouse is closer
* to the center of this button then it is the best choice. */
if(d < dist) {
dist = d;
best = button;
}
}
}
/* As an efficiency measure, only re-select the button
* if it is different to the previously selected one. */
if (best != 0 && best != cur_button)
dvdnav_button_select(this, pci, best);
/* return DVDNAV_STATUS_OK only if we actually found a matching button */
return best ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR;
}
dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *this, pci_t *pci, int32_t x, int32_t y) {
/* A trivial function */
if(dvdnav_mouse_select(this, pci, x,y) != DVDNAV_STATUS_ERR)
return dvdnav_button_activate(this, pci);
return DVDNAV_STATUS_ERR;
}

282
src/navigation.c Normal file
View File

@ -0,0 +1,282 @@
/*
* Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net>
*
* This file is part of libdvdnav, a DVD navigation library.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <inttypes.h>
#include <limits.h>
#include <string.h>
#include <sys/time.h>
#include "dvdnav/dvdnav.h"
#include <dvdread/nav_types.h>
#include <dvdread/ifo_types.h>
#include "vm/decoder.h"
#include "vm/vm.h"
#include "dvdnav_internal.h"
/* Navigation API calls */
dvdnav_status_t dvdnav_still_skip(dvdnav_t *this) {
pthread_mutex_lock(&this->vm_lock);
this->position_current.still = 0;
pthread_mutex_unlock(&this->vm_lock);
this->skip_still = 1;
this->sync_wait = 0;
this->sync_wait_skip = 1;
return DVDNAV_STATUS_OK;
}
dvdnav_status_t dvdnav_wait_skip(dvdnav_t *this) {
this->sync_wait = 0;
this->sync_wait_skip = 1;
return DVDNAV_STATUS_OK;
}
dvdnav_status_t dvdnav_get_number_of_titles(dvdnav_t *this, int32_t *titles) {
if (!this->vm->vmgi) {
printerr("Bad VM state.");
return DVDNAV_STATUS_ERR;
}
(*titles) = vm_get_vmgi(this->vm)->tt_srpt->nr_of_srpts;
return DVDNAV_STATUS_OK;
}
dvdnav_status_t dvdnav_get_number_of_parts(dvdnav_t *this, int32_t title, int32_t *parts) {
if (!this->vm->vmgi) {
printerr("Bad VM state.");
return DVDNAV_STATUS_ERR;
}
if ((title < 1) || (title > vm_get_vmgi(this->vm)->tt_srpt->nr_of_srpts) ) {
printerr("Passed a title number out of range.");
return DVDNAV_STATUS_ERR;
}
(*parts) = vm_get_vmgi(this->vm)->tt_srpt->title[title-1].nr_of_ptts;
return DVDNAV_STATUS_OK;
}
dvdnav_status_t dvdnav_current_title_info(dvdnav_t *this, int32_t *title, int32_t *part) {
int32_t retval;
pthread_mutex_lock(&this->vm_lock);
if (!this->vm->vtsi || !this->vm->vmgi) {
printerr("Bad VM state.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
if (!this->started) {
printerr("Virtual DVD machine not started.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
if (!this->vm->state.pgc) {
printerr("No current PGC.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
if ( (this->vm->state.domain == DVD_DOMAIN_VTSMenu)
|| (this->vm->state.domain == DVD_DOMAIN_VMGM) ) {
/* Get current Menu ID: into *part. */
if(! vm_get_current_menu(this->vm, part)) {
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
if (*part > -1) {
*title = 0;
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_OK;
}
}
if (this->vm->state.domain == DVD_DOMAIN_VTSTitle) {
retval = vm_get_current_title_part(this->vm, title, part);
pthread_mutex_unlock(&this->vm_lock);
return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR;
}
printerr("Not in a title or menu.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
dvdnav_status_t dvdnav_current_title_program(dvdnav_t *this, int32_t *title, int32_t *pgcn, int32_t *pgn) {
int32_t retval;
int32_t part;
pthread_mutex_lock(&this->vm_lock);
if (!this->vm->vtsi || !this->vm->vmgi) {
printerr("Bad VM state.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
if (!this->started) {
printerr("Virtual DVD machine not started.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
if (!this->vm->state.pgc) {
printerr("No current PGC.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
if ( (this->vm->state.domain == DVD_DOMAIN_VTSMenu)
|| (this->vm->state.domain == DVD_DOMAIN_VMGM) ) {
/* Get current Menu ID: into *part. */
if(! vm_get_current_menu(this->vm, &part)) {
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
if (part > -1) {
*title = 0;
*pgcn = this->vm->state.pgcN;
*pgn = this->vm->state.pgN;
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_OK;
}
}
if (this->vm->state.domain == DVD_DOMAIN_VTSTitle) {
retval = vm_get_current_title_part(this->vm, title, &part);
*pgcn = this->vm->state.pgcN;
*pgn = this->vm->state.pgN;
pthread_mutex_unlock(&this->vm_lock);
return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR;
}
printerr("Not in a title or menu.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
dvdnav_status_t dvdnav_title_play(dvdnav_t *this, int32_t title) {
return dvdnav_part_play(this, title, 1);
}
dvdnav_status_t dvdnav_program_play(dvdnav_t *this, int32_t title, int32_t pgcn, int32_t pgn) {
int32_t retval;
pthread_mutex_lock(&this->vm_lock);
if (!this->vm->vmgi) {
printerr("Bad VM state.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
if (!this->started) {
/* don't report an error but be nice */
vm_start(this->vm);
this->started = 1;
}
if (!this->vm->state.pgc) {
printerr("No current PGC.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
if((title < 1) || (title > this->vm->vmgi->tt_srpt->nr_of_srpts)) {
printerr("Title out of range.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
retval = vm_jump_title_program(this->vm, title, pgcn, pgn);
if (retval)
this->vm->hop_channel++;
pthread_mutex_unlock(&this->vm_lock);
return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR;
}
dvdnav_status_t dvdnav_part_play(dvdnav_t *this, int32_t title, int32_t part) {
int32_t retval;
pthread_mutex_lock(&this->vm_lock);
if (!this->vm->vmgi) {
printerr("Bad VM state.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
if (!this->started) {
/* don't report an error but be nice */
vm_start(this->vm);
this->started = 1;
}
if (!this->vm->state.pgc) {
printerr("No current PGC.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
if((title < 1) || (title > this->vm->vmgi->tt_srpt->nr_of_srpts)) {
printerr("Title out of range.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
if((part < 1) || (part > this->vm->vmgi->tt_srpt->title[title-1].nr_of_ptts)) {
printerr("Part out of range.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
retval = vm_jump_title_part(this->vm, title, part);
if (retval)
this->vm->hop_channel++;
pthread_mutex_unlock(&this->vm_lock);
return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR;
}
dvdnav_status_t dvdnav_part_play_auto_stop(dvdnav_t *this, int32_t title,
int32_t part, int32_t parts_to_play) {
/* FIXME: Implement auto-stop */
if (dvdnav_part_play(this, title, part) == DVDNAV_STATUS_OK)
printerr("Not implemented yet.");
return DVDNAV_STATUS_ERR;
}
dvdnav_status_t dvdnav_time_play(dvdnav_t *this, int32_t title,
uint64_t time) {
/* FIXME: Implement */
printerr("Not implemented yet.");
return DVDNAV_STATUS_ERR;
}
dvdnav_status_t dvdnav_stop(dvdnav_t *this) {
pthread_mutex_lock(&this->vm_lock);
this->vm->stopped = 1;
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_OK;
}
dvdnav_status_t dvdnav_go_up(dvdnav_t *this) {
/* A nice easy function... delegate to the VM */
int retval;
pthread_mutex_lock(&this->vm_lock);
if (!this->vm->state.pgc) {
printerr("No current PGC.");
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_ERR;
}
retval = vm_jump_up(this->vm);
pthread_mutex_unlock(&this->vm_lock);
return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR;
}

349
src/read_cache.c Normal file
View File

@ -0,0 +1,349 @@
/*
* Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net>
* 2001-2004 the dvdnav project
*
* This file is part of libdvdnav, a DVD navigation library.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* There was a multithreaded read ahead cache in here for some time, but
* it had only been used for a short time. If you want to have a look at it,
* search the CVS attic.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <inttypes.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/time.h>
#include <time.h>
#include "dvdnav/dvdnav.h"
#include <dvdread/nav_types.h>
#include <dvdread/ifo_types.h>
#include "vm/decoder.h"
#include "vm/vm.h"
#include "dvdnav_internal.h"
#include "read_cache.h"
#define READ_CACHE_CHUNKS 10
/* all cache chunks must be memory aligned to allow use of raw devices */
#define ALIGNMENT 2048
#define READ_AHEAD_SIZE_MIN 4
#define READ_AHEAD_SIZE_MAX 512
typedef struct read_cache_chunk_s {
uint8_t *cache_buffer;
uint8_t *cache_buffer_base; /* used in malloc and free for alignment */
int32_t cache_start_sector; /* -1 means cache invalid */
int32_t cache_read_count; /* this many sectors are already read */
size_t cache_block_count; /* this many sectors will go in this chunk */
size_t cache_malloc_size;
int cache_valid;
int usage_count; /* counts how many buffers where issued from this chunk */
} read_cache_chunk_t;
struct read_cache_s {
read_cache_chunk_t chunk[READ_CACHE_CHUNKS];
int current;
int freeing; /* is set to one when we are about to dispose the cache */
uint32_t read_ahead_size;
int read_ahead_incr;
int last_sector;
pthread_mutex_t lock;
/* Bit of strange cross-linking going on here :) -- Gotta love C :) */
dvdnav_t *dvd_self;
};
/*
#define READ_CACHE_TRACE 0
*/
#ifdef __GNUC__
# if READ_CACHE_TRACE
# define dprintf(fmt, args...) fprintf(MSG_OUT, "libdvdnav: %s: "fmt, __func__ , ## args)
# else
# define dprintf(fmt, args...) /* Nowt */
# endif
#else
# if READ_CACHE_TRACE
# define dprintf(fmt, ...) fprintf(MSG_OUT, "libdvdnav: %s: "fmt, __func__ , __VA_ARGS__)
# else
#ifdef _MSC_VER
# define dprintf(fmt, str) /* Nowt */
#else
# define dprintf(fmt, ...) /* Nowt */
#endif /* _MSC_VER */
# endif
#endif
read_cache_t *dvdnav_read_cache_new(dvdnav_t* dvd_self) {
read_cache_t *self;
int i;
self = (read_cache_t *)calloc(1, sizeof(read_cache_t));
if(!self)
return NULL;
self->dvd_self = dvd_self;
self->read_ahead_size = READ_AHEAD_SIZE_MIN;
pthread_mutex_init(&self->lock, NULL);
dvdnav_read_cache_clear(self);
for (i = 0; i < READ_CACHE_CHUNKS; i++) {
self->chunk[i].cache_buffer = NULL;
self->chunk[i].usage_count = 0;
}
return self;
}
void dvdnav_read_cache_free(read_cache_t* self) {
dvdnav_t *tmp;
int i;
pthread_mutex_lock(&self->lock);
self->freeing = 1;
for (i = 0; i < READ_CACHE_CHUNKS; i++)
if (self->chunk[i].cache_buffer && self->chunk[i].usage_count == 0) {
free(self->chunk[i].cache_buffer_base);
self->chunk[i].cache_buffer = NULL;
}
pthread_mutex_unlock(&self->lock);
for (i = 0; i < READ_CACHE_CHUNKS; i++)
if (self->chunk[i].cache_buffer) return;
/* all buffers returned, free everything */
tmp = self->dvd_self;
pthread_mutex_destroy(&self->lock);
free(self);
free(tmp);
}
/* This function MUST be called whenever self->file changes. */
void dvdnav_read_cache_clear(read_cache_t *self) {
int i;
if(!self)
return;
pthread_mutex_lock(&self->lock);
for (i = 0; i < READ_CACHE_CHUNKS; i++)
self->chunk[i].cache_valid = 0;
pthread_mutex_unlock(&self->lock);
}
/* This function is called just after reading the NAV packet. */
void dvdnav_pre_cache_blocks(read_cache_t *self, int sector, size_t block_count) {
int i, use;
if(!self)
return;
if(!self->dvd_self->use_read_ahead)
return;
pthread_mutex_lock(&self->lock);
/* find a free cache chunk that best fits the required size */
use = -1;
for (i = 0; i < READ_CACHE_CHUNKS; i++)
if (self->chunk[i].usage_count == 0 && self->chunk[i].cache_buffer &&
self->chunk[i].cache_malloc_size >= block_count &&
(use == -1 || self->chunk[use].cache_malloc_size > self->chunk[i].cache_malloc_size))
use = i;
if (use == -1) {
/* we haven't found a cache chunk, so we try to reallocate an existing one */
for (i = 0; i < READ_CACHE_CHUNKS; i++)
if (self->chunk[i].usage_count == 0 && self->chunk[i].cache_buffer &&
(use == -1 || self->chunk[use].cache_malloc_size < self->chunk[i].cache_malloc_size))
use = i;
if (use >= 0) {
self->chunk[use].cache_buffer_base = realloc(self->chunk[use].cache_buffer_base,
block_count * DVD_VIDEO_LB_LEN + ALIGNMENT);
self->chunk[use].cache_buffer =
(uint8_t *)(((uintptr_t)self->chunk[use].cache_buffer_base & ~((uintptr_t)(ALIGNMENT - 1))) + ALIGNMENT);
dprintf("pre_cache DVD read realloc happened\n");
self->chunk[use].cache_malloc_size = block_count;
} else {
/* we still haven't found a cache chunk, let's allocate a new one */
for (i = 0; i < READ_CACHE_CHUNKS; i++)
if (!self->chunk[i].cache_buffer) {
use = i;
break;
}
if (use >= 0) {
/* We start with a sensible figure for the first malloc of 500 blocks.
* Some DVDs I have seen venture to 450 blocks.
* This is so that fewer realloc's happen if at all.
*/
self->chunk[i].cache_buffer_base =
malloc((block_count > 500 ? block_count : 500) * DVD_VIDEO_LB_LEN + ALIGNMENT);
self->chunk[i].cache_buffer =
(uint8_t *)(((uintptr_t)self->chunk[i].cache_buffer_base & ~((uintptr_t)(ALIGNMENT - 1))) + ALIGNMENT);
self->chunk[i].cache_malloc_size = block_count > 500 ? block_count : 500;
dprintf("pre_cache DVD read malloc %d blocks\n",
(block_count > 500 ? block_count : 500 ));
}
}
}
if (use >= 0) {
self->chunk[use].cache_start_sector = sector;
self->chunk[use].cache_block_count = block_count;
self->chunk[use].cache_read_count = 0;
self->chunk[use].cache_valid = 1;
self->current = use;
} else {
dprintf("pre_caching was impossible, no cache chunk available\n");
}
pthread_mutex_unlock(&self->lock);
}
int dvdnav_read_cache_block(read_cache_t *self, int sector, size_t block_count, uint8_t **buf) {
int i, use;
int start;
int size;
int incr;
uint8_t *read_ahead_buf;
int32_t res;
if(!self)
return 0;
use = -1;
if(self->dvd_self->use_read_ahead) {
/* first check, if sector is in current chunk */
read_cache_chunk_t cur = self->chunk[self->current];
if (cur.cache_valid && sector >= cur.cache_start_sector &&
sector <= (cur.cache_start_sector + cur.cache_read_count) &&
sector + block_count <= cur.cache_start_sector + cur.cache_block_count)
use = self->current;
else
for (i = 0; i < READ_CACHE_CHUNKS; i++)
if (self->chunk[i].cache_valid &&
sector >= self->chunk[i].cache_start_sector &&
sector <= (self->chunk[i].cache_start_sector + self->chunk[i].cache_read_count) &&
sector + block_count <= self->chunk[i].cache_start_sector + self->chunk[i].cache_block_count)
use = i;
}
if (use >= 0) {
read_cache_chunk_t *chunk;
/* Increment read-ahead size if sector follows the last sector */
if (sector == (self->last_sector + 1)) {
if (self->read_ahead_incr < READ_AHEAD_SIZE_MAX)
self->read_ahead_incr++;
} else {
self->read_ahead_size = READ_AHEAD_SIZE_MIN;
self->read_ahead_incr = 0;
}
self->last_sector = sector;
/* The following resources need to be protected by a mutex :
* self->chunk[*].cache_buffer
* self->chunk[*].cache_malloc_size
* self->chunk[*].usage_count
*/
pthread_mutex_lock(&self->lock);
chunk = &self->chunk[use];
read_ahead_buf = chunk->cache_buffer + chunk->cache_read_count * DVD_VIDEO_LB_LEN;
*buf = chunk->cache_buffer + (sector - chunk->cache_start_sector) * DVD_VIDEO_LB_LEN;
chunk->usage_count++;
pthread_mutex_unlock(&self->lock);
dprintf("libdvdnav: sector=%d, start_sector=%d, last_sector=%d\n", sector, chunk->cache_start_sector, chunk->cache_start_sector + chunk->cache_block_count);
/* read_ahead_size */
incr = self->read_ahead_incr >> 1;
if ((self->read_ahead_size + incr) > READ_AHEAD_SIZE_MAX) {
self->read_ahead_size = READ_AHEAD_SIZE_MAX;
} else {
self->read_ahead_size += incr;
}
/* real read size */
start = chunk->cache_start_sector + chunk->cache_read_count;
if (chunk->cache_read_count + self->read_ahead_size > chunk->cache_block_count) {
size = chunk->cache_block_count - chunk->cache_read_count;
} else {
size = self->read_ahead_size;
/* ensure that the sector we want will be read */
if (sector >= chunk->cache_start_sector + chunk->cache_read_count + size)
size = sector - chunk->cache_start_sector - chunk->cache_read_count;
}
dprintf("libdvdnav: read_ahead_size=%d, size=%d\n", self->read_ahead_size, size);
if (size)
chunk->cache_read_count += DVDReadBlocks(self->dvd_self->file,
start,
size,
read_ahead_buf);
res = DVD_VIDEO_LB_LEN * block_count;
} else {
if (self->dvd_self->use_read_ahead) {
dprintf("cache miss on sector %d\n", sector);
}
res = DVDReadBlocks(self->dvd_self->file,
sector,
block_count,
*buf) * DVD_VIDEO_LB_LEN;
}
return res;
}
dvdnav_status_t dvdnav_free_cache_block(dvdnav_t *self, unsigned char *buf) {
read_cache_t *cache;
int i;
if (!self)
return DVDNAV_STATUS_ERR;
cache = self->cache;
if (!cache)
return DVDNAV_STATUS_ERR;
pthread_mutex_lock(&cache->lock);
for (i = 0; i < READ_CACHE_CHUNKS; i++) {
if (cache->chunk[i].cache_buffer && buf >= cache->chunk[i].cache_buffer &&
buf < cache->chunk[i].cache_buffer + cache->chunk[i].cache_malloc_size * DVD_VIDEO_LB_LEN) {
cache->chunk[i].usage_count--;
}
}
pthread_mutex_unlock(&cache->lock);
if (cache->freeing)
/* when we want to dispose the cache, try freeing it now */
dvdnav_read_cache_free(cache);
return DVDNAV_STATUS_OK;
}

46
src/read_cache.h Normal file
View File

@ -0,0 +1,46 @@
/*
* Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net>
*
* This file is part of libdvdnav, a DVD navigation library.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef LIBDVDNAV_READ_CACHE_H
#define LIBDVDNAV_READ_CACHE_H
/* Opaque cache type -- defined in dvdnav_internal.h */
/* typedef struct read_cache_s read_cache_t; */
/* EXPERIMENTAL: Setting the following to 1 will use an experimental multi-threaded
* read-ahead cache.
*/
#define _MULTITHREAD_ 0
/* Constructor/destructors */
read_cache_t *dvdnav_read_cache_new(dvdnav_t* dvd_self);
void dvdnav_read_cache_free(read_cache_t* self);
/* This function MUST be called whenever self->file changes. */
void dvdnav_read_cache_clear(read_cache_t *self);
/* This function is called just after reading the NAV packet. */
void dvdnav_pre_cache_blocks(read_cache_t *self, int sector, size_t block_count);
/* This function will do the cache read.
* The buffer handed in must be malloced to take one dvd block.
* On a cache hit, a different buffer will be returned though.
* Those buffers must _never_ be freed. */
int dvdnav_read_cache_block(read_cache_t *self, int sector, size_t block_count, uint8_t **buf);
#endif /* LIBDVDNAV_READ_CACHE_H */

1320
src/searching.c Normal file

File diff suppressed because it is too large Load Diff

92
src/settings.c Normal file
View File

@ -0,0 +1,92 @@
/*
* Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net>
*
* This file is part of libdvdnav, a DVD navigation library.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <inttypes.h>
#include <limits.h>
#include <string.h>
#include <sys/time.h>
#include "dvdnav/dvdnav.h"
#include <dvdread/nav_types.h>
#include <dvdread/ifo_types.h>
#include "vm/decoder.h"
#include "vm/vm.h"
#include "dvdnav_internal.h"
/* Characteristics/setting API calls */
dvdnav_status_t dvdnav_get_region_mask(dvdnav_t *this, int32_t *region) {
(*region) = this->vm->state.registers.SPRM[20];
return DVDNAV_STATUS_OK;
}
dvdnav_status_t dvdnav_set_region_mask(dvdnav_t *this, int32_t mask) {
pthread_mutex_lock(&this->vm_lock);
this->vm->state.registers.SPRM[20] = (mask & 0xff);
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_OK;
}
dvdnav_status_t dvdnav_set_readahead_flag(dvdnav_t *this, int32_t use_readahead) {
this->use_read_ahead = use_readahead;
return DVDNAV_STATUS_OK;
}
dvdnav_status_t dvdnav_get_readahead_flag(dvdnav_t *this, int32_t *flag) {
(*flag) = this->use_read_ahead;
return DVDNAV_STATUS_OK;
}
static dvdnav_status_t set_language_register(dvdnav_t *this, char *code, int reg) {
if(!code[0] || !code[1]) {
printerr("Passed illegal language code.");
return DVDNAV_STATUS_ERR;
}
pthread_mutex_lock(&this->vm_lock);
this->vm->state.registers.SPRM[reg] = (code[0] << 8) | code[1];
pthread_mutex_unlock(&this->vm_lock);
return DVDNAV_STATUS_OK;
}
dvdnav_status_t dvdnav_menu_language_select(dvdnav_t *this, char *code) {
return set_language_register(this, code, 0);
}
dvdnav_status_t dvdnav_audio_language_select(dvdnav_t *this, char *code) {
return set_language_register(this, code, 16);
}
dvdnav_status_t dvdnav_spu_language_select(dvdnav_t *this, char *code) {
return set_language_register(this, code, 18);
}
dvdnav_status_t dvdnav_set_PGC_positioning_flag(dvdnav_t *this, int32_t pgc) {
this->pgc_based = pgc;
return DVDNAV_STATUS_OK;
}
dvdnav_status_t dvdnav_get_PGC_positioning_flag(dvdnav_t *this, int32_t *flag) {
(*flag) = this->pgc_based;
return DVDNAV_STATUS_OK;
}

784
src/vm/decoder.c Normal file
View File

@ -0,0 +1,784 @@
/*
* Copyright (C) 2000, 2001 Martin Norbäck, Håkan Hjort
* 2002-2004 the dvdnav project
*
* This file is part of libdvdnav, a DVD navigation library. It is modified
* from a file originally part of the Ogle DVD player.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <limits.h>
#include <string.h> /* For memset */
#include <sys/time.h>
#include <assert.h>
#include <dvdread/nav_types.h>
#include <dvdread/ifo_types.h> /* vm_cmd_t */
#include "dvdnav/dvdnav.h"
#include "decoder.h"
#include "vm.h"
#include "vmcmd.h"
#include "dvdnav_internal.h"
uint32_t vm_getbits(command_t *command, int32_t start, int32_t count) {
uint64_t result = 0;
uint64_t bit_mask = 0;
uint64_t examining = 0;
int32_t bits;
if (count == 0) return 0;
if ( ((start - count) < -1) ||
(count > 32) ||
(start > 63) ||
(count < 0) ||
(start < 0) ) {
fprintf(MSG_OUT, "libdvdnav: Bad call to vm_getbits. Parameter out of range\n");
abort();
}
/* all ones, please */
bit_mask = ~bit_mask;
bit_mask >>= 63 - start;
bits = start + 1 - count;
examining = ((bit_mask >> bits) << bits );
command->examined |= examining;
result = (command->instruction & bit_mask) >> bits;
return (uint32_t) result;
}
static uint16_t get_GPRM(registers_t* registers, uint8_t reg) {
if (registers->GPRM_mode[reg] & 0x01) {
struct timeval current_time, time_offset;
uint16_t result;
/* Counter mode */
/* fprintf(MSG_OUT, "libdvdnav: Getting counter %d\n",reg);*/
gettimeofday(&current_time, NULL);
time_offset.tv_sec = current_time.tv_sec - registers->GPRM_time[reg].tv_sec;
time_offset.tv_usec = current_time.tv_usec - registers->GPRM_time[reg].tv_usec;
if (time_offset.tv_usec < 0) {
time_offset.tv_sec--;
time_offset.tv_usec += 1000000;
}
result = (uint16_t) (time_offset.tv_sec & 0xffff);
registers->GPRM[reg]=result;
return result;
} else {
/* Register mode */
return registers->GPRM[reg];
}
}
static void set_GPRM(registers_t* registers, uint8_t reg, uint16_t value) {
if (registers->GPRM_mode[reg] & 0x01) {
struct timeval current_time;
/* Counter mode */
/* fprintf(MSG_OUT, "libdvdnav: Setting counter %d\n",reg); */
gettimeofday(&current_time, NULL);
registers->GPRM_time[reg] = current_time;
registers->GPRM_time[reg].tv_sec -= value;
}
registers->GPRM[reg] = value;
}
/* Eval register code, can either be system or general register.
SXXX_XXXX, where S is 1 if it is system register. */
static uint16_t eval_reg(command_t* command, uint8_t reg) {
if(reg & 0x80) {
if ((reg & 0x1f) == 20) {
fprintf(MSG_OUT, "libdvdnav: Suspected RCE Region Protection!!!\n");
}
return command->registers->SPRM[reg & 0x1f]; /* FIXME max 24 not 32 */
} else {
return get_GPRM(command->registers, reg & 0x0f) ;
}
}
/* Eval register or immediate data.
AAAA_AAAA BBBB_BBBB, if immediate use all 16 bits for data else use
lower eight bits for the system or general purpose register. */
static uint16_t eval_reg_or_data(command_t* command, int32_t imm, int32_t start) {
if(imm) { /* immediate */
return vm_getbits(command, start, 16);
} else {
return eval_reg(command, vm_getbits(command, (start - 8), 8));
}
}
/* Eval register or immediate data.
xBBB_BBBB, if immediate use all 7 bits for data else use
lower four bits for the general purpose register number. */
/* Evaluates gprm or data depending on bit, data is in byte n */
static uint16_t eval_reg_or_data_2(command_t* command,
int32_t imm, int32_t start) {
if(imm) /* immediate */
return vm_getbits(command, (start - 1), 7);
else
return get_GPRM(command->registers, (vm_getbits(command, (start - 4), 4)) );
}
/* Compare data using operation, return result from comparison.
Helper function for the different if functions. */
static int32_t eval_compare(uint8_t operation, uint16_t data1, uint16_t data2) {
switch(operation) {
case 1:
return data1 & data2;
case 2:
return data1 == data2;
case 3:
return data1 != data2;
case 4:
return data1 >= data2;
case 5:
return data1 > data2;
case 6:
return data1 <= data2;
case 7:
return data1 < data2;
}
fprintf(MSG_OUT, "libdvdnav: eval_compare: Invalid comparison code\n");
return 0;
}
/* Evaluate if version 1.
Has comparison data in byte 3 and 4-5 (immediate or register) */
static int32_t eval_if_version_1(command_t* command) {
uint8_t op = vm_getbits(command, 54, 3);
if(op) {
return eval_compare(op, eval_reg(command, vm_getbits(command, 39, 8)),
eval_reg_or_data(command, vm_getbits(command, 55, 1), 31));
}
return 1;
}
/* Evaluate if version 2.
This version only compares register which are in byte 6 and 7 */
static int32_t eval_if_version_2(command_t* command) {
uint8_t op = vm_getbits(command, 54, 3);
if(op) {
return eval_compare(op, eval_reg(command, vm_getbits(command, 15, 8)),
eval_reg(command, vm_getbits(command, 7, 8)));
}
return 1;
}
/* Evaluate if version 3.
Has comparison data in byte 2 and 6-7 (immediate or register) */
static int32_t eval_if_version_3(command_t* command) {
uint8_t op = vm_getbits(command, 54, 3);
if(op) {
return eval_compare(op, eval_reg(command, vm_getbits(command, 47, 8)),
eval_reg_or_data(command, vm_getbits(command, 55, 1), 15));
}
return 1;
}
/* Evaluate if version 4.
Has comparison data in byte 1 and 4-5 (immediate or register)
The register in byte 1 is only the lowe nibble (4 bits) */
static int32_t eval_if_version_4(command_t* command) {
uint8_t op = vm_getbits(command, 54, 3);
if(op) {
return eval_compare(op, eval_reg(command, vm_getbits(command, 51, 4)),
eval_reg_or_data(command, vm_getbits(command, 55, 1), 31));
}
return 1;
}
/* Evaluate special instruction.... returns the new row/line number,
0 if no new row and 256 if Break. */
static int32_t eval_special_instruction(command_t* command, int32_t cond) {
int32_t line, level;
switch(vm_getbits(command, 51, 4)) {
case 0: /* NOP */
line = 0;
return cond ? line : 0;
case 1: /* Goto line */
line = vm_getbits(command, 7, 8);
return cond ? line : 0;
case 2: /* Break */
/* max number of rows < 256, so we will end this set */
line = 256;
return cond ? 256 : 0;
case 3: /* Set temporary parental level and goto */
line = vm_getbits(command, 7, 8);
level = vm_getbits(command, 11, 4);
if(cond) {
/* This always succeeds now, if we want real parental protection */
/* we need to ask the user and have passwords and stuff. */
command->registers->SPRM[13] = level;
}
return cond ? line : 0;
}
return 0;
}
/* Evaluate link by subinstruction.
Return 1 if link, or 0 if no link
Actual link instruction is in return_values parameter */
static int32_t eval_link_subins(command_t* command, int32_t cond, link_t *return_values) {
uint16_t button = vm_getbits(command, 15, 6);
uint8_t linkop = vm_getbits(command, 4, 5);
if(linkop > 0x10)
return 0; /* Unknown Link by Sub-Instruction command */
/* Assumes that the link_cmd_t enum has the same values as the LinkSIns codes */
return_values->command = linkop;
return_values->data1 = button;
return cond;
}
/* Evaluate link instruction.
Return 1 if link, or 0 if no link
Actual link instruction is in return_values parameter */
static int32_t eval_link_instruction(command_t* command, int32_t cond, link_t *return_values) {
uint8_t op = vm_getbits(command, 51, 4);
switch(op) {
case 1:
return eval_link_subins(command, cond, return_values);
case 4:
return_values->command = LinkPGCN;
return_values->data1 = vm_getbits(command, 14, 15);
return cond;
case 5:
return_values->command = LinkPTTN;
return_values->data1 = vm_getbits(command, 9, 10);
return_values->data2 = vm_getbits(command, 15, 6);
return cond;
case 6:
return_values->command = LinkPGN;
return_values->data1 = vm_getbits(command, 6, 7);
return_values->data2 = vm_getbits(command, 15, 6);
return cond;
case 7:
return_values->command = LinkCN;
return_values->data1 = vm_getbits(command, 7, 8);
return_values->data2 = vm_getbits(command, 15, 6);
return cond;
}
return 0;
}
/* Evaluate a jump instruction.
returns 1 if jump or 0 if no jump
actual jump instruction is in return_values parameter */
static int32_t eval_jump_instruction(command_t* command, int32_t cond, link_t *return_values) {
switch(vm_getbits(command, 51, 4)) {
case 1:
return_values->command = Exit;
return cond;
case 2:
return_values->command = JumpTT;
return_values->data1 = vm_getbits(command, 22, 7);
return cond;
case 3:
return_values->command = JumpVTS_TT;
return_values->data1 = vm_getbits(command, 22, 7);
return cond;
case 5:
return_values->command = JumpVTS_PTT;
return_values->data1 = vm_getbits(command, 22, 7);
return_values->data2 = vm_getbits(command, 41, 10);
return cond;
case 6:
switch(vm_getbits(command, 23, 2)) {
case 0:
return_values->command = JumpSS_FP;
return cond;
case 1:
return_values->command = JumpSS_VMGM_MENU;
return_values->data1 = vm_getbits(command, 19, 4);
return cond;
case 2:
return_values->command = JumpSS_VTSM;
return_values->data1 = vm_getbits(command, 31, 8);
return_values->data2 = vm_getbits(command, 39, 8);
return_values->data3 = vm_getbits(command, 19, 4);
return cond;
case 3:
return_values->command = JumpSS_VMGM_PGC;
return_values->data1 = vm_getbits(command, 46, 15);
return cond;
}
break;
case 8:
switch(vm_getbits(command, 23, 2)) {
case 0:
return_values->command = CallSS_FP;
return_values->data1 = vm_getbits(command, 31, 8);
return cond;
case 1:
return_values->command = CallSS_VMGM_MENU;
return_values->data1 = vm_getbits(command, 19, 4);
return_values->data2 = vm_getbits(command, 31, 8);
return cond;
case 2:
return_values->command = CallSS_VTSM;
return_values->data1 = vm_getbits(command, 19, 4);
return_values->data2 = vm_getbits(command, 31, 8);
return cond;
case 3:
return_values->command = CallSS_VMGM_PGC;
return_values->data1 = vm_getbits(command, 46, 15);
return_values->data2 = vm_getbits(command, 31, 8);
return cond;
}
break;
}
return 0;
}
/* Evaluate a set sytem register instruction
May contain a link so return the same as eval_link */
static int32_t eval_system_set(command_t* command, int32_t cond, link_t *return_values) {
int32_t i;
uint16_t data, data2;
switch(vm_getbits(command, 59, 4)) {
case 1: /* Set system reg 1 &| 2 &| 3 (Audio, Subp. Angle) */
for(i = 1; i <= 3; i++) {
if(vm_getbits(command, 63 - ((2 + i)*8), 1)) {
data = eval_reg_or_data_2(command, vm_getbits(command, 60, 1), (47 - (i*8)));
if(cond) {
command->registers->SPRM[i] = data;
}
}
}
break;
case 2: /* Set system reg 9 & 10 (Navigation timer, Title PGC number) */
data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47);
data2 = vm_getbits(command, 23, 8); /* ?? size */
if(cond) {
command->registers->SPRM[9] = data; /* time */
command->registers->SPRM[10] = data2; /* pgcN */
}
break;
case 3: /* Mode: Counter / Register + Set */
data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47);
data2 = vm_getbits(command, 19, 4);
if(vm_getbits(command, 23, 1)) {
command->registers->GPRM_mode[data2] |= 1; /* Set bit 0 */
} else {
command->registers->GPRM_mode[data2] &= ~ 0x01; /* Reset bit 0 */
}
if(cond) {
set_GPRM(command->registers, data2, data);
}
break;
case 6: /* Set system reg 8 (Highlighted button) */
data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 31); /* Not system reg!! */
if(cond) {
command->registers->SPRM[8] = data;
}
break;
}
if(vm_getbits(command, 51, 4)) {
return eval_link_instruction(command, cond, return_values);
}
return 0;
}
/* Evaluate set operation
Sets the register given to the value indicated by op and data.
For the swap case the contents of reg is stored in reg2.
*/
static void eval_set_op(command_t* command, int32_t op, int32_t reg, int32_t reg2, int32_t data) {
static const int32_t shortmax = 0xffff;
int32_t tmp;
switch(op) {
case 1:
set_GPRM(command->registers, reg, data);
break;
case 2: /* SPECIAL CASE - SWAP! */
set_GPRM(command->registers, reg2, get_GPRM(command->registers, reg));
set_GPRM(command->registers, reg, data);
break;
case 3:
tmp = get_GPRM(command->registers, reg) + data;
if(tmp > shortmax) tmp = shortmax;
set_GPRM(command->registers, reg, (uint16_t)tmp);
break;
case 4:
tmp = get_GPRM(command->registers, reg) - data;
if(tmp < 0) tmp = 0;
set_GPRM(command->registers, reg, (uint16_t)tmp);
break;
case 5:
tmp = get_GPRM(command->registers, reg) * data;
if(tmp > shortmax) tmp = shortmax;
set_GPRM(command->registers, reg, (uint16_t)tmp);
break;
case 6:
if (data != 0) {
set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) / data) );
} else {
set_GPRM(command->registers, reg, 0xffff); /* Avoid that divide by zero! */
}
break;
case 7:
if (data != 0) {
set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) % data) );
} else {
set_GPRM(command->registers, reg, 0xffff); /* Avoid that divide by zero! */
}
break;
case 8: /* SPECIAL CASE - RND! Return numbers between 1 and data. */
set_GPRM(command->registers, reg, 1 + ((uint16_t) ((float) data * rand()/(RAND_MAX+1.0))) );
break;
case 9:
set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) & data) );
break;
case 10:
set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) | data) );
break;
case 11:
set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) ^ data) );
break;
}
}
/* Evaluate set instruction, combined with either Link or Compare. */
static void eval_set_version_1(command_t* command, int32_t cond) {
uint8_t op = vm_getbits(command, 59, 4);
uint8_t reg = vm_getbits(command, 35, 4); /* FIXME: This is different from vmcmd.c!!! */
uint8_t reg2 = vm_getbits(command, 19, 4);
uint16_t data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 31);
if(cond) {
eval_set_op(command, op, reg, reg2, data);
}
}
/* Evaluate set instruction, combined with both Link and Compare. */
static void eval_set_version_2(command_t* command, int32_t cond) {
uint8_t op = vm_getbits(command, 59, 4);
uint8_t reg = vm_getbits(command, 51, 4);
uint8_t reg2 = vm_getbits(command, 35, 4); /* FIXME: This is different from vmcmd.c!!! */
uint16_t data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47);
if(cond) {
eval_set_op(command, op, reg, reg2, data);
}
}
/* Evaluate a command
returns row number of goto, 0 if no goto, -1 if link.
Link command in return_values */
static int32_t eval_command(uint8_t *bytes, registers_t* registers, link_t *return_values) {
int32_t cond, res = 0;
command_t command;
command.instruction =( (uint64_t) bytes[0] << 56 ) |
( (uint64_t) bytes[1] << 48 ) |
( (uint64_t) bytes[2] << 40 ) |
( (uint64_t) bytes[3] << 32 ) |
( (uint64_t) bytes[4] << 24 ) |
( (uint64_t) bytes[5] << 16 ) |
( (uint64_t) bytes[6] << 8 ) |
(uint64_t) bytes[7] ;
command.examined = 0;
command.registers = registers;
memset(return_values, 0, sizeof(link_t));
switch(vm_getbits(&command, 63, 3)) { /* three first old_bits */
case 0: /* Special instructions */
cond = eval_if_version_1(&command);
res = eval_special_instruction(&command, cond);
if(res == -1) {
fprintf(MSG_OUT, "libdvdnav: Unknown Instruction!\n");
assert(0);
}
break;
case 1: /* Link/jump instructions */
if(vm_getbits(&command, 60, 1)) {
cond = eval_if_version_2(&command);
res = eval_jump_instruction(&command, cond, return_values);
} else {
cond = eval_if_version_1(&command);
res = eval_link_instruction(&command, cond, return_values);
}
if(res)
res = -1;
break;
case 2: /* System set instructions */
cond = eval_if_version_2(&command);
res = eval_system_set(&command, cond, return_values);
if(res)
res = -1;
break;
case 3: /* Set instructions, either Compare or Link may be used */
cond = eval_if_version_3(&command);
eval_set_version_1(&command, cond);
if(vm_getbits(&command, 51, 4)) {
res = eval_link_instruction(&command, cond, return_values);
}
if(res)
res = -1;
break;
case 4: /* Set, Compare -> Link Sub-Instruction */
eval_set_version_2(&command, /*True*/ 1);
cond = eval_if_version_4(&command);
res = eval_link_subins(&command, cond, return_values);
if(res)
res = -1;
break;
case 5: /* Compare -> (Set and Link Sub-Instruction) */
/* FIXME: These are wrong. Need to be updated from vmcmd.c */
cond = eval_if_version_4(&command);
eval_set_version_2(&command, cond);
res = eval_link_subins(&command, cond, return_values);
if(res)
res = -1;
break;
case 6: /* Compare -> Set, allways Link Sub-Instruction */
/* FIXME: These are wrong. Need to be updated from vmcmd.c */
cond = eval_if_version_4(&command);
eval_set_version_2(&command, cond);
res = eval_link_subins(&command, /*True*/ 1, return_values);
if(res)
res = -1;
break;
default: /* Unknown command type */
fprintf(MSG_OUT, "libdvdnav: WARNING: Unknown Command Type=%x\n", vm_getbits(&command, 63, 3));
}
/* Check if there are bits not yet examined */
if(command.instruction & ~ command.examined) {
fprintf(MSG_OUT, "libdvdnav: decoder.c: [WARNING, unknown bits:");
fprintf(MSG_OUT, " %08"PRIx64, (command.instruction & ~ command.examined) );
fprintf(MSG_OUT, "]\n");
}
return res;
}
/* Evaluate a set of commands in the given register set (which is modified) */
int32_t vmEval_CMD(vm_cmd_t commands[], int32_t num_commands,
registers_t *registers, link_t *return_values) {
int32_t i = 0;
int32_t total = 0;
#ifdef TRACE
/* DEBUG */
fprintf(MSG_OUT, "libdvdnav: Registers before transaction\n");
vm_print_registers( registers );
fprintf(MSG_OUT, "libdvdnav: Full list of commands to execute\n");
for(i = 0; i < num_commands; i++)
vm_print_cmd(i, &commands[i]);
fprintf(MSG_OUT, "libdvdnav: --------------------------------------------\n");
fprintf(MSG_OUT, "libdvdnav: Single stepping commands\n");
#endif
i = 0;
while(i < num_commands && total < 100000) {
int32_t line;
#ifdef TRACE
vm_print_cmd(i, &commands[i]);
#endif
line = eval_command(&commands[i].bytes[0], registers, return_values);
if (line < 0) { /* Link command */
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: Registers after transaction\n");
vm_print_registers( registers );
fprintf(MSG_OUT, "libdvdnav: eval: Doing Link/Jump/Call\n");
#endif
return 1;
}
if (line > 0) /* Goto command */
i = line - 1;
else /* Just continue on the next line */
i++;
total++;
}
memset(return_values, 0, sizeof(link_t));
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: Registers after transaction\n");
vm_print_registers( registers );
#endif
return 0;
}
#ifdef TRACE
static char *linkcmd2str(link_cmd_t cmd) {
switch(cmd) {
case LinkNoLink:
return "LinkNoLink";
case LinkTopC:
return "LinkTopC";
case LinkNextC:
return "LinkNextC";
case LinkPrevC:
return "LinkPrevC";
case LinkTopPG:
return "LinkTopPG";
case LinkNextPG:
return "LinkNextPG";
case LinkPrevPG:
return "LinkPrevPG";
case LinkTopPGC:
return "LinkTopPGC";
case LinkNextPGC:
return "LinkNextPGC";
case LinkPrevPGC:
return "LinkPrevPGC";
case LinkGoUpPGC:
return "LinkGoUpPGC";
case LinkTailPGC:
return "LinkTailPGC";
case LinkRSM:
return "LinkRSM";
case LinkPGCN:
return "LinkPGCN";
case LinkPTTN:
return "LinkPTTN";
case LinkPGN:
return "LinkPGN";
case LinkCN:
return "LinkCN";
case Exit:
return "Exit";
case JumpTT:
return "JumpTT";
case JumpVTS_TT:
return "JumpVTS_TT";
case JumpVTS_PTT:
return "JumpVTS_PTT";
case JumpSS_FP:
return "JumpSS_FP";
case JumpSS_VMGM_MENU:
return "JumpSS_VMGM_MENU";
case JumpSS_VTSM:
return "JumpSS_VTSM";
case JumpSS_VMGM_PGC:
return "JumpSS_VMGM_PGC";
case CallSS_FP:
return "CallSS_FP";
case CallSS_VMGM_MENU:
return "CallSS_VMGM_MENU";
case CallSS_VTSM:
return "CallSS_VTSM";
case CallSS_VMGM_PGC:
return "CallSS_VMGM_PGC";
case PlayThis:
return "PlayThis";
}
return "*** (bug)";
}
void vm_print_link(link_t value) {
char *cmd = linkcmd2str(value.command);
switch(value.command) {
case LinkNoLink:
case LinkTopC:
case LinkNextC:
case LinkPrevC:
case LinkTopPG:
case LinkNextPG:
case LinkPrevPG:
case LinkTopPGC:
case LinkNextPGC:
case LinkPrevPGC:
case LinkGoUpPGC:
case LinkTailPGC:
case LinkRSM:
fprintf(MSG_OUT, "libdvdnav: %s (button %d)\n", cmd, value.data1);
break;
case LinkPGCN:
case JumpTT:
case JumpVTS_TT:
case JumpSS_VMGM_MENU: /* == 2 -> Title Menu */
case JumpSS_VMGM_PGC:
fprintf(MSG_OUT, "libdvdnav: %s %d\n", cmd, value.data1);
break;
case LinkPTTN:
case LinkPGN:
case LinkCN:
fprintf(MSG_OUT, "libdvdnav: %s %d (button %d)\n", cmd, value.data1, value.data2);
break;
case Exit:
case JumpSS_FP:
case PlayThis: /* Humm.. should we have this at all.. */
fprintf(MSG_OUT, "libdvdnav: %s\n", cmd);
break;
case JumpVTS_PTT:
fprintf(MSG_OUT, "libdvdnav: %s %d:%d\n", cmd, value.data1, value.data2);
break;
case JumpSS_VTSM:
fprintf(MSG_OUT, "libdvdnav: %s vts %d title %d menu %d\n",
cmd, value.data1, value.data2, value.data3);
break;
case CallSS_FP:
fprintf(MSG_OUT, "libdvdnav: %s resume cell %d\n", cmd, value.data1);
break;
case CallSS_VMGM_MENU: /* == 2 -> Title Menu */
case CallSS_VTSM:
fprintf(MSG_OUT, "libdvdnav: %s %d resume cell %d\n", cmd, value.data1, value.data2);
break;
case CallSS_VMGM_PGC:
fprintf(MSG_OUT, "libdvdnav: %s %d resume cell %d\n", cmd, value.data1, value.data2);
break;
}
}
void vm_print_registers( registers_t *registers ) {
int32_t i;
fprintf(MSG_OUT, "libdvdnav: # ");
for(i = 0; i < 24; i++)
fprintf(MSG_OUT, " %2d |", i);
fprintf(MSG_OUT, "\nlibdvdnav: SRPMS: ");
for(i = 0; i < 24; i++)
fprintf(MSG_OUT, "%04x|", registers->SPRM[i]);
fprintf(MSG_OUT, "\nlibdvdnav: GRPMS: ");
for(i = 0; i < 16; i++)
fprintf(MSG_OUT, "%04x|", get_GPRM(registers, i) );
fprintf(MSG_OUT, "\nlibdvdnav: Gmode: ");
for(i = 0; i < 16; i++)
fprintf(MSG_OUT, "%04x|", registers->GPRM_mode[i]);
fprintf(MSG_OUT, "\nlibdvdnav: Gtime: ");
for(i = 0; i < 16; i++)
fprintf(MSG_OUT, "%04lx|", registers->GPRM_time[i].tv_sec & 0xffff);
fprintf(MSG_OUT, "\n");
}
#endif

111
src/vm/decoder.h Normal file
View File

@ -0,0 +1,111 @@
/*
* Copyright (C) 2000, 2001 Martin Norbäck, Håkan Hjort
*
* This file is part of libdvdnav, a DVD navigation library. It is modified
* from a file originally part of the Ogle DVD player.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef LIBDVDNAV_DECODER_H
#define LIBDVDNAV_DECODER_H
#include <sys/time.h>
/* link command types */
typedef enum {
LinkNoLink = 0,
LinkTopC = 1,
LinkNextC = 2,
LinkPrevC = 3,
LinkTopPG = 5,
LinkNextPG = 6,
LinkPrevPG = 7,
LinkTopPGC = 9,
LinkNextPGC = 10,
LinkPrevPGC = 11,
LinkGoUpPGC = 12,
LinkTailPGC = 13,
LinkRSM = 16,
LinkPGCN,
LinkPTTN,
LinkPGN,
LinkCN,
Exit,
JumpTT, /* 22 */
JumpVTS_TT,
JumpVTS_PTT,
JumpSS_FP,
JumpSS_VMGM_MENU,
JumpSS_VTSM,
JumpSS_VMGM_PGC,
CallSS_FP, /* 29 */
CallSS_VMGM_MENU,
CallSS_VTSM,
CallSS_VMGM_PGC,
PlayThis
} link_cmd_t;
/* a link's data set */
typedef struct {
link_cmd_t command;
uint16_t data1;
uint16_t data2;
uint16_t data3;
} link_t;
/* the VM registers */
typedef struct {
uint16_t SPRM[24];
uint16_t GPRM[16];
uint8_t GPRM_mode[16]; /* Need to have some thing to indicate normal/counter mode for every GPRM */
struct timeval GPRM_time[16]; /* For counter mode */
} registers_t;
/* a VM command data set */
typedef struct {
uint64_t instruction;
uint64_t examined;
registers_t *registers;
} command_t;
/* the big VM function, executing the given commands and writing
* the link where to continue, the return value indicates if a jump
* has been performed */
int32_t vmEval_CMD(vm_cmd_t commands[], int32_t num_commands,
registers_t *registers, link_t *return_values);
/* extracts some bits from the command */
uint32_t vm_getbits(command_t* command, int32_t start, int32_t count);
#ifdef TRACE
/* for debugging: prints a link in readable form */
void vm_print_link(link_t value);
/* for debugging: dumps VM registers */
void vm_print_registers( registers_t *registers );
#endif
#endif /* LIBDVDNAV_DECODER_H */

366
src/vm/getset.c Normal file
View File

@ -0,0 +1,366 @@
/*
* Copyright (C) 2000, 2001 Håkan Hjort
* Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net>
* 2002-2004 the dvdnav project
*
* This file is part of libdvdnav, a DVD navigation library. It is modified
* from a file originally part of the Ogle DVD player.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <dvdread/nav_types.h>
#include <dvdread/ifo_types.h>
#include <dvdread/ifo_read.h>
#include "dvdnav/dvdnav.h"
#include "decoder.h"
#include "vm.h"
#include "getset.h"
#include "dvdnav_internal.h"
#include "getset.h"
/* Set functions */
int set_TT(vm_t *vm, int tt) {
return set_PTT(vm, tt, 1);
}
int set_PTT(vm_t *vm, int tt, int ptt) {
assert(tt <= vm->vmgi->tt_srpt->nr_of_srpts);
return set_VTS_PTT(vm, vm->vmgi->tt_srpt->title[tt - 1].title_set_nr,
vm->vmgi->tt_srpt->title[tt - 1].vts_ttn, ptt);
}
int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn) {
return set_VTS_PTT(vm, vtsN, vts_ttn, 1);
}
int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part) {
int pgcN, pgN, res;
(vm->state).domain = DVD_DOMAIN_VTSTitle;
if (vtsN != (vm->state).vtsN)
if (!ifoOpenNewVTSI(vm, vm->dvd, vtsN)) /* Also sets (vm->state).vtsN */
return 0;
if ((vts_ttn < 1) || (vts_ttn > vm->vtsi->vts_ptt_srpt->nr_of_srpts) ||
(part < 1) || (part > vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].nr_of_ptts) ) {
return 0;
}
pgcN = vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgcn;
pgN = vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgn;
(vm->state).TT_PGCN_REG = pgcN;
(vm->state).PTTN_REG = part;
(vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn);
if( (vm->state.TTN_REG) == 0 )
return 0;
(vm->state).VTS_TTN_REG = vts_ttn;
(vm->state).vtsN = vtsN; /* Not sure about this one. We can get to it easily from TTN_REG */
/* Any other registers? */
res = set_PGCN(vm, pgcN); /* This clobber's state.pgN (sets it to 1), but we don't want clobbering here. */
(vm->state).pgN = pgN;
return res;
}
int set_PROG(vm_t *vm, int tt, int pgcn, int pgn) {
assert(tt <= vm->vmgi->tt_srpt->nr_of_srpts);
return set_VTS_PROG(vm, vm->vmgi->tt_srpt->title[tt - 1].title_set_nr,
vm->vmgi->tt_srpt->title[tt - 1].vts_ttn, pgcn, pgn);
}
int set_VTS_PROG(vm_t *vm, int vtsN, int vts_ttn, int pgcn, int pgn) {
int pgcN, pgN, res, title, part = 0;
(vm->state).domain = DVD_DOMAIN_VTSTitle;
if (vtsN != (vm->state).vtsN)
if (!ifoOpenNewVTSI(vm, vm->dvd, vtsN)) /* Also sets (vm->state).vtsN */
return 0;
if ((vts_ttn < 1) || (vts_ttn > vm->vtsi->vts_ptt_srpt->nr_of_srpts)) {
return 0;
}
pgcN = pgcn;
pgN = pgn;
(vm->state).TT_PGCN_REG = pgcN;
(vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn);
assert( (vm->state.TTN_REG) != 0 );
(vm->state).VTS_TTN_REG = vts_ttn;
(vm->state).vtsN = vtsN; /* Not sure about this one. We can get to it easily from TTN_REG */
/* Any other registers? */
res = set_PGCN(vm, pgcN); /* This clobber's state.pgN (sets it to 1), but we don't want clobbering here. */
(vm->state).pgN = pgN;
vm_get_current_title_part(vm, &title, &part);
(vm->state).PTTN_REG = part;
return res;
}
int set_FP_PGC(vm_t *vm) {
if (!vm || !vm->vmgi)
return 1;
(vm->state).domain = DVD_DOMAIN_FirstPlay;
if (!vm->vmgi->first_play_pgc) {
return set_PGCN(vm, 1);
}
(vm->state).pgc = vm->vmgi->first_play_pgc;
(vm->state).pgcN = vm->vmgi->vmgi_mat->first_play_pgc;
return 1;
}
int set_MENU(vm_t *vm, int menu) {
assert((vm->state).domain == DVD_DOMAIN_VMGM || (vm->state).domain == DVD_DOMAIN_VTSMenu);
return set_PGCN(vm, get_ID(vm, menu));
}
int set_PGCN(vm_t *vm, int pgcN) {
pgcit_t *pgcit;
pgcit = get_PGCIT(vm);
if (pgcit == NULL)
return 0;
if(pgcN < 1 || pgcN > pgcit->nr_of_pgci_srp) {
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: ** No such pgcN = %d\n", pgcN);
#endif
return 0;
}
(vm->state).pgc = pgcit->pgci_srp[pgcN - 1].pgc;
(vm->state).pgcN = pgcN;
(vm->state).pgN = 1;
if((vm->state).domain == DVD_DOMAIN_VTSTitle)
(vm->state).TT_PGCN_REG = pgcN;
return 1;
}
/* Figure out the correct pgN from the cell and update (vm->state). */
int set_PGN(vm_t *vm) {
int new_pgN = 0;
int dummy, part = 0;
if ((vm->state).pgc == NULL)
return 0;
while(new_pgN < (vm->state).pgc->nr_of_programs
&& (vm->state).cellN >= (vm->state).pgc->program_map[new_pgN])
new_pgN++;
if(new_pgN == (vm->state).pgc->nr_of_programs) /* We are at the last program */
if((vm->state).cellN > (vm->state).pgc->nr_of_cells)
return 0; /* We are past the last cell */
(vm->state).pgN = new_pgN;
if((vm->state).domain == DVD_DOMAIN_VTSTitle) {
if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts)
return 0; /* ?? */
vm_get_current_title_part(vm, &dummy, &part);
(vm->state).PTTN_REG = part;
}
return 1;
}
/* Must be called before domain is changed (set_PGCN()) */
void set_RSMinfo(vm_t *vm, int cellN, int blockN) {
int i;
if(cellN) {
(vm->state).rsm_cellN = cellN;
(vm->state).rsm_blockN = blockN;
} else {
(vm->state).rsm_cellN = (vm->state).cellN;
(vm->state).rsm_blockN = blockN;
}
(vm->state).rsm_vtsN = (vm->state).vtsN;
(vm->state).rsm_pgcN = get_PGCN(vm);
/* assert((vm->state).rsm_pgcN == (vm->state).TT_PGCN_REG); for DVD_DOMAIN_VTSTitle */
for(i = 0; i < 5; i++) {
(vm->state).rsm_regs[i] = (vm->state).registers.SPRM[4 + i];
}
}
/* Force the highlight button number register */
void set_HL_BTN(vm_t *vm, int btnn)
{
(vm->state).HL_BTNN_REG = btnn << 10;
}
/* Get functions */
/* Searches the TT tables, to find the current TT.
* returns the current TT.
* returns 0 if not found.
*/
int get_TT(vm_t *vm, int vtsN, int vts_ttn) {
int i;
int tt=0;
for(i = 1; i <= vm->vmgi->tt_srpt->nr_of_srpts; i++) {
if( vm->vmgi->tt_srpt->title[i - 1].title_set_nr == vtsN &&
vm->vmgi->tt_srpt->title[i - 1].vts_ttn == vts_ttn) {
tt=i;
break;
}
}
return tt;
}
/* Search for entry_id match of the PGC Category in the current VTS PGCIT table.
* Return pgcN based on entry_id match.
*/
int get_ID(vm_t *vm, int id) {
int pgcN, i;
pgcit_t *pgcit;
/* Relies on state to get the correct pgcit. */
pgcit = get_PGCIT(vm);
if(pgcit == NULL) {
fprintf(MSG_OUT, "libdvdnav: PGCIT null!\n");
return 0;
}
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: ** Searching for menu (0x%x) entry PGC\n", id);
#endif
/* Force high bit set. */
id |=0x80;
/* Get menu/title */
for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {
if( (pgcit->pgci_srp[i].entry_id) == id) {
pgcN = i + 1;
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: Found menu.\n");
#endif
return pgcN;
}
}
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: ** No such id/menu (0x%02x) entry PGC\n", id & 0x7f);
for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {
if ( (pgcit->pgci_srp[i].entry_id & 0x80) == 0x80) {
fprintf(MSG_OUT, "libdvdnav: Available menus: 0x%x\n",
pgcit->pgci_srp[i].entry_id & 0x7f);
}
}
#endif
return 0; /* error */
}
/* FIXME: we have a pgcN member in the vm's state now, so this should be obsolete */
int get_PGCN(vm_t *vm) {
pgcit_t *pgcit;
int pgcN = 1;
if ((vm->state).pgc == NULL) {
return 0; /* error */
}
pgcit = get_PGCIT(vm);
if (pgcit) {
while(pgcN <= pgcit->nr_of_pgci_srp) {
if(pgcit->pgci_srp[pgcN - 1].pgc == (vm->state).pgc) {
assert((vm->state).pgcN == pgcN);
return pgcN;
}
pgcN++;
}
}
fprintf(MSG_OUT, "libdvdnav: get_PGCN failed. Was trying to find pgcN in domain %d\n",
(vm->state).domain);
return 0; /* error */
}
pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang) {
int i;
if(h == NULL || h->pgci_ut == NULL) {
fprintf(MSG_OUT, "libdvdnav: *** pgci_ut handle is NULL ***\n");
return NULL; /* error? */
}
i = 0;
while(i < h->pgci_ut->nr_of_lus
&& h->pgci_ut->lu[i].lang_code != lang)
i++;
if(i == h->pgci_ut->nr_of_lus) {
fprintf(MSG_OUT, "libdvdnav: Language '%c%c' not found, using '%c%c' instead\n",
(char)(lang >> 8), (char)(lang & 0xff),
(char)(h->pgci_ut->lu[0].lang_code >> 8),
(char)(h->pgci_ut->lu[0].lang_code & 0xff));
fprintf(MSG_OUT, "libdvdnav: Menu Languages available: ");
for(i = 0; i < h->pgci_ut->nr_of_lus; i++) {
fprintf(MSG_OUT, "%c%c ",
(char)(h->pgci_ut->lu[i].lang_code >> 8),
(char)(h->pgci_ut->lu[i].lang_code & 0xff));
}
fprintf(MSG_OUT, "\n");
i = 0; /* error? */
}
return h->pgci_ut->lu[i].pgcit;
}
/* Uses state to decide what to return */
pgcit_t* get_PGCIT(vm_t *vm) {
pgcit_t *pgcit = NULL;
switch ((vm->state).domain) {
case DVD_DOMAIN_VTSTitle:
if(!vm->vtsi) return NULL;
pgcit = vm->vtsi->vts_pgcit;
break;
case DVD_DOMAIN_VTSMenu:
if(!vm->vtsi) return NULL;
pgcit = get_MENU_PGCIT(vm, vm->vtsi, (vm->state).registers.SPRM[0]);
break;
case DVD_DOMAIN_VMGM:
case DVD_DOMAIN_FirstPlay:
pgcit = get_MENU_PGCIT(vm, vm->vmgi, (vm->state).registers.SPRM[0]);
break;
default:
abort();
}
return pgcit;
}

50
src/vm/getset.h Normal file
View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2000, 2001 Håkan Hjort
* Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net>
* 2002-2004 the dvdnav project
*
* This file is part of libdvdnav, a DVD navigation library. It is modified
* from a file originally part of the Ogle DVD player.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* get_XYZ returns a value.
* set_XYZ sets state using passed parameters.
* returns success/failure.
*/
/* Set */
int set_TT(vm_t *vm, int tt);
int set_PTT(vm_t *vm, int tt, int ptt);
int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn);
int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part);
int set_PROG(vm_t *vm, int tt, int pgcn, int pgn);
int set_VTS_PROG(vm_t *vm, int vtsN, int vts_ttn, int pgcn, int pgn);
int set_FP_PGC(vm_t *vm);
int set_MENU(vm_t *vm, int menu);
int set_PGCN(vm_t *vm, int pgcN);
int set_PGN(vm_t *vm); /* Set PGN based on (vm->state).CellN */
void set_RSMinfo(vm_t *vm, int cellN, int blockN);
void set_HL_BTN(vm_t *vm, int btnn);
/* Get */
int get_TT(vm_t *vm, int vtsN, int vts_ttn);
int get_ID(vm_t *vm, int id);
int get_PGCN(vm_t *vm);
pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang);
pgcit_t* get_PGCIT(vm_t *vm);

341
src/vm/play.c Normal file
View File

@ -0,0 +1,341 @@
/*
* Copyright (C) 2000, 2001 Håkan Hjort
* Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net>
* 2002-2004 the dvdnav project
*
* This file is part of libdvdnav, a DVD navigation library. It is modified
* from a file originally part of the Ogle DVD player.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <dvdread/nav_types.h>
#include <dvdread/ifo_types.h>
#include <dvdread/ifo_read.h>
#include "dvdnav/dvdnav.h"
#include "decoder.h"
#include "vm.h"
#include "play.h"
#include "vm/getset.h"
#include "dvdnav_internal.h"
/* Playback control */
link_t play_PGC(vm_t *vm) {
link_t link_values;
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: play_PGC:");
if((vm->state).domain != DVD_DOMAIN_FirstPlay) {
fprintf(MSG_OUT, " (vm->state).pgcN (%i)\n", get_PGCN(vm));
} else {
fprintf(MSG_OUT, " first_play_pgc\n");
}
#endif
/* This must be set before the pre-commands are executed because they
* might contain a CallSS that will save resume state */
/* FIXME: This may be only a temporary fix for something... */
(vm->state).pgN = 1;
(vm->state).cellN = 0;
(vm->state).blockN = 0;
/* Handle random playback mode by choosing our initial program
* number randomly - some discs end up jumping to nowhere if you
* always choose the first cell.
*/
if ((vm->state).pgc->pg_playback_mode!=0 &&
((vm->state).pgc->pg_playback_mode & 0x80)==0) {
int pgCnt = ((vm->state).pgc->pg_playback_mode & 0x7f) + 1;
if (pgCnt > (vm->state).pgc->nr_of_programs) {
pgCnt = (vm->state).pgc->nr_of_programs;
}
if (pgCnt>1) {
(vm->state).pgN = 1 + ((int) ((float) pgCnt * rand()/(RAND_MAX+1.0)));
}
}
/* eval -> updates the state and returns either
- some kind of jump (Jump(TT/SS/VTS_TTN/CallSS/link C/PG/PGC/PTTN)
- just play video i.e first PG
(This is what happens if you fall of the end of the pre_cmds)
- or an error (are there more cases?) */
if((vm->state).pgc->command_tbl && (vm->state).pgc->command_tbl->nr_of_pre) {
if(vmEval_CMD((vm->state).pgc->command_tbl->pre_cmds,
(vm->state).pgc->command_tbl->nr_of_pre,
&(vm->state).registers, &link_values)) {
/* link_values contains the 'jump' return value */
return link_values;
} else {
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: PGC pre commands didn't do a Jump, Link or Call\n");
#endif
}
}
return play_PG(vm);
}
link_t play_PGC_PG(vm_t *vm, int pgN) {
link_t link_values;
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: play_PGC_PG:");
if((vm->state).domain != DVD_DOMAIN_FirstPlay) {
fprintf(MSG_OUT, " (vm->state).pgcN (%i)\n", get_PGCN(vm));
} else {
fprintf(MSG_OUT, " first_play_pgc\n");
}
#endif
/* This must be set before the pre-commands are executed because they
* might contain a CallSS that will save resume state */
/* FIXME: This may be only a temporary fix for something... */
(vm->state).pgN = pgN;
(vm->state).cellN = 0;
(vm->state).blockN = 0;
/* eval -> updates the state and returns either
- some kind of jump (Jump(TT/SS/VTS_TTN/CallSS/link C/PG/PGC/PTTN)
- just play video i.e first PG
(This is what happens if you fall of the end of the pre_cmds)
- or an error (are there more cases?) */
if((vm->state).pgc->command_tbl && (vm->state).pgc->command_tbl->nr_of_pre) {
if(vmEval_CMD((vm->state).pgc->command_tbl->pre_cmds,
(vm->state).pgc->command_tbl->nr_of_pre,
&(vm->state).registers, &link_values)) {
/* link_values contains the 'jump' return value */
return link_values;
} else {
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: PGC pre commands didn't do a Jump, Link or Call\n");
#endif
}
}
return play_PG(vm);
}
link_t play_PGC_post(vm_t *vm) {
link_t link_values = { LinkNoLink, 0, 0, 0 };
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: play_PGC_post:\n");
#endif
/* eval -> updates the state and returns either
- some kind of jump (Jump(TT/SS/VTS_TTN/CallSS/link C/PG/PGC/PTTN)
- just go to next PGC
(This is what happens if you fall of the end of the post_cmds)
- or an error (are there more cases?) */
if((vm->state).pgc->command_tbl && (vm->state).pgc->command_tbl->nr_of_post &&
vmEval_CMD((vm->state).pgc->command_tbl->post_cmds,
(vm->state).pgc->command_tbl->nr_of_post,
&(vm->state).registers, &link_values)) {
return link_values;
}
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: ** Fell of the end of the pgc, continuing in NextPGC\n");
#endif
/* Should end up in the STOP_DOMAIN if next_pgc is 0. */
if(!set_PGCN(vm, (vm->state).pgc->next_pgc_nr)) {
link_values.command = Exit;
return link_values;
}
return play_PGC(vm);
}
link_t play_PG(vm_t *vm) {
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: play_PG: (vm->state).pgN (%i)\n", (vm->state).pgN);
#endif
assert((vm->state).pgN > 0);
if((vm->state).pgN > (vm->state).pgc->nr_of_programs) {
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: play_PG: (vm->state).pgN (%i) > pgc->nr_of_programs (%i)\n",
(vm->state).pgN, (vm->state).pgc->nr_of_programs );
#endif
assert((vm->state).pgN == (vm->state).pgc->nr_of_programs + 1);
return play_PGC_post(vm);
}
(vm->state).cellN = (vm->state).pgc->program_map[(vm->state).pgN - 1];
return play_Cell(vm);
}
link_t play_Cell(vm_t *vm) {
static const link_t play_this = {PlayThis, /* Block in Cell */ 0, 0, 0};
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: play_Cell: (vm->state).cellN (%i)\n", (vm->state).cellN);
#endif
assert((vm->state).cellN > 0);
if((vm->state).cellN > (vm->state).pgc->nr_of_cells) {
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: (vm->state).cellN (%i) > pgc->nr_of_cells (%i)\n",
(vm->state).cellN, (vm->state).pgc->nr_of_cells );
#endif
assert((vm->state).cellN == (vm->state).pgc->nr_of_cells + 1);
return play_PGC_post(vm);
}
/* Multi angle/Interleaved */
switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode) {
case 0: /* Normal */
assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 0);
break;
case 1: /* The first cell in the block */
switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type) {
case 0: /* Not part of a block */
assert(0);
break;
case 1: /* Angle block */
/* Loop and check each cell instead? So we don't get outside the block? */
(vm->state).cellN += (vm->state).AGL_REG - 1;
#ifdef DVDNAV_STRICT
assert((vm->state).cellN <= (vm->state).pgc->nr_of_cells);
assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode != 0);
assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 1);
#else
if (!((vm->state).cellN <= (vm->state).pgc->nr_of_cells) ||
!((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode != 0) ||
!((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 1)) {
fprintf(MSG_OUT, "libdvdnav: Invalid angle block\n");
(vm->state).cellN -= (vm->state).AGL_REG - 1;
}
#endif
break;
case 2: /* reserved */
case 3: /* reserved */
default:
fprintf(MSG_OUT, "libdvdnav: Invalid? Cell block_mode (%d), block_type (%d)\n",
(vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode,
(vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type);
assert(0);
}
break;
case 2: /* Cell in the block */
case 3: /* Last cell in the block */
/* These might perhaps happen for RSM or LinkC commands? */
default:
fprintf(MSG_OUT, "libdvdnav: Cell is in block but did not enter at first cell!\n");
}
/* Updates (vm->state).pgN and PTTN_REG */
if(!set_PGN(vm)) {
/* Should not happen */
assert(0);
return play_PGC_post(vm);
}
(vm->state).cell_restart++;
(vm->state).blockN = 0;
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: Cell should restart here\n");
#endif
return play_this;
}
link_t play_Cell_post(vm_t *vm) {
cell_playback_t *cell;
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: play_Cell_post: (vm->state).cellN (%i)\n", (vm->state).cellN);
#endif
cell = &(vm->state).pgc->cell_playback[(vm->state).cellN - 1];
/* Still time is already taken care of before we get called. */
/* Deal with a Cell command, if any */
if(cell->cell_cmd_nr != 0) {
link_t link_values;
if ((vm->state).pgc->command_tbl != NULL &&
(vm->state).pgc->command_tbl->nr_of_cell >= cell->cell_cmd_nr) {
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: Cell command present, executing\n");
#endif
if(vmEval_CMD(&(vm->state).pgc->command_tbl->cell_cmds[cell->cell_cmd_nr - 1], 1,
&(vm->state).registers, &link_values)) {
return link_values;
} else {
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: Cell command didn't do a Jump, Link or Call\n");
#endif
}
} else {
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: Invalid Cell command\n");
#endif
}
}
/* Where to continue after playing the cell... */
/* Multi angle/Interleaved */
switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode) {
case 0: /* Normal */
assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 0);
(vm->state).cellN++;
break;
case 1: /* The first cell in the block */
case 2: /* A cell in the block */
case 3: /* The last cell in the block */
default:
switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type) {
case 0: /* Not part of a block */
assert(0);
break;
case 1: /* Angle block */
/* Skip the 'other' angles */
(vm->state).cellN++;
while((vm->state).cellN <= (vm->state).pgc->nr_of_cells &&
(vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode >= 2) {
(vm->state).cellN++;
}
break;
case 2: /* reserved */
case 3: /* reserved */
default:
fprintf(MSG_OUT, "libdvdnav: Invalid? Cell block_mode (%d), block_type (%d)\n",
(vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode,
(vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type);
assert(0);
}
break;
}
/* Figure out the correct pgN for the new cell */
if(!set_PGN(vm)) {
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: last cell in this PGC\n");
#endif
return play_PGC_post(vm);
}
return play_Cell(vm);
}

31
src/vm/play.h Normal file
View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2000, 2001 Håkan Hjort
* Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net>
* 2002-2004 the dvdnav project
*
* This file is part of libdvdnav, a DVD navigation library. It is modified
* from a file originally part of the Ogle DVD player.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* Play */
link_t play_PGC(vm_t *vm);
link_t play_PGC_PG(vm_t *vm, int pgN);
link_t play_PGC_post(vm_t *vm);
link_t play_PG(vm_t *vm);
link_t play_Cell(vm_t *vm);
link_t play_Cell_post(vm_t *vm);

1106
src/vm/vm.c Normal file

File diff suppressed because it is too large Load Diff

174
src/vm/vm.h Normal file
View File

@ -0,0 +1,174 @@
/*
* Copyright (C) 2000, 2001 Håkan Hjort
* Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net>
*
* This file is part of libdvdnav, a DVD navigation library. It is modified
* from a file originally part of the Ogle DVD player.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef LIBDVDNAV_VM_H
#define LIBDVDNAV_VM_H
/**
* State: SPRM, GPRM, Domain, pgc, pgN, cellN, ?
*/
typedef struct {
registers_t registers;
DVDDomain_t domain;
int vtsN; /* 0 is vmgm? */
pgc_t *pgc; /* either this or 'int pgcN' is enough? */
int pgcN; /* but provide pgcN for quick lookup */
int pgN; /* is this needed? can allways fid pgN from cellN? */
int cellN;
int32_t cell_restart; /* get cell to restart */
int blockN;
/* Resume info */
int rsm_vtsN;
int rsm_blockN; /* of nav_packet */
uint16_t rsm_regs[5]; /* system registers 4-8 */
int rsm_pgcN;
int rsm_cellN;
} dvd_state_t;
typedef struct vm_position_s {
int16_t button; /* Button highlighted */
int32_t vts; /* vts number to use */
DVDDomain_t domain; /* domain to use */
int32_t spu_channel; /* spu channel to use */
int32_t angle_channel; /* angle channel to use */
int32_t audio_channel; /* audio channel to use */
int32_t hop_channel; /* channel hopping. E.g menu button pressed */
#if 0
/* currently unused */
int32_t title; /* title number */
int32_t chapter; /* chapter number */
#endif
int32_t cell; /* cell number */
int32_t cell_restart; /* get cell to restart */
int32_t cell_start; /* sector number of start of current cell in use */
int32_t still; /* is cell still */
int32_t block; /* block number within cell in use */
} vm_position_t;
typedef struct {
dvd_reader_t *dvd;
ifo_handle_t *vmgi;
ifo_handle_t *vtsi;
dvd_state_t state;
int32_t hop_channel;
char dvd_name[50];
char dvd_serial[15];
int stopped;
} vm_t;
/* magic number for seeking hops */
#define HOP_SEEK 0x1000
/* Audio stream number */
#define AST_REG registers.SPRM[1]
/* Subpicture stream number */
#define SPST_REG registers.SPRM[2]
/* Angle number */
#define AGL_REG registers.SPRM[3]
/* Title Track Number */
#define TTN_REG registers.SPRM[4]
/* VTS Title Track Number */
#define VTS_TTN_REG registers.SPRM[5]
/* PGC Number for this Title Track */
#define TT_PGCN_REG registers.SPRM[6]
/* Current Part of Title (PTT) number for (One_Sequential_PGC_Title) */
#define PTTN_REG registers.SPRM[7]
/* Highlighted Button Number (btn nr 1 == value 1024) */
#define HL_BTNN_REG registers.SPRM[8]
/* Parental Level */
#define PTL_REG registers.SPRM[13]
/* Initialisation & destruction */
vm_t *vm_new_vm(void);
void vm_free_vm(vm_t *vm);
/* IFO access */
ifo_handle_t *vm_get_vmgi(vm_t *vm);
ifo_handle_t *vm_get_vtsi(vm_t *vm);
/* Reader Access */
dvd_reader_t *vm_get_dvd_reader(vm_t *vm);
/* Basic Handling */
int vm_start(vm_t *vm);
void vm_stop(vm_t *vm);
int vm_reset(vm_t *vm, const char *dvdroot, void *stream,
dvdnav_stream_cb *stream_cb);
/* copying and merging - useful for try-running an operation */
vm_t *vm_new_copy(vm_t *vm);
void vm_merge(vm_t *target, vm_t *source);
void vm_free_copy(vm_t *vm);
/* regular playback */
void vm_position_get(vm_t *vm, vm_position_t *position);
void vm_get_next_cell(vm_t *vm);
/* Jumping - all these return 1, if a hop has been performed */
int vm_jump_pg(vm_t *vm, int pg);
int vm_jump_cell_block(vm_t *vm, int cell, int block);
int vm_jump_title_part(vm_t *vm, int title, int part);
int vm_jump_title_program(vm_t *vm, int title, int pgcn, int pgn);
int vm_jump_top_pg(vm_t *vm);
int vm_jump_next_pg(vm_t *vm);
int vm_jump_prev_pg(vm_t *vm);
int vm_jump_up(vm_t *vm);
int vm_jump_menu(vm_t *vm, DVDMenuID_t menuid);
int vm_jump_resume(vm_t *vm);
int vm_exec_cmd(vm_t *vm, vm_cmd_t *cmd);
/* getting information */
int vm_get_current_menu(vm_t *vm, int *menuid);
int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result);
int vm_get_audio_stream(vm_t *vm, int audioN);
int vm_get_subp_stream(vm_t *vm, int subpN, int mode);
int vm_get_audio_active_stream(vm_t *vm);
int vm_get_subp_active_stream(vm_t *vm, int mode);
void vm_get_angle_info(vm_t *vm, int *current, int *num_avail);
#if 0
/* currently unused */
void vm_get_audio_info(vm_t *vm, int *current, int *num_avail);
void vm_get_subp_info(vm_t *vm, int *current, int *num_avail);
#endif
void vm_get_video_res(vm_t *vm, int *width, int *height);
int vm_get_video_aspect(vm_t *vm);
int vm_get_video_scale_permission(vm_t *vm);
video_attr_t vm_get_video_attr(vm_t *vm);
audio_attr_t vm_get_audio_attr(vm_t *vm, int streamN);
subp_attr_t vm_get_subp_attr(vm_t *vm, int streamN);
ifo_handle_t *vm_get_title_ifo(vm_t *vm, uint32_t title);
void vm_ifo_close(ifo_handle_t *ifo);
/* Uncomment for VM command tracing */
/* #define TRACE */
#ifdef TRACE
/* Debug */
void vm_position_print(vm_t *vm, vm_position_t *position);
#endif
int ifoOpenNewVTSI(vm_t *vm, dvd_reader_t *dvd, int vtsN);
#endif /* LIBDVDNAV_VM_H */

544
src/vm/vmcmd.c Normal file
View File

@ -0,0 +1,544 @@
/*
* Copyright (C) 2000, 2001 Martin Norbäck, Håkan Hjort
* 2002-2004 the dvdnav project
*
* This file is part of libdvdnav, a DVD navigation library. It is modified
* from a file originally part of the Ogle DVD player.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <ctype.h>
#include <inttypes.h>
#include <limits.h>
#include <sys/time.h>
#include "dvdnav/dvdnav.h"
#include <dvdread/nav_types.h>
#include <dvdread/ifo_types.h>
#include "decoder.h"
#include "vm.h"
#include "vmcmd.h"
#include "dvdnav_internal.h"
/* freebsd compatibility */
#ifndef PRIu8
#define PRIu8 "d"
#endif
/* freebsd compatibility */
#ifndef PRIu16
#define PRIu16 "d"
#endif
static const char cmp_op_table[][4] = {
"", "&", "==", "!=", ">=", ">", "<=", "<"
};
static const char set_op_table[][4] = {
"", "=", "<->", "+=", "-=", "*=", "/=", "%=", "rnd", "&=", "|=", "^="
};
static const char link_table[][16] = {
"LinkNoLink", "LinkTopC", "LinkNextC", "LinkPrevC",
"", "LinkTopPG", "LinkNextPG", "LinkPrevPG",
"", "LinkTopPGC", "LinkNextPGC", "LinkPrevPGC",
"LinkGoUpPGC", "LinkTailPGC", "", "",
"RSM"
};
static const char *const system_reg_table[] = {
"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[][8] = {
"",
"ASTN",
"SPSTN",
"AGLN",
"TTN",
"VTS_TTN",
"TT_PGCN",
"PTTN",
"HL_BTNN",
"NVTMR",
"NV_PGCN",
"",
"CC_PLT",
"PLT",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
};
static void print_system_reg(uint16_t reg) {
if(reg < sizeof(system_reg_abbr_table) / sizeof(system_reg_abbr_table[0]))
fprintf(MSG_OUT, "%s (SRPM:%d)", system_reg_table[reg], reg);
else
fprintf(MSG_OUT, " WARNING: Unknown system register ( reg=%d ) ", reg);
}
static void print_g_reg(uint8_t reg) {
if(reg < 16)
fprintf(MSG_OUT, "g[%" PRIu8 "]", reg);
else
fprintf(MSG_OUT, " WARNING: Unknown general register ");
}
static void print_reg(uint8_t reg) {
if(reg & 0x80)
print_system_reg(reg & 0x7f);
else
print_g_reg(reg & 0x7f);
}
static void print_cmp_op(uint8_t op) {
if(op < sizeof(cmp_op_table) / sizeof(cmp_op_table[0]))
fprintf(MSG_OUT, " %s ", cmp_op_table[op]);
else
fprintf(MSG_OUT, " WARNING: Unknown compare op ");
}
static void print_set_op(uint8_t op) {
if(op < sizeof(set_op_table) / sizeof(cmp_op_table[0]))
fprintf(MSG_OUT, " %s ", set_op_table[op]);
else
fprintf(MSG_OUT, " WARNING: Unknown set op ");
}
static void print_reg_or_data(command_t* command, int immediate, int start) {
if(immediate) {
uint32_t i = vm_getbits(command, start, 16);
fprintf(MSG_OUT, "0x%x", i);
if(isprint(i & 0xff) && isprint((i>>8) & 0xff))
fprintf(MSG_OUT, " (\"%c%c\")", (char)((i>>8) & 0xff), (char)(i & 0xff));
} else {
print_reg(vm_getbits(command, start - 8, 8));
}
}
static void print_reg_or_data_2(command_t* command, int immediate, int start) {
if(immediate)
fprintf(MSG_OUT, "0x%x", vm_getbits(command, start - 1, 7));
else
fprintf(MSG_OUT, "g[%" PRIu8 "]", vm_getbits(command, start - 4, 4));
}
static void print_reg_or_data_3(command_t* command, int immediate, int start) {
if(immediate) {
uint32_t i = vm_getbits(command, start, 16);
fprintf(MSG_OUT, "0x%x", i);
if(isprint(i & 0xff) && isprint((i>>8) & 0xff))
fprintf(MSG_OUT, " (\"%c%c\")", (char)((i>>8) & 0xff), (char)(i & 0xff));
} else {
print_reg(vm_getbits(command, start, 8));
}
}
static void print_if_version_1(command_t* command) {
uint8_t op = vm_getbits(command, 54, 3);
if(op) {
fprintf(MSG_OUT, "if (");
print_g_reg(vm_getbits(command,39,8));
print_cmp_op(op);
print_reg_or_data(command, vm_getbits(command, 55,1), 31);
fprintf(MSG_OUT, ") ");
}
}
static void print_if_version_2(command_t* command) {
uint8_t op = vm_getbits(command, 54, 3);
if(op) {
fprintf(MSG_OUT, "if (");
print_reg(vm_getbits(command, 15, 8));
print_cmp_op(op);
print_reg(vm_getbits(command, 7, 8));
fprintf(MSG_OUT, ") ");
}
}
static void print_if_version_3(command_t* command) {
uint8_t op = vm_getbits(command, 54, 3);
if(op) {
fprintf(MSG_OUT, "if (");
print_g_reg(vm_getbits(command, 43, 4));
print_cmp_op(op);
print_reg_or_data(command, vm_getbits(command, 55, 1), 15);
fprintf(MSG_OUT, ") ");
}
}
static void print_if_version_4(command_t* command) {
uint8_t op = vm_getbits(command, 54, 3);
if(op) {
fprintf(MSG_OUT, "if (");
print_g_reg(vm_getbits(command, 51, 4));
print_cmp_op(op);
print_reg_or_data(command, vm_getbits(command, 55, 1), 31);
fprintf(MSG_OUT, ") ");
}
}
static void print_if_version_5(command_t* command) {
uint8_t op = vm_getbits(command, 54, 3);
int set_immediate = vm_getbits(command, 60, 1);
if(op) {
if (set_immediate) {
fprintf(MSG_OUT, "if (");
print_g_reg(vm_getbits(command, 31, 8));
print_cmp_op(op);
print_reg(vm_getbits(command, 23, 8));
fprintf(MSG_OUT, ") ");
} else {
fprintf(MSG_OUT, "if (");
print_g_reg(vm_getbits(command, 39, 8));
print_cmp_op(op);
print_reg_or_data(command, vm_getbits(command, 55, 1), 31);
fprintf(MSG_OUT, ") ");
}
}
}
static void print_special_instruction(command_t* command) {
uint8_t op = vm_getbits(command, 51, 4);
switch(op) {
case 0: /* NOP */
fprintf(MSG_OUT, "Nop");
break;
case 1: /* Goto line */
fprintf(MSG_OUT, "Goto %" PRIu8, vm_getbits(command, 7, 8));
break;
case 2: /* Break */
fprintf(MSG_OUT, "Break");
break;
case 3: /* Parental level */
fprintf(MSG_OUT, "SetTmpPML %" PRIu8 ", Goto %" PRIu8,
vm_getbits(command, 11, 4), vm_getbits(command, 7, 8));
break;
default:
fprintf(MSG_OUT, "WARNING: Unknown special instruction (%i)",
vm_getbits(command, 51, 4));
}
}
static void print_linksub_instruction(command_t* command) {
uint32_t linkop = vm_getbits(command, 7, 8);
uint32_t button = vm_getbits(command, 15, 6);
if(linkop < sizeof(link_table)/sizeof(link_table[0]))
fprintf(MSG_OUT, "%s (button %" PRIu8 ")", link_table[linkop], button);
else
fprintf(MSG_OUT, "WARNING: Unknown linksub instruction (%i)", linkop);
}
static void print_link_instruction(command_t* command, int optional) {
uint8_t op = vm_getbits(command, 51, 4);
if(optional && op)
fprintf(MSG_OUT, ", ");
switch(op) {
case 0:
if(!optional)
fprintf(MSG_OUT, "WARNING: NOP (link)!");
break;
case 1:
print_linksub_instruction(command);
break;
case 4:
fprintf(MSG_OUT, "LinkPGCN %" PRIu16, vm_getbits(command, 14, 15));
break;
case 5:
fprintf(MSG_OUT, "LinkPTT %" PRIu16 " (button %" PRIu8 ")",
vm_getbits(command, 9, 10), vm_getbits(command, 15, 6));
break;
case 6:
fprintf(MSG_OUT, "LinkPGN %" PRIu8 " (button %" PRIu8 ")",
vm_getbits(command, 6, 7), vm_getbits(command, 15, 6));
break;
case 7:
fprintf(MSG_OUT, "LinkCN %" PRIu8 " (button %" PRIu8 ")",
vm_getbits(command, 7, 8), vm_getbits(command, 15, 6));
break;
default:
fprintf(MSG_OUT, "WARNING: Unknown link instruction");
}
}
static void print_jump_instruction(command_t* command) {
switch(vm_getbits(command, 51, 4)) {
case 1:
fprintf(MSG_OUT, "Exit");
break;
case 2:
fprintf(MSG_OUT, "JumpTT %" PRIu8, vm_getbits(command, 22, 7));
break;
case 3:
fprintf(MSG_OUT, "JumpVTS_TT %" PRIu8, vm_getbits(command, 22, 7));
break;
case 5:
fprintf(MSG_OUT, "JumpVTS_PTT %" PRIu8 ":%" PRIu16,
vm_getbits(command, 22, 7), vm_getbits(command, 41, 10));
break;
case 6:
switch(vm_getbits(command, 23, 2)) {
case 0:
fprintf(MSG_OUT, "JumpSS FP");
break;
case 1:
fprintf(MSG_OUT, "JumpSS VMGM (menu %" PRIu8 ")", vm_getbits(command, 19, 4));
break;
case 2:
fprintf(MSG_OUT, "JumpSS VTSM (vts %" PRIu8 ", title %" PRIu8
", menu %" PRIu8 ")", vm_getbits(command, 30, 7), vm_getbits(command, 38, 7), vm_getbits(command, 19, 4));
break;
case 3:
fprintf(MSG_OUT, "JumpSS VMGM (pgc %" PRIu8 ")", vm_getbits(command, 46, 15));
break;
}
break;
case 8:
switch(vm_getbits(command, 23, 2)) {
case 0:
fprintf(MSG_OUT, "CallSS FP (rsm_cell %" PRIu8 ")",
vm_getbits(command, 31, 8));
break;
case 1:
fprintf(MSG_OUT, "CallSS VMGM (menu %" PRIu8
", rsm_cell %" PRIu8 ")", vm_getbits(command, 19, 4), vm_getbits(command, 31, 8));
break;
case 2:
fprintf(MSG_OUT, "CallSS VTSM (menu %" PRIu8
", rsm_cell %" PRIu8 ")", vm_getbits(command, 19, 4), vm_getbits(command, 31, 8));
break;
case 3:
fprintf(MSG_OUT, "CallSS VMGM (pgc %" PRIu8 ", rsm_cell %" PRIu8 ")",
vm_getbits(command, 46, 15), vm_getbits(command, 31, 8));
break;
}
break;
default:
fprintf(MSG_OUT, "WARNING: Unknown Jump/Call instruction");
}
}
static void print_system_set(command_t* command) {
int i;
/* FIXME: What about SPRM11 ? Karaoke */
/* Surely there must be some system set command for that ? */
switch(vm_getbits(command, 59, 4)) {
case 1: /* Set system reg 1 &| 2 &| 3 (Audio, Subp. Angle) */
for(i = 1; i <= 3; i++) {
if(vm_getbits(command, 47 - (i*8), 1)) {
print_system_reg(i);
fprintf(MSG_OUT, " = ");
print_reg_or_data_2(command, vm_getbits(command, 60, 1), 47 - (i*8) );
fprintf(MSG_OUT, " ");
}
}
break;
case 2: /* Set system reg 9 & 10 (Navigation timer, Title PGC number) */
print_system_reg(9);
fprintf(MSG_OUT, " = ");
print_reg_or_data(command, vm_getbits(command, 60, 1), 47);
fprintf(MSG_OUT, " ");
print_system_reg(10);
fprintf(MSG_OUT, " = %" PRIu16, vm_getbits(command, 30, 15)); /* ?? */
break;
case 3: /* Mode: Counter / Register + Set */
fprintf(MSG_OUT, "SetMode ");
if(vm_getbits(command, 23, 1))
fprintf(MSG_OUT, "Counter ");
else
fprintf(MSG_OUT, "Register ");
print_g_reg(vm_getbits(command, 19, 4));
print_set_op(0x1); /* '=' */
print_reg_or_data(command, vm_getbits(command, 60, 1), 47);
break;
case 6: /* Set system reg 8 (Highlighted button) */
print_system_reg(8);
if(vm_getbits(command, 60, 1)) /* immediate */
fprintf(MSG_OUT, " = 0x%x (button no %d)", vm_getbits(command, 31, 16), vm_getbits(command, 31, 6));
else
fprintf(MSG_OUT, " = g[%" PRIu8 "]", vm_getbits(command, 19, 4));
break;
default:
fprintf(MSG_OUT, "WARNING: Unknown system set instruction (%i)",
vm_getbits(command, 59, 4));
}
}
static void print_set_version_1(command_t* command) {
uint8_t set_op = vm_getbits(command, 59, 4);
if(set_op) {
print_g_reg(vm_getbits(command, 35, 4));
print_set_op(set_op);
print_reg_or_data(command, vm_getbits(command, 60, 1), 31);
} else {
fprintf(MSG_OUT, "NOP");
}
}
static void print_set_version_2(command_t* command) {
uint8_t set_op = vm_getbits(command, 59, 4);
if(set_op) {
print_g_reg(vm_getbits(command, 51, 4));
print_set_op(set_op);
print_reg_or_data(command, vm_getbits(command, 60, 1), 47);
} else {
fprintf(MSG_OUT, "NOP");
}
}
static void print_set_version_3(command_t* command) {
uint8_t set_op = vm_getbits(command, 59, 4);
if(set_op) {
print_g_reg(vm_getbits(command, 51, 4));
print_set_op(set_op);
print_reg_or_data_3(command, vm_getbits(command, 60, 1), 47);
} else {
fprintf(MSG_OUT, "NOP");
}
}
void vm_print_mnemonic(vm_cmd_t *vm_command) {
command_t command;
command.instruction =( (uint64_t) vm_command->bytes[0] << 56 ) |
( (uint64_t) vm_command->bytes[1] << 48 ) |
( (uint64_t) vm_command->bytes[2] << 40 ) |
( (uint64_t) vm_command->bytes[3] << 32 ) |
( (uint64_t) vm_command->bytes[4] << 24 ) |
( (uint64_t) vm_command->bytes[5] << 16 ) |
( (uint64_t) vm_command->bytes[6] << 8 ) |
(uint64_t) vm_command->bytes[7] ;
command.examined = 0;
switch(vm_getbits(&command,63,3)) { /* three first bits */
case 0: /* Special instructions */
print_if_version_1(&command);
print_special_instruction(&command);
break;
case 1: /* Jump/Call or Link instructions */
if(vm_getbits(&command,60,1)) {
print_if_version_2(&command);
print_jump_instruction(&command);
} else {
print_if_version_1(&command);
print_link_instruction(&command, 0); /* must be pressent */
}
break;
case 2: /* Set System Parameters instructions */
print_if_version_2(&command);
print_system_set(&command);
print_link_instruction(&command, 1); /* either 'if' or 'link' */
break;
case 3: /* Set General Parameters instructions */
print_if_version_3(&command);
print_set_version_1(&command);
print_link_instruction(&command, 1); /* either 'if' or 'link' */
break;
case 4: /* Set, Compare -> LinkSub instructions */
print_set_version_2(&command);
fprintf(MSG_OUT, ", ");
print_if_version_4(&command);
print_linksub_instruction(&command);
break;
case 5: /* Compare -> (Set and LinkSub) instructions */
print_if_version_5(&command);
fprintf(MSG_OUT, "{ ");
print_set_version_3(&command);
fprintf(MSG_OUT, ", ");
print_linksub_instruction(&command);
fprintf(MSG_OUT, " }");
break;
case 6: /* Compare -> Set, always LinkSub instructions */
print_if_version_5(&command);
fprintf(MSG_OUT, "{ ");
print_set_version_3(&command);
fprintf(MSG_OUT, " } ");
print_linksub_instruction(&command);
break;
default:
fprintf(MSG_OUT, "WARNING: Unknown instruction type (%i)", vm_getbits(&command, 63, 3));
}
/* Check if there still are bits set that were not examined */
if(command.instruction & ~ command.examined) {
fprintf(MSG_OUT, " libdvdnav: vmcmd.c: [WARNING, unknown bits:");
fprintf(MSG_OUT, " %08"PRIx64, (command.instruction & ~ command.examined) );
fprintf(MSG_OUT, "]");
}
}
void vm_print_cmd(int row, vm_cmd_t *vm_command) {
int i;
fprintf(MSG_OUT, "(%03d) ", row + 1);
for(i = 0; i < 8; i++)
fprintf(MSG_OUT, "%02x ", vm_command->bytes[i]);
fprintf(MSG_OUT, "| ");
vm_print_mnemonic(vm_command);
fprintf(MSG_OUT, "\n");
}

28
src/vm/vmcmd.h Normal file
View File

@ -0,0 +1,28 @@
/*
* Copyright (C) 2000, 2001 Martin Norbäck, Håkan Hjort
*
* This file is part of libdvdnav, a DVD navigation library. It is modified
* from a file originally part of the Ogle DVD player.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef LIBDVDNAV_VMCMD_H
#define LIBDVDNAV_VMCMD_H
void vm_print_mnemonic(vm_cmd_t *command);
void vm_print_cmd(int row, vm_cmd_t *command);
#endif /* LIBDVDNAV_VMCMD_H */

353
src/vm/vmget.c Normal file
View File

@ -0,0 +1,353 @@
/*
* Copyright (C) 2000, 2001 Håkan Hjort
* Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net>
* 2002-2004 the dvdnav project
*
* This file is part of libdvdnav, a DVD navigation library. It is modified
* from a file originally part of the Ogle DVD player.
*
* libdvdnav 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.
*
* libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dvdread/nav_types.h>
#include <dvdread/ifo_types.h>
#include <dvdread/ifo_read.h>
#include "dvdnav/dvdnav.h"
#include "decoder.h"
#include "vm.h"
#include "getset.h"
#include "dvdnav_internal.h"
/* getting information */
int vm_get_current_menu(vm_t *vm, int *menuid) {
pgcit_t* pgcit;
int pgcn;
pgcn = (vm->state).pgcN;
pgcit = get_PGCIT(vm);
if(pgcit==NULL) return 0;
*menuid = pgcit->pgci_srp[pgcn - 1].entry_id & 0xf ;
return 1;
}
int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result) {
vts_ptt_srpt_t *vts_ptt_srpt;
int title, part = 0, vts_ttn;
int found;
int16_t pgcN, pgN;
vts_ptt_srpt = vm->vtsi->vts_ptt_srpt;
pgcN = get_PGCN(vm);
pgN = vm->state.pgN;
found = 0;
for (vts_ttn = 0; (vts_ttn < vts_ptt_srpt->nr_of_srpts) && !found; vts_ttn++) {
for (part = 0; (part < vts_ptt_srpt->title[vts_ttn].nr_of_ptts) && !found; part++) {
if (vts_ptt_srpt->title[vts_ttn].ptt[part].pgcn == pgcN) {
if (vts_ptt_srpt->title[vts_ttn].ptt[part].pgn == pgN) {
found = 1;
break;
}
if (part > 0 && vts_ptt_srpt->title[vts_ttn].ptt[part].pgn > pgN &&
vts_ptt_srpt->title[vts_ttn].ptt[part - 1].pgn < pgN) {
part--;
found = 1;
break;
}
}
}
if (found) break;
}
vts_ttn++;
part++;
if (!found) {
fprintf(MSG_OUT, "libdvdnav: chapter NOT FOUND!\n");
return 0;
}
title = get_TT(vm, vm->state.vtsN, vts_ttn);
#ifdef TRACE
if (title) {
fprintf(MSG_OUT, "libdvdnav: ************ this chapter FOUND!\n");
fprintf(MSG_OUT, "libdvdnav: VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i\n",
title, part,
vts_ptt_srpt->title[vts_ttn-1].ptt[part-1].pgcn ,
vts_ptt_srpt->title[vts_ttn-1].ptt[part-1].pgn );
}
#endif
*title_result = title;
*part_result = part;
return 1;
}
/* Return the substream id for 'logical' audio stream audioN.
* 0 <= audioN < 8
*/
int vm_get_audio_stream(vm_t *vm, int audioN) {
int streamN = -1;
if((vm->state).domain != DVD_DOMAIN_VTSTitle)
audioN = 0;
if(audioN < 8) {
/* Is there any control info for this logical stream */
if((vm->state).pgc->audio_control[audioN] & (1<<15)) {
streamN = ((vm->state).pgc->audio_control[audioN] >> 8) & 0x07;
}
}
if((vm->state).domain != DVD_DOMAIN_VTSTitle && streamN == -1)
streamN = 0;
/* FIXME: Should also check in vtsi/vmgi status what kind of stream
* it is (ac3/lpcm/dts/sdds...) to find the right (sub)stream id */
return streamN;
}
/* Return the substream id for 'logical' subpicture stream subpN and given mode.
* 0 <= subpN < 32
* mode == 0 - widescreen
* mode == 1 - letterbox
* mode == 2 - pan&scan
*/
int vm_get_subp_stream(vm_t *vm, int subpN, int mode) {
int streamN = -1;
int source_aspect = vm_get_video_aspect(vm);
if((vm->state).domain != DVD_DOMAIN_VTSTitle)
subpN = 0;
if(subpN < 32) { /* a valid logical stream */
/* Is this logical stream present */
if((vm->state).pgc->subp_control[subpN] & (1<<31)) {
if(source_aspect == 0) /* 4:3 */
streamN = ((vm->state).pgc->subp_control[subpN] >> 24) & 0x1f;
if(source_aspect == 3) /* 16:9 */
switch (mode) {
case 0:
streamN = ((vm->state).pgc->subp_control[subpN] >> 16) & 0x1f;
break;
case 1:
streamN = ((vm->state).pgc->subp_control[subpN] >> 8) & 0x1f;
break;
case 2:
streamN = (vm->state).pgc->subp_control[subpN] & 0x1f;
}
}
}
if((vm->state).domain != DVD_DOMAIN_VTSTitle && streamN == -1)
streamN = 0;
/* FIXME: Should also check in vtsi/vmgi status what kind of stream it is. */
return streamN;
}
int vm_get_audio_active_stream(vm_t *vm) {
int audioN;
int streamN;
audioN = (vm->state).AST_REG ;
streamN = vm_get_audio_stream(vm, audioN);
/* If no such stream, then select the first one that exists. */
if(streamN == -1) {
for(audioN = 0; audioN < 8; audioN++) {
if((vm->state).pgc->audio_control[audioN] & (1<<15)) {
if ((streamN = vm_get_audio_stream(vm, audioN)) >= 0)
break;
}
}
}
return streamN;
}
int vm_get_subp_active_stream(vm_t *vm, int mode) {
int subpN;
int streamN;
subpN = (vm->state).SPST_REG & ~0x40;
streamN = vm_get_subp_stream(vm, subpN, mode);
/* If no such stream, then select the first one that exists. */
if(streamN == -1) {
for(subpN = 0; subpN < 32; subpN++) {
if((vm->state).pgc->subp_control[subpN] & (1<<31)) {
if ((streamN = vm_get_subp_stream(vm, subpN, mode)) >= 0)
break;
}
}
}
if((vm->state).domain == DVD_DOMAIN_VTSTitle && !((vm->state).SPST_REG & 0x40))
/* Bit 7 set means hide, and only let Forced display show */
return (streamN | 0x80);
else
return streamN;
}
void vm_get_angle_info(vm_t *vm, int *current, int *num_avail) {
*num_avail = 1;
*current = 1;
if((vm->state).domain == DVD_DOMAIN_VTSTitle) {
title_info_t *title;
/* TTN_REG does not allways point to the correct title.. */
if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts)
return;
title = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1];
if(title->title_set_nr != (vm->state).vtsN ||
title->vts_ttn != (vm->state).VTS_TTN_REG)
return;
*num_avail = title->nr_of_angles;
*current = (vm->state).AGL_REG;
}
}
#if 0
/* currently unused */
void vm_get_audio_info(vm_t *vm, int *current, int *num_avail) {
switch ((vm->state).domain) {
case DVD_DOMAIN_VTSTitle:
*num_avail = vm->vtsi->vtsi_mat->nr_of_vts_audio_streams;
*current = (vm->state).AST_REG;
break;
case DVD_DOMAIN_VTSMenu:
*num_avail = vm->vtsi->vtsi_mat->nr_of_vtsm_audio_streams; /* 1 */
*current = 1;
break;
case DVD_DOMAIN_VMGM:
case DVD_DOMAIN_FirstPlay:
*num_avail = vm->vmgi->vmgi_mat->nr_of_vmgm_audio_streams; /* 1 */
*current = 1;
break;
}
}
/* currently unused */
void vm_get_subp_info(vm_t *vm, int *current, int *num_avail) {
switch ((vm->state).domain) {
case DVD_DOMAIN_VTSTitle:
*num_avail = vm->vtsi->vtsi_mat->nr_of_vts_subp_streams;
*current = (vm->state).SPST_REG;
break;
case DVD_DOMAIN_VTSMenu:
*num_avail = vm->vtsi->vtsi_mat->nr_of_vtsm_subp_streams; /* 1 */
*current = 0x41;
break;
case DVD_DOMAIN_VMGM:
case DVD_DOMAIN_FirstPlay:
*num_avail = vm->vmgi->vmgi_mat->nr_of_vmgm_subp_streams; /* 1 */
*current = 0x41;
break;
}
}
#endif
void vm_get_video_res(vm_t *vm, int *width, int *height) {
video_attr_t attr = vm_get_video_attr(vm);
if(attr.video_format != 0)
*height = 576;
else
*height = 480;
switch(attr.picture_size) {
case 0:
*width = 720;
break;
case 1:
*width = 704;
break;
case 2:
*width = 352;
break;
case 3:
*width = 352;
*height /= 2;
break;
}
}
int vm_get_video_aspect(vm_t *vm) {
int aspect = vm_get_video_attr(vm).display_aspect_ratio;
if(aspect != 0 && aspect != 3) {
fprintf(MSG_OUT, "libdvdnav: display aspect ratio is unexpected: %d!\n", aspect);
return -1;
}
(vm->state).registers.SPRM[14] &= ~(0x3 << 10);
(vm->state).registers.SPRM[14] |= aspect << 10;
return aspect;
}
int vm_get_video_scale_permission(vm_t *vm) {
return vm_get_video_attr(vm).permitted_df;
}
video_attr_t vm_get_video_attr(vm_t *vm) {
switch ((vm->state).domain) {
case DVD_DOMAIN_VTSTitle:
return vm->vtsi->vtsi_mat->vts_video_attr;
case DVD_DOMAIN_VTSMenu:
return vm->vtsi->vtsi_mat->vtsm_video_attr;
case DVD_DOMAIN_VMGM:
case DVD_DOMAIN_FirstPlay:
return vm->vmgi->vmgi_mat->vmgm_video_attr;
default:
assert(0);
}
}
audio_attr_t vm_get_audio_attr(vm_t *vm, int streamN) {
switch ((vm->state).domain) {
case DVD_DOMAIN_VTSTitle:
return vm->vtsi->vtsi_mat->vts_audio_attr[streamN];
case DVD_DOMAIN_VTSMenu:
return vm->vtsi->vtsi_mat->vtsm_audio_attr;
case DVD_DOMAIN_VMGM:
case DVD_DOMAIN_FirstPlay:
return vm->vmgi->vmgi_mat->vmgm_audio_attr;
default:
assert(0);
}
}
subp_attr_t vm_get_subp_attr(vm_t *vm, int streamN) {
switch ((vm->state).domain) {
case DVD_DOMAIN_VTSTitle:
return vm->vtsi->vtsi_mat->vts_subp_attr[streamN];
case DVD_DOMAIN_VTSMenu:
return vm->vtsi->vtsi_mat->vtsm_subp_attr;
case DVD_DOMAIN_VMGM:
case DVD_DOMAIN_FirstPlay:
return vm->vmgi->vmgi_mat->vmgm_subp_attr;
default:
assert(0);
}
}