project-x/0000700000175000017500000000000010412367136014120 5ustar supermariosupermarioproject-x/Copying0000600000175000017500000004364110102605506015455 0ustar supermariosupermario 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. Copyright (C) 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. , 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. project-x/MANIFEST.MF0000600000175000017500000000027210310657276015561 0ustar supermariosupermarioManifest-Version: 1.0 Main-Class: net.sourceforge.dvb.projectx.common.Start Created-By: 1.2.2 (Sun Microsystems Inc.) Class-Path: lib/commons-net-1.3.0.jar lib/jakarta-oro-2.0.8.jar project-x/ReadMe.txt0000600000175000017500000001451310370031166016016 0ustar supermariosupermario/==============================================================================/ ProjectX - a free Java based demux utility Copyright (C) 2001-2006 dvb.matt, All Rights Reserved By the authors, ProjectX is intended for educational purposes only, as a non-commercial test project. /==============================================================================/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA /==============================================================================/ This program is completely designed as a test, therefore it mostly implements its own code instead of a derivation of an ISO reference source or any other code. Considerable effort has been expended to ensure an useful implementation, even in cases where the standards are ambiguous or misleading. Do not expect any useful output, even if that may be possible. For a program compliant to the international standards ISO 11172 and ISO 13818 it is inevitable to use methods covered by patents in various countries. The authors of this program disclaim any liability for patent infringement caused by using, modifying or redistributing this program. /==============================================================================/ This program includes software developed by the Apache Software Foundation (http://www.apache.org/). This software contains fast high-quality IDCT decoder by Miha Peternel. /==============================================================================/ This program is provided in sourcecode form only, because it is meant for educational purposes. Binaries of this project itself will not be included (may not apply to external libraries) If you need an executable, you have to compile the package by yourself, or you ask someone to do so for you. /==============================================================================/ For a compilation, you need a Java SDK, which is available for various platforms. All classes should work at least with Sun's JDK/J2RE 1.2.2 and higher. Note: under special circumstances, some graphic drivers/locales cause big troubles with some versions of JRE's on different OS's. Extract all files from the received archive to a separate directory. Note: dependent on the used JDK/JRE, ensure that the directory does not start with a '!'-sign or similars, otherwise you'll get an error like 'main class not found' /** * sample of a compilation (may differ on your system) : */ (A) open "build.bat" with an editor and check/correct the entry/path of JAVA_HOME of your installed JDK (B) execute the "build.bat" on its place. that will - compile all sources, - build the .jar file and - copies the resource files from the resource folder into the new .jar, Notes: [i] now, we made a package for the sources, the file sources.lst points to every required sourcefile and its location [ii] the following libraries are required on this place from the V 0.82.0, related to the executed .jar: - lib/commons-net-1.3.0.jar (compiled with JDK 1.2.2) *) - lib/jakarta-oro-2.0.8.jar (compiled with JDK 1.2.2) *) [iii] the following libraries are optional from the V 0.82.0 : - lib/idct***.dll (win32 optimized lib's for a faster preview) copy one of them to the systems folder or where the compiled .jar is located [iv] dependent on the used JDK, you'll encounter some 'warnings' about 'using a deprecated API' that's not critical, as long as an actual JDK still supports these methods *) further informations and newer versions (mostly compiled with JDK 1.4.2) you'll find at: 'jakarta.apache.org/site/binindex.cgi', look for 'Commons Net' and 'ORO' - using newer lib's possibly requires an update of the 'build.bat' and 'MANIFEST.MF' ! (C) additional received resource files (e.g. other language files) can be added to the .jar file, later, or you put them into the same folder where the compiled .jar is executed. (D) new with version 0.90 and later: it is possible to compile and run this program without the gui (means all source files in /gui/..). so no javax.swing component will be used, calling it from the commandline. if you can't start the non-gui version without a X server, try to call pjx with the 'headless' option java -Djava.awt.headless=true -jar ProjectX.jar [options] the compiling process doesn't take more than about 30 seconds. /==============================================================================/ the 2 official ProjectX sites: Project + D/L, only @ sourceforge.net/projects/project-x/ voluntary Support for the official (non-modified) version, only @ forum.dvbtechnics.info /==============================================================================/ CREDITS - thanx to all the people, who gave hints, files and other things to this project: dvb.matt - father of Project-X Lucike - forum hoster, documentation TheHorse - keyboardcontrol of preview java.lang - conditional patch of H-resolution R-One - DTS support ghost - dreambox file segment completion roehrist - CVS, X-input pstorch - i18n support chrisg - Topfield disk access (AddOn) jazzydane - danish translation Kano / RoEn - Unix buils script Eric Albert - BrowserLauncher catapult,Bonni - Topfield 5x00 export MartinR - Gui-BaseOutputFileName ...and all other supporters... /===============================================================================/ project-x/ReleaseNotes_0.90.4.00.txt0000600000175000017500000000024510413071170020272 0ustar supermariosupermario Note: - the archive contains all necessary files Project X 0.90.4.00 30.03.2006 basic release: Project X 0.90.4 see ReleaseNotes_0.90.4.txt project-x/ReleaseNotes_0.90.4.txt0000600000175000017500000000275410413071212020060 0ustar supermariosupermario Note: - the archive contains all necessary files Project X 0.90.4.00 30.03.2006 collects all patches from 0.90.3 series fixes: - better preview of bad I-Frames, and some rare resolutions - exception at older JRE when saving preview frame with DAR option - wrong assoziation at ac3 header look-up - exceptions when decoding RDS-data from mpeg frames - ttx-pagematrix info erased at process completion - dvb subicture, page id 0 wasn't accepted - ... changes: - omits padding packets in TS private streams - mpv ES demux, omits data from seq.end to seq.start - more error and processing logs - re-scan when changing stream type assignment - ac3.bin incl. 192kbs 2/0 frame - ... new: - subpicture, 2nd export format accessible - dvb subpicture, new entry for mtv adria - export RDS-data stream 0xDA (e.g. video EPG) - optional pre-read buffer (1MB, for special access acceleration), thx to Artemis1121 - optional creation of cuttermaran project file (info-xml >=1.61), thx to Arnaud - italian language file, thx to mfsav - modif. idct sources for OS2, thx to Ronald - pes demux, check for errors in pes_extension (probs with some vdr-plugins) - ttx, enhanced parity check (drop lines with more than x parity errors); iniKey only, std: SubtitlePanel.maxParityErrors=2 (0..40) - mpa decoding, wav/aif export with optional fade-in/out; iniKey only, std: AudioPanel.fadeInOutMillis=2000 (1..5000) - ... project-x/build.bat0000644000175000017500000000267110355537716015740 0ustar supermariosupermario@echo off rem test if JAVA_HOME is already set in the system environment if exist "%JAVA_HOME%\bin\javac.exe" goto JAVA_HOME_SET rem IMPORTANT! Edit the next line and set JAVA_HOME according to your environment. set JAVA_HOME=C:\programme\jdk150 rem test if JAVA_HOME is set correctly now if exist "%JAVA_HOME%\bin\javac.exe" goto JAVA_HOME_SET echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! echo ! Error: JAVA_HOME not found ! echo ! Please correct the build.bat file and set the JAVA_HOME path variable. ! echo ! If not installed a Java SDK can be downloaded from http://java.sun.com ! echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! pause goto END :JAVA_HOME_SET echo deleting old ProjectX.jar file del ProjectX.jar echo creating build subdirectory mkdir build echo compiling ProjectX with JAVA_HOME=%JAVA_HOME% "%JAVA_HOME%\bin\javac.exe" -O -classpath lib\commons-net-1.3.0.jar -d build @sources.lst if errorlevel 1 goto ERROR echo copying resources copy resources\*.* build if errorlevel 1 goto ERROR echo building ProjectX.jar file "%JAVA_HOME%\bin\jar.exe" cfvm ProjectX.jar MANIFEST.MF -C build . if errorlevel 1 goto ERROR goto END :ERROR echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! echo ! Some Errors occured, stopping build ! echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! pause :END project-x/build.sh0000600000175000017500000000111310310662536015550 0ustar supermariosupermario#! /bin/bash # Build script for ProjectX under Linux if [ -e ./ProjectX.jar ] ; then rm -f ./ProjectX.jar fi if [ -d ./build ] ; then rm -rf ./build fi mkdir -p build javac -encoding "ISO-8859-1" -deprecation -O -g:none -classpath lib/commons-net-1.3.0.jar:lib/jakarta-oro-2.0.8.jar -d build @sources.lst cp ./resources/* ./build jar cfvm ProjectX.jar MANIFEST.MF -C build . ###################################################### # Change Log # # 5.9.2005 by fredmuc # - added -deprecation switch for javac # - renamed bin directory to build # - conditional removal of files # project-x/htmls/0000700000175000017500000000000010745203152015243 5ustar supermariosupermarioproject-x/htmls/cli.html0000600000175000017500000000364510317321446016714 0ustar supermariosupermario CL-Interface
  
CL-Interface:
Note: CL doesn't load the GUI components, except with switch [-gui]
...starts the GUI
switches and inputfiles can be in any order

options:
[-ini ] ..use that specified iniFile instead of the standard
[-dvx1] ..create a .d2v ProjectFile on demux
[-dvx2] ..create a .d2v ProjectFile + .ac3.wav (RIFF WAVE Header)
[-dvx3] ..create a .d2v ProjectFile + .mpa.wav (RIFF WAVE Header)
[-dvx4] ..create a .d2v ProjectFile + .ac3.wav + mpa.wav (RIFF WAVE Header)
[-out ] ..use that specified directory for output
[-name ] ..use that specified filename for output
[-cut ] ..use that text based file as cutpoint list
[-id ] ..use only these (P)IDs, separated by comma \",\"
[-gui] ..display the GUI using all given CLI options
[-log] ..write the normal logfile
[-saveini] ..save changes made bei CLI in active .ini [-split ] ..split output at xxx MB
[-demux, -tom2p, -topva, -tovdr, -tots, -filter] ..action types
  
project-x/htmls/de/0000700000175000017500000000000010745203152015633 5ustar supermariosupermarioproject-x/htmls/de/cli.html0000600000175000017500000000406510317321534017277 0ustar supermariosupermario CL-Interface
  
CL-Interface:
Hinweis: CL laedt kein GUI (Swing), ausser bei Option [-gui]
...startet die graphische Oberflaeche
Reihenfolge der Kommandostrings ist beliebig, nicht erkannte Optionen gelten als Eingabedatei

Optionen:
[-ini ] ..verwendet eine andere Konfigurationsdatei als die Standard X.ini
[-dvx1] ..erstelle eine .d2v Projektdatei beim demuxen
[-dvx2] ..erstelle eine .d2v Projektdatei + .ac3.wav (RIFF WAVE Header)
[-dvx3] ..erstelle eine .d2v Projektdatei + .mpa.wav (RIFF WAVE Header)
[-dvx4] ..erstelle eine .d2v Projektdatei + .ac3.wav + mpa.wav (RIFF WAVE Header)
[-out ] ..benutze diesen Pfad als Ausgabepfad
[-name ] ..benutze diesen Dateinamen fuer Ausgabedatei
[-cut ] ..nutze diese Datei als Schnittliste
[-id ] ..benutze nur diese (P)IDs, getrennt durch Komma \",\"
[-gui] ..oeffne GUI mit den angegebenen CLI Optionen
[-log] ..schreibe eine normale Logdatei
[-saveini] ..bei CLI Aufruf geaenderte Einstellungen speichern
[-split ] ..Ausgabe teilen bei xxx MB
[-demux, -tom2p, -topva, -tovdr, -tots, -filter] ..Aktionstypen
  
project-x/htmls/de/faq.html0000600000175000017500000002734210140632456017304 0ustar supermariosupermario faq
  
NAQs & FAQs

im folgenden werden für diejenigen, die dem 'Geist' von Projekt X folgen und sich mit der Materie auseinandersetzen möchten, in loser Folge ein paar Anregungen und Denkanstöße zum Studieren und Ausprobieren gegeben.

im übrigen kann man sich weitergehenden Problemen nur annehmen, wenn diese auch im Forum geäußert werden. Andernfalls werden diese ungelöst bleiben.
Die Fülle an verfügbarer Hard- und Software mit all ihren Eigenheiten zum Mitschnitt von DVB-Aufnahmen erfordert u.U. eine Abweichung von den Allgemeineinstellungen in Pj. X .
 
 

1.) Ich bin gehörlos und möchte gern die Teletext-Untertitel aus einer aufgezeichneten Sendung mit auf meine DVD übernehmen. 

Voraussetzungen:
1) Untertitel werden im Teletext mit übertragen. (z.B. Tafel 149, 150, 888, ...)
2) Das Aufzeichnungsprogramm muss in der Lage sein, den Bild-/Ton-und Teletext-Datenstrom unverändert als separate Datei(en) oder alles inklusive aufzuzeichnen.
3) Die Sendeanstalten übertragen die zur späteren Bild-Synchronisation wichtigen Zeitangaben. Nicht alle tun dies oder nicht richtig!
4) Ein Authoringprogramm, dass eines der Untertitelformate unterstützt.

Vorgehensweise:
1) Aufzeichnen der Sendung.
2) Einladen der Dateien als eine Collection in Projekt X, wobei eine/mehrere separate Teletextdatei(en) zuletzt stehen.
3) im Reiter {teletext}die Tafel(n) mit den Untertiteln von Interesse (max. 6) auswählen bzw. eingeben.
Zusätzlich das Ausgabeformat entsprechend dem Authoringprogramm auswählen.
4) falls nötig, Schnittpunkte über die {collection specials} setzen und weitere Einstellungen vornehmen.
5) im Reiter {main} {demux} wählen und {Go}.
6) DVD mit den neu erzeugten Dateien authoren.

Hinweise:
Der einfachste und sicherste Weg für diesen Zweck ist die Kette: Aufnahme -> Projekt X -> ifoedit -> DVD.
Das im Ergebnis kein Startmenü vorliegt, lässt sich verschmerzen.

vorher ist jedoch einmalig Einiges einzustellen und das Ergebnis zu testen:
1) in Projekt X im Reiter {teletext} das Format {SUP} wählen, dazu {show preview} aktivieren und einen {Textfont} wählen.
2) entsprechend o.g. Vorgehensweise den Vorgang starten.
3) in der {subtitle preview} ist zu subjektiv beurteilen, ob einem die gewählte Schriftart zusagt und der Text im allgemeinen den schwarzen Hintergrund gut ausfüllt jedoch nicht überschreibt. Entsprechend sind die speziellen SUP-Werte lt. Pj.X Dokumentation zu variieren.
+ Es ist zu beachten, das die Plazierung der UTs im Bild von der Auflösung der Bilddatei abhängen! Die Vorgaben entsprechen hierbei alle dem üblichen D1 Standard von 720*576 .
4) in ifoedit sind nun nacheinander die Videodatei, Audiodatei und UT-Datei ( xyz[X].sup ) und evtl. Kapiteldatei zu laden und mit {ok} als DVD zu kompilieren.
5) Da die erzeugten .IFO-Dateien noch Standard-Farbwerte für Menüs/Untertitel enthalten, müssen diese -abgesehen von anderen notwendigen Einstellungen, die jedoch nicht mit den UTs im Zusammenhang stehen- im Nachhinein für die Teletextfarben angepasst werden.
+ zusätzlich zu den erzeugten .IFOs ist noch, falls vorhanden, eine spezielle vorgefertigte COLORS.IFO mit den 'neuen' Farben zu laden und dort im Menü VTS_PGCITI der Eintrag VTS_PGC_1 zu wählen und dann im ifoedit-Menü der Punkt {subtitle colors} {copy colors..}, andernfalls müssen alle Farbwerte manuell eingegeben werden.
+ In der neuen VTS_xx_0.IFO ist derselbe Eintrag zu wählen, dann jedoch statt {copy...} {paste colors...}! Die Änderungen sind in dieser .IFO zu speichern.
6) das erzeugte Titleset auf eine -RW brennen bzw. in einem Softwarespieler testen.

Besonderheiten:
1) das SUP und SSA Format übernehmen die Vordergrundfarben weitestgehend so wie im Teletext. Im SUP Format sind jedoch nur 4 Farben je Einblendung zulässig (zumeist halbtransparenter Text-Hintergrund eingeschlossen), wodurch sich ggfs. zwangsläufig Änderungen in der Darstellung ergeben. Ab der V.081.6 int10 werden Schriften, die im Original nicht schwarz hinterlegt sind, zur besseren Unterscheidung kursiv dargestellt, so es die gewählte Schriftart auch unterstützt.
2) Synchronität: (siehe auch Voraussetzung 3)
+ abhängig von Sender und Tafel, sind die Ergebnisse tlw. sehr unterschiedlich.
+ unmöglich ist es derzeit mangels notwendiger Daten bei: Kabel1, NDR, ...
Anm: mit der V.081.7 wurde die Teletextausgabe überarbeitet und sollte nun (korrekte Insertion in den jeweiligen DPC's vorausgesetzt) genauso synchron sein wie bei der Live-ausgabe (Schnitte eingeschlossen)
3) auch Untertitel unterliegen dem Urheberrecht. Bei der weiteren Verwendung ist das zu beachten.
 

2.) Ich habe eine 2 Kanalton Aufnahme von z.B. Worldnet, eine mit Audiodescription z.B. von 3sat bzw. eine, bei der zwar in 2Kanal gesendet wird, mich aber nur ein Kanal interessiert, und möchte die Kanäle trennen.

Dazu gibt es in der Kartei {audio} die Option {2channel to 2*single}.
Das funktioniert allerdings nur beim Ausgangsformat: MPEG-1 Audio Layer2 48kHz zw. 112...384kbps.
Dabei wird die Bitrate in den neuen 1Kanal Dateien so niedrig wie möglich, aber konstant gehalten.
Geschehen kann das bei allen Bearbeitungsschritten, die eine MPEG Audiodatei überprüfen.
Wenn bei bestimmten Dateien die Zielbitrate für 1Kanal ausserhalb zulässiger Werte liegt, werden diese automatisch ins StereoFormat gewandelt.
 

3.) Ich habe eine Aufnahme, die (mehrfach) zwischen verschiedenen Bitraten und/oder mono/stereo etc. wechselt. Beim Wandeln nach *.wav oä. bricht mein Programm immer ab oder sie klingt wie "Mickey Mouse".

Dazu gibt es in der Kartei {audio} die Optionen {single to ....}.
Möchte man eine Stereodatei, ist die Option {single to jointstereo} bzw. {single to jointstereo} zu wählen.
Dabei werden mono-Teile zu stereo(2fach mono) gewandelt. Die Ausgangsdatei erhält dabei über die gesamte Länge eine einheitliche Bitrate (wenn nötig auch der bereits stereo-Teil).
Das funktioniert allerdings nur beim Ausgangsformat: MPEG-1 Audio Layer2 48kHz zw. 56...192kbps.
Geschehen kann das bei allen Bearbeitungsschritten, die eine MPEG Audiodatei überprüfen.

Reicht stattdessen eine Monodatei, ist die Option {2channel to 2*single} zu wählen.
Mono-Teile werden dabei direkt kopiert und die Bitrate/Modi wenn nötig angepasst, 2kanalige wie beschrieben gewandelt.

Enthält die Aufnahme von der Wandlung nicht unterstützte Frames, wird die gesamte Wandlung nicht durchgeführt.
Stattdessen kann dies dann aber über die Wandlung nach PCM erfolgen.
 

4.) Ich habe eine (S)VCD, und dort werden massenhaft Fehler gemeldet

Pj. X ist in erster Linie für DVB Daten gedacht.
(S)VCD sind zwar MPEG Daten, aber in einem speziellen CD-XA Container speziell für transportable Datenträger verpackt und müssen daher vorher entpackt werden.
Weiters ist u.U. bei {specials2} {get only enclosed PES packs..} zu deaktivieren.
(S)VCDs nach dem jap./amerik. Standard werden jedoch zudem noch nicht unterstützt.
 

5.) Ich habe eine PVA-Aufnahme mit vielen Audiofehlern (inserts) in der 'Hauptspur'. Das Abspielen scheint aber fehlerfrei

Es ist bei {specials2} {strictly PVA specs for Audio..} zu aktivieren.
Sollte so überhaupt keine Audiospur gefunden werden, erzeugt das Aufzeichnungsprogramm keine konforme PVA-Tonspur.
Treten die Fehler bei aktivierter Option auf, erzeugt das Aufzeichnungsprogramm ebenso keine konforme PVA-Tonspur, jedoch läßt sich das mit dem Deaktivieren der Option umgehen.
 

6.) Ich habe eine PVA-Aufnahme mit mehreren Tonspuren, jedoch mit vielen Audiofehlern (inserts) nur in den zusätzlichen. Die 'Hauptspur' ist o.k.

Es ist bei {main} {i} einmal zu drücken.
Anschließend nacheinander die in der darunter erstellten Liste eine ID nach der anderen (von den zusätzl. Tonspuren) zu wählen und mit {e} in eine neue Datei zu speichern.
Die neuen Dateien dann der aktuellen Collection hinzufügen und den normalen Vorgang starten.
Die in der PVA-Datei noch vorhandenen Tonspuren sollten vorher über die spezielle PID-Liste abgewählt werden.
 

7.) Ich habe eine TS-Aufnahme, jedoch bricht der Vorgang bereits frühzeitig mit der Meldung "PID scrambled, ignored" ab. Die Aufnahme ist aber nicht verschlüsselt.

Es ist bei {specials1} {ignore scrambled TS packets} zu deaktivieren. Wenngleich X auch ohnedies weiterhin nach unverschlüsselt markierten Paketen weitersucht, um daraus verwertbare Daten zu erhalten.

Wird stattdessen auf der erwarteten PID eine Meldung wie "PID xyz (payload ...) -> ignored" ausgegeben, sind in der {collection specials} {PIDlist} diese und alle weitern wesentlichen PIDs einzugeben, um in diesen nach verwertbaren Daten zu suchen.
Selbst wenn die TS-Pakete ztw. verschlüsselte Daten enthalten, jedoch nicht als "scrambled" markiert sind, wird die Suche nach Daten fortgesetzt und solange nicht ignoriert, bis bekannte Startcodes erkannt werden die einen Abbruch bzw. das 'Weitersammeln' rechtfertigen.
 

8.) Ich habe eine Radio-Aufnahme, die an manchen Stellen Störungen hat. Beim Demux werden diese Stellen mit Stille o.ä. zum Sync-Erhalt aufgefüllt. Kann man das verhindern?

Es ist bei {specials2} {take only 1st audio PTS...} zu aktivieren. Dann werden die Fehlstellen ohne weiteren Ausgleich der Audiospur-eigenen Zeitlinie übergangen.
 

...

  
project-x/htmls/de/index.html0000600000175000017500000000404510317320712017632 0ustar supermariosupermario Project X - Online Hilfe


Hilfe


Inhalt:

Online Resourcen:

project-x/htmls/faq.html0000600000175000017500000002340410140726124016703 0ustar supermariosupermario faq
  
NAQs & FAQs

For those following the 'spirit' of Project X, who want to learn more about this topic, we provide some loosely coupled thoughts and tips which might be useful.

Further problems can only be solved if they are discussed in the forum. Otherwise they might never be solved.
The overwhelming presents of different hard- and software for DVB recording might require settings which are different from the standard in Project X.
 
 

1.) I'm deaf and I want to transfer the teletext-subtitles from a recorded broadcasting to a DVD. 

Preconditions:
1) Subtitles are transmitted via teletext. (e.g. page 149, 150, 888, ...)
2) The recording software must be capable to capture the Video-/Audio- and Teletext stream without a change to one ore several files.
3) The broadcasting company transmits the timestamps to synchronize the texts with the picture. Not all of them are doing this or not correctly!
4) A DVD-Authoring application which is supporting subtitle formats.

Walk through:
1) record the broadcast.
2) load the file as one collection into Project X, where one or more teletext files are given at the end.
3) choose in the tab {teletext}the page(s) with the subtitles you want (max. 6).
Additionally you have to choose the output format according to your authoring application.
4) if necessary: set cut-point via {collection specials} and set additional options.
5) choose {demux} in the main window and push {Go}.
6) author your new DVD with the created files.

Hint:
The easiest and best way for this purpose is the following processing chain: record -> Project X -> ifoedit -> DVD.
The missing start menu is not important.

before you start you have to set some properties and to check the result:
1) choose the format {SUP} in the tab {teletext} in Project X. Activate {show preview} and choose a {Text font}.
2) start the process according the the steps given above.
3) you have to check if the chosen font in the {subtitle preview} is as you like and if the text fills the black background but not doesn't exceeds the borders. You have to adjust the special SUP-values according to the Project X documentation.
+ take into consideration that the position of the subtitles within the picture depends on the resolution of the picture file. The default values fit the common D1 standard of 720*576.
4) in ifoedit you have to load the video file, audio file, subtitle-file ( xyz[X].sup ) and optionally a chapter file and finally compile this with {ok} to a DVD file structure.
5) the created .IFO-files have default color values for menus and subtitles. These have to be adjusted to the teletext colors.
+ additionally to the created .IFOs you have to load a COLORS.IFO (if existing) with the 'new' colors. In the menu VTS_PGCITI choose the entry VTS_PGC_1 and in the ifoedit-menu the entry {subtitle colors} {copy colors..}, otherwise you have to set all color-values manually.
+ you have to choose the same entry in the new VTS_xx_0.IFO, but instead of {copy...} choose {paste colors...}! These changes have to be saved in this .IFO.
6) the created title set has to be burned on a -RW and tested with your standalone DVD-player.

<>Particularities:
1) the SUP and the SSA format take the text colors as far as possible from the teletext. There are only 4 colors valid In the SUP format for each occurance (mostly half-transparent text-background included), this might cause differences in the result. From the V.081.6 int10 onwards fonts, which are not provided with a black background are displayed in Italic (if supported by the font) to state the difference.
2) Synchronization: (see Preconditions 3)
+ the results are (very) differently dependent on the station and page
+ because of missing data it's impossible for the stations: Kabel1, NDR, ...
Comment: the teletext output was reworked in V.081.7 and should be as synchrony as the live output (including cuts) provided that correct insertions are made into the appropriate DPC's.
3) please take into account the subtitles are protected by copyright.
 

2.) I have a 2 audio channel record from e.g. Worldnet, a audio description e.g. from 3sat or a recording where only 1 channel is of interest and want to separate the channels.

Therefor we have the tab {audio} and the option {2channel to 2*single}.
This works only with the output format: MPEG-1 Audio Layer2 48kHz between 112...384kbps.
The bitrate in the new 1 channel files is kept as low but as constant as possible.
This can be done with all jobs which check a MPEG audio file.
If the target bitrate exceeds valid values the file format is automatically transformed to stereo.
 

3.) I have a recording which changes (many times) between different bitrates and/or mono/stereo. The program crashes during processing or the result sounds like "Mickey Mouse".

Therefor we have the tab {audio} and the option {single to ....}.
If you want a stereo file you have to chose the option {single to jointstereo} or {single to jointstereo}.
With these options the mono parts are transformed to (2 times mono). The output file is then created with a constant bitrate over the full length (if necessary also the stereo parts).
This works only with the output format: MPEG-1 Audio Layer2 48kHz between 56...192kbps.
This can be done with all jobs which check a MPEG audio file.

If a mono-file is sufficient you can chose the option {2channel to 2*single}.
Mono parts are copied directly and the bitrate is adjusted if necessary. 2 channel parts are transformed as described.

If the recording contains non supported frames the whole transformation is not performed.
Instead this can be achieved via transformation to PCM.
 

4.) I have a (S)VCD with a lot of errors

Project X is made for DVB data primarily.
(S)VCD contains MPEG data, but in a special CD-XA container especially made for portable media. These must be extracted before.
You might have to deactivate the {get only enclosed PES packs..} option in {specials2}.
(S)VCDs according to the jap./amerik. standard are not yet supported.
 

5.) I have a PVA-Recording with a lot of audio errors (inserts) in the 'mainstream'. I don't recognize errors during play.

Your have to activate the {strictly PVA specs for Audio..} option in {specials2}.
If there can't be found any audio stream the recording application created a non-standard PVA audio stream.
If the errors occour with activated option then the recording application produces a non-standard PVA audio stream but this can be worked around with deactivating this option.
 

6.) I have a PVA-Recording with several audio stream with a lot of error (inserts). But only in the additional stream the main audio stream is o.k.

First click {i} in the main window.
Then you have to choose one ID after the other (of the additional streams) and save them in a new file.
Then add these new files to the collection and start the job again.
The additional audio stream in the PVA file should be deselected before processing.
 

7.) I have a TS-Recording where the job stops with the message "PID scrambled, ignored", but this recording is not scrambled.

Deactivate {ignore scrambled TS packets} in {specials1}. X looks anyway for unscrambled packets for processing.

If the message "PID xyz (payload ...) -> ignored" is given while parsing an expected PID, you have to enter these and any other PIDs you want in the {PIDlist} in {collection specials}.  Then X is searching these PIDs for usable data.
Even if the TS-Pakets contain scrambled data from time to time, but the pakets are not marked as "scrambled", the search doesn't ignore these pakets until well known startcodes are recoknized which cause a stop.
 

8.) I have a radio recording which has disturbances. While demuxing these parts are filled with silence or something like that for synchronization. Can this behavior be disabled?

Activate the option {take only 1st audio PTS...} in {specials2}. Then these parts are ignored without further compensation.
 

...

  
project-x/htmls/images/0000700000175000017500000000000010745203152016510 5ustar supermariosupermarioproject-x/htmls/images/px.gif0000600000175000017500000000337010140632456017635 0ustar supermariosupermarioGIF89a#TИذؠ,#T0I8ͻ`(dihlp,tmx|pH,Ȥrl:ШtJZجvzxL.zn|N~ J[2HY!5 EUÐ˺0FSƣ н 2 CQₔ! br@ڌx Sz7Bp(A-VEaӹh? TƇ*N7:VEĤ5@/ 'nRR̥|SHBdf&z(՚*@Ƭ䶠6IJHZt:XQ]lӤ D]5Hr;UD"}M^6$ʠnրÞu2 O&=x%G ny9*`Nc ;L J qmH$9r OmEA.u - ץ&=Cx 59Cst  FgF JV#bPB=xds;r"|p"vpbZ Ĉt(e8y٤?>A;_(iv·#XPV6U4eylO.O^tu&Ah('FtXM}e I,bAu:!j\=.SNڀ|W~)%=G~J]կRaLӀJ#2ܵkLZ,Z:{k[~u zવ=ފ_6*(nj γe5HVCdI"NAHsAkO !TNq+o76NadOjB0+ #pACeLjrC;vQքA/{È䀟U9PY;;GɕJ}*̋aLӼ8U99@:YJLp'jA<0o߿R *ތ1_?L3h>*ZEgnvwt:TQyb$U@hFXQ ohL_ӴkJָx#[׾D_;*" V:d'KZͬf7zl;project-x/htmls/images/right.gif0000600000175000017500000000206010102604054020305 0ustar supermariosupermarioGIF89aO!Y)L)Mgyz];)CXѶ.CGڳ-,z4phF^&UW8v;p}s[-KTW5o^Q]xU[a[ԃځ.w?[vz=0JN@_勦܍ #~sch3}1v:|vaKK.57]Kz@h$@O^z%AMvZHS@Zj>JuN*U8]rH'9q͏vy7|G\`2|?xrs\:L(GXyEőNFm^@,QÐIOdZim2w>Z!tHM*ozU㞼WlUkO{b$u{y!Tj6YǫXfep{t9v]j$<5r⍶_bQCvW G<;@=`rCv$+8{7}bp흼G` (c6qL>ps@@x&UmpLzG!, ,+T2p`2-Sꔊ[z t3]!jݘ(9"P1N @*\)e= Project X - Online Help


Help

Table of Contents:

Online Resourcen:

project-x/noguisources.lst0000600000175000017500000001234710411113022017360 0ustar supermariosupermariosrc/net/sourceforge/dvb/projectx/audio/AudioFormat.java src/net/sourceforge/dvb/projectx/audio/AudioFormatDTS.java src/net/sourceforge/dvb/projectx/audio/AudioFormatAC3.java src/net/sourceforge/dvb/projectx/audio/AudioFormatLPCM.java src/net/sourceforge/dvb/projectx/audio/AudioFormatWAV.java src/net/sourceforge/dvb/projectx/audio/AudioFormatMPA.java src/net/sourceforge/dvb/projectx/audio/MpaConverter.java src/net/sourceforge/dvb/projectx/audio/MpaDecoder.java src/net/sourceforge/dvb/projectx/audio/RIFFHeader.java src/net/sourceforge/dvb/projectx/common/Common.java src/net/sourceforge/dvb/projectx/common/GuiInterface.java src/net/sourceforge/dvb/projectx/common/GuiInterfaceIF.java src/net/sourceforge/dvb/projectx/common/JobCollection.java src/net/sourceforge/dvb/projectx/common/JobProcessing.java src/net/sourceforge/dvb/projectx/common/Keys.java src/net/sourceforge/dvb/projectx/common/Resource.java src/net/sourceforge/dvb/projectx/common/Settings.java src/net/sourceforge/dvb/projectx/common/Start.java src/net/sourceforge/dvb/projectx/io/BitWalker.java src/net/sourceforge/dvb/projectx/io/IDDBufferedOutputStream.java src/net/sourceforge/dvb/projectx/io/RawFile.java src/net/sourceforge/dvb/projectx/io/StandardBuffer.java src/net/sourceforge/dvb/projectx/net/WebInterface.java src/net/sourceforge/dvb/projectx/parser/CommonParsing.java src/net/sourceforge/dvb/projectx/parser/Gop.java src/net/sourceforge/dvb/projectx/parser/GopArray.java src/net/sourceforge/dvb/projectx/parser/HpFix.java src/net/sourceforge/dvb/projectx/parser/MainProcess.java src/net/sourceforge/dvb/projectx/parser/Scan.java src/net/sourceforge/dvb/projectx/parser/StreamBuffer.java src/net/sourceforge/dvb/projectx/parser/StreamConverter.java src/net/sourceforge/dvb/projectx/parser/StreamDemultiplexer.java src/net/sourceforge/dvb/projectx/parser/StreamParser.java src/net/sourceforge/dvb/projectx/parser/StreamParserBase.java src/net/sourceforge/dvb/projectx/parser/StreamParserPVA.java src/net/sourceforge/dvb/projectx/parser/StreamParserTS.java src/net/sourceforge/dvb/projectx/parser/StreamParserPESPrimary.java src/net/sourceforge/dvb/projectx/parser/StreamParserPESSecondary.java src/net/sourceforge/dvb/projectx/parser/StreamParserESVideo.java src/net/sourceforge/dvb/projectx/parser/StreamParserESAudio.java src/net/sourceforge/dvb/projectx/parser/StreamParserESSubpicture.java src/net/sourceforge/dvb/projectx/parser/StreamProcess.java src/net/sourceforge/dvb/projectx/parser/StreamProcessBase.java src/net/sourceforge/dvb/projectx/parser/StreamProcessTeletext.java src/net/sourceforge/dvb/projectx/parser/StreamProcessSubpicture.java src/net/sourceforge/dvb/projectx/parser/StreamProcessAudio.java src/net/sourceforge/dvb/projectx/parser/StreamProcessLPCMAudio.java src/net/sourceforge/dvb/projectx/parser/StripAudio.java src/net/sourceforge/dvb/projectx/parser/StripRelook.java src/net/sourceforge/dvb/projectx/parser/VBI.java src/net/sourceforge/dvb/projectx/subtitle/Bitmap.java src/net/sourceforge/dvb/projectx/subtitle/BMP.java src/net/sourceforge/dvb/projectx/subtitle/CharSet.java src/net/sourceforge/dvb/projectx/subtitle/DVBSubpicture.java src/net/sourceforge/dvb/projectx/subtitle/Subpicture.java src/net/sourceforge/dvb/projectx/subtitle/Teletext.java src/net/sourceforge/dvb/projectx/subtitle/UnicodeWriter.java src/net/sourceforge/dvb/projectx/thirdparty/Chapters.java src/net/sourceforge/dvb/projectx/thirdparty/D2V.java src/net/sourceforge/dvb/projectx/thirdparty/Ifo.java src/net/sourceforge/dvb/projectx/thirdparty/TS.java src/net/sourceforge/dvb/projectx/video/IDCTRefNative.java src/net/sourceforge/dvb/projectx/video/IDCTSseNative.java src/net/sourceforge/dvb/projectx/video/MpvDecoder.java src/net/sourceforge/dvb/projectx/video/Preview.java src/net/sourceforge/dvb/projectx/video/PreviewObject.java src/net/sourceforge/dvb/projectx/video/Video.java src/net/sourceforge/dvb/projectx/video/WSS.java src/net/sourceforge/dvb/projectx/xinput/DirType.java src/net/sourceforge/dvb/projectx/xinput/FileType.java src/net/sourceforge/dvb/projectx/xinput/StreamInfo.java src/net/sourceforge/dvb/projectx/xinput/XInputDirectory.java src/net/sourceforge/dvb/projectx/xinput/XInputDirectoryIF.java src/net/sourceforge/dvb/projectx/xinput/XInputFile.java src/net/sourceforge/dvb/projectx/xinput/XInputFileIF.java src/net/sourceforge/dvb/projectx/xinput/XInputStream.java src/net/sourceforge/dvb/projectx/xinput/file/XInputDirectoryImpl.java src/net/sourceforge/dvb/projectx/xinput/file/XInputFileImpl.java src/net/sourceforge/dvb/projectx/xinput/ftp/FtpServer.java src/net/sourceforge/dvb/projectx/xinput/ftp/FtpVO.java src/net/sourceforge/dvb/projectx/xinput/ftp/StringCommandListener.java src/net/sourceforge/dvb/projectx/xinput/ftp/XInputDirectoryImpl.java src/net/sourceforge/dvb/projectx/xinput/ftp/XInputFileImpl.java src/net/sourceforge/dvb/projectx/xinput/topfield_raw/RawFileInputStream.java src/net/sourceforge/dvb/projectx/xinput/topfield_raw/RawInterface.java src/net/sourceforge/dvb/projectx/xinput/topfield_raw/RawReadIF.java src/net/sourceforge/dvb/projectx/xinput/topfield_raw/XInputDirectoryImpl.java src/net/sourceforge/dvb/projectx/xinput/topfield_raw/XInputFileImpl.java src/edu/stanford/ejalbert/BrowserLauncher.java src/RawRead.java project-x/projectx.desktop0000600000175000017500000000045210310662606017351 0ustar supermariosupermario[Desktop Entry] X-SuSE-translate=true Categories=AudioVideo;AudioVideoEditing Comment=A video editing and demultiplexing tool Encoding=UTF-8 Exec=java -jar /usr/share/projectx/ProjectX.jar GenericName=ProjectX Icon=package_multimedia Name=ProjectX Name[de]=ProjectX Terminal=false Type=Application project-x/resources/0000700000175000017500000000000010745203152016126 5ustar supermariosupermarioproject-x/resources/_audio.gif0000600000175000017500000000157510304464042020065 0ustar supermariosupermarioGIF89a333ffffff33̙33ff333f33ff33f3f33fff3̙ff3@f3̙̙3ff̙3fff3̙3f333ff3f33fff3f3ff3ff33f3f33ff3f3̙33ff333f33ff333f3f3ff3ff̙f3f33̙ff̙3f3ff3f333ff3f33ff3ff3ff3f3f3f33f3ff33f33ff333f33ff33f3f33fff3f3ff̙3̙3ff3ff3f̙̙3f333ff3f33ff3fff3f3f3f3f33f3! ,Z @*,B\$D(p"D)jXcƍ;z,XH2d04/W:4P3KVtS'ͅ<bÇ-Z|H€;project-x/resources/_container.gif0000600000175000017500000000155310306715722020750 0ustar supermariosupermarioGIF89a333ffffff33̙33ff333f33ff33f3f33fff3̙ff3@f3̙̙3ff̙3fff3̙3f333ff3f33fff3f3ff3ff33f3f33ff3f3̙33ff333f33ff333f3f3ff3ff̙f3f33̙ff̙3f3ff3f333ff3f33ff3ff3ff3f3f3f33f3ff33f33ff333f33ff33f3f33fff3f3ff̙3̙3ff3ff3f̙̙3f333ff3f33ff3fff3f3f3f3f33f3! ,H @i(\`!C:!aÃ*$8bG'VdqƏ%Q%ǐU$ʘ6kƄ2;project-x/resources/_playtime.gif0000600000175000017500000000156110272774272020620 0ustar supermariosupermarioGIF89a333ffffff33̙33ff333f33ff33f3f33fff3̙ff3@f3̙̙3ff̙3fff3̙3f333ff3f33fff3f3ff3ff33f3f33ff3f3̙33ff333f33ff333f3f3ff3ff̙f3f33̙ff̙3f3ff3f333ff3f33ff3ff3ff3f3f3f33f3ff33f33ff333f33ff33f3f33fff3f3ff̙3̙3ff3ff3f̙̙3f333ff3f33ff3fff3f3f3f3f33f3!,N @A\X0@W0!D)p@B=22ɓ'K\y$Â$-(cG4 ڼSŗw;project-x/resources/_ppl.gif0000600000175000017500000000202110306716022017542 0ustar supermariosupermarioGIF89a,333ffffff33̙33ff333f33ff33f3f33fff3̙ff3f3̙̙3ff̙3fff3̙3f333ff3f33fff3f3ff3ff33f3f33ff3f3̙33ff333f33ff333f3f3ff3ff̙f3f33̙ff̙3f3ff3f333ff3f33ff3ff3ff3f3f3f33f3ff33f33ff333f33ff33f3f33fff3f3ff̙3̙3ff3ff3f̙̙3f333ff3f33ff3fff3f3f3f3f33f3! ,, HaCWvhjdhGB8bƍ;~<r"ɗ'#|XcD"G^4s&G6Wl'A*SGMD$ ԪT@XnJfY>}%Yf^-iժZи_s/`jB+3K VpM`-^.yl|@jEuĊMvf}߄Fq;|x;project-x/resources/_subtitle.gif0000600000175000017500000000154110306716106020613 0ustar supermariosupermarioGIF89a333ffffff33̙33ff333f33ff33f3f33fff3̙ff3@f3̙̙3ff̙3fff3̙3f333ff3f33fff3f3ff3ff33f3f33ff3f3̙33ff333f33ff333f3f3ff3ff̙f3f33̙ff̙3f3ff3f333ff3f33ff3ff3ff3f3f3f33f3ff33f33ff333f33ff33f3f33fff3f3ff̙3̙3ff3ff3f̙̙3f333ff3f33ff3fff3f3f3f3f33f3! ,> @*\Ç!HĊ/bXpcD x!A%Mr@ IP`@;project-x/resources/_teletext.gif0000600000175000017500000000154410306716150020620 0ustar supermariosupermarioGIF89a333ffffff33̙33ff333f33ff33f3f33fff3̙ff3f3̙̙3ff̙3fff3̙3f333ff3f33fff3f3ff3ff33f3f33ff3f3̙33ff333f33ff333f3f3ff3ff̙f3f33̙ff̙3f3ff3f333ff3f33ff3ff3ff3f3f3f33f3ff33f33ff333f33ff33f3f33fff3f3ff̙3̙3ff3ff3f̙̙3f333ff3f33ff3fff3f3f3f3f33f3! ,A C*\xÇ!tȐ łflƍ ?qǎ&IT9ɈDpfL;project-x/resources/_video.gif0000600000175000017500000000160610307431050020061 0ustar supermariosupermarioGIF89a333ffffff33̙33ff333f33ff33f3f33fff3̙ff3f3̙̙3ff̙3fff3̙3f333ff3f33fff3f3ff3ff33f3f33ff3f3̙33ff333f33ff333f3f3ff3ff̙f3f33̙ff̙3f3ff3f333ff3f33ff3ff3ff3f3f3f33f3ff33f33ff333f33ff33f3f33fff3f3ff̙3̙3ff3ff3f̙̙3f333ff3f33ff3fff3f3f3f3f33f3! ,c @*\@3b/8q2D1j0Ċ3n,$Ȕ#YRJ-iTIɝ1q fá/mtY'  ;project-x/resources/ac3.bin0000600000175000017500000002040010407356432017271 0ustar supermariosupermario w2@CKeqϟ>|ϟ>|ϿWϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|Ͽϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|)ɒmmxǍkZֵkZֵkZֵkZmmxǍkZֵkZֵkZֵkZ`kZֵkZֵkZֵkZ6mmǎkZֵkZֵkZֵkZ+F wL@BJa:|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟyO$@w|ϟǎmm浭kZϟ>|ϟ>|x㻻wwvm|kZֵϟ>|ϟ>|w|ϟǏ;mkZֵ>|ϟ>|x㻻wwvm|kZֵϟ>|ϟ>|˭wPw|ϟǎmm浭kZϟ>|ϟ>|"@ 8Mѻz*_|Qt@p}G2u1|ϟ>|;Ǐ;wwwmmϚֵk_>|ϟ>|ό5,|Wr]z7B9cӴR.ѮxwwwwmZֵkϟ>|ϟ>|kZֵ|ϟ>|ϟ>[d w@BJa:|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟyO @Ǐ|www0wwwxǏ|Ǐ|Ǐ|ό5, >y4CF|wwwxǏ|"` z*_|Qt@p}G2u1Mk #=UǏ|X'%ct#=;O+"Bb6z,Ǐ|www w@CKa:|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟyO @ǏxǏYx<W>|ϟ>|ϟ>}:|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>}ί>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|:|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>}ιO$H"Dmmx㻻x|kZֵkZֵkZִmmwwwwwwwwwwwwwxmZֵkZֵkZֵh mmǎm浭kZֵkZֵkZmm;ǏmϚֵkZֵkZֵk@mmommx㻻x|kZֵkZֵkZִmmwwwwwwwwwwwwwxmZֵkZֵkZֵh mmǎm浭kZֵkZֵkZmm;ǏmϚֵkZֵkZֵk@mmommx㻻x|kZֵkZֵkZִmmwwwwwwwwwwwwwxmZֵkZֵkZֵh mmǎm浭kZֵkZֵkZmm;ǏmϚֵkZֵkZֵk@mmommx㻻x|kZֵkZֵkZִmmwwwwwwwwwwwwwxmZֵkZֵkZֵh mmǎm浭kZֵkZֵkZmm;ǏmϚֵkZֵkZֵk@mmommx㻻x|kZֵkZֵkZִmmwwwwwwwwwwwwwxmZֵkZֵkZֵh mmǎm浭kZֵkZֵkZmm;ǏmϚֵkZֵkZֵk@mmo]̀6mmxԷxxxUϟ>|ϟ>|ϟ>|ϟί>|ϟ>|ϟ>|ϟ>|ϟϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|:|ϟ>|ϟ>|ϟ>|ϟ>}ί>|ϟ>|ϟ>|ϟ>|ϟS$H"@ommkZֵkZֵkZֵmmxkZֵkZֵkZֵmmxkZֵkZֵkZֵmmxkZֵkZֵkZֵmmxkZֵkZֵkZֵmmxkZֵmmxzO8xȉUM@?2$)O@;project-x/resources/addleft.gif0000600000175000017500000000204710140614416020223 0ustar supermariosupermarioGIF89a 333ffffff3333ff333f3f33f3f3fffff3333ff3ff3f3ff3ff33f3f33ff3f3̙33ff333f33ff333f3f3ff3ff̙f3f33̙ff̙3̠f3ff3f333ff3f3x`px3ffИ3ff̠3ff3hȘРhx@PhfxȠ`pXhP`x3f̠3fؘhp`h@H`08P33fpx舠3XhphxxЀxؐ舘耈Ƞpx舘hpxxhppxЀ؀؀Ȱff33f33ff333f33ff33f3f33fff3f3ff̙33f3ff3f3333ff3f3ff3f3f33!, W zdjT, LhΈIJW0Z` +V-TDA 0w*EUvŲ*֧(&ΫPfi تP\:Ԝ@f Ͳ9Z@Ckh4;d KV5SYNd WA|T]nDztJqD$KcJ(_5{$I%ZY4[K,T'S-:e,btv]@ * ;project-x/resources/bwd_10.gif0000600000175000017500000000176710230615146017705 0ustar supermariosupermarioGIF89a PYQZӥ䂔PX{ނR[iv􋗸Sahwz|昛t̂نǟ؃kw|bq|nyowwȚަّWg7AVڕɢȢ㆓ޣ_hz䁏邔Á㌔is֪7?WEQo~fz~rփٞضȝ᚟ÎʄөӊQZퟸش=Fv͆꠿QY>F棧|Ó@La!, xNX`_،  -XbF!QeXYdJ+;ȈX JID̬y3 4>`ĕ "AY3Rjf]D.aǖL"yj\"#FrЍ&@١ !gB4t\1d(!spУ C **.(ܔ ;project-x/resources/bwd_100.gif0000600000175000017500000000206410230615222017747 0ustar supermariosupermarioGIF89a PYQZӥ䂔PX{ނR[iv􋗸Sahwz|昛t̂نǟ؃kw|bq|nyowwȚަّWg7AVڕɢȢ㆓ޣ_hz䁏邔Á㌔is֪7?WEQo~fz~rփٞضȝ᚟ÎʄөӊQZퟸش=Fv͆꠿QY>F棧|Ó@La!, xN hBr 0Ђ9z6QeXaL/cZ TP :(&>IV*%T( uX03,kۢUkf0IÉy70_ H0Ȉqɕ!LLĹC)YF>4Rth3!A:.`zIan޷sA3 5ɗ7s5Hl.({M ;project-x/resources/bwd_gop.gif0000600000175000017500000000177610230615034020246 0ustar supermariosupermarioGIF89a PYQZӥ䂔PX{ނR[iv􋗸Sahwz|昛t̂نǟ؃kw|bq|nyowwȚަّWg7AVڕɢȢ㆓ޣ_hz䁏邔Á㌔is֪7?WEQo~fz~rփٞضȝ᚟ÎʄөӊQZퟸش=Fv͆꠿QY>F棧|Ó@La!, xN'K6Y"Z0 fx\ nj*` +7VaP&J\A# uX0N3St jd΃ 䩱rY4LĹC)nb拜 qK2IxaƁA3 5hE-=B nPP"J2e;project-x/resources/bwd_ncp.gif0000600000175000017500000000202510230615164020231 0ustar supermariosupermarioGIF89a PYQZӥ䂔PX{ނR[iv􋗸Sahwz|昛t̂نǟ؃kw|bq|nyowwȚަّWg7AVڕɢȢ㆓ޣ_hz䁏邔Á㌔is֪7?WEQo~fz~rփٞضȝ᚟ÎʄөӊQZퟸش=Fv͆꠿QY>F棧|Ó@La!, )%J(PxNr)hp` XhhDCcer̨K#VvŌ.;8 @$ɕ,5aGR hj!uX0FO,h1 .x\p"08=҇"yj\"#F8oTr&G-,>ip%EI\)`ē=e88g (j%K,ddpSH@;project-x/resources/colours.tbl0000600000175000017500000000257510405044616020333 0ustar supermariosupermario//project X optional file //user colour table definition for DVB subpictures, creating a .sup file, as a replacement of the internal remapping //required entries of a table: //table=list name //model=final colour link depth of this table in bits (2, 4, 8) (means max. 4, 16, 256 paletized colours, best value depends on broadcasters std. table) //0..x=ARGB (alpha,red,green,blue as 32bit uimsbf, 8bit each) (undefined colour links are fully transparent) //you can add as many tables you wish table=SVT model=4 0=0 1=FF101000 2=0 3=FF101010 4=FF101010 5=FF101010 6=FF101010 7=FF101010 8=FF101010 9=FF101010 10=FF101010 11=FF989898 12=FF989898 13=FF989898 14=FFDCDCDC 15=FFDCDCDC table=NRK model=4 0=0 1=D4101010 2=D4101010 3=D4101010 4=D4101010 5=D4101010 6=D4101010 7=D4101010 8=D4101010 9=D4101010 10=FF7C7C7C 11=FF7C7C7C 12=FF7C7C7C 13=FFDCDCDC 14=FFDCDCDC 15=FFDCDCDC table=YLE model=4 0=0 1=FF010101 2=FF010101 3=FF010101 4=FF010101 5=FF010101 6=FF010101 7=FF9C9C9C 8=FF9C9C9C 9=FFD0D0D0 10=FFD0D0D0 11=FFD0D0D0 12=FFD0D0D0 13=FFD0D0D0 14=FFD0D0D0 15=FFD0D0D0 table=C+Pol model=2 0=0 1=FF101010 2=FFDCDCDC 3=FF9C9C9C table=MTVAdria model=4 0=0 1=FF010101 2=FF010101 3=FF010101 4=0 5=FF010101 6=FF010101 7=FF010101 8=FF010101 9=FF010101 10=FF010101 11=FF8C8C8C 12=FFC9C9C9 13=FFC9C9C9 14=FFC9C9C9 15=0 project-x/resources/dn.gif0000600000175000017500000000106110140614416017214 0ustar supermariosupermarioGIF89a PYQZӥ䂔PX{ނR[iv􋗸Sahwz|昛t̂نǟ؃kw|bq|nyowwȚަّWg7AVڕɢȢ㆓ޣ_hz䁏邔Á㌔is֪7?WEQo~fz~rփٞضȝ᚟ÎʄөӊQZퟸش=Fv͆꠿QY>F棧|Ó@La!, @w65qi(- 2\Q?BV$WkYR)jn~Du4.s*c9"]E=_;hz`p:!He'LFI%f 1}^PGONKSmXg7t/T3+#bxy& AJCl @rl ;project-x/resources/extract.gif0000600000175000017500000000165410306716314020301 0ustar supermariosupermarioGIF89a333ffffff33̙33ff333f33ff33f3f33fff3̙ff3f3̙̙3ff̙3Аfff3̙3f333ff3f33fff3f3ff3ff33f3f33ff3f3̙33ff333f33ff333f3f3ff3ff̙f3f33̙ff̙3f3ff3f333ff3f33ff3ff3ff3f3f3f33f3ff33f33ff333f33ff33f3f33fff3f3ff̙3̙3ff3ff3f̙̙3f333ff3f33ff3fff3f3f3f3f33f3! , H‡†3FXD)Z9$PrB(]ftI0&L5aIrO myQP $RANTjJjy*ըGv*Ӯe+,֬[K݇;project-x/resources/ftp.gif0000600000175000017500000000212310306716370017412 0ustar supermariosupermarioGIF89aU$$U$$IIUIImmUmmUUU۪U$$U$$$$$$U$$$$$I$IU$I$I$m$mU$m$m$$U$$$$U$$$$U$۪$$$U$$IIUIII$I$UI$I$IIIIUIIIIImImUImImIIUIIIIUIIIIUI۪IIIUIImmUmmm$m$Um$m$mImIUmImImmmmUmmmmmmUmmmmUmmmmUm۪mmmUmmU$$U$$IIUIImmUmmUUU۪UU$$U$$IIUIImmUmmUUU۪UU$$U$$IIUIImmUmmےےUےے۶۶U۶۶U۪UU$$U$$IIUIImmUmmUUU۪U! , *hK -jckam,ӖBƍ€mIF棧|Ó@La!, q!T \[ Q˔9/LB"FA8a"\I`I*YNE>Pވc͜vDN2ѤK Nhӥլ[g O!ٴk#(PJ GPݼ~ $ PiBĊ c#( l2#̛;/1@`aiԪYasˏ i۹w0$ ;project-x/resources/fwd_100.gif0000600000175000017500000000206210230615230017750 0ustar supermariosupermarioGIF89a PYQZӥ䂔PX{ނR[iv􋗸Sahwz|昛t̂نǟ؃kw|bq|nyowwȚަّWg7AVڕɢȢ㆓ޣ_hz䁏邔Á㌔is֪7?WEQo~fz~rփٞضȝ᚟ÎʄөӊQZퟸش=Fv͆꠿QY>F棧|Ó@La!, q!TP(R`…*.8Tc $jp2煃 7v  .Ie̙5aL0ARtxy#NC=*h%%/kz5VXh- $8Ok۾U.Yc“:/Ō7` @+%ycDȓT,!D3 V6 ҧS c#/ l2vݽq;0i3w]zư ;x͇Ð;project-x/resources/fwd_gop.gif0000600000175000017500000000177610230615016020252 0ustar supermariosupermarioGIF89a PYQZӥ䂔PX{ނR[iv􋗸Sahwz|昛t̂نǟ؃kw|bq|nyowwȚަّWg7AVڕɢȢ㆓ޣ_hz䁏邔Á㌔is֪7?WEQo~fz~rփٞضȝ᚟ÎʄөӊQZퟸش=Fv͆꠿QY>F棧|Ó@La!, ˔% (drAJzlq" eʜpt(KJt$ 3Rvp O78 tCƒ5 P :-<! x@sŌL1cIb" kHJ``TrBVI8`2UTY6Tc+̜x&-46_BO'(fC;project-x/resources/fwd_ncp.gif0000600000175000017500000000203210230615174020234 0ustar supermariosupermarioGIF89a PYQZӥ䂔PX{ނR[iv􋗸Sahwz|昛t̂نǟ؃kw|bq|nyowwȚަّWg7AVڕɢȢ㆓ޣ_hz䁏邔Á㌔is֪7?WEQo~fz~rփٞضȝ᚟ÎʄөӊQZퟸش=Fv͆꠿QY>F棧|Ó@La!, q!TP(Om|(\y ~$H0 E!Rx4 &0rh!M78`'$W*dy'K KXSG\A $8O,ٚ%5f,F棧|Ó@La!, xNr 0Ђ6QeX ΀T&>W*A :O,Y'L.x@p"08S1y87@v#E9!X9S@QϖJPPQq!J7e;project-x/resources/pjxresources_en.properties0000600000175000017500000017177710412355074023512 0ustar supermariosupermario# Project-X Resource File # english, std, V 1.1 # by pstorch, dvb.matt # Credits credits=dvb.matt - father of Project-X\n\ Lucike - forum hoster, documentation\n\ TheHorse - keyboardcontrol of preview\n\ java.lang - conditional patch of H-resolution\n\ R-One - DTS support\n\ ghost - dreambox file segment completion\n\ roehrist - CVS, X-input, ftp\n\ pstorch - i18n support, settings\n\ chrisg - Topfield disk access (AddOn)\n\ jazzydane - danish translation\n\ Kano / RoEn - Unix buils script\n\ Eric Albert - BrowserLauncher\n\ catapult,Bonni - Topfield 5x00 export\n\ ...and all other supporters... # Common.File=&File Common.Save=&Save Common.SaveAs=Save &as.. Common.Open=&Open.. Common.Load=&Load.. Common.Edit=&Edit Common.Messages=&Messages Common.Options=&Options Common.Close=&Close Common.Cancel=&Cancel Common.Exit=E&xit Common.LogFile=&Logfile Common.Preferences=&PreSettings Common.Addons=Addo&ns General.Yes=Yes General.No=No StartUp.Title=X Startup, load components... StartUp.Error=Error while starting Project-X: StartUp.Error.Title=Project-X Startup Error StartUp.Init=Initializing. StartUp.Wait=Please wait... StartUp.Choose=Choose an option... # PreferencesPanel.Title=PreSettings PreferencesPanel.Button=PreSettings Application.SaveSettingsOnExit=Save Settings on Exit Application.InputDirectoriesDepth=subdirectory expansion (FILE only) # Popupmenu popup.what=what popup.cutspecials=open Cut/Specials.. popup.url=add URL.. popup.add=add.. popup.remove=remove popup.rename=rename.. popup.openhex=open in Hexviewer.. popup.patchbasics=patch Video Basics.. popup.sendtocl3=sendTo CL#3.. popup.newOutName=new Output as.. popup.changeTimestamp=update timestamp of file.. popup.copyInfoToClipboard=copy file info to clipboard popup.assignStreamType=assign stream type directly.. popup.automatic=automatic popup.assignActionType=assign action type directly.. popup.unspecified=unspecified popup.fixHpAc3=create corrected Hp ac3 file.. popup.stripAudio=strip raw audio data from DD/DTS-Wave.. #Filechooser FileChooser.Select=Select FileChooser.Title=Selection #File Menu file.menu=&File file.url=Add &URL.. file.add=&Add.. file.remove=&Remove file.rename=Re&name.. file.exit=E&xit #dialog dialog.input.url=input an URL.. #Settings Menu settings.menu=&Settings settings.settings=&Settings.. #Language Menu language.menu=&Language language.system=S&ystem default language.check=check &online #General Menu general.menu=&View #Options Menu options.menu=E&dit options.opencutspecials=open &VideoCut/Specials.. options.openhexview=open in &HexViewer.. options.pachtbasics=&patch Video Basics.. options.subtitlepreview=show &Subtitle Preview.. options.teletext=show &TeletextPageMatrix.. #Help Menu help.menu=&Help help.about=&About.. help.help=&Help.. help.lucike.info=http://www.lucike.info help.lucike.forum=http://forum.lucike.info help.sourceforge.net=http://sourceforge.net/projects/project-x help.version=&Latest version? help.version.info=Latest version: help.version.info.title=Latest version of Project-X help.version.error=Error retrieving latest version: progress.title=Progress #Html Frame html.title=Help #Buttons button.go=&Go! button.go.Tip=starts, pauses or resumes the process button.i=&I button.i.Tip=short processing to inform about the IDs found in streamfile (in specified filesize, see out) button.c=&C button.c.Tip=cancel the current process button.p=&P button.p.Tip=stop(pause) or continue the current process button.e=&E button.e.Tip=PVA raw file extraction, using the specified ID: (press 'i' to get the found IDs) #Mainpanel MainPanel.Collection=Collection MainPanel.Process=Process MainPanel.Process.Tip=if not DEMUX, it converts a streamformat to an other (stream content copy, no error correction!!) MainPanel.BitrateMonitor.Tip=actual Bitrate of GOP from 0...10Mbps (depends on the kind of computing) / GOP structure / videotime MainPanel.writtenMB=out MB MainPanel.writtenMB.Tip=written MB of new created files of collection (without temporaries) MainPanel.useAllCollections=process all collections MainPanel.useAllCollections.Tip=enable to work with all collections in one run MainPanel.enablePostProcessing=enable post processing MainPanel.enablePostProcessing.Tip=enable post processing (->see external panel, if field is not empty ) MainPanel.simpleMPG=MPG=>sPES MainPanel.simpleMPG.Tip=simple PES parsing, enable for MPEG-PS including data w/o a regular sub ID of private_stream_1 MainPanel.enhancedPES=sPES=>MPG MainPanel.enhancedPES.Tip=enhanced PES parsing, enable for PES including data with a sub ID of private_stream_1 MainPanel.nonVideoExportStatus=not started MainPanel.nonVideoExportStatus.Tip=status of audioexport or written subpictures/pages MainPanel.AudioVideoOffset=A/V offset MainPanel.AudioVideoOffset.Tip=shows the A/V timeoffset at the beginning of each GOP in ms: a/b/c

(cuts cause different offsets)

a) A/V PTS offset in source

b) A/V frame begin offset for actual GOP in demuxed file

c) new real A/V offset for actual GOP in demuxed file MainPanel.ConversionMode.demux=demux MainPanel.ConversionMode.toVDR=to VDR MainPanel.ConversionMode.toM2P=to M2P MainPanel.ConversionMode.toPVA=to PVA MainPanel.ConversionMode.toTS=to TS MainPanel.ConversionMode.PidFilter=PIDFilter (1:1 Copy) MainPanel.ConversionModePriority=Collection has priority MainPanel.ConversionModePriority.Tip=use collections action type MainPanel.useAutoPidFilter=apply PMT-PID filter MainPanel.useAutoPidFilter.Tip= MainPanel.QuickStart=QuickStart MainPanel.QuickStart.Tip=starts the process immediately, using the last active settings ProcessWindow.Title=ProcessWindow ProcessWindowPanel.Button=prepare >> ProcessWindowPanel.Title=Logmessages ProcessWindowPanel.Action=Action: #Tab.msg MessagePanel.Title=message handling MessagePanel.logSequenceError=log 'packets out of sequence' / bit errors MessagePanel.logSequenceError.Tip=disable, if this message bombs the logwindow (and decrease the speed) MessagePanel.logMissingStartcode=log 'missing startcodes' MessagePanel.logMissingStartcode.Tip=disable, if this message bombs the logwindow (and decrease the speed) MessagePanel.logESError=log 'PES header found in ES' MessagePanel.logESError.Tip=disable, if this message bombs the logwindow (and decrease the speed) MessagePanel.leadingTimeIndex=add time index of process to all log messages MessagePanel.leadingTimeIndex.Tip= MessagePanel.logWSS=log WSS MessagePanel.logWSS.Tip= MessagePanel.logVPS=log VPS MessagePanel.logVPS.Tip= MessagePanel.logRDS=log RDS MessagePanel.logRDS.Tip= MessagePanel.hideProcessWindow=hide process window while processing MessagePanel.hideProcessWindow.Tip= MessagePanel.minimizeMainFrame=minimize main frame while processing MessagePanel.minimizeMainFrame.Tip= MessagePanel.showSubpictureWindow=show subpicture preview while creating subpictures MessagePanel.showSubpictureWindow.Tip= MessagePanel.logErrorMaximum=log max. 500 warnings/errors MessagePanel.logErrorMaximum.Tip= #usage note usage=quick CL usage: \n\ Note: CL doesn't load the GUI components, except with switch [-gui]\n\ ...starts the GUI\n\ switches and inputfiles can be in any order\n\ \n\ options:\n\ [-ini ] ..use that specified iniFile instead of the standard\n\ [-dvx1] ..create a .d2v ProjectFile on demux\n\ [-dvx2] ..create a .d2v ProjectFile + .ac3.wav (RIFF WAVE Header)\n\ [-dvx3] ..create a .d2v ProjectFile + .mpa.wav (RIFF WAVE Header)\n\ [-dvx4] ..create a .d2v ProjectFile + .ac3.wav + mpa.wav (RIFF WAVE Header)\n\ [-out ] ..use that specified directory for output\n\ [-name ] ..use that specified filename for output\n\ [-cut ] ..use that text based file as cutpoint list\n\ [-chp ] ..use that text based file as chapterpoint list\n\ [-id ] ..use only these (P)IDs, separated by comma \",\"\n\ [-gui] ..display the GUI using all given CLI options\n\ [-log] ..write the normal logfile\n\ [-saveini] ..save changes made bei CLI in active .ini\n\ [-split ] ..split output at xxx MB\n\ [-demux, -tom2p, -topva, -tovdr, -tots, -filter] ..action types #terms of conditions terms=\n\ TERMS AND CONDITIONS:\n\ (1) this is a free Java based demux utility.\n\ (2) It is intended for educational purposes only, as a non-commercial test project.\n\ (3) released under the terms of the GNU GPL.\n\ (4) there is NO WARRANTY of any kind attached to this software.\n\ (5) use it at your own risk and for your own education.\n\ terms.disagree=I disagree (closing) terms.agree=I agree startup.title=X Startup, loading components... startup.error=Error during Project-X startup: startup.error.title=Project-X startup error about.title=About.. about.ok=Ok about.credits.label=Credits: #version info version.info=TEST PROJECT ONLY version.user=, User: #JavaEV javaev.java.version=java.version javaev.java.vendor=java.vendor javaev.java.home=java.home javaev.java.vm.version=java.vm.version javaev.java.vm.vendor=java.vm.vendor javaev.java.vm.name=java.vm.name javaev.java.class.vers=java.class.vers javaev.java.class.path=java.class.path javaev.java.os.name=os.name javaev.java.os.arch=os.arch javaev.java.os.version=os.version javaev.java.user.name=user.name javaev.java.user.home=user.home javaev.java.user.lang=user.language javaev.java.ini.file=ini.file javaev.java.disk.access=ext.disk.access #messages msg.infomessage=Information msg.new.language=The Language change requires a restart of Project-X. msg.loadlang.error=load language error: msg.init.error=initialization error: msg.loadini.error=ini load error: msg.saveini.error=ini save error: msg.loading.cutpoints=-> loading {0} Cutpoints... msg.loading.cutpoints.error=error loading cutpoints msg.loading.pids=-> loading {0} (P)IDs... msg.ptsfile.error=..ptsfile access error: msg.savecut=-> saving cut PTS value ({0}) to file.. msg.savecut.error=cutpoint save error: msg.log.error=log error: msg.cuts.cutin=-> cut-in @ GOP# {0} / new vframe {1} / new Timecode {2} msg.cuts.cutout=-> cut-out @ GOP# {0} msg.newfile=---> new File: msg.browser.launcher.error=browser launcher error: #Hex Viewer hexviewer.title=Hex Viewer hexviewer.file=Hex Viewer for file hexviewer.filesize= Size hexviewer.error=..cannot access file hexviewer.save=Hex Viewer, saving hexviewer.close= close hexviewer.to=to hexviewer.extractfrom=extract from: (hex.) hexviewer.extractfrom_tip=click to extract to file hexviewer.extract_tip=extract file segment to new file hexviewer.jumptohex=Jump to Hex.: hexviewer.jumptodec=Jump to Dec.: hexviewer.jumpto_tip=hit henter to jump to file position hexviewer.textmode=text mode #TeletextPageMatrix ttpagematrix.title=TeletextPageMatrix ttpagematrix.tip=decreases demux speed, if visible ttpagematrix.file=file ttpagematrix.composition1=teletext pagenumber composition ttpagematrix.composition2='MXY' : M = magazine number, XY = page number ttpagematrix.composition3=magazine number colours #Scan scan.unsupported=unknown scan.msg1=no video found at a short scan scan.msg2=no audio found at a short scan scan.msg3=no teletext found at a short scan scan.msg4=no subpicture found at a short scan scan.msg5=no PMT found scan.msg6=PMT parsing error (language) scan.msg7=video data, but no sequence header found at a short scan scan.msg8=error while checking scan.msg9=file doesn't start with a sequence header! #TS ts.msg1=!> no IDs found! ..use fixed PMT #WSS wss.run_in=Run-In-Code found wss.no_run_in=no Run-In-Code found wss.startcode=Start-Code found wss.no_startcode=no Start-Code found wss.start=start wss.group_1=Group 1 (Picture Format) wss.group_2=Group 2 (Picture Enhancements) wss.group_3=Group 3 (Subtitles) wss.group_4=Group 4 (others) wss.group_1.0001=4:3 full format, 576 lines, full screen wss.group_1.1000=14:9 letterbox, 504 lines, center wss.group_1.0100=14:9 letterbox, 504 lines, top wss.group_1.1101=16:9 letterbox, 432 lines, center wss.group_1.0010=16:9 letterbox, 432 lines, top wss.group_1.0111=14:9 full format, 576 lines, center, full screen wss.group_1.1110=16:9 full format, 576 lines, full screen wss.group_1.error=error parsing group 1 (bits0..3) wss.group_2.0.01=camera mode wss.group_2.0.10=film mode wss.group_2.0.00=error parsing bit4 wss.group_2.1.01=standard PAL wss.group_2.1.10=MACP (motion adaptive color plus) wss.group_2.1.00=error parsing bit5 wss.group_2.2.01=no helper wss.group_2.2.10=helper modulation (PALplus) wss.group_2.2.00=error parsing bit6 wss.group_2.3.01=reserved (0) wss.group_2.3.10=reserved (1) wss.group_2.3.00=error parsing bit7 wss.group_3.0.01=no subtitles in teletext wss.group_3.0.10=subtitles in teletext wss.group_3.0.00=error parsing bit8 wss.group_3.1.00=no 'open subtitles' wss.group_3.1.01='open subtitles' inside active picture wss.group_3.1.10='open subtitles' outside active picture wss.group_3.1.11=reserved (11) wss.group_3.1.err=error parsing bit9..10 wss.group_4.0.01=no surround sound wss.group_4.0.10=surround sound wss.group_4.0.00=error parsing bit11 wss.group_4.1.01=no copyright/unknown wss.group_4.1.10=copyright asserted wss.group_4.1.00=error parsing bit12 wss.group_4.2.01=copying not restricted wss.group_4.2.10=copying restricted wss.group_4.2.00=error parsing bit13 wss.group_4.1.err=error parsing bit12..13 #Subpicture subpicture.title=Subtitle PreViewer subpicture.in_time=in subpicture.duration=duration subpicture.msg1=!> subpic write error subpicture.msg2=!> simple picture packet subpicture.msg3=!> suppic unknown cmd #RawRead rawread.msg1=disabled or library not found #Common common.rename_error1=!> cannot rename common.rename_error2=to #TabPanel TabPanel.LogwindowPanel=logwindow TabPanel.FileinfoPanel=info TabPanel.MessagePanel=msg TabPanel.ExportPanel=output TabPanel.SpecialPanel=special TabPanel.VideoPanel=video TabPanel.AudioPanel=audio TabPanel.SubtitlePanel=subtitle TabPanel.ExternPanel=extern TabPanel.OptionPanel=options TabPanel.NetPanel=net TabPanel.PostCommandsPanel=postprocess #Tab.logwindow LogwindowPanel.showTtxHeader=TTX LogwindowPanel.showTtxHeader.Tip=shows ttx header line and VPS status (decreases speed, if enabled) LogwindowPanel.showTtxHeader.Tip1=header line of actual transmitted page (row 0) LogwindowPanel.showVpsLabel.Tip=short VPS status (VBI-line 16), a few stations have meaningful VPS data via DVB-teletext #Tab.options OptionPanel.Various.Title=various OptionPanel.LookAndFeel=installed look & feels: OptionPanel.LookAndFeel.Info1=choose your preferred look & feel OptionPanel.LookAndFeel.Info2=sometimes a l&f crashes internally OptionPanel.DebugLog=save big log file OptionPanel.DebugLog.Tip=reduces speed, only for test purposes OptionPanel.NormalLog=save normal log file OptionPanel.NormalLog.Tip=writes the logwindow content to file OptionPanel.dumpDroppedGop=dump dropped GOPs to separate files OptionPanel.dumpDroppedGop.Tip=only meant for later error analysis OptionPanel.StartPath=starting path for file selection: OptionPanel.StartPath.Value.Tip=leave empty, or type in a start path, a leading '?' ever resets to this path before OptionPanel.Buffer.Title=Buffer OptionPanel.MainBuffer=main I/O-Buffersize in bytes OptionPanel.MainBuffer.Tip=lower values may prevent internal memory overflows -> OutOfMemory error OptionPanel.PesPreBuffer=I-Buffersize in bytes (only PES packetsize=0 !) OptionPanel.PesPreBuffer.Tip=try lower/higher values if you work with high bitrate videostreams OptionPanel.ScanBuffer=pre-Scan Buffersize in bytes OptionPanel.ScanBuffer.Tip=try lower/higher values if known filetypes are not detected OptionPanel.PreviewBuffer=Preview Buffersize in bytes OptionPanel.PreviewBuffer.Tip=lower values speed up the preview, with possible loss of picture data OptionPanel.callGc=garbage collector OptionPanel.callGc.Tip=calls the garbage collector OptionPanel.closeOnEnd=close program when process is finished OptionPanel.closeOnEnd.Tip=close program when finished OptionPanel.holdStreamInfoOnOSD=hold StreamInfo on OSD OptionPanel.holdStreamInfoOnOSD.Tip=hold StreamInfo on OSD OptionPanel.additionalInputBuffer=use additional input buffer OptionPanel.additionalInputBuffer.Tip=use additional input buffer of 1MB, better for small data segments #ScanInfo ScanInfo.Location=Location: ScanInfo.Name=Name: ScanInfo.Size=Size: ScanInfo.Bytes=bytes ScanInfo.Type=Type: ScanInfo.Date=Date: ScanInfo.Video=Video: ScanInfo.Audio=Audio: ScanInfo.Teletext=Teletext: ScanInfo.Subpicture=Subpict.: ScanInfo.Playtime=est. Playtime: ScanInfo.NotFound=File doesn't exists! #Execute PostCommands.Title=external programs PostCommands.PostProcessing=post commands: PostCommands.PostProcessing.Tip=execute this command after a coll./split part has been processed PostCommands.Execute=exec PostCommands.Close=close PostCommands.Error=!> execution error: #Collection CollectionPanel.Title=collection specials CollectionPanel.Title2=collection specials for coll.# collection.title.processing=processing preview... CollectionPanel.CutPanel=Preview / Videofile cuts CollectionPanel.CutPanel.Tip1=use also the keyboard keys for navigation, preview only works with bytepos. cut CollectionPanel.CutPanel.Tip2=active segment/number of segments + filename of active segment CollectionPanel.CutPanel.Tip3=processed (P)ID to get the current picture CollectionPanel.CutPanel.Tip4=key in a number, or drag&drop a cutpoint file over here CollectionPanel.addPoint=add point CollectionPanel.removePoint=del point CollectionPanel.NumberOfPoints=Number of Points: CollectionPanel.NumberOfPoints.Tip=all numbers are automatically sorted CollectionPanel.NumberOfChapters=Chapters: CollectionPanel.NumberOfChapters.Tip=all numbers are automatically sorted CollectionPanel.expectedSize=exp.Size : CollectionPanel.Preview.offline=preview not available CollectionPanel.Preview.processedPid=processing Video (P)ID 0x CollectionPanel.Various=Various CollectionPanel.Preview.fastDecode=faster/worse decoding of preview CollectionPanel.Preview.fastDecode.Tip=reconstruct and interpolate only the upper/left pixel of each macroblock CollectionPanel.Preview.LiveUpdate=live update while scrolling CollectionPanel.Preview.LiveUpdate.Tip=not recommended on slow systems or file access, refers to preview buffer CollectionPanel.Preview.AllGops=also preview GOPs w/o sequ.header CollectionPanel.Preview.AllGops.Tip=for DVB data it's not recommended, enable only for some streams with only one sequ.header! CollectionPanel.PidList=PES(&Sub)-ID/PID list: CollectionPanel.PidList.Tip1=enter PES-ID or sub-ID (MPG etc) or PID (PVA,TS); empty list == use all IDs CollectionPanel.PidList.Tip2=doubleclick to remove a selected entry CollectionPanel.transferPids1=transfer selected (P)IDs to new coll# CollectionPanel.transferPids1.Tip=changes in the active coll# you must apply CollectionPanel.transferPids2=transfer cutpoint pairs to new coll# CollectionPanel.transferPids2.Tip=changes in the active coll# you must apply CollectionPanel.ExportLimits=additional export limits: CollectionPanel.OptionHorizontalResolution=H-Resol.: CollectionPanel.OptionHorizontalResolution.Tip=global,..that will automatically ignore any other video sequences CollectionPanel.OptionDAR=DAR: CollectionPanel.OptionDAR.Tip=global,..that will automatically ignore any other video sequences CollectionPanel.loadCutpointList=load Cutpoints from file CollectionPanel.loadCutpointList.Tip=open a cutpoint file or drag & drop it over here CollectionPanel.saveCutpointList=save Cutpoints to file CollectionPanel.ApplyAndClose=apply & close CollectionPanel.Apply=apply CollectionPanel.CutMode.Bytepos=(0) use BytePos. for cuts CollectionPanel.CutMode.Gop=(1) use GOP number for cuts CollectionPanel.CutMode.Frame=(2) use Frame number for cuts CollectionPanel.CutMode.Pts=(3) use PTS for cuts CollectionPanel.CutMode.Timecode=(4) use Timecode for cuts CollectionPanel.Preview.Error=preview error: CollectionPanel.FileAccessError=.. cannot access file CollectionPanel.Title.Error=collection specials for coll.# {0} -> ERROR! collection doesn't exists CollectionPanel.loadCutpointList.Error=error loading CollectionPanel.Preview.disable=disable preview CollectionPanel.Preview.disable.Tip= #makeVDR StreamConverter.IOError=!> make stream IO error: StreamConverter.PayloadError=!> incoming PES packet without payload or wrong header data StreamConverter.Summary=Stream: #patch PatchPanel.Title=edit basic video infos in 1st sequence header PatchPanel.Error=patch error PatchPanel.Error2=patch error 2 PatchPanel.Change=change PatchPanel.Cancel=cancel #CutListener cutlistener.wrongnumber=-> wrong number as ID #GoListener golistener.msg.cancelled=--- process cancelled ---- golistener.msg.paused=--- process paused ---- golistener.msg.resumed=--- process resumed ---- golistener.msg.extracting=extracting raw(PES) data of ID 0x #AC3 ac3.msg.loading.start=loading AC3 frames: ac3.msg.loading.error=error loading ac3.bin ac3.msg.frames=ac3.bin contains {0} AC3 frames #Run run.prepare.colls=preparing collection(s)... run.av.offset=A/V offset run.session.infos=<<< session infos >>> run.working.coll=-> working with collection run.split.output=-> split output @ appr. run.add.time.offset=-> add time offset to audio/ttx/pics : {0} ms (if it follows on a video) run.stream.type.disabled=-> PES stream type disabled: run.write.output.to=-> write output files to: run.write.output.notexists=!> specified output directory isn't accessible run.write.output.nowriteaccess=!> no write access in specified output directory run.cutpoints.defined=cutpoint(s) defined run.start.quick.info=<<< quick info >>> run.end.quick.info=<<< end of quick info >>> run.no.input=no input file... run.write.raw=write separated raw file to: run.coll.empty=Collection is empty... run.done=done... {0} collection(s) processed @ run.stopped=stopped... run.status=ready... run.splitpart=actual part of split output #Working working.convertType.demux=-> demux working.convertType.makeVDR=-> make a VDR (A/V PES) working.convertType.makeMPG2=-> make a MPG2 working.convertType.makePVA=-> make a PVA working.convertType.makeTS=-> make a TS working.convertType.packetFilter=-> simple packet filter working.file=-> Input File {0}: {1} ({2} bytes) working.file.not.found=!> File not found ! working.filetype=-> Filetype is {0} working.file.notsupported=!> Filetype not supported ! working.end.of.part=---> END OF PART working.summary=summary of created media files: working.post.command=-> post command performed: working.bytes.written=bytes written... working.log.error2=log error2: working.output.std=output to same location as 1st file in collection #MPVD mpvdecoder.tip1=right click to save as bmp #FilePanel FilePanel.DragDrop.Tip=drag & drop file(s) here, or use the context menu FilePanel.FileUp.Tip=move file(s) up in collection list FilePanel.FileDown.Tip=move file(s) down in collection list FilePanel.FileRemove.Tip=remove file(s) from collection list FilePanel.CollectionNumber=coll.# FilePanel.CollectionNumber.Tip=choose active file collection FilePanel.addCollection.Tip=create new file collection FilePanel.removeCollection.Tip=delete file collection FilePanel.openAutoloadPanel.Tip=open autoload file window FilePanel.OutputDirectory=output directory: FilePanel.OutputDirectory.Tip=specified output directory of selected collection FilePanel.recentOutputDirectories=recent output directories: FilePanel.addRecentOutputDirectory.Tip=add directory to recent output directory list FilePanel.removeRecentOutputDirectory.Tip=remove directory from recent output directory list FilePanel.Textfield.Tip=Collection-Infos FilePanel.FileAdd.Tip=add file(s) to collection list #ExternTab ExternPanel.Title1=externals / post processing ExternPanel.Title1.Tip=define your prefered applications ExternPanel.Applications=external applications... ExternPanel.createVdrIndex=create index.vdr on: ExternPanel.createVdrIndex.Tip=created vdr file segments will then be renamed to 0xx.vdr ExternPanel.createCellTimes=create cellTimes.txt for multiple infiles/cuts ExternPanel.createCellTimes.Tip=demux only, add's an entry for the framenumber on file switchin' and cut-in's (new chapter) ExternPanel.exportPts=autosave PTS values of cutpoints ExternPanel.exportPts.Tip=to share and reload with {PTS cut} in another X instance ExternPanel.save1stFrameOfGop=autosave GOPs 1st I-Frame as .bmp ExternPanel.save1stFrameOfGop.Tip=demux only... ExternPanel.createChapters=autosave timecode on mode changes ExternPanel.createChapters.Tip=exports an additional timecode entry to a list if a change in mode occurs ExternPanel.renameAudio=rename all MPEG-Audios to *.mpa ExternPanel.renameAudio.Tip=instead of using the Layer number -> .mp1, .mp2, .mp3 ExternPanel.renameVideo=rename all MPEG-Videos to *.mpv ExternPanel.renameVideo.Tip=instead of using the MPEG type -> .m1v, .m2v ExternPanel.Title2=Projectfile settings ExternPanel.Title2.Tip=change the entries, if you know what you do ExternPanel.createM2sIndex=Mpeg2Schnitt idd version: V2/A3 ExternPanel.createM2sIndex.Tip=create *.idd Projectfile on demux: ExternPanel.createD2vIndex=create *.d2v Projectfile on demux: ExternPanel.createD2vIndex.Tip=if each part should be converted separatly ExternPanel.createDgiIndex=create *.dgi.d2v Projectfile on demux: ExternPanel.createDgiIndex.Tip=if each part should be converted separatly ExternPanel.splitProjectFile=auto split video, but keep as one project ExternPanel.splitProjectFile.Tip=auto split demuxed video in specified part size, not audio; better for big files on <=FAT32 systems ExternPanel.ProjectFileSplitSize=-> split only video at xxx MB: ExternPanel.ProjectFileSplitSize.Tip= ExternPanel.appendExtension=append new file extensions (PES) ExternPanel.appendExtension.Tip=will keep the source file name (incl. extension) of all secondary PES streams ExternPanel.createInfoLabel=Cuttermaran Info on demux: ExternPanel.createInfoIndex=Cuttermaran info Version: 1.61ff ExternPanel.createInfoIndex.Tip=create *.info indexfile for Cuttermaran on demux: FtpPanel.killFtpClient=drop client w/o logout FtpPanel.killFtpClient.Tip=don't use, except the ftp server won't accept a logout until a transfer was completed (may not disconnect the client!) FtpPanel.useFtpServerResume=server supports 'resume' FtpPanel.useFtpServerResume.Tip= #SpecialTab SpecialPanel.Title1=specials 1 SpecialPanel.PtsShift=global PTS shift (in hours): SpecialPanel.PtsShift.Tip=try 'auto or 1..13', in case of source A/V PTS mismatch, or if it doesn't demux audio (std=0) SpecialPanel.PVA.FileOverlap=PVA: check for overlapping on read SpecialPanel.PVA.FileOverlap.Tip=disable, if multiple PVA's of one recording has been recorded without overlap SpecialPanel.PVA.Audio=PVA: strictly specs. for audio streams SpecialPanel.PVA.Audio.Tip=enable to avoid audio detection errors; but on some recordings there are missing flags! (MD) SpecialPanel.VOB.resetPts=VOB: determine diff. Cell timelines SpecialPanel.VOB.resetPts.Tip=enable, if the PTSs of consecutive VobIds/Cells are not continuous SpecialPanel.TS=only TS related: SpecialPanel.TS.ignoreScrambled=TS: ignore scrambled packets SpecialPanel.TS.ignoreScrambled.Tip=disable, if you think the packets are not, but marked as scrambled SpecialPanel.TS.blindSearch=TS: enhanced search for open packets SpecialPanel.TS.blindSearch.Tip=enable, if the PID detection stops the search at unknown payload SpecialPanel.TS.joinPackets=TS: join file segments (of Dreambox) SpecialPanel.TS.joinPackets.Tip=enable to join incomplete TS packets on boundaries of multiple file segments SpecialPanel.TS.HumaxAdaption=TS: Humax file format adaption SpecialPanel.TS.HumaxAdaption.Tip=enable for special Humax HD file format of TS SpecialPanel.TS.FinepassAdaption=TS: Finepass file format adaption SpecialPanel.TS.FinepassAdaption.Tip=enable for special Finepass HD file format of TS SpecialPanel.TS.generatePmt=TS: generate PMT stream dependent SpecialPanel.TS.generatePmt.Tip=disable, to generate an independent pre-defined PMT that also fit most streams SpecialPanel.TS.generateTtx=TS: generate info TTX service (test) SpecialPanel.TS.generateTtx.Tip=add a teletext service stream (Pid 0x9F) for status informations on page 150 (only @ autoPMT) SpecialPanel.TS.HeaderMode0=(0) no additional TS header SpecialPanel.TS.HeaderMode1=(1) add Topfield 4000 header to TS SpecialPanel.TS.HeaderMode2=(2) add Topfield 5000 header to TS SpecialPanel.TS.HeaderMode3=(3) add Topfield 5x00 header to TS (new) SpecialPanel.TS.setMainAudioAc3=TF-header: set AC3 as main AudioTrack SpecialPanel.TS.setMainAudioAc3.Tip=TF-Header: setze AC3 als aktive Tonspur SpecialPanel.Title2=specials 2 SpecialPanel.Input.getEnclosedPackets=get only enclosed PES/TS packets SpecialPanel.Input.getEnclosedPackets.Tip=disable, if no packets were found (on packet end, the next mpeg-startcode is missing, e.g. on Images) SpecialPanel.Input.concatenateForeignRecords=concatenate different recordings SpecialPanel.Input.concatenateForeignRecords.Tip=enable, if you want merge equal types of PVA, MPEG or VDR files from different recording times SpecialPanel.Audio.ignoreErrors=Audio: use only first PTS for sync SpecialPanel.Audio.ignoreErrors.Tip=counts the audiotime from its framelengths after syncing the A/V-startpoint, skip errors SpecialPanel.Audio.limitPts=Audio: limit points of PTS for sync SpecialPanel.Audio.limitPts.Tip=better than 1st Audio PTS only (as above), Audio may keep in sync SpecialPanel.Video.ignoreErrors=Video: ignore errors after 1st PTS/GOP SpecialPanel.Video.ignoreErrors.Tip=enable, if probably only Video PTS errors occurs (Pics seems ok) SpecialPanel.Video.trimPts=Video: adapt sliding PTSs SpecialPanel.Video.trimPts.Tip=enable, if audio export stops early, caused by smoothly PTS slidings SpecialPanel.Conversion=only to'XYZ' conversions related: SpecialPanel.Conversion.startWithVideo=ensure 1st PES-packet start with video SpecialPanel.Conversion.startWithVideo.Tip=enable, if some players have problems if it's not; disable for audio-only conversions SpecialPanel.Conversion.addPcrToStream=generate PCR/SCR from PTS SpecialPanel.Conversion.addPcrToStream.Tip=specify the PCR-Offset, DVB needs more than DVD, high bitrates needs more than low SpecialPanel.Conversion.PcrCounter=incTScnt SpecialPanel.Conversion.PcrCounter.Tip=increment TS-packet counter even without payload(PCR-only); non-conform, but sometimes necessary! #OutTab ExportPanel.SplitPanel=split output ExportPanel.SplitSize=split @ appr. xxx MB ExportPanel.SplitSize.Tip=edit field for another size; currently, split size is referred to written videofilesize! (mpv) ExportPanel.Overlap=overlap by ExportPanel.Overlap.Tip= ExportPanel.StreamtypePanel=stream types to process ExportPanel.StreamtypePanel.Tip=de-/select stream types you want to process (does not applies to ES as input) ExportPanel.Streamtype.MpgVideo=Mpg Video ExportPanel.Streamtype.MpgAudio=Mpg Audio ExportPanel.Streamtype.Ac3Audio=AC3/DTS Audio ExportPanel.Streamtype.PcmAudio=LPCM Audio ExportPanel.Streamtype.Teletext=Teletext ExportPanel.Streamtype.Subpicture=Subpicture ExportPanel.Streamtype.Vbi=Generic_VBI ExportPanel.Streamtype.MpgVideo.Tip=Mpg Video ExportPanel.Streamtype.MpgAudio.Tip=Mpg Audio ExportPanel.Streamtype.Ac3Audio.Tip=AC3/DTS Audio ExportPanel.Streamtype.PcmAudio.Tip=LPCM Audio ExportPanel.Streamtype.Teletext.Tip=Teletext ExportPanel.Streamtype.Subpicture.Tip=Untertitel ExportPanel.Streamtype.Vbi.Tip=Generic_VBI ExportPanel.WriteOptions=write options for conversion & demux ExportPanel.WriteOptions.Tip=that affects also the 'to VDR/MPG/PVA/TS' function to include Audio and/or Video ES ExportPanel.WriteOptions.writeVideo=write all video data ExportPanel.WriteOptions.writeAudio=write all other data ExportPanel.WriteOptions.writeVideo.Tip=write all video data ExportPanel.WriteOptions.writeAudio.Tip=write all other data ExportPanel.WriteOptions.InfoScan=quick demux/convert of 1st xx MB : ExportPanel.additionalOffset.Title=additional time offset (demultiplex) ExportPanel.additionalOffset=enable offset ExportPanel.additionalOffset.Tip=original start of stream will be moved with the given offset ExportPanel.additionalOffset.Value.Tip=enter time offset in milliseconds, hit enter; affects all streams, which follows on a video ExportPanel.createSubDirNumber=create collection number as subdirectory ExportPanel.createSubDirNumber.Tip=global: create new subdirectory for each collection number (better for same files in diff. collections) ExportPanel.createSubDirName=create collection's basename as subdirectory ExportPanel.createSubDirName.Tip=global: create new subdirectory based on 1st source filename for each collection #VideoTab VideoPanel.Title1=video corrections (demultiplex) VideoPanel.addEndcode=add sequence end code VideoPanel.addEndcode.Tip=enable for a conform MPEG sequence end VideoPanel.insertEndcode=insert sequenzendcode on format changes VideoPanel.insertEndcode.Tip=enable for a conform MPEG sequence end VideoPanel.addSequenceHeader=ensure each GOP has a sequenceheader VideoPanel.addSequenceHeader.Tip=re-init (resol. & q_matrix) of Picturedecoding on each GOP boundary (automatically on split) VideoPanel.patchToProgressive=patch all frames to progressive VideoPanel.patchToProgressive.Tip=set the progressive bits to reduce the field number VideoPanel.patchToInterlaced=patch all frames to interlaced VideoPanel.patchToInterlaced.Tip=delete the progressive bits VideoPanel.toggleFieldorder=change field order VideoPanel.toggleFieldorder.Tip=toggle the Top_field_first bit VideoPanel.addSde=set resolution in SDE VideoPanel.addSde.Tip=change existing oder insert new entries, empty field means same values as in sequ.header; e.g. 720*576 VideoPanel.SdeValue.Tip=change existing oder insert new entries, empty field means same values as in sequ.header; e.g. 720*576 VideoPanel.clearCdf=patch c.d.flagged infos of pictures VideoPanel.clearCdf.Tip=may solve the 'green picture' prob. of some old HW decoder chipsets VideoPanel.patchResolution.Tip=conditional patch 1st horiz. resolution VideoPanel.patchResolution=patch 1st h-res: VideoPanel.patchResolutionValue.0=(0) never VideoPanel.patchResolutionValue.1=(1) ever VideoPanel.patchResolutionValue.2=(2) if <> 352|720 VideoPanel.patchResolutionValue.3=(3) if <> to 352|704|720 VideoPanel.Title2=new bitrate values (demultiplex) VideoPanel.ChangeVbvBuffer.Tip=sometimes it's better to define the maximum size VideoPanel.Unchanged=don't change VideoPanel.ChangeVbvBuffer.Mode1=(1) maximum (112*16384) VideoPanel.ChangeVbvBuffer=vbv buffer: VideoPanel.ChangeVbvDelay.Tip=max. time recommended VideoPanel.ChangeVbvDelay.Mode1=(1) max. time (0xFFFF) VideoPanel.ChangeVbvDelay=vbv delay: VideoPanel.ChangeAspectRatio.Tip=change if you mean it's necessary VideoPanel.ChangeAspectRatio=aspect ratio: VideoPanel.patchBitrateValue.0=(0) keep original VideoPanel.patchBitrateValue.1=(1) computed from GOP bitlength VideoPanel.patchBitrateValue.2=(2) computed from VBV VideoPanel.patchBitrateValue.3=(3) mark as VBR (MPEG-1 Video) VideoPanel.patchBitrateValue.4=(4) fix 3 Mbps VideoPanel.patchBitrateValue.5=(5) fix 6 Mbps VideoPanel.patchBitrateValue.6=(6) fix 9 Mbps VideoPanel.patchBitrateValue.7=(7) fix 12 Mbps VideoPanel.patchBitrateValue.8=(8) fix 15 Mbps VideoPanel.patchBitrateValue=bitrate values per sequence: VideoPanel.patch1stBitrateValue.0=(0) keep original VideoPanel.patch1stBitrateValue.1=(1) computed average (nominal) VideoPanel.patch1stBitrateValue.2=(2) computed maximum <= 9.0 Mbps(DVD) VideoPanel.patch1stBitrateValue.3=(3) computed maximum (e.g. HDTV) VideoPanel.patch1stBitrateValue.4=(4) mark as VBR (MPEG-1 Video) VideoPanel.patch1stBitrateValue=bitrate value in first sequence: #AudioTab AudioPanel.Title1=audio conversions (demultiplex) AudioPanel.loslessMpaConversion.Tip1=direct losless conversion (limited AudioPanel.loslessMpaConversion.Tip2=to MPEG-1, Layer2, 48kHz, 56..384kbps) : AudioPanel.loslessMpaConversion.Tip=if conversion is chosen, bitrate & channelmode will be constant over the complete file AudioPanel.loslessMpaConversionMode0=(0) no conversion AudioPanel.loslessMpaConversionMode1=(1) single to 3D-stereo (L+R = original) AudioPanel.loslessMpaConversionMode2=(2) single to stereo (L+R = original) AudioPanel.loslessMpaConversionMode3=(3) single to jointstereo (L+R = original) AudioPanel.loslessMpaConversionMode4=(4) split 2channel into 2 single (1=L,2=R) AudioPanel.decodeMpgAudio=decode MPEG Layer1,2 to PCM: AudioPanel.decodeMpgAudio.Tip=MPEG-Audio Decoder (not for Layer3), std output into stereo pcm AudioPanel.decodeMpgAudio.resampleAudioMode0=(0) no resampling AudioPanel.decodeMpgAudio.resampleAudioMode1=(1) linear resampling 48kHz to 32kHz AudioPanel.decodeMpgAudio.resampleAudioMode2=(2) linear resampling 48kHz to 44.1kHz AudioPanel.decodeMpgAudio.Normalize=normalize to % : AudioPanel.decodeMpgAudio.Normalize.Tip=normalize L+R equally, values from 0...100 are possible, std is 98%; forces restarts if necessary AudioPanel.NormalizeValue.Tip=normalize L+R equally, values from 0...100 are possible, std is 98%; forces restarts if necessary AudioPanel.decodeMpgAudio.Downmix=downmix and output as one channel AudioPanel.decodeMpgAudio.Downmix.Tip=downmix stereo/2channel source to one single channel AudioPanel.decodeMpgAudio.changeByteorder=save in Motorola byte order AudioPanel.decodeMpgAudio.changeByteorder.Tip=means MSB first, nonIntel type AudioPanel.decodeMpgAudio.addRiffHeader=add RIFF(RIFX) header to PCM (.wav) AudioPanel.decodeMpgAudio.addRiffHeader.Tip=PC standard AudioPanel.decodeMpgAudio.addAiffHeader=add AIFF header to PCM (.aif) AudioPanel.decodeMpgAudio.addAiffHeader.Tip=Apple standard AudioPanel.Title2=audio manipulations (demultiplex) AudioPanel.validateCRC=check CRC of AC-3 / MPEG-Audio L1,2 AudioPanel.validateCRC.Tip=if enabled, this ensures lowest erroneous output on costs of performance AudioPanel.clearCRC=delete CRC in MPEG-Audio Layer1,2 AudioPanel.clearCRC.Tip=if enabled, this may prevent some audio error messages AudioPanel.fillGapsWithLastFrame=fill gaps with prev. frame AudioPanel.fillGapsWithLastFrame.Tip=instead of inserting silent frames; is std for AC-3, when ac3.bin doesn't contain a suitable silent frame for AC-3 AudioPanel.addFrames=add frames AudioPanel.addFrames.Tip=if audio ends before video, to reach the video time length AudioPanel.patch1stAc3Header=patch 1st AC-3 header to 3/2 ch-mode AudioPanel.patch1stAc3Header.Tip=some AC-3 decoding software needs it to decode all channels even if there are less AudioPanel.replaceAc3withSilence=replace all non-3/2 AC-3 by 3/2lfe silence AudioPanel.replaceAc3withSilence.Tip=enable, to mask unwanted 2/0 frames by 3/2 silence (48khz,448kbps, ac3.bin required) AudioPanel.addRiffToAc3=add RIFF WAVE header to AC-3 Audio AudioPanel.addRiffToAc3.Tip=create a .wav file, using the AC-3 Wave Format (tag 0x2000) Header AudioPanel.addRiffToMpgAudioL12=MPA: add RIFF WAVE header Layer1,2 AudioPanel.addRiffToMpgAudioL12.Tip=Broadcast Wave Format (tag 0x0050), better for MPEG Layer 1 & 2 AudioPanel.addRiffToMpgAudioL3=MPA: add RIFF WAVE header Layer3 AudioPanel.addRiffToMpgAudioL3.Tip=more usual ACM Wave Format (tag 0x0055), better for MPEG Layer 3 AudioPanel.pitchAudio=discard every xxx Audioframe : AudioPanel.pitchAudio.Tip=compress/pitch Audio (elementary streams only) AudioPanel.allowSpaces=allow spaces between frames (h.w.c.!) AudioPanel.allowSpaces.Tip=only detect valid frame headers, but without verifying frame length! (resulting in psb. incorrect sizes) AudioPanel.createDDWave=AC-3/DTS: output as DD/DTS-Wave AudioPanel.createDDWave.Tip=output Ac3/DTS as DD/DTS-Wave, fixed header: PCM 44.1kHz,16bit,2-ch AudioPanel.fadeInOut=fade in and out AudioPanel.fadeInOut.Tip=fades the sound in and out, using the iniKey 'AudioPanel.fadeInOutMillis' ; std = 2000 ms, 1...5000 ms #SubtitleTab SubtitlePanel.Title=DVB teletext, DVB subtitles (demultiplex) SubtitlePanel.Title.Teletext=DVB Teletext (demultiplex) SubtitlePanel.decodeMegaradio=test: export MegaRadio MP3-stream SubtitlePanel.decodeMegaradio.Tip=formerly transmitted via Hotbird 13E, 11.054GHz Hor., SR 27500, FEC 5/6, TTX-PID 553 SubtitlePanel.decodeHiddenRows=decode hidden rows of teletext (id 0xFF, means offline pages) SubtitlePanel.decodeHiddenRows.Tip=some pages or complete teletexts/subtitles are hidden, so that may help SubtitlePanel.rebuildPTS=re-build TTX-PTS from 1st MpgAudio stream SubtitlePanel.rebuildPTS.Tip=use it ONLY for TTX streams included in a stream file (TS,PES..) but w/o proper time base to video SubtitlePanel.keepOriginalTimecode=keep original Timecode (PTS) on independent decoding SubtitlePanel.keepOriginalTimecode.Tip=without a leading video to demux, new Timecode doesn't start at 0 SubtitlePanel.exportTextAsUnicode=Unicode (UTF-16 BE) on text export SubtitlePanel.exportTextAsUnicode.Tip=Unicode (UTF-16 Big-Endian) on text export SubtitlePanel.exportTextAsUTF8=Unicode (UTF-8) on text export SubtitlePanel.exportTextAsUTF8.Tip=Unicode (UTF-8) on text export SubtitlePanel.TtxPages=teletext pages to decode: SubtitlePanel.TtxPages.Tip=autodetection of special characters based on Teletext Level 1.5 codepages in unicode SubtitlePanel.Language= language: SubtitlePanel.Language.Tip=fix to a language pair, if an automatic switch is not supported by the broadcaster SubtitlePanel.Format.Tip=select your favourite export format SubtitlePanel.Format.Free=text SubtitlePanel.Format=subtitle export formats: SubtitlePanel.Colormodel.Mode0=(0) 4 colours SubtitlePanel.Colormodel.Mode1=(1) 16 colours SubtitlePanel.Colormodel.Mode2=(2) 256 colours SubtitlePanel.PageId.Value.Tip=empty field = use what comes, else: key in the page ID of interest (depends on broadcast) SubtitlePanel.Colormodel=simulate DVB Subpictures IRD color model: SubtitlePanel.Colormodel.Tip=that extremely affects the look of exported subtitles, best setting depends on what you want SubtitlePanel.PageId= fix to pageID: SubtitlePanel.showPreview=show Subtitle Preview SubtitlePanel.Format.SUP.Values.Tip=(offsets from left bottom) Font pointsize; BckGrd Alpha; Yoffset; Xoffset; Xwidth; H(unused); V; Yoffset2; max.lines SubtitlePanel.SupValues= Val: SubtitlePanel.Font.LoadError=Error while getting system fonts SubtitlePanel.useTextOutline=draw text with black outline (SUP only) SubtitlePanel.useTextOutline.Tip=draws a 3 pix outline around each char at a max. of 2 'speaker colors' per frame, else a black bg is used SubtitlePanel.Font=Schriftart: SubtitlePanel.Font.Tip=bei SUP-Export SubtitlePanel.specialTermination=special ttx page termination (test) SubtitlePanel.specialTermination.Tip=forces time out of unclosed pages SubtitlePanel.ChangeDisplay=change display mode: SubtitlePanel.ChangeDisplay.Tip=only when processing a .sup file as input format (from DVD or as an ES) SubtitlePanel.MovePosition=move picture position: SubtitlePanel.MovePosition.Tip=leave it empty, or set additional offsets for X and Y like: -20,-40 (top.left) #Autoload autoload.title=list of pre-defined input directories autoload.dir.remove.tip=remove directory from autoload list autoload.dir.add.tip=add directory to autoload list autoload.dir.refresh.tip=refresh file list autoload.ftp.add.tip=add ftp server directory to autoload list autoload.add.coll.tip=create new collection for each selected file and add it autoload.add.file.tip=add file(s) to collection autoload.rename.tip=left doubleclick or enter to add file(s) to a collection, right click to rename autoload.dialog.rename=rename autoload.dialog.fileexists=File exists! Overwrite? autoload.close=closing window #splitreset splitreset.novideo=! -> no videofile PTS, split disabled #checkpts checkpts.1st.latter=!> 1st video PTS starts later than the last PTS of this stream! critical for Sync checkpts.last.ends=!> last video PTS ends before the start PTS of this stream! Sync impossible #parseSecondaryPES parseSecondaryPES.continue=-> continue while using extracted raw data from parseSecondaryPES.demux.pes=demuxing PES file parseSecondaryPES.missing.startcode=!> missing startcode @ parseSecondaryPES.found.startcode=!> found startcode @ parseSecondaryPES.packet.length=-> ! packet length is 0 @ parseSecondaryPES.miss.next.startcode=!> missing next startcode @ {0} from {1} (PES-ID 0x{2}), dropping packet.. parseSecondaryPES.packs=packs: {0} {1}% {2} parseSecondaryPES.found.pesid=-> found PES-ID 0x{0} {1} @ {2} parseSecondaryPES.ac3.audio=--> AC-3/DTS Audio parseSecondaryPES.teletext=--> Teletext parseSecondaryPES.mpeg.audio=--> MPEG Audio parseSecondaryPES.lpcm.audio=--> LPCM Audio parseSecondaryPES.subpic=--> Subpicture parseSecondaryPES.eof.error=parseSecondaryPES EOF reached in error: parseSecondaryPES.io.error=parseSecondaryPES File I/O error: parseSecondaryPES.msg.noexport=--> stream omitted #ID type idtype.mpeg.video.ignored=(MPEG Video) -> ignored idtype.mpeg.audio=(MPEG Audio) idtype.private.stream=(private stream 1) idtype.mpeg.video=(MPEG Video) idtype.mapped.to= mapped to 0x idtype.mapped.to.e0= mapped to 0xE0 idtype.ignored= -> ignored idtype.video=(Video) idtype.main.audio=(mainAudio) idtype.additional=(additional) idtype.has.pesid= has PES-ID 0x #parsePrimaryPES parsePrimaryPES.special.pes=-> special PES-IDs for searching defined parsePrimaryPES.continue=continue with file parsePrimaryPES.demuxing=demuxing parsePrimaryPES.converting=converting parsePrimaryPES.avpes.file=A/V PES file parsePrimaryPES.missing.startcode=!> missing startcode @ parsePrimaryPES.found.startcode=!> found startcode @ parsePrimaryPES.split.cellids=-> VobID {0} CellID {1} @ {2} (GOP#{3} / Frame#{4}) parsePrimaryPES.packet.length=-> ! packet length is 0 @ parsePrimaryPES.miss.startcode=!> missing next startcode (packetsize=0) @ {0} from {1} /I-Buffer {2} parsePrimaryPES.miss.startcode2=!> missing next startcode @ {0} from {1} (PES-ID 0x{2}), dropping packet.. parsePrimaryPES.packs=packs parsePrimaryPES.dump.1st=-> dump 1st packet to file parsePrimaryPES.found.pesid=-> found PES-ID 0x parsePrimaryPES.pes.incoming=!> PES-ID 0x{0}, incoming PES packet without payload or wrong header data @ {1} parsePrimaryPES.actual.written=-> actual written vframes: parsePrimaryPES.switch=switch to file: parsePrimaryPES.ac3=--> AC-3/DTS Audio parsePrimaryPES.teletext=--> Teletext (SubID 0x parsePrimaryPES.mpeg.audio=--> MPEG Audio (0x parsePrimaryPES.lpcm.audio=--> LPCM Audio (SubID 0x parsePrimaryPES.subpic=--> Subpicture (SubID 0x parsePrimaryPES.eof.error=parsePrimaryPES EOF reached in error: parsePrimaryPES.io.error=parsePrimaryPES File I/O error: parsePrimaryPES.msg.noexport=--> stream omitted (0x #parseTS parseTS.sid=-> Service ID 0x parseTS.pmt.refers=-> PMT 0x{0} refers to these usable streams: parseTS.no.pmt=-> no PMT found (at a short scan) parseTS.special.pids=-> special PIDs for searching defined parseTS.continue=continue with file: parseTS.demuxing=demuxing parseTS.converting=converting parseTS.dvb.mpeg= DVB MPEG-TS file parseTS.incomplete=!> incomplete ts packet at EOF detected @ parseTS.comp.failed=!> ts packet completion failed :-( parseTS.missing.sync=!> missing sync. byte @ parseTS.comp.ok=!> ts packet completion ok :-) parseTS.found.sync=!> found sync. byte @ parseTS.bit.error=!> PID 0x{0} -> TS bit error in packet {1} @ pos. {2}, dropping.. parseTS.stuffing=--> PID 0x1FFF => stuffing packet -> ignored parseTS.scrambled=-> PID 0x{0} => marked as scrambled data, packet {1} @ {2} -> ignored parseTS.clear=-> PID 0x{0} => get clear data, packet {1} @ {2} parseTS.outof.sequence=!> PID 0x{0} -> packet {1} @ pos. {2} out of sequence ({3}/{4}) (shifting..) parseTS.priv.stream2.ignored=-> PID 0x{0}(private stream 2) -> ignored parseTS.scrambled.notignored=-> PID 0x{0} => marked as scrambled data (not ignored){1} parseTS.ignored= -> ignored parseTS.pid.has.pes=ok> PID 0x{0} has PES-ID 0x{1} {2} parseTS.lackof.pes=!> PID 0x{0} lack of PES Data -> packet skipped parseTS.actual.vframes=-> actual written vframes: parseTS.tryto.complete=!> try to complete incomplete ts packet... parseTS.packs=packs: {0} {1}% {2} parseTS.ac3.audio=--> AC-3/DTS Audio on PID 0x parseTS.teletext.onpid=--> Teletext on PID 0x parseTS.mpeg.audio=--> MPEG Audio (0x{0}) on PID 0x{1} parseTS.subpicture=--> Subpicture (SubID 0x parseTS.eof.error=raw EOF reached in error: parseTS.io.error=raw File I/O error: parseTS.switch.to=switch to file: parseTS.msg.noexport=--> stream (0x{0}) on PID 0x{1} omitted #nextfile nextfile.io.error=nextfile File I/O error: nextfile.shift.auto=-> shift original PTS automatic backward by {0} hour(s) nextfile.shift.manual=-> shift original PTS manual backward by {0} hour(s) nextfile.next.file.start=-> next datas start with PTS: {0} / last actual PTS is {1} nextfile.next.file.start.adaption=-> use new PTS-Offset: {0} for following data #overlapPVA overlappva.io.error=overlap read error: #parsePVA parsePVA.special.pids=-> special PIDs for searching defined parsePVA.streamtype.ac3= (AC-3/DTS) parsePVA.streamtype.ttx= (TTX) parsePVA.streamtype.mpeg.audio= (MPEG Audio) parsePVA.streamtype.mpeg.video= (MPEG Video) parsePVA.continue=continue with file: parsePVA.demuxing=demuxing parsePVA.converting=converting parsePVA.pvafile= PVA file parsePVA.missing.sync=!> missing syncword @ parsePVA.found.sync=!> found syncword @ parsePVA.file.overlap=File-Overlap detected @ filepos.: parsePVA.packs=packs parsePVA.found.id=-> found ID 0x parsePVA.outof.sequence=!> ID 0x{0} -> packet {1} @ pos. {2} out of sequence ({3}/{4}) (shifting..) parsePVA.id.0x=-> ID 0x parsePVA.actual.vframes=-> actual written vframes: parsePVA.ac3.onid=--> AC-3/DTS Audio on ID 0x parsePVA.teletext.onid=--> Teletext on ID 0x parsePVA.mpeg.audio.onid=--> MPEG Audio on ID 0x parsePVA.eof.error=pva EOF reached in error: parsePVA.io.error=pva File I/O error: parsePVA.msg.noexport=--> stream omitted on ID (0x #Audioprocess audio.progress=check & synchronize audio file audio.status.pre-insert=pre-inserting... audio.status.insert=inserting... audio.status.write=writing... audio.status.pause=paused... audio.status.add=adding... audio.status.finish=finished... audio.convert=-> convert MPA : audio.decode=-> decode MPA : audio.restart=!> restart audio processing, forced by changes @ output frame# audio.error.io=file I/O error: audio.msg.pts.discard=!> {0} PTS's discarded in stream audio.msg.pts.firstonly=-> take only first Audio PTS (to sync the starttime) audio.msg.pts.start_end=Audio PTS: first packet {0}, last packet audio.msg.pts.mismatch=-> !! video & audio PTS doesn't match at any time! audio.msg.pts.wo_frame=!> PTS without a frame audio.msg.adjust.at.videopts=-> adjusting audio at video-timeline audio.msg.adjust.at.ownpts=-> adjusting audio at its own timeline audio.msg.addriff.acm=-> add RIFF WAVE header to MPEG Audio as ACM Waveformat audio.msg.addriff.bwf=-> add RIFF WAVE header to MPEG Audio as BWF Waveformat audio.msg.addriff.ac3=-> add RIFF WAVE header to AC-3 Audio audio.msg.syncword.lost=!> missing syncword @ {0}, @ audio.msg.syncword.found=!> found syncword @ audio.msg.frame.discard=!> discard frame# audio.msg.crc.error=!> CRC{0} check failed @ audio.msg.source=-> src_audio: {0} @ audio.msg.source.max=-> src_audio: stop displaying, more than 100 audio mode changes in one file reduce work speed audio.msg.summary.skip=!> skipped sourceframe(s) @ audio.msg.summary.pre-insert=!> {0} frame(s) ({1}ms) pre-inserted @ audio.msg.summary.insert=!> {0} frame(s) ({1}ms) inserted @ audio.msg.summary.add=!> {0} frame(s) ({1}ms) added @ audio.msg.summary.frames=audio frames: wri/pre/skip/ins/add {0} @ {1} done... audio.msg.summary.jstereo=-> {0} stereo/jointstereo change(s) detected... audio.msg.audio=Audio audio.msg.newfile.left=(left): audio.msg.newfile.right=(right): audio.msg.noaudio=!> no Audio found on this stream data... audio.msg.convert.disabled=!> source frame does not fit the transcode criteria, function deactivated.. (frame# {0}) audio.msg.convert.error=!> source frame generates a convertion error (error {0}), (frame# {1}) #Videoprocess video.msg.pts.start_end=Video PTS: start 1.GOP {0}, end last GOP video.msg.summary=-> Video: fr/ ct/ 1p/ cg/ og/ dg -> video.progress=analyze video stream file video.msg.skip.sec=-> skip sequence_end_code following GOP# {0} @ video.error.io=!> pure video access error video.msg.error.lackofdata=!> GOP# {0} - lack of data, ignored... video.msg.error.nopts.use_goptc=!> GOP# {0} has no PTS, use GOP TC for sync video.msg.error.nopts.use_lastpts=!> GOP# {0} has no PTS, use last PTS for sync video.msg.basics=-> video basics: {0}bps, vbvBuffer video.msg.newformat=GOP# {0}, new format in next leading sequenceheader detected: video.msg.error.pesext_in_es=!> GOP# {0}, PES_header and extension found in ES, filled with zero... (GOP offs. {1}) video.msg.error.pes_in_es=!> GOP# {0}, PES_header found in ES, filled with zero... (GOP offs. {1}) video.msg.error.frame.wrong=!> wrong frametype {0}, tref video.msg.export.start=-> starting export of video data @ GOP# video.msg.pts.diff=!> PTS difference of {0} ({1}) to last exported GOP detected video.msg.error.brokenlink=(broken_link corrected) video.msg.frame.drop=!> dropping useless B-Frames @ GOP# {0} / new Timecode video.msg.error.frame.not=!> GOP# {0} contains no frames video.msg.error.frame.not.i=!> GOP# {0} doesn't start with an I-Frame at tref '0' video.msg.error.pts.early=!> startPTS of GOP# {0} is earlier than the end of last GOP.. (exp. {1}) video.msg.error.gop.drop=!> dropping GOP# {0} @ orig.PTS {1} ({2}) video.msg.error.gop.diff=!> Pics exp/cnt {0}, inGOP PTS diff. {1}ms, new Timecode video.msg.error.gop.dump=-> dump GOP to file: video.msg.io.non=no video.msg.io.int=interlaced video.msg.io.pro=progressive video.msg.io.int_pro=interlaced & progressive video.msg.length=-> Video length: {0} frames @ video.msg.gop.summary=-> GOP summary: min. {0}, max. {1} fields; contains {2} frames video.error.pts.same=-> found {0} GOPs with the same PTS value for different pictures! video.summary=.Video {0}:\t{1} Frames\t{2}\t\t video.msg.bitrate.avg=-> avg. bitrate {0}bps (min/max: {1}) video.msg.bitrate.avgnom=-> avg. nom. bitrate {0}bps (min/max: {1}) video.msg.bitrate.vbr=-> set first sequenceheader bitrate to VBR video.msg.bitrate.val=-> set first sequenceheader bitrate to {0}bps video.msg.resolution=-> set first sequenceheader resolution from {0} to #Teletextprocess teletext.msg.nooutput=!> no output format for teletext specified... teletext.msg.output=-> export format: teletext.msg.tmpfile=-> temp. file: {0} ({1} bytes) teletext.msg.page=page number teletext.msg.megaradio=MegaRadio mp3 stream teletext.progress=searching & decoding teletext.msg.search=-> looking for teletext.status=pages: teletext.msg.discard=!> {0} PTS's discarded in stream teletext.msg.pts.start_end=Teletext PTS: first packet {0}, last packet teletext.msg.pts.missed=!> teletext stream doesn't use PTS's, sync impossible teletext.msg.pts.mismatch=!> video & teletext PTS doesn't match at any time! teletext.msg.adjust.at.video=->adjusting teletext at video-timeline teletext.msg.adjust.at.own=-> adjusting teletext at its own timeline teletext.msg.syncword.lost=!> missing syncword @ teletext.msg.syncword.found=!> found syncword @ teletext.msg.vps=-> VPS status: {0} @ PTS teletext.msg.provider=-> provider: teletext.msg.program=-> program: teletext.msg.summary={0} pages of No. {1} written... teletext.summary=Teletext {0}:\t{1} pages of No. {2}\t{3}\t teletext.error.eof=!> Teletext EOF reached in error: teletext.error.io=!> Teletext I/O error: {0} / teletext.msg.newrun=-> perform 2nd SUP Yoffset #Subpictureprocess subpicture.msg.error3=!> error while decoding DVB Subpicture subpicture.msg.error4=!> lack of packet data subpicture.msg.error5=!> packet size doesn't match packet data subpicture.msg.error6=!> wrong chunk position index subpicture.msg.error7=!> wrong chunk position subpicture.msg.error8=!> wrong end of chunk index subpicture.msg.error9=!> wrong end of chunk subpicture.msg.model=-> selected DVB subpicture color model: {0} ; fixed to page id: subpicture.msg.output=-> export format: subpicture.msg.tmpfile=-> temp. file: {0} ({1} bytes) subpicture.progress=check & synchronize subpicture.msg.discard=!> {0} PTS's discarded in stream subpicture.msg.pts.mismatch=!> video & subpicture PTS doesn't match at any time! subpicture.msg.adjust.at.video=-> adjusting subpicture at video-timeline subpicture.msg.adjust.at.own=-> adjusting subpicture at its own timeline subpicture.msg.syncword.lost=!> missing syncword @ subpicture.msg.syncword.found=!> found syncword @ subpicture.msg.error={0} @ {1}, dropping picture... subpicture.msg.dvbsource=-> source is DVB Subtitle... subpicture.status=pic's: subpicture.preview.title.dvdexport=/ picture {0} -> in: {1} duration: subpicture.preview.title.dvbexport=/ page id {0} / picture {1} -> in: {2} duration: subpicture.msg.forced=from picture subpicture.msg.forced.no=-> display status: not forced, subpicture.msg.forced.yes=-> display status: forced, subpicture.preview.title.noexport=/ picture not exported... subpicture.msg.pts.start_end=Subpicture PTS: first packet {0}, last packet subpicture.msg.summary={0} subpictures written... subpicture.summary=SubPicture {0}:\t{1} subpictures\t{2}\t subpicture.msg.error.eof=!> Subpicture EOF reached in error: subpicture.msg.error.io=!> Subpicture IO error {0} / subpicture.msg.error.dvbdecoding=!> decoding error: {0}, Region_Id {1} (pts {2}) #LPCMprocess lpcm.msg.develop=...under development... lpcm.msg.tmpfile=-> temp. file: {0} ({1} bytes) lpcm.progress=check & synchronize lpcm.msg.pts.mismatch=!> video & LPCM PTS doesn't match at any time! lpcm.msg.adjust.at.video=-> adjusting LPCM at video-timeline lpcm.msg.adjust.at.own=-> adjusting LPCM at its own timeline lpcm.msg.syncword.lost=!> missing syncword @ lpcm.msg.syncword.found=!> found syncword @ lpcm.msg.source=-> src_audio: {0} @ lpcm.msg.source.max=-> src_audio: stop displaying, more than 100 audio mode changes in one file reduce work speed lpcm.msg.error.align=!> packet not WORD aligned lpcm.msg.pts.start_end=LPCM PTS: first packet {0}, last packet lpcm.msg.summary={0} packs written... lpcm.summary=LPCM {0}:\t{1} packs\t{2}\t lpcm.error.eof=!> LPCM EOF reached in error: lpcm.error.io=!> LPCM IO error: {0} / #various all.msg.pts.faked=--> using faked PTS for following data: logalias.error.io=!> Logalias IO Error: all.msg.error.max=-> more than 500 warnings/errors, stop logging.. all.msg.error.summary=-> we have {0} warnings/errors. all.msg.noprimaryfile=!> filetype is not supported as a secondary file. check the file order/segmentation. #demux demux.error.audio.startcode=!> invalid startcode, refuse PES packet demux.error.audio.io=!> demux Audio error: demux.error.video.io=!> demux Video error: demux.msg.celltimes=--> Celltimes in: {0}CellTimes.txt demux.error.video.startcode=!> invalid startcode, refuse video PES packet demux.error.video.payload=!> incoming PES packet without payload or wrong header data demux.msg.skip.sec=-> skip sequence_end_code following GOP# demux.error.gop.toobig=-> dropping video data, GOP larger than 6MB #ftpchooser ftpchooser.server.tip=Name or IP adress of ftp server ftpchooser.server=Server: ftpchooser.port.tip=Port of ftp server ftpchooser.port=Port: ftpchooser.user.tip=User for ftp connection ftpchooser.user=User: ftpchooser.password.tip=Password for ftp connection ftpchooser.password=Password: ftpchooser.directory.tip=Directory on ftp server ftpchooser.directory=Directory: ftpchooser.test=Test ftpchooser.state.tip=State ftpchooser.state=State: ftpchooser.untested=untested, try to connect ftpchooser.ok=OK ftpchooser.cancel=Cancel ftpchooser.title=choose ftp server ftpchooser.msg.noconnect=Can't connect. ftpchooser.msg.nologin=Can't login. ftpchooser.msg.nodirectory=Can't change to directory. ftpchooser.msg.success=Everything is fine. ftp.command.label=FTP command: ftp.command.tip=user specific FTP commands for FTP access, for multiple commands use delimiter '|' FtpServer.Commands=FTP command: FtpServer.Commands.Tip=user specific FTP commands for FTP access, for multiple commands use delimiter '|' FtpPanel.Title=FTP Settings #JobCollection JobCollection.NoInfo=no Info JobCollection.InProgress=In Progress! JobCollection.Idle=Idle. JobCollection.Action=Action: JobCollection.unspecified=not specif. JobCollection.PrimaryFileSegments=FileSegments: JobCollection.SecondaryFiles=second. Files: JobCollection.Cutpoints=Cutpoints: JobCollection.Chapters=Chapters: JobCollection.PidSelection=PID-Selection: JobCollection.OwnSettings=sep.Settings: JobCollection.AllSize=Size \u03A3: #CollectionTable CollectionTable.FileLocation=Location CollectionTable.FileName=Filename CollectionTable.Size=Size CollectionTable.lastModified=lastModified CollectionTable.Streamtype=Streamtype CollectionTable.Source=Src #PreviewPanel PreviewPanel.saveCurrentPicture=save current picture.. PreviewPanel.saveCurrentPictureDAR=save current picture with DAR.. #NetPanel NetPanel.WebServerPort=Port: NetPanel.WebServerAccess=AccessString: NetPanel.autostartWebServer=autostart WebIFServer NetPanel.Title=WebInterface NetPanel.autostartWebServer.Tip= NetPanel.WebServerPort.Tip= NetPanel.WebServerAccess.Tip= project-x/resources/px.gif0000600000175000017500000000337010140614420017242 0ustar supermariosupermarioGIF89a#TИذؠ,#T0I8ͻ`(dihlp,tmx|pH,Ȥrl:ШtJZجvzxL.zn|N~ J[2HY!5 EUÐ˺0FSƣ н 2 CQₔ! br@ڌx Sz7Bp(A-VEaӹh? TƇ*N7:VEĤ5@/ 'nRR̥|SHBdf&z(՚*@Ƭ䶠6IJHZt:XQ]lӤ D]5Hr;UD"}M^6$ʠnրÞu2 O&=x%G ny9*`Nc ;L J qmH$9r OmEA.u - ץ&=Cx 59Cst  FgF JV#bPB=xds;r"|p"vpbZ Ĉt(e8y٤?>A;_(iv·#XPV6U4eylO.O^tu&Ah('FtXM}e I,bAu:!j\=.SNڀ|W~)%=G~J]կRaLӀJ#2ܵkLZ,Z:{k[~u zવ=ފ_6*(nj γe5HVCdI"NAHsAkO !TNq+o76NadOjB0+ #pACeLjrC;vQքA/{È䀟U9PY;;GɕJ}*̋aLӼ8U99@:YJLp'jA<0o߿R *ތ1_?L3h>*ZEgnvwt:TQyb$U@hFXQ ohL_ӴkJָx#[׾D_;*" V:d'KZͬf7zl;project-x/resources/rem.gif0000600000175000017500000000167110140614420017400 0ustar supermariosupermarioGIF89a 333ffffff33̙33ff333f3f33f3̙ff3f̙3f̙fff3̙3f333ff33fff3f3ff3ff33f3f33ff3f3̙33ff333f33ff333f3f3ff3ff̙f3f33̙ff̰̙3f3ff3f333ff3f3Xhp3ff؀Ј3ff3ff3ȘАذf3f3f33fx@Hh3x@HpXhhxx؀耘px耐PhppxȐppHHhff@@h33f̀33ff3338f33ff33f3f33fff3f3ff̙3̙3ff3ff3f̙̙3f333ff3f3fff3f3f333!, JEXWR k \hݢl֬]z:*)SpJ)S Z9hMH = qϟ4+П )TaTPIJdB M*]c(Ց#N/vb噓'DI;project-x/resources/rf.gif0000600000175000017500000000166710140614420017231 0ustar supermariosupermarioGIF89a 333ffffff33̙33ff333f3333f33f3̙ff3f̙3f̙fff3̙3f333ff33fff3f3ff3ff33f3f33ff3f3̙33ff333f33ff333f3f3ff3ff̙f3f33̙ff̙3f3ff3f333ff3f33ffXhx3ff̠3ff3ȐfPXh3f3fpxhp33fxȀ萨p3PXXhhxȀ؀蘨PXx8@pبpx8@xhppxиff33f33ff333f33ff33f3f33fff3f3ff̙3̙3ff3ff3f̙̙3f333ff3f3fff3f3f3f333f3!, E`Re'Ot.[\iV+PN*Vf-\'{1:9kԣZ:Ѭ^YLF|QW @Sd?Z K UiQW{2J&@CUI@;project-x/resources/save_yes.gif0000600000175000017500000000174610326330272020444 0ustar supermariosupermarioGIF89a(((HHHhhpPP` (! ,H(0P`@ PA <8@ (8bp` A\p̨ǏA(r ɒNT)%HazّFqJԹ#ʟ@K;project-x/resources/start.gif0000600000175000017500000000200410306716524017755 0ustar supermariosupermarioGIF89a<333ffffff33̙33ff333f33ff33f3f33fff3̙ff3f3̙̙3ff̙3fff3̙3f333ff3f33fff3f3ff3ff33f3f33ff3f3̙33ff333f33ff333f3f3ff3ff̙f3f33̙ff̙3f3ff3f333ff3f33ff3ff3ff3f3f3f33f3ff33f33ff333f33ff33f3f33fff3f3ff̙3̙3ff3ff3f̙̙3f333ff3f33ff3fff3f3f3f3f33f3! ,< H*\ȰÇ#J|hĂ Xp CZHI9 LHMfȒfʆ/_B9sMqPfǟjs!ϣA\ȔiBP*Z*F(nUص+Aa&EJlUO5eے'n[nSy/́h\߯k[Ċm6k2洓7W3ń.mZs詎Cp/.,Aھ N;project-x/resources/stop.gif0000600000175000017500000000157210306716532017615 0ustar supermariosupermarioGIF89a333ffffff33̙33ff333f33ff33f3f33fff3̙ff3f3̙̙3ff̙3fff3̙3f333ff3f33fff3f3ff3ff33f3f33ff3f3̙33ff333f33ff333f3f3ff3ff̙f3f33̙ff̙3f3ff3f333ff3f33ff3ff3ff3f3f3f33f3ff33f33ff333f33ff33f3f33fff3f3ff̙3̙3ff3ff3f̙̙3f333ff3f33ff3fff3f3f3f3f33f3! ,W H*\ȰM#Jq!ŋbX1!Ǎ?^ )r"ɒOܤe˒/E8cMW̩%O719TãH*m;project-x/resources/up.gif0000600000175000017500000000170110140614420017233 0ustar supermariosupermarioGIF89a PYQZӥ䂔PX{ނR[iv􋗸Sahwz|昛t̂نǟ؃kw|bq|nyowwȚަّWg7AVڕɢȢ㆓ޣ_hz䁏邔Á㌔is֪7?WEQo~fz~rփٞضȝ᚟ÎʄөӊQZퟸش=Fv͆꠿QY>F棧|Ó@La!, ؑ @,`3 tAD1I`"1#V4qjA{sc3Q1JuV ”K<9R(\t!ZPK ̔Hb 7jRH`V($8`T@c |Xhy#L&F棧|Ó@La!,  @HI &Ft!F/PPh@1dt ydI)T^!.ڨbÙ)os͚@ؠ@..R \ɑN k(ЂB(^#LNQBa 4!G@;project-x/sources.lst0000600000175000017500000001526010411113010016310 0ustar supermariosupermariosrc/net/sourceforge/dvb/projectx/audio/AudioFormat.java src/net/sourceforge/dvb/projectx/audio/AudioFormatDTS.java src/net/sourceforge/dvb/projectx/audio/AudioFormatAC3.java src/net/sourceforge/dvb/projectx/audio/AudioFormatLPCM.java src/net/sourceforge/dvb/projectx/audio/AudioFormatWAV.java src/net/sourceforge/dvb/projectx/audio/AudioFormatMPA.java src/net/sourceforge/dvb/projectx/audio/MpaConverter.java src/net/sourceforge/dvb/projectx/audio/MpaDecoder.java src/net/sourceforge/dvb/projectx/audio/RIFFHeader.java src/net/sourceforge/dvb/projectx/common/Common.java src/net/sourceforge/dvb/projectx/common/GuiInterface.java src/net/sourceforge/dvb/projectx/common/GuiInterfaceIF.java src/net/sourceforge/dvb/projectx/common/JobCollection.java src/net/sourceforge/dvb/projectx/common/JobProcessing.java src/net/sourceforge/dvb/projectx/common/Keys.java src/net/sourceforge/dvb/projectx/common/Resource.java src/net/sourceforge/dvb/projectx/common/Settings.java src/net/sourceforge/dvb/projectx/common/Start.java src/net/sourceforge/dvb/projectx/io/BitWalker.java src/net/sourceforge/dvb/projectx/io/IDDBufferedOutputStream.java src/net/sourceforge/dvb/projectx/io/RawFile.java src/net/sourceforge/dvb/projectx/io/StandardBuffer.java src/net/sourceforge/dvb/projectx/net/WebInterface.java src/net/sourceforge/dvb/projectx/parser/CommonParsing.java src/net/sourceforge/dvb/projectx/parser/Gop.java src/net/sourceforge/dvb/projectx/parser/GopArray.java src/net/sourceforge/dvb/projectx/parser/HpFix.java src/net/sourceforge/dvb/projectx/parser/MainProcess.java src/net/sourceforge/dvb/projectx/parser/Scan.java src/net/sourceforge/dvb/projectx/parser/StreamBuffer.java src/net/sourceforge/dvb/projectx/parser/StreamConverter.java src/net/sourceforge/dvb/projectx/parser/StreamDemultiplexer.java src/net/sourceforge/dvb/projectx/parser/StreamParser.java src/net/sourceforge/dvb/projectx/parser/StreamParserBase.java src/net/sourceforge/dvb/projectx/parser/StreamParserPVA.java src/net/sourceforge/dvb/projectx/parser/StreamParserTS.java src/net/sourceforge/dvb/projectx/parser/StreamParserPESPrimary.java src/net/sourceforge/dvb/projectx/parser/StreamParserPESSecondary.java src/net/sourceforge/dvb/projectx/parser/StreamParserESVideo.java src/net/sourceforge/dvb/projectx/parser/StreamParserESAudio.java src/net/sourceforge/dvb/projectx/parser/StreamParserESSubpicture.java src/net/sourceforge/dvb/projectx/parser/StreamProcess.java src/net/sourceforge/dvb/projectx/parser/StreamProcessBase.java src/net/sourceforge/dvb/projectx/parser/StreamProcessTeletext.java src/net/sourceforge/dvb/projectx/parser/StreamProcessSubpicture.java src/net/sourceforge/dvb/projectx/parser/StreamProcessAudio.java src/net/sourceforge/dvb/projectx/parser/StreamProcessLPCMAudio.java src/net/sourceforge/dvb/projectx/parser/StripAudio.java src/net/sourceforge/dvb/projectx/parser/StripRelook.java src/net/sourceforge/dvb/projectx/parser/VBI.java src/net/sourceforge/dvb/projectx/subtitle/Bitmap.java src/net/sourceforge/dvb/projectx/subtitle/BMP.java src/net/sourceforge/dvb/projectx/subtitle/CharSet.java src/net/sourceforge/dvb/projectx/subtitle/DVBSubpicture.java src/net/sourceforge/dvb/projectx/subtitle/Subpicture.java src/net/sourceforge/dvb/projectx/subtitle/Teletext.java src/net/sourceforge/dvb/projectx/subtitle/UnicodeWriter.java src/net/sourceforge/dvb/projectx/thirdparty/Chapters.java src/net/sourceforge/dvb/projectx/thirdparty/D2V.java src/net/sourceforge/dvb/projectx/thirdparty/Ifo.java src/net/sourceforge/dvb/projectx/thirdparty/TS.java src/net/sourceforge/dvb/projectx/video/IDCTRefNative.java src/net/sourceforge/dvb/projectx/video/IDCTSseNative.java src/net/sourceforge/dvb/projectx/video/MpvDecoder.java src/net/sourceforge/dvb/projectx/video/Preview.java src/net/sourceforge/dvb/projectx/video/PreviewObject.java src/net/sourceforge/dvb/projectx/video/Video.java src/net/sourceforge/dvb/projectx/video/WSS.java src/net/sourceforge/dvb/projectx/xinput/DirType.java src/net/sourceforge/dvb/projectx/xinput/FileType.java src/net/sourceforge/dvb/projectx/xinput/StreamInfo.java src/net/sourceforge/dvb/projectx/xinput/XInputDirectory.java src/net/sourceforge/dvb/projectx/xinput/XInputDirectoryIF.java src/net/sourceforge/dvb/projectx/xinput/XInputFile.java src/net/sourceforge/dvb/projectx/xinput/XInputFileIF.java src/net/sourceforge/dvb/projectx/xinput/XInputStream.java src/net/sourceforge/dvb/projectx/xinput/file/XInputDirectoryImpl.java src/net/sourceforge/dvb/projectx/xinput/file/XInputFileImpl.java src/net/sourceforge/dvb/projectx/xinput/ftp/FtpServer.java src/net/sourceforge/dvb/projectx/xinput/ftp/FtpVO.java src/net/sourceforge/dvb/projectx/xinput/ftp/StringCommandListener.java src/net/sourceforge/dvb/projectx/xinput/ftp/XInputDirectoryImpl.java src/net/sourceforge/dvb/projectx/xinput/ftp/XInputFileImpl.java src/net/sourceforge/dvb/projectx/xinput/topfield_raw/RawFileInputStream.java src/net/sourceforge/dvb/projectx/xinput/topfield_raw/RawInterface.java src/net/sourceforge/dvb/projectx/xinput/topfield_raw/RawReadIF.java src/net/sourceforge/dvb/projectx/xinput/topfield_raw/XInputDirectoryImpl.java src/net/sourceforge/dvb/projectx/xinput/topfield_raw/XInputFileImpl.java src/edu/stanford/ejalbert/BrowserLauncher.java src/RawRead.java src/net/sourceforge/dvb/projectx/gui/AboutBox.java src/net/sourceforge/dvb/projectx/gui/BitrateMonitor.java src/net/sourceforge/dvb/projectx/gui/CheckBoxListener.java src/net/sourceforge/dvb/projectx/gui/CollectionPanel.java src/net/sourceforge/dvb/projectx/gui/ColumnLayout.java src/net/sourceforge/dvb/projectx/gui/ComboBoxIndexListener.java src/net/sourceforge/dvb/projectx/gui/ComboBoxItemListener.java src/net/sourceforge/dvb/projectx/gui/CommonGui.java src/net/sourceforge/dvb/projectx/gui/CutView.java src/net/sourceforge/dvb/projectx/gui/FtpChooser.java src/net/sourceforge/dvb/projectx/gui/GuiInterfaceImpl.java src/net/sourceforge/dvb/projectx/gui/HexViewer.java src/net/sourceforge/dvb/projectx/gui/Html.java src/net/sourceforge/dvb/projectx/gui/MainFrame.java src/net/sourceforge/dvb/projectx/gui/MemoryMonitor.java src/net/sourceforge/dvb/projectx/gui/PatchDialog.java src/net/sourceforge/dvb/projectx/gui/PicturePanel.java src/net/sourceforge/dvb/projectx/gui/PreSettings.java src/net/sourceforge/dvb/projectx/gui/ProcessWindow.java src/net/sourceforge/dvb/projectx/gui/StartUp.java src/net/sourceforge/dvb/projectx/gui/SubpictureFrame.java src/net/sourceforge/dvb/projectx/gui/TeletextPageMatrix.java src/net/sourceforge/dvb/projectx/gui/TextFieldListener.java src/net/sourceforge/dvb/projectx/gui/TextFieldKeyListener.java src/net/sourceforge/dvb/projectx/gui/UISwitchListener.java src/net/sourceforge/dvb/projectx/gui/X_JFileChooser.java project-x/src/0000700000175000017500000000000010745203152014703 5ustar supermariosupermarioproject-x/src/RawRead.java0000600000175000017500000000621710351110064017073 0ustar supermariosupermario/* * @(#)RawRead.java - alias class definition, may be replaced by additional disk access * * This code implements the interface to the C++ code. * * This code was developed by chrisg to access a Topfield 4000 * * Updated: * 2004-04-09 Adapted to show load status * 2004-01-25 Initial implementation * * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ import java.util.ArrayList; //import net.sourceforge.dvb.projectx.xinput.topfield_raw.*;; import net.sourceforge.dvb.projectx.xinput.topfield_raw.RawReadIF; public class RawRead implements RawReadIF { // check DLL load status and errors native public String GetLoadStatus(); // directory read functions native public int findOpen(String directoryname); native public String findNextFile(int findhandle); native public int findClose(int findhandle); // file read functions native public int openFile(String filename); native public int readFile(int filehandle,byte[] array,int offsetinbuffer,int readlen); native public int closeFile(int filehandle); native public long skipBytes(int filehandle,long skipbytes); native public long getFileSize(String filename); native public long lastModified(String filename); static boolean DllLoaded; public void add_native_files(ArrayList arraylist) { String s; int i=0; int hdl=findOpen("\\"); if (hdl!=0) { do { s=findNextFile(hdl); if (s.length()!=0) arraylist.add(s); i++; //if (i>100) // break; } while (s.length()!=0); findClose(hdl); } return; } /* public boolean isAccessibleDisk(String sourcefile) { // make sure it's not a PC file (c: or UNC prefix) and not a Linux file (/ prefix) // support of URLs untested ( file:// , http:// .. ) if (DllLoaded && sourcefile.charAt(1) != ':' && sourcefile.charAt(1) != '\\' && sourcefile.charAt(0) != '/') return true; else return false; } */ public boolean AccessEnabled() { return DllLoaded; } // Loads the file Rawread.dll at run-time // don't load if access isn't required static { try { System.loadLibrary("Rawread"); DllLoaded=true; } catch (UnsatisfiedLinkError exc) { DllLoaded=false; } } // Constructor public RawRead() {} } project-x/src/edu/0000700000175000017500000000000010745203152015460 5ustar supermariosupermarioproject-x/src/edu/stanford/0000700000175000017500000000000010412367426017306 5ustar supermariosupermarioproject-x/src/edu/stanford/ejalbert/0000700000175000017500000000000010412367426021076 5ustar supermariosupermarioproject-x/src/edu/stanford/ejalbert/BrowserLauncher.java0000600000175000017500000005755010140632462025055 0ustar supermariosupermariopackage edu.stanford.ejalbert; import java.io.File; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * BrowserLauncher is a class that provides one static method, openURL, which opens the default * web browser for the current user of the system to the given URL. It may support other * protocols depending on the system -- mailto, ftp, etc. -- but that has not been rigorously * tested and is not guaranteed to work. *

* Yes, this is platform-specific code, and yes, it may rely on classes on certain platforms * that are not part of the standard JDK. What we're trying to do, though, is to take something * that's frequently desirable but inherently platform-specific -- opening a default browser -- * and allow programmers (you, for example) to do so without worrying about dropping into native * code or doing anything else similarly evil. *

* Anyway, this code is completely in Java and will run on all JDK 1.1-compliant systems without * modification or a need for additional libraries. All classes that are required on certain * platforms to allow this to run are dynamically loaded at runtime via reflection and, if not * found, will not cause this to do anything other than returning an error when opening the * browser. *

* There are certain system requirements for this class, as it's running through Runtime.exec(), * which is Java's way of making a native system call. Currently, this requires that a Macintosh * have a Finder which supports the GURL event, which is true for Mac OS 8.0 and 8.1 systems that * have the Internet Scripting AppleScript dictionary installed in the Scripting Additions folder * in the Extensions folder (which is installed by default as far as I know under Mac OS 8.0 and * 8.1), and for all Mac OS 8.5 and later systems. On Windows, it only runs under Win32 systems * (Windows 95, 98, and NT 4.0, as well as later versions of all). On other systems, this drops * back from the inherently platform-sensitive concept of a default browser and simply attempts * to launch Netscape via a shell command. *

* This code is Copyright 1999-2001 by Eric Albert (ejalbert@cs.stanford.edu) and may be * redistributed or modified in any form without restrictions as long as the portion of this * comment from this paragraph through the end of the comment is not removed. The author * requests that he be notified of any application, applet, or other binary that makes use of * this code, but that's more out of curiosity than anything and is not required. This software * includes no warranty. The author is not repsonsible for any loss of data or functionality * or any adverse or unexpected effects of using this software. *

* Credits: *
Steven Spencer, JavaWorld magazine (Java Tip 66) *
Thanks also to Ron B. Yeh, Eric Shapiro, Ben Engber, Paul Teitlebaum, Andrea Cantatore, * Larry Barowski, Trevor Bedzek, Frank Miedrich, and Ron Rabakukk * * @author Eric Albert (ejalbert@cs.stanford.edu) * @version 1.4b1 (Released June 20, 2001) */ public class BrowserLauncher { /** * The Java virtual machine that we are running on. Actually, in most cases we only care * about the operating system, but some operating systems require us to switch on the VM. */ private static int jvm; /** The browser for the system */ private static Object browser; /** * Caches whether any classes, methods, and fields that are not part of the JDK and need to * be dynamically loaded at runtime loaded successfully. *

* Note that if this is false, openURL() will always return an * IOException. */ private static boolean loadedWithoutErrors; /** The com.apple.mrj.MRJFileUtils class */ private static Class mrjFileUtilsClass; /** The com.apple.mrj.MRJOSType class */ private static Class mrjOSTypeClass; /** The com.apple.MacOS.AEDesc class */ private static Class aeDescClass; /** The (int) method of com.apple.MacOS.AETarget */ private static Constructor aeTargetConstructor; /** The (int, int, int) method of com.apple.MacOS.AppleEvent */ private static Constructor appleEventConstructor; /** The (String) method of com.apple.MacOS.AEDesc */ private static Constructor aeDescConstructor; /** The findFolder method of com.apple.mrj.MRJFileUtils */ private static Method findFolder; /** The getFileCreator method of com.apple.mrj.MRJFileUtils */ private static Method getFileCreator; /** The getFileType method of com.apple.mrj.MRJFileUtils */ private static Method getFileType; /** The openURL method of com.apple.mrj.MRJFileUtils */ private static Method openURL; /** The makeOSType method of com.apple.MacOS.OSUtils */ private static Method makeOSType; /** The putParameter method of com.apple.MacOS.AppleEvent */ private static Method putParameter; /** The sendNoReply method of com.apple.MacOS.AppleEvent */ private static Method sendNoReply; /** Actually an MRJOSType pointing to the System Folder on a Macintosh */ private static Object kSystemFolderType; /** The keyDirectObject AppleEvent parameter type */ private static Integer keyDirectObject; /** The kAutoGenerateReturnID AppleEvent code */ private static Integer kAutoGenerateReturnID; /** The kAnyTransactionID AppleEvent code */ private static Integer kAnyTransactionID; /** The linkage object required for JDirect 3 on Mac OS X. */ private static Object linkage; /** The framework to reference on Mac OS X */ private static final String JDirect_MacOSX = "/System/Library/Frameworks/Carbon.framework/Frameworks/HIToolbox.framework/HIToolbox"; /** JVM constant for MRJ 2.0 */ private static final int MRJ_2_0 = 0; /** JVM constant for MRJ 2.1 or later */ private static final int MRJ_2_1 = 1; /** JVM constant for Java on Mac OS X 10.0 (MRJ 3.0) */ private static final int MRJ_3_0 = 3; /** JVM constant for MRJ 3.1 */ private static final int MRJ_3_1 = 4; /** JVM constant for any Windows NT JVM */ private static final int WINDOWS_NT = 5; /** JVM constant for any Windows 9x JVM */ private static final int WINDOWS_9x = 6; /** JVM constant for any other platform */ private static final int OTHER = -1; /** * The file type of the Finder on a Macintosh. Hardcoding "Finder" would keep non-U.S. English * systems from working properly. */ private static final String FINDER_TYPE = "FNDR"; /** * The creator code of the Finder on a Macintosh, which is needed to send AppleEvents to the * application. */ private static final String FINDER_CREATOR = "MACS"; /** The name for the AppleEvent type corresponding to a GetURL event. */ private static final String GURL_EVENT = "GURL"; /** * The first parameter that needs to be passed into Runtime.exec() to open the default web * browser on Windows. */ private static final String FIRST_WINDOWS_PARAMETER = "/c"; /** The second parameter for Runtime.exec() on Windows. */ private static final String SECOND_WINDOWS_PARAMETER = "start"; /** * The third parameter for Runtime.exec() on Windows. This is a "title" * parameter that the command line expects. Setting this parameter allows * URLs containing spaces to work. */ private static final String THIRD_WINDOWS_PARAMETER = "\"\""; /** * The shell parameters for Netscape that opens a given URL in an already-open copy of Netscape * on many command-line systems. */ private static final String NETSCAPE_REMOTE_PARAMETER = "-remote"; private static final String NETSCAPE_OPEN_PARAMETER_START = "'openURL("; private static final String NETSCAPE_OPEN_PARAMETER_END = ")'"; /** * The message from any exception thrown throughout the initialization process. */ private static String errorMessage; /** * An initialization block that determines the operating system and loads the necessary * runtime data. */ static { loadedWithoutErrors = true; String osName = System.getProperty("os.name"); if (osName.startsWith("Mac OS")) { String mrjVersion = System.getProperty("mrj.version"); String majorMRJVersion = mrjVersion.substring(0, 3); try { double version = Double.valueOf(majorMRJVersion).doubleValue(); if (version == 2) { jvm = MRJ_2_0; } else if (version >= 2.1 && version < 3) { // Assume that all 2.x versions of MRJ work the same. MRJ 2.1 actually // works via Runtime.exec() and 2.2 supports that but has an openURL() method // as well that we currently ignore. jvm = MRJ_2_1; } else if (version == 3.0) { jvm = MRJ_3_0; } else if (version >= 3.1) { // Assume that all 3.1 and later versions of MRJ work the same. jvm = MRJ_3_1; } else { loadedWithoutErrors = false; errorMessage = "Unsupported MRJ version: " + version; } } catch (NumberFormatException nfe) { loadedWithoutErrors = false; errorMessage = "Invalid MRJ version: " + mrjVersion; } } else if (osName.startsWith("Windows")) { if (osName.indexOf("9") != -1) { jvm = WINDOWS_9x; } else { jvm = WINDOWS_NT; } } else { jvm = OTHER; } if (loadedWithoutErrors) { // if we haven't hit any errors yet loadedWithoutErrors = loadClasses(); } } /** * This class should be never be instantiated; this just ensures so. */ private BrowserLauncher() { } /** * Called by a static initializer to load any classes, fields, and methods required at runtime * to locate the user's web browser. * @return true if all intialization succeeded * false if any portion of the initialization failed */ private static boolean loadClasses() { switch (jvm) { case MRJ_2_0: try { Class aeTargetClass = Class.forName("com.apple.MacOS.AETarget"); Class osUtilsClass = Class.forName("com.apple.MacOS.OSUtils"); Class appleEventClass = Class.forName("com.apple.MacOS.AppleEvent"); Class aeClass = Class.forName("com.apple.MacOS.ae"); aeDescClass = Class.forName("com.apple.MacOS.AEDesc"); aeTargetConstructor = aeTargetClass.getDeclaredConstructor(new Class [] { int.class }); appleEventConstructor = appleEventClass.getDeclaredConstructor(new Class[] { int.class, int.class, aeTargetClass, int.class, int.class }); aeDescConstructor = aeDescClass.getDeclaredConstructor(new Class[] { String.class }); makeOSType = osUtilsClass.getDeclaredMethod("makeOSType", new Class [] { String.class }); putParameter = appleEventClass.getDeclaredMethod("putParameter", new Class[] { int.class, aeDescClass }); sendNoReply = appleEventClass.getDeclaredMethod("sendNoReply", new Class[] { }); Field keyDirectObjectField = aeClass.getDeclaredField("keyDirectObject"); keyDirectObject = (Integer) keyDirectObjectField.get(null); Field autoGenerateReturnIDField = appleEventClass.getDeclaredField("kAutoGenerateReturnID"); kAutoGenerateReturnID = (Integer) autoGenerateReturnIDField.get(null); Field anyTransactionIDField = appleEventClass.getDeclaredField("kAnyTransactionID"); kAnyTransactionID = (Integer) anyTransactionIDField.get(null); } catch (ClassNotFoundException cnfe) { errorMessage = cnfe.getMessage(); return false; } catch (NoSuchMethodException nsme) { errorMessage = nsme.getMessage(); return false; } catch (NoSuchFieldException nsfe) { errorMessage = nsfe.getMessage(); return false; } catch (IllegalAccessException iae) { errorMessage = iae.getMessage(); return false; } break; case MRJ_2_1: try { mrjFileUtilsClass = Class.forName("com.apple.mrj.MRJFileUtils"); mrjOSTypeClass = Class.forName("com.apple.mrj.MRJOSType"); Field systemFolderField = mrjFileUtilsClass.getDeclaredField("kSystemFolderType"); kSystemFolderType = systemFolderField.get(null); findFolder = mrjFileUtilsClass.getDeclaredMethod("findFolder", new Class[] { mrjOSTypeClass }); getFileCreator = mrjFileUtilsClass.getDeclaredMethod("getFileCreator", new Class[] { File.class }); getFileType = mrjFileUtilsClass.getDeclaredMethod("getFileType", new Class[] { File.class }); } catch (ClassNotFoundException cnfe) { errorMessage = cnfe.getMessage(); return false; } catch (NoSuchFieldException nsfe) { errorMessage = nsfe.getMessage(); return false; } catch (NoSuchMethodException nsme) { errorMessage = nsme.getMessage(); return false; } catch (SecurityException se) { errorMessage = se.getMessage(); return false; } catch (IllegalAccessException iae) { errorMessage = iae.getMessage(); return false; } break; case MRJ_3_0: try { Class linker = Class.forName("com.apple.mrj.jdirect.Linker"); Constructor constructor = linker.getConstructor(new Class[]{ Class.class }); linkage = constructor.newInstance(new Object[] { BrowserLauncher.class }); } catch (ClassNotFoundException cnfe) { errorMessage = cnfe.getMessage(); return false; } catch (NoSuchMethodException nsme) { errorMessage = nsme.getMessage(); return false; } catch (InvocationTargetException ite) { errorMessage = ite.getMessage(); return false; } catch (InstantiationException ie) { errorMessage = ie.getMessage(); return false; } catch (IllegalAccessException iae) { errorMessage = iae.getMessage(); return false; } break; case MRJ_3_1: try { mrjFileUtilsClass = Class.forName("com.apple.mrj.MRJFileUtils"); openURL = mrjFileUtilsClass.getDeclaredMethod("openURL", new Class[] { String.class }); } catch (ClassNotFoundException cnfe) { errorMessage = cnfe.getMessage(); return false; } catch (NoSuchMethodException nsme) { errorMessage = nsme.getMessage(); return false; } break; default: break; } return true; } /** * Attempts to locate the default web browser on the local system. Caches results so it * only locates the browser once for each use of this class per JVM instance. * @return The browser for the system. Note that this may not be what you would consider * to be a standard web browser; instead, it's the application that gets called to * open the default web browser. In some cases, this will be a non-String object * that provides the means of calling the default browser. */ private static Object locateBrowser() { if (browser != null) { return browser; } switch (jvm) { case MRJ_2_0: try { Integer finderCreatorCode = (Integer) makeOSType.invoke(null, new Object[] { FINDER_CREATOR }); Object aeTarget = aeTargetConstructor.newInstance(new Object[] { finderCreatorCode }); Integer gurlType = (Integer) makeOSType.invoke(null, new Object[] { GURL_EVENT }); Object appleEvent = appleEventConstructor.newInstance(new Object[] { gurlType, gurlType, aeTarget, kAutoGenerateReturnID, kAnyTransactionID }); // Don't set browser = appleEvent because then the next time we call // locateBrowser(), we'll get the same AppleEvent, to which we'll already have // added the relevant parameter. Instead, regenerate the AppleEvent every time. // There's probably a way to do this better; if any has any ideas, please let // me know. return appleEvent; } catch (IllegalAccessException iae) { browser = null; errorMessage = iae.getMessage(); return browser; } catch (InstantiationException ie) { browser = null; errorMessage = ie.getMessage(); return browser; } catch (InvocationTargetException ite) { browser = null; errorMessage = ite.getMessage(); return browser; } case MRJ_2_1: File systemFolder; try { systemFolder = (File) findFolder.invoke(null, new Object[] { kSystemFolderType }); } catch (IllegalArgumentException iare) { browser = null; errorMessage = iare.getMessage(); return browser; } catch (IllegalAccessException iae) { browser = null; errorMessage = iae.getMessage(); return browser; } catch (InvocationTargetException ite) { browser = null; errorMessage = ite.getTargetException().getClass() + ": " + ite.getTargetException().getMessage(); return browser; } String[] systemFolderFiles = systemFolder.list(); // Avoid a FilenameFilter because that can't be stopped mid-list for(int i = 0; i < systemFolderFiles.length; i++) { try { File file = new File(systemFolder, systemFolderFiles[i]); if (!file.isFile()) { continue; } // We're looking for a file with a creator code of 'MACS' and // a type of 'FNDR'. Only requiring the type results in non-Finder // applications being picked up on certain Mac OS 9 systems, // especially German ones, and sending a GURL event to those // applications results in a logout under Multiple Users. Object fileType = getFileType.invoke(null, new Object[] { file }); if (FINDER_TYPE.equals(fileType.toString())) { Object fileCreator = getFileCreator.invoke(null, new Object[] { file }); if (FINDER_CREATOR.equals(fileCreator.toString())) { browser = file.toString(); // Actually the Finder, but that's OK return browser; } } } catch (IllegalArgumentException iare) { //browser = browser; errorMessage = iare.getMessage(); return null; } catch (IllegalAccessException iae) { browser = null; errorMessage = iae.getMessage(); return browser; } catch (InvocationTargetException ite) { browser = null; errorMessage = ite.getTargetException().getClass() + ": " + ite.getTargetException().getMessage(); return browser; } } browser = null; break; case MRJ_3_0: case MRJ_3_1: browser = ""; // Return something non-null break; case WINDOWS_NT: browser = "cmd.exe"; break; case WINDOWS_9x: browser = "command.com"; break; case OTHER: default: browser = "netscape"; break; } return browser; } /** * Attempts to open the default web browser to the given URL. * @param url The URL to open * @throws IOException If the web browser could not be located or does not run */ public static void openURL(String url) throws IOException { if (!loadedWithoutErrors) { throw new IOException("Exception in finding browser: " + errorMessage); } Object browser = locateBrowser(); if (browser == null) { throw new IOException("Unable to locate browser: " + errorMessage); } switch (jvm) { case MRJ_2_0: Object aeDesc = null; try { aeDesc = aeDescConstructor.newInstance(new Object[] { url }); putParameter.invoke(browser, new Object[] { keyDirectObject, aeDesc }); sendNoReply.invoke(browser, new Object[] { }); } catch (InvocationTargetException ite) { throw new IOException("InvocationTargetException while creating AEDesc: " + ite.getMessage()); } catch (IllegalAccessException iae) { throw new IOException("IllegalAccessException while building AppleEvent: " + iae.getMessage()); } catch (InstantiationException ie) { throw new IOException("InstantiationException while creating AEDesc: " + ie.getMessage()); } finally { aeDesc = null; // Encourage it to get disposed if it was created browser = null; // Ditto } break; case MRJ_2_1: Runtime.getRuntime().exec(new String[] { (String) browser, url } ); break; case MRJ_3_0: int[] instance = new int[1]; int result = ICStart(instance, 0); if (result == 0) { int[] selectionStart = new int[] { 0 }; byte[] urlBytes = url.getBytes(); int[] selectionEnd = new int[] { urlBytes.length }; result = ICLaunchURL(instance[0], new byte[] { 0 }, urlBytes, urlBytes.length, selectionStart, selectionEnd); if (result == 0) { // Ignore the return value; the URL was launched successfully // regardless of what happens here. ICStop(instance); } else { throw new IOException("Unable to launch URL: " + result); } } else { throw new IOException("Unable to create an Internet Config instance: " + result); } break; case MRJ_3_1: try { openURL.invoke(null, new Object[] { url }); } catch (InvocationTargetException ite) { throw new IOException("InvocationTargetException while calling openURL: " + ite.getMessage()); } catch (IllegalAccessException iae) { throw new IOException("IllegalAccessException while calling openURL: " + iae.getMessage()); } break; case WINDOWS_NT: // Add quotes around the URL to allow ampersands and other special // characters to work. Process process = Runtime.getRuntime().exec(new String[] { (String) browser, FIRST_WINDOWS_PARAMETER, SECOND_WINDOWS_PARAMETER, THIRD_WINDOWS_PARAMETER, '"' + url + '"' }); // This avoids a memory leak on some versions of Java on Windows. // That's hinted at in . try { process.waitFor(); process.exitValue(); } catch (InterruptedException ie) { throw new IOException("InterruptedException while launching browser: " + ie.getMessage()); } break; case WINDOWS_9x: // 2004-10-23 dvb.matt mod, Win98SE 'start' command seems not work with a 'title' string in the commandline chain // Add quotes around the URL to allow ampersands and other special // characters to work. process = Runtime.getRuntime().exec(new String[] { (String) browser, FIRST_WINDOWS_PARAMETER, SECOND_WINDOWS_PARAMETER, '"' + url + '"' }); // This avoids a memory leak on some versions of Java on Windows. // That's hinted at in . try { process.waitFor(); process.exitValue(); } catch (InterruptedException ie) { throw new IOException("InterruptedException while launching browser: " + ie.getMessage()); } break; case OTHER: // Assume that we're on Unix and that Netscape is installed // First, attempt to open the URL in a currently running session of Netscape process = Runtime.getRuntime().exec(new String[] { (String) browser, NETSCAPE_REMOTE_PARAMETER, NETSCAPE_OPEN_PARAMETER_START + url + NETSCAPE_OPEN_PARAMETER_END }); try { int exitCode = process.waitFor(); if (exitCode != 0) { // if Netscape was not open Runtime.getRuntime().exec(new String[] { (String) browser, url }); } } catch (InterruptedException ie) { throw new IOException("InterruptedException while launching browser: " + ie.getMessage()); } break; default: // This should never occur, but if it does, we'll try the simplest thing possible Runtime.getRuntime().exec(new String[] { (String) browser, url }); break; } } /** * Methods required for Mac OS X. The presence of native methods does not cause * any problems on other platforms. */ private native static int ICStart(int[] instance, int signature); private native static int ICStop(int[] instance); private native static int ICLaunchURL(int instance, byte[] hint, byte[] data, int len, int[] selectionStart, int[] selectionEnd); } project-x/src/net/0000700000175000017500000000000010745203152015471 5ustar supermariosupermarioproject-x/src/net/sourceforge/0000700000175000017500000000000010412367426020022 5ustar supermariosupermarioproject-x/src/net/sourceforge/dvb/0000700000175000017500000000000010412367426020575 5ustar supermariosupermarioproject-x/src/net/sourceforge/dvb/projectx/0000700000175000017500000000000010412367426022433 5ustar supermariosupermarioproject-x/src/net/sourceforge/dvb/projectx/audio/0000700000175000017500000000000010745203152023526 5ustar supermariosupermarioproject-x/src/net/sourceforge/dvb/projectx/audio/AudioFormat.java0000600000175000017500000002534010355016404026610 0ustar supermariosupermario/* * @(#)AudioFormat.java - parse Audioheaders, basic class * * Copyright (c) 2003-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * The part of audio parsing was derived from the MPEG/Audio * Software Simulation Group's audio codec and ATSC A/52 in a special modified manner. * * * 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 * */ package net.sourceforge.dvb.projectx.audio; import java.io.File; import java.io.RandomAccessFile; import java.io.IOException; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.audio.AudioFormatDTS; import net.sourceforge.dvb.projectx.audio.AudioFormatAC3; import net.sourceforge.dvb.projectx.audio.AudioFormatLPCM; import net.sourceforge.dvb.projectx.audio.AudioFormatWAV; import net.sourceforge.dvb.projectx.audio.AudioFormatMPA; public class AudioFormat extends Object { private AudioFormat impl = null; /** * */ public AudioFormat(int type) { setNewType(type); } /** * */ public AudioFormat(byte[] frame) { //unused, meant for autodetection } /** * */ public AudioFormat() { init(); } /** * */ public void setNewType(int type) { switch (type) { case CommonParsing.DTS_AUDIO: impl = new AudioFormatDTS(); break; case CommonParsing.AC3_AUDIO: impl = new AudioFormatAC3(); break; case CommonParsing.LPCM_AUDIO: impl = new AudioFormatLPCM(); break; case CommonParsing.WAV_AUDIO: impl = new AudioFormatWAV(); break; case CommonParsing.MPEG_AUDIO: impl = new AudioFormatMPA(); break; } } public static boolean INTEL; public static int ID; public static int Layer; public static int Protection_bit; public static int Private_bit; public static int Bitrate; public static int Sampling_frequency; public static int Padding_bit; public static int public_bit; public static int Mode; public static int Mode_extension; public static int Copyright; public static int Original; public static int Channel; public static int Emphasis; public static int Size; public static int Size_base; public static int Bound; public static int Sblimit; public static double Time_length; public int nID; public int nLayer; public int nProtection_bit; public int nPrivate_bit; public int nBitrate; public int nSampling_frequency; public int nPadding_bit; public int npublic_bit; public int nMode; public int nMode_extension; public int nCopyright; public int nOriginal; public int nChannel; public int nEmphasis; public int nSize; public int nSize_base; public double nTime_length; public static int lID; public static int lLayer; public static int lProtection_bit; public static int lPrivate_bit; public static int lBitrate; public static int lSampling_frequency; public static int lPadding_bit; public static int lpublic_bit; public static int lMode; public static int lMode_extension; public static int lCopyright; public static int lOriginal; public static int lChannel; public static int lEmphasis; public static int lSize; public static int lSize_base; public static double lTime_length; /** * */ public void init() { INTEL = false; ID = 0; Layer = 0; Protection_bit = 0; Private_bit = 0; Bitrate = 0; Sampling_frequency = 0; Padding_bit = 0; Private_bit = 0; Mode = 0; Mode_extension = 0; Copyright = 0; Original = 0; Channel = 0; Emphasis = 0; Size = 0; Size_base = 0; Bound = 0; Sblimit = 32; Time_length = 0.0; } /** * */ public int getLastModeExtension() { return lMode_extension; } /** * */ public int getID() { return ID; } /** * */ public int getLayer() { return Layer; } /** * */ public int getBitrate() { return Bitrate; } /** * */ public int getSamplingFrequency() { return Sampling_frequency; } /** * */ public int getMode() { return Mode; } /** * */ public int getModeExtension() { return Mode_extension; } /** * */ public int getEmphasis() { return Emphasis; } /** * */ public int getSize() { return Size; } /** * */ public int getSizeBase() { return Size_base; } /** * */ public int getChannel() { return Channel; } /** * */ public double getFrameTimeLength() { return Time_length; } /** * */ public int parseHeader(byte[] data, int offset, int endoffset) { int ret = 0; if (impl != null) { for (int i = 0; i < endoffset; i++) if ((ret = parseHeader(data, offset + i)) < 0) continue; } return ret; } /** * */ public int parseHeader(byte[] frame, int offset) { return (impl == null ? 0 : impl.parseHeader(frame, offset)); } /** * */ public int parseNextHeader(byte[] frame, int offset) { return (impl == null ? 0 : impl.parseNextHeader(frame, offset)); } /** * save last header */ public void saveHeader() { lID = ID; lLayer = Layer; lProtection_bit = Protection_bit; lPrivate_bit = Private_bit; lBitrate = Bitrate; lSampling_frequency = Sampling_frequency; lPadding_bit = Padding_bit; lPrivate_bit = Private_bit; lMode = Mode; lMode_extension = Mode_extension; lCopyright = Copyright; lOriginal = Original; lChannel = Channel; lEmphasis = Emphasis; lSize = Size; lSize_base = Size_base; lTime_length = Time_length; } /** * */ public int compareHeader() { return (impl == null ? 0 : impl.compareHeader()); } /** * */ public String displayHeader() { return (impl == null ? "" : impl.displayHeader()); } /** * save and display last header */ public String saveAndDisplayHeader() { saveHeader(); return displayHeader(); } /** * */ public byte[] editFrame(byte[] frame, int framesize, int mode) { return (impl == null ? frame : impl.editFrame(frame, framesize, mode)); } /** * */ public void removeCRC(byte[] frame) { if (impl != null) impl.removeCRC(frame); } /** * */ public int validateCRC(byte[] frame, int offset, int len) { return (impl == null ? 0 : impl.validateCRC(frame, offset, len)); } /** * */ public void setAncillaryDataDecoder(boolean b1, boolean b2) { if (impl != null) impl.setAncillaryDataDecoder(b1, b2); } /** * */ public void decodeAncillaryData(byte[] frame) { if (impl != null) impl.decodeAncillaryData(frame); } /** * */ public int[] parseRiffData(byte[] frame) { return (impl == null ? null : impl.parseRiffData( frame)); } /** * returns RIFF */ public byte[] getRiffHeader() { return (new byte[] { 0x52, 0x49, 0x46, 0x46, //'RIFF' 0, 0, 0, 0, // all size LSB 0x57, 0x41, 0x56, 0x45, //'WAVE' 0x66, 0x6D, 0x74, 0x20, //'fmt ' 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x64, 0x61, 0x74, 0x61, // 'data' 0, 0, 0, 0 // data size LSB }); } /** * updates std RIFF */ public void fillStdRiffHeader(String file, long time_len) { try { RandomAccessFile riff = new RandomAccessFile(file, "rw"); int len = (int) riff.length() - 8; int bitrate = 1411200; riff.seek(4); riff.writeInt(littleEndian(len, 4, true)); //data+chunksize riff.seek(16); riff.writeInt(littleEndian(0x10, 4, true)); //chunk length riff.writeShort(littleEndian(1, 2, true)); //pcm riff.writeShort((short)littleEndian(2, 2, true)); //channels riff.writeInt(littleEndian(44100, 4, true)); //sample_freq riff.writeInt(littleEndian(bitrate / 8, 4, true)); //byterate riff.writeShort((short)littleEndian(4, 2, true)); //blockalign riff.writeShort((short)littleEndian(16, 2, true)); //bits_per_sample riff.seek(40); riff.writeInt(littleEndian(len - 36, 4, true)); //data-size riff.close(); } catch (IOException e) { Common.setExceptionMessage(e); } } /** * updates RIFF * returns playtime as int */ public long fillRiffHeader(String file) { long value = 0; try { RandomAccessFile riff = new RandomAccessFile(file, "rw"); int len = (int)riff.length() - 8; riff.seek(3); if (!INTEL) riff.write((byte)'X'); riff.seek(4); riff.writeInt(littleEndian(len, 4)); //data+chunksize riff.seek(16); riff.writeInt(littleEndian(0x10, 4)); //chunk length riff.writeShort(littleEndian(1, 2)); //pcm riff.writeShort((short)littleEndian(lChannel, 2)); //channels riff.writeInt(littleEndian(lSampling_frequency, 4)); //sample_freq riff.writeInt(littleEndian(lBitrate / 8, 4)); //byterate riff.writeShort((short)littleEndian(lMode, 2)); //blockalign riff.writeShort((short)littleEndian(lSize, 2)); //bits_per_sample riff.seek(40); riff.writeInt(littleEndian(len - 36, 4)); //data-size riff.close(); value = (8000L * (len - 36)) / lBitrate; } catch (IOException e) { Common.setExceptionMessage(e); } return value; } /** * */ public int littleEndian(byte[] data, int offset, int len, boolean reverse) { int value = 0; for (int a = 0; a < len; a++) value |= reverse ? ((0xFF & data[offset + a])<<(a * 8)) : ((0xFF & data[offset + a])<<((len - 1 - a) * 8)); return value; } /** * */ public int littleEndian(int data, int len) { return littleEndian(data, len, INTEL); } /** * */ public int littleEndian(int data, int len, boolean b) { if (!b) return data; if (len == 4) return ( (0xFF & data>>>24) | (0xFF & data>>>16)<<8 | (0xFF & data>>>8)<<16 | (0xFF & data)<<24 ); else return ( (0xFF & data>>>8) | (0xFF & data)<<8 ); } }project-x/src/net/sourceforge/dvb/projectx/audio/AudioFormatAC3.java0000600000175000017500000002514710370305332027102 0ustar supermariosupermario/* * @(#)AudioFormatAC3.java - parse Audioheaders, ac3 * * Copyright (c) 2003-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * The part of audio parsing was derived from * ATSC A/52 in a special modified manner. * * crc computing derived from: * The simplest AC3 encoder, Copyright (c) 2000 Fabrice Bellard. * * 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 * */ package net.sourceforge.dvb.projectx.audio; import net.sourceforge.dvb.projectx.audio.AudioFormat; public class AudioFormatAC3 extends AudioFormat { public AudioFormatAC3() { super(); ac3_crc_init(); } private int CRC16_POLY = 0x18005; //((1 << 0) | (1 << 2) | (1 << 15) | (1 << 16)); private int[] crc_table = new int[256]; private int[] ac3_frequency_index = { 48000, 44100, 32000, 0 }; private int[] ac3_bitrate_index = { 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 448000, 512000, 576000, 640000, 0,0,0,0,0,0,0,0,0,0,0,0,0 // (fix4) }; private int[][] ac3_size_table = { { 128,160,192,224,256,320,384,448,512,640,768,896,1024,1280,1536,1792,2080,2304,2560 }, { 138,174,208,242,278,348,416,486,556,696,834,974,1114,1392,1670,1950,2228,2506,2786 }, { 192,240,288,336,384,480,576,672,768,960,1152,1344,1536,1920,2304,2688,3120,3456,3840 } }; private String[] bsmod = { ", CM" , ", ME" , ", K:VI" , ", K:HI" , ", K:D" , ", K:C" , ", K:E" , ", K:VO" }; private String[] cmixlev = { "", ", cm -3.0dB", ", cm -4.5dB", ", cm -6.0dB", ", cm -4.5dB" }; private String[] surmixlev = { "", ", sm -3dB", ", sm -6dB", ", sm 0dB", ", sm -6dB" }; private String[] dsurmod = { "" , ", notDS" , ", DS" , "" }; private String[] acmod = { "1+1", "1/0", "2/0", "3/0", "2/1", "3/1", "2/2", "3/2" }; private String[][] lfe = {{ ".0", ".1" },{ "", "lfe" }}; private int[] ac3_channels = { 2, 1, 2, 3, 3, 4, 4, 5 }; /** * parse ac3 Header */ public int parseHeader(byte[] frame, int pos) { if ( (0xFF & frame[pos]) != 0x0B || (0xFF & frame[pos + 1]) != 0x77 ) return -1; ID = 0; Emphasis = 0; Private_bit = 0; Protection_bit = 0 ^ 1; if ((Sampling_frequency = ac3_frequency_index[3 & frame[pos + 4]>>>6]) < 1) return -4; if ((Bitrate = ac3_bitrate_index[0x1F & frame[pos + 4]>>>1]) < 1) return -3; Layer = 7 & frame[pos + 5]; //bsmod Padding_bit = 1 & frame[pos + 4]; Mode = 7 & frame[pos + 6]>>>5; Mode_extension = 0; int mode = (0xFF & frame[pos + 6])<<8 | (0xFF & frame[pos + 7]); int skip=0; if ((Mode & 1) > 0 && Mode != 1) // cmix { Emphasis = 1 + (3 & frame[pos + 6]>>>3); skip++; } if ((Mode & 4) > 0) //surmix { Private_bit = 1 + (3 & frame[pos + 6]>>>(skip > 0 ? 1 : 3)); skip++; } if (Mode == 2) { Mode_extension |= 6 & mode>>>(10 - (2 * skip)); //DS skip++; } if (skip < 4) { Mode_extension |= 1 & mode>>>(12 - (2 * skip)); //lfe Original = 0x1F & mode>>>(7 - (2 * skip)); //dialnorm } Channel = ac3_channels[Mode] + (1 & Mode_extension); Copyright = 0; Time_length = 138240000.0 / Sampling_frequency; Size = (Size_base = ac3_size_table[3 & frame[pos + 4]>>>6][0x1F & frame[pos + 4]>>>1]) + Padding_bit * 2; return 1; } /** * parse next ac3 Header */ public int parseNextHeader(byte[] frame, int pos) { if ( (0xFF & frame[pos]) != 0xB || (0xFF & frame[pos+1]) != 0x77 ) return -1; nID = 0; nEmphasis = 0; nPrivate_bit = 0; nProtection_bit = 0 ^ 1; if ( (nSampling_frequency = ac3_frequency_index[3 & frame[pos+4]>>>6]) < 1) return -4; if ( (nBitrate = ac3_bitrate_index[0x1F & frame[pos+4]>>>1]) < 1) return -3; nLayer = 7 & frame[pos+5]; //bsmod nPadding_bit = 1 & frame[pos+4]; nMode = 7 & frame[pos+6]>>>5; int mode = (0xFF & frame[pos+6])<<8 | (0xFF & frame[pos+7]); int skip=0; if ( (nMode & 1) > 0 && nMode != 1) { //cmix nEmphasis = 1 + (3 & frame[pos+6]>>>3); skip++; } if ( (nMode & 4) > 0) { //surmix nPrivate_bit = 1 + (3 & frame[pos+6]>>>(skip > 0 ? 1 : 3)); skip++; } if ( nMode == 2 ) { //DS mode nMode_extension |= 6 & mode>>>(10 - (2 * skip)); //DS skip++; } if (skip < 4) { nMode_extension |= 1 & mode>>>(12 - (2 * skip)); //lfe nOriginal = 0x1F & mode>>>(7 - (2 * skip)); //dialnorm } nChannel = ac3_channels[nMode] + (1 & nMode_extension); nCopyright = 0; nTime_length = 138240000.0 / nSampling_frequency; nSize = (nSize_base = ac3_size_table[3 & frame[pos+4]>>>6][5 & frame[pos+4]>>>1]) + nPadding_bit * 2; return 1; } /** * compare current & last ac3 header */ public int compareHeader() { if (lLayer != Layer) return 1; else if (lBitrate != Bitrate) return 2; else if (lSampling_frequency != Sampling_frequency) return 3; else if (lMode != Mode) return 4; else if (lMode_extension != Mode_extension) return 5; else if (lOriginal != Original) return 6; else if (lEmphasis != Emphasis) return 7; else return 0; } /** * display last ac3 header */ public String displayHeader() { return ("AC-3" + bsmod[lLayer] + ", " + acmod[lMode] + lfe[1][1 & lMode_extension] + "(" + ac3_channels[lMode] + lfe[0][1 & lMode_extension] + ")" + ", dn -" + lOriginal + "dB" + dsurmod[lMode_extension>>>1] + cmixlev[lEmphasis] + surmixlev[lPrivate_bit] + ", " + lSampling_frequency + "Hz, " + (lBitrate / 1000) + "kbps"); } /** * validate crc16 1 + 2 */ public int validateCRC(byte[] frame, int offset, int frame_size) { // frame_size is BYTE int words = frame_size>>>1; //to word int frame_size_58 = 2* ((words>>>1) + (words>>>3)); //frame_size_58 int crc = -1; //crc1 if ((crc = ac3_crc(frame, 2, frame_size_58, 0)) != 0) return 1; //crc2 if ((crc = ac3_crc(frame, frame_size_58, frame_size, crc)) != 0) return 2; return 0; } /** * */ public byte[] editFrame(byte[] frame, int framesize, int mode) { if (mode == 1) { setChannelFlags(frame); // computeCRC(frame, framesize); } return frame; } /** * 3+2 channels, note the following bits will be dispointed and the frame is corrupted */ private void setChannelFlags(byte[] frame) { frame[6] = (byte)((0xF & frame[6]) | 0xE0); } /** * compute crc16 1 + 2 */ private void computeCRC(byte[] frame, int frame_size) { // frame_size is WORD frame_size >>>= 1; //to word int frame_size_58 = (frame_size>>>1) + (frame_size>>>3); int crc1 = -1; int crc2 = -1; int crc_inv = -1; crc1 = ac3_crc(frame, 4, 2 * frame_size_58, 0); crc_inv = pow_poly((CRC16_POLY >>> 1), (16 * frame_size_58) - 16, CRC16_POLY); //crc1 crc1 = mul_poly(crc_inv, crc1, CRC16_POLY); frame[2] = (byte)(0xFF & (crc1 >> 8)); frame[3] = (byte)(0xFF & crc1); //crc2 crc2 = ac3_crc(frame, 2 * frame_size_58, (2 * frame_size) - 2, 0); frame[(2* frame_size) - 2] = (byte)(0xFF & (crc2 >> 8)); frame[(2* frame_size) - 1] = (byte)(0xFF & crc2); } /** * ac3 crc init table */ private void ac3_crc_init() { for (int n = 0, c, k; n < 256; n++) { c = n << 8; for (k = 0; k < 8; k++) { if ((c & (1 << 15)) != 0) c = ((c << 1) & 0xFFFF) ^ (CRC16_POLY & 0xFFFF); else c = c << 1; } crc_table[n] = c; } } /** * ac3 crc */ private int ac3_crc(byte[] data, int offs, int len, int crc) { int i; for (i = offs; i < len; i++) crc = (crc_table[(0xFF & data[i]) ^ (crc >> 8)] ^ (crc << 8)) & 0xFFFF; return crc; } /** * crc poly */ private int mul_poly(int a, int b, int poly) { int c = 0; while (a > 0) { if ((a & 1) > 0) c ^= b; a = a >>> 1; b = b << 1; if ((b & (1 << 16)) > 0) b ^= poly; } return c; } /** * crc poly */ private int pow_poly(int a, int n, int poly) { int r = 1; while (n > 0) { if ((n & 1) > 0) r = mul_poly(r, a, poly); a = mul_poly(a, a, poly); n >>>= 1; } return r; } /** * ac3 riff header stuff */ // 1536s / 44.1 -> 34.8299ms -> 3134.691 // 1536s / 48 -> 32ms -> 2880 // 1536s / 32 -> 48ms -> 4320 private final int[] armode = { 0, 1, 2, 3, 3, 4, 4, 5 }; private final int[] arsample = { 48000, 44100, 32000, 0 }; private final int[] arbitrate = { 0, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 448000, 512000, 576000, 640000, 0, 0 }; /** * ac3 bitrate constants */ /* 96k,112k,128k,160k,192k,224k,256k,320k,384k,448k,512k,576k,640k * 0=48khz,1=44.1khz,2=32khz 32ms,36ms,48ms 44.1khz padding +2 bytes */ private final int[][] ac3const = { { 288000000,160,192,224,256,320,384,448,512,640,768,896,1024,1280,1536,1792,2080,2304,2560 }, { 313469388,174,208,242,278,348,416,486,556,696,834,974,1114,1392,1670,1950,2228,2506,2786 }, { 432000000,240,288,336,384,480,576,672,768,960,1152,1344,1536,1920,2304,2688,3120,3456,3840 } }; /** * riffdata from ac3 audio * awaiting a frame byte array, only the header is used */ public int[] parseRiffData(byte[] frame) { int[] riffdata = new int[10]; // nSamplesPerSec riffdata[2] = arsample[(0xC0 & frame[4])>>>6]; // nChannels riffdata[4] = armode[(0xE0 & frame[6])>>>5]; // dwHeadBitrate riffdata[6] = arbitrate[(0x3F & frame[4])>>>1]; // nBlockAlign riffdata[8] = ac3const[(0xC0 & frame[4])>>>6][(0x3E & frame[4])>>>1] + (((1 & frame[4])!=0) ? 2 : 0); return riffdata; } }project-x/src/net/sourceforge/dvb/projectx/audio/AudioFormatDTS.java0000600000175000017500000001246210351077136027171 0ustar supermariosupermario/* * @(#)AudioFormatDTS.java - parse Audioheaders, dts * * Copyright (c) 2003-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * The part of audio parsing was derived from the MPEG/Audio * Software Simulation Group's audio codec and ATSC A/52 in a special modified manner. * * * 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 * */ package net.sourceforge.dvb.projectx.audio; import net.sourceforge.dvb.projectx.audio.AudioFormat; public class AudioFormatDTS extends AudioFormat { public AudioFormatDTS() { super(); } /* DTS stuff taken from the VideoLAN project. */ /* Added by R One, 2003/12/18. */ private int[] dts_frequency_index = { 0, 8000, 16000, 32000, 64000, 128000, 11025, 22050, 44100, 88200, 176400, 12000, 24000, 48000, 96000, 192000 }; /** * */ private int[] dts_bitrate_index = { 32000, 56000, 64000, 96000, 112000, 128000, 192000, 224000, 256000, 320000, 384000, 448000, 512000, 576000, 640000, 768000, 896000, 1024000, 1152000, 1280000, 1344000, 1408000, 1411200, 1472000, 1536000, 1920000, 2048000, 3072000, 3840000, 4096000, 0, 0 }; /** * */ private String[] dts_acmod = { "1", "DM", "2/0", "2/0", "2/0", "3/0", "2.1/0", "3.1/0", "2/2", "3/2", "2/2/2", "2/2/2", "3/2/2", "3.1/2/2", "","", "","","","","","","","","","","","","","","","", "","","","","","","","","","","","","","","","", "","","","","","","","","","","","","","","","" }; /** * */ private int[] dts_channels = { 1,2,2,2, 2,3,3,4, 4,5,6,6, 7,8,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 }; /** * parse dts Header */ public int parseHeader(byte[] frame, int pos) { if (frame[pos] != 0x7F || frame[pos + 1] != (byte)0xFE || frame[pos + 2] != (byte)0x80 || frame[pos + 3] != 1 ) return -1; ID = 0; Emphasis = 0; Protection_bit = 0 ^ 1; if ((Sampling_frequency = dts_frequency_index[0xF & (frame[pos + 8]>>>2)]) < 1) return -4; Bitrate = dts_bitrate_index[((3 & frame[pos + 8])<<3) | (7 & (frame[pos + 9]>>>5))]; if (Bitrate < 1) return -3; Layer = 0; Padding_bit = 0; Private_bit = 0; Mode = ((0xF & frame[pos + 7])<<2) | ((0xC0 & frame[pos + 8])>>>6); Mode_extension = 0; Channel = dts_channels[Mode]; Copyright = 0; Original = 0; Size = ((1 & frame[pos + 4])<<6) | ((0xFC & frame[pos + 5])>>>2); Size = (Size + 1)<<5; Time_length = 90000.0 * Size / Sampling_frequency; Size = ((3 & frame[pos + 5])<<12) | ((0xFF & frame[pos + 6])<<4) | ((0xF0 & frame[pos + 7])>>>4); Size++; Size_base = Size; return 1; } /** * parse dts Header */ public int parseNextHeader(byte[] frame, int pos) { if (frame[pos] != 0x7F || frame[pos + 1] != (byte)0xFE || frame[pos + 2] != (byte)0x80 || frame[pos + 3] != 1) return -1; nID = 0; nEmphasis = 0; nProtection_bit = 0 ^ 1; if ((nSampling_frequency = dts_frequency_index[0xF & (frame[pos + 8]>>>2)]) < 1) return -4; nBitrate = dts_bitrate_index[((3 & frame[pos + 8])<<3) | (7 & (frame[pos + 9]>>>5))]; if (nBitrate < 1) return -3; nLayer = 0; nPadding_bit = 0; nPrivate_bit = 0; nMode = ((0xF & frame[pos + 7])<<2) | ((0xC0 & frame[pos + 8])>>>6); nMode_extension = 0; nChannel = dts_channels[nMode]; nCopyright = 0; nOriginal = 0; nSize = ((1 & frame[pos + 4])<<6) | ((0xFC & frame[pos + 5])>>>2); nSize = (nSize + 1)<<5; nTime_length = 90000.0 * nSize / nSampling_frequency; nSize = ((3 & frame[pos + 5])<<12) | ((0xFF & frame[pos + 6])<<4) | ((0xF0 & frame[pos + 7])>>>4); nSize++; nSize_base = nSize; return 1; } /** * verify current & last dts header */ public int compareHeader() { if (lLayer != Layer) return 1; else if (lBitrate != Bitrate) return 2; else if (lSampling_frequency != Sampling_frequency) return 3; else if (lMode != Mode) return 4; else if (lMode_extension != Mode_extension) return 5; else if (lSize != Size) return 6; else return 0; } /** * display last dts header */ public String displayHeader() { return ("DTS, " + dts_acmod[lMode] + "(" + dts_channels[lMode] + "), " + lSampling_frequency + "Hz, " + (lBitrate / 1000.0) + "kbps, " + lSize + "BpF"); } //ROne18122003 }project-x/src/net/sourceforge/dvb/projectx/audio/AudioFormatLPCM.java0000600000175000017500000001005510351077152027264 0ustar supermariosupermario/* * @(#)AudioFormatLPCM.java - parse Audioheaders, lpcm * * Copyright (c) 2003-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * The part of audio parsing was derived from the MPEG/Audio * Software Simulation Group's audio codec and ATSC A/52 in a special modified manner. * * * 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 * */ package net.sourceforge.dvb.projectx.audio; import net.sourceforge.dvb.projectx.audio.AudioFormat; public class AudioFormatLPCM extends AudioFormat { public AudioFormatLPCM() { super(); } private int lpcm_frequency_index[] = { 48000, 96000 }; private int lpcm_bps_index[] = { 16, 20, 24, -1 }; /** * */ public int parseHeader(byte[] frame_header, int pos) { INTEL=true; // force intel/wav output ID = 0xFF & frame_header[pos]; // no of frameheaders Padding_bit = (0xFF & frame_header[pos + 1])<<8 | (0xFF & frame_header[pos + 2]); // first_access_unit_pointer Layer = 0xFF & frame_header[pos + 3]; // audio_frame_number Protection_bit = 0^1; Private_bit = 0; Copyright = 0; Original = 0; Size_base = 0; Size = lpcm_bps_index[(3 & frame_header[pos + 4]>>>6)]; //bits per sample Sampling_frequency = lpcm_frequency_index[(1 & frame_header[pos + 4]>>>4)]; // samplerate Channel = 1 + (7 & frame_header[pos + 4]); // channels Emphasis = 0xFF & frame_header[pos + 5]; // dynamic_range Mode = (Channel * Size) / 8; // block_align, bytes per sample Bitrate = Channel * Sampling_frequency * Size; // bitrate per second if (Size < 1) return -1; Time_length = 90000.0 / Sampling_frequency; // 1 frame = 150 * timelength return 0; } /** * */ public int parseNextHeader(byte[] frame_header, int pos) { INTEL=true; // force intel/wav output nID = 0xFF & frame_header[pos]; // no of frameheaders nPadding_bit = (0xFF & frame_header[pos + 1])<<8 | (0xFF & frame_header[pos + 2]); // first_access_unit_pointer nLayer = 0xFF & frame_header[pos + 3]; // audio_frame_number nProtection_bit = 0^1; nPrivate_bit = 0; nCopyright = 0; nOriginal = 0; nSize_base = 0; nSize = lpcm_bps_index[(3 & frame_header[pos + 4]>>>6)]; //bits per sample nSampling_frequency = lpcm_frequency_index[(1 & frame_header[pos + 4]>>>4)]; // samplerate nChannel = 1 + (7 & frame_header[pos + 4]); // channels nEmphasis = 0xFF & frame_header[pos + 5]; // dynamic_range nMode = (nChannel * nSize) / 8; // block_align, bytes per sample nBitrate = nChannel * nSampling_frequency * nSize; // bitrate per second if (nSize < 1) return -1; nTime_length = 90000.0 / nSampling_frequency; // 1 frame = 150 * timelength return 0; } /** * */ public String displayHeader() { return ("LPCM, DR-" + lEmphasis + ", " + lChannel + "-ch, " + lSampling_frequency + "Hz, " + lSize + "bit, " + (lBitrate / 1000.0) + "kbps"); } /** * */ public int compareHeader() { if (lChannel != Channel) return 1; else if (lSampling_frequency != Sampling_frequency) return 2; else if (lSize != Size) return 3; else if (lEmphasis != Emphasis) return 4; else return 0; } }project-x/src/net/sourceforge/dvb/projectx/audio/AudioFormatMPA.java0000600000175000017500000005572410407315154027161 0ustar supermariosupermario/* * @(#)AudioFormatMPA.java - parse Audioheaders, mpa, incl. RDS * * Copyright (c) 2003-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * The part of audio parsing was derived from the MPEG/Audio * Software Simulation Group's audio codec and ATSC A/52 in a special modified manner. * * * 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 * */ package net.sourceforge.dvb.projectx.audio; import java.util.Arrays; import java.util.ArrayList; import java.io.IOException; import java.io.RandomAccessFile; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.BufferedOutputStream; import net.sourceforge.dvb.projectx.audio.MpaDecoder; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.audio.AudioFormat; public class AudioFormatMPA extends AudioFormat { private String instanced_time = ""; public AudioFormatMPA() { super(); instanced_time = String.valueOf(System.currentTimeMillis()); } private int[][][] bitrate_index = {{ {-1,8000,16000,24000,32000,40000,48000,56000,64000, 80000,96000,112000,128000,144000,160000,0 }, //MPG-2, L3 {-1,8000,16000,24000,32000,40000,48000,56000,64000, 80000,96000,112000,128000,144000,160000,0 }, //MPG-2, L2 {-1,32000,48000,56000,64000,80000,96000,112000,128000, 144000,160000,176000,192000,224000,256000,0 } //MPG-2, L1 },{ {-1,32000,40000,48000,56000,64000,80000,96000, 112000,128000,160000,192000,224000,256000,320000, 0 }, //MPG-1, L3 {-1,32000,48000,56000,64000,80000,96000,112000, 128000,160000,192000,224000,256000,320000,384000, 0 }, //MPG-1, L2 {-1,32000,64000,96000,128000,160000,192000,224000, 256000,288000,320000,352000,384000,416000,448000,0 } //MPG-1, L1 },{ {-1, 6000, 8000, 10000, 12000, 16000, 20000, 24000, //MPG-2.5, L3?? 28000, 320000, 40000, 48000, 56000, 64000, 80000, 0 }, {-1, 6000, 8000, 10000, 12000, 16000, 20000, 24000, //MPG-2.5, L2 28000, 320000, 40000, 48000, 56000, 64000, 80000, 0 }, {-1, 8000, 12000, 16000, 20000, 24000, 32000, 40000, //MPG-2.5, L1 48000, 560000, 64000, 80000, 96000, 112000, 128000, 0 } }}; private int frequency_index[][] = { { 22050,24000,16000,0 }, //MPG2 - 22.05,24,16khz { 44100,48000,32000,0 }, //MPG1 - 44.1 ,48,32khz { 11025,12000,8000,0 } //MPG2.5 - 11.025,12,8khz }; private double time_index[] = { 0.0,103680000.0,103680000.0,34560000.0 }; //L3,L2,L1 * 90 private String[] dID = { "MPEG-2", "MPEG-1", "MPEG-2.5" }; private String[] dLayer = { "n.a.", "Layer3", "Layer2", "Layer1" }; private String[] dCRC = { "noCRC", "CRC" }; private String[] dMode = { "stereo", "jstereo", "dual", "mono" }; /** * parse mpa Header */ public int parseHeader(byte[] frame, int pos) { int sblimit = 32; if ( (0xFF & frame[pos]) != 0xFF || (0xF0 & frame[pos + 1]) != 0xF0 ) return -1; ID = 1 & frame[pos + 1]>>>3; Emphasis = 3 & frame[pos + 3]; if (ID == 1 && Emphasis == 2) ID = 2; if ( (Layer = 3 & frame[pos + 1]>>>1) < 1) return -2; Protection_bit = (1 & frame[pos + 1]) ^ 1; if ( (Bitrate = bitrate_index[ID][Layer - 1][0xF & frame[pos + 2]>>>4]) < 1) return -3; if ( (Sampling_frequency = frequency_index[ID][3 & frame[pos + 2]>>>2]) == 0) return -4; Padding_bit = 1 & frame[pos + 2]>>>1; Private_bit = 1 & frame[pos + 2]; Mode = 3 & frame[pos + 3]>>>6; Mode_extension = 3 & frame[pos + 3]>>>4; if (Mode == 0) Mode_extension = 0; Bound = Mode == 1 ? ((Mode_extension + 1) << 2) : sblimit; Channel = Mode == 3 ? 1 : 2; Copyright = 1 & frame[pos + 3]>>>3; Original = 1 & frame[pos + 3]>>>2; Time_length = time_index[Layer] / Sampling_frequency; if (ID == 1 && Layer == 2) // MPEG-1, L2 restrictions { if (Bitrate / Channel < 32000) return -5; /* unsupported bitrate */ if (Bitrate / Channel > 192000) return -6; /* unsupported bitrate */ if (Bitrate / Channel < 56000) { if(Sampling_frequency == 32000) Sblimit = 12; else Sblimit = 8; } else if (Bitrate / Channel < 96000) Sblimit = 27; else { if (Sampling_frequency == 48000) Sblimit = 27; else Sblimit = 30; } if (Bound > Sblimit) Bound = Sblimit; } else if (Layer == 2) // MPEG-2 { Sblimit = 30; } if (Layer < 3) { if (Bound > Sblimit) Bound = Sblimit; Size = (Size_base = 144 * Bitrate / Sampling_frequency) + Padding_bit; } else { Sblimit = 32; Size = (Size_base = (12 * Bitrate / Sampling_frequency) * 4) + (4 * Padding_bit); } return (Layer < 3 ? 1 : 2); } /** * parse next mpa Header */ public int parseNextHeader(byte[] frame, int pos) { if ( (0xFF&frame[pos])!=0xFF || (0xF0&frame[pos+1])!=0xF0 ) return -1; nID = 1&frame[pos+1]>>>3; nEmphasis = 3&frame[pos+3]; if (nID==1 && nEmphasis==2) nID = 2; if ( (nLayer = 3&frame[pos+1]>>>1) < 1) return -2; nProtection_bit = (1&frame[pos+1]) ^ 1; if ( (nBitrate = bitrate_index[nID][nLayer-1][0xF&frame[pos+2]>>>4]) < 1) return -3; if ( (nSampling_frequency = frequency_index[nID][3&frame[pos+2]>>>2]) == 0) return -4; nPadding_bit = 1&frame[pos+2]>>>1; nPrivate_bit = 1&frame[pos+2]; nMode = 3&frame[pos+3]>>>6; nMode_extension = 3&frame[pos+3]>>>4; if (nMode==0) nMode_extension=0; nChannel = (nMode==3) ? 1: 2; nCopyright = 1&frame[pos+3]>>>3; nOriginal = 1&frame[pos+3]>>>2; nTime_length = time_index[nLayer]/nSampling_frequency; if (nID==1 && nLayer==2) { // MPEG-1,L2 restrictions if(nBitrate/Channel < 32000) return -5; /* unsupported bitrate */ if(nBitrate/Channel > 192000) return -6; /* unsupported bitrate */ } if (nLayer<3) { nSize = (nSize_base = 144*nBitrate/nSampling_frequency) + nPadding_bit; return 1; } else { nSize = (nSize_base = (12*nBitrate/nSampling_frequency)*4) + (4*nPadding_bit); return 2; } } /** * compare current & last mpa header */ public int compareHeader() { if (lID != ID) return 1; else if (lLayer != Layer) return 2; else if (lBitrate != Bitrate) return 3; else if (lSampling_frequency != Sampling_frequency) return 4; else if (lProtection_bit != Protection_bit) return 5; else if (lMode != Mode) { if (Mode + lMode < 2) return 6; else return 7; } else return 0; } /** * display last mpa header */ public String displayHeader() { return ("" + dID[lID] + ", " + dLayer[lLayer] + ", " + lSampling_frequency + "Hz, " + dMode[lMode] + ", "+ (lBitrate/1000) + "kbps, " + dCRC[lProtection_bit]); } /** * remove CRC from mpa **/ public void removeCRC(byte[] frame) { if (Layer < 2) return; removePrivateBit(frame); if ((frame[1] & 1) == 1) return; System.arraycopy(frame, 6, frame, 4, frame.length - 6); Arrays.fill(frame, frame.length - 2, frame.length, (byte) 0); frame[1] |= 1; Protection_bit = 1; } /** * remove private Bit from mpa **/ private void removePrivateBit(byte[] frame) { if ( (frame[2] & 1) == 0) return; frame[2] &= ~1; Private_bit = 0; } /** * */ public int validateCRC(byte[] _data, int offs, int len) { if (Layer < 2 || Protection_bit==0) return 0; int crc_val = (0xFF & _data[4])<<8 | (0xFF & _data[5]); byte[] data = new byte[_data.length]; System.arraycopy(_data, 0, data, 0, 4); System.arraycopy(_data, 6, data, 4, _data.length - 6); int ch, sb, offset = 2, nr_bits = 16, BitPos[] = { 32 }; if (Layer==3) // BAL only, of 32 subbands { for( sb=0; sb 20) { table_nbal = MpaDecoder.table_b2ab_nbal; table_alloc = MpaDecoder.table_b2ab; } else { table_nbal = MpaDecoder.table_b2cd_nbal; table_alloc = MpaDecoder.table_b2cd; } } else { table_nbal = MpaDecoder.table_MPG2_nbal; table_alloc = MpaDecoder.table_MPG2; } for( sb=0; sb0) nr_bits += 2; } int[] g = { 1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1 }; // x^16 + x^15 + x^2 + 1 int[] shift_reg = new int[16]; int crc = 0; Arrays.fill(shift_reg, 1); for (int bit_count=0, bit_in_byte=0, data_bit, j = data.length; bit_count < nr_bits; bit_count++) { if (offset >= j) break; data_bit = (data[offset] & 0x80>>>(bit_in_byte++)) != 0 ? 1 : 0; if ((bit_in_byte &= 7) == 0) offset++; data_bit ^= shift_reg[15]; for (int i = 15; i > 0; i--) shift_reg[i] = g[i]==1 ? (shift_reg[i-1] ^ data_bit) : shift_reg[i-1]; shift_reg[0] = data_bit; } for (int i=0; i<16; i++) crc = ((crc << 1) | (shift_reg[15-i])); if (crc != crc_val) return 1; else return 0; } /** * */ private int getBits(byte buf[], int BitPos[], int N) { int Pos, Val; Pos = BitPos[0]>>>3; Val = (0xFF & buf[Pos])<<24 | (0xFF & buf[Pos+1])<<16 | (0xFF & buf[Pos+2])<<8 | (0xFF & buf[Pos+3]); Val <<= BitPos[0] & 7; Val >>>= 32-N; BitPos[0] += N; return Val; } /** * mpa riff header stuff */ private final int[] rpadding = { 0, 1, 1, 4 }; private final int[] rlayer = { 0, 4, 2, 1 }; private final int[][] rsample = { { 22050, 24000, 16000, 0 }, { 44100, 48000, 32000, 0 } }; private final int[] rmode = { 1, 2, 4, 8 }; private final int[] rchnl = { 2, 2, 2, 1 }; private final int[] rmext = { 1, 2, 4, 8 }; private final int[] remph = { 1, 2, 3, 4 }; private final int[][][] rbitrate = { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,8000,16000,24000,32000,40000,48000,56000,64000,80000,96000,112000,128000,144000,160000,0 }, { 0,8000,16000,24000,32000,40000,48000,56000,64000,80000,96000,112000,128000,144000,160000,0 }, { 0,32000,48000,56000,64000,80000,96000,112000,128000,144000,160000,176000,192000,224000,256000,0 } }, { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,32000,40000,48000,56000,64000,80000,96000,112000,128000,160000,192000,224000,256000,320000,0 }, { 0,32000,48000,56000,64000,80000,96000,112000,128000,160000,192000,224000,256000,320000,384000,0 }, { 0,32000,64000,96000,128000,160000,192000,224000,256000,288000,320000,352000,384000,416000,448000,0 } } }; /** * riffdata from mpeg audio * awaiting a frame byte array, only the header is used */ public int[] parseRiffData(byte[] rh) { int[] riffdata = new int[10]; // fwHeadFlags riffdata[0] = (8 & rh[1])<<1 | (1 & rh[1])<<3 | (4 & rh[3]) | (8 & rh[3])>>>2 | (1 & rh[2]); // fwHeadLayer riffdata[1] = rlayer[(6 & rh[1])>>>1]; // nSamplesPerSec riffdata[2] = rsample[(8 & rh[1])>>>3][(0xC & rh[2])>>>2]; // fwHeadMode riffdata[3] = rmode[(0xC0 & rh[3])>>>6]; // nChannels riffdata[4] = rchnl[(0xC0 & rh[3])>>>6]; // fwHeadModeExt riffdata[5] = rmext[(0x30 & rh[3])>>>4]; // dwHeadBitrate riffdata[6] = rbitrate[(8 & rh[1])>>>3][(6 & rh[1])>>>1][(0xF0 & rh[2])>>>4]; // wHeadEmphasis riffdata[7] = remph[(3 & rh[3])]; // nBlockAlign riffdata[8] = riffdata[1] == 1 ? 4 * (12 * riffdata[6] / riffdata[2]) : 144 * riffdata[6] / riffdata[2]; riffdata[8] /= ( (8 & rh[1]) == 0 && (6 & rh[1]) == 1 ) ? 2 : 1 ; if ((2 & rh[2]) != 0) riffdata[8] += rpadding[(6 & rh[1])>>>1]; return riffdata; } /** * RDS-Test, cant find any similars to RDS, I-RDS, RBDS i.e. group/block coding * PI-Code is missing, WDR2 shall have Dx92 * */ ArrayList _list = new ArrayList(); ByteArrayOutputStream bo = new ByteArrayOutputStream(); private boolean DecodeRDS = false; private boolean Debug = false; private boolean hasRawData = false; private String[] rds_values = new String[7]; private final String[] pty_list = { "undefined", "News", "Current Affairs", "Information", "Sport", "Education", "Drama", "Culture", "Science", "Varied", "Pop Music", "Rock Music", "Easy Listening", "Light Classical", "Seriuos Classical", "Other Music", "Weather", "Finance", "Children", "Social Affairs", "Religion", "Phone In", "Travel", "Leisure", "Jazz Music", "Country Music", "National Music", "Oldies Music", "Folk Music", "Documentary", "Alarm Test", "Alarm" }; /** * RDS-char map table , unicode */ private final short[] chars = { 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x0020, 0x00e1, 0x00e0, 0x00e9, 0x00e8, 0x00ed, 0x00ec, 0x00f3, 0x00f2, 0x00fa, 0x00f9, 0x00d1, 0x00c7, 0x015e, 0x00df, 0x0130, 0x0132, 0x00e2, 0x00e4, 0x00ea, 0x00eb, 0x00ee, 0x00ef, 0x00f4, 0x00f6, 0x00fb, 0x00fc, 0x00f1, 0x00e7, 0x015f, 0x011f, 0x0131, 0x0133 }; /** * */ public void setAncillaryDataDecoder(boolean b, boolean b1) { DecodeRDS = b; Debug = b1; Arrays.fill(rds_values, null); } /** * */ public void decodeAncillaryData(byte[] frame) { if (!DecodeRDS) return; int neg_offs = Size - 1; if (frame[neg_offs] != (byte)0xFD) { neg_offs -= 2; if (frame[neg_offs] != (byte)0xFD) return; } int len = 0xFF & frame[neg_offs - 1]; for (int i = neg_offs - 2, val; i > neg_offs - 2 - len; i--) { val = 0xFF & frame[i]; _list.add(String.valueOf(val)); } decodeChunk(_list); } /** * */ private void decodeChunk(ArrayList list) { int index = list.indexOf("254"); //0xfe, start if (index < 0) { list.clear(); return; } while (index > 0) { list.remove(0); index--; } int eom_index = list.indexOf("255"); //0xff, end if (eom_index < 0) return; else if (eom_index < 5) //fe xx yy zz ll aa { list.remove(0); return; } if (Debug) { String str = ""; String str_1 = ""; for (int i = 0; i <= eom_index; i++) { str_1 = Integer.toHexString(Integer.parseInt(list.get(i).toString())).toUpperCase(); str += " " + (str_1.length() < 2 ? "0" + str_1 : str_1); } System.out.println("RDS:" + str); } int chunk_length = Integer.parseInt(list.get(4).toString()); int real_length = -1; int type = -1; // fill bytearray, excluding crc + EOM, correct special bytes for (int i = 0, j = 0, k = 0, value; i <= eom_index; i++, list.remove(0)) { value = Integer.parseInt(list.get(0).toString()); if (i < 5 || value > 0xFD) continue; if (i == 5) { type = value; continue; } // coding of 0xFD,FE,FF if (value == 0xFD) { j = 1; continue; } if (j == 1) { value += 0xFD; j = 0; } if (k < chunk_length - 1) bo.write(value); real_length = k; k++; } // wrong length if (real_length != chunk_length) type = -1; String str; switch (type) { case 0xDA: //Video-programminfos getRawData(bo.toByteArray()); break; case 0x0A: //RT compareMsg(getRT(bo.toByteArray()), 0); break; case 0x01: //PI compareMsg(getPI(bo.toByteArray()), 1); break; case 0x02: //PS program service name compareMsg(getPS(bo.toByteArray()), 2); break; case 0x03: //TA compareMsg(getTP(bo.toByteArray()), 3); break; case 0x05: //MS compareMsg(getMS(bo.toByteArray()), 4); break; case 0x07: //PTY compareMsg(getPTY(bo.toByteArray()), 5); break; case 0x0D: //RTC compareMsg(getRTC(bo.toByteArray()), 6); break; case 0x30: //TMC case 0x40: //ODA SMC case 0x42: //ODA free case 0x46: //ODA data case 0x4A: //CT case 0x06: //PIN break; } bo.reset(); } /** * */ private void getRawData(byte[] array) { try { int index = 0; int len = 0xFF & array[index]; int end = array.length; index += 5; int counter = 0xFF & array[index]; index += 3; int bound = 0xFF & array[index]; index++; try { if (!hasRawData) { hasRawData = true; Common.setMessage("-> exporting RDS data type 0xDA to '" + instanced_time + "_rawdata_0xDA_RDS'"); } BufferedOutputStream rawdata = new BufferedOutputStream(new FileOutputStream(Common.getCollection().getOutputNameParent(instanced_time + "_rawdata@RDS"), true)); for (int i = index, k; i < end; i++) { k = (0xFF & array[i]); rawdata.write(k); } rawdata.flush(); rawdata.close(); } catch (IOException ie) { Common.setMessage("!> error rds1"); } } catch (ArrayIndexOutOfBoundsException ae) { Common.setMessage("!> error rds2"); } } /** * */ private void compareMsg(String str, int index) { if (str == null || str.equals(rds_values[index])) return; rds_values[index] = str; Common.setMessage(str); } /** * */ private String getRT(byte[] array) { try { int index = 0; int dsn = 0xFF & array[index]; int psn = 0xFF & array[index + 1]; index += 2; int len = 0xFF & array[index]; index++; int change = 0xFF & array[index]; index++; String str = getString(array, index, len - 1); return ("-> RT (" + Integer.toHexString(change).toUpperCase() + "): '" + str.trim() + "'"); } catch (ArrayIndexOutOfBoundsException ae) {} return null; } /** * */ private String getPS(byte[] array) { try { int index = 0; int dsn = 0xFF & array[index]; int psn = 0xFF & array[index + 1]; index += 2; int len = array.length >= index + 8 ? 8 : array.length - index; String str = getString(array, index, len); return ("-> PS (" + psn + "): '" + str.trim() + "'"); } catch (ArrayIndexOutOfBoundsException ae) {} return null; } /** * */ private String getPI(byte[] array) { try { int index = 0; int dsn = 0xFF & array[index]; int psn = 0xFF & array[index + 1]; index += 2; int pi_code = (0xFF & array[index])<<8 | (0xFF & array[index + 1]); return ("-> PI (" + psn + "): 0x" + Integer.toHexString(pi_code).toUpperCase()); } catch (ArrayIndexOutOfBoundsException ae) {} return null; } /** * */ private String getTP(byte[] array) { try { int index = 0; int dsn = 0xFF & array[index]; int psn = 0xFF & array[index + 1]; index += 2; boolean tp = (2 & array[index]) != 0; boolean ta = (1 & array[index]) != 0; return ("-> TP/TA (" + psn + "): " + (tp ? "TP" : "no TP") + " / " + (ta ? "TA on air" : "no TA")); } catch (ArrayIndexOutOfBoundsException ae) {} return null; } /** * */ private String getMS(byte[] array) { try { int index = 0; int dsn = 0xFF & array[index]; int psn = 0xFF & array[index + 1]; index += 2; boolean speech = (1 & array[index]) != 0; return ("-> MS (" + psn + "): " + (speech ? "Speech" : "Music")); } catch (ArrayIndexOutOfBoundsException ae) {} return null; } /** * */ private String getPTY(byte[] array) { try { int index = 0; int dsn = 0xFF & array[index]; int psn = 0xFF & array[index + 1]; index += 2; int pty = 0x1F & array[index]; return ("-> PTY (" + psn + "): " + pty_list[pty]); } catch (ArrayIndexOutOfBoundsException ae) {} return null; } /** * */ private String getRTC(byte[] array) { try { int index = 0; String year = "20" + Common.adaptString(Integer.toHexString(0x7F & array[index]), 2); String month = Common.adaptString(String.valueOf(0xF & array[index + 1]), 2); String date = Common.adaptString(String.valueOf(0x1F & array[index + 2]), 2); String hour = Common.adaptString(String.valueOf(0x1F & array[index + 3]), 2); String min = Common.adaptString(String.valueOf(0x3F & array[index + 4]), 2); String sec = Common.adaptString(String.valueOf(0x3F & array[index + 5]), 2); String censec= Common.adaptString(String.valueOf(0x7F & array[index + 6]), 2); int ltoffs = 0xFF & array[index + 7]; String loctime = ltoffs != 0xFF ? (((0x20 & ltoffs) != 0) ? "-" + ((0x1F & ltoffs) / 2) : "+" + ((0x1F & ltoffs) / 2)) : "\u00B1" + "0"; return ("-> RTC (" + loctime + "h): " + year + "." + month + "." + date + " " + hour + ":" + min + ":" + sec + "." + censec); } catch (ArrayIndexOutOfBoundsException ae) {} return null; } /** * */ private String getString(byte[] array, int offset, int length) { String str = ""; try { for (int i = offset, val, j = offset + length; i < j; i++) { val = 0xFF & array[i]; str += (val > 0x9F || val < 0x20) ? (char)chars[0] : (char)chars[val - 0x20]; } } catch (ArrayIndexOutOfBoundsException ae) {} return str; } }project-x/src/net/sourceforge/dvb/projectx/audio/AudioFormatWAV.java0000600000175000017500000001067310351077224027174 0ustar supermariosupermario/* * @(#)AudioFormatWAV.java - parse Audioheaders, wav / riff * * Copyright (c) 2003-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * The part of audio parsing was derived from the MPEG/Audio * Software Simulation Group's audio codec and ATSC A/52 in a special modified manner. * * * 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 * */ package net.sourceforge.dvb.projectx.audio; import java.util.Arrays; import net.sourceforge.dvb.projectx.audio.AudioFormat; public class AudioFormatWAV extends AudioFormat { public AudioFormatWAV() { super(); } private final int WaveChunks[] = { 0x57415645, //0 'WAVE' 0x63756520, //1 'cue ' 0x64617461, //2 'data' 0x66616374, //3 'fact' 0x666D7420, //4 'fmt ' 0x696E7374, //5 'inst' 0x6C61626C, //6 'labl' 0x6C697374, //7 'list' 0x6C747874, //8 'ltxt' 0x6E6F7465, //9 'note' 0x706C7374, //10 'plst' 0x736D706C //11 'smpl' }; /** * parse RIFF_WAVE Header */ public int parseHeader(byte[] frame, int pos) { INTEL = false; if (frame[pos] != 0x52 || frame[pos + 1] != 0x49 || frame[pos + 2] != 0x46 ) return -1; if (frame[pos + 3] == 0x46) INTEL=true; else if (frame[pos + 3] != 0x58) return -2; ID = INTEL ? 0 : 1; Emphasis = 0; Protection_bit = 0 ^ 1; Arrays.sort(WaveChunks); if (littleEndian(frame, pos + 8, 4, false) != WaveChunks[0]) return -3; int chunk = 0; int chunksize = 0; for (int a = pos + 12; a < frame.length - 4; a++) { if (Arrays.binarySearch(WaveChunks, (chunk = littleEndian(frame, a, 4, false))) < 0) continue; if (chunk == WaveChunks[4]) { //fmt chunk read info datas chunksize = littleEndian(frame, a + 4, 4, INTEL); Layer = littleEndian(frame, a + 8, 2, INTEL); // Compression type (1=PCM) Channel = littleEndian(frame, a + 10, 2, INTEL); // channels Sampling_frequency = littleEndian(frame, a + 12, 4, INTEL); // samplerate Bitrate = littleEndian(frame, a + 16, 4, INTEL) * 8; // avg bits per second Mode = littleEndian(frame, a + 20, 2, INTEL); // block align, bytes per sample Size = littleEndian(frame, a + 22, 2, INTEL); //bits per sample //extrabits not of interest } else if (chunk == WaveChunks[2]) { //data chunk, sample data chunksize = littleEndian(frame, a + 4, 4, INTEL); Size_base = chunksize; // length of whole sample data Emphasis = a + 8; // real start of whole sample data } else chunksize = littleEndian(frame, a + 4, 4, INTEL); a += chunksize + 3; } //PTS low+high may exists in 'fact' of MPEG1audio ! if (Bitrate < 1 || Sampling_frequency < 1 || Channel < 1) return -4; Padding_bit = 0; Private_bit = 0; Copyright = 0; Original = 0; Time_length = 90000.0 / Sampling_frequency; switch (Layer) { case 1: Mode_extension = 1; return 1; case 0x50: Mode_extension = 2; return 0; case 0x55: Mode_extension = 3; return 0; case 0x2000: Mode_extension = 4; return 0; default: Mode_extension = 0; } return 0; } private final String[] LSB_mode = { "F", "X" }; private final String[] compression = { "", "PCM", "MPEG", "MPEG-L3", "AC3" }; /** * display last wav header */ public String displayHeader() { return ("RIF" + LSB_mode[lID] + ", " + (lMode_extension > 0 ? compression[lMode_extension] : "tag 0x" + Integer.toHexString(Layer)) + ", " + lChannel + "-ch, " + lSampling_frequency + "Hz, " + lSize + "bit, " + (lBitrate/1000.0) + "kbps"); } }project-x/src/net/sourceforge/dvb/projectx/audio/MpaConverter.java0000600000175000017500000005353110351077304027010 0ustar supermariosupermario/* * @(#)MpaConverter.java - converter M1L2,48khz losless * * Copyright (c) 2002-2005 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * The part of audio parsing was derived from the MPEG/Audio * Software Simulation Group's audio codec in a special modified manner. * * * 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 * */ /* * rewritten Oct 2003 by dvb.matt */ package net.sourceforge.dvb.projectx.audio; import java.util.Arrays; import net.sourceforge.dvb.projectx.audio.AudioFormat; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.parser.CommonParsing; public class MpaConverter extends Object { //mpeg-1 27 subbands private final short alloc27[][] = { { 0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17 }, { 0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17 }, { 0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17 }, { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17 }, { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17 }, { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17 }, { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17 }, { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17 }, { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17 }, { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17 }, { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17 }, { 0,1,2,3,4,5,6,17 }, { 0,1,2,3,4,5,6,17 }, { 0,1,2,3,4,5,6,17 }, { 0,1,2,3,4,5,6,17 }, { 0,1,2,3,4,5,6,17 }, { 0,1,2,3,4,5,6,17 }, { 0,1,2,3,4,5,6,17 }, { 0,1,2,3,4,5,6,17 }, { 0,1,2,3,4,5,6,17 }, { 0,1,2,3,4,5,6,17 }, { 0,1,2,3,4,5,6,17 }, { 0,1,2,3,4,5,6,17 }, { 0,1,2,17 }, { 0,1,2,17 }, { 0,1,2,17 }, { 0,1,2,17 } }; private final short bal27mp1[] = { 4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2 }; private final short getbits[] = { 0,5,7,3,10,4,5,6,7,8,9,10,11,12,13,14,15,16 }; private final short grouping[] = { 0,3,5,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0 }; private final int MPA_48M1L2[] = { 0,768,1152,1344,1536,1920,2304,2688,3072,3840,4608,5376,6144,7680,9216,16384 }; private final int STEREO = 0; private final int JSTEREO = 1; private final int DUAL = 2; private final int SINGLE = 3; private final int SINGLE_TO_3DSTEREO= 1; private final int SINGLE_TO_STEREO = 2; private final int SINGLE_TO_JSTEREO = 3; private final int SPLIT_INTO_SINGLE = 4; private boolean[] framebuffer; private int maxBitSize = 0; private short[] Bal = new short[0]; private short[][] Allocation; private int[] Sizes; private int[] BRindex = new int[3]; private int Restart = 0; private int error_flag = 0; private AudioFormat Audio; //init public MpaConverter() { Audio = new AudioFormat(CommonParsing.MPEG_AUDIO); Sizes = MPA_48M1L2; Arrays.sort(Sizes); maxBitSize = Sizes[14]; Bal = bal27mp1; Allocation = alloc27; framebuffer = new boolean[maxBitSize]; //max=1152bytes=9216bits } /** * */ public void resetBuffer() { Arrays.fill(framebuffer, false); } /** * modify mpegaudio frame 48khz 56..384kbps M1L2 */ public byte[][] modifyframe(byte[] AudioFrame, int MpaConversionMode) { byte newAudioFrames[][] = new byte[2][AudioFrame.length]; for (int i = 0; i < 3; i++) //0-s, 1-l, 2-r BRindex[i] = (int)(0xF & CommonParsing.getAudioProcessingFlags()>>>(4 + (i<<2))); Restart = 0; error_flag = 0; //secure, but most was already done by X.java if (Audio.parseHeader(AudioFrame, 0) != 1 || Audio.getID() != 1 || Audio.getLayer() != 2 || Audio.getSamplingFrequency() != 48000 || Audio.getBitrate() < 56000 || (Audio.getMode() == SINGLE && Audio.getBitrate() > 192000) || (Audio.getMode() != SINGLE && Audio.getBitrate() < 112000)) { System.arraycopy(AudioFrame,0,newAudioFrames[0],0,AudioFrame.length); System.arraycopy(AudioFrame,0,newAudioFrames[1],0,AudioFrame.length); // copy frame Common.setMessage(Resource.getString("audio.msg.convert.disabled", "" + (CommonParsing.getAudioProcessingFlags()>>>18))); CommonParsing.setAudioProcessingFlags(CommonParsing.getAudioProcessingFlags() | 0x1000CL); return newAudioFrames; } //explicit call necessary, if crc removing is disabled in presettings Audio.removeCRC(AudioFrame); switch(MpaConversionMode) { case SINGLE_TO_3DSTEREO: //single channel to 3D case SINGLE_TO_STEREO: //single channel to stereo case SINGLE_TO_JSTEREO: //single channel to jstereo if (Audio.getChannel() == 1) newAudioFrames = createByteArrays(makeTwoChannel(createBitArray(AudioFrame), MpaConversionMode, 0)); else newAudioFrames = adaptSourceFrame(AudioFrame, newAudioFrames, MpaConversionMode); //check to pass BR break; case SPLIT_INTO_SINGLE: //dual-stereo-jointstereo to 2 x mono if (Audio.getChannel() == 2) newAudioFrames = createByteArrays(splitTwoChannel(createBitArray(AudioFrame),MpaConversionMode)); else newAudioFrames = adaptSourceFrame(AudioFrame, newAudioFrames, MpaConversionMode); //check to pass BR } CommonParsing.setAudioProcessingFlags(CommonParsing.getAudioProcessingFlags() & ~0xFFFCL); for (int i = 0; i < 3; i++) //0-s, 1-l, 2-r CommonParsing.setAudioProcessingFlags(CommonParsing.getAudioProcessingFlags() | BRindex[i]<<(4 + (i<<2))); CommonParsing.setAudioProcessingFlags(CommonParsing.getAudioProcessingFlags() | Restart<<2); if (error_flag > 0) Common.setMessage(Resource.getString("audio.msg.convert.error", String.valueOf(error_flag), String.valueOf(CommonParsing.getAudioProcessingFlags()>>>18))); return newAudioFrames; } private void setError(int error) { error_flag |= error; } //check to pass BR private byte[][] adaptSourceFrame(byte[] AudioFrame, byte[][] input, int MpaConversionMode) { System.arraycopy(AudioFrame, 0, input[0], 0, AudioFrame.length); System.arraycopy(AudioFrame, 0, input[1], 0, AudioFrame.length); // copy frame int[] size = new int[2]; size[1] = size[0] = (0xF0 & AudioFrame[2])>>>4; if (MpaConversionMode != SPLIT_INTO_SINGLE) { if (size[0] == BRindex[0]) //same size return input; else if (size[0] > BRindex[0]) { //restart with new size if (BRindex[0] != 0) Restart |= 3; BRindex[0] = size[0]; return input; } } else { if (size[0] == BRindex[1] && size[1] == BRindex[2]) //same size return input; else { //restart with new size if (size[0] > BRindex[1]) { //fill to size L if (BRindex[1] != 0) Restart |= 1; BRindex[1] = size[0]; } if (size[1] > BRindex[2]) { //fill to size R if (BRindex[2] != 0) Restart |= 2; BRindex[2] = size[1]; } if (Restart > 0) return input; } } byte[][] output = new byte[2][0]; for (int ch=0; ch<2; ch++) { output[ch] = new byte[Sizes[BRindex[ch + (MpaConversionMode>>>2)]]>>>3]; System.arraycopy(input[ch], 0, output[ch], 0, input[ch].length); output[ch][2] &= (byte)~0xF0; output[ch][2] |= (byte)BRindex[ch + (MpaConversionMode>>>2)]<<4; if (MpaConversionMode != SPLIT_INTO_SINGLE) break; else if (BRindex[ch+1] > 10) output[ch] = createByteArray(makeTwoChannel(createBitArray(output[ch]), 3, ch + 1)); } return output; } //bytearray to bitarray private boolean[] createBitArray(byte[] input) { boolean[] output = new boolean[maxBitSize]; //max=1152bytes=9216bits for (int a=0; a < input.length; a++) for (int b=0; b < 8; b++) if ( ((0x80>>>b) & input[a]) != 0 ) output[b + (a<<3)] = true; return output; } //1ch_bitarray to 1ch_bytearray, frame in bitform must already be compliant, but will be shortened in this method to the indexed BR private byte[] createByteArray(boolean[] input) { int size = getSizeFromIndex(input)>>>3; byte[] output = new byte[size]; for (int a=0; a < size; a++) for (int b=0; b < 8; b++) output[a] |= input[b + (a<<3)] ? 0x80>>>b : 0; return output; } //1ch_bitarray to 2ch_bytearray, frame in bitform must already be compliant, but will be shortened in this method to the indexed BR private byte[][] createByteArrays(boolean[] input) { int size = getSizeFromIndex(input)>>>3; byte[][] output = { new byte[size], new byte[0] }; for (int a=0; a < size; a++) for (int b=0; b < 8; b++) output[0][a] |= input[b + (a<<3)] ? 0x80>>>b : 0; return output; } //2ch_bitarray to 2ch_bytearray, frame in bitform must already be compliant, but will be shortened in this method to the indexed BR private byte[][] createByteArrays(boolean[][] input) { int[] size = new int[2]; for (int ch=0; ch < 2; ch++) size[ch] = getSizeFromIndex(input[ch])>>>3; byte[][] output = { new byte[size[0]], new byte[size[1]] }; for (int ch=0; ch < 2; ch++) for (int a=0; a < size[ch]; a++) for (int b=0; b < 8; b++) output[ch][a] |= input[ch][b + (a<<3)] ? 0x80>>>b : 0; return output; } //read out BR_index in bitlength private int getSizeFromIndex(boolean[] input) { int size = 0; for (int a=0; a<4; a++) size |= input[a + 16] ? 8>>>a : 0; size = Sizes[size]; return size; } //set Bitrate index private void setBitRateIndex(boolean[] input, int size, int channel) { if ( (size = Arrays.binarySearch(Sizes, size)) < 0); size = Math.abs(size) - 1; if (channel == 0 && size < 7) size = 7; if (channel > 0 && size < 3) size = 3; size = updateCBRIndex(size, channel); for (int a=0; a < 4; a++) input[a + 16] = (size & 8>>a) != 0 ? true : false; } //update Bitrate index for CBR private int updateCBRIndex(int size, int channel) { if (BRindex[channel] == 0) // if 0 set first BR BRindex[channel] = size; else if (BRindex[channel] >= size) size = BRindex[channel]; else { Restart |= (3 - channel); BRindex[channel] = size; } return size; } //set channelmode private void setChannelMode(boolean[] input, int mode) { mode <<= 2; for (int a=0; a < 4; a++) input[a + 24] = (mode & 8>>a) != 0; } //single bitarray to one 2channel bitarray, bitrate_index must hold place for whole frame data private boolean[] makeTwoChannel(boolean[] input, int MpaConversionMode, int channel) { boolean[] output = new boolean[maxBitSize]; int i = 32; int i_b = 32; int o = 32; int size = getSizeFromIndex(input); System.arraycopy(input, 0, output, 0, 32); //copy source frameheader 1:1 switch(MpaConversionMode) { case SINGLE_TO_3DSTEREO: //make a 3d stereo (delayed channel B) int _Bal_length = Bal.length; int[][] _allocation = new int[2][_Bal_length]; int[][] _scfsi = new int[2][_Bal_length]; try { // copy BAL for (int a = 0; a < _Bal_length; a++) { // ch A for (int b = 0; b < Bal[a]; b++) { if (input[i + b]) { output[o + b] = true; _allocation[0][a] |= 1<<(Bal[a] - 1 - b); } } i += Bal[a]; o += Bal[a]; // ch B for (int b = 0; b < Bal[a]; b++) { if (framebuffer[i_b + b]) { output[o + b] = true; _allocation[1][a] |= 1<<(Bal[a] - 1 - b); } } i_b += Bal[a]; o += Bal[a]; } // copy SCFSI for (int a = 0; a < _Bal_length; a++) { // ch A if (_allocation[0][a] != 0) { for (int b = 0; b < 2; b++) { if (input[i + b]) { output[o + b] = true; _scfsi[0][a] |= 1<<(1 - b); } } i += 2; o += 2; } // ch B if (_allocation[1][a] != 0) { for (int b = 0; b < 2; b++) { if (framebuffer[i_b + b]) { output[o + b] = true; _scfsi[1][a] |= 1<<(1 - b); } } i_b += 2; o += 2; } } // copy Scalefactors for (int a = 0, b = 0; a < _Bal_length; a++) { // ch A if (_allocation[0][a] != 0) { switch (_scfsi[0][a]) { case 0: b = 18; break; case 1: case 3: b = 12; break; case 2: b = 6; } System.arraycopy(input, i, output, o, b); i += b; o += b; } // ch B if (_allocation[1][a] != 0) { switch (_scfsi[1][a]) { case 0: b = 18; break; case 1: case 3: b = 12; break; case 2: b = 6; } System.arraycopy(framebuffer, i_b, output, o, b); i_b += b; o += b; } } // copy Samples for (int x = 0; x < 12; x++) { for (int a = 0, j, k; a < _Bal_length; a++) { // ch A if (_allocation[0][a] != 0) { j = Allocation[a][_allocation[0][a]]; k = getbits[j]; if (grouping[j] > 0) { System.arraycopy(input, i, output, o, k); o += k; i += k; } else { System.arraycopy(input, i, output, o, (3 * k)); o += (3 * k); i += (3 * k); } } // ch B if (_allocation[1][a] != 0) { j = Allocation[a][_allocation[1][a]]; k = getbits[j]; if (grouping[j] > 0) { System.arraycopy(framebuffer, i_b, output, o, k); o += k; i_b += k; } else { System.arraycopy(framebuffer, i_b, output, o, (3 * k)); o += (3 * k); i_b += (3 * k); } } } } } catch (Exception e) { setError(1); } setChannelMode(output, STEREO); //set to stereo/jstereo setBitRateIndex(output, o, channel); //set BR_index System.arraycopy(input, 0, framebuffer, 0, input.length); //copy source frame 1:1 break; case SINGLE_TO_STEREO: // make a stereo case SINGLE_TO_JSTEREO: // make a jointstereo mode 00, sb 4..31 shared int Bal_length = Bal.length; int[] allocation = new int[Bal_length]; int[] scfsi = new int[Bal_length]; try { // copy BAL for (int a=0; a < Bal_length; a++) { for (int b=0; b < Bal[a]; b++) { if (input[i + b]) { output[o + b] = true; if (MpaConversionMode == SINGLE_TO_STEREO || a < 4) output[o + Bal[a] + b] = true; allocation[a] |= 1<<(Bal[a] - 1 - b); } } i += Bal[a]; o += (MpaConversionMode == SINGLE_TO_STEREO || a < 4) ? (Bal[a]<<1) : Bal[a]; } // copy SCFSI for (int a=0; a < Bal_length; a++) { if (allocation[a] != 0) { for (int b=0; b < 2; b++) { if (input[i + b]) { output[o + b] = true; output[o + b + 2] = true; scfsi[a] |= 1<<(1 - b); } } i += 2; o += 4; } } // copy Scalefactors for (int a=0, b=0; a < Bal_length; a++) { if (allocation[a] != 0) { switch (scfsi[a]) { case 0: b = 18; break; case 1: case 3: b = 12; break; case 2: b = 6; } System.arraycopy(input, i, output, o, b); System.arraycopy(input, i, output, o + b, b); i += b; o += b<<1; } } // copy Samples for (int x=0; x < 12; x++) { for (int a=0, j, k; a < Bal_length; a++) { if (allocation[a] != 0) { j = Allocation[a][allocation[a]]; k = getbits[j]; if (grouping[j] > 0) { System.arraycopy(input, i, output, o, k); o += k; if (MpaConversionMode == SINGLE_TO_STEREO || a < 4) { System.arraycopy(input, i, output, o, k); o += k; } i += k; } else { System.arraycopy(input, i, output, o, (3 * k)); o += (3 * k); if (MpaConversionMode == SINGLE_TO_STEREO || a < 4) { System.arraycopy(input, i, output, o, (3 * k)); o += (3 * k); } i += (3 * k); } } } } } catch (Exception e) { setError(1); } setChannelMode(output, 1 & MpaConversionMode); //set to stereo/jstereo setBitRateIndex(output, o, channel); //set BR_index } return output; } //2channel bitarray to 2 single channel bitarrays private boolean[][] splitTwoChannel(boolean[] input, int MpaConversionMode) { boolean[][] output = new boolean[2][maxBitSize]; System.arraycopy(input, 0, output[0], 0, 32); //copy source frameheader 1:1 L System.arraycopy(input, 0, output[1], 0, 32); //copy source frameheader 1:1 R int i = 32; int[] o = { 32,32 }; int Bal_length = Bal.length; int[][] allocation = new int[2][Bal_length]; int[][] scfsi = new int[2][Bal_length]; int bound = 32; if (Audio.getMode() == 1) //source is jointstereo bound=(Audio.getModeExtension() + 1) * 4; if (bound == 32) bound = Bal_length; try { //copy BAL for (int a=0; a < bound; a++) { for (int ch=0; ch < 2; ch++) { for (int b=0; b < Bal[a]; b++) { if (input[i + b]) { allocation[ch][a] |= 1<<(Bal[a] - 1 - b); output[ch][o[ch] + b] = true; } } i += Bal[a]; o[ch] += Bal[a]; } } for (int a=bound; a < Bal_length; a++) { for (int b=0; b < Bal[a]; b++) { if (input[i + b]) { for (int ch=0; ch < 2; ch++) { allocation[ch][a] |= 1<<(Bal[a] - 1 - b); output[ch][o[ch] + b] = true; } } } i += Bal[a]; for (int ch=0; ch < 2; ch++) o[ch] += Bal[a]; } //copy SCFSI for (int a=0; a < Bal_length; a++) { for (int ch=0; ch < 2; ch++) { if (allocation[ch][a] != 0) { for (int b=0; b < 2; b++) { if (input[i + b]) { scfsi[ch][a] |= 1<<(1 - b); output[ch][o[ch] + b] = true; } } i += 2; o[ch] += 2; } } } //copy Scalefactors for (int a=0, b=0; a < Bal_length; a++) { for (int ch=0; ch < 2; ch++) { if (allocation[ch][a] != 0) { switch (scfsi[ch][a]) { case 0: b = 18; break; case 1: case 3: b = 12; break; case 2: b = 6; } System.arraycopy(input, i, output[ch], o[ch], b); i += b; o[ch] += b; } } } //copy Samples for (int x=0; x < 12; x++) { for (int a=0; a < bound; a++) { for (int ch=0, j, k; ch < 2; ch++) { if (allocation[ch][a] != 0) { j = Allocation[a][allocation[ch][a]]; k = getbits[j]; if (grouping[j] > 0) { System.arraycopy(input, i, output[ch], o[ch], k); i += k; o[ch] += k; } else { System.arraycopy(input, i, output[ch], o[ch], (3 * k)); i += (3 * k); o[ch] += (3 * k); } } } } for (int a=bound, j, k; a < Bal_length; a++) { if (allocation[0][a] != 0) { j = Allocation[a][allocation[0][a]]; k = getbits[j]; if (grouping[j] > 0) { for (int ch=0; ch < 2; ch++) { System.arraycopy(input, i, output[ch], o[ch], k); o[ch] += k; } i+=k; } else { for (int ch=0; ch < 2; ch++) { System.arraycopy(input, i, output[ch], o[ch], (3 * k)); o[ch] += (3 * k); } i += (3 * k); } } } } } catch (Exception e) { setError(2); } for (int ch=0; ch < 2; ch++) { setChannelMode(output[ch], SINGLE); //set to mono setBitRateIndex(output[ch], o[ch], ch + 1); //set BR_index if (getSizeFromIndex(output[ch]) > Sizes[10]) output[ch] = makeTwoChannel(output[ch], 3, ch + 1); } return output; } } /***** options[17] CommonParsing.setAudioProcessingFlags() CommonParsing.getAudioProcessingFlags(); * bit 1,0 : if options[10]>=4, not used anymore, but still set * 00 = std CBR in complete file * 01 = VBR same mode = same BR * 10 = VBR each frame/channel its own * 11 = free * bit 3,2 : * 00 = no restart * 01 = restart due left ch. * 10 = restart due right ch. * 11 = restart due both ch. * * bit 7,6,5,4 : bitrate value of last frame 2channel * bit 11,10,9,8 : bitrate value of last frame left * bit 15,14,13,12 : bitrate value of last frame right * * bit 16 : set to 1 if conversion isn't possible, clear befor the next file * bit 17 free * bit63..18 MSB : current audioframes number ******/ project-x/src/net/sourceforge/dvb/projectx/audio/MpaDecoder.java0000600000175000017500000027743710412363406026422 0ustar supermariosupermario/* * @(#)MpaDecoder.java - MPA dec * * Copyright (c) 2003-2006 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * The mostly part of audio decoding was derived from the MPEG/Audio * Software Simulation Group's audio codec. * * simple resampling, amplifying and others added. * now decoding MPEG Layer 1 + 2 * * * 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 * */ package net.sourceforge.dvb.projectx.audio; import java.io.RandomAccessFile; import java.io.IOException; import java.io.ByteArrayOutputStream; import java.util.Arrays; import net.sourceforge.dvb.projectx.parser.CommonParsing; public class MpaDecoder extends Object { static int ERROR_CODE=0, ERROR_CODE1=0; static final double table_b1[] = { // scalefactors 2.00000000000000, 1.58740105196820, 1.25992104989487, 1.00000000000000, 0.79370042498410, 0.62996052494744, 0.50000000000000, 0.39685026299205, 0.31498026247372, 0.25000000000000, 0.19842513149602, 0.15749013123686, 0.12500000000000, 0.09921256574801, 0.07874506561843, 0.06250000000000, 0.04960628287401, 0.03937253280921, 0.03125000000000, 0.02480314143700, 0.01968626640461, 0.01562500000000, 0.01240157071850, 0.00984313320230, 0.00781250000000, 0.00620078535925, 0.00492156660115, 0.00390625000000, 0.00310039267963, 0.00246078330058, 0.00195312500000, 0.00155019633981, 0.00123039165029, 0.00097656250000, 0.00077509816991, 0.00061519582514, 0.00048828125000, 0.00038754908495, 0.00030759791257, 0.00024414062500, 0.00019377454248, 0.00015379895629, 0.00012207031250, 0.00009688727124, 0.00007689947814, 0.00006103515625, 0.00004844363562, 0.00003844973907, 0.00003051757813, 0.00002422181781, 0.00001922486954, 0.00001525878906, 0.00001211090890, 0.00000961243477, 0.00000762939453, 0.00000605545445, 0.00000480621738, 0.00000381469727, 0.00000302772723, 0.00000240310869, 0.00000190734863, 0.00000151386361, 0.00000120155435, 1E-20 }; static final int table_b2ab_nbal[] = { // sblimit 27,30 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2 }; static final int table_b2cd_nbal[] = { // sblimit 8,12 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; static final int table_MPG2_nbal[] = { // sblimit 30 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ,2 ,2 }; static final int table_b2_4a[] = { 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 //0, 1,_3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 changed due to grouping }; static final int table_b2_4b[] = { 0, 1, 2, 4, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17 //0, 1, 2,_3,_4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17 changed due to grouping }; static final int table_b2_4c[] = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 //0, 1, 2,_4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 changed due to grouping }; static final int table_b2_3a[] = { 0, 1, 2, 4, 3, 5, 6, 17 //0, 1, 2,_3,_4, 5, 6, 17 changed due to grouping }; static final int table_b2_3b[] = { 0, 1, 2, 3, 5, 6, 7, 8 //0, 1, 2,_4, 5, 6, 7,_127 changed due to grouping }; static final int table_b2_2[] = { 0, 1, 2, 17 //0, 1, 2, 17 }; static final int table_MPG2_a[] = { //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 changed due to grouping 0, 1, 2, 4, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; static final int table_MPG2_b[] = { //0, 1, 2, 4, 5, 6, 7, 8 changed due to grouping 0, 1, 2, 3, 5, 6, 7, 8 }; static final int table_MPG2_c[] = { //0, 1, 2, 4 changed due to grouping 0, 1, 2, 3 }; static final int table_MPG2[][] = { table_MPG2_a, table_MPG2_a, table_MPG2_a, table_MPG2_a, table_MPG2_b, table_MPG2_b, table_MPG2_b, table_MPG2_b, table_MPG2_b, table_MPG2_b, table_MPG2_b, table_MPG2_c, table_MPG2_c, table_MPG2_c, table_MPG2_c, table_MPG2_c, table_MPG2_c, table_MPG2_c, table_MPG2_c, table_MPG2_c, table_MPG2_c, table_MPG2_c, table_MPG2_c, table_MPG2_c, table_MPG2_c, table_MPG2_c, table_MPG2_c, table_MPG2_c, table_MPG2_c, table_MPG2_c }; static final int table_b2ab[][] = { //sblimit 27,30 table_b2_4a, table_b2_4a, table_b2_4a, table_b2_4b, table_b2_4b, table_b2_4b, table_b2_4b, table_b2_4b, table_b2_4b, table_b2_4b, table_b2_4b, table_b2_3a, table_b2_3a, table_b2_3a, table_b2_3a, table_b2_3a, table_b2_3a, table_b2_3a, table_b2_3a, table_b2_3a, table_b2_3a, table_b2_3a, table_b2_3a, table_b2_2, table_b2_2, table_b2_2, table_b2_2, table_b2_2, table_b2_2, table_b2_2, table_b2_2, table_b2_2 }; static final int table_b2cd[][] = { //sblimit 8,12 table_b2_4c, table_b2_4c, table_b2_3b, table_b2_3b, table_b2_3b, table_b2_3b, table_b2_3b, table_b2_3b, table_b2_3b, table_b2_3b, table_b2_3b, table_b2_3b }; static final double table_b4[][] = { //c,d,bits,step {0.0, 0.0, 0, 0}, {1.0+1.0/3.0, 1.0/2.0, 5, 3}, {1.0+3.0/5.0, 1.0/2.0, 7, 5}, {1.0+7.0/9.0, 1.0/2.0, 10, 9}, {1.0+1.0/7.0, 1.0/4.0, 3, 4}, {1.0+1.0/15.0, 1.0/8.0, 4, 8}, {1.0+1.0/31.0, 1.0/16.0, 5, 16}, {1.0+1.0/63.0, 1.0/32.0, 6, 32}, {1.0+1.0/127.0, 1.0/64.0, 7, 64}, {1.0+1.0/255.0, 1.0/128.0, 8, 128}, {1.0+1.0/511.0, 1.0/256.0, 9, 256}, {1.0+1.0/1023.0, 1.0/512.0, 10, 512}, {1.0+1.0/2047.0, 1.0/1024.0, 11, 1024}, {1.0+1.0/4095.0, 1.0/2048.0, 12, 2048}, {1.0+1.0/8191.0, 1.0/4096.0, 13, 4096}, {1.0+1.0/16383.0, 1.0/8192.0, 14, 8192}, {1.0+1.0/32767.0, 1.0/16384.0, 15, 16384}, {1.0+1.0/65535.0, 1.0/32768.0, 16, 32768} }; static final double table_b3[] = { 0.000000000, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000030518, -0.000030518, -0.000030518, -0.000030518, -0.000045776, -0.000045776, -0.000061035, -0.000061035, -0.000076294, /* 15 */ -0.000076294, -0.000091553, -0.000106812, -0.000106812, -0.000122070, -0.000137329, -0.000152588, -0.000167847, -0.000198364, -0.000213623, -0.000244141, -0.000259399, -0.000289917, -0.000320435, -0.000366211, -0.000396729, /* 31 */ -0.000442505, -0.000473022, -0.000534058, -0.000579834, -0.000625610, -0.000686646, -0.000747681, -0.000808716, -0.000885010, -0.000961304, -0.001037598, -0.001113892, -0.001205444, -0.001296997, -0.001388550, -0.001480103, /* 47 */ -0.001586914, -0.001693726, -0.001785278, -0.001907349, -0.002014160, -0.002120972, -0.002243042, -0.002349854, -0.002456665, -0.002578735, -0.002685547, -0.002792358, -0.002899170, -0.002990723, -0.003082275, -0.003173828, /* 63 */ 0.003250122, 0.003326416, 0.003387451, 0.003433228, 0.003463745, 0.003479004, 0.003479004, 0.003463745, 0.003417969, 0.003372192, 0.003280640, 0.003173828, 0.003051758, 0.002883911, 0.002700806, 0.002487183, /* 79 */ 0.002227783, 0.001937866, 0.001617432, 0.001266479, 0.000869751, 0.000442505, -0.000030518, -0.000549316, -0.001098633, -0.001693726, -0.002334595, -0.003005981, -0.003723145, -0.004486084, -0.005294800, -0.006118774, /* 95 */ -0.007003784, -0.007919312, -0.008865356, -0.009841919, -0.010848999, -0.011886597, -0.012939453, -0.014022827, -0.015121460, -0.016235352, -0.017349243, -0.018463135, -0.019577026, -0.020690918, -0.021789551, -0.022857666, /* 111 */ -0.023910522, -0.024932861, -0.025909424, -0.026840210, -0.027725220, -0.028533936, -0.029281616, -0.029937744, -0.030532837, -0.031005859, -0.031387329, -0.031661987, -0.031814575, -0.031845093, -0.031738281, -0.031478882, /* 127 */ 0.031082153, 0.030517578, 0.029785156, 0.028884888, 0.027801514, 0.026535034, 0.025085449, 0.023422241, 0.021575928, 0.019531250, 0.017257690, 0.014801025, 0.012115479, 0.009231567, 0.006134033, 0.002822876, /* 143 */ -0.000686646, -0.004394531, -0.008316040, -0.012420654, -0.016708374, -0.021179199, -0.025817871, -0.030609131, -0.035552979, -0.040634155, -0.045837402, -0.051132202, -0.056533813, -0.061996460, -0.067520142, -0.073059082, /* 159 */ -0.078628540, -0.084182739, -0.089706421, -0.095169067, -0.100540161, -0.105819702, -0.110946655, -0.115921021, -0.120697021, -0.125259399, -0.129562378, -0.133590698, -0.137298584, -0.140670776, -0.143676758, -0.146255493, /* 175 */ -0.148422241, -0.150115967, -0.151306152, -0.151962280, -0.152069092, -0.151596069, -0.150497437, -0.148773193, -0.146362305, -0.143264771, -0.139450073, -0.134887695, -0.129577637, -0.123474121, -0.116577148, -0.108856201, /* 191 */ 0.100311279, 0.090927124, 0.080688477, 0.069595337, 0.057617187, 0.044784546, 0.031082153, 0.016510010, 0.001068115, -0.015228271, -0.032379150, -0.050354004, -0.069168091, -0.088775635, -0.109161377, -0.130310059, /* 207 */ -0.152206421, -0.174789429, -0.198059082, -0.221984863, -0.246505737, -0.271591187, -0.297210693, -0.323318481, -0.349868774, -0.376800537, -0.404083252, -0.431655884, -0.459472656, -0.487472534, -0.515609741, -0.543823242, /* 223 */ -0.572036743, -0.600219727, -0.628295898, -0.656219482, -0.683914185, -0.711318970, -0.738372803, -0.765029907, -0.791213989, -0.816864014, -0.841949463, -0.866363525, -0.890090942, -0.913055420, -0.935195923, -0.956481934, /* 239 */ -0.976852417, -0.996246338, -1.014617920, -1.031936646, -1.048156738, -1.063217163, -1.077117920, -1.089782715, -1.101211548, -1.111373901, -1.120223999, -1.127746582, -1.133926392, -1.138763428, -1.142211914, -1.144287109, /* 255 */ 1.144989014, 1.144287109, 1.142211914, 1.138763428, 1.133926392, 1.127746582, 1.120223999, 1.111373901, 1.101211548, 1.089782715, 1.077117920, 1.063217163, 1.048156738, 1.031936646, 1.014617920, 0.996246338, /* 271 */ 0.976852417, 0.956481934, 0.935195923, 0.913055420, 0.890090942, 0.866363525, 0.841949463, 0.816864014, 0.791213989, 0.765029907, 0.738372803, 0.711318970, 0.683914185, 0.656219482, 0.628295898, 0.600219727, /* 287 */ 0.572036743, 0.543823242, 0.515609741, 0.487472534, 0.459472656, 0.431655884, 0.404083252, 0.376800537, 0.349868774, 0.323318481, 0.297210693, 0.271591187, 0.246505737, 0.221984863, 0.198059082, 0.174789429, /* 304 */ 0.152206421, 0.130310059, 0.109161377, 0.088775635, 0.069168091, 0.050354004, 0.032379150, 0.015228271, -0.001068115, -0.016510010, -0.031082153, -0.044784546, -0.057617187, -0.069595337, -0.080688477, -0.090927124, /* 319 */ 0.100311279, 0.108856201, 0.116577148, 0.123474121, 0.129577637, 0.134887695, 0.139450073, 0.143264771, 0.146362305, 0.148773193, 0.150497437, 0.151596069, 0.152069092, 0.151962280, 0.151306152, 0.150115967, /* 335 */ 0.148422241, 0.146255493, 0.143676758, 0.140670776, 0.137298584, 0.133590698, 0.129562378, 0.125259399, 0.120697021, 0.115921021, 0.110946655, 0.105819702, 0.100540161, 0.095169067, 0.089706421, 0.084182739, /* 351 */ 0.078628540, 0.073059082, 0.067520142, 0.061996460, 0.056533813, 0.051132202, 0.045837402, 0.040634155, 0.035552979, 0.030609131, 0.025817871, 0.021179199, 0.016708374, 0.012420654, 0.008316040, 0.004394531, /* 367 */ 0.000686646, -0.002822876, -0.006134033, -0.009231567, -0.012115479, -0.014801025, -0.017257690, -0.019531250, -0.021575928, -0.023422241, -0.025085449, -0.026535034, -0.027801514, -0.028884888, -0.029785156, -0.030517578, /* 383 */ 0.031082153, 0.031478882, 0.031738281, 0.031845093, 0.031814575, 0.031661987, 0.031387329, 0.031005859, 0.030532837, 0.029937744, 0.029281616, 0.028533936, 0.027725220, 0.026840210, 0.025909424, 0.024932861, /* 399 */ 0.023910522, 0.022857666, 0.021789551, 0.020690918, 0.019577026, 0.018463135, 0.017349243, 0.016235352, 0.015121460, 0.014022827, 0.012939453, 0.011886597, 0.010848999, 0.009841919, 0.008865356, 0.007919312, /* 415 */ 0.007003784, 0.006118774, 0.005294800, 0.004486084, 0.003723145, 0.003005981, 0.002334595, 0.001693726, 0.001098633, 0.000549316, 0.000030518, -0.000442505, -0.000869751, -0.001266479, -0.001617432, -0.001937866, /* 431 */ -0.002227783, -0.002487183, -0.002700806, -0.002883911, -0.003051758, -0.003173828, -0.003280640, -0.003372192, -0.003417969, -0.003463745, -0.003479004, -0.003479004, -0.003463745, -0.003433228, -0.003387451, -0.003326416, /* 447 */ 0.003250122, 0.003173828, 0.003082275, 0.002990723, 0.002899170, 0.002792358, 0.002685547, 0.002578735, 0.002456665, 0.002349854, 0.002243042, 0.002120972, 0.002014160, 0.001907349, 0.001785278, 0.001693726, /* 463 */ 0.001586914, 0.001480103, 0.001388550, 0.001296997, 0.001205444, 0.001113892, 0.001037598, 0.000961304, 0.000885010, 0.000808716, 0.000747681, 0.000686646, 0.000625610, 0.000579834, 0.000534058, 0.000473022, /* 479 */ 0.000442505, 0.000396729, 0.000366211, 0.000320435, 0.000289917, 0.000259399, 0.000244141, 0.000213623, 0.000198364, 0.000167847, 0.000152588, 0.000137329, 0.000122070, 0.000106812, 0.000106812, 0.000091553, /* 495 */ 0.000076294, 0.000076294, 0.000061035, 0.000061035, 0.000045776, 0.000045776, 0.000030518, 0.000030518, 0.000030518, 0.000030518, 0.000015259, 0.000015259, 0.000015259, 0.000015259, 0.000015259, 0.000015259 /* 511 */ }; static final double table_Nik[][] = { { 0.707106781186547573, -0.707106781186547462, -0.707106781186547684, 0.707106781186547351, 0.707106781186547684, -0.707106781186547906, -0.707106781186547129, 0.707106781186547795, 0.707106781186547240, -0.707106781186547795, -0.707106781186547351, 0.707106781186546352, 0.707106781186547462, -0.707106781186546352, -0.707106781186547573, 0.707106781186548683, 0.707106781186547573, -0.707106781186548683, -0.707106781186547684, 0.707106781186548572, 0.707106781186545241, -0.707106781186546018, -0.707106781186547906, 0.707106781186548350, 0.707106781186545463, -0.707106781186545796, -0.707106781186548017, 0.707106781186548239, 0.707106781186545574, -0.707106781186545574, -0.707106781186548239, 0.707106781186548017, },{ 0.671558954847018330, -0.803207531480644832, -0.514102744193221772, 0.903989293123443449, 0.336889853392220051, -0.970031253194544085, -0.146730474455361665, 0.998795456205172405, -0.049067674327417293, -0.989176509964780903, 0.242980179903262428, 0.941544065183020806, -0.427555093430283195, -0.857728610000272562, 0.595699304492433690, 0.740951125354960216, -0.740951125354958884, -0.595699304492432469, 0.857728610000271452, 0.427555093430285082, -0.941544065183021361, -0.242980179903264426, 0.989176509964780570, 0.049067674327415829, -0.998795456205172405, 0.146730474455359611, 0.970031253194543308, -0.336889853392220606, -0.903989293123444004, 0.514102744193224659, 0.803207531480644166, -0.671558954847017664, },{ 0.634393284163645488, -0.881921264348354939, -0.290284677254462442, 0.995184726672196929, -0.098017140329560840, -0.956940335732208713, 0.471396736825997364, 0.773010453362736549, -0.773010453362736993, -0.471396736825998308, 0.956940335732208935, 0.098017140329559285, -0.995184726672197040, 0.290284677254462220, 0.881921264348354605, -0.634393284163644267, -0.634393284163645932, 0.881921264348355272, 0.290284677254464329, -0.995184726672196818, 0.098017140329560631, 0.956940335732208602, -0.471396736825999529, -0.773010453362734995, 0.773010453362735106, 0.471396736825999307, -0.956940335732208602, -0.098017140329560382, 0.995184726672196818, -0.290284677254464552, -0.881921264348353495, 0.634393284163643378, },{ 0.595699304492433357, -0.941544065183020806, -0.049067674327418029, 0.970031253194544085, -0.514102744193221439, -0.671558954847018108, 0.903989293123443005, 0.146730474455361803, -0.989176509964780903, 0.427555093430283306, 0.740951125354960105, -0.857728610000271674, -0.242980179903263954, 0.998795456205172405, -0.336889853392221328, -0.803207531480645831, 0.803207531480644388, 0.336889853392220162, -0.998795456205172294, 0.242980179903265148, 0.857728610000272895, -0.740951125354960882, -0.427555093430282196, 0.989176509964780570, -0.146730474455362997, -0.903989293123444004, 0.671558954847020440, 0.514102744193221883, -0.970031253194543308, 0.049067674327419257, 0.941544065183021361, -0.595699304492435466, },{ 0.555570233019602289, -0.980785280403230431, 0.195090322016128304, 0.831469612302545014, -0.831469612302545125, -0.195090322016128026, 0.980785280403230320, -0.555570233019601512, -0.555570233019602622, 0.980785280403230431, -0.195090322016128581, -0.831469612302544903, 0.831469612302545791, 0.195090322016126888, -0.980785280403230098, 0.555570233019601067, 0.555570233019600179, -0.980785280403230986, 0.195090322016131440, 0.831469612302547123, -0.831469612302543459, -0.195090322016130968, 0.980785280403230875, -0.555570233019600512, -0.555570233019603621, 0.980785280403230209, -0.195090322016127360, -0.831469612302545569, 0.831469612302545125, 0.195090322016128082, -0.980785280403230320, 0.555570233019602955, },{ 0.514102744193221661, -0.998795456205172405, 0.427555093430282140, 0.595699304492433246, -0.989176509964781014, 0.336889853392220218, 0.671558954847018219, -0.970031253194544085, 0.242980179903262428, 0.740951125354960105, -0.941544065183020251, 0.146730474455360332, 0.803207531480645720, -0.903989293123442783, 0.049067674327416683, 0.857728610000272784, -0.857728610000273228, -0.049067674327419250, 0.903989293123442339, -0.803207531480644166, -0.146730474455359361, 0.941544065183021139, -0.740951125354960771, -0.242980179903264926, 0.970031253194543419, -0.671558954847017664, -0.336889853392217609, 0.989176509964781125, -0.595699304492435466, -0.427555093430282862, 0.998795456205172294, -0.514102744193227101, },{ 0.471396736825997587, -0.995184726672196929, 0.634393284163645599, 0.290284677254462553, -0.956940335732208713, 0.773010453362736993, 0.098017140329560812, -0.881921264348354383, 0.881921264348355494, -0.098017140329561242, -0.773010453362736771, 0.956940335732208824, -0.290284677254462109, -0.634393284163645932, 0.995184726672196818, -0.471396736825999751, -0.471396736825995866, 0.995184726672196707, -0.634393284163646598, -0.290284677254461276, 0.956940335732208602, -0.773010453362737326, -0.098017140329560382, 0.881921264348355050, -0.881921264348354828, 0.098017140329559896, 0.773010453362737548, -0.956940335732208491, 0.290284677254460832, 0.634393284163647042, -0.995184726672197373, 0.471396736826001694, },{ 0.427555093430282196, -0.970031253194543974, 0.803207531480645054, -0.049067674327418424, -0.740951125354958662, 0.989176509964781014, -0.514102744193221217, -0.336889853392219552, 0.941544065183020806, -0.857728610000271674, 0.146730474455360332, 0.671558954847017331, -0.998795456205172405, 0.595699304492433468, 0.242980179903260873, -0.903989293123443782, 0.903989293123444115, -0.242980179903261595, -0.595699304492432913, 0.998795456205172183, -0.671558954847017886, -0.146730474455359611, 0.857728610000273117, -0.941544065183021028, 0.336889853392216942, 0.514102744193222105, -0.989176509964780570, 0.740951125354957996, 0.049067674327416808, -0.803207531480646719, 0.970031253194545751, -0.427555093430284638, },{ 0.382683432365089837, -0.923879532511286850, 0.923879532511286850, -0.382683432365089893, -0.382683432365090559, 0.923879532511286738, -0.923879532511287072, 0.382683432365089560, 0.382683432365090892, -0.923879532511286294, 0.923879532511286850, -0.382683432365089227, -0.382683432365091225, 0.923879532511286405, -0.923879532511285406, 0.382683432365092169, 0.382683432365088283, -0.923879532511286516, 0.923879532511286627, -0.382683432365088505, -0.382683432365091947, 0.923879532511288071, -0.923879532511287849, 0.382683432365091447, 0.382683432365089005, -0.923879532511286850, 0.923879532511286294, -0.382683432365094389, -0.382683432365092613, 0.923879532511285628, -0.923879532511284851, 0.382683432365090781, },{ 0.336889853392220051, -0.857728610000272118, 0.989176509964781014, -0.671558954847018885, 0.049067674327417418, 0.595699304492433468, -0.970031253194543863, 0.903989293123442894, -0.427555093430283195, -0.242980179903263954, 0.803207531480645720, -0.998795456205172405, 0.740951125354958773, -0.146730474455363497, -0.514102744193224437, 0.941544065183021028, -0.941544065183021250, 0.514102744193218775, 0.146730474455362997, -0.740951125354958440, 0.998795456205172183, -0.803207531480643944, 0.242980179903264454, 0.427555093430279587, -0.903989293123444226, 0.970031253194544085, -0.595699304492435244, -0.049067674327413380, 0.671558954847013334, -0.989176509964781681, 0.857728610000270564, -0.336889853392219440, },{ 0.290284677254462331, -0.773010453362736882, 0.995184726672196818, -0.881921264348354828, 0.471396736825997364, 0.098017140329560812, -0.634393284163645599, 0.956940335732209380, -0.956940335732208935, 0.634393284163644378, -0.098017140329560992, -0.471396736825998752, 0.881921264348354716, -0.995184726672196818, 0.773010453362735217, -0.290284677254465051, -0.290284677254461276, 0.773010453362737326, -0.995184726672197151, 0.881921264348356604, -0.471396736825999085, -0.098017140329560631, 0.634393284163646820, -0.956940335732209824, 0.956940335732209490, -0.634393284163640381, 0.098017140329566488, 0.471396736825993867, -0.881921264348353828, 0.995184726672196929, -0.773010453362736549, 0.290284677254460111, },{ 0.242980179903263982, -0.671558954847018330, 0.941544065183020695, -0.989176509964781014, 0.803207531480644832, -0.427555093430281807, -0.049067674327418521, 0.514102744193220773, -0.857728610000272562, 0.998795456205172405, -0.903989293123442783, 0.595699304492433468, -0.146730474455363497, -0.336889853392216942, 0.740951125354960549, -0.970031253194544196, 0.970031253194544196, -0.740951125354960771, 0.336889853392217165, 0.146730474455363247, -0.595699304492433357, 0.903989293123442672, -0.998795456205172516, 0.857728610000270897, -0.514102744193227101, 0.049067674327418764, 0.427555093430286415, -0.803207531480642611, 0.989176509964781236, -0.941544065183023138, 0.671558954847019440, -0.242980179903259930, },{ 0.195090322016128331, -0.555570233019602178, 0.831469612302545014, -0.980785280403230320, 0.980785280403230431, -0.831469612302545014, 0.555570233019601512, -0.195090322016128581, -0.195090322016126777, 0.555570233019602844, -0.831469612302545014, 0.980785280403230098, -0.980785280403230986, 0.831469612302545569, -0.555570233019600734, 0.195090322016131218, 0.195090322016127610, -0.555570233019603621, 0.831469612302543459, -0.980785280403230320, 0.980785280403230098, -0.831469612302547012, 0.555570233019602955, -0.195090322016126888, -0.195090322016124973, 0.555570233019607285, -0.831469612302545902, 0.980785280403229764, -0.980785280403229320, 0.831469612302544570, -0.555570233019605175, 0.195090322016122558, },{ 0.146730474455361748, -0.427555093430282474, 0.671558954847018108, -0.857728610000272340, 0.970031253194543863, -0.998795456205172405, 0.941544065183020362, -0.803207531480644610, 0.595699304492433690, -0.336889853392221328, 0.049067674327416683, 0.242980179903260873, -0.514102744193224437, 0.740951125354960549, -0.903989293123443893, 0.989176509964781014, -0.989176509964781014, 0.903989293123443893, -0.740951125354960549, 0.514102744193224437, -0.242980179903260873, -0.049067674327420228, 0.336889853392221328, -0.595699304492433690, 0.803207531480644610, -0.941544065183020362, 0.998795456205172294, -0.970031253194544751, 0.857728610000274116, -0.671558954847021994, 0.427555093430287303, -0.146730474455368354, },{ 0.098017140329560548, -0.290284677254462442, 0.471396736825997975, -0.634393284163645377, 0.773010453362736549, -0.881921264348354383, 0.956940335732209380, -0.995184726672197040, 0.995184726672196818, -0.956940335732208824, 0.881921264348355272, -0.773010453362737548, 0.634393284163643934, -0.471396736825999529, 0.290284677254461498, -0.098017140329563809, -0.098017140329560382, 0.290284677254465051, -0.471396736825996476, 0.634393284163646820, -0.773010453362735439, 0.881921264348355272, -0.956940335732207825, 0.995184726672196818, -0.995184726672196596, 0.956940335732207270, -0.881921264348357714, 0.773010453362738659, -0.634393284163645266, 0.471396736825994755, -0.290284677254456336, 0.098017140329565516, },{ 0.049067674327417904, -0.146730474455361443, 0.242980179903264232, -0.336889853392219329, 0.427555093430282807, -0.514102744193220662, 0.595699304492432247, -0.671558954847017220, 0.740951125354960216, -0.803207531480645831, 0.857728610000272784, -0.903989293123443782, 0.941544065183021028, -0.970031253194544196, 0.989176509964781014, -0.998795456205172405, 0.998795456205172405, -0.989176509964781014, 0.970031253194544085, -0.941544065183021028, 0.903989293123443671, -0.857728610000272562, 0.803207531480641390, -0.740951125354960105, 0.671558954847014444, -0.595699304492434911, 0.514102744193217442, -0.427555093430284194, 0.336889853392215777, -0.242980179903266591, 0.146730474455357668, -0.049067674327421214, },{ 0.000000000000000061, -0.000000000000000184, 0.000000000000000306, -0.000000000000000429, 0.000000000000000551, 0.000000000000001103, -0.000000000000000980, 0.000000000000000858, -0.000000000000000735, 0.000000000000000613, -0.000000000000000491, -0.000000000000003185, -0.000000000000000246, -0.000000000000003430, -0.000000000000000001, 0.000000000000003431, 0.000000000000000244, 0.000000000000003186, 0.000000000000000489, 0.000000000000002941, -0.000000000000006371, -0.000000000000004409, 0.000000000000000979, 0.000000000000002451, -0.000000000000005881, -0.000000000000004899, 0.000000000000001469, 0.000000000000001961, -0.000000000000005392, -0.000000000000005389, 0.000000000000001959, 0.000000000000001472, },{ -0.049067674327418008, 0.146730474455361942, -0.242980179903264509, 0.336889853392220218, -0.427555093430281807, 0.514102744193222660, -0.595699304492433801, 0.671558954847018441, -0.740951125354958884, 0.803207531480644388, -0.857728610000273228, 0.903989293123444115, -0.941544065183021250, 0.970031253194544196, -0.989176509964781014, 0.998795456205172405, -0.998795456205172405, 0.989176509964781125, -0.970031253194544307, 0.941544065183021361, -0.903989293123441229, 0.857728610000269787, -0.803207531480642611, 0.740951125354956774, -0.671558954847016221, 0.595699304492431358, -0.514102744193219996, 0.427555093430280642, -0.336889853392218996, 0.242980179903263260, -0.146730474455361554, 0.049067674327418272, },{ -0.098017140329560645, 0.290284677254462054, -0.471396736825997476, 0.634393284163646043, -0.773010453362736993, 0.881921264348355494, -0.956940335732208935, 0.995184726672196818, -0.995184726672197040, 0.956940335732208491, -0.881921264348356493, 0.773010453362737104, -0.634393284163643600, 0.471396736825999307, -0.290284677254461498, 0.098017140329564045, 0.098017140329559896, -0.290284677254464329, 0.471396736825995644, -0.634393284163640381, 0.773010453362738992, -0.881921264348354494, 0.956940335732207270, -0.995184726672197262, 0.995184726672196929, -0.956940335732210157, 0.881921264348352385, -0.773010453362736216, 0.634393284163647930, -0.471396736825991758, 0.290284677254460111, -0.098017140329562588, },{ -0.146730474455361859, 0.427555093430282140, -0.671558954847018885, 0.857728610000271896, -0.970031253194544085, 0.998795456205172405, -0.941544065183020917, 0.803207531480645720, -0.595699304492432469, 0.336889853392220162, -0.049067674327419250, -0.242980179903261595, 0.514102744193218775, -0.740951125354960771, 0.903989293123443893, -0.989176509964781014, 0.989176509964781125, -0.903989293123444226, 0.740951125354961215, -0.514102744193225436, 0.242980179903262289, 0.049067674327411423, -0.336889853392219440, 0.595699304492437687, -0.803207531480643166, 0.941544065183021806, -0.998795456205172183, 0.970031253194543752, -0.857728610000268565, 0.671558954847019440, -0.427555093430278033, 0.146730474455365439, },{ -0.195090322016128193, 0.555570233019601845, -0.831469612302545125, 0.980785280403230431, -0.980785280403230320, 0.831469612302544792, -0.555570233019602733, 0.195090322016126888, 0.195090322016128220, -0.555570233019600956, 0.831469612302545569, -0.980785280403230986, 0.980785280403230875, -0.831469612302545458, 0.555570233019600734, -0.195090322016131440, -0.195090322016127138, 0.555570233019602955, -0.831469612302542904, 0.980785280403230098, -0.980785280403230431, 0.831469612302544014, -0.555570233019598736, 0.195090322016122086, 0.195090322016122558, -0.555570233019599069, 0.831469612302544348, -0.980785280403230542, 0.980785280403229986, -0.831469612302542682, 0.555570233019596627, -0.195090322016133605, },{ -0.242980179903263871, 0.671558954847018330, -0.941544065183021028, 0.989176509964780903, -0.803207531480645498, 0.427555093430281419, 0.049067674327416926, -0.514102744193222327, 0.857728610000271452, -0.998795456205172294, 0.903989293123442339, -0.595699304492432913, 0.146730474455362997, 0.336889853392217165, -0.740951125354960549, 0.970031253194544085, -0.970031253194544307, 0.740951125354961215, -0.336889853392218053, -0.146730474455362053, 0.595699304492432136, -0.903989293123441895, 0.998795456205172627, -0.857728610000275671, 0.514102744193216998, -0.049067674327414358, -0.427555093430283750, 0.803207531480644943, -0.989176509964780681, 0.941544065183022028, -0.671558954847022327, 0.242980179903257071, },{ -0.290284677254462387, 0.773010453362737215, -0.995184726672196929, 0.881921264348355272, -0.471396736825998308, -0.098017140329561242, 0.634393284163644378, -0.956940335732208824, 0.956940335732208491, -0.634393284163643378, 0.098017140329563560, 0.471396736825996254, -0.881921264348354939, 0.995184726672196818, -0.773010453362735217, 0.290284677254465273, 0.290284677254460832, -0.773010453362736771, 0.995184726672196263, -0.881921264348353828, 0.471396736826000362, 0.098017140329566002, -0.634393284163645266, 0.956940335732207159, -0.956940335732208158, 0.634393284163647930, -0.098017140329555261, -0.471396736825997364, 0.881921264348352163, -0.995184726672196596, 0.773010453362738992, -0.290284677254457280, },{ -0.336889853392220162, 0.857728610000272007, -0.989176509964781125, 0.671558954847018219, -0.049067674327418521, -0.595699304492433801, 0.970031253194544418, -0.903989293123443671, 0.427555093430285082, 0.242980179903265148, -0.803207531480644166, 0.998795456205172183, -0.740951125354958440, 0.146730474455363247, 0.514102744193224437, -0.941544065183021028, 0.941544065183021361, -0.514102744193225436, -0.146730474455362053, 0.740951125354962437, -0.998795456205172183, 0.803207531480644943, -0.242980179903259458, -0.427555093430277588, 0.903989293123443116, -0.970031253194542975, 0.595699304492437687, 0.049067674327417300, -0.671558954847021328, 0.989176509964780126, -0.857728610000272562, 0.336889853392216665, },{ -0.382683432365089726, 0.923879532511286850, -0.923879532511286738, 0.382683432365089060, 0.382683432365089560, -0.923879532511286960, 0.923879532511286294, -0.382683432365091225, -0.382683432365089005, 0.923879532511286738, -0.923879532511286516, 0.382683432365088505, 0.382683432365091669, -0.923879532511287849, 0.923879532511285406, -0.382683432365092391, -0.382683432365094389, 0.923879532511288959, -0.923879532511284296, 0.382683432365096221, 0.382683432365084009, -0.923879532511284629, 0.923879532511288626, -0.382683432365093501, -0.382683432365086729, 0.923879532511285739, -0.923879532511287405, 0.382683432365090781, 0.382683432365089449, -0.923879532511286850, 0.923879532511286294, -0.382683432365088061, },{ -0.427555093430282251, 0.970031253194543974, -0.803207531480645387, 0.049067674327418397, 0.740951125354959106, -0.989176509964780903, 0.514102744193220995, 0.336889853392221217, -0.941544065183021361, 0.857728610000272895, -0.146730474455359361, -0.671558954847017886, 0.998795456205172183, -0.595699304492433357, -0.242980179903260873, 0.903989293123443671, -0.903989293123441229, 0.242980179903262289, 0.595699304492432136, -0.998795456205172183, 0.671558954847013667, 0.146730474455364940, -0.857728610000272118, 0.941544065183021806, -0.336889853392225935, -0.514102744193225880, 0.989176509964781236, -0.740951125354960105, -0.049067674327413380, 0.803207531480648718, -0.970031253194543197, 0.427555093430281974, },{ -0.471396736825997698, 0.995184726672196929, -0.634393284163645377, -0.290284677254462553, 0.956940335732208935, -0.773010453362736771, -0.098017140329560992, 0.881921264348355272, -0.881921264348356493, 0.098017140329563560, 0.773010453362735106, -0.956940335732209713, 0.290284677254465051, 0.634393284163643378, -0.995184726672197151, 0.471396736825999918, 0.471396736826001694, -0.995184726672196596, 0.634393284163641824, 0.290284677254460111, -0.956940335732210268, 0.773010453362738326, 0.098017140329565516, -0.881921264348354050, 0.881921264348352607, -0.098017140329562588, -0.773010453362740213, 0.956940335732209380, -0.290284677254457280, -0.634393284163644156, 0.995184726672196374, -0.471396736825986540, },{ -0.514102744193221661, 0.998795456205172405, -0.427555093430282696, -0.595699304492434023, 0.989176509964780903, -0.336889853392219829, -0.671558954847018441, 0.970031253194544085, -0.242980179903264426, -0.740951125354960882, 0.941544065183021139, -0.146730474455359611, -0.803207531480643944, 0.903989293123442672, -0.049067674327420228, -0.857728610000272562, 0.857728610000269787, 0.049067674327411423, -0.903989293123441895, 0.803207531480644943, 0.146730474455364940, -0.941544065183023027, 0.740951125354962104, 0.242980179903262788, -0.970031253194544529, 0.671558954847014444, 0.336889853392214833, -0.989176509964780681, 0.595699304492432469, 0.427555093430285971, -0.998795456205172738, 0.514102744193224548, },{ -0.555570233019602289, 0.980785280403230431, -0.195090322016128026, -0.831469612302545014, 0.831469612302544792, 0.195090322016128442, -0.980785280403230320, 0.555570233019600179, 0.555570233019603843, -0.980785280403230209, 0.195090322016127610, 0.831469612302545236, -0.831469612302545569, -0.195090322016127138, 0.980785280403230098, -0.555570233019598292, -0.555570233019605619, 0.980785280403229764, -0.195090322016125445, -0.831469612302546457, 0.831469612302544348, 0.195090322016129303, -0.980785280403230542, 0.555570233019602400, 0.555570233019601512, -0.980785280403230764, 0.195090322016130246, 0.831469612302543792, -0.831469612302547012, -0.195090322016124473, 0.980785280403232318, -0.555570233019594628, },{ -0.595699304492433357, 0.941544065183020695, 0.049067674327417418, -0.970031253194544085, 0.514102744193220773, 0.671558954847018441, -0.903989293123443671, -0.146730474455363497, 0.989176509964780570, -0.427555093430282196, -0.740951125354960771, 0.857728610000273117, 0.242980179903264454, -0.998795456205172516, 0.336889853392221328, 0.803207531480641390, -0.803207531480642611, -0.336889853392219440, 0.998795456205172627, -0.242980179903259458, -0.857728610000272118, 0.740951125354962104, 0.427555093430286859, -0.989176509964780903, 0.146730474455365439, 0.903989293123445892, -0.671558954847017331, -0.514102744193219108, 0.970031253194542420, -0.049067674327415822, -0.941544065183024803, 0.595699304492438797, },{ -0.634393284163645377, 0.881921264348355050, 0.290284677254462664, -0.995184726672196818, 0.098017140329559285, 0.956940335732208824, -0.471396736825998752, -0.773010453362737548, 0.773010453362737104, 0.471396736825996254, -0.956940335732209713, -0.098017140329563560, 0.995184726672197040, -0.290284677254461998, -0.881921264348357936, 0.634393284163647153, 0.634393284163648263, -0.881921264348357270, -0.290284677254463386, 0.995184726672196263, -0.098017140329562089, -0.956940335732210157, 0.471396736826001250, 0.773010453362738104, -0.773010453362741212, -0.471396736825996920, 0.956940335732207381, 0.098017140329557217, -0.995184726672197151, 0.290284677254468104, 0.881921264348361711, -0.634393284163641158, },{ -0.671558954847018441, 0.803207531480644721, 0.514102744193221328, -0.903989293123443449, -0.336889853392221550, 0.970031253194543974, 0.146730474455360110, -0.998795456205172405, 0.049067674327415829, 0.989176509964780570, -0.242980179903264926, -0.941544065183021028, 0.427555093430279587, 0.857728610000270897, -0.595699304492433690, -0.740951125354960105, 0.740951125354956774, 0.595699304492437687, -0.857728610000275671, -0.427555093430277588, 0.941544065183021806, 0.242980179903262788, -0.989176509964780903, -0.049067674327420721, 0.998795456205172627, -0.146730474455355253, -0.970031253194542642, 0.336889853392223604, 0.903989293123448667, -0.514102744193233874, -0.803207531480637615, 0.671558954847025991, },{ -0.707106781186547462, 0.707106781186547684, 0.707106781186547795, -0.707106781186547351, -0.707106781186546352, 0.707106781186547573, 0.707106781186548572, -0.707106781186547906, -0.707106781186545796, 0.707106781186545574, 0.707106781186548017, -0.707106781186548350, -0.707106781186545241, 0.707106781186546129, 0.707106781186542466, -0.707106781186543909, -0.707106781186549793, 0.707106781186546685, 0.707106781186547018, -0.707106781186549460, -0.707106781186544242, 0.707106781186552236, 0.707106781186551458, -0.707106781186544908, -0.707106781186548683, 0.707106781186547684, 0.707106781186546018, -0.707106781186540467, -0.707106781186543243, 0.707106781186543243, 0.707106781186540467, -0.707106781186546018, },{ -0.740951125354959217, 0.595699304492433246, 0.857728610000271896, -0.427555093430281308, -0.941544065183020251, 0.242980179903264093, 0.989176509964781125, -0.049067674327419250, -0.998795456205172405, -0.146730474455362997, 0.970031253194543419, 0.336889853392216942, -0.903989293123444226, -0.514102744193227101, 0.803207531480644610, 0.671558954847014444, -0.671558954847016221, -0.803207531480643166, 0.514102744193216998, 0.903989293123443116, -0.336889853392225935, -0.970031253194544529, 0.146730474455365439, 0.998795456205172627, 0.049067674327416808, -0.989176509964782014, -0.242980179903265148, 0.941544065183017476, 0.427555093430285527, -0.857728610000273117, -0.595699304492427029, 0.740951125354968321, },{ -0.773010453362736993, 0.471396736825997975, 0.956940335732209046, -0.098017140329559174, -0.995184726672197040, -0.290284677254462109, 0.881921264348354716, 0.634393284163643934, -0.634393284163643600, -0.881921264348354939, 0.290284677254465051, 0.995184726672197040, 0.098017140329559660, -0.956940335732207825, -0.471396736825992146, 0.773010453362738104, 0.773010453362738659, -0.471396736826003859, -0.956940335732208158, 0.098017140329558675, 0.995184726672196263, 0.290284677254459167, -0.881921264348354494, -0.634393284163649818, 0.634393284163648707, 0.881921264348355161, -0.290284677254457779, -0.995184726672197817, -0.098017140329574287, 0.956940335732211822, 0.471396736825992591, -0.773010453362737771, },{ -0.803207531480644832, 0.336889853392220051, 0.998795456205172405, 0.242980179903262428, -0.857728610000272562, -0.740951125354958884, 0.427555093430285082, 0.989176509964780570, 0.146730474455359611, -0.903989293123444004, -0.671558954847017664, 0.514102744193222105, 0.970031253194544085, 0.049067674327418764, -0.941544065183020362, -0.595699304492434911, 0.595699304492431358, 0.941544065183021806, -0.049067674327414358, -0.970031253194542975, -0.514102744193225880, 0.671558954847014444, 0.903989293123445892, -0.146730474455355253, -0.989176509964782014, -0.427555093430276256, 0.740951125354963103, 0.857728610000276670, -0.242980179903268478, -0.998795456205171850, -0.336889853392216720, 0.803207531480638170, },{ -0.831469612302545347, 0.195090322016127915, 0.980785280403230320, 0.555570233019601512, -0.555570233019602733, -0.980785280403230320, -0.195090322016128082, 0.831469612302547123, 0.831469612302545458, -0.195090322016131218, -0.980785280403230320, -0.555570233019600179, 0.555570233019601178, 0.980785280403230098, 0.195090322016123030, -0.831469612302542127, -0.831469612302546457, 0.195090322016129275, 0.980785280403231319, 0.555570233019607729, -0.555570233019599513, -0.980785280403230431, -0.195090322016124973, 0.831469612302548899, 0.831469612302547567, -0.195090322016141293, -0.980785280403228099, -0.555570233019609283, 0.555570233019597848, 0.980785280403230875, 0.195090322016126888, -0.831469612302547900, },{ -0.857728610000272007, 0.049067674327418154, 0.903989293123443449, 0.803207531480644721, -0.146730474455362164, -0.941544065183020917, -0.740951125354961104, 0.242980179903261123, 0.970031253194543308, 0.671558954847020440, -0.336889853392217609, -0.989176509964780570, -0.595699304492435244, 0.427555093430286415, 0.998795456205172294, 0.514102744193217442, -0.514102744193219996, -0.998795456205172183, -0.427555093430283750, 0.595699304492437687, 0.989176509964781236, 0.336889853392214833, -0.671558954847017331, -0.970031253194542642, -0.242980179903265148, 0.740951125354963103, 0.941544065183021139, 0.146730474455369797, -0.803207531480652825, -0.903989293123440674, -0.049067674327418764, 0.857728610000268121, },{ -0.881921264348354939, -0.098017140329560840, 0.773010453362736549, 0.956940335732208935, 0.290284677254462220, -0.634393284163645932, -0.995184726672196818, -0.471396736825999529, 0.471396736825999307, 0.995184726672196818, 0.634393284163643378, -0.290284677254461998, -0.956940335732207825, -0.773010453362741212, 0.098017140329565017, 0.881921264348355605, 0.881921264348355827, 0.098017140329565516, -0.773010453362740879, -0.956940335732207936, -0.290284677254462442, 0.634393284163643045, 0.995184726672197484, 0.471396736825993479, -0.471396736825986540, -0.995184726672196707, -0.634393284163638049, 0.290284677254454948, 0.956940335732209824, 0.773010453362745875, -0.098017140329557703, -0.881921264348358935, },{ -0.903989293123443338, -0.242980179903264509, 0.595699304492433468, 0.998795456205172405, 0.671558954847018441, -0.146730474455362414, -0.857728610000271008, -0.941544065183021250, -0.336889853392220606, 0.514102744193221883, 0.989176509964781125, 0.740951125354957996, -0.049067674327413380, -0.803207531480642611, -0.970031253194544751, -0.427555093430284194, 0.427555093430280642, 0.970031253194543752, 0.803207531480644943, 0.049067674327417300, -0.740951125354960105, -0.989176509964780681, -0.514102744193219108, 0.336889853392223604, 0.941544065183017476, 0.857728610000276670, 0.146730474455369797, -0.671558954847012890, -0.998795456205172738, -0.595699304492438020, 0.242980179903258958, 0.903989293123441451, },{ -0.923879532511286738, -0.382683432365089893, 0.382683432365089060, 0.923879532511286183, 0.923879532511286850, 0.382683432365089116, -0.382683432365091447, -0.923879532511286516, -0.923879532511287960, -0.382683432365088283, 0.382683432365089005, 0.923879532511285517, 0.923879532511288959, 0.382683432365090781, -0.382683432365093057, -0.923879532511284407, -0.923879532511287294, -0.382683432365086729, 0.382683432365084009, 0.923879532511286183, 0.923879532511285628, 0.382683432365095777, -0.382683432365088061, -0.923879532511287849, -0.923879532511289292, -0.382683432365078569, 0.382683432365092169, 0.923879532511284074, 0.923879532511282187, 0.382683432365087617, -0.382683432365083065, -0.923879532511291179, },{ -0.941544065183020806, -0.514102744193221439, 0.146730474455361803, 0.740951125354960105, 0.998795456205172405, 0.803207531480644388, 0.242980179903265148, -0.427555093430282196, -0.903989293123444004, -0.970031253194543308, -0.595699304492435466, 0.049067674327416808, 0.671558954847013334, 0.989176509964781236, 0.857728610000274116, 0.336889853392215777, -0.336889853392218996, -0.857728610000268565, -0.989176509964780681, -0.671558954847021328, -0.049067674327413380, 0.595699304492432469, 0.970031253194542420, 0.903989293123448667, 0.427555093430285527, -0.242980179903268478, -0.803207531480652825, -0.998795456205172738, -0.740951125354957774, -0.146730474455351367, 0.514102744193213668, 0.941544065183020473, },{ -0.956940335732208824, -0.634393284163644822, -0.098017140329561492, 0.471396736825998419, 0.881921264348354605, 0.995184726672196818, 0.773010453362735217, 0.290284677254461498, -0.290284677254461498, -0.773010453362735217, -0.995184726672197151, -0.881921264348357936, -0.471396736825992146, 0.098017140329565017, 0.634393284163647597, 0.956940335732209157, 0.956940335732209157, 0.634393284163647597, 0.098017140329565017, -0.471396736825992146, -0.881921264348357936, -0.995184726672196485, -0.773010453362735217, -0.290284677254461498, 0.290284677254461498, 0.773010453362735217, 0.995184726672196485, 0.881921264348357936, 0.471396736826004692, -0.098017140329550875, -0.634393284163636606, -0.956940335732205050, },{ -0.970031253194543974, -0.740951125354959328, -0.336889853392220107, 0.146730474455362025, 0.595699304492432469, 0.903989293123443782, 0.998795456205172405, 0.857728610000271230, 0.514102744193224659, 0.049067674327419257, -0.427555093430282862, -0.803207531480646719, -0.989176509964781681, -0.941544065183023138, -0.671558954847021994, -0.242980179903266591, 0.242980179903263260, 0.671558954847019440, 0.941544065183022028, 0.989176509964780126, 0.803207531480648718, 0.427555093430285971, -0.049067674327415822, -0.514102744193233874, -0.857728610000273117, -0.998795456205171850, -0.903989293123440674, -0.595699304492438020, -0.146730474455351367, 0.336889853392218552, 0.740951125354949891, 0.970031253194544640, },{ -0.980785280403230431, -0.831469612302545125, -0.555570233019601512, -0.195090322016128581, 0.195090322016126888, 0.555570233019600179, 0.831469612302547123, 0.980785280403230875, 0.980785280403230209, 0.831469612302545125, 0.555570233019602955, 0.195090322016130246, -0.195090322016132162, -0.555570233019598736, -0.831469612302546235, -0.980785280403229209, -0.980785280403230542, -0.831469612302542127, -0.555570233019604398, -0.195090322016124973, 0.195090322016123530, 0.555570233019603177, 0.831469612302541350, 0.980785280403230209, 0.980785280403229431, 0.831469612302539129, 0.555570233019611726, 0.195090322016133605, -0.195090322016128803, -0.555570233019607618, -0.831469612302552230, -0.980785280403228543, },{ -0.989176509964781014, -0.903989293123443116, -0.740951125354959217, -0.514102744193222549, -0.242980179903265509, 0.049067674327415579, 0.336889853392220384, 0.595699304492435910, 0.803207531480644166, 0.941544065183021361, 0.998795456205172294, 0.970031253194545751, 0.857728610000270564, 0.671558954847019440, 0.427555093430287303, 0.146730474455357668, -0.146730474455361554, -0.427555093430278033, -0.671558954847022327, -0.857728610000272562, -0.970031253194543197, -0.998795456205172738, -0.941544065183024803, -0.803207531480637615, -0.595699304492427029, -0.336889853392216720, -0.049067674327418764, 0.242980179903258958, 0.514102744193213668, 0.740951125354949891, 0.903989293123447779, 0.989176509964781903, },{ -0.995184726672196929, -0.956940335732209046, -0.881921264348354716, -0.773010453362737882, -0.634393284163644267, -0.471396736825999751, -0.290284677254465051, -0.098017140329563809, 0.098017140329564045, 0.290284677254465273, 0.471396736825999918, 0.634393284163647153, 0.773010453362738104, 0.881921264348355605, 0.956940335732209157, 0.995184726672196929, 0.995184726672196929, 0.956940335732208935, 0.881921264348355383, 0.773010453362737771, 0.634393284163646820, 0.471396736825999529, 0.290284677254451229, 0.098017140329563560, -0.098017140329571359, -0.290284677254458723, -0.471396736826006413, -0.634393284163641824, -0.773010453362742767, -0.881921264348352385, -0.956940335732211267, -0.995184726672196263, },{ -0.998795456205172405, -0.989176509964781014, -0.970031253194544085, -0.941544065183020251, -0.903989293123442783, -0.857728610000273228, -0.803207531480644166, -0.740951125354960771, -0.671558954847017664, -0.595699304492435466, -0.514102744193227101, -0.427555093430284638, -0.336889853392219440, -0.242980179903259930, -0.146730474455368354, -0.049067674327421214, 0.049067674327418272, 0.146730474455365439, 0.242980179903257071, 0.336889853392216665, 0.427555093430281974, 0.514102744193224548, 0.595699304492438797, 0.671558954847025991, 0.740951125354968321, 0.803207531480638170, 0.857728610000268121, 0.903989293123441451, 0.941544065183020473, 0.970031253194544640, 0.989176509964781903, 0.998795456205172849, },{ -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, -1.000000000000000000, },{ -0.998795456205172405, -0.989176509964781125, -0.970031253194543863, -0.941544065183020917, -0.903989293123443671, -0.857728610000271008, -0.803207531480646053, -0.740951125354958440, -0.671558954847020773, -0.595699304492433468, -0.514102744193225436, -0.427555093430283306, -0.336889853392218552, -0.242980179903259458, -0.146730474455368326, -0.049067674327421699, 0.049067674327417300, 0.146730474455363968, 0.242980179903268950, 0.336889853392214389, 0.427555093430279365, 0.514102744193233874, 0.595699304492435688, 0.671558954847012224, 0.740951125354964990, 0.803207531480643500, 0.857728610000265013, 0.903989293123444892, 0.941544065183018142, 0.970031253194546306, 0.989176509964780681, 0.998795456205171739, },{ -0.995184726672196929, -0.956940335732208713, -0.881921264348354383, -0.773010453362736771, -0.634393284163645932, -0.471396736825995866, -0.290284677254461276, -0.098017140329560382, 0.098017140329559896, 0.290284677254460832, 0.471396736826001694, 0.634393284163648263, 0.773010453362738659, 0.881921264348355827, 0.956940335732209157, 0.995184726672196929, 0.995184726672196929, 0.956940335732209380, 0.881921264348356382, 0.773010453362739325, 0.634393284163638049, 0.471396736825989982, 0.290284677254454948, 0.098017140329553804, -0.098017140329566488, -0.290284677254467161, -0.471396736826001250, -0.634393284163647930, -0.773010453362738326, -0.881921264348355605, -0.956940335732208935, -0.995184726672196818, },{ -0.989176509964781014, -0.903989293123443338, -0.740951125354959994, -0.514102744193220884, -0.242980179903264204, 0.049067674327419986, 0.336889853392217387, 0.595699304492432913, 0.803207531480645942, 0.941544065183019807, 0.998795456205172405, 0.970031253194545306, 0.857728610000270120, 0.671558954847019107, 0.427555093430287303, 0.146730474455358167, -0.146730474455360582, -0.427555093430276700, -0.671558954847020884, -0.857728610000278668, -0.970031253194542531, -0.998795456205172183, -0.941544065183016476, -0.803207531480648718, -0.595699304492430914, -0.336889853392208394, -0.049067674327424635, 0.242980179903266591, 0.514102744193232208, 0.740951125354954443, 0.903989293123444448, 0.989176509964782680, },{ -0.980785280403230431, -0.831469612302545569, -0.555570233019602622, -0.195090322016126777, 0.195090322016128220, 0.555570233019603843, 0.831469612302545458, 0.980785280403230209, 0.980785280403230986, 0.831469612302543792, 0.555570233019607285, 0.195090322016128803, -0.195090322016133133, -0.555570233019599069, -0.831469612302546235, -0.980785280403229098, -0.980785280403230764, -0.831469612302542904, -0.555570233019606063, -0.195090322016141293, 0.195090322016134576, 0.555570233019600290, 0.831469612302539129, 0.980785280403232207, 0.980785280403230431, 0.831469612302550010, 0.555570233019592963, 0.195090322016125917, -0.195090322016122086, -0.555570233019613391, -0.831469612302547900, -0.980785280403229653, },{ -0.970031253194543974, -0.740951125354958662, -0.336889853392219552, 0.146730474455360332, 0.595699304492433468, 0.903989293123444115, 0.998795456205172183, 0.857728610000273117, 0.514102744193222105, 0.049067674327416808, -0.427555093430284638, -0.803207531480647607, -0.989176509964781903, -0.941544065183022916, -0.671558954847021994, -0.242980179903267063, 0.242980179903262289, 0.671558954847018441, 0.941544065183021361, 0.989176509964782569, 0.803207531480650494, 0.427555093430289079, -0.049067674327411916, -0.514102744193217887, -0.857728610000270564, -0.998795456205172294, -0.903989293123443116, -0.595699304492431692, -0.146730474455358167, 0.336889853392224992, 0.740951125354963658, 0.970031253194546084, },{ -0.956940335732208824, -0.634393284163645377, -0.098017140329559174, 0.471396736825996920, 0.881921264348355272, 0.995184726672196707, 0.773010453362737326, 0.290284677254465051, -0.290284677254464329, -0.773010453362736771, -0.995184726672196596, -0.881921264348357270, -0.471396736826003859, 0.098017140329565516, 0.634393284163647597, 0.956940335732208935, 0.956940335732209380, 0.634393284163648707, 0.098017140329566974, -0.471396736825989982, -0.881921264348356604, -0.995184726672198150, -0.773010453362737771, -0.290284677254452117, 0.290284677254456835, 0.773010453362740879, 0.995184726672195930, 0.881921264348354272, 0.471396736825985707, -0.098017140329557703, -0.634393284163652482, -0.956940335732206715, },{ -0.941544065183020806, -0.514102744193221994, 0.146730474455360582, 0.740951125354958884, 0.998795456205172405, 0.803207531480643944, 0.242980179903261345, -0.427555093430278921, -0.903989293123442228, -0.970031253194544418, -0.595699304492428139, 0.049067674327418279, 0.671558954847014000, 0.989176509964781236, 0.857728610000274116, 0.336889853392216221, -0.336889853392218053, -0.857728610000275116, -0.989176509964781014, -0.671558954847023104, -0.049067674327430505, 0.595699304492441128, 0.970031253194544862, 0.903989293123444448, 0.427555093430289968, -0.242980179903277027, -0.803207531480649273, -0.998795456205172294, -0.740951125354962437, -0.146730474455372711, 0.514102744193231320, 0.941544065183022472, },{ -0.923879532511286850, -0.382683432365090559, 0.382683432365089560, 0.923879532511286850, 0.923879532511286405, 0.382683432365088283, -0.382683432365088505, -0.923879532511287849, -0.923879532511286850, -0.382683432365092613, 0.382683432365090781, 0.923879532511288737, 0.923879532511288626, 0.382683432365090337, -0.382683432365093057, -0.923879532511284296, -0.923879532511287627, -0.382683432365088061, 0.382683432365082177, 0.923879532511285184, 0.923879532511286738, 0.382683432365085785, -0.382683432365097609, -0.923879532511291623, -0.923879532511291179, -0.382683432365096665, 0.382683432365086729, 0.923879532511287072, 0.923879532511284851, 0.382683432365081289, -0.382683432365102105, -0.923879532511282631, },{ -0.903989293123443227, -0.242980179903263482, 0.595699304492433912, 0.998795456205172405, 0.671558954847017442, -0.146730474455363247, -0.857728610000273006, -0.941544065183020029, -0.336889853392217831, 0.514102744193217887, 0.989176509964780348, 0.740951125354961770, -0.049067674327414358, -0.803207531480642944, -0.970031253194544751, -0.427555093430284638, 0.427555093430279809, 0.970031253194543419, 0.803207531480637615, 0.049067674327419743, -0.740951125354967655, -0.989176509964781125, -0.514102744193210337, 0.336889853392219440, 0.941544065183025469, 0.857728610000272118, 0.146730474455375598, -0.671558954847018774, -0.998795456205173071, -0.595699304492432469, 0.242980179903251381, 0.903989293123444004, },{ -0.881921264348355050, -0.098017140329560687, 0.773010453362737993, 0.956940335732208380, 0.290284677254464329, -0.634393284163646598, -0.995184726672197151, -0.471396736825996476, 0.471396736825995644, 0.995184726672196263, 0.634393284163641824, -0.290284677254463386, -0.956940335732208158, -0.773010453362740879, 0.098017140329565017, 0.881921264348355383, 0.881921264348356382, 0.098017140329566974, -0.773010453362739658, -0.956940335732208713, -0.290284677254465273, 0.634393284163640381, 0.995184726672197928, 0.471396736826009854, -0.471396736826007301, -0.995184726672197595, -0.634393284163642601, 0.290284677254462442, 0.956940335732207825, 0.773010453362741434, -0.098017140329549904, -0.881921264348361711, },{ -0.857728610000272118, 0.049067674327417418, 0.903989293123442894, 0.803207531480645720, -0.146730474455363497, -0.941544065183021250, -0.740951125354958440, 0.242980179903264454, 0.970031253194544085, 0.671558954847013334, -0.336889853392219440, -0.989176509964781903, -0.595699304492434467, 0.427555093430286859, 0.998795456205172294, 0.514102744193217887, -0.514102744193219108, -0.998795456205172960, -0.427555093430285527, 0.595699304492435688, 0.989176509964779571, 0.336889853392231431, -0.671558954847014444, -0.970031253194543641, -0.242980179903256127, 0.740951125354949891, 0.941544065183023138, 0.146730474455362025, -0.803207531480648718, -0.903989293123437676, -0.049067674327426591, 0.857728610000271119, },{ -0.831469612302545236, 0.195090322016128942, 0.980785280403230431, 0.555570233019602844, -0.555570233019600956, -0.980785280403230209, -0.195090322016131218, 0.831469612302545125, 0.831469612302543792, -0.195090322016133605, -0.980785280403229320, -0.555570233019604842, 0.555570233019601956, 0.980785280403229986, 0.195090322016123030, -0.831469612302541905, -0.831469612302547012, 0.195090322016127860, 0.980785280403228099, 0.555570233019597848, -0.555570233019597071, -0.980785280403228321, -0.195090322016128803, 0.831469612302538574, 0.831469612302542460, -0.195090322016122086, -0.980785280403232540, -0.555570233019602733, 0.555570233019592186, 0.980785280403229431, 0.195090322016134576, -0.831469612302551120, },{ -0.803207531480644943, 0.336889853392220218, 0.998795456205172405, 0.242980179903264093, -0.857728610000273228, -0.740951125354958329, 0.427555093430282196, 0.989176509964781125, 0.146730474455356696, -0.903989293123445004, -0.671558954847016221, 0.514102744193223327, 0.970031253194543752, 0.049067674327418272, -0.941544065183020362, -0.595699304492435244, 0.595699304492430581, 0.941544065183017476, -0.049067674327426598, -0.970031253194545862, -0.514102744193216221, 0.671558954847022438, 0.903989293123441451, -0.146730474455364940, -0.989176509964781236, -0.427555093430281086, 0.740951125354959106, 0.857728610000272562, -0.242980179903261817, -0.998795456205172183, -0.336889853392224048, 0.803207531480641723, },{ -0.773010453362736882, 0.471396736825997364, 0.956940335732209380, -0.098017140329560992, -0.995184726672196818, -0.290284677254461276, 0.881921264348356604, 0.634393284163646820, -0.634393284163640381, -0.881921264348353828, 0.290284677254460111, 0.995184726672196263, 0.098017140329558675, -0.956940335732207936, -0.471396736825992146, 0.773010453362737771, 0.773010453362739325, -0.471396736825989982, -0.956940335732208713, 0.098017140329570387, 0.995184726672195930, 0.290284677254462442, -0.881921264348359379, -0.634393284163653259, 0.634393284163644933, 0.881921264348351053, -0.290284677254452117, -0.995184726672197040, -0.098017140329552832, 0.956940335732205605, 0.471396736825999529, -0.773010453362741545, },{ -0.740951125354959106, 0.595699304492432691, 0.857728610000272451, -0.427555093430282973, -0.941544065183019807, 0.242980179903264926, 0.989176509964781125, -0.049067674327415586, -0.998795456205172183, -0.146730474455360582, 0.970031253194545529, 0.336889853392222216, -0.903989293123444670, -0.514102744193226657, 0.803207531480644610, 0.671558954847014777, -0.671558954847015444, -0.803207531480644055, 0.514102744193215333, 0.903989293123438120, -0.336889853392223160, -0.970031253194545306, 0.146730474455375626, 0.998795456205172183, 0.049067674327421699, -0.989176509964779127, -0.242980179903257071, 0.941544065183020140, 0.427555093430291744, -0.857728610000276670, -0.595699304492433357, 0.740951125354953222, } }; static final float Resample[][] = { //0: 48000 to 32000, 1: 48000 to 44100 { -1, 0, 0.5f // write pcm, save act pcm, save act pcm before recalc to new pcm },{ -1, 0, 0.088435374f, 0.17687075f, 0.26530612f, 0.3537415f, 0.44217688f, 0.53061223f, 0.61904764f, 0.707483f, 0.79591835f, 0.88435376f, 0.9727891f, 0, 0.06122449f, 0.14965986f, 0.23809524f, 0.3265306f, 0.414966f, 0.50340134f, 0.59183675f, 0.6802721f, 0.76870745f, 0.85714287f, 0.9455782f, 0, 0.034013607f, 0.12244898f, 0.21088435f, 0.2993197f, 0.3877551f, 0.47619048f, 0.56462586f, 0.6530612f, 0.7414966f, 0.829932f, 0.9183673f, 0, 0.006802721f, 0.0952381f, 0.18367347f, 0.27210885f, 0.3605442f, 0.4489796f, 0.53741497f, 0.6258503f, 0.71428573f, 0.8027211f, 0.89115644f, 0.97959185f, 0, 0.06802721f, 0.15646258f, 0.24489796f, 0.33333334f, 0.4217687f, 0.5102041f, 0.5986394f, 0.68707484f, 0.7755102f, 0.8639456f, 0.95238096f, 0, 0.040816326f, 0.1292517f, 0.21768707f, 0.30612245f, 0.39455783f, 0.4829932f, 0.5714286f, 0.65986395f, 0.7482993f, 0.8367347f, 0.92517006f, 0, 0.013605442f, 0.10204082f, 0.1904762f, 0.27891156f, 0.36734694f, 0.45578232f, 0.5442177f, 0.63265306f, 0.7210884f, 0.8095238f, 0.8979592f, 0.9863946f, 0, 0.07482993f, 0.1632653f, 0.25170067f, 0.34013605f, 0.42857143f, 0.5170068f, 0.60544217f, 0.6938776f, 0.7823129f, 0.8707483f, 0.9591837f, 0, 0.04761905f, 0.13605443f, 0.2244898f, 0.31292516f, 0.40136054f, 0.48979592f, 0.5782313f, 0.6666667f, 0.75510204f, 0.8435374f, 0.9319728f, 0, 0.020408163f, 0.108843535f, 0.19727892f, 0.2857143f, 0.37414965f, 0.46258503f, 0.5510204f, 0.6394558f, 0.72789115f, 0.81632656f, 0.9047619f, 0.99319726f, 0, 0.08163265f, 0.17006803f, 0.2585034f, 0.3469388f, 0.43537414f, 0.52380955f, 0.6122449f, 0.70068026f, 0.78911567f, 0.877551f, 0.9659864f, 0, 0.054421768f, 0.14285715f, 0.23129252f, 0.3197279f, 0.40816328f, 0.49659863f, 0.585034f, 0.67346936f, 0.7619048f, 0.8503401f, 0.93877554f, 0, 0.027210884f, 0.11564626f, 0.20408164f, 0.292517f, 0.3809524f, 0.46938777f, 0.5578231f, 0.64625853f, 0.7346939f, 0.82312924f, 0.91156465f } }; static final int Resample_frequency[][] = { //0: 48000 to 32000, 1: 48000 to 44100 { 2, 3 }, { 147, 160 } }; public static byte RIFF[] = { 0x52, 0x49, 0x46, 0x46, //RIFF 0, 0, 0, 0, //32-bit filesize-8 0x57, 0x41, 0x56, 0x45, //WAVE 0x66, 0x6d, 0x74, 0x20, //fmt chunk 0, 0, 0, 0, //chunk size 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x64, 0x61, 0x74, 0x61, //data chunk 0, 0, 0, 0 //chunk size }; //DM07022004 081.6 int16 new public static byte AIFF[] = { 0x46, 0x4F, 0x52, 0x4D, //FORM 0, 0, 0, 0, //32-bit filesize-8 0x41, 0x49, 0x46, 0x46, //AIFF 0x43, 0x4F, 0x4D, 0x4D, //COMM chunk 0, 0, 0, 0x12, //chunk size 0, 0, // number of channels 0, 0, 0, 0, // number of samples 0, 0, // bits per sample 0, 0, 0, 0, // sample rate + ? 0, 0, 0, 0, 0, 0, 0x53, 0x53, 0x4E, 0x44, //SSND chunk 0, 0, 0, 0 //chunk size }; static class HEADER { int ID; int layer; int protection_bit; int bitrate_index; int sampling_frequency; int new_sampling_frequency=0; //DM30122003 081.6 int10 add int padding_bit; int private_bit; int mode; int mode_extension; int copyright; int original; int channel; int newchannel=0; //DM30122003 081.6 int10 changed int bound; int emphasis; int sblimit; int framesize; int bits_per_sample; public HEADER() { return; } } static class WORK { double area[] = new double[2048]; int offset; public WORK() { return; } } private static byte[] buf; private static boolean[] Bits; private static int BitPos=0, BufferPos=0, resample=0, Frame=0; private static HEADER head = new HEADER(); private static WORK work = new WORK(); private static ByteArrayOutputStream out1 = new ByteArrayOutputStream(); private static ByteArrayOutputStream out2 = new ByteArrayOutputStream(); private static double saveS[] = new double[2]; //DM14052004 081.7 int02 changed public static boolean PRESCAN = false; private static int LEFT_RIGHT = 0; public static boolean MOTOROLA=false, DOWNSAMPLE=false, DOWNMIX=false, WAVE=true, MONO=false, RESET=false, NORMALIZE=false; public static double MULTIPLY = 1; //DM10042004 081.7 int01 changed public static int MAX_VALUE = 32767; //DM10042004 081.7 int01 add public static int check_sync() { if ( (0xFF&buf[BufferPos]) != 0xFF || (0xF0&buf[BufferPos+1]) != 0xF0) return 0; else return 1; } /*** public static void loadbits(int size) { BitPos = BufferPos<<3; BufferPos += size; } public static int getbits(int N) { int Pos, Val; Pos = BitPos>>>3; Val = (0xFF&buf[Pos])<<24 | (0xFF&buf[Pos+1])<<16 | (0xFF&buf[Pos+2])<<8 | (0xFF&buf[Pos+3]); Val <<= BitPos & 7; Val >>>= 32-N; BitPos += N; return Val; } ***/ public static void loadbits(int size) { Bits = new boolean[size*8]; BitPos = 0; for (int a=0; a < size; a++) for (int b=0; b < 8; b++) if (((0x80>>>b) & buf[BufferPos + a]) != 0) Bits[(a * 8) + b] = true; BufferPos += size; } //DM10062004 081.7 int04 fixed public static int getbits(int N) { int Val=0; for (int a = 0; a < N && BitPos + a < Bits.length; a++) if (Bits[BitPos + a]) Val |= 1<<(N - 1 - a); BitPos += N; return Val; } //DM10062004 081.7 int04 fixed public static int showbits(int N) { int Val=0; for (int a = 0; a < N && BitPos + a < Bits.length; a++) if (Bits[BitPos + a]) Val |= 1<<(N-1-a); return Val; } public static void flushbits(int N) { BitPos += N; } public static void flushBuffer(int N) { BufferPos += N; } /** * */ private static byte[] intel_ByteOrder(short value) { byte b[] = new byte[2]; if (!MOTOROLA) { b[0] = (byte)(value & 0xFF); b[1] = (byte)(value>>>8 & 0xFF); } else { b[0] = (byte)(value>>>8 & 0xFF); b[1] = (byte)(value & 0xFF); } return b; } /** * */ private static void writeSample(ByteArrayOutputStream baos, short value) throws IOException { if (PRESCAN) return; baos.write(intel_ByteOrder(value)); } //DM30122003 081.6 int10 changed & moved+ final static int bitrate[][][] = { { {-1,8000,16000,24000,32000,40000,48000,56000,64000, 80000,96000,112000,128000,144000,160000,0 }, //MPG-2, L3 {-1,8000,16000,24000,32000,40000,48000,56000,64000,80000, //MPG-2, L2 96000,112000,128000,144000,160000,0 }, {-1,32000,48000,56000,64000,80000,96000,112000,128000, //MPG-2, L1 144000,160000,176000,192000,224000,256000,0 } },{ {-1,32000,40000,48000,56000,64000,80000,96000, 112000,128000,160000,192000,224000,256000,320000, 0 }, //MPG-1, L3 {-1, 32000, 48000, 56000, 64000, 80000, 96000, 112000, //MPG-1, L2 128000, 160000, 192000, 224000, 256000, 320000, 384000, 0 }, {-1,32000,64000,96000,128000,160000,192000,224000, //MPG-1, L1 256000,288000,320000,352000,384000,416000,448000,0 } },{ {-1, 6000, 8000, 10000, 12000, 16000, 20000, 24000, //MPG-2.5, L3?? 28000, 320000, 40000, 48000, 56000, 64000, 80000, 0 }, {-1, 6000, 8000, 10000, 12000, 16000, 20000, 24000, //MPG-2.5, L2 28000, 320000, 40000, 48000, 56000, 64000, 80000, 0 }, {-1, 8000, 12000, 16000, 20000, 24000, 32000, 40000, //MPG-2.5, L1 48000, 560000, 64000, 80000, 96000, 112000, 128000, 0 } } }; final static int frequency[][] = { { 22050,24000,16000,0 }, //MPG-2 { 44100,48000,32000,0 }, //MPG-1 { 11025,12000,8000,0 } //MPG-2.5 }; //DM30122003 081.6 int10 moved- public static int parse_header() { int channel_bitrate, newfrequency=0; int sblimit = 32; head.ID = 1&buf[BufferPos+1]>>>3; head.emphasis = 3&buf[BufferPos+3]; if (head.ID==1 && head.emphasis==2) head.ID = 2; if ( (head.layer = 3&buf[BufferPos+1]>>>1) < 1) //DM30122003 081.6 int10 changed return -3; head.protection_bit = (1&buf[BufferPos+1]) ^ 1; if ( (head.bitrate_index = bitrate[head.ID][head.layer-1][0xF&buf[BufferPos+2]>>>4]) < 1) //DM30122003 081.6 int10 changed return -4; if ( (newfrequency = frequency[head.ID][3&buf[BufferPos+2]>>>2]) == 0) return -5; head.sampling_frequency = newfrequency; head.padding_bit = 1&buf[BufferPos+2]>>>1; head.private_bit = 1&buf[BufferPos+2]; head.mode = 3&buf[BufferPos+3]>>>6; head.mode_extension = 3&buf[BufferPos+3]>>>4;; if (head.mode==0) head.mode_extension=0; switch(head.mode){ case 0: /* stereo */ case 2: { /* dual channel */ head.channel = 2; head.bound = sblimit; break; } case 1: { /* intensity stereo */ head.channel = 2; head.bound = (head.mode_extension + 1) << 2; break; } case 3: { /* monaural */ head.channel = 1; head.bound = sblimit; break; } } head.copyright = 1&buf[BufferPos+3]>>>3; head.original = 1&buf[BufferPos+3]>>>2; if (head.ID==1 && head.layer==2) { // MPEG-1 if(head.channel == 2) { channel_bitrate = head.bitrate_index / 2; if(channel_bitrate < 32000) return -6; /* unsupported bitrate */ } else { channel_bitrate = head.bitrate_index; if(channel_bitrate > 192000) return -7; /* unsupported bitrate */ } if (channel_bitrate < 56000) { if(head.sampling_frequency == 32000) head.sblimit = 12; else head.sblimit = 8; } else if (channel_bitrate < 96000) head.sblimit = 27; else { if (head.sampling_frequency == 48000) head.sblimit = 27; else head.sblimit = 30; } if (head.bound > head.sblimit) head.bound = head.sblimit; } else if (head.layer==2) { // MPEG-2 head.sblimit = 30; } head.bits_per_sample=16; flushBuffer(4); if(head.protection_bit>0) flushBuffer(2); if (head.layer==2) { if (head.bound > head.sblimit) head.bound = head.sblimit; head.framesize = 144*head.bitrate_index/head.sampling_frequency+head.padding_bit; return 2; }else if (head.layer==1) { //DM30122003 081.6 int10 new if (head.bound > head.sblimit) head.bound = head.sblimit; head.framesize = 144*head.bitrate_index/head.sampling_frequency+head.padding_bit; return 1; } else { head.sblimit = 32; head.framesize = (12*head.bitrate_index/head.sampling_frequency+head.padding_bit)*4; return 3; } } public static int decode_layer2() throws IOException { loadbits(head.framesize-4-(head.protection_bit*2)); short[] pcm = new short[2]; int i,j,k,n,m; int step; int bits; int o1,o2; int code; int sb,ch,gr; int[][] allocation = new int[32][2]; int[][] scfsi = new int[32][2]; int[][][] scalefactor = new int[32][2][3]; double[][][][] sample = new double[12][3][32][2]; double[] U = new double[1024]; double[] W = new double[1024]; double[] s = new double[2]; int[] ss = new int[2]; final int[] table_nbal; final int[][] table_alloc; if (head.ID==1) { if(head.sblimit > 20) { table_nbal = table_b2ab_nbal; table_alloc = table_b2ab; } else { table_nbal = table_b2cd_nbal; table_alloc = table_b2cd; } } else { table_nbal = table_MPG2_nbal; table_alloc = table_MPG2; } /* read allocation */ for(sb=0;sb0) scfsi[sb][ch] = getbits(2); } } /* read scalefactor */ for(sb=0;sb0){ scalefactor[sb][ch][0] = getbits(6); switch(scfsi[sb][ch]){ case 0: { scalefactor[sb][ch][1] = getbits(6); scalefactor[sb][ch][2] = getbits(6); break; } case 1: { scalefactor[sb][ch][1] = scalefactor[sb][ch][0]; scalefactor[sb][ch][2] = getbits(6); break; } case 2: { scalefactor[sb][ch][2] = scalefactor[sb][ch][1] = scalefactor[sb][ch][0]; break; } case 3: { scalefactor[sb][ch][2] = scalefactor[sb][ch][1] = getbits(6); break; } } } } } /* read sample and requantize and normalize */ for(gr=0;gr<12;gr++){ for(sb=0;sb>>2]]; code /= step; } }else{ bits = (int)table_b4[n][2]; //bits step = (int)table_b4[n][3]; //step for(i=0;i<3;i++){ m = getbits(bits); m -= step; sample[gr][i][sb][ch] = m; sample[gr][i][sb][ch] /= step; sample[gr][i][sb][ch] += table_b4[n][1]; // d sample[gr][i][sb][ch] *= table_b4[n][0]; // c sample[gr][i][sb][ch] *= table_b1[scalefactor[sb][ch][gr>>>2]]; } } } } for(sb=head.bound;sb>>2]]; sample[gr][i][sb][1] *= table_b1[scalefactor[sb][1][gr>>>2]]; code /= step; } }else{ bits = (int)table_b4[n][2]; //bits step = (int)table_b4[n][3]; //step for(i=0;i<3;i++){ m = getbits(bits); m -= step; sample[gr][i][sb][0] = m; sample[gr][i][sb][0] /= step; sample[gr][i][sb][0] += table_b4[n][1]; // d sample[gr][i][sb][0] *= table_b4[n][0]; // c sample[gr][i][sb][1] = sample[gr][i][sb][0]; sample[gr][i][sb][0] *= table_b1[scalefactor[sb][0][gr>>>2]]; sample[gr][i][sb][1] *= table_b1[scalefactor[sb][1][gr>>>2]]; } } } /** downmix */ if (DOWNMIX && head.channel==2) { //12,3,32,2 for (sb=0;sb<32;sb++) for (i=0;i<3;i++) sample[gr][i][sb][0] = (sample[gr][i][sb][0] + sample[gr][i][sb][1]) * 0.5f; } } /** downmix */ if (DOWNMIX && head.channel==2) head.newchannel=1; else head.newchannel=2; int channel = head.channel; int last_resample = resample; writeLoop: while (true) { out1.reset(); out2.reset(); resample = last_resample; // subband synthesis for(gr = 0; gr < 12; gr++) { for(m = 0; m < 3; m++) { // shifting work.offset -= 128; work.offset &= 0x7FF; // matrixing for(i = 0; i < 64; i++) { j = work.offset + i * 2; for(ch = 0; ch < head.channel; ch++) { work.area[j + ch] = table_Nik[i][0] * sample[gr][m][0][ch]; for(k = 1; k < head.sblimit; k++) work.area[j + ch] += table_Nik[i][k] * sample[gr][m][k][ch]; } } // build vector U for(i = 0; i < 8; i++) { j = work.offset + i * 256; o1 = j & 0x7FF; o2 = (j + 192) & 0x7FF; for(k = 0; k < 32; k++) { j = (i * 64 + k) * 2; n = o1 + k * 2; U[j] = work.area[n]; U[j + 1] = work.area[n + 1]; j = (i * 64 + 32 + k) * 2; n = o2 + k * 2; U[j] = work.area[n]; U[j + 1] = work.area[n + 1]; } } // window for(i = 0; i < 512; i++) { j = i * 2; W[j] = U[j] * table_b3[i]; W[j + 1] = U[j + 1] * table_b3[i]; } // calc sample for(i = 0; i < 32; i++) { j = i * 2; s[0] = W[j]; s[1] = W[j + 1]; for(k = 1; k < 16; k++) { j = (32 * k + i) * 2; s[0] += W[j]; s[1] += W[j + 1]; } s[0] *= 32768; s[1] *= 32768; if (resample == Resample[LEFT_RIGHT>>>3 & 1].length) resample = 0; if (head.sampling_frequency == 48000 && (LEFT_RIGHT & 0xC) != 0) //resample { double interpolator = Resample[LEFT_RIGHT>>>3 & 1][resample]; if (interpolator == -1) resample++; if (interpolator == 0) { resample++; System.arraycopy(s, 0, saveS, 0, 2); continue; } else if (interpolator > 0) { resample++; double saveS2[] = new double[2]; System.arraycopy(s, 0, saveS2, 0, 2); s[0] = interpolator * s[0] + (1 - interpolator) * saveS[0]; s[1] = interpolator * s[1] + (1 - interpolator) * saveS[1]; System.arraycopy(saveS2, 0, saveS, 0, 2); } } ss[0] = (int)(s[0] * MULTIPLY); ss[1] = (int)(s[1] * MULTIPLY); if(ss[0] > MAX_VALUE) { if (NORMALIZE) MULTIPLY = 1.0 * MAX_VALUE / s[0]; pcm[0] = (short)MAX_VALUE; } else if(ss[0] < -(MAX_VALUE + 1)) { if (NORMALIZE) MULTIPLY = Math.abs(1.0 * -(MAX_VALUE + 1) / s[0]); pcm[0] = (short)(-(MAX_VALUE + 1)); } else { pcm[0] = (short)ss[0]; } if(ss[1] > MAX_VALUE) { if (NORMALIZE) MULTIPLY = 1.0 * MAX_VALUE / s[1]; pcm[1] = (short)MAX_VALUE; } else if(ss[1] < -(MAX_VALUE + 1)) { if (NORMALIZE) MULTIPLY = Math.abs(1.0 * -(MAX_VALUE + 1) / s[1]); pcm[1] = (short)(-(MAX_VALUE + 1)); } else { pcm[1] = (short)ss[1]; } if ((LEFT_RIGHT & 1) != 1) // exchange r<->l writeSample(out1, pcm[0]); else writeSample(out1, pcm[1]); if (!MONO) { if (head.channel == 1) { if ((LEFT_RIGHT & 1) != 1) writeSample(out1, pcm[0]); else writeSample(out1, pcm[1]); channel = 2; } else { if ((LEFT_RIGHT & 1) != 1) writeSample(out1, pcm[1]); else writeSample(out1, pcm[0]); } } else { channel = 1; writeSample(out2, pcm[1]); } if (DOWNSAMPLE) i++; } } } break; } head.newchannel = channel; return 1; } public static int decode_layer1() throws IOException { out1.reset(); out2.reset(); loadbits(head.framesize-4-(head.protection_bit*2)); short pcm[] = new short[2]; int i,k,n,gr; int o1,o2; int sb,ch; int allocation[][] = new int[32][2]; int scalefactor[][] = new int[32][2]; int sample[][][] = new int[12][32][2]; double fraction[][][] = new double[12][32][2]; double U[] = new double[1024]; double W[] = new double[1024]; double s[] = new double[2]; int ss[] = new int[2]; /* read allocation */ for(sb=0;sb0){ scalefactor[sb][ch] = getbits(6); } } } // lay1 s = (s' + 2^(-nb+1) ) * 2^nb / (2^nb-1) , lay2 s = s' * c + d // read 1 sample of each allocated subband per channel, then continue with next sample for each sb , -> do this ever for 12samples per frame /* read sample and requantize and normalize */ for (gr=0;gr<12;gr++) { for(sb=0;sb 0) { // samples of interest sample[gr][sb][ch] = getbits(++n); //read sample (read alloc +1 bit mehr = sample) if (((sample[gr][sb][ch]>>n-1) &1) != 1) fraction[gr][sb][ch] = -1.0; fraction[gr][sb][ch] += (double)(sample[gr][sb][ch] & ((1< 0) { // samples of interest sample[gr][sb][0] = getbits(++n); //read sample if (((sample[gr][sb][0]>>n-1) &1) != 1) fraction[gr][sb][0] = -1.0; fraction[gr][sb][0] += (double)(sample[gr][sb][0] & ((1<>>3 & 1].length) resample=0; if (head.sampling_frequency == 48000 && (LEFT_RIGHT & 0xC) != 0) //resample { double interpolator = Resample[LEFT_RIGHT>>>3 & 1][resample]; if (interpolator == -1) resample++; if (interpolator == 0) { resample++; System.arraycopy(s, 0, saveS, 0, 2); continue; } else if (interpolator > 0) { resample++; double saveS2[] = new double[2]; System.arraycopy(s, 0, saveS2, 0, 2); s[0] = interpolator * s[0] + (1 - interpolator) * saveS[0]; s[1] = interpolator * s[1] + (1 - interpolator) * saveS[1]; System.arraycopy(saveS2, 0, saveS, 0, 2); } } //DM14052004 081.7 int02 changed++ ss[0] = (int)(s[0] * MULTIPLY); ss[1] = (int)(s[1] * MULTIPLY); if(ss[0] > MAX_VALUE) { if (NORMALIZE) MULTIPLY = 1.0 * MAX_VALUE / s[0]; pcm[0] = (short)MAX_VALUE; } else if(ss[0] < -(MAX_VALUE+1)) { if (NORMALIZE) MULTIPLY = Math.abs(1.0 * -(MAX_VALUE+1) / s[0]); pcm[0] = (short)(-(MAX_VALUE+1)); } else { pcm[0] = (short)ss[0]; } if(ss[1] > MAX_VALUE) { if (NORMALIZE) MULTIPLY = 1.0 * MAX_VALUE / s[1]; pcm[1] = (short)MAX_VALUE; } else if(ss[1] < -(MAX_VALUE+1)) { if (NORMALIZE) MULTIPLY = Math.abs(1.0 * -(MAX_VALUE+1) / s[1]); pcm[1] = (short)(-(MAX_VALUE+1)); } else { pcm[1] = (short)ss[1]; } //DM10042004 081.7 int01 changed- if ((LEFT_RIGHT & 1) != 1) writeSample(out1, pcm[0]); else writeSample(out1, pcm[1]); if (!MONO) { if (head.channel==1) { if ((LEFT_RIGHT & 1) != 1) writeSample(out1, pcm[0]); else writeSample(out1, pcm[1]); channel=2; } else { if ((LEFT_RIGHT & 1) != 1) writeSample(out1, pcm[1]); else writeSample(out1, pcm[0]); } } else channel=1; if (DOWNSAMPLE) i++; } } head.newchannel = channel; return 1; } /** * */ public static void init_work(int resample_type) { Arrays.fill(work.area, 0.0); work.offset = 0; resample = 0; Frame = 0; BufferPos = 0; saveS = new double[2]; LEFT_RIGHT = resample_type<<2; } /** * */ private static int littleEndian(int data, int flag) { if (MOTOROLA) return data; if (flag == 4) return ( (0xFF & data>>>24) | (0xFF & data>>>16)<<8 | (0xFF & data>>>8)<<16 | (0xFF & data)<<24 ); else return ( (0xFF & data>>>8) | (0xFF & data)<<8 ); } /** * */ public static void fillAiff(String file, long playtime, boolean fade, int fade_millis) throws IOException { //always MSB RandomAccessFile aiff = new RandomAccessFile(file,"rw"); int len = (int)(aiff.length() - 8); if (DOWNSAMPLE) head.sampling_frequency /= 2; else if ((LEFT_RIGHT & 0xC) != 0 && head.sampling_frequency == 48000) head.sampling_frequency = (head.sampling_frequency * Resample_frequency[LEFT_RIGHT>>>3 & 1][0]) / Resample_frequency[LEFT_RIGHT>>>3 & 1][1]; aiff.seek(4); aiff.writeInt(len); //data+chunksize aiff.seek(16); aiff.writeInt(0x12); //chunk length aiff.writeShort((short)head.newchannel); //channels aiff.writeInt((int)(head.sampling_frequency * playtime / 1000.0)); //playtime aiff.writeShort((short)head.bits_per_sample); //bits_per_sample aiff.write(ConvertToIeeeExtended((double)head.sampling_frequency)); //sample_freq aiff.seek(42); aiff.writeInt(len - 38); //chunk size sample data if (fade) { fadeIn(aiff, fade_millis, 46, len - 38); fadeOut(aiff, fade_millis, 46, len - 38); } aiff.close(); } /** * */ public static void deleteAiff(String file) throws IOException { RandomAccessFile aiff = new RandomAccessFile(file,"rw"); aiff.seek(0); aiff.write(new byte[46]); aiff.close(); } /* * C O N V E R T T O I E E E E X T E N D E D * * Copyright (C) 1988-1991 Apple Computer, Inc. * All rights reserved. * * Machine-independent I/O routines for IEEE floating-point numbers. * * here: 80-bit floating point value of sample_rate in AIFF files * * simple Java adaption by dvb.matt 2004/02/07 * no deep tests.. */ private static long FloatToUnsigned(double f) { return ((long)(((long)(f - 2147483648.0)) + 2147483647L) + 1); } /** * */ private static byte[] ConvertToIeeeExtended(double num) { byte bytes[] = new byte[10]; int sign; int expon=0; double fMant = 0.0, fsMant; long hiMant, loMant; if (num < 0) { sign = 0x8000; num *= -1; } else sign = 0; if (num == 0) { expon = 0; hiMant = 0; loMant = 0; } else { for (int a = 1; a < 32; a++) if ((num /= 2) < 1.0) { expon = a; fMant = num; break; } if ((expon > 16384) || !(fMant < 1)) { /* Infinity or NaN */ expon = sign | 0x7FFF; hiMant = 0; loMant = 0; /* infinity */ } else { /* Finite */ expon += 16382; if (expon < 0) { /* denormalized */ fMant *= (1L<> 8); bytes[1] = (byte)expon; bytes[2] = (byte)(hiMant >> 24); bytes[3] = (byte)(hiMant >> 16); bytes[4] = (byte)(hiMant >> 8); bytes[5] = (byte)hiMant; bytes[6] = (byte)(loMant >> 24); bytes[7] = (byte)(loMant >> 16); bytes[8] = (byte)(loMant >> 8); bytes[9] = (byte)loMant; return bytes; } /** * */ public static void fillRIFF(String file, boolean fade, int fade_millis) throws IOException { RandomAccessFile riff = new RandomAccessFile(file, "rw"); int len = (int)riff.length() - 8; if (DOWNSAMPLE) head.sampling_frequency /= 2; else if ((LEFT_RIGHT & 0xC) != 0 && head.sampling_frequency == 48000) head.sampling_frequency = (head.sampling_frequency * Resample_frequency[LEFT_RIGHT>>>3 & 1][0]) / Resample_frequency[LEFT_RIGHT>>>3 & 1][1]; if (MOTOROLA) { riff.seek(3); riff.write('X'); //RIFX nonIntel } riff.seek(4); riff.writeInt(littleEndian(len, 4)); //data+chunksize riff.seek(16); riff.writeInt(littleEndian(0x10, 4)); //chunk length riff.writeShort(littleEndian(1, 2)); //pcm riff.writeShort((short)littleEndian(head.newchannel, 2)); //channels riff.writeInt(littleEndian(head.sampling_frequency, 4)); //sample_freq riff.writeInt(littleEndian(head.sampling_frequency * head.newchannel * head.bits_per_sample / 8, 4)); //byterate riff.writeShort((short)littleEndian(head.newchannel * head.bits_per_sample / 8, 2)); //blockalign riff.writeShort((short)littleEndian(head.bits_per_sample, 2)); //bits_per_sample riff.seek(40); riff.writeInt(littleEndian(len - 36, 4)); //data-size if (fade) { fadeIn(riff, fade_millis, 44, len - 36); fadeOut(riff, fade_millis, 44, len - 36); } riff.close(); } /** * */ public static void deleteRIFF(String file) throws IOException { RandomAccessFile riff = new RandomAccessFile(file, "rw"); riff.seek(0); riff.write(new byte[44]); riff.close(); } private final static int SamplesPerFrame[] = { 0, 1152, 1152, 384 }; //u,L3,L2,L1 /** * */ public static void silentSamples(int new_sampling_frequency) throws IOException { if (DOWNSAMPLE) new_sampling_frequency /= 2; else if ((LEFT_RIGHT & 0xC) != 0) new_sampling_frequency = (new_sampling_frequency * Resample_frequency[LEFT_RIGHT>>>3 &1][0])/Resample_frequency[LEFT_RIGHT>>>3 &1][1]; int silent_samples = head.newchannel * (head.bits_per_sample / 8) * (int)Math.abs((1.0 * SamplesPerFrame[head.layer] * new_sampling_frequency) / head.sampling_frequency); byte samples[] = new byte[silent_samples]; out1.reset(); out2.reset(); out1.write(samples); out2.write(samples); } /** * */ public static byte[] decodeArray(byte[] data) throws IOException { buf = data; BufferPos = 0; ERROR_CODE = ERROR_CODE1 = 0; double last_Multiply = MULTIPLY; if ( (ERROR_CODE1 = check_sync()) == 0) return new byte[0]; if ( (ERROR_CODE1 = parse_header()) < 1) return new byte[0]; if (head.new_sampling_frequency == 0) head.new_sampling_frequency = head.sampling_frequency; if (head.newchannel == 0) head.newchannel = DOWNMIX ? 1 : 2; switch (ERROR_CODE1) { case 1: silentSamples(head.new_sampling_frequency); break; case 2: ERROR_CODE = decode_layer2(); break; case 3: ERROR_CODE = decode_layer1(); } if (ERROR_CODE == 1) head.new_sampling_frequency = head.sampling_frequency; if (last_Multiply != MULTIPLY) CommonParsing.setAudioProcessingFlags(CommonParsing.getAudioProcessingFlags() | 0x1000CL); return out1.toByteArray(); } /** * */ public static byte[] get2ndArray() { return out2.toByteArray(); } /** * */ private static void fadeIn(RandomAccessFile pcm_file, int fade_millis, long seek_position, int datachunk_length) throws IOException { fade(pcm_file, fade_millis, seek_position, datachunk_length, 1); } /** * */ private static void fadeOut(RandomAccessFile pcm_file, int fade_millis, long seek_position, int datachunk_length) throws IOException { fade(pcm_file, fade_millis, seek_position, datachunk_length, 2); } /** * */ private static void fade(RandomAccessFile pcm_file, int fade_millis, long seek_position, int datachunk_length, int fade_mode) throws IOException { int millis = (fade_millis < 0 || fade_millis > 5000) ? 2000 : fade_millis; int load = head.newchannel * (int)((1L * millis * head.sampling_frequency * head.bits_per_sample) / 8000); int bytes_per_sample = head.bits_per_sample / 8; if (load > datachunk_length) load = datachunk_length; double amp = 1.0; byte[] array = new byte[load]; if (fade_mode == 2) seek_position = seek_position + datachunk_length - load; pcm_file.seek(seek_position); pcm_file.readFully(array); for (int i = 0; i < load; ) { amp = (1.0 * (fade_mode == 2 ? (load - i) : i)) / load; for (int ch = 0, sample; ch < head.newchannel; ch++) { sample = (0xFF & array[i])<<8 | (0xFF & array[i + 1]); sample = littleEndian(sample, 2); sample = (0x8000 & sample) != 0 ? (0xFFFF0000 | sample) : sample; sample = (int) (amp * sample); sample = littleEndian(sample, 2); array[i] = (byte) (0xFF & sample>>8); array[i + 1] = (byte) (0xFF & sample); i += bytes_per_sample; } } pcm_file.seek(seek_position); pcm_file.write(array); } } project-x/src/net/sourceforge/dvb/projectx/audio/RIFFHeader.java0000600000175000017500000001375210351077540026245 0ustar supermariosupermario/* * @(#)RIFFHeader.java - create a RIFF Header for nonPCM data * * Copyright (c) 2002-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.audio; public class RIFFHeader extends Object { byte[] riffacm = { 82, 73, 70, 70, 0, 0, 0, 0, 87, 65, 86, 69,102,109,116, 32, 30, 0, 0, 0, 85, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 1, 0, 2, 0, 0, 0, 0, 0, 1, 0, 113, 5,102, 97, 99,116, 4, 0, 0, 0, 0, 0, 0, 0,100, 97, 116, 97, 0, 0, 0, 0 }; byte[] riffbwf = { 82, 73, 70, 70, 0, 0, 0, 0, 87, 65, 86, 69,102,109,116, 32, 40, 0, 0, 0, 80, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102, 97, 99,116, 4, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 0, 0, 0, 0 }; byte[] riffac3 = { 82, 73, 70, 70, 0, 0, 0, 0, 87, 65, 86, 69,102,109,116, 32, 18, 0, 0, 0, 0, 32, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0,100, 97,116, 97, 0, 0, 0, 0, }; long Samples=0, SampleCount=0; public void RiffData(int[] riffdata) { Samples += riffdata[2]; SampleCount++; int nSamplesPerSec = (255&riffbwf[24]) | (255&riffbwf[24+1])<<8 | (255&riffbwf[24+2])<<16 | (255&riffbwf[24+3])<<24; int dwHeadBitrate = (255&riffbwf[40]) | (255&riffbwf[40+1])<<8 | (255&riffbwf[40+2])<<16 | (255&riffbwf[40+3])<<24; int nBlockAlign = (255&riffbwf[32]) | (255&riffbwf[32+1])<<8; if ( nBlockAlign == 0 ) //nBlockAlign for (int a=0;a<2;a++) riffacm[44+a] = riffbwf[32+a] = (byte)(255 & riffdata[8]>>>(a*8)); else if ( nBlockAlign != 1 && nBlockAlign != riffdata[8] ) { riffbwf[32] = 1; riffbwf[32+1] = 0; } if ( nSamplesPerSec == 1 ) //nSamplesPerSec for (int a=0;a<4;a++) riffacm[24+a] = riffbwf[24+a] = (byte)(255 & riffdata[2]>>>(a*8)); else if ( nSamplesPerSec != 0 && nSamplesPerSec != riffdata[2] ) for (int a=0;a<4;a++) riffacm[24+a] = riffbwf[24+a] = 0; if ( dwHeadBitrate == 1 ) //dwHeadBitrate for (int a=0;a<4;a++) riffbwf[40+a] = (byte)(255 & riffdata[6]>>>(a*8)); else if ( dwHeadBitrate != 0 && dwHeadBitrate != riffdata[6] ) for (int a=0;a<4;a++) riffbwf[40+a] = 0; if ( riffdata[3]==2 ) // fwHeadModeExt riffbwf[46] |= (byte)riffdata[5]; if ( riffbwf[22]==1 ) // nChannels riffacm[22] = riffbwf[22] = (byte)riffdata[4]; riffbwf[38] |= (byte)riffdata[1]; // fwHeadLayer riffbwf[44] |= (byte)riffdata[3]; // fwHeadMode riffbwf[48] |= (byte)riffdata[7]; // wHeadEmphasis riffbwf[50] |= (byte)riffdata[0]; // fwHeadFlags } public void AC3RiffData(int[] riffdata) { Samples += riffdata[2]; SampleCount++; int nSamplesPerSec = (255&riffac3[24]) | (255&riffac3[24+1])<<8 | (255&riffac3[24+2])<<16 | (255&riffac3[24+3])<<24; int nBlockAlign = (255&riffac3[32]) | (255&riffac3[32+1])<<8; if ( nBlockAlign == 0 ) //nBlockAlign for (int a=0;a<2;a++) riffac3[32+a] = (byte)(255 & riffdata[8]>>>(a*8)); else if ( nBlockAlign != 1 && nBlockAlign != riffdata[8] ) { riffac3[32] = 1; riffac3[32+1] = 0; } if ( nSamplesPerSec == 1 ) //nSamplesPerSec for (int a=0;a<4;a++) riffac3[24+a] = (byte)(255 & riffdata[2]>>>(a*8)); else if ( nSamplesPerSec != 0 && nSamplesPerSec != riffdata[2] ) for (int a=0;a<4;a++) riffac3[24+a] = 0; if ( (0xFF&riffac3[22]) < riffdata[4] ) // nChannels riffac3[22] = (byte)riffdata[4]; } /** placeholder **/ public byte[] ACMnull() { return new byte[70]; } public byte[] BWFnull() { return new byte[80]; } public byte[] AC3null() { return new byte[46]; } /** update header **/ public byte[] ACM() { return riffacm; } public byte[] BWF() { return riffbwf; } public byte[] AC3() { return riffac3; } public void Length(long filelength, long timelength) { int lengthACM = (int)filelength-70; int lengthBWF = (int)filelength-80; int lengthAC3 = (int)filelength-46; for (int a=0;a<4;a++) { riffacm[4+a] = (byte)(255 & (lengthACM+62)>>>(a*8)); riffbwf[4+a] = (byte)(255 & (lengthBWF+72)>>>(a*8)); riffac3[4+a] = (byte)(255 & (lengthAC3+38)>>>(a*8)); riffacm[66+a] = (byte)(255 & lengthACM>>>(a*8)); riffbwf[76+a] = (byte)(255 & lengthBWF>>>(a*8)); riffac3[42+a] = (byte)(255 & lengthAC3>>>(a*8)); } if (filelength>100) { int time = (int)timelength; int nAvgBytePerSecACM = (int)(1000L*lengthACM / time ); int nAvgBytePerSecBWF = (int)(1000L*lengthBWF / time ); int nAvgBytePerSecAC3 = (int)(1000L*lengthAC3 / time ); for (int a=0;a<4;a++) { riffacm[28+a] = (byte)(255 & nAvgBytePerSecACM>>>(a*8)); riffbwf[28+a] = (byte)(255 & nAvgBytePerSecBWF>>>(a*8)); riffac3[28+a] = (byte)(255 & nAvgBytePerSecAC3>>>(a*8)); } int fact = (int)(1L * (Samples/SampleCount) * time /1000); for (int a=0;a<4;a++) riffacm[58+a] = riffbwf[68+a] = (byte)(255 & fact>>>(a*8)); } } } project-x/src/net/sourceforge/dvb/projectx/common/0000700000175000017500000000000010745203152023715 5ustar supermariosupermarioproject-x/src/net/sourceforge/dvb/projectx/common/Common.java0000600000175000017500000010441210413071022026003 0ustar supermariosupermario/* * @(#)Common.java - carries various stuff, the center class * * Copyright (c) 2004-2006 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.common; import java.awt.GraphicsEnvironment; import java.awt.Color; import java.awt.Rectangle; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.List; import java.util.Arrays; import java.util.Hashtable; import java.util.StringTokenizer; import java.util.Date; import java.util.TimeZone; import java.util.Comparator; import java.text.NumberFormat; import java.io.StringWriter; import java.io.PrintWriter; import java.text.DateFormat; import java.text.SimpleDateFormat; import net.sourceforge.dvb.projectx.audio.AudioFormat; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.common.Settings; import net.sourceforge.dvb.projectx.common.GuiInterface; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.parser.Scan; import net.sourceforge.dvb.projectx.parser.MainProcess; import net.sourceforge.dvb.projectx.subtitle.Subpicture; import net.sourceforge.dvb.projectx.video.MpvDecoder; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.xinput.XInputDirectory; import net.sourceforge.dvb.projectx.xinput.topfield_raw.RawInterface; import net.sourceforge.dvb.projectx.xinput.DirType; import net.sourceforge.dvb.projectx.net.WebInterface; /** * */ public final class Common extends Object { /* main version index */ private static String version_name = "ProjectX 0.90.4.00"; private static String version_date = "30.03.2006"; private static String line_separator = System.getProperty("line.separator"); private static String messagelog = ""; private static int ProcessedCollection = 0; private static int ActiveCollection = -1; private static int ProcessedPercent = 0; private static int ErrorCount = 0; private static boolean showGUI = false; private static boolean runningCLI = false; private static boolean runningProcess = false; private static boolean GlobalDebug = false; private static boolean TimeLog = false; private static boolean MaxLog = false; private static boolean canAccessFtp = true; private static boolean canAccessRawread = true; private static boolean canAccessColorTable = true; private static boolean canAccessSilentAC3 = true; /** name of the colours table file */ private static final String COLOUR_TABLES_FILENAME = "colours.tbl"; /** name of the ac3 file */ private static final String AC3_FILENAME = "ac3.bin"; /** */ private static ArrayList subpicture_colormodels = null; /** list of AC3 frames */ private static List AC3list = new ArrayList(); private static DateFormat time_format_1 = new SimpleDateFormat("HH:mm:ss.SSS"); private static DateFormat time_format_2 = new SimpleDateFormat("HH:mm:ss:SSS"); private static DateFormat time_format_3 = new SimpleDateFormat("dd.MM.yy HH:mm"); private static DateFormat time_format_4 = new SimpleDateFormat("HH:mm:ss"); private static byte temp_byte; private static Settings settings; /* status panel */ private static int[] FpsValue = { 0, 0 }; private static long[] Data_Troughput = { 0, 0 }; private static int SplitPart = 0; private static String StatusString = null; /* linkage to x.swing components */ private static GuiInterface guiInterface = null; private static Subpicture subpicture = null; private static Scan scan = null; private static MpvDecoder mpvdecoder = null; private static WebInterface webserver = null; private static MainProcess mainprocess = null; private static long ProcessTime = 0; /** * carries all new collection classes */ private static List collectionList = new ArrayList(); /** * */ private Common() {} /** * save settings, if enabled and no fatal error has occured */ public static void exitApplication(int returncode) { if (returncode == 0 && getSettings().getBooleanProperty(Keys.KEY_SaveSettingsOnExit)) saveSettings(); System.exit(returncode); } /** * */ public static void setSettings() { setSettings(null); } /** * */ public static void setSettings(String str) { if (settings != null) return; if (str == null) settings = new Settings(); else settings = new Settings(str); } /** * */ public static Settings getSettings() { return settings; } /** * */ public static void saveSettings() { saveSettings(null); } /** * */ public static void saveSettings(String str) { getSettings().setProperty(Keys.KEY_Language[0], Resource.getChosenLanguage()); getMainFrameBounds(); settings.save(str); } /** * */ public static void init() { StatusString = Resource.getString("run.status"); scan = new Scan(); subpicture = new Subpicture(); mpvdecoder = new MpvDecoder(); subpicture_colormodels = loadColorModels(); } /** * */ public static void startWebServer() { if (webserver == null) webserver = new WebInterface(); stopWebServer(); webserver.start(); } /** * */ public static void stopWebServer() { if (webserver == null) return; webserver.stop(); } /** * */ public static boolean isWebServerOnline() { if (webserver != null && webserver.isOnline()) return true; return false; } /** * */ public static void prepareGui(boolean b) { showGUI = b; //prepare gui guiInterface = new GuiInterface(showGUI); //load gui if (showGUI()) getGuiInterface().loadGui(); } /** * */ public static GuiInterface getGuiInterface() { return guiInterface; } /** * */ public static boolean showGUI() { return showGUI; } /** * */ public static Subpicture getSubpictureClass() { return subpicture; } /** * */ public static Scan getScanClass() { return scan; } /** * */ public static MpvDecoder getMpvDecoderClass() { return mpvdecoder; } /** * */ public static boolean startProcess() { boolean b = true; if (isRunningProcess()) return !b; if (isCollectionListEmpty()) return !b; setRunningProcess(b); CommonParsing.setPvaPidToExtract(-1); return b; } /** * */ public static boolean waitingMainProcess() { return (mainprocess != null ? mainprocess.pause() : false); } /** * */ public static void startMainProcess() { mainprocess = new MainProcess(); mainprocess.start(); } /** * */ public static void breakMainProcess() { if (!isRunningProcess()) return; setMessage(Resource.getString("golistener.msg.cancelled"), true, 0xE0E0FF); CommonParsing.setProcessPausing(false); CommonParsing.setProcessCancelled(true); } /** * */ public static void setRunningProcess(boolean b) { runningProcess = b; TimeLog = getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg4); MaxLog = getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg8); ErrorCount = 0; if (runningProcess) { setMessage(null, true, 0xFFFFFF); if (getSettings().getBooleanProperty(Keys.KEY_minimizeMainFrame)) showMainFrame(false); if (getSettings().getBooleanProperty(Keys.KEY_hideProcessWindow)) getGuiInterface().closeLogWindow(); } else { showMainFrame(true); getGuiInterface().showLogWindow(); } } /** * */ public static boolean isRunningProcess() { return runningProcess; } /** * */ public static void setRunningCLI(boolean b) { runningCLI = b; } /** * */ public static boolean isRunningCLI() { return runningCLI; } /** * */ public static void setProcessTime(long val) { ProcessTime = val; } /** * */ public static long getProcessTime() { if (!isRunningProcess() || ProcessTime <= 0) return 0L; return (System.currentTimeMillis() - ProcessTime); } /** * */ public static void setGlobalDebug(boolean b) { GlobalDebug = b; } /** * */ public static boolean getGlobalDebug() { return GlobalDebug; } /** * */ public static int getProcessedCollection() { return ProcessedCollection; } /** * */ public static void setProcessedCollection(int val) { ProcessedCollection = val; } /** * */ public static int getActiveCollection() { return ActiveCollection; } /** * */ public static void setActiveCollection(int val) { ActiveCollection = val; } /** * */ public static String getLineSeparator() { return line_separator; } /** * */ public static String getVersionName() { return version_name; } /** * */ public static String getVersionDate() { return version_date; } /** * Returns the Version information * * @return String[] */ public static String[] getVersion() { return new String[] { getVersionName(), getVersionDate(), Resource.getString("version.info"), Resource.getString("version.user") + System.getProperty("user.name") }; } /** * */ public static String getDateAndTime() { return (DateFormat.getDateInstance(DateFormat.LONG).format(new Date()) + " " + DateFormat.getTimeInstance(DateFormat.LONG).format(new Date())); } /** * */ public static String formatNumber(long val) { return NumberFormat.getInstance().format(val); } /** * return collection */ public static boolean isCollectionListEmpty() { return collectionList.isEmpty(); } /** * return collectionlist size */ public static int getCollectionListSize() { return collectionList.size(); } /** * remove collection */ public static boolean removeCollection(int index) { if (index < 0 || index >= collectionList.size()) return false; if (getCollection(index).isActive()) return false; collectionList.remove(index); return true; } /** * return collection */ public static JobCollection getCollection() { return getCollection(getActiveCollection()); } /** * return collection */ public static JobCollection getCollection(int index) { if (index < 0 || index >= collectionList.size()) return null; return (JobCollection) collectionList.get(index); } /** * if collection doesnt exists, create one */ public static JobCollection addCollection() { return addCollection(true); } /** * if collection doesnt exists, create one */ public static JobCollection addCollection(boolean append) { /** * ensure only, that at least one coll exists */ if (!append && !collectionList.isEmpty()) return null; /** * create new coll, with current output dir. */ return addCollection(new JobCollection(getSettings().getProperty(Keys.KEY_OutputDirectory))); } /** * */ public static JobCollection addCollection(JobCollection collection) { /** * add new coll */ collectionList.add(collection); addCollectionAtEnd(); return collection; } /** * check whether commons-net is available, to prevent malfunctions */ public static String checkLibraryAccess() { try { Class cls = Class.forName("org.apache.commons.net.ftp.FTPClient"); canAccessFtp = true; return null; } catch (Exception exc) {} catch (Error err) {} return "\ncommons-net library not accessible! see readme.txt [ii]\nensure the correct location/classpath, related to the executed .jar\n"; } /** * */ public static boolean canAccessFtp() { return canAccessFtp; } /** * */ public static boolean canAccessRawRead() { return canAccessRawread; } /** * */ public static boolean canAccessColorTable() { return canAccessColorTable; } /** * */ public static boolean canAccessSilentAC3() { return canAccessSilentAC3; } /** * changes the byte order, fixed to 2bytes len ATM! */ public static void changeByteOrder(byte[] data, int off, int len) { for (int i = off, j = len - 1; i < j; i += 2) { temp_byte = data[i + 1]; data[i + 1] = data[i]; data[i] = temp_byte; } if ((len & 1) != 0) setMessage("!> byte swap, len has an odd value: " + len + " /off " + off); } // should try a while to rename with success, if file_system is blocked by another app. public static boolean renameTo(File oldfile, File newfile) { //explicit call, otherwise java >= 1.5 ? doesnt release a closed file object immediately System.gc(); for (int i = 0; i < 10000; i++) if ( oldfile.renameTo(newfile) ) return true; setMessage(Resource.getString("common.rename_error1") + " '" + oldfile.toString() + "' " + Resource.getString("common.rename_error2") + " '" + newfile.toString() + "'", true, 0xFFE0E0); return false; } /** * */ public static boolean renameTo(String oldfile, String newfile) { return renameTo(new File(oldfile), new File(newfile)); } /** * */ public static String adaptString(int str, int len) { return adaptString(String.valueOf(str), len); } /** * */ public static String adaptString(String str, int len) { StringBuffer strbuf = new StringBuffer(str.trim()); while (strbuf.length() < len) strbuf.insert(0, "0"); return strbuf.toString(); } /** * */ public static String formatTime_1(long time_value) { time_format_1.setTimeZone(TimeZone.getTimeZone("GMT+0:00")); return time_format_1.format(new Date(time_value)); } /** * */ public static String formatTime_2(long time_value, long frame_rate) { time_format_2.setTimeZone(TimeZone.getTimeZone("GMT+0:00")); String time_str = time_format_2.format(new Date(time_value)); return (time_str.substring(0, time_str.length() - 3) + adaptString((Integer.parseInt(time_str.substring(time_str.length() - 3)) * 90 / (int)frame_rate), 2)); } /** * */ public static String formatTime_3(long time_value) { //time_format_3.setTimeZone(TimeZone.getTimeZone("GMT+0:00")); return time_format_3.format(new Date(time_value)); } /** * */ public static String formatTime_4(long time_value) { time_format_4.setTimeZone(TimeZone.getTimeZone("GMT+0:00")); return time_format_4.format(new Date(time_value)); } /** * */ public static Object[] getColorModels() { return subpicture_colormodels.toArray(); } /** * */ public static ArrayList getColorModelsList() { return subpicture_colormodels; } /** * */ private static ArrayList loadColorModels() { ArrayList list = new ArrayList(); list.add(Resource.getString("SubtitlePanel.Colormodel.Mode0")); list.add(Resource.getString("SubtitlePanel.Colormodel.Mode1")); list.add(Resource.getString("SubtitlePanel.Colormodel.Mode2")); URL url = Resource.getResourceURL(COLOUR_TABLES_FILENAME); if (url == null) return list; try { BufferedReader table = new BufferedReader(new InputStreamReader(url.openStream())); String line; while( (line = table.readLine()) != null) { if ( line.trim().length() == 0 ) continue; if ( line.startsWith("table") ) list.add( (line.substring( line.indexOf("=") + 1)).trim() ); } table.close(); } catch (IOException e) { System.err.println("IOException loadColorModels " + e); } if (list.size() <= 3) canAccessColorTable = false; return list; } /** * */ public static Hashtable getUserColourTable(String model) throws IOException { Hashtable user_table = new Hashtable(); URL url = Resource.getResourceURL(COLOUR_TABLES_FILENAME); if ( url == null ) return user_table; BufferedReader table = new BufferedReader( new InputStreamReader(url.openStream())); String line; boolean table_match = false; while( (line = table.readLine()) != null) { if ( line.trim().length() == 0 ) continue; if ( line.startsWith("table") ) table_match = line.substring( line.indexOf("=") + 1).trim().equals(model); else if (table_match) { if ( line.startsWith("model") ) user_table.put( "model", line.substring( line.indexOf("=") + 1).trim() ); else user_table.put( line.substring(0, line.indexOf("=")).trim(), line.substring( line.indexOf("=") + 1).trim() ); } } table.close(); if ( !user_table.isEmpty() && !user_table.containsKey("model") ) user_table.put( "model", "16"); return user_table; } /** * Loads the ac3.bin file. */ public static void loadAC3() { AudioFormat audio = new AudioFormat(CommonParsing.AC3_AUDIO); AC3list.clear(); try { URL url = Resource.getResourceURL(AC3_FILENAME); if (url != null) { BufferedInputStream bis = new BufferedInputStream(url.openStream()); ByteArrayOutputStream bao = new ByteArrayOutputStream(); byte[] buff = new byte[1024]; int bytesRead = -1; while ((bytesRead = bis.read(buff, 0, buff.length)) != -1) bao.write(buff, 0, bytesRead); byte[] check = bao.toByteArray(); setMessage(Resource.getString("ac3.msg.loading.start")); int a = 0, frame_counter = 0; while (a < check.length) { audio.parseHeader(check, a); setMessage("(" + frame_counter + ") " + audio.saveAndDisplayHeader()); byte[] ac3data = new byte[audio.getSize()]; System.arraycopy(check, a, ac3data, 0, audio.getSize()); AC3list.add(ac3data); a += audio.Size; frame_counter++; } check = null; } } catch (IOException e5) { setExceptionMessage(e5); AC3list.clear(); } if (AC3list.size() > 0) setMessage(Resource.getString("ac3.msg.frames", "" + AC3list.size())); else canAccessSilentAC3 = false; } /** * Returns the AC3list. * * @return ArrayList */ public static List getAC3list() { return AC3list; } public static Object[] getFonts() { Object[] fonts = new Object[0]; try { fonts = (Object[]) GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); } catch (Exception exc) { System.out.println(Resource.getString("SubtitlePanel.Font.LoadError") + ": " + exc); } catch (Error err) { System.out.println(Resource.getString("SubtitlePanel.Font.LoadError") + ": " + err); } return fonts; } /** * */ public static void appendLogMessage(String str) { messagelog += getLineSeparator() + str; } /** * */ public static void clearMessageLog() { messagelog = ""; ErrorCount = 0; } /** * */ public static String getMessageLog() { return messagelog; } /** * */ public static int getErrorCount() { return ErrorCount; } /** * messages * * @param1 - the msg */ public static void setMessage(Object[] obj) { for (int i = 0; obj != null && i < obj.length; i++) setMessage(obj[i].toString()); } /** * messages * * @param1 - the msg */ public static void setMessage(String msg) { setMessage(msg, false); } /** * messages of interest, also with current systems time_index * * @param1 - the msg * @param2 - force windows visibility */ public static void setMessage(String msg, boolean tofront) { setMessage(msg, tofront, -1); } /** * messages of interest, also with current systems time_index * * @param1 - the msg * @param2 - force windows visibility */ public static void setMessage(String msg, boolean tofront, int background) { if (msg == null) { if (!isRunningCLI()) { if (getGuiInterface() != null) getGuiInterface().setMessage(msg, tofront, background); else System.out.println(msg); } return; } if (msg.startsWith("!>")) { ErrorCount++; if (MaxLog && ErrorCount > 500) return; } if (MaxLog && ErrorCount == 500) msg += getLineSeparator() + Resource.getString("all.msg.error.max"); if (TimeLog) msg = "[" + formatTime_1(System.currentTimeMillis()) + "] " + msg; if (getGlobalDebug()) System.out.println(msg); if (isRunningCLI() || getGuiInterface() == null) System.out.println(msg); else getGuiInterface().setMessage(msg, tofront, background); appendLogMessage(msg); } /** * messages * * @param1 - the msg */ public static void setExceptionMessage(Exception exc) { StringWriter sw = new StringWriter(); exc.printStackTrace(new PrintWriter(sw)); setErrorMessage(sw.toString()); } /** * messages * * @param1 - the msg */ public static void setErrorMessage(Error err) { StringWriter sw = new StringWriter(); err.printStackTrace(new PrintWriter(sw)); setErrorMessage(sw.toString()); } /** * messages * * @param1 - the msg */ public static void setErrorMessage(String str) { /** * show error messge */ setMessage(""); setMessage("!> an error has occured.. (please inform the authors at 'forum.dvbtechnics.info')"); setMessage(str, true, 0xFFE0E0); } /** * messages * * @param1 - the msg */ public static void setOSDMessage(String str) { setOSDMessage(str, false); } /** * messages * * @param1 - the msg */ public static void setOSDErrorMessage(String str) { setOSDMessage(str, true); } /** * messages * * @param1 - the msg * @param2 - is error */ public static void setOSDMessage(String str, boolean b) { getGuiInterface().setOSDMessage(str, b); } /** * post commands */ public static void performCommand(String str) { if (str == null || str.trim().length() == 0) return; try { Runtime.getRuntime().exec(str); } catch (Exception ex) { setExceptionMessage(ex); } } /** * post commands */ public static void performPostCommand(Object[] lastlist) { if (!getSettings().getBooleanProperty(Keys.KEY_enablePostProcessing)) return; String cmdl = ""; switch (getSettings().getIntProperty(Keys.KEY_ConversionMode)) { case CommonParsing.ACTION_DEMUX: cmdl = getSettings().getProperty(Keys.KEY_PostCommands_Cmd4); break; case CommonParsing.ACTION_TO_VDR: cmdl = getSettings().getProperty(Keys.KEY_PostCommands_Cmd5); break; case CommonParsing.ACTION_TO_M2P: cmdl = getSettings().getProperty(Keys.KEY_PostCommands_Cmd6); break; case CommonParsing.ACTION_TO_PVA: cmdl = getSettings().getProperty(Keys.KEY_PostCommands_Cmd7); break; case CommonParsing.ACTION_TO_TS: cmdl = getSettings().getProperty(Keys.KEY_PostCommands_Cmd8); default: return; } cmdl = cmdl.trim(); if (cmdl.length() > 0 && lastlist.length > 0) { ArrayList argList = new ArrayList(); String append_str = ""; boolean isQuoted = false; int appending = cmdl.lastIndexOf(" \"?"); if (appending < 0) appending = cmdl.lastIndexOf(" ?"); else isQuoted = true; if (appending < 0) argList.add(cmdl.trim()); else { append_str = cmdl.substring(appending).replace('"', ' ').trim(); cmdl = cmdl.substring(0, appending).trim(); argList.add(cmdl); appending = Integer.parseInt(append_str.substring(1)); if (appending == 0 || appending > lastlist.length) appending = lastlist.length; for (int l = 0; l < lastlist.length && l < appending; l++) { String str = lastlist[l].toString(); str = str.substring(str.indexOf("'") + 1, str.length() - 1); if (isQuoted) argList.add("" + (char)34 + str + (char)34); else argList.add(str); } } String commandline = ""; String[] arguments = new String[argList.size()]; for (int l = 0; l < arguments.length; l++) { arguments[l] = argList.get(l).toString(); commandline += l == 0 ? "" : " "; commandline += arguments[l]; } setMessage(Resource.getString("working.post.command") + " {" + commandline + "}"); try { Runtime.getRuntime().exec(arguments); } catch (IOException re) { setExceptionMessage(re); } argList = null; } } /** * should support loading of supported URLs/files via CLI */ public static XInputFile getInputFile(String value) { XInputFile inputValue = null; URL url = null; if (value == null) return null; try { url = new URL(value); String protocol = url.getProtocol(); if (protocol.equals("ftp")) { XInputDirectory xid = new XInputDirectory(url); XInputFile[] xif = xid.getFiles(); for (int i = 0; i < xif.length; i++) { if ( new URL(xif[i].toString()).getFile().equals(url.getFile()) ) { inputValue = xif[i]; break; } } } else if (protocol.equals("file")) inputValue = new XInputFile(new File(url.getHost() + url.getFile())); else System.out.println("!> Protocol not yet supported: " + protocol); return inputValue; } catch (Exception u1) {} try { File f = new File(value); if (f.exists()) { inputValue = new XInputFile(f); return inputValue; } } catch (Exception e) { System.out.println("local Filesystem access: '" + value + "' > " + e); } try { inputValue = new XInputFile(value); return inputValue; } catch (Exception e) { System.out.println("ext. Filesystem access: '" + value + "' > " + e); } return null; } /** * show java EV */ public static Object[] getJavaEV(String inifile) { List list = new ArrayList(); list.add("Java Environment"); list.add(getDateAndTime()); list.add(Resource.getString("javaev.java.version") + "\t" + System.getProperty("java.version")); list.add(Resource.getString("javaev.java.vendor") + "\t" + System.getProperty("java.vendor")); list.add(Resource.getString("javaev.java.home") + "\t" + System.getProperty("java.home")); list.add(Resource.getString("javaev.java.vm.version") + "\t" + System.getProperty("java.vm.version")); list.add(Resource.getString("javaev.java.vm.vendor") + "\t" + System.getProperty("java.vm.vendor")); list.add(Resource.getString("javaev.java.vm.name") + "\t" + System.getProperty("java.vm.name")); list.add(Resource.getString("javaev.java.class.vers") + "\t" + System.getProperty("java.class.version")); list.add(Resource.getString("javaev.java.class.path") + "\t" + System.getProperty("java.class.path")); list.add(Resource.getString("javaev.java.os.name") + "\t" + System.getProperty("os.name")); list.add(Resource.getString("javaev.java.os.arch") + "\t" + System.getProperty("os.arch")); list.add(Resource.getString("javaev.java.os.version") + "\t" + System.getProperty("os.version")); list.add(Resource.getString("javaev.java.ini.file") + "\t" + inifile); String str = (new RawInterface("")).GetLoadStatus(); if (str == null) { str = Resource.getString("rawread.msg1"); canAccessRawread = false; } list.add(Resource.getString("javaev.java.disk.access") + "\t" + str); list.add(Resource.getString("javaev.java.user.lang") + "\t" + Resource.getChosenLanguage()); list.add(Resource.getString("javaev.java.user.name") + "\t" + System.getProperty("user.name")); list.add(Resource.getString("javaev.java.user.home") + "\t" + System.getProperty("user.home")); return list.toArray(); } /** * */ public static String getDataTroughput() { long val = (Data_Troughput[1] - Data_Troughput[0]) / 1024L; Data_Troughput[1] = Data_Troughput[0] = 0; return String.valueOf(val < 0 ? 0 : val); } /** * */ public static String getFps() { int val = FpsValue[1] - FpsValue[0]; FpsValue[1] = FpsValue[0] = 0; return String.valueOf(val < 0 ? 0 : val); } /** * */ public static void setFps(int val) { if (FpsValue[0] == 0) FpsValue[1] = FpsValue[0] = val; else FpsValue[1] = val; } /** * */ public static String getExportedSize() { JobCollection collection = getCollection(getProcessedCollection()); long val = collection == null || collection.getJobProcessing() == null ? 0 : collection.getJobProcessing().getMediaFilesExportLength() / 1048576L; return String.valueOf(val) + " MB - " + SplitPart; } /** * */ public static void showSplitPart(int value) { SplitPart = value; } /** * progress */ public static int getProcessedPercent() { return ProcessedPercent; } /** * progress * * @param1 - the msg */ public static void updateProgressBar(long position, long size) { if (Data_Troughput[0] == 0) Data_Troughput[1] = Data_Troughput[0] = position; else Data_Troughput[1] = position; if (size <= 0) size = 1; int percent = (int)(position * 100 / size) + 1; if (percent == ProcessedPercent) return; ProcessedPercent = percent; getGuiInterface().updateProgressBar(ProcessedPercent); } /** * progress * * @param1 - the msg */ public static void updateProgressBar(String str) { setStatusString(str); getGuiInterface().updateProgressBar(str); } /** * progress * * @param1 - the msg * @param2 - % */ public static void updateProgressBar(String str, long position, long size) { if (str != null) updateProgressBar(str); updateProgressBar(position, size); } /** * */ public static String getStatusString() { return StatusString; } /** * */ public static void setStatusString(String str) { StatusString = str; } /** * Checks the latest version of Project-X */ public static void checkVersion() { try { URL url = new URL("http://project-x.sourceforge.net/update/update.txt"); URLConnection urlConn = url.openConnection(); BufferedReader br = new BufferedReader(new InputStreamReader(urlConn.getInputStream())); String line = br.readLine(); String version = line; String date = null; if (line != null) { StringTokenizer st = new StringTokenizer(line, ";"); if (st.hasMoreTokens()) version = st.nextToken(); if (st.hasMoreTokens()) date = st.nextToken(); } if (date != null) version += "\n" + date; getGuiInterface().showMessageDialog(Resource.getString("help.version.info") + "\n"+version, Resource.getString("help.version.info.title")); } catch(Exception e) { setExceptionMessage(e); } } /** * */ public static void getMainFrameBounds() { Rectangle rect = (Rectangle) getGuiInterface().getMainFrameBounds(); if (rect != null) { getSettings().setIntProperty(Keys.KEY_WindowPositionMain_X[0], (int) rect.getX()); getSettings().setIntProperty(Keys.KEY_WindowPositionMain_Y[0], (int) rect.getY()); getSettings().setIntProperty(Keys.KEY_WindowPositionMain_Width[0], (int) rect.getWidth()); getSettings().setIntProperty(Keys.KEY_WindowPositionMain_Height[0], (int) rect.getHeight()); } } /** * */ public static void showMainFrame(boolean b) { getGuiInterface().showMainFrame(b); } /** * */ public static void setFrameTitle(String str) { getGuiInterface().setMainFrameTitle(str); } /** * */ public static void addCollectionAtEnd() { if (getGuiInterface() != null) getGuiInterface().addCollectionAtEnd(); } /** * refresh inputfileslist */ public static Object[] reloadInputDirectories() { ArrayList arraylist = new ArrayList(); ArrayList input_directories = Common.getSettings().getInputDirectories(); for (int a = 0; a < input_directories.size(); a++) { // Get input files Object item = input_directories.get(a); XInputDirectory xInputDirectory = (XInputDirectory) item; XInputFile[] addlist = xInputDirectory.getFiles(); // Sort them if (addlist.length > 0) { class MyComparator implements Comparator { public int compare(Object o1, Object o2) { return o1.toString().compareTo(o2.toString()); } } Arrays.sort(addlist, new MyComparator()); } // Add them to the list for (int b = 0; b < addlist.length; b++) arraylist.add(addlist[b]); } try { // Get input files from topfield raw disk access XInputDirectory xInputDirectory = new XInputDirectory(DirType.RAW_DIR); XInputFile[] addlist = xInputDirectory.getFiles(); // Sort them if (addlist.length > 0) { class MyComparator implements Comparator { public int compare(Object o1, Object o2) { return o1.toString().compareTo(o2.toString()); } } Arrays.sort(addlist, new MyComparator()); } // Add them to the list for (int b = 0; b < addlist.length; b++) arraylist.add(addlist[b]); } catch (Throwable t) { // Assume no dll available or no hd or no file, so do nothing! } return (arraylist.isEmpty() ? new Object[0] : arraylist.toArray()); } }project-x/src/net/sourceforge/dvb/projectx/common/GuiInterface.java0000600000175000017500000001570510351105514027133 0ustar supermariosupermario/* * @(#)GuiInterface.java * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.common; import net.sourceforge.dvb.projectx.common.GuiInterfaceIF; public class GuiInterface implements GuiInterfaceIF { private GuiInterfaceIF impl = null; private boolean accessible = false; public GuiInterface() {} /** * */ public GuiInterface(boolean loadGUI) { getImplementation(loadGUI); } /** * */ private void getImplementation(boolean loadGUI) { try { if (loadGUI) { impl = (GuiInterfaceIF) Class.forName("net.sourceforge.dvb.projectx.gui.GuiInterfaceImpl").newInstance(); accessible = true; } } catch (Exception e) { // no gui class found } } /** * */ public boolean isAvailable() { return accessible; } /** * load main stuff */ public void loadGui() { if (isAvailable()) impl.loadGui(); } /** * */ public void showTtxPageMatrix() { if (isAvailable()) impl.showTtxPageMatrix(); } /** * */ public void initTtxPageMatrix(String str) { if (isAvailable()) impl.initTtxPageMatrix(str); } /** * */ public void updateTtxPageMatrix(String str) { if (isAvailable()) impl.updateTtxPageMatrix(str); } /** * */ public void showPreSettings() { if (isAvailable()) impl.showPreSettings(); } /** * */ public void resetBitrateMonitor() { if (isAvailable()) impl.resetBitrateMonitor(); } /** * */ public void updateBitrateMonitor(int value, byte[] array, String str) { if (isAvailable()) impl.updateBitrateMonitor(value, array, str); } /** * */ public void updateTtxHeader(String str) { if (isAvailable()) impl.updateTtxHeader(str); } /** * */ public void updateVpsLabel(String str) { if (isAvailable()) impl.updateVpsLabel(str); } /** * */ public void showAVOffset(String str) { if (isAvailable()) impl.showAVOffset(str); } /** * */ public void showExportStatus(String str) { if (isAvailable()) impl.showExportStatus(str); } /** * */ public void showExportStatus(String str, int value) { if (isAvailable()) impl.showExportStatus(str, value); } /** * */ public void updateProgressBar(int percent) { if (isAvailable()) impl.updateProgressBar(percent); else System.out.print("\r" + percent + " %"); } /** * */ public void updateProgressBar(String str) { if (isAvailable()) impl.updateProgressBar(str); else System.out.println(str); } /** * */ public void setMessage(String msg, boolean tofront, int background) { if (isAvailable()) impl.setMessage(msg, tofront, background); } /** * */ public void addPidToExtract(Object obj) { if (isAvailable()) impl.addPidToExtract(obj); } /** * */ public void closeLogWindow() { if (isAvailable()) impl.closeLogWindow(); } /** * */ public void showLogWindow() { if (isAvailable()) impl.showLogWindow(); } /** * */ public String getUserInputDialog(String arg1, String arg2) { return (isAvailable() ? impl.getUserInputDialog(arg1, arg2) : null); } /** * */ public boolean getUserConfirmationDialog(String str) { return (isAvailable() ? impl.getUserConfirmationDialog(str) : false); } /** * */ public void showErrorMessageDialog(Object message, String title) { if (isAvailable()) impl.showErrorMessageDialog(message, title); else { System.err.println(title); System.err.println(message.toString()); } } /** * */ public void showMessageDialog(Object message, String title) { if (isAvailable()) impl.showMessageDialog(message, title); else { System.out.println(title); System.out.println(message.toString()); } } /** * */ public Object getMainFrameBounds() { if (isAvailable()) return impl.getMainFrameBounds(); return null; } /** * */ public void showMainFrame(boolean b) { if (isAvailable()) impl.showMainFrame(b); } /** * */ public void setMainFrameTitle(String str) { if (isAvailable()) impl.setMainFrameTitle(str); } /** * */ public void resetMainFrameTitle() { if (isAvailable()) impl.resetMainFrameTitle(); } /** * */ public void addCollectionAtEnd() { if (isAvailable()) impl.addCollectionAtEnd(); } /** * */ public void showActiveCollection(int index) { if (isAvailable()) impl.showActiveCollection(index); } /** * */ public void updateCollectionPanel(int index) { if (isAvailable()) impl.updateCollectionPanel(index); } /** * */ public void setSubpictureTitle(String str) { if (isAvailable()) impl.setSubpictureTitle(str); } /** * */ public void showSubpicture() { if (isAvailable()) impl.showSubpicture(); } /** * */ public void hideSubpicture() { if (isAvailable()) impl.hideSubpicture(); } /** * */ public boolean isSubpictureVisible() { if (isAvailable()) return impl.isSubpictureVisible(); return false; } /** * */ public void repaintSubpicture() { if (isAvailable()) impl.repaintSubpicture(); } /** * */ public void setOSDMessage(String str, boolean b) { if (isAvailable()) impl.setOSDMessage(str, b); } /** * */ public void showCutIcon(boolean b, Object[] obj, Object list) { if (isAvailable()) impl.showCutIcon(b, obj, list); } /** * */ public void showChapterIcon(Object[] obj, Object list) { if (isAvailable()) impl.showChapterIcon(obj, list); } /** * */ public void updatePreviewPixel() { if (isAvailable()) impl.updatePreviewPixel(); } /** * */ public void repaintPicturePanel() { if (isAvailable()) impl.repaintPicturePanel(); } } project-x/src/net/sourceforge/dvb/projectx/common/GuiInterfaceIF.java0000600000175000017500000000547710351105524027360 0ustar supermariosupermario/* * @(#)GuiInterfaceIF.java * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.common; public interface GuiInterfaceIF { public void loadGui(); public void showTtxPageMatrix(); public void initTtxPageMatrix(String str); public void updateTtxPageMatrix(String str); public void showPreSettings(); public void resetBitrateMonitor(); public void updateBitrateMonitor(int value, byte[] array, String str); public void updateTtxHeader(String str); public void updateVpsLabel(String str); public void showAVOffset(String str); public void showExportStatus(String str); public void showExportStatus(String str, int value); public void updateProgressBar(int percent); public void updateProgressBar(String str); public void setMessage(String msg, boolean tofront, int background); public void addPidToExtract(Object obj); public void closeLogWindow(); public void showLogWindow(); public String getUserInputDialog(String arg1, String arg2); public boolean getUserConfirmationDialog(String str); public void showErrorMessageDialog(Object message, String title); public void showMessageDialog(Object message, String title); public Object getMainFrameBounds(); public void showMainFrame(boolean b); public void setMainFrameTitle(String str); public void resetMainFrameTitle(); public void addCollectionAtEnd(); public void showActiveCollection(int index); public void updateCollectionPanel(int index); public void setSubpictureTitle(String str); public void showSubpicture(); public void hideSubpicture(); public boolean isSubpictureVisible(); public void repaintSubpicture(); public void setOSDMessage(String str, boolean b); public void showCutIcon(boolean b, Object[] obj, Object list); public void showChapterIcon(Object[] obj, Object list); public void updatePreviewPixel(); public void repaintPicturePanel(); } project-x/src/net/sourceforge/dvb/projectx/common/JobCollection.java0000600000175000017500000004445310367304644027332 0ustar supermariosupermario/* * @(#)JobCollection.java - all about a collection * * Copyright (c) 2005-2006 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.common; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Hashtable; import java.io.File; import java.io.RandomAccessFile; import java.io.PrintStream; import java.io.PrintWriter; import java.io.IOException; import java.io.FileOutputStream; import java.io.ByteArrayInputStream; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.common.Settings; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.parser.Gop; import net.sourceforge.dvb.projectx.parser.GopArray; import net.sourceforge.dvb.projectx.parser.CommonParsing; //import net.sourceforge.dvb.projectx.thirdparty.D2V; //import net.sourceforge.dvb.projectx.thirdparty.Chapters; /** * saves all stuff of a collection */ public class JobCollection extends Object { private List cut_points = null; private List chapter_points = null; private List input_files = null; private List predefined_IDs = null; private String output_directory = null; private String output_name = null; private String normalLog = null; private String file_separator = System.getProperty("file.separator"); private String line_separator = System.getProperty("line.separator"); private boolean debug = false; private boolean progress_status = false; private int primaryInputFileSegments = 0; private int action_type = -1; private PrintStream logging; private JobProcessing job_processing; private Hashtable cut_images; private Settings settings; /** * */ private JobCollection() {} /** * */ public JobCollection(String _output_directory) { cut_points = new ArrayList(); chapter_points = new ArrayList(); input_files = new ArrayList(); predefined_IDs = new ArrayList(); init(_output_directory, "", action_type); } /** * */ public JobCollection(String _output_directory, String _output_name, int _action_type, List _cut_points, List _chapter_points, List _input_files, List _predefined_IDs) { cut_points = copyListElements(_cut_points); chapter_points = copyListElements(_chapter_points); input_files = copyListElements(_input_files); predefined_IDs = copyListElements(_predefined_IDs); init(_output_directory, _output_name, _action_type); } /** * */ private void init(String _output_directory, String _output_name, int _action_type) { setOutputDirectory(_output_directory); setOutputName(_output_name); normalLog = ""; action_type = _action_type; cut_images = new Hashtable(); } /** * */ private List copyListElements(List sourceList) { List list = new ArrayList(); for (int i = 0; i < sourceList.size(); i++) list.add(sourceList.get(i)); return list; } /** * */ public JobCollection getNewInstance() { return (new JobCollection(output_directory, output_name, action_type, cut_points, chapter_points, input_files, predefined_IDs)); } /** * init the process and all variables */ public void startProcessing(boolean b) { progress_status = true; job_processing = new JobProcessing(this, b, getOutputDirectory()); } /** * finish the process and all objects */ public void finishProcessing() { progress_status = false; if (job_processing != null) { job_processing.finishProcessing(); setOutputDirectory(job_processing.getSavedOutputDirectory()); } job_processing = null; } /** * check if a process from this coll is running * hinder some modifications of files and so on */ public boolean isActive() { return progress_status; } /** * */ public String getFileSeparator() { return file_separator; } /** * */ public JobProcessing getJobProcessing() { return job_processing; } /** * */ public void addInputFile(Object input) { addInputFile(-1, input); } /** * */ public void addInputFile(Object[] input) { for (int i = 0; i < input.length; i++) addInputFile(input[i]); } /** * */ public void addInputFile(int index, Object input) { if (isActive()) return; if (index < 0) index = input_files.size(); input_files.add(index, input); determinePrimaryFileSegments(); } /** * */ public Object removeInputFile(int index) { if (isActive()) return null; if (index < 0 || index >= getInputFilesCount()) return null; Object obj = input_files.remove(index); determinePrimaryFileSegments(); return obj; } /** * remove file index, start with last */ public Object[] removeInputFile(int[] index) { if (isActive()) return null; Object[] objects = new Object[index.length]; for (int i = index.length - 1; i >= 0; i--) objects[i] = removeInputFile(index[i]); return objects; } /** * */ public void determinePrimaryFileSegments() { int primaryFilesCount = 0; // at least one file is primary boolean completed = false; XInputFile xInputFile; filesearch: for (int i = 0, j = -1, stream_type = -1, k = getInputFilesCount(); i < k; i++) { xInputFile = (XInputFile) getInputFile(i); if (xInputFile.getStreamInfo() == null) Common.getScanClass().getStreamInfo(xInputFile); // continue loop to scan all files for later use if (completed) continue; stream_type = xInputFile.getStreamInfo().getStreamType(); switch (stream_type) { case CommonParsing.TS_TYPE: case CommonParsing.PES_AV_TYPE: case CommonParsing.PES_MPA_TYPE: case CommonParsing.PES_PS1_TYPE: case CommonParsing.MPEG1PS_TYPE: case CommonParsing.MPEG2PS_TYPE: case CommonParsing.PVA_TYPE: if (j != -1 && j != stream_type) { completed = true; continue; } break; default: continue; } j = stream_type; primaryFilesCount++; } setPrimaryInputFileSegments(primaryFilesCount); } /** * */ public Object getInputFile(int index) { return input_files.get(index); } /** * */ public Object[] getInputFiles() { return input_files.toArray(); } /** * */ public List getInputFilesAsList() { return input_files; } /** * */ public int getInputFilesCount() { return input_files.size(); } /** * */ public int getCutpointCount() { return cut_points.size(); } /** * */ public int getChapterpointCount() { return chapter_points.size(); } /** * */ public int getPIDCount() { return predefined_IDs.size(); } /** * */ public List getCutpointList() { return cut_points; } /** * */ public List getChapterpointList() { return chapter_points; } /** * */ public String getOutputNameParent(String str) { int index; if ( (index = str.lastIndexOf(".")) < 0) return (getOutputDirectory() + getFileSeparator() + str); return (getOutputDirectory() + getFileSeparator() + str.substring(0, index)); } /** * */ public String getOutputDirectory() { return output_directory; } /** * */ public void setOutputDirectory(String value) { if (value.endsWith(getFileSeparator())) output_directory = value.substring(0, value.length() - 1); else output_directory = value; } /** * */ public String checkOutputDirectory() { String str = output_directory; if (str == null || str.length() == 0) { if (input_files.size() == 0) return ""; str = new File(input_files.get(0).toString()).getParent(); } if (checkWriteAccess(str)) { output_directory = str; return null; } return str; } /** * check write access */ private boolean checkWriteAccess(String path) { File _path = new File(path); String _file = path + getFileSeparator() + "~$pjx$.tmp"; if (path == null || !_path.exists()) return false; try { RandomAccessFile raf = new RandomAccessFile(_file, "rw"); raf.close(); new File(_file).delete(); } catch (IOException e) { return false; } return true; } /** * */ public String getOutputName() { return output_name; } /** * */ public String getOutputName(String str) { if (output_name.length() > 0) return getOutputName(); return str; } /** * */ public void setOutputName(String str) { output_name = str; } /** * */ public void addPID(Object value) { if (!predefined_IDs.contains(value)) predefined_IDs.add(value); } /** * */ public void addPID(Object[] values) { for (int i = 0; i < values.length; i++) addPID(values[i]); } /** * */ public void clearPIDs() { predefined_IDs.clear(); } /** * */ public void removePID(Object value) { int index; if ((index = predefined_IDs.indexOf(value)) < 0) return; predefined_IDs.remove(index); } /** * */ public void removePID(Object[] values) { for (int i = 0; i < values.length; i++) removePID(values[i]); } /** * */ public Object[] getPIDs() { return predefined_IDs.toArray(); } /** * */ public int[] getPIDsAsInteger() { int len = predefined_IDs == null ? 0 : predefined_IDs.size(); int[] array = new int[len]; for (int i = 0; i < len; i++) array[i] = Integer.parseInt(predefined_IDs.get(i).toString().substring(2), 16); return array; } /** * */ public void addCutpoint(Object value) { if (!cut_points.contains(value)) cut_points.add(value); } /** * */ public void addCutpoint(int index, Object value) { cut_points.add(index, value); } /** * */ public void addCutpoint(Object[] values) { for (int i = 0; i < values.length; i++) addCutpoint(values[i]); } /** * */ public void clearCutpoints() { cut_points.clear(); } /** * */ public Object removeCutpoint(int index) { if (index < 0 || index >= cut_points.size()) return null; Object obj = cut_points.remove(index); removeCutImage(obj); return obj; } /** * */ public Object[] getCutpoints() { return cut_points.toArray(); } /** * */ public void addChapterpoint(Object value) { if (!chapter_points.contains(value)) chapter_points.add(value); } /** * */ public void addChapterpoint(int index, Object value) { chapter_points.add(index, value); } /** * */ public void addChapterpoint(Object[] values) { for (int i = 0; i < values.length; i++) addChapterpoint(values[i]); } /** * */ public void clearChapterpoints() { chapter_points.clear(); } /** * */ public Object removeChapterpoint(int index) { if (index < 0 || index >= chapter_points.size()) return null; Object obj = chapter_points.remove(index); return obj; } /** * */ public Object[] getChapterpoints() { return chapter_points.toArray(); } /** * */ public String getFirstFileBase() { return (getOutputDirectory() + getFirstFileName()); } /** * */ public String getFirstFileName() { String firstFileChild = new File(getInputFiles()[0].toString()).getName(); int index; if ( (index = firstFileChild.lastIndexOf(".")) != -1 ) firstFileChild = firstFileChild.substring(0, index); return firstFileChild; } /** * */ public long getFirstFileDate() { return ((XInputFile) getInputFiles()[0]).lastModified(); } /** * set log files */ public void setLogFiles() { String str = getOutputName(getFirstFileName()); if (Common.getSettings().getBooleanProperty(Keys.KEY_DebugLog)) { debug = true; setDebugLogStream(getOutputDirectory() + getFileSeparator() + str + "_biglog.txt"); } //settings bergeben!! if (Common.getSettings().getBooleanProperty(Keys.KEY_NormalLog)) { if (Common.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createVdrIndex) && Common.getSettings().getIntProperty(Keys.KEY_ConversionMode) == 1) normalLog = getOutputDirectory() + getFileSeparator() + "summary.vdr"; else normalLog = getOutputDirectory() + getFileSeparator() + str + "_log.txt"; } } /** * set systems log output for 'big log' */ private void setDebugLogStream(String str) { try { logging = new PrintStream(new FileOutputStream(str)); System.setOut(logging); } catch (IOException e) { Common.setExceptionMessage(e); } } /** * */ public void closeDebugLogStream() { if ( !Common.getSettings().getBooleanProperty(Keys.KEY_DebugLog)) return; if (logging != null) { logging.flush(); logging.close(); } debug = false; } /** * */ public void closeNormalLogStream(String str) { if ( !Common.getSettings().getBooleanProperty(Keys.KEY_NormalLog)) return; try { PrintWriter nlf = new PrintWriter(new FileOutputStream(normalLog)); nlf.print(str); nlf.close(); } catch (IOException e) { Common.setExceptionMessage(e); } } /** * */ public boolean DebugMode() { return debug; } /** * */ public void setPrimaryInputFileSegments(int val) { primaryInputFileSegments = val; } /** * */ public int getPrimaryInputFileSegments() { return primaryInputFileSegments; } /** * */ public int[] getCutImage(Object obj) { if (cut_images.containsKey(obj)) return ((int[]) cut_images.get(obj)); return null; } /** * */ public void setCutImage(String str, int[] data) { cut_images.put(str, data); } /** * */ public int[] removeCutImage(Object obj) { if (cut_images.containsKey(obj)) return ((int[]) cut_images.remove(obj)); return null; } /** * the coll table (gui only) */ public Object[][] getCollectionAsTable() { int size = getInputFilesCount(); Object[][] table = new Object[size > 5 ? size : 5][11]; for (int i = 0; i < size; i++) { XInputFile xInputFile = (XInputFile) getInputFile(i); table[i][0] = new Integer(i); table[i][1] = xInputFile.getStreamInfo().getFileSourceBase(); table[i][2] = xInputFile.getName(); table[i][3] = (xInputFile.getParent().length() > 0 ? xInputFile.getParent() : xInputFile.toString().substring(0, xInputFile.toString().indexOf(xInputFile.getName()))); table[i][4] = String.valueOf(xInputFile.length() / 1048576L) + " MB"; table[i][5] = Common.formatTime_3(xInputFile.lastModified()); table[i][6] = new Integer(xInputFile.getStreamInfo().getVideoStreams().length); table[i][7] = new Integer(xInputFile.getStreamInfo().getAudioStreams().length); table[i][8] = new Integer(xInputFile.getStreamInfo().getTeletextStreams().length); table[i][9] = new Integer(xInputFile.getStreamInfo().getSubpictureStreams().length); table[i][10] = xInputFile.getStreamInfo().getFileType(); } return table; } /** * */ public void setActionType(int value) { action_type = value; } /** * */ public int getActionType() { return action_type; } /** * */ public long getAllSizes() { long value = 0; for (int i = 0, j = getInputFilesCount(); i < j; i++) value += ((XInputFile) getInputFile(i)).length(); return (value / 1048576L); } /** * */ public String getShortSummary() { String str = isActive() ? Resource.getString("JobCollection.InProgress") : Resource.getString("JobCollection.Idle"); str += line_separator; str += Resource.getString("JobCollection.Action") + " " + (getActionType() < 0 ? Resource.getString("JobCollection.unspecified") : Keys.ITEMS_ConversionMode[getActionType()].toString()); str += line_separator; str += Resource.getString("JobCollection.PrimaryFileSegments") + " " + getPrimaryInputFileSegments(); str += line_separator; str += Resource.getString("JobCollection.SecondaryFiles") + " " + (getInputFilesCount() - getPrimaryInputFileSegments()); str += line_separator; str += Resource.getString("JobCollection.Cutpoints") + " " + getCutpointCount(); str += line_separator; str += Resource.getString("JobCollection.Chapters") + " " + getChapterpointCount(); str += line_separator; str += Resource.getString("JobCollection.PidSelection") + " " + getPIDCount(); str += line_separator; str += Resource.getString("JobCollection.OwnSettings") + " " + (settings != null ? Resource.getString("General.Yes") : Resource.getString("General.No")); str += line_separator; str += Resource.getString("JobCollection.AllSize")+ " " + getAllSizes() + "MB"; return str; } /** * routing returning settings */ public Settings getSettings() { if (settings == null) return Common.getSettings(); return settings; } /** * collection specific settings */ public void setSettings(Settings _settings) throws IOException { if (isActive()) return; settings = new Settings(); settings.loadProperties(new ByteArrayInputStream(_settings.storeProperties())); } } project-x/src/net/sourceforge/dvb/projectx/common/JobProcessing.java0000600000175000017500000003447310367305070027346 0ustar supermariosupermario/* * @(#)JobProcessing.java - used by a collection when processing it * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.common; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.io.File; import java.io.RandomAccessFile; import java.io.PrintStream; import java.io.PrintWriter; import java.io.IOException; import java.io.FileOutputStream; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.parser.Gop; import net.sourceforge.dvb.projectx.parser.GopArray; import net.sourceforge.dvb.projectx.thirdparty.D2V; import net.sourceforge.dvb.projectx.thirdparty.Chapters; /** * saves all stuff of a collection process */ public class JobProcessing extends Object { private Gop gop; private GopArray gop_array; private D2V d2v; private Chapters chapters; private List TSPidlist; private List PVAPidlist; private List TSdemuxlist; private List PVAdemuxlist; private List VDRdemuxlist; private List PESdemuxlist; private List TempFileList; private List InfoAtEnd; private List CellTimesList; private int[] clv; private int SourceVideoFrameNumber; private int ExportedVideoFrameNumber; private int FileNumber; private int NoOfAudio; private int NoOfPictures; private int NoOfTTX; private int MinBitrateValue; private int MaxBitrateValue; private int SplitPartNumber; private boolean newvideo; private boolean PureVideo; private boolean hasSequenceHeader; private boolean SplitLoopActive; private boolean runningFromCLI; private String[] VBASIC; private String savedOutputDirectory; private long firstVideoPTS; private long CUT_BYTEPOSITION; private long pva_videopts; private long fakedPTS; private long LastHeader_BytePosition; private long NextFileStartPts; private long CutComparePoint; private long VideoExportTimeCounter; private long VideoExportTimeSummary; private long LastGopTimecode; private long LastGopPts; private long FirstAudioPts; private long LastSimplifiedPts; private long EndPtsOfGop; private long ProjectFileExportLength; private long MediaFilesExportLength; private long AllMediaFilesExportLength; private long SplitPartSize; private long ProjectFileSplitSize; /** * */ public JobProcessing(JobCollection collection, boolean b, String str) { runningFromCLI = b; savedOutputDirectory = str; startProcessing(collection); } /** * init the process and all variables */ private void startProcessing(JobCollection collection) { TSPidlist = new ArrayList(); PVAPidlist = new ArrayList(); TSdemuxlist = new ArrayList(); PVAdemuxlist = new ArrayList(); VDRdemuxlist = new ArrayList(); PESdemuxlist = new ArrayList(); TempFileList = new ArrayList(); InfoAtEnd = new ArrayList(); CellTimesList = new ArrayList(); clv = new int[10]; gop = new Gop(collection); gop_array = new GopArray(); d2v = new D2V(); chapters = new Chapters(); SourceVideoFrameNumber = 0; ExportedVideoFrameNumber = 0; FileNumber = 0; newvideo = true; firstVideoPTS = -1; PureVideo = false; VBASIC = new String[5]; CUT_BYTEPOSITION = 0; hasSequenceHeader = true; pva_videopts = -1; NoOfAudio = 0; NoOfPictures = 0; NoOfTTX = 0; fakedPTS = -1; LastHeader_BytePosition = 0; NextFileStartPts = 0; CutComparePoint = 0; VideoExportTimeCounter = 0; VideoExportTimeSummary = 0; LastGopTimecode = 0; LastGopPts = 0; FirstAudioPts = 0; SplitLoopActive = true; MinBitrateValue = 262143; MaxBitrateValue = 0; LastSimplifiedPts = 0; SplitPartNumber = 0; SplitPartSize = 0; EndPtsOfGop = 0; ProjectFileSplitSize = 0; ProjectFileExportLength = 0; MediaFilesExportLength = 0; AllMediaFilesExportLength = 0; } /** * finish the process and all objects */ public void finishProcessing() { TSPidlist = null; PVAPidlist = null; TSdemuxlist = null; PVAdemuxlist = null; VDRdemuxlist = null; PESdemuxlist = null; TempFileList = null; InfoAtEnd = null; CellTimesList = null; clv = null; gop = null; gop_array = null; d2v = null; chapters = null; VBASIC = null; } /** * */ public boolean isRunningFromCLI() { return runningFromCLI; } /** * */ public List getTSPidList() { return TSPidlist; } /** * */ public List getPVAPidList() { return PVAPidlist; } /** * */ public List getTSDemuxList() { return TSdemuxlist; } /** * */ public List getPVADemuxList() { return PVAdemuxlist; } /** * */ public List getPrimaryPESDemuxList() { return PESdemuxlist; } /** * */ public List getSecondaryPESDemuxList() { return PESdemuxlist; } /** * */ public List getTemporaryFileList() { return TempFileList; } /** * */ public List getSummaryInfo() { return InfoAtEnd; } /** * */ public void clearSummaryInfo() { InfoAtEnd.clear(); } /** * */ public void addSummaryInfo(String str) { InfoAtEnd.add(str); } /** * */ public List getCellTimes() { return CellTimesList; } /** * */ public void addCellTime(String str) { CellTimesList.add(str); } /** * */ public int[] getStatusVariables() { return clv; } /** * */ public void clearStatusVariables() { Arrays.fill(clv, 0); } /** * */ public String[] getStatusStrings() { return VBASIC; } /** * */ public void clearStatusStrings() { Arrays.fill(VBASIC, null); } /** * */ public Gop getGop() { return gop; } /** * */ public D2V getProjectFileD2V() { return d2v; } /** * */ public Chapters getChapters() { return chapters; } /** * */ public void setSourceVideoFrameNumber(int val) { SourceVideoFrameNumber = val; } /** * */ public int countSourceVideoFrameNumber(int val) { SourceVideoFrameNumber += val; return SourceVideoFrameNumber; } /** * */ public int getSourceVideoFrameNumber() { return SourceVideoFrameNumber; } /** * */ public void setFileNumber(int val) { FileNumber = val; } /** * */ public int countFileNumber(int val) { FileNumber += val; return FileNumber; } /** * */ public int getFileNumber() { return FileNumber; } /** * */ public boolean isNewVideoStream() { return newvideo; } /** * */ public void setNewVideoStream(boolean b) { newvideo = b; } /** * */ public long get1stVideoPTS() { return firstVideoPTS; } /** * */ public void set1stVideoPTS(long val) { firstVideoPTS = val; } /** * */ public boolean hasElementaryVideoStream() { return PureVideo; } /** * */ public void setElementaryVideoStream(boolean b) { PureVideo = b; } /** * */ public long getCutByteposition() { return CUT_BYTEPOSITION; } /** * */ public void setCutByteposition(long val) { CUT_BYTEPOSITION = val; } /** * */ public boolean hasSequenceHeader() { return hasSequenceHeader; } /** * */ public void setSequenceHeader(boolean b) { hasSequenceHeader = b; } /** * */ public GopArray getGopArray() { return gop_array; } /** * */ public long getPvaVideoPts() { return pva_videopts; } /** * */ public void setPvaVideoPts(long val) { pva_videopts = val; } /** * */ public void clearSubStreamCounters() { NoOfAudio = 0; NoOfPictures = 0; NoOfTTX = 0; } /** * */ public int countAudioStream() { return (NoOfAudio++); } /** * */ public int countPictureStream() { return (NoOfPictures++); } /** * */ public int countTeletextStream() { return (NoOfTTX++); } /** * */ public long getBorrowedPts() { return fakedPTS; } /** * */ public void setBorrowedPts(long val) { fakedPTS = val; } /** * */ public long getLastHeaderBytePosition() { return LastHeader_BytePosition; } /** * */ public void setLastHeaderBytePosition(long val) { LastHeader_BytePosition = val; } /** * */ public long getNextFileStartPts() { return NextFileStartPts; } /** * */ public void setNextFileStartPts(long val) { NextFileStartPts = val; } /** * */ public long getCutComparePoint() { return CutComparePoint; } /** * */ public void setCutComparePoint(long val) { CutComparePoint = val; } /** * */ public void setVideoExportTime(long val) { VideoExportTimeCounter = val; } /** * */ public long countVideoExportTime(long val) { VideoExportTimeCounter += val; return VideoExportTimeCounter; } /** * */ public long getVideoExportTime() { return VideoExportTimeCounter; } /** * */ public void setVideoExportTimeSummary(long val) { VideoExportTimeSummary = val; } /** * */ public long countVideoExportTimeSummary(long val) { VideoExportTimeSummary += val; return VideoExportTimeSummary; } /** * */ public long getVideoExportTimeSummary() { return VideoExportTimeSummary; } /** * */ public void setLastGopTimecode(long val) { LastGopTimecode = val; } /** * */ public long countLastGopTimecode(long val) { LastGopTimecode += val; return LastGopTimecode; } /** * */ public long getLastGopTimecode() { return LastGopTimecode; } /** * */ public void setLastGopPts(long val) { LastGopPts = val; } /** * */ public long getLastGopPts() { return LastGopPts; } /** * */ public void setFirstAudioPts(long val) { FirstAudioPts = val; } /** * */ public long getFirstAudioPts() { return FirstAudioPts; } /** * */ public void setSplitLoopActive(boolean b) { SplitLoopActive = b; } /** * */ public boolean isSplitLoopActive() { return SplitLoopActive; } /** * determined bitrates */ public void setMinBitrate(int val) { MinBitrateValue = val; } /** * determined bitrates */ public int getMinBitrate() { return MinBitrateValue; } /** * determined bitrates */ public void setMaxBitrate(int val) { MaxBitrateValue = val; } /** * determined bitrates */ public int getMaxBitrate() { return MaxBitrateValue; } /** * pts build from video es */ public void setLastSimplifiedPts(long val) { LastSimplifiedPts = val; } /** * pts build from video es */ public long getLastSimplifiedPts() { return LastSimplifiedPts; } /** * */ public void setSplitPart(int val) { SplitPartNumber = val; } /** * */ public int getSplitPart() { return SplitPartNumber; } /** * */ public void setSplitSize(long val) { SplitPartSize = val; } /** * */ public long getSplitSize() { return SplitPartSize; } /** * */ public void setEndPtsOfGop(long val) { EndPtsOfGop = val; } /** * */ public long getEndPtsOfGop() { return EndPtsOfGop; } /** * */ public void setProjectFileSplitSize(long val) { ProjectFileSplitSize = val; } /** * */ public long getProjectFileSplitSize() { return ProjectFileSplitSize; } /** * */ public void setProjectFileExportLength(long val) { ProjectFileExportLength = val; } /** * */ public long countProjectFileExportLength(long val) { ProjectFileExportLength += val; return ProjectFileExportLength; } /** * */ public long getProjectFileExportLength() { return ProjectFileExportLength; } /** * */ public void setExportedVideoFrameNumber(int val) { ExportedVideoFrameNumber = val; } /** * */ public int countExportedVideoFrameNumber(int val) { ExportedVideoFrameNumber += val; return ExportedVideoFrameNumber; } /** * */ public int getExportedVideoFrameNumber() { return ExportedVideoFrameNumber; } /** * */ public void setMediaFilesExportLength(long val) { MediaFilesExportLength = val; } /** * */ public long countMediaFilesExportLength(long val) { MediaFilesExportLength += val; return MediaFilesExportLength; } /** * */ public long getMediaFilesExportLength() { return MediaFilesExportLength; } /** * */ public void setAllMediaFilesExportLength(long val) { AllMediaFilesExportLength = val; } /** * */ public long countAllMediaFilesExportLength(long val) { AllMediaFilesExportLength += val; return AllMediaFilesExportLength; } /** * */ public long getAllMediaFilesExportLength() { return AllMediaFilesExportLength; } /** * */ public String getSavedOutputDirectory() { return savedOutputDirectory; } } project-x/src/net/sourceforge/dvb/projectx/common/Keys.java0000600000175000017500000007065010412364210025477 0ustar supermariosupermario/* * @(#)Keys.java - static, fixed keys * * Copyright (c) 2005 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.common; import net.sourceforge.dvb.projectx.common.Resource; public class Keys extends Object { public final static String KEY_Tip = ".Tip"; /** * General */ public final static String[] KEY_Agreement = { "Application.Agreement", "0" }; //rbutton[1] public final static String[] KEY_ActiveDirectory = { "Application.ActiveDirectory", "" }; public final static String[] KEY_LookAndFeel = { "Application.LookAndFeel", "" }; public final static String[] KEY_InputDirectoriesDepth = { "Application.InputDirectoriesDepth", "0" }; public final static String KEY_InputDirectories = "Application.InputDirectories."; public final static String KEY_OutputDirectories = "Application.OutputDirectories."; public final static String[] KEY_OutputDirectory = { "Application.OutputDirectory", "" }; public final static String[] KEY_Language = { "Application.Language", "en" }; public final static String[] KEY_SaveSettingsOnExit = { "Application.SaveSettingsOnExit", "1" }; public final static String[] KEY_FtpServer_Commands = { "FtpServer.Commands", "" }; public final static String[] KEY_WindowPositionMain_X = { "WindowPosition.Main.X", "50" }; public final static String[] KEY_WindowPositionMain_Y = { "WindowPosition.Main.Y", "50" }; public final static String[] KEY_WindowPositionMain_Width = { "WindowPosition.Main.Width", "906" }; public final static String[] KEY_WindowPositionMain_Height = { "WindowPosition.Main.Height", "652" }; /** * PostCommands */ public final static String[] KEY_PostCommands_Cmd1 = { "PostCommands.Cmd1", "" }; public final static String[] KEY_PostCommands_Cmd2 = { "PostCommands.Cmd2", "" }; public final static String[] KEY_PostCommands_Cmd3 = { "PostCommands.Cmd3", "" }; public final static String[] KEY_PostCommands_Cmd4 = { "PostCommands.Cmd4", "" }; public final static String[] KEY_PostCommands_Cmd5 = { "PostCommands.Cmd5", "" }; public final static String[] KEY_PostCommands_Cmd6 = { "PostCommands.Cmd6", "" }; public final static String[] KEY_PostCommands_Cmd7 = { "PostCommands.Cmd7", "" }; public final static String[] KEY_PostCommands_Cmd8 = { "PostCommands.Cmd8", "" }; /** * MessagePanel */ public final static String[] KEY_MessagePanel_Msg1 = { "MessagePanel.logSequenceError", "1" }; //cbox[40] sequence error public final static String[] KEY_MessagePanel_Msg2 = { "MessagePanel.logMissingStartcode", "1" }; //cbox[3] missing startcode public final static String[] KEY_MessagePanel_Msg3 = { "MessagePanel.logESError", "1" }; //cbox[74] pes in es public final static String[] KEY_MessagePanel_Msg4 = { "MessagePanel.leadingTimeIndex", "0" }; //cbox[72] timeindex public final static String[] KEY_MessagePanel_Msg5 = { "MessagePanel.logWSS", "1" }; //WSS public final static String[] KEY_MessagePanel_Msg6 = { "MessagePanel.logVPS", "1" }; //VPS public final static String[] KEY_MessagePanel_Msg7 = { "MessagePanel.logRDS", "1" }; //RDS public final static String[] KEY_MessagePanel_Msg8 = { "MessagePanel.logErrorMaximum", "1" }; /** * MainPanel */ public static Object[] ITEMS_ConversionMode = null; public final static String[] KEY_ConversionMode = { "MainPanel.ConversionMode", "0" }; //combox[19], index public final static String[] KEY_ConversionModePriority = { "MainPanel.ConversionModePriority", "0" }; public final static String[] KEY_useAllCollections = { "MainPanel.useAllCollections", "0" }; //cbox[18] public final static String[] KEY_enablePostProcessing = { "MainPanel.enablePostProcessing", "0" }; //cbox[25] public final static String[] KEY_minimizeMainFrame = { "MessagePanel.minimizeMainFrame", "0" }; public final static String[] KEY_hideProcessWindow = { "MessagePanel.hideProcessWindow", "0" }; public final static String[] KEY_showSubpictureWindow = { "MessagePanel.showSubpictureWindow", "0" }; public final static String[] KEY_simpleMPG = { "MainPanel.simpleMPG", "0" }; //cbox[14] public final static String[] KEY_enhancedPES = { "MainPanel.enhancedPES", "0" }; //cbox[14] public final static String[] KEY_useAutoPidFilter = { "MainPanel.useAutoPidFilter", "0" }; /** * LogWindowPanel */ public final static String[] KEY_showTtxHeader = { "LogwindowPanel.showTtxHeader", "0" }; //cbox[19] /** * ExportPanel */ public final static String[] KEY_SplitSize = { "ExportPanel.SplitSize", "0" }; //cbox[5] public final static String[] KEY_Streamtype_MpgVideo = { "ExportPanel.Streamtype.MpgVideo", "1" }; //cbox[55] public final static String[] KEY_Streamtype_MpgAudio = { "ExportPanel.Streamtype.MpgAudio", "1" }; //cbox[56] public final static String[] KEY_Streamtype_Ac3Audio = { "ExportPanel.Streamtype.Ac3Audio", "1" }; //cbox[57] public final static String[] KEY_Streamtype_PcmAudio = { "ExportPanel.Streamtype.PcmAudio", "1" }; //cbox[58] public final static String[] KEY_Streamtype_Teletext = { "ExportPanel.Streamtype.Teletext", "1" }; //cbox[59] public final static String[] KEY_Streamtype_Subpicture = { "ExportPanel.Streamtype.Subpicture", "1" }; //cbox[60] public final static String[] KEY_Streamtype_Vbi = { "ExportPanel.Streamtype.Vbi", "1" }; //cbox[81] public final static String[] KEY_WriteOptions_writeVideo = { "ExportPanel.WriteOptions.writeVideo", "1" }; //cbox[6] public final static String[] KEY_WriteOptions_writeAudio = { "ExportPanel.WriteOptions.writeAudio", "1" }; //cbox[7] public final static String[] KEY_additionalOffset = { "ExportPanel.additionalOffset", "0" }; //cbox[8] public final static String[] KEY_ExportPanel_Export_Overlap = { "ExportPanel.Overlap", "0" }; public final static String[] KEY_ExportPanel_createSubDirNumber = { "ExportPanel.createSubDirNumber", "0" }; //cbox[2] public final static String[] KEY_ExportPanel_createSubDirName = { "ExportPanel.createSubDirName", "0" }; //cbox[71] public final static String[] KEY_ExportPanel_SplitSize_Value = { "ExportPanel.SplitSize.Value", "650" }; //combox[2] public final static String[] KEY_ExportPanel_Overlap_Value = { "ExportPanel.Overlap.Value", "0" }; //combox[25] public final static String[] KEY_ExportPanel_Infoscan_Value = { "ExportPanel.Infoscan.Value", "5" }; //combox[21] public final static String[] KEY_ExportPanel_additionalOffset_Value = { "ExportPanel.additionalOffset.Value", "0" }; //combobox[8], item public static Object[] ITEMS_Export_SplitSize = { "650", "700", "735", "792", "2000", "4700" }; public static Object[] ITEMS_Export_Overlap = { "1 MB", "2 MB", "3 MB", "4 MB", "5 MB", "6 MB", "7 MB", "8 MB", "9 MB", "10 MB" }; public static Object[] ITEMS_Infoscan = { "5", "10", "25" }; /** * OptionPanel */ public final static String[] KEY_DebugLog = { "OptionPanel.DebugLog", "0" }; //cbox[11] - group1 public final static String[] KEY_NormalLog = { "OptionPanel.NormalLog", "1" }; //cbox[21] -group1 public final static String[] KEY_dumpDroppedGop = { "OptionPanel.dumpDroppedGop", "0" }; //cbox[43] public final static String[] KEY_closeOnEnd = { "OptionPanel.closeOnEnd", "0" }; //cbox[78] public final static String[] KEY_StartPath_Value = { "OptionPanel.StartPath.Value", "" }; public final static String[] KEY_MainBuffer = { "OptionPanel.MainBuffer", "4096000" }; //combobox[10] public final static String[] KEY_ScanBuffer = { "OptionPanel.ScanBuffer", "1024000" }; //combobox[37] public final static String[] KEY_PreviewBuffer = { "OptionPanel.PreviewBuffer", "1024000" }; //combobox[38] public final static String[] KEY_holdStreamInfoOnOSD = { "OptionPanel.holdStreamInfoOnOSD", "0" }; public final static String[] KEY_OptionPanelIndex = { "OptionPanel.PanelIndex", "0" }; public final static String[] KEY_additionalInputBuffer = { "OptionPanel.additionalInputBuffer", "1" }; //test /** * SpecialPanel */ public final static String[] KEY_PVA_FileOverlap = { "SpecialPanel.PVA.FileOverlap", "0" }; //cbox[48] public final static String[] KEY_PVA_Audio = { "SpecialPanel.PVA.Audio", "1" }; //cbox[28], true public final static String[] KEY_VOB_resetPts = { "SpecialPanel.VOB.resetPts", "1" }; //cbox[76], true public final static String[] KEY_TS_ignoreScrambled = { "SpecialPanel.TS.ignoreScrambled", "1" }; //cbox[38], true public final static String[] KEY_TS_blindSearch = { "SpecialPanel.TS.blindSearch", "1" }; //cbox[61], true public final static String[] KEY_TS_joinPackets = { "SpecialPanel.TS.joinPackets", "1" }; //cbox[53], true public final static String[] KEY_TS_HumaxAdaption = { "SpecialPanel.TS.HumaxAdaption", "0" }; //cbox[70] public final static String[] KEY_TS_FinepassAdaption = { "SpecialPanel.TS.FinepassAdaption", "0" }; public final static String[] KEY_TS_generatePmt = { "SpecialPanel.TS.generatePmt", "1" }; //cbox[41], true public final static String[] KEY_TS_generateTtx = { "SpecialPanel.TS.generateTtx", "0" }; //cbox[42] --ts !! public final static String[] KEY_TS_setMainAudioAc3 = { "SpecialPanel.TS.setMainAudioAc3", "0" }; //cbox[37] --ts !! public final static String[] KEY_Input_getEnclosedPackets = { "SpecialPanel.Input.getEnclosedPackets", "1" }; //cbox[33], true public final static String[] KEY_Input_concatenateForeignRecords = { "SpecialPanel.Input.concatenateForeignRecords", "1" }; //cbox[49], true public final static String[] KEY_Audio_ignoreErrors = { "SpecialPanel.Audio.ignoreErrors", "0" }; //cbox[24] public final static String[] KEY_Audio_limitPts = { "SpecialPanel.Audio.limitPts", "0" }; //cbox[15] public final static String[] KEY_Video_ignoreErrors = { "SpecialPanel.Video.ignoreErrors", "0" }; //cbox[39] public final static String[] KEY_Video_trimPts = { "SpecialPanel.Video.trimPts", "0" }; //cbox[73] public final static String[] KEY_Conversion_startWithVideo = { "SpecialPanel.Conversion.startWithVideo", "1" }; //cbox[23] -streamconv !! public final static String[] KEY_Conversion_addPcrToStream = { "SpecialPanel.Conversion.addPcrToStream", "1" }; //cbox[36] -streamconv !! public final static String[] KEY_Conversion_PcrCounter = { "SpecialPanel.Conversion.PcrCounter", "0" }; //cbox[46] -streamconv !! public final static String[] KEY_TsHeaderMode = { "SpecialPanel.TS.HeaderMode", "0" }; //combox[20] public final static String[] KEY_PtsShift_Value = { "SpecialPanel.PtsShift.Value", "0" }; //combox[27] public final static String[] KEY_PcrDelta_Value = { "SpecialPanel.PcrDelta.Value", "65000" }; //combox[23] public static Object[] ITEMS_TsHeaderMode = null; public static Object[] ITEMS_PtsShift = { "auto", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13" }; public static Object[] ITEMS_PcrDelta = { "25000", "35000", "45000", "55000", "65000", "80000", "100000", "125000", "150000" }; /** * ExternPanel */ public final static String[] KEY_ExternPanel_createVdrIndex = { "ExternPanel.createVdrIndex", "0" }; //cbox[54] public final static String[] KEY_ExternPanel_createCellTimes = { "ExternPanel.createCellTimes", "1" }; //cbox[26] !! public final static String[] KEY_ExternPanel_exportPts = { "ExternPanel.exportPts", "0" }; //cbox[64] !! public final static String[] KEY_ExternPanel_save1stFrameOfGop = { "ExternPanel.save1stFrameOfGop", "0" }; //cbox[65] public final static String[] KEY_ExternPanel_createChapters = { "ExternPanel.createChapters", "0" }; //cbox[63] public final static String[] KEY_ExternPanel_renameAudio = { "ExternPanel.renameAudio", "0" }; //cbox[16] public final static String[] KEY_ExternPanel_renameVideo = { "ExternPanel.renameVideo", "0" }; //cbox[32] public final static String[] KEY_ExternPanel_appendExtension = { "ExternPanel.appendExtension", "0" }; //cbox[66] !! public final static String[] KEY_ExternPanel_createM2sIndex = { "ExternPanel.createM2sIndex", "0" }; //cbox[34] public final static String[] KEY_ExternPanel_createD2vIndex = { "ExternPanel.createD2vIndex", "0" }; //cbox[29] public final static String[] KEY_ExternPanel_createDgiIndex = { "ExternPanel.createDgiIndex", "0" }; //cbox[82] !! public final static String[] KEY_ExternPanel_splitProjectFile = { "ExternPanel.splitProjectFile", "0" }; //cbox[30] !! public final static String[] KEY_ExternPanel_ProjectFileSplitSize = { "ExternPanel.ProjectFileSplitSize", "2048" }; public final static String[] KEY_ExternPanel_createInfoIndex = { "ExternPanel.createInfoIndex", "0" }; public final static String[] KEY_killFtpClient = { "FtpPanel.killFtpClient", "0" }; //cbox[80] !! public final static String[] KEY_useFtpServerResume = { "FtpPanel.useFtpServerResume", "1" }; public final static String[] KEY_autostartWebServer = { "NetPanel.autostartWebServer", "0" }; public final static String[] KEY_WebServerPort = { "NetPanel.WebServerPort", "-1" }; public final static String[] KEY_WebServerAccess = { "NetPanel.WebServerAccess", "" }; /** * VideoPanel */ public final static String[] KEY_VideoPanel_addEndcode = { "VideoPanel.addEndcode", "1" }; //cbox[13] public final static String[] KEY_VideoPanel_insertEndcode = { "VideoPanel.insertEndcode", "0" }; //cbox[75] public final static String[] KEY_VideoPanel_addSequenceHeader = { "VideoPanel.addSequenceHeader", "0" }; //cbox[27] public final static String[] KEY_VideoPanel_clearCDF = { "VideoPanel.clearCdf", "1" }; //cbox[35] public final static String[] KEY_VideoPanel_patchToProgressive = { "VideoPanel.patchToProgressive", "0" }; //cbox[31] public final static String[] KEY_VideoPanel_patchToInterlaced = { "VideoPanel.patchToInterlaced", "0" }; //cbox[44] public final static String[] KEY_VideoPanel_toggleFieldorder = { "VideoPanel.toggleFieldorder", "0" }; //cbox[45] public final static String[] KEY_VideoPanel_addSde = { "VideoPanel.addSde", "1" }; //cbox[77] public final static String[] KEY_VideoPanel_SdeValue = { "VideoPanel.SdeValue", "" }; public final static String[] KEY_ChangeVbvBuffer = { "VideoPanel.ChangeVbvBuffer", "0" }; //combox[4] public final static String[] KEY_ChangeVbvDelay = { "VideoPanel.ChangeVbvDelay", "1" }; //combox[5] public final static String[] KEY_ChangeAspectRatio = { "VideoPanel.ChangeAspectRatio", "0" }; //combox[6] public final static String[] KEY_ChangeBitrateInAllSequences = { "VideoPanel.ChangeBitrateInAllSequences", "1" }; //combox[3] public final static String[] KEY_ChangeBitrateInFirstSequence = { "VideoPanel.ChangeBitrateInFirstSequence", "2" }; //combox[15] public final static String[] KEY_ConditionalHorizontalPatch = { "VideoPanel.ConditionalHorizontalPatch", "0" }; //combox[35] public final static String[] KEY_ConditionalHorizontalResolution = { "VideoPanel.ConditionalHorizontalResolution", "352" }; //combox[22] public static Object[] ITEMS_ConditionalHorizontalPatch = null; public static Object[] ITEMS_ChangeVbvBuffer = null; public static Object[] ITEMS_ChangeVbvDelay = null; public static Object[] ITEMS_ChangeAspectRatio = null; public static Object[] ITEMS_BitrateInAllSequences = null; public static Object[] ITEMS_BitrateInFirstSequence = null; public final static String[] KEY_SubtitlePanel_decodeMegaradio = { "SubtitlePanel.decodeMegaradio", "0" }; //cbox[17] public final static String[] KEY_SubtitlePanel_decodeHiddenRows = { "SubtitlePanel.decodeHiddenRows", "0" }; //cbox[22] public final static String[] KEY_SubtitlePanel_rebuildPTS = { "SubtitlePanel.rebuildPTS", "0" }; //cbox[62] !! public final static String[] KEY_SubtitlePanel_keepOriginalTimecode = { "SubtitlePanel.keepOriginalTimecode", "0" }; //cbox[67] public final static String[] KEY_SubtitlePanel_exportTextAsUnicode = { "SubtitlePanel.exportTextAsUnicode", "0" }; public final static String[] KEY_SubtitlePanel_exportTextAsUTF8 = { "SubtitlePanel.exportTextAsUTF8", "0" }; public final static String[] KEY_SubtitlePanel_useTextOutline = { "SubtitlePanel.useTextOutline", "1" }; //cbox[79] !! public final static String[] KEY_SubtitlePanel_Format_SUP_Values = { "SubtitlePanel.Format.SUP.Values", "26;10;32;80;560;720;576;-1;4;3;1" }; public final static String[] KEY_SubtitlePanel_PageId_Value = { "SubtitlePanel.PageId.Value", "" }; public final static String[] KEY_SubtitlePanel_MaxParityErrors = { "SubtitlePanel.maxParityErrors", "2" }; public final static String[] KEY_SubtitlePanel_TtxPage1 = { "SubtitlePanel.TtxPage1", "null" }; //combobox[28] public final static String[] KEY_SubtitlePanel_TtxPage2 = { "SubtitlePanel.TtxPage2", "null" }; //combobox[29] public final static String[] KEY_SubtitlePanel_TtxPage3 = { "SubtitlePanel.TtxPage3", "null" }; //combobox[30] public final static String[] KEY_SubtitlePanel_TtxPage4 = { "SubtitlePanel.TtxPage4", "null" }; //combobox[31] public final static String[] KEY_SubtitlePanel_TtxPage5 = { "SubtitlePanel.TtxPage5", "null" }; //combobox[32] public final static String[] KEY_SubtitlePanel_TtxPage6 = { "SubtitlePanel.TtxPage6", "null" }; //combobox[33] public final static String[] KEY_SubtitlePanel_TtxPage7 = { "SubtitlePanel.TtxPage7", "null" }; //combobox[33] public final static String[] KEY_SubtitlePanel_TtxPage8 = { "SubtitlePanel.TtxPage8", "null" }; //combobox[33] public final static String[] KEY_TtxLanguagePair = { "SubtitlePanel.TtxLanguagePair", "0" }; //combobox[18], index public final static String[] KEY_SubtitleFont = { "SubtitlePanel.SubtitleFont", "Tahoma" }; //combobox[26], item public final static String[] KEY_SubtitleExportFormat = { "SubtitlePanel.SubtitleExportFormat", "SUB" }; public final static String[] KEY_SubtitleExportFormat_2 = { "SubtitlePanel.SubtitleExportFormat_2", "null" }; public final static String[] KEY_SubpictureColorModel = { "SubtitlePanel.SubpictureColorModel", "(0) 4 colors" }; public final static String[] KEY_SubtitleChangeDisplay = { "SubtitlePanel.ChangeDisplay", "0" }; public final static String[] KEY_SubtitleMovePosition_Value = { "SubtitlePanel.MovePosition.Value", "" }; //test public final static String[] KEY_SubtitlePanel_specialTermination = { "SubtitlePanel.specialTermination", "1" }; public static Object[] ITEMS_TtxLanguagePair = { "auto", "basic latin", "polish", "turkish", "cro,slo,rum", "est,lit,rus", "res.", "greek,latin", "res.", "arabic,latin", "res.", "hebrew,arabic" }; public static Object[] ITEMS_SubtitleExportFormat = null; public static Object[] ITEMS_SubtitleChangeDisplay = null; public final static String[] KEY_AudioPanel_decodeMpgAudio = { "AudioPanel.decodeMpgAudio", "0" }; //cbox[50] public final static String[] KEY_AudioPanel_validateCRC = { "AudioPanel.validateCRC", "1" }; //cbox[68] public final static String[] KEY_AudioPanel_clearCRC = { "AudioPanel.clearCRC", "1" }; //cbox[1] public final static String[] KEY_AudioPanel_fillGapsWithLastFrame = { "AudioPanel.fillGapsWithLastFrame", "0" }; //cbox[0] public final static String[] KEY_AudioPanel_addFrames = { "AudioPanel.addFrames", "1" }; //cbox[20] public final static String[] KEY_AudioPanel_patch1stAc3Header = { "AudioPanel.patch1stAc3Header", "0" }; //cbox[9] public final static String[] KEY_AudioPanel_replaceAc3withSilence = { "AudioPanel.replaceAc3withSilence", "0" }; //cbox[10] public final static String[] KEY_AudioPanel_allowSpaces = { "AudioPanel.allowSpaces", "0" }; //cbox[69] public final static String[] KEY_AudioPanel_addRiffToAc3 = { "AudioPanel.addRiffToAc3", "0" }; //cbox[12] public final static String[] KEY_AudioPanel_addRiffToMpgAudio = { "AudioPanel.addRiffToMpgAudioL12", "0" }; //cbox[4] + rbutton[14] riff fr layer1+2 public final static String[] KEY_AudioPanel_pitchAudio = { "AudioPanel.pitchAudio", "0" }; //cbox[51] public final static String[] KEY_AudioPanel_Normalize = { "AudioPanel.decodeMpgAudio.Normalize", "0" }; //rbutton[2] + exefield[8] normalize public final static String[] KEY_AudioPanel_Downmix = { "AudioPanel.decodeMpgAudio.Downmix", "0" }; //rbutton[3] public final static String[] KEY_AudioPanel_changeByteorder = { "AudioPanel.decodeMpgAudio.changeByteorder", "0" }; //rbutton[4] public final static String[] KEY_AudioPanel_addRiffHeader = { "AudioPanel.decodeMpgAudio.addRiffHeader", "1" }; //rbutton[5] public final static String[] KEY_AudioPanel_addAiffHeader = { "AudioPanel.decodeMpgAudio.addAiffHeader", "0" }; //rbutton[9] public final static String[] KEY_AudioPanel_addRiffToMpgAudioL3 = { "AudioPanel.addRiffToMpgAudioL3", "0" }; //cbox[4] + rbutton[15] riff fr layer3 public final static String[] KEY_AudioPanel_PitchValue = { "AudioPanel.PitchValue", "0" }; public final static String[] KEY_AudioPanel_NormalizeValue = { "AudioPanel.NormalizeValue", "98" }; public final static String[] KEY_AudioPanel_createDDWave = { "AudioPanel.createDDWave", "0" }; public final static String[] KEY_AudioPanel_fadeInOut = { "AudioPanel.fadeInOut", "0" }; public final static String[] KEY_AudioPanel_fadeInOutMillis = { "AudioPanel.fadeInOutMillis", "2000" }; public final static String[] KEY_AudioPanel_loslessMpaConversionMode = { "AudioPanel.loslessMpaConversionMode", "0" }; public static Object[] ITEMS_loslessMpaConversionMode = null; public final static String[] KEY_AudioPanel_resampleAudioMode = { "AudioPanel.decodeMpgAudio.resampleAudioMode", "0" }; public static Object[] ITEMS_resampleAudioMode = null; public final static String[] KEY_Preview_disable = { "CollectionPanel.Preview.disable", "0" }; public final static String[] KEY_Preview_fastDecode = { "CollectionPanel.Preview.fastDecode", "0" }; //rbutton[10] public final static String[] KEY_Preview_LiveUpdate = { "CollectionPanel.Preview.LiveUpdate", "1" }; //rbutton[16] public final static String[] KEY_Preview_AllGops = { "CollectionPanel.Preview.AllGops", "0" }; //rbutton[6] public final static String[] KEY_OptionHorizontalResolution = { "CollectionPanel.OptionHorizontalResolution", "0" }; //cbox[52] public final static String[] KEY_OptionDAR = { "CollectionPanel.OptionDAR", "0" }; //cbox[47] public final static String[] KEY_ExportHorizontalResolution = { "CollectionPanel.ExportHorizontalResolution", "720" }; //combox[34] public final static String[] KEY_ExportDAR = { "CollectionPanel.ExportDAR", "2" }; //combox[24] public final static String[] KEY_CutMode = { "CollectionPanel.CutMode", "0" }; //combox[17] public static Object[] ITEMS_ExportHorizontalResolution = { "304", "320", "352", "384", "480", "528", "544", "576", "640", "704", "720" }; public static Object[] ITEMS_ExportDAR = { "1.000 (1:1)", "0.6735 (4:3)", "0.7031 (16:9)", "0.7615 (2.21:1)", "0.8055", "0.8437", "0.9375", "0.9815", "1.0255", "1.0695", "1.1250", "1.1575", "1.2015" }; public static Object[] ITEMS_CutMode = null; public static Object[] ITEMS_FileTypes = null; /** * Constructor */ public Keys() { Object[] ITEMS_ConversionMode = { Resource.getString("MainPanel.ConversionMode.demux"), Resource.getString("MainPanel.ConversionMode.toVDR"), Resource.getString("MainPanel.ConversionMode.toM2P"), Resource.getString("MainPanel.ConversionMode.toPVA"), Resource.getString("MainPanel.ConversionMode.toTS"), Resource.getString("MainPanel.ConversionMode.PidFilter") }; this.ITEMS_ConversionMode = ITEMS_ConversionMode; Object[] ITEMS_TsHeaderMode = { Resource.getString("SpecialPanel.TS.HeaderMode0"), Resource.getString("SpecialPanel.TS.HeaderMode1"), Resource.getString("SpecialPanel.TS.HeaderMode2"), Resource.getString("SpecialPanel.TS.HeaderMode3") }; this.ITEMS_TsHeaderMode = ITEMS_TsHeaderMode; Object[] ITEMS_ConditionalHorizontalPatch = { Resource.getString("VideoPanel.patchResolutionValue.0"), Resource.getString("VideoPanel.patchResolutionValue.1"), Resource.getString("VideoPanel.patchResolutionValue.2"), Resource.getString("VideoPanel.patchResolutionValue.3") }; this.ITEMS_ConditionalHorizontalPatch = ITEMS_ConditionalHorizontalPatch; Object[] ITEMS_ChangeVbvBuffer = { Resource.getString("VideoPanel.Unchanged"), Resource.getString("VideoPanel.ChangeVbvBuffer.Mode1") }; this.ITEMS_ChangeVbvBuffer = ITEMS_ChangeVbvBuffer; Object[] ITEMS_ChangeVbvDelay = { Resource.getString("VideoPanel.Unchanged"), Resource.getString("VideoPanel.ChangeVbvDelay.Mode1") }; this.ITEMS_ChangeVbvDelay = ITEMS_ChangeVbvDelay; Object[] ITEMS_ChangeAspectRatio = { Resource.getString("VideoPanel.Unchanged"), "1.000 (1:1)", "0.6735 (4:3)", "0.7031 (16:9)", "0.7615 (2.21:1)", "0.8055", "0.8437", "0.9375", "0.9815", "1.0255", "1.0695", "1.1250", "1.1575", "1.2015" }; this.ITEMS_ChangeAspectRatio = ITEMS_ChangeAspectRatio; Object[] ITEMS_BitrateInAllSequences = { Resource.getString("VideoPanel.patchBitrateValue.0"), Resource.getString("VideoPanel.patchBitrateValue.1"), Resource.getString("VideoPanel.patchBitrateValue.2"), Resource.getString("VideoPanel.patchBitrateValue.3"), Resource.getString("VideoPanel.patchBitrateValue.4"), Resource.getString("VideoPanel.patchBitrateValue.5"), Resource.getString("VideoPanel.patchBitrateValue.6"), Resource.getString("VideoPanel.patchBitrateValue.7"), Resource.getString("VideoPanel.patchBitrateValue.8") }; this.ITEMS_BitrateInAllSequences = ITEMS_BitrateInAllSequences; Object[] ITEMS_BitrateInFirstSequence = { Resource.getString("VideoPanel.patch1stBitrateValue.0"), Resource.getString("VideoPanel.patch1stBitrateValue.1"), Resource.getString("VideoPanel.patch1stBitrateValue.2"), Resource.getString("VideoPanel.patch1stBitrateValue.3"), Resource.getString("VideoPanel.patch1stBitrateValue.4") }; this.ITEMS_BitrateInFirstSequence = ITEMS_BitrateInFirstSequence; Object[] ITEMS_loslessMpaConversionMode = { Resource.getString("AudioPanel.loslessMpaConversionMode0"), Resource.getString("AudioPanel.loslessMpaConversionMode1"), Resource.getString("AudioPanel.loslessMpaConversionMode2"), Resource.getString("AudioPanel.loslessMpaConversionMode3"), Resource.getString("AudioPanel.loslessMpaConversionMode4") }; this.ITEMS_loslessMpaConversionMode = ITEMS_loslessMpaConversionMode; Object[] ITEMS_resampleAudioMode = { Resource.getString("AudioPanel.decodeMpgAudio.resampleAudioMode0"), Resource.getString("AudioPanel.decodeMpgAudio.resampleAudioMode1"), Resource.getString("AudioPanel.decodeMpgAudio.resampleAudioMode2") }; this.ITEMS_resampleAudioMode = ITEMS_resampleAudioMode; Object[] ITEMS_CutMode = { Resource.getString("CollectionPanel.CutMode.Bytepos"), Resource.getString("CollectionPanel.CutMode.Gop"), Resource.getString("CollectionPanel.CutMode.Frame"), Resource.getString("CollectionPanel.CutMode.Pts"), Resource.getString("CollectionPanel.CutMode.Timecode") }; this.ITEMS_CutMode = ITEMS_CutMode; Object[] ITEMS_SubtitleExportFormat = { Resource.getString("SubtitlePanel.Format.Free"), "SC", "SUB", "SRT", "STL", "SSA", "SON", "SUP", "null" }; this.ITEMS_SubtitleExportFormat = ITEMS_SubtitleExportFormat; Object[] ITEMS_SubtitleChangeDisplay = { "no change", "all forced", "all not forced" }; this.ITEMS_SubtitleChangeDisplay = ITEMS_SubtitleChangeDisplay; Object[] ITEMS_FileTypes = { Resource.getString("scan.unsupported"), "PES (incl. MPEG Video)", "MPEG-1 PS/SS (PES Container)", "MPEG-2 PS/SS (PES Container)", "PVA (PES Container of TT)", "TS (generic PES Container)", "PES (MPEG Audio first)", "PES (private stream 1 first)", "ES (MPEG Video)", "ES (MPEG Audio)", "ES (AC-3 Audio)", "ES (AC-3 Audio) (psb. SMPTE)", "ES (DTS Audio)", "ES (DTS Audio) (psb. SMPTE)", "ES (RIFF Audio)", "ES (compressed RIFF Audio)", "ES (Subpicture 2-bit RLE)" }; this.ITEMS_FileTypes = ITEMS_FileTypes; } }project-x/src/net/sourceforge/dvb/projectx/common/Resource.java0000600000175000017500000003140010351106052026341 0ustar supermariosupermario/* * @(#)Resource.java - resource and i18n * * Copyright (c) 2004-2005 by pstorch, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.common; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; import java.net.JarURLConnection; import java.net.URL; import java.net.URLConnection; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.MissingResourceException; import java.util.PropertyResourceBundle; import java.util.ResourceBundle; import java.util.Set; import java.util.StringTokenizer; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.awt.Image; import java.awt.Toolkit; import net.sourceforge.dvb.projectx.common.Keys; /** * Project-X resource and localization handling. * * @author Peter Storch */ public class Resource extends Object { /** the prefix of all pjx resource files */ private static final String PJX_RESOURCE_PREFIX = "pjxresources"; /** current working directory */ public static final String workdir = System.getProperty("user.dir"); /** os dependent file separator */ public static final String filesep = System.getProperty("file.separator"); /** the users locale */ private static Locale locale = null; /** the default resource bundle */ private static ResourceBundle defaultResource = null; /** the resource bundle for the current users locale or language setting */ private static ResourceBundle resource = null; /** * Loads a resource bundle for the given locale. * * @param locale * @return ResourceBundle */ private static ResourceBundle loadResourceBundle(Locale locale) throws MissingResourceException { ResourceBundle newBundle = null; String resourceName = PJX_RESOURCE_PREFIX + "_" + locale.getLanguage() + ".properties"; // first we try to find one in the current working directory try { File file = new File(workdir + filesep + resourceName); if (file.exists() && file.canRead()) { newBundle = new PropertyResourceBundle(new FileInputStream(file)); return newBundle; } } catch (Exception e) { // shit happens, go on and try to find one in our jar file } try { URL url = Resource.class.getClassLoader().getResource(resourceName); newBundle = new PropertyResourceBundle(url.openStream()); } catch (Exception e) { throw new MissingResourceException("couldn't find " + resourceName, Resource.class.getName(), resourceName); } return newBundle; } static{ // the default resource must be available defaultResource = loadResourceBundle(Locale.ENGLISH); try { // now try to load the resource bundle form the users locale resource = loadResourceBundle(Locale.getDefault()); } catch (MissingResourceException e) { // our fallback is english resource = defaultResource; } } /** * Constructor of Resource. */ private Resource() { // singleton } /** * Loads Language from ini file. * * @param filename Name of the inifile. */ public static void loadLang(String lang) { locale = new Locale(lang, ""); try { resource = loadResourceBundle(locale); } catch (MissingResourceException e) { // our fallback is english resource = defaultResource; } // initialize languages dependent keys new Keys(); } /** * */ public static String getChosenLanguage() { if (locale == null) return null; return locale.getLanguage(); } /** * */ public static void setChosenLanguage(String str) { if (str == null) locale = null; else locale = new Locale(str, "", ""); } /** * Gets a String from the Resource file. If the key is not found, the key * itself is returned as text. * * @param key * @return String */ public static String getString(String key) { String text = null; try { text = resource.getString(key); } catch (MissingResourceException e) { try { // fallback to defaultResource text = defaultResource.getString(key); } catch (MissingResourceException e2) { System.out.println("ResourceKey '" + key + "' not found in pjxresources"); } } // use key as text as fallback if (text == null) { text = "?" + key + "?"; } return text; } /** * Returns a resource String as a String Array of lines. * * @return String[] */ public static String[] getStringByLines(String key) { List lines = new ArrayList(); StringTokenizer st = new StringTokenizer(getString(key), "\n"); while (st.hasMoreTokens()) { lines.add(st.nextToken()); } return (String[])lines.toArray(new String[0]); } /** * Gets a String from the resource and inserts optional arguments. * * @param key * @param args * @return */ public static String getString(String key, Object args[]) { return MessageFormat.format(getString(key), args); } /** * Gets a String from the resource and inserts an optional argument. * * @param key * @param args * @return */ public static String getString(String key, Object arg) { return MessageFormat.format(getString(key), new Object[]{arg}); } /** * Gets a String from the resource and inserts two optional arguments. * * @param key * @param arg1 * @param arg2 * @return */ public static String getString(String key, Object arg1, Object arg2) { return MessageFormat.format(getString(key), new Object[]{arg1, arg2}); } /** * Gets a String from the resource and inserts three optional arguments. * * @param key * @param arg1 * @param arg2 * @param arg3 * @return */ public static String getString(String key, Object arg1, Object arg2, Object arg3) { return MessageFormat.format(getString(key), new Object[]{arg1, arg2, arg3}); } /** * Gets a String from the resource and inserts four optional arguments. * * @param key * @param arg1 * @param arg2 * @param arg3 * @param arg4 * @return */ public static String getString(String key, Object arg1, Object arg2, Object arg3, Object arg4) { return MessageFormat.format(getString(key), new Object[]{arg1, arg2, arg3, arg4}); } /** * Gets a String from the resource and inserts five optional arguments. * * @param key * @param arg1 * @param arg2 * @param arg3 * @param arg4 * @param arg5 * @return */ public static String getString(String key, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { return MessageFormat.format(getString(key), new Object[]{arg1, arg2, arg3, arg4, arg5}); } /** * Returns the available Locales for pjxresources. * * @return Locale[] */ public static Locale[] getAvailableLocales() { Set locales = new HashSet(); String defLang = Locale.getDefault().getLanguage(); try { // we know we have an english resource, so first find this one to find the location URL url = ClassLoader.getSystemResource(PJX_RESOURCE_PREFIX + "_en.properties"); if (url != null) { URLConnection urlc = null; urlc = url.openConnection(); // If the resources are located in a JAR file, we need this // version to get the available locales. if (urlc != null && urlc instanceof JarURLConnection) { JarURLConnection jurlc = (JarURLConnection) urlc; addAvailableLocalesFromJar(locales, jurlc); } // .. else if the resources are in the file system, we use the // default version to get the available locales. else { File enFile = new File(url.getFile()); File dir = enFile.getParentFile(); addAvailableLocalesFromFileSystem(locales, dir); } } else { System.err.println("Couldn't find \"" + PJX_RESOURCE_PREFIX + "\"*.properties"); } // also look into the current working directory for additional resource files File workDirFile = new File(workdir); addAvailableLocalesFromFileSystem(locales, workDirFile); } catch (Exception e) { System.out.println(e); } return (Locale[])locales.toArray(new Locale[0]); } /** * Adds available Locales from the file system. * * @param locales * @param dir */ private static void addAvailableLocalesFromFileSystem(Set locales, File dir) { File[] files = dir.listFiles(); if (files != null) { for (int i = 0; i < files.length; i++) { File file = files[i]; if (file.isFile() && file.getName().startsWith(PJX_RESOURCE_PREFIX)) { try { String code = file.getName(); int pos = code.indexOf('_'); if (pos != -1) { code = code.substring(pos + 1); } pos = code.indexOf('.'); if (pos != -1) { code = code.substring(0, pos); } Locale locale = new Locale(code, ""); locales.add(locale); } catch (Exception e) { System.out.println(e); } } } } } /** * Adds available Locales from a Jar file location * * @param locales * @param jurlc */ private static void addAvailableLocalesFromJar(Set locales, JarURLConnection jurlc) { JarFile jarf = null; try { jarf = jurlc.getJarFile(); } catch (Exception e) { System.out.println(e); } if (jarf != null) { for (Enumeration en = jarf.entries(); en.hasMoreElements();) { JarEntry jare = (JarEntry) en.nextElement(); String name = jare.getName(); if (name.startsWith(PJX_RESOURCE_PREFIX)) { String code = name.substring(0, name.length() - ".properties".length()); int pos = code.indexOf('_'); if (pos != -1) { code = code.substring(pos + 1); } pos = code.indexOf('.'); if (pos != -1) { code = code.substring(0, pos); } Locale locale = new Locale(code, ""); locales.add(locale); } } } } /** * Returns a resource (e.g. from the jar file) as an URL. * * @param resource the name of the resource * @return URL */ public static URL getResourceURL(String resource) { try { String filename = workdir + filesep + resource; File file = new File(filename); if (file.exists() && file.canRead()) { return file.toURL(); } } catch(Exception e) { // ignore it, it was just a try to get this resource from the filesystem } // for the classloader we need to replace all backslashes to forward slashes. // this is only necessary on windows systems and doesn't harm others resource = resource.replace('\\', '/'); // ok, not founde in the filesystem, now try the classloader return Resource.class.getClassLoader().getResource(resource); } /** * Returns a resource (e.g. from the jar file) as an URL. * * @param resourceName the name of the resource * @return URL */ public static URL getLocalizedResourceURL(String path, String resourceName) { Locale usedLocale = null; if (locale != null) { usedLocale = locale; } else { usedLocale = Locale.getDefault(); } String localizedResource = path + filesep + usedLocale.getLanguage() + filesep + resourceName; URL url = getResourceURL(localizedResource); if (url != null) { return url; } // there is no localized version of this file, try the default version return getResourceURL(path + filesep + resourceName); } /** * */ public static Image loadImage(String imageName) { try { return Toolkit.getDefaultToolkit().createImage(getResourceURL(imageName)); } catch (Exception e) { return null; } } } project-x/src/net/sourceforge/dvb/projectx/common/Settings.java0000600000175000017500000003430010355275042026366 0ustar supermariosupermario/* * @(#)Settings.java - holds all data of interest to re-use * * Copyright (c) 2005 * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ /* * initiated by pstorch */ package net.sourceforge.dvb.projectx.common; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.InputStreamReader; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.TreeMap; import java.net.URL; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.xinput.XInputDirectory; /** * The Settings class handles the settings for Project-X. * * @author Peter Storch */ public class Settings extends Object { /** the default ini filename */ private static final String DEFAULT_INI = "X.ini"; /** the current ini filename */ private String inifile = ""; /** all settings are being hold in this properties object */ private Properties props = new Properties(); /** */ private ArrayList input_directories = new ArrayList(); /** */ private ArrayList output_directories = new ArrayList(); /** * Constructor */ public Settings() { this(Resource.workdir + Resource.filesep + DEFAULT_INI); } /** * Constructor * * @param filename */ public Settings(String filename) { inifile = filename; load(); buildInputDirectories(); buildOutputDirectories(); } /** * */ public void loadProperties(java.io.ByteArrayInputStream is) throws IOException { props.load(is); } /** * */ public byte[] storeProperties() throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); props.store(os, null); return os.toByteArray(); } /** * Loads the ini file. */ public void load() { try { BufferedReader r = new BufferedReader(new FileReader(inifile)); String line = null; while ((line = r.readLine()) != null) { if (line.startsWith("#")) continue; int pos = line.indexOf('='); if (pos != -1) { String key = line.substring(0, pos); String value = line.substring(pos + 1); props.put(key, value); } } r.close(); } catch(IOException e) { System.out.println(Resource.getString("msg.loadini.error") + " " + e); } } /** * Saves the ini file. */ public void save() { save(inifile); } /** * Saves the ini file (std or extra name) */ public void save(String str) { if (str == null) str = inifile; try { PrintWriter w = new PrintWriter(new FileWriter(str)); String base_key = "# Project-X INI"; w.println(base_key); w.println("# " + Common.getVersionName() + " / " + Common.getVersionDate()); TreeMap map = new TreeMap(props); Set keys = map.keySet(); for (Iterator iter = keys.iterator(); iter.hasNext(); ) { String element = (String) iter.next(); String key = element.substring(0, element.indexOf(".")); if (!base_key.equals(key)) { w.println(); w.println("# " + key); base_key = key; } w.println(element + "=" + map.get(element)); } w.close(); } catch(IOException e) { Common.setExceptionMessage(e); } } /** * build input_directory Xinput object from property list (strings only) */ public void buildInputDirectories() { String key = Keys.KEY_InputDirectories; ArrayList input = (ArrayList)getListProperty(key); int i = 0; for ( ; i < input.size(); i++) { if (addInputDirectory(input.get(i)) == null) { input.remove(i); i--; } } if (i != input.size()) setListProperty(key, input); } /** * updates property list (strings only) */ public void updateInputDirectories() { ArrayList input = new ArrayList(); for (int i = 0; i < input_directories.size(); i++) input.add( input_directories.get(i).toString()); setListProperty(Keys.KEY_InputDirectories, input); } /** * adds input_directory Xinput object */ public String addInputDirectory(Object value) { if (value == null) return null; try { XInputDirectory xInputDirectory = (XInputDirectory) value; input_directories.add(xInputDirectory); return xInputDirectory.toString(); } catch (Exception e) { // is not yet xinput object } try { XInputDirectory xInputDirectory = new XInputDirectory(value); if (xInputDirectory.test()) { input_directories.add(xInputDirectory); return xInputDirectory.toString(); } } catch (RuntimeException e) { // If there are problems with the directory simply ignore it and do nothing } return null; } /** * removes input_directory Xinput object */ public void removeInputDirectory(int index) { if (index < 0 || input_directories.isEmpty() || input_directories.size() <= index) return; input_directories.remove(index); } /** * returns input_directory Xinput objects */ public ArrayList getInputDirectories() { return input_directories; } /** * build output_directory from property list (strings only) */ public void buildOutputDirectories() { String key = Keys.KEY_OutputDirectories; ArrayList output = (ArrayList)getListProperty(key); int i = 0; for ( ; i < output.size(); i++) addOutputDirectory(output.get(i)); if (i != output.size()) setListProperty(key, output); } /** * updates property list (strings only) */ public void updateOutputDirectories() { ArrayList output = new ArrayList(); for (int i = 0; i < output_directories.size(); i++) output.add( output_directories.get(i).toString()); setListProperty(Keys.KEY_OutputDirectories, output); } /** * adds output_directory string */ public void addOutputDirectory(Object value) { addOutputDirectory(value, -1); } /** * adds output_directory string */ public void addOutputDirectory(Object value, int index) { if (value == null) return; if (index < 0 || index > output_directories.size()) output_directories.add(value); else output_directories.add(index, value); updateOutputDirectories(); } /** * removes output_directory string */ public void removeOutputDirectory(int index) { if (index < 0 || output_directories.size() < index - 1) return; output_directories.remove(index); updateOutputDirectories(); } /** * returns output_directory strings */ public ArrayList getOutputDirectories() { return output_directories; } /** * Sets a String property. * * @param key * @param value * @return */ public void setProperty(String key, String value) { if (value != null) props.setProperty(key, value); else props.remove(key); } /** * Sets a Object property. * * @param key * @param value * @return */ public void setProperty(String key, Object value) { String str = value == null ? null : String.valueOf(value); setProperty(key, str); } /** * Sets a Object property. * * @param key of obj * @param value * @return */ public void setProperty(Object[] key, Object value) { setProperty(key[0].toString(), String.valueOf(value)); } /** * Returns a String property. * * @param key * @return */ public String getProperty(String key) { return props.getProperty(key); } /** * Returns a String property. If not found it returns the given default value. * * @param key * @param defaultValue * @return */ public String getProperty(String key, String defaultValue) { return props.getProperty(key, defaultValue); } /** * Returns a String property. If not found it returns the given default value. * * @param key * @param defaultValue * @return */ public String getProperty(String[] key_defaultValue) { String key = key_defaultValue[0]; String defaultValue = key_defaultValue[1]; return props.getProperty(key, defaultValue); } /** * Returns an integer property. * * @param key * @param value * @return */ public void setIntProperty(String key, int value) { props.setProperty(key, String.valueOf(value)); } /** * Returns an integer property. * * @param key * @return */ public int getIntProperty(String key) { return Integer.parseInt(props.getProperty(key)); } /** * Returns an integer property. If not found or not parseable it returns the default value. * * @param key * @param defaultValue * @return */ public int getIntProperty(String key, int defaultValue) { int value = defaultValue; try { value = Integer.parseInt(getProperty(key)); } catch(Exception e) { // ok, then we stay with the default value } return value; } /** * Returns an integer property. If not found or not parseable it returns the default value. * * @param key * @param defaultValue * @return */ public int getIntProperty(String[] key_defaultValue) { String key = key_defaultValue[0]; int value = Integer.parseInt(key_defaultValue[1]); try { value = Integer.parseInt(getProperty(key)); } catch(Exception e) { // ok, then we stay with the default value } return value; } /** * Returns a boolean property. * Default is false. * * @param key * @return */ public void setBooleanProperty(String key, boolean value) { props.setProperty(key, value ? "1" : "0"); } /** * Returns a Boolean property. * Null if key not found. Default is false. * * @param key * @return */ public Boolean getBooleanProperty(String key) { String value = getProperty(key); if (value == null) return null; else if (value.equals("1") || value.equals("true") || value.equals("yes") || value.equals("on")) return Boolean.TRUE; return Boolean.FALSE; } /** * Returns a Boolean property or the given defaultValue. * * @param key * @param defaultValue * @return */ public boolean getBooleanProperty(String key, boolean defaultValue) { Boolean value = getBooleanProperty(key); if (value == null) return defaultValue; return value.booleanValue(); } /** * Returns a Boolean property or the given defaultValue. * * @param key * @param defaultValue * @return */ public boolean getBooleanProperty(String[] key_defaultValue) { String key = key_defaultValue[0]; String defaultValue = key_defaultValue[1]; Boolean value = getBooleanProperty(key); if (value != null) return value.booleanValue(); if (defaultValue.equals("1") || defaultValue.equals("true") || defaultValue.equals("yes") || defaultValue.equals("on")) return true; return false; } /** * Sets a List of properties starting with key. * * @param key * @param list * @return */ public void setListProperty(String key, List list) { removeListProperty(key); for (int i = 0; i < list.size(); i++) { Object element = list.get(i); setProperty(key + i, element); } } /** * Gets a List of properties starting with key. * * @param key * @return */ public List getListProperty(String key) { Set keys = props.keySet(); List list = new ArrayList(); for (Iterator iter = keys.iterator(); iter.hasNext(); ) { String element = (String) iter.next(); if (element.startsWith(key)) list.add(props.getProperty(element)); } return list; } /** * removes a List of properties starting with key. * * @param key * @return */ public void removeListProperty(String key) { Set keys = props.keySet(); ArrayList list = new ArrayList(); for (Iterator iter = keys.iterator(); iter.hasNext(); ) { String element = (String) iter.next(); if (element.startsWith(key)) list.add(element); } for (int i = 0; i < list.size(); i++) remove(list.get(i).toString()); } /** * Sets a Map of properties starting with key. * * @param key * @param map * @return */ public void setHashMapProperty(String key, Map map) { Set keys = map.keySet(); for (Iterator iter = keys.iterator(); iter.hasNext(); ) { String element = (String) iter.next(); setProperty(key + element, map.get(element)); } } /** * Gets a Map of properties starting with key. * The Map contains the entries with a new key like this: * mapKey = propsKey - key. * * @param key * @return */ public Map getHashMapProperty(String key) { Set keys = props.keySet(); Map map = new HashMap(); for (Iterator iter = keys.iterator(); iter.hasNext();) { String element = (String) iter.next(); if (element.startsWith(key)) map.put(element.substring(key.length()), props.getProperty(element)); } return map; } /** * Removes a property. * * @param key */ public void remove(String key) { props.remove(key); } /** * Returns the ini filename. * * @return */ public String getInifile() { return inifile; } }project-x/src/net/sourceforge/dvb/projectx/common/Start.java0000600000175000017500000004353110355323604025667 0ustar supermariosupermario/* * @(#)Start.java - main start class * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ /* * X is completely designed as a test, therefore it mostly implements its * own code instead of a derivation of an ISO reference source or * any other code. Considerable effort has been expended to ensure * an useful implementation, even in cases where the standards * are ambiguous or misleading. * Do not expect any useful output, even if that may be possible. * * For a program compliant to the international standards ISO 11172 * and ISO 13818 it is inevitable to use methods covered by patents * in various countries. The authors of this program disclaim any * liability for patent infringement caused by using, modifying or * redistributing this program. * */ package net.sourceforge.dvb.projectx.common; import java.io.StringWriter; import java.io.PrintWriter; import java.io.File; import java.io.BufferedReader; import java.io.FileReader; import java.util.ArrayList; import java.util.StringTokenizer; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.parser.MainProcess; /** * the holy start */ public class Start extends Object { private static ArrayList cli_switches = new ArrayList(); public Start() {} /** * main */ public static void main(String[] args) { boolean iniSet = false; boolean showGUI = args.length == 0; boolean help = false; boolean switch_error = false; int index = -1; String inifile = null; String str = null; String[] version; Object[] environment; /** * */ for (int i = 0; i < args.length; i++) cli_switches.add(args[i]); try { /** * don't change the order!! */ /** * get version switch */ if (getBooleanSwitch("-version")) System.out.println("Version: " + Common.getVersionName() + "/" + Common.getVersionDate()); System.out.println("Reading GUI-Switch..."); /** * get gui switch */ if (getBooleanSwitch("-gui")) showGUI = true; System.out.println("Reading Help Switch..."); /** * get help switch */ if (getBooleanSwitch("-?")) help = true; System.out.println("Reading Config File Switch..."); /** * get 'config file' switch */ if ((index = getSwitch("-ini")) >= 0) { switch_error = false; if (index < cli_switches.size()) { str = cli_switches.get(index).toString(); if (new File(str).exists()) { inifile = str; iniSet = true; } else switch_error = true; cli_switches.remove(index); } else switch_error = false; if (switch_error) { System.out.println("stopped, config file '" + inifile + "' not found ..."); System.exit(1); } } System.out.println(showGUI ? "Start with GUI..." : "Start without GUI..."); /** * use 'config file' */ if (!iniSet) { System.out.println("Loading last Config or Standard File..."); Common.setSettings(); } else { System.out.println("Loading Config File: '" + inifile + "' ..."); Common.setSettings(inifile); } /** * initialize language */ Resource.loadLang(Common.getSettings().getProperty(Keys.KEY_Language)); Common.getSettings().setProperty(Keys.KEY_Language[0], Resource.getChosenLanguage()); System.out.println("Loading Language -> '" + Resource.getChosenLanguage() + "'"); /** * dont save settings on exit on CLI, see cli-switches */ if (args.length != 0) Common.getSettings().setProperty(Keys.KEY_SaveSettingsOnExit[0], "0"); /** * version */ version = Common.getVersion(); System.out.println(); System.out.println(version[0] + "/" + version[1] + " " + version[2] + " " + version[3]); System.out.println(); /** * terms */ System.out.println(Resource.getString("terms")); /** * environment */ environment = Common.getJavaEV(Common.getSettings().getInifile()); for (int i = 0; i < environment.length; i++) System.out.println(environment[i].toString()); System.out.println(); /** * usage */ System.out.println(Resource.getString("usage")); System.out.println(); /** * stop on help switch */ if (help) Common.exitApplication(0); System.out.println("Loading Basic Classes..."); /** * load main stuff */ Common.init(); // access after the keys has been loaded!, separate to userinterface later System.out.println("Reading CLI Switches..."); /** * read cli switches */ if (readSwitches(cli_switches)) System.out.println("Error while reading CLI Switches ..."); /** * initialize the gui interface */ Common.prepareGui(showGUI); // access after the keys has been loaded!, separate to userinterface later System.out.println("Checking Commons-Net library access..."); /** * planned to disable ftp only, if commons-net is missing */ if ((str = Common.checkLibraryAccess()) != null) { throw new Exception(str); //System.out.println(ret); } System.out.println("Loading AC3 frames..."); /** * load silent ac3 frames */ Common.loadAC3(); //Common.clearMessageLog(); if (Common.getSettings().getBooleanProperty(Keys.KEY_autostartWebServer)) Common.startWebServer(); /** * starts CL processing */ if (!showGUI) { if (!Common.getSettings().getBooleanProperty(Keys.KEY_autostartWebServer)) { if (Common.isCollectionListEmpty()) { System.out.println("Error: No Collection to Process ..."); Common.exitApplication(2); } System.out.println("Starting Collection Process..."); Common.setRunningCLI(true); Common.setRunningProcess(true); Common.startMainProcess(); } else System.out.println("Starting WebIF..."); } else { if (!Common.getGuiInterface().isAvailable()) System.out.println("Stopped! Can't start GUI, Classes not available..."); else if (!Common.isCollectionListEmpty()) { Common.getGuiInterface().addCollectionAtEnd(); Common.getGuiInterface().showActiveCollection(0); } } } /** * catch all other unhandled exception */ catch(Exception e) { /** * in GUI mode clean GUI and show GUI message */ if (showGUI) { /** * show exception messge */ StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); Common.getGuiInterface().showErrorMessageDialog(Resource.getString("StartUp.Error") + Common.getLineSeparator() + Common.getLineSeparator() + sw.toString(), Resource.getString("StartUp.Error.Title")); } /** * in CLI mode simply show stackTrace */ else { System.out.println("Stopped! An Error has occured..."); e.printStackTrace(); } System.exit(1); } } /** * create single collection */ private static JobCollection createCollection(JobCollection collection) { if (collection == null) { collection = Common.addCollection(false); Common.setActiveCollection(0); } return collection; } /** * get switch */ private static boolean getBooleanSwitch(String str) { return (getSwitch(str) >= 0); } /** * get switch */ private static int getSwitch(String str) { int index; if ((index = cli_switches.indexOf(str)) >= 0) cli_switches.remove(index); return index; } /** * read cli */ private static boolean readSwitches(ArrayList cli_switches) { JobCollection collection = null; boolean error = false; boolean switch_error = false; String str = null; int index = -1; try { /** * get switches */ if (getBooleanSwitch("-dvx1")) Common.getSettings().setProperty(Keys.KEY_ExternPanel_splitProjectFile[0], "1"); if (getBooleanSwitch("-dvx2")) { Common.getSettings().setProperty(Keys.KEY_ExternPanel_splitProjectFile[0], "1"); Common.getSettings().setProperty(Keys.KEY_AudioPanel_addRiffToAc3[0], "1"); } if (getBooleanSwitch("-dvx3")) { Common.getSettings().setProperty(Keys.KEY_ExternPanel_splitProjectFile[0], "1"); Common.getSettings().setProperty(Keys.KEY_AudioPanel_addRiffToMpgAudio[0], "1"); } if (getBooleanSwitch("-dvx4")) { Common.getSettings().setProperty(Keys.KEY_ExternPanel_splitProjectFile[0], "1"); Common.getSettings().setProperty(Keys.KEY_AudioPanel_addRiffToAc3[0], "1"); Common.getSettings().setProperty(Keys.KEY_AudioPanel_addRiffToMpgAudio[0], "1"); } /** * save normal log */ if (getBooleanSwitch("-log")) Common.getSettings().setProperty(Keys.KEY_NormalLog[0], "1"); /** * save on exit */ if (getBooleanSwitch("-saveini")) Common.getSettings().setProperty(Keys.KEY_SaveSettingsOnExit[0], "1"); /** * web if */ if (getBooleanSwitch("-webif")) Common.getSettings().setProperty(Keys.KEY_autostartWebServer[0], "1"); /** * action type */ if (getBooleanSwitch("-demux")) Common.getSettings().setProperty(Keys.KEY_ConversionMode[0], "0"); if (getBooleanSwitch("-tovdr")) Common.getSettings().setProperty(Keys.KEY_ConversionMode[0], "1"); if (getBooleanSwitch("-tom2p")) Common.getSettings().setProperty(Keys.KEY_ConversionMode[0], "2"); if (getBooleanSwitch("-topva")) Common.getSettings().setProperty(Keys.KEY_ConversionMode[0], "3"); if (getBooleanSwitch("-tots")) Common.getSettings().setProperty(Keys.KEY_ConversionMode[0], "4"); if (getBooleanSwitch("-filter")) Common.getSettings().setProperty(Keys.KEY_ConversionMode[0], "5"); /** * split output */ if ((index = getSwitch("-split")) >= 0) { switch_error = false; if (index < cli_switches.size()) { str = cli_switches.get(index).toString(); try { int val = Integer.parseInt(str); Common.getSettings().setProperty(Keys.KEY_SplitSize[0], "1"); Common.getSettings().setProperty(Keys.KEY_ExportPanel_SplitSize_Value[0], String.valueOf(val)); } catch (Exception e) { switch_error = true; } cli_switches.remove(index); } else switch_error = false; if (switch_error) { System.out.println("can't set split size value ..."); error = true; } } /** * new output base directory */ if ((index = getSwitch("-out")) >= 0) { switch_error = false; collection = createCollection(collection); if (index < cli_switches.size()) { str = cli_switches.get(index).toString(); if (new File(str).exists()) collection.setOutputDirectory(str); else switch_error = true; cli_switches.remove(index); } else switch_error = false; if (switch_error) { System.out.println("can't set output directory ..."); error = true; } } /** * new output name */ if ((index = getSwitch("-name")) >= 0) { switch_error = false; collection = createCollection(collection); if (index < cli_switches.size()) { str = cli_switches.get(index).toString(); if (str.length() > 0) collection.setOutputName(str); else switch_error = false; cli_switches.remove(index); } else switch_error = false; if (switch_error) { System.out.println("can't set output name ..."); error = true; } } /** * load point list */ if ((index = getSwitch("-cut")) >= 0) { switch_error = false; collection = createCollection(collection); if (index < cli_switches.size()) { str = cli_switches.get(index).toString(); if (new File(str).exists()) loadCutPoints(collection, str); else switch_error = false; cli_switches.remove(index); } else switch_error = false; if (switch_error) { System.out.println("can't set cutpoints ..."); error = true; } } /** * load point list */ if ((index = getSwitch("-chp")) >= 0) { switch_error = false; collection = createCollection(collection); if (index < cli_switches.size()) { str = cli_switches.get(index).toString(); if (new File(str).exists()) loadChapterPoints(collection, str); else switch_error = false; cli_switches.remove(index); } else switch_error = false; if (switch_error) { System.out.println("can't set chapterpoints ..."); error = true; } } /** * load PID list */ if ((index = getSwitch("-id")) >= 0) { switch_error = false; collection = createCollection(collection); if (index < cli_switches.size()) { str = cli_switches.get(index).toString(); if (str.length() > 0) loadIDs(collection, str); else switch_error = false; cli_switches.remove(index); } else switch_error = false; if (switch_error) { System.out.println("can't set pidfilter ..."); error = true; } } /** * jrmann1999, patch to work with batch file list (.bfl, .tpl) */ for (int i = 0; i < cli_switches.size(); i++) { collection = createCollection(collection); try { String _str = cli_switches.get(i).toString(); str = _str.toLowerCase(); XInputFile xif = null; if (str.endsWith("bfl") || str.endsWith("tpl")) { XInputFile _xif = Common.getInputFile(_str); if (_xif != null) { _xif.randomAccessOpen("r"); _xif.randomAccessSeek(0); /** * note: readline does not yet support full unicode here */ while ((str = _xif.randomAccessReadLine()) != null) { xif = Common.getInputFile(str); if (xif != null) collection.addInputFile(xif); } _xif.randomAccessClose(); } } else { xif = Common.getInputFile(_str); if (xif != null) collection.addInputFile(xif); } } catch (Exception e) { System.err.println("File input error"); error = true; } } } catch (Exception ex) { error = true; } catch (Error er) { error = true; } return error; } /** * */ private static void loadIDs(JobCollection collection, String nIDs) { StringTokenizer st = new StringTokenizer(nIDs, ","); String nID = null; int i = 0; collection.clearPIDs(); while (st.hasMoreTokens()) { nID = st.nextToken(); if (!nID.startsWith("0x")) nID = "0x" + Integer.toHexString(Integer.parseInt(nID)); collection.addPID(nID); i++; } Common.setMessage(Resource.getString("msg.loading.pids", String.valueOf(collection.getPIDCount()))); } /** * load cutfile */ private static void loadCutPoints(JobCollection collection, String file) { try { BufferedReader points = new BufferedReader(new FileReader(file)); String point = ""; while (true) { point = points.readLine(); if (point == null) break; if (point.trim().equals("")) continue; if (point.startsWith(Keys.KEY_CutMode[0])) { Common.getSettings().setProperty(Keys.KEY_CutMode[0], point.substring(point.indexOf("=") + 1).trim()); continue; } if (point.startsWith("(")) continue; collection.addCutpoint(point); } points.close(); Common.setMessage("Successful reading of " + String.valueOf(collection.getCutpointCount()) + " cutpoints"); } catch (Exception e5) { Common.setMessage("Error while reading file: '" + file + "'"); Common.setExceptionMessage(e5); } } /** * load chapterfile */ private static void loadChapterPoints(JobCollection collection, String file) { try { BufferedReader points = new BufferedReader(new FileReader(file)); String point = ""; while (true) { point = points.readLine(); if (point == null) break; if (point.trim().equals("")) continue; collection.addChapterpoint(point); } points.close(); Common.setMessage("Successful reading of " + String.valueOf(collection.getChapterpointCount()) + " chapterpoints"); } catch (Exception e5) { Common.setMessage("Error while reading file: '" + file + "'"); Common.setExceptionMessage(e5); } } } project-x/src/net/sourceforge/dvb/projectx/gui/0000700000175000017500000000000010745203152023211 5ustar supermariosupermarioproject-x/src/net/sourceforge/dvb/projectx/gui/AboutBox.java0000600000175000017500000001324410351107526025606 0ustar supermariosupermario/* * @(#)AboutBox.java - about box of Project-X, with terms of condition and credits * * Copyright (c) 2004-2005 by pstorch, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Frame; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JViewport; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.gui.CommonGui; /** * AboutBox for Project-X GUI. * * @author Peter Storch */ public class AboutBox extends JDialog { /** Background Color */ private static final Color BACKGROUND_COLOR = new Color(224,224,224); /** * Constructor of AboutBox. * * @param frame */ public AboutBox(Frame frame) { super(frame, true); setTitle(Resource.getString("about.title")); JPanel container = new JPanel(); container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS)); container.setBorder( BorderFactory.createEmptyBorder(10,10,10,10)); container.setBackground(BACKGROUND_COLOR); JLabel logo = new JLabel(CommonGui.loadIcon("px.gif")); logo.setOpaque(true); logo.setBackground(BACKGROUND_COLOR); container.add(new JLabel(Resource.getString("about.credits.label"))); String credits = "\n" + Resource.getString("credits") + "\n"; JTextArea list = new JTextArea(credits, 5, 10); list.setEnabled(false); list.setDisabledTextColor(Color.black); JScrollPane scroll = new JScrollPane(list); scroll.setBackground(Color.white); scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); container.add(scroll); final CreditsScroller creditScroller = new CreditsScroller(scroll); creditScroller.start(); container.add(new JLabel(" ")); // as spacer String terms[] = Resource.getStringByLines("terms"); for (int a=0; a 0) { viewHeight--; } else { viewHeight++; up = true; } } viewport.setViewPosition(new Point(0,viewHeight)); } } /** * Sets the variable stopIt to bring this Thread to an end. */ public void stopIt() { stopIt = true; } } } project-x/src/net/sourceforge/dvb/projectx/gui/BitrateMonitor.java0000600000175000017500000001727210351107540027026 0ustar supermariosupermario/* * @(#)BitrateMonitor.java * * Copyright (c) 2002-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ /* * the base code was derived from MemoryMonitor.java 1.26 99/04/23 * * Copyright (c) 1998, 1999 by Sun Microsystems, Inc. All Rights Reserved. * * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use, * modify and redistribute this software in source and binary code form, * provided that i) this copyright notice and license appear on all copies of * the software; and ii) Licensee does not utilize the software in a manner * which is disparaging to Sun. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * This software is not designed or intended for use in on-line control of * aircraft, air traffic, aircraft navigation or aircraft communications; or in * the design, construction, operation or maintenance of any nuclear * facility. Licensee represents and warrants that it will not use or * redistribute the Software for such purposes. */ package net.sourceforge.dvb.projectx.gui; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.image.BufferedImage; import javax.swing.JPanel; public class BitrateMonitor extends JPanel { private int w = 110; private int h = 32; private int divisor = 695; private BufferedImage bimg; private Graphics2D big; private Font font = new Font("Times New Roman", Font.PLAIN, 11); private int columnInc; private int pts[]; private int ptNum; private int ascent; private int descent; private int bitrate; private int maxbitrate = 0; private int minbitrate = 37500; private Rectangle graphOutlineRect = new Rectangle(); private Color graphColor = new Color(46, 139, 87); private String usedStr; private String timeStr="00:00:00"; private boolean first = true; private boolean greatgop = false; private Color[] GOP = { Color.black, Color.cyan, Color.magenta, Color.white, Color.green, Color.red, Color.red, Color.red, Color.yellow }; private byte[] frame = new byte[0]; /** * */ public BitrateMonitor() { bimg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); big = bimg.createGraphics(); big.setFont(font); FontMetrics fm = big.getFontMetrics(font); ascent = (int) fm.getAscent(); descent = (int) fm.getDescent(); reset(); setLayout(new BorderLayout()); setBackground(Color.black); setVisible(true); } /** * */ public Dimension getMinimumSize() { return getPreferredSize(); } /** * */ public Dimension getMaximumSize() { return getPreferredSize(); } /** * */ public Dimension getPreferredSize() { return new Dimension(w, h); } /** * */ public void paint(Graphics g) { if (big == null) return; g.drawImage(bimg, 0, 0, this); } /** * */ private void refresh() { if (big == null) return; big.setColor(Color.black); big.clearRect(0, 0, w, h); // .. Draw bitrate string .. big.setColor(Color.white); usedStr = String.valueOf(bitrate * 400 / 1000) + "kbps "; big.drawString(usedStr, 60, h - descent - 9 - descent); big.drawString(timeStr, 60, h - descent); // .. Draw History Graph .. big.setColor(graphColor); int graphX = 2; int graphY = 1; int graphW = 50; // w =55 int graphH = 30; // h=55. 48 graphOutlineRect.setRect(graphX, graphY, graphW, graphH); big.draw(graphOutlineRect); int graphRow = graphH / 5; // .. Draw row .. for (int j = graphY; j <= graphH + graphY; j += graphRow) big.drawLine(graphX, j, graphX + graphW, j); // .. Draw animated column movement .. int graphColumn = graphW / 5; for (int j = graphX; j < graphW + graphX; j += graphColumn) big.drawLine(j, graphY, j, graphY + graphH); //.. 9Mbps big.setColor(Color.red); big.drawLine(2, 5, 52, 5); //.. 2.5Mbps big.setColor(Color.magenta); big.drawLine(2, 28, 52, 28); //.. max,min Mbps big.setColor(Color.white); big.drawLine(52, (graphY + graphH - (maxbitrate / divisor)), 56, (graphY + graphH - (maxbitrate / 695))); big.drawLine(52, (graphY + graphH - (minbitrate / divisor)), 56, (graphY + graphH - (minbitrate / 695))); //.. frametypegraph int b = frame.length > 17 ? 17 : frame.length; for (int a = 0; a < b; a++) { big.setColor(GOP[0xF & frame[a]]); if ((0x80 & frame[a]) != 0) { // progressive frame big.fillRect(60 + (a * 3), 2, 2, 5); } else { // interlaced frame big.fillRect(60 + (a * 3), 2, 2, 2); big.fillRect(60 + (a * 3), 5, 2, 2); } } if (frame.length > 16) greatgop = true; if (greatgop) { big.setColor(Color.red); big.fillRect(52, 40, 2, 5); } if (pts == null) { pts = new int[graphW]; ptNum = 0; } else { big.setColor(Color.yellow); pts[ptNum] = ( graphY + graphH - (bitrate / divisor) ); if (pts[ptNum] < 1) pts[ptNum] = 0; for (int j = graphX + graphW - ptNum, k = 0; k < ptNum; k++, j++) { if (k != 0) { if (pts[k] != pts[k - 1]) big.drawLine(j - 1, pts[k - 1], j, pts[k]); else big.fillRect(j, pts[k], 1, 1); } } if (ptNum + 2 == pts.length) { // throw out oldest point for (int j = 1; j < ptNum; j++) pts[j - 1] = pts[j]; --ptNum; } else ptNum++; } } /** * */ public void reset() { greatgop = false; maxbitrate = 0; minbitrate = 37500; timeStr = "00:00:00"; bitrate = 0; frame = new byte[0]; refresh(); repaint(); } /** * */ public void update(int _bitrate, byte[] _frames, String str) { bitrate = _bitrate; if (bitrate > maxbitrate) maxbitrate = bitrate; if (bitrate < minbitrate) minbitrate = bitrate; timeStr = str; frame = _frames; refresh(); repaint(); } } project-x/src/net/sourceforge/dvb/projectx/gui/CheckBoxListener.java0000600000175000017500000000276010351107552027257 0ustar supermariosupermario/* * @(#)CheckBoxListener * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import javax.swing.JCheckBox; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import net.sourceforge.dvb.projectx.common.Common; /** * */ public class CheckBoxListener implements ActionListener { public void actionPerformed(ActionEvent e) { String actName = e.getActionCommand(); JCheckBox box = (JCheckBox)e.getSource(); Common.getSettings().setBooleanProperty(actName, box.isSelected()); } } project-x/src/net/sourceforge/dvb/projectx/gui/CollectionPanel.java0000600000175000017500000013660610355315776027162 0ustar supermariosupermario/* * @(#)CollectionPanel * * Copyright (c) 2001-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Comparator; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.JLabel; import javax.swing.JButton; import javax.swing.JList; import javax.swing.JSlider; import javax.swing.JTabbedPane; import javax.swing.JComboBox; import javax.swing.JScrollPane; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JCheckBox; import javax.swing.JFileChooser; import javax.swing.SwingUtilities; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.event.ChangeListener; import javax.swing.event.ChangeEvent; import javax.swing.JComponent; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.video.Preview; import net.sourceforge.dvb.projectx.video.PreviewObject; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.gui.ComboBoxIndexListener; import net.sourceforge.dvb.projectx.gui.ComboBoxItemListener; import net.sourceforge.dvb.projectx.gui.CheckBoxListener; import net.sourceforge.dvb.projectx.gui.CommonGui; /** * collection panel */ public class CollectionPanel extends JPanel { private X_JFileChooser chooser; private JList includeList; private JSlider slider; private JTextField includeField; private JTextField cutfield; private JTextField chapterfield; private JTextField pointslength; private JTextField chp; private JTextField firstfile; private JTextField scannedPID; private JLabel titleLabel; private JButton cutdel; private JButton cutadd; private JButton chapterdel; private JButton chapteradd; private JButton loadlist; private JButton savelist; private JComboBox cut_combobox; private JComboBox chapter_combobox; private JComboBox cutmode_combobox; private JTabbedPane tabbedPane; private List previewList = new ArrayList(); private DNDListener2 dnd2 = new DNDListener2(); private CutListener cutAction = new CutListener(); private JumpListener jumpAction = new JumpListener(); private boolean action = false; private boolean decode = false; private String file = " "; private String title = ""; private String navigation[] = { "bwd_ncp.gif", "bwd_100.gif", "bwd_10.gif", "bwd_gop.gif", "fwd_gop.gif", "fwd_10.gif", "fwd_100.gif", "fwd_ncp.gif" }; private int filetype = 0; private int active_collection = 0; private int loadSizeForward = 2560000; private long lastPosition = 0; private Preview Preview = new Preview(loadSizeForward); private JobCollection collection; private CutView cutview; // /** * class to control short OSD fadings */ private class SlideShow implements Runnable { private Thread clockThread = null; private long value = 0; private long skip = 50000; private Object[] cutpoints = null; /** * */ public void start(long _value) { if (clockThread == null) { clockThread = new Thread(this, "SlideShow"); clockThread.setPriority(Thread.MIN_PRIORITY); value = _value; skip = getLoadSize() / 8; getCutPoints(); clockThread.start(); } } /** * */ private void getCutPoints() { cutpoints = collection == null ? null : collection.getCutpoints(); } /** * */ public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { try { for (long val;; ) { val = update(value); Thread.sleep(5); if (!slideshow || val < value) break; value = skipArea(val); if (value < val) break; } stop(); } catch (InterruptedException e) {} } } /** * */ private long update(long val) { return preview(val); } /** * */ private long skipArea(long val) { // next gop if (cutpoints == null || cutpoints.length == 0) return (val + skip); int index = getCutIndex(cutpoints, String.valueOf(val)); // area among cutpoints if (index < 0) { // next gop "in" area if ((index & 1) == 0) return (val + skip); // stop if (-index > cutpoints.length) return (val - skip); // jump to next export area (-index - 1) return Long.parseLong(cutpoints[index + 1].toString()); } // exact cut point "in" area if ((index & 1) == 0) return (val + skip); // stop if (index + 1 >= cutpoints.length) return (val - skip); // jump to next exported area return Long.parseLong(cutpoints[index + 1].toString()); } /** * */ public void stop() { clockThread = null; } } private SlideShow cl = new SlideShow(); private boolean slideshow = false; // ComboBoxIndexListener _ComboBoxIndexListener = new ComboBoxIndexListener(); ComboBoxItemListener _ComboBoxItemListener = new ComboBoxItemListener(); CheckBoxListener _CheckBoxListener = new CheckBoxListener(); class DNDListener2 implements DropTargetListener { public void drop(DropTargetDropEvent e) { try { int dropaction = e.getDropAction(); // 1=copy, 2=move if ( dropaction == 0 || dropaction > 2) { e.rejectDrop(); return; } e.acceptDrop(dropaction); Transferable tr = e.getTransferable(); DataFlavor[] df = tr.getTransferDataFlavors(); List li = (List) tr.getTransferData(df[0]); // see note about mac os x Object[] val = li.toArray(); if (val.length > 0) loadList(val[0].toString()); e.dropComplete(true); } catch (Exception eee) { e.dropComplete(false); Common.setExceptionMessage(eee); } } public void dragEnter(DropTargetDragEvent e) {} public void dragExit(DropTargetEvent e) {} public void dragOver(DropTargetDragEvent e) {} public void dropActionChanged(DropTargetDragEvent e) {} } class JumpListener implements ActionListener { public void actionPerformed(ActionEvent e) { if (collection == null) return; if (!action) return; String actName = e.getActionCommand(); int val = slider.getValue(); /** * prev. cut point pos. */ if (actName.equals(navigation[0])) { int i = 0; int ic = cut_combobox.getItemCount(); if (ic > 0) { i = ic - 1; if (lastPosition > Long.parseLong(cut_combobox.getItemAt(0).toString())) while (lastPosition <= Long.parseLong(cut_combobox.getItemAt(i).toString())) i--; cut_combobox.setSelectedIndex(i); } } else if (actName.equals(navigation[1])) slider.setValue(val - 3125000); else if (actName.equals(navigation[2])) slider.setValue(val - 312500); else if (actName.equals(navigation[3])) slider.setValue(val - 2); else if (actName.equals(navigation[4])) slider.setValue(val + 2); else if (actName.equals(navigation[5])) slider.setValue(val + 312500); else if (actName.equals(navigation[6])) slider.setValue(val + 3125000); /** * next cut point pos. */ else if (actName.equals(navigation[7])) { int i = 0; int ic = cut_combobox.getItemCount(); if (ic > 0) { if (lastPosition < Long.parseLong(cut_combobox.getItemAt(ic - 1).toString())) while (lastPosition >= Long.parseLong(cut_combobox.getItemAt(i).toString())) i++; cut_combobox.setSelectedIndex(i); } } else if (actName.equals("loadlist")) loadList(); else if (actName.equals("savelist")) saveList(); } } class CutListener implements ActionListener { public void actionPerformed(ActionEvent e) { if (collection == null) return; if (!action) return; action = false; String actName = e.getActionCommand(); if (actName.equals("delpoint")) { if (cut_combobox.getItemCount() > 0) removeCutpoint(cut_combobox.getSelectedIndex()); } else if (actName.equals("cutnumber") || actName.equals("addpoint")) { String value = cutfield.getText(); if (!value.equals("") && addCutpoint(value)) { if (Common.getSettings().getIntProperty(Keys.KEY_CutMode) == CommonParsing.CUTMODE_BYTE) collection.setCutImage(value, Common.getMpvDecoderClass().getCutImage()); } cutfield.setText(""); } else if (actName.equals("delchapter")) { if (chapter_combobox.getItemCount() > 0) removeChapterpoint(chapter_combobox.getSelectedIndex()); } else if (actName.equals("addchapter")) { String value = cutfield.getText(); if (!value.equals("") && addChapterpoint(value)) {} } else if (actName.equals("ID")) { try { String value = includeField.getText(); if (!value.equals("")) { if (!value.startsWith("0x")) value = "0x" + Integer.toHexString(0x1FFF & Integer.parseInt(value)); value = value.toUpperCase().replace('X', 'x'); collection.addPID(value); includeList.setListData(collection.getPIDs()); includeList.ensureIndexIsVisible(collection.getPIDs().length - 1); } } catch (NumberFormatException ne) { Common.setOSDErrorMessage(Resource.getString("cutlistener.wrongnumber")); } includeField.setText(""); action = true; return; } /** * changes will be saved immediately */ else if (actName.equals("transferPIDs")) { try { Object[] values = includeList.getSelectedValues(); if (values.length > 0) { JobCollection new_collection = Common.addCollection(collection.getNewInstance()); collection.removePID(values); new_collection.clearPIDs(); new_collection.addPID(values); new_collection.determinePrimaryFileSegments(); entry(Common.getActiveCollection()); } } catch (Exception e2) { Common.setExceptionMessage(e2); } action = true; return; } /** * changes will be saved immediately */ else if (actName.equals("transferCuts")) { try { int NumOfPts = 0; if ((NumOfPts = cut_combobox.getItemCount()) > 2) //2cutpoints are not enough { for (int b = 2; b < NumOfPts; b += 2) { JobCollection new_collection = Common.addCollection(collection.getNewInstance()); new_collection.clearCutpoints(); for (int c = 0; c < 2 && b + c < NumOfPts; c++) new_collection.addCutpoint( collection.removeCutpoint(2)); new_collection.determinePrimaryFileSegments(); } entry(Common.getActiveCollection()); action = true; } } catch (Exception e2) { Common.setExceptionMessage(e2); } action = true; return; } /** * stuff completion for add and del cutpoints */ if (cut_combobox.getItemCount() > 0) { Object[] obj = collection.getCutpoints(); int index = cut_combobox.getSelectedIndex(); Common.getGuiInterface().showCutIcon((index & 1) == 0, obj, previewList); if (actName.equals("cutbox") || actName.equals("delpoint")) { if (Common.getSettings().getIntProperty(Keys.KEY_CutMode) == CommonParsing.CUTMODE_BYTE) preview(Long.parseLong(obj[index].toString())); } if (actName.equals("addpoint")) updateCutView(String.valueOf(lastPosition)); } else { Common.getGuiInterface().showCutIcon(true, null, previewList); updateCutView(String.valueOf(lastPosition)); } /** * stuff completion for add and del chapterpoints */ if (chapter_combobox.getItemCount() > 0) { Object[] obj = collection.getChapterpoints(); int index = chapter_combobox.getSelectedIndex(); chapterfield.setText(String.valueOf(index + 1)); Common.getGuiInterface().showChapterIcon(obj, previewList); if (actName.equals("chapterbox")) { if (Common.getSettings().getIntProperty(Keys.KEY_CutMode) == CommonParsing.CUTMODE_BYTE) preview(Long.parseLong(obj[index].toString())); } } else { Common.getGuiInterface().showChapterIcon(null, previewList); chapterfield.setText(""); } /** * */ if (Common.getSettings().getIntProperty(Keys.KEY_CutMode) == CommonParsing.CUTMODE_BYTE) slider.requestFocus(); getExpectedSize(); action = true; } } /** * */ public CollectionPanel() { initialize(); } /** * */ protected JPanel buildRightPanel() { JPanel panel = new JPanel(); tabbedPane = new JTabbedPane(); tabbedPane.setTabPlacement(SwingConstants.BOTTOM); tabbedPane.addTab("Settings", buildPanel_1()); tabbedPane.addTab("CutViews", buildPanel_2()); final String[] object = Keys.KEY_OptionPanelIndex; int index = Common.getSettings().getIntProperty(object); if (index >= 0 && index < tabbedPane.getTabCount()) tabbedPane.setSelectedIndex(index); tabbedPane.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { Common.getSettings().setProperty(object[0], String.valueOf(tabbedPane.getSelectedIndex())); } }); panel.add(tabbedPane, BorderLayout.CENTER); return panel; } /** * */ protected JPanel buildPanel_1() { JPanel panel = new JPanel(); panel.setLayout (new ColumnLayout()); String[][] objects = { Keys.KEY_Preview_disable, Keys.KEY_Preview_fastDecode, Keys.KEY_Preview_LiveUpdate, Keys.KEY_Preview_AllGops, Keys.KEY_OptionHorizontalResolution, Keys.KEY_OptionDAR }; JCheckBox[] box = new JCheckBox[objects.length]; for (int i = 0; i < objects.length; i++) { box[i] = new JCheckBox(Resource.getString(objects[i][0])); box[i].setPreferredSize(new Dimension(220, 20)); box[i].setMaximumSize(new Dimension(220, 20)); box[i].setToolTipText(Resource.getString(objects[i][0] + Keys.KEY_Tip)); box[i].setActionCommand(objects[i][0]); box[i].setSelected(Common.getSettings().getBooleanProperty(objects[i])); box[i].addActionListener(_CheckBoxListener); } for (int i = 0; i < 4; i++) panel.add(box[i]); panel.add(Box.createRigidArea(new Dimension(1, 4))); panel.add(new JLabel(Resource.getString("CollectionPanel.ExportLimits"))); /** * */ JPanel CL2 = new JPanel(); CL2.setLayout(new BoxLayout(CL2, BoxLayout.X_AXIS)); box[4].setPreferredSize(new Dimension(110, 20)); box[4].setMaximumSize(new Dimension(110, 20)); CL2.add(box[4]); JComboBox combobox_34 = new JComboBox(Keys.ITEMS_ExportHorizontalResolution); combobox_34.setMaximumRowCount(7); combobox_34.setPreferredSize(new Dimension(90, 20)); combobox_34.setMaximumSize(new Dimension(90, 20)); combobox_34.setActionCommand(Keys.KEY_ExportHorizontalResolution[0]); combobox_34.setEditable(true); combobox_34.setSelectedItem(Common.getSettings().getProperty(Keys.KEY_ExportHorizontalResolution)); combobox_34.addActionListener(_ComboBoxItemListener); CL2.add(combobox_34); panel.add(CL2); /** * */ JPanel CL3 = new JPanel(); CL3.setLayout(new BoxLayout(CL3, BoxLayout.X_AXIS)); box[5].setPreferredSize(new Dimension(80, 20)); box[5].setMaximumSize(new Dimension(80, 20)); CL3.add(box[5]); JComboBox combobox_24 = new JComboBox(Keys.ITEMS_ExportDAR); combobox_24.setMaximumRowCount(7); combobox_24.setPreferredSize(new Dimension(120, 20)); combobox_24.setMaximumSize(new Dimension(120, 20)); combobox_24.setActionCommand(Keys.KEY_ExportDAR[0]); combobox_24.setSelectedIndex(Common.getSettings().getIntProperty(Keys.KEY_ExportDAR)); combobox_24.addActionListener(_ComboBoxIndexListener); CL3.add(combobox_24); panel.add(CL3); panel.add(Box.createRigidArea(new Dimension(1, 4))); /** * */ JPanel CL4 = new JPanel(); CL4.setLayout(new BoxLayout(CL4, BoxLayout.X_AXIS)); CL4.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), Resource.getString("CollectionPanel.PidList"))); includeField = new JTextField(""); includeField.setPreferredSize(new Dimension(80, 25)); includeField.setMaximumSize(new Dimension(80, 25)); includeField.setEditable(true); includeField.setActionCommand("ID"); includeField.setToolTipText(Resource.getString("CollectionPanel.PidList.Tip1")); includeList = new JList(); includeList.setToolTipText(Resource.getString("CollectionPanel.PidList.Tip2")); CL4.add(includeField); includeField.addActionListener(cutAction); CL4.add(new JLabel("=>")); JScrollPane scrollList = new JScrollPane(); scrollList.setPreferredSize(new Dimension(80, 100)); scrollList.setMaximumSize(new Dimension(80, 100)); scrollList.setViewportView(includeList); CL4.add(scrollList); includeList.addMouseListener( new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (collection == null) return; if (e.getClickCount() >= 2) { Object[] val = includeList.getSelectedValues(); collection.removePID(val); includeList.setListData(collection.getPIDs()); } } }); panel.add(CL4); panel.add(Box.createRigidArea(new Dimension(1, 4))); JButton pids = new JButton(Resource.getString("CollectionPanel.transferPids1")); pids.setPreferredSize(new Dimension(220, 20)); pids.setMaximumSize(new Dimension(220, 20)); pids.setActionCommand("transferPIDs"); pids.setToolTipText(Resource.getString("CollectionPanel.transferPids1.Tip")); pids.addActionListener(cutAction); panel.add(pids); JButton cpoints = new JButton(Resource.getString("CollectionPanel.transferPids2")); cpoints.setPreferredSize(new Dimension(220,20)); cpoints.setMaximumSize(new Dimension(220,20)); cpoints.setActionCommand("transferCuts"); cpoints.setToolTipText(Resource.getString("CollectionPanel.transferPids2.Tip")); cpoints.addActionListener(cutAction); panel.add(cpoints); panel.add(Box.createRigidArea(new Dimension(1, 6))); return panel; } /** * */ protected JPanel buildPanel_2() { JPanel panel = new JPanel(); panel.setLayout (new BorderLayout()); panel.add(cutview = new CutView()); return panel; } /** * */ protected void setComponentColor(JComponent comp, Color c) { comp.setBackground(c); comp.setForeground(c); } /** * */ private void initialize() { chooser = CommonGui.getMainFileChooser(); setLayout( new BorderLayout() ); JPanel grid = new JPanel(); grid.setLayout(new BorderLayout()); /** * */ JPanel previewPanel = new JPanel(); previewPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLoweredBevelBorder(), Resource.getString("CollectionPanel.CutPanel"))); previewPanel.setLayout ( new BorderLayout() ); previewPanel.setToolTipText(Resource.getString("CollectionPanel.CutPanel.Tip1")); previewPanel.add(CommonGui.getPicturePanel()); /** * */ slider = new JSlider(0, (10240000 / 16), 0); slider.setPreferredSize(new Dimension(512, 24)); slider.setMaximumSize(new Dimension(512, 24)); slider.setValue(0); slider.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (slideshow || previewList.isEmpty() || Common.getSettings().getIntProperty(Keys.KEY_CutMode) != CommonParsing.CUTMODE_BYTE) { slideshow = false; return; } if (e.getClickCount() < 2) return; slideshow = true; cl.start(lastPosition); } }); /** * */ JPanel grid_3 = new JPanel(); grid_3.setLayout(new BoxLayout(grid_3, BoxLayout.X_AXIS)); grid_3.add(buildCutPointPanel()); grid_3.add(buildChapterPointPanel()); /** * */ JPanel grid_1 = new JPanel(); grid_1.setLayout(new GridLayout(0, 2)); grid_1.add(buildNavigationPanel()); grid_1.add(grid_3); /** * */ JPanel grid_2 = new JPanel(); grid_2.setLayout(new BorderLayout()); grid_2.setBorder(BorderFactory.createRaisedBevelBorder()); grid_2.add(slider); grid_2.add(grid_1, BorderLayout.SOUTH); previewPanel.add(grid_2, BorderLayout.SOUTH); slider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { if (collection == null) return; if (!action) return; if (slider.getValueIsAdjusting() && !Common.getSettings().getBooleanProperty(Keys.KEY_Preview_LiveUpdate)) return; long val = (Common.getSettings().getIntProperty(Keys.KEY_CutMode) == CommonParsing.CUTMODE_BYTE ? 16L : 1L) * slider.getValue(); if (Common.getSettings().getIntProperty(Keys.KEY_CutMode) == CommonParsing.CUTMODE_BYTE && val != (lastPosition & ~15)) preview(val); else if (Common.getSettings().getIntProperty(Keys.KEY_CutMode) != CommonParsing.CUTMODE_BYTE) scannedPID.setText(Resource.getString("CollectionPanel.Preview.offline")); getType(); } }); slider.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { if (collection == null) return; int i = 0; int ic = 0; int offs = 0; int keyval=e.getKeyCode(); switch(e.getKeyChar()) { case 'p': ic=cut_combobox.getItemCount(); if (ic > 0) { i = ic - 1; if (lastPosition>Long.parseLong(cut_combobox.getItemAt(0).toString())) while (lastPosition <= Long.parseLong(cut_combobox.getItemAt(i).toString())) i--; cut_combobox.setSelectedIndex(i); } return; case 'n': ic=cut_combobox.getItemCount(); if (ic > 0) { if (lastPosition= Long.parseLong(cut_combobox.getItemAt(i).toString())) i++; cut_combobox.setSelectedIndex(i); } return; case 'a': cutadd.doClick(); return; case 'd': cutdel.doClick(); return; } if (e.isShiftDown()) offs = 62500; else if (e.isControlDown()) offs = 312500; else if (e.isAltDown()) offs = 3125000; else return; switch (keyval) { case KeyEvent.VK_RIGHT: slider.setValue(slider.getValue() + offs); break; case KeyEvent.VK_LEFT: slider.setValue(slider.getValue() - offs); } } }); grid.add(previewPanel); JPanel cutPanel = new JPanel(); cutPanel.setBorder(BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), Resource.getString("CollectionPanel.Various"))); cutPanel.setLayout ( new ColumnLayout() ); titleLabel = new JLabel(""); titleLabel.setPreferredSize(new Dimension(230, 22)); titleLabel.setMaximumSize(new Dimension(230, 22)); // cutPanel.add(titleLabel); cutPanel.add(buildRightPanel()); cutmode_combobox = new JComboBox(Keys.ITEMS_CutMode); cutmode_combobox.setPreferredSize(new Dimension(230, 22)); cutmode_combobox.setMaximumSize(new Dimension(230, 22)); cutmode_combobox.setActionCommand(Keys.KEY_CutMode[0]); cutmode_combobox.setSelectedIndex(Common.getSettings().getIntProperty(Keys.KEY_CutMode)); cutmode_combobox.addActionListener(_ComboBoxIndexListener); cutPanel.add(cutmode_combobox); loadlist = new JButton(Resource.getString("CollectionPanel.loadCutpointList")); loadlist.setPreferredSize(new Dimension(230, 22)); loadlist.setMaximumSize(new Dimension(230, 22)); loadlist.setToolTipText(Resource.getString("CollectionPanel.loadCutpointList.Tip")); //DM18022004 081.6 int17 new loadlist.setActionCommand("loadlist"); loadlist.addActionListener(jumpAction); savelist = new JButton(Resource.getString("CollectionPanel.saveCutpointList")); savelist.setPreferredSize(new Dimension(230, 22)); savelist.setMaximumSize(new Dimension(230, 22)); savelist.setActionCommand("savelist"); savelist.addActionListener(jumpAction); cutPanel.add(loadlist); cutPanel.add(savelist); DropTarget dropTarget_3 = new DropTarget(loadlist, dnd2); DropTarget dropTarget_4 = new DropTarget(cutfield, dnd2); grid.add(cutPanel, BorderLayout.EAST); add(grid); setTitle(Resource.getString("CollectionPanel.Title2")); } /** * */ protected JPanel buildNavigationPanel() { /** * */ JPanel jumpPanel = new JPanel(); jumpPanel.setLayout(new BoxLayout(jumpPanel, BoxLayout.X_AXIS)); JButton jump[] = new JButton[navigation.length]; for (int i = 0; i < jump.length; i++) { jump[i] = new JButton(CommonGui.loadIcon(navigation[i])); jump[i].setPreferredSize(new Dimension(31, 22)); jump[i].setMaximumSize(new Dimension(31, 22)); jump[i].setActionCommand(navigation[i]); jump[i].addActionListener(jumpAction); jumpPanel.add(jump[i]); } /** * */ firstfile = new JTextField(file); firstfile.setToolTipText(Resource.getString("CollectionPanel.CutPanel.Tip2")); firstfile.setBackground(new Color(230, 230, 230)); firstfile.setEditable(false); JPanel panel_1 = new JPanel(); panel_1.setLayout(new GridLayout(1, 1)); panel_1.setPreferredSize(new Dimension(248, 22)); panel_1.setMaximumSize(new Dimension(248, 22)); panel_1.setMinimumSize(new Dimension(248, 22)); panel_1.add(firstfile); /** * */ scannedPID = new JTextField(""); scannedPID.setToolTipText(Resource.getString("CollectionPanel.CutPanel.Tip3")); scannedPID.setBackground(new java.awt.Color(230, 230, 230)); scannedPID.setEditable(false); JPanel panel_2 = new JPanel(); panel_2.setLayout(new GridLayout(1, 1)); panel_2.setPreferredSize(new Dimension(248, 22)); panel_2.setMaximumSize(new Dimension(248, 22)); panel_2.setMinimumSize(new Dimension(248, 22)); panel_2.add(scannedPID); /** * */ JPanel panel = new JPanel(); panel.setLayout(new ColumnLayout()); panel.add(jumpPanel); panel.add(panel_2); panel.add(panel_1); return panel; } /** * */ protected JPanel buildCutPointPanel() { /** * */ cutadd = new JButton(CommonGui.loadIcon("add.gif")); cutadd.setActionCommand("addpoint"); cutadd.setPreferredSize(new Dimension(34, 22)); cutadd.setMaximumSize(new Dimension(34, 22)); cutfield = new JTextField(""); cutfield.setPreferredSize(new Dimension(112, 22)); cutfield.setMaximumSize(new Dimension(112, 22)); cutfield.setToolTipText(Resource.getString("CollectionPanel.CutPanel.Tip4")); cutfield.setActionCommand("cutnumber"); /** * */ JPanel panel_1 = new JPanel(); panel_1.setLayout(new BoxLayout(panel_1, BoxLayout.X_AXIS)); panel_1.add(cutadd); panel_1.add(cutfield); /** * */ cutdel = new JButton(CommonGui.loadIcon("rem.gif")); cutdel.setActionCommand("delpoint"); cutdel.setPreferredSize(new Dimension(34, 22)); cutdel.setMaximumSize(new Dimension(34, 22)); cut_combobox = new JComboBox(); cut_combobox.setMaximumRowCount(8); cut_combobox.setPreferredSize(new Dimension(112, 22)); cut_combobox.setMaximumSize(new Dimension(112, 22)); cut_combobox.setActionCommand("cutbox"); /** * */ JPanel panel_2 = new JPanel(); panel_2.setLayout(new BoxLayout(panel_2, BoxLayout.X_AXIS)); panel_2.add(cutdel); panel_2.add(cut_combobox); /** * */ pointslength = new JTextField(Resource.getString("CollectionPanel.NumberOfPoints")); pointslength.setToolTipText(Resource.getString("CollectionPanel.NumberOfPoints.Tip")); pointslength.setBackground(new java.awt.Color(230, 230, 230)); pointslength.setEditable(false); JPanel panel_3 = new JPanel(); panel_3.setLayout(new GridLayout(1, 1)); panel_3.setPreferredSize(new Dimension(146, 22)); panel_3.setMaximumSize(new Dimension(146, 22)); panel_3.setMinimumSize(new Dimension(146, 22)); panel_3.add(pointslength); cutdel.addActionListener(cutAction); cutadd.addActionListener(cutAction); cut_combobox.addActionListener(cutAction); cutfield.addActionListener(cutAction); /** * */ JPanel panel = new JPanel(); panel.setLayout(new ColumnLayout()); panel.add(panel_1); panel.add(panel_2); panel.add(panel_3); Color c = new Color(200, 150, 200); setComponentColor(cutadd, c); setComponentColor(cutdel, c); setComponentColor(panel, c); return panel; } /** * */ protected JPanel buildChapterPointPanel() { /** * */ chapteradd = new JButton(CommonGui.loadIcon("add.gif")); chapteradd.setActionCommand("addchapter"); chapteradd.setPreferredSize(new Dimension(34, 22)); chapteradd.setMaximumSize(new Dimension(34, 22)); chapterdel = new JButton(CommonGui.loadIcon("rem.gif")); chapterdel.setActionCommand("delchapter"); chapterdel.setPreferredSize(new Dimension(34, 22)); chapterdel.setMaximumSize(new Dimension(34, 22)); chapterfield = new JTextField(""); chapterfield.setPreferredSize(new Dimension(34, 22)); chapterfield.setMaximumSize(new Dimension(34, 22)); chapterfield.setEditable(false); /** * */ JPanel panel_1 = new JPanel(); panel_1.setLayout(new BoxLayout(panel_1, BoxLayout.X_AXIS)); panel_1.add(chapteradd); panel_1.add(chapterdel); panel_1.add(chapterfield); /** * */ chapter_combobox = new JComboBox(); chapter_combobox.setMaximumRowCount(8); chapter_combobox.setPreferredSize(new Dimension(102, 22)); chapter_combobox.setMaximumSize(new Dimension(102, 22)); chapter_combobox.setActionCommand("chapterbox"); /** * */ JPanel panel_2 = new JPanel(); panel_2.setLayout(new BoxLayout(panel_2, BoxLayout.X_AXIS)); panel_2.add(chapter_combobox); /** * */ chp = new JTextField(Resource.getString("CollectionPanel.NumberOfChapters")); chp.setToolTipText(Resource.getString("CollectionPanel.NumberOfChapters.Tip")); chp.setBackground(new java.awt.Color(230, 230, 230)); chp.setEditable(false); JPanel panel_3 = new JPanel(); panel_3.setLayout(new GridLayout(1, 1)); panel_3.setPreferredSize(new Dimension(102, 22)); panel_3.setMaximumSize(new Dimension(102, 22)); panel_3.setMinimumSize(new Dimension(102, 22)); panel_3.add(chp); chapterdel.addActionListener(cutAction); chapteradd.addActionListener(cutAction); chapter_combobox.addActionListener(cutAction); chp.addActionListener(cutAction); /** * */ JPanel panel = new JPanel(); panel.setLayout(new ColumnLayout()); panel.add(panel_1); panel.add(panel_2); panel.add(panel_3); Color c = new Color(195, 205, 255); setComponentColor(chapteradd, c); setComponentColor(chapterdel, c); setComponentColor(panel, c); return panel; } /** * */ private void getType() { /** * cuts */ Object[] obj = collection != null ? collection.getCutpoints() : new Object[0]; int index; if (obj.length > 0) { index = getCutIndex(obj, String.valueOf(lastPosition)); Common.getGuiInterface().showCutIcon((index & 1) == 0, obj, previewList); } else Common.getGuiInterface().showCutIcon(true, null, previewList); /** * chapters */ obj = collection != null ? collection.getChapterpoints() : new Object[0]; if (obj.length > 0) Common.getGuiInterface().showChapterIcon(obj, previewList); else Common.getGuiInterface().showChapterIcon(null, previewList); } /** * */ private int getLoadSize() { try { int val = Integer.parseInt(Common.getSettings().getProperty(Keys.KEY_PreviewBuffer)); return val; } catch (Exception e) { Common.setMessage("!> wrong preview_buffer field entry", true); } return loadSizeForward; } /** * */ private long preview(long position) { boolean direction = false; try { if (Common.getSettings().getIntProperty(Keys.KEY_CutMode) != CommonParsing.CUTMODE_BYTE || previewList.isEmpty()) { scannedPID.setText(Resource.getString("CollectionPanel.Preview.offline")); return lastPosition; } action = false; int loadSize = getLoadSize(); // bytes for searching the next I-frame ;changed for X0.81 if (position>>>4 >= (long)slider.getMaximum()) // last { position = position > loadSize ? position - loadSize : 0; direction = true; } else if (position > 0 && position < lastPosition && ((lastPosition>>>4) - (position>>>4)) < 3L ) { position = position > loadSize ? position - loadSize : 0; direction = true; } position = Preview.load(position, ((direction && position == 0) ? (int)lastPosition : loadSize), previewList, direction, Common.getSettings().getBooleanProperty(Keys.KEY_Preview_AllGops), Common.getSettings().getBooleanProperty(Keys.KEY_Preview_fastDecode), collection.getPIDs(), active_collection); String str = Preview.getProcessedFile(); if (str.length() > 32) { int i = str.indexOf('-'); String _str = str.substring(0, i + 2); str = _str + "..." + str.substring(i + 2 + (str.length() - 34 - i), str.length()); } firstfile.setText(str); scannedPID.setText(Resource.getString("CollectionPanel.Preview.processedPid") + Preview.getProcessedPID()); lastPosition = position; slider.setValue((int)(lastPosition / 16)); cutfield.setText(String.valueOf(lastPosition)); slider.requestFocus(); } catch (IOException e6) { Common.setExceptionMessage(e6); } setTitle(title); getExpectedSize(); updateCutView(String.valueOf(lastPosition)); action = true; return lastPosition; } /** * */ private boolean addChapterpoint(String value) { int index = 0; index = getCutIndex(collection.getChapterpoints(), value); if (index >= 0) return false; collection.addChapterpoint(-index - 1, value); reloadChapterpoints(); chapter_combobox.setSelectedItem(value); return true; } /** * */ private Object removeChapterpoint(int index) { Object obj = collection.removeChapterpoint(index); reloadChapterpoints(); Object[] objects = collection.getChapterpoints(); if (objects.length > 0) { int _index = -getCutIndex(collection.getChapterpoints(), obj.toString()) - 1; if (_index >= objects.length) _index = objects.length - 1; chapter_combobox.setSelectedIndex(_index); } return obj; } /** * */ private void reloadChapterpoints() { chapter_combobox.removeAllItems(); Object[] object = collection != null ? collection.getChapterpoints() : new Object[0]; for (int i = 0; i < object.length; i++) chapter_combobox.addItem(object[i]); } /** * */ private boolean addCutpoint(String value) { int index = 0; index = getCutIndex(collection.getCutpoints(), value); if (index >= 0) return false; collection.addCutpoint(-index - 1, value); reloadCutpoints(); cut_combobox.setSelectedItem(value); return true; } /** * */ private Object removeCutpoint(int index) { Object obj = collection.removeCutpoint(index); reloadCutpoints(); Object[] objects = collection.getCutpoints(); if (objects.length > 0) { int _index = -getCutIndex(collection.getCutpoints(), obj.toString()) - 1; if (_index >= objects.length) _index = objects.length - 1; cut_combobox.setSelectedIndex(_index); } return obj; } /** * */ private void reloadCutpoints() { cut_combobox.removeAllItems(); Object[] object = collection != null ? collection.getCutpoints() : new Object[0]; for (int i = 0; i < object.length; i++) cut_combobox.addItem(object[i]); } /** * */ private int getCutIndex(Object[] obj, String value) { class MyComparator implements Comparator { public int compare(Object o1, Object o2) { if (Common.getSettings().getIntProperty(Keys.KEY_CutMode) == CommonParsing.CUTMODE_TIME) return Long.toString(CommonParsing.parseCutValue(o1.toString(), false)).compareTo(Long.toString(CommonParsing.parseCutValue(o2.toString(), false))); else return Long.valueOf(o1.toString()).compareTo(Long.valueOf(o2.toString())); } } /** * handle wrong numbers */ if (Common.getSettings().getIntProperty(Keys.KEY_CutMode) == CommonParsing.CUTMODE_BYTE) if (CommonParsing.parseCutValue(value, false) < 0) return 0; return Arrays.binarySearch(obj, value, new MyComparator()); // is already sorted } /** * updates last and next cutpoint view */ private void updateCutView(String value) { if (Common.getSettings().getIntProperty(Keys.KEY_CutMode) != CommonParsing.CUTMODE_BYTE) { cutview.clearViews(); return; } Object[] listData = collection == null ? null : collection.getCutpoints(); if (listData == null || listData.length == 0) { cutview.clearViews(); return; } int index = getCutIndex(listData, value); if (index < 0) { int i = -index - 1; cutview.setMatchingPoint(false, listData, index); cutview.setImage(i < listData.length ? collection.getCutImage(listData[i]) : null, listData, i, cutview.getBottom()); cutview.setImage(i - 1 >= 0 && i - 1 < listData.length ? collection.getCutImage(listData[i - 1]) : null, listData, i - 1, cutview.getTop()); } else { if (collection.getCutImage(listData[index]) == null) collection.setCutImage(value, Common.getMpvDecoderClass().getCutImage()); cutview.setMatchingPoint(true, listData, index); cutview.setImage(index + 1 < listData.length ? collection.getCutImage(listData[index + 1]) : null, listData, index + 1, cutview.getBottom()); cutview.setImage(index - 1 >= 0 ? collection.getCutImage(listData[index - 1]) : null, listData, index - 1, cutview.getTop()); } } /** * */ private boolean checkActiveCollection() { if (active_collection >= 0) return true; collection = null; action = false; includeList.setListData(new Object[0]); previewList.clear(); reloadCutpoints(); reloadChapterpoints(); Common.getGuiInterface().showCutIcon(true, null, previewList); Common.getGuiInterface().showChapterIcon(null, previewList); scannedPID.setText(Resource.getString("CollectionPanel.Preview.offline")); firstfile.setText(""); slider.setMaximum(1); setTitle(Resource.getString("CollectionPanel.Title2")); Common.setOSDMessage(Resource.getString("CollectionPanel.Preview.offline")); action = true; return false; } /** * */ public void entry(int _active_collection) { if (active_collection != _active_collection) cutview.clearViews(); active_collection = _active_collection; Common.getMpvDecoderClass().clearPreviewPixel(); /** * */ if (!checkActiveCollection()) return; CommonGui.getPicturePanel().showCollectionNumber(active_collection); cutmode_combobox.setSelectedIndex(Common.getSettings().getIntProperty(Keys.KEY_CutMode)); collection = Common.getCollection(active_collection); includeList.setListData(collection.getPIDs()); List input_files = collection.getInputFilesAsList(); previewList.clear(); file = !input_files.isEmpty() ? input_files.get(0).toString() : ""; /** * determine primary file segments, scan only if changed (date modified) or not scanned */ long start = 0; long end = 0; int size = input_files.size(); int primaryFilesCount = 1; if (Common.getSettings().getBooleanProperty(Keys.KEY_Preview_disable)) size = 0; filesearch: for (int a = 0, b = -1, type = -1; a < size; a++) { XInputFile xInputFile = ((XInputFile) input_files.get(a)).getNewInstance(); if (xInputFile == null) continue; if (xInputFile.getStreamInfo() == null) Common.getScanClass().getStreamInfo(xInputFile); //note: is a new instance type = xInputFile.getStreamInfo().getStreamType(); if (b != -1 && b != type) { primaryFilesCount = a; break filesearch; } switch (type) { case CommonParsing.PES_AV_TYPE: case CommonParsing.MPEG1PS_TYPE: case CommonParsing.MPEG2PS_TYPE: case CommonParsing.PVA_TYPE: case CommonParsing.TS_TYPE: case CommonParsing.ES_MPV_TYPE: b = type; start = end; end += xInputFile.length(); previewList.add(new PreviewObject(start, end, type, xInputFile)); break; default: break filesearch; } } action = false; slider.setMaximum(end > 16 ? (int)(end / 16) : 1); action = true; if (Common.getSettings().getIntProperty(Keys.KEY_CutMode) == CommonParsing.CUTMODE_BYTE && !previewList.isEmpty()) preview(0); else { scannedPID.setText(Resource.getString("CollectionPanel.Preview.offline")); firstfile.setText(""); Common.getMpvDecoderClass().clearPreviewPixel(); Common.setOSDMessage(Resource.getString("CollectionPanel.Preview.offline")); } title = Resource.getString("CollectionPanel.Title2") + " " + active_collection; setTitle(title); action = false; reloadCutpoints(); reloadChapterpoints(); cut_combobox.setSelectedIndex(cut_combobox.getItemCount() - 1); getExpectedSize(); getType(); action = true; } /** * */ private void saveList() { Object[] object = collection.getCutpoints(); if (object.length == 0) return; String newfile = file + "[" + active_collection + "].Xcl"; chooser.setSelectedFile(new File(newfile)); chooser.rescanCurrentDirectory(); int retval = chooser.showSaveDialog(this); if(retval == JFileChooser.APPROVE_OPTION) { File theFile = chooser.getSelectedFile(); if(theFile != null && !theFile.isDirectory()) { newfile = theFile.getAbsolutePath(); } } else return; try { BufferedWriter listwriter = new BufferedWriter(new FileWriter(newfile)); listwriter.write(Keys.KEY_CutMode[0] + "=" + Common.getSettings().getProperty(Keys.KEY_CutMode)); listwriter.newLine(); for (int i = 0; i < object.length; i++) { listwriter.write(object[i].toString()); listwriter.newLine(); } listwriter.close(); } catch (IOException e) { Common.setMessage(Resource.getString("CollectionPanel.FileAccessError") + " " + file); } } /** * */ private void loadList() { loadList(""); } /** * */ private void loadList(String newfile) { List pointlist = new ArrayList(); String point = ""; if (!(new File(newfile).exists())) { chooser.rescanCurrentDirectory(); int retval = chooser.showOpenDialog(this); if(retval == JFileChooser.APPROVE_OPTION) { File theFile = chooser.getSelectedFile(); if(theFile != null && !theFile.isDirectory()) newfile = theFile.getAbsolutePath(); } else return; } try { BufferedReader listreader = new BufferedReader(new FileReader(newfile)); while (true) { point = listreader.readLine(); if (point == null) break; if (point.trim().equals("")) continue; if (point.startsWith(Keys.KEY_CutMode[0])) { cutmode_combobox.setSelectedIndex(Integer.parseInt(point.substring(point.indexOf("=") + 1).trim())); continue; } if (point.startsWith("(")) continue; pointlist.add(point); } listreader.close(); } catch (IOException e5) { Common.setMessage(Resource.getString("CollectionPanel.loadCutpointList.Error") + " " + file); } Object[] obj = pointlist.toArray(); if (obj.length > 0) { long[] cutPoints = new long[obj.length]; for (int i = 0; i < cutPoints.length; i++) cutPoints[i] = CommonParsing.parseCutValue(obj[i].toString(), false); Arrays.sort(cutPoints); for (int i = 0; i < cutPoints.length; i++) collection.addCutpoint(CommonParsing.parseCutValue(cutPoints[i])); action = false; reloadCutpoints(); cut_combobox.setSelectedIndex(cut_combobox.getItemCount() - 1); } getExpectedSize(); getType(); action = true; } /** * */ private void getExpectedSize() { if (previewList.isEmpty()) { pointslength.setText(Resource.getString("CollectionPanel.NumberOfPoints") + " " + cut_combobox.getItemCount()); return; } Object[] object = collection.getCutpoints(); long newSize[] = new long[object.length]; long start = 0; long diff = 0; long end = 0; if (Common.getSettings().getIntProperty(Keys.KEY_CutMode) == CommonParsing.CUTMODE_BYTE) { for (int i = 0; i < newSize.length; i++) newSize[i] = Long.parseLong(object[i].toString()); if (newSize.length == 0 || (newSize.length & 1) == 1) end = ((PreviewObject) previewList.get(previewList.size() - 1)).getEnd(); else end = newSize[newSize.length - 1]; for (int i = 0; i < newSize.length; i += 2) { diff += newSize[i] - start; start = i + 1 < newSize.length ? newSize[i + 1] : start; } } String length = Common.getSettings().getIntProperty(Keys.KEY_CutMode) == CommonParsing.CUTMODE_BYTE ? (Resource.getString("CollectionPanel.expectedSize") + ((end - diff) / 1048576L) + "MB") : ""; pointslength.setText(length); chp.setText(Resource.getString("CollectionPanel.NumberOfChapters") + " " + chapter_combobox.getItemCount()); } private void setTitle(String str) { titleLabel.setText(str); } } project-x/src/net/sourceforge/dvb/projectx/gui/ColumnLayout.java0000600000175000017500000000500210351107572026510 0ustar supermariosupermario/* * @(#)ColumnLayout.java - * * Copyright (c) 2005 by ?, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import java.awt.LayoutManager; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; public class ColumnLayout implements LayoutManager { int xInset = 2; int yInset = 0; int yGap = 0; public void addLayoutComponent(String s, Component c) {} public void layoutContainer(Container c) { Insets insets = c.getInsets(); int height = yInset + insets.top; Component[] children = c.getComponents(); Dimension compSize = null; for (int i = 0; i < children.length; i++) { compSize = children[i].getPreferredSize(); children[i].setSize(compSize.width, compSize.height); children[i].setLocation( xInset + insets.left, height); height += compSize.height + yGap; } } public Dimension minimumLayoutSize(Container c) { Insets insets = c.getInsets(); int height = yInset + insets.top; int width = 0 + insets.left + insets.right; Component[] children = c.getComponents(); Dimension compSize = null; for (int i = 0; i < children.length; i++) { compSize = children[i].getPreferredSize(); height += compSize.height + yGap; width = Math.max(width, compSize.width + insets.left + insets.right + xInset*2); } height += insets.bottom; return new Dimension( width, height); } public Dimension preferredLayoutSize(Container c) { return minimumLayoutSize(c); } public void removeLayoutComponent(Component c) {} } project-x/src/net/sourceforge/dvb/projectx/gui/ComboBoxIndexListener.java0000600000175000017500000000301110351107602030253 0ustar supermariosupermario/* * @(#)ComboBoxIndexListener * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import javax.swing.JComboBox; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import net.sourceforge.dvb.projectx.common.Common; /** * */ public class ComboBoxIndexListener implements ActionListener { public void actionPerformed(ActionEvent e) { String actName = e.getActionCommand(); JComboBox box = (JComboBox)e.getSource(); Common.getSettings().setProperty(actName, String.valueOf(box.getSelectedIndex())); } } project-x/src/net/sourceforge/dvb/projectx/gui/ComboBoxItemListener.java0000600000175000017500000000315510351107612030114 0ustar supermariosupermario/* * @(#)ComboBoxItemListener * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import javax.swing.JComboBox; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import net.sourceforge.dvb.projectx.common.Common; /** * */ public class ComboBoxItemListener implements ActionListener { public void actionPerformed(ActionEvent e) { String actName = e.getActionCommand(); // refuse additional actioncommand "comboBoxEdit" from jre > 1.4 ? if (actName.indexOf('.') < 0) return; JComboBox box = (JComboBox)e.getSource(); Common.getSettings().setProperty(actName, box.getSelectedItem()); } } project-x/src/net/sourceforge/dvb/projectx/gui/CommonGui.java0000600000175000017500000001045710351107624025762 0ustar supermariosupermario/* * @(#)CommonGui * * Copyright (c) 2004-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import javax.swing.JOptionPane; import javax.swing.JFrame; import javax.swing.AbstractButton; import javax.swing.ImageIcon; import net.sourceforge.dvb.projectx.gui.X_JFileChooser; import net.sourceforge.dvb.projectx.gui.PicturePanel; import net.sourceforge.dvb.projectx.common.Resource; public class CommonGui extends Object { private static JFrame frame = null; private static Object suggestion = null; private static X_JFileChooser chooser; private static PicturePanel picturepanel; /** * */ public CommonGui() { chooser = new X_JFileChooser(); picturepanel = new PicturePanel(); } public static void setMainFrame(JFrame _frame) { frame = _frame; } /** * */ public static String getUserInput(String arg1) { return getUserInput(arg1, null); } /** * */ public static String getUserInput(String arg1, String arg2) { Object obj = getUserInput(arg1, arg2, suggestion); if (obj != null) { suggestion = obj; return obj.toString(); } return null; } /** * user dialog field filled with suggestion * by 'mcr42' 2005/06/16 */ public static String getUserInput(String arg1, String arg2, Object arg3) { return getUserInput(null, arg1, arg2, arg3); } /** * */ public static String getUserInput(JFrame _frame, String arg1, String arg2, Object arg3) { if (_frame == null) _frame = frame; Object obj = JOptionPane.showInputDialog(_frame, arg1, arg2, JOptionPane.QUESTION_MESSAGE, null, null, arg3); if (obj != null) return obj.toString(); return null; } /** * */ public static boolean getUserConfirmation(String arg1) { int option = JOptionPane.showConfirmDialog(frame, arg1); if (option == JOptionPane.YES_OPTION) return true; return false; } /** * */ public static void showErrorMessageDialog(Object message, String title) { JOptionPane.showMessageDialog(null, message, title, JOptionPane.ERROR_MESSAGE); } /** * */ public static void showMessageDialog(Object message, String title) { JOptionPane.showMessageDialog(null, message, title, JOptionPane.INFORMATION_MESSAGE); } /** * Sets a button's text and mnemonic values using the specified resource * key. The button text is scanned for &. If found the character after it is * used as menmonic. * * @param button * the button (e.g. a menu or menu item) to localize * @param key * the resource string to find */ public static final void localize(AbstractButton button, String key) { String text = Resource.getString(key); int pos = text.indexOf('&'); if (pos != -1) { char mnemonic = text.charAt(pos + 1); button.setMnemonic(mnemonic); text = text.substring(0, pos) + text.substring(pos + 1); } button.setText(text); } /** * Loads an image as ImageIcon. * * @param iconName * @return ImageIcon */ public static ImageIcon loadIcon(String iconName) { return new ImageIcon(Resource.getResourceURL(iconName)); } /** * */ public static X_JFileChooser getMainFileChooser() { return chooser; } /** * */ public static PicturePanel getPicturePanel() { return picturepanel; } } project-x/src/net/sourceforge/dvb/projectx/gui/CutView.java0000600000175000017500000001166510363600074025455 0ustar supermariosupermario/* * @(#)CutView * * Copyright (c) 2005-2006 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Image; import java.awt.image.MemoryImageSource; import java.awt.Font; import java.util.Arrays; import javax.swing.JPanel; public class CutView extends JPanel { private final int Top = 20; private final int Bottom = 184; private int[] image_data; private int width = 224; private int height = 126; private boolean matchingPoint = false; private boolean cut_top = true; private boolean cut_bottom = false; private boolean cut_match = false; private String string_bottom = "Next:"; private String string_top = "Prev:"; private String string_matchingpoint = ""; private String[] string_in_out = { " -IN- ", " -OUT- " }; private Image image_top; private Image image_bottom; private MemoryImageSource source_top; private MemoryImageSource source_bottom; private final Color BackgroundColor; private final Color RedColor; private final Font font; /** * */ public CutView() { image_data = new int[width * height]; source_top = new MemoryImageSource(width, height, image_data, 0, width); source_top.setAnimated(true); image_top = createImage(source_top); source_bottom = new MemoryImageSource(width, height, image_data, 0, width); source_bottom.setAnimated(true); image_bottom = createImage(source_bottom); BackgroundColor = new Color(0, 35, 110); RedColor = new Color(255, 100, 100); font = new Font("Tahoma", Font.PLAIN, 14); setBackground(Color.black); setVisible(true); } /** * */ public int getTop() { return Top; } /** * */ public int getBottom() { return Bottom; } /** * */ public void clearViews() { matchingPoint = false; clearView(Top); clearView(Bottom); } /** * */ public void clearView(int position) { Arrays.fill(image_data, 0xFF505050); updateView(position); } /** * */ public void updateView(int position) { updateView(position, null, -1); } /** * */ public void updateView(int position, Object[] object, int index) { if (position < 100) { source_top.newPixels(); string_top = "Prev: " + (object != null ? "#" + index + " @ " + object[index] + string_in_out[index & 1] : "= Collection Begin"); cut_top = object != null ? (index & 1) == 0 : (!matchingPoint ? !cut_bottom : false); } else { source_bottom.newPixels(); string_bottom = "Next: " + (object != null ? "#" + index + " @ " + object[index] + string_in_out[index & 1] : "= Collection End"); cut_bottom = object != null ? (index & 1) == 0 : false; } repaint(); } /** * */ public void setImage(int[] data, Object[] object, int index, int position) { if (data == null) { clearView(position); return; } System.arraycopy(data, 0, image_data, 0 , data.length); updateView(position, object, index); } /** * */ public void setMatchingPoint(boolean b, Object[] object, int index) { matchingPoint = b; string_matchingpoint = matchingPoint ? "This: #" + index + " @ " + object[index] + string_in_out[index & 1] : ""; cut_match = (index & 1) == 0; } /** * */ public void paint(Graphics g) { g.setColor(BackgroundColor); g.fillRect(0, 0, 300, 500); g.setFont(font); g.setColor(cut_top ? Color.green : RedColor); g.drawRect(0, Top - 1, width - 1, height + 1); g.drawString(string_top, 8, Top - 4); g.setColor(cut_bottom ? Color.green : RedColor); g.drawRect(0, Bottom - 1, width - 1, height + 1); g.drawString(string_bottom, 8, Bottom - 4); if (matchingPoint) { g.setColor(cut_match ? Color.green : RedColor); g.drawString(string_matchingpoint, 8, Bottom - 21); } g.drawImage(image_top, 0, Top, this); g.drawImage(image_bottom, 0, Bottom, this); } } project-x/src/net/sourceforge/dvb/projectx/gui/FtpChooser.java0000600000175000017500000003462710351107644026150 0ustar supermariosupermario/* * @(#)FtpChooser.java - for ftp access * * Copyright (c) 2004-2005 by roehrist, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.FocusEvent; import java.awt.event.FocusAdapter; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.Dimension; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.xinput.XInputDirectory; import net.sourceforge.dvb.projectx.xinput.ftp.FtpVO; /** *

* berschrift: *

*

* Beschreibung: *

*

* Copyright: Copyright (c) 2004 *

*

* Organisation: *

* * @author unbekannt * @version 1.0 */ public class FtpChooser extends JDialog { private final String _base_key = "FtpServer."; private final String ftp_server = "192.168.0.5"; private final String ftp_port = "21"; private final String ftp_user = "root"; private final String ftp_password = "dreambox"; private final String ftp_directory = "/hdd/movie"; boolean isTested; XInputDirectory xInputDirectory; GridBagLayout gridBagLayout1 = new GridBagLayout(); JPanel jPanel1 = new JPanel(); JLabel jLabel1 = new JLabel(); JLabel jLabel1a = new JLabel(); JLabel jLabel2 = new JLabel(); JLabel jLabel3 = new JLabel(); JLabel jLabel4 = new JLabel(); JTextField tfServer = new JTextField(); JTextField tfPort = new JTextField(); JTextField tfUser = new JTextField(); JTextField tfPassword = new JTextField(); JTextField tfDirectory = new JTextField(); JButton testButton = new JButton(); JLabel jLabel5 = new JLabel(); JTextField tfState = new JTextField(); JButton okButton = new JButton(); JButton cancelButton = new JButton(); JScrollPane spState = new JScrollPane(); JTextArea taState = new JTextArea(); GridBagLayout gridBagLayout2 = new GridBagLayout(); public FtpChooser() { try { jbInit(); loadFields(); } catch (Exception e) { e.printStackTrace(); } } public XInputDirectory getXInputDirectory() { return xInputDirectory; } public void setXInputDirectory(XInputDirectory aXInputDirectory) { isTested = false; okButton.setEnabled(false); tfServer.setText(aXInputDirectory.getServer()); tfPort.setText(aXInputDirectory.getPort()); tfUser.setText(aXInputDirectory.getUser()); tfPassword.setText(aXInputDirectory.getPassword()); tfDirectory.setText(aXInputDirectory.getDirectory()); } public boolean isTested() { return isTested; } private void jbInit() throws Exception { this.getContentPane().setLayout(gridBagLayout1); jPanel1.setLayout(gridBagLayout2); jLabel1.setToolTipText(Resource.getString("ftpchooser.server.tip")); jLabel1.setText(Resource.getString("ftpchooser.server")); jLabel1a.setToolTipText(Resource.getString("ftpchooser.port.tip")); jLabel1a.setText(Resource.getString("ftpchooser.port")); jLabel2.setToolTipText(Resource.getString("ftpchooser.user.tip")); jLabel2.setText(Resource.getString("ftpchooser.user")); jLabel3.setToolTipText(Resource.getString("ftpchooser.password.tip")); jLabel3.setText(Resource.getString("ftpchooser.password")); jLabel4.setToolTipText(Resource.getString("ftpchooser.directory.tip")); jLabel4.setText(Resource.getString("ftpchooser.directory")); tfServer.setMinimumSize(new Dimension(80, 21)); tfServer.setNextFocusableComponent(tfPort); tfServer.setPreferredSize(new Dimension(80, 21)); tfServer.setToolTipText(Resource.getString("ftpchooser.server.tip")); tfServer.setText(ftp_server); tfServer.addFocusListener(new FtpChooser_tfServer_focusAdapter(this)); tfPort.setMinimumSize(new Dimension(80, 21)); tfPort.setNextFocusableComponent(tfUser); tfPort.setPreferredSize(new Dimension(80, 21)); tfPort.setToolTipText(Resource.getString("ftpchooser.port.tip")); tfPort.setText(ftp_port); tfPort.addFocusListener(new FtpChooser_tfPort_focusAdapter(this)); tfUser.setNextFocusableComponent(tfPassword); tfUser.setToolTipText(Resource.getString("ftpchooser.user.tip")); tfUser.setText(ftp_user); tfUser.addFocusListener(new FtpChooser_tfUser_focusAdapter(this)); tfPassword.setNextFocusableComponent(tfDirectory); tfPassword.setToolTipText(Resource.getString("ftpchooser.password.tip")); tfPassword.setText(ftp_password); tfPassword.addFocusListener(new FtpChooser_tfPassword_focusAdapter(this)); tfDirectory.setMinimumSize(new Dimension(153, 21)); tfDirectory.setNextFocusableComponent(testButton); tfDirectory.setPreferredSize(new Dimension(153, 21)); tfDirectory.setToolTipText(Resource.getString("ftpchooser.directory.tip")); tfDirectory.setText(ftp_directory); tfDirectory.addFocusListener(new FtpChooser_tfDirectory_focusAdapter(this)); testButton.setNextFocusableComponent(okButton); testButton.setText(Resource.getString("ftpchooser.test")); testButton.addActionListener(new FtpChooser_testButton_actionAdapter(this)); jLabel5.setToolTipText(Resource.getString("ftpchooser.state.tip")); jLabel5.setText(Resource.getString("ftpchooser.state")); tfState.setEditable(false); tfState.setText(Resource.getString("ftpchooser.untested")); okButton.setEnabled(false); okButton.setNextFocusableComponent(cancelButton); okButton.setText(Resource.getString("ftpchooser.ok")); okButton.addActionListener(new FtpChooser_okButton_actionAdapter(this)); cancelButton.setNextFocusableComponent(tfServer); cancelButton.setText(Resource.getString("ftpchooser.cancel")); cancelButton.addActionListener(new FtpChooser_cancelButton_actionAdapter(this)); spState.setViewportView(taState); jPanel1.setMinimumSize(new Dimension(600, 266)); jPanel1.setPreferredSize(new Dimension(600, 266)); this.setModal(true); this.setTitle(Resource.getString("ftpchooser.title")); taState.setEditable(false); jPanel1.add(jLabel1, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 10, 5, 5), 0, 0)); jPanel1.add(jLabel1a, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 10, 5, 5), 0, 0)); jPanel1.add(jLabel2, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 10, 5, 5), 0, 0)); jPanel1.add(jLabel4, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 10, 5, 5), 0, 0)); jPanel1.add(jLabel3, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 10, 5, 5), 0, 0)); jPanel1.add(jLabel5, new GridBagConstraints(0, 5, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 10, 5, 5), 0, -3)); jPanel1.add(tfServer, new GridBagConstraints(1, 0, 2, 1, 0.5, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 5, 5), 64, 0)); jPanel1.add(tfPort, new GridBagConstraints(1, 1, 2, 1, 0.5, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 5, 5), 64, 0)); jPanel1.add(tfUser, new GridBagConstraints(1, 2, 2, 1, 0.5, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 119, 0)); jPanel1.add(tfPassword, new GridBagConstraints(1, 3, 2, 1, 0.5, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 89, 0)); jPanel1.add(tfDirectory, new GridBagConstraints(1, 4, 2, 1, 0.5, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); jPanel1.add(tfState, new GridBagConstraints(1, 5, 2, 1, 0.5, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 93, -1)); jPanel1.add(testButton, new GridBagConstraints(0, 6, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTH, GridBagConstraints.NONE, new Insets(5, 10, 10, 5), 15, 0)); jPanel1.add(okButton, new GridBagConstraints(1, 6, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTH, GridBagConstraints.NONE, new Insets(5, 5, 10, 5), 21, 0)); jPanel1.add(cancelButton, new GridBagConstraints(2, 6, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTH, GridBagConstraints.NONE, new Insets(5, 5, 10, 5), 3, 0)); jPanel1.add(spState, new GridBagConstraints(3, 0, 1, 6, 0.5, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(10, 5, 10, 10), 193, 229)); this.getContentPane().add( jPanel1, new GridBagConstraints(0, 0, 4, 4, 1.0, 1.0, GridBagConstraints.SOUTHEAST, GridBagConstraints.BOTH, new Insets( 0, 0, 0, 0), 0, 0)); xInputDirectory = null; isTested = false; okButton.setEnabled(false); setLocation(200, 200); } void testButton_actionPerformed(ActionEvent e) { saveFields(); FtpVO ftpVO = new FtpVO(tfServer.getText(), tfUser.getText(), tfPassword.getText(), tfDirectory.getText(), tfPort.getText(), null); xInputDirectory = new XInputDirectory(ftpVO); isTested = xInputDirectory.test(); okButton.setEnabled(isTested); tfState.setText(xInputDirectory.getTestMsg()); taState.setText(xInputDirectory.getLog()); if (!isTested) { xInputDirectory = null; } } void okButton_actionPerformed(ActionEvent e) { saveFields(); setVisible(false); } void cancelButton_actionPerformed(ActionEvent e) { isTested = false; xInputDirectory = null; okButton.setEnabled(false); setVisible(false); } void tfServer_focusLost(FocusEvent e) { okButton.setEnabled(false); } void tfPort_focusLost(FocusEvent e) { okButton.setEnabled(false); } void tfUser_focusLost(FocusEvent e) { okButton.setEnabled(false); } void tfPassword_focusLost(FocusEvent e) { okButton.setEnabled(false); } void tfDirectory_focusLost(FocusEvent e) { okButton.setEnabled(false); } /** * */ private void loadFields() { String str = null; str = Common.getSettings().getProperty( _base_key + "Server"); if (str != null) tfServer.setText(str); str = Common.getSettings().getProperty( _base_key + "Port"); if (str != null) tfPort.setText(str); str = Common.getSettings().getProperty( _base_key + "User"); if (str != null) tfUser.setText(str); str = Common.getSettings().getProperty( _base_key + "Password"); if (str != null) tfPassword.setText(str); str = Common.getSettings().getProperty( _base_key + "Directory"); if (str != null) tfDirectory.setText(str); } /** * */ private void saveFields() { Common.getSettings().setProperty( _base_key + "Server" , tfServer.getText()); Common.getSettings().setProperty( _base_key + "Port" , tfPort.getText()); Common.getSettings().setProperty( _base_key + "User" , tfUser.getText()); Common.getSettings().setProperty( _base_key + "Password" , tfPassword.getText()); Common.getSettings().setProperty( _base_key + "Directory" , tfDirectory.getText()); } } class FtpChooser_testButton_actionAdapter implements java.awt.event.ActionListener { FtpChooser adaptee; FtpChooser_testButton_actionAdapter(FtpChooser adaptee) { this.adaptee = adaptee; } public void actionPerformed(ActionEvent e) { adaptee.testButton_actionPerformed(e); } } class FtpChooser_okButton_actionAdapter implements java.awt.event.ActionListener { FtpChooser adaptee; FtpChooser_okButton_actionAdapter(FtpChooser adaptee) { this.adaptee = adaptee; } public void actionPerformed(ActionEvent e) { adaptee.okButton_actionPerformed(e); } } class FtpChooser_cancelButton_actionAdapter implements java.awt.event.ActionListener { FtpChooser adaptee; FtpChooser_cancelButton_actionAdapter(FtpChooser adaptee) { this.adaptee = adaptee; } public void actionPerformed(ActionEvent e) { adaptee.cancelButton_actionPerformed(e); } } class FtpChooser_tfServer_focusAdapter extends java.awt.event.FocusAdapter { FtpChooser adaptee; FtpChooser_tfServer_focusAdapter(FtpChooser adaptee) { this.adaptee = adaptee; } public void focusLost(FocusEvent e) { adaptee.tfServer_focusLost(e); } } class FtpChooser_tfPort_focusAdapter extends java.awt.event.FocusAdapter { FtpChooser adaptee; FtpChooser_tfPort_focusAdapter(FtpChooser adaptee) { this.adaptee = adaptee; } public void focusLost(FocusEvent e) { adaptee.tfPort_focusLost(e); } } class FtpChooser_tfUser_focusAdapter extends java.awt.event.FocusAdapter { FtpChooser adaptee; FtpChooser_tfUser_focusAdapter(FtpChooser adaptee) { this.adaptee = adaptee; } public void focusLost(FocusEvent e) { adaptee.tfUser_focusLost(e); } } class FtpChooser_tfPassword_focusAdapter extends java.awt.event.FocusAdapter { FtpChooser adaptee; FtpChooser_tfPassword_focusAdapter(FtpChooser adaptee) { this.adaptee = adaptee; } public void focusLost(FocusEvent e) { adaptee.tfPassword_focusLost(e); } } class FtpChooser_tfDirectory_focusAdapter extends java.awt.event.FocusAdapter { FtpChooser adaptee; FtpChooser_tfDirectory_focusAdapter(FtpChooser adaptee) { this.adaptee = adaptee; } public void focusLost(FocusEvent e) { adaptee.tfDirectory_focusLost(e); } }project-x/src/net/sourceforge/dvb/projectx/gui/GuiInterfaceImpl.java0000600000175000017500000001657310351107652027262 0ustar supermariosupermario/* * @(#)GuiInterfaceImpl * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import net.sourceforge.dvb.projectx.gui.TeletextPageMatrix; import net.sourceforge.dvb.projectx.gui.PreSettings; import net.sourceforge.dvb.projectx.gui.ProcessWindow; import net.sourceforge.dvb.projectx.gui.MainFrame; import net.sourceforge.dvb.projectx.gui.CommonGui; import net.sourceforge.dvb.projectx.gui.SubpictureFrame; import net.sourceforge.dvb.projectx.gui.StartUp; import net.sourceforge.dvb.projectx.common.GuiInterfaceIF; import net.sourceforge.dvb.projectx.common.Common; public class GuiInterfaceImpl implements GuiInterfaceIF { private TeletextPageMatrix teletextpagematrix; private PreSettings presettings; private ProcessWindow processwindow; private SubpictureFrame subpictureframe; private StartUp startup; /** * */ public GuiInterfaceImpl() { init(); } /** * */ private void init() { new CommonGui(); processwindow = new ProcessWindow(); } /** * load main stuff */ public void loadGui() { startup = new StartUp(); startup.show(); new MainFrame(startup); } /** * */ private void loadTeletextPageMatrix() { if (teletextpagematrix == null) teletextpagematrix = new TeletextPageMatrix(); } /** * */ public void showTtxPageMatrix() { loadTeletextPageMatrix(); teletextpagematrix.show(); } /** * */ public void initTtxPageMatrix(String str) { loadTeletextPageMatrix(); teletextpagematrix.picture.init(str); } /** * */ public void updateTtxPageMatrix(String str) { loadTeletextPageMatrix(); teletextpagematrix.picture.update(str); } /** * */ private void initPreSettings() { if (presettings == null) presettings = new PreSettings(); } /** * */ public void showPreSettings() { initPreSettings(); if (presettings.isVisible()) { presettings.setState(0); presettings.toFront(); } else presettings.show(); } /** * */ public void resetBitrateMonitor() { processwindow.resetBitrateMonitor(); } /** * */ public void updateBitrateMonitor(int value, byte[] array, String str) { processwindow.updateBitrateMonitor(value, array, str); } /** * */ public void updateTtxHeader(String str) { processwindow.updateTtxHeader(str); } /** * */ public void updateVpsLabel(String str) { processwindow.updateVpsLabel(str); } /** * */ public void showAVOffset(String str) { processwindow.showAVOffset(str); } /** * */ public void showExportStatus(String str) { processwindow.showExportStatus(str); } /** * */ public void showExportStatus(String str, int value) { processwindow.showExportStatus(str, value); } /** * progress * * @param1 - the msg */ public void updateProgressBar(int percent) { processwindow.updateProgressBar(percent); } /** * progress * * @param1 - the msg */ public void updateProgressBar(String str) { processwindow.updateProgressBar(str); } /** * */ public void setMessage(String msg, boolean tofront, int background) { processwindow.setMessage(msg, tofront, background); } /** * */ public void addPidToExtract(Object obj) { processwindow.addPidToExtract(obj); } /** * */ public void closeLogWindow() { processwindow.close(); } /** * */ public void showLogWindow() { if (processwindow.isVisible()) { processwindow.setState(0); processwindow.toFront(); } else processwindow.show(); } /** * */ public String getUserInputDialog(String arg1, String arg2) { return CommonGui.getUserInput(arg1, arg2); } /** * */ public boolean getUserConfirmationDialog(String str) { return CommonGui.getUserConfirmation(str); } /** * */ public void showErrorMessageDialog(Object message, String title) { CommonGui.showErrorMessageDialog(message, title); } /** * */ public void showMessageDialog(Object message, String title) { CommonGui.showMessageDialog(message, title); } /** * */ public Object getMainFrameBounds() { return MainFrame.getFrameBounds(); } /** * */ public void showMainFrame(boolean b) { MainFrame.showFrame(b); } /** * */ public void setMainFrameTitle(String str) { MainFrame.setFrameTitle(str); } /** * */ public void resetMainFrameTitle() { MainFrame.resetFrameTitle(); } /** * */ public void addCollectionAtEnd() { MainFrame.addCollectionAtEnd(); } /** * */ public void showActiveCollection(int index) { MainFrame.showActiveCollection(index); } /** * */ public void updateCollectionPanel(int index) { MainFrame.updateCollectionPanel(index); } /** * */ private void initSubpictureFrame() { if (subpictureframe == null) subpictureframe = new SubpictureFrame(); } /** * */ public void setSubpictureTitle(String str) { initSubpictureFrame(); subpictureframe.setFrameTitle(str); } /** * */ public void showSubpicture() { initSubpictureFrame(); if (subpictureframe.isVisible()) { subpictureframe.setState(0); subpictureframe.toFront(); } else subpictureframe.show(); } /** * */ public void hideSubpicture() { initSubpictureFrame(); subpictureframe.close(); } /** * */ public boolean isSubpictureVisible() { if (subpictureframe == null || !subpictureframe.isVisible()) return false; return true; } /** * */ public void repaintSubpicture() { initSubpictureFrame(); subpictureframe.repaintSubpicture(); } /** * */ public void setOSDMessage(String str, boolean b) { CommonGui.getPicturePanel().setOSDMessage(str, b); } /** * */ public void showCutIcon(boolean b, Object[] obj, Object list) { CommonGui.getPicturePanel().showCutIcon(b, obj, list); } /** * */ public void showChapterIcon(Object[] obj, Object list) { CommonGui.getPicturePanel().showChapterIcon(obj, list); } /** * */ public void updatePreviewPixel() { CommonGui.getPicturePanel().updatePreviewPixel(); } /** * */ public void repaintPicturePanel() { CommonGui.getPicturePanel().repaint(); } } project-x/src/net/sourceforge/dvb/projectx/gui/HexViewer.java0000600000175000017500000003142610363303406025771 0ustar supermariosupermario/* * @(#)HEXVIEWER.java - simple hexviewer * * Copyright (c) 2002-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import java.awt.*; import java.awt.event.*; import javax.swing.event.*; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.JScrollPane; import javax.swing.JViewport; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JSlider; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JCheckBoxMenuItem; import javax.swing.UIManager; import javax.swing.KeyStroke; import javax.swing.BoxLayout; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.gui.CommonGui; import net.sourceforge.dvb.projectx.gui.ColumnLayout; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.File; public class HexViewer extends JFrame { private XInputFile xinputFile; private JTextArea HexArea; private JTextField Field, Field1, from, fsize; private JScrollPane scroll; private JViewport viewport; private JLabel flen, hexn, decn; private JSlider slider; private JFileChooser chooser; private boolean textonly = false; /** * */ public HexViewer() { init(); } /** * */ protected void init() { addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) { close(); } }); buildMenu(); setTitle(Resource.getString("hexviewer.title")); chooser = new JFileChooser(); scroll = new JScrollPane(); HexArea = new JTextArea(); HexArea.setFont(new Font("Courier New", Font.PLAIN, 12)); HexArea.setEditable(false); HexArea.setRows(24); HexArea.setTabSize(12); scroll.setViewportView(HexArea); viewport = scroll.getViewport(); slider = new JSlider(JSlider.VERTICAL, 0, 15, 0); slider.setInverted(true); slider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { readfile((16L * slider.getValue())); } }); Field = new JTextField("0"); Field.setToolTipText(Resource.getString("hexviewer.jumpto_tip")); Field.setPreferredSize(new Dimension(100,25)); Field.setMaximumSize(new Dimension(100,25)); Field.setEditable(true); hexn = new JLabel("= hex: "); hexn.setPreferredSize(new Dimension(120,25)); hexn.setMaximumSize(new Dimension(120,25)); Field1 = new JTextField("0"); Field1.setToolTipText(Resource.getString("hexviewer.jumpto_tip")); Field1.setPreferredSize(new Dimension(100,25)); Field1.setMaximumSize(new Dimension(100,25)); Field1.setEditable(true); decn = new JLabel("= dec: "); decn.setPreferredSize(new Dimension(120,25)); decn.setMaximumSize(new Dimension(120,25)); JPanel container = new JPanel(); container.setLayout( new BorderLayout() ); JPanel menu_1 = new JPanel(); menu_1.setLayout( new BoxLayout(menu_1, BoxLayout.X_AXIS )); menu_1.setToolTipText(Resource.getString("hexviewer.jumpto_tip")); menu_1.add(new JLabel(Resource.getString("hexviewer.jumptodec"))); menu_1.add(Field); menu_1.add(hexn); JPanel menu_2 = new JPanel(); menu_2.setLayout( new BoxLayout(menu_2, BoxLayout.X_AXIS )); menu_2.setToolTipText(Resource.getString("hexviewer.jumpto_tip")); menu_2.add(new JLabel(Resource.getString("hexviewer.jumptohex"))); menu_2.add(Field1); menu_2.add(decn); JPanel menu = new JPanel(); menu.setLayout( new ColumnLayout()); flen = new JLabel(Resource.getString("hexviewer.filesize")); menu.add(flen); menu.add(menu_1); menu.add(menu_2); Field.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { if (!Field.getText().equals("")) { hexn.setText("= hex: " + Long.toHexString(Long.parseLong(Field.getText())).toUpperCase()); slider.setValue((int)(Long.parseLong(Field.getText()) / 16)); } } catch (Exception e1) {} } }); Field1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { if (!Field1.getText().equals("")) { decn.setText("= dec: " + Long.parseLong(Field1.getText(), 16)); slider.setValue((int)(Long.parseLong(Field1.getText(), 16) / 16)); } } catch (Exception e1) {} } }); JPanel grid = new JPanel(); grid.setLayout( new GridLayout(1,1) ); grid.add(scroll); from = new JTextField("0"); from.setPreferredSize(new Dimension(100,25)); from.setMaximumSize(new Dimension(100,25)); from.setEditable(true); fsize = new JTextField("1000"); fsize.setPreferredSize(new Dimension(100,25)); fsize.setMaximumSize(new Dimension(100,25)); fsize.setEditable(true); JButton extract = new JButton(Resource.getString("hexviewer.extractfrom")); extract.setToolTipText(Resource.getString("hexviewer.extractfrom_tip")); extract.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { if (!from.getText().equals("") && !fsize.getText().equals("")) { long pos = Long.parseLong(from.getText(),16); long size = Long.parseLong(fsize.getText(),16) - pos; savefile(pos,size); } } catch (Exception e1) {} } }); JPanel menu2 = new JPanel(); menu2.setLayout( new BoxLayout(menu2, BoxLayout.X_AXIS )); menu2.setToolTipText(Resource.getString("hexviewer.extract_tip")); menu2.add(extract); menu2.add(from); menu2.add(new JLabel(Resource.getString("hexviewer.to") + ": (hex.)")); menu2.add(fsize); JPanel menu3 = new JPanel(); menu3.setLayout( new ColumnLayout()); menu3.add(menu); menu3.add(menu2); container.add(slider, BorderLayout.EAST); container.add(grid); container.add(menu3, BorderLayout.SOUTH); getContentPane().add(container); centerDialog(); UIManager.addPropertyChangeListener(new UISwitchListener(getRootPane())); } /** * */ protected void buildMenu() { JMenuBar menuBar = new JMenuBar(); menuBar.add(buildFileMenu()); menuBar.add(buildOptionMenu()); setJMenuBar(menuBar); } /** * */ protected JMenu buildFileMenu() { JMenu fileMenu = new JMenu(); CommonGui.localize(fileMenu, "Common.File"); JMenuItem save = new JMenuItem(); CommonGui.localize(save, "Common.SaveAs"); fileMenu.add(save); fileMenu.addSeparator(); JMenuItem close = new JMenuItem(); CommonGui.localize(close, "Common.Close"); close.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.ALT_MASK)); close.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { close(); } }); fileMenu.add(close); return fileMenu; } /** * */ protected JMenu buildOptionMenu() { JMenu optionMenu = new JMenu(); CommonGui.localize(optionMenu, "Common.Options"); JCheckBoxMenuItem text_mode = new JCheckBoxMenuItem(Resource.getString("hexviewer.textmode")); text_mode.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { textonly = ((JCheckBoxMenuItem) e.getSource()).getState(); } }); optionMenu.add(text_mode); return optionMenu; } /** * */ private void savefile(long startPos, long size) { long len = xinputFile.length(); size = (startPos + size > len) ? (len - startPos) : size; if (startPos >= len || startPos<0 || size < 1) return; String newfile = xinputFile + "(0x" + Long.toHexString(startPos) + " to 0x" + Long.toHexString(startPos + size) + ").bin"; chooser.setSelectedFile(new File(newfile)); chooser.rescanCurrentDirectory(); int retval = chooser.showSaveDialog(this); if(retval == JFileChooser.APPROVE_OPTION) { File theFile = chooser.getSelectedFile(); if(theFile != null && !theFile.isDirectory()) { newfile = theFile.getAbsolutePath(); } } else return; setTitle(Resource.getString("hexviewer.save") + ": " + newfile); try { int buf = 3072000; BufferedInputStream hex = new BufferedInputStream(xinputFile.getInputStream(), buf); BufferedOutputStream hex1 = new BufferedOutputStream(new FileOutputStream(newfile), buf); long filePos = 0; long endPos = startPos + size; while (filePos < startPos) filePos += hex.skip(startPos - filePos); byte data[]; int datalen; while (filePos < endPos) { datalen = (endPos-filePos) < (long)buf ? (int)(endPos-filePos) : buf; data = new byte[datalen]; datalen = hex.read(data); hex1.write(data,0,datalen); filePos += datalen; } hex.close(); hex1.flush(); hex1.close(); } catch (IOException e) { HexArea.setText(Resource.getString("hexviewer.error") + ": " + xinputFile); } setTitle(Resource.getString("hexviewer.file") + ": " + xinputFile); } /** * */ private void readfile(long position) { try { xinputFile.randomAccessOpen("r"); long len = xinputFile.length(); if (position < len) { if (textonly) { xinputFile.randomAccessSeek(position); String text = ""; String nextLine = null; if (position != 0) xinputFile.randomAccessReadLine(); for (int a = 0; a < 24 && (nextLine = xinputFile.randomAccessReadLine()) != null; a++) text += nextLine + "\n"; HexArea.setText(text); } else { int viewsize = (int)(((len - position) >= 384L) ? 384 : (len - position) ); byte[] data = new byte[viewsize]; xinputFile.randomAccessSeek(position); xinputFile.randomAccessRead(data); print(data, position); } } xinputFile.randomAccessClose(); } catch (IOException e) { HexArea.setText(Resource.getString("hexviewer.error") + ": " + xinputFile); } } /** * */ private void print(byte[] data, long position) { String fill = "0000000000"; String text = ""; text += " Offset : 0 1 2 3 4 5 6 7- 8 9 A B C D E F : Ascii \n"; text += "-----------|--------------------------------------------------|-----------------\n"; for (int a = 0; a < data.length; a += 16) { String ascii = " : "; String stuff = " "; String pos = Long.toHexString(position + a).toUpperCase(); text += fill.substring(0, 10 - pos.length()) + pos + " : "; int b=0; for (; b < 16 && a + b < data.length; b++) { String val = Integer.toHexString((0xFF & data[a + b])).toUpperCase(); text += fill.substring(0, 2 - val.length()) + val + ((b == 7) ? "-" : " "); ascii += ((0xFF & data[a + b]) > 0x1F && (0xFF & data[a + b]) < 0x7F) ? "" + ((char)data[a + b]) : "."; } for (; b < 16; b++) text += stuff; text += ascii + "\n"; } HexArea.setText(text); } /** * */ public void view(XInputFile aXInputFile) { long filelen = aXInputFile.length(); if ((xinputFile == null) || !(xinputFile.equals(aXInputFile))) { xinputFile = aXInputFile; HexArea.setText(""); slider.setMaximum((int)(filelen / 16)); if (slider.getValue() == 0) readfile(0); else slider.setValue(0); } setTitle(Resource.getString("hexviewer.file") + ": " + xinputFile); flen.setText(Resource.getString("hexviewer.filesize") + ": " + Common.formatNumber(filelen) + " bytes"); show(); } /** * */ protected void centerDialog() { setLocation(150, 150); setSize(620, 530); } /** * */ private void close() { dispose(); } } project-x/src/net/sourceforge/dvb/projectx/gui/Html.java0000600000175000017500000001165210351107674024774 0ustar supermariosupermario/* * @(#)Html.java - provides an external HTML pane for additional infos * * Copyright (c) 2004-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.net.URL; import java.net.MalformedURLException; import java.io.*; import javax.swing.text.*; import javax.swing.event.*; import edu.stanford.ejalbert.BrowserLauncher; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Common; /** * Html.java - provides an external HTML pane for additional infos. * * @since DM20032004 081.6 int18 */ public class Html extends JFrame { /** * Constructor of Html. */ public Html() { init(null); } public Html(String str) { init(str); } private void init(String str) { setBounds( 200, 25, 600, 600); HtmlPane html = new HtmlPane(str); setContentPane(html); setTitle(Resource.getString("html.title")); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { quit(); } }); UIManager.addPropertyChangeListener(new UISwitchListener((JComponent)getRootPane())); } /** * Quit disposes this window. */ public void quit() { dispose(); } } /** * HtmlPane. */ class HtmlPane extends JScrollPane implements HyperlinkListener { /** the JEditorPane */ private JEditorPane html; /** * Constructor of HtmlPane. */ public HtmlPane(String url_str) { try { if (url_str != null) html = new JEditorPane(url_str); else html = new JEditorPane(Resource.getLocalizedResourceURL("htmls", "index.html")); html.setEditable(false); html.addHyperlinkListener(this); JViewport vp = getViewport(); vp.add(html); } catch (MalformedURLException e) { Common.setMessage("Malformed URL: " + e); } catch (IOException e) { Common.setMessage("IOException: " + e); } } /** * Notification of a change relative to a hyperlink. * * @see javax.swing.event.HyperlinkListener#hyperlinkUpdate(javax.swing.event.HyperlinkEvent) */ public void hyperlinkUpdate(HyperlinkEvent e) { if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { linkActivated(e.getURL()); } } /** * Called if someone has activated a hyperlink. * * @param u URL of the link */ protected void linkActivated(URL u) { // external links are loaded by the BrowserLauncher if (u.getProtocol().equals("http") || u.getProtocol().equals("https")) { try { BrowserLauncher.openURL(u.toString()); } catch (IOException e) { Common.setMessage(Resource.getString("msg.browser.launcher.error") + " " + e); } } else { // all local links are loaded into the JEditorPane Cursor c = html.getCursor(); Cursor waitCursor = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR); html.setCursor(waitCursor); SwingUtilities.invokeLater(new PageLoader(u, c)); } } /** * PageLoader provides a thread for loading a page. */ private class PageLoader implements Runnable { private URL url; private Cursor cursor; /** * Constructor of PageLoader. * * @param u URL to load * @param c Cursor to display */ PageLoader(URL u, Cursor c) { url = u; cursor = c; } /* (non-Javadoc) * @see java.lang.Runnable#run() */ public void run() { if (url == null) { // restore the original cursor html.setCursor(cursor); Container parent = html.getParent(); parent.repaint(); } else { Document doc = html.getDocument(); try { html.setPage(url); } catch (IOException ioe) { html.setDocument(doc); getToolkit().beep(); } finally { // schedule the cursor to revert after // the paint has happended. url = null; SwingUtilities.invokeLater(this); } } } } } project-x/src/net/sourceforge/dvb/projectx/gui/MainFrame.java0000600000175000017500000023661210412354304025724 0ustar supermariosupermario/* * @(#)MainFrame.java - holds main gui * * Copyright (c) 2001-2005 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.Insets; import java.awt.LayoutManager; import java.awt.Point; import java.awt.Rectangle; import java.awt.Font; import java.awt.Toolkit; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.io.FileReader; import java.io.BufferedReader; import java.io.IOException; import java.io.PrintStream; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Date; import java.util.List; import java.text.DateFormat; import java.util.Comparator; import java.util.ArrayList; import java.util.Arrays; import java.util.StringTokenizer; import java.util.Locale; import java.util.Calendar; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JRadioButton; import javax.swing.JRadioButtonMenuItem; import javax.swing.JCheckBoxMenuItem; import javax.swing.JScrollPane; import javax.swing.JSlider; import javax.swing.JTabbedPane; import javax.swing.JTextField; import javax.swing.JTextArea; import javax.swing.JViewport; import javax.swing.SwingUtilities; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.KeyStroke; import javax.swing.MenuElement; import javax.swing.JTable; import javax.swing.table.TableModel; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import java.net.URL; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.parser.MainProcess; import net.sourceforge.dvb.projectx.parser.HpFix; import net.sourceforge.dvb.projectx.parser.StripAudio; import net.sourceforge.dvb.projectx.parser.StripRelook; import net.sourceforge.dvb.projectx.xinput.DirType; import net.sourceforge.dvb.projectx.xinput.XInputDirectory; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.gui.FtpChooser; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.gui.AboutBox; import net.sourceforge.dvb.projectx.gui.HexViewer; import net.sourceforge.dvb.projectx.gui.Html; import net.sourceforge.dvb.projectx.gui.StartUp; import net.sourceforge.dvb.projectx.gui.UISwitchListener; import net.sourceforge.dvb.projectx.gui.CommonGui; import net.sourceforge.dvb.projectx.gui.PatchDialog; import net.sourceforge.dvb.projectx.gui.ColumnLayout; import net.sourceforge.dvb.projectx.gui.MemoryMonitor; import net.sourceforge.dvb.projectx.gui.CollectionPanel; import net.sourceforge.dvb.projectx.gui.ComboBoxIndexListener; import net.sourceforge.dvb.projectx.gui.ComboBoxItemListener; import net.sourceforge.dvb.projectx.gui.CheckBoxListener; import net.sourceforge.dvb.projectx.gui.TextFieldListener; import net.sourceforge.dvb.projectx.gui.CommonGui; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.ClipboardOwner; /** * */ public class MainFrame extends JPanel { private static String frametitle = ""; private static int GlobalReturnCode = 0; private static boolean SilentAction = true; //create empty table private static Object[][] FileObjectTable = new Object[5][11]; private static CollectionPanel collection_panel; private static JFrame frame = new JFrame(); // static { // frame.setIconImage(Resource.loadImage("pjx_icon.gif")); // } // global boxes private static JComboBox comboBox_0; /** * radio buttons for look and feels in general menu */ private JRadioButtonMenuItem lf_item[] = null; private JTable tableView; private JList list1; private JViewport viewport; private JTextField outfield; private ComboBoxIndexListener _ComboBoxIndexListener = new ComboBoxIndexListener(); private ComboBoxItemListener _ComboBoxItemListener = new ComboBoxItemListener(); private CheckBoxListener _CheckBoxListener = new CheckBoxListener(); private TextFieldListener _TextFieldListener = new TextFieldListener(); private JPopupMenu popup; private JFrame autoload; private Thread thread = null; private PatchDialog patch_panel; /** * copy fileinfo to clipboard, see popup, menulistener */ private static ClipboardOwner defaultClipboardOwner = new ClipboardObserver(); static class ClipboardObserver implements ClipboardOwner { public void lostOwnership(Clipboard clipboard, Transferable contents) {} } /** * */ private ActionListener _BoxListener = new ActionListener() { public void actionPerformed(ActionEvent e) { String actName = e.getActionCommand(); JCheckBoxMenuItem box = (JCheckBoxMenuItem) e.getSource(); Common.getSettings().setBooleanProperty(actName, box.getState()); } }; /** * */ private ActionListener _MenuListener = new ActionListener() { public void actionPerformed(ActionEvent e) { String actName = e.getActionCommand(); /** * */ if (actName.equals("sendTo3")) { if (Common.isCollectionListEmpty()) return; int index = tableView.getSelectedRow(); if (index < 0) return; try { String str = Common.getSettings().getProperty(Keys.KEY_PostCommands_Cmd3); if (str.trim().length() > 0) Common.performCommand(str + " \"" + Common.getCollection().getInputFile(index).toString() + "\""); } catch (Exception ex) { Common.setExceptionMessage(ex); } } /** * */ else if (actName.equals("add")) { CommonGui.getMainFileChooser().rescanCurrentDirectory(); CommonGui.getMainFileChooser().setDialogType(JFileChooser.OPEN_DIALOG); CommonGui.getMainFileChooser().setMultiSelectionEnabled(true); int retval = CommonGui.getMainFileChooser().showDialog(frame, null); if (retval == JFileChooser.APPROVE_OPTION) { File theFiles[] = CommonGui.getMainFileChooser().getSelectedFiles(); if (theFiles == null) return; /** * adaption, if multiselection doesnt work */ if (theFiles.length == 0) { theFiles = new File[1]; theFiles[0] = CommonGui.getMainFileChooser().getSelectedFile(); } if (theFiles != null) { Common.addCollection(false); JobCollection collection = Common.getCollection(); /** * must use getAbsolutFile to ensure right ClassType, * sometimes the returned Object.getClass * from selection is NOT of java.io.File!! */ for (int i = 0; i < theFiles.length; i++) if (theFiles[i].isFile()) collection.addInputFile( new XInputFile(theFiles[i].getAbsoluteFile())); updateCollectionTable(collection.getCollectionAsTable()); updateCollectionPanel(Common.getActiveCollection()); } return; } } /** * */ else if (actName.equals("newOutName")) { int index = tableView.getSelectedRow(); JobCollection collection = Common.getCollection(); if (index < 0 || index >= collection.getInputFilesCount()) return; String name = ((XInputFile) collection.getInputFiles()[0]).getName(); String newoutname = CommonGui.getUserInput( name, Resource.getString("popup.newOutName") + " " + name, collection.getOutputName()); if (newoutname != null) { collection.setOutputName(newoutname); updateOutputField(collection); updateCollectionTable(collection.getCollectionAsTable()); } } /** * */ else if (actName.equals("remove")) { int[] indices = tableView.getSelectedRows(); if (indices.length > 0) { JobCollection collection = Common.getCollection(); if (collection == null) return; collection.removeInputFile(indices); updateCollectionTable(collection.getCollectionAsTable()); updateCollectionPanel(Common.getActiveCollection()); tableView.clearSelection(); } } /** * */ else if (actName.equals("rename")) { int index = tableView.getSelectedRow(); if (index < 0 || tableView.getValueAt(index, 0) == null) return; JobCollection collection = Common.getCollection(); try { if (((XInputFile) collection.getInputFile(index)).rename()) reloadInputDirectories(); } catch (IOException ioe) {} updateCollectionTable(collection.getCollectionAsTable()); } /** * */ else if (actName.equals("changeTimestamp")) { int[] indices = tableView.getSelectedRows(); if (indices.length == 0) return; JobCollection collection = Common.getCollection(); for (int i = 0; i < indices.length; i++) { if (tableView.getValueAt(i, 0) == null) continue; XInputFile xInputFile = (XInputFile) collection.getInputFile(i); if (CommonGui.getUserConfirmation("really update the timestamp of '" + xInputFile.getName() + "' ?")) xInputFile.setLastModified(); } updateCollectionTable(collection.getCollectionAsTable()); } /** * */ else if (actName.equals("viewAsHex")) { int index = tableView.getSelectedRow(); if (index < 0 || tableView.getValueAt(index, 0) == null) return; JobCollection collection = Common.getCollection(); XInputFile xInputFile = ((XInputFile) collection.getInputFile(index)).getNewInstance(); if (xInputFile != null && xInputFile.exists()) new HexViewer().view(xInputFile); } /** * */ else if (actName.equals("fixHpAc3")) { int index = tableView.getSelectedRow(); if (index < 0 || tableView.getValueAt(index, 0) == null) return; JobCollection collection = Common.getCollection(); XInputFile xInputFile = ((XInputFile) collection.getInputFile(index)).getNewInstance(); if (xInputFile != null && xInputFile.exists() && CommonGui.getUserConfirmation("really process '" + xInputFile.getName() + "' ?")) { HpFix hpfix = new HpFix(); Common.setOSDMessage("fixing wrong Hp Ac3 File..."); xInputFile = hpfix.process(xInputFile); collection.removeInputFile(index); if (xInputFile != null) collection.addInputFile(index, xInputFile); updateCollectionTable(collection.getCollectionAsTable()); updateCollectionPanel(Common.getActiveCollection()); tableView.clearSelection(); } } /** * */ else if (actName.equals("stripAudio")) { int index = tableView.getSelectedRow(); if (index < 0 || tableView.getValueAt(index, 0) == null) return; JobCollection collection = Common.getCollection(); XInputFile xInputFile = ((XInputFile) collection.getInputFile(index)).getNewInstance(); if (xInputFile != null && xInputFile.exists() && xInputFile.getStreamInfo().getStreamType() == CommonParsing.ES_RIFF_TYPE && CommonGui.getUserConfirmation("really process '" + xInputFile.getName() + "' ?")) { StripAudio stripAudio = new StripAudio(); Common.setOSDMessage("strip audio data..."); xInputFile = stripAudio.process(xInputFile); collection.removeInputFile(index); if (xInputFile != null) collection.addInputFile(index, xInputFile); updateCollectionTable(collection.getCollectionAsTable()); updateCollectionPanel(Common.getActiveCollection()); tableView.clearSelection(); } } /** * */ else if (actName.equals("stripRelook")) { stripRelook(0); } /** * */ else if (actName.equals("stripRelook1")) { stripRelook(1); } /** * */ else if (actName.equals("editBasics")) { int index = tableView.getSelectedRow(); if (index < 0 || tableView.getValueAt(index, 0) == null) return; JobCollection collection = Common.getCollection(); XInputFile xInputFile = (XInputFile) collection.getInputFile(index); if (patch_panel == null) patch_panel = new PatchDialog(frame); if (patch_panel.entry(xInputFile)) ScanInfo(xInputFile); } /** * */ else if (actName.equals("clipboard")) { int index = tableView.getSelectedRow(); if (index < 0 || tableView.getValueAt(index, 0) == null) return; JobCollection collection = Common.getCollection(); XInputFile xInputFile = (XInputFile) collection.getInputFile(index); try { Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); if (clipboard != null) { String srcData = xInputFile.getStreamInfo().getFullInfo(); StringSelection contents = new StringSelection(srcData); clipboard.setContents(contents, defaultClipboardOwner); } } catch (Exception er) { //just return } } /** * */ else if (actName.equals("applyAction")) { Object[] items = Keys.ITEMS_ConversionMode; String str = ((JMenuItem) e.getSource()).getText(); int val = -1; for (int i = 0; i < items.length; i++) { if (str.equals(items[i].toString())) { val = i; break; } } Common.getCollection().setActionType(val); } /** * */ else if (actName.equals("assignStreamtype")) { int index = tableView.getSelectedRow(); if (index < 0 || tableView.getValueAt(index, 0) == null) return; JobCollection collection = Common.getCollection(); XInputFile xInputFile = (XInputFile) collection.getInputFile(index); Object[] items = Keys.ITEMS_FileTypes; String str = ((JMenuItem) e.getSource()).getText(); for (int i = 0; i < items.length; i++) { if (str.equals(items[i].toString())) { if (xInputFile.getStreamInfo() == null) ScanInfo(xInputFile); xInputFile.getStreamInfo().setStreamType(i); ScanInfo(xInputFile, i); updateCollectionTable(collection.getCollectionAsTable()); return; } } xInputFile.setStreamInfo(null); ScanInfo(xInputFile); updateCollectionTable(collection.getCollectionAsTable()); } /** * */ else if (actName.equals("exit")) Common.exitApplication(0); /** * shall support manual loading of supported URLs */ else if (actName.equals("url")) { String value = null; XInputFile inputValue = null; URL url = null; loop: while (true) { value = CommonGui.getUserInput(Resource.getString("dialog.input.url")); if (value == null) return; try { url = new URL(value); String protocol = url.getProtocol(); if (protocol.equals("ftp")) { XInputDirectory xid = new XInputDirectory(url); XInputFile[] xif = xid.getFiles(); for (int i = 0; i < xif.length; i++) { if ( new URL(xif[i].toString()).getFile().equals(url.getFile()) ) { inputValue = xif[i]; break loop; } } Common.setMessage("!> URL incorrect or not accessible: " + url.toString(), true); continue loop; } else if (protocol.equals("file")) { inputValue = new XInputFile(new File(url.getHost() + url.getFile())); break; } else Common.setMessage("!> Protocol not yet supported: " + protocol, true); return; } catch (Exception u1) { Common.setMessage("!> URL Exc: (" + value + ")"); Common.setExceptionMessage(u1); } } if (inputValue == null) return; Common.addCollection(false); JobCollection collection = Common.getCollection(); collection.addInputFile(inputValue); updateCollectionTable(collection.getCollectionAsTable()); updateCollectionPanel(Common.getActiveCollection()); return; } } /** * */ private void stripRelook(int type) { int index = tableView.getSelectedRow(); if (index < 0 || tableView.getValueAt(index, 0) == null) return; JobCollection collection = Common.getCollection(); XInputFile xInputFile = ((XInputFile) collection.getInputFile(index)).getNewInstance(); if (xInputFile != null && xInputFile.exists() && xInputFile.getStreamInfo().getStreamType() == CommonParsing.PES_AV_TYPE && CommonGui.getUserConfirmation("really process '" + xInputFile.getName() + "' ?")) { StripRelook stripRelook = new StripRelook(type); Common.setOSDMessage("strip Relook data, type " + type + "..."); XInputFile[] xif = stripRelook.process(xInputFile, collection.getOutputDirectory()); collection.removeInputFile(index); if (xif != null) { for (int i = 0, j = index; i < xif.length; i++) { if (xif[i] != null) collection.addInputFile(j++, xif[i]); } } updateCollectionTable(collection.getCollectionAsTable()); updateCollectionPanel(Common.getActiveCollection()); tableView.clearSelection(); } } }; /** * Constructor of X. */ public MainFrame(StartUp startup) { frame.setBackground(new Color(200, 200, 200)); CommonGui.setMainFrame(frame); initialize(startup); } /** * */ public static void addCollectionAtEnd() { SilentAction = true; comboBox_0.addItem(String.valueOf(comboBox_0.getItemCount())); comboBox_0.setSelectedIndex(comboBox_0.getItemCount() - 1); SilentAction = false; } /** * */ private void updateOutputField(JobCollection collection) { outfield.setText(collection.getOutputDirectory()); String str; if ( (str = collection.getOutputName()).length() > 0) { outfield.setText(outfield.getText() + " {" + str + "}"); outfield.setBackground(new Color(255, 225, 255)); } else outfield.setBackground(new Color(225, 255, 225)); } /** * updates GUI JList collection list view * * param1 - array of file objects */ private void updateCollectionTable(Object[][] objects) { FileObjectTable = objects == null ? new Object[5][11] : objects; tableView.clearSelection(); tableView.revalidate(); tableView.repaint(); } /** * updates GUI JList autoload list view * * param1 - array of file objects */ private void updateAutoloadList(Object[] objects) { list1.setListData(objects); } /** * */ private void buildGUI(StartUp startup) { setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); showStartUpProgress(startup, 10, "Loading Menus..."); buildMenus(); showStartUpProgress(startup, 20, "Loading Popup Menus..."); buildPopupMenu(); showStartUpProgress(startup, 30, "Loading Quickload Panel..."); buildAutoloadPanel(); showStartUpProgress(startup, 40, "Loading Control Panel..."); /** * mid panel */ add(buildMainPanel()); showStartUpProgress(startup, 50, "Loading Status Panel..."); /** * south panel */ add(buildStatusPanel(), BorderLayout.SOUTH); add(Box.createRigidArea(new Dimension(1, 5))); } /** * */ protected void buildPopupMenu() { popup = new JPopupMenu(Resource.getString("popup.what")); JMenuItem menuitem_8 = popup.add(Resource.getString("popup.url")); menuitem_8.setActionCommand("url"); JMenuItem menuitem_4 = popup.add(Resource.getString("popup.rename")); menuitem_4.setActionCommand("rename"); JMenuItem menuitem_5 = popup.add(Resource.getString("popup.openhex")); menuitem_5.setActionCommand("viewAsHex"); JMenuItem menuitem_6 = popup.add(Resource.getString("popup.patchbasics")); menuitem_6.setActionCommand("editBasics"); JMenuItem menuitem_7 = popup.add(Resource.getString("popup.sendtocl3")); menuitem_7.setActionCommand("sendTo3"); popup.addSeparator(); JMenuItem menuitem_10 = popup.add(Resource.getString("popup.changeTimestamp")); menuitem_10.setActionCommand("changeTimestamp"); JMenuItem menuitem_12 = popup.add(Resource.getString("popup.fixHpAc3")); menuitem_12.setActionCommand("fixHpAc3"); JMenuItem menuitem_14 = popup.add(Resource.getString("popup.stripAudio")); menuitem_14.setActionCommand("stripAudio"); JMenuItem menuitem_15 = popup.add("strip Relook type 0 to separate pes.."); menuitem_15.setActionCommand("stripRelook"); JMenuItem menuitem_16 = popup.add("strip Relook type 1 to separate pes.."); menuitem_16.setActionCommand("stripRelook1"); popup.addSeparator(); JMenuItem menuitem_11 = popup.add(Resource.getString("popup.copyInfoToClipboard")); menuitem_11.setActionCommand("clipboard"); /** * */ Object[] objects = Keys.ITEMS_FileTypes; JMenu streamtype = new JMenu(Resource.getString("popup.assignStreamType")); for (int i = 0; i <= objects.length; i++) { JMenuItem item = new JMenuItem(i == objects.length ? Resource.getString("popup.automatic") : objects[i].toString()); item.setActionCommand("assignStreamtype"); item.addActionListener(_MenuListener); if (i == objects.length) streamtype.addSeparator(); streamtype.add(item); } popup.add(streamtype); popup.addSeparator(); JMenuItem menuitem_9 = popup.add(Resource.getString("popup.newOutName")); menuitem_9.setActionCommand("newOutName"); /** * */ objects = Keys.ITEMS_ConversionMode; JMenu action = new JMenu(Resource.getString("popup.assignActionType")); for (int i = -1; i < objects.length; i++) { JMenuItem item = new JMenuItem(i < 0 ? Resource.getString("popup.unspecified") : objects[i].toString()); item.setActionCommand("applyAction"); item.addActionListener(_MenuListener); if (i == 0) action.addSeparator(); action.add(item); } popup.add(action); popup.pack(); UIManager.addPropertyChangeListener(new UISwitchListener(popup)); menuitem_4.addActionListener(_MenuListener); menuitem_5.addActionListener(_MenuListener); menuitem_6.addActionListener(_MenuListener); menuitem_7.addActionListener(_MenuListener); menuitem_8.addActionListener(_MenuListener); menuitem_9.addActionListener(_MenuListener); menuitem_10.addActionListener(_MenuListener); menuitem_11.addActionListener(_MenuListener); menuitem_12.addActionListener(_MenuListener); menuitem_14.addActionListener(_MenuListener); menuitem_15.addActionListener(_MenuListener); menuitem_16.addActionListener(_MenuListener); } /** * */ protected void buildMenus() { JMenuBar menuBar = new JMenuBar(); menuBar.add(buildFileMenu()); menuBar.add(buildViewerMenu()); menuBar.add(buildGeneralMenu()); menuBar.add(buildPreferencesMenu()); menuBar.add(buildLanguageMenu()); menuBar.add(buildAddonMenu()); menuBar.add(buildHelpMenu()); frame.setJMenuBar(menuBar); } /** * */ protected JMenu buildFileMenu() { JMenu file = new JMenu(); CommonGui.localize(file, "Common.File"); JMenuItem add = new JMenuItem(); CommonGui.localize(add, "file.add"); add.setActionCommand("add"); add.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK)); JMenuItem url = new JMenuItem(); CommonGui.localize(url, "file.url"); url.setActionCommand("url"); url.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_U, ActionEvent.CTRL_MASK)); JMenuItem remove = new JMenuItem(); CommonGui.localize(remove, "file.remove"); remove.setActionCommand("remove"); remove.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, ActionEvent.CTRL_MASK)); JMenuItem rename = new JMenuItem(); CommonGui.localize(rename, "file.rename"); rename.setActionCommand("rename"); rename.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.CTRL_MASK)); JMenuItem exit = new JMenuItem(); CommonGui.localize(exit, "Common.Exit"); exit.setActionCommand("exit"); exit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.ALT_MASK)); file.add(add); file.add(url); file.add(remove); file.addSeparator(); file.add(rename); file.addSeparator(); file.add(exit); url.addActionListener(_MenuListener); add.addActionListener(_MenuListener); remove.addActionListener(_MenuListener); rename.addActionListener(_MenuListener); exit.addActionListener(_MenuListener); return file; } /** * */ protected JMenu buildSettingsMenu() { JMenu setting = new JMenu(); CommonGui.localize(setting, "settings.menu"); JMenuItem open = new JMenuItem(); CommonGui.localize(open, "settings.settings"); setting.add(open); return setting; } /** * */ protected JMenu buildPreferencesMenu() { JMenu preferencesMenu = new JMenu(); CommonGui.localize(preferencesMenu, "Common.Preferences"); JMenuItem preferences = new JMenuItem(); CommonGui.localize(preferences, "Common.Preferences"); preferences.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK)); preferences.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Common.getGuiInterface().showPreSettings(); } }); preferencesMenu.add(preferences); preferencesMenu.addSeparator(); JCheckBoxMenuItem save = new JCheckBoxMenuItem(Resource.getString(Keys.KEY_SaveSettingsOnExit[0])); save.setActionCommand(Keys.KEY_SaveSettingsOnExit[0]); save.setState(Common.getSettings().getBooleanProperty(Keys.KEY_SaveSettingsOnExit)); save.addActionListener(_BoxListener); preferencesMenu.add(save); return preferencesMenu; } /** * */ protected JMenu buildGeneralMenu() { JMenu general = new JMenu(); CommonGui.localize(general, "general.menu"); UIManager.LookAndFeelInfo[] lf_info = UIManager.getInstalledLookAndFeels(); lf_item = new JRadioButtonMenuItem[lf_info.length]; ButtonGroup lfgroup = new ButtonGroup(); ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e) { String lnfName = e.getActionCommand(); Common.getSettings().setProperty(Keys.KEY_LookAndFeel[0], lnfName); setLookAndFeel(lnfName); } }; for (int a = 0; a < lf_item.length; a++) { lf_item[a] = new JRadioButtonMenuItem(lf_info[a].getClassName()); general.add(lf_item[a]); lfgroup.add(lf_item[a]); lf_item[a].addActionListener(al); } setLookAndFeel(Common.getSettings().getProperty(Keys.KEY_LookAndFeel)); return general; } /** * sets the new look and feel. * * @param lnfName */ private void setLookAndFeel(String lnfName) { if (lnfName != null && !lnfName.equals("")) { JRadioButtonMenuItem selectedRadio = null; try { // update radio menu items for (int a=0; a < lf_item.length; a++) { if (lf_item[a].getActionCommand().equals(lnfName)) { lf_item[a].setSelected(true); selectedRadio = lf_item[a]; } } // now update the components UIManager.setLookAndFeel(lnfName); SwingUtilities.updateComponentTreeUI(frame); if(CommonGui.getMainFileChooser() != null) SwingUtilities.updateComponentTreeUI(CommonGui.getMainFileChooser()); } catch (Exception exc) { selectedRadio.getParent().remove(selectedRadio); System.err.println("!> Could not load LookAndFeel: " + lnfName); Common.setErrorMessage("!> Could not load LookAndFeel: " + lnfName); } } } /** * */ protected JMenu buildViewerMenu() { JMenu preview = new JMenu(); CommonGui.localize(preview, "options.menu"); JMenuItem hex = new JMenuItem(); CommonGui.localize(hex, "options.openhexview"); hex.setActionCommand("viewAsHex"); hex.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H, ActionEvent.CTRL_MASK)); preview.add(hex); preview.addSeparator(); JMenuItem basic = new JMenuItem(); CommonGui.localize(basic, "options.pachtbasics"); basic.setActionCommand("editBasics"); basic.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, ActionEvent.CTRL_MASK)); preview.add(basic); preview.addSeparator(); JMenuItem subtitle = new JMenuItem(); CommonGui.localize(subtitle, "options.subtitlepreview"); subtitle.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Common.getGuiInterface().showSubpicture(); } }); subtitle.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.CTRL_MASK)); preview.add(subtitle); preview.addSeparator(); JMenuItem pagematrix = new JMenuItem(); CommonGui.localize(pagematrix, "options.teletext"); pagematrix.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Common.getGuiInterface().showTtxPageMatrix(); } }); pagematrix.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, ActionEvent.CTRL_MASK)); preview.add(pagematrix); hex.addActionListener(_MenuListener); basic.addActionListener(_MenuListener); return preview; } /** * Builds the Language Menu. * * @return JMenu */ protected JMenu buildLanguageMenu() { ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent event) { String action = event.getActionCommand(); if (action.equals("check")) { new Html("http://project-x.sourceforge.net/optional/resources/").show(); return; } if (action.equals("system")) Resource.setChosenLanguage(null); else Resource.setChosenLanguage(action); CommonGui.showMessageDialog(Resource.getString("msg.new.language"), Resource.getString("msg.infomessage")); } }; JMenu langMenu = new JMenu(); CommonGui.localize(langMenu, "language.menu"); JMenuItem item_check = new JMenuItem(); CommonGui.localize(item_check, "language.check"); item_check.addActionListener(listener); item_check.setActionCommand("check"); langMenu.add(item_check); langMenu.addSeparator(); ButtonGroup group = new ButtonGroup(); JRadioButtonMenuItem item_sys = new JRadioButtonMenuItem(); CommonGui.localize(item_sys, "language.system"); item_sys.addActionListener(listener); item_sys.setSelected(Resource.getChosenLanguage() == null); item_sys.setActionCommand("system"); langMenu.add(item_sys); group.add(item_sys); langMenu.addSeparator(); Locale[] locales = Resource.getAvailableLocales(); for (int i = 0; i < locales.length; i++) { Locale item = locales[i]; JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem(item.getLanguage()); menuItem.addActionListener(listener); if (Resource.getChosenLanguage() != null) menuItem.setSelected(item.getLanguage().equals(Resource.getChosenLanguage())); menuItem.setActionCommand(item.getLanguage()); langMenu.add(menuItem); group.add(menuItem); } return langMenu; } /** * */ protected JMenu buildAddonMenu() { JMenu menu = new JMenu(); CommonGui.localize(menu, "Common.Addons"); menu.add(new JMenuItem("available components:")); menu.addSeparator(); // change: read table or list from common. if (Common.canAccessFtp()) menu.add(new JMenuItem("commons-net library (FTP access)")); if (Common.canAccessRawRead()) menu.add(new JMenuItem("rawread dll (ext. disk access)")); if (Common.getMpvDecoderClass().isAccelerated()) menu.add(new JMenuItem("accelerated preview (ext. IDCT)")); if (Common.canAccessColorTable()) menu.add(new JMenuItem("color tables (DVB subpicture)")); if (Common.canAccessSilentAC3()) menu.add(new JMenuItem("silent AC3 frames (replacements)")); return menu; } /** * */ protected JMenu buildHelpMenu() { JMenu help = new JMenu(); CommonGui.localize(help, "help.menu"); JMenuItem about = new JMenuItem(); CommonGui.localize(about, "help.about"); about.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { new AboutBox(frame); } }); JMenuItem openHtml = new JMenuItem(); CommonGui.localize(openHtml, "help.help"); openHtml.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { new Html().show(); } }); openHtml.setAccelerator(KeyStroke.getKeyStroke("F1")); JMenuItem version = new JMenuItem(); CommonGui.localize(version, "help.version"); version.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Common.checkVersion(); } }); help.add(about); help.addSeparator(); help.add(openHtml); help.addSeparator(); help.add(version); return help; } /** * */ protected JScrollPane createTable() { JScrollPane scrollpane; // final final String[] names = { "#", Resource.getString("CollectionTable.Source"), Resource.getString("CollectionTable.FileName"), Resource.getString("CollectionTable.FileLocation"), Resource.getString("CollectionTable.Size"), Resource.getString("CollectionTable.lastModified"), Resource.getString("ScanInfo.Video").substring(0, 1), Resource.getString("ScanInfo.Audio").substring(0, 1), Resource.getString("ScanInfo.Teletext").substring(0, 1), Resource.getString("ScanInfo.Subpicture").substring(0, 1), Resource.getString("CollectionTable.Streamtype") }; // Create a model of the data. TableModel dataModel = new AbstractTableModel() { public int getColumnCount() { return names.length; } public int getRowCount() { return FileObjectTable.length; } public Object getValueAt(int row, int col) { return FileObjectTable[row][col]; } public String getColumnName(int column) { return names[column]; } public Class getColumnClass(int c) { Object obj = getValueAt(0, c); if (obj == null) return String.class; return obj.getClass(); } public boolean isCellEditable(int row, int col) { return false; //return getColumnClass(col) == String.class; } public void setValueAt(Object aValue, int row, int column) { FileObjectTable[row][column] = aValue; } }; // Create the table tableView = new JTable(dataModel); // Show colors by rendering them in their own color. DefaultTableCellRenderer renderer_1 = new DefaultTableCellRenderer(); DefaultTableCellRenderer renderer_2 = new DefaultTableCellRenderer(); renderer_1.setHorizontalAlignment(JLabel.RIGHT); renderer_2.setHorizontalAlignment(JLabel.CENTER); tableView.setRowHeight(15); tableView.setGridColor(new Color(220, 220, 220)); tableView.removeEditor(); tableView.setToolTipText(Resource.getString("FilePanel.DragDrop.Tip")); tableView.setSelectionMode(2); tableView.setSelectionBackground(new Color(220, 220, 255)); tableView.setSelectionForeground(Color.black); tableView.getColumn("#").setCellRenderer(renderer_2); tableView.getColumn("#").setMaxWidth(20); tableView.getColumn(names[1]).setCellRenderer(renderer_2); tableView.getColumn(names[1]).setMinWidth(32); tableView.getColumn(names[1]).setMaxWidth(32); tableView.getColumn(names[2]).setPreferredWidth(200); tableView.getColumn(names[3]).setPreferredWidth(200); tableView.getColumn(names[4]).setCellRenderer(renderer_1); tableView.getColumn(names[4]).setMinWidth(62); tableView.getColumn(names[4]).setMaxWidth(62); tableView.getColumn(names[5]).setCellRenderer(renderer_2); tableView.getColumn(names[5]).setMinWidth(96); tableView.getColumn(names[5]).setMaxWidth(96); for (int i = 6; i < 10; i++) { tableView.getColumn(names[i]).setCellRenderer(renderer_2); tableView.getColumn(names[i]).setMinWidth(16); tableView.getColumn(names[i]).setMaxWidth(16); } tableView.getColumn(names[10]).setMinWidth(90); tableView.sizeColumnsToFit(JTable.AUTO_RESIZE_LAST_COLUMN); tableView.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() < 1) return; int row = tableView.getSelectedRow(); // empty row if (row >= 0 && tableView.getValueAt(row, 0) == null) row = -1; int index = Common.getActiveCollection(); if (e.getModifiers() == MouseEvent.BUTTON3_MASK) { MenuElement[] elements = popup.getSubElements(); if (elements == null) return; for (int i = 1; i < 12; i++) elements[i].getComponent().setEnabled(row >= 0); for (int i = 12; i < elements.length; i++) elements[i].getComponent().setEnabled(index >= 0); popup.show(tableView, e.getX(), e.getY() - popup.getHeight()); } else if (row >= 0) ScanInfo((XInputFile) Common.getCollection(index).getInputFile(row)); if (e.getClickCount() >= 2 && e.getModifiers() == MouseEvent.BUTTON1_MASK) Common.getGuiInterface().showPreSettings(); } }); DropTargetListener dnd1Listener = new DropTargetListener() { public void drop(DropTargetDropEvent e) { try { int dropaction = e.getDropAction(); // 1=copy, 2=move if (dropaction == 0 || dropaction > 2) { e.rejectDrop(); return; } e.acceptDrop(dropaction); Transferable tr = e.getTransferable(); DataFlavor[] df = tr.getTransferDataFlavors(); // Get list with one or more File objects // List li = (java.util.List)tr.getTransferData(df[0]); List list = null; Object obj = tr.getTransferData(df[0]); try { list = (java.util.List) obj; } catch (Exception ce1) { // MacOsX tiger returns one Url instead of a file list, works only without host specification of the file try { URL url = (URL)obj; File f = new File(url.getFile()); list = new ArrayList(); list.add(f); } catch (Exception ce2) { e.dropComplete(true); return; } } // Replace dropped File objects by XInputFile objects ArrayList tempList = new ArrayList(); for (int i = 0; i < list.size(); i++) tempList.add(new XInputFile((File)list.get(i))); list = tempList; if (dropaction == 1) // copy = new coll each { Object[] val = list.toArray(); /** * create new collection for each file */ for (int i = 0; i < val.length; i++) { JobCollection collection = Common.addCollection(); collection.addInputFile(val[i]); updateCollectionTable(collection.getCollectionAsTable()); } } else if (dropaction == 2) // move = one coll { Common.addCollection(false); Object[] val = list.toArray(); if (val.length > 0) { JobCollection collection = Common.getCollection(comboBox_0.getSelectedIndex()); collection.addInputFile(val); updateCollectionTable(collection.getCollectionAsTable()); } } e.dropComplete(true); if (list.size() > 0) updateCollectionPanel(Common.getActiveCollection()); } catch (Exception eee) { e.dropComplete(false); Common.setExceptionMessage(eee); } tableView.setBackground(Color.white); } public void dragEnter(DropTargetDragEvent e) { tableView.setBackground(Color.green); } public void dragExit(DropTargetEvent e) { tableView.setBackground(Color.white); } public void dragOver(DropTargetDragEvent e) {} public void dropActionChanged(DropTargetDragEvent e) {} }; DropTarget dropTarget_2 = new DropTarget(tableView, dnd1Listener); scrollpane = new JScrollPane(tableView); return scrollpane; } /** * */ protected JPanel buildFilePanel() { JPanel panel_1 = new JPanel(); panel_1.setLayout(new ColumnLayout()); /** * autoload */ JButton open_autoload = new JButton(CommonGui.loadIcon("fwd_10.gif")); open_autoload.setPreferredSize(new Dimension(30, 22)); open_autoload.setMaximumSize(new Dimension(30, 22)); open_autoload.setToolTipText(Resource.getString("FilePanel.openAutoloadPanel.Tip")); open_autoload.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { autoload.setState(0); autoload.show(); } }); panel_1.add(open_autoload); /** * add */ JButton file_add = new JButton(CommonGui.loadIcon("add.gif")); file_add.setPreferredSize(new Dimension(30, 22)); file_add.setMaximumSize(new Dimension(30, 22)); file_add.setToolTipText(Resource.getString("FilePanel.FileAdd.Tip")); file_add.setActionCommand("add"); file_add.addActionListener(_MenuListener); panel_1.add(file_add); /** * remove */ JButton file_remove = new JButton(CommonGui.loadIcon("rem.gif")); file_remove.setPreferredSize(new Dimension(30, 22)); file_remove.setMaximumSize(new Dimension(30, 22)); file_remove.setToolTipText(Resource.getString("FilePanel.FileRemove.Tip")); file_remove.setActionCommand("remove"); file_remove.addActionListener(_MenuListener); panel_1.add(file_remove); /** * up */ JButton file_up = new JButton(CommonGui.loadIcon("up.gif")); file_up.setPreferredSize(new Dimension(30, 22)); file_up.setMaximumSize(new Dimension(30, 22)); file_up.setToolTipText(Resource.getString("FilePanel.FileUp.Tip")); file_up.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int[] indices = tableView.getSelectedRows(); if (indices.length > 0) { JobCollection collection = Common.getCollection(comboBox_0.getSelectedIndex()); if (collection == null) return; for (int i = 0; i < indices.length; i++) { int index = indices[i]; if (index > 0 && tableView.getValueAt(index, 0) != null) { Object object = collection.removeInputFile(index); collection.addInputFile(index - 1, object); indices[i] = index - 1; } } updateCollectionTable(collection.getCollectionAsTable()); updateCollectionPanel(Common.getActiveCollection()); } } }); panel_1.add(file_up); /** * down */ JButton file_down = new JButton(CommonGui.loadIcon("dn.gif")); file_down.setPreferredSize(new Dimension(30, 22)); file_down.setMaximumSize(new Dimension(30, 22)); file_down.setToolTipText(Resource.getString("FilePanel.FileDown.Tip")); file_down.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int[] indices = tableView.getSelectedRows(); if (indices.length > 0) { JobCollection collection = Common.getCollection(comboBox_0.getSelectedIndex()); if (collection == null) return; for (int i = indices.length - 1; i >= 0; i--) { int index = indices[i]; if (index < collection.getInputFilesCount() - 1 && tableView.getValueAt(index, 0) != null) { Object object = collection.removeInputFile(index); collection.addInputFile(index + 1, object); indices[i] = index + 1; } } updateCollectionTable(collection.getCollectionAsTable()); updateCollectionPanel(Common.getActiveCollection()); } } }); panel_1.add(file_down); /** * */ JPanel panel_2 = new JPanel(); panel_2.setLayout(new BoxLayout(panel_2, BoxLayout.X_AXIS)); panel_2.add(new JLabel(Resource.getString("FilePanel.OutputDirectory"))); panel_2.add(Box.createRigidArea(new Dimension(6, 1))); outfield = new JTextField(); outfield.setBackground(new Color(225, 255, 225)); outfield.setMaximumSize(new Dimension(280, 20)); outfield.setMinimumSize(new Dimension(280, 20)); outfield.setEditable(false); outfield.setToolTipText(Resource.getString("FilePanel.OutputDirectory.Tip")); panel_2.add(outfield); panel_2.add(Box.createRigidArea(new Dimension(6, 1))); panel_2.add(new JLabel(Resource.getString("FilePanel.recentOutputDirectories"))); panel_2.add(Box.createRigidArea(new Dimension(6, 1))); /** * */ // recent output final JComboBox comboBox_13 = new JComboBox(Common.getSettings().getOutputDirectories().toArray()); comboBox_13.setMinimumSize(new Dimension(280, 20)); comboBox_13.setMaximumSize(new Dimension(280, 20)); comboBox_13.setMaximumRowCount(8); comboBox_13.insertItemAt(Resource.getString("working.output.std"), 0); comboBox_13.setSelectedItem(Common.getSettings().getProperty(Keys.KEY_OutputDirectory)); comboBox_13.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (comboBox_13.getItemCount() > 1) { if (comboBox_13.getSelectedIndex() == 0) Common.getSettings().remove(Keys.KEY_OutputDirectory[0]); else Common.getSettings().setProperty(Keys.KEY_OutputDirectory[0], comboBox_13.getSelectedItem()); if (comboBox_0.getItemCount() > 0) { Common.setActiveCollection(comboBox_0.getSelectedIndex()); JobCollection collection = Common.getCollection(); collection.setOutputDirectory(Common.getSettings().getProperty(Keys.KEY_OutputDirectory)); updateOutputField(collection); updateCollectionTable(collection.getCollectionAsTable()); } } else { Common.getSettings().remove(Keys.KEY_OutputDirectory[0]); if (comboBox_0.getItemCount() > 0) { Common.setActiveCollection(comboBox_0.getSelectedIndex()); JobCollection collection = Common.getCollection(); collection.setOutputDirectory(Common.getSettings().getProperty(Keys.KEY_OutputDirectory)); updateOutputField(collection); updateCollectionTable(collection.getCollectionAsTable()); } } } }); /** * */ JButton add_output = new JButton(CommonGui.loadIcon("add.gif")); add_output.setMinimumSize(new Dimension(24, 20)); add_output.setMaximumSize(new Dimension(24, 20)); add_output.setToolTipText(Resource.getString("FilePanel.addRecentOutputDirectory.Tip")); add_output.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { CommonGui.getMainFileChooser().rescanCurrentDirectory(); CommonGui.getMainFileChooser().setDialogType(JFileChooser.OPEN_DIALOG); CommonGui.getMainFileChooser().setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); int retval = CommonGui.getMainFileChooser().showDialog(frame, null); if (retval == JFileChooser.APPROVE_OPTION) { File theFile = CommonGui.getMainFileChooser().getSelectedFile(); String file = ""; if (theFile != null) { if (theFile.isFile()) file = theFile.getParent(); else if (theFile.isDirectory()) file = theFile.getAbsolutePath(); // do not list duplicates for (int i = 0; i < comboBox_13.getItemCount(); i++) if (file.equalsIgnoreCase(comboBox_13.getItemAt(i).toString())) return; Common.getSettings().addOutputDirectory(file); comboBox_13.addItem(file); comboBox_13.setSelectedItem(file); } } } }); /** * */ JButton remove_output = new JButton(CommonGui.loadIcon("rem.gif")); remove_output.setMinimumSize(new Dimension(24, 20)); remove_output.setMaximumSize(new Dimension(24, 20)); remove_output.setToolTipText(Resource.getString("FilePanel.removeRecentOutputDirectory.Tip")); remove_output.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (comboBox_13.getItemCount() > 1) { int index = comboBox_13.getSelectedIndex(); if (index > 0) { Common.getSettings().removeOutputDirectory(index - 1); comboBox_13.removeItemAt(index); } else Common.setOSDErrorMessage("Eintrag kann nicht entfernt werden.."); } if (comboBox_13.getItemCount() <= 1) Common.getSettings().remove(Keys.KEY_OutputDirectory[0]); } }); panel_2.add(add_output); panel_2.add(remove_output); panel_2.add(comboBox_13); /** * table + output dir's */ JPanel control_1 = new JPanel(new BorderLayout()); control_1.setAlignmentX(CENTER_ALIGNMENT); control_1.add(createTable(), BorderLayout.CENTER); control_1.add(panel_2, BorderLayout.SOUTH); /** * file panel at all */ JPanel control_2 = new JPanel(new BorderLayout()); control_2.setAlignmentX(CENTER_ALIGNMENT); control_2.add(control_1, BorderLayout.CENTER); control_2.add(panel_1, BorderLayout.WEST); /** * panel */ JPanel panel = new JPanel(); panel.setLayout( new GridLayout(1, 1) ); panel.setBorder(BorderFactory.createEtchedBorder()); panel.add(control_2); panel.setPreferredSize(new Dimension(900, 114)); panel.setMaximumSize(new Dimension(900, 114)); panel.setMinimumSize(new Dimension(900, 114)); return panel; } /** * */ private void closeAutoloadPanel() { autoload.dispose(); } /** * */ protected void buildAutoloadPanel() { autoload = new JFrame(Resource.getString("autoload.title")); autoload.addWindowListener ( new WindowAdapter() { public void windowClosing(WindowEvent e) { closeAutoloadPanel(); } }); JMenu fileMenu = new JMenu(); CommonGui.localize(fileMenu, "Common.File"); JMenuItem closemenu = new JMenuItem(); CommonGui.localize(closemenu, "Common.Close"); closemenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.ALT_MASK)); closemenu.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { closeAutoloadPanel(); } }); fileMenu.add(closemenu); JMenu editMenu = new JMenu(); CommonGui.localize(editMenu, "Common.Edit"); JCheckBoxMenuItem subdir = new JCheckBoxMenuItem(Resource.getString(Keys.KEY_InputDirectoriesDepth[0])); subdir.setToolTipText(Resource.getString(Keys.KEY_InputDirectoriesDepth[0]) + Keys.KEY_Tip); subdir.setActionCommand(Keys.KEY_InputDirectoriesDepth[0]); subdir.setState(Common.getSettings().getBooleanProperty(Keys.KEY_InputDirectoriesDepth)); subdir.addActionListener(_BoxListener); editMenu.add(subdir); /** * */ JMenuBar menuBar = new JMenuBar(); menuBar.add(fileMenu); menuBar.add(editMenu); autoload.setJMenuBar(menuBar); JPanel bb = new JPanel(); bb.setLayout( new ColumnLayout() ); /** * */ final JComboBox comboBox_12 = new JComboBox(Common.getSettings().getListProperty(Keys.KEY_InputDirectories).toArray()); // recent input comboBox_12.setMaximumRowCount(8); comboBox_12.setPreferredSize(new Dimension(400, 24)); /** * */ JButton remove_input = new JButton(CommonGui.loadIcon("rem.gif")); remove_input.setPreferredSize(new Dimension(50,28)); remove_input.setMaximumSize(new Dimension(50,28)); remove_input.setToolTipText(Resource.getString("autoload.dir.remove.tip")); remove_input.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (comboBox_12.getItemCount() > 0) { int index = comboBox_12.getSelectedIndex(); Common.getSettings().removeInputDirectory(index); Common.getSettings().updateInputDirectories(); comboBox_12.removeItemAt(index); } reloadInputDirectories(); } }); bb.add(remove_input); /** * */ JButton add_input = new JButton(CommonGui.loadIcon("add.gif")); add_input.setPreferredSize(new Dimension(50,28)); add_input.setMaximumSize(new Dimension(50,24)); add_input.setToolTipText(Resource.getString("autoload.dir.add.tip")); add_input.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { CommonGui.getMainFileChooser().rescanCurrentDirectory(); CommonGui.getMainFileChooser().setDialogType(JFileChooser.OPEN_DIALOG); CommonGui.getMainFileChooser().setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); int retval = CommonGui.getMainFileChooser().showDialog(frame, null); if (retval == JFileChooser.APPROVE_OPTION) { File theFile = CommonGui.getMainFileChooser().getSelectedFile(); if (theFile != null) { if (theFile.isFile()) theFile = theFile.getParentFile(); /** * must use getAbsolutFile to ensure right ClassType, * sometimes the returned Object.getClass * from selection is NOT of java.io.File!! */ String str = Common.getSettings().addInputDirectory(theFile.getAbsoluteFile()); if (str != null) { Common.getSettings().updateInputDirectories(); comboBox_12.addItem(str); comboBox_12.setSelectedItem(str); } reloadInputDirectories(); } autoload.toFront(); return; } autoload.toFront(); } }); bb.add(add_input); // Button to add a ftp server directory to the autoload list JButton add_inputftp = new JButton(CommonGui.loadIcon("ftp.gif")); add_inputftp.setPreferredSize(new Dimension(50,28)); add_inputftp.setMaximumSize(new Dimension(50,24)); add_inputftp.setToolTipText(Resource.getString("autoload.ftp.add.tip")); add_inputftp.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // Add ftp server directory to autoload list FtpChooser ftpChooser = new FtpChooser(); ftpChooser.pack(); ftpChooser.show(); XInputDirectory xInputDirectory = ftpChooser.getXInputDirectory(); if (ftpChooser.isTested() && xInputDirectory != null) { String str = Common.getSettings().addInputDirectory(xInputDirectory); if (str != null) { Common.getSettings().updateInputDirectories(); comboBox_12.addItem(str); comboBox_12.setSelectedItem(str); } reloadInputDirectories(); } autoload.setState(0); autoload.toFront(); } }); bb.add(add_inputftp); /** * */ JButton refresh_list = new JButton(CommonGui.loadIcon("rf.gif")); refresh_list.setPreferredSize(new Dimension(50,28)); refresh_list.setMaximumSize(new Dimension(50,28)); refresh_list.setToolTipText(Resource.getString("autoload.dir.refresh.tip")); refresh_list.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { reloadInputDirectories(); } }); bb.add(refresh_list); bb.add(new JLabel(" ")); /** * */ JButton add_coll_and_files = new JButton(CommonGui.loadIcon("addleft.gif")); add_coll_and_files.setPreferredSize(new Dimension(50,28)); add_coll_and_files.setMaximumSize(new Dimension(50,28)); add_coll_and_files.setToolTipText(Resource.getString("autoload.add.coll.tip")); add_coll_and_files.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Object[] val = list1.getSelectedValues(); /** * create new collection for each file */ for (int i = 0; i < val.length; i++) { JobCollection collection = Common.addCollection(); collection.addInputFile(val[i]); updateCollectionTable(collection.getCollectionAsTable()); } if (val.length > 0) updateCollectionPanel(Common.getActiveCollection()); autoload.toFront(); } }); bb.add(add_coll_and_files); /** * */ JButton add_files = new JButton(CommonGui.loadIcon("left.gif")); add_files.setPreferredSize(new Dimension(50, 28)); add_files.setMaximumSize(new Dimension(50, 28)); add_files.setToolTipText(Resource.getString("autoload.add.file.tip")); add_files.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Object[] val = list1.getSelectedValues(); if (val.length > 0) // one or more files { Common.addCollection(false); JobCollection collection = Common.getCollection(comboBox_0.getSelectedIndex()); collection.addInputFile(val); updateCollectionTable(collection.getCollectionAsTable()); updateCollectionPanel(Common.getActiveCollection()); autoload.toFront(); } } }); bb.add(add_files); bb.add(new JLabel(" ")); /** * */ JButton close = new JButton(CommonGui.loadIcon("x.gif")); close.setPreferredSize(new Dimension(50,28)); close.setMaximumSize(new Dimension(50,28)); close.setToolTipText(Resource.getString("autoload.close")); close.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { closeAutoloadPanel(); } }); bb.add(close); // in list list1 = new JList(new Object[0]); list1.setName("inl"); list1.setVisibleRowCount(8); list1.setSelectionMode(2); list1.setToolTipText(Resource.getString("autoload.rename.tip")); list1.addMouseListener( new MouseAdapter() { public void mouseClicked(MouseEvent e) { int index = list1.locationToIndex( e.getPoint()); if (e.getClickCount() > 1) { if (e.getModifiers() == MouseEvent.BUTTON3_MASK && index > -1) // rename file { try { if (((XInputFile)list1.getSelectedValue()).rename()) reloadInputDirectories(); } catch (IOException ioe) {} autoload.toFront(); } else if (e.getModifiers() == MouseEvent.BUTTON1_MASK && index > -1) // add file to coll { Common.addCollection(false); Object[] val = list1.getSelectedValues(); if (val.length > 0) // one or more files { JobCollection collection = Common.getCollection(comboBox_0.getSelectedIndex()); collection.addInputFile(val); updateCollectionTable(collection.getCollectionAsTable()); updateCollectionPanel(Common.getActiveCollection()); } autoload.toFront(); } } else if (e.getClickCount() == 1) { if (list1.getSelectedValue() != null ) ScanInfo( (XInputFile) list1.getSelectedValue()); } } }); list1.addKeyListener( new KeyAdapter() { public void keyPressed(KeyEvent e) { if (e.getKeyChar() == KeyEvent.VK_ENTER) { Common.addCollection(false); Object[] val = list1.getSelectedValues(); if (val.length > 0) // one or more files { JobCollection collection = Common.getCollection(comboBox_0.getSelectedIndex()); collection.addInputFile(val); updateCollectionTable(collection.getCollectionAsTable()); updateCollectionPanel(Common.getActiveCollection()); } autoload.toFront(); } } }); JScrollPane scrolltext = new JScrollPane(); scrolltext.setViewportView(list1); /** * */ JPanel control_1 = new JPanel(new BorderLayout()); control_1.setAlignmentX(CENTER_ALIGNMENT); control_1.add(scrolltext, BorderLayout.CENTER); control_1.add(comboBox_12, BorderLayout.NORTH); JPanel control_2 = new JPanel(new BorderLayout()); control_2.setAlignmentX(CENTER_ALIGNMENT); control_2.add(control_1, BorderLayout.CENTER); control_2.add(bb, BorderLayout.WEST); autoload.getContentPane().add(control_2); UIManager.addPropertyChangeListener(new UISwitchListener(control_2)); autoload.setBounds(200, 200, 700, 350); } /** * */ protected JPanel buildMainPanel() { /** * */ JPanel panel_1 = new JPanel(); panel_1.setLayout(new ColumnLayout()); MemoryMonitor memo = new MemoryMonitor(); if (Common.showGUI()) memo.surf.start(); panel_1.add(memo, BorderLayout.NORTH); panel_1.add(Box.createRigidArea(new Dimension(1, 5))); panel_1.add(Box.createRigidArea(new Dimension(1, 54))); panel_1.add(buildProcessControlPanel()); panel_1.add(buildCollectionControlPanel()); panel_1.setPreferredSize(new Dimension(115, 468)); panel_1.setMaximumSize(new Dimension(115, 468)); panel_1.setMinimumSize(new Dimension(115, 468)); /** * */ JPanel panel_2 = new JPanel(); panel_2.setLayout(new BoxLayout(panel_2, BoxLayout.X_AXIS)); panel_2.add(panel_1, BorderLayout.WEST); panel_2.add(collection_panel = new CollectionPanel(), BorderLayout.CENTER); panel_2.setPreferredSize(new Dimension(900, 468)); panel_2.setMaximumSize(new Dimension(900, 468)); panel_2.setMinimumSize(new Dimension(900, 468)); /** * */ JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); panel.add(panel_2, BorderLayout.CENTER); panel.add(buildFilePanel(), BorderLayout.SOUTH); return panel; } /** * */ protected javax.swing.JRootPane buildFilePanel1() { javax.swing.JRootPane pane = new javax.swing.JRootPane(); //javax.swing.JLayeredPane pane = new javax.swing.JLayeredPane(); pane.getContentPane().add(buildFilePanel()); return pane; } /** * */ protected JPanel buildProcessControlPanel() { JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); panel.setBorder(BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), Resource.getString("MainPanel.Process"))); /** * */ JButton process = new JButton(Resource.getString("MainPanel.QuickStart")); process.setToolTipText(Resource.getString("MainPanel.QuickStart.Tip")); process.setMnemonic('q'); process.setPreferredSize(new Dimension(100, 24)); process.setMaximumSize(new Dimension(100, 24)); process.setMinimumSize(new Dimension(100, 24)); process.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (Common.startProcess()) Common.startMainProcess(); } }); panel.add(process); panel.add(Box.createRigidArea(new Dimension(1, 5))); /** * process window open */ JButton processwindow = new JButton(Resource.getString("ProcessWindowPanel.Button")); processwindow.setPreferredSize(new Dimension(100, 24)); processwindow.setMaximumSize(new Dimension(100, 24)); processwindow.setMinimumSize(new Dimension(100, 24)); processwindow.setToolTipText(Resource.getString("MainPanel.Process") + " " + Resource.getString("ProcessWindowPanel.Button")); processwindow.setMnemonic('p'); processwindow.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Common.getGuiInterface().showLogWindow(); } }); panel.add(processwindow); return panel; } /** * */ protected JPanel buildCollectionControlPanel() { JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); panel.setBorder(BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), Resource.getString("MainPanel.Collection"))); final Color idle_color = new Color(230, 230, 230); final Color running_color = new Color(245, 215, 215); /** * info field */ final JTextArea textarea = new JTextArea(); textarea.setToolTipText(Resource.getString("FilePanel.Textfield.Tip")); textarea.setBackground(idle_color); textarea.setFont(new Font("Tahoma", Font.PLAIN, 11)); textarea.setEditable(false); JPanel panel_2 = new JPanel(); panel_2.setLayout(new GridLayout(1,1)); panel_2.setBorder(BorderFactory.createLoweredBevelBorder()); panel_2.setPreferredSize(new Dimension(100, 138)); panel_2.setMaximumSize(new Dimension(100, 138)); panel_2.setMinimumSize(new Dimension(100, 138)); panel_2.add(textarea); panel.add(panel_2); /** * collection label */ JLabel coll_label = new JLabel(Resource.getString("FilePanel.CollectionNumber")); coll_label.setPreferredSize(new Dimension(50, 24)); coll_label.setMaximumSize(new Dimension(50, 24)); coll_label.setHorizontalAlignment(SwingConstants.CENTER); coll_label.setToolTipText(Resource.getString("FilePanel.CollectionNumber.Tip")); /** * number of act. coll. */ comboBox_0 = new JComboBox(); comboBox_0.setPreferredSize(new Dimension(50, 24)); comboBox_0.setMaximumSize(new Dimension(50, 24)); comboBox_0.setMinimumSize(new Dimension(50, 24)); comboBox_0.setMaximumRowCount(6); comboBox_0.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (comboBox_0.getItemCount() > 0) { Common.setActiveCollection(comboBox_0.getSelectedIndex()); JobCollection collection = Common.getCollection(); updateOutputField(collection); updateCollectionTable(collection.getCollectionAsTable()); if (!SilentAction) updateCollectionPanel(Common.getActiveCollection()); } else { Common.setActiveCollection(-1); outfield.setText(""); updateCollectionTable(null); } } }); /** * remove collection */ JButton remove_coll = new JButton(CommonGui.loadIcon("rem.gif")); remove_coll.setPreferredSize(new Dimension(50, 24)); remove_coll.setMaximumSize(new Dimension(50, 24)); remove_coll.setToolTipText(Resource.getString("FilePanel.removeCollection.Tip")); remove_coll.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (Common.isCollectionListEmpty()) return; int index = comboBox_0.getSelectedIndex(); if (!Common.removeCollection(index)) return; comboBox_0.removeAllItems(); for (int i = 0; i < Common.getCollectionListSize(); i++) comboBox_0.addItem(String.valueOf(i)); if (index < comboBox_0.getItemCount()) comboBox_0.setSelectedIndex(index); if (!Common.isCollectionListEmpty() && index >= comboBox_0.getItemCount()) comboBox_0.setSelectedIndex(comboBox_0.getItemCount() - 1); if (Common.isCollectionListEmpty()) updateCollectionPanel(-1); } }); /** * add collection */ JButton add_coll = new JButton(CommonGui.loadIcon("add.gif")); add_coll.setPreferredSize(new Dimension(50, 24)); add_coll.setMaximumSize(new Dimension(50, 24)); add_coll.setToolTipText(Resource.getString("FilePanel.addCollection.Tip")); add_coll.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Common.addCollection(); updateCollectionPanel(Common.getActiveCollection()); } }); JPanel panel_0 = new JPanel(); panel_0.setLayout(new BoxLayout(panel_0, BoxLayout.X_AXIS)); panel_0.add(add_coll); panel_0.add(coll_label); panel.add(panel_0); JPanel panel_1 = new JPanel(); panel_1.setLayout(new BoxLayout(panel_1, BoxLayout.X_AXIS)); panel_1.add(remove_coll); panel_1.add(comboBox_0); panel.add(panel_1); /** * watch on changes */ class Clock implements Runnable { private Thread clockThread = null; private String text = ""; public void start() { if (clockThread == null) { clockThread = new Thread(this, "Clock_3"); clockThread.setPriority(Thread.MIN_PRIORITY); clockThread.start(); } } public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { update(); try { Thread.sleep(1000); } catch (InterruptedException e) {} } } private void update() { JobCollection collection = Common.getCollection(); String str = collection == null ? Resource.getString("JobCollection.NoInfo") : collection.getShortSummary(); if (text.equals(str)) return; text = str; textarea.setText(text); textarea.setBackground(collection != null && collection.isActive() ? running_color : idle_color); } public void stop() { clockThread = null; } } new Clock().start(); return panel; } /** * */ protected JPanel buildStatusPanel() { final JLabel status = new JLabel(Resource.getString("run.status")); status.setToolTipText("status of processing"); final JLabel settings = new JLabel(CommonGui.loadIcon("save_yes.gif")); settings.setToolTipText("do or don't save settings on exit"); settings.setEnabled(false); final JLabel date = new JLabel(); final JLabel time = new JLabel(); final JLabel onlineIcon = new JLabel("OFF"); onlineIcon.setToolTipText("WebIF online status"); final DateFormat date_format = DateFormat.getDateInstance(DateFormat.LONG); final DateFormat time_format = DateFormat.getTimeInstance(DateFormat.LONG); class Clock implements Runnable { private Thread clockThread = null; private String StatusString = ""; private String DateString = ""; private boolean SaveSettings = false; private boolean WebIFisOnline = false; public void start() { if (clockThread == null) { clockThread = new Thread(this, "Clock_1"); clockThread.setPriority(Thread.MIN_PRIORITY); clockThread.start(); } } public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { update(); try { Thread.sleep(1000); } catch (InterruptedException e) {} } } private void update() { updateStatusLabel(); updateWebIFLabel(); updateSettingsLabel(); updateDateLabel(); updateTimeLabel(); } private void updateStatusLabel() { String str = Common.getStatusString(); if (str.equals(StatusString)) return; StatusString = str; status.setText(StatusString); } private void updateWebIFLabel() { boolean b = Common.isWebServerOnline(); if (b == WebIFisOnline) return; WebIFisOnline = b; onlineIcon.setText(WebIFisOnline ? "ON" : "OFF"); } private void updateSettingsLabel() { boolean b = Common.getSettings().getBooleanProperty(Keys.KEY_SaveSettingsOnExit); if (b == SaveSettings) return; SaveSettings = b; settings.setEnabled(SaveSettings); // settings.setIcon(CommonGui.loadIcon(SaveSettings ? "save_yes.gif" : "save_no.gif")); } private void updateDateLabel() { String str = date_format.format(new Date()); if (str.equals(DateString)) return; DateString = str; date.setText(DateString); } private void updateTimeLabel() { time.setText(time_format.format(new Date())); } public void stop() { clockThread = null; } } new Clock().start(); JPanel status_1 = new JPanel(new BorderLayout()); status_1.setBorder(BorderFactory.createLoweredBevelBorder()); status_1.setPreferredSize(new Dimension(580, 22)); status_1.setMaximumSize(new Dimension(580, 22)); status_1.add(status); JPanel status_2 = new JPanel(new BorderLayout()); status_2.setBorder(BorderFactory.createLoweredBevelBorder()); status_2.setPreferredSize(new Dimension(30, 22)); status_2.setMaximumSize(new Dimension(30, 22)); status_2.add(onlineIcon); JPanel status_3 = new JPanel(new BorderLayout()); status_3.setBorder(BorderFactory.createLoweredBevelBorder()); status_3.setPreferredSize(new Dimension(30, 22)); status_3.setMaximumSize(new Dimension(30, 22)); status_3.add(settings); JPanel status_4 = new JPanel(new BorderLayout()); status_4.setBorder(BorderFactory.createLoweredBevelBorder()); status_4.setPreferredSize(new Dimension(130, 22)); status_4.setMaximumSize(new Dimension(130, 22)); status_4.add(date); JPanel status_5 = new JPanel(new BorderLayout()); status_5.setBorder(BorderFactory.createLoweredBevelBorder()); status_5.setPreferredSize(new Dimension(130, 22)); status_5.setMaximumSize(new Dimension(130, 22)); status_5.add(time); JPanel mainStatusPanel = new JPanel(); mainStatusPanel.setLayout(new BoxLayout(mainStatusPanel, BoxLayout.X_AXIS)); mainStatusPanel.add(status_1); mainStatusPanel.add(status_2); mainStatusPanel.add(status_3); mainStatusPanel.add(status_4); mainStatusPanel.add(status_5); return mainStatusPanel; } /** * show ScanInfos */ public void ScanInfo(XInputFile aXInputFile) { ScanInfo(aXInputFile, -1); } /** * show ScanInfos, only directly called from manual stream assignment */ public void ScanInfo(XInputFile aXInputFile, int streamtype) { if (aXInputFile.getStreamInfo() == null || streamtype > -1) Common.getScanClass().getStreamInfo(aXInputFile, streamtype); CommonGui.getPicturePanel().setStreamInfo(aXInputFile.getStreamInfo()); } /** * refresh inputfileslist */ public void reloadInputDirectories() { updateAutoloadList(Common.reloadInputDirectories()); } /** * main */ private void showStartUpProgress(StartUp startup, int value, String str) { if (startup == null) System.out.println(str); else startup.setProgress(value, str); } /** * main */ private void initialize(StartUp startup) { String[] version = Common.getVersion(); //StartUp startup = new StartUp(); try { //startup.show(); showStartUpProgress(startup, 0, "Loading GUI..."); buildGUI(startup); showStartUpProgress(startup, 70, "Loading Input Directories..."); reloadInputDirectories(); /** * loading GUI */ showStartUpProgress(startup, 80, "Loading Main Frame..."); frame.addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) { // X.closeProgram(true); Common.exitApplication(0); } }); frame.addComponentListener(new ComponentListener() { public void componentHidden(ComponentEvent e) {} public void componentMoved(ComponentEvent e) {} public void componentShown(ComponentEvent e) {} public void componentResized(ComponentEvent e) { int w = Integer.parseInt(Keys.KEY_WindowPositionMain_Width[1]); int h = Integer.parseInt(Keys.KEY_WindowPositionMain_Height[1]); Component c = e.getComponent(); Dimension preferred = new Dimension(w, h), current = c.getSize(); double newHeight = (preferred.getHeight() > current.getHeight()) ? preferred.getHeight() : current.getHeight(); double newWidth = (preferred.getWidth() > current.getWidth()) ? preferred.getWidth() : current.getWidth(); c.setSize(new Dimension((int)newWidth, (int)newHeight)); } }); frame.getContentPane().add(this); frame.setLocation(Common.getSettings().getIntProperty(Keys.KEY_WindowPositionMain_X), Common.getSettings().getIntProperty(Keys.KEY_WindowPositionMain_Y)); frame.setSize(new Dimension(Common.getSettings().getIntProperty(Keys.KEY_WindowPositionMain_Width), Common.getSettings().getIntProperty(Keys.KEY_WindowPositionMain_Height))); setFrameTitle(frametitle = version[0] + "/" + version[1] + " " + version[2] + " " + version[3]); showStartUpProgress(startup, 90, "Printing Environment Settings..."); Common.setMessage(null, false); Object[] obj = Common.getJavaEV(Common.getSettings().getInifile()); Common.setMessage(obj); Common.setMessage(""); // to OSD CommonGui.getPicturePanel().setOSDMessage(obj, true); showStartUpProgress(startup, 100, "Showing Main Frame..."); if (startup != null) { startup.set(Common.getSettings().getBooleanProperty(Keys.KEY_Agreement)); if (startup.get()) { setVisible0(true); startup.close(); startup = null; } } else setVisible0(true); /** * catch all other unhandled exception */ } catch(Exception e) { /** * in GUI mode clean GUI and show GUI message */ if (Common.showGUI()) { /** * close startup */ if (startup != null) { startup.close(); startup = null; } /** * close main frame */ if (frame != null) { frame.setVisible(false); } /** * show exception messge */ StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); CommonGui.showErrorMessageDialog(Resource.getString("startup.error") + "\n\n" + sw.toString(), Resource.getString("startup.error.title")); } /** * in CLI mode simply show stackTrace */ else { e.printStackTrace(); } Common.exitApplication(1); } } /** * */ public static void setVisible0(boolean b) { SwingUtilities.updateComponentTreeUI(frame); // update selecte L&F frame.setVisible(b); } /** * geht nicht.. */ public static void closeProgram(boolean b) { if (Common.isRunningProcess() && !CommonGui.getUserConfirmation("process is running, really stop'em ?")) return; Common.exitApplication(GlobalReturnCode); } /** * */ public static void setFrameTitle(String str) { frame.setTitle(str); } /** * */ public static void resetFrameTitle() { setFrameTitle(frametitle); } /** * */ public static Rectangle getFrameBounds() { return frame.getBounds(); } /** * */ public static void showFrame(boolean b) { frame.setState(b ? frame.NORMAL : frame.ICONIFIED); } /** * */ public static void showActiveCollection(int index) { if (index >= 0 && index < Common.getCollectionListSize()) comboBox_0.setSelectedIndex(index); if (Common.isCollectionListEmpty()) { Common.setActiveCollection(-1); comboBox_0.removeAllItems(); updateCollectionPanel(-1); } } /** * */ public static void updateCollectionPanel(int index) { collection_panel.entry(index); } }project-x/src/net/sourceforge/dvb/projectx/gui/MemoryMonitor.java0000600000175000017500000002635510307153316026711 0ustar supermariosupermario/* * @(#)MemoryMonitor.java 1.26 99/04/23 * * Copyright (c) 1998, 1999 by Sun Microsystems, Inc. All Rights Reserved. * * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use, * modify and redistribute this software in source and binary code form, * provided that i) this copyright notice and license appear on all copies of * the software; and ii) Licensee does not utilize the software in a manner * which is disparaging to Sun. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * This software is not designed or intended for use in on-line control of * aircraft, air traffic, aircraft navigation or aircraft communications; or in * the design, construction, operation or maintenance of any nuclear * facility. Licensee represents and warrants that it will not use or * redistribute the Software for such purposes. */ /** * 05/07/31, added sequential system.gc() call */ package net.sourceforge.dvb.projectx.gui; import java.awt.*; import java.awt.event.*; import java.awt.image.BufferedImage; import java.awt.geom.Line2D; import java.awt.geom.Rectangle2D; import java.util.Date; import javax.swing.*; import javax.swing.border.EtchedBorder; import javax.swing.border.TitledBorder; import net.sourceforge.dvb.projectx.common.Common; /** * Tracks Memory allocated & used, displayed in graph form. */ public class MemoryMonitor extends JPanel { public Surface surf; JPanel controls; boolean doControls; JTextField tf; JCheckBox box; public MemoryMonitor() { setLayout(new BorderLayout()); setBorder(new TitledBorder(new EtchedBorder(), "Memory Monitor")); add(surf = new Surface()); controls = new JPanel(); controls.setToolTipText("click to start/stop monitoring + memory saving"); Font font = new Font("serif", Font.PLAIN, 10); JLabel label; tf = new JTextField("1000"); tf.setPreferredSize(new Dimension(40,20)); controls.add(tf); controls.add(label = new JLabel("ms")); box = new JCheckBox("call gc()"); box.setPreferredSize(new Dimension(80,20)); box.setSelected(true); controls.add(box); controls.setPreferredSize(new Dimension(100, 80)); controls.setMaximumSize(new Dimension(100, 80)); label.setFont(font); label.setForeground(Color.black); addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { removeAll(); if ((doControls = !doControls)) { surf.stop(); add(controls); } else { try { long val = Long.parseLong(tf.getText().trim()); if (val >= 50) surf.sleepAmount = val; } catch (Exception ex) {} surf.start(); add(surf); } validate(); repaint(); } }); } public class Surface extends JPanel implements Runnable { public Thread thread; public long sleepAmount = 1000; private int w, h; private BufferedImage bimg; private Graphics2D big; private Font font = new Font("Times New Roman", Font.PLAIN, 11); private Runtime r = Runtime.getRuntime(); private int columnInc; private int pts[]; private int ptNum; private int ascent, descent; private float freeMemory, totalMemory; private Rectangle graphOutlineRect = new Rectangle(); private Rectangle2D mfRect = new Rectangle2D.Float(); private Rectangle2D muRect = new Rectangle2D.Float(); private Line2D graphLine = new Line2D.Float(); private Color graphColor = new Color(46, 139, 87); private Color mfColor = new Color(0, 100, 0); private String usedStr; private int gc_counter = 0; public Surface() { setBackground(Color.black); addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (thread == null) start(); else stop(); } }); } public Dimension getMinimumSize() { return getPreferredSize(); } public Dimension getMaximumSize() { return getPreferredSize(); } public Dimension getPreferredSize() { return new Dimension(100, 80); } public void paint(Graphics g) { if (big == null) { return; } big.setBackground(getBackground()); big.clearRect(0,0,w,h); float freeMemory = (float) r.freeMemory(); float totalMemory = (float) r.totalMemory(); // .. Draw allocated and used strings .. big.setColor(Color.green); big.drawString(String.valueOf((int) totalMemory/1024) + "K allocated", 4.0f, (float) ascent+0.5f); usedStr = String.valueOf(((int) (totalMemory - freeMemory))/1024) + "K used"; big.drawString(usedStr, 4, h-descent); // Calculate remaining size float ssH = ascent + descent; float remainingHeight = (float) (h - (ssH*2) - 0.5f); float blockHeight = remainingHeight/10; float blockWidth = 20.0f; float remainingWidth = (float) (w - blockWidth - 10); // .. Memory Free .. big.setColor(mfColor); int MemUsage = (int) ((freeMemory / totalMemory) * 10); int i = 0; for ( ; i < MemUsage ; i++) { mfRect.setRect(5,(float) ssH+i*blockHeight, blockWidth,(float) blockHeight-1); big.fill(mfRect); } // .. Memory Used .. big.setColor(Color.green); for ( ; i < 10; i++) { muRect.setRect(5,(float) ssH+i*blockHeight, blockWidth,(float) blockHeight-1); big.fill(muRect); } // .. Draw History Graph .. big.setColor(graphColor); int graphX = 30; int graphY = (int) ssH; int graphW = w - graphX - 5; int graphH = (int) remainingHeight; graphOutlineRect.setRect(graphX, graphY, graphW, graphH); big.draw(graphOutlineRect); int graphRow = graphH/10; // .. Draw row .. for (int j = graphY; j <= graphH+graphY; j += graphRow) { graphLine.setLine(graphX,j,graphX+graphW,j); big.draw(graphLine); } // .. Draw animated column movement .. int graphColumn = graphW/15; if (columnInc == 0) { columnInc = graphColumn; } for (int j = graphX+columnInc; j < graphW+graphX; j+=graphColumn) { graphLine.setLine(j,graphY,j,graphY+graphH); big.draw(graphLine); } --columnInc; if (pts == null) { pts = new int[graphW]; ptNum = 0; } else if (pts.length != graphW) { int tmp[] = null; if (ptNum < graphW) { tmp = new int[ptNum]; System.arraycopy(pts, 0, tmp, 0, tmp.length); } else { tmp = new int[graphW]; System.arraycopy(pts, pts.length-tmp.length, tmp, 0, tmp.length); ptNum = tmp.length - 2; } pts = new int[graphW]; System.arraycopy(tmp, 0, pts, 0, tmp.length); } else { big.setColor(Color.yellow); pts[ptNum] = (int)(graphY+graphH*(freeMemory/totalMemory)); for (int j=graphX+graphW-ptNum, k=0;k < ptNum; k++, j++) { if (k != 0) { if (pts[k] != pts[k-1]) { big.drawLine(j-1, pts[k-1], j, pts[k]); } else { big.fillRect(j, pts[k], 1, 1); } } } if (ptNum+2 == pts.length) { // throw out oldest point for (int j = 1;j < ptNum; j++) { pts[j-1] = pts[j]; } --ptNum; } else { ptNum++; } } if (gc_counter > 4) { //if (!Common.isRunningProcess() && thread != null && box.isSelected() && freeMemory < 2048000L) if (thread != null && box.isSelected() && freeMemory < 2048000L) { big.setColor(Color.red); big.fillRect(84, h - descent - 6, 4, 4); System.gc(); } gc_counter = 0; } else gc_counter++; g.drawImage(bimg, 0, 0, this); } public void start() { thread = new Thread(this); thread.setPriority(Thread.MIN_PRIORITY); thread.setName("MemoryMonitor"); thread.start(); } public synchronized void stop() { thread = null; notify(); } public void run() { Thread me = Thread.currentThread(); while (thread == me && !isShowing() || getSize().width == 0) { try { thread.sleep(500); } catch (InterruptedException e) { return; } } while (thread == me && isShowing()) { Dimension d = getSize(); if (d.width != w || d.height != h) { w = d.width; h = d.height; bimg = (BufferedImage) createImage(w, h); big = bimg.createGraphics(); big.setFont(font); FontMetrics fm = big.getFontMetrics(font); ascent = (int) fm.getAscent(); descent = (int) fm.getDescent(); } repaint(); try { thread.sleep(sleepAmount); } catch (InterruptedException e) { break; } } thread = null; } } } project-x/src/net/sourceforge/dvb/projectx/gui/PatchDialog.java0000600000175000017500000001530010351107720026231 0ustar supermariosupermario/* * @(#)PatchDialog.java - patching video basics * * Copyright (c) 2001-2005 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.UIManager; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.gui.UISwitchListener; import net.sourceforge.dvb.projectx.gui.CommonGui; import net.sourceforge.dvb.projectx.xinput.XInputFile; /** * Class Patch Panel. */ public class PatchDialog extends JDialog { /** patchfield */ private JTextField[] patchfield = new JTextField[3]; /** the file to be patched */ XInputFile xInputFile=null; /** the labels */ private String[] notes = { " H:"," V:"," BR:","bps " }; private long ins=0; private byte[] os = new byte[1]; /** instance of the PatchListener */ private PatchListener patchAction = new PatchListener(); /** * ActionListener for the PatchPanel. */ private class PatchListener implements ActionListener { /* (non-Javadoc) * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ public void actionPerformed(ActionEvent e) { String actName = e.getActionCommand(); if (actName.equals("change")) change(); else if (actName.equals("cancel")) cancel(); } } /** * Constructor of the PatchPanel. * * @param f The parent Frame */ public PatchDialog(JFrame f) { super(f, Resource.getString("PatchPanel.Title"), true); JPanel container = new JPanel(); container.setLayout( new BorderLayout() ); JPanel grid = new JPanel(); grid.setLayout(new BoxLayout(grid, BoxLayout.X_AXIS)); for (int a = 0; a < 3; a++) { patchfield[a] = new JTextField(""); patchfield[a].setPreferredSize(new Dimension(65,22)); patchfield[a].setMaximumSize(new Dimension(65,22)); grid.add(new JLabel(notes[a])); grid.add(patchfield[a]); } grid.add(new JLabel(notes[3])); JButton changebutton = new JButton(); CommonGui.localize(changebutton, "PatchPanel.Change"); changebutton.setActionCommand("change"); changebutton.addActionListener(patchAction); grid.add(changebutton); JButton cancelbutton = new JButton(); CommonGui.localize(cancelbutton, "PatchPanel.Cancel"); cancelbutton.setActionCommand("cancel"); cancelbutton.addActionListener(patchAction); grid.add(cancelbutton); getRootPane().setDefaultButton(cancelbutton); container.add(grid); getContentPane().add(container); pack(); centerDialog(); UIManager.addPropertyChangeListener(new UISwitchListener(container)); } /** * Search the given file for video basics. * * @param file * @param os * @return */ private boolean search(XInputFile aXInputFile, byte[] os) { try { long size = aXInputFile.length(); byte[] ps = new byte[((size<650000)?(int)size:650000)]; aXInputFile.randomAccessSingleRead(ps, 0); for (int a = 0; a < ps.length - 15; a++) { if (ps[a] != 0 || ps[a + 1] != 0 || ps[a + 2] != 1 || ps[a + 3] != (byte)0xB3 || ps[a + 4] != os[4] || ps[a + 5] != os[5] || ps[a + 6] != os[6] || ps[a + 7] != os[7] ) continue; ins = a; patchfield[0].setText("" + ((255 & ps[a + 4])<<4 | (240 & ps[a + 5])>>>4)); patchfield[1].setText("" + ((15 & ps[a + 5])<<8 | (255 & ps[a + 6]))); patchfield[2].setText("" + (((255 & ps[a + 8])<<10 | (255 & ps[a + 9])<<2 | (192 & ps[a + 10])>>>6) * 400)); return true; } } catch (IOException e) { Common.setExceptionMessage(e); } return false; } /** * @param file1 * @param os */ public boolean entry(XInputFile aXInputFile) { xInputFile = aXInputFile; os = xInputFile.getStreamInfo().getVideoHeader(); if (os == null) return false; if (search(xInputFile, os)) this.show(); return true; } /** * Centers this dialog on the users screen. */ protected void centerDialog() { Dimension screenSize = this.getToolkit().getScreenSize(); Dimension size = this.getSize(); screenSize.height = screenSize.height / 2; screenSize.width = screenSize.width / 2; size.height = size.height / 2; size.width = size.width / 2; int y = screenSize.height - size.height; int x = screenSize.width - size.width; this.setLocation(x,y); } /** * Callback for the cancel event. */ private void cancel() { this.setVisible(false); } /** * Callback for the change event. */ private void change() { try { int hsize=Integer.parseInt(patchfield[0].getText()); int vsize=Integer.parseInt(patchfield[1].getText()); int brate=Integer.parseInt(patchfield[2].getText()) / 400; os[4] = (byte)(0xFF & hsize>>>4); os[5] = (byte)((0xF0 & hsize<<4) | (0xF & vsize>>>8)); os[6] = (byte)(0xFF & vsize); os[8] = (byte)(0xFF & brate>>>10); os[9] = (byte)(0xFF & brate>>>2); os[10]= (byte)((0x3F & os[10]) | (0xC0 & brate<<6)); dochange(); } catch (NumberFormatException e) {} catch (NullPointerException e) {} } /** * applies the actual change to the file. */ private void dochange() { try { xInputFile.randomAccessOpen("rw"); xInputFile.randomAccessSeek(ins); xInputFile.randomAccessWrite(os); xInputFile.randomAccessClose(); } catch (IOException e) { Common.setExceptionMessage(e); } this.setVisible(false); } } project-x/src/net/sourceforge/dvb/projectx/gui/PicturePanel.java0000600000175000017500000005775110402447040026464 0ustar supermariosupermario/* * @(#)PicturePanel * * Copyright (c) 2003-2006 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Image; import java.awt.Font; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.MemoryImageSource; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.UIManager; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.gui.X_JFileChooser; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.video.PreviewObject; import net.sourceforge.dvb.projectx.video.Video; import net.sourceforge.dvb.projectx.xinput.StreamInfo; public class PicturePanel extends JPanel { private Image StreamTypeImage = Resource.loadImage("_container.gif"); private Image VideoImage = Resource.loadImage("_video.gif"); private Image AudioImage = Resource.loadImage("_audio.gif"); private Image TeletextImage = Resource.loadImage("_teletext.gif"); private Image SubtitleImage = Resource.loadImage("_subtitle.gif"); private Image PlaytimeImage = Resource.loadImage("_playtime.gif"); private Image PalPlusImage = Resource.loadImage("_ppl.gif"); private Image SubpictureImage; private Image image; private MemoryImageSource source; private boolean showFileInfo = false; private boolean isSubpictureAvailable = false; private boolean isOSDInfoAvailable = false; private boolean isOSDErrorInfo = false; private boolean PLAY = true; private StreamInfo streamInfo = null; private Font font_1; private Font font_2; private Font font_3; private int ErrorFlag = 0; private int bmpCount = 0; private int collection_number = -1; private final String tooltip1 = Resource.getString("mpvdecoder.tip1"); private long cutfiles_length = 0; private long[] cutfiles_points = null; private long chapter_length = 0; private long[] chapter_points = null; private Object[] OSDInfo; private JPopupMenu popup; private Clock clock; /** * class to control short OSD fadings */ private class Clock implements Runnable { private Thread clockThread = null; private int sleepAmount = 3000; public void start() { start(3000); } public void start(int value) { if (clockThread == null) { clockThread = new Thread(this, "Clock_4"); clockThread.setPriority(Thread.MIN_PRIORITY); sleepAmount = value; clockThread.start(); } } public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { try { Thread.sleep(sleepAmount); // time on screen } catch (InterruptedException e) {} if (update()) repaint(); stop(); } } private boolean update() { boolean b = false; if (collection_number >= 0) { collection_number = -1; b = true; } if (showFileInfo) { showFileInfo = false; b = true; } if (isOSDInfoAvailable) { isOSDInfoAvailable = false; b = true; } return b; } public void stop() { clockThread = null; } } /** * */ public PicturePanel() { source = new MemoryImageSource(512, 288, Common.getMpvDecoderClass().getPreviewPixel(), 0, 512); source.setAnimated(true); image = createImage(source); font_1 = new Font("Tahoma", Font.PLAIN, 12); font_2 = new Font("Tahoma", Font.BOLD, 12); font_3 = new Font("Tahoma", Font.BOLD, 24); setBackground(Color.black); setVisible(true); setToolTipText(tooltip1); // <- VORSCHLAG 1 Tooltip! setSize(512, 346); buildPopupMenu(); addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() >= 1 && (showFileInfo || isOSDInfoAvailable)) { showFileInfo = false; isOSDInfoAvailable = false; repaint(); } // if (e.getClickCount() > 1) // saveBMP(Common.getMpvDecoderClass().getPixels(), Common.getMpvDecoderClass().getWidth(), Common.getMpvDecoderClass().getHeight(), Common.getMpvDecoderClass().getAspectRatio()); if (e.getClickCount() >= 1 && e.getModifiers() == MouseEvent.BUTTON3_MASK) popup.show(getParent(), e.getX(), e.getY()); } }); clock = new Clock(); } /** * */ protected void buildPopupMenu() { ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e) { String actName = e.getActionCommand(); if (actName.equals("save_1")) saveBMP(Common.getMpvDecoderClass().getPixels(), Common.getMpvDecoderClass().getWidth(), Common.getMpvDecoderClass().getHeight(), 0, false); else if (actName.equals("save_2")) saveBMP(Common.getMpvDecoderClass().getPixels(), Common.getMpvDecoderClass().getWidth(), Common.getMpvDecoderClass().getHeight(), Common.getMpvDecoderClass().getAspectRatio(), true); } }; popup = new JPopupMenu("save"); JMenuItem menuitem_1 = popup.add(Resource.getString("PreviewPanel.saveCurrentPicture")); menuitem_1.setActionCommand("save_1"); JMenuItem menuitem_2 = popup.add(Resource.getString("PreviewPanel.saveCurrentPictureDAR")); menuitem_2.setActionCommand("save_2"); popup.pack(); UIManager.addPropertyChangeListener(new UISwitchListener(popup)); menuitem_1.addActionListener(al); menuitem_2.addActionListener(al); } /** * holds special messages */ public void startClock() { clock.start(); } /** * holds special messages */ public void startClock(int value) { clock.start(value); } /** * updates the preview graphic */ public void paint(Graphics g) { g.setColor(Color.black); g.fillRect(0, 0, 600, 600); g.setColor(new Color(0, 35, 110)); g.fillRect(0, 290, 514, 340); paintOutline(g); g.drawImage(image, 2, 2, this); g.setFont(font_1); g.setColor(Color.white); g.drawString(Common.getMpvDecoderClass().getInfo_1(), 36, 303); g.drawString(Common.getMpvDecoderClass().getInfo_2(), 36, 317); paintWSSInfo(g); paintErrorInfo(g); paintPlayInfo(g); g.setFont(font_2); paintCutInfo(g); paintChapterInfo(g); paintSubpicture(g); paintOSDInfo(g); paintFileInfo(g); paintCollectionNumber(g); } /** * paint */ private void paintOutline(Graphics g) { Color line_1 = new Color(191, 191, 191); Color line_2 = new Color(255, 255, 255); Color line_3 = new Color(151, 151, 151); g.setColor(line_3); g.drawLine(1, 1, 514, 1); g.drawLine(1, 1, 1, 400); g.setColor(line_1); g.drawLine(2, 290, 514, 290); g.drawLine(514, 2, 514, 400); g.setColor(line_2); g.drawLine(0, 0, 515, 0); g.drawLine(0, 0, 0, 400); g.drawLine(0, 291, 515, 291); g.drawLine(515, 0, 515, 400); } /** * paint */ private void paintCollectionNumber(Graphics g) { if (collection_number < 0) return; g.setFont(font_2); g.setColor(Color.green); g.drawString("Collection", 454, 16); g.setFont(font_3); g.setColor(Color.green); g.drawString(String.valueOf(collection_number), 474, 38); } /** * paint wss info */ private void paintWSSInfo(Graphics g) { String str; if ((str = Common.getMpvDecoderClass().getWSSInfo()) == null) { setToolTipText(tooltip1); return; } g.setFont(font_2); g.setColor(Color.green); g.drawString("WSS present", 10, 16); g.drawString(Common.getMpvDecoderClass().getWSSFormatInfo(), 10, 30); if (Common.getMpvDecoderClass().getPalPlusInfo()) g.drawImage(PalPlusImage, 8, 34, this); setToolTipText("" + tooltip1 + "

" + str + ""); } /** * paint play info */ private void paintPlayInfo(Graphics g) { int x[] = { 10, 10, 30 }; int y[] = { 294, 314, 304 }; if (PLAY) { g.setColor(Color.green); g.fillPolygon(x, y, 3); } else { g.setColor(Color.red); g.fillRect(10, 294, 20, 20); } } /** * paint error info */ private void paintErrorInfo(Graphics g) { ErrorFlag = Common.getMpvDecoderClass().getErrors(); if ((ErrorFlag & 1) != 0) { g.setColor(Color.white); g.fill3DRect(150, 120, 200, 20, true); g.setColor(Color.red); g.drawString("error while decoding frame", 160, 133); } if ((ErrorFlag & 4) != 0) { g.setColor(Color.white); g.fill3DRect(150, 135, 200, 20, true); g.setColor(Color.red); g.drawString("not enough data in buffer", 160, 148); } if ((ErrorFlag & 2) != 0) { g.setColor(Color.white); g.fill3DRect(150, 150, 200, 20, true); g.setColor(Color.red); g.drawString("cannot find sequence header", 160, 163); } } /** * paint cut info */ private void paintCutInfo(Graphics g) { if (cutfiles_length <= 0) return; int x1 = 10, y1 = 327, w1 = 492, h1 = 6; g.setColor(new Color(0, 200, 0)); g.fillRect(x1, y1, w1, h1); g.setColor(Color.white); g.drawRect(x1 -2, y1 -2, w1 +3, h1 +3); /** * paint cut markers */ if (cutfiles_points != null && cutfiles_points.length > 0) { int p0 = 0, p1 = 0; for (int i = 0; i < cutfiles_points.length; i++) { if (cutfiles_points[i] > cutfiles_length) break; p0 = i == 0 ? 0 : (int)(cutfiles_points[i - 1] * w1 / cutfiles_length); p1 = (int)(cutfiles_points[i] * w1 / cutfiles_length); if (i % 2 == 0) { g.setColor(new Color(150, 0, 0)); g.fillRect(x1 + p0, y1, p1 - p0, h1); } g.setColor(new Color(200, 100, 200)); g.fillRect(x1 + p1 - 1, y1 - 4, 2, h1 + 8); int[] x = { x1 + p1 - 1, x1 + p1 - 5, x1 + p1 + 5 }; int[] y = { y1 - 3, y1 - 3 - 5, y1 - 3 - 5 }; g.fillPolygon(x, y, 3); } if ((cutfiles_points.length & 1) == 0) { p0 = (int)(cutfiles_points[cutfiles_points.length - 1] * w1 / cutfiles_length); g.setColor(new Color(150, 0, 0)); g.fillRect(x1 + p0, y1, w1 - p0, h1); } } } /** * paint chapter info */ private void paintChapterInfo(Graphics g) { if (chapter_length <= 0) return; int x1 = 10, y1 = 327, w1 = 492, h1 = 6; /** * paint chapter markers */ if (chapter_points != null && chapter_points.length > 0) { int p0 = 0, p1 = 0; for (int i = 0; i < chapter_points.length; i++) { if (chapter_points[i] > chapter_length) break; p0 = i == 0 ? 0 : (int)(chapter_points[i - 1] * w1 / chapter_length); p1 = (int)(chapter_points[i] * w1 / chapter_length); g.setColor(new Color(195, 205, 255)); g.fillRect(x1 + p1 - 1, y1 - 4, 2, h1 + 8); int[] x = { x1 + p1 - 1, x1 + p1 - 5, x1 + p1 + 5 }; int[] y = { y1 + h1 + 3, y1 + h1 + 3 + 5, y1 +h1 + 3 + 5 }; g.fillPolygon(x, y, 3); } } } /** * paint */ private void paintOSDBg(Graphics g, int x3, int y3, int w3, int h3) { Color blue_1 = new Color(150, 150, 255, 210); Color blue_2 = new Color(50, 20, 225, 210); Color red_1 = new Color(255, 150, 150, 210); Color red_2 = new Color(225, 20, 20, 210); g.setColor(isOSDErrorInfo ? red_1 : blue_1); g.fillRect(x3, y3 + 20, w3, 220); g.setColor(isOSDErrorInfo ? red_2 : blue_2); g.fillRect(x3, y3, w3, 20); g.fillRect(x3, y3 + h3, w3, 34); g.setColor(Color.white); g.drawLine(x3, y3 + 20, x3 + w3 - 1, y3 + 20); g.drawLine(x3, y3 + 240, x3 + w3 - 1, y3 + 240); } /** * paint prescan file info */ private void paintOSDInfo(Graphics g) { if (!isOSDInfoAvailable || OSDInfo == null || OSDInfo.length == 0) return; int x3 = 8; //15; int y3 = 8; int w3 = 496; //482; int h3 = 240; int yOffset = 0; paintOSDBg(g, x3, y3, w3, h3); g.setColor(Color.white); g.drawString(OSDInfo[0].toString(), x3 + 10, y3 + 14); g.drawString(OSDInfo[1].toString(), x3 + 10, y3 + h3 + 16); yOffset = y3 + 24; for (int i = 2; i < OSDInfo.length; i++) yOffset = paintSubInfo(g, OSDInfo[i].toString(), null, x3, yOffset); } /** * paint prescan file info */ private void paintFileInfo(Graphics g) { if (!showFileInfo) return; int x3 = 8; //15; int y3 = 8; int w3 = 496; //482; int h3 = 240; int yOffset = 0; Object[] obj; paintOSDBg(g, x3, y3, w3, h3); g.setColor(Color.white); g.drawString(streamInfo.getFileSourceAndName(), x3 + 6, y3 + 14); g.drawString(streamInfo.getFileDate(), x3 + 6, y3 + h3 + 16); g.drawString(streamInfo.getFileSize(), x3 + 6, y3 + h3 + 30); yOffset = y3 + 24; yOffset = paintSubInfo(g, streamInfo.getFileType(), StreamTypeImage, x3, yOffset); obj = streamInfo.getVideoStreams(); yOffset = paintSubInfo(g, obj, VideoImage, x3, yOffset); obj = streamInfo.getAudioStreams(); yOffset = paintSubInfo(g, obj, AudioImage, x3, yOffset); obj = streamInfo.getTeletextStreams(); yOffset = paintSubInfo(g, obj, TeletextImage, x3, yOffset); obj = streamInfo.getSubpictureStreams(); yOffset = paintSubInfo(g, obj, SubtitleImage, x3, yOffset); yOffset = paintSubInfo(g, streamInfo.getPlaytime(), PlaytimeImage, x3, yOffset); } /** * line height = 16 */ private int paintSubInfo(Graphics g, String str, Image icon, int x, int y) { if (str != null && str.length() > 0) { if (y > 230) { g.fillPolygon(new int[] { x + 3, x + 17, x + 9 }, new int[] { y, y, y + 7 }, 3); g.drawString("...", x + 25, y + 6); return y; } int i = str.indexOf("\t"); int j = icon != null ? 25 : 10; if (icon != null) g.drawImage(icon, x + 2, y, this); if (i >= 0) { g.drawString(str.substring(i + 1), x + j + 120, y + 12); g.drawString(str.substring(0, i), x + j, y + 12); } else g.drawString(str, x + j, y + 12); y += 16; } return y; } /** * */ private int paintSubInfo(Graphics g, Object[] obj, Image icon, int x, int y) { if (obj != null && obj.length > 0) { for (int i = 0; i < obj.length; i++) y = paintSubInfo(g, "" + (i + 1) + ". " + obj[i].toString(), icon, x, y); } return y; } /** * paint prescan file info */ private void paintSubpicture(Graphics g) { if (!isSubpictureAvailable) return; g.drawImage(SubpictureImage, 66, 2, this); } /** * */ private void loadSubpicture() { SubpictureImage = !isSubpictureAvailable ? null : Common.getSubpictureClass().getScaledImage(); } /** * */ public void setStreamInfo(StreamInfo _streamInfo) { streamInfo = _streamInfo.getNewInstance(); //betta to get a copy showFileInfo = streamInfo != null; if (showFileInfo && !Common.getSettings().getBooleanProperty(Keys.KEY_holdStreamInfoOnOSD)) startClock(10000); isSubpictureAvailable = showFileInfo && streamInfo.getStreamType() == CommonParsing.ES_SUP_TYPE; loadSubpicture(); isOSDInfoAvailable = false; isOSDErrorInfo = false; repaint(); } /** * */ public void setOSD(Object[] obj) { isOSDErrorInfo = false; setOSDMessage(obj); } /** * */ public void setOSDMessage(String str, boolean b) { isOSDErrorInfo = b; setOSDMessage(new Object[]{ b ? "Fehler" : "Info", "", "", str }); } /** * */ public void setOSDMessage(Object[] obj) { setOSDMessage(obj, false); } /** * */ public void setOSDMessage(Object[] obj, boolean hold) { OSDInfo = obj; isOSDInfoAvailable = true; showFileInfo = false; if (!hold) startClock(10000); repaint(); } /** * */ public void showCollectionNumber(int value) { collection_number = value; startClock(); repaint(); } /** * */ public void updatePreviewPixel() { source.newPixels(); } /** * updates cut symbols in preview info field * * @param1 - do_export bool * @param2 - cutpoints list array * @param3 - previewlist of files */ public void showCutIcon(boolean play, Object[] obj, Object list) { PLAY = play; List previewList = (List) list; if (!previewList.isEmpty()) { cutfiles_length = ((PreviewObject) previewList.get(previewList.size() - 1)).getEnd(); if (obj != null) { cutfiles_points = new long[obj.length]; for (int i = 0; i < cutfiles_points.length; i++) cutfiles_points[i] = CommonParsing.parseCutValue(obj[i].toString(), false); } else cutfiles_points = null; } else { cutfiles_length = 0; cutfiles_points = null; } repaint(); } /** * updates chapter symbols in preview info field * * @param1 - do_export bool * @param2 - chapterpoints list array * @param3 - previewlist of files */ public void showChapterIcon(Object[] obj, Object list) { List previewList = (List) list; if (!previewList.isEmpty()) { chapter_length = ((PreviewObject) previewList.get(previewList.size() - 1)).getEnd(); if (obj != null) { chapter_points = new long[obj.length]; for (int i = 0; i < chapter_points.length; i++) chapter_points[i] = CommonParsing.parseCutValue(obj[i].toString(), false); } else chapter_points = null; } else { chapter_length = 0; chapter_points = null; } repaint(); } /** * performs YUV to RGB conversion */ private int YUVtoRGB(int YUV) { int T = 0xFF; int Y = 0xFF & YUV>>>16; int Cb = 0xFF & YUV>>>8; int Cr = 0xFF & YUV; if (Y == 0) return 0; int R = (int)((float)Y +1.402f * (Cr - 128)); int G = (int)((float)Y -0.34414 * (Cb - 128) -0.71414 * (Cr - 128)); int B = (int)((float)Y +1.722 * (Cb - 128)); R = R < 0 ? 0 : (R > 0xFF ? 0xFF : R); G = G < 0 ? 0 : (G > 0xFF ? 0xFF : G); B = B < 0 ? 0 : (B > 0xFF ? 0xFF : B); return (T<<24 | R<<16 | G<<8 | B); } /** * BMP 24-bit header */ private byte bmpHead[] = { 0x42, 0x4D, //'B','M' 0, 0, 0, 0, // real filesize 32bit, little endian (real size*3 + header(0x36)) 0, 0, 0, 0, 0x36, 0, 0, 0, //bitmap info size 0x28, 0, 0, 0, 0, 0, 0, 0, //hsize 0, 0, 0, 0, //vsize 1, 0, //nplane 0x18, 0, //bitcount 24b 0, 0, 0, 0, //ncompr 0, 0, 0, 0, //image bytesize (byte)0x88, 0xB, 0, 0, //nxpm (byte)0x88, 0xB, 0, 0, //nypm 0, 0, 0, 0, //nclrused, 0, 0, 0, 0 //nclrimp }; /** * performs change of byte order * * @param1 - source byte array * @param2 - array position * @param3 - source int value */ private void littleEndian(byte[] array, int aPos, int value) { for (int a = 0; a < 4; a++) array[aPos + a] = (byte)(value>>(a * 8) & 0xFF); } /** * */ private double[] aspectratio_table = { 1.3333, 1.3333, 1.3333, 1.7778, 2.2100, 1.3333, 1.3333, 1.3333, 1.3333, 1.3333, 1.3333, 1.3333, 1.3333, 1.3333, 1.3333, 1.3333 }; /** * saves cached preview source picture as BMP * * @param1 - automatic saving (demux mode - panel option) * @param2 - if GUI is not visible, don't update */ private void saveBMP(int[] pixels, int horizontal_size, int vertical_size, int aspectratio_index, boolean useAspectRatio) { int[] sourcepixel = null; int source_mb_width = (0xF & horizontal_size) != 0 ? (horizontal_size & ~0xF) + 16 : horizontal_size; if (useAspectRatio) { sourcepixel = getScaledPixel(pixels, horizontal_size, vertical_size, aspectratio_table[aspectratio_index]); if (sourcepixel == null) sourcepixel = pixels; else { horizontal_size = (int) Math.round(aspectratio_table[aspectratio_index] * vertical_size); source_mb_width = horizontal_size; } } else sourcepixel = pixels; int size = horizontal_size * vertical_size; if (size <= 0) return; X_JFileChooser chooser = CommonGui.getMainFileChooser(); if (bmpCount == 0) { //suggest the current collection directory } String newfile = chooser.getCurrentDirectory() + System.getProperty("file.separator") + "X_picture[" + bmpCount + "].bmp"; chooser.setSelectedFile(new File(newfile)); chooser.rescanCurrentDirectory(); chooser.setDialogTitle("save picture"); int retval = chooser.showSaveDialog(this); if(retval == JFileChooser.APPROVE_OPTION) { File theFile = chooser.getSelectedFile(); if (theFile != null && !theFile.isDirectory()) newfile = theFile.getAbsolutePath(); } else return; byte[] bmp24 = new byte[3]; //int source_mb_width = (0xF & horizontal_size) != 0 ? (horizontal_size & ~0xF) + 16 : horizontal_size; int padding = (horizontal_size & 3) != 0 ? (horizontal_size & 3) : 0; size = (horizontal_size * vertical_size * 3) + (padding > 0 ? (padding * vertical_size) : 0); littleEndian(bmpHead, 2, (54 + size)); littleEndian(bmpHead, 18, horizontal_size); littleEndian(bmpHead, 22, vertical_size); littleEndian(bmpHead, 34, size); try { BufferedOutputStream BMPfile = new BufferedOutputStream(new FileOutputStream(newfile), 2048000); BMPfile.write(bmpHead); for (int a = vertical_size - 1; a >= 0; a--) { for (int b = 0, pixel = 0; b < horizontal_size; b++) { pixel = YUVtoRGB(sourcepixel[b + (a * source_mb_width)]); for (int c = 0; c < 3; c++) bmp24[c] = (byte)(pixel >>(c * 8) & 0xFF); BMPfile.write(bmp24); } if (padding > 0) BMPfile.write(new byte[padding]); } BMPfile.flush(); BMPfile.close(); bmpCount++; } catch (Exception e) { Common.setExceptionMessage(e); } } /** * create new cutimage pixel data * jdk122 seems to have a problem when it does multiplication !! */ private int[] getScaledPixel(int[] pixels, int horizontal_size, int vertical_size, double aspectratio) { int source_height = vertical_size; int source_width = horizontal_size; int source_mb_width = (0xF & horizontal_size) != 0 ? (horizontal_size & ~0xF) + 16 : horizontal_size; int new_height = vertical_size; int new_width = ((int) Math.round(vertical_size * aspectratio)); int new_size = new_width * new_height; // oversized or zero ? if (new_size > 0x1000000 || new_size <= 0) return null; float Y = 0; float X = 0; double decimate_height = (double)source_height / new_height; double decimate_width = (double)source_width / new_width; int[] new_image = new int[new_size]; for (int y = 0; Y < source_height && y < new_height; Y += decimate_height, y++, X = 0) for (int x = 0; X < source_width && x < new_width; X += decimate_width, x++) new_image[x + (y * new_width)] = pixels[(int)X + ((int)Y * source_mb_width)]; return new_image; } }project-x/src/net/sourceforge/dvb/projectx/gui/PreSettings.java0000600000175000017500000016141610412354704026337 0ustar supermariosupermario/* * @(#)PreSettings.java * * Copyright (c) 2005-2006 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.KeyEvent; import java.awt.Color; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.JTextField; import javax.swing.UIManager; import javax.swing.SwingConstants; import javax.swing.JMenuBar; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.KeyStroke; import net.sourceforge.dvb.projectx.gui.UISwitchListener; import net.sourceforge.dvb.projectx.gui.CommonGui; import net.sourceforge.dvb.projectx.gui.ColumnLayout; import net.sourceforge.dvb.projectx.gui.ComboBoxIndexListener; import net.sourceforge.dvb.projectx.gui.ComboBoxItemListener; import net.sourceforge.dvb.projectx.gui.CheckBoxListener; import net.sourceforge.dvb.projectx.gui.TextFieldListener; import net.sourceforge.dvb.projectx.gui.TextFieldKeyListener; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; /** * */ public class PreSettings extends JFrame { private String title = Resource.getString("PreferencesPanel.Title"); private final Color head_color = new Color(224, 224, 224); private ComboBoxIndexListener _ComboBoxIndexListener = new ComboBoxIndexListener(); private ComboBoxItemListener _ComboBoxItemListener = new ComboBoxItemListener(); private CheckBoxListener _CheckBoxListener = new CheckBoxListener(); private TextFieldListener _TextFieldListener = new TextFieldListener(); private TextFieldKeyListener _TextFieldKeyListener = new TextFieldKeyListener(); /** * Constructor */ public PreSettings() { addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { close(); } }); JPanel container = new JPanel(); container.setLayout(new BorderLayout()); buildMenu(); container.add(buildTabPanel()); getContentPane().add(container); setTitle(title); setBounds(200, 100, 720, 400); setResizable(false); UIManager.addPropertyChangeListener(new UISwitchListener(getRootPane())); } /** * */ public void close() { dispose(); } /** * */ public void savePreferences() { String str = CommonGui.getUserInput(this, "save ini", "save inifile", Common.getSettings().getInifile()); if (str != null && str.length() > 0) Common.saveSettings(str); toFront(); } /** * */ protected void buildMenu() { JMenuBar menuBar = new JMenuBar(); menuBar.add(buildFileMenu()); setJMenuBar(menuBar); } /** * */ protected JMenu buildFileMenu() { JMenu fileMenu = new JMenu(); CommonGui.localize(fileMenu, "Common.File"); JMenuItem save = new JMenuItem(); CommonGui.localize(save, "Common.SaveAs"); save.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { savePreferences(); } }); fileMenu.add(save); fileMenu.addSeparator(); JMenuItem close = new JMenuItem(); CommonGui.localize(close, "Common.Close"); close.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.ALT_MASK)); close.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { close(); } }); fileMenu.add(close); return fileMenu; } /** * */ protected JPanel buildTabPanel() { JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); panel.setBorder(BorderFactory.createEmptyBorder(5, 2, 2, 2)); JTabbedPane logtab = new JTabbedPane(SwingConstants.LEFT); // logtab.addTab( "", buildMainPanel()); logtab.addTab( Resource.getString("TabPanel.OptionPanel"), buildOptionPanel()); logtab.addTab( Resource.getString("TabPanel.ExportPanel"), buildExportPanel()); logtab.addTab( Resource.getString("TabPanel.SpecialPanel"), buildSpecialPanel()); logtab.addTab( Resource.getString("TabPanel.VideoPanel"), buildVideoPanel()); logtab.addTab( Resource.getString("TabPanel.AudioPanel"), buildAudioPanel()); logtab.addTab( Resource.getString("TabPanel.SubtitlePanel"), buildSubtitlePanel()); logtab.addTab( Resource.getString("TabPanel.ExternPanel"), buildExternPanel()); logtab.addTab( Resource.getString("TabPanel.NetPanel"), buildNetPanel()); logtab.addTab( Resource.getString("TabPanel.PostCommandsPanel"), buildPostCommandsPanel()); logtab.setSelectedIndex(0); panel.add(logtab, BorderLayout.CENTER); return panel; } /** * */ protected JPanel buildHeadPanel(JPanel panel, String str) { JPanel panel_1 = new JPanel(new BorderLayout()); panel_1.setBackground(head_color); panel_1.setBorder(BorderFactory.createTitledBorder("")); panel_1.add(new JLabel(" " + str)); JPanel panel_2 = new JPanel(new BorderLayout()); panel_2.add(panel, BorderLayout.CENTER); panel_2.add(panel_1, BorderLayout.NORTH); return panel_2; } /** * */ protected JPanel buildMainPanel() { JPanel panel = new JPanel(); panel.setLayout( new BorderLayout() ); panel.setBorder( BorderFactory.createTitledBorder("") ); return panel; } /** * */ protected JPanel buildSpecialPanel() { JPanel idbigPanel = new JPanel(); idbigPanel.setLayout( new GridLayout(1,2) ); JPanel idPanel3 = new JPanel(); idPanel3.setLayout ( new ColumnLayout() ); idPanel3.setBorder( BorderFactory.createTitledBorder(Resource.getString("SpecialPanel.Title1")) ); String[][] objects = { Keys.KEY_PVA_FileOverlap, Keys.KEY_PVA_Audio, Keys.KEY_VOB_resetPts, Keys.KEY_TS_ignoreScrambled, Keys.KEY_TS_blindSearch, Keys.KEY_TS_joinPackets, Keys.KEY_TS_HumaxAdaption, Keys.KEY_TS_FinepassAdaption, Keys.KEY_TS_generatePmt, Keys.KEY_TS_generateTtx, Keys.KEY_TS_setMainAudioAc3 }; for (int i = 0; i < objects.length; i++) { JCheckBox box = new JCheckBox(Resource.getString(objects[i][0])); box.setToolTipText(Resource.getString(objects[i][0] + Keys.KEY_Tip)); box.setPreferredSize(new Dimension(270, 20)); box.setMaximumSize(new Dimension(270, 20)); box.setActionCommand(objects[i][0]); box.setSelected(Common.getSettings().getBooleanProperty(objects[i])); box.addActionListener(_CheckBoxListener); if (i == 2 || i == 3) idPanel3.add(Box.createRigidArea(new Dimension(1, 10))); idPanel3.add(box); } JComboBox tsheader_mode = new JComboBox(Keys.ITEMS_TsHeaderMode); tsheader_mode.setPreferredSize(new Dimension(270, 20)); tsheader_mode.setMaximumSize(new Dimension(270, 20)); tsheader_mode.setActionCommand(Keys.KEY_TsHeaderMode[0]); tsheader_mode.setSelectedIndex(Common.getSettings().getIntProperty(Keys.KEY_TsHeaderMode)); tsheader_mode.addActionListener(_ComboBoxIndexListener); idPanel3.add(tsheader_mode); idbigPanel.add(idPanel3); // next grid JPanel idPanel2 = new JPanel(); idPanel2.setLayout ( new ColumnLayout() ); idPanel2.setBorder( BorderFactory.createTitledBorder(Resource.getString("SpecialPanel.Title2")) ); JLabel gpts = new JLabel(Resource.getString("SpecialPanel.PtsShift") + " "); gpts.setToolTipText(Resource.getString("SpecialPanel.PtsShift.Tip")); JComboBox pts_shift = new JComboBox(Keys.ITEMS_PtsShift); pts_shift.setPreferredSize(new Dimension(60, 20)); pts_shift.setMaximumSize(new Dimension(60, 20)); pts_shift.setEditable(true); pts_shift.setActionCommand(Keys.KEY_PtsShift_Value[0]); pts_shift.setSelectedItem(Common.getSettings().getProperty(Keys.KEY_PtsShift_Value)); pts_shift.addActionListener(_ComboBoxItemListener); JPanel spec5 = new JPanel(); spec5.setLayout(new BoxLayout(spec5, BoxLayout.X_AXIS)); spec5.add(gpts); spec5.add(pts_shift); idPanel2.add(spec5); String[][] objects_2 = { Keys.KEY_Input_getEnclosedPackets, Keys.KEY_Input_concatenateForeignRecords, Keys.KEY_Audio_ignoreErrors, Keys.KEY_Audio_limitPts, Keys.KEY_Video_ignoreErrors, Keys.KEY_Video_trimPts }; for (int i = 0; i < objects_2.length; i++) { JCheckBox box = new JCheckBox(Resource.getString(objects_2[i][0])); box.setToolTipText(Resource.getString(objects_2[i][0] + Keys.KEY_Tip)); box.setPreferredSize(new Dimension(270, 20)); box.setMaximumSize(new Dimension(270, 20)); box.setActionCommand(objects_2[i][0]); box.setSelected(Common.getSettings().getBooleanProperty(objects_2[i])); box.addActionListener(_CheckBoxListener); if (i == 2 || i == 4) idPanel2.add(Box.createRigidArea(new Dimension(1, 10))); idPanel2.add(box); } idPanel2.add(Box.createRigidArea(new Dimension(1, 10))); idPanel2.add(new JLabel(Resource.getString("SpecialPanel.Conversion"))); String[][] objects_3 = { Keys.KEY_Conversion_startWithVideo }; JCheckBox box_1 = new JCheckBox(Resource.getString(objects_3[0][0])); box_1.setToolTipText(Resource.getString(objects_3[0][0] + Keys.KEY_Tip)); box_1.setPreferredSize(new Dimension(270, 20)); box_1.setMaximumSize(new Dimension(270, 20)); box_1.setActionCommand(objects_3[0][0]); box_1.setSelected(Common.getSettings().getBooleanProperty(objects_3[0])); box_1.addActionListener(_CheckBoxListener); idPanel2.add(box_1); String[][] objects_4 = { Keys.KEY_Conversion_addPcrToStream }; JCheckBox box_2 = new JCheckBox(Resource.getString(objects_4[0][0])); box_2.setToolTipText(Resource.getString(objects_4[0][0] + Keys.KEY_Tip)); box_2.setPreferredSize(new Dimension(192, 20)); box_2.setMaximumSize(new Dimension(192, 20)); box_2.setActionCommand(objects_4[0][0]); box_2.setSelected(Common.getSettings().getBooleanProperty(objects_4[0])); box_2.addActionListener(_CheckBoxListener); String[][] objects_5 = { Keys.KEY_Conversion_PcrCounter }; JCheckBox box_3 = new JCheckBox(Resource.getString(objects_5[0][0])); box_3.setToolTipText(Resource.getString(objects_5[0][0] + Keys.KEY_Tip)); box_3.setPreferredSize(new Dimension(80, 20)); box_3.setMaximumSize(new Dimension(80, 20)); box_3.setActionCommand(objects_5[0][0]); box_3.setSelected(Common.getSettings().getBooleanProperty(objects_5[0])); box_3.addActionListener(_CheckBoxListener); JPanel spec3 = new JPanel(); spec3.setLayout(new BoxLayout(spec3, BoxLayout.X_AXIS)); spec3.add(box_2); spec3.add(box_3); idPanel2.add(spec3); JComboBox pcr_delta = new JComboBox(Keys.ITEMS_PcrDelta); pcr_delta.setPreferredSize(new Dimension(60, 20)); pcr_delta.setMaximumSize(new Dimension(60, 20)); pcr_delta.setEditable(true); pcr_delta.setActionCommand(Keys.KEY_PcrDelta_Value[0]); pcr_delta.setSelectedItem(Common.getSettings().getProperty(Keys.KEY_PcrDelta_Value)); pcr_delta.addActionListener(_ComboBoxItemListener); idPanel2.add(pcr_delta); idbigPanel.add(idPanel2); return buildHeadPanel(idbigPanel, Resource.getString("TabPanel.SpecialPanel")); } /** * */ protected JPanel buildExportPanel() { JPanel exportPanel = new JPanel(); exportPanel.setLayout( new GridLayout(2, 2) ); JPanel op1 = new JPanel(); op1.setLayout( new ColumnLayout() ); op1.setBorder( BorderFactory.createTitledBorder(Resource.getString("ExportPanel.SplitPanel")) ); String[][] objects = { Keys.KEY_SplitSize, Keys.KEY_Streamtype_MpgVideo, Keys.KEY_Streamtype_MpgAudio, Keys.KEY_Streamtype_Ac3Audio, Keys.KEY_Streamtype_PcmAudio, Keys.KEY_Streamtype_Teletext, Keys.KEY_Streamtype_Subpicture, Keys.KEY_Streamtype_Vbi, Keys.KEY_WriteOptions_writeVideo, Keys.KEY_WriteOptions_writeAudio, Keys.KEY_additionalOffset, Keys.KEY_ExportPanel_Export_Overlap }; JCheckBox[] box = new JCheckBox[objects.length]; for (int i = 0; i < objects.length; i++) { box[i] = new JCheckBox(Resource.getString(objects[i][0])); box[i].setToolTipText(Resource.getString(objects[i][0] + Keys.KEY_Tip)); box[i].setActionCommand(objects[i][0]); box[i].setSelected(Common.getSettings().getBooleanProperty(objects[i])); box[i].addActionListener(_CheckBoxListener); } JComboBox split_sizes = new JComboBox(Keys.ITEMS_Export_SplitSize); split_sizes.setPreferredSize(new Dimension(100, 22)); split_sizes.setMaximumSize(new Dimension(100, 22)); split_sizes.setEditable(true); split_sizes.setActionCommand(Keys.KEY_ExportPanel_SplitSize_Value[0]); split_sizes.setSelectedItem(Common.getSettings().getProperty(Keys.KEY_ExportPanel_SplitSize_Value)); split_sizes.addActionListener(_ComboBoxItemListener); JPanel sp1 = new JPanel(); sp1.setLayout(new BoxLayout(sp1, BoxLayout.X_AXIS)); sp1.add(box[0]); sp1.add(split_sizes); op1.add(sp1); JComboBox overlap = new JComboBox(Keys.ITEMS_Export_Overlap); overlap.setPreferredSize(new Dimension(100, 22)); overlap.setMaximumSize(new Dimension(100, 22)); overlap.setActionCommand(Keys.KEY_ExportPanel_Overlap_Value[0]); overlap.setSelectedIndex(Common.getSettings().getIntProperty(Keys.KEY_ExportPanel_Overlap_Value)); overlap.addActionListener(_ComboBoxIndexListener); JPanel sp2 = new JPanel(); sp2.setLayout(new BoxLayout(sp2, BoxLayout.X_AXIS)); sp2.add(box[11]); sp2.add(overlap); op1.add(sp2); op1.add(Box.createRigidArea(new Dimension(1, 10))); JPanel op6 = new JPanel(); op6.setLayout(new BoxLayout(op6, BoxLayout.X_AXIS)); op6.add(new JLabel(Resource.getString("ExportPanel.WriteOptions.InfoScan"))); JComboBox infoscan = new JComboBox(Keys.ITEMS_Infoscan); infoscan.setPreferredSize(new Dimension(60, 22)); infoscan.setMaximumSize(new Dimension(60, 22)); infoscan.setEditable(true); infoscan.setActionCommand(Keys.KEY_ExportPanel_Infoscan_Value[0]); infoscan.setSelectedItem(Common.getSettings().getProperty(Keys.KEY_ExportPanel_Infoscan_Value)); infoscan.addActionListener(_ComboBoxItemListener); op6.add(infoscan); op1.add(op6); exportPanel.add(op1); JPanel idPanel = new JPanel(); idPanel.setBorder(BorderFactory.createTitledBorder(Resource.getString("ExportPanel.StreamtypePanel"))); idPanel.setLayout(new BoxLayout(idPanel, BoxLayout.X_AXIS)); idPanel.setToolTipText(Resource.getString("ExportPanel.StreamtypePanel.Tip")); JPanel panel_1 = new JPanel(); panel_1.setLayout ( new ColumnLayout() ); for (int i = 1; i < 5; i++) panel_1.add(box[i]); JPanel panel_2 = new JPanel(); panel_2.setLayout ( new ColumnLayout() ); for (int i = 5; i < 8; i++) panel_2.add(box[i]); idPanel.add(panel_1); idPanel.add(panel_2); exportPanel.add(idPanel); JPanel op4 = new JPanel(); op4.setLayout( new ColumnLayout() ); op4.setBorder( BorderFactory.createTitledBorder(Resource.getString("ExportPanel.WriteOptions")) ); op4.setToolTipText(Resource.getString("ExportPanel.WriteOptions.Tip")); op4.add(box[8]); op4.add(box[9]); exportPanel.add(op4); JPanel op5 = new JPanel(); op5.setLayout( new ColumnLayout() ); op5.setBorder( BorderFactory.createTitledBorder(Resource.getString("ExportPanel.additionalOffset.Title")) ); JPanel op7 = new JPanel(); op7.setLayout(new BoxLayout(op7, BoxLayout.X_AXIS)); op7.add(box[10]); JTextField offset_value = new JTextField(Common.getSettings().getProperty(Keys.KEY_ExportPanel_additionalOffset_Value)); offset_value.setPreferredSize(new Dimension(80, 22)); offset_value.setMaximumSize(new Dimension(80, 22)); offset_value.setToolTipText(Resource.getString(Keys.KEY_ExportPanel_additionalOffset_Value[0] + Keys.KEY_Tip)); offset_value.setEditable(true); offset_value.setActionCommand(Keys.KEY_ExportPanel_additionalOffset_Value[0]); offset_value.addActionListener(_TextFieldListener); offset_value.addKeyListener(_TextFieldKeyListener); op7.add(offset_value); op5.add(op7); exportPanel.add(op5); return buildHeadPanel(exportPanel, Resource.getString("TabPanel.ExportPanel")); } /** * */ protected JPanel buildVideoPanel() { JPanel video1 = new JPanel(); video1.setLayout( new GridLayout(1, 2) ); JPanel video2Panel = new JPanel(); video2Panel.setLayout( new ColumnLayout() ); video2Panel.setBorder( BorderFactory.createTitledBorder(Resource.getString("VideoPanel.Title1")) ); String[][] objects = { Keys.KEY_VideoPanel_addEndcode, Keys.KEY_VideoPanel_insertEndcode, Keys.KEY_VideoPanel_addSequenceHeader, Keys.KEY_VideoPanel_clearCDF, Keys.KEY_VideoPanel_patchToProgressive, Keys.KEY_VideoPanel_patchToInterlaced, Keys.KEY_VideoPanel_toggleFieldorder, Keys.KEY_VideoPanel_addSde }; final JCheckBox[] box = new JCheckBox[objects.length]; for (int i = 0; i < objects.length; i++) { box[i] = new JCheckBox(Resource.getString(objects[i][0])); box[i].setPreferredSize(new Dimension(270, 20)); box[i].setMaximumSize(new Dimension(270, 20)); box[i].setToolTipText(Resource.getString(objects[i][0] + Keys.KEY_Tip)); box[i].setActionCommand(objects[i][0]); box[i].setSelected(Common.getSettings().getBooleanProperty(objects[i])); box[i].addActionListener(_CheckBoxListener); } ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e) { JCheckBox checkBox = (JCheckBox)e.getSource(); String str = checkBox.getActionCommand(); if (str.equals(Keys.KEY_VideoPanel_patchToProgressive[0]) && checkBox.isSelected()) { box[5].setSelected(false); Common.getSettings().setBooleanProperty(Keys.KEY_VideoPanel_patchToInterlaced[0], false); return; } else if (str.equals(Keys.KEY_VideoPanel_patchToInterlaced[0]) && checkBox.isSelected()) { box[4].setSelected(false); Common.getSettings().setBooleanProperty(Keys.KEY_VideoPanel_patchToProgressive[0], false); return; } } }; box[4].addActionListener(al); box[5].addActionListener(al); for (int i = 0; i < 7; i++) video2Panel.add(box[i]); JPanel SdePanel = new JPanel(); SdePanel.setLayout(new BoxLayout(SdePanel, BoxLayout.X_AXIS)); box[7].setPreferredSize(new Dimension(180, 20)); box[7].setMaximumSize(new Dimension(180, 20)); SdePanel.add(box[7]); JTextField sde_value = new JTextField(Common.getSettings().getProperty(Keys.KEY_VideoPanel_SdeValue)); sde_value.setPreferredSize(new Dimension(80, 20)); sde_value.setMaximumSize(new Dimension(80, 20)); sde_value.setToolTipText(Resource.getString(Keys.KEY_VideoPanel_SdeValue[0] + Keys.KEY_Tip)); sde_value.setEditable(true); sde_value.setActionCommand(Keys.KEY_VideoPanel_SdeValue[0]); sde_value.addActionListener(_TextFieldListener); sde_value.addKeyListener(_TextFieldKeyListener); SdePanel.add(sde_value); video2Panel.add(SdePanel); video2Panel.add(new JLabel (Resource.getString("VideoPanel.patchResolution"))); JPanel hPPanel = new JPanel(); hPPanel.setLayout(new BoxLayout(hPPanel, BoxLayout.X_AXIS)); hPPanel.setToolTipText(Resource.getString("VideoPanel.patchResolution.Tip")); JComboBox combobox_35 = new JComboBox(Keys.ITEMS_ConditionalHorizontalPatch); combobox_35.setPreferredSize(new Dimension(160, 20)); combobox_35.setMaximumSize(new Dimension(160, 20)); combobox_35.setActionCommand(Keys.KEY_ConditionalHorizontalPatch[0]); combobox_35.setSelectedIndex(Common.getSettings().getIntProperty(Keys.KEY_ConditionalHorizontalPatch)); combobox_35.addActionListener(_ComboBoxIndexListener); hPPanel.add(combobox_35); JComboBox combobox_22 = new JComboBox(Keys.ITEMS_ExportHorizontalResolution); combobox_22.setPreferredSize(new Dimension(50, 20)); combobox_22.setMaximumSize(new Dimension(50, 20)); combobox_22.setActionCommand(Keys.KEY_ConditionalHorizontalResolution[0]); combobox_22.setSelectedItem(Common.getSettings().getProperty(Keys.KEY_ConditionalHorizontalResolution)); combobox_22.addActionListener(_ComboBoxItemListener); hPPanel.add(combobox_22); video2Panel.add(hPPanel); video2Panel.add(Box.createRigidArea(new Dimension(1, 10))); JPanel video2 = new JPanel(); video2.setLayout(new ColumnLayout()); video2.setBorder( BorderFactory.createTitledBorder(Resource.getString("VideoPanel.Title1")) ); String[] labels = { Resource.getString("VideoPanel.ChangeVbvBuffer"), Resource.getString("VideoPanel.ChangeVbvDelay"), Resource.getString("VideoPanel.ChangeAspectRatio") }; Object[][] items = { Keys.ITEMS_ChangeVbvBuffer, Keys.ITEMS_ChangeVbvDelay, Keys.ITEMS_ChangeAspectRatio, }; String[][] keys = { Keys.KEY_ChangeVbvBuffer, Keys.KEY_ChangeVbvDelay, Keys.KEY_ChangeAspectRatio }; for (int i = 0; i < keys.length; i++) { JLabel label = new JLabel(labels[i]); label.setPreferredSize(new Dimension(120, 20)); label.setMaximumSize(new Dimension(120, 20)); JComboBox combobox = new JComboBox(items[i]); combobox.setPreferredSize(new Dimension(150, 20)); combobox.setMaximumSize(new Dimension(150, 20)); combobox.setActionCommand(keys[i][0]); combobox.setSelectedIndex(Common.getSettings().getIntProperty(keys[i])); combobox.addActionListener(_ComboBoxIndexListener); JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); panel.setToolTipText(labels[i] + Keys.KEY_Tip); panel.add(label); panel.add(combobox); video2Panel.add(panel); } video1.add(video2Panel); JPanel video3 = new JPanel(); video3.setLayout( new GridLayout(2, 1) ); JPanel newBrPanel = new JPanel(); newBrPanel.setLayout(new ColumnLayout()); newBrPanel.setBorder( BorderFactory.createTitledBorder(Resource.getString("VideoPanel.Title2")) ); String[] labels_2 = { Resource.getString("VideoPanel.patchBitrateValue"), Resource.getString("VideoPanel.patch1stBitrateValue") }; Object[][] items_2 = { Keys.ITEMS_BitrateInAllSequences, Keys.ITEMS_BitrateInFirstSequence }; String[][] keys_2 = { Keys.KEY_ChangeBitrateInAllSequences, Keys.KEY_ChangeBitrateInFirstSequence }; for (int i = 0; i < keys_2.length; i++) { JLabel label = new JLabel(labels_2[i]); label.setPreferredSize(new Dimension(270, 20)); label.setMaximumSize(new Dimension(270, 20)); label.setToolTipText(labels_2[i] + Keys.KEY_Tip); JComboBox combobox = new JComboBox(items_2[i]); combobox.setPreferredSize(new Dimension(270, 20)); combobox.setMaximumSize(new Dimension(270, 20)); combobox.setActionCommand(keys_2[i][0]); combobox.setSelectedIndex(Common.getSettings().getIntProperty(keys_2[i])); combobox.addActionListener(_ComboBoxIndexListener); newBrPanel.add(label); newBrPanel.add(combobox); } video3.add(newBrPanel); video1.add(video3); return buildHeadPanel(video1, Resource.getString("TabPanel.VideoPanel")); } /** * */ protected JPanel buildExternPanel() { JPanel video2 = new JPanel(); video2.setLayout( new GridLayout(1, 2) ); JPanel video2Panel = new JPanel(); video2Panel.setLayout( new ColumnLayout() ); video2Panel.setBorder( BorderFactory.createTitledBorder(Resource.getString("ExternPanel.Title1")) ); video2Panel.setToolTipText(Resource.getString("ExternPanel.Title1.Tip")); // Keys.KEY_ExternPanel_save1stFrameOfGop, String[][] objects = { Keys.KEY_ExternPanel_createVdrIndex, Keys.KEY_ExternPanel_createCellTimes, Keys.KEY_ExternPanel_exportPts, Keys.KEY_ExternPanel_createChapters, Keys.KEY_ExternPanel_renameAudio, Keys.KEY_ExternPanel_renameVideo, Keys.KEY_ExternPanel_appendExtension, Keys.KEY_ExternPanel_createM2sIndex, Keys.KEY_ExternPanel_createInfoIndex, Keys.KEY_ExternPanel_createD2vIndex, Keys.KEY_ExternPanel_createDgiIndex, Keys.KEY_ExternPanel_splitProjectFile }; JCheckBox[] box = new JCheckBox[objects.length]; for (int i = 0; i < objects.length; i++) { box[i] = new JCheckBox(Resource.getString(objects[i][0])); box[i].setPreferredSize(new Dimension(270, 20)); box[i].setMaximumSize(new Dimension(270, 20)); box[i].setToolTipText(Resource.getString(objects[i][0] + Keys.KEY_Tip)); box[i].setActionCommand(objects[i][0]); box[i].setSelected(Common.getSettings().getBooleanProperty(objects[i])); box[i].addActionListener(_CheckBoxListener); if (i == 10) box[i].setEnabled(false); } // left grid for (int i = 0; i < 7; i++) video2Panel.add(box[i]); video2.add(video2Panel); // next grid JPanel video3Panel = new JPanel(); video3Panel.setLayout( new ColumnLayout() ); video3Panel.setBorder( BorderFactory.createTitledBorder(Resource.getString("ExternPanel.Title2")) ); video3Panel.setToolTipText(Resource.getString("ExternPanel.Title2.Tip")); video3Panel.add(new JLabel(Resource.getString("ExternPanel.createM2sIndex"))); // right grid video3Panel.add(box[7]); video3Panel.add(Box.createRigidArea(new Dimension(1, 10))); video3Panel.add(new JLabel(Resource.getString("ExternPanel.createInfoLabel"))); video3Panel.add(box[8]); video3Panel.add(Box.createRigidArea(new Dimension(1, 10))); video3Panel.add(new JLabel(Resource.getString("ExternPanel.createD2vIndex"))); // right grid for (int i = 9; i < objects.length; i++) video3Panel.add(box[i]); JTextField d2v_splitsize = new JTextField(Common.getSettings().getProperty(Keys.KEY_ExternPanel_ProjectFileSplitSize)); d2v_splitsize.setPreferredSize(new Dimension(70, 20)); d2v_splitsize.setToolTipText(Resource.getString(Keys.KEY_ExternPanel_ProjectFileSplitSize[0] + Keys.KEY_Tip)); d2v_splitsize.setEditable(true); d2v_splitsize.setActionCommand(Keys.KEY_ExternPanel_ProjectFileSplitSize[0]); d2v_splitsize.addActionListener(_TextFieldListener); d2v_splitsize.addKeyListener(_TextFieldKeyListener); JPanel d2vPanel = new JPanel(); JLabel d2vLabel = new JLabel (Resource.getString("ExternPanel.ProjectFileSplitSize")); d2vPanel.add(d2vLabel); d2vPanel.add(d2v_splitsize); video3Panel.add(d2vPanel); video2.add(video3Panel); return buildHeadPanel(video2, Resource.getString("TabPanel.ExternPanel")); } /** * */ protected JPanel buildAudioPanel() { JPanel audio = new JPanel(); audio.setLayout( new GridLayout(1,2) ); JPanel audio0 = new JPanel(); audio0.setLayout( new ColumnLayout() ); audio0.setBorder( BorderFactory.createTitledBorder(Resource.getString("AudioPanel.Title1")) ); audio0.add(new JLabel(Resource.getString("AudioPanel.loslessMpaConversion.Tip1"))); audio0.add(new JLabel(Resource.getString("AudioPanel.loslessMpaConversion.Tip2"))); audio0.setToolTipText(Resource.getString("AudioPanel.loslessMpaConversion.Tip")); JComboBox conversion_selection = new JComboBox(Keys.ITEMS_loslessMpaConversionMode); conversion_selection.setPreferredSize(new Dimension(270, 20)); conversion_selection.setMaximumSize(new Dimension(270, 20)); conversion_selection.setActionCommand(Keys.KEY_AudioPanel_loslessMpaConversionMode[0]); conversion_selection.setSelectedIndex(Common.getSettings().getIntProperty(Keys.KEY_AudioPanel_loslessMpaConversionMode)); conversion_selection.addActionListener(_ComboBoxIndexListener); audio0.add(conversion_selection); //audio0.add(new JLabel(" ")); audio0.add(Box.createRigidArea(new Dimension(1, 20))); String[][] objects = { Keys.KEY_AudioPanel_decodeMpgAudio, Keys.KEY_AudioPanel_Normalize, Keys.KEY_AudioPanel_Downmix, Keys.KEY_AudioPanel_fadeInOut, Keys.KEY_AudioPanel_changeByteorder, Keys.KEY_AudioPanel_addRiffHeader, Keys.KEY_AudioPanel_addAiffHeader, Keys.KEY_AudioPanel_validateCRC, Keys.KEY_AudioPanel_clearCRC, Keys.KEY_AudioPanel_fillGapsWithLastFrame, Keys.KEY_AudioPanel_addFrames, Keys.KEY_AudioPanel_patch1stAc3Header, Keys.KEY_AudioPanel_replaceAc3withSilence, Keys.KEY_AudioPanel_allowSpaces, Keys.KEY_AudioPanel_addRiffToMpgAudio, Keys.KEY_AudioPanel_addRiffToMpgAudioL3, Keys.KEY_AudioPanel_addRiffToAc3, Keys.KEY_AudioPanel_createDDWave }; final JCheckBox[] box = new JCheckBox[objects.length]; for (int i = 0; i < objects.length; i++) { box[i] = new JCheckBox(Resource.getString(objects[i][0])); box[i].setPreferredSize(new Dimension(270, 20)); box[i].setMaximumSize(new Dimension(270, 20)); box[i].setToolTipText(Resource.getString(objects[i][0] + Keys.KEY_Tip)); box[i].setActionCommand(objects[i][0]); box[i].setSelected(Common.getSettings().getBooleanProperty(objects[i])); box[i].addActionListener(_CheckBoxListener); } audio0.add(box[0]); JComboBox resample_selection = new JComboBox(Keys.ITEMS_resampleAudioMode); resample_selection.setPreferredSize(new Dimension(270, 20)); resample_selection.setMaximumSize(new Dimension(270, 20)); resample_selection.setActionCommand(Keys.KEY_AudioPanel_resampleAudioMode[0]); resample_selection.setSelectedIndex(Common.getSettings().getIntProperty(Keys.KEY_AudioPanel_resampleAudioMode)); resample_selection.addActionListener(_ComboBoxIndexListener); audio0.add(resample_selection); final JTextField normalize_value = new JTextField(Common.getSettings().getProperty(Keys.KEY_AudioPanel_NormalizeValue)); normalize_value.setPreferredSize(new Dimension(50, 20)); normalize_value.setMaximumSize(new Dimension(50, 20)); normalize_value.setToolTipText(Resource.getString(Keys.KEY_AudioPanel_NormalizeValue[0] + Keys.KEY_Tip)); normalize_value.setEditable(true); normalize_value.setActionCommand(Keys.KEY_AudioPanel_NormalizeValue[0]); normalize_value.addActionListener(_TextFieldListener); normalize_value.addKeyListener(_TextFieldKeyListener); normalize_value.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String str = normalize_value.getText(); if (str.length() == 0) { normalize_value.setText("98"); return; } try { int val = Integer.parseInt(str); if (val > 100 || val < 0) val = 98; normalize_value.setText("" + val); } catch (Exception pe) { normalize_value.setText("98"); } } }); box[1].setPreferredSize(new Dimension(180, 20)); box[1].setMaximumSize(new Dimension(180, 20)); JPanel audio5 = new JPanel(); audio5.setLayout(new BoxLayout(audio5, BoxLayout.X_AXIS)); audio5.add(box[1]); audio5.add(normalize_value); audio0.add(audio5); for (int i = 2; i < 7; i++) audio0.add(box[i]); ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e) { JCheckBox checkBox = (JCheckBox)e.getSource(); String str = checkBox.getActionCommand(); if (str.equals(Keys.KEY_AudioPanel_changeByteorder[0]) && Common.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_addAiffHeader)) { box[4].setSelected(true); Common.getSettings().setBooleanProperty(Keys.KEY_AudioPanel_changeByteorder[0], true); return; } else if (str.equals(Keys.KEY_AudioPanel_addRiffHeader[0]) && checkBox.isSelected()) { box[6].setSelected(false); Common.getSettings().setBooleanProperty(Keys.KEY_AudioPanel_addAiffHeader[0], false); return; } else if (str.equals(Keys.KEY_AudioPanel_addAiffHeader[0]) && checkBox.isSelected()) { box[4].setSelected(true); box[5].setSelected(false); Common.getSettings().setBooleanProperty(Keys.KEY_AudioPanel_changeByteorder[0], true); Common.getSettings().setBooleanProperty(Keys.KEY_AudioPanel_addRiffHeader[0], false); return; } } }; box[4].addActionListener(al); box[5].addActionListener(al); box[6].addActionListener(al); JPanel audio1 = new JPanel(); audio1.setLayout( new ColumnLayout() ); audio1.setBorder( BorderFactory.createTitledBorder(Resource.getString("AudioPanel.Title2")) ); for (int i = 7; i < objects.length; i++) { if (i == 14 || i == 17) audio1.add(Box.createRigidArea(new Dimension(1, 10))); audio1.add(box[i]); } ActionListener al_2 = new ActionListener() { public void actionPerformed(ActionEvent e) { JCheckBox checkBox = (JCheckBox)e.getSource(); String str = checkBox.getActionCommand(); if (str.equals(Keys.KEY_AudioPanel_addRiffToMpgAudioL3[0]) && checkBox.isSelected()) { box[15].setSelected(false); Common.getSettings().setBooleanProperty(Keys.KEY_AudioPanel_addRiffToMpgAudio[0], false); return; } else if (str.equals(Keys.KEY_AudioPanel_addRiffToMpgAudio[0]) && checkBox.isSelected()) { box[16].setSelected(false); Common.getSettings().setBooleanProperty(Keys.KEY_AudioPanel_addRiffToMpgAudioL3[0], false); return; } } }; box[15].addActionListener(al_2); box[16].addActionListener(al_2); audio.add(audio0); audio.add(audio1); return buildHeadPanel(audio, Resource.getString("TabPanel.AudioPanel")); } /** * */ protected JPanel buildSubtitlePanel() { JPanel teletext = new JPanel(); teletext.setLayout( new GridLayout( 1, 2) ); JPanel panel_0 = new JPanel(); panel_0.setLayout( new ColumnLayout() ); panel_0.setBorder( BorderFactory.createTitledBorder(Resource.getString("SubtitlePanel.Title.Teletext")) ); String[][] objects = { Keys.KEY_SubtitlePanel_decodeMegaradio, Keys.KEY_SubtitlePanel_decodeHiddenRows, Keys.KEY_SubtitlePanel_rebuildPTS, Keys.KEY_SubtitlePanel_keepOriginalTimecode, Keys.KEY_SubtitlePanel_exportTextAsUnicode, Keys.KEY_SubtitlePanel_exportTextAsUTF8, Keys.KEY_SubtitlePanel_useTextOutline, Keys.KEY_SubtitlePanel_specialTermination }; final JCheckBox[] box = new JCheckBox[objects.length]; for (int i = 0; i < objects.length; i++) { box[i] = new JCheckBox(Resource.getString(objects[i][0])); box[i].setPreferredSize(new Dimension(260, 20)); box[i].setMaximumSize(new Dimension(260, 20)); box[i].setToolTipText(Resource.getString(objects[i][0] + Keys.KEY_Tip)); box[i].setActionCommand(objects[i][0]); box[i].setSelected(Common.getSettings().getBooleanProperty(objects[i])); box[i].addActionListener(_CheckBoxListener); } panel_0.add(box[0]); panel_0.add(box[1]); panel_0.add(box[2]); panel_0.add(box[3]); panel_0.add(box[4]); panel_0.add(box[5]); //toggle action ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e) { JCheckBox checkBox = (JCheckBox)e.getSource(); String str = checkBox.getActionCommand(); if (str.equals(Keys.KEY_SubtitlePanel_exportTextAsUnicode[0]) && checkBox.isSelected()) { box[5].setSelected(false); Common.getSettings().setBooleanProperty(Keys.KEY_SubtitlePanel_exportTextAsUTF8[0], false); return; } else if (str.equals(Keys.KEY_SubtitlePanel_exportTextAsUTF8[0]) && checkBox.isSelected()) { box[4].setSelected(false); Common.getSettings().setBooleanProperty(Keys.KEY_SubtitlePanel_exportTextAsUnicode[0], false); return; } } }; box[4].addActionListener(al); box[5].addActionListener(al); panel_0.add(Box.createRigidArea(new Dimension(1, 10))); JLabel page_decode = new JLabel(Resource.getString("SubtitlePanel.TtxPages")); page_decode.setToolTipText(Resource.getString("SubtitlePanel.TtxPages.Tip")); panel_0.add(page_decode); JPanel panel_0_1 = new JPanel(); panel_0_1.setLayout(new BoxLayout(panel_0_1, BoxLayout.X_AXIS)); JPanel panel_0_2 = new JPanel(); panel_0_2.setLayout(new BoxLayout(panel_0_2, BoxLayout.X_AXIS)); String[][] keys = { Keys.KEY_SubtitlePanel_TtxPage1, Keys.KEY_SubtitlePanel_TtxPage2, Keys.KEY_SubtitlePanel_TtxPage3, Keys.KEY_SubtitlePanel_TtxPage4, Keys.KEY_SubtitlePanel_TtxPage5, Keys.KEY_SubtitlePanel_TtxPage6, Keys.KEY_SubtitlePanel_TtxPage7, Keys.KEY_SubtitlePanel_TtxPage8 }; Object[] pagenumber = { "null", "149", "150", "199", "299", "599", "691", "692", "693", "694", "699", "777", "779", "784", "785", "786", "881", "882", "884", "885", "886", "887", "888", "889" }; for (int i = 0; i < keys.length; i++) { JComboBox combobox = new JComboBox(pagenumber); combobox.setPreferredSize(new Dimension(64, 22)); combobox.setMaximumSize(new Dimension(64, 22)); combobox.setEditable(true); combobox.setActionCommand(keys[i][0]); combobox.setSelectedItem(Common.getSettings().getProperty(keys[i])); combobox.addActionListener(_ComboBoxItemListener); if (i < 4) panel_0_1.add(combobox); else panel_0_2.add(combobox); } panel_0.add(panel_0_1); panel_0.add(panel_0_2); JPanel panel_0_3 = new JPanel(); panel_0_3.setLayout(new BoxLayout(panel_0_3, BoxLayout.X_AXIS)); JLabel lang_decode = new JLabel(Resource.getString("SubtitlePanel.Language")); lang_decode.setToolTipText(Resource.getString("SubtitlePanel.Language.Tip")); lang_decode.setPreferredSize(new Dimension(80, 22)); lang_decode.setMaximumSize(new Dimension(80, 22)); panel_0_3.add(lang_decode); JComboBox language_pair = new JComboBox(Keys.ITEMS_TtxLanguagePair); language_pair.setPreferredSize(new Dimension(140, 22)); language_pair.setMaximumSize(new Dimension(140, 22)); language_pair.setActionCommand(Keys.KEY_TtxLanguagePair[0]); language_pair.setSelectedIndex(Common.getSettings().getIntProperty(Keys.KEY_TtxLanguagePair)); language_pair.addActionListener(_ComboBoxIndexListener); panel_0_3.add(language_pair); panel_0.add(panel_0_3); panel_0.add(Box.createRigidArea(new Dimension(1, 10))); JPanel panel_0_4 = new JPanel(); panel_0_4.setLayout(new BoxLayout(panel_0_4, BoxLayout.X_AXIS)); panel_0_4.setToolTipText(Resource.getString("SubtitlePanel.Format.Tip")); panel_0_4.add(new JLabel("1. " + Resource.getString("SubtitlePanel.Format"))); JComboBox export_format = new JComboBox(Keys.ITEMS_SubtitleExportFormat); export_format.setPreferredSize(new Dimension(80, 22)); export_format.setMaximumSize(new Dimension(80, 22)); export_format.setActionCommand(Keys.KEY_SubtitleExportFormat[0]); export_format.setSelectedItem(Common.getSettings().getProperty(Keys.KEY_SubtitleExportFormat)); export_format.addActionListener(_ComboBoxItemListener); panel_0_4.add(export_format); panel_0.add(panel_0_4); JPanel panel_0_5 = new JPanel(); panel_0_5.setLayout(new BoxLayout(panel_0_5, BoxLayout.X_AXIS)); panel_0_5.setToolTipText(Resource.getString("SubtitlePanel.Format.Tip")); panel_0_5.add(new JLabel("2. " + Resource.getString("SubtitlePanel.Format"))); JComboBox export_format_2 = new JComboBox(Keys.ITEMS_SubtitleExportFormat); export_format_2.setPreferredSize(new Dimension(80, 22)); export_format_2.setMaximumSize(new Dimension(80, 22)); export_format_2.setActionCommand(Keys.KEY_SubtitleExportFormat_2[0]); export_format_2.setSelectedItem(Common.getSettings().getProperty(Keys.KEY_SubtitleExportFormat_2)); export_format_2.addActionListener(_ComboBoxItemListener); panel_0_5.add(export_format_2); panel_0.add(panel_0_5); teletext.add(panel_0); JPanel panel_1 = new JPanel(); panel_1.setLayout( new ColumnLayout() ); panel_1.setBorder( BorderFactory.createTitledBorder(Resource.getString("SubtitlePanel.Title")) ); panel_1.add(new JLabel(Resource.getString("SubtitlePanel.Title.Teletext"))); panel_1.add(box[6]); JPanel panel_1_2 = new JPanel(); panel_1_2.setLayout(new BoxLayout(panel_1_2, BoxLayout.X_AXIS)); JLabel font = new JLabel(Resource.getString("SubtitlePanel.Font")); font.setToolTipText(Resource.getString("SubtitlePanel.Font.Tip")); font.setPreferredSize(new Dimension(100, 22)); font.setMaximumSize(new Dimension(100, 22)); panel_1_2.add(font); JComboBox font_list = new JComboBox(Common.getFonts()); font_list.setPreferredSize(new Dimension(150, 22)); font_list.setMaximumSize(new Dimension(150, 22)); font_list.setActionCommand(Keys.KEY_SubtitleFont[0]); font_list.setSelectedItem(Common.getSettings().getProperty(Keys.KEY_SubtitleFont)); font_list.addActionListener(_ComboBoxItemListener); panel_1_2.add(font_list); panel_1.add(panel_1_2); JPanel panel_1_3 = new JPanel(); panel_1_3.setLayout(new BoxLayout(panel_1_3, BoxLayout.X_AXIS)); JLabel sup_label = new JLabel(Resource.getString("SubtitlePanel.SupValues")); sup_label.setPreferredSize(new Dimension(60, 22)); sup_label.setMaximumSize(new Dimension(60, 22)); panel_1_3.add(sup_label); JTextField subpicture_values = new JTextField(Common.getSettings().getProperty(Keys.KEY_SubtitlePanel_Format_SUP_Values)); subpicture_values.setPreferredSize(new Dimension(190, 22)); subpicture_values.setMaximumSize(new Dimension(190, 22)); subpicture_values.setToolTipText(Resource.getString(Keys.KEY_SubtitlePanel_Format_SUP_Values[0] + Keys.KEY_Tip)); subpicture_values.setEditable(true); subpicture_values.setActionCommand(Keys.KEY_SubtitlePanel_Format_SUP_Values[0]); subpicture_values.addActionListener(_TextFieldListener); subpicture_values.addKeyListener(_TextFieldKeyListener); panel_1_3.add(subpicture_values); panel_1.add(panel_1_3); panel_1.add(Box.createRigidArea(new Dimension(1, 15))); JLabel color_model = new JLabel(Resource.getString("SubtitlePanel.Colormodel")); color_model.setToolTipText(Resource.getString("SubtitlePanel.Colormodel.Tip")); panel_1.add(color_model); JComboBox color_table = new JComboBox(Common.getColorModels()); color_table.setPreferredSize(new Dimension(130, 22)); color_table.setMaximumSize(new Dimension(130, 22)); color_table.setActionCommand(Keys.KEY_SubpictureColorModel[0]); color_table.setSelectedItem(Common.getSettings().getProperty(Keys.KEY_SubpictureColorModel)); color_table.addActionListener(_ComboBoxItemListener); panel_1.add(color_table); JPanel panel_2_1 = new JPanel(); panel_2_1.setLayout(new BoxLayout(panel_2_1, BoxLayout.X_AXIS)); panel_2_1.add(new JLabel(Resource.getString("SubtitlePanel.PageId"))); JTextField page_id = new JTextField(Common.getSettings().getProperty(Keys.KEY_SubtitlePanel_PageId_Value)); page_id.setPreferredSize(new Dimension(40, 20)); page_id.setMaximumSize(new Dimension(100, 20)); page_id.setToolTipText(Resource.getString(Keys.KEY_SubtitlePanel_PageId_Value[0] + Keys.KEY_Tip)); page_id.setEditable(true); page_id.setActionCommand(Keys.KEY_SubtitlePanel_PageId_Value[0]); page_id.addActionListener(_TextFieldListener); page_id.addKeyListener(_TextFieldKeyListener); panel_2_1.add(page_id); panel_1.add(panel_2_1); panel_1.add(Box.createRigidArea(new Dimension(1, 10))); panel_1.add(new JLabel(Resource.getString("SubtitlePanel.Title"))); JPanel panel_2_2 = new JPanel(); panel_2_2.setLayout(new BoxLayout(panel_2_2, BoxLayout.X_AXIS)); panel_2_2.setToolTipText(Resource.getString("SubtitlePanel.ChangeDisplay.Tip")); JLabel label_2_2_1 = new JLabel(Resource.getString("SubtitlePanel.ChangeDisplay")); label_2_2_1.setPreferredSize(new Dimension(140, 22)); label_2_2_1.setMaximumSize(new Dimension(140, 22)); panel_2_2.add(label_2_2_1); JComboBox display_mode = new JComboBox(Keys.ITEMS_SubtitleChangeDisplay); display_mode.setPreferredSize(new Dimension(120, 22)); display_mode.setMaximumSize(new Dimension(120, 22)); display_mode.setActionCommand(Keys.KEY_SubtitleChangeDisplay[0]); display_mode.setSelectedIndex(Common.getSettings().getIntProperty(Keys.KEY_SubtitleChangeDisplay)); display_mode.addActionListener(_ComboBoxIndexListener); panel_2_2.add(display_mode); panel_1.add(panel_2_2); JPanel panel_2_3 = new JPanel(); panel_2_3.setLayout(new BoxLayout(panel_2_3, BoxLayout.X_AXIS)); panel_2_3.setToolTipText(Resource.getString("SubtitlePanel.MovePosition.Tip")); JLabel label_2_3_1 = new JLabel(Resource.getString("SubtitlePanel.MovePosition")); label_2_3_1.setPreferredSize(new Dimension(140, 22)); label_2_3_1.setMaximumSize(new Dimension(140, 22)); panel_2_3.add(label_2_3_1); JTextField position_values = new JTextField(Common.getSettings().getProperty(Keys.KEY_SubtitleMovePosition_Value)); position_values.setPreferredSize(new Dimension(120, 22)); position_values.setMaximumSize(new Dimension(120, 22)); position_values.setEditable(true); position_values.setActionCommand(Keys.KEY_SubtitleMovePosition_Value[0]); position_values.addActionListener(_TextFieldListener); position_values.addKeyListener(_TextFieldKeyListener); panel_2_3.add(position_values); panel_1.add(panel_2_3); panel_1.add(Box.createRigidArea(new Dimension(1, 10))); panel_1.add(new JLabel("Test:")); panel_1.add(box[7]); teletext.add(panel_1); return buildHeadPanel(teletext, Resource.getString("TabPanel.SubtitlePanel")); } /** * */ protected JPanel buildOptionPanel() { JPanel option = new JPanel(); option.setLayout( new GridLayout(1,2) ); JPanel op0 = new JPanel(); op0.setLayout( new ColumnLayout() ); op0.setBorder( BorderFactory.createTitledBorder(Resource.getString("OptionPanel.Various.Title")) ); String[][] objects = { Keys.KEY_dumpDroppedGop, Keys.KEY_holdStreamInfoOnOSD, Keys.KEY_additionalInputBuffer }; JCheckBox[] box = new JCheckBox[objects.length]; for (int i = 0; i < objects.length; i++) { box[i] = new JCheckBox(Resource.getString(objects[i][0])); box[i].setPreferredSize(new Dimension(270, 20)); box[i].setMaximumSize(new Dimension(270, 20)); box[i].setToolTipText(Resource.getString(objects[i][0] + Keys.KEY_Tip)); box[i].setActionCommand(objects[i][0]); box[i].setSelected(Common.getSettings().getBooleanProperty(objects[i])); box[i].addActionListener(_CheckBoxListener); if (i < 2) op0.add(box[i]); } op0.add(Box.createRigidArea(new Dimension(1, 4))); JTextField start_path = new JTextField(Common.getSettings().getProperty(Keys.KEY_StartPath_Value)); start_path.setPreferredSize(new Dimension(250, 25)); start_path.setToolTipText(Resource.getString(Keys.KEY_StartPath_Value[0] + Keys.KEY_Tip)); start_path.setEditable(true); start_path.setActionCommand(Keys.KEY_StartPath_Value[0]); start_path.addActionListener(_TextFieldListener); start_path.addKeyListener(_TextFieldKeyListener); op0.add(new JLabel(Resource.getString("OptionPanel.StartPath"))); op0.add(start_path); option.add(op0); JPanel op2 = new JPanel(); op2.setLayout( new ColumnLayout() ); op2.setBorder( BorderFactory.createTitledBorder(Resource.getString("OptionPanel.Buffer.Title")) ); op2.add(box[2]); String[][] keys = { Keys.KEY_MainBuffer, Keys.KEY_ScanBuffer, Keys.KEY_PreviewBuffer }; Object[][] buffersizes = { { "10240000", "8192000", "7168000", "6144000", "5120000", "4096000", "3072000", "2048000", "1024000" }, { "384000", "512000", "1024000", "1536000", "2048000", "2560000", "3072000" }, { "256000", "384000", "512000", "768000", "1024000", "1536000", "2048000", "2560000", "3072000" } }; for (int i = 0; i < keys.length; i++) { JComboBox combobox = new JComboBox(buffersizes[i]); combobox.setPreferredSize(new Dimension(100, 24)); combobox.setMaximumSize(new Dimension(100, 24)); combobox.setEditable(true); combobox.setMaximumRowCount(6); combobox.setActionCommand(keys[i][0]); combobox.setSelectedItem(Common.getSettings().getProperty(keys[i])); combobox.addActionListener(_ComboBoxItemListener); JLabel label = new JLabel(Resource.getString(keys[i][0])); label.setToolTipText(Resource.getString(keys[i][0] + Keys.KEY_Tip)); op2.add(label); op2.add(combobox); } option.add(op2); return buildHeadPanel(option, Resource.getString("TabPanel.OptionPanel")); } /** * */ protected JPanel buildNetPanel() { JPanel panel = new JPanel(); panel.setLayout( new GridLayout(1, 2) ); JPanel panel_1 = new JPanel(); panel_1.setLayout( new ColumnLayout() ); panel_1.setBorder( BorderFactory.createTitledBorder(Resource.getString("FtpPanel.Title")) ); /** * */ String[][] objects = { Keys.KEY_killFtpClient, Keys.KEY_useFtpServerResume, Keys.KEY_autostartWebServer }; JCheckBox[] box = new JCheckBox[objects.length]; for (int i = 0; i < 2; i++) { box[i] = new JCheckBox(Resource.getString(objects[i][0])); box[i].setPreferredSize(new Dimension(270, 20)); box[i].setMaximumSize(new Dimension(270, 20)); box[i].setToolTipText(Resource.getString(objects[i][0] + Keys.KEY_Tip)); box[i].setActionCommand(objects[i][0]); box[i].setSelected(Common.getSettings().getBooleanProperty(objects[i])); box[i].addActionListener(_CheckBoxListener); panel_1.add(box[i]); } panel_1.add(Box.createRigidArea(new Dimension(1, 5))); /** * */ JPanel ftpPanel = new JPanel(); ftpPanel.setLayout(new BoxLayout(ftpPanel, BoxLayout.X_AXIS)); JLabel label_1 = new JLabel (Resource.getString("ftp.command.label")); label_1.setPreferredSize(new Dimension(100, 20)); label_1.setMaximumSize(new Dimension(100, 20)); label_1.setToolTipText(Resource.getString("ftp.command.tip")); ftpPanel.add(label_1); JTextField ftpcommand = new JTextField(Common.getSettings().getProperty(Keys.KEY_FtpServer_Commands)); ftpcommand.setPreferredSize(new Dimension(160, 20)); ftpcommand.setMaximumSize(new Dimension(160, 20)); ftpcommand.setToolTipText(Resource.getString(Keys.KEY_FtpServer_Commands[0] + Keys.KEY_Tip)); ftpcommand.setActionCommand(Keys.KEY_FtpServer_Commands[0]); ftpcommand.addActionListener(_TextFieldListener); ftpcommand.addKeyListener(_TextFieldKeyListener); ftpPanel.add(ftpcommand); panel_1.add(ftpPanel); panel.add(panel_1); JPanel panel_2 = new JPanel(); panel_2.setLayout( new ColumnLayout() ); panel_2.setBorder( BorderFactory.createTitledBorder(Resource.getString("NetPanel.Title")) ); /** * */ for (int i = 2; i < objects.length; i++) { box[i] = new JCheckBox(Resource.getString(objects[i][0])); box[i].setPreferredSize(new Dimension(270, 20)); box[i].setMaximumSize(new Dimension(270, 20)); box[i].setToolTipText(Resource.getString(objects[i][0] + Keys.KEY_Tip)); box[i].setActionCommand(objects[i][0]); box[i].setSelected(Common.getSettings().getBooleanProperty(objects[i])); box[i].addActionListener(_CheckBoxListener); panel_2.add(box[i]); } panel_2.add(Box.createRigidArea(new Dimension(1, 5))); /** * */ JPanel netPanel = new JPanel(); netPanel.setLayout(new BoxLayout(netPanel, BoxLayout.X_AXIS)); JLabel label_2 = new JLabel ("Port:"); label_2.setPreferredSize(new Dimension(100, 20)); label_2.setMaximumSize(new Dimension(100, 20)); netPanel.add(label_2); JTextField port = new JTextField(Common.getSettings().getProperty(Keys.KEY_WebServerPort)); port.setPreferredSize(new Dimension(160, 20)); port.setMaximumSize(new Dimension(160, 20)); port.setToolTipText(Resource.getString(Keys.KEY_WebServerPort[0] + Keys.KEY_Tip)); port.setActionCommand(Keys.KEY_WebServerPort[0]); port.addActionListener(_TextFieldListener); port.addKeyListener(_TextFieldKeyListener); netPanel.add(port); panel_2.add(netPanel); /** * */ JPanel netPanel2 = new JPanel(); netPanel2.setLayout(new BoxLayout(netPanel2, BoxLayout.X_AXIS)); JLabel label_3 = new JLabel("Keyword:"); label_3.setPreferredSize(new Dimension(100, 20)); label_3.setMaximumSize(new Dimension(100, 20)); label_3.setToolTipText("mustn't be empty"); netPanel2.add(label_3); JTextField access = new JTextField(Common.getSettings().getProperty(Keys.KEY_WebServerAccess)); access.setPreferredSize(new Dimension(160, 20)); access.setMaximumSize(new Dimension(160, 20)); access.setToolTipText(Resource.getString(Keys.KEY_WebServerAccess[0] + Keys.KEY_Tip)); access.setActionCommand(Keys.KEY_WebServerAccess[0]); access.addActionListener(_TextFieldListener); access.addKeyListener(_TextFieldKeyListener); netPanel2.add(access); panel_2.add(netPanel2); JButton button_1 = new JButton("re-/start WebIF"); button_1.setPreferredSize(new Dimension(120, 22)); button_1.setMaximumSize(new Dimension(120, 22)); button_1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Common.startWebServer(); } }); JButton button_2 = new JButton("stop WebIF"); button_2.setPreferredSize(new Dimension(120, 22)); button_2.setMaximumSize(new Dimension(120, 22)); button_2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Common.stopWebServer(); } }); panel_2.add(button_1); panel_2.add(button_2); panel.add(panel_2); return buildHeadPanel(panel, Resource.getString("TabPanel.NetPanel")); } /** * */ protected JPanel buildPostCommandsPanel() { ActionListener _ExecuteListener = new ActionListener() { public void actionPerformed(ActionEvent e) { try { String actName = e.getActionCommand(); String str = ""; if (actName.equals(Keys.KEY_PostCommands_Cmd1[0])) str = Common.getSettings().getProperty(Keys.KEY_PostCommands_Cmd1); else if (actName.equals(Keys.KEY_PostCommands_Cmd2[0])) str = Common.getSettings().getProperty(Keys.KEY_PostCommands_Cmd2); else if (actName.equals(Keys.KEY_PostCommands_Cmd3[0])) str = Common.getSettings().getProperty(Keys.KEY_PostCommands_Cmd3); Common.performCommand(str); } catch (Exception ex) { Common.setExceptionMessage(ex); } } }; JPanel container = new JPanel(); container.setLayout( new ColumnLayout() ); container.setBorder( BorderFactory.createTitledBorder(Resource.getString("PostCommands.Title"))); String[][] objects = { Keys.KEY_PostCommands_Cmd1, Keys.KEY_PostCommands_Cmd2, Keys.KEY_PostCommands_Cmd3, Keys.KEY_PostCommands_Cmd4, Keys.KEY_PostCommands_Cmd5, Keys.KEY_PostCommands_Cmd6, Keys.KEY_PostCommands_Cmd7, Keys.KEY_PostCommands_Cmd8 }; for (int i = 0; i < 3; i++) { JTextField text_field = new JTextField(Common.getSettings().getProperty(objects[i])); text_field.setPreferredSize(new Dimension(400, 25)); text_field.setEditable(true); text_field.setActionCommand(objects[i][0]); text_field.addActionListener(_TextFieldListener); text_field.addKeyListener(_TextFieldKeyListener); JButton exe = new JButton(Resource.getString("PostCommands.Execute")); exe.setActionCommand(objects[i][0]); exe.setPreferredSize(new Dimension(100, 20)); exe.addActionListener(_ExecuteListener); JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); panel.add(text_field); panel.add(exe); container.add(panel); } container.add(Box.createRigidArea(new Dimension(1, 10))); JLabel label = new JLabel(Resource.getString("PostCommands.PostProcessing")); label.setToolTipText(Resource.getString("PostCommands.PostProcessing.Tip")); container.add(label); for (int i = 3; i < objects.length; i++) { JTextField text_field = new JTextField(Common.getSettings().getProperty(objects[i])); text_field.setPreferredSize(new Dimension(400, 25)); text_field.setEditable(true); text_field.setActionCommand(objects[i][0]); text_field.addActionListener(_TextFieldListener); text_field.addKeyListener(_TextFieldKeyListener); JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); panel.add(text_field); panel.add(new JLabel(Keys.ITEMS_ConversionMode[i - 3].toString())); container.add(panel); } return buildHeadPanel(container, Resource.getString("TabPanel.PostCommandsPanel")); } } project-x/src/net/sourceforge/dvb/projectx/gui/ProcessWindow.java0000600000175000017500000006605310412354356026702 0ustar supermariosupermario/* * @(#)ProcessWindow * * Copyright (c) 2005-2006 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.Point; import java.awt.Color; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.KeyEvent; import java.io.StringWriter; import java.io.PrintWriter; import java.io.FileOutputStream; import java.io.IOException; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JScrollPane; import javax.swing.JViewport; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JTextArea; import javax.swing.JMenuItem; import javax.swing.JCheckBoxMenuItem; import javax.swing.UIManager; import javax.swing.SwingConstants; import javax.swing.JComboBox; import javax.swing.JRadioButton; import javax.swing.JProgressBar; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.KeyStroke; import javax.swing.ButtonGroup; import net.sourceforge.dvb.projectx.gui.UISwitchListener; import net.sourceforge.dvb.projectx.gui.ColumnLayout; import net.sourceforge.dvb.projectx.gui.CommonGui; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.gui.CheckBoxListener; import net.sourceforge.dvb.projectx.gui.BitrateMonitor; /** * */ public class ProcessWindow extends JFrame { private String title = Resource.getString("ProcessWindow.Title"); private JLabel ttxheaderLabel; private JLabel ttxvpsLabel; private JLabel OffsetLabel; private JLabel StatusLabel; private JTextArea TextArea; private JViewport viewport; private JComboBox extractComboBox; private JProgressBar Progressbar; private String SplitPart; private BitrateMonitor Monitor; private CheckBoxListener _CheckBoxListener = new CheckBoxListener(); ActionListener _BoxListener = new ActionListener() { public void actionPerformed(ActionEvent e) { String actName = e.getActionCommand(); JCheckBoxMenuItem box = (JCheckBoxMenuItem) e.getSource(); Common.getSettings().setBooleanProperty(actName, box.getState()); } }; /** * Constructor */ public ProcessWindow() { addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { close(); } }); JPanel container = new JPanel(); container.setLayout(new BorderLayout()); setBounds(200, 100, 740, 480); buildMenu(); container.add(buildHeadPanel(), BorderLayout.NORTH); container.add(buildLogWindowPanel(), BorderLayout.CENTER); container.add(buildProgressPanel(), BorderLayout.SOUTH); getContentPane().add(container); setTitle(title); UIManager.addPropertyChangeListener(new UISwitchListener(getRootPane())); } /** * */ public void close() { focusToText(); dispose(); } /** * */ public void iconify() { focusToText(); setState(ICONIFIED); } /** * */ private void focusToText() { TextArea.requestFocus(); } /** * */ private void saveLog() { String str = CommonGui.getUserInput(this, "save log", "save logfile", Common.getSettings().getProperty(Keys.KEY_OutputDirectory) + System.getProperty("file.separator") + "pjx_log.txt"); if (str != null && str.length() > 0) { try { PrintWriter pw = new PrintWriter(new FileOutputStream(str)); pw.print(getLogContent()); pw.close(); } catch (IOException e) { Common.setExceptionMessage(e); } } toFront(); } /** * */ private String getLogContent() { return TextArea.getText(); } /** * */ protected void buildMenu() { JMenuBar menuBar = new JMenuBar(); menuBar.add(buildFileMenu()); menuBar.add(buildEditMenu()); menuBar.add(buildMessageMenu()); menuBar.add(buildPreferencesMenu()); setJMenuBar(menuBar); } /** * */ protected JMenu buildFileMenu() { JMenu fileMenu = new JMenu(); CommonGui.localize(fileMenu, "Common.File"); String[][] objects = { Keys.KEY_DebugLog, Keys.KEY_NormalLog }; for (int i = 0; i < objects.length; i++) { JCheckBoxMenuItem box = new JCheckBoxMenuItem(Resource.getString(objects[i][0])); box.setToolTipText(Resource.getString(objects[i][0] + Keys.KEY_Tip)); box.setActionCommand(objects[i][0]); box.setState(Common.getSettings().getBooleanProperty(objects[i])); box.addActionListener(_BoxListener); fileMenu.add(box); } fileMenu.addSeparator(); JCheckBoxMenuItem closeOnEnd = new JCheckBoxMenuItem(Resource.getString(Keys.KEY_closeOnEnd[0])); closeOnEnd.setToolTipText(Resource.getString(Keys.KEY_closeOnEnd[0]) + Keys.KEY_Tip); closeOnEnd.setActionCommand(Keys.KEY_closeOnEnd[0]); closeOnEnd.setState(Common.getSettings().getBooleanProperty(Keys.KEY_closeOnEnd)); closeOnEnd.addActionListener(_BoxListener); fileMenu.add(closeOnEnd); fileMenu.addSeparator(); JMenuItem save = new JMenuItem(); CommonGui.localize(save, "Common.SaveAs"); save.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { saveLog(); } }); fileMenu.add(save); fileMenu.addSeparator(); JMenuItem close = new JMenuItem(); CommonGui.localize(close, "Common.Close"); close.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.ALT_MASK)); close.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { close(); } }); fileMenu.add(close); return fileMenu; } /** * */ protected JMenu buildEditMenu() { JMenu editMenu = new JMenu(); CommonGui.localize(editMenu, "Common.Edit"); String[][] objects = { Keys.KEY_minimizeMainFrame, Keys.KEY_hideProcessWindow, Keys.KEY_showSubpictureWindow, Keys.KEY_useAllCollections, Keys.KEY_ExportPanel_createSubDirNumber, Keys.KEY_ExportPanel_createSubDirName, Keys.KEY_enablePostProcessing, Keys.KEY_simpleMPG, Keys.KEY_enhancedPES, Keys.KEY_useAutoPidFilter }; for (int i = 0; i < objects.length; i++) { JCheckBoxMenuItem box = new JCheckBoxMenuItem(Resource.getString(objects[i][0])); box.setToolTipText(Resource.getString(objects[i][0] + Keys.KEY_Tip)); box.setActionCommand(objects[i][0]); box.setState(Common.getSettings().getBooleanProperty(objects[i])); box.addActionListener(_BoxListener); if (i == 3 || i == 4 || i == 6 || i == 7) editMenu.addSeparator(); editMenu.add(box); } /** JMenu menu_2 = new JMenu(Resource.getString(Keys.KEY_OptionDAR[0])); Object[] objects_2 = Keys.ITEMS_ExportDAR; ButtonGroup group = new ButtonGroup(); for (int i = 0; i < objects_2.length; i++) { JRadioButtonMenuItem box = new JRadioButtonMenuItem(objects_2[i].toString()); box.setActionCommand(Keys.KEY_ExportDAR[0]); box.setSelected(Common.getSettings().getIntProperty(Keys.KEY_ExportDAR) == i); box.addActionListener(_BoxListener); group.add(box); menu_2.add(box); } editMenu.add(menu_2); **/ return editMenu; } /** * */ protected JMenu buildMessageMenu() { JMenu messageMenu = new JMenu(); CommonGui.localize(messageMenu, "Common.Messages"); String[][] objects = { Keys.KEY_MessagePanel_Msg1, Keys.KEY_MessagePanel_Msg2, Keys.KEY_MessagePanel_Msg3, Keys.KEY_MessagePanel_Msg8, Keys.KEY_MessagePanel_Msg5, Keys.KEY_MessagePanel_Msg6, Keys.KEY_MessagePanel_Msg7, Keys.KEY_MessagePanel_Msg4 }; for (int i = 0; i < objects.length; i++) { JCheckBoxMenuItem box = new JCheckBoxMenuItem(Resource.getString(objects[i][0])); box.setToolTipText(Resource.getString(objects[i][0] + Keys.KEY_Tip)); box.setActionCommand(objects[i][0]); box.setState(Common.getSettings().getBooleanProperty(objects[i])); box.addActionListener(_BoxListener); if (i == 3 || i == 4 || i == 7) messageMenu.addSeparator(); messageMenu.add(box); } return messageMenu; } /** * */ protected JMenu buildPreferencesMenu() { JMenu preferencesMenu = new JMenu(); CommonGui.localize(preferencesMenu, "Common.Preferences"); JMenuItem preferences = new JMenuItem(); preferences.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK)); CommonGui.localize(preferences, "Common.Preferences"); preferences.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Common.getGuiInterface().showPreSettings(); } }); preferencesMenu.add(preferences); return preferencesMenu; } /** * */ protected JPanel buildHeadPanel() { JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); panel.add(buildProcessPanel(), BorderLayout.NORTH); panel.add(buildActionPanel(), BorderLayout.SOUTH); return panel; } /** * */ protected JPanel buildProcessPanel() { JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), Resource.getString("MainPanel.Process"))); JButton doitButton = new JButton(CommonGui.loadIcon("start.gif")); doitButton.setMnemonic('s'); doitButton.setMaximumSize(new Dimension(60, 36)); doitButton.setPreferredSize(new Dimension(60, 36)); doitButton.setToolTipText(Resource.getString("button.go.Tip")); doitButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { if (!Common.isRunningProcess()) { if (Common.isCollectionListEmpty()) return; Common.setRunningProcess(true); extractComboBox.removeAllItems(); CommonParsing.setPvaPidToExtract(-1); Common.startMainProcess(); } else { if (!CommonParsing.isProcessPausing()) Common.setMessage(Resource.getString("golistener.msg.paused"), true, 0xFFFFE0); else Common.setMessage(Resource.getString("golistener.msg.resumed"), true, 0xFFFFFF); CommonParsing.setProcessPausing(!CommonParsing.isProcessPausing()); } } }); panel.add(doitButton); panel.add(Box.createRigidArea(new Dimension(4, 1))); JButton breakButton = new JButton(CommonGui.loadIcon("stop.gif")); breakButton.setMnemonic('c'); breakButton.setMaximumSize(new Dimension(36, 36)); breakButton.setPreferredSize(new Dimension(36, 36)); breakButton.setToolTipText(Resource.getString("button.c.Tip")); breakButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { Common.breakMainProcess(); } }); panel.add(breakButton); panel.add(Box.createRigidArea(new Dimension(10, 1))); JButton scanButton = new JButton(CommonGui.loadIcon("scan.gif")); scanButton.setMnemonic('i'); scanButton.setMaximumSize(new Dimension(36, 36)); scanButton.setPreferredSize(new Dimension(36, 36)); scanButton.setToolTipText(Resource.getString("button.i.Tip")); scanButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { if (!Common.startProcess()) return; extractComboBox.removeAllItems(); CommonParsing.setInfoScan(true); Common.startMainProcess(); } }); panel.add(scanButton); panel.add(Box.createRigidArea(new Dimension(4, 1))); JButton extractButton = new JButton(CommonGui.loadIcon("extract.gif")); extractButton.setMnemonic('e'); extractButton.setMaximumSize(new Dimension(36, 36)); extractButton.setPreferredSize(new Dimension(36, 36)); extractButton.setToolTipText(Resource.getString("button.e.Tip")); extractButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { if (Common.isRunningProcess()) return; if (extractComboBox.getItemCount() == 0) return; Common.setRunningProcess(true); CommonParsing.setPvaPidExtraction(true); CommonParsing.setPvaPidToExtract(Integer.parseInt(extractComboBox.getSelectedItem().toString(), 16)); Common.setMessage(Resource.getString("golistener.msg.extracting") + extractComboBox.getSelectedItem().toString() + "..."); Common.startMainProcess(); } }); panel.add(extractButton); panel.add(Box.createRigidArea(new Dimension(4, 1))); extractComboBox = new JComboBox(); extractComboBox.setMaximumSize(new Dimension(44, 26)); extractComboBox.setPreferredSize(new Dimension(44, 26)); extractComboBox.setMaximumRowCount(5); panel.add(extractComboBox); panel.add(Box.createRigidArea(new Dimension(10, 1))); panel.add(buildStatusPanel()); return panel; } /** * */ protected JPanel buildStatusPanel() { JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); Monitor = new BitrateMonitor(); Monitor.setToolTipText(Resource.getString("MainPanel.BitrateMonitor.Tip")); panel.add(Monitor); JPanel status_7 = new JPanel(new BorderLayout()); status_7.setBorder(BorderFactory.createLoweredBevelBorder()); status_7.add(Monitor); status_7.setPreferredSize(new Dimension(114, 36)); status_7.setMaximumSize(new Dimension(114, 36)); panel.add(status_7); final JLabel troughput = new JLabel(); final JLabel collLabel = new JLabel(); final JLabel FpsLabel = new JLabel(); final JLabel outSize = new JLabel(); outSize.setToolTipText(Resource.getString("MainPanel.writtenMB.Tip")); /** * */ JPanel status_3 = new JPanel(new BorderLayout()); status_3.setBorder(BorderFactory.createLoweredBevelBorder()); status_3.setPreferredSize(new Dimension(100, 18)); status_3.setMaximumSize(new Dimension(100, 18)); status_3.setBackground(new Color(225, 225, 250)); status_3.add(collLabel); JPanel status_4 = new JPanel(new BorderLayout()); status_4.setBorder(BorderFactory.createLoweredBevelBorder()); status_4.setPreferredSize(new Dimension(100, 18)); status_4.setMaximumSize(new Dimension(100, 18)); status_4.add(outSize); JPanel panel_2 = new JPanel(); panel_2.setLayout(new BoxLayout(panel_2, BoxLayout.Y_AXIS)); panel_2.add(status_3); panel_2.add(status_4); panel.add(panel_2); /** * */ JPanel status_1 = new JPanel(new BorderLayout()); status_1.setBorder(BorderFactory.createLoweredBevelBorder()); status_1.setPreferredSize(new Dimension(100, 18)); status_1.setMaximumSize(new Dimension(100, 18)); status_1.add(troughput); JPanel status_2 = new JPanel(new BorderLayout()); status_2.setBorder(BorderFactory.createLoweredBevelBorder()); status_2.setPreferredSize(new Dimension(100, 18)); status_2.setMaximumSize(new Dimension(100, 18)); status_2.add(FpsLabel); JPanel panel_1 = new JPanel(); panel_1.setLayout(new BoxLayout(panel_1, BoxLayout.Y_AXIS)); panel_1.add(status_1); panel_1.add(status_2); panel.add(panel_1); /** * */ OffsetLabel = new JLabel(Resource.getString("MainPanel.AudioVideoOffset")); OffsetLabel.setToolTipText(Resource.getString("MainPanel.AudioVideoOffset.Tip")); StatusLabel = new JLabel(Resource.getString("MainPanel.nonVideoExportStatus")); StatusLabel.setToolTipText(Resource.getString("MainPanel.nonVideoExportStatus.Tip")); JPanel status_5 = new JPanel(new BorderLayout()); status_5.setBorder(BorderFactory.createLoweredBevelBorder()); status_5.setPreferredSize(new Dimension(100, 18)); status_5.setMaximumSize(new Dimension(100, 18)); status_5.add(OffsetLabel); JPanel status_6 = new JPanel(new BorderLayout()); status_6.setBorder(BorderFactory.createLoweredBevelBorder()); status_6.setPreferredSize(new Dimension(100, 18)); status_6.setMaximumSize(new Dimension(100, 18)); status_6.add(StatusLabel); JPanel panel_3 = new JPanel(); panel_3.setLayout(new BoxLayout(panel_3, BoxLayout.Y_AXIS)); panel_3.add(status_5); panel_3.add(status_6); panel.add(panel_3); /** * */ final JLabel TimeLabel = new JLabel(); TimeLabel.setToolTipText("process time elapsed"); final JLabel ErrorLabel = new JLabel(); ErrorLabel.setToolTipText("warnings/error counter"); JPanel status_8 = new JPanel(new BorderLayout()); status_8.setBorder(BorderFactory.createLoweredBevelBorder()); status_8.setPreferredSize(new Dimension(60, 18)); status_8.setMaximumSize(new Dimension(60, 18)); status_8.add(TimeLabel); JPanel status_9 = new JPanel(new BorderLayout()); status_9.setBorder(BorderFactory.createLoweredBevelBorder()); status_9.setPreferredSize(new Dimension(60, 18)); status_9.setMaximumSize(new Dimension(60, 18)); status_9.add(ErrorLabel); JPanel panel_4 = new JPanel(); panel_4.setLayout(new BoxLayout(panel_4, BoxLayout.Y_AXIS)); panel_4.add(status_8); panel_4.add(status_9); panel.add(panel_4); class Clock implements Runnable { private Thread clockThread = null; private String last_value = ""; private String last_exp = ""; private String last_fps = ""; private int last_coll = 0; public void start() { if (clockThread == null) { clockThread = new Thread(this, "Clock_2"); clockThread.setPriority(Thread.MIN_PRIORITY); clockThread.start(); } } public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { update(); try { Thread.sleep(1000); } catch (InterruptedException e) {} } } private void update() { updateFpsLabel(); updateDataTroughputLabel(); updateExportedSizeLabel(); updateCollectionLabel(); updateTimeLabel(); } private void updateFpsLabel() { String str = Common.getFps(); if (!last_fps.equals(str)) FpsLabel.setText(str + " fps"); last_fps = str; } private void updateDataTroughputLabel() { String str = Common.getDataTroughput(); if (!last_value.equals(str)) troughput.setText(str + " kB/s"); last_value = str; } private void updateExportedSizeLabel() { String str = Common.getExportedSize(); if (!last_exp.equals(str)) outSize.setText(str); last_exp = str; } private void updateCollectionLabel() { int val = Common.isRunningProcess() ? Common.getProcessedCollection() : Common.getActiveCollection(); if (last_coll != val) collLabel.setText("Collection: " + (val < 0 ? "-" : String.valueOf(val))); last_coll = val; } private void updateTimeLabel() { TimeLabel.setText(Common.formatTime_4(Common.getProcessTime())); ErrorLabel.setText(String.valueOf(Common.getErrorCount())); } public void stop() { clockThread = null; } } new Clock().start(); return panel; } /** * */ protected JPanel buildActionPanel() { final Object[] objects = Keys.ITEMS_ConversionMode; int index = Common.getSettings().getIntProperty(Keys.KEY_ConversionMode); ActionListener _RadioListener = new ActionListener() { public void actionPerformed(ActionEvent e) { JRadioButton radio = (JRadioButton) e.getSource(); String str = radio.getActionCommand(); for (int i = 0; i < objects.length; i++) { if (!str.equals(objects[i].toString())) continue; Common.getSettings().setProperty(Keys.KEY_ConversionMode[0], String.valueOf(i)); } } }; JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); panel.setBorder(BorderFactory.createEtchedBorder()); panel.add(new JLabel(Resource.getString("ProcessWindowPanel.Action"))); panel.setToolTipText(Resource.getString("MainPanel.Process.Tip")); panel.add(Box.createRigidArea(new Dimension(10, 1))); ButtonGroup group = new ButtonGroup(); for (int i = 0; i < objects.length; i++) { JRadioButton action = new JRadioButton(objects[i].toString()); action.setActionCommand(objects[i].toString()); action.setSelected(i == index); action.addActionListener(_RadioListener); group.add(action); panel.add(action); } panel.add(Box.createRigidArea(new Dimension(10, 1))); JCheckBox priority = new JCheckBox(Resource.getString(Keys.KEY_ConversionModePriority[0])); priority.setToolTipText(Resource.getString(Keys.KEY_ConversionModePriority[0] + Keys.KEY_Tip)); priority.setActionCommand(Keys.KEY_ConversionModePriority[0]); priority.setSelected(Common.getSettings().getBooleanProperty(Keys.KEY_ConversionModePriority)); priority.addActionListener(_CheckBoxListener); panel.add(priority); return panel; } /** * */ protected JPanel buildLogWindowPanel() { JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); JPanel main5 = new JPanel(); main5.setLayout(new BorderLayout()); JPanel panel_2 = new JPanel(); panel_2.setLayout(new BoxLayout(panel_2, BoxLayout.X_AXIS)); JLabel icon = new JLabel(CommonGui.loadIcon("_teletext.gif")); panel_2.add(icon); panel_2.add(Box.createRigidArea(new Dimension(4, 1))); JCheckBox box = new JCheckBox(); box.setToolTipText(Resource.getString(Keys.KEY_showTtxHeader[0] + Keys.KEY_Tip)); box.setActionCommand(Keys.KEY_showTtxHeader[0]); box.setSelected(Common.getSettings().getBooleanProperty(Keys.KEY_showTtxHeader)); box.addActionListener(_CheckBoxListener); panel_2.add(box); main5.add(panel_2, BorderLayout.WEST); ttxheaderLabel = new JLabel(""); ttxheaderLabel.setToolTipText(Resource.getString("LogwindowPanel.showTtxHeader.Tip1")); main5.add(ttxheaderLabel, BorderLayout.CENTER); ttxvpsLabel = new JLabel(""); ttxvpsLabel.setToolTipText(Resource.getString("LogwindowPanel.showVpsLabel.Tip")); main5.add(ttxvpsLabel, BorderLayout.EAST); JPanel main6 = new JPanel(); main6.setLayout(new GridLayout(1, 1)); main6.add(main5); TextArea = new JTextArea(); TextArea.setEditable(true); TextArea.setRows(16); TextArea.setTabSize(12); TextArea.setFont(new Font("Tahoma", Font.PLAIN, 12)); JScrollPane scrolltext = new JScrollPane(); scrolltext.setViewportView(TextArea); viewport = scrolltext.getViewport(); //viewport.setScrollMode(JViewport.BLIT_SCROLL_MODE); //enable for >= JDK1.3 //viewport.setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE); //alternative, enable for >= JDK1.3 //viewport.setBackingStoreEnabled(true); // enable for < JDK1.3 JPanel control04 = new JPanel(new BorderLayout()); control04.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), Resource.getString("ProcessWindowPanel.Title"))); control04.setAlignmentX(CENTER_ALIGNMENT); control04.add(main6, BorderLayout.NORTH); control04.add(scrolltext, BorderLayout.CENTER); panel.add(control04); return panel; } /** * */ protected JPanel buildProgressPanel() { JPanel progress = new JPanel(); progress.setLayout(new BoxLayout(progress, BoxLayout.X_AXIS)); Progressbar = new JProgressBar(); Progressbar.setString(Resource.getString("run.status")); Progressbar.setStringPainted(true); /** * bei cli nicht nutzbar */ Progressbar.addChangeListener(new ChangeListener() { int _val = 0; public void stateChanged(ChangeEvent e) { if (Common.isRunningCLI()) { // System.out.print("\r" + (int)(Progressbar.getPercentComplete() * 100) + "% "); // System.out.print("" + Progressbar.getString()); } else { Common.setFrameTitle("" + (int)(Progressbar.getPercentComplete() * 100) + "% (" + Common.getProcessedCollection() + ") " + Common.getVersionName() + "/" + Common.getVersionDate()); /** * disabled, colorchange by percent, slows down * int val = (int)(128 * Progressbar.getPercentComplete()); if (val != _val) Progressbar.setForeground(new Color(192 - val, 64 + val, 0)); _val = val; **/ } } }); progress.add(Progressbar); return progress; } /** * messages of interest, also with current systems time_index * * @param1 - the msg * @param2 - force windows visibility * @param3 - background */ public void setMessage(String msg, boolean tofront, int background) { if (background != -1) TextArea.setBackground(new Color(background)); /** * ensure Logmsg is visible in GUI mode */ if (tofront) show(); if (msg == null) { TextArea.setText(null); return; } TextArea.append(Common.getLineSeparator() + msg); viewport.setViewPosition(new Point(0, TextArea.getHeight())); } /** * */ public void updateTtxHeader(String str) { ttxheaderLabel.setText(str); } /** * */ public void updateVpsLabel(String str) { ttxvpsLabel.setText(str); } /** * */ public void addPidToExtract(Object obj) { extractComboBox.addItem(obj); } /** * */ public void showExportStatus(String str) { StatusLabel.setText(str); } /** * */ public void showExportStatus(String str, int value) { StatusLabel.setText(str + " " + value); } /** * */ public void showAVOffset(String str) { OffsetLabel.setText(str); } /** * */ public void resetBitrateMonitor() { Monitor.reset(); } /** * */ public void updateBitrateMonitor(int value, byte[] array, String str) { Monitor.update(value, array, str); } /** * progress * * @param1 - the msg */ public void updateProgressBar(int percent) { Progressbar.setValue(percent); } /** * progress * * @param1 - the msg */ public void updateProgressBar(String str) { Progressbar.setString(str); Progressbar.setStringPainted(true); } } project-x/src/net/sourceforge/dvb/projectx/gui/StartUp.java0000600000175000017500000001635010351107756025473 0ustar supermariosupermario/* * @(#)StartUp.java - mini info, hold a place for start infos * * Copyright (c) 2004-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.Dimension; import java.awt.BorderLayout; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JButton; import javax.swing.JProgressBar; import javax.swing.Box; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.gui.MainFrame; import net.sourceforge.dvb.projectx.gui.ColumnLayout; import net.sourceforge.dvb.projectx.gui.CommonGui; /** * */ public class StartUp extends JFrame { /** Background Color */ private final Color BACKGROUND_COLOR = new Color(200, 200, 200); private boolean agreement = false; private JButton agree; private JProgressBar progressBar; private JLabel progress; private JLabel message; /** * */ public StartUp() { open(Resource.getString("StartUp.Title")); } /** * */ public StartUp(String title) { open(title); } /** * */ protected void open(String title) { setTitle(title); JPanel container = new JPanel(); container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS)); container.setBackground(BACKGROUND_COLOR); container.add(buildUpperPanel()); container.add(buildHLinePanel()); container.add(buildLoadPanel()); container.add(buildHLinePanel()); container.add(Box.createRigidArea(new Dimension(1, 10))); container.add(buildButtonPanel()); container.add(Box.createRigidArea(new Dimension(1, 10))); JPanel container2 = new JPanel(); container2.setBorder(BorderFactory.createRaisedBevelBorder()); container2.setBackground(BACKGROUND_COLOR); container2.add(container); getContentPane().add(container2); pack(); setLocation(200, 200); setResizable(false); addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) { Common.exitApplication(0); } }); return; } /** * */ protected JPanel buildUpperPanel() { JPanel panel = new JPanel(); panel.setBackground(new Color(224, 224, 224)); panel.setLayout(new ColumnLayout()); panel.add(Box.createRigidArea(new Dimension(1, 20))); panel.add(new JLabel(" " + Resource.getString("StartUp.Init"))); panel.add(Box.createRigidArea(new Dimension(1, 10))); panel.add(message = new JLabel(" " + Resource.getString("StartUp.Wait"))); panel.add(Box.createRigidArea(new Dimension(1, 20))); JPanel panel_1 = new JPanel(); panel_1.setBackground(new Color(224, 224, 224)); panel_1.setLayout(new BorderLayout()); panel_1.add(new JLabel(CommonGui.loadIcon("px.gif")), BorderLayout.EAST); panel_1.add(panel, BorderLayout.WEST); return panel_1; } /** * */ protected JPanel buildHLinePanel() { JPanel panel = new JPanel(); panel.setLayout(new ColumnLayout()); panel.setBorder(BorderFactory.createEtchedBorder()); return panel; } /** * */ protected JPanel buildLoadPanel() { JPanel panel = new JPanel(); panel.setBackground(BACKGROUND_COLOR); panel.setLayout(new ColumnLayout()); panel.add(Box.createRigidArea(new Dimension(1, 10))); progress = new JLabel("Start..."); panel.add(progress); progressBar = new JProgressBar(); progressBar.setStringPainted(true); progressBar.setValue(0); progressBar.setPreferredSize(new Dimension(500, 24)); progressBar.setForeground(new Color(20, 240, 20)); panel.add(Box.createRigidArea(new Dimension(1, 5))); panel.add(progressBar); panel.add(Box.createRigidArea(new Dimension(1, 20))); String terms[] = Resource.getStringByLines("terms"); for (int i = 0; i < terms.length; i++) panel.add(new JLabel(terms[i])); panel.add(Box.createRigidArea(new Dimension(1, 10))); return panel; } /** * */ protected JPanel buildButtonPanel() { JButton cancel = new JButton(); CommonGui.localize(cancel, "Common.Cancel"); cancel.setActionCommand("disagree"); cancel.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { Common.exitApplication(0); } }); JButton disagree = new JButton(Resource.getString("terms.disagree")); disagree.setActionCommand("disagree"); disagree.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { Common.exitApplication(0); } }); agree = new JButton(Resource.getString("terms.agree")); agree.setActionCommand("agree"); agree.setEnabled(false); agree.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { if (!agree.isEnabled()) return; setVisible(false); Common.getSettings().setProperty(Keys.KEY_Agreement[0], "1"); MainFrame.setVisible0(true); } }); JPanel panel = new JPanel(); panel.setBackground(BACKGROUND_COLOR); panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); panel.add(agree); panel.add(Box.createRigidArea(new Dimension(10, 1))); panel.add(disagree); JPanel panel_1 = new JPanel(); panel_1.setBackground(BACKGROUND_COLOR); panel_1.setLayout(new BorderLayout()); panel_1.add(panel, BorderLayout.WEST); panel_1.add(cancel, BorderLayout.EAST); return panel_1; } /** * */ public void set(boolean _agreement) { agree.setEnabled(!_agreement); agreement = _agreement; agree.setSelected(agreement); if (agreement) agree.setForeground(Color.green); else message.setText(" " + Resource.getString("StartUp.Choose")); } /** * */ public boolean get() { return agree.isSelected(); } /** * */ public void setProgress(int value, String str) { progress.setText(str); progressBar.setStringPainted(true); progressBar.setValue(value); System.out.println(str); } /** * */ public void close() { dispose(); } } project-x/src/net/sourceforge/dvb/projectx/gui/SubpictureFrame.java0000600000175000017500000000730110351107766027166 0ustar supermariosupermario/* * @(#)SubpictureFrame * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import java.awt.Image; import java.awt.Color; import java.awt.Graphics; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.KeyEvent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JMenuBar; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.KeyStroke; import javax.swing.UIManager; import net.sourceforge.dvb.projectx.gui.CommonGui; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Common; public class SubpictureFrame extends JFrame { String title = Resource.getString("subpicture.title"); private Picture picture; /** * */ public SubpictureFrame() { addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { close(); } }); buildMenu(); getContentPane().add("Center", picture = new Picture()); setTitle(title); setBounds(200, 100, 726, 621); setResizable(false); UIManager.addPropertyChangeListener(new UISwitchListener(getRootPane())); } /** * */ public void setFrameTitle(String newtitle) { setTitle(title + " " + newtitle); } /** * */ public void repaintSubpicture() { picture.repaint(); } /** * */ public void close() { dispose(); } /** * */ protected void buildMenu() { JMenuBar menuBar = new JMenuBar(); menuBar.add(buildFileMenu()); setJMenuBar(menuBar); } /** * */ protected JMenu buildFileMenu() { JMenu fileMenu = new JMenu(); CommonGui.localize(fileMenu, "Common.File"); JMenuItem close = new JMenuItem(); CommonGui.localize(close, "Common.Close"); close.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.ALT_MASK)); close.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { close(); } }); fileMenu.add(close); return fileMenu; } /** * */ public class Picture extends JPanel { /** * */ public Picture() { setBackground(Color.gray); setPreferredSize(new Dimension(720, 576)); setMinimumSize(new Dimension(720, 576)); setMaximumSize(new Dimension(720, 576)); } /** * */ public void paint(Graphics g) { Image image = Common.getSubpictureClass().getImage(); if (image != null) g.drawImage(image, 0, 0, this); } } } project-x/src/net/sourceforge/dvb/projectx/gui/TeletextPageMatrix.java0000600000175000017500000001156010351107774027647 0ustar supermariosupermario/* * @(#)TeletextPageMatrix.java - graphical representation of found TTX pages * * Copyright (c) 2004-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.BufferedImage; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.UIManager; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.gui.UISwitchListener; //DM17042004 081.7 int02 introduced public class TeletextPageMatrix extends JFrame { public Picture picture; private String title = Resource.getString("ttpagematrix.title"); private int w = 310; private int h = 410; public TeletextPageMatrix() { addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { close(); } }); UIManager.addPropertyChangeListener(new UISwitchListener((JComponent)getRootPane())); picture = new Picture(); getContentPane().add("Center", picture); setTitle(title); setSize(new Dimension(w, h)); setLocation(100, 100); setResizable(false); } public void close() { dispose(); } public class Picture extends JPanel { private Color[] color = { Color.red, Color.yellow, Color.green, new Color(255, 144, 0), //orange new Color(144, 144, 255), //light blue Color.cyan, Color.magenta, Color.white, Color.black, new Color(0, 200, 0) // dark green }; private BufferedImage bimg; private Graphics2D big; private int x = 0, y = 0; public Picture() { bimg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); big = bimg.createGraphics(); big.setFont(new Font("Sans Serif", Font.PLAIN, 12)); setBackground(color[8]); setToolTipText(Resource.getString("ttpagematrix.tip")); init(); } public void paint(Graphics g) { if (big == null) return; g.drawImage(bimg, 0, 0, this); } public void init() { init(""); } public void init(String file) { x = 0; y = 0; big.setColor(color[8]); big.fillRect(0, 0, w, h); big.setColor(color[7]); big.drawString(Resource.getString("ttpagematrix.file") + ": " + file, x + 10, y + 14); y += 16; big.drawString(Resource.getString("ttpagematrix.composition1") + ": ", x + 10, y + 14); big.drawString(Resource.getString("ttpagematrix.composition2"), x + 20, y + 30); big.drawString(Resource.getString("ttpagematrix.composition3") + ":", x + 10, y + 46); for (int a=0; a<8; a++) big.drawString(" = " + (a+1), x + 28 + (a<<5), y + 62); for (int a=0; a<8; a++) { big.setColor(color[a]); big.fillRect(x + 22 + (a<<5), y + 52, 3, 12); } big.setColor(color[7]); big.drawString("X", x + 40, y + 80); big.drawString("Y", x + 8, y + 113); x += 20; y += 84; for (int a=0; a<16; a++) { big.drawString(Integer.toHexString(a).toUpperCase(), x + 20 + (a<<4), y + 12); big.drawString(Integer.toHexString(a).toUpperCase(), x + 5, y + 29 + (a<<4)); } big.setColor(color[9]); for (int a=1; a<18; a++) { big.drawLine( x, y + (a<<4), x + 272, y + (a<<4)); big.drawLine( x + (a<<4), y, x + (a<<4), y + 272); } x += 18; y += 19; repaint(); } public void update(String page) { int pagenumber = Integer.parseInt(page, 16); int pm = (0xF & pagenumber>>>8) - 1; if (pm < 0) return; int px = x + (0xF0 & pagenumber) + ((3 & pm)<<2); int py = y + (0xF0 & pagenumber<<4) + ((4 & pm) != 0 ? 6 : 0); if ((0xFFFFFF & bimg.getRGB(px, py)) != 0) return; big.setColor(color[pm]); big.fillRect(px, py, 2, 5); if (picture.isVisible()) repaint(); } } } project-x/src/net/sourceforge/dvb/projectx/gui/TextFieldKeyListener.java0000600000175000017500000000265710351110006030123 0ustar supermariosupermario/* * @(#)TextFieldKeyListener * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import javax.swing.JTextField; import java.awt.event.KeyEvent; import java.awt.event.KeyAdapter; import net.sourceforge.dvb.projectx.common.Common; /** * */ public class TextFieldKeyListener extends KeyAdapter { /** * */ public void keyReleased(KeyEvent e) { JTextField textfield = (JTextField) e.getSource(); textfield.postActionEvent(); } } project-x/src/net/sourceforge/dvb/projectx/gui/TextFieldListener.java0000600000175000017500000000301310351110014027434 0ustar supermariosupermario/* * @(#)TextFieldListener * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import javax.swing.JTextField; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import net.sourceforge.dvb.projectx.common.Common; /** * */ public class TextFieldListener implements ActionListener { /** * */ public void actionPerformed(ActionEvent e) { String actName = e.getActionCommand(); JTextField textfield = (JTextField) e.getSource(); Common.getSettings().setProperty(actName, textfield.getText()); } } project-x/src/net/sourceforge/dvb/projectx/gui/UISwitchListener.java0000600000175000017500000000522510351110036027256 0ustar supermariosupermario/* * @(#)UISwitchListener.java 1.4 99/04/23 * * Copyright (c) 1998, 1999 by Sun Microsystems, Inc. All Rights Reserved. * * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use, * modify and redistribute this software in source and binary code form, * provided that i) this copyright notice and license appear on all copies of * the software; and ii) Licensee does not utilize the software in a manner * which is disparaging to Sun. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * This software is not designed or intended for use in on-line control of * aircraft, air traffic, aircraft navigation or aircraft communications; or in * the design, construction, operation or maintenance of any nuclear * facility. Licensee represents and warrants that it will not use or * redistribute the Software for such purposes. */ /* * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * */ package net.sourceforge.dvb.projectx.gui; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JComponent; import javax.swing.SwingUtilities; /** * This class listens for UISwitches, and updates a given component. * * @version 1.4 04/23/99 * @author Steve Wilson */ public class UISwitchListener implements PropertyChangeListener { JComponent componentToSwitch; public UISwitchListener(JComponent c) { componentToSwitch = c; } public void propertyChange(PropertyChangeEvent e) { String name = e.getPropertyName(); if (name.equals("lookAndFeel")) { SwingUtilities.updateComponentTreeUI(componentToSwitch); componentToSwitch.invalidate(); componentToSwitch.validate(); componentToSwitch.repaint(); } } } project-x/src/net/sourceforge/dvb/projectx/gui/X_JFileChooser.java0000600000175000017500000000506510351110046026657 0ustar supermariosupermario/* * @(#)X_JFileChooser.java - extracted JFileChooser * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.gui; import javax.swing.JFileChooser; import java.io.File; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Keys; public class X_JFileChooser extends JFileChooser { /** * */ public X_JFileChooser() { super(); localize(); } /** * */ public X_JFileChooser(String current_directory) { super(current_directory); localize(); } /** * */ private void localize() { setCurrentDirectory(Common.getSettings().getProperty(Keys.KEY_ActiveDirectory)); setApproveButtonText(Resource.getString("FileChooser.Select")); setDialogTitle(Resource.getString("FileChooser.Title")); } /** * */ public void setCurrentDirectory(String current_directory) { if (current_directory.startsWith("?")) super.setCurrentDirectory(new File(current_directory.substring(1))); // else if (!current_directory.equals("") && super.getCurrentDirectory().toString().equals(System.getProperty("user.home"))) else if (!current_directory.equals("")) super.setCurrentDirectory(new File(current_directory)); } /** * */ public void rescanCurrentDirectory() { String current_directory = Common.getSettings().getProperty(Keys.KEY_StartPath_Value); setCurrentDirectory(current_directory); super.rescanCurrentDirectory(); Common.getSettings().setProperty(Keys.KEY_ActiveDirectory[0], super.getCurrentDirectory().toString()); } } project-x/src/net/sourceforge/dvb/projectx/io/0000700000175000017500000000000010745203152023034 5ustar supermariosupermarioproject-x/src/net/sourceforge/dvb/projectx/io/BitWalker.java0000600000175000017500000001212610404135504025564 0ustar supermariosupermario/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ /* * Disclaimer of Warranty * * These software programs are available to the user without any license fee or * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims * any and all warranties, whether express, implied, or statuary, including any * implied warranties or merchantability or of fitness for a particular * purpose. In no event shall the copyright-holder be liable for any * incidental, punitive, or consequential damages of any kind whatsoever * arising from the use of these programs. * * This disclaimer of warranty extends to the user of these programs and user's * customers, employees, agents, transferees, successors, and assigns. * * The MPEG Software Simulation Group does not represent or warrant that the * programs furnished hereunder are free of infringement of any third-party * patents. * * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, * are subject to royalty fees to patent holders. Many of these patents are * general enough such that they are unavoidable regardless of implementation * design. * */ /* * net.sourceforge.dvb.projectx.io.BitWalker * * Parts of MpvDecoder.java copied - especially to retrieve the picture_structure * from the PICTURE_CODING_EXTENSION of a picture. * And some other stuff in this context for further use. * * --- cminfo --- * * Created on 27.02.2006 by Arno * */ package net.sourceforge.dvb.projectx.io; public class BitWalker { private final int USER_DATA_START_CODE = 0x1B2; private final int EXTENSION_START_CODE = 0x1B5; /* extension start code IDs */ private final int PICTURE_CODING_EXTENSION_ID = 8; public static final int FRAME_PICTURE = 3; private int BitPos = 0; private int BufferPos = 0; private long StartPos = 0; private byte[] buf = new byte[0]; public BitWalker() { super(); } public BitWalker(byte[] inpBuf, int inpStartPos) { super(); setBuf(inpBuf, inpStartPos); } public void resetCounters() { BufferPos = (int) StartPos; BitPos = BufferPos << 3; } public void setStartPos(int inpStartPos) { StartPos = inpStartPos; resetCounters(); } public void setBuf(byte[] inpBuf, int inpStartPos) { buf = inpBuf; setStartPos(inpStartPos); } private void skipBits(int n) { BitPos += n; BufferPos = BitPos >>> 3; } private void Flush_Bits(int n) { skipBits(n); } private int showBits(int n) { int Pos = BitPos >>> 3; int Val = (0xFF & buf[Pos]) << 24 | (0xFF & buf[Pos + 1]) << 16 | (0xFF & buf[Pos + 2]) << 8 | (0xFF & buf[Pos + 3]); Val <<= BitPos & 7; Val >>>= 32 - n; return Val; } private int Show_Bits(int n) { return showBits(n); } private int popBits(int n) { int Val = showBits(n); BitPos += n; BufferPos = BitPos >>> 3; return Val; } private int Get_Bits(int n) { return popBits(n); } /* align to start of next next_start_code */ private void next_start_code() { skipBits((8 - (BitPos & 7)) & 7); while (showBits(24) != 1) skipBits(8); } // ISO/IEC 13818-2 sections 6.3.4.1 and 6.2.2.2.2 private void user_data() { skipBits(32); while (popBits(24) != 0x000001) { skipBits(8); } } /* decode picture coding extension */ private int search_picture_structure() { // f_code:4[2][2]; // int intra_dc_precision:2 skipBits(18); int picture_structure = popBits(2); skipBits(8); int progressive_frame = popBits(1); if (progressive_frame == 1) { return FRAME_PICTURE; } return picture_structure; } /* decode extension and user data */ /* ISO/IEC 13818-2 section 6.2.2.2 */ private int find_picture_structure() { int code; next_start_code(); while ((code = showBits(32)) == EXTENSION_START_CODE || code == USER_DATA_START_CODE) { if (code == EXTENSION_START_CODE) { skipBits(32); int ext_ID = popBits(4); switch (ext_ID) { case PICTURE_CODING_EXTENSION_ID: return search_picture_structure(); } } else { user_data(); } next_start_code(); } return FRAME_PICTURE; // not found } public int getPictureStructure(boolean inpIsPicHd) { int tmpStruct = FRAME_PICTURE; try { resetCounters(); tmpStruct = find_picture_structure(); } catch (Exception e) { // maybe ArrayOutOfBounds // e.printStackTrace(); } return tmpStruct; } } project-x/src/net/sourceforge/dvb/projectx/io/IDDBufferedOutputStream.java0000600000175000017500000003754210411343352030351 0ustar supermariosupermario/* * @(#)IDDBufferedOutputStream.java - export * * Copyright (c) 2003-2006 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ /** * cuttermaran info part from Arnaud * */ package net.sourceforge.dvb.projectx.io; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.util.Arrays; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.parser.CommonParsing; public class IDDBufferedOutputStream extends BufferedOutputStream { long pos = 0; int type = 0; String name = ""; String chaptersname = ""; boolean sequenceend = false; boolean chapters = false; boolean CreateAc3Wave = false; boolean CreateDtsWave = false; boolean CreateDts48Wave = false; byte[][] IddHeader = { { (byte)'i', (byte)'d', (byte)'d', 2 }, //video V2 { (byte)'i', (byte)'d', (byte)'d', 3 } //audio V3 }; /** * Lil' endian - header, one frame, length of this frame in bits */ byte[] DD_header = { 0x72, (byte)0xF8, 0x1F, 0x4E, 1, 0, 0, 0 }; byte[] padding_block = null; BufferedOutputStream IddOut = null; PrintWriter ChaptersOut = null; // cminfo ----- BEGIN ----- private String aInfoName = ""; private BufferedOutputStream aInfoOut = null; // --- cminfo --- private boolean aInfoSeqEnd = false; private BitWalker aBitWalker = null; private StringBuffer aStringBuffer = null; // cminfo ------ END ------ int filenumber = 1; /** * */ public IDDBufferedOutputStream(OutputStream out) { super(out); } /** * */ public IDDBufferedOutputStream(OutputStream out, int size) { super(out, size); } /** * */ public synchronized void write(byte b[], int off, int len) throws IOException { switch (type) { case 3: //vdrindex if ((0xF0 & b[off + 3]) != 0xE0) break; for (int a = off + 9 + (0xFF & b[8]), ret; a < off + len - 3; a++) { if ((ret = CommonParsing.validateStartcode(b, a)) < 0) { a += (-ret) - 1; continue; } if (b[a + 3] != 0) { a += 3; continue; } if (a + 5 >= off + len) break; int frametype = (7 & b[a + 5]>>>3); if (frametype == 0 || frametype > 3) break; IddOut.write(VdrIndex()); //pos IddOut.write(frametype); //type IddOut.write(filenumber); IddOut.write(new byte[2]); break; } break; case 1: //idd Video // cminfo ----- BEGIN ----- if (aInfoOut != null) { writeInfo(b, off, len); if (IddOut == null) break; } // cminfo ------ END ------ for (int a = off, ret; a < off + len - 3; a++) { if ((ret = CommonParsing.validateStartcode(b, a)) < 0) { a += (-ret) - 1; continue; } if ((0xFF & b[a + 3]) == 0xB3) { IddOut.write(0xB3); IddOut.write(littleEndian(a - off)); a += 12; } else if ((0xFF & b[a + 3]) == 0xB7) { IddOut.write(0xB7); IddOut.write(littleEndian(a - off)); sequenceend = true; a += 3; } else if ((0xFF & b[a + 3]) == 0xB8) { IddOut.write(0xB8); IddOut.write(littleEndian(a - off)); a += 7; } else if (b[a + 3] == 0) { IddOut.write(0); //type IddOut.write(littleEndian(a - off)); //pos int tref = (3 & b[a + 5]>>>6) | (0xFF & b[a + 4])<<2; IddOut.write(0xFF & tref); IddOut.write(tref>>>8); IddOut.write(7 & b[a + 5]>>>3); //pic a += 8; } } break; case 2: //idd audio if ( !(pos == 0 && b.length <= 0x50)) IddOut.write(littleEndian(0)); } /** * build new frame with header + padding */ if (CreateAc3Wave) { int bitlen = len<<3; DD_header[6] = (byte) (0xFF & bitlen); DD_header[7] = (byte) (0xFF & bitlen>>8); super.write(DD_header, 0, 8); // header pos += 8; Common.changeByteOrder(b, off, len); super.write(b, off, len); // the reversed frame super.write(padding_block, len, padding_block.length - len); // the padding zero's pos += padding_block.length; } /** * build new frame with padding */ else if (CreateDtsWave) { if (CreateDts48Wave) { int len_1 = len > 0x800 ? 0x1000 : 0x800; System.arraycopy(b, off, padding_block, 0, len); //copy frame Arrays.fill(padding_block, len, len_1 + 1, (byte)0); Common.changeByteOrder(padding_block, 0, len_1); super.write(padding_block, 0, len_1); // the reversed frame pos += len_1; } else { int j = 0; long val; for (int i = off, k = off + len; i < k; i += 7, j += 8) { val = CommonParsing.getValue(b, i, 7, !CommonParsing.BYTEREORDERING); padding_block[j] = (byte)(0xFF & val>>42); padding_block[j + 1] = (byte)((byte)(0xFC & val>>48)>>2); padding_block[j + 2] = (byte)(0xFF & val>>28); padding_block[j + 3] = (byte)((byte)(0xFC & val>>34)>>2); padding_block[j + 4] = (byte)(0xFF & val>>14); padding_block[j + 5] = (byte)((byte)(0xFC & val>>20)>>2); padding_block[j + 6] = (byte)(0xFF & val); padding_block[j + 7] = (byte)((byte)(0xFC & val>>6)>>2); } super.write(padding_block, 0, j); // the reversed frame pos += j; } } else { super.write(b, off, len); pos += len; } } /** * */ public synchronized void write(int b) throws IOException { super.write(b); pos++; } /** * */ public byte[] VdrIndex() { byte bpos[] = new byte[4]; for (int a = 0; a < 4; a++) bpos[a] = (byte)(0xFFL & pos>>>(a * 8)); return bpos; } /** * */ public void setWave(boolean b1, boolean b2, boolean b3, int val) throws IOException { if (!b1) return; CreateAc3Wave = b2; CreateDtsWave = b3; CreateDts48Wave = (CreateDtsWave && val > 1411200); if (padding_block == null) padding_block = new byte[0x17F8]; } /** * */ public void InitVdr(String vdrname, int file_number) throws IOException { name = vdrname; filenumber = file_number + 1; type = 3; IddOut = new BufferedOutputStream(new FileOutputStream(name, filenumber == 1 ? false : true), 655350); } /** * */ public String renameVdrTo(String parent, String oldName) { String num = "000" + filenumber + ".vdr"; String newName = parent + num.substring(num.length() - 7); File nname = new File(newName); File oname = new File(oldName); if (!oname.getName().equals(nname.getName()) && nname.exists()) nname.delete(); Common.renameTo(oname, nname); return newName; } /** * */ public byte[] littleEndian(int off) { byte bpos[] = new byte[8]; for (int a = 0; a < 8; a++) bpos[a] = (byte)(0xFFL & (pos + off)>>>(a * 8)); return bpos; } /** * */ public void InitIdd(String iddname, int iddtype) throws IOException { name = iddname + ".id"; type = iddtype; IddOut = new BufferedOutputStream(new FileOutputStream(name), 655350); IddOut.write(IddHeader[type - 1]); } /** * */ public void renameIddTo(File newName) { String str = newName.toString(); File nname = new File(str + ".idd"); File file = new File(str + ".m2s.txt"); if (newName.exists()) { if (nname.exists()) nname.delete(); if (new File(name).exists()) Common.renameTo(new File(name), nname); } else new File(name).delete(); if (chapters) { if (file.exists()) file.delete(); if (new File(chaptersname).exists()) Common.renameTo(new File(chaptersname), file); } } /** * */ public void renameVideoIddTo(String newName) { File nname = new File(newName + ".idd"); if (nname.exists()) nname.delete(); Common.renameTo(new File(name), nname); } /** * */ public void deleteIdd() { new File(name).delete(); new File(chaptersname).delete(); } /** * */ public void InitChapters(String filename) throws IOException { chaptersname = filename + ".chp"; chapters = true; ChaptersOut = new PrintWriter(new FileOutputStream(chaptersname)); } /** * */ public void addChapter(String str) throws IOException { if (!chapters) return; ChaptersOut.println(str); } /** * */ public synchronized void flush() throws IOException { super.flush(); } /** * */ public synchronized void close() throws IOException { if (chapters) { ChaptersOut.flush(); ChaptersOut.close(); } switch (type) { case 1: // cminfo ----- BEGIN ----- if (aInfoOut != null) { closeInfo(); if (IddOut == null) break; } // cminfo ------ END ------ if(!sequenceend) { IddOut.write(0xB7); IddOut.write(littleEndian(0)); } IddOut.flush(); IddOut.close(); IddOut = null; // cminfo break; case 2: IddOut.write(littleEndian(0)); case 3: IddOut.flush(); IddOut.close(); } super.close(); } // cminfo ----- BEGIN ----- /** * @param inpName * @throws IOException */ public void InitInfo(String inpName) throws IOException { aInfoName = inpName + ".info"; type = 1; aInfoOut = new BufferedOutputStream(new FileOutputStream(aInfoName), 655350); // ??? aInfoOut.write((byte)0xEF); aInfoOut.write((byte)0xBB); aInfoOut.write((byte)0xBF); StringBuffer tmpBuf = getStringBuffer(); tmpBuf.setLength(0); tmpBuf.append("1.61"); dumpInfo(tmpBuf); } /** * @param newName */ public void renameVideoInfoTo(String newName) { File nname = new File(newName + ".info"); if (nname.exists()) nname.delete(); Common.renameTo(new File(aInfoName), nname); // 2 Minuten - 120000ms (?) fr CM dazuschummeln ;-) nname.setLastModified(nname.lastModified() + 120000); } private void dumpInfo(StringBuffer inpBuf) throws IOException { int len = (inpBuf == null) ? 0 : inpBuf.length(); for (int i = 0; i < len; i++) // for i aInfoOut.write((byte) inpBuf.charAt(i)); } /** * @throws IOException */ private synchronized void closeInfo() throws IOException { StringBuffer tmpBuf = getStringBuffer(); tmpBuf.setLength(0); if (!aInfoSeqEnd) { tmpBuf.append(""); } tmpBuf.append(""); dumpInfo(tmpBuf); aInfoOut.flush(); aInfoOut.close(); aInfoOut = null; aInfoSeqEnd = false; setBitWalker(null); setStringBuffer(null); } /** * */ public void deleteInfo() { new File(aInfoName).delete(); } /** * Write .info for CM * * @param b * @param off * @param len * @throws IOException */ private synchronized void writeInfo(byte b[], int off, int len) throws IOException { if (aInfoOut == null) return; for (int a = off, ret; a < off + len - 3; a++) { if ((ret = CommonParsing.validateStartcode(b, a)) < 0) { a += (-ret) - 1; continue; } StringBuffer tmpBuf; if ((0xFF & b[a + 3]) == 0xB3) { int ratio = 0xF & b[a + 7] >>> 4; tmpBuf = getStringBuffer(); tmpBuf.setLength(0); tmpBuf.append(""); dumpInfo(tmpBuf); a += 12; } else if ((0xFF & b[a + 3]) == 0xB7) { tmpBuf = getStringBuffer(); tmpBuf.setLength(0); tmpBuf.append(""); dumpInfo(tmpBuf); aInfoSeqEnd = true; a += 3; } else if ((0xFF & b[a + 3]) == 0xB8) { tmpBuf = getStringBuffer(); tmpBuf.setLength(0); tmpBuf.append(""); dumpInfo(tmpBuf); a += 7; } else if (b[a + 3] == 0) { tmpBuf = getStringBuffer(); tmpBuf.setLength(0); tmpBuf.append(">> 6) | (0xFF & b[a + 4]) << 2; tmpBuf.append(" tempRef=\""); tmpBuf.append(tref); tmpBuf.append('\"'); int typ = 7 & b[a + 5] >>> 3; tmpBuf.append(" type=\""); tmpBuf.append(typ); tmpBuf.append('\"'); // picture_structure BitWalker tmpWalker = getBitWalker(); tmpWalker.setBuf(b, a + 3); int struct = tmpWalker.getPictureStructure(true); if (struct != BitWalker.FRAME_PICTURE) { tmpBuf.append(" struct=\""); tmpBuf.append(struct); tmpBuf.append('\"'); } tmpBuf.append(" />"); dumpInfo(tmpBuf); a += 8; } } // for a } private BitWalker getBitWalker() { if (aBitWalker == null) aBitWalker = new BitWalker(); return aBitWalker; } private void setBitWalker(BitWalker inpBitWalker) { aBitWalker = inpBitWalker; } private StringBuffer getStringBuffer() { if (aStringBuffer == null) aStringBuffer = new StringBuffer(); return aStringBuffer; } private void setStringBuffer(StringBuffer inpStringBuffer) { aStringBuffer = inpStringBuffer; } // cminfo ------ END ------ } project-x/src/net/sourceforge/dvb/projectx/io/RawFile.java0000600000175000017500000000426610351106230025232 0ustar supermariosupermario/* * @(#)RawFile.java - raw data extraction * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.io; import java.io.File; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.io.IDDBufferedOutputStream; /** * raw file from pva */ public class RawFile extends Object { IDDBufferedOutputStream out; String name; private RawFile() {} public RawFile(String new_name, int PidToExtract, int buffersize) throws IOException { name = new_name + "_0x" + Integer.toHexString(PidToExtract).toUpperCase() + ".raw"; out = new IDDBufferedOutputStream( new FileOutputStream(name), buffersize); } public void write(byte[] data) throws IOException { out.write(data); } public void write(byte[] data, int offset, int len) throws IOException { out.write(data, offset, len); } public void close() throws IOException { out.flush(); out.close(); if (new File(name).length() < 10) new File(name).delete(); else Common.setMessage(Resource.getString("msg.newfile") + " " + name); } } project-x/src/net/sourceforge/dvb/projectx/io/StandardBuffer.java0000600000175000017500000000346110351106260026572 0ustar supermariosupermario/* * @(#)StandardBuffer.java - temporary buffer of any data * * Copyright (c) 2004-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.io; import java.io.*; public class StandardBuffer extends Object { private ByteArrayOutputStream buf = null; private int id; private int type; public StandardBuffer() { buf = new ByteArrayOutputStream(); id = 0; } public StandardBuffer(int val1) { buf = new ByteArrayOutputStream(); id = val1; } public int getType() { return type; } public void write(byte data[]) throws IOException { buf.write(data); } public void write(byte data[], int offset, int length) throws IOException { buf.write(data, offset, length); } public byte[] getData() throws IOException { buf.flush(); return buf.toByteArray(); } public void reset() { buf.reset(); } } project-x/src/net/sourceforge/dvb/projectx/net/0000700000175000017500000000000010745203152023213 5ustar supermariosupermarioproject-x/src/net/sourceforge/dvb/projectx/net/WebInterface.java0000600000175000017500000002657510357074046026444 0ustar supermariosupermario/* * @(#)WebInterface.java - provides simple remote http access * * Copyright (C) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.net; import java.net.ServerSocket; import java.net.Socket; import java.net.BindException; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.IOException; import java.util.StringTokenizer; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.xinput.XInputFile; public class WebInterface implements Runnable { private Thread thread = null; private long request_number = 0; private String last_request = ""; private String return_string = ""; private String access_string; private boolean isOnline = false; private boolean showLog = false; private ServerSocket serverSocket = null; private Socket connection = null; /** * */ public void run() { Thread myThread = Thread.currentThread(); while (thread == myThread) { if (!runServer()) break; try { Thread.sleep(1000); } catch (InterruptedException e) {} } isOnline = false; showLog = false; } public void start() { if (thread == null) { thread = new Thread(this, "WebIF"); thread.setPriority(Thread.MIN_PRIORITY); thread.start(); Common.setMessage("-> re-/start WebIFServer on Port: " + Common.getSettings().getProperty(Keys.KEY_WebServerPort)); } } /** * */ public void stop() { connection = null; try { if (serverSocket != null) serverSocket.close(); } catch (Exception ie) { } thread = null; System.gc(); Common.setMessage("-> close WebIFServer on Port: " + Common.getSettings().getProperty(Keys.KEY_WebServerPort)); } /** * */ private boolean runServer() { int port_change; int port = -1; try { request_number = 0; while (true) { if ((port_change = getPort()) < 0) return false; if ((access_string = getAccess()) == null) return false; isOnline = true; // init server if (port_change != port) { port = port_change; serverSocket = new ServerSocket(port); } connection = serverSocket.accept(); // awaiting conn. BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream())); request_number++; if (!getRequest(br.readLine(), connection)) //resolve http command return_string = "missing or wrong keyword"; // answer PrintWriter pw = new PrintWriter(connection.getOutputStream()); pw.println(buildSite(return_string)); pw.flush(); connection.close(); } } catch (Exception e) { Common.setMessage("" + e); Common.setMessage("" + e.getMessage(), true); connection = null; try { serverSocket.close(); } catch (Exception ie) { } } System.gc(); return true; } /** * */ private int getPort() { int value = -1; try { value = Common.getSettings().getIntProperty(Keys.KEY_WebServerPort); if (value < 0 || value > 65535) throw new Exception(); } catch (Exception e) { Common.setMessage("!> WebIF: invalid port number: '" + value + "'", true); value = -1; } return value; } /** * */ private String getAccess() { String str = null; try { str = Common.getSettings().getProperty(Keys.KEY_WebServerAccess).trim(); if (str == null || str.length() == 0) throw new Exception(); } catch (Exception e) { Common.setMessage("!> WebIF: invalid access_string: '" + str + "'", true); str = null; } return str; } /** * */ public boolean isOnline() { return isOnline; } /** * */ private String buildSite(String body) { String str = "HTTP/1.0 200 Ok\n" + "Content-type: text/html\n\n" + "" + "\n" + "\n" + "\n" + "ProjectX Status of " + Common.getVersionName() + "/" + Common.getVersionDate() + "\n" + "

ProjectX WebInterface

\n" + "
request# " + request_number + " - " + Common.getVersionName() + " / " + Common.getVersionDate() + " - " + Common.getDateAndTime() + "
" + 
			body + 
			"
"; return str; // "\n" + } /** * */ private boolean getRequest(String str, Socket connection) { last_request = str; // log the msg Common.setMessage("--> request# " + request_number + " from " + connection.getInetAddress().getHostAddress() + " - " + str); return_string = ""; str = str.trim(); int index_GET = str.indexOf("GET /"); // only 'get' cmd accepted if (index_GET >= 3 || index_GET < 0) return false; // only http accepted if (!str.endsWith("HTTP/1.0") && !str.endsWith("HTTP/1.1")) return false; // raw parameters str = str.substring(index_GET + 5, str.indexOf("HTTP/1")); str = str.trim(); // user access string if (!str.startsWith(access_string)) return false; StringTokenizer st = new StringTokenizer(str, "&"); while (st.hasMoreTokens()) getCommand(st.nextToken()); if (showLog) return_string += getLog(); // std answer body return_string += getCollection(); return true; } /** * */ private void getCommand(String str) { if (str.equals("addcoll")) { Common.addCollection(); Common.setActiveCollection(Common.getCollectionListSize() - 1); updateCollectionView(); } else if (str.equals("removecoll")) { if (Common.removeCollection(Common.getActiveCollection())) updateCollectionView(); } else if (str.equals("exit")) Common.exitApplication(0); else if (str.equals("start")) { if (Common.startProcess()) Common.startMainProcess(); } else if (str.equals("stop")) Common.breakMainProcess(); else if (str.equals("getlog")) showLog = true; else if (str.equals("hidelog")) showLog = false; else if (str.equals("filelist")) return_string += getInputFileList(); else if (str.equals("getsettings")) return_string += getSettings(); else if (str.startsWith("addfile")) { JobCollection collection = Common.getCollection(); if (collection != null) { Object[] files = Common.reloadInputDirectories(); int index = Integer.parseInt(str.substring(7)); if (files.length > index) collection.addInputFile(files[index]); } updateCollectionView(); } else if (str.startsWith("removefile")) { JobCollection collection = Common.getCollection(); if (collection != null) collection.removeInputFile(Integer.parseInt(str.substring(10))); updateCollectionView(); } else if (str.startsWith("setcoll")) { Common.setActiveCollection(Integer.parseInt(str.substring(7))); updateCollectionView(); } } /** * */ private void updateCollectionView() { Common.getGuiInterface().showActiveCollection(Common.getActiveCollection()); } /** * */ private String getInputFileList() { String str = ""; Object[] files = Common.reloadInputDirectories(); str += "
List of available files:"; for (int i = 0; i < files.length; i++) str += "
add file " + i + " - " + files[i].toString() + ""; return str; } /** * */ private String getCollection() { String str = ""; //exit str += "
shutdown remote application"; //settings str += "
get current settings"; //status str += "
Process Status: (show message log)"; str += "
" + Common.getProcessedPercent() + "% - " + Common.getStatusString(); str += "
start processing"; str += " / stop processing"; //collection str += "
Collection access:"; str += "
active Collection: " + Common.getActiveCollection() + ""; str += "
remove active Collection"; str += " / add new Collection"; str += "
choose other Collection:"; for (int i = 0, j = Common.getCollectionListSize(); i < j; i++) str += " " + i + ""; JobCollection collection = Common.getCollection(); if (collection != null) { str += "
Infos:\n"; str += "Output to: '" + collection.getOutputDirectory() + "'\n"; str += collection.getShortSummary(); str += getCollectionFiles(collection); } return str; } /** * */ private String getCollectionFiles(JobCollection collection) { String str = ""; Object[] files = collection.getInputFiles(); str += "
Content: add file from fixed directories"; for (int i = 0; i < files.length; i++) { str += "
" + i + " - " + files[i].toString() + " remove"; str += "
    " + ((XInputFile)files[i]).getStreamInfo().getFullInfo() + "
"; } return str; } /** * */ private String getLog() { String str = ""; //status str += "
current processing log: (hide message log) (refresh log)"; str += "
" + Common.getMessageLog(); return str; } /** * */ private String getSettings() { String str = ""; String line; //settings str += "
current settings: (hide settings)"; try { BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(Common.getSettings().storeProperties()))); while ((line = br.readLine()) != null) str += "
" + line; } catch (IOException e) { } return str; } }project-x/src/net/sourceforge/dvb/projectx/parser/0000700000175000017500000000000010745203152023721 5ustar supermariosupermarioproject-x/src/net/sourceforge/dvb/projectx/parser/CommonParsing.java0000600000175000017500000007054710411411650027351 0ustar supermariosupermario/* * @(#)CommonParsing * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.IOException; import java.io.File; import java.io.RandomAccessFile; import java.io.PrintWriter; import java.io.FileOutputStream; import java.util.Calendar; import java.util.TimeZone; import java.util.Date; import java.util.StringTokenizer; import java.util.ArrayList; import java.util.List; import java.text.DateFormat; import java.text.SimpleDateFormat; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Settings; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobProcessing; /** * common stuff for parsing functions */ public class CommonParsing extends Object { public final static boolean BYTEREORDERING = true; public final static int SECONDARY_PES_PARSER = 0; public final static int PRIMARY_PES_PARSER = 1; public final static int TS_PARSER = 2; public final static int PVA_PARSER = 3; public final static int ES_VIDEO_PARSER = 4; public final static int ES_AUDIO_PARSER = 5; public final static int ES_SUBPICTURE_PARSER = 6; public final static int Unsupported = 0; // "unsupported" public final static int PES_AV_TYPE = 1; // "PES (Video/Audio/TTX)" public final static int MPEG1PS_TYPE = 2; // "MPEG-1 PS/SS (Video/Audio PES)" public final static int MPEG2PS_TYPE = 3; // "MPEG-2 PS/SS (Video/Audio PES)" public final static int PVA_TYPE = 4; // "PVA (Video/Audio PES)" public final static int TS_TYPE = 5; // "DVB/MPEG2 TS" public final static int PES_MPA_TYPE = 6; // "PES (MPEG Audio)" public final static int PES_PS1_TYPE = 7; // "PES (private stream 1)" public final static int ES_MPV_TYPE = 8; // "ES (MPEG Video)" public final static int ES_MPA_TYPE = 9; // "ES (MPEG Audio)" public final static int ES_AC3_TYPE = 10; // "ES (AC-3 Audio)" public final static int ES_AC3_A_TYPE = 11; // "ES (AC-3 Audio) (psb. SMPTE)" public final static int ES_DTS_TYPE = 12; // "ES (DTS Audio)" public final static int ES_DTS_A_TYPE = 13; // "ES (DTS Audio) (psb. SMPTE)" public final static int ES_RIFF_TYPE = 14; // "ES (RIFF Audio)" public final static int ES_cRIFF_TYPE = 15; // "ES (compressed RIFF Audio)" public final static int ES_SUP_TYPE = 16; // "ES (Subpicture 2-bit RLE)" public final static int ES_TYPE = 1; // "ElementaryStream" // "ElementaryStream" public final static int UNKNOWN = -1; public final static int AC3_AUDIO = 0; public final static int TELETEXT = 1; public final static int MPEG_AUDIO = 2; public final static int MPEG_VIDEO = 3; public final static int LPCM_AUDIO = 4; public final static int SUBPICTURE = 5; public final static int DTS_AUDIO = 6; //handled with in AC3_AUDIO so far public final static int WAV_AUDIO = 7; public final static int ACTION_DEMUX = 0; public final static int ACTION_TO_VDR = 1; public final static int ACTION_TO_M2P = 2; public final static int ACTION_TO_PVA = 3; public final static int ACTION_TO_TS = 4; public final static int ACTION_FILTER = 5; public final static int CUTMODE_BYTE = 0; public final static int CUTMODE_GOP = 1; public final static int CUTMODE_FRAME = 2; public final static int CUTMODE_PTS = 3; public final static int CUTMODE_TIME = 4; public final static int PICTURE_START_CODE = 0; public final static int SLICE_START_CODE_MIN = 1; public final static int SLICE_START_CODE_MAX = 0xAF; public final static int USER_DATA_START_CODE = 0xB2; public final static int SEQUENCE_HEADER_CODE = 0xB3; public final static int EXTENSION_START_CODE = 0xB5; public final static int SEQUENCE_END_CODE = 0xB7; public final static int GROUP_START_CODE = 0xB8; public final static int SYSTEM_END_CODE = 0xB9; public final static int PACK_START_CODE = 0xBA; public final static int SYSTEM_START_CODE = 0xBB; public final static int PROGRAM_STREAM_MAP_CODE= 0xBC; public final static int PRIVATE_STREAM_1_CODE = 0xBD; public final static int PADDING_STREAM_CODE = 0xBE; public final static int PRIVATE_STREAM_2_CODE = 0xBF; public final static int ECM_STREAM_CODE = 0xF0; public final static int EMM_STREAM_CODE = 0xF1; public final static int DSM_CC_STREAM_CODE = 0xF2; public final static int FRAME_I_TYPE = 1; public final static int FRAME_P_TYPE = 2; public final static int FRAME_B_TYPE = 3; public final static int FRAME_D_TYPE = 4; public final static int MAX_BITRATE_VALUE = 262143; //3FFFF *400 = 104857200 bps private static int Pva_PidToExtract = -1; private static boolean Pva_PidExtraction = false; private static boolean InfoScan = false; private static boolean qbreak = false; private static boolean qpause = false; private static boolean _bool = false; private static int _cutcount = 0; private static double _videoframerate = 3600.0; private static long AudioProcessingFlags = 0; private CommonParsing() {} /** * */ public static boolean isInfoScan() { return InfoScan; } /** * */ public static void setInfoScan(boolean b) { InfoScan = b; } /** * */ public static boolean isProcessCancelled() { return qbreak; } /** * */ public static void setProcessCancelled(boolean b) { qbreak = b; } /** * */ public static boolean isProcessPausing() { return qpause; } /** * */ public static void setProcessPausing(boolean b) { qpause = b; } /** * */ public static long getAudioProcessingFlags() { return AudioProcessingFlags; } /** * */ public static void setAudioProcessingFlags(long val) { AudioProcessingFlags = val; } /** * */ public static double getVideoFramerate() { return _videoframerate; } /** * */ public static void setVideoFramerate(double val) { _videoframerate = val; } /** * */ public static int getCutCounter() { return _cutcount; } /** * */ public static void setCutCounter(int val) { _cutcount = val; } /** * */ public static boolean getCutStatus() { return _bool; } /** * */ public static void setCutStatus(boolean b) { _bool = b; } /** * */ public static boolean getPvaPidExtraction() { return Pva_PidExtraction; } /** * */ public static void setPvaPidExtraction(boolean b) { Pva_PidExtraction = b; } /** * */ public static int getPvaPidToExtract() { return Pva_PidToExtract; } /** * */ public static void setPvaPidToExtract(int val) { Pva_PidToExtract = val; } /** * returns pts value from pes_extension * * @param1 - source array * @param2 - array offset * @return - pts */ public static long getPTSfromBytes(byte[] array, int offset) { return getPTSfromBytes(array, offset, true); } /** * returns pts value from pes_extension * * @param1 - source array * @param2 - array offset * @param3 - trim to positive 32bit value * @return - pts */ public static long getPTSfromBytes(byte[] array, int offset, boolean trim) { long pts = (6 & array[offset])<<29 | (0xFF & array[offset + 1])<<22 | (0xFE & array[offset + 2])<<14 | (0xFF & array[offset + 3])<<7 | (0xFE & array[offset + 4])>>>1; if (trim) pts &= 0xFFFFFFFFL; return pts; } /** * returns pts value from pes_extension * * @param1 - source array * @param2 - array offset * @param3 - trim to positive 32bit value * @return - pts */ public static long readPTS(byte[] array, int offset, int length, boolean bytereordering, boolean trim) { long value = getValue(array, offset, length, bytereordering); if (trim) value &= 0xFFFFFFFFL; return value; } /** * */ public static void setValue(byte[] array, int offset, int length, boolean bytereordering, long value) { for (int i = 0; bytereordering && i < length; i++) array[i + offset] = (byte)(0xFFL & (value>>>(i * 8))); for (int i = 0, j = length - 1; !bytereordering && i < length; i++, j--) array[i + offset] = (byte)(0xFFL & (value>>>(j * 8))); } /** * returns value * * @param1 - source array * @param2 - array offset * @param3 - * @return - */ public static long getValue(byte[] array, int offset, int length, boolean bytereordering) { long value = 0; for (int i = 0; bytereordering && i < length; i++) value |= (0xFFL & array[i + offset])<<(i * 8); for (int i = 0, j = length - 1; !bytereordering && i < length; i++, j--) value |= (0xFFL & array[i + offset])<<(j * 8); return value; } public static int getIntValue(byte[] array, int offset, int length, boolean bytereordering) { return ((int) getValue(array, offset, length, bytereordering)); } /** * */ public static void setPES_PTSField(byte[] array, int offset, long value) { array[9 + offset] = (byte)(0x21 | (0xE & (value>>>29))); array[10 + offset] = (byte)(0xFF & (value>>>22)); array[11 + offset] = (byte)(1 | (0xFE & (value>>>14))); array[12 + offset] = (byte)(0xFF & (value>>>7)); array[13 + offset] = (byte)(1 | (0xFE & (value<<1))); } /** * */ public static void setPES_LengthField(byte[] array, int offset, int value) { array[4 + offset] = (byte)(0xFF & value>>>8); array[5 + offset] = (byte)(0xFF & value); } /** * */ public static void setPES_IdField(byte[] array, int offset, int value) { array[3 + offset] = (byte)(0xFF & value); } /** * */ public static void setPES_SubIdField(byte[] array, int offset, int pes_headerlength, int pes_extensionlength, int value) { array[pes_headerlength + pes_extensionlength + offset] = (byte)(0xFF & value); } /** * */ public static int getPES_LengthField(byte[] array, int offset) { int value = (0xFF & array[4 + offset])<<8 | (0xFF & array[5 + offset]); return value; } /** * */ public static int getPES_IdField(byte[] array, int offset) { int value = 0xFF & array[3 + offset]; return value; } /** * */ public static int getPES_ExtensionLengthField(byte[] array, int offset) { int value = 0xFF & array[8 + offset]; return value; } /** * */ public static boolean clearBit33ofPTS(byte[] array, int offset) { if ((0x80 & array[7 + offset]) != 0) { array[9 + offset] &= ~8; return true; } return false; } /** * */ public static boolean clearBit33ofDTS(byte[] array, int offset) { if ((0x40 & array[7 + offset]) != 0) { array[9 + 5 + offset] &= ~8; return true; } return false; } /** * */ public static int nextBits(byte buffer[], int BitPos, int N) { int Pos, Val; Pos = BitPos>>>3; Val = (0xFF & buffer[Pos])<<24 | (0xFF & buffer[Pos + 1])<<16 | (0xFF & buffer[Pos + 2])<<8 | (0xFF & buffer[Pos + 3]); Val <<= BitPos & 7; Val >>>= 32-N; return Val; } /** * check startcode * return int of skip'able data (negative) */ public static int validateStartcode(byte[] pes_packet, int offset) { if (pes_packet[2 + offset] == 1) { if (pes_packet[1 + offset] == 0) if (pes_packet[offset] == 0) return 0; } else if (pes_packet[2 + offset] == 0) { if (pes_packet[1 + offset] == 0) return -1; else return -2; } return -3; } /** * skip leading bytes before first valid startcodes and return fixed array */ public static boolean alignSyncword(byte[] pes_packet, int pes_offset, int es_streamtype) { int pes_payloadlength = getPES_LengthField(pes_packet, pes_offset); int pes_headerlength = 9; int pes_packetlength = pes_headerlength - 3 + pes_payloadlength; int pes_extensionlength = getPES_ExtensionLengthField(pes_packet, pes_offset); int offset = pes_headerlength + pes_extensionlength; int i, j, k; boolean found = false; packloop: for (i = offset, j = pes_packetlength - 3, k = offset + pes_offset; i < j; i++, k++) { switch (es_streamtype) { case MPEG_VIDEO: if (pes_packet[k] != 0 || pes_packet[1 + k] != 0 || pes_packet[2 + k] != 1 || pes_packet[3 + k] != (byte)SEQUENCE_HEADER_CODE) continue packloop; found = true; break packloop; case AC3_AUDIO: case DTS_AUDIO: if ((pes_packet[k] != 0xB || pes_packet[1 + k] != 0x77) && (pes_packet[k] != 0x7F || pes_packet[1 + k] != (byte)0xFE || pes_packet[2 + k] != (byte)0x80 || pes_packet[3 + k] != 1)) continue packloop; found = true; break packloop; case MPEG_AUDIO: if ( pes_packet[k] != (byte)0xFF || (0xF0 & pes_packet[1 + k]) != 0xF0) continue packloop; found = true; break packloop; } } if (found) { System.arraycopy(pes_packet, i + pes_offset, pes_packet, offset + pes_offset, pes_packetlength - i); pes_payloadlength -= (i - offset); setPES_LengthField(pes_packet, pes_offset, pes_payloadlength); } return found; } /** * create PTS alias */ public static void logAlias(JobProcessing job_processing, String _vptslog, String _datalog) { File vpts = new File(_vptslog); try { RandomAccessFile log = new RandomAccessFile(_datalog, "rw"); log.seek(0); if (vpts.exists() && vpts.length() > 0) { RandomAccessFile vlog = new RandomAccessFile(_vptslog, "r"); long p = vlog.readLong(); if (!job_processing.hasElementaryVideoStream() && job_processing.getSplitPart() == 0) job_processing.setFirstAudioPts(p); log.writeLong(job_processing.getFirstAudioPts() + (Common.getSettings().getBooleanProperty(Keys.KEY_additionalOffset) ? 90L * Common.getSettings().getIntProperty(Keys.KEY_ExportPanel_additionalOffset_Value) : 0)); vlog.close(); } else log.writeLong(0L + (Common.getSettings().getBooleanProperty(Keys.KEY_additionalOffset) ? Common.getSettings().getIntProperty(Keys.KEY_ExportPanel_additionalOffset_Value) : 0)); log.writeLong(0L); log.close(); Common.setMessage(""); Common.setMessage(Resource.getString("all.msg.pts.faked")); } catch (IOException e) { Common.setExceptionMessage(e); } } /** * split reset */ public static void resetSplitMode(JobProcessing job_processing, String vptslog) { if ( vptslog.equals("-1") && job_processing.getSplitSize() > 0 ) { job_processing.setSplitSize(0); Common.setMessage(Resource.getString("splitreset.novideo")); } } /** * parse cut long value */ public static String parseCutValue(long value) { if (Common.getSettings().getIntProperty(Keys.KEY_CutMode) != CUTMODE_TIME) return String.valueOf(value); String str = ""; long frametime = 1; value /= 90; DateFormat time = new SimpleDateFormat("H:mm:ss:"); time.setTimeZone(TimeZone.getTimeZone("GMT+0:00")); Calendar cal = Calendar.getInstance(); cal.setTimeZone(TimeZone.getTimeZone("GMT+0:00")); cal.setTime(new Date(value)); int frame = (cal.get(14) / ((int)frametime)); str = time.format(new Date(value)) + (frame < 10 ? "0" : "") + frame; return str; } /** * parse cut field value */ public static long parseCutValue(String value, boolean demux) { if (value == null) return 0; value = value.trim(); try { if (Common.getSettings().getIntProperty(Keys.KEY_CutMode) != CUTMODE_TIME) return Long.parseLong(value); } catch (Exception e) { return -1L; } int i; if ( (i = value.indexOf(" ")) > -1) value = value.substring(0, i); value = value.replace('.',':'); if (value.indexOf(":") < 0) return Long.parseLong(value); StringTokenizer st = new StringTokenizer(value, ":"); String str = null; long val = 0; long frametime = !demux ? 90 : (long)_videoframerate; long mp[] = { 324000000L, 5400000L, 90000L, frametime }; //h,m,s,f for (int a=0; st.hasMoreTokens() && a < 4; a++) { str = st.nextToken(); val += (mp[a] * Long.parseLong(str)); } return val; } /** * video timelength read from ptslogfile */ public static long calcVideoTime(String logfile) { long vtime = 0; try { long vlogsize = new File(logfile).length(); RandomAccessFile vlog = new RandomAccessFile(logfile, "r"); vlog.seek(vlogsize - 8); vtime = vlog.readLong(); vlog.close(); } catch (IOException e) { Common.setExceptionMessage(e); } return vtime; } /** * make cut */ public static boolean makecut(JobProcessing job_processing, long comparePoint, List ctemp) { return makecut(job_processing, null, 0, comparePoint, new ArrayList(), 0, ctemp, 0, new ArrayList()); } /** * make cut */ public static boolean makecut(JobProcessing job_processing, String cuts_filename, long startPTS, long comparePoint, List newcut, int lastframes, List ctemp, int gopnumber, List cell) { if (ctemp.isEmpty()) return true; long[] abc; if ( _cutcount < ctemp.size() ) { if ( comparePoint > parseCutValue(ctemp.get(_cutcount).toString(), true) ) { /** * ungerade == cutout */ if ((_cutcount & 1) == 1) { _bool = false; for (int c = newcut.size() - 1; c >- 1; c--) { abc = (long[])newcut.get(c); if ( abc[0] < parseCutValue(ctemp.get(_cutcount).toString(), true) ) { _bool = true; Common.setMessage(Resource.getString("msg.cuts.cutin", "" + gopnumber, "" + lastframes, "" + Common.formatTime_1((long)(lastframes * (double)(_videoframerate / 90.0f)) )) + " (" + comparePoint + ")"); saveCuts(comparePoint, startPTS, lastframes, cuts_filename); // if (lastframes > 0) // cell.add("" + lastframes); // celltimes for cutin break; } } if (!_bool) { Common.setMessage(Resource.getString("msg.cuts.cutout", "" + gopnumber) + " (" + comparePoint + ")"); saveCuts(comparePoint, startPTS, lastframes, cuts_filename); } _cutcount++; return _bool; } /** * gerade == cutin */ else { _bool = true; _cutcount++; Common.setMessage(Resource.getString("msg.cuts.cutin", "" + gopnumber, "" + lastframes, "" + Common.formatTime_1((long)(lastframes * (double)(_videoframerate / 90.0f)) )) + " (" + comparePoint + ")"); saveCuts(comparePoint, startPTS, lastframes, cuts_filename); // if (lastframes > 0) // cell.add("" + lastframes); // celltimes for cutin if (_cutcount >= ctemp.size()) return _bool; for (int c = newcut.size() - 1; c >- 1; c--) { abc = (long[])newcut.get(c); if ( abc[0] < parseCutValue(ctemp.get(_cutcount).toString(), true) ) { _cutcount++; break; } } return _bool; } } } else { if (!_bool && job_processing.getCutComparePoint() == 10000000) job_processing.setCutComparePoint(comparePoint); } return _bool; } /** * saves the cutpoint list from coll specials */ private static void saveCuts(long cutposition, long startPTS, long lastframes, String cuts_filename) { if ( Common.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_exportPts) && cuts_filename != null) { try { cuts_filename += ".Xpl"; PrintWriter pts_writer = new PrintWriter(new FileOutputStream(cuts_filename, lastframes > 0)); if (new File(cuts_filename).length() == 0) pts_writer.println(Keys.KEY_CutMode[0] + "=3"); // PTS cut mode fixed for file pts_writer.println(startPTS); pts_writer.close(); Common.setMessage(Resource.getString("msg.savecut", "" + startPTS)); } catch (IOException e) { Common.setExceptionMessage(e); } } } /** * set 1. videoheader */ public static void setVideoHeader(JobProcessing job_processing, String videofile, String logfile, int[] clv, int[] MPGVideotype) { long time = 0; String videotype[] = { "(m1v)", "(m2v)" }; String frames_used[] = { Resource.getString("video.msg.io.non"), Resource.getString("video.msg.io.int"), Resource.getString("video.msg.io.pro"), Resource.getString("video.msg.io.int_pro") }; if (new File(logfile).exists()) { time = (calcVideoTime(logfile) / 90); String vt = Common.formatTime_1( time / 10 * 10 ); Common.setMessage(Resource.getString("video.msg.length", "" + job_processing.getExportedVideoFrameNumber()) + " " + vt); Common.setMessage(Resource.getString("video.msg.gop.summary", "" + (0x7FFF & clv[9]>>>15), "" + (0x7FFF & clv[9]), "" + frames_used[clv[9]>>>30])); if (clv[8] > 0) Common.setMessage(Resource.getString("video.error.pts.same", "" + clv[8])); job_processing.getSummaryInfo().add(Resource.getString("video.summary", videotype[MPGVideotype[0]], "" + job_processing.getExportedVideoFrameNumber(), "" + vt) + "'" + videofile + "'"); } try { RandomAccessFile pv2 = new RandomAccessFile(videofile, "rw"); if (Common.getSettings().getIntProperty(Keys.KEY_ChangeBitrateInAllSequences) > 0) { if (time == 0) Common.setMessage(Resource.getString("video.msg.bitrate.avg", "" + ((job_processing.getMinBitrate() + job_processing.getMaxBitrate()) / 2 * 400), "" + (job_processing.getMinBitrate() * 400) + "/" + (job_processing.getMaxBitrate() * 400))); else Common.setMessage(Resource.getString("video.msg.bitrate.avgnom", "" + ((pv2.length() * 8000L) / time), "" + (job_processing.getMinBitrate() * 400) + "/" + (job_processing.getMaxBitrate() * 400))); } else if (Common.getSettings().getBooleanProperty(Keys.KEY_DebugLog)) System.out.println(); if (!Common.getSettings().getBooleanProperty(Keys.KEY_WriteOptions_writeVideo)) { pv2.close(); return; } int max_bitrate_value = 22500; // 9.0Mbit, (video only) /** * bitraten */ if (Common.getSettings().getIntProperty(Keys.KEY_ChangeBitrateInFirstSequence) > 0) { int newmux = (Common.getSettings().getIntProperty(Keys.KEY_ChangeBitrateInFirstSequence) == 3) ? job_processing.getMaxBitrate() : max_bitrate_value; if (Common.getSettings().getIntProperty(Keys.KEY_ChangeBitrateInFirstSequence) == 2 && job_processing.getMaxBitrate() < max_bitrate_value) newmux = job_processing.getMaxBitrate(); if (Common.getSettings().getIntProperty(Keys.KEY_ChangeBitrateInFirstSequence) == 1) { if (time == 0) newmux = (job_processing.getMinBitrate() + job_processing.getMaxBitrate()) / 2; // old calcul. avg. else { newmux = (int)(((pv2.length() * 8000L) / time) / 400); if (newmux < 0 || newmux > max_bitrate_value) newmux = (job_processing.getMinBitrate() + job_processing.getMaxBitrate()) / 2; // old calcul. avg. } } if (Common.getSettings().getIntProperty(Keys.KEY_ChangeBitrateInFirstSequence) == 4) { newmux = 0x3FFFF; Common.setMessage(Resource.getString("video.msg.bitrate.vbr")); } else Common.setMessage(Resource.getString("video.msg.bitrate.val", "" + (newmux*400))); pv2.seek(8); newmux = (newmux<<14) | ((pv2.readInt()<<18)>>>18); pv2.seek(8); pv2.writeInt(newmux); } /** * patch resolution DVD-conform */ //JLA14082003+ //0: no patch, 1:patch unconditionally, 2:patch if <>720|352, 3:pach if <>720|704|352 if (Common.getSettings().getIntProperty(Keys.KEY_ConditionalHorizontalPatch) != 0) { pv2.seek(4); int resolutionOrig = pv2.readInt(); int hresOrg = (resolutionOrig>>>20); int resolution = (0xFFFFF & resolutionOrig) | Common.getSettings().getIntProperty(Keys.KEY_ConditionalHorizontalResolution)<<20; boolean doPatch; switch (Common.getSettings().getIntProperty(Keys.KEY_ConditionalHorizontalPatch)) { case 2: doPatch = hresOrg != 720 && hresOrg != 352; break; case 3: doPatch = hresOrg != 720 && hresOrg != 704 && hresOrg != 352; break; default: doPatch = true; } if(doPatch) { pv2.seek(4); pv2.writeInt(resolution); Common.setMessage(Resource.getString("video.msg.resolution", "" + (resolutionOrig>>>20)+"*"+((0xFFF00&resolutionOrig)>>>8)) + " " + (resolution>>>20)+"*"+((0xFFF00&resolution)>>>8)); } } //JLA14082003- pv2.close(); Common.setMessage(Resource.getString("msg.newfile") + " " + videofile); } catch (IOException e) { Common.setExceptionMessage(e); } } /** * vdr_dvbsub determination */ public static int getExtension2_Id(byte[] pes_packet, int pes_headerlength, int pes_payloadlength, int pesID, boolean pes_isMpeg2, long file_position) { boolean extension_error = false; int pes_extension2_id = -1; if (!pes_isMpeg2) return pes_extension2_id; else if (pesID != PRIVATE_STREAM_1_CODE && (0xE0 & pesID) != 0xC0 && (0xF0 & pesID) != 0xE0) //not pD, Aud, Vid return pes_extension2_id; //read flags int pes_shift = pes_headerlength; //points to 1st appendix pes_shift += (0x80 & pes_packet[7]) != 0 ? 5 : 0; //pes_pts pes_shift += (0x40 & pes_packet[7]) != 0 ? 5 : 0; //pes_dts pes_shift += (0x20 & pes_packet[7]) != 0 ? 6 : 0; //pes_escr pes_shift += (0x10 & pes_packet[7]) != 0 ? 3 : 0; //pes_esrate pes_shift += (4 & pes_packet[7]) != 0 ? 1 : 0; //pes_copy pes_shift += (2 & pes_packet[7]) != 0 ? 2 : 0; //pes_crc boolean pes_ext1 = (1 & pes_packet[7]) != 0; //ext1 boolean pes_ext2 = false; //ext2 int pes_extension_length = 0xFF & pes_packet[8]; //all data must be inside extension if (pes_headerlength + pes_extension_length < pes_shift) extension_error = true; else if (pes_ext1 && pes_headerlength + pes_extension_length < pes_shift + 1) extension_error = true; else if (pes_ext1) { int shift = pes_shift; if (6 + pes_payloadlength < pes_shift + 1) extension_error = true; else { pes_shift += (0x80 & pes_packet[shift]) != 0 ? 16 : 0; //pes_private pes_shift += (0x40 & pes_packet[shift]) != 0 ? 1 : 0; //pes_packfield pes_shift += (0x20 & pes_packet[shift]) != 0 ? 2 : 0; //pes_sequ_counter pes_shift += (0x10 & pes_packet[shift]) != 0 ? 2 : 0; //pes_P-STD // marker 3 bits pes_ext2 = (1 & pes_packet[shift]) != 0; //ext2 pes_shift++; //skip flag_fields of ext1 if (pes_headerlength + pes_extension_length < pes_shift) extension_error = true; else if (pes_ext2) { int pes_ext2_length = 0x7F & pes_packet[pes_shift]; pes_shift++; //skip length_fields of ext2 if (6 + pes_payloadlength < pes_shift + pes_ext2_length) extension_error = true; else if (pes_headerlength + pes_extension_length < pes_shift + pes_ext2_length) extension_error = true; else if (pesID == PRIVATE_STREAM_1_CODE) pes_extension2_id = 0xFF & pes_packet[pes_shift]; //read byte0 (res.) of ext2 } } } if (extension_error) Common.setMessage("!> error in pes_extension of pes-ID 0x" + Integer.toHexString(pesID).toUpperCase() + " @ pos: " + file_position + " (" + (6 + pes_payloadlength) + " / " + (pes_headerlength + pes_extension_length) + " / " + (pes_shift + 1) + " / " + pes_ext1 + " / " + pes_ext2 + ")"); return pes_extension2_id; } }project-x/src/net/sourceforge/dvb/projectx/parser/Gop.java0000600000175000017500000011762110404445030025316 0ustar supermariosupermario/* * @(#)Gop * * Copyright (c) 2005-2006 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.IOException; import java.io.DataOutputStream; import java.io.FileOutputStream; import java.io.ByteArrayOutputStream; import java.util.Arrays; import java.util.ArrayList; import java.util.List; import java.util.Date; import java.util.Calendar; import java.util.TimeZone; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.video.Video; import net.sourceforge.dvb.projectx.io.IDDBufferedOutputStream; import net.sourceforge.dvb.projectx.thirdparty.D2V; /** * placeholder for future class */ public class Gop extends Object { private byte[] headerrescue = new byte[1]; private long VbvBuffer_Value = 0; private boolean Debug; private boolean CreateD2vIndex; private boolean SplitProjectFile; private boolean AddSequenceHeader; private boolean Message_3; private boolean AddSequenceDisplayExension; private boolean PatchToProgressive; private boolean PatchToInterlaced; private boolean ToggleFieldorder; private boolean ClearCDF; private boolean Save1stFrameOfGop; private boolean Preview_AllGops; private boolean Preview_fastDecode; private boolean TrimPts; private boolean IgnoreErrors; private boolean OptionDAR; private boolean OptionHorizontalResolution; private boolean WriteVideo; private boolean InsertEndcode; private boolean DumpDroppedGop; private int ChangeBitrateInAllSequences; private int ChangeVbvDelay; private int CutMode; private int ExportDAR; private int ChangeAspectRatio; private int ChangeVbvBuffer; private String ExportHorizontalResolution; private String SDE_Value; private JobProcessing job_processing; public Gop(JobCollection collection) { getSettings(collection); } private void getSettings(JobCollection collection) { Debug = collection.getSettings().getBooleanProperty(Keys.KEY_DebugLog); CreateD2vIndex = collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createD2vIndex); SplitProjectFile = collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_splitProjectFile); AddSequenceHeader = collection.getSettings().getBooleanProperty(Keys.KEY_VideoPanel_addSequenceHeader); Message_3 = collection.getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg3); AddSequenceDisplayExension = collection.getSettings().getBooleanProperty(Keys.KEY_VideoPanel_addSde); PatchToProgressive = collection.getSettings().getBooleanProperty(Keys.KEY_VideoPanel_patchToProgressive); PatchToInterlaced = collection.getSettings().getBooleanProperty(Keys.KEY_VideoPanel_patchToInterlaced); ToggleFieldorder = collection.getSettings().getBooleanProperty(Keys.KEY_VideoPanel_toggleFieldorder); ClearCDF = collection.getSettings().getBooleanProperty(Keys.KEY_VideoPanel_clearCDF); Save1stFrameOfGop = collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_save1stFrameOfGop); Preview_AllGops = collection.getSettings().getBooleanProperty(Keys.KEY_Preview_AllGops); Preview_fastDecode = collection.getSettings().getBooleanProperty(Keys.KEY_Preview_fastDecode); TrimPts = collection.getSettings().getBooleanProperty(Keys.KEY_Video_trimPts); IgnoreErrors = collection.getSettings().getBooleanProperty(Keys.KEY_Video_ignoreErrors); OptionDAR = collection.getSettings().getBooleanProperty(Keys.KEY_OptionDAR); OptionHorizontalResolution = collection.getSettings().getBooleanProperty(Keys.KEY_OptionHorizontalResolution); WriteVideo = collection.getSettings().getBooleanProperty(Keys.KEY_WriteOptions_writeVideo); InsertEndcode = collection.getSettings().getBooleanProperty(Keys.KEY_VideoPanel_insertEndcode); DumpDroppedGop = collection.getSettings().getBooleanProperty(Keys.KEY_dumpDroppedGop); ChangeBitrateInAllSequences = collection.getSettings().getIntProperty(Keys.KEY_ChangeBitrateInAllSequences); ChangeVbvDelay = collection.getSettings().getIntProperty(Keys.KEY_ChangeVbvDelay); CutMode = collection.getSettings().getIntProperty(Keys.KEY_CutMode); ExportDAR = collection.getSettings().getIntProperty(Keys.KEY_ExportDAR); ChangeAspectRatio = collection.getSettings().getIntProperty(Keys.KEY_ChangeAspectRatio); ChangeVbvBuffer = collection.getSettings().getIntProperty(Keys.KEY_ChangeVbvBuffer); ExportHorizontalResolution = collection.getSettings().getProperty(Keys.KEY_ExportHorizontalResolution); SDE_Value = collection.getSettings().getProperty(Keys.KEY_VideoPanel_SdeValue); } /** * gop dropp */ private void messageDropError(byte[] gop, byte[] pts, int maxtref, int frame, int gop_number, int frame_number, long startpts, long lastpts, String dumpname, int errorcode) { Common.setMessage(Resource.getString("video.msg.error.gop.drop", String.valueOf(gop_number - 1), Common.formatTime_1(startpts / 90L), String.valueOf(startpts)) + ", errorcode: " + Integer.toHexString(errorcode).toUpperCase()); Common.setMessage(Resource.getString("video.msg.error.gop.diff", String.valueOf(maxtref + 1) + "/" + (frame + 1), String.valueOf((lastpts - startpts) / 90)) + " " + Common.formatTime_1((long)(frame_number * (double)(CommonParsing.getVideoFramerate() / 90.0f) ))); /** * dump dropped gop to file */ if (DumpDroppedGop) { String gopdumpname = dumpname + "-GOP#" + (gop_number - 1) + ".bin"; byte[] dumpfill = new byte[16]; Arrays.fill(dumpfill, (byte)0xFF); try { DataOutputStream dump = new DataOutputStream(new FileOutputStream(gopdumpname)); dump.writeInt(gop_number - 1); dump.writeInt(maxtref); dump.writeInt(frame); dump.write(dumpfill, 0, 4); dump.write(pts); dump.write(dumpfill); dump.write(gop); dump.write(Video.getSequenceEndCode()); dump.flush(); dump.close(); Common.setMessage(Resource.getString("video.msg.error.gop.dump") + " " + dumpname); } catch (IOException e) { Common.setExceptionMessage(e); } } } /** * gop changing/testing */ public void goptest(JobProcessing job_processing, IDDBufferedOutputStream video_sequence, byte[] gop, byte[] pts, DataOutputStream log, String dumpname, int[] MPGVideotype, List CutpointList, List ChapterpointList) { goptest(job_processing, video_sequence, gop, pts, log, dumpname, MPGVideotype, CutpointList, ChapterpointList, true); } /** * gop changing/testing */ public void goptest(JobProcessing job_processing, IDDBufferedOutputStream video_sequence, byte[] gop, byte[] pts, DataOutputStream log, String dumpname, int[] MPGVideotype, List CutpointList, List ChapterpointList, boolean doWrite) { int[] clv = job_processing.getStatusVariables(); int ErrorCode = 0; String[] VBASIC = job_processing.getStatusStrings(); Common.setFps(job_processing.getSourceVideoFrameNumber()); if (gop.length < 12) { Common.setMessage(Resource.getString("video.msg.error.lackofdata", String.valueOf(clv[6]))); return; } if (pts.length == 0) { double npts = 0; double thisTC = 0; double diff = 0; double ref = 0; int p = 0; for (int i = 0, returncode, pes_ID; i < gop.length - 7; ) { if ((returncode = CommonParsing.validateStartcode(gop, i)) < 0) { i += (-returncode); continue; } pes_ID = CommonParsing.getPES_IdField(gop, i); if (pes_ID == CommonParsing.GROUP_START_CODE) { /** options[8] ist ende PTS vom letzten GOP = beginn dieses Gop wie bei ttx die diff merken zw. PTS und TC zu beginn, dann vergleichen und startpts neu setzen, NUR wenn TC genau past zur erwarteten PTS, dann nehm wa den (TC 0 was dann) **/ thisTC = 90.0 * (3600000.0 * ((0x7C & gop[i + 4])>>>2) + 60000.0 * ((3 & gop[i + 4])<<4 | (0xF0 & gop[i + 5])>>>4) + 1000.0 * ((7 & gop[i + 5])<<3 | (0xE0 & gop[i + 6])>>>5) + (((0x1F & gop[i + 6])<<1 | (0x80 & gop[i + 7])>>>7) * (CommonParsing.getVideoFramerate() / 90.0f)) ); i += 7; } else if (pes_ID == CommonParsing.PICTURE_START_CODE) { p = i; ref = CommonParsing.getVideoFramerate() * ((0xFF & gop[i + 4])<<2 | (0xC0 & gop[i + 5])>>>6); npts = ref + job_processing.getEndPtsOfGop(); break; } else i += 4; } diff = thisTC - job_processing.getLastGopTimecode(); // TC diff >=0ms <5min if (diff >= 0 && diff < 27000000) { npts = job_processing.getLastGopPts() + diff + ref; Common.setMessage(Resource.getString("video.msg.error.nopts.use_goptc", "" + clv[6])); } else Common.setMessage(Resource.getString("video.msg.error.nopts.use_lastpts", "" + clv[6])); pts = new byte[16]; for (int i = 0; i < 8; i++) { pts[7 - i] = (byte)(0xFF & (long)npts>>>(i * 8)); pts[15 - i] = (byte)(0xFF & (long)p>>>(i * 8)); } job_processing.setLastGopTimecode((long)thisTC); } /* vpts[0] = pts, vpts[1] = for next frame following this byteposition in sequ_array */ long[][] vpts = new long[2][pts.length/16]; for (int i = 0; i < (pts.length / 16); i++) { for (int j = 0; j < 8; j++) { vpts[0][i] |= (0xFFL & pts[(i * 16) + j])<<((7 - j) * 8); vpts[1][i] |= (0xFFL & pts[(i * 16) + 8 + j])<<((7 - j) * 8); } } //horrible nebula PTS stuff if (vpts[0].length > 1 && Math.abs(vpts[0][vpts[0].length-1] - vpts[0][0]) < 100) { long a1 = vpts[0][0]; long a2 = vpts[1][0]; vpts = new long[2][1]; vpts[0][0] = a1; vpts[1][0] = a2; clv[8]++; } if (Debug) { System.out.println("\ngop" + clv[6] + "/tc_o53 " + job_processing.getLastGopTimecode() + "/lp_o54 " + job_processing.getLastGopPts() + "/lp_o8 " + job_processing.getEndPtsOfGop() + "/lp_o40 " + job_processing.getLastSimplifiedPts()); for (int i = 0; i < vpts[0].length; i++) System.out.println("p" + i + " " + vpts[0][i] + "/ " + vpts[1][i]); } Calendar cal = Calendar.getInstance(); String ct = Common.formatTime_1((long)(job_processing.getExportedVideoFrameNumber() * (double)(CommonParsing.getVideoFramerate() / 90.0f))); String nv = ""; String[] aspratio = {"res.","1.000 (1:1)","0.6735 (4:3)","0.7031 (16:9)","0.7615 (2.21:1)","0.8055","0.8437","0.9375","0.9815","1.0255","1.0695","1.1250","1.1575","1.2015","res." }; String[] fps_tabl1 = {"forbidden fps","23.976fps","24fps","25fps","29.97fps","30fps","50fps","59.94fps","60fps","n.def.","n.def.","n.def.","n.def.","n.def.","n.def.","n.def."}; double[] fps_tabl2 = { 0, 3753.7537, 3750, 3600, 3003.003, 3000, 1800, 1501.5015, 1500, 0,0,0,0,0,0,0}; int tref = 0; int maxtref = 0; int frame = -1; int newframes = 0; int progressive = 0; int closedgop = 0; int smark = 0; int trefcheck = 0; int vbvdelay = 65535; int lastframes = job_processing.getExportedVideoFrameNumber(); int frametype = 0; int SDE_marker = -1; int pD_marker = -1; int prog_seq = -1; int s = 0; int[] frt = { 5,50,20,5,5,5,5,5 }; boolean start = false; boolean last = false; boolean changegop = false; boolean writeframe = true; boolean is_I_Frame = false; boolean d2vinsert = false; boolean mpeg2type = false; boolean format_changed = false; boolean error = false; boolean broken_link = false; boolean sequenceheader_complete = false; boolean SDE_found = false; boolean doExport = false; long videotimes = job_processing.getVideoExportTime(); long lTC = job_processing.getLastGopTimecode(); long TC = 0; long lastpts = job_processing.getEndPtsOfGop() == -10000 ? -20000 : job_processing.getEndPtsOfGop(); long startpts = lastpts; long cutposition = 0; String frT[] = { "0","I","P","B","D","5","6","7" }; List newPics = new ArrayList(); List dropList = new ArrayList(); List infos = new ArrayList(); List newcut = new ArrayList(); ByteArrayOutputStream gopbuffer = new ByteArrayOutputStream(); ByteArrayOutputStream frametypebuffer = new ByteArrayOutputStream(); byte d2vframerate = 0; try { if (job_processing.hasSequenceHeader()) frametypebuffer.write((byte)0x88); else frametypebuffer.write((byte)0x80); if (job_processing.getSplitSize() > 0 && !job_processing.hasSequenceHeader() && job_processing.getExportedVideoFrameNumber() == 0) { byte[] newgop = new byte[headerrescue.length + gop.length]; System.arraycopy(headerrescue, 0, newgop, 0, headerrescue.length); System.arraycopy(gop, 0, newgop, headerrescue.length, gop.length); gop = newgop; job_processing.setSequenceHeader(true); for (int a = 0; a < vpts[1].length; a++) vpts[1][a] += headerrescue.length; } else if (!CutpointList.isEmpty() && !job_processing.hasSequenceHeader() && !CommonParsing.getCutStatus()) { byte[] newgop = new byte[headerrescue.length + gop.length]; System.arraycopy(headerrescue, 0, newgop, 0, headerrescue.length); System.arraycopy(gop, 0, newgop, headerrescue.length, gop.length); gop = newgop; job_processing.setSequenceHeader(true); for (int a = 0; a < vpts[1].length; a++) vpts[1][a] += headerrescue.length; } else if (!job_processing.hasSequenceHeader() && AddSequenceHeader) { byte[] newgop = new byte[headerrescue.length + gop.length]; System.arraycopy(headerrescue, 0, newgop, 0, headerrescue.length); System.arraycopy(gop, 0, newgop, headerrescue.length, gop.length); gop = newgop; job_processing.setSequenceHeader(true); for (int a = 0; a < vpts[1].length; a++) vpts[1][a] += headerrescue.length; } /* header check */ if (job_processing.hasSequenceHeader()) { /** * get new header, check if valid and not 0!! */ int _h_reso = ((0xFF & gop[s + 4])<<4 | (0xF0 & gop[s + 5])>>>4); int _v_reso = ((0xF & gop[s + 5])<<8 | (0xFF & gop[s + 6])); int _framerate = 0xF & gop[s + 7]; int _dar = 0xF & gop[s + 7]>>>4; double d = fps_tabl2[_framerate]; if (_h_reso == 0 || _v_reso == 0 || d == 0 || _dar == 0 || _dar > 13) { clv[4]++; ErrorCode |= 0x80; messageDropError(gop, pts, maxtref, frame, clv[6], job_processing.getExportedVideoFrameNumber(), startpts, lastpts, dumpname, ErrorCode); job_processing.setSequenceHeader(false); gopbuffer.close(); frametypebuffer.close(); gop = null; return; } CommonParsing.setVideoFramerate(d); // framerateconstant VbvBuffer_Value = 16 * 1024 * ( (0x1F & gop[s + 10])<<5 | (0xF8 & gop[s + 11])>>>3 ); String[] vbasics = { String.valueOf(_h_reso), String.valueOf(_v_reso), fps_tabl1[_framerate], aspratio[_dar], "" }; clv[7] = _dar - 1; if (job_processing.isNewVideoStream() || job_processing.getExportedVideoFrameNumber() == 0) { nv = Resource.getString("video.msg.basics", "" + vbasics[0] + "*" + vbasics[1] + " @ " + vbasics[2] + " @ " + vbasics[3] + " @ " + ( ((255&gop[s+8])<<10 | (255&gop[s+9])<<2 | (192 & gop[s+10])>>>6)*400 )) + " " + ( (31&gop[s+10])<<5 | (248&gop[s+11])>>>3 ); infos.add(nv); /** * no frames written 'til now */ if (job_processing.getExportedVideoFrameNumber() == 0) { d2vinsert = true; d2vframerate = gop[s + 7]; } else format_changed = true; System.arraycopy(vbasics, 0, VBASIC, 0, VBASIC.length); } if (!Arrays.equals(VBASIC, vbasics)) { String str = Resource.getString("video.msg.basics", vbasics[0] + "*" + vbasics[1] + " @ " + vbasics[2] + " @ " + vbasics[3] + " @ " + ( ((255&gop[s+8])<<10 | (255&gop[s+9])<<2 | (192 & gop[s+10])>>>6)*400 )) + " " + ( (31&gop[s+10])<<5 | (248&gop[s+11])>>>3 ); Common.setMessage(Resource.getString("video.msg.newformat", "" + clv[6]) + " (" + ct + ")"); Common.setMessage(str); job_processing.getChapters().addChapter(ct, str); format_changed = true; System.arraycopy(vbasics, 0, VBASIC, 0, VBASIC.length); } s = 12; } clv[6]++; /* gop check */ goploop: for (int returncode, pes_ID; s < gop.length - 10; s++ ) { if ((returncode = CommonParsing.validateStartcode(gop, s)) < 0) { s += (-returncode) - 1; continue goploop; } /** * action on next found startcode */ if (pD_marker > -1 && ClearCDF) { Arrays.fill( gop, pD_marker, s, (byte)0); //clear privare data on behalf of cdf flag setting pD_marker = -1; } // if ((dropList.size() & 1) != 0 && !dropList.get(dropList.size() - 1).toString().startsWith("_")) { dropList.add(String.valueOf(s)); } pes_ID = CommonParsing.getPES_IdField(gop, s); /** * slices */ if (pes_ID >= CommonParsing.SLICE_START_CODE_MIN && pes_ID <= CommonParsing.SLICE_START_CODE_MAX) { if (Debug) System.out.println("A " + s + " /slice " + pes_ID); s += 7; continue goploop; } /** * user data */ if (pes_ID == CommonParsing.USER_DATA_START_CODE) { if ((dropList.size() & 1) == 0) dropList.add(String.valueOf(s)); pD_marker = s; s += 3; continue goploop; } // /** * shit progdvb_data check */ else if ((0xF0 & gop[s+3]) == 0xE0) { int drop_length = 4; if (CommonParsing.getPES_LengthField(gop, s) == 0 ) { drop_length += 5 + (0xFF & gop[s + 8]); if (s + drop_length >= gop.length) drop_length = gop.length - s; Arrays.fill( gop, s, s + drop_length, (byte)0); if (Message_3) Common.setMessage(Resource.getString("video.msg.error.pesext_in_es", String.valueOf(clv[6] - 1), String.valueOf(s))); } else { Arrays.fill( gop, s, s + drop_length, (byte)0); if (Message_3) Common.setMessage(Resource.getString("video.msg.error.pes_in_es", String.valueOf(clv[6] - 1), String.valueOf(s))); } s += drop_length - 1; continue goploop; } else if (!mpeg2type && pes_ID == CommonParsing.EXTENSION_START_CODE && gop[s + 4]>>>4 == 1) /*** 0xb5 sequence extension ***/ { MPGVideotype[0] = 1; mpeg2type = true; prog_seq = s + 5; SDE_marker = s + 10; s += 9; if (job_processing.hasSequenceHeader() && frametypebuffer.size() == 1) { frametypebuffer.reset(); frametypebuffer.write((byte)(8 | (8 & gop[prog_seq])<<4)); } } else if (!sequenceheader_complete && pes_ID == CommonParsing.EXTENSION_START_CODE && gop[s + 4]>>>4 == 2) /*** 0xb5 MPEG-2 seq dis extension ***/ { if (AddSequenceDisplayExension && job_processing.hasSequenceHeader()) Video.setSequenceDisplayExtension( gop, s, SDE_Value, VBASIC); SDE_found = true; s += 8; } /** * 0xb8 gop header + timecode */ else if (pes_ID == CommonParsing.GROUP_START_CODE) { sequenceheader_complete = true; closedgop = s + 7; writeframe = true; broken_link = (0x20 & gop[s + 7]) != 0; //gop TC TC = 90L * (3600000L * ((0x7C & gop[s + 4])>>>2) + 60000L * ((3 & gop[s + 4])<<4 | (0xF0 & gop[s + 5])>>>4) + 1000L * ((7 & gop[s + 5])<<3 | (0xE0 & gop[s + 6])>>>5) + (long)(((0x1F & gop[s + 6])<<1 | (0x80 & gop[s + 7])>>>7) * (double)(CommonParsing.getVideoFramerate() / 90.0f)) ); if (Math.abs(TC - job_processing.getLastGopTimecode()) < CommonParsing.getVideoFramerate() || job_processing.getSourceVideoFrameNumber() == 0) job_processing.setLastGopTimecode(TC); if (Debug) System.out.println("\n//b8 " + TC + "/ " + Integer.toHexString((0x80&gop[s+4]) | (0x7F&gop[s+7])) + "/ " + s + "/ " + job_processing.hasSequenceHeader()); if (job_processing.hasSequenceHeader()) { headerrescue = new byte[s]; System.arraycopy(gop, 0, headerrescue, 0, s); } /** * set Timezone (videoframerate may be 0!!, check this) */ Date videotime = new Date((long)(job_processing.getExportedVideoFrameNumber() * (double)(CommonParsing.getVideoFramerate() / 90.0f))); cal.setTimeZone(TimeZone.getTimeZone("GMT+0:00")); cal.setTime(videotime); /** * get SMPTE (videoframerate may be 0!!, check this) */ int vh = cal.get(11); int vm = cal.get(12); int vs = cal.get(13); int vf = (cal.get(14) / ((int)CommonParsing.getVideoFramerate() / 90)) ; // earlier versions +1 gop[4 + s] = (byte)( (128 & gop[s+4]) | vh<<2 | vm>>>4 ); gop[5 + s] = (byte)( (15 & vm)<<4 | 8 | vs>>>3 ); gop[6 + s] = (byte)( (7 & vs)<<5 | vf>>>1 ); gop[7 + s] = (byte)( 127 & gop[s+7] | vf<<7 ); s += 6; } /** * 0x0 new frame */ else if (pes_ID == CommonParsing.PICTURE_START_CODE) { sequenceheader_complete = true; tref = ((0xFF & gop[s + 4]) << 2) | (0xC0 & gop[s + 5])>>>6; // temporalrefence of picture frametype = (0x38 & gop[s + 5])>>>3; if (frametype < CommonParsing.FRAME_I_TYPE || frametype > CommonParsing.FRAME_D_TYPE) { Common.setMessage(Resource.getString("video.msg.error.frame.wrong", "" + frametype) + " " + tref); error = true; ErrorCode |= 1; } newPics.add(String.valueOf(tref<<4 | frametype)); /** * vbv delay to 0xffff */ if (ChangeBitrateInAllSequences != 2 && ChangeBitrateInAllSequences > 0 && ChangeVbvDelay > 0) { gop[s + 5] |= 0x07; gop[s + 6] |= 0xFF; gop[s + 7] |= 0xF8; } if (tref > maxtref) maxtref = tref; if (Debug) System.out.println(frame + "/ " + maxtref + "/ " + tref + "/ " + s + " * " + frT[frametype] + "/ " + gop.length); if (!start && s >= vpts[1][0]) { startpts = vpts[0][0] - (long)(CommonParsing.getVideoFramerate() * tref); start = true; } else if (!last && s >= vpts[1][vpts[1].length - 1]) { lastpts = vpts[0][vpts[0].length-1] - (long)(CommonParsing.getVideoFramerate() * tref); last = true; } /** * determine cuts */ if (frame == -1 && frametype == CommonParsing.FRAME_I_TYPE) { /** * determine vbv-delay of I-frame */ vbvdelay = (7 & gop[s + 5])<<13 | (0xFF & gop[s + 6])<<5 | (0xF8 & gop[s + 7])>>>3; is_I_Frame = true; if (job_processing.getExportedVideoFrameNumber() == 0) infos.add(Resource.getString("video.msg.export.start") + " " + (clv[6] - 1)); /** * drop B-Frames, also if broken_link flag is set */ if (tref > 0 && (Math.abs(startpts - job_processing.getEndPtsOfGop()) > CommonParsing.getVideoFramerate() || broken_link)) { gop[s + 4] = 0; gop[s + 5] &= 0x3F; /* set first I-Frame's tref to 0 */ gop[closedgop] |= 0x40; if (broken_link) gop[closedgop] &= ~0x20; gopbuffer.write(gop, 0, s); smark = s; if (job_processing.getExportedVideoFrameNumber() > 0) infos.add(Resource.getString("video.msg.pts.diff", String.valueOf(startpts - job_processing.getEndPtsOfGop()), Common.formatTime_1((startpts - job_processing.getEndPtsOfGop()) / 90)) + " " + (broken_link ? Resource.getString("video.msg.error.brokenlink") : "")); infos.add(Resource.getString("video.msg.frame.drop", "" + (clv[6] - 1)) + " " + Common.formatTime_1((long)(job_processing.getExportedVideoFrameNumber() * (double)(CommonParsing.getVideoFramerate() / 90.0f)))); job_processing.countExportedVideoFrameNumber(-tref); newframes -= tref; trefcheck = tref; changegop = true; clv[0]++; //cut } } /** * recalculate tref, timecode, frames + delete b-frames */ if (frame > -1 && changegop) { if (writeframe) gopbuffer.write(gop, smark, s - smark); smark = s; /** * drop b-frame from temporal sequence */ if ( trefcheck > tref ) { writeframe = false; if ((dropList.size() & 1) == 0) dropList.add("_" + String.valueOf(s)); } else { writeframe = true; gop[s + 4] = (byte)( (tref - trefcheck)>>>2); gop[s + 5] = (byte)( (63 & gop[s + 5]) | ((tref - trefcheck)<<6)); if ((dropList.size() & 1) == 1) dropList.add("_" + String.valueOf(s)); } } /** * P-frames for cut in gop */ if (frametype == CommonParsing.FRAME_P_TYPE) { if (!changegop) { long[] cutdata = { job_processing.getSourceVideoFrameNumber(), s }; newcut.add(cutdata); } else { long[] cutdata = { job_processing.getSourceVideoFrameNumber(), gopbuffer.size() }; newcut.add(cutdata); } } job_processing.countSourceVideoFrameNumber(+1); job_processing.countExportedVideoFrameNumber(+1); frame++; newframes++; progressive = 0x80; /* 0xb5 pic coding extension */ for (int i = s + 6; i < s + 15 && i + 8 < gop.length; i++ ) { if ((returncode = CommonParsing.validateStartcode(gop, i)) < 0) { i += (-returncode) - 1; continue; } if (gop[i + 3] != (byte)0xb5 || (0xF0 & gop[i + 4]) != 0x80) continue; progressive = (0x80 & gop[i + 8]); if (PatchToProgressive) gop[i + 8] |= (byte)0x80; // mark as progressiv else if (PatchToInterlaced) gop[i + 8] &= (byte)~0x80; // mark as interlaced if (ToggleFieldorder) gop[i + 7] ^= (byte)0x80; // toggle top field first /** * zero'es the comp.disp.flag infos */ if (ClearCDF && (0x40 & gop[i + 8]) != 0) { gop[i + 8] &= (byte)0x80; gop[i + 9] = 0; gop[i + 10] = 0; if ((dropList.size() & 1) == 0) dropList.add(String.valueOf(i + 9)); s = i; } break; } if (is_I_Frame || !changegop || (changegop && writeframe)) frametypebuffer.write((byte)(frametype | progressive)); s += 7; // slices B min 5, I min 50, p min 25 is_I_Frame = false; } } // end of gop search /** for (int dl = 0; dl < dropList.size(); dl++) { String str = dropList.get(dl).toString(); if (str.startsWith("_")) str = "_" + Integer.toHexString(Integer.parseInt(str.substring(1))); else str = Integer.toHexString(Integer.parseInt(str)); Common.setMessage("dl " + dl + " : '0x" + str.toUpperCase() + "'"); } **/ /** * put the rest of data into buffer, if gop was changed */ if (changegop) { if (writeframe) gopbuffer.write(gop, smark, gop.length - smark); gop = gopbuffer.toByteArray(); gopbuffer.reset(); changegop = false; } if (prog_seq != -1 && prog_seq < gop.length) { if (PatchToProgressive) gop[prog_seq] |= (byte)8; // mark as progressiv_seq else if (PatchToInterlaced) gop[prog_seq] &= (byte)~8; // unmark ^ } if (vpts[0].length < 2) { lastpts = startpts; clv[1]++; } if (job_processing.get1stVideoPTS() == -1) job_processing.set1stVideoPTS(startpts); int Pics[] = new int[newPics.size()]; for (int a = 0; a < Pics.length; a++) Pics[a] = Integer.parseInt(newPics.get(a).toString()); int newTref[] = new int[Pics.length]; Arrays.fill(newTref, -1); /** * error, no Frames found */ if (Pics.length == 0) { Common.setMessage(Resource.getString("video.msg.error.frame.not", String.valueOf(clv[6] - 1))); error = true; ErrorCode |= 2; } /** * error, no leading I-Frame */ if (Pics.length > 0 && (Pics[0] & 0xF) != 1) Common.setMessage(Resource.getString("video.msg.error.frame.not.i", String.valueOf(clv[6] - 1))); for (int i = 0; !error && i < Pics.length; i++) { int Tref = Pics[i]>>>4; if (Tref < 0 || Tref > Pics.length - 1 || newTref[Tref] != -1) { error = true; ErrorCode |= 4; break; } newTref[Tref] = Pics[i]; } for (int i = 0; !error && i < newTref.length; i++) if (newTref[i] == -1) { error = true; ErrorCode |= 8; } /** * show and save I-frame when demuxing * disabled, will be changed later */ if (Save1stFrameOfGop) { Common.getMpvDecoderClass().decodeArray(gop, false, Preview_AllGops, Preview_fastDecode); //CommonGui.getPicturePanel().saveBMP(true, job_processing.isRunningFromCLI()); } /** * error, start pts is to early as last */ if (startpts < job_processing.getLastGopPts() - CommonParsing.getVideoFramerate() / 2) { Common.setMessage(Resource.getString("video.msg.error.pts.early", String.valueOf(clv[6] - 1), String.valueOf(job_processing.getLastGopPts()))); error = true; ErrorCode |= 0x10; } /** * falls startpts kleiner als options[8] (lende letzte GOP) aber innerhalb toleranz, * dann options[8] schreiben, setzen des neuen Endes aber mit ermittelter lastpts dieser gop */ if (TrimPts && startpts < job_processing.getEndPtsOfGop() && (double)(job_processing.getEndPtsOfGop() - startpts) < (CommonParsing.getVideoFramerate() / 2.0)) { if (Debug) System.out.println("videostart trimmed to o8 " + job_processing.getEndPtsOfGop() + " /sp " + startpts); startpts = job_processing.getEndPtsOfGop(); } /** * error, if pts diff. between frames > half of a frame */ if (maxtref != frame || Math.abs(lastpts - startpts) > 2000) { error = true; ErrorCode |= 0x20; } /** * ignore v-errors */ if (job_processing.getSourceVideoFrameNumber() > 0 && IgnoreErrors) { lastpts = startpts; maxtref = frame; error = false; } /** * error, if gop on mp@ml is too big */ if (Integer.parseInt(VBASIC[0]) <= 720 && gop.length > 2750000) { error = true; ErrorCode |= 0x40; } /** * return last orig pts for plain mpv */ job_processing.setLastSimplifiedPts(startpts + (long)(trefcheck * CommonParsing.getVideoFramerate()) + (long)((maxtref - trefcheck + 1) * CommonParsing.getVideoFramerate())); /** * message error */ if (error) { job_processing.setExportedVideoFrameNumber(lastframes); clv[4]++; messageDropError(gop, pts, maxtref, frame, clv[6], job_processing.getExportedVideoFrameNumber(), startpts, lastpts, dumpname, ErrorCode); } else { /** * unused! * temp delete, disable for P-frame cutout */ newcut.clear(); /** * read out gop timecode as long ,TC 081.5++ */ job_processing.countLastGopTimecode((long)(CommonParsing.getVideoFramerate() * (maxtref + 1))); job_processing.setLastGopPts(startpts + (long)(CommonParsing.getVideoFramerate() * (maxtref + 1))); /** * how to cut */ switch (CutMode) { case CommonParsing.CUTMODE_BYTE: cutposition = job_processing.getCutByteposition(); break; case CommonParsing.CUTMODE_GOP: cutposition = clv[6]; break; case CommonParsing.CUTMODE_FRAME: cutposition = job_processing.getSourceVideoFrameNumber(); break; case CommonParsing.CUTMODE_PTS: cutposition = startpts + 1000; //exclude jitter break; case CommonParsing.CUTMODE_TIME: cutposition = startpts - job_processing.get1stVideoPTS(); } /** * cut using bytepos, frame#, gop#, timecode or pts */ if (!CommonParsing.makecut(job_processing, dumpname, startpts, cutposition, newcut, lastframes, CutpointList, clv[6] - 1, job_processing.getCellTimes())) job_processing.setExportedVideoFrameNumber(lastframes); /** * DAR request for auto cut */ else if (OptionDAR && ExportDAR != clv[7]) job_processing.setExportedVideoFrameNumber(lastframes); /** * H Resolution request for auto cut */ else if (OptionHorizontalResolution && !ExportHorizontalResolution.equals(VBASIC[0])) job_processing.setExportedVideoFrameNumber(lastframes); else if (!doWrite) {} else { startpts += (long)(trefcheck * CommonParsing.getVideoFramerate()); /** * videoframe-pts-counter */ job_processing.setEndPtsOfGop(startpts + (long)((maxtref - trefcheck + 1) * CommonParsing.getVideoFramerate())); /** * write V-PTS Log for audio/data sync */ log.writeLong(startpts); log.writeLong(job_processing.getEndPtsOfGop()); /** * write V-Time Log for audio/data sync */ log.writeLong(videotimes); log.writeLong(job_processing.countVideoExportTime((long)((maxtref - trefcheck + 1) * CommonParsing.getVideoFramerate()))); /** * value for gop bitrate per second */ double svbr = CommonParsing.getVideoFramerate() * (maxtref - trefcheck + 1); if (svbr <= 0) svbr = CommonParsing.getVideoFramerate() * 10; /** * calculate the bitrate from gop length * !!renew determination */ int vbr = (int)( ( (90000L * (gop.length * 8)) / svbr ) / 400); /** * set value for gop bitrate per second */ if (job_processing.hasSequenceHeader()) { /** * value for bitrate per vbv */ if (ChangeBitrateInAllSequences == 2 && vbvdelay < 65535 ) vbr = (int)( (90000L * VbvBuffer_Value) / vbvdelay / 400); /** * set new aspectratio */ if (ChangeAspectRatio > 0) gop[7] = (byte)((0xF & gop[7]) | ChangeAspectRatio<<4); /** * set new vbvsize */ if (ChangeVbvBuffer > 0) { gop[10] = (byte)((0xE0 & gop[10]) | 112>>>5); gop[11] = (byte)((7 & gop[11]) | (0x1F & 112)<<3); } } /** * determ. avg bitrates */ if (vbr < job_processing.getMinBitrate()) job_processing.setMinBitrate(vbr); if (vbr > job_processing.getMaxBitrate()) job_processing.setMaxBitrate(vbr); if (job_processing.hasSequenceHeader()) { /** * set new bitrate in SH */ if (ChangeBitrateInAllSequences > 0) { int val = (ChangeBitrateInAllSequences - 3) * 2500 * 3; if (val > 0) vbr = val; int vbr1 = vbr; if (ChangeBitrateInAllSequences == 3) vbr1 = 262143; /** * set sequence bitrate */ gop[8] = (byte)(vbr1>>>10); gop[9] = (byte)(0xFF & (vbr1>>2)); gop[10] = (byte)( (0x3F & gop[10]) | (3 & vbr1)<<6 ); clv[2]++; } else clv[3]++; } /** * update data for the gop info picture */ frametypebuffer.flush(); byte ftb[] = frametypebuffer.toByteArray(); int fields_in_frame = 0, min = 0x7FFF & clv[9]>>>15, max = 0x7FFF & clv[9], prog_flag = clv[9]>>>30; for (int i = 1; i < ftb.length; i++) { fields_in_frame += 2; prog_flag |= (0x80 & ftb[i]) != 0 ? 2 : 1; } if (fields_in_frame < min || min == 0) min = fields_in_frame; if (fields_in_frame > max || max == 0) max = fields_in_frame; clv[9] = prog_flag<<30 | (0x7FFF & min)<<15 | (0x7FFF & max); /** * refresh the gop info picture */ Common.getGuiInterface().updateBitrateMonitor(vbr, ftb, Common.formatTime_1((job_processing.getVideoExportTimeSummary() + job_processing.getVideoExportTime()) / 90).substring(0, 8)); /** * add chapter index of a change in basic data */ if (job_processing.isNewVideoStream() && infos.size() > 0) job_processing.getChapters().addChapter(ct, nv); /** * print cached messages */ for (int i = 0; i < infos.size(); i++) { Common.setMessage(infos.get(i).toString()); job_processing.setNewVideoStream(false); } /** * d2v project, update framerate */ if (d2vinsert && (CreateD2vIndex || SplitProjectFile)) { job_processing.getProjectFileD2V().FrameRate(d2vframerate); d2vinsert = false; } /** * d2v project, update gop line, even if video export is disabled */ job_processing.getProjectFileD2V().addGOP(job_processing.getProjectFileExportLength(), newframes); /** * add SEC on a change of basic data */ if (format_changed && InsertEndcode) { if (WriteVideo) { video_sequence.write(Video.getSequenceEndCode()); job_processing.countMediaFilesExportLength(+4); job_processing.countAllMediaFilesExportLength(+4); job_processing.countProjectFileExportLength(+4); } job_processing.addCellTime(String.valueOf(job_processing.getExportedVideoFrameNumber())); Common.setMessage("-> save ChapterFrameIndex: " + job_processing.getExportedVideoFrameNumber()); } /** * if write is enabled, write gop */ if (WriteVideo) { /** * add SDE, mpeg2 only */ if (mpeg2type && AddSequenceDisplayExension && !SDE_found && job_processing.hasSequenceHeader()) { int offs = SDE_marker != -1 ? SDE_marker : headerrescue.length; video_sequence.write(gop, 0, offs); video_sequence.write(Video.setSequenceDisplayExtension(SDE_Value, VBASIC)); video_sequence.write(gop, offs, gop.length - offs); job_processing.countMediaFilesExportLength(+12); job_processing.countAllMediaFilesExportLength(+12); job_processing.countProjectFileExportLength(+12); } else { video_sequence.write(gop); } job_processing.countMediaFilesExportLength(gop.length); doExport = true; } if (ChapterpointList.indexOf(String.valueOf(cutposition)) >= 0) { job_processing.addCellTime(String.valueOf(job_processing.getExportedVideoFrameNumber())); Common.setMessage("-> save ChapterFrameIndex: " + job_processing.getExportedVideoFrameNumber()); } job_processing.countProjectFileExportLength(gop.length); job_processing.countAllMediaFilesExportLength(gop.length); } // end if makecut Common.getGuiInterface().showExportStatus(doExport ? Resource.getString("audio.status.write") : Resource.getString("audio.status.pause")); } infos.clear(); job_processing.setSequenceHeader(false); gopbuffer.close(); frametypebuffer.close(); gop = null; } catch (IOException e) { Common.setExceptionMessage(e); } } } project-x/src/net/sourceforge/dvb/projectx/parser/GopArray.java0000600000175000017500000000504010351107364026312 0ustar supermariosupermario/* * @(#)GopArray * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; /** * not used ATM */ public class GopArray extends Object { private byte[] gop_array; private int gop_offset; /** * */ public GopArray() { gop_offset = 0; } /** * maximum gop size */ private void init() { if (gop_array == null) gop_array = new byte[4096000]; } /** * */ public byte[] getGopArray() { return gop_array; } /** * */ public boolean isBufferFull() { if (gop_offset >= gop_array.length) return true; return false; } /** * */ public void write(byte[] array, int offset, int length) { write(array, offset, length, gop_offset); } /** * */ public void write(byte[] array, int offset, int length, int _gop_offset) { init(); if (_gop_offset >= gop_array.length) return; if (_gop_offset + length > gop_array.length) length = gop_array.length - _gop_offset; System.arraycopy(array, offset, gop_array, _gop_offset, length); gop_offset += length; } /** * */ public byte[] read(int length) { return read(gop_offset, length); } /** * */ public byte[] read(int offset, int length) { init(); if (offset >= gop_array.length) return null; byte[] array = new byte[length]; if (offset + length > gop_array.length) length = gop_array.length - offset; System.arraycopy(gop_array, offset, array, 0, length); return array; } /** * */ public int getOffset() { return gop_offset; } } project-x/src/net/sourceforge/dvb/projectx/parser/HpFix.java0000600000175000017500000000522410351107374025611 0ustar supermariosupermario/* * @(#)HpFix * * Copyright (c) 2004-2005 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.PushbackInputStream; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.File; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.parser.CommonParsing; public class HpFix extends Object { public HpFix() {} public XInputFile process(XInputFile xInputFile) { String file_fixed = xInputFile.toString() + "[fixed].pes"; try { PushbackInputStream in = new PushbackInputStream(xInputFile.getInputStream(), 9); BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream(file_fixed), 5096000); byte[] header = new byte[9]; byte[] data; for (int ret, len, pes_ext;;) { ret = in.read(header, 0, 9); if (ret < 9) break; if ((ret = CommonParsing.validateStartcode(header, 0)) < 0 || header[3] != (byte)0xBD) { ret = ret < 0 ? -ret : 4; in.unread(header, ret, 9 - ret); continue; } len = (0xFF & header[4])<<8 | (0xFF & header[5]); len -= 6; header[4] = (byte)(0xFF & len>>>8); header[5] = (byte)(0xFF & len); pes_ext = (0xFF & header[8]); pes_ext += 4; header[8] = (byte)(0xFF & pes_ext); out.write(header); data = new byte[len - 3]; in.read(data, 0 , data.length); out.write(data); } in.close(); out.flush(); out.close(); } catch (IOException e) { Common.setExceptionMessage(e); return null; } return (new XInputFile(new File(file_fixed))); } } project-x/src/net/sourceforge/dvb/projectx/parser/MainProcess.java0000600000175000017500000010307710411340472027016 0ustar supermariosupermario/* * @(#)MainProcess * * Copyright (c) 2001-2006 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ /* * X is completely designed as a test, therefore it mostly implements its * own code instead of a derivation of an ISO reference source or * any other code. Considerable effort has been expended to ensure * an useful implementation, even in cases where the standards * are ambiguous or misleading. * Do not expect any useful output, even if that may be possible. * * For a program compliant to the international standards ISO 11172 * and ISO 13818 it is inevitable to use methods covered by patents * in various countries. The authors of this program disclaim any * liability for patent infringement caused by using, modifying or * redistributing this program. * */ package net.sourceforge.dvb.projectx.parser; import java.awt.Toolkit; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.File; import java.io.InputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintStream; import java.io.PrintWriter; import java.io.PushbackInputStream; import java.io.RandomAccessFile; import java.io.StringWriter; import java.io.InputStreamReader; import java.text.SimpleDateFormat; import java.text.DateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.StringTokenizer; import java.util.Calendar; import java.util.TimeZone; import java.net.URL; import net.sourceforge.dvb.projectx.audio.AudioFormat; import net.sourceforge.dvb.projectx.audio.MpaConverter; import net.sourceforge.dvb.projectx.audio.MpaDecoder; import net.sourceforge.dvb.projectx.audio.RIFFHeader; import net.sourceforge.dvb.projectx.subtitle.BMP; import net.sourceforge.dvb.projectx.subtitle.Bitmap; import net.sourceforge.dvb.projectx.subtitle.Subpicture; import net.sourceforge.dvb.projectx.subtitle.Teletext; import net.sourceforge.dvb.projectx.subtitle.UnicodeWriter; import net.sourceforge.dvb.projectx.thirdparty.Chapters; import net.sourceforge.dvb.projectx.thirdparty.D2V; import net.sourceforge.dvb.projectx.thirdparty.Ifo; import net.sourceforge.dvb.projectx.thirdparty.TS; import net.sourceforge.dvb.projectx.video.Video; import net.sourceforge.dvb.projectx.parser.VBI; import net.sourceforge.dvb.projectx.parser.StreamBuffer; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.parser.Scan; import net.sourceforge.dvb.projectx.parser.StreamConverter; import net.sourceforge.dvb.projectx.parser.StreamDemultiplexer; import net.sourceforge.dvb.projectx.parser.StreamParserBase; import net.sourceforge.dvb.projectx.parser.StreamParser; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.io.IDDBufferedOutputStream; import net.sourceforge.dvb.projectx.io.StandardBuffer; import net.sourceforge.dvb.projectx.io.RawFile; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.xinput.StreamInfo; /** * main thread */ public class MainProcess extends Thread { private MpaConverter MPAConverter; private MpaDecoder MPADecoder; private int ERRORCODE = 0; private int MainBufferSize = 8192000; private TS tf = new TS(); /** * run */ public void run() { Common.setRunningProcess(true); startProcessing(); Common.setRunningProcess(false); } /** * process */ private void startProcessing() { boolean stop_on_error = false; Common.setGlobalDebug(Common.getSettings().getBooleanProperty(Keys.KEY_DebugLog)); JobCollection collection = null; JobProcessing job_processing = null; try { Common.setProcessTime(System.currentTimeMillis()); Common.updateProgressBar(Resource.getString("run.prepare.colls"), 0, 0); Common.getGuiInterface().showAVOffset(Resource.getString("run.av.offset")); Common.getGuiInterface().updateTtxHeader(""); Common.getGuiInterface().updateVpsLabel(""); Common.setMessage(null, false); if (CommonParsing.isInfoScan()) { Common.setMessage(Resource.getString("run.start.quick.info")); Common.setMessage(""); } int a = 0; int b = 0; int d = 0; /** * normal processing */ if (CommonParsing.getPvaPidToExtract() == -1) { if (Common.getSettings().getBooleanProperty(Keys.KEY_useAllCollections)) b = Common.getCollectionListSize(); else { a = Common.getActiveCollection(); b = a + 1; } Common.setMessage(Resource.getString("run.session.infos")); Common.setMessage(""); String str; /** * the Collection main loop */ for ( ; a < b ; a++, d++) { Common.clearMessageLog(); Common.setMessage(DateFormat.getDateInstance(DateFormat.FULL).format(new Date()) + " " + DateFormat.getTimeInstance(DateFormat.FULL).format(new Date())); Common.setMessage(Common.getVersionName() + " (" + Common.getVersionDate() + ")"); // clean up before each collection run System.gc(); if (a >= Common.getCollectionListSize()) continue; Common.setProcessedCollection(a); collection = Common.getCollection(a); collection.startProcessing(Common.isRunningCLI()); job_processing = collection.getJobProcessing(); // Common.getGuiInterface().showActiveCollection(a); //brings mainframe to front and load preview Common.setMessage(""); Common.setMessage(Resource.getString("run.working.coll") + " " + a); /** * do nothing, if collection is empty */ if (collection.getInputFilesCount() == 0) { Common.getGuiInterface().showAVOffset(Resource.getString("run.av.offset")); Common.updateProgressBar("", 0, 0); Common.setMessage(Resource.getString("run.no.input")); continue; } Common.getGuiInterface().updateTtxHeader(""); Common.getGuiInterface().updateVpsLabel(""); CommonParsing.setCutCounter(0); // move to collection CommonParsing.setCutStatus(false); // move to collection tf.setfirstID(); messageSettings(); if ( (str = collection.checkOutputDirectory()) != null) { Common.setMessage(Resource.getString("run.write.output.notexists") + ":"); Common.setMessage("'" + str + "'"); continue; } if (Common.getSettings().getBooleanProperty(Keys.KEY_ExportPanel_createSubDirNumber)) { str = "[" + a + "]"; collection.setOutputDirectory( collection.getOutputDirectory() + collection.getFileSeparator() + str); new File(collection.getOutputDirectory()).mkdirs(); } /** * out directory named by first file of coll. */ if (Common.getSettings().getBooleanProperty(Keys.KEY_ExportPanel_createSubDirName)) { File f = new File(collection.getFirstFileBase()); str = new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss").format(new Date(collection.getFirstFileDate())) + "_" + collection.getFirstFileName(); collection.setOutputDirectory( collection.getOutputDirectory() + collection.getFileSeparator() + str); new File(collection.getOutputDirectory()).mkdirs(); } /** * create index.vdr + new path */ if (Common.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createVdrIndex) && Common.getSettings().getIntProperty(Keys.KEY_ConversionMode) == 1) { str = "_" + new File(collection.getFirstFileBase()).getName() + System.getProperty("file.separator") + new SimpleDateFormat("yyyy-MM-dd.HH.mm.ss.SSS").format(new Date()) + ".rec"; collection.setOutputDirectory( collection.getOutputDirectory() + collection.getFileSeparator() + str); new File(collection.getOutputDirectory()).mkdirs(); } Common.setMessage(Resource.getString("run.write.output.to") + " '" + collection.getOutputDirectory() + "'"); int val = collection.getCutpointCount(); if (val > 0) Common.setMessage("-> " + val + " " + Resource.getString("run.cutpoints.defined") + " ( " + Keys.ITEMS_CutMode[Common.getSettings().getIntProperty(Keys.KEY_CutMode)] + " )"); collection.setLogFiles(); /** * gets collection priority of action type */ int action = collection.getActionType(); if (action < 0) action = Common.getSettings().getIntProperty(Keys.KEY_ConversionMode); /** * quick pre-run for TS autoPMT * depends also on collection priority of action type */ if (!CommonParsing.isInfoScan() && action == CommonParsing.ACTION_TO_TS && Common.getSettings().getBooleanProperty(Keys.KEY_TS_generatePmt)) { Common.setMessage(""); Common.setMessage(Resource.getString("run.start.quick.info")); CommonParsing.setInfoScan(true); /** * no split on infoscan */ long splitlen = job_processing.getSplitSize(); job_processing.setSplitSize(0); /** * call the process */ processCollection(collection); job_processing.setSourceVideoFrameNumber(0); job_processing.setFileNumber(0); CommonParsing.setCutCounter(0); // move to collection CommonParsing.setCutStatus(false); // move to collection CommonParsing.setInfoScan(false); job_processing.setSplitSize(splitlen); Common.setMessage(""); Common.setMessage(Resource.getString("run.end.quick.info")); } /** * M2S chapters per coll# */ job_processing.getChapters().init(Common.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createChapters)); /** * call the process */ processCollection(collection); job_processing.clearStatusStrings(); /** * M2S finish chapters file per coll# */ job_processing.getChapters().finish(collection.getOutputDirectory(), collection.getFirstFileName()); /** * finish collection */ collection.finishProcessing(); } } /** * extract raw pes data processing */ else { Common.setProcessedCollection(Common.getActiveCollection()); Common.setMessage(DateFormat.getDateInstance(DateFormat.FULL).format(new Date()) + " " + DateFormat.getTimeInstance(DateFormat.FULL).format(new Date())); Common.setMessage(Common.getVersionName() + " (" + Common.getVersionDate() + ")"); Common.setMessage(""); Common.setMessage(Resource.getString("run.session.infos")); Common.setMessage(""); Common.setMessage(Resource.getString("run.working.coll") + " " + Common.getProcessedCollection()); String str; /** * loop is not used ATM */ for (;;) { collection = Common.getCollection(Common.getProcessedCollection()); if (collection.getInputFilesCount() == 0) { Common.setMessage(Resource.getString("run.coll.empty")); break; } if ( (str = collection.checkOutputDirectory()) != null) { Common.setMessage(Resource.getString("run.write.output.notexists") + ":"); Common.setMessage("'" + str + "'"); break; } Common.setMessage(Resource.getString("run.write.raw") + " " + collection.getOutputDirectory()); collection.startProcessing(Common.isRunningCLI()); /** * call the process */ processCollection(collection); CommonParsing.setPvaPidToExtract(0); /** * finish collection */ collection.finishProcessing(); break; } } Common.updateProgressBar(Resource.getString("run.done", "" + d) + " " + Common.formatTime_1(Common.getProcessTime())); } catch (Exception e8) { Common.setMessage(Resource.getString("run.stopped")); Common.setExceptionMessage(e8); stop_on_error = true; } catch (Error e9) { Common.setMessage(Resource.getString("run.stopped")); Common.setErrorMessage(e9); stop_on_error = true; } CommonParsing.setPvaPidExtraction(false); if (CommonParsing.isInfoScan()) { Common.setMessage(""); Common.setMessage(Resource.getString("run.end.quick.info")); } CommonParsing.setProcessPausing(false); CommonParsing.setProcessCancelled(false); CommonParsing.setInfoScan(false); if (stop_on_error) { Common.setMessage(Resource.getString("all.msg.error.summary", String.valueOf(Common.getErrorCount()))); collection.closeDebugLogStream(); collection.closeNormalLogStream(Common.getMessageLog()); } else Common.setMessage(" ", false, 0xEFFFEF); collection.finishProcessing(); /** * exit on CLI mode */ if (Common.isRunningCLI() || Common.getSettings().getBooleanProperty(Keys.KEY_closeOnEnd)) Common.exitApplication(stop_on_error ? 1 : 0); Common.getGuiInterface().resetMainFrameTitle(); } /** * list settings on start */ private void messageSettings() { Common.setMessage(" "); //biglog messageSetting(Keys.KEY_DebugLog); //normallog messageSetting(Keys.KEY_NormalLog); //MPG->sPES messageSetting(Keys.KEY_simpleMPG); //sPES->MPG messageSetting(Keys.KEY_enhancedPES); //split if (Common.getSettings().getBooleanProperty(Keys.KEY_SplitSize)) Common.setMessage(Resource.getString("run.split.output") + " " + Common.getSettings().getProperty(Keys.KEY_ExportPanel_SplitSize_Value) + " MB"); //write video messageSetting(Keys.KEY_WriteOptions_writeVideo); //write others messageSetting(Keys.KEY_WriteOptions_writeAudio); //demux if (Common.getSettings().getIntProperty(Keys.KEY_ConversionMode) == CommonParsing.ACTION_DEMUX) { //add offset if (Common.getSettings().getBooleanProperty(Keys.KEY_additionalOffset)) Common.setMessage(Resource.getString("run.add.time.offset", "" + Common.getSettings().getProperty(Keys.KEY_ExportPanel_additionalOffset_Value))); //idd if (Common.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createM2sIndex)) Common.setMessage("-> " + Resource.getString("ExternPanel.createM2sIndex.Tip") + " " + Resource.getString(Keys.KEY_ExternPanel_createM2sIndex[0])); // cminfo if (Common.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createInfoIndex)) Common.setMessage("-> " + Resource.getString("ExternPanel.createInfoIndex.Tip") + " " + Resource.getString(Keys.KEY_ExternPanel_createInfoIndex[0])); //d2v_1 messageSetting(Keys.KEY_ExternPanel_createD2vIndex); //d2v_2 if (Common.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_splitProjectFile)) Common.setMessage("-> " + Resource.getString(Keys.KEY_ExternPanel_createD2vIndex[0]) + " " + Resource.getString(Keys.KEY_ExternPanel_splitProjectFile[0])); //dar export limit if (Common.getSettings().getBooleanProperty(Keys.KEY_OptionDAR)) Common.setMessage("-> " + Resource.getString("CollectionPanel.ExportLimits") + " " + Resource.getString(Keys.KEY_OptionDAR[0]) + " " + Keys.ITEMS_ExportDAR[Common.getSettings().getIntProperty(Keys.KEY_ExportDAR)]); //h_resol export limit if (Common.getSettings().getBooleanProperty(Keys.KEY_OptionHorizontalResolution)) Common.setMessage("-> " + Resource.getString("CollectionPanel.ExportLimits") + " " + Resource.getString(Keys.KEY_OptionHorizontalResolution[0]) + " " + Common.getSettings().getProperty(Keys.KEY_ExportHorizontalResolution)); //C.D.Flag messageSetting(Keys.KEY_VideoPanel_clearCDF); //patch2interl messageSetting(Keys.KEY_VideoPanel_patchToInterlaced); //patch2progr messageSetting(Keys.KEY_VideoPanel_patchToProgressive); //patchfield messageSetting(Keys.KEY_VideoPanel_toggleFieldorder); //Sequ_endcode messageSetting(Keys.KEY_VideoPanel_addEndcode); //Sequ_endcode on changes messageSetting(Keys.KEY_VideoPanel_insertEndcode); //SDE if (Common.getSettings().getBooleanProperty(Keys.KEY_VideoPanel_addSde)) Common.setMessage("-> " + Resource.getString(Keys.KEY_VideoPanel_addSde[0]) + " " + Common.getSettings().getProperty(Keys.KEY_VideoPanel_SdeValue)); //add missing sequ_header messageSetting(Keys.KEY_VideoPanel_addSequenceHeader); } boolean invers = true; //es types to demux_detect messageSetting(Resource.getString("run.stream.type.disabled"), Keys.KEY_Streamtype_MpgVideo, invers); messageSetting(Resource.getString("run.stream.type.disabled"), Keys.KEY_Streamtype_MpgAudio, invers); messageSetting(Resource.getString("run.stream.type.disabled"), Keys.KEY_Streamtype_Ac3Audio, invers); messageSetting(Resource.getString("run.stream.type.disabled"), Keys.KEY_Streamtype_PcmAudio, invers); messageSetting(Resource.getString("run.stream.type.disabled"), Keys.KEY_Streamtype_Teletext, invers); messageSetting(Resource.getString("run.stream.type.disabled"), Keys.KEY_Streamtype_Subpicture, invers); messageSetting(Resource.getString("run.stream.type.disabled"), Keys.KEY_Streamtype_Vbi, invers); /** * enhanced */ messageSetting(Keys.KEY_PVA_FileOverlap); messageSetting(Keys.KEY_PVA_Audio); messageSetting(Keys.KEY_VOB_resetPts); messageSetting(Keys.KEY_TS_ignoreScrambled); messageSetting(Keys.KEY_TS_blindSearch); messageSetting(Keys.KEY_TS_joinPackets); messageSetting(Keys.KEY_TS_HumaxAdaption); messageSetting(Keys.KEY_TS_FinepassAdaption); messageSetting(Keys.KEY_TS_generatePmt); messageSetting(Keys.KEY_TS_generateTtx); messageSetting(Keys.KEY_Input_getEnclosedPackets); messageSetting(Keys.KEY_Input_concatenateForeignRecords); messageSetting(Keys.KEY_Video_ignoreErrors); messageSetting(Keys.KEY_Video_trimPts); messageSetting(Keys.KEY_Conversion_startWithVideo); messageSetting(Keys.KEY_Conversion_addPcrToStream); Common.setMessage(" "); } /** * list settings on start */ private void messageSetting(String[] key) { if (Common.getSettings().getBooleanProperty(key)) Common.setMessage("-> " + Resource.getString(key[0])); } /** * list settings on start */ private void messageSetting(String str, String[] key) { if (Common.getSettings().getBooleanProperty(key)) Common.setMessage(str + " " + Resource.getString(key[0])); } /** * list settings on start */ private void messageSetting(String str, String[] key, boolean invers) { if (Common.getSettings().getBooleanProperty(key) != invers) Common.setMessage(str + " " + Resource.getString(key[0])); } /** * stops the processing until next user action */ public boolean pause() { if (!CommonParsing.isProcessPausing()) return false; try { sleep(1000); } catch (InterruptedException ie) { Common.setMessage("!> interrupted suspend mode "); Common.setExceptionMessage(ie); } return true; } /** * call the important routines */ private void processCollection(JobCollection collection) { JobProcessing job_processing = collection.getJobProcessing(); String vptslog = "-1"; String oldvptslog = "-1"; MainBufferSize = Integer.parseInt(Common.getSettings().getProperty(Keys.KEY_MainBuffer)); if (MainBufferSize <= 0) MainBufferSize = 4096000; job_processing.setSplitSize(Common.getSettings().getBooleanProperty(Keys.KEY_SplitSize) ? 0x100000L * Integer.parseInt(Common.getSettings().getProperty(Keys.KEY_ExportPanel_SplitSize_Value)) : 0); long splitsize = job_processing.getSplitSize(); job_processing.setLastHeaderBytePosition(0); job_processing.setFirstAudioPts(0); job_processing.setSplitPart(0); job_processing.setSplitLoopActive(true); job_processing.setNextFileStartPts(0); job_processing.setCutComparePoint(10000000); job_processing.setVideoExportTime(0); job_processing.setVideoExportTimeSummary(0); job_processing.setLastGopTimecode(0); job_processing.setLastGopPts(0); job_processing.setLastSimplifiedPts(0); job_processing.setMediaFilesExportLength(0); CommonParsing.setVideoFramerate(3600.0); if (Common.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_splitProjectFile)) job_processing.setProjectFileSplitSize(Long.parseLong(Common.getSettings().getProperty(Keys.KEY_ExternPanel_ProjectFileSplitSize)) * 1048576L); job_processing.setElementaryVideoStream(false); job_processing.set1stVideoPTS(-1); VBI.reset(); String[] convertType = { Resource.getString("working.convertType.demux"), Resource.getString("working.convertType.makeVDR"), Resource.getString("working.convertType.makeMPG2"), Resource.getString("working.convertType.makePVA"), Resource.getString("working.convertType.makeTS"), Resource.getString("working.convertType.packetFilter") }; /** * gets collection priority of action type */ int action = collection.getActionType(); if (action < 0) action = Common.getSettings().getIntProperty(Keys.KEY_ConversionMode); /** * determine primary file segments * scan only if changed (date modified) or not scanned, planned */ List input_files = collection.getInputFilesAsList(); int inputfiles_size = input_files.size(); int primaryInputFiles = 0; XInputFile xInputFile; StreamParserBase streamparser_basic = new StreamParserBase(); filesearch: for (int a = 0, b = -1, type = -1; a < inputfiles_size; a++) { xInputFile = ((XInputFile) input_files.get(a)).getNewInstance(); if (xInputFile == null) continue; if (xInputFile.getStreamInfo() == null) // should already be set Common.getScanClass().getStreamInfo(xInputFile); type = xInputFile.getStreamInfo().getStreamType(); if (b != -1 && b != type) break filesearch; switch (type) { case CommonParsing.PES_AV_TYPE: case CommonParsing.PES_MPA_TYPE: case CommonParsing.PES_PS1_TYPE: if (a == 0 && action == CommonParsing.ACTION_DEMUX) job_processing.setNextFileStartPts(streamparser_basic.nextFilePTS(collection, CommonParsing.PRIMARY_PES_PARSER, CommonParsing.PES_AV_TYPE, 0, 0)); break; case CommonParsing.MPEG1PS_TYPE: if (a == 0 && action == CommonParsing.ACTION_DEMUX) job_processing.setNextFileStartPts(streamparser_basic.nextFilePTS(collection, CommonParsing.PRIMARY_PES_PARSER, type, 0, 0)); break; case CommonParsing.MPEG2PS_TYPE: if (a == 0 && action == CommonParsing.ACTION_DEMUX) job_processing.setNextFileStartPts(streamparser_basic.nextFilePTS(collection, CommonParsing.PRIMARY_PES_PARSER, type, 0, 0)); break; case CommonParsing.PVA_TYPE: if (a == 0 && action == CommonParsing.ACTION_DEMUX) job_processing.setNextFileStartPts(streamparser_basic.nextFilePTS(collection, CommonParsing.PVA_PARSER, CommonParsing.PES_AV_TYPE, 0, 0)); break; case CommonParsing.TS_TYPE: if (a == 0 && action == CommonParsing.ACTION_DEMUX) job_processing.setNextFileStartPts(streamparser_basic.nextFilePTS(collection, CommonParsing.TS_PARSER, CommonParsing.PES_AV_TYPE, 0, 0)); break; default: break filesearch; } b = type; primaryInputFiles++; } collection.setPrimaryInputFileSegments(primaryInputFiles); Common.getGuiInterface().resetBitrateMonitor(); /** * loop for split output segments */ while (job_processing.isSplitLoopActive()) { Common.showSplitPart(job_processing.getSplitPart()); job_processing.clearSummaryInfo(); job_processing.clearSubStreamCounters(); job_processing.setBorrowedPts(-1); job_processing.countVideoExportTimeSummary(job_processing.getVideoExportTime()); job_processing.setVideoExportTime(0); /** * do not need the last video pts log anymore */ if (new File(vptslog).exists()) new File(vptslog).delete(); /** * loop of collection input files */ inputfile_loop: for (int i = 0; i < inputfiles_size; i++) { /** * skip the combined file segments and continue with secondary data */ if (i == 1 && collection.getPrimaryInputFileSegments() > 0) i = collection.getPrimaryInputFileSegments(); /** * secondary data empty */ if (i >= inputfiles_size) break; xInputFile = (XInputFile) input_files.get(i); Common.setMessage(""); Common.setMessage(Resource.getString("working.file", "" + i, "'" + xInputFile + "'", Common.formatNumber(xInputFile.length()))); /** * was added, but is lost now */ if (!xInputFile.exists()) { Common.setMessage(Resource.getString("working.file.not.found")); continue inputfile_loop; } /** * some probs with the length, e.g. wrong time information in the FAT */ if (xInputFile.length() <= 0) { Common.setMessage(Resource.getString("working.file.not.found") + " " + Resource.getString("ScanInfo.Size") + " " + Common.formatNumber(xInputFile.length()) + " " + Resource.getString("ScanInfo.Bytes")); continue inputfile_loop; } /** * determine filetype again */ if (xInputFile.getStreamInfo() == null) Common.getScanClass().getStreamInfo(xInputFile); int filetype = xInputFile.getStreamInfo().getStreamType(); Common.setMessage(Resource.getString("working.filetype", Keys.ITEMS_FileTypes[filetype])); /** * the parsing */ switch (filetype) { case CommonParsing.PES_AV_TYPE: if (i > 0) //added (new StreamParser(CommonParsing.SECONDARY_PES_PARSER)).parseStream(collection, xInputFile, filetype, action, vptslog); else { if (!CommonParsing.getPvaPidExtraction()) Common.setMessage(convertType[action]); if (Common.getSettings().getBooleanProperty(Keys.KEY_enhancedPES)) vptslog = (new StreamParser(CommonParsing.PRIMARY_PES_PARSER)).parseStream(collection, xInputFile, CommonParsing.MPEG2PS_TYPE, action, vptslog); else vptslog = (new StreamParser(CommonParsing.PRIMARY_PES_PARSER)).parseStream(collection, xInputFile, filetype, action, vptslog); if (action == CommonParsing.ACTION_DEMUX) CommonParsing.resetSplitMode(job_processing, vptslog); } break; case CommonParsing.MPEG1PS_TYPE: if (i > 0) (new StreamParser(CommonParsing.SECONDARY_PES_PARSER)).parseStream(collection, xInputFile, filetype, action, vptslog); else { if (!CommonParsing.getPvaPidExtraction()) Common.setMessage(convertType[action]); vptslog = (new StreamParser(CommonParsing.PRIMARY_PES_PARSER)).parseStream(collection, xInputFile, filetype, action, vptslog); if (action == CommonParsing.ACTION_DEMUX) CommonParsing.resetSplitMode(job_processing, vptslog); } break; case CommonParsing.MPEG2PS_TYPE: if (i > 0) (new StreamParser(CommonParsing.SECONDARY_PES_PARSER)).parseStream(collection, xInputFile, filetype, action, vptslog); else { if (!CommonParsing.getPvaPidExtraction()) Common.setMessage(convertType[action]); if (Common.getSettings().getBooleanProperty(Keys.KEY_simpleMPG)) vptslog = (new StreamParser(CommonParsing.PRIMARY_PES_PARSER)).parseStream(collection, xInputFile, CommonParsing.PES_AV_TYPE, action, vptslog); else vptslog = (new StreamParser(CommonParsing.PRIMARY_PES_PARSER)).parseStream(collection, xInputFile, filetype, action, vptslog); if (action == CommonParsing.ACTION_DEMUX) CommonParsing.resetSplitMode(job_processing, vptslog); } break; case CommonParsing.PVA_TYPE: if (i > 0) Common.setMessage(Resource.getString("all.msg.noprimaryfile")); else { if (!CommonParsing.getPvaPidExtraction()) Common.setMessage(convertType[action]); vptslog = (new StreamParser(CommonParsing.PVA_PARSER)).parseStream(collection, xInputFile, CommonParsing.PES_AV_TYPE, action, vptslog); if (action == CommonParsing.ACTION_DEMUX) CommonParsing.resetSplitMode(job_processing, vptslog); } break; case CommonParsing.TS_TYPE: if (i > 0) Common.setMessage(Resource.getString("all.msg.noprimaryfile")); else { if (!CommonParsing.getPvaPidExtraction()) Common.setMessage(convertType[action]); vptslog = (new StreamParser(CommonParsing.TS_PARSER)).parseStream(collection, xInputFile, CommonParsing.PES_AV_TYPE, action, null); if (action == CommonParsing.ACTION_DEMUX) CommonParsing.resetSplitMode(job_processing, vptslog); } break; case CommonParsing.PES_MPA_TYPE: case CommonParsing.PES_PS1_TYPE: if (i > 0) { CommonParsing.resetSplitMode(job_processing, vptslog); (new StreamParser(CommonParsing.SECONDARY_PES_PARSER)).parseStream(collection, xInputFile, CommonParsing.PES_AV_TYPE, action, vptslog); } else { if (!CommonParsing.getPvaPidExtraction()) Common.setMessage(convertType[action]); if (Common.getSettings().getBooleanProperty(Keys.KEY_enhancedPES)) vptslog = (new StreamParser(CommonParsing.PRIMARY_PES_PARSER)).parseStream(collection, xInputFile, CommonParsing.MPEG2PS_TYPE, action, vptslog); else vptslog = (new StreamParser(CommonParsing.PRIMARY_PES_PARSER)).parseStream(collection, xInputFile, CommonParsing.PES_AV_TYPE, action, vptslog); if (action == CommonParsing.ACTION_DEMUX) CommonParsing.resetSplitMode(job_processing, vptslog); } break; case CommonParsing.ES_MPA_TYPE: case CommonParsing.ES_AC3_A_TYPE: case CommonParsing.ES_AC3_TYPE: case CommonParsing.ES_DTS_TYPE: case CommonParsing.ES_DTS_A_TYPE: case CommonParsing.ES_RIFF_TYPE: CommonParsing.resetSplitMode(job_processing, vptslog); (new StreamParser(CommonParsing.ES_AUDIO_PARSER)).parseStream(collection, xInputFile, filetype, action, vptslog); break; case CommonParsing.ES_MPV_TYPE: vptslog = (new StreamParser(CommonParsing.ES_VIDEO_PARSER)).parseStream(collection, xInputFile, filetype, action, vptslog); CommonParsing.resetSplitMode(job_processing, vptslog); break; case CommonParsing.ES_SUP_TYPE: CommonParsing.resetSplitMode(job_processing, vptslog); (new StreamParser(CommonParsing.ES_SUBPICTURE_PARSER)).parseStream(collection, xInputFile, filetype, action, vptslog); break; case CommonParsing.Unsupported: default: Common.setMessage(Resource.getString("working.file.notsupported")); } } /** * print end of splitpart */ if (job_processing.getSplitSize() > 0) { Common.setMessage(Resource.getString("working.end.of.part") + " " + job_processing.getSplitPart()); job_processing.setSplitPart(job_processing.getSplitPart() + 1); } else job_processing.setSplitLoopActive(false); Common.setMessage(""); /** * print created files summary */ Object[] lastlist = job_processing.getSummaryInfo().toArray(); Arrays.sort(lastlist); Common.setMessage(Resource.getString("working.summary")); Common.setMessage(lastlist); job_processing.clearSummaryInfo(); if (!CommonParsing.isInfoScan()) Common.performPostCommand(lastlist); } Common.setMessage("=> " + Common.formatNumber(job_processing.getMediaFilesExportLength()) + " " + Resource.getString("working.bytes.written")); Common.setMessage(Resource.getString("all.msg.error.summary", String.valueOf(Common.getErrorCount()))); File mpegvideolog = new File(vptslog); if (mpegvideolog.exists()) mpegvideolog.delete(); collection.closeDebugLogStream(); collection.closeNormalLogStream(Common.getMessageLog()); //Common.clearMessageLog(); /** * delete tempfiles which have been multi-used */ List tempfiles = job_processing.getTemporaryFileList(); if (!tempfiles.isEmpty()) { for (int i = 0; i < tempfiles.size(); i += 2) if ( new File(tempfiles.get(i).toString()).exists() ) new File(tempfiles.get(i).toString()).delete(); tempfiles.clear(); } job_processing.setSplitSize(splitsize); Toolkit.getDefaultToolkit().beep(); } } project-x/src/net/sourceforge/dvb/projectx/parser/Scan.java0000600000175000017500000011746010406651730025466 0ustar supermariosupermario/* * @(#)SCAN.java - pre-scanning to check supported files * * Copyright (c) 2002-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import net.sourceforge.dvb.projectx.audio.AudioFormat; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.video.Video; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.xinput.StreamInfo; public class Scan extends Object { private final String msg_1 = Resource.getString("scan.msg1"); private final String msg_2 = Resource.getString("scan.msg2"); private final String msg_3 = Resource.getString("scan.msg3"); private final String msg_4 = Resource.getString("scan.msg4"); private final String msg_5 = Resource.getString("scan.msg5"); private final String msg_6 = Resource.getString("scan.msg6"); private final String msg_7 = Resource.getString("scan.msg7"); private final String msg_8 = Resource.getString("scan.msg8"); private final String msg_9 = Resource.getString("scan.msg9"); private String addInfo = ""; private String playtime = ""; private boolean hasVideo = false; private byte[] vbasic = new byte[12]; private int filetype = CommonParsing.Unsupported; private ArrayList pidlist; private ArrayList video_streams; private ArrayList audio_streams; private ArrayList ttx_streams; private ArrayList pic_streams; private AudioFormat Audio = new AudioFormat(); /** * */ public Scan() { video_streams = new ArrayList(); audio_streams = new ArrayList(); ttx_streams = new ArrayList(); pic_streams = new ArrayList(); pidlist = new ArrayList(); } /** * show ScanInfos */ public void getStreamInfo(XInputFile aXInputFile) { getStreamInfo(aXInputFile, -1); } /** * show ScanInfos */ public void getStreamInfo(XInputFile aXInputFile, int assigned_streamtype) { long length = aXInputFile.length(); String _name = getName(aXInputFile); String _location = getLocation(aXInputFile); String _date = getDate(aXInputFile); String _size = getSize(aXInputFile); StreamInfo streamInfo = aXInputFile.getStreamInfo(); if (aXInputFile.exists()) { if (streamInfo == null) streamInfo = new StreamInfo(); // type must be first when scanning streamInfo.setStreamInfo(aXInputFile.getFileType().getName(), getType(aXInputFile, assigned_streamtype), _name, _location, _date, _size, getPlaytime(), getVideo(), getAudio(), getText(), getPics()); streamInfo.setStreamType(filetype, addInfo); streamInfo.setPIDs(getPIDs()); streamInfo.setVideoHeader(getVBasic()); } else streamInfo = new StreamInfo("", Resource.getString("ScanInfo.NotFound"), _name, _location, "", "", ""); aXInputFile.setStreamInfo(streamInfo); } /** * */ private String getType(XInputFile aXInputFile, int assigned_streamtype) { filetype = testFile(aXInputFile, true, assigned_streamtype); return (Keys.ITEMS_FileTypes[filetype].toString() + addInfo); } /** * */ private String getName(XInputFile aXInputFile) { return aXInputFile.getName(); } /** * */ private String getLocation(XInputFile aXInputFile) { return aXInputFile.getParent(); } /** * */ private String getDate(XInputFile aXInputFile) { return DateFormat.getDateInstance(DateFormat.LONG).format(new Date(aXInputFile.lastModified())) + " " + DateFormat.getTimeInstance(DateFormat.LONG).format(new Date(aXInputFile.lastModified())); } /** * */ private String getSize(XInputFile aXInputFile) { long length = aXInputFile.length(); return (String.valueOf(length / 1048576) + " MB (" + Common.formatNumber(length) + " " + Resource.getString("ScanInfo.Bytes") + ")"); } /** * */ private String getPlaytime() { return playtime; } /** * */ private Object[] getVideo() { return video_streams.toArray(); } /** * */ private Object[] getAudio() { return audio_streams.toArray(); } /** * */ private Object[] getText() { return ttx_streams.toArray(); } /** * */ private Object[] getPics() { return pic_streams.toArray(); } /** * */ private Object[] getPIDs() { return pidlist.toArray(); } /** * */ private String getAudioTime(long len) { return Common.formatTime_1((len * 8000) / Audio.getBitrate()); } /** * */ public byte[] getVBasic() { if (hasVideo) return vbasic; return null; } /** * */ private int AC3Audio(byte[] check) { Audio.setNewType(CommonParsing.AC3_AUDIO); audiocheck: for (int a=0; a<10000; a++) { if (Audio.parseHeader(check, a) < 0) continue audiocheck; for (int b = 0; b < 17; b++) { if (Audio.parseNextHeader(check, a + Audio.getSize() + b) == 1) { if ( (0xFF & check[a + Audio.getSize()]) > 0x3f || (0xFF & check[a + Audio.getSize()]) == 0 ) //smpte continue audiocheck; audio_streams.add(Audio.saveAndDisplayHeader()); return 1; } } } return 0; } /* DTS stuff taken from the VideoLAN project. */ /* Added by R One, 2003/12/18. */ private void DTSAudio(byte[] check) { Audio.setNewType(CommonParsing.DTS_AUDIO); audiocheck: for (int i = 0; i < 10000; i++) { if (Audio.parseHeader(check, i) < 0) continue audiocheck; for (int j = 0; j < 15; j++) { if (Audio.parseNextHeader(check, i + Audio.getSize() + j) == 1) { if ( (0xFF & check[i + Audio.getSize()]) > 0x7F || (0xFF & check[i + Audio.getSize()]) == 0 ) //smpte continue audiocheck; audio_streams.add(Audio.saveAndDisplayHeader()); return; } } } } /** * */ private void MPEGAudio(byte[] check) { Audio.setNewType(CommonParsing.MPEG_AUDIO); audiocheck: for (int a = 0; a < 10000; a++) { if (Audio.parseHeader(check, a) < 0) continue audiocheck; if (Audio.parseNextHeader(check, a + Audio.getSize()) < 0) continue audiocheck; audio_streams.add(Audio.saveAndDisplayHeader()); return; } } /** * */ private byte[] loadPES(byte[] check, int a) { ByteArrayOutputStream bytecheck = new ByteArrayOutputStream(); int jump, offs, len; boolean mpg1; for (; a < check.length; ) { jump = (0xFF & check[a + 4])<<8 | (0xFF & check[a + 5]); mpg1 = (0x80 & check[a + 6]) == 0 ? true : false; offs = a + 6 + ( !mpg1 ? 3 + (0xFF & check[a+8]) : 0); len = jump - ( !mpg1 ? 3 + (0xFF & check[a+8]) : 0); if (offs + len > check.length) break; bytecheck.write(check, offs, len); a += 6 + jump; } return bytecheck.toByteArray(); } /** * */ private void loadMPG2(byte[] check, int b, boolean vdr, boolean mpg1, boolean nullpacket, int size) throws IOException { Hashtable table = new Hashtable(); ScanObject scanobject; String str; int jump = 1, id; int end = check.length > 580000 ? 512000 : check.length - 65000; mpg2check: for (int a = b, returncode; a < end; a += jump) { if ((returncode = CommonParsing.validateStartcode(check, a)) < 0) { jump = -returncode; continue mpg2check; } id = CommonParsing.getPES_IdField(check, a); str = String.valueOf(id); if (id == CommonParsing.PACK_START_CODE) { if ((0xC0 & check[4 + a]) == 0) //mpg1 jump = 12; else if ((0xC0 & check[4 + a]) == 0x40) //mpg2 jump = 14 + (7 & check[13 + a]); else jump = 4; } //video mpg e0..ef else if ( (0xF0 & id) == 0xE0 ) { jump = nullpacket ? 2048 : (6 + CommonParsing.getPES_LengthField(check, a)); if (!table.containsKey(str)) table.put(str, new ScanObject(id)); scanobject = (ScanObject)table.get(str); scanobject.write(check, a + 6 + (!mpg1 ? 3 + CommonParsing.getPES_ExtensionLengthField(check, a) : 0), jump - (!mpg1 ? 6 - 3 - CommonParsing.getPES_ExtensionLengthField(check, a) : 0) ); } //audio mpg c0..df else if ( (0xE0 & id) == 0xC0 ) { jump = 6 + CommonParsing.getPES_LengthField(check, a); if (!table.containsKey(str)) table.put(str, new ScanObject(id)); scanobject = (ScanObject)table.get(str); scanobject.write(check, a, jump ); } //private bd else if (id == CommonParsing.PRIVATE_STREAM_1_CODE) { jump = 6 + CommonParsing.getPES_LengthField(check, a); int pes_extensionlength = CommonParsing.getPES_ExtensionLengthField(check, a); boolean pes_alignment = (4 & check[a + 6]) != 0; if (pes_extensionlength == 0x24 && (0xF0 & check[a + 9 + pes_extensionlength])>>>4 == 1) { str = "SubID 0x" + Integer.toHexString((0xFF & check[a + 9 + pes_extensionlength])).toUpperCase(); if (ttx_streams.indexOf(str) < 0) ttx_streams.add(str); } else if ( ((!mpg1 && !vdr) || (vdr && pes_alignment)) && ((0xF0 & check[a + 9 + pes_extensionlength])>>>4 == 2 || (0xF0 & check[a + 9 + pes_extensionlength])>>>4 == 3)) { str = "SubID 0x" + Integer.toHexString((0xFF & check[a + 9 + pes_extensionlength])).toUpperCase(); if (pic_streams.indexOf(str) < 0) pic_streams.add(str); } else { if (!vdr) { id = 0xFF & check[a + 9 + pes_extensionlength]; str = String.valueOf(id); check[a + 8] = (byte)(4 + pes_extensionlength); } if (!table.containsKey(str)) table.put(str, new ScanObject(id)); scanobject = (ScanObject)table.get(str); scanobject.write(check, a, jump ); } } else { switch (id) { case 0xBB: case 0xBC: case 0xBE: case 0xBF: case 0xF0: case 0xF1: case 0xF2: case 0xF3: case 0xF4: case 0xF5: case 0xF6: case 0xF7: case 0xF8: case 0xF9: case 0xFA: case 0xFB: case 0xFC: case 0xFD: case 0xFE: case 0xFF: jump = 6 + CommonParsing.getPES_LengthField(check, a); break; default: jump = 1; } } } for (Enumeration n = table.keys(); n.hasMoreElements() ; ) { str = n.nextElement().toString(); id = Integer.parseInt(str); scanobject = (ScanObject)table.get(str); if ( (0xF0 & id) == 0xE0) { try { checkVid(scanobject.getData()); } catch (Exception e) { video_streams.add(msg_8); } } else { try { checkPES(scanobject.getData()); } catch (Exception e) { audio_streams.add(msg_8); } } } table.clear(); return; } /** * */ private void loadPVA(byte[] check, int a) throws IOException { Hashtable table = new Hashtable(); ScanObject scanobject; String str; int jump, id; int end = check.length > 580000 ? 512000 : check.length - 65000; while ( a < end) { jump = (0xFF & check[a+6])<<8 | (0xFF & check[a+7]); if (a + 8 + ((1 & check[a+5]>>>4) * 4) + jump > check.length) break; id = 0xFF & check[a+2]; str = String.valueOf(id); if (!table.containsKey(str)) table.put(str, new ScanObject(id)); scanobject = (ScanObject)table.get(str); switch (id) { case 1: scanobject.write(check, a + 8 + ((1 & check[a+5]>>>4) * 4), jump ); break; default: scanobject.write(check, a + 8, jump ); } a += 8 + jump; } for (Enumeration n = table.keys(); n.hasMoreElements() ; ) { str = n.nextElement().toString(); scanobject = (ScanObject)table.get(str); if (str.equals("1")) { try { checkVid(scanobject.getData()); } catch ( Exception e) { video_streams.add(msg_8); } } else { try { checkPES(scanobject.getData()); } catch ( Exception e) { audio_streams.add(msg_8); } } } table.clear(); return; } /** * */ private void checkPES(byte[] check) { checkPES(check, 0); } /** * */ private void checkPES(byte[] check, int a) { int end = a + 8000; rawcheck: for (int returncode; a < end; a++) { if ((returncode = CommonParsing.validateStartcode(check, a)) < 0) { a += (-returncode) - 1; continue rawcheck; } if ( (0xE0 & check[a+3]) == 0xC0 || CommonParsing.getPES_IdField(check, a) == CommonParsing.PRIVATE_STREAM_1_CODE) { int next = a + 6 + CommonParsing.getPES_LengthField(check, a); if (CommonParsing.validateStartcode(check, next) < 0) continue rawcheck; if ( (0xE0 & check[a+3]) == 0xC0 && (0xE0 & check[a+3]) == (0xE0 & check[next+3]) ) { MPEGAudio(loadPES(check,a)); return; } else if (CommonParsing.getPES_IdField(check, a) == CommonParsing.PRIVATE_STREAM_1_CODE && CommonParsing.getPES_IdField(check, a) == CommonParsing.getPES_IdField(check, next)) { byte buffer[] = loadPES(check, a); if (AC3Audio(buffer) < 1) DTSAudio(buffer); return; } } } } /** * */ private void checkVid(byte[] check) { checkVid(check, check.length - 630); } /** * */ private boolean checkVid(byte[] check, int length) { ByteArrayOutputStream bytecheck = new ByteArrayOutputStream(); for (int i = 0, returncode, pes_ID; i < length; i++) { if ((returncode = CommonParsing.validateStartcode(check, i)) < 0 || CommonParsing.getPES_IdField(check, i) != CommonParsing.SEQUENCE_HEADER_CODE) { i += (returncode < 0 ? -returncode : 4) - 1; continue; } for (int j = 7, mpgtype = 1; j < 600; j++) { if ((returncode = CommonParsing.validateStartcode(check, i + j)) < 0) { j += (-returncode) - 1; continue; } pes_ID = CommonParsing.getPES_IdField(check, i + j); if (pes_ID == CommonParsing.EXTENSION_START_CODE && (0xF0 & check[4 + i + j]) == 0x10) mpgtype = 2; else if (pes_ID == CommonParsing.GROUP_START_CODE || pes_ID == CommonParsing.PICTURE_START_CODE) { hasVideo = true; System.arraycopy(check, i, vbasic, 0, 12); bytecheck.write(check, i, 20); video_streams.add("MPEG-" + mpgtype + ", " + Video.getVideoformatfromBytes(bytecheck.toByteArray())); return true; } } } return checkH264(check, length); //return false; } /** * */ private boolean checkH264(byte[] check, int length) { ByteArrayOutputStream bytecheck = new ByteArrayOutputStream(); int[] BitPosition = { 0 }; for (int i = 0, flag, nal_unit, nal_ref, profile, forb_zero, level_idc, hori, vert, j = length - 50; i < j; i++) { if (check[i] != 0 || check[1 + i] != 0 || check[2 + i] != 0 || check[3 + i] != 1) continue; BitPosition[0] = (4 + i)<<3; forb_zero = getBits(check, BitPosition, 1); //forb_zero = 0x80 & check[4 + i]; nal_ref = getBits(check, BitPosition, 2); //nal_ref = (0xE0 & check[4 + i])>>>5; nal_unit = getBits(check, BitPosition, 5); //nal_unit = 0x1F & check[4 + i]; if (forb_zero != 0 || nal_unit != 7) continue; //seq_param profile = getBits(check, BitPosition, 8); //profile = 0xFF & check[5 + i]; getBits(check, BitPosition, 3); //constraint 0,1,2 getBits(check, BitPosition, 5); //5 zero_bits level_idc = getBits(check, BitPosition, 8); //0xFF & check[7 + i]; flag = getCodeNum(check, BitPosition); // seq_parameter_set_id 0 ue(v) flag = getCodeNum(check, BitPosition); // log2_max_frame_num_minus4 0 ue(v) flag = getCodeNum(check, BitPosition); // pic_order_cnt_type 0 ue(v) if (flag == 0) getCodeNum(check, BitPosition); // log2_max_pic_order_cnt_lsb_minus4 0 ue(v) else if (flag == 1) { getBits(check, BitPosition, 1); //delta_pic_order_always_zero_flag 0 u(1) getSignedCodeNum(check, BitPosition); //offset_for_non_ref_pic 0 se(v) getSignedCodeNum(check, BitPosition); //offset_for_top_to_bottom_field 0 se(v) flag = getCodeNum(check, BitPosition); // num_ref_frames_in_pic_order_cnt_cycle 0 ue(v) for (int k = 0; k < flag; k++) getSignedCodeNum(check, BitPosition); //offset_for_ref_frame[ i ] 0 se(v) } getCodeNum(check, BitPosition); //num_ref_frames 0 ue(v) getBits(check, BitPosition, 1); //gaps_in_frame_num_value_allowed_flag 0 u(1) hori = 16 * (1 + getCodeNum(check, BitPosition)); //pic_width_in_mbs_minus1 0 ue(v) vert = 16 * (1 + getCodeNum(check, BitPosition)); //pic_height_in_map_units_minus1 0 ue(v) flag = getBits(check, BitPosition, 1); //frame_mbs_only_flag 0 u(1) video_streams.add("MPEG-4/H.264, " + hori + "*" + (flag == 0 ? vert<<1 : vert)); return true; } return false; } /** * */ private int getSignedCodeNum(byte[] array, int[] BitPosition) { int codeNum = getCodeNum(array, BitPosition); codeNum = (codeNum & 1) == 0 ? codeNum>>>1 : -(codeNum>>>1); return codeNum; } /** * */ private int getCodeNum(byte[] array, int[] BitPosition) { int leadingZeroBits = -1; int codeNum; for (int b = 0; b == 0; leadingZeroBits++) b = getBits(array, BitPosition, 1); codeNum = (1<>>3; if (N == 0) return 0; if (Pos >= array.length - 4) { BitPosition[0] += N; return -1; } Val = (0xFF & array[Pos])<<24 | (0xFF & array[Pos + 1])<<16 | (0xFF & array[Pos + 2])<<8 | (0xFF & array[Pos + 3]); Val <<= BitPosition[0] & 7; Val >>>= 32 - N; BitPosition[0] += N; return Val; } /** * */ private void readPMT(byte[] check, int a) { ByteArrayOutputStream bytecheck = new ByteArrayOutputStream(); // pidlist.clear(); boolean ts_start = false; tscheck: for (int adaptfield, pmtpid, offset; a < check.length - 1000; a++) { if ( check[a] != 0x47 || check[a + 188] != 0x47 || check[a + 376] != 0x47 ) continue tscheck; if ((0x40 & check[a + 1]) == 0) // start continue tscheck; if ((0xC0 & check[a + 3]) != 0) // scrambling continue tscheck; adaptfield = (0x30 & check[a + 3])>>>4; if ((adaptfield & 1) == 0) // adapt - no payload continue tscheck; offset = adaptfield == 3 ? 1 + (0xFF & check[a + 4]) : 0; //adaptlength if (check[a + offset + 4] != 0 || check[a + offset + 5] != 2 || (0xF0 & check[a + offset + 6]) != 0xB0) { a += 187; continue tscheck; } bytecheck.write(check, a + 4 + offset, 184 - offset); pmtpid = (0x1F & check[a + 1])<<8 | (0xFF & check[a + 2]); if ( bytecheck.size() < 188 ) { a += 188; addpack: for ( ; a < check.length - 500; a++) { if ( check[a] != 0x47 || check[a + 188] != 0x47 || check[a + 376] != 0x47 ) continue addpack; if ((0x40 & check[a + 1]) != 0) // start continue addpack; if ((0xC0 & check[a + 3]) != 0) // scrambling continue addpack; adaptfield = (0x30 & check[a + 3])>>>4; if ((adaptfield & 1) == 0) // adapt - no payload continue addpack; offset = adaptfield == 3 ? 1 + (0xFF & check[a + 4]) : 0; //adaptlength if ( ((0x1F & check[a + 1])<<8 | (0xFF & check[a + 2])) != pmtpid ) { a += 187; continue addpack; } bytecheck.write(check, a + 4 + offset, 184 - offset); if ( bytecheck.size() > 188 ) break addpack; } } byte[] pmt = bytecheck.toByteArray(); if (pmt.length > 5) { int sid = (0xFF & pmt[4])<<8 | (0xFF & pmt[5]); pidlist.add("" + sid); pidlist.add("" + pmtpid); addInfo = " (SID 0x" + Integer.toHexString(sid).toUpperCase() + " ,PMT 0x" + Integer.toHexString(pmtpid).toUpperCase() + ")"; } int pmt_len = (0xF&pmt[2])<<8 | (0xFF&pmt[3]); pidsearch: for (int b=8, r=8; b < pmt_len-4 && b < pmt.length-6; b++) { r = b; if ( (0xe0 & pmt[b+1]) != 0xe0 ) continue pidsearch; int pid = (0x1F & pmt[b+1])<<8 | (0xFF & pmt[b+2]); switch(0xFF & pmt[b]) { case 1: case 2: getDescriptor(pmt, b+5, (b += 4+ (0xFF & pmt[b+4])), pid, 2); pidlist.add("" + pid); break; case 3: case 4: getDescriptor(pmt, b+5, (b += 4+ (0xFF & pmt[b+4])), pid, 4); pidlist.add("" + pid); break; case 0x1B: getDescriptor(pmt, b+5, (b += 4+ (0xFF & pmt[b+4])), pid, 0x1B); pidlist.add("" + pid); break; case 0x80: case 0x81: //private data of AC3 in ATSC case 0x82: case 0x83: case 6: getDescriptor(pmt, b+5, (b += 4+ (0xFF & pmt[b+4])), pid, 6); pidlist.add("" + pid); break; default: b += 4+ (0xFF & pmt[b+4]); } if (b < 0) b = r; } return; } return; } /** * */ private void getDescriptor(byte check[], int off, int end, int pid, int type) { String str = ""; int chunk_end = 0; try { loop: for (; off < end && off < check.length; off++) { switch(0xFF & check[off]) { case 0x59: //dvb subtitle descriptor type = 0x59; chunk_end = off + 2 + (0xFF & check[off+1]); str += "("; for (int a=off+2; a>>3; int page_number = 0xFF & check[a+4]; str += "_"; switch (page_type) { case 1: str += "i"; break; case 2: str += "s"; break; case 3: str += "ai"; break; case 4: str += "ps"; break; case 5: str += "s.hip"; break; default: str += "res"; } str += Integer.toHexString((7 & check[a+3]) == 0 ? 8 : (7 & check[a+3])).toUpperCase(); str += (page_number < 0x10 ? "0" : "") + Integer.toHexString(page_number).toUpperCase() + " "; } str += ")"; //break loop; off++; off += (0xFF & check[off]); break; case 0xA: //ISO 639 language descriptor str += "("; for (int a=off+2; a 0) return returncode; } catch (Exception e) { playtime = msg_8; Common.setExceptionMessage(e); } check = null; return CommonParsing.Unsupported; } /** * */ private int scanRiffAudio(byte[] check, int buffersize, boolean more, long size) throws Exception { Audio.setNewType(CommonParsing.WAV_AUDIO); riffcheck: for (int i = 0, ERRORCODE; i < buffersize; i++) //compressed as AC3,MPEG is currently better detected as ES-not RIFF { ERRORCODE = Audio.parseHeader(check, i); if (ERRORCODE > -1) { Audio.saveHeader(); if (more) { audio_streams.add(Audio.displayHeader()); playtime = getAudioTime(size); } if (ERRORCODE > 0) return CommonParsing.ES_RIFF_TYPE; else if (Audio.getLastModeExtension() > 1) break riffcheck; else return CommonParsing.ES_cRIFF_TYPE; } } return -1; } /** * */ private int scanSubpicture(byte[] check, int buffersize, boolean more) throws Exception { supcheck: for (int i = 0, supframe_size, supframe_link, supframe_check, supframe_check2; i < buffersize; i++) { if (check[i] != 0x53 || check[i + 1]!=0x50) continue supcheck; supframe_size = (0xFF & check[i + 10])<<8 | (0xFF & check[i + 11]); supframe_link = (0xFF & check[i + 12])<<8 | (0xFF & check[i + 13]); supframe_check = (0xFF & check[i + 12 + supframe_link])<<8 | (0xFF & check[i + 13 + supframe_link]); supframe_check2 = (0xFF & check[i + 36 + supframe_link])<<8 | (0xFF & check[i + 37 + supframe_link]); if (supframe_link == supframe_check - 24 && supframe_check == supframe_check2) { if (more) { int b = i + 14 + supframe_link, c = b + 24, d, xa, xe, ya, ye; for (d = b; d < c; d++) { switch(0xFF & check[d]) { case 1: d++; continue; case 2: d += 24; continue; case 3: case 4: d += 2; continue; case 6: d += 4; continue; case 5: xa= (0xFF & check[++d])<<4 | (0xF0 & check[++d])>>>4; xe= (0xF & check[d])<<8 | (0xFF & check[++d]); ya= (0xFF & check[++d])<<4 | (0xF0 & check[++d])>>>4; ye= (0xF & check[d])<<8 | (0xFF & check[++d]); pic_streams.add("up.left x" + xa + ",y" + ya + " @ size " + (xe - xa + 1) + "*" + (ye - ya + 1)); } break; } byte packet[] = new byte[10 + supframe_size]; System.arraycopy(check, i, packet, 0, 10 + supframe_size); // shows first found subpicture scaled on OSD Common.getSubpictureClass().decode_picture(packet, 10, true, new String[2]); } return CommonParsing.ES_SUP_TYPE; } } return -1; } /** * */ private int scanTS(byte[] check, int buffersize, boolean more) throws Exception { mpegtscheck: for (int i = 0; i < buffersize; i++) { if ( check[i] != 0x47 || check[i + 188] != 0x47 || check[i + 376] != 0x47 || check[i + 564] != 0x47 || check[i + 752] != 0x47) continue mpegtscheck; readPMT(check, i); return CommonParsing.TS_TYPE; } return -1; } /** * */ private int scanPVA(byte[] check, int buffersize, boolean more) throws Exception { pvacheck: for (int i = 0; i < buffersize; i++) { if ( check[i] != 0x41 || check[i + 1] != 0x56 || check[i + 4] != 0x55 ) continue pvacheck; int next = i + 8 + ((0xFF & check[i + 6])<<8 | (0xFF & check[i + 7])); if ( check[next] != 0x41 || check[next + 1] != 0x56 || check[next + 4] != 0x55 ) continue pvacheck; else { if (more) loadPVA(check, i); return CommonParsing.PVA_TYPE; } } return -1; } /** * */ private int scanMpg12(byte[] check, int buffersize_1, int buffersize_2, boolean more) throws Exception { boolean nullpacket = false; mpgcheck: for (int i = 0, j, flag, returncode; i < buffersize_1; i++) { if ((returncode = CommonParsing.validateStartcode(check, i)) < 0 || CommonParsing.getPES_IdField(check, i) != CommonParsing.PACK_START_CODE) { i += (returncode < 0 ? -returncode : 4) - 1; continue mpgcheck; } flag = 0xC0 & check[i + 4]; if (flag == 0) { j = i + 12; if (CommonParsing.validateStartcode(check, j) < 0 || CommonParsing.getPES_IdField(check, j) < CommonParsing.SEQUENCE_HEADER_CODE) continue mpgcheck; if (more) loadMPG2(check, i, false, true, nullpacket, buffersize_2); return CommonParsing.MPEG1PS_TYPE; } else if (flag == 0x40 ) { j = i + 14 + (7 & check[i + 13]); if (CommonParsing.validateStartcode(check, j) < 0 || CommonParsing.getPES_IdField(check, j) < CommonParsing.SEQUENCE_HEADER_CODE) continue mpgcheck; if (more) loadMPG2(check, i, Common.getSettings().getBooleanProperty(Keys.KEY_simpleMPG), false, nullpacket, buffersize_2); return CommonParsing.MPEG2PS_TYPE; } } return -1; } /** * */ private int scanPrimaryPES(byte[] check, int buffersize_1, int buffersize_2, boolean more) throws Exception { boolean nullpacket = false; vdrcheck: for (int i = 0, returncode; i < buffersize_1; i++) { if ((returncode = CommonParsing.validateStartcode(check, i)) < 0 || (0xF0 & CommonParsing.getPES_IdField(check, i)) != 0xE0) { i += (returncode < 0 ? -returncode : 4) - 1; continue vdrcheck; } int next = i + 6 + CommonParsing.getPES_LengthField(check, i); if ( (next == i + 6) && (0xC0 & check[i + 6]) == 0x80 && (0xC0 & check[i + 8]) == 0) { addInfo = " !!(VPacketLengthField is 0)"; next = i; nullpacket = true; } if (CommonParsing.validateStartcode(check, next) < 0) continue vdrcheck; else { if (more) loadMPG2(check, i, !Common.getSettings().getBooleanProperty(Keys.KEY_enhancedPES), false, nullpacket, buffersize_2); return CommonParsing.PES_AV_TYPE; } } return -1; } /** * */ private int scanSecondaryPES(byte[] check, int buffersize_1, int buffersize_2, boolean more) throws Exception { boolean nullpacket = false; rawcheck: for (int i = 0, returncode; i < buffersize_1; i++) { if ((returncode = CommonParsing.validateStartcode(check, i)) < 0) { i += (-returncode) - 1; continue rawcheck; } if ( (0xE0 & check[i + 3]) == 0xC0 || (0xFF & check[i + 3]) == 0xBD ) { int next = i + 6 + CommonParsing.getPES_LengthField(check, i); if (CommonParsing.validateStartcode(check, next) < 0) continue rawcheck; if ( (0xE0 & check[i + 3]) == 0xC0 && (0xE0 & check[i + 3]) == (0xE0 & check[next + 3]) ) { if (more) loadMPG2(check, i, true, false, nullpacket, buffersize_2); return CommonParsing.PES_MPA_TYPE; } else if ( (0xFF & check[i + 3]) == 0xBD && check[i + 3] == check[next + 3] ) { if (more) { if (check[i + 8] == 0x24 && (0xF0 & check[i + 9 + 0x24])>>>4 == 1) { addInfo = " (TTX)"; ttx_streams.add("SubID 0x" + Integer.toHexString((0xFF & check[i + 9 + 0x24])).toUpperCase()); } else loadMPG2(check, i, true, false, nullpacket, buffersize_2); } return CommonParsing.PES_PS1_TYPE; } } } return -1; } /** * */ private int scanDtsAudio(byte[] check, int buffersize, boolean more, long size) throws Exception { Audio.setNewType(CommonParsing.DTS_AUDIO); audiocheck: for (int i = 0; i < buffersize; i++) { /* DTS stuff taken from the VideoLAN project. */ /* Added by R One, 2003/12/18. */ if (Audio.parseHeader(check, i) < 1) continue; for (int b = 0; b < 15; b++) { if (Audio.parseNextHeader(check, i + Audio.getSize() + b) != 1) continue; if ( (0xFF & check[i + Audio.getSize()]) > 0x7F || (0xFF & check[i + Audio.getSize()]) == 0 ) //smpte continue audiocheck; if (more) { audio_streams.add(Audio.saveAndDisplayHeader()); playtime = getAudioTime(size); } if (b == 0) return CommonParsing.ES_DTS_TYPE; else return CommonParsing.ES_DTS_A_TYPE; } if (Common.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_allowSpaces)) { if (more) audio_streams.add(Audio.saveAndDisplayHeader()); playtime = getAudioTime(size); return CommonParsing.ES_DTS_TYPE; } } return -1; } /** * */ private int scanAc3Audio(byte[] check, int buffersize, boolean more, long size) throws Exception { Audio.setNewType(CommonParsing.AC3_AUDIO); audiocheck: for (int i = 0; i < buffersize; i++) { if (Audio.parseHeader(check, i) < 1) continue; for (int b = 0; b < 17; b++) { if (Audio.parseNextHeader(check, i + Audio.getSize() + b) != 1) continue; if ( (0xFF & check[i + Audio.getSize()]) > 0x3F || (0xFF & check[i + Audio.getSize()]) == 0 ) //smpte continue audiocheck; if (more) { audio_streams.add(Audio.saveAndDisplayHeader()); playtime = getAudioTime(size); } if (b == 0) return CommonParsing.ES_AC3_TYPE; else return CommonParsing.ES_AC3_A_TYPE; } if (Common.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_allowSpaces)) { if (more) audio_streams.add(Audio.saveAndDisplayHeader()); playtime = getAudioTime(size); return CommonParsing.ES_AC3_TYPE; } } return -1; } /** * */ private int scanMpgAudio(byte[] check, int buffersize, boolean more, long size) throws Exception { Audio.setNewType(CommonParsing.MPEG_AUDIO); audiocheck: for (int i = 0; i < buffersize; i++) { if (Audio.parseHeader(check, i) < 1) continue; if (!Common.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_allowSpaces) && Audio.parseNextHeader(check, i + Audio.getSize()) < 0) continue audiocheck; if (more) { audio_streams.add(Audio.saveAndDisplayHeader()); playtime = getAudioTime(size); } return CommonParsing.ES_MPA_TYPE; } return -1; } /** * */ private int scanMpgVideo(byte[] check, int buffersize, boolean more) throws Exception { mpvcheck: if (checkVid(check, buffersize)) return CommonParsing.ES_MPV_TYPE; return -1; } /** * */ private class ScanObject { private ByteArrayOutputStream buf = null; private int id; private int type; private ScanObject() { buf = new ByteArrayOutputStream(); id = 0; } private ScanObject(int val1) { buf = new ByteArrayOutputStream(); id = val1; } private int getType() { return type; } private void write(byte data[]) throws IOException { buf.write(data); } private void write(byte data[], int offset, int length) throws IOException { buf.write(data, offset, length); } private byte[] getData() throws IOException { buf.flush(); return buf.toByteArray(); } private void reset() { buf.reset(); } } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamBuffer.java0000600000175000017500000000527710351107426027166 0ustar supermariosupermario/* * @(#)StreamBuffer.java - * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.ByteArrayOutputStream; /** * stuff for pre-buffering of PID data */ public class StreamBuffer extends Object { private boolean pidstart = false; private boolean pidscram = false; private boolean need = true; private int ID = -1; private int PID = -1; private int demux = -1; private int counter = -1; private ByteArrayOutputStream buffer; public StreamBuffer() { buffer = new ByteArrayOutputStream(); } public void setStarted(boolean b) { pidstart = b; } public boolean isStarted() { return pidstart; } public void setScram(boolean b) { pidscram = b; } public boolean getScram() { return pidscram; } public void setID(int val) { ID = val; } public int getID() { return ID; } public void setCounter(int val) { counter = val; } public int getCounter() { return counter; } public void count() { counter += (counter < 15) ? 1 : -15 ; } public void countPVA() { counter += (counter < 255) ? 1 : -255 ; } public void setPID(int val) { PID = val; } public int getPID() { return PID; } public void setDemux(int val) { demux = val; } public int getDemux() { return demux; } public void setneeded(boolean b) { need = b; } public boolean isneeded() { return need; } public void writeData(byte[] data, int off, int len) { buffer.write(data, off, len); } public ByteArrayOutputStream getData() { return buffer; } public int getDataSize() { return buffer.size(); } public void reset() { buffer.reset(); } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamConverter.java0000600000175000017500000011634410365007114027720 0ustar supermariosupermario/* * @(#)StreamConverter * * Copyright (c) 2005-2006 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.util.ArrayList; import java.util.List; import java.util.Arrays; import java.io.File; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.io.IDDBufferedOutputStream; import net.sourceforge.dvb.projectx.thirdparty.TS; import net.sourceforge.dvb.projectx.video.Video; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.parser.StreamDemultiplexer; /** * create streams */ public class StreamConverter extends Object { private String FileName = ""; private boolean FirstPacket = true; private boolean ptsover = false; private boolean ContainsVideo = false; private boolean BrokenLinkFlag = false; private boolean Debug = false; private boolean AddPcrToStream = false; private boolean ExportVideo = false; private boolean ExportNonVideo = false; private boolean MustStartWithVideo = false; private boolean SetMainAudioAc3 = false; private boolean GenerateTTX = false; private boolean GeneratePMT = false; private boolean PcrCounter = false; private boolean CreateVdrIndex = false; private byte[] PackHeader = { 0, 0, 1, (byte)0xBA, 0x44, 0, 4, 0, 4, 1, 0, (byte)0xEA, 0x63, (byte)0xF8 }; // 8000kbps private byte[] LeadingPackHeader = { 0, 0, 1, (byte)0xBA, 0x44, 0, 4, 0, 4, 1, 0, (byte)0xEA, 0x63, (byte)0xF8 }; // 8000kbps private byte[] SequenceEndCode = { 0, 0, 1, (byte)0xB9 }; private byte[] TsStartPacketHeader = { 0x47, 0x40, 0, 0 }; // 1x = no adap, 3x adap follw private byte[] TsSubPacketHeader = { 0x47, 0, 0, 0 }; // 1x = no adap, 3x adap follw private byte[] PvaPacketHeader = { 0x41, 0x56, 0, 0, 0x55, 0, 0, 0 }; private byte[] PvaPacketHeaderAndPTS = { 0x41, 0x56, 0, 0, 0x55, 0x10, 0, 0, 0, 0, 0, 0 }; private byte[] SystemHeader = { 0, 0, 1, (byte)0xBB, 0, 0xC, (byte)0x80, (byte)0x9C, 0x41, 4, 0x21, 0x7F }; // 12+ byte std 1A, 1V 8Mbps (20000 * 400) private byte[][] sys = { { (byte)0xE0, (byte)0xE0, (byte)0xE0 }, // 224kb 0 MPV { (byte)0xBD, (byte)0xC0, 0x20 }, // 4kb 1 pd_AC3 { (byte)0xC0, (byte)0xC0, 0x20 } // 4kb 2 MPA }; private byte[] subID = { (byte)0x80, 1, 0, 1 }; // std 0x80,1,0,1 private byte[] sysID = { (byte)0xE0, (byte)0xC0 }; // ID adder mpv+mpa private byte[] adapt = { 0, 0 }; private byte[] StuffingData = new byte[2324]; private long[] time = new long[2]; private long SCR_Value = 0; private long PmtCounter = 0; private long PCR_Delta = 65000; private final int PVA_MAINVIDEO = 1; private final int PVA_MAINAUDIO = 2; private int Action = 0; private int CutMode = 0; private int SystemHeaderInsertPoint = 26; private int SystemHeaderLength = 138; private int Packet = 0; private int TsHeaderMode = 0; private int[] PacketCounter = new int[70]; // pva counter , 1=stream1,2=stream2 4... rest private int[] SystemHeaderStreams = new int[2]; // number of audio[0], video[1] streams private List PaddingStreamPositions; private List IDs; private IDDBufferedOutputStream OutputStream; private ByteArrayOutputStream Buffer; public StreamConverter() { PaddingStreamPositions = new ArrayList(); IDs = new ArrayList(); Buffer = new ByteArrayOutputStream(); } /** * */ private void getSettings() { ExportVideo = Common.getSettings().getBooleanProperty(Keys.KEY_WriteOptions_writeVideo); ExportNonVideo = Common.getSettings().getBooleanProperty(Keys.KEY_WriteOptions_writeAudio); Debug = Common.getSettings().getBooleanProperty(Keys.KEY_DebugLog); PCR_Delta = Long.parseLong(Common.getSettings().getProperty(Keys.KEY_PcrDelta_Value)); CutMode = Common.getSettings().getIntProperty(Keys.KEY_CutMode); AddPcrToStream = Common.getSettings().getBooleanProperty(Keys.KEY_Conversion_addPcrToStream); MustStartWithVideo = Common.getSettings().getBooleanProperty(Keys.KEY_Conversion_startWithVideo); SetMainAudioAc3 = Common.getSettings().getBooleanProperty(Keys.KEY_TS_setMainAudioAc3); GenerateTTX = Common.getSettings().getBooleanProperty(Keys.KEY_TS_generateTtx); GeneratePMT = Common.getSettings().getBooleanProperty(Keys.KEY_TS_generatePmt); TsHeaderMode = Common.getSettings().getIntProperty(Keys.KEY_TsHeaderMode); PcrCounter = Common.getSettings().getBooleanProperty(Keys.KEY_Conversion_PcrCounter); CreateVdrIndex = Common.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createVdrIndex); } /** * */ public void init(String _name, int buffersize, int action, int filenumber) { FileName = _name; FirstPacket = true; ContainsVideo = false; Action = action; BrokenLinkFlag = false; ptsover = false; PmtCounter = 0; SystemHeaderInsertPoint = 26; LeadingPackHeader[2] = 0; time[0] = -1; SCR_Value = 0; Packet = 0; getSettings(); Arrays.fill(StuffingData, (byte)0xFF); Buffer.reset(); if (filenumber == 0) IDs.clear(); try { OutputStream = new IDDBufferedOutputStream(new FileOutputStream(FileName), buffersize); if (Action == CommonParsing.ACTION_TO_VDR && CreateVdrIndex) OutputStream.InitVdr(new File(FileName).getParent() + System.getProperty("file.separator") + "index.vdr", filenumber); } catch (IOException e) { Common.setExceptionMessage(e); } } /** * set broken link flag after a cut */ private void setBrokenLink(byte[] pes_packet, int pes_offset) { if (CommonParsing.validateStartcode(pes_packet, pes_offset) < 0) { Common.setMessage("!> invalid start_code of packet"); return; } int pes_payloadlength = CommonParsing.getPES_LengthField(pes_packet, pes_offset); int pes_headerlength = 9; int pes_packetlength = pes_headerlength - 3 + pes_payloadlength; int pes_extensionlength = CommonParsing.getPES_ExtensionLengthField(pes_packet, pes_offset); for (int i = pes_headerlength + pes_extensionlength + pes_offset, j = pes_packetlength - 7 + pes_offset, returncode; i < j; ) { if ((returncode = CommonParsing.validateStartcode(pes_packet, i)) < 0 || CommonParsing.getPES_IdField(pes_packet, i) != CommonParsing.GROUP_START_CODE) { i += returncode < 0 ? -returncode : 4; continue; } pes_packet[7 + i] |= 0x20; break; } BrokenLinkFlag = true; // even if it wasn't found } /** * repack mpg1 to mpg2 */ private void repackMpg1(byte[] pes_packet, int pes_offset, StreamDemultiplexer streamdemultiplexer) { if (streamdemultiplexer.getStreamType() != CommonParsing.MPEG1PS_TYPE) return; int pes_packetoffset = 6; int pes_headerlength = 9; int pes_extensionlength = 0; int pes_payloadlength = CommonParsing.getPES_LengthField(pes_packet, pes_offset); int pes_packetlength = pes_packetoffset + pes_payloadlength; int offset = pes_packetoffset; int value = 0x800000; skiploop: for (;;) { switch (0xC0 & pes_packet[offset + pes_offset]) { case 0x40: offset += 2; continue skiploop; case 0x80: offset += 3; continue skiploop; case 0xC0: offset++; continue skiploop; case 0: break; } switch (0x30 & pes_packet[offset + pes_offset]) { case 0x20: //PTS pes_extensionlength = 5; break skiploop; case 0x30: //PTS+DTS pes_extensionlength = 10; break skiploop; case 0x10: //DTS offset += 5; break skiploop; case 0: offset++; break skiploop; } } if (pes_extensionlength == 5) value = 0x808005; else if (pes_extensionlength == 10) value = 0x80C00A; System.arraycopy(pes_packet, offset + pes_offset, pes_packet, pes_headerlength + pes_offset, pes_packetlength - offset); CommonParsing.setValue(pes_packet, pes_packetoffset + pes_offset, 3, !CommonParsing.BYTEREORDERING, value); CommonParsing.setPES_LengthField(pes_packet, pes_offset, pes_packetlength - offset + 3); } /** * */ private void setSCRField(byte[] packet_header) { if (Debug) System.out.println("SCR_Value " + SCR_Value); if (!AddPcrToStream) return; packet_header[4] = (byte)(0x44 | (0x3 & (SCR_Value>>>28)) | (0x38 & (SCR_Value>>>27))); packet_header[5] = (byte)(0xFF & (SCR_Value>>>20)); packet_header[6] = (byte)(0x4 | (0x3 & (SCR_Value>>>13)) | (0xF8 & (SCR_Value>>>12))); packet_header[7] = (byte)(0xFF & (SCR_Value>>>5)); packet_header[8] = (byte)(0x4 | (0xF8 & (SCR_Value<<3))); } /** * */ private void updateSCR(int length) { SCR_Value += (length * 8) / 150; } /** * */ private void updateSCR(long value) { SCR_Value += value; } /** * entry point and pre functions */ public void write(JobProcessing job_processing, byte[] pes_packet, StreamDemultiplexer streamdemultiplexer, long cutposition, boolean qinfo, List cutpoints) throws IOException { write(job_processing, pes_packet, 0, pes_packet.length, streamdemultiplexer, cutposition, qinfo, cutpoints); } /** * entry point and pre functions */ public void write(JobProcessing job_processing, byte[] pes_packet, int pes_offset, StreamDemultiplexer streamdemultiplexer, long cutposition, boolean qinfo, List cutpoints) throws IOException { write(job_processing, pes_packet, pes_offset, pes_packet.length, streamdemultiplexer, cutposition, qinfo, cutpoints); } /** * entry point and pre functions */ public void write(JobProcessing job_processing, byte[] pes_packet, int pes_offset, int pes_packetlength, StreamDemultiplexer streamdemultiplexer, long cutposition, boolean qinfo, List cutpoints) throws IOException { /** * cut-off determination */ if (CutMode == CommonParsing.CUTMODE_BYTE && !qinfo && !CommonParsing.makecut(job_processing, cutposition + 5, cutpoints) ) { BrokenLinkFlag = false; return; } /** * 1:1 copy filter */ if (Action == CommonParsing.ACTION_FILTER) { writePacket(job_processing, pes_packet, pes_offset, pes_packetlength); return; } /** * repack mpg1 pes source to mpg2 */ repackMpg1(pes_packet, pes_offset, streamdemultiplexer); if (streamdemultiplexer.getType() == CommonParsing.MPEG_VIDEO && !BrokenLinkFlag) setBrokenLink(pes_packet, pes_offset); if (Buffer.size() != 0) Buffer.reset(); switch(Action) { case CommonParsing.ACTION_TO_VDR: packetizeToVDR(job_processing, pes_packet, pes_offset, streamdemultiplexer); return; case CommonParsing.ACTION_TO_M2P: packetizeToM2P(job_processing, pes_packet, pes_offset, streamdemultiplexer); return; case CommonParsing.ACTION_TO_PVA: packetizeToPVA(job_processing, pes_packet, pes_offset, streamdemultiplexer); return; case CommonParsing.ACTION_TO_TS: packetizeToTS(job_processing, pes_packet, pes_offset, streamdemultiplexer, qinfo); return; } } /** * simply write the packet */ public void writePacket(JobProcessing job_processing, byte[] packet) throws IOException { writePacket(job_processing, packet, 0, packet.length); } /** * simply write the packet */ public void writePacket(JobProcessing job_processing, byte[] packet, int offset, int length) throws IOException { if (offset < 0 || offset >= packet.length) { Common.setMessage("!> packet writing: index out of bounds, ignore it.. (" + Packet + ")"); return; } if (offset + length > packet.length) { Common.setMessage("!> packet writing: length index out of bounds, shortened.. (" + Packet + ")"); length = packet.length - offset; } OutputStream.write(packet, offset, length); job_processing.countMediaFilesExportLength(length); job_processing.countAllMediaFilesExportLength(length); } /** * export VDR */ private void packetizeToVDR(JobProcessing job_processing, byte[] pes_packet, int pes_offset, StreamDemultiplexer streamdemultiplexer) { try { int es_streamtype = streamdemultiplexer.getType(); int pes_streamtype = streamdemultiplexer.getStreamType(); int newID = streamdemultiplexer.getnewID(); if (CommonParsing.validateStartcode(pes_packet, pes_offset) < 0) { Common.setMessage("!> invalid startcode " + Packet + " (" + Integer.toHexString(newID) + "/" + es_streamtype + ")"); return; } int pes_payloadlength = CommonParsing.getPES_LengthField(pes_packet, pes_offset); int pes_headerlength = 9; int pes_packetlength = pes_headerlength - 3 + pes_payloadlength; int offset = 0; if (pes_packetlength + pes_offset > pes_packet.length) return; int pes_extensionlength = CommonParsing.getPES_ExtensionLengthField(pes_packet, pes_offset); CommonParsing.clearBit33ofPTS(pes_packet, pes_offset); CommonParsing.clearBit33ofDTS(pes_packet, pes_offset); switch (es_streamtype) { case CommonParsing.AC3_AUDIO: case CommonParsing.DTS_AUDIO: if (!ExportNonVideo || (0xFF & newID) != 0x80) return; // not more than one stream if (pes_streamtype == CommonParsing.MPEG2PS_TYPE) { // skip substream-header pes_payloadlength -= 4; CommonParsing.setPES_LengthField(pes_packet, pes_offset, pes_payloadlength); offset = pes_headerlength + pes_extensionlength; writePacket(job_processing, pes_packet, pes_offset, offset); // write leading hader offset += 4; } break; case CommonParsing.MPEG_AUDIO: if (!ExportNonVideo) return; CommonParsing.setPES_IdField(pes_packet, pes_offset, newID); break; case CommonParsing.TELETEXT: if (!ExportNonVideo || (0x7F & newID) > 0x1F) return; // not more than 16 streams CommonParsing.setPES_SubIdField(pes_packet, pes_offset, pes_headerlength, pes_extensionlength, newID - 0x80); break; case CommonParsing.MPEG_VIDEO: if (!ExportVideo) return; CommonParsing.setPES_IdField(pes_packet, pes_offset, newID); break; case CommonParsing.LPCM_AUDIO: case CommonParsing.SUBPICTURE: default: return; } writePacket(job_processing, pes_packet, offset + pes_offset, pes_packetlength - offset); } catch (IOException e) { Common.setExceptionMessage(e); } } /** * write MPG */ private void packetizeToM2P(JobProcessing job_processing, byte[] pes_packet, int pes_offset, StreamDemultiplexer streamdemultiplexer) { try { int es_streamtype = streamdemultiplexer.getType(); int pes_streamtype = streamdemultiplexer.getStreamType(); int newID = streamdemultiplexer.getnewID(); if (CommonParsing.validateStartcode(pes_packet, pes_offset) < 0) { Common.setMessage("!> invalid startcode " + Packet + " (" + Integer.toHexString(newID) + "/" + es_streamtype + ")"); return; } int pes_payloadlength = CommonParsing.getPES_LengthField(pes_packet, pes_offset); int pes_headerlength = 9; int pes_packetlength = pes_headerlength - 3 + pes_payloadlength; int offset = 0; if (pes_packetlength + pes_offset > pes_packet.length) return; int pes_extensionlength = CommonParsing.getPES_ExtensionLengthField(pes_packet, pes_offset); boolean newSCR = false; boolean containsPTS; containsPTS = CommonParsing.clearBit33ofPTS(pes_packet, pes_offset); CommonParsing.clearBit33ofDTS(pes_packet, pes_offset); switch (es_streamtype) { case CommonParsing.AC3_AUDIO: case CommonParsing.DTS_AUDIO: if (!ExportNonVideo) return; break; case CommonParsing.MPEG_AUDIO: if (!ExportNonVideo) return; CommonParsing.setPES_IdField(pes_packet, pes_offset, newID); break; case CommonParsing.MPEG_VIDEO: if (!ExportVideo || (0xFF & newID) != 0xE0) // not more than one stream return; CommonParsing.setPES_IdField(pes_packet, pes_offset, newID); break; case CommonParsing.LPCM_AUDIO: case CommonParsing.SUBPICTURE: case CommonParsing.TELETEXT: default: return; } /** * return, newID is not set, for mpg (curr. 0x20..,0xA0..) */ if (newID == 0) return; // indexof, int a = 0; /** * new ID arrived, align data */ for ( ; a < IDs.size(); a++) { if (newID == (0xFF & Integer.parseInt(IDs.get(a).toString()))) break; } if (a == IDs.size()) { if (es_streamtype != CommonParsing.MPEG_VIDEO && !ContainsVideo && MustStartWithVideo) return; if (!CommonParsing.alignSyncword(pes_packet, pes_offset, es_streamtype)) return; pes_payloadlength = CommonParsing.getPES_LengthField(pes_packet, pes_offset); pes_packetlength = pes_headerlength - 3 + pes_payloadlength; IDs.add(String.valueOf((newID > 0xDF) ? newID : (0x100 + newID))); } // if (FirstPacket) { writePacket(job_processing, PackHeader); writePacket(job_processing, new byte[SystemHeaderLength - 8]); // placeholder for systemheader FirstPacket = false; } if (es_streamtype == CommonParsing.AC3_AUDIO || es_streamtype == CommonParsing.DTS_AUDIO) { if (pes_streamtype == CommonParsing.MPEG2PS_TYPE) { CommonParsing.setPES_SubIdField(pes_packet, pes_offset, pes_headerlength, pes_extensionlength, newID); updateSCR(pes_packetlength); setSCRField(PackHeader); writePacket(job_processing, PackHeader); writePacket(job_processing, pes_packet, pes_offset, pes_packetlength); return; } else { pes_payloadlength += 4; pes_packetlength += 4; offset = pes_headerlength + pes_extensionlength; CommonParsing.setPES_LengthField(pes_packet, pes_offset, pes_payloadlength); CommonParsing.setValue(subID, pes_offset, 1, !CommonParsing.BYTEREORDERING, newID); updateSCR(pes_packetlength); setSCRField(PackHeader); writePacket(job_processing, PackHeader); writePacket(job_processing, pes_packet, pes_offset, offset); writePacket(job_processing, subID, pes_offset, subID.length); // write 4 byte of substreamheader writePacket(job_processing, pes_packet, offset + pes_offset, pes_packetlength - offset - subID.length); return; } } if (!ContainsVideo) { if (es_streamtype == CommonParsing.MPEG_VIDEO) ContainsVideo = true; else PaddingStreamPositions.add(String.valueOf(job_processing.getAllMediaFilesExportLength() + 17)); } if (es_streamtype == CommonParsing.MPEG_VIDEO && containsPTS && AddPcrToStream) { for (int i = pes_headerlength + pes_extensionlength + pes_offset, picture_type, returncode; i < pes_packetlength - 6 + pes_offset; i++) { /** * search picture header */ if ((returncode = CommonParsing.validateStartcode(pes_packet, i)) < 0 || CommonParsing.getPES_IdField(pes_packet, i) != CommonParsing.PICTURE_START_CODE) { i += (returncode < 0 ? -returncode : 4) - 1; continue; } picture_type = 7 & pes_packet[i + 5]>>>3; /** * is I or P-Frame */ // if (picture_type == CommonParsing.FRAME_I_TYPE || picture_type == CommonParsing.FRAME_P_TYPE) if (picture_type == CommonParsing.FRAME_I_TYPE) { SCR_Value = CommonParsing.getPTSfromBytes(pes_packet, pes_headerlength + pes_offset); updateSCR(-PCR_Delta); setSCRField(PackHeader); if (LeadingPackHeader[2] == 0) System.arraycopy(PackHeader, 0, LeadingPackHeader, 0, PackHeader.length); writePacket(job_processing, PackHeader); newSCR = true; } break; } } if (!newSCR) { updateSCR(pes_packetlength); setSCRField(PackHeader); writePacket(job_processing, PackHeader); } writePacket(job_processing, pes_packet, pes_offset, pes_packetlength); } catch (IOException e) { Common.setExceptionMessage(e); } } /** * write pva */ private void packetizeToPVA(JobProcessing job_processing, byte[] pes_packet, int pes_offset, StreamDemultiplexer streamdemultiplexer) { try { long pts; int es_streamtype = streamdemultiplexer.getType(); int pes_streamtype = streamdemultiplexer.getStreamType(); int newID = streamdemultiplexer.getnewID(); // read new mapped ID if (CommonParsing.validateStartcode(pes_packet, pes_offset) < 0) { Common.setMessage("!> invalid startcode " + Packet + " (" + Integer.toHexString(newID) + "/" + es_streamtype + ")"); return; } int pes_payloadlength = CommonParsing.getPES_LengthField(pes_packet, pes_offset); int pes_headerlength = 9; int pes_packetlength = pes_headerlength - 3 + pes_payloadlength; int offset = 0; int countID = 3; if (pes_packetlength + pes_offset > pes_packet.length) return; int pes_extensionlength = CommonParsing.getPES_ExtensionLengthField(pes_packet, pes_offset); boolean containsPTS; containsPTS = CommonParsing.clearBit33ofPTS(pes_packet, pes_offset); CommonParsing.clearBit33ofDTS(pes_packet, pes_offset); switch (es_streamtype) { case CommonParsing.AC3_AUDIO: case CommonParsing.DTS_AUDIO: case CommonParsing.TELETEXT: if (!ExportNonVideo) return; break; case CommonParsing.MPEG_AUDIO: if (!ExportNonVideo) return; CommonParsing.setPES_IdField(pes_packet, pes_offset, newID); break; case CommonParsing.MPEG_VIDEO: if (!ExportVideo || (0xFF & newID) != 0xE0) // not more than one video return; /** * looking for sequence_start_code */ for (int i = pes_headerlength + pes_extensionlength + pes_offset; !ContainsVideo && i < pes_packetlength - 4 + pes_offset; i++) { if (pes_packet[i] != 0 || pes_packet[1 + i] != 0 || pes_packet[2 + i] != 1 || pes_packet[3 + i] != (byte)CommonParsing.SEQUENCE_HEADER_CODE) continue; ContainsVideo = true; } if (MustStartWithVideo && !ContainsVideo) return; offset = pes_headerlength; CommonParsing.setPES_IdField(pes_packet, pes_offset, newID); if (containsPTS) { pts = CommonParsing.getPTSfromBytes(pes_packet, offset + pes_offset); offset += pes_extensionlength; pes_payloadlength = pes_packetlength - offset; CommonParsing.setValue(PvaPacketHeaderAndPTS, 2, 1, !CommonParsing.BYTEREORDERING, PVA_MAINVIDEO); CommonParsing.setValue(PvaPacketHeaderAndPTS, 3, 1, !CommonParsing.BYTEREORDERING, 0xFF & PacketCounter[PVA_MAINVIDEO]); CommonParsing.setValue(PvaPacketHeaderAndPTS, 6, 2, !CommonParsing.BYTEREORDERING, pes_payloadlength + 4); CommonParsing.setValue(PvaPacketHeaderAndPTS, 8, 4, !CommonParsing.BYTEREORDERING, pts); writePacket(job_processing, PvaPacketHeaderAndPTS); } else { offset += pes_extensionlength; pes_payloadlength = pes_packetlength - offset; CommonParsing.setValue(PvaPacketHeader, 2, 1, !CommonParsing.BYTEREORDERING, PVA_MAINVIDEO); CommonParsing.setValue(PvaPacketHeader, 3, 1, !CommonParsing.BYTEREORDERING, 0xFF & PacketCounter[PVA_MAINVIDEO]); CommonParsing.setValue(PvaPacketHeader, 5, 1, !CommonParsing.BYTEREORDERING, 0); CommonParsing.setValue(PvaPacketHeader, 6, 2, !CommonParsing.BYTEREORDERING, pes_payloadlength); writePacket(job_processing, PvaPacketHeader); } writePacket(job_processing, pes_packet, offset + pes_offset, pes_payloadlength); PacketCounter[PVA_MAINVIDEO]++; return; case CommonParsing.LPCM_AUDIO: case CommonParsing.SUBPICTURE: default: return; } if (MustStartWithVideo && !ContainsVideo) return; switch (newID) { case 0xC0: //ndern CommonParsing.setValue(PvaPacketHeader, 2, 1, !CommonParsing.BYTEREORDERING, PVA_MAINAUDIO); CommonParsing.setValue(PvaPacketHeader, 3, 1, !CommonParsing.BYTEREORDERING, 0xFF & PacketCounter[PVA_MAINAUDIO]); CommonParsing.setValue(PvaPacketHeader, 5, 1, !CommonParsing.BYTEREORDERING, 0x10); CommonParsing.setValue(PvaPacketHeader, 6, 2, !CommonParsing.BYTEREORDERING, pes_packetlength); PacketCounter[PVA_MAINAUDIO]++; writePacket(job_processing, PvaPacketHeader); writePacket(job_processing, pes_packet, pes_offset, pes_packetlength); return; default: //ndern switch (0xF0 & newID) { case 0x90: //ttx ndern countID = newID - 0x8C; break; case 0x80: countID = newID - 0x6C; break; case 0xC0: case 0xD0: countID = newID - 0x9C; } CommonParsing.setValue(PvaPacketHeader, 2, 1, !CommonParsing.BYTEREORDERING, newID); CommonParsing.setValue(PvaPacketHeader, 3, 1, !CommonParsing.BYTEREORDERING, 0xFF & PacketCounter[countID]); CommonParsing.setValue(PvaPacketHeader, 5, 1, !CommonParsing.BYTEREORDERING, 0x10); PacketCounter[countID]++; if (es_streamtype == CommonParsing.AC3_AUDIO || es_streamtype == CommonParsing.DTS_AUDIO) { if (pes_streamtype == CommonParsing.MPEG2PS_TYPE) { // skip substream-header pes_payloadlength -= 4; CommonParsing.setPES_LengthField(pes_packet, pes_offset, pes_payloadlength); CommonParsing.setValue(PvaPacketHeader, 6, 2, !CommonParsing.BYTEREORDERING, pes_packetlength - 4); offset = pes_headerlength + pes_extensionlength; writePacket(job_processing, PvaPacketHeader); writePacket(job_processing, pes_packet, pes_offset, offset); offset += 4; writePacket(job_processing, pes_packet, offset + pes_offset, pes_packetlength - offset); return; } } CommonParsing.setValue(PvaPacketHeader, 6, 2, !CommonParsing.BYTEREORDERING, pes_packetlength); writePacket(job_processing, PvaPacketHeader); writePacket(job_processing, pes_packet, pes_offset, pes_packetlength); } } catch (IOException e) { Common.setExceptionMessage(e); } } /** * mpeg-ts */ private void packetizeToTS(JobProcessing job_processing, byte[] pes_packet, int pes_offset, StreamDemultiplexer streamdemultiplexer, boolean qinfo) { try { boolean pcr = false; long pcrbase = 0; long pts = 0; int es_streamtype = streamdemultiplexer.getType(); int pes_streamtype = streamdemultiplexer.getStreamType(); int newID = streamdemultiplexer.getnewID(); if (CommonParsing.validateStartcode(pes_packet, pes_offset) < 0) { Common.setMessage("!> invalid startcode " + Packet + " (" + Integer.toHexString(newID) + "/" + es_streamtype + ")"); return; } int pes_payloadlength = CommonParsing.getPES_LengthField(pes_packet, pes_offset); int pes_headerlength = 9; int pes_packetlength = pes_headerlength - 3 + pes_payloadlength; int offset = 0; int countID = 3; if (pes_packetlength + pes_offset > pes_packet.length) return; int pes_extensionlength = CommonParsing.getPES_ExtensionLengthField(pes_packet, pes_offset); boolean containsPTS; containsPTS = CommonParsing.clearBit33ofPTS(pes_packet, pes_offset); CommonParsing.clearBit33ofDTS(pes_packet, pes_offset); switch (es_streamtype) { case CommonParsing.AC3_AUDIO: case CommonParsing.DTS_AUDIO: if (!ExportNonVideo) return; break; case CommonParsing.MPEG_AUDIO: if (!ExportNonVideo) return; break; case CommonParsing.TELETEXT: if (!ExportNonVideo) return; break; case CommonParsing.MPEG_VIDEO: if (!ExportVideo || (0xFF & newID) != 0xE0) // not more than one stream return; break; case CommonParsing.LPCM_AUDIO: case CommonParsing.SUBPICTURE: default: return; } if (!qinfo) if (es_streamtype != CommonParsing.MPEG_VIDEO && !ContainsVideo && MustStartWithVideo) return; // must start with video if (es_streamtype == CommonParsing.AC3_AUDIO || es_streamtype == CommonParsing.DTS_AUDIO) { if (pes_streamtype == CommonParsing.MPEG2PS_TYPE) { // skip substream-header offset = pes_headerlength + pes_extensionlength + 4; // System.arraycopy(pes_packet, pes_headerlength + pes_extensionlength + pes_offset, pes_packet, offset + pes_offset, pes_packetlength - offset); System.arraycopy(pes_packet, offset + pes_offset, pes_packet, pes_headerlength + pes_extensionlength + pes_offset, pes_packetlength - offset); pes_payloadlength -= 4; pes_packetlength -= 4; CommonParsing.setPES_LengthField(pes_packet, pes_offset, pes_payloadlength); } } // int a = 0; /** * new ID arrived, save for PMT */ for (; a < IDs.size(); a++) { if (newID == (0xFF & Integer.parseInt(IDs.get(a).toString()))) break; } if (a == IDs.size()) //make adaptions of 1st paket { int newID2 = newID; //sort the id's for PMT table, MPV has highest prior. if (newID2 < 0x90) //AC3 DTS SUP newID2 |= 0x200; if (newID2 < 0xC0) //TTX PCM newID2 |= 0x300; if (newID2 < 0xE0) //MPA newID2 |= 0x100; if (!qinfo) { if (es_streamtype != CommonParsing.TELETEXT) { if (!CommonParsing.alignSyncword(pes_packet, pes_offset, es_streamtype)) return; } pes_payloadlength = CommonParsing.getPES_LengthField(pes_packet, pes_offset); pes_packetlength = pes_headerlength - 3 + pes_payloadlength; } IDs.add(String.valueOf(newID2)); } // CommonParsing.setValue(TsStartPacketHeader, 2, 1, !CommonParsing.BYTEREORDERING, newID); CommonParsing.setValue(TsSubPacketHeader, 2, 1, !CommonParsing.BYTEREORDERING, newID); if (es_streamtype == CommonParsing.MPEG_VIDEO) CommonParsing.setPES_LengthField(pes_packet, pes_offset, 0); /** * add TS header */ if (FirstPacket) { Buffer.write(TS.init( FileName, SetMainAudioAc3, GenerateTTX, TsHeaderMode)); FirstPacket = false; } if (containsPTS && TS.getfirstID() == (0xFF & newID)) { pts = CommonParsing.getPTSfromBytes(pes_packet, pes_headerlength + pes_offset); pcrbase = pts - PCR_Delta; if ( (pts & 0xFF000000L) == 0xFF000000L ) ptsover = true; if (ptsover && pts < 0xF0000000L) pts |= 0x100000000L; time[1] = pts; pcr = true; if (time[0] == -1) time[0] = time[1]; } switch (0xF0 & newID) //ndern { case 0x80: countID = newID - 0x6C; break; case 0x90: countID = newID - 0x8C; break; case 0xC0: case 0xD0: countID = newID - 0x9C; break; case 0xE0: countID = 1; if (containsPTS) { pcr = false; for (int i = pes_headerlength + pes_extensionlength + pes_offset, picture_type, returncode; i < pes_packetlength - 6 + pes_offset; i++) { /** * search picture header */ if ((returncode = CommonParsing.validateStartcode(pes_packet, i)) < 0 || CommonParsing.getPES_IdField(pes_packet, i) != CommonParsing.PICTURE_START_CODE) { i += (returncode < 0 ? -returncode : 4) - 1; continue; } picture_type = 7 & pes_packet[i + 5]>>>3 ; /** * is I or P-Frame */ //if (picture_type == CommonParsing.FRAME_I_TYPE || picture_type == CommonParsing.FRAME_P_TYPE) if (picture_type == CommonParsing.FRAME_I_TYPE) { pcr = true; ContainsVideo = true; } break; } } break; } if (es_streamtype == CommonParsing.MPEG_VIDEO && !ContainsVideo && MustStartWithVideo) return; // must start with video, reached on qinfo if (30000L * PmtCounter <= job_processing.getAllMediaFilesExportLength()) { Buffer.write(TS.getPAT()); if (GeneratePMT) Buffer.write(TS.getAutoPMT()); else Buffer.write(TS.getPMT()); PmtCounter++; } /** * add own TTX */ if (pcr && GeneratePMT && GenerateTTX) Buffer.write( TS.getTTX(pes_packet, pes_offset, Common.formatTime_1((pcrbase + PCR_Delta) / 90)) ); /** * add Pcr */ if (pcr && AddPcrToStream) { if (!PcrCounter) Buffer.write(TS.getPCR(pcrbase, PacketCounter[countID], (0xFF & newID))); // no payload==no counter++ else Buffer.write(TS.getPCR(pcrbase, ++PacketCounter[countID], (0xFF & newID))); } int i = 0; int stuffinglength; while (i < pes_packetlength) { if (i == 0) { if (pes_packetlength - i < 183) { TsStartPacketHeader[3] = (byte)(0x30 | (0xF & ++PacketCounter[countID])); stuffinglength = 182 - (pes_packetlength - i); adapt[0] = (byte)(stuffinglength + 1); Buffer.write(TsStartPacketHeader); Buffer.write(adapt); Buffer.write(StuffingData, 6, stuffinglength); Buffer.write(pes_packet, i + pes_offset, pes_packetlength - i); i += (pes_packetlength - i); } else if (pes_packetlength - i == 184) { TsStartPacketHeader[3] = (byte)(0x10 | (0xF & ++PacketCounter[countID])); Buffer.write(TsStartPacketHeader); Buffer.write(pes_packet, i + pes_offset, 184); i += 184; } else if (pes_packetlength - i < 185) { TsStartPacketHeader[3] = (byte)(0x30 | (0xF & ++PacketCounter[countID])); adapt[0] = 1; Buffer.write(TsStartPacketHeader); Buffer.write(adapt); Buffer.write(pes_packet, i + pes_offset, 182); i += 182; } else { TsStartPacketHeader[3] = (byte)(0x10 | (0xF & ++PacketCounter[countID])); Buffer.write(TsStartPacketHeader); Buffer.write(pes_packet, i + pes_offset, 184); i += 184; } } else if (pes_packetlength - i < 183) { TsSubPacketHeader[3] = (byte)(0x30 | (0xF & ++PacketCounter[countID])); stuffinglength = 182 - (pes_packetlength - i); adapt[0] = (byte)(stuffinglength + 1); Buffer.write(TsSubPacketHeader); Buffer.write(adapt); Buffer.write(StuffingData, 6, stuffinglength); Buffer.write(pes_packet, i + pes_offset, pes_packetlength - i); i += (pes_packetlength - i); } else if (pes_packetlength - i == 184) { TsSubPacketHeader[3] = (byte)(0x10 | (0xF & ++PacketCounter[countID])); Buffer.write(TsSubPacketHeader); Buffer.write(pes_packet, i + pes_offset, 184); i += 184; } else if (pes_packetlength - i < 185) { TsSubPacketHeader[3] = (byte)(0x30 | (0xF & ++PacketCounter[countID])); adapt[0] = 1; Buffer.write(TsSubPacketHeader); Buffer.write(adapt); Buffer.write(pes_packet, i + pes_offset, 182); i += 182; } else { TsSubPacketHeader[3] = (byte)(0x10 | (0xF & ++PacketCounter[countID])); Buffer.write(TsSubPacketHeader); Buffer.write(pes_packet, i + pes_offset, 184); i += 184; } job_processing.countMediaFilesExportLength(+188); job_processing.countAllMediaFilesExportLength(+188); } Buffer.writeTo(OutputStream); Buffer.reset(); } catch (IOException e) { Common.setExceptionMessage(e); } } public void close(JobProcessing job_processing, boolean qinfo) { try { if (Action == CommonParsing.ACTION_TO_M2P) writePacket(job_processing, SequenceEndCode); OutputStream.flush(); OutputStream.close(); switch (Action) { case CommonParsing.ACTION_TO_M2P: RandomAccessFile mpg = new RandomAccessFile(FileName, "rw"); if (LeadingPackHeader[2] == 1) { mpg.seek(0); mpg.write(LeadingPackHeader); } mpg.seek(SystemHeaderInsertPoint); Object[] ID = IDs.toArray(); Arrays.sort(ID); // write systemheader pointer stuff for (int i = 0; i < ID.length; i++) { int IDt = (0xFF & Integer.parseInt(ID[i].toString())); if ((0xF0 & IDt) == 0xE0) { sys[0][0] = (byte)(sysID[0]++); mpg.write(sys[0]); SystemHeaderInsertPoint += 3; SystemHeaderStreams[1]++; } else if ((0xF0 & IDt) == 0x80) { mpg.write(sys[1]); SystemHeaderInsertPoint += 3; SystemHeaderStreams[0]++; } else if ((0xE0 & IDt) == 0xC0) { sys[2][0] = (byte)(sysID[1]++); mpg.write(sys[2]); SystemHeaderInsertPoint += 3; SystemHeaderStreams[0]++; } } /**** add padding ***/ mpg.writeInt(0x100 | CommonParsing.PADDING_STREAM_CODE); mpg.writeShort((short)(0x8A - SystemHeaderInsertPoint)); mpg.write(StuffingData, 0, (0x8A - SystemHeaderInsertPoint)); int syslen = ((SystemHeaderStreams[0] + SystemHeaderStreams[1]) * 3) + 6; // IDs (3byte) + std CommonParsing.setPES_LengthField(SystemHeader, 0, syslen); SystemHeader[9] = (byte)(SystemHeaderStreams[0]<<2); // set number of audios SystemHeader[10] = (byte)(0x20 | (0x1F & SystemHeaderStreams[1])); // set number of videos mpg.seek(14); mpg.write(SystemHeader); // write system header for (int i = 0; ContainsVideo && MustStartWithVideo && i < PaddingStreamPositions.size(); i++) { mpg.seek(Long.parseLong(PaddingStreamPositions.get(i).toString())); mpg.write((byte)CommonParsing.PADDING_STREAM_CODE); } mpg.close(); break; case CommonParsing.ACTION_TO_TS: if (qinfo && GeneratePMT) TS.setPmtPids(IDs); FileName = TS.updateAdditionalHeader(FileName, time, TsHeaderMode); break; case CommonParsing.ACTION_TO_VDR: if (CreateVdrIndex) { if (new File(FileName).length() < 150) OutputStream.deleteIdd(); else FileName = OutputStream.renameVdrTo(new File(FileName).getParent() + System.getProperty("file.separator"), FileName); } } if (new File(FileName).length() < 150) new File(FileName).delete(); else { Common.setMessage(Resource.getString("msg.newfile") + " " + FileName); job_processing.addSummaryInfo(Resource.getString("StreamConverter.Summary") + "\t'" + FileName + "'"); } } catch (IOException e) { Common.setExceptionMessage(e); } } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamDemultiplexer.java0000600000175000017500000007753610411340762030606 0ustar supermariosupermario/* * @(#)StreamDemultiplexer * * Copyright (c) 2005-2006 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.util.ArrayList; import java.util.List; import java.io.File; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.BufferedWriter; import java.io.FileWriter; import net.sourceforge.dvb.projectx.io.IDDBufferedOutputStream; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.video.Video; /** * demuxes all packetized data */ public class StreamDemultiplexer extends Object { private boolean ptsover = false; private boolean misshead = false; private boolean first = true; private boolean overlap = false; private boolean seqhead = false; private boolean isPTSwritten = false; private boolean WriteNonVideo; private boolean WriteVideo; private boolean Debug; private boolean DecodeVBI; private boolean RebuildPTS; private boolean Streamtype_MpgVideo; private boolean Streamtype_MpgAudio; private boolean Streamtype_Ac3Audio; private boolean Streamtype_PcmAudio; private boolean Streamtype_Teletext; private boolean Streamtype_Subpicture; private boolean AddSequenceEndcode; private boolean RenameVideo; private boolean CreateD2vIndex; private boolean CreateM2sIndex; private boolean SplitProjectFile; private boolean CreateCellTimes; private boolean CreateInfoIndex; private long AddOffset = 0; private long target_position = 0; private long ptsoffset = 0; private long pts = -1; private long lastPTS = -1; private int pack = -1; private int pes_ID = 0; private int newID = 0; private int PID = 0; private int es_streamtype = 0; private int subid = 0x1FF; private int pes_streamtype = 0; private int lfn = -1; private int buffersize = 1024; private int sourcetype = 0; private int[] MPGVideotype = { 0 }; // 0 =m1v, 1 = m2v, changed at goptest private String FileName = ""; private String parentname = ""; private String[] type = { "ac", "tt", "mp", "mv", "pc", "sp", "vp" }; private String[] source = { ".$spes$", ".$ppes$", ".$ts$", ".$pva$" }; private String[] videoext = { ".mpv", ".mpv", ".m1v", ".m2v" }; private IDDBufferedOutputStream out; private DataOutputStream pts_log; private ByteArrayOutputStream vidbuf; private ByteArrayOutputStream vptsbytes; private ByteArrayOutputStream packet; private DataOutputStream vpts; private byte[] subpicture_header = { 0x53, 0x50, 0, 0, 0, 0, 0, 0, 0, 0 }; private byte[] lpcm_header = { 0x50, 0x43, 0x4D, 0, 0, 0, 0, 0, 0, 0 }; //'PCM'+5b(pts)+2b(size) public StreamDemultiplexer() { getSettings(); } public StreamDemultiplexer(long val) { getSettings(); ptsoffset = val; } /** * Object yet intialized */ public int getNum() { return lfn; } /** * get PID for later selection */ public int getPID() { return PID; } /** * returns PES pes_ID for later selection */ public int getID() { return pes_ID; } /** * set PID for later selection */ public void setPID(int val) { PID = val; } /** * set pes_ID for later selection */ public void setID(int val) { pes_ID = val; } /** * set newID for later selection /or subid */ public void setnewID(int val) { newID = val; } /** * returns newID for later selection /or subid */ public int getnewID() { return newID; } /** * returns packet counter */ public int getPackCount() { return pack; } /** * returns es_streamtype */ public int getType() { return es_streamtype; } /** * sets stream tpye, vdr/es/mpeg1/2... */ public void setStreamType(int val) { pes_streamtype = val; } /** * returns stream tpye, vdr/es/mpeg1/2... */ public int getStreamType() { return pes_streamtype; } /** * sets type */ public void setType(int val) { es_streamtype = val; } /** * sets subid */ public void setsubID(int val) { subid = val; } /** * returns subid */ public int subID() { return subid; } /** * is it TTX? */ public boolean isTTX() { return es_streamtype == CommonParsing.TELETEXT; } /** * set ttx */ public void setTTX(boolean b) { if (b) es_streamtype = CommonParsing.TELETEXT; } /** * last PTS */ public long getPTS() { return pts; } /** * PTS offset if needed */ public void PTSOffset(long val) { ptsoffset = val; } /** * stream type preselector */ public boolean StreamEnabled() { switch(newID>>>4) { case 0xE: //video return Streamtype_MpgVideo; case 0xC: //mpa case 0xD: return Streamtype_MpgAudio; case 0x8: //ac3,mpg return Streamtype_Ac3Audio; case 0xA: //lpcm,mpg return Streamtype_PcmAudio; case 0x9: //ttx return Streamtype_Teletext; case 0x2: //subpic case 0x3: return Streamtype_Subpicture; default: return true; } } /** * */ private void getSettings() { Streamtype_MpgVideo = Common.getSettings().getBooleanProperty(Keys.KEY_Streamtype_MpgVideo); Streamtype_MpgAudio = Common.getSettings().getBooleanProperty(Keys.KEY_Streamtype_MpgAudio); Streamtype_Ac3Audio = Common.getSettings().getBooleanProperty(Keys.KEY_Streamtype_Ac3Audio); Streamtype_PcmAudio = Common.getSettings().getBooleanProperty(Keys.KEY_Streamtype_PcmAudio); Streamtype_Teletext = Common.getSettings().getBooleanProperty(Keys.KEY_Streamtype_Teletext); Streamtype_Subpicture = Common.getSettings().getBooleanProperty(Keys.KEY_Streamtype_Subpicture); AddOffset = Common.getSettings().getBooleanProperty(Keys.KEY_additionalOffset) ? 90L * Common.getSettings().getIntProperty(Keys.KEY_ExportPanel_additionalOffset_Value) : 0; // time offset for data WriteNonVideo = Common.getSettings().getBooleanProperty(Keys.KEY_WriteOptions_writeAudio); WriteVideo = Common.getSettings().getBooleanProperty(Keys.KEY_WriteOptions_writeVideo); Debug = Common.getSettings().getBooleanProperty(Keys.KEY_DebugLog); DecodeVBI = Common.getSettings().getBooleanProperty(Keys.KEY_Streamtype_Vbi); RebuildPTS = Common.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_rebuildPTS); AddSequenceEndcode = Common.getSettings().getBooleanProperty(Keys.KEY_VideoPanel_addEndcode); RenameVideo = Common.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_renameVideo); CreateD2vIndex = Common.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createD2vIndex); CreateM2sIndex = Common.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createM2sIndex); SplitProjectFile = Common.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_splitProjectFile); CreateCellTimes = Common.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createCellTimes); CreateInfoIndex = Common.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createInfoIndex); } /** * init nonVideo streams */ private void initNonVideo(String _name) { parentname = _name; FileName = parentname + source[sourcetype] + lfn; target_position = 0; getSettings(); try { out = new IDDBufferedOutputStream(new FileOutputStream(FileName), buffersize); pts_log = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(FileName + ".pts"), 65535)); } catch (IOException e) { Common.setExceptionMessage(e); } } /** * main init nonVideo */ public void init(String _name, int _buffersize, int _lfn, int _parsertype) { lfn = _lfn; buffersize = _buffersize; sourcetype = _parsertype; initNonVideo(_name); } /** * re-init nonVideo */ public void init2(String _name) { initNonVideo(_name); } /** * process nonvideo data = 1 pespacket from demux */ public void write(JobProcessing job_processing, byte[] pes_packet, boolean pes_hasHeader) { write(job_processing, pes_packet, 0, pes_packet.length, pes_hasHeader); } /** * process nonvideo data = 1 pespacket from demux */ public void write(JobProcessing job_processing, byte[] pes_packet, int pes_packetoffset, int pes_payloadlength, boolean pes_hasHeader) { boolean pes_isAligned = false; int pes_extensionlength = 0; int offset = pes_packetoffset; int _es_streamtype = CommonParsing.AC3_AUDIO; pack++; if (pes_hasHeader) { if (CommonParsing.validateStartcode(pes_packet, offset) < 0) { Common.setMessage(Resource.getString("demux.error.audio.startcode") + " " + pack + " (" + Integer.toHexString(PID) + "/" + Integer.toHexString(pes_ID) + "/" + Integer.toHexString(newID) + "/" + es_streamtype + ")"); return; } pes_ID = CommonParsing.getPES_IdField(pes_packet, offset); pes_payloadlength = CommonParsing.getPES_LengthField(pes_packet, offset); pes_isAligned = (pes_streamtype == CommonParsing.PES_AV_TYPE || pes_streamtype == CommonParsing.MPEG2PS_TYPE) && (4 & pes_packet[6 + offset]) != 0; if (pes_ID == CommonParsing.PADDING_STREAM_CODE) return; if (pes_streamtype == CommonParsing.MPEG1PS_TYPE) { skiploop: while(true) { switch (0xC0 & pes_packet[6 + offset]) { case 0x40: offset += 2; continue skiploop; case 0x80: offset += 3; continue skiploop; case 0xC0: offset++; continue skiploop; case 0: break; } switch (0x30 & pes_packet[6 + offset]) { case 0x20: //PTS pes_extensionlength = 5; break skiploop; case 0x30: //PTS+DTS pes_extensionlength = 10; break skiploop; case 0x10: //DTS offset += 5; break skiploop; case 0: offset++; break skiploop; } } } else { pes_extensionlength = CommonParsing.getPES_ExtensionLengthField(pes_packet, offset); if (pes_ID == CommonParsing.PRIVATE_STREAM_1_CODE && pes_extensionlength == 0x24 && (0xFF & pes_packet[9 + pes_extensionlength + offset])>>>4 == 1) _es_streamtype = CommonParsing.TELETEXT; /** * no PTS in PES_extension */ if ((0x80 & pes_packet[7 + offset]) == 0) { offset += pes_extensionlength; pes_extensionlength = 0; } offset += 3; } es_streamtype = pes_ID == CommonParsing.PRIVATE_STREAM_1_CODE ? _es_streamtype : CommonParsing.MPEG_AUDIO; subid = ((es_streamtype == CommonParsing.AC3_AUDIO || es_streamtype == CommonParsing.DTS_AUDIO || es_streamtype == CommonParsing.TELETEXT) && ((pes_streamtype == CommonParsing.PES_AV_TYPE && (pes_isAligned || es_streamtype == CommonParsing.TELETEXT)) || pes_streamtype == CommonParsing.MPEG2PS_TYPE)) ? (0xFF & pes_packet[9 + (0xFF & pes_packet[8 + pes_packetoffset]) + pes_packetoffset]) : 0; switch (subid>>>4) { case 8: if (pes_streamtype == CommonParsing.PES_AV_TYPE || pes_streamtype == CommonParsing.MPEG1PS_TYPE) { subid = 0; break; } case 1: case 2: case 3: case 9: case 0xA: break; case 0: if (pes_isAligned && subid == 0x09) break; default: if (pes_streamtype != CommonParsing.MPEG2PS_TYPE) subid = 0; } switch (subid>>>4) { case 0xA: //LPCM from MPG-PS es_streamtype = CommonParsing.LPCM_AUDIO; break; case 2: //SubPic 0-31 from MPG-PS case 3: //SubPic 32-63 from MPG-PS es_streamtype = CommonParsing.SUBPICTURE; break; case 8: //AC3-DTS from MPG-PS case 1: //TTX case 0: //AC3-DTS from PES/VDR break; case 9: //VBI from TS,MPG2 if (pes_isAligned) { if (pes_streamtype == CommonParsing.MPEG1PS_TYPE || pes_streamtype == CommonParsing.PES_AV_TYPE) subid = 0; if (DecodeVBI) VBI.parsePES(pes_packet, pes_packetoffset); return; } break; default: return; } pes_payloadlength -= (offset - pes_packetoffset + pes_extensionlength); offset += 6; } if (!WriteNonVideo) return; if (out == null) return; try { /** * re-build PTS */ if (es_streamtype == CommonParsing.TELETEXT && RebuildPTS) { if (job_processing.getBorrowedPts() != lastPTS) { lastPTS = job_processing.getBorrowedPts(); pts_log.writeLong(lastPTS); pts_log.writeLong(target_position); if (Debug) System.out.println(" stolen ttx PTS: " + lastPTS + " /ao " + AddOffset + " /tp " + target_position); } } /** * read out source PTS */ else if (pes_extensionlength > 0 && pes_payloadlength >= 0) { pts = CommonParsing.getPTSfromBytes(pes_packet, offset); //returns 32bit pts -= job_processing.getNextFileStartPts(); pts &= 0xFFFFFFFFL; if ( (pts & 0xFF000000L) == 0xFF000000L ) ptsover = true; // bit 33 was set if (ptsover && pts < 0xF0000000L) pts |= 0x100000000L; pts += ptsoffset; pts += AddOffset; if (lastPTS != pts) { if ((es_streamtype == CommonParsing.MPEG_AUDIO || es_streamtype == CommonParsing.AC3_AUDIO || es_streamtype == CommonParsing.DTS_AUDIO || es_streamtype == CommonParsing.LPCM_AUDIO) && lastPTS != -1 && Math.abs(lastPTS - pts) > 100000) Common.setMessage("!> ID 0x" + Integer.toHexString(pes_ID).toUpperCase() + " (sub 0x" + Integer.toHexString(subid).toUpperCase() + ") packet# " + pack + ", big PTS difference: this " + pts + ", prev. " + lastPTS); pts_log.writeLong(pts); pts_log.writeLong(target_position); } if (Debug) System.out.println(" pda PTS: " + pts + "/ " + AddOffset + "/ " + target_position); lastPTS = pts; } /** * save re-build PTS, taken from 1st mpa */ if (newID == 0xC0 && job_processing.getBorrowedPts() != lastPTS) job_processing.setBorrowedPts(lastPTS); /** * skip subid and info fields */ switch(subid>>>4) { case 0xA: //LPCM, keep info fields 6 bytes offset += 1; //7 pes_payloadlength -= 1; //7 break; case 8: //AC3-DTS offset += 4; pes_payloadlength -= 4; break; case 1: //TTX case 2: //subpic 0.31 case 3: //subpic 32.63 offset += 1; pes_payloadlength -= 1; } if (subid == 0x09) { offset += 4; pes_payloadlength -= 4; } if (pes_payloadlength <= 0) return; if (pes_extensionlength > 0) { switch(es_streamtype) { case CommonParsing.SUBPICTURE: CommonParsing.setValue(subpicture_header, 2, 8, CommonParsing.BYTEREORDERING, pts); target_position += writePacket(subpicture_header); /** * DVB subs adaption */ if (CommonParsing.nextBits(pes_packet, (offset + pes_extensionlength) * 8, 16) == 0xF) { out.write(0xFF & (pes_payloadlength + 3)>>>8); out.write(0xFF & (pes_payloadlength + 3)); out.write(0); //padding target_position += 3; } break; case CommonParsing.LPCM_AUDIO: CommonParsing.setValue(lpcm_header, 3, 5, CommonParsing.BYTEREORDERING, pts); lpcm_header[8] = (byte)(0xFF & pes_payloadlength>>>8); lpcm_header[9] = (byte)(0xFF & pes_payloadlength); target_position += writePacket(lpcm_header); } } /** * DVB subs adaption, prevent lost packets */ else if (es_streamtype == CommonParsing.SUBPICTURE && pes_isAligned && CommonParsing.nextBits(pes_packet, (offset + pes_extensionlength) * 8, 16) == 0xF) // else if (es_streamtype == CommonParsing.SUBPICTURE && CommonParsing.nextBits(pes_packet, (offset + pes_extensionlength) * 8, 16) == 0xF) { CommonParsing.setValue(subpicture_header, 2, 8, CommonParsing.BYTEREORDERING, 0); target_position += writePacket(subpicture_header); out.write(0xFF & (pes_payloadlength + 3)>>>8); out.write(0xFF & (pes_payloadlength + 3)); out.write(0); //padding! target_position += 3; } if (subid == 0x09) for (int i = 0; i < pes_payloadlength; i += 3) target_position += writePacket(pes_packet, offset + pes_extensionlength + i, 2); else target_position += writePacket(pes_packet, offset + pes_extensionlength, pes_payloadlength); } catch (IOException e) { Common.setExceptionMessage(e); } } /** * */ public String[] close(JobProcessing job_processing, String _vptslog) { String pts_log_name = FileName + ".pts"; String parameters[] = { FileName, pts_log_name, type[es_streamtype], parentname }; try { if (out == null) { parameters[0] = ""; return parameters; } out.flush(); out.close(); pts_log.flush(); pts_log.close(); if (new File(pts_log_name).length() < 10) CommonParsing.logAlias(job_processing, _vptslog, pts_log_name); if (new File(FileName).length() < 10) { new File(FileName).delete(); new File(pts_log_name).delete(); parameters[0] = ""; } } catch (IOException e) { Common.setExceptionMessage(e); } return parameters; } /** * */ public void initVideo(String _name, int _buffersize, int _lfn, int _parsertype) { getSettings(); parentname = _name; lfn = _lfn; buffersize = _buffersize; sourcetype = _parsertype; FileName = parentname + source[sourcetype] + lfn; es_streamtype = CommonParsing.MPEG_VIDEO; MPGVideotype[0] = 0; try { out = new IDDBufferedOutputStream(new FileOutputStream(FileName), buffersize); if (CreateM2sIndex) out.InitIdd(FileName, 1); if (CreateInfoIndex) out.InitInfo(FileName); pts_log = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(FileName + ".pts"), 65535)); packet = new ByteArrayOutputStream(); vidbuf = new ByteArrayOutputStream(); vptsbytes = new ByteArrayOutputStream(); vpts = new DataOutputStream(vptsbytes); } catch (IOException e) { Common.setExceptionMessage(e); } } public void initVideo2(String _name) { getSettings(); parentname = _name; FileName = parentname + source[sourcetype] + lfn; first = true; MPGVideotype[0] = 0; try { out = new IDDBufferedOutputStream(new FileOutputStream(FileName), buffersize); if (CreateM2sIndex) out.InitIdd(FileName, 1); if (CreateInfoIndex) out.InitInfo(FileName); pts_log = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(FileName + ".pts"), 65535)); packet.reset(); vidbuf.reset(); vptsbytes.reset(); } catch (IOException e) { Common.setExceptionMessage(e); } } /** * clean Up for next foreign inputfile in case of multiple */ public void resetVideo() { if (vidbuf != null) vidbuf.reset(); if (packet != null) packet.reset(); if (vptsbytes != null) vptsbytes.reset(); first = true; } public String closeVideo(JobProcessing job_processing, String workouts) { String logfile = "-1"; List cell = job_processing.getCellTimes(); int[] clv = job_processing.getStatusVariables(); try { if (AddSequenceEndcode && job_processing.getExportedVideoFrameNumber() > 0) { out.write(Video.getSequenceEndCode()); job_processing.countMediaFilesExportLength(+4); job_processing.countAllMediaFilesExportLength(+4); } packet.close(); vidbuf.flush(); vidbuf.close(); out.flush(); out.close(); pts_log.flush(); pts_log.close(); vpts.flush(); vpts.close(); vptsbytes.flush(); vptsbytes.close(); String videofile = ""; if (new File(FileName).length() < 10) { new File(FileName).delete(); if (!WriteVideo && new File(FileName + ".pts").length() > 16) logfile = FileName + ".pts"; else new File(FileName + ".pts").delete(); } else { int ot = (RenameVideo || CreateD2vIndex || SplitProjectFile) ? 0 : 2; videofile = parentname + videoext[MPGVideotype[0] + ot]; File newfile = new File(videofile); if (newfile.exists()) newfile.delete(); Common.renameTo(new File(FileName), newfile); logfile = FileName + ".pts"; CommonParsing.setVideoHeader(job_processing, videofile, logfile, clv, MPGVideotype); /** * celltimes.txt */ if (CreateCellTimes && !cell.isEmpty()) { BufferedWriter cellout = new BufferedWriter(new FileWriter(workouts + "CellTimes.txt")); for (int i = 0; i < cell.size(); i++) { cellout.write(cell.get(i).toString()); cellout.newLine(); } cellout.close(); Common.setMessage(Resource.getString("demux.msg.celltimes", workouts)); long fl = new File(workouts + "CellTimes.txt").length(); job_processing.countMediaFilesExportLength(fl); job_processing.countAllMediaFilesExportLength(fl); } cell.clear(); } if (CreateM2sIndex) { if (new File(videofile).exists()) out.renameVideoIddTo(parentname); else out.deleteIdd(); } if (CreateInfoIndex) { if (new File(videofile).exists()) { String tmpFN = videofile.toString(); out.renameVideoInfoTo(tmpFN); } else out.deleteInfo(); } } catch (IOException e) { Common.setExceptionMessage(e); } return logfile; } /** * temporary redirected access to goptest from video-es */ public void writeVideoES(JobProcessing job_processing, IDDBufferedOutputStream _out, byte[] _vidbuf, byte[] _vptsbytes, DataOutputStream _pts_log, String _parentname, int[] _MPGVideotype, List _CutpointList, List _ChapterpointList, boolean _doWrite) { job_processing.getGop().goptest(job_processing, _out, _vidbuf, _vptsbytes, _pts_log, _parentname, _MPGVideotype, _CutpointList, _ChapterpointList, _doWrite); } /** * write video * data = 1 pespacket from demux */ public void writeVideo(JobProcessing job_processing, byte[] pes_packet, boolean pes_hasHeader, List CutpointList, List ChapterpointList) { writeVideo(job_processing, pes_packet, 0, pes_packet.length, pes_hasHeader, CutpointList, ChapterpointList); } /** * write video * data = 1 pespacket from demux */ public void writeVideo(JobProcessing job_processing, byte[] pes_packet, int pes_packetoffset, int pes_payloadlength, boolean pes_hasHeader, List CutpointList, List ChapterpointList) { int pes_extensionlength = 0; int offset = pes_packetoffset; byte[] data = null; int[] clv = job_processing.getStatusVariables(); pack++; if (!pes_hasHeader) { if (job_processing.getPvaVideoPts() != -1) { offset -= 4; pes_extensionlength += 4; } } else { if (CommonParsing.validateStartcode(pes_packet, offset) < 0) { Common.setMessage(Resource.getString("demux.error.video.startcode") + " " + pack + " (" + Integer.toHexString(PID) + "/" + Integer.toHexString(pes_ID) + "/" + Integer.toHexString(newID) + "/" + es_streamtype + ")"); return; } pes_ID = CommonParsing.getPES_IdField(pes_packet, offset); pes_payloadlength = CommonParsing.getPES_LengthField(pes_packet, offset); if (pes_streamtype == CommonParsing.MPEG1PS_TYPE) { skiploop: while(true) { switch (0xC0 & pes_packet[6 + offset]) { case 0x40: offset += 2; continue skiploop; case 0x80: offset += 3; continue skiploop; case 0xC0: offset++; continue skiploop; case 0: break; } switch (0x30 & pes_packet[6 + offset]) { case 0x20: //PTS pes_extensionlength = 5; break skiploop; case 0x30: //PTS + DTS pes_extensionlength = 10; break skiploop; case 0x10: //DTS offset += 5; break skiploop; case 0: offset++; break skiploop; } } } else { pes_extensionlength = CommonParsing.getPES_ExtensionLengthField(pes_packet, offset); if ((0x80 & pes_packet[7 + offset]) == 0) { offset += pes_extensionlength; pes_extensionlength = 0; } offset += 3; } pes_payloadlength -= (offset - pes_packetoffset + pes_extensionlength); offset += 6; } /** * read pts */ if (pes_extensionlength > 0 && pes_payloadlength >= 0) { pts = !pes_hasHeader ? job_processing.getPvaVideoPts() : CommonParsing.getPTSfromBytes(pes_packet, offset); //returns 32bit pts -= job_processing.getNextFileStartPts(); pts &= 0xFFFFFFFFL; if ( (pts & 0xFF000000L) == 0xFF000000L ) ptsover = true; // bit 33 was set if (ptsover && pts < 0xF0000000L) pts |= 0x100000000L; pts += ptsoffset; if (Debug) System.out.println(" pdv PTS: " + pts); isPTSwritten = false; } try { if (pes_payloadlength <= 0) Common.setMessage(Resource.getString("demux.error.video.payload") + " (" + pack + "/" + pes_packet.length + "/" + offset + "/" + pes_extensionlength + "/" + pes_payloadlength + ")"); else packet.write(pes_packet, offset + pes_extensionlength, pes_payloadlength); packet.flush(); data = packet.toByteArray(); packet.reset(); boolean gop = false; boolean packetfirstframe = true; packloop: for (int i = 0, j = 0, id, returncode; i < data.length - 3; i++) { if ((returncode = CommonParsing.validateStartcode(data, i)) < 0) { i += (-returncode) - 1; continue packloop; } id = CommonParsing.getPES_IdField(data, i); /** * new frame at first */ if (!isPTSwritten && packetfirstframe && id == CommonParsing.PICTURE_START_CODE) { if (misshead && i < 3) { misshead = false; continue packloop; } if (pts != -1) { vpts.writeLong(pts); vpts.writeLong((long)vidbuf.size()); vpts.flush(); } isPTSwritten = true; packetfirstframe = false; i += 8; } else if (id == CommonParsing.SEQUENCE_HEADER_CODE || id == CommonParsing.SEQUENCE_END_CODE || id == CommonParsing.GROUP_START_CODE) { if (id == CommonParsing.SEQUENCE_HEADER_CODE) seqhead = true; if (id == CommonParsing.GROUP_START_CODE && seqhead && vidbuf.size() < 400) { seqhead = false; continue packloop; } vidbuf.write(data, j, i); if (!first) job_processing.getGop().goptest(job_processing, out, vidbuf.toByteArray(), vptsbytes.toByteArray(), pts_log, parentname, MPGVideotype, CutpointList, ChapterpointList); vptsbytes.reset(); vidbuf.reset(); /** * split size reached */ if (job_processing.getSplitSize() > 0 && job_processing.getSplitSize() < job_processing.getAllMediaFilesExportLength()) return; /** * d2v split reached */ if (SplitProjectFile && job_processing.getProjectFileExportLength() > job_processing.getProjectFileSplitSize()) { int part = job_processing.getProjectFileD2V().getPart() + 1; String newpart = parentname + "[" + part + "].mpv"; /** * sequence end code */ if (WriteVideo && AddSequenceEndcode && job_processing.getExportedVideoFrameNumber() > 0 ) { out.write(Video.getSequenceEndCode()); job_processing.countMediaFilesExportLength(+4); job_processing.countAllMediaFilesExportLength(+4); } out.flush(); out.close(); //System.gc(); out = new IDDBufferedOutputStream( new FileOutputStream(newpart), buffersize); /** * M2S idd */ if (CreateM2sIndex) out.InitIdd(newpart, 1); if (CreateInfoIndex) out.InitInfo(newpart); job_processing.getProjectFileD2V().setFile(newpart); job_processing.setProjectFileExportLength(0); } if (!isPTSwritten && packetfirstframe) { if (pts != -1) { vpts.writeLong(pts); vpts.writeLong(vidbuf.size()); vpts.flush(); } isPTSwritten = true; } if (id == CommonParsing.SEQUENCE_END_CODE) { Common.setMessage(Resource.getString("demux.msg.skip.sec") + " " + clv[6]); first = true; job_processing.setSequenceHeader(false); i += 3; continue packloop; } else vidbuf.write(data, i, data.length - i); if (id == CommonParsing.GROUP_START_CODE) { job_processing.setSequenceHeader(false); if (job_processing.getSplitPart() > 0) first = false; } else if (id == CommonParsing.SEQUENCE_HEADER_CODE) { job_processing.setSequenceHeader(true); first = false; } gop = true; misshead = false; break packloop; } } // end packloop if (!gop) { if (data.length > 2) { vidbuf.write(data, 0, data.length - 3); packet.write(data, data.length - 3, 3); misshead = true; } else vidbuf.write(data); } } catch (IOException e) { Common.setExceptionMessage(e); } if (vidbuf.size() > 6144000) { vptsbytes.reset(); vidbuf.reset(); packet.reset(); Common.setMessage(Resource.getString("demux.error.gop.toobig")); misshead = false; first = true; } } /** * simply write the packet */ private int writePacket(byte[] packet) throws IOException { return writePacket(packet, 0, packet.length); } /** * simply write the packet */ private int writePacket(byte[] packet, int offset, int length) throws IOException { if (offset < 0 || offset >= packet.length) { Common.setMessage("!> packet writing: index out of bounds, ignore it.. (" + Integer.toHexString(getPID()) + " / " + Integer.toHexString(getID()) + " / " + Integer.toHexString(getnewID()) + " / " + getPackCount() + " -- " + packet.length + " / " + offset + " / " + length + ") @ PTS " + Common.formatTime_1(lastPTS / 90)); return 0; } if (offset + length > packet.length) { Common.setMessage("!> packet writing: length index out of bounds, shortened.. (" + Integer.toHexString(getPID()) + " / " + Integer.toHexString(getID()) + " / " + Integer.toHexString(getnewID()) + " / " + getPackCount() + " -- " + packet.length + " / " + offset + " / " + length + ") @ PTS " + Common.formatTime_1(lastPTS / 90)); length = packet.length - offset; } out.write(packet, offset, length); return length; } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamParser.java0000600000175000017500000000525110354375344027212 0ustar supermariosupermario/* * @(#)StreamParser * * Copyright (c) 2005 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.parser.StreamParserBase; import net.sourceforge.dvb.projectx.parser.StreamParserPVA; import net.sourceforge.dvb.projectx.parser.StreamParserTS; import net.sourceforge.dvb.projectx.parser.StreamParserPESPrimary; import net.sourceforge.dvb.projectx.parser.StreamParserPESSecondary; /** * main thread */ public class StreamParser extends Object { private StreamParserBase impl = null; /** * */ public StreamParser(int parser_type) { switch (parser_type) { case CommonParsing.SECONDARY_PES_PARSER: impl = new StreamParserPESSecondary(); break; case CommonParsing.PRIMARY_PES_PARSER: impl = new StreamParserPESPrimary(); break; case CommonParsing.TS_PARSER: impl = new StreamParserTS(); break; case CommonParsing.PVA_PARSER: impl = new StreamParserPVA(); break; case CommonParsing.ES_VIDEO_PARSER: impl = new StreamParserESVideo(); break; case CommonParsing.ES_AUDIO_PARSER: impl = new StreamParserESAudio(); break; case CommonParsing.ES_SUBPICTURE_PARSER: impl = new StreamParserESSubpicture(); break; default: impl = new StreamParserBase(); } } /** * */ public String parseStream(JobCollection collection, XInputFile aXInputFile, int pes_streamtype, int action, String vptslog) { return (impl != null ? impl.parseStream(collection, aXInputFile, pes_streamtype, action, vptslog) : null); } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamParserBase.java0000600000175000017500000002076410363525664030015 0ustar supermariosupermario/* * @(#)StreamParser * * Copyright (c) 2005 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.File; import java.io.InputStream; import java.io.IOException; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.parser.CommonParsing; /** * main thread */ public class StreamParserBase extends Object { public int ERRORCODE = 0; public int MainBufferSize = 8192000; /** * */ public StreamParserBase() { init(); } /** * */ public void init() { MainBufferSize = Integer.parseInt(Common.getSettings().getProperty(Keys.KEY_MainBuffer)); if (MainBufferSize <= 0) MainBufferSize = 4096000; } /** * */ public String parseStream(JobCollection collection, XInputFile aXInputFile, int pes_streamtype, int action, String vptslog) { return null; } /** * */ public boolean pause() { return Common.waitingMainProcess(); } /** * nextfile PTS check * * returns new pts offset to append */ public long nextFilePTS(JobCollection collection, int parser_type, int pes_streamtype, long lastpts, int file_number) { return nextFilePTS(collection, parser_type, pes_streamtype, lastpts, file_number, 0L); } /** * nextfile PTS check * * returns new pts offset to append */ public long nextFilePTS(JobCollection collection, int parser_type, int pes_streamtype, long lastpts, int file_number, long startPoint) { JobProcessing job_processing = collection.getJobProcessing(); byte[] data; long pts = 0; int position = 0; int buffersize = Integer.parseInt(collection.getSettings().getProperty(Keys.KEY_ScanBuffer)); int pes_ID; boolean PVA_Audio = collection.getSettings().getBooleanProperty(Keys.KEY_PVA_Audio); boolean containsPts; lastpts &= 0xFFFFFFFFL; //ignore bit33 of lastpts if (collection.getPrimaryInputFileSegments() > file_number) { try { XInputFile aXinputFile = ((XInputFile) collection.getInputFile(file_number)).getNewInstance(); if (aXinputFile == null) return -1L; data = new byte[buffersize]; aXinputFile.randomAccessSingleRead(data, startPoint); switch (parser_type) { case CommonParsing.PVA_PARSER: // pva int pva_pid; int ptsflag; int pva_payloadlength; loop: while (position < buffersize - 20) { if (data[position] != 0x41 || data[position + 1] != 0x56 || data[position + 4] != 0x55) { position++; continue loop; } pva_pid = 0xFF & data[position + 2]; ptsflag = 0xFF & data[position + 5]; pva_payloadlength = (0xFF & data[position + 6])<<8 | (0xFF & data[position + 7]); containsPts = (0x10 & ptsflag) != 0; if (pva_pid == 1) //video { if (containsPts) { pts = CommonParsing.readPTS(data, position + 8, 4, !CommonParsing.BYTEREORDERING, true); break loop; } } else if (pva_pid != 0) //mainaudio mpa and other pids { ptsloop: for (int i = position + 8, j = (PVA_Audio && !containsPts) ? position + 8: position + 11; i < j; i++) { if (CommonParsing.validateStartcode(data, i) < 0) continue ptsloop; pes_ID = CommonParsing.getPES_IdField(data, i); if (pes_ID != 0xBD && (0xF0 & pes_ID) != 0xC0) continue ptsloop; if ((0x80 & data[i + 7]) == 0) break ptsloop; pts = CommonParsing.getPTSfromBytes(data, i + 9); //returns 32bit break loop; } } position += 8 + pva_payloadlength; } break; case CommonParsing.PRIMARY_PES_PARSER: // mpg int pes_payloadlength = 0; int ptslength = 0; int returncode; int pes_offset = 0; boolean nullpacket = false; loop: while (position < buffersize - 20) { if ((returncode = CommonParsing.validateStartcode(data, position)) < 0) { position += -returncode; continue loop; } pes_ID = CommonParsing.getPES_IdField(data, position); if (pes_ID < 0xBA) { position += 3; continue loop; } if (pes_ID == 0xBA) { position += 12; continue loop; } pes_payloadlength = CommonParsing.getPES_LengthField(data, position); if (pes_payloadlength == 0) nullpacket = true; if ((0xF0 & pes_ID) != 0xE0 && (0xF0 & pes_ID) != 0xC0 && pes_ID != 0xBD ) { position += 6 + pes_payloadlength; continue loop; } if (pes_streamtype == CommonParsing.MPEG1PS_TYPE) { pes_offset = 6; skiploop: while(true) { switch (0xC0 & data[position + pes_offset]) { case 0x40: pes_offset += 2; continue skiploop; case 0x80: pes_offset += 3; continue skiploop; case 0xC0: pes_offset++; continue skiploop; case 0: break; } switch (0x30 & data[position + pes_offset]) { case 0x20: containsPts = true; break skiploop; case 0x30: containsPts = true; break skiploop; case 0x10: containsPts = false; break skiploop; case 0: containsPts = false; pes_offset++; break skiploop; } } } else { containsPts = (0x80 & data[position + 7]) != 0; pes_offset = 9; } if (containsPts) pts = CommonParsing.getPTSfromBytes(data, position + pes_offset); position += 6 + pes_payloadlength; if (nullpacket) break; } break; } // end switch } catch (IOException e) { Common.setExceptionMessage(e); } } if (file_number == 0 && startPoint == 0) { // need global offset? pts &= 0xFFFFFFFFL; String str = collection.getSettings().getProperty(Keys.KEY_PtsShift_Value); if (str.equals("auto")) { long newpts = ((pts / 324000000L) - 1L) * 324000000L; Common.setMessage(Resource.getString("nextfile.shift.auto", "" + (newpts / 324000000L))); return newpts; } else if (!str.equals("0")) { Common.setMessage(Resource.getString("nextfile.shift.manual", collection.getSettings().getProperty(Keys.KEY_PtsShift_Value))); return ((long)(Double.parseDouble(collection.getSettings().getProperty(Keys.KEY_PtsShift_Value)) * 324000000L)); } else return 0L; } else { pts -= job_processing.getNextFileStartPts(); pts &= 0xFFFFFFFFL; long ret = 0L; if (Math.abs(pts - lastpts) < 900000) ret = -1L; else if (pts > lastpts) ret = 0L; else ret = ((lastpts + 1728000L) - pts); // offset is multiple of 40,24,32,33.1,8ms if (ret >= 0) Common.setMessage(Resource.getString("nextfile.next.file.start", Common.formatTime_1(pts / 90L), Common.formatTime_1(lastpts / 90L))); if (ret > 0) Common.setMessage(Resource.getString("nextfile.next.file.start.adaption", Common.formatTime_1(ret / 90L))); return ret; } } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamParserESAudio.java0000600000175000017500000000667310354406644030433 0ustar supermariosupermario/* * @(#)StreamParser * * Copyright (c) 2005 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.io.PushbackInputStream; import java.io.FileOutputStream; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import java.util.Hashtable; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.io.StandardBuffer; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.xinput.StreamInfo; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.parser.StreamConverter; import net.sourceforge.dvb.projectx.parser.StreamDemultiplexer; import net.sourceforge.dvb.projectx.parser.StreamParserBase; import net.sourceforge.dvb.projectx.parser.StreamProcess; /** * main thread */ public class StreamParserESAudio extends StreamParserBase { /** * */ public StreamParserESAudio() { super(); } /** * check audio ES */ public String parseStream(JobCollection collection, XInputFile aXInputFile, int pes_streamtype, int action, String vptslog) { String fchild = collection.getOutputName(aXInputFile.getName()); String fparent = collection.getOutputNameParent(fchild); String audio_pts = fparent + ".pts"; CommonParsing.logAlias(collection.getJobProcessing(), vptslog, audio_pts); String type = "mp"; int es_streamtype = CommonParsing.MPEG_AUDIO; switch (pes_streamtype) { case CommonParsing.ES_AC3_TYPE: case CommonParsing.ES_AC3_A_TYPE: type = "ac"; es_streamtype = CommonParsing.AC3_AUDIO; break; case CommonParsing.ES_DTS_TYPE: case CommonParsing.ES_DTS_A_TYPE: type = "ac"; es_streamtype = CommonParsing.DTS_AUDIO; break; case CommonParsing.ES_MPA_TYPE: type = "mp"; es_streamtype = CommonParsing.MPEG_AUDIO; break; case CommonParsing.ES_RIFF_TYPE: type = "wa"; es_streamtype = CommonParsing.WAV_AUDIO; break; } /** * audiofile goes to synch methode */ new StreamProcess(es_streamtype, collection, aXInputFile, audio_pts, type, vptslog, CommonParsing.ES_TYPE); new File(audio_pts).delete(); return null; } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamParserESSubpicture.java0000600000175000017500000000504210354403410031470 0ustar supermariosupermario/* * @(#)StreamParser * * Copyright (c) 2005 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.io.PushbackInputStream; import java.io.FileOutputStream; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import java.util.Hashtable; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.io.StandardBuffer; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.xinput.StreamInfo; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.parser.StreamConverter; import net.sourceforge.dvb.projectx.parser.StreamDemultiplexer; import net.sourceforge.dvb.projectx.parser.StreamParserBase; import net.sourceforge.dvb.projectx.parser.StreamProcess; /** * main thread */ public class StreamParserESSubpicture extends StreamParserBase { /** * */ public StreamParserESSubpicture() { super(); } /** * subpicture elementary stream */ public String parseStream(JobCollection collection, XInputFile xInputFile, int pes_streamtype, int action, String vptslog) { // is elementary new StreamProcess(CommonParsing.SUBPICTURE, collection, xInputFile, "-1", "sp", vptslog, CommonParsing.ES_TYPE); return null; } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamParserESVideo.java0000600000175000017500000004073710411115242030420 0ustar supermariosupermario/* * @(#)StreamParser * * Copyright (c) 2005-2006 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.io.PushbackInputStream; import java.io.FileOutputStream; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.BufferedWriter; import java.io.FileWriter; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import java.util.Hashtable; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.io.StandardBuffer; import net.sourceforge.dvb.projectx.io.IDDBufferedOutputStream; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.xinput.StreamInfo; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.parser.StreamConverter; import net.sourceforge.dvb.projectx.parser.StreamDemultiplexer; import net.sourceforge.dvb.projectx.parser.StreamParserBase; import net.sourceforge.dvb.projectx.video.Video; /** * main thread */ public class StreamParserESVideo extends StreamParserBase { private double videotimecount = 0.0; /** * */ public StreamParserESVideo() { super(); } /** * check video ES */ public String parseStream(JobCollection collection, XInputFile aXInputFile, int pes_streamtype, int action, String vptslog) { String fchild = collection.getOutputName(aXInputFile.getName()); String fparent = collection.getOutputNameParent(fchild); JobProcessing job_processing = collection.getJobProcessing(); /** * split part */ fparent += job_processing.getSplitSize() > 0 ? "(" + job_processing.getSplitPart() + ")" : ".new" ; boolean CreateInfoIndex = collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createInfoIndex); boolean CreateM2sIndex = collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createM2sIndex); boolean CreateD2vIndex = collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createD2vIndex); boolean SplitProjectFile = collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_splitProjectFile); boolean WriteVideo = collection.getSettings().getBooleanProperty(Keys.KEY_WriteOptions_writeVideo); boolean AddSequenceEndcode = collection.getSettings().getBooleanProperty(Keys.KEY_VideoPanel_addEndcode); boolean RenameVideo = collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_renameVideo); boolean Debug = collection.getSettings().getBooleanProperty(Keys.KEY_DebugLog); boolean Overlap = collection.getSettings().getBooleanProperty(Keys.KEY_ExportPanel_Export_Overlap); boolean CreateCellTimes = collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createCellTimes); boolean first = true; boolean doWrite = true; boolean lead_sequenceheader = false; boolean isHeaderless = false; byte[] vgl = new byte[4]; byte[] vptsbytes = new byte[16]; byte[] vload = new byte[0]; byte[] es_packet; long filelength = aXInputFile.length(); long pos = 0; long pts = 0; long startPoint = 0; long Overlap_Value = 1048576L * (collection.getSettings().getIntProperty(Keys.KEY_ExportPanel_Overlap_Value) + 1); int CutMode = collection.getSettings().getIntProperty(Keys.KEY_CutMode); int[] MPGVideotype = { 0 }; int load = MainBufferSize / 2; int mark; int diff; int extension_index; int part; job_processing.clearStatusVariables(); int[] clv = job_processing.getStatusVariables(); double[] fps_tabl2 = { 0, 3753.7537, 3750, 3600, 3003.003, 3000, 1800, 1501.5015, 1500, 0,0,0,0,0,0,0 }; String[] videoext = { ".mpv", ".mpv", ".m1v", ".m2v" }; vptslog = "-1"; //fix Common.updateProgressBar(Resource.getString("video.progress") + " " + fchild, 0, 0); StreamDemultiplexer streamdemultiplexer = new StreamDemultiplexer(); try { PushbackInputStream in = new PushbackInputStream(aXInputFile.getInputStream(), 4); IDDBufferedOutputStream vstream = new IDDBufferedOutputStream( new FileOutputStream(fparent + ".s1"), MainBufferSize); /** * M2s project */ if (CreateM2sIndex) vstream.InitIdd(fparent, 1); /** * CM project */ if (CreateInfoIndex) vstream.InitInfo(fparent); DataOutputStream vlog = new DataOutputStream( new FileOutputStream(fparent + ".s1.pts") ); ByteArrayOutputStream es_packetbuffer = new ByteArrayOutputStream(); job_processing.setElementaryVideoStream(true); job_processing.setMinBitrate(CommonParsing.MAX_BITRATE_VALUE); job_processing.setMaxBitrate(0); job_processing.setExportedVideoFrameNumber(0); job_processing.setEndPtsOfGop(-10000); job_processing.setAllMediaFilesExportLength(0); job_processing.setProjectFileExportLength(0); job_processing.setCutByteposition(0); /** * d2v project */ if (CreateD2vIndex || SplitProjectFile) job_processing.getProjectFileD2V().Init(fparent); /** * split skipping first */ if (job_processing.getSplitSize() > 0) { startPoint = job_processing.getLastHeaderBytePosition(); startPoint -= !Overlap ? 0 : Overlap_Value; doWrite = false; /** * set to 0, because we do not jump directly to the position due to possible audio sync-lost of elementary streams */ job_processing.setLastGopTimecode(0); job_processing.setLastGopPts(0); job_processing.setLastSimplifiedPts(0); /** if (pos < startPoint) startPoint = pos; while (pos < startPoint) pos += in.skip(startPoint-pos); **/ } List CutpointList = collection.getCutpointList(); List ChapterpointList = collection.getChapterpointList(); /** * if you do so, there's no common entry point with audio anymore, * therefore only one inputfile is allowed * jump to first cut-in point * if (CutMode == CommonParsing.CUTMODE_BYTE && CommonParsing.getCutCounter() == 0 && CutpointList.size() > 0) { long startPoint = Long.parseLong(CutpointList.get(CommonParsing.getCutCounter()).toString()); while (pos < startPoint) pos += in.skip(startPoint-pos); } **/ bigloop: while (pos < filelength) { while (pause()) {} if (CommonParsing.isProcessCancelled()) { CommonParsing.setProcessCancelled(false); job_processing.setSplitSize(0); break bigloop; } /** * cut end reached */ if (job_processing.getCutComparePoint() + 20 < job_processing.getSourceVideoFrameNumber()) break bigloop; load = (filelength - pos < (long)load) ? (int)(filelength - pos) : load; vload = new byte[load]; in.read(vload); pos += load; Common.updateProgressBar(pos, filelength); //yield(); mark = 0; loop: for (int i = 0, returncode, pes_ID; i < vload.length - 3; i++) { if (CutMode == CommonParsing.CUTMODE_BYTE && CutpointList.size() > 0) { if (CommonParsing.getCutCounter() == CutpointList.size() && (CommonParsing.getCutCounter() & 1) == 0) if (pos + i > Long.parseLong(CutpointList.get(CommonParsing.getCutCounter() - 1).toString())) break bigloop; } if ((returncode = CommonParsing.validateStartcode(vload, i)) < 0) { i += (-returncode) - 1; //note i++ continue loop; } pes_ID = CommonParsing.getPES_IdField(vload, i); switch (pes_ID) { case CommonParsing.PICTURE_START_CODE: lead_sequenceheader = false; i += 3; continue loop; case CommonParsing.GROUP_START_CODE: if (lead_sequenceheader) { lead_sequenceheader = false; i += 8; continue loop; } // do not break case CommonParsing.SEQUENCE_HEADER_CODE: case CommonParsing.SEQUENCE_END_CODE: if (pes_ID == CommonParsing.SEQUENCE_HEADER_CODE) lead_sequenceheader = true; es_packetbuffer.write(vload, mark, i - mark); mark = i; job_processing.setCutByteposition(pos - load + mark); if (job_processing.getCutByteposition() >= startPoint) doWrite = true; //if (!first) if (!first && !isHeaderless) //changed { es_packet = es_packetbuffer.toByteArray(); es_packetbuffer.reset(); firstframeloop: for (int j = 0, pes_ID_temp; j < 6000 && j < es_packet.length - 5; j++) { if ((returncode = CommonParsing.validateStartcode(es_packet, j)) < 0) { j += (-returncode) - 1; //note j++ continue firstframeloop; } pes_ID_temp = CommonParsing.getPES_IdField(es_packet, j); if (pes_ID_temp == CommonParsing.SEQUENCE_HEADER_CODE) videotimecount = fps_tabl2[15 & es_packet[j + 7]]; else if (pes_ID_temp == CommonParsing.PICTURE_START_CODE) { pts = (long)(job_processing.getSourceVideoFrameNumber() == 0 ? videotimecount * ((0xFF & es_packet[j + 4])<<2 | (0xC0 & es_packet[j + 5])>>>6) : (videotimecount * ( (0xFF & es_packet[j + 4])<<2 | (0xC0 & es_packet[j + 5])>>>6 )) + job_processing.getLastSimplifiedPts()); CommonParsing.setValue(vptsbytes, 0, 8, !CommonParsing.BYTEREORDERING, pts); break firstframeloop; } } // route through demuxer streamdemultiplexer.writeVideoES(job_processing, vstream, es_packet, vptsbytes, vlog, fparent, MPGVideotype, CutpointList, ChapterpointList, doWrite); } es_packetbuffer.reset(); if (pes_ID == CommonParsing.SEQUENCE_END_CODE) { Common.setMessage(Resource.getString("video.msg.skip.sec", "" + clv[6]) + " " + (pos - load + i)); i += 4; mark = i; } job_processing.setLastHeaderBytePosition(pos - load + i); // split marker sequence_gop start /** * split size reached */ if (job_processing.getSplitSize() > 0 && job_processing.getSplitSize() < job_processing.getAllMediaFilesExportLength()) break bigloop; /** * d2v split reached */ if (SplitProjectFile && job_processing.getProjectFileExportLength() > job_processing.getProjectFileSplitSize()) { part = job_processing.getProjectFileD2V().getPart() + 1; String newpart = fparent + "[" + part + "].mpv"; /** * sequence end code */ if (WriteVideo && AddSequenceEndcode && job_processing.getExportedVideoFrameNumber() > 0 ) { vstream.write(Video.getSequenceEndCode()); job_processing.countMediaFilesExportLength(+4); } job_processing.countAllMediaFilesExportLength(+4); vstream.flush(); vstream.close(); //System.gc(); vstream = new IDDBufferedOutputStream( new FileOutputStream(newpart), MainBufferSize - 1000000); if (CreateM2sIndex) vstream.InitIdd(newpart, 1); if (CreateInfoIndex) vstream.InitInfo(newpart); job_processing.getProjectFileD2V().setFile(newpart); job_processing.setProjectFileExportLength(0); } if (pes_ID == CommonParsing.GROUP_START_CODE) { job_processing.setSequenceHeader(false); if (job_processing.getSplitPart() > 0) first = false; } else { job_processing.setSequenceHeader(true); first = false; } //new isHeaderless = false; diff = (vload.length - mark - 4 < 2500) ? (vload.length - mark - 4) : 2500; //new if (pes_ID == CommonParsing.SEQUENCE_END_CODE) { diff = 0; isHeaderless = true; //skip data between sequnece end + sequence start } // if (diff > 0) { es_packetbuffer.write(vload, mark, diff); i += diff; mark = i; } break; default: i += 3; // do nothing } //overload if (es_packetbuffer.size() > 6144000) { Arrays.fill(vptsbytes, (byte)0); es_packetbuffer.reset(); first = true; Common.setMessage(Resource.getString("demux.error.gop.toobig")); } } /** * file end reached */ if (pos >= filelength - 1) { if (job_processing.getSplitSize() > 0) job_processing.setSplitLoopActive(false); break bigloop; } diff = vload.length < 3 ? vload.length : 3; es_packetbuffer.write(vload, mark, vload.length - mark - diff); in.unread(vload, vload.length - diff, diff); pos -= diff; } /** * d2v project */ if (CreateD2vIndex || SplitProjectFile) job_processing.getProjectFileD2V().write(job_processing.getProjectFileExportLength(), job_processing.getExportedVideoFrameNumber()); /** * sequence end code */ if (WriteVideo && AddSequenceEndcode && job_processing.getExportedVideoFrameNumber() > 0 ) { vstream.write(Video.getSequenceEndCode()); job_processing.countMediaFilesExportLength(+4); } in.close(); vstream.flush(); vstream.close(); vlog.flush(); vlog.close(); Common.setMessage(""); Common.setMessage(Resource.getString("video.msg.summary") + " " + job_processing.getExportedVideoFrameNumber() + "/ " + clv[0] + "/ " + clv[1] + "/ " + clv[2] + "/ " + clv[3] + "/ " + clv[4]); File newfile = new File(fparent + ".s1"); String videofile = ""; if (newfile.length() < 20) newfile.delete(); else if (!WriteVideo) newfile.delete(); else { extension_index = (RenameVideo || CreateD2vIndex || SplitProjectFile) ? 0 : 2; videofile = fparent + videoext[MPGVideotype[0] + extension_index]; newfile = new File(videofile); if (newfile.exists()) newfile.delete(); Common.renameTo(new File(fparent + ".s1"), newfile); vptslog = fparent + ".s1.pts"; CommonParsing.setVideoHeader(job_processing, videofile, vptslog, clv, MPGVideotype); } if (CreateM2sIndex) { if (new File(videofile).exists()) vstream.renameVideoIddTo(fparent); else vstream.deleteIdd(); } if (CreateInfoIndex) { if (new File(videofile).exists()) { String tmpFN = videofile.toString(); vstream.renameVideoInfoTo(tmpFN); } else vstream.deleteInfo(); } List cell = job_processing.getCellTimes(); String workouts = collection.getOutputDirectory() + collection.getFileSeparator(); /** * celltimes.txt */ if (CreateCellTimes && !cell.isEmpty()) { BufferedWriter cellout = new BufferedWriter(new FileWriter(workouts + "CellTimes.txt")); for (int i = 0; i < cell.size(); i++) { cellout.write(cell.get(i).toString()); cellout.newLine(); } cellout.close(); Common.setMessage(Resource.getString("demux.msg.celltimes", workouts)); long fl = new File(workouts + "CellTimes.txt").length(); job_processing.countMediaFilesExportLength(fl); job_processing.countAllMediaFilesExportLength(fl); } } catch (IOException e) { Common.setExceptionMessage(e); } return vptslog; } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamParserPESPrimary.java0000600000175000017500000011772510411351174031125 0ustar supermariosupermario/* * @(#)StreamParser * * Copyright (c) 2005-2006 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.io.PushbackInputStream; import java.io.FileOutputStream; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import java.util.Hashtable; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.io.StandardBuffer; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.xinput.StreamInfo; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.parser.StreamConverter; import net.sourceforge.dvb.projectx.parser.StreamDemultiplexer; import net.sourceforge.dvb.projectx.parser.StreamParserBase; import net.sourceforge.dvb.projectx.parser.StreamProcess; /** * main thread */ public class StreamParserPESPrimary extends StreamParserBase { /** * */ public StreamParserPESPrimary() { super(); } /** * primary PES Parser */ public String parseStream(JobCollection collection, XInputFile aXInputFile, int _pes_streamtype, int action, String vptslog) { String fchild = collection.getOutputName(aXInputFile.getName()); String fparent = collection.getOutputNameParent(fchild); JobProcessing job_processing = collection.getJobProcessing(); /** * split part */ fparent += job_processing.getSplitSize() > 0 ? "(" + job_processing.getSplitPart() + ")" : "" ; boolean Message_2 = collection.getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg2); boolean Debug = collection.getSettings().getBooleanProperty(Keys.KEY_DebugLog); boolean SimpleMPG = collection.getSettings().getBooleanProperty(Keys.KEY_simpleMPG); boolean GetEnclosedPackets = collection.getSettings().getBooleanProperty(Keys.KEY_Input_getEnclosedPackets); boolean IgnoreScrambledPackets = collection.getSettings().getBooleanProperty(Keys.KEY_TS_ignoreScrambled); boolean PreviewAllGops = collection.getSettings().getBooleanProperty(Keys.KEY_Preview_AllGops); boolean DumpDroppedGop = collection.getSettings().getBooleanProperty(Keys.KEY_dumpDroppedGop); boolean CreateD2vIndex = collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createD2vIndex); boolean SplitProjectFile = collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_splitProjectFile); boolean Overlap = collection.getSettings().getBooleanProperty(Keys.KEY_ExportPanel_Export_Overlap); boolean isTeletext = false; boolean missing_startcode = false; boolean scrambling_messaged = false; boolean pes_isMpeg2; boolean pes_alignment; boolean pes_scrambled; boolean containsPts = false; boolean usePidfilter = false; boolean isZeroPacket = false; boolean isZeroSubPacket = false; boolean ende = false; boolean foundObject; int Infoscan_Value = Integer.parseInt(collection.getSettings().getProperty(Keys.KEY_ExportPanel_Infoscan_Value)); int CutMode = collection.getSettings().getIntProperty(Keys.KEY_CutMode); int pes_streamtype = _pes_streamtype; int pes_payloadlength; int pes_packetlength; int pes_extensionlength; int pes_headerlength = 9; int pes_packetoffset = 6; int pes_extension2_id; int pesID; int subID; int offset; int returncode = 0; int vob_ID = 0; int cell_ID = 0; int ZeroPacketPayload = 0x17FA; int pesID0 = 0; //first video stream ID int dumped_packets = 0; job_processing.clearStatusVariables(); int[] clv = job_processing.getStatusVariables(); int[] newID = { 0x80, 0x90, 0xC0, 0xE0, 0xA0, 0x20 }; byte[] pes_packet = new byte[0x10010]; byte[] buffered_data; long count = 0; long base; long size = count; long qexit; long ptsoffset = 0; long lastpts = 0; long startPoint = 0; long starts[] = new long[collection.getPrimaryInputFileSegments()]; long Overlap_Value = 1048576L * (collection.getSettings().getIntProperty(Keys.KEY_ExportPanel_Overlap_Value) + 1); vptslog = "-1"; //fix StreamDemultiplexer streamdemultiplexer = null; StreamConverter streamconverter = new StreamConverter(); Hashtable substreams = new Hashtable(); StandardBuffer sb; List demuxList = job_processing.getPrimaryPESDemuxList(); /** * re-read old streams, for next split part */ if (job_processing.getSplitPart() == 0) demuxList.clear(); else { for (int i = 0; i < demuxList.size(); i++) { streamdemultiplexer = (StreamDemultiplexer) demuxList.get(i); if (streamdemultiplexer.getnewID() != 0) newID[streamdemultiplexer.getType()]++; if (streamdemultiplexer.getNum() == -1) continue; if (streamdemultiplexer.getType() == CommonParsing.MPEG_VIDEO) { streamdemultiplexer.initVideo2(fparent); if (pesID0 == 0) //? pesID0 = streamdemultiplexer.getID(); } else streamdemultiplexer.init2(fparent); } } String mpeg_type_str = (Keys.ITEMS_FileTypes[pes_streamtype]).toString().toLowerCase(); mpeg_type_str = "[" + mpeg_type_str.substring(0, mpeg_type_str.indexOf(' ')) + "]"; switch (action) { case CommonParsing.ACTION_TO_VDR: streamconverter.init(fparent + (job_processing.getSplitSize() == 0 ? mpeg_type_str : "") + ".vdr", MainBufferSize, action, job_processing.getSplitPart()); break; case CommonParsing.ACTION_TO_M2P: streamconverter.init(fparent + (job_processing.getSplitSize() == 0 ? mpeg_type_str : "") + ".m2p", MainBufferSize, action, job_processing.getSplitPart()); break; case CommonParsing.ACTION_TO_PVA: streamconverter.init(fparent + ".pva", MainBufferSize, action, job_processing.getSplitPart()); break; case CommonParsing.ACTION_TO_TS: streamconverter.init(fparent + ".ts", MainBufferSize, action, job_processing.getSplitPart()); break; case CommonParsing.ACTION_FILTER: streamconverter.init(fparent + "[filtered].pes", MainBufferSize, action, job_processing.getSplitPart()); } /** * d2v projectfile */ if (CreateD2vIndex || SplitProjectFile) job_processing.getProjectFileD2V().Init(fparent); job_processing.setMinBitrate(CommonParsing.MAX_BITRATE_VALUE); job_processing.setMaxBitrate(0); job_processing.setExportedVideoFrameNumber(0); job_processing.setEndPtsOfGop(-10000); job_processing.setSequenceHeader(true); job_processing.setAllMediaFilesExportLength(0); job_processing.setProjectFileExportLength(0); job_processing.setCutByteposition(0); /** * pid inclusion */ int[] predefined_Pids = collection.getPIDsAsInteger(); int[] include = new int[predefined_Pids.length]; for (int i = 0; i < include.length; i++) include[i] = 0xFF & predefined_Pids[i]; if (include.length > 0) { Arrays.sort(include); String str = " "; for (int i = 0; i < include.length; i++) str += "0x" + Integer.toHexString(include[i]).toUpperCase() + " "; Common.setMessage(Resource.getString("parsePrimaryPES.special.pes") + ": {" + str + "}"); usePidfilter = true; } try { /** * determine start & end byte pos. of each file segment */ for (int i = 0; i < starts.length; i++) { aXInputFile = (XInputFile) collection.getInputFile(i); starts[i] = size; size += aXInputFile.length(); } aXInputFile = (XInputFile) collection.getInputFile(job_processing.getFileNumber()); /** * set start & end byte pos. of first file segment */ count = starts[job_processing.getFileNumber()]; size = count + aXInputFile.length(); /** * split skipping first, for next split part */ if (job_processing.getSplitSize() > 0) { startPoint = job_processing.getLastHeaderBytePosition(); startPoint -= !Overlap ? 0 : Overlap_Value; job_processing.setLastGopTimecode(0); job_processing.setLastGopPts(0); job_processing.setLastSimplifiedPts(0); } List CutpointList = collection.getCutpointList(); List ChapterpointList = collection.getChapterpointList(); /** * jump near to first cut-in point to collect more audio */ if (CutMode == CommonParsing.CUTMODE_BYTE && CutpointList.size() > 0 && CommonParsing.getCutCounter() == 0 && (!PreviewAllGops || action != CommonParsing.ACTION_DEMUX)) startPoint = Long.parseLong(CutpointList.get(CommonParsing.getCutCounter()).toString()) - ((action == CommonParsing.ACTION_DEMUX) ? 2048000: 0); if (startPoint < 0) startPoint = count; // =0 else if (startPoint < count) { for (int i = starts.length; i > 0; i--) if (starts[i - 1] > startPoint) job_processing.countFileNumber(-1); } else if (startPoint > count) { for (int i = job_processing.getFileNumber() + 1; i < starts.length; i++) { if (starts[i] > startPoint) break; else job_processing.countFileNumber(+1); } } aXInputFile = (XInputFile) collection.getInputFile(job_processing.getFileNumber()); count = starts[job_processing.getFileNumber()]; if (job_processing.getFileNumber() > 0) Common.setMessage(Resource.getString("parsePrimaryPES.continue") + ": " + aXInputFile); base = count; size = count + aXInputFile.length(); PushbackInputStream in = new PushbackInputStream(aXInputFile.getInputStream(startPoint - base), pes_packet.length); count += (startPoint - base); Common.updateProgressBar((action == CommonParsing.ACTION_DEMUX ? Resource.getString("parsePrimaryPES.demuxing") : Resource.getString("parsePrimaryPES.converting")) + " " + Resource.getString("parsePrimaryPES.avpes.file") + " " + aXInputFile.getName(), (count - base), (size - base)); qexit = count + (0x100000L * Infoscan_Value); //yield(); bigloop: while (true) { loop: while (count < size) { pes_streamtype = _pes_streamtype; // reset to original type Common.updateProgressBar(count, size); //yield(); while (pause()) {} if (CommonParsing.isProcessCancelled() || (CommonParsing.isInfoScan() && count > qexit)) { CommonParsing.setProcessCancelled(false); job_processing.setSplitSize(0); break bigloop; } /** * after last cut out, still read some packets to collect some audio */ if (job_processing.getCutComparePoint() + 20 < job_processing.getSourceVideoFrameNumber()) { ende = true; break bigloop; } /** * cut mode bytepos + min 1 cutpoint */ if (CutMode == CommonParsing.CUTMODE_BYTE && CutpointList.size() > 0) { if (CommonParsing.getCutCounter() == CutpointList.size() && (CommonParsing.getCutCounter() & 1) == 0) if (count > Long.parseLong(CutpointList.get(CommonParsing.getCutCounter() - 1).toString()) + (action == CommonParsing.ACTION_DEMUX ? 2048000 : 64000)) { ende = true; break bigloop; } } in.read(pes_packet, 0, pes_packetoffset); pesID = CommonParsing.getPES_IdField(pes_packet, 0); /** * */ if ((returncode = CommonParsing.validateStartcode(pes_packet, 0)) < 0 || pesID < CommonParsing.SYSTEM_END_CODE) { returncode = returncode < 0 ? -returncode : 4; if (Message_2 && !missing_startcode) Common.setMessage(Resource.getString("parsePrimaryPES.missing.startcode") + " " + count); in.read(pes_packet, pes_packetoffset, pes_packet.length - pes_packetoffset); int i = returncode; for (; i < pes_packet.length - 3; ) { returncode = CommonParsing.validateStartcode(pes_packet, i); if (returncode < 0) { i += -returncode; continue; } else { in.unread(pes_packet, i, pes_packet.length - i); count += i; missing_startcode = true; continue loop; } } in.unread(pes_packet, i, pes_packet.length - i); count += i; missing_startcode = true; continue loop; } if (Message_2 && missing_startcode) Common.setMessage(Resource.getString("parsePrimaryPES.found.startcode") + " " + count); missing_startcode = false; if (pes_streamtype == CommonParsing.MPEG1PS_TYPE || pes_streamtype == CommonParsing.MPEG2PS_TYPE || SimpleMPG) { switch (pesID) { case CommonParsing.SYSTEM_END_CODE: in.unread(pes_packet, 4, 2); Common.setMessage("-> skip system_end_code @ " + count); count += 4; continue loop; case CommonParsing.PACK_START_CODE: if ((0xC0 & pes_packet[4]) == 0) //mpg1 { in.skip(pes_packetoffset); count += 12; continue loop; } else if ((0xC0 & pes_packet[4]) == 0x40) //mpg2 { in.read(pes_packet, pes_packetoffset, 8); offset = 7 & pes_packet[13]; count += 14; in.read(pes_packet, 14, offset); if (offset > 0) { for (int i = 0; i < offset; i++) if (pes_packet[14 + i] != -1) { in.unread(pes_packet, 14, offset); Common.setMessage("!> wrong pack header stuffing @ " + count); missing_startcode = true; continue loop; } } count += offset; continue loop; } else { in.unread(pes_packet, 4, 2); count += 4; continue loop; } case CommonParsing.PRIVATE_STREAM_2_CODE: //determine cellids pes_payloadlength = CommonParsing.getPES_LengthField(pes_packet, 0); in.read(pes_packet, pes_packetoffset, pes_payloadlength); if (pes_packet[pes_packetoffset] == 1) //substream id 1 { int cellid = 0xFF & pes_packet[0x22]; int vobid = (0xFF & pes_packet[0x1F])<<8 | (0xFF & pes_packet[0x20]); if (cell_ID != cellid || vob_ID != vobid) { Common.setMessage(Resource.getString("parsePrimaryPES.split.cellids", "" + vobid, "" + cellid, "" + count, "" + clv[6], "" + job_processing.getExportedVideoFrameNumber())); if (collection.getSettings().getBooleanProperty(Keys.KEY_VOB_resetPts)) { ptsoffset = nextFilePTS(collection, CommonParsing.PRIMARY_PES_PARSER, pes_streamtype, lastpts, job_processing.getFileNumber(), (count - base)); if (ptsoffset == -1) ptsoffset = 0; else { for (int i = 0; i < demuxList.size(); i++) { streamdemultiplexer = (StreamDemultiplexer)demuxList.get(i); streamdemultiplexer.PTSOffset(ptsoffset); if (streamdemultiplexer.getID() == pesID0) streamdemultiplexer.resetVideo(); } job_processing.setSequenceHeader(true); job_processing.setNewVideoStream(true); // job_processing.addCellTime(String.valueOf(job_processing.getExportedVideoFrameNumber())); } } } cell_ID = cellid; vob_ID = vobid; } count += (pes_packetoffset + pes_payloadlength); continue loop; case CommonParsing.SYSTEM_START_CODE: case CommonParsing.PROGRAM_STREAM_MAP_CODE: case CommonParsing.PADDING_STREAM_CODE: case CommonParsing.ECM_STREAM_CODE: case CommonParsing.EMM_STREAM_CODE: case CommonParsing.DSM_CC_STREAM_CODE: case 0xF3: case 0xF4: case 0xF5: case 0xF6: case 0xF7: case 0xF8: case 0xF9: case 0xFA: case 0xFB: case 0xFC: case 0xFD: case 0xFE: case 0xFF: pes_payloadlength = CommonParsing.getPES_LengthField(pes_packet, 0); in.skip(pes_payloadlength); count += (pes_packetoffset + pes_payloadlength); continue loop; } } if ( (0xF0 & pesID) != 0xE0 && (0xE0 & pesID) != 0xC0 && pesID != CommonParsing.PRIVATE_STREAM_1_CODE) { in.unread(pes_packet, 3, pes_packetoffset - 3); count += 3; continue loop; } /** * mark for split at sequenceheader */ job_processing.setLastHeaderBytePosition(count); job_processing.setCutByteposition(count); pes_payloadlength = CommonParsing.getPES_LengthField(pes_packet, 0); /** * zeropackets of video only as PES from TS allowed */ isZeroPacket = pes_payloadlength == 0 && (0xF0 & pesID) == 0xE0; if (isZeroPacket) pes_payloadlength = ZeroPacketPayload; in.read(pes_packet, pes_packetoffset, pes_payloadlength + 4); pes_packetlength = pes_packetoffset + pes_payloadlength; /** * determine next startcode in zero packets */ if (isZeroPacket) { if (Debug) System.out.println("A " + Resource.getString("parsePrimaryPES.packet.length") + " " + count); for (int i = pes_packetoffset; isZeroPacket && i <= pes_packetlength; ) { if ((returncode = CommonParsing.validateStartcode(pes_packet, i)) < 0 || CommonParsing.getPES_IdField(pes_packet, i) < CommonParsing.SYSTEM_END_CODE) { i += (returncode < 0 ? -returncode : 4); continue; } /** * next header found before max. size of ZeroPacketPayload * handle packet as normal, the 4 added bytes will be unread in the next startcode check */ in.unread(pes_packet, i + 4, pes_packetlength - i); pes_packetlength = i; pes_payloadlength = pes_packetlength - pes_packetoffset; isZeroPacket = false; } CommonParsing.setPES_LengthField(pes_packet, 0, pes_payloadlength); } /** * check next startcode */ if (GetEnclosedPackets && !isZeroPacket && CommonParsing.validateStartcode(pes_packet, pes_packetlength) < 0) { if (count + pes_packetlength < size) { if (Message_2 && !missing_startcode) Common.setMessage(Resource.getString("parsePrimaryPES.miss.startcode2", String.valueOf(count + pes_packetlength), String.valueOf(count), Integer.toHexString(pesID).toUpperCase())); missing_startcode = true; in.unread(pes_packet, pes_packetoffset, pes_payloadlength + 4); count += pes_packetoffset; continue loop; } } else in.unread(pes_packet, pes_packetlength, 4); clv[5]++; if (Debug) System.out.print("\r"+Resource.getString("parsePrimaryPES.packs") + ": " + pesID + "/" + clv[5] + "/" + (pes_packetlength) + "/" + ((count * 100 / size)) + "% " + (count)); pes_extensionlength = CommonParsing.getPES_ExtensionLengthField(pes_packet, 0); pes_isMpeg2 = (0xC0 & pes_packet[6]) == 0x80; pes_alignment = pes_isMpeg2 && (4 & pes_packet[6]) != 0; pes_scrambled = pes_isMpeg2 && (0x30 & pes_packet[6]) != 0; count += pes_packetlength; zeropacketloop: do { /** * exit loop */ if (isZeroPacket && count >= size) break zeropacketloop; /** * read videos zerosubpacket data in a loop, if packet data is greater than max. ZeroPacketPayload * the first read header data is re-used, we read only the rest */ if (isZeroSubPacket) { if (Debug) System.out.println("B " + Resource.getString("parsePrimaryPES.packet.length") + " " + count); pes_payloadlength = ZeroPacketPayload; pes_packetlength = pes_packetoffset + pes_payloadlength; offset = pes_isMpeg2 ? 3 : 1; in.read(pes_packet, pes_packetoffset + offset, pes_payloadlength - offset + 4); in.unread(pes_packet, pes_packetlength, 4); for (int i = pes_packetoffset + offset; isZeroPacket && i <= pes_packetlength; ) { if ((returncode = CommonParsing.validateStartcode(pes_packet, i)) < 0 || CommonParsing.getPES_IdField(pes_packet, i) < CommonParsing.SYSTEM_END_CODE) { i += (returncode < 0 ? -returncode : 4); continue; } /** * next header found before max. size of ZeroPacketPayload * handle packet as normal, the 4 added bytes will be unread in the next startcode check */ in.unread(pes_packet, i, pes_packetlength - i); pes_packetlength = i; pes_payloadlength = pes_packetlength - pes_packetoffset; // set isZeroPacket to false, if next startcode was found isZeroPacket = false; } CommonParsing.setValue(pes_packet, pes_packetoffset, offset, false, pes_isMpeg2 ? (0xF3 & pes_packet[pes_packetoffset])<<16 : 0x0F); // values of pes scrambling and copyright/copy prot. are taken from orig. CommonParsing.setPES_LengthField(pes_packet, 0, pes_payloadlength); count += (pes_payloadlength - offset); } isZeroSubPacket = isZeroPacket; /** * check scrambling */ if (IgnoreScrambledPackets) { // cannot work with scrambled data if (pes_scrambled) { if (!scrambling_messaged) { scrambling_messaged = true; Common.setMessage(Resource.getString("parseTS.scrambled", Integer.toHexString(pesID).toUpperCase(), String.valueOf(clv[5]), String.valueOf(count - pes_packetlength))); } continue zeropacketloop; } else if (scrambling_messaged) { Common.setMessage(Resource.getString("parseTS.clear", Integer.toHexString(pesID).toUpperCase(), String.valueOf(clv[5]), String.valueOf(count - pes_packetlength))); scrambling_messaged = false; } } /** * vdr_dvbsub determination */ pes_extension2_id = CommonParsing.getExtension2_Id(pes_packet, pes_headerlength, pes_payloadlength, pesID, pes_isMpeg2, job_processing.getLastHeaderBytePosition()); isTeletext = false; subID = 0; if (pesID == CommonParsing.PRIVATE_STREAM_1_CODE && pes_payloadlength > 2) { offset = pes_headerlength + pes_extensionlength; if (offset < pes_packetlength) { subID = 0xFF & pes_packet[offset]; isTeletext = pes_extensionlength == 0x24 && subID>>>4 == 1; //subpic in vdr_pes if (pes_alignment && !isTeletext && (subID>>>4 == 2 || subID>>>4 == 3)) pes_streamtype = CommonParsing.MPEG2PS_TYPE; //will be resetted before next packet if (pes_streamtype != CommonParsing.MPEG1PS_TYPE && pes_streamtype != CommonParsing.MPEG2PS_TYPE && !isTeletext) subID = 0; //disables LPCM too } else if (pes_streamtype != CommonParsing.MPEG1PS_TYPE) //? { pes_extensionlength = pes_payloadlength - 3; pes_packet[8] = (byte)(pes_extensionlength); } /** * packet buffering esp. of subpics from vdr or other pes */ if (pes_extension2_id != -1) { String str = String.valueOf(pes_extension2_id); offset = pes_headerlength + pes_extensionlength; if ( !substreams.containsKey(str)) substreams.put(str, new StandardBuffer()); sb = (StandardBuffer) substreams.get(str); // buffer raw packet data if (!pes_alignment) { sb.write(pes_packet, offset, pes_packetlength - offset); continue zeropacketloop; } // start packet, buffer this and get last completed packet else { buffered_data = sb.getData(); sb.reset(); sb.write(pes_packet, 0, pes_packetlength); if (buffered_data == null || buffered_data.length < 10) continue zeropacketloop; pes_packetlength = buffered_data.length; if (pes_packetlength > 0x10005) { Common.setMessage("!> sub packet too long: 0x" + Integer.toHexString(pesID).toUpperCase() + " /ext2_id " + pes_extension2_id); pes_packetlength = 0x10005; } pes_payloadlength = pes_packetlength - pes_packetoffset; System.arraycopy(buffered_data, 0, pes_packet, 0, pes_packetlength); CommonParsing.setPES_LengthField(pes_packet, 0, pes_payloadlength); buffered_data = null; } } } /** * pesID, subID inclusion */ if (usePidfilter) { if (Arrays.binarySearch(include, pesID) < 0 && Arrays.binarySearch(include, subID) < 0) continue zeropacketloop; } /** * raw id filter extraction */ if (action == CommonParsing.ACTION_FILTER) { if (subID != 0) pes_packet[6] |= 4; //set alignment streamconverter.write(job_processing, pes_packet, 0, pes_packetlength, null, job_processing.getCutByteposition(), CommonParsing.isInfoScan(), CutpointList); continue zeropacketloop; } foundObject = false; /** * find ID object */ for (int i = 0; i < demuxList.size(); i++) { streamdemultiplexer = (StreamDemultiplexer) demuxList.get(i); foundObject = pesID == streamdemultiplexer.getID() && subID == streamdemultiplexer.subID() && isTeletext == streamdemultiplexer.isTTX(); if (foundObject) break; } /** * create new ID object */ if (!foundObject) { /** * dump startpacket */ if (DumpDroppedGop) { String dumpname = fparent + "(" + Integer.toHexString(pesID) + "-" + Integer.toHexString(subID) + "#" + (dumped_packets++) + "@" + (count - pes_packetlength) + ").bin"; FileOutputStream dump = new FileOutputStream(dumpname); dump.write(pes_packet, 0, pes_packetlength); dump.flush(); dump.close(); Common.setMessage(Resource.getString("parsePrimaryPES.dump.1st") + ": " + dumpname); } String IDtype = ""; switch (0xF0 & pesID) { case 0xE0: IDtype = Resource.getString("idtype.mpeg.video"); streamdemultiplexer = new StreamDemultiplexer(ptsoffset); streamdemultiplexer.setID(pesID); streamdemultiplexer.setType(CommonParsing.MPEG_VIDEO); streamdemultiplexer.setnewID(newID[CommonParsing.MPEG_VIDEO]++); streamdemultiplexer.setsubID(0); streamdemultiplexer.setStreamType(pes_streamtype); demuxList.add(streamdemultiplexer); if (pesID0 == 0 || pesID0 == pesID) { if (action == CommonParsing.ACTION_DEMUX) streamdemultiplexer.initVideo(fparent, MainBufferSize, demuxList.size(), CommonParsing.PRIMARY_PES_PARSER); else IDtype += " " + Resource.getString("idtype.mapped.to") + Integer.toHexString(streamdemultiplexer.getnewID()).toUpperCase(); pesID0 = pesID; } else IDtype += Resource.getString("idtype.ignored"); break; case 0xC0: case 0xD0: IDtype = Resource.getString("idtype.mpeg.audio"); streamdemultiplexer = new StreamDemultiplexer(ptsoffset); streamdemultiplexer.setID(pesID); streamdemultiplexer.setType(CommonParsing.MPEG_AUDIO); streamdemultiplexer.setnewID(newID[CommonParsing.MPEG_AUDIO]++); streamdemultiplexer.setsubID(0); streamdemultiplexer.setStreamType(pes_streamtype); demuxList.add(streamdemultiplexer); if (action == CommonParsing.ACTION_DEMUX) streamdemultiplexer.init(fparent, MainBufferSize / demuxList.size(), demuxList.size(), CommonParsing.PRIMARY_PES_PARSER); else IDtype += " " + Resource.getString("idtype.mapped.to") + Integer.toHexString(streamdemultiplexer.getnewID()).toUpperCase(); break; } switch (pesID) { case CommonParsing.PRIVATE_STREAM_1_CODE: IDtype = Resource.getString("idtype.private.stream"); IDtype += (isTeletext ? " TTX " : "") + (subID != 0 ? " (SubID 0x" + Integer.toHexString(subID).toUpperCase() + ")" : ""); streamdemultiplexer = new StreamDemultiplexer(ptsoffset); streamdemultiplexer.setID(pesID); streamdemultiplexer.setsubID(subID); streamdemultiplexer.setTTX(isTeletext); if (isTeletext) { streamdemultiplexer.setnewID(newID[CommonParsing.TELETEXT]++); streamdemultiplexer.setType(CommonParsing.TELETEXT); } else { switch(subID>>>4) { case 0: if (pes_streamtype != CommonParsing.MPEG1PS_TYPE && pes_streamtype != CommonParsing.MPEG2PS_TYPE) { streamdemultiplexer.setnewID(newID[CommonParsing.AC3_AUDIO]++); streamdemultiplexer.setType(CommonParsing.AC3_AUDIO); } break; case 8: streamdemultiplexer.setnewID(newID[CommonParsing.AC3_AUDIO]++); streamdemultiplexer.setType(CommonParsing.AC3_AUDIO); break; case 0xA: streamdemultiplexer.setnewID(newID[CommonParsing.LPCM_AUDIO]++); streamdemultiplexer.setType(CommonParsing.LPCM_AUDIO); break; case 2: case 3: streamdemultiplexer.setnewID(newID[CommonParsing.SUBPICTURE]++); streamdemultiplexer.setType(CommonParsing.SUBPICTURE); break; default: streamdemultiplexer.setType(CommonParsing.UNKNOWN); } } streamdemultiplexer.setStreamType(pes_streamtype); demuxList.add(streamdemultiplexer); if (action == CommonParsing.ACTION_DEMUX) { switch (streamdemultiplexer.getType()) { case CommonParsing.AC3_AUDIO: case CommonParsing.DTS_AUDIO: case CommonParsing.TELETEXT: case CommonParsing.SUBPICTURE: case CommonParsing.LPCM_AUDIO: streamdemultiplexer.init(fparent, MainBufferSize / demuxList.size(), demuxList.size(), CommonParsing.PRIMARY_PES_PARSER); break; default: IDtype += Resource.getString("idtype.ignored"); } } else { if (pes_streamtype != CommonParsing.MPEG1PS_TYPE && pes_streamtype != CommonParsing.MPEG2PS_TYPE) IDtype += " " + Resource.getString("idtype.mapped.to") + Integer.toHexString(streamdemultiplexer.getnewID()).toUpperCase(); else if (isTeletext || subID>>>4 == 8) IDtype += " " + Resource.getString("idtype.mapped.to") + Integer.toHexString(streamdemultiplexer.getnewID()).toUpperCase(); else IDtype += Resource.getString("idtype.ignored"); } if (action == CommonParsing.ACTION_TO_VDR) { if ((pes_streamtype == CommonParsing.MPEG1PS_TYPE || pes_streamtype == CommonParsing.MPEG2PS_TYPE) && subID>>>4 != 8) IDtype += Resource.getString("idtype.ignored"); } break; } Common.setMessage(Resource.getString("parsePrimaryPES.found.pesid") + Integer.toHexString(pesID).toUpperCase() + " " + IDtype + " @ " + job_processing.getCutByteposition()); } if (!streamdemultiplexer.StreamEnabled()) continue zeropacketloop; /** * packet to streamdemultiplexer */ if (action == CommonParsing.ACTION_DEMUX) { if (streamdemultiplexer.getType() == CommonParsing.MPEG_VIDEO) { if (pesID0 != streamdemultiplexer.getID()) continue zeropacketloop; streamdemultiplexer.writeVideo(job_processing, pes_packet, 0, pes_packetlength, true, CutpointList, ChapterpointList); } else streamdemultiplexer.write(job_processing, pes_packet, 0, pes_packetlength, true); if (streamdemultiplexer.getPTS() > lastpts) lastpts = streamdemultiplexer.getPTS(); } /** * packet to streamconverter */ else streamconverter.write(job_processing, pes_packet, streamdemultiplexer, job_processing.getCutByteposition(), CommonParsing.isInfoScan(), CutpointList); } while (isZeroPacket); if (action != CommonParsing.ACTION_DEMUX) job_processing.setLastHeaderBytePosition(count); /** * split size reached */ if (job_processing.getSplitSize() > 0 && job_processing.getSplitSize() < job_processing.getAllMediaFilesExportLength()) break loop; } if (job_processing.getSplitSize() > 0 && job_processing.getSplitSize() < job_processing.getAllMediaFilesExportLength()) break bigloop; /** * next file segment */ if (job_processing.getFileNumber() < collection.getPrimaryInputFileSegments() - 1) { in.close(); //System.gc(); if (collection.getSettings().getBooleanProperty(Keys.KEY_Input_concatenateForeignRecords) && action == CommonParsing.ACTION_DEMUX) { ptsoffset = nextFilePTS(collection, CommonParsing.PRIMARY_PES_PARSER, pes_streamtype, lastpts, job_processing.getFileNumber() + 1); if (ptsoffset == -1) ptsoffset = 0; else { for (int i = 0; i < demuxList.size(); i++) { streamdemultiplexer = (StreamDemultiplexer) demuxList.get(i); streamdemultiplexer.PTSOffset(ptsoffset); if (streamdemultiplexer.getID() == pesID0) // ?? streamdemultiplexer.resetVideo(); } job_processing.setSequenceHeader(true); job_processing.setNewVideoStream(true); // job_processing.addCellTime(String.valueOf(job_processing.getExportedVideoFrameNumber())); } } XInputFile nextXInputFile = (XInputFile) collection.getInputFile(job_processing.countFileNumber(+1)); count = size; base = count; size += nextXInputFile.length(); in = new PushbackInputStream(nextXInputFile.getInputStream(), 0x10010); Common.setMessage(Resource.getString("parsePrimaryPES.actual.written") + " " + job_processing.getExportedVideoFrameNumber()); Common.setMessage(Resource.getString("parsePrimaryPES.switch") + " " + nextXInputFile + " (" + Common.formatNumber(nextXInputFile.length()) + " bytes) @ " + base); Common.updateProgressBar((action == CommonParsing.ACTION_DEMUX ? Resource.getString("parsePrimaryPES.demuxing") : Resource.getString("parsePrimaryPES.converting")) + " " + Resource.getString("parsePrimaryPES.avpes.file") + " " + nextXInputFile.getName()); } else break bigloop; } /** * file end reached for split */ if ( (count >= size || ende) && job_processing.getSplitSize() > 0 ) job_processing.setSplitLoopActive(false); in.close(); if (action != CommonParsing.ACTION_DEMUX) streamconverter.close(job_processing, CommonParsing.isInfoScan()); else { for (int i = 0, NumberOfVideostreams = 0; i < demuxList.size(); i++) { streamdemultiplexer = (StreamDemultiplexer) demuxList.get(i); if (streamdemultiplexer.getType() == CommonParsing.MPEG_VIDEO) { /** * accept only first video */ if (NumberOfVideostreams > 0) { Common.setMessage("!> further videostream found (ID 0x" + Integer.toHexString(streamdemultiplexer.getID()).toUpperCase() + ") -> ignored"); continue; } /** * d2v project */ if (CreateD2vIndex || SplitProjectFile) job_processing.getProjectFileD2V().write(job_processing.getProjectFileExportLength(), job_processing.getExportedVideoFrameNumber()); Common.setMessage(""); Common.setMessage(Resource.getString("video.msg.summary") + " " + job_processing.getExportedVideoFrameNumber() + "/ " + clv[0] + "/ " + clv[1] + "/ " + clv[2] + "/ " + clv[3] + "/ " + clv[4]); vptslog = streamdemultiplexer.closeVideo(job_processing, collection.getOutputDirectory() + collection.getFileSeparator()); NumberOfVideostreams++; } } //System.gc(); int[] stream_number = new int[10]; for (int i = 0, es_streamtype; i < demuxList.size(); i++) { streamdemultiplexer = (StreamDemultiplexer) demuxList.get(i); es_streamtype = streamdemultiplexer.getType(); if (es_streamtype == CommonParsing.MPEG_VIDEO) continue; String[] values = streamdemultiplexer.close(job_processing, vptslog); if (values[0].equals("")) { Common.setMessage(Resource.getString("parsePrimaryPES.msg.noexport") + Integer.toHexString(streamdemultiplexer.getID()).toUpperCase() + ")"); continue; } String newfile = values[3] + (stream_number[es_streamtype] > 0 ? ("[" + stream_number[es_streamtype] + "]") : "") + "." + values[2]; Common.renameTo(values[0], newfile); values[0] = newfile; values[3] = vptslog; switch (es_streamtype) { case CommonParsing.AC3_AUDIO: case CommonParsing.DTS_AUDIO: if (streamdemultiplexer.subID() != 0 && (0xF0 & streamdemultiplexer.subID()) != 0x80) break; Common.setMessage(""); Common.setMessage(Resource.getString("parsePrimaryPES.ac3") + " " + (streamdemultiplexer.subID() != 0 ? ("(SubID 0x" + Integer.toHexString(streamdemultiplexer.subID()).toUpperCase() + ")") : "")); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; case CommonParsing.TELETEXT: Common.setMessage(""); Common.setMessage(Resource.getString("parsePrimaryPES.teletext") + Integer.toHexString(streamdemultiplexer.subID()).toUpperCase() + ")"); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; case CommonParsing.MPEG_AUDIO: Common.setMessage(""); Common.setMessage(Resource.getString("parsePrimaryPES.mpeg.audio") + Integer.toHexString(streamdemultiplexer.getID()).toUpperCase() + ")"); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; case CommonParsing.LPCM_AUDIO: Common.setMessage(""); Common.setMessage(Resource.getString("parsePrimaryPES.lpcm.audio") + Integer.toHexString(streamdemultiplexer.subID()).toUpperCase() + ")"); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; case CommonParsing.SUBPICTURE: Common.setMessage(""); Common.setMessage(Resource.getString("parsePrimaryPES.subpic") + Integer.toHexString(streamdemultiplexer.subID()).toUpperCase() + ")"); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; } stream_number[es_streamtype]++; new File(newfile).delete(); new File(values[1]).delete(); } } } catch (IOException e2) { Common.setExceptionMessage(e2); } return vptslog; } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamParserPESSecondary.java0000600000175000017500000005277110411351456031433 0ustar supermariosupermario/* * @(#)StreamParser * * Copyright (c) 2005-2006 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.io.PushbackInputStream; import java.io.FileOutputStream; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import java.util.Hashtable; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.io.StandardBuffer; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.xinput.StreamInfo; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.parser.StreamConverter; import net.sourceforge.dvb.projectx.parser.StreamDemultiplexer; import net.sourceforge.dvb.projectx.parser.StreamParserBase; import net.sourceforge.dvb.projectx.parser.StreamProcess; /** * main thread */ public class StreamParserPESSecondary extends StreamParserBase { /** * */ public StreamParserPESSecondary() { super(); } /** * secondary PES Parser */ public String parseStream(JobCollection collection, XInputFile aXInputFile, int _pes_streamtype, int action, String vptslog) { String fchild = collection.getOutputName(aXInputFile.getName()); String fparent = collection.getOutputNameParent(fchild); if (collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_appendExtension)) fparent = collection.getOutputDirectory() + collection.getFileSeparator() + fchild; JobProcessing job_processing = collection.getJobProcessing(); /** * split part */ fparent += job_processing.getSplitSize() > 0 ? "(" + job_processing.getSplitPart() + ")" : "" ; String paname = fparent + ".ma1"; List tempfiles = job_processing.getTemporaryFileList(); if (!tempfiles.isEmpty()) { for (int i = 0; i < tempfiles.size(); i += 4 ) { if ( tempfiles.get(i + 1).toString().equals(aXInputFile.toString()) ) { Common.renameTo(tempfiles.get(i).toString(), paname); tempfiles.set(i, paname); Common.setMessage(Resource.getString("parseSecondaryPES.continue") + " " + aXInputFile); String str = tempfiles.get(i + 3).toString(); if (str.equals("tt")) //vtx new StreamProcess(CommonParsing.TELETEXT, collection, tempfiles.get(i).toString(), tempfiles.get(i + 2).toString(), tempfiles.get(i + 3).toString(), vptslog); else if (str.equals("sp")) //subpics new StreamProcess(CommonParsing.SUBPICTURE, collection, tempfiles.get(i).toString(), tempfiles.get(i + 2).toString(), tempfiles.get(i + 3).toString(), vptslog); else if (str.equals("pc")) //lpcm new StreamProcess(CommonParsing.LPCM_AUDIO, collection, tempfiles.get(i).toString(), tempfiles.get(i + 2).toString(), tempfiles.get(i + 3).toString(), vptslog); else //other audio new StreamProcess(CommonParsing.MPEG_AUDIO, collection, tempfiles.get(i).toString(), tempfiles.get(i + 2).toString(), tempfiles.get(i + 3).toString(), vptslog); return vptslog; } } } boolean Message_2 = collection.getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg2); boolean Debug = collection.getSettings().getBooleanProperty(Keys.KEY_DebugLog); boolean SimpleMPG = collection.getSettings().getBooleanProperty(Keys.KEY_simpleMPG); boolean GetEnclosedPackets = collection.getSettings().getBooleanProperty(Keys.KEY_Input_getEnclosedPackets); boolean IgnoreScrambledPackets = collection.getSettings().getBooleanProperty(Keys.KEY_TS_ignoreScrambled); boolean isTeletext = false; boolean missing_startcode = false; boolean scrambling_messaged = false; boolean pes_isMpeg2; boolean pes_alignment; boolean pes_scrambled; boolean containsPts = false; boolean foundObject; int pes_streamtype; int pes_payloadlength; int pes_packetlength; int pes_extensionlength; int pes_headerlength = 9; int pes_packetoffset = 6; int pes_extension2_id; int pesID; int subID; int offset; int returncode = 0; byte[] pes_packet = new byte[0x10006]; byte[] buffered_data; long count = 0; long size; long qexit; job_processing.clearStatusVariables(); int[] clv = job_processing.getStatusVariables(); job_processing.setMinBitrate(CommonParsing.MAX_BITRATE_VALUE); job_processing.setMaxBitrate(0); job_processing.setExportedVideoFrameNumber(0); job_processing.setEndPtsOfGop(-10000); job_processing.setSequenceHeader(true); job_processing.setAllMediaFilesExportLength(0); job_processing.setProjectFileExportLength(0); Hashtable substreams = new Hashtable(); StandardBuffer sb; List demuxList = job_processing.getSecondaryPESDemuxList(); demuxList.clear(); StreamDemultiplexer streamdemultiplexer = null; try { PushbackInputStream in = new PushbackInputStream(aXInputFile.getInputStream(), pes_packet.length); size = aXInputFile.length(); Common.updateProgressBar(Resource.getString("parseSecondaryPES.demux.pes") + " " + aXInputFile.getName(), 0, 0); qexit = count + (0x100000L * Integer.parseInt(collection.getSettings().getProperty(Keys.KEY_ExportPanel_Infoscan_Value))); bigloop: while (true) { loop: while (count < size) { pes_streamtype = _pes_streamtype; // reset to original type Common.updateProgressBar(count, size); //yield(); while (pause()) {} if (CommonParsing.isProcessCancelled() || (CommonParsing.isInfoScan() && count > qexit)) { CommonParsing.setProcessCancelled(false); job_processing.setSplitSize(0); break bigloop; } in.read(pes_packet, 0, pes_packetoffset); pesID = CommonParsing.getPES_IdField(pes_packet, 0); if ((returncode = CommonParsing.validateStartcode(pes_packet, 0)) < 0 || pesID < CommonParsing.SYSTEM_END_CODE) { returncode = returncode < 0 ? -returncode : 4; if (Message_2 && !missing_startcode) Common.setMessage(Resource.getString("parseSecondaryPES.missing.startcode") + " " + count); in.read(pes_packet, pes_packetoffset, pes_packet.length - pes_packetoffset); int i = returncode; for (; i < pes_packet.length - 3; ) { returncode = CommonParsing.validateStartcode(pes_packet, i); if (returncode < 0) { i += -returncode; continue; } else { in.unread(pes_packet, i, pes_packet.length - i); count += i; missing_startcode = true; continue loop; } } in.unread(pes_packet, i, pes_packet.length - i); count += i; missing_startcode = true; continue loop; } if (Message_2 && missing_startcode) Common.setMessage(Resource.getString("parseSecondaryPES.found.startcode") + " " + count); missing_startcode = false; if (pes_streamtype == CommonParsing.MPEG1PS_TYPE || pes_streamtype == CommonParsing.MPEG2PS_TYPE || SimpleMPG) { switch (pesID) { case CommonParsing.SYSTEM_END_CODE: in.unread(pes_packet, 4, 2); Common.setMessage("-> skip system_end_code @ " + count); count += 4; continue loop; case CommonParsing.PACK_START_CODE: if ((0xC0 & pes_packet[4]) == 0) //mpg1 { in.skip(6); count += 12; continue loop; } else if ((0xC0 & pes_packet[4]) == 0x40) //mpg2 { in.read(pes_packet, 6, 8); offset = 7 & pes_packet[13]; count += 14; in.read(pes_packet, 14, offset); if (offset > 0) { for (int i = 0; i < offset; i++) if (pes_packet[14 + i] != -1) { in.unread(pes_packet, 14, offset); Common.setMessage("!> wrong pack header stuffing @ " + count); missing_startcode = true; continue loop; } } count += offset; continue loop; } else { in.unread(pes_packet, 4, 2); count += 4; continue loop; } case CommonParsing.SYSTEM_START_CODE: case CommonParsing.PROGRAM_STREAM_MAP_CODE: case CommonParsing.PADDING_STREAM_CODE: case CommonParsing.PRIVATE_STREAM_2_CODE: case CommonParsing.ECM_STREAM_CODE: case CommonParsing.EMM_STREAM_CODE: case CommonParsing.DSM_CC_STREAM_CODE: case 0xF3: case 0xF4: case 0xF5: case 0xF6: case 0xF7: case 0xF8: case 0xF9: case 0xFA: case 0xFB: case 0xFC: case 0xFD: case 0xFE: case 0xFF: pes_payloadlength = CommonParsing.getPES_LengthField(pes_packet, 0); in.skip(pes_payloadlength); count += (pes_packetoffset + pes_payloadlength); continue loop; } } if ( (0xF0 & pesID) != 0xE0 && (0xE0 & pesID) != 0xC0 && pesID != CommonParsing.PRIVATE_STREAM_1_CODE) { in.unread(pes_packet, 3, pes_packetoffset - 3); count += 3; continue loop; } pes_payloadlength = CommonParsing.getPES_LengthField(pes_packet, 0); if (pes_payloadlength == 0) { Common.setMessage(Resource.getString("parseSecondaryPES.packet.length") + " " + count); count += pes_packetoffset; continue loop; } in.read(pes_packet, pes_packetoffset, pes_payloadlength + 4); pes_packetlength = pes_packetoffset + pes_payloadlength; if (GetEnclosedPackets && CommonParsing.validateStartcode(pes_packet, pes_packetlength) < 0) { if (count + pes_packetlength < size) { if (Message_2 && !missing_startcode) Common.setMessage(Resource.getString("parseSecondaryPES.miss.next.startcode", String.valueOf(count + pes_packetlength), String.valueOf(count), Integer.toHexString(pesID).toUpperCase())); missing_startcode = true; in.unread(pes_packet, pes_packetoffset, pes_payloadlength + 4); count += pes_packetoffset; continue loop; } } else in.unread(pes_packet, pes_packetlength, 4); clv[5]++; if (Debug) System.out.print("\r"+Resource.getString("parseSecondaryPES.packs", String.valueOf(clv[5]), String.valueOf((count * 100 / size)), String.valueOf(count))); pes_extensionlength = CommonParsing.getPES_ExtensionLengthField(pes_packet, 0); pes_isMpeg2 = (0xC0 & pes_packet[6]) == 0x80; pes_alignment = pes_isMpeg2 && (4 & pes_packet[6]) != 0; pes_scrambled = pes_isMpeg2 && (0x30 & pes_packet[6]) != 0; count += pes_packetlength; /** * check scrambling */ if (IgnoreScrambledPackets) { // cannot work with scrambled data if (pes_scrambled) { if (!scrambling_messaged) { scrambling_messaged = true; Common.setMessage(Resource.getString("parseTS.scrambled", Integer.toHexString(pesID).toUpperCase(), String.valueOf(clv[5]), String.valueOf(count - pes_packetlength))); } continue loop; } else if (scrambling_messaged) { Common.setMessage(Resource.getString("parseTS.clear", Integer.toHexString(pesID).toUpperCase(), String.valueOf(clv[5]), String.valueOf(count - pes_packetlength))); scrambling_messaged = false; } } /** * vdr_dvbsub determination */ pes_extension2_id = CommonParsing.getExtension2_Id(pes_packet, pes_headerlength, pes_payloadlength, pesID, pes_isMpeg2, count - pes_packetlength); isTeletext = false; subID = 0; if (pesID == CommonParsing.PRIVATE_STREAM_1_CODE && pes_payloadlength > 2) { offset = pes_headerlength + pes_extensionlength; if (offset < pes_packetlength) { subID = 0xFF & pes_packet[offset]; isTeletext = pes_extensionlength == 0x24 && subID>>>4 == 1; //subpic in vdr_pes if (pes_alignment && !isTeletext && (subID>>>4 == 2 || subID>>>4 == 3)) pes_streamtype = CommonParsing.MPEG2PS_TYPE; //will be resetted before next packet if (pes_streamtype != CommonParsing.MPEG1PS_TYPE && pes_streamtype != CommonParsing.MPEG2PS_TYPE && !isTeletext) subID = 0; //disables LPCM too } else if (pes_streamtype != CommonParsing.MPEG1PS_TYPE) //? { pes_extensionlength = pes_payloadlength - 3; pes_packet[8] = (byte)(pes_extensionlength); } /** * packet buffering esp. of subpics from vdr or other pes */ if (pes_extension2_id != -1) { String str = String.valueOf(pes_extension2_id); offset = pes_headerlength + pes_extensionlength; if ( !substreams.containsKey(str)) substreams.put(str, new StandardBuffer()); sb = (StandardBuffer) substreams.get(str); // buffer raw packet data if (!pes_alignment) { sb.write(pes_packet, offset, pes_packetlength - offset); continue loop; } // start packet, buffer this and get last completed packet else { buffered_data = sb.getData(); sb.reset(); sb.write(pes_packet, 0, pes_packetlength); if (buffered_data == null || buffered_data.length < 10) continue loop; pes_packetlength = buffered_data.length; if (pes_packetlength > 0x10005) { Common.setMessage("!> sub packet too long: 0x" + Integer.toHexString(pesID).toUpperCase() + " /ext2_id " + pes_extension2_id); pes_packetlength = 0x10005; } pes_payloadlength = pes_packetlength - pes_packetoffset; System.arraycopy(buffered_data, 0, pes_packet, 0, pes_packetlength); CommonParsing.setPES_LengthField(pes_packet, 0, pes_payloadlength); buffered_data = null; } } } foundObject = false; /** * find ID object */ for (int i = 0; i < demuxList.size(); i++) { streamdemultiplexer = (StreamDemultiplexer) demuxList.get(i); foundObject = pesID == streamdemultiplexer.getID() && subID == streamdemultiplexer.subID() && isTeletext == streamdemultiplexer.isTTX(); if (foundObject) break; } /** * create new ID object */ if (!foundObject) { String IDtype = ""; switch (0xF0 & pesID) { case 0xE0: IDtype = Resource.getString("idtype.mpeg.video.ignored"); streamdemultiplexer = new StreamDemultiplexer(); streamdemultiplexer.setID(pesID); streamdemultiplexer.setsubID(0); streamdemultiplexer.setType(CommonParsing.MPEG_VIDEO); streamdemultiplexer.setStreamType(pes_streamtype); demuxList.add(streamdemultiplexer); break; case 0xC0: case 0xD0: IDtype = Resource.getString("idtype.mpeg.audio"); streamdemultiplexer = new StreamDemultiplexer(); streamdemultiplexer.setID(pesID); streamdemultiplexer.setsubID(0); streamdemultiplexer.setType(CommonParsing.MPEG_AUDIO); streamdemultiplexer.setStreamType(pes_streamtype); demuxList.add(streamdemultiplexer); streamdemultiplexer.init(fparent, MainBufferSize / demuxList.size(), demuxList.size(), CommonParsing.SECONDARY_PES_PARSER); break; } switch (pesID) { case CommonParsing.PRIVATE_STREAM_1_CODE: IDtype = Resource.getString("idtype.private.stream"); IDtype += (isTeletext ? " TTX ": "") + (subID != 0 ? " (SubID 0x" + Integer.toHexString(subID).toUpperCase() + ")" : ""); streamdemultiplexer = new StreamDemultiplexer(); streamdemultiplexer.setID(pesID); streamdemultiplexer.setsubID(subID); switch (subID>>>4) { case 1: streamdemultiplexer.setType(CommonParsing.TELETEXT); break; case 2: case 3: streamdemultiplexer.setType(CommonParsing.SUBPICTURE); break; case 8: streamdemultiplexer.setType(CommonParsing.AC3_AUDIO); break; case 0xA: streamdemultiplexer.setType(CommonParsing.LPCM_AUDIO); } streamdemultiplexer.setTTX(isTeletext); streamdemultiplexer.setStreamType(pes_streamtype); demuxList.add(streamdemultiplexer); streamdemultiplexer.init(fparent, MainBufferSize / demuxList.size(), demuxList.size(), CommonParsing.SECONDARY_PES_PARSER); break; } Common.setMessage(Resource.getString("parseSecondaryPES.found.pesid", Integer.toHexString(pesID).toUpperCase(), IDtype, "" + (count - 6 - pes_payloadlength))); } if (!streamdemultiplexer.StreamEnabled()) continue loop; if (streamdemultiplexer.getType() == CommonParsing.MPEG_VIDEO) continue loop; else streamdemultiplexer.write(job_processing, pes_packet, 0, pes_packetlength, true); } /** * loop not yet used */ break bigloop; } Common.setMessage(Resource.getString("parseSecondaryPES.packs", String.valueOf(clv[5]), String.valueOf(count * 100 / size), String.valueOf(count))); in.close(); int[] stream_number = new int[10]; for (int i = 0, es_streamtype; i < demuxList.size(); i++) { streamdemultiplexer = (StreamDemultiplexer) demuxList.get(i); es_streamtype = streamdemultiplexer.getType(); if (es_streamtype == CommonParsing.MPEG_VIDEO) continue; String[] values = streamdemultiplexer.close(job_processing, vptslog); if (values[0].equals("")) { Common.setMessage(Resource.getString("parseSecondaryPES.msg.noexport") + Integer.toHexString(streamdemultiplexer.getID()).toUpperCase() + ")"); continue; } String newfile = values[3] + (stream_number[es_streamtype] > 0 ? ("[" + stream_number[es_streamtype] + "]") : "") + "." + values[2]; Common.renameTo(values[0], newfile); values[0] = newfile; values[3] = vptslog; switch (es_streamtype) { case CommonParsing.AC3_AUDIO: case CommonParsing.DTS_AUDIO: if ( streamdemultiplexer.subID() != 0 && (0xF0 & streamdemultiplexer.subID()) != 0x80 ) break; Common.setMessage(""); Common.setMessage(Resource.getString("parseSecondaryPES.ac3.audio") + ((streamdemultiplexer.subID() != 0) ? ("(SubID 0x" + Integer.toHexString(streamdemultiplexer.subID()).toUpperCase()+")") : "")); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; case CommonParsing.TELETEXT: Common.setMessage(""); Common.setMessage(Resource.getString("parseSecondaryPES.teletext") + " (SubID 0x" + Integer.toHexString(streamdemultiplexer.subID()).toUpperCase() + ")"); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; case CommonParsing.MPEG_AUDIO: Common.setMessage(""); Common.setMessage(Resource.getString("parseSecondaryPES.mpeg.audio") + " (0x" + Integer.toHexString(streamdemultiplexer.getID()).toUpperCase() + ")"); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; case CommonParsing.LPCM_AUDIO: Common.setMessage(""); Common.setMessage(Resource.getString("parseSecondaryPES.lpcm.audio") + " (SubID 0x" + Integer.toHexString(streamdemultiplexer.subID()).toUpperCase() + ")"); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; case CommonParsing.SUBPICTURE: Common.setMessage(""); Common.setMessage(Resource.getString("parseSecondaryPES.subpic") + " (SubID 0x" + Integer.toHexString(streamdemultiplexer.subID()).toUpperCase() + ")"); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; } stream_number[es_streamtype]++; // save infos for output segmentation tempfiles.add(values[0]); tempfiles.add(aXInputFile); tempfiles.add(values[1]); tempfiles.add(values[2]); if (job_processing.getSplitSize() == 0) { new File(newfile).delete(); new File(values[1]).delete(); } } } catch (IOException e2) { Common.setExceptionMessage(e2); } return vptslog; } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamParserPVA.java0000600000175000017500000010246710365230446027563 0ustar supermariosupermario/* * @(#)StreamParser * * Copyright (c) 2005-2006 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.io.PushbackInputStream; import java.util.Arrays; import java.util.List; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.io.RawFile; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.parser.StreamConverter; import net.sourceforge.dvb.projectx.parser.StreamDemultiplexer; import net.sourceforge.dvb.projectx.parser.StreamParserBase; import net.sourceforge.dvb.projectx.parser.StreamProcess; /** * main thread */ public class StreamParserPVA extends StreamParserBase { /** * */ public StreamParserPVA() { super(); } /** * read bytes for overlap pva check */ private byte[] overlapPVA(JobCollection collection, byte[] overlapnext) { JobProcessing job_processing = collection.getJobProcessing(); if (job_processing.getFileNumber() < collection.getPrimaryInputFileSegments() - 1) { try { ((XInputFile) collection.getInputFile(job_processing.getFileNumber() + 1)).randomAccessSingleRead(overlapnext, 0); } catch (IOException e) { Common.setExceptionMessage(e); } } return overlapnext; } /** * PVA/PSV/PSA Parser */ public String parseStream(JobCollection collection, XInputFile aPvaXInputFile, int pes_streamtype, int action, String vptslog) { String fchild = collection.getOutputName(aPvaXInputFile.getName()); String fparent = collection.getOutputNameParent(fchild); JobProcessing job_processing = collection.getJobProcessing(); /** * split part */ fparent += job_processing.getSplitSize() > 0 ? "(" + job_processing.getSplitPart() + ")" : "" ; boolean Message_1 = collection.getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg1); boolean Message_2 = collection.getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg2); boolean ConformAudioCheck = collection.getSettings().getBooleanProperty(Keys.KEY_PVA_Audio); boolean Debug = collection.getSettings().getBooleanProperty(Keys.KEY_DebugLog); boolean OverlapCheck = collection.getSettings().getBooleanProperty(Keys.KEY_PVA_FileOverlap); boolean Concatenate = collection.getSettings().getBooleanProperty(Keys.KEY_Input_concatenateForeignRecords); boolean CreateD2vIndex = collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createD2vIndex); boolean SplitProjectFile = collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_splitProjectFile); boolean Overlap = collection.getSettings().getBooleanProperty(Keys.KEY_ExportPanel_Export_Overlap); boolean containsPts = false; boolean ende = false; boolean missing_syncword = false; boolean usePidfilter = false; boolean isTeletext; boolean foundObject; int pva_buffersize = 0x10006; byte[] pva_packet = new byte[pva_buffersize]; // packets usually up to 6kB byte[] overlapnext = new byte[0x100]; byte[] new_pes_packet = new byte[pva_buffersize]; byte[] new_pes_packetheader = { 0, 0, 1, (byte)0xE0, 0, 0, (byte)0x80, 0, 0 }; byte[] new_pes_packetheader_and_pts = { 0, 0, 1, (byte)0xE0, 0, 0, (byte)0x80, (byte)0x80, 5, 0, 0, 0, 0, 0 }; int Infoscan_Value = Integer.parseInt(collection.getSettings().getProperty(Keys.KEY_ExportPanel_Infoscan_Value)); int CutMode = collection.getSettings().getIntProperty(Keys.KEY_CutMode); int pva_pid; int ptsflag; int pva_packetoffset; int pva_payloadlength; int pva_headerlength = 8; int pva_ptslength = 4; int pva_counter; int pre_bytes; int post_bytes; int[] newID = { 0x80, 0x90, 0xC0, 0xE0, 0xA0, 0x20 }; job_processing.clearStatusVariables(); int[] clv = job_processing.getStatusVariables(); long pts = 0; long lastpts = 0; long ptsoffset = 0; long packet = 0; long count = 0; long size = 0; long base; long startPoint = 0; long starts[] = new long[collection.getPrimaryInputFileSegments()]; long Overlap_Value = 1048576L * (collection.getSettings().getIntProperty(Keys.KEY_ExportPanel_Overlap_Value) + 1); long qexit; String[] streamtypes = { Resource.getString("parsePVA.streamtype.ac3"), Resource.getString("parsePVA.streamtype.ttx"), Resource.getString("parsePVA.streamtype.mpeg.audio"), Resource.getString("parsePVA.streamtype.mpeg.video") }; RawFile rawfile = null; StreamBuffer streambuffer = null; StreamDemultiplexer streamdemultiplexer = null; StreamConverter streamconverter = new StreamConverter(); List demuxList = job_processing.getPVADemuxList(); List PVAPidlist = job_processing.getPVAPidList(); /** * re-read old streams, for next split part */ if (job_processing.getSplitPart() == 0) { PVAPidlist.clear(); demuxList.clear(); } else { for (int i = 0; i < PVAPidlist.size(); i++) { streambuffer = (StreamBuffer) PVAPidlist.get(i); streambuffer.reset(); streambuffer.setStarted(true); } for (int i = 0; i < demuxList.size(); i++) { streamdemultiplexer = (StreamDemultiplexer) demuxList.get(i); if (streamdemultiplexer.getnewID() != 0) newID[streamdemultiplexer.getType()]++; if (streamdemultiplexer.getNum() == -1) continue; if (streamdemultiplexer.getType() == CommonParsing.MPEG_VIDEO) streamdemultiplexer.initVideo2(fparent); else streamdemultiplexer.init2(fparent); } } /** * init conversions */ switch (action) { case CommonParsing.ACTION_TO_VDR: streamconverter.init(fparent + ".vdr", MainBufferSize, action, job_processing.getSplitPart()); break; case CommonParsing.ACTION_TO_M2P: streamconverter.init(fparent + ".m2p", MainBufferSize, action, job_processing.getSplitPart()); break; case CommonParsing.ACTION_TO_PVA: streamconverter.init(fparent + ".new.pva", MainBufferSize, action, job_processing.getSplitPart()); break; case CommonParsing.ACTION_TO_TS: streamconverter.init(fparent + ".ts", MainBufferSize, action, job_processing.getSplitPart()); break; case CommonParsing.ACTION_FILTER: streamconverter.init(fparent + "[filtered].pva", MainBufferSize, action, job_processing.getSplitPart()); } /** * d2v project */ if (CreateD2vIndex || SplitProjectFile) job_processing.getProjectFileD2V().Init(fparent); job_processing.setMinBitrate(CommonParsing.MAX_BITRATE_VALUE); job_processing.setMaxBitrate(0); job_processing.setExportedVideoFrameNumber(0); job_processing.setEndPtsOfGop(-10000); job_processing.setSequenceHeader(true); job_processing.setAllMediaFilesExportLength(0); job_processing.setProjectFileExportLength(0); job_processing.setCutByteposition(0); /** * pid inclusion */ Object[] predefined_Pids = collection.getPIDs(); int[] include = new int[predefined_Pids.length]; for (int i = 0; i < include.length; i++) include[i] = 0xFF & Integer.parseInt(predefined_Pids[i].toString().substring(2), 16); if (include.length > 0) { Arrays.sort(include); String str = " "; for (int i = 0; i < include.length; i++) str += "0x" + Integer.toHexString(include[i]).toUpperCase() + " "; Common.setMessage(Resource.getString("parsePVA.special.pids") + ": {" + str + "}"); usePidfilter = true; } try { /** * determine start & end byte pos. of each file segment */ for (int i = 0; i < starts.length; i++) { aPvaXInputFile = (XInputFile) collection.getInputFile(i); starts[i] = size; size += aPvaXInputFile.length(); } aPvaXInputFile = (XInputFile) collection.getInputFile(job_processing.getFileNumber()); /** * set start & end byte pos. of first file segment */ count = starts[job_processing.getFileNumber()]; size = count + aPvaXInputFile.length(); if (CommonParsing.getPvaPidExtraction()) rawfile = new RawFile(fparent, CommonParsing.getPvaPidToExtract(), MainBufferSize); /** * split skipping first, for next split part */ if (job_processing.getSplitSize() > 0) { startPoint = job_processing.getLastHeaderBytePosition(); startPoint -= !Overlap ? 0 : Overlap_Value; job_processing.setLastGopTimecode(0); job_processing.setLastGopPts(0); job_processing.setLastSimplifiedPts(0); } List CutpointList = collection.getCutpointList(); List ChapterpointList = collection.getChapterpointList(); /** * jump near to first cut-in point to collect more audio */ if (CutMode == CommonParsing.CUTMODE_BYTE && CutpointList.size() > 0 && CommonParsing.getCutCounter() == 0) startPoint = Long.parseLong(CutpointList.get(CommonParsing.getCutCounter()).toString()) - ((action == CommonParsing.ACTION_DEMUX) ? 2048000: 0); if (startPoint < 0) startPoint = count; else if (startPoint < count) { for (int i = starts.length; i > 0; i--) if (starts[i - 1] > startPoint) job_processing.countFileNumber(-1); } else if (startPoint > count) { for (int i = job_processing.getFileNumber() + 1; i < starts.length; i++) { if (starts[i] > startPoint) break; else job_processing.countFileNumber(+1); } } aPvaXInputFile = (XInputFile) collection.getInputFile(job_processing.getFileNumber()); count = starts[job_processing.getFileNumber()]; if (job_processing.getFileNumber() > 0) Common.setMessage(Resource.getString("parsePVA.continue") + " " + aPvaXInputFile); base = count; size = count + aPvaXInputFile.length(); PushbackInputStream in = new PushbackInputStream(aPvaXInputFile.getInputStream(startPoint - base), pva_buffersize); count += (startPoint - base); overlapPVA(collection, overlapnext); Common.updateProgressBar((action == CommonParsing.ACTION_DEMUX ? Resource.getString("parsePVA.demuxing") : Resource.getString("parsePVA.converting")) + " " + Resource.getString("parsePVA.pvafile") + " " + aPvaXInputFile.getName(), (count - base), (size - base)); qexit = count + (0x100000L * Infoscan_Value); bigloop: while (true) { loop: while (count < size) { while (pause()) {} if (CommonParsing.isProcessCancelled() || (CommonParsing.isInfoScan() && count > qexit)) { CommonParsing.setProcessCancelled(false); job_processing.setSplitSize(0); break bigloop; } /** * cut end reached */ if (job_processing.getCutComparePoint() + 20 < job_processing.getSourceVideoFrameNumber()) { ende = true; break bigloop; } /** * cut end reached */ if (CutMode == CommonParsing.CUTMODE_BYTE && CutpointList.size() > 0) { if (CommonParsing.getCutCounter() == CutpointList.size() && (CommonParsing.getCutCounter() & 1) == 0) { if (count > Long.parseLong(CutpointList.get(CommonParsing.getCutCounter() - 1).toString()) + 2048000) { ende = true; break bigloop; } } } in.read(pva_packet, 0, pva_headerlength); /** * check 0x4156__55 is PVA (ascii AV) */ if (pva_packet[0] != 0x41 || pva_packet[1] != 0x56 || pva_packet[4] != 0x55) { if (Message_2 && !missing_syncword) Common.setMessage(Resource.getString("parsePVA.missing.sync") + " " + count); // fill complete buffer... in.read(pva_packet, pva_headerlength, pva_buffersize - pva_headerlength); // ... and search next startcode for (int i = pva_headerlength; i < pva_buffersize - 4; i++) { if (pva_packet[i] == 0x41 && pva_packet[i + 1] == 0x56 && pva_packet[i + 4] == 0x55) { in.unread(pva_packet, i, pva_buffersize - i); count += i; missing_syncword = true; Common.updateProgressBar((count - base), (size - base)); continue loop; } } count += pva_buffersize; missing_syncword = true; continue loop; } if (Message_2 && missing_syncword) Common.setMessage(Resource.getString("parsePVA.found.sync") + " " + count); missing_syncword = false; /** * overlapcheck */ if (OverlapCheck && job_processing.getFileNumber() < collection.getPrimaryInputFileSegments() - 1) { in.read(pva_packet, pva_headerlength, overlapnext.length - pva_headerlength); for (int i = 255; i >= 0; i--) { if (pva_packet[i] != overlapnext[i]) break; if (i == 0) { Common.setMessage(Resource.getString("parsePVA.file.overlap") + " " + count); break loop; } } in.unread(pva_packet, pva_headerlength, overlapnext.length - pva_headerlength); } /** * mark for split */ job_processing.setLastHeaderBytePosition(count); job_processing.setCutByteposition(count); packet++; pva_pid = 0xFF & pva_packet[2]; pva_counter = 0xFF & pva_packet[3]; ptsflag = 0xFF & pva_packet[5]; containsPts = (0x10 & ptsflag) != 0; pre_bytes = 3 & ptsflag>>>2; post_bytes = 3 & ptsflag; pva_payloadlength = (0xFF & pva_packet[6])<<8 | (0xFF & pva_packet[7]); pva_packetoffset = pva_headerlength; Common.updateProgressBar((count - base), (size - base)); //yield(); clv[5]++; if (Debug) System.out.println(Resource.getString("parsePVA.packs") + clv[5] + " /pid " + pva_pid + " @ " + ((count * 100 / size)) + "% " + count); count += pva_headerlength; /** * pid inclusion */ if (usePidfilter && Arrays.binarySearch(include, pva_pid) < 0) { in.skip(pva_payloadlength); count += pva_payloadlength; continue loop; } /** * read pts of video pid */ if (pva_pid == 1 && containsPts) { in.read(pva_packet, pva_headerlength, pva_ptslength); pts = CommonParsing.readPTS(pva_packet, pva_headerlength, pva_ptslength, !CommonParsing.BYTEREORDERING, true); job_processing.setPvaVideoPts(pts); count += pva_ptslength; pva_packetoffset += pva_ptslength; pva_payloadlength -= pva_ptslength; } else job_processing.setPvaVideoPts(-1); /** * re-formatted PES data extraction */ if (CommonParsing.getPvaPidExtraction()) { if (pva_pid != CommonParsing.getPvaPidToExtract()) in.skip(pva_payloadlength); else { if (pva_pid == 1) { if (containsPts) { CommonParsing.setPES_LengthField(new_pes_packetheader_and_pts, 0, 8 + pva_payloadlength); CommonParsing.setPES_PTSField(new_pes_packetheader_and_pts, 0, pts); rawfile.write(new_pes_packetheader_and_pts); } else { CommonParsing.setPES_LengthField(new_pes_packetheader, 0, 3 + pva_payloadlength); rawfile.write(new_pes_packetheader); } } in.read(pva_packet, pva_packetoffset, pva_payloadlength); rawfile.write(pva_packet, pva_packetoffset, pva_payloadlength); job_processing.countMediaFilesExportLength(pva_payloadlength); } count += pva_payloadlength; continue loop; } in.read(pva_packet, pva_packetoffset, pva_payloadlength); count += pva_payloadlength; /** * raw pid filter extraction */ if (action == CommonParsing.ACTION_FILTER) { streamconverter.write(job_processing, pva_packet, 0, pva_packetoffset + pva_payloadlength, null, job_processing.getCutByteposition(), CommonParsing.isInfoScan(), CutpointList); continue loop; } foundObject = false; for (int i = 0; i < PVAPidlist.size(); i++) { streambuffer = (StreamBuffer)PVAPidlist.get(i); foundObject = pva_pid == streambuffer.getPID(); if (foundObject) break; } /** * create new PID object */ if (!foundObject) { streambuffer = new StreamBuffer(); streambuffer.setPID(pva_pid); Common.setMessage(Resource.getString("parsePVA.found.id") + Integer.toHexString(pva_pid).toUpperCase() + " @ " + job_processing.getCutByteposition()); Common.getGuiInterface().addPidToExtract(Integer.toHexString(pva_pid)); PVAPidlist.add(streambuffer); } /** * out of sequence? */ if (Message_1) { if (streambuffer.getCounter() != -1) { if (pva_counter != streambuffer.getCounter()) { Common.setMessage(Resource.getString("parsePVA.outof.sequence", Integer.toHexString(pva_pid).toUpperCase(), "" + packet, "" + (count-8-pva_payloadlength), "" + pva_counter, "" + streambuffer.getCounter()) + " (~" + Common.formatTime_1( (long)((CommonParsing.getVideoFramerate() / 90.0f) * job_processing.getExportedVideoFrameNumber())) + ")"); streambuffer.setCounter(pva_counter); } streambuffer.countPVA(); } else { streambuffer.setCounter(pva_counter); streambuffer.countPVA(); } } if (pva_pid != 1 && !containsPts && !ConformAudioCheck && pva_payloadlength > post_bytes + 3) { int p = pva_packetoffset + post_bytes; if (pva_packet[p] == 0 && pva_packet[p + 1] == 0 && pva_packet[p + 2] == 1 && (pva_packet[p + 3] == (byte)CommonParsing.PRIVATE_STREAM_1_CODE || (0xE0 & pva_packet[p + 3]) == 0xC0)) containsPts = true; } if (!containsPts) post_bytes = 0; if (streambuffer.isStarted()) streamdemultiplexer = (StreamDemultiplexer)demuxList.get(streambuffer.getID()); else { // create new ID object String IDtype = ""; switch (pva_pid) { case 1: IDtype=Resource.getString("idtype.video"); streamdemultiplexer = new StreamDemultiplexer(ptsoffset); streambuffer.setStarted(true); streamdemultiplexer.setID(0xE0); streamdemultiplexer.setType(CommonParsing.MPEG_VIDEO); streamdemultiplexer.setnewID(newID[CommonParsing.MPEG_VIDEO]++); streamdemultiplexer.setPID(pva_pid); streamdemultiplexer.setsubID(0); streamdemultiplexer.setStreamType(pes_streamtype); streambuffer.setID(demuxList.size()); demuxList.add(streamdemultiplexer); if (action == CommonParsing.ACTION_DEMUX) streamdemultiplexer.initVideo(fparent, MainBufferSize, demuxList.size(), CommonParsing.PVA_PARSER); else IDtype += " " + Resource.getString("idtype.mapped.to.e0") + streamtypes[3]; break; case 2: IDtype=Resource.getString("idtype.main.audio"); //do not break default: IDtype=Resource.getString("idtype.additional"); if (!containsPts) continue loop; int streamID = 0xFF & pva_packet[pva_packetoffset + post_bytes + 3]; if ((0xE0 & streamID) != 0xC0 && streamID != CommonParsing.PRIVATE_STREAM_1_CODE) { streambuffer.setneeded(false); break; } streamdemultiplexer = new StreamDemultiplexer(ptsoffset); streambuffer.setStarted(true); streamdemultiplexer.setPID(pva_pid); streamdemultiplexer.setType(streamID != CommonParsing.PRIVATE_STREAM_1_CODE ? CommonParsing.MPEG_AUDIO : CommonParsing.AC3_AUDIO); // MPA? streamdemultiplexer.setID(streamID); streamdemultiplexer.setsubID(0); isTeletext = (0xFF & pva_packet[pva_packetoffset + post_bytes + 8]) == 0x24; streamdemultiplexer.setnewID((streamID == CommonParsing.PRIVATE_STREAM_1_CODE ? (isTeletext ? newID[CommonParsing.TELETEXT]++ : newID[CommonParsing.AC3_AUDIO]++) : newID[CommonParsing.MPEG_AUDIO]++)); streamdemultiplexer.setTTX(isTeletext); streamdemultiplexer.setStreamType(pes_streamtype); streambuffer.setID(demuxList.size()); demuxList.add(streamdemultiplexer); IDtype += " " + Resource.getString("idtype.has.pesid") + Integer.toHexString(streamID).toUpperCase() + " " + streamtypes[streamdemultiplexer.getType()]; if (action == CommonParsing.ACTION_DEMUX) streamdemultiplexer.init(fparent, MainBufferSize / demuxList.size(), demuxList.size(), CommonParsing.PVA_PARSER); else IDtype += " " + Resource.getString("idtype.mapped.to") + Integer.toHexString(streamdemultiplexer.getnewID()).toUpperCase(); break; } Common.setMessage(Resource.getString("parsePVA.id.0x") + Integer.toHexString(pva_pid).toUpperCase() + " " + IDtype); } if (!streamdemultiplexer.StreamEnabled()) continue loop; /** * packet to streamdemultiplexer */ if (action == CommonParsing.ACTION_DEMUX) { if (streamdemultiplexer.getType() == CommonParsing.MPEG_VIDEO) streamdemultiplexer.writeVideo(job_processing, pva_packet, pva_packetoffset, pva_payloadlength, false, CutpointList, ChapterpointList); else { if (containsPts) { if (post_bytes > 0) { streamdemultiplexer.write(job_processing, pva_packet, pva_packetoffset, post_bytes, false); pva_packetoffset += post_bytes; pva_payloadlength -= post_bytes; } CommonParsing.setPES_LengthField(pva_packet, pva_packetoffset, pva_payloadlength - 6); } streamdemultiplexer.write(job_processing, pva_packet, pva_packetoffset, pva_payloadlength, containsPts); } if (streamdemultiplexer.getPTS() > lastpts) lastpts = streamdemultiplexer.getPTS(); /** * split size reached */ if (job_processing.getSplitSize() > 0 && job_processing.getSplitSize() < job_processing.getAllMediaFilesExportLength()) break loop; continue loop; } /** * packet to streamconverter * create new pes_header + pts of video */ if (pva_pid == 1) { if (containsPts) { System.arraycopy(new_pes_packetheader_and_pts, 0, new_pes_packet, 0, new_pes_packetheader_and_pts.length); System.arraycopy(pva_packet, pva_packetoffset, new_pes_packet, new_pes_packetheader_and_pts.length, pva_payloadlength); CommonParsing.setPES_LengthField(new_pes_packet, 0, new_pes_packetheader_and_pts.length - 6 + pva_payloadlength); CommonParsing.setPES_PTSField(new_pes_packet, 0, pts); } else { System.arraycopy(new_pes_packetheader, 0, new_pes_packet, 0, new_pes_packetheader.length); System.arraycopy(pva_packet, pva_packetoffset, new_pes_packet, new_pes_packetheader.length, pva_payloadlength); CommonParsing.setPES_LengthField(new_pes_packet, 0, new_pes_packetheader.length - 6 + pva_payloadlength); } } /** * create new pes_header + pts of others */ else { /** * flag defines existence of an own pes_header, immediately following the pva_header * but is misused by several app's to include up to 3 alignment bytes (to DWORD) <- only allowed for video */ if (containsPts) { if (post_bytes > 0) { System.arraycopy(new_pes_packetheader, 0, new_pes_packet, 0, new_pes_packetheader.length); System.arraycopy(pva_packet, pva_packetoffset, new_pes_packet, new_pes_packetheader.length, post_bytes); CommonParsing.setPES_LengthField(new_pes_packetheader, 0, 3 + post_bytes); CommonParsing.setPES_IdField(new_pes_packetheader, 0, streamdemultiplexer.getID()); streamconverter.write(job_processing, new_pes_packet, streamdemultiplexer, job_processing.getCutByteposition(), CommonParsing.isInfoScan(), CutpointList); pva_packetoffset += post_bytes; pva_payloadlength -= post_bytes; System.arraycopy(pva_packet, pva_packetoffset, new_pes_packet, new_pes_packetheader.length, pva_payloadlength); } else System.arraycopy(pva_packet, pva_packetoffset, new_pes_packet, 0, pva_payloadlength); CommonParsing.setPES_LengthField(new_pes_packet, 0, pva_payloadlength - 6); } else { System.arraycopy(new_pes_packetheader, 0, new_pes_packet, 0, new_pes_packetheader.length); System.arraycopy(pva_packet, pva_packetoffset, new_pes_packet, new_pes_packetheader.length, pva_payloadlength); CommonParsing.setPES_LengthField(new_pes_packet, 0, new_pes_packetheader.length - 6 + pva_payloadlength); } } CommonParsing.setPES_IdField(new_pes_packet, 0, streamdemultiplexer.getID()); streamconverter.write(job_processing, new_pes_packet, streamdemultiplexer, job_processing.getCutByteposition(), CommonParsing.isInfoScan(), CutpointList); job_processing.setLastHeaderBytePosition(count); /** * split size reached **/ if ( job_processing.getSplitSize() > 0 && job_processing.getSplitSize() < job_processing.getAllMediaFilesExportLength()) break loop; } // end while loop if ( job_processing.getSplitSize() > 0 && job_processing.getSplitSize() < job_processing.getAllMediaFilesExportLength()) break bigloop; if (job_processing.getFileNumber() < collection.getPrimaryInputFileSegments() - 1) { in.close(); //System.gc(); if (Concatenate && action == CommonParsing.ACTION_DEMUX) { ptsoffset = nextFilePTS(collection, CommonParsing.PVA_PARSER, 0, lastpts, job_processing.getFileNumber() + 1); if (ptsoffset == -1) ptsoffset = 0; else { for (int i = 0; i < demuxList.size(); i++) { streamdemultiplexer = (StreamDemultiplexer) demuxList.get(i); streamdemultiplexer.PTSOffset(ptsoffset); if (streamdemultiplexer.getPID() == 1) streamdemultiplexer.resetVideo(); } job_processing.setSequenceHeader(true); job_processing.setNewVideoStream(true); } // job_processing.addCellTime(String.valueOf(job_processing.getExportedVideoFrameNumber())); } XInputFile nextXInputFile = (XInputFile) collection.getInputFile(job_processing.countFileNumber(+1)); count = size; in = new PushbackInputStream(nextXInputFile.getInputStream(), pva_buffersize); size += nextXInputFile.length(); base = count; Common.setMessage(Resource.getString("parsePVA.actual.vframes") + " " + job_processing.getExportedVideoFrameNumber()); Common.setMessage(Resource.getString("parsePVA.continue") + " " + nextXInputFile + " (" + Common.formatNumber(nextXInputFile.length()) + " bytes) @ " + base); Common.updateProgressBar((action == CommonParsing.ACTION_DEMUX ? Resource.getString("parsePVA.demuxing") : Resource.getString("parsePVA.converting")) + " " + Resource.getString("parsePVA.pvafile") + " " + nextXInputFile.getName()); overlapPVA(collection, overlapnext); } else break bigloop; } /** * file end reached for split */ if ( (count >= size || ende) && job_processing.getSplitSize() > 0 ) job_processing.setSplitLoopActive(false); in.close(); if (action != CommonParsing.ACTION_DEMUX) streamconverter.close(job_processing, CommonParsing.isInfoScan()); else { for (int i = 0, NumberOfVideostreams = 0; i < demuxList.size(); i++) { streamdemultiplexer = (StreamDemultiplexer)demuxList.get(i); if (streamdemultiplexer.getType() == CommonParsing.MPEG_VIDEO) { /** * accept only first video */ if (NumberOfVideostreams > 0) { Common.setMessage("!> further videostream found (ID 0x" + Integer.toHexString(streamdemultiplexer.getPID()).toUpperCase() + ") -> ignored"); continue; } /** * d2v project */ if (CreateD2vIndex || SplitProjectFile) job_processing.getProjectFileD2V().write(job_processing.getProjectFileExportLength(), job_processing.getExportedVideoFrameNumber()); Common.setMessage(""); Common.setMessage(Resource.getString("video.msg.summary") + " " + job_processing.getExportedVideoFrameNumber() + "/ " + clv[0] + "/ " + clv[1] + "/ " + clv[2] + "/ " + clv[3] + "/ " + clv[4]); vptslog = streamdemultiplexer.closeVideo(job_processing, collection.getOutputDirectory() + collection.getFileSeparator()); NumberOfVideostreams++; } } int[] stream_number = new int[10]; for (int i = 0, es_streamtype; i < demuxList.size(); i++) { streamdemultiplexer = (StreamDemultiplexer)demuxList.get(i); es_streamtype = streamdemultiplexer.getType(); if (es_streamtype == CommonParsing.MPEG_VIDEO) continue; if (streamdemultiplexer.getID() == 0) continue; String[] values = streamdemultiplexer.close(job_processing, vptslog); if (values[0].equals("")) { Common.setMessage(Resource.getString("parsePVA.msg.noexport") + Integer.toHexString(streamdemultiplexer.getPID()).toUpperCase() + " (0x" + Integer.toHexString(streamdemultiplexer.getID()).toUpperCase() + ")"); continue; } String newfile = values[3] + ( stream_number[es_streamtype] > 0 ? ("[" + stream_number[es_streamtype] + "]") : "") + "." + values[2]; Common.renameTo(values[0], newfile); values[0] = newfile; values[3] = vptslog; switch (es_streamtype) { case CommonParsing.AC3_AUDIO: case CommonParsing.DTS_AUDIO: if (streamdemultiplexer.subID() != 0 && (0xF0 & streamdemultiplexer.subID()) != 0x80) break; Common.setMessage(""); Common.setMessage(Resource.getString("parsePVA.ac3.onid") + Integer.toHexString(streamdemultiplexer.getPID()).toUpperCase() + " " + ((streamdemultiplexer.subID() != 0) ? ("(SubID 0x" + Integer.toHexString(streamdemultiplexer.subID()).toUpperCase() + ")") : "")); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; case CommonParsing.TELETEXT: Common.setMessage(""); Common.setMessage(Resource.getString("parsePVA.teletext.onid") + Integer.toHexString(streamdemultiplexer.getPID()).toUpperCase() + " (SubID 0x" + Integer.toHexString(streamdemultiplexer.subID()).toUpperCase() + ")"); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; case CommonParsing.MPEG_AUDIO: Common.setMessage(""); Common.setMessage(Resource.getString("parsePVA.mpeg.audio.onid") + Integer.toHexString(streamdemultiplexer.getPID()).toUpperCase() + " (0x" + Integer.toHexString(streamdemultiplexer.getID()).toUpperCase() + ")"); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; case CommonParsing.LPCM_AUDIO: Common.setMessage(""); Common.setMessage(Resource.getString("parsePVA.lpcm.onid") + Integer.toHexString(streamdemultiplexer.getPID()).toUpperCase() + " (SubID 0x" + Integer.toHexString(streamdemultiplexer.subID()).toUpperCase() + ")"); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; case CommonParsing.SUBPICTURE: Common.setMessage(""); Common.setMessage(Resource.getString("parsePVA.subpicture.onid") + Integer.toHexString(streamdemultiplexer.getPID()).toUpperCase() + " (SubID 0x" + Integer.toHexString(streamdemultiplexer.subID()).toUpperCase() + ")"); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; } stream_number[es_streamtype]++; new File(newfile).delete(); new File(values[1]).delete(); } } if (job_processing.getSplitSize() == 0) { demuxList.clear(); PVAPidlist.clear(); } if (CommonParsing.getPvaPidExtraction()) rawfile.close(); } catch (IOException e2) { Common.setExceptionMessage(e2); } return vptslog; } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamParserTS.java0000600000175000017500000012332410365007644027460 0ustar supermariosupermario/* * @(#)StreamParser * * Copyright (c) 2005-2006 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.io.PushbackInputStream; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.io.RawFile; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.xinput.StreamInfo; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.parser.StreamConverter; import net.sourceforge.dvb.projectx.parser.StreamDemultiplexer; import net.sourceforge.dvb.projectx.parser.StreamParserBase; import net.sourceforge.dvb.projectx.parser.StreamProcess; /** * main thread */ public class StreamParserTS extends StreamParserBase { StreamBuffer streambuffer; StreamDemultiplexer streamdemultiplexer; StreamConverter streamconverter; ArrayList usedPIDs; List demuxList; List TSPidlist; boolean CreateD2vIndex; boolean SplitProjectFile; /** * */ public StreamParserTS() { super(); } /** * ts Parser */ public String parseStream(JobCollection collection, XInputFile xInputFile, int pes_streamtype, int action, String vptslog) { String fchild = collection.getOutputName(xInputFile.getName()); String fparent = collection.getOutputNameParent(fchild); JobProcessing job_processing = collection.getJobProcessing(); /** * split part */ fparent += job_processing.getSplitSize() > 0 ? "(" + job_processing.getSplitPart() + ")" : "" ; vptslog = "-1"; //fix boolean Message_1 = collection.getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg1); boolean Message_2 = collection.getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg2); boolean Debug = collection.getSettings().getBooleanProperty(Keys.KEY_DebugLog); boolean JoinPackets = collection.getSettings().getBooleanProperty(Keys.KEY_TS_joinPackets); boolean HumaxAdaption = collection.getSettings().getBooleanProperty(Keys.KEY_TS_HumaxAdaption); boolean FinepassAdaption = collection.getSettings().getBooleanProperty(Keys.KEY_TS_FinepassAdaption); boolean GetEnclosedPackets = collection.getSettings().getBooleanProperty(Keys.KEY_Input_getEnclosedPackets); boolean IgnoreScrambledPackets = collection.getSettings().getBooleanProperty(Keys.KEY_TS_ignoreScrambled); boolean PcrCounter = collection.getSettings().getBooleanProperty(Keys.KEY_Conversion_PcrCounter); boolean BlindSearch = collection.getSettings().getBooleanProperty(Keys.KEY_TS_blindSearch); CreateD2vIndex = collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createD2vIndex); SplitProjectFile = collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_splitProjectFile); boolean UseAutoPidFilter = collection.getSettings().getBooleanProperty(Keys.KEY_useAutoPidFilter); boolean Overlap = collection.getSettings().getBooleanProperty(Keys.KEY_ExportPanel_Export_Overlap); boolean ts_isIncomplete = false; boolean ts_startunit = false; boolean ts_hasErrors = false; boolean containsPts = false; boolean ende = false; boolean missing_syncword = false; boolean usePidfilter = false; boolean isTeletext; boolean foundObject; int ts_buffersize = 189; int ts_packetlength = 188; byte[] ts_packet = new byte[ts_buffersize]; byte[] pes_packet; byte[] hav_chunk = { 0x5B, 0x48, 0x4F, 0x4A, 0x49, 0x4E, 0x20, 0x41 }; //'[HOJIN A' int Infoscan_Value = Integer.parseInt(collection.getSettings().getProperty(Keys.KEY_ExportPanel_Infoscan_Value)); int CutMode = collection.getSettings().getIntProperty(Keys.KEY_CutMode); int ts_pid; int ts_scrambling = 0; int ts_adaptionfield = 0; int ts_counter = 0; int ts_adaptionfieldlength = 0; int payload_pesID = 0; int payload_psiID = 0; int pes_extensionlength = 0; int pes_payloadlength = 0; int pes_packetlength; int pes_packetoffset = 6; int pes_headerlength = 9; int pes_offset = 0; int pes_subID = 0; int pes_ID; int bytes_read = 0; int[] newID = { 0x80, 0x90, 0xC0, 0xE0, 0xA0, 0x20 }; job_processing.clearStatusVariables(); int[] clv = job_processing.getStatusVariables(); long next_CUT_BYTEPOSITION = 0; long lastpts = 0; long ptsoffset = 0; long packet = 0; long count = 0; long size = 0; long base; long startPoint = 0; long starts[] = new long[collection.getPrimaryInputFileSegments()]; long Overlap_Value = 1048576L * (collection.getSettings().getIntProperty(Keys.KEY_ExportPanel_Overlap_Value) + 1); long qexit; streamconverter = new StreamConverter(); usedPIDs = new ArrayList(); demuxList = job_processing.getTSDemuxList(); TSPidlist = job_processing.getTSPidList(); /** * re-read old streams, for next split part */ if (job_processing.getSplitPart() == 0) { TSPidlist.clear(); demuxList.clear(); } else { for (int i = 0; i < TSPidlist.size(); i++) { streambuffer = (StreamBuffer) TSPidlist.get(i); streambuffer.reset(); streambuffer.setStarted(false); } for (int i = 0; i < demuxList.size(); i++) { streamdemultiplexer = (StreamDemultiplexer) demuxList.get(i); if (streamdemultiplexer.getnewID() != 0) newID[streamdemultiplexer.getType()]++; if (streamdemultiplexer.getNum() == -1) continue; if (streamdemultiplexer.getType() == CommonParsing.MPEG_VIDEO) streamdemultiplexer.initVideo2(fparent); else streamdemultiplexer.init2(fparent); } } /** * first split part, or one file only */ if (job_processing.getSplitPart() == 0) { StreamInfo streamInfo = xInputFile.getStreamInfo(); int[] pids = streamInfo.getPIDs(); if (pids.length > 0) { Common.setMessage(Resource.getString("parseTS.sid") + Integer.toHexString(pids[0]).toUpperCase()); Common.setMessage(Resource.getString("parseTS.pmt.refers", Integer.toHexString(pids[1]).toUpperCase())); Common.setMessage(Resource.getString("ScanInfo.Video")); Common.setMessage(streamInfo.getVideo()); Common.setMessage(Resource.getString("ScanInfo.Audio")); Common.setMessage(streamInfo.getAudio()); Common.setMessage(Resource.getString("ScanInfo.Teletext")); Common.setMessage(streamInfo.getTeletext()); Common.setMessage(Resource.getString("ScanInfo.Subpicture")); Common.setMessage(streamInfo.getSubpicture()); Common.setMessage(""); for (int i = 2; i < pids.length; i++) { TSPidlist.add(streambuffer = new StreamBuffer()); streambuffer.setPID(pids[i]); } } else Common.setMessage(Resource.getString("parseTS.no.pmt")); } /** * init conversions */ switch (action) { case CommonParsing.ACTION_TO_VDR: streamconverter.init(fparent + ".vdr", MainBufferSize, action, job_processing.getSplitPart()); break; case CommonParsing.ACTION_TO_M2P: streamconverter.init(fparent + ".m2p", MainBufferSize, action, job_processing.getSplitPart()); break; case CommonParsing.ACTION_TO_PVA: streamconverter.init(fparent + ".pva", MainBufferSize, action, job_processing.getSplitPart()); break; case CommonParsing.ACTION_TO_TS: streamconverter.init(fparent + ".new.ts", MainBufferSize, action, job_processing.getSplitPart()); break; case CommonParsing.ACTION_FILTER: streamconverter.init(fparent + "[filtered].ts", MainBufferSize, action, job_processing.getSplitPart()); } /** * d2v project */ if (CreateD2vIndex || SplitProjectFile) job_processing.getProjectFileD2V().Init(fparent); job_processing.setMinBitrate(CommonParsing.MAX_BITRATE_VALUE); job_processing.setMaxBitrate(0); job_processing.setExportedVideoFrameNumber(0); job_processing.setEndPtsOfGop(-10000); job_processing.setSequenceHeader(true); job_processing.setAllMediaFilesExportLength(0); job_processing.setProjectFileExportLength(0); job_processing.setCutByteposition(0); /** * pid inclusion */ int[] predefined_Pids = UseAutoPidFilter ? xInputFile.getStreamInfo().getMediaPIDs() : collection.getPIDsAsInteger(); int[] include = new int[predefined_Pids.length]; for (int i = 0; i < include.length; i++) include[i] = 0x1FFF & predefined_Pids[i]; if (include.length > 0) { Arrays.sort(include); String str = " "; for (int i = 0; i < include.length; i++) str += "0x" + Integer.toHexString(include[i]).toUpperCase() + " "; Common.setMessage(Resource.getString("parseTS.special.pids") + ": {" + str + "}"); usePidfilter = true; } try { /** * determine start & end byte pos. of each file segment */ for (int i = 0; i < starts.length; i++) { xInputFile = (XInputFile) collection.getInputFile(i); starts[i] = size; size += xInputFile.length(); } xInputFile = (XInputFile) collection.getInputFile(job_processing.getFileNumber()); /** * set start & end byte pos. of first file segment */ count = starts[job_processing.getFileNumber()]; size = count + xInputFile.length(); /** * split skipping first, for next split part */ if (job_processing.getSplitSize() > 0) { startPoint = job_processing.getLastHeaderBytePosition(); startPoint -= !Overlap ? 0 : Overlap_Value; job_processing.setLastGopTimecode(0); job_processing.setLastGopPts(0); job_processing.setLastSimplifiedPts(0); } List CutpointList = collection.getCutpointList(); List ChapterpointList = collection.getChapterpointList(); /** * jump near to first cut-in point to collect more audio */ if (CutMode == CommonParsing.CUTMODE_BYTE && CutpointList.size() > 0 && CommonParsing.getCutCounter() == 0) startPoint = Long.parseLong(CutpointList.get(CommonParsing.getCutCounter()).toString()) - ((action == CommonParsing.ACTION_DEMUX) ? 2048000: 0); if (startPoint < 0) startPoint = count; else if (startPoint < count) { for (int i = starts.length; i > 0; i--) if (starts[i - 1] > startPoint) job_processing.countFileNumber(-1); } else if (startPoint > count) { for (int i = job_processing.getFileNumber() + 1; i < starts.length; i++) { if (starts[i] > startPoint) break; else job_processing.countFileNumber(+1); } } xInputFile = (XInputFile) collection.getInputFile(job_processing.getFileNumber()); count = starts[job_processing.getFileNumber()]; if (job_processing.getFileNumber() > 0) Common.setMessage(Resource.getString("parseTS.continue") + " " + xInputFile); base = count; size = count + xInputFile.length(); PushbackInputStream in = new PushbackInputStream(xInputFile.getInputStream(startPoint - base), 200); count += (startPoint - base); Common.updateProgressBar((action == CommonParsing.ACTION_DEMUX ? Resource.getString("parseTS.demuxing") : Resource.getString("parseTS.converting")) + " " + Resource.getString("parseTS.dvb.mpeg") + " " + xInputFile.getName(), (count - base), (size - base)); qexit = count + (0x100000L * Infoscan_Value); bigloop: while (true) { loop: while (count < size) { while (pause()) {} if (CommonParsing.isProcessCancelled() || (CommonParsing.isInfoScan() && count > qexit)) { CommonParsing.setProcessCancelled(false); job_processing.setSplitSize(0); break bigloop; } /** * cut end reached */ if (job_processing.getCutComparePoint() + 20 < job_processing.getSourceVideoFrameNumber()) { ende = true; break bigloop; } /** * cut end reached */ if (CutMode == CommonParsing.CUTMODE_BYTE && CutpointList.size() > 0) { if (CommonParsing.getCutCounter() == CutpointList.size() && (CommonParsing.getCutCounter() & 1) == 0) if (count > Long.parseLong(CutpointList.get(CommonParsing.getCutCounter() - 1).toString()) + 2048000) { ende = true; break bigloop; } } /** * regular read */ if (!ts_isIncomplete || !JoinPackets) { bytes_read = in.read(ts_packet, 0, ts_buffersize); /** * EOF is packet aligned */ if (bytes_read == ts_packetlength && size - count == bytes_read) ts_packet[188] = 0x47; else if (bytes_read < ts_buffersize && JoinPackets) { Common.setMessage(Resource.getString("parseTS.incomplete") + " " + count); count += bytes_read; break loop; } } /** * humax .vid workaround, skip special data chunk */ if (HumaxAdaption && ts_packet[0] == 0x7F && ts_packet[1] == 0x41 && ts_packet[2] == 4 && ts_packet[3] == (byte)0xFD) { in.skip(995); count += 1184; continue loop; } /** * finepass .hav workaround, chunks fileposition index (hdd sectors) unused, because a file can be hard-cut anywhere */ if (FinepassAdaption && ts_packet[0] == 0x47 && ts_packet[188] != 0x47) { int i = ts_packetlength; int j; int k = ts_buffersize; int l = hav_chunk.length; while (i > 0) { j = 0; while (i > 0 && ts_packet[i] != hav_chunk[j]) i--; for ( ; i > 0 && j < l && i + j < k; j++) if (ts_packet[i + j] != hav_chunk[j]) break; /** * found at least one byte of chunk */ if (j > 0) { /** ident of chunk doesnt match completely */ if (j < l && i + j < k) { i--; continue; } in.skip(0x200 - (k - i)); in.read(ts_packet, i, k - i); count += 0x200; break; } } } if (HumaxAdaption && ts_packet[0] == 0x47 && ts_packet[188] == 0x7F) {} // do nothing, take the packet else if (ts_packet[0] != 0x47 || (GetEnclosedPackets && ts_packet[188] != 0x47) ) { if (Message_2 && !missing_syncword) Common.setMessage(Resource.getString("parseTS.missing.sync") + " " + count); if (ts_isIncomplete && JoinPackets) { Common.setMessage(Resource.getString("parseTS.comp.failed")); in.unread(ts_packet, 190 - bytes_read, bytes_read - 1); ts_isIncomplete = false; count++; } else { int i = 1; while (i < ts_buffersize) { if (ts_packet[i] == 0x47) break; i++; } // in.unread(ts_packet, 1, ts_packetlength); in.unread(ts_packet, i, ts_buffersize - i); count += i; } missing_syncword = true; continue loop; } else if (ts_isIncomplete && JoinPackets) Common.setMessage(Resource.getString("parseTS.comp.ok")); if (Message_2 && missing_syncword) Common.setMessage(Resource.getString("parseTS.found.sync") + " " + count); missing_syncword = false; in.unread(ts_packet, ts_packetlength, 1); /** * mark for split and cut */ job_processing.setLastHeaderBytePosition(count); next_CUT_BYTEPOSITION = count; if (ts_isIncomplete && JoinPackets) { count += (bytes_read - 1); ts_isIncomplete = false; } else count += ts_packetlength; packet++; ts_hasErrors = (0x80 & ts_packet[1]) != 0; // TS error indicator ts_startunit = (0x40 & ts_packet[1]) != 0; // new PES packet start ts_pid = (0x1F & ts_packet[1])<<8 | (0xFF & ts_packet[2]); // the PID ts_scrambling = (0xC0 & ts_packet[3])>>>6; // packet is scrambled (>0) ts_adaptionfield = (0x30 & ts_packet[3])>>>4; // has adaption field ? ts_counter = (0x0F & ts_packet[3]); // packet counter 0..f ts_adaptionfieldlength = ts_adaptionfield > 1 ? (0xFF & ts_packet[4]) + 1 : 0; // adaption field length Common.updateProgressBar((count - base), (size - base)); //yield(); /** * pid inclusion */ if (usePidfilter && Arrays.binarySearch(include, ts_pid) < 0) continue loop; /** * raw pid filter extraction */ if (action == CommonParsing.ACTION_FILTER) { streamconverter.write(job_processing, ts_packet, 0, ts_packetlength, null, next_CUT_BYTEPOSITION, CommonParsing.isInfoScan(), CutpointList); continue loop; } /** * 00 = reserved value */ if ((ts_adaptionfield & 1) == 0) continue loop; if (ts_adaptionfieldlength > 183 || (ts_adaptionfieldlength > 180 && ts_startunit)) ts_hasErrors = true; if (ts_hasErrors) { if (Message_1) Common.setMessage(Resource.getString("parseTS.bit.error", Integer.toHexString(ts_pid).toUpperCase(), "" + packet, "" + (count-188))); continue loop; } payload_pesID = ts_startunit ? CommonParsing.getIntValue(ts_packet, 4 + ts_adaptionfieldlength, 4, !CommonParsing.BYTEREORDERING) : 0; payload_psiID = ts_startunit ? payload_pesID>>>16 : 0; foundObject = false; /** * find PID object */ for (int i = 0; i < TSPidlist.size(); i++) { streambuffer = (StreamBuffer)TSPidlist.get(i); foundObject = ts_pid == streambuffer.getPID(); if (foundObject) break; } /** * create new PID object */ if (!foundObject) { TSPidlist.add(streambuffer = new StreamBuffer()); streambuffer.setPID(ts_pid); /** * padding packet */ if (ts_pid == 0x1FFF) { Common.setMessage(Resource.getString("parseTS.stuffing")); streambuffer.setneeded(false); } } if (Debug) System.out.println("pk " + packet + " /pid " + Integer.toHexString(ts_pid) + " /pes " + Integer.toHexString(payload_pesID) + " /tn " + streambuffer.isneeded() + " /er " + ts_hasErrors + " /st " + ts_startunit + " /sc " + ts_scrambling + " /ad " + ts_adaptionfield + " /al " + ts_adaptionfieldlength); /** * PID not of interest */ if (!streambuffer.isneeded()) continue loop; if (IgnoreScrambledPackets) { // cannot work with scrambled data if (ts_scrambling > 0) { if (!streambuffer.getScram()) { streambuffer.setScram(true); Common.setMessage(Resource.getString("parseTS.scrambled", Integer.toHexString(ts_pid).toUpperCase(), String.valueOf(packet), String.valueOf(count - 188))); } continue loop; } else { if (streambuffer.getScram()) { streambuffer.setScram(false); Common.setMessage(Resource.getString("parseTS.clear", Integer.toHexString(ts_pid).toUpperCase(), String.valueOf(packet), String.valueOf(count - 188))); } } } /** * out of sequence? * no payload == no counter++ */ if (Message_1 && (PcrCounter || (!PcrCounter && (1 & ts_adaptionfield) != 0))) { if (streambuffer.getCounter() != -1) { if (streambuffer.isStarted() && ts_counter != streambuffer.getCounter()) { Common.setMessage(Resource.getString("parseTS.outof.sequence", Integer.toHexString(ts_pid).toUpperCase(), String.valueOf(packet), String.valueOf(count - 188), String.valueOf(ts_counter), String.valueOf(streambuffer.getCounter())) + " (~" + Common.formatTime_1( (long)((CommonParsing.getVideoFramerate() / 90.0f) * job_processing.getExportedVideoFrameNumber())) + ")"); streambuffer.setCounter(ts_counter); } streambuffer.count(); } else { streambuffer.setCounter(ts_counter); streambuffer.count(); } } /** * buffering of subsequent packets */ if (!ts_startunit) { if (streambuffer.isneeded() && streambuffer.isStarted()) streambuffer.writeData(ts_packet, 4 + ts_adaptionfieldlength, 184 - ts_adaptionfieldlength); if (streambuffer.getDataSize() > 6000000) { Common.setMessage("!> 0x" + Integer.toHexString(streambuffer.getPID()).toUpperCase() + ", buffered packet exceed maximum size, flushed..."); streambuffer.reset(); } } else { isTeletext = false; pes_subID = 0; if (streambuffer.getID() == -1 && payload_pesID == 0x1BD) { pes_extensionlength = 0; pes_offset = 0; try { pes_extensionlength = 0xFF & ts_packet[12 + ts_adaptionfieldlength]; pes_offset = 13 + ts_adaptionfieldlength + pes_extensionlength; isTeletext = (pes_extensionlength == 0x24 && (0xFF & ts_packet[pes_offset])>>>4 == 1); if (!isTeletext) pes_subID = ((0xFF & ts_packet[pes_offset]) == 0x20 && (0xFF & ts_packet[pes_offset + 1]) == 0 && (0xFF & ts_packet[pes_offset + 2]) == 0xF) ? 0x20 : 0; } catch (ArrayIndexOutOfBoundsException e) { Common.setMessage(Resource.getString("parseTS.io.error") + " / " + pes_extensionlength + " / " + pes_offset); Common.setExceptionMessage(e); streambuffer.reset(); streambuffer.setStarted(false); continue loop; } } streambuffer.setStarted(true); /** * create new streamdemultiplexer object */ if (streambuffer.getID() == -1) { streambuffer.setID(payload_pesID); String type = ""; switch (0xFFFFFFF0 & payload_pesID) { case 0x1E0: type = Resource.getString("idtype.mpeg.video"); streambuffer.setDemux(demuxList.size()); streamdemultiplexer = new StreamDemultiplexer(); streamdemultiplexer.setPID(ts_pid); streamdemultiplexer.setID(payload_pesID); streamdemultiplexer.setnewID(newID[CommonParsing.MPEG_VIDEO]++); streamdemultiplexer.setsubID(0); streamdemultiplexer.setType(CommonParsing.MPEG_VIDEO); streamdemultiplexer.setStreamType(pes_streamtype); demuxList.add(streamdemultiplexer); if (action == CommonParsing.ACTION_DEMUX) { if (newID[CommonParsing.MPEG_VIDEO] - 1 == 0xE0) streamdemultiplexer.initVideo(fparent, MainBufferSize / demuxList.size(), demuxList.size(), 2); else { type += Resource.getString("idtype.ignored"); streambuffer.setneeded(false); } } else type += " " + Resource.getString("idtype.mapped.to") + Integer.toHexString(newID[CommonParsing.MPEG_VIDEO] - 1).toUpperCase(); break; case 0x1C0: case 0x1D0: type = Resource.getString("idtype.mpeg.audio"); streambuffer.setDemux(demuxList.size()); streamdemultiplexer = new StreamDemultiplexer(); streamdemultiplexer.setPID(ts_pid); streamdemultiplexer.setID(payload_pesID); streamdemultiplexer.setnewID(newID[CommonParsing.MPEG_AUDIO]++); streamdemultiplexer.setsubID(0); streamdemultiplexer.setType(CommonParsing.MPEG_AUDIO); streamdemultiplexer.setStreamType(pes_streamtype); demuxList.add(streamdemultiplexer); if (action == CommonParsing.ACTION_DEMUX) streamdemultiplexer.init(fparent, MainBufferSize / demuxList.size(), demuxList.size(), 2); else type += " " + Resource.getString("idtype.mapped.to") + Integer.toHexString(newID[CommonParsing.MPEG_AUDIO] - 1).toUpperCase(); break; } switch (payload_pesID) { case 0x1BD: type = Resource.getString("idtype.private.stream"); type += (isTeletext ? " (TTX) ": "") + (pes_subID != 0 ? " (SubID 0x" + Integer.toHexString(pes_subID).toUpperCase() + ")" : ""); streambuffer.setDemux(demuxList.size()); streamdemultiplexer = new StreamDemultiplexer(); streamdemultiplexer.setPID(ts_pid); streamdemultiplexer.setID(payload_pesID); streamdemultiplexer.setsubID(pes_subID); streamdemultiplexer.setTTX(isTeletext); if (isTeletext) { streamdemultiplexer.setnewID(newID[CommonParsing.TELETEXT]++); streamdemultiplexer.setType(CommonParsing.TELETEXT); } else if (pes_subID == 0x20) { streamdemultiplexer.setnewID(newID[CommonParsing.SUBPICTURE]++); streamdemultiplexer.setType(CommonParsing.SUBPICTURE); } else { streamdemultiplexer.setnewID(newID[CommonParsing.AC3_AUDIO]++); streamdemultiplexer.setType(CommonParsing.AC3_AUDIO); } streamdemultiplexer.setStreamType(pes_subID == 0x20 ? CommonParsing.MPEG2PS_TYPE : CommonParsing.PES_AV_TYPE); demuxList.add(streamdemultiplexer); if (action == CommonParsing.ACTION_DEMUX) streamdemultiplexer.init(fparent, MainBufferSize/demuxList.size(), demuxList.size(), 2); if (action != CommonParsing.ACTION_DEMUX && pes_subID != 0) { type += Resource.getString("idtype.ignored"); streambuffer.setneeded(false); } if (action != CommonParsing.ACTION_DEMUX && !isTeletext) type += " " + Resource.getString("idtype.mapped.to") + Integer.toHexString(newID[CommonParsing.AC3_AUDIO] - 1).toUpperCase(); if (action != CommonParsing.ACTION_DEMUX && isTeletext) type += " " + Resource.getString("idtype.mapped.to") + Integer.toHexString(newID[CommonParsing.TELETEXT] - 1).toUpperCase(); break; case 0x1BF: Common.setMessage(Resource.getString("parseTS.priv.stream2.ignored", Integer.toHexString(ts_pid).toUpperCase())); //break; streambuffer.setneeded(false); // skip foll. packs continue loop; } if (type.equals("")) { if (ts_pid == 0 && payload_psiID == 0) type = "(PAT)"; else if (ts_pid == 1 && payload_psiID == 1) type = "(CAT)"; else if (ts_pid == 2 && payload_psiID == 3) type = "(TSDT)"; else if (ts_pid == 0x10 && (payload_psiID == 6 || payload_psiID == 0x40 || payload_psiID == 0x41)) type = "(NIT)"; else if (ts_pid == 0x11 && (payload_psiID == 0x42 || payload_psiID == 0x46)) type = "(SDT)"; else if (ts_pid == 0x11 && payload_psiID == 0x4A) type = "(BAT)"; else if (ts_pid == 0x12 && payload_psiID >= 0x4E && payload_psiID <= 0x6F) type = "(EIT)"; else if (ts_pid == 0x13 && payload_psiID == 0x71) type = "(RST)"; else if (ts_pid == 0x1F && payload_psiID == 0x7F) type = "(SIT)"; else if (ts_pid == 0x1E && payload_psiID == 0x7E) type = "(DIT)"; else if (ts_pid == 0x14 && payload_psiID == 0x70) type = "(TDS)"; else if (ts_pid == 0x14 && payload_psiID == 0x73) type = "(TOT)"; else if (payload_psiID == 0x72 && ts_pid >= 0x10 && ts_pid <= 0x14) type = "(ST)"; else { switch (payload_psiID) { case 2: type = "(PMT)"; break; case 4: type = "(PSI)"; break; case 0x82: type = "(EMM)"; break; case 0x80: case 0x81: case 0x83: case 0x84: type = "(ECM)"; break; case 0x43: case 0x44: case 0x45: case 0x47: case 0x48: case 0x49: case 0x4B: case 0x4C: case 0x4D: case 0xFF: type = "(res.)"; break; default: if ((payload_psiID >= 4 && payload_psiID <= 3F) || (payload_psiID >= 0x74 && payload_psiID <= 0x7D)) { type = "(res.)"; break; } if (payload_psiID >= 0x80 && payload_psiID < 0xFF) { type = "(user def. 0x" + Integer.toHexString(payload_psiID).toUpperCase() + ")"; break; } type += "(payload: "; for (int j = 0; j < 8; j++) { String val = Integer.toHexString((0xFF & ts_packet[4 + ts_adaptionfieldlength + j])).toUpperCase(); type += " " + (val.length() < 2 ? ("0" + val) : val); } type += " ..)"; } } if (ts_scrambling > 0 && !IgnoreScrambledPackets) { type += " (0x" + Long.toHexString(count - 188).toUpperCase() + " #" + packet + ") "; // pos + packno if (!streambuffer.getScram()) Common.setMessage(Resource.getString("parseTS.scrambled.notignored", Integer.toHexString(ts_pid).toUpperCase(), type)); streambuffer.setScram(true); streambuffer.setStarted(false); streambuffer.setID(-1); streambuffer.reset(); continue loop; } type += " (" + (count - 188) + " #" + packet + ") "; // pos + packno Common.setMessage("!> PID 0x" + Integer.toHexString(ts_pid).toUpperCase() + " " + type + Resource.getString("parseTS.ignored")); if (!BlindSearch || type.indexOf("pay") == -1) streambuffer.setneeded(false); else streambuffer.setID(-1); continue loop; } else { type += " (" + (count - 188) + " #" + packet + ") "; // pos + packno Common.setMessage(Resource.getString("parseTS.pid.has.pes", Integer.toHexString(ts_pid).toUpperCase(), Integer.toHexString(0xFF & payload_pesID).toUpperCase(), type)); usedPIDs.add("0x" + Integer.toHexString(ts_pid)); } } if (streambuffer.getDemux() == -1 || !streambuffer.isneeded()) continue loop; streamdemultiplexer = (StreamDemultiplexer) demuxList.get(streambuffer.getDemux()); /** * pes_packet completed */ if (streamdemultiplexer.StreamEnabled()) { pes_packet = streambuffer.getData().toByteArray(); if (pes_packet.length < 6) { if (streamdemultiplexer.getPackCount() != -1) Common.setMessage(Resource.getString("parseTS.lackof.pes", Integer.toHexString(ts_pid).toUpperCase())); } else if (CommonParsing.validateStartcode(pes_packet, 0) < 0) Common.setMessage("!> PID 0x" + Integer.toHexString(ts_pid).toUpperCase() + " - invalid start_code of buffered packet.."); else { pes_payloadlength = CommonParsing.getPES_LengthField(pes_packet, 0); pes_packetlength = pes_packetoffset + pes_payloadlength; pes_ID = streamdemultiplexer.getID(); /** * non video packet size usually < 0xFFFF */ if (streamdemultiplexer.getType() != CommonParsing.MPEG_VIDEO) { if (action == CommonParsing.ACTION_DEMUX) streamdemultiplexer.write(job_processing, pes_packet, 0, pes_packetlength, true); else streamconverter.write(job_processing, pes_packet, streamdemultiplexer, next_CUT_BYTEPOSITION, CommonParsing.isInfoScan(), CutpointList); } /** * special handling, video packet is possibly greater than 0xffff max. size */ else { pes_packetlength = action == CommonParsing.ACTION_DEMUX ? 0xFFFC : 0x1800; for (int i = 0, j, pes_remaininglength = pes_packetlength, flags = (0xF3 & pes_packet[6])<<16; i < pes_packet.length; i += pes_remaininglength) { if (pes_packet.length - i < pes_remaininglength) pes_remaininglength = pes_packet.length - i; if (i == 0) { CommonParsing.setPES_LengthField(pes_packet, i, pes_remaininglength - pes_packetoffset); if (action == CommonParsing.ACTION_DEMUX) { streamdemultiplexer.writeVideo(job_processing, pes_packet, i, pes_remaininglength, true, CutpointList, ChapterpointList); job_processing.setCutByteposition(next_CUT_BYTEPOSITION); } else streamconverter.write(job_processing, pes_packet, i, streamdemultiplexer, next_CUT_BYTEPOSITION, CommonParsing.isInfoScan(), CutpointList); } else { j = i - pes_headerlength; CommonParsing.setValue(pes_packet, j, 4, !CommonParsing.BYTEREORDERING, 0x100 | pes_ID); CommonParsing.setPES_LengthField(pes_packet, j, pes_remaininglength + 3); CommonParsing.setValue(pes_packet, j + pes_packetoffset, 3, !CommonParsing.BYTEREORDERING, flags); if (action == CommonParsing.ACTION_DEMUX) { streamdemultiplexer.writeVideo(job_processing, pes_packet, j, pes_remaininglength + 3, true, CutpointList, ChapterpointList); job_processing.setCutByteposition(next_CUT_BYTEPOSITION); } else streamconverter.write(job_processing, pes_packet, j, streamdemultiplexer, next_CUT_BYTEPOSITION, CommonParsing.isInfoScan(), CutpointList); } } } } } pes_packet = null; streambuffer.reset(); /** * buffer actual packet data */ streambuffer.writeData(ts_packet, 4 + ts_adaptionfieldlength, 184 - ts_adaptionfieldlength); } clv[5]++; if (action != CommonParsing.ACTION_DEMUX) job_processing.setLastHeaderBytePosition(count); /** * split size reached */ if (job_processing.getSplitSize() > 0 && job_processing.getSplitSize() < job_processing.getAllMediaFilesExportLength()) break loop; } /** * split size reached */ if (job_processing.getSplitSize() > 0 && job_processing.getSplitSize() < job_processing.getAllMediaFilesExportLength()) break bigloop; /** * more files */ if (job_processing.getFileNumber() < collection.getPrimaryInputFileSegments() - 1) { in.close(); //System.gc(); XInputFile nextXInputFile = (XInputFile) collection.getInputFile(job_processing.countFileNumber(+1)); count = size; in = new PushbackInputStream(nextXInputFile.getInputStream(), 200); size += nextXInputFile.length(); base = count; // job_processing.addCellTime(String.valueOf(job_processing.getExportedVideoFrameNumber())); Common.setMessage(Resource.getString("parseTS.actual.vframes") + " " + job_processing.getExportedVideoFrameNumber()); Common.setMessage(Resource.getString("parseTS.switch.to") + " " + nextXInputFile + " (" + Common.formatNumber(nextXInputFile.length()) + " bytes) @ " + base); Common.updateProgressBar((action == CommonParsing.ACTION_DEMUX ? Resource.getString("parseTS.demuxing") : Resource.getString("parseTS.converting")) + " " + Resource.getString("parseTS.dvb.mpeg") + " " + nextXInputFile.getName()); if (JoinPackets && bytes_read < 188 && nextXInputFile.length() >= 189 - bytes_read) { ts_isIncomplete = true; bytes_read = in.read(ts_packet, bytes_read, 189 - bytes_read); Common.setMessage(Resource.getString("parseTS.tryto.complete")); } } else break bigloop; } Common.setMessage(Resource.getString("parseTS.packs", String.valueOf(clv[5]), String.valueOf(count * 100 / size), String.valueOf(count))); /** * file end reached for split */ if ( (count >= size || ende) && job_processing.getSplitSize() > 0 ) job_processing.setSplitLoopActive(false); in.close(); if (action != CommonParsing.ACTION_DEMUX) streamconverter.close(job_processing, CommonParsing.isInfoScan()); else vptslog = demultiplexStreams(collection, job_processing, vptslog); loadUsablePids(collection); } catch (IOException e2) { Common.setExceptionMessage(e2); } return vptslog; } /** * */ private String demultiplexStreams(JobCollection collection, JobProcessing job_processing, String vptslog) { for (int i = 0, NumberOfVideostreams = 0; i < demuxList.size(); i++) { streamdemultiplexer = (StreamDemultiplexer) demuxList.get(i); if (streamdemultiplexer.getType() == CommonParsing.MPEG_VIDEO) { /** * accept only first video */ if (NumberOfVideostreams > 0) { Common.setMessage("!> further videostream found (PID 0x" + Integer.toHexString(streamdemultiplexer.getPID()).toUpperCase() + ") -> ignored"); continue; } /** * d2v project */ if (CreateD2vIndex || SplitProjectFile) job_processing.getProjectFileD2V().write(job_processing.getProjectFileExportLength(), job_processing.getExportedVideoFrameNumber()); int[] clv = job_processing.getStatusVariables(); Common.setMessage(""); Common.setMessage(Resource.getString("video.msg.summary") + " " + job_processing.getExportedVideoFrameNumber() + "/ " + clv[0] + "/ " + clv[1] + "/ " + clv[2] + "/ " + clv[3] + "/ " + clv[4]); vptslog = streamdemultiplexer.closeVideo(job_processing, collection.getOutputDirectory() + collection.getFileSeparator()); NumberOfVideostreams++; } } int[] stream_number = new int[10]; for (int i = 0, es_streamtype; i < demuxList.size(); i++) { streamdemultiplexer = (StreamDemultiplexer) demuxList.get(i); es_streamtype = streamdemultiplexer.getType(); if (es_streamtype == CommonParsing.MPEG_VIDEO) continue; String[] values = streamdemultiplexer.close(job_processing, vptslog); if (values[0].equals("")) { Common.setMessage(Resource.getString("parseTS.msg.noexport", Integer.toHexString(0xFF & streamdemultiplexer.getID()).toUpperCase(), Integer.toHexString(streamdemultiplexer.getPID()).toUpperCase())); continue; } String newfile = values[3] + (stream_number[es_streamtype] > 0 ? ("[" + stream_number[es_streamtype] + "]") : "") + "." + values[2]; Common.renameTo(values[0], newfile); values[0] = newfile; values[3] = vptslog; switch (es_streamtype) { case CommonParsing.AC3_AUDIO: case CommonParsing.DTS_AUDIO: Common.setMessage(""); Common.setMessage(Resource.getString("parseTS.ac3.audio") + Integer.toHexString(streamdemultiplexer.getPID()).toUpperCase()); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; case CommonParsing.TELETEXT: Common.setMessage(""); Common.setMessage(Resource.getString("parseTS.teletext.onpid") + Integer.toHexString(streamdemultiplexer.getPID()).toUpperCase() + " (SubID 0x"+Integer.toHexString(streamdemultiplexer.subID()).toUpperCase() + ")"); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; case CommonParsing.MPEG_AUDIO: Common.setMessage(""); Common.setMessage(Resource.getString("parseTS.mpeg.audio", Integer.toHexString(0xFF & streamdemultiplexer.getID()).toUpperCase(), Integer.toHexString(streamdemultiplexer.getPID()).toUpperCase())); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; case CommonParsing.LPCM_AUDIO: Common.setMessage(""); Common.setMessage(Resource.getString("parseTS.lpcm.audio") + Integer.toHexString(streamdemultiplexer.subID()).toUpperCase() + ")"); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; case CommonParsing.SUBPICTURE: Common.setMessage(""); Common.setMessage(Resource.getString("parseTS.subpicture") + Integer.toHexString(streamdemultiplexer.subID()).toUpperCase() + ")"); new StreamProcess(es_streamtype, collection, values[0], values[1], values[2], values[3]); break; } stream_number[es_streamtype]++; new File(newfile).delete(); new File(values[1]).delete(); } return vptslog; } /** * on InfoScan load usable PIDs in pidlist, if list was empty */ private void loadUsablePids(JobCollection collection) { if (CommonParsing.isInfoScan() && collection.getPIDCount() == 0) { collection.addPID(usedPIDs.toArray()); Common.setActiveCollection(Common.getProcessedCollection()); /* update pid list of an opened panel */ Common.getGuiInterface().updateCollectionPanel(Common.getActiveCollection()); } } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamProcess.java0000600000175000017500000000735610354540522027374 0ustar supermariosupermario/* * @(#)StreamParser * * Copyright (c) 2005 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.File; import java.io.InputStream; import java.io.IOException; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.parser.StreamProcessBase; import net.sourceforge.dvb.projectx.parser.StreamProcessAudio; import net.sourceforge.dvb.projectx.parser.StreamProcessLPCMAudio; import net.sourceforge.dvb.projectx.parser.StreamProcessTeletext; import net.sourceforge.dvb.projectx.parser.StreamProcessSubpicture; /** * main thread */ public class StreamProcess extends Object { private StreamProcessBase impl = null; /** * */ public StreamProcess(int es_streamtype, JobCollection collection, String filename, String filename_pts, String filename_type, String videofile_pts) { process(es_streamtype, collection, new XInputFile(new File(filename)), filename_pts, filename_type, videofile_pts, 0); } /** * */ public StreamProcess(int es_streamtype, JobCollection collection, XInputFile aXInputFile, String filename_pts, String filename_type, String videofile_pts, int isElementaryStream) { process(es_streamtype, collection, aXInputFile, filename_pts, filename_type, videofile_pts, isElementaryStream); } /** * */ private void process(int es_streamtype, JobCollection collection, XInputFile aXInputFile, String filename_pts, String filename_type, String videofile_pts, int isElementaryStream) { switch (es_streamtype) { case CommonParsing.AC3_AUDIO: case CommonParsing.DTS_AUDIO: case CommonParsing.MPEG_AUDIO: case CommonParsing.WAV_AUDIO: impl = new StreamProcessAudio(collection, aXInputFile, filename_pts, filename_type, videofile_pts, isElementaryStream); break; case CommonParsing.LPCM_AUDIO: impl = new StreamProcessLPCMAudio(collection, aXInputFile, filename_pts, filename_type, videofile_pts, isElementaryStream); break; case CommonParsing.TELETEXT: impl = new StreamProcessTeletext(collection, aXInputFile, filename_pts, filename_type, videofile_pts, isElementaryStream); break; case CommonParsing.SUBPICTURE: impl = new StreamProcessSubpicture(collection, aXInputFile, filename_pts, filename_type, videofile_pts, isElementaryStream); break; case CommonParsing.UNKNOWN: case CommonParsing.MPEG_VIDEO: default: Common.setMessage("!> unsupported stream to process: " + es_streamtype); break; } } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamProcessAudio.java0000600000175000017500000024333510412363266030360 0ustar supermariosupermario/* * @(#)StreamParser * * Copyright (c) 2005-2006 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.io.PushbackInputStream; import java.io.RandomAccessFile; import java.io.ByteArrayOutputStream; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import java.util.Hashtable; import java.util.Date; import java.util.TimeZone; import java.text.DateFormat; import java.text.SimpleDateFormat; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.io.IDDBufferedOutputStream; import net.sourceforge.dvb.projectx.audio.MpaDecoder; import net.sourceforge.dvb.projectx.audio.MpaConverter; import net.sourceforge.dvb.projectx.audio.AudioFormat; import net.sourceforge.dvb.projectx.audio.RIFFHeader; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.parser.StreamConverter; import net.sourceforge.dvb.projectx.parser.StreamDemultiplexer; import net.sourceforge.dvb.projectx.parser.StreamProcessBase; /** * main thread */ public class StreamProcessAudio extends StreamProcessBase { private MpaConverter MPAConverter = null; private MpaDecoder MPADecoder = null; /** * */ public StreamProcessAudio(JobCollection collection, XInputFile xInputFile, String filename_pts, String filename_type, String videofile_pts, int isElementaryStream) { super(); processStream(collection, xInputFile, filename_pts, filename_type, videofile_pts, isElementaryStream); } /** * start method for adjusting audio at timeline */ private void processStream(JobCollection collection, XInputFile xInputFile, String filename_pts, String filename_type, String videofile_pts, int isElementaryStream) { Common.updateProgressBar(Resource.getString("audio.progress") + " " + xInputFile.getName(), 0, 0); boolean Normalize = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_Normalize); boolean DecodeMpgAudio = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_decodeMpgAudio); if (MPAConverter == null) MPAConverter = new MpaConverter(); if (MPADecoder == null) MPADecoder = new MpaDecoder(); MpaDecoder.RESET = false; MpaDecoder.MAX_VALUE = Normalize ? (Integer.parseInt(collection.getSettings().getProperty(Keys.KEY_AudioPanel_NormalizeValue)) * 32767 / 100) : 32767; MpaDecoder.MULTIPLY = Normalize ? 32767 : 1; MpaDecoder.NORMALIZE = Normalize; MpaDecoder.PRESCAN = MpaDecoder.NORMALIZE; if (MpaDecoder.MAX_VALUE > 32767) { MpaDecoder.MAX_VALUE = 32767; Common.setMessage(Resource.getString("audio.msg.normalize.fixed") + " 100%"); } /** * messages */ int MpaConversionMode = collection.getSettings().getIntProperty(Keys.KEY_AudioPanel_loslessMpaConversionMode); if (MpaConversionMode > 0) Common.setMessage(Resource.getString("audio.convert") + " " + Keys.ITEMS_loslessMpaConversionMode[MpaConversionMode]); if (DecodeMpgAudio) { Common.setMessage(Resource.getString("audio.decode")); Common.setMessage("-> " + Keys.ITEMS_resampleAudioMode[collection.getSettings().getIntProperty(Keys.KEY_AudioPanel_resampleAudioMode)]); if (Normalize) Common.setMessage("-> " + Resource.getString(Keys.KEY_AudioPanel_Normalize[0]) + " " + (100 * MpaDecoder.MAX_VALUE / 32767) + "%"); if (collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_Downmix)) Common.setMessage("-> " + Resource.getString(Keys.KEY_AudioPanel_Downmix[0])); if (collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_fadeInOut)) Common.setMessage("-> " + Resource.getString(Keys.KEY_AudioPanel_fadeInOut[0])); if (collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_changeByteorder)) Common.setMessage("-> " + Resource.getString(Keys.KEY_AudioPanel_changeByteorder[0])); if (collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_addRiffHeader)) Common.setMessage("-> " + Resource.getString(Keys.KEY_AudioPanel_addRiffHeader[0])); if (collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_addAiffHeader)) Common.setMessage("-> " + Resource.getString(Keys.KEY_AudioPanel_addAiffHeader[0])); } /** * restart loop */ while (processAudio(collection, xInputFile, filename_pts, filename_type, videofile_pts, isElementaryStream, MpaConversionMode)) { CommonParsing.setAudioProcessingFlags(CommonParsing.getAudioProcessingFlags() & ~0xCL); Common.setMessage(" "); Common.setMessage(Resource.getString("audio.restart") + " " + ((CommonParsing.getAudioProcessingFlags()>>>18) - 1)); if (DecodeMpgAudio && Normalize) Common.setMessage("-> normalize: multiply factor: " + MpaDecoder.MULTIPLY); if ( (0x10000L & CommonParsing.getAudioProcessingFlags()) != 0) MpaConversionMode = 0; MPAConverter.resetBuffer(); } CommonParsing.setAudioProcessingFlags(CommonParsing.getAudioProcessingFlags() & 3L); } /** * method for audio processing */ private boolean processAudio(JobCollection collection, XInputFile xInputFile, String filename_pts, String filename_type, String videofile_pts, int isElementaryStream, int MpaConversionMode) { String fchild = isElementaryStream == CommonParsing.ES_TYPE ? collection.getOutputName(xInputFile.getName()) : xInputFile.getName(); String fparent = collection.getOutputNameParent(fchild); Common.getGuiInterface().showAVOffset(Resource.getString("MainPanel.AudioVideoOffset")); Common.getGuiInterface().showExportStatus(Resource.getString("MainPanel.nonVideoExportStatus")); JobProcessing job_processing = collection.getJobProcessing(); if (isElementaryStream == CommonParsing.ES_TYPE && job_processing.getSplitSize() > 0) fparent += "(" + job_processing.getSplitPart() + ")"; String newnameL = fparent + ".$mpL$"; String newnameR = fparent + ".$mpR$"; boolean Debug = collection.getSettings().getBooleanProperty(Keys.KEY_DebugLog); boolean CreateM2sIndex = collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createM2sIndex); boolean AddRiffToMpgAudioL3 = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_addRiffToMpgAudioL3); boolean AddRiffToMpgAudio = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_addRiffToMpgAudio); boolean AddRiffToAc3 = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_addRiffToAc3); boolean Message_2 = collection.getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg2); boolean PitchAudio = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_pitchAudio); boolean AllowSpaces = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_allowSpaces); boolean ValidateCRC = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_validateCRC); boolean ReplaceAc3withSilence = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_replaceAc3withSilence); boolean Patch1stAc3Header = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_patch1stAc3Header); boolean FillGapsWithLastFrame = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_fillGapsWithLastFrame); boolean LimitPts = collection.getSettings().getBooleanProperty(Keys.KEY_Audio_limitPts); boolean AddFrames = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_addFrames); boolean DownMix = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_Downmix); boolean ChangeByteorder = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_changeByteorder); boolean AddRiffHeader = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_addRiffHeader); boolean AddAiffHeader = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_addAiffHeader); boolean DecodeMpgAudio = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_decodeMpgAudio); boolean ClearCRC = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_clearCRC); boolean IgnoreErrors = collection.getSettings().getBooleanProperty(Keys.KEY_Audio_ignoreErrors); boolean CreateDDWave = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_createDDWave); boolean FadeInOut = collection.getSettings().getBooleanProperty(Keys.KEY_AudioPanel_fadeInOut); int FadeInOutMillis = collection.getSettings().getIntProperty(Keys.KEY_AudioPanel_fadeInOutMillis); /** * messages */ if (IgnoreErrors) Common.setMessage("-> " + Resource.getString(Keys.KEY_Audio_ignoreErrors[0])); if (AllowSpaces) Common.setMessage("-> " + Resource.getString(Keys.KEY_AudioPanel_allowSpaces[0])); if (LimitPts) Common.setMessage("-> " + Resource.getString(Keys.KEY_Audio_limitPts[0])); if (ValidateCRC) Common.setMessage("-> " + Resource.getString(Keys.KEY_AudioPanel_validateCRC[0])); if (ClearCRC) Common.setMessage("-> " + Resource.getString(Keys.KEY_AudioPanel_clearCRC[0])); if (Patch1stAc3Header) Common.setMessage("-> " + Resource.getString(Keys.KEY_AudioPanel_patch1stAc3Header[0])); if (ReplaceAc3withSilence) Common.setMessage("-> " + Resource.getString(Keys.KEY_AudioPanel_replaceAc3withSilence[0])); if (FillGapsWithLastFrame) Common.setMessage("-> " + Resource.getString(Keys.KEY_AudioPanel_fillGapsWithLastFrame[0])); if (AddFrames) Common.setMessage("-> " + Resource.getString(Keys.KEY_AudioPanel_addFrames[0])); if (CreateDDWave) Common.setMessage("-> " + Resource.getString(Keys.KEY_AudioPanel_createDDWave[0])); int ResampleAudioMode = collection.getSettings().getIntProperty(Keys.KEY_AudioPanel_resampleAudioMode); int PitchValue = Integer.parseInt(collection.getSettings().getProperty(Keys.KEY_AudioPanel_PitchValue)); boolean ptsdata = false; boolean vptsdata = false; boolean insertSilenceLoop = false; boolean awrite = false; boolean preloop = true; boolean newformat = true; boolean missing_syncword = false; boolean is_DTS = false; boolean is_AC3 = false; byte[] header_copy = new byte[4]; byte[][] newframes = new byte[2][1]; byte[][] copyframe= new byte[2][1]; byte[][] silent_Frame=new byte[2][0]; byte[] pushback = new byte[10]; byte[] frame = new byte[1]; byte[] pushmpa = new byte[4]; byte[] push24 = new byte[24]; long[] ptsval = {0}; long[] ptspos = {0}; long[] vptsval = {0}; long[] vtime = {0}; long n = 0; long actframe = 0; long timeline = 0; long audiosize = 0; long ModeChangeCount = 0; int pitch[] = { 1, PitchValue }; int minSync = 0; int[] vw = new int[2]; int cb = 0; int cc = 0; int cd = 0; int ce = 0; int i = 0; int pos = 0; int x = 0; int layertype = -1; int v = 0; int w = 0; int frame_counter = 0; int layer = 0; int samplerate = 0; int lastheader = 0; int padding = 0; int jss = 0; int returncode = 0; int[] layermode2 = { 0,0,0,0 }; final int AC3_AUDIOSTREAM = 0; final int MP3_AUDIOSTREAM = 1; final int MP2_AUDIOSTREAM = 2; final int MP1_AUDIOSTREAM = 3; final int DTS_AUDIOSTREAM = 4; final int WAV_AUDIOSTREAM = 5; final int NO_AUDIOSTREAM = 10; double time_counter = 0.0; int es_streamtype = CommonParsing.MPEG_AUDIO; //"mp" std /** * mp, ac, wa */ if (filename_type.equals("ac")) //means dts, too es_streamtype = CommonParsing.AC3_AUDIO; else if (filename_type.equals("dt")) //later, other handling es_streamtype = CommonParsing.DTS_AUDIO; else if (filename_type.equals("wa")) es_streamtype = CommonParsing.LPCM_AUDIO; IDDBufferedOutputStream audiooutL; IDDBufferedOutputStream audiooutR; /** * pre-init audioparser */ AudioFormat audio = new AudioFormat(es_streamtype); // pre-check for toggling ac3<->dts AudioFormat test_audio = new AudioFormat(CommonParsing.DTS_AUDIO); try { //System.gc(); long[][] obj = loadTempOtherPts(filename_pts, "audio.msg.pts.discard", "audio.msg.pts.firstonly", "audio.msg.pts.start_end", "", 0, IgnoreErrors, Debug); if (obj != null) { ptsval = obj[0]; ptspos = obj[1]; ptsdata = true; obj = null; } obj = loadTempVideoPts(videofile_pts, Debug); if (obj != null) { vptsval = obj[0]; vtime = obj[1]; vptsdata = true; obj = null; } //System.gc(); PushbackInputStream audioin = new PushbackInputStream(xInputFile.getInputStream(), 1000000); audiosize = xInputFile.length(); long[] addf = { 0, 0 }; if (audiosize < 1000) Common.setMessage(" Filesize < 1000 byte"); audiooutL = new IDDBufferedOutputStream(new FileOutputStream(newnameL), 2048000); if (MpaConversionMode >= 4) // half of mainbuffer audiooutR = new IDDBufferedOutputStream(new FileOutputStream(newnameR), 2048000); else audiooutR = new IDDBufferedOutputStream(new FileOutputStream(newnameR)); ByteArrayOutputStream silentFrameBuffer = new ByteArrayOutputStream(); if (CreateM2sIndex) { audiooutL.InitIdd(newnameL, 2); audiooutR.InitIdd(newnameR, 2); } if (vptsdata && ptsdata) { int jump = checkPTSMatch(vptsval, ptsval); if (jump < 0) { Common.setMessage(Resource.getString("audio.msg.pts.mismatch")); vptsdata = false; x = 0; } else x = jump; } if (vptsdata) Common.setMessage(Resource.getString("audio.msg.adjust.at.videopts")); if (ptsdata && !vptsdata && isElementaryStream != CommonParsing.ES_TYPE) Common.setMessage(Resource.getString("audio.msg.adjust.at.ownpts")); if (ptsdata) { timeline = ptsval[x]; n = ptspos[x]; } if (n > 0) audioin.skip(n); /** * riff wave header */ RIFFHeader[] riffw = new RIFFHeader[2]; riffw[0] = new RIFFHeader(); // normal, left riffw[1] = new RIFFHeader(); // right if (es_streamtype == CommonParsing.MPEG_AUDIO) { if (AddRiffToMpgAudioL3) { audiooutL.write(riffw[0].ACMnull()); if (MpaConversionMode >= 4) audiooutR.write(riffw[1].ACMnull()); Common.setMessage(Resource.getString("audio.msg.addriff.acm")); } else if (AddRiffToMpgAudio) { audiooutL.write(riffw[0].BWFnull()); if (MpaConversionMode >= 4) audiooutR.write(riffw[1].BWFnull()); Common.setMessage(Resource.getString("audio.msg.addriff.bwf")); } } else if (AddRiffToAc3 && es_streamtype == CommonParsing.AC3_AUDIO) { audiooutL.write(riffw[0].AC3null()); Common.setMessage(Resource.getString("audio.msg.addriff.ac3")); } else if (CreateDDWave && es_streamtype == CommonParsing.AC3_AUDIO) audiooutL.write(audio.getRiffHeader()); else if (CreateDDWave && es_streamtype == CommonParsing.DTS_AUDIO) audiooutL.write(audio.getRiffHeader()); bigloop: while (true) { /** * AC-3/DTS Audio */ readloopdd: while ((es_streamtype == CommonParsing.AC3_AUDIO || es_streamtype == CommonParsing.DTS_AUDIO) && n < audiosize - 10) { Common.updateProgressBar(n, audiosize); //yield(); if (Debug) System.out.println(" n" + n); while (pause()) {} if (CommonParsing.isProcessCancelled()) { CommonParsing.setProcessCancelled(false); job_processing.setSplitSize(0); break bigloop; } if (ptspos[x + 1] != -1 && n > ptspos[x + 1]) { Common.setMessage(Resource.getString("audio.msg.pts.wo_frame") + " (" + ptspos[x + 1] + "/" + n + ")"); x++; } /** * read 10 bytes for headercheck */ audioin.read(pushback, 0, 10); n += 10; /** * parse header */ ERRORCODE = (is_AC3 || !is_DTS) ? audio.parseHeader(pushback, 0) : 0; if (ERRORCODE < 1) { if (!is_AC3 || is_DTS) ERRORCODE = test_audio.parseHeader(pushback, 0); if (ERRORCODE < 1) { audioin.unread(pushback, 1, 9); if (Message_2 && !missing_syncword) Common.setMessage(Resource.getString("audio.msg.syncword.lost", " " + (n - 10)) + " " + Common.formatTime_1((long)(time_counter / 90.0f))); missing_syncword = true; n -= 9; continue readloopdd; } is_DTS = true; is_AC3 = false; //set special type audio = new AudioFormat(CommonParsing.DTS_AUDIO); audio.parseHeader(pushback, 0); } else { is_DTS = false; is_AC3 = true; } audiooutL.setWave(CreateDDWave, is_AC3, is_DTS, audio.getBitrate()); /** * prepare fo read entire frame */ audioin.unread(pushback); n -= 10; /** * read entire frame */ frame = new byte[audio.getSize()]; audioin.read(frame, 0, audio.getSize()); /** * startfileposition of current frame */ actframe = n; /** * expected position for following frame */ n += audio.getSize(); if (PitchAudio) { // skip a frame if (pitch[1] * pitch[0] == frame_counter) { Common.setMessage(Resource.getString("audio.msg.frame.discard") + " " + frame_counter + " (" + pitch[0] + ")"); pitch[0]++; continue readloopdd; } } /** * finish loop if last frame in file is shorter than nominal size */ if ( n > audiosize ) break readloopdd; /** * read following frame header, not if it is the last frame * check following frameheader for valid , if not starting with next byte */ if (n < audiosize - 10) { int d = 0; if (!AllowSpaces) { audioin.read(push24, 0, 24); miniloop: for (; d < (is_DTS ? 15 : 17); d++) { //smpte ERRORCODE = audio.parseNextHeader(push24, d); if (ERRORCODE > 0) break miniloop; } audioin.unread(push24); } if (ERRORCODE < 1) { audioin.unread(frame, 1, frame.length - 1); n = actframe + 1; continue readloopdd; } else { layertype = is_DTS ? DTS_AUDIOSTREAM : AC3_AUDIOSTREAM; audioin.skip(d); n += d; } } if (ValidateCRC && (ERRORCODE = audio.validateCRC(frame, 2, audio.getSize())) != 0 ) { Common.setMessage(Resource.getString("audio.msg.crc.error", "" + ERRORCODE) + " " + actframe); audioin.unread(frame, 2, frame.length - 2); n = actframe + 2; continue readloopdd; } if (Message_2 && missing_syncword) Common.setMessage(Resource.getString("audio.msg.syncword.found") + " " + actframe); missing_syncword = false; /** * check for change in frametype */ if (audio.compareHeader() > 0) newformat = true; if (frame_counter == 0) newformat = true; audio.saveHeader(); /** * replace not 3/2 with silence ac3 3/2 061i++ */ if (!is_DTS && ReplaceAc3withSilence && audio.getMode() != 7 ) { for (int c = 0; c < Common.getAC3list().size(); c++) { byte[] ac3data = (byte[]) Common.getAC3list().get(c); if ( ((0xE0 & ac3data[6])>>>5) != 7 ) continue; frame = new byte[ac3data.length]; System.arraycopy(ac3data, 0, frame, 0, frame.length); break; } } // timeline ist hier aktuelle audiopts Common.setFps(frame_counter); /** * preloop if audio starts later than video, and i must insert */ if ( (preloop && v>=vptsval.length) || !( preloop && vptsdata && vptsval[v] < timeline - (audio.getFrameTimeLength() / 2.0) ) ) preloop=false; else { /** * patch ac-3 to 3/2 */ if (!is_DTS && Patch1stAc3Header && frame_counter == 0) frame = audio.editFrame(frame, audio.getSize(), 1); // frame[6] = (byte)((0xF & frame[6]) | 0xE0); long precount = vptsval[v]; long[] ins = { (long)time_counter, 0 }; silentFrameBuffer.reset(); /** * insert silence ac3 */ if (!is_DTS && !FillGapsWithLastFrame) { for (int c = 0; c < Common.getAC3list().size(); c++) { byte[] ac3data = (byte[]) Common.getAC3list().get(c); if ( (0xFE & ac3data[4]) != (0xFE & frame[4]) || ( (7 & ac3data[5]) != (7 & frame[5]) ) || (0xE0&ac3data[6])!=(0xE0&frame[6]) ) continue; silentFrameBuffer.write(ac3data); break; } } else silentFrameBuffer.write(frame); /** * pre inserting */ while (precount < timeline - (audio.getFrameTimeLength() / 2.0)) { /** * check if frame write should paused */ if (vptsdata && w < vptsval.length) { double ms1 = (double) (precount - vptsval[w + 1]); double ms2 = (double) (time_counter - vtime[w + 1]); if ((double) Math.abs(ms2) <= audio.getFrameTimeLength() / 2.0 ) { awrite = false; w += 2; } else if ((double) Math.abs(ms1) <= audio.getFrameTimeLength() / 2.0 ) { awrite = false; w += 2; } } /** * calculate A/V Offset for true */ if (vptsdata && (v < vptsval.length)) { double ms3 = precount - vptsval[v], ms4 = time_counter - vtime[v]; if (Debug) System.out.println(" " + ms3 + "/" + ms4 + "/" + (ms4 - ms3)); if (!awrite && (double) Math.abs((time_counter - vtime[v]) - (precount - vptsval[v])) <= (double) audio.getFrameTimeLength() / 2.0 ) { awrite = true; v += 2; double ms1 = precount - vptsval[v - 2]; double ms2 = time_counter - vtime[v - 2]; Common.getGuiInterface().showAVOffset("" + (int)(ms1 / 90) + "/" + (int)(ms2 / 90) + "/" + (int)((ms2 - ms1) / 90)); if (Debug) System.out.println(" " + ms1 + "/" + ms2 + "/" + (ms2 - ms1)); } } /** * calculate A/V Offset for true */ if ((v < vptsval.length) ) { if ((double) Math.abs(vptsval[v] - precount) <= ((double) audio.getFrameTimeLength() / 2.0) ) { awrite = true; v += 2; double ms1 = precount - vptsval[v - 2]; double ms2 = time_counter - vtime[v - 2]; Common.getGuiInterface().showAVOffset("" + (int)(ms1 / 90) + "/" + (int)(ms2 / 90) + "/" + (int)((ms2 - ms1) / 90)); if (Debug) System.out.println(" " + ms1 + "/" + ms2 + "/" + (ms2 - ms1)); } /** * calculate A/V Offset for false */ if (awrite && (double) Math.abs((time_counter - vtime[v - 2]) - (precount - vptsval[v-2])) > (double) audio.getFrameTimeLength() / 2.0 ) { awrite = false; v -= 2; } } /** * write message */ if (awrite || !vptsdata) Common.getGuiInterface().showExportStatus(Resource.getString("audio.status.pre-insert")); else Common.getGuiInterface().showExportStatus(Resource.getString("audio.status.pause")); /** * stop if no more audio needed */ if (precount > vptsval[vptsval.length - 1] + 10000) { Common.updateProgressBar(audiosize, audiosize); break readloopdd; } if (awrite) { silentFrameBuffer.writeTo(audiooutL); /** * RIFF */ if (!is_DTS && AddRiffToAc3) riffw[0].AC3RiffData(audio.parseRiffData(frame)); frame_counter++; cb++; ins[1]++; time_counter += audio.getFrameTimeLength(); } precount += audio.getFrameTimeLength(); if (Debug) System.out.println("(6)audio frames: wri/pre/skip/ins/add " + frame_counter + "/" + cb + "/" + ce + "/" + cc + "/" + cd + " @ " + Common.formatTime_1((long)(time_counter / 90.0) ) + " "); } // end while n = actframe; audioin.unread(frame); if (ins[1] > 0) Common.setMessage(Resource.getString("audio.msg.summary.pre-insert", "" + ins[1], FramesToTime((int)ins[1], audio.getFrameTimeLength())) + " " + Common.formatTime_1(ins[0] / 90L)); continue readloopdd; } // end if preloop /****** check if frame write should paused *****/ if (vptsdata) { vw[0] = v; vw[1] = w; awrite = SyncCheck(vw, time_counter, audio.getFrameTimeLength(), timeline, frame_counter, vptsval, vtime, awrite, Debug); v = vw[0]; w = vw[1]; } //System.out.println(""+awrite+"/"+v+"/"+w); /** * message */ if (awrite || !vptsdata) Common.getGuiInterface().showExportStatus(Resource.getString("audio.status.write")); else Common.getGuiInterface().showExportStatus(Resource.getString("audio.status.pause")); if (Debug) System.out.println(" k)" + timeline + " l)" + (audio.getFrameTimeLength() / 2.0) + " u)" + audio.getSize() + " m)" + awrite + " n)"+w+" o)"+v+" p)"+n); /** * stop if no more audio needed */ if (vptsdata && timeline > vptsval[vptsval.length - 1] + 10000) { Common.updateProgressBar(audiosize, audiosize); break readloopdd; } /** * message */ if ((newformat && awrite) || (newformat && !vptsdata)) { String hdr = audio.displayHeader(); if (ModeChangeCount < 100) { String str = Common.formatTime_1((long)(time_counter / 90.0f)); Common.setMessage(Resource.getString("audio.msg.source", hdr) + " " + str); if (collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createChapters)) job_processing.getChapters().addChapter(str, hdr); } else if (ModeChangeCount == 100) Common.setMessage(Resource.getString("audio.msg.source.max")); else if (Debug) System.out.println("=> src_audio: " + hdr + " @ " + Common.formatTime_1((long)(time_counter / 90.0f))); ModeChangeCount++; newformat = false; //yield(); } /** * patch ac-3 to 3/2 */ if (!is_DTS && Patch1stAc3Header && frame_counter == 0) frame = audio.editFrame(frame, audio.getSize(), 1); // frame[6] = (byte)((0xF & frame[6]) | 0xE0); if (Debug) System.out.println("(7)audio frames: wri/pre/skip/ins/add " + frame_counter + "/" + cb + "/" + ce + "/" + cc + "/" + cd + " @ " + Common.formatTime_1((long)(time_counter / 90.0f) )); if (Debug) System.out.println(" x" + ((x < ptspos.length - 1) ? x + "/" + ptsval[x + 1] + "/" + ptspos[x + 1] : "-")); /** * pts for next frame!! */ timeline += audio.getFrameTimeLength(); silentFrameBuffer.reset(); silentFrameBuffer.write(frame); /** * simple sync */ if (LimitPts && ptspos[x + 1] != -1 && ptspos[x + 1] < n) { if (Debug) System.out.println(" minSync " + minSync + "/ " + x); if ( (++minSync) < 20) x++; else minSync = 0; } if ( (ptspos[x + 1] == -1) || (ptspos[x + 1] > n ) ) { if (!vptsdata || (vptsdata && awrite)) { audiooutL.write(frame); /** * RIFF */ if (!is_DTS && AddRiffToAc3) riffw[0].AC3RiffData(audio.parseRiffData(frame)); frame_counter++; time_counter += audio.getFrameTimeLength(); } continue readloopdd; } minSync = 0; if ( (double) Math.abs(ptsval[x + 1] - timeline) < (double) audio.getFrameTimeLength() / 2.0 ) { timeline = ptsval[x + 1]; x++; if (!vptsdata || (vptsdata && awrite)) { audiooutL.write(frame); /** * RIFF */ if (!is_DTS && AddRiffToAc3) riffw[0].AC3RiffData(audio.parseRiffData(frame)); frame_counter++; time_counter += audio.getFrameTimeLength(); } continue readloopdd; } if (ptsval[x + 1] > timeline) insertSilenceLoop = true; if (ptsval[x + 1] < timeline) { x++; timeline = ptsval[x]; Common.setMessage(Resource.getString("audio.msg.summary.skip") + " " + Common.formatTime_1((long)time_counter / 90L)); ce++; } if (insertSilenceLoop) { /** * test , write the actual frame and then loop to fill */ if (!vptsdata || (vptsdata && awrite)) { audiooutL.write(frame); /** * RIFF */ if (!is_DTS && AddRiffToAc3) riffw[0].AC3RiffData(audio.parseRiffData(frame)); frame_counter++; time_counter += audio.getFrameTimeLength(); if (Debug) System.out.println("(10)audio frames: wri/pre/skip/ins/add " + frame_counter + "/" + cb + "/" + ce + "/" + cc + "/" + cd + " @ " + Common.formatTime_1((long)(time_counter / 90.0) ) + " "); } timeline += audio.getFrameTimeLength(); /** * insert silence ac3 */ if (!is_DTS && !FillGapsWithLastFrame) { for (int c = 0; c < Common.getAC3list().size(); c++) { byte[] ac3data = (byte[]) Common.getAC3list().get(c); if ( (0xFE & ac3data[4]) != (0xFE & frame[4]) || ( (7 & ac3data[5]) != (7 & frame[5]) ) || (0xE0 & ac3data[6]) != (0xE0 & frame[6]) ) continue; silentFrameBuffer.reset(); silentFrameBuffer.write(ac3data); break; } } long[] ins = { (long)time_counter, 0 }; while (ptsval[x + 1] > (timeline - (audio.getFrameTimeLength() / 2.0)) ) { if (vptsdata && w < vptsval.length) { double ms1 = (double) (timeline - audio.getFrameTimeLength() - vptsval[w + 1]); double ms2 = (double) (time_counter - vtime[w + 1]); if ((double) Math.abs(ms2) <= audio.getFrameTimeLength() / 2.0 ) { awrite = false; w += 2; } else if ((double) Math.abs(ms1) <= audio.getFrameTimeLength() / 2.0 ) { awrite = false; w += 2; } } if (vptsdata && v < vptsval.length) { if (!awrite && (double) Math.abs((time_counter - vtime[v]) - (timeline - audio.getFrameTimeLength() - vptsval[v]) ) <= (double) audio.getFrameTimeLength() / 2.0 ) { double ms1 = (double) (timeline - audio.getFrameTimeLength() - vptsval[v]); double ms2 = (double) (time_counter - vtime[v]); Common.getGuiInterface().showAVOffset("" + (int)(ms1 / 90) + "/" + (int)(ms2 / 90) + "/" + (int)((ms2 - ms1) / 90)); if (Debug) System.out.println(" " + ms1 + "/" + ms2 + "/" + (ms2 - ms1)); awrite = true; v += 2; } } if (vptsdata && v < vptsval.length) { if ((double) Math.abs(vptsval[v] - (timeline - audio.getFrameTimeLength())) <= ((double) audio.getFrameTimeLength() / 2.0) ) { double ms1 = (double) (timeline - audio.getFrameTimeLength() - vptsval[v]); double ms2 = (double) (time_counter - vtime[v]); Common.getGuiInterface().showAVOffset("" + (int)(ms1 / 90) + "/" + (int)(ms2 / 90) + "/" + (int)((ms2 - ms1) / 90)); if (Debug) System.out.println(" " + ms1 + "/" + ms2 + "/" + (ms2 - ms1)); awrite = true; v += 2; } if (awrite && (double) Math.abs((time_counter - vtime[v - 2]) - (timeline - audio.getFrameTimeLength() - vptsval[v - 2]) ) > (double) audio.getFrameTimeLength() / 2.0 ) { awrite = false; v -= 2; } } if (awrite || !vptsdata) Common.getGuiInterface().showExportStatus(Resource.getString("audio.status.insert")); else Common.getGuiInterface().showExportStatus(Resource.getString("audio.status.pause")); if (!vptsdata || (vptsdata && awrite)) { silentFrameBuffer.writeTo(audiooutL); /** * RIFF */ if (!is_DTS && AddRiffToAc3) riffw[0].AC3RiffData(audio.parseRiffData(silentFrameBuffer.toByteArray())); frame_counter++; time_counter += audio.getFrameTimeLength(); cc++; ins[1]++; } if (Debug) { System.out.println("(8)audio frames: wri/pre/skip/ins/add " + frame_counter + "/" + cb + "/" + ce + "/" + cc + "/" + cd + " @ " + Common.formatTime_1((long)(time_counter / 90.0f) ) + " "); System.out.println(" t)" + timeline); System.out.println(" x" + ((x < ptspos.length - 1) ? x + "/" + ptsval[x + 1] + "/" + ptspos[x + 1] : "-")); } timeline += audio.getFrameTimeLength(); } // end while timeline -= audio.getFrameTimeLength(); insertSilenceLoop = false; x++; if (ins[1] > 0) Common.setMessage(Resource.getString("audio.msg.summary.insert", "" + ins[1], FramesToTime((int)ins[1], audio.getFrameTimeLength())) + " " + Common.formatTime_1(ins[0] / 90L)); /** * reset PTS after inserting */ timeline = ptsval[x]; continue readloopdd; } // end if insertSilenceLoop if ( (actframe + audio.getSize()) >= audiosize ) break readloopdd; } // end while /** * add frames at the end */ if ((es_streamtype == CommonParsing.AC3_AUDIO || es_streamtype == CommonParsing.DTS_AUDIO) && AddFrames && vptsdata && awrite && (w < vptsval.length)) { timeline += audio.getFrameTimeLength(); addf[0] = (long) time_counter; /** * insert silence ac3 */ if (!is_DTS && !FillGapsWithLastFrame) { for (int c = 0; c < Common.getAC3list().size(); c++) { byte[] ac3data = (byte[]) Common.getAC3list().get(c); if ( (0xFE & ac3data[4]) != (0xFE & frame[4]) || ( (7 & ac3data[5]) != (7 & frame[5]) ) || (0xE0 & ac3data[6]) != (0xE0 & frame[6]) ) continue; silentFrameBuffer.reset(); silentFrameBuffer.write(ac3data); break; } } while ( w < vptsval.length ) { while (vtime[w + 1] > time_counter && (double) Math.abs(vtime[w + 1] - time_counter) > (double) audio.getFrameTimeLength() / 2.0) { silentFrameBuffer.writeTo(audiooutL); /** * RIFF */ if (!is_DTS && AddRiffToAc3) riffw[0].AC3RiffData(audio.parseRiffData(silentFrameBuffer.toByteArray())); Common.getGuiInterface().showExportStatus(Resource.getString("audio.status.add")); frame_counter++; time_counter += audio.getFrameTimeLength(); timeline += audio.getFrameTimeLength(); cd++; addf[1]++; if (Debug) { System.out.println("(9)audio frames: wri/pre/skip/ins/add " + frame_counter + "/" + cb + "/" + ce + "/" + cc + "/" + cd + " @ " + Common.formatTime_1((long)(time_counter / 90.0f) )); System.out.print(" t)" + (long)(timeline - audio.getFrameTimeLength()) + " w)" + w); } } w += 2; } w -= 2; timeline -= audio.getFrameTimeLength(); if (Debug) System.out.println(" eot_video:" + (vptsval[w + 1] / 90) + "ms, eot_audio:" + (timeline / 90) + "ms "); } // mpa start /** * init FFT/window for mpa decoding for 1 file */ if (es_streamtype == CommonParsing.MPEG_AUDIO && DecodeMpgAudio) { MpaDecoder.init_work(ResampleAudioMode); MpaDecoder.DOWNMIX = DownMix; MpaDecoder.MONO = (DownMix || MpaConversionMode == 4); MpaDecoder.MOTOROLA = ChangeByteorder; MpaDecoder.WAVE = AddRiffHeader; if (AddRiffHeader) { audiooutL.write(MpaDecoder.RIFF); if (MpaConversionMode >= 4) audiooutR.write(MpaDecoder.RIFF); } else if (AddAiffHeader) { audiooutL.write(MpaDecoder.AIFF); if (MpaConversionMode >= 4) audiooutR.write(MpaDecoder.AIFF); } } if (es_streamtype == CommonParsing.MPEG_AUDIO) // audio is global audio.setAncillaryDataDecoder(collection.getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg7), collection.DebugMode()); /** * MPEG1+2 Audio Layer 1,2,3 */ readloop: while (es_streamtype == CommonParsing.MPEG_AUDIO && n < audiosize - 4) { Common.updateProgressBar(n, audiosize); //yield(); if (Debug) System.out.println(" n" + n); while (pause()) {} if (CommonParsing.isProcessCancelled()) { CommonParsing.setProcessCancelled(false); job_processing.setSplitSize(0); break bigloop; } /** * updates global audio_error and framecounter variable */ CommonParsing.setAudioProcessingFlags((0x3FFFFL & CommonParsing.getAudioProcessingFlags()) | ((long)frame_counter)<<18); /** * fix VBR & restart processing */ if (MpaDecoder.RESET) return true; /** * fix VBR & restart processing */ if (!MpaDecoder.PRESCAN && (0xCL & CommonParsing.getAudioProcessingFlags()) != 0) return true; if (ptspos[x + 1] != -1 && n > ptspos[x + 1]) { Common.setMessage(Resource.getString("audio.msg.pts.wo_frame") + " (" + ptspos[x + 1] + "/" + n + ")"); x++; } /** * read 4 bytes for headercheck */ audioin.read(pushmpa, 0, 4); n += 4; /** * parse header */ if ((ERRORCODE = audio.parseHeader(pushmpa, 0)) < 1) { audioin.unread(pushmpa, 1, 3); if (Message_2 && !missing_syncword) Common.setMessage(Resource.getString("audio.msg.syncword.lost", " " + (n - 4)) + " " + Common.formatTime_1((long)(time_counter / 90.0f))); missing_syncword = true; n -= 3; continue readloop; } /** * prepare fo read entire frame */ audioin.unread(pushmpa); n -= 4; /** * read entire frame */ frame = new byte[audio.getSize()]; audioin.read(frame, 0, frame.length); System.arraycopy(frame, 0, header_copy, 0, 4); header_copy[3] &= 0xCF; header_copy[2] &= ~2; /** * startfileposition of current frame */ actframe = n; /** * expected position for following frame */ n += audio.getSize(); /** * pitch */ if (PitchAudio) { // skip a frame if (pitch[1] * pitch[0] == frame_counter) { Common.setMessage(Resource.getString("audio.msg.frame.discard") + " " + frame_counter + " (" + pitch[0] + ")"); pitch[0]++; continue readloop; } } /** * save current frame for copying, delete crc if nec. */ if (FillGapsWithLastFrame) { copyframe[0] = new byte[frame.length]; System.arraycopy(frame, 0, copyframe[0], 0, frame.length); if (ClearCRC) audio.removeCRC(copyframe[0]); } /** * finish loop if last frame in file is shorter than nominal size */ if (n > audiosize) break readloop; /** * read following frame header, not if it is the last frame * check following frameheader for valid mpegaudio, if not starting with next byte */ if (n < audiosize - 4) { if (!AllowSpaces) { audioin.read(pushmpa, 0, 4); ERRORCODE = audio.parseNextHeader(pushmpa, 0); audioin.unread(pushmpa); if (ERRORCODE < 1) { audioin.unread(frame, 1, frame.length - 1); n = actframe + 1; continue readloop; } } layertype = audio.getLayer(); } if (ValidateCRC && (ERRORCODE = audio.validateCRC(frame, 0, audio.getSize())) != 0 ) { Common.setMessage(Resource.getString("audio.msg.crc.error", "") + " " + actframe); audioin.unread(frame, 2, frame.length - 2); n = actframe + 2; continue readloop; } if (Message_2 && missing_syncword) Common.setMessage(Resource.getString("audio.msg.syncword.found") + " " + actframe); missing_syncword = false; /** * check for change in frametype */ if ((returncode = audio.compareHeader()) > 0) { newformat = true; if (returncode == 6) { jss++; newformat = false; } } if (frame_counter == 0) newformat = true; audio.saveHeader(); audio.decodeAncillaryData(frame); // timeline ist hier aktuelle audiopts Common.setFps(frame_counter); /** * message */ if (Debug) System.out.println(" k)" +timeline +" l)" + (audio.getFrameTimeLength() / 2.0) + " m)" + awrite + " n)" + w + " o)" + v + " p)" + n); /** * preloop if audio starts later than video, and i must insert */ if ( (preloop && vptsdata && v >= vptsval.length) || !( preloop && vptsdata && vptsval[v] < timeline - (audio.getFrameTimeLength() / 2.0) ) ) preloop = false; else { silent_Frame[0] = new byte[audio.getSizeBase()]; //silence without padd, std silent_Frame[1] = new byte[audio.getSize()]; //silence with padd for 22.05, 44.1 for (int a = 0; a < 2; a++) { System.arraycopy(header_copy, 0, silent_Frame[a], 0, 4); //copy last header data silent_Frame[a][1] |= 1; //mark noCRC silent_Frame[a][2] |= (a * 2); //set padding bit } int padding_counter = 1; //count padding long precount=vptsval[v]; long[] ins = { (long)time_counter, 0 }; while ( precount < timeline- (audio.getFrameTimeLength() / 2.0) ) { //better for RTS /** * check if frame write should paused */ if (vptsdata && w < vptsval.length) { double ms1 = (double) (precount - vptsval[w + 1]); double ms2 = (double) (time_counter - vtime[w + 1]); if ( (double) Math.abs(ms2) <= audio.getFrameTimeLength() / 2.0 ) { awrite = false; w += 2; } else if ((double) Math.abs(ms1) <= audio.getFrameTimeLength() / 2.0 ) { awrite = false; w += 2; } } /** * calculate A/V Offset for true */ if (vptsdata && v < vptsval.length) { double ms3 = precount - vptsval[v]; double ms4 = time_counter - vtime[v]; if (Debug) System.out.println(" " + ms3 + "/" + ms4 + "/" + (ms4 - ms3)); if (!awrite && (double) Math.abs((time_counter - vtime[v]) - (precount - vptsval[v]) ) <= (double)audio.getFrameTimeLength() / 2.0 ) { awrite = true; v += 2; double ms1 = precount - vptsval[v - 2]; double ms2 = time_counter - vtime[v - 2]; Common.getGuiInterface().showAVOffset("" + (int)(ms1 / 90) + "/" + (int)(ms2 / 90) + "/" + (int)((ms2 - ms1) / 90)); if (Debug) System.out.println(" " + ms1 + "/" + ms2 + "/" + (ms2 - ms1)); } } /** * calculate A/V Offset for true */ if (v < vptsval.length) { if ((double) Math.abs(vptsval[v] - precount) <= (double) audio.getFrameTimeLength() / 2.0) { awrite = true; v += 2; double ms1 = precount - vptsval[v - 2]; double ms2 = time_counter - vtime[v - 2]; Common.getGuiInterface().showAVOffset("" + (int)(ms1 / 90) + "/" + (int)(ms2 / 90) + "/" + (int)((ms2 - ms1) / 90)); if (Debug) System.out.println(" " + ms1 + "/" + ms2 + "/" + (ms2 - ms1)); } /** * calculate A/V Offset for false */ if (awrite && Math.abs((time_counter - vtime[v - 2]) - (precount - vptsval[v - 2]) ) > audio.getFrameTimeLength() / 2.0 ) { awrite = false; v -= 2; } } /** * message */ if (awrite || !vptsdata) Common.getGuiInterface().showExportStatus(Resource.getString("audio.status.pre-insert")); else Common.getGuiInterface().showExportStatus(Resource.getString("audio.status.pause")); /** * stop if no more audio needed */ if (precount > vptsval[vptsval.length - 1] + 10000) { Common.updateProgressBar(audiosize, audiosize); break readloop; } if (awrite) { if (FillGapsWithLastFrame) { // copy last frame if (audio.getLayer() > 0 && DecodeMpgAudio) { audiooutL.write(MpaDecoder.decodeArray(copyframe[0])); if (MpaConversionMode >= 4) audiooutR.write(MpaDecoder.get2ndArray()); } else if (MpaConversionMode > 0) { newframes = MPAConverter.modifyframe(copyframe[0], MpaConversionMode); audiooutL.write(newframes[0]); if (MpaConversionMode >= 4) audiooutR.write(newframes[1]); /** * RIFF */ if (AddRiffToMpgAudio || AddRiffToMpgAudioL3) { riffw[0].RiffData(audio.parseRiffData(newframes[0])); if (MpaConversionMode >= 4) riffw[1].RiffData(audio.parseRiffData(newframes[1])); } } else { audiooutL.write(copyframe[0]); /** * RIFF */ if (AddRiffToMpgAudio || AddRiffToMpgAudioL3) riffw[0].RiffData(audio.parseRiffData(copyframe[0])); } } else { //if (padding_counter==padding) padding_counter=0; //reset padd count //else if (samplerate==0) padding_counter++; //count padding if (audio.getLayer() > 0 && DecodeMpgAudio) { audiooutL.write(MpaDecoder.decodeArray(silent_Frame[(padding_counter > 0) ? 0 : 1])); if (MpaConversionMode >= 4) audiooutR.write(MpaDecoder.get2ndArray()); } else if (MpaConversionMode > 0) { newframes = MPAConverter.modifyframe(silent_Frame[(padding_counter > 0) ? 0 : 1], MpaConversionMode); audiooutL.write(newframes[0]); if (MpaConversionMode >= 4) audiooutR.write(newframes[1]); /** * RIFF */ if (AddRiffToMpgAudio || AddRiffToMpgAudioL3) { riffw[0].RiffData(audio.parseRiffData(newframes[0])); if (MpaConversionMode >= 4) riffw[1].RiffData(audio.parseRiffData(newframes[1])); } } else { audiooutL.write(silent_Frame[(padding_counter > 0) ? 0 : 1]); /** * RIFF */ if (AddRiffToMpgAudio || AddRiffToMpgAudioL3) riffw[0].RiffData(audio.parseRiffData(silent_Frame[(padding_counter > 0) ? 0 : 1])); } } frame_counter++; time_counter += audio.getFrameTimeLength(); cb++; ins[1]++; } precount += audio.getFrameTimeLength(); if (Debug) System.out.println("(5)audio frames: wri/pre/skip/ins/add " + frame_counter + "/" + cb + "/" + ce + "/" + cc + "/" + cd + " @ " + Common.formatTime_1((long)(time_counter / 90.0f) )); } /** end while **/ n = actframe; audioin.unread(frame); if (ins[1] > 0) Common.setMessage(Resource.getString("audio.msg.summary.pre-insert", "" + ins[1], FramesToTime((int)ins[1], audio.getFrameTimeLength())) + " " + Common.formatTime_1(ins[0] / 90L)); continue readloop; } /** * check if frame write should paused */ if (vptsdata) { vw[0] = v; vw[1] = w; awrite = SyncCheck(vw, time_counter, audio.getFrameTimeLength(), timeline, frame_counter, vptsval, vtime, awrite, Debug); v = vw[0]; w = vw[1]; } // System.out.println(""+awrite+"/"+v+"/"+w); /** * message */ if (awrite || !vptsdata) Common.getGuiInterface().showExportStatus(Resource.getString("audio.status.write")); else Common.getGuiInterface().showExportStatus(Resource.getString("audio.status.pause")); /** * stop if no more audio needed */ if (vptsdata && timeline > vptsval[vptsval.length - 1] + 10000) { Common.updateProgressBar(audiosize, audiosize); break readloop; } /** * message */ if ((newformat && awrite) || (newformat && !vptsdata)) { if (ModeChangeCount < 100) { String str = Common.formatTime_1((long)(time_counter / 90.0f)); Common.setMessage(Resource.getString("audio.msg.source", audio.displayHeader()) + " " + str); if (collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_createChapters)) job_processing.getChapters().addChapter(str, audio.displayHeader()); } else if (ModeChangeCount == 100) Common.setMessage(Resource.getString("audio.msg.source.max")); else if (Debug) System.out.println("=> src_audio: "+audio.displayHeader() + " @ " + Common.formatTime_1((long)(time_counter / 90.0f))); ModeChangeCount++; newformat = false; //yield(); } /** * message */ if (Debug) System.out.println("(1)audio frames: wri/pre/skip/ins/add " + frame_counter + "/" + cb + "/" + ce + "/" + cc + "/" + cd + " @ " + Common.formatTime_1((long)(time_counter / 90.0f) )); if (Debug) System.out.println(" x" + ((x < ptspos.length - 1) ? x + "/" + ptsval[x + 1] + "/" + ptspos[x + 1] : "-")); /** * pts for next frame!! */ timeline += audio.getFrameTimeLength(); /** * remove CRC */ if (ClearCRC) audio.removeCRC(frame); /** * copy frame header */ System.arraycopy(frame, 0, header_copy, 0, 4); header_copy[3] &= 0xCF; header_copy[2] &= ~2; /** * message */ //if (Debug) // System.out.print(" tl"+timeline+" /px "+ptsval[x]+" /1_"+ptsval[x+1]+" /p1-tl "+(ptsval[x+1]-timeline)+" /pp1 "+ptspos[x+1]+" /n "+n); /** * simple sync */ if (LimitPts && ptspos[x + 1] != -1 && ptspos[x + 1] < n) { if (Debug) System.out.println(" minSync " + minSync + "/ " + x); if ((++minSync) < 20) x++; else minSync = 0; } /** * frame is in last pes packet or packet end not yet reached */ if ((ptspos[x + 1] == -1) || (ptspos[x + 1] > n )) { if (vptsdata && !awrite) continue readloop; if (audio.getLayer() > 0 && DecodeMpgAudio) { audiooutL.write(MpaDecoder.decodeArray(frame)); if (MpaConversionMode >= 4) audiooutR.write(MpaDecoder.get2ndArray()); } else if (MpaConversionMode > 0) { newframes = MPAConverter.modifyframe(frame, MpaConversionMode); audiooutL.write(newframes[0]); if (MpaConversionMode >= 4) audiooutR.write(newframes[1]); /** * RIFF */ if (AddRiffToMpgAudio || AddRiffToMpgAudioL3) { riffw[0].RiffData(audio.parseRiffData(newframes[0])); if (MpaConversionMode >= 4) riffw[1].RiffData(audio.parseRiffData(newframes[1])); } } else { audiooutL.write(frame); /** * RIFF */ if (AddRiffToMpgAudio || AddRiffToMpgAudioL3) riffw[0].RiffData(audio.parseRiffData(frame)); } frame_counter++; time_counter += audio.getFrameTimeLength(); continue readloop; } minSync = 0; /** * frame is on pes packet corner */ if ((double) Math.abs(ptsval[x + 1] - timeline) < (double) audio.getFrameTimeLength() / 2.0 ) { timeline = ptsval[x + 1]; x++; if (vptsdata && !awrite) continue readloop; if (audio.getLayer() > 0 && DecodeMpgAudio) { audiooutL.write(MpaDecoder.decodeArray(frame)); if (MpaConversionMode >= 4) audiooutR.write(MpaDecoder.get2ndArray()); } else if (MpaConversionMode > 0) { newframes = MPAConverter.modifyframe(frame, MpaConversionMode); audiooutL.write(newframes[0]); if (MpaConversionMode >= 4) audiooutR.write(newframes[1]); /** * RIFF */ if (AddRiffToMpgAudio || AddRiffToMpgAudioL3) { riffw[0].RiffData(audio.parseRiffData(newframes[0])); if (MpaConversionMode >= 4) riffw[1].RiffData(audio.parseRiffData(newframes[1])); } } else { audiooutL.write(frame); /** * RIFF */ if (AddRiffToMpgAudio || AddRiffToMpgAudioL3) riffw[0].RiffData(audio.parseRiffData(frame)); } frame_counter++; time_counter += audio.getFrameTimeLength(); continue readloop; } if (ptsval[x + 1] > timeline) insertSilenceLoop = true; if (ptsval[x + 1] < timeline) { x++; timeline = ptsval[x]; Common.setMessage(Resource.getString("audio.msg.summary.skip") + " " + Common.formatTime_1((long)time_counter / 90L)); ce++; } if (insertSilenceLoop) { silent_Frame[0] = new byte[audio.getSizeBase()]; //silence without padd, std silent_Frame[1] = new byte[audio.getSize()]; //silence with padd for 22.05, 44.1 for (int a = 0; a < 2; a++) { System.arraycopy(header_copy, 0, silent_Frame[a], 0, 4); //copy last header data silent_Frame[a][1] |= 1; //mark noCRC silent_Frame[a][2] |= (a * 2); //set padding bit } int padding_counter = 1; //count padding long[] ins = { (long)time_counter, 0 }; // solange nchster ptsval minus nchster framebeginn ist grer der halben framezeit, fge stille ein while (ptsval[x + 1] > (timeline - (audio.getFrameTimeLength() / 2.0))) { if (vptsdata && w < vptsval.length) { double ms1 = (double) (timeline - audio.getFrameTimeLength() - vptsval[w + 1]); double ms2 = (double) (time_counter - vtime[w + 1]); if ((double) Math.abs(ms2) <= audio.getFrameTimeLength() / 2.0) { awrite = false; w += 2; } else if ((double) Math.abs(ms1) <= audio.getFrameTimeLength() / 2.0) { awrite = false; w += 2; } } if (vptsdata && v < vptsval.length) { if (!awrite && (double) Math.abs((time_counter - vtime[v]) - (timeline - audio.getFrameTimeLength() - vptsval[v]) ) <= (double) audio.getFrameTimeLength() / 2.0 ) { double ms1 = (double) (timeline - audio.getFrameTimeLength() - vptsval[v]); double ms2 = (double) (time_counter - vtime[v]); Common.getGuiInterface().showAVOffset("" + (int)(ms1 / 90) + "/" + (int)(ms2 / 90) + "/" + (int)((ms2 - ms1) / 90)); if (Debug) System.out.println(" " + ms1 + "/" + ms2 + "/" + (ms2 - ms1)); awrite = true; v += 2; } } if (vptsdata && v < vptsval.length) { if ((double) Math.abs(vptsval[v] - (timeline - audio.getFrameTimeLength())) <= ((double) audio.getFrameTimeLength() / 2.0) ) { double ms1 = (double) (timeline - audio.getFrameTimeLength() - vptsval[v]); double ms2 = (double) (time_counter - vtime[v]); Common.getGuiInterface().showAVOffset("" + (int)(ms1 / 90) + "/" + (int)(ms2 / 90) + "/" + (int)((ms2 - ms1) / 90)); if (Debug) System.out.println(" " + ms1 + "/" + ms2 + "/" + (ms2 - ms1)); awrite = true; v += 2; } if (awrite && (double) Math.abs((time_counter - vtime[v - 2]) - (timeline - audio.getFrameTimeLength() - vptsval[v - 2]) ) > (double) audio.getFrameTimeLength() / 2.0 ) { awrite = false; v -= 2; } } /** * message */ if (awrite || !vptsdata) Common.getGuiInterface().showExportStatus(Resource.getString("audio.status.insert")); else Common.getGuiInterface().showExportStatus(Resource.getString("audio.status.pause")); if (!vptsdata || (vptsdata && awrite)) { if (FillGapsWithLastFrame) { if (audio.getLayer() > 0 && DecodeMpgAudio) { audiooutL.write(MpaDecoder.decodeArray(copyframe[0])); if (MpaConversionMode >= 4) audiooutR.write(MpaDecoder.get2ndArray()); } else if (MpaConversionMode > 0) { newframes = MPAConverter.modifyframe(copyframe[0], MpaConversionMode); audiooutL.write(newframes[0]); if (MpaConversionMode >= 4) audiooutR.write(newframes[1]); /** * RIFF */ if (AddRiffToMpgAudio || AddRiffToMpgAudioL3) { riffw[0].RiffData(audio.parseRiffData(newframes[0])); if (MpaConversionMode >= 4) riffw[1].RiffData(audio.parseRiffData(newframes[1])); } } else { audiooutL.write(copyframe[0]); /** * RIFF */ if (AddRiffToMpgAudio || AddRiffToMpgAudioL3) riffw[0].RiffData(audio.parseRiffData(copyframe[0])); } } else { //if (padding_counter==padding) padding_counter=0; //reset padd count //else if (samplerate==0) padding_counter++; //count padding if (audio.getLayer() > 0 && DecodeMpgAudio) { audiooutL.write(MpaDecoder.decodeArray(silent_Frame[(padding_counter > 0) ? 0 : 1])); if (MpaConversionMode >= 4) audiooutR.write(MpaDecoder.get2ndArray()); } else if (MpaConversionMode > 0) { newframes = MPAConverter.modifyframe(silent_Frame[(padding_counter > 0) ? 0 : 1], MpaConversionMode); audiooutL.write(newframes[0]); if (MpaConversionMode >= 4) audiooutR.write(newframes[1]); /** * RIFF */ if (AddRiffToMpgAudio || AddRiffToMpgAudioL3) { riffw[0].RiffData(audio.parseRiffData(newframes[0])); if (MpaConversionMode >= 4) riffw[1].RiffData(audio.parseRiffData(newframes[1])); } } else { audiooutL.write(silent_Frame[(padding_counter > 0) ? 0 : 1]); /** * RIFF */ if (AddRiffToMpgAudio || AddRiffToMpgAudioL3) riffw[0].RiffData(audio.parseRiffData(silent_Frame[(padding_counter > 0) ? 0 : 1])); } } frame_counter++; time_counter += audio.getFrameTimeLength(); cc++; ins[1]++; } if (Debug) { System.out.println("(2)audio frames: wri/pre/skip/ins/add " + frame_counter + "/" + cb + "/" + ce + "/" + cc + "/" + cd + " @ " + Common.formatTime_1((long)(time_counter / 90.0f) )); System.out.print(" t)" + timeline); System.out.println(" x" + ((x < ptspos.length - 1) ? x + "/" + ptsval[x + 1] + "/" + ptspos[x + 1] : "-")); } timeline += audio.getFrameTimeLength(); } // end while timeline -= audio.getFrameTimeLength(); insertSilenceLoop = false; x++; if (ins[1] > 0) Common.setMessage(Resource.getString("audio.msg.summary.insert", "" + ins[1], FramesToTime((int)ins[1], audio.getFrameTimeLength())) + " " + Common.formatTime_1(ins[0] / 90L)); /** * reset PTS after inserting */ timeline = ptsval[x]; continue readloop; } if ( (actframe + audio.getSize()) >= audiosize ) break readloop; } // end while if (Debug) System.out.println("(3)audio frames: wri/pre/skip/ins/add " + frame_counter + "/" + cb + "/" + ce + "/" + cc + "/" + cd + " @ " + Common.formatTime_1((long)(time_counter / 90.0f) )); /** * add frames at the end */ if (es_streamtype == CommonParsing.MPEG_AUDIO && AddFrames && vptsdata && awrite && (w < vptsval.length)) { timeline += audio.getFrameTimeLength(); addf[0] = (long) time_counter; silent_Frame[0] = new byte[audio.getSizeBase()]; //silence without padd, std silent_Frame[1] = new byte[audio.getSize()]; //silence with padd for 22.05, 44.1 for (int a = 0; a < 2; a++) { System.arraycopy(header_copy,0, silent_Frame[a], 0, 4); //copy last header data silent_Frame[a][1] |= 1; //mark noCRC silent_Frame[a][2] |= (a * 2); //set padding bit } int padding_counter = 1; //count padding while (w < vptsval.length) { while ( vtime[w + 1] > time_counter && (double) Math.abs(vtime[w + 1] - time_counter) > (double) audio.getFrameTimeLength() / 2.0 ) { if (FillGapsWithLastFrame) { //add_copy prev. frame if (audio.getLayer() > 0 && DecodeMpgAudio) { audiooutL.write(MpaDecoder.decodeArray(copyframe[0])); if (MpaConversionMode >= 4) audiooutR.write(MpaDecoder.get2ndArray()); } else if (MpaConversionMode > 0) { //modify frame newframes = MPAConverter.modifyframe(copyframe[0], MpaConversionMode); audiooutL.write(newframes[0]); if (MpaConversionMode >= 4) audiooutR.write(newframes[1]); /** * RIFF */ if (AddRiffToMpgAudio || AddRiffToMpgAudioL3) { riffw[0].RiffData(audio.parseRiffData(newframes[0])); if (MpaConversionMode >= 4) riffw[1].RiffData(audio.parseRiffData(newframes[1])); } } else { audiooutL.write(copyframe[0]); /** * RIFF */ if (AddRiffToMpgAudio || AddRiffToMpgAudioL3) riffw[0].RiffData(audio.parseRiffData(copyframe[0])); } } else { //add silence //if (padding_counter==padding) padding_counter=0; //reset padd count //else if (samplerate==0) padding_counter++; //count padding if (audio.getLayer() > 0 && DecodeMpgAudio) { audiooutL.write(MpaDecoder.decodeArray(silent_Frame[(padding_counter > 0) ? 0 : 1])); if (MpaConversionMode >= 4) audiooutR.write(MpaDecoder.get2ndArray()); } else if (MpaConversionMode > 0) { //modify frame newframes = MPAConverter.modifyframe(silent_Frame[(padding_counter > 0) ? 0 : 1], MpaConversionMode); audiooutL.write(newframes[0]); if (MpaConversionMode >= 4) audiooutR.write(newframes[1]); /** * RIFF */ if (AddRiffToMpgAudio || AddRiffToMpgAudioL3) { riffw[0].RiffData(audio.parseRiffData(newframes[0])); if (MpaConversionMode >= 4) riffw[1].RiffData(audio.parseRiffData(newframes[1])); } } else { audiooutL.write(silent_Frame[(padding_counter > 0) ? 0 : 1]); /** * RIFF */ if (AddRiffToMpgAudio || AddRiffToMpgAudioL3) riffw[0].RiffData(audio.parseRiffData(silent_Frame[(padding_counter > 0) ? 0 : 1])); } } timeline += audio.getFrameTimeLength(); cd++; frame_counter++; addf[1]++; time_counter += audio.getFrameTimeLength(); Common.getGuiInterface().showExportStatus(Resource.getString("audio.status.add")); if (Debug) { System.out.println("(4)audio frames: wri/pre/skip/ins/add " + frame_counter + "/" + cb + "/" + ce + "/" + cc + "/" + cd + " @ " + Common.formatTime_1((long)(time_counter / 90.0f) )); System.out.print(" t)" + (long)(timeline - audio.getFrameTimeLength()) + " w)" + w); } } w += 2; } w -= 2; timeline -= audio.getFrameTimeLength(); if (Debug) System.out.println(" eot_video:" + (vptsval[w + 1] / 90) + "ms, eot_audio:" + ((timeline) / 90) + "ms "); } //end add mpa /** * PCM Audio */ if (es_streamtype == CommonParsing.LPCM_AUDIO) { // parse header frame = new byte[1000]; audioin.read(frame); audio.parseHeader(frame, 0); audioin.unread(frame, audio.getEmphasis(), 1000 - audio.getEmphasis()); Common.setMessage(Resource.getString("audio.msg.source", audio.saveAndDisplayHeader()) + " " + Common.formatTime_1((long)(time_counter / 90.0f))); layertype = WAV_AUDIOSTREAM; n = audio.getEmphasis(); //start of pcm data long pcm_end_pos = audio.getEmphasis() + audio.getSizeBase(); //whole sample data size timeline = ptsval[0]; audiooutL.write(audio.getRiffHeader()); long sample_bytes; long skip_bytes; long sample_pts; long skip_pts; int sample_size; int read_size = 960000 / audio.getMode(); // Size/8 * Channel = bytes per sample // 16bit/8 * 2 = 4 // per sample: Audio.Time_length = 90000.0 / Samplefre // 48000hz = 1.875 ticks (of 90khz) 1 frame = 192 samples = 360ticks // 44100hz = 2.040816 for (int f = 0; f < ptsval.length - 1; f++) { for (int a = 0; a < vptsval.length; a+=2) { while (pause()) {} if (CommonParsing.isProcessCancelled()) { CommonParsing.setProcessCancelled(false); job_processing.setSplitSize(0); break bigloop; } if (vptsdata && vptsval[a] < timeline) //jump back (not yet) or insert silent samples { sample_pts = vptsval[a + 1] > timeline ? timeline - vptsval[a] : vptsval[a + 1] - vptsval[a]; sample_bytes = (long)Math.round(1.0 * audio.getSamplingFrequency() * sample_pts / 90000.0) * audio.getMode(); if (Debug) System.out.println("a " + sample_pts + "/" + sample_bytes + "/" + n + "/" + timeline); for (long sample_pos = 0; sample_pos < sample_bytes; ) { sample_size = (sample_bytes - sample_pos) >= read_size ? read_size : (int)(sample_bytes - sample_pos); frame = new byte[sample_size]; sample_pos += sample_size; audiooutL.write(frame); } time_counter += sample_pts; frame_counter += (sample_bytes / audio.getMode()); Common.setFps(frame_counter); if (vptsval[a + 1] > timeline) { sample_pts = vptsval[a + 1] - timeline; sample_bytes = (long) Math.round(1.0 * audio.getSamplingFrequency() * sample_pts / 90000.0) * audio.getMode(); if (Debug) System.out.println("b " + sample_pts + "/" + sample_bytes + "/" + n + "/" + timeline); for (long sample_pos = 0; sample_pos < sample_bytes; ) { sample_size = (sample_bytes - sample_pos) >= read_size ? read_size : (int)(sample_bytes - sample_pos); frame = new byte[sample_size]; audioin.read(frame); sample_pos += sample_size; audiooutL.write(frame); } n += sample_bytes; timeline += sample_pts; time_counter += sample_pts; frame_counter += (sample_bytes / audio.getMode()); } } else { skip_pts = vptsdata ? vptsval[a] - timeline : 0; skip_bytes = (long)Math.round(1.0 * audio.getSamplingFrequency() * skip_pts / 90000.0) * audio.getMode(); sample_pts = vptsdata ? vptsval[a + 1] - vptsval[a] : (long)(1.0 * (audio.getSizeBase() / audio.getMode()) / audio.getSamplingFrequency() * 90000.0); sample_bytes = (long) Math.round(1.0 * audio.getSamplingFrequency() * sample_pts / 90000.0) * audio.getMode(); for (long skip_pos = 0; skip_pos < skip_bytes; ) skip_pos += audioin.skip(skip_bytes - skip_pos); n += skip_bytes; if (Debug) System.out.println("c " + skip_pts + "/" + skip_bytes + "/" + sample_pts + "/" + sample_bytes + "/" + n + "/" + timeline); for (long sample_pos = 0; sample_pos < sample_bytes; ) { sample_size = (sample_bytes - sample_pos) >= read_size ? read_size : (int)(sample_bytes - sample_pos); frame = new byte[sample_size]; audioin.read(frame); sample_pos += sample_size; audiooutL.write(frame); } n += sample_bytes; timeline += (skip_pts + sample_pts); time_counter += sample_pts; frame_counter += (sample_bytes / audio.getMode()); } if (Debug) System.out.println("(4w)audio frames: wri/pre/skip/ins/add " + frame_counter + "/" + cb + "/" + ce + "/" + cc + "/" + cd + " @ " + Common.formatTime_1((long)(time_counter / 90.0f) )); Common.updateProgressBar(n, audiosize); //yield(); if (Debug) System.out.println(" n" + n); } break; } } /** * restart decoding after a peak search */ if (es_streamtype == CommonParsing.MPEG_AUDIO && DecodeMpgAudio && MpaDecoder.PRESCAN && !MpaDecoder.RESET) { MpaDecoder.PRESCAN = false; MpaDecoder.NORMALIZE = false; return true; } break; } // end while bigloop if (addf[1] > 0) Common.setMessage(Resource.getString("audio.msg.summary.add", "" + addf[1], FramesToTime((int)addf[1], audio.getFrameTimeLength())) + " " + Common.formatTime_1(addf[0] / 90L)); Common.getGuiInterface().showExportStatus(Resource.getString("audio.status.finish")); String tc = Common.formatTime_1((long)(time_counter / 90.0f) ); Common.setMessage(Resource.getString("audio.msg.summary.frames", "" + frame_counter + "/" + cb + "/" + ce + "/" + cc + "/" + cd, "" + tc)); if (jss > 0) Common.setMessage(Resource.getString("audio.msg.summary.jstereo", "" + jss)); audioin.close(); silentFrameBuffer.close(); audiooutL.flush(); audiooutL.close(); audiooutR.flush(); audiooutR.close(); String[][] pureaudio = { { ".ac3",".mp1",".mp2",".mp3",".dts" }, { ".new.ac3",".new.mp1",".new.mp2",".new.mp3",".new.dts" } }; if (collection.getSettings().getBooleanProperty(Keys.KEY_ExternPanel_renameAudio)) { for (int g = 1; g < 4; g++) { pureaudio[0][g] = ".mpa"; pureaudio[1][g] = ".new.mpa"; } } if (DecodeMpgAudio && audio.getLayer() > 1) { if (MpaDecoder.WAVE) { for (int g = 1; g < 4; g++) { pureaudio[0][g] += ".wav"; pureaudio[1][g] += ".wav"; } } else if (AddAiffHeader) { for (int g = 1; g < 4; g++) { pureaudio[0][g] += ".aif"; pureaudio[1][g] += ".aif"; } } else { for (int g = 1; g < 4; g++) { pureaudio[0][g] += ".pcm"; pureaudio[1][g] += ".pcm"; } } } else if (AddRiffToMpgAudio || AddRiffToMpgAudioL3) { for (int g = 1; g < 4; g++) { pureaudio[0][g] += ".wav"; pureaudio[1][g] += ".wav"; } } if (AddRiffToAc3) { pureaudio[0][0] += ".wav"; pureaudio[1][0] += ".wav"; } else if (CreateDDWave) { pureaudio[0][0] += ".wav"; pureaudio[1][0] += ".wav"; pureaudio[0][4] += ".wav"; pureaudio[1][4] += ".wav"; } File ac3name = new File (fparent + pureaudio[isElementaryStream][0]); File mp1name = new File (fparent + pureaudio[isElementaryStream][1]); File mp2name = new File (fparent + pureaudio[isElementaryStream][2]); File mp3name = new File (fparent + pureaudio[isElementaryStream][3]); File mp2nameL = new File (fparent + "[L]" + pureaudio[0][2]); File mp2nameR = new File (fparent + "[R]" + pureaudio[0][2]); File dtsname = new File (fparent + pureaudio[isElementaryStream][4]); File wavname = new File (fparent + ".new.wav"); /*** make riff ***/ if (DecodeMpgAudio && es_streamtype == CommonParsing.MPEG_AUDIO && MpaDecoder.WAVE) { if (audio.getLayer() > 1) { MpaDecoder.fillRIFF(newnameL, FadeInOut, FadeInOutMillis); if (MpaConversionMode >= 4) MpaDecoder.fillRIFF(newnameR, FadeInOut, FadeInOutMillis); } else { MpaDecoder.deleteRIFF(newnameL); if (MpaConversionMode >= 4) MpaDecoder.deleteRIFF(newnameR); } } else if (DecodeMpgAudio && es_streamtype == CommonParsing.MPEG_AUDIO && AddAiffHeader) { if (audio.getLayer() > 1) { MpaDecoder.fillAiff(newnameL,(long)(time_counter / 90.0f), FadeInOut, FadeInOutMillis); if (MpaConversionMode >= 4) MpaDecoder.fillAiff(newnameR,(long)(time_counter / 90.0f), FadeInOut, FadeInOutMillis); } else { MpaDecoder.deleteAiff(newnameL); if (MpaConversionMode >= 4) MpaDecoder.deleteAiff(newnameR); } } else if ((AddRiffToMpgAudio || AddRiffToMpgAudioL3) && es_streamtype == CommonParsing.MPEG_AUDIO) { RandomAccessFile[] rifffile = { new RandomAccessFile(newnameL, "rw"), new RandomAccessFile(newnameR, "rw") }; riffw[0].Length( rifffile[0].length() , (long)(time_counter / 90.0f) ); riffw[1].Length( rifffile[1].length() , (long)(time_counter / 90.0f) ); rifffile[0].seek(0); rifffile[1].seek(0); if (AddRiffToMpgAudioL3) { rifffile[0].write(riffw[0].ACM()); if (MpaConversionMode >= 4) rifffile[1].write(riffw[1].ACM()); } else { rifffile[0].write(riffw[0].BWF()); if (MpaConversionMode >= 4) rifffile[1].write(riffw[1].BWF()); } rifffile[0].close(); rifffile[1].close(); } else if (AddRiffToAc3 && es_streamtype == CommonParsing.AC3_AUDIO) { RandomAccessFile rifffile = new RandomAccessFile(newnameL, "rw"); riffw[0].Length( rifffile.length() , (long)(time_counter / 90.0f) ); rifffile.seek(0); rifffile.write(riffw[0].AC3()); rifffile.close(); } else if (es_streamtype == CommonParsing.LPCM_AUDIO) audio.fillRiffHeader(newnameL); else if (CreateDDWave && es_streamtype == CommonParsing.AC3_AUDIO) audio.fillStdRiffHeader(newnameL, (long)(time_counter / 90.0f)); else if (CreateDDWave && es_streamtype == CommonParsing.DTS_AUDIO) audio.fillStdRiffHeader(newnameL, (long)(time_counter / 90.0f)); File audioout1 = new File(newnameL); File audioout2 = new File(newnameR); job_processing.countMediaFilesExportLength(audioout1.length()); job_processing.countMediaFilesExportLength(audioout2.length()); String audio_type[] = { "(ac3)", "(mp3)", "(mp2)", "(mp1)", "(dts)", "(pcm)" }; if (DecodeMpgAudio) audio_type[1] = audio_type[2] = "(pcm)"; String comparedata = ""; if (layertype < 0) layertype = NO_AUDIOSTREAM; else comparedata = Resource.getString("audio.msg.audio") + " " + job_processing.countAudioStream() + " " + audio_type[layertype] + ":\t" + frame_counter + " Frames\t" + tc + "\t" + infoPTSMatch(filename_pts, videofile_pts, vptsdata, ptsdata) + cb + "/" + ce + "/" + cc + "/" + cd; /** * */ switch (layertype) { case AC3_AUDIOSTREAM: if (ac3name.exists()) ac3name.delete(); if (audioout1.length() < 100) audioout1.delete(); else { Common.renameTo(audioout1, ac3name); Common.setMessage(Resource.getString("msg.newfile", "") + " '" + ac3name + "'"); job_processing.addSummaryInfo(comparedata + "\t'" + ac3name + "'"); } if (audioout2.length() < 100) audioout2.delete(); audiooutL.renameIddTo(ac3name); audiooutR.deleteIdd(); break; case MP3_AUDIOSTREAM: if ( mp3name.exists() ) mp3name.delete(); if (audioout1.length() < 100) audioout1.delete(); else { Common.renameTo(audioout1, mp3name); Common.setMessage(Resource.getString("msg.newfile", "") + " '" + mp3name + "'"); job_processing.addSummaryInfo(comparedata + "\t'" + mp3name + "'"); } if (audioout2.length() < 100) audioout2.delete(); audiooutL.renameIddTo(mp3name); audiooutR.deleteIdd(); break; case MP2_AUDIOSTREAM: if (MpaConversionMode >= 4) { if ( mp2nameL.exists() ) mp2nameL.delete(); if ( mp2nameR.exists() ) mp2nameR.delete(); if (audioout2.length() < 100) audioout2.delete(); else { Common.renameTo(audioout2, mp2nameR); Common.setMessage(Resource.getString("msg.newfile", Resource.getString("audio.msg.newfile.right")) + " '" + mp2nameR + "'"); job_processing.addSummaryInfo(comparedata + "\t'" + mp2nameR + "'"); } if (audioout1.length() < 100) audioout1.delete(); else { Common.renameTo(audioout1, mp2nameL); Common.setMessage(Resource.getString("msg.newfile", Resource.getString("audio.msg.newfile.left")) + " '" + mp2nameL + "'"); job_processing.addSummaryInfo(comparedata + "\t'" + mp2nameL + "'"); } audiooutL.renameIddTo(mp2nameL); audiooutR.renameIddTo(mp2nameR); } else { if ( mp2name.exists() ) mp2name.delete(); if (audioout1.length() < 100) audioout1.delete(); else { Common.renameTo(audioout1, mp2name); Common.setMessage(Resource.getString("msg.newfile", "") + " '" + mp2name + "'"); job_processing.addSummaryInfo(comparedata + "\t'" + mp2name + "'"); } if (audioout2.length() < 100) audioout2.delete(); audiooutL.renameIddTo(mp2name); audiooutR.deleteIdd(); } break; case MP1_AUDIOSTREAM: if ( mp1name.exists() ) mp1name.delete(); if (audioout1.length() < 100) audioout1.delete(); else { Common.renameTo(audioout1, mp1name); Common.setMessage(Resource.getString("msg.newfile", "") + " '" + mp1name + "'"); job_processing.addSummaryInfo(comparedata + "\t'" + mp1name + "'"); } if (audioout2.length() < 100) audioout2.delete(); audiooutL.renameIddTo(mp1name); audiooutR.deleteIdd(); break; case DTS_AUDIOSTREAM: if (dtsname.exists()) dtsname.delete(); if (audioout1.length() < 100) audioout1.delete(); else { Common.renameTo(audioout1, dtsname); Common.setMessage(Resource.getString("msg.newfile", "") + " '" + dtsname + "'"); job_processing.addSummaryInfo(comparedata + "\t'" + dtsname + "'"); } if (audioout2.length() < 100) audioout2.delete(); audiooutL.renameIddTo(dtsname); audiooutR.deleteIdd(); break; case WAV_AUDIOSTREAM: if (wavname.exists()) wavname.delete(); if (audioout1.length() < 100) audioout1.delete(); else { Common.renameTo(audioout1, wavname); Common.setMessage(Resource.getString("msg.newfile", "") + " '" + wavname + "'"); job_processing.addSummaryInfo(comparedata + "\t'" + wavname + "'"); } if (audioout2.length() < 100) audioout2.delete(); audiooutL.renameIddTo(wavname); audiooutR.deleteIdd(); break; case NO_AUDIOSTREAM: Common.setMessage(Resource.getString("audio.msg.noaudio")); audioout1.delete(); audioout2.delete(); audiooutL.deleteIdd(); audiooutR.deleteIdd(); break; } } catch (IOException e) { Common.setExceptionMessage(e); } Common.updateProgressBar(audiosize, audiosize); return false; } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamProcessBase.java0000600000175000017500000002351210354311752030160 0ustar supermariosupermario /* * @(#)StreamParser * * Copyright (c) 2005 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.File; import java.io.InputStream; import java.io.IOException; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.parser.CommonParsing; /** * main thread */ public class StreamProcessBase extends Object { public int ERRORCODE = 0; public int MainBufferSize = 8192000; /** * */ public StreamProcessBase() { init(); } /** * */ public void init() { MainBufferSize = Integer.parseInt(Common.getSettings().getProperty(Keys.KEY_MainBuffer)); if (MainBufferSize <= 0) MainBufferSize = 4096000; } /** * */ public boolean pause() { return Common.waitingMainProcess(); } /** * */ public String FramesToTime(int framenumber, double framelength) { return String.valueOf(Math.round(framenumber * framelength / 90.0)); } /** * loadTempVideoPts */ public long[][] loadTempVideoPts(String videofile_pts, boolean debug) { if (videofile_pts.equals("-1")) return null; if (debug) System.out.println("-> loading video PTS logfile..."); XInputFile xInputFile = new XInputFile(new File(videofile_pts)); int vlogsize = (int)xInputFile.length() / 16; long[][] vptsval = new long[2][vlogsize]; byte[] data = new byte[(int)xInputFile.length()]; int pos = 0; try { InputStream pts_file = xInputFile.getInputStream(); pts_file.read(data, 0, data.length); for (int i = 0; i < vlogsize; i += 2 ) { vptsval[0][i] = CommonParsing.getValue(data, pos, 8, !CommonParsing.BYTEREORDERING); pos += 8; vptsval[0][i + 1] = CommonParsing.getValue(data, pos, 8, !CommonParsing.BYTEREORDERING); pos += 8; vptsval[1][i] = CommonParsing.getValue(data, pos, 8, !CommonParsing.BYTEREORDERING); pos += 8; vptsval[1][i + 1] = CommonParsing.getValue(data, pos, 8, !CommonParsing.BYTEREORDERING); pos += 8; if (debug) System.out.println("#s " + i + " _" + vptsval[0][i] + " #e " + (i + 1) + " _" + vptsval[0][i + 1] + " /#s " + i + " _" + vptsval[1][i] + " #e " + (i + 1) + " _" + vptsval[1][i + 1]); } pts_file.close(); } catch (Exception e) { Common.setExceptionMessage(e); return null; } Common.setMessage(Resource.getString("video.msg.pts.start_end", Common.formatTime_1(vptsval[0][0] / 90)) + " " + Common.formatTime_1(vptsval[0][vptsval[0].length - 1] / 90)); return vptsval; } /** * loadTempOtherPts */ public long[][] loadTempOtherPts(String filename_pts, String message_1, String message_2, String message_3, String message_4, int es_streamtype, boolean ignoreErrors, boolean debug) { if (filename_pts.equals("-1")) return null; if (debug) System.out.println("-> loading PTS logfile..."); XInputFile xInputFile = new XInputFile(new File(filename_pts)); int logsize = (int)xInputFile.length() / 16; long[][] ptsval = new long[2][logsize + 1]; ptsval[0][logsize] = -1; ptsval[1][logsize] = -1; byte[] data = new byte[(int)xInputFile.length()]; int pos = 0; try { InputStream pts_file = xInputFile.getInputStream(); pts_file.read(data, 0, data.length); int aa = 0; long ptsVal; long ptsPos; for (int a = 0; a < logsize; a++) { ptsVal = CommonParsing.getValue(data, pos, 8, !CommonParsing.BYTEREORDERING); pos += 8; ptsPos = CommonParsing.getValue(data, pos, 8, !CommonParsing.BYTEREORDERING); pos += 8; if (debug) System.out.println(" #" + aa + "/" + a + " _" + ptsVal + " / " + ptsPos); if (aa > 0 && ptsVal <= ptsval[0][aa - 1]) { if (aa > 1 && Math.abs(ptsVal - ptsval[0][aa - 2]) < 150000 && Math.abs(ptsVal - ptsval[0][aa - 1]) > 500000) { aa--; if (debug) System.out.print(" "); } else { if (debug) System.out.print(" "); continue; } } ptsval[0][aa] = ptsVal; ptsval[1][aa] = ptsPos; aa++; } if (aa < logsize) { Common.setMessage(Resource.getString(message_1, " " + (logsize - aa))); long tmp[][] = new long[2][aa]; System.arraycopy(ptsval[0], 0, tmp[0], 0, aa); System.arraycopy(ptsval[1], 0, tmp[1], 0, aa); ptsval[0] = new long[aa + 1]; System.arraycopy(tmp[0], 0, ptsval[0], 0, aa); ptsval[0][aa]= -1; ptsval[1] = new long[aa + 1]; System.arraycopy(tmp[1], 0, ptsval[1], 0, aa); ptsval[1][aa]= -1; } pts_file.close(); if (es_streamtype == CommonParsing.TELETEXT && ((ptsval[0][0] == 0xFFFFFFFFL) || (ptsval[0][0] == 0))) { // missing pts values Common.setMessage(Resource.getString(message_4)); ignoreErrors = true; } if (ignoreErrors) { long[] tmp = { ptsval[0][0], ptsval[1][0] }; ptsval[0] = new long[2]; ptsval[0][0] = tmp[0]; ptsval[0][1]= - 1; ptsval[1] = new long[2]; ptsval[1][0] = tmp[1]; ptsval[1][1]= - 1; Common.setMessage(Resource.getString(message_2)); } } catch (Exception e) { Common.setExceptionMessage(e); return null; } Common.setMessage(Resource.getString(message_3, Common.formatTime_1(ptsval[0][0] / 90)) + " " + Common.formatTime_1(ptsval[0][ptsval[0].length - 2] / 90)); return ptsval; } /** * */ public int checkPTSMatch(long video_pts_values[], long data_pts_values[]) { if (data_pts_values[0] < video_pts_values[0]) { if (data_pts_values[data_pts_values.length - 2] < video_pts_values[0]) { /** * maybe does match later, jump just to end */ Common.setMessage(Resource.getString("checkpts.1st.latter")); return (data_pts_values.length - 2); } else { /** * maybe does match later, jump just to this position */ int end = data_pts_values.length - 1; for (int i = 0; i < end; i++) { if (data_pts_values[i + 1] > video_pts_values[0]) return i; } return 0; } } else { if (data_pts_values[0] >= video_pts_values[video_pts_values.length - 1]) { Common.setMessage(Resource.getString("checkpts.last.ends")); return -1; } /** * does match anywhere, no pre-jump */ else return 0; } } /** * */ public String infoPTSMatch(String filename_pts, String videofile_pts, boolean video_pts, boolean data_pts) { if ( !videofile_pts.equals("-1") && !filename_pts.equals("-1") && !video_pts && data_pts) return "? "; else return ""; } /** * synccheck A/V */ public boolean SyncCheck(int[] vw, double timecount, double timelength, long timeline, int mpf, long[] vptsval, long[] vtime, boolean awrite, boolean debug) { int v = vw[0]; int w = vw[1]; if (w < vptsval.length) { double ms1 = (double)(timeline - vptsval[w + 1]); double ms2 = (double)(timecount - vtime[w + 1]); if (debug) System.out.println("A " + awrite + "/" + v + "/" + w + "/ =1 " + mpf + "/" + vtime[w + 1] + "/" + timecount + " ~2 " + vptsval[w + 1] + "/" + timeline + " ~3 " + ms1 + "/" + ms2 + "/" + (ms2 - ms1)); if ( (double)Math.abs(ms2) <= timelength / 2.0 ) { awrite = false; w += 2; } else if ( (double)Math.abs(ms1) <= timelength / 2.0 ) { awrite = false; w += 2; } if (debug) System.out.println("B " + awrite + "/" + v + "/" + w); } if (v < vptsval.length) { boolean show = false; double ms3 = (double)(timeline - vptsval[v]); double ms4 = (double)(timecount - vtime[v]); if (debug) System.out.println("C " + awrite + "/" + v + "/" + w + "/ =4 " + mpf + "/" + vtime[v] + "/" + timecount + " ~5 " + vptsval[v] + "/" + timeline + " ~6 " + ms3 + "/" + ms4 + "/" + (ms4 - ms3)); if (!awrite && (double)Math.abs(ms3) <= timelength / 2.0 ) { awrite = true; show = true; v += 2; } else if (!awrite && (double)Math.abs( (double)Math.abs(ms4) - (double)Math.abs(ms3) ) <= timelength / 2.0 ) { awrite = true; show = true; v += 2; } if (debug) System.out.println("D " + awrite + "/" + v + "/" + w); if (v < vptsval.length && awrite && (timecount + (timelength / 2.0)) > vtime[v] ) awrite = false; if (debug) System.out.println("E " + awrite + "/" + v + "/" + w); if (show && awrite) Common.getGuiInterface().showAVOffset("" + (int)(ms3 / 90) + "/" + (int)(ms4 / 90) + "/" + (int)((ms4 - ms3) / 90)); } vw[0] = v; vw[1] = w; return awrite; } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamProcessLPCMAudio.java0000600000175000017500000002355210363526042031027 0ustar supermariosupermario/* * @(#)StreamParser * * Copyright (c) 2005-2006 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.io.PushbackInputStream; import java.io.RandomAccessFile; import java.io.ByteArrayOutputStream; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import java.util.Hashtable; import java.util.Date; import java.util.TimeZone; import java.text.DateFormat; import java.text.SimpleDateFormat; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.parser.StreamConverter; import net.sourceforge.dvb.projectx.parser.StreamDemultiplexer; import net.sourceforge.dvb.projectx.parser.StreamProcessBase; import net.sourceforge.dvb.projectx.audio.AudioFormat; import net.sourceforge.dvb.projectx.io.IDDBufferedOutputStream; /** * main thread */ public class StreamProcessLPCMAudio extends StreamProcessBase { /** * */ public StreamProcessLPCMAudio(JobCollection collection, XInputFile xInputFile, String filename_pts, String filename_type, String videofile_pts, int isElementaryStream) { super(); processStream(collection, xInputFile, filename_pts, filename_type, videofile_pts, isElementaryStream); } /** * LPCM stream */ private void processStream(JobCollection collection, XInputFile xInputFile, String filename_pts, String filename_type, String videofile_pts, int isElementaryStream) { String fchild = collection.getOutputName(xInputFile.getName()); String fparent = collection.getOutputNameParent(fchild); JobProcessing job_processing = collection.getJobProcessing(); String pcmfile = fparent + (isElementaryStream == CommonParsing.ES_TYPE ? ".new": "") + ".wav"; byte[] parser = new byte[16]; byte[] packet = new byte[0xFFFF]; long size = xInputFile.length(); long count = 0; long startPoint = 0; long time_difference = 0; long source_pts = 0; long new_pts = 0; long first_pts = -1; long packet_pts = 0; long ModeChangeCount = 0; boolean vptsdata = false; boolean ptsdata = false; boolean write = false; boolean missing_syncword = false; boolean newformat = false; boolean debug = collection.getSettings().getBooleanProperty(Keys.KEY_DebugLog); boolean message_2 = collection.getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg2); int samples = 0; int x = 0; int v = 0; int packetlength = 0; int parserlength = parser.length; AudioFormat LPCM_Audio = new AudioFormat(CommonParsing.LPCM_AUDIO); try { PushbackInputStream in = new PushbackInputStream(xInputFile.getInputStream(), 20); IDDBufferedOutputStream out = new IDDBufferedOutputStream( new FileOutputStream(pcmfile), 2048000); Common.setMessage(Resource.getString("lpcm.msg.develop")); Common.setMessage(Resource.getString("lpcm.msg.tmpfile", xInputFile.getName(), "" + size)); Common.updateProgressBar(Resource.getString("lpcm.progress") + " " + xInputFile.getName(), 0, 0); long[] ptsval = { 0 }; long[] ptspos = { 0 }; long[] vptsval = { 0 }; long[][] obj = loadTempVideoPts(videofile_pts, debug); if (obj != null) { vptsval = obj[0]; vptsdata = true; obj = null; } /*** * preloading audio PTS file is disabled, too big caused by too many PTS, will overload memory * pts is here inluded in each packet instead */ ptsdata = true; if (vptsdata && ptsdata) { //int jump = checkPTSMatch(vptsval, ptsval); //temp. check disabled int jump = 0; if (jump < 0) { Common.setMessage(Resource.getString("lpcm.msg.pts.mismatch")); vptsdata = false; x = 0; } else x = jump; } if (vptsdata && ptsdata) { Common.setMessage(Resource.getString("lpcm.msg.adjust.at.video")); time_difference = vptsval[0]; } if (!vptsdata && ptsdata) { Common.setMessage(Resource.getString("lpcm.msg.adjust.at.own")); time_difference = 0; } if (ptsdata) { source_pts = ptsval[x]; startPoint = ptspos[x]; } //don't need it anymore ptsval = null; ptspos = null; while (count < startPoint) count += in.skip(startPoint - count); out.write(LPCM_Audio.getRiffHeader()); //wav header readloop: while ( count < size ) { Common.updateProgressBar(count, size); //yield(); while (pause()) {} if (CommonParsing.isProcessCancelled()) { CommonParsing.setProcessCancelled(false); job_processing.setSplitSize(0); break readloop; } //special X header in.read(parser, 0, parserlength); // find "PCM" if (parser[0] != 0x50 || parser[1] != 0x43 || parser[2] != 0x4D) { if (message_2 && !missing_syncword) Common.setMessage(Resource.getString("lpcm.msg.syncword.lost") + " " + count); in.unread(parser, 1, parserlength - 1); missing_syncword = true; count++; continue readloop; } if (message_2 && missing_syncword) Common.setMessage(Resource.getString("lpcm.msg.syncword.found") + " " + count); missing_syncword = false; packet_pts = 0; packetlength = ((0xFF & parser[8])<<8 | (0xFF & parser[9])) - 6; // packetlength <= 0 not handled ! in.read(packet, 0, packetlength); count += parserlength; count += packetlength; // 5 bytes of packet pts, auslagern for (int a = 0; a < 5; a++) packet_pts |= (0xFFL & parser[3 + a])<<(a * 8); if (packet_pts != 0) source_pts = packet_pts; if (first_pts == -1) first_pts = source_pts; if (debug) System.out.println(" " + (count - packetlength) + "/ " + packetlength + "/ " + source_pts); if (LPCM_Audio.parseHeader(parser, 10) < 0) continue readloop; if (LPCM_Audio.compareHeader() > 0 || samples == 0 ) newformat = true; LPCM_Audio.saveHeader(); if (ptsdata) { write = !vptsdata; rangeloop: while (vptsdata && v < vptsval.length) //sample_start_pts must be in range ATM { if (source_pts < vptsval[v]) break rangeloop; else if (source_pts == vptsval[v] || source_pts < vptsval[v + 1]) { write = true; break rangeloop; } v += 2; if (v < vptsval.length) time_difference += (vptsval[v] - vptsval[v - 1]); } } else write = true; if (write) { new_pts = source_pts - time_difference; if (newformat) { if (ModeChangeCount < 100) Common.setMessage(Resource.getString("lpcm.msg.source", LPCM_Audio.displayHeader()) + " " + Common.formatTime_1( (long)(new_pts / 90.0f))); else if (ModeChangeCount == 100) Common.setMessage(Resource.getString("lpcm.msg.source.max")); ModeChangeCount++; newformat = false; //yield(); } Common.changeByteOrder(packet, 0, packetlength); if ((packetlength & 1) != 0) Common.setMessage(Resource.getString("lpcm.msg.error.align")); out.write(packet, 0, packetlength); samples++; Common.getGuiInterface().showExportStatus(Resource.getString("audio.status.write")); } else Common.getGuiInterface().showExportStatus(Resource.getString("audio.status.pause")); if (debug) System.out.println(" -> " + write + "/ " + v + "/ " + new_pts + "/ " + time_difference + "/ " + samples); Common.setFps(samples); } in.close(); out.flush(); out.close(); if (filename_pts.equals("-1") || ptsdata) Common.setMessage(Resource.getString("lpcm.msg.pts.start_end", Common.formatTime_1(first_pts / 90)) + " " + Common.formatTime_1(source_pts / 90)); Common.setMessage(Resource.getString("lpcm.msg.summary", " " + samples)); File pcmfile1 = new File(pcmfile); if (samples == 0) pcmfile1.delete(); else { long playtime = LPCM_Audio.fillRiffHeader(pcmfile); //update riffheader Common.setMessage(Resource.getString("msg.newfile") + " " + pcmfile); job_processing.countMediaFilesExportLength(pcmfile1.length()); job_processing.addSummaryInfo(Resource.getString("lpcm.summary", "" + job_processing.countPictureStream(), "" + samples, Common.formatTime_1(playtime)) + infoPTSMatch(filename_pts, videofile_pts, vptsdata, ptsdata) + "\t'" + pcmfile1 + "'"); } } catch (IOException e2) { Common.setExceptionMessage(e2); } } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamProcessSubpicture.java0000600000175000017500000005020610404674404031435 0ustar supermariosupermario/* * @(#)StreamParser * * Copyright (c) 2005-2006 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.io.PushbackInputStream; import java.io.RandomAccessFile; import java.io.ByteArrayOutputStream; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.PrintStream; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import java.util.Hashtable; import java.util.Date; import java.util.TimeZone; import java.util.Enumeration; import java.util.StringTokenizer; import java.text.DateFormat; import java.text.SimpleDateFormat; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.io.IDDBufferedOutputStream; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.parser.StreamConverter; import net.sourceforge.dvb.projectx.parser.StreamDemultiplexer; import net.sourceforge.dvb.projectx.parser.StreamProcessBase; import net.sourceforge.dvb.projectx.subtitle.Subpicture; import net.sourceforge.dvb.projectx.subtitle.BMP; import net.sourceforge.dvb.projectx.subtitle.Bitmap; import net.sourceforge.dvb.projectx.subtitle.Teletext; import net.sourceforge.dvb.projectx.thirdparty.Ifo; /** * main thread */ public class StreamProcessSubpicture extends StreamProcessBase { private final String subdecode_errors[] = { "", "", // -1 = correct decoded dvb-subpicture segments, can export "", // -2 = correct decoded dvb-subpicture segments, w/o export Resource.getString("subpicture.msg.error3"), // -3 = error while decoding dvb-subpicture Resource.getString("subpicture.msg.error4"), Resource.getString("subpicture.msg.error5"), Resource.getString("subpicture.msg.error6"), Resource.getString("subpicture.msg.error7"), Resource.getString("subpicture.msg.error8"), Resource.getString("subpicture.msg.error9") }; private String Extension = ".new"; private boolean debug; private boolean KeepOriginalTimecode; private boolean UseAdditionalOffset; private boolean ShowSubpictureWindow; private boolean Message_2; private int AdditionalOffset_Value; private int X_Offset = 0; private int Y_Offset = 0; private int DisplayMode = 0; private String SubpictureColorModel; private String PageId_Value; private String SubtitleExportFormat; /** * */ public StreamProcessSubpicture(String extension) { super(); Extension = extension; } /** * */ public StreamProcessSubpicture(JobCollection collection, XInputFile xInputFile, String filename_pts, String filename_type, String videofile_pts, int isElementaryStream) { super(); get_XY_Offset(collection, isElementaryStream); getDisplayMode(collection, isElementaryStream); String SubtitleExportFormat = collection.getSettings().getProperty(Keys.KEY_SubtitleExportFormat); processStream(collection, xInputFile, filename_pts, filename_type, videofile_pts, isElementaryStream, SubtitleExportFormat); // 2nd export format, new run SubtitleExportFormat = collection.getSettings().getProperty(Keys.KEY_SubtitleExportFormat_2); if (!SubtitleExportFormat.equalsIgnoreCase("null")) processStream(collection, xInputFile, filename_pts, filename_type, videofile_pts, isElementaryStream, SubtitleExportFormat); } /** * set new X with or without offset */ public void set_XY_Offset(int x_value, int y_value) { X_Offset = x_value; Y_Offset = y_value; } /** * set new X with or without offset */ private void get_XY_Offset(JobCollection collection, int isElementaryStream) { //if (isElementaryStream != CommonParsing.ES_TYPE) // return; StringTokenizer st = new StringTokenizer(collection.getSettings().getProperty(Keys.KEY_SubtitleMovePosition_Value), ","); int a = 0; int[] values = new int[2]; while (st.hasMoreTokens() && a < values.length) { try { values[a] = Integer.parseInt(st.nextToken()); } catch (Exception e) {} a++; } X_Offset = values[0]; Y_Offset = values[1]; } /** * set new display to be forced or not */ private void getDisplayMode(JobCollection collection, int isElementaryStream) { //if (isElementaryStream != CommonParsing.ES_TYPE) // return; DisplayMode = collection.getSettings().getIntProperty(Keys.KEY_SubtitleChangeDisplay); } /** * decoding subpicture stream, forces SUP, simple method for modifying a SUP stream from teletext process */ public void processStream(JobCollection collection, XInputFile xInputFile, int isElementaryStream) { processStream(collection, xInputFile, "-1", "sp", "-1", isElementaryStream, Keys.ITEMS_SubtitleExportFormat[7].toString()); } /** * decoding subpicture stream */ private void processStream(JobCollection collection, XInputFile xInputFile, String filename_pts, String filename_type, String videofile_pts, int isElementaryStream, String SubtitleExportFormat) { Subpicture subpicture = Common.getSubpictureClass(); JobProcessing job_processing = collection.getJobProcessing(); String fchild = isElementaryStream == CommonParsing.ES_TYPE ? collection.getOutputName(xInputFile.getName()) : xInputFile.getName(); String fparent = collection.getOutputNameParent(fchild); fparent += isElementaryStream == CommonParsing.ES_TYPE ? Extension : ""; String subfile = fparent + ".sup"; long size = xInputFile.length(); byte[] parse12 = new byte[12]; byte[] packet = new byte[0]; long count = 0; long startPoint = 0; long time_difference = 0; long display_time = 0; long source_pts = 0; long new_pts = 0; long first_pts = -1; long last_pts = 0; int x = 0; int pics = 0; int v = 0; int packetlength = 0; int export_type = 0; int last_pgc_set = 0; boolean vptsdata = false; boolean ptsdata = false; boolean write = false; boolean missing_syncword = false; boolean DVBpicture = false; debug = collection.getSettings().getBooleanProperty(Keys.KEY_DebugLog); KeepOriginalTimecode = isElementaryStream == CommonParsing.ES_TYPE ? true : collection.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_keepOriginalTimecode); UseAdditionalOffset = collection.getSettings().getBooleanProperty(Keys.KEY_additionalOffset); ShowSubpictureWindow = collection.getSettings().getBooleanProperty(Keys.KEY_showSubpictureWindow); Message_2 = collection.getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg2); AdditionalOffset_Value = collection.getSettings().getIntProperty(Keys.KEY_ExportPanel_additionalOffset_Value); SubpictureColorModel = collection.getSettings().getProperty(Keys.KEY_SubpictureColorModel); PageId_Value = collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_PageId_Value); // SubtitleExportFormat = collection.getSettings().getProperty(Keys.KEY_SubtitleExportFormat); try { if (ShowSubpictureWindow) Common.getGuiInterface().showSubpicture(); Hashtable user_table = new Hashtable(); ArrayList subpicture_colormodel = Common.getColorModelsList(); if (subpicture_colormodel.indexOf(SubpictureColorModel) > 2) user_table = Common.getUserColourTable(SubpictureColorModel); subpicture.reset(); subpicture.dvb.setIRD(2< move source picture position: X " + X_Offset + ", Y " + Y_Offset); if (DisplayMode != 0) Common.setMessage("-> set new picture display mode: " + Keys.ITEMS_SubtitleChangeDisplay[DisplayMode]); Common.updateProgressBar(Resource.getString("subpicture.progress") + " " + xInputFile.getName(), 0, 0); long[] ptsval = {0}; long[] ptspos = {0}; long[] vptsval = {0}; long pts_offset = UseAdditionalOffset ? 90L * AdditionalOffset_Value : 0; //System.gc(); long[][] obj = loadTempOtherPts(filename_pts, "subpicture.msg.discard", "audio.msg.pts.firstonly", "subpicture.msg.pts.start_end", "", CommonParsing.SUBPICTURE, false, debug); if (obj != null) { ptsval = obj[0]; ptspos = obj[1]; ptsdata = true; obj = null; } ptsdata = true; obj = loadTempVideoPts(videofile_pts, debug); if (obj != null) { vptsval = obj[0]; vptsdata = true; obj = null; } //System.gc(); if (vptsdata && ptsdata) { int jump = checkPTSMatch(vptsval, ptsval); if (jump < 0) { Common.setMessage(Resource.getString("subpicture.msg.pts.mismatch")); vptsdata = false; x = 0; } else x = jump; } if (vptsdata && ptsdata) { Common.setMessage(Resource.getString("subpicture.msg.adjust.at.video")); time_difference = vptsval[0]; } if (!vptsdata && ptsdata) { Common.setMessage(Resource.getString("subpicture.msg.adjust.at.own")); time_difference = 0; } if (ptsdata) { source_pts = ptsval[x]; startPoint = ptspos[x]; } //don't need it anymore ptsval = null; ptspos = null; while (count < startPoint) count += in.skip(startPoint-count); //yield(); readloop: while ( count < size ) { Common.updateProgressBar(count, size); //yield(); while (pause()) {} if (CommonParsing.isProcessCancelled()) { CommonParsing.setProcessCancelled(false); job_processing.setSplitSize(0); break readloop; } in.read(parse12, 0, 12); if (parse12[0] != 0x53 || parse12[1] != 0x50) // find "SP" { if (Message_2 && !missing_syncword) Common.setMessage(Resource.getString("subpicture.msg.syncword.lost") + " " + count); missing_syncword = true; count++; in.unread(parse12, 1, 11); continue readloop; } if (Message_2 && missing_syncword) Common.setMessage(Resource.getString("subpicture.msg.syncword.found") + " " + count); in.unread(parse12, 0, 12); missing_syncword = false; packetlength = ((0xFF & parse12[10])<<8 | (0xFF & parse12[11])) + 10; packet = new byte[packetlength]; in.read(packet); count += packetlength; source_pts = 0; for (int a = 0; a < 5; a++) // 5bytes for pts, maybe wrong source_pts |= (0xFFL & packet[2+a])<<(a*8); //DM15072004 081.7 int06 add, use add. time offset if not applied by class-piddemux (e.g. ES) if (filename_pts.equals("-1")) source_pts += pts_offset; // if (source_pts == pts_offset) // first pts would be 0, ever if (source_pts == pts_offset && first_pts != -1) source_pts = last_pts; else last_pts = source_pts; //remember pts of 1st packet if (first_pts == -1) first_pts = source_pts; if (debug) System.out.println(" " + (count - packetlength) + "/ " + packetlength + "/ " + source_pts); if (ptsdata) { write = !vptsdata; rangeloop: while (vptsdata && v < vptsval.length) //pic_start_pts must be in range ATM { if (source_pts < vptsval[v]) break rangeloop; else if (source_pts == vptsval[v] || source_pts < vptsval[v + 1]) { write = true; break rangeloop; } v += 2; if (v < vptsval.length) time_difference += (vptsval[v] - vptsval[v-1]); } } else write = true; if (!vptsdata && time_difference == 0 && !KeepOriginalTimecode) time_difference = source_pts; new_pts = source_pts - time_difference; if ((display_time = subpicture.decode_picture(packet, 10, Common.getGuiInterface().isSubpictureVisible(), job_processing.getStatusStrings(), new_pts, write, Common.getGuiInterface().isSubpictureVisible())) < -2) Common.setMessage(Resource.getString("subpicture.msg.error", subdecode_errors[Math.abs((int)display_time)], String.valueOf(count - packetlength))); if (debug) System.out.println("PTS: source " + Common.formatTime_1(source_pts / 90) + "(" + source_pts + ")" + " /new " + Common.formatTime_1(new_pts / 90) + "(" + new_pts + ")" + " / write: " + write + " / dec.state: " + display_time); if (display_time < 0) //dvb_subpic { if (!DVBpicture) Common.setMessage(Resource.getString("subpicture.msg.dvbsource")); DVBpicture = true; if (display_time == -1) // -1 full data, -2 forced end_time { String num = "00000" + pics; String outfile_base = fparent + "_st" + num.substring(num.length() - 5); String key, object_id_str, outfile; int object_id; for (Enumeration e = BMP.getKeys(); e.hasMoreElements() ; ) { key = e.nextElement().toString(); object_id = Integer.parseInt(key); object_id_str = Integer.toHexString(object_id).toUpperCase(); outfile = outfile_base + "p" + object_id_str; Bitmap bitmap = BMP.getBitmap(object_id); if (export_type == 0) //.sup out.write( subpicture.writeRLE(bitmap)); else //.son + .bmp { if (pics == 0) { String[] SONhead = Teletext.getSONHead(new File(subfile).getParent(), (long)CommonParsing.getVideoFramerate()); for (int a=0; a < SONhead.length; a++) print_out.println(SONhead[a]); } subpicture.updateUserColorTable(bitmap); outfile = BMP.buildBMP_palettized(outfile, bitmap, subpicture.getUserColorTable(), 256); job_processing.countMediaFilesExportLength(new File(outfile).length()); int pgc_values = subpicture.setPGClinks(); // a change in color_links if ((0xFFFF & pgc_values) != (0xFFFF & last_pgc_set)) { String pgc_colors = ""; for (int a = 0; a < 4; a++) pgc_colors += "" + (0xF & pgc_values>>>(a * 4)) + " "; print_out.println("Color\t\t(" + pgc_colors.trim() + ")"); } // a change in alpha_links if ((0xFFFF0000 & pgc_values) != (0xFFFF0000 & last_pgc_set)) { String pgc_alphas = ""; for (int a = 0; a < 4; a++) pgc_alphas += "" + (0xF & pgc_values>>>((4 + a) * 4)) + " "; print_out.println("Contrast\t(" + pgc_alphas.trim() + ")"); } last_pgc_set = pgc_values; print_out.println("Display_Area\t(" + Common.adaptString(bitmap.getX(), 3) + " " + Common.adaptString(bitmap.getY(), 3) + " " + Common.adaptString(bitmap.getMaxX(), 3) + " " + Common.adaptString(bitmap.getMaxY(), 3) + ")"); print_out.println(outfile_base.substring(outfile_base.length() - 4) + "\t\t" + Common.formatTime_2(bitmap.getInTime() / 90, (long)CommonParsing.getVideoFramerate()) + "\t" + Common.formatTime_2((bitmap.getInTime() / 90) + (bitmap.getPlayTime() * 10), (long)CommonParsing.getVideoFramerate()) + "\t" + new File(outfile).getName()); } //Common.setMessage(subpicture.getArea()); //BMP.buildBMP_24bit(outfile, key); Common.getGuiInterface().setSubpictureTitle(" " + Resource.getString("subpicture.preview.title.dvbexport", "" + bitmap.getPageId(), "" + pics, Common.formatTime_1(new_pts / 90)) + " " + Common.formatTime_1(bitmap.getPlayTime() * 10)); } if (!BMP.isEmpty()) Common.getGuiInterface().showExportStatus(Resource.getString("subpicture.status"), ++pics); BMP.clear(); } } else if (write) //dvd_subpic { for (int a = 0; a < 8; a++) packet[2 + a] = (byte)(0xFFL & new_pts>>>(a * 8)); //later, to allow overlapping on cut boundaries //if (display_time > 0) // packet = subpicture.setTime(packet,display_time); out.write(packet); Common.getGuiInterface().showExportStatus(Resource.getString("subpicture.status"), ++pics); Common.getGuiInterface().setSubpictureTitle(" " + Resource.getString("subpicture.preview.title.dvdexport", "" + pics, Common.formatTime_1(new_pts / 90)) + " " + Common.formatTime_1(display_time / 90)); String str = subpicture.isForced_Msg(); if (str != null) Common.setMessage(str + " " + Resource.getString("subpicture.msg.forced") + " " + pics); } else Common.getGuiInterface().setSubpictureTitle(" " + Resource.getString("subpicture.preview.title.noexport")); if (debug) System.out.println(" -> " + write + "/ " + v + "/ " + new_pts + "/ " + time_difference + "/ " + pics + "/ " + display_time); } in.close(); print_out.flush(); print_out.close(); out.flush(); out.close(); if (filename_pts.equals("-1")) Common.setMessage(Resource.getString("subpicture.msg.pts.start_end", Common.formatTime_1(first_pts / 90)) + " " + Common.formatTime_1(source_pts / 90)); Common.setMessage(Resource.getString("subpicture.msg.summary", "" + pics)); if (!DVBpicture && export_type == 1) { String renamed_file = subfile.substring(0, subfile.length() - 3) + "sup"; Common.renameTo(subfile, renamed_file); subfile = renamed_file; } File subfile1 = new File(subfile); if (pics == 0) subfile1.delete(); else { if (DVBpicture && export_type == 0) job_processing.countMediaFilesExportLength(Ifo.createIfo(subfile, subpicture.getUserColorTableArray())); else if (DVBpicture && export_type == 1) job_processing.countMediaFilesExportLength(new File( BMP.write_ColorTable(fparent, subpicture.getUserColorTable(), 256)).length()); Common.setMessage(Resource.getString("msg.newfile") + " " + subfile); job_processing.countMediaFilesExportLength(subfile1.length()); job_processing.addSummaryInfo(Resource.getString("subpicture.summary", "" + job_processing.countPictureStream(), "" + pics, infoPTSMatch(filename_pts, videofile_pts, vptsdata, ptsdata)) + "'" + subfile1 + "'"); } Common.updateProgressBar(size, size); } catch (IOException e2) { Common.setExceptionMessage(e2); } if (ShowSubpictureWindow) Common.getGuiInterface().hideSubpicture(); } } project-x/src/net/sourceforge/dvb/projectx/parser/StreamProcessTeletext.java0000600000175000017500000012015610411322072031075 0ustar supermariosupermario/* * @(#)StreamParser * * Copyright (c) 2005-2006 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.io.PushbackInputStream; import java.io.RandomAccessFile; import java.io.ByteArrayOutputStream; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import java.util.Hashtable; import java.util.Date; import java.util.TimeZone; import java.text.DateFormat; import java.text.SimpleDateFormat; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.common.JobCollection; import net.sourceforge.dvb.projectx.common.JobProcessing; import net.sourceforge.dvb.projectx.io.RawFile; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.parser.CommonParsing; import net.sourceforge.dvb.projectx.parser.StreamConverter; import net.sourceforge.dvb.projectx.parser.StreamDemultiplexer; import net.sourceforge.dvb.projectx.parser.StreamProcessBase; import net.sourceforge.dvb.projectx.parser.StreamProcessSubpicture; import net.sourceforge.dvb.projectx.subtitle.Teletext; import net.sourceforge.dvb.projectx.subtitle.UnicodeWriter; import net.sourceforge.dvb.projectx.subtitle.Subpicture; import net.sourceforge.dvb.projectx.thirdparty.Ifo; /** * main thread */ public class StreamProcessTeletext extends StreamProcessBase { private final int MEGARADIO = 0; private final int EXPORT_TEXT = 1; private final int EXPORT_SC = 2; private final int EXPORT_SUB = 3; private final int EXPORT_SRT = 4; private final int EXPORT_SSA = 5; private final int EXPORT_SUP = 6; private final int EXPORT_STL = 7; private final int EXPORT_SON = 8; private byte tmp_byte_value = -1; private int tmp_int_value = -1; /** * */ public StreamProcessTeletext(JobCollection collection, XInputFile xInputFile, String filename_pts, String filename_type, String videofile_pts, int isElementaryStream) { super(); String SubtitleExportFormat = collection.getSettings().getProperty(Keys.KEY_SubtitleExportFormat); processStream(collection, xInputFile, filename_pts, filename_type, videofile_pts, isElementaryStream, SubtitleExportFormat); // 2nd export format, new run SubtitleExportFormat = collection.getSettings().getProperty(Keys.KEY_SubtitleExportFormat_2); if (!SubtitleExportFormat.equalsIgnoreCase("null")) processStream(collection, xInputFile, filename_pts, filename_type, videofile_pts, isElementaryStream, SubtitleExportFormat); } /** * decoding teletext stream */ private void processStream(JobCollection collection, XInputFile xInputFile, String filename_pts, String filename_type, String videofile_pts, int isElementaryStream, String SubtitleExportFormat) { int[] SUP_Offset = { -1, -1 }; //1st + 2nd Offset long size = 0; boolean debug = collection.getSettings().getBooleanProperty(Keys.KEY_DebugLog); boolean Message_2 = collection.getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg2); boolean ShowSubpictureWindow = collection.getSettings().getBooleanProperty(Keys.KEY_showSubpictureWindow); boolean DecodeMegaradio = collection.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_decodeMegaradio); boolean ExportTextAsUnicode = collection.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_exportTextAsUnicode); boolean ExportTextAsUTF8 = collection.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_exportTextAsUTF8); boolean DecodeHiddenRows = collection.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_decodeHiddenRows); boolean KeepOriginalTimecode = collection.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_keepOriginalTimecode); //test boolean SpecialTermination = collection.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_specialTermination); //String SubtitleExportFormat = collection.getSettings().getProperty(Keys.KEY_SubtitleExportFormat); String SubtitleFont = collection.getSettings().getProperty(Keys.KEY_SubtitleFont); String Format_SUP_Values = collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_Format_SUP_Values); JobProcessing job_processing = collection.getJobProcessing(); Subpicture subpicture = Common.getSubpictureClass(); if (ShowSubpictureWindow && (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[6].toString()) || SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[7].toString()))) Common.getGuiInterface().showSubpicture(); if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[7].toString()) || SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[6].toString())) // SUP + SON, set variables SUP_Offset = subpicture.set(SubtitleFont, Format_SUP_Values); String[] userdefined_pages = { collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_TtxPage1), collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_TtxPage2), collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_TtxPage3), collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_TtxPage4), collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_TtxPage5), collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_TtxPage6), collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_TtxPage7), collection.getSettings().getProperty(Keys.KEY_SubtitlePanel_TtxPage8) }; for (int pn = 0; pn < userdefined_pages.length; pn++) { String page = "0"; if (!DecodeMegaradio) { page = userdefined_pages[pn]; if (page.equalsIgnoreCase("null")) continue; } else pn = userdefined_pages.length; String fchild = xInputFile.getName(); String fparent = collection.getOutputNameParent(fchild); size = xInputFile.length(); Common.getGuiInterface().initTtxPageMatrix(fchild); Teletext.clearEnhancements(); if (!DecodeMegaradio) fparent += "[" + page + "]"; String ttxfile; int subtitle_type; if (DecodeMegaradio) { ttxfile = fparent + ".mgr"; subtitle_type = MEGARADIO; } else if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[1].toString())) { ttxfile = fparent + ".sc"; subtitle_type = EXPORT_SC; } else if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[2].toString())) { ttxfile = fparent + ".sub"; subtitle_type = EXPORT_SUB; } else if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[3].toString())) { ttxfile = fparent + ".srt"; subtitle_type = EXPORT_SRT; } else if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[5].toString())) { ttxfile = fparent + ".ssa"; subtitle_type = EXPORT_SSA; } else if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[7].toString())) { ttxfile = fparent + ".sup"; subtitle_type = EXPORT_SUP; } else if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[4].toString())) { ttxfile = fparent + ".stl"; subtitle_type = EXPORT_STL; } else if (SubtitleExportFormat.equalsIgnoreCase(Keys.ITEMS_SubtitleExportFormat[6].toString())) //placeholder for .son export { ttxfile = fparent + ".ssa"; //.son subtitle_type = EXPORT_SSA; // 8 } else if (SubtitleExportFormat.equalsIgnoreCase("null")) continue; else // free format { ttxfile = fparent + ".txt"; subtitle_type = EXPORT_TEXT; } Common.setMessage(""); Common.setMessage(Resource.getString("teletext.msg.output") + " " + ttxfile.substring(ttxfile.length() - 3)); if (ExportTextAsUnicode && subtitle_type != EXPORT_SUP) Common.setMessage("-> " + Resource.getString(Keys.KEY_SubtitlePanel_exportTextAsUnicode[0])); if (ExportTextAsUTF8 && subtitle_type != EXPORT_SUP) Common.setMessage("-> " + Resource.getString(Keys.KEY_SubtitlePanel_exportTextAsUTF8[0])); if (DecodeHiddenRows) Common.setMessage("-> " + Resource.getString(Keys.KEY_SubtitlePanel_decodeHiddenRows[0])); if (KeepOriginalTimecode) Common.setMessage("-> " + Resource.getString(Keys.KEY_SubtitlePanel_keepOriginalTimecode[0])); if (SpecialTermination) Common.setMessage("-> " + Resource.getString(Keys.KEY_SubtitlePanel_specialTermination[0])); DateFormat timeformat_1 = new SimpleDateFormat("HH:mm:ss.SSS"); timeformat_1.setTimeZone(TimeZone.getTimeZone("GMT+0:00")); DateFormat timeformat_2 = new SimpleDateFormat("HH:mm:ss,SSS"); timeformat_2.setTimeZone(TimeZone.getTimeZone("GMT+0:00")); boolean vptsdata = false; boolean ptsdata = false; boolean write = false; boolean loadpage = false; boolean valid = false; long count = 0; long time_difference = 0; long source_pts = 0; long startPoint = 0; int page_value = subtitle_type == MEGARADIO ? 0x800 : Integer.parseInt(page, 16); int x = 0; int seiten = 0; int v = 0; int w = 0; String page_number = ""; String subpage_number = ""; char txline[]; try { PushbackInputStream in = new PushbackInputStream(xInputFile.getInputStream(), 94); BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(ttxfile), 655350); ByteArrayOutputStream byte_buffer = new ByteArrayOutputStream(); UnicodeWriter print_buffer = new UnicodeWriter(byte_buffer, ExportTextAsUnicode, ExportTextAsUTF8); Common.setMessage(Resource.getString("teletext.msg.tmpfile", xInputFile.getName(), "" + size)); Common.setMessage(Resource.getString("teletext.msg.search") + " " + (subtitle_type == MEGARADIO ? Resource.getString("teletext.msg.megaradio") : Resource.getString("teletext.msg.page") + " " + page)); Common.updateProgressBar(Resource.getString("teletext.progress") + " " + (subtitle_type == MEGARADIO ? Resource.getString("teletext.msg.megaradio") : Resource.getString("teletext.msg.page") + " " + page), 0, 0); long[] pts_value = {0}; long[] pts_position = {0}; long[] video_pts_value = {0}; long[] vtime = {0}; Common.getGuiInterface().showExportStatus(Resource.getString("teletext.status"), seiten); long[][] obj = loadTempOtherPts(filename_pts, "teletext.msg.discard", "audio.msg.pts.firstonly", "teletext.msg.pts.start_end", "teletext.msg.pts.missed", CommonParsing.TELETEXT, false, debug); if (obj != null) { pts_value = obj[0]; pts_position = obj[1]; ptsdata = true; obj = null; } obj = loadTempVideoPts(videofile_pts, debug); if (obj != null) { video_pts_value = obj[0]; vtime = obj[1]; vptsdata = true; obj = null; } // 1st line switch (subtitle_type) { case EXPORT_SC: print_buffer.println("Subtitle File Mark:"+((CommonParsing.getVideoFramerate()==3600L) ? "2" : "1")); print_buffer.flush(); byte_buffer.writeTo(out); byte_buffer.reset(); break; case EXPORT_SSA: String[] SSAhead = Teletext.getSSAHead(); for (int a = 0; a < SSAhead.length; a++) print_buffer.println(SSAhead[a]); print_buffer.flush(); byte_buffer.writeTo(out); byte_buffer.reset(); break; case EXPORT_STL: String[] STLhead = Teletext.getSTLHead(Common.getVersionName() + " on " + DateFormat.getDateInstance(DateFormat.MEDIUM).format(new Date(System.currentTimeMillis()))); for (int a = 0; a < STLhead.length; a++) print_buffer.println(STLhead[a]); print_buffer.flush(); byte_buffer.writeTo(out); byte_buffer.reset(); break; case EXPORT_SON: //DM14052004 081.7 int02 add, still unused! String[] SONhead = Teletext.getSONHead(new File(ttxfile).getParent(), (long)CommonParsing.getVideoFramerate()); for (int a = 0; a < SONhead.length; a++) print_buffer.println(SONhead[a]); print_buffer.flush(); byte_buffer.writeTo(out); byte_buffer.reset(); } if (vptsdata && ptsdata) { int jump = checkPTSMatch(video_pts_value, pts_value); if (jump < 0) { Common.setMessage(Resource.getString("teletext.msg.pts.mismatch")); vptsdata = false; x = 0; } else x = jump; } x = 0; //start at 0 if (ptsdata) { source_pts = pts_value[x]; startPoint = pts_position[x]; if (vptsdata) { Common.setMessage(Resource.getString("teletext.msg.adjust.at.video")); time_difference = video_pts_value[0]; } else { Common.setMessage(Resource.getString("teletext.msg.adjust.at.own")); time_difference = 0; } } while (count < startPoint) count += in.skip(startPoint-count); boolean missing_syncword = false; boolean vps = false; boolean page_match = false; boolean lastpage_match = false; int row = -1; int magazine = -1; int vbi = 0; int character_set = 0; int data_unit_id = -1; int required_data_unit_id = -1; byte packet[] = new byte[48]; Hashtable load_buffer = new Hashtable(); Hashtable write_buffer = new Hashtable(); Hashtable flags = new Hashtable(); ArrayList picture_String = new ArrayList(); String provider = ""; String program_title = ""; String vps_str = ""; readloop: while ( count < size ) { Common.updateProgressBar(count, size); while (pause()) {} if (CommonParsing.isProcessCancelled()) { CommonParsing.setProcessCancelled(false); job_processing.setSplitSize(0); break readloop; } in.read(packet); if (packet[1] != 0x2C && packet[47] != 0x2C && packet[1] != 0x5A && (0xFF & packet[1]) != 0x88 && (0xFF & packet[1]) != 0xFF) { if (Message_2 && !missing_syncword) Common.setMessage(Resource.getString("teletext.msg.syncword.lost") + " " + count); missing_syncword = true; count++; in.unread(packet, 1, 47); continue readloop; } /** * stuffing packet with size 0x5A + 2 */ else if (packet[1] == 0x5A && packet[0] == -1) { in.skip(0x5C - 48); count += 0x5C; continue readloop; } /** * stuffing packet with size 0x88 + 2 */ else if ((0xFF & packet[1]) == 0x88 && packet[0] == -1) { in.skip(0x8A - 48); count += 0x8A; continue readloop; } /** * stuffing packet without size value, skips std packet size 46 */ else if (packet[1] == -1 && packet[0] == -1) { in.unread(packet, 46, 2); count += 0x2E; continue readloop; } else in.unread(packet, 46, 2); if (Message_2 && missing_syncword) Common.setMessage(Resource.getString("teletext.msg.syncword.found") + " " + count); missing_syncword = false; count += 46; vps = false; valid = false; data_unit_id = 0xFF & packet[0]; switch (data_unit_id) { case 2: // 0x02 EBU non subtitle data case 3: // 0x03 EBU subtitle data valid = true; break; case 0xC3: // VPS valid = true; vps = true; break; case 0xFF: // hidden if (DecodeHiddenRows) valid = true; break; default: // others, unknown if (debug) System.out.println(" unkn_"+Integer.toHexString(0xFF & packet[0])+"/"+(count-46)); //continue readloop; } // logging if (debug) { System.out.println(); for (int a = 0; a < 46; a++) System.out.print(" " + ((0xFF & packet[a])<0x10 ? "0" : "") + Integer.toHexString(0xFF & packet[a]).toUpperCase()); System.out.println(); } if (!valid) continue readloop; vbi = ((0x20 & packet[2]) != 0 ? 0 : 313) + (0x1F & packet[2]); if (!vps) { tmp_int_value = (Teletext.hamming_8_4(packet[4]))<<4 | Teletext.hamming_8_4(packet[5]); if (tmp_int_value < 0) // decode error { row = -1; magazine = -1; } else { // row = 0xFF & Teletext.bytereverse((byte)((0xF & Teletext.hamming_8_4(packet[4]))<<4 | (0xF & Teletext.hamming_8_4(packet[5])))); row = 0xFF & Teletext.bytereverse((byte) tmp_int_value); magazine = (7 & row) == 0 ? 8 : (7 & row); row >>>= 3; } } else { if ((0x3F & packet[2]) != 0x30) continue readloop; /** * show vps status of VBI 16 in GUI */ String str = VBI.decodeVPS(packet, 2); if (str != null && !str.equals(vps_str)) { vps_str = str; if (collection.getSettings().getBooleanProperty(Keys.KEY_showTtxHeader)) //interactive checkbox Common.getGuiInterface().updateVpsLabel(vps_str); Common.setMessage(Resource.getString("teletext.msg.vps", str) + " " + Common.formatTime_1(source_pts / 90)); } continue readloop; } // X3/31.1 ttx provider if (magazine == 3 && row == 31 && packet[7] == 0x40 && packet[8] == 0x57 && provider.equals("")) { provider = Teletext.makestring(packet, 10, 34, 31, 0, 0, false).trim(); Common.setMessage(Resource.getString("teletext.msg.provider") + " " + provider); } // X8/30.0 program title else if (magazine == 8 && row == 30 && packet[7] == (byte)0xA8) { String str = Teletext.makestring(packet, 26, 20, 30, 0, 0, true).trim() + " "; if (!str.equals(program_title)) { program_title = str; Common.setMessage(Resource.getString("teletext.msg.program") + " " + program_title); } } if (row == 0) { int flag = 0; for (int a = 0; a < 6; a++) flag |= (0xF & Teletext.bytereverse((byte) Teletext.hamming_8_4(packet[8+a]) )>>>4 ) <<(a*4); page_number = Integer.toHexString(0xF & Teletext.bytereverse((byte) Teletext.hamming_8_4(packet[7]) )>>>4 ).toUpperCase() + Integer.toHexString(0xF & Teletext.bytereverse((byte) Teletext.hamming_8_4(packet[6]) )>>>4 ).toUpperCase(); int o[] = { 0xF, 7, 0xF, 3 }; subpage_number = ""; for (int a = 3; a > -1; a--) subpage_number += Integer.toHexString(o[a] & flag>>>(a*4)).toUpperCase(); flags.put("data_unit_id", "" + data_unit_id); flags.put("magazine", "" + magazine); flags.put("page_number", page_number); flags.put("subpage_number", subpage_number); flags.put("news", "" + (1 & flag>>>14)); flags.put("subtitle", "" + (1 & flag>>>15)); flags.put("erase", "" + (1 & flag>>>7)); flags.put("suppressed_head", "" + (1 & flag>>>16)); flags.put("update", "" + (1 & flag>>>17)); flags.put("interrupt", "" + (1 & flag>>>18)); flags.put("inhibit", "" + (1 & flag>>>19)); flags.put("magazine_serial", "" + (1 & flag>>>20)); flags.put("character_set", "" + (7 & flag>>>21)); // page_number matches -- subpage_numer currently always accepted if ( page.equalsIgnoreCase( Integer.toHexString(magazine) + page_number) ) { character_set = 7 & flag>>>21; page_match = true; } else page_match = false; Common.getGuiInterface().updateTtxPageMatrix("" + magazine + page_number); // show header_line in GUI if (collection.getSettings().getBooleanProperty(Keys.KEY_showTtxHeader) || debug) { String str = magazine + page_number + " " + subpage_number + " " + Teletext.makestring(packet, 14, 32, 0, (7 & flag>>>21), 0, true) + " " + program_title; if (collection.getSettings().getBooleanProperty(Keys.KEY_showTtxHeader)) //interactive checkbox Common.getGuiInterface().updateTtxHeader(str); if (debug) System.out.println(str); } if (debug) System.out.println(flags.toString()); } if (ptsdata) { write = !vptsdata; while (pts_position[x+1] != -1 && pts_position[x+1] <= count - 46) { x++; source_pts = pts_value[x]; } rangeloop: while (vptsdata && v < video_pts_value.length) //pic_start_pts must be in range ATM { if (source_pts < video_pts_value[v]) { //write_buffer.put("cut_in_time", "" + video_pts_value[v]); // save value for cuts break rangeloop; } else if (source_pts == video_pts_value[v] || source_pts < video_pts_value[v+1]) { write = true; break rangeloop; } v += 2; if (v < video_pts_value.length) { //write_buffer.put("cut_out_time", "" + video_pts_value[v-1]); // save value for cuts time_difference += (video_pts_value[v] - video_pts_value[v-1]); } } } else write = true; // logging if (debug) System.out.println("pos "+ (count-46) + "/vbi "+vbi+"/ "+magazine+"-"+row+"-"+page_number+"-"+subpage_number+"/pts "+source_pts+"/ "+timeformat_1.format(new Date(source_pts/90))+"/ "+Integer.toHexString(page_value)+"/wr "+write+"/lo "+loadpage+"/lastp "+lastpage_match+"/pagm "+page_match+"/v "+(v>>8) //row > 0, but not of current magazine continue readloop; if (row == 0) //accept all 0-rows of all magazines till now { boolean interrupt_loading = false; //stop loading if same magazine, but other page //stop loading if interrupted_flag by any page only if magazine_serial == 1, means rows of diff. pages of multiple magazines don't overlap by sent order if (page_match || magazine == page_value>>>8 || flags.get("magazine_serial").toString().equals("1") ) interrupt_loading = true; if (debug) System.out.println("int " + interrupt_loading +"/load "+ loadpage + "/wri "+ write + "/wb " + write_buffer.size() + "/lb " + load_buffer.size()); // page header does not interrupt an active loading if (!interrupt_loading) continue readloop; // megaradio_mode, magazine 8 only, other magazines are already ignored before page check if (subtitle_type == MEGARADIO) { switch (Integer.parseInt(page_number, 16)) { case 0xA: case 0xB: case 0xC: loadpage=true; } switch (Integer.parseInt(subpage_number, 16)) { case 0x0D: case 0x0E: case 0x1C: case 0x1D: //case 0x2A: case 0x2B: case 0x2C: case 0x2D: loadpage=false; } continue readloop; } // row 0 defines out_time of current buffered page forced by an interrupt event, // sets the out_time of displaying and write it out if (lastpage_match) { long out_time = source_pts - time_difference; /** * adapt out_time of page, if termination of it was detected later than 80ms after last row */ Object buffer_time = load_buffer.get("buffer_time"); if (buffer_time != null) { long l = Long.parseLong(buffer_time.toString()); if (source_pts - l > 7200) { out_time = l - time_difference + 7200; if (debug) System.out.println("termination for in_time too late, new out_time: " + out_time); } } if (write) //buffered page can be written { write_buffer.put("out_time", "" + out_time); while (true) { if ( !write_buffer.containsKey("active") ) break; if ( !write_buffer.containsKey("in_time") ) break; switch (subtitle_type) { case EXPORT_TEXT: // free print_buffer.print( "in_" + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) )); print_buffer.println( "|out_" + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) )); break; case EXPORT_SC: // SC print_buffer.print( Teletext.SMPTE( timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ), (long)CommonParsing.getVideoFramerate()) + "&"); print_buffer.print( Teletext.SMPTE( timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ), (long)CommonParsing.getVideoFramerate()) + "#"); break; case EXPORT_SUB: // SUB print_buffer.print( "{" + ( (long)(Long.parseLong( write_buffer.get("in_time").toString()) / CommonParsing.getVideoFramerate())) + "}"); print_buffer.print( "{" + ( (long)(Long.parseLong( write_buffer.get("out_time").toString()) / CommonParsing.getVideoFramerate())) + "}"); break; case EXPORT_SRT: // SRT print_buffer.println( "" + (seiten + 1)); print_buffer.print( timeformat_2.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) )); print_buffer.println(" --> " + timeformat_2.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) )); break; case EXPORT_SSA: // SSA print_buffer.print( Teletext.getSSALine()[0] + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ).substring(1, 11) + ","); print_buffer.print( timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ).substring(1, 11) + Teletext.getSSALine()[1]); break; case EXPORT_STL: // STL print_buffer.print( Teletext.SMPTE(timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ), (long)CommonParsing.getVideoFramerate()) + ","); print_buffer.print( Teletext.SMPTE(timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ), (long)CommonParsing.getVideoFramerate()) + ","); break; case EXPORT_SUP: // SUP long sup_in_time = Long.parseLong( write_buffer.get("in_time").toString() ); if ( sup_in_time >= 0 ) { for (int a = 1; a < 24; a++) if ( write_buffer.containsKey("" + a) ) picture_String.add(write_buffer.get("" + a)); while (picture_String.size() > subpicture.getMaximumLines()) // max. lines as defined picture_String.remove(0); subpicture.showPicTTX( picture_String.toArray(), job_processing.getStatusStrings()); byte_buffer.write( subpicture.writeRLE( sup_in_time, 0xB4)); // alias duration 1.800 sec if out_time is missing if ( write_buffer.containsKey("out_time") ) out.write(subpicture.setTime( byte_buffer.toByteArray(), Long.parseLong( write_buffer.get("out_time").toString()))); } picture_String.clear(); } int b = 0; for (int a = 1; subtitle_type != EXPORT_SUP && a < 24; a++) { if ( !write_buffer.containsKey("" + a) ) continue; String str = write_buffer.get("" + a).toString(); switch (subtitle_type) { case EXPORT_TEXT: // free case EXPORT_SRT: // SRT print_buffer.println(str); break; case EXPORT_SC: // SC print_buffer.print(str); break; case EXPORT_SUB: // SUB case EXPORT_STL: // STL print_buffer.print( (b > 0 ? "|" : "") + str); break; case EXPORT_SSA: // SSA print_buffer.print( (b > 0 ? "\\n" : "") + str); } b++; } if (subtitle_type != EXPORT_SUP && b > 0) { print_buffer.println(); print_buffer.flush(); byte_buffer.writeTo(out); } seiten++; Common.getGuiInterface().showExportStatus(Resource.getString("teletext.status"), seiten); break; } } byte_buffer.reset(); write_buffer.clear(); } lastpage_match = page_match; // row 0 defines completion of current page to buffer, // sets the in_time of displaying but cannot write it w/o still unknown out_time if (loadpage) { write_buffer.clear(); if (!vptsdata && time_difference == 0 && !KeepOriginalTimecode) time_difference = source_pts; long in_time = source_pts - time_difference; boolean rows = false; /** * adapt in_time of page, if termination of it was detected later than 80ms after last row */ Object buffer_time = load_buffer.get("buffer_time"); if (buffer_time != null) { long l = Long.parseLong(buffer_time.toString()); if (source_pts - l > 7200) { in_time = l - time_difference + 7200; if (debug) System.out.println("termination too late, new in_time: " + in_time); } } // copy keys+values to clear for next page, only row 1..23 used instead of 0..31 for (int a = 1; a < 24; a++) { if ( !load_buffer.containsKey("" + a) ) continue; rows = true; // non blank page write_buffer.put("" + a, load_buffer.get("" + a)); } if (rows && write) // if false, in_time has to be set/updated at synccheck above until an exported gop pts area write_buffer.put("in_time", "" + in_time); if (!rows) lastpage_match = false; else write_buffer.put("active", "1"); Teletext.clearEnhancements(); load_buffer.clear(); } loadpage = page_match; /** * test 0903 * updates current timestamp of last packet */ if (SpecialTermination) load_buffer.put("buffer_time", String.valueOf(source_pts)); // logging if (debug) System.out.println("lo " + loadpage + "/lp_p "+lastpage_match+"/pg_m "+page_match+"/wbuf: " + write_buffer.toString()); continue readloop; } // only rows > 0 // logging if (debug) System.out.println("load " + loadpage + "/lbuf " + load_buffer.toString()); // ignore if row is not of expected magazine if (magazine != page_value>>>8) continue readloop; // load and filter re-defined chars from X26/0..15 triplets if (row > 23 && subtitle_type != 0) { if (row == 29 || loadpage) Teletext.setEnhancements(packet, row, character_set); continue readloop; } if (!loadpage) continue readloop; if (subtitle_type == MEGARADIO) // megaradio, simple decode the bytes of row 1..23 { for (int b = (row == 1) ? 17: 0; row < 24 && b < 39; b++) // framebytes to MSB out.write(Teletext.bytereverse(packet[7+b])); continue readloop; } // decode row 1..23 , 0=header, 24 fasttext labels, 25 supressedheader, >26 non text packets String str = null; int[] picture_data = null; switch (subtitle_type) { case EXPORT_TEXT: str = Teletext.makestring(packet, 6, 40, row, character_set, 0, true); break; case EXPORT_SC: case EXPORT_STL: case EXPORT_SUB: case EXPORT_SRT: str = Teletext.makestring(packet, 6, 40, row, character_set, 0, true).trim(); break; case EXPORT_SSA: str = Teletext.makestring(packet, 6, 40, row, character_set, 1, true).trim(); break; case EXPORT_SUP: picture_data = Teletext.makepic(packet, 6, 40, row, character_set, true); } if (str != null && !str.equals("")) load_buffer.put("" + row, str); else if (picture_data != null) load_buffer.put("" + row, picture_data); if (debug) System.out.println("row " + row + ": " + str + "/lb " + load_buffer.size()); /** * updates current timestamp of last packet */ load_buffer.put("buffer_time", String.valueOf(source_pts)); } // return to read next packet //write out last page in buffer if (!write_buffer.isEmpty() && write) { long out_time = (vptsdata ? video_pts_value[video_pts_value.length - 1] : source_pts) - time_difference; write_buffer.put("out_time", "" + out_time); while (true) { if ( !write_buffer.containsKey("active") || !write_buffer.containsKey("in_time") ) break; switch (subtitle_type) { case EXPORT_TEXT: // free print_buffer.print( "in_" + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) )); print_buffer.println( "|out_" + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) )); break; case EXPORT_SC: // SC print_buffer.print( Teletext.SMPTE(timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ), (long)CommonParsing.getVideoFramerate()) + "&"); print_buffer.print( Teletext.SMPTE(timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ), (long)CommonParsing.getVideoFramerate()) + "#"); break; case EXPORT_SUB: // SUB print_buffer.print( "{" + ( (long)(Long.parseLong( write_buffer.get("in_time").toString()) / CommonParsing.getVideoFramerate())) + "}"); print_buffer.print( "{" + ( (long)(Long.parseLong( write_buffer.get("out_time").toString()) / CommonParsing.getVideoFramerate())) + "}"); break; case EXPORT_SRT: // SRT print_buffer.println( "" + (seiten + 1)); print_buffer.print( timeformat_2.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) )); print_buffer.println(" --> " + timeformat_2.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) )); break; case EXPORT_SSA: // SSA print_buffer.print( Teletext.getSSALine()[0] + timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ).substring(1, 11) + ","); print_buffer.print( timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ).substring(1, 11) + Teletext.getSSALine()[1]); break; case EXPORT_STL: // STL print_buffer.print( Teletext.SMPTE(timeformat_1.format( new Date( Long.parseLong( write_buffer.get("in_time").toString()) / 90) ), (long)CommonParsing.getVideoFramerate()) + ","); print_buffer.print( Teletext.SMPTE(timeformat_1.format( new Date( Long.parseLong( write_buffer.get("out_time").toString()) / 90) ), (long)CommonParsing.getVideoFramerate()) + ","); break; case EXPORT_SUP: // SUP long sup_in_time = Long.parseLong( write_buffer.get("in_time").toString() ); if ( sup_in_time >= 0 ) { for (int a = 1; a < 24; a++) if ( write_buffer.containsKey("" + a) ) picture_String.add(write_buffer.get("" + a)); while (picture_String.size() > subpicture.getMaximumLines()) picture_String.remove(0); subpicture.showPicTTX( picture_String.toArray(), job_processing.getStatusStrings()); byte_buffer.write( subpicture.writeRLE( sup_in_time, 0xB4)); // alias duration 2.000 sec if out_time is missing out.write(subpicture.setTime( byte_buffer.toByteArray(), Long.parseLong( write_buffer.get("out_time").toString()))); } picture_String.clear(); } int b = 0; for (int a = 1; subtitle_type != EXPORT_SUP && a < 24; a++) { if ( !write_buffer.containsKey("" + a) ) continue; String str = write_buffer.get("" + a).toString(); switch (subtitle_type) { case EXPORT_TEXT: // free case EXPORT_SRT: // SRT print_buffer.println(str); break; case EXPORT_SC: // SC print_buffer.print(str); break; case EXPORT_SUB: // SUB case EXPORT_STL: // STL print_buffer.print( (b > 0 ? "|" : "") + str); break; case EXPORT_SSA: // SSA print_buffer.print( (b > 0 ? "\\n" : "") + str); } b++; } if (subtitle_type != EXPORT_SUP && b > 0) { print_buffer.println(); print_buffer.flush(); byte_buffer.writeTo(out); } seiten++; Common.getGuiInterface().showExportStatus(Resource.getString("teletext.status"), seiten); break; } } if (debug) System.out.println(); Common.setMessage(Resource.getString("teletext.msg.summary", "" + seiten, page)); if (seiten > 0) Common.setMessage(Resource.getString("msg.newfile") + " " + ttxfile); write_buffer.clear(); in.close(); print_buffer.flush(); print_buffer.close(); byte_buffer.flush(); byte_buffer.close(); out.flush(); out.close(); File ttxfile1 = new File(ttxfile); if (subtitle_type != MEGARADIO && seiten==0) ttxfile1.delete(); else if (subtitle_type == MEGARADIO) { String pts_file = fparent + ".pts"; RandomAccessFile log = new RandomAccessFile(pts_file, "rw"); log.writeLong(0L); log.writeLong(0L); log.close(); Common.setMessage(ttxfile); Common.setMessage(Resource.getString("working.filetype", Keys.ITEMS_FileTypes[CommonParsing.ES_MPA_TYPE])); // audiofile goes to synch methode new StreamProcess(CommonParsing.MPEG_AUDIO, collection, ttxfile, pts_file, "mp", "-1"); new File(ttxfile).delete(); new File(pts_file).delete(); return; } else { if (subtitle_type == EXPORT_SUP) Ifo.createIfo(ttxfile, subpicture.getUserColorTableArray()); job_processing.countMediaFilesExportLength(ttxfile1.length()); job_processing.addSummaryInfo(Resource.getString("teletext.summary", "" + job_processing.countPictureStream(), "" + seiten, "" + page, infoPTSMatch(filename_pts, videofile_pts, vptsdata, ptsdata)) + "'" + ttxfile1 + "'"); } } catch (IOException e2) { Common.setExceptionMessage(e2); } //2nd offset applies if (subtitle_type == EXPORT_SUP && SUP_Offset[1] >= 0) { Common.setMessage(""); Common.setMessage(Resource.getString("teletext.msg.newrun") + ": " + SUP_Offset[1]); StreamProcessSubpicture streamprocess = new StreamProcessSubpicture("[P1]"); streamprocess.set_XY_Offset(0, SUP_Offset[0] - SUP_Offset[1]); //offset x +- 0, y = 32 - 96 (= -64 e.g.) streamprocess.processStream(collection, new XInputFile(new File(ttxfile)), CommonParsing.ES_TYPE); } } // end for Common.updateProgressBar(size, size); if (ShowSubpictureWindow) Common.getGuiInterface().hideSubpicture(); } } project-x/src/net/sourceforge/dvb/projectx/parser/StripAudio.java0000600000175000017500000001245610351107454026662 0ustar supermariosupermario/* * @(#)StripAudio * * Copyright (c) 2005 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.PushbackInputStream; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.File; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.parser.CommonParsing; public class StripAudio extends Object { private byte[] DD_header = { 0x72, (byte)0xF8, 0x1F, 0x4E, 1, 0, 0, 0 }; private byte[] DTS44_header = { (byte)0xFF, 0x1F, 0, (byte)0xE8 }; private byte[] DTS48_header = { (byte)0xFE, 0x7F, 01, (byte)0x80 }; private boolean isAC3 = false; private boolean isDTS = false; private boolean isDTS48 = false; private long val; /** * */ public StripAudio() {} /** * */ public XInputFile process(XInputFile xInputFile) { String temp_file = xInputFile.toString() + "[stripped].$es$"; XInputFile newXInputFile; try { PushbackInputStream in = new PushbackInputStream(xInputFile.getInputStream(), 8); BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream(temp_file), 5096000); int sector = 0; byte[] data = new byte[0x1800]; in.skip(0x2C); //std pcm wave header, already known through streaminfo for (int ret, len;;) { ret = in.read(data, 0, 8); if (ret < 8) break; if (!verifyHeader(data)) { in.unread(data, 1, 7); continue; } if (isAC3) { len = (0xFF & data[7])<<8 | (0xFF & data[6]); len >>>= 3; ret = in.read(data, 8, len); sector++; if (ret < len) { Common.setMessage("!> not enough data in sector " + sector + ", dropped..", true); continue; } Common.changeByteOrder(data, 8, len + 8); out.write(data, 8, len); in.skip(0x1800 - len - 8); } else if (isDTS) { len = 0x1000; ret = in.read(data, 8, len - 8); sector++; if (ret < len - 8) { Common.setMessage("!> not enough data in sector " + sector + ", dropped..", true); continue; } int j = 0; // dts44 with padding if (!isDTS48) { for (int i = 0, k; i < len; i += 8, j += 7) { val = (0xFFL & data[i])<<42; val |= (0x3FL & data[i + 1])<<50; val |= (0xFFL & data[i + 2])<<28; val |= (0x3FL & data[i + 3])<<36; val |= (0xFFL & data[i + 4])<<14; val |= (0x3FL & data[i + 5])<<22; val |= (0xFFL & data[i + 6]); val |= (0x3FL & data[i + 7])<<8; CommonParsing.setValue(data, j, 7, !CommonParsing.BYTEREORDERING, val); } } // dts48 else { j = len; Common.changeByteOrder(data, 0, len); } out.write(data, 0, j); } } in.close(); out.flush(); out.close(); } catch (IOException e) { Common.setExceptionMessage(e); return null; } if (isAC3) return finish(temp_file, xInputFile.toString() + "[stripped].ac3"); else if (isDTS) return finish(temp_file, xInputFile.toString() + "[stripped].dts"); return null; } /** * */ private XInputFile finish(String temp_file, String new_file) { File file = new File(new_file); if (file.exists()) file.delete(); Common.renameTo(new File(temp_file), file); return (new XInputFile(file)); } /** * */ private boolean verifyHeader(byte[] header) { if (!isAC3 && !isDTS) { isAC3 = getAC3(header); if (!isAC3) isDTS = getDTS(header); } if (isAC3) return getAC3(header); if (isDTS) return getDTS(header); return false; } /** * */ private boolean getAC3(byte[] header) { for (int i = 0; i < 6; i++) if (DD_header[i] != header[i]) return false; return true; } /** * */ private boolean getDTS(byte[] header) { if (!isDTS) isDTS48 = getDTS48(header); if (isDTS48) return getDTS48(header); for (int i = 0; i < 4; i++) if (DTS44_header[i] != header[i]) return false; return true; } /** * */ private boolean getDTS48(byte[] header) { for (int i = 0; i < 4; i++) if (DTS48_header[i] != header[i]) return false; return true; } } project-x/src/net/sourceforge/dvb/projectx/parser/StripRelook.java0000600000175000017500000001076310362050424027047 0ustar supermariosupermario/* * @(#)StripRelook * * Copyright (c) 2005 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import java.io.PushbackInputStream; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.File; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.parser.CommonParsing; public class StripRelook extends Object { private boolean debug = false; private int type = 0; /** * */ public StripRelook(int value) { debug = Common.getSettings().getBooleanProperty(Keys.KEY_DebugLog); type = value; } /** * */ public XInputFile[] process(XInputFile xInputFile, String output) { String parent = output + System.getProperty("file.separator") + xInputFile.getName(); String strippedfile_video = parent + "[stripped].vpes"; String strippedfile_audio = parent + "[stripped].apes"; String strippedfile_teletext = parent + "[stripped].tpes"; try { PushbackInputStream in = new PushbackInputStream(xInputFile.getInputStream()); BufferedOutputStream out_1 = new BufferedOutputStream( new FileOutputStream(strippedfile_video), 5120000); BufferedOutputStream out_2 = new BufferedOutputStream( new FileOutputStream(strippedfile_audio), 4096000); BufferedOutputStream out_3 = new BufferedOutputStream( new FileOutputStream(strippedfile_teletext), 4096000); int count = 0; int[] buffersize = { 0xC000, 0xE800 }; long pos = 0; long len = xInputFile.length(); byte[] array = new byte[buffersize[type]]; int ret, seqhead, audiolength, videolength, seqoffs, frameoffs, audiooffs, teletextlength; while (pos < len) { ret = in.read(array); if (ret < array.length) in.read(array, ret, array.length - ret); seqhead = getValue(array, 0); audiolength = getValue(array, 4); videolength = getValue(array, 8); seqoffs = getValue(array, 12); frameoffs = getValue(array, 16); audiooffs = getValue(array, 20); //? teletextlength = type == 0 ? 0 : getValue(array, 32); if (debug) System.out.println("rl pos + " + pos + " /v " + videolength + " /a " + audiolength + " /t " + teletextlength); if (videolength > 0) out_1.write(array, 0x200, videolength); if (audiolength > 0) out_2.write(array, 0x9200, audiolength); if (teletextlength > 0) out_3.write(array, 0xC000, teletextlength); count++; pos += array.length; } out_1.flush(); out_1.close(); out_2.flush(); out_2.close(); out_3.flush(); out_3.close(); in.close(); } catch (IOException e) { Common.setExceptionMessage(e); return null; } XInputFile[] xif = new XInputFile[3]; xif = finishFile(strippedfile_video, xif, 0); xif = finishFile(strippedfile_audio, xif, 1); xif = finishFile(strippedfile_teletext, xif, 2); return xif; } /** * */ private int getValue(byte[] array, int offset) { int value = 0; for (int i = 0; i < 4; i++) value |= (0xFF & array[offset + i])<<((3 - i) * 8); return value; } /** * */ private XInputFile[] finishFile(String strippedfile, XInputFile[] xif, int index) { File file = new File(strippedfile); if (debug) System.out.println("rl file + " + index + " /l " + file.length()); if (file.length() > 100) xif[index] = new XInputFile(file); else file.delete(); return xif; } } project-x/src/net/sourceforge/dvb/projectx/parser/VBI.java0000600000175000017500000002321510355335532025216 0ustar supermariosupermario/* * @(#)VBI.java - carries various stuff * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.parser; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.video.Video; public final class VBI extends Object { private static long source_pts = 0; private static String vps_str = ""; private static String vps_sound_mode[] = { "n/a", "mono", "stereo", "dual" }; private static byte[] wss = new byte[3]; /** * */ private VBI() {} /** * */ public static void reset() { source_pts = 0; vps_str = ""; wss = new byte[3]; } /** * */ // mpg2 pes expected public static void parsePES(byte[] pes_packet, int pes_packetoffset) throws ArrayIndexOutOfBoundsException { if (pes_packet[pes_packetoffset] != 0 || pes_packet[1 + pes_packetoffset] != 0 || pes_packet[2 + pes_packetoffset] != 1) return; int pes_id = 0xFF & pes_packet[3 + pes_packetoffset]; int pes_packetlength = (0xFF & pes_packet[4 + pes_packetoffset])<<8 | (0xFF & pes_packet[5 + pes_packetoffset]); int pes_mpeg_flag = 0xC0 & pes_packet[6 + pes_packetoffset]; if (pes_mpeg_flag != 0x80 && pes_mpeg_flag != 0x40) // neither mpeg2 nor mpeg1 return; int pes_extensionlength = 0xFF & pes_packet[8 + pes_packetoffset]; boolean pts_flag = (0x80 & pes_packet[7 + pes_packetoffset]) != 0; source_pts = pts_flag ? CommonParsing.getPTSfromBytes(pes_packet, 9 + pes_packetoffset) : 0; decodeVBI(pes_packet, 9 + pes_extensionlength + pes_packetoffset); } /** * */ private static void decodeVBI(byte[] packet, int offs) throws ArrayIndexOutOfBoundsException { String str; boolean wss_online = false; /** * 0x99..0x9B -> PES contains one or multiple VBI Data definitions */ if ((0xFC & packet[offs]) != 0x98 || (3 & packet[offs]) == 0) return; for (int i = offs + 1, data_unit_id, len; i < packet.length - 1; ) { data_unit_id = 0xFF & packet[i++]; len = 0xFF & packet[i++]; /** * VPS */ if (data_unit_id == 0xC3) { str = decodeVPS(packet, i); if (str != null && !str.equals(vps_str)) { vps_str = str; Common.setMessage(Resource.getString("teletext.msg.vps", str) + " " + Common.formatTime_1(source_pts / 90)); } } /** * WSS */ else if (data_unit_id == 0xC4) { str = decodeWSS(packet, i); if (str != null) { wss_online = true; if (str.length() > 0) { Common.setMessage("-> WSS Status - changed @ PTS " + Common.formatTime_1(source_pts / 90)); Common.setMessage(str); } else if (wss[2] == 0) { Common.setMessage("-> WSS Status - no change @ PTS " + Common.formatTime_1(source_pts / 90)); wss[2] = -2; } } } else if (data_unit_id == 0xFF) {} i += len; } if (!wss_online && wss[2] == -1) { wss[2] = 0; Common.setMessage("-> WSS Status - offline @ PTS " + Common.formatTime_1(source_pts / 90)); } } /** * */ public static String decodeVPS(byte[] packet, int offs) { if (!Common.getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg6)) return null; String vps_status = ""; if (packet.length - 1 < offs + 12) return null; int vps_data = (0x3F & packet[offs + 9])<<24 | (0xFF & packet[offs + 10])<<16 | (0xFF & packet[offs + 11])<<8 | (0xFF & packet[offs + 12]); switch (0x1F & vps_data>>>16) { case 0x1C: vps_status = "Contin."; break; case 0x1D: vps_status = "Pause "; break; case 0x1E: vps_status = "Stop "; break; case 0x1F: vps_status = "Timer "; break; default: vps_status = "" + formatString(0x1F & (vps_data>>>25)) + "." + formatString(0xF & (vps_data>>>21)) + ". " + formatString(0x1F & (vps_data>>>16)) + ":" + formatString(0x3F & (vps_data>>>10)) + " "; } vps_status += vps_sound_mode[(3 & packet[offs + 3]>>>6)] + " " + Integer.toHexString(0xF & vps_data>>>6).toUpperCase() + " " + Integer.toHexString(0x3F & vps_data).toUpperCase(); return vps_status; } /** * */ private static String formatString(int value) { String str = "00" + String.valueOf(value); return str.substring(str.length() - 2); } /** * */ private static String decodeWSS(byte[] packet, int offs) { if (!Common.getSettings().getBooleanProperty(Keys.KEY_MessagePanel_Msg5)) return null; if (packet.length - 1 < offs + 2) return null; if (packet[offs + 1] == wss[0] && packet[offs + 2] == wss[1]) return ""; System.arraycopy(packet, offs + 1, wss, 0, 2); wss[2] = -1; // read PAL-625line WSS String str = getGroup1(wss); str += getGroup2(wss); str += getGroup3(wss); str += getGroup4(wss); return str; } /** * */ private static String getGroup1(byte[] packet) { String str = ""; switch (0xF & packet[0]>>4) { case 1: // 0001 Biphase 01010110 str = " " + Resource.getString("wss.group_1.0001"); break; case 8: // 1000 Biphase 10010101 str = " " + Resource.getString("wss.group_1.1000"); break; case 4: // 0100 Biphase 01100101 str = " " + Resource.getString("wss.group_1.0100"); break; case 0xD: // 1101 Biphase 10100110 str = " " + Resource.getString("wss.group_1.1101"); break; case 2: // 0010 Biphase 01011001 str = " " + Resource.getString("wss.group_1.0010"); break; case 7: // 0111 Biphase 01101010 str = " " + Resource.getString("wss.group_1.0111"); break; case 0xE: // 1110 Biphase 10101001 str = " " + Resource.getString("wss.group_1.1110"); break; default: str = " " + Resource.getString("wss.group_1.error"); } str += "\n"; return str; } /** * */ private static String getGroup2(byte[] packet) { String str = ""; switch (1 & packet[0]>>3) { case 0: // 0 Biphase 01 str += " " + Resource.getString("wss.group_2.0.01"); break; case 1: // 1 Biphase 10 str += " " + Resource.getString("wss.group_2.0.10"); } str += ","; switch (1 & packet[0]>>2) { case 0: // 0 Biphase 01 str += " " + Resource.getString("wss.group_2.1.01"); break; case 1: // 1 Biphase 10 str += " " + Resource.getString("wss.group_2.1.10"); } str += ","; switch (1 & packet[0]>>1) { case 0: // 0 Biphase 01 str += " " + Resource.getString("wss.group_2.2.01"); break; case 1: // 1 Biphase 10 str += " " + Resource.getString("wss.group_2.2.10"); } str += ","; switch (1 & packet[0]) { case 0: // 0 Biphase 01 str += " " + Resource.getString("wss.group_2.3.01"); break; case 1: // 1 Biphase 10 str += " " + Resource.getString("wss.group_2.3.10"); } str += "\n"; return str; } /** * */ private static String getGroup3(byte[] packet) { String str = ""; switch (1 & packet[1]>>7) { case 0: // 0 Biphase 01 str += " " + Resource.getString("wss.group_3.0.01"); break; case 1: // 1 Biphase 10 str += " " + Resource.getString("wss.group_3.0.10"); } str += ","; switch (3 & packet[1]>>5) { case 0: // 00 Biphase 0101 str += " " + Resource.getString("wss.group_3.1.00"); break; case 1: // 01 Biphase 0110 str += " " + Resource.getString("wss.group_3.1.01"); break; case 2: // 10 Biphase 1001 str += " " + Resource.getString("wss.group_3.1.10"); break; case 3: // 11 Biphase 1010 str += " " + Resource.getString("wss.group_3.1.11"); } str += "\n"; return str; } /** * */ private static String getGroup4(byte[] packet) { String str = ""; switch (1 & packet[1]>>4) { case 0: // 0 Biphase 01 str += " " + Resource.getString("wss.group_4.0.01"); break; case 1: // 1 Biphase 10 str += " " + Resource.getString("wss.group_4.0.10"); } str += ","; switch (1 & packet[1]>>3) { case 0: // 0 Biphase 01 str += " " + Resource.getString("wss.group_4.1.01"); break; case 1: // 1 Biphase 10 str += " " + Resource.getString("wss.group_4.1.10"); } str += ","; switch (1 & packet[1]>>2) { case 0: // 0 Biphase 01 str += " " + Resource.getString("wss.group_4.2.01"); break; case 1: // 1 Biphase 10 str += " " + Resource.getString("wss.group_4.2.10"); } return str; } }project-x/src/net/sourceforge/dvb/projectx/subtitle/0000700000175000017500000000000010745203152024260 5ustar supermariosupermarioproject-x/src/net/sourceforge/dvb/projectx/subtitle/BMP.java0000600000175000017500000001530610351106336025547 0ustar supermariosupermario/* * @(#)BMP.java - carries BMP stuff, access from 'all sides' * * Copyright (c) 2004-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.subtitle; //DM24042004 081.7 int02 introduced import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Hashtable; import java.util.Enumeration; public class BMP extends Object { private static final byte defaultHeader[] = { 0x42, 0x4D, //'B','M' 0, 0, 0, 0, // real filesize 32bit, little endian (real size*3 + header(0x36)) 0, 0, 0, 0, 0x36, 0, 0, 0, //bitmap info size 0x28, 0, 0, 0, 0, 0, 0, 0, //hsize 0, 0, 0, 0, //vsize 1, 0, //nplane 0x18, 0, //bitcount 24b 0, 0, 0, 0, //ncompr 0, 0, 0, 0, //image bytesize (byte)0x88, 0xB, 0, 0, //nxpm 75dpi (byte)0x88, 0xB, 0, 0, //nypm 75dpi 0, 0, 0, 0, //nclrused 0, 0, 0, 0 //nclrimp }; private static Hashtable bmps = new Hashtable(); private BMP() {} public static String getContents() { return bmps.toString(); } public static Enumeration getKeys() { return bmps.keys(); } public static boolean isEmpty() { return bmps.isEmpty(); } public static void clear() { bmps.clear(); } public static void savePixels(Bitmap bitmap) { bmps.put("" + bitmap.getId(), bitmap); } public static Bitmap getBitmap(int id) { return (Bitmap)bmps.get("" + id); } private static void littleEndian(byte[] array, int aPos, int value) { for (int a=0; a<4; a++) array[aPos+a] = (byte)(value>>(a*8) & 0xFF); } public static void buildBMP_24bit(String outfile, String key) throws IOException { Bitmap bitmap = (Bitmap)bmps.get(key); if (bitmap == null) return; int width = bitmap.getWidth(); int height = bitmap.getHeight(); int size = 3 * width * height + height * (width & 3); if (size == 0) return; int pixels[] = bitmap.getPixel(); BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream( outfile + ".bmp"), 65535); byte BMPheader[] = new byte[defaultHeader.length]; System.arraycopy(defaultHeader, 0, BMPheader, 0, defaultHeader.length); byte RGB_24bit[] = new byte[3]; littleEndian(BMPheader , 2, (0x36 + size)); littleEndian(BMPheader , 18, width); littleEndian(BMPheader , 22, height); littleEndian(BMPheader , 34, size); out.write(BMPheader); for (int a = height-1; a >= 0; a--) { for (int b = 0; b < width; b++) { for (int c = 0; c < 3; c++) RGB_24bit[c] = (byte)(pixels[b + a * width]>>(c * 8) & 0xFF); out.write(RGB_24bit); } out.write(new byte[width & 3]); //padding bytes } out.flush(); out.close(); } public static String buildBMP_palettized(String outfile, String key, ArrayList color_table_array, int palette) throws IOException { return buildBMP_palettized(outfile, (Bitmap)bmps.get(key), color_table_array, palette); } public static String buildBMP_palettized(String outfile, Bitmap bitmap, ArrayList color_table_array, int palette) throws IOException { if (bitmap == null) return ""; palette = 256; //still fixed! int width = bitmap.getWidth(); int height = bitmap.getHeight(); int size = palette * 4 + width * height + height * (width & 3); if (size == 0) return ""; outfile += ".bmp"; BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream(outfile), 65535); byte BMPheader[] = new byte[defaultHeader.length]; System.arraycopy(defaultHeader, 0, BMPheader, 0, defaultHeader.length); byte RGB_4bit = 0; // 1 pixel_index if (palette == 256) BMPheader[28] = 8; else BMPheader[28] = 4; littleEndian(BMPheader , 2, (0x36 + size)); littleEndian(BMPheader , 10, (0x36 + palette * 4)); //pixel start littleEndian(BMPheader , 18, width); littleEndian(BMPheader , 22, height); littleEndian(BMPheader , 34, size); out.write(BMPheader); Object color_table[] = color_table_array.toArray(); byte base_color_index[] = new byte[4]; //paletize 256 * 4byte BGR0 indices for (int a=0, color; a < palette; a++) { if (a < color_table.length) { color = 0xFFFFFF & Integer.parseInt(color_table[a].toString()); for (int b=0; b < 3; b++) base_color_index[b] = (byte)(0xFF & color>>(b<<3)); } out.write(base_color_index); } color_table = null; int pixels[] = bitmap.getPixel(); for (int a = height - 1; a >= 0; a--) { for (int b = 0, val = 0; b < width; b++) { out.write(0xFF & getColorIndex(pixels[b + a * width], color_table_array)); } out.write(new byte[width & 3]); //padding bytes } out.flush(); out.close(); return outfile; } private static int getColorIndex(int color, ArrayList color_table) { String color_str = "" + color; int index = color_table.indexOf(color_str); if (index != -1) return index; return (color_table.size() - 1); } public static String write_ColorTable(String outfile, ArrayList color_table_array, int palette) throws IOException { Object color_table[] = color_table_array.toArray(); byte base_color_index[] = new byte[4]; outfile += ".spf"; palette = 256; //still fixed! BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream(outfile), 65535); //palettize number * 4byte BGR0 indices (e.g.256 or 16) for (int a=0, color; a < palette; a++) { if (a < color_table.length) { color = 0xFFFFFF & Integer.parseInt(color_table[a].toString()); for (int b=0; b < 3; b++) base_color_index[b] = (byte)(0xFF & color>>(b<<3)); } out.write(base_color_index); } color_table = null; out.flush(); out.close(); return outfile; } }project-x/src/net/sourceforge/dvb/projectx/subtitle/Bitmap.java0000600000175000017500000000775710351106324026355 0ustar supermariosupermario/* * @(#)Bitmap.java - provides a Bitmap buffer from painted subpic * * Copyright (c) 2004-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.subtitle; //DM24042004 081.7 int02 introduced import java.util.ArrayList; public class Bitmap extends Object { private int width = 0; private int height = 0; private int depth = 0; private int pixel[] = null; private int page_id = -1; private int region_id = -1; private int object_id = -1; private int x = 0; private int y = 0; private long in_time = -1; private int play_time = -1; private ArrayList color_indices = new ArrayList(); private ArrayList color_table = new ArrayList(); public Bitmap() {} public Bitmap(int newx, int newy, int w, int h, int[] p, int d, int page, int region, int object, long pts, int time) { x = newx; //y = newy; y = newy & ~1; //DM26052004 081.7 int03 changed width = w; height = h; pixel = p; depth = d; page_id = 0xFF & page; region_id = 0xFF & region; object_id = 0xFFFF & object; in_time = pts; play_time = time; } public int getX() { return x; } public int getY() { return y; } public int getMaxX() { return (x + width); } public int getMaxY() { return (y + height); } public int getWidth() { return width; } public int getHeight() { return height; } public void setWidth(int val) { width = val; } public void setHeight(int val) { height = val; } public void setPixel(int[] p) { pixel = p; } public int[] getPixel() { return pixel; } public int getDepth() { return depth; } public int getPageId() { return page_id; } public int getRegionId() { return region_id; } public int getObjectId() { return object_id; } public int getId() { //return (page_id<<24 | region_id<<16 | object_id); return page_id; } public void setTime(long time_1, int time_2) { in_time = time_1; play_time = time_2; } public long getInTime() { return in_time; } public int getPlayTime() { return play_time; } public void createColorTable() { for (int a=0; a < pixel.length; a++) { String pixel_str = "" + pixel[a]; if (color_table.contains(pixel_str)) continue; else color_table.add(pixel_str); } } public void clearColorTable() { color_table.clear(); } public Object[] getColorTable() { return color_table.toArray(); } public ArrayList getColorTableArray() { return color_table; } // returns 0 .. 3, indices > 3 mapped to 3 public int getColorIndex(int color_index) { String color_index_str = "" + color_index; int index = color_indices.indexOf(color_index_str); if (index != -1) return index; else if (color_indices.size() < 4) color_indices.add(color_index_str); return (color_indices.size() - 1); } public void clearColorIndices() { color_indices.clear(); } public Object[] getColorIndices() { return color_indices.toArray(); } } project-x/src/net/sourceforge/dvb/projectx/subtitle/CharSet.java0000600000175000017500000005477410351106346026477 0ustar supermariosupermario/* * @(#)CharSet.java - constants of teletext System B * * Copyright (c) 2004-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.subtitle; //DM06082004 081.7 int07 introduced public final class CharSet extends Object { private CharSet() {} private final static short G0_sets[][] = { { //0 = latin 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x0020 },{ //1 = cyrillic-1, //DM08082004 081.7 int08 changed 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0427, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, 0x0425, 0x0418, 0x0408, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, 0x040c, 0x0420, 0x0421, 0x0422, 0x0423, 0x0412, 0x0403, 0x0409, 0x040a, 0x0417, 0x040b, 0x0416, 0x0402, 0x0428, 0x040f, 0x0447, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, 0x0445, 0x0438, 0x0458, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x045c, 0x0440, 0x0441, 0x0442, 0x0443, 0x0432, 0x0453, 0x0459, 0x045a, 0x044d, 0x045b, 0x0436, 0x0452, 0x0448, 0x0020 },{ //2 = cyrillic-2, //DM08082004 081.7 int08 changed 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x044b, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, 0x042c, 0x042a, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042b, 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, 0x044c, 0x044a, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x0020 },{ //3 = cyrillic-3, //DM08082004 081.7 int08 changed 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0457, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, 0x042c, 0x0406, 0x0417, 0x0428, 0x0404, 0x0429, 0x0427, 0x0407, 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, 0x044c, 0x0456, 0x0437, 0x0448, 0x0454, 0x0449, 0x0447, 0x0020 },{ //4 = greek, //DM08082004 081.7 int08 changed 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x00ab, 0x003d, 0x00bb, 0x003f, 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, 0x03a1, 0x0384, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0020 },{ //5 = arabic, still a copy of latin! 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x061f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x0020 },{ //6 = hebrew, //DM08082004 081.7 int08 changed 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x2190, 0x00bd, 0x2192, 0x2191, 0x0023, 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x0020, 0x05f0, 0x00bc, 0x00f7, 0x0020 } }; //DM10082004 081.7 int08 changed private final static short G2_sets[][] = { { //0 = latin 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x00a1, 0x00a2, 0x00a3, 0x0024, 0x00a5, 0x0023, 0x00a7, 0x00a4, 0x00b4, 0x0022, 0x00ab, 0x003c, 0x005e, 0x003d, 0x0076, 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00d7, 0x00b5, 0x00b6, 0x00b7, 0x00f7, 0x00b4, 0x0022, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, 0x0020, 0x0060, 0x00b4, 0x02c6, 0x007e, 0x02c9, 0x02d8, 0x02d9, 0x0308, 0x002e, 0x02da, 0x0020, 0x005f, 0x0022, 0x0020, 0x02d8, 0x002d, 0x00b9, 0x00ae, 0x00a9, 0x2122, 0x002a, 0x20ac, 0x2030, 0x03b1, 0x0020, 0x0020, 0x0020, 0x002a, 0x002a, 0x002a, 0x002a, 0x03a9, 0x00c6, 0x0110, 0x0061, 0x0126, 0x0020, 0x0132, 0x013f, 0x0141, 0x00d8, 0x0152, 0x006f, 0x00de, 0x0166, 0x014a, 0x0149, 0x0138, 0x00e6, 0x0111, 0x010f, 0x0127, 0x0131, 0x0133, 0x0140, 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x0167, 0x014b, 0x0020, },{ //1 = cyrillic, //DM08082004 081.7 int08 changed 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x00a1, 0x00a2, 0x00a3, 0x0024, 0x00a5, 0x0020, 0x00a7, 0x0020, 0x00b4, 0x0022, 0x00ab, 0x003c, 0x005e, 0x003d, 0x0076, 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00d7, 0x00b5, 0x00b6, 0x00b7, 0x00f7, 0x00b4, 0x0022, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, 0x0020, 0x0060, 0x00b4, 0x02c6, 0x007e, 0x02c9, 0x02d8, 0x02d9, 0x0308, 0x002e, 0x02da, 0x0020, 0x005f, 0x0022, 0x0020, 0x02d8, 0x002d, 0x00b9, 0x00ae, 0x00a9, 0x2122, 0x002a, 0x20ac, 0x2030, 0x03b1, 0x0141, 0x0142, 0x00df, 0x002a, 0x002a, 0x002a, 0x002a, 0x0044, 0x0045, 0x0046, 0x0047, 0x0049, 0x004a, 0x004b, 0x004c, 0x004e, 0x0051, 0x0052, 0x0053, 0x0055, 0x0056, 0x0057, 0x005a, 0x0064, 0x0065, 0x0066, 0x0067, 0x0069, 0x006a, 0x006b, 0x006c, 0x006e, 0x0071, 0x0072, 0x0073, 0x0075, 0x0076, 0x0077, 0x007a, },{ //2 = greek, //DM08082004 081.7 int08 changed 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0061, 0x0062, 0x00a3, 0x0065, 0x0068, 0x0069, 0x00a7, 0x003a, 0x00b4, 0x0022, 0x006b, 0x003c, 0x005e, 0x003d, 0x0076, 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00d7, 0x006d, 0x006e, 0x0070, 0x00f7, 0x00b4, 0x0022, 0x0074, 0x00bc, 0x00bd, 0x00be, 0x0078, 0x0020, 0x0060, 0x00b4, 0x02c6, 0x007e, 0x02c9, 0x02d8, 0x02d9, 0x0308, 0x002e, 0x02da, 0x0020, 0x005f, 0x0022, 0x0020, 0x02d8, 0x003f, 0x00b9, 0x00ae, 0x00a9, 0x2122, 0x002a, 0x20ac, 0x2030, 0x03b1, 0x038a, 0x038e, 0x038f, 0x002a, 0x002a, 0x002a, 0x002a, 0x0043, 0x0044, 0x0046, 0x0047, 0x004a, 0x004c, 0x0051, 0x0052, 0x0053, 0x0055, 0x0056, 0x0057, 0x0059, 0x005a, 0x0386, 0x0389, 0x0063, 0x0064, 0x0066, 0x0067, 0x006a, 0x006c, 0x0071, 0x0072, 0x0073, 0x0075, 0x0076, 0x0077, 0x0079, 0x007a, 0x0388, 0x0020, },{ //3 = arabic, still a copy of latin! 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x00a1, 0x00a2, 0x00a3, 0x0024, 0x00a5, 0x0023, 0x00a7, 0x00a4, 0x00b4, 0x0022, 0x00ab, 0x003c, 0x005e, 0x003d, 0x0076, 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00d7, 0x00b5, 0x00b6, 0x00b7, 0x00f7, 0x00b4, 0x0022, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, 0x0020, 0x0060, 0x00b4, 0x02c6, 0x007e, 0x02c9, 0x02d8, 0x02d9, 0x0308, 0x002e, 0x02da, 0x0020, 0x005f, 0x0022, 0x0020, 0x02d8, 0x002d, 0x00b9, 0x00ae, 0x00a9, 0x2122, 0x002a, 0x20ac, 0x2030, 0x0020, 0x0020, 0x0020, 0x0020, 0x002a, 0x002a, 0x002a, 0x002a, 0x03a9, 0x00c6, 0x0110, 0x0061, 0x0126, 0x0020, 0x0132, 0x013f, 0x0141, 0x00d8, 0x0152, 0x006f, 0x00de, 0x0166, 0x014a, 0x0149, 0x0138, 0x00e6, 0x0111, 0x010f, 0x0127, 0x0131, 0x0133, 0x0140, 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x0167, 0x014b, 0x0020, } }; private final static short national_subsets[][] = { { 0x00a3, 0x0024, 0x0040, 0x00ab, 0x00bd, 0x00bb, 0x005e, 0x0023, 0x002d, 0x00bc, 0x00a6, 0x00be, 0x00f7 }, // english ,000 { 0x00e9, 0x00ef, 0x00e0, 0x00eb, 0x00ea, 0x00f9, 0x00ee, 0x0023, 0x00e8, 0x00e2, 0x00f4, 0x00fb, 0x00e7 }, // french ,001 { 0x0023, 0x00a4, 0x00c9, 0x00c4, 0x00d6, 0x00c5, 0x00dc, 0x005f, 0x00e9, 0x00e4, 0x00f6, 0x00e5, 0x00fc }, // swedish,finnish,hungarian ,010 { 0x0023, 0x016f, 0x010d, 0x0165, 0x017e, 0x00fd, 0x00ed, 0x0159, 0x00e9, 0x00e1, 0x0115, 0x00fa, 0x0161 }, // czech,slovak ,011 { 0x0023, 0x0024, 0x00a7, 0x00c4, 0x00d6, 0x00dc, 0x005e, 0x005f, 0x00b0, 0x00e4, 0x00f6, 0x00fc, 0x00df }, // german ,100 { 0x00e7, 0x0024, 0x00a1, 0x00e1, 0x00e9, 0x00ed, 0x00f3, 0x00fa, 0x00bf, 0x00fc, 0x00f1, 0x00e8, 0x00e0 }, // portuguese,spanish ,101 { 0x00a3, 0x0024, 0x00e9, 0x00b0, 0x00e7, 0x00bb, 0x005e, 0x0023, 0x00f9, 0x00e0, 0x00f2, 0x00e8, 0x00ec }, // italian ,110 { 0x0023, 0x00a4, 0x0162, 0x00c2, 0x015e, 0x0102, 0x00ce, 0x0131, 0x0163, 0x00e2, 0x015f, 0x0103, 0x00ee }, // rumanian ,111 { 0x0023, 0x0024, 0x0160, 0x0117, 0x0119, 0x017d, 0x010d, 0x016b, 0x0161, 0x0105, 0x0173, 0x017e, 0x012f }, // lettish,lithuanian ,1000 { 0x0023, 0x0144, 0x0105, 0x005a, 0x015a, 0x0141, 0x0107, 0x00f3, 0x0119, 0x017c, 0x015b, 0x0142, 0x017a }, // polish, 1001 { 0x0023, 0x00cb, 0x010c, 0x0106, 0x017d, 0x0110, 0x0160, 0x00eb, 0x010d, 0x0107, 0x017e, 0x0111, 0x0161 }, // serbian,croatian,slovenian, 1010 { 0x0023, 0x00f5, 0x0160, 0x00c4, 0x00d6, 0x017e, 0x00dc, 0x00d5, 0x0161, 0x00e4, 0x00f6, 0x017e, 0x00fc }, // estonian ,1011 { 0x0054, 0x011f, 0x0130, 0x015e, 0x00d6, 0x00c7, 0x00dc, 0x011e, 0x0131, 0x015f, 0x00f6, 0x00e7, 0x00fc }, // turkish ,1100 null //res. }; //4 bits main triple + 3 bits character_set private final static int G0_set_mapping[][] = { { 0, 0, 0, 0, 0, 0, 0, 0 }, //0, latin { 0, 0, 0, 0, 0, 0, 0, 0 }, //1, latin { 0, 0, 0, 0, 0, 0, 0, 0 }, //2, latin { 0, 0, 0, 0, 0, 0, 0, 0 }, //3, latin { 1, 2, 0, 0, 0, 3, 0, 0 }, //4, cy-1,cy-2,la,la,la,cy-3,la,la { 0, 0, 0, 0, 0, 0, 0, 0 }, //5, all res. { 0, 0, 0, 0, 0, 0, 0, 4 }, //6, res,res,res,la,res,res,res,gre { 0, 0, 0, 0, 0, 0, 0, 0 }, //7, all res. { 0, 0, 0, 0, 0, 0, 0, 5 }, //8, la,la,res,res,res,res,res,ara { 0, 0, 0, 0, 0, 0, 0, 0 }, //9, all res. { 0, 0, 0, 0, 0, 6, 0, 5 }, //10, res,res,res,res,res,heb,res,ara { 0, 0, 0, 0, 0, 0, 0, 0 }, //11, all res. { 0, 0, 0, 0, 0, 0, 0, 0 }, //12, all res. { 0, 0, 0, 0, 0, 0, 0, 0 }, //13, all res. { 0, 0, 0, 0, 0, 0, 0, 0 }, //14, all res. { 0, 0, 0, 0, 0, 0, 0, 0 }, //15, all res. }; //4 bits main triple + 3 bits character_set private final static int G2_set_mapping[][] = { { 0, 0, 0, 0, 0, 0, 0, 0 }, //0, latin { 0, 0, 0, 0, 0, 0, 0, 0 }, //1, latin { 0, 0, 0, 0, 0, 0, 0, 0 }, //2, latin { 0, 0, 0, 0, 0, 0, 0, 0 }, //3, latin { 1, 1, 0, 0, 0, 1, 0, 0 }, //4, cy,cy,la,la,la,cy,la,res { 0, 0, 0, 0, 0, 0, 0, 0 }, //5, all res. { 0, 0, 0, 0, 0, 0, 0, 2 }, //6, res,res,res,la,res,res,res,gre { 0, 0, 0, 0, 0, 0, 0, 0 }, //7, all res. { 3, 3, 0, 0, 0, 0, 0, 3 }, //8, ara,ara,res,res,res,res,res,ara { 0, 0, 0, 0, 0, 0, 0, 0 }, //9, all res. { 0, 0, 0, 0, 0, 3, 0, 3 }, //10, res,res,res,res,res,ara,res,ara { 0, 0, 0, 0, 0, 0, 0, 0 }, //11, all res. { 0, 0, 0, 0, 0, 0, 0, 0 }, //12, all res. { 0, 0, 0, 0, 0, 0, 0, 0 }, //13, all res. { 0, 0, 0, 0, 0, 0, 0, 0 }, //14, all res. { 0, 0, 0, 0, 0, 0, 0, 0 }, //15, all res. }; //DM10082004 081.7 int08 changed //4 bits main tripl + 3 bits character_set private final static int national_subset_mapping[][] = { { 0, 1, 2, 3, 4, 5, 6, 7 }, //0, en,fr,se,cz,de,es,it,ro { 9, 1, 2, 3, 4, 5, 6, 7 }, //1, pl,fr,se,cz,de,es,it,ro { 0, 1, 2, 12, 4, 5, 6, 7 }, //2, en,fr,se,tr,de,es,it,ro { 13, 13, 13, 13, 13, 10, 13, 7 }, //3, en,fr,se,cz,de,cr,it,ro { 13, 13, 11, 3, 4, 13, 8, 13 }, //4, et,cz,de,cr { 13, 13, 13, 13, 13, 13, 13, 13 }, //5, res! { 13, 13, 13, 12, 13, 13, 13, 13 }, //6, res,res,res,tr,res,res,res,(gr) { 13, 13, 13, 13, 13, 13, 13, 13 }, //7, res! { 0, 1, 13, 13, 13, 13, 13, 13 }, //8, en,fr,res,res,res,res,res,(ar) { 13, 13, 13, 13, 13, 13, 13, 13 }, //9, res! { 13, 13, 13, 13, 13, 13, 13, 13 }, //10, res,res,res,res,res,(he),res,(ar) { 13, 13, 13, 13, 13, 13, 13, 13 }, //11, res! { 13, 13, 13, 13, 13, 13, 13, 13 }, //12, res! { 13, 13, 13, 13, 13, 13, 13, 13 }, //13, res! { 13, 13, 13, 13, 13, 13, 13, 13 }, //14, res! { 13, 13, 13, 13, 13, 13, 13, 13 }, //15, res! }; //DM10082004 081.7 int08 changed //A=65 .. Z=90 private final static short diacritical_uppercase_char_map[][] = { { 0, 192, 193, 194, 195, 256, 258, 0, 196, 0, 197, 0, 0, 0, 260, 258 }, //A { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //B { 0, 0, 262, 264, 0, 0, 268, 266, 0, 0, 0, 199, 0, 0, 0, 268 }, //C { 0, 0, 0, 0, 0, 0, 270, 0, 0, 0, 0, 0, 0, 0, 0, 270 }, //D { 0, 200, 201, 202, 0, 274, 276, 278, 203, 0, 0, 0, 0, 0, 280, 282 }, //E { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //F { 0, 0, 0, 284, 0, 0, 286, 288, 0, 0, 0, 290, 0, 0, 0, 0 }, //G { 0, 0, 0, 292, 0, 294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //H { 0, 204, 205, 206, 296, 298, 300, 304, 207, 0, 0, 0, 0, 0, 302, 300 }, //I { 0, 0, 0, 308, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //J { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 310, 0, 0, 0, 0 }, //K { 0, 0, 313, 0, 0, 0, 0, 319, 0, 0, 0, 315, 0, 0, 0, 317 }, //L { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //M { 0, 0, 323, 0, 209, 0, 0, 0, 0, 0, 0, 325, 0, 0, 0, 327 }, //N { 0, 210, 211, 212, 213, 332, 334, 0, 214, 0, 0, 0, 0, 336, 0, 334 }, //O { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //P { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //Q { 0, 0, 340, 0, 0, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 344 }, //R { 0, 0, 346, 348, 0, 0, 0, 0, 0, 0, 0, 350, 0, 0, 0, 352 }, //S { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 354, 0, 0, 0, 356 }, //T { 0, 217, 218, 219, 360, 362, 364, 0, 220, 0, 366, 0, 0, 368, 370, 364 }, //U { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //V { 0, 0, 0, 372, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //W { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //X { 0, 0, 221, 374, 0, 0, 0, 0, 376, 0, 0, 0, 0, 0, 0, 0 }, //Y { 0, 0, 377, 0, 0, 0, 0, 379, 0, 0, 0, 0, 0, 0, 0, 381 }, //Z }; //DM10082004 081.7 int08 changed //a=97 .. z=122 private final static short diacritical_lowercase_char_map[][] = { { 0, 224, 225, 226, 227, 257, 259, 0, 228, 0, 229, 0, 0, 0, 261, 259 }, //a { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //b { 0, 0, 263, 265, 0, 0, 269, 267, 0, 0, 0, 231, 0, 0, 0, 269 }, //c { 0, 0, 0, 0, 0, 0, 271, 0, 0, 0, 0, 0, 0, 0, 0, 271 }, //d { 0, 232, 233, 234, 0, 275, 277, 279, 235, 0, 0, 0, 0, 0, 281, 283 }, //e { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //f { 0, 0, 0, 285, 0, 0, 287, 289, 0, 0, 0, 291, 0, 0, 0, 0 }, //g { 0, 0, 0, 293, 0, 295, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //h { 0, 236, 237, 238, 297, 299, 301, 305, 239, 0, 0, 0, 0, 0, 303, 301 }, //i { 0, 0, 0, 309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //j { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 311, 0, 0, 0, 0 }, //k { 0, 0, 314, 0, 0, 0, 0, 320, 0, 0, 0, 316, 0, 0, 0, 318 }, //l { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //m { 0, 0, 324, 0, 241, 0, 0, 0, 0, 0, 0, 326, 0, 0, 0, 328 }, //n { 0, 242, 243, 244, 245, 333, 335, 0, 246, 0, 0, 0, 0, 337, 0, 335 }, //o { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //p { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //q { 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 345 }, //r { 0, 0, 347, 349, 0, 0, 0, 0, 0, 0, 0, 351, 0, 0, 0, 353 }, //s { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 355, 0, 0, 0, 357 }, //t { 0, 249, 250, 251, 361, 363, 365, 0, 252, 0, 367, 0, 0, 369, 371, 365 }, //u { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //v { 0, 0, 0, 373, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //w { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //x { 0, 0, 253, 375, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0 }, //y { 0, 0, 378, 0, 0, 0, 0, 380, 0, 0, 0, 0, 0, 0, 0, 382 }, //z }; public static short[] getActive_G0_Set(int mapping, int character_set, int row) { if (row < 26) return G0_sets[G0_set_mapping[mapping][character_set]]; else return G0_sets[G0_set_mapping[0][0]]; } public static short[] getActive_G2_Set(int mapping, int character_set, int row) { if (row < 26) return G2_sets[G2_set_mapping[mapping][character_set]]; else return G2_sets[G2_set_mapping[0][0]]; } public static short[] getActiveNationalSubset(int mapping, int character_set, int row) { if (row < 26) return national_subsets[national_subset_mapping[mapping][character_set]]; else return national_subsets[national_subset_mapping[0][0]]; } public static short getCombinedCharacter(int basic_char, int combine_char) { short val = 0; if (basic_char >= 65 && basic_char <= 90) val = diacritical_uppercase_char_map[basic_char - 65][combine_char]; else if (basic_char >= 97 && basic_char <= 122) val = diacritical_lowercase_char_map[basic_char - 97][combine_char]; if (val == 0) return (short)basic_char; else return val; } } project-x/src/net/sourceforge/dvb/projectx/subtitle/DVBSubpicture.java0000600000175000017500000012040510405056010027600 0ustar supermariosupermario/* * @(#)DVBSubpicture.java - decodes DVB subtitles * * Copyright (c) 2004-2005 by dvb.matt, All rights reserved * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ /* * example of a basic implementation of a DVB subtitle decoder * * it does not yet implement export (only log it) of encoded string characters, only bitmapped pictures * */ package net.sourceforge.dvb.projectx.subtitle; //DM24042004 081.7 int02 introduced import java.awt.Graphics2D; import java.awt.Color; import java.awt.image.BufferedImage; import java.util.Hashtable; import java.util.Enumeration; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Common; public class DVBSubpicture extends Object { private byte data[]; private int BytePosition, BitPosition; private Graphics2D big; private BufferedImage bimg; private Epoch epoch; private Page page; private Region region; private CLUT clut; private OBJECT object; private Hashtable epoches = new Hashtable(); private int table_CLUT_8bit[]; private int IRD; private int epoch_id = 0; private boolean biglog; private int pixel_data[], preview_pixel_data[]; private long pts; private int width = 720, height = 576; private int from_index, to_index; private boolean picture_saved; private boolean save; private boolean preview_visible = false; private int fix_page_id; //DM13062004 081.7 int04 add private Hashtable user_table = new Hashtable(); private boolean user_table_enabled; //DM30072004 081.7 int07 add private boolean global_error = false; public DVBSubpicture() { table_CLUT_8bit = generateDefaultCLUT_8Bits(); setIRD(8, user_table, false, ""); //DM13062004 081.7 int04 changed } public void setIRD(int val, Hashtable table, boolean log, String page_id_str) { IRD = val; //2,4,8 = 4,16,256-color support //DM13062004 081.7 int04 add++ user_table = table; user_table_enabled = !user_table.isEmpty(); //DM23062004 081.7 int05 changed if (user_table_enabled) IRD = Integer.parseInt(user_table.get("model").toString().trim()); //DM13062004 081.7 int04 add-- biglog = log; resetEpoch(); if (page_id_str.trim().length() != 0) fix_page_id = Integer.parseInt(page_id_str.trim()); else fix_page_id = -1; preview_visible = false; } private void addBigMessage(String msg) { if (!biglog) return; System.out.println(msg); } private void resetEpoch() { epoches.clear(); epoch = setEpoch(epoch_id); preview_pixel_data = new int[width * height]; picture_saved = false; save = false; } private int getBits(int N) { int Pos, Val; Pos = BitPosition>>>3; //DM03082004 081.7 int07 add if (Pos >= data.length - 4) { global_error = true; BitPosition += N; BytePosition = BitPosition>>>3; return 0; } Val = (0xFF & data[Pos])<<24 | (0xFF & data[Pos+1])<<16 | (0xFF & data[Pos+2])<<8 | (0xFF & data[Pos+3]); Val <<= BitPosition & 7; Val >>>= 32-N; BitPosition += N; BytePosition = BitPosition>>>3; return Val; } private int nextBits(int N) { int Pos, Val; Pos = BitPosition>>>3; //DM03082004 081.7 int07 add if (Pos >= data.length - 4) { global_error = true; return 0; } Val = (0xFF & data[Pos])<<24 | (0xFF & data[Pos+1])<<16 | (0xFF & data[Pos+2])<<8 | (0xFF & data[Pos+3]); Val <<= BitPosition & 7; Val >>>= 32-N; return Val; } private void flushBits(int N) { BitPosition += N; BytePosition = BitPosition>>>3; } private void alignToByte() { alignToByte(1); } private void alignToByte(int N) { while ( (7 & BitPosition) != 0 ) flushBits(N); } private void alignToWord() { if ((1 & BytePosition) != 0 && nextBits(8) != 0x0F) flushBits(8); } public int getTimeOut() { return page.getTimeOut(); } public int decodeDVBSubpicture(byte packet[], int BPos[], Graphics2D big, BufferedImage bimg, long pts, boolean save, boolean preview_visible) { data = packet; //packet + 4 bytes overhead BytePosition = BPos[0]; //bytpos BitPosition = BPos[0]<<3; //bitpos this.big = big; this.bimg = bimg; this.pts = pts; this.save = save; this.preview_visible = preview_visible; picture_saved = false; //DM30072004 081.7 int07 add global_error = false; flushBits(8); //padding int stream_ident = getBits(8); // 0 = std int segment_type = 0; int sync_byte = 0; //DM30072004 081.7 int07 changed //while ( nextBits(8) == 0x0F ) for (int ret; BytePosition < data.length - 4; ) { ret = nextBits(8); addBigMessage("ret " + Integer.toHexString(ret) + " /bi " + BitPosition + " /by " + BytePosition); if (ret == 0xFF) break; if (ret != 0x0F) { flushBits(8); continue; } segment_type = Subtitle_Segment(); alignToByte(); if (global_error && region != null) region.setError(4); } if ( nextBits(8) == 0xFF ) {} if (picture_saved) return -1; return -2; } private int Subtitle_Segment() { if ( getBits(8) != 0x0F ) //syncbyte return -1; int segment_type = getBits(8); int page_id = getBits(16); //page_id if (fix_page_id >= 0 && page_id != fix_page_id) // exclude unwanted pages { stuffing(); return 0xFF; } page = epoch.setPage(page_id); addBigMessage("segm: 0x" + Integer.toHexString(segment_type) + " / " + pts); switch (segment_type) { case 0x10: return page_composition(); //return segment_type; case 0x11: region_composition(); return segment_type; case 0x12: CLUT_definition(); return segment_type; case 0x13: object_data(); return segment_type; case 0x80: end_display(); return segment_type; case 0xFF: stuffing(); return segment_type; default: stuffing(); return segment_type; } } private void end_display() { int segment_length = getBits(16); flushBits(segment_length * 8); //DM18062004 081.7 int05 changed } private void stuffing() { int segment_length = getBits(16); //+ BytePosition; flushBits(segment_length * 8); //DM18062004 081.7 int05 changed } private void prepare_output() { //DM26052004 081.7 int03 changed //long new_time_out = (long)Math.round((pts - page.getTimeIn()) / 900.0); 1000 long new_time_out = 1L + ((pts - page.getTimeIn()) / 1024); if (page.getTimeOut() > 0 && new_time_out > page.getTimeOut()) new_time_out = page.getTimeOut(); int page_pixel_data[] = new int[page.getWidth() * page.getHeight()]; for (int y = 0; y < page.getHeight(); y++) System.arraycopy(preview_pixel_data, page.getX() + ((page.getY() + y) * width), page_pixel_data, y * page.getWidth(), page.getWidth()); if (page.getWriteStatus()) BMP.savePixels( new Bitmap( page.getX(), page.getY(), page.getWidth(), page.getHeight(), page_pixel_data, IRD, page.getId(), region.getId(), 0, page.getTimeIn(), (int)new_time_out)); if (preview_visible) bimg.setRGB(page.getX(), page.getY(), page.getWidth(), page.getHeight(), page_pixel_data, 0, page.getWidth()); paintRegionBorder(page.getX(), page.getY(), page.getWidth(), page.getHeight()); picture_saved = true; addBigMessage("time: in " + page.getTimeIn() + " /len " + new_time_out + " /save " + save + " /prev " + preview_visible); } private int page_composition() { int segment_end = getBits(16) + BytePosition; int segment_type = 0x10; int time_out = getBits(8) * 100; //page_time_out, milliseconds (here ticks) 'til disappearing without another erase event page.setVersionNumber(getBits(4)); //page_version_number, if number exists, update isn't necessary page.setState(getBits(2)); //page_state //0 = only updates of this page contents //1 = new page instance, all contents with new definitions //2 = new epoch, see 1, reset all, complete dec. model (IRD) changes possible flushBits(2); addBigMessage("pagecomp: state " + page.getState() + " /page " + page.getId() + " /pv " + page.getVersionNumber() + " /to " + time_out); if (page.getState() > 0) { clearBackground(); page.clearArea(); } for (Enumeration e = epoch.getRegions(); e.hasMoreElements() ; ) { region = epoch.setRegion(Integer.parseInt(e.nextElement().toString())); //DM23062004 081.7 int05 add if (region.getErrors() > 0) { Common.setMessage(Resource.getString("subpicture.msg.error.dvbdecoding", "" + region.getErrors(), "" + region.getId(), "" + page.getTimeIn())); //region.setActive(false); } addBigMessage("enum: region " + region.getId() + " /err " + region.getErrors() + " /acti " + region.isActive() + " /chng " + region.isChanged() + " /ti_o " + time_out); // if ( page.getState() == 0 && time_out > 6000 ) continue; // region.setError(0); //DM23062004 081.7 int05 add if ( !region.isActive() || !region.isChanged() ) continue; region.setChanged(false); pixel_data = region.getPixel(); page.addArea(region.getXBound(), region.getYBound(), region.getWidth(), region.getHeight()); for (int a = 0; a < region.getHeight(); a++) System.arraycopy(pixel_data, a * region.getWidth(), preview_pixel_data, region.getXBound() + ((region.getYBound() + a) * width), region.getWidth()); segment_type = 0x80; addBigMessage("addToBMP: region " + region.getId()); addBigMessage("newSize: x " + page.getX() + " y " + page.getY() + " w " + page.getWidth() + " h " + page.getHeight()); } if (segment_type == 0x80) prepare_output(); if (page.getState() > 0) //if not update, page content has to die { page = epoch.newPage(page.getId()); page.setTimeIn(pts); page.setWriteStatus(save); epoch.clearRegions(); epoch.clearObjects(); } page.setTimeOut(time_out); //page_time_out, seconds to stand while (BytePosition < segment_end) { region = epoch.setRegion(getBits(8)); //region_ids of this epoch region.setActive(true); region.setChanged(true); flushBits(8); region.setHorizontalAddress(getBits(16)); // start_x region.setVerticalAddress(getBits(16)); // start_y addBigMessage("addreg: reg " + region.getId() + " /x " + region.getXBound() + " /y " + region.getYBound()); } return segment_type; } private void region_composition() { int segment_end = getBits(16) + BytePosition; region = epoch.setRegion(getBits(8)); //region_id region.setVersionNumber(getBits(4)); //region_version_number, if number exists, update isn't necessary region.setFillFlag(getBits(1)); flushBits(3); region.setWidth(getBits(16)); region.setHeight(getBits(16)); region.setLevelOfCompatibility(getBits(3)); region.setDepth(getBits(3)); flushBits(2); int CLUT_id = getBits(8); clut = epoch.setCLUT(CLUT_id); //CLUT_id region.setCLUT_id(CLUT_id); region.setPixelCode_8bit(getBits(8)); region.setPixelCode_4bit(getBits(4)); region.setPixelCode_2bit(getBits(2)); pixel_data = region.initPixel(); flushBits(2); paintRegionBackground(); addBigMessage("regcomp: page " + page.getId() + " /reg " + region.getId() + " /rv " + region.getVersionNumber() + " /lv " + region.getCompatibility() + " /clut " + clut.getId() + " /activ " + region.isActive()); while (BytePosition < segment_end) { object = epoch.setObject(getBits(16)); //object_id object.setRegionId(region.getId()); object.setType(getBits(2)); object.setProvider(getBits(2)); object.setHorizontalPosition(getBits(12)); flushBits(4); object.setVerticalPosition(getBits(12)); if (object.getType() == 1 || object.getType() == 2) //character or ch.strings { object.setForegroundCode(getBits(8)); //foreground_pixel_code object.setBackgroundCode(getBits(8)); //background_pixel_code } addBigMessage("addobj: reg " + region.getId() + " /obj " + Integer.toHexString(object.getId()).toUpperCase() + " /x " + object.getHorizontalPosition() + " /y " + object.getVerticalPosition()); } } private void CLUT_definition() { int segment_end = getBits(16) + BytePosition; clut = epoch.setCLUT(getBits(8)); //CLUT_id clut.setVersionNumber(getBits(4)); //CLUT_version_number, if number exists, update isn't necessary addBigMessage("clutcomp: " + clut.getId() + " /v " + clut.getVersionNumber()); flushBits(4); //user table //DM13062004 081.7 int04 add if (user_table_enabled) { setUserClut(); flushBits( (segment_end - BytePosition) * 8); return; } while (BytePosition < segment_end) { int CLUT_entry_id = getBits(8); int CLUT_flag_2bit_entry = getBits(1); int CLUT_flag_4bit_entry = getBits(1); int CLUT_flag_8bit_entry = getBits(1); int flag = CLUT_flag_8bit_entry<<3 | CLUT_flag_4bit_entry<<2 | CLUT_flag_2bit_entry<<1; flushBits(4); int full_range_flag = getBits(1); int ARGB, Y, Cr, Cb, T; if (full_range_flag == 1) { Y = getBits(8); Cr = getBits(8); Cb = getBits(8); T = getBits(8); } else //only MSB transmitted { Y = getBits(6)<<2; Cr = getBits(4)<<4; Cb = getBits(4)<<4; T = getBits(2)<<6; } ARGB = YUVtoRGB(Y, Cr, Cb, T); addBigMessage("addclut: " + CLUT_entry_id + " /flag " + Integer.toHexString(flag).toUpperCase() + " /ARGB " + Integer.toHexString(ARGB).toUpperCase() + " /range " + full_range_flag); for (int i=0; i<3; i++) clut.setClutEntry(mapColorIndex(CLUT_entry_id, region.getDepth(), 2< 0) {} alignToByte(); // flush 2 bits if not aligned } else if (data_type == 0x11) { while (pixel_code_string_4bit() > 0) {} alignToByte(); //flush 4 bits if not aligned } else if (data_type == 0x12) { while (pixel_code_string_8bit() > 0) {} } else if (data_type == 0x20) for (int a=0; a<4; a++) //getBits(16) = 4 entries object.setMapTable_2to4bit( a, getBits(4)); else if (data_type == 0x21) for (int a=0; a<4; a++) //getBits(32) = 4 entries object.setMapTable_2to8bit( a, getBits(8)); else if (data_type == 0x22) for (int a=0; a<16; a++) //getBits(128) = 16 entries object.setMapTable_4to8bit( a, getBits(8)); else if (data_type == 0xF0) { if (object.getCopyTopFieldFlag()) paintCopiedField(region.getX(0), region.getY() + 1, region.getWidth()); region.nextLine(); } } private int pixel_code_string_2bit() { if (nextBits(2) != 0) paintPixelLine(region.getX(1), region.getY(), 1, getBits(2), 2); else { flushBits(2); if (getBits(1) == 1) //switch_1 { int run_length_3to10 = getBits(3) + 3; //pixel_len + 3 paintPixelLine(region.getX(run_length_3to10), region.getY(), run_length_3to10, getBits(2), 2); } else { int switch_2 = getBits(1); if (switch_2 == 1) paintPixelLine(region.getX(1), region.getY(), 1, 0, 2); else if (switch_2 == 0) { int switch_3 = getBits(2); if (switch_3 == 0) return 0; // end_of_string_signal = 0 else if (switch_3 == 1) paintPixelLine(region.getX(2), region.getY(), 2, 0, 2); else if (switch_3 == 2) { int run_length_12to27 = getBits(4) + 12; //pixel_len + 29 paintPixelLine(region.getX(run_length_12to27), region.getY(), run_length_12to27, getBits(2), 2); } else if (switch_3 == 3) { int run_length_29to284 = getBits(8) + 29; //pixel_len + 29 paintPixelLine(region.getX(run_length_29to284), region.getY(), run_length_29to284, getBits(2), 2); } } } } return 1; } private int pixel_code_string_4bit() { if (nextBits(4) != 0) //1 pixel of color enry 1..15 paintPixelLine(region.getX(1), region.getY(), 1, getBits(4), 4); else { flushBits(4); if (getBits(1) == 0) //switch_1 { if (nextBits(3) != 0) { int run_length_3to9 = getBits(3) + 2; //pixel_len + 2 paintPixelLine(region.getX(run_length_3to9), region.getY(), run_length_3to9, 0, 4); } else return getBits(3); // end_of_string_signal = 0 } else { if (getBits(1) == 0) //switch_2 { int run_length_4to7 = getBits(2) + 4; //pixel_len + 4 paintPixelLine(region.getX(run_length_4to7), region.getY(), run_length_4to7, getBits(4), 4); } else { int switch_3 = getBits(2); if (switch_3 < 2) { int run_length_1to2 = switch_3 + 1; //pixel_len (1 or 2) paintPixelLine(region.getX(run_length_1to2), region.getY(), run_length_1to2, 0, 4); } else if (switch_3 == 2) { int run_length_9to24 = getBits(4) + 9; //pixel_len + 9 paintPixelLine(region.getX(run_length_9to24), region.getY(), run_length_9to24, getBits(4), 4); } else if (switch_3 == 3) { int run_length_25to280 = getBits(8) + 25; //pixel_len + 25 paintPixelLine(region.getX(run_length_25to280), region.getY(), run_length_25to280, getBits(4), 4); } } } } return 1; } private int pixel_code_string_8bit() { int pixel_code_8bit; if (nextBits(8) != 0) paintPixelLine(region.getX(1), region.getY(), 1, getBits(8), 8); else { flushBits(8); if (getBits(1) == 0) //switch_1 { if (nextBits(7) != 0) { int run_length_1to127 = getBits(7); //pixel_len paintPixelLine(region.getX(run_length_1to127), region.getY(), run_length_1to127, 0, 8); } else return getBits(7); //end_of_string_signal = 0 } else { int run_length_3to127 = getBits(7); //pixel_len with colorindex in next 8bits paintPixelLine(region.getX(run_length_3to127), region.getY(), run_length_3to127, getBits(8), 8); } } return 1; } private int YUVtoRGB(int Y, int Cr, int Cb, int T) { if (Y == 0) return 0; int R = (int)((float)Y +1.402f * (Cr-128)); int G = (int)((float)Y -0.34414 * (Cb-128) -0.71414 * (Cr-128)); int B = (int)((float)Y +1.722 * (Cb-128)); R = R < 0 ? 0 : (R > 0xFF ? 0xFF : R); G = G < 0 ? 0 : (G > 0xFF ? 0xFF : G); B = B < 0 ? 0 : (B > 0xFF ? 0xFF : B); T = 0xFF - (T < 0 ? 0 : (T > 0xFF ? 0xFF : T)); return (T<<24 | R<<16 | G<<8 | B); } private int[] generateDefaultCLUT_8Bits() { int table[] = new int[256]; for (int i=0; i<256; i++) table[i] = generateClutEntry_8Bits(i); return table; } private int generateClutEntry_4Bits(int i) { int T, R, G, B; if ((i & 8) == 0) { if ((i & 7) == 0) T = R = G = B = 0; else { R = (i & 1) != 0 ? 0xFF : 0; G = (i & 2) != 0 ? 0xFF : 0; B = (i & 4) != 0 ? 0xFF : 0; T = 0xFF; } } else { R = (i & 1) != 0 ? 0x80 : 0; G = (i & 2) != 0 ? 0x80 : 0; B = (i & 4) != 0 ? 0x80 : 0; T = 0xFF; } return (T<<24 | R<<16 | G<<8 | B); } private int generateClutEntry_8Bits(int i) { int T=0, R=0, G=0, B=0; if ((i & 0x88) == 0) { if ((i & 0x70) == 0) { if ((i & 7) == 0) T = R = G = B = 0; else { R = (i & 1) != 0 ? 0xFF : 0; G = (i & 2) != 0 ? 0xFF : 0; B = (i & 4) != 0 ? 0xFF : 0; T = 0x40; } } else { R = ((i & 1) != 0 ? 0x55 : 0) + ((i & 0x10) != 0 ? 0xAA : 0); G = ((i & 2) != 0 ? 0x55 : 0) + ((i & 0x20) != 0 ? 0xAA : 0); B = ((i & 4) != 0 ? 0x55 : 0) + ((i & 0x40) != 0 ? 0xAA : 0); T = 0xFF; } } else if ((i & 0x88) == 8) { R = ((i & 1) != 0 ? 0x55 : 0) + ((i & 0x10) != 0 ? 0xAA : 0); G = ((i & 2) != 0 ? 0x55 : 0) + ((i & 0x20) != 0 ? 0xAA : 0); B = ((i & 4) != 0 ? 0x55 : 0) + ((i & 0x40) != 0 ? 0xAA : 0); T = 0x80; } else if ((i & 0x88) == 0x80) { R = ((i & 1) != 0 ? 0x2A : 0) + ((i & 0x10) != 0 ? 0x55 : 0) + 0x80; G = ((i & 2) != 0 ? 0x2A : 0) + ((i & 0x20) != 0 ? 0x55 : 0) + 0x80; B = ((i & 4) != 0 ? 0x2A : 0) + ((i & 0x40) != 0 ? 0x55 : 0) + 0x80; T = 0xFF; } else if ((i & 0x88) == 0x88) { R = ((i & 1) != 0 ? 0x2A : 0) + ((i & 0x10) != 0 ? 0x55 : 0); G = ((i & 2) != 0 ? 0x2A : 0) + ((i & 0x20) != 0 ? 0x55 : 0); B = ((i & 4) != 0 ? 0x2A : 0) + ((i & 0x40) != 0 ? 0x55 : 0); T = 0xFF; } return (T<<24 | R<<16 | G<<8 | B); } private void paintRegionBackground() { if (!region.isActive() || !region.getFillFlag()) return; int color; if (IRD == 2) color = clut.getCLUT_2bit()[mapColorIndex(region.getPixelCode_2bit(), 2, IRD)]; else if (IRD == 4) color = clut.getCLUT_4bit()[mapColorIndex(region.getPixelCode_4bit(), 4, IRD)]; else color = clut.getCLUT_8bit()[mapColorIndex(region.getPixelCode_8bit(), 8, IRD)]; color = scaleRGB(color); java.util.Arrays.fill(pixel_data, color); } // private void paintRegionBorder(int x, int y, int w, int h) { big.setColor(Color.white); big.drawRect( x -1, y -1, w +2, h +1); big.drawString("x" + x + ", y" + y + " / " + w + "*" + h, x , y - 6); } // only for painted preview picture, else not necessary private void clearBackground() { java.util.Arrays.fill(preview_pixel_data, 0x60); big.setColor( new Color(0, 0, 0x60)); //deep blue to see full transparency big.fillRect( bimg.getMinX(), bimg.getMinY(), bimg.getWidth(), bimg.getHeight()); } private void paintPixelLine(int x, int y, int w, int color_index, int depth) { x += object.getHorizontalPosition(); y += object.getVerticalPosition(); int color = 0, color_model = IRD; color_index = mapColorIndex(color_index, depth, IRD); if (clut.getModifyFlags() > 0 && (clut.getModifyFlags() & IRD) == 0) //remap if no alternative color def. { color_index = mapColorIndex(color_index, IRD, depth); color_model = depth; } if (color_model == 2) color = clut.getCLUT_2bit()[color_index]; else if (color_model == 4) color = clut.getCLUT_4bit()[color_index]; else color = clut.getCLUT_8bit()[color_index]; color = scaleRGB(color); if ((0xFF000000 & color) == 0) //keep underlying pixel if new pixel is full transparent return; //DM23062004 081.7 int05 add if (x > region.getWidth() - 1 || y > region.getHeight() - 1) { region.setError(2); return; } from_index = x + y * region.getWidth(); to_index = from_index + w; //DM23062004 081.7 int05 add if (x + w > region.getWidth()) { to_index = from_index + region.getWidth() - x; region.setError(1); } java.util.Arrays.fill(pixel_data, from_index, to_index, color); } // not yet exported, only info for existence private void paintStringObjects(int x, int y, String str) { x += object.getHorizontalPosition(); y += object.getVerticalPosition(); big.setColor(Color.cyan); big.drawString(str, x , y + 26); } private void paintCopiedField(int x, int y, int w) { System.arraycopy(pixel_data, x + y * w, pixel_data, x + (y + 1) * w, w); } private int scaleRGB(int ARGB) { if ((ARGB & 0xFF000000) == 0) //deep blue to see full transparency return 0x60; int R = 15 + (0xFF & ARGB>>>16); int G = 15 + (0xFF & ARGB>>>8); int B = 15 + (0xFF & ARGB); R = R > 0xEB ? 0xEB : R; G = G > 0xEB ? 0xEB : G; B = B > 0xEB ? 0xEB : B; // color float scale 16..235 for RGB //int R = 16 + (int)(0.85546875f * (0xFF & ARGB>>>16)); //int G = 16 + (int)(0.85546875f * (0xFF & ARGB>>>8)); //int B = 16 + (int)(0.85546875f * (0xFF & ARGB)); int T = 0xFF & ARGB>>>24; return (T<<24 | R<<16 | G<<8 | B); } private int mapColorIndex(int color_index, int depth, int new_depth) // depth is 2,4,8! { switch (new_depth) { case 2: if (depth == 8) color_index >>>= 4; if (depth > 2) color_index = (2 & color_index>>>2) | (1 & color_index>>>2) | (1 & color_index>>>1) | (1 & color_index); break; case 4: if (depth == 2) color_index = (object != null) ? object.getMapTable_2to4bit()[color_index] : color_index; else if (depth == 8) color_index >>>= 4; break; case 8: if (depth == 2) color_index = (object != null) ? object.getMapTable_2to8bit()[color_index] : color_index; else if (depth == 4) color_index = (object != null) ? object.getMapTable_4to8bit()[color_index] : color_index; } return color_index; } //DM13062004 081.7 int04 add private void setUserClut() { int model = Integer.parseInt(user_table.get("model").toString().trim()); int max_indices = model > 2 ? (model > 4 ? 256 : 16) : 4; if (region.getDepth() < model) max_indices = region.getDepth(); for (int i = 0; i < max_indices; i++) { if (user_table.containsKey("" + i)) { addBigMessage("addUserClut: " + i + " /ARGB " + user_table.get("" + i)); clut.setClutEntry(mapColorIndex(i, region.getDepth(), model), model, (int)Long.parseLong(user_table.get("" + i).toString().trim(), 16)); } } } private Epoch setEpoch(int epoch_id) { String epoch_id_str = "" + epoch_id; if ( !epoches.containsKey(epoch_id_str) ) epoches.put(epoch_id_str, new Epoch(epoch_id) ); return (Epoch)epoches.get(epoch_id_str); } class Epoch { private int id; private Hashtable pages = new Hashtable(); private Hashtable cluts = new Hashtable(); private Hashtable regions = new Hashtable(); private Hashtable objects = new Hashtable(); private Epoch() {} private Epoch(int val) { id = val; } private void setId(int val) { id = val; } private int getId() { return id; } private Page setPage(int page_id) { String page_id_str = "" + page_id; if ( !pages.containsKey(page_id_str) ) pages.put(page_id_str, new Page(page_id) ); return (Page)pages.get(page_id_str); } private Page newPage(int page_id) { String page_id_str = "" + page_id; pages.put(page_id_str, new Page(page_id) ); return (Page)pages.get(page_id_str); } private Region setRegion(int region_id) { String region_id_str = "" + region_id; if (!regions.containsKey(region_id_str) ) regions.put(region_id_str, new Region(region_id) ); return (Region)regions.get(region_id_str); } private CLUT setCLUT(int CLUT_id) { String CLUT_id_str = "" + CLUT_id; if ( !cluts.containsKey(CLUT_id_str) ) cluts.put(CLUT_id_str, new CLUT(CLUT_id) ); return (CLUT)cluts.get(CLUT_id_str); } private OBJECT setObject(int object_id) { String object_id_str = "" + object_id; if ( !objects.containsKey(object_id_str) ) objects.put(object_id_str, new OBJECT(object_id) ); return (OBJECT)objects.get(object_id_str); } private void clearRegions() { for (Enumeration e = regions.keys(); e.hasMoreElements() ; ) ((Region)regions.get(e.nextElement().toString())).setActive(false); } private Enumeration getRegions() { return regions.keys(); } private void clearObjects() { objects.clear(); } } class Page { private int id; private int version_number = -1; private long time_in = 0; private int time_out = 0; private int state; private int minX = 720, minY = 576, maxX = 0, maxY = 0; private int pixel[]; private boolean write = false; private Page() {} private Page(int val) { id = val; } private void setId(int val) { id = val; } private int getId() { return id; } private void setVersionNumber(int val) //modulo16, if a change { version_number = val; } private int getVersionNumber() { return version_number; } private void setWriteStatus(boolean b) { write = b; } private boolean getWriteStatus() { return write; } private void setTimeIn(long val) { time_in = val; } private long getTimeIn() { return time_in; } private void setTimeOut(int val) { time_out = val; } private int getTimeOut() { return time_out; } private int[] initPixel() { return (pixel = new int[720 * 576]); } private int[] getPixel() { return pixel; } private void setState(int val) { state = val; } private int getState() { return state; } private void clearArea() { minX = 720; minY = 576; maxX = maxY = 0; } private void addArea(int x, int y, int w, int h) { int x2 = x + w; int y2 = y + h; minX = x < minX ? x : minX; minY = y < minY ? y : minY; maxX = x2 > maxX ? x2 : maxX; maxY = y2 > maxY ? y2 : maxY; } private int getX() { return minX; } private int getY() { return minY; } private int getWidth() { return (maxX - minX); } private int getHeight() { return (maxY - minY); } } class Region { private int id; private int horizontal_address; private int vertical_address; private int version_number = -1; private boolean fill_flag; private boolean active = false; private boolean changed = false; private int width; private int height; private int x; private int y; private int level_of_compatibility; private int depth; private int CLUT_id; private int pixel_code_8bit; private int pixel_code_4bit; private int pixel_code_2bit; private int pixel[]; //DM23062004 081.7 int05 add private int error = 0; private Region() {} private Region(int val) { id = val; } private void setId(int val) { id = val; } private int getId() { return id; } private void setHorizontalAddress(int val) { horizontal_address = val; x = 0; } private void setVerticalAddress(int val) { vertical_address = val; y = 0; } private void setVersionNumber(int val) //modulo16, if a change { version_number = val; } private int getVersionNumber() { return version_number; } private int[] initPixel() { return (pixel = new int[width * height]); } private int[] getPixel() { return pixel; } private void setFillFlag(int val) // fill background with color of region_pixel_code_xbit index { fill_flag = val != 0; } private boolean getFillFlag() { return fill_flag; } private void setActive(boolean b) { active = b; } private boolean isActive() { return active; } private void setWidth(int val) //max 720, if h_address =1 { width = val; } private int getWidth() { return width; } private void setHeight(int val) //max 576, if v_address =1 { height = val; } private int getHeight() { return height; } private void setLevelOfCompatibility(int val) //1,2,3 = 2,4,8bit supported colors by IRD, X can use all :) { level_of_compatibility = val; } private int getCompatibility() { return level_of_compatibility; } private void setDepth(int val) //1,2,3 = 2,4,8bit pixel depth { depth = 1<>>8); tmp[35 + tp] = (byte)(0xFF & difference); Common.getGuiInterface().setSubpictureTitle(" / " + Resource.getString("subpicture.in_time") + ": " + Common.formatTime_1(in_time / 90) + " " + Resource.getString("subpicture.duration") + ": " + Common.formatTime_1((out_time - in_time) / 90) ); // if (debug) // System.out.println("in " + in_time + "/out " + out_time + "/d1 " + (out_time - in_time) + "/90 " + ((out_time - in_time)/90) + "/d2 " + difference); return tmp; } /** * build Image from text */ private void buildImgTTX(Object obj) { int space = 6; Rect[0] = option[3]; Rect[3] = (2 * space) + (line_offset * str.length); Rect[1] = option[6] - option[2] - Rect[3]; Rect[2] = option[4]; pos[0] = Rect[0]; pos[1] = Rect[1]; pos[2] = Rect[0] + Rect[2] - 1; pos[3] = Rect[1] + Rect[3] - 1; paintVideoSize(obj); big.setColor(Color.white); big.drawRect(Rect[0] - 1, Rect[1] - 1, Rect[2] + 1, Rect[3] + 1); big.setFont(font_std); big.drawString("x" + pos[0] + ", y" + pos[1] + " / " + (pos[2] - pos[0] + 1) + "*" + (pos[3] - pos[1] + 1), Rect[0] - 1, Rect[1] - 5); int color_table[] = getColorTable(1); big.setFont(font); ArrayList list = new ArrayList(); boolean antialiasing; /** * pre-check, whether we have not more than 2 'speaker-colors' */ for (int a = 0; a < str.length; a++) { int[] chars = (int[])str[a]; for (int b = 0; b < chars.length; b++) { //source background color int offset = (7 & chars[b]>>>4)<<3; //source modified foreground color int paint_color = color_table[offset + (7 & chars[b])]; String nstr = Integer.toString(paint_color); String sign = new Character((char)(chars[b]>>>8)).toString(); //remember new color if (list.indexOf(nstr) < 0 && !sign.equals(" ")) list.add(nstr); } } /** * define background; if less than 3 front-colors, use 'simple' antialiasing with full transparency */ if (list.size() < 3 && Common.getSettings().getBooleanProperty(Keys.KEY_SubtitlePanel_useTextOutline)) { big.setColor(new Color(color_table[65])); // deep blue, full transp modified_alpha = 0; antialiasing = true; } else { big.setColor(new Color(color_table[64])); // black, half transp modified_alpha = default_alpha; antialiasing = false; } big.fillRect(Rect[0], Rect[1], Rect[2], Rect[3]); // background Rectangle2D r; // paint background of char for (int a = 0; antialiasing && a < str.length; a++) { int[] chars = (int[])str[a]; String nstr = ""; big.setColor(new Color(color_table[64])); // black /** * concatenate string, no special colors required */ for (int i = 0; i < chars.length; i++) nstr += new Character((char)(chars[i]>>>8)).toString(); x = option[3]; int y = Rect[1] + (line_offset * (1 + a)); int[] offs = new int[(option[9] * 2) + 1]; /** * overhead around a pixel: x pix WEST, 1 pix MID, x pix EAST * pix > 4 not recommended, option[9] = outline_pixels */ offs[0] = offs[offs.length - 1] = option[9] - 1; Arrays.fill(offs, 1, offs.length - 1, option[9]); for (int i = 0; i < offs.length; i++) // horiz. lines { int _x = x; int _y = y - (offs.length / 2) + i; for (int j = -offs[i]; j < offs[i] + 1; j++) big.drawString(nstr, _x + j, _y); } } // paint ascii char for (int a=0; a < str.length; a++) { int[] chars = (int[])str[a]; x = option[3]; for (int b=0; b < chars.length; b++) { //source background color int offset = (7 & chars[b]>>>4)<<3; //source foreground color big.setColor(new Color(color_table[offset + (7 & chars[b])])); big.drawString("" + (char)(chars[b]>>>8), x, Rect[1] + (line_offset * (1 + a))); x += font.getStringBounds("" + (char)(chars[b]>>>8), frc).getWidth(); } } } public void resetUserColorTable() { user_color_table.clear(); } public Object[] getUserColorTableArray() { return user_color_table.toArray(); } public ArrayList getUserColorTable() { return user_color_table; } public void updateUserColorTable(Bitmap new_bitmap) { bitmap = new_bitmap; int pixel[] = bitmap.getPixel(); for (int a=0; a < pixel.length; a++) { String pixel_str = "" + pixel[a]; if (!user_color_table.contains(pixel_str)) user_color_table.add(pixel_str); bitmap.getColorIndex(getUserColorTableIndex(pixel[a])); } } private void updateUserColorTable(int pixel[]) { for (int a=0; a < pixel.length; a++) { String pixel_str = "" + pixel[a]; if (user_color_table.contains(pixel_str)) continue; else user_color_table.add(pixel_str); } } private int getUserColorTableIndex(int color_index) { int value; if ((value = user_color_table.indexOf("" + color_index)) < 0) return 0; return value; } public byte[] writeRLE(long start_time, int onscreen_time) throws IOException { read_from_Image = true; // use user defined alpha value for color index 0 bitmap = new Bitmap( Rect[0], Rect[1], Rect[2], Rect[3], bimg.getRGB(Rect[0], Rect[1], Rect[2], Rect[3], null, 0, Rect[2]), 2, 0, 1, 2, start_time, onscreen_time); return buildRLE(); } public byte[] writeRLE(Bitmap new_bitmap) throws IOException { bitmap = new_bitmap; setArea(); return buildRLE(); } private byte[] buildRLE() { byte picture_packet[] = null; try { int pixels[] = bitmap.getPixel(); updateUserColorTable(pixels); out.reset(); out.write(RLEheader); //start picture in .sup form int bottom_field_start_pos = 0; // read out interlaced RGB for (int i=0, l=0, a=0, b=0, color_index=0; i < 2; i++) { // top_field first for (l=0, color_index=0, a = i * bitmap.getWidth(); a < pixels.length; a += (2 * bitmap.getWidth())) { for (l=0, color_index=0, b=0; b < bitmap.getWidth(); b++, l++) { if (pixels[a + b] != color_index) { // write last RLE nibbles, while color change updateRLE(l, color_index); color_index = pixels[a + b]; l=0; } else if ( l > 254 ) { // write last RLE nibbles, cannot incl. more than 255 pixels updateRLE(l, color_index); l=0; } // std: adds l-bit to active color } l -= 1; while ( l > 255 ) // never used ?! { updateRLE(255, color_index); l -= 255; } updateRLE(l, color_index); // write last RLE nibbles, line end alignRLE(); out.write(newline); // new line CR, byte aligned } alignRLE(); if (bottom_field_start_pos == 0) bottom_field_start_pos = out.size() - 10; // save startpos of bottom_field (size-14) } out.write(newline); //DM26052004 081.7 int03 add , not the best solution, but need the "0,0" here int pack = out.size() - 12; int control_block_pos = pack + 24; int onscreen_time_pos = out.size() + 22; setScreenPosition(bitmap.getX(), bitmap.getY(), bitmap.getMaxX() - 1, bitmap.getMaxY() - 1); setControlBlockPosition(control_block_pos, bottom_field_start_pos); setPGCsection(); out.write(sections); //write control_block if ((out.size() & 1) == 1) out.write((byte)255); out.flush(); picture_packet = out.toByteArray(); int size = picture_packet.length - 10; picture_packet[10] = (byte)(0xFF & size>>>8); picture_packet[11] = (byte)(0xFF & size); picture_packet[12] = (byte)(0xFF & pack>>>8); picture_packet[13] = (byte)(0xFF & pack); for (int a=0; a < 4; a++) picture_packet[a + 2] = (byte)(0xFF & bitmap.getInTime()>>>(a*8)); picture_packet[onscreen_time_pos] = (byte)(0xFF & bitmap.getPlayTime()>>>8); picture_packet[onscreen_time_pos + 1] = (byte)(0xFF & bitmap.getPlayTime()); } catch (IOException e) { Common.setExceptionMessage(e); } read_from_Image = false; return picture_packet; } // write last nibble, if it was not aligned private void alignRLE() { if (nibble == 0) return; else { out.write((byte)val); val = nibble = 0; } } private void updateRLE(int l, int color_index) { if (l < 1) return; // color_index shall not exceed value 3! int pgc_color = getUserColorTableIndex(color_index); pgc_color = bitmap.getColorIndex(pgc_color); l = l<<2 | pgc_color; // combine bits + color_index // new byte begin if (nibble == 0) { if (l > 0xFF) // 16 { out.write((byte)(0xFF & l>>>8)); out.write((byte)(0xFF & l)); } else if (l > 0x3F) // 12 { out.write((byte)(0xFF & l>>>4)); val = 0xF0 & l<<4; nibble = 4; } else if (l > 0xF) // 8 { out.write((byte)(0xFF & l)); } else // 4 { val = 0xF0 & l<<4; nibble = 4; } } else // middle of byte { if (l > 0xFF) // 16 { out.write((byte)(val | (0xF & l>>>12))); out.write((byte)(0xFF & l>>>4)); val = 0xF0 & l<<4; } else if (l > 0x3F) // 12 { out.write((byte)(val | (0xF & l>>>8))); out.write((byte)(0xFF & l)); val = nibble = 0; } else if (l > 0xF) // 8 { out.write((byte)(val | (0xF & l>>>4))); val = 0xF0 & l<<4; } else // 4 { out.write((byte)(val | (0xF & l))); val = nibble = 0; } } } private void setScreenPosition(int minX, int minY, int maxX, int maxY) { // set planned pic pos. on tvscreen sections[9] = (byte)(minX>>>4); sections[10] = (byte)(minX<<4 | maxX>>>8); sections[11] = (byte)maxX; sections[12] = (byte)(minY>>>4); sections[13] = (byte)(minY<<4 | maxY>>>8); sections[14] = (byte)maxY; } private void setControlBlockPosition(int control_block_pos, int bottom_field_start_pos) { // top_field sections[16] = 0; sections[17] = 4; // bottom_field sections[18] = (byte)(0xFF & bottom_field_start_pos>>>8); sections[19] = (byte)(0xFF & bottom_field_start_pos); // control_block sections[0] = sections[24] = (byte)(0xFF & control_block_pos>>>8); sections[1] = sections[25] = (byte)(0xFF & control_block_pos); } private void setPGCsection() { int pgc_values = setPGClinks(); // color index 3,2 + 1,0 sections[3] = (byte)(0xFF & pgc_values>>>8); sections[4] = (byte)(0xFF & pgc_values); // alpha index 3,2 + 1,0 sections[6] = (byte)(0xFF & pgc_values>>>24); sections[7] = (byte)(0xFF & pgc_values>>>16); } public int setPGClinks() { Object pgc_color_links[] = bitmap.getColorIndices(); Object pgc_alpha_links[] = getUserColorTableArray(); int pgc_colors = 0xFE10; int pgc_alphas = 0xFFF9; int pgc_color_value, pgc_alpha_value; for (int a=0; a < 4; a++) { if (a < pgc_color_links.length) { pgc_color_value = 0xF & Integer.parseInt(pgc_color_links[a].toString()); pgc_alpha_value = 0xF & Integer.parseInt(pgc_alpha_links[pgc_color_value].toString())>>>28; pgc_colors = (pgc_colors & ~(0xF<<(a * 4))) | pgc_color_value<<(a * 4); pgc_alphas = (pgc_alphas & ~(0xF<<(a * 4))) | pgc_alpha_value<<(a * 4); } } if (read_from_Image) // pgc_alphas &= (0xFFF0 | default_alpha); pgc_alphas &= (0xFFF0 | modified_alpha); return (pgc_alphas<<16 | pgc_colors); } public void set2() { option[2] = option[7]; } public int getMaximumLines() { return option[8]; } /*** set user packet ("Font pointsize; Backgr. Alpha value; Yoffset; Xoffset; Screenwidth"); **/ public int[] set(String nm, String values) { resetUserColorTable(); System.arraycopy(standard_values, 0, option, 0, standard_values.length); StringTokenizer st = new StringTokenizer(values, ";"); int a = 0; while (st.hasMoreTokens() && a < option.length) { option[a] = Integer.parseInt(st.nextToken()); a++; } line_offset = option[0] + 2; default_alpha = 0xF & option[1]; font = new Font(nm, option[10] == 0 ? Font.PLAIN : Font.BOLD, option[0]); font_std = new Font("Tahoma", Font.PLAIN, 14); //DM01032004 081.6 int18 add int[] ret_val = { option[2], option[7] }; return ret_val; } /** * */ private int[] getColorTable(int flag) { //define alternative color_table here if (flag == 0) return default_sup_colors; else return default_teletext_colors; } /** * */ private void setArea() { Rect[0] = bitmap.getX(); Rect[1] = bitmap.getY(); Rect[2] = bitmap.getWidth(); Rect[3] = bitmap.getHeight(); pos[0] = bitmap.getX(); pos[1] = bitmap.getY(); pos[2] = bitmap.getMaxX(); pos[3] = bitmap.getMaxY(); } /** * */ public String getArea() { String string = ""; string += "x " + Rect[0]; string += " y " + Rect[1]; string += " w " + Rect[2]; string += " h " + Rect[3]; string += " x1 " + pos[0]; string += " y1 " + pos[1]; string += " x2 " + pos[2]; string += " y2 " + pos[3]; return string; } /** * */ private int paintVideoSize(Object obj) { String[] str = (String[]) obj; int video_horizontal = 720; int video_vertical = 576; // H video_horizontal = str[0] == null ? 720 : Integer.parseInt(str[0]); // V video_vertical = str[1] == null ? 576 : Integer.parseInt(str[1]); //deep red background to verify picture rectangle with given video resolution big.setColor(new Color(0xFF550000)); big.fillRect(0, 0, w, h); //picture area which the subpicture must not exceed, have to adjust to the hor. middle of it big.setColor(Color.gray); big.fillRect(0, 0, video_horizontal, video_vertical); return video_vertical; } /** * */ private void Set_Bits(byte buf[], int BPos[], int N, int Val) { int Pos = BPos[1]>>>3; int BitOffs = BPos[1] & 7; if (Pos >= buf.length || BitOffs + N >= (BPos[1] & ~7) + 32) { global_error = true; } else { int NoOfBytes = 1 + ((BitOffs + N - 1)>>>3); int NoOfBits = NoOfBytes<<3; int tmp_value = CommonParsing.getIntValue(buf, Pos, NoOfBytes, !CommonParsing.BYTEREORDERING); int mask = (-1)>>>(32 - N); int k = NoOfBits - N - BitOffs; mask <<= k; Val <<= k; tmp_value &= ~mask; tmp_value |= (Val & mask); CommonParsing.setValue(buf, Pos, NoOfBytes, !CommonParsing.BYTEREORDERING, tmp_value); } BPos[1] += N; BPos[0] = BPos[1]>>>3; } /** * */ private int Get_Bits(byte buf[], int BPos[], int N) { int Pos, Val; Pos = BPos[1]>>>3; if (Pos >= buf.length) { global_error = true; BPos[1] += N; BPos[0] = BPos[1]>>>3; return 0; } Val = (0xFF & buf[Pos++])<<24; if (Pos < buf.length) Val |= (0xFF & buf[Pos++])<<16; if (Pos < buf.length) Val |= (0xFF & buf[Pos++])<<8; if (Pos < buf.length) Val |= (0xFF & buf[Pos]); Val <<= BPos[1] & 7; Val >>>= 32-N; BPos[1] += N; BPos[0] = BPos[1]>>>3; return Val; } /** * */ private int Show_Bits(byte buf[], int BPos[], int N) { int Pos, Val; Pos = BPos[1]>>>3; if (Pos >= buf.length) { global_error = true; return 0; } Val = (0xFF & buf[Pos++])<<24; if (Pos < buf.length) Val |= (0xFF & buf[Pos++])<<16; if (Pos < buf.length) Val |= (0xFF & buf[Pos++])<<8; if (Pos < buf.length) Val |= (0xFF & buf[Pos]); Val <<= BPos[1] & 7; Val >>>= 32 - N; return Val; } /** * */ private void Flush_Bits(int BPos[], int N) { BPos[1] += N; BPos[0] = BPos[1]>>>3; } /** * */ private void align_Bits(int BPos[]) { if ((1 & BPos[1]>>>2) != 0) Flush_Bits( BPos, 4); } /** * */ public String isForced_Msg() { String str = null; //change of status occured if ((isforced_status & 1) == 0) { if ((isforced_status & 2) > 0) str = Resource.getString("subpicture.msg.forced.no"); else str = Resource.getString("subpicture.msg.forced.yes"); } isforced_status |= 1; return str; } /** * */ public void reset() { isforced_status = 0; set_XY_Offset(0, 0); setDisplayMode(0); } /** * modify X,Y Position */ public void set_XY_Offset(int x_value, int y_value) { X_Offset = x_value; Y_Offset = y_value; } /** * modify force display flag */ public void setDisplayMode(int value) { DisplayMode = value; } /** * */ public int decode_picture(byte[] packet, int off, boolean decode, Object obj) { return decode_picture(packet, off, decode, obj, 0, false, true); } /** * */ public int decode_picture(byte[] packet, int off, boolean decode, Object obj, long pts, boolean save, boolean visible) { read_from_Image = false; global_error = false; boolean simple_picture = false; int picture_length = packet.length; int BPos[] = { off, off<<3 }; //BytePos, BitPos int position[] = new int[4]; int start_pos[] = new int[3]; int print_colors[] = new int[4]; if (BPos[0] > picture_length) return -4; int packetlength = Get_Bits(packet, BPos, 16); // required pack length if (Show_Bits(packet, BPos, 24) == 0xF) // DVB subpicture: 8bit padding 0x00 + 8bit subtitle_stream_id 0x00 + start of subtitle segment 0x0F { big.setFont(font_std); byte[] data = new byte[picture_length + 4]; System.arraycopy(packet, 0, data, 0, picture_length); int ret = dvb.decodeDVBSubpicture(data, BPos, big, bimg, pts, save, visible); if (ret > -2) repaint(); return ret; } if (BPos[0] + packetlength != picture_length + 2) return -5; start_pos[2] = Get_Bits(packet, BPos, 16) - 2; Flush_Bits(BPos, start_pos[2]<<3); // jump to sections chunk int playtime_pos = Get_Bits(packet, BPos, 16); //fixed pos, so it must follow the 1st ctrl sequ, if (playtime_pos == start_pos[2] + 2) { playtime_pos = packetlength; simple_picture = true; Common.setMessage(Resource.getString("subpicture.msg2")); } else start_pos[2] += off + 2; int color_table[] = getColorTable(0); while (BPos[0] < off + playtime_pos) // read sections chunk { int cmd_switch = Show_Bits(packet, BPos, 8); // show at first, to enable editing switch(cmd_switch) { case 0: // force display flag isforced_status = (isforced_status & 5) != 5 ? 4 : 5; if (DisplayMode == 2) //set normal Set_Bits(packet, BPos, 8, 1); else Flush_Bits(BPos, 8); break; case 1: // start display flag, normal isforced_status = (isforced_status & 3) != 3 ? 2 : 3; if (DisplayMode == 1) //set forced Set_Bits(packet, BPos, 8, 0); else Flush_Bits(BPos, 8); break; case 2: // stop display flag case 0xFF: // end of ctrl sequ. Flush_Bits(BPos, 8); break; case 3: // 4 color links Flush_Bits(BPos, 8); for (int b = 0; b < 4; b++) print_colors[3 - b] |= (color_table[Get_Bits(packet, BPos, 4)] & 0xFFFFFF); break; case 4: // alpha blending Flush_Bits(BPos, 8); for (int b = 0; b < 4; b++) print_colors[3 - b] |= (0x11 * (0xF ^ Get_Bits(packet, BPos, 4)))<<24; break; case 5: // x,y pos. Flush_Bits(BPos, 8); if (X_Offset != 0) //move X-pos { position[0] = Show_Bits(packet, BPos, 12) + X_Offset; //X-links Set_Bits(packet, BPos, 12, position[0]); //X-links position[1] = Show_Bits(packet, BPos, 12) + X_Offset; //X-rechts Set_Bits(packet, BPos, 12, position[1]); //X-rechts } else { position[0] = Get_Bits(packet, BPos, 12); //X-links position[1] = Get_Bits(packet, BPos, 12); //X-rechts } if (Y_Offset != 0) //move Y-pos { position[2] = Show_Bits(packet, BPos, 12) + Y_Offset; //Y-oben Set_Bits(packet, BPos, 12, position[2]); //Y-oben position[3] = Show_Bits(packet, BPos, 12) + Y_Offset; //Y-unten Set_Bits(packet, BPos, 12, position[3]); //Y-unten } else { position[2] = Get_Bits(packet, BPos, 12); //X-links position[3] = Get_Bits(packet, BPos, 12); //X-rechts } break; case 6: // pos. of decode_start of a field Flush_Bits(BPos, 8); for (int b = 0; b < 2; b++) start_pos[b] = Get_Bits(packet, BPos, 16); break; case 7: // extra alpha + color area definition Flush_Bits(BPos, 8); Flush_Bits(BPos, 16); break; default: Common.setMessage(Resource.getString("subpicture.msg3") + ": " + cmd_switch); } } if (off + playtime_pos != BPos[0]) return -6; int playtime = 0; if (!simple_picture) { playtime = Get_Bits(packet, BPos, 16); if (playtime_pos != Get_Bits(packet, BPos, 16)) return -7; if (Get_Bits(packet, BPos, 8) != 2) return -8; Flush_Bits( BPos, ((BPos[0] & 1) != 1) ? 16 : 8 ); } if (BPos[0] != picture_length) return -9; if (global_error) return -3; if (!decode) return (playtime * 1024); //DM26052004 081.7 int03 changed , 900, 1000 for (int b=0; b<2; b++) start_pos[b] += off; paintVideoSize(obj); int y0 = position[2]; int width = position[1] - position[0] + 1; int height = position[3] - position[2] + 1; big.setColor(Color.white); big.drawRect(position[0] - 1, y0 - 1, width + 1, height + 1); big.setFont(font_std); big.drawString("x" + position[0] + ", y" + position[2] + " / " + width + "*" + height, position[0] - 1, y0 - 5); for (int b=0; b<2; b++) { int Val=0, x1 = position[0], y1 = y0 + b; BPos[1] = (BPos[0] = start_pos[b])<<3; // top_field at first while (BPos[0] < start_pos[b+1]) // stop at pos_marker { if ((Val = Get_Bits(packet, BPos, 4)) > 3) //4..F (0..3 never encodable) { big.setColor(new Color(print_colors[Val & 3])); big.drawLine(x1, y1, (x1 += Val>>>2), y1); } else if ((Val = Val<<4 | Get_Bits(packet, BPos, 4)) > 0xF) //10..3F { big.setColor(new Color(print_colors[Val & 3])); big.drawLine(x1, y1, (x1 += Val>>>2), y1); } else if ((Val = Val<<4 | Get_Bits(packet, BPos, 4)) > 0x3F) //40..FF { big.setColor(new Color(print_colors[Val & 3])); big.drawLine(x1, y1, (x1 += Val>>>2), y1); } else if ((Val = Val<<4 | Get_Bits(packet, BPos, 4)) > 0) //100..3FF { big.setColor(new Color(print_colors[Val & 3])); big.drawLine(x1, y1, (x1 += Val>>>2), y1); } else // 0 forced carriage return { x1 = position[0]; y1 += 2; align_Bits(BPos); continue; } /** if (x1 >= position[1]) // line end, carriage return { x1=position[0]; y1+=2; align_Bits(BPos); } **/ } } repaint(); if (global_error) return -3; return (playtime * 1024); //DM26052004 081.7 int03 changed, 900, 1000 } } project-x/src/net/sourceforge/dvb/projectx/subtitle/Teletext.java0000600000175000017500000005332610411553556026742 0ustar supermariosupermario/* * @(#)Teletext.java - constants/decode of teletext System B * * Copyright (c) 2001-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.subtitle; import java.util.Hashtable; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Keys; public final class Teletext extends Object { private Teletext() {} private final static String[] ssaHeader = { "[Script Info]", "; This is a Sub Station Alpha v4 script.", "; For Sub Station Alpha info and downloads,", "; go to http://www.eswat.demon.co.uk/", "; or email kotus@eswat.demon.co.uk", "; to burn-in these subtitles into an AVI, just install subtitler2.3 PlugIn for VirtualDub, see doom9.org", "Title: Subtitles taken from TV teletext", "Original Script: by their respective owner", "ScriptType: v4.00", "Collisions: Normal", "PlayResY: 240", // maybe replaced [10] "PlayDepth: 0", "Timer: 100.0000", // maybe replaced [12] "[V4 Styles]", "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, TertiaryColour, BackColour, Bold, Italic, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding", "Style: MainB,Arial,14,&H00FFFF,&H00FFFF,&H00FFFF,0,0,-1,1,2,4,1,16,16,16,0,0", "Style: MainT,Arial,14,&HFFFFFF,&HFFFFFF,&HFFFFFF,0,1,0,1,2,4,1,16,16,16,0,0", "Style: MainI,Arial,14,&HFFFFFF,&HFFFFFF,&HFFFFFF,0,1,1,1,2,4,1,16,16,16,0,0", //DM30122003 081.6 int10 add "Style: MainC,Courier New,14,&HFFFFFF,&HFFFFFF,&HFFFFFF,0,1,0,1,2,4,1,16,16,16,0,0", "[Events]", "Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text", "Comment: Marked=0,0:00:00.00,0:00:00.01,MainB,,0000,0000,0000,!Effect,This script was created by decoding a tv teletext stream to build coloured subtitles" }; private final static String[] ssaLine = { "Dialogue: Marked=0,", ",MainT,,0000,0000,0000,!Effect,{\\q2\\a2}" }; //DM26052004 081.7 int03 changed private final static String[] stlHeader = { "", "//Font select and font size", "$FontName = Arial", "$FontSize = 30", "//Character attributes (global)", "$Bold = FALSE", "$UnderLined = FALSE", "$Italic = FALSE", "//Position Control", "$HorzAlign = Center", "$VertAlign = Bottom", "$XOffset = 10", "$YOffset = 10", "//Contrast Control", "$TextContrast = 15", "$Outline1Contrast = 8", "$Outline2Contrast = 15", "$BackgroundContrast = 0", "//Effects Control", "$ForceDisplay = FALSE", "$FadeIn = 0", "$FadeOut = 0", "//Other Controls", "$TapeOffset = FALSE", "//Colors", "$ColorIndex1 = 0", "$ColorIndex2 = 1", "$ColorIndex3 = 2", "$ColorIndex4 = 3", "//Subtitles" }; //DM14052004 081.7 int02 add private final static String[] sonHeader = { "st_format\t2", "Display_Start\tnon_forced", "TV_Type\t\tPAL", "Tape_Type\tNON_DROP", "Pixel_Area\t(0 575)", "Directory\t", "", "SP_NUMBER\tSTART\t\tEND\t\tFILE_NAME" }; private final static String[] colors = { "{\\c&HC0C0C0&}", // black /gray "{\\c&H4040FF&}", // red "{\\c&H00FF00&}", // green "{\\c&H00FFFF&}", // yellow "{\\c&HFF409B&}", // blue //DM15032004 081.6 int18 changed "{\\c&HFF00FF&}", // magenta "{\\c&HFFFF00&}", // cyan "{\\c&HFFFFFF&}", // white }; //DM14052004 081.7 int02 add public static String[] getSONHead(String path, long frame_rate) { if (frame_rate != 3600) { sonHeader[2] = "TV_Type\t\tNTSC"; sonHeader[3] = "Tape_Type\tDROP"; } else { sonHeader[2] = "TV_Type\t\tPAL"; sonHeader[3] = "Tape_Type\tNON_DROP"; } sonHeader[5] = "Directory\t" + path; return sonHeader; } /***************** * return STL header * *****************/ public static String[] getSTLHead(String version) { stlHeader[0] = "//Generated by " + version; return stlHeader; } /***************** * return SSA header * *****************/ public static String[] getSSAHead() { return ssaHeader; } /***************** * return SSA line * *****************/ public static String[] getSSALine() { return ssaLine; } /***************** * return SMPTE * *****************/ public static String SMPTE(String time, long videoframetime) { StringBuffer a = new StringBuffer(); a.append(time.substring(0, 8) + ":00"); String b = "" + (Integer.parseInt(time.substring(9, 12)) / ((int)videoframetime / 90)); a.replace((b.length() == 1) ? 10 : 9 , 11, b); return a.toString(); } /***************** * change endian * *****************/ public static byte bytereverse(byte n) { n = (byte) (((n >> 1) & 0x55) | ((n << 1) & 0xaa)); n = (byte) (((n >> 2) & 0x33) | ((n << 2) & 0xcc)); n = (byte) (((n >> 4) & 0x0f) | ((n << 4) & 0xf0)); return n; } /************** * set parity * **************/ public static byte parity(byte n) { boolean par=true; if (n == 0) return n; for (int a=0; a < 8; a++) if ((n>>>a & 1) == 1) par = !par; if (par) return (byte)(0x80 | n); return n; } /**************** * check parity * ****************/ public static boolean cparity(byte n) { boolean par=true; if (n == 0) return true; for (int a=0; a < 7; a++) if ((n>>>a & 1) == 1) par = !par; if (par && (1 & n>>>7) == 1) return true; else if (!par && (1 & n>>>7) == 0) return true; return false; } //DM24052004 081.7 int03 introduced //no error correction ATM public static int hamming_24_18(byte b[], int off) { int val = 0; val |= (0xFE & b[off + 2])>>>1; val |= (0xFE & b[off + 1])<<6; val |= (0xE & b[off])<<13; val |= (0x20 & b[off])<<12; return val; } /****************** * hamming decode 8/4 * ******************/ public static int hamming_8_4(byte a) { switch (0xFF & a) { case 0xA8: return 0; case 0x0B: return 1; case 0x26: return 2; case 0x85: return 3; case 0x92: return 4; case 0x31: return 5; case 0x1C: return 6; case 0xBF: return 7; case 0x40: return 8; case 0xE3: return 9; case 0xCE: return 10; case 0x6D: return 11; case 0x7A: return 12; case 0xD9: return 13; case 0xF4: return 14; case 0x57: return 15; default: return -1; // decoding error , not yet corrected } } /****************************** * make suppic from teletext * ******************************/ public static int[] makepic(byte[] packet, int offset, int len, int row, int character_set, boolean checkParity) { // return int char<<8 | 0xF0 & active_color backgrnd | 0xF & active_color foregrnd boolean ascii = true, toggle = false; int chars[] = new int[len]; int active_color = 7; // init with white ascii color per line + black background int parity_error = 0; int language_code = Common.getSettings().getIntProperty(Keys.KEY_TtxLanguagePair) - 1; int primary_set_mapping = language_code < 0 ? 0 : language_code; int primary_national_set_mapping = character_set; int secondary_set_mapping = primary_set_mapping; int secondary_national_set_mapping = primary_national_set_mapping; if (page_modifications.containsKey("primary_set")) secondary_set_mapping = primary_set_mapping = Integer.parseInt(page_modifications.get("primary_set").toString()); if (page_modifications.containsKey("primary_national_set")) secondary_national_set_mapping = primary_national_set_mapping = Integer.parseInt(page_modifications.get("primary_national_set").toString()); if (page_modifications.containsKey("secondary_set")) { secondary_set_mapping = Integer.parseInt(page_modifications.get("secondary_set").toString()); secondary_national_set_mapping = Integer.parseInt(page_modifications.get("secondary_national_set").toString()); } active_set = CharSet.getActive_G0_Set(primary_set_mapping, primary_national_set_mapping, row); active_national_set = CharSet.getActiveNationalSubset(primary_set_mapping, primary_national_set_mapping, row); for (int c = offset, val, i = 0; i < len; c++, i++) { val = row<<16 | i; if (page_modifications.containsKey("" + val)) { chars[i] = active_color | (int)(page_modifications.get("" + val).toString().charAt(0))<<8; continue; } //if error, switch to graphics mode (= space) if (checkParity && !cparity(packet[c])) { parity_error++; packet[i] = 8; } int char_value = 0x7F & bytereverse(packet[c]); if (char_value>>>3 == 0) //0x0..7 { ascii=true; chars[i] = (active_set[32]<<8 | active_color); active_color = (0xF0 & active_color) | char_value; continue; } else if (char_value>>>4 == 0) //0x8..F { chars[i] = active_set[32]<<8 | active_color; continue; } else if (char_value>>>7 == 1) //0x80..FF { chars[i] = active_set[32]<<8 | active_color; continue; } else if (char_value < 27) //0x10..1A { ascii = false; chars[i] = active_set[32]<<8 | active_color; continue; } else if (char_value < 32) //0x1B..1F { switch (char_value) //1d=new bg with last color, 1c=black bg, 1b ESC { case 0x1B: if (toggle) { active_set = CharSet.getActive_G0_Set(primary_set_mapping, primary_national_set_mapping, row); active_national_set = CharSet.getActiveNationalSubset(primary_set_mapping, primary_national_set_mapping, row); } else { active_set = CharSet.getActive_G0_Set(secondary_set_mapping, secondary_national_set_mapping, row); active_national_set = CharSet.getActiveNationalSubset(secondary_set_mapping, secondary_national_set_mapping, row); } toggle = !toggle; break; case 0x1C: active_color &= 0xF; break; case 0x1D: active_color |= (0xF & active_color)<<4; } chars[i] = active_set[32]<<8 | active_color; continue; } else if (char_value == 0x7F) //0x7F { chars[i] = active_set[32]<<8 | active_color; continue; } if (!ascii) { chars[i] = active_set[32]<<8 | active_color; continue; } if (active_national_set != null) { // all chars 0x20..7F special characters switch (char_value) { case 0x23: chars[i] = active_color | active_national_set[0]<<8; continue; case 0x24: chars[i] = active_color | active_national_set[1]<<8; continue; case 0x40: chars[i] = active_color | active_national_set[2]<<8; continue; case 0x5b: chars[i] = active_color | active_national_set[3]<<8; continue; case 0x5c: chars[i] = active_color | active_national_set[4]<<8; continue; case 0x5d: chars[i] = active_color | active_national_set[5]<<8; continue; case 0x5e: chars[i] = active_color | active_national_set[6]<<8; continue; case 0x5f: chars[i] = active_color | active_national_set[7]<<8; continue; case 0x60: chars[i] = active_color | active_national_set[8]<<8; continue; case 0x7b: chars[i] = active_color | active_national_set[9]<<8; continue; case 0x7c: chars[i] = active_color | active_national_set[10]<<8; continue; case 0x7d: chars[i] = active_color | active_national_set[11]<<8; continue; case 0x7e: chars[i] = active_color | active_national_set[12]<<8; continue; } } chars[i] = active_color | active_set[char_value]<<8; continue; } String test = ""; for (int s = 0; s < chars.length; s++) test += (char)(chars[s]>>>8); // ab 3 parittsfehlern zeile droppen if (checkParity && parity_error > 0) { String msg = "!> line " + row + ", parity check failed at " + parity_error + " of " + len + " characters: '" + test + "'"; int max_errors = Common.getSettings().getIntProperty(Keys.KEY_SubtitlePanel_MaxParityErrors); if (parity_error > max_errors) { test = ""; msg += ", line dropped.."; } Common.setMessage(msg); } if (test.trim().length() == 0) return null; return chars; } /****************************** * make strings from teletext * ******************************/ public static String makestring(byte[] packet, int offset, int len, int row, int character_set, int color, boolean checkParity) { boolean ascii = true, toggle = false; String text = ""; int parity_error = 0; int language_code = Common.getSettings().getIntProperty(Keys.KEY_TtxLanguagePair) - 1; int primary_set_mapping = language_code < 0 ? 0 : language_code; int primary_national_set_mapping = character_set; int secondary_set_mapping = primary_set_mapping; int secondary_national_set_mapping = primary_national_set_mapping; if (page_modifications.containsKey("primary_set")) secondary_set_mapping = primary_set_mapping = Integer.parseInt(page_modifications.get("primary_set").toString()); if (page_modifications.containsKey("primary_national_set")) secondary_national_set_mapping = primary_national_set_mapping = Integer.parseInt(page_modifications.get("primary_national_set").toString()); if (page_modifications.containsKey("secondary_set")) { secondary_set_mapping = Integer.parseInt(page_modifications.get("secondary_set").toString()); secondary_national_set_mapping = Integer.parseInt(page_modifications.get("secondary_national_set").toString()); } active_set = CharSet.getActive_G0_Set(primary_set_mapping, primary_national_set_mapping, row); active_national_set = CharSet.getActiveNationalSubset(primary_set_mapping, primary_national_set_mapping, row); loopi: for (int c = offset, val, i = 0; i < len; c++, i++) { val = row<<16 | i; if (page_modifications.containsKey("" + val)) { text += page_modifications.get("" + val).toString(); continue; } //if error, switch to graphics mode (= space), by loosing all following chars if (checkParity && !cparity(packet[c])) { parity_error++; packet[c] = 8; } int char_value = 0x7F & bytereverse(packet[c]); if (char_value>>>3 == 0) //0x0..7 { ascii = true; text += ((color==1) ? colors[char_value] : "") + (char)active_set[32]; continue; } else if (char_value>>>4 == 0) //0x8..F { text += (char)active_set[32]; continue; } else if (char_value>>>7 == 1) //0x80..FF { text += (char)active_set[32]; continue; } else if (char_value < 27) //0x10..1A { ascii = false; text += (char)active_set[32]; continue; } else if (char_value < 32) //0x1B..1F { if (char_value == 0x1B) //ESC { if (toggle) { active_set = CharSet.getActive_G0_Set(primary_set_mapping, primary_national_set_mapping, row); active_national_set = CharSet.getActiveNationalSubset(primary_set_mapping, primary_national_set_mapping, row); } else { active_set = CharSet.getActive_G0_Set(secondary_set_mapping, secondary_national_set_mapping, row); active_national_set = CharSet.getActiveNationalSubset(secondary_set_mapping, secondary_national_set_mapping, row); } toggle = !toggle; } text += (char)active_set[32]; continue; } else if (char_value == 0x7F) //0x7F { text += (char)active_set[32]; continue; } if (!ascii) { text += (char)active_set[32]; continue; } if (active_national_set != null) { // all chars 0x20..7F switch (char_value) // special national characters { case 0x23: text += (char)active_national_set[0]; continue loopi; case 0x24: text += (char)active_national_set[1]; continue loopi; case 0x40: text += (char)active_national_set[2]; continue loopi; case 0x5b: text += (char)active_national_set[3]; continue loopi; case 0x5c: text += (char)active_national_set[4]; continue loopi; case 0x5d: text += (char)active_national_set[5]; continue loopi; case 0x5e: text += (char)active_national_set[6]; continue loopi; case 0x5f: text += (char)active_national_set[7]; continue loopi; case 0x60: text += (char)active_national_set[8]; continue loopi; case 0x7b: text += (char)active_national_set[9]; continue loopi; case 0x7c: text += (char)active_national_set[10]; continue loopi; case 0x7d: text += (char)active_national_set[11]; continue loopi; case 0x7e: text += (char)active_national_set[12]; continue loopi; } } text += (char)active_set[char_value]; continue loopi; } // ab 3 parittsfehlern zeile droppen if (checkParity && parity_error > 0) { String msg = "!> line " + row + ", parity check failed at " + parity_error + " of " + len + " characters: '" + text + "'"; int max_errors = Common.getSettings().getIntProperty(Keys.KEY_SubtitlePanel_MaxParityErrors); if (parity_error > max_errors) { text = ""; color = 0; msg += ", line dropped.."; } Common.setMessage(msg); } if (color == 1) return colors[7] + text.trim(); else return text; } //DM30072004 081.7 int07 add private static Hashtable page_modifications = new Hashtable(); private static boolean use = false; private static int display_row = 0, display_column = 0; private static short active_set[]; private static short active_national_set[]; //DM30072004 081.7 int07 add public static void clearEnhancements() { page_modifications.clear(); use = false; display_row = 0; display_column = 0; active_set = CharSet.getActive_G0_Set(0, 0, 0); active_national_set = CharSet.getActiveNationalSubset(0, 0, 0); } //analyze triplets etc. //DM30072004 081.7 int07 add public static void setEnhancements(byte packet[], int row, int character_set) { int val, mapping, position = 0, code; byte address, mode, data, designation; designation = bytereverse((byte)((0xF & hamming_8_4(packet[6]))<<4)); //Common.setMessage("row " + row + " /designation " + designation); if ((row == 29 && designation == 0) || (row == 29 && designation == 4) || (row == 28 && designation == 4)) { // read triplet 1 val = hamming_24_18(packet, 7); code = val<<3; if (row == 28 && designation == 0 && (0x3F800 & val) != 0) return; // not X/28/0 format 1 // read triplet 2 val = hamming_24_18(packet, 10); code |= (7 & val>>15); //primary set mapping = 0xFE & bytereverse((byte)(0x7F & code>>7)); page_modifications.put("primary_set", "" + (0xF & mapping>>4)); if (row != 29) page_modifications.put("primary_national_set", "" + character_set); //secondary set mapping = 0xFE & bytereverse((byte)(0x7F & code)); page_modifications.put("secondary_set", "" + (0xF & mapping>>4)); page_modifications.put("secondary_national_set", "" + (7 & mapping>>1)); } if (row != 26) return; for (int a = 7; a < 46; a += 3) { val = hamming_24_18(packet, a); address = bytereverse( (byte)(0xFC & val>>10)); mode = bytereverse( (byte)(0xF8 & val>>4)); data = bytereverse( (byte)(0xFE & val<<1)); /** Common.setMessage("triplet " + a + " / " + Integer.toBinaryString(val)); Common.setMessage(" address " + address ); Common.setMessage(" mode " + mode ); Common.setMessage(" data " + data ); **/ if (address >= 40) //40..63 means row 24,1..23 { if (address == 63 && mode == 31) //termination break; if (mode != 4 && mode != 1) { use = false; continue; } display_row = address == 40 ? 0 : address - 40; display_column = mode == 1 ? 0 : data; use = true; } else //0..39 means column 0..39 { if (!use) continue; display_column = address; String str = ""; if (mode == 15) //char from G2 set str += (char)CharSet.getActive_G2_Set(0, character_set, display_row)[data]; else if (mode == 16) //char from G0 set w/o diacr. str += (char)CharSet.getActive_G0_Set(0, character_set, display_row)[data]; //combination fixed table (because it won't work here when combine unicode chars) else if (mode > 16) //char from G0 set w/ diacr. str += (char)CharSet.getCombinedCharacter(data, mode & 0xF); else continue; position = display_row<<16 | display_column; page_modifications.put("" + position, str); //Common.setMessage("replaced char " + str + " /m " + mode); } } } } project-x/src/net/sourceforge/dvb/projectx/subtitle/UnicodeWriter.java0000600000175000017500000000643710370024316027717 0ustar supermariosupermario/* * @(#)UnicodeWriter.java * * Copyright (c) 2005-2006 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.subtitle; import java.io.DataOutputStream; import java.io.ByteArrayOutputStream; import java.io.PrintWriter; import java.io.IOException; /** * */ public class UnicodeWriter extends Object { private DataOutputStream out1; private PrintWriter out2; private boolean useUnicode = false; private boolean useUTF8 = false; private short mask_1 = ~0x7F; private short mask_2 = ~0x7FF; /** * */ private UnicodeWriter() {} /** * */ public UnicodeWriter(ByteArrayOutputStream _out, boolean _useUTF16, boolean _useUTF8) { useUnicode = (_useUTF16 || _useUTF8); //UTF16 standard useUTF8 = _useUTF8; if (useUnicode) out1 = new DataOutputStream(_out); else out2 = new PrintWriter(_out, true); } /** * */ public void flush() throws IOException { if (useUnicode) out1.flush(); else out2.flush(); } /** * */ public void close() throws IOException { if (useUnicode) out1.close(); else out2.close(); } /** * */ public void print(String str) throws IOException { if (!useUnicode) { out2.print(str); return; } // UTF8 if (useUTF8) { char[] chars = str.toCharArray(); for (int i = 0, j = chars.length; i < j; i++) { if ((mask_1 & chars[i]) == 0) //0xxxxxxx - 0000-007F out1.writeByte(chars[i]); else if ((mask_2 & chars[i]) == 0) //110xxxxx 10xxxxxx - 0080-07FF out1.writeShort(0xC080 | (0x1F00 & chars[i]<<2) | (0x3F & chars[i])); else //1110xxxx 10xxxxxx 10xxxxxx - 0800-FFFF { out1.writeByte(0xE0 | (0xF0000 & chars[i]<<4)); out1.writeShort(0x8080 | (0x3F00 & chars[i]<<2) | (0x3F & chars[i])); } } return; } // UTF16 /** * mark file as big endian unicode */ if (out1.size() == 0) out1.writeChar(0xFEFF); out1.writeChars(str); } /** * */ public void println(String str) throws IOException { if (useUnicode) { print(str); print(System.getProperty("line.separator")); } else out2.println(str); } /** * */ public void println() throws IOException { if (useUnicode) print(System.getProperty("line.separator")); else out2.println(); } } project-x/src/net/sourceforge/dvb/projectx/thirdparty/0000700000175000017500000000000010745203152024617 5ustar supermariosupermarioproject-x/src/net/sourceforge/dvb/projectx/thirdparty/Chapters.java0000600000175000017500000000443410351106432027236 0ustar supermariosupermario/* * @(#)Chapters.java * * Copyright (c) 2004-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.thirdparty; import java.io.IOException; import java.io.PrintWriter; import java.io.FileOutputStream; import java.util.Arrays; import java.util.ArrayList; public class Chapters extends Object { boolean active = false; String file_separator = System.getProperty("file.separator"); ArrayList list; public Chapters() { list = new ArrayList(); } public void init(boolean b) { active = b; list.clear(); } public void addChapter(String time) { if (!active) return; list.add(time); } public void addChapter(String time, String comment) { if (!active) return; list.add(time + " ; " + comment); } public void finish(String str, String name) throws IOException { if (!active || list.size() == 0) return; if (!str.endsWith(file_separator)) str += file_separator; str += (name + ".chp.txt"); Object chapters[] = list.toArray(); Arrays.sort(chapters); write(str, chapters); list.clear(); } private void write(String str, Object chapters[]) throws IOException { PrintWriter out = new PrintWriter(new FileOutputStream(str)); for (int a=0; a < chapters.length; a++) out.println(chapters[a]); out.flush(); out.close(); } } project-x/src/net/sourceforge/dvb/projectx/thirdparty/D2V.java0000600000175000017500000000725110351106442026061 0ustar supermariosupermario/* * @(#)D2V.java - simple independent implementation to create a d2v Projectfile * * Copyright (c) 2002-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.thirdparty; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.video.Video; public class D2V extends Object { ArrayList d2v = new ArrayList(); int entry=0, file=0, frame1=0, frame2=0; String[] type = { " 2"," 9" }; String lastGOP = "", nextGOP = ""; String d2vfile = ""; String[] d2voptions = { "iDCT_Algorithm=2", "YUVRGB_Scale=1", "Luminance=128,0", "Picture_Size=0,0,0,0,0,0", "Field_Operation=0" }; public D2V() {} public void Init(String fparent) { entry=0; file=0; d2v.clear(); d2vfile = fparent + ".d2v"; d2v.add("DVD2AVIProjectFile"); d2v.add("1"); d2v.add("" + (fparent.length() + 4) + " " + fparent + ".mpv"); d2v.add(""); d2v.add("Stream_Type=0,0,0"); d2v.add(d2voptions[0]); d2v.add(d2voptions[1]); d2v.add(d2voptions[2]); d2v.add(d2voptions[3]); d2v.add(d2voptions[4]); entry += 9; } public int getPart() { return file; } public void setFile(String fparent) { d2v.add(3 + file, "" + fparent.length() + " " + fparent); file++; entry++; } public String[] readOptions() { return d2voptions; } public void setOptions(String[] newoptions) { d2voptions = (String[])newoptions.clone(); } public void FrameRate(byte framerate) { d2v.add("Frame_Rate=" + Video.getFrameRate(0xF & framerate)); d2v.add(""); entry += 2; } public void addGOP(long pos, int frames) { String fill = "7 " + file + " " + Integer.toHexString((int)(pos/2048L)).toUpperCase(); for (int a=0; a < frames; a++) fill += type[0]; lastGOP = fill + type[0] + type[0] + type[1]; d2v.add(fill); entry++; } public void write(long pos, long frame3) { if (d2v.size() < 11) { d2v.clear(); return; } d2v.set(1, "" + (file + 1)); d2v.add(11 + file,"Location=0,0," + file + "," + Integer.toHexString((int)(pos/2048L)).toUpperCase()); entry++; d2v.set(entry,lastGOP); d2v.add(""); d2v.add("FINISHED"); if (d2v.size() < 14) { d2v.clear(); return; } try { BufferedWriter d2vout = new BufferedWriter(new FileWriter(d2vfile)); for (int a=0; a < d2v.size(); a++) { d2vout.write(d2v.get(a).toString()); d2vout.newLine(); } d2vout.close(); } catch (IOException e) { Common.setExceptionMessage(e); } d2v.clear(); } } project-x/src/net/sourceforge/dvb/projectx/thirdparty/Ifo.java0000600000175000017500000001255010351106450026200 0ustar supermariosupermario/* * @(#)Ifo.java - carries various stuff * * Copyright (c) 2004-2005 by dvb.matt,, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.thirdparty; import java.io.ByteArrayOutputStream; import java.io.ByteArrayInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.File; import java.util.zip.InflaterInputStream; //DM10052004 081.7 int02 introduced public final class Ifo extends Object { private Ifo() {} public static int RGBtoYUV(int ARGB) { int Y, Cr, Cb; int R = 0xFF & ARGB>>>16; int G = 0xFF & ARGB>>>8; int B = 0xFF & ARGB; Y = (int)(0.299f * R +0.587f * G +0.114f * B); Cr = (int)(0.5f * R -0.4187f * G -0.0813f * B + 128); Cb = (int)(-0.1687f * R -0.3313f * G +0.5f * B + 128); Y = Y < 16 ? 16 : (Y > 0xEB ? 0xEB : Y); Cr = Cr < 0 ? 0 : (Cr > 0xFF ? 0xFF : Cr); Cb = Cb < 0 ? 0 : (Cb > 0xFF ? 0xFF : Cb); if (Y == 0) return 0x108080; return (Y<<16 | Cr<<8 | Cb); } public static long createIfo(String file, Object color_table[]) throws IOException { file += ".IFO"; FileOutputStream fos = new FileOutputStream(file); fos.write(setPGCColors(getDefaultIfo(), color_table)); fos.flush(); fos.close(); return new File(file).length(); } private static byte[] setPGCColors(byte ifo[], Object color_table[]) throws IOException { //VTS_PGC_1 starts at 0x1010, color_index 0 starts at offs 0xA5 (0x10B5) for (int a=0, color; a < 16 && a < color_table.length; a++) { color = RGBtoYUV(0xFFFFFF & Integer.parseInt(color_table[a].toString())); for (int b=0, val; b < 3; b++) ifo[0x10B5 + (a<<2) + b] = (byte)(0xFF & color>>(16-(b*8))); } return ifo; } private static byte[] getDefaultIfo() throws IOException { byte compressed_ifo[] = { 120, -100, -19, -103, 61, 72, 28, 65, 28, -59, -33, -100, -69, 123, -98, 119, -71, -81, -100, 31, 39, -63, 52, 41, -124, -112, 70, -125, -88, -115, -122, -100, -127, 84, 6, 12, 7, -119, -126, 16, 8, -60, 70, 16, 3, 10, -79, 88, 59, 13, -110, 34, 90, 41, -104, 70, -71, -30, 20, 44, 20, -108, 36, 85, 16, -60, 38, -91, -74, 41, 82, 36, -28, 3, 82, 5, -101, -28, -19, -50, 21, -79, 8, 22, 49, 30, -54, -5, -63, -17, 118, 102, 118, 119, -18, 63, -43, -50, -66, 45, 20, 11, -59, -69, -123, -66, -2, 27, -59, -5, 3, 64, -13, 34, -114, -29, 34, -125, -1, 76, -12, -41, 41, 76, -30, 81, 67, 35, -107, 126, -51, 31, -25, 28, 4, -21, -8, 11, 3, -41, 78, -31, -33, -49, 49, 92, -65, -23, 53, -113, 71, -85, 93, -121, 16, 66, -120, 51, -58, -124, -65, 41, -102, 96, -37, 84, -73, 24, 33, -124, 16, 66, -100, 9, -31, 19, -33, -28, -89, 109, 47, -51, 54, 71, 58, -17, 5, 29, -65, 106, 69, -99, 64, -38, -9, -15, -103, -50, -67, 27, -63, 108, 75, 27, 22, 39, -41, -15, 126, 62, -114, -107, 120, 9, 75, -37, 107, 40, -81, -113, 97, -9, -31, -93, 112, 124, 107, 117, 25, 62, -81, 61, -50, 23, 124, 51, -98, -87, -60, 5, 118, -75, -106, -26, 86, -6, 66, 59, 33, 33, -124, 16, 23, 28, -5, -100, 107, -89, 9, 7, -120, 1, -111, 36, -32, 44, 3, -34, 75, -96, -10, -128, -61, -20, -89, 62, 1, -39, 17, -96, 62, -30, -93, -87, 84, -35, -126, -123, 16, 66, 8, -15, -49, -40, -25, -1, -27, -16, -75, 63, -124, 111, -65, 66, 8, 33, -124, -72, -32, -104, -37, -107, 70, 31, 13, 62, 3, -68, -91, 63, 57, -34, 65, 39, -24, -122, -51, 4, 34, 79, -24, 26, 80, -109, -93, -93, -12, 13, -32, -60, -24, 3, -101, 23, 56, -121, -128, -53, -21, 92, -50, -25, 62, -91, -101, -12, 7, -32, 93, -89, -61, 54, 79, -16, -10, -128, 40, 55, 26, -47, 46, -70, 68, -65, 3, -75, 61, -12, -71, -51, 26, 98, 121, 58, 72, 121, -82, 46, 65, -57, -23, 71, 32, 62, 101, 115, -120, 4, 107, -71, 116, -109, -14, -104, 100, 125, -55, 18, -112, 114, 105, -111, -66, -78, 57, 69, -70, -101, -50, -48, 15, 64, -122, 107, -54, -52, 83, -50, -99, -67, 98, 51, -116, -20, 22, 61, -30, -106, -25, 22, 93, -96, 95, -127, -36, 29, 90, 14, -14, 13, 58, 68, 95, 3, 13, 87, -23, 51, -54, 123, 27, 89, 111, -29, 14, -48, -60, 99, -112, 127, -28, -21, -23, 24, -35, -73, 95, 12, -124, 16, 66, -120, -13, -59, 111, -73, 44, 80, 66 }; InflaterInputStream inflater = new InflaterInputStream( new ByteArrayInputStream(compressed_ifo)); ByteArrayOutputStream uncompressed_ifo = new ByteArrayOutputStream(); int x = 0; while ((x = inflater.read()) != -1) uncompressed_ifo.write(x); uncompressed_ifo.flush(); return uncompressed_ifo.toByteArray(); } }project-x/src/net/sourceforge/dvb/projectx/thirdparty/TS.java0000600000175000017500000004522710365320534026026 0ustar supermariosupermario/* * @(#)TS.java - constants to create TS packets * * Copyright (c) 2002-2006 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.thirdparty; import java.util.List; import java.util.Calendar; import java.util.Date; import java.util.Arrays; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; //import net.sourceforge.dvb.projectx.audio.CRC; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.subtitle.Teletext; public class TS { public TS() {} private static byte[] TF4000header = { (byte)0xCD, 0x39, 0xc, 0, //MJD (byte)0xCD, 0x39, 0xc, 0, //MJD 0, 0x3c, //duration 0, 0x1f, //service 0, 0, //0=tv, 1=radio 5, 0, 6, (byte)0xb0, //tuner 1, 2, //sid 1, 0, //pmt 0, (byte)0xe0, //pcr 0, (byte)0xe0, //vid 0, (byte)0xc0, //aud 0x4D,0x79,0x20,0x70,0x65,0x72,0x73,0x6F,0x6E,0x61,0x6C,0x20,0x54,0x56,0x20,0x43,0x68,0x61,0x6E,0x6E,0x65,0x6C,0,0, 5, 0, 0x30, (byte)0xc0, 0x6b, 0x6c, 0, 1, 0x40, 0x1f, 1, 1, (byte)0xCD, 0x39, 0xb, 0, (byte)0xCD, 0x39, 0xc, 0, 0, 0x3c, 4, 4, 84, 69, 83, 84, 0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 1,2 }; //introduced by 'catapult' 09082004 private static byte[] TF5000header = { // HEADER 14 bytes, start at 0 0x54, 0x46, 0x72, 0x63, // Id "TFrc" * 0x50, 0, // Version * 0, 0, // Reserved * 0, 0, // Duration in Minutes 0, 0xa, // Service number in channel list (Does not matter in playback) 0, 0, // Service type 0:TV 1:Radio // SERVICE_INFO 38 bytes starts at 14 0, 0, 1, 0x30, // Reserved and Tuner (Does not matter in playback) (Tuner 1+2 flagged) 1, 2, // Service ID of TS stream 1, 0, // PID number of PMT TS packet 0, (byte)0xe0, // PID number of PCR TS packet 0, (byte)0xe0, // PID number of Video TS packet 0, (byte)0xc0, // PID number of Audio TS packet, MPA as std 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x69, 0x6E, 0x67, 0, 0, 0, 0, 0, 0, 0, // Service Name // TP_INFO 16 bytes starts at 52 0, // Satelite Index 8, 7, 0, // Polarity and Reserved (Does not matter in playback) 0x6b, 0x6c, 0, 1, // Frequency (Does not matter in playback) 0x40, 0x1f, // Symbol Rate (Does not matter in playback) 1, 1, // Transport Stream Id (Does not matter in playback) 0, 0, 0, 0, // Reserved * // EVT_INFO 160 bytes starts at 68 (byte)0x80, 0x02, // Reserved * 0, 0, // Duration in Minutes 0, 0x3c, 4, 4, // Event Id 84, 69, // Modified Julian date start time 83, // Hour of start time 84, // Minute os start time 0, 0, // Modified Julian date end time 0, // Hour of end time 0, // Minute os end time 4, // Reserved 0, // Length of name in Event text 0, // Parental rate // the rest is 0 so it's not defined explicitly // Event text // EXT_EVT_INFO 1088 bytes starts at 228 // Extended Event text }; private static byte[] pmt1 = { 0x47,0x41,0,0x10, 0, 2, (byte)0xB0, (byte)0x95, 1, 2,(byte)0xC1, 0, 0, (byte)0xE0, (byte)0xE0, (byte)0xF0, 0, 2, (byte)0xE0, (byte)0xE0, (byte)0xF0, 3, 0x52, 1, 1, 3, (byte)0xE0, (byte)0xc0, (byte)0xF0, 0x9, 0x52, 1, 3, 0xA, 4, 0x64, 0x65, 0x75, 1, 3, (byte)0xE0, (byte)0xc1, (byte)0xF0, 0x9, 0x52, 1, 4, 0xA, 4, 0x64, 0x65, 0x75, 1, 3, (byte)0xE0, (byte)0xc2, (byte)0xF0, 0x9, 0x52, 1, 5, 0xA, 4, 0x64, 0x65, 0x75, 1, 3, (byte)0xE0, (byte)0xc3, (byte)0xF0, 0x9, 0x52, 1, 6, 0xA, 4, 0x64, 0x65, 0x75, 1, 6, (byte)0xE0, (byte)0x80, (byte)0xF0, 0xC, 0x52, 1, 0x11, 0x6A, 1, 0, 0xA, 4, 0x64, 0x65, 0x75, 0, 6, (byte)0xE0, (byte)0x81, (byte)0xF0, 0xC, 0x52, 1, 0x12, 0x6A, 1, 0, 0xA, 4, 0x64, 0x65, 0x75, 0, 6, (byte)0xE0, (byte)0x82, (byte)0xF0, 0xC, 0x52, 1, 0x13, 0x6A, 1, 0, 0xA, 4, 0x64, 0x65, 0x75, 0, 6, (byte)0xE0, (byte)0x90, (byte)0xF0, 0x10,0x52, 1, (byte)0xC2, 0x56, 5, 0x65, (byte)0x6E, 0x67, 0x9, 0, 0xA, 4, 0x64, 0x65, 0x75, 0, (byte)0x85, (byte)0x33, (byte)0x49, (byte)0x7e }; private static int count1=0, count2=0, count3=0; private static byte[] pcr = new byte[188]; private static byte[] pat = new byte[188]; private static byte[] pmt = new byte[188]; private static byte[] pmtHead = { 0x47,1,0,0x10 }; private static byte[] pmtStart = { 0, 2, (byte)0xB0, 0, 1, 2,(byte)0xC1, 0 }; private static byte[] pmtPCR = { 0, (byte)0xE0, (byte)0xE0, (byte)0xF0, 0 }; private static byte[] pmtMPV = { 2, (byte)0xE0, (byte)0xE0, (byte)0xF0, 3, 0x52, 1, 1 }; private static byte[] pmtMPA = { 3, (byte)0xE0, (byte)0xC0, (byte)0xF0, 0x9, 0x52, 1, 3, 0xA, 4, 0x64, 0x65, 0x75, 1 }; private static byte[] pmtAC3 = { 6, (byte)0xE0, (byte)0x80, (byte)0xF0, 0xC, 0x52, 1, 4, 0x6A, 1, 0, 0xA, 4, 0x64, 0x65, 0x75, 0 }; private static byte[] pmtAC3_atsc = { (byte)0x81, (byte)0xE0, (byte)0x80, (byte)0xF0, 0xF, 0x52, 1, 4, 0xA, 4, 0x65, 0x6E, 0x67, 0, 5, 4, 0x41, 0x43, 0x2D, 0x33 }; private static byte[] pmtTTX = { 6, (byte)0xE0, (byte)0x90, (byte)0xF0, 0x1F, 0x52, 1, 5, 0x56, 20, 0x65, 0x6E, 0x67, 0x9, 0, 0x64, 0x65, 0x75, 0x11, 0x50, 0x67, 0x65, 0x72, 0x17, 0x77, 0x65, 0x6E, 0x67, 0x10, (byte)0x88, 0xA, 4, 0x64, 0x65, 0x75, 0 }; private static byte[] autopmt = new byte[0]; private static int firstID = 0xE0; private static boolean myTTX = false; public static void setPmtPids(List PIDs) throws IOException { if (myTTX) PIDs.add("" + 0x39F); Object[] Pids = PIDs.toArray(); if (Pids.length == 0) { Common.setMessage(Resource.getString("ts.msg1")); autopmt = pmt; return; } ByteArrayOutputStream pmtout = new ByteArrayOutputStream(); Arrays.sort(Pids); int lfn = 1; // byte 7 = substreamID for program component pmtout.write(pmtStart); firstID = (0xFF & Integer.parseInt(Pids[0].toString())); pmtPCR[2] = (byte)firstID; updateHeader(23, firstID); pmtout.write(pmtPCR); for (int a = 0; a < Pids.length; a++) // get Pid Hex: 0..=V, 1..=MPA, 2..=AC3, 3..=TTX { int Pid = Integer.parseInt(Pids[a].toString()); switch (0xF & (Pid>>>8)) { case 0: // vid pmtMPV[2] = (byte)(0xFF&Pid); pmtMPV[7] = (byte)lfn++; pmtout.write(pmtMPV); break; case 1: // mpeg-1 (-2) audio pmtMPA[2] = (byte)(0xFF&Pid); pmtMPA[7] = (byte)lfn++; pmtout.write(pmtMPA); break; case 2: // ac3 audio pmtAC3[2] = (byte)(0xFF&Pid); pmtAC3[7] = (byte)lfn++; pmtout.write(pmtAC3); // ac3_atsc addition, same values pmtAC3_atsc[2] = (byte)(0xFF & Pid); pmtAC3_atsc[7] = (byte)(lfn - 1); pmtout.write(pmtAC3_atsc); break; case 3: // ttx pmtTTX[2] = (byte)(0xFF&Pid); pmtTTX[7] = (byte)lfn++; pmtout.write(pmtTTX); break; } } byte newpmt[] = pmtout.toByteArray(); int sectionlen = newpmt.length; newpmt[2] = (byte)(0xB0 | (0xF & sectionlen>>8)); newpmt[3] = (byte)(0xFF & sectionlen); pmtout.reset(); pmtout.write(newpmt); pmtout.write(generateCRC32(newpmt, 1)); newpmt = pmtout.toByteArray(); int pmtpacks = ((newpmt.length - 1) / 184) + 1; // = number of needed pmt packs autopmt = new byte[pmtpacks * 188]; Arrays.fill(autopmt, (byte)0xff); int i = 0, c = 0; while (i < newpmt.length) { System.arraycopy(pmtHead, 0, autopmt, c, 4); if (newpmt.length >= i+184) { System.arraycopy(newpmt, i, autopmt, 4 + c, 184); i += 184; c += 188; } else { System.arraycopy(newpmt, i, autopmt, 4 + c, newpmt.length - i); break; } } autopmt[1] = 0x41; // = set startpacket bit pmtout.close(); } // auto PMT public static byte[] getAutoPMT() { for (int i=0; i < autopmt.length; i+=188) autopmt[i+3] = (byte)(0x10 | (0xf&(count1++))); return autopmt; } public static int getfirstID() { return firstID; } //DM09082004 081.7 int08 changed public static void setfirstID() { firstID = 0xE0; pmtPCR[2] = (byte)firstID; updateHeader(23, firstID); } // PAT with section 0 and SID = 0x102, PMT = 0x100 , CRC32 private static byte[] pat1 = { 0x47,0x40,0,0x10, 0, 0, (byte)0xB0, 0xd, 0, 1, 1, 0, 0, 1, 2, (byte)0xE1, 0, (byte)0x8f, (byte)0xa5, 0x26, (byte)0xcf, }; // counter shall not be updated in PCR only paket (but do it), 42bits for PCR private static byte pcr1[] = { 0x47,0,(byte)0xe0,0x20, (byte)0xB7,0x10,0,0,0,0,0,0 }; private static byte ttx[] = { 0x47,0x40,(byte)0x9F,0x10, 0,0,1,(byte)0xBD,0,(byte)0xB2,(byte)0x84,(byte)0x80,0x24, (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, (byte)0xFF, 0x10, // 022C E7E4 40A8 A8CE A80B A80B 7A40 2,44,-25,-28,64,-88,-88,-50,-88,11,-88,11,122,64, 38,-50,117,87,-122,79,4,42,-53,-75,-110,118,103,-9,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 022C E8E4 40D9 2,44,-24,-28,64,-39, // l i n e 2 2 : 4,55,-105,118,-89,4,76,76, 4,107,67,-110,4,-116,-12,28,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 022C E9E4 E3D9 2,44,-23,-28,-29,-39, // line 23 PTS 4,55,-105,118,-89,4,76,-51, 4,107,67,-110,4,-116,-12,-99,4,11,42,-53,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 }; //DM26052004 081.7 int03 changed public static byte[] getTTX(byte[] data, int offset, String pts) { byte[] tPTS = pts.getBytes(); for (int a = 0; a < tPTS.length; a++) tPTS[a] = Teletext.bytereverse(Teletext.parity(tPTS[a])); System.arraycopy(tPTS, 0, ttx, 169, tPTS.length); System.arraycopy(data, 9 + offset, ttx, 13, 5); ttx[13] &= ~0x10; ttx[3] = (byte)(0x10 | (0xF & (count3++))); return ttx; } public static byte[] getPMT() { pmt[3] = (byte)(0x10 | (0xf & (count1++))); return pmt; } public static byte[] getPAT() { pat[3] = (byte)(0x10 | (0xf & (count2++))); return pat; } public static byte[] getPCR(long pts, int count, int PCRPid) { /* Construct the PCR, PTS-55000 (2ms) 1Bit ~ 3Ticks (counter) */ pcr[2] = (byte)(PCRPid); pcr[3] = (byte)(0x20 | (0xF & count)); pcr[6] = (byte)(0xFF & pts>>>25); pcr[7] = (byte)(0xFF & pts>>>17); pcr[8] = (byte)(0xFF & pts>>>9); pcr[9] = (byte)(0xFF & pts>>>1); pcr[10] = (byte)((1 & pts) << 7 ); /* PCR ext is 0, byte10+byte11 */ return pcr; } public static byte[] init(String name, boolean ac3, boolean _myTTX, int mode) { count1 = count2 = count3 = 0; myTTX = _myTTX; Arrays.fill(pat, (byte) 0xFF); Arrays.fill(pmt, (byte) 0xFF); Arrays.fill(pcr, (byte) 0xFf); System.arraycopy(pmt1, 0, pmt, 0, pmt1.length); System.arraycopy(pat1, 0, pat, 0, pat1.length); System.arraycopy(pcr1, 0, pcr, 0, pcr1.length); switch (mode) { case 1: return initTF4000header(name, ac3); case 2: return initTF5000header(name, ac3, 1692); //fmly 1316 case 3: return initTF5000header(name, ac3, 3760); } return (new byte[0]); } private static void updateHeader(int pos, int val) { //only last 8 bits used TF4000header[pos] = (byte) val; TF5000header[pos] = (byte) val; } public static String updateAdditionalHeader(String old_name, long time[], int mode) throws IOException { String new_name = ""; switch (mode) { case 0: return old_name; case 1: new_name = old_name.substring(0, old_name.length() - 3) + ".raw"; if (new File(new_name).exists()) new File(new_name).delete(); Common.renameTo(old_name, new_name); //DM13042004 081.7 int01 changed finishTF4000header(new_name, time); break; case 2: case 3: new_name = old_name.substring(0, old_name.length() - 3) + ".rec"; if (new File(new_name).exists()) new File(new_name).delete(); Common.renameTo(old_name, new_name); finishTF5000header(new_name, time); break; } return new_name; } private static void finishTF4000header(String name, long time[]) throws IOException { long event[] = new long[4]; long millis = (time[1] - time[0]) / 90L; short minutes = (short)(0xFFFF & (Math.round(millis / 60000f))); event[0] = System.currentTimeMillis(); event[1] = event[0] - millis; event[2] = (event[0] / 86400000L) + 40587; event[3] = (event[1] / 86400000L) + 40587; Calendar datum = Calendar.getInstance(); datum.setTime(new Date(event[0])); RandomAccessFile ts = new RandomAccessFile(name, "rw"); ts.seek(0); ts.writeShort((short)event[2]); ts.writeByte((byte)datum.get(Calendar.HOUR_OF_DAY)); ts.writeByte((byte)datum.get(Calendar.MINUTE)); ts.writeShort((short)event[2]); ts.writeByte((byte)datum.get(Calendar.HOUR_OF_DAY)); ts.writeByte((byte)datum.get(Calendar.MINUTE)); ts.writeShort(minutes); ts.seek(0x44); ts.writeShort((short)event[2]); ts.writeByte((byte)datum.get(Calendar.HOUR_OF_DAY)); ts.writeByte((byte)datum.get(Calendar.MINUTE)); ts.writeShort(minutes); datum.setTime(new Date(event[1])); ts.seek(0x40); ts.writeShort((short)event[3]); ts.writeByte((byte)datum.get(Calendar.HOUR_OF_DAY)); ts.writeByte((byte)datum.get(Calendar.MINUTE)); ts.close(); } //introduced by 'catapult' 09082004 private static void finishTF5000header(String name, long time[]) throws IOException { long event[] = new long[4]; long millis = (time[1] - time[0]) / 90L; short minutes = (short)(0xFFFF & (Math.round(millis / 60000f))); event[0] = System.currentTimeMillis(); event[1] = event[0] - millis; event[2] = (event[0] / 86400000L) + 40587; event[3] = (event[1] / 86400000L) + 40587; Calendar datum = Calendar.getInstance(); datum.setTime(new Date(event[0])); RandomAccessFile ts = new RandomAccessFile(name, "rw"); ts.seek(0x08); ts.writeShort(minutes); ts.seek(0x46); ts.writeShort(minutes); ts.seek(0x50); ts.writeShort((short)event[2]); ts.writeByte((byte)datum.get(Calendar.HOUR_OF_DAY)); ts.writeByte((byte)datum.get(Calendar.MINUTE)); datum.setTime(new Date(event[1])); ts.seek(0x4C); ts.writeShort((short)event[3]); ts.writeByte((byte)datum.get(Calendar.HOUR_OF_DAY)); ts.writeByte((byte)datum.get(Calendar.MINUTE)); String eventname = new File(name).getName(); if (eventname.length() > 128) eventname = eventname.substring(0, 128); ts.seek(0x55); ts.writeUTF(eventname); ts.seek(0x56); int val = ts.read(); ts.seek(0x55); ts.writeShort(val<<8); ts.close(); } private static byte[] initTF4000header(String name, boolean ac3) { byte header[] = new byte[564]; //TF4000 System.arraycopy(TF4000header, 0, header, 0, TF4000header.length); byte file_name[] = new File(name).getName().getBytes(); header[75] = (byte)(file_name.length - 3); System.arraycopy(file_name, 0, header, 76, file_name.length - 3); if (ac3) { header[26] = 0; header[27] = (byte)0x80; // set 1. AC3 PID as main TFaudio } else { header[26] = 0; header[27] = (byte)0xC0; } return header; } private static byte[] initTF5000header(String name, boolean ac3, int headerlength) { byte header[] = new byte[headerlength]; System.arraycopy(TF5000header, 0, header, 0, TF5000header.length); byte file_name[] = new File(name).getName().getBytes(); header[75] = (byte)(file_name.length - 3); System.arraycopy(file_name, 0, header, 76, file_name.length - 3); if (ac3) { header[26] = 0; header[27] = (byte)0x80; // set 1. AC3 PID as main TFaudio } else { header[26] = 0; header[27] = (byte)0xC0; //MPA } return header; } private static byte[] generateCRC32(byte[] data, int offset) { // x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 int[] g = { 1,1,1,0,1,1,0,1,1,0,1,1,1,0,0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,1 }; int[] shift_reg = new int[32]; long crc = 0; byte[] crc32 = new byte[4]; // Initialize shift register's to '1' Arrays.fill(shift_reg, 1); // Calculate nr of data bits, summa of bits int nr_bits = (data.length - offset) * 8; for (int bit_count = 0, bit_in_byte = 0, data_bit; bit_count < nr_bits; bit_count++) { // Fetch bit from bitstream data_bit = (data[offset] & 0x80>>>(bit_in_byte++)) != 0 ? 1 : 0; if ((bit_in_byte &= 7) == 0) offset++; // Perform the shift and modula 2 addition data_bit ^= shift_reg[31]; for (int i = 31; i > 0; i--) shift_reg[i] = g[i]==1 ? (shift_reg[i - 1] ^ data_bit) : shift_reg[i - 1]; shift_reg[0] = data_bit; } for (int i = 0; i < 32; i++) crc = ((crc << 1) | (shift_reg[31 - i])); for (int i = 0; i < 4; i++) crc32[i] = (byte)(0xFF & (crc >>>((3 - i) * 8))); return crc32; } }project-x/src/net/sourceforge/dvb/projectx/video/0000700000175000017500000000000010745203152023533 5ustar supermariosupermarioproject-x/src/net/sourceforge/dvb/projectx/video/IDCTRefNative.java0000600000175000017500000000704710351106550026734 0ustar supermariosupermario/* * @(#)IDCT Ref * * Copyright (c) 2004-2005 by pstorch, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.video; /** * JNI java class to access idctref.dll. * * @author Peter Storch */ public class IDCTRefNative { /** indicates whether the library is loaded */ private static boolean libraryLoaded = false; private static boolean debug = false; /* load the native libray */ static { try { System.loadLibrary("idctref"); libraryLoaded = true; } catch(Exception e) { if (debug) System.out.println(e); //e.printStackTrace(); } catch(UnsatisfiedLinkError ue) { if (debug) System.out.println(ue); //e.printStackTrace(); } } /** * Returns true if the library is loaded. * * @return */ public static boolean isLibraryLoaded() { return libraryLoaded; } /** * Initializes the IDCT algorithm */ public native void init(); /** * Performs the IDCT on an short[8][8] array. * * @param block * @return */ public native short[][] referenceIDCT(short[][] block); /** * Performs the IDCT on an short[64] array. * * @param block * @return */ public native void referenceIDCT(short[] block); /** * Main method for testing. * * @param args */ public static void main(String args[]) { IDCTRefNative idct = new IDCTRefNative(); idct.init(); short[][] block = new short[8][8]; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { block[i][j]=(short)(i*j); } } System.out.println("block before"); printArray(block); block = idct.referenceIDCT(block); System.out.println("block after"); printArray(block); short[] block2 = new short[64]; for (int i = 0, k = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { block2[k]=(short)(i*j); k++; } } System.out.println("block2 before"); printArray2(block2); idct.referenceIDCT(block2); System.out.println("block2 after"); printArray2(block2); } /** * Helper method to print the array. * * @param block */ public static void printArray(short[][] block) { for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { System.out.print(block[i][j] + " "); } System.out.println(); } } /** * Helper method to print the array. * * @param block */ public static void printArray2(short[] block) { for (int i = 0; i < 64; i++) { if (i % 8 == 0) { System.out.println(); } System.out.print(block[i] + " "); } System.out.println(); } } project-x/src/net/sourceforge/dvb/projectx/video/IDCTSseNative.java0000600000175000017500000000527310351106560026752 0ustar supermariosupermario/* * @(#)IDCT SSE * * Copyright (c) 2004-2005 by pstorch, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.video; /** * JNI java class to access idctsse.dll. * * @author Peter Storch */ public class IDCTSseNative { /** indicates whether the library is loaded */ private static boolean libraryLoaded = false; private static boolean debug = false; /* load the native libray */ static { try { System.loadLibrary("idctsse"); libraryLoaded = true; } catch(Exception e) { if (debug) System.out.println(e); //e.printStackTrace(); } catch(UnsatisfiedLinkError ue) { if (debug) System.out.println(ue); //e.printStackTrace(); } } /** * Returns true if the library is loaded. * * @return */ public static boolean isLibraryLoaded() { return libraryLoaded; } /** * Performs the IDCT on an short[64] array. * * @param block * @return */ public native void referenceIDCT(short[] block); /** * Main method for testing. * * @param args */ public static void main(String args[]) { IDCTSseNative idct = new IDCTSseNative(); short[] block = new short[64]; for (int i = 0, k = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { block[k]=(short)(i*j); k++; } } System.out.println("block before"); printArray(block); idct.referenceIDCT(block); System.out.println("block after"); printArray(block); } /** * Helper method to print the array. * * @param block */ public static void printArray(short[] block) { for (int i = 0; i < 64; i++) { if (i % 8 == 0) { System.out.println(); } System.out.print(block[i] + " "); } System.out.println(); } } project-x/src/net/sourceforge/dvb/projectx/video/MpvDecoder.java0000600000175000017500000024642710402176332026446 0ustar supermariosupermario/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ /* * Disclaimer of Warranty * * These software programs are available to the user without any license fee or * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims * any and all warranties, whether express, implied, or statuary, including any * implied warranties or merchantability or of fitness for a particular * purpose. In no event shall the copyright-holder be liable for any * incidental, punitive, or consequential damages of any kind whatsoever * arising from the use of these programs. * * This disclaimer of warranty extends to the user of these programs and user's * customers, employees, agents, transferees, successors, and assigns. * * The MPEG Software Simulation Group does not represent or warrant that the * programs furnished hereunder are free of infringement of any third-party * patents. * * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, * are subject to royalty fees to patent holders. Many of these patents are * general enough such that they are unavoidable regardless of implementation * design. * */ /* * @(#)MpvDecoder.java - still Picture Decoder * * Copyright (c) 2003-2006 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * necessary codes are derived from the MSSG mpeg2dec * * display modifications: shows I-Frames only * * * 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 * */ package net.sourceforge.dvb.projectx.video; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.parser.CommonParsing; public class MpvDecoder extends Object { private IDCTRefNative idct; private IDCTSseNative idctsse; private int[] pixels2 = new int[512 * 288]; private int[] pixels = new int[250]; //full pixel data private int Fault_Flag = 0; private int BitPos = 0; private int BufferPos = 0; private int SequenceHeader = 0; private long StartPos = 0; private boolean acceleration = false; private boolean FAST = false; private boolean PLAY = true; private boolean DIRECTION = false; private boolean ERROR1 = false; private boolean ERROR2 = false; private boolean ERROR3 = false; private boolean viewGOP = true; private String info_4 = ""; private String info_3 = ""; private String info_2 = ""; private String info_1 = ""; private byte[] buf = new byte[0]; /** * */ public MpvDecoder() { Arrays.fill(pixels2, 0xFF505050); idct = new IDCTRefNative(); idctsse = new IDCTSseNative(); if (IDCTRefNative.isLibraryLoaded()) idct.init(); if (IDCTRefNative.isLibraryLoaded() || IDCTSseNative.isLibraryLoaded()) acceleration = true; } /** * */ public boolean isAccelerated() { return acceleration; } final int PICTURE_START_CODE=0x100; final int SLICE_START_CODE_MIN=0x101; final int SLICE_START_CODE_MAX=0x1AF; final int USER_DATA_START_CODE=0x1B2; final int SEQUENCE_HEADER_CODE=0x1B3; final int EXTENSION_START_CODE=0x1B5; final int SEQUENCE_END_CODE=0x1B7; final int GROUP_START_CODE=0x1B8; final int SYSTEM_END_CODE=0x1B9; final int PACK_START_CODE=0x1BA; final int SYSTEM_START_CODE=0x1BB; private int File_Flag; private int File_Limit; private int FO_Flag; private int IDCT_Flag; private int Luminance_Flag; private int Scale_Flag; private int SystemStream_Flag; private int ERROR_CODE=0; private int ERROR_CODE1=0; /* extension start code IDs */ final int SEQUENCE_EXTENSION_ID=1; final int SEQUENCE_DISPLAY_EXTENSION_ID=2; final int QUANT_MATRIX_EXTENSION_ID=3; final int COPYRIGHT_EXTENSION_ID=4; final int PICTURE_DISPLAY_EXTENSION_ID=7; final int PICTURE_CODING_EXTENSION_ID=8; final int ZIG_ZAG=0; final int MB_WEIGHT=32; final int MB_CLASS4=64; final int MC_FIELD=1; final int MC_FRAME=2; final int MC_16X8=2; final int MC_DMV=3; final int MV_FIELD=0; final int MV_FRAME=1; final int I_TYPE=1; final int P_TYPE=2; final int B_TYPE=3; final int TOP_FIELD=1; final int BOTTOM_FIELD=2; final int FRAME_PICTURE=3; final int MACROBLOCK_INTRA=1; final int MACROBLOCK_PATTERN=2; final int MACROBLOCK_MOTION_BACKWARD=4; final int MACROBLOCK_MOTION_FORWARD=8; final int MACROBLOCK_QUANT=16; final int CHROMA420=1; final int CHROMA422=2; final int CHROMA444=3; final int IDCT_CLIP_TABLE_OFFSET=512; private int q_scale_type=0; //1 private int quantizer_scale=0, alternate_scan=0;//1 private int Coded_Picture_Width=0, Coded_Picture_Height=0, Chroma_Width=0, Chroma_Height=0; private int block_count=0, Second_Field=0; private int horizontal_size=0, vertical_size=0, mb_width=0, mb_height=0; /* ISO/IEC 13818-2 section 6.2.2.1: sequence_header() */ private int frame_rate_code=0; private int aspect_ratio_information=0; /* ISO/IEC 13818-2 section 6.2.2.3: sequence_extension() */ private int progressive_sequence=1; //prog.s std private int chroma_format=1; //4:2:0std private int profile_and_level_indication; private int video_format; private String video_format_S[] = { "comp","PAL","NTSC","SECAM","MAC","unspec","res","res" }; private String prof[] = { "res","HP","SS","SNR","MP","SP","res","res" }; private String lev[] = { "res","res","res","res","HL","res","HL1440","res","ML","res","LL","res","res","res","res" }; /* ISO/IEC 13818-2 section 6.2.3: picture_header() */ private int picture_coding_type=0; private int temporal_reference=0; /* ISO/IEC 13818-2 section 6.2.3.1: picture_coding_extension() header */ private int f_code[][] = new int[2][2]; private int picture_structure=3; //0 private int frame_pred_frame_dct=1; //0 private int progressive_frame=1; //0 private int concealment_motion_vectors=0; private int intra_dc_precision=0; //8bit private int top_field_first=0; private int repeat_first_field=0; private int intra_vlc_format=0; // private int intra_quantizer_matrix[] = new int[64]; private int non_intra_quantizer_matrix[] = new int[64]; private int chroma_intra_quantizer_matrix[] = new int[64]; private int chroma_non_intra_quantizer_matrix[] = new int[64]; private int load_intra_quantizer_matrix=0; private int load_non_intra_quantizer_matrix=0; private int load_chroma_intra_quantizer_matrix=0; private int load_chroma_non_intra_quantizer_matrix=0; private short block[][]=new short[12][64]; //macroblocks final String picture_coding_type_string[] = { "bad","I","P","B","D" }; final String progressive_string[] = { "i","p" }; final String aspect_ratio_string[] = { "bad","(1:1)","(4:3)","(16:9)","(2.21:1)","(0.8055)","(0.8437)","(0.9375)","(0.9815)","(1.0255)","(1.0695)","(1.1250)","(1.1575)","(1.2015)" }; /* cosine transform matrix for 8x1 IDCT */ final float ref_dct_matrix[][] = { { // [0][0-7] 3.5355339059327379e-001f, 3.5355339059327379e-001f, 3.5355339059327379e-001f, 3.5355339059327379e-001f, 3.5355339059327379e-001f, 3.5355339059327379e-001f, 3.5355339059327379e-001f, 3.5355339059327379e-001f, }, { // [1][0-7] 4.9039264020161522e-001f, 4.1573480615127262e-001f, 2.7778511650980114e-001f, 9.7545161008064166e-002f, -9.7545161008064096e-002f, -2.7778511650980098e-001f, -4.1573480615127267e-001f, -4.9039264020161522e-001f, }, { // [2][0-7] 4.6193976625564337e-001f, 1.9134171618254492e-001f, -1.9134171618254486e-001f, -4.6193976625564337e-001f, -4.6193976625564342e-001f, -1.9134171618254517e-001f, 1.9134171618254500e-001f, 4.6193976625564326e-001f, }, { // [3][0-7] 4.1573480615127262e-001f, -9.7545161008064096e-002f, -4.9039264020161522e-001f, -2.7778511650980109e-001f, 2.7778511650980092e-001f, 4.9039264020161522e-001f, 9.7545161008064388e-002f, -4.1573480615127256e-001f, }, { // [4][0-7] 3.5355339059327379e-001f, -3.5355339059327373e-001f, -3.5355339059327384e-001f, 3.5355339059327368e-001f, 3.5355339059327384e-001f, -3.5355339059327334e-001f, -3.5355339059327356e-001f, 3.5355339059327329e-001f, }, { // [5][0-7] 2.7778511650980114e-001f, -4.9039264020161522e-001f, 9.7545161008064152e-002f, 4.1573480615127273e-001f, -4.1573480615127256e-001f, -9.7545161008064013e-002f, 4.9039264020161533e-001f, -2.7778511650980076e-001f, }, { // [6][0-7] 1.9134171618254492e-001f, -4.6193976625564342e-001f, 4.6193976625564326e-001f, -1.9134171618254495e-001f, -1.9134171618254528e-001f, 4.6193976625564337e-001f, -4.6193976625564320e-001f, 1.9134171618254478e-001f, }, { // [7][0-7] 9.7545161008064166e-002f, -2.7778511650980109e-001f, 4.1573480615127273e-001f, -4.9039264020161533e-001f, 4.9039264020161522e-001f, -4.1573480615127251e-001f, 2.7778511650980076e-001f, -9.7545161008064291e-002f, }, }; final short idct_clip_table[] = { -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-256,-256,-256,-256,-256,-256,-256, -256,-255,-254,-253,-252,-251,-250,-249, -248,-247,-246,-245,-244,-243,-242,-241, -240,-239,-238,-237,-236,-235,-234,-233, -232,-231,-230,-229,-228,-227,-226,-225, -224,-223,-222,-221,-220,-219,-218,-217, -216,-215,-214,-213,-212,-211,-210,-209, -208,-207,-206,-205,-204,-203,-202,-201, -200,-199,-198,-197,-196,-195,-194,-193, -192,-191,-190,-189,-188,-187,-186,-185, -184,-183,-182,-181,-180,-179,-178,-177, -176,-175,-174,-173,-172,-171,-170,-169, -168,-167,-166,-165,-164,-163,-162,-161, -160,-159,-158,-157,-156,-155,-154,-153, -152,-151,-150,-149,-148,-147,-146,-145, -144,-143,-142,-141,-140,-139,-138,-137, -136,-135,-134,-133,-132,-131,-130,-129, -128,-127,-126,-125,-124,-123,-122,-121, -120,-119,-118,-117,-116,-115,-114,-113, -112,-111,-110,-109,-108,-107,-106,-105, -104,-103,-102,-101,-100, -99, -98, -97, -96, -95, -94, -93, -92, -91, -90, -89, -88, -87, -86, -85, -84, -83, -82, -81, -80, -79, -78, -77, -76, -75, -74, -73, -72, -71, -70, -69, -68, -67, -66, -65, -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53, -52, -51, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, -40, -39, -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }; final byte cc_table[] = { 0, 0, 0, 0, 1, 2, 1, 2, 1, 2, 1, 2 }; final int ChromaFormat[] = { 0, 6, 8, 12 }; /* non-linear quantization coefficient table */ final byte Non_Linear_quantizer_scale[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, 104, 112 }; final byte MBAtab1[][] = { //VLCtab val,len {-1,0}, {-1,0}, {7,5}, {6,5}, {5,4}, {5,4}, {4,4}, {4,4}, {3,3}, {3,3}, {3,3}, {3,3}, {2,3}, {2,3}, {2,3}, {2,3} }; /* Table B-1, macroblock_address_increment, codes 00000011000 ... 0000111xxxx */ final byte MBAtab2[][] = { //VLCtab val,len {33,11}, {32,11}, {31,11}, {30,11}, {29,11}, {28,11}, {27,11}, {26,11}, {25,11}, {24,11}, {23,11}, {22,11}, {21,10}, {21,10}, {20,10}, {20,10}, {19,10}, {19,10}, {18,10}, {18,10}, {17,10}, {17,10}, {16,10}, {16,10}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7} }; /* default intra quantization matrix */ final int default_intra_quantizer_matrix[] = { 8, 16, 19, 22, 26, 27, 29, 34, 16, 16, 22, 24, 27, 29, 34, 37, 19, 22, 26, 27, 29, 34, 34, 38, 22, 22, 26, 27, 29, 34, 37, 40, 22, 26, 27, 29, 32, 35, 40, 48, 26, 27, 29, 32, 35, 40, 48, 58, 26, 27, 29, 34, 38, 46, 56, 69, 27, 29, 35, 38, 46, 56, 69, 83 }; /* zig-zag and alternate scan patterns */ final byte scan[][] = { { /* Zig-Zag scan pattern */ 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 } , { /* Alternate scan pattern */ 0, 8, 16, 24, 1, 9, 2, 10, 17, 25, 32, 40, 48, 56, 57, 49, 41, 33, 26, 18, 3, 11, 4, 12, 19, 27, 34, 42, 50, 58, 35, 43, 51, 59, 20, 28, 5, 13, 6, 14, 21, 29, 36, 44, 52, 60, 37, 45, 53, 61, 22, 30, 7, 15, 23, 31, 38, 46, 54, 62, 39, 47, 55, 63 } }; /*** typedef struct { char run, level, len; } DCTtab; typedef struct { char val, len; } VLCtab; ***/ /* Table B-14, DCT coefficients table zero, * codes 000001xx ... 00111xxx */ final byte DCTtab0[][] = { {65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */ {2,2,7}, {2,2,7}, {9,1,7}, {9,1,7}, {0,4,7}, {0,4,7}, {8,1,7}, {8,1,7}, {7,1,6}, {7,1,6}, {7,1,6}, {7,1,6}, {6,1,6}, {6,1,6}, {6,1,6}, {6,1,6}, {1,2,6}, {1,2,6}, {1,2,6}, {1,2,6}, {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6}, {13,1,8}, {0,6,8}, {12,1,8}, {11,1,8}, {3,2,8}, {1,3,8}, {0,5,8}, {10,1,8}, {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5} }; /* Table B-15, DCT coefficients table one, * codes 000001xx ... 11111111 */ final byte DCTtab0a[][] = { {65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */ {7,1,7}, {7,1,7}, {8,1,7}, {8,1,7}, {6,1,7}, {6,1,7}, {2,2,7}, {2,2,7}, {0,7,6}, {0,7,6}, {0,7,6}, {0,7,6}, {0,6,6}, {0,6,6}, {0,6,6}, {0,6,6}, {4,1,6}, {4,1,6}, {4,1,6}, {4,1,6}, {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6}, {1,5,8}, {11,1,8}, {0,11,8}, {0,10,8}, {13,1,8}, {12,1,8}, {3,2,8}, {1,4,8}, {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, /* EOB */ {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, {9,1,7}, {9,1,7}, {1,3,7}, {1,3,7}, {10,1,7}, {10,1,7}, {0,8,7}, {0,8,7}, {0,9,7}, {0,9,7}, {0,12,8}, {0,13,8}, {2,3,8}, {4,2,8}, {0,14,8}, {0,15,8} }; /* Table B-14, DCT coefficients table zero, * codes 0000001000 ... 0000001111 */ final byte DCTtab1[][] = { {16,1,10}, {5,2,10}, {0,7,10}, {2,3,10}, {1,4,10}, {15,1,10}, {14,1,10}, {4,2,10} }; /* Table B-15, DCT coefficients table one, * codes 000000100x ... 000000111x */ final byte DCTtab1a[][] = { {5,2,9}, {5,2,9}, {14,1,9}, {14,1,9}, {2,4,10}, {16,1,10}, {15,1,9}, {15,1,9} }; /* Table B-14/15, DCT coefficients table zero / one, * codes 000000010000 ... 000000011111 */ final byte DCTtab2[][] = { {0,11,12}, {8,2,12}, {4,3,12}, {0,10,12}, {2,4,12}, {7,2,12}, {21,1,12}, {20,1,12}, {0,9,12}, {19,1,12}, {18,1,12}, {1,5,12}, {3,3,12}, {0,8,12}, {6,2,12}, {17,1,12} }; /* Table B-14/15, DCT coefficients table zero / one, * codes 0000000010000 ... 0000000011111 */ final byte DCTtab3[][] = { {10,2,13}, {9,2,13}, {5,3,13}, {3,4,13}, {2,5,13}, {1,7,13}, {1,6,13}, {0,15,13}, {0,14,13}, {0,13,13}, {0,12,13}, {26,1,13}, {25,1,13}, {24,1,13}, {23,1,13}, {22,1,13} }; /* Table B-14/15, DCT coefficients table zero / one, * codes 00000000010000 ... 00000000011111 */ final byte DCTtab4[][] = { {0,31,14}, {0,30,14}, {0,29,14}, {0,28,14}, {0,27,14}, {0,26,14}, {0,25,14}, {0,24,14}, {0,23,14}, {0,22,14}, {0,21,14}, {0,20,14}, {0,19,14}, {0,18,14}, {0,17,14}, {0,16,14} }; /* Table B-14/15, DCT coefficients table zero / one, * codes 000000000010000 ... 000000000011111 */ final byte DCTtab5[][] = { {0,40,15}, {0,39,15}, {0,38,15}, {0,37,15}, {0,36,15}, {0,35,15}, {0,34,15}, {0,33,15}, {0,32,15}, {1,14,15}, {1,13,15}, {1,12,15}, {1,11,15}, {1,10,15}, {1,9,15}, {1,8,15} }; /* Table B-14/15, DCT coefficients table zero / one, * codes 0000000000010000 ... 0000000000011111 */ final byte DCTtab6[][] = { //DCTtab run,level,len {1,18,16}, {1,17,16}, {1,16,16}, {1,15,16}, {6,3,16}, {16,2,16}, {15,2,16}, {14,2,16}, {13,2,16}, {12,2,16}, {11,2,16}, {31,1,16}, {30,1,16}, {29,1,16}, {28,1,16}, {27,1,16} }; /* Table B-14, DCT coefficients table zero, * codes 0100 ... 1xxx (used for first (DC) coefficient) */ final byte DCTtabfirst[][] = { {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3}, {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1} }; /* Table B-14, DCT coefficients table zero, * codes 0100 ... 1xxx (used for all other coefficients) */ final byte DCTtabnext[][] = { {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3}, {64,0,2}, {64,0,2}, {64,0,2}, {64,0,2}, /* EOB */ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2} }; /* Table B-9, coded_block_pattern, codes 01000 ... 111xx */ final byte CBPtab0[][] = { {-1,0}, {-1,0}, {-1,0}, {-1,0}, {-1,0}, {-1,0}, {-1,0}, {-1,0}, {62,5}, {2,5}, {61,5}, {1,5}, {56,5}, {52,5}, {44,5}, {28,5}, {40,5}, {20,5}, {48,5}, {12,5}, {32,4}, {32,4}, {16,4}, {16,4}, {8,4}, {8,4}, {4,4}, {4,4}, {60,3}, {60,3}, {60,3}, {60,3} }; /* Table B-9, coded_block_pattern, codes 00000100 ... 001111xx */ final byte CBPtab1[][] = { {-1,0}, {-1,0}, {-1,0}, {-1,0}, {58,8}, {54,8}, {46,8}, {30,8}, {57,8}, {53,8}, {45,8}, {29,8}, {38,8}, {26,8}, {37,8}, {25,8}, {43,8}, {23,8}, {51,8}, {15,8}, {42,8}, {22,8}, {50,8}, {14,8}, {41,8}, {21,8}, {49,8}, {13,8}, {35,8}, {19,8}, {11,8}, {7,8}, {34,7}, {34,7}, {18,7}, {18,7}, {10,7}, {10,7}, {6,7}, {6,7}, {33,7}, {33,7}, {17,7}, {17,7}, {9,7}, {9,7}, {5,7}, {5,7}, {63,6}, {63,6}, {63,6}, {63,6}, {3,6}, {3,6}, {3,6}, {3,6}, {36,6}, {36,6}, {36,6}, {36,6}, {24,6}, {24,6}, {24,6}, {24,6} }; /* Table B-9, coded_block_pattern, codes 000000001 ... 000000111 */ final byte CBPtab2[][] = { {-1,0}, {0,9}, {39,9}, {27,9}, {59,9}, {55,9}, {47,9}, {31,9} }; /* Table B-12, dct_dc_size_luminance, codes 00xxx ... 11110 */ final byte DClumtab0[][] = { {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5}, {-1, 0} }; /* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */ final byte DClumtab1[][] = { {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10,9}, {11,9} }; /* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */ final byte DCchromtab0[][] = { {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5}, {-1, 0} }; /* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */ final byte DCchromtab1[][] = { {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {9, 9}, {9, 9}, {10,10}, {11,10} }; /* Table B-10, motion_code, codes 0001 ... 01xx */ final byte MVtab0[][] = { {-1,0}, {3,3}, {2,2}, {2,2}, {1,1}, {1,1}, {1,1}, {1,1} }; /* Table B-10, motion_code, codes 0000011 ... 000011x */ final byte MVtab1[][] = { {-1,0}, {-1,0}, {-1,0}, {7,6}, {6,6}, {5,6}, {4,5}, {4,5} }; /* Table B-10, motion_code, codes 0000001100 ... 000001011x */ final byte MVtab2[][] = { {16,9}, {15,9}, {14,9}, {13,9}, {12,9}, {11,9}, {10,8}, {10,8}, {9,8}, {9,8}, {8,8}, {8,8} }; /* Table B-3, macroblock_type in P-pictures, codes 001..1xx */ final byte PMBtab0[][] = { {-1,0}, {MACROBLOCK_MOTION_FORWARD,3}, {MACROBLOCK_PATTERN,2}, {MACROBLOCK_PATTERN,2}, {MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,1}, {MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,1}, {MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,1}, {MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,1} }; /* Table B-3, macroblock_type in P-pictures, codes 000001..00011x */ final byte PMBtab1[][] = { {-1,0}, {MACROBLOCK_QUANT|MACROBLOCK_INTRA,6}, {MACROBLOCK_QUANT|MACROBLOCK_PATTERN,5}, {MACROBLOCK_QUANT|MACROBLOCK_PATTERN,5}, {MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,5}, {MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,5}, {MACROBLOCK_INTRA,5}, {MACROBLOCK_INTRA,5} }; /* Table B-4, macroblock_type in B-pictures, codes 0010..11xx */ final byte BMBtab0[][] = { {-1,0}, {-1,0}, {MACROBLOCK_MOTION_FORWARD,4}, {MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,4}, {MACROBLOCK_MOTION_BACKWARD,3}, {MACROBLOCK_MOTION_BACKWARD,3}, {MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,3}, {MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,3}, {MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2}, {MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2}, {MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2}, {MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2}, {MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2}, {MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2}, {MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2}, {MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2} }; /* Table B-4, macroblock_type in B-pictures, codes 000001..00011x */ final byte BMBtab1[][] = { {-1,0}, {MACROBLOCK_QUANT|MACROBLOCK_INTRA,6}, {MACROBLOCK_QUANT|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,6}, {MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,6}, {MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,5}, {MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,5}, {MACROBLOCK_INTRA,5}, {MACROBLOCK_INTRA,5} }; final double frame_rate_Table[] = { 0.0, ((24.0*1000.0)/1001.0), 24.0, 25.0, ((30.0*1000.0)/1001.0), 30.0, 50.0, ((60.0*1000.0)/1001.0), 60.0, -1, // reserved -1, -1, -1, -1, -1, -1 }; /* global value */ private byte backward_reference_frame[] = new byte[3], forward_reference_frame[] = new byte[3]; private byte auxframe[] = new byte[3], current_frame[] = new byte[3]; private byte u422, v422, u444, v444, rgb24, lum; private int pf_backward, pf_forward, pf_current; private float frame_rate,Frame_Rate; //from gopheader private int gop_hour; private int gop_minute; private int gop_sec; private int gop_frame; private int drop_flag; private int closed_gop; private int broken_link; /** * */ private void Clear_Block(int comp) // assembler? { Arrays.fill(block[comp],(short)0); //clear macroblaock } /** * */ private int Get_Bits(int N) { int Pos, Val; Pos = BitPos>>>3; if (Pos >= buf.length) ERROR3 = true; Val = (0xFF & buf[Pos++])<<24; if (Pos < buf.length) Val |= (0xFF & buf[Pos++])<<16; if (Pos < buf.length) Val |= (0xFF & buf[Pos++])<<8; if (Pos < buf.length) Val |= (0xFF & buf[Pos]); Val <<= BitPos & 7; Val >>>= 32-N; BitPos += N; BufferPos = BitPos>>>3; return Val; } /** * */ private int Show_Bits(int N) { int Pos, Val; Pos = BitPos>>>3; if (Pos >= buf.length) ERROR3 = true; Val = (0xFF & buf[Pos++])<<24; if (Pos < buf.length) Val |= (0xFF & buf[Pos++])<<16; if (Pos < buf.length) Val |= (0xFF & buf[Pos++])<<8; if (Pos < buf.length) Val |= (0xFF & buf[Pos]); Val <<= BitPos & 7; Val >>>= 32 - N; return Val; } /** * */ private void Flush_Bits(int N) { BitPos += N; BufferPos = BitPos>>>3; } /* decode headers from one input stream */ public int extern_Get_Hdr() { int start_code; for (;;){ /* look for next_start_code */ if (DIRECTION) previous_start_code(); else next_start_code(); if ((start_code=Get_Bits(32))==SEQUENCE_HEADER_CODE){ resetDecoder(); //DM26112003 081.5++ StartPos=BufferPos-4; sequence_header(); next_start_code(); if ((start_code=Get_Bits(32))==GROUP_START_CODE) { group_of_pictures_header(); next_start_code(); if ((start_code=Get_Bits(32))==PICTURE_START_CODE) { picture_header(); return 1; } } } else if (viewGOP && start_code==GROUP_START_CODE){ StartPos=BufferPos-4; group_of_pictures_header(); next_start_code(); if ((start_code=Get_Bits(32))==PICTURE_START_CODE){ picture_header(); return 1; } } //else if (start_code==SEQUENCE_END_CODE) // return 2; else if (DIRECTION) Flush_Bits(-40); } } /* decode headers from one input stream */ public int Get_Hdr() { video_format=5; for (;;){ /* look for next_start_code */ next_start_code(); switch (Get_Bits(32)){ case SEQUENCE_HEADER_CODE: resetDecoder(); //DM26112003 081.5++ StartPos=BufferPos-4; sequence_header(); break; case GROUP_START_CODE: group_of_pictures_header(); break; case PICTURE_START_CODE: picture_header(); return 1; case SEQUENCE_END_CODE: return 2; } } } /* align to start of next next_start_code */ private void next_start_code() { Flush_Bits((8 - (BitPos & 7)) & 7); while (Show_Bits(24) != 1) Flush_Bits(8); } /* align to start of next next_start_code */ private void previous_start_code() { Flush_Bits((8 - (BitPos & 7)) & 7); while (Show_Bits(24) != 1) Flush_Bits(-8); } /* decode sequence header */ private void sequence_header(){ int constrained_parameters_flag; int bit_rate_value; int vbv_buffer_size; int i; horizontal_size = Get_Bits(12); vertical_size = Get_Bits(12); aspect_ratio_information = Get_Bits(4); frame_rate_code = Get_Bits(4); bit_rate_value = Get_Bits(18); Flush_Bits(1); // marker bit vbv_buffer_size = Get_Bits(10); constrained_parameters_flag = Get_Bits(1); //DM05072004 081.7 int06 changed info_4 = " "; if ((load_intra_quantizer_matrix = Get_Bits(1))>0) { for (i=0; i<64; i++) intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8); //DM05072004 081.7 int06 add info_4 += ",iqm"; } else { System.arraycopy(default_intra_quantizer_matrix,0,intra_quantizer_matrix,0,64); } if ((load_non_intra_quantizer_matrix = Get_Bits(1))>0) { for (i=0; i<64; i++) non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8); //DM05072004 081.7 int06 add info_4 += ",niqm"; } else { Arrays.fill(non_intra_quantizer_matrix,16); } /* copy luminance to chrominance matrices */ System.arraycopy(intra_quantizer_matrix,0,chroma_intra_quantizer_matrix,0,64); System.arraycopy(non_intra_quantizer_matrix,0,chroma_non_intra_quantizer_matrix,0,64); frame_rate = (float)frame_rate_Table[frame_rate_code]; //DM06022004 081.6 int15 add extension_and_user_data(); //DM06052004 081.7 int02 add //DM29082004 081.7 int10 changed info_3 = ", " + (bit_rate_value * 400) + "bps, vbv " + vbv_buffer_size + (constrained_parameters_flag > 0 ? ", cpf" : ""); } /* decode group of pictures header */ /* ISO/IEC 13818-2 section 6.2.2.6 */ private void group_of_pictures_header(){ drop_flag = Get_Bits(1); gop_hour = Get_Bits(5); gop_minute = Get_Bits(6); Flush_Bits(1); // marker bit gop_sec = Get_Bits(6); gop_frame = Get_Bits(6); closed_gop = Get_Bits(1); broken_link = Get_Bits(1); extension_and_user_data(); } /* decode extension and user data */ /* ISO/IEC 13818-2 section 6.2.2.2 */ private void extension_and_user_data(){ int code, ext_ID; next_start_code(); while ((code = Show_Bits(32))==EXTENSION_START_CODE || code==USER_DATA_START_CODE){ if (code==EXTENSION_START_CODE) { Flush_Bits(32); ext_ID = Get_Bits(4); switch (ext_ID) { case SEQUENCE_EXTENSION_ID: sequence_extension(); break; case SEQUENCE_DISPLAY_EXTENSION_ID: sequence_display_extension(); break; case QUANT_MATRIX_EXTENSION_ID: quant_matrix_extension(); break; case PICTURE_DISPLAY_EXTENSION_ID: picture_display_extension(); break; case PICTURE_CODING_EXTENSION_ID: picture_coding_extension(); break; case COPYRIGHT_EXTENSION_ID: copyright_extension(); break; } next_start_code(); }else{ info_4 += ", user_data"; //DM06052004 081.7 int02 add Flush_Bits(32); // ISO/IEC 13818-2 sections 6.3.4.1 and 6.2.2.2.2 next_start_code(); // skip user data } } } /* decode picture header */ /* ISO/IEC 13818-2 section 6.2.3 */ private void picture_header(){ int vbv_delay; int full_pel_forward_vector; int forward_f_code; int full_pel_backward_vector; int backward_f_code; int Extra_Information_Byte_Count; temporal_reference = Get_Bits(10); picture_coding_type = Get_Bits(3); vbv_delay = Get_Bits(16); if (picture_coding_type==P_TYPE || picture_coding_type==B_TYPE) { full_pel_forward_vector = Get_Bits(1); forward_f_code = Get_Bits(3); } if (picture_coding_type==B_TYPE){ full_pel_backward_vector = Get_Bits(1); backward_f_code = Get_Bits(3); } Extra_Information_Byte_Count = extra_bit_information(); extension_and_user_data(); } /* decode sequence extension */ /* ISO/IEC 13818-2 section 6.2.2.3 */ private void sequence_extension(){ int low_delay; int frame_rate_extension_n; int frame_rate_extension_d; int horizontal_size_extension; int vertical_size_extension; int bit_rate_extension; int vbv_buffer_size_extension; profile_and_level_indication = Get_Bits(8); progressive_sequence = Get_Bits(1); chroma_format = Get_Bits(2); horizontal_size_extension = Get_Bits(2); vertical_size_extension = Get_Bits(2); bit_rate_extension = Get_Bits(12); Flush_Bits(1); // marker bit vbv_buffer_size_extension = Get_Bits(8); low_delay = Get_Bits(1); frame_rate_extension_n = Get_Bits(2); frame_rate_extension_d = Get_Bits(5); frame_rate = frame_rate * (frame_rate_extension_n+1) / (frame_rate_extension_d+1); //DM06022004 081.6 int15 changed horizontal_size = (horizontal_size_extension<<12) | (horizontal_size&0xfff); vertical_size = (vertical_size_extension<<12) | (vertical_size&0xfff); info_4 += ", ld=" + low_delay; //DM26052004 081.7 int03 add } /* decode sequence display extension */ private void sequence_display_extension(){ int color_description; int color_primaries; int transfer_characteristics; int matrix_coefficients; int display_horizontal_size; int display_vertical_size; video_format = Get_Bits(3); color_description = Get_Bits(1); if (color_description>0){ color_primaries = Get_Bits(8); transfer_characteristics = Get_Bits(8); matrix_coefficients = Get_Bits(8); } display_horizontal_size = Get_Bits(14); Flush_Bits(1); // marker bit display_vertical_size = Get_Bits(14); //DM06052004 081.7 int02 add //DM26052004 081.7 int03 changed info_4 += ", SDE: " + display_horizontal_size + "*" + display_vertical_size; } /* decode quant matrix entension */ /* ISO/IEC 13818-2 section 6.2.3.2 */ private void quant_matrix_extension(){ int i; if ((load_intra_quantizer_matrix = Get_Bits(1))>0) for (i=0; i<64; i++) chroma_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8); if ((load_non_intra_quantizer_matrix = Get_Bits(1))>0) for (i=0; i<64; i++) chroma_non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8); if ((load_chroma_intra_quantizer_matrix = Get_Bits(1))>0) for (i=0; i<64; i++) chroma_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8); if ((load_chroma_non_intra_quantizer_matrix = Get_Bits(1))>0) for (i=0; i<64; i++) chroma_non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8); } /* decode picture display extension */ /* ISO/IEC 13818-2 section 6.2.3.3. */ private void picture_display_extension(){ int frame_center_horizontal_offset[] = new int[3]; int frame_center_vertical_offset[] = new int[3]; int i; int number_of_frame_center_offsets; /* based on ISO/IEC 13818-2 section 6.3.12 (November 1994) Picture display extensions */ /* derive number_of_frame_center_offsets */ if (progressive_sequence>0){ if (repeat_first_field>0) { if (top_field_first>0) number_of_frame_center_offsets = 3; else number_of_frame_center_offsets = 2; }else number_of_frame_center_offsets = 1; }else{ if (picture_structure!=FRAME_PICTURE) number_of_frame_center_offsets = 1; else{ if (repeat_first_field>0) number_of_frame_center_offsets = 3; else number_of_frame_center_offsets = 2; } } /* now parse */ for (i=0; i0){ v_axis = Get_Bits(1); field_sequence = Get_Bits(3); sub_carrier = Get_Bits(1); burst_amplitude = Get_Bits(7); sub_carrier_phase = Get_Bits(8); //DM29082004 081.7 int10 add info_3 += ", cdf"; } } /* Copyright extension */ /* ISO/IEC 13818-2 section 6.2.3.6. */ /* (header added in November, 1994 to the IS document) */ public void copyright_extension(){ int copyright_flag; int copyright_identifier; int original_or_copy; int copyright_number_1; int copyright_number_2; int copyright_number_3; int reserved_data; copyright_flag = Get_Bits(1); copyright_identifier = Get_Bits(8); original_or_copy = Get_Bits(1); /* reserved */ reserved_data = Get_Bits(7); Flush_Bits(1); // marker bit copyright_number_1 = Get_Bits(20); Flush_Bits(1); // marker bit copyright_number_2 = Get_Bits(22); Flush_Bits(1); // marker bit copyright_number_3 = Get_Bits(22); } /* set std for lower profiles as mpeg1 */ public void resetDecoder(){ Fault_Flag=0; //DM14052004 081.7 int02 add,fix picture_coding_type=0; //DM14052004 081.7 int02 add,fix SequenceHeader=1; video_format=5; progressive_sequence=1; chroma_format=1; profile_and_level_indication=0; Second_Field=0; intra_dc_precision=0; picture_structure=FRAME_PICTURE; top_field_first=0; frame_pred_frame_dct=1; concealment_motion_vectors=0; intra_vlc_format=0; repeat_first_field=0; progressive_frame=1; q_scale_type=0; quantizer_scale=0; alternate_scan=0; } public void InitialDecoder(){ mb_width = (horizontal_size+15)/16; mb_height = (progressive_sequence>0) ? (vertical_size+15)/16 : 2*((vertical_size+31)/32); Coded_Picture_Width = 16 * mb_width; Coded_Picture_Height = 16 * mb_height; Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width : Coded_Picture_Width>>1; Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height : Coded_Picture_Height>>1; block_count = ChromaFormat[chroma_format]; if (picture_coding_type==I_TYPE) pixels = new int[Coded_Picture_Width*Coded_Picture_Height]; //DM30112003 081.5++ fix } //public void Decode_Picture(int ref, byte dst, int pitch){ public void Decode_Picture(){ if (picture_structure==FRAME_PICTURE && Second_Field>0) Second_Field = 0; if (picture_coding_type!=B_TYPE){ pf_forward = pf_backward; pf_backward = pf_current; } //moved String SH[] = { "G","S" }; String cf[] = { "res.","4:2:0","4:2:2","4:4:4" }; String fieldorder[] = {"bff","tff"}; //<==TheHorse 221003 String picture_struc[] = {"-","T","B","F"}; //DM08022004 081.6 int16 add //DM26022004 081.6 int18 changed //DM06052004 081.7 int02 changed info_2 = "" + gop_hour + ":" + gop_minute + ":" + gop_sec + ":" + gop_frame + " "; info_2 += ", " + drop_flag + "/" + closed_gop + "/" + broken_link + " "; info_2 += ", " + (Math.round(frame_rate * 1000) / 1000.0f) + "fps "; //DM06022004 081.6 int15 change info_2 += ", " + SH[SequenceHeader] + " "; info_2 += ", " + picture_struc[picture_structure]; //DM08022004 081.6 int16 add info_2 += ", " + ((progressive_sequence==0) ? fieldorder[top_field_first] : "-") + " "; //<==TheHorse 221003 info_2 += ", " + cf[chroma_format]; info_2 += info_3; SequenceHeader=0; Update_Picture_Buffers(); picture_data(); // scale_Picture(); /** if (ref>0 && (picture_structure==FRAME_PICTURE || Second_Field>0)){ if (picture_coding_type==B_TYPE) FrametoRGB(auxframe, pf_current, dst, pitch); else FrametoRGB(forward_reference_frame, pf_forward, dst, pitch); } **/ if (picture_structure!=FRAME_PICTURE) Second_Field ^= Second_Field; } /* reuse old picture buffers as soon as they are no longer needed */ public void Update_Picture_Buffers(){ int cc; /* color component index */ byte tmp; /* temporary swap pointer */ for (cc=0; cc<3; cc++) { /* B pictures do not need to be save for future reference */ if (picture_coding_type==B_TYPE) current_frame[cc] = auxframe[cc]; else{ if (Second_Field<1){ /* only update at the beginning of the coded frame */ tmp = forward_reference_frame[cc]; /* the previously decoded reference frame is stored coincident with the location where the backward reference frame is stored (backwards prediction is not needed in P pictures) */ forward_reference_frame[cc] = backward_reference_frame[cc]; /* update pointer for potential future B pictures */ backward_reference_frame[cc] = tmp; } /* can erase over old backward reference frame since it is not used in a P picture, and since any subsequent B pictures will use the previously decoded I or P frame as the backward_reference_frame */ current_frame[cc] = backward_reference_frame[cc]; } if (picture_structure==BOTTOM_FIELD) current_frame[cc] += (cc==0) ? Coded_Picture_Width : Chroma_Width; } } /* decode all macroblocks of the current picture */ /* stages described in ISO/IEC 13818-2 section 7 */ public void picture_data(){ int MBAmax; int err=0; /* number of macroblocks per picture */ MBAmax = mb_width*mb_height; if (picture_structure!=FRAME_PICTURE) MBAmax>>=1; for (;;) if (slice(MBAmax)<0) return; } /* decode slice header */ /* ISO/IEC 13818-2 section 6.2.4 */ public int slice_header(){ int slice_picture_id_enable = 0; int slice_picture_id = 0; int extra_information_slice = 0; int slice_vertical_position_extension = vertical_size>2800 ? Get_Bits(3) : 0; int quantizer_scale_code = Get_Bits(5); quantizer_scale = (q_scale_type>0) ? Non_Linear_quantizer_scale[quantizer_scale_code] : quantizer_scale_code<<1; /* slice_id introduced in March 1995 as part of the video corridendum (after the IS was drafted in November 1994) */ if (Get_Bits(1)>0){ Get_Bits(1); // intra slice slice_picture_id_enable = Get_Bits(1); slice_picture_id = Get_Bits(6); extra_information_slice = extra_bit_information(); } return slice_vertical_position_extension; } /* decode extra bit information */ /* ISO/IEC 13818-2 section 6.2.3.4. */ public int extra_bit_information(){ int Byte_Count = 0; while (Get_Bits(1)>0){ Flush_Bits(8); Byte_Count ++; } return Byte_Count; } /* decode all macroblocks of the current picture */ /* ISO/IEC 13818-2 section 6.3.16 */ /* return 0 : go to next slice */ /* return -1: go to next picture */ public int slice(int MBAmax){ int MBA[] = {0}, MBAinc[] ={0}, macroblock_type[]={0}, motion_type[]={0}, dct_type[]={0}, ret=0; int dc_dct_pred[] = new int[3], PMV[][][] = new int[2][2][2], motion_vertical_field_select[][] = new int[2][2], dmvector[] = new int[2]; if ((ret=start_of_slice(MBA, MBAinc, dc_dct_pred, PMV))!=1) return ret; for (;;){ /* this is how we properly exit out of picture */ if (MBA[0]>=MBAmax) return -1; // all macroblocks decoded if (MBAinc[0]==0) { if (Show_Bits(23)<1 || Fault_Flag>0){ // next_start_code or fault Fault_Flag = 0; return 0; // trigger: go to next slice }else{ /* neither next_start_code nor Fault_Flag */ /* decode macroblock address increment */ MBAinc[0] = Get_macroblock_address_increment(); if (Fault_Flag>0) { Fault_Flag = 0; return 0; // trigger: go to next slice } } } //test //System.out.println("mba " + MBA[0]); if (MBAinc[0]==1) { /* not skipped */ if (decode_macroblock(macroblock_type, motion_type, dct_type, PMV, dc_dct_pred, motion_vertical_field_select, dmvector)<1) { Fault_Flag = 0; //DM14052004 081.7 int02 changed return 0; //return -1; // return 0; // trigger: go to next slice } }else{ /* MBAinc[0]!=1: skipped macroblock */ /* ISO/IEC 13818-2 section 7.6.6 */ skipped_macroblock(dc_dct_pred, PMV, motion_type, motion_vertical_field_select, macroblock_type); } /* ISO/IEC 13818-2 section 7.6 */ motion_compensation(MBA, macroblock_type, motion_type, PMV, motion_vertical_field_select, dmvector, dct_type); /* advance to next macroblock */ MBA[0]++; MBAinc[0]--; if (MBA[0]>=MBAmax) return -1; // all macroblocks decoded } } /* ISO/IEC 13818-2 section 7.6.6 */ public void skipped_macroblock(int dc_dct_pred[], int PMV[][][], int motion_type[], int motion_vertical_field_select[][], int macroblock_type[]){ int comp; for (comp=0; comp0) return 0; // trigger: go to next slice if ( (macroblock_type[0] & MACROBLOCK_QUANT)>0 ){ quantizer_scale_code = Get_Bits(5); /* ISO/IEC 13818-2 section 7.4.2.2: Quantizer scale factor */ quantizer_scale = (q_scale_type>0) ? Non_Linear_quantizer_scale[quantizer_scale_code] : (quantizer_scale_code << 1); } /* ISO/IEC 13818-2 section 6.3.17.2: Motion vectors */ /* decode forward motion vectors */ if ( ((macroblock_type[0] & MACROBLOCK_MOTION_FORWARD)>0) || (((macroblock_type[0] & MACROBLOCK_INTRA)>0) && (concealment_motion_vectors>0))) motion_vectors(PMV, dmvector, motion_vertical_field_select, 0, motion_vector_count, mv_format, f_code[0][0]-1, f_code[0][1]-1, dmv, mvscale); if (Fault_Flag>0) return 0; // trigger: go to next slice /* decode backward motion vectors */ if ((macroblock_type[0] & MACROBLOCK_MOTION_BACKWARD)>0) motion_vectors(PMV, dmvector, motion_vertical_field_select, 1, motion_vector_count,mv_format, f_code[1][0]-1, f_code[1][1]-1, new int[1], mvscale); if (Fault_Flag>0) return 0; // trigger: go to next slice if (((macroblock_type[0] & MACROBLOCK_INTRA)>0) && (concealment_motion_vectors>0)) Flush_Bits(1); // marker bit /* macroblock_pattern */ /* ISO/IEC 13818-2 section 6.3.17.4: Coded block pattern */ if ((macroblock_type[0] & MACROBLOCK_PATTERN)>0) { coded_block_pattern = Get_coded_block_pattern(); if (chroma_format==CHROMA422) coded_block_pattern = (coded_block_pattern<<2) | Get_Bits(2); else if (chroma_format==CHROMA444) coded_block_pattern = (coded_block_pattern<<6) | Get_Bits(6); }else coded_block_pattern = ((macroblock_type[0] & MACROBLOCK_INTRA)>0) ? (1<0) return 0; // trigger: go to next slice //test /** System.out.println( "ma " + macroblock_type[0] + " /mt " + motion_type[0] + " /mv " + motion_vector_count[0] + " /mf " + mv_format[0] + " /ms " + mvscale[0] + " /dm " + dmv[0] + " /dc " + dct_type[0] + " /qs " + quantizer_scale + " /qt " + q_scale_type + " /cm " + concealment_motion_vectors ); **/ /* decode blocks */ for (comp=0; comp0){ if ((macroblock_type[0] & MACROBLOCK_INTRA)>0) Decode_MPEG2_Intra_Block(comp, dc_dct_pred); else Decode_MPEG2_Non_Intra_Block(comp); if (Fault_Flag>0) return 0; // trigger: go to next slice } } /* reset intra_dc predictors */ /* ISO/IEC 13818-2 section 7.2.1: DC coefficients in intra blocks */ if ((macroblock_type[0] & MACROBLOCK_INTRA)<1) dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0; /* reset motion vector predictors */ if ((macroblock_type[0] & MACROBLOCK_INTRA)>0 && concealment_motion_vectors<1 ) { /* intra mb without concealment motion vectors */ /* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */ PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0; PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0; } /* special "No_MC" macroblock_type case */ /* ISO/IEC 13818-2 section 7.6.3.5: Prediction in P pictures */ if ((picture_coding_type==P_TYPE) && (macroblock_type[0] & (MACROBLOCK_MOTION_FORWARD|MACROBLOCK_INTRA))<1) { /* non-intra mb without forward mv in a P picture */ /* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */ PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0; /* derive motion_type */ /* ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes, frame_motion_type */ if (picture_structure==FRAME_PICTURE) motion_type[0] = MC_FRAME; else{ motion_type[0] = MC_FIELD; motion_vertical_field_select[0][0] = (picture_structure==BOTTOM_FIELD)?1:0; } } /* successfully decoded macroblock */ return 1 ; } /* decode one intra coded MPEG-2 block */ public void Decode_MPEG2_Intra_Block(int comp, int dc_dct_pred[]) { int val=0, i, j, sign, qmat[]; //qmat woanders?? int code; byte tab[]; short bp[]; //bp woanders array? bp = block[comp]; //macroblock qmat = (comp<4 || chroma_format==CHROMA420) ? intra_quantizer_matrix : chroma_intra_quantizer_matrix; /* ISO/IEC 13818-2 section 7.2.1: decode DC coefficients */ switch (cc_table[comp]) { case 0: val = (dc_dct_pred[0]+= Get_Luma_DC_dct_diff()); break; case 1: val = (dc_dct_pred[1]+= Get_Chroma_DC_dct_diff()); break; case 2: val = (dc_dct_pred[2]+= Get_Chroma_DC_dct_diff()); break; } //test /** System.out.println("comp " + comp + " /dc " + val); if (quantizer_scale > 4) val -= 128; **/ bp[0] = (short)(val << (3-intra_dc_precision)); //the top-left pixel value of block /* decode AC coefficients */ for (i=1; ; i++){ code = Show_Bits(16); if (code>=16384 && intra_vlc_format<1) tab = DCTtabnext[(code>>12)-4]; else if (code>=1024){ if (intra_vlc_format>0) tab = DCTtab0a[(code>>8)-4]; else tab = DCTtab0[(code>>8)-4]; } else if (code>=512){ if (intra_vlc_format>0) tab = DCTtab1a[(code>>6)-8]; else tab = DCTtab1[(code>>6)-8]; } else if (code>=256) tab = DCTtab2[(code>>4)-16]; else if (code>=128) tab = DCTtab3[(code>>3)-16]; else if (code>=64) tab = DCTtab4[(code>>2)-16]; else if (code>=32) tab = DCTtab5[(code>>1)-16]; else if (code>=16) tab = DCTtab6[code-16]; else{ Fault_Flag = 1; return; } Flush_Bits(tab[2]); if (tab[0]<64){ i+= tab[0]; val = tab[1]; sign = Get_Bits(1); } else if (tab[0]==64) /* end_of_block */ return; else{ /* escape */ if (profile_and_level_indication==0){ //mpeg1 //DM28112003 081.5++ i+= Get_Bits(6); val = Get_Bits(8); if (val==0) val = Get_Bits(8); else if(val==128) val = Get_Bits(8)-128; else if(val>128) val-=256; sign = 0; }else{ //mpeg2 i+= Get_Bits(6); val = Get_Bits(12); if ( (sign = (val>=2048)?1:0) >0) val = 4096 - val; } } //prevent outside index i = i > 63 ? 63 : i; j = scan[alternate_scan][i]; val = (val * quantizer_scale * qmat[j]) >> 4; bp[j] = (short)((sign>0) ? -val : val); } } /* decode one non-intra coded MPEG-2 block */ public void Decode_MPEG2_Non_Intra_Block(int comp){ int val, i, j, sign, qmat[]; int code; byte tab[]; short bp[]; bp = block[comp]; qmat = (comp<4 || chroma_format==CHROMA420) ? non_intra_quantizer_matrix : chroma_non_intra_quantizer_matrix; /* decode AC coefficients */ for (i=0; ; i++){ code = Show_Bits(16); if (code>=16384){ if (i==0) tab = DCTtabfirst[(code>>12)-4]; else tab = DCTtabnext[(code>>12)-4]; } else if (code>=1024) tab = DCTtab0[(code>>8)-4]; else if (code>=512) tab = DCTtab1[(code>>6)-8]; else if (code>=256) tab = DCTtab2[(code>>4)-16]; else if (code>=128) tab = DCTtab3[(code>>3)-16]; else if (code>=64) tab = DCTtab4[(code>>2)-16]; else if (code>=32) tab = DCTtab5[(code>>1)-16]; else if (code>=16) tab = DCTtab6[code-16]; else{ Fault_Flag = 1; return; } Flush_Bits(tab[2]); if (tab[0]<64){ i+= tab[0]; val = tab[1]; sign = Get_Bits(1); } else if (tab[0]==64) /* end_of_block */ return; else { /* escape */ i+= Get_Bits(6); val = Get_Bits(12); if ( (sign = (val>=2048)?1:0)>0 ) val = 4096 - val; } j = scan[alternate_scan][i]; val = (((val<<1)+1) * quantizer_scale * qmat[j]) >> 5; bp[j] = (short)((sign>0) ? -val : val); } } /* parse VLC and perform dct_diff arithmetic. MPEG-2: ISO/IEC 13818-2 section 7.2.1 Note: the arithmetic here is presented more elegantly than the spec, yet the results, dct_diff, are the same. */ public int Get_Luma_DC_dct_diff(){ int code, size, dct_diff; /* decode length */ code = Show_Bits(5); if (code<31){ size = DClumtab0[code][0]; Flush_Bits(DClumtab0[code][1]); }else{ code = Show_Bits(9) - 0x1f0; size = DClumtab1[code][0]; Flush_Bits(DClumtab1[code][1]); } if (size==0) dct_diff = 0; else{ dct_diff = Get_Bits(size); if ((dct_diff & (1<<(size-1)))==0) dct_diff-= (1<=128) { code >>= 4; Flush_Bits(CBPtab0[code][1]); return CBPtab0[code][0]; } if (code>=8) { code >>= 1; Flush_Bits(CBPtab1[code][1]); return CBPtab1[code][0]; } if (code<1) { Fault_Flag = 3; return 0; } Flush_Bits(CBPtab2[code][1]); return CBPtab2[code][0]; } /* return==-1 means go to next picture */ /* the expression "start of slice" is used throughout the normative body of the MPEG specification */ public int start_of_slice(int MBA[], int MBAinc[], int dc_dct_pred[], int PMV[][][]){ next_start_code(); int code = Get_Bits(32); if (codeSLICE_START_CODE_MAX){ // only slice headers are allowed in picture_data Fault_Flag = 10; return -1; } /* decode slice header (may change quantizer_scale) */ int slice_vert_pos_ext = slice_header(); /* decode macroblock address increment */ MBAinc[0] = Get_macroblock_address_increment(); if (Fault_Flag>0) return -1; /* set current location */ /* NOTE: the arithmetic used to derive macroblock_address below is equivalent to ISO/IEC 13818-2 section 6.3.17: Macroblock */ MBA[0] = ((slice_vert_pos_ext<<7) + (code&255) - 1) * mb_width + MBAinc[0] - 1; MBAinc[0] = 1; // first macroblock in slice: not skipped /* reset all DC coefficient and motion vector predictors */ /* ISO/IEC 13818-2 section 7.2.1: DC coefficients in intra blocks */ dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0; /* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */ PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0; PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0; /* successfull: trigger decode macroblocks in slice */ return 1; } public int Get_macroblock_address_increment(){ int code=0, val=0; while ((code = Show_Bits(11))<24){ if (code!=15){ /* if not macroblock_stuffing */ if (code==8) /* if macroblock_escape */ val+= 33; else{ Fault_Flag = 4; return 1; } } Flush_Bits(11); } /* macroblock_address_increment == 1 */ /* ('1' is in the MSB position of the lookahead) */ if (code>=1024) { Flush_Bits(1); return (val + 1); } /* codes 00010 ... 011xx */ if (code>=128) { /* remove leading zeros */ code >>= 6; Flush_Bits(MBAtab1[code][1]); return (val + MBAtab1[code][0]); } /* codes 00000011000 ... 0000111xxxx */ code-= 24; /* remove common base */ Flush_Bits(MBAtab2[code][1]); return (val + MBAtab2[code][0]); } /* ISO/IEC 13818-2 sections 6.2.5.2, 6.3.17.2, and 7.6.3: Motion vectors */ public void motion_vectors(int PMV[][][],int dmvector[], int motion_vertical_field_select[][], int s, int motion_vector_count[], int mv_format[], int h_r_size, int v_r_size, int dmv[], int mvscale[]){ if (motion_vector_count[0]==1) { if (mv_format[0]==MV_FIELD && dmv[0]<1) motion_vertical_field_select[1][s] = motion_vertical_field_select[0][s] = Get_Bits(1); motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0); /* update other motion vector predictors */ PMV[1][s][0] = PMV[0][s][0]; PMV[1][s][1] = PMV[0][s][1]; }else{ motion_vertical_field_select[0][s] = Get_Bits(1); motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0); motion_vertical_field_select[1][s] = Get_Bits(1); motion_vector(PMV[1][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0); } } /* get and decode motion vector and differential motion vector for one prediction */ public void motion_vector(int PMV[], int dmvector[], int h_r_size, int v_r_size, int dmv[], int mvscale[], int full_pel_vector){ int motion_code, motion_residual; /* horizontal component */ /* ISO/IEC 13818-2 Table B-10 */ motion_code = Get_motion_code(); motion_residual = (h_r_size!=0 && motion_code!=0) ? Get_Bits(h_r_size) : 0; decode_motion_vector(PMV[0],h_r_size,motion_code,motion_residual,full_pel_vector); if (dmv[0]>0) dmvector[0] = Get_dmvector(); /* vertical component */ motion_code = Get_motion_code(); motion_residual = (v_r_size!=0 && motion_code!=0) ? Get_Bits(v_r_size) : 0; if (mvscale[0]>0) PMV[1] >>= 1; /* DIV 2 */ decode_motion_vector(PMV[1],v_r_size,motion_code,motion_residual,full_pel_vector); if (mvscale[0]>0) PMV[1] <<= 1; if (dmv[0]>0) dmvector[1] = Get_dmvector(); } /* calculate motion vector component */ /* ISO/IEC 13818-2 section 7.6.3.1: Decoding the motion vectors */ /* Note: the arithmetic here is more elegant than that which is shown in 7.6.3.1. The end results (PMV[][][]) should, however, be the same. */ public void decode_motion_vector(int pred, int r_size, int motion_code, int motion_residual, int full_pel_vector){ int lim, vec; lim = 16<0) ? (pred >> 1) : (pred); if (motion_code>0){ vec+= ((motion_code-1)<=lim) vec-= lim + lim; }else if (motion_code<0){ vec-= ((-motion_code-1)<0) ? (vec<<1) : vec; } /* ISO/IEC 13818-2 section 7.6.3.6: Dual prime additional arithmetic */ public void Dual_Prime_Arithmetic(int DMV[][],int dmvector[], int mvx,int mvy){ if (picture_structure==FRAME_PICTURE){ if (top_field_first>0){ /* vector for prediction of top field from bottom field */ DMV[0][0] = ((mvx +((mvx>0)?1:0))>>1) + dmvector[0]; DMV[0][1] = ((mvy +((mvy>0)?1:0))>>1) + dmvector[1] - 1; /* vector for prediction of bottom field from top field */ DMV[1][0] = ((3*mvx+((mvx>0)?1:0))>>1) + dmvector[0]; DMV[1][1] = ((3*mvy+((mvy>0)?1:0))>>1) + dmvector[1] + 1; }else{ /* vector for prediction of top field from bottom field */ DMV[0][0] = ((3*mvx+((mvx>0)?1:0))>>1) + dmvector[0]; DMV[0][1] = ((3*mvy+((mvy>0)?1:0))>>1) + dmvector[1] - 1; /* vector for prediction of bottom field from top field */ DMV[1][0] = ((mvx +((mvx>0)?1:0))>>1) + dmvector[0]; DMV[1][1] = ((mvy +((mvy>0)?1:0))>>1) + dmvector[1] + 1; } }else{ /* vector for prediction from field of opposite 'parity' */ DMV[0][0] = ((mvx+((mvx>0)?1:0))>>1) + dmvector[0]; DMV[0][1] = ((mvy+((mvy>0)?1:0))>>1) + dmvector[1]; /* correct for vertical field shift */ if (picture_structure==TOP_FIELD) DMV[0][1]--; else DMV[0][1]++; } } /* ISO/IEC 13818-2 section 7.6 */ public void motion_compensation(int MBA[], int macroblock_type[], int motion_type[], int PMV[][][], int motion_vertical_field_select[][], int dmvector[], int dct_type[]){ int bx, by; int comp; /* derive current macroblock position within picture */ /* ISO/IEC 13818-2 section 6.3.1.6 and 6.3.1.7 */ bx = 16*(MBA[0]%mb_width); by = 16*(MBA[0]/mb_width); /* motion compensation */ //if ((macroblock_type[0] & MACROBLOCK_INTRA)<1) //form_predictions(bx, by, macroblock_type, motion_type, PMV, motion_vertical_field_select, dmvector); if (IDCTSseNative.isLibraryLoaded()) { /* copy or add block data into picture */ for (comp=0; comp> 32); block[0] = idct_clip_table[IDCT_CLIP_TABLE_OFFSET + v]; Arrays.fill(block,block[0]); } public void IDCT_reference(short block[]){ int i, j, k, v; long tmp[] = new long[64]; int i8 = 0; for (i = 0; i < 8; i++) { for (j = 0; j < 8; j++) { tmp[i8 + j] = ( ref_dct_matrix_i[0 + j] * block[i8] + ref_dct_matrix_i[8 + j] * block[i8 + 1] + ref_dct_matrix_i[16 + j] * block[i8 + 2] + ref_dct_matrix_i[24 + j] * block[i8 + 3] + ref_dct_matrix_i[32 + j] * block[i8 + 4] + ref_dct_matrix_i[40 + j] * block[i8 + 5] + ref_dct_matrix_i[48 + j] * block[i8 + 6] + ref_dct_matrix_i[56 + j] * block[i8 + 7]); } i8 += 8; } // Transpose operation is integrated into address mapping by switching loop order of i and j for (j = 0; j < 8; j++) { for (i = 0; i < 8; i++) { long partial_product = ( ref_dct_matrix_i[i] * tmp[j] + ref_dct_matrix_i[8 + i] * tmp[8 + j] + ref_dct_matrix_i[16 + i] * tmp[16 + j] + ref_dct_matrix_i[24 + i] * tmp[24 + j] + ref_dct_matrix_i[32 + i] * tmp[32 + j] + ref_dct_matrix_i[40 + i] * tmp[40 + j] + ref_dct_matrix_i[48 + i] * tmp[48 + j] + ref_dct_matrix_i[56 + i] * tmp[56 + j]); v = (int) (partial_product >> 32); block[8 * i + j] = idct_clip_table[IDCT_CLIP_TABLE_OFFSET + v]; } } } **/ /* move/add 8x8-Block from block[comp] to backward_reference_frame */ /* copy reconstructed 8x8 block from block[comp] to current_frame[] ISO/IEC 13818-2 section 7.6.8: Adding prediction and coefficient data This stage also embodies some of the operations implied by: - ISO/IEC 13818-2 section 7.6.7: Combining predictions - ISO/IEC 13818-2 section 6.1.3: Macroblock */ //DM02092003+ changed //DM08022004 081.6 int16 changed to float public void Add_Block(int comp, int bx, int by, int dct_type[], boolean addflag){ int cc, iincr; int rfp; short Block_Ptr[] = block[comp]; /* derive color component index */ /* equivalent to ISO/IEC 13818-2 Table 7-1 */ cc = cc_table[comp]; if (cc==0){ if (picture_structure==FRAME_PICTURE){ //progressive if (dct_type[0]>0){ rfp = current_frame[0] + Coded_Picture_Width*(by+((comp&2)>>1)) + bx + ((comp&1)<<3); iincr = (Coded_Picture_Width<<1) - 8; }else{ rfp = current_frame[0] + Coded_Picture_Width*(by+((comp&2)<<2)) + bx + ((comp&1)<<3); iincr = Coded_Picture_Width - 8; } }else{ rfp = current_frame[0] + (Coded_Picture_Width<<1)*(by+((comp&2)<<2)) + bx + ((comp&1)<<3); iincr = (Coded_Picture_Width<<1) - 8; } }else{ // chrominance // scale coordinates if (chroma_format!=CHROMA444) bx >>= 1; //if (chroma_format==CHROMA420) by >>= 1; // disabled if (picture_structure==FRAME_PICTURE){ //two fields in one pic=std if (dct_type[0]>0 && chroma_format!=CHROMA420){ // field DCT coding rfp = current_frame[cc] + Chroma_Width*(by+((comp&2)>>1)) + bx + (comp&8); iincr = (Chroma_Width<<1) - 8; }else{ // frame DCT coding rfp = current_frame[cc] + Chroma_Width*(by+((comp&2)<<2)) + bx + (comp&8); iincr = Chroma_Width - 8; } }else{ // field picture, one field in one pic rfp = current_frame[cc] + (Chroma_Width<<1)*(by+((comp&2)<<2)) + bx + (comp&8); iincr = (Chroma_Width<<1) - 8; } } iincr += 8; //DM02092003+ int val, luma, pPos, r, g, b; //DM20082004 081.7 int10 changed if (cc == 0) //lumi { for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { pPos = rfp + x + (y * iincr); val = Block_Ptr[x + (y * 8)] + ((picture_coding_type == I_TYPE) ? 128 : 0); val = val < 0 ? 0 : (val > 255 ? 255 : val); pixels[pPos] |= val<<16; //Y } } } else { //chroma cc1 = Cb, cc2=Cr if (chroma_format != CHROMA444) { rfp <<= 1; iincr <<= 1; } for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { pPos = rfp + (x >>(chroma_format == CHROMA444 ? 1 : 0)) + ((y >>(chroma_format != CHROMA420 ? 1 : 0)) * iincr); val = 128 + Block_Ptr[(x >>1) + (8 * (chroma_format != CHROMA420 ? (y >>1) : ((y & 1) == 0 ? ((y >>1) & ~dct_type[0]) : ((y >>1) | dct_type[0]))))]; val = val < 0 ? 0 : (val > 255 ? 255 : val); if (cc == 1) //U pixels[pPos] |= val<<8; else //V pixels[pPos] |= val; if (chroma_format == CHROMA444) x++; } if (chroma_format != CHROMA420) y++; } } } //DM02092003- /* ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes */ public void macroblock_modes(int pmacroblock_type[], int pmotion_type[], int pmotion_vector_count[], int pmv_format[], int pdmv[], int pmvscale[], int pdct_type[]){ int macroblock_type, motion_type=0, motion_vector_count; int mv_format, dmv, mvscale, dct_type; /* get macroblock_type */ macroblock_type = Get_macroblock_type(); if (Fault_Flag>0) return; /* get frame/field motion type */ if ((macroblock_type & (MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD))>0) { if (picture_structure==FRAME_PICTURE) motion_type = (frame_pred_frame_dct>0) ? MC_FRAME : Get_Bits(2); else motion_type = Get_Bits(2); }else if ((macroblock_type & MACROBLOCK_INTRA)>0 && concealment_motion_vectors>0) motion_type = (picture_structure==FRAME_PICTURE) ? MC_FRAME : MC_FIELD; /* derive motion_vector_count, mv_format and dmv, (table 6-17, 6-18) */ if (picture_structure==FRAME_PICTURE){ motion_vector_count = (motion_type==MC_FIELD) ? 2 : 1; mv_format = (motion_type==MC_FRAME) ? MV_FRAME : MV_FIELD; }else{ motion_vector_count = (motion_type==MC_16X8) ? 2 : 1; mv_format = MV_FIELD; } dmv = (motion_type==MC_DMV)?1:0; /* dual prime */ /* field mv predictions in frame pictures have to be scaled ISO/IEC 13818-2 section 7.6.3.1 Decoding the motion vectors */ mvscale = ((mv_format==MV_FIELD) && (picture_structure==FRAME_PICTURE)) ?1:0; /* get dct_type (frame DCT / field DCT) */ dct_type = (picture_structure==FRAME_PICTURE) && (frame_pred_frame_dct<1) && ((macroblock_type & (MACROBLOCK_PATTERN|MACROBLOCK_INTRA))>0 ) ? Get_Bits(1) : 0; /* return values */ pmacroblock_type[0] = macroblock_type; pmotion_type[0] = motion_type; pmotion_vector_count[0] = motion_vector_count; pmv_format[0] = mv_format; pdmv[0] = dmv; pmvscale[0] = mvscale; pdct_type[0] = dct_type; } private int Get_macroblock_type() { int macroblock_type=0; switch (picture_coding_type) { case I_TYPE: macroblock_type = Get_I_macroblock_type(); break; case P_TYPE: macroblock_type = Get_P_macroblock_type(); break; case B_TYPE: macroblock_type = Get_B_macroblock_type(); break; } return macroblock_type; } private int Get_I_macroblock_type() { if (Get_Bits(1) > 0) return 1; if (Get_Bits(1) < 1) Fault_Flag = 2; return 17; } private int Get_P_macroblock_type() { int code; if ((code = Show_Bits(6)) >= 8) { code >>= 3; Flush_Bits(PMBtab0[code][1]); return PMBtab0[code][0]; } if (code == 0) { Fault_Flag = 2; return 0; } Flush_Bits(PMBtab1[code][1]); return PMBtab1[code][0]; } private int Get_B_macroblock_type() { int code; if ((code = Show_Bits(6)) >= 8) { code >>= 2; Flush_Bits(BMBtab0[code][1]); return BMBtab0[code][0]; } if (code == 0) { Fault_Flag = 2; return 0; } Flush_Bits(BMBtab1[code][1]); return BMBtab1[code][0]; } private int Get_motion_code() { int code; if (Get_Bits(1) > 0) return 0; if ((code = Show_Bits(9)) >= 64) { code >>= 6; Flush_Bits(MVtab0[code][1]); return ((Get_Bits(1) > 0) ? -MVtab0[code][0] : MVtab0[code][0]); } if (code >= 24) { code >>= 3; Flush_Bits(MVtab1[code][1]); return ((Get_Bits(1) > 0) ? -MVtab1[code][0] : MVtab1[code][0]); } if ((code -= 12) < 0) { Fault_Flag = 10; return 0; } Flush_Bits(MVtab2[code][1]); return ((Get_Bits(1)>0) ? -MVtab2[code][0] : MVtab2[code][0]); } /** * get differential motion vector (for dual prime prediction) */ private int Get_dmvector() { if (Get_Bits(1) > 0) return ((Get_Bits(1) > 0) ? -1 : 1); else return 0; } /** * performs YUV to RGB conversion */ private int YUVtoRGB(int YUV) { int T = 0xFF; int Y = 0xFF & YUV>>>16; int Cb = 0xFF & YUV>>>8; int Cr = 0xFF & YUV; if (Y == 0) return 0; int R = (int)((float)Y +1.402f * (Cr-128)); int G = (int)((float)Y -0.34414 * (Cb-128) -0.71414 * (Cr-128)); int B = (int)((float)Y +1.722 * (Cb-128)); R = R < 0 ? 0 : (R > 0xFF ? 0xFF : R); G = G < 0 ? 0 : (G > 0xFF ? 0xFF : G); B = B < 0 ? 0 : (B > 0xFF ? 0xFF : B); return (T<<24 | R<<16 | G<<8 | B); } /** * scales source picture to 2nd picture of memoryimagesource * includes YUV to RGB conversion */ private void scale_Picture() { Arrays.fill(pixels2, 0xFF505050); int x_offset = ((aspect_ratio_information == 3 || aspect_ratio_information == 4) && profile_and_level_indication != 0) ? 0 : 64; int scanline = 512; int ny = 288; int nx = x_offset == 0 ? scanline : scanline - x_offset; float Y = 0, X = 0; float Ydecimate = vertical_size / (float)ny; float Xdecimate = horizontal_size / (float)(nx - x_offset); for (int y = 0; Y < vertical_size && y < ny; Y += Ydecimate, y++, X=0) for (int x = x_offset; X < horizontal_size && x < nx; X += Xdecimate, x++) pixels2[x + (y * scanline)] = YUVtoRGB(pixels[(int)X + ((int)Y * Coded_Picture_Width)]); //source.newPixels(); Common.getGuiInterface().updatePreviewPixel(); messageStreamInfo(); /** * expects pixels in YUV format for WSS recognition */ WSS.init(pixels, horizontal_size); } /** * updates info field 1 */ private void messageStreamInfo() { String prog[] = { "i", "p" }; info_1 = horizontal_size + "*" + vertical_size; info_1 += prog[progressive_sequence] + " "; info_1 += aspect_ratio_string[aspect_ratio_information] + " "; info_1 += picture_coding_type_string[picture_coding_type]; info_1 += "(" + temporal_reference + ")"; info_1 += progressive_string[progressive_frame] + " "; info_1 += ", " + video_format_S[video_format] + " "; info_1 += ", " + (profile_and_level_indication==0 ? "MPEG1" : (1 & profile_and_level_indication>>>7) + "|" + prof[7 & profile_and_level_indication>>>4] + "@" + lev[15 & profile_and_level_indication]); info_1 += "(" + Coded_Picture_Width + "*" + Coded_Picture_Height + ") "; info_1 += info_4; } /** * */ public int[] getPixels() { return pixels; } /** * */ public int[] getPreviewPixel() { return pixels2; } /** * */ public void clearPreviewPixel() { info_1 = ""; info_2 = ""; Arrays.fill(pixels2, 0xFF505050); WSS.init(new int[0], 0); Common.getGuiInterface().updatePreviewPixel(); } /** * */ public int getWidth() { return horizontal_size; } /** * */ public int getHeight() { return vertical_size; } /** * */ public int getAspectRatio() { return aspect_ratio_information; } /** * */ public String getInfo_1() { return info_1; } /** * */ public String getInfo_2() { return info_2; } /** * */ public String getWSSInfo() { return WSS.getWSS(); } /** * */ public boolean getPalPlusInfo() { return WSS.isPalPlus(); } /** * */ public String getWSSFormatInfo() { return WSS.getFormatInfo(); } /** * */ public int getErrors() { return (0 | (ERROR1 ? 1 : 0) | (ERROR2 ? 2 : 0) | (ERROR3 ? 4 : 0)); } /** * */ private void repaint() { Common.getGuiInterface().repaintPicturePanel(); } /** * create new smaller cutimage pixel data */ public int[] getCutImage() { int new_height = 126; int new_width = 224; int source_height = 288; int source_width = 512; float Y = 0; float X = 0; float decimate_height = (float)source_height / new_height; float decimate_width = (float)source_width / new_width; int[] cut_image = new int[new_width * new_height]; for (int y = 0; Y < source_height && y < new_height; Y += decimate_height, y++, X = 0) for (int x = 0; X < source_width && x < new_width; X += decimate_width, x++) cut_image[x + (y * new_width)] = pixels2[(int)X + ((int)Y * source_width)]; return cut_image; } /** * returns arrays byteposition offset of 1st successful decoded GOP * interface, entry point to decode picture for preview * * @param1 - ES byte array * @param2 - search direction * @param3 - enable GOPheader alignment * @param4 - simple_fast decode * @return */ public long decodeArray(byte array[], boolean direction, boolean _viewGOP, boolean fast) { return decodeArray(array, 0, direction, _viewGOP, fast); } /** * returns arrays byteposition offset of 1st successful decoded GOP * interface, entry point to decode picture for preview * * @param1 - ES byte array * @param2 - start index position * @param3 - search direction * @param4 - enable GOPheader alignment * @param5 - simple_fast decode * @return */ public long decodeArray(byte array[], int start_position, boolean direction, boolean _viewGOP, boolean fast) { FAST = fast; DIRECTION = direction; ERROR1 = false; ERROR2 = false; ERROR3 = false; buf = array; BufferPos = start_position; BitPos = BufferPos<<3; StartPos = BufferPos; viewGOP = _viewGOP; if (DIRECTION) { StartPos = BufferPos = buf.length - 4; BitPos = BufferPos<<3; } try { while (BufferPos < buf.length && BufferPos >= 0) { ERROR_CODE1 = extern_Get_Hdr(); if ( ERROR_CODE1 == 1 ) { if (picture_coding_type != I_TYPE) { BufferPos += 2048; continue; } InitialDecoder(); Decode_Picture(); scale_Picture(); repaint(); return StartPos; } else if (ERROR_CODE1 == 2 ) { repaint(); return 0; } else BufferPos++; } ERROR2 = true; } catch (ArrayIndexOutOfBoundsException ae) { ERROR1 = true; } catch (Error ee) { ERROR1 = true; } scale_Picture(); repaint(); return 0; } }project-x/src/net/sourceforge/dvb/projectx/video/Preview.java0000600000175000017500000002412710351106660026026 0ustar supermariosupermario/* * @(#)Preview.java - prepare files for previewing * * Copyright (c) 2004-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.video; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.parser.CommonParsing; public class Preview extends Object { private byte preview_data[]; private int loadSizeForward; private int active_collection; private int processed_PID; private int position[]; private String processed_file; private List positionList; private PreviewObject preview_object; private Object[] predefined_Pids; public Preview(int _loadSizeForward) { loadSizeForward = _loadSizeForward; position = new int[2]; positionList = new ArrayList(); processed_PID = -1; processed_file = ""; } public String getProcessedFile() { return processed_file; } public String getProcessedPID() { if (processed_PID < 0) return "---"; return (Integer.toHexString(processed_PID).toUpperCase()); } public long load(long startposition, int size, List previewList, boolean direction, boolean all_gops, boolean fast_decode, Object[] _predefined_Pids, int _active_collection) throws IOException { predefined_Pids = _predefined_Pids; active_collection = _active_collection; preview_data = new byte[size]; int filetype = 0; int read_offset = 0; for (int i = 0; i < previewList.size(); i++) { preview_object = (PreviewObject) previewList.get(i); filetype = preview_object.getType(); if (startposition < preview_object.getEnd()) { XInputFile lXInputFile = (XInputFile) preview_object.getFile(); lXInputFile.randomAccessOpen("r"); lXInputFile.randomAccessSeek(startposition - preview_object.getStart()); lXInputFile.randomAccessRead(preview_data, read_offset, size); lXInputFile.randomAccessClose(); if (preview_object.getEnd() - startposition < size && i < previewList.size() - 1) { i++; int diff = (int)(preview_object.getEnd() - startposition); byte data2[] = new byte[size]; preview_object = (PreviewObject) previewList.get(i); lXInputFile = (XInputFile) preview_object.getFile(); lXInputFile.randomAccessSingleRead(data2, 0); System.arraycopy(data2, 0, preview_data, diff, size - diff); data2 = null; } break; } } preview_data = search(preview_data, startposition, filetype); long newposition = Common.getMpvDecoderClass().decodeArray(preview_data, direction, all_gops, fast_decode); for (int i = positionList.size() - 1; i >= 0; i--) { position = (int[]) positionList.get(i); if (position[1] <= newposition) { startposition += position[0]; i = 0; } } if (positionList.size() == 0) startposition += newposition; for (int i = 0; i < previewList.size(); i++) { preview_object = (PreviewObject)previewList.get(i); if (startposition < preview_object.getEnd()) { processed_file = "" + (i + 1) + "/" + previewList.size() + " - " + preview_object.getFile().getName(); break; } } preview_data = null; //System.gc(); return startposition; } private byte[] search(byte data[], long startposition, int filetype) { ByteArrayOutputStream array = new ByteArrayOutputStream(); positionList.clear(); byte[] hav_chunk = { 0x5B, 0x48, 0x4F, 0x4A, 0x49, 0x4E, 0x20, 0x41 }; //'[HOJIN A' int mark = 0; int offset = 0; int ID = -1; int[] include = new int[predefined_Pids.length]; boolean save = false; for (int i = 0; i < include.length; i++) include[i] = Integer.parseInt(predefined_Pids[i].toString().substring(2), 16); Arrays.sort(include); for (int a = 0; a < data.length - 9; a++) { //mpg es: if (filetype == CommonParsing.ES_MPV_TYPE) return data; //pva: if (filetype == CommonParsing.PVA_TYPE && (0xFF & data[a]) == 0x41 && (0xFF & data[a + 1]) == 0x56 && (0xFF & data[a + 4]) == 0x55) { if (save) array.write(data, mark, a - mark); mark = a; if (data[a + 2] == 1) { ID = 1; mark = ((0x10 & data[a + 5]) != 0) ? a + 12 : a + 8; int currentposition[] = { a,array.size() }; positionList.add(currentposition); save = true; } else save = false; a += 7 + ((0xFF & data[a + 6])<<8 | (0xFF & data[a + 7])); } //humax .vid workaround, skip special data chunk if (filetype == CommonParsing.TS_TYPE && data[a] == 0x7F && data[a + 1] == 0x41 && data[a + 2] == 4 && data[a + 3] == (byte)0xFD) { if (save && mark <= a) array.write(data, mark, a - mark); save = false; a += 1183; mark = a + 1; continue; } //ts: if (filetype == CommonParsing.TS_TYPE && a < data.length - 188 && data[a] == 0x47) { int chunk_offset = 0; if (data[a + 188] != 0x47 && data[a + 188] != 0x7F) { int i = a + 188; int j; int k = a + 189; int l = hav_chunk.length; while (i > a) { j = 0; while (i > a && data[i] != hav_chunk[j]) i--; for ( ; i > a && j < l && i + j < k; j++) if (data[i + j] != hav_chunk[j]) break; /** * found at least one byte of chunk */ if (j > 0) { /** ident of chunk doesnt match completely */ if (j < l && i + j < k) { i--; continue; } /** * re-sorts packet in array */ if (i + 0x200 + (k - i) < data.length) { chunk_offset = 0x200; System.arraycopy(data, i + chunk_offset, data, i, k - i - 1); System.arraycopy(data, a, data, a + chunk_offset, i - a); } break; } } if (chunk_offset == 0) continue; } if (save && mark <= a) array.write(data, mark, a - mark); mark = a; int PID = (0x1F & data[a + 1])<<8 | (0xFF & data[a + 2]); if (include.length > 0 && Arrays.binarySearch(include, PID) < 0) save = false; else if ((ID == PID || ID == -1) && (0xD & data[a + 3]>>>4) == 1) { if ((0x20 & data[a + 3]) != 0) //payload start position, adaption field mark = a + 5 + (0xFF & data[a + 4]); else mark = a + 4; if ((0x40 & data[a + 1]) != 0) //start indicator { if (data[mark] == 0 && data[mark + 1] == 0 && data[mark + 2] == 1 && (0xF0 & data[mark + 3]) == 0xE0) //DM06032004 081.6 int18 fix { ID = PID; mark = mark + 9 + (0xFF & data[mark + 8]); int[] currentposition = { a, array.size() }; positionList.add(currentposition); } else save = false; } if (ID == PID) save = true; } else save = false; a += 187; a += chunk_offset; mark += chunk_offset; } //mpg2-ps if ((filetype == CommonParsing.MPEG2PS_TYPE || filetype == CommonParsing.PES_AV_TYPE) && data[a] == 0 && data[a + 1] == 0 && data[a + 2] == 1) { int PID = 0xFF&data[a+3]; if (PID < 0xB9) continue; if (save) array.write(data,mark,a-mark); mark = a; if (include.length>0 && Arrays.binarySearch(include,PID)<0) save=false; else if ((ID==PID || ID==-1) && (0xF0&PID)==0xE0) { ID=PID; mark = a + 9 + (0xFF&data[a+8]); int currentposition[] = { a,array.size() }; positionList.add(currentposition); save=true; } else save=false; offset=(0xFF&data[a+3])<0xBB?11:0; a += (offset==0) ? (5+((0xFF&data[a+4])<<8 | (0xFF&data[a+5]))) : offset; } //mpg1-ps if (filetype == CommonParsing.MPEG1PS_TYPE && data[a]==0 && data[a+1]==0 && data[a+2]==1) { int PID = 0xFF&data[a+3]; if (PID < 0xB9) continue; if (save) array.write(data,mark,a-mark); mark = a; if (include.length>0 && Arrays.binarySearch(include,PID)<0) save=false; else if ((ID==PID || ID==-1) && (0xF0&PID)==0xE0){ ID=PID; int shift=a+6; skiploop: while(true) { switch (0xC0&data[shift]) { case 0x40: shift+=2; continue skiploop; case 0x80: shift+=3; continue skiploop; case 0xC0: shift++; continue skiploop; case 0: break; } switch (0x30&data[shift]) { case 0x20: shift+=5; break skiploop; case 0x30: shift+=10; break skiploop; case 0x10: shift+=5; break skiploop; case 0: shift++; break skiploop; } } mark = shift; int currentposition[] = { a,array.size() }; positionList.add(currentposition); save=true; } else save = false; offset = (0xFF & data[a + 3]) < 0xBB ? 11 : 0; a += (offset == 0) ? (5 + ((0xFF & data[a + 4])<<8 | (0xFF & data[a + 5]))) : offset; } } processed_PID = ID; return array.toByteArray(); } } project-x/src/net/sourceforge/dvb/projectx/video/PreviewObject.java0000600000175000017500000000335310351106670027154 0ustar supermariosupermario/* * @(#)PreviewObject.java - file object for preview * * Copyright (c) 2004-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.video; import net.sourceforge.dvb.projectx.xinput.XInputFile; //DM24062004 081.7 int05 introduced public class PreviewObject extends Object { private long start, end; private int file_type; private XInputFile xInputFile; private PreviewObject() {} public PreviewObject(long _start, long _end, int _file_type, XInputFile _xInputFile) { start = _start; end = _end; file_type = _file_type; xInputFile = _xInputFile; } public long getStart() { return start; } public long getEnd() { return end; } public int getType() { return file_type; } public XInputFile getFile() { return xInputFile; } } project-x/src/net/sourceforge/dvb/projectx/video/Video.java0000600000175000017500000001136210351106700025443 0ustar supermariosupermario/* * @(#)Video.java - some video constants * * Copyright (c) 2003-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.video; import java.util.StringTokenizer; public class Video extends Object { private final static String[] aspectratio_table_strings = { "res." , "1:1" , "4:3" , "16:9" , "2.21:1" , "0.8055" , "0.8437" , "0.9375" , "0.9815" , "1.0255" , "1.0695" , "1.1250" , "1.1575" , "1.2015" , "res." , "res." }; private final static String[] framerate_table_strings = { "forbidden fps" , "23.976fps" , "24fps" , "25fps" , "29.97fps" , "30fps" , "50fps" , "59.94fps" , "60fps" , "n.def." , "n.def." , "n.def." , "n.def." , "n.def." , "n.def." , "n.def." }; private final static float[] aspectratio_table = { 1.0f, 1.0f, 1.3333f, 1.7778f, 2.21f, 0.8055f, 0.8437f, 0.9375f, 0.9815f, 1.0255f, 1.0695f, 1.125f, 1.1575f, 1.2015f, 1.0f, 1.0f }; private final static int[] framerate_table = { -1, 23976, 24000, 25000, 29970, 30000, 50000, 59940, 60000, -1, -1, -1, -1, -1, -1, -1 }; /** * returns aspectratio as string * * @return */ public static String getAspectRatio(int index) { return aspectratio_table_strings[index]; } /** * returns aspectratio as string * * @return */ public static float getAspectRatioValue(int index) { return aspectratio_table[index]; } /** * returns framerate as string * * @return */ public static int getFrameRate(int index) { return framerate_table[index]; } /** * returns formatted display from sequence header * * @param1 - source array * @return - string */ public static String getVideoformatfromBytes(byte[] gop) { return "" + ((0xFF & gop[4])<<4 | (0xF0 & gop[5])>>>4) + "*" + ((0xF & gop[5])<<8 | (0xFF & gop[6])) + ", " + framerate_table_strings[0xF & gop[7]] + ", " + aspectratio_table_strings[(0xFF & gop[7])>>>4] + ", " + ( ((0xFF & gop[8])<<10 | (0xFF & gop[9])<<2 | (0xC0 & gop[10])>>>6) * 400 ) + "bps, vbv " + ( (0x1F & gop[10])<<5 | (0xF8 & gop[11])>>>3 ); } /** * returns Sequence End Code as array * * @return */ public static byte[] getSequenceEndCode() { byte[] b = { 0, 0, 1, (byte)0xB7 }; return b; } /** * returns Sequence End Code as array * * @return */ public static byte[] getSequenceStartCode() { byte[] b = { 0, 0, 1, (byte)0xB3 }; return b; } /** * returns std Sequence Display Ext as array * * @return */ public static byte[] setSequenceDisplayExtension( String str, String[] videobasics) { byte[] b = { 0, 0, 1, (byte)0xB5, 0x2B, 2, 2, 2, 0, 0, 0, 0 }; setSequenceDisplayExtension( b, 0, str, videobasics); return b; } /** * returns std Sequence Display Ext as array * * @return */ public static void setSequenceDisplayExtension( byte[] b, int offs, String str, String[] videobasics) throws ArrayIndexOutOfBoundsException { int[] size = getHVSize( str, videobasics); offs += (1 & b[offs + 4]) != 0 ? 8 : 5; b[offs] = (byte) (0xFF & size[0]>>>6); b[offs + 1] = (byte) (0xFC & size[0]<<2); b[offs + 1] |= 2; b[offs + 1] |= (byte) (1 & size[0]>>>13); b[offs + 2] = (byte) (0xFF & size[1]>>>5); b[offs + 3] = (byte) (0xF8 & size[1]<<3); } private static int[] getHVSize(String str, String[] videobasics) { StringTokenizer st = new StringTokenizer(str, "*"); int[] tokens = { 720, 576 }; for (int i = 0, val; i < 2; i++) { try { val = Integer.parseInt(videobasics[i].trim()); tokens[i] = val; } catch (Exception e) { } } for (int i = 0, val; st.hasMoreTokens() && i < 2; i++) { try { val = Integer.parseInt(st.nextElement().toString().trim()); tokens[i] = val; } catch (Exception e) { } } return tokens; } }project-x/src/net/sourceforge/dvb/projectx/video/WSS.java0000600000175000017500000002325710404712540025063 0ustar supermariosupermario/* * @(#)WSS.java - mini info about WSS * * Copyright (c) 2004-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.video; import net.sourceforge.dvb.projectx.common.Resource; import java.util.Arrays; //DM30072004 introduced with 081.7 int07 public final class WSS extends Object { private static boolean isPalplus = false; private static int pixels[] = new int[267]; private static int a; private static String str; private static String format; private static String start = Resource.getString("wss.start"); public WSS() { init(new int[0], 0); } public static void init(int source_pixels[], int width) { str = null; format = ""; if (source_pixels.length < 200) return; scale(source_pixels, width); } public static String getWSS() { return str; } public static boolean isPalPlus() { return isPalplus; } public static String getFormatInfo() { return format; } private static void scale(int source_pixels[], int width) { Arrays.fill(pixels, 0); int nx = 267; float fx = 0; float Xdecimate = width / (float)(nx); for (int x = 0; fx < width && x < nx; fx += Xdecimate, x++) pixels[x] = 0xFF & source_pixels[(int)fx]>>>16; a = 0; /** * WSS of PAL 625-lines */ handlepixels("line 0 (23)"); // read out if (str == null) { fx = 0; for (int x = 0; fx < width && x < nx; fx += Xdecimate, x++) pixels[x] = 0xFF & source_pixels[width + (int)fx]>>>16; a = 0; handlepixels("line 1 (335)"); // read out } } private static void handlepixels(String _str) { isPalplus = false; format = ""; str = "WSS status @ " + _str; str += ":

"; if (getRunIn()) { str += Resource.getString("wss.run_in") + " @ " + a + "

"; a += 29; if (getStartCode()) { str += Resource.getString("wss.startcode") + " @ " + a + "

"; a += 24; str += Resource.getString("wss.group_1") + " " + start + " @ " + a + " :" + "

"; str += " * " + getGroup1() + "

"; a += 24; str += Resource.getString("wss.group_2") + " " + start + " @ " + a + " :" + "

"; String[] group = getGroup2(); for (int d = 0; d < group.length; d++) str += " * " + group[d] + "

"; a += 24; str += Resource.getString("wss.group_3") + " " + start + " @ " + a + " :" + "

"; group = getGroup3(); for (int d = 0; d < group.length; d++) str += " * " + group[d] + "

"; a += 18; str += Resource.getString("wss.group_4") + " " + start + " @ " + a + " :" + "

"; group = getGroup4(); for (int d = 0; d < group.length; d++) str += " * " + group[d] + "

"; } else str += Resource.getString("wss.no_startcode"); } else { str += Resource.getString("wss.no_run_in"); str = null; } a=0; } private static boolean getRunIn() { for (; a < 30; a++) if ( pixels[a] > 120 && pixels[a + 2] >= 120 && pixels[a + 5] < 120 && pixels[a + 8] >= 120 && pixels[a + 11] < 120 && pixels[a + 14] >= 120 && pixels[a + 17] < 120 && pixels[a + 20] >= 120 && pixels[a + 23] < 120 && pixels[a + 26] >= 120 ) return true; return false; } private static boolean getStartCode() { if ( pixels[a] < 120 && pixels[a + 3] >= 120 && pixels[a + 7] < 120 && pixels[a + 10] >= 120 && pixels[a + 14] < 120 && pixels[a + 19] >= 120 ) return true; return false; } private static String getGroup1() { int b1=0; for (int c=0; c < 8; c++) b1 |= pixels[a + (3 * c)] < 120 ? 0 : (1<<(7 - c)); switch (b1) { case 0x56: // 0001 Biphase 01010110 format = "[4:3 full]"; return (" " + Resource.getString("wss.group_1.0001")); case 0x95: // 1000 Biphase 10010101 format = "[14:9 LB center]"; return (" " + Resource.getString("wss.group_1.1000")); case 0x65: // 0100 Biphase 01100101 format = "[14:9 LB top]"; return (" " + Resource.getString("wss.group_1.0100")); case 0xA6: // 1101 Biphase 10100110 format = "[16:9 LB center]"; return (" " + Resource.getString("wss.group_1.1101")); case 0x59: // 0010 Biphase 01011001 format = "[16:9 LB top]"; return (" " + Resource.getString("wss.group_1.0010")); case 0x6A: // 0111 Biphase 01101010 format = "[14:9 full]"; return (" " + Resource.getString("wss.group_1.0111")); case 0xA9: // 1110 Biphase 10101001 format = "[16:9 full]"; return (" " + Resource.getString("wss.group_1.1110")); default: return (" " + Resource.getString("wss.group_1.error")); } } private static String[] getGroup2() { int b1=0; for (int c=0; c < 8; c++) b1 |= pixels[a + (3 * c)] < 120 ? 0 : (1<<(7 - c)); String[] group2 = new String[4]; switch (b1>>>6) { case 1: // 0 Biphase 01 group2[0]= " " + Resource.getString("wss.group_2.0.01"); break; case 2: // 1 Biphase 10 group2[0]= " " + Resource.getString("wss.group_2.0.10"); break; default: group2[0]= " " + Resource.getString("wss.group_2.0.00"); } switch (0x3 & (b1>>>4)) { case 1: // 0 Biphase 01 group2[1]= " " + Resource.getString("wss.group_2.1.01"); break; case 2: // 1 Biphase 10 group2[1]= " " + Resource.getString("wss.group_2.1.10"); break; default: group2[1]= " " + Resource.getString("wss.group_2.1.00"); } switch (0x3 & (b1>>>2)) { case 1: // 0 Biphase 01 group2[2]= " " + Resource.getString("wss.group_2.2.01"); break; case 2: // 1 Biphase 10 group2[2]= " " + Resource.getString("wss.group_2.2.10"); isPalplus = true; break; default: group2[2]= " " + Resource.getString("wss.group_2.2.00"); } switch (0x3 & b1) { case 1: // 0 Biphase 01 group2[3]= " " + Resource.getString("wss.group_2.3.01"); break; case 2: // 1 Biphase 10 group2[3]= " " + Resource.getString("wss.group_2.3.10"); break; default: group2[3]= " " + Resource.getString("wss.group_2.3.00"); } return group2; } private static String[] getGroup3() { int b1 = 0; for (int c=0; c < 6; c++) b1 |= pixels[a + (3 * c)] < 120 ? 0 : (1<<(5 - c)); String[] group2 = new String[2]; switch (0x3 & (b1>>>4)) { case 1: // 0 Biphase 01 group2[0]= " " + Resource.getString("wss.group_3.0.01"); break; case 2: // 1 Biphase 10 group2[0]= " " + Resource.getString("wss.group_3.0.10"); format += "[UT]"; break; default: group2[0]= " " + Resource.getString("wss.group_3.0.00"); } switch (0xF & b1) { case 5: // 00 Biphase 0101 group2[1]= " " + Resource.getString("wss.group_3.1.00"); break; case 6: // 01 Biphase 0110 group2[1]= " " + Resource.getString("wss.group_3.1.01"); break; case 9: // 10 Biphase 1001 group2[1]= " " + Resource.getString("wss.group_3.1.10"); break; case 0xA: // 11 Biphase 1010 group2[1]= " " + Resource.getString("wss.group_3.1.11"); break; default: group2[1]= " " + Resource.getString("wss.group_3.1.err"); } return group2; } private static String[] getGroup4() { int b1 = 0; for (int c = 0; c < 6; c++) b1 |= pixels[a + (3 * c)] < 120 ? 0 : (1<<(5 - c)); String[] group2 = new String[3]; switch (3 & (b1>>>4)) { case 1: // 0 Biphase 01 group2[0]= " " + Resource.getString("wss.group_4.0.01"); break; case 2: // 1 Biphase 10 group2[0]= " " + Resource.getString("wss.group_4.0.10"); break; default: group2[0]= " " + Resource.getString("wss.group_4.0.00"); } switch (3 & (b1>>>2)) { case 1: // 0 Biphase 01 group2[1]= " " + Resource.getString("wss.group_4.1.01"); break; case 2: // 1 Biphase 10 group2[1]= " " + Resource.getString("wss.group_4.1.10"); break; default: group2[1]= " " + Resource.getString("wss.group_4.1.00"); } switch (3 & b1) { case 1: // 0 Biphase 01 group2[2]= " " + Resource.getString("wss.group_4.2.01"); break; case 2: // 1 Biphase 10 group2[2]= " " + Resource.getString("wss.group_4.2.10"); break; default: group2[2]= " " + Resource.getString("wss.group_4.2.00"); } return group2; } } /*** WSS takt = 200ns 1 bit = 3*200ns = 600ns 1NRZ bit = 2*3*200 = 1200ns 864 bit auf 64000ns PAL @ 13.5MHz 74.074 (864*15.625khz) 320 bit auf 64000ns @ 5MHz 200ns = 74.074 ns / bit = 702 pix auf 52000ns = 720 pix auf 53333ns = 266.666 bits bei 200ns/b 142 + 20 858 bit auf 63560ns NTSC @ 13.5MHz **/project-x/src/net/sourceforge/dvb/projectx/xinput/0000700000175000017500000000000010745203152023754 5ustar supermariosupermarioproject-x/src/net/sourceforge/dvb/projectx/xinput/DirType.java0000600000175000017500000000524310351106740026203 0ustar supermariosupermario/* * @(#)DirType.java * * Copyright (c) 2004-2005 by roehrist, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.xinput; import java.util.ArrayList; import java.util.Collection; public class DirType { /** * Stores all instances of DirType */ private final static Collection dirTypes = new ArrayList(10); /** * Directory in a normal filesystem */ public final static DirType FILE_DIR = new DirType(0, "FILE_DIR", net.sourceforge.dvb.projectx.xinput.file.XInputDirectoryImpl.class); /** * Directory on a ftp server */ public final static DirType FTP_DIR = new DirType(1, "FTP_DIR", net.sourceforge.dvb.projectx.xinput.ftp.XInputDirectoryImpl.class); /** * Directory on a harddisk of a topfield receiver in raw format */ public final static DirType RAW_DIR = new DirType(2, "RAW_DIR", net.sourceforge.dvb.projectx.xinput.topfield_raw.XInputDirectoryImpl.class); /** * Default DirType */ public final static DirType DEFAULT = FILE_DIR; private int type; private String name; private Class implementation; private DirType(int aType, String aName, Class aImplementation) { type = aType; name = aName; implementation = aImplementation; dirTypes.add(this); } /** * Get type name * * @return type name */ public String getName() { return name; } /** * Get type value * * @return type value */ public int getType() { return type; } /** * @return Returns the implementation. */ public Class getImplementation() { return implementation; } /** * @return Returns the fileTypes. */ public static Collection getDirTypes() { return dirTypes; } public String toString() { return getName(); } }project-x/src/net/sourceforge/dvb/projectx/xinput/FileType.java0000600000175000017500000000517110351106746026352 0ustar supermariosupermario/* * @(#)FileType.java * * Copyright (c) 2004-2005 by roehrist, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.xinput; import java.util.ArrayList; import java.util.Collection; public class FileType { /** * Stores all instances of FileType */ private final static Collection fileTypes = new ArrayList(10); /** * File in a normal filesystem */ public final static FileType FILE = new FileType(0, "FILE", net.sourceforge.dvb.projectx.xinput.file.XInputFileImpl.class); /** * File on a ftp server */ public final static FileType FTP = new FileType(1, "FTP", net.sourceforge.dvb.projectx.xinput.ftp.XInputFileImpl.class); /** * File on a harddisk of a topfield receiver in raw format */ public final static FileType RAW = new FileType(2, "RAW", net.sourceforge.dvb.projectx.xinput.topfield_raw.XInputFileImpl.class); /** * Default FileType */ public final static FileType DEFAULT = FILE; private int type; private String name; private Class implementation; private FileType(int aType, String aName, Class aImplementation) { type = aType; name = aName; implementation = aImplementation; fileTypes.add(this); } /** * Get type name * * @return type name */ public String getName() { return name; } /** * Get type value * * @return type value */ public int getType() { return type; } /** * @return Returns the implementation. */ public Class getImplementation() { return implementation; } /** * @return Returns the fileTypes. */ public static Collection getFileTypes() { return fileTypes; } public String toString() { return getName(); } }project-x/src/net/sourceforge/dvb/projectx/xinput/StreamInfo.java0000600000175000017500000002246110351106760026675 0ustar supermariosupermario/* * @(#)StreamInfo * * Copyright (c) 2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.xinput; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Keys; /** * */ public class StreamInfo extends Object { private Object[] videostreams; private Object[] audiostreams; private Object[] teletextstreams; private Object[] subpicturestreams; private String file_name; private String file_date; private String file_size; private String file_type; private String file_location; private String file_playtime; private String file_source; private String additionals; private int streamtype; private Object[] pids; private byte[] videoheader; private String line_separator = System.getProperty("line.separator"); /** * */ public StreamInfo() { setStreamInfo("", "", "", "", "", "", ""); } /** * */ public StreamInfo(String _file_source, String _file_type, String _file_name, String _file_location, String _file_date, String _file_size, String _file_playtime) { setStreamInfo(_file_source, _file_type, _file_name, _file_location, _file_date, _file_size, _file_playtime); } /** * */ public StreamInfo(String _file_source, String _file_type, String _file_name, String _file_location, String _file_date, String _file_size, String _file_playtime, Object[] _videostreams, Object[] _audiostreams, Object[] _teletextstreams, Object[] _subpicturestreams) { setStreamInfo(_file_source, _file_type, _file_name, _file_location, _file_date, _file_size, _file_playtime, _videostreams, _audiostreams, _teletextstreams, _subpicturestreams); } /** * */ public StreamInfo(int _streamtype, String _file_source, String _file_type, String _file_name, String _file_location, String _file_date, String _file_size, String _file_playtime, Object[] _videostreams, Object[] _audiostreams, Object[] _teletextstreams, Object[] _subpicturestreams, Object[] _pids, byte[] _videoheader) { streamtype = _streamtype; pids = _pids; videoheader = _videoheader; setStreamInfo(_file_source, _file_type, _file_name, _file_location, _file_date, _file_size, _file_playtime, _videostreams, _audiostreams, _teletextstreams, _subpicturestreams); } /** * */ public void setStreamInfo(String _file_source, String _file_type, String _file_name, String _file_location, String _file_date, String _file_size, String _file_playtime) { setStreamInfo(_file_source, _file_type, _file_name, _file_location, _file_date, _file_size, _file_playtime, null, null, null, null); } /** * */ public void setStreamInfo(String _file_source, String _file_type, String _file_name, String _file_location, String _file_date, String _file_size, String _file_playtime, Object[] _videostreams, Object[] _audiostreams, Object[] _teletextstreams, Object[] _subpicturestreams) { videostreams = _videostreams; audiostreams = _audiostreams; teletextstreams = _teletextstreams; subpicturestreams = _subpicturestreams; file_name = _file_name; file_date = _file_date; file_size = _file_size; file_type = _file_type; file_location = _file_location; file_playtime = _file_playtime; file_source = _file_source; } /** * */ public String getFileName() { return file_name; } /** * */ public String getFileSourceBase() { return file_source; } /** * */ public String getFileSource() { return "[" + getFileSourceBase() + "]"; } /** * */ public String getFileSourceAndName() { return getFileSource() + " - " + getFileName(); } /** * */ public String getFileDate() { return file_date; } /** * */ public String getFileSize() { return file_size; } /** * */ public String getFileType() { return file_type; } /** * */ public String getFileLocation() { return file_location; } /** * */ public String getPlaytime() { return file_playtime; } /** * */ public Object[] getVideoStreams() { return videostreams; } /** * */ public Object[] getAudioStreams() { return audiostreams; } /** * */ public Object[] getTeletextStreams() { return teletextstreams; } /** * */ public Object[] getSubpictureStreams() { return subpicturestreams; } /** * */ public String getVideo() { return getString(getVideoStreams()); } /** * */ public String getAudio() { return getString(getAudioStreams()); } /** * */ public String getTeletext() { return getString(getTeletextStreams()); } /** * */ public String getSubpicture() { return getString(getSubpictureStreams()); } /** * */ public String getAdditionals() { return additionals; } /** * */ private String getString(Object[] obj) { String str = ""; if (obj == null || obj.length == 0) return "n/a"; str = obj[0].toString(); for (int i = 1; i < obj.length; i++) str += line_separator + obj[i].toString(); return str; } /** * */ public String getFullInfo() { String str = ""; str += Resource.getString("ScanInfo.Location") + line_separator; str += getFileSource() + " @ " + getFileLocation() + line_separator; str += Resource.getString("ScanInfo.Name") + line_separator; str += getFileName() + line_separator; str += Resource.getString("ScanInfo.Size") + line_separator; str += getFileSize() + line_separator; str += Resource.getString("ScanInfo.Date") + line_separator; str += getFileDate() + line_separator; str += line_separator; str += Resource.getString("ScanInfo.Type") + line_separator; str += getFileType() + line_separator; str += Resource.getString("ScanInfo.Video") + line_separator; str += getVideo() + line_separator; str += Resource.getString("ScanInfo.Audio") + line_separator; str += getAudio() + line_separator; str += Resource.getString("ScanInfo.Teletext") + line_separator; str += getTeletext() + line_separator; str += Resource.getString("ScanInfo.Subpicture") + line_separator; str += getSubpicture() + line_separator; str += Resource.getString("ScanInfo.Playtime") + line_separator; str += getPlaytime(); return str; } /** * */ public void setStreamType(int _streamtype) { streamtype = _streamtype; file_type = Keys.ITEMS_FileTypes[streamtype].toString(); } /** * */ public void setStreamType(int _streamtype, String str) { streamtype = _streamtype; file_type = Keys.ITEMS_FileTypes[streamtype].toString() + str; } /** * */ public int getStreamType() { return streamtype; } /** * */ public void setPIDs(Object[] _pids) { pids = _pids; } /** * */ public int[] getPIDs() { int len = pids == null ? 0 : pids.length; int[] array = new int[len]; for (int i = 0; i < len; i++) array[i] = Integer.parseInt(pids[i].toString()); return array; } /** * */ public int[] getMediaPIDs() { int len = pids == null || pids.length == 0 ? 0 : pids.length - 1; int[] array = new int[len]; for (int i = 0; i < len; i++) array[i] = Integer.parseInt(pids[1 + i].toString()); return array; } /** * */ public void setVideoHeader(byte[] _videoheader) { if (_videoheader == null) videoheader = null; else { videoheader = new byte[12]; System.arraycopy(_videoheader, 0, videoheader, 0, _videoheader.length); } } /** * */ public byte[] getVideoHeader() { return videoheader; } /** * */ private Object[] copyContent(Object[] _obj) { if (_obj == null) return null; Object[] obj = new Object[_obj.length]; System.arraycopy(_obj, 0, obj, 0, obj.length); return obj; } /** * */ private byte[] copyContent(byte[] _array) { if (_array == null) return null; byte[] array = new byte[_array.length]; System.arraycopy(_array, 0, array, 0, array.length); return array; } /** * */ public StreamInfo getNewInstance() { return new StreamInfo(streamtype, file_source, file_type, file_name, file_location, file_date, file_size, file_playtime, copyContent(videostreams), copyContent(audiostreams), copyContent(teletextstreams), copyContent(subpicturestreams), copyContent(pids), copyContent(videoheader)); } } project-x/src/net/sourceforge/dvb/projectx/xinput/XInputDirectory.java0000600000175000017500000002054510351106770027744 0ustar supermariosupermario/* * @(#)XInputDirectory * * Copyright (c) 2004-2005 by roehrist, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.xinput; import java.util.Iterator; import net.sourceforge.dvb.projectx.common.Common; public class XInputDirectory implements XInputDirectoryIF { // Implementation class private XInputDirectoryIF impl = null; private boolean debug = false; private Object constructorParameter = null; /** * Private Constructor, don't use! */ private XInputDirectory() { throw new UnsupportedOperationException(); } /** */ public XInputDirectory(Object aVO) { if (debug) System.out.println("Enter XInputDirectory(Object '" + aVO + "')"); Class[] parameterTypes = { aVO.getClass() }; Object[] parameterValues = { aVO }; retrieveImplementation(parameterTypes, parameterValues); constructorParameter = aVO; if (debug) System.out.println("Leave XInputDirectory(Object '" + aVO + "')"); } public XInputDirectory getNewInstance() { if (debug) System.out.println("Enter XInputDirectory.getNewInstance()"); XInputDirectory xid = new XInputDirectory(constructorParameter); if (debug) System.out.println("Leave XInputDirectory.getNewInstance() returning " + xid); return xid; } /** */ private void retrieveImplementation(Class[] parameterTypes, Object[] parameterValues) { if (debug) System.out .println("Enter XInputDirectory.retrieveImplementation(Class[] parameterTypes, Object[] parameterValues)"); DirType dirType = null; for (Iterator dirTypes = DirType.getDirTypes().iterator(); dirTypes.hasNext();) { dirType = (DirType) dirTypes.next(); if (dirType.equals(DirType.DEFAULT)) continue; try { if (debug) System.out.println("Try DirType '" + dirType.getName() + "'"); impl = (XInputDirectoryIF) dirType.getImplementation().getConstructor(parameterTypes).newInstance( parameterValues); /** * simply disable access, if commons-net is missing */ /** if (dirType.getName().equals("FTP_DIR") && !Common.canAccessFtp()) impl = null; **/ if (debug) System.out.println("Use DirType '" + dirType.getName() + "' for file '" + impl.toString() + "'"); if (debug) System.out.println("Leave XInputDirectory.retrieveImplementation(Class[] parameterTypes, Object[] parameterValues)"); return; } catch (Exception e) { // Failed, try next type impl = null; } } try { dirType = DirType.DEFAULT; if (debug) System.out.println("Try default DirType '" + dirType.getName() + "'"); impl = (XInputDirectoryIF) dirType.getImplementation().getConstructor(parameterTypes) .newInstance(parameterValues); if (debug) System.out.println("Use default DirType '" + dirType.getName() + "' for file '" + impl.toString() + "'"); if (debug) System.out .println("Leave XInputDirectory.retrieveImplementation(Class[] parameterTypes, Object[] parameterValues)"); return; } catch (Exception e) { // Failed, no type left, so this is final failure impl = null; if (debug) System.out.println("No matching DirType found or directory doesn't exist"); if (debug) System.out .println("XInputDirectory.Leave retrieveImplementation(Class[] parameterTypes, Object[] parameterValues)"); throw new IllegalArgumentException("No matching DirType found or directory doesn't exist"); } } /* * (non-Javadoc) * * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object aObj) { if (debug) System.out.println("Enter XInputDirectory.equals(Object '" + aObj + "')"); if (!(aObj instanceof XInputDirectory)) { if (debug) System.out.println("Leave XInputDirectory.equals(Object '" + aObj + "') returning false"); return false; } XInputDirectory other = (XInputDirectory) aObj; if (other.getDirType().equals(getDirType()) && other.toString().equals(toString())) { if (debug) System.out.println("Leave XInputDirectory.equals(Object '" + aObj + "') returning true"); return true; } else { if (debug) System.out.println("Leave XInputDirectory.equals(Object '" + aObj + "') returning false"); return false; } } /** * @return */ public String getDirectory() { if (debug) System.out.println("Enter XInputDirectory.getDirectory()"); String s = impl.getDirectory(); if (debug) System.out.println("Leave XInputDirectory.getDirectory() returning " + s); return s; } /** * @return */ public DirType getDirType() { if (debug) System.out.println("Enter XInputDirectory.getDirType()"); DirType dt = impl.getDirType(); if (debug) System.out.println("Leave XInputDirectory.getDirType() returning " + dt); return dt; } /** * @return */ public XInputFile[] getFiles() { if (debug) System.out.println("Enter XInputDirectory.getFiles()"); XInputFile[] xInputFiles = impl.getFiles(); if (debug) System.out.println("Leave XInputDirectory.getFiles() returning " + xInputFiles.length + " xInputFiles"); return xInputFiles; } /** * @return */ public String getLog() { if (debug) System.out.println("Enter XInputDirectory.getLog()"); String s = impl.getLog(); if (debug) System.out.println("Leave XInputDirectory.getLog() returning " + s); return s; } /** * @return */ public String getPassword() { if (debug) System.out.println("Enter XInputDirectory.getPassword()"); String s = impl.getPassword(); if (debug) System.out.println("Leave XInputDirectory.getPassword() returning " + s); return s; } /** * @return */ public String getServer() { if (debug) System.out.println("Enter XInputDirectory.getServer()"); String s = impl.getServer(); if (debug) System.out.println("Leave XInputDirectory.getServer() returning " + s); return s; } /** * @return */ public String getPort() { if (debug) System.out.println("Enter XInputDirectory.getPort()"); String s = impl.getPort(); if (debug) System.out.println("Leave XInputDirectory.getPort() returning " + s); return s; } /** * @return */ public String getTestMsg() { if (debug) System.out.println("Enter XInputDirectory.getTestMsg()"); String s = impl.getTestMsg(); if (debug) System.out.println("Leave XInputDirectory.getTestMsg() returning " + s); return s; } /** * @return */ public String getUser() { if (debug) System.out.println("Enter XInputDirectory.getUser()"); String s = impl.getUser(); if (debug) System.out.println("Leave XInputDirectory.getUser() returning " + s); return s; } /* * (non-Javadoc) * * @see java.lang.Object#hashCode() */ public int hashCode() { if (debug) System.out.println("Enter XInputDirectory.hashCode()"); int i = impl.hashCode(); if (debug) System.out.println("Leave XInputDirectory.hashCode() returning " + i); return i; } /** * @return */ public boolean test() { if (debug) System.out.println("Enter XInputDirectory.getDirectory()"); boolean b = impl.test(); if (debug) System.out.println("Leave XInputDirectory.getDirectory() returning " + (new Boolean(b))); return b; } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ public String toString() { if (debug) System.out.println("Enter XInputDirectory.toString()"); String s = impl.toString(); if (debug) System.out.println("Leave XInputDirectory.toString() returning " + s); return s; } }project-x/src/net/sourceforge/dvb/projectx/xinput/XInputDirectoryIF.java0000600000175000017500000000573210351107000030147 0ustar supermariosupermario/* * @(#)XInputDirectoryIF.java * * Copyright (c) 2004-2005 by roehrist, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ /* * Created on 26.08.2004 * */ package net.sourceforge.dvb.projectx.xinput; /** * @author Stefan * */ public interface XInputDirectoryIF { /** * Get String representation of the object. * * @return String representation of the object */ public String toString(); /** * Get path of directory * * @return Path of directory */ public String getDirectory(); /** * Get password for the ftp server * * @return Password for the ftp server * @throws IllegalStateException * If file type of object is not FileType.FTP_DIR */ public String getPassword(); /** * Get name or ip address of the ftp server * * @return Name or ip address of the ftp server * @throws IllegalStateException * If file type of object is not FileType.FTP_DIR */ public String getServer(); /** * Get port of the ftp server * * @return port of the ftp server * @throws IllegalStateException * If file type of object is not FileType.FTP_DIR */ public String getPort(); /** * Get user for the ftp server * * @return User for the ftp server * @throws IllegalStateException * If file type of object is not FileType.FTP_DIR */ public String getUser(); /** * Get log of communication with ftp server. * * @return Log of communication with ftp server * @throws IllegalStateException * If file type of object is not FileType.FTP_DIR */ public String getLog(); /** * Get files in the directory. * * @return files in the directory */ public XInputFile[] getFiles(); /** * Test if directory data is valid. * * @return Test successful or not */ public boolean test(); /** * Get result message after test(). * * @return result message after test() */ public String getTestMsg(); /** * @return Type of XInputDirectory */ public DirType getDirType(); }project-x/src/net/sourceforge/dvb/projectx/xinput/XInputFile.java0000600000175000017500000004071110355317030026651 0ustar supermariosupermario/* * @(#)XInputFile.java * * Copyright (c) 2004-2005 by roehrist, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.xinput; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.util.Iterator; import net.sourceforge.dvb.projectx.xinput.StreamInfo; import net.sourceforge.dvb.projectx.common.Common; public class XInputFile implements XInputFileIF { // Implementation class private XInputFileIF impl = null; private boolean debug = false; private Object constructorParameter = null; /** * Private Constructor, don't use! */ private XInputFile() { throw new UnsupportedOperationException(); } /** */ public XInputFile(Object aVO) { if (debug) System.out.println("Enter XInputFile(Object '" + aVO + "')"); Class[] parameterTypes = { aVO.getClass() }; Object[] parameterValues = { aVO }; retrieveImplementation(parameterTypes, parameterValues); constructorParameter = aVO; if (impl != null) impl.setConstructorParameter(aVO); if (debug) System.out.println("Leave XInputFile(Object '" + aVO + "')"); } public XInputFile getNewInstance() { if (debug) System.out.println("Enter XInputFile.getNewInstance()"); if (impl != null) constructorParameter = impl.getConstructorParameter(); XInputFile xif = new XInputFile(constructorParameter); if (xif.getImpl() == null) return null; /** * copy already parsed streaminfo */ if (impl.getStreamInfo() != null) xif.setStreamInfo(impl.getStreamInfo().getNewInstance()); if (debug) System.out.println("Leave XInputFile.getNewInstance() returning " + xif); return xif; } /** */ private void retrieveImplementation(Class[] parameterTypes, Object[] parameterValues) { if (debug) System.out.println("Enter XInputFile.retrieveImplementation(Class[] parameterTypes, Object[] parameterValues)"); FileType fileType = null; for (Iterator fileTypes = FileType.getFileTypes().iterator(); fileTypes.hasNext(); ) { fileType = (FileType) fileTypes.next(); if (fileType.equals(FileType.DEFAULT)) continue; try { if (debug) System.out.println("Try FileType '" + fileType.getName() + "'"); impl = (XInputFileIF) fileType.getImplementation().getConstructor(parameterTypes).newInstance(parameterValues); /** * simply disable access, if commons-net is missing */ /** if (fileType.getName().equals("FTP") && !Common.canAccessFtp()) impl = null; **/ if (debug) System.out.println("Use FileType '" + fileType.getName() + "' for file '" + impl.toString() + "'"); if (debug) System.out.println("Leave XInputFile.retrieveImplementation(Class[] parameterTypes, Object[] parameterValues"); return; } catch (Exception e) { // Failed, try next type impl = null; } } try { fileType = FileType.DEFAULT; if (debug) System.out.println("Try default FileType '" + fileType.getName() + "'"); impl = (XInputFileIF) fileType.getImplementation().getConstructor(parameterTypes).newInstance(parameterValues); if (debug) System.out.println("Use default FileType '" + fileType.getName() + "' for file '" + impl.toString() + "'"); if (debug) System.out.println("Leave XInputFile.retrieveImplementation(Class[] parameterTypes, Object[] parameterValues)"); return; } catch (Exception e) { // Failed, no type left, so this is final failure impl = null; if (debug) System.out.println("No matching FileType found or file doesn't exist"); if (debug) System.out.println("Leave XInputFile.retrieveImplementation(Class[] parameterTypes, Object[] parameterValues)"); //throw new IllegalArgumentException("No matching FileType found or file doesn't exist"); Common.setErrorMessage("No matching FileType found or file doesn't exist: '" + parameterValues[0] + "'"); Common.setExceptionMessage(e); } } public void setConstructorParameter(Object obj) { if (debug) System.out.println("Enter XInputFile.setConstructorParameter(Object obj)" + "'" + obj + "'"); impl.setConstructorParameter(obj); if (debug) System.out.println("Leave XInputFile.setConstructorParameter(Object obj)"); } public Object getConstructorParameter() { if (debug) System.out.println("Enter XInputFile.getConstructorParameter()"); Object obj = impl.getConstructorParameter(); if (debug) System.out.println("Leave XInputFile.getConstructorParameter()" + "'" + obj + "'"); return obj; } /** * @return */ public boolean exists() { if (debug) System.out.println("Enter XInputFile.exists()"); boolean b = impl.exists(); if (debug) System.out.println("Leave XInputFile.exists() returning " + (new Boolean(b))); return b; } /** * @return @throws * FileNotFoundException * @throws MalformedURLException * @throws IOException */ public InputStream getInputStream() throws FileNotFoundException, MalformedURLException, IOException { if (debug) System.out.println("Enter XInputFile.getInputStream()"); InputStream is = null; try { is = impl.getInputStream(); } catch (IOException e) { if (debug) System.out.println(e.getLocalizedMessage()); if (debug) e.printStackTrace(); throw e; } if (debug) System.out.println("Leave XInputFile.getInputStream() returning " + is); return is; } /** * @return @throws * FileNotFoundException * @throws MalformedURLException * @throws IOException */ public InputStream getInputStream(long start_position) throws FileNotFoundException, MalformedURLException, IOException { if (debug) System.out.println("Enter XInputFile.getInputStream(long start_position)"); InputStream is = null; try { is = impl.getInputStream(start_position); } catch (IOException e) { if (debug) System.out.println(e.getLocalizedMessage()); if (debug) e.printStackTrace(); throw e; } if (debug) System.out.println("Leave XInputFile.getInputStream(long start_position) returning " + is); return is; } /** * @return */ public String getName() { if (debug) System.out.println("Enter XInputFile.getName()"); String s = impl.getName(); if (debug) System.out.println("Leave XInputFile.getName() returning " + s); return s; } /** * @return */ public String getParent() { if (debug) System.out.println("Enter XInputFile.getParent()"); String s = impl.getParent(); if (debug) System.out.println("Leave XInputFile.getParent() returning " + s); return s; } /** * @return */ public String getUrl() { if (debug) System.out.println("Enter XInputFile.getUrl()"); String s = impl.getUrl(); if (debug) System.out.println("Leave XInputFile.getUrl() returning " + s); return s; } /* * (non-Javadoc) * * @see java.lang.Object#hashCode() */ public int hashCode() { if (debug) System.out.println("Enter XInputFile.hashCode()"); int i = impl.hashCode(); if (debug) System.out.println("Leave XInputFile.hashCode() returning " + i); return i; } /** * @return */ public long lastModified() { if (debug) System.out.println("Enter XInputFile.lastModified()"); long l = impl.lastModified(); if (debug) System.out.println("Leave XInputFile.lastModified() returning " + l); return l; } /** * @return */ public boolean setLastModified() { if (debug) System.out.println("Enter XInputFile.setLastModified()"); boolean b = impl.setLastModified(); if (debug) System.out.println("Leave XInputFile.setLastModified() returning " + b); return b; } /** * @return */ public long length() { if (debug) System.out.println("Enter XInputFile.length()"); long l = impl.length(); if (debug) System.out.println("Leave XInputFile.length() returning " + l); return l; } /** * rename * * @return */ public boolean rename() throws IOException { if (debug) System.out.println("Enter XInputFile.rename()"); boolean b = impl.rename(); if (debug) System.out.println("Leave XInputFile.rename() returning " + b); return b; } /** * @throws IOException */ public void randomAccessClose() throws IOException { if (debug) System.out.println("Enter XInputFile.randomAccessClose()"); try { impl.randomAccessClose(); } catch (IOException e) { if (debug) System.out.println(e.getLocalizedMessage()); if (debug) e.printStackTrace(); throw e; } if (debug) System.out.println("Leave XInputFile.randomAccessClose()"); } /** * @param aMode * @throws IOException */ public void randomAccessOpen(String aMode) throws IOException { if (debug) System.out.println("Enter XInputFile.randomAccessOpen(String '" + aMode + "')"); try { impl.randomAccessOpen(aMode); } catch (IOException e) { if (debug) System.out.println(e.getLocalizedMessage()); if (debug) e.printStackTrace(); throw e; } if (debug) System.out.println("Leave XInputFile.randomAccessOpen(String '" + aMode + "')"); } /** * @return @throws * IOException */ public int randomAccessRead() throws IOException { if (debug) System.out.println("Enter XInputFile.randomAccessRead()"); int i = 0; try { i = impl.randomAccessRead(); } catch (IOException e) { if (debug) System.out.println(e.getLocalizedMessage()); if (debug) e.printStackTrace(); throw e; } if (debug) System.out.println("Leave XInputFile.randomAccessRead() returning " + i); return i; } /** * @param aBuffer * @return @throws * IOException */ public int randomAccessRead(byte[] aBuffer) throws IOException { if (debug) System.out.println("Enter XInputFile.randomAccessRead(byte[] aBuffer)"); int i = 0; try { i = impl.randomAccessRead(aBuffer); } catch (IOException e) { if (debug) System.out.println(e.getLocalizedMessage()); if (debug) e.printStackTrace(); throw e; } if (debug) System.out.println("Leave XInputFile.randomAccessRead(byte[] aBuffer) returning " + i); return i; } /** * @param aBuffer * @param aOffset * @param aLength * @return @throws * IOException */ public int randomAccessRead(byte[] aBuffer, int aOffset, int aLength) throws IOException { if (debug) System.out.println("Enter XInputFile.randomAccessRead(byte[] aBuffer, int aOffset, int aLength)"); int i = 0; try { i = impl.randomAccessRead(aBuffer, aOffset, aLength); } catch (IOException e) { if (debug) System.out.println(e.getLocalizedMessage()); if (debug) e.printStackTrace(); throw e; } if (debug) System.out .println("Leave XInputFile.randomAccessRead(byte[] aBuffer, int aOffset, int aLength) returning " + i); return i; } /** * @return Read line * @throws IOException */ public String randomAccessReadLine() throws IOException { if (debug) System.out.println("Enter XInputFile.randomAccessReadLine()"); String s = null; try { s = impl.randomAccessReadLine(); } catch (IOException e) { if (debug) System.out.println(e.getLocalizedMessage()); if (debug) e.printStackTrace(); throw e; } if (debug) System.out.println("Leave XInputFile.randomAccessReadLine() returning " + s); return s; } /** * @param aPosition * @throws IOException */ public void randomAccessSeek(long aPosition) throws IOException { if (debug) System.out.println("Enter XInputFile.randomAccessSeek(long '" + aPosition + "')"); try { impl.randomAccessSeek(aPosition); } catch (IOException e) { if (debug) System.out.println(e.getLocalizedMessage()); if (debug) e.printStackTrace(); throw e; } if (debug) System.out.println("Leave XInputFile.randomAccessSeek(long '" + aPosition + "')"); } /** * @return @throws * IOException */ public long randomAccessGetFilePointer() throws IOException { if (debug) System.out.println("Enter XInputFile.randomAccessGetFilePointer()"); long l = 0; try { l = impl.randomAccessGetFilePointer(); } catch (IOException e) { if (debug) System.out.println(e.getLocalizedMessage()); if (debug) e.printStackTrace(); throw e; } if (debug) System.out.println("Leave XInputFile.randomAccessGetFilePointer() returning " + l); return l; } /** * @param aBuffer * @param aPosition * @throws IOException */ public void randomAccessSingleRead(byte[] aBuffer, long aPosition) throws IOException { if (debug) System.out.println("Enter XInputFile.randomAccessSingleRead(byte[] aBuffer, long aPosition)"); try { impl.randomAccessSingleRead(aBuffer, aPosition); } catch (IOException e) { if (debug) System.out.println(e.getLocalizedMessage()); if (debug) e.printStackTrace(); throw e; } if (debug) System.out.println("Leave XInputFile.randomAccessSingleRead(byte[] aBuffer, long aPosition)"); } /** * @param aBuffer * @throws IOException */ public void randomAccessWrite(byte[] aBuffer) throws IOException { if (debug) System.out.println("Enter XInputFile.randomAccessWrite(byte[] aBuffer)"); try { impl.randomAccessWrite(aBuffer); } catch (IOException e) { if (debug) System.out.println(e.getLocalizedMessage()); if (debug) e.printStackTrace(); throw e; } if (debug) System.out.println("Leave XInputFile.randomAccessWrite(byte[] aBuffer)"); } /** * @return @throws * IOException */ public long randomAccessReadLong() throws IOException { if (debug) System.out.println("Enter XInputFile.readLong()"); long l = 0; try { l = impl.randomAccessReadLong(); } catch (IOException e) { if (debug) System.out.println(e.getLocalizedMessage()); if (debug) e.printStackTrace(); throw e; } if (debug) System.out.println("Leave XInputFile.readLong() returning " + l); return l; } /* * (non-Javadoc) * * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object aObj) { if (debug) System.out.println("Enter XInputFile.equals(Object '" + aObj + "')"); if (!(aObj instanceof XInputFile)) { if (debug) System.out.println("Leave XInputFile.equals(Object '" + aObj + "') returning false"); return false; } XInputFile other = (XInputFile) aObj; if (other.getFileType().equals(getFileType()) && other.toString().equals(toString())) { if (debug) System.out.println("Leave XInputFile.equals(Object '" + aObj + "') returning true"); return true; } else { if (debug) System.out.println("Leave XInputFile.equals(Object '" + aObj + "') returning false"); return false; } } /* * (non-Javadoc) * * @see net.sourceforge.dvb.projectx.xinput.XInputFileIF#getFileType() */ public FileType getFileType() { if (debug) System.out.println("Enter XInputFile.getFileType()"); FileType ft = impl.getFileType(); if (debug) System.out.println("Leave XInputFile.getFileType() returning " + ft); return ft; } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ public String toString() { if (debug) System.out.println("Enter XInputFile.toString()"); String s = impl.toString(); if (debug) System.out.println("Leave XInputFile.toString() returning " + s); return s; } /* * */ public XInputFileIF getImpl() { return impl; } /** * */ public void setStreamInfo(StreamInfo _streamInfo) { if (impl != null) impl.setStreamInfo(_streamInfo); } /** * */ public StreamInfo getStreamInfo() { return (impl != null ? impl.getStreamInfo() : null); } }project-x/src/net/sourceforge/dvb/projectx/xinput/XInputFileIF.java0000600000175000017500000001263310351107022027064 0ustar supermariosupermario/* * @(#)XInputFileIF.java * * Copyright (c) 2004-2005 by roehrist, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ /* * Created on 24.08.2004 * */ package net.sourceforge.dvb.projectx.xinput; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import net.sourceforge.dvb.projectx.xinput.StreamInfo; /** * @author Stefan * */ public interface XInputFileIF { /** * Get String representation of the object. * * @return String representation of the object */ public String toString(); public void setConstructorParameter(Object obj); public Object getConstructorParameter(); /** * Gets the type of this XInputFile implementation. * * @return FileType */ public FileType getFileType(); /** * Get url representation of the object. * * @return String with url */ public String getUrl(); /** * Length of file in bytes. * * @return Length of file in bytes */ public long length(); /** * Time in milliseconds from the epoch. * * @return Time in milliseconds from the epoch */ public long lastModified(); /** * set Time in milliseconds from the epoch. * * @return success */ public boolean setLastModified(); /** * Checks if file exists * * @return Result of check */ public boolean exists(); /** * Get Name of file * * @return Name of file */ public String getName(); /** * Get Path of parent * * @return Path of parent */ public String getParent(); /** * Get input stream from the file. close() on stream closes XInputFile, too. * * @return Input stream from the file */ public InputStream getInputStream() throws FileNotFoundException, MalformedURLException, IOException; /** * Get input stream from the file. close() on stream closes XInputFile, too. * * @return Input stream from the file */ public InputStream getInputStream(long start_position) throws FileNotFoundException, MalformedURLException, IOException; /** * rename file * * @return success */ public boolean rename() throws IOException; /** * Opens XInputFile for random access * * @param mode * Access mode as in RandomAccessFile * @throws IOException */ public void randomAccessOpen(String mode) throws IOException; /** * @throws java.io.IOException */ public void randomAccessClose() throws IOException; /** * @param aPosition * The offset position, measured in bytes from the beginning of the * file, at which to set the file pointer. * @throws java.io.IOException */ public void randomAccessSeek(long aPosition) throws IOException; /** * @return @throws * IOException */ public long randomAccessGetFilePointer() throws IOException; /** * @return @throws * IOException */ public int randomAccessRead() throws IOException; /** * @param aBuffer * The buffer into which the data is read. * @return @throws * java.io.IOException */ public int randomAccessRead(byte[] aBuffer) throws IOException; /** * @param aBuffer * The buffer into which the data is written. * @param aOffset * The offset at which the data should be written. * @param aLength * The amount of data to be read. * @return @throws * IOException */ public int randomAccessRead(byte[] aBuffer, int aOffset, int aLength) throws IOException; /** * @return Read line * @throws IOException */ public String randomAccessReadLine() throws IOException; /** * @param aBuffer * The data. * @throws java.io.IOException */ public void randomAccessWrite(byte[] aBuffer) throws IOException; /** * Convinience method for a single random read access to a input file. The * file is opened before and closed after read. * * @param aBuffer * Buffer to fill with read bytes (up to aBuffer.length() bytes) * @param aPosition * Fileposition at which we want read * @throws IOException */ public void randomAccessSingleRead(byte[] aBuffer, long aPosition) throws IOException; /** * @return Long value read. * @throws java.io.IOException */ public long randomAccessReadLong() throws IOException; /** * */ public void setStreamInfo(StreamInfo _streamInfo); /** * */ public StreamInfo getStreamInfo(); }project-x/src/net/sourceforge/dvb/projectx/xinput/XInputStream.java0000600000175000017500000001265010407317542027234 0ustar supermariosupermario/* * @(#)XInputStream.java * * Copyright (c) 2004-2005 by pstorch, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.xinput; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.io.BufferedInputStream; import net.sourceforge.dvb.projectx.xinput.ftp.XInputFileImpl; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Keys; public class XInputStream extends FilterInputStream { private boolean debug = false; private byte[] buffer = new byte[1]; private XInputFileImpl xInputFile = null; /** * Create stream, which is able to handle special needs of the xinput package. * * @param aIs * InputStream * @see java.io.FilterInputStream#FilterInputStream(InputStream in) */ public XInputStream(InputStream aIs) { super(Common.getSettings().getBooleanProperty(Keys.KEY_additionalInputBuffer) ? new BufferedInputStream(aIs, 1048576) : aIs); } public void setFtpFile(XInputFileImpl aIf) { xInputFile = aIf; } /** * Takes care, that always the full amount of data is read (if possible). * Blocks until it succeeds. * * @see java.io.InputStream#read() */ public final int read() throws IOException { if (read(buffer, 0, 1) == 1) return (int) buffer[0]; else return -1; } /** * Takes care, that always the full amount of data is read (if possible). * Blocks until it succeeds. * * @param aBuffer * Buffer to fill with data * @see java.io.InputStream#read(byte[]) */ public final int read(byte[] aBuffer) throws IOException { return read(aBuffer, 0, aBuffer.length); } /** * Takes care, that always the full amount of data is read (if possible). * Blocks until it succeeds. * * @param aBuffer * Buffer to keep data * @param off * Offset in buffer * @param len * Length of data to read * @see java.io.InputStream#read(byte[], int, int) */ public final int read(byte[] aBuffer, int off, int len) throws IOException { if (debug) System.out.println("Enter XInputStream.read(" + aBuffer + ", " + off + ", " + len + ")"); int result = 0; long read = 0; long readBytes = 0; long remaining = len; long retryCount = 0; try { do { read = super.read(aBuffer, (int)(off + readBytes), (int) remaining); if (debug) System.out.println(" Bytes read in this cycle: " + read); if (read > 0) { readBytes += read; remaining -= read; } if (read == 0) { retryCount++; } else { retryCount = 0; } } while ((remaining > 0) && (read != -1) && (retryCount <= 100)); result = (int) (len - remaining); if ((read == -1) && (result == 0)) { if (debug) System.out.println("Leave XInputStream.read(aBuffer,off,len) returning -1"); return -1; } else { if (debug) System.out.println("Leave XInputStream.read(aBuffer,off,len) returning " + result); return result; } } finally { if (debug && (readBytes != len)) System.out.println("********** ATTENTION! Bytes to read: " + len + ", Read: " + readBytes + ", Difference: " + (len - readBytes) + "**********"); } } /** * @see java.io.InputStream#close() */ public final void close() throws IOException { if (debug) System.out.println("Enter XInputStream.close()"); if (xInputFile != null) { xInputFile.randomAccessClose(); xInputFile = null; } super.close(); if (debug) System.out.println("Leave XInputStream.close()"); } /** * @see java.io.InputStream#skip(long) */ public final long skip(long n) throws IOException { if (debug) System.out.println("Enter XInputStream.skip(" + n + ")"); long retryCount = 0; long skiped = 0; long skipedBytes = 0; long remaining = n; try { do { skiped = super.skip(remaining); if (debug) System.out.println(" Bytes skiped in this cycle: " + skiped); skipedBytes += skiped; remaining -= skiped; if (skiped == 0) { retryCount++; } else { retryCount = 0; } } while ((remaining > 0) && (retryCount <= 100)); if (debug) System.out.println("Leave XInputStream.skip(" + n + ") returning " + skipedBytes); return skipedBytes; } finally { if (debug && (skipedBytes != n)) System.out.println("********** ATTENTION! Bytes to skip: " + n + ", Skiped: " + skipedBytes + ", Difference: " + (n - skipedBytes) + "**********"); } } }project-x/src/net/sourceforge/dvb/projectx/xinput/file/0000700000175000017500000000000010745203152024673 5ustar supermariosupermarioproject-x/src/net/sourceforge/dvb/projectx/xinput/file/XInputDirectoryImpl.java0000600000175000017500000001430410355106364031504 0ustar supermariosupermario/* * @(#)XInputDirectoryImpl.java - implementation for files * * Copyright (c) 2004-2005 by roehrist, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.xinput.file; import java.io.File; import java.io.FileFilter; import java.util.ArrayList; import net.sourceforge.dvb.projectx.xinput.DirType; import net.sourceforge.dvb.projectx.xinput.XInputDirectoryIF; import net.sourceforge.dvb.projectx.xinput.XInputFile; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Keys; public class XInputDirectoryImpl implements XInputDirectoryIF { private DirType dirType = null; private File file = null; private String testMsg = null; /** * Mustn't be used * * @throws UnsupportedOperationException * Because it mustn't be used! */ private XInputDirectoryImpl() { throw new UnsupportedOperationException("Usage is not allowed!"); } /** * Create a XInputDirectory of type DirType.FILE_DIR. * * @param aFile * Directory data to use * @throws IllegalArgumentException * If aFile is not a directory */ public XInputDirectoryImpl(File aFile) { if (aFile.exists() && aFile.isDirectory()) { dirType = DirType.FILE_DIR; file = aFile; } else { throw new IllegalArgumentException("aFile is not a directory!"); } } /** * Create a XInputDirectory of type DirType.FILE_DIR. * * @param aFileIdentifier * Directory name * @throws IllegalArgumentException * If aFile is not a directory */ public XInputDirectoryImpl(String aFileIdentifier) { File f = new File(aFileIdentifier); if (f.exists() && f.isDirectory()) { dirType = DirType.FILE_DIR; file = f; } else { throw new IllegalArgumentException("'" + aFileIdentifier + "' is not a directory!"); } } /** * Get String representation of the object. * * @return String representation of the object */ public String toString() { return file.getAbsolutePath(); } /** * Get path of directory * * @return Path of directory */ public String getDirectory() { return file.getParent(); } /** * Get password for the ftp server * * @return Password for the ftp server * @throws IllegalStateException * If file type of object is not DirType.FTP_DIR */ public String getPassword() { return ""; } /** * Get name or ip address of the ftp server * * @return Name or ip address of the ftp server * @throws IllegalStateException * If file type of object is not DirType.FTP_DIR */ public String getServer() { return ""; } /** * Get port of the ftp server * * @return port of the ftp server * @throws IllegalStateException * If file type of object is not DirType.FTP_DIR */ public String getPort() { return ""; } /** * Get user for the ftp server * * @return User for the ftp server * @throws IllegalStateException * If file type of object is not DirType.FTP_DIR */ public String getUser() { return ""; } /** * Get log of communication with ftp server. * * @return Log of communication with ftp server * @throws IllegalStateException * If file type of object is not DirType.FTP_DIR */ public String getLog() { return ""; } /** * Get files in the directory. * * @return files in the directory */ public XInputFile[] getFiles() { ArrayList list = new ArrayList(); class MyFileFilter implements FileFilter { public boolean accept(File pathname) { return pathname.isFile(); } } File[] files = file.listFiles(new MyFileFilter()); for (int i = 0; i < files.length; i++) list.add(files[i]); if (Common.getSettings().getBooleanProperty(Keys.KEY_InputDirectoriesDepth)) getDirectories(file, list); // depth 1 XInputFile[] xInputFiles = new XInputFile[list.size()]; for (int i = 0; i < xInputFiles.length; i++) { xInputFiles[i] = new XInputFile((File) list.get(i)); } return xInputFiles; } /** * */ private void getDirectories(File dir, ArrayList list) { class MyFileFilter implements FileFilter { public boolean accept(File pathname) { return pathname.isFile(); } } class MyDirFilter implements FileFilter { public boolean accept(File pathname) { return pathname.isDirectory(); } } File[] dirs = dir.listFiles(new MyDirFilter()); File[] files; for (int i = 0; i < dirs.length; i++) { files = dirs[i].listFiles(new MyFileFilter()); for (int j = 0; j < files.length; j++) list.add(files[j]); getDirectories(dirs[i], list); // depth 2 } } /** * Test if directory data is valid. * * @return Test successful or not */ public boolean test() { boolean b = false; b = (file.exists() && file.isDirectory()) ? true : false; testMsg = b ? "Test succeeded" : "Test failed"; return b; } /** * Get result message after test(). * * @return result message after test() */ public String getTestMsg() { return testMsg; } /** * @return Type of XInputDirectory */ public DirType getDirType() { return dirType; } }project-x/src/net/sourceforge/dvb/projectx/xinput/file/XInputFileImpl.java0000600000175000017500000002304110353557460030422 0ustar supermariosupermario/* * @(#)XInputFileImpl.java - implementation for files * * Copyright (c) 2004-2005 by roehrist, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.xinput.file; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.MalformedURLException; import net.sourceforge.dvb.projectx.xinput.FileType; import net.sourceforge.dvb.projectx.xinput.XInputFileIF; import net.sourceforge.dvb.projectx.xinput.XInputStream; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.xinput.StreamInfo; public class XInputFileImpl implements XInputFileIF { private boolean debug = false; // Members, which are type independent private FileType fileType = null; private boolean isopen = false; private InputStream inputStream = null; // Members used for type FileType.FILE private File file = null; private String file_separator = System.getProperty("file.separator"); private RandomAccessFile randomAccessFile = null; private Object constructorParameter = null; private StreamInfo streamInfo = null; /** * Private Constructor, don't use! */ private XInputFileImpl() { throw new UnsupportedOperationException(); } /** * Create a XInputFile of type FileType.FILE. * * @param aFile * File data to use * @throws IllegalArgumentException * If aFile is not a file */ public XInputFileImpl(File aFile) { if (debug) System.out.println("Try to create XInputFile of Type FILE"); if (!aFile.isFile()) { throw new IllegalArgumentException("File is not of type FileType.FILE"); } file = aFile; fileType = FileType.FILE; if (!exists()) { throw new IllegalArgumentException("File doesn't exist"); } if (debug) System.out.println("Succeeded to create XInputFile of Type FILE"); } /** * Get String representation of the object. * * @return String representation of the object */ public String toString() { return file.getAbsolutePath(); // return (file.getAbsolutePath() + " (" + Common.formatNumber(length()) + " bytes)"); } public void setConstructorParameter(Object obj) { constructorParameter = obj; } public Object getConstructorParameter() { return constructorParameter; } /** * Get url representation of the object. * * @return String with url */ public String getUrl() { return "file://" + file.getAbsolutePath(); } /** * Length of file in bytes. * * @return Length of file in bytes */ public long length() { return file.length(); } /** * Time in milliseconds from the epoch. * * @return Time in milliseconds from the epoch */ public long lastModified() { return file.lastModified(); } /** * sets Time in milliseconds from the epoch. * * @return Time in milliseconds from the epoch */ public boolean setLastModified() { return file.setLastModified(System.currentTimeMillis()); } /** * Checks if file exists * * @return Result of check */ public boolean exists() { return file.exists(); } /** * Get Name of file * * @return Name of file */ public String getName() { return file.getName(); } /** * Get Path of parent * * @return Path of parent */ public String getParent() { return file.getParent(); } /** * Get input stream from the file. close() on stream closes XInputFile, too. * * @return Input stream from the file */ public InputStream getInputStream() throws FileNotFoundException, MalformedURLException, IOException { return getInputStream(0L); } /** * Get input stream from the file. close() on stream closes XInputFile, too. * * @return Input stream from the file */ public InputStream getInputStream(long start_position) throws FileNotFoundException, MalformedURLException, IOException { XInputStream xIs = new XInputStream(new FileInputStream(file)); xIs.skip(start_position); return xIs; } /** * rename this file * @return */ public boolean rename() throws IOException { // if (isopen) { throw new IllegalStateException("XInputFile is open!"); } if (isopen) return false; String parent = getParent(); String name = getName(); String newName = null; boolean ret = false; if ( !parent.endsWith(file_separator) ) parent += file_separator; newName = Common.getGuiInterface().getUserInputDialog(name, Resource.getString("autoload.dialog.rename") + " " + parent + name); if (newName != null && !newName.equals("")) { if (new File(parent + newName).exists()) { ret = Common.getGuiInterface().getUserConfirmationDialog(Resource.getString("autoload.dialog.fileexists")); if (ret) { new File(parent + newName).delete(); ret = Common.renameTo(parent + name, parent + newName); } } else ret = Common.renameTo(parent + name, parent + newName); } if (ret) { file = new File(parent + newName); constructorParameter = file; } return ret; } /** * Opens XInputFile for random access * * @param mode * Access mode as in RandomAccessFile * @throws IOException */ public void randomAccessOpen(String mode) throws IOException { if (isopen) { throw new IllegalStateException("XInputFile is already open!"); } randomAccessFile = new RandomAccessFile(file, mode); isopen = true; } /** * @throws java.io.IOException */ public void randomAccessClose() throws IOException { if (!isopen) { throw new IllegalStateException("XInputFile is already closed!"); } if (randomAccessFile != null) { randomAccessFile.close(); randomAccessFile = null; } isopen = false; } /** * @param aPosition * The offset position, measured in bytes from the beginning of the * file, at which to set the file pointer. * @throws java.io.IOException */ public void randomAccessSeek(long aPosition) throws IOException { randomAccessFile.seek(aPosition); } /** * @return @throws * IOException */ public long randomAccessGetFilePointer() throws IOException { return randomAccessFile.getFilePointer(); } /** * @return @throws * IOException */ public int randomAccessRead() throws IOException { return randomAccessFile.read(); } /** * @param aBuffer * The buffer into which the data is read. * @return @throws * java.io.IOException */ public int randomAccessRead(byte[] aBuffer) throws IOException { return randomAccessFile.read(aBuffer); } /** * @param aBuffer * The buffer into which the data is written. * @param aOffset * The offset at which the data should be written. * @param aLength * The amount of data to be read. * @return @throws * IOException */ public int randomAccessRead(byte[] aBuffer, int aOffset, int aLength) throws IOException { return randomAccessFile.read(aBuffer, aOffset, aLength); } /** * @return Read line * @throws IOException */ public String randomAccessReadLine() throws IOException { return randomAccessFile.readLine(); } /** * @param aBuffer * The data. * @throws java.io.IOException */ public void randomAccessWrite(byte[] aBuffer) throws IOException { randomAccessFile.write(aBuffer); } /** * Convinience method for a single random read access to a input file. The * file is opened before and closed after read. * * @param aBuffer * Buffer to fill with read bytes (up to aBuffer.length() bytes) * @param aPosition * Fileposition at which we want read * @throws IOException */ public void randomAccessSingleRead(byte[] aBuffer, long aPosition) throws IOException { randomAccessOpen("r"); randomAccessSeek(aPosition); randomAccessRead(aBuffer); randomAccessClose(); } /** * @return Long value read. * @throws java.io.IOException */ public long randomAccessReadLong() throws IOException { return randomAccessFile.readLong(); } /* * (non-Javadoc) * * @see net.sourceforge.dvb.projectx.xinput.XInputFileIF#getFileType() */ public FileType getFileType() { return fileType; } // /** * */ public void setStreamInfo(StreamInfo _streamInfo) { streamInfo = _streamInfo; } /** * */ public StreamInfo getStreamInfo() { return streamInfo; } }project-x/src/net/sourceforge/dvb/projectx/xinput/ftp/0000700000175000017500000000000010745203152024545 5ustar supermariosupermarioproject-x/src/net/sourceforge/dvb/projectx/xinput/ftp/FtpServer.java0000600000175000017500000001542210351107064027334 0ustar supermariosupermario/* * @(#)FtpServer.java - for ftp access * * Copyright (c) 2004-2005 by roehrist, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ /* * requires Jakarta Commons Net library, developed by the * Apache Software Foundation (http://www.apache.org/). */ package net.sourceforge.dvb.projectx.xinput.ftp; import java.io.IOException; import java.io.InputStream; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.xinput.XInputFile; import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPReply; public class FtpServer { private FtpVO ftpVO; private StringCommandListener scl; private FTPClient ftpClient; private boolean isOpen; private String testMsg; private FtpServer() { throw new UnsupportedOperationException(); } public FtpServer(FtpVO aFtpVO) { if (aFtpVO == null) { throw new IllegalArgumentException("aFtpVO mustn't be null!"); } ftpVO = aFtpVO; scl = new StringCommandListener(); ftpClient = new FTPClient(); ftpClient.addProtocolCommandListener(scl); isOpen = false; } public boolean open() { boolean isSuccessful = false; if (isOpen) { throw new IllegalStateException("Is already open, must be closed before!"); } try { int reply; ftpClient.connect(ftpVO.getServer(), ftpVO.getPortasInteger()); reply = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftpClient.disconnect(); throw new IOException("Can't connect!"); } if (!ftpClient.login(ftpVO.getUser(), ftpVO.getPassword())) { ftpClient.logout(); throw new IOException("Can't login!"); } if (!ftpClient.changeWorkingDirectory(ftpVO.getDirectory())) { ftpClient.logout(); throw new IOException("Can't change directory!"); } ftpClient.setFileType(FTP.BINARY_FILE_TYPE); ftpClient.enterLocalPassiveMode(); isSuccessful = true; } catch (Exception e) { if (ftpClient.isConnected()) { try { ftpClient.disconnect(); } catch (IOException f) { // do nothing } } isSuccessful = false; } isOpen = isSuccessful; return isSuccessful; } public XInputFile[] listFiles() { FTPFile[] ftpFiles = null; XInputFile[] ftpInputFiles = null; try { ftpFiles = ftpClient.listFiles(); ftpInputFiles = new XInputFile[ftpFiles.length]; for (int i = 0; i < ftpFiles.length; i++) { FtpVO tempFtpVO = (FtpVO) ftpVO.clone(); tempFtpVO.setFtpFile(ftpFiles[i]); ftpInputFiles[i] = new XInputFile(tempFtpVO); } } catch (Exception e) { ftpInputFiles = new XInputFile[0]; } return ftpInputFiles; } public InputStream retrieveFileStream(String aFileName) throws IOException { return ftpClient.retrieveFileStream(aFileName); } public void close() { if (!isOpen) { throw new IllegalStateException("Is already closed, must be opened before!"); } else { try { ftpClient.logout(); ftpClient.disconnect(); } catch (Exception e) { // do nothing } isOpen = false; } } public boolean test() { int base = 0; boolean error = false; FTPFile[] ftpFiles; testMsg = null; try { int reply; ftpClient.connect(ftpVO.getServer(), ftpVO.getPortasInteger()); // Check connection reply = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftpClient.disconnect(); testMsg = Resource.getString("ftpchooser.msg.noconnect"); return false; } // Login if (!ftpClient.login(ftpVO.getUser(), ftpVO.getPassword())) { ftpClient.logout(); testMsg = Resource.getString("ftpchooser.msg.nologin"); return false; } ftpClient.syst(); // Change directory if (!ftpClient.changeWorkingDirectory(ftpVO.getDirectory())) { testMsg = Resource.getString("ftpchooser.msg.nodirectory"); return false; } testMsg = Resource.getString("ftpchooser.msg.success"); ftpClient.logout(); } catch (IOException ex) { testMsg = ex.getLocalizedMessage(); error = true; } finally { if (ftpClient.isConnected()) { try { ftpClient.disconnect(); } catch (IOException f) { } } } return !error; } public String getTestMsg() { return testMsg; } public String getLog() { return scl.getMessages(); } } /* * int base = 0; boolean storeFile = false, binaryTransfer = false, error = * false; String server, username, password, remote, local, remoteDir; FTPClient * ftp; FTPFile[] ftpFiles; * * server = "192.168.0.5"; username = "root"; password = "dreambox"; remote = * ""; local = ""; remoteDir = "/hdd/movie"; * * ftp = new FTPClient(); ftp.addProtocolCommandListener( new * PrintCommandListener(new PrintWriter(System.out))); * * * try { if (!ftp.login(username, password)) { ftp.logout(); error = true; } * else { System.out.println("Remote system is " + ftp.getSystemName()); * * ftp.setFileType(FTP.BINARY_FILE_TYPE); ftp.enterLocalPassiveMode(); * * ftp.changeWorkingDirectory(remoteDir); ftpFiles = ftp.listFiles(); for (int i = * 0; i < ftpFiles.length; i++) { FTPFile file = ftpFiles[i]; * System.out.println("Listing of " + remoteDir + ": " + file.getName()); } * * * if (storeFile) { InputStream input; * * input = new FileInputStream(local); ftp.storeFile(remote, input); } else { * OutputStream output; * * output = new FileOutputStream(local); ftp.retrieveFile(remote, output); } * * * ftp.logout(); } } catch (FTPConnectionClosedException e) { error = true; * System.err.println("Server closed connection."); e.printStackTrace(); } catch * (IOException e) { error = true; e.printStackTrace(); } finally { if * (ftp.isConnected()) { try { ftp.disconnect(); } catch (IOException f) { // do * nothing } } } */ project-x/src/net/sourceforge/dvb/projectx/xinput/ftp/FtpVO.java0000600000175000017500000001140310351107074026406 0ustar supermariosupermario/* * @(#)FtpVO.java - for ftp access * * Copyright (c) 2004-2005 by roehrist, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ /* * requires Jakarta Commons Net library, developed by the * Apache Software Foundation (http://www.apache.org/). */ package net.sourceforge.dvb.projectx.xinput.ftp; import java.util.StringTokenizer; import org.apache.commons.net.ftp.FTPFile; public class FtpVO implements Cloneable { private String server = null; private String user = null; private String password = null; private String directory = null; private String port = null; private FTPFile ftpFile = null; public FtpVO(String server, String user, String password, String directory, FTPFile ftpFile) { this.server = server; this.user = user; this.password = password; this.directory = directory; this.ftpFile = ftpFile; port = null; } public FtpVO(String server, String user, String password, String directory, String port, FTPFile ftpFile) { this.server = server; this.user = user; this.password = password; this.directory = directory; this.port = port; this.ftpFile = ftpFile; } public void reset() { server = null; user = null; password = null; directory = null; port = null; } public String toString() { return "ftp://|" + server + "|" + port + "|" + directory + "|" + user + "|" + password; } public void fromString(String string) { // Don't use String.split(), because it is not available on jdk 1.2 StringTokenizer st = new StringTokenizer(string, "|"); String[] tokens = new String[6]; for (int i = 0; st.hasMoreTokens() && i < 6; i++) tokens[i] = st.nextElement().toString(); server = tokens[1]; directory = tokens[3]; user = tokens[4]; password = tokens[5]; try { Integer.parseInt(tokens[2]); port = tokens[2]; } catch (Exception e) { port = null; } } /** * @return Returns the directory. */ public String getDirectory() { return directory; } /** * @param directory * The directory to set. */ public void setDirectory(String directory) { this.directory = directory; } /** * @return Returns the password. */ public String getPassword() { return password; } /** * @param password * The password to set. */ public void setPassword(String password) { this.password = password; } /** * @return Returns the server. */ public String getServer() { return server; } /** * @param server * The server to set. */ public void setServer(String server) { this.server = server; } /** * @return Returns the port. */ public String getPort() { if (port == null || port.trim().length() == 0) return null; return port; } /** * @return Returns the port. */ public String getPort(String prefix) { if (port == null || port.trim().length() == 0) return ""; return prefix + port; } /** * @return Returns the port. */ public int getPortasInteger() { if (port == null) return 21; return Integer.parseInt(port); } /** * @param port * The port to set. */ public void setPort(int port) { this.port = String.valueOf(port); } /** * @return Returns the user. */ public String getUser() { return user; } /** * @param user * The user to set. */ public void setUser(String user) { this.user = user; } /** * @return Returns the ftpFile. */ public FTPFile getFtpFile() { return ftpFile; } /** * @param aFtpFile * The ftpFile to set. */ public void setFtpFile(FTPFile aFtpFile) { ftpFile = aFtpFile; } /* * (non-Javadoc) * * @see java.lang.Object#clone() */ public Object clone() { return new FtpVO(server, user, password, directory, port, ftpFile); } }project-x/src/net/sourceforge/dvb/projectx/xinput/ftp/StringCommandListener.java0000600000175000017500000000474610351107110031666 0ustar supermariosupermario/* * @(#)StringCommandListener.java - for ftp access * * Copyright (c) 2004-2005 by roehrist, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ /* * requires Jakarta Commons Net library, developed by the * Apache Software Foundation (http://www.apache.org/). */ package net.sourceforge.dvb.projectx.xinput.ftp; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import org.apache.commons.net.ProtocolCommandEvent; import org.apache.commons.net.ProtocolCommandListener; /******************************************************************************* * This is a support class for some of the example programs. It is a sample * implementation of the ProtocolCommandListener interface which just prints out * to a specified stream all command/reply traffic. *

******************************************************************************/ class StringCommandListener implements ProtocolCommandListener { private StringWriter sWriter = new StringWriter(); private PrintWriter pWriter = new PrintWriter(sWriter); public void protocolCommandSent(ProtocolCommandEvent event) { pWriter.print(event.getMessage()); pWriter.flush(); } public void protocolReplyReceived(ProtocolCommandEvent event) { pWriter.print(event.getMessage()); pWriter.flush(); } public String getMessages() { return sWriter.toString(); } public void reset() { pWriter.close(); try { sWriter.close(); } catch (IOException e) { // do nothing } sWriter = new StringWriter(); pWriter = new PrintWriter(sWriter); } }project-x/src/net/sourceforge/dvb/projectx/xinput/ftp/XInputDirectoryImpl.java0000600000175000017500000001676210351107122031355 0ustar supermariosupermario/* * @(#)XInputDirectoryImpl.java - implementation for ftp access * * Copyright (c) 2004-2005 by roehrist, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.xinput.ftp; import net.sourceforge.dvb.projectx.xinput.DirType; import net.sourceforge.dvb.projectx.xinput.XInputDirectoryIF; import net.sourceforge.dvb.projectx.xinput.XInputFile; import java.net.URL; public class XInputDirectoryImpl implements XInputDirectoryIF { private DirType dirType = null; private FtpVO ftpVO = null; private FtpServer ftpServer = null; /** * Mustn't be used * * @throws UnsupportedOperationException * Because it mustn't be used! */ private XInputDirectoryImpl() { throw new UnsupportedOperationException("Usage is not allowed!"); } /** * Create a XInputDirectory of type DirType.FTP_DIR. * * @param aFtpVO * Directory data to use */ public XInputDirectoryImpl(FtpVO aFtpVO) { ftpVO = aFtpVO; ftpServer = new FtpServer(ftpVO); dirType = DirType.FTP_DIR; } /** * Create a XInputDirectory of type DirType.FILE_DIR. * * @param aFileIdentifier * Directory name * @throws IllegalArgumentException * If aFile is not a directory */ public XInputDirectoryImpl(String aFileIdentifier) { if (aFileIdentifier.startsWith("ftp://")) { int posColon = aFileIdentifier.indexOf(':', 6); int posAt = aFileIdentifier.indexOf('@', posColon); int posSlash = aFileIdentifier.indexOf('/', posAt); if (posAt == -1 || posColon == -1 || posSlash == -1) { throw new IllegalArgumentException( "aFileIdentifier is a malformed ftp URL!"); } String user = aFileIdentifier.substring(6, posColon); String password = aFileIdentifier.substring(posColon + 1, posAt); String server = aFileIdentifier.substring(posAt + 1, posSlash); String directory = aFileIdentifier.substring(posSlash); String port = null; int posColon2 = server.indexOf(':'); if (posColon2 != -1) { server = server.substring(0, posColon2); port = server.substring(posColon2 + 1); } ftpVO = new FtpVO(server, user, password, directory, port, null); ftpServer = new FtpServer(ftpVO); dirType = DirType.FTP_DIR; if (!test()) { ftpVO = null; ftpServer = null; dirType = null; throw new IllegalArgumentException(aFileIdentifier + " is not a correct ftp URL!"); } } else { throw new IllegalArgumentException(aFileIdentifier + " is not a correct ftp URL!"); } } /** * Create a XInputDirectory of type DirType.FILE_DIR. * * @param aFileIdentifier * Directory URL * @throws IllegalArgumentException * If URL is not a directory */ public XInputDirectoryImpl(URL url) { if (url.getProtocol().compareTo("ftp") != -1) { /** * JDK122 cannot parse user + pw, but returns it in getHost() */ String _link = url.toString(); String _host = url.getHost(); int j = _link.indexOf(_host); if (j > 6) _host = _link.substring(6, j) + _host; String server = _host; String user = null; String password = null; String directory = null; String port = null; int i = _host.indexOf("@"); if (i != -1) { server = _host.substring(i + 1); user = _host.substring(0, i); i = user.indexOf(":"); if (i != -1) { password = user.substring(i + 1); user = user.substring(0, i); } } if (user == null && password == null) { user = "anonymous"; password = ""; } int _port = url.getPort(); port = _port != -1 ? String.valueOf(_port) : null; String _file = url.getFile(); i = _file.lastIndexOf("/"); directory = _file.substring(0, i); ftpVO = new FtpVO(server, user, password, directory, port, null); ftpServer = new FtpServer(ftpVO); dirType = DirType.FTP_DIR; if (!test()) { ftpVO = null; ftpServer = null; dirType = null; throw new IllegalArgumentException(url + " is not a correct ftp URL!"); } } else { throw new IllegalArgumentException(url + " is not a correct ftp URL!"); } } /** * Get String representation of the object. * * @return String representation of the object */ public String toString() { String s = null; s = "ftp://" + ftpVO.getUser() + ":" + ftpVO.getPassword() + "@" + ftpVO.getServer() + ftpVO.getPort(":") + ftpVO.getDirectory(); return s; } /** * Get path of directory * * @return Path of directory */ public String getDirectory() { return ftpVO.getDirectory(); } /** * Get password for the ftp server * * @return Password for the ftp server * @throws IllegalStateException * If file type of object is not DirType.FTP_DIR */ public String getPassword() { return ftpVO.getPassword(); } /** * Get name or ip address of the ftp server * * @return Name or ip address of the ftp server * @throws IllegalStateException * If file type of object is not DirType.FTP_DIR */ public String getServer() { return ftpVO.getServer(); } /** * Get name or ip address of the ftp server * * @return port of the ftp server * @throws IllegalStateException * If file type of object is not DirType.FTP_DIR */ public String getPort() { return ftpVO.getPort(); } /** * Get user for the ftp server * * @return User for the ftp server * @throws IllegalStateException * If file type of object is not DirType.FTP_DIR */ public String getUser() { return ftpVO.getUser(); } /** * Get log of communication with ftp server. * * @return Log of communication with ftp server * @throws IllegalStateException * If file type of object is not DirType.FTP_DIR */ public String getLog() { return ftpServer.getLog(); } /** * Get files in the directory. * * @return files in the directory */ public XInputFile[] getFiles() { XInputFile[] xInputFiles = null; ftpServer.open(); xInputFiles = ftpServer.listFiles(); ftpServer.close(); return xInputFiles; } /** * Test if directory data is valid. * * @return Test successful or not */ public boolean test() { return ftpServer.test(); } /** * Get result message after test(). * * @return result message after test() */ public String getTestMsg() { return ftpServer.getTestMsg(); } /** * @return Type of XInputDirectory */ public DirType getDirType() { return dirType; } }project-x/src/net/sourceforge/dvb/projectx/xinput/ftp/XInputFileImpl.java0000600000175000017500000004136110351107132030262 0ustar supermariosupermario/* * @(#)XInputFileImpl.java - implementation for ftp access * * Copyright (c) 2004-2005 by roehrist, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ /* * requires Jakarta Commons Net library, developed by the * Apache Software Foundation (http://www.apache.org/). */ package net.sourceforge.dvb.projectx.xinput.ftp; import java.io.EOFException; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.PushbackInputStream; import java.io.RandomAccessFile; import java.net.MalformedURLException; import java.net.URL; import java.util.StringTokenizer; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.xinput.FileType; import net.sourceforge.dvb.projectx.xinput.XInputFileIF; import net.sourceforge.dvb.projectx.xinput.XInputStream; import org.apache.commons.net.ftp.FTPFile; import java.io.DataInputStream; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTP; import net.sourceforge.dvb.projectx.xinput.StreamInfo; public class XInputFileImpl implements XInputFileIF { private boolean debug = false; // Members, which are type independent private FileType fileType = null; private boolean isopen = false; private PushbackInputStream pbis = null; private File rafFile = null; private RandomAccessFile raf = null; private byte[] buffer = new byte[8]; // Members used for type FileType.FTP private FtpVO ftpVO = null; private FTPFile ftpFile = null; private FTPClient client = null; private DataInputStream in = null; public XInputStream xIs = null; private Object constructorParameter = null; private StreamInfo streamInfo = null; private boolean supportsResume = true; /** * Private Constructor, don't use! */ private XInputFileImpl() { throw new UnsupportedOperationException(); } /** * Create a XInputFile of type FileType.FTP. * * @param aFtpVO * Directory data to use * @param aFtpFile * File data to use */ public XInputFileImpl(FtpVO aFtpVO) { if (debug) System.out.println("Try to create XInputFile of Type FTP"); ftpVO = aFtpVO; ftpFile = aFtpVO.getFtpFile(); fileType = FileType.FTP; if (!exists()) { throw new IllegalArgumentException("File is not of type FileType.FTP"); } if (debug) System.out.println("Succeeded to create XInputFile of Type FTP"); } /** * Get String representation of the object. * * @return String representation of the object */ public String toString() { String s; String name = ftpFile.getName(); name = replaceStringByString(name, "ä", ""); name = replaceStringByString(name, "ö", ""); name = replaceStringByString(name, "ü", ""); name = replaceStringByString(name, "Ä", ""); name = replaceStringByString(name, "Ö", ""); name = replaceStringByString(name, "Ü", ""); name = replaceStringByString(name, "ß", ""); name = replaceStringByString(name, "á", ""); name = replaceStringByString(name, "à", ""); name = replaceStringByString(name, "é", ""); name = replaceStringByString(name, "è", ""); name = replaceStringByString(name, "í", ""); name = replaceStringByString(name, "ì", ""); name = replaceStringByString(name, "ó", ""); name = replaceStringByString(name, "ò", ""); name = replaceStringByString(name, "ú", ""); name = replaceStringByString(name, "ù", ""); s = "ftp://" + ftpVO.getUser() + ":" + ftpVO.getPassword() + "@" + ftpVO.getServer() + ftpVO.getPort(":") + ftpVO.getDirectory() + "/" + name; return s; } /** * @return String, checked of arg1 and replaced with arg2 JDK 1.2.2 * compatibility, replacement of newer String.replaceAll() */ private String replaceStringByString(String name, String arg1, String arg2) { if (name == null) return name; StringBuffer sb = new StringBuffer(name); for (int i = 0; (i = sb.toString().indexOf(arg1, i)) != -1;) sb.replace(i, i + 2, arg2); return sb.toString(); } public void setConstructorParameter(Object obj) { constructorParameter = obj; } public Object getConstructorParameter() { return constructorParameter; } /* * (non-Javadoc) * * @see net.sourceforge.dvb.projectx.xinput.XInputFileIF#getFileType() */ public FileType getFileType() { return fileType; } /** * Get url representation of the object. * * @return String with url */ public String getUrl() { String s = "ftp://" + ftpVO.getUser() + ":" + ftpVO.getPassword() + "@" + ftpVO.getServer() + ftpVO.getPort(":") + ftpVO.getDirectory() + "/" + ftpFile.getName(); return s; } /** * Length of file in bytes. * * @return Length of file in bytes */ public long length() { return ftpFile.getSize(); } /** * Time in milliseconds from the epoch. JDK1.2.2 adaption: Date.getTime() * * @return Time in milliseconds from the epoch */ public long lastModified() { // JDK 1.2.2 going trough Date.getTime(), Time is rounded or 0, but date // seems correct return ftpFile.getTimestamp().getTime().getTime(); // JDK 1.4.2 return value long is not protected //return ftpFile.getTimestamp().getTimeInMillis(); } /** * sets Time in milliseconds from the epoch. * * @return success */ public boolean setLastModified() { return true; //later } /** * Checks if file exists * * @return Result of check */ public boolean exists() { boolean b = false; // This method is more exact, but too expensive // try { // b = true; // inputStream = getInputStream(); // inputStream.close(); // inputStream = null; // } catch (Exception e) { // b = false; // } // If ftpFile is set, it was possible to retrieve it, so the file exists if (ftpFile != null) { b = true; } return b; } /** * Get Name of file * * @return Name of file */ public String getName() { String s = null; s = ftpFile.getName(); s = replaceStringByString(s, "ä", ""); s = replaceStringByString(s, "ö", ""); s = replaceStringByString(s, "ü", ""); s = replaceStringByString(s, "Ä", ""); s = replaceStringByString(s, "Ö", ""); s = replaceStringByString(s, "Ü", ""); s = replaceStringByString(s, "ß", ""); s = replaceStringByString(s, "á", ""); s = replaceStringByString(s, "à", ""); s = replaceStringByString(s, "é", ""); s = replaceStringByString(s, "è", ""); s = replaceStringByString(s, "í", ""); s = replaceStringByString(s, "ì", ""); s = replaceStringByString(s, "ó", ""); s = replaceStringByString(s, "ò", ""); s = replaceStringByString(s, "ú", ""); s = replaceStringByString(s, "ù", ""); return s; } /** * Get Path of parent * * @return Path of parent */ public String getParent() { return ftpVO.getDirectory(); } /** * Get input stream from the file. close() on stream closes XInputFile, too. * * @return Input stream from the file */ public InputStream getInputStream() throws FileNotFoundException, MalformedURLException, IOException { return getInputStream(0L); } /** * Get input stream from the file. close() on stream closes XInputFile, too. * * @return Input stream from the file */ public InputStream getInputStream(long start_position) throws FileNotFoundException, MalformedURLException, IOException { supportsResume = Common.getSettings().getBooleanProperty(Keys.KEY_useFtpServerResume); randomAccessOpen("r"); if (supportsResume) client.setRestartOffset(start_position); //void if (debug) System.out.println("gIS name " + getName()); xIs = new XInputStream(client.retrieveFileStream(ftpFile.getName())); if (debug) System.out.println("gIS retriveStream " + client.getReplyString()); if (!supportsResume) xIs.skip(start_position); xIs.setFtpFile(this); return xIs; } /** * rename this file * * @return success */ public boolean rename() throws IOException { // if (isopen) { throw new IllegalStateException("XInputFile is open!"); } if (isopen) return false; randomAccessOpen("r"); String name = getName(); String newName = null; boolean ret = false; newName = Common.getGuiInterface().getUserInputDialog(name, Resource.getString("autoload.dialog.rename") + " " + getUrl()); if (newName != null && !newName.equals("")) ret = client.rename(name, newName); if (ret) { FTPFile[] aFtpFiles = client.listFiles(); for (int i = 0; i < aFtpFiles.length; i++) if (aFtpFiles[i].getName().equals(newName) && aFtpFiles[i].isFile()) { ftpFile = aFtpFiles[i]; ftpVO.setFtpFile(ftpFile); break; } } randomAccessClose(); return ret; } /** * Opens XInputFile for random access * * @param mode * Access mode as in RandomAccessFile * @throws IOException */ public void randomAccessOpen(String mode) throws IOException { if (isopen) { throw new IllegalStateException("XInputFile is already open!"); } if (mode.compareTo("r") != 0) { throw new IllegalStateException("Illegal access mode for FileType.FTP"); } boolean ret = false; client = new FTPClient(); client.connect(ftpVO.getServer(), ftpVO.getPortasInteger()); //void if (debug) System.out.println("rAO connect " + client.getReplyString()); ret = client.login(ftpVO.getUser(), ftpVO.getPassword()); //bool if (debug) System.out.println("rAO login " + ret + " / " + client.getReplyString()); ret = client.changeWorkingDirectory(ftpVO.getDirectory()); //bool if (debug) System.out.println("rAO cwd " + ret + " / " + client.getReplyString()); ret = client.setFileType(FTP.BINARY_FILE_TYPE); //bool if (debug) System.out.println("rAO binary " + ret + " / " + client.getReplyString()); client.enterLocalPassiveMode(); //void if (debug) System.out.println("rAO PASV " + client.getReplyString()); String[] commands = getUserFTPCommand(); for (int i = 0; i < commands.length; i++) { if (commands[i] != null && commands[i].length() > 0) { client.sendCommand(commands[i]); //bool if (debug) System.out.println("rAO cmd " + client.getReplyString()); } } isopen = true; } /** * @throws java.io.IOException */ public String[] getUserFTPCommand() { StringTokenizer st = new StringTokenizer(Common.getSettings().getProperty(Keys.KEY_FtpServer_Commands), "|"); String[] tokens = new String[st.countTokens()]; for (int i = 0; st.hasMoreTokens(); i++) tokens[i] = st.nextElement().toString().trim(); return tokens; } private boolean EOF() throws IOException { int ret; if (in != null) { ret = in.read(); if (ret < 0) return true; } else if (xIs != null) { ret = xIs.read(); if (ret < 0) return true; } return false; } /** * @throws java.io.IOException */ public void randomAccessClose() throws IOException { if (!isopen) { throw new IllegalStateException("XInputFile is already closed!"); } //no need to abort a transfer explicitly, because we logout here boolean ret = false; if (debug) System.out.println("rAC last " + client.getReplyCode() + " / " + client.getReplyString()); ret = client.isConnected(); if (debug) System.out.println("rAC isCon " + ret + " / " + client.getReplyCode() + " / " + client.getReplyString()); /** * alternative kills the client instance, some server won't abort an incomplete data transfer * (current box-idx 80) */ if (Common.getSettings().getBooleanProperty(Keys.KEY_killFtpClient)) { if (debug) System.out.println("rAC kill "); } /** * standard close of a client connection */ else { if ( !EOF() ) { if (debug) System.out.println("rAC !eof "); ret = client.abort(); if (debug) System.out.println("rAC abort " + ret + " / " + client.getReplyCode() + " / " + client.getReplyString()); } ret = client.logout(); if (debug) System.out.println("rAC logout " + ret + " / " + client.getReplyCode() + " / " + client.getReplyString()); ret = client.isConnected(); if (debug) System.out.println("rAC isCon " + ret + " / " + client.getReplyCode() + " / " + client.getReplyString()); if (ret) { try { client.disconnect(); if (debug) System.out.println("rAC disc " + client.getReplyCode() + " / " + client.getReplyString()); } catch (IOException e) { if (debug) System.out.println("rAC disc-er " + e); } } } in = null; xIs = null; client = null; isopen = false; System.gc(); if (debug) System.out.println("rAC out "); } /** * @param aPosition * The offset position, measured in bytes from the beginning of the * file, at which to set the file pointer. * @throws java.io.IOException */ public void randomAccessSeek(long aPosition) throws IOException { client.setRestartOffset(aPosition); //void if (debug) System.out.println("rAS REST " + client.getReplyString() + " /aP " + aPosition); in = new DataInputStream(client.retrieveFileStream(ftpFile.getName())); if (debug) System.out.println("rAS retriveStream " + client.getReplyString()); } /** * @return @throws * IOException */ public long randomAccessGetFilePointer() throws IOException { return raf.getFilePointer(); } /** * @return @throws * IOException */ public int randomAccessRead() throws IOException { buffer[0] = -1; randomAccessRead(buffer, 0, 1); return (int) buffer[0]; } /** * @param aBuffer * The buffer into which the data is read. * @return @throws * java.io.IOException */ public int randomAccessRead(byte[] aBuffer) throws IOException { return randomAccessRead(aBuffer, 0, aBuffer.length); } /** * @param aBuffer * The buffer into which the data is written. * @param aOffset * The offset at which the data should be written. * @param aLength * The amount of data to be read. * @return @throws * IOException */ public int randomAccessRead(byte[] aBuffer, int aOffset, int aLength) throws IOException { int bytesRead, totalBytes = aOffset; while( (bytesRead = in.read(aBuffer, totalBytes, aLength - totalBytes)) > 0) totalBytes += bytesRead; return bytesRead; } /** * @return Read line * @throws IOException */ public String randomAccessReadLine() throws IOException { return in.readLine(); } /** * @param aBuffer * The data. * @throws java.io.IOException */ public void randomAccessWrite(byte[] aBuffer) throws IOException { throw new IllegalStateException("Illegal access for FileType.FTP"); } /** * Convinience method for a single random read access to a input file. The * file is opened before and closed after read. * * @param aBuffer * Buffer to fill with read bytes (up to aBuffer.length() bytes) * @param aPosition * Fileposition at which we want read * @throws IOException */ public void randomAccessSingleRead(byte[] aBuffer, long aPosition) throws IOException { randomAccessOpen("r"); randomAccessSeek(aPosition); randomAccessRead(aBuffer); randomAccessClose(); } /** * @return Long value read. * @throws java.io.IOException */ public long randomAccessReadLong() throws IOException { return in.readLong(); } // /** * */ public void setStreamInfo(StreamInfo _streamInfo) { streamInfo = _streamInfo; } /** * */ public StreamInfo getStreamInfo() { return streamInfo; } }project-x/src/net/sourceforge/dvb/projectx/xinput/topfield_raw/0000700000175000017500000000000010745203152026433 5ustar supermariosupermarioproject-x/src/net/sourceforge/dvb/projectx/xinput/topfield_raw/RawFileInputStream.java0000600000175000017500000000555310351107146033034 0ustar supermariosupermario/* * @(#)RawFileInputStream.java - alias class definition, may be replaced by * additional disk access * * Copyright (c) 2004-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.xinput.topfield_raw; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; public class RawFileInputStream extends InputStream { private byte[] b = new byte[1]; private String file; private int handle; private long currentpos; private RawReadIF rawread; public RawFileInputStream(RawReadIF rawread, String file) throws FileNotFoundException { this.rawread = rawread; this.file = file; this.handle = rawread.openFile(this.file); currentpos = 0; } public final int read(byte[] b, int off, int len) throws IOException { len = rawread.readFile(handle, b, off, len); currentpos += len; return len; } public final int read(byte[] b) throws IOException { return read(b, 0, b.length); } public final int read() throws IOException { // byte[] b = new byte[1]; is now Attribute of class if (read(b, 0, 1) == 1) return (int) b[0]; else return -1; } public final int available() throws IOException { long avail = streamSize() - currentpos; if (avail > 2 * 1024 * 1024 * 104) return 2 * 1024 * 1024 * 104; else return (int) avail; } public final void mark(int readlimit) { // not implemented } public final void reset() throws IOException { // not implemented } public final boolean markSupported() { return false; } public final long skip(long n) throws IOException { long skipped = rawread.skipBytes(handle, n); currentpos += skipped; return skipped; } //alias required public final long streamSize() throws IOException { return rawread.getFileSize(file); } public final void close() throws IOException { if (handle != 0) rawread.closeFile(handle); handle = 0; } }project-x/src/net/sourceforge/dvb/projectx/xinput/topfield_raw/RawInterface.java0000600000175000017500000000625310351107154031656 0ustar supermariosupermario/* * @(#)RawInterface.java - provides a little interface * * Copyright (c) 2004-2005 by dvb.matt, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.xinput.topfield_raw; import java.io.IOException; import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; import net.sourceforge.dvb.projectx.common.Resource; public class RawInterface { RawReadIF rawRead; long stream_size; String sourcefile; public RawInterface(String aSourceFile) { try { Class rawReadClass = Class.forName("RawRead"); rawRead = (RawReadIF) rawReadClass.newInstance(); sourcefile = aSourceFile; stream_size = 0; } catch (Exception e) { throw new IllegalArgumentException("Can't instantiate RawInterface"); } } public final void add_native_files(ArrayList arraylist) { rawRead.add_native_files(arraylist); } public final String GetLoadStatus() { if (rawRead.AccessEnabled()) return rawRead.GetLoadStatus(); else return null; } /* * true bei tf raw file public boolean isAccessibleDisk(String sourcefile) { * return rawRead.isAccessibleDisk(sourcefile); } */ public final long getFileSize() { return rawRead.getFileSize(sourcefile); } public final String getFileDate() { long datetime = rawRead.lastModified(sourcefile.substring(1)); return DateFormat.getDateInstance(DateFormat.LONG).format(new Date(datetime)) + " " + DateFormat.getTimeInstance(DateFormat.LONG).format(new Date(datetime)); } /* public boolean getScanData(byte data[]) throws IOException { RawFileInputStream rawin = new RawFileInputStream(rawRead, sourcefile); rawin.read(data, 0, data.length); rawin.close(); return true; } */ /* public boolean getData(byte data[], long skip_size, int read_offset, int size) throws IOException { RawFileInputStream rawin = new RawFileInputStream(rawRead, sourcefile); rawin.skip(skip_size); rawin.read(data, read_offset, size); rawin.close(); return true; } */ public final RawFileInputStream getStream() throws IOException { RawFileInputStream rawin = new RawFileInputStream(rawRead, sourcefile); stream_size = rawin.streamSize(); return rawin; } public final long getStreamSize() { return stream_size; } }project-x/src/net/sourceforge/dvb/projectx/xinput/topfield_raw/RawReadIF.java0000600000175000017500000000356210351107164031051 0ustar supermariosupermario/* * @(#)RawREadIF.java - Interface for RawRead to load from the default package * via reflection * * Copyright (c) 2004-2005 by pstorch, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.xinput.topfield_raw; import java.util.ArrayList; public interface RawReadIF { // check DLL load status and errors public String GetLoadStatus(); // directory read functions public int findOpen(String directoryname); public String findNextFile(int findhandle); public int findClose(int findhandle); // file read functions public int openFile(String filename); public int readFile(int filehandle, byte[] array, int offsetinbuffer, int readlen); public int closeFile(int filehandle); public long skipBytes(int filehandle, long skipbytes); public long getFileSize(String filename); public long lastModified(String filename); public void add_native_files(ArrayList arraylist); public boolean AccessEnabled(); }project-x/src/net/sourceforge/dvb/projectx/xinput/topfield_raw/XInputDirectoryImpl.java0000600000175000017500000001131210351107174033234 0ustar supermariosupermario/* * @(#)XInputDirectoryImpl.java - implementation for topfield hd access * * Copyright (c) 2004-2005 by roehrist, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.xinput.topfield_raw; import java.util.ArrayList; import java.util.Iterator; import net.sourceforge.dvb.projectx.xinput.DirType; import net.sourceforge.dvb.projectx.xinput.XInputDirectoryIF; import net.sourceforge.dvb.projectx.xinput.XInputFile; public class XInputDirectoryImpl implements XInputDirectoryIF { private DirType dirType = null; private String testMsg = null; private RawInterface rawInterface = null; /** * Mustn't be used * * @throws UnsupportedOperationException * Because it mustn't be used! */ private XInputDirectoryImpl() { throw new UnsupportedOperationException("Usage is not allowed!"); } /** * Create a XInputDirectory of type DirType.RAW_DIR. * * @param aFtpVO * Directory data to use */ public XInputDirectoryImpl(DirType aDirType) { if (aDirType != DirType.RAW_DIR) { throw new IllegalArgumentException("aDirType is not DirType.RAW_DIR"); } dirType = aDirType; rawInterface = new RawInterface(""); if (!rawInterface.rawRead.AccessEnabled()) { throw new IllegalArgumentException( "Topfield raw disk access is not enabled"); } } /** * Get String representation of the object. * * @return String representation of the object */ public String toString() { return "Topfield raw disk access"; } /** * Get path of directory * * @return Path of directory */ public String getDirectory() { return ""; } /** * Get password for the ftp server * * @return Password for the ftp server * @throws IllegalStateException * If file type of object is not DirType.FTP_DIR */ public String getPassword() { return ""; } /** * Get name or ip address of the ftp server * * @return Name or ip address of the ftp server * @throws IllegalStateException * If file type of object is not DirType.FTP_DIR */ public String getServer() { return ""; } /** * Get port of the ftp server * * @return port of the ftp server * @throws IllegalStateException * If file type of object is not DirType.FTP_DIR */ public String getPort() { return ""; } /** * Get user for the ftp server * * @return User for the ftp server * @throws IllegalStateException * If file type of object is not DirType.FTP_DIR */ public String getUser() { return ""; } /** * Get log of communication with ftp server. * * @return Log of communication with ftp server * @throws IllegalStateException * If file type of object is not DirType.FTP_DIR */ public String getLog() { return ""; } /** * Get files in the directory. * * @return files in the directory */ public XInputFile[] getFiles() { ArrayList arrayList = new ArrayList(); rawInterface.add_native_files(arrayList); XInputFile[] xInputFiles = new XInputFile[arrayList.size()]; int i = 0; for (Iterator it = arrayList.iterator(); it.hasNext();) { xInputFiles[i++] = new XInputFile((String) it.next()); } return xInputFiles; } /** * Test if directory data is valid. * * @return Test successful or not */ public boolean test() { boolean b = false; b = rawInterface.rawRead.AccessEnabled(); testMsg = b ? "Test succeeded" : "Test failed"; return b; } /** * Get result message after test(). * * @return result message after test() */ public String getTestMsg() { return testMsg; } /** * @return Type of XInputDirectory */ public DirType getDirType() { return dirType; } }project-x/src/net/sourceforge/dvb/projectx/xinput/topfield_raw/XInputFileImpl.java0000600000175000017500000002365010351107206032153 0ustar supermariosupermario/* * @(#)XInputFileImpl.java - implementation for topfield hd access * * Copyright (c) 2004-2005 by roehrist, All Rights Reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * 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 * */ package net.sourceforge.dvb.projectx.xinput.topfield_raw; import java.io.EOFException; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.PushbackInputStream; import java.net.MalformedURLException; import net.sourceforge.dvb.projectx.xinput.FileType; import net.sourceforge.dvb.projectx.xinput.XInputFileIF; import net.sourceforge.dvb.projectx.xinput.XInputStream; import net.sourceforge.dvb.projectx.xinput.StreamInfo; public class XInputFileImpl implements XInputFileIF { private boolean debug = false; // Members, which are type independent private FileType fileType = null; private boolean isopen = false; private PushbackInputStream pbis = null; private long randomAccessCurrentPosition = 0; private byte[] buffer = new byte[8]; // Members used for type FileType.RAW private RawInterface rawInterface = null; private String fileName = null; private Object constructorParameter = null; private StreamInfo streamInfo = null; /** * Private Constructor, don't use! */ private XInputFileImpl() { throw new UnsupportedOperationException(); } /** * Create a XInputFile of type FileType.RAW. * * @param aFtpVO * Directory data to use * @param aFtpFile * File data to use */ public XInputFileImpl(String aFileName) { if (debug) System.out.println("Try to create XInputFile of Type RAW"); try { fileName = aFileName; fileType = FileType.RAW; rawInterface = new RawInterface(aFileName); rawInterface.getStream().close(); } catch (IOException e) { throw new IllegalArgumentException("File is not of type FileType.RAW"); } if (debug) System.out.println("Succeeded to create XInputFile of Type RAW"); } /** * Get String representation of the object. * * @return String representation of the object */ public String toString() { return fileName; } public void setConstructorParameter(Object obj) { constructorParameter = obj; } public Object getConstructorParameter() { return constructorParameter; } /* * (non-Javadoc) * * @see net.sourceforge.dvb.projectx.xinput.XInputFileIF#getFileType() */ public FileType getFileType() { return fileType; } /** * Get url representation of the object. * * @return String with url */ public String getUrl() { String s; s = "raw://" + fileName; return s; } /** * Length of file in bytes. * * @return Length of file in bytes */ public long length() { return rawInterface.getFileSize(); } /** * Time in milliseconds from the epoch. * * @return Time in milliseconds from the epoch */ public long lastModified() { return rawInterface.rawRead.lastModified(fileName); } /** * sets Time in milliseconds from the epoch. * * @return success */ public boolean setLastModified() { return true; //later } /** * Checks if file exists * * @return Result of check */ public boolean exists() { boolean b = false; try { rawInterface.getStream().close(); b = true; } catch (IOException e) { b = false; } return b; } /** * Get Name of file * * @return Name of file */ public String getName() { return fileName; } /** * Get Path of parent * * @return Path of parent */ public String getParent() { return ""; } /** * Get input stream from the file. close() on stream closes XInputFile, too. * * @return Input stream from the file */ public InputStream getInputStream() throws FileNotFoundException, MalformedURLException, IOException { return getInputStream(0L); } /** * Get input stream from the file. close() on stream closes XInputFile, too. * * @return Input stream from the file */ public InputStream getInputStream(long start_position) throws FileNotFoundException, MalformedURLException, IOException { XInputStream xIs = new XInputStream(rawInterface.getStream()); xIs.skip(start_position); return xIs; } /** * @return bool * not yet supported */ public boolean rename() throws IOException { return false; } /** * Opens XInputFile for random access * * @param mode * Access mode as in RandomAccessFile * @throws IOException */ public void randomAccessOpen(String mode) throws IOException { if (isopen) { throw new IllegalStateException("XInputFile is already open!"); } if (mode.compareTo("r") != 0) { throw new IllegalStateException("Illegal access mode for FileType.RAW"); } pbis = new PushbackInputStream(getInputStream()); randomAccessCurrentPosition = 0; isopen = true; } /** * @throws java.io.IOException */ public void randomAccessClose() throws IOException { if (!isopen) { throw new IllegalStateException("XInputFile is already closed!"); } if (pbis != null) { try { pbis.close(); } catch (IOException e) { if (debug) System.out.println(e.getLocalizedMessage()); if (debug) e.printStackTrace(); } pbis = null; } randomAccessCurrentPosition = 0; isopen = false; } /** * @param aPosition * The offset position, measured in bytes from the beginning of the * file, at which to set the file pointer. * @throws java.io.IOException */ public void randomAccessSeek(long aPosition) throws IOException { if (aPosition > randomAccessCurrentPosition) { randomAccessCurrentPosition += pbis.skip(aPosition - randomAccessCurrentPosition); } if (aPosition < randomAccessCurrentPosition) { randomAccessClose(); randomAccessOpen("r"); randomAccessCurrentPosition = pbis.skip(aPosition); } } /** * @return @throws * IOException */ public long randomAccessGetFilePointer() throws IOException { return randomAccessCurrentPosition; } /** * @return @throws * IOException */ public int randomAccessRead() throws IOException { buffer[0] = -1; randomAccessRead(buffer, 0, 1); return (int) buffer[0]; } /** * @param aBuffer * The buffer into which the data is read. * @return @throws * java.io.IOException */ public int randomAccessRead(byte[] aBuffer) throws IOException { return randomAccessRead(aBuffer, 0, aBuffer.length); } /** * @param aBuffer * The buffer into which the data is written. * @param aOffset * The offset at which the data should be written. * @param aLength * The amount of data to be read. * @return @throws * IOException */ public int randomAccessRead(byte[] aBuffer, int aOffset, int aLength) throws IOException { int result = 0; result = pbis.read(aBuffer, aOffset, aLength); if (result != -1) { randomAccessCurrentPosition += result; } return result; } /** * @return Read line * @throws IOException */ public String randomAccessReadLine() throws IOException { StringBuffer sb = new StringBuffer(); int ch = 0; do { ch = randomAccessRead(); sb.append(ch); } while ((ch != '\r') && (ch != '\n') && (ch != -1)); sb.deleteCharAt(sb.length() - 1); if (ch == '\r') { ch = randomAccessRead(); if (ch != '\n' && (ch != -1)) { pbis.unread(ch); randomAccessCurrentPosition -= 1; } } return sb.toString(); } /** * @param aBuffer * The data. * @throws java.io.IOException */ public void randomAccessWrite(byte[] aBuffer) throws IOException { throw new IllegalStateException("Illegal access for FileType.RAW"); } /** * Convinience method for a single random read access to a input file. The * file is opened before and closed after read. * * @param aBuffer * Buffer to fill with read bytes (up to aBuffer.length() bytes) * @param aPosition * Fileposition at which we want read * @throws IOException */ public void randomAccessSingleRead(byte[] aBuffer, long aPosition) throws IOException { randomAccessOpen("r"); randomAccessSeek(aPosition); randomAccessRead(aBuffer); randomAccessClose(); } /** * @return Long value read. * @throws java.io.IOException */ public long randomAccessReadLong() throws IOException { long l = 0; int bytesRead = 0; bytesRead = randomAccessRead(buffer, 0, 8); if (bytesRead < 8) { throw new EOFException("Less than 8 bytes read"); } l = ((long) buffer[1] << 56) + ((long) buffer[2] << 48) + ((long) buffer[3] << 40) + ((long) buffer[4] << 32) + ((long) buffer[5] << 24) + ((long) buffer[6] << 16) + ((long) buffer[7] << 8) + buffer[8]; return l; } /** * */ public void setStreamInfo(StreamInfo _streamInfo) { streamInfo = _streamInfo; } /** * */ public StreamInfo getStreamInfo() { return streamInfo; } }