summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COPYING340
-rw-r--r--HISTORY463
-rw-r--r--Makefile416
-rw-r--r--README653
-rw-r--r--black_720x576.mpgbin8815 -> 0 bytes
-rw-r--r--config.c903
-rw-r--r--config.h443
-rwxr-xr-xconfigure450
-rw-r--r--device.c1640
-rw-r--r--device.h268
-rw-r--r--dummy_player.c102
-rw-r--r--dummy_player.h39
-rw-r--r--equalizer.c145
-rw-r--r--equalizer.h36
-rwxr-xr-xexamples/Live Radio/BBC Radio 4 Live.m3u4
-rw-r--r--examples/Live Radio/BBC World Service.ram1
-rw-r--r--examples/remote.conf.example63
-rw-r--r--frontend.c898
-rw-r--r--frontend.h157
-rw-r--r--frontend_local.c469
-rw-r--r--frontend_local.h74
-rw-r--r--frontend_svr.c1977
-rw-r--r--frontend_svr.h143
-rw-r--r--logdefs.c50
-rw-r--r--logdefs.h179
-rw-r--r--media_player.c1346
-rw-r--r--media_player.h127
-rw-r--r--menu.c873
-rw-r--r--menu.h55
-rw-r--r--menuitems.c220
-rw-r--r--menuitems.h104
-rw-r--r--mpg2c.c50
-rw-r--r--nosignal_720x576.mpgbin13195 -> 0 bytes
-rw-r--r--osd.c620
-rw-r--r--osd.h36
-rw-r--r--po/cs_CZ.po651
-rw-r--r--po/de_DE.po650
-rw-r--r--po/fi_FI.po651
-rw-r--r--po/it_IT.po653
-rw-r--r--po/ru_RU.po650
-rw-r--r--setup_menu.c1983
-rw-r--r--setup_menu.h27
-rw-r--r--tools.c24
-rw-r--r--tools/backgroundwriter.h162
-rw-r--r--tools/bitstream.h175
-rw-r--r--tools/cxsocket.c430
-rw-r--r--tools/cxsocket.h195
-rw-r--r--tools/debug_mutex.h206
-rw-r--r--tools/display_message.h73
-rw-r--r--tools/functor.h47
-rw-r--r--tools/functorimpl.h150
-rw-r--r--tools/future.h87
-rw-r--r--tools/general_remote.h27
-rw-r--r--tools/gnome_screensaver.c128
-rw-r--r--tools/gnome_screensaver.h6
-rw-r--r--tools/h264.c224
-rw-r--r--tools/h264.h68
-rw-r--r--tools/http.c434
-rw-r--r--tools/http.h147
-rw-r--r--tools/iso639.h186
-rw-r--r--tools/listiter.h83
-rw-r--r--tools/metainfo_menu.c98
-rw-r--r--tools/metainfo_menu.h38
-rw-r--r--tools/mpeg.c67
-rw-r--r--tools/mpeg.h58
-rw-r--r--tools/pes.c152
-rw-r--r--tools/pes.h120
-rw-r--r--tools/playlist.c1005
-rw-r--r--tools/playlist.h132
-rw-r--r--tools/rle.c171
-rw-r--r--tools/rle.h52
-rw-r--r--tools/rtcp.h134
-rw-r--r--tools/rtp.h100
-rw-r--r--tools/sap.h207
-rw-r--r--tools/sdp.h112
-rw-r--r--tools/time_pts.c172
-rw-r--r--tools/time_pts.h43
-rw-r--r--tools/timer.c288
-rw-r--r--tools/timer.h296
-rw-r--r--tools/ts.c694
-rw-r--r--tools/ts.h167
-rw-r--r--tools/udp_buffer.h144
-rw-r--r--tools/udp_pes_scheduler.c945
-rw-r--r--tools/udp_pes_scheduler.h119
-rw-r--r--tools/vdrdiscovery.c273
-rw-r--r--tools/vdrdiscovery.h81
-rw-r--r--vdrlogo_32x32.c141
-rw-r--r--vdrlogo_720x576.mpgbin22739 -> 0 bytes
-rw-r--r--xine/adjustable_scr.c309
-rw-r--r--xine/adjustable_scr.h37
-rw-r--r--xine/demux_xvdr.c1209
-rw-r--r--xine/demux_xvdr_tsdata.c91
-rw-r--r--xine/demux_xvdr_tsdata.h34
-rw-r--r--xine/osd_manager.c729
-rw-r--r--xine/osd_manager.h36
-rw-r--r--xine/post.c901
-rw-r--r--xine/post.h99
-rw-r--r--xine/post_util.h144
-rw-r--r--xine/ts2es.c262
-rw-r--r--xine/ts2es.h21
-rw-r--r--xine/vo_hook.c201
-rw-r--r--xine/vo_hook.h42
-rw-r--r--xine/vo_osdreorder.c100
-rw-r--r--xine/vo_osdreorder.h16
-rw-r--r--xine/vo_osdscaler.c439
-rw-r--r--xine/vo_osdscaler.h16
-rw-r--r--xine/vo_post.h25
-rw-r--r--xine/vo_props.h60
-rw-r--r--xine/xvdr_metronom.c164
-rw-r--r--xine/xvdr_metronom.h49
-rw-r--r--xine_fbfe_frontend.c316
-rw-r--r--xine_frontend.c1854
-rw-r--r--xine_frontend.h130
-rw-r--r--xine_frontend_internal.h92
-rw-r--r--xine_frontend_lirc.c281
-rw-r--r--xine_frontend_lirc.h19
-rw-r--r--xine_frontend_main.c820
-rw-r--r--xine_input_vdr.c5641
-rw-r--r--xine_input_vdr.h68
-rw-r--r--xine_input_vdr_mrl.h23
-rw-r--r--xine_input_vdr_net.h169
-rw-r--r--xine_osd_command.h157
-rw-r--r--xine_post_audiochannel.c323
-rw-r--r--xine_post_autocrop.c1617
-rw-r--r--xine_post_swscale.c1730
-rw-r--r--xine_sxfe_frontend.c1779
-rw-r--r--xineliboutput.c353
127 files changed, 0 insertions, 47626 deletions
diff --git a/COPYING b/COPYING
deleted file mode 100644
index f90922ee..00000000
--- a/COPYING
+++ /dev/null
@@ -1,340 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/HISTORY b/HISTORY
deleted file mode 100644
index e12f5a52..00000000
--- a/HISTORY
+++ /dev/null
@@ -1,463 +0,0 @@
-VDR Plugin 'xineliboutput' Revision History
--------------------------------------------
-
-????-??-??: Version 1.1.0
-
-- Fixed compilation with gcc-4.4.0 (invalid casts)
-- Added --geometry option to vdr-sxfe
-- Updated logo (Thanks to Stefan Wagner)
-- Implemented demuxer with mpeg-ts support
-- Initial support for vdr-1.7.7
-- Support for multilayer OSD
-- Improved OSD scaling (OSD reacts now immediately to frame size changes)
-- Fixed setting focus in vdr-sxfe fullscreen mode
-- Added Gnome screensaver support to vdr-sxfe (Thanks to Alex Stansfield)
-- Changed the default grab quality to match VDR's documentation.
-- Added sharpness and noise reduction setup options for VDPAU.
-- Added '-C'/'--config' command-line option to specify xine's configuration file.
-- Replaced cIConv with VDR's cCharConv.
-- Supports only for vdr-1.6.0 or later.
-- Added an option to limit number of remote clients
-- Implemented build-time configuration script
-- Replaced build-time options INTERPRET_LIRC_KEYS and FE_TOGGLE_FULLSCREEN
- with run-time option --hotkeys
-- Added an option to adjust the stepping value that is used for
- metronom live mode sync (Thanks to Andreas Auras)
-- Added preliminary SVDRP interface (Thanks to Rolf Ahrenberg)
-- Fixed aspect ratio problems when using ffmpeg mpeg2 decoder
-- H.264 updates
-- Added an option to use xine-lib DVB subtitles decoder
-
-2009-02-12: Version 1.0.4 (branch-1_0_x)
-Backported bugfixes from CVS trunk:
-- Updated Italian translations (Thanks to Diego Pierotto)
-- Fixed default grab quality (Thanks to Jochen Dolze, patch #2454827)
-- Added math library (-lm) to vdr-sxfe when building with
- Xrender / HUD OSD support (Thanks to Anssi Hannula)
-- Reduced H.264 logging
-- Fixed CD track count query
-- Fixed mrl backwards compability
-
-2008-10-24: Version 1.0.3 (branch-1_0_x)
-Backported bugfixes from CVS trunk:
-- Added missing sxfe display locks (Thanks to Antti Seppälä)
-- Modified HUD OSD scaling parameters (Thanks to Rolf Ahrenberg)
-- Fixes to HUD OSD drawing (Thanks to Rolf Ahrenberg)
-- Fixed --aspect=auto:path_to_script option (Thanks to Armin Diedering)
-- Fixed playing first track of audio CD (requires xine-lib 1.1.5)
-- OS X build fixes (Thanks to Tero Siironen)
-- Updated finnish translations (Thanks to Rolf Ahrenberg)
-- Updated Italian translations (Thanks to Diego Pierotto)
-
-2008-10-04: Version 1.0.2 (branch-1_0_x)
-Backported bugfixes from CVS trunk:
-- Fixed segfault when committing uninitialized OSD (Thanks to Rolf Ahrenberg)
-- Fixed buffer errors when switching from HD channel to SD channel
-- Fixed selecting DVD subtitles language from DVD menus
-- Fixed setting DVD subtitles preferred language
-- Fixed missing VDR OSD while playing DVDs
-- Fixed DVD menu navigation when menu is not in title 0
-- Fixed infinite loop when trying to replay unaccessible DVD
-- Fixed infinite loop when trying to play only one unacessible or very short music file
-- Fixed replaying images from network sources (http://, ...) (Thanks to Rolf Ahrenberg)
-- Fixed segfault when media file meta info contains thumbnails (Thanks to Petri Helin)
-- Fixed smooth trickspeed setup menu entry with VDR-1.5.10+ (Thanks to Timo Eskola)
-- Fixed vdr-sxfe icon in 64-bit systems
-- Fixed updating window title when protocol is part of mrl
-- Fixed German translation for "Play DVD disc >>" (Thanks to Helmar Gerloni)
-- Increased timeout when opening media files from network sources (Thanks to Tobias Grimm)
-- OS X build fixes (Thanks to Tero Siironen)
-- xine-lib 1.2 updates
-- Added WM class hint ("VDR") to vdr-sxfe windows (Thanks to Rolf Ahrenberg)
-
-2008-05-07: Version 1.0.1
-
-- Fixed freezes while zapping and/or seeking
-- Added metainfo menu to media player (Petri Helin)
-
-2008-04-14: Version 1.0.0
-- Added Italian translations (Thanks to Diego Pierotto)
-- Added Czech translations (Thanks to Maya)
-- Added HUD OSD (Blend OSD using graphics hardware) and --hud command-line option.
- (Thanks to Antti Seppälä and Rolf Ahrenberg)
-- Added support for libextractor metadata parsing library (Petri Helin)
-- Added service interface for launching media player (Suggested by Tobias Grimm)
-- Added configuration options for unsharp and denoise3d post plugins (Petri Helin)
-- Fixed the case when watching image files and the first one just flashes and
- gets replaced by black image (Petri Helin)
-- Added support for VDR 1.5.x and 1.6.0
-- Dropped legacy code for vdr-1.3.x
-- Added support for xine-lib up to 1.1.11.1
-- Added support for xine-lib 1.2 hg branch
-- Changed mrl syntax from xvdr[:proto]:// to xvdr[+proto]://
-- Added video softwarwe scaling support
-- Added non-linear 4:3 -> 16:9 "smart" scaling
-- Added configure option for video aspect ratio (Petri Helin)
-- Added media player options for enabling or disabling metainfo types, metainfo
- scanner and metainfo caching (Petri Helin)
-- Added support for smooth fast forward (Thanks to Timo Eskola)
-- Added setup option to limit trick speed
-- Removed support for arts audio output
-- Added setup option to change external subtitle (.sub/.srt) font size
-- Added command-line option for binding to specific local interface address
-- Initial support for H.264 video
-- Support for HD-resolution OSD (Petri Helin). Requires patched vdr.
-- Increased local frontend initialization timeout (Thanks to Mikko Vartiainen)
-- Removed configuration option to disable OSD downscaling
-- Improved media player playlist handling and menu (Petri Helin)
-- Fixed DVD menu domain detection (Petri Helin)
-- Fixed DVD title and chapter information shown on the OSD (Petri Helin)
-- Improved key mappings for audio player (Petri Helin)
-- Allow users to add single files to playlist as well as whole directories (Petri Helin)
-- Fixed "TCP fifo full" problem
-- Added hotkeys for audio delay (Thanks to Timo Eskola)
-- Enabled streaming of external subtitle files for remote frontends
-- Added support for multithreaded video decoding. Auto-detect number of CPUs.
-- Show address of current VDR server in X title bar
-- Added support to control HW aspect ratio with external script
-- Added support to output video and OSD to existing X11 window
-- Allow fine-tuning of SCR (should reduce frame drops/duplications and make video smoother)
-- Support using ffmpeg mpeg2 video decoder instead of libmpeg2 decoder
-- Improved PTS warp detection
-- Restore DPMS state at exit
-- Fixed sxfe window position when returning from fullscreen mode (Thanks to Timo Eskola)
-
-2007-05-17: Version 1.0.0rc2
-
-- Workaround for xine-lib demux_mpeg_block PTS wrap issue
- (this should fix daily picture freezes)
-- Support for denoise3d and unsharp post plugins (Thanks to Petri Helin)
-- Fixed media player random play kNext (next file) handling (Thanks to Petri Helin)
-- Fixed media player MsgReplaying status messages (Thanks to Petri Helin)
-- Fixed closing DVD player with Back key (Thanks to Petri Helin)
-- Improved media player resume file creation
-- Fixed UDP segfault
-- Mac OS X build fixes (Thanks to Tero Siironen)
-- Updated remote.conf example
-- Added support for xine-lib software volume control
- (useful with digital audio output)
-- Removed (unused) decoder priority setting
-- Fixed yuy2 frame grabbing
-- Adapted for xine-lib 1.1.5
-- Added vdr-sxfe fullscreen and de-interlace toggling with lirc keys
- "Fullscreen" and "Deinterlace"
-
-2007-03-17: Version 1.0.0rc1
-
-- PLUGIN HOMEPAGE CHANGED
-
-- Fixed audio CD replay (cdda:/)
-- Adapted for xine-lib 1.1.4
-- Adapted for vdr-1.5.1 (Thanks to Rolf Ahrenberg)
-- Mac OS X compability fixes (Thanks to Tero Siironen)
-- DXR3 added to list of output devices (experimental; Thanks to Ville Skyttä)
-- Subtitle selection menu updated to use VDR audio menu skin
-- New subtitle macro key handling (identical to VDR kAudio)
-- Added preferred subtitle language selection for media player
-- Updated trick speed modes and still image handling
-- Remote mode can now survive longer network delays
-- Fixed tvtime options (Thanks to Petri Helin)
-- Fixed using video driver "none"
-- Simple "slave mode" for remote frontends
-- Added automatic re-connection to remote frontends (--reconnect option)
-- Slow down DVD drive speed
-- Initialize video size from stream info when playing slave streams,
- (Thanks to Antti Seppälä)
-- Makefile shell scripts modified to run in dash (Ubuntu).
- (Thanks to realKano@directbox.com)
-- Increased frame-based buffering time after channel changes
-- Use iconv to translate id3 tags from utf8 to VDR charset
-- Use /dev/dsp as OSS default device (Thanks to Ville Skyttä)
-- Lot of small fixes and enhancements, complete log in CVS
-
-2007-01-07: Version 1.0.0pre7
-
-- Added possibility to add files to playlist
-- Added playlist menu to media player
-- Added "Play Audio CD" / "Play remote Audio CD" entry to plugin menu
-- Makefile modified to allow overriding default directory environment.
- Using "install" to install files. (Thanks to Timo Weingärtner)
-- Added metainfo caching to media player. Cached metainfo is stored to
- ".xineliboutput-playlist.m3u" files by default.
-- Added support for playlists inside playlists
- (ex. http://.../?.pls entries in playlists)
-- Added playlist HTTP download support to playlists (curl required)
-- lirc forwarding updated (synced with vdr-1.4.3-2): added re-connecting to lircd.
-- Lirc forwarding key repeat fixed (Thanks to Timo Ruottinen).
-- Display metainfo (ID3 etc) instead of file name in (audio)player
-- Fixed deadlock in audio post plugin loading and wiring
- (in some cases plugins were loaded multiple times)
-- Fixed buffer overflow problems in xineliboutput device polling
-- Fixed buffer overflow problems in UDP packet scheduler queue
-- Several new media file types added to media player
-- Subtitle type .ssa added
-- Parsing for .pls, .asx and .ram playlists added
-- Eliminated some warnings when compiling to 64bit (Thanks to Anssi Hannula)
-- Vidix(fb) added to supported video drivers (Thanks to Antti Seppälä)
-- Media player/audio file browser does not anymore show video files
-- When replaying music files, replay moves to next file automatically
-- Decoder setup menu moved to Local setup menu
- (decoder settings have effect on local frontend only)
-- Implemented simple RTSP streaming support (rtsp://vdr-host:xineliboutput-port/)
-- Implemented simple HTTP streaming support (http://vdr-host:xineliboutput-port/)
-- Fixed control channel disconnection detection in frontend_svr.c
-- Media player: Try to detect when navigating in DVD menus and change
- functions of Up/Down/Left/Right/Ok/Back keys when in menus
-- Added RFC2974 SAP (Session Announcement Protocol) implementation
-- Now using RFC3550 RTP headers when multicasting
-
-2006-10-20: Version 1.0.0pre6
-
-- Display Audio track languages when replaying DVDs
-- Display DVD SPU track language names instead track numbers
-- Improved shortcut key support
-- Fixed garbage in bottom of image when using autocrop
-- Fixed SCR tunning when only one TCP/PIPE client
-- Fixed unscaled OSD scaling to display size when low-resolution video or
- different aspect ratio
-- Allow overriding default startup image
-- German translations (Thanks to Udo Richter)
-- Setup menu re-arranged
-- Command-line given post plugin parameters are never changed at runtime
-- Added string length checks to several places
-- Added missing frame buffer device selection
-- Support for ffmpeg post processing
-- Easier configuration for tvtime post plugin in menu
-- Autoplay list support for xine (patch from sf feature request #1561688)
-- Removed busy loop from vdr-fbfe/vdr-sxfe when console was unavailable
-
-2006-09-17: Version 1.0.0pre5
-
-- Allow overriding default no signal image
-- Several fixes to post plugin handling
-- Fixed --audio=driver:port parsing in vdr plugin
-- Fixed overscan when image does not fill whole output window
- (bug #1556912)
-- Implemented simple MMX/SSE and YUY2 detection routines
- to autocrop
-- Main menu re-arranged (Thanks to Petri Helin)
-- Fixed display blanking aspect ratio (bug #1554070)
-- Lirc receiver accepts shorter LIRC commands (bug #1540896)
-- Fixed immediate re-configuration when setup entries are
- changed with repeated keys (Thanks to Petri Helin)
-- Implemented audio channel selection as xine post plugin
- (to select only left or right channel from stereo)
-- Several minor fixes / enhancements to autocrop plugin
-
-2006-09-06: Version 1.0.0pre4
-
-- WARNING: updated command-line options !
-- Support for HD (larger buffers with HD content)
-- Simple playlist support to media player
-- Fixed starting replay of new file while old file is still playing
-- Fixed segfault in OSD downscaling
-- Added SPU track selection for DVDs without menu
-- Forcing order and location of video filter post plugins
- autocrop and tvtime in post plugin chain
-- Fixed replaying some older VDR recordings (video PID != 0xE0)
- (Reported by Petri Helin)
-- Fixed deadlock when closing xine input plugin and threads
- in TCP mode (reported by Tobias Grimm)
-- Fixed wrong XKeySym remote learning trigger when using fbfe
- (reported by Voitto Tuomainen)
-- Minor updates to playlists and file replay OSD handling
-- Added trick speed modes (forward only) to DVD player
-- Improved X11 fullscreen <-> window mode switching
-- Improved display blanking: blank image is now generated using
- last seen video frame size and aspect ratio. This should reduce
- OSD resizings and re-positioning when switching channels.
-
-2006-08-25: Version 1.0.0pre3
-
-- Fixed segfault when grabbing with remote-only frontends
-- Configurable speaker configuration and spdif passthru
-- Support for playlists (.m3u or whole directory) in media player
-- Separate menu item for playing music
-- Configuration options for letterbox cropping
-- Added audio visualization support for media files
- (originally supported only with DVB radio)
-- Implemented image grabbing for remote frontends
-- Fixed restoring primary device when using tcp transport
-- Executing primary device switching in main thread context
-- Added configurable overscan option (%) to crop frame borders
- when using displays without overscan
-
-2006-08-16: Version 1.0.0pre2
-
-- Xine plugins and frontends are not installed automatically.
- (Suggested by Udo Richter).
-- Added support for AC3 passthrough (thanks to Petri Helin)
-- Automatic 4:3 letterbox to 16:9 cropping pre-version
-- Added daemon mode to stand-alone frontends
-- Removed possible busy loop from lirc receiver thread
-- New localized texts
-- Fixed local media player when remote server is active and there are no clients
-- Option for audio-only playback (discards video)
-- Fixed DVD navigation in local mode (Thanks to Petri Helin)
-- Completed simple playlist support
- (play all media files in folder ; play .m3u playlist)
-
-2006-07-23: Verson 1.0.0pre1
-
-- Added DVD playback and navigation support to media player
-- Added support for DVD subtitles in VDR recordings
-- Fixed audio surround mode (Thanks to Petri Helin)
-- Added option to disable keyboard input in vdr-fbfe and vdr-sxfe
- (required when running as daemon)
-- Fixed OSD updating, closing and re-scaling under high system load
-
-2006-07-05: Version 0.99
-
-- Finished implementing audio stream switching
-- Improved VDR server detection and refused connection handling
-- Added option to close VDR when local frontend window is closed
-- Added always-on-top mode, window title and icon to vdr-sxfe
-
-2006-06-12: Version 0.99rc5
-- OSD endian problems fixed
-- More x64 fixes (Thanks to Anssi Hannula)
-- Better TCP and PIPE disconnection detection
-- Fixed possible race conditions in xine input plugin
-- Fixed image player (reported by Petri Helin)
-- Improved (?) X11 fullscreen mode
-- X11 fullscreen mode can be toggled by double-clicking window
-
-2006-06-03: Version 0.99rc4
-
-- Fixed missing audio after trick speed modes (thanks to Tero Saarni)
-- Fixed fullscreen size detection with frame buffer / DirectFB
-- Added unscaled OSD capability check for framebuffer / DirectFB
-
-2006-06-02: Version 0.99rc3
-
-- OSD is scaled to display resolution instead of video resolution
- when using unscaled OSD
-- OSD is re-centered when resolution is slighty different from 720x576
-- Added configuration options for multicast parameters (address, port, TTL)
-- Added option to set multicast transmission always on for third-party
- clients (vlc, ...)
-- Some new x64 fixes
-- Several configuration menu fixes
-- Fixed compilation problem with xine-lib < 1.1.2
-- Fixed missing audio after trick speed modes (thanks to Tero Saarni)
-
-2006-05-18: Version 0.99rc2
-
-- Fixed control input deadlock when using xine-ui
-- Experimental automatic primary device mode included
-- Fixed remote frontend keyboard handling for escape sequences
-- Added several new command-line options to stand-alone frontends
-- Adapted for vdr 1.4.0
-- Fixed automatic server discovery
-- Fixed fullscreen mode when screen resolution != 720x576
-- Fixed --local=none option (reported by Ulf Betlehem)
-- Faster channel switching
-- Fixed --post option
-- Fixed several endian problems and byte ordering in network modes
- (reported by Carsten Rietzschel)
-- Fixed segmentation fault when frontend was executed from path
- (reported by Carsten Rietzschel)
-- Fixed amd64 compilation problems (reported by Voitto Tuomainen)
-- Many finnish menu texts updated (patch provided by Rolf Ahrenberg)
-- Socket option SO_REUSEADDR added to several places to speed
- up VDR restart
-
-2006-04-08: Version 0.99rc
-
-- Fixed compilation problems with gcc 3.4.5 (timer.h, osd.c).
- (reported by Gavin Hamill and Voitto Tuomainen)
-- Suspend mode removed (it is now implemented only as separate plugin)
-- Fixed X11 keyboard input handling
-- Faster seeks and channel switches in udp and rtp streaming modes
-- Fixed disconnection when playing to end of avi file
-- Fixed multi-speed modes (reported by Vladimir Monchenko)
-- Updated russian translations (thanks to Vladimir Monchenko)
-- Pipe transport fixed
-
-2006-03-28: Version 0.99pre
-
-- Russian translations (thanks to Vladimir Monchenko)
-- New de-interlacing methods and options
-- Updated for vdr 1.3.43
-- Support for xine post-processing plugins
-- Stand-alone frontends can now automatically find
- vdr (xineliboutput) server from network.
-- Makefile modified to auto-detect vdr.
- If vdr is not installed, only stand-alone frontends and
- xine plugin are compiled.
- (use "make frontends" in plugin source directory)
-- Xine plugin is automatically copied to xine's plugin directory
- instead of statically linking it to frontends.
- -> any xine frontend can be used.
-- All logging goes to syslog and honors vdr's logging level
-
-2005-11-22: Version 0.4
-
-- Updated for xine-lib 1.1.0 and 1.1.1
-- Framebuffer and DirectFB frontend is now tested and working.
-- Remote frontends tested and working (TCP/UDP/RTP).
-- README updated.
-- Frontend is now loaded dynamically if needed.
- VDR part of plugin is not anymore linked against xine-lib and X11.
- -> plugin itself can be compiled and used without installing xine
- and/or X11 to VDR machine.
- Frontends still need X11 and/or xine-lib.
-- Makefile modified to auto-detect xine-lib and X11.
- If X11 is not installed, only framebuffer frontend is compiled.
- If xine-lib is not installed, frontends are not compiled (-> only
- remote frontends can be used).
-- Updated for vdr 1.3.34
-- Stand-alone frontends (sxfe and fbfe) can now forward lirc keys to VDR.
-- New command-line parameters: frontend type, video driver and audio driver.
-- Command-line parameters now override saved configuration parameters.
-
-- Updated for xine-lib 1.0.1
-
-2005-02-17: Version 0.3
-
-- Updated for vdr 1.3.19 and xine-lib 1.0
-- Direct playback of all xine-supported media types
- (+ automatic loading of external .srt/.sub subtitles)
-- Support for http/rtsp network streams
-- Image viewer
-- New configuration options
-- Improved OSD support for low-resolution video
-- OSD performance optimizations
-- Improved X server detection
-- Support for xxmc output driver
-- Support for DVB radio streams
-- Support for audio visualization plugins
-
-2004-08-19: Version 0.2
-
-- Tested with VDR versions 1.2.6, 1.3.7 and 1.3.12
-- Modified to compile with xine-lib 1.0.0 (rc4)
-- New configuration options
-- Decoder can be stopped manually or using inactivity timer
-- Support for image grabbing
-- Support for localization (i18n)
-
-2003-12-20: Version 0.1
-
-- Modified to compile with xine-lib 1.0.0 (rc2)
-- Support for Xshm, Xv and XvMC.
-- Audio driver and port can be selected (alsa,oss,...)
-- X11 display location configurable (in setup.conf,
- OSD menu or usind DISPLAY environment variable)
-- Support for unscaled OSD (requires XShape X server extension)
-- Support for deinterlacing
-- Multiple bug fixes
-- Many new configuration options
-- Support for DVD plugin (GetSTC)
-- Support for VDR Make.config
-
-2003-09-10
-
-- C Compilation problems fixed
-- OSD scaling fixed
-
-2003-05-23: Version 0.0.0
-
-- Initial revision.
-
-
diff --git a/Makefile b/Makefile
deleted file mode 100644
index d6467da8..00000000
--- a/Makefile
+++ /dev/null
@@ -1,416 +0,0 @@
-#
-# Makefile for a Video Disk Recorder plugin
-#
-# See the main source file 'xineliboutput.c' for copyright information and
-# how to reach the author.
-#
-# $Id: Makefile,v 1.86 2009-06-02 08:49:32 phintuka Exp $
-#
-
-# The official name of this plugin.
-# This name will be used in the '-P...' option of VDR to load the plugin.
-# By default the main source file also carries this name.
-
-PLUGIN = xineliboutput
-
-_default: all
-
-
-# check for Apple Darwin
-ARCH_APPLE_DARWIN = no
-ifeq ($(shell gcc -dumpmachine | grep -q 'apple-darwin' && echo "1" || echo "0"), 1)
- ARCH_APPLE_DARWIN = yes
-endif
-
-#
-# Override configuration here or in ../../../Make.config
-#
-
-#NOSIGNAL_IMAGE_FILE=/usr/share/vdr/xineliboutput/nosignal.mpv
-#STARTUP_IMAGE_FILE=/usr/share/vdr/xineliboutput/logodisplay.mpv
-XINELIBOUTPUT_CONFIGURE_OPTS =
-
-
-###
-### The version number of this plugin (taken from the main source file):
-###
-
-VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | cut -d'"' -f2)
-
-
-###
-### The C++ compiler and options:
-###
-
-CXX ?= g++
-CC ?= gcc
-OPTFLAGS ?=
-
-ifeq ($(ARCH_APPLE_DARWIN), yes)
- CXXFLAGS ?= -O3 -pipe -Wall -Woverloaded-virtual -fPIC -g -fno-common -bundle -flat_namespace -undefined suppress
- CFLAGS ?= -O3 -pipe -Wall -fPIC -g -fno-common -bundle -flat_namespace -undefined suppress
- LDFLAGS_SO ?= -fvisibility=hidden
-else
- CXXFLAGS ?= -O3 -pipe -Wall -Woverloaded-virtual -fPIC -g
- CFLAGS ?= -O3 -pipe -Wall -fPIC -g
- LDFLAGS_SO ?= -shared -fvisibility=hidden
-endif
-
-###
-### The directory environment:
-###
-
-VDRDIR ?= ../../..
-LIBDIR ?= ../../lib
-TMPDIR ?= /tmp
-BINDIR ?= /usr/bin
-DESTDIR ?= /
-
-INSTALL ?= install
-
-VDRINCDIR ?= $(VDRDIR)/include
-
-###
-### Allow user defined options to overwrite defaults:
-###
-
--include $(VDRDIR)/Make.config
--include Make.config
-
-
-###
-### check for VDR
-###
-
-ifeq ($(ARCH_APPLE_DARWIN), yes)
- VDRVERSION = $(shell sed -ne '/define VDRVERSION/s/^.*"\(.*\)".*$$/\1/p' $(VDRDIR)/config.h)
- APIVERSION = $(shell sed -ne '/define APIVERSION/s/^.*"\(.*\)".*$$/\1/p' $(VDRDIR)/config.h)
-else
- VDRVERSION = $(shell sed -ne '/define VDRVERSION/ { s/^.*"\(.*\)".*$$/\1/; p }' $(VDRDIR)/config.h)
- APIVERSION = $(shell sed -ne '/define APIVERSION/ { s/^.*"\(.*\)".*$$/\1/; p }' $(VDRDIR)/config.h)
-endif
-
-ifeq ($(strip $(VDRVERSION)),)
- $(warning ********************************************************)
- $(warning VDR not detected ! VDR plugin will not be compiled. )
- $(warning ********************************************************)
- CONFIGURE_OPTS += --disable-vdr
-else
- ifeq ($(strip $(APIVERSION)),)
- $(warning VDR APIVERSION missing, using VDRVERSION $(VDRVERSION) )
- APIVERSION = $(VDRVERSION)
- endif
- CONFIGURE_OPTS += --add-cflags=-I$(VDRDIR)
-endif
-
-
-###
-### run configure script
-###
-
-config.mak: Makefile configure
- @echo Running configure
- @sh configure --cc=$(CC) --cxx=$(CXX) $(CONFIGURE_OPTS) $(XINELIBOUTPUT_CONFIGURE_OPTS)
--include config.mak
-
-###
-### The name of the distribution archive:
-###
-
-ARCHIVE = $(PLUGIN)-$(VERSION)
-PACKAGE = vdr-$(ARCHIVE)
-
-
-###
-### The name of executable and libraries
-###
-
-VDRPLUGIN = libvdr-$(PLUGIN).so
-VDRPLUGIN_SXFE = lib$(PLUGIN)-sxfe.so
-VDRPLUGIN_FBFE = lib$(PLUGIN)-fbfe.so
-VDRSXFE = vdr-sxfe
-VDRFBFE = vdr-fbfe
-XINEINPUTVDR = xineplug_inp_xvdr.so
-XINEPOSTAUTOCROP = xineplug_post_autocrop.so
-XINEPOSTSWSCALE = xineplug_post_swscale.so
-XINEPOSTAUDIOCHANNEL = xineplug_post_audiochannel.so
-
-###
-### which programs and libs to build
-###
-
-TARGETS_VDR =
-TARGETS_FE =
-TARGETS_XINE =
-ifeq ($(XINELIBOUTPUT_VDRPLUGIN), yes)
- TARGETS_VDR += $(VDRPLUGIN)
-endif
-ifeq ($(XINELIBOUTPUT_XINEPLUGIN), yes)
- TARGETS_XINE += $(XINEINPUTVDR) $(XINEPOSTAUTOCROP) $(XINEPOSTSWSCALE) $(XINEPOSTAUDIOCHANNEL)
-endif
-ifeq ($(XINELIBOUTPUT_X11), yes)
- TARGETS_FE += $(VDRSXFE)
- ifeq ($(XINELIBOUTPUT_VDRPLUGIN), yes)
- TARGETS_VDR += $(VDRPLUGIN_SXFE)
- endif
-endif
-ifeq ($(XINELIBOUTPUT_FB), yes)
- TARGETS_FE += $(VDRFBFE)
- ifeq ($(XINELIBOUTPUT_VDRPLUGIN), yes)
- TARGETS_VDR += $(VDRPLUGIN_FBFE)
- endif
-endif
-
-
-###
-### Includes and Defines (add further entries here):
-###
-
-INCLUDES += -I$(VDRINCDIR)
-
-ifeq ($(ARCH_APPLE_DARWIN), yes)
- INCLUDES += -I/sw/include
- LIBDIRS += -L/sw/lib
- LIBS += $(LIBDIRS)
-else
- LIBS += -lrt
-endif
-
-DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' \
- -D_REENTRANT -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \
- -DXINELIBOUTPUT_VERSION='"$(VERSION)"'
-
-ifdef NOSIGNAL_IMAGE_FILE
- DEFINES += -DNOSIGNAL_IMAGE_FILE='"$(NOSIGNAL_IMAGE_FILE)"'
-endif
-ifdef STARTUP_IMAGE_FILE
- DEFINES += -DSTARTUP_IMAGE_FILE='"$(STARTUP_IMAGE_FILE)"'
-endif
-
-
-###
-### The object files (add further files here):
-###
-
-# VDR plugin
-OBJS = $(PLUGIN).o device.o frontend.o osd.o config.o menu.o setup_menu.o \
- menuitems.o media_player.o equalizer.o \
- frontend_local.o frontend_svr.o \
- tools/cxsocket.o tools/udp_pes_scheduler.o \
- tools/backgroundwriter.o tools/playlist.o tools/http.o \
- tools/vdrdiscovery.o tools/time_pts.o tools.o \
- tools/metainfo_menu.o logdefs.o tools/rle.o
-OBJS_MPG = black_720x576.o nosignal_720x576.o vdrlogo_720x576.o
-
-# frontends
-OBJS_FE_SO = xine_frontend.o logdefs.o \
- xine/post.o xine/vo_hook.o xine/vo_osdscaler.o xine/vo_osdreorder.o \
- tools/rle.o
-OBJS_FE = $(OBJS_FE_SO) tools/vdrdiscovery.o xine_frontend_main.o xine_frontend_lirc.o
-
-OBJS_SXFE_SO = xine_sxfe_frontend.o $(OBJS_FE_SO)
-OBJS_SXFE = xine_sxfe_frontend.o $(OBJS_FE)
-OBJS_FBFE_SO = xine_fbfe_frontend.o $(OBJS_FE_SO)
-OBJS_FBFE = xine_fbfe_frontend.o $(OBJS_FE)
-
-ifneq ($(HAVE_DBUS_GLIB_1), no)
-OBJS_SXFE += tools/gnome_screensaver.o
-OBJS_SXFE_SO += tools/gnome_screensaver.o
-endif
-
-# xine plugins
-OBJS_XINEINPUTVDR = xine_input_vdr.o xine/demux_xvdr.o \
- xine/ts2es.o xine/demux_xvdr_tsdata.o \
- xine/adjustable_scr.o xine/xvdr_metronom.o xine/osd_manager.o \
- tools/rle.o tools/ts.o tools/pes.o tools/mpeg.o tools/h264.o
-
-OBJS_XINE = $(OBJS_XINEINPUTVDR) xine_post_autocrop.o xine_post_swscale.o xine_post_audiochannel.o
-
-###
-### Implicit rules:
-###
-
-%.o: %.c
- $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $(CFLAGS_VDR) -o $@ $<
-
-
-###
-### Dependencies:
-###
-
-MAKEDEP = g++ -MM -MG
-DEPFILE = .dependencies
-$(DEPFILE): Makefile config.mak
- @rm -f $@
- @for i in $(OBJS:%.o=%.c) $(OBJS_SXFE:%.o=%.c) $(OBJS_FBFE:%.o=%.c) $(OBJS_XINE:%.o=%.c) ; do \
- $(MAKEDEP) $(DEFINES) $(INCLUDES) -MT "`dirname $$i`/`basename $$i .c`.o" $$i >>$@ ; \
- done
-
--include $(DEPFILE)
-
-DEFINES += -Wall
-
-
-###
-### Rules:
-###
-
-mpg2c: mpg2c.c
- $(CC) mpg2c.c -o $@
-
-# data
-black_720x576.c: mpg2c black_720x576.mpg
- @./mpg2c black black_720x576.mpg black_720x576.c
-nosignal_720x576.c: mpg2c nosignal_720x576.mpg
- @./mpg2c nosignal nosignal_720x576.mpg nosignal_720x576.c
-vdrlogo_720x576.c: mpg2c vdrlogo_720x576.mpg
- @./mpg2c vdrlogo vdrlogo_720x576.mpg vdrlogo_720x576.c
-
-# C code (xine plugins and frontends)
-$(sort $(OBJS_SXFE) $(OBJS_FBFE) $(OBJS_XINE)):
- $(CC) $(CFLAGS) -c $(DEFINES) $(INCLUDES) $(CFLAGS_X11) $(OPTFLAGS) -o $@ $<
-
-### Internationalization (I18N):
-
-PODIR = po
-LOCALEDIR ?= $(VDRDIR)/locale
-I18Npo = $(wildcard $(PODIR)/*.po)
-I18Nmsgs = $(addprefix $(LOCALEDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file))))))
-I18Npot = $(PODIR)/$(PLUGIN).pot
-
-%.mo: %.po
- msgfmt -c -o $@ $<
-
-$(I18Npot): $(wildcard *.c)
- xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --msgid-bugs-address='<phintuka@users.sourceforge.net>' -o $@ $^
-
-%.po: $(I18Npot)
- msgmerge -U --no-wrap --no-location --backup=none -q $@ $<
- @touch $@
-
-$(I18Nmsgs): $(LOCALEDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
- @mkdir -p $(dir $@)
- cp $< $@
-
-.PHONY: i18n
-i18n: $(I18Nmsgs)
-
-###
-### targets
-###
-
-XINELIBOUTPUT_INSTALL_MSG = \
- $(warning *********************** xineliboutput ***************************) \
- $(warning Xine plugins and frontends will not be installed automatically. ) \
- $(warning To install files execute "make install" in ) \
- $(warning $(shell echo `pwd`)) \
- $(warning *****************************************************************)
-
-install : XINELIBOUTPUT_INSTALL_MSG =
-
-.PHONY: all
-all: config $(TARGETS_VDR) frontends i18n
-
-frontends: config $(TARGETS_FE) $(TARGETS_XINE)
- $(XINELIBOUTPUT_INSTALL_MSG)
-
-config: config.mak
-
-.PHONY: config
-
-.PHONY: frontends install dist clean
-
-#
-# VDR plugin
-#
-
-$(VDRPLUGIN): $(OBJS) $(OBJS_MPG)
- $(CXX) $(CXXFLAGS) $(LDFLAGS_SO) $(OBJS) $(OBJS_MPG) $(LIBS) $(LIBS_VDR) -o $@
- @-rm -rf $(LIBDIR)/$@.$(APIVERSION)
- @cp $@ $(LIBDIR)/$@.$(APIVERSION)
-
-#
-# vdr-sxfe
-#
-
-$(VDRPLUGIN_SXFE): $(OBJS_SXFE_SO)
- $(CC) $(CFLAGS) $(LDFLAGS_SO) $(OBJS_SXFE_SO) $(LIBS_X11) $(LIBS_XINE) -o $@
- @-rm -rf $(LIBDIR)/$(VDRPLUGIN_SXFE).$(VERSION)
- @cp $@ $(LIBDIR)/$(VDRPLUGIN_SXFE).$(VERSION)
-$(VDRSXFE): $(OBJS_SXFE)
- $(CC) -g $(OBJS_SXFE) $(LIBS_X11) $(LIBS_XINE) -o $@
-
-#
-# vdr-fbfe
-#
-
-$(VDRPLUGIN_FBFE): $(OBJS_FBFE_SO)
- $(CC) $(CFLAGS) $(LDFLAGS_SO) $(OBJS_FBFE_SO) $(LIBS_XINE) -o $@
- @-rm -rf $(LIBDIR)/$(VDRPLUGIN_FBFE).$(VERSION)
- @cp $@ $(LIBDIR)/$(VDRPLUGIN_FBFE).$(VERSION)
-$(VDRFBFE): $(OBJS_FBFE)
- $(CC) -g $(OBJS_FBFE) $(LIBS_XINE) -o $@
-
-#
-# xine plugins
-#
-
-$(XINEINPUTVDR): $(OBJS_XINEINPUTVDR)
- $(CC) $(CFLAGS) $(LDFLAGS_SO) $(LIBS_XINE) -o $@ $(OBJS_XINEINPUTVDR)
-$(XINEPOSTAUTOCROP): xine_post_autocrop.o
- $(CC) $(CFLAGS) $(LDFLAGS_SO) $(LIBS_XINE) -o $@ $<
-$(XINEPOSTSWSCALE): xine_post_swscale.o
- $(CC) $(CFLAGS) $(LDFLAGS_SO) $(LIBS_XINE) -o $@ $<
-$(XINEPOSTAUDIOCHANNEL): xine_post_audiochannel.o
- $(CC) $(CFLAGS) $(LDFLAGS_SO) $(LIBS_XINE) -o $@ $<
-
-#
-# install
-#
-
-install: all
-ifeq ($(XINELIBOUTPUT_XINEPLUGIN), yes)
- @mkdir -p $(DESTDIR)/$(XINEPLUGINDIR)/post
- @echo Installing $(DESTDIR)/$(XINEPLUGINDIR)/$(XINEINPUTVDR)
- @-rm -rf $(DESTDIR)/$(XINEPLUGINDIR)/$(XINEINPUTVDR)
- @$(INSTALL) -m 0644 $(XINEINPUTVDR) $(DESTDIR)/$(XINEPLUGINDIR)/$(XINEINPUTVDR)
- @echo Installing $(DESTDIR)/$(XINEPLUGINDIR)/post/$(XINEPOSTAUTOCROP)
- @-rm -rf $(DESTDIR)/$(XINEPLUGINDIR)/post/$(XINEPOSTAUTOCROP)
- @$(INSTALL) -m 0644 $(XINEPOSTAUTOCROP) $(DESTDIR)/$(XINEPLUGINDIR)/post/$(XINEPOSTAUTOCROP)
- @echo Installing $(DESTDIR)/$(XINEPLUGINDIR)/post/$(XINEPOSTSWSCALE)
- @-rm -rf $(DESTDIR)/$(XINEPLUGINDIR)/post/$(XINEPOSTSWSCALE)
- @$(INSTALL) -m 0644 $(XINEPOSTSWSCALE) $(DESTDIR)/$(XINEPLUGINDIR)/post/$(XINEPOSTSWSCALE)
- @echo Installing $(DESTDIR)/$(XINEPLUGINDIR)/post/$(XINEPOSTAUDIOCHANNEL)
- @-rm -rf $(DESTDIR)/$(XINEPLUGINDIR)/post/$(XINEPOSTAUDIOCHANNEL)
- @$(INSTALL) -m 0644 $(XINEPOSTAUDIOCHANNEL) $(DESTDIR)/$(XINEPLUGINDIR)/post/$(XINEPOSTAUDIOCHANNEL)
-endif
-ifeq ($(XINELIBOUTPUT_FB), yes)
- @echo Installing $(DESTDIR)/$(BINDIR)/vdr-fbfe
- @mkdir -p $(DESTDIR)/$(BINDIR)
- @-rm -rf $(DESTDIR)/$(BINDIR)/vdr-fbfe
- @$(INSTALL) -m 0755 vdr-fbfe $(DESTDIR)/$(BINDIR)/vdr-fbfe
-endif
-ifeq ($(XINELIBOUTPUT_X11), yes)
- @echo Installing $(DESTDIR)/$(BINDIR)/vdr-sxfe
- @mkdir -p $(DESTDIR)/$(BINDIR)
- @-rm -rf $(DESTDIR)/$(BINDIR)/vdr-sxfe
- @$(INSTALL) -m 0755 vdr-sxfe $(DESTDIR)/$(BINDIR)/vdr-sxfe
-endif
-
-dist: clean
- @-rm -rf $(TMPDIR)/$(ARCHIVE)
- @mkdir $(TMPDIR)/$(ARCHIVE)
- @cp -a * $(TMPDIR)/$(ARCHIVE)
- @tar czf $(PACKAGE).tgz --exclude=CVS -C $(TMPDIR) $(ARCHIVE)
- @-rm -rf $(TMPDIR)/$(ARCHIVE)
- @echo Distribution package created as $(PACKAGE).tgz
-
-
-clean:
- @-rm -f $(DEPFILE) *.so* *.o *.tgz core* *~ *.flc *.bak \
- tools/*.o tools/*~ tools/*.flc xine/*.o xine/*~ \
- xine/*.flc $(VDR_FBFE) $(VDR_SXFE) mpg2c black_720x576.c \
- nosignal_720x576.c vdrlogo_720x576.c vdr-sxfe vdr-fbfe \
- $(PODIR)/*.mo $(PODIR)/*.pot \
- features.h config.mak configure.log
-
diff --git a/README b/README
deleted file mode 100644
index d2d01f0b..00000000
--- a/README
+++ /dev/null
@@ -1,653 +0,0 @@
-This is a "plugin" for the Video Disk Recorder (VDR).
-
-Written by: Petri Hintukainen <phintuka@users.sourceforge.net>
-
-Project's homepage: http://www.sourceforge.net/projects/xineliboutput
-
-Latest version available at: http://prdownloads.sourceforge.net/xineliboutput/
-
-
-See the file COPYING for license information.
-
-
-Description
-
- X11 and Linux framebuffer front-end for VDR.
- Plugin displays video and OSD in X/Xv/XvMC window,
- Linux framebuffer/DirectFB/vidixfb or DXR3 card.
-
- Support for local and remote frontends.
-
- Built-in image and media player supports playback of most known
- media files (avi/mp3/divx/jpeg/...), DVDs and radio/video streams
- (http, rtsp, ...) directly from VDR.
-
-
-Requirements
-
- - vdr-1.6.0 or later (use "1.0.x" branch for older vdr versions)
- (vdr is required only at server side)
- - xine-lib 1.1.1 or later
- (xine-lib is not required for server in network-only usage)
- - Enough CPU power and memory to decode streams
- (PII 400Mhz + 64M should be enough with Xv or DirectFB)
-
- Optional:
-
- - X server with Composite and Xrender extensions,
- compositing window manager or composite manager (xcompmgr).
- (Required for HUD OSD to blend high-quality OSD using graphics hardware)
- - libextractor 0.5.20 or later (http://libextractor.sourceforge.net).
- (used for media file metadata extraction in media player)
- - libjpeg for grabbing in JPEG format
-
-WARNING
-
- Remote (network) mode should be used only in firewalled
- environment; it gives anyone full control to VDR !
-
- Full access is allowed to all hosts listed in svdrphosts.conf.
-
- Multicast streaming can flood your internet connection and/or
- wireless LAN. If there is no router (or intelligent switch ?)
- all multicast packets will be broadcasted to all network links.
- This will flood slow network links:
- - Internet connection if outgoing bandwith is < 10 Mbit/s
- - Wireless LAN (11 or 54 Mbit/s).
- By default multicast TTL is set to 1 so multicast packets should
- be stopped to first router regardless of network configuration.
-
-
-Public CVS
-
- Latest fixes are available from sourceforge.net public CVS
- (http://sourceforge.net/cvs/?group_id=160063).
-
- CVS checkout command:
- cvs -d:pserver:anonymous@xineliboutput.cvs.sourceforge.net:/cvsroot/xineliboutput co vdr-xineliboutput
-
-
-Buildtime options
-
- VDR, X11 and xine-lib are auto-detected by the build system.
- By default all possible plugins and executables are build.
-
- Default configuration can be overridden by running configure
- script manually. List of all configurable features can be
- acquired by running
-
- ./configure --help
-
- For long-time use it is preferred to set configure options
- in Make.config file. Make.config is first read from VDR source
- directory and then from xineliboutput plugin source directory.
-
- Basic Make.config entries:
-
- enable/disable building of VDR plugin:
- XINELIBOUTPUT_CONFIGURE_OPTS += --enable-vdr / --disable-vdr
-
- enable/disable X11 frontends:
- XINELIBOUTPUT_CONFIGURE_OPTS += --enable-x11 / --disable-x11
-
- enable/disable framebuffer frontends:
- XINELIBOUTPUT_CONFIGURE_OPTS += --enable-fb / --disable-fb
-
- enable/disable xine (input)plugin:
- XINELIBOUTPUT_CONFIGURE_OPTS += --enable-libxine / --disable-libxine
-
- It is possible to compile only remote frontends with command
- "make frontends". Building frontends is possible without VDR.
- Only xine-lib and corresponding development package or headers
- are required.
-
-
-Installing - IMPORTANT
-
- XINE'S DYNAMIC LIBRARIES AND FRONTEND EXECUTABLES ARE NOT
- INSTALLED AUTOMATICALLY.
-
- It is important to copy required libraries to right place
- either by hand or by executing "make install" in plugin's
- source directory.
- Installing binaries and libraries usually requires root
- permissions.
-
- PLUGIN WILL NOT WORK UNLESS ALL FILES HAVE BEEN INSTALLED !
-
- To be able to use remote frontends each client's IP address
- must be defined in VDR's svdrphosts.conf.
- Full access is allowed to all hosts listed in svdrphosts.conf.
- Connections from any other hosts are rejected.
-
-
-Usage examples (VDR plugin)
-
- If no arguments are given, both X11 and framebuffer frontends are tried.
- First working frontend is used with best available video driver.
- Complete list of available command-line arguments can be obtained
- with "vdr --help".
-
- Only local frontend, X11/Xv video, alsa audio:
- vdr -P"xineliboutput --local=sxfe --video=xv --audio=alsa --remote=none"
-
- Only local frontend, (slow) X11 video, oss audio:
- vdr -P"xineliboutput --local=sxfe --video=xshm --audio=oss --remote=none"
-
- Only local frontend, DirectFB:
- vdr -P"xineliboutput --local=fbfe --video=DirectFB --remote=none"
-
- Only remote frontend(s):
- vdr -P"xineliboutput --local=none --remote=37890"
-
- Local and remote frontends:
- vdr -P"xineliboutput --local=sxfe --remote=37890"
- or
- vdr -P"xineliboutput --local=fbfe --remote=37890"
-
-
-Using remote frontends
-
- Two remote frontends are included, vdr-fbfe for framebuffer and
- vdr-sxfe for X11.
- Complete list of available command-line arguments can be obtained
- with "vdr-??fe --help".
-
- Frontend should find server automatically (from local subnet)
- and negotiate best available transport. If frontend does not
- find server (or specific transport should be used), mrl must
- be given on command line.
-
- Examples:
-
- Search for VDR (xineliboutput) server, connect to it and
- negotiate best available transport. Use best available audio
- and video driver.
- vdr-fbfe
- or
- vdr-sxfe
-
- Connect to 192.168.1.3 default port and negotiate best available transport
- vdr-fbfe xvdr://192.168.1.3
-
- Connect to 192.168.2.100, port 12550 and use TCP transport
- vdr-fbfe xvdr+tcp://192.168.2.100:12550
-
- Automatically search for VDR server and use UDP transport
- vdr-fbfe xvdr+udp:
- or
- vdr-fbfe --udp
-
- Available transports for video/audio
- pipe Use local pipe; server and front-end must be running on
- same machine.
- rtp Use RTP/UDP multicast for data and TCP for control.
- Multiple frontends can receive same stream.
- udp Use UDP unicast for data and TCP for control.
- tcp Use TCP protocol for control and data. Both channels
- use same server port and are opened by client.
-
- Forwarding lirc keys to server
- Use option --lirc with optional lircd socket name to
- forward LIRC commands from client to server.
-
- Audio driver
- Use alsa:
- vdr-fbfe --audio alsa
- Use alsa (and specific card/sub-device):
- vdr-fbfe --audio alsa:plughw:1,1
-
- Video driver (and display / device):
- With X11 frontend (vdr-sxfe):
- vdr-sxfe --video [xshm | xv | xvmc | xxmc | vidix | vdpau |
- XDirectFB | opengl | sdl | none [:display]]
- Examples:
- --video xv
- --video xvmc:127.0.0.1:1.0
-
- With framebuffer frontend (vdr-fbfe):
- vdr-fbfe --video [fb | DirectFB | sdl | vidixfb | dxr3 | aadxr3 | none [:fb_device]]
- Examples:
- --video DirectFB
- --video fb:/dev/fb/1
- --video vidixfb
- --video aadxr3
-
- De-interlacing
- If deinterlacing post plugin options are not given at command line,
- deinterlacing is controlled by VDR plugin configuration menu settings.
-
- De-interlacing can also be forced on or off with command-line option --post tvtime.
- Examples:
- vdr-sxfe --post tvtime:method=Linear,cheap_mode=1,pulldown=0,use_progressive_frame_flag=1
- vdr -P"xineliboutput --post=tvtime:method=Linear,cheap_mode=1,pulldown=0,use_progressive_frame_flag=1"
- Disable deinterlacing:
- vdr-sxfe --post tvtime:enable=0
-
-
-VDPAU
-
- All video scaling, cropping, and postprocessing options must be disabled
- if the VDPAU output device is used.
- De-interlacing can be enabled with command-line option --post tvtime:
- Examples:
- vdr-sxfe --video vdpau --post tvtime:method=use_vo_driver
- vdr -P"xineliboutput --video=vdpau --post=tvtime:method=use_vo_driver"
-
-
-HUD OSD
-
- HUD OSD implements high-quality OSD using modern graphics hardware.
- OSD is scaled and blended using hardware, so it adds no extra CPU
- overhead. OSD is always blended to output (display) resolution,
- so it remains sharp and detailed even with low-resolution video.
-
- HUD OSD must be enabled with command-line option (--hud). Scaling
- options can be configured in xineliboutput plugin setup menu,
- OSD settings page.
-
- Requirements:
- - X server with Composite and Xrender extensions.
- Composite extension must be enabled in Xorg config.
- - Composite window manager (compiz, beryl, or properly configured xfce4, metacity, ...)
- or separate composite manager (xcompmgr).
- - Compatible graphics hardware and drivers.
- HUD OSD has been tested with:
- nVidia GF FX5700LE (driver version 169.09)
- Intel G965 (GMA-X3000) (driver version 2.2.1, textured XVideo)
-
- metacity 2.23.2
- xcompmgr 1.1.3
-
- NOTE:
- - Drawing video (even without OSD) may be slower when composite
- extension is enabled.
-
- - Try to adjust OSD size and offsets to get rid of possible graphical
- corruption.
-
- - For true HD-resolution OSD VDR needs to be patched.
-
- HUD OSD was contributed by Antti Seppälä and Rolf Ahrenberg.
-
-
-Using with xine-ui (xine, fbxine, gxine, ...)
-
- Examples:
- xine "xvdr://127.0.0.1#nocache"
- xine "xvdr+tcp://127.0.0.1:37890#nocache"
- xine "xvdr+udp://127.0.0.1:37890#nocache"
-
- "#nocache" should always be appended to end of mrl.
-
- Remote mode must be enabled in VDR plugin.
-
- Some configuration options are not available when using
- third-party frontends.
-
-
-Using with other media players (mplayer, vlc, ...)
-
- Primary device video and audio (without OSD or subtitles)
- can be streamed from plugin control port to almost any media
- player using http or rtsp.
-
- Session Announcement Protocol (SAP) compatible players
- should detect stream automatically and add it to playlist
- or bookmarks when RTP transmission is active (tested with vlc).
-
- Tested players:
-
- Linux: mplayer, vlc, xine
- Windows: vlc
-
- Examples:
-
- mplayer http://192.168.1.3:37890
- vlc http://192.168.1.3:37890
- vlc rtsp://192.168.1.3:37890
- vlc rtp://@224.0.1.9:37890
-
-
-Controlling VDR
-
- With local frontend, vdr-sxfe and vdr-fbfe:
-
- Keyboard input from console is mapped to VDR keyboard input.
- If VDR was compiled or configured without keyboard support,
- console keyboard input does not work.
-
- Keyboard input from X11 window is mapped to XKeySym remote.
- Keys are mapped to VDR keys in remote.conf file. Simple example
- of X11 key mappings is included in examples directory.
-
- It should be possible to use VDR's remote controller learning
- mode by pressing some key just after VDR has been started.
- Learning mode does not work with remote frontends.
-
- Keyboard input can be disabled in configuration menu. There
- are separate entries for local and remote frontends.
-
- With xine-ui:
-
- Keyboard shortcuts and remote events from xine menus are
- automatically forwarded to VDR and translated to VDR keys.
- Translation to VDR keys is static and defined in xine_input_vdr.c.
-
-
-Frontend key bindings
-
- Esc Close frontend (vdr-fbfe / fdr-sxfe)
-
- Mouse left button double-click
- Toggle between fullscreen / window mode (vdr-sxfe only)
-
- Mouse right button click
- Toggle between normal window / always on top /
- borderless window (vdr-sxfe only)
-
- Close Window
- Close frontend (fdr-sxfe only)
-
-
-Image viewer key bindings
-
- Left/Prev Previous image
- Right/Next Next image
- Up/Down Jump 5 images forward/backward
- Yellow Delete current image
- Back Return to image list
- Stop/Blue Exit image viewer
- Play Start slide show
- Pause Stop slide show
- FastFwd/FastRew Start slide show; Increase/decrease slide show speed;
- Change slideshow direction
- Ok Toggle replay display mode
-
-Media player key bindings for video files
-
- Back Return to file list
- Red Open playlist if more than one file in the playlist,
- otherwise jump to beginning of file
- Green Jump 1 min back
- Yellow Jump 1 min forward
- Stop/Blue Stop replay
- User7 Random play / normal play
- 1, User8 Jump 20 s back
- 3, User9 Jump 20 s forward
- 2 Move subtitles up
- 5 Move subtitles down
- Down/Pause Pause replay
- Up/Play Play
- Ok Toggle replay display mode
- Next Skip to next file when replaying playlist
- Prev Skip to previous file when replaying playlist
- FastRew/Left Play slower
- FastFwd/Right Play faster
-
-Media player key bindings for audio files
-
- Back Return to file list
- Red Open playlist
- Green Jump 1 min back
- Yellow Jump 1 min forward
- Stop/Blue Stop replay
- 0...9 Use to select a file from the playlist
- according to its position on the playlist
- Down/Pause Pause replay
- Up/Play Play
- Ok Toggle replay display mode
- Next/Right Skip to next file
- Prev/Left Skip to previous file or restart the currently playing file
- if more than three seconds has been played back already
- FastRew/FastFwd Play faster/slower
- User7 Random play / normal play
-
- If media file includes multiple subtitles (DVD, .mkv file, ...),
- subtitle language can be selected with VDR Subtitle key or from
- DVD subtitle menu.
- Plugin uses VDR's preferred subtitle language settings.
-
-DVD player key bindings
-
- Up/Down/Left/Right/Ok/Back DVD menu navigation when DVD menu is active
- Red Access DVD menu(s)
- Green Jump 1 min back
- Yellow Jump 1 min forward
- Stop/Blue/Back Stop replay
- Ok / Info Toggle replay display mode
- 1 / User8 Jump 20 s back
- 3 / User9 Jump 20 s forward
- Pause / Down Pause replay
- Play / Up Play
- 6 / Next, Next chapter
- 4 / Prev Previous chapter
- 9 Next title
- 7 Previous title
- Info Show progress display
- FastRew/FastFwd,
- Left/Right Play faster/slower
-
-
-DVD playback
-
- DVD images
-
- Media player supports playing DVDs directly from hard disk.
- Found DVD folders are marked with 'D' in media player
- file list.
- Plugin detects folders as DVDs if there is file
- Name_Of_DVD/VIDEO_TS/VIDEO_TS.IFO.
-
- It is also possible to replay DVD as VDR recording by
- creating empty recording directory and renaming or
- symlinking .VOBs of selected title to 00?.vdr files.
- DVD menus (VTS_??_0.VOB) should _not_ be copied.
- Audio can be selected from main menu just as with normal
- VDR recordings.
- For seeking it is necessarily to create index.vdr file
- with genindex or similar tool.
-
- DVD discs
-
- "Real" DVD discs (accessible from /dev/dvd) can be played
- from xineliboutput plugin menu.
-
- In case of remote frontend (vdr-sxfe/vdr-fbfe) DVD drive
- of _remote client_ is used.
-
- Audio track can be selected from VDR audio track menu
- (keys "Menu" + "Green" or "Audio") or from DVD menu.
-
- DVD subtitle language can be selected with VDR Subtitle key or
- from DVD subtitle menu.
- Plugin uses VDR's preferred subtitle language settings.
-
-
-Aspect ratio setting
-
- default Aspect ratio is calculated from display resolution.
-
- 4:3 4:3 video is scaled to fill whole window;
- 16:9 video has black bars at top and bottom
-
- 16:9 16:9 video is scaled to fill whole window;
- 4:3 video has black bars at left and right.
-
- 16:10
-
- auto 4:3 and 16:9 are scaled to fill whole window.
- (useful if TV can "smart scale" 4:3 video to 16:9)
-
-
-Shortcut key macros
-
- It is possible to change some settings and execute actions with
- user-defined key macros and VDR User? keys.
-
- Supported settings and corresponding key sequences in VDR
- keymacros.conf format are:
-
- Start replaying DVD (User? @xineliboutput Red 0)
- Start replaying Title 1 from DVD (User? @xineliboutput Red 1)
- <reserved> (User? @xineliboutput Red 2)
- Toggle aspect ratio (User? @xineliboutput Red 3)
- Toggle letterbox -> 16:9 cropping (User? @xineliboutput Red 4)
- Toggle stereo -> 5.1 upmix (User? @xineliboutput Red 5)
- Toggle 5.1 -> surround downmix (User? @xineliboutput Red 6)
- Toggle de-interlacing (User? @xineliboutput Red 7)
- Toggle local frontend on/off (User? @xineliboutput Red 8)
- Start replaying default playlist or file pointed by symlink
- $(CONFDIR)/plugins/xineliboutput/default_playlist
- (User? @xineliboutput Red 9)
- Increase audio delay (User? @xineliboutput Red Up)
- Decrease audio delay (User? @xineliboutput Red Down)
- Toggle the video aspect ratio (User? @xineliboutput Red Right)
-
-
-Special frontend control keys
-
- When frontend is started with --hotkeys command-line option, following
- keyboard and LIRC keys are interpreted by vdr-sxfe/vdr-fbfe:
-
- Keyboard (console and X11 window)
- f, F Toggle fullscreen state
- d, D Toggle deinterlacing
-
- LIRC
- Fullscreen Toggle fullscreen state
- Deinterlace Toggle deinterlacing
- Quit Close program
-
- [ this run-time option replaces old build-time options
- INTERPRET_LIRC_KEYS and XINELIBOUTPUT_FE_FULLSCREEN_TOGGLE ]
-
-
-Xine-specific settings
-
- All xine-specific settings can be changed by editing file
- $(HOME)/.xine/config_xineliboutput.
-
- Default mpeg2 decoder (libmpeg2) can be switched to ffmpeg mpeg2 decoder
- by increasing ffmpeg decoder priority:
-
- engine.decoder_priorities.ffmpegvideo:1
-
- (ffmpeg decoder is slower but handles errors better).
-
-
-Slave mode
-
- vdr-sxfe and vdr-fbfe implement simple slave mode. Slave mode is
- activated with command-line option --slave. In slave mode program reads
- CRLF-terminated commands from standard input instead of using keyboard
- as VDR remote controller. Supported commands are:
-
- HITK <vdrkey> Send key press event to VDR
- FULLSCREEN Toggle fullscreen state
- DEINTERLACE Toggle deinterlacing
- QUIT Close program
-
- Video can be drawn to existing X11 window with vdr-sxfe
- option --wid=<x_window_id>
-
-
-Distributed set-up - multiple clients and/or servers
-
- Simple multi-head setup
-
- When there is no need to watch different recordings / channels at
- different clients at the same time, just running vdr-[sx/fb]fe at
- each client is enough. In this case the same video + OSD is mirrored
- to all clients and all clients control the same (shared) VDR.
-
- Real multi-user setup
-
- When there is a need to have multiple independently controlled
- clients (each with separate video and OSD), running multiple
- instances of VDR is required.
- It doesn't matter if all VDR instances run at server or at each
- client. However, there are some benefits when running all
- instances of VDR on the same server:
- - less maintenance: only one installation of VDR and plugins is required
- - posibility to use simpler, diskless clients with less memory
- - Faster cutting / DVD burning / ... as there is no
- network between VDR and disks
- - no need to export and mount /video to every client
- - overall resource usage is lower
- - ...
-
- It is preferred to allow recording only at the "master" vdr.
- Recording the same timer on two VDR instances will most likely
- corrupt the recording. Besides that, doing all recordings directly
- from DVB card (no streamdev in middle) makes things simpler and less
- error prone. It is probably even impossible to do several recordings
- from different transponders using single streamdev instance.
-
- Timersync plugin disables recording on client VDRs. All timers
- are still visible at each client and timers can be created/modified
- at any client just as with the single VDR setup.
- Timersync plugin synchronizes all timer modifications between VDR instances
- and takes care that all recordings are made by the "master" vdr.
- Still, all kind of autotimer plugins etc. that generate timers
- should be activated only at server vdr (there shouldn't
- be any reasons to run multiple instances of such plugins).
-
- Simplified example:
- (xinelibout and streamdev plugins required)
-
- Start 3 VDRs at server:
-
- "Master" VDR: controls all DVB cards, does all recordings,
- server for client 1
-
- vdr -c /etc/vdr \
- -P"xineliboutput --local=none --remote=37890" \
- -Pstreamdev-server
-
- VDR server for client 2:
-
- vdr -c /etc/vdr2 \
- -D 10 -p 2102 \
- -P"xineliboutput --local=none --remote=37892" \
- -Pstreamdev-client
-
- VDR server for client 3
-
- vdr -c /etc/vdr3 \
- -D 10 -p 2103 \
- -P"xineliboutput --local=none --remote=37894" \
- -Pstreamdev-client
-
- + all possible other options and plugins.
-
- - Using -D 10 option for client VDR instances "forces" all DVB
- cards for master VDR.
- - Each VDR instance must have its own configuration directory (-c option).
- - Each xineliboutput server uses different port
- - Streamdev plugin is used to provide live view for client
- VDR's. It is not required to just watch recordings.
- To correctly configure vdr-streamdev plugin, see
- streamdev plugin's README.
- - Using suspendoutput plugin with some proper timeout value
- in VDR instances might be good idea - it releases
- streamdev VTP connection and server-side DVB devices
- for other use when the client is not in use.
-
- Starting clients:
-
- Client 1: vdr-sxfe
-
- Client 2: vdr-sxfe xvdr://<server ip>:37892
-
- Client 3: vdr-sxfe xvdr://<server ip>:37894
-
- - If RTP is used between vdr and vdr-sxfe, using separate
- RTP address or port for each xineliboutput server
- instance might be good idea.
-
-
-VDR Logo
-
- The VDR logo was designed by Jan Grell.
-
diff --git a/black_720x576.mpg b/black_720x576.mpg
deleted file mode 100644
index 1d466be0..00000000
--- a/black_720x576.mpg
+++ /dev/null
Binary files differ
diff --git a/config.c b/config.c
deleted file mode 100644
index 02556cb5..00000000
--- a/config.c
+++ /dev/null
@@ -1,903 +0,0 @@
-/*
- * config.c: User settings
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: config.c,v 1.82 2009-05-31 15:30:07 phintuka Exp $
- *
- */
-
-#include "features.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-
-#include <vdr/config.h>
-#include <vdr/videodir.h>
-#include <vdr/device.h>
-#include <vdr/i18n.h>
-
-#include "logdefs.h"
-#include "config.h"
-
-#define STRN0CPY(dst, src) \
- do { \
- strn0cpy(dst, src, sizeof(dst)); \
- if(strlen(src) >= sizeof(dst)) \
- LOGMSG("WARNING: Setting %s truncated to %s !", Name, dst); \
- } while(0)
-
-
-#define DEFAULT_DEINTERLACE_OPTS "method=Linear,cheap_mode=1,pulldown=0,use_progressive_frame_flag=1"
-
-const int config_t::i_pesBufferSize[ PES_BUFFERS_count+1 ] = {
- 0, 50, 250, 500, 1000, 2000, 500
-};
-
-const char * const config_t::s_bufferSize[ PES_BUFFERS_count+1 ] = {
- trNOOP("custom"),
- trNOOP("tiny"),
- trNOOP("small"),
- trNOOP("medium"),
- trNOOP("large"),
- trNOOP("huge"),
- NULL
-};
-
-const char * const config_t::s_aspects[ ASPECT_count+1 ] = {
- trNOOP("automatic"),
- trNOOP("default"),
- "4:3",
- "16:9",
- "16:10",
- trNOOP("Pan&Scan"),
- trNOOP("CenterCutOut"),
- NULL
-};
-
-const char * const config_t::s_vo_aspects[ VO_ASPECT_count+1 ] = {
- trNOOP("automatic"),
- trNOOP("square"),
- "4:3",
- trNOOP("anamorphic"),
- trNOOP("DVB"),
- NULL
-};
-
-
-const char * const config_t::s_deinterlaceMethods[ DEINTERLACE_count+1 ] = {
- "none",
- "bob",
- "weave",
- "greedy",
- "onefield",
- "onefield_xv",
- "linearblend",
- "tvtime",
- NULL
-};
-
-const char * const config_t::s_deinterlaceMethodNames[ DEINTERLACE_count+1 ] = {
- trNOOP("off"),
- "Bob",
- "Weave",
- "Greedy",
- "One Field",
- "One Field XV",
- "Linear Blend",
- "TvTime",
- NULL
-};
-
-const char * const config_t::s_fieldOrder[ FIELD_ORDER_count+1 ] = {
- trNOOP("normal"),
- trNOOP("inverted"),
- NULL
-};
-
-const char * const config_t::s_audioDrivers[ AUDIO_DRIVER_count+1 ] = {
- "auto", "alsa", "oss", "none", "esd", "jack",
- NULL
-};
-
-const char * const config_t::s_audioDriverNames[ AUDIO_DRIVER_count+1 ] = {
- trNOOP("automatic"),
- "Alsa",
- "OSS",
- trNOOP("no audio"),
- "ESD",
- "Jack",
- NULL
-};
-
-const char * const config_t::s_videoDriversX11[ X11_DRIVER_count+1 ] = {
- "auto", "xshm", "xv", "xvmc", "xxmc", "vidix", "XDirectFB", "opengl", "sdl", "none",
- NULL
-};
-
-const char * const config_t::s_videoDriverNamesX11[ X11_DRIVER_count+1 ] = {
- trNOOP("automatic"),
- "XShm",
- "Xv",
- "XvMC",
- "XvMC+VLD",
- "Vidix",
- "XDirectFB",
- "OpenGL",
- "SDL",
- trNOOP("no video"),
- NULL
-};
-
-const char * const config_t::s_videoDriversFB[ FB_DRIVER_count+1 ] = {
- "auto", "fb", "DirectFB", "sdl", "vidixfb", "aadxr3", "none",
- NULL
-};
-
-const char * const config_t::s_videoDriverNamesFB [ FB_DRIVER_count+1 ] = {
- trNOOP("automatic"),
- "Framebuffer",
- "DirectFB",
- "SDL",
- "VidixFB",
- "DXR3",
- trNOOP("no video"),
- NULL
-};
-
-const char * const config_t::s_frontends[ FRONTEND_count+1 ] = {
- "sxfe", "fbfe", "none",
- NULL
-};
-
-const char * const config_t::s_frontendNames[ FRONTEND_count+1 ] = {
- "X11 (sxfe)",
- "Framebuffer (fbfe)",
- trNOOP("Off"),
- NULL
-};
-
-const char * const config_t::s_frontend_files[ FRONTEND_count+1 ] = {
- "lib" PLUGIN_NAME_I18N "-sxfe.so." XINELIBOUTPUT_VERSION,
- "lib" PLUGIN_NAME_I18N "-fbfe.so." XINELIBOUTPUT_VERSION,
- // example: libxineliboutput-sxfe.so.0.4.0
- "",
- NULL
-};
-
-const char * const config_t::s_audioEqNames[ AUDIO_EQ_count+1 ] = {
- "30 Hz", "60 Hz", "125 Hz", "250 Hz", "500 Hz",
- "1 kHz", "2 kHz", "4 kHz", "8 kHz", "16 kHz",
- NULL
-};
-
-const char * const config_t::s_audioVisualizations[ AUDIO_VIS_count+1 ] = {
- "none", "goom", "oscope", "fftscope", "fftgraph",
- NULL
-};
-
-const char * const config_t::s_audioVisualizationNames[ AUDIO_VIS_count+1 ] = {
- trNOOP("Off"),
- trNOOP("Goom"),
- trNOOP("Oscilloscope"),
- trNOOP("FFT Scope"),
- trNOOP("FFT Graph"),
- NULL
-};
-
-/* xine, audio_alsa_out.c */
-const char * const config_t::s_speakerArrangements[ SPEAKERS_count+1 ] = {
- trNOOP("Mono 1.0"), trNOOP("Stereo 2.0"), trNOOP("Headphones 2.0"), trNOOP("Stereo 2.1"),
- trNOOP("Surround 3.0"), trNOOP("Surround 4.0"), trNOOP("Surround 4.1"),
- trNOOP("Surround 5.0"), trNOOP("Surround 5.1"), trNOOP("Surround 6.0"),
- trNOOP("Surround 6.1"), trNOOP("Surround 7.1"), trNOOP("Pass Through"),
- NULL
-};
-
-const char * const config_t::s_subtitleSizes[ SUBTITLESIZE_count+1 ] = {
- trNOOP("default"),
- trNOOP("tiny"),
- trNOOP("small"),
- trNOOP("medium"),
- trNOOP("large"),
- trNOOP("very large"),
- trNOOP("huge"),
- NULL
-};
-
-const char * const config_t::s_subExts[] = {
- ".sub", ".srt", ".txt", ".ssa",
- ".SUB", ".SRT", ".TXT", ".SSA",
- NULL
-};
-
-const char * const config_t::s_osdBlendingMethods[] = {
- trNOOP("Software"),
- trNOOP("Hardware"),
- NULL
-};
-
-const char * const config_t::s_osdMixers[] = {
- trNOOP("no"),
- trNOOP("grayscale"), // item [1]
- trNOOP("transparent"), // item [2]
- trNOOP("transparent grayscale"), // item [3] ([1 | 2])
- trNOOP("yes"),
- NULL
-};
-
-const char * const config_t::s_osdScalings[] = {
- trNOOP("no"),
- trNOOP("nearest"), // item [1]
- trNOOP("bilinear"), // item [2]
- NULL
-};
-
-const char * const config_t::s_decoders_MPEG2[] = {
- trNOOP("automatic"),
- "libmpeg2",
- "FFmpeg",
- NULL
-};
-
-const char * const config_t::s_decoders_H264[] = {
- trNOOP("automatic"),
- "FFmpeg",
- "CoreAVC",
- NULL
-};
-
-const char * const config_t::s_ff_skip_loop_filters[] = {
- trNOOP("automatic"),
- trNOOP("default"),
- trNOOP("none"),
- trNOOP("nonref"),
- trNOOP("bidir"),
- trNOOP("nonkey"),
- trNOOP("all"),
- NULL
-};
-
-const char * const config_t::s_ff_speed_over_accuracy[] = {
- trNOOP("automatic"),
- trNOOP("yes"),
- trNOOP("no"),
-};
-
-static const char exts_playlist[][4] = {
- "asx",
- "m3u",
- "pls",
- "ram",
-};
-
-static const char exts_audio[][8] = {
- "ac3",
- "asf",
- "au",
- "aud",
- "flac",
- "mpa",
- "mpega",
- "mp2",
- "mp3",
- "m4a",
- "ogg",
- "ogm",
- "ra",
- "spx",
- "wav",
- "wma",
-};
-
-static const char exts_video[][8] = {
- "asf",
- "avi",
- "dat",
- "divx",
- "dv",
- "fli",
- "flv",
- "iso", /* maybe dvd */
- "mkv",
- "mov",
- "mpeg",
- "mpg",
- "mpv",
- "mp4",
- "m2v",
- "m2t",
- "m2ts",
- "m4v",
- "mts",
- "pes",
- "rm",
- "ts",
- "vdr",
- "vob",
- "wmv",
- "xvid",
-};
-
-static const char exts_image[][8] = {
- "bmp",
- "gif",
- "jpeg",
- "jpg",
- "mng",
- "png",
- "tiff",
-};
-
-#define DEF_EXT_IS(TYPE) \
-static bool ext_is_ ## TYPE(const char *ext) \
-{ \
- for(unsigned int i=0; i<sizeof(exts_ ## TYPE)/sizeof(exts_ ## TYPE[0]); i++) \
- if(!strcasecmp(ext, exts_ ## TYPE[i])) \
- return true; \
- return false; \
-}
-DEF_EXT_IS(playlist)
-DEF_EXT_IS(audio)
-DEF_EXT_IS(video)
-DEF_EXT_IS(image)
-
-static const char *get_extension(const char *fname)
-{
- if(fname) {
- const char *pos = strrchr(fname, '.');
- if(pos)
- return pos+1;
- }
- return NULL;
-}
-
-static char *strcatrealloc(char *dest, const char *src)
-{
- if (!src || !*src)
- return dest;
-
- size_t l = (dest ? strlen(dest) : 0) + strlen(src) + 1;
- if(dest) {
- dest = (char *)realloc(dest, l);
- strcat(dest, src);
- } else {
- dest = (char*)malloc(l);
- strcpy(dest, src);
- }
- return dest;
-}
-
-
-bool config_t::IsPlaylistFile(const char *fname)
-{
- const char *ext = get_extension(fname);
- return ext && ext_is_playlist(ext);
-}
-
-bool config_t::IsAudioFile(const char *fname)
-{
- const char *ext = get_extension(fname);
- return ext && (ext_is_audio(ext) || ext_is_playlist(ext));
-}
-
-bool config_t::IsVideoFile(const char *fname)
-{
- const char *ext = get_extension(fname);
- return ext && (ext_is_video(ext) || ext_is_audio(ext) || ext_is_playlist(ext));
-}
-
-bool config_t::IsImageFile(const char *fname)
-{
- const char *ext = get_extension(fname);
- return ext && (ext_is_image(ext) || ext_is_playlist(ext));
-}
-
-bool config_t::IsDvdImage(const char *fname)
-{
- const char *ext = get_extension(fname);
- return (ext && !strcasecmp(ext, "iso")) ? true : false;
-}
-
-bool config_t::IsDvdFolder(const char *fname)
-{
- struct stat st;
- cString buf, folder;
-
- buf = cString::sprintf("%s/VIDEO_TS/", fname);
- if (stat(buf, &st) == 0) {
- folder = buf;
- } else {
- buf = cString::sprintf("%s/video_ts/", fname);
- if (stat(buf, &st) == 0)
- folder = buf;
- else
- return false;
- }
-
- buf = cString::sprintf("%s/video_ts.ifo", *folder);
- if (stat(buf, &st) == 0)
- return true;
-
- buf = cString::sprintf("%s/VIDEO_TS.IFO", *folder);
- if (stat(buf, &st) == 0)
- return true;
-
- return false;
-}
-
-cString config_t::AutocropOptions(void)
-{
- if (!autocrop)
- return NULL;
-
- return cString::sprintf("enable_autodetect=%d,soft_start=%d,stabilize=%d,enable_subs_detect=%d",
- autocrop_autodetect, autocrop_soft, autocrop_fixedsize, autocrop_subs);
-}
-
-cString config_t::SwScaleOptions(void)
-{
- if (!swscale)
- return NULL;
-
- return cString::sprintf("output_aspect=%s,output_width=%d,output_height=%d,no_downscaling=%d",
- swscale_change_aspect ? "auto" : "0.0",
- swscale_resize ? swscale_width : 0,
- swscale_resize ? swscale_height : 0,
- swscale_downscale ? 0 : 1 );
-}
-
-cString config_t::FfmpegPpOptions(void)
-{
- if (!ffmpeg_pp)
- return NULL;
-
- if(*ffmpeg_pp_mode)
- return cString::sprintf("quality=%d,mode=%s", ffmpeg_pp_quality, ffmpeg_pp_mode);
-
- return cString::sprintf("quality=%d", ffmpeg_pp_quality);
-}
-
-cString config_t::UnsharpOptions(void)
-{
- if (!unsharp)
- return NULL;
-
- return cString::sprintf("luma_matrix_width=%d,luma_matrix_height=%d,luma_amount=%1.1f,"
- "chroma_matrix_width=%d,chroma_matrix_height=%d,chroma_amount=%1.1f",
- unsharp_luma_matrix_width, unsharp_luma_matrix_height,
- ((float)unsharp_luma_amount)/10.0,
- unsharp_chroma_matrix_width, unsharp_chroma_matrix_height,
- ((float)unsharp_chroma_amount)/10.0);
-}
-
-cString config_t::Denoise3dOptions(void)
-{
- if (!denoise3d)
- return NULL;
-
- return cString::sprintf("luma=%1.1f,chroma=%1.1f,time=%1.1f",
- ((float)denoise3d_luma)/10.0,
- ((float)denoise3d_chroma)/10.0,
- ((float)denoise3d_time)/10.0);
-}
-
-config_t::config_t() {
- memset(this, 0, sizeof(config_t));
-
- strn0cpy(local_frontend, s_frontends[FRONTEND_X11], sizeof(local_frontend));
- strn0cpy(video_driver , s_videoDriversX11[X11_DRIVER_XV], sizeof(video_driver));
- strn0cpy(video_port , "0.0", sizeof(video_port));
- strn0cpy(modeline , "", sizeof(modeline));
-
- strn0cpy(audio_driver , s_audioDrivers[AUDIO_DRIVER_ALSA], sizeof(audio_driver));
- strn0cpy(audio_port , "default", sizeof(audio_port));
- speaker_type = SPEAKERS_STEREO;
-
- post_plugins = NULL;
- config_file = NULL;
-
- audio_delay = 0;
- audio_compression = 0;
- memset(audio_equalizer,0,sizeof(audio_equalizer));
- strn0cpy(audio_visualization, "goom", sizeof(audio_visualization));
- strn0cpy(audio_vis_goom_opts, "fps:25,width:720,height:576", sizeof(audio_vis_goom_opts));
-
- headphone = 0;
- audio_upmix = 0;
- audio_surround = 0;
- sw_volume_control = 0;
-
- pes_buffers = i_pesBufferSize[PES_BUFFERS_SMALL_250];
- strn0cpy(deinterlace_method, s_deinterlaceMethods[DEINTERLACE_NONE], sizeof(deinterlace_method));
- strn0cpy(deinterlace_opts, DEFAULT_DEINTERLACE_OPTS, sizeof(deinterlace_opts));
- ffmpeg_pp = 0;
- ffmpeg_pp_quality = 3;
- strn0cpy(ffmpeg_pp_mode, "de", sizeof(ffmpeg_pp_mode));
- subtitle_vpos = 0;
-
- unsharp = 0;
- unsharp_luma_matrix_width = 5;
- unsharp_luma_matrix_height = 5;
- unsharp_luma_amount = 0;
- unsharp_chroma_matrix_width = 3;
- unsharp_chroma_matrix_height = 3;
- unsharp_chroma_amount = 0;
-
- denoise3d = 0;
- denoise3d_luma = 40;
- denoise3d_chroma = 30;
- denoise3d_time = 60;
-
- display_aspect = 0; /* auto */
-
- hide_main_menu = 0;
- osd_mixer = OSD_MIXER_FULL;
- osd_scaling = OSD_SCALING_NEAREST;
- hud_osd = 0;
-
- osd_blending = OSD_BLENDING_SOFTWARE;
- osd_blending_lowresvideo = OSD_BLENDING_HARDWARE;
-
- extsub_size = -1;
- dvb_subtitles = 0;
-
- alpha_correction = 0;
- alpha_correction_abs = 0;
-
- fullscreen = 0;
- modeswitch = 1;
- width = 720;
- height = 576;
- scale_video = 0;
- field_order = 0;
- autocrop = 0;
- autocrop_autodetect = 1;
- autocrop_soft = 1;
- autocrop_fixedsize = 1;
- autocrop_subs = 1;
-
- swscale = 0; // enable/disable
- swscale_change_aspect = 0; // change video aspect ratio
- swscale_resize = 0; // change video size
- swscale_width = 720; // output video width
- swscale_height = 576; // output video height
- swscale_downscale = 0; // allow downscaling
-
- remote_mode = 0;
- listen_port = LISTEN_PORT;
- remote_keyboard = 1;
- remote_max_clients = MAXCLIENTS;
- remote_usetcp = 1;
- remote_useudp = 1;
- remote_usertp = 1;
- remote_usepipe = 1;
- remote_usebcast = 1;
- remote_http_files = 1; /* allow http streaming of media files to xineliboutput clients
- * (currently replayed media file from xineliboutput media player)
- * - will be used if client can't access file directly (nfs etc.) */
-
- strn0cpy(remote_rtp_addr, "224.0.1.9", sizeof(remote_rtp_addr));
- remote_rtp_port = (LISTEN_PORT) & (0xfffe); /* even ports only */
- remote_rtp_ttl = 1;
- remote_rtp_always_on = 0;
- remote_rtp_sap = 1;
-
- remote_use_rtsp = 1; // allow generic rtsp for primary device. needs enabled udp or rtp
- remote_use_rtsp_ctrl = 0; // allow rtsp to control primary device (play/pause/seek...)
- remote_use_http = 1; // allow generic http streaming (primary device output)
- remote_use_http_ctrl = 0; // allow http to control primary device (play/pause/seek...)
-
- remote_local_if[0] = 0; // use only this interface - undefined -> any/all
- remote_local_ip[0] = 0; // bind locally to this IP - undefined -> any/all
-
- use_x_keyboard = 1;
-
- // video settings
- ibp_trickspeed = 1;
- max_trickspeed = 12;
- overscan = 0;
- hue = -1;
- saturation = -1;
- contrast = -1;
- brightness = -1;
- sharpness = -1;
- noise_reduction = -1;
- vo_aspect_ratio = 0;
-
- live_mode_sync = 1; // Sync SCR to transponder clock in live mode
- scr_tuning = 0; // Fine-tune xine egine SCR (to sync video to graphics output)
- scr_hz = 90000; // Current SCR speed (Hz), default is 90000
-
- decoder_mpeg2 = DECODER_MPEG2_auto;
- decoder_h264 = DECODER_H264_auto;
- ff_h264_speed_over_accurancy = FF_H264_SPEED_OVER_ACCURACY_auto;
- ff_h264_skip_loop_filter = FF_H264_SKIP_LOOPFILTER_auto;
-
- strn0cpy(browse_files_dir, VideoDirectory, sizeof(browse_files_dir));
- strn0cpy(browse_music_dir, VideoDirectory, sizeof(browse_music_dir));
- strn0cpy(browse_images_dir, VideoDirectory, sizeof(browse_images_dir));
- cache_implicit_playlists = 1;
- enable_id3_scanner = 1;
- dvd_arrow_keys_control_playback = 1;
-
- main_menu_mode = ShowMenu;
- force_primary_device = 0;
-};
-
-static uint8_t g_hidden_options[sizeof(config_t)] = {0};
-static uint8_t g_readonly_options[sizeof(config_t)] = {0};
-uint8_t *config_t::hidden_options = &g_hidden_options[0];
-uint8_t *config_t::readonly_options = &g_readonly_options[0];
-
-cString config_t::m_ProcessedArgs;
-bool config_t::ProcessArg(const char *Name, const char *Value)
-{
- if(SetupParse(Name, Value)) {
- m_ProcessedArgs = cString::sprintf("%s%s ", *m_ProcessedArgs ? *m_ProcessedArgs : " ", Name);
- return true;
- }
- return false;
-}
-
-bool config_t::ProcessArgs(int argc, char *argv[])
-{
- static const char short_options[] = "fDw:h:l:r:A:V:d:P:C:pc";
-
- static const struct option long_options[] = {
- { "fullscreen", no_argument, NULL, 'f' },
- { "hud", no_argument, NULL, 'D' },
- { "width", required_argument, NULL, 'w' },
- { "height", required_argument, NULL, 'h' },
- //{ "xkeyboard", no_argument, NULL, 'k' },
- //{ "noxkeyboard", no_argument, NULL, 'K' },
- { "local", required_argument, NULL, 'l' },
- //{ "modeline", required_argument, NULL, 'm' },
- { "remote", required_argument, NULL, 'r' },
- { "audio", required_argument, NULL, 'A' },
- { "video", required_argument, NULL, 'V' },
- { "display", required_argument, NULL, 'd' },
- { "post", required_argument, NULL, 'P' },
- { "config", required_argument, NULL, 'C' },
- { "primary", no_argument, NULL, 'p' },
- { "exit-on-close",no_argument, NULL, 'c' },
- { NULL }
- };
-
- int c;
- while ((c = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) {
- switch (c) {
- case 'd': ProcessArg("Video.Port", optarg);
- break;
- case 'f': ProcessArg("Fullscreen", "1");
- break;
- case 'D': ProcessArg("X11.HUDOSD", "1");
-#ifndef HAVE_XRENDER
- LOGMSG("HUD OSD not supported\n");
-#endif
- break;
- case 'w': ProcessArg("Fullscreen", "0");
- ProcessArg("X11.WindowWidth", optarg);
- break;
- case 'h': ProcessArg("Fullscreen", "0");
- ProcessArg("X11.WindowHeight", optarg);
- break;
- //case 'k': ProcessArg("X11.UseKeyboard", "1");
- // break;
- //case 'K': ProcessArg("X11.UseKeyboard", "0");
- // break;
- case 'l': ProcessArg("Frontend", optarg);
- break;
- //case 'm': ProcessArg("Modeline", optarg);
- // break;
- case 'r': if(strcmp(optarg, "none")) {
- if(strchr(optarg, ':')) {
- char *tmp = strdup(optarg);
- char *pt = strchr(tmp,':');
- *pt++ = 0;
- ProcessArg("Remote.ListenPort", pt);
- ProcessArg("RemoteMode", listen_port>0 ? "1" : "0");
- ProcessArg("Remote.LocalIP", tmp);
- free(tmp);
- LOGMSG("Listening on address \'%s\' port %d", remote_local_ip, listen_port);
- } else {
- ProcessArg("Remote.ListenPort", optarg);
- ProcessArg("RemoteMode", listen_port>0 ? "1" : "0");
- }
- } else
- ProcessArg("RemoteMode", "0");
- break;
- case 'V': ProcessArg("Video.Driver", optarg);
- break;
- case 'A': if(strchr(optarg,':')) {
- char *tmp = strdup(optarg);
- char *pt = strchr(tmp,':');
- *pt = 0;
- ProcessArg("Audio.Driver", tmp);
- ProcessArg("Audio.Port", pt+1);
- free(tmp);
- } else
- ProcessArg("Audio.Driver", optarg);
- break;
- case 'P': if(post_plugins)
- post_plugins = strcatrealloc(post_plugins, ";");
- post_plugins = strcatrealloc(post_plugins, optarg);
- break;
- case 'C': config_file = strdup(optarg);
- break;
- case 'p': ProcessArg("ForcePrimaryDevice", "1");
- break;
- case 'c': exit_on_close = 1;
- break;
-
- default: return false;
- }
- }
- return true;
-}
-
-bool config_t::SetupParse(const char *Name, const char *Value)
-{
- const char *pt;
- if(*m_ProcessedArgs && NULL != (pt=strstr(m_ProcessedArgs+1, Name)) &&
- *(pt-1) == ' ' && *(pt+strlen(Name)) == ' ') {
- LOGDBG("Skipping configuration entry %s=%s (overridden in command line)", Name, Value);
- return true;
- }
-
- if (!strcasecmp(Name, "Frontend")) STRN0CPY(local_frontend, Value);
- else if (!strcasecmp(Name, "Modeline")) STRN0CPY(modeline, Value);
- else if (!strcasecmp(Name, "VideoModeSwitching")) modeswitch = atoi(Value);
- else if (!strcasecmp(Name, "Fullscreen")) fullscreen = atoi(Value);
- else if (!strcasecmp(Name, "DisplayAspect")) display_aspect = strstra(Value, s_aspects, 0);
- else if (!strcasecmp(Name, "ForcePrimaryDevice")) force_primary_device = atoi(Value);
-
- else if (!strcasecmp(Name, "X11.WindowWidth")) width = atoi(Value);
- else if (!strcasecmp(Name, "X11.WindowHeight")) height = atoi(Value);
- else if (!strcasecmp(Name, "X11.UseKeyboard")) use_x_keyboard = atoi(Value);
- else if (!strcasecmp(Name, "X11.HUDOSD")) hud_osd = atoi(Value);
-
- else if (!strcasecmp(Name, "Audio.Driver")) STRN0CPY(audio_driver, Value);
- else if (!strcasecmp(Name, "Audio.Port")) STRN0CPY(audio_port, Value);
- else if (!strcasecmp(Name, "Audio.Speakers")) speaker_type = strstra(Value, s_speakerArrangements,
- SPEAKERS_STEREO);
- else if (!strcasecmp(Name, "Audio.Delay")) audio_delay = atoi(Value);
- else if (!strcasecmp(Name, "Audio.Compression")) audio_compression = atoi(Value);
- else if (!strcasecmp(Name, "Audio.Visualization.GoomOpts")) STRN0CPY(audio_vis_goom_opts, Value);
- else if (!strcasecmp(Name, "Audio.Visualization")) STRN0CPY(audio_visualization, Value);
- else if (!strcasecmp(Name, "Audio.Surround")) audio_surround = atoi(Value);
- else if (!strcasecmp(Name, "Audio.Upmix")) audio_upmix = atoi(Value);
- else if (!strcasecmp(Name, "Audio.Headphone")) headphone = atoi(Value);
- else if (!strcasecmp(Name, "Audio.SoftwareVolumeControl")) sw_volume_control = atoi(Value);
-
- else if (!strcasecmp(Name, "OSD.HideMainMenu")) hide_main_menu = atoi(Value);
- else if (!strcasecmp(Name, "OSD.LayersVisible")) osd_mixer = atoi(Value);
- else if (!strcasecmp(Name, "OSD.Scaling")) osd_scaling = atoi(Value);
- else if (!strcasecmp(Name, "OSD.Blending")) osd_blending = atoi(Value);
- else if (!strcasecmp(Name, "OSD.BlendingLowRes")) osd_blending_lowresvideo = atoi(Value);
-#if 1
- // < 1.0.1
- else if (!strcasecmp(Name, "OSD.UnscaledAlways")) osd_blending = atoi(Value);
- else if (!strcasecmp(Name, "OSD.UnscaledLowRes")) osd_blending_lowresvideo = atoi(Value);
-#endif
- else if (!strcasecmp(Name, "OSD.AlphaCorrection")) alpha_correction = atoi(Value);
- else if (!strcasecmp(Name, "OSD.AlphaCorrectionAbs")) alpha_correction_abs = atoi(Value);
-
- else if (!strcasecmp(Name, "OSD.ExtSubSize")) extsub_size = atoi(Value);
- else if (!strcasecmp(Name, "OSD.DvbSubtitles")) dvb_subtitles = atoi(Value);
-
- else if (!strcasecmp(Name, "RemoteMode")) remote_mode = atoi(Value);
- else if (!strcasecmp(Name, "Remote.ListenPort")) listen_port = atoi(Value);
- else if (!strcasecmp(Name, "Remote.Keyboard")) remote_keyboard = atoi(Value);
- else if (!strcasecmp(Name, "Remote.MaxClients")) remote_max_clients = atoi(Value);
- else if (!strcasecmp(Name, "Remote.UseTcp")) remote_usetcp = atoi(Value);
- else if (!strcasecmp(Name, "Remote.UseUdp")) remote_useudp = atoi(Value);
- else if (!strcasecmp(Name, "Remote.UseRtp")) remote_usertp = atoi(Value);
- else if (!strcasecmp(Name, "Remote.UsePipe")) remote_usepipe= atoi(Value);
- else if (!strcasecmp(Name, "Remote.UseHttp")) remote_http_files = atoi(Value);
- else if (!strcasecmp(Name, "Remote.UseBroadcast")) remote_usebcast = atoi(Value);
-
- else if (!strcasecmp(Name, "Remote.Rtp.Address")) STRN0CPY(remote_rtp_addr, Value);
- else if (!strcasecmp(Name, "Remote.Rtp.Port")) remote_rtp_port = (atoi(Value)) & (0xfffe);
- else if (!strcasecmp(Name, "Remote.Rtp.TTL")) remote_rtp_ttl = atoi(Value);
- else if (!strcasecmp(Name, "Remote.Rtp.AlwaysOn")) remote_rtp_always_on = atoi(Value);
- else if (!strcasecmp(Name, "Remote.Rtp.SapAnnouncements")) remote_rtp_sap = atoi(Value);
-
- else if (!strcasecmp(Name, "Remote.AllowRtsp")) remote_use_rtsp = atoi(Value);
- else if (!strcasecmp(Name, "Remote.AllowRtspCtrl")) remote_use_rtsp_ctrl = atoi(Value);
- else if (!strcasecmp(Name, "Remote.AllowHttp")) remote_use_http = atoi(Value);
- else if (!strcasecmp(Name, "Remote.AllowHttpCtrl")) remote_use_http_ctrl = atoi(Value);
-
- else if (!strcasecmp(Name, "Remote.Iface")) STRN0CPY(remote_local_if, Value);
- else if (!strcasecmp(Name, "Remote.LocalIP")) STRN0CPY(remote_local_ip, Value);
-
- else if (!strcasecmp(Name, "Decoder.PesBuffers")) pes_buffers=atoi(Value);
-
- else if (!strcasecmp(Name, "Video.Driver")) STRN0CPY(video_driver, Value);
- else if (!strcasecmp(Name, "Video.Port")) STRN0CPY(video_port, Value);
- else if (!strcasecmp(Name, "Video.Scale")) scale_video = atoi(Value);
- else if (!strcasecmp(Name, "Video.DeinterlaceOptions")) STRN0CPY(deinterlace_opts, Value);
- else if (!strcasecmp(Name, "Video.Deinterlace")) STRN0CPY(deinterlace_method, Value);
- else if (!strcasecmp(Name, "Video.FieldOrder")) field_order=atoi(Value)?1:0;
-
- else if (!strcasecmp(Name, "Video.AutoCrop")) autocrop = atoi(Value);
- else if (!strcasecmp(Name, "Video.AutoCrop.AutoDetect")) autocrop_autodetect = atoi(Value);
- else if (!strcasecmp(Name, "Video.AutoCrop.SoftStart")) autocrop_soft = atoi(Value);
- else if (!strcasecmp(Name, "Video.AutoCrop.FixedSize")) autocrop_fixedsize = atoi(Value);
- else if (!strcasecmp(Name, "Video.AutoCrop.DetectSubs")) autocrop_subs = atoi(Value);
-
- else if (!strcasecmp(Name, "Video.SwScale")) swscale = atoi(Value);
- else if (!strcasecmp(Name, "Video.SwScale.Aspect")) swscale_change_aspect = atoi(Value);
- else if (!strcasecmp(Name, "Video.SwScale.Resize")) swscale_resize = atoi(Value);
- else if (!strcasecmp(Name, "Video.SwScale.Downscale")) swscale_downscale = atoi(Value);
- else if (!strcasecmp(Name, "Video.SwScale.Width")) swscale_width = atoi(Value);
- else if (!strcasecmp(Name, "Video.SwScale.Height")) swscale_height = atoi(Value);
-
- else if (!strcasecmp(Name, "Video.HUE")) hue = atoi(Value);
- else if (!strcasecmp(Name, "Video.Saturation")) saturation = atoi(Value);
- else if (!strcasecmp(Name, "Video.Contrast")) contrast = atoi(Value);
- else if (!strcasecmp(Name, "Video.Brightness")) brightness = atoi(Value);
- else if (!strcasecmp(Name, "Video.Sharpness")) sharpness = atoi(Value);
- else if (!strcasecmp(Name, "Video.NoiseReduction")) noise_reduction = atoi(Value);
- else if (!strcasecmp(Name, "Video.Overscan")) overscan = atoi(Value);
- else if (!strcasecmp(Name, "Video.IBPTrickSpeed")) ibp_trickspeed = atoi(Value);
- else if (!strcasecmp(Name, "Video.MaxTrickSpeed")) max_trickspeed = atoi(Value);
- else if (!strcasecmp(Name, "Video.AspectRatio")) vo_aspect_ratio = atoi(Value);
-
- else if (!strcasecmp(Name, "Video.Decoder.MPEG2")) decoder_mpeg2 = strstra(Value, s_decoders_MPEG2, 0);
- else if (!strcasecmp(Name, "Video.Decoder.H264")) decoder_h264 = strstra(Value, s_decoders_H264, 0);
- else if (!strcasecmp(Name, "Video.Decoder.H264.SpeedOverAccuracy")) ff_h264_speed_over_accurancy = strstra(Value, s_ff_speed_over_accuracy, 0);
- else if (!strcasecmp(Name, "Video.Decoder.H264.SkipLoopFilter")) ff_h264_skip_loop_filter = strstra(Value, s_ff_skip_loop_filters, 0);
-
- else if (!strcasecmp(Name, "Post.pp.Enable")) ffmpeg_pp = atoi(Value);
- else if (!strcasecmp(Name, "Post.pp.Quality")) ffmpeg_pp_quality = atoi(Value);
- else if (!strcasecmp(Name, "Post.pp.Mode")) STRN0CPY(ffmpeg_pp_mode, Value);
-
- else if (!strcasecmp(Name, "Post.unsharp.Enable")) unsharp = atoi(Value);
- else if (!strcasecmp(Name, "Post.unsharp.luma_matrix_width")) unsharp_luma_matrix_width = atoi(Value);
- else if (!strcasecmp(Name, "Post.unsharp.luma_matrix_height")) unsharp_luma_matrix_height = atoi(Value);
- else if (!strcasecmp(Name, "Post.unsharp.luma_amount")) unsharp_luma_amount = atoi(Value);
- else if (!strcasecmp(Name, "Post.unsharp.chroma_matrix_width")) unsharp_chroma_matrix_width = atoi(Value);
- else if (!strcasecmp(Name, "Post.unsharp.chroma_matrix_height")) unsharp_chroma_matrix_height = atoi(Value);
- else if (!strcasecmp(Name, "Post.unsharp.chroma_amount")) unsharp_chroma_amount = atoi(Value);
-
- else if (!strcasecmp(Name, "Post.denoise3d.Enable")) denoise3d = atoi(Value);
- else if (!strcasecmp(Name, "Post.denoise3d.luma")) denoise3d_luma = atoi(Value);
- else if (!strcasecmp(Name, "Post.denoise3d.chroma")) denoise3d_chroma = atoi(Value);
- else if (!strcasecmp(Name, "Post.denoise3d.time")) denoise3d_time = atoi(Value);
-
- else if (!strcasecmp(Name, "Media.BrowseFilesDir")) STRN0CPY(browse_files_dir, Value);
- else if (!strcasecmp(Name, "Media.BrowseMusicDir")) STRN0CPY(browse_music_dir, Value);
- else if (!strcasecmp(Name, "Media.BrowseImagesDir")) STRN0CPY(browse_images_dir, Value);
- else if (!strcasecmp(Name, "Media.CacheImplicitPlaylists")) cache_implicit_playlists = atoi(Value);
- else if (!strcasecmp(Name, "Media.EnableID3Scanner")) enable_id3_scanner = atoi(Value);
- else if (!strcasecmp(Name, "Media.DVD.ArrowKeysControlPlayback")) dvd_arrow_keys_control_playback = atoi(Value);
-
- else if (!strcasecmp(Name, "Playlist.Tracknumber")) playlist_tracknumber = atoi(Value);
- else if (!strcasecmp(Name, "Playlist.Artist")) playlist_artist = atoi(Value);
- else if (!strcasecmp(Name, "Playlist.Album")) playlist_album = atoi(Value);
-
- else if (!strcasecmp(Name, "Advanced.LiveModeSync")) live_mode_sync = atoi(Value);
- else if (!strcasecmp(Name, "Advanced.AdjustSCR")) scr_tuning = atoi(Value);
- else if (!strcasecmp(Name, "Advanced.SCRSpeed")) scr_hz = atoi(Value);
-
- else if (!strcasecmp(Name, "Audio.Equalizer"))
- sscanf(Value,"%d %d %d %d %d %d %d %d %d %d",
- audio_equalizer ,audio_equalizer+1,
- audio_equalizer+2,audio_equalizer+3,
- audio_equalizer+4,audio_equalizer+5,
- audio_equalizer+6,audio_equalizer+7,
- audio_equalizer+8,audio_equalizer+9);
-
- else return false;
-
- return true;
-}
-
-/* Global instance */
-config_t xc;
-
-
diff --git a/config.h b/config.h
deleted file mode 100644
index 86ce315d..00000000
--- a/config.h
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * config.h: Global configuration and user settings
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: config.h,v 1.61 2009-05-31 15:30:07 phintuka Exp $
- *
- */
-
-#ifndef _XINELIB_CONFIG_H_
-#define _XINELIB_CONFIG_H_
-
-#include "features.h"
-
-#include <string.h>
-#include <stdint.h>
-
-#include <vdr/config.h>
-
-// Max number of remote clients
-#define MAXCLIENTS 10
-
-// Decoder buffer size
-#define PES_BUFFERS_CUSTOM 0
-#define PES_BUFFERS_TINY_50 1
-#define PES_BUFFERS_SMALL_250 2
-#define PES_BUFFERS_MEDIUM_500 3
-#define PES_BUFFERS_LARGE_1000 4
-#define PES_BUFFERS_HUGE_2000 5
-#define PES_BUFFERS_count 6
-
-// Output window aspect ratio
-#define ASPECT_AUTO 0
-#define ASPECT_DEFAULT 1
-#define ASPECT_4_3 2
-#define ASPECT_16_9 3
-#define ASPECT_16_10 4
-#define ASPECT_PAN_SCAN 5
-#define ASPECT_CENTER_CUT_OUT 6
-#define ASPECT_count 7
-
-// VIDEO OUTPUT ASPECT RATIO
-#define VO_ASPECT_AUTO 0
-#define VO_ASPECT_SQUARE 1 /* 1:1 */
-#define VO_ASPECT_4_3 2 /* 4:3 */
-#define VO_ASPECT_ANAMORPHIC 3 /* 16:9 */
-#define VO_ASPECT_DVB 4 /* 2.11:1 */
-#define VO_ASPECT_count 5
-
-// De-interlace method
-#define DEINTERLACE_NONE 0
-#define DEINTERLACE_BOB 1
-#define DEINTERLACE_WEAVE 2
-#define DEINTERLACE_GREEDY 3
-#define DEINTERLACE_ONEFIELD 4
-#define DEINTERLACE_ONEFIELD_XV 5
-#define DEINTERLACE_LINEARLEND 6
-#define DEINTERLACE_TVTIME 7
-#define DEINTERLACE_count 8
-
-#define FIELD_ORDER_NORMAL 0
-#define FIELD_ORDER_INVERTED 1
-#define FIELD_ORDER_count 2
-
-// Audio driver
-#define AUDIO_DRIVER_AUTO 0
-#define AUDIO_DRIVER_ALSA 1
-#define AUDIO_DRIVER_OSS 2
-#define AUDIO_DRIVER_NONE 3
-#define AUDIO_DRIVER_ESD 4
-#define AUDIO_DRIVER_JACK 5
-#define AUDIO_DRIVER_count 6
-
-// Video driver
-#define X11_DRIVER_AUTO 0
-#define X11_DRIVER_XSHM 1
-#define X11_DRIVER_XV 2
-#define X11_DRIVER_XVMC 3
-#define X11_DRIVER_XXMC 4
-#define X11_DRIVER_VIDIX 5
-#define X11_DRIVER_DIRECTFB 6
-#define X11_DRIVER_OPENGL 7
-#define X11_DRIVER_SDL 8
-#define X11_DRIVER_NONE 9
-#define X11_DRIVER_count 10
-
-#define FB_DRIVER_AUTO 0
-#define FB_DRIVER_FB 1
-#define FB_DRIVER_DIRECTFB 2
-#define FB_DRIVER_SDL 3
-#define FB_DRIVER_VIDIXFB 4
-#define FB_DRIVER_DXR3 5
-#define FB_DRIVER_NONE 6
-#define FB_DRIVER_count 7
-
-// Local frontend
-#define FRONTEND_X11 0
-#define FRONTEND_FB 1
-#define FRONTEND_NONE 2
-#define FRONTEND_count 3
-#define DEFAULT_FRONTEND "sxfe"
-
-#define LISTEN_PORT 37890
-#define LISTEN_PORT_S "37890"
-#define DISCOVERY_PORT 37890
-
-#define AUDIO_EQ_30HZ 0
-#define AUDIO_EQ_60HZ 1
-#define AUDIO_EQ_125HZ 2
-#define AUDIO_EQ_250HZ 3
-#define AUDIO_EQ_500HZ 4
-#define AUDIO_EQ_1000HZ 5
-#define AUDIO_EQ_2000HZ 6
-#define AUDIO_EQ_4000HZ 7
-#define AUDIO_EQ_8000HZ 8
-#define AUDIO_EQ_16000HZ 9
-#define AUDIO_EQ_count 10
-
-#define AUDIO_VIS_NONE 0
-#define AUDIO_VIS_GOOM 1
-#define AUDIO_VIS_count 5
-
-/* speaker arrangements: xine, audio_out_alsa.c */
-#define SPEAKERS_MONO 0
-#define SPEAKERS_STEREO 1
-#define SPEAKERS_HEADPHONES 2
-#define SPEAKERS_SURROUND21 3
-#define SPEAKERS_SURROUND3 4
-#define SPEAKERS_SURROUND4 5
-#define SPEAKERS_SURROUND41 6
-#define SPEAKERS_SURROUND5 7
-#define SPEAKERS_SURROUND51 8
-#define SPEAKERS_SURROUND6 9
-#define SPEAKERS_SURROUND61 10
-#define SPEAKERS_SURROUND71 11
-#define SPEAKERS_A52_PASSTHRU 12
-#define SPEAKERS_count 13
-
-#define SUBTITLESIZE_count 7
-
-// OSD blending methods
-#define OSD_BLENDING_SOFTWARE 0 // xine-lib "normal" osd
-#define OSD_BLENDING_HARDWARE 1 // xine-lib "unscaled osd"
-#define OSD_BLENDING_count 2
-
-// OSD layers mixing
-#define OSD_MIXER_NONE 0
-#define OSD_MIXER_GRAY 1
-#define OSD_MIXER_ALPHA 2
-#define OSD_MIXER_GRAYALPHA 3 // OSD_MIXER_GRAY | OSD_MIXER_ALPHA
-#define OSD_MIXER_FULL 4
-#define OSD_MIXER_count 5
-
-// OSD scaling modes
-#define OSD_SCALING_NONE 0
-#define OSD_SCALING_NEAREST 1
-#define OSD_SCALING_BILINEAR 2
-#define OSD_SCALING_count 3
-
-// Video decoder
-#define DECODER_MPEG2_auto 0 /* use value from frontend config_xineliboutput */
-#define DECODER_MPEG2_LIBMPEG2 1
-#define DECODER_MPEG2_FFMPEG 2
-#define DECODER_MPEG2_count 3
-
-#define DECODER_H264_auto 0 /* use value from frontend config_xineliboutput */
-#define DECODER_H264_FFMPEG 1
-#define DECODER_H264_COREAVC 2
-#define DECODER_H264_count 3
-
-#define FF_H264_SKIP_LOOPFILTER_auto 0 /* use value from frontend config_xineliboutput */
-#define FF_H264_SKIP_LOOPFILTER_DEFAULT 1
-#define FF_H264_SKIP_LOOPFILTER_NONE 2
-#define FF_H264_SKIP_LOOPFILTER_NONREF 3
-#define FF_H264_SKIP_LOOPFILTER_BIDIR 4
-#define FF_H264_SKIP_LOOPFILTER_NONKEY 5
-#define FF_H264_SKIP_LOOPFILTER_ALL 6
-#define FF_H264_SKIP_LOOPFILTER_count 7
-
-#define FF_H264_SPEED_OVER_ACCURACY_auto 0 /* use value from frontend config_xineliboutput */
-#define FF_H264_SPEED_OVER_ACCURACY_no 1
-#define FF_H264_SPEED_OVER_ACCURACY_yes 2
-#define FF_H264_SPEED_OVER_ACCURACY_count 3
-
-#define HIDDEN_OPTION(opt) \
- (xc.IsOptionHidden(xc.opt))
-#define READONLY_OPTION(opt) \
- (xc.IsOptionReadOnly(xc.opt))
-
-#define DEFAULT_POLL_SIZE 16
-
-typedef enum {
- ShowMenu = 0,
- ShowEq = 1,
- ShowFiles = 2,
- ShowMusic = 3,
- ShowImages = 4,
- CloseOsd = 5
-} eMainMenuMode;
-
-class config_t {
- public:
- static const char * const s_bufferSize [PES_BUFFERS_count + 1];
- static const int i_pesBufferSize [PES_BUFFERS_count + 1];
- static const char * const s_aspects [ASPECT_count + 1];
- static const char * const s_vo_aspects [VO_ASPECT_count + 1];
- static const char * const s_deinterlaceMethods [DEINTERLACE_count + 1];
- static const char * const s_deinterlaceMethodNames [DEINTERLACE_count + 1];
- static const char * const s_fieldOrder [FIELD_ORDER_count + 1];
- static const char * const s_audioDriverNames [AUDIO_DRIVER_count + 1];
- static const char * const s_audioDrivers [AUDIO_DRIVER_count + 1];
- static const char * const s_videoDriverNamesX11 [X11_DRIVER_count + 1];
- static const char * const s_videoDriversX11 [X11_DRIVER_count + 1];
- static const char * const s_videoDriverNamesFB [FB_DRIVER_count + 1];
- static const char * const s_videoDriversFB [FB_DRIVER_count + 1];
- static const char * const s_frontendNames [FRONTEND_count + 1];
- static const char * const s_frontends [FRONTEND_count + 1];
- static const char * const s_frontend_files [FRONTEND_count + 1];
- static const char * const s_audioEqNames [AUDIO_EQ_count + 1];
- static const char * const s_audioVisualizations [AUDIO_VIS_count + 1];
- static const char * const s_audioVisualizationNames[AUDIO_VIS_count + 1];
- static const char * const s_speakerArrangements [SPEAKERS_count + 1];
- static const char * const s_subtitleSizes [SUBTITLESIZE_count + 1];
- static const char * const s_osdBlendingMethods [OSD_BLENDING_count + 1];
- static const char * const s_osdMixers [OSD_MIXER_count + 1];
- static const char * const s_osdScalings [OSD_SCALING_count + 1];
- static const char * const s_decoders_MPEG2 [DECODER_MPEG2_count + 1];
- static const char * const s_decoders_H264 [DECODER_H264_count + 1];
- static const char * const s_ff_skip_loop_filters [FF_H264_SKIP_LOOPFILTER_count + 1];
- static const char * const s_ff_speed_over_accuracy [FF_H264_SPEED_OVER_ACCURACY_count + 1];
-
- static const char * const s_subExts[];
-
- public:
-
- // Force xineliboutput to be the primary device
- int force_primary_device;
-
- // local frontend settings
- char local_frontend[64];
- char video_driver[32];
- char video_port[32]; // X11: DISPLAY=...
- char audio_driver[32];
- char audio_port[64];
- char *post_plugins; // static post plugins from command line options
- char *config_file; // config file from command line options
- int pes_buffers;
-
- char modeline[64];
- int fullscreen;
- int modeswitch;
- int width;
- int height;
- int display_aspect;
- int scale_video;
- int field_order;
- int exit_on_close; // Terminate VDR when local frontend is closed
- int use_x_keyboard; // Use X11 keyboard to control VDR (console kbd is handled by VDR)
-
- // Audio settings
- int speaker_type;
- int audio_delay; // in ms
- int audio_compression; // 100%(=off)...500%
- int audio_equalizer[AUDIO_EQ_count];
- int audio_surround; // downmix multichannel audio to stereo surround
- int headphone; // mix audio for headphones
- int audio_upmix; // upmix stereo to 5.1
- int sw_volume_control; // software (xine-lib) or hardware (alsa) volume control and muting
-
- // Video settings
- int ibp_trickspeed;
- int max_trickspeed;
- int overscan; // %
- int hue; // 0...0xffff, -1 == off
- int saturation; // 0...0xffff, -1 == off
- int contrast; // 0...0xffff, -1 == off
- int brightness; // 0...0xffff, -1 == off
- int sharpness; // 0...0xffff, -1 == off
- int noise_reduction; // 0...0xffff, -1 == off
- int vo_aspect_ratio;
-
- // OSD settings
- eMainMenuMode main_menu_mode; // used internally to open right sub-menu
- int hide_main_menu;
- int osd_mixer; // show multiple OSD layers
- int osd_scaling; // OSD scaling mode: off, nearest, bilinear
- int hud_osd; // head up display OSD
- int osd_blending; // OSD blending method
- int osd_blending_lowresvideo; // Use hardware blending for low-resolution video
- int alpha_correction;
- int alpha_correction_abs;
- int extsub_size; // size of separate subtitles ( -1 = xine default ; 0...6 = { tiny small normal large very large huge }
- int dvb_subtitles; // send DVB subtitles in data stream (decode+display using xine-lib or external media player)
-
- // Media player
- char browse_files_dir[4096];
- char browse_music_dir[4096];
- char browse_images_dir[4096];
- int cache_implicit_playlists; // used in playlist.c
- int enable_id3_scanner; // used in playlist.c
- int subtitle_vpos; // used in media player. Not saved !
- int playlist_tracknumber;
- int playlist_artist;
- int playlist_album;
- int dvd_arrow_keys_control_playback;
-
- // Audio visualization
- char audio_visualization[64];
- char audio_vis_goom_opts[256];
-
- // deinterlacing post plugin
- char deinterlace_method[32];
- char deinterlace_opts[256];
-
- // ffmpeg post processing
- int ffmpeg_pp; // enable / disable
- int ffmpeg_pp_quality; // 0...6
- char ffmpeg_pp_mode[256];
-
- // automatic 4:3 letterbox -> 16:9 cropping post plugin
- int autocrop; // enable / disable
- int autocrop_autodetect;
- int autocrop_soft;
- int autocrop_fixedsize;
- int autocrop_subs;
-
- // (video) software scaling
- int swscale; // enable/disable
- int swscale_change_aspect; // change video aspect ratio
- int swscale_resize; // change video size
- int swscale_width; // output video width
- int swscale_height; // output video height
- int swscale_downscale; // allow downscaling
-
- // sharpen / soften post plugin
- int unsharp; // enable / disable
- int unsharp_luma_matrix_width; // 3..11, should be an odd number
- int unsharp_luma_matrix_height; // 3..11, should be an odd number
- int unsharp_luma_amount; // Actually a double between -2.0 and 2.0, but handled as a int between -20 and 20
- int unsharp_chroma_matrix_width; // 3..11, should be an odd number
- int unsharp_chroma_matrix_height; // 3..11, should be an odd number
- int unsharp_chroma_amount; // Actually a double between -2.0 and 2.0, but handled as a int between -20 and 20
-
- // 3D noise reduction post plugin
- int denoise3d; // enable / disable
- int denoise3d_luma; // Actually a double between 0.0 and 10.0, but handled as a int between 0 and 100
- int denoise3d_chroma; // Actually a double between 0.0 and 10.0, but handled as a int between 0 and 100
- int denoise3d_time; // Actually a double between 0.0 and 10.0, but handled as a int between 0 and 100
-
- int volnorm; // enable/disable volnorm post plugin (normalize audio volume)
-
- // Remote server settings
- int remote_mode; // Allow remote clients (vdr-sxfe, vdr-fbfe, ...)
- int listen_port; // Port of remote server
- char remote_local_if[32]; // Listen only on this interface
- char remote_local_ip[32]; // Bind locally to this IP
- int remote_keyboard; // Allow remote client to control VDR with keyboard, LIRC, etc.
- int remote_max_clients; // Max. number of clients
-
- int remote_usebcast; // Use broadcasts to find servers automatically
- int remote_usepipe; // enable local pipes for video transport
- int remote_usertp; // enable RTP multicast for video transport
- int remote_useudp; // enable UDP unicast for video transport
- int remote_usetcp; // enable TCP streams for video transport
- int remote_http_files; // allow http streaming of media files to xineliboutput clients
- // (=currently replayed media file from xineliboutput media player)
- // streaming is used only if client can't access file directly (nfs etc.)
- int remote_use_rtsp; // allow generic rtsp for primary device. needs enabled udp or rtp
- int remote_use_rtsp_ctrl;// allow rtsp to control primary device (play/pause/seek...)
- int remote_use_http; // allow generic http streaming (primary device output)
- int remote_use_http_ctrl;// allow http to control primary device (play/pause/seek...)
-
- // RTP parameters
- char remote_rtp_addr[32]; //xxx.xxx.xxx.xxx\0
- int remote_rtp_port;
- int remote_rtp_ttl;
- int remote_rtp_always_on;
- int remote_rtp_sap;
-
- // Advanced settings
- int live_mode_sync; /* Sync SCR to transponder clock in live mode */
- int scr_tuning; /* Fine-tune xine egine SCR (to sync video to graphics output) */
- int scr_hz; /* Current SCR speed (Hz), default is 90000 */
-
- int decoder_mpeg2; /* DECODER_MPEG2_... */
- int decoder_h264; /* DECODER_H264_... */
- int ff_h264_speed_over_accurancy;
- int ff_h264_skip_loop_filter; /* FF_H264_SKIP_LOOPFILTER_* */
-
- config_t();
-
- bool SetupParse(const char *Name, const char *Value);
- bool ProcessArgs(int argc, char *argv[]);
-
- bool IsImageFile(const char *);
- bool IsAudioFile(const char *);
- bool IsVideoFile(const char *);
- bool IsPlaylistFile(const char *);
- bool IsDvdFolder(const char *);
- bool IsDvdImage(const char *);
-
- cString AutocropOptions(void);
- cString SwScaleOptions(void);
- cString FfmpegPpOptions(void);
- cString UnsharpOptions(void);
- cString Denoise3dOptions(void);
-
- template<typename T> bool IsOptionHidden(T & option)
- { return hidden_options[(int)((long int)&option - (long int)this)];};
- template<typename T> bool IsOptionReadOnly(T & option)
- { return readonly_options[(int)((long int)&option - (long int)this)];};
-
- protected:
- bool ProcessArg(const char *Name, const char *Value);
- static cString m_ProcessedArgs;
-
- static uint8_t *hidden_options;
- static uint8_t *readonly_options;
-
- template<typename T> void HideOption(T & option)
- { hidden_options[(int)((long int)&option - (long int)this)] = 1;};
- template<typename T> void ReadOnlyOption(T & option)
- { readonly_options[(int)((long int)&option - (long int)this)] = 1;};
-};
-
-// Global instance
-extern config_t xc;
-
-// Find index of string in array of strings
-static inline int strstra(const char * const str, const char * const stra[], int def_index)
-{
- if(str && stra) {
- int i;
- for(i=0; stra[i]; i++)
- if(!strcmp(str,stra[i]))
- return i;
- }
- return def_index;
-}
-
-#endif //_XINELIB_CONFIG_H_
-
diff --git a/configure b/configure
deleted file mode 100755
index 76cb4956..00000000
--- a/configure
+++ /dev/null
@@ -1,450 +0,0 @@
-#!/bin/sh
-#
-# vdr-xinelibout configure script
-#
-# Copyright (c) Petri Hintukainen 2008
-#
-# See the main source file 'xineliboutput.c' for copyright information and
-# how to reach the author.
-#
-# * $Id: configure,v 1.18 2009-02-17 13:01:16 phintuka Exp $
-#
-
-PKG_CONFIG="pkg-config"
-makefile="config.mak"
-header="features.h"
-logfile="configure.log"
-debug=no
-
-CC="cc"
-CXX="g++"
-CFLAGS=""
-
-#
-# tools
-#
-
-toupper(){
- echo "$@" | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_
-}
-
-die(){
- log "$@"
- exit -1
-}
-
-log(){
- echo "$@"
- echo "$@" >> $logfile
-}
-
-logdbg(){
- [ x$debug = xyes ] && log "$@" || echo "$@" >> $logfile
-}
-
-not_in_list(){
- key=$1
- shift
- for item in $*; do
- test $key = $item && return 1
- done
- return 0
-}
-
-add_flag(){
- eval not_in_list $flag \$$flags_list || return 1
- logdbg "adding $flag to $flags_list"
- eval $flags_list=\"\$${flags_list} ${flag}\"
-}
-
-add_flags(){
- flags_list=$1
- shift
- for flag in $*; do
- add_flag $flags_list $flag
- done
-}
-
-#
-# enable/disable
-#
-
-set_opt(){
- eval HAVE_$(toupper $1)=$2
-}
-
-set_opts(){
- optvalue=$1
- shift
- for optname in $*; do
- set_opt $optname $optvalue
- done
-}
-
-enable(){
- set_opts yes $*
-}
-
-disable(){
- set_opts no $*
-}
-
-enabled(){
- ucfeature=$(toupper $1)
- eval test "x\$HAVE_${ucfeature}" = "xyes"
-}
-
-disabled(){
- ucfeature=$(toupper $1)
- eval test "x\$HAVE_${ucfeature}" = "xno"
-}
-
-#
-# compile/link tests
-#
-
-generate_test_c(){
- hdrname="$1"
- subsys="$2"
- func="$3"
- if test x"$subsys" = xX11 ; then
- cat <<EOF >testhdr.c
-#include <X11/Xlib.h>
-#include <$hdrname>
-int main(int c, char **v) {
- $func;
- return 0;
-}
-EOF
- else
- cat <<EOF >testhdr.c
-#include <stdio.h>
-#include <$hdrname>
-int main(int c, char **v) {
- $func;
-}
-EOF
- fi
-}
-
-test_library_c(){
-
- log -n "Checking for $libname ... "
- generate_test_c "$hdr" "$subsys" "$func"
- $CC -g testhdr.c -o testhdr $CFLAGS $inc $lib >> $logfile 2>&1
- err=$?
-
- if test $err = 0; then
- log "yes"
- add_flags LIBS_$subsys $lib
- add_flags CFLAGS_$subsys $inc
- else
- log "no"
- logdbg "--------"
- logdbg "/* $CC -g testhdr.c -o testhdr $CFLAGS $inc $lib */"
- logdbg `cat testhdr.c`
- logdbg "--------"
- fi
-
- rm -f testhdr.c testhdr
- return $err
-}
-
-#
-# pkg-config tests
-#
-
-test_pkgconfig(){
- disabled pkgconfig && return 1
- log -n "Checking for $PKG_CONFIG ... "
- disable pkgconfig
- $PKG_CONFIG --version>/dev/null && enable pkgconfig
- log $HAVE_PKGCONFIG
-}
-
-test_library_pc(){
- subsys="$1"
- libname="$2"
-
- log -n "Checking for pkg-config $libname ... "
- if $PKG_CONFIG --exists $libname; then
- add_flags LIBS_$subsys \
- `pkg-config --libs-only-L $libname` \
- `pkg-config --libs-only-l $libname`
- add_flags CFLAGS_$subsys `pkg-config --cflags-only-I $libname`
- log "yes"
- return 0
- fi
- log "no"
- return 1
-}
-
-#
-# generic test
-#
-
-test_library(){
- subsys="$1"
- libname="$2"
- hdr="$3"
- lib="$4"
- func="$5"
- inc="$6"
- feature=$(toupper $libname)
-
- # do not test if disabled from command-line
- if disabled $feature; then
- log "Not checking for $libname"
- disable $feature
- return 1
- fi
-
- disable $feature
-
- # try pkg-config first
- if enabled pkgconfig; then
- test_library_pc "$subsys" "$libname" && enable "$feature"
- fi
-
- # compile/link test as fallback
- if disabled $feature; then
- test_library_c "$subsys" "$libname" "$hdr" "$lib" "$func" "$inc" && enable $feature
- fi
-}
-
-#
-# configurable features
-#
-
-SUBSYSTEMS="
- x11
- fb
- vdr
- libxine
-"
-FEATURES="
- $SUBSYSTEMS
- libextractor
- libavutil
- libjpeg
- dbus_glib_1
- xshm
- xdpms
- xinerama
- xrandr
- xrender
- vdpau
-"
-
-# set defaults
-
-enable x11 vdr fb xine
-
-# clear log file
-
-rm -f $logfile
-
-#
-# Parse command-line arguments
-#
-
-show_help(){
- echo "Usage: configure [options]"
- echo "Options: [defaults in brackets after descriptions]"
- echo
- echo " --help print this message"
- echo " --enable-x11 build X11 frontend (vdr-sxfe) [yes]"
- echo " --enable-fb build framebuffer frontend (vdr-fbfe) [yes]"
- echo " --enable-vdr build VDR plugin [yes]"
- echo " --enable-libxine build xine plugins [yes]"
- echo
- echo " --disable-libextractor disable libextractor support (media file metainfo) [no]"
- echo " --disable-libjpeg disable libjpeg support [no]"
- echo " --disable-dbus-glib-1 disable dbus-glib support [no]"
- echo " --disable-xshm disable XShm support [no]"
- echo " --disable-xdpms disable Xdpms support [no]"
- echo " --disable-xinerama disable Xinerama support [no]"
- echo " --disable-xrandr disable Xrandr support (video mode switching) [no]"
- echo " --disable-xrender disable Xrender support (HUD OSD) [no]"
- echo " --disable-vdpau disable VDPAU support (X11) [no]"
- echo
- echo " --debug debug configure script"
- echo " --disable-pkgconfig do not use pkg-config"
- echo " --cc=CC select C compiler"
- echo " --cxx=CXX select C++ compiler"
- echo " --add-cflags=FLAGS add compiler flags"
-}
-
-for opt do
- optval="${opt#*=}"
- logdbg "Command line: $opt [$optval]"
- case "$opt" in
- --help)
- show_help && die
- ;;
- --debug)
- debug=yes
- logdbg "Debug mode"
- ;;
- --cc=?*)
- CC=$optval
- logdbg "C compiler: $CC"
- ;;
- --cxx=?*)
- CXX=$optval
- logdbg "C++ compiler: $CXX"
- ;;
- --add-cflags=?*)
- CFLAGS="$CFLAGS $optval"
- logdbg "CFLAGS: $CFLAGS"
- ;;
- --disable-pkgconfig)
- disable pkgconfig
- logdbg "Disabled pkg-config"
- ;;
- --enable-?*|--disable-?*)
- eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
- logdbg " $action $option"
- not_in_list $option $FEATURES && die "unknown option $opt"
- eval $action \${option}
- ;;
- -*)
- die "unknown option $opt"
- ;;
- esac
-done
-
-#
-# maintain deps
-#
-
-check_deps(){
- disabled libxine && disable x11 fb libavutil libjpeg
- disabled x11 && disable xshm xrender xrandr xdpms xinerama vdpau
- disabled x11 && disable dbus-glib-1 xshm xrender xrandr xdpms xinerama vdpau
- disabled vdr && disable libextractor
-}
-
-check_deps
-
-#
-# Run the tests
-#
-
-test_pkgconfig
-
-# fake test that should fail
-[ $debug = yes ] && \
- test_library X11 do_error "none.h" "-lnolib"
-
-test_library VDR libextractor "extractor.h" "-lextractor" "EXTRACTOR_getKeywords(0,0)"
-test_library XINE libxine "xine.h" "-lxine" "xine_init(0)"
-
-if enabled libxine; then
-
- log -n "Checking for xine plugin directory ..."
- if enabled pkgconfig && $PKG_CONFIG libxine --atleast-version 1.1.90; then
- XINEPLUGINDIR=`$PKG_CONFIG libxine --variable=plugindir`
- else
- XINEPLUGINDIR=`xine-config --plugindir`
- fi
- log " $XINEPLUGINDIR"
-
- test_library XINE libavutil "libavutil/mem.h" "-lavutil" "av_mallocz(1)"
- test_library XINE libjpeg "jpeglib.h" "-ljpeg" "jpeg_create_compress(0)"
- test_library X11 x11 "X11/X.h" "-lX11" "XInitThreads()"
- if enabled x11; then
- test_library X11 xext "X11/extensions/Xext.h" "-lXext" ""
- test_library X11 xshm "X11/extensions/XShm.h" "-lXext" "XShmQueryExtension(0)"
- test_library X11 xrender "X11/extensions/Xrender.h" "-lXrender" "XRenderQueryFormats(0)"
- test_library X11 xrandr "X11/extensions/Xrandr.h" "-lXrandr" "XRRGetScreenInfo(0,0)"
- test_library X11 xdpms "X11/extensions/dpms.h" "-lXext" "DPMSDisable(0)"
- test_library X11 xinerama "X11/extensions/Xinerama.h" "-lXinerama" "XineramaQueryScreens(0,0)"
- test_library X11 vdpau "vdpau/vdpau_x11.h" "-lvdpau" "vdp_device_create_x11(0,0,0,0)"
- test_library X11 dbus-glib-1 \
- "dbus/dbus-glib.h" \
- "-ldbus-glib-1 -ldbus-1 -lgobject-2.0 -lglib-2.0" \
- "dbus_g_bus_get(0,0)" \
- "-I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include"
- fi
-fi
-
-check_deps
-
-# need -lm for ceil/floor in HUD OSD
-enabled xrender && add_flags "LIBS_X11" "-lm"
-
-#
-# Print results
-#
-
-log
-log "Enabled features:"
-for feature in $FEATURES; do
- enabled $feature && log " $feature"
-done
-log "Disabled features:"
-for feature in $FEATURES; do
- enabled $feature || log " $feature"
-done
-log
-
-#
-# create features.h
-#
-
-log "Creating $header ..."
-
-cat <<EOF >$header
-/* Automatically generated by configure - do not modify! */
-
-#ifndef XINELIBOUTPUT_FEATURES_H
-#define XINELIBOUTPUT_FEATURES_H
-
-EOF
-
-for feature in $FEATURES; do
- enabled $feature &&
- echo "#define HAVE_$(toupper $feature) 1">>$header || \
- echo "#undef HAVE_$(toupper $feature)">>$header
-done
-
-echo "" >> $header
-echo "#endif /* XINELIBOUTPUT_FEATURES_H */" >> $header
-
-#
-# create features.mak
-#
-
-log "Creating $makefile ..."
-
-echo "# Automatically generated by configure - do not modify!" > $makefile
-echo >> $makefile
-
-# subsystems
-echo "XINELIBOUTPUT_VDRPLUGIN=$HAVE_VDR" >> $makefile
-echo "XINELIBOUTPUT_XINEPLUGIN=$HAVE_LIBXINE" >> $makefile
-echo "XINELIBOUTPUT_X11=$HAVE_X11" >> $makefile
-echo "XINELIBOUTPUT_FB=$HAVE_FB" >> $makefile
-echo >> $makefile
-
-# features
-for feature in $FEATURES; do
- feature="`toupper $feature`"
- enabled $feature &&
- echo "HAVE_$feature=yes">>$makefile ||
- echo "HAVE_$feature=no">>$makefile
-done
-echo >> $makefile
-
-# xine plugin dir
-enabled libxine && echo "XINEPLUGINDIR=$XINEPLUGINDIR" >> $makefile && echo >> $makefile
-
-# cc/ld flags
-echo "CFLAGS_XINE += $CFLAGS_XINE">>$makefile
-echo "CFLAGS_VDR += $CFLAGS_VDR">>$makefile
-echo "CFLAGS_X11 += $CFLAGS_X11">>$makefile
-echo "LIBS_XINE += $LIBS_XINE">>$makefile
-echo "LIBS_VDR += $LIBS_VDR">>$makefile
-echo "LIBS_X11 += $LIBS_X11">>$makefile
-
diff --git a/device.c b/device.c
deleted file mode 100644
index 0d797f92..00000000
--- a/device.c
+++ /dev/null
@@ -1,1640 +0,0 @@
-/*
- * device.c: xine-lib output device for the Video Disk Recorder
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: device.c,v 1.84 2009-06-24 20:45:40 phintuka Exp $
- *
- */
-
-#define __STDC_FORMAT_MACROS
-#define __STDC_CONSTANT_MACROS
-#include <inttypes.h>
-
-#include <vdr/config.h>
-#include <vdr/thread.h>
-#include <vdr/dvbspu.h>
-#include <vdr/channels.h>
-#include <vdr/skins.h>
-#include <vdr/status.h>
-#include <vdr/remote.h>
-
-//#define XINELIBOUTPUT_DEBUG
-//#define XINELIBOUTPUT_DEBUG_STDERR
-//#define TRACK_EXEC_TIME
-//#define FORWARD_DVD_SPUS
-//#define DEBUG_SWITCHING_TIME
-//#define LOG_TRICKSPEED
-
-#include "logdefs.h"
-#include "config.h"
-#include "osd.h"
-
-#include "tools/listiter.h"
-#include "tools/mpeg.h"
-#include "tools/pes.h"
-#include "tools/ts.h"
-#include "tools/functor.h"
-
-#include "frontend_local.h"
-#include "frontend_svr.h"
-
-#include "device.h"
-
-#define STILLPICTURE_REPEAT_COUNT 3
-#define LOCAL_INIT_TIMEOUT 20 // seconds
-#define SERVER_INIT_TIMEOUT 5 // seconds
-
-#ifdef LOG_TRICKSPEED
-# define LOGTRICKSPEED(x...) LOGMSG("trs: " x)
-#else
-# define LOGTRICKSPEED(x...)
-#endif
-
-//---------------------------- status monitor -------------------------------
-
-class cXinelibStatusMonitor : public cStatus
-{
- private:
- cXinelibStatusMonitor();
- cXinelibStatusMonitor(cXinelibStatusMonitor&);
-
- public:
- cXinelibStatusMonitor(cXinelibDevice& device, int cardIndex) :
- m_Device(device), m_cardIndex(cardIndex)
- {
-#ifdef DEBUG_SWITCHING_TIME
- switchtimeOff = 0LL;
- switchtimeOn = 0LL;
- switchingIframe = false;
-#endif
- };
-
- protected:
- virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber);
- virtual void Replaying(const cControl *Control, const char *Name,
- const char *FileName, bool On);
-
- cXinelibDevice& m_Device;
- int m_cardIndex;
-
-#ifdef DEBUG_SWITCHING_TIME
- public:
- int64_t switchtimeOff;
- int64_t switchtimeOn;
- bool switchingIframe;
-
- void IFrame(void)
- {
- if(!switchingIframe) {
- int64_t now = cTimeMs::Now();
- switchingIframe = true;
- LOGMSG("Channel switch: off -> on %" PRId64 " ms, "
- "on -> 1. I-frame %" PRId64 " ms",
- switchtimeOn-switchtimeOff, now-switchtimeOn);
- } else {
- int64_t now = cTimeMs::Now();
- LOGMSG("Channel switch: on -> 2. I-frame %" PRId64 " ms, "
- "Total %" PRId64 " ms",
- now-switchtimeOn, now-switchtimeOff);
- switchtimeOff = 0LL;
- switchtimeOn = 0LL;
- switchingIframe = false;
- }
- }
-#endif
-};
-
-void cXinelibStatusMonitor::ChannelSwitch(const cDevice *Device,
- int ChannelNumber)
-{
- TRACEF("cXinelibStatusMonitor::ChannelSwitch");
- TRACK_TIME(200);
-
- if (ChannelNumber) {
- if (Device->CardIndex() == m_cardIndex) {
-#ifdef DEBUG_SWITCHING_TIME
- switchtimeOn = cTimeMs::Now();
-#endif
- m_Device.SetTvMode(Channels.GetByNumber(ChannelNumber));
- TRACE("cXinelibStatusMonitor: Set to TvMode");
- }
- } else {
- if (Device->CardIndex() == m_cardIndex) {
-#ifdef DEBUG_SWITCHING_TIME
- switchtimeOff = cTimeMs::Now();
-#endif
- m_Device.StopOutput();
- TRACE("cXinelibStatusMonitor: received stop");
- }
- }
-}
-
-void cXinelibStatusMonitor::Replaying(const cControl *Control,
- const char *Name,
- const char *FileName, bool On)
-{
- TRACEF("cXinelibStatusMonitor::Replaying");
-
- if (On /*&& Name != NULL*/) {
- TRACE("cXinelibStatusMonitor: Replaying " << Name << "(" << FileName << ")");
- m_Device.SetReplayMode();
- }
-}
-
-//----------------------------- device ----------------------------------------
-
-//
-// Singleton
-//
-
-cXinelibDevice* cXinelibDevice::m_pInstance = NULL;
-
-cXinelibDevice& cXinelibDevice::Instance(void)
-{
- TRACEF("cXinelibDevice::Instance");
- if (!m_pInstance) {
- m_pInstance = new cXinelibDevice();
- TRACE("cXinelibDevice::Instance(): create, cardindex = "
- << m_pInstance->CardIndex());
- }
-
- return *m_pInstance;
-}
-
-void cXinelibDevice::Dispose(void)
-{
- TRACEF("cXinelibDevice::Dispose");
- delete m_pInstance;
- m_pInstance = NULL;
-}
-
-//
-// init and shutdown
-//
-
-cXinelibDevice::cXinelibDevice()
-{
- TRACEF("cXinelibDevice::cXinelibDevice");
-
- m_statusMonitor = NULL;
- m_spuDecoder = NULL;
-
- m_local = NULL;
- m_server = NULL;
-
- m_OriginalPrimaryDevice = 0;
- m_ForcePrimaryDeviceCnt = 0;
-
- if(*xc.local_frontend && strncmp(xc.local_frontend, "none", 4))
- m_clients.Add(m_local = new cXinelibLocal(xc.local_frontend));
- if(xc.remote_mode && xc.listen_port>0)
- m_clients.Add(m_server = new cXinelibServer(xc.listen_port));
-
- m_ac3Present = false;
- m_spuPresent = false;
-
- memset(m_MetaInfo, 0, sizeof(m_MetaInfo));
-
- m_PlayMode = pmNone;
- m_AudioChannel = 0;
-
- m_liveMode = true;
- m_TrickSpeed = -1;
- m_TrickSpeedPts = 0;
- m_TrickSpeedMode = 0;
- m_TrickSpeedDelay = 0;
- m_SkipAudio = false;
- m_PlayingFile = pmNone;
- m_StreamStart = true;
- m_RadioStream = false;
- m_AudioCount = 0;
- m_FreeBufs = 0;
- m_Cleared = true;
- m_h264 = false;
-
- m_VideoSize = (video_size_t*)calloc(1, sizeof(video_size_t));
-
- TsBufferClear();
-}
-
-cXinelibDevice::~cXinelibDevice()
-{
- TRACEF("cXinelibDevice::~cXinelibDevice");
-
- StopDevice();
-
- m_pInstance = NULL;
-
- free (m_VideoSize);
-}
-
-bool cXinelibDevice::StartDevice()
-{
- TRACEF("cXinelibDevice::StartDevice");
-
- if(m_local)
- m_local->Start();
- if(m_server)
- m_server->Start();
-
- // if(dynamic_cast<cXinelibLocal*>(it))
- if(m_local) {
- int timer = 0;
- while(!m_local->IsReady()) {
- cCondWait::SleepMs(100);
- if(m_local->IsFinished()) {
- LOGMSG("cXinelibDevice::Start(): Local frontend init failed");
- return false;
- }
- if(++timer >= LOCAL_INIT_TIMEOUT*10) {
- LOGMSG("cXinelibDevice::Start(): Local frontend init timeout");
- return false;
- }
- }
- if(xc.force_primary_device)
- ForcePrimaryDevice(true);
- }
-
- if(m_server) {
- int timer = 0;
- while(!m_server->IsReady()) {
- cCondWait::SleepMs(100);
- if(m_server->IsFinished()) {
- LOGMSG("cXinelibDevice::Start(): Server init failed");
- return false;
- }
- if(++timer >= SERVER_INIT_TIMEOUT*10) {
- LOGMSG("cXinelibDevice::Start(): Server init timeout");
- return false;
- }
- }
- }
-
- ASSERT(m_statusMonitor == NULL, false);
- m_statusMonitor = new cXinelibStatusMonitor(*this, CardIndex());
-
- LOGDBG("cXinelibDevice::StartDevice(): Device started");
- return true;
-}
-
-void cXinelibDevice::StopDevice(void)
-{
- TRACEF("cXinelibDevice::StopDevice");
- LOGDBG("cXinelibDevice::StopDevice(): Stopping device ...");
-
- if(m_statusMonitor) {
- delete m_statusMonitor;
- m_statusMonitor = NULL;
- }
- if (m_spuDecoder) {
- delete m_spuDecoder;
- m_spuDecoder = NULL;
- }
-
- cXinelibThread *server = m_server;
- cXinelibThread *local = m_local;
- m_local = m_server = NULL;
-
- cControl::Shutdown();
- ForEach(m_clients, &cXinelibThread::SetLiveMode, false);
- TrickSpeed(-1);
-
- if(local) m_clients.Del(local, false);
- if(server) m_clients.Del(server, false);
-
- if(server) {
- server->Stop();
- delete server;
- }
- if(local) {
- local->Stop();
- delete local;
- }
-
- m_clients.Clear();
-}
-
-//
-// Primary device switching
-//
-
-void cXinelibDevice::MakePrimaryDevice(bool On)
-{
- TRACEF("cXinelibDevice::MakePrimaryDevice");
-
- cDevice::MakePrimaryDevice(On);
-
- if(On)
- new cXinelibOsdProvider(this);
-}
-
-void cXinelibDevice::ForcePrimaryDevice(bool On)
-{
- TRACEF("cXinelibDevice::ForcePrimaryDevice");
-
- m_MainThreadLock.Lock();
- m_MainThreadFunctors.Add(CreateFunctor(this, &cXinelibDevice::ForcePrimaryDeviceImpl, On));
- m_MainThreadLock.Unlock();
-}
-
-void cXinelibDevice::ForcePrimaryDeviceImpl(bool On)
-{
- TRACEF("cXinelibDevice::ForcePrimaryDeviceImpl");
- ASSERT(cThread::IsMainThread(), false);
-
- if(On) {
- m_ForcePrimaryDeviceCnt++;
-
- if(xc.force_primary_device) {
- if(cDevice::PrimaryDevice() && this != cDevice::PrimaryDevice()) {
- m_OriginalPrimaryDevice = cDevice::PrimaryDevice()->DeviceNumber() + 1;
- cControl::Shutdown();
- LOGMSG("Forcing primary device, original index = %d", m_OriginalPrimaryDevice);
- if(cOsd::IsOpen()) {
- LOGMSG("Forcing primary device, old OSD still open !");
- xc.main_menu_mode = CloseOsd;
- cRemote::CallPlugin("xineliboutput");
- }
- SetPrimaryDevice(DeviceNumber() + 1);
- }
- }
-
- } else /* Off */ {
- m_ForcePrimaryDeviceCnt--;
-
- if(m_ForcePrimaryDeviceCnt < 0)
- LOGMSG("ForcePrimaryDevice: Internal error (ForcePrimaryDevice < 0)");
- else if(m_ForcePrimaryDeviceCnt == 0) {
- if(m_OriginalPrimaryDevice) {
- LOGMSG("Restoring original primary device %d", m_OriginalPrimaryDevice);
- cControl::Shutdown();
- if(cOsd::IsOpen()) {
- LOGMSG("Restoring primary device, xineliboutput OSD still open !");
- xc.main_menu_mode = CloseOsd; /* will be executed in future by vdr main thread */
- cRemote::CallPlugin("xineliboutput");
- }
- cChannel *channel = Channels.GetByNumber(CurrentChannel());
- cDevice::SetPrimaryDevice(m_OriginalPrimaryDevice);
- PrimaryDevice()->SwitchChannel(channel, true);
- m_OriginalPrimaryDevice = 0;
- }
- }
- }
-}
-
-//
-// Execute functors in main thread context
-//
-
-void cXinelibDevice::MainThreadHook(void)
-{
- TRACEF("cXinelibDevice::MainThreadHook");
-
- if(m_MainThreadFunctors.First()) {
- cFunctor *f = NULL;
- do {
- m_MainThreadLock.Lock();
- if(f)
- m_MainThreadFunctors.Del(f);
- f = m_MainThreadFunctors.First();
- m_MainThreadLock.Unlock();
-
- if(f) {
- /*LOGDBG("cXinelibDevice::MainThreadHook: executing functor 0x%lx",(long)f);*/
- f->Execute();
- }
-
- } while(f);
- }
-}
-
-//
-// Configuration
-//
-
-void cXinelibDevice::ConfigurePostprocessing(const char *deinterlace_method,
- int audio_delay,
- int audio_compression,
- const int *audio_equalizer,
- int audio_surround,
- int speaker_type)
-{
- TRACEF("cXinelibDevice::ConfigurePostprocessing");
-
- if(m_local)
- m_local->ConfigurePostprocessing(deinterlace_method, audio_delay,
- audio_compression, audio_equalizer,
- audio_surround, speaker_type);
- if(m_server)
- m_server->ConfigurePostprocessing(deinterlace_method, audio_delay,
- audio_compression, audio_equalizer,
- audio_surround, speaker_type);
-}
-
-void cXinelibDevice::ConfigurePostprocessing(const char *name, bool on,
- const char *args)
-{
- TRACEF("cXinelibDevice::ConfigurePostprocessing");
-
- if(m_local)
- m_local->ConfigurePostprocessing(name, on, args);
- if(m_server)
- m_server->ConfigurePostprocessing(name, on, args);
-}
-
-void cXinelibDevice::ConfigureVideo(int hue, int saturation, int brightness, int sharpness,
- int noise_reduction, int contrast, int overscan, int vo_aspect_ratio)
-{
- TRACEF("cXinelibDevice::ConfigureVideo");
-
- if(m_local)
- m_local->ConfigureVideo(hue, saturation, brightness, sharpness, noise_reduction, contrast, overscan, vo_aspect_ratio);
- if(m_server)
- m_server->ConfigureVideo(hue, saturation, brightness, sharpness, noise_reduction, contrast, overscan, vo_aspect_ratio);
-}
-
-void cXinelibDevice::ConfigureDecoder(int pes_buffers)
-{
- TRACEF("cXinelibDevice::ConfigureDecoder");
-
- if(m_local)
- m_local->ConfigureDecoder(pes_buffers);
- //if(m_server)
- // m_server->ConfigureDecoder(pes_buffers);
-
- cXinelibOsdProvider::RefreshOsd();
-}
-
-void cXinelibDevice::ConfigureWindow(int fullscreen, int width, int height,
- int modeswitch, const char *modeline,
- int aspect, int scale_video,
- int field_order)
-{
- TRACEF("cXinelibDevice::ConfigureWindow");
-
- if((!*xc.local_frontend || !strncmp(xc.local_frontend, "none", 4)) && m_local) {
- cXinelibThread *tmp = m_local;
- m_clients.Del(tmp, false);
- m_local = NULL;
- cCondWait::SleepMs(5);
- tmp->Stop();
- cCondWait::SleepMs(5);
- delete tmp;
- if(xc.force_primary_device)
- ForcePrimaryDevice(false);
- }
-
- if(m_local)
- m_local->ConfigureWindow(fullscreen, width, height, modeswitch, modeline,
- aspect, scale_video, field_order);
-
- else if(*xc.local_frontend && strncmp(xc.local_frontend, "none", 4)) {
- cXinelibThread *tmp = new cXinelibLocal(xc.local_frontend);
- tmp->Start();
- m_clients.Add(m_local = tmp);
-
- cCondWait::SleepMs(25);
- while(!m_local->IsReady() && !m_local->IsFinished())
- cCondWait::SleepMs(25);
-
- if(m_local->IsFinished()) {
- m_local = NULL;
- m_clients.Del(tmp, true);
- Skins.QueueMessage(mtError, tr("Frontend initialization failed"), 10);
- } else {
- if(xc.force_primary_device)
- ForcePrimaryDevice(true);
-
- m_local->ConfigureWindow(fullscreen, width, height, modeswitch, modeline,
- aspect, scale_video, field_order);
- }
- }
-}
-
-void cXinelibDevice::Listen(bool activate, int port)
-{
- TRACEF("cXinelibDevice::Listen");
-
- if(activate && port>0) {
- if(!m_server) {
- cXinelibThread *tmp = new cXinelibServer(port);
- tmp->Start();
- m_clients.Add(m_server = tmp);
-
- cCondWait::SleepMs(10);
- while(!m_server->IsReady() && !m_server->IsFinished())
- cCondWait::SleepMs(10);
-
- if(m_server->IsFinished()) {
- Skins.QueueMessage(mtError, tr("Server initialization failed"), 10);
- m_server = NULL;
- m_clients.Del(tmp, true);
- }
-
- } else {
- if(! m_server->Listen(port))
- Skins.QueueMessage(mtError, tr("Server initialization failed"), 10);
- }
- } else if( /*((!activate) || port<=0) && */ m_server) {
- cXinelibThread *tmp = m_server;
- m_clients.Del(tmp, false);
- m_server = NULL;
- cCondWait::SleepMs(5);
- tmp->Stop();
- cCondWait::SleepMs(5);
- delete tmp;
- }
-}
-
-//
-// OSD
-//
-
-void cXinelibDevice::OsdCmd(void *cmd)
-{
- TRACEF("cXinelibDevice::OsdCmd");
- TRACK_TIME(250);
-
- if(m_server) // call first server, local frontend modifies contents of the message ...
- m_server->OsdCmd(cmd);
- if(m_local)
- m_local->OsdCmd(cmd);
-}
-
-//
-// Play mode control
-//
-void cXinelibDevice::StopOutput(void)
-{
- TRACEF("cXinelibDevice::StopOutput");
- TRACK_TIME(250);
-
- m_RadioStream = false;
- m_AudioCount = 0;
- ForEach(m_clients, &cXinelibThread::SetLiveMode, false);
- Clear();
- ForEach(m_clients, &cXinelibThread::QueueBlankDisplay);
- ForEach(m_clients, &cXinelibThread::SetNoVideo, false);
-}
-
-void cXinelibDevice::SetTvMode(cChannel *Channel)
-{
- TRACEF("cXinelibDevice::SetTvMode");
- TRACK_TIME(250);
-
-#if VDRVERSNUM >= 10701
- m_PatPmtParser.Reset();
-#endif
-
- m_RadioStream = false;
- if (Channel && !Channel->Vpid() && (Channel->Apid(0) || Channel->Apid(1)))
- m_RadioStream = true;
- if(m_PlayMode == pmAudioOnlyBlack)
- m_RadioStream = true;
- TRACE("cXinelibDevice::SetTvMode - isRadio = "<<m_RadioStream);
-
- m_StreamStart = true;
- m_liveMode = true;
- m_TrickSpeed = -1;
- m_SkipAudio = false;
- m_AudioCount = 0;
- m_spuPresent = false;
-
- Clear();
- ForEach(m_clients, &cXinelibThread::SetNoVideo, m_RadioStream);
- ForEach(m_clients, &cXinelibThread::SetLiveMode, true);
- ForEach(m_clients, &cXinelibThread::ResumeOutput);
-}
-
-void cXinelibDevice::SetReplayMode(void)
-{
- TRACEF("cXinelibDevice::SetReplayMode");
-
- m_RadioStream = true; // first seen replayed video packet resets this
- m_AudioCount = 15;
- m_StreamStart = true;
-
- ForEach(m_clients, &cXinelibThread::SetLiveMode, false);
- Clear();
- ForEach(m_clients, &cXinelibThread::SetNoVideo, false /*m_RadioStream*/);
- if(m_RadioStream && !m_liveMode)
- ForEach(m_clients, &cXinelibThread::BlankDisplay);
- ForEach(m_clients, &cXinelibThread::ResumeOutput);
-
- m_liveMode = false;
-}
-
-bool cXinelibDevice::SetPlayMode(ePlayMode PlayMode)
-{
- TRACEF("cXinelibDevice::SetPlayMode");
-
-#ifdef XINELIBOUTPUT_DEBUG
- switch (PlayMode) {
- case pmNone:
- TRACE("cXinelibDevice::SetPlayMode audio/video from decoder"); break;
- case pmAudioVideo:
- TRACE("cXinelibDevice::SetPlayMode audio/video from player"); break;
- case pmVideoOnly:
- TRACE("cXinelibDevice::SetPlayMode video from player, audio from decoder"); break;
- case pmAudioOnly:
- TRACE("cXinelibDevice::SetPlayMode audio from player, video from decoder"); break;
- case pmAudioOnlyBlack:
- TRACE("cXinelibDevice::SetPlayMode audio only from player, no video (black screen)"); break;
- case pmExtern_THIS_SHOULD_BE_AVOIDED:
- TRACE("cXinelibDevice::SetPlayMode this should be avoided"); break;
- }
-#endif
-
- m_ac3Present = false;
- m_spuPresent = false;
-
- m_PlayMode = PlayMode;
-
- TrickSpeed(-1);
- if (m_PlayMode == pmAudioOnlyBlack) {
- TRACE("pmAudioOnlyBlack --> BlankDisplay, NoVideo");
- ForEach(m_clients, &cXinelibThread::BlankDisplay);
- ForEach(m_clients, &cXinelibThread::SetNoVideo, true);
- } else {
- if(m_liveMode)
- ForEach(m_clients, &cXinelibThread::SetNoVideo, m_RadioStream);
- else
- ForEach(m_clients, &cXinelibThread::SetNoVideo,
- m_RadioStream && (m_AudioCount<1));
- Clear();
- }
-
- return true;
-}
-
-//
-// Playback control
-//
-
-// m_TrickSpeedMode flags
-#define trs_IPB_frames 0x01 // stream has all frame types
-#define trs_I_frames 0x02 // stream has only I-frames
-#define trs_PTS_recalc 0x04 // PTS must be re-calculated
-#define trs_NoAudio 0x08 // no audio in trick speed mode
-#define trs_PTS_check 0x80 // detect in PlayVideo if PTS must be recalculated
-
-void cXinelibDevice::TrickSpeed(int Speed)
-{
- TRACEF("cXinelibDevice::TrickSpeed");
-
- if(m_TrickSpeed != Speed) {
- int RealSpeed = abs(Speed);
- LOGTRICKSPEED("TrickSpeed changed from %d to %d [%d]", m_TrickSpeed, Speed, RealSpeed);
-
- m_TrickSpeedPts = 0;
- m_TrickSpeed = Speed;
- m_TrickSpeedDelay = 0;
-
- // Possible transitions:
- // fast <-> play
- // play <-> pause
- // pause <-> slow
- // _and_ from any mode to normal play and pause
-
- if(Speed == 8 || Speed == 4 || Speed == 2) {
- LOGTRICKSPEED(" Slow forward (1/%d speed), IPB-frames", Speed);
-
- // do nothing - slow forward is just slow playback of complete stream
- m_TrickSpeedMode = trs_IPB_frames;
-
- // previous state was slow forward or pause --> no need for clear
-
- // change decoder and UDP/RTP scheduler clock rates
- ForEach(m_clients, &cXinelibThread::TrickSpeed, RealSpeed);
- }
-
- else if(Speed == 63 || Speed == 48 || Speed == 24) {
- RealSpeed = (Speed+11)/12;
- LOGTRICKSPEED(" Slow backward (1/%d speed), I-frames only", RealSpeed);
-
- // previous state was slow backwards or pause --> clear if it was pause
- //
- //if(PrevSpeed == 0 && !(m_TrickSpeedMode & trs_PTS_recalc)) {
- // LOGMSG(" -> Clear");
- // ForEach(m_clients, &cXinelibThread::Clear);
- //}
-
- // only I-frames, backwards, pts must be re-generated
- m_TrickSpeedMode = trs_I_frames | trs_PTS_recalc | trs_NoAudio;
-
- // change decoder and UDP/RTP scheduler clock rates
- ForEach(m_clients, &cXinelibThread::TrickSpeed, RealSpeed);
- }
-
- else if(Speed == 6 || Speed == 3 || Speed == 1) {
- RealSpeed = 12/Speed;
- LOGTRICKSPEED(" Fast (%dx speed), direction unknown", RealSpeed);
-
- if(RealSpeed > xc.max_trickspeed) {
- RealSpeed = xc.max_trickspeed;
- LOGTRICKSPEED(" Trick speed limited to %dx speed", RealSpeed);
- }
-
- /* only I-frames, backwards, pts must be re-generated if playing backwards */
- m_TrickSpeedMode |= trs_PTS_check;
-
- /* backward/forward state is unknown until first PTS is seen
- so, clear() must be done in PlayVideo. */
- /* previous trick speed state is not overwritten yet ... ! */
-
- // change decoder and UDP/RTP scheduler clock rates
- ForEach(m_clients, &cXinelibThread::TrickSpeed, -RealSpeed);
- }
-
- else if(Speed==-1 || Speed == 0) {
- LOGTRICKSPEED(" Play/Pause");
-
- // change decoder and UDP/RTP scheduler clock rates
- ForEach(m_clients, &cXinelibThread::TrickSpeed, RealSpeed);
-
- // returning from backward mode needs Clear
- //
- //if(Speed==-1 && (m_TrickSpeedMode & trs_PTS_recalc)) {
- // LOGMSG(" -> Clear");
- // ForEach(m_clients, &cXinelibThread::Clear);
- // m_TrickSpeedMode = 0;
- //}
- // returning from fast forward mode needs Clear
- // because of DvbPlayer jumps few seconds back at mode change ...
- //
- //if(Speed==-1 && (m_TrickSpeedMode & trs_I_frames)) {
- // LOGMSG(" -> Clear");
- // ForEach(m_clients, &cXinelibThread::Clear);
- //}
- m_TrickSpeedMode = 0;
- }
-
- else {
- LOGTRICKSPEED(" Unknown trickspeed %d !", Speed);
- m_TrickSpeedMode = 0;
- m_TrickSpeed = -1;
- ForEach(m_clients, &cXinelibThread::TrickSpeed, -1);
- }
- }
-}
-
-void cXinelibDevice::Clear(void)
-{
- TRACEF("cXinelibDevice::Clear");
- TRACK_TIME(100);
-
- TsBufferClear();
-
- if(m_Cleared && m_StreamStart && m_TrickSpeed == -1) {
- //LOGMSG("************ Double Clear ***************");
- } else {
- //LOGMSG("************ FIRST Clear ***************");
- m_Cleared = true;
- m_StreamStart = true;
- m_h264 = false;
- m_FreeBufs = 0;
- TrickSpeed(-1);
- ForEach(m_clients, &cXinelibThread::Clear);
- ForEach(m_clients, &cXinelibThread::SetStillMode, false);
- }
-}
-
-void cXinelibDevice::Play(void)
-{
- TRACEF("cXinelibDevice::Play");
-
- m_SkipAudio = false;
-
- ForEach(m_clients, &cXinelibThread::SetLiveMode, false);
- TrickSpeed(-1);
-}
-
-void cXinelibDevice::Freeze(void)
-{
- TRACEF("cXinelibDevice::Freeze");
-
- TsBufferFlush();
- TrickSpeed(0);
-}
-
-int64_t cXinelibDevice::GetSTC(void)
-{
- TRACEF("cXinelibDevice::GetSTC");
-
- if(m_local)
- return m_local->GetSTC();
- if(m_server)
- return m_server->GetSTC();
- return cDevice::GetSTC();
-}
-
-bool cXinelibDevice::Flush(int TimeoutMs)
-{
- TRACEF("cXinelibDevice::Flush");
- TRACK_TIME(500);
-
- TsBufferFlush();
-
- if(m_TrickSpeed == 0) {
- ForEach(m_clients, &cXinelibThread::SetLiveMode, false);
- TrickSpeed(-1);
- }
-
- bool r = ForEach(m_clients, &cXinelibThread::Flush, TimeoutMs,
- &mand<bool>, true);
-
- return r;
-}
-
-
-//
-// Playback of files and images
-//
-
-int cXinelibDevice::PlayFileCtrl(const char *Cmd, int TimeoutMs)
-{
- TRACEF("cXinelibDevice::PlayFile");
- int result = -1;
-
- /*if(m_PlayingFile != pmNone)*/ {
- if(m_server)
- result = m_server->PlayFileCtrl(Cmd, TimeoutMs);
- if(m_local)
- result = m_local->PlayFileCtrl(Cmd, TimeoutMs);
- }
- return result;
-}
-
-bool cXinelibDevice::EndOfStreamReached(void)
-{
- if(m_local && !m_local->EndOfStreamReached())
- return false;
- if(m_server && !m_server->EndOfStreamReached())
- return false;
- return true;
-}
-
-bool cXinelibDevice::PlayFile(const char *FileName, int Position,
- bool LoopPlay, ePlayMode PlayMode,
- int TimeoutMs)
-{
- TRACEF("cXinelibDevice::PlayFile");
- TRACE("cXinelibDevice::PlayFile(\"" << FileName << "\")");
-
- bool result = true;
-
- if(FileName) {
- if(m_PlayingFile == pmNone) {
- m_PlayingFile = PlayMode;
- if (!xc.IsImageFile(FileName))
- StopOutput();
- }
- for(int i = 0; i < mi_Count; i++)
- m_MetaInfo[i][0] = 0;
- if(m_server)
- result = m_server->PlayFile(FileName, Position, LoopPlay, PlayMode, TimeoutMs);
- if(m_local)
- result = m_local->PlayFile(FileName, Position, LoopPlay, PlayMode, TimeoutMs);
- } else if(/*!FileName &&*/m_PlayingFile != pmNone) {
- if(m_server)
- result = m_server->PlayFile(NULL, 0, 0, pmNone, TimeoutMs);
- if(m_local)
- result = m_local->PlayFile(NULL, 0, 0, pmNone, TimeoutMs);
- if(!m_liveMode)
- SetReplayMode();
- else
- SetTvMode(Channels.GetByNumber(cDevice::CurrentChannel()));
- m_PlayingFile = pmNone;
- }
-
- return result;
-}
-
-//
-// Data stream handling
-//
-
-int cXinelibDevice::PlayTrickSpeed(const uchar *buf, int length)
-{
-#if VDRVERSNUM >= 10705
- return 0;
-#endif
- if(abs(m_TrickSpeed) > 1 && (m_TrickSpeedMode & trs_I_frames)) {
- uint8_t PictureType = pes_get_picture_type(buf, length);
-#ifdef LOG_TRICKSPEED
- if(PictureType != NO_PICTURE && PES_HAS_PTS(buf)) {
- int64_t pts = pes_get_pts(buf, length);
- LOGMSG(" TrickSpeed: frame %s pts %"PRId64, picture_type_str[PictureType], pts);
- }
-#endif
-
-#if 1
- // limit I-frame rate
- if(PictureType == I_FRAME) {
- static int64_t t0 = 0;
- int64_t t1 = cTimeMs::Now();
- if((t1 - t0) < 1000) {
- int fdelay = 40*12; // = 480 ms, time of one GOP in normal speed
- switch(m_TrickSpeed) {
- case 6: /* 2x ff */ fdelay /= min( 2, xc.max_trickspeed); break;
- case 3: /* 4x ff */ fdelay /= min( 4, xc.max_trickspeed); break;
- case 1: /* 12x ff */ fdelay /= min(12, xc.max_trickspeed); break;
- case 63: /* 1/6x rew */ fdelay *= 6; break;
- case 48: /* 1/4x rew */ fdelay *= 4; break;
- case 24: /* 1/2x rew */ fdelay *= 2; break;
- default: break;
- }
- /* wait if data is coming in too fast */
- if(fdelay - (t1-t0) >= 40) {
- m_TrickSpeedDelay = 40;
- return -1;
- }
-
- t0 += fdelay;
-
- pes_change_pts((uchar*)buf, length, INT64_C(0));
- } else {
- t0 = t1;
- }
- }
-#endif
- }
-
- //
- // detecting trick speed mode ?
- //
- if( m_TrickSpeed > 0 && (m_TrickSpeedMode & trs_PTS_check) && IS_VIDEO_PACKET(buf)) {
- int64_t pts;
- if (PES_HAS_PTS(buf) && (pts = pes_get_pts(buf, length)) > 0) {
- uint8_t PictureType = pes_get_picture_type(buf, length);
- if(PictureType != I_FRAME && PictureType != NO_PICTURE) {
- // --> must be fast worward with IBP frames.
- // --> PTS check does not work (frames are sent in decoder order) ! */
- m_TrickSpeedPts = pts - 1;
- LOGTRICKSPEED(" Detected fast forward mode, using IBP frames");
- }
- if(m_TrickSpeedPts == 0) {
- m_TrickSpeedMode |= trs_NoAudio;
- m_TrickSpeedPts = pts;
- LOGTRICKSPEED(" Seen video pts = %"PRId64, pts);
- } else {
- if(pts < m_TrickSpeedPts) {
- /* -> playing fast backwards */
- LOGTRICKSPEED(" Detected fast backward mode. last %"PRId64" now %"PRId64,
- m_TrickSpeedPts, pts);
- //if(!(m_TrickSpeedMode & trs_PTS_recalc))
- // ForEach(m_clients, &cXinelibThread::Clear);
- m_TrickSpeedMode = trs_I_frames | trs_PTS_recalc | trs_NoAudio;
- } else {
- LOGTRICKSPEED(" Detected fast forward mode");
- if(xc.ibp_trickspeed)
- m_TrickSpeedMode = trs_IPB_frames;
- else
- m_TrickSpeedMode = trs_I_frames;
- }
- }
- }
- }
-
- //
- // Trick speed mode with PTS re-calc
- //
- if( m_TrickSpeed > 0 && (m_TrickSpeedMode & trs_PTS_recalc) &&
- IS_VIDEO_PACKET(buf) && PES_HAS_PTS(buf)) {
- int64_t pts = pes_get_pts(buf, length);
- if (pts > 0) {
-
- /* m_TrickSpeedPts could be 0 in case of slow backwards */
- if(m_TrickSpeedPts == 0)
- m_TrickSpeedPts = pts;
-
- LOGTRICKSPEED(" pts %"PRId64" -> %"PRId64" (diff %"PRId64") %"PRId64"", pts,
- m_TrickSpeedPts + 40*12*90, m_TrickSpeedPts + 40*12*90 - pts,
- (m_TrickSpeedPts + 40*12*90)^0x80000000);
- pts = m_TrickSpeedPts = m_TrickSpeedPts + 40*12*90; /* 12 frames * 40ms -> pts units */
- pts ^= 0x80000000; /* discontinuity (when mode changes) forces re-syncing of all clocks */
- pes_change_pts((uchar*)buf, length, pts);
- }
- }
-
-#if 1
- else if (m_TrickSpeedMode & trs_I_frames) {
- if (IS_VIDEO_PACKET(buf) && PES_HAS_PTS(buf)) {
- int64_t pts = pes_get_pts(buf, length);
- if (pts > 0) {
- pts ^= 0x80000000; /* discontinuity (when mode changes) forces re-syncing of all clocks */
- pes_change_pts((uchar*)buf, length, pts);
- }
- }
- }
-#endif
-
- return 0;
-}
-
-int cXinelibDevice::PlayAny(const uchar *buf, int length)
-{
- TRACEF("cXinelibDevice::PlayAny");
- TRACK_TIME(100);
-
-#if 0
- if(m_PlayingFile)
- return length;
-#endif
-
- if (!buf || length <= 0)
- return length;
-
- //
- // Need to be sure Poll has been called for every frame:
- // - cDevice can feed multiple frames after each poll from player/transfer.
- // - If only part of frames are consumed, rest are fed again after next Poll.
- // - If there are multiple clients it is possible first client(s)
- // can queue more frames than last client(s).
- // -> frame(s) are either lost immediately (last client(s))
- // or duplicated after next poll (first client(s))
- //
- if(m_FreeBufs < 1) {
- cPoller Poller;
- if(!Poll(Poller,0)) {
- errno = EAGAIN;
- return 0;
- }
- }
-
- bool isMpeg1 = false;
- if (DATA_IS_PES(buf)) {
- isMpeg1 = pes_is_mpeg1(buf);
- int len = pes_packet_len(buf, length);
- if (len>0 && len != length)
- LOGMSG("cXinelibDevice::PlayAny: invalid data !");
- }
-
- if(m_TrickSpeed > 0) {
- if(PlayTrickSpeed(buf, length) < 0)
- return 0; /* wait if data is coming in too fast */
- } else if(m_SkipAudio) {
- /* needed for still images when moving cutting marks */
- if (DATA_IS_PES(buf))
- pes_change_pts((uchar*)buf, length, INT64_C(0));
- }
- m_Cleared = false;
- m_FreeBufs --;
-
- if(m_local) {
- length = (isMpeg1 ? m_local->Play_Mpeg1_PES(buf,length) :
- m_local->Play_PES(buf,length));
- }
- if(m_server && length > 0) {
- int length2 = isMpeg1 ? m_server->Play_Mpeg1_PES(buf, length) :
- m_server->Play_PES(buf, length);
- if(!m_local)
- return length2;
- }
-
- return length;
-}
-
-#if VDRVERSNUM >= 10701
-/*
- * hook to PlayTs() to get PAT and PMT
- */
-int cXinelibDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
-{
- if (Length > TS_SIZE) Length = TS_SIZE;
-
- if (Length == TS_SIZE && TsHasPayload(Data)) {
- int PayloadOffset = TsPayloadOffset(Data);
- if (PayloadOffset < Length) {
- int Pid = TsPid(Data);
- if (Pid == 0) {
-#if VDRVERSNUM >= 10704
- m_PatPmtParser.ParsePat(Data, Length);
-#else
- m_PatPmtParser.ParsePat(Data + PayloadOffset, Length - PayloadOffset);
-#endif
- LOGMSG("Got PAT: PMT pid = %d", m_PatPmtParser.PmtPid());
- if (m_server)
- m_server->SetHeader(Data, Length, true);
- PlayTsAny(Data, Length);
- } else if (Pid == m_PatPmtParser.PmtPid()) {
-#if VDRVERSNUM >= 10704
- m_PatPmtParser.ParsePmt(Data, Length);
-#else
- m_PatPmtParser.ParsePmt(Data + PayloadOffset, Length - PayloadOffset);
-#endif
- m_h264 = (m_PatPmtParser.Vtype() == 0x1b); /* ISO_14496_PART10_VIDEO */
- LOGMSG("Got PMT packet, h264 = %d", m_h264?1:0);
- if (m_server)
- m_server->SetHeader(Data, Length);
- PlayTsAny(Data, Length);
- TsBufferFlush();
- }
- }
- } else if (!Data) {
- TsBufferFlush();
- }
-
- return cDevice::PlayTs(Data, Length, VideoOnly);
-}
-
-int cXinelibDevice::TsBufferFlush(void)
-{
- if (m_TsBufSize) {
- int n;
- if ((n = PlayAny(m_TsBuf, m_TsBufSize)) == (int)m_TsBufSize) {
- m_TsBufSize = 0;
- return n;
- }
- if (n)
- LOGMSG("cXinelibDevice::TsBufferFlush: error: cache not flushed (%d %d)", n, m_TsBufSize);
- errno = EAGAIN;
- }
- return 0;
-}
-
-int cXinelibDevice::PlayTsAny(const uchar *buf, int length)
-{
- if (!DATA_IS_TS(buf))
- LOGMSG("PlayTsAny(): TS SYNC byte missing !");
- if (length != TS_SIZE)
- LOGMSG("PlayTsAny(): length == %d !", length);
-
- // cache full ? try to flush it
- if (m_TsBufSize >= 2048)
- if (!TsBufferFlush())
- return 0;
-
- // add packet to cache
- memcpy(m_TsBuf + m_TsBufSize, buf, length);
- m_TsBufSize += length;
-
- // time to flush ?
- if (m_TsBufSize >= 2048-TS_SIZE-1)
- TsBufferFlush();
-
- return length;
-}
-
-int cXinelibDevice::PlayTsSubtitle(const uchar *Data, int Length)
-{
- if (!xc.dvb_subtitles)
- return cDevice::PlayTsSubtitle(Data, Length);
-
- return PlayTsAny(Data, Length);
-}
-
-int cXinelibDevice::PlayTsAudio(const uchar *Data, int Length)
-{
- return PlayTsAny(Data, Length);
-}
-
-int cXinelibDevice::PlayTsVideo(const uchar *Data, int Length)
-{
- return PlayTsAny(Data, Length);
-}
-#endif // VDRVERSNUM >= 10701
-
-int cXinelibDevice::PlayVideo(const uchar *buf, int length)
-{
- TRACEF("cXinelibDevice::PlayVideo");
- TRACK_TIME(100);
-
- if(m_PlayMode == pmAudioOnlyBlack)
- return length;
-
- if (!DATA_IS_PES(buf)) {
- LOGMSG("PlayVideo: data is not PES !");
- return length;
- }
-
- if(m_RadioStream) {
- m_RadioStream = false;
- m_AudioCount = 0;
- ForEach(m_clients, &cXinelibThread::SetNoVideo, m_RadioStream);
- }
-
- if(m_StreamStart) {
-#ifdef START_IFRAME
- // Start with I-frame if stream has video
- // wait for first I-frame
- if (pes_get_picture_type(buf, length) == I_FRAME) {
- m_StreamStart = false;
- } else {
- return length;
- }
-#endif
-
- if (!m_h264 && pes_is_frame_h264(buf, length)) {
- LOGMSG("cXinelibDevice::PlayVideo: Detected H.264 video");
- m_h264 = true;
- }
-
- if (pes_get_video_size(buf, length, m_VideoSize, m_h264 ? 1:0)) {
- m_StreamStart = false;
- LOGDBG("Detected video size %dx%d", m_VideoSize->width, m_VideoSize->height);
- ForEach(m_clients, &cXinelibThread::SetHDMode, (m_VideoSize->width > 800));
- }
- }
-
-#ifdef DEBUG_SWITCHING_TIME
- if(m_statusMonitor->switchtimeOff && m_statusMonitor->switchtimeOn) {
- if (pes_get_picture_type(buf, length) == I_FRAME)
- m_statusMonitor->IFrame();
- }
-#endif
-
- if(m_PlayingFile && (m_PlayingFile == pmAudioVideo || m_PlayingFile == pmVideoOnly))
- return length;
-
- return PlayAny(buf, length);
-}
-
-void cXinelibDevice::StillPicture(const uchar *Data, int Length)
-{
- TRACEF("cXinelibDevice::StillPicture");
-
- // skip still images coming in too fast (ex. when moving cutting marks)
- if(cRemote::HasKeys()) {
- static int skipped = 0;
- static uint64_t lastshow = 0;
- uint64_t now = cTimeMs::Now();
- if(now - lastshow < 500) {
- skipped++;
- //LOGMSG("Skipping still image (coming in too fast)");
- return;
- }
- LOGDBG("Forcing still image - skipped %d images", skipped);
- lastshow = now;
- skipped = 0;
- }
-
- bool isPes = DATA_IS_PES(Data) && ((Data[3] & 0xF0) == 0xE0);
- bool isMpeg1 = isPes && ((Data[6] & 0xC0) != 0x80);
- bool isH264 = isPes && pes_is_frame_h264(Data, Length);
-#if VDRVERSNUM >= 10701
- bool isTs = DATA_IS_TS(Data);
-#endif
-
- int i;
-
- if(m_PlayingFile && (m_PlayingFile == pmAudioVideo || m_PlayingFile == pmVideoOnly))
- return;
-
- TsBufferFlush();
-
- ForEach(m_clients, &cXinelibThread::Clear);
- ForEach(m_clients, &cXinelibThread::SetNoVideo, false);
- ForEach(m_clients, &cXinelibThread::SetLiveMode, false);
- ForEach(m_clients, &cXinelibThread::SetStillMode, true);
- ForEach(m_clients, &cXinelibThread::TrickSpeed, 1);
-
- m_TrickSpeed = -1; // to make Poll work ...
- m_SkipAudio = 1; // enables audio and pts stripping
-
- for(i=0; i<STILLPICTURE_REPEAT_COUNT; i++)
- if(isMpeg1) {
- ForEach(m_clients, &cXinelibThread::Play_Mpeg1_PES, Data, Length,
- &mmin<int>, Length);
- } else if(isPes) {
- /*cDevice::*/PlayPes(Data, Length, m_SkipAudio);
-#if VDRVERSNUM >= 10701
- } else if(isTs) {
- /*cDevice::*/PlayTs(Data, Length, m_SkipAudio);
-#endif
- } else {
- ForEach(m_clients, &cXinelibThread::Play_Mpeg2_ES,
- Data, Length, VIDEO_STREAM,
- &mand<bool>, true);
- }
-
- if(!isH264) {
- // creates empty video PES with pseudo-pts
- ForEach(m_clients, &cXinelibThread::Play_Mpeg2_ES,
- Data, 0, VIDEO_STREAM,
- &mand<bool>, true);
- }
-
- TsBufferFlush();
-
- ForEach(m_clients, &cXinelibThread::Flush, 60,
- &mand<bool>, true);
-
- m_TrickSpeed = 0;
- m_SkipAudio = 0;
-}
-
-int cXinelibDevice::PlayAudio(const uchar *buf, int length, uchar Id)
-{
- TRACEF("cXinelibDevice::PlayAudio");
- TRACK_TIME(100);
-
- if(!buf || length < 6)
- return length;
-
-#ifdef SKIP_AC3_AUDIO
- // skip AC3 audio
- if(((unsigned char *)buf)[3] == PRIVATE_STREAM1) {
- TRACE("cXinelibDevice::PlayVideo: PRIVATE_STREAM1 discarded");
- return length;
- }
-#endif
-
- // strip audio in trick speed modes and when displaying still images
- if(m_SkipAudio /*|| m_TrickSpeed > 0*/)
- return length;
- if(m_TrickSpeedMode & trs_NoAudio)
- return length;
-
- if(m_RadioStream) {
- if(m_AudioCount) {
- m_AudioCount--;
- if(!m_AudioCount) {
- LOGDBG("PlayAudio detected radio stream");
- ForEach(m_clients, &cXinelibThread::SetNoVideo, m_RadioStream);
- }
- }
- }
-
- if(m_PlayingFile && (m_PlayingFile == pmAudioVideo || m_PlayingFile == pmAudioOnly))
- return length;
-
- return PlayAny(buf, length);
-}
-
-int cXinelibDevice::PlaySubtitle(const uchar *Data, int Length)
-{
- if(!xc.dvb_subtitles)
- return cDevice::PlaySubtitle(Data, Length);
- return PlayAny(Data, Length);
-}
-
-bool cXinelibDevice::Poll(cPoller &Poller, int TimeoutMs)
-{
- TRACEF("cXinelibDevice::Poll");
- TRACK_TIME(400);
-
- if(m_PlayingFile == pmAudioVideo)
- return true;
-
- if(m_TrickSpeed == 0) {
- cCondWait::SleepMs(min(TimeoutMs, 20));
- return Poller.Poll(0);
- }
-
- if(!m_local && !m_server) {
- /* nothing to do... why do I exist ... ? */
- //cCondWait::SleepMs(TimeoutMs);
- //return Poller.Poll(0);
- return true;
- }
-
- if(m_TrickSpeed > 1 && m_TrickSpeedDelay > 20) {
- LOGTRICKSPEED(" Poll: m_TrickSpeedDelay=%d.", m_TrickSpeedDelay);
- cCondWait::SleepMs(20);
- m_TrickSpeedDelay -= 20;
- return false;
- }
-
- if(m_FreeBufs < 1) {
- int result = DEFAULT_POLL_SIZE;
-
- if(m_local)
- result = min(result, m_local->Poll(Poller, TimeoutMs));
- if(m_server)
- result = min(result, m_server->Poll(Poller, TimeoutMs));
-
- m_FreeBufs = max(result, 0);
- }
-
- return m_FreeBufs > 0 /*|| Poller.Poll(0)*/;
-}
-
-//
-// Audio facilities
-//
-
-void cXinelibDevice::SetVolumeDevice(int Volume)
-{
- TRACEF("cXinelibDevice::SetVolumeDevice");
-
- ForEach(m_clients, &cXinelibThread::SetVolume, Volume);
-}
-
-void cXinelibDevice::SetAudioTrackDevice(eTrackType Type)
-{
- TRACEF("cXinelibDevice::SetAudioTrackDevice");
-
- // track changes are autodetected at xine side
-}
-
-void cXinelibDevice::SetAudioChannelDevice(int AudioChannel)
-{
- TRACEF("cXinelibDevice::SetAudioChannelDevice");
-
- if(m_AudioChannel != AudioChannel) {
- m_AudioChannel = AudioChannel;
- //LOGDBG("cXinelibDevice::SetAudioChannelDevice --> %d", AudioChannel);
-#if 0
- switch(AudioChannel) {
- default:
- //case 0: ConfigurePostprocessing("upmix_mono", false, NULL);
- case 0: ConfigurePostprocessing("upmix_mono", true, "channel=-1");
- break;
- case 1: ConfigurePostprocessing("upmix_mono", true, "channel=0");
- break;
- case 2: ConfigurePostprocessing("upmix_mono", true, "channel=1");
- break;
- }
-#else
- switch(AudioChannel) {
- default:
- case 0: ConfigurePostprocessing("audiochannel", false, NULL);
- break;
- case 1: ConfigurePostprocessing("audiochannel", true, "channel=0");
- break;
- case 2: ConfigurePostprocessing("audiochannel", true, "channel=1");
- break;
- }
-#endif
- }
-}
-
-void cXinelibDevice::SetDigitalAudioDevice(bool On)
-{
- TRACEF("cXinelibDevice::SetDigitalAudioDevice");
-
- // track changes are autodetected at xine side
-}
-
-//
-// Video format facilities
-//
-
-void cXinelibDevice::SetVideoFormat(bool VideoFormat16_9)
-{
- TRACEF("cXinelibDevice::SetVideoFormat");
- cDevice::SetVideoFormat(VideoFormat16_9);
-
-#if 0
- //
- // TODO
- //
- if(xc.aspect != ASPECT_AUTO &&
- xc.aspect != ASPECT_DEFAULT) {
- if(VideoFormat16_9)
- xc.aspect = ASPECT_16_9;
- else if(xc.aspect == ASPECT_16_9)
- xc.aspect = ASPECT_4_3;
- ConfigureDecoder(,,,xc.aspect,,,);
- }
-#endif
-}
-
-void cXinelibDevice::SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
-{
- TRACEF("cXinelibDevice::SetVideoDisplayFormat");
- cDevice::SetVideoDisplayFormat(VideoDisplayFormat);
-
-#if 0
- //
- // TODO
- //
- // - set normal, pan&scan, letterbox (only for 4:3?)
- //
- if(xc.aspect != ASPECT_AUTO &&
- xc.aspect != ASPECT_DEFAULT) {
- switch(VideoDisplayFormat) {
- case vdfPanAndScan:
- xc.aspect = ASPECT_PAN_SCAN;
- break;
- case vdfLetterBox:
- xc.aspect = ASPECT_4_3; /* borders are added automatically if needed */
- break;
- case vdfCenterCutOut:
- xc.aspect = ASPECT_CENTER_CUT_OUT;
- break;
- }
- ConfigureDecoder(,,,xc.aspect,,,);
- }
-#endif
-}
-
-eVideoSystem cXinelibDevice::GetVideoSystem(void)
-{
- TRACEF("cXinelibDevice::GetVideoSystem");
- return cDevice::GetVideoSystem();
-}
-
-#if VDRVERSNUM >= 10708
-void cXinelibDevice::GetVideoSize(int &Width, int &Height, double &VideoAspect)
-{
- Width = m_VideoSize->width;
- Height = m_VideoSize->height;
- VideoAspect = 1.0;
- if (m_VideoSize->pixel_aspect.den) {
- VideoAspect = (double)m_VideoSize->pixel_aspect.num / (double)m_VideoSize->pixel_aspect.den;
- VideoAspect *= (double)Width / (double)Height;
- }
-}
-#endif
-
-void cXinelibDevice::GetOsdSize(int &Width, int &Height, double &PixelAspect)
-{
- Width = 720;
- Height = 576;
- PixelAspect = 16.0 / 9.0 / (double)Width * (double)Height;
-}
-
-//
-// SPU decoder
-//
-
-#ifdef FORWARD_DVD_SPUS
-# include "spu_decoder.h"
-#endif
-
-cSpuDecoder *cXinelibDevice::GetSpuDecoder(void)
-{
- TRACEF("cXinelibDevice::GetSpuDecoder");
- if (!m_spuDecoder && IsPrimaryDevice()) {
- //
- // TODO
- //
- // - use own derived SpuDecoder with special cXinelibOsd
- // -> always visible
- //
-
-#ifdef FORWARD_DVD_SPUS
- // forward DVD SPUs to xine without decoding
- m_spuDecoder = new cFwdSpuDecoder(this);
-#else
- m_spuDecoder = new cDvbSpuDecoder();
-#endif
- }
- return m_spuDecoder;
-}
-
-//
-// Image Grabbing
-//
-
-uchar *cXinelibDevice::GrabImage(int &Size, bool Jpeg,
- int Quality, int SizeX, int SizeY)
-{
- TRACEF("cXinelibDevice::GrabImage");
-
- if(m_local)
- return m_local->GrabImage(Size, Jpeg, Quality, SizeX, SizeY);
- if(m_server)
- return m_server->GrabImage(Size, Jpeg, Quality, SizeX, SizeY);
-
- return NULL;
-}
-
-
-//
-// Available DVD SPU tracks
-//
-
-void cXinelibDevice::SetSubtitleTrackDevice(eTrackType Type)
-{
- if (m_PlayingFile == pmAudioVideo || m_PlayingFile == pmVideoOnly)
- ForEach(m_clients, &cXinelibThread::SetSubtitleTrack, Type);
-}
-
-//
-// Metainfo
-//
-
-const char *cXinelibDevice::GetMetaInfo(eMetainfoType Type)
-{
- if(Type >= 0 && Type < mi_Count) {
- if ((Type == miTitle) ||
- (Type == miTracknumber && xc.playlist_tracknumber == 1) ||
- (Type == miArtist && xc.playlist_artist == 1) ||
- (Type == miAlbum && xc.playlist_album == 1) ||
- (Type > miAlbum)) {
- return m_MetaInfo[Type];
- }
- return "";
- }
-
- LOGMSG("cXinelibDevice::GetMetaInfo: unknown metainfo type");
- return "";
-}
-
-void cXinelibDevice::SetMetaInfo(eMetainfoType Type, const char *Value)
-{
- if(Type >= 0 && Type < mi_Count) {
- /* set to 0 first, so if player is accessing string in middle of
- copying it will always be 0-terminated (but truncated) */
- memset(m_MetaInfo[Type], 0, sizeof(m_MetaInfo[Type]));
- strn0cpy(m_MetaInfo[Type], Value, MAX_METAINFO_LEN);
- } else {
- LOGMSG("cXinelibDevice::SetMetaInfo: unknown metainfo type");
- }
-}
-
diff --git a/device.h b/device.h
deleted file mode 100644
index 04f23f52..00000000
--- a/device.h
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * device.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: device.h,v 1.48 2009-06-24 20:43:45 phintuka Exp $
- *
- */
-
-#ifndef __XINELIB_DEVICE_H
-#define __XINELIB_DEVICE_H
-
-#include <vdr/config.h>
-#include <vdr/device.h>
-#include <vdr/tools.h>
-
-class cXinelibStatusMonitor;
-class cXinelibThread;
-class cChannel;
-class cFunctor;
-
-struct video_size_s;
-
-typedef enum {
- miTitle = 0,
- miTracknumber = 1,
- miArtist = 2,
- miAlbum = 3,
- miDvdTitleNo = 4,
- miDvdButtons = 5,
- mi_Count = 6
-} eMetainfoType;
-
-# define ttXSubtitleNone (-2)
-# define ttXSubtitleAuto (-1)
-
-#define MAX_METAINFO_LEN 63
-
-class cXinelibDevice : public cDevice
-{
-
- // Singleton
-
- private:
- static cXinelibDevice* m_pInstance; // singleton
- cXinelibDevice(); //
- cXinelibDevice(cXinelibDevice&); // no copy constructor
-
- public:
- static cXinelibDevice& Instance(void); // singleton
- static void Dispose(void);
-
- virtual ~cXinelibDevice();
-
- // device start/stop (from cPlugin)
-
- public:
- bool StartDevice(void);
- void StopDevice(void);
-
- // function calls waiting to be executed in VDR main thread context
-
- private:
- cList<cFunctor> m_MainThreadFunctors;
- cMutex m_MainThreadLock;
-
- public:
- void MainThreadHook(void);
-
- // Primary device switching
-
- private:
- int m_OriginalPrimaryDevice;
- int m_ForcePrimaryDeviceCnt;
-
- void ForcePrimaryDeviceImpl(bool On);
-
- public:
- virtual void MakePrimaryDevice(bool On);
- void ForcePrimaryDevice(bool On);
-
- // Device capabilities
-
- public:
- virtual bool HasDecoder(void) const { return true; };
- virtual bool CanReplay(void) const { return true; };
- virtual bool HasIBPTrickSpeed(void) { return xc.ibp_trickspeed; }
-
- // Playback control
-
- private:
- ePlayMode m_PlayMode;
- int m_TrickSpeed;
- int64_t m_TrickSpeedPts;
- int m_TrickSpeedMode;
- int m_TrickSpeedDelay;
-
- public:
- virtual bool SetPlayMode(ePlayMode PlayMode);
- ePlayMode GetPlayMode(void) const { return m_PlayMode; };
-
- protected:
- virtual void Clear(void);
- virtual void Play(void);
- virtual void TrickSpeed(int Speed);
- virtual void Freeze(void);
- virtual bool Flush(int TimeoutMs = 0);
- virtual int64_t GetSTC(void);
-
- // Video format facilities
-
- public:
- virtual void SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat);
- virtual void SetVideoFormat(bool VideoFormat16_9);
- virtual eVideoSystem GetVideoSystem(void);
-
- struct video_size_s *m_VideoSize;
-#if VDRVERSNUM >= 10708
- virtual void GetVideoSize(int &Width, int &Height, double &VideoAspect);
-#endif
- virtual void GetOsdSize(int &Width, int &Height, double &PixelAspect);
-
- // Track facilities
-
- protected:
- virtual void SetAudioTrackDevice(eTrackType Type);
- public:
- virtual void SetSubtitleTrackDevice(eTrackType Type);
-
- // Audio facilities
-
- private:
- int m_AudioChannel;
-
- protected:
- virtual int GetAudioChannelDevice(void) { return m_AudioChannel; }
- virtual void SetAudioChannelDevice(int AudioChannel);
- virtual void SetVolumeDevice(int Volume);
- virtual void SetDigitalAudioDevice(bool On);
-
- // Image grabbing
-
- public:
- virtual uchar *GrabImage(int &Size, bool Jpeg = true,
- int Quality = -1, int SizeX = -1, int SizeY = -1);
-
- // SPU decoder
-
- private:
- cSpuDecoder *m_spuDecoder;
-
- friend class cXineSpuDecoder;
-
- public:
- virtual cSpuDecoder *GetSpuDecoder(void);
-
- // Messages from StatusMonitor:
-
- private:
- cXinelibStatusMonitor *m_statusMonitor;
- bool m_liveMode;
-
- public:
- void SetTvMode(cChannel *Channel);
- void SetReplayMode(void);
- void StopOutput(void);
-
- // Osd Commands (from cXinelibOsd)
-
- public:
- void OsdCmd(void *cmd);
-
- // Configuration
-
- private:
- cList<cXinelibThread> m_clients;
- cXinelibThread *m_server;
- cXinelibThread *m_local;
-
- public:
- void ConfigurePostprocessing(const char *deinterlace_method,
- int audio_delay,
- int audio_compression,
- const int *audio_equalizer,
- int audio_surround,
- int speaker_type);
- void ConfigurePostprocessing(const char *name, bool on = true,
- const char *args = NULL);
- void ConfigureVideo(int hue, int saturation, int brightness, int sharpness,
- int noise_reduction, int contrast, int overscan, int vo_aspect_ratio);
- // local mode:
- void ConfigureWindow(int fullscreen, int width, int height,
- int modeswitch, const char *modeline,
- int aspect, int scale_video, int field_order);
- void ConfigureDecoder(int pes_buffers);
- // remote mode:
- void Listen(bool activate, int port);
-
- // File playback
-
- private:
- ePlayMode m_PlayingFile;
-
- public:
- bool PlayFile(const char *Filename, int Position = 0,
- bool LoopPlay = false, ePlayMode PlayMode = pmAudioVideo,
- int TimeoutMs = -1);
- int PlayFileCtrl(const char *Cmd, int TimeoutMs = -1);
- bool EndOfStreamReached(void);
-
- // Metainfo cache
-
- private:
- char m_MetaInfo[mi_Count][MAX_METAINFO_LEN+1];
-
- public:
- const char *GetMetaInfo(eMetainfoType Type);
- void SetMetaInfo(eMetainfoType Type, const char *Value);
-
- // Stream data
-
- private:
- bool m_ac3Present;
- bool m_spuPresent;
- bool m_RadioStream;
- int m_AudioCount;
- bool m_SkipAudio;
- bool m_StreamStart;
- int m_FreeBufs;
- bool m_Cleared;
- bool m_h264;
-
- int PlayAny(const uchar *Data, int Length);
- int PlayTrickSpeed(const uchar *buf, int length);
-
- protected:
-
- virtual bool Poll(cPoller &Poller, int TimeoutMs = 0);
-
- virtual void StillPicture(const uchar *Data, int Length);
-
- virtual int PlayVideo(const uchar *Data, int Length);
- virtual int PlayAudio(const uchar *Data, int Length, uchar Id);
- virtual int PlaySubtitle(const uchar *Data, int Length);
-
-#if VDRVERSNUM >= 10701
- cPatPmtParser m_PatPmtParser;
-
- /* join multiple TS packets to xineliboutput transport packet */
- uint8_t m_TsBuf[4096];
- uint m_TsBufSize;
- int TsBufferFlush(void);
- void TsBufferClear(void) { m_TsBufSize = 0; };
-
- int PlayTsAny(const uchar *Data, int Length);
-
- virtual int PlayTsVideo(const uchar *Data, int Length);
- virtual int PlayTsAudio(const uchar *Data, int Length);
- virtual int PlayTsSubtitle(const uchar *Data, int Length);
- virtual int PlayTs(const uchar *Data, int Length, bool VideoOnly = false);
-#else
- void TsBufferClear(void) {}
- void TsBufferFlush(void) {}
-#endif
-};
-
-#endif // __XINELIB_DEVICE_H
diff --git a/dummy_player.c b/dummy_player.c
deleted file mode 100644
index 8980e656..00000000
--- a/dummy_player.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * dummy_player.c: Player that does nothing (saves CPU time)
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: dummy_player.c,v 1.3 2007-10-15 00:15:07 phintuka Exp $
- *
- */
-
-#include <vdr/status.h>
-
-#include "dummy_player.h"
-#include "tools/timer.h"
-
-#define STILLPICTURE_INTERVAL (5*1000) // 5 sec
-
-//
-// cDummyPlayerControl
-//
-
-extern const unsigned char v_mpg_vdrlogo[]; // vdrlogo_720x576.mpg.c
-extern const int v_mpg_vdrlogo_length; // vdrlogo_720x576.mpg.c
-//extern const unsigned char v_mpg_nosignal[];// nosignal_720x576.mpg.c
-//extern const int v_mpg_nosignal_length; // nosignal_720x576.mpg.c
-//extern const unsigned char v_mpg_black[]; // black_720x576.mpg.c
-//extern const int v_mpg_black_length; // black_720x576.mpg.c
-
-class cDummyPlayer : public cPlayer {
- protected:
- virtual void Activate(bool On)
- {
- if(On) {
- TimerHandler();
- CreateTimerEvent(this, &cDummyPlayer::TimerHandler, STILLPICTURE_INTERVAL);
- } else {
- CancelTimerEvents(this);
- }
- }
- bool TimerHandler(void)
- {
- DeviceStillPicture(v_mpg_vdrlogo, v_mpg_vdrlogo_length);
- //DeviceStillPicture(v_mpg_nosignal, v_mpg_nosignal_length);
- //DeviceStillPicture(v_mpg_black, v_mpg_black_length);
- return true;
- }
-
- public:
- cDummyPlayer(void) {};
- virtual ~cDummyPlayer()
- {
- Activate(false);
- Detach();
- }
-};
-
-//
-// cDummyPlayerControl
-//
-
-cDummyPlayer *cDummyPlayerControl::m_Player = NULL;
-cMutex cDummyPlayerControl::m_Lock;
-
-cDummyPlayerControl::cDummyPlayerControl(void) :
- cControl(OpenPlayer())
-{
- cStatus::MsgReplaying(this, "none", NULL, true);
-}
-
-cDummyPlayerControl::~cDummyPlayerControl()
-{
- cStatus::MsgReplaying(this, NULL, NULL, false);
- Close();
-}
-
-cDummyPlayer *cDummyPlayerControl::OpenPlayer(void)
-{
- m_Lock.Lock();
- if(!m_Player)
- m_Player = new cDummyPlayer;
- m_Lock.Unlock();
- return m_Player;
-}
-
-void cDummyPlayerControl::Close(void)
-{
- m_Lock.Lock();
- if(m_Player)
- delete m_Player;
- m_Player = NULL;
- m_Lock.Unlock();
-}
-
-eOSState cDummyPlayerControl::ProcessKey(eKeys Key)
-{
- if(!ISMODELESSKEY(Key) || Key == kBack || Key == kStop) {
- Close();
- return osEnd;
- }
- return osContinue;
-}
-
diff --git a/dummy_player.h b/dummy_player.h
deleted file mode 100644
index 9af28ba7..00000000
--- a/dummy_player.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * dummy_player.h: Player that does nothing (saves CPU time)
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: dummy_player.h,v 1.1 2006-06-03 09:50:54 phintuka Exp $
- *
- */
-
-#ifndef __DUMMY_PLAYER_H
-#define __DUMMY_PLAYER_H
-
-#include <vdr/player.h>
-
-class cDummyPlayer;
-
-class cDummyPlayerControl : public cControl
-{
- private:
- static cDummyPlayer *m_Player;
- static cMutex m_Lock;
-
- static cDummyPlayer *OpenPlayer(void);
-
- public:
- cDummyPlayerControl(void);
- virtual ~cDummyPlayerControl();
-
- virtual void Show(void) {};
- virtual void Hide(void) {};
- virtual eOSState ProcessKey(eKeys Key);
-
- static void Close(void);
- static bool IsOpen(void) {return m_Player != NULL;};
-};
-
-#endif //__DUMMY_PLAYER_H
-
diff --git a/equalizer.c b/equalizer.c
deleted file mode 100644
index 8762c88c..00000000
--- a/equalizer.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * equalizer.c: audio equalizer OSD control
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: equalizer.c,v 1.5 2008-11-20 11:46:30 rofafor Exp $
- *
- */
-
-#include <vdr/config.h>
-
-#include "config.h"
-#include "device.h"
-#include "equalizer.h"
-
-cEqualizer::cEqualizer() : cOsdObject()
-{
- m_Values = new int[AUDIO_EQ_count];
- memcpy(m_Values, xc.audio_equalizer, sizeof(xc.audio_equalizer));
- m_Osd = NULL;
- m_Current = 0;
-}
-
-cEqualizer::~cEqualizer()
-{
- delete m_Osd;
- delete m_Values;
-}
-
-#define OSD_W (220)
-#define OSD_H (220)
-#define OSD_X (720-50-OSD_W)
-#define OSD_Y (576-50-OSD_H)
-/* dvbdevice requires bpp*width to be n*8 */
-
-#define ADJUST_MIN (-100)
-#define ADJUST_MAX (100)
-#define ADJUST_STEP (5)
-
-void cEqualizer::Show()
-{
- tArea areas [] = { {0, 0, OSD_W - 1, OSD_H - 1, 4} };
-
- m_Osd = cOsdProvider::NewOsd(OSD_X, OSD_Y, 0);
-
- if(m_Osd) {
- if (m_Osd->CanHandleAreas(areas, sizeof(areas) / sizeof(tArea) ) == oeOk) {
- m_Osd->SetAreas(areas, sizeof(areas) / sizeof(tArea));
- m_Osd->Flush();
- DrawBackground();
- DrawBar(0,true);
- for(int i=1; i<AUDIO_EQ_count; i++)
- DrawBar(i);
- }
- }
-}
-
-eOSState cEqualizer::ProcessKey(eKeys key)
-{
- eOSState state = cOsdObject::ProcessKey(key);
- if (state == osUnknown) {
- switch (key & ~k_Repeat) {
- case kDown:
- m_Values[m_Current] -= ADJUST_STEP;
- if(m_Values[m_Current] < ADJUST_MIN)
- m_Values[m_Current] = ADJUST_MIN;
- DrawBar(m_Current,true);
- cXinelibDevice::Instance().ConfigurePostprocessing(xc.deinterlace_method, xc.audio_delay, xc.audio_compression, m_Values, xc.audio_surround, xc.speaker_type);
- break;
- case kUp:
- m_Values[m_Current] += ADJUST_STEP;
- if(m_Values[m_Current] > ADJUST_MAX)
- m_Values[m_Current] = ADJUST_MAX;
- DrawBar(m_Current,true);
- cXinelibDevice::Instance().ConfigurePostprocessing(xc.deinterlace_method, xc.audio_delay, xc.audio_compression, m_Values, xc.audio_surround, xc.speaker_type);
- break;
- case kLeft:
- if(m_Current>0) {
- DrawBar(m_Current);
- m_Current--;
- DrawBar(m_Current, true);
- }
- break;
- case kRight:
- if(m_Current+1 < AUDIO_EQ_count) {
- DrawBar(m_Current);
- m_Current++;
- DrawBar(m_Current, true);
- }
- break;
- case kBack:
- cXinelibDevice::Instance().ConfigurePostprocessing(xc.deinterlace_method, xc.audio_delay, xc.audio_compression, xc.audio_equalizer, xc.audio_surround, xc.speaker_type);
- return osEnd;
- case kOk:
- memcpy(xc.audio_equalizer, m_Values, sizeof(xc.audio_equalizer));
- return osEnd;
- }
- }
-
- return state;
-}
-
-#define COL_BORDER 0xffb0b0b0
-#define COL_BG 0x7f7f7f7f
-#define COL_BAR 0xff000000
-#define COL_BAR_SEL 0xffff0000
-#define COL_BAR_ON 0xff00FF00
-#define COL_BAR_OFF 0xff000000
-#define COL_BAR_BORDER 0xff7f7f7f
-
-void cEqualizer::DrawBackground()
-{
- // border
- m_Osd->DrawRectangle(0, 0, OSD_W - 1, OSD_H - 1, COL_BORDER);
- m_Osd->DrawRectangle(1, 1, OSD_W - 2, OSD_H - 2, COL_BORDER);
- // background
- m_Osd->DrawRectangle(2, 2, OSD_W - 3, OSD_H - 3, COL_BG);
- // line
- m_Osd->DrawRectangle(5, 10+100-1, OSD_W-6, 10+100, COL_BAR);
- // commit
- m_Osd->Flush();
-}
-
-void cEqualizer::DrawBar(int Index, bool Selected)
-{
- // bar
- if(Selected)
- m_Osd->DrawRectangle(10+20*Index, 10, 10+20*Index+7, OSD_H - 10, COL_BAR_SEL);
- else
- m_Osd->DrawRectangle(10+20*Index, 10, 10+20*Index+7, OSD_H - 10, COL_BAR);
- // off
- m_Osd->DrawRectangle(12+20*Index, 10, 10+20*Index+5, OSD_H - 10, COL_BAR_OFF);
- // on
- if(m_Values[Index]>0)
- m_Osd->DrawRectangle(12+20*Index, 10+100-m_Values[Index], 10+20*Index+5, 10+100, COL_BAR_ON);
- else
- m_Osd->DrawRectangle(12+20*Index, 10+100, 10+20*Index+5, 10+100-m_Values[Index], COL_BAR_ON);
- // line
- m_Osd->DrawRectangle(12+20*Index, 10+100-1, 10+20*Index+5, 10+100, COL_BAR_ON);
-
- m_Osd->Flush();
-}
-
-
diff --git a/equalizer.h b/equalizer.h
deleted file mode 100644
index e2c7a9fa..00000000
--- a/equalizer.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * equalizer.h: audio equalizer OSD control
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: equalizer.h,v 1.1 2006-06-03 09:50:54 phintuka Exp $
- *
- */
-
-#ifndef __EQUALIZER_H
-#define __EQUALIZER_H
-
-#include <vdr/config.h>
-#include <vdr/osdbase.h>
-
-class cEqualizer : public cOsdObject
-{
- private:
- int *m_Values;
- int m_Current;
-
- cOsd *m_Osd;
-
- public:
- cEqualizer();
- virtual ~cEqualizer();
-
- virtual void Show();
- virtual eOSState ProcessKey(eKeys Key);
-
- void DrawBackground(void);
- void DrawBar(int Index, bool Selected = false);
-};
-
-#endif // __EQUALIZER_H_
diff --git a/examples/Live Radio/BBC Radio 4 Live.m3u b/examples/Live Radio/BBC Radio 4 Live.m3u
deleted file mode 100755
index daebab2f..00000000
--- a/examples/Live Radio/BBC Radio 4 Live.m3u
+++ /dev/null
@@ -1,4 +0,0 @@
-#EXTM3U
-#EXTINF:111,BBC Radio 4 Live
-rtsp://rmlivev8bb.bbc.net.uk/farm/*/ev7/live24/radio4/live/r4_dsat_g2.ra
-
diff --git a/examples/Live Radio/BBC World Service.ram b/examples/Live Radio/BBC World Service.ram
deleted file mode 100644
index 0a706198..00000000
--- a/examples/Live Radio/BBC World Service.ram
+++ /dev/null
@@ -1 +0,0 @@
-rtsp://rmlivev8.bbc.net.uk/farm/*/ev7/live24/worldservice/liveinfent.ra
diff --git a/examples/remote.conf.example b/examples/remote.conf.example
deleted file mode 100644
index df13bc33..00000000
--- a/examples/remote.conf.example
+++ /dev/null
@@ -1,63 +0,0 @@
-LIRC.Up up
-LIRC.Down down
-LIRC.Left left
-LIRC.Right right
-LIRC.Menu menu
-LIRC.Ok ok
-LIRC.Back exit
-KBD.Up 00000000001B5B41
-KBD.Down 00000000001B5B42
-KBD.Menu 000000000000006D
-KBD.Ok 000000000000000D
-KBD.Back 0000000000000062
-KBD.Left 00000000001B5B44
-KBD.Right 00000000001B5B43
-XKeySym.Up Up
-XKeySym.Down Down
-XKeySym.Left Left
-XKeySym.Right Right
-XKeySym.Menu F1
-XKeySym.Ok Return
-XKeySym.Back BackSpace
-XKeySym.Red F2
-XKeySym.Green F3
-XKeySym.Yellow F4
-XKeySym.Blue F5
-XKeySym.0 0
-XKeySym.1 1
-XKeySym.2 2
-XKeySym.3 3
-XKeySym.4 4
-XKeySym.5 5
-XKeySym.6 6
-XKeySym.7 7
-XKeySym.8 8
-XKeySym.9 9
-XKeySym.Play p
-XKeySym.Pause space
-XKeySym.Stop s
-XKeySym.FastFwd f
-XKeySym.FastRew b
-XKeySym.Channel+ Prior
-XKeySym.Channel- Next
-XKeySym.Volume+ KP_Add
-XKeySym.Volume- KP_Subtract
-XKeySym.Mute m
-XKeySym.Info I
-XKeySym.Audio A
-XKeySym.Subtitles S
-XKeySym.Schedule F6
-XKeySym.Channels F7
-XKeySym.Timers F8
-XKeySym.Recordings F9
-XKeySym.Setup F10
-XKeySym.Commands F11
-XKeySym.User1 q
-XKeySym.User2 w
-XKeySym.User3 e
-XKeySym.User4 r
-XKeySym.User5 t
-XKeySym.User6 y
-XKeySym.User7 u
-XKeySym.User8 i
-XKeySym.User9 o
diff --git a/frontend.c b/frontend.c
deleted file mode 100644
index 9a45d2c7..00000000
--- a/frontend.c
+++ /dev/null
@@ -1,898 +0,0 @@
-/*
- * frontend.c:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: frontend.c,v 1.69 2009-05-29 14:31:46 phintuka Exp $
- *
- */
-
-#define __STDC_FORMAT_MACROS
-#define __STDC_CONSTANT_MACROS
-#include <inttypes.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <time.h>
-#include <pthread.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-
-#include <vdr/config.h>
-#include <vdr/tools.h>
-#include <vdr/plugin.h>
-
-#include "logdefs.h"
-#include "config.h"
-#include "frontend.h"
-#include "device.h"
-
-#include "tools/pes.h"
-#include "tools/mpeg.h"
-#include "tools/h264.h"
-#include "tools/general_remote.h"
-#include "tools/iso639.h"
-
-//#define LOG_CONTROL_MESSAGES
-//#define XINELIBOUTPUT_LOG_KEYS
-
-#ifndef STARTUP_IMAGE_FILE
-# define STARTUP_IMAGE_FILE "/usr/share/vdr/xineliboutput/logo.mpv"
-#endif
-#ifndef STARTUP_MAX_SIZE
-# define STARTUP_MAX_SIZE (256*1024)
-#endif
-
-//----------------------------- cXinelibThread --------------------------------
-
-//
-// keyboard control handler
-//
-
-/*static*/
-void cXinelibThread::KeypressHandler(const char *keymap, const char *key,
- bool repeat, bool release)
-{
-#ifdef XINELIBOUTPUT_LOG_KEYS
- static FILE *flog = fopen("/video/keys.log","w");
- if (flog) {
- fprintf(flog,"KEY %s %s %d %d\n",keymap,key,repeat,release); fflush(flog);
- }
-#endif
-
- TRACE("keypress_handler: " << (keymap?keymap:"") << " " << key);
-
- if(!key)
- return;
-
- if(keymap) {
- cRemote *item = Remotes.First();
- while(item) {
- if(!strcmp(item->Name(), keymap)) {
- // dirty... but only way to support learning ...
- ((cGeneralRemote*)item)->Put(key, repeat, release);
- return;
- }
- item = Remotes.Next(item);
- }
- cGeneralRemote *r = new cGeneralRemote(keymap);
- if(*key)
- r->Put(key, repeat, release);
- } else {
- cRemote::Put(cKey::FromString(key));
- }
-}
-
-#include <vdr/status.h>
-class cFrontendStatusMonitor : public cStatus {
- private:
- bool& m_SpuLangAuto;
- public:
- cFrontendStatusMonitor(bool& SpuLangAuto) : m_SpuLangAuto(SpuLangAuto) {};
- virtual void SetSubtitleTrack(int /*Index*/, const char * const */*Tracks*/) { m_SpuLangAuto = false; }
-};
-
-void cXinelibThread::InfoHandler(const char *info)
-{
- char *pmap = strdup(info), *map = pmap, *pt;
-
- if(NULL != (pt=strchr(map, '\r')))
- *pt = 0;
-
- if(!strncmp(info, "TRACKMAP SPU", 12)) {
- int CurrentTrack = ttXSubtitleAuto;
- map += 12;
- while(*map) {
- bool Current = false;
- while(*map == ' ') map++;
- if(*map == '*') {
- Current = true;
- map++;
- if (*map == '-') {
- CurrentTrack = atoi(map);
- while (*map && *map != ' ') map++;
- continue;
- }
- }
- if(*map >= '0' && *map <= '9') {
- int id = atoi(map);
- while(*map && *map != ':') map++;
- if(*map == ':') map++;
- char *lang = map;
- while(*map && *map != ' ') map++;
- if(*map == ' ') { *map = 0; map++; };
- cXinelibDevice::Instance().SetAvailableTrack(ttSubtitle, id, id+1, iso639_2_to_iso639_1(lang));
- if (Current)
- CurrentTrack = id;
- }
- }
- if (CurrentTrack == ttXSubtitleAuto)
- cXinelibDevice::Instance().EnsureSubtitleTrack();
- else if (CurrentTrack == ttXSubtitleNone)
- cXinelibDevice::Instance().SetCurrentSubtitleTrack(ttNone, true);
- else
- cXinelibDevice::Instance().SetCurrentSubtitleTrack(eTrackType(CurrentTrack+ttSubtitleFirst), true);
- }
-
- else if(!strncmp(info, "TRACKMAP AUDIO", 14)) {
- map += 14;
- cXinelibDevice::Instance().ClrAvailableTracks();
- while(*map) {
- bool Current = false;
- while(*map == ' ') map++;
- if(*map == '*') {
- Current = true;
- map++;
- }
- int id = atoi(map);
- while(*map && *map != ':') map++;
- if(*map == ':') map++;
- char *lang = map;
- while(*map && *map != ' ') map++;
- if(*map == ' ') { *map = 0; map++; };
- cXinelibDevice::Instance().SetAvailableTrack(ttDolby, id, ttDolby+id, iso639_2_to_iso639_1(lang));
- if(Current)
- cXinelibDevice::Instance().SetCurrentAudioTrack((eTrackType)(ttDolby+id));
- }
- }
-
- else if(!strncmp(info, "METAINFO", 8)) {
- map += 8;
- while(*map) {
- while(*map == ' ') map++;
- char *next = strstr(map, "=@");
- if(!next)
- break;
- *next = 0;
- next += 2;
- char *end = strstr(next, "@");
- if(!end)
- break;
- *end = 0;
-
- if(!strcmp(map, "title"))
- cXinelibDevice::Instance().SetMetaInfo(miTitle, next);
- if(!strcmp(map, "tracknumber"))
- cXinelibDevice::Instance().SetMetaInfo(miTracknumber, next);
- if(!strcmp(map, "album"))
- cXinelibDevice::Instance().SetMetaInfo(miAlbum, next);
- if(!strcmp(map, "artist"))
- cXinelibDevice::Instance().SetMetaInfo(miArtist, next);
- map = end+1;
- }
- }
-
- else if(!strncmp(info, "DVDBUTTONS ", 11)) {
- map += 11;
- while(*map == ' ') map++;
- cXinelibDevice::Instance().SetMetaInfo(miDvdButtons, map);
- }
-
- else if(!strncmp(info, "TITLE ", 6)) {
- map += 6;
- while(*map == ' ') map++;
- cXinelibDevice::Instance().SetMetaInfo(miTitle, map);
- }
-
- else if(!strncmp(info, "DVDTITLE ", 9)) {
- map += 9;
- while(*map == ' ') map++;
- cXinelibDevice::Instance().SetMetaInfo(miDvdTitleNo, map);
- if (*map == '0') // DVD Menu, set spu track to 0
- cXinelibDevice::Instance().SetCurrentSubtitleTrack(ttSubtitleFirst);
- }
-
- free(pmap);
-}
-
-cXinelibThread::cXinelibThread(const char *Description) : cThread(Description)
-{
- TRACEF("cXinelibThread::cXinelibThread");
-
- m_Volume = 255;
- m_bStopThread = false;
- m_bReady = false;
- m_bIsFinished = false;
- m_bNoVideo = true;
- m_bLiveMode = true; /* can't be replaying when there is no output device */
- m_StreamPos = 0;
- m_Frames = 0;
- m_bEndOfStreamReached = false;
- m_bPlayingFile = false;
- m_StatusMonitor = NULL;
-}
-
-cXinelibThread::~cXinelibThread()
-{
- TRACEF("cXinelibThread::~cXinelibThread");
-
- m_bStopThread = true;
- if(Active())
- Cancel();
- if(m_StatusMonitor)
- delete m_StatusMonitor;
-}
-
-//
-// Thread control
-//
-
-void cXinelibThread::Start(void)
-{
- TRACEF("cXinelibThread::Start");
-
- cThread::Start();
-}
-
-void cXinelibThread::Stop(void)
-{
- TRACEF("cXinelibThread::Stop");
-
- SetStopSignal();
-
- //if(Active())
- Cancel(5);
-}
-
-void cXinelibThread::SetStopSignal(void)
-{
- TRACEF("cXinelibThread::SetStopSignal");
-
- LOCK_THREAD;
- m_bStopThread = true;
-}
-
-bool cXinelibThread::GetStopSignal(void)
-{
- TRACEF("cXinelibThread::GetStopSignal");
-
- LOCK_THREAD;
- return m_bStopThread;
-}
-
-bool cXinelibThread::IsReady(void)
-{
- LOCK_THREAD;
- return m_bReady;
-}
-
-bool cXinelibThread::IsFinished(void)
-{
- LOCK_THREAD;
- return m_bIsFinished;
-}
-
-//
-// Playback control
-//
-
-void cXinelibThread::SetVolume(int NewVolume)
-{
- m_Volume = NewVolume;
- cString str = cString::sprintf("VOLUME %d%s", NewVolume * 100 / 255,
- xc.sw_volume_control ? " SW" : "");
- Xine_Control(str);
-}
-
-void cXinelibThread::TrickSpeed(int Speed)
-{
- TRACEF("cXinelibThread::TrickSpeed");
-
- Xine_Control("TRICKSPEED", Speed);
-}
-
-void cXinelibThread::SetLiveMode(bool LiveModeOn)
-{
- TRACEF("cXinelibThread::SetLiveMode");
-
- Lock();
- if(m_bLiveMode == LiveModeOn) {
- Unlock();
- return;
- }
- m_bLiveMode = LiveModeOn;
- Unlock();
-
- Xine_Control("LIVE", m_bLiveMode ? 1 : 0);
-}
-
-void cXinelibThread::SetStillMode(bool StillModeOn)
-{
- TRACEF("cXinelibThread::SetStillMode");
- Xine_Control("STILL", StillModeOn ? 1 : 0);
-}
-
-void cXinelibThread::SetNoVideo(bool bVal)
-{
- TRACEF("cXinelibThread::SetNoVideo");
-
- Lock();
- if(m_bNoVideo == bVal) {
- Unlock();
- return;
- }
- m_bNoVideo = bVal;
- Unlock();
-
- Xine_Control("NOVIDEO", m_bNoVideo ? 1 : 0);
-
- char *opts = NULL;
- if(xc.audio_vis_goom_opts[0] && !strcmp(xc.audio_visualization, "goom"))
- opts = xc.audio_vis_goom_opts;
-
- if(m_bNoVideo && strcmp(xc.audio_visualization, "none")) {
- ConfigurePostprocessing(xc.audio_visualization, true, opts);
- } else {
- ConfigurePostprocessing("AudioVisualization", false, NULL);
- }
-}
-
-void cXinelibThread::AudioStreamChanged(bool ac3, int StreamId)
-{
- TRACEF("cXinelibThread::AudioStreamChanged");
- if(ac3)
- Xine_Control("AUDIOSTREAM AC3", StreamId);
- else
- Xine_Control("AUDIOSTREAM", StreamId);
-}
-
-void cXinelibThread::SetSubtitleTrack(eTrackType Track)
-{
- TRACEF("cXinelibThread::SetSubtitleTrack");
- cString buf = cString::sprintf("SPUSTREAM %d%s",
- Track==ttNone ? ttXSubtitleNone : (Track - ttSubtitleFirst),
- m_SpuLangAuto ? " auto" : "");
- Xine_Control(buf);
-}
-
-void cXinelibThread::Clear(void)
-{
- TRACEF("cXinelibThread::Clear");
-
- Lock();
- int64_t tmp1 = m_StreamPos;
- uint32_t tmp2 = m_Frames;
- Unlock();
-
- char buf[128];
- snprintf(buf, sizeof(buf), "DISCARD %" PRId64 " %d", tmp1, tmp2);
- /* Send to control stream and data stream. If message is sent only to
- * control stream, and it is delayed, engine flush will be skipped.
- */
- Xine_Control(buf);
- Xine_Control_Sync(buf);
-}
-
-bool cXinelibThread::Flush(int TimeoutMs)
-{
- TRACEF("cXinelibThread::Flush");
-
- return Xine_Control("FLUSH", TimeoutMs) <= 0;
-}
-
-int cXinelibThread::Poll(cPoller& Poller, int TimeoutMs)
-{
- TRACEF("cXinelibThread::Poll");
-
- if(!m_bReady) {
- if(TimeoutMs>0)
- cCondWait::SleepMs(TimeoutMs);
- if(!m_bReady)
- return 0;
- }
-
- int n = Xine_Control("POLL", TimeoutMs);
-
- return max(n, 0);
-}
-
-//
-// Data transfer
-//
-
-int cXinelibThread::Play_PES(const uchar *data, int len)
-{
- Lock();
- m_StreamPos += len;
- m_Frames++;
- /*m_bEndOfStreamReached = false;*/
- Unlock();
- return len;
-}
-
-//
-// Stream conversions
-//
-
-// Convert MPEG1 PES headers to MPEG2 PES headers
-
-int cXinelibThread::Play_Mpeg1_PES(const uchar *data1, int len)
-{
- if(!data1[0] && !data1[1] && data1[2] == 0x01 && len>7 && /* header sync bytes */
- ( IS_VIDEO_PACKET(data1) || IS_AUDIO_PACKET(data1)) && /* video / audio / ps1 stream */
- ((data1[6] & 0xC0) != 0x80) && /* really mpeg1 pes */
- (len == ((data1[4]<<8) | data1[5]) + 6)) { /* whole PES packet and nothing else */
- uchar *data2 = new uchar[len+64];
- int i1=0, i2=0, r=0;
-
- data2[i2++]=data1[i1++]; // 00 (sync)
- data2[i2++]=data1[i1++]; // 00 (sync)
- data2[i2++]=data1[i1++]; // 01 (sync)
- data2[i2++]=data1[i1++]; // stream ID
- data2[i2++]=data1[i1++]; // len hi
- data2[i2++]=data1[i1++]; // len lo
-
- // skip stuffing
- while ((data1[i1] & 0x80) == 0x80)
- i1++;
-
- if ((data1[i1] & 0xc0) == 0x40) {
- // skip STD_buffer_scale, STD_buffer_size
- i1 += 2;
- }
-
- if(len<i1+5) return len;
-
- data2[i2++] = 0x80;
-
- if ((data1[i1] & 0xf0) == 0x20) {
- /* PTS */
- data2[i2++] = 0x80;
- data2[i2++] = 5;
- data2[i2++] = data1[i1++] & 0x0E;
- data2[i2++] = data1[i1++] & 0xFF;
- data2[i2++] = data1[i1++] & 0xFE;
- data2[i2++] = data1[i1++] & 0xFF;
- data2[i2++] = data1[i1++] & 0xFE;
- }
- else if ((data1[i1] & 0xf0) == 0x30) {
- /* PTS & DTS */
- data2[i2++] = 0x80|0x40;
- data2[i2++] = 10;
- data2[i2++] = data1[i1++] & 0x0E;
- data2[i2++] = data1[i1++] & 0xFF;
- data2[i2++] = data1[i1++] & 0xFE;
- data2[i2++] = data1[i1++] & 0xFF;
- data2[i2++] = data1[i1++] & 0xFE;
-
- data2[i2++] = data1[i1++] & 0x0E;
- data2[i2++] = data1[i1++] & 0xFF;
- data2[i2++] = data1[i1++] & 0xFE;
- data2[i2++] = data1[i1++] & 0xFF;
- data2[i2++] = data1[i1++] & 0xFE;
- } else {
- i1++;
- data2[i2++] = 0; /* no pts, no dts */
- data2[i2++] = 0; /* header len */
- }
-
- int newlen = ((data1[4]<<8) | data1[5]) + (i2-i1), loops=0;
- data2[4] = ((newlen)&0xff00)>>8;
- data2[5] = ((newlen)&0xff);
- if(len-i1 > 0) {
- memcpy(data2+i2, data1+i1, len-i1);
- cPoller p;
- while(!Poll(p,100) && loops++ < 10) {
- LOGDBG("Play_Mpeg1_PES: poll failed");
- }
- r = Play_PES(data2,newlen+6);
- }
-
- delete data2;
- return r==newlen+6 ? ((data1[4]<<8)|data1[5])+6 : 0;
- }
- return len; // nothing useful found ...
-}
-
-// Pack elementary MPEG stream to PES
-
-bool cXinelibThread::Play_Mpeg2_ES(const uchar *data, int len, int streamID)
-{
- static uchar hdr_vid[] = {0x00,0x00,0x01,0xe0, 0x00,0x00,0x80,0x00,0x00}; /* mpeg2 */
- static uchar hdr_pts[] = {0x00,0x00,0x01,0xe0, 0x00,0x08,0x80,0x80,
- 0x05,0x00,0x00,0x00, 0x00,0x00}; /* mpeg2 */
- static uchar seq_end[] = {0x00,0x00,0x01,0xe0, 0x00,0x07,0x80,0x00,
- 0x00,
- 0x00,0x00,0x01,0xB7}; /* mpeg2 */
- int todo = len, done = 0, hdrlen = 9/*sizeof(hdr)*/;
- uchar *frame = new uchar[PES_CHUNK_SIZE+32];
- cPoller p;
- bool h264 = IS_NAL_AUD(data);
-
- hdr_pts[3] = (uchar)streamID;
- Poll(p, 100);
- Play_PES(hdr_pts, sizeof(hdr_pts));
-
- hdr_vid[3] = (uchar)streamID;
- while(todo) {
- int blocklen = todo;
- if(blocklen > ((PES_CHUNK_SIZE - hdrlen) & 0xfffc))
- blocklen = (PES_CHUNK_SIZE - hdrlen) & 0xfffc;
- hdr_vid[4] = ((blocklen+3)&0xff00)>>8;
- hdr_vid[5] = ((blocklen+3)&0xff);
-
- memcpy(frame, hdr_vid, hdrlen);
- memcpy(frame+hdrlen, data+done, blocklen);
-
- done += blocklen;
- todo -= blocklen;
-
- Poll(p, 100);
-
- if(blocklen+hdrlen != Play_PES(frame,blocklen+hdrlen)) {
- delete frame;
- return false;
- }
- }
-
- // append sequence end code to video
- if((streamID & 0xF0) == 0xE0) {
- seq_end[3] = (uchar)streamID;
- seq_end[12] = h264 ? NAL_END_SEQ : 0xB7;
- Poll(p, 100);
- Play_PES(seq_end, sizeof(seq_end));
- }
-
- delete[] frame;
- return true;
-}
-
-//
-// Built-in still images
-//
-
-bool cXinelibThread::QueueBlankDisplay(void)
-{
- TRACEF("cXinelibThread::BlankDisplay");
-#if 0
- extern const unsigned char v_mpg_black[]; // black_720x576.c
- extern const int v_mpg_black_length;
-
- Play_Mpeg2_ES(v_mpg_black, v_mpg_black_length, VIDEO_STREAM);
-#endif
- Xine_Control_Sync("BLANK");
- return true;
-}
-
-bool cXinelibThread::BlankDisplay(void)
-{
- TRACEF("cXinelibThread::BlankDisplay");
-
- bool r = QueueBlankDisplay();
- for(int i=0; i<5 && !Flush(100); i++)
- ;
- return r;
-}
-
-bool cXinelibThread::LogoDisplay(void)
-{
- TRACEF("cXinelibThread::LogoDisplay");
-
- cString Path;
- int fd = -1;
-
- if(Setup.FileName()) {
- cString SetupPath = Setup.FileName();
- const char *end = strrchr(SetupPath, '/');
- if(end) {
- SetupPath.Truncate(end - (const char *)SetupPath);
- fd = open(Path=cString::sprintf("%s/plugins/xineliboutput/logo.mpv", *SetupPath), O_RDONLY);
- }
- }
-
- if(fd<0)
- fd = open(Path=STARTUP_IMAGE_FILE, O_RDONLY);
-
- if(fd >= 0) {
- uint8_t *data = (uint8_t*)malloc(STARTUP_MAX_SIZE);
- int datalen = read(fd, data, STARTUP_MAX_SIZE);
- if(datalen == STARTUP_MAX_SIZE) {
- LOGMSG("WARNING: custom startup image %s too large", *Path);
- } else if(datalen<=0) {
- LOGERR("error reading custom startup image %s", *Path);
- } else {
- LOGMSG("using custom startup image %s", *Path);
- bool r = Play_Mpeg2_ES(data, datalen, VIDEO_STREAM);
- free(data);
- for(int i=0; i<5 && !Flush(100); i++)
- ;
- return r;
- }
- free(data);
- close(fd);
- }
-
- /* use default image */
- extern const unsigned char v_mpg_vdrlogo[]; // vdrlogo_720x576.c
- extern const int v_mpg_vdrlogo_length;
-
- bool r = Play_Mpeg2_ES(v_mpg_vdrlogo, v_mpg_vdrlogo_length, VIDEO_STREAM);
- for(int i=0; i<5 && !Flush(100); i++)
- ;
- return r;
-}
-
-bool cXinelibThread::NoSignalDisplay(void)
-{
- TRACEF("cXinelibThread::NoSignalDisplay");
-
- extern const unsigned char v_mpg_nosignal[]; // nosignal_720x576.c
- extern const int v_mpg_nosignal_length;
-
- bool r = Play_Mpeg2_ES(v_mpg_nosignal, v_mpg_nosignal_length, VIDEO_STREAM);
- for(int i=0; i<5 && !Flush(100); i++)
- ;
- return r;
-}
-
-//
-// Xine Control
-//
-
-int cXinelibThread::Xine_Control(const char *cmd, int p1)
-{
- char buf[128];
- if(snprintf(buf, sizeof(buf), "%s %d", cmd, p1) >= (int)sizeof(buf)) {
- LOGMSG("Xine_Control %s: message too long !", cmd);
- return 0;
- }
- //buf[sizeof(buf)-1] = 0;
- return Xine_Control(buf);
-}
-
-int cXinelibThread::Xine_Control(const char *cmd, int64_t p1)
-{
- char buf[128];
- if(snprintf(buf, sizeof(buf), "%s %" PRId64, cmd, p1) >= (int)sizeof(buf)) {
- LOGMSG("Xine_Control %s: message too long !", cmd);
- return 0;
- }
- //buf[sizeof(buf)-1] = 0;
- return Xine_Control(buf);
-}
-
-int cXinelibThread::Xine_Control(const char *cmd, const char *p1)
-{
- char buf[1024];
- if(snprintf(buf, sizeof(buf), "%s %s", cmd, p1) >= (int)sizeof(buf)) {
- LOGMSG("Xine_Control %s: message too long !", cmd);
- return 0;
- }
- //buf[sizeof(buf)-1] = 0;
- return Xine_Control(buf);
-}
-
-bool cXinelibThread::PlayFile(const char *FileName, int Position,
- bool LoopPlay, ePlayMode PlayMode,
- int TimeoutMs)
-{
- TRACEF("cXinelibThread::PlayFile");
-
- char vis[256];
-
- switch(PlayMode) {
- case pmVideoOnly:
- LOGDBG("cXinelibThread::PlayFile: Video from file, audio from VDR");
- strcpy(vis, "Video");
- break;
- case pmAudioOnly:
- LOGDBG("cXinelibThread::PlayFile: Audio from file, video from VDR");
- strcpy(vis, "Audio");
- break;
- case pmAudioOnlyBlack:
- //LOGDBG("cXinelibThread::PlayFile: Audio from file, no video");
- strcpy(vis, "none");
- break;
- case pmAudioVideo:
- default:
- if(xc.audio_vis_goom_opts[0] && !strcmp(xc.audio_visualization, "goom"))
- snprintf(vis, sizeof(vis), "%s:%s", xc.audio_visualization, xc.audio_vis_goom_opts);
- else
- strn0cpy(vis, xc.audio_visualization, sizeof(vis));
- vis[sizeof(vis)-1] = 0;
- break;
- }
-
- char buf[4096];
- m_bEndOfStreamReached = false;
- if(snprintf(buf, sizeof(buf), "PLAYFILE %s %d %s %s",
- LoopPlay ? "Loop" : "", Position, vis, FileName ? FileName : "")
- >= 4096) {
- LOGMSG("PlayFile: message too long !");
- return 0;
- }
-
- if(FileName) {
- Lock();
- m_FileName = FileName;
- m_bPlayingFile = true;
- m_SpuLangAuto = true;
- if (m_StatusMonitor)
- DELETENULL(m_StatusMonitor);
- m_StatusMonitor = new cFrontendStatusMonitor(m_SpuLangAuto);
- Unlock();
- }
-
- int result = PlayFileCtrl(buf, TimeoutMs);
-
- if(!FileName || result != 0) {
- Lock();
- m_bPlayingFile = false;
- m_FileName = NULL;
- if (m_StatusMonitor)
- DELETENULL(m_StatusMonitor);
- Unlock();
- } else {
- if(xc.extsub_size >= 0)
- Xine_Control("EXTSUBSIZE", xc.extsub_size);
-
- // set preferred subtitle language
- if (Setup.DisplaySubtitles) {
- const char *langs = I18nLanguageCode(Setup.SubtitleLanguages[0]);
- if (langs) {
- char lang1[5];
- strn0cpy(lang1, langs, 4); /* truncate */
- const char *spu_lang = iso639_1_to_iso639_2(lang1);
- LOGMSG("Preferred SPU language: %s (%s)", lang1, spu_lang);
- if (spu_lang && spu_lang[0] && spu_lang[1] && !spu_lang[2])
- Xine_Control(cString::sprintf("SPUSTREAM %s", spu_lang));
- }
- } else {
- LOGMSG("Preferred SPU language: (none)");
- Xine_Control(cString::sprintf("SPUSTREAM %d", ttXSubtitleNone));
- }
- }
-
- return (!GetStopSignal()) && (result==0);
-}
-
-
-//
-// Configuration
-//
-
-void cXinelibThread::Configure(void)
-{
- ConfigurePostprocessing(xc.deinterlace_method, xc.audio_delay,
- xc.audio_compression, xc.audio_equalizer,
- xc.audio_surround, xc.speaker_type);
- ConfigureVideo(xc.hue, xc.saturation, xc.brightness, xc.sharpness, xc.noise_reduction, xc.contrast, xc.overscan, xc.vo_aspect_ratio);
- ConfigurePostprocessing("upmix", xc.audio_upmix ? true : false, NULL);
- ConfigurePostprocessing("autocrop", xc.autocrop ? true : false,
- xc.AutocropOptions());
- ConfigurePostprocessing("swscale", xc.swscale ? true : false,
- xc.SwScaleOptions());
- ConfigurePostprocessing("pp", xc.ffmpeg_pp ? true : false,
- xc.FfmpegPpOptions());
- ConfigurePostprocessing("unsharp",xc.unsharp ? true : false,
- xc.UnsharpOptions());
- ConfigurePostprocessing("denoise3d",xc.denoise3d ? true : false,
- xc.Denoise3dOptions());
-
-#ifdef ENABLE_TEST_POSTPLUGINS
- ConfigurePostprocessing("headphone", xc.headphone ? true : false, NULL);
-#endif
-
- Xine_Control(cString::sprintf("SCR %s %d",
- xc.live_mode_sync ? "Sync" : "NoSync",
- xc.scr_tuning ? xc.scr_hz : 90000));
-}
-
-int cXinelibThread::ConfigurePostprocessing(const char *deinterlace_method,
- int audio_delay,
- int audio_compression,
- const int *audio_equalizer,
- int audio_surround,
- int speaker_type)
-{
- char buf[1024];
- int r = true;
-
- if(strcmp(deinterlace_method, "tvtime"))
- r = ConfigurePostprocessing("tvtime", false, NULL) && r;
-
- r = Xine_Control("DEINTERLACE", deinterlace_method) && r;
- r = Xine_Control("AUDIODELAY", audio_delay) && r;
- r = Xine_Control("AUDIOCOMPRESSION", audio_compression) && r;
- r = Xine_Control("AUDIOSURROUND", audio_surround) && r;
- r = Xine_Control("SPEAKERS", speaker_type) && r;
- sprintf(buf,"EQUALIZER %d %d %d %d %d %d %d %d %d %d",
- audio_equalizer[0],audio_equalizer[1],
- audio_equalizer[2],audio_equalizer[3],
- audio_equalizer[4],audio_equalizer[5],
- audio_equalizer[6],audio_equalizer[7],
- audio_equalizer[8],audio_equalizer[9]);
- r = Xine_Control(buf) && r;
-
- if(m_bNoVideo && strcmp(xc.audio_visualization, "none")) {
- char *opts = NULL;
- if(xc.audio_vis_goom_opts[0] && !strcmp(xc.audio_visualization, "goom"))
- opts = xc.audio_vis_goom_opts;
- //fe->post_open(fe, xc.audio_visualization, NULL);
- r = ConfigurePostprocessing(xc.audio_visualization, true, opts) && r;
- } else {
- //fe->post_close(fe, NULL, 0);
- r = ConfigurePostprocessing("AudioVisualization", false, NULL) && r;
- }
-
- if(!strcmp(deinterlace_method, "tvtime"))
- r = ConfigurePostprocessing("tvtime", true, xc.deinterlace_opts) && r;
-
- return r;
-}
-
-int cXinelibThread::ConfigurePostprocessing(const char *name, bool on, const char *args)
-{
- char buf[1024];
- int l;
-
- if(on)
- l = snprintf(buf, sizeof(buf), "POST %s On %s", (name&&*name)?name:"0", args?args:"");
- else
- // 0 - audio vis.
- // 1 - audio post
- // 2 - video post
- //return fe->post_close(fe, name, -1);
- l = snprintf(buf, sizeof(buf), "POST %s Off", (name&&*name)?name:"0");
-
- if(l >= (int)sizeof(buf)) {
- LOGMSG("ConfigurePostprocessing %s: message too long !", name);
- return 0;
- }
- //buf[sizeof(buf)-1] = 0;
-
- return Xine_Control(buf);
-}
-
-int cXinelibThread::ConfigureVideo(int hue, int saturation,
- int brightness, int sharpness,
- int noise_reduction, int contrast,
- int overscan, int vo_aspect_ratio)
-{
- char cmd[128];
- Xine_Control("OVERSCAN", overscan);
- snprintf(cmd, sizeof(cmd),
- "VIDEO_PROPERTIES %d %d %d %d %d %d %d",
- hue, saturation, brightness, sharpness, noise_reduction, contrast, vo_aspect_ratio);
- return Xine_Control(cmd);
-}
-
-//
-// Playback files
-//
-
-bool cXinelibThread::EndOfStreamReached(void)
-{
- LOCK_THREAD;
- bool r = m_bEndOfStreamReached;
- return r;
-}
-
-
diff --git a/frontend.h b/frontend.h
deleted file mode 100644
index a80c5b9b..00000000
--- a/frontend.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * frontend.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: frontend.h,v 1.28 2009-03-20 18:26:23 phintuka Exp $
- *
- */
-
-#ifndef __XINELIB_FRONTEND_H
-#define __XINELIB_FRONTEND_H
-
-#include <vdr/tools.h>
-#include <vdr/thread.h>
-#include <vdr/device.h> // ePlayMode
-
-class cStatus;
-
-//----------------------------- cXinelibThread --------------------------------
-
-class cXinelibThread : public cThread, public cListObject
-{
- private:
- cXinelibThread(cXinelibThread&); // no copy contructor
-
- public:
- cXinelibThread(const char *Description = NULL);
- virtual ~cXinelibThread();
-
- //
- // Thread control
- //
-
- public:
- virtual void Start(void);
- virtual void Stop(void);
- bool IsReady(void);
- bool IsFinished(void);
-
- protected:
- void SetStopSignal(void);
- bool GetStopSignal(void);
-
- virtual void Action(void) = 0;
-
- //
- // Playback control
- //
-
- public:
- void PauseOutput(void) { TrickSpeed(0); }
- void ResumeOutput(void) { TrickSpeed(1); }
- virtual void TrickSpeed(int Speed);
- void SetVolume(int NewVolume);
- void SetLiveMode(bool);
- void SetStillMode(bool);
- void SetNoVideo(bool bVal);
- void AudioStreamChanged(bool ac3, int StreamId);
- void SetSubtitleTrack(eTrackType Track);
-
- protected:
- int Xine_Control(const char *cmd, const char *p1);
- int Xine_Control(const char *cmd, int p1);
- int Xine_Control(const char *cmd, int64_t p1);
- virtual int Xine_Control(const char *cmd) = 0;
- virtual int Xine_Control_Sync(const char *cmd) { return Xine_Control(cmd); }
-
- void Configure(void);
-
- //
- // Data transfer
- //
-
- public:
- virtual int Poll(cPoller &Poller, int TimeoutMs);
- virtual bool Flush(int TimeoutMs);
- virtual void Clear(void);
- virtual int Play_PES(const uchar *buf, int len);
- virtual void OsdCmd(void *cmd) = 0;
- virtual int64_t GetSTC(void) { return -1; }
- virtual void SetHDMode(bool On) { (void)Xine_Control("HDMODE",On?1:0); };
- virtual void SetHeader(const uchar *data, int length, bool reset = false) {};
-
- // Stream type conversions
- int Play_Mpeg1_PES(const uchar *data, int len);
- bool Play_Mpeg2_ES(const uchar *data, int len, int streamID);
-
- // Built-in still images
- bool BlankDisplay(void);
- bool QueueBlankDisplay(void);
- bool LogoDisplay(void);
- bool NoSignalDisplay(void);
-
- // Playback files
- virtual bool PlayFile(const char *FileName, int Position,
- bool LoopPlay = false, ePlayMode PlayMode = pmAudioVideo,
- int TimeoutMs = -1);
- virtual int PlayFileCtrl(const char *Cmd, int TimeoutMs=-1) { return Xine_Control(Cmd); }
- virtual bool EndOfStreamReached(void);
-
- // Image grabbing
- virtual uchar *GrabImage(int &Size, bool Jpeg, int Quality,
- int SizeX, int SizeY) { return NULL; }
-
- // Control from frontend
- static void KeypressHandler(const char *keymap, const char *key,
- bool repeat, bool release);
- static void InfoHandler(const char *info);
-
- //
- // Configuration
- //
-
- public:
- virtual int ConfigurePostprocessing(const char *deinterlace_method,
- int audio_delay,
- int audio_compression,
- const int *audio_equalizer,
- int audio_surround,
- int speaker_type);
- virtual int ConfigurePostprocessing(const char *name, bool on, const char *args);
- virtual int ConfigureVideo(int hue, int saturation,
- int brightness, int sharpness, int noise_reduction, int contrast,
- int overscan, int vo_aspect_ratio);
- // Local frontend:
- virtual void ConfigureWindow(int fullscreen, int width, int height,
- int modeswitch, const char *modeline,
- int aspect, int scale_video,
- int field_order) {};
- virtual void ConfigureDecoder(int pes_buffers) {};
- // Remote frontend server:
- virtual bool Listen(int port) { return false; }
-
- //
- // Data
- //
-
- protected:
- bool m_bStopThread;
- bool m_bReady;
- bool m_bIsFinished;
- bool m_bNoVideo;
- bool m_bLiveMode;
- bool m_bEndOfStreamReached;
- bool m_bPlayingFile;
- int m_Volume;
- cString m_FileName;
- uint64_t m_StreamPos;
- uint32_t m_Frames;
-
- cStatus *m_StatusMonitor;
- bool m_SpuLangAuto;
-};
-
-
-#endif // __XINELIB_FRONTEND_H
diff --git a/frontend_local.c b/frontend_local.c
deleted file mode 100644
index 6a4006c4..00000000
--- a/frontend_local.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * frontend_local.c:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: frontend_local.c,v 1.41 2009-06-01 14:01:28 phintuka Exp $
- *
- */
-
-#define __STDC_CONSTANT_MACROS
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <dlfcn.h>
-
-#include <vdr/config.h>
-#include <vdr/tools.h>
-#include <vdr/shutdown.h>
-#include <vdr/plugin.h>
-
-#include "logdefs.h"
-#include "config.h"
-
-#include "xine_frontend.h"
-
-#include "frontend_local.h"
-
-//------------------------------ cRwLockBlock ---------------------------------
-
-class cRwLockBlock
-{
- private:
- cRwLock& m_Lock;
-
- public:
- cRwLockBlock(cRwLock& lock, bool write) : m_Lock(lock)
- { m_Lock.Lock(write);}
-
- ~cRwLockBlock()
- { m_Lock.Unlock(); }
-};
-
-#define LOCK_FE cRwLockBlock(m_feLock, false)
-#define LOCK_FE_WR cRwLockBlock(m_feLock, true)
-
-//----------------- keyboard control handler (C callback) --------------------
-
-extern "C" {
- static void keypress_handler(const char *keymap, const char *key)
- {
- if(!strncmp("INFO ", keymap, 5)) {
-
- cXinelibThread::InfoHandler(keymap+5);
-
- } else if(!xc.use_x_keyboard || !key) {
-
- /* Only X11 key events came this way in local mode.
- Keyboard is handled by vdr. */
- LOGMSG("keypress_handler(%s): X11 Keyboard disabled in config", key);
-
- } else {
-
- cXinelibThread::KeypressHandler(keymap, key, false, false);
-
- }
- }
-};
-
-//----------------------------- cXinelibLocal --------------------------------
-
-cXinelibLocal::cXinelibLocal(const char *frontend_name) :
- cXinelibThread("Local decoder/display (cXinelibThread)"), m_feLock(true)
-{
- fe = NULL;
- h_fe_lib = NULL;
- m_bReconfigRequest = true;
-
- if (!xc.config_file &&
- 0 < asprintf(&xc.config_file,
- "%s/xineliboutput/config",
- cPlugin::ConfigDirectory()))
- LOGMSG("cXinelibLocal: Using xine-lib configuration file %s", xc.config_file);
-}
-
-cXinelibLocal::~cXinelibLocal()
-{
- TRACEF("cXinelibLocal::~cXinelibLocal");
-
- m_bReady = false;
-
- Stop();
- if(fe) {
- fe->fe_free(fe);
- fe = NULL;
- }
- if(h_fe_lib) {
- dlclose(h_fe_lib);
- }
-}
-
-void cXinelibLocal::Stop(void)
-{
- TRACEF("cXinelibLocal::Stop");
-
- SetStopSignal();
-
- {
- LOCK_FE;
- m_bReady = false;
- if(fe)
- fe->fe_interrupt(fe);
- }
-
- cXinelibThread::Stop();
-}
-
-//
-// Data transfer
-//
-
-int cXinelibLocal::Play_PES(const uchar *data, int len)
-{
- TRACEF("cXinelibLocal::Play_PES");
-
- {
- LOCK_FE;
- if(fe && !m_bStopThread) {
- int done = fe->xine_queue_pes_packet(fe, (char*)data, len);
- if (done >= 0) {
- Lock();
- m_StreamPos += done;
- Unlock();
- return done;
- }
- }
- }
-
- //cCondWait::SleepMs(5);
- return len;
-}
-
-void cXinelibLocal::OsdCmd(void *cmd)
-{
- TRACEF("cXinelibLocal::OsdCmd");
- LOCK_FE;
- if(cmd && fe && m_bReady)
- fe->xine_osd_command(fe, (struct osd_command_s*)cmd);
-}
-
-uchar *cXinelibLocal::GrabImage(int &Size, bool Jpeg,
- int Quality, int SizeX,
- int SizeY)
-{
- uchar *data;
- LOCK_FE;
- if(fe && fe->grab && m_bReady)
- if((data = (uchar*)fe->grab(fe, &Size, Jpeg, Quality, SizeX, SizeY)))
- return data;
- return NULL;
-}
-
-int64_t cXinelibLocal::GetSTC()
-{
- TRACEF("cXinelibLocal::GetSTC");
-
- union {
- char buf[32];
- int64_t pts;
- } u = {"GETSTC\r\n"};
-
- LOCK_FE;
-
- if (fe && m_bReady)
- if (0 == fe->xine_control(fe, u.buf))
- return u.pts;
-
- return INT64_C(-1);
-}
-
-//
-// Playback files
-//
-
-bool cXinelibLocal::EndOfStreamReached(void)
-{
- LOCK_THREAD;
- if(fe && fe->xine_is_finished(fe, 1))
- return true;
- return cXinelibThread::EndOfStreamReached();
-}
-
-//
-// Configuration
-//
-
-void cXinelibLocal::ConfigureWindow(int fullscreen, int width, int height,
- int modeswitch, const char *modeline,
- int aspect, int scale_video,
- int field_order)
-{
- LOCK_FE;
- if(fe)
- fe->fe_display_config(fe, -1, -1, width, height,
- fullscreen, modeswitch, modeline,
- aspect, scale_video, field_order);
-}
-
-void cXinelibLocal::ConfigureDecoder(int pes_buffers)
-{
- // needs xine restart
- {
- LOCK_FE;
- xc.pes_buffers = pes_buffers;
- if(!fe)
- return;
- m_bReady = false;
- m_bReconfigRequest = true;
- fe->fe_interrupt(fe);
- }
-
- while(!m_bReady && !GetStopSignal())
- cCondWait::SleepMs(100);
-
- cCondWait::SleepMs(100);
-}
-
-//
-// Xine control
-//
-
-int cXinelibLocal::Xine_Control(const char *cmd)
-{
- TRACEF("cXinelibLocal::Xine_Control");
- if(cmd && *cmd && !GetStopSignal()) {
- char buf[4096];
- if(snprintf(buf, sizeof(buf), "%s\r\n", cmd) >= (int)sizeof(buf)) {
- buf[sizeof(buf)-1] = 0;
- LOGMSG("Xine_Control: message too long ! (%s)", buf);
- return 0;
- }
- LOCK_FE;
- if(fe)
- return fe->xine_control(fe, (char*)buf);
- }
- return 0;
-}
-
-//
-// Frontend loader
-//
-
-frontend_t *cXinelibLocal::load_frontend(const char *fe_name)
-{
- Dl_info info;
- struct stat statbuffer;
- char libname[4096]="";
- void *lib = NULL;
- fe_creator_f *fe_creator = NULL;
- static int my_marker = 0;
-
- if(!dladdr((void *)&my_marker, &info)) {
- LOGERR("Error searching plugin: dladdr() returned false (%s)",dlerror());
- return NULL;
- }
- LOGDBG("xineliboutput: plugin file is %s", info.dli_fname);
-
- int fe_ind = strstra(fe_name, xc.s_frontends, FRONTEND_NONE);
- bool fe_try = false;
- if(fe_ind == FRONTEND_NONE) {
- LOGMSG("Front-end %s unknown!", fe_name);
- fe_ind = 0;
- fe_try = true;
- }
-
- strn0cpy(libname, info.dli_fname, sizeof(libname) - 128);
- if(strrchr(libname, '/'))
- *(strrchr(libname, '/')+1) = 0;
-
- LOGDBG("Searching frontend %s from %s", xc.s_frontends[fe_ind], libname);
-
- do {
- strncat(libname, xc.s_frontend_files[fe_ind], 64);
- LOGDBG("Probing %s", libname);
-
- if (stat(libname, &statbuffer)) {
- LOGERR("load_frontend: can't stat %s",libname);
- } else if((statbuffer.st_mode & S_IFMT) != S_IFREG) {
- LOGMSG("load_frontend: %s not regular file ! trying to load anyway ...",
- libname);
- }
-
- if( !(lib = dlopen (libname, RTLD_LAZY | RTLD_GLOBAL))) {
- char *dl_error_msg = dlerror();
- LOGERR("load_frontend: cannot dlopen file %s: %s",
- libname, dl_error_msg);
- } else if ( (fe_creator = (fe_creator_f*)dlsym(lib, "fe_creator"))) {
- LOGDBG("load_frontend: entry at %p", fe_creator);
- frontend_t *fe = (**fe_creator)();
-
- if(fe) {
- if(h_fe_lib)
- dlclose(h_fe_lib);
- h_fe_lib = lib;
-
- LOGDBG("Using frontend %s (%s) from %s",
- xc.s_frontends[fe_ind], xc.s_frontendNames[fe_ind],
- xc.s_frontend_files[fe_ind]);
-
- return fe;
- } else {
- LOGMSG("Frontend %s (%s) creation failed",
- xc.s_frontends[fe_ind], xc.s_frontendNames[fe_ind]);
- }
- } else {
- LOGERR("Frontend entry point not found");
- dlclose(lib);
- }
-
- fe_ind++; // try next frontend ...
-
- } while(fe_try && fe_ind < FRONTEND_count);
-
- LOGMSG("No usable frontends found, giving up !");
- return NULL;
-}
-
-//
-// Thread main loop
-//
-
-void cXinelibLocal::Action(void)
-{
- frontend_t *curr_fe = NULL;
-
- TRACEF("cXinelibLocal::Action");
-
- SetPriority(2); /* lower priority */
-
- // init frontend
- if(!curr_fe) {
- curr_fe = load_frontend(xc.local_frontend);
- if(!curr_fe) {
- LOGMSG("cXinelibLocal: Error initializing frontend");
- SetStopSignal();
- } else {
- LOGDBG("cXinelibLocal::Action - fe created");
- if(!curr_fe->fe_display_open(curr_fe, 0, 0, xc.width, xc.height, xc.fullscreen, xc.hud_osd,
- xc.modeswitch, xc.modeline, xc.display_aspect,
- keypress_handler, 0/*no_x_kbd*/, 0/*gui_hotkeys*/,
- xc.video_port,
- xc.scale_video,
- xc.field_order,
- NULL, -1)) {
- LOGMSG("cXinelibLocal: Error initializing display");
- SetStopSignal();
- } else {
- LOGDBG("cXinelibLocal::Action - fe->fe_display_open ok");
- }
- }
- }
-
- // main loop
- while (!GetStopSignal()) {
-
- {
- // init and start xine engine
- LOCK_FE_WR;
- LOGDBG("cXinelibLocal::Action - xine_init");
-
- fe = curr_fe;
- if(m_bReconfigRequest) {
- if(!fe->xine_init(fe, xc.audio_driver, xc.audio_port,
- xc.video_driver,
- xc.pes_buffers,
- xc.post_plugins, xc.config_file)) {
- LOGMSG("cXinelibLocal: Error initializing frontend");
- break;
- }
- LOGDBG("cXinelibLocal::Action - fe->xine_init ok");
- m_bReconfigRequest = false;
- }
-
- // open (xine) stream
- LOGDBG("cXinelibLocal::Action - xine_open");
- if(!fe->xine_open(fe, NULL)) {
- LOGMSG("cXinelibLocal: Error opening xvdr://");
- break;
- }
- LOGDBG("cXinelibLocal::Action - fe->xine_open ok");
-
- // start playing (xine) stream
- if(!fe->xine_play(fe)) {
- LOGMSG("cXinelibLocal: Error playing xvdr://");
- break;
- }
- LOGDBG("cXinelibLocal::Action - fe->xine_play ok");
-
- m_StreamPos = 0;
- Xine_Control("STREAMPOS 0");
- Xine_Control("VERSION " XINELIBOUTPUT_VERSION " " "\r\n");
- }
-
- // configure frontend and xine
- m_bNoVideo = false;
- Configure();
- LOGDBG("cXinelibLocal::Action - fe config OK");
-
- LogoDisplay();
- LOGDBG("cXinelibLocal::Action - logo sent");
-
- {
- LOCK_THREAD;
- Xine_Control("NOVIDEO 0");
- Xine_Control("LIVE 1");
- Xine_Control("CLEAR");
- m_bNoVideo = false;
- m_bLiveMode = true;
- m_bReady = true;
- }
-
- // main event loop
- LOGDBG("cXinelibLocal:Action - Starting event loop");
- {
- LOCK_FE;
- while(!GetStopSignal() && m_bReady &&
- (/*m_bLoopPlay ||*/ !fe->xine_is_finished(fe, 0)) &&
- fe->fe_run(fe))
- /*cCondWait::SleepMs(50)*/ ;
- }
-
- LOGDBG("cXinelibLocal::Action - event loop terminated, "
- "xine_is_finished=%d", fe->xine_is_finished(fe, 0));
-
- {
- LOCK_THREAD;
- m_bReady = false;
- m_bEndOfStreamReached = true;
- }
-
- {
- LOCK_FE_WR;
- if(fe)
- fe->xine_close(fe);
- fe = NULL;
- }
-
- LOGMSG("cXinelibLocal::Action: Xine closed");
-
- if(!m_bReconfigRequest && xc.exit_on_close) {
- LOGMSG("Shutting down VDR");
- ShutdownHandler.RequestEmergencyExit();
- break;
- }
- }
-
- if(curr_fe) {
- curr_fe->xine_exit(fe);
- curr_fe->fe_display_close(curr_fe);
- curr_fe->fe_free(curr_fe);
- }
-
- m_bIsFinished = true;
- LOGMSG("cXinelibLocal::Action: thread finished");
-}
-
diff --git a/frontend_local.h b/frontend_local.h
deleted file mode 100644
index 1a44f3bd..00000000
--- a/frontend_local.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * frontend_local.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: frontend_local.h,v 1.6 2008-11-18 15:06:12 phintuka Exp $
- *
- */
-
-#ifndef __XINELIB_FRONTEND_LOCAL_H
-#define __XINELIB_FRONTEND_LOCAL_H
-
-#include "frontend.h"
-
-//----------------------------- cXinelibLocal --------------------------------
-
-extern "C" {
- typedef struct frontend_s frontend_t;
-}
-
-class cXinelibLocal : public cXinelibThread
-{
-
- public:
- cXinelibLocal(const char *frontend_name);
- virtual ~cXinelibLocal();
-
- // Thread control
- virtual void Stop(void);
-
- protected:
- virtual void Action(void);
-
-
- public:
-
- // Data transfer
- virtual int Play_PES(const uchar *buf, int len);
- virtual void OsdCmd(void *cmd);
- virtual int64_t GetSTC();
-
- // Playback files
- virtual bool EndOfStreamReached(void);
-
- // Image grabbing
- virtual uchar *GrabImage(int &Size, bool Jpeg, int Quality,
- int SizeX, int SizeY);
-
- // Configuration
- virtual void ConfigureWindow(int fullscreen, int width, int height,
- int modeswitch, const char *modeline,
- int aspect, int scale_video, int field_order);
- virtual void ConfigureDecoder(int pes_buffers);
-
- protected:
-
- // Playback control
- virtual int Xine_Control(const char *cmd);
-
- protected:
-
- // Frontend access
- frontend_t *load_frontend(const char *fe_name);
-
- // Data
- void *h_fe_lib;
- frontend_t *fe;
- cRwLock m_feLock;
- bool m_bReconfigRequest;
-};
-
-
-#endif // __XINELIB_FRONTEND_LOCAL_H
diff --git a/frontend_svr.c b/frontend_svr.c
deleted file mode 100644
index c993fec2..00000000
--- a/frontend_svr.c
+++ /dev/null
@@ -1,1977 +0,0 @@
-/*
- * frontend_svr.c: server for remote frontends
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: frontend_svr.c,v 1.74 2009-07-02 18:27:19 phintuka Exp $
- *
- */
-
-#define __STDC_FORMAT_MACROS
-#include <inttypes.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <time.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <netinet/tcp.h>
-
-#include <vdr/config.h>
-#include <vdr/tools.h>
-#include <vdr/plugin.h>
-
-#include "logdefs.h"
-#include "config.h"
-
-#include "xine_input_vdr_net.h" // stream header(s)
-#include "xine_osd_command.h" // osd commands
-
-#include "tools/cxsocket.h"
-#include "tools/future.h"
-#include "tools/backgroundwriter.h"
-#include "tools/udp_pes_scheduler.h"
-#include "tools/http.h"
-#include "tools/vdrdiscovery.h"
-#include "tools/sdp.h"
-
-#include "frontend_svr.h"
-#include "device.h"
-#include "osd.h"
-
-//#define HTTP_OSD
-
-#define MAX_OSD_TIMEOUTS (25*5) /* max. rate 25 updates/s -> at least 5 seconds */
-#define LOG_OSD_BANDWIDTH (128*1024) /* log messages if OSD bandwidth > 1 Mbit/s */
-
-#define PLAYFILE_CTRL_TIMEOUT 300 /* ms */
-#define PLAYFILE_TIMEOUT 20000 /* ms */
-
-typedef struct {
- int Size;
- uchar *Data;
-} grab_result_t;
-
-class cStcFuture : public cFuture<int64_t> {};
-class cReplyFuture : public cFuture<int>, public cListObject {};
-class cGrabReplyFuture : public cFuture<grab_result_t>, public cListObject {};
-class cCmdFutures : public cHash<cReplyFuture> {};
-
-
-//----------------------------- cXinelibServer --------------------------------
-
-// (control stream) connection types
-enum {
- ctDetecting = 0x00,
- ctControl = 0x01,
- ctHttp = 0x02,
- ctRtsp = 0x04, // TCP/RTSP + UDP/RTP
- ctRtspMux = 0x08 // TCP: multiplexed RTSP control + RTP/RTCP data/control
-};
-
-// (data) connection types
-enum {
- dtPipe = 0x01,
- dtTcp = 0x02,
- dtUdp = 0x04,
- dtRtp = 0x08,
- dtHttp = 0x10,
- dtRtspMux = 0x20,
-};
-
-// (data) connection properties
-#define DATA_STREAM(dt) ((dt) & (dtPipe | dtTcp | dtHttp | dtRtspMux))
-#define DATA_DATAGRAM(dt) ((dt) & (dtUdp | dtRtp))
-#define DATA_NOPOLL(dt) ((dt) & (dtHttp | dtRtspMux))
-#define DATA_NOCONTROL(dt) ((dt) & (dtHttp | dtRtspMux))
-
-cXinelibServer::cXinelibServer(int listen_port) :
- cXinelibThread("Remote decoder/display server (cXinelibServer)")
-{
- int i;
- for(i=0; i<MAXCLIENTS; i++) {
- fd_data[i] = -1;
- m_OsdTimeouts[i] = 0;
- m_Writer[i] = NULL;
- m_State[i] = NULL;
- m_bMulticast[i] = 0;
- m_bConfigOk[i] = false;
- m_bUdp[i] = 0;
- m_ConnType[i] = ctDetecting;
- }
-
- m_Port = listen_port;
- m_ServerId = time(NULL) ^ getpid();
-
- fd_listen = -1;
- fd_discovery = -1;
-
- m_iMulticastMask = 0;
- m_MasterCli = -1;
-
- m_Master = false;
-
- m_Scheduler = new cUdpScheduler;
- m_StcFuture = new cStcFuture;
- m_Futures = new cCmdFutures;
-
- cString Base(cPlugin::ConfigDirectory());
- if(*Base)
- m_PipesDir = cString::sprintf("%s/xineliboutput/pipes.%d", *Base, getpid());
- else
- m_PipesDir = cString::sprintf("/tmp/xineliboutput/pipes.%d", getpid());
-
- m_Token = 1;
-
- m_Header = NULL;
- m_HeaderLength = 0;
- m_HeaderSize = 0;
-}
-
-cXinelibServer::~cXinelibServer()
-{
- int i;
-
- CLOSESOCKET(fd_listen);
- CLOSESOCKET(fd_discovery);
-
- cHttpStreamer::CloseAll();
-
- for(i=0; i<MAXCLIENTS; i++)
- CloseConnection(i);
-
- delete m_StcFuture;
- delete m_Futures;
- delete m_Scheduler;
-
- free(m_Header);
-}
-
-void cXinelibServer::Stop(void)
-{
- int i;
-
- TRACEF("cXinelibServer::Stop");
-
- SetStopSignal();
-
- CLOSESOCKET(fd_listen);
- CLOSESOCKET(fd_discovery);
-
- for(i=0; i<MAXCLIENTS; i++)
- CloseConnection(i);
-
- cXinelibThread::Stop();
-}
-
-void cXinelibServer::Clear(void)
-{
- TRACEF("cXinelibServer::Clear");
-
- LOCK_THREAD;
-
- for(int i = 0; i < MAXCLIENTS; i++)
- if(fd_control[i].open() && m_Writer[i])
- m_Writer[i]->Clear();
-
- if(m_Scheduler)
- m_Scheduler->Clear();
-
- cXinelibThread::Clear();
-}
-
-void cXinelibServer::CloseDataConnection(int cli)
-{
- if(m_bUdp[cli] && fd_data[cli]>=0)
- m_Scheduler->RemoveHandle(fd_data[cli]);
-
- CLOSESOCKET(fd_data[cli]);
-
- if(m_Writer[cli]) {
- delete m_Writer[cli];
- m_Writer[cli] = NULL;
- }
-
- m_bUdp[cli] = false;
- m_bMulticast[cli] = false;
- m_bConfigOk[cli] = false;
-
- m_iMulticastMask &= ~(1<<cli);
-
- if(!m_iMulticastMask && !xc.remote_rtp_always_on)
- m_Scheduler->RemoveRtp();
-}
-
-void cXinelibServer::CloseConnection(int cli)
-{
- CloseDataConnection(cli);
- if(fd_control[cli].open()) {
- LOGMSG("Closing connection %d", cli);
- fd_control[cli].close();
- if(m_State[cli]) {
- delete m_State[cli];
- m_State[cli] = NULL;
- }
- cXinelibDevice::Instance().ForcePrimaryDevice(false);
- }
-}
-
-static int recompress_osd_net(uint8_t *raw, xine_rle_elem_t *data, int elems)
-{
- uint8_t *raw0 = raw;
- for(int i=0; i<elems; i++) {
- uint16_t len = data[i].len;
- uint16_t color = data[i].color;
- if(len >= 0x80) {
- *(raw++) = (len>>8) | 0x80;
- *(raw++) = (len & 0xff);
- } else {
- *(raw++) = (len & 0x7f);
- }
- *(raw++) = color;
- }
- return (raw-raw0);
-}
-
-static int write_osd_command(cxSocket& s, osd_command_t *cmd)
-{
- cxPoller p(s, true);
- if(!p.Poll(100)) {
- LOGMSG("write_osd_command: poll failed, OSD send skipped");
- return 0;
- }
-
- ssize_t max = s.tx_buffer_free();
- ssize_t size = (ssize_t)8 +
- (ssize_t)(sizeof(osd_command_t)) +
- (ssize_t)(sizeof(xine_clut_t) * ntohl(cmd->colors)) +
- (ssize_t)(ntohl(cmd->datalen));
-
- if(max > 0 && max < size) {
-/* #warning TODO: buffer latest failed OSD and retry
- -> skipped OSDs can be left out but
- latest will be always delivered */
- LOGMSG("write_osd_command: socket buffer full, OSD send skipped (got %d ; need %d",
- (int)max, (int)size);
- return 0;
- }
-
- cmd->size = sizeof(osd_command_t);
-
- if(8 != s.write("OSDCMD\r\n", 8, 100)) {
- LOGDBG("write_osd_command: write (command) failed");
- return -1;
- }
- if((ssize_t)sizeof(osd_command_t) !=
- s.write(cmd, sizeof(osd_command_t), 100)) {
- LOGDBG("write_osd_command: write (data) failed");
- return -1;
- }
- if(cmd->palette && cmd->colors &&
- (ssize_t)(sizeof(xine_clut_t)*ntohl(cmd->colors)) !=
- s.write(cmd->palette, sizeof(xine_clut_t)*ntohl(cmd->colors), 100)) {
- LOGDBG("write_osd_command: write (palette) failed");
- return -1;
- }
- if(cmd->data && cmd->datalen &&
- (ssize_t)ntohl(cmd->datalen) != s.write(cmd->data, ntohl(cmd->datalen), 300)) {
- LOGDBG("write_osd_command: write (bitmap) failed");
- return -1;
- }
- return 1;
-}
-
-#ifdef HTTP_OSD
-#include "dvdauthor/rgb.h"
-#include "dvdauthor/subgen-encode.c"
-#include "dvdauthor/subgen.c"
-#include "dvdauthor/subgen-image.c"
-//subgen-image: palette generation, image divided to buttons --> 16-col palette
-static uint8_t *dvdspu_encode(osd_command_t *cmd, int *spulen)
-{
-#if 0
- stinfo st;
- st.x0 = cmd->x;
- st.y0 = cmd->y;
- st.xd = cmd->w;
- st.yd = cmd->h;
-
- st.spts = 0; /* start pts */
- st.sd = 0; /* duration */
- st.forced = 0;
- st.numbuttons = 0;
- st.numpal = 0;
-
- st.autooutline = 0; /* -> 1 -> imgfix calls detectbuttons(s); */
- st.outlinewidth = 0;
- st.autoorder = 0;
-
- st.img =; /* img */
- st.hlt =; /* img */
- st.sel =; /* img */
- st.fimg = NULL;
-
- st.pal[4] = ; /* palt */
- st.masterpal[16] = ; /* palt */
- st.transparentc = ; /* palt */
-
- st.numgroups = ;
- st.groupmap[3][4] = ;
- st.buttons = ; /* button * */
-
- if(imgfix(&st))
- dvd_encode(&st);
-#endif
- return NULL;
-
-}
-#endif
-
-void cXinelibServer::OsdCmd(void *cmd_gen)
-{
- TRACEF("cXinelibServer::OsdCmd");
- int i;
-
- LOCK_THREAD;
-
- // check if there are any clients
- if(!HasClients())
- return;
-
- if(cmd_gen) {
- osd_command_t *cmd = (osd_command_t*)cmd_gen;
- osd_command_t cmdnet;
- memcpy(&cmdnet, cmd, sizeof(osd_command_t));
- if (cmd->data) {
- cmdnet.raw_data = (uint8_t *)malloc(cmd->datalen);
- cmdnet.datalen = recompress_osd_net(cmdnet.raw_data, cmd->data, cmd->num_rle);
- }
- // -> network byte order
- hton_osdcmd(cmdnet);
-
-#ifdef HTTP_OSD
- uint8_t *spudata = NULL;
- int spulen = 0;
-#endif
-
- for(i = 0; i < MAXCLIENTS; i++) {
- if(fd_control[i].open() && m_bConfigOk[i]) {
- int r = write_osd_command(fd_control[i], &cmdnet);
- if(r < 0) {
- LOGMSG("Send OSD command failed, closing connection");
- CloseConnection(i);
- } else if(r == 0) {
- if(m_OsdTimeouts[i]++ > MAX_OSD_TIMEOUTS) {
- LOGMSG("Too many OSD timeouts, dropping client");
- CloseConnection(i);
- }
- } else {
- m_OsdTimeouts[i] = 0;
- }
- }
-#ifdef HTTP_OSD
- if(m_ConnType[i] == ctHttp) {
- if(m_Writer[i]) {
- if(!spudata)
- spudata = dvdspu_encode(cmd, &spulen);
- if(spudata)
- m_Writer[i]->Put(-1, spudata, spulen);
- }
- }
-#endif
- }
-
-#ifdef HTTP_OSD
- free(spudata);
-#endif
-
- free(cmdnet.data);
-
-#ifdef LOG_OSD_BANDWIDTH
- {
- static int64_t timer = 0LL;
- static int bytes = 0;
- int64_t now = cTimeMs::Now();
-
- if(timer + 5000LL < now) {
- timer = now;
- bytes = 0;
- } else if(timer + 1000LL < now) {
- bytes = bytes / (((int)(now - timer)) / 1000);
- if(bytes > LOG_OSD_BANDWIDTH)
- LOGMSG("OSD bandwidth: %d bytes/s (%d kbit/s)", bytes, bytes*8/1024);
- timer = now;
- bytes = 0;
- }
- bytes += sizeof(osd_command_t) + ntohl(cmdnet.datalen);
- }
-#endif
- }
-}
-
-int64_t cXinelibServer::GetSTC(void)
-{
- Lock();
-
- // check if there are any clients
- if(!HasClients()) {
- Unlock();
- return -1ULL;
- }
-
- // Query client(s)
- m_StcFuture->Reset();
- Xine_Control("GETSTC");
-
- Unlock();
-
- if(! m_StcFuture->Wait(200)) {
- LOGMSG("cXinelibServer::GetSTC timeout (200ms)");
- return -1ULL;
- }
-
- //if(delay.Elapsed() > 0 && !is_Paused)
- // LOGMSG("GetSTC: compensating network delay by %s ticks (ms)\n",
- // delay.Elapsed()*90000/2, delay.Elapsed()/2);
-
- return m_StcFuture->Value() /*+ (delay.Elapsed()*90000/2*/;
-}
-
-void cXinelibServer::SetHeader(const uchar *Data, int Length, bool Reset)
-{
- LOCK_THREAD; // Lock control thread out
-
- if (Reset)
- m_HeaderLength = 0;
-
- if (m_HeaderSize < m_HeaderLength + Length) {
- if (!m_Header) {
- m_HeaderSize = Length;
- m_Header = (uchar*)malloc(m_HeaderSize);
- } else {
- m_HeaderSize = m_HeaderLength + Length;
- m_Header = (uchar*)realloc(m_Header, m_HeaderSize);
- }
- }
-
- if (m_Header) {
- memcpy(m_Header + m_HeaderLength, Data, Length);
- m_HeaderLength += Length;
- }
-}
-
-int cXinelibServer::Play_PES(const uchar *data, int len)
-{
- int TcpClients = 0, UdpClients = 0, RtpClients = 0;
-
- LOCK_THREAD; // Lock control thread out
-
- for(int i=0; i<MAXCLIENTS; i++) {
- if(fd_control[i].open()) {
- if((m_bConfigOk[i] && fd_data[i] >= 0) ||
- m_ConnType[i] & (ctHttp|ctRtsp)) {
-
- if(m_bUdp[i]) {
-
- UdpClients++;
-
- } else if(m_Writer[i]) {
-
- int result = m_Writer[i]->Put(m_StreamPos, data, len);
- if(!result) {
- LOGMSG("cXinelibServer::Play_PES Write/Queue error (TCP/PIPE)");
- CloseConnection(i);
- } else if(result<0) {
- LOGMSG("cXinelibServer::Play_PES Buffer overflow (TCP/PIPE)");
- if(m_ConnType[i] == ctHttp)
- m_Writer[i]->Clear();
- }
-
- TcpClients++;
- }
- }
- }
- }
-
- RtpClients = (m_iMulticastMask || xc.remote_rtp_always_on);
-
- if(UdpClients || RtpClients)
- if(! m_Scheduler->Queue(m_StreamPos, data, len))
- LOGMSG("cXinelibServer::Play_PES Buffer overflow (UDP/RTP)");
-
- if(TcpClients || UdpClients || RtpClients)
- cXinelibThread::Play_PES(data, len);
-
- return len;
-}
-
-void cXinelibServer::SetHDMode(bool On)
-{
- cXinelibThread::SetHDMode(On);
-#if 0
- /*#warning TODO*/
- LOCK_THREAD;
-
- int i;
- for(i=0; i<MAXCLIENTS; i++)
- if(m_Writer[i])
- m_Writer[i]->SetBuffer(On ? 2048 : 512);
- m_Scheduler->SetWindow(On ? 512 : 128);
-#endif
-}
-
-int cXinelibServer::Poll(cPoller &Poller, int TimeoutMs)
-{
- // in live mode transponder clock is the master ...
- // in replay mode local frontend (if present) is master
- if(m_bLiveMode || (*xc.local_frontend && strncmp(xc.local_frontend, "none", 4))) {
- if(m_Scheduler->Clients())
- return m_Scheduler->Poll(TimeoutMs, m_Master = false);
- return DEFAULT_POLL_SIZE;
- }
-
- // replay mode:
- do {
- Lock();
- m_Master = true;
- int Free = 0xfffff, FreeHttp = 0xfffff, FreeUdp = 0;
- int Clients = 0, Http = 0, Udp = 0;
- for(int i=0; i<MAXCLIENTS; i++) {
- if(fd_control[i].open()) {
- if(m_bConfigOk[i]) {
- if(m_Writer[i])
- Free = min(Free, m_Writer[i]->Free());
- else if(m_bUdp[i])
- Udp++;
- Clients++;
- } else if(m_ConnType[i] & (ctHttp|ctRtspMux)) {
- if(m_Writer[i]) {
- FreeHttp = min(FreeHttp, m_Writer[i]->Free());
- Http++;
- }
- }
- }
- }
- if(m_iMulticastMask) {
- Clients++;
- Udp++;
- }
-
- /* select master timing source for replay mode */
- int master = -1;
- if(Clients && !Udp) {
- for(int i=0; i<MAXCLIENTS; i++)
- if(fd_control[i].open() && m_bConfigOk[i] && m_Writer[i]) {
- master = i;
- break;
- }
- }
- if(master != m_MasterCli) {
- if(m_MasterCli >= 0)
- Xine_Control("MASTER 0");
- if(master >= 0)
- fd_control[master].write_cmd("MASTER 1\r\n");
- m_MasterCli = master;
- }
-
- Unlock();
-
- if(!Clients && !Http) {
- // live mode runs even if there are no clients
- if(m_bLiveMode)
- return DEFAULT_POLL_SIZE;
- // replay is paused when no clients
- if(TimeoutMs>0)
- cCondWait::SleepMs(TimeoutMs);
- return 0;
- }
-
- // in replay mode cUdpScheduler is master timing source
- if( Free < 8128 ||
- ((FreeUdp = m_Scheduler->Poll(TimeoutMs, true)) < 1) ||
- (!Clients && FreeHttp < 8128)) {
-
- if(TimeoutMs > 0)
- cCondWait::SleepMs(min(TimeoutMs, 5));
- TimeoutMs -= 5;
-
- } else {
- Free = min(Free, FreeHttp) / 2070;
- Free = min(Free, FreeUdp);
- return max(0, Free);
- }
-
- } while(TimeoutMs > 0);
-
- return 0;
-}
-
-bool cXinelibServer::Flush(int TimeoutMs)
-{
- int result = true;
-
- if(m_Scheduler)
- result = m_Scheduler->Flush(TimeoutMs) && result;
-
- for(int i=0; i<MAXCLIENTS; i++)
- if(fd_control[i].open() && fd_data[i]>=0 && m_Writer[i])
- result = m_Writer[i]->Flush(TimeoutMs) && result;
-
- if(TimeoutMs > 50)
- TimeoutMs = 50;
-
- if(result) {
- cString tmp = cString::sprintf("FLUSH %d %" PRIu64 " %d",
- TimeoutMs, m_StreamPos, m_Frames);
- result = (PlayFileCtrl(tmp)) <= 0 && result;
- }
-
- return result;
-}
-
-int cXinelibServer::Xine_Control(const char *cmd)
-{
- TRACEF("cXinelibServer::Xine_Control");
-
- if(cmd && *cmd) {
- char buf[4096];
- int len = snprintf(buf, sizeof(buf), "%s\r\n", cmd);
- if(len >= (int)sizeof(buf)) {
- LOGMSG("Xine_Control: command truncated !");
- //len = sizeof(buf);
- return 0;
- }
-
- LOCK_THREAD;
-
- for(int i=0; i<MAXCLIENTS; i++)
- if(fd_control[i].open() && (fd_data[i]>=0 || m_bMulticast[i]) && m_bConfigOk[i])
- if(len != fd_control[i].write(buf, len, 100)) {
- LOGMSG("Control send failed (%s), dropping client", cmd);
- CloseConnection(i);
- }
- }
-
- return 1;
-}
-
-int cXinelibServer::Xine_Control_Sync(const char *cmd)
-{
- TRACEF("cXinelibServer::Xine_Control_Sync");
-
- if(cmd && *cmd) {
- int i, len, UdpClients = 0, RtpClients = 0;
- char buf[256];
-
- len = snprintf(buf, sizeof(buf), "%s\r\n", cmd) + 1;
- if(len >= (int)sizeof(buf)) {
- LOGMSG("Xine_Control_Sync: command truncated ! (%s)", cmd);
- len = sizeof(buf);
- }
-
- LOCK_THREAD;
-
- for(i=0; i<MAXCLIENTS; i++)
- if(fd_control[i].open() && m_bConfigOk[i]) {
- if(fd_data[i] >= 0) {
- if(m_bUdp[i])
- UdpClients++;
- else if(m_Writer[i])
- m_Writer[i]->Put((uint64_t)(-1ULL), (const uchar*)buf, len);
- }
- }
-
- RtpClients = (m_iMulticastMask || xc.remote_rtp_always_on);
-
- if(UdpClients || RtpClients)
- if(! m_Scheduler->Queue((uint64_t)(-1ULL), (const uchar*)buf, len))
- LOGMSG("cXinelibServer::Xine_Control_Sync overflow (UDP/RTP)");
- }
-
- return 1;
-}
-
-void cXinelibServer::TrickSpeed(int Speed)
-{
- if(Speed == 0) {
- m_Scheduler->Pause(true);
- } else {
- m_Scheduler->Pause(false);
- m_Scheduler->TrickSpeed(Speed == -1 ? 1 : Speed);
- }
-
- cXinelibThread::TrickSpeed(Speed);
-}
-
-bool cXinelibServer::EndOfStreamReached(void)
-{
- LOCK_THREAD;
-
- /* Check if there are any clients */
- if(!HasClients())
- return true;
-
- return cXinelibThread::EndOfStreamReached();
-}
-
-int cXinelibServer::AllocToken(void)
-{
- LOCK_THREAD;
-
- m_Token = (m_Token+1) & 0xffff;
-
- cXinelibThread::Xine_Control((const char *)"TOKEN", m_Token);
-
- return m_Token;
-}
-
-bool cXinelibServer::HasClients(void)
-{
- LOCK_THREAD;
-
- int i;
- for(i=0; i<MAXCLIENTS; i++)
- if(fd_control[i].open() && m_bConfigOk[i])
- return true;
-
- return false;
-}
-
-int cXinelibServer::PlayFileCtrl(const char *Cmd, int TimeoutMs)
-{
- /* Check if there are any clients */
- if(!HasClients()) {
- cHttpStreamer::CloseAll();
- return -1;
- }
-
- bool bPlayfile = false /*, bGet = false, bFlush = false*/;
- if((!strncmp(Cmd, "FLUSH", 5) /*&& (bFlush=true)*/) ||
- (!strncmp(Cmd, "PLAYFILE", 8) && (bPlayfile=true)) ||
- (!strncmp(Cmd, "GET", 3) /*&& (bGet=true)*/)) { // GETPOS, GETLENGTH, ...
-
- Lock();
-
- /* Get token, send it to client and set future for it */
- int token = AllocToken();
- cReplyFuture future;
- m_Futures->Add(&future, token);
-
- /* Send actual command */
- cXinelibThread::PlayFileCtrl(Cmd);
-
- Unlock();
-
- /* When server thread get REPLY %d %d (first %d == token, second returned value)
- * it sets corresponding future (by token; if found) in list
- * and removes it from list.
- */
-
-#ifdef XINELIBOUTPUT_DEBUG
- int64_t t = cTimeMs::Now();
-#endif
-
- if(TimeoutMs < 0)
- TimeoutMs = bPlayfile ? PLAYFILE_TIMEOUT : PLAYFILE_CTRL_TIMEOUT;
-
- future.Wait(TimeoutMs);
-
- Lock();
- m_Futures->Del(&future, token);
- Unlock();
-
- if(!future.IsReady()) {
- LOGMSG("cXinelibServer::PlayFileCtrl: Timeout (%s , %d ms) %d", Cmd, TimeoutMs, token);
- return -1;
- }
-
- TRACE("cXinelibServer::PlayFileCtrl("<<Cmd<<"): result=" << future.Value()
- << " delay: " << (int)(cTimeMs::Now()-t) << "ms");
-
- if(bPlayfile)
- m_bEndOfStreamReached = false;
-
- return future.Value();
- }
-
- bool result = cXinelibThread::PlayFileCtrl(Cmd);
- if(!*m_FileName)
- cHttpStreamer::CloseAll();
- return result;
-}
-
-
-bool cXinelibServer::Listen(int listen_port)
-{
- LOCK_THREAD;
-
- bool result = false;
- TRACEF("cXinelibServer::Listen");
-
- if(listen_port <= 0 || listen_port > 0xffff) {
- CLOSESOCKET(fd_listen);
- CLOSESOCKET(fd_discovery);
- if(m_Scheduler)
- m_Scheduler->RemoveRtp();
- cHttpStreamer::CloseAll();
- LOGMSG("Not listening for remote connections");
- return false;
- }
-
- if(fd_listen<0 || listen_port != m_Port) {
- m_Port = listen_port;
- CLOSESOCKET(fd_listen);
-
- int iReuse = 1;
- struct sockaddr_in name;
- name.sin_family = AF_INET;
- name.sin_addr.s_addr = htonl(INADDR_ANY);
- name.sin_port = htons(m_Port);
-
- if(xc.remote_local_ip[0]) {
- uint32_t ip = inet_addr(xc.remote_local_ip);
- if(ip != INADDR_NONE) {
- char txt[128];
- name.sin_addr.s_addr = ip;
- LOGDBG("Binding server to %s", cxSocket::ip2txt(name.sin_addr.s_addr, htons(m_Port), txt));
- } else {
- LOGERR("Local interface address %s is invalid !", xc.remote_local_ip);
- }
- }
- fd_listen = socket(PF_INET,SOCK_STREAM,0);
- setsockopt(fd_listen, SOL_SOCKET, SO_REUSEADDR, &iReuse, sizeof(int));
-
- if (bind(fd_listen, (struct sockaddr *)&name, sizeof(name)) < 0) {
- LOGERR("cXinelibServer: bind error %s port %d: %s",
- xc.remote_local_ip[0] ? xc.remote_local_ip : "",
- m_Port, strerror(errno));
- CLOSESOCKET(fd_listen);
- } else if(listen(fd_listen, MAXCLIENTS)) {
- LOGERR("cXinelibServer: listen error (port %d): %s",
- m_Port, strerror(errno));
- CLOSESOCKET(fd_listen);
- } else {
- LOGMSG("Listening on port %d", m_Port);
- result = true;
- }
- } else {
- result = true;
- }
-
- // set listen for discovery messages
- CLOSESOCKET(fd_discovery);
- if(xc.remote_usebcast) {
- fd_discovery = udp_discovery_init();
- if(udp_discovery_broadcast(fd_discovery, m_Port, xc.remote_local_ip) < 0)
- CLOSESOCKET(fd_discovery);
- else
- LOGMSG("Listening for UDP broadcasts on port %d", m_Port);
- }
-
- // set up multicast sockets
-
- if(m_Scheduler)
- m_Scheduler->RemoveRtp();
-
- if(xc.remote_usertp) {
- if(xc.remote_rtp_always_on)
- LOGMSG("WARNING: RTP Configuration: transmission is always on !");
- if(xc.remote_rtp_always_on || m_iMulticastMask)
- m_Scheduler->AddRtp();
- }
-
- return result;
-}
-
-uchar *cXinelibServer::GrabImage(int &Size, bool Jpeg,
- int Quality, int SizeX, int SizeY)
-{
- cGrabReplyFuture future;
- uchar *result = NULL;
- cString cmd;
-
- cmd = cString::sprintf("GRAB %s %d %d %d\r\n",
- Jpeg ? "JPEG" : "PNM",
- Quality, SizeX, SizeY);
-
- Lock();
-
- /* Check if there are any clients */
- if(!HasClients()) {
- Unlock();
- return NULL;
- }
-
- int token = AllocToken();
- m_Futures->Add(&future, token);
-
- // might be better to request iamge from one client only (?)
- Xine_Control(cmd);
-
- Unlock();
-
- if(future.Wait(5000)) {
- grab_result_t r = future.Value();
- if((Size = r.Size) > 0) {
- LOGDBG("cXinelibServer::GrabImage: image size is %d bytes", Size);
- result = r.Data;
- } else {
- LOGMSG("cXinelibServer::Grab: Grab failed (%d)", Size);
- }
- } else {
- LOGMSG("cXinelibServer::Grab: Timeout (5000 ms)");
- }
-
- Lock();
- m_Futures->Del(&future, token);
- Unlock();
-
- return result;
-}
-
-//
-// (Client) Control message handling
-//
-
-void cXinelibServer::Handle_Control_PIPE(int cli, const char *arg)
-{
- LOGDBG("Trying PIPE connection ...");
-
- CloseDataConnection(cli);
-
- //
- // TODO: client should create pipe; waiting here is not good thing ...
- //
-
- if(!xc.remote_usepipe) {
- LOGMSG("PIPE transport disabled in configuration");
- fd_control[cli].write_cmd("PIPE: Pipe transport disabled in config.\r\n");
- return;
- }
-
- MakeDirs(m_PipesDir, true);
-
- int i;
- cString pipeName;
- for(i=0; i<10; i++) {
- pipeName = cString::sprintf("%s/pipe.%d", *m_PipesDir, i);
- if(mknod(pipeName, 0644|S_IFIFO, 0) < 0) {
- unlink(pipeName);
- continue;
- }
- else
- break;
- }
- if(i>=10) {
- LOGERR("Pipe creation failed (%s)", *pipeName);
- RemoveFileOrDir(m_PipesDir, false);
- fd_control[cli].write_cmd("PIPE: Pipe creation failed.\r\n");
- return;
- }
-
- fd_control[cli].printf("PIPE %s\r\n", *pipeName);
-
- cxPoller poller(fd_control[cli]);
- poller.Poll(500); /* quite short time ... */
-
- int fd;
- if((fd = open(pipeName, O_WRONLY|O_NONBLOCK)) < 0) {
- LOGDBG("Pipe not opened by client");
- /*write_cmd(fd_control[cli], "PIPE NONE\r\n");*/
- unlink(pipeName);
- RemoveFileOrDir(m_PipesDir, false);
- return;
- }
-
- fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)|O_NONBLOCK);
-
- //LOGDBG("cXinelibServer::Handle_Control: pipe %s open", pipeName);
-
- unlink(pipeName); /* safe to remove now, both ends are open or closed. */
- RemoveFileOrDir(m_PipesDir, false);
- fd_control[cli].write_cmd("PIPE OK\r\n");
-
- if (m_Writer[cli])
- delete m_Writer[cli];
- m_Writer[cli] = new cTcpWriter(fd);
-
- if (m_Header)
- m_Writer[cli]->Put(0, m_Header, m_HeaderLength);
-
- fd_data[cli] = fd;
-}
-
-
-void cXinelibServer::Handle_Control_DATA(int cli, const char *arg)
-{
- int clientId = -1;
- unsigned int ipc, portc;
-
- LOGDBG("Data connection (TCP) requested");
-
- CloseDataConnection(cli);
-
- if(!xc.remote_usetcp) {
- LOGMSG("TCP transports disabled in configuration");
- fd_control[cli].write_cmd("TCP: TCP transport disabled in config.\r\n");
- CloseConnection(cli); /* actually closes the new data connection */
- return;
- }
-
- /* validate client ID */
- if(3 != sscanf(arg, "%d 0x%x:%d", &clientId, &ipc, &portc) ||
- clientId < 0 ||
- clientId >= MAXCLIENTS ||
- !fd_control[clientId].open()) {
- fd_control[cli].write_cmd("TCP: Error in request (ClientId).\r\n");
- LOGDBG("Invalid data connection (TCP) request");
- /* close only new data connection, no control connection */
- CloseConnection(cli);
- return;
- }
-
- /* check client IP's */
- struct sockaddr_in sinc, sind;
- socklen_t len = sizeof(sinc);
- sinc.sin_addr.s_addr = 0;
- sind.sin_addr.s_addr = ~0;
- fd_control[cli].getpeername((struct sockaddr *)&sind, &len);
- fd_control[clientId].getpeername((struct sockaddr *)&sinc, &len);
- if(sinc.sin_addr.s_addr != sind.sin_addr.s_addr) {
- fd_control[cli].write_cmd("TCP: Error in request (IP does not match).\r\n");
- LOGMSG("Invalid data connection (TCP) request: IP does not match: ctrl %x, data %x",
- (unsigned int)sinc.sin_addr.s_addr, (unsigned int)sind.sin_addr.s_addr);
- CloseConnection(cli);
- return;
- }
- if(htonl(ipc) != sinc.sin_addr.s_addr || htons(portc) != sinc.sin_port) {
- fd_control[cli].write_cmd("TCP: Error in request (invalid IP:port).\r\n");
- LOGMSG("Invalid data connection (TCP) request: control IP:port does not match"
- "control: %x:%d client: %x:%d",
- (unsigned int)sinc.sin_addr.s_addr, (unsigned int)sinc.sin_port,
- (unsigned int)htonl(ipc), (unsigned int)htons(portc));
- CloseConnection(cli);
- return;
- }
-
- /* close old data connection */
- CloseDataConnection(clientId);
-
- /* change connection type */
-
- fd_control[cli].write_cmd("DATA\r\n");
- fd_data[clientId] = fd_control[cli].handle(true);
-
- cli = clientId;
-
- if (m_Writer[cli])
- delete m_Writer[cli];
- m_Writer[cli] = new cTcpWriter(fd_data[cli]);
-
- if (m_Header)
- m_Writer[cli]->Put(0, m_Header, m_HeaderLength);
-
- /* not anymore control connection, so dec primary device reference counter */
- cXinelibDevice::Instance().ForcePrimaryDevice(false);
-}
-
-void cXinelibServer::Handle_Control_RTP(int cli, const char *arg)
-{
- LOGDBG("Trying RTP connection ...");
-
- CloseDataConnection(cli);
-
-#if VDRVERSNUM > 10700
- // UDP/RTP not MPEG-TS compatible yet
- fd_control[cli].write_cmd("RTP: RTP transport not implemented for vdr-1.7.x.\r\n");
- LOGMSG("RTP transport not implemented for vdr-1.7.x");
- return;
-#endif
-
- if(!xc.remote_usertp) {
- fd_control[cli].write_cmd("RTP: RTP transport disabled in configuration.\r\n");
- LOGMSG("RTP transports disabled");
- return;
- }
-
- fd_control[cli].printf("RTP %s:%d\r\n", xc.remote_rtp_addr, xc.remote_rtp_port);
-
- if(!m_iMulticastMask && !xc.remote_rtp_always_on)
- m_Scheduler->AddRtp();
-
- m_bMulticast[cli] = true;
- m_iMulticastMask |= (1<<cli);
-
- // Send padding packet before header (PAT/PMT).
- // Client uses first received UDP/RTP packet to test connection.
- m_Scheduler->QueuePadding();
- if (m_Header)
- m_Scheduler->Queue(0, m_Header, m_HeaderLength);
-}
-
-void cXinelibServer::Handle_Control_UDP(int cli, const char *arg)
-{
- LOGDBG("Trying UDP connection ...");
-
- CloseDataConnection(cli);
-
-#if VDRVERSNUM > 10700
- // UDP/RTP not MPEG-TS compatible yet
- fd_control[cli].write_cmd("UDP: UDP transport not implemented vor vdr-1.7.x.\r\n");
- LOGMSG("UDP transport not implemented for vdr-1.7.x");
- return;
-#endif
-
- if(!xc.remote_useudp) {
- fd_control[cli].write_cmd("UDP: UDP transport disabled in configuration.\r\n");
- LOGMSG("UDP transport disabled in configuration");
- return;
- }
-
- int fd = sock_connect(fd_control[cli].handle(), atoi(arg), SOCK_DGRAM);
- if(fd < 0) {
- LOGERR("socket() for UDP failed");
- fd_control[cli].write_cmd("UDP: Socked failed.\r\n");
- return;
- }
-
- fd_control[cli].write_cmd("UDP OK\r\n");
- m_bUdp[cli] = true;
- fd_data[cli] = fd;
- m_Scheduler->AddHandle(fd);
-
- // Send padding packet before header (PAT/PMT).
- // Client uses first received UDP/RTP packet to test connection.
- m_Scheduler->QueuePadding();
- if (m_Header)
- m_Scheduler->Queue(0, m_Header, m_HeaderLength);
-}
-
-void cXinelibServer::Handle_Control_KEY(int cli, const char *arg)
-{
- TRACE("cXinelibServer received KEY " << buf);
-
- if(!xc.remote_keyboard) {
- LOGMSG("Handle_Control_KEY(%s): Remote keyboard disabled in config", arg);
- return;
- }
-
- char buf[256], *pt, *key;
- bool repeat = false, release = false;
- strn0cpy(buf, arg, sizeof(buf));
-
- size_t n = *buf ? strlen(buf)-1 : 0;
- while(n && buf[n]==' ') buf[n--]=0; /* trailing spaces */
- if(NULL != (key=strchr(buf, ' '))) {
- while(*key == ' ')
- *(key++) = 0;
- if(NULL != (pt = strchr(key, ' '))) {
- *(pt++) = 0;
- if(strstr(pt, "Repeat"))
- repeat = true;
- if(strstr(pt, "Release"))
- release = true;
- }
- cXinelibThread::KeypressHandler(buf, key, repeat, release);
- } else {
- cXinelibThread::KeypressHandler(NULL, buf, repeat, release);
- }
-}
-
-void cXinelibServer::Handle_Control_CONFIG(int cli)
-{
- m_bConfigOk[cli] = true;
-
- fd_control[cli].set_nodelay(true);
-
- fd_control[cli].printf("NOVIDEO %d\r\nLIVE %d\r\n",
- m_bNoVideo?1:0, m_bLiveMode?1:0);
-
- SetVolume(m_Volume);
-
- Configure();
-
- fd_control[cli].write_cmd("CLEAR\r\n");
-
- if(m_bPlayingFile && *m_FileName) {
- Unlock();
- int pos = cXinelibDevice::Instance().PlayFileCtrl("GETPOS");
- Lock();
- if(m_bPlayingFile && *m_FileName) {
- fd_control[cli].printf("PLAYFILE %d %s %s\r\n",
- (pos>0?pos/1000:0), xc.audio_visualization, *m_FileName);
- }
- }
-
- cXinelibOsdProvider::RefreshOsd();
-}
-
-void cXinelibServer::Handle_Control_UDP_RESEND(int cli, const char *arg)
-{
- unsigned int seq1, seq2;
- uint64_t pos;
-
- if( (!fd_data[cli] || !m_bUdp[cli]) &&
- (!m_bMulticast[cli])) {
- LOGMSG("Got invalid re-send request: no udp/rtp in use");
- return;
- }
-
- if(3 == sscanf(arg, "%d-%d %" PRIu64, &seq1, &seq2, &pos)) {
-
- if(seq1 <= UDP_SEQ_MASK && seq2 <= UDP_SEQ_MASK && pos <= m_StreamPos) {
-
- if(fd_data[cli] >= 0)
- m_Scheduler->ReSend(fd_data[cli], pos, seq1, seq2);
- else
- m_Scheduler->ReSend(-1, pos, seq1, seq2);
- } else {
- LOGMSG("Invalid re-send request: %s (send pos=%" PRIu64 ")",
- arg, m_StreamPos);
- }
- } else {
- LOGMSG("Invalid re-send request: %s (send pos=%" PRIu64 ")",
- arg, m_StreamPos);
- }
-}
-
-void cXinelibServer::Handle_Control_GRAB(int cli, const char *arg)
-{
- cGrabReplyFuture *f;
- int token = -1, size = 0;
- if(2 == sscanf(arg, "%d %d", &token, &size)) {
- if(size > 0 && size < 20480000) {
- uchar *result = (uchar*)malloc(size);
- Unlock(); /* may take a while ... */
- ssize_t n = fd_control[cli].read(result, size, 2000);
- Lock();
- if(n == size) {
- if(NULL != (f = (cGrabReplyFuture*)m_Futures->Get(token))) {
- grab_result_t r;
- r.Size = size;
- r.Data = result;
- m_Futures->Del(f, token);
- f->Set(r);
- result = NULL;
- } else {
- LOGMSG("cXinelibServer: Grab image discarded");
- }
- } else {
- LOGMSG("cXinelibServer: Grab result read() failed");
- CloseConnection(cli);
- }
- free(result);
- } else if(NULL != (f = (cGrabReplyFuture*)m_Futures->Get(token))) {
- grab_result_t r;
- r.Size = 0;
- r.Data = NULL;
- m_Futures->Del(f, token);
- f->Set(r);
- }
- }
-}
-
-void cXinelibServer::Handle_Control_CONTROL(int cli, const char *arg)
-{
- fd_control[cli].printf("VDR-" VDRVERSION " "
- "xineliboutput-" XINELIBOUTPUT_VERSION " "
- "READY\r\nCLIENT-ID %d\r\n", cli);
- m_ConnType[cli] = ctControl;
-}
-
-static int strcmp_escaped(const char *s1, const char *s2)
-{
- if(!strncmp(s1, "file:", 5))
- s1 += 5;
-
- while(*s1 && *s2) {
- int c1 = *s1;
- int c2 = *s2;
- if(c1 == '%' && s1[1] && s1[2] && 1 == sscanf(s1+1, "%02x", &c1)) s1 += 2;
- if(c2 == '%' && s2[1] && s2[2] && 1 == sscanf(s2+1, "%02x", &c2)) s2 += 2;
- if(c1 < c2) return -1;
- if(c1 > c2) return 1;
- s1++; s2++;
- }
- return *s1 ? -1 : *s2 ? 1 : 0;
-}
-
-void cXinelibServer::Handle_Control_HTTP(int cli, const char *arg)
-{
- // Parse request
- if(m_ConnType[cli] == ctDetecting || !m_State[cli]) {
- LOGDBG("HTTP request: %s", arg);
-
- DELETENULL(m_Writer[cli]);
- DELETENULL(m_State[cli]);
-
- m_State[cli] = new cConnState;
- if( !m_State[cli]->SetCommand(arg) ||
- strncmp(m_State[cli]->Version(), "HTTP/1.", 7) ||
- strcmp(m_State[cli]->Name(), "GET")) {
- LOGMSG("invalid HTTP request: %s", arg);
- CloseConnection(cli);
- return;
- }
- m_ConnType[cli] = ctHttp;
- return;
- }
-
- // Handle request
- else if(m_ConnType[cli] == ctHttp) {
- LOGDBG("HTTP(%d): %s", cli, arg);
-
- // Collect headers
- if(*arg) {
- m_State[cli]->AddHeader(arg);
- return;
- }
-
- LOGMSG("HTTP Request complete");
-
- //
- // primary device output (PES)
- //
- if(!strcmp(m_State[cli]->Uri(), "/")) {
-
- if(!xc.remote_use_http) {
- LOGMSG("HTTP transport disabled in configuration");
- fd_control[cli].write_cmd(HTTP_REPLY_404);
- LOGDBG("HTTP Reply: HTTP/1.1 404 Not Found");
- CloseConnection(cli);
- return;
- }
-
- LOGMSG("HTTP streaming primary device feed");
- fd_control[cli].write_cmd(HTTP_REPLY_200_PRIMARY);
-#if 0
- // pack header (scr 0, mux rate 0x6270)
- fd_control[cli].write(
- "\x00\x00\x01\xba"
- "\x44\x00\x04\x00" "\x04\x01\x01\x89" "\xc3\xf8", 14);
- // system header (streams C0, E0, BD, BF)
- fd_control[cli].write(
- "\x00\x00\x01\xbb" "\x00\x12"
- "\x80\xc4\xe1" "\x00\xe1" "\x7f"
- "\xb9\xe0\xe8" "\xb8\xc0\x20" "\xbd\xe0\x3a" "\xbf\xe0\x02", 24);
-#endif
- m_Writer[cli] = new cRawWriter(fd_control[cli].handle(), KILOBYTE(1024));
-
- if (m_Header)
- m_Writer[cli]->Put(0, m_Header, m_HeaderLength);
-
- DELETENULL(m_State[cli]);
- return;
- }
-
-#if 0
- //
- // primary device output (TS)
- //
- if(!strcmp(m_State[cli]->Uri(), "/TS")) {
- LOGMSG("HTTP streaming primary device feed (TS)");
- fd_control[cli].write_cmd(HTTP_REPLY_200_PRIMARY_TS);
- m_Writer[cli] = new cTsWriter(fd_control[cli].handle(), KILOBYTE(1024));
- DELETENULL(m_State[cli]);
- return;
- }
-#endif
-
-#if 0 /* for testing */
- else if(!strcmp(m_State[cli]->Uri(), "/test.avi")) {
- LOGMSG("HTTP streaming test file");
-
- // detach socket
- new cHttpStreamer(fd_control[cli].handle(true), "/tmp/test.avi", m_State[cli]);
- m_State[cli] = NULL;
- CloseConnection(cli);
- return;
- }
-#endif
-
- //
- // currently playing media file
- //
- else if(!strncmp(m_State[cli]->Uri(), "/PLAYFILE", 9)) {
-
- if(!xc.remote_http_files) {
- LOGMSG("HTTP transport for media files disabled in configuration");
- fd_control[cli].write_cmd(HTTP_REPLY_404);
- LOGDBG("HTTP Reply: HTTP/1.1 404 Not Found");
- CloseConnection(cli);
- return;
- }
-
- if( *m_FileName && m_bPlayingFile) {
- cString file = m_FileName;
- const char *pos = strstr(m_FileName, "#subtitle:");
- if(pos)
- file.Truncate(pos - m_FileName);
- bool Allow = ( !strcmp_escaped(file, m_State[cli]->Uri() + 9)
- || (pos && !strcmp_escaped(pos + 10, m_State[cli]->Uri() + 9)));
- if(Allow) {
- LOGMSG("HTTP streaming media file");
-
- // detach socket
- new cHttpStreamer(fd_control[cli].handle(true), m_State[cli]->Uri() + 9, m_State[cli]);
- m_State[cli] = NULL;
- CloseConnection(cli);
- return;
- }
- LOGDBG("HTTP Unauthorized request: %s", *m_State[cli]->Uri());
- }
- else
- LOGDBG("No currently playing file");
- }
-
- //
- // nothing else will be served ...
- //
- LOGMSG("Rejected HTTP request for \'%s\'", *m_State[cli]->Uri());
- fd_control[cli].write_cmd(HTTP_REPLY_404);
- LOGDBG("HTTP Reply: HTTP/1.1 404 Not Found");
- CloseConnection(cli);
- }
-}
-
-#define RTSP_200_OK "RTSP/1.0 200 OK\r\n" \
- "CSeq: %d\r\n"
-#define RTSP_401 "RTSP/1.0 401 Unauthorized\r\n" \
- "CSeq: %d\r\n" RTSP_FIN
-#define RTSP_415 "RTSP/1.0 415 Unsupported media type\r\n" \
- "CSeq: %d\r\n" RTSP_FIN
-#define RTSP_461 "RTSP/1.0 461 Unsupported transport\r\n" \
- "CSeq: %d\r\n" RTSP_FIN
-#define RTSP_501 "RTSP/1.0 501 Not implemented\r\n" \
- "CSeq: %d\r\n" RTSP_FIN
-#define RTSP_FIN "\r\n", CSeq
-
-#define RTSPOUT(x...) do { fd_control[cli].printf(x); LOGMSG("RTSP TX:" x); } while(0)
-//#define RTSPOUT(x...) fd_control[cli].printf_cmd(x)
-
-void cXinelibServer::Handle_Control_RTSP(int cli, const char *arg)
-{
- //
- // Minimal RTSP (RFC 2326) server implementation
- //
-
-
- //
- // collect request and headers
- //
- if(m_ConnType[cli] == ctDetecting || !m_State[cli]) {
- LOGDBG("RTSP request: %s", arg);
-
- DELETENULL(m_State[cli]);
- m_State[cli] = new cConnState;
-
- if( !m_State[cli]->SetCommand(arg) ||
- strcmp(m_State[cli]->Version(), "RTSP/1.0")) {
- LOGMSG("invalid RTSP request: %s", arg);
- CloseConnection(cli);
- return;
- }
- m_ConnType[cli] = ctRtsp;
- return;
- }
-
- //
- // Process complete request
- //
- else if(m_ConnType[cli] == ctRtsp) {
- LOGDBG("RTSP(%d): %s", cli, arg);
-
- if(*arg) {
- m_State[cli]->AddHeader(arg);
- return;
- }
-
- cHeader *cseq = m_State[cli]->Header("CSeq");
- int CSeq = cseq ? cseq->IntValue() : -1;
- LOGMSG("RTSP Request complete (cseq %d)", CSeq);
-
- if(!xc.remote_use_rtsp) {
- LOGMSG("RTSP transport disabled in configuration");
- fd_control[cli].write_cmd(RTSP_401);
- LOGDBG("HTTP Reply: HTTP/1.1 404 Not Found");
- CloseConnection(cli);
- return;
- }
-
- //
- // OPTIONS rtsp://127.0.0.1:37890 RTSP/1.0
- // CSeq: 1
- //
- if(!strcmp(m_State[cli]->Name(), "OPTIONS")) {
- RTSPOUT(RTSP_200_OK
- "Public: DESCRIBE, SETUP, TEARDOWN, PLAY\r\n"
- RTSP_FIN);
- } // OPTIONS
-
- //
- // DESCRIBE rtsp://127.0.0.1:37890 RTSP/1.0
- // CSeq: 2
- // Accept: application/sdp
- //
- else if(!strcmp(m_State[cli]->Name(), "DESCRIBE")) {
- cHeader *accept = m_State[cli]->Header("Accept");
- if(accept && strstr(accept->Value(), "application/sdp")) {
- struct sockaddr_in sin;
- socklen_t len = sizeof(sin);
- char buf[64];
- uint32_t payload_type = VDRVERSNUM > 10702 ? SDP_PAYLOAD_MPEG_TS : SDP_PAYLOAD_MPEG_PES;
- fd_control[cli].getsockname((struct sockaddr *)&sin, &len);
- const char *sdp_descr = vdr_sdp_description(cxSocket::ip2txt(sin.sin_addr.s_addr,
- sin.sin_port, buf),
- 2001,
- xc.listen_port,
- xc.remote_rtp_addr,
- payload_type,
- /*m_ssrc*/0x4df73452,
- xc.remote_rtp_port,
- xc.remote_rtp_ttl);
- size_t sdplen = sdp_descr ? strlen(sdp_descr) : 0;
- RTSPOUT(RTSP_200_OK
- "Content-Type: application/sdp\r\n"
- "Content-Length: %lu\r\n"
- "\r\n",
- CSeq, (unsigned long)sdplen);
- fd_control[cli].write_cmd(sdp_descr, sdplen);
- } else {
- RTSPOUT(RTSP_415 /*UNSUPPORTED_MEDIATYPE*/);
- }
- } // DESCRIBE
-
- //
- // SETUP rtsp://127.0.0.1:37890/ RTSP/1.0
- // CSeq: 15
- // Transport: RTP/AVP;unicast;client_port=37890-37891
- // User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10)
- //
- else if(!strcmp(m_State[cli]->Name(), "SETUP")) {
- cHeader *transport = m_State[cli]->Header("Transport");
- int urtp=0, mrtp=0, tcp=0;
- if(transport &&
- ( (strstr(transport->Value(), "RTP/AVP;multicast") && (mrtp=1)) ||
- (strstr(transport->Value(), "RTP/AVP;unicast") && (urtp=1)) ||
- (strstr(transport->Value(), "RTP/AVP;interleaved") && (tcp=1)))) {
- //if(!mrtp)
- // sprintf(buf, "RTSP/1.0 461 Unsupported transport\r\n" RTSP_H_CSEQ RTSP_OK_FIN);
- //else
- RTSPOUT(RTSP_200_OK
- "Session: %u\r\n"
- "Transport: RTP/AVP;multicast;destination=224.8.4.9;server_port=37890-37891\r\n"
- RTSP_FIN,
- cli);
- } else {
- RTSPOUT(RTSP_461 /*UNSUPPORTED_TRANSPORT*/ );
- }
- } // SETUP
-
- //
- // PLAY rtsp://127.0.0.1:37890 RTSP/1.0
- // CSeq: 13
- // Session: 0
- // Range: npt=0.000-
- // User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10)
- //
- else if(!strcmp(m_State[cli]->Name(), "PLAY")) {
- RTSPOUT(RTSP_200_OK
- RTSP_FIN);
-
- if(!m_iMulticastMask && !xc.remote_rtp_always_on)
- m_Scheduler->AddRtp();
-
- m_bMulticast[cli] = true;
- m_iMulticastMask |= (1<<cli);
-#if 0
- //udp
- int fd = sock_connect(fd_control[cli], atoi(arg), SOCK_DGRAM);
- if(fd < 0) {
- LOGERR("socket() for UDP failed");
- write_cmd(fd_control[cli], "UDP: Socked failed.\r\n");
- return;
- }
- m_bUdp[cli] = true;
- fd_data[cli] = fd;
- m_Scheduler->AddHandle(fd);
-#endif
- } // PLAY
-
- //
- // TEARDOWN rtsp://127.0.0.1:37890 RTSP/1.0
- // CSeq: 39
- // Session: 1
- // User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10)
- //
- else if(!strcmp(m_State[cli]->Name(), "TEARDOWN")) {
- RTSPOUT(RTSP_200_OK
- RTSP_FIN);
- CloseConnection(cli);
- } // TEARDOWN
-
- //
- // unknown/unsupported request
- //
- else {
- LOGMSG("Unsupported RTSP request: %s", *m_State[cli]->Name());
- RTSPOUT(RTSP_501 /*NOT_IMPLEMENTED*/);
- } // unsupported request
-
-
- // dispose buffer
- DELETENULL(m_State[cli]);
-
- } // ConnectionType == ctRtsp
-}
-
-void cXinelibServer::Handle_Control(int cli, const char *cmd)
-{
- TRACEF("cXinelibServer::Handle_Control");
-
-#ifdef LOG_CONTROL_MESSAGES
- static FILE *flog = fopen("/video/control.log","w");
- if (flog) {
- fprintf(flog,"CTRL (%d): %s\n",cli,cmd); fflush(flog);
- }
-#endif
-
- //LOGDBG("Server received %s", cmd);
- TRACE("Server received " << cmd);
-
- /* Order of tests is significant !!!
- (example: UDP 2\r\n or UDP FULL 1\r\n) */
-
- if(!strncasecmp(cmd, "OPTIONS ", 8) ||
- !strncasecmp(cmd, "SETUP ", 6) ||
- !strncasecmp(cmd, "DESCRIBE ", 9) ||
- m_ConnType[cli] == ctRtsp) {
-
- Handle_Control_RTSP(cli, cmd);
-
- } else if(!strncasecmp(cmd, "GET ", 4) ||
- m_ConnType[cli] == ctHttp) {
-
- Handle_Control_HTTP(cli, cmd);
-
- } else if(!strncasecmp(cmd, "PIPE OPEN", 9)) {
- LOGDBG("Pipe open");
-
- } else if(!strncasecmp(cmd, "PIPE", 4)) {
- Handle_Control_PIPE(cli, cmd+4);
-
- } else if(!strncasecmp(cmd, "RTP", 3)) {
- Handle_Control_RTP(cli, cmd+4);
-
- } else if(!strncasecmp(cmd, "UDP FULL", 8)) {
-
- } else if(!strncasecmp(cmd, "UDP RESEND ", 11)) {
- Handle_Control_UDP_RESEND(cli, cmd+11);
-
- } else if(!strncasecmp(cmd, "UDP ", 4)) {
- Handle_Control_UDP(cli, cmd+4);
-
- } else if(!strncasecmp(cmd, "DATA ", 5)) {
- Handle_Control_DATA(cli, cmd+5);
-
- } else if(!strncasecmp(cmd, "KEY ", 4)) {
- Handle_Control_KEY(cli, cmd+4);
-
- } else if(!strncasecmp(cmd, "CONFIG", 6)) {
- Handle_Control_CONFIG(cli);
-
- } else if(!strncasecmp(cmd, "STC ", 4)) {
- int64_t pts = -1;
- if(1 == sscanf(cmd+4, "%" PRId64, &pts))
- m_StcFuture->Set(pts);
-
- } else if(!strncasecmp(cmd, "ENDOFSTREAM", 11)) {
- m_bEndOfStreamReached = true;
-
- } else if(!strncasecmp(cmd, "RESULT ", 7)) {
- int token = -1, result = -1;
- if(2 == sscanf(cmd+7, "%d %d", &token, &result)) {
- cReplyFuture *f = m_Futures->Get(token);
- if(f) {
- m_Futures->Del(f, token);
- f->Set(result);
- }
- }
-
- } else if(!strncmp(cmd, "INFO ", 5)) {
- if(!*xc.local_frontend || !strncmp(xc.local_frontend, "none", 4))
- cXinelibThread::InfoHandler(cmd+5);
-
- } else if(!strncasecmp(cmd, "GRAB ", 5)) {
- Handle_Control_GRAB(cli, cmd+5);
-
- } else if(!strncasecmp(cmd, "CLOSE", 5)) {
- CloseConnection(cli);
-
- } else if(!strncasecmp(cmd, "CONTROL", 7)) {
- Handle_Control_CONTROL(cli, cmd);
-
- }
-}
-
-void cXinelibServer::Read_Control(int cli)
-{
- int n;
- while((n = fd_control[cli].recv(&m_CtrlBuf[ cli ][ m_CtrlBufPos[cli] ], 1)) == 1) {
-
- ++m_CtrlBufPos[cli];
-
- if( m_CtrlBufPos[cli] > CTRL_BUF_SIZE-2) {
- LOGMSG("Received too long control message from client %d (%d bytes)",
- cli, m_CtrlBufPos[cli]);
- LOGMSG("%81s",m_CtrlBuf[cli]);
- CloseConnection(cli);
- return;
- }
-
- if( m_CtrlBufPos[cli] > 1 &&
- m_CtrlBuf[ cli ][ m_CtrlBufPos[cli] - 2 ] == '\r' &&
- m_CtrlBuf[ cli ][ m_CtrlBufPos[cli] - 1 ] == '\n') {
-
- m_CtrlBufPos[cli] -= 2;
- m_CtrlBuf[ cli ][ m_CtrlBufPos[cli] ] = 0;
-
- Handle_Control(cli, m_CtrlBuf[cli]);
-
- m_CtrlBufPos[cli] = 0;
- }
- }
- if (n == 0) {
- LOGMSG("Client connection %d closed", cli);
- CloseConnection(cli);
- }
-}
-
-void cXinelibServer::Handle_ClientConnected(int fd)
-{
- char buf[64];
- struct sockaddr_in sin;
- socklen_t len = sizeof(sin);
- int cli;
-
- for(cli=0; cli<MAXCLIENTS; cli++)
- if(!fd_control[cli].open())
- break;
-
- if(getpeername(fd, (struct sockaddr *)&sin, &len)) {
- LOGERR("getpeername() failed, dropping new incoming connection %d", cli);
- CLOSESOCKET(fd);
- return;
- }
-
- LOGMSG("Client %d connected: %s", cli,
- cxSocket::ip2txt(sin.sin_addr.s_addr, sin.sin_port, buf));
-
- bool accepted = SVDRPhosts.Acceptable(sin.sin_addr.s_addr);
- if(!accepted) {
- const char *msg = "Access denied.\r\n";
- ssize_t len = strlen(msg);
- LOGMSG("Address not allowed to connect (svdrphosts.conf).");
- if(write(fd, msg, len) != len)
- LOGERR("Write failed.");
- CLOSESOCKET(fd);
- return;
- }
-
- if(cli>=xc.remote_max_clients || cli>=MAXCLIENTS) {
- const char *msg = "Server busy.\r\n";
- ssize_t len = strlen(msg);
- // too many clients
- LOGMSG("Too many clients, connection refused");
- if(write(fd, msg, len) != len)
- LOGERR("Write failed.");
- CLOSESOCKET(fd);
- return;
- }
-
- if (fcntl (fd, F_SETFL, fcntl (fd, F_GETFL) | O_NONBLOCK) == -1) {
- LOGERR("Error setting control socket to nonblocking mode");
- CLOSESOCKET(fd);
- }
-
- CloseDataConnection(cli);
-
- m_OsdTimeouts[cli] = 0;
- m_CtrlBufPos[cli] = 0;
- m_CtrlBuf[cli][0] = 0;
- m_ConnType[cli] = ctDetecting;
- fd_control[cli].set_handle(fd);
- fd_control[cli].set_buffers(KILOBYTE(128), KILOBYTE(128));
- cXinelibDevice::Instance().ForcePrimaryDevice(true);
-}
-
-void cXinelibServer::Handle_Discovery_Broadcast(void)
-{
- if(!xc.remote_usebcast) {
- LOGDBG("BROADCASTS disabled in configuration");
- CLOSESOCKET(fd_discovery);
- return;
- }
-
- char buf[DISCOVERY_MSG_MAXSIZE] = {0};
- struct sockaddr_in from;
-
- if(udp_discovery_recv(fd_discovery, buf, 0, &from) > 0)
- if(udp_discovery_is_valid_search(buf)) {
-
- // Reply only if we can accept one more client
- int clients = 0;
- for(int c=0; c<MAXCLIENTS; c++)
- if(fd_control[c].open())
- clients++;
- if(clients >= xc.remote_max_clients) {
- LOGMSG("Not replying to discovery broadcast (too many clients)");
- return;
- }
-
- udp_discovery_broadcast(fd_discovery, m_Port, xc.remote_local_ip);
- }
-}
-
-void cXinelibServer::Action(void)
-{
- TRACEF("cXinelibServer::Action");
-
- int i, fds=0;
- pollfd pfd[MAXCLIENTS];
-
- /* higher priority */
- SetPriority(-1);
-
- sched_param temp;
- temp.sched_priority = 2;
-
- /* request real-time scheduling */
- if (!pthread_setschedparam(pthread_self(), SCHED_RR, &temp)) {
- LOGDBG("cXinelibServer priority set successful SCHED_RR %d [%d,%d]",
- temp.sched_priority,
- sched_get_priority_min(SCHED_RR),
- sched_get_priority_max(SCHED_RR));
- } else {
- LOGDBG("cXinelibServer: Can't set priority to SCHED_RR %d [%d,%d]",
- temp.sched_priority,
- sched_get_priority_min(SCHED_RR),
- sched_get_priority_max(SCHED_RR));
- }
- errno = 0;
-
- Lock();
- Listen(m_Port);
- m_bReady=true;
-
- if(fd_listen>=0)
- while (!GetStopSignal() && fds>=0) {
-
- fds = 0;
- if(fd_listen>=0) {
- pfd[fds].fd = fd_listen;
- pfd[fds++].events = POLLIN;
- }
- if(fd_discovery >= 0) {
- pfd[fds].fd = fd_discovery;
- pfd[fds++].events = POLLIN;
- }
-
- for(i=0; i<MAXCLIENTS; i++) {
- if(fd_control[i].open()) {
- pfd[fds].fd = fd_control[i].handle();
- pfd[fds++].events = POLLIN;
- }
- if(fd_data[i]>=0) {
- pfd[fds].fd = fd_data[i];
- pfd[fds++].events = 0; /* check for errors only */
- }
- }
- Unlock();
-
- int err = poll(pfd,fds,1000);
-
- if(err < 0) {
- LOGERR("cXinelibServer: poll failed");
- if(!GetStopSignal())
- cCondWait::SleepMs(100);
-
- } else if(err == 0) {
- // poll timeout
-
- } else {
- Lock();
- for(int f=0; f<fds; f++) {
-
- // Check errors (closed connections etc.)
- if(pfd[f].revents & (POLLERR|POLLHUP|POLLNVAL)) {
-
- if(pfd[f].fd == fd_listen) {
- LOGERR("cXinelibServer: listen socket error");
- CLOSESOCKET(fd_listen);
- cCondWait::SleepMs(100);
- Listen(m_Port);
- } /* fd_listen */
-
- else if(pfd[f].fd == fd_discovery) {
- LOGERR("cXinelibServer: discovery socket error");
- CLOSESOCKET(fd_discovery);
- } /* fd_discovery */
-
- else /* fd_data[] / fd_control[] */ {
- for(i=0; i<MAXCLIENTS; i++) {
- if(pfd[f].fd == fd_data[i] || pfd[f].fd == fd_control[i].handle()) {
- LOGMSG("Client %d disconnected", i);
- CloseConnection(i);
- }
- }
- } /* fd_data / fd_control */
-
- } /* Check ERRORS */
-
- // Check ready for reading
- else if(pfd[f].revents & POLLIN) {
-
- // New connection
- if(pfd[f].fd == fd_listen) {
- int fd = accept(fd_listen, 0, 0);
- if(fd>=0)
- Handle_ClientConnected(fd);
- } /* fd_listen */
-
- // VDR Discovery
- else if(pfd[f].fd == fd_discovery) {
- Handle_Discovery_Broadcast();
- } /* fd_discovery */
-
- // Control data
- else {
- for(i=0; i<MAXCLIENTS; i++) {
- if(pfd[f].fd == fd_control[i].handle()) {
- Read_Control(i);
- break;
- }
- }
- } /* fd_control */
-
- } /* Check ready for reading */
-
- } /* for(fds) */
-
- Unlock();
- } /* Check poll result */
-
- Lock();
- } /* while running */
-
- m_bReady = false;
- m_bIsFinished = true;
- Unlock();
-}
diff --git a/frontend_svr.h b/frontend_svr.h
deleted file mode 100644
index 73117944..00000000
--- a/frontend_svr.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * frontend_svr.h: server for remote frontends
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: frontend_svr.h,v 1.23 2009-03-20 07:20:53 phintuka Exp $
- *
- */
-
-#ifndef __XINELIB_FRONTEND_SVR_H
-#define __XINELIB_FRONTEND_SVR_H
-
-
-#include "config.h"
-#include "frontend.h"
-
-//----------------------------- cXinelibServer --------------------------------
-
-#define CTRL_BUF_SIZE 1024
-
-class cBackgroundWriterI;
-class cUdpScheduler;
-class cStcFuture;
-class cCmdFutures;
-class cConnState;
-
-#include "tools/cxsocket.h"
-
-class cXinelibServer : public cXinelibThread
-{
-
- public:
- cXinelibServer(int listen_port);
- virtual ~cXinelibServer();
-
- // Thread control
- virtual void Stop(void);
-
- protected:
- virtual void Action(void);
-
- public:
- // Playback control
- virtual void TrickSpeed(int Speed);
-
- // Data transfer
- virtual int Poll(cPoller &Poller, int TimeoutMs);
- virtual bool Flush(int TimeoutMs);
- virtual void Clear(void);
- virtual int Play_PES(const uchar *buf, int len);
- virtual void OsdCmd(void *cmd);
- virtual int64_t GetSTC();
- virtual void SetHDMode(bool On);
-
- // Image grabbing
- virtual uchar *GrabImage(int &Size, bool Jpeg, int Quality,
- int SizeX, int SizeY);
- // Playback files
- virtual int PlayFileCtrl(const char *Cmd, int TimeoutMs=-1);
- virtual bool EndOfStreamReached(void);
-
- // Configuration
- virtual bool Listen(int port);
-
-protected:
- // Playback control
- virtual int Xine_Control(const char *cmd);
- virtual int Xine_Control_Sync(const char *cmd);
-
-protected:
-
- // Handling of messages from client(s)
-
- void Handle_Discovery_Broadcast(void);
- void Handle_ClientConnected(int fd);
-
- void Read_Control(int cli);
- void Handle_Control(int cli, const char *cmd);
-
- void Handle_Control_PIPE (int cli, const char *arg);
- void Handle_Control_RTP (int cli, const char *arg);
- void Handle_Control_UDP (int cli, const char *arg);
- void Handle_Control_DATA (int cli, const char *arg);
- void Handle_Control_KEY (int cli, const char *arg);
- void Handle_Control_UDP_RESEND(int cli, const char *arg);
- void Handle_Control_CONFIG (int cli);
- void Handle_Control_GRAB (int cli, const char *arg);
- void Handle_Control_CONTROL (int cli, const char *arg);
- void Handle_Control_HTTP (int cli, const char *arg);
- void Handle_Control_RTSP (int cli, const char *arg);
-
- void CloseDataConnection(int cli);
- void CloseConnection (int cli);
-
-protected:
-
- // Data
-
- int m_Port;
- int m_ServerId;
-
- int fd_listen;
- int fd_discovery;
-
- cxSocket fd_control[MAXCLIENTS];
- int fd_data [MAXCLIENTS];
-
- int m_OsdTimeouts[MAXCLIENTS];
- char m_CtrlBuf [MAXCLIENTS][CTRL_BUF_SIZE + 1];
- int m_CtrlBufPos [MAXCLIENTS];
-
- int m_ConnType [MAXCLIENTS]; // Control connection type. See frontend_svr.c.
- bool m_bUdp [MAXCLIENTS]; // Client uses UDP transport
- bool m_bMulticast [MAXCLIENTS]; // Client uses multicast RTP
- bool m_bConfigOk [MAXCLIENTS]; // Client has been configured
- int m_iMulticastMask; // bit [cli] is 1 or 0. 1 == multicast in use.
- int m_MasterCli; // Master client (controls playback speed)
-
- cString m_PipesDir;
-
- cBackgroundWriterI *m_Writer[MAXCLIENTS]; // buffered output (pipe/tcp/http)
- cConnState *m_State[MAXCLIENTS]; // connection state (http/rtsp)
- cUdpScheduler *m_Scheduler;
- bool m_Master;
-
- // Storage for return values of pending RPCs
- cStcFuture *m_StcFuture;
- cCmdFutures *m_Futures;
-
- int m_Token;
- int AllocToken(void);
- bool HasClients(void);
-
- // Cache current PAT/PMT for new clients
- uchar *m_Header;
- size_t m_HeaderLength; // bytes used
- size_t m_HeaderSize; // bytes allocated
- public:
- void SetHeader(const uchar *Data, int Length, bool Reset = false);
-};
-
-#endif // __XINELIB_FRONTEND_SVR_H
diff --git a/logdefs.c b/logdefs.c
deleted file mode 100644
index 063e1924..00000000
--- a/logdefs.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * logdefs.c: Logging and debug output
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: logdefs.c,v 1.2 2008-11-04 12:29:36 phintuka Exp $
- *
- */
-
-#include "logdefs.h"
-
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <stdarg.h>
-
-#ifndef __APPLE__
-# include <linux/unistd.h> /* syscall(__NR_gettid) */
-#endif
-
-/* next symbol is dynamically linked from input plugin */
-int LogToSysLog __attribute__((visibility("default"))) = 1; /* log to syslog instead of console */
-
-void x_syslog(int level, const char *module, const char *fmt, ...)
-{
- va_list argp;
- char buf[512];
-
- va_start(argp, fmt);
- vsnprintf(buf, 512, fmt, argp);
- buf[sizeof(buf)-1] = 0;
-
-#ifndef __APPLE__
- if(!LogToSysLog) {
- fprintf(stderr,"[%ld] %s%s\n", (long int)syscall(__NR_gettid), module, buf);
- } else {
- syslog(level, "[%ld] %s%s", (long int)syscall(__NR_gettid), module, buf);
- }
-#else
- if(!LogToSysLog) {
- fprintf(stderr, "%s%s\n", module, buf);
- } else {
- syslog(level, "%s%s", module, buf);
- }
-#endif
-
- va_end(argp);
-}
-
diff --git a/logdefs.h b/logdefs.h
deleted file mode 100644
index f9076439..00000000
--- a/logdefs.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * logdefs.h: Logging and debug output
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: logdefs.h,v 1.13 2008-11-20 11:46:31 rofafor Exp $
- *
- */
-
-#ifndef _LOGDEFS_H_
-#define _LOGDEFS_H_
-
-/*
- * Default module name (goes to every log line)
- */
-
-#ifndef LOG_MODULENAME
-# define LOG_MODULENAME "[xine..put] "
-#endif
-
-/*
- * Logging functions, should not be used directly
- */
-
-#include <syslog.h> /* logging levels: LOG_ERR, LOG_INFO, LOG_DEBUG */
-
-#define SYSLOGLEVEL_NONE 0
-#define SYSLOGLEVEL_ERRORS 1
-#define SYSLOGLEVEL_INFO 2
-#define SYSLOGLEVEL_DEBUG 3
-#define SYSLOGLEVEL_VERBOSE 4
-
-#if defined(esyslog)
-# define x_syslog(l,m,x...) syslog_with_tid(l, m x)
-#else
-
-# ifdef __cplusplus
- extern "C" {
-# endif
-
- /* from xine_frontend.c or vdr/tools.c: */
- extern int SysLogLevel; /* errors, info, debug */
-
- /* from logdefs.c: */
- extern int LogToSysLog;
-
- void x_syslog(int level, const char *module, const char *fmt, ...)
- __attribute__((format (printf, 3, 4)))
- __attribute__((visibility("default")));
-
-# ifdef __cplusplus
- } /* extern "C" { */
-# endif
-
-#endif /* VDR */
-
-#ifdef NEED_x_syslog
-# error NEED_x_syslog is deprecated
-#endif
-
-
-/*
- * Macros used for logging
- */
-
-#include <errno.h>
-
-#define LOG_ERRNO x_syslog(LOG_ERR, LOG_MODULENAME, " (ERROR (%s,%d): %s)", \
- __FILE__, __LINE__, strerror(errno))
-
-#define LOGERR(x...) do { \
- if(SysLogLevel > 0) { \
- x_syslog(LOG_ERR, LOG_MODULENAME, x); \
- if(errno) \
- LOG_ERRNO; \
- } \
- } while(0)
-#define LOGMSG(x...) do{ if(SysLogLevel > 1) x_syslog(LOG_INFO, LOG_MODULENAME, x); } while(0)
-#define LOGDBG(x...) do{ if(SysLogLevel > 2) x_syslog(LOG_DEBUG, LOG_MODULENAME, x); } while(0)
-
-#define TRACELINE LOGDBG("at %s:%d %s", __FILE__, __LINE__, __FUNCTION__)
-
-
-
-/*
- * ASSERT
- */
-
-#ifdef NDEBUG
-# define ASSERT(expr)
-#else
-# define ASSERT(expr,fatal) \
- do { \
- if(!(expr)) { \
- LOGERR("Asseretion failed: %s at %s:%d (%s)", \
- #expr, __FILE__, __LINE__, __FUNCTION__); \
- if(fatal) \
- abort(); \
- } \
- } while(0)
-#endif
-
-
-/*
- * Plugin (call)trace
- */
-
-#ifdef XINELIBOUTPUT_DEBUG
-# ifdef __cplusplus
-#
-# include <fstream>
-# include <iostream>
-# include <stdio.h>
-#
-# ifndef TRACE_IDENT
-# define TRACE_IDENT ""
-# endif
-# if defined(XINELIBOUTPUT_DEBUG_STDOUT)
-# define TRACE(x) do {std::cout << TRACE_IDENT << x << "\n"; fflush(stdout);}while(0)
-# elif defined(XINELIBOUTPUT_DEBUG_STDERR)
-# define TRACE(x) do {std::cerr << TRACE_IDENT << x << "\n"; fflush(stderr);}while(0)
-# else
-# error No trace target !
-# endif
-# define TRACEF(x) cTraceFunctionCall _x_cTraceFunctionCall(x);
- class cTraceFunctionCall {
- public:
- const char *m_name;
- cTraceFunctionCall(const char *name) : m_name(name)
- { TRACE(m_name << " - Enter"); }
- ~cTraceFunctionCall()
- { TRACE(m_name << " - Leave "); }
- };
-# endif
-#else
-# define TRACE(x)
-# define TRACEF(x)
-#endif
-
-
-/*
- * Execution time tracker:
- * log a message when function execution takes longer than expected
- */
-
-#ifdef __cplusplus
-# ifdef TRACK_EXEC_TIME
- class cTimeTracker
- {
- private:
- const char *m_Message;
- const char *m_Where;
- uint64_t m_Start;
- uint64_t m_Trigger;
- public:
- cTimeTracker(const char *Message, int TriggerMs, const char *Where) {
- m_Message = Message;
- m_Where = Where;
- m_Trigger = TriggerMs;
- m_Start = cTimeMs::Now();
- }
- ~cTimeTracker() {
- if(cTimeMs::Now() - m_Start > m_Trigger)
- LOGMSG("********** TimeTracker hit in %s: %d ms %s",
- m_Where, (int)(cTimeMs::Now() - m_Start),
- m_Message?m_Message:"");
- }
- };
-# define TRACK_TIME(limit) cTimeTracker _timetracker(NULL,limit,__PRETTY_FUNCTION__)
-# define TRACK_TIME_EXT(limit,msg) cTrimeTracker __timetracker(msg,limit,__PRETTY_FUNCTION__)
-# else
-# define TRACK_TIME(limit)
-# define TRACK_TIME_EXT(limit,msg)
-# endif
-# endif
-
-
-#endif /* _LOGDEFS_H_ */
diff --git a/media_player.c b/media_player.c
deleted file mode 100644
index f3901fca..00000000
--- a/media_player.c
+++ /dev/null
@@ -1,1346 +0,0 @@
-/*
- * media_player.c:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: media_player.c,v 1.68 2009-06-02 08:59:45 phintuka Exp $
- *
- */
-
-#include <unistd.h>
-
-#include <vdr/config.h>
-#include <vdr/status.h>
-#include <vdr/interface.h>
-#include <vdr/tools.h>
-
-#include "config.h"
-#include "media_player.h"
-#include "device.h"
-#include "tools/playlist.h"
-#include "tools/metainfo_menu.h"
-#include "menu.h"
-
-#include "logdefs.h"
-
-static void BackToMenu(void)
-{
- cRemote::CallPlugin("xineliboutput");
-}
-
-
-//
-// cXinelibPlayer
-//
-
-class cXinelibPlayer : public cPlayer
-{
- private:
- cString m_File;
- cString m_ResumeFile;
- cString m_SubFile;
-
- cPlaylist m_Playlist;
-
- bool m_Error;
- bool m_UseResumeFile;
- int m_Speed;
-
- void UpdateNumTracks(void);
-
- protected:
- virtual void Activate(bool On);
-
- public:
- cXinelibPlayer(const char *File, bool Queue = false, const char *SubFile = NULL);
- virtual ~cXinelibPlayer();
-
- // cPlayer
- virtual void SetAudioTrack(eTrackType Type, const tTrackId *TrackId);
- virtual void SetSubtitleTrack(eTrackType Type, const tTrackId *TrackId);
- virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false);
- virtual bool GetReplayMode(bool &Play, bool &Forward, int &Speed);
-
- // cXinelibPlayer
- void Control(const char *s) { (void)cXinelibDevice::Instance().PlayFileCtrl(s); }
- void Control(const char *s, int i) {
- cString cmd = cString::sprintf(s, i);
- Control(cmd);
- }
- void SetSpeed(int Speed);
- int Speed(void) { return m_Speed; };
-
- bool NextFile(int step);
- bool Playing(void) { return !(m_Error || cXinelibDevice::Instance().EndOfStreamReached()); }
- bool Error(void) { return m_Error; }
- void UseResumeFile(bool Val) { m_UseResumeFile = Val; }
-
- /* Playlist access */
- cPlaylist& Playlist(void) { return m_Playlist; }
- const cString& File(void) { return m_File; }
- int CurrentFile(void) { return m_Playlist.Current()->Index(); }
- int Files(void) { return m_Playlist.Count(); }
-};
-
-cXinelibPlayer::cXinelibPlayer(const char *File, bool Queue, const char *SubFile)
-{
- m_ResumeFile = NULL;
- m_UseResumeFile = true;
- m_Error = false;
- m_Speed = 1;
-
- if(File) {
- size_t len = strlen(File);
- if(len && File[len-1] == '/') {
- // whole directory, create temporary playlist
- m_Playlist.Read(File, true);
- m_Playlist.Sort();
- } else if(xc.IsPlaylistFile(File)) {
- m_Playlist.Read(File);
- } else {
- // a single file but not a playlist file, create playlist with only one item
- m_Playlist.Read(File);
- }
-
- if(m_Playlist.Count() < 1)
- LOGMSG("cXinelibPlayer: nothing to play !");
-
- if(m_Playlist.Count() > 0)
- m_Playlist.StartScanner();
-
- m_File = m_Playlist.Current()->Filename;
- m_SubFile = SubFile;
- }
-}
-
-cXinelibPlayer::~cXinelibPlayer()
-{
- Activate(false);
- Detach();
-}
-
-void cXinelibPlayer::SetAudioTrack(eTrackType Type, const tTrackId *TrackId)
-{
- if(IS_DOLBY_TRACK(Type))
- Control("AUDIOSTREAM AC3 %d", (int)(Type - ttDolbyFirst));
- if(IS_AUDIO_TRACK(Type))
- Control("AUDIOSTREAM AC3 %d", (int)(Type - ttAudioFirst));
-}
-
-void cXinelibPlayer::SetSubtitleTrack(eTrackType Type, const tTrackId *TrackId)
-{
- cXinelibDevice::Instance().SetSubtitleTrackDevice(Type);
-}
-
-bool cXinelibPlayer::GetIndex(int &Current, int &Total, bool SnapToIFrame)
-{
- // Returns the current and total frame index, optionally snapped to the
- // nearest I-frame.
- int msCurrent = cXinelibDevice::Instance().PlayFileCtrl("GETPOS");
- int msTotal = cXinelibDevice::Instance().PlayFileCtrl("GETLENGTH");
- if(msCurrent>=0 && msTotal>=0) {
- Current = msCurrent * 25 / 1000;
- Total = msTotal * 25 / 1000;
- return true;
- }
- return false;
-}
-
-bool cXinelibPlayer::GetReplayMode(bool &Play, bool &Forward, int &Speed)
-{
- // Returns the current replay mode (if applicable).
- // 'Play' tells whether we are playing or pausing, 'Forward' tells whether
- // we are going forward or backward and 'Speed' is -1 if this is normal
- // play/pause mode, 0 if it is single speed fast/slow forward/back mode
- // and >0 if this is multi speed mode.
- Play = (m_Speed>0);
- Forward = true;
- Speed = abs(m_Speed) - 2;
- if(Speed<-1) Speed=-1;
-
- return true;
-}
-
-void cXinelibPlayer::SetSpeed(int Speed)
-{
- m_Speed = Speed;
- switch(Speed) {
- case -4: Control("TRICKSPEED 8"); break;
- case -3: Control("TRICKSPEED 4"); break;
- case -2: Control("TRICKSPEED 2"); break;
- case 0: Control("TRICKSPEED 0"); break;
- default: m_Speed = 1;
- case 1: Control("TRICKSPEED 1"); break;
- case 2: Control("TRICKSPEED -2"); break;
- case 3: Control("TRICKSPEED -4"); break;
- case 4: Control("TRICKSPEED -12"); break;
- }
-}
-
-bool cXinelibPlayer::NextFile(int step)
-{
- if(m_Playlist.Count()>0) {
- for(;step < 0; step++)
- m_Playlist.Prev();
- for(;step > 0; step--)
- m_Playlist.Next();
-
- if(!m_Playlist.Current())
- LOGERR("!m_Playlist.Get(m_CurrInd)");
- m_File = *m_Playlist.Current()->Filename;
- m_ResumeFile = NULL;
- m_SubFile = NULL;
-
- Activate(true);
- return !m_Error;
- }
-
- return false;
-}
-
-void cXinelibPlayer::UpdateNumTracks(void)
-{
- // cdda tracks
- if(m_Playlist.Count() == 1 && !strcmp("cdda:/", m_Playlist.First()->Filename)) {
- int count = cXinelibDevice::Instance().PlayFileCtrl("GETAUTOPLAYSIZE CD", 10000);
- if(count>0) {
- for(int i=0; i<count; i++)
- m_Playlist.Read(cString::sprintf("cdda:/%d", i+1));
- m_Playlist.Del(m_Playlist.First());
- }
- }
-}
-
-void cXinelibPlayer::Activate(bool On)
-{
- int pos = 0, len = 0, fd = -1;
- if(On) {
- if(m_UseResumeFile && !*m_ResumeFile)
- m_ResumeFile = cString::sprintf("%s.resume", *m_File);
- if(m_UseResumeFile && 0 <= (fd = open(m_ResumeFile, O_RDONLY))) {
- if(read(fd, &pos, sizeof(int)) != sizeof(int))
- pos = 0;
- close(fd);
- }
- // escape file name and join subtitle file
- // Maybe mrls from playlist files should not be escaped ?
- // (those may contain #subtitle, #volnorm etc. directives)
- cString mrl;
- if(*m_SubFile)
- mrl = cString::sprintf("%s%s#subtitle:%s%s",
- m_File[0] == '/' ? "file:" : "",
- *cPlaylist::EscapeMrl(m_File),
- m_SubFile[0] == '/' ? "file:" : "",
- *cPlaylist::EscapeMrl(m_SubFile));
- else if((*m_File)[0] == '/')
- mrl = cString::sprintf("%s%s",
- m_File[0] == '/' ? "file:" : "",
- *cPlaylist::EscapeMrl(m_File));
- else
- mrl = cPlaylist::EscapeMrl(m_File);
-
- // Start replay
- UpdateNumTracks();
- m_Error = !cXinelibDevice::Instance().PlayFile(mrl, pos);
- LOGDBG("cXinelibPlayer playing %s (%s)", *m_File, m_Error ? "FAIL" : "OK");
-
- if(!m_Error) {
- // update playlist metainfo
- const char *ti = cXinelibDevice::Instance().GetMetaInfo(miTitle);
- const char *tr = cXinelibDevice::Instance().GetMetaInfo(miTracknumber);
- const char *al = cXinelibDevice::Instance().GetMetaInfo(miAlbum);
- const char *ar = cXinelibDevice::Instance().GetMetaInfo(miArtist);
- if(ti && ti[0] && (!*m_Playlist.Current()->Title || !strstr(m_Playlist.Current()->Title, ti)))
- m_Playlist.Current()->Title = ti;
- if(tr && tr[0])
- m_Playlist.Current()->Tracknumber = tr;
- if(al && al[0])
- m_Playlist.Current()->Album = al;
- if(ar && ar[0])
- m_Playlist.Current()->Artist = ar;
-
- UpdateNumTracks();
- }
- } else {
- if(m_UseResumeFile && *m_ResumeFile) {
- pos = cXinelibDevice::Instance().PlayFileCtrl("GETPOS");
- len = cXinelibDevice::Instance().PlayFileCtrl("GETLENGTH");
- if(pos>10000 && pos < (len-10000)) {
- pos = (pos/1000) - 10; // skip back 10 seconds ("VDR style")
- if(0 <= (fd = open(m_ResumeFile, O_WRONLY | O_CREAT,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
- if(write(fd, &pos, sizeof(int)) != sizeof(int)) {
- Skins.QueueMessage(mtInfo, "Error writing resume position !", 5, 30);
- }
- close(fd);
- } else {
- Skins.QueueMessage(mtInfo, "Error creating resume file !", 5, 30);
- }
- } else {
- unlink(m_ResumeFile);
- }
- m_ResumeFile = NULL;
- }
- cXinelibDevice::Instance().PlayFile(NULL);
- m_Error = false;
- }
-}
-
-//
-// cPlaylistMenu
-//
-
-
-class cPlaylistMenu : public cOsdMenu, cPlaylistChangeNotify
-{
- protected:
-
- cPlaylist& m_Playlist;
- bool m_NeedsUpdate;
- bool& m_RandomPlay;
- cCharSetConv m_IC;
-
- public:
-
- cPlaylistMenu(cPlaylist &Playlist, bool& RandomPlay);
- virtual ~cPlaylistMenu();
-
- void Set(bool setCurrentPlaying = false);
- void SetCurrentExt(int i);
- void SetHelpButtons(void);
-
- // cOsdMenu
- virtual eOSState ProcessKey(eKeys Key);
-
- // cPlaylistChangeNotify
- virtual void PlaylistChanged(const cPlaylistItem *item);
-};
-
-cPlaylistMenu::cPlaylistMenu(cPlaylist &Playlist, bool& RandomPlay) :
- cOsdMenu(tr("Playlist")),
- m_Playlist(Playlist),
- m_RandomPlay(RandomPlay),
- m_IC("UTF-8", cCharSetConv::SystemCharacterTable())
-{
- SetTitle(cString::sprintf("%s: %s", tr("Playlist"), m_IC.Convert(*Playlist.Name())));
- Playlist.Listen(this);
- Set(true);
-}
-
-cPlaylistMenu::~cPlaylistMenu()
-{
- m_Playlist.Listen(NULL);
-}
-
-void cPlaylistMenu::PlaylistChanged(const cPlaylistItem *item)
-{
- m_NeedsUpdate = true;
-}
-
-eOSState cPlaylistMenu::ProcessKey(eKeys Key)
-{
- bool hadSubMenu = HasSubMenu();
-
- if(m_NeedsUpdate)
- Set();
-
- eOSState state = cOsdMenu::ProcessKey(Key);
-
- if(state == osUnknown) {
- switch(Key) {
- case kBack:
- return osEnd;
- case kRed:
- m_RandomPlay = !m_RandomPlay;
- SetHelpButtons();
- return osContinue;
- case kGreen:
- return AddSubMenu(cMenuXinelib::CreateMenuBrowseFiles(ShowMusic));
- case kYellow: if(m_Playlist.Count() > 1) {
- eOSState result = osContinue;
- cPlaylistItem *i = m_Playlist.Current();
- if(i->Index() == Current()) {
- if(i->Next())
- result = (eOSState)(os_User + i->Index()); /* forces jump to next item */
- else
- result = (eOSState)(os_User + i->Index() - 1);/* forces jump to last item */
- }
- for(i = m_Playlist.First(); i && i->Index() != Current(); i = m_Playlist.Next(i));
- if(i)
- m_Playlist.Del(i);
- if(Current() == Count()-1)
- SetCurrent(Get(Current()-1));
- Set();
- return result;
- }
- case kBlue:
- m_Playlist.Sort();
- Set();
- return osContinue;
- default: break;
- }
- }
-
- if(hadSubMenu && !HasSubMenu())
- Set();
-
- return state;
-}
-
-void cPlaylistMenu::SetCurrentExt(int i)
-{
- SetCurrent(Get(i));
- Set();
-}
-
-void cPlaylistMenu::SetHelpButtons(void)
-{
- SetHelp(!m_RandomPlay ? tr("Button$Random") : tr("Button$Normal"),
- tr("Button$Add files"),
- m_Playlist.Count()>1 ? tr("Button$Remove") : NULL,
- tr("Button$Sort"));
- Display();
-}
-
-void cPlaylistMenu::Set(bool setCurrentPlaying)
-{
- m_NeedsUpdate = false;
-
- int currentItem = Current();
- Clear();
- SetHasHotkeys();
- SetCols(2, 30);
- SetHelpButtons();
-
- int currentPlaying = m_Playlist.Current()->Index();
- int j = 0;
-
- for(cPlaylistItem *i = m_Playlist.First(); i; i = m_Playlist.Next(i), j++) {
- cString Title = cPlaylist::GetEntry(i, true, j==currentPlaying);
- Add(new cOsdItem(m_IC.Convert(*Title), (eOSState)(os_User + j)));
- }
-
- if(setCurrentPlaying)
- SetCurrent(Get(currentPlaying));
- else
- SetCurrent(Get(currentItem));
-
- Display();
-}
-
-
-//
-// cXinelibPlayerControl
-//
-
-#include <vdr/skins.h>
-
-cXinelibPlayer *cXinelibPlayerControl::m_Player = NULL;
-cMutex cXinelibPlayerControl::m_Lock;
-
-cXinelibPlayerControl::cXinelibPlayerControl(eMainMenuMode Mode, const char *File, const char *SubFile) :
- cControl(OpenPlayer(File, false, SubFile))
-{
- m_DisplayReplay = NULL;
- m_PlaylistMenu = NULL;
- m_ShowModeOnly = true;
- m_Mode = Mode;
- m_RandomPlay = false;
- m_AutoShowStart = time(NULL);
- m_BlinkState = true;
-
- number = 0;
- lastTime.Set();
-
- m_Player->UseResumeFile( (Mode==ShowFiles) );
-
- MsgReplaying(*m_Player->Playlist().Current()->Title, *m_Player->File());
-}
-
-cXinelibPlayerControl::~cXinelibPlayerControl()
-{
- if(m_PlaylistMenu) {
- delete m_PlaylistMenu;
- m_PlaylistMenu = NULL;
- }
- if(m_DisplayReplay) {
- delete m_DisplayReplay;
- m_DisplayReplay = NULL;
- }
-
- MsgReplaying(NULL, NULL);
- Close();
-}
-
-void cXinelibPlayerControl::MsgReplaying(const char *Title, const char *File)
-{
- cStatus::MsgReplaying(this, NULL, NULL, false);
- if(Title || File)
- cStatus::MsgReplaying(this, Title, File, true);
-}
-
-void cXinelibPlayerControl::Queue(const char *File)
-{
- if(!File)
- return;
-
- m_Lock.Lock();
-
- LOGMSG("cXinelibPlayerControl::Queue(%s)", File);
-
- if(!m_Player) {
- OpenPlayer(File, true);
- cControl::Launch(new cXinelibPlayerControl(ShowMusic, NULL));
- } else {
- size_t len = strlen(File);
- if(len && File[len-1] == '/')
- m_Player->Playlist().Read(File, true);
- else
- m_Player->Playlist().Read(File);
- }
-
- Skins.Message(mtInfo, tr("Queued to playlist"));
-
- m_Lock.Unlock();
-
- if(m_Player->Playlist().Count() > 0)
- m_Player->Playlist().StartScanner();
-
-}
-
-cXinelibPlayer *cXinelibPlayerControl::OpenPlayer(const char *File, bool Queue, const char *SubFile)
-{
- m_Lock.Lock();
- if(!m_Player)
- m_Player = new cXinelibPlayer(File, Queue, SubFile);
- m_Lock.Unlock();
- return m_Player;
-}
-
-void cXinelibPlayerControl::Close(void)
-{
- m_Lock.Lock();
- if(m_Player)
- delete m_Player;
- m_Player = NULL;
- m_Lock.Unlock();
-}
-
-void cXinelibPlayerControl::Show()
-{
- bool Play = (m_Player->Speed() > 0);
- bool Forward = true;
- int Speed = abs(m_Player->Speed()) - 2;
- if(Speed<-1) Speed=-1;
-
- if(!m_DisplayReplay) {
- if(cOsd::IsOpen())
- return;
- m_DisplayReplay = Skins.Current()->DisplayReplay(m_ShowModeOnly);
- }
-
- if(!m_ShowModeOnly) {
- char t[128] = "";
- int Current = cXinelibDevice::Instance().PlayFileCtrl("GETPOS");
- int Total = cXinelibDevice::Instance().PlayFileCtrl("GETLENGTH");
- if(Current>=0) m_CurrentPos = Current;
- if(Total>=0) m_CurrentLen = Total;
-
- if(m_CurrentLen >= 0 /*&& Total >= 0*/) {
- Total = (m_CurrentLen + 500) / 1000; // ms --> s
- Current = (m_CurrentPos + 500) / 1000;
-
- cString Title = cPlaylist::GetEntry(m_Player->Playlist().Current());
- cCharSetConv ic("UTF-8", cCharSetConv::SystemCharacterTable());
- m_DisplayReplay->SetTitle(ic.Convert(*Title));
-
- m_DisplayReplay->SetProgress(Current, Total);
- sprintf(t, "%d:%02d:%02d", Total/3600, (Total%3600)/60, Total%60);
- m_DisplayReplay->SetTotal( t );
- sprintf(t, "%d:%02d:%02d", Current/3600, (Current%3600)/60, Current%60);
- m_BlinkState = (m_Player->Speed() != 0) || (!m_BlinkState);
- m_DisplayReplay->SetCurrent( m_BlinkState ? t : "");
- }
- }
-
- m_DisplayReplay->SetMode(Play, Forward, Speed);
-
- m_DisplayReplay->Flush();
-}
-
-void cXinelibPlayerControl::Hide()
-{
- if(m_PlaylistMenu) {
- delete m_PlaylistMenu;
- m_PlaylistMenu = NULL;
- }
- if(m_DisplayReplay) {
- delete m_DisplayReplay;
- m_DisplayReplay = NULL;
- }
-}
-
-cOsdObject *cXinelibPlayerControl::GetInfo(void)
-{
- return new cMetainfoMenu(m_Player->Playlist().Current()->Filename);
-}
-
-eOSState cXinelibPlayerControl::ProcessKey(eKeys Key)
-{
- if ( !m_Player->Playing() ) {
- LOGDBG("cXinelibPlayerControl: EndOfStreamReached");
- if (m_Mode == ShowMusic && m_Player->Files() == 1 && !m_Player->Error()) {
- m_Player->NextFile(0);
- return osContinue;
- }
- int Jump = 1;
- if(m_RandomPlay) {
- srand((unsigned int)time(NULL));
- Jump = (random() % m_Player->Files()) - m_Player->CurrentFile();
- }
- if(m_Player->Files() < 2 || !m_Player->NextFile(Jump)) {
- Hide();
- return osEnd;
- }
- if(m_PlaylistMenu) {
- m_PlaylistMenu->PlaylistChanged(m_Player->Playlist().Current());
- m_PlaylistMenu->SetCurrentExt(m_Player->CurrentFile());
- }
-
- if(!m_DisplayReplay)
- m_AutoShowStart = time(NULL);
-
- MsgReplaying(*m_Player->Playlist().Current()->Title, *m_Player->File());
- }
-
- else {
- // metainfo may change during playback (DVD titles, CDDA tracks)
- const char *ti = cXinelibDevice::Instance().GetMetaInfo(miTitle);
- if(ti && ti[0] && (!*m_Player->Playlist().Current()->Title ||
- !strstr(m_Player->Playlist().Current()->Title, ti))) {
- const char *tr = cXinelibDevice::Instance().GetMetaInfo(miTracknumber);
- const char *al = cXinelibDevice::Instance().GetMetaInfo(miAlbum);
- const char *ar = cXinelibDevice::Instance().GetMetaInfo(miArtist);
- LOGDBG("metainfo changed: %s->%s %s->%s %s->%s %s->%s",
- *m_Player->Playlist().Current()->Artist?:"-", ar?:"-",
- *m_Player->Playlist().Current()->Album ?:"-", al?:"-",
- *m_Player->Playlist().Current()->Tracknumber ?:"-", tr?:"-",
- *m_Player->Playlist().Current()->Title ?:"-", ti?:"-");
- m_Player->Playlist().Current()->Title = ti;
- if(tr && tr[0])
- m_Player->Playlist().Current()->Tracknumber = tr;
- if(al && al[0])
- m_Player->Playlist().Current()->Album = al;
- if(ar && ar[0])
- m_Player->Playlist().Current()->Artist = ar;
- MsgReplaying(*m_Player->Playlist().Current()->Title, *m_Player->File());
- }
- }
-
- if(m_PlaylistMenu) {
- m_AutoShowStart = 0;
-
- eOSState state = osUnknown;
-
- switch(state=m_PlaylistMenu->ProcessKey(Key)) {
- case osBack:
- case osEnd: Hide(); break;
- default: if(state >= os_User) {
- m_Player->NextFile( (int)state - (int)os_User - m_Player->CurrentFile());
- m_PlaylistMenu->SetCurrentExt(m_Player->CurrentFile());
- MsgReplaying(*m_Player->Playlist().Current()->Title, *m_Player->File());
- }
- break;
- }
-
- if(state != osUnknown)
- return osContinue;
- }
-
- if (m_DisplayReplay)
- Show();
-
- if ( m_Mode == ShowFiles ) {
- switch(Key) {
- case kRed: if(m_Player->Playlist().Count() > 1) {
- Hide();
- m_PlaylistMenu = new cPlaylistMenu(m_Player->Playlist(), m_RandomPlay);
- m_AutoShowStart = 0;
- } else {
- m_Player->Control("SEEK 0"); break;
- }
- break;
- case kUser8:
- case k1: m_Player->Control("SEEK -20"); break;
- case kUser9:
- case k3: m_Player->Control("SEEK +20"); break;
- case k2: xc.subtitle_vpos -= 10;
- case k5: xc.subtitle_vpos += 5;
- m_Player->Control("SUBTITLES %d", xc.subtitle_vpos);
- break;
- case kRight:
- {
- static const int speeds[] = { -3, -2, 1, 2, -4, 2, 3, 4, 4 };
- m_Player->SetSpeed(speeds[m_Player->Speed() + 4]);
- if(m_Player->Speed() != 1)
- Show();
- else
- Hide();
- break;
- }
- case kLeft:
- {
- static const int speeds[] = { 0, -4, -3, -2, 0, -2, 1, 2, 3 };
- m_Player->SetSpeed(speeds[m_Player->Speed() + 4]);
- if(m_Player->Speed() != 1 || !m_ShowModeOnly)
- Show();
- else
- Hide();
- break;
- }
- default: break;
- }
- }
- if ( m_Mode == ShowMusic ) {
- switch(Key) {
- case kRed: Hide();
- m_PlaylistMenu = new cPlaylistMenu(m_Player->Playlist(), m_RandomPlay);
- m_AutoShowStart = 0;
- break;
- case kNext:
- case kRight: if(m_RandomPlay) {
- srand((unsigned int)time(NULL));
- m_Player->NextFile((random() % m_Player->Files()) - m_Player->CurrentFile());
- }
- else {
- m_Player->NextFile(1);
- }
- if(!m_DisplayReplay)
- m_AutoShowStart = time(NULL);
- MsgReplaying(*m_Player->Playlist().Current()->Title, *m_Player->File());
- break;
- case kPrev:
- case kLeft: if(cXinelibDevice::Instance().PlayFileCtrl("GETPOS") < 3000) {
- m_Player->NextFile(-1);
- if(!m_DisplayReplay)
- m_AutoShowStart = time(NULL);
- MsgReplaying(*m_Player->Playlist().Current()->Title, *m_Player->File());
- }
- else {
- m_Player->NextFile(0);
- if(!m_DisplayReplay)
- m_AutoShowStart = time(NULL);
- }
- break;
- case k0 ... k9:
- if (number >= 0) {
- if (number * 10 + Key - k0 > m_Player->Files())
- number = m_Player->Files();
- else
- number = number * 10 + Key - k0;
- }
- break;
- case kNone:
- if (number > 0 && int(lastTime.Elapsed()) > 3000) {
- m_Player->NextFile( number - (m_Player->CurrentFile() + 1) );
- if (!m_DisplayReplay)
- m_AutoShowStart = time(NULL);
- MsgReplaying(*m_Player->Playlist().Current()->Title, *m_Player->File());
- number = 0;
- lastTime.Set();
- }
- break;
- default: break;
- }
- }
- switch(Key) { // key bindings common for both players
- case kBack: xc.main_menu_mode = m_Mode;
- Hide();
- BackToMenu();
- break;
- case kStop:
- case kBlue: Hide();
- Close();
- return osEnd;
- case kUser7: if(m_Player->Playlist().Count()>1) {
- m_RandomPlay = !m_RandomPlay;
- if(m_RandomPlay)
- Skins.Message(mtInfo, tr("Random play"));
- else
- Skins.Message(mtInfo, tr("Normal play"));
- }
- break;
- case kGreen: m_Player->Control("SEEK -60"); break;
- case kYellow: m_Player->Control("SEEK +60"); break;
- case kUser8: m_Player->Control("SEEK -20"); break;
- case kUser9: m_Player->Control("SEEK +20"); break;
- case kDown:
- case kPause: if(m_Player->Speed()) {
- m_Player->SetSpeed(0);
- if(!m_DisplayReplay)
- m_ShowModeOnly = true;
- Show();
- break;
- }
- // fall thru
- case kUp:
- case kPlay: m_Player->SetSpeed(1);
- if(m_ShowModeOnly && m_DisplayReplay)
- Hide();
- else if(m_DisplayReplay)
- Show();
- m_ShowModeOnly = false;
- break;
- case kFastFwd:
- {
- static const int speeds[] = { -3, -2, 1, 2, -4, 2, 3, 4, 4 };
- m_Player->SetSpeed(speeds[m_Player->Speed() + 4]);
- if(m_Player->Speed() != 1)
- Show();
- else
- Hide();
- break;
- }
- case kFastRew:
- {
- static const int speeds[] = { 0, -4, -3, -2, 0, -2, 1, 2, 3 };
- m_Player->SetSpeed(speeds[m_Player->Speed() + 4]);
- if(m_Player->Speed() != 1 || !m_ShowModeOnly)
- Show();
- else
- Hide();
- break;
- }
- case kOk:
- m_AutoShowStart = 0;
- if(m_Player->Speed() != 1) {
- Hide();
- m_ShowModeOnly = !m_ShowModeOnly;
- Show();
- } else {
- if(m_DisplayReplay) {
- m_ShowModeOnly = true;
- Hide();
- } else {
- Hide();
- m_ShowModeOnly = false;
- Show();
- }
- }
- break;
- default: break;
- }
-
- if(m_DisplayReplay &&
- m_AutoShowStart &&
- time(NULL) - m_AutoShowStart > 5) {
- m_AutoShowStart = 0;
- Hide();
- }
-
- if(!m_DisplayReplay &&
- m_AutoShowStart) {
- m_ShowModeOnly = false;
- Show();
- }
-
- return osContinue;
-}
-
-//
-// cDvdMenu
-//
-
-class cDvdMenu : public cOsdMenu {
- public:
- cDvdMenu(void) : cOsdMenu("DVD Menu")
- {
- Add(new cOsdItem("Exit DVD menu", osUser1));
- Add(new cOsdItem("DVD Root menu", osUser2));
- Add(new cOsdItem("DVD Title menu", osUser3));
- Add(new cOsdItem("DVD SPU menu", osUser4));
- Add(new cOsdItem("DVD Audio menu", osUser5));
- Add(new cOsdItem("Close menu", osEnd));
- Display();
- }
-};
-
-
-//
-// cXinelibDvdPlayerControl
-//
-
-cXinelibDvdPlayerControl::~cXinelibDvdPlayerControl()
-{
- if(Menu) {
- delete Menu;
- Menu = NULL;
- }
-}
-
-void cXinelibDvdPlayerControl::Hide(void)
-{
- if(Menu) {
- delete Menu;
- Menu = NULL;
- }
- cXinelibPlayerControl::Hide();
-}
-
-void cXinelibDvdPlayerControl::Show(void)
-{
- if(!Menu)
- cXinelibPlayerControl::Show();
- else
- cXinelibPlayerControl::Hide();
-}
-
-eOSState cXinelibDvdPlayerControl::ProcessKey(eKeys Key)
-{
- // Check for end of stream and failed open
- if ( !m_Player->Playing() ) {
- LOGDBG("cXinelibDvdPlayerControl: EndOfStreamReached");
- Hide();
- return osEnd;
- }
-
- // Update DVD title information
- const char *ti = cXinelibDevice::Instance().GetMetaInfo(miTitle);
- if (ti && ti[0] && (!m_CurrentDVDTitle || !strstr(m_CurrentDVDTitle, ti))) {
- memset(m_CurrentDVDTitle, 0, 63);
- strn0cpy(m_CurrentDVDTitle, ti, 63);
- m_Player->Playlist().Current()->Title = m_CurrentDVDTitle;
- MsgReplaying(m_CurrentDVDTitle, NULL);
- }
-
- // Handle menu selection
- if(Menu) {
- if(Key == kRed)
- Hide();
- else switch(Menu->ProcessKey(Key)) {
- case osUser1: Hide(); m_Player->Control("EVENT XINE_EVENT_INPUT_MENU1"); break;
- case osUser2: Hide(); m_Player->Control("EVENT XINE_EVENT_INPUT_MENU2"); break;
- case osUser3: Hide(); m_Player->Control("EVENT XINE_EVENT_INPUT_MENU3"); break;
- case osUser4: Hide(); m_Player->Control("EVENT XINE_EVENT_INPUT_MENU4"); break;
- case osUser5: Hide(); m_Player->Control("EVENT XINE_EVENT_INPUT_MENU5"); break;
- case osBack:
- case osEnd: Hide(); break;
- default: break;
- }
- return osContinue;
- }
-
- // Update progress bar display
- if (m_DisplayReplay)
- Show();
-
- // Handle menu navigation
-
- bool MenuDomain = !xc.dvd_arrow_keys_control_playback;
- if(Key != kNone || m_DisplayReplay) {
- const char *dt = cXinelibDevice::Instance().GetMetaInfo(miDvdTitleNo);
- if(dt && !strcmp("0", dt))
- MenuDomain = true;
- else {
- dt = cXinelibDevice::Instance().GetMetaInfo(miDvdButtons);
- if(dt && *dt && *dt != '0')
- MenuDomain = true;
- }
- }
-
- if(MenuDomain) {
- if(m_DisplayReplay)
- Hide();
-
- switch(Key) {
- // DVD navigation
- case kUp: m_Player->Control("EVENT XINE_EVENT_INPUT_UP"); return osContinue;
- case kDown: m_Player->Control("EVENT XINE_EVENT_INPUT_DOWN"); return osContinue;
- case kLeft: m_Player->Control("EVENT XINE_EVENT_INPUT_LEFT"); return osContinue;
- case kRight: m_Player->Control("EVENT XINE_EVENT_INPUT_RIGHT"); return osContinue;
- case kOk: m_Player->Control("EVENT XINE_EVENT_INPUT_SELECT"); return osContinue;
- case kBack: m_Player->Control("EVENT XINE_EVENT_INPUT_MENU1"); return osContinue;
- default: break;
- }
- }
-
- // Handle normal keys
-
- if(!MenuDomain) {
- switch(Key) {
- // Replay control
- case kUp: Key = kPlay; break;
- case kDown: Key = kPause; break;
- case kLeft: Key = kFastRew; break;
- case kRight: Key = kFastFwd; break;
- case kOk:
- if(m_Player->Speed() != 1) {
- Hide();
- m_ShowModeOnly = !m_ShowModeOnly;
- Show();
- break;
- }
- if(m_DisplayReplay) {
- Hide();
- m_ShowModeOnly = true;
- } else {
- Hide();
- m_ShowModeOnly = false;
- Show();
- }
- break;
- case kInfo: Hide();
- if(m_DisplayReplay && !m_ShowModeOnly) {
- m_ShowModeOnly = true;
- } else {
- m_ShowModeOnly = false;
- Show();
- }
- break;
- case kBack: xc.main_menu_mode = m_Mode;
- Hide();
- Close();
- return osEnd;
- default: break;
- }
- }
-
- switch(Key) {
- // DVD menus
- case kRed: Hide();
- Menu = new cDvdMenu();
- break;
- // Playback control
- case kGreen: m_Player->Control("SEEK -60"); break;
- case kYellow: m_Player->Control("SEEK +60"); break;
- case kUser8:
- case k1: m_Player->Control("SEEK -20"); break;
- case kUser9:
- case k3: m_Player->Control("SEEK +20"); break;
-
- case kStop:
- case kBlue: Hide();
- Close();
- return osEnd;
-
- case k9: m_Player->Control("EVENT XINE_EVENT_INPUT_NEXT TITLE"); break;
- case k7: m_Player->Control("EVENT XINE_EVENT_INPUT_PREVIOUS TITLE"); break;
- case k6:
- case kNext: m_Player->Control("EVENT XINE_EVENT_INPUT_NEXT CHAPTER"); break;
- case k4:
- case kPrev: m_Player->Control("EVENT XINE_EVENT_INPUT_PREVIOUS CHAPTER"); break;
-
- case kFastFwd:
- {
- static const int speeds[] = { -3, -2, 1, 2, -4, 2, 3, 4, 4 };
- m_Player->SetSpeed(speeds[m_Player->Speed() + 4]);
- if(m_Player->Speed() != 1)
- Show();
- else
- Hide();
- break;
- }
- case kFastRew:
- {
- static const int speeds[] = { 0, -4, -3, -2, 0, -2, 1, 2, 3 };
- m_Player->SetSpeed(speeds[m_Player->Speed() + 4]);
- if(m_Player->Speed() != 1 || !m_ShowModeOnly)
- Show();
- else
- Hide();
- break;
- }
- case kInfo: if(m_DisplayReplay) {
- Hide();
- } else {
- m_ShowModeOnly = false;
- Show();
- }
- break;
- case kPause: if(m_Player->Speed()) {
- m_Player->SetSpeed(0);
- m_ShowModeOnly = false;
- Show();
- break;
- }
- // fall thru
- case kPlay: m_Player->SetSpeed(1);
- m_ShowModeOnly = true;
- Hide();
- break;
- default: break;
- }
-
- return osContinue;
-}
-
-//
-// cXinelibImagePlayer
-//
-
-class cXinelibImagePlayer : public cPlayer {
- private:
- cString m_Mrl;
- bool m_Active;
- bool m_Error;
- cXinelibDevice *m_Dev;
-
- bool Play(void);
-
- protected:
- virtual void Activate(bool On);
-
- public:
- cXinelibImagePlayer(const char *File);
- virtual ~cXinelibImagePlayer();
-
- bool ShowImage(const char *File);
- bool Error(void) { return m_Error; }
-};
-
-cXinelibImagePlayer::cXinelibImagePlayer(const char *File)
-{
- m_Mrl = File;
- m_Active = false;
- m_Error = false;
- m_Dev = &(cXinelibDevice::Instance());
-}
-
-cXinelibImagePlayer::~cXinelibImagePlayer()
-{
- Activate(false);
- Detach();
-}
-
-bool cXinelibImagePlayer::Play(void)
-{
- if ((*m_Mrl)[0] == '/')
- m_Mrl = cString::sprintf("file:%s", *cPlaylist::EscapeMrl(m_Mrl));
-
- return m_Dev->PlayFile(m_Mrl, 0, true);
-}
-
-void cXinelibImagePlayer::Activate(bool On)
-{
- m_Active = On;
- m_Error = false;
- if (On)
- Play();
- else
- m_Dev->PlayFile(NULL);
-}
-
-bool cXinelibImagePlayer::ShowImage(const char *File)
-{
- m_Mrl = File;
- if (m_Active)
- return Play();
- return true;
-}
-
-
-//
-// cXinelibImagesControl
-//
-
-cXinelibImagePlayer *cXinelibImagesControl::m_Player = NULL;
-cMutex cXinelibImagesControl::m_Lock;
-
-cXinelibImagesControl::cXinelibImagesControl(char **Files, int Index, int Count) :
- cControl(OpenPlayer(Files[Index]))
-{
- m_DisplayReplay = NULL;
- m_Files = Files;
- m_File = NULL;
- m_Index = Index;
- m_Count = Count;
- m_Speed = 0;
- m_ShowModeOnly = false;
-
- Seek(0);
-}
-
-cXinelibImagesControl::~cXinelibImagesControl()
-{
- if(m_DisplayReplay)
- delete m_DisplayReplay;
- m_DisplayReplay = NULL;
-
- cStatus::MsgReplaying(this, NULL, NULL, false);
- Close();
-
- if(m_Files) {
- int i=0;
- while(m_Files[i]) {
- free(m_Files[i]);
- m_Files[i] = NULL;
- i++;
- }
- delete [] m_Files;
- m_Files = NULL;
- }
-}
-
-cXinelibImagePlayer *cXinelibImagesControl::OpenPlayer(const char *File)
-{
- m_Lock.Lock();
- if(!m_Player)
- m_Player = new cXinelibImagePlayer(File);
- m_Lock.Unlock();
- return m_Player;
-}
-
-void cXinelibImagesControl::Close(void)
-{
- m_Lock.Lock();
- if(m_Player)
- delete m_Player;
- m_Player = NULL;
- m_Lock.Unlock();
-}
-
-void cXinelibImagesControl::Delete(void)
-{
- if(Interface->Confirm(tr("Delete image ?"))) {
- if(!unlink(m_Files[m_Index])) {
- free(m_Files[m_Index]);
- for(int i=m_Index; i<m_Count; i++)
- m_Files[i] = m_Files[i+1];
- m_Count--;
- m_Files[m_Count] = NULL;
- Seek(0);
- }
- }
-}
-
-cOsdObject *cXinelibImagesControl::GetInfo(void)
-{
- return new cMetainfoMenu(m_Files[m_Index]);
-}
-
-void cXinelibImagesControl::Seek(int Rel)
-{
- if(m_Index == m_Count-1 && Rel>0)
- m_Index = 0;
- else if(m_Index == 0 && Rel<0)
- m_Index = m_Count-1;
- else
- m_Index += Rel;
-
- if(m_Index < 0)
- m_Index = 0;
- else if(m_Index >= m_Count)
- m_Index = m_Count;
-
- char *pt;
- free(m_File);
- m_File = strdup(m_Files[m_Index]);
- if(NULL != (pt=strrchr(m_File, '/')))
- strcpy(m_File, pt+1);
- if(NULL != (pt=strrchr(m_File, '.')))
- *pt = 0;
-
- cStatus::MsgReplaying(this, m_File, m_Files[m_Index], true);
-
- m_Player->ShowImage(m_Files[m_Index]);
- m_LastShowTime = time(NULL);
- strn0cpy(xc.browse_images_dir, m_Files[m_Index], sizeof(xc.browse_images_dir));
-}
-
-void cXinelibImagesControl::Show(void)
-{
- bool Play = (m_Speed!=0), Forward = m_Speed>=0;
- int Speed = abs(m_Speed);
-
- if(!m_DisplayReplay) {
- m_DisplayReplay = Skins.Current()->DisplayReplay(m_ShowModeOnly);
- }
-
- if(!m_ShowModeOnly) {
- char t[128] = "";
- m_DisplayReplay->SetTitle(m_File);
- m_DisplayReplay->SetProgress(m_Index, m_Count);
- sprintf(t, "%d", m_Count);
- m_DisplayReplay->SetTotal( t );
- sprintf(t, "%d", m_Index+1);
- m_DisplayReplay->SetCurrent( t );
- }
-
- m_DisplayReplay->SetMode(Play, Forward, Speed);
- m_DisplayReplay->Flush();
-}
-
-void cXinelibImagesControl::Hide(void)
-{
- if(m_DisplayReplay) {
- delete m_DisplayReplay;
- m_DisplayReplay = NULL;
- }
-}
-
-eOSState cXinelibImagesControl::ProcessKey(eKeys Key)
-{
- switch(Key) {
- case kBack: xc.main_menu_mode = ShowImages;
- Hide();
- Close();
- BackToMenu();
- //return osPlugin;
- return osEnd;
- case kYellow: Delete();
- break;
- case kStop:
- case kBlue: Hide();
- Close();
- return osEnd;
- case kPrev:
- case kLeft: Seek(-1);
- break;
- case kNext:
- case kRight: Seek(1);
- break;
- case kUp: Seek(5);
- break;
- case kDown: Seek(-5);
- break;
- case kPause: m_Speed = 0;
- break;
- case kPlay: m_Speed = 2;
- break;
- case kFastFwd: m_Speed++;
- break;
- case kFastRew: m_Speed--;
- break;
- case kOk: if(m_DisplayReplay) {
- if(m_ShowModeOnly) {
- Hide();
- m_ShowModeOnly = false;
- Show();
- } else {
- Hide();
- }
- } else {
- m_ShowModeOnly = true;
- Show();
- }
- break;
- default: break;
- }
-
- static const int Speed2Time[] = { 0, 5, 3, 1 };
- if(m_Speed > 3)
- m_Speed = 3;
- if(m_Speed < -3)
- m_Speed = -3;
-
- if(Key == kNone && m_Speed != 0) {
- if(m_LastShowTime + Speed2Time[m_Speed<0 ? -m_Speed : m_Speed] <= time(NULL))
- Seek(sgn(m_Speed));
- }
-
- if (m_DisplayReplay)
- Show();
-
- return osContinue;
-}
diff --git a/media_player.h b/media_player.h
deleted file mode 100644
index 8b55fceb..00000000
--- a/media_player.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * media_player.h: Media and image players
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: media_player.h,v 1.16 2008-05-07 13:27:15 phintuka Exp $
- *
- */
-
-#ifndef __XINELIB_PLAYER_H
-#define __XINELIB_PLAYER_H
-
-#include <vdr/player.h>
-
-#include "config.h"
-
-// --- Media player ---------------------------------------------------------
-
-class cXinelibPlayer;
-class cSkinDisplayReplay;
-class cPlaylistMenu;
-
-class cXinelibPlayerControl : public cControl
-{
- private:
- static cMutex m_Lock;
-
- static cXinelibPlayer *OpenPlayer(const char *File, bool Queue = false, const char *SubFile = NULL);
-
- protected:
- static cXinelibPlayer *m_Player;
-
- cSkinDisplayReplay *m_DisplayReplay;
- cPlaylistMenu *m_PlaylistMenu;
-
- eMainMenuMode m_Mode;
- bool m_ShowModeOnly;
- bool m_RandomPlay;
- time_t m_AutoShowStart;
- int m_CurrentPos;
- int m_CurrentLen;
- bool m_BlinkState;
-
- cTimeMs lastTime;
- int number;
-
- void MsgReplaying(const char *Title, const char *File);
-
- public:
- cXinelibPlayerControl(eMainMenuMode Mode, const char *File, const char *SubFile = NULL);
- virtual ~cXinelibPlayerControl();
-
- virtual void Show(void);
- virtual void Hide(void);
- virtual eOSState ProcessKey(eKeys Key);
-
- virtual cOsdObject *GetInfo(void);
-
- static void Close(void);
- static bool IsOpen(void) { return m_Player != NULL; };
- static void Queue(const char *File);
-};
-
-
-// --- DVD player -----------------------------------------------------------
-
-class cDvdMenu;
-class cXinelibDvdPlayerControl : public cXinelibPlayerControl
-{
- private:
- cDvdMenu *Menu;
- char m_CurrentDVDTitle[63];
-
- public:
- cXinelibDvdPlayerControl(const char *File) :
- cXinelibPlayerControl(ShowFiles, File), Menu(NULL)
- {}
- virtual ~cXinelibDvdPlayerControl();
-
- virtual void Show(void);
- virtual void Hide(void);
- virtual eOSState ProcessKey(eKeys Key);
-};
-
-// --- Image player ---------------------------------------------------------
-
-class cXinelibImagePlayer;
-
-class cXinelibImagesControl : public cControl
-{
- private:
- static cXinelibImagePlayer *m_Player;
- static cMutex m_Lock;
-
- cSkinDisplayReplay *m_DisplayReplay;
-
- char **m_Files;
- char *m_File;
- int m_Index;
- int m_Count;
- int m_Speed;
- int m_LastShowTime;
- bool m_ShowModeOnly;
-
- static cXinelibImagePlayer *OpenPlayer(const char *File);
-
- protected:
- void Seek(int Rel);
- void Delete(void);
-
- public:
- cXinelibImagesControl(char **Files, int Index, int Count);
- virtual ~cXinelibImagesControl();
-
- virtual void Show(void);
- virtual void Hide(void);
- virtual eOSState ProcessKey(eKeys Key);
-
- virtual cOsdObject *GetInfo(void);
-
- static void Close(void);
- static bool IsOpen(void) { return m_Player != NULL; }
-};
-
-#endif // __XINELIB_PLAYER_H
-
diff --git a/menu.c b/menu.c
deleted file mode 100644
index 73b983cd..00000000
--- a/menu.c
+++ /dev/null
@@ -1,873 +0,0 @@
-/*
- * menu.c: Main Menu
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: menu.c,v 1.64 2009-06-01 14:04:42 phintuka Exp $
- *
- */
-
-#include "features.h"
-
-#include <dirent.h>
-
-#include <vdr/config.h>
-#include <vdr/interface.h>
-#include <vdr/menu.h>
-#include <vdr/plugin.h>
-#include <vdr/videodir.h>
-#include <vdr/i18n.h>
-
-#include "logdefs.h"
-#include "config.h"
-#include "menu.h"
-#include "menuitems.h"
-#include "tools/metainfo_menu.h"
-#include "device.h"
-#include "media_player.h"
-#include "equalizer.h"
-
-#ifndef HOTKEY_START
-# define HOTKEY_START kRed
-
-# define HOTKEY_DVD k0 /* */
-# define HOTKEY_DVD_TRACK1 k1 /* */
-# define HOTKEY_RESERVED k2 /* */
-
-# define HOTKEY_NEXT_ASPECT k3 /* auto, 4:3, 16:9 */
-# define HOTKEY_TOGGLE_CROP k4 /* off, force, auto */
-# define HOTKEY_UPMIX k5 /* off, on */
-# define HOTKEY_DOWNMIX k6 /* off, on */
-# define HOTKEY_DEINTERLACE k7 /* off, on */
-# define HOTKEY_LOCAL_FE k8 /* off, on */
-
-# define HOTKEY_PLAYLIST k9 /* Start replaying playlist or file pointed by
- symlink $(CONFDIR)/plugins/xineliboutput/default_playlist */
-# define HOTKEY_ADELAY_UP kUp /* audio delay up */
-# define HOTKEY_ADELAY_DOWN kDown /* audio delay down */
-# define HOTKEY_TOGGLE_VO_ASPECT kRight
-#endif
-
-//#define OLD_TOGGLE_FE
-
-#define ISNUMBERKEY(k) (RAWKEY(k) >= k0 && RAWKEY(k) <= k9)
-
-//--------------------------- cMenuBrowseFiles -------------------------------
-
-class cMenuBrowseFiles : public cOsdMenu
-{
- protected:
- const eMainMenuMode m_Mode;
- bool m_OnlyQueue;
- char *m_CurrentDir;
- char *m_ConfigLastDir;
-
- virtual bool ScanDir(const char *DirName);
- virtual eOSState Open(bool ForceOpen = false, bool Parent = false, bool Queue = false);
- virtual eOSState Delete(void);
- virtual eOSState Info(void);
- virtual void Set(void);
- virtual void SetHelpButtons(void);
- cFileListItem *GetCurrent() { return (cFileListItem *)Get(Current()); }
- void StoreConfig(void);
- char *GetLastDir(void);
-
- public:
- cMenuBrowseFiles(eMainMenuMode mode = ShowFiles, bool OnlyQueue=false);
- ~cMenuBrowseFiles();
-
- virtual eOSState ProcessKey(eKeys Key);
-};
-
-static char *ParentDir(const char *dir)
-{
- char *result = strdup(dir);
- char *pt = strrchr(result, '/');
- if(pt) {
- *(pt+1)=0;
- if(pt != result)
- *pt = 0;
- }
- return result;
-}
-
-static char *LastDir(const char *dir)
-{
- const char *pt = strrchr(dir, '/');
- if(pt && pt[0] && pt[1])
- return strdup(pt+1);
- return NULL;
-}
-
-cMenuBrowseFiles::cMenuBrowseFiles(eMainMenuMode mode, bool OnlyQueue) :
- cOsdMenu( ( mode==ShowImages ? tr("Images") :
- mode==ShowMusic ? (!OnlyQueue ? tr("Play music") : tr("Add to playlist")) :
- /*mode==ShowFiles ?*/ tr("Play file")),
- 2, 4),
- m_Mode(mode)
-{
- m_CurrentDir = NULL;
- m_OnlyQueue = OnlyQueue;
-
- m_ConfigLastDir = GetLastDir();
- Set();
-}
-
-cMenuBrowseFiles::~cMenuBrowseFiles()
-{
- Setup.Save();
- free(m_CurrentDir);
-}
-
-char *cMenuBrowseFiles::GetLastDir(void)
-{
- switch(m_Mode) {
- case ShowMusic: return xc.browse_music_dir;
- case ShowImages: return xc.browse_images_dir;
- default:
- case ShowFiles: return xc.browse_files_dir;
- }
- return xc.browse_files_dir;
-}
-
-void cMenuBrowseFiles::Set(void)
-{
- Clear();
-
- if(!m_CurrentDir)
- m_CurrentDir = strdup(m_ConfigLastDir);
-
- if(m_CurrentDir[0] != '/') {
- free(m_CurrentDir);
- m_CurrentDir = strdup(VideoDirectory);
- }
-
- // find deepest accessible directory from path
- while(!ScanDir(m_CurrentDir) && strlen(m_CurrentDir) > 1) {
- char *n = ParentDir(m_CurrentDir);
- free(m_CurrentDir);
- m_CurrentDir = n;
- }
-
- // add link to parent folder
- if(strlen(m_CurrentDir) > 1)
- Add(new cFileListItem("..",true));
-
- Sort();
-
- SetCurrent(Get(Count()>1 && strlen(m_CurrentDir)>1 ? 1 : 0));
-
- // select last selected item
-
- char *lastParent = ParentDir(m_ConfigLastDir);
- if(!strncmp(m_CurrentDir,lastParent,strlen(m_CurrentDir))) {
- char *item = LastDir(m_ConfigLastDir);
- if(item) {
- for(cFileListItem *it = (cFileListItem*)First(); it; it = (cFileListItem*)Next(it))
- if(!strcmp(it->Name(),item))
- SetCurrent(it);
- free(item);
- }
- }
- free(lastParent);
-
- strn0cpy(m_ConfigLastDir, m_CurrentDir, sizeof(xc.browse_files_dir));
- StoreConfig();
-
- SetHelpButtons();
-}
-
-void cMenuBrowseFiles::StoreConfig(void)
-{
- cPluginManager::GetPlugin(PLUGIN_NAME_I18N)->SetupStore("Media.BrowseMusicDir",
- xc.browse_music_dir);
- cPluginManager::GetPlugin(PLUGIN_NAME_I18N)->SetupStore("Media.BrowseFilesDir",
- xc.browse_files_dir);
- cPluginManager::GetPlugin(PLUGIN_NAME_I18N)->SetupStore("Media.BrowseImagesDir",
- xc.browse_images_dir);
-#if 1
- // delete old keys (<1.0.0)
- cPluginManager::GetPlugin(PLUGIN_NAME_I18N)->SetupStore("BrowseMusicDir");
- cPluginManager::GetPlugin(PLUGIN_NAME_I18N)->SetupStore("BrowseFilesDir");
- cPluginManager::GetPlugin(PLUGIN_NAME_I18N)->SetupStore("BrowseImagesDir");
-#endif
-}
-
-void cMenuBrowseFiles::SetHelpButtons(void)
-{
- bool isDir = !GetCurrent() || GetCurrent()->IsDir();
- bool isDvd = GetCurrent() && GetCurrent()->IsDvd();
- SetHelp((isDir && isDvd) ? trVDR("Button$Open") : !m_OnlyQueue ? trVDR("Button$Play"): NULL,
- (m_Mode == ShowMusic) ? tr("Button$Queue") :
- strlen(m_CurrentDir)>1 ? "[..]" : NULL,
- (isDir && !isDvd) ? NULL : trVDR("Button$Delete"),
- isDir ? NULL : trVDR("Button$Info"));
- Display();
-}
-
-eOSState cMenuBrowseFiles::Delete(void)
-{
- cFileListItem *it = GetCurrent();
- if(!it->IsDir()) {
- if (Interface->Confirm(trVDR("Delete recording?"))) {
- cString name = cString::sprintf("%s/%s", m_CurrentDir, it->Name());
- if(!unlink(name)) {
- isyslog("file %s deleted", *name);
- if(m_Mode != ShowImages) {
- name = cString::sprintf("%s.resume", *name);
- unlink(name);
- }
- cOsdMenu::Del(Current());
- SetHelpButtons();
- Display();
- } else {
- Skins.Message(mtError, trVDR("Error while deleting recording!"));
- isyslog("Error deleting file %s", *name);
- }
- }
- }
- return osContinue;
-}
-
-eOSState cMenuBrowseFiles::Open(bool ForceOpen, bool Parent, bool Queue)
-{
- if(!GetCurrent()) {
- return osContinue;
- }
-
- /* parent directory */
- if(Parent || !strcmp("..", GetCurrent()->Name())) {
- char *n = ParentDir(m_CurrentDir);
- free(m_CurrentDir);
- m_CurrentDir = n;
- Set();
- return osContinue;
-
- /* directory */
- } else if (GetCurrent()->IsDir()) {
-
- if(!ForceOpen && GetCurrent()->IsDvd()) {
- /* play dvd */
- cString f = cString::sprintf("dvd:%s/%s", m_CurrentDir, GetCurrent()->Name());
- cControl::Shutdown();
- cControl::Launch(new cXinelibDvdPlayerControl(f));
- return osEnd;
- }
- if(ForceOpen && GetCurrent()->IsDir() && !GetCurrent()->IsDvd()) {
- /* play all files */
- if(m_Mode != ShowImages) {
-
- if(m_OnlyQueue && !Queue)
- return osContinue;
-
- cString f = cString::sprintf("%s/%s/", m_CurrentDir, GetCurrent()->Name());
-
- if(!Queue || !cXinelibPlayerControl::IsOpen())
- cControl::Shutdown();
- if(Queue)
- cXinelibPlayerControl::Queue(f);
- else
- cControl::Launch(new cXinelibPlayerControl(m_Mode, f));
- return Queue ? osContinue : osEnd;
-
- } else {
- // TODO: show all images
- }
- }
- const char *d = GetCurrent()->Name();
- char *buffer = NULL;
- if(asprintf(&buffer, "%s/%s", m_CurrentDir, d) >= 0) {
- while(buffer[0] == '/' && buffer[1] == '/')
- strcpy(buffer, buffer+1);
- free(m_CurrentDir);
- m_CurrentDir = buffer;
- }
- Set();
- return osContinue;
-
- /* regular file */
- } else {
- cString f = cString::sprintf("%s%s/%s",
- GetCurrent()->IsDvd() ? "dvd:" : "",
- m_CurrentDir, GetCurrent()->Name());
- if (GetCurrent()->IsDvd())
- strn0cpy(m_ConfigLastDir, m_CurrentDir, sizeof(xc.browse_files_dir));
- else
- strn0cpy(m_ConfigLastDir, f, sizeof(xc.browse_files_dir));
- StoreConfig();
-
- if(m_Mode != ShowImages) {
- /* video/audio */
- if(m_OnlyQueue && !Queue)
- return osContinue;
- if(!Queue || !cXinelibPlayerControl::IsOpen())
- cControl::Shutdown();
- if(Queue)
- cXinelibPlayerControl::Queue(f);
- if(!cXinelibPlayerControl::IsOpen())
- cControl::Launch(GetCurrent()->IsDvd()
- ? new cXinelibDvdPlayerControl(f)
- : new cXinelibPlayerControl(m_Mode, f, GetCurrent()->SubFile()));
- if(Queue)
- return osContinue;
- } else {
- /* image */
- char **files = new char*[Count()+1];
- int i = 0, index = 0;
- memset(files, 0, sizeof(char*)*(Count()+1));
- for(cFileListItem *it = (cFileListItem*)First(); it; it=(cFileListItem*)Next(it)) {
- if(it==Get(Current()))
- index = i;
- if(!it->IsDir())
- if(asprintf(&files[i++], "%s/%s", m_CurrentDir, it->Name()) < 0)
- i--;
- }
- cControl::Shutdown();
- cControl::Launch(new cXinelibImagesControl(files, index, i));
- }
- return osEnd;
- }
- return osContinue;
-}
-
-eOSState cMenuBrowseFiles::Info(void)
-{
- if(GetCurrent() && !GetCurrent()->IsDir()) {
- cString filename = cString::sprintf("%s/%s", m_CurrentDir, GetCurrent()->Name());
- return AddSubMenu(new cMetainfoMenu(filename));
- }
- return osContinue;
-}
-
-bool cMenuBrowseFiles::ScanDir(const char *DirName)
-{
- DIR *d = opendir(DirName);
- if (d) {
- struct dirent *e;
- while ((e = readdir(d)) != NULL) {
- if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
- cString buffer = cString::sprintf("%s/%s", DirName, e->d_name);
- struct stat st;
- if (stat(buffer, &st) == 0) {
-
- // check symlink destination
- if (S_ISLNK(st.st_mode)) {
- buffer = ReadLink(buffer);
- if (!*buffer || stat(buffer, &st))
- continue;
- }
-
- // folders
- if (S_ISDIR(st.st_mode)) {
-
- if(m_Mode == ShowImages || m_Mode == ShowMusic)
- Add(new cFileListItem(e->d_name, true));
- else
- Add(new cFileListItem(e->d_name, true, false, false, xc.IsDvdFolder(buffer)));
-
- // regular files
- } else if(e->d_name[0] != '.') {
-
- // audio
- if (m_Mode == ShowMusic && xc.IsAudioFile(buffer)) {
- Add(new cFileListItem(e->d_name, false));
-
- // images
- } else if(m_Mode == ShowImages && xc.IsImageFile(buffer)) {
- Add(new cFileListItem(e->d_name, false));
-
- // DVD image (.iso)
- } else if (m_Mode == ShowFiles && xc.IsDvdImage(buffer)) {
- Add(new cFileListItem(e->d_name, false, false, false, true));
-
- // video
- } else if (m_Mode == ShowFiles && xc.IsVideoFile(buffer)) {
- cString subfile;
- cString resumefile;
-
- // separate subtitles ?
- cString basename = cString::sprintf("%s/%s", DirName, e->d_name);
- const char *p = strrchr(basename, '.');
- if (p)
- basename.Truncate(p - basename);
- int i;
- for(i=0; xc.s_subExts[i] && !*subfile; i++) {
- cString tmp = cString::sprintf("%s%s", *basename, xc.s_subExts[i]);
- if (stat(tmp, &st) == 0)
- subfile = tmp;
- }
-
- // resume file ?
- resumefile = cString::sprintf("%s/%s.resume", DirName, e->d_name);
- if (stat(resumefile, &st) != 0)
- resumefile = NULL;
-
- Add(new cFileListItem(e->d_name, false, *resumefile, subfile));
- }
- }
- }
- }
- }
- closedir(d);
- return true;
- }
- return false;
-}
-
-eOSState cMenuBrowseFiles::ProcessKey(eKeys Key)
-{
- eOSState state = cOsdMenu::ProcessKey(Key);
-
- if (state == osUnknown) {
- switch (Key) {
- case kPlay:
- case kOk: return Open(false, false, m_OnlyQueue);
- case kRed: return Open(true);
- case kGreen: return Open(true, m_Mode != ShowMusic,
- m_Mode==ShowMusic ? m_OnlyQueue=true : false);
- case kYellow: return Delete();
- case kBlue: return Info();
- default: break;
- }
- }
-
- if (state == osUnknown)
- state = osContinue;
-
- if(!HasSubMenu())
- SetHelpButtons();
-
- return state;
-}
-
-
-//----------------------------- cMenuXinelib ---------------------------------
-
-#include "tools/display_message.h"
-
-static cOsdItem *NewTitle(const char *s)
-{
- cString str = cString::sprintf("----- %s -----", s);
- cOsdItem *tmp = new cOsdItem(str);
- tmp->SetSelectable(false);
- return tmp;
-}
-
-
-extern cOsdObject *g_PendingMenuAction;
-
-time_t cMenuXinelib::g_LastHotkeyTime = 0;
-eKeys cMenuXinelib::g_LastHotkey = kNone;
-
-cMenuXinelib::cMenuXinelib()
-{
- field_order = xc.field_order;
- compression = xc.audio_compression;
- headphone = xc.headphone;
- autocrop = xc.autocrop;
- overscan = xc.overscan;
-
- hotkey_state = hkInit;
-
- novideo = cXinelibDevice::Instance().GetPlayMode() == pmAudioOnlyBlack ? 1 : 0;
-
- Add(NewTitle(tr("Media")));
- Add(new cOsdItem(tr("Play file >>"), osUser1));
- Add(new cOsdItem(tr("Play music >>"), osUser2));
- Add(new cOsdItem(tr("View images >>"), osUser3));
- if(xc.remote_mode)
- Add(new cOsdItem(tr("Play remote DVD >>"), osUser4));
- else
- Add(new cOsdItem(tr("Play DVD disc >>"), osUser4));
- if(xc.remote_mode)
- Add(new cOsdItem(tr("Play remote CD >>"), osUser6));
- else
- Add(new cOsdItem(tr("Play audio CD >>"), osUser6));
- Add(NewTitle(tr("Video settings")));
- Add(ctrl_novideo = new cMenuEditBoolItem(tr("Play only audio"),
- &novideo));
- Add(ctrl_autocrop = new cMenuEditBoolItem(tr("Crop letterbox 4:3 to 16:9"),
- &autocrop));
- Add(ctrl_overscan = new cMenuEditTypedIntItem(tr("Overscan (crop image borders)"), "%",
- &overscan, 0, 10,
- tr("Off")));
-#ifdef HAVE_XV_FIELD_ORDER
- Add(video_ctrl_interlace_order = new cMenuEditStraI18nItem(tr("Interlaced Field Order"),
- &field_order, 2, xc.s_fieldOrder));
-#endif
-
- Add(NewTitle(tr("Audio settings")));
-#ifdef ENABLE_TEST_POSTPLUGINS
- Add(ctrl_headphone = new cMenuEditBoolItem(tr("Headphone audio mode"),
- &headphone));
-#else
- ctrl_headphone = NULL;
-#endif
-
- Add(audio_ctrl_compress = new cMenuEditTypedIntItem(tr("Audio Compression"),"%",
- &compression, 100, 500, NULL, tr("Off")));
-
- Add(new cOsdItem(tr("Audio equalizer >>"), osUser7));
-
- switch(xc.main_menu_mode) {
- case ShowFiles: AddSubMenu(new cMenuBrowseFiles(ShowFiles)); break;
- case ShowMusic: AddSubMenu(new cMenuBrowseFiles(ShowMusic)); break;
- case ShowImages: AddSubMenu(new cMenuBrowseFiles(ShowImages)); break;
- default: break;
- }
-
- xc.main_menu_mode = ShowMenu;
-}
-
-cMenuXinelib::~cMenuXinelib()
-{
-#ifdef HAVE_XV_FIELD_ORDER
- if(xc.field_order != field_order )
- cXinelibDevice::Instance().ConfigureWindow(xc.fullscreen, xc.width, xc.height,
- xc.modeswitch, xc.modeline, xc.display_aspect,
- xc.scale_video, xc.field_order);
-#endif
-
- if(xc.audio_compression != compression)
- cXinelibDevice::Instance().ConfigurePostprocessing(xc.deinterlace_method, xc.audio_delay,
- xc.audio_compression, xc.audio_equalizer,
- xc.audio_surround, xc.speaker_type);
-
- if(xc.overscan != overscan)
- cXinelibDevice::Instance().ConfigureVideo(xc.hue, xc.saturation, xc.brightness, xc.sharpness,
- xc.noise_reduction, xc.contrast, xc.overscan,
- xc.vo_aspect_ratio);
-
- if(xc.headphone != headphone)
- cXinelibDevice::Instance().ConfigurePostprocessing("headphone",
- xc.headphone ? true : false);
-
- if(xc.autocrop != autocrop)
- cXinelibDevice::Instance().ConfigurePostprocessing("autocrop",
- xc.autocrop ? true : false,
- xc.AutocropOptions());
-
- int dev_novideo = cXinelibDevice::Instance().GetPlayMode() == pmAudioOnlyBlack ? 1 : 0;
- if(dev_novideo != novideo)
- cXinelibDevice::Instance().SetPlayMode(novideo ? pmAudioOnlyBlack : pmNone);
-}
-
-cOsdMenu *cMenuXinelib::CreateMenuBrowseFiles(eMainMenuMode mode, bool Queue)
-{
- return new cMenuBrowseFiles(mode, true);
-}
-
-eOSState cMenuXinelib::ProcessKey(eKeys Key)
-{
- /* Hot key support */
- if(hotkey_state == hkInit && Key == kNone)
- return osContinue;
- if(hotkey_state == hkInit && Key == HOTKEY_START) {
- hotkey_state = hkSeen;
- return osContinue;
- } else if(hotkey_state == hkSeen && Key != kNone) {
- hotkey_state = hkNone;
- return ProcessHotkey(Key);
- }
- hotkey_state = hkNone;
-
- cOsdItem *item = Get(Current());
-
- eOSState state = cMenuSetupPage::ProcessKey(Key);
-
- if(HasSubMenu())
- return state;
-
- switch(state) {
- case osUser1:
- AddSubMenu(new cMenuBrowseFiles(ShowFiles));
- return osUnknown;
- case osUser2:
- AddSubMenu(new cMenuBrowseFiles(ShowMusic));
- return osUnknown;
- case osUser3:
- AddSubMenu(new cMenuBrowseFiles(ShowImages));
- return osContinue;
- case osUser4:
- cControl::Shutdown();
- cControl::Launch(new cXinelibDvdPlayerControl("dvd:/"));
- return osEnd;
- case osUser6:
- cControl::Shutdown();
- cControl::Launch(new cXinelibPlayerControl(ShowMusic, "cdda:/"));
- return osEnd;
- case osUser7:
- if(!g_PendingMenuAction) {
- g_PendingMenuAction = new cEqualizer();
- return osPlugin;
- }
- return osContinue;
- default: ;
- }
-
- Key = NORMALKEY(Key);
-
- if(Key==kLeft || Key==kRight || ISNUMBERKEY(Key)) {
- if(item == audio_ctrl_compress)
- cXinelibDevice::Instance().ConfigurePostprocessing(xc.deinterlace_method, xc.audio_delay,
- compression, xc.audio_equalizer,
- xc.audio_surround, xc.speaker_type);
- else if(item == ctrl_overscan)
- cXinelibDevice::Instance().ConfigureVideo(xc.hue, xc.saturation, xc.brightness, xc.sharpness,
- xc.noise_reduction, xc.contrast, overscan,
- xc.vo_aspect_ratio);
- }
- if(Key==kLeft || Key==kRight) {
- if(item == ctrl_headphone)
- cXinelibDevice::Instance().ConfigurePostprocessing("headphone", headphone?true:false);
- else if(item == ctrl_autocrop)
- cXinelibDevice::Instance().ConfigurePostprocessing("autocrop", autocrop?true:false,
- xc.AutocropOptions());
- else if(item == ctrl_novideo)
- cXinelibDevice::Instance().SetPlayMode(novideo ? pmAudioOnlyBlack : pmNone);
-#ifdef HAVE_XV_FIELD_ORDER
- else if(video_ctrl_interlace_order && item == video_ctrl_interlace_order)
- cXinelibDevice::Instance().ConfigureWindow(xc.fullscreen, xc.width, xc.height,
- xc.modeswitch, xc.modeline,
- xc.display_aspect, xc.scale_video,
- field_order);
-#endif
- }
-
- return state;
-}
-
-void cMenuXinelib::Store(void)
-{
-#ifdef HAVE_XV_FIELD_ORDER
- xc.field_order = field_order;
-#endif
- xc.audio_compression = compression;
- xc.autocrop = autocrop;
- xc.overscan = overscan;
- xc.headphone = headphone;
-}
-
-eOSState cMenuXinelib::ProcessHotkey(eKeys Key)
-{
- eOSState NewState = osEnd;
- cString Message;
- time_t now = time(NULL);
- bool OnlyInfo = ((g_LastHotkeyTime < now-3) || g_LastHotkey != Key);
-
- switch(Key) {
- case HOTKEY_DVD:
- cControl::Shutdown();
- cControl::Launch(new cXinelibDvdPlayerControl("dvd:/"));
- break;
-
- case HOTKEY_DVD_TRACK1:
- cControl::Shutdown();
- cControl::Launch(new cXinelibDvdPlayerControl("dvd:/1"));
- break;
-
- case HOTKEY_LOCAL_FE:
- /* off, on */
- {
- int local_frontend = strstra(xc.local_frontend, xc.s_frontends, 0);
-
-#ifndef OLD_TOGGLE_FE
- if(local_frontend==FRONTEND_NONE)
- // no need to show current frontend if there is no output device ...
- OnlyInfo = false;
-#endif
- if(!OnlyInfo) {
-#ifndef OLD_TOGGLE_FE
- static int orig_frontend = -1;
- if(orig_frontend < 0)
- orig_frontend = local_frontend;
-
- if(orig_frontend == FRONTEND_NONE) {
- // no frontends were loaded at startup -> loop thru all frontends
- local_frontend++;
- } else {
- // frontend was loaded at startup -> toggle it on/off
- if(local_frontend == FRONTEND_NONE)
- local_frontend = orig_frontend;
- else
- local_frontend = FRONTEND_NONE;
- }
-#else
- local_frontend++;
-#endif
- if(local_frontend >= FRONTEND_count)
- local_frontend = 0;
- strn0cpy(xc.local_frontend, xc.s_frontends[local_frontend], sizeof(xc.local_frontend));
- cXinelibDevice::Instance().ConfigureWindow(
- xc.fullscreen, xc.width, xc.height, xc.modeswitch, xc.modeline,
- xc.display_aspect, xc.scale_video, xc.field_order);
- }
- Message = cString::sprintf("%s %s %s", tr("Local Frontend"),
- OnlyInfo ? ":" : "->",
- xc.s_frontendNames[local_frontend]);
- }
- break;
-
- case HOTKEY_NEXT_ASPECT:
- /* auto, 4:3, 16:9, ... */
- if(!OnlyInfo) {
- xc.display_aspect = (xc.display_aspect < ASPECT_count-1) ? xc.display_aspect+1 : 0;
- cXinelibDevice::Instance().ConfigureWindow(xc.fullscreen, xc.width, xc.height,
- xc.modeswitch, xc.modeline, xc.display_aspect,
- xc.scale_video, xc.field_order);
- }
- Message = cString::sprintf("%s %s %s", tr("Aspect ratio"),
- OnlyInfo ? ":" : "->",
- tr(xc.s_aspects[xc.display_aspect]));
- break;
-
- case HOTKEY_TOGGLE_VO_ASPECT:
- /* auto, square, 4:3, anamorphic or DVB */
- if(!OnlyInfo) {
- xc.vo_aspect_ratio = (xc.vo_aspect_ratio < VO_ASPECT_count-1) ? xc.vo_aspect_ratio + 1 : 0;
- cXinelibDevice::Instance().ConfigureVideo(xc.hue, xc.saturation, xc.brightness, xc.sharpness,
- xc.noise_reduction, xc.contrast, xc.overscan,
- xc.vo_aspect_ratio);
- }
- Message = cString::sprintf("%s %s %s", tr("Video aspect ratio"),
- OnlyInfo ? ":" : "->",
- tr(xc.s_vo_aspects[xc.vo_aspect_ratio]));
- break;
-
- case HOTKEY_TOGGLE_CROP:
- /* off, force, auto */
- if(!OnlyInfo) {
- if(!xc.autocrop) {
- xc.autocrop = 1;
- xc.autocrop_autodetect = 1;
- } else if(xc.autocrop_autodetect) {
- xc.autocrop_autodetect = 0;
- } else {
- xc.autocrop = 0;
- }
- cXinelibDevice::Instance().ConfigurePostprocessing("autocrop",
- xc.autocrop ? true : false,
- xc.AutocropOptions());
- }
-
- Message = cString::sprintf("%s %s %s", tr("Crop letterbox 4:3 to 16:9"),
- OnlyInfo ? ":" : "->",
- !xc.autocrop ? tr("Off") : xc.autocrop_autodetect ? tr("automatic") : tr("On"));
- break;
-
- case HOTKEY_DEINTERLACE:
- {
- /* off, on */
- int off = !strcmp(xc.deinterlace_method, "none");
- if(!OnlyInfo) {
- off = !off;
- if(off)
- strcpy(xc.deinterlace_method, "none");
- else
- strcpy(xc.deinterlace_method, "tvtime");
- cXinelibDevice::Instance().ConfigurePostprocessing(xc.deinterlace_method, xc.audio_delay,
- compression, xc.audio_equalizer,
- xc.audio_surround, xc.speaker_type);
- }
- Message = cString::sprintf("%s %s %s", tr("Deinterlacing"),
- OnlyInfo ? ":" : "->",
- tr(off ? "Off":"On"));
- }
- break;
-
- case HOTKEY_UPMIX:
- /* off, on */
- if(!OnlyInfo) {
- xc.audio_upmix = xc.audio_upmix ? 0 : 1;
- cXinelibDevice::Instance().ConfigurePostprocessing(
- "upmix", xc.audio_upmix ? true : false, NULL);
- }
- Message = cString::sprintf("%s %s %s",
- tr("Upmix stereo to 5.1"),
- OnlyInfo ? ":" : "->",
- tr(xc.audio_upmix ? "On" : "Off"));
- break;
-
- case HOTKEY_DOWNMIX:
- /* off, on */
- if(!OnlyInfo) {
- xc.audio_surround = xc.audio_surround ? 0 : 1;
- cXinelibDevice::Instance().ConfigurePostprocessing(
- xc.deinterlace_method, xc.audio_delay, xc.audio_compression,
- xc.audio_equalizer, xc.audio_surround, xc.speaker_type);
- }
- Message = cString::sprintf("%s %s %s",
- tr("Downmix AC3 to surround"),
- OnlyInfo ? ":" : "->",
- tr(xc.audio_surround ? "On":"Off"));
- break;
-
- case HOTKEY_PLAYLIST:
- /* Start replaying playlist or file pointed by
- symlink $(CONFDIR)/plugins/xineliboutput/default_playlist */
- {
- struct stat st;
- cString file = cString::sprintf("%s%s", cPlugin::ConfigDirectory("xineliboutput"), "/default_playlist");
- if (lstat(file, &st) == 0) {
- if (S_ISLNK(st.st_mode)) {
- cString buffer(ReadLink(file), true);
- if (!*buffer || stat(buffer, &st)) {
- Message = tr("Default playlist not found");
- } else {
- LOGDBG("Replaying default playlist: %s", *file);
- cControl::Shutdown();
- cControl::Launch(new cXinelibPlayerControl(CloseOsd, buffer));
- }
- } else {
- Message = tr("Default playlist is not symlink");
- }
- } else {
- Message = tr("Default playlist not defined");
- }
- }
- break;
-
- case HOTKEY_ADELAY_UP:
- /* audio delay up */
- if(!OnlyInfo) {
- xc.audio_delay++;
- cXinelibDevice::Instance().ConfigurePostprocessing(xc.deinterlace_method, xc.audio_delay,
- xc.audio_compression, xc.audio_equalizer,
- xc.audio_surround, xc.speaker_type);
- }
- Message = cString::sprintf("%s %s %d %s", tr("Delay"),
- OnlyInfo ? ":" : "->",
- xc.audio_delay, tr("ms"));
- break;
-
- case HOTKEY_ADELAY_DOWN:
- /* audio delay up */
- if(!OnlyInfo) {
- xc.audio_delay--;
- cXinelibDevice::Instance().ConfigurePostprocessing(xc.deinterlace_method, xc.audio_delay,
- xc.audio_compression, xc.audio_equalizer,
- xc.audio_surround, xc.speaker_type);
- }
- Message = cString::sprintf("%s %s %d %s", tr("Delay"),
- OnlyInfo ? ":" : "->",
- xc.audio_delay, tr("ms"));
- break;
-
- default:
- Message = cString::sprintf(tr("xineliboutput: hotkey %s not binded"), cKey::ToString(Key));
- break;
- }
-
- if(*Message) {
- if(!g_PendingMenuAction &&
- !cRemote::HasKeys() &&
- cRemote::CallPlugin("xineliboutput"))
- g_PendingMenuAction = new cDisplayMessage(Message);
- }
-
- g_LastHotkeyTime = now;
- g_LastHotkey = Key;
-
- return NewState;
-}
diff --git a/menu.h b/menu.h
deleted file mode 100644
index f6817996..00000000
--- a/menu.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * menu.h: Main Menu
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: menu.h,v 1.7 2008-11-01 07:23:00 phintuka Exp $
- *
- */
-
-#ifndef __XINELIB_MENU_H
-#define __XINELIB_MENU_H
-
-#include "features.h"
-
-#include <vdr/menuitems.h>
-
-class cMenuXinelib : public cMenuSetupPage
-{
- private:
- int field_order;
- int compression;
- int headphone;
- int autocrop;
- int overscan;
- int novideo;
-
- // Hotkeys
- enum {hkInit, hkSeen, hkNone} hotkey_state;
- static time_t g_LastHotkeyTime;
- static eKeys g_LastHotkey;
- virtual eOSState ProcessHotkey(eKeys Key);
-
-#ifdef HAVE_XV_FIELD_ORDER
- cOsdItem *video_ctrl_interlace_order;
-#endif
- cOsdItem *audio_ctrl_compress;
-
- cOsdItem *ctrl_autocrop;
- cOsdItem *ctrl_overscan;
- cOsdItem *ctrl_headphone;
- cOsdItem *ctrl_novideo;
-
- protected:
- virtual void Store(void);
-
- public:
- cMenuXinelib(void);
- virtual ~cMenuXinelib();
- virtual eOSState ProcessKey(eKeys Key);
-
- static cOsdMenu *CreateMenuBrowseFiles(eMainMenuMode mode, bool Queue=true);
-};
-
-#endif //__XINELIB_SETUP_MENU_H
diff --git a/menuitems.c b/menuitems.c
deleted file mode 100644
index 609c6a6b..00000000
--- a/menuitems.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * menuitems.c: New menu item types
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: menuitems.c,v 1.14 2009-05-29 15:05:19 phintuka Exp $
- *
- */
-
-#include <vdr/i18n.h>
-
-#include "menuitems.h"
-
-// --- cMenuEditTypedIntItem -------------------------------------------------
-
-cMenuEditTypedIntItem::cMenuEditTypedIntItem(const char *Name, const char *Type, int *Value,
- int Min, int Max, const char *ZeroString,
- const char *MinString, const char *MaxString)
-:cMenuEditIntItem(Name,Value,Min,Max,MinString,MaxString)
-{
- type = Type ? Type : "";
- zeroString = ZeroString ? ZeroString : NULL;
- Set();
-}
-
-void cMenuEditTypedIntItem::Set(void)
-{
- if(*value == 0 && *zeroString)
- SetValue(zeroString);
- else if (minString && *value == min)
- SetValue(minString);
- else if (maxString && *value == max)
- SetValue(maxString);
- else
- SetValue(cString::sprintf("%d %s", *value, *type));
-}
-
-// --- cMenuEditOddIntItem ------------------------------------------------------
-
-cMenuEditOddIntItem::cMenuEditOddIntItem(const char *Name, int *Value, int Min, int Max, const char *MinString, const char *MaxString)
-:cMenuEditIntItem(Name,Value,Min,Max,MinString,MaxString)
-{
- value = Value;
- min = Min;
- max = Max;
- minString = MinString;
- maxString = MaxString;
- if (*value < min)
- *value = min;
- else if (*value > max)
- *value = max;
- Set();
-}
-
-eOSState cMenuEditOddIntItem::ProcessKey(eKeys Key)
-{
- eOSState state = cMenuEditItem::ProcessKey(Key);
-
- if (state == osUnknown) {
- int newValue = *value;
- bool IsRepeat = Key & k_Repeat;
- Key = NORMALKEY(Key);
- switch (Key) {
- case kNone: break;
- case kLeft:
- newValue = *value - 2;
- fresh = true;
- if (!IsRepeat && newValue < min && max != INT_MAX)
- newValue = max;
- break;
- case kRight:
- newValue = *value + 2;
- fresh = true;
- if (!IsRepeat && newValue > max && min != INT_MIN)
- newValue = min;
- break;
- default:
- if (*value < min) { *value = min; Set(); }
- if (*value > max) { *value = max; Set(); }
- return state;
- }
- if (newValue != *value && (!fresh || min <= newValue) && newValue <= max) {
- *value = newValue;
- Set();
- }
- state = osContinue;
- }
- return state;
-}
-
-// --- cMenuEditFpIntItem ----------------------------------------------------
-
-cMenuEditFpIntItem::cMenuEditFpIntItem(const char *Name, int *Value, int Min, int Max,
- int Decimals, const char *ZeroString,
- const char *MinString, const char *MaxString)
-:cMenuEditIntItem(Name,Value,Min,Max,MinString,MaxString)
-{
- decimals = Decimals;
- zeroString = ZeroString ? ZeroString : NULL;
- Set();
-}
-
-static int my_exp10(int x)
-{
- int r = 1;
- for (; x > 0; x--, r *= 10) ;
- return r;
-}
-
-void cMenuEditFpIntItem::Set(void)
-{
- if(*value == 0 && *zeroString)
- SetValue(zeroString);
- else if (minString && *value == min)
- SetValue(minString);
- else if (maxString && *value == max)
- SetValue(maxString);
- else
- SetValue(cString::sprintf("%1.1f", ((float)(*value)) / (float)my_exp10(decimals)));
-}
-
-// --- cMenuEditStraI18nItem -------------------------------------------------
-
-cMenuEditStraI18nItem::cMenuEditStraI18nItem(const char *Name, int *Value, int NumStrings, const char * const *Strings)
-:cMenuEditIntItem(Name, Value, 0, NumStrings - 1)
-{
- strings = Strings;
- Set();
-}
-
-void cMenuEditStraI18nItem::Set(void)
-{
- SetValue(tr(strings[*value]));
-}
-
-// --- cFileListItem -------------------------------------------------
-
-cFileListItem::cFileListItem(const char *name, bool isDir)
-{
- m_Name = name;
- m_IsDir = isDir;
- m_IsDvd = false;
- m_HasResume = false;
- m_SubFile = NULL;
- m_ShowFlags = false;
- m_Up = m_IsDir && !strcmp(m_Name, "..");
- Set();
-}
-
-cFileListItem::cFileListItem(const char *name, bool IsDir,
- bool HasResume, const char *subfile,
- bool IsDvd)
-{
- m_Name = name;
- m_IsDir = IsDir;
- m_IsDvd = IsDvd;
- m_HasResume = HasResume;
- m_SubFile = subfile;
- m_ShowFlags = true;
- m_Up = m_IsDir && !strcmp(m_Name, "..");
- Set();
-}
-
-void cFileListItem::Set(void)
-{
- cString txt;
- const char *pt;
- if(m_ShowFlags) {
- if(m_IsDir) {
- if(m_IsDvd)
- txt = cString::sprintf("\tD\t[%s] ", *m_Name); // text2skin requires space at end of string to display item correctly ...
- else
- txt = cString::sprintf("\t\t[%s] ", *m_Name); // text2skin requires space at end of string to display item correctly ...
- } else {
- txt = cString::sprintf("%c\t%c\t%s", m_HasResume ? ' ' : '*', *m_SubFile ? 'S' : m_IsDvd ? 'D' : ' ', *m_Name);
- if(NULL != (pt = strrchr(txt,'.')))
- txt.Truncate(pt - txt);
- }
- } else {
- if(m_IsDir) {
- txt = cString::sprintf("[%s] ", *m_Name); // text2skin requires space at end of string to display item correctly ...
- } else {
- txt = m_Name;
- if(NULL != (pt = strrchr(txt,'.')))
- txt.Truncate(pt - txt);
- }
- }
- SetText(txt);
-}
-
-int cFileListItem::Compare(const cListObject &ListObject) const
-{
- cFileListItem *other = (cFileListItem *)&ListObject;
-
- if(m_IsDir && !other->m_IsDir)
- return -1;
- if(!m_IsDir && other->m_IsDir)
- return 1;
- if(m_Up && !other->m_Up)
- return -1;
- if(!m_Up && other->m_Up)
- return 1;
- return strcmp(m_Name, other->m_Name);
-}
-
-bool cFileListItem::operator< (const cListObject &ListObject)
-{
- cFileListItem *other = (cFileListItem *)&ListObject;
-
- if(m_IsDir && !other->m_IsDir)
- return true;
- if(!m_IsDir && other->m_IsDir)
- return false;
- if(m_Up && !other->m_Up)
- return true;
- if(!m_Up && other->m_Up)
- return false;
- return strcmp(m_Name, other->m_Name) < 0;
-}
diff --git a/menuitems.h b/menuitems.h
deleted file mode 100644
index cb158881..00000000
--- a/menuitems.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * menuitems.h: New menu item types
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: menuitems.h,v 1.7 2007-06-21 10:00:29 phintuka Exp $
- *
- */
-
-#ifndef __XINELIB_MENUITEMS_H_
-#define __XINELIB_MENUITEMS_H_
-
-#include <vdr/menuitems.h>
-
-// --- cMenuEditTypedIntItem -------------------------------------------------
-
-class cMenuEditTypedIntItem : public cMenuEditIntItem
-{
- protected:
- cString type;
- cString zeroString;
-
- virtual void Set(void);
-
- public:
- cMenuEditTypedIntItem(const char *Name, const char *Type, int *Value,
- int Min = 0, int Max = INT_MAX, const char *ZeroString = NULL,
- const char *MinString = NULL, const char *MaxString = NULL);
-};
-
-// --- cMenuEditOddIntItem -------------------------------------------------
-
-class cMenuEditOddIntItem : public cMenuEditIntItem
-{
- public:
- cMenuEditOddIntItem(const char *Name, int *Value, int Min = 1, int Max = INT_MAX, const char *MinString = NULL, const char *MaxString = NULL);
- eOSState ProcessKey(eKeys Key);
-};
-
-
-// --- cMenuEditFpIntItem -------------------------------------------------
-
-// Fixed-point decimal number
-
-class cMenuEditFpIntItem : public cMenuEditIntItem
-{
- protected:
- int decimals;
- cString zeroString;
-
- virtual void Set(void);
-
- public:
- cMenuEditFpIntItem(const char *Name, int *Value, int Min = 1, int Max = INT_MAX,
- int Decimals = 1, const char *ZeroString = NULL,
- const char *MinString = NULL, const char *MaxString = NULL);
-};
-
-
-// --- cMenuEditStraI18nItem -------------------------------------------------
-
-class cMenuEditStraI18nItem : public cMenuEditIntItem
-{
- private:
- const char * const *strings;
-
- protected:
- virtual void Set(void);
-
- public:
- cMenuEditStraI18nItem(const char *Name, int *Value,
- int NumStrings, const char * const *Strings);
-};
-
-// --- cFileListItem ---------------------------------------------------------
-
-class cFileListItem : public cOsdItem
-{
- private:
- cString m_Name;
- cString m_SubFile;
- bool m_IsDir, m_HasResume, m_ShowFlags, m_Up;
- bool m_IsDvd;
-
- protected:
- virtual void Set(void);
-
- public:
- cFileListItem(const char *name, bool isDir,
- bool HasResume, const char *subfile,
- bool IsDvd = false);
- cFileListItem(const char *name, bool isDir);
-
- const char *Name(void) { return m_Name; }
- const char *SubFile(void) { return m_SubFile; }
- bool IsDir(void) { return m_IsDir; }
- bool IsDvd(void) { return m_IsDvd; }
-
- virtual bool operator< (const cListObject &ListObject);
- virtual int Compare(const cListObject &ListObject) const;
-};
-
-#endif //__XINELIB_MENUITEMS_H_
diff --git a/mpg2c.c b/mpg2c.c
deleted file mode 100644
index 50c1e25a..00000000
--- a/mpg2c.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2003-2006 Petri Hintukainen <phintuka@cc.hut.fi>
- *
- * This code is distributed under the terms and conditions of the
- * GNU GENERAL PUBLIC LICENSE. See the file COPYING for details.
- *
- * mpg2.c:
- *
- * $Id: mpg2c.c,v 1.3 2006-06-04 11:00:04 phintuka Exp $
- *
- */
-
-#include <stdio.h>
-
-#define LINELEN 20
-
-int main(int argc, char *argv[])
-{
- int ch;
- int pos=1;
-
- if(argc != 4) {
- printf("%s - convert binary file to C code\n\n"
- "usage: %s variable inputfile outputfile\n",
- argv[0],argv[0]);
- return -1;
- }
-
- FILE *fi = fopen(argv[2],"rb");
- FILE *fo = fopen(argv[3],"wt");
- if(!fi ||!fo) {
- printf("Error opening files\n");
- return -1;
- }
- fprintf(fo, "extern const unsigned char v_mpg_%s[] = \n \"", argv[1]);
- while(EOF != (ch = fgetc(fi))) {
- fprintf(fo, "\\x%02x", ch);
- if(pos++ > LINELEN) {
- fprintf(fo, "\"\n \"");
- pos=1;
- }
- }
- fprintf(fo, "\";\n\nextern const int v_mpg_%s_length = sizeof(v_mpg_%s);\n\n",
- argv[1], argv[1]);
-
- fclose(fi);
- fclose(fo);
-
- return 0;
-}
diff --git a/nosignal_720x576.mpg b/nosignal_720x576.mpg
deleted file mode 100644
index cff01b4c..00000000
--- a/nosignal_720x576.mpg
+++ /dev/null
Binary files differ
diff --git a/osd.c b/osd.c
deleted file mode 100644
index f74b78a0..00000000
--- a/osd.c
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- * osd.c: Xinelib On Screen Display control
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: osd.c,v 1.37 2009-05-03 20:35:36 phintuka Exp $
- *
- */
-
-#include <vdr/config.h>
-#include <vdr/tools.h>
-#include <vdr/thread.h>
-
-#include "logdefs.h"
-#include "config.h"
-#include "device.h"
-#include "xine_osd_command.h"
-#include "tools/rle.h"
-
-#include "osd.h"
-
-//#define LIMIT_OSD_REFRESH_RATE
-
-#define LOGOSD(x...)
-
-//
-// tools
-//
-
-static inline int saturate(int x, int min, int max)
-{
- return x < min ? min : (x > max ? max : x);
-}
-
-static inline void prepare_palette(xine_clut_t *clut, const unsigned int *palette, int colors, bool top, bool rgb)
-{
- if (colors) {
- int c;
-
- // Apply alpha layer correction and convert ARGB -> AYCrCb
-
- for(c=0; c<colors; c++) {
- int A = (palette[c] & 0xff000000) >> 24;
- int R = (palette[c] & 0x00ff0000) >> 16;
- int G = (palette[c] & 0x0000ff00) >> 8;
- int B = (palette[c] & 0x000000ff);
- A = A + xc.alpha_correction*A/100 + xc.alpha_correction_abs;
- if(rgb) {
- clut[c].r = R;
- clut[c].g = G;
- clut[c].b = B;
- clut[c].alpha = saturate( A, 0, 255);
- } else {
- int Y = (( + 66*R + 129*G + 25*B + 0x80) >> 8) + 16;
- int CR = (( + 112*R - 94*G - 18*B + 0x80) >> 8) + 128;
- int CB = (( - 38*R - 74*G + 112*B + 0x80) >> 8) + 128;
- clut[c].y = saturate( Y, 16, 235);
- clut[c].cb = saturate(CB, 16, 240);
- clut[c].cr = saturate(CR, 16, 240);
- clut[c].alpha = saturate( A, 0, 255);
- }
- }
-
- // Apply OSD mixer settings
-
- if(!top) {
- if(xc.osd_mixer & OSD_MIXER_ALPHA)
- for(c=0; c<colors; c++)
- clut[c].alpha >>= 1; /* fade */
- if(xc.osd_mixer & OSD_MIXER_GRAY)
- for(c=0; c<colors; c++) {
- if(rgb)
- clut[c].r = clut[c].g = clut[c].b = (clut[c].r + clut[c].g + clut[c].b)/3;
- else
- clut[c].cb = clut[c].cr = 0x80;
- }
- }
- }
-}
-
-//
-// cXinelibOsd
-//
-
-class cXinelibOsd : public cOsd, public cListObject
-{
- private:
- cXinelibOsd();
- cXinelibOsd(cXinelibOsd&); // no copy
-
- cXinelibDevice *m_Device;
-
- void CloseWindows(void);
- void CmdSize(int Width, int Height);
- void CmdRle(int Wnd, int X0, int Y0,
- int W, int H, unsigned char *Data,
- int Colors, unsigned int *Palette,
- osd_rect_t *DirtyArea);
- void CmdPalette(int Wnd, int Colors, unsigned int *Palette);
- void CmdMove(int Wnd, int Width, int Height);
- void CmdClose(int Wnd);
- void CmdFlush(void);
-
- /* map single OSD window indexes to unique xine-side window handles */
- static uint64_t m_HandlesBitmap;
- int *m_WindowHandles;
- int AllocWindowHandles(int NumWindows);
- void FreeWindowHandles(void);
-
- protected:
- static cMutex m_Lock;
- static cList<cXinelibOsd> m_OsdStack;
-
- bool m_IsVisible;
- bool m_Refresh;
- uint m_Layer;
- uint16_t m_ExtentWidth;
- uint16_t m_ExtentHeight;
-
- virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas);
- virtual eOsdError SetAreas(const tArea *Areas, int NumAreas);
- virtual void Flush(void);
-
- // Messages from cXinelibOsdProvider
- void Show(void);
- void Hide(void);
- void Refresh(void);
- void Detach(void);
-
- friend class cXinelibOsdProvider;
-
- public:
- cXinelibOsd(cXinelibDevice *Device, int x, int y, uint Level = 0);
- virtual ~cXinelibOsd();
-};
-
-cList<cXinelibOsd> cXinelibOsd::m_OsdStack;
-cMutex cXinelibOsd::m_Lock;
-uint64_t cXinelibOsd::m_HandlesBitmap;
-
-int cXinelibOsd::AllocWindowHandles(int NumWindows)
-{
- uint64_t bit = 1;
- int index = 0, wnd = 0;
-
- FreeWindowHandles();
- m_WindowHandles = new int[NumWindows+1];
-
- for (index = 0; index < MAX_OSD_OBJECT; index++) {
- if (! (m_HandlesBitmap & bit)) {
- m_WindowHandles[wnd++] = index;
- m_HandlesBitmap |= bit;
- }
- if (wnd >= NumWindows)
- break;
- bit <<= 1;
- }
- m_WindowHandles[NumWindows] = -1;
-
- if (wnd < NumWindows) {
- LOGMSG("cXinelibOsd::AllocOsdHandles(): Too many open OSD windows !");
- while(wnd < NumWindows) m_WindowHandles[wnd++] = -1;
- return 0;
- }
-
- return NumWindows;
-}
-
-void cXinelibOsd::FreeWindowHandles(void)
-{
- if (m_WindowHandles) {
- int wnd = 0;
- while (m_WindowHandles[wnd] >= 0) {
- m_HandlesBitmap &= ~( ((uint64_t)1) << m_WindowHandles[wnd]);
- wnd++;
- }
- delete [] m_WindowHandles;
- m_WindowHandles = NULL;
- }
-}
-
-void cXinelibOsd::CmdSize(int Width, int Height)
-{
- TRACEF("cXinelibOsd::CmdSize");
-
- if (m_Device) {
- osd_command_t osdcmd = {0};
-
- for (int Wnd = 0; GetBitmap(Wnd); Wnd++) {
- osdcmd.cmd = OSD_Size;
- osdcmd.wnd = m_WindowHandles[Wnd];
- osdcmd.w = Width;
- osdcmd.h = Height;
-
- m_Device->OsdCmd((void*)&osdcmd);
- }
- }
-}
-
-void cXinelibOsd::CmdMove(int Wnd, int NewX, int NewY)
-{
- TRACEF("cXinelibOsd::CmdMove");
-
- if (m_Device) {
- osd_command_t osdcmd = {0};
-
- osdcmd.cmd = OSD_Move;
- osdcmd.wnd = m_WindowHandles[Wnd];
- osdcmd.x = NewX;
- osdcmd.y = NewY;
-
- m_Device->OsdCmd((void*)&osdcmd);
- }
-}
-
-void cXinelibOsd::CmdPalette(int Wnd, int Colors, unsigned int *Palette)
-{
- TRACEF("cXinelibOsd::CmdPalette");
-
- if (m_Device) {
- xine_clut_t clut[Colors];
- osd_command_t osdcmd = {0};
-
- osdcmd.cmd = OSD_SetPalette;
- osdcmd.wnd = m_WindowHandles[Wnd];
- osdcmd.palette = clut;
- osdcmd.colors = Colors;
-
- prepare_palette(&clut[0], Palette, Colors, /*Top*/(Prev() == NULL), true);
-
- m_Device->OsdCmd((void*)&osdcmd);
- }
-}
-
-void cXinelibOsd::CmdClose(int Wnd)
-{
- TRACEF("cXinelibOsd::CmdClose");
-
- if (m_Device) {
- osd_command_t osdcmd = {0};
-
- osdcmd.cmd = OSD_Close;
- osdcmd.wnd = m_WindowHandles[Wnd];
-
- if (m_Refresh)
- osdcmd.flags |= OSDFLAG_REFRESH;
- if (Prev() == NULL)
- osdcmd.flags |= OSDFLAG_TOP_LAYER;
-
- m_Device->OsdCmd((void*)&osdcmd);
- }
-}
-
-void cXinelibOsd::CmdFlush(void)
-{
- TRACEF("cXinelibOsd::CmdFlush");
-
- if (m_Device) {
- osd_command_t osdcmd = {0};
-
- osdcmd.cmd = OSD_Flush;
-
- m_Device->OsdCmd((void*)&osdcmd);
- }
-}
-
-void cXinelibOsd::CmdRle(int Wnd, int X0, int Y0,
- int W, int H, unsigned char *Data,
- int Colors, unsigned int *Palette,
- osd_rect_t *DirtyArea)
-{
- TRACEF("cXinelibOsd::CmdRle");
-
- if (m_Device) {
-
- xine_clut_t clut[Colors];
- osd_command_t osdcmd = {0};
-
- osdcmd.cmd = OSD_Set_RLE;
- osdcmd.wnd = m_WindowHandles[Wnd];
- osdcmd.layer = saturate(m_Layer, 0, 0xffff);
- osdcmd.x = X0;
- osdcmd.y = Y0;
- osdcmd.w = W;
- osdcmd.h = H;
- osdcmd.colors = Colors;
- osdcmd.palette = clut;
- osdcmd.scaling = xc.osd_scaling;
-
- if (DirtyArea)
- memcpy(&osdcmd.dirty_area, DirtyArea, sizeof(osd_rect_t));
- if (m_Refresh)
- osdcmd.flags |= OSDFLAG_REFRESH;
- if (xc.osd_blending == OSD_BLENDING_HARDWARE)
- osdcmd.flags |= OSDFLAG_UNSCALED;
- if (xc.osd_blending_lowresvideo == OSD_BLENDING_HARDWARE)
- osdcmd.flags |= OSDFLAG_UNSCALED_LOWRES;
- if (Prev() == NULL)
- osdcmd.flags |= OSDFLAG_TOP_LAYER;
-
- prepare_palette(&clut[0], Palette, Colors, /*Top*/(Prev() == NULL), true);
-
- if (xc.osd_blending_lowresvideo == OSD_BLENDING_HARDWARE)
- osdcmd.flags |= OSDFLAG_UNSCALED_LOWRES;
- osdcmd.num_rle = rle_compress(&osdcmd.data, Data, W, H);
- osdcmd.datalen = 4 * osdcmd.num_rle;
-
- m_Device->OsdCmd((void*)&osdcmd);
-
- free(osdcmd.data);
- }
-}
-
-cXinelibOsd::cXinelibOsd(cXinelibDevice *Device, int x, int y, uint Level)
- : cOsd(x, y, Level)
-{
- TRACEF("cXinelibOsd::cXinelibOsd");
-
- m_Device = Device;
- m_Refresh = false;
- m_IsVisible = true;
- m_Layer = Level;
- m_ExtentWidth = 720;
- m_ExtentHeight = 576;
-
- m_WindowHandles = NULL;
-}
-
-cXinelibOsd::~cXinelibOsd()
-{
- TRACEF("cXinelibOsd::~cXinelibOsd");
-
- cMutexLock ml(&m_Lock);
-
- CloseWindows();
- FreeWindowHandles();
-
- m_OsdStack.Del(this, false);
-
- if(m_OsdStack.First())
- m_OsdStack.First()->Show();
-}
-
-eOsdError cXinelibOsd::SetAreas(const tArea *Areas, int NumAreas)
-{
- TRACEF("cXinelibOsd::SetAreas");
- cMutexLock ml(&m_Lock);
-
- LOGOSD("cXinelibOsd::SetAreas");
-
- // Close all existing windows
- CloseWindows();
- FreeWindowHandles();
-
- eOsdError Result = cOsd::SetAreas(Areas, NumAreas);
-
- if (Result != oeOk)
- return Result;
-
- // Allocate xine OSD window handles
- if (!AllocWindowHandles(NumAreas)) {
- FreeWindowHandles();
- return oeTooManyAreas;
- }
-
- // Detect full OSD area size
- if(Left() + Width() > 720 || Top() + Height() > 576) {
- m_ExtentWidth = Setup.OSDWidth + 2 * Setup.OSDLeft;
- m_ExtentHeight = Setup.OSDHeight + 2 * Setup.OSDTop;
- LOGDBG("Detected HD OSD, size > %dx%d, using setup values %dx%d",
- 2*Left() + Width(), 2*Top() + Height(),
- m_ExtentWidth, m_ExtentHeight);
- } else {
- m_ExtentWidth = 720;
- m_ExtentHeight = 576;
- }
- CmdSize(m_ExtentWidth, m_ExtentHeight);
-
- return Result;
-}
-
-eOsdError cXinelibOsd::CanHandleAreas(const tArea *Areas, int NumAreas)
-{
- TRACEF("cXinelibOsd::CanHandleAreas");
-
- eOsdError Result = cOsd::CanHandleAreas(Areas, NumAreas);
-
- if (Result != oeOk)
- return Result;
-
- if (NumAreas > MAX_OSD_OBJECT)
- return oeTooManyAreas;
-
- for (int i = 0; i < NumAreas; i++) {
- if (Areas[i].bpp < 1 || Areas[i].bpp > 8) {
- LOGMSG("cXinelibOsd::CanHandleAreas(): invalid bpp (%d)", Areas[i].bpp);
- return oeBppNotSupported;
- }
- }
-
- // enough free xine OSD windows ?
- uint64_t bit = 1;
- int windows = NumAreas;
- for (int index = 0; index < MAX_OSD_OBJECT && windows > 0; index++) {
- if (! (m_HandlesBitmap & bit))
- windows--;
- bit <<= 1;
- }
- if (windows > 0) {
- LOGMSG("cXinelibOsd::CanHandleAreas(): not enough free window handles !");
- return oeTooManyAreas;
- }
-
- return oeOk;
-}
-
-void cXinelibOsd::Flush(void)
-{
- TRACEF("cXinelibOsd::Flush");
-
- cMutexLock ml(&m_Lock);
-
- cBitmap *Bitmap;
-
- if(!m_IsVisible)
- return;
-
- int SendDone = 0;
- for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) {
- int x1 = 0, y1 = 0, x2 = Bitmap->Width()-1, y2 = Bitmap->Height()-1;
- if (m_Refresh || Bitmap->Dirty(x1, y1, x2, y2)) {
-
- /* XXX what if only palette has been changed ? */
- int NumColors;
- const tColor *Colors = Bitmap->Colors(NumColors);
- if (Colors) {
- osd_rect_t DirtyArea = {x1:x1, y1:y1, x2:x2, y2:y2};
- CmdRle(i,
- Left() + Bitmap->X0(), Top() + Bitmap->Y0(),
- Bitmap->Width(), Bitmap->Height(),
- (unsigned char *)Bitmap->Data(0,0),
- NumColors, (unsigned int *)Colors,
- &DirtyArea);
- SendDone++;
- }
- }
- Bitmap->Clean();
- }
-
-#ifdef LIMIT_OSD_REFRESH_RATE
- if(SendDone) {
- static int64_t last_refresh = 0LL;
- int64_t now = cTimeMs::Now();
- if(now - last_refresh < 100) {
- /* too fast refresh rate, delay ... */
- cCondWait::SleepMs(40); /* Can't update faster anyway ... */
-# if 0
- LOGDBG("cXinelibOsd::Flush: OSD refreshing too fast ! (>10Hz) -> Sleeping 50ms");
-# endif
- }
- last_refresh = now;
- }
-#endif
-}
-
-void cXinelibOsd::Refresh(void)
-{
- TRACEF("cXinelibOsd::Refresh");
-
- cMutexLock ml(&m_Lock);
-
- m_Refresh = true;
- CloseWindows();
- CmdSize(m_ExtentWidth, m_ExtentHeight);
- Flush();
- m_Refresh = false;
-}
-
-void cXinelibOsd::Show(void)
-{
- TRACEF("cXinelibOsd::Show");
-
- cMutexLock ml(&m_Lock);
-
- m_IsVisible = true;
- Refresh();
-}
-
-void cXinelibOsd::CloseWindows(void)
-{
- TRACEF("cXinelibOsd::CloseWindows");
-
- if(m_IsVisible) {
- cBitmap *Bitmap;
- for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) {
- LOGOSD("Close OSD %d.%d", Index(), i);
- if (m_WindowHandles[i] < 0)
- LOGMSG("Close unallocated OSD %d.%d @%d", Index(), i, m_WindowHandles[i]);
- CmdClose(i);
- }
- }
-
- if (!m_Refresh)
- CmdFlush();
-}
-
-void cXinelibOsd::Hide(void)
-{
- TRACEF("cXinelibOsd::Hide");
-
- cMutexLock ml(&m_Lock);
-
- CloseWindows();
- m_IsVisible = false;
-}
-
-void cXinelibOsd::Detach(void)
-{
- TRACEF("cXinelibOsd::Detach");
-
- cMutexLock ml(&m_Lock);
-
- Hide();
- m_Device = NULL;
-}
-
-//
-// cXinelibOsdProvider
-//
-
-cXinelibOsdProvider::cXinelibOsdProvider(cXinelibDevice *Device)
-{
- m_Device = Device;
-}
-
-cXinelibOsdProvider::~cXinelibOsdProvider()
-{
- LOGMSG("cXinelibOsdProvider: shutting down !");
-
- cMutexLock ml(&cXinelibOsd::m_Lock);
-
- m_Device = NULL;
-
- if(cXinelibOsd::m_OsdStack.First()) {
- LOGMSG("cXinelibOsdProvider: OSD open while OSD provider shutting down !");
-
- // Detach all OSD instances from device
- cXinelibOsd *osd;
- while(NULL != (osd = cXinelibOsd::m_OsdStack.First())) {
- osd->Detach();
- cXinelibOsd::m_OsdStack.Del(osd, false);
- }
- }
-}
-
-cOsd *cXinelibOsdProvider::CreateOsd(int Left, int Top, uint Level)
-{
- TRACEF("cXinelibOsdProvider::CreateOsd");
-
- cMutexLock ml(&cXinelibOsd::m_Lock);
-
- cXinelibOsd *m_OsdInstance = new cXinelibOsd(m_Device, Left, Top, Level);
-
- // sorted insert
- cXinelibOsd *it = cXinelibOsd::m_OsdStack.First();
- while(it) {
- if(it->m_Layer >= Level) {
- cXinelibOsd::m_OsdStack.Ins(m_OsdInstance, it);
- break;
- }
- it = cXinelibOsd::m_OsdStack.Next(it);
- }
- if(!it)
- cXinelibOsd::m_OsdStack.Add(m_OsdInstance);
-
- LOGOSD("New OSD: index %d, layer %d [now %d OSDs]",
- m_OsdInstance->Index(), Level, cXinelibOsd::m_OsdStack.Count());
-
- if(xc.osd_mixer == OSD_MIXER_NONE) {
- // hide all but top-most OSD
- LOGOSD(" OSD mixer off");
- it = cXinelibOsd::m_OsdStack.Last();
- while(cXinelibOsd::m_OsdStack.Prev(it)) {
- LOGOSD(" -> hide OSD %d", it->Index());
- it->Hide();
- it = cXinelibOsd::m_OsdStack.Prev(it);
- }
-
- } else /*if(xc.osd_mixer > OSD_MIXER_NONE)*/ {
- LOGOSD("OSD mixer on (%d)", xc.osd_mixer);
- it = cXinelibOsd::m_OsdStack.Last();
- while (cXinelibOsd::m_OsdStack.Prev(it)) {
- LOGOSD(" -> show OSD %d", it->Index());
- it->Show();
- it = cXinelibOsd::m_OsdStack.Prev(it);
- }
- }
-
- it->Show();
-
- return m_OsdInstance;
-}
-
-void cXinelibOsdProvider::RefreshOsd(void)
-{
- TRACEF("cXinelibOsdProvider::RefreshOsd");
-
- cMutexLock ml(&cXinelibOsd::m_Lock);
-
- // bottom --> top (draw lower layer OSDs first)
- cXinelibOsd *it = cXinelibOsd::m_OsdStack.Last();
- while(it) {
- it->Refresh();
- it = cXinelibOsd::m_OsdStack.Prev(it);
- }
-}
-
-
-
diff --git a/osd.h b/osd.h
deleted file mode 100644
index 74baf804..00000000
--- a/osd.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * osd.h: Xinelib On Screen Display control
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: osd.h,v 1.5 2007-10-15 00:31:39 phintuka Exp $
- *
- */
-
-#ifndef __XINELIB_OSD_H
-#define __XINELIB_OSD_H
-
-#include <vdr/osd.h>
-
-class cXinelibDevice;
-
-class cXinelibOsdProvider : public cOsdProvider
-{
- protected:
- cXinelibDevice *m_Device;
-
- public:
- cXinelibOsdProvider(cXinelibDevice *Device);
- virtual ~cXinelibOsdProvider();
-
- virtual cOsd *CreateOsd(int Left, int Top, uint Level);
-
- static void RefreshOsd(void);
-
- // VDR < 1.5.9 compability
- virtual cOsd *CreateOsd(int Left, int Top) { return CreateOsd(Left, Top, 0); }
-};
-
-#endif //__XINELIB_OSD_H
-
diff --git a/po/cs_CZ.po b/po/cs_CZ.po
deleted file mode 100644
index 4cd41613..00000000
--- a/po/cs_CZ.po
+++ /dev/null
@@ -1,651 +0,0 @@
-# VDR plugin language source file.
-# Copyright (C) 2007 Klaus Schmidinger <kls@cadsoft.de>
-# This file is distributed under the same license as the VDR package.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Xineliboutput 1.1.0\n"
-"Report-Msgid-Bugs-To: <phintuka@users.sourceforge.net>\n"
-"POT-Creation-Date: 2009-01-07 15:46+0200\n"
-"PO-Revision-Date: 2008-03-20 23:57+0100\n"
-"Last-Translator: Maya <maja373@gmail.com>\n"
-"Language-Team: <vdr@linuxtv.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=iso-8859-2\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Language: Czech\n"
-"X-Poedit-Country: CZECH REPUBLIC\n"
-
-msgid "custom"
-msgstr "u¾ivatelský"
-
-msgid "tiny"
-msgstr "nejmen¹í"
-
-msgid "small"
-msgstr "malý"
-
-msgid "medium"
-msgstr "støední"
-
-msgid "large"
-msgstr "velký"
-
-msgid "huge"
-msgstr "nejvìt¹í"
-
-msgid "automatic"
-msgstr "automaticky"
-
-msgid "default"
-msgstr "výchozí"
-
-msgid "Pan&Scan"
-msgstr "Pan&Scan"
-
-msgid "CenterCutOut"
-msgstr ""
-
-msgid "square"
-msgstr "ètvercový"
-
-msgid "anamorphic"
-msgstr "anamorfní"
-
-msgid "DVB"
-msgstr "DVB"
-
-msgid "off"
-msgstr "vypnuto"
-
-msgid "normal"
-msgstr "normální"
-
-msgid "inverted"
-msgstr "inverzní"
-
-msgid "no audio"
-msgstr "bez zvuku"
-
-msgid "no video"
-msgstr "bez obrazu"
-
-msgid "Off"
-msgstr "vypnuto"
-
-msgid "Goom"
-msgstr "Soutìska"
-
-msgid "Oscilloscope"
-msgstr "Osciloskop"
-
-msgid "FFT Scope"
-msgstr "FFT spektrum"
-
-msgid "FFT Graph"
-msgstr "FFT graf"
-
-msgid "Mono 1.0"
-msgstr "Mono 1.0"
-
-msgid "Stereo 2.0"
-msgstr "Stereo 2.0"
-
-msgid "Headphones 2.0"
-msgstr "Sluchátka 2.0"
-
-msgid "Stereo 2.1"
-msgstr "Stereo 2.1"
-
-msgid "Surround 3.0"
-msgstr "Surround 3.0"
-
-msgid "Surround 4.0"
-msgstr "Surround 4.0"
-
-msgid "Surround 4.1"
-msgstr "Surround 4.1"
-
-msgid "Surround 5.0"
-msgstr "Surround 5.0"
-
-msgid "Surround 5.1"
-msgstr "Surround 5.1"
-
-msgid "Surround 6.0"
-msgstr "Surround 6.0"
-
-msgid "Surround 6.1"
-msgstr "Surround 6.1"
-
-msgid "Surround 7.1"
-msgstr "Surround 7.1"
-
-msgid "Pass Through"
-msgstr "Prùchozí"
-
-msgid "very large"
-msgstr "velmi velký"
-
-msgid "Software"
-msgstr "softwarové"
-
-msgid "Hardware"
-msgstr "hardwarové"
-
-msgid "no"
-msgstr "ne"
-
-msgid "grayscale"
-msgstr "odstíny ¹edi"
-
-msgid "transparent"
-msgstr "prùhledný"
-
-msgid "transparent grayscale"
-msgstr ""
-
-msgid "yes"
-msgstr "ano"
-
-msgid "nearest"
-msgstr ""
-
-msgid "bilinear"
-msgstr ""
-
-msgid "none"
-msgstr ""
-
-msgid "nonref"
-msgstr ""
-
-msgid "bidir"
-msgstr ""
-
-msgid "nonkey"
-msgstr ""
-
-msgid "all"
-msgstr ""
-
-msgid "Frontend initialization failed"
-msgstr "Inicializace rozhraní selhala"
-
-msgid "Server initialization failed"
-msgstr "Inicializace serveru selhala"
-
-msgid "Playlist"
-msgstr "Seznam stop"
-
-msgid "Button$Random"
-msgstr "Náhodné"
-
-msgid "Button$Normal"
-msgstr "Normální"
-
-msgid "Button$Add files"
-msgstr "Pøidat soubory"
-
-msgid "Button$Remove"
-msgstr "Odstranit"
-
-msgid "Button$Sort"
-msgstr "Tøídìní"
-
-msgid "Queued to playlist"
-msgstr "Pøidáno do seznamu stop"
-
-msgid "Random play"
-msgstr "Náhodné pøehrávání"
-
-msgid "Normal play"
-msgstr "Normální pøehrávání"
-
-msgid "Delete image ?"
-msgstr "Smazat obrázek ?"
-
-msgid "Images"
-msgstr "Obrázky"
-
-msgid "Play music"
-msgstr "Pøehrát hudbu"
-
-msgid "Add to playlist"
-msgstr "Pøidat do seznamu stop"
-
-msgid "Play file"
-msgstr "Pøehrát soubor"
-
-msgid "Button$Queue"
-msgstr "Fronta"
-
-msgid "Media"
-msgstr "Média"
-
-msgid "Play file >>"
-msgstr "Pøehrát soubor >>"
-
-msgid "Play music >>"
-msgstr "Pøehrát hudbu >>"
-
-msgid "View images >>"
-msgstr "Prohlí¾et obrázky >>"
-
-msgid "Play remote DVD >>"
-msgstr "Pøehrát vzdálené DVD >>"
-
-msgid "Play DVD disc >>"
-msgstr "Pøehrát DVD >>"
-
-msgid "Play remote CD >>"
-msgstr "Pøehrát vzdálené CD >>"
-
-msgid "Play audio CD >>"
-msgstr "Pøehrát zvukové CD >>"
-
-msgid "Video settings"
-msgstr "Nastavení obrazu"
-
-msgid "Play only audio"
-msgstr "Pøehrávat pouze zvuk"
-
-msgid "Crop letterbox 4:3 to 16:9"
-msgstr "Oøíznout letterbox 4:3 na 16:9"
-
-msgid "Overscan (crop image borders)"
-msgstr "Overscan (oøez okrajù obrazu)"
-
-msgid "Interlaced Field Order"
-msgstr "Poøadí pùlsnímkù"
-
-msgid "Audio settings"
-msgstr "Nastavení zvuku"
-
-msgid "Headphone audio mode"
-msgstr ""
-
-msgid "Audio Compression"
-msgstr ""
-
-msgid "Audio equalizer >>"
-msgstr "Korekce zvuku (ekvalizér) >>"
-
-msgid "Local Frontend"
-msgstr "Lokální rozhraní"
-
-msgid "Aspect ratio"
-msgstr "Pomìr stran"
-
-msgid "Video aspect ratio"
-msgstr "Pomìr stran obrazu"
-
-msgid "On"
-msgstr "zapnuto"
-
-msgid "Deinterlacing"
-msgstr "Odstranìní prokládání"
-
-msgid "Upmix stereo to 5.1"
-msgstr "Pøevzorkovat stereo na 5.1"
-
-msgid "Downmix AC3 to surround"
-msgstr "Pøevzorkovat AC3 na surround"
-
-msgid "Default playlist not found"
-msgstr "Výchozí seznam stop nenalezen"
-
-msgid "Default playlist is not symlink"
-msgstr "Výchozí seznam stop není symbolický odkaz"
-
-msgid "Default playlist not defined"
-msgstr "Výchozí seznam stop není definován"
-
-msgid "Delay"
-msgstr "Zpo¾dìní"
-
-msgid "ms"
-msgstr "ms"
-
-#, c-format
-msgid "xineliboutput: hotkey %s not binded"
-msgstr "xineliboutput: horká klávesa %s není pøiøazena"
-
-msgid "Audio"
-msgstr "Zvuk"
-
-msgid "Speakers"
-msgstr "Reproduktory"
-
-msgid "Volume control"
-msgstr "Ovládání hlasitosti"
-
-msgid "Mix to headphones"
-msgstr ""
-
-msgid "Visualization"
-msgstr "Vizualizace"
-
-msgid " Width"
-msgstr " ©íøka"
-
-msgid "px"
-msgstr "bodù"
-
-msgid " Height"
-msgstr " Vý¹ka"
-
-msgid " Speed"
-msgstr " Rychlost"
-
-msgid "fps"
-msgstr "snímkù/sek."
-
-msgid "Audio Equalizer"
-msgstr "Korekce zvuku"
-
-msgid "Use Video-Out Driver"
-msgstr ""
-
-msgid "vector"
-msgstr ""
-
-msgid "full"
-msgstr ""
-
-msgid "half (top)"
-msgstr ""
-
-msgid "half (bottom)"
-msgstr ""
-
-msgid "Video"
-msgstr "Obraz"
-
-msgid " Autodetect letterbox"
-msgstr " Automaticky detekovat letterbox"
-
-msgid " Soft start"
-msgstr " Postupné zvìt¹ení"
-
-msgid " Crop to"
-msgstr " Oøíznout na"
-
-msgid " Detect subtitles"
-msgstr " Detekovat titulky"
-
-msgid "Software scaling"
-msgstr "Softwarové ¹kálování"
-
-msgid " Change aspect ratio"
-msgstr " Zmìna pomìru stran obrazu"
-
-msgid " Change video size"
-msgstr " Zmìnit velikost obrazu"
-
-msgid " Allow downscaling"
-msgstr " Povolit zmen¹ení"
-
-msgid "Post processing (ffmpeg)"
-msgstr "Post processing (ffmpeg)"
-
-msgid " Quality"
-msgstr " Kvalita"
-
-msgid " Mode"
-msgstr " Mód"
-
-msgid " Method"
-msgstr " Metoda"
-
-msgid " Cheap mode"
-msgstr " Zjednodu¹ený mód"
-
-msgid " Pulldown"
-msgstr ""
-
-msgid " Frame rate"
-msgstr " Snímková rychlost"
-
-msgid " Judder Correction"
-msgstr " Korekce chvìní"
-
-msgid " Use progressive frame flag"
-msgstr ""
-
-msgid " Chroma Filter"
-msgstr ""
-
-msgid "Sharpen / Blur"
-msgstr "Zaostøení / rozmazání"
-
-msgid " Width of the luma matrix"
-msgstr ""
-
-msgid " Height of the luma matrix"
-msgstr ""
-
-msgid " Amount of luma sharpness/blur"
-msgstr ""
-
-msgid " Width of the chroma matrix"
-msgstr ""
-
-msgid " Height of the chroma matrix"
-msgstr ""
-
-msgid " Amount of chroma sharpness/blur"
-msgstr ""
-
-msgid "3D Denoiser"
-msgstr "3D odstranìní ¹umu"
-
-msgid " Spatial luma strength"
-msgstr ""
-
-msgid " Spatial chroma strength"
-msgstr ""
-
-msgid " Temporal strength"
-msgstr ""
-
-msgid "HUE"
-msgstr ""
-
-msgid "Saturation"
-msgstr ""
-
-msgid "Contrast"
-msgstr "Kontrast"
-
-msgid "Brightness"
-msgstr "Jas"
-
-msgid "Sharpness"
-msgstr ""
-
-msgid "Noise Reduction"
-msgstr ""
-
-msgid "Smooth fast forward"
-msgstr "Plynulé pøetáèení"
-
-msgid "Fastest trick speed"
-msgstr ""
-
-msgid "On-Screen Display"
-msgstr "Obrazovkové menu"
-
-msgid "Hide main menu"
-msgstr "Nezobrazovat v hlavním menu"
-
-msgid "Blending method"
-msgstr ""
-
-msgid " Use hardware for low-res video"
-msgstr ""
-
-msgid "Scaling method"
-msgstr ""
-
-msgid "Show all layers"
-msgstr "Zobrazit v¹echny vrstvy"
-
-msgid "Dynamic transparency correction"
-msgstr "Úprava dynamické prùhlednosti"
-
-msgid "Static transparency correction"
-msgstr "Úprava statické prùhlednosti"
-
-msgid "External subtitle size"
-msgstr "Velikost externích titulkù"
-
-msgid "DVB subtitle decoder"
-msgstr ""
-
-msgid "Decoder"
-msgstr "Dekodér"
-
-msgid "Buffer size"
-msgstr "Velikost vyrovnávací pamìti"
-
-msgid " Number of PES packets"
-msgstr " Poèet PES paketù"
-
-msgid "Local Display Frontend"
-msgstr "Lokální zobrazovací rozhraní"
-
-msgid "Use keyboard"
-msgstr "Pou¾ívat klávesnici"
-
-msgid "Driver"
-msgstr "Ovladaè"
-
-msgid "Display address"
-msgstr ""
-
-msgid "Framebuffer device"
-msgstr ""
-
-msgid "Fullscreen mode"
-msgstr "Celoobrazovkový re¾im"
-
-msgid " Window width"
-msgstr " ©íøka okna"
-
-msgid " Window height"
-msgstr " Vý¹ka okna"
-
-msgid "Window aspect"
-msgstr "Pomìr stran okna"
-
-msgid "Scale to window size"
-msgstr "©kálovat do velikosti okna"
-
-msgid "Port"
-msgstr "Port"
-
-msgid "Remote Clients"
-msgstr "Vzdálení klienti"
-
-msgid "Allow remote clients"
-msgstr "Povolit vzdálené klienty"
-
-msgid " Listen port (TCP and broadcast)"
-msgstr ""
-
-msgid " Listen address"
-msgstr ""
-
-msgid " Remote keyboard"
-msgstr ""
-
-msgid " Max number of clients"
-msgstr ""
-
-msgid " PIPE transport"
-msgstr " PIPE transport"
-
-msgid " TCP transport"
-msgstr " TCP transport"
-
-msgid " UDP transport"
-msgstr " UDP transport"
-
-msgid " RTP (multicast) transport"
-msgstr " RTP (multicast) transport"
-
-msgid " Address"
-msgstr " Adresa"
-
-msgid " Port"
-msgstr " Port"
-
-msgid " TTL"
-msgstr ""
-
-msgid " Transmit always on"
-msgstr " Pøenos stále zapnut"
-
-msgid " SAP announcements"
-msgstr ""
-
-msgid " Server announce broadcasts"
-msgstr ""
-
-msgid " HTTP transport for media files"
-msgstr " HTTP transport pro média"
-
-msgid "Additional network services"
-msgstr "Dal¹í sí»ové slu¾by"
-
-msgid "HTTP server"
-msgstr "HTTP server"
-
-msgid "HTTP clients can control VDR"
-msgstr "HTTP klienti mohou ovládat VDR"
-
-msgid "RTSP server"
-msgstr "RTSP server"
-
-msgid "RTSP clients can control VDR"
-msgstr "RTSP klienti mohou ovládat VDR"
-
-msgid "Playlist settings"
-msgstr "Nastavení seznamu stop"
-
-msgid "Show the track number"
-msgstr "Zobrazovat èíslo stopy"
-
-msgid "Show the name of the artist"
-msgstr "Zobrazovat jméno autora"
-
-msgid "Show the name of the album"
-msgstr "Zobrazovat název alba"
-
-msgid "Scan for metainfo"
-msgstr "Vyhledávat metainfo"
-
-msgid "Cache metainfo"
-msgstr "Uchovávat metainfo"
-
-msgid "Arrow keys control DVD playback"
-msgstr ""
-
-msgid "Grayscale"
-msgstr "Odstíny ¹edi"
-
-msgid "Bitmap"
-msgstr "Rastr"
-
-msgid "OSD"
-msgstr "OSD"
-
-msgid "Media Player"
-msgstr "Pøehrávaè médií"
-
-msgid "Test Images"
-msgstr "Zku¹ební obrazce"
-
-msgid "X11/xine-lib output plugin"
-msgstr "X11/xine-lib výstupní plugin"
diff --git a/po/de_DE.po b/po/de_DE.po
deleted file mode 100644
index f1840bbf..00000000
--- a/po/de_DE.po
+++ /dev/null
@@ -1,650 +0,0 @@
-# VDR plugin language source file.
-# Copyright (C) 2007 Klaus Schmidinger <kls@cadsoft.de>
-# This file is distributed under the same license as the VDR package.
-# Udo Richter
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Xineliboutput 1.1.0\n"
-"Report-Msgid-Bugs-To: <phintuka@users.sourceforge.net>\n"
-"POT-Creation-Date: 2009-01-07 15:46+0200\n"
-"PO-Revision-Date: 2007-11-23 10:17+0200\n"
-"Last-Translator: Udo Richter\n"
-"Language-Team: <vdr@linuxtv.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ISO-8859-15\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-msgid "custom"
-msgstr "Benutzerdefiniert"
-
-msgid "tiny"
-msgstr "Winzig"
-
-msgid "small"
-msgstr "Klein"
-
-msgid "medium"
-msgstr "Mittel"
-
-msgid "large"
-msgstr "Groß"
-
-msgid "huge"
-msgstr "Riesig"
-
-msgid "automatic"
-msgstr "Automatik"
-
-msgid "default"
-msgstr "Standard"
-
-msgid "Pan&Scan"
-msgstr "Pan&Scan"
-
-msgid "CenterCutOut"
-msgstr "CenterCutOut"
-
-msgid "square"
-msgstr ""
-
-msgid "anamorphic"
-msgstr ""
-
-msgid "DVB"
-msgstr ""
-
-msgid "off"
-msgstr "Aus"
-
-msgid "normal"
-msgstr "Normal"
-
-msgid "inverted"
-msgstr "Invertiert"
-
-msgid "no audio"
-msgstr "Kein Audio"
-
-msgid "no video"
-msgstr "Kein Video"
-
-msgid "Off"
-msgstr "Aus"
-
-msgid "Goom"
-msgstr "Goom"
-
-msgid "Oscilloscope"
-msgstr "Oszilloskop"
-
-msgid "FFT Scope"
-msgstr "FFT Spektrum"
-
-msgid "FFT Graph"
-msgstr "FFT Graph"
-
-msgid "Mono 1.0"
-msgstr ""
-
-msgid "Stereo 2.0"
-msgstr ""
-
-msgid "Headphones 2.0"
-msgstr ""
-
-msgid "Stereo 2.1"
-msgstr ""
-
-msgid "Surround 3.0"
-msgstr ""
-
-msgid "Surround 4.0"
-msgstr ""
-
-msgid "Surround 4.1"
-msgstr ""
-
-msgid "Surround 5.0"
-msgstr ""
-
-msgid "Surround 5.1"
-msgstr ""
-
-msgid "Surround 6.0"
-msgstr ""
-
-msgid "Surround 6.1"
-msgstr ""
-
-msgid "Surround 7.1"
-msgstr ""
-
-msgid "Pass Through"
-msgstr ""
-
-msgid "very large"
-msgstr ""
-
-msgid "Software"
-msgstr ""
-
-msgid "Hardware"
-msgstr ""
-
-msgid "no"
-msgstr ""
-
-msgid "grayscale"
-msgstr ""
-
-msgid "transparent"
-msgstr ""
-
-msgid "transparent grayscale"
-msgstr ""
-
-msgid "yes"
-msgstr ""
-
-msgid "nearest"
-msgstr ""
-
-msgid "bilinear"
-msgstr ""
-
-msgid "none"
-msgstr ""
-
-msgid "nonref"
-msgstr ""
-
-msgid "bidir"
-msgstr ""
-
-msgid "nonkey"
-msgstr ""
-
-msgid "all"
-msgstr ""
-
-msgid "Frontend initialization failed"
-msgstr "Initialisierung des Frontends fehlgeschlagen"
-
-msgid "Server initialization failed"
-msgstr "Initialisierung des Servers fehlgeschlagen"
-
-msgid "Playlist"
-msgstr "Wiedergabeliste"
-
-msgid "Button$Random"
-msgstr "Zufall"
-
-msgid "Button$Normal"
-msgstr "Normal"
-
-msgid "Button$Add files"
-msgstr "Füge Dateien hinzu"
-
-msgid "Button$Remove"
-msgstr "Entferne"
-
-msgid "Button$Sort"
-msgstr "Sortiere"
-
-msgid "Queued to playlist"
-msgstr "Hänge an Wiedergabeliste an"
-
-msgid "Random play"
-msgstr "Zufallswiedergabe"
-
-msgid "Normal play"
-msgstr "Normale Wiedergabe"
-
-msgid "Delete image ?"
-msgstr "Bild löschen?"
-
-msgid "Images"
-msgstr "Bilder"
-
-msgid "Play music"
-msgstr "Musik abspielen"
-
-msgid "Add to playlist"
-msgstr "Füge zur Wiedergabeliste hinzu"
-
-msgid "Play file"
-msgstr "Datei abspielen"
-
-msgid "Button$Queue"
-msgstr "Warteschlange"
-
-msgid "Media"
-msgstr "Medien"
-
-msgid "Play file >>"
-msgstr "Datei abspielen >>"
-
-msgid "Play music >>"
-msgstr "Musik abspielen >>"
-
-msgid "View images >>"
-msgstr "Bilder ansehen >>"
-
-msgid "Play remote DVD >>"
-msgstr "Entfernte DVD abspielen >>"
-
-msgid "Play DVD disc >>"
-msgstr "DVD abspielen >>"
-
-msgid "Play remote CD >>"
-msgstr "Entfernte CD abspielen >>"
-
-msgid "Play audio CD >>"
-msgstr "Musik-CD abspielen >>"
-
-msgid "Video settings"
-msgstr "Video-Einstellungen"
-
-msgid "Play only audio"
-msgstr "Nur Audio spielen"
-
-msgid "Crop letterbox 4:3 to 16:9"
-msgstr "Schneide letterbox 4:3 zu 16:9"
-
-msgid "Overscan (crop image borders)"
-msgstr "Overscan (Bildränder abschneiden)"
-
-msgid "Interlaced Field Order"
-msgstr "Interlaced Halbbild-Reihenfolge"
-
-msgid "Audio settings"
-msgstr "Audio-Einstellungen"
-
-msgid "Headphone audio mode"
-msgstr ""
-
-msgid "Audio Compression"
-msgstr "Audio-Komprimierung"
-
-msgid "Audio equalizer >>"
-msgstr "Audio-Equalizer >>"
-
-msgid "Local Frontend"
-msgstr "Lokale Anzeige"
-
-msgid "Aspect ratio"
-msgstr "Seitenverhältnis"
-
-msgid "Video aspect ratio"
-msgstr ""
-
-msgid "On"
-msgstr ""
-
-msgid "Deinterlacing"
-msgstr "Deinterlacing"
-
-msgid "Upmix stereo to 5.1"
-msgstr "Stereo zu 5.1 hoch mischen"
-
-msgid "Downmix AC3 to surround"
-msgstr "AC3 zu Surround herunter mischen"
-
-msgid "Default playlist not found"
-msgstr ""
-
-msgid "Default playlist is not symlink"
-msgstr ""
-
-msgid "Default playlist not defined"
-msgstr ""
-
-msgid "Delay"
-msgstr "Verzögerung"
-
-msgid "ms"
-msgstr "ms"
-
-#, c-format
-msgid "xineliboutput: hotkey %s not binded"
-msgstr ""
-
-msgid "Audio"
-msgstr "Audio"
-
-msgid "Speakers"
-msgstr "Lautsprecher"
-
-msgid "Volume control"
-msgstr ""
-
-msgid "Mix to headphones"
-msgstr ""
-
-msgid "Visualization"
-msgstr "Visualisierung"
-
-msgid " Width"
-msgstr " Breite"
-
-msgid "px"
-msgstr "px"
-
-msgid " Height"
-msgstr " Höhe"
-
-msgid " Speed"
-msgstr " Bildrate"
-
-msgid "fps"
-msgstr ""
-
-msgid "Audio Equalizer"
-msgstr "Audio Equalizer"
-
-msgid "Use Video-Out Driver"
-msgstr ""
-
-msgid "vector"
-msgstr ""
-
-msgid "full"
-msgstr ""
-
-msgid "half (top)"
-msgstr ""
-
-msgid "half (bottom)"
-msgstr ""
-
-msgid "Video"
-msgstr "Video"
-
-msgid " Autodetect letterbox"
-msgstr " Letterbox automatisch erkennen"
-
-msgid " Soft start"
-msgstr " Weich starten"
-
-msgid " Crop to"
-msgstr " Schneide auf"
-
-msgid " Detect subtitles"
-msgstr " Erkenne Untertitel"
-
-msgid "Software scaling"
-msgstr ""
-
-msgid " Change aspect ratio"
-msgstr ""
-
-msgid " Change video size"
-msgstr ""
-
-msgid " Allow downscaling"
-msgstr " Verkleinern zulassen"
-
-msgid "Post processing (ffmpeg)"
-msgstr "Nachbearbeitung (ffmpeg)"
-
-msgid " Quality"
-msgstr " Qualität"
-
-msgid " Mode"
-msgstr " Modus"
-
-msgid " Method"
-msgstr " Methode"
-
-msgid " Cheap mode"
-msgstr " einfacher Modus"
-
-msgid " Pulldown"
-msgstr " Pulldown"
-
-msgid " Frame rate"
-msgstr " Bildrate"
-
-msgid " Judder Correction"
-msgstr " Ruckel-Korrektur"
-
-msgid " Use progressive frame flag"
-msgstr " Nutze progressive frame flag"
-
-msgid " Chroma Filter"
-msgstr " Chrominanz-Filter"
-
-msgid "Sharpen / Blur"
-msgstr ""
-
-msgid " Width of the luma matrix"
-msgstr ""
-
-msgid " Height of the luma matrix"
-msgstr ""
-
-msgid " Amount of luma sharpness/blur"
-msgstr ""
-
-msgid " Width of the chroma matrix"
-msgstr ""
-
-msgid " Height of the chroma matrix"
-msgstr ""
-
-msgid " Amount of chroma sharpness/blur"
-msgstr ""
-
-msgid "3D Denoiser"
-msgstr ""
-
-msgid " Spatial luma strength"
-msgstr ""
-
-msgid " Spatial chroma strength"
-msgstr ""
-
-msgid " Temporal strength"
-msgstr ""
-
-msgid "HUE"
-msgstr "Farbton"
-
-msgid "Saturation"
-msgstr "Sättigung"
-
-msgid "Contrast"
-msgstr "Kontrast"
-
-msgid "Brightness"
-msgstr "Helligkeit"
-
-msgid "Sharpness"
-msgstr ""
-
-msgid "Noise Reduction"
-msgstr ""
-
-msgid "Smooth fast forward"
-msgstr ""
-
-msgid "Fastest trick speed"
-msgstr ""
-
-msgid "On-Screen Display"
-msgstr "On-Screen Display"
-
-msgid "Hide main menu"
-msgstr "Verstecke Hauptmenü"
-
-msgid "Blending method"
-msgstr ""
-
-msgid " Use hardware for low-res video"
-msgstr ""
-
-msgid "Scaling method"
-msgstr ""
-
-msgid "Show all layers"
-msgstr ""
-
-msgid "Dynamic transparency correction"
-msgstr "Dynamische Transparenz-Korrektur"
-
-msgid "Static transparency correction"
-msgstr "Statische Transparenz-Korrektur"
-
-msgid "External subtitle size"
-msgstr "Untertitel größe"
-
-msgid "DVB subtitle decoder"
-msgstr ""
-
-msgid "Decoder"
-msgstr "Dekoder"
-
-msgid "Buffer size"
-msgstr "Puffergröße"
-
-msgid " Number of PES packets"
-msgstr " Anzahl PES-Pakete"
-
-msgid "Local Display Frontend"
-msgstr "Lokale Bildschirmanzeige"
-
-msgid "Use keyboard"
-msgstr "Tastatur benutzen"
-
-msgid "Driver"
-msgstr "Treiber"
-
-msgid "Display address"
-msgstr "Bildschirm-Adresse"
-
-msgid "Framebuffer device"
-msgstr "Framebuffer-Device"
-
-msgid "Fullscreen mode"
-msgstr "Vollbild-Modus"
-
-msgid " Window width"
-msgstr " Fensterbreite"
-
-msgid " Window height"
-msgstr " Fensterhöhe"
-
-msgid "Window aspect"
-msgstr "Fenster-Seitenverhältnis"
-
-msgid "Scale to window size"
-msgstr "Skaliere auf Fenster-Größe"
-
-msgid "Port"
-msgstr "Port"
-
-msgid "Remote Clients"
-msgstr "Entfernte Clients"
-
-msgid "Allow remote clients"
-msgstr "Erlaube entfernte Clients"
-
-msgid " Listen port (TCP and broadcast)"
-msgstr " Empfangender Port (TCP und Broadcast)"
-
-msgid " Listen address"
-msgstr ""
-
-msgid " Remote keyboard"
-msgstr " Tastaturfernsteuerung"
-
-msgid " Max number of clients"
-msgstr ""
-
-msgid " PIPE transport"
-msgstr " Pipe-Übertragung"
-
-msgid " TCP transport"
-msgstr " TCP-Übertragung"
-
-msgid " UDP transport"
-msgstr " UDP-Übertragung"
-
-msgid " RTP (multicast) transport"
-msgstr " RTP (multicast) Übertragung"
-
-msgid " Address"
-msgstr " Multicast-Adresse"
-
-msgid " Port"
-msgstr " Multicast-Port"
-
-msgid " TTL"
-msgstr " Multicast-TTL"
-
-msgid " Transmit always on"
-msgstr " Immer senden"
-
-msgid " SAP announcements"
-msgstr " SAP-Ankündigungen"
-
-msgid " Server announce broadcasts"
-msgstr " Server-Bekanntmachung Broadcast"
-
-msgid " HTTP transport for media files"
-msgstr " HTTP-Verbindung für Medien-Dateien"
-
-msgid "Additional network services"
-msgstr "Zusätzliche Netzwerk-Services"
-
-msgid "HTTP server"
-msgstr "HTTP-Server"
-
-msgid "HTTP clients can control VDR"
-msgstr "HTTP-Clients können VDR kontrollieren"
-
-msgid "RTSP server"
-msgstr "RTSP-Server"
-
-msgid "RTSP clients can control VDR"
-msgstr "RTSP-Clients können VDR kontrollieren"
-
-msgid "Playlist settings"
-msgstr ""
-
-msgid "Show the track number"
-msgstr ""
-
-msgid "Show the name of the artist"
-msgstr ""
-
-msgid "Show the name of the album"
-msgstr ""
-
-msgid "Scan for metainfo"
-msgstr ""
-
-msgid "Cache metainfo"
-msgstr ""
-
-msgid "Arrow keys control DVD playback"
-msgstr ""
-
-msgid "Grayscale"
-msgstr "Graustufen"
-
-msgid "Bitmap"
-msgstr "Bitmap"
-
-msgid "OSD"
-msgstr ""
-
-msgid "Media Player"
-msgstr "Medien..."
-
-msgid "Test Images"
-msgstr "Testbilder"
-
-msgid "X11/xine-lib output plugin"
-msgstr "X11/xine-lib Ausgabe-Plugin"
diff --git a/po/fi_FI.po b/po/fi_FI.po
deleted file mode 100644
index e3c8a9b9..00000000
--- a/po/fi_FI.po
+++ /dev/null
@@ -1,651 +0,0 @@
-# VDR plugin language source file.
-# Copyright (C) 2007 Klaus Schmidinger <kls@cadsoft.de>
-# This file is distributed under the same license as the VDR package.
-# Petri Hintukainen
-# Rolf Ahrenberg
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Xineliboutput 1.1.0\n"
-"Report-Msgid-Bugs-To: <phintuka@users.sourceforge.net>\n"
-"POT-Creation-Date: 2009-01-07 15:46+0200\n"
-"PO-Revision-Date: 2008-10-06 11:19+0200\n"
-"Last-Translator: Rolf Ahrenberg\n"
-"Language-Team: <vdr@linuxtv.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-msgid "custom"
-msgstr "oma"
-
-msgid "tiny"
-msgstr "olematon"
-
-msgid "small"
-msgstr "pieni"
-
-msgid "medium"
-msgstr "keskikokoinen"
-
-msgid "large"
-msgstr "suuri"
-
-msgid "huge"
-msgstr "valtava"
-
-msgid "automatic"
-msgstr "automaattinen"
-
-msgid "default"
-msgstr "oletus"
-
-msgid "Pan&Scan"
-msgstr "Pan&Scan"
-
-msgid "CenterCutOut"
-msgstr "CenterCutOut"
-
-msgid "square"
-msgstr "neliö"
-
-msgid "anamorphic"
-msgstr "anamorfinen"
-
-msgid "DVB"
-msgstr "DVB"
-
-msgid "off"
-msgstr "ei käytössä"
-
-msgid "normal"
-msgstr "normaali"
-
-msgid "inverted"
-msgstr "käänteinen"
-
-msgid "no audio"
-msgstr "ei ääntä"
-
-msgid "no video"
-msgstr "ei kuvaa"
-
-msgid "Off"
-msgstr "ei käytössä"
-
-msgid "Goom"
-msgstr "Goom"
-
-msgid "Oscilloscope"
-msgstr "oskilloskooppi"
-
-msgid "FFT Scope"
-msgstr "spektri"
-
-msgid "FFT Graph"
-msgstr "spektrogrammi"
-
-msgid "Mono 1.0"
-msgstr "Mono 1.0"
-
-msgid "Stereo 2.0"
-msgstr "Stereo 2.0"
-
-msgid "Headphones 2.0"
-msgstr "Kuulokkeet 2.0"
-
-msgid "Stereo 2.1"
-msgstr "Stereo 2.1"
-
-msgid "Surround 3.0"
-msgstr "Surround 3.0"
-
-msgid "Surround 4.0"
-msgstr "Surround 4.0"
-
-msgid "Surround 4.1"
-msgstr "Surround 4.1"
-
-msgid "Surround 5.0"
-msgstr "Surround 5.0"
-
-msgid "Surround 5.1"
-msgstr "Surround 5.1"
-
-msgid "Surround 6.0"
-msgstr "Surround 6.0"
-
-msgid "Surround 6.1"
-msgstr "Surround 6.1"
-
-msgid "Surround 7.1"
-msgstr "Surround 7.1"
-
-msgid "Pass Through"
-msgstr "läpivienti"
-
-msgid "very large"
-msgstr "erittäin suuri"
-
-msgid "Software"
-msgstr "ohjelmallisesti"
-
-msgid "Hardware"
-msgstr "laitteistolla"
-
-msgid "no"
-msgstr "ei"
-
-msgid "grayscale"
-msgstr "harmaasävy"
-
-msgid "transparent"
-msgstr "läpinäkyvä"
-
-msgid "transparent grayscale"
-msgstr "läpinäkyvä harmaasävy"
-
-msgid "yes"
-msgstr "kyllä"
-
-msgid "nearest"
-msgstr "lähin"
-
-msgid "bilinear"
-msgstr "bilineaarinen"
-
-msgid "none"
-msgstr "ei"
-
-msgid "nonref"
-msgstr "ei referoituja"
-
-msgid "bidir"
-msgstr "vain B-ruudut"
-
-msgid "nonkey"
-msgstr "ei avainruutuja"
-
-msgid "all"
-msgstr "kaikki"
-
-msgid "Frontend initialization failed"
-msgstr "Näyttölaitteen alustus epäonnistui"
-
-msgid "Server initialization failed"
-msgstr "Palvelimen käynnistys epäonnistui"
-
-msgid "Playlist"
-msgstr "Soittolista"
-
-msgid "Button$Random"
-msgstr "Satunnaistoisto"
-
-msgid "Button$Normal"
-msgstr "Normaali toisto"
-
-msgid "Button$Add files"
-msgstr "Lisää"
-
-msgid "Button$Remove"
-msgstr "Poista"
-
-msgid "Button$Sort"
-msgstr "Järjestä"
-
-msgid "Queued to playlist"
-msgstr "Lisätty soittolistalle"
-
-msgid "Random play"
-msgstr "Satunnaistoisto"
-
-msgid "Normal play"
-msgstr "Normaali toisto"
-
-msgid "Delete image ?"
-msgstr "Poistetaanko kuva ?"
-
-msgid "Images"
-msgstr "Kuvat"
-
-msgid "Play music"
-msgstr "Toista musiikkia"
-
-msgid "Add to playlist"
-msgstr "Lisää soittolistalle"
-
-msgid "Play file"
-msgstr "Toista tiedosto"
-
-msgid "Button$Queue"
-msgstr "Soittolistalle"
-
-msgid "Media"
-msgstr "Media"
-
-msgid "Play file >>"
-msgstr "Toista tiedosto >>"
-
-msgid "Play music >>"
-msgstr "Toista musiikkia >>"
-
-msgid "View images >>"
-msgstr "Katsele kuvia >>"
-
-msgid "Play remote DVD >>"
-msgstr "Toista DVD-levy etäkoneesta >>"
-
-msgid "Play DVD disc >>"
-msgstr "Toista DVD-levy >>"
-
-msgid "Play remote CD >>"
-msgstr "Toista CD-levy etäkoneesta >>"
-
-msgid "Play audio CD >>"
-msgstr "Toista CD-levy >>"
-
-msgid "Video settings"
-msgstr "Videoasetukset"
-
-msgid "Play only audio"
-msgstr "Toista pelkkä ääni"
-
-msgid "Crop letterbox 4:3 to 16:9"
-msgstr "Leikkaa 4:3-letterbox 16:9:ksi"
-
-msgid "Overscan (crop image borders)"
-msgstr "Leikkaa kuvan reunoja (overscan)"
-
-msgid "Interlaced Field Order"
-msgstr "Lomitettujen kenttien järjestys"
-
-msgid "Audio settings"
-msgstr "Ääniasetukset"
-
-msgid "Headphone audio mode"
-msgstr "Kuulokkeiden äänimoodi"
-
-msgid "Audio Compression"
-msgstr "Voimista hiljaisia ääniä"
-
-msgid "Audio equalizer >>"
-msgstr "Taajuuskorjain >>"
-
-msgid "Local Frontend"
-msgstr "Paikallinen näyttö"
-
-msgid "Aspect ratio"
-msgstr "Kuvasuhde"
-
-msgid "Video aspect ratio"
-msgstr "Videon kuvasuhde"
-
-msgid "On"
-msgstr "Käytössä"
-
-msgid "Deinterlacing"
-msgstr "Lomituksen poisto"
-
-msgid "Upmix stereo to 5.1"
-msgstr "Miksaa stereoääni 5.1-kanavaiseksi"
-
-msgid "Downmix AC3 to surround"
-msgstr "Miksaa AC3-ääni surroundiksi"
-
-msgid "Default playlist not found"
-msgstr "Oletussoittolistaa ei löydetä"
-
-msgid "Default playlist is not symlink"
-msgstr "Oletussoittolista ei ole symbolinen linkki"
-
-msgid "Default playlist not defined"
-msgstr "Oletussoittolistaa ei ole määritelty"
-
-msgid "Delay"
-msgstr "Viive"
-
-msgid "ms"
-msgstr "ms"
-
-#, c-format
-msgid "xineliboutput: hotkey %s not binded"
-msgstr "xineliboutput: pikanäppäintä %s ei ole kytketty"
-
-msgid "Audio"
-msgstr "Ääni"
-
-msgid "Speakers"
-msgstr "Kaiuttimet"
-
-msgid "Volume control"
-msgstr "Äänenvoimakkuuden säätö"
-
-msgid "Mix to headphones"
-msgstr "Miksaa kuulokkeille"
-
-msgid "Visualization"
-msgstr "Visualisointi"
-
-msgid " Width"
-msgstr " Leveys"
-
-msgid "px"
-msgstr "px"
-
-msgid " Height"
-msgstr " Korkeus"
-
-msgid " Speed"
-msgstr " Nopeus"
-
-msgid "fps"
-msgstr "fps"
-
-msgid "Audio Equalizer"
-msgstr "Taajuuskorjain"
-
-msgid "Use Video-Out Driver"
-msgstr "videoajuri"
-
-msgid "vector"
-msgstr "vektoroitu"
-
-msgid "full"
-msgstr "täysi"
-
-msgid "half (top)"
-msgstr "alempi puolisko"
-
-msgid "half (bottom)"
-msgstr "ylempi puolisko"
-
-msgid "Video"
-msgstr "Kuva"
-
-msgid " Autodetect letterbox"
-msgstr " Tunnista letterbox automaattisesti"
-
-msgid " Soft start"
-msgstr " Portaittainen aloitus"
-
-msgid " Crop to"
-msgstr " Leikkaa kokoon"
-
-msgid " Detect subtitles"
-msgstr " Huomioi tekstitys"
-
-msgid "Software scaling"
-msgstr "Skaalaa ohjelmistolla"
-
-msgid " Change aspect ratio"
-msgstr " Muuta kuvasuhdetta"
-
-msgid " Change video size"
-msgstr " Muuta videokuvan kokoa"
-
-msgid " Allow downscaling"
-msgstr " Salli skaalaus pienemmäksi"
-
-msgid "Post processing (ffmpeg)"
-msgstr "Käytä jälkikäsittelyä (ffmpeg)"
-
-msgid " Quality"
-msgstr " Laatu"
-
-msgid " Mode"
-msgstr " Moodi"
-
-msgid " Method"
-msgstr " Menetelmä"
-
-msgid " Cheap mode"
-msgstr " Käytä Cheap-moodia"
-
-msgid " Pulldown"
-msgstr " Pulldown-moodi"
-
-msgid " Frame rate"
-msgstr " Ruudunpäivitys"
-
-msgid " Judder Correction"
-msgstr " Käytä tärinänkorjausta"
-
-msgid " Use progressive frame flag"
-msgstr " Tunnista progressiivinen kuva"
-
-msgid " Chroma Filter"
-msgstr " Käytä Chroma-suodinta"
-
-msgid "Sharpen / Blur"
-msgstr "Terävöinti / sumennus"
-
-msgid " Width of the luma matrix"
-msgstr " Luma-matriisin leveys"
-
-msgid " Height of the luma matrix"
-msgstr " Luma-matriisin korkeus"
-
-msgid " Amount of luma sharpness/blur"
-msgstr " Luma-terävöinti/-sumennus"
-
-msgid " Width of the chroma matrix"
-msgstr " Chroma-matriisin leveys"
-
-msgid " Height of the chroma matrix"
-msgstr " Chroma-matriisin korkeus"
-
-msgid " Amount of chroma sharpness/blur"
-msgstr " Chroma-terävöinti/-sumennus"
-
-msgid "3D Denoiser"
-msgstr "3D-kohinanpoisto"
-
-msgid " Spatial luma strength"
-msgstr " Luman tilavoimakkuus"
-
-msgid " Spatial chroma strength"
-msgstr " Chroman tilavoimakkuus"
-
-msgid " Temporal strength"
-msgstr " Ajallinen voimakkuus"
-
-msgid "HUE"
-msgstr "Värisävy"
-
-msgid "Saturation"
-msgstr "Saturaatio"
-
-msgid "Contrast"
-msgstr "Kontrasti"
-
-msgid "Brightness"
-msgstr "Kirkkaus"
-
-msgid "Sharpness"
-msgstr "Terävöinti"
-
-msgid "Noise Reduction"
-msgstr "Kohinanpoisto"
-
-msgid "Smooth fast forward"
-msgstr "Tasainen kuvakelaus"
-
-msgid "Fastest trick speed"
-msgstr "Suurin kelausnopeus"
-
-msgid "On-Screen Display"
-msgstr "Kuvaruutunäyttö"
-
-msgid "Hide main menu"
-msgstr "Piilota valinta päävalikossa"
-
-msgid "Blending method"
-msgstr "Piirtotapa"
-
-msgid " Use hardware for low-res video"
-msgstr " Laitteisto matalaresoluutioisella videolla"
-
-msgid "Scaling method"
-msgstr "Skaalaustapa"
-
-msgid "Show all layers"
-msgstr "Näytä kaikki kerrokset"
-
-msgid "Dynamic transparency correction"
-msgstr "Dynaaminen läpinäkyvyyden korjaus"
-
-msgid "Static transparency correction"
-msgstr "Läpinäkyvyyden korjaus"
-
-msgid "External subtitle size"
-msgstr "Erillisen tekstityksen koko"
-
-msgid "DVB subtitle decoder"
-msgstr "DVB-tekstityksen dekooderi"
-
-msgid "Decoder"
-msgstr "Dekooderi"
-
-msgid "Buffer size"
-msgstr "Puskurin koko"
-
-msgid " Number of PES packets"
-msgstr " PES-pakettien lukumäärä"
-
-msgid "Local Display Frontend"
-msgstr "Paikallinen näyttö"
-
-msgid "Use keyboard"
-msgstr "Käytä näppäimistöä"
-
-msgid "Driver"
-msgstr "Ohjain"
-
-msgid "Display address"
-msgstr "Näytön osoite"
-
-msgid "Framebuffer device"
-msgstr "Framebuffer-laite"
-
-msgid "Fullscreen mode"
-msgstr "Kokoruututila"
-
-msgid " Window width"
-msgstr " Ikkunan leveys"
-
-msgid " Window height"
-msgstr " Ikkunan korkeus"
-
-msgid "Window aspect"
-msgstr "Ikkunan kuvasuhde"
-
-msgid "Scale to window size"
-msgstr "Skaalaa ikkunan kokoiseksi"
-
-msgid "Port"
-msgstr "Portti"
-
-msgid "Remote Clients"
-msgstr "Etäkäyttö"
-
-msgid "Allow remote clients"
-msgstr "Salli etäkäyttö"
-
-msgid " Listen port (TCP and broadcast)"
-msgstr " Kuuntele TCP-porttia"
-
-msgid " Listen address"
-msgstr " Kuuntele osoitteessa"
-
-msgid " Remote keyboard"
-msgstr " Käytä etänäppäimistöä"
-
-msgid " Max number of clients"
-msgstr " Asiakkaiden maksimimäärä"
-
-msgid " PIPE transport"
-msgstr " PIPE-siirto"
-
-msgid " TCP transport"
-msgstr " TCP-siirto"
-
-msgid " UDP transport"
-msgstr " UDP-siirto"
-
-msgid " RTP (multicast) transport"
-msgstr " RTP (multicast) -siirto"
-
-msgid " Address"
-msgstr " Osoite"
-
-msgid " Port"
-msgstr " Portti"
-
-msgid " TTL"
-msgstr " TTL-aika"
-
-msgid " Transmit always on"
-msgstr " Pidä lähetys aina päällä"
-
-msgid " SAP announcements"
-msgstr " SAP-ilmoitukset"
-
-msgid " Server announce broadcasts"
-msgstr " Palvelimen broadcast-ilmoitukset"
-
-msgid " HTTP transport for media files"
-msgstr " HTTP -siirto mediatiedostoille"
-
-msgid "Additional network services"
-msgstr "Muut verkkopalvelut"
-
-msgid "HTTP server"
-msgstr "HTTP-palvelin"
-
-msgid "HTTP clients can control VDR"
-msgstr "Anna HTTP-asiakkaiden ohjata VDR:ää"
-
-msgid "RTSP server"
-msgstr "RTSP-palvelin"
-
-msgid "RTSP clients can control VDR"
-msgstr "Anna RTSP-asiakkaiden ohjata VDR:ää"
-
-msgid "Playlist settings"
-msgstr "Soittolistan asetukset"
-
-msgid "Show the track number"
-msgstr "Näytä raidan numero"
-
-msgid "Show the name of the artist"
-msgstr "Näytä esittäjän nimi"
-
-msgid "Show the name of the album"
-msgstr "Näytä levyn nimi"
-
-msgid "Scan for metainfo"
-msgstr "Tutki kappaleiden metatiedot"
-
-msgid "Cache metainfo"
-msgstr "Tallenna metatieto"
-
-msgid "Arrow keys control DVD playback"
-msgstr "Ohjaa nuolinäppäimillä DVD-toistoa"
-
-msgid "Grayscale"
-msgstr "Harmaasävy"
-
-msgid "Bitmap"
-msgstr "Bittikartta"
-
-msgid "OSD"
-msgstr "Kuvaruutunäyttö"
-
-msgid "Media Player"
-msgstr "Mediasoitin"
-
-msgid "Test Images"
-msgstr "Testikuvat"
-
-msgid "X11/xine-lib output plugin"
-msgstr "X11/xine-lib näyttölaite"
diff --git a/po/it_IT.po b/po/it_IT.po
deleted file mode 100644
index 9276bd93..00000000
--- a/po/it_IT.po
+++ /dev/null
@@ -1,653 +0,0 @@
-# VDR plugin language source file.
-# Copyright (C) 2007 Klaus Schmidinger <kls@cadsoft.de>
-# This file is distributed under the same license as the VDR package.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Xineliboutput 1.1.0\n"
-"Report-Msgid-Bugs-To: <phintuka@users.sourceforge.net>\n"
-"POT-Creation-Date: 2009-01-07 15:46+0200\n"
-"PO-Revision-Date: 2009-02-08 20:09+0100\n"
-"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
-"Language-Team: <vdr@linuxtv.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Language: Italian\n"
-"X-Poedit-Country: ITALY\n"
-"X-Poedit-SourceCharset: utf-8\n"
-
-msgid "custom"
-msgstr "personalizza"
-
-msgid "tiny"
-msgstr "molto piccolo"
-
-msgid "small"
-msgstr "piccolo"
-
-msgid "medium"
-msgstr "medio"
-
-msgid "large"
-msgstr "grande"
-
-msgid "huge"
-msgstr "enorme"
-
-msgid "automatic"
-msgstr "automatica"
-
-msgid "default"
-msgstr "predefinita"
-
-msgid "Pan&Scan"
-msgstr "Pan&Scan"
-
-msgid "CenterCutOut"
-msgstr "CenterCutOut"
-
-msgid "square"
-msgstr "quadrato"
-
-msgid "anamorphic"
-msgstr "anamorfico"
-
-msgid "DVB"
-msgstr "DVB"
-
-msgid "off"
-msgstr "spento"
-
-msgid "normal"
-msgstr "normale"
-
-msgid "inverted"
-msgstr "invertito"
-
-msgid "no audio"
-msgstr "niente audio"
-
-msgid "no video"
-msgstr "niente video"
-
-msgid "Off"
-msgstr "Spento"
-
-msgid "Goom"
-msgstr "Goom"
-
-msgid "Oscilloscope"
-msgstr "Oscilloscopio"
-
-msgid "FFT Scope"
-msgstr "Spettro FFT"
-
-msgid "FFT Graph"
-msgstr "Grafico FFT"
-
-msgid "Mono 1.0"
-msgstr "Mono 1.0"
-
-msgid "Stereo 2.0"
-msgstr "Stereo 2.0"
-
-msgid "Headphones 2.0"
-msgstr "Cuffie 2.0"
-
-msgid "Stereo 2.1"
-msgstr "Stereo 2.1"
-
-msgid "Surround 3.0"
-msgstr "Surround 3.0"
-
-msgid "Surround 4.0"
-msgstr "Surround 4.0"
-
-msgid "Surround 4.1"
-msgstr "Surround 4.1"
-
-msgid "Surround 5.0"
-msgstr "Surround 5.0"
-
-msgid "Surround 5.1"
-msgstr "Surround 5.1"
-
-msgid "Surround 6.0"
-msgstr "Surround 6.0"
-
-msgid "Surround 6.1"
-msgstr "Surround 6.1"
-
-msgid "Surround 7.1"
-msgstr "Surround 7.1"
-
-msgid "Pass Through"
-msgstr "Passa attraverso"
-
-msgid "very large"
-msgstr "molto grande"
-
-msgid "Software"
-msgstr "Software"
-
-msgid "Hardware"
-msgstr "Hardware"
-
-msgid "no"
-msgstr "no"
-
-msgid "grayscale"
-msgstr "scala di grigi"
-
-msgid "transparent"
-msgstr "trasparente"
-
-msgid "transparent grayscale"
-msgstr "scala di grigi trasparente"
-
-msgid "yes"
-msgstr "sì"
-
-msgid "nearest"
-msgstr "più vicino"
-
-msgid "bilinear"
-msgstr "bilineare"
-
-msgid "none"
-msgstr "nessuno"
-
-msgid "nonref"
-msgstr "nonref"
-
-msgid "bidir"
-msgstr "nonref"
-
-msgid "nonkey"
-msgstr "nonref"
-
-msgid "all"
-msgstr "tutti"
-
-msgid "Frontend initialization failed"
-msgstr "Inizializzazione frontend fallita"
-
-msgid "Server initialization failed"
-msgstr "Inizializzazione server fallita"
-
-msgid "Playlist"
-msgstr "Lista esecuzione"
-
-msgid "Button$Random"
-msgstr "Casuale"
-
-msgid "Button$Normal"
-msgstr "Normale"
-
-msgid "Button$Add files"
-msgstr "Aggiungi files"
-
-msgid "Button$Remove"
-msgstr "Rimuovi"
-
-msgid "Button$Sort"
-msgstr "Ordina"
-
-msgid "Queued to playlist"
-msgstr "Accoda alla lista esecuzione"
-
-msgid "Random play"
-msgstr "Riproduzione casuale"
-
-msgid "Normal play"
-msgstr "Riproduzione normale"
-
-msgid "Delete image ?"
-msgstr "Eliminare immagine ?"
-
-msgid "Images"
-msgstr "Immagini"
-
-msgid "Play music"
-msgstr "Riproduci musica"
-
-msgid "Add to playlist"
-msgstr "Aggiungi alla lista esec."
-
-msgid "Play file"
-msgstr "Riproduci file"
-
-msgid "Button$Queue"
-msgstr "Coda"
-
-msgid "Media"
-msgstr "Media"
-
-msgid "Play file >>"
-msgstr "Riproduci file >>"
-
-msgid "Play music >>"
-msgstr "Riproduci musica >>"
-
-msgid "View images >>"
-msgstr "Visualizza immagini >>"
-
-msgid "Play remote DVD >>"
-msgstr "Riproduci DVD remoto >>"
-
-msgid "Play DVD disc >>"
-msgstr "Riproduci disco DVD >>"
-
-msgid "Play remote CD >>"
-msgstr "Riproduci CD remoto >>"
-
-msgid "Play audio CD >>"
-msgstr "Riproduci CD audio >>"
-
-msgid "Video settings"
-msgstr "Impostazioni video"
-
-msgid "Play only audio"
-msgstr "Riproduci solo audio"
-
-msgid "Crop letterbox 4:3 to 16:9"
-msgstr "Ritaglia letterbox 4:3 a 16:9"
-
-msgid "Overscan (crop image borders)"
-msgstr "Overscan (ritaglia bordi immagine)"
-
-msgid "Interlaced Field Order"
-msgstr "Ordine campo interlacciato"
-
-msgid "Audio settings"
-msgstr "Impostazioni audio"
-
-msgid "Headphone audio mode"
-msgstr "Modalità cuffie audio"
-
-msgid "Audio Compression"
-msgstr "Compressione audio"
-
-msgid "Audio equalizer >>"
-msgstr "Equalizzatore audio >>"
-
-msgid "Local Frontend"
-msgstr "Frontend locale"
-
-msgid "Aspect ratio"
-msgstr "Formato"
-
-msgid "Video aspect ratio"
-msgstr "Formato video"
-
-msgid "On"
-msgstr "Attivo"
-
-msgid "Deinterlacing"
-msgstr "Deinterlacciamento"
-
-msgid "Upmix stereo to 5.1"
-msgstr "Suono da Stereo a 5.1"
-
-msgid "Downmix AC3 to surround"
-msgstr "Suono da AC3 a Surround"
-
-msgid "Default playlist not found"
-msgstr "Lista esec. predefinita non trovata"
-
-msgid "Default playlist is not symlink"
-msgstr "La lista esec. predefinita non è un link simbolico"
-
-msgid "Default playlist not defined"
-msgstr "Lista esec. predefinita non definita"
-
-msgid "Delay"
-msgstr "Ritardo"
-
-msgid "ms"
-msgstr "ms"
-
-#, c-format
-msgid "xineliboutput: hotkey %s not binded"
-msgstr "xineliboutput: tasto %s non associato"
-
-msgid "Audio"
-msgstr "Audio"
-
-msgid "Speakers"
-msgstr "Altoparlanti"
-
-msgid "Volume control"
-msgstr "Controllo volume"
-
-msgid "Mix to headphones"
-msgstr "Suono a cuffie"
-
-msgid "Visualization"
-msgstr "Visualizzazione"
-
-msgid " Width"
-msgstr " Larghezza"
-
-msgid "px"
-msgstr "px"
-
-msgid " Height"
-msgstr " Altezza"
-
-msgid " Speed"
-msgstr " Velocità"
-
-msgid "fps"
-msgstr "fps"
-
-msgid "Audio Equalizer"
-msgstr "Equalizzatore audio"
-
-msgid "Use Video-Out Driver"
-msgstr "Utilizza driver uscita video"
-
-msgid "vector"
-msgstr "vettoriale"
-
-msgid "full"
-msgstr "intero"
-
-msgid "half (top)"
-msgstr "metà (superiore)"
-
-msgid "half (bottom)"
-msgstr "metà (inferiore)"
-
-msgid "Video"
-msgstr "Video"
-
-msgid " Autodetect letterbox"
-msgstr " Rileva letterbox in automatico"
-
-msgid " Soft start"
-msgstr " Avvio leggero"
-
-msgid " Crop to"
-msgstr " Ritaglia a"
-
-msgid " Detect subtitles"
-msgstr " Rileva sottotitoli"
-
-msgid "Software scaling"
-msgstr "Ridimensionamento software"
-
-msgid " Change aspect ratio"
-msgstr " Cambia formato video"
-
-msgid " Change video size"
-msgstr " Cambia dimensione video"
-
-msgid " Allow downscaling"
-msgstr " Permetti ridimensionamento"
-
-msgid "Post processing (ffmpeg)"
-msgstr "Codifica (ffmpeg)"
-
-msgid " Quality"
-msgstr " Qualità"
-
-msgid " Mode"
-msgstr " Modalità"
-
-msgid " Method"
-msgstr " Metodo"
-
-msgid " Cheap mode"
-msgstr " Modalità economica"
-
-msgid " Pulldown"
-msgstr " Pulldown"
-
-msgid " Frame rate"
-msgstr " Frame rate"
-
-msgid " Judder Correction"
-msgstr " Correzione gamma"
-
-msgid " Use progressive frame flag"
-msgstr " Utilizza flag frame progressivo"
-
-msgid " Chroma Filter"
-msgstr " Filtro Chroma"
-
-msgid "Sharpen / Blur"
-msgstr "Nitido / Blur"
-
-msgid " Width of the luma matrix"
-msgstr " Larghezza della matrice luma"
-
-msgid " Height of the luma matrix"
-msgstr " Altezza della matrice luma"
-
-msgid " Amount of luma sharpness/blur"
-msgstr " Valore di nitidezza/blur luma"
-
-msgid " Width of the chroma matrix"
-msgstr " Larghezza della matrice chroma"
-
-msgid " Height of the chroma matrix"
-msgstr " Altezza della matrice chroma"
-
-msgid " Amount of chroma sharpness/blur"
-msgstr " Valore di nitidezza/blur chroma"
-
-msgid "3D Denoiser"
-msgstr "Denoiser 3D"
-
-msgid " Spatial luma strength"
-msgstr " Resistenza luma spaziale"
-
-msgid " Spatial chroma strength"
-msgstr " Resistenza chroma spaziale"
-
-msgid " Temporal strength"
-msgstr " Resistenza temporale"
-
-msgid "HUE"
-msgstr "Tonalità"
-
-msgid "Saturation"
-msgstr "Saturazione"
-
-msgid "Contrast"
-msgstr "Contrasto"
-
-msgid "Brightness"
-msgstr "Luminosità"
-
-msgid "Sharpness"
-msgstr "Nitidezza"
-
-msgid "Noise Reduction"
-msgstr "Riduzione rumore"
-
-msgid "Smooth fast forward"
-msgstr "Avanzamento veloce leggero"
-
-msgid "Fastest trick speed"
-msgstr "Trucco velocità più rapida"
-
-msgid "On-Screen Display"
-msgstr "Messaggi in sovrimpressione (OSD)"
-
-msgid "Hide main menu"
-msgstr "Nascondi voce menu princ."
-
-msgid "Blending method"
-msgstr "Metodo di sfocatura"
-
-msgid " Use hardware for low-res video"
-msgstr "Utilizza hardware per video bassa risoluzione"
-
-msgid "Scaling method"
-msgstr "Metodo ridimensione"
-
-msgid "Show all layers"
-msgstr "Mostra tutti i livelli"
-
-msgid "Dynamic transparency correction"
-msgstr "Correzione trasparenza dinamica"
-
-msgid "Static transparency correction"
-msgstr "Correzione trasparenza statica"
-
-msgid "External subtitle size"
-msgstr "Dimensione sottotitoli esterni"
-
-msgid "DVB subtitle decoder"
-msgstr "Decoder sottotitoli DVB"
-
-msgid "Decoder"
-msgstr "Decoder"
-
-msgid "Buffer size"
-msgstr "Dimensione buffer"
-
-msgid " Number of PES packets"
-msgstr " Numero di pacchetti PES"
-
-msgid "Local Display Frontend"
-msgstr "Frontend visualizzazione locale"
-
-msgid "Use keyboard"
-msgstr "Utilizza tastiera"
-
-msgid "Driver"
-msgstr "Driver"
-
-msgid "Display address"
-msgstr "Mostra indirizzo"
-
-msgid "Framebuffer device"
-msgstr "Periferica framebuffer"
-
-msgid "Fullscreen mode"
-msgstr "Mod. schermo intero"
-
-msgid " Window width"
-msgstr " Larghezza finestra"
-
-msgid " Window height"
-msgstr " Altezza finestra"
-
-msgid "Window aspect"
-msgstr "Aspetto finestra"
-
-msgid "Scale to window size"
-msgstr "Scala a dimensione finestra"
-
-msgid "Port"
-msgstr "Porta"
-
-msgid "Remote Clients"
-msgstr "Client remoti"
-
-msgid "Allow remote clients"
-msgstr "Permetti client remoti"
-
-msgid " Listen port (TCP and broadcast)"
-msgstr " Porta in ascolto (TCP e broadcast)"
-
-msgid " Listen address"
-msgstr " Indirizzo in ascolto"
-
-msgid " Remote keyboard"
-msgstr " Tastiera remota"
-
-msgid " Max number of clients"
-msgstr " Numero massimo di client"
-
-msgid " PIPE transport"
-msgstr " Protocollo PIPE"
-
-msgid " TCP transport"
-msgstr " Protocollo TCP"
-
-msgid " UDP transport"
-msgstr " Protocollo UDP"
-
-msgid " RTP (multicast) transport"
-msgstr " Protocollo RTP (multicast)"
-
-msgid " Address"
-msgstr " Indirizzo"
-
-msgid " Port"
-msgstr " Porta"
-
-msgid " TTL"
-msgstr " TTL"
-
-msgid " Transmit always on"
-msgstr " Trasmetti sempre"
-
-msgid " SAP announcements"
-msgstr " Annunci SAP"
-
-msgid " Server announce broadcasts"
-msgstr " Annuncio trasmissioni dal server"
-
-msgid " HTTP transport for media files"
-msgstr " Protocollo HTTP per file multimediali"
-
-msgid "Additional network services"
-msgstr "Ulteriori servizi di rete"
-
-msgid "HTTP server"
-msgstr "Server HTTP"
-
-msgid "HTTP clients can control VDR"
-msgstr "I client HTTP possono controllare VDR"
-
-msgid "RTSP server"
-msgstr "Server RTSP"
-
-msgid "RTSP clients can control VDR"
-msgstr "I client RTSP possono controllare VDR"
-
-msgid "Playlist settings"
-msgstr "Impostazioni lista esec."
-
-msgid "Show the track number"
-msgstr "Mostra il numero della traccia"
-
-msgid "Show the name of the artist"
-msgstr "Mostra il nome dell'artista"
-
-msgid "Show the name of the album"
-msgstr "Mostra il nome dell'album"
-
-msgid "Scan for metainfo"
-msgstr "Scansione metainfo"
-
-msgid "Cache metainfo"
-msgstr "Cache metainfo"
-
-msgid "Arrow keys control DVD playback"
-msgstr "Controllo riprod. DVD con tasti freccia"
-
-msgid "Grayscale"
-msgstr "Scala di grigi"
-
-msgid "Bitmap"
-msgstr "Bitmap"
-
-msgid "OSD"
-msgstr "OSD"
-
-msgid "Media Player"
-msgstr "Lettore multimediale"
-
-msgid "Test Images"
-msgstr "Prova immagini"
-
-msgid "X11/xine-lib output plugin"
-msgstr "Plugin uscita X11/xine-lib"
-
diff --git a/po/ru_RU.po b/po/ru_RU.po
deleted file mode 100644
index 27a45d25..00000000
--- a/po/ru_RU.po
+++ /dev/null
@@ -1,650 +0,0 @@
-# VDR plugin language source file.
-# Copyright (C) 2007 Klaus Schmidinger <kls@cadsoft.de>
-# This file is distributed under the same license as the VDR package.
-# Vladimir Monchenko
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Xineliboutput 1.1.0\n"
-"Report-Msgid-Bugs-To: <phintuka@users.sourceforge.net>\n"
-"POT-Creation-Date: 2009-01-07 15:46+0200\n"
-"PO-Revision-Date: 2007-11-23 10:17+0200\n"
-"Last-Translator: Vladimir Monchenko\n"
-"Language-Team: <vdr@linuxtv.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ISO-8859-5\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-msgid "custom"
-msgstr "¿ÞÛì×ÞÒÐâÕÛì"
-
-msgid "tiny"
-msgstr "¾çÕÝì ÜÐÛÕÝìÚØÙ"
-
-msgid "small"
-msgstr "¼ÐÛÕÝìÚØÙ"
-
-msgid "medium"
-msgstr "ÁàÕÔÝØÙ"
-
-msgid "large"
-msgstr "±ÞÛìèÞÙ"
-
-msgid "huge"
-msgstr "¾çÕÝì ÑÞÛìÝÞÙ"
-
-msgid "automatic"
-msgstr "°ÒâÞÜÐâØçÕáÚØ"
-
-msgid "default"
-msgstr "¿Þ ãÜÞÛçÐÝØî"
-
-msgid "Pan&Scan"
-msgstr "Pan&Scan"
-
-msgid "CenterCutOut"
-msgstr ""
-
-msgid "square"
-msgstr ""
-
-msgid "anamorphic"
-msgstr ""
-
-msgid "DVB"
-msgstr ""
-
-msgid "off"
-msgstr "²ëÚÛ."
-
-msgid "normal"
-msgstr "½ÞàÜÐÛìÝëÙ"
-
-msgid "inverted"
-msgstr "¸ÝÒÕàâØàÞÒÐÝÞ"
-
-msgid "no audio"
-msgstr "½Õâ ÐãÔØÞ"
-
-msgid "no video"
-msgstr "½Õâ ÒØÔÕÞ"
-
-msgid "Off"
-msgstr ""
-
-msgid "Goom"
-msgstr ""
-
-msgid "Oscilloscope"
-msgstr ""
-
-msgid "FFT Scope"
-msgstr ""
-
-msgid "FFT Graph"
-msgstr ""
-
-msgid "Mono 1.0"
-msgstr ""
-
-msgid "Stereo 2.0"
-msgstr ""
-
-msgid "Headphones 2.0"
-msgstr ""
-
-msgid "Stereo 2.1"
-msgstr ""
-
-msgid "Surround 3.0"
-msgstr ""
-
-msgid "Surround 4.0"
-msgstr ""
-
-msgid "Surround 4.1"
-msgstr ""
-
-msgid "Surround 5.0"
-msgstr ""
-
-msgid "Surround 5.1"
-msgstr ""
-
-msgid "Surround 6.0"
-msgstr ""
-
-msgid "Surround 6.1"
-msgstr ""
-
-msgid "Surround 7.1"
-msgstr ""
-
-msgid "Pass Through"
-msgstr ""
-
-msgid "very large"
-msgstr ""
-
-msgid "Software"
-msgstr ""
-
-msgid "Hardware"
-msgstr ""
-
-msgid "no"
-msgstr ""
-
-msgid "grayscale"
-msgstr ""
-
-msgid "transparent"
-msgstr ""
-
-msgid "transparent grayscale"
-msgstr ""
-
-msgid "yes"
-msgstr ""
-
-msgid "nearest"
-msgstr ""
-
-msgid "bilinear"
-msgstr ""
-
-msgid "none"
-msgstr ""
-
-msgid "nonref"
-msgstr ""
-
-msgid "bidir"
-msgstr ""
-
-msgid "nonkey"
-msgstr ""
-
-msgid "all"
-msgstr ""
-
-msgid "Frontend initialization failed"
-msgstr ""
-
-msgid "Server initialization failed"
-msgstr ""
-
-msgid "Playlist"
-msgstr ""
-
-msgid "Button$Random"
-msgstr ""
-
-msgid "Button$Normal"
-msgstr ""
-
-msgid "Button$Add files"
-msgstr ""
-
-msgid "Button$Remove"
-msgstr ""
-
-msgid "Button$Sort"
-msgstr ""
-
-msgid "Queued to playlist"
-msgstr ""
-
-msgid "Random play"
-msgstr ""
-
-msgid "Normal play"
-msgstr ""
-
-msgid "Delete image ?"
-msgstr "ÃÔÐÛØâì ÚÐàâØÝÚã ?"
-
-msgid "Images"
-msgstr "¸×ÞÑàÐÖÕÝØï"
-
-msgid "Play music"
-msgstr ""
-
-msgid "Add to playlist"
-msgstr ""
-
-msgid "Play file"
-msgstr "¿àÞØÓàÐâì äÐÙÛ"
-
-msgid "Button$Queue"
-msgstr ""
-
-msgid "Media"
-msgstr ""
-
-msgid "Play file >>"
-msgstr "¿àÞØÓàÐâì äÐÙÛ >>"
-
-msgid "Play music >>"
-msgstr "¿àÞØÓàÐâì äÐÙÛ >>"
-
-msgid "View images >>"
-msgstr "¿àÞáÜÞâàÕâì Ø×ÞÑàÐÖÕÝØï >>"
-
-msgid "Play remote DVD >>"
-msgstr ""
-
-msgid "Play DVD disc >>"
-msgstr ""
-
-msgid "Play remote CD >>"
-msgstr ""
-
-msgid "Play audio CD >>"
-msgstr ""
-
-msgid "Video settings"
-msgstr ""
-
-msgid "Play only audio"
-msgstr ""
-
-msgid "Crop letterbox 4:3 to 16:9"
-msgstr ""
-
-msgid "Overscan (crop image borders)"
-msgstr ""
-
-msgid "Interlaced Field Order"
-msgstr "ÇÕàÕ×áâàÞçÝëÙ ßÞàïÔÞÚ ßÞÛÕÙ"
-
-msgid "Audio settings"
-msgstr ""
-
-msgid "Headphone audio mode"
-msgstr ""
-
-msgid "Audio Compression"
-msgstr "°ãÔØÞ ÚÞÜßàÕááØï"
-
-msgid "Audio equalizer >>"
-msgstr "°ãÔØÞ íÚÒÐÛÐÙ×Õà >>"
-
-msgid "Local Frontend"
-msgstr "»ÞÚÐÛìÝëÙ äàÞÝâÕÝÔ"
-
-msgid "Aspect ratio"
-msgstr ""
-
-msgid "Video aspect ratio"
-msgstr ""
-
-msgid "On"
-msgstr ""
-
-msgid "Deinterlacing"
-msgstr "´ÕØÝâÕàÛÕÙáØÝÓ"
-
-msgid "Upmix stereo to 5.1"
-msgstr "¿àÕÞÑàÐ×ÞÒÐâì áâÕàÕÞ Ò 5.1"
-
-msgid "Downmix AC3 to surround"
-msgstr ""
-
-msgid "Default playlist not found"
-msgstr ""
-
-msgid "Default playlist is not symlink"
-msgstr ""
-
-msgid "Default playlist not defined"
-msgstr ""
-
-msgid "Delay"
-msgstr "·ÐÔÕàÖÚÐ"
-
-msgid "ms"
-msgstr "ms"
-
-#, c-format
-msgid "xineliboutput: hotkey %s not binded"
-msgstr ""
-
-msgid "Audio"
-msgstr "°ãÔØÞ"
-
-msgid "Speakers"
-msgstr ""
-
-msgid "Volume control"
-msgstr ""
-
-msgid "Mix to headphones"
-msgstr ""
-
-msgid "Visualization"
-msgstr "²Ø×ãÐÛØ×ÐæØï"
-
-msgid " Width"
-msgstr ""
-
-msgid "px"
-msgstr "ߨÚáÕÛÕÙ"
-
-msgid " Height"
-msgstr ""
-
-msgid " Speed"
-msgstr ""
-
-msgid "fps"
-msgstr ""
-
-msgid "Audio Equalizer"
-msgstr "°ãÔØÞ íÚÒÐÛÐÙ×Õà"
-
-msgid "Use Video-Out Driver"
-msgstr ""
-
-msgid "vector"
-msgstr ""
-
-msgid "full"
-msgstr ""
-
-msgid "half (top)"
-msgstr ""
-
-msgid "half (bottom)"
-msgstr ""
-
-msgid "Video"
-msgstr "²ØÔÕÞ"
-
-msgid " Autodetect letterbox"
-msgstr ""
-
-msgid " Soft start"
-msgstr ""
-
-msgid " Crop to"
-msgstr ""
-
-msgid " Detect subtitles"
-msgstr ""
-
-msgid "Software scaling"
-msgstr ""
-
-msgid " Change aspect ratio"
-msgstr ""
-
-msgid " Change video size"
-msgstr ""
-
-msgid " Allow downscaling"
-msgstr " ¼ÐáèâÐÑØàÞÒÐâì á ßÐÔÕÝØÕÜ ÚÐçÕáâÒÐ"
-
-msgid "Post processing (ffmpeg)"
-msgstr ""
-
-msgid " Quality"
-msgstr ""
-
-msgid " Mode"
-msgstr ""
-
-msgid " Method"
-msgstr ""
-
-msgid " Cheap mode"
-msgstr ""
-
-msgid " Pulldown"
-msgstr ""
-
-msgid " Frame rate"
-msgstr ""
-
-msgid " Judder Correction"
-msgstr ""
-
-msgid " Use progressive frame flag"
-msgstr ""
-
-msgid " Chroma Filter"
-msgstr ""
-
-msgid "Sharpen / Blur"
-msgstr ""
-
-msgid " Width of the luma matrix"
-msgstr ""
-
-msgid " Height of the luma matrix"
-msgstr ""
-
-msgid " Amount of luma sharpness/blur"
-msgstr ""
-
-msgid " Width of the chroma matrix"
-msgstr ""
-
-msgid " Height of the chroma matrix"
-msgstr ""
-
-msgid " Amount of chroma sharpness/blur"
-msgstr ""
-
-msgid "3D Denoiser"
-msgstr ""
-
-msgid " Spatial luma strength"
-msgstr ""
-
-msgid " Spatial chroma strength"
-msgstr ""
-
-msgid " Temporal strength"
-msgstr ""
-
-msgid "HUE"
-msgstr "HUE"
-
-msgid "Saturation"
-msgstr "½ÐáëéÕÝÝÞáâì"
-
-msgid "Contrast"
-msgstr "ºÞÝâàÐáâÝÞáâì"
-
-msgid "Brightness"
-msgstr "ÏàÚÞáâì"
-
-msgid "Sharpness"
-msgstr ""
-
-msgid "Noise Reduction"
-msgstr ""
-
-msgid "Smooth fast forward"
-msgstr ""
-
-msgid "Fastest trick speed"
-msgstr ""
-
-msgid "On-Screen Display"
-msgstr "ÍÚàÐÝÝÞÕ ÜÕÝî"
-
-msgid "Hide main menu"
-msgstr "ÁÚàëâì ÞáÝÞÒÝÞÕ ÜÕÝî"
-
-msgid "Blending method"
-msgstr ""
-
-msgid " Use hardware for low-res video"
-msgstr ""
-
-msgid "Scaling method"
-msgstr ""
-
-msgid "Show all layers"
-msgstr ""
-
-msgid "Dynamic transparency correction"
-msgstr "´ØÝÐÜØçÕáÚÐï ÚÞààÕÚæØï ßàÞ×àÐçÝÞáâØ"
-
-msgid "Static transparency correction"
-msgstr "ÁâÐâØçÕáÚÐï ÚÞààÕÚæØï ßàÞ×àÐçÝÞáâØ"
-
-msgid "External subtitle size"
-msgstr ""
-
-msgid "DVB subtitle decoder"
-msgstr ""
-
-msgid "Decoder"
-msgstr "´ÕÚÞÔÕà"
-
-msgid "Buffer size"
-msgstr "ÀÐ×ÜÕà ÑãäÕàÐ"
-
-msgid " Number of PES packets"
-msgstr " PES ßÐÚÕâÞÒ"
-
-msgid "Local Display Frontend"
-msgstr "ÄàÞÝâÕÝÔ ÛÞÚÐÛìÝÞÓÞ íÚàÐÝÐ"
-
-msgid "Use keyboard"
-msgstr "¸áßÞÛì×ÞÒÐâì ÚÛÐÒØÐâãàã"
-
-msgid "Driver"
-msgstr "´àÐÙÒÕà"
-
-msgid "Display address"
-msgstr "°ÔàÕá ÔØáßÛÕï"
-
-msgid "Framebuffer device"
-msgstr "Framebuffer ãáâàÞÙáâÒÞ"
-
-msgid "Fullscreen mode"
-msgstr "¿ÞÛÝÞíÚàÐÝÝëÙ àÕÖØÜ"
-
-msgid " Window width"
-msgstr " ÈØàØÝÐ ÞÚÝÐ"
-
-msgid " Window height"
-msgstr " ²ëáÞâÐ ÞÚÝÐ"
-
-msgid "Window aspect"
-msgstr "ÁÞÞâÝÞèÕÝØÕ áâÞàÞÝ"
-
-msgid "Scale to window size"
-msgstr "¼ÐáèâÐÑØàÞÒÐâì Ò àÐ×ÜÕà ÞÚÝÐ"
-
-msgid "Port"
-msgstr "¿Þàâ"
-
-msgid "Remote Clients"
-msgstr "ÃÔÐÛÕÝÝëÕ ÚÛØÕÝâë"
-
-msgid "Allow remote clients"
-msgstr "ÀÐ×àÕèØâì ãÔÐÛÕÝÝëå ÚÛØÕÝâÞÒ"
-
-msgid " Listen port (TCP and broadcast)"
-msgstr " ¿Þàâ (TCP Ø èØàÞÚÞÒÕèÐâÕÛìÝëÙ)"
-
-msgid " Listen address"
-msgstr ""
-
-msgid " Remote keyboard"
-msgstr " ÃÔÐÛÕÝÝÐï ÚÛÐÒØÐâãàÐ"
-
-msgid " Max number of clients"
-msgstr ""
-
-msgid " PIPE transport"
-msgstr " PIPE âàÐÝáßÞàâ"
-
-msgid " TCP transport"
-msgstr "TCP âàÐÝáßÞàâ"
-
-msgid " UDP transport"
-msgstr "UDP âàÐÝáßÞàâ"
-
-msgid " RTP (multicast) transport"
-msgstr " RTP (èØàÞÚÞÒÕéÐâÕÛìÝëÙ) âàÐÝáßÞàâ"
-
-msgid " Address"
-msgstr ""
-
-msgid " Port"
-msgstr ""
-
-msgid " TTL"
-msgstr ""
-
-msgid " Transmit always on"
-msgstr ""
-
-msgid " SAP announcements"
-msgstr ""
-
-msgid " Server announce broadcasts"
-msgstr " ÁÕàÒÕà ØáßÞÛì×ãÕâ èØàÞÚÞÒÕéÐÝØÕ"
-
-msgid " HTTP transport for media files"
-msgstr ""
-
-msgid "Additional network services"
-msgstr ""
-
-msgid "HTTP server"
-msgstr ""
-
-msgid "HTTP clients can control VDR"
-msgstr ""
-
-msgid "RTSP server"
-msgstr ""
-
-msgid "RTSP clients can control VDR"
-msgstr ""
-
-msgid "Playlist settings"
-msgstr ""
-
-msgid "Show the track number"
-msgstr ""
-
-msgid "Show the name of the artist"
-msgstr ""
-
-msgid "Show the name of the album"
-msgstr ""
-
-msgid "Scan for metainfo"
-msgstr ""
-
-msgid "Cache metainfo"
-msgstr ""
-
-msgid "Arrow keys control DVD playback"
-msgstr ""
-
-msgid "Grayscale"
-msgstr "¾ââÕÝÚØ áÕàÞÓÞ"
-
-msgid "Bitmap"
-msgstr "±ØâÞÒÐï ÚÐàâÐ"
-
-msgid "OSD"
-msgstr ""
-
-msgid "Media Player"
-msgstr "Xine-lib"
-
-msgid "Test Images"
-msgstr "ÂÕáâÞÒëÕ Ø×ÞÑàÐÖÕÝØï"
-
-msgid "X11/xine-lib output plugin"
-msgstr "X11/xine-lib ÒØÔÕÞ ÜÞÔãÛì"
diff --git a/setup_menu.c b/setup_menu.c
deleted file mode 100644
index 0cd91bf8..00000000
--- a/setup_menu.c
+++ /dev/null
@@ -1,1983 +0,0 @@
-/*
- * setup_menu.c: Setup Menu
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: setup_menu.c,v 1.70 2009-05-29 15:09:10 phintuka Exp $
- *
- */
-
-#include "features.h"
-
-#include <vdr/config.h>
-#include <vdr/plugin.h>
-#include <vdr/remote.h>
-#include <vdr/i18n.h>
-
-#include "config.h"
-#include "device.h"
-#include "menuitems.h"
-#include "osd.h" // cXinelibOsdProvider::RefreshOsd()
-#include "setup_menu.h"
-
-
-namespace XinelibOutputSetupMenu {
-
-//#define INTEGER_CONFIG_VIDEO_CONTROLS
-//#define LINEAR_VIDEO_CONTROLS
-//#define LOGARITHM_SCALING
-
-#define ISNUMBERKEY(k) (RAWKEY(k) >= k0 && RAWKEY(k) <= k9)
-
-//--- Setup Menu -------------------------------------------------------------
-
-const char *ModeLineChars =
- " 0123456789+-hvsync.";
-const char *DriverNameChars =
- " abcdefghijklmnopqrstuvwxyz0123456789-.,#~:;";
-const char *OptionsChars =
- "=.,abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-const char *LangNameChars =
- "abcdefghijklmnopqrstuvwxyz";
-
-const char *controls[] =
- { "Off",
- "[|---------------]","[|---------------]",
- "[-|--------------]","[-|--------------]",
- "[--|-------------]","[--|-------------]",
- "[---|------------]","[---|------------]",
- "[----|-----------]","[----|-----------]",
- "[-----|----------]","[-----|----------]",
- "[------|---------]","[------|---------]",
- "[-------|--------]","[-------|--------]",
- "[--------|-------]","[--------|-------]",
- "[---------|------]","[---------|------]",
- "[----------|-----]","[----------|-----]",
- "[-----------|----]","[-----------|----]",
- "[------------|---]","[------------|---]",
- "[-------------|--]","[-------------|--]",
- "[--------------|-]","[--------------|-]",
- "[---------------|]","[---------------|]",
- NULL
- };
-
-#ifdef LINEAR_VIDEO_CONTROLS
-# define CONTROL_TO_INDEX(val) ((val)>=0 ? ((val)>>11)+1 : 0)
-# define INDEX_TO_CONTROL(ind) ((ind)==0 ? -1 : ((ind)-1)<<11)
-#else
-#ifdef LOGARITHM_SCALING
-const int ind2ctrl_tbl[33] = {
- -1, 0, 0x0001, 0x0002, 0x0003, 0x0004, 0x0007, 0x000a,
- 0x000f, 0x0014, 0x001f, 42, 0x003f, 80, 0x007f, 170,
- 0x00ff, 336, 0x01ff, 682, 0x03ff, 1630, 0x07ff, 2730,
- 0x0fff, 5726, 0x1fff, 10858, 0x3fff, 22110, 0x7fff, 43224,
- 0xffff };
-#else
-const int ind2ctrl_tbl[33] = {
- -1,
- 0x0000, 0x0843, 0x1085, 0x18c7, 0x2109, 0x294b, 0x318d, 0x39cf,
- 0x4211, 0x4a53, 0x5295, 0x5ad7, 0x6319, 0x6b5b, 0x739d, 0x7bdf,
- 0x8421, 0x8c63, 0x94a5, 0x9ce7, 0xa529, 0xad6b, 0xb5ad, 0xbdef,
- 0xc631, 0xce73, 0xd6b5, 0xdef7, 0xe739, 0xef7b, 0xf7bd, 0xffff
-};
-#endif
-static int CONTROL_TO_INDEX(int val)
-{
- for(int i=0; i<33;i++)
- if(val<=ind2ctrl_tbl[i])
- return i;
- return 32;
-}
-static int INDEX_TO_CONTROL(int ind)
-{
- if(ind<0) ind=0;
- if(ind>32) ind=32;
- return ind2ctrl_tbl[ind];
-}
-#endif
-
-static cOsdItem *NewTitle(const char *s)
-{
- char str[128];
- cOsdItem *tmp;
- snprintf(str, sizeof(str), "----- %s -----", s);
- str[sizeof(str)-1] = 0;
- tmp = new cOsdItem(str);
- tmp->SetSelectable(false);
- return tmp;
-}
-
-//--- cMenuSetupAudio --------------------------------------------------------
-
-class cMenuSetupAudio : public cMenuSetupPage
-{
- private:
- config_t newconfig;
- int visualization;
- int goom_width, goom_height, goom_fps;
-
- cOsdItem *audio_ctrl_speakers;
- cOsdItem *audio_ctrl_volume;
- cOsdItem *audio_ctrl_delay;
- cOsdItem *audio_ctrl_compression;
- cOsdItem *audio_ctrl_upmix;
- cOsdItem *audio_ctrl_surround;
- cOsdItem *audio_ctrl_headphone;
- cOsdItem *audio_ctrl_vis;
-
- protected:
- virtual void Store(void);
- void Set(void);
-
- public:
- cMenuSetupAudio(void);
- ~cMenuSetupAudio(void);
-
- virtual eOSState ProcessKey(eKeys Key);
-};
-
-cMenuSetupAudio::cMenuSetupAudio(void)
-{
- memcpy(&newconfig, &xc, sizeof(config_t));
-
- visualization = strstra(xc.audio_visualization,
- xc.s_audioVisualizations,
- 0);
- goom_width = 720;
- goom_height = 576;
- goom_fps = 25;
-
- char *pt;
- if(NULL != (pt=strstr(xc.audio_vis_goom_opts, "width=")))
- goom_width = max(320, min(1920, atoi(pt+6)));
- if(NULL != (pt=strstr(xc.audio_vis_goom_opts, "height=")))
- goom_height = max(240, min(1280, atoi(pt+7)));
- if(NULL != (pt=strstr(xc.audio_vis_goom_opts, "fps=")))
- goom_fps = max(1, min(100, atoi(pt+4)));
-
- Set();
-}
-
-cMenuSetupAudio::~cMenuSetupAudio(void)
-{
- cXinelibDevice::Instance().ConfigurePostprocessing(
- xc.deinterlace_method, xc.audio_delay, xc.audio_compression,
- xc.audio_equalizer, xc.audio_surround, xc.speaker_type);
- cXinelibDevice::Instance().ConfigurePostprocessing(
- "upmix", xc.audio_upmix ? true : false, NULL);
-#ifdef ENABLE_TEST_POSTPLUGINS
- cXinelibDevice::Instance().ConfigurePostprocessing(
- "headphone", xc.headphone ? true : false, NULL);
-#endif
-}
-
-void cMenuSetupAudio::Set(void)
-{
- SetPlugin(cPluginManager::GetPlugin(PLUGIN_NAME_I18N));
- int current = Current();
- Clear();
-
- Add(NewTitle(tr("Audio")));
-
- Add(audio_ctrl_speakers =
- new cMenuEditStraI18nItem(tr("Speakers"), &newconfig.speaker_type,
- SPEAKERS_count, xc.s_speakerArrangements));
-
- Add(audio_ctrl_volume =
- new cMenuEditBoolItem(tr("Volume control"),
- &newconfig.sw_volume_control,
- tr("Hardware"), tr("Software")));
-
- Add(audio_ctrl_delay =
- new cMenuEditTypedIntItem(tr("Delay"), tr("ms"), &newconfig.audio_delay,
- -3000, 3000, tr("Off")));
- Add(audio_ctrl_compression =
- new cMenuEditTypedIntItem(tr("Audio Compression"), "%",
- &newconfig.audio_compression,
- 100, 500, NULL, tr("Off")));
- Add(audio_ctrl_upmix =
- new cMenuEditBoolItem(tr("Upmix stereo to 5.1"),
- &newconfig.audio_upmix));
- Add(audio_ctrl_surround =
- new cMenuEditBoolItem(tr("Downmix AC3 to surround"),
- &newconfig.audio_surround));
-#ifdef ENABLE_TEST_POSTPLUGINS
- Add(audio_ctrl_headphone =
- new cMenuEditBoolItem(tr("Mix to headphones"),
- &newconfig.headphone));
-#else
- audio_ctrl_headphone = NULL;
-#endif
- Add(audio_ctrl_vis =
- new cMenuEditStraI18nItem(tr("Visualization"), &visualization,
- AUDIO_VIS_count,
- xc.s_audioVisualizationNames));
- if(visualization == AUDIO_VIS_GOOM) {
- Add(new cMenuEditTypedIntItem(tr(" Width"), tr("px"), &goom_width,
- 320, 1920));
- Add(new cMenuEditTypedIntItem(tr(" Height"),tr("px"), &goom_height,
- 240, 1280));
- Add(new cMenuEditTypedIntItem(tr(" Speed"), tr("fps"), &goom_fps,
- 1, 100));
- }
-
- if(current<1) current=1; /* first item is not selectable */
- SetCurrent(Get(current));
- Display();
-}
-
-eOSState cMenuSetupAudio::ProcessKey(eKeys Key)
-{
- cOsdItem *item = Get(Current());
-
- eOSState state = cMenuSetupPage::ProcessKey(Key);
-
- Key = NORMALKEY(Key);
-
- if(Key!=kLeft && Key!=kRight)
- return state;
-
- if(item == audio_ctrl_delay || item == audio_ctrl_compression) {
- cXinelibDevice::Instance().ConfigurePostprocessing(
- xc.deinterlace_method, newconfig.audio_delay,
- newconfig.audio_compression, newconfig.audio_equalizer,
- newconfig.audio_surround, newconfig.speaker_type);
- }
- else if(item == audio_ctrl_vis) {
- Set();
- }
- else if(item == audio_ctrl_speakers) {
- cXinelibDevice::Instance().ConfigurePostprocessing(
- xc.deinterlace_method, newconfig.audio_delay,
- newconfig.audio_compression, newconfig.audio_equalizer,
- newconfig.audio_surround, newconfig.speaker_type);
- if(newconfig.speaker_type <= SPEAKERS_STEREO &&
- newconfig.audio_upmix) {
- newconfig.audio_upmix = false;
- Set();
- }
- }
- else if(item == audio_ctrl_surround) {
- cXinelibDevice::Instance().ConfigurePostprocessing(
- xc.deinterlace_method, newconfig.audio_delay,
- newconfig.audio_compression, newconfig.audio_equalizer,
- newconfig.audio_surround, newconfig.speaker_type);
- if(newconfig.audio_surround && newconfig.audio_upmix) {
- newconfig.audio_upmix = 0;
- Set();
- }
- }
- else if(item == audio_ctrl_volume) {
- // trigger volume control message by toggling mute
- cRemote::Put(kMute);
- cRemote::Put(kMute);
- }
- else if(item == audio_ctrl_upmix) {
- cXinelibDevice::Instance().ConfigurePostprocessing(
- "upmix", newconfig.audio_upmix ? true : false, NULL);
- if(newconfig.audio_upmix && newconfig.audio_surround) {
- newconfig.audio_surround = 0;
- Set();
- }
- }
-#ifdef ENABLE_TEST_POSTPLUGINS
- else if(item == audio_ctrl_headphone) {
- cXinelibDevice::Instance().ConfigurePostprocessing(
- "headphone", newconfig.headphone ? true : false, NULL);
- }
-#endif
-
- return state;
-}
-
-
-void cMenuSetupAudio::Store(void)
-{
- memcpy(&xc, &newconfig, sizeof(config_t));
-
- strn0cpy(xc.audio_visualization, xc.s_audioVisualizations[visualization],
- sizeof(xc.audio_visualization));
- snprintf(xc.audio_vis_goom_opts, sizeof(xc.audio_vis_goom_opts),
- "width=%d,height=%d,fps=%d",
- goom_width, goom_height, goom_fps);
- xc.audio_vis_goom_opts[sizeof(xc.audio_vis_goom_opts)-1] = 0;
-
- SetupStore("Audio.Speakers", xc.s_speakerArrangements[xc.speaker_type]);
- SetupStore("Audio.Delay", xc.audio_delay);
- SetupStore("Audio.Compression", xc.audio_compression);
- SetupStore("Audio.Surround", xc.audio_surround);
- SetupStore("Audio.Upmix", xc.audio_upmix);
- SetupStore("Audio.Headphone", xc.headphone);
- SetupStore("Audio.Visualization",xc.audio_visualization);
- SetupStore("Audio.Visualization.GoomOpts",xc.audio_vis_goom_opts);
- SetupStore("Audio.SoftwareVolumeControl", xc.sw_volume_control);
- Setup.Save();
-}
-
-//--- cMenuSetupAudioEq ------------------------------------------------------
-
-class cMenuSetupAudioEq : public cMenuSetupPage
-{
- private:
- config_t newconfig;
-
- protected:
- virtual void Store(void);
- void Set(void);
-
- public:
- cMenuSetupAudioEq(void);
- ~cMenuSetupAudioEq(void);
-
- virtual eOSState ProcessKey(eKeys Key);
-};
-
-cMenuSetupAudioEq::cMenuSetupAudioEq(void)
-{
- memcpy(&newconfig, &xc, sizeof(config_t));
- Set();
-}
-
-cMenuSetupAudioEq::~cMenuSetupAudioEq(void)
-{
- cXinelibDevice::Instance().ConfigurePostprocessing(
- xc.deinterlace_method, xc.audio_delay, xc.audio_compression,
- xc.audio_equalizer, xc.audio_surround, xc.speaker_type);
-}
-
-void cMenuSetupAudioEq::Set(void)
-{
- SetPlugin(cPluginManager::GetPlugin(PLUGIN_NAME_I18N));
- int current = Current();
- Clear();
-
- Add(NewTitle(tr("Audio Equalizer")));
- for(int i=0; i<AUDIO_EQ_count; i++)
- Add(new cMenuEditTypedIntItem(config_t::s_audioEqNames[i], "%",
- &newconfig.audio_equalizer[i],
- -100, 100, tr("Off")));
-
- if(current<1) current=1; /* first item is not selectable */
- SetCurrent(Get(current));
- Display();
-}
-
-eOSState cMenuSetupAudioEq::ProcessKey(eKeys Key)
-{
- eOSState state = cMenuSetupPage::ProcessKey(Key);
-
- Key = NORMALKEY(Key);
-
- if(Key == kLeft || Key == kRight) {
- cXinelibDevice::Instance().ConfigurePostprocessing(
- xc.deinterlace_method, xc.audio_delay, xc.audio_compression,
- newconfig.audio_equalizer, xc.audio_surround, xc.speaker_type);
- }
-
- return state;
-}
-
-void cMenuSetupAudioEq::Store(void)
-{
- memcpy(&xc, &newconfig, sizeof(config_t));
-
- char tmp[256];
- sprintf(tmp,"%d %d %d %d %d %d %d %d %d %d",
- xc.audio_equalizer[0], xc.audio_equalizer[1],
- xc.audio_equalizer[2], xc.audio_equalizer[3],
- xc.audio_equalizer[4], xc.audio_equalizer[5],
- xc.audio_equalizer[6], xc.audio_equalizer[7],
- xc.audio_equalizer[8], xc.audio_equalizer[9]);
- SetupStore("Audio.Equalizer", tmp);
- Setup.Save();
-}
-
-//--- cMenuSetupVideo --------------------------------------------------------
-
-static const char * const tvtime_method[] =
- { "use_vo_driver",
- "Linear",
- "LinearBlend",
- "Greedy",
- "Greedy2Frame",
- "Weave",
- "LineDoubler",
- "Vertical",
- "ScalerBob",
- "GreedyH",
- "TomsMoComp",
- NULL};
-
-static const int tvtime_methods_count = (sizeof(tvtime_method)/sizeof(tvtime_method[0]) - 1);
-
-static const char * const tvtime_method_name[] =
- {trNOOP("Use Video-Out Driver"), // "use_vo_driver"
- "Linear Interpolation", // "Linear",
- "Linear Blend (mplayer)", // "LinearBlend",
- "Greedy - Low motion (DScaler)", // "Greedy",
- "Greedy 2-frame (DScaler)", // "Greedy2Frame",
- "Weave Last Field", // "Weave",
- "Line Doubler", // "LineDoubler",
- "Vertical Blend (ffmpeg)", // "Vertical",
- "Scaler Bob", // "ScalerBob",
- "Greedy - High Motion (DScaler)", // "GreedyH",
- "Tom's Motion Compensated (DScaler)", // "TomsMoComp",
- NULL};
-
-static const char * const tvtime_pulldown[] =
- { "none",
- "vector",
- NULL};
-
-static const char * const tvtime_pulldown_name[] =
- { trNOOP("none"),
- trNOOP("vector"),
- NULL};
-
-static const char * const tvtime_framerate[] =
- { "full",
- "half_top",
- "half_bottom",
- NULL};
-
-static const char * const tvtime_framerate_name[] =
- { trNOOP("full"),
- trNOOP("half (top)"),
- trNOOP("half (bottom)"),
- NULL};
-
-struct tvtime_s {
- int method;
- int cheap_mode; // on/off
- int pulldown; // none, vector
- int framerate; // full, half_top, half_bottom
- int judder_correction; // on/off
- int use_progressive_frame_flag; // on/off
- int chroma_filter; // on/off
-
- void Parse(const char *str)
- {
- cheap_mode = strstr(str, "cheap_mode=1") ? 1 : 0;
- pulldown = strstr(str, "pulldown=none") ? 0 :
- strstr(str, "pulldown=0") ? 0 : 1;
- framerate = strstr(str, "framerate_mode=half_top") ? 1 :
- strstr(str, "framerate_mode=1") ? 1 :
- strstr(str, "framerate_mode=half_bottom") ? 2 :
- strstr(str, "framerate_mode=2") ? 2 : 0;
- chroma_filter = strstr(str, "chroma_filter=1") ? 1 : 0;
- judder_correction = strstr(str, "judder_correction=0") ? 0 : 1;
- use_progressive_frame_flag = strstr(str, "use_progressive_frame_flag=0") ? 0 : 1;
- method=1;
- const char *m = strstr(str, "method=");
- if(m) {
- char *tmp = strdup(m + 7);
- if(strchr(tmp, ','))
- *strchr(tmp, ',') = 0;
- method = strstra(tmp, tvtime_method, 1);
- free(tmp);
- }
- }
-
- const char *ToString(void)
- {
- static char buf[256];
- snprintf(buf, sizeof(buf),
- "method=%s,cheap_mode=%d,pulldown=%s,framerate_mode=%s,"
- "judder_correction=%d,use_progressive_frame_flag=%d,"
- "chroma_filter=%d,enabled=1",
- tvtime_method[method], cheap_mode, tvtime_pulldown[pulldown],
- tvtime_framerate[framerate], judder_correction,
- use_progressive_frame_flag, chroma_filter);
- buf[sizeof(buf)-1] = 0;
- return buf;
- }
-};
-
-class cMenuSetupVideo : public cMenuSetupPage
-{
- private:
- config_t newconfig;
-
- cOsdItem *ctrl_autocrop;
- cOsdItem *ctrl_swscale;
- cOsdItem *ctrl_swscale_resize;
- cOsdItem *ctrl_swscale_aspect;
- cOsdItem *ctrl_swscale_width;
- cOsdItem *ctrl_swscale_height;
- cOsdItem *ctrl_hue;
- cOsdItem *ctrl_saturation;
- cOsdItem *ctrl_contrast;
- cOsdItem *ctrl_brightness;
- cOsdItem *ctrl_sharpness;
- cOsdItem *ctrl_noise_reduction;
- cOsdItem *ctrl_overscan;
- cOsdItem *ctrl_pp;
- cOsdItem *ctrl_deinterlace;
- cOsdItem *ctrl_tvtime_method;
- cOsdItem *ctrl_unsharp;
- cOsdItem *ctrl_denoise3d;
- cOsdItem *ctrl_vo_aspect_ratio;
-
- int deinterlace;
- struct tvtime_s tvtime;
-
- protected:
- virtual void Store(void);
- void Set(void);
-
- public:
- cMenuSetupVideo(void);
- ~cMenuSetupVideo(void);
-
- virtual eOSState ProcessKey(eKeys Key);
-};
-
-cMenuSetupVideo::cMenuSetupVideo(void)
-{
- memcpy(&newconfig, &xc, sizeof(config_t));
-
- newconfig.hue = CONTROL_TO_INDEX(newconfig.hue);
- newconfig.saturation = CONTROL_TO_INDEX(newconfig.saturation);
- newconfig.contrast = CONTROL_TO_INDEX(newconfig.contrast);
- newconfig.brightness = CONTROL_TO_INDEX(newconfig.brightness);
- newconfig.sharpness = CONTROL_TO_INDEX(newconfig.sharpness);
- newconfig.noise_reduction = CONTROL_TO_INDEX(newconfig.noise_reduction);
-
- deinterlace = strstra(xc.deinterlace_method, xc.s_deinterlaceMethods, 0);
-
- tvtime.Parse(newconfig.deinterlace_opts);
-
- Set();
-}
-
-cMenuSetupVideo::~cMenuSetupVideo(void)
-{
- cXinelibDevice::Instance().ConfigureVideo(xc.hue, xc.saturation,
- xc.brightness, xc.sharpness,
- xc.noise_reduction, xc.contrast,
- xc.overscan, xc.vo_aspect_ratio);
- cXinelibDevice::Instance().ConfigurePostprocessing(
- "autocrop", xc.autocrop ? true : false, xc.AutocropOptions());
- cXinelibDevice::Instance().ConfigurePostprocessing(
- "swscale", xc.swscale ? true : false, xc.SwScaleOptions());
- cXinelibDevice::Instance().ConfigurePostprocessing(
- "pp", xc.ffmpeg_pp ? true : false, xc.FfmpegPpOptions());
- cXinelibDevice::Instance().ConfigurePostprocessing(
- "unsharp", xc.unsharp ? true : false, xc.UnsharpOptions());
- cXinelibDevice::Instance().ConfigurePostprocessing(
- "denoise3d", xc.denoise3d ? true : false, xc.Denoise3dOptions());
- cXinelibDevice::Instance().ConfigurePostprocessing(
- xc.deinterlace_method, xc.audio_delay, xc.audio_compression,
- xc.audio_equalizer, xc.audio_surround, xc.speaker_type);
-}
-
-void cMenuSetupVideo::Set(void)
-{
- SetPlugin(cPluginManager::GetPlugin(PLUGIN_NAME_I18N));
- int current = Current();
- Clear();
-
- Add(NewTitle(tr("Video")));
-
- Add(ctrl_vo_aspect_ratio =
- new cMenuEditStraI18nItem(tr("Aspect ratio"), &newconfig.vo_aspect_ratio,
- VO_ASPECT_count, xc.s_vo_aspects));
-
- Add(ctrl_autocrop =
- new cMenuEditBoolItem(tr("Crop letterbox 4:3 to 16:9"),
- &newconfig.autocrop));
- if(newconfig.autocrop) {
- Add(new cMenuEditBoolItem(tr(" Autodetect letterbox"),
- &newconfig.autocrop_autodetect));
- Add(new cMenuEditBoolItem(tr(" Soft start"),
- &newconfig.autocrop_soft));
- Add(new cMenuEditBoolItem(tr(" Crop to"),
- &newconfig.autocrop_fixedsize,
- "4:3...20:9", "14:9/16:9"));
- Add(new cMenuEditBoolItem(tr(" Detect subtitles"),
- &newconfig.autocrop_subs));
- }
-
- ctrl_swscale_resize = ctrl_swscale_aspect = ctrl_swscale_width = ctrl_swscale_height = NULL;
- Add(ctrl_swscale =
- new cMenuEditBoolItem(tr("Software scaling"),
- &newconfig.swscale));
- if(newconfig.swscale) {
- Add(ctrl_swscale_aspect =
- new cMenuEditBoolItem(tr(" Change aspect ratio"),
- &newconfig.swscale_change_aspect));
- Add(ctrl_swscale_resize =
- new cMenuEditBoolItem(tr(" Change video size"),
- &newconfig.swscale_resize));
- if(newconfig.swscale_resize) {
- Add(ctrl_swscale_width =
- new cMenuEditIntItem( tr(" Width"),
- &newconfig.swscale_width, 360, 2000));
- Add(ctrl_swscale_height =
- new cMenuEditIntItem( tr(" Height"),
- &newconfig.swscale_height, 288, 1200));
- Add(new cMenuEditBoolItem(tr(" Allow downscaling"),
- &newconfig.swscale_downscale));
- }
- }
-
- Add(ctrl_overscan =
- new cMenuEditTypedIntItem(tr("Overscan (crop image borders)"), "%",
- &newconfig.overscan, 0, 10,
- tr("Off")));
-
- Add(ctrl_pp = new cMenuEditBoolItem(tr("Post processing (ffmpeg)"),
- &newconfig.ffmpeg_pp));
- if(newconfig.ffmpeg_pp) {
- Add(new cMenuEditIntItem( tr(" Quality"),
- &newconfig.ffmpeg_pp_quality, 0, 6));
- Add(new cMenuEditStrItem( tr(" Mode"), newconfig.ffmpeg_pp_mode,
- 255, OptionsChars));
- }
-
- Add(ctrl_deinterlace =
- new cMenuEditStraI18nItem(tr("Deinterlacing"), &deinterlace,
- DEINTERLACE_count,
- xc.s_deinterlaceMethodNames));
-
- ctrl_tvtime_method = NULL;
- if(deinterlace == DEINTERLACE_TVTIME) {
- Add(ctrl_tvtime_method =
- new cMenuEditStraI18nItem(tr(" Method"), &tvtime.method,
- tvtime_methods_count, tvtime_method_name));
- Add(new cMenuEditBoolItem(tr(" Cheap mode"), &tvtime.cheap_mode));
- Add(new cMenuEditStraI18nItem(tr(" Pulldown"), &tvtime.pulldown,
- 2, tvtime_pulldown_name));
- Add(new cMenuEditStraI18nItem(tr(" Frame rate"), &tvtime.framerate,
- 3, tvtime_framerate_name));
- Add(new cMenuEditBoolItem(tr(" Judder Correction"), &tvtime.judder_correction));
- Add(new cMenuEditBoolItem(tr(" Use progressive frame flag"),
- &tvtime.use_progressive_frame_flag));
- Add(new cMenuEditBoolItem(tr(" Chroma Filter"),
- &tvtime.chroma_filter));
- }
-
- Add(ctrl_unsharp = new cMenuEditBoolItem(tr("Sharpen / Blur"),
- &newconfig.unsharp));
- if(newconfig.unsharp) {
- Add(new cMenuEditOddIntItem( tr(" Width of the luma matrix"),
- &newconfig.unsharp_luma_matrix_width, 3, 11));
- Add(new cMenuEditOddIntItem( tr(" Height of the luma matrix"),
- &newconfig.unsharp_luma_matrix_height, 3, 11));
- Add(new cMenuEditFpIntItem( tr(" Amount of luma sharpness/blur"),
- &newconfig.unsharp_luma_amount, -20, 20, 1,
- tr("Off")));
- Add(new cMenuEditOddIntItem( tr(" Width of the chroma matrix"),
- &newconfig.unsharp_chroma_matrix_width, 3, 11));
- Add(new cMenuEditOddIntItem( tr(" Height of the chroma matrix"),
- &newconfig.unsharp_chroma_matrix_height, 3, 11));
- Add(new cMenuEditFpIntItem( tr(" Amount of chroma sharpness/blur"),
- &newconfig.unsharp_chroma_amount, -20, 20, 1,
- tr("Off")));
- }
-
- Add(ctrl_denoise3d = new cMenuEditBoolItem(tr("3D Denoiser"),
- &newconfig.denoise3d));
- if(newconfig.denoise3d) {
- Add(new cMenuEditFpIntItem( tr(" Spatial luma strength"),
- &newconfig.denoise3d_luma, 0, 100, 1));
- Add(new cMenuEditFpIntItem( tr(" Spatial chroma strength"),
- &newconfig.denoise3d_chroma, 0, 100, 1));
- Add(new cMenuEditFpIntItem( tr(" Temporal strength"),
- &newconfig.denoise3d_time, 0, 100, 1));
- }
-
-
-#ifdef INTEGER_CONFIG_VIDEO_CONTROLS
- Add(new cMenuEditIntItem(tr("HUE"), &newconfig.hue, -1, 0xffff));
- Add(new cMenuEditIntItem(tr("Saturation"), &newconfig.saturation,-1,0xffff));
- Add(new cMenuEditIntItem(tr("Contrast"), &newconfig.contrast, -1, 0xffff));
- Add(new cMenuEditIntItem(tr("Brightness"), &newconfig.brightness,-1,0xffff));
-#ifdef HAVE_VDPAU
- Add(new cMenuEditIntItem(tr("Sharpness"), &newconfig.sharpness, -1,0xffff));
- Add(new cMenuEditIntItem(tr("Noise Reduction"), &newconfig.noise_reduction, -1,0xffff));
-#endif
-#else
- Add(ctrl_hue = new cMenuEditStraItem(tr("HUE"), &newconfig.hue, 33,
- controls));
- Add(ctrl_saturation =
- new cMenuEditStraItem(tr("Saturation"), &newconfig.saturation, 33,
- controls));
- Add(ctrl_contrast =
- new cMenuEditStraItem(tr("Contrast"), &newconfig.contrast, 33,
- controls));
- Add(ctrl_brightness =
- new cMenuEditStraItem(tr("Brightness"), &newconfig.brightness, 33,
- controls));
-#ifdef HAVE_VDPAU
- Add(ctrl_sharpness =
- new cMenuEditStraItem(tr("Sharpness"), &newconfig.sharpness, 33,
- controls));
- Add(ctrl_noise_reduction =
- new cMenuEditStraItem(tr("Noise Reduction"), &newconfig.noise_reduction, 33,
- controls));
-#endif
-#endif
-
-#ifdef DEVICE_SUPPORTS_IBP_TRICKSPEED
- Add(new cMenuEditBoolItem(tr("Smooth fast forward"),
- &newconfig.ibp_trickspeed));
-#endif
- Add(new cMenuEditIntItem(tr("Fastest trick speed"),
- &newconfig.max_trickspeed, 1, 12));
-
- if(current<1) current=1; /* first item is not selectable */
- SetCurrent(Get(current));
- //SetCurrent(Get(1));
- Display();
-}
-
-eOSState cMenuSetupVideo::ProcessKey(eKeys Key)
-{
- cOsdItem *item = Get(Current());
-
- eOSState state = cMenuSetupPage::ProcessKey(Key);
-
- Key = NORMALKEY(Key);
-
- if(Key!=kLeft && Key!=kRight)
- return state;
-
- if(item == ctrl_hue || item == ctrl_saturation ||
- item == ctrl_sharpness || item == ctrl_noise_reduction ||
- item == ctrl_contrast || item == ctrl_brightness ||
- item == ctrl_overscan || item == ctrl_vo_aspect_ratio)
-#ifdef INTEGER_CONFIG_VIDEO_CONTROLS
- cXinelibDevice::Instance().ConfigureVideo(newconfig.hue,
- newconfig.saturation,
- newconfig.brightness,
- newconfig.sharpness,
- newconfig.noise_reduction,
- newconfig.contrast,
- newconfig.overscan,
- newconfig.vo_aspect_ratio);
-#else
- cXinelibDevice::Instance().ConfigureVideo(
- INDEX_TO_CONTROL(newconfig.hue),
- INDEX_TO_CONTROL(newconfig.saturation),
- INDEX_TO_CONTROL(newconfig.brightness),
- INDEX_TO_CONTROL(newconfig.sharpness),
- INDEX_TO_CONTROL(newconfig.noise_reduction),
- INDEX_TO_CONTROL(newconfig.contrast),
- newconfig.overscan, newconfig.vo_aspect_ratio);
-#endif
- else if(item == ctrl_autocrop) {
- cXinelibDevice::Instance().ConfigurePostprocessing(
- "autocrop", newconfig.autocrop ? true : false,
- newconfig.AutocropOptions());
- Set();
- }
- else if(item == ctrl_swscale ||
- item == ctrl_swscale_resize ||
- item == ctrl_swscale_aspect ||
- item == ctrl_swscale_width ||
- item == ctrl_swscale_height) {
- cXinelibDevice::Instance().ConfigurePostprocessing(
- "swscale", newconfig.swscale ? true : false,
- newconfig.SwScaleOptions());
- Set();
- }
- else if(item == ctrl_pp) {
- cXinelibDevice::Instance().ConfigurePostprocessing(
- "pp", newconfig.ffmpeg_pp ? true : false,
- newconfig.FfmpegPpOptions());
- Set();
- }
- else if(item == ctrl_unsharp) {
- cXinelibDevice::Instance().ConfigurePostprocessing(
- "unsharp", newconfig.unsharp ? true : false,
- newconfig.UnsharpOptions());
- Set();
- }
- else if(item == ctrl_denoise3d) {
- cXinelibDevice::Instance().ConfigurePostprocessing(
- "denoise3d", newconfig.denoise3d ? true : false,
- newconfig.Denoise3dOptions());
- Set();
- }
- else if(item == ctrl_deinterlace) {
- if(deinterlace == DEINTERLACE_TVTIME && !ctrl_tvtime_method) {
- Set();
- } else if(deinterlace != DEINTERLACE_TVTIME && ctrl_tvtime_method) {
- Set();
- }
- }
-
- return state;
-}
-
-void cMenuSetupVideo::Store(void)
-{
- memcpy(&xc, &newconfig, sizeof(config_t));
-
-#ifdef INTEGER_CONFIG_VIDEO_CONTROLS
-#else
- xc.hue = INDEX_TO_CONTROL(xc.hue);
- xc.saturation = INDEX_TO_CONTROL(xc.saturation);
- xc.contrast = INDEX_TO_CONTROL(xc.contrast);
- xc.brightness = INDEX_TO_CONTROL(xc.brightness);
- xc.sharpness = INDEX_TO_CONTROL(xc.sharpness);
- xc.noise_reduction = INDEX_TO_CONTROL(xc.noise_reduction);
-#endif
-
- strn0cpy(xc.deinterlace_method, xc.s_deinterlaceMethods[deinterlace], sizeof(xc.deinterlace_method));
- strn0cpy(xc.deinterlace_opts, tvtime.ToString(), sizeof(xc.deinterlace_opts));
- SetupStore("Video.Deinterlace", xc.deinterlace_method);
- SetupStore("Video.DeinterlaceOptions", xc.deinterlace_opts);
-
- SetupStore("Video.AutoCrop", xc.autocrop);
- SetupStore("Video.AutoCrop.AutoDetect", xc.autocrop_autodetect);
- SetupStore("Video.AutoCrop.SoftStart", xc.autocrop_soft);
- SetupStore("Video.AutoCrop.FixedSize", xc.autocrop_fixedsize);
- SetupStore("Video.AutoCrop.DetectSubs", xc.autocrop_subs);
- SetupStore("Video.SwScale", xc.swscale);
- SetupStore("Video.SwScale.Aspect", xc.swscale_change_aspect);
- SetupStore("Video.SwScale.Resize", xc.swscale_resize);
- SetupStore("Video.SwScale.Width", xc.swscale_width);
- SetupStore("Video.SwScale.Height", xc.swscale_height);
- SetupStore("Video.SwScale.Downscale", xc.swscale_downscale);
- SetupStore("Video.HUE", xc.hue);
- SetupStore("Video.Saturation", xc.saturation);
- SetupStore("Video.Contrast", xc.contrast);
- SetupStore("Video.Brightness", xc.brightness);
- SetupStore("Video.Sharpness", xc.sharpness);
- SetupStore("Video.NoiseReduction", xc.noise_reduction);
- SetupStore("Video.Overscan", xc.overscan);
- SetupStore("Video.IBPTrickSpeed", xc.ibp_trickspeed);
- SetupStore("Video.MaxTrickSpeed", xc.max_trickspeed);
- SetupStore("Video.AspectRatio", xc.vo_aspect_ratio);
- SetupStore("Post.pp.Enable", xc.ffmpeg_pp);
- SetupStore("Post.pp.Quality", xc.ffmpeg_pp_quality);
- SetupStore("Post.pp.Mode", xc.ffmpeg_pp_mode);
- SetupStore("Post.unsharp.Enable", xc.unsharp);
- SetupStore("Post.unsharp.luma_matrix_width", xc.unsharp_luma_matrix_width);
- SetupStore("Post.unsharp.luma_matrix_height", xc.unsharp_luma_matrix_height);
- SetupStore("Post.unsharp.luma_amount", xc.unsharp_luma_amount);
- SetupStore("Post.unsharp.chroma_matrix_width", xc.unsharp_chroma_matrix_width);
- SetupStore("Post.unsharp.chroma_matrix_height", xc.unsharp_chroma_matrix_height);
- SetupStore("Post.unsharp.chroma_amount", xc.unsharp_chroma_amount);
- SetupStore("Post.denoise3d.Enable", xc.denoise3d);
- SetupStore("Post.denoise3d.luma", xc.denoise3d_luma);
- SetupStore("Post.denoise3d.chroma", xc.denoise3d_chroma);
- SetupStore("Post.denoise3d.time", xc.denoise3d_time);
- SetupStore("Video.Decoder.MPEG2", xc.s_decoders_MPEG2[xc.decoder_mpeg2]);
- SetupStore("Video.Decoder.H264", xc.s_decoders_H264[xc.decoder_h264]);
-#if 1
- // delete old keys (<1.0.0)
- SetupStore("Video.AutoScale");
-#endif
- Setup.Save();
-}
-
-
-//--- cMenuSetupOSD ----------------------------------------------------------
-
-class cMenuSetupOSD : public cMenuSetupPage
-{
- private:
- config_t newconfig;
-
- int orig_alpha_correction;
- int orig_alpha_correction_abs;
-
- cOsdItem *ctrl_scaling;
- cOsdItem *ctrl_alpha;
- cOsdItem *ctrl_alpha_abs;
- cOsdItem *ctrl_blending;
- cOsdItem *ctrl_lowres;
-
- protected:
- virtual void Store(void);
- void Set(void);
-
- public:
- cMenuSetupOSD(void);
- ~cMenuSetupOSD();
-
- virtual eOSState ProcessKey(eKeys Key);
-};
-
-cMenuSetupOSD::cMenuSetupOSD(void)
-{
- memcpy(&newconfig, &xc, sizeof(config_t));
- orig_alpha_correction = xc.alpha_correction;
- orig_alpha_correction_abs = xc.alpha_correction_abs;
- newconfig.extsub_size++;
-
- Set();
-}
-
-cMenuSetupOSD::~cMenuSetupOSD()
-{
- xc.alpha_correction = orig_alpha_correction;
- xc.alpha_correction_abs = orig_alpha_correction_abs;
-}
-
-void cMenuSetupOSD::Set(void)
-{
- SetPlugin(cPluginManager::GetPlugin(PLUGIN_NAME_I18N));
- int current = Current();
- Clear();
-
- ctrl_scaling = NULL;
- ctrl_blending = NULL;
- ctrl_lowres = NULL;
- ctrl_alpha = NULL;
- ctrl_alpha_abs = NULL;
-
- Add(NewTitle(tr("On-Screen Display")));
- Add(new cMenuEditBoolItem(tr("Hide main menu"),
- &newconfig.hide_main_menu));
-
- Add(ctrl_blending =
- new cMenuEditBoolItem(tr("Blending method"),
- &newconfig.osd_blending,
- tr(xc.s_osdBlendingMethods[OSD_BLENDING_SOFTWARE]),
- tr(xc.s_osdBlendingMethods[OSD_BLENDING_HARDWARE])));
- if(newconfig.osd_blending == OSD_BLENDING_SOFTWARE) {
- Add(ctrl_lowres =
- new cMenuEditBoolItem(tr(" Use hardware for low-res video"),
- &newconfig.osd_blending_lowresvideo));
- }
-
- Add(ctrl_scaling =
- new cMenuEditStraI18nItem(tr("Scaling method"), &newconfig.osd_scaling,
- OSD_SCALING_count, xc.s_osdScalings));
-
- Add(new cMenuEditStraI18nItem(tr("Show all layers"), &newconfig.osd_mixer,
- OSD_MIXER_count, xc.s_osdMixers));
-
- Add(ctrl_alpha =
- new cMenuEditTypedIntItem(tr("Dynamic transparency correction"), "%",
- &newconfig.alpha_correction, -200, 200,
- tr("Off")));
- Add(ctrl_alpha_abs =
- new cMenuEditTypedIntItem(tr("Static transparency correction"), "",
- &newconfig.alpha_correction_abs, -0xff, 0xff,
- tr("Off")));
-
- Add(new cMenuEditStraI18nItem(tr("External subtitle size"),
- &newconfig.extsub_size, SUBTITLESIZE_count, xc.s_subtitleSizes));
-
- Add(new cMenuEditBoolItem(tr("DVB subtitle decoder"),
- &newconfig.dvb_subtitles,
- "VDR",
- "frontend"));
-
- if(current<1) current=1; /* first item is not selectable */
- SetCurrent(Get(current));
- //SetCurrent(Get(1));
- Display();
-}
-
-eOSState cMenuSetupOSD::ProcessKey(eKeys Key)
-{
- cOsdItem *item = Get(Current());
-
- eOSState state = cMenuSetupPage::ProcessKey(Key);
-
- Key = NORMALKEY(Key);
-
- if(Key!=kLeft && Key!=kRight)
- return state;
-
- if(item == ctrl_scaling)
- cXinelibOsdProvider::RefreshOsd();
- else if(item == ctrl_alpha)
- xc.alpha_correction = newconfig.alpha_correction;
- else if(item == ctrl_alpha_abs)
- xc.alpha_correction_abs = newconfig.alpha_correction_abs;
-
- if(newconfig.osd_blending==OSD_BLENDING_SOFTWARE && !ctrl_lowres)
- Set();
- if(newconfig.osd_blending!=OSD_BLENDING_SOFTWARE && ctrl_lowres)
- Set();
- return state;
-}
-
-void cMenuSetupOSD::Store(void)
-{
- newconfig.extsub_size --;
- if(newconfig.extsub_size != xc.extsub_size) {
- cString tmp = cString::sprintf("EXTSUBSIZE %d", newconfig.extsub_size);
- cXinelibDevice::Instance().PlayFileCtrl(tmp);
- }
-
- memcpy(&xc, &newconfig, sizeof(config_t));
- orig_alpha_correction = xc.alpha_correction;
- orig_alpha_correction_abs = xc.alpha_correction_abs;
-
- SetupStore("OSD.Scaling", xc.osd_scaling);
- SetupStore("OSD.HideMainMenu", xc.hide_main_menu);
- SetupStore("OSD.LayersVisible", xc.osd_mixer);
- SetupStore("OSD.Blending", xc.osd_blending);
- SetupStore("OSD.BlendingLowRes", xc.osd_blending_lowresvideo);
-#if 1
- // Delete old keys (<=1.0.0)
- SetupStore("OSD.UnscaledAlways");
- SetupStore("OSD.UnscaledLowRes");
- SetupStore("OSD.UnscaledOpaque");
- SetupStore("OSD.Prescale");
- SetupStore("OSD.Downscale");
-#endif
- SetupStore("OSD.AlphaCorrection", xc.alpha_correction);
- SetupStore("OSD.AlphaCorrectionAbs", xc.alpha_correction_abs);
-
- SetupStore("OSD.ExtSubSize", xc.extsub_size);
- SetupStore("OSD.DvbSubtitles", xc.dvb_subtitles);
-
- Setup.Save();
-}
-
-
-//--- cMenuSetupDecoder ------------------------------------------------------
-
-class cMenuSetupDecoder : public cMenuSetupPage
-{
- private:
- config_t newconfig;
-
- int pes_buffers_ind;
-
- cOsdItem *ctrl_pes_buffers_ind;
- cOsdItem *ctrl_pes_buffers;
-
- protected:
- virtual void Store(void);
- void Set(void);
-
- public:
- cMenuSetupDecoder(void);
-
- virtual eOSState ProcessKey(eKeys Key);
-};
-
-cMenuSetupDecoder::cMenuSetupDecoder(void)
-{
- int i;
- memcpy(&newconfig, &xc, sizeof(config_t));
-
- pes_buffers_ind = PES_BUFFERS_CUSTOM;
- for(i=0;xc.s_bufferSize[i];i++)
- if(xc.pes_buffers == xc.i_pesBufferSize[i])
- pes_buffers_ind = i;
-
- Set();
-}
-
-void cMenuSetupDecoder::Set(void)
-{
- SetPlugin(cPluginManager::GetPlugin(PLUGIN_NAME_I18N));
- int current = Current();
- Clear();
-
- Add(NewTitle(tr("Decoder")));
- Add(ctrl_pes_buffers_ind =
- new cMenuEditStraI18nItem(tr("Buffer size"), &pes_buffers_ind,
- PES_BUFFERS_count, xc.s_bufferSize));
- if(pes_buffers_ind == PES_BUFFERS_CUSTOM)
- Add(ctrl_pes_buffers =
- new cMenuEditIntItem(tr(" Number of PES packets"), &newconfig.pes_buffers,
- 10, 10000));
- else
- ctrl_pes_buffers = NULL;
-
- if(current<1) current=1; /* first item is not selectable */
- SetCurrent(Get(current));
- Display();
-}
-
-eOSState cMenuSetupDecoder::ProcessKey(eKeys Key)
-{
- cOsdItem *item = Get(Current());
-
- eOSState state = cMenuSetupPage::ProcessKey(Key);
-
- Key = NORMALKEY(Key);
-
- if(Key!=kLeft && Key!=kRight)
- return state;
-
- if(item == ctrl_pes_buffers_ind) {
- if(pes_buffers_ind == PES_BUFFERS_CUSTOM && !ctrl_pes_buffers) {
- Set();
- } else if(pes_buffers_ind != PES_BUFFERS_CUSTOM && ctrl_pes_buffers) {
- Set();
- }
- }
-
- return state;
-}
-
-void cMenuSetupDecoder::Store(void)
-{
- int old_buffers = xc.pes_buffers;
-
- //memcpy(&xc, &newconfig, sizeof(config_t));
- xc.pes_buffers = newconfig.pes_buffers;
-
- if(pes_buffers_ind != PES_BUFFERS_CUSTOM)
- xc.pes_buffers = xc.i_pesBufferSize[pes_buffers_ind];
-
- SetupStore("Decoder.PesBuffers", xc.pes_buffers);
-#if 1
- // delete old keys (<1.0.0)
- SetupStore("Decoder.Priority");
- SetupStore("Decoder.InactivityTimer");
-#endif
-
- if(xc.pes_buffers != old_buffers)
- cXinelibDevice::Instance().ConfigureDecoder(xc.pes_buffers);
- Setup.Save();
-}
-
-
-//--- cMenuSetupLocal --------------------------------------------------------
-
-class cMenuSetupLocal : public cMenuSetupPage
-{
- private:
- config_t newconfig;
-
- int local_frontend;
- int local_frontend_orig;
- int audio_driver;
- int audio_driver_orig;
- int video_driver;
- int video_driver_orig;
-
- cOsdItem *ctrl_scale;
- cOsdItem *ctrl_local_fe;
- cOsdItem *ctrl_driver;
- cOsdItem *ctrl_fullscreen;
- cOsdItem *ctrl_window_width;
- cOsdItem *ctrl_window_height;
- cOsdItem *ctrl_interlace_order;
- cOsdItem *ctrl_aspect;
- cOsdItem *ctrl_audio_driver;
- cOsdItem *ctrl_audio_port;
-
- protected:
- virtual void Store(void);
- void Set(void);
-
- public:
- cMenuSetupLocal(void);
- ~cMenuSetupLocal(void);
-
- virtual eOSState ProcessKey(eKeys Key);
-};
-
-cMenuSetupLocal::cMenuSetupLocal(void)
-{
- SetPlugin(cPluginManager::GetPlugin(PLUGIN_NAME_I18N));
-
- memcpy(&newconfig, &xc, sizeof(config_t));
-
- local_frontend_orig = local_frontend = strstra(xc.local_frontend, xc.s_frontends, 0);
- audio_driver_orig = audio_driver = strstra(xc.audio_driver, xc.s_audioDrivers, 0);
-
- video_driver = 0;
- if(local_frontend == FRONTEND_X11)
- video_driver = strstra(xc.video_driver, xc.s_videoDriversX11, 0);
- if(local_frontend == FRONTEND_FB)
- video_driver = strstra(xc.video_driver, xc.s_videoDriversFB, 0);
- video_driver_orig = video_driver;
-
- Set();
-}
-
-cMenuSetupLocal::~cMenuSetupLocal(void)
-{
- cXinelibDevice::Instance().ConfigureWindow(
- xc.fullscreen, xc.width, xc.height, xc.modeswitch, xc.modeline,
- xc.display_aspect, xc.scale_video, xc.field_order);
- cXinelibDevice::Instance().ConfigurePostprocessing(
- xc.deinterlace_method, xc.audio_delay, xc.audio_compression,
- xc.audio_equalizer, xc.audio_surround, xc.speaker_type);
-}
-
-void cMenuSetupLocal::Set(void)
-{
- int current = Current();
- Clear();
-
- ctrl_interlace_order = NULL;
- ctrl_fullscreen = NULL;
- ctrl_window_width = NULL;
- ctrl_window_height = NULL;
- ctrl_driver = NULL;
- ctrl_aspect = NULL;
- ctrl_scale = NULL;
- ctrl_audio_driver = NULL;
- ctrl_audio_port = NULL;
-
- Add(NewTitle(tr("Local Frontend")));
-
- Add(ctrl_local_fe =
- new cMenuEditStraI18nItem(tr("Local Display Frontend"), &local_frontend,
- FRONTEND_count, xc.s_frontendNames));
-
- if(local_frontend == FRONTEND_X11) {
- Add(new cMenuEditBoolItem(tr("Use keyboard"),
- &newconfig.use_x_keyboard));
- }
-
- if(local_frontend != FRONTEND_NONE) {
- cString tmp = cString::sprintf("%s >>", tr("Decoder"));
- Add(new cOsdItem(tmp, osUser1));
- Add(NewTitle(tr("Video")));
- }
-
- if(local_frontend == FRONTEND_X11) {
- Add(ctrl_driver =
- new cMenuEditStraI18nItem(tr("Driver"), &video_driver,
- X11_DRIVER_count,
- xc.s_videoDriverNamesX11));
- Add(new cMenuEditStrItem(tr("Display address"), newconfig.video_port,
- 31, DriverNameChars));
-
- } else if(local_frontend == FRONTEND_FB) {
- Add(ctrl_driver =
- new cMenuEditStraI18nItem(tr("Driver"), &video_driver,
- FB_DRIVER_count,
- xc.s_videoDriverNamesFB));
- Add(new cMenuEditStrItem(tr("Framebuffer device"), newconfig.video_port, 31,
- DriverNameChars));
- }
-#if 0
- if(local_frontend == FRONTEND_FB || !newconfig.fullscreen) {
- Add(new cMenuEditStrItem( "Modeline", newconfig.modeline, 31,
- ModeLineChars));
- Add(new cMenuEditBoolItem("Videomode switching", &xc.modeswitch));
- }
-#endif
-
- if(local_frontend == FRONTEND_X11) {
- Add(ctrl_fullscreen = new cMenuEditBoolItem(tr("Fullscreen mode"),
- &newconfig.fullscreen));
- if(!newconfig.fullscreen) {
- Add(ctrl_window_width =
- new cMenuEditTypedIntItem( tr(" Window width"), tr("px"),
- &newconfig.width, 1, 2048));
- Add(ctrl_window_height =
- new cMenuEditTypedIntItem( tr(" Window height"), tr("px"),
- &newconfig.height, 1, 2048));
- }
- }
-
- if(local_frontend != FRONTEND_NONE) {
- Add(ctrl_aspect =
- new cMenuEditStraI18nItem(tr("Window aspect"), &newconfig.display_aspect,
- ASPECT_count, xc.s_aspects));
- Add(ctrl_scale =
- new cMenuEditBoolItem(tr("Scale to window size"), &newconfig.scale_video));
-
-#ifdef HAVE_XV_FIELD_ORDER
- Add(ctrl_interlace_order =
- new cMenuEditStraI18nItem(tr("Interlaced Field Order"),
- &newconfig.field_order, FIELD_ORDER_count,
- xc.s_fieldOrder));
-#endif
-
- Add(NewTitle(tr("Audio")));
-
- Add(ctrl_audio_driver =
- new cMenuEditStraI18nItem(tr("Driver"), &audio_driver,
- AUDIO_DRIVER_count, xc.s_audioDriverNames));
- if(audio_driver != AUDIO_DRIVER_AUTO && audio_driver != AUDIO_DRIVER_NONE)
- Add(ctrl_audio_port =
- new cMenuEditStrItem(tr("Port"), newconfig.audio_port, 31,
- DriverNameChars));
- }
-
- if(current<1) current=1; /* first item is not selectable */
- SetCurrent(Get(current));
- Display();
-}
-
-eOSState cMenuSetupLocal::ProcessKey(eKeys Key)
-{
- int prev_frontend = local_frontend;
- int prev_audio_driver = audio_driver;
-
- cOsdItem *item = Get(Current());
-
- eOSState state = cMenuSetupPage::ProcessKey(Key);
-
- if(state == osUser1)
- return AddSubMenu(new XinelibOutputSetupMenu::cMenuSetupDecoder);
-
- Key = NORMALKEY(Key);
-
- if((Key!=kLeft && Key!=kRight) || !item)
- return state;
-
- if(item == ctrl_audio_driver) {
- if(prev_audio_driver != audio_driver) {
-
- if(audio_driver == audio_driver_orig)
- strcpy(newconfig.audio_port, xc.audio_port);
- else if(audio_driver == AUDIO_DRIVER_ALSA)
- strcpy(newconfig.audio_port, "default");
- else if(audio_driver == AUDIO_DRIVER_OSS)
- strcpy(newconfig.audio_port, "/dev/dsp");
- else
- strcpy(newconfig.audio_port, "");
- Set();
- }
- else if((audio_driver != AUDIO_DRIVER_AUTO &&
- audio_driver != AUDIO_DRIVER_NONE) &&
- !ctrl_audio_port)
- Set();
- else if((audio_driver == AUDIO_DRIVER_AUTO ||
- audio_driver == AUDIO_DRIVER_NONE) &&
- ctrl_audio_port)
- Set();
- }
- else if(item == ctrl_aspect || item == ctrl_scale || item == ctrl_interlace_order)
- cXinelibDevice::Instance().ConfigureWindow(
- xc.fullscreen, xc.width, xc.height, xc.modeswitch, xc.modeline,
- newconfig.display_aspect, newconfig.scale_video,
- newconfig.field_order);
- else if(item == ctrl_local_fe && local_frontend != prev_frontend) {
-
- if(local_frontend == local_frontend_orig) {
- video_driver = video_driver_orig;
- strcpy(newconfig.video_port, xc.video_port);
- }
- else if(local_frontend == FRONTEND_FB)
- strcpy(newconfig.video_port, "/dev/fb/0");
- else if(local_frontend == FRONTEND_X11)
- strcpy(newconfig.video_port, "0.0");
-
- Set();
- }
- else if(item == ctrl_fullscreen) {
- if(!newconfig.fullscreen && !ctrl_window_width) {
- Set();
- } else if(newconfig.fullscreen && ctrl_window_width) {
- Set();
- }
- }
-
- return state;
-}
-
-void cMenuSetupLocal::Store(void)
-{
- int old_buffers = xc.pes_buffers;
-
- memcpy(&xc, &newconfig, sizeof(config_t));
-
- xc.pes_buffers = old_buffers;
-
- strn0cpy(xc.audio_driver, xc.s_audioDrivers[audio_driver], sizeof(xc.audio_driver));
- strn0cpy(xc.local_frontend, xc.s_frontends[local_frontend], sizeof(xc.local_frontend));
- if(local_frontend == FRONTEND_X11)
- strn0cpy(xc.video_driver, xc.s_videoDriversX11[video_driver], sizeof(xc.video_driver));
- if(local_frontend == FRONTEND_FB)
- strn0cpy(xc.video_driver, xc.s_videoDriversFB[video_driver], sizeof(xc.video_driver));
-
- SetupStore("Frontend", xc.local_frontend);
- SetupStore("Audio.Driver", xc.audio_driver);
- SetupStore("Audio.Port", xc.audio_port);
- SetupStore("Video.Driver", xc.video_driver);
- SetupStore("Video.Port", xc.video_port);
-#if 0
- SetupStore("Video.Port", NULL); /* should delete entry ? */
- SetupStore("Video.Port.X11",xc.video_port_x11);
- SetupStore("Video.Port.FB", xc.video_port_fb);
-#endif
- SetupStore("Video.Scale", xc.scale_video);
- SetupStore("Video.FieldOrder", xc.field_order);
- SetupStore("Modeline", xc.modeline);
- SetupStore("VideoModeSwitching", xc.modeswitch);
- SetupStore("Fullscreen", xc.fullscreen);
- SetupStore("DisplayAspect", xc.s_aspects[xc.display_aspect]);
- SetupStore("X11.WindowWidth", xc.width);
- SetupStore("X11.WindowHeight", xc.height);
- SetupStore("X11.UseKeyboard", xc.use_x_keyboard);
- Setup.Save();
-}
-
-//--- cMenuSetupRemote -------------------------------------------------------
-
-class cMenuSetupRemote : public cMenuSetupPage
-{
- private:
- config_t newconfig;
-
- cOsdItem *ctrl_remote_mode;
- cOsdItem *ctrl_usertp;
- cOsdItem *ctrl_rtp_addr;
- cOsdItem *ctrl_use_http;
- cOsdItem *ctrl_http_ctrl;
- cOsdItem *ctrl_use_rtsp;
- cOsdItem *ctrl_rtsp_ctrl;
-
- protected:
- virtual void Store(void);
- void Set(void);
-
- public:
- cMenuSetupRemote(void);
-
- virtual eOSState ProcessKey(eKeys Key);
-};
-
-cMenuSetupRemote::cMenuSetupRemote(void)
-{
- memcpy(&newconfig, &xc, sizeof(config_t));
- Set();
-}
-
-void cMenuSetupRemote::Set(void)
-{
- int current = Current();
- SetPlugin(cPluginManager::GetPlugin(PLUGIN_NAME_I18N));
- Clear();
-
- Add(NewTitle(tr("Remote Clients")));
- Add(ctrl_remote_mode = new cMenuEditBoolItem(tr("Allow remote clients"),
- &newconfig.remote_mode));
- ctrl_usertp = NULL;
- ctrl_rtp_addr = NULL;
- ctrl_use_http = NULL;
- ctrl_use_rtsp = NULL;
- ctrl_http_ctrl = NULL;
- ctrl_rtsp_ctrl = NULL;
- if(newconfig.remote_mode) {
- Add(new cMenuEditIntItem( tr(" Listen port (TCP and broadcast)"),
- &newconfig.listen_port,
- 0, 0xffff));
- Add(new cMenuEditStrItem( tr(" Listen address"),
- &newconfig.remote_local_ip[0], 16, "0123456789."));
- Add(new cMenuEditBoolItem(tr(" Remote keyboard"),
- &newconfig.remote_keyboard));
- Add(new cMenuEditIntItem( tr(" Max number of clients"),
- &newconfig.remote_max_clients,
- 1, MAXCLIENTS));
-
- Add(new cMenuEditBoolItem(tr(" PIPE transport"),
- &newconfig.remote_usepipe));
- Add(new cMenuEditBoolItem(tr(" TCP transport"),
- &newconfig.remote_usetcp));
- Add(new cMenuEditBoolItem(tr(" UDP transport"),
- &newconfig.remote_useudp));
- Add(ctrl_usertp =
- new cMenuEditBoolItem(tr(" RTP (multicast) transport"),
- &newconfig.remote_usertp));
- if(newconfig.remote_usertp) {
- Add(ctrl_rtp_addr =
- new cMenuEditStrItem( tr(" Address"),
- &newconfig.remote_rtp_addr[0], 16, "0123456789."));
- Add(new cMenuEditOddIntItem( tr(" Port"),
- &newconfig.remote_rtp_port, 1000, 0xfffe));
- Add(new cMenuEditIntItem( tr(" TTL"),
- &newconfig.remote_rtp_ttl, 1, 10));
- Add(new cMenuEditBoolItem(tr(" Transmit always on"),
- &newconfig.remote_rtp_always_on));
- Add(new cMenuEditBoolItem(tr(" SAP announcements"),
- &newconfig.remote_rtp_sap));
- }
- Add(new cMenuEditBoolItem(tr(" Server announce broadcasts"),
- &newconfig.remote_usebcast));
-
- Add(new cMenuEditBoolItem(tr(" HTTP transport for media files"),
- &newconfig.remote_http_files));
-
- Add(NewTitle(tr("Additional network services")));
- Add(ctrl_use_http =
- new cMenuEditBoolItem(tr("HTTP server"),
- &newconfig.remote_use_http));
- if(newconfig.remote_use_http)
- Add(ctrl_http_ctrl =
- new cMenuEditBoolItem(tr("HTTP clients can control VDR"),
- &newconfig.remote_use_http_ctrl));
- Add(ctrl_use_rtsp =
- new cMenuEditBoolItem(tr("RTSP server"),
- &newconfig.remote_use_rtsp));
- if(newconfig.remote_use_rtsp)
- Add(ctrl_rtsp_ctrl =
- new cMenuEditBoolItem(tr("RTSP clients can control VDR"),
- &newconfig.remote_use_rtsp_ctrl));
- }
-
- if(current<1) current=1; /* first item is not selectable */
- SetCurrent(Get(current));
- Display();
-}
-
-eOSState cMenuSetupRemote::ProcessKey(eKeys Key)
-{
- cOsdItem *item = Get(Current());
-
- eOSState state = cMenuSetupPage::ProcessKey(Key);
-
- Key = NORMALKEY(Key);
-
- if(Key!=kLeft && Key!=kRight)
- return state;
-
- if(item == ctrl_remote_mode) {
- if(newconfig.remote_mode && !ctrl_usertp) {
- Set();
- } else if(!newconfig.remote_mode && ctrl_usertp) {
- Set();
- }
- }
- if(item == ctrl_usertp) {
- if(newconfig.remote_usertp && !ctrl_rtp_addr) {
- Set();
- } else if(!newconfig.remote_usertp && ctrl_rtp_addr) {
- Set();
- }
- }
- if(item == ctrl_use_http) {
- if(newconfig.remote_use_http && !ctrl_http_ctrl) {
- Set();
- } else if(!newconfig.remote_use_http && ctrl_http_ctrl) {
- Set();
- }
- }
- if(item == ctrl_use_rtsp) {
- if(newconfig.remote_use_rtsp && !ctrl_rtsp_ctrl) {
- Set();
- } else if(!newconfig.remote_use_rtsp && ctrl_rtsp_ctrl) {
- Set();
- }
- }
-
- return state;
-}
-
-void cMenuSetupRemote::Store(void)
-{
- memcpy(&xc, &newconfig, sizeof(config_t));
-
- SetupStore("RemoteMode", xc.remote_mode);
- SetupStore("Remote.ListenPort", xc.listen_port);
- SetupStore("Remote.Iface", xc.remote_local_if);
- SetupStore("Remote.LocalIP", xc.remote_local_ip);
- SetupStore("Remote.Keyboard", xc.remote_keyboard);
-
- SetupStore("Remote.MaxClients", xc.remote_max_clients);
- SetupStore("Remote.UsePipe",xc.remote_usepipe);
- SetupStore("Remote.UseTcp", xc.remote_usetcp);
- SetupStore("Remote.UseUdp", xc.remote_useudp);
- SetupStore("Remote.UseRtp", xc.remote_usertp);
- SetupStore("Remote.UseBroadcast", xc.remote_usebcast);
-
- SetupStore("Remote.UseHttp", xc.remote_http_files);
-
- SetupStore("Remote.Rtp.Address", xc.remote_rtp_addr);
- SetupStore("Remote.Rtp.Port", xc.remote_rtp_port);
- SetupStore("Remote.Rtp.TTL", xc.remote_rtp_ttl);
- SetupStore("Remote.Rtp.AlwaysOn", xc.remote_rtp_always_on);
- SetupStore("Remote.Rtp.SapAnnouncements", xc.remote_rtp_sap);
-
- SetupStore("Remote.AllowRtsp", xc.remote_use_rtsp);
- SetupStore("Remote.AllowRtspCtrl", xc.remote_use_rtsp_ctrl);
- SetupStore("Remote.AllowHttp", xc.remote_use_http);
- SetupStore("Remote.AllowHttpCtrl", xc.remote_use_http_ctrl);
-
- cXinelibDevice::Instance().Listen(xc.remote_mode, xc.listen_port);
- Setup.Save();
-}
-
-//--- cMenuSetupMediaPlayer --------------------------------------------------------
-
-class cMenuSetupMediaPlayer : public cMenuSetupPage
-{
- private:
- config_t newconfig;
-
- cOsdItem *media_ctrl_playlist_tracknumber;
- cOsdItem *media_ctrl_playlist_artist;
- cOsdItem *media_ctrl_playlist_album;
- cOsdItem *media_ctrl_playlist_cache;
- cOsdItem *media_ctrl_playlist_id3scanner;
-
- protected:
- virtual void Store(void);
- void Set(void);
-
- public:
- cMenuSetupMediaPlayer(void);
-
- virtual eOSState ProcessKey(eKeys Key);
-};
-
-cMenuSetupMediaPlayer::cMenuSetupMediaPlayer(void)
-{
- memcpy(&newconfig, &xc, sizeof(config_t));
- Set();
-}
-
-void cMenuSetupMediaPlayer::Set(void)
-{
- SetPlugin(cPluginManager::GetPlugin(PLUGIN_NAME_I18N));
- int current = Current();
- Clear();
-
- Add(NewTitle(tr("Playlist settings")));
-
- Add(media_ctrl_playlist_tracknumber =
- new cMenuEditBoolItem(tr("Show the track number"),
- &newconfig.playlist_tracknumber));
-
- Add(media_ctrl_playlist_artist =
- new cMenuEditBoolItem(tr("Show the name of the artist"),
- &newconfig.playlist_artist));
-
- Add(media_ctrl_playlist_album =
- new cMenuEditBoolItem(tr("Show the name of the album"),
- &newconfig.playlist_album));
-
- Add(media_ctrl_playlist_id3scanner =
- new cMenuEditBoolItem(tr("Scan for metainfo"),
- &newconfig.enable_id3_scanner));
-
- Add(media_ctrl_playlist_cache =
- new cMenuEditBoolItem(tr("Cache metainfo"),
- &newconfig.cache_implicit_playlists));
-
- Add(new cMenuEditBoolItem(tr("Arrow keys control DVD playback"),
- &newconfig.dvd_arrow_keys_control_playback));
-
- if(current<1) current=1; /* first item is not selectable */
- SetCurrent(Get(current));
- Display();
-}
-
-eOSState cMenuSetupMediaPlayer::ProcessKey(eKeys Key)
-{
- eOSState state = cMenuSetupPage::ProcessKey(Key);
- return state;
-}
-
-void cMenuSetupMediaPlayer::Store(void)
-{
- memcpy(&xc, &newconfig, sizeof(config_t));
-
- SetupStore("Playlist.Tracknumber", xc.playlist_tracknumber);
- SetupStore("Playlist.Album", xc.playlist_album);
- SetupStore("Playlist.Artist", xc.playlist_artist);
- SetupStore("Media.CacheImplicitPlaylists", xc.cache_implicit_playlists);
- SetupStore("Media.EnableID3Scanner", xc.enable_id3_scanner);
- SetupStore("Media.DVD.ArrowKeysControlPlayback", xc.dvd_arrow_keys_control_playback);
-
- Setup.Save();
-}
-
-} // namespace
-
-
-//--- cMenuTestImages ------------------------------------------------------
-
-#include <vdr/osdbase.h>
-
-#define OSD_W (720-2)
-#define OSD_H (576-2)
-#define OSD_X (1)
-#define OSD_Y (1)
-
-//
-// cTestGrayscale
-//
-
-class cTestGrayscale : public cOsdObject
-{
- private:
- cOsd *m_Osd;
-
- public:
- cTestGrayscale() { m_Osd = NULL; }
- virtual ~cTestGrayscale() { delete m_Osd; }
-
- virtual void Show();
- virtual eOSState ProcessKey(eKeys Key);
-};
-
-void cTestGrayscale::Show()
-{
- tArea areas [] = { { 0, 0, OSD_W/2 - 1, OSD_H - 1, 8},
- {OSD_W/2, 0, OSD_W - 1, OSD_H - 1, 8}};
- int i;
-
- if(!m_Osd)
- m_Osd = cOsdProvider::NewOsd(OSD_X, OSD_Y, 0);
-
- if(m_Osd) {
- if (m_Osd->CanHandleAreas(areas, sizeof(areas) / sizeof(tArea) ) == oeOk) {
- m_Osd->SetAreas(areas, sizeof(areas) / sizeof(tArea));
- m_Osd->Flush();
-
- // border
- m_Osd->DrawRectangle(0, 0, OSD_W - 1, OSD_H - 1, 0xff000000);
- m_Osd->DrawRectangle(1, 1, OSD_W - 2, OSD_H - 2, 0xff000000);
-
- // background
- m_Osd->DrawRectangle(2, 2, 2+103, OSD_H - 3, 0xffffffff);
- m_Osd->DrawRectangle(OSD_W-2-103, 2, OSD_W-2, OSD_H - 3, 0xff000000);
-
- for(i=0; i<0xff; i++)
- m_Osd->DrawRectangle(2+103+2*i, 2, 2+103+2*(i+1), OSD_H - 3,
- 0xff000000|(i*0x00010101)/*=(i<<16)|(i<<8)|(i)*/);
- // line
- m_Osd->DrawRectangle(1, OSD_H/2-20, OSD_W - 2, OSD_H/2, 0xffffffff);
- m_Osd->DrawRectangle(1, OSD_H/2+1, OSD_W - 2, OSD_H/2+21, 0xff000000);
-
- // Cross
- for(int x=0; x<OSD_W;x++) {
- m_Osd->DrawPixel(x, x*OSD_H/OSD_W, 0x00000000);
- m_Osd->DrawPixel(x, OSD_H - 1 - x*OSD_H/OSD_W, 0x00000000);
- }
-
- // commit
- m_Osd->Flush();
- }
-
- }
-}
-
-eOSState cTestGrayscale::ProcessKey(eKeys key)
-{
- char s[32];
- static int br = xc.brightness;
- static int co = xc.contrast;
- eOSState state = cOsdObject::ProcessKey(key);
- if (state == osUnknown) {
- switch (key & ~k_Repeat) {
- case kOk:
- case kBack:
- return osEnd;
- case kRight:
- br += 0xffff/1024*2;
- case kLeft:
- br -= 0xffff/1024;
- sprintf(s, "b %d", br);
- m_Osd->DrawText(400, 100, s, 0xff000000, 0xffffffff, cFont::GetFont(fontSml));
- cXinelibDevice::Instance().ConfigureVideo(xc.hue, xc.saturation, br, xc.sharpness, xc.noise_reduction, co, xc.overscan, xc.vo_aspect_ratio);
- m_Osd->Flush();
- return osContinue;
- case kUp:
- co += 0xffff/1024*2;
- case kDown:
- co -= 0xffff/1024;
- sprintf(s, "c %d", co);
- m_Osd->DrawText(400, 130, s, 0xff000000, 0xffffffff, cFont::GetFont(fontSml));
- cXinelibDevice::Instance().ConfigureVideo(xc.hue, xc.saturation, br, xc.sharpness, xc.noise_reduction, co, xc.overscan, xc.vo_aspect_ratio);
- m_Osd->Flush();
- return osContinue;
- }
- }
- return state;
-}
-
-
-//
-// cTestBitmap
-//
-
-class cTestBitmap : public cOsdObject
-{
- private:
- cOsd *m_Osd;
- int bpp;
-
- public:
- cTestBitmap(int _bpp = 1) {
- m_Osd = NULL;
- if(_bpp<1) _bpp = 1;
- if(_bpp>6) _bpp = 6;
- bpp = 1<<_bpp;
- }
- virtual ~cTestBitmap() { delete m_Osd; }
-
- virtual void Show();
- virtual eOSState ProcessKey(eKeys Key);
-};
-
-void cTestBitmap::Show()
-{
- tArea areas [] = {{ 0, 0, OSD_W - 1, OSD_H - 1, 8}};
- int x, y, bit = 0;
-
- if(!m_Osd) {
- m_Osd = cOsdProvider::NewOsd(OSD_X, OSD_Y, 0);
-
- if(m_Osd) {
- if (m_Osd->CanHandleAreas(areas, sizeof(areas) / sizeof(tArea) ) == oeOk) {
- m_Osd->SetAreas(areas, sizeof(areas) / sizeof(tArea));
- m_Osd->Flush();
- }
- }
- }
-
- if(m_Osd) {
- for(x=0; x<OSD_W; x+=bpp) {
- bit = (x/bpp) & 1;
- for(y=0; y<OSD_H; y+=bpp) {
- m_Osd->DrawRectangle(x, y, x+bpp, y+bpp, bit?0xffffffff:0xff000000);
- bit = !bit;
- }
- }
- // commit
- m_Osd->Flush();
- }
-}
-
-eOSState cTestBitmap::ProcessKey(eKeys key)
-{
- eOSState state = cOsdObject::ProcessKey(key);
-
- if (state == osUnknown) {
- switch (key & ~k_Repeat) {
- case kOk:
- case kBack:
- return osEnd;
- case kRight:
- bpp = (bpp<64) ? (bpp<<1) : 1;
- Show();
- return osContinue;
- case kLeft:
- bpp = (bpp>1) ? (bpp>>1) : 64;
- Show();
- return osContinue;
- default:
- break;
- }
- }
- return state;
-}
-
-//
-// cMenuTestImages
-//
-
-#include <vdr/remote.h> // CallPlugin
-
-extern cOsdObject *g_PendingMenuAction;
-
-class cMenuTestImages : public cMenuSetupPage {
-
- protected:
- void Set(void);
- virtual void Store(void) {};
-
- public:
- cMenuTestImages();
-
- virtual eOSState ProcessKey(eKeys Key);
-};
-
-cMenuTestImages::cMenuTestImages()
-{
- Set();
-}
-
-void cMenuTestImages::Set(void)
-{
- char buf[128];
- Clear();
-
- SetHasHotkeys();
- Add(new cOsdItem(tr("Grayscale"), osUser1));
-
- snprintf(buf, sizeof(buf), "%s 1bit", tr("Bitmap"));
- buf[sizeof(buf)-1] = 0;
- Add(new cOsdItem(buf, osUser2));
-
- snprintf(buf, sizeof(buf), "%s 4bit", tr("Bitmap"));
- buf[sizeof(buf)-1] = 0;
- Add(new cOsdItem(buf, osUser3));
-
- Display();
-}
-
-eOSState cMenuTestImages::ProcessKey(eKeys Key)
-{
- eOSState state = cMenuSetupPage::ProcessKey(Key);
-
- switch (state) {
- case osUser1:
- if(cRemote::CallPlugin("xineliboutput"))
- g_PendingMenuAction = new cTestGrayscale();
- return osEnd;
- case osUser2:
- if(cRemote::CallPlugin("xineliboutput"))
- g_PendingMenuAction = new cTestBitmap(1);
- return osEnd;
- case osUser3:
- if(cRemote::CallPlugin("xineliboutput"))
- g_PendingMenuAction = new cTestBitmap(4);
- return osEnd;
- default: ;
- }
-
- return state;
-}
-
-//--- cMenuSetupXinelib ------------------------------------------------------
-
-cMenuSetupXinelib::cMenuSetupXinelib(void)
-{
- XinelibOutputSetupMenu::controls[0] = tr("Off");
- Set();
-}
-
-void cMenuSetupXinelib::Set(void)
-{
- Clear();
-
- SetHasHotkeys();
- Add(new cOsdItem(hk(tr("Audio")), osUser1));
- Add(new cOsdItem(hk(tr("Audio Equalizer")),osUser2));
- Add(new cOsdItem(hk(tr("Video")), osUser3));
- Add(new cOsdItem(hk(tr("OSD")), osUser4));
- //Add(new cOsdItem(hk(tr("Decoder")), osUser5));
- Add(new cOsdItem(hk(tr("Media Player")), osUser5));
- Add(new cOsdItem(hk(tr("Local Frontend")), osUser6));
- Add(new cOsdItem(hk(tr("Remote Clients")), osUser7));
- Add(new cOsdItem(hk(tr("Test Images")), osUser8));
-
- Display();
-}
-
-eOSState cMenuSetupXinelib::ProcessKey(eKeys Key)
-{
- eOSState state = cMenuSetupPage::ProcessKey(Key);
-
- switch (state) {
- case osUser1:
- return AddSubMenu(new XinelibOutputSetupMenu::cMenuSetupAudio);
- case osUser2:
- return AddSubMenu(new XinelibOutputSetupMenu::cMenuSetupAudioEq);
- case osUser3:
- return AddSubMenu(new XinelibOutputSetupMenu::cMenuSetupVideo);
- case osUser4:
- return AddSubMenu(new XinelibOutputSetupMenu::cMenuSetupOSD);
- case osUser5:
- return AddSubMenu(new XinelibOutputSetupMenu::cMenuSetupMediaPlayer);
- case osUser6:
- return AddSubMenu(new XinelibOutputSetupMenu::cMenuSetupLocal);
- case osUser7:
- return AddSubMenu(new XinelibOutputSetupMenu::cMenuSetupRemote);
- case osUser8:
- return AddSubMenu(new cMenuTestImages);
-
- default: ;
- }
-
- return state;
-}
-
-
diff --git a/setup_menu.h b/setup_menu.h
deleted file mode 100644
index d77cc797..00000000
--- a/setup_menu.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * setup_menu.h: Setup Menu
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: setup_menu.h,v 1.1 2006-06-03 09:50:54 phintuka Exp $
- *
- */
-
-#ifndef __XINELIB_SETUP_MENU_H
-#define __XINELIB_SETUP_MENU_H
-
-#include <vdr/menuitems.h>
-
-class cMenuSetupXinelib : public cMenuSetupPage {
-
- protected:
- void Set(void);
- virtual void Store(void) {};
-
- public:
- cMenuSetupXinelib(void);
- virtual eOSState ProcessKey(eKeys Key);
-};
-
-#endif //__XINELIB_SETUP_MENU_H
diff --git a/tools.c b/tools.c
deleted file mode 100644
index 480325f0..00000000
--- a/tools.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * tools.c: VDR/C++ wrapper for common tools
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: tools.c,v 1.2 2009-01-27 09:25:22 phintuka Exp $
- *
- */
-
-#define __STDC_CONSTANT_MACROS
-#include <stdint.h>
-#define __STDC_FORMAT_MACROS
-#include <inttypes.h>
-
-#include <vdr/tools.h>
-#include "logdefs.h"
-
-//#include "tools/vdrdiscovery.c"
-
-#include "tools/pes.c"
-#include "tools/mpeg.c"
-#include "tools/h264.c"
-#include "tools/ts.c"
diff --git a/tools/backgroundwriter.h b/tools/backgroundwriter.h
deleted file mode 100644
index d7a0dacc..00000000
--- a/tools/backgroundwriter.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * backgroundwriter.h: Buffered socket/file writing thread
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: backgroundwriter.h,v 1.5 2009-07-21 10:45:13 phintuka Exp $
- *
- */
-
-#ifndef __BACKGROUNDWRITER_H
-#define __BACKGROUNDWRITER_H
-
-#include <stdint.h>
-
-#include <vdr/thread.h>
-#include <vdr/ringbuffer.h>
-
-//
-// cBackgroundWriterI
-// - generic interface for buffered output
-//
-class cBackgroundWriterI : public cThread
-{
- protected:
- cRingBufferLinear m_RingBuffer;
-
- volatile bool m_Active;
- int m_fd;
- bool m_IsSocket;
-
- uint64_t m_PutPos;
- uint64_t m_DiscardStart;
- uint64_t m_DiscardEnd;
-
- int m_BufferOverflows;
-
- protected:
- virtual void Action(void) = 0;
- void Cork(void);
-
- public:
- cBackgroundWriterI(int fd, int Size = KILOBYTE(512), int Margin = 0);
- virtual ~cBackgroundWriterI();
-
- // Add PES frame to buffer
- //
- // Return value:
- // Success: Count (all bytes pushed to queue)
- // Error: 0 (write error ; socket disconnected)
- // Buffer full: -Count (no bytes will be pushed to queue)
- //
- virtual int Put(uint64_t StreamPos, const uchar *Data, int DataCount) = 0;
-
- int Free(void); // Return largest possible Put size
- void Clear(void); // Drop all data (only complete frames) from buffer
- bool Flush(int TimeoutMs); // Flush buffer (wait for data to be sent)
-};
-
-
-//
-// cTcpWriter
-// - xineliboutput TCP data steam
-// - stream_tcp_header_t encapsulated PES frames
-//
-class cTcpWriter : public cBackgroundWriterI
-{
- protected:
- virtual void Action(void);
-
- int Put(const uchar *Header, int HeaderCount,
- const uchar *Data, int DataCount);
-
- public:
- cTcpWriter(int fd, int Size = KILOBYTE(512));
- virtual ~cTcpWriter() {};
-
- virtual int Put(uint64_t StreamPos, const uchar *Data, int DataCount);
-};
-
-
-//
-// cRawWriter
-// - Raw PES stream
-// - Used with HTTP
-//
-class cRawWriter : public cBackgroundWriterI
-{
- protected:
- virtual void Action(void);
-
- public:
- cRawWriter(int fd, int Size = KILOBYTE(512));
- virtual ~cRawWriter() {};
-
- virtual int Put(uint64_t StreamPos, const uchar *Data, int DataCount);
-};
-
-
-//
-// cTsWriter
-// - Demux PES stream to PS
-//
-class cTsWriter : public cBackgroundWriterI
-{
- protected:
- virtual void Action(void);
-
- public:
- cTsWriter(int fd, int Size = KILOBYTE(512));
- virtual ~cTsWriter() {};
-
- virtual int Put(uint64_t StreamPos, const uchar *Data, int DataCount);
-};
-
-
-//
-// cRtspMuxWriter
-// - RTSP multiplexed control+data
-// - Each encapsulated PES frame is written atomically to socket buffer
-// - Atomic control data can be written directly to socket
-// from another thread to bypass buffer
-//
-
-class cRtspMuxWriter : public cBackgroundWriterI
-{
- protected:
- virtual void Action(void);
-
- public:
- cRtspMuxWriter(int fd, int Size = KILOBYTE(512));
- virtual ~cRtspMuxWriter() {};
-
- virtual int Put(uint64_t StreamPos, const uchar *Data, int DataCount);
-};
-
-
-//
-// cRtspRemuxWriter
-// - RTSP multiplexed control+data
-// - Demux PES stream to independent ES streams
-// - encapsulate ES to RTP/AVP compatible frames
-// - Mux RTP/AVP ES streams to pipelined RTCP control connection
-// - Each encapsulated frame is written atomically to socket buffer
-// - Atomic control data can be written directly to socket
-// from another thread to bypass buffer
-//
-
-class cRtspRemuxWriter : public cBackgroundWriterI
-{
- protected:
- virtual void Action(void);
-
- public:
- cRtspRemuxWriter(int fd, int Size = KILOBYTE(512));
- virtual ~cRtspRemuxWriter() {};
-
- virtual int Put(uint64_t StreamPos, const uchar *Data, int DataCount);
-};
-
-
-#endif
diff --git a/tools/bitstream.h b/tools/bitstream.h
deleted file mode 100644
index 569c491b..00000000
--- a/tools/bitstream.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * bitstream.h: generic bitstream parsing
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: bitstream.h,v 1.3 2009-02-14 20:44:15 phintuka Exp $
- *
- */
-
-#ifndef _XINELIBOUTPUT_BITSTREAM_H_
-#define _XINELIBOUTPUT_BITSTREAM_H_
-
-
-# ifdef NOCACHE
-
-typedef struct {
- const uint8_t *data;
- int count; /* in bits */
- int index; /* in bits */
-} br_state;
-
-#define BR_INIT(data,bytes) { (data), 8*(bytes), 0 }
-
-#define BR_EOF(br) ((br)->index >= (br)->count)
-
-static inline void br_init(br_state *br, const uint8_t *data, int bytes)
-{
- br->data = data;
- br->count = 8*bytes;
- br->index = 0;
-}
-
-static inline int br_get_bit(br_state *br)
-{
- if(br->index >= br->count)
- return 1; /* -> no infinite colomb's ... */
-
- int r = (br->data[br->index>>3] >> (7 - (br->index&7))) & 1;
- br->index++;
- return r;
-}
-
-static inline uint32_t br_get_bits(br_state *br, uint32_t n)
-{
- uint32_t r = 0;
- while(n--)
- r = r | (br_get_bit(br) << n);
- return r;
-}
-
-#define br_skip_bit(br) br_skip_bits(br,1)
-
-static inline void br_skip_bits(br_state *br, int n)
-{
- br->index += n;
-}
-
-
-# else /* NOCACHE */
-
-
-typedef struct {
- uint8_t *data;
- uint8_t *data_end;
- uint32_t cache;
- uint32_t cache_bits;
-} br_state;
-
-#define BR_INIT(data,bytes) { (data), (data)+(bytes), 0, 0 }
-
-static inline void br_init(br_state *br, const uint8_t *data, int bytes)
-{
- br->data = data;
- br->data_end = data + bytes;
- br->cache = 0;
- br->cache_bits = 0;
-}
-
-#define BR_GET_BYTE(br) \
- (br->data < br->data_end ? *br->data++ : 0xff)
-
-#define BR_EOF(br) ((br)->data >= (br)->data_end)
-
-static inline uint32_t br_get_bits(br_state *br, uint32_t n)
-{
- if(n > 24)
- return (br_get_bits(br, 16) << 16) | br_get_bits(br, n-16);
-
- while (br->cache_bits < 24) {
- br->cache = (br->cache<<8) | BR_GET_BYTE(br);
- br->cache_bits += 8;
- }
-
- br->cache_bits -= n;
- return (br->cache >> br->cache_bits) & ((1<<n) - 1);
-}
-
-static inline int br_get_bit(br_state *br)
-{
- if(!br->cache_bits) {
- br->cache = BR_GET_BYTE(br);
- br->cache_bits = 7;
- } else {
- br->cache_bits--;
- }
- return (br->cache >> br->cache_bits) & 1;
-}
-
-static inline void br_skip_bit(br_state *br)
-{
- if(!br->cache_bits) {
- br->cache = BR_GET_BYTE(br);
- br->cache_bits = 7;
- } else {
- br->cache_bits--;
- }
-}
-
-static inline void br_skip_bits(br_state *br, int n)
-{
- if(br->cache_bits >= n) {
- br->cache_bits -= n;
- } else {
- /* drop cached bits */
- n -= br->cache_bits;
-
- /* drop full bytes */
- br->data += (n >> 3);
- n &= 7;
-
- /* update cache */
- if(n) {
- br->cache = BR_GET_BYTE(br);
- br->cache_bits = 8 - n;
- } else {
- br->cache_bits = 0;
- }
- }
-}
-
-
-# endif /* NOCACHE */
-
-
-#define br_get_u8(br) br_get_bits(br, 8)
-#define br_get_u16(br) ((br_get_bits(br, 8)<<8) | br_get_bits(br, 8))
-
-static inline uint32_t br_get_ue_golomb(br_state *br)
-{
- int n = 0;
- while (!br_get_bit(br) && n < 32)
- n++;
- return n ? ((1<<n) - 1) + br_get_bits(br, n) : 0;
-}
-
-static inline int32_t br_get_se_golomb(br_state *br)
-{
- uint32_t r = br_get_ue_golomb(br) + 1;
- return (r&1) ? -(r>>1) : (r>>1);
-}
-
-static inline void br_skip_golomb(br_state *br)
-{
- int n = 0;
- while (!br_get_bit(br) && n < 32)
- n++;
- br_skip_bits(br, n);
-}
-
-#define br_skip_ue_golomb(br) br_skip_golomb(br)
-#define br_skip_se_golomb(br) br_skip_golomb(br)
-
-
-#endif /* _XINELIBOUTPUT_BITSTREAM_H_ */
diff --git a/tools/cxsocket.c b/tools/cxsocket.c
deleted file mode 100644
index e6a95a72..00000000
--- a/tools/cxsocket.c
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * cxsocket.c: Socket wrapper classes
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: cxsocket.c,v 1.11 2007-03-27 02:45:48 phintuka Exp $
- *
- */
-
-#define __STDC_FORMAT_MACROS
-#include <inttypes.h>
-
-#include <stdlib.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#ifndef __APPLE__
-# include <sys/sendfile.h>
-#endif
-#include <netinet/tcp.h>
-
-#include <vdr/config.h>
-#include <vdr/tools.h>
-
-#include "../logdefs.h"
-
-#include "cxsocket.h"
-
-bool cxSocket::connect(struct sockaddr *addr, socklen_t len)
-{
- return ::connect(m_fd, addr, len) == 0;
-}
-
-bool cxSocket::connect(const char *ip, int port)
-{
- struct sockaddr_in sin;
- sin.sin_family = AF_INET;
- sin.sin_port = htons(port);
- sin.sin_addr.s_addr = inet_addr(ip);
- return connect((struct sockaddr *)&sin, sizeof(sin));
-}
-
-bool cxSocket::set_blocking(bool state)
-{
- int flags = fcntl (m_fd, F_GETFL);
-
- if(flags == -1) {
- LOGERR("cxSocket::SetBlocking: fcntl(F_GETFL) failed");
- return false;
- }
-
- flags = state ? (flags&(~O_NONBLOCK)) : (flags|O_NONBLOCK);
-
- if(fcntl (m_fd, F_SETFL, flags) == -1) {
- LOGERR("cxSocket::SetBlocking: fcntl(F_SETFL) failed");
- return false;
- }
-
- return true;
-}
-
-bool cxSocket::set_buffers(int Tx, int Rx)
-{
- int max_buf = Tx;
- /*while(max_buf) {*/
- errno = 0;
- if(setsockopt(m_fd, SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(int))) {
- LOGERR("cxSocket: setsockopt(SO_SNDBUF,%d) failed", max_buf);
- /*max_buf >>= 1;*/
- }
- /*else {*/
- int tmp = 0;
- int len = sizeof(int);
- errno = 0;
- if(getsockopt(m_fd, SOL_SOCKET, SO_SNDBUF, &tmp, (socklen_t*)&len)) {
- LOGERR("cxSocket: getsockopt(SO_SNDBUF,%d) failed", max_buf);
- /*break;*/
- } else if(tmp != max_buf) {
- LOGDBG("cxSocket: setsockopt(SO_SNDBUF): got %d bytes", tmp);
- /*max_buf >>= 1;*/
- /*continue;*/
- }
- /*}*/
- /*}*/
-
- max_buf = Rx;
- setsockopt(m_fd, SOL_SOCKET, SO_RCVBUF, &max_buf, sizeof(int));
-
- return true;
-}
-
-bool cxSocket::set_multicast(int ttl)
-{
- int iReuse = 1, iLoop = 1, iTtl = ttl;
-
- errno = 0;
-
- if(setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, &iReuse, sizeof(int)) < 0) {
- LOGERR("cxSocket: setsockopt(SO_REUSEADDR) failed");
- return false;
- }
-
- if(setsockopt(m_fd, IPPROTO_IP, IP_MULTICAST_TTL, &iTtl, sizeof(int))) {
- LOGERR("cxSocket: setsockopt(IP_MULTICAST_TTL, %d) failed", iTtl);
- return false;
- }
-
- if(setsockopt(m_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &iLoop, sizeof(int))) {
- LOGERR("cxSocket: setsockopt(IP_MULTICAST_LOOP) failed");
- return false;
- }
-
- return true;
-}
-
-ssize_t cxSocket::sendfile(int fd_file, off_t *offset, size_t count)
-{
- int r;
-#ifndef __APPLE__
- r = ::sendfile(m_fd, fd_file, offset, count);
- if(r<0 && (errno == ENOSYS || errno == EINVAL)) {
- // fall back to read/write
- LOGERR("sendfile failed - using simple read/write");
-#endif
- cxPoller p(*this, true);
- char buf[0x10000];
- int todor = count, todow, done = 0;
- if(offset)
- if((r=::lseek(fd_file, *offset, SEEK_SET)) < 0)
- return r;
- todow = ::read(fd_file, buf, count>sizeof(buf) ? sizeof(buf) : count);
- if(todow <= 0)
- return todow;
- todor -= todow;
- while(todow > 0) {
- if(p.Poll(100)) {
- r = write(buf+done, todow);
- if(r <= 0)
- return r;
- todow -= r;
- done += r;
- }
- }
- return done;
-#ifndef __APPLE__
- }
- return r;
-#endif
-}
-
-bool cxSocket::set_cork(bool state)
-{
-#ifdef __APPLE__
- return false;
-#else
- int iCork = state ? 1 : 0;
- if(setsockopt(m_fd, IPPROTO_TCP, TCP_CORK, &iCork, sizeof(int))) {
- LOGERR("cxSocket: setsockopt(TCP_CORK) failed");
- return false;
- }
- return true;
-#endif
-}
-
-bool cxSocket::set_nodelay(bool state)
-{
- int i = state ? 1 : 0;
- if(setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(int))) {
- LOGERR("cxSocket: setsockopt(TCP_NODELAY) failed");
- return false;
- }
- return true;
-}
-
-ssize_t cxSocket::tx_buffer_size(void)
-{
- socklen_t l = sizeof(int);
- int wmem = -1;
- if(getsockopt(m_fd, SOL_SOCKET, SO_SNDBUF, &wmem, &l)) {
- LOGERR("getsockopt(SO_SNDBUF) failed");
- return (ssize_t)-1;
- }
- return (ssize_t)wmem;
-}
-
-ssize_t cxSocket::tx_buffer_free(void)
-{
- int wmem = tx_buffer_size();
- int size = -1;
- if(ioctl(m_fd, TIOCOUTQ, &size)) {
- LOGERR("ioctl(TIOCOUTQ) failed");
- return (ssize_t)-1;
- }
-
- return (ssize_t)(wmem - size);
-}
-
-int cxSocket::getsockname(struct sockaddr *name, socklen_t *namelen)
-{
- return ::getsockname(m_fd, name, namelen);
-}
-
-int cxSocket::getpeername(struct sockaddr *name, socklen_t *namelen)
-{
- return ::getpeername(m_fd, name, namelen);
-}
-
-ssize_t cxSocket::send(const void *buf, size_t size, int flags,
- const struct sockaddr *to, socklen_t tolen)
-{
- return ::sendto(m_fd, buf, size, flags, to, tolen);
-}
-
-ssize_t cxSocket::recv(void *buf, size_t size, int flags,
- struct sockaddr *from, socklen_t *fromlen)
-{
- return ::recvfrom(m_fd, buf, size, flags, from, fromlen);
-}
-
-ssize_t cxSocket::write(const void *buffer, size_t size,
- int timeout_ms)
-{
- ssize_t written = (ssize_t)size;
- const unsigned char *ptr = (const unsigned char *)buffer;
- cPoller poller(m_fd, true);
-
- while (size > 0) {
- errno = 0;
- if(!poller.Poll(timeout_ms)) {
- LOGERR("cxSocket::write: poll() failed");
- return written-size;
- }
-
- errno = 0;
- ssize_t p = ::write(m_fd, ptr, size);
-
- if (p <= 0) {
- if (errno == EINTR || errno == EAGAIN) {
- LOGDBG("cxSocket::write: EINTR during write(), retrying");
- continue;
- }
- LOGERR("cxSocket::write: write() error");
- return p;
- }
-
- ptr += p;
- size -= p;
- }
-
- return written;
-}
-
-ssize_t cxSocket::read(void *buffer, size_t size, int timeout_ms)
-{
- ssize_t missing = (ssize_t)size;
- unsigned char *ptr = (unsigned char *)buffer;
- cPoller poller(m_fd);
-
- while (missing > 0) {
-
- if(!poller.Poll(timeout_ms)) {
- LOGERR("cxSocket::read: poll() failed at %d/%d", (int)(size-missing), (int)size);
- return size-missing;
- }
-
- errno = 0;
- ssize_t p = ::read(m_fd, ptr, missing);
-
- if (p <= 0) {
- if (errno == EINTR || errno == EAGAIN) {
- LOGDBG("cxSocket::read: EINTR/EAGAIN during read(), retrying");
- continue;
- }
- LOGERR("cxSocket::read: read() error at %d/%d", (int)(size-missing), (int)size);
- return size-missing;
- }
-
- ptr += p;
- missing -= p;
- }
-
- return size;
-}
-
-ssize_t cxSocket::printf(const char *fmt, ...)
-{
- va_list argp;
- char buf[1024];
- int r;
-
- va_start(argp, fmt);
- r = vsnprintf(buf, sizeof(buf), fmt, argp);
- if(r<0)
- LOGERR("cxSocket::printf: vsnprintf failed");
- else if(r >= (int)sizeof(buf))
- LOGMSG("cxSocket::printf: vsnprintf overflow (%20s)", buf);
- else
- return write(buf, r);
-
- return (ssize_t)-1;
-}
-
-/* readline return value:
- * <0 : failed
- * >=maxsize : buffer overflow
- * >=0 : if errno = EAGAIN -> line is not complete (there was timeout)
- * if errno = 0 -> succeed
- * (return value 0 indicates empty line "\r\n")
- */
-ssize_t cxSocket::readline(char *buf, int bufsize, int timeout, int bufpos)
-{
- int n = -1, cnt = bufpos;
- cPoller p(m_fd);
-
- do {
- if(timeout>0 && !p.Poll(timeout)) {
- errno = EAGAIN;
- return cnt;
- }
-
- while((n = ::read(m_fd, buf+cnt, 1)) == 1) {
- buf[++cnt] = 0;
-
- if( cnt > 1 && buf[cnt - 2] == '\r' && buf[cnt - 1] == '\n') {
- cnt -= 2;
- buf[cnt] = 0;
- errno = 0;
- return cnt;
- }
-
- if( cnt >= bufsize) {
- LOGMSG("cxSocket::readline: too long control message (%d bytes): %20s", cnt, buf);
- errno = 0;
- return bufsize;
- }
- }
-
- /* connection closed ? */
- if (n == 0) {
- LOGMSG("cxSocket::readline: disconnected");
- if(errno == EAGAIN)
- errno = ENOTCONN;
- return -1;
- }
-
- } while (timeout>0 && n<0 && errno == EAGAIN);
-
- if(errno == EAGAIN)
- return cnt;
-
- LOGERR("cxSocket::readline: read failed");
- return n;
-}
-
-#include <sys/ioctl.h>
-#include <net/if.h>
-
-uint32_t cxSocket::get_local_address(char *ip_address)
-{
- uint32_t local_addr = 0;
- struct ifconf conf;
- struct ifreq buf[3];
- unsigned int n;
-
- struct sockaddr_in sin;
- socklen_t len = sizeof(sin);
-
- if(!getsockname((struct sockaddr *)&sin, &len)) {
- local_addr = sin.sin_addr.s_addr;
-
- } else {
- //LOGERR("getsockname failed");
-
- // scan network interfaces
-
- conf.ifc_len = sizeof(buf);
- conf.ifc_req = buf;
- memset(buf, 0, sizeof(buf));
-
- errno = 0;
- if(ioctl(m_fd, SIOCGIFCONF, &conf) < 0)
- LOGERR("cxSocket: can't obtain socket local address");
- else {
- for(n=0; n<conf.ifc_len/sizeof(struct ifreq); n++) {
- struct sockaddr_in *in = (struct sockaddr_in *) &buf[n].ifr_addr;
-# if 0
- uint32_t tmp = ntohl(in->sin_addr.s_addr);
- LOGMSG("Local address %6s %d.%d.%d.%d",
- conf.ifc_req[n].ifr_name,
- ((tmp>>24)&0xff), ((tmp>>16)&0xff),
- ((tmp>>8)&0xff), ((tmp)&0xff));
-# endif
- if(n==0 || local_addr == htonl(INADDR_LOOPBACK))
- local_addr = in->sin_addr.s_addr;
- else
- break;
- }
- }
- }
-
- if(!local_addr)
- LOGERR("No local address found");
-
- if(ip_address)
- cxSocket::ip2txt(local_addr, 0, ip_address);
-
- return local_addr;
-}
-
-char *cxSocket::ip2txt(uint32_t ip, unsigned int port, char *str)
-{
- // inet_ntoa is not thread-safe (?)
- if(str) {
- unsigned int iph =(unsigned int)ntohl(ip);
- unsigned int porth =(unsigned int)ntohs(port);
- if(!porth)
- sprintf(str, "%d.%d.%d.%d",
- ((iph>>24)&0xff), ((iph>>16)&0xff),
- ((iph>>8)&0xff), ((iph)&0xff));
- else
- sprintf(str, "%u.%u.%u.%u:%u",
- ((iph>>24)&0xff), ((iph>>16)&0xff),
- ((iph>>8)&0xff), ((iph)&0xff),
- porth);
- }
- return str;
-}
diff --git a/tools/cxsocket.h b/tools/cxsocket.h
deleted file mode 100644
index 92954f3c..00000000
--- a/tools/cxsocket.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * cxsocket.h: Socket wrapper classes
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: cxsocket.h,v 1.20 2007-01-20 17:24:40 phintuka Exp $
- *
- */
-
-#ifndef __CXSOCKET_H
-#define __CXSOCKET_H
-
-#include <inttypes.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#define CLOSESOCKET(fd) do { if(fd>=0) { ::close(fd); fd=-1; } } while(0)
-
-class cxSocket {
- private:
- int m_fd;
-
- cxSocket(const cxSocket& s) ;//{ m_fd = s.m_fd>=0 ? dup(s.m_fd) : -1; }
- cxSocket &operator=(const cxSocket &S)
- ;// { close(); m_fd = S.m_fd >= 0 ? dup(S.m_fd) : -1; return *this; };
-
- public:
-
- typedef enum {
- estSTREAM = SOCK_STREAM,
- estDGRAM = SOCK_DGRAM
- } eSockType;
-
- cxSocket() : m_fd(-1) {}
- cxSocket(eSockType type) : m_fd(::socket(PF_INET, (int)type, 0)) {}
-
- ~cxSocket() { CLOSESOCKET(m_fd); }
-
- //operator int () const { return Handle(); }
- //operator bool () const { return open(); }
- //bool operator==(const cxSocket &s) { return m_fd == s.m_fd; }
-
- int handle(bool take_ownership=false)
- { int r=m_fd; if(take_ownership) m_fd=-1; return r; }
- void set_handle(int h) { if(h != m_fd) {close(); m_fd = h;} }
- bool create(eSockType type) { close(); return (m_fd=::socket(PF_INET, (int)type, 0)) >= 0; }
- bool open(void) const { return m_fd>0; }
- void close(void) { CLOSESOCKET(m_fd); }
-
- ssize_t send(const void *buf, size_t size, int flags=0,
- const struct sockaddr *to = NULL, socklen_t tolen = 0);
- ssize_t recv(void *buf, size_t size, int flags = 0,
- struct sockaddr *from = NULL, socklen_t *fromlen = NULL);
- ssize_t sendfile(int fd_file, off_t *offset, size_t count);
-
- ssize_t read(void *buffer, size_t size, int timeout_ms = -1);
- ssize_t write(const void *buffer, size_t size, int timeout_ms = -1);
-
- ssize_t printf(const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
- ssize_t write_str(const char *str, int timeout_ms=-1, int len=0)
- { return write(str, len ?: strlen(str), timeout_ms); }
- ssize_t write_cmd(const char *str, int len=0)
- { return write(str, len ?: strlen(str), 10); }
-
-/* readline return value:
- * <0 : failed
- * >=maxsize : buffer overflow
- * >=0 : if errno = EAGAIN -> line is not complete (there was timeout)
- * if errno = 0 -> succeed
- * (return value 0 indicates empty line "\r\n")
- */
- ssize_t readline(char *buf, int bufsize, int timeout=0, int bufpos=0);
-
- bool set_buffers(int Tx, int Rx);
- bool set_multicast(int ttl);
- bool set_blocking(bool state);
- bool set_cork(bool state);
- bool flush_cork(void) { return set_nodelay(true); };
- bool set_nodelay(bool state);
- ssize_t tx_buffer_size(void);
- ssize_t tx_buffer_free(void);
- int getsockname(struct sockaddr *name, socklen_t *namelen);
- int getpeername(struct sockaddr *name, socklen_t *namelen);
-
-
- bool connect(struct sockaddr *addr, socklen_t len);
- bool connect(const char *ip, int port);
-
- uint32_t get_local_address(char *ip_address);
-
- static char *ip2txt(uint32_t ip, unsigned int port, char *str);
-};
-
-
-#include <vdr/tools.h>
-
-class cxPoller : public cPoller {
- public:
- cxPoller(cxSocket& Sock, bool Out=false) : cPoller(Sock.handle(), Out) {};
-
- cxPoller(cxSocket* Socks, int count, bool Out=false)
- {
- for(int i=0; i<count; i++)
- Add(Socks[i].handle(), Out);
- }
-};
-
-//
-// Set socket buffers
-//
-static inline void set_socket_buffers(int s, int txbuf, int rxbuf)
-{
- int max_buf = txbuf;
- /*while(max_buf) {*/
- errno = 0;
- if(setsockopt(s, SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(int))) {
- LOGERR("setsockopt(SO_SNDBUF,%d) failed", max_buf);
- /*max_buf >>= 1;*/
- }
- /*else {*/
- int tmp = 0;
- int len = sizeof(int);
- errno = 0;
- if(getsockopt(s, SOL_SOCKET, SO_SNDBUF, &tmp, (socklen_t*)&len)) {
- LOGERR("getsockopt(SO_SNDBUF,%d) failed", max_buf);
- /*break;*/
- } else if(tmp != max_buf) {
- LOGDBG("setsockopt(SO_SNDBUF): got %d bytes", tmp);
- /*max_buf >>= 1;*/
- /*continue;*/
- }
- /*}*/
- /*}*/
-
- max_buf = rxbuf;
- setsockopt(s, SOL_SOCKET, SO_RCVBUF, &max_buf, sizeof(int));
-}
-
-//
-// Connect data socket to client (take address from fd_control)
-//
-static inline int sock_connect(int fd_control, int port, int type)
-{
- struct sockaddr_in sin;
- socklen_t len = sizeof(sin);
- int s, one = 1;
-
- if(getpeername(fd_control, (struct sockaddr *)&sin, &len)) {
- LOGERR("sock_connect: getpeername failed");
- return -1;
- }
-
- uint32_t tmp = ntohl(sin.sin_addr.s_addr);
- LOGMSG("Client address: %d.%d.%d.%d",
- ((tmp>>24)&0xff), ((tmp>>16)&0xff),
- ((tmp>>8)&0xff), ((tmp)&0xff));
-
-#if 0
- if ((h = gethostbyname(tmp)) == NULL) {
- LOGDBG("sock_connect: unable to resolve host name", tmp);
- }
-#endif
-
- if ((s = socket(PF_INET, type,
- type==SOCK_DGRAM?IPPROTO_UDP:IPPROTO_TCP)) < 0) {
- LOGERR("sock_connect: failed to create socket");
- return -1;
- }
-
- // Set socket buffers: large send buffer, small receive buffer
- set_socket_buffers(s, KILOBYTE(256), 2048);
-
- if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int)) < 0)
- LOGERR("sock_connect: setsockopt(SO_REUSEADDR) failed");
-
- sin.sin_family = AF_INET;
- sin.sin_port = htons(port);
-
- if (connect(s, (struct sockaddr *)&sin, sizeof(sin))==-1 &&
- errno != EINPROGRESS) {
- LOGERR("connect() failed");
- CLOSESOCKET(s);
- }
-
- if (fcntl (s, F_SETFL, fcntl (s, F_GETFL) | O_NONBLOCK) == -1) {
- LOGERR("can't put socket in non-blocking mode");
- CLOSESOCKET(s);
- return -1;
- }
-
- return s;
-}
-
-#endif // __CXSOCKET_H
diff --git a/tools/debug_mutex.h b/tools/debug_mutex.h
deleted file mode 100644
index 0802c7cc..00000000
--- a/tools/debug_mutex.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * debug_mutex.h: debugging wrappers for pthread_mutex_ functions
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: debug_mutex.h,v 1.3 2007-03-14 11:50:08 phintuka Exp $
- *
- */
-
-#ifndef DEBUG_MUTEX_H
-#define DEBUG_MUTEX_H
-
-#ifndef _PTHREAD_H
-# error pthread.h must be included before debug_mutex.h
-#endif
-
-/*
- * Override pthread_mutex_ calls:
- *
- * Change type of each mutex to PTHREAD_MUTEX_ERRORCHECK_NP
- *
- * Store line number of last succeed pthread_mutex_lock call
- * for each initialized mutex
- *
- * Check every pthread_mutex_ call for errors and log all errors
- *
- * To help detecting deadlocks and minimize logging:
- * - Try locking first in pthread_mutex_lock
- * - If pthread_mutex_trylock fails, log a message and retry.
- * - When trylock failed, log another message when lock is acquired.
- *
- *
- * NOTE: debugging itself is not thread-safe and may indicate wrong line numbers !
- *
- */
-
-#define MAX_DBG_MUTEX 64
-static struct {
- pthread_mutex_t *lock;
- int line;
- int tid;
-} dbgdata[MAX_DBG_MUTEX+1] = {{NULL,0}};
-
-static void dbg_setdata(pthread_mutex_t *mutex, int line)
-{
- int i;
- for(i=0; i<MAX_DBG_MUTEX; i++)
- if(dbgdata[i].lock == mutex) {
- dbgdata[i].line = line;
- dbgdata[i].tid = syscall(__NR_gettid);
- return;
- }
-
- LOGMSG("********** dbg_setdata: new entry (0x%lx at %d)", (unsigned long int)mutex, line);
- for(i=0; i<MAX_DBG_MUTEX; i++)
- if(!dbgdata[i].lock) {
- dbgdata[i].lock = mutex;
- dbgdata[i].line = line;
- dbgdata[i].tid = syscall(__NR_gettid);
- return;
- }
-
- LOGMSG("********** dbg_setdata: table full !");
-}
-
-static int dbg_getdata(pthread_mutex_t *mutex, int line)
-{
- int i;
- for(i=0; i<MAX_DBG_MUTEX; i++)
- if(dbgdata[i].lock == mutex)
- return dbgdata[i].line;
-
- LOGMSG("********** dbg_getdata: NO ENTRY ! (%d)", line);
- return -1;
-}
-
-static void dbg_deldata(pthread_mutex_t *mutex, int line)
-{
- int i;
- for(i=0; i<MAX_DBG_MUTEX; i++)
- if(dbgdata[i].lock == mutex) {
- dbgdata[i].lock = NULL;
- return;
- }
-
- LOGMSG("********** dbg_deldata: NO ENTRY ! (%d)", line);
- return;
-}
-
-static int dbg_init(pthread_mutex_t *mutex, pthread_mutexattr_t *pattr, int line)
-{
- int r;
-
- errno = 0;
- if(!pattr) {
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
- r = pthread_mutex_init(mutex, &attr);
- } else {
- LOGMSG("********** dbg_init: mutex attribute already given !");
- r = pthread_mutex_init(mutex, pattr);
- }
-
- if(r)
- LOGERR("********** dbg_init: pthread_mutex_init FAILED at %d", line);
-
- dbg_setdata(mutex, line);
-
- return r;
-}
-
-static int dbg_free(pthread_mutex_t *mutex, int line)
-{
- int r;
-
- errno = 0;
- r = pthread_mutex_destroy(mutex);
-
- if(r)
- LOGERR("********** dbg_free: pthread_mutex_destroy FAILED at %d ; last lock at %d",
- line, dbg_getdata(mutex, line));
- dbg_deldata(mutex, line);
-
- return r;
-}
-
-static int dbg_lock(pthread_mutex_t *mutex, int line)
-{
- int r;
- /*struct timespec abs_timeout;*/
-
- /* try lock first to reduce logging */
- errno = 0;
- r = pthread_mutex_trylock(mutex);
- if(!r) {
- dbg_setdata(mutex,line);
- return r;
- }
-
- /* try failed - we're going to wait, so log at wait start and end to detect deadlocks */
- LOGERR("********** dbg_lock: pthread_mutex_trylock failed at %d (locked at %d)",
- line, dbg_getdata(mutex, line));
-
- /* int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex,
- const struct timespec *restrict abs_timeout); */
-
- errno = 0;
- r = pthread_mutex_lock(mutex);
-
- if(r)
- LOGERR("********** dbg_lock: pthread_mutex_lock FAILED at %d", line);
-
- dbg_setdata(mutex, line);
- LOGMSG("********** dbg_lock: pthread_mutex_lock done at %d", line);
-
- return r;
-}
-
-static int dbg_trylock(pthread_mutex_t *mutex, int line)
-{
- int r;
- /*struct timespec abs_timeout;*/
-
- /* try lock first to reduce logging */
- errno = 0;
- r = pthread_mutex_trylock(mutex);
- if(!r) {
- dbg_setdata(mutex,line);
- return r;
- }
-
- LOGERR("********** dbg_trylock: pthread_mutex_trylock failed at %d (locked at %d)",
- line, dbg_getdata(mutex, line));
-
- return r;
-}
-
-static int dbg_unlock(pthread_mutex_t *mutex, int line)
-{
- int r;
-
- errno = 0;
- r = pthread_mutex_unlock(mutex);
-
- if(r)
- LOGERR("********** dbg_unlock: pthread_mutex_unlock FAILED at %d (last locket at %d)",
- line, dbg_getdata(mutex, line));
-
- //else
- // dbg_setdata(mutex, 0);
-
- return r;
-}
-
-/* override pthread_ functions with own ones */
-#define pthread_mutex_init(l,a) dbg_init(l, a, __LINE__)
-#define pthread_mutex_lock(l) dbg_lock(l, __LINE__)
-#define pthread_mutex_trylock(l) dbg_trylock(l, __LINE__)
-#define pthread_mutex_unlock(l) dbg_unlock(l, __LINE__)
-#define pthread_mutex_destroy(l) dbg_free(l, __LINE__)
-
-#else
-# error debug_mutex.h included twice
-#endif /* DEBUG_MUTEX_H */
diff --git a/tools/display_message.h b/tools/display_message.h
deleted file mode 100644
index 407f07c8..00000000
--- a/tools/display_message.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * display_message.h: Display simple message
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: display_message.h,v 1.2 2007-01-06 04:28:08 phintuka Exp $
- *
- */
-
-#ifndef __DISPLAY_MESSAGE_H
-#define __DISPLAY_MESSAGE_H
-
-#include <vdr/osdbase.h>
-#include <vdr/skins.h>
-
-class cDisplayMessage : public cOsdObject
-{
- cSkinDisplayMessage *displayMessage;
- char *Message;
- int Timer;
- int Timeout;
-
- public:
-
- cDisplayMessage(const char *message, int timeout = 3)
- {
- displayMessage = NULL;
- Message = strdup(message);
- Timer = 0;
- Timeout = timeout;
- }
-
- virtual ~cDisplayMessage()
- {
- delete displayMessage;
- free(Message);
- }
-
- void Update(const char *message)
- {
- Timer = 0;
- free(Message);
- Message = strdup(message);
- Show();
- }
-
- virtual eOSState ProcessKey(eKeys Key)
- {
- if(Key == kNone && Timer++ > Timeout)
- return osEnd;
-
- if(Key != kNone) {
- // put back and close
- cRemote::Put(Key, true);
- return osEnd;
- }
-
- return osContinue;
- }
-
- virtual void Show(void)
- {
- if(!displayMessage)
- displayMessage = Skins.Current()->DisplayMessage();
-
- displayMessage->SetMessage(mtInfo, Message);
- displayMessage->Flush();
- }
-
-};
-
-#endif
diff --git a/tools/functor.h b/tools/functor.h
deleted file mode 100644
index 0dadf1fc..00000000
--- a/tools/functor.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * functor.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: functor.h,v 1.1 2006-08-24 23:25:07 phintuka Exp $
- *
- */
-
-#ifndef __XINELIB_FUNCTOR_H
-#define __XINELIB_FUNCTOR_H
-
-#include <vdr/tools.h>
-
-
-class cFunctor : public cListObject
-{
- public:
- cFunctor() : cListObject() {}
- virtual ~cFunctor() {}
- virtual void Execute(void) = 0;
-};
-
-#if 1 /* gcc 3.3.x (?) does not accept class TRESULT=void */
-template<class TCLASS>
-cFunctor *CreateFunctor(TCLASS *c,
- void (TCLASS::*fp)(void));
-
-template<class TCLASS, class TARG1>
-cFunctor *CreateFunctor(TCLASS *c,
- void (TCLASS::*fp)(TARG1),
- TARG1 arg1);
-#endif
-
-template<class TCLASS, class TRESULT>
-cFunctor *CreateFunctor(TCLASS *c,
- TRESULT (TCLASS::*fp)(void));
-
-template<class TCLASS, class TRESULT, class TARG1>
-cFunctor *CreateFunctor(TCLASS *c,
- TRESULT (TCLASS::*fp)(TARG1),
- TARG1 arg1);
-
-#include "functorimpl.h"
-
-#endif
diff --git a/tools/functorimpl.h b/tools/functorimpl.h
deleted file mode 100644
index 2d3504e6..00000000
--- a/tools/functorimpl.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * functorimpl.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: functorimpl.h,v 1.1 2006-08-24 23:25:07 phintuka Exp $
- *
- */
-
-#ifndef __XINELIB_FUNCTORIMPL_H
-
-#ifndef __XINELIB_FUNCTOR_H
-# error functorimpl.h should not be included, use functor.h instead
-#endif
-
-#if 1 /* gcc 3.3.x (?) does not accept class TRESULT=void */
-template <class TCLASS>
-class cFunctor0 : public cFunctor {
-
- public:
- protected:
-
- typedef void (TCLASS::*TFUNC)(void);
-
- cFunctor0(TCLASS *obj, TFUNC f) : m_obj(obj), m_f(f) {}
- virtual ~cFunctor0() {};
-
- virtual void Execute(void)
- {
- (*m_obj.*m_f)();
- }
-
- private:
- TCLASS *m_obj;
- TFUNC m_f;
-
- friend cFunctor *CreateFunctor<TCLASS>(TCLASS*,TFUNC);
-};
-
-template <class TCLASS, class TARG1>
-class cFunctor1 : public cFunctor {
-
- public:
-
- protected:
- typedef void (TCLASS::*TFUNC)(TARG1);
-
- cFunctor1(TCLASS *obj, TFUNC f, TARG1 arg1) :
- m_obj(obj), m_f(f), m_arg1(arg1) {}
- virtual ~cFunctor1() {};
-
- virtual void Execute(void)
- {
- (*m_obj.*m_f)(m_arg1);
- }
-
- private:
- TCLASS *m_obj;
- TFUNC m_f;
- TARG1 m_arg1;
-
- friend cFunctor *CreateFunctor<TCLASS,TARG1>(TCLASS*,TFUNC,TARG1);
-};
-#endif
-
-template <class TCLASS, class TRESULT>
-class cFunctorR0 : public cFunctor {
-
- public:
- protected:
-
- typedef TRESULT (TCLASS::*TFUNC)(void);
-
- cFunctorR0(TCLASS *obj, TFUNC f) : m_obj(obj), m_f(f) {}
- virtual ~cFunctorR0() {};
-
- virtual void Execute(void)
- {
- // TODO: use future to pass back value
- (void) (*m_obj.*m_f)();
- }
-
- private:
- TCLASS *m_obj;
- TFUNC m_f;
-
- friend cFunctor *CreateFunctor<TCLASS,TRESULT>(TCLASS*,TFUNC);
-};
-
-template <class TCLASS, class TRESULT, class TARG1>
-class cFunctorR1 : public cFunctor {
-
- public:
- protected:
-
- typedef TRESULT (TCLASS::*TFUNC)(TARG1);
-
- cFunctorR1(TCLASS *obj, TFUNC f, TARG1 arg1) :
- m_obj(obj), m_f(f), m_arg1(arg1) {}
- virtual ~cFunctorR1() {};
-
- virtual void Execute(void)
- {
- // TODO: use future to pass back value
- (void) (*m_obj.*m_f)(m_arg1);
- }
-
- private:
- TCLASS *m_obj;
- TFUNC m_f;
- TARG1 m_arg1;
-
- friend cFunctor *CreateFunctor<TCLASS,TRESULT>(TCLASS*,TFUNC,TARG1);
-};
-
-#if 1 /* gcc 3.3.x (?) does not accept class TRESULT=void */
-template<class TCLASS>
-cFunctor *CreateFunctor(TCLASS *c,
- void (TCLASS::*fp)(void))
-{
- return new cFunctor0<TCLASS>(c, fp);
-}
-
-template<class TCLASS, class TARG1>
-cFunctor *CreateFunctor(TCLASS *c,
- void (TCLASS::*fp)(TARG1),
- TARG1 arg1)
-{
- return new cFunctor1<TCLASS,TARG1>(c, fp, arg1);
-}
-#endif
-
-template<class TCLASS, class TRESULT>
-cFunctor *CreateFunctor(TCLASS *c,
- TRESULT (TCLASS::*fp)(void))
-{
- return new cFunctorR0<TCLASS,TRESULT>(c, fp);
-}
-
-template<class TCLASS, class TRESULT, class TARG1>
-cFunctor *CreateFunctor(TCLASS *c,
- TRESULT (TCLASS::*fp)(TARG1),
- TARG1 arg1)
-{
- return new cFunctorR1<TCLASS,TRESULT,TARG1>(c, fp, arg1);
-}
-
-
-#endif
diff --git a/tools/future.h b/tools/future.h
deleted file mode 100644
index bdd0498c..00000000
--- a/tools/future.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * future.h: A variable that gets its value in future.
- * Used to convert asynchronous IPCs to synchronous.
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: future.h,v 1.2 2006-08-19 23:44:07 phintuka Exp $
- *
- */
-
-#ifndef __FUTURE_H
-#define __FUTURE_H
-
-#include <vdr/thread.h>
-
-template <class T>
-class cFuture {
-
- private:
- cMutex mutex;
- cCondVar cond;
- bool m_Ready;
- T m_Value;
-
- public:
-
- cFuture()
- {
- m_Ready = false;
- }
-
- void Reset(void)
- {
- cMutexLock l(&mutex);
- m_Ready = false;
- }
-
- //
- // Producer interface
- //
-
- void Set(T& Value)
- {
- cMutexLock l(&mutex);
- m_Value = Value;
- m_Ready = true;
- cond.Broadcast();
- }
-
- //
- // Consumer interface
- //
-
- bool Wait(int Timeout = -1)
- {
- cMutexLock l(&mutex);
-
- if(Timeout==0 || m_Ready)
- return m_Ready;
-
- if(Timeout >= 0)
- return cond.TimedWait(mutex, Timeout) && m_Ready;
-
- while(!m_Ready)
- cond.Wait(mutex);
-
- return m_Ready;
- }
-
- bool IsReady(void)
- {
- cMutexLock l(&mutex);
- return m_Ready;
- }
-
- T Value(void)
- {
- cMutexLock l(&mutex);
- while(!m_Ready)
- cond.Wait(mutex);
- return m_Value;
- }
-};
-
-
-#endif // __FUTURE_H
diff --git a/tools/general_remote.h b/tools/general_remote.h
deleted file mode 100644
index aed60463..00000000
--- a/tools/general_remote.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * general_remote.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: general_remote.h,v 1.1 2006-06-03 10:04:27 phintuka Exp $
- *
- */
-
-#ifndef __GENERAL_REMOTE_H
-#define __GENERAL_REMOTE_H
-
-
-//----------------------------- cGeneralRemote --------------------------------
-
-#include <vdr/remote.h>
-
-class cGeneralRemote : public cRemote {
- public:
- cGeneralRemote(const char *Name) : cRemote(Name) {};
- bool Put(const char *Code, bool Repeat=false, bool Release=false)
- { return cRemote::Put(Code, Repeat, Release); };
-};
-
-
-#endif
diff --git a/tools/gnome_screensaver.c b/tools/gnome_screensaver.c
deleted file mode 100644
index 245f1f63..00000000
--- a/tools/gnome_screensaver.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * gnome_screensaver.c v0.0.7
- *
- * Enable/Disable the GNOME screensaver
- * Supports GNOME screensaver API 2.14 and 2.15
- *
- * Call gnome_screensaver_control(1) to enable and
- * gnome_screensaver_control(0) to disable
- *
- */
-/*
- * Orginally written for mplayer by Piotr Kaczuba
- * (http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2006-April/042661.html)
- *
- * Modified for xineliboutput by Alex Stansfield
- * (http://www.linuxtv.org/pipermail/vdr/2007-July/013458.html)
- */
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <dbus/dbus-glib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-
-#define LOG_MODULENAME "[vdr-fe] "
-#include "../logdefs.h"
-
-#include "gnome_screensaver.h"
-
-#define GS_SERVICE "org.gnome.ScreenSaver"
-#define GS_PATH "/org/gnome/ScreenSaver"
-#define GS_INTERFACE "org.gnome.ScreenSaver"
-
-#define GS_APPLICATION_NAME "vdr-sxfe"
-#define GS_REASON_FOR_INHIBIT "Watching TV"
-
-/* Log Messages */
-#define MSG_OpenBusConnectionError "Failed to open connection to bus: %s"
-#define MSG_RemoteMethodException "Caught remote method exception %s: %s"
-#define MSG_GnomeAPI215Failed "GNOME screensaver 2.15 API failed, trying 2.14 API"
-#define MSG_GError "Error: %s"
-#define MSG_GNOMEScreensaverEnabled "GNOME screensaver enabled"
-#define MSG_GNOMEScreensaverDisabled "GNOME screensaver disabled"
-
-static guint32 cookie;
-
-void gnome_screensaver_control(int enable)
-{
- DBusGConnection *connection;
- GError *error;
- DBusGProxy *proxy;
- gboolean ret;
-
- g_type_init();
-
- /* Get a connection to the session bus */
- error = NULL;
- connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
- if (connection == NULL) {
- LOGERR(MSG_OpenBusConnectionError, error->message);
- g_error_free(error);
- return;
- }
-
- /* Create a proxy object */
- proxy = dbus_g_proxy_new_for_name(connection,
- GS_SERVICE, GS_PATH, GS_INTERFACE);
-
- /* Enable the screensaver */
- if (enable) {
- /* First call the GNOME screensaver 2.15 API method */
- error = NULL;
- ret =
- dbus_g_proxy_call(proxy, "UnInhibit", &error, G_TYPE_UINT,
- cookie, G_TYPE_INVALID, G_TYPE_INVALID);
-
- /* If this fails, try the GNOME screensaver 2.14 API */
- if (!ret && error->domain == DBUS_GERROR
- && error->code == DBUS_GERROR_UNKNOWN_METHOD) {
- LOGERR(MSG_GnomeAPI215Failed);
- g_error_free(error);
- error = NULL;
- ret =
- dbus_g_proxy_call(proxy, "AllowActivation", &error,
- G_TYPE_INVALID, G_TYPE_INVALID);
- }
- }
- /* Disable the screensaver */
- else {
- /* First call the GNOME screensaver 2.15 API method */
- error = NULL;
- ret =
- dbus_g_proxy_call(proxy, "Inhibit", &error, G_TYPE_STRING,
- GS_APPLICATION_NAME, G_TYPE_STRING,
- GS_REASON_FOR_INHIBIT, G_TYPE_INVALID,
- G_TYPE_UINT, cookie, G_TYPE_INVALID);
-
- /* If this fails, try the GNOME screensaver 2.14 API */
- if (!ret && error->domain == DBUS_GERROR
- && error->code == DBUS_GERROR_UNKNOWN_METHOD) {
- LOGERR(MSG_GnomeAPI215Failed);
- g_error_free(error);
- error = NULL;
- ret =
- dbus_g_proxy_call(proxy, "InhibitActivation", &error,
- G_TYPE_STRING, GS_REASON_FOR_INHIBIT,
- G_TYPE_INVALID, G_TYPE_INVALID);
- }
- }
-
- if (!ret) {
- /* Check if it's a remote exception or a regular GError */
- if (error->domain == DBUS_GERROR
- && error->code == DBUS_GERROR_REMOTE_EXCEPTION) {
- LOGERR(MSG_RemoteMethodException, dbus_g_error_get_name(error), error->message);
- }
- else {
- LOGERR(MSG_GError, error->message);
- }
- g_error_free(error);
- }
- else {
- LOGMSG(enable ? MSG_GNOMEScreensaverEnabled : MSG_GNOMEScreensaverDisabled);
- }
-
- g_object_unref(proxy);
-}
diff --git a/tools/gnome_screensaver.h b/tools/gnome_screensaver.h
deleted file mode 100644
index 84dee38e..00000000
--- a/tools/gnome_screensaver.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _GNOME_SCREENSAVER_H
-#define _GNOME_SCREENSAVER_H
-
-extern void gnome_screensaver_control(int enable);
-
-#endif /* !_GNOME_SCREENSAVER_H */
diff --git a/tools/h264.c b/tools/h264.c
deleted file mode 100644
index a729a289..00000000
--- a/tools/h264.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * h264.c: H.264 bitstream decoding
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: h264.c,v 1.7 2009-03-31 11:33:05 phintuka Exp $
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-
-#ifndef LOG_MODULENAME
-# define LOG_MODULENAME "[h264 ] "
-# define SysLogLevel iSysLogLevel
-# include "../logdefs.h"
-#endif
-
-#define NOCACHE 1
-#include "bitstream.h"
-
-#include "mpeg.h"
-#include "h264.h"
-
-
-int h264_parse_sps(const uint8_t *buf, int len, h264_sps_data_t *sps)
-{
- br_state br = BR_INIT(buf, len);
- int profile_idc, pic_order_cnt_type;
- int frame_mbs_only;
- int i, j;
-
- profile_idc = br_get_u8(&br);
- LOGDBG("H.264 SPS: profile_idc %d", profile_idc);
- /* constraint_set0_flag = br_get_bit(br); */
- /* constraint_set1_flag = br_get_bit(br); */
- /* constraint_set2_flag = br_get_bit(br); */
- /* constraint_set3_flag = br_get_bit(br); */
- /* reserved = br_get_bits(br,4); */
- /* level_idc = br_get_u8(br); */
- br_skip_bits(&br, 16);
- br_skip_ue_golomb(&br); /* seq_parameter_set_id */
- if (profile_idc >= 100) {
- if (br_get_ue_golomb(&br) == 3) /* chroma_format_idc */
- br_skip_bit(&br); /* residual_colour_transform_flag */
- br_skip_ue_golomb(&br); /* bit_depth_luma - 8 */
- br_skip_ue_golomb(&br); /* bit_depth_chroma - 8 */
- br_skip_bit(&br); /* transform_bypass */
- if (br_get_bit(&br)) /* seq_scaling_matrix_present */
- for (i = 0; i < 8; i++)
- if (br_get_bit(&br)) { /* seq_scaling_list_present */
- int last = 8, next = 8, size = (i<6) ? 16 : 64;
- for (j = 0; j < size; j++) {
- if (next)
- next = (last + br_get_se_golomb(&br)) & 0xff;
- last = next ?: last;
- }
- }
- }
-
- br_skip_ue_golomb(&br); /* log2_max_frame_num - 4 */
- pic_order_cnt_type = br_get_ue_golomb(&br);
- if (pic_order_cnt_type == 0)
- br_skip_ue_golomb(&br); /* log2_max_poc_lsb - 4 */
- else if (pic_order_cnt_type == 1) {
- br_skip_bit(&br); /* delta_pic_order_always_zero */
- br_skip_se_golomb(&br); /* offset_for_non_ref_pic */
- br_skip_se_golomb(&br); /* offset_for_top_to_bottom_field */
- j = br_get_ue_golomb(&br); /* num_ref_frames_in_pic_order_cnt_cycle */
- for (i = 0; i < j; i++)
- br_skip_se_golomb(&br); /* offset_for_ref_frame[i] */
- }
- br_skip_ue_golomb(&br); /* ref_frames */
- br_skip_bit(&br); /* gaps_in_frame_num_allowed */
- sps->width /* mbs */ = br_get_ue_golomb(&br) + 1;
- sps->height /* mbs */ = br_get_ue_golomb(&br) + 1;
- frame_mbs_only = br_get_bit(&br);
- LOGDBG("H.264 SPS: pic_width: %u mbs", (unsigned) sps->width);
- LOGDBG("H.264 SPS: pic_height: %u mbs", (unsigned) sps->height);
- LOGDBG("H.264 SPS: frame only flag: %d", frame_mbs_only);
-
- sps->width *= 16;
- sps->height *= 16 * (2-frame_mbs_only);
-
- if (!frame_mbs_only)
- if (br_get_bit(&br)) /* mb_adaptive_frame_field_flag */
- LOGDBG("H.264 SPS: MBAFF");
- br_skip_bit(&br); /* direct_8x8_inference_flag */
- if (br_get_bit(&br)) { /* frame_cropping_flag */
- uint32_t crop_left = br_get_ue_golomb(&br);
- uint32_t crop_right = br_get_ue_golomb(&br);
- uint32_t crop_top = br_get_ue_golomb(&br);
- uint32_t crop_bottom = br_get_ue_golomb(&br);
- LOGDBG("H.264 SPS: cropping %d %d %d %d",
- crop_left, crop_top, crop_right, crop_bottom);
-
- sps->width -= 2*(crop_left + crop_right);
- if (frame_mbs_only)
- sps->height -= 2*(crop_top + crop_bottom);
- else
- sps->height -= 4*(crop_top + crop_bottom);
- }
-
- /* VUI parameters */
- sps->pixel_aspect.num = 0;
- if (br_get_bit(&br)) { /* vui_parameters_present flag */
- if (br_get_bit(&br)) { /* aspect_ratio_info_present */
- uint32_t aspect_ratio_idc = br_get_u8(&br);
- LOGDBG("H.264 SPS: aspect_ratio_idc %d", aspect_ratio_idc);
-
- if (aspect_ratio_idc == 255 /* Extended_SAR */) {
- sps->pixel_aspect.num = br_get_u16(&br); /* sar_width */
- sps->pixel_aspect.den = br_get_u16(&br); /* sar_height */
- LOGDBG("H.264 SPS: -> sar %dx%d", sps->pixel_aspect.num, sps->pixel_aspect.den);
- } else {
- static const mpeg_rational_t aspect_ratios[] =
- { /* page 213: */
- /* 0: unknown */
- {0, 1},
- /* 1...16: */
- { 1, 1}, {12, 11}, {10, 11}, {16, 11}, { 40, 33}, {24, 11}, {20, 11}, {32, 11},
- {80, 33}, {18, 11}, {15, 11}, {64, 33}, {160, 99}, { 4, 3}, { 3, 2}, { 2, 1}
- };
-
- if (aspect_ratio_idc < sizeof(aspect_ratios)/sizeof(aspect_ratios[0])) {
- memcpy(&sps->pixel_aspect, &aspect_ratios[aspect_ratio_idc], sizeof(mpeg_rational_t));
- LOGDBG("H.264 SPS: -> aspect ratio %d / %d", sps->pixel_aspect.num, sps->pixel_aspect.den);
- } else {
- LOGMSG("H.264 SPS: aspect_ratio_idc out of range !");
- }
- }
- }
- }
-
- LOGDBG("H.264 SPS: -> video size %dx%d, aspect %d:%d",
- sps->width, sps->height, sps->pixel_aspect.num, sps->pixel_aspect.den);
-
- if(BR_EOF(&br)) {
- LOGDBG("H.264 SPS: not enough data ?");
- return 0;
- }
- return 1;
-}
-
-static int h264_nal_unescape(uint8_t *dst, const uint8_t *src, int len)
-{
- int s = 0, d = 0;
- while (s < len) {
- if (!src[s] && !src[s+1]) {
- /* hit 00 00 xx */
- dst[d] = dst[d+1] = 0;
- s += 2;
- d += 2;
- if (src[s] == 3) {
- s++; /* 00 00 03 xx --> 00 00 xx */
- /*LOGDBG("h264_nal_unescape: hit 00 00 03 %02x", src[s]);*/
- if (s >= len)
- return d;
- } /* else if (src[s] == 0 || src[s] == 1) {
- LOGDBG("h264_nal_unescape: invalid NAL sequence 00 00 %02x %02x", src[s], src[s+1]);
- return -1;
- }*/
- }
- dst[d++] = src[s++];
- }
- return d;
-}
-
-int h264_get_picture_type(const uint8_t *buf, int len)
-{
- int i;
- for (i = 0; i < len-5; i++) {
- if (buf[i] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1 && buf[i + 3] == NAL_AUD) {
- uint8_t type = (buf[i + 4] >> 5);
- switch (type) {
- case 0: case 3: case 5: return I_FRAME;
- case 1: case 4: case 6: return P_FRAME;
- case 2: case 7: return B_FRAME;
- default:;
- }
- }
- }
- return NO_PICTURE;
-}
-
-int h264_get_video_size(const uint8_t *buf, int len, video_size_t *size)
-{
- int i;
-
- /* H.264 detection, search for NAL AUD */
- if (!IS_NAL_AUD(buf))
- return 0;
-
- /* if I-frame, search for NAL SPS */
- if (h264_get_picture_type(buf, len) != I_FRAME)
- return 0;
-
- /* scan video packet for sequence parameter set */
- for (i = 5; i < len-4; i++)
- if (buf[i] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1 && (buf[i + 3] & 0x1f) == NAL_SPS) {
-
- uint8_t nal_data[len];
- int nal_len;
-
- LOGDBG("H.264: Found NAL SPS at offset %d/%d", i, len);
-
- if (0 < (nal_len = h264_nal_unescape(nal_data, buf+i+4, len-i-4))) {
-
- h264_sps_data_t sps = {0};
-
- if (h264_parse_sps(nal_data, nal_len, &sps)) {
- size->width = sps.width;
- size->height = sps.height;
- memcpy(&size->pixel_aspect, &sps.pixel_aspect, sizeof(mpeg_rational_t));
- return 1;
- }
- LOGMSG("h264_get_video_size: not enough data ?");
- }
- }
-
- return 0;
-}
-
diff --git a/tools/h264.h b/tools/h264.h
deleted file mode 100644
index df869e96..00000000
--- a/tools/h264.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * h264.h: H.264 bitstream decoding
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: h264.h,v 1.9 2009-06-29 15:49:43 phintuka Exp $
- *
- */
-
-#ifndef _XINELIBOUTPUT_H264_H_
-#define _XINELIBOUTPUT_H264_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "mpeg.h"
-
-
-#define NAL_SPS 0x07 /* Sequence Parameter Set */
-#define NAL_AUD 0x09 /* Access Unit Delimiter */
-#define NAL_END_SEQ 0x0a /* End of Sequence */
-
-
-#if defined(__i386__) || defined(__x86_64__)
-# define IS_NAL_SPS(buf) (*(uint32_t*)(buf) == 0x07010000U)
-# define IS_NAL_AUD(buf) (*(uint32_t*)(buf) == 0x09010000U)
-# define IS_NAL_END_SEQ(buf) (*(uint32_t*)(buf) == 0x0a010000U)
-#else
-# define IS_NAL_SPS(buf) ((buf)[0] == 0 && (buf)[1] == 0 && (buf)[2] == 1 && (buf)[3] == NAL_SPS)
-# define IS_NAL_AUD(buf) ((buf)[0] == 0 && (buf)[1] == 0 && (buf)[2] == 1 && (buf)[3] == NAL_AUD)
-# define IS_NAL_END_SEQ(buf) ((buf)[0] == 0 && (buf)[1] == 0 && (buf)[2] == 1 && (buf)[3] == NAL_END_SEQ)
-#endif
-
-
-typedef struct {
- uint16_t width;
- uint16_t height;
- mpeg_rational_t pixel_aspect;
- /* ... */
-} h264_sps_data_t;
-
-struct video_size_s;
-
-
-/*
- * input: start of NAL SPS (without 00 00 01 07)
- */
-int h264_parse_sps(const uint8_t *buf, int len, h264_sps_data_t *sps);
-
-/*
- * input: start of H.264 video data (not PES)
- */
-int h264_get_picture_type(const uint8_t *buf, int len);
-
-/*
- * input: start of H.264 video data (not PES)
- */
-int h264_get_video_size(const uint8_t *buf, int len, struct video_size_s *size);
-
-
-#ifdef __cplusplus
-} /* extern "C" { */
-#endif
-
-
-#endif /* _XINELIBOUTPUT_H264_H_ */
diff --git a/tools/http.c b/tools/http.c
deleted file mode 100644
index 0e7de26a..00000000
--- a/tools/http.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * http.c: HTTP (/RTSP) helper classes
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: http.c,v 1.7 2009-06-02 08:37:58 phintuka Exp $
- *
- */
-
-#define __STDC_FORMAT_MACROS
-#include <inttypes.h>
-
-#include <string.h>
-
-#include <vdr/config.h>
-#include <vdr/tools.h>
-
-#include "../logdefs.h"
-
-#include "http.h"
-
-//
-// cHttpReq
-//
-
-bool cHttpReq::SetCommand(const char *Command)
-{
- char *tmp = strdup(Command);
- char *pt = strchr(tmp, ' '), *uri;
-
- m_Valid = false;
- if(pt) {
- *pt++ = 0;
- m_Name = tmp;
-
- while(*pt && *pt == ' ') pt++;
-
- uri = pt;
- pt = strrchr(uri, ' ');
- if(pt) {
- m_Version = pt+1;
- while(*pt && *pt == ' ') *pt-- = 0;
- m_Uri = uri;
- m_Valid = true;
- }
- }
-
- free(tmp);
- return m_Valid;
-}
-
-cHeader *cHttpReq::Header(const char *Name)
-{
- for(cHeader *i = m_Headers.First(); i; i = m_Headers.Next(i))
- if(!strcmp(Name, i->Name()))
- return i;
- return NULL;
-}
-
-void cHttpReq::AddHeader(const char *Header, bool Duplicate)
-{
- if(strlen(Header) < 4096) {
- char *name = strdup(Header);
- char *val = strchr(name, ':');
- if(val) {
- *val++ = 0;
- while(*val == ' ') val++;
- AddHeader(name, val, Duplicate);
- }
- free(name);
- } else {
- LOGMSG("cConnState::AddHeader: header length exceeds 4096 !");
- }
-}
-
-void cHttpReq::AddHeader(const char *Name, const char *Value, bool Duplicate)
-{
- if(strlen(Name) > 64 || strlen(Value) > 4096) {
- LOGMSG("cConnState::AddHeader: header length exceeds limit !");
- } else {
- cHeader *h = Header(Name);
- if(!Duplicate && h)
- h->SetValue(Value);
- else {
- if(m_Headers.Count() < 50)
- m_Headers.Add(new cHeader(Name, Value));
- else
- LOGMSG("cConnState::AddHeader: header count exceeds 50 !");
- }
- }
-}
-
-void cHttpReq::Reset(void)
-{
- m_Name = NULL;
- m_Uri = NULL;
- m_Version = NULL;
- m_Valid = false;
- m_Headers.Clear();
-}
-
-//
-// Map file extensions to mime types
-//
-
-static const char *mimetype(const char *ext)
-{
- static const struct {
- const char *ext;
- const char *mime;
- } ext2mime[] = {
- {"avi", "video/avi"},
- {"vob", "video/mpeg"},
- {"mpg", "video/mpeg"},
- {"mpeg", "video/mpeg"},
- {"vdr", "video/mp2p"},
-
- {"mp3", "audio/mp3"},
- {"flac", "audio/flac"},
-
- {"jpg", "image/jpeg"},
- {"jpeg", "image/jpeg"},
- {"gif", "image/gif"},
-
- {NULL, NULL}
- };
-
- int i = -1;
- while(ext2mime[++i].ext)
- if(!strcmp(ext, ext2mime[i].ext))
- return ext2mime[i].mime;
- return NULL;
-}
-
-static char *unescape_uri(const char *uri)
-{
- char *d = strdup(uri), *s = d, *result = d;
- while(*s) {
- if(s[0] == '%' && s[1] && s[2]) {
- unsigned int c;
- if (sscanf(s+1, "%02x", &c) == 1) {
- *d++ = (char)c;
- s += 3;
- continue;
- }
- }
- *d++ = *s++;
- }
- *d = 0;
- return result;
-}
-
-//
-// cHttpStreamer
-//
-
-cList<cHttpStreamer> cHttpStreamer::m_Streamers;
-
-void cHttpStreamer::CloseAll(bool OnlyFinished)
-{
- if(!OnlyFinished) {
- while(m_Streamers.First())
- m_Streamers.Del(m_Streamers.First());
-
- } else {
- /* purge finished streamers from list */
- cHttpStreamer *it = m_Streamers.First();
- while(it) {
- if(it->Active()) {
- it = (cHttpStreamer*)it->Next();
- } else {
- m_Streamers.Del(it);
- it = m_Streamers.First();
- }
- }
- }
-}
-
-cHttpStreamer::cHttpStreamer(int fd_http, const char *filename,
- cConnState *Request) :
- m_Filename(unescape_uri(filename), true)
-{
- m_fds.set_handle(fd_http);
- m_fds.set_cork(true);
- m_fdf = -1;
-
- //m_Filename = filename;
- m_FileSize = -1;
- m_Start = 0;
- m_End = -1;
- m_KeepOpen = true;
-
- m_ConnState = Request;
-
- m_Finished = false;
-
- CloseAll(true);
-
- m_Streamers.Add(this);
-
- if(m_Streamers.Count() > 5) {
- LOGMSG("WARNING: There are %d running HTTP streamers !", m_Streamers.Count());
- if(m_Streamers.Count() > 20) {
- errno = 0;
- LOGERR("ERROR: There are %d running HTTP streamers, cancelling first",
- m_Streamers.Count());
- m_Streamers.Del(m_Streamers.First());
- }
- }
-
- Start();
-}
-
-cHttpStreamer::~cHttpStreamer()
-{
- Cancel(3);
- if(m_ConnState)
- delete m_ConnState;
- if(m_fdf >= 0)
- close(m_fdf);
- m_fdf = -1;
-}
-
-void cHttpStreamer::ParseRange(const char *Range)
-{
- m_Start = 0;
- m_End = -1;
- if(Range) {
- LOGDBG("cHttpStreamer: Request range is \'%s\'", Range);
- switch(sscanf(Range, "bytes=%" PRId64 "-%" PRId64, &m_Start, &m_End)) {
- case 2: LOGMSG(" Range: %s (%" PRId64 " - %" PRId64 ")", Range, m_Start, m_End);
- break;
- case 1: m_End = -1;
- LOGMSG(" Range start: %s (%" PRId64 " - )", Range, m_Start);
- break;
- default:
- case 0: m_Start = 0;
- m_End = -1;
- break;
- }
- }
-}
-
-bool cHttpStreamer::ParseRequest(void)
-{
- cHeader *h;
-
- if((h = m_ConnState->Header("Range")) != NULL)
- ParseRange(h->Value());
-
- m_KeepOpen = false;
- if((h = m_ConnState->Header("Connection")) != NULL) {
- m_KeepOpen = !strcasecmp(h->Value(), "keep-alive");
- if(m_KeepOpen)
- LOGDBG("cHttpStreamer: client wants to keep connection open");
- }
-
- return true;
-}
-
-bool cHttpStreamer::Seek(void)
-{
- if(m_fdf < 0) {
- m_fdf = open(m_Filename, O_RDONLY);
- if(m_fdf < 0) {
- LOGERR("cHttpStreamer: error opening %s", *m_Filename);
- m_fds.write_cmd(HTTP_REPLY_401); // 401 Not Found
- return false;
- }
-
- m_FileSize = lseek(m_fdf, 0, SEEK_END);
- if(m_FileSize <= 0) {
- LOGERR("cHttpStreamer: error seeking %s to end", *m_Filename);
- m_fds.write_cmd(HTTP_REPLY_401); // 401 Not Found
- return false;
- }
- }
-
- if(m_Start >= m_FileSize) {
- LOGERR("cHttpStreamer: Requested range not available "
- "(%s:%" PRId64 "-%" PRId64 " ; len=%" PRIu64 ")",
- *m_Filename, m_Start, m_End, (uint64_t)m_FileSize);
- m_fds.write_cmd(HTTP_REPLY_416); // 416 Requested Range Not Satisfiable
- return false;
- }
-
- if(m_Start > 0) {
- if(m_End >= m_FileSize || m_End < 0)
- m_End = m_FileSize-1;
-
- m_fds.write_cmd("HTTP/1.1 206 Partial Content\r\n");
- m_fds.printf("Content-Range: bytes %" PRId64 "-%" PRId64 "/%" PRIu64 "\r\n",
- m_Start, m_End, (uint64_t)m_FileSize);
- } else {
- m_fds.write_cmd("HTTP/1.1 200 OK\r\n");
- }
-
- /* content type */
- const char *ext = strrchr(m_Filename, '.');
- if(ext) {
- const char *mime = mimetype(ext+1);
- if(mime)
- m_fds.printf("Content-Type: %s\r\n", mime);
- }
-
- /* Content-Length */
- if(m_FileSize >= 0) {
- int64_t len = m_FileSize;
- if(m_End >= 0)
- len = m_End + 1;
- if(m_Start >= 0)
- len -= m_Start;
- m_fds.printf("Content-Length: %" PRId64 "\r\n", len);
- }
-
- /* Connection and end of reply */
- if(m_KeepOpen)
- m_fds.write_cmd("Connection: Keep-Alive\r\n"
- "\r\n");
- else
- m_fds.write_cmd("Connection: Close\r\n"
- "\r\n");
-
- if(m_Start)
- lseek(m_fdf, (off_t)m_Start, SEEK_SET);
- else
- lseek(m_fdf, 0, SEEK_SET);
-
- return true;
-}
-
-bool cHttpStreamer::ReadPipelined(void)
-{
- char buf[2048];
- int r;
-
- if(m_ConnState)
- delete m_ConnState;
- m_ConnState = new cConnState;
-
- do {
- r = m_fds.readline(buf, sizeof(buf), 1000);
- if(r < 0 || errno == EAGAIN || r >= (int)sizeof(buf)) {
- LOGMSG("cHttpStreamer: disconnected");
- return false;
- }
-
- LOGMSG("cHttpStreamer: pipelined request: %s", buf);
-
- if(!*m_ConnState->Name()) {
- if(!m_ConnState->SetCommand(buf) ||
- strcmp(m_ConnState->Name(), "GET") ||
- strncmp(m_ConnState->Uri(), "/PLAYFILE", 9) ||
- strncmp(m_ConnState->Version(), "HTTP/1.", 7)) {
- LOGMSG("Incorrect HTTP request: %s", buf);
- return false;
- }
- }
- else if(r > 0)
- m_ConnState->AddHeader(buf);
- } while(r>0);
-
- return true;
-}
-
-void cHttpStreamer::Action(void)
-{
- int n = 0;
- cxPoller p(m_fds);
- bool Disc = !(ParseRequest() && Seek());
- uint64_t pos = m_Start;
- off_t start = (off_t)m_Start;
-
- while(Running() && !Disc) {
-
- n = m_End>0 ? (m_End-start+1) : m_FileSize - start;
- if(n > 0) {
- errno = 0;
- pthread_testcancel();
- n = m_fds.sendfile(m_fdf, &start, n);
- pthread_testcancel();
- if(n <= 0) {
- if(errno == EAGAIN || errno == EINTR) {
- p.Poll(100);
- pthread_testcancel();
- } else {
- LOGERR("cHttpStreamer: sendfile() failed");
- Disc=true;
- }
- } else if(n == 0) {
- LOGMSG("cHttpStreamer: disconnected at %" PRId64, (int64_t)start);
- Disc = true;
- }
- continue;
- }
-
- LOGDBG("cHttpStreamer: Hit to EOF or end of requested range");
-
- m_fds.flush_cork();
-
- if(!m_KeepOpen) {
- LOGMSG("cHttpStreamer: disconnecting (request complete)");
- Disc = true;
- continue;
- }
-
- // keep connection open for new range for max. 30 sec
- n = 30;
- do {
- pthread_testcancel();
- //cxPoller p(m_fds);
- LOGDBG("cHttpStreamer: Request complete, waiting...");
- if(p.Poll(1000)) {
- LOGDBG("cHttpStreamer: Reading pipelined request");
- pthread_testcancel();
- Disc = !(ReadPipelined() && ParseRequest() && Seek());
- pos = m_Start;
- }
- } while(--n && Running() && !Disc);
-
- if(n <= 0) {
- LOGMSG("cHttpStreamer: Disconnecting (timeout)");
- Disc = true;
- }
- }
-
- close(m_fdf);
- m_fdf = -1;
-
- m_fds.close();
-
- m_Finished = true;
-}
diff --git a/tools/http.h b/tools/http.h
deleted file mode 100644
index 2adcf8e3..00000000
--- a/tools/http.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * http.h: HTTP (/RTSP) helper classes
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: http.h,v 1.5 2007-01-07 09:45:48 phintuka Exp $
- *
- */
-
-#ifndef XINELIBOUTPUT_HTTP_H_
-#define XINELIBOUTPUT_HTTP_H_
-
-#include <vdr/tools.h>
-
-
-#define HTTP_REPLY_401 \
- "HTTP/1.1 401 Unauthorized\r\n" \
- "Connection: Close\r\n" \
- "\r\n"
-
-#define HTTP_REPLY_404 \
- "HTTP/1.1 404 Not Found\r\n" \
- "Connection: Close\r\n" \
- "\r\n"
-
-#define HTTP_REPLY_416 \
- "HTTP/1.1 416 Requested Range Not Satisfiable\r\n" \
- "Connection: Close\r\n" \
- "\r\n"
-
-#define HTTP_REPLY_200_PRIMARY \
- "HTTP/1.1 200 OK\r\n" \
- "Content-Type: video/mpeg\r\n" \
- "Connection: Close\r\n" \
- "\r\n"
-//"Content-Type: video/mp2p\r\n"
-
-
-//
-// cHeader
-//
-
-class cHeader : public cListObject
-{
- protected:
- cString m_Name;
- cString m_Value;
-
- private:
- cHeader();
-
- public:
- cHeader(const char *Name, const char *Value) :
- m_Name(Name), m_Value(Value) {};
-
- const cString& Name(void) { return m_Name; }
- const cString& Value(void) { return m_Value; }
- int IntValue(void) { return *m_Value?atoi(m_Value):-1; }
- void SetValue(const char *Value) { m_Value = Value; }
-};
-
-
-//
-// cHttpReq
-//
-
-class cHttpReq
-{
- private:
- cString m_Name;
- cString m_Uri;
- cString m_Version;
- cList<cHeader> m_Headers;
-
- bool m_Valid;
-
- public:
- cHttpReq() : m_Valid(false) {}
-
- bool SetCommand(const char *Command);
- const cString& Name(void) { return m_Name; }
- const cString& Uri(void) { return m_Uri; }
- const cString& Version(void) { return m_Version; }
- bool Valid(void) { return m_Valid; }
-
- void AddHeader(const char *Header, bool Duplicate=false);
- void AddHeader(const char *Name, const char *Value, bool Duplicate=false);
- cHeader *Header(const char *Name);
-
- void Reset(void);
-};
-
-
-//
-// cConnState
-//
-
-class cConnState : public cHttpReq
-{
- public:
-};
-
-
-//
-// cHttpStreamer
-//
-
-#include <vdr/tools.h>
-#include <vdr/thread.h>
-
-#include "cxsocket.h"
-
-class cHttpStreamer : protected cListObject, cThread
-{
- public:
- cHttpStreamer(int fd_http, const char *filename, cConnState *Request);
- virtual ~cHttpStreamer();
-
- static void CloseAll(bool OnlyFinished = false);
-
- private:
- static cList<cHttpStreamer> m_Streamers;
-
- cxSocket m_fds;
- int m_fdf;
-
- cString m_Filename;
- int64_t m_FileSize;
- int64_t m_Start;
- int64_t m_End;
- bool m_KeepOpen;
-
- cConnState *m_ConnState;
-
- bool m_Finished;
-
- virtual void Action(void);
-
- bool ParseRequest(void);
- void ParseRange(const char *Range);
- bool ReadPipelined(void);
- bool Seek(void);
-};
-
-#endif // XINELIBOUTPUT_HTTP_H_
-
diff --git a/tools/iso639.h b/tools/iso639.h
deleted file mode 100644
index ae30fa0e..00000000
--- a/tools/iso639.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * iso639.h: iso-639-1 <-> iso-639-2 language code translations
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: iso639.h,v 1.4 2009-05-29 14:25:06 phintuka Exp $
- *
- */
-
-#ifndef __ISO_639_H
-#define __ISO_639_H
-
-static const struct {
- const char iso639_2[4];
- const char iso639_1[4];
-} ISO639_map[] =
-{
- {"???", "??"},
- {"abk", "ab"},
- {"aar", "aa"},
- {"afr", "af"},
- {"alb", "sq"},
- {"amh", "am"},
- {"ara", "ar"},
- {"arm", "hy"},
- {"ast", "as"},
- {"aym", "ay"},
- {"aze", "az"},
- {"bak", "ba"},
- {"baq", "eu"},
- {"bel", "be"},
- {"ben", "bn"},
- {"bih", "bh"},
- {"bis", "bi"},
- {"bre", "br"},
- {"bul", "bg"},
- {"bur", "my"},
- {"cat", "ca"},
- {"chi", "zh"},
- {"cos", "co"},
- {"scr", "hr"},
- {"cze", "cs"},
- {"dan", "da"},
- {"dut", "nl"},
- {"dzo", "dz"},
- {"eng", "en"},
- {"epo", "eo"},
- {"est", "et"},
- {"fao", "fo"},
- {"fij", "fj"},
- {"fin", "fi"},
- {"fre", "fr"},
- {"fry", "fy"},
- {"glg", "gl"},
- {"geo", "ka"},
- {"ger", "de"},
- {"gre", "el"},
- {"grn", "gn"},
- {"guj", "gu"},
- {"hau", "ha"},
- {"heb", "he"},
- {"heb", "iw"},
- {"hin", "hi"},
- {"hun", "hu"},
- {"ice", "is"},
- {"ind", "id"},
- {"ina", "ia"},
- {"iku", "iu"},
- {"ipk", "ik"},
- {"gle", "ga"},
- {"ita", "it"},
- {"jpn", "ja"},
- {"jav", "jv"},
- {"kal", "kl"},
- {"kan", "kn"},
- {"kas", "ks"},
- {"kaz", "kk"},
- {"khm", "km"},
- {"kin", "rw"},
- {"kir", "ky"},
- {"kor", "ko"},
- {"kur", "ku"},
- {"lao", "lo"},
- {"lat", "la"},
- {"lav", "lv"},
- {"lin", "ln"},
- {"lit", "lt"},
- {"mac", "mk"},
- {"mlg", "mg"},
- {"may", "ms"},
- {"mlt", "ml"},
- {"mao", "mi"},
- {"mar", "mr"},
- {"mol", "mo"},
- {"mon", "mn"},
- {"nau", "na"},
- {"nep", "ne"},
- {"nor", "no"},
- {"oci", "oc"},
- {"ori", "or"},
- {"orm", "om"},
- {"per", "fa"},
- {"pol", "pl"},
- {"por", "pt"},
- {"pus", "ps"},
- {"que", "qu"},
- {"roh", "rm"},
- {"rum", "ro"},
- {"run", "rn"},
- {"rus", "ru"},
- {"smo", "sm"},
- {"sag", "sg"},
- {"san", "sa"},
- {"srp", "sr"},
- {"scr", "sh"},
- {"sna", "sn"},
- {"snd", "sd"},
- {"sin", "si"},
- {"slo", "sk"},
- {"slv", "sl"},
- {"som", "so"},
- {"sot", "st"},
- {"spa", "es"},
- {"sun", "su"},
- {"swa", "sw"},
- {"ssw", "ss"},
- {"swe", "sv"},
- {"tgl", "tl"},
- {"tgk", "tg"},
- {"tam", "ta"},
- {"tat", "tt"},
- {"tel", "te"},
- {"tha", "th"},
- {"tib", "bo"},
- {"tir", "ti"},
- {"tog", "to"},
- {"tso", "ts"},
- {"tsn", "tn"},
- {"tur", "tr"},
- {"tuk", "tk"},
- {"twi", "tw"},
- {"uig", "ug"},
- {"ukr", "uk"},
- {"urd", "ur"},
- {"uzb", "uz"},
- {"vie", "vi"},
- {"vol", "vo"},
- {"wel", "cy"},
- {"wol", "wo"},
- {"xho", "xh"},
- {"yid", "yi"},
- {"yor", "yo"},
- {"zha", "za"},
- {"zul", "zu"},
-};
-
-static const char *iso639_2_to_iso639_1(const char *lang)
-{
- if (lang && lang[0]) {
- if (lang[1] && !lang[2]) {
- for (unsigned int i = 0 ; i < sizeof(ISO639_map) / sizeof(ISO639_map[0]); i++)
- if (!memcmp(ISO639_map[i].iso639_1, lang, 2))
- return ISO639_map[i].iso639_2;
- LOGMSG("Unknown iso639-2 code: %s", lang);
- }
- return lang;
- }
- return NULL;
-}
-
-static const char *iso639_1_to_iso639_2(const char *lang)
-{
- if (lang && lang[0]) {
- if (lang[1] && lang[2] && !lang[3]) {
- for (unsigned int i = 0 ; i < sizeof(ISO639_map) / sizeof(ISO639_map[0]); i++)
- if (!memcmp(ISO639_map[i].iso639_2, lang, 3))
- return ISO639_map[i].iso639_1;
- LOGMSG("Unknown iso639-1 code: %s", lang);
- }
- return lang;
- }
- return NULL;
-}
-
-#endif
diff --git a/tools/listiter.h b/tools/listiter.h
deleted file mode 100644
index 9c88940e..00000000
--- a/tools/listiter.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * listiter.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: listiter.h,v 1.1 2006-06-03 10:04:27 phintuka Exp $
- *
- */
-
-
-#ifndef _LISTITER_H_
-#define _LISTITER_H_
-
-//------------------------------ list ----------------------------------------
-
-template <class LIST,class ITEM, class RESULT>
-void ForEach(LIST& List, RESULT (ITEM::*f)())
-{
- for(ITEM *it = List.First(); it; it = List.Next(it))
- (*it.*f)();
-}
-
-template <class LIST,class ITEM, class ARG1, class RESULT>
-void ForEach(LIST& List, RESULT (ITEM::*f)(ARG1), ARG1 arg1)
-{
- for(ITEM *it = List.First(); it; it = List.Next(it))
- (*it.*f)(arg1);
-}
-
-template <class LIST,class ITEM, class ARG1, class ARG2>
-void ForEach(LIST& List, void (ITEM::*f)(ARG1,ARG2), ARG1 arg1, ARG2 arg2)
-{
- for(ITEM *it = List.First(); it; it = List.Next(it))
- (*it.*f)(arg1,arg2);
-}
-
-template <class LIST,class ITEM, class ARG1, class RESULT>
-RESULT ForEach(LIST& List, RESULT (ITEM::*f)(ARG1), ARG1 arg1,
- RESULT (*combiner)(RESULT,RESULT), RESULT def)
-{
- RESULT result = def;
- for(ITEM *it = List.First(); it; it = List.Next(it))
- result = (*combiner)((*it.*f)(arg1),result);
- return result;
-}
-
-template <class LIST,class ITEM, class ARG1, class ARG2, class RESULT>
-RESULT ForEach(LIST& List, RESULT (ITEM::*f)(ARG1,ARG2),
- ARG1 arg1, ARG2 arg2,
- RESULT (*combiner)(RESULT,RESULT), RESULT def)
-{
- RESULT result = def;
- for(ITEM *it = List.First(); it; it = List.Next(it))
- result = (*combiner)((*it.*f)(arg1,arg2),result);
- return result;
-}
-
-template <class LIST,class ITEM, class ARG1, class ARG2, class ARG3,
- class RESULT>
-RESULT ForEach(LIST& List, RESULT (ITEM::*f)(ARG1,ARG2,ARG3),
- ARG1 arg1, ARG2 arg2, ARG3 arg3,
- RESULT (*combiner)(RESULT,RESULT), RESULT def)
-{
- RESULT result = def;
- for(ITEM *it = List.First(); it; it = List.Next(it))
- result = (*combiner)((*it.*f)(arg1,arg2,arg3),result);
- return result;
-}
-
-template<class T>
-T mmin(T a, T b) {return a<b ? a : b;}
-
-template<class T>
-T mmax(T a, T b) {return a>b ? a : b;}
-
-template<class T>
-T mand(T a, T b) {return a&&b;}
-
-template<class T>
-T mor(T a, T b) {return a||b;}
-
-#endif
diff --git a/tools/metainfo_menu.c b/tools/metainfo_menu.c
deleted file mode 100644
index 01d97f30..00000000
--- a/tools/metainfo_menu.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * metainfo_menu.c: Media file info menu
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: metainfo_menu.c,v 1.7 2008-11-20 15:44:37 phintuka Exp $
- *
- */
-
-#include "../features.h"
-
-#ifdef HAVE_LIBEXTRACTOR
-# include <extractor.h>
-#endif
-
-#include <vdr/status.h>
-#include <vdr/i18n.h>
-
-#include "../config.h"
-
-#include "metainfo_menu.h"
-
-//
-// cMetainfoMenu
-//
-
-cMetainfoMenu::cMetainfoMenu(cString Filename) :
- cOsdMenu(Filename),
- m_Filename(Filename)
-{
- const char *Title = strrchr(Filename, '/');
- if(Title && *(Title+1))
- SetTitle(Title+1);
-}
-
-cMetainfoMenu::~cMetainfoMenu()
-{
-}
-
-void cMetainfoMenu::Display(void)
-{
- cOsdMenu::Display();
- char metadata[4096];
- metadata[0] = 0;
-
-#ifdef HAVE_LIBEXTRACTOR
- EXTRACTOR_ExtractorList * plugins;
- EXTRACTOR_KeywordList * md_list;
- plugins = EXTRACTOR_loadDefaultLibraries();
- md_list = EXTRACTOR_getKeywords(plugins, m_Filename);
- md_list = EXTRACTOR_removeEmptyKeywords (md_list);
- md_list = EXTRACTOR_removeDuplicateKeywords(md_list, 0);
- md_list = EXTRACTOR_removeKeywordsOfType(md_list, EXTRACTOR_THUMBNAILS);
-
- const char *key;
- char * buf;
- while(md_list) {
- if((key=EXTRACTOR_getKeywordTypeAsString(md_list->keywordType))) {
- buf = strdup(md_list->keyword);
- sprintf(metadata, "%s%s: %s\n", metadata, key, buf);
- free(buf);
- }
- md_list=md_list->next;
- }
- EXTRACTOR_freeKeywords(md_list);
- EXTRACTOR_removeAll(plugins); /* unload plugins */
-#else
- cString cmd;
- if(xc.IsPlaylistFile(m_Filename))
- cmd = cString::sprintf("file -b '%s'; cat '%s'", *m_Filename, *m_Filename);
- else if(xc.IsAudioFile(m_Filename))
- cmd = cString::sprintf("mp3info -x '%s' ; file -b '%s'", *m_Filename, *m_Filename);
- else if(xc.IsVideoFile(m_Filename))
- cmd = cString::sprintf("file -b '%s'; midentify '%s'", *m_Filename, *m_Filename);
- else if(xc.IsImageFile(m_Filename))
- cmd = cString::sprintf("file -b '%s'; identify '%s'", *m_Filename, *m_Filename);
- else
- cmd = cString::sprintf("file -b '%s'", *m_Filename);
-
- cPipe p;
- if(p.Open(*cmd, "r")) {
- int n = fread(metadata, 1, sizeof(metadata)-1, p);
- if(n>0) {
- metadata[n] = 0;
- strreplace(metadata, ',', '\n');
- }
- }
-#endif
- DisplayMenu()->SetText(metadata, false);
- cStatus::MsgOsdTextItem(cString::sprintf("%s\n%s", tr("Metainfo"), *m_Filename));
-}
-
-eOSState cMetainfoMenu::ProcessKey(eKeys Key)
-{
- eOSState state = cOsdMenu::ProcessKey(Key);
- return state;
-}
diff --git a/tools/metainfo_menu.h b/tools/metainfo_menu.h
deleted file mode 100644
index 45d60f22..00000000
--- a/tools/metainfo_menu.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * metainfo_menu.h: Media file info menu
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: metainfo_menu.h,v 1.1 2008-05-07 13:27:15 phintuka Exp $
- *
- */
-
-#ifndef __XINELIB_INFO_MENU_H_
-#define __XINELIB_INFO_MENU_H_
-
-//
-// cMetainfoMenu
-//
-
-#include <vdr/osdbase.h>
-
-class cMetainfoMenu : public cOsdMenu
-{
- protected:
-
- cString m_Filename;
-
- public:
-
- cMetainfoMenu(cString Filename);
- virtual ~cMetainfoMenu();
-
- virtual void Display(void);
-
- // cOsdMenu
- virtual eOSState ProcessKey(eKeys Key);
-
-};
-
-#endif // __XINELIB_INFO_MENU_H_
diff --git a/tools/mpeg.c b/tools/mpeg.c
deleted file mode 100644
index b827e096..00000000
--- a/tools/mpeg.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * mpeg.c:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: mpeg.c,v 1.3 2009-02-16 16:03:18 phintuka Exp $
- *
- */
-
-#include <inttypes.h>
-#include <string.h>
-
-#include "mpeg.h"
-
-
-const char * const picture_type_str[] = {
- "(none)",
- "I-Frame",
- "B-Frame",
- "P-Frame"
-};
-
-int mpeg2_get_picture_type(const uint8_t *buf, int len)
-{
- int i;
- for (i = 0; i < len-5; i++) {
- if (buf[i] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1) {
- switch (buf[i + 3]) {
- case SC_PICTURE:
- return (buf[i + 5] >> 3) & 0x07;
- }
- }
- }
- return NO_PICTURE;
-}
-
-int mpeg2_get_video_size(const uint8_t *buf, int len, video_size_t *size)
-{
- int i;
- for (i = 0; i < len-6; i++) {
- if (buf[i] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1) {
- if (buf[i + 3] == SC_SEQUENCE) {
- static const mpeg_rational_t mpeg2_aspect[16] = {
- {0,1}, {1,1}, {4,3}, {16,9}, {221,100},
- {0,1}, {0,1}, {0,1}, { 0,1}, { 0,1},
- {0,1}, {0,1}, {0,1}, { 0,1}, { 0,1},
- {0,1},
- };
-
- int d = (buf[i+4] << 16) | (buf[i+5] << 8) | buf[i+6];
- int a = buf[i+7] >> 4;
-
- size->width = (d >> 12);
- size->height = (d & 0xfff);
-
- memcpy(&size->pixel_aspect, &mpeg2_aspect[a], sizeof(mpeg_rational_t));
- size->pixel_aspect.num *= size->height;
- size->pixel_aspect.den *= size->width;
-
- return 1;
- }
- }
- }
- return 0;
-}
-
diff --git a/tools/mpeg.h b/tools/mpeg.h
deleted file mode 100644
index 8a9b6493..00000000
--- a/tools/mpeg.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * mpeg.h: MPEG definitions
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: mpeg.h,v 1.6 2009-02-16 16:03:18 phintuka Exp $
- *
- */
-
-#ifndef XINELIBOUTPUT_MPEG_H_
-#define XINELIBOUTPUT_MPEG_H_
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#define SC_PICTURE 0x00 /* picture atart code */
-#define SC_SEQUENCE 0xb3 /* sequence header */
-
-/* Picture types */
-#define NO_PICTURE 0
-#define I_FRAME 1
-#define P_FRAME 2
-#define B_FRAME 3
-
-typedef struct mpeg_rational_s {
- int num;
- int den;
-} mpeg_rational_t;
-
-typedef struct video_size_s {
- uint16_t width;
- uint16_t height;
- mpeg_rational_t pixel_aspect;
-} video_size_t;
-
-extern const char * const picture_type_str[];
-
-/*
- * input: start of MPEG video data (not PES)
- */
-int mpeg2_get_picture_type(const uint8_t *buf, int len);
-
-/*
- * input: start of MPEG video data (not PES)
- */
-int mpeg2_get_video_size(const uint8_t *buf, int len, video_size_t *size);
-
-
-#ifdef __cplusplus
-} /* extern "C" { */
-#endif
-
-
-#endif
diff --git a/tools/pes.c b/tools/pes.c
deleted file mode 100644
index 14773f2e..00000000
--- a/tools/pes.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * pes.h: PES header definitions
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: pes.c,v 1.10 2009-07-01 09:31:17 phintuka Exp $
- *
- */
-
-#include <inttypes.h>
-#include <string.h>
-
-#include "../logdefs.h"
-
-#include "mpeg.h"
-#include "h264.h"
-
-#include "pes.h"
-
-
-int64_t pes_get_pts(const uint8_t *buf, int len)
-{
- /* assume mpeg2 pes header ... */
- if (IS_VIDEO_PACKET(buf) || IS_AUDIO_PACKET(buf)) {
-
- if ((buf[6] & 0xC0) != 0x80)
- return NO_PTS;
- if ((buf[6] & 0x30) != 0)
- return NO_PTS;
-
- if ((len > 13) && (buf[7] & 0x80)) { /* pts avail */
- int64_t pts;
- pts = ((int64_t)(buf[ 9] & 0x0E)) << 29 ;
- pts |= ((int64_t) buf[10]) << 22 ;
- pts |= ((int64_t)(buf[11] & 0xFE)) << 14 ;
- pts |= ((int64_t) buf[12]) << 7 ;
- pts |= ((int64_t)(buf[13] & 0xFE)) >> 1 ;
- return pts;
- }
- }
- return NO_PTS;
-}
-
-int64_t pes_get_dts(const uint8_t *buf, int len)
-{
- if (IS_VIDEO_PACKET(buf) || IS_AUDIO_PACKET(buf)) {
-
- if ((buf[6] & 0xC0) != 0x80)
- return NO_PTS;
- if ((buf[6] & 0x30) != 0)
- return NO_PTS;
-
- if (len > 18 && (buf[7] & 0x40)) { /* dts avail */
- int64_t dts;
- dts = ((int64_t)( buf[14] & 0x0E)) << 29 ;
- dts |= (int64_t)( buf[15] << 22 );
- dts |= (int64_t)((buf[16] & 0xFE) << 14 );
- dts |= (int64_t)( buf[17] << 7 );
- dts |= (int64_t)((buf[18] & 0xFE) >> 1 );
- return dts;
- }
- }
- return NO_PTS;
-}
-
-void pes_change_pts(uint8_t *buf, int len, int64_t new_pts)
-{
- /* assume mpeg2 pes header ... Assume header already HAS pts */
- if (IS_VIDEO_PACKET(buf) || IS_AUDIO_PACKET(buf)) {
-
- if ((buf[6] & 0xC0) != 0x80)
- return;
- if ((buf[6] & 0x30) != 0)
- return;
-
- if ((len > 13) && (buf[7] & 0x80)) { /* pts avail */
- buf[ 9] = ((new_pts >> 29) & 0x0E) | (buf[ 9] & 0xf1);
- buf[10] = ((new_pts >> 22) & 0xFF);
- buf[11] = ((new_pts >> 14) & 0xFE) | (buf[11] & 0x01);
- buf[12] = ((new_pts >> 7 ) & 0xFF);
- buf[13] = ((new_pts << 1 ) & 0xFE) | (buf[13] & 0x01);
- }
- }
-}
-
-int pes_strip_pts_dts(uint8_t *buf, int size)
-{
- if(size > 13 && buf[7] & 0x80) { /* pts avail */
- int n = 5;
- int pes_len = (buf[4] << 8) | buf[5];
- if ((buf[6] & 0xC0) != 0x80)
- return size;
- if ((buf[6] & 0x30) != 0) /* scrambling control */
- return size;
- /* dts too ? */
- if(size > 18 && buf[7] & 0x40)
- n += 5;
- pes_len -= n; /* update packet len */
- buf[4] = pes_len >> 8; /* packet len (hi) */
- buf[5] = pes_len & 0xff; /* packet len (lo) */
- buf[7] &= 0x3f; /* clear pts and dts flags */
- buf[8] -= n; /* update header len */
- memmove(buf+4+n, buf+9+n, size-9-n);
- return size - n;
- }
- return size;
-}
-
-int pes_is_frame_h264(const uint8_t *buf, int len)
-{
- if (len < 9 || len < 9 + buf[8])
- return 0;
- if ( (buf[6] & 0xC0) != 0x80) /* MPEG 2 PES */
- return 0;
-
- buf += 9 + buf[8];
-
- if (IS_NAL_AUD(buf))
- return 1;
- return 0;
-}
-
-uint8_t pes_get_picture_type(const uint8_t *buf, int len)
-{
- int i = PES_HEADER_LEN(buf);
-
- buf += i;
- len -= i;
-
- if (buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01) {
- if (buf[3] == NAL_AUD)
- return h264_get_picture_type(buf, len);
- return mpeg2_get_picture_type(buf, len);
- }
-
- return NO_PICTURE;
-}
-
-int pes_get_video_size(const uint8_t *buf, int len, video_size_t *size, int h264)
-{
- int i = PES_HEADER_LEN(buf);
-
- buf += i;
- len -= i;
-
- if (h264 || IS_NAL_AUD(buf))
- return h264_get_video_size(buf, len, size);
-
- return mpeg2_get_video_size(buf, len, size);
-}
-
diff --git a/tools/pes.h b/tools/pes.h
deleted file mode 100644
index d25374a7..00000000
--- a/tools/pes.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * pes.h: PES header definitions
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: pes.h,v 1.13 2009-07-01 09:56:26 phintuka Exp $
- *
- */
-
-#ifndef _XINELIBOUTPUT_PES_H_
-#define _XINELIBOUTPUT_PES_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * Constants
- */
-
-#define PES_CHUNK_SIZE 2048
-
-#define MAX_SCR ((int64_t)0x1ffffffffLL)
-
-#define NO_PTS (INT64_C(-1))
-
-/* PES PIDs */
-#define PRIVATE_STREAM1 0xBD
-#define PADDING_STREAM 0xBE
-#define PRIVATE_STREAM2 0xBF
-#define AUDIO_STREAM_S 0xC0 /* 1100 0000 */
-#define AUDIO_STREAM_E 0xDF /* 1101 1111 */
-#define VIDEO_STREAM_S 0xE0 /* 1110 0000 */
-#define VIDEO_STREAM_E 0xEF /* 1110 1111 */
-
-#define AUDIO_STREAM_MASK 0x1F /* 0001 1111 */
-#define VIDEO_STREAM_MASK 0x0F /* 0000 1111 */
-#define AUDIO_STREAM 0xC0 /* 1100 0000 */
-#define VIDEO_STREAM 0xE0 /* 1110 0000 */
-
-#define ECM_STREAM 0xF0
-#define EMM_STREAM 0xF1
-#define DSM_CC_STREAM 0xF2
-#define ISO13522_STREAM 0xF3
-#define PROG_STREAM_DIR 0xFF
-
-#define IS_VIDEO_PACKET(data) (VIDEO_STREAM == ((data)[3] & ~VIDEO_STREAM_MASK))
-#define IS_MPEG_AUDIO_PACKET(data) (AUDIO_STREAM == ((data)[3] & ~AUDIO_STREAM_MASK))
-#define IS_PS1_PACKET(data) (PRIVATE_STREAM1 == (data)[3])
-#define IS_PADDING_PACKET(data) (PADDING_STREAM == (data)[3])
-#define IS_AUDIO_PACKET(data) (IS_MPEG_AUDIO_PACKET(data) || IS_PS1_PACKET(data))
-
-#define PES_HAS_PTS(data) ((data)[7] & 0x80)
-#define PES_HAS_DTS(data) ((data)[7] & 0x40)
-
-#define DATA_IS_PES(data) (!(data)[0] && !(data)[1] && (data)[2] == 1)
-
-#define PES_HEADER_LEN(data) (8 + (data)[8] + 1)
-
-
-/*
- * timestamps
- */
-
-static inline int pts_to_ms(int64_t pts) { return (int)(pts/INT64_C(90)); }
-static inline int64_t ms_to_pts(int ms) { return ((int64_t)(ms)) * INT64_C(90); }
-
-int64_t pes_get_pts(const uint8_t *buf, int len);
-int64_t pes_get_dts(const uint8_t *buf, int len);
-void pes_change_pts(uint8_t *buf, int len, int64_t new_pts);
-int pes_strip_pts_dts(uint8_t *buf, int len);
-
-/*
- * payload
- */
-
-struct video_size_s;
-
-int pes_is_frame_h264(const uint8_t *buf, int len);
-uint8_t pes_get_picture_type(const uint8_t *buf, int len);
-int pes_get_video_size(const uint8_t *buf, int len, struct video_size_s *size, int h264);
-
-static inline int pes_is_mpeg1(const uint8_t *header)
-{
- if (IS_VIDEO_PACKET(header) || IS_AUDIO_PACKET(header))
- return ((header[6] & 0xC0) != 0x80);
- if (header[3] == 0xBA)
- return ((header[4] & 0x40) == 0); /* mpeg1 */
- return 0;
-}
-
-/*
- * Extract PES packet length
- */
-
-static inline int pes_packet_len(const uint8_t *data, const int len)
-{
- if (IS_VIDEO_PACKET(data) || IS_AUDIO_PACKET(data)) {
- return 6 + (data[4] << 8 | data[5]);
- } else if (data[3] == PADDING_STREAM) {
- return 6 + (data[4] << 8 | data[5]);
- } else if (data[3] == 0xBA) {
- if ((data[4] & 0x40) == 0) /* mpeg1 */
- return 12;
- else /* mpeg 2 */
- return 14 + (data[0xD] & 0x07);
- } else if (data[3] <= 0xB9) {
- return -3;
- }
- return -(6 + (data[4] << 8 | data[5]));
-}
-
-
-#ifdef __cplusplus
-} /* extern "C" { */
-#endif
-
-#endif /* _XINELIBOUTPUT_PES_H_ */
diff --git a/tools/playlist.c b/tools/playlist.c
deleted file mode 100644
index e227b9c9..00000000
--- a/tools/playlist.c
+++ /dev/null
@@ -1,1005 +0,0 @@
-/*
- * playlist.c: Media player playlist
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: playlist.c,v 1.23 2009-06-02 08:36:16 phintuka Exp $
- *
- */
-
-#include "../features.h"
-
-#include <stdlib.h>
-
-#ifdef HAVE_LIBEXTRACTOR
-# include <extractor.h>
- // libextractor 0.5.20 (2008-03-20) adds support for track numbers
-# if EXTRACTOR_VERSION < 0x00052000
-# warning libextractor version too old (0.5.20 required for track numbers)
-# undef HAVE_LIBEXTRACTOR
-# endif
-#endif
-
-#include <vdr/config.h>
-#include <vdr/tools.h>
-#include <vdr/thread.h>
-
-#include "../config.h"
-
-#include "playlist.h"
-
-#include "../logdefs.h"
-
-
-#ifndef PLAYLIST_CACHE
-# define PLAYLIST_CACHE ".xineliboutput-playlist.pls"
-#endif
-
-#define MAX_PLAYLIST_FILES 1024
-
-static void strip_extension(cString& fname)
-{
- const char *ext = strrchr(fname, '.');
- if (ext)
- fname.Truncate(ext - fname);
-}
-
-//
-// cPlaylistItem
-//
-
-cPlaylistItem::cPlaylistItem(const char *filename)
-{
- const char *pt;
-
- Filename = filename;
- Position = -1;
-
- if(NULL != (pt = strrchr(filename, '/')))
- Title = pt + 1;
- else
- Title = filename;
-
- strip_extension(Title);
-}
-
-cPlaylistItem::cPlaylistItem(const char *filename,
- const char *path,
- const char *title,
- int position)
-{
- if(path[strlen(path)-1] != '/')
- Filename = cString::sprintf("%s/%s", path, filename);
- else
- Filename = cString::sprintf("%s%s", path, filename);
- Position = position;
- Title = title ?: filename;
-
- if (!title)
- strip_extension(Title);
-}
-
-int cPlaylistItem::Compare(const cListObject &ListObject) const
-{
- ///< Must return 0 if this object is equal to ListObject, a positive value
- ///< if it is "greater", and a negative value if it is "smaller".
-
- const cPlaylistItem *o = (cPlaylistItem *)&ListObject;
-
- // Use Position (if defined in playlist file)
- // compare as unsigned --> -1 goes to last position
- if(Position != o->Position)
- return ((unsigned int)Position) > ((unsigned int)o->Position) ? 1 : -1;
-
- // same position (or no positions definend) -> alphabetical order
-#if 0
- return strcmp(Title, o->Title);
-#else
- // use filename, because:
- // - implicit playlist has no track names available when sorting
- // (track names are read during playback), so track name is
- // just file name without path.
- // using full path allows sorting of each album and tracks inside albums...
- // - "normal" playlist is ordered using Position,
- // so track names are never compared anyway ...
- return strcmp(Filename, o->Filename);
-#endif
-}
-
-
-//
-// cID3Scanner
-//
-
-#ifndef HAVE_LIBEXTRACTOR
-static const char *shell_escape(char *buf, int buflen, const cString& src, char ch)
-{
- const char *pt = *src;
- int n = 0;
-
- if(pt) {
- while(*pt && n < buflen-2) {
- if(*pt == ch || *pt == '\\' /*|| *pt == '\"' || *pt == '\''*/) {
- buf[n++] = '\\';
- }
- buf[n++] = *pt++;
- }
- buf[n] = 0;
- return buf;
- }
- return "";
-}
-#endif
-
-class cID3Scanner : public cThread
-{
- public:
- cPlaylist& m_List;
- cID3Scanner(cPlaylist& List) : cThread("Metadata scanner"), m_List(List), m_Done(false) {};
-
- void CancelScanner(void) { Cancel(3); }
-
- private:
- bool m_Done;
-
- virtual void Action(void)
- {
- cPlaylistItem *Item = NULL;
- unsigned int Version = 0;
- const int priority = 10;
- errno = 0;
- if((nice(priority) == -1) && errno)
- LOGDBG("ID3Scanner: Can't nice to value: %d", priority);
-
- LOGDBG("ID3Scanner Started");
- while(Running()) {
-
- cMutexLock ml(&m_List.m_Lock);
-
- if(Version < m_List.m_Version) {
- // restart after sort, add, del
- Item = NULL;
- Version = m_List.m_Version;
- }
-
- if(!(Item = m_List.Next(Item)))
- break;
-
- if(xc.IsAudioFile(Item->Filename)) {
- LOGDBG("Scanning metainfo for file %s", *Item->Filename);
-#ifdef HAVE_LIBEXTRACTOR
- EXTRACTOR_ExtractorList * plugins;
- EXTRACTOR_KeywordList * md_list;
- plugins = EXTRACTOR_loadDefaultLibraries();
- md_list = EXTRACTOR_getKeywords(plugins, *Item->Filename);
- const char *key;
- while(md_list) {
- if ((key=EXTRACTOR_getKeywordTypeAsString(md_list->keywordType))) {
- if (!strcasecmp(key,"title"))
- Item->Title = md_list->keyword;
- else if (!strcasecmp(key,"artist"))
- Item->Artist = md_list->keyword;
- else if (!strcasecmp(key,"album"))
- Item->Album = md_list->keyword;
- else if (!strcasecmp(key,"track number"))
- Item->Tracknumber = cString::sprintf("%s%s", strlen(md_list->keyword) == 1 ? "0" : "", md_list->keyword);
- md_list=md_list->next;
- }
- }
- EXTRACTOR_freeKeywords(md_list);
- EXTRACTOR_removeAll(plugins); /* unload plugins */
-#else
- char buf[4096];
- cString Cmd = "";
- if(!strcasecmp((Item->Filename) + strlen(Item->Filename) - 5, ".flac"))
- Cmd = cString::sprintf("metaflac "
- " --show-tag=TITLE "
- " --show-tag=ALBUM "
- " --show-tag=ARTIST "
- " --show-tag=TRACKNUMBER "
- " \"%s\"",
- shell_escape(buf, sizeof(buf)-1, Item->Filename, '\"'));
- else
- Cmd = cString::sprintf("mp3info -p \""
- "ARTIST=%%a\\r\\n"
- "ALBUM=%%l\\r\\n"
- "TITLE=%%t\\r\\n"
- "TRACKNUMBER=%%n\\r\\n\""
- " \"%s\"",
- shell_escape(buf, sizeof(buf)-1, Item->Filename, '\"'));
-
- cPipe p;
- if(p.Open(*Cmd, "r")) {
- cReadLine r;
- char *pt;
- while(NULL != (pt = r.Read(p))) {
- if(!strncasecmp(pt, "ARTIST=", 7) && strlen(pt) > 8)
- Item->Artist = (pt+7);
- else if(!strncasecmp(pt, "ALBUM=", 6) && strlen(pt) > 7)
- Item->Album = (pt+6);
- else if(!strncasecmp(pt, "TITLE=", 6) && strlen(pt) > 7)
- Item->Title = (pt+6);
- else if(!strncasecmp(pt, "TRACKNUMBER=", 12) && strlen(pt) > 12)
- Item->Tracknumber = cString::sprintf("%s%s", strlen(pt) == 13 ? "0" : "", (pt+12));
- }
- }
-#endif
- }
- }
- LOGDBG("ID3Scanner Done.");
-
- m_List.PlaylistChanged(Item);
- m_Done = true;
- }
-};
-
-//
-// cPlaylistReader
-//
-
-class cPlaylistReader
-{
- private:
- cPlaylist& m_Playlist;
-
- protected:
- cString m_Title;
- int m_Position;
-
- cPlaylistItem *Prev(void) { return m_Playlist.Last(); }
-
- public:
- cPlaylistReader(cPlaylist& Playlist) : m_Playlist(Playlist) {}
- virtual ~cPlaylistReader() {}
-
- virtual char *Parse(char *line) = 0;
-
- void ResetCache(void) { m_Title = NULL; m_Position = -1; }
- const char *Title(void) { return m_Title; }
- int Position(void) { return m_Position; }
-};
-
-class cM3uReader : public cPlaylistReader
-{
- public:
- cM3uReader(cPlaylist& Playlist) : cPlaylistReader(Playlist), m_Next(1) {}
-
- protected:
- int m_Next;
- virtual char *Parse(char *line) {
- if(!*line)
- return NULL;
- if(*line == '#') {
- if(!strncmp(line, "#EXTINF:", 8)) {
- int len = -1;
- sscanf(line+8,"%d", &len);
- while(*line && *line != ',')
- line++;
- m_Title = *line ? (line+1) : NULL;
- m_Position = m_Next++;
- }
- return NULL;
- }
- return *line ? line : NULL;
- }
-};
-
-class cPlsReader : public cPlaylistReader
-{
- public:
- cPlsReader(cPlaylist& Playlist) : cPlaylistReader(Playlist), m_Current(0) {}
-
- protected:
- int m_Current;
- virtual char *Parse(char *line) {
- char *t = strchr(line, '=');
- if(t) {
- int n;
- if(!strncasecmp(line, "file", 4) &&
- 1 == sscanf(line + 4, "%d=", &n)) {
- m_Current = n;
- m_Position = n;
- if(*(t+1))
- return t+1;
- }
- else if(!strncasecmp(line, "title", 5) &&
- 1 == sscanf(line + 5, "%d=", &n)) {
- if(*(t+1)) {
- if(n == m_Current)
- Prev()->Title = t;
- else
- m_Title = t;
- }
- }
- //else if(!strncasecmp(line, "length", 6) &&
- // 1 == sscanf(line + 4, "%d=", &n)) {
- //}
- }
- return NULL;
- }
-};
-
-class cAsxReader : public cPlaylistReader
-{
- public:
- cAsxReader(cPlaylist& Playlist) : cPlaylistReader(Playlist) {}
-
- protected:
- virtual char *Parse(char *line) {
- char *pt = strstr(line, "<REF HREF");
- if(!pt)
- pt = strstr(line, "<ref href");
- if(!pt)
- pt = strstr(line, "<ENTRY HREF");
- if(!pt)
- pt = strstr(line, "<entry href");
- if(pt) {
- pt = strchr(pt, '=');
- if(pt) {
- pt = strchr(pt, '\"');
- if(pt) {
- pt++;
- if(strchr(pt, '\"'))
- *strchr(pt, '\"') = 0;
- return pt;
- }
- }
- }
-
- pt = strstr(line, "<TITLE>");
- if(!pt)
- pt = strstr(line, "<title>");
- if(pt) {
- pt += 7;
- if(strstr(line, "</"))
- *strstr(line, "</") = 0;
- m_Title = pt;
- }
-
- if(*m_Title) {
- pt = strstr(line, "<ENTRY>");
- if(!pt)
- pt = strstr(line, "<entry>");
- if(pt) {
- if(*m_Title && Prev()) {
- Prev()->Title = m_Title;
- m_Title = NULL;
- }
- }
- }
- return NULL;
- }
-};
-
-
-//
-// cPlaylist
-//
-
-cPlaylist::cPlaylist()
-{
- m_Origin = eImplicit;
- m_Menu = NULL;
- m_Scanner = NULL;
- m_Current = NULL;
- m_Version = 1;
-}
-
-cPlaylist::~cPlaylist()
-{
- if(m_Scanner) {
- m_Scanner->CancelScanner();
- delete m_Scanner;
- }
-
- if(m_Origin == eImplicit)
- StoreCache();
-}
-
-void cPlaylist::Listen(cPlaylistChangeNotify *Menu)
-{
- cMutexLock ml(&m_Lock);
- m_Menu = Menu;
-}
-
-void cPlaylist::PlaylistChanged(const cPlaylistItem *Item)
-{
- cMutexLock ml(&m_Lock);
- /*if(m_Origin == eImplicit)*/
- Sort();
- if(m_Menu)
- m_Menu->PlaylistChanged(Item);
-}
-
-void cPlaylist::Sort(void)
-{
- cMutexLock ml(&m_Lock);
- cListBase::Sort();
- m_Version++;
-}
-
-int cPlaylist::Count(void) const
-{
- return cListBase::Count();
-}
-
-cPlaylistItem *cPlaylist::Next(const cPlaylistItem *i)
-{
- cMutexLock ml(&m_Lock);
- return i ? cList<cPlaylistItem>::Next(i) : cList<cPlaylistItem>::First();
-}
-
-cPlaylistItem *cPlaylist::Current(void)
-{
- cMutexLock ml(&m_Lock);
- return m_Current ?: First();
-}
-
-void cPlaylist::Del(cPlaylistItem *it)
-{
- cMutexLock ml(&m_Lock);
-
- if(!it || Count() < 2)
- return;
-
- if(m_Current == it)
- m_Current = cList<cPlaylistItem>::Next(Current()) ?:
- cList<cPlaylistItem>::Prev(Current());
-
- cListBase::Del(it);
- m_Version++;
-}
-
-void cPlaylist::SetCurrent(cPlaylistItem *current)
-{
- cMutexLock ml(&m_Lock);
- m_Current = current;
-}
-
-cPlaylistItem *cPlaylist::Next(void)
-{
- cMutexLock ml(&m_Lock);
- if(Current())
- return m_Current = (cList<cPlaylistItem>::Next(Current()) ?: First());
- return NULL;
-}
-
-cPlaylistItem *cPlaylist::Prev(void)
-{
- cMutexLock ml(&m_Lock);
- if(Current())
- return m_Current = (cList<cPlaylistItem>::Prev(Current()) ?: Last());
- return NULL;
-}
-
-bool cPlaylist::StoreCache(void)
-{
- if(!xc.cache_implicit_playlists ||
- m_Origin != eImplicit ||
- !*m_Folder)
- return false;
-
- cString Name = cString::sprintf("%s%s", *m_Folder, PLAYLIST_CACHE);
- int len = strlen(m_Folder), entries = 0;
- FILE *f = NULL;
-
- for(cPlaylistItem *i = First(); i; i=Next(i)) {
- // store only items in "current" root folder
- if(!strncmp(i->Filename, m_Folder, len)) {
- if(/**i->Title ||*/ *i->Artist || *i->Album) {
- cString Filename = ((*i->Filename) + len); // relative
- if(entries < 1) {
- f = fopen(Name, "w");
- if(!f) {
- LOGERR("creation of metadata cache %s%s failed",
- *m_Folder, PLAYLIST_CACHE);
- return false;
- }
- fprintf(f, "[playlist]\r\n");
- }
- entries++;
- fprintf(f, "File%d=%s\r\n", entries, *Filename);
- if(*i->Title && (*i->Title)[0])
- fprintf(f, "Title%d=%s\r\n", entries, *i->Title);
- if(*i->Tracknumber && (*i->Tracknumber)[0])
- fprintf(f, "Tracknumber%d=%s\r\n", entries, *i->Tracknumber);
- if(*i->Artist && (*i->Artist)[0])
- fprintf(f, "Artist%d=%s\r\n", entries, *i->Artist);
- if(*i->Album && (*i->Album)[0])
- fprintf(f, "Album%d=%s\r\n", entries, *i->Album);
- }
- }
- }
-
- if(entries > 0) {
- fprintf(f, "NumberOfEntries=%d\r\nVersion=2\r\n", entries);
- fclose(f);
- return true;
- }
-
- return false;
-}
-
-static const char *strchrnext(const char *s, char c)
-{
- return (s = strchr(s, c)) ? ((*(s+1))?(s+1):NULL) : NULL;
-}
-
-bool cPlaylist::ReadCache(void)
-{
- if(xc.cache_implicit_playlists && m_Origin == eImplicit && *m_Folder) {
-
- cString Name = cString::sprintf("%s%s", *m_Folder, PLAYLIST_CACHE);
- FILE *f = fopen(Name, "r");
- if(f) {
- int len = strlen(m_Folder);
- cPlaylistItem *it = NULL;
- cReadLine r;
- const char *pt;
- while(NULL != (pt = r.Read(f))) {
- if(!strncmp(pt, "File", 4)) {
- it = NULL;
- const char *Filename = strchrnext(pt+4, '=');
- if(Filename && *Filename) {
- for(cPlaylistItem *i = First(); i; i=Next(i)) {
- if(!strncmp(i->Filename, m_Folder, len)) {
- if(!strcmp(*i->Filename + len, Filename)) {
- it = i;
- break;
- }
- }
- }
- }
- } else if(it && !strncmp(pt, "Title", 5)) {
- it->Title = strchrnext(pt, '=');
- } else if(it && !strncmp(pt, "Tracknumber", 11)) {
- it->Tracknumber = strchrnext(pt, '=');
- } else if(it && !strncmp(pt, "Artist", 6)) {
- it->Artist = strchrnext(pt, '=');
- } else if(it && !strncmp(pt, "Album", 5)) {
- it->Album = strchrnext(pt, '=');
- } else {
- /*it = NULL;*/
- }
- }
- fclose(f);
- return true;
- }
- }
-
- return false;
-}
-
-#if 0
-static FILE *open_http(const char *PlaylistFile)
-{
- char file[1024] = "", host[128] = "", pt;
- int fd, port = 80;
-
- strn0cpy(host, PlaylistFile+strlen("http://"), sizeof(host)-1);
- pt = strchr(host, '/');
- if(pt) {
- strn0cpy(file, pt, sizeof(file)-1);
- *pt = 0;
- }
- pt = strchr(host, ':');
- if(pt) {
- *pt++ = 0;
- port = atoi(pt);
- }
-
- fd = tcp_connect(host, port);
- if(fd < 0) {
- LOGERR("TCP connect failed");
- return NULL;
- }
-
- int len = asprintf(&pt,
- "GET %s HTTP/1.1" "\r\n"
- "Host: %s" "\r\n"
- "\r\n",
- file, host);
- if(len != write(fd, pt, len)) {
- LOGERR("HTTP request write failed");
- free(pt);
- close(fd);
- return NULL;
- }
- free(pt);
-
- int state = 0;
- FILE *f = fdopen(fd, "r");
- cReadLine r;
- while(state >= 0 && NULL != (pt = r.Read(f))) {
- switch(state) {
- case 0: if(!strncmp(pt, "HTTP/1", 6) || !strstr(pt, " 200 ")) {
- LOGERR("HTTP error: %s", pt);
- fclose(f);
- return NULL;
- }
- state = 1;
- break;
- case 1: if(strcmp(pt, "\r\n"))
- break;
- return f;
- default: break;
- }
- }
-
- fclose(f);
- return NULL;
-}
-#endif
-
-int cPlaylist::ScanFolder(const char *FolderName,
- bool Recursive,
- bool (config_t::*Filter)(const char *))
-{
- cMutexLock ml(&m_Lock);
- static int depth = 0;
-
- DIR *d = opendir(FolderName);
-
- if (d) {
- LOGDBG("ScanFolder(%s)", FolderName);
- struct dirent *e;
- int n = 0, warn = -1;
- while ((e = readdir(d)) != NULL) {
- cString Buffer = cString::sprintf("%s%s", FolderName, e->d_name);
- struct stat st;
- if (stat(Buffer, &st) == 0) {
- if(S_ISDIR(st.st_mode)) {
- if (Recursive && !S_ISLNK(st.st_mode)) { /* don't want to loop ... */
- if(depth > 4) {
- LOGMSG("ScanFolder: Too deep directory tree");
- } else if(e->d_name[0]=='.') {
- } else {
- if(n<MAX_PLAYLIST_FILES) {
- depth++; /* limit depth */
- Buffer = cString::sprintf("%s/", *Buffer);
- n += ScanFolder(Buffer, Recursive, Filter);
- depth--;
- } else {
- if(!++warn)
- LOGMSG("ScanFolder: Found over %d matching files, list truncated!", n);
- break;
- }
- }
- }
- } else /* == if(!S_ISDIR(st.st_mode))*/ {
- // check symlink destination
- if (S_ISLNK(st.st_mode)) {
- Buffer = ReadLink(Buffer);
- if (!*Buffer)
- continue;
- if (stat(Buffer, &st) != 0)
- continue;
- }
- if((xc.*Filter)(Buffer)) {
- /* TODO: Should ScanDir add contents of playlist files ... ? */
- if(Filter == &config_t::IsPlaylistFile || !xc.IsPlaylistFile(Buffer)) {
- n++;
- if(n<MAX_PLAYLIST_FILES) {
- Add(new cPlaylistItem(e->d_name, FolderName));
- //LOGDBG("ScanFolder: %s", e->d_name);
- } else {
- if(!++warn)
- LOGMSG("ScanFolder: Found over %d matching files, list truncated!", n);
- break;
- }
- }
- }
- }
- }
- }
- LOGDBG("ScanFolder: Found %d matching files from %s", n, FolderName);
- closedir(d);
-
- return n;
- }
-
- LOGERR("ScanFolder: Error opening %s", FolderName);
- return 0;
-}
-
-void cPlaylist::StartScanner(void)
-{
- cMutexLock ml(&m_Lock);
-
- if(m_Scanner) {
- if(m_Scanner->Active())
- return;
- delete m_Scanner;
- m_Scanner = NULL;
- }
-
- /* check if cache is already up-to-date */
- cString CacheName = cString::sprintf("%s%s", *m_Folder, PLAYLIST_CACHE);
- struct stat stf, stc;
- if(!stat(m_Folder, &stf)) {
- if(!stat(CacheName, &stc)) {
- //LOGDBG("ID3 Cache modified %d, folder modified %d, diff %d",
- // (unsigned int)stc.st_mtime, (unsigned int)stf.st_mtime,
- // (unsigned int)(stc.st_mtime - stf.st_mtime));
- if(stc.st_mtime >= stf.st_mtime) {
- if(ReadCache()) {
- LOGDBG("cPlaylist: using up-to-date ID3 cache");
- //LOGMSG(" Cache read OK.");
- return;
- }
- LOGMSG("cPlaylist: ID3 cache read FAILED");
- } else {
- LOGDBG("cPlaylist: ID3 cache not up-to-date, using old cache and scanning for changes");
- ReadCache();
- }
- }
- //else LOGERR("cPlaylist: stat(%s) failed");
- }
- //else LOGERR("cPlaylist: stat(%s) failed");
-
- if(xc.enable_id3_scanner) {
- m_Scanner = new cID3Scanner(*this);
- m_Scanner->Start();
- }
-}
-
-int cPlaylist::ReadPlaylist(const char *file)
-{
- static int depth = 0; /* limit recursion */
- cPipe p;
- cPlaylistReader *parser = NULL;
- FILE *f;
-
- if(strncmp(file, "http:", 5) && strncmp(file, "https:", 6)) {
- f = fopen(file, "r");
- } else {
- // fetch playlist from server using curl
- LOGDBG("cPlaylist: fetching remote playlist from %s", file);
- cString Cmd = cString::sprintf("curl %s", file);
- if(!p.Open(Cmd, "r")) {
- LOGERR("cPlaylist: CURL command (%s) failed", *Cmd);
- return false;
- }
- // process as normal file
- f = p;
- }
-
- if(f) {
- LOGDBG("cPlaylist: parsing %s", file);
- const char *ext = strrchr(file, '.');
- if(!strcasecmp(ext, ".pls"))
- parser = new cPlsReader(*this);
- else if(!strcasecmp(ext, ".asx"))
- parser = new cAsxReader(*this);
- else /*if(!strcasecmp(ext, ".m3u"))*/
- parser = new cM3uReader(*this); /* parses plain lists (.ram, ...) too ...*/
-
- /* get folder */
- cString Folder = file;
- const char *folder = strrchr(Folder, '/');
- if (folder)
- Folder.Truncate(folder - Folder + 1);
-
- int n = 0;
- cReadLine r;
- char *pt;
- while(NULL != (pt = r.Read(f)) && n < MAX_PLAYLIST_FILES) {
- if(NULL != (pt = parser->Parse(pt))) {
-
- if(xc.IsPlaylistFile(pt)) {
- parser->ResetCache();
- LOGDBG("cPlaylist: found playlist inside playlist");
- if(depth > 4)
- LOGMSG("cPlaylist: recursion too deep, skipped %s", pt);
- else {
- depth++;
- if(*pt == '/' ||
- (strstr(pt,"://")+1 == strchr(pt,'/') &&
- strchr(pt,'/') - pt < 8))
- n += ReadPlaylist(pt);
- else
- n += ReadPlaylist(cString::sprintf("%s%s", *Folder, pt));
- depth--;
- }
-
- } else {
- if(*pt == '/' ||
- (strstr(pt,"://")+1 == strchr(pt,'/') &&
- strchr(pt,'/') - pt < 8)) {
- // absolute path
- Add(new cPlaylistItem(pt));
- if(parser->Title())
- Last()->Title = parser->Title();
- } else {
- // relative path
- Add(new cPlaylistItem(pt, Folder, parser->Title()));
- }
- Last()->Position = parser->Position();
- parser->ResetCache();
- //LOGDBG("read_playlist: %s", pt);
- n++;
- }
- }
- }
-
- if(! (FILE*) p)
- fclose(f);
-
- if(n >= MAX_PLAYLIST_FILES)
- LOGMSG("cPlaylist: Found over %d matching files, list truncated!", n);
- LOGDBG("cPlaylist: Found %d matching files", n);
- return n;
- }
-
- LOGERR("cPlaylist: Error opening %s", file);
- return 0;
-}
-
-static cString LastDir(cString& path)
-{
- cString tmp = path;
- const char *pt = strrchr(tmp, '/');
- if(pt && pt > *tmp) {
- tmp.Truncate(pt - tmp);
- pt = strrchr(tmp, '/');
- if(pt)
- return cString(pt+1);
- }
- return cString(NULL);
-}
-
-bool cPlaylist::Read(const char *PlaylistFile, bool Recursive)
-{
- cMutexLock ml(&m_Lock);
- bool Result = true;
-
- // extract playlist root folder
- if(!*m_Folder) {
- const char *pt;
- m_Folder = PlaylistFile;
- if (NULL != (pt=strrchr(m_Folder, '/')))
- m_Folder.Truncate(pt - m_Folder + 1);
- }
-
- if(xc.IsPlaylistFile(PlaylistFile)) {
- // Read playlist file
- Result = ReadPlaylist(PlaylistFile);
- m_Origin = ePlaylist;
-
- cString dir = LastDir(m_Folder);
- const char *name = strrchr(PlaylistFile, '/');
- name = name ? name+1 : NULL;
- if(*dir && name)
- m_Name = cString::sprintf("%s - %s", *dir, name);
- else
- m_Name = name ?: "";
-
- strip_extension(m_Name);
-
- } else if(PlaylistFile[ 0] == '/' &&
- PlaylistFile[strlen(PlaylistFile)-1] == '/') {
- // Scan folder
- Result = ScanFolder(PlaylistFile, Recursive) > 0;
- m_Origin = eImplicit;
- Sort();
-
- if(!*m_Name) {
- m_Name = PlaylistFile;
- m_Name.Truncate( strrchr(m_Name, '/') - m_Name);
- if(strrchr(m_Name, '/')) {
- cString dir = LastDir(m_Name);
- if(*dir)
- m_Name = cString::sprintf("%s - %s", *dir, strrchr(m_Name, '/')+1);
- else
- m_Name = strrchr(m_Name, '/')+1;
- }
- }
-
- } else {
- // Single file
- Add(new cPlaylistItem(PlaylistFile));
- m_Origin = eImplicit;
-
- if(!*m_Name) {
- m_Name = LastDir(m_Folder);
- if(!*m_Name)
- m_Name = "";
- }
- }
-
- if(Count() < 1) {
- LOGMSG("Empty playlist %s !", PlaylistFile);
- Add(new cPlaylistItem(PlaylistFile));
- }
-
- m_Version++;
- return Result;
-}
-
-cString cPlaylist::EscapeMrl(const char *mrl)
-{
- static const uint8_t hex[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
- const uint8_t *fn = (const uint8_t*)mrl;
- int size = strlen(mrl) + 16;
- char *buf = (char *)malloc(size);
- int i = 0, found = 0;
- LOGDBG("cPlaylist::EscapeMrl('%s')", fn);
-
- // Wait for first '/' (do not escape mrl start dvd:/, http://a@b/, ...)
- if (*fn == '/')
- found = 3;
-
- while (*fn) {
- if(size-7 < i)
- buf = (char *)realloc(buf, (size=size+16));
- switch (*fn) {
- case 1 ... ' ':
- case 127 ... 255:
- case '#':
- case '%':
- case ':':
- case ';':
- case '\'':
- case '\"':
- case '(':
- case ')':
- if (found > 2) {
- buf[i++] = '%';
- buf[i++] = hex[(*fn & 0xf0)>>4];
- buf[i++] = hex[(*fn & 0x0f)];
- break;
- }
- default:
- // file:/... -> only one '/' before escaping
- // http://.../ --> three '/' before escaping
- if(!found && (fn[0] == ':' && fn[1] == '/')) {
- if(fn[2] == '/') {
- // ex. http://user:pass@host/... --> wait for third '/'
- buf[i++] = *fn++;
- buf[i++] = *fn++;
- found += 2;
- } else {
- // ex. file:/local_file
- buf[i++] = *fn++;
- found += 3;
- }
- } else if(*fn == '/') {
- found++;
- }
- buf[i++] = *fn;
- break;
- }
- fn++;
- }
-
- buf[i] = 0;
- LOGDBG(" --> '%s'", buf);
- return cString(buf, true);
-}
-
-cString cPlaylist::GetEntry(cPlaylistItem *i, bool isPlaylist, bool isCurrent)
-{
-
- cString Entry = "";
- if ((*i->Artist && xc.playlist_artist) || (*i->Album && xc.playlist_album)) {
- Entry = cString::sprintf("%s%s%s%s%s%s(%s%s%s)",
- isPlaylist ? (isCurrent ? "*" : " ") : "",
- isPlaylist ? "\t" : " ",
- xc.playlist_tracknumber ? (*i->Tracknumber ?: "") : "",
- xc.playlist_tracknumber ? (*i->Tracknumber ? " - " : "") : "",
- *i->Title,
- isPlaylist ? "\t" : " ",
- xc.playlist_artist ? (*i->Artist ?: "") : "",
- xc.playlist_artist && xc.playlist_album ? (*i->Artist && *i->Album ? ":" : "") : "",
- xc.playlist_album ? (*i->Album ?: "") : "");
- } else {
- Entry = cString::sprintf("%s%s%s%s%s",
- isPlaylist ? (isCurrent ? "*" : " ") : "",
- isPlaylist ? "\t" : " ",
- xc.playlist_tracknumber ? (*i->Tracknumber ?: "") : "",
- xc.playlist_tracknumber ? (*i->Tracknumber ? " - " : "") : "",
- *i->Title);
- }
- return Entry;
-}
diff --git a/tools/playlist.h b/tools/playlist.h
deleted file mode 100644
index 50c3d97a..00000000
--- a/tools/playlist.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * playlist.h: Media player playlist
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: playlist.h,v 1.8 2008-02-19 04:24:34 phintuka Exp $
- *
- */
-
-#ifndef __XINELIBOUTPUT_PLAYLIST_H
-#define __XINELIBOUTPUT_PLAYLIST_H
-
-#include <vdr/tools.h> // cString, cListObject, cList<>
-#include <vdr/thread.h> // cMutex
-
-
-//
-// cPlaylistItem
-//
-
-class cPlaylistItem : public cListObject
-{
- private:
- cPlaylistItem();
-
- virtual int Compare(const cListObject &ListObject) const;
-
- public:
- cPlaylistItem(const char *filename); /* file name with full path */
- cPlaylistItem(const char *filename, /* file name without path */
- const char *path,
- const char *title = NULL,
- int position = -1);
-
- cString Filename; /* file name and full path */
-
- // Metainfo (ID3 etc.)
- cString Title;
- cString Tracknumber;
- cString Artist;
- cString Album;
-
- // position in playlist (if given in playlist file)
- int Position;
-};
-
-
-//
-// cPlaylistChangeNotify interface
-//
-
-class cPlaylistChangeNotify
-{
- public:
- virtual void PlaylistChanged(const cPlaylistItem *Item) = 0;
-
- virtual ~cPlaylistChangeNotify() {}
-};
-
-
-//
-// cPlaylist
-//
-
-
-class cID3Scanner;
-
-class cPlaylist : protected cList<cPlaylistItem>
-{
- private:
-
- cMutex m_Lock;
- cString m_Name; // playlist (or folder) name
- cString m_Folder; // path to "root" of playlist
- cPlaylistItem *m_Current; // now playing
- unsigned int m_Version;
-
- enum { ePlaylist, eImplicit } m_Origin;
-
- cPlaylistChangeNotify *m_Menu;
- cID3Scanner *m_Scanner;
-
- protected:
-
- bool StoreCache(void);
- bool ReadCache(void);
-
- int ReadPlaylist(const char *PlaylistFile);
- int ScanFolder(const char *FolderName,
- bool Recursive = false,
- bool (config_t::*Filter)(const char *) = &config_t::IsAudioFile);
-
- friend class cID3Scanner;
- friend class cPlaylistReader;
- void PlaylistChanged(const cPlaylistItem *Item);
- cPlaylistItem *Last(void) { return cList<cPlaylistItem>::Last(); }
-
- public:
-
- cPlaylist();
- virtual ~cPlaylist();
-
- const cString& Name(void) const { return m_Name; }
-
- // listen for changes in playlist
- void Listen(cPlaylistChangeNotify *Menu = NULL);
-
- // read playlist from file or create playlist from directory tree
- bool Read(const char *PlaylistFile, bool Recursive = false);
- void StartScanner(void);
- void Del(cPlaylistItem *it);
-
- void Sort(void);
- int Count(void) const;
-
- // access/iterate playlist items
- cPlaylistItem *First(void) { return Next(NULL); }
- cPlaylistItem *Next(const cPlaylistItem *i);
-
- // get/set current (now playing) item
- cPlaylistItem *Current(void);
- void SetCurrent(cPlaylistItem *current);
- cPlaylistItem *Next(void);
- cPlaylistItem *Prev(void);
-
- static cString EscapeMrl(const char *name);
- static cString GetEntry(cPlaylistItem *i, bool isPlaylist = false, bool isCurrent = false);
-};
-
-
-#endif // __XINELIBOUTPUT_PLAYLIST_H
diff --git a/tools/rle.c b/tools/rle.c
deleted file mode 100644
index 2425630b..00000000
--- a/tools/rle.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * rle.c: RLE utils
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: rle.c,v 1.3 2009-02-16 16:14:58 phintuka Exp $
- *
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "../xine_osd_command.h"
-
-#include "rle.h"
-
-
-#undef MAX
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-
-/*
- * rle_compress()
- *
- */
-int rle_compress(xine_rle_elem_t **rle_data, const uint8_t *data, uint w, uint h)
-{
- xine_rle_elem_t rle, *rle_p = 0, *rle_base;
- int x, y, num_rle = 0, rle_size = 8128;
- const uint8_t *c;
-
- rle_p = (xine_rle_elem_t*)malloc(4*rle_size);
- rle_base = rle_p;
-
- for (y = 0; y < h; y++) {
- rle.len = 0;
- rle.color = 0;
- c = data + y * w;
- for (x = 0; x < w; x++, c++) {
- if (rle.color != *c) {
- if (rle.len) {
- if ( (num_rle + h-y+1) > rle_size ) {
- rle_size *= 2;
- rle_base = (xine_rle_elem_t*)realloc( rle_base, 4*rle_size );
- rle_p = rle_base + num_rle;
- }
- *rle_p++ = rle;
- num_rle++;
- }
- rle.color = *c;
- rle.len = 1;
- } else {
- rle.len++;
- }
- }
- *rle_p++ = rle;
- num_rle++;
- }
-
- *rle_data = rle_base;
- return num_rle;
-}
-
-/*
- * rle_scale_nearest()
- *
- * - Simple nearest-neighbour scaling for RLE-compressed image
- * - fast scaling in compressed form without decompression
- */
-xine_rle_elem_t *rle_scale_nearest(const xine_rle_elem_t *old_rle, int *rle_elems,
- uint w, uint h, uint new_w, uint new_h)
-{
- #define FACTORBASE 0x100
- #define FACTOR2PIXEL(f) ((f)>>8)
- #define SCALEX(x) FACTOR2PIXEL(factor_x*(x))
- #define SCALEY(y) FACTOR2PIXEL(factor_y*(y))
-
- uint old_w = w, old_h = h;
- uint old_y = 0, new_y = 0;
- uint factor_x = FACTORBASE*new_w/old_w;
- uint factor_y = FACTORBASE*new_h/old_h;
- uint rle_size = MAX(8128, *rle_elems * new_h/h ); /* guess ... */
- uint num_rle = 0;
- xine_rle_elem_t *new_rle = (xine_rle_elem_t*)malloc(sizeof(xine_rle_elem_t)*rle_size);
- xine_rle_elem_t *new_rle_start = new_rle;
-
- /* we assume rle elements are breaked at end of line */
- while (old_y < old_h) {
- uint elems_current_line = 0;
- uint old_x = 0, new_x = 0;
-
- while (old_x < old_w) {
- uint new_x_end = SCALEX(old_x + old_rle->len);
-
- if (new_x_end > new_w) {
- new_x_end = new_w;
- }
-
- new_rle->len = new_x_end - new_x;
- new_rle->color = old_rle->color;
-
- old_x += old_rle->len;
- old_rle++; /* may be incremented to last element + 1 (element is not accessed anymore) */
-
- if (new_rle->len > 0) {
- new_x += new_rle->len;
- new_rle++;
-
- num_rle++;
- elems_current_line++;
-
- if ( (num_rle + 1) >= rle_size ) {
- rle_size *= 2;
- new_rle_start = (xine_rle_elem_t*)realloc( new_rle_start, 4*rle_size);
- new_rle = new_rle_start + num_rle;
- }
- }
- }
- if (new_x < new_w)
- (new_rle-1)->len += new_w - new_x;
- old_y++;
- new_y++;
-
- if (factor_y > FACTORBASE) {
- /* scale up -- duplicate current line ? */
- int dup = SCALEY(old_y) - new_y;
-
- /* if no lines left in (old) rle, copy all lines still missing from new */
- if (old_y == old_h)
- dup = new_h - new_y - 1;
-
- while (dup-- && (new_y+1<new_h)) {
- xine_rle_elem_t *prevline;
- uint n;
- if ( (num_rle + elems_current_line + 1) >= rle_size ) {
- rle_size *= 2;
- new_rle_start = (xine_rle_elem_t*)realloc( new_rle_start, 4*rle_size);
- new_rle = new_rle_start + num_rle;
- }
-
- /* duplicate previous line */
- prevline = new_rle - elems_current_line;
- for (n = 0; n < elems_current_line; n++) {
- *new_rle++ = *prevline++;
- num_rle++;
- }
- new_y++;
- }
-
- } else if (factor_y < FACTORBASE) {
- /* scale down -- drop next line ? */
- uint skip = new_y - SCALEY(old_y);
- if (old_y == old_h-1) {
- /* one (old) line left ; don't skip it if new rle is not complete */
- if (new_y < new_h)
- skip = 0;
- }
- while (skip-- &&
- old_y<old_h /* rounding error may add one line, filter it out */) {
- for (old_x = 0; old_x < old_w;) {
- old_x += old_rle->len;
- old_rle++;
- }
- old_y++;
- }
- }
- }
-
- *rle_elems = num_rle;
- return new_rle_start;
-}
diff --git a/tools/rle.h b/tools/rle.h
deleted file mode 100644
index d6900e8f..00000000
--- a/tools/rle.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * rle.h: RLE utils
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: rle.h,v 1.2 2009-02-16 16:14:58 phintuka Exp $
- *
- */
-
-#ifndef XINELIBOUTPUT_RLE_H_
-#define XINELIBOUTPUT_RLE_H_
-
-#if defined __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- scale_fast = 0, /* simple pixel doubling/dropping */
- scale_good_BW = 1, /* linear interpolation, palette re-generation */
-} scale_mode_t;
-
-
-struct xine_rle_elem_s;
-struct xine_clut_s;
-
-
-int rle_compress(struct xine_rle_elem_s **rle_data, const uint8_t *data, uint w, uint h);
-
-void rle_uncompress_lut8(const struct xine_rle_elem_s *rle_data,
- uint8_t *data, uint w, uint h);
-void rle_uncompress_argb(uint32_t *dst,
- const struct xine_rle_elem_s *rle_data, uint num_rle,
- uint w, uint h, uint stride,
- struct xine_clut_s *palette);
-
-/*
- * rle_scale_nearest()
- *
- * - Simple nearest-neighbour scaling for RLE-compressed image
- * - fast scaling in compressed form without decompression
- */
-struct xine_rle_elem_s *rle_scale_nearest(const struct xine_rle_elem_s *old_rle,
- int *rle_elems,
- uint w, uint h, uint new_w, uint new_h);
-
-
-#if defined __cplusplus
-}
-#endif
-
-#endif /* XINELIBOUTPUT_RLE_H_ */
diff --git a/tools/rtcp.h b/tools/rtcp.h
deleted file mode 100644
index 608f2daf..00000000
--- a/tools/rtcp.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * rtcp.h: RFC1889: RTCP
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: rtcp.h,v 1.3 2007-03-29 14:22:31 phintuka Exp $
- *
- */
-
-#ifndef XINELIBOUTPUT_RTCP_H_
-#define XINELIBOUTPUT_RTCP_H_
-
-#ifdef __APPLE__
-# include <machine/endian.h>
-#else
-# include <endian.h>
-#endif
-
-
-#ifndef PACKED
-# define PACKED __attribute__((packed))
-#endif
-
-#if __BYTE_ORDER == __BIG_ENDIAN
-#elif __BYTE_ORDER == __LITTLE_ENDIAN
-#else
-# error __BYTE_ORDER not defined
-#endif
-
-#if defined __cplusplus
-extern "C" {
-#endif
-
-
-/* RTCP packet types */
-typedef enum {
- RTCP_SR = 200,
- RTCP_RR = 201,
- RTCP_SDES = 202,
- RTCP_BYE = 203,
- RTCP_APP = 204
-} rtcp_type_t;
-
-/* RTCP SDES types */
-typedef enum {
- RTCP_SDES_END = 0,
- RTCP_SDES_CNAME = 1,
-
- RTCP_SDES_NAME = 2,
- RTCP_SDES_EMAIL = 3,
- RTCP_SDES_PHONE = 4,
- RTCP_SDES_LOC = 5,
- RTCP_SDES_TOOL = 6,
- RTCP_SDES_NOTE = 7,
- RTCP_SDES_PRIV = 8
-} rtcp_sdes_type_t;
-
-/* RTCP common header word */
-typedef struct {
- union {
- uint8_t raw[4];
- struct {
-#if __BYTE_ORDER == __BIG_ENDIAN
- unsigned int version:2; /* protocol version */
- unsigned int padding:1; /* padding flag */
- unsigned int count:5; /* varies by packet type */
-#else
- unsigned int count:5; /* varies by packet type */
- unsigned int padding:1; /* padding flag */
- unsigned int version:2; /* protocol version */
-#endif
- unsigned int ptype:8; /* RTCP packet type */
-
- uint16_t length; /* pkt len in words, w/o this word */
- } PACKED;
- } PACKED;
-} PACKED rtcp_common_t;
-
-/* RTCP RR (Reception report) */
-typedef struct {
- uint32_t ssrc; /* data source being reported */
- unsigned int fraction:8; /* fraction lost since last SR/RR */
- int lost:24; /* cumul. no. pkts lost (signed!) */
- uint32_t last_seq; /* extended last seq. no. received */
- uint32_t jitter; /* interarrival jitter */
- uint32_t lsr; /* last SR packet from this source */
- uint32_t dlsr; /* delay since last SR packet */
-} PACKED rtcp_rr_t;
-
-/* RTCP SR (Sender report) */
-typedef struct {
- uint32_t ssrc;
- uint32_t ntp_sec; /* NTP timestamp, most significant word / seconds */
- uint32_t ntp_frac;
- uint32_t rtp_ts;
- uint32_t psent; /* packets sent */
- uint32_t osent; /* octets sent */
- rtcp_rr_t rr[0]; /* variable-length list */
-} PACKED rtcp_sr_t;
-
-/* RTCP SDES item */
-typedef struct {
- uint8_t type; /* type of item (rtcp_sdes_type_t) */
- uint8_t length; /* length of item (in octets) */
- char data[0]; /* text, not null-terminated */
-} PACKED rtcp_sdes_item_t;
-
-/* RTCP packet */
-typedef struct {
- rtcp_common_t hdr;
- union {
- rtcp_sr_t sr;
- struct {
- uint32_t ssrc;
- rtcp_rr_t rr[0];
- } PACKED rr;
- struct {
- uint32_t ssrc; /* first SSRC/CSRC */
- rtcp_sdes_item_t item[0]; /* list of SDES items */
- } PACKED sdes;
- struct {
- uint32_t src[0]; /* list of sources */
- /* can't express trailing text for reason */
- } PACKED bye;
- } PACKED;
-} PACKED rtcp_packet_t;
-
-
-#if defined __cplusplus
-};
-#endif
-
-#endif /* XINELIBOUTPUT_RTCP_H_ */
diff --git a/tools/rtp.h b/tools/rtp.h
deleted file mode 100644
index fa2ccf63..00000000
--- a/tools/rtp.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * rtp.h: RFC1889: RTP - A Transport Protocol for Real-Time Applications
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: rtp.h,v 1.3 2007-03-29 14:22:31 phintuka Exp $
- *
- */
-
-#ifndef XINELIBOUTPUT_RTP_H_
-#define XINELIBOUTPUT_RTP_H_
-
-#ifdef __APPLE__
-# include <machine/endian.h>
-#else
-# include <endian.h>
-#endif
-
-
-#ifndef PACKED
-# define PACKED __attribute__((packed))
-#endif
-
-#if __BYTE_ORDER == __BIG_ENDIAN
-#elif __BYTE_ORDER == __LITTLE_ENDIAN
-#else
-# error __BYTE_ORDER not defined
-#endif
-
-#if defined __cplusplus
-extern "C" {
-#endif
-
-
-/* Generic RTP header extension */
-typedef struct stream_rtp_header_ext {
-
- union {
- uint8_t raw[4];
- uint32_t rawd;
-
- struct {
- uint16_t type;
- uint16_t size; /* Size of ext_data field in DWORDS */
- } PACKED;
- } PACKED;
-
- uint8_t ext_data[0];
-
-} PACKED stream_rtp_header_ext_t;
-
-
-/* Common RTP data header */
-typedef struct stream_rtp_header {
-
- union {
- uint8_t raw[12];
-
- struct {
-#if __BYTE_ORDER == __BIG_ENDIAN
- unsigned int version:2; /* protocol version */
- unsigned int padding:1; /* padding flag */
- unsigned int ext:1; /* header extension flag */
- unsigned int cc:4; /* CSRC count */
-
- unsigned int marker:1; /* marker bit */
- unsigned int paytype:7; /* payload type */
-#else
- unsigned int cc:4; /* CSRC count */
- unsigned int ext:1; /* header extension flag */
- unsigned int padding:1; /* padding flag */
- unsigned int version:2; /* protocol version */
-
- unsigned int paytype:7; /* payload type */
- unsigned int marker:1; /* marker bit */
-#endif
- uint16_t seq; /* sequence number */
- uint32_t ts; /* timestamp */
- uint32_t ssrc; /* synchronization source */
-
- /*uint32_t csrc[0];*/ /* optional CSRC list */
- } PACKED;
- } PACKED;
-
-
- union {
- stream_rtp_header_ext_t hdr_ext[0];
- uint8_t payload[0];
- } PACKED;
-
-
-} PACKED stream_rtp_header_t;
-
-#if defined __cplusplus
-};
-#endif
-
-#endif /* XINELIBOUTPUT_RTP_H_ */
-
diff --git a/tools/sap.h b/tools/sap.h
deleted file mode 100644
index 6b341efc..00000000
--- a/tools/sap.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * sap.h: RFC2974 Session Announcement Protocol (SAP) version 2
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: sap.h,v 1.8 2007-03-29 14:22:30 phintuka Exp $
- *
- */
-
-#ifndef XINELIBOUTPUT_SAP_H_
-#define XINELIBOUTPUT_SAP_H_
-
-#include <arpa/inet.h>
-#ifdef __APPLE__
-# include <machine/endian.h>
-#else
-# include <endian.h>
-#endif
-
-
-#ifndef PACKED
-# define PACKED __attribute__((packed))
-#endif
-
-/*#define LOG_SAP*/
-
-/* SAP IPv4 multicast addresses */
-#define SAP_IP_ADDRESS_GLOBAL "224.2.127.254" /* SAPv1 IP4 global scope multicast address */
-#define SAP_IP_ADDRESS_ORG "239.195.255.255" /* organization-local */
-#define SAP_IP_ADDRESS_LOCAL "239.255.255.255" /* local */
-#define SAP_IP_ADDRESS_LINK "224.0.0.255" /* link-local */
-
-#define SAP_IP_TTL 255
-#define SAP_UDP_PORT 9875
-
-
-typedef struct {
-
- /* RFC2974: SAP (Session Announcement Protocol) version 2 PDU */
-
- union {
- uint8_t raw0;
- struct {
-#if __BYTE_ORDER == __BIG_ENDIAN
- uint8_t version : 3;
- uint8_t addr_type : 1;
- uint8_t reserved : 1;
- uint8_t msg_type : 1;
- uint8_t encrypted : 1;
- uint8_t compressed : 1;
-#else
- uint8_t compressed : 1;
- uint8_t encrypted : 1;
- uint8_t msg_type : 1;
- uint8_t reserved : 1;
- uint8_t addr_type : 1;
- uint8_t version : 3;
-#endif
- } PACKED;
- } PACKED;
-
- uint8_t auth_len;
- uint16_t msgid_hash;
-
- union {
- uint8_t u8[4];
- uint32_t u32;
- } PACKED ip4_source;
-
- char payload[0];
-
-} PACKED sap_pdu_t;
-
-
-static inline sap_pdu_t *sap_create_pdu(uint32_t src_ip,
- uint16_t msgid,
- int announce,
- const char *payload_type,
- const char *payload)
-{
- sap_pdu_t *pdu;
- int length = sizeof(sap_pdu_t) + strlen(payload) + 3;
-
- if(payload_type)
- length += strlen(payload_type);
-
- if(! (pdu = (sap_pdu_t*)malloc(length)))
- return NULL;
-
- memset(pdu, 0, sizeof(sap_pdu_t));
- pdu->version = 1; /* SAP v1 / v2 */
- pdu->msg_type = announce ? 0 : 1;
- pdu->msgid_hash = msgid;
- pdu->ip4_source.u32 = src_ip;
-
- if(payload_type) {
- char *tmp = &pdu->payload[0];
- strcpy(tmp, payload_type);
- tmp += strlen(tmp) + 1;
- strcpy(tmp, payload);
- } else {
- /* payload type defaults to application/sdp */
- sprintf(&pdu->payload[0], "%s%c%c", payload, 0, 0);
- }
-
- return pdu;
-}
-
-static inline int sap_compress_pdu(sap_pdu_t *pdu)
-{
-#ifdef HAVE_ZLIB_H
-
- /* zlib compression */
-
- Compress();
-
- /*pdu->compressed = 1;*/
-
-#endif
-
- /* not implemented */
-
- pdu->compressed = 0;
- return -1;
-}
-
-static inline int sap_send_pdu(int *pfd, sap_pdu_t *pdu, uint32_t dst_ip)
-{
- int len = 0, r;
- int iReuse = 1, iLoop = 1, iTtl = SAP_IP_TTL;
- int fd;
-
- if(!pfd || *pfd < 0) {
- fd = socket(AF_INET, SOCK_DGRAM, 0);
-
- if(fd < 0) {
- LOGERR("socket() failed (UDP/SAP multicast)");
- return -1;
- }
-
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &iReuse, sizeof(int));
- setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &iTtl, sizeof(int));
- setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &iLoop, sizeof(int));
-
- // Connect to multicast address
- struct sockaddr_in sin;
- sin.sin_family = AF_INET;
- sin.sin_port = htons(SAP_UDP_PORT);
- sin.sin_addr.s_addr = dst_ip ? dst_ip : inet_addr(SAP_IP_ADDRESS_GLOBAL);
-
- if(connect(fd, (struct sockaddr *)&sin, sizeof(sin))==-1)
- LOGERR("UDP/SAP multicast connect() failed.");
-
- // Set to non-blocking mode
- fcntl (fd, F_SETFL, fcntl (fd, F_GETFL) | O_NONBLOCK);
-
- if(pfd)
- *pfd = fd;
-
- } else {
- fd = *pfd;
- }
-
- // size of PDU
- len += strlen(&pdu->payload[0]);
- if(!strstr(&pdu->payload[0], "\r\n")) {
- /* assume mime content type is present */
- len += 1;
- len += strlen(&pdu->payload[len]);
- len += sizeof(sap_pdu_t);
- }
-
- // network order
- pdu->msgid_hash = htons(pdu->msgid_hash);
-
- // send
- r = send(fd, pdu, len, 0);
- if(r < 0)
- LOGERR("UDP/SAP multicast send() failed.");
-
- if(!pfd)
- close(fd);
-
-#ifdef LOG_SAP
- /* log PDU */
- for(int i=0; i<len;) {
- char x[4096]="", a[4096]="";
- for(int j=0; j<16 && i<len; i++, j++) {
- char t[8], ch = ((char*)pdu)[i];
- sprintf(t, "%02X ", ((unsigned int)ch)&0xff);
- strcat(x, t);
- sprintf(t, "%c", (ch>=32 && ch<127) ? ch : '.');
- strcat(a, t);
- }
- LOGMSG("SAP: 0x%02x: %-50s%-18s", i/16-1, x, a);
- }
-#endif
-
- // back to host order
- pdu->msgid_hash = ntohs(pdu->msgid_hash);
-
- return r == len ? len : -1;
-}
-
-
-#endif /* XINELIBOUTPUT_SAP_H_ */
diff --git a/tools/sdp.h b/tools/sdp.h
deleted file mode 100644
index 514c29c1..00000000
--- a/tools/sdp.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * sdp.h: RFC2974 Session Description Protocol (SDP)
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: sdp.h,v 1.5 2009-02-10 12:42:38 phintuka Exp $
- *
- */
-
-#ifndef XINELIBOUTPUT_SDP_H_
-#define XINELIBOUTPUT_SDP_H_
-
-
-#define SDP_MIME_TYPE "application/sdp"
-
-#define SDP_PAYLOAD_MPEG_PES 96
-#define SDP_PAYLOAD_MPEG_TS 33
-
-static const char *vdr_sdp_description(const char *vdr_ip,
- int vdr_svdrp_port,
- int vdr_xineliboutput_port,
- const char *rtp_ip,
- uint32_t rtp_ssrc,
- uint32_t payload_type,
- int rtp_port,
- int rtp_ttl)
-{
- static uint8_t s_serial = 0;
- static cString s_data;
- static char s_hostname[257] = {0};
-
- uint64_t serial = (time(NULL) << 2) + ((s_serial++) & 0x03);
- cString payload;
-
- if (!s_hostname[0])
- gethostname(s_hostname, 256);
-
- if (payload_type == SDP_PAYLOAD_MPEG_PES) {
- payload = cString::sprintf(
- /* video/mp2p udp/rtp */
- /* media */ "m=video %d RTP/AVP 96"
- /* */ "\r\n" "a=rtpmap:96 MP2P/90000"
- , rtp_port
- );
- } else {
- payload = cString::sprintf(
- /* video/mp2t udp/rtp */
- /* media */ "m=video %d RTP/AVP 33"
- , rtp_port
- );
- }
-
- s_data = cString::sprintf(
- /*** session ***/
- /* version */ "v=0"
- /* origin */ "\r\n" "o=%s %u %"PRIu64" IN IP4 %s"
- /* name */ "\r\n" "s=%s@%s (multicast %s:%d)"
- /* opt:info */ /*"\r\n" "i=vdr-xineliboutput primary device output"*/
- /* time */ "\r\n" "t=0 0"
-
- /*** data stream(s) ***/
- /* connection */ "\r\n" "c=IN IP4 %s/%d"
- /* */ "\r\n" "a=recvonly"
- /* */ "\r\n" "a=type:broadcast"
- /* */ "\r\n" "a=x-plgroup:vdr"
- /* *media */ "\r\n" "%s"
-
- /* media */ /*"\r\n" "m=video %d udp MP2P"*/
- /* */ /*"\r\n" "a=mux:ps"*/
- /* */ /*"\r\n" "a=packetformat:RAW"*/
-#if 0
- /*** rtsp control port ***/
- /* connection */ "\r\n" "c=IN IP4 %s"
- /* media */ "\r\n" "m=control %d tcp/http rtsp"
-#endif
- /*** xineliboutput control port ***/
- /* connection */ "\r\n" "c=IN IP4 %s"
- /* media */ "\r\n" "m=control %d tcp x-vdr-xineliboutput"
-
- /*** SVDRP control port ***/
- /* connection */ "\r\n" "c=IN IP4 %s"
- /* media */ "\r\n" "m=control %d tcp x-svdrp"
-
- /* origin */
- , "vdr", rtp_ssrc, serial, vdr_ip
-
- /* name */
- , "vdr", s_hostname, rtp_ip, rtp_port
-
- /* media */
- , rtp_ip, rtp_ttl
- , *payload
-
-#if 0
- /* tcp/http control/rtsp */
- , vdr_ip
- , vdr_xineliboutput_port
-#endif
- /* tcp control/x-vdr-xineliboutput */
- , vdr_ip
- , vdr_xineliboutput_port
-
- /* tcp control/x-svdrp */
- , vdr_ip
- , vdr_svdrp_port
- );
- return s_data;
-}
-
-
-#endif /* XINELIBOUTPUT_SDP_H_ */
diff --git a/tools/time_pts.c b/tools/time_pts.c
deleted file mode 100644
index 81ee7c73..00000000
--- a/tools/time_pts.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * time_pts.c: Adjustable clock in PTS units
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: time_pts.c,v 1.4 2008-04-28 20:48:05 phintuka Exp $
- *
- */
-
-#define __STDC_FORMAT_MACROS
-#define __STDC_CONSTANT_MACROS
-#include <inttypes.h>
-#include <time.h>
-
-#include <vdr/config.h>
-
-#include "../logdefs.h" // logging
-
-#include "time_pts.h"
-
-
-#define MAX_SCR ((int64_t)0x1ffffffffLL)
-
-#if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK)
-#else
-# warning Posix monotonic clock not available
-#endif
-
-int cTimePts::m_Monotonic = -1;
-
-void cTimePts::Init(void)
-{
-#if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK)
- if(m_Monotonic >= 0)
- return;
-
- m_Monotonic = 0;
-
- struct timespec resolution;
- if(clock_getres(CLOCK_MONOTONIC, &resolution)) {
- LOGERR("cTimePts: clock_getres(CLOCK_MONOTONIC) failed");
- return;
- }
-
- LOGDBG("cTimePts: clock_gettime(CLOCK_MONOTONIC): clock resolution %d us",
- ((int)resolution.tv_nsec) / 1000);
-
- if( resolution.tv_sec == 0 && resolution.tv_nsec <= 1000000 ) {
- struct timespec tp;
- if(clock_gettime(CLOCK_MONOTONIC, &tp)) {
- LOGERR("cTimePts: clock_gettime(CLOCK_MONOTONIC) failed");
- } else {
- LOGDBG("cTimePts: using monotonic clock");
- m_Monotonic = 1;
- }
- }
-#endif
-}
-
-cTimePts::cTimePts(void)
-{
- m_Paused = false;
- m_ScrSpeed = 90000;
- m_Multiplier = 90000;
-
- Init();
-
- Set();
-}
-
-int64_t cTimePts::Now(void) const
-{
- if(m_Paused)
- return begin;
-
- struct timeval t;
-
-#if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK)
- if(m_Monotonic) {
- struct timespec tp;
-
- if(clock_gettime(CLOCK_MONOTONIC, &tp)) {
- LOGERR("cTimePts: clock_gettime(CLOCK_MONOTONIC) failed");
- return -1;
- }
-
- t.tv_sec = tp.tv_sec;
- t.tv_usec = tp.tv_nsec/1000;
-
- } else if (gettimeofday(&t, NULL)) {
- LOGERR("cTimePts: gettimeofday() failed");
- return -1;
- }
-#else
- if (gettimeofday(&t, NULL)) {
- LOGERR("cTimePts: gettimeofday() failed");
- return -1;
- }
-#endif
-
- t.tv_sec -= tbegin.tv_sec;
- if(t.tv_usec < tbegin.tv_usec) {
- t.tv_sec--;
- t.tv_usec += 1000000;
- }
- t.tv_usec -= tbegin.tv_usec;
-
- int64_t pts = 0;
- pts += (int64_t)t.tv_sec * (int64_t)m_ScrSpeed;
- pts += (int64_t)t.tv_usec * (int64_t)m_ScrSpeed / INT64_C(1000000);
-
- if(m_Multiplier != 90000)
- pts = pts * m_Multiplier / INT64_C(90000);
-
- return ( pts + begin ) & MAX_SCR;
-}
-
-void cTimePts::Set(int64_t Pts)
-{
- begin = Pts;
-
-#if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK)
- if(m_Monotonic) {
- struct timespec tp;
-
- if(!clock_gettime(CLOCK_MONOTONIC, &tp)) {
- tbegin.tv_sec = tp.tv_sec;
- tbegin.tv_usec = tp.tv_nsec/1000;
- return;
- }
-
- LOGERR("cTimePts: clock_gettime(CLOCL_MONOTONIC) failed");
- m_Monotonic = 0;
- }
-#endif
-
- gettimeofday(&tbegin, NULL);
-}
-
-void cTimePts::Pause(void)
-{
- Set(Now());
- m_Paused = true;
-}
-
-void cTimePts::Resume(void)
-{
- if(m_Paused) {
- Set(begin);
- m_Paused = false;
- }
-}
-
-void cTimePts::TrickSpeed(const int Multiplier)
-{
- Set(Now());
-
- if(Multiplier < 0)
- m_Multiplier = 90000 * (-Multiplier);
- else if(Multiplier > 0)
- m_Multiplier = 90000 / Multiplier;
- else
- LOGERR("cTimePts::SetSpeed: Multiplier=%d", Multiplier);
-}
-
-void cTimePts::SetScrSpeed(const int ScrSpeed)
-{
- Set(Now());
-
- m_ScrSpeed = ScrSpeed;
-}
diff --git a/tools/time_pts.h b/tools/time_pts.h
deleted file mode 100644
index fafc7199..00000000
--- a/tools/time_pts.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * time_pts.h: Adjustable clock in PTS units
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: time_pts.h,v 1.4 2008-04-28 20:48:05 phintuka Exp $
- *
- */
-
-#ifndef __TIME_PTS_H
-#define __TIME_PTS_H
-
-#include <stdint.h> // int64_t
-#include <sys/time.h> // struct timeval
-
-
-class cTimePts
-{
- private:
- int64_t begin; /* Start time (PTS) */
- struct timeval tbegin; /* Start time (real time) */
- bool m_Paused;
- int m_Multiplier;
- int m_ScrSpeed;
-
- static int m_Monotonic;
- static void Init(void);
-
- public:
- cTimePts(void);
-
- int64_t Now(void) const;
- void Set(int64_t Pts = 0LL);
-
- void Pause(void);
- void Resume(void);
- void TrickSpeed(const int Multiplier);
-
- void SetScrSpeed(const int ScrSpeed = 90000);
-};
-
-#endif // __TIME_PTS_H
diff --git a/tools/timer.c b/tools/timer.c
deleted file mode 100644
index f24e925a..00000000
--- a/tools/timer.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * timer.c: Threaded timer class
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: timer.c,v 1.2 2007-10-15 00:15:07 phintuka Exp $
- *
- */
-
-#include <sys/time.h>
-
-#include <vdr/config.h>
-#include <vdr/tools.h>
-#include <vdr/thread.h>
-
-#include "timer.h"
-
-//#define XINELIBOUTPUT_DEBUG
-//#define XINELIBOUTPUT_DEBUG_STDOUT
-#ifdef XINELIBOUTPUT_DEBUG
-# include "logdefs.h"
-#else
-# define TRACE(x)
-# define TRACEF(x)
-#endif
-
-// ---------------------------- cTimerThreadEvent ----------------------------
-
-class cTimerThreadEvent : public cListObject {
- public:
- cTimerThreadEvent(cTimerCallback *Handler, unsigned int TimeoutMs,
- bool DeleteOnCancel = false) :
- m_Handler(Handler),
- m_DeleteOnCancel(DeleteOnCancel),
- m_TimeoutMs(TimeoutMs)
- {
- m_NextEventTime = cTimeMs::Now();
- UpdateEventTime();
- }
-
- ~cTimerThreadEvent()
- {
- if(m_DeleteOnCancel && m_Handler)
- delete m_Handler;
- }
-
- void UpdateEventTime()
- {
- m_NextEventTime += m_TimeoutMs;
- }
-
- int TimeToNextEvent(void)
- {
- return m_NextEventTime - cTimeMs::Now();
- }
-
- virtual bool operator< (const cListObject &ListObject)
- {
- const cTimerThreadEvent *o = (cTimerThreadEvent *)&ListObject;
- return m_NextEventTime<o->m_NextEventTime;
- }
-
- virtual int Compare(const cListObject &ListObject) const
- {
- const cTimerThreadEvent *o = (cTimerThreadEvent *)&ListObject;
- if(m_NextEventTime<o->m_NextEventTime)
- return -1;
- else if(m_NextEventTime>o->m_NextEventTime)
- return 1;
- return 0;
- }
-
- cTimerCallback *m_Handler;
-
- protected:
- bool m_DeleteOnCancel;
- unsigned int m_TimeoutMs;
- int64_t m_NextEventTime;
-};
-
-// ------------------------------- cTimerThread ------------------------------
-
-class cTimerThread : public cThread {
- private:
- cTimerThread(cTimerThread&); // copy not allowed
-
- static cMutex m_InstanceLock;
- static cTimerThread *m_Instance; // singleton
-
- cMutex m_Lock;
- cCondVar m_Signal;
- cList<cTimerThreadEvent> m_Events;
- cTimerThreadEvent *m_RunningEvent;
- bool m_Finished;
- bool m_HandlerRunning;
-
- cTimerThread() :
- m_RunningEvent(NULL),
- m_Finished(false),
- m_HandlerRunning(false)
- {
- }
-
- virtual ~cTimerThread()
- {
- m_Lock.Lock();
- cTimerThreadEvent *ev;
- while(NULL != (ev = m_Events.First())) {
- m_Events.Del(ev,true);
- }
- m_Lock.Unlock();
- m_Signal.Broadcast();
- Cancel(1);
- }
-
- protected:
-
- virtual void Action()
- {
- TRACEF("cTimerThread::Action");
- m_Lock.Lock();
- while(m_Events.First()) {
- m_Signal.TimedWait(m_Lock,
- max(1, m_Events.First()->TimeToNextEvent()));
- TRACE("cTimerThread::Action waked up");
- while(NULL != (m_RunningEvent = m_Events.First()) &&
- m_RunningEvent->TimeToNextEvent() <= 0) {
- TRACE("cTimerThread::Action calling handler");
- m_HandlerRunning=true;
-// m_Lock.Unlock();
-// - can't unlock or running timer handler may be deleted while
-// executing (or thread may be killed by Delete)
- bool result = m_RunningEvent->m_Handler->TimerEvent();
-// m_Lock.Lock();
- m_HandlerRunning=false;
- if(!result) {
- if(m_RunningEvent) { // check if event was cancelled in handler...
- TRACE("cTimerThread::Action handler cancelled timer");
- m_Events.Del(m_RunningEvent, true);
- }
- } else {
- if(m_RunningEvent) {
- TRACE("cTimerThread::Action timer re-scheduled");
- m_RunningEvent->UpdateEventTime();
- m_Events.Sort();
- }
- }
- m_RunningEvent = NULL;
- }
- }
- m_Finished = true;
- m_Lock.Unlock();
- }
-
- void Add(cTimerThreadEvent *Event)
- {
- TRACEF("cTimerThread::Add");
- //m_Events.Del(Event, false);
- Event->Unlink();
- Del(Event->m_Handler);
- m_Events.Add(Event);
- m_Events.Sort();
- }
-
- bool Del(cTimerCallback *Handler, void *TargetId=NULL,
- bool inDestructor=false)
- {
- TRACEF("cTimerThread::Del");
- cTimerThreadEvent *ev = m_Events.First();
- while(ev) {
- if(ev->m_Handler == Handler ||
- (TargetId && ev->m_Handler->TargetId() == TargetId) ||
- (Handler && ev->m_Handler->is(Handler,Handler->size()))) {
- cTimerThreadEvent *nev = m_Events.Next(ev);
- if(inDestructor) ev->m_Handler=NULL;
- m_Events.Del(ev, true);
- ev = nev;
- } else
- ev = m_Events.Next(ev);
- }
- if(m_RunningEvent &&
- (m_RunningEvent->m_Handler == Handler ||
- m_RunningEvent->m_Handler->TargetId() == TargetId))
- m_RunningEvent = NULL;
- return !m_HandlerRunning && !m_RunningEvent && !m_Events.First();
- }
-
- public:
-
- static void AddEvent(cTimerCallback *Handler, unsigned int TimeoutMs,
- bool DeleteOnCancel=false)
- {
- TRACEF("cTimerThread::AddEvent");
- m_InstanceLock.Lock();
- if(m_Instance && m_Instance->m_Finished) {
- delete m_Instance;
- m_Instance = NULL;
- }
- if(!m_Instance) {
- m_Instance = new cTimerThread;
- m_Instance->m_Lock.Lock();
- m_Instance->Start();
- } else {
- m_Instance->m_Lock.Lock();
- m_Instance->m_Signal.Broadcast();
- }
- m_Instance->Add(new cTimerThreadEvent(Handler, max(1U,TimeoutMs),
- DeleteOnCancel));
- m_Instance->m_Lock.Unlock();
- m_InstanceLock.Unlock();
- }
-
- static void CancelEvent(cTimerCallback *Handler, void *TargetId = NULL,
- bool inDestructor=false)
- {
- TRACEF("cTimerThread::CancelEvent");
- m_InstanceLock.Lock();
- if(m_Instance && !m_Instance->m_Finished) {
- m_Instance->m_Lock.Lock();
- if(m_Instance->Del(Handler, TargetId, inDestructor) && !inDestructor) {
- m_Instance->m_Lock.Unlock();
- delete m_Instance;
- m_Instance = NULL;
- } else
- m_Instance->m_Lock.Unlock();
- }
- m_InstanceLock.Unlock();
- }
-
-};
-
-cMutex cTimerThread::m_InstanceLock;
-cTimerThread *cTimerThread::m_Instance = NULL;
-
-// ------------------------------ cTimerCallback -----------------------------
-
-cTimerCallback::~cTimerCallback()
-{
- TRACEF("cTimerCallback::~cTimerCallback");
- cTimerThread::CancelEvent(this, NULL, true);
-}
-
-void cTimerCallback::Set(cTimerCallback *handler, unsigned int TimeoutMs)
-{
- TRACEF("cTimerCallback::Set");
- cTimerThread::AddEvent(handler, TimeoutMs);
-}
-
-void cTimerCallback::Cancel(cTimerCallback *handler)
-{
- TRACEF("cTimerCallback::Cancel");
- cTimerThread::CancelEvent(handler);
-}
-
-// ------------------------------- cTimerEvent -------------------------------
-
-//cTimerEvent::cTimerEvent(unsigned int TimeoutMs)
-//{
-// TRACEF("cTimerEvent::cTimerEvent");
-//// cTimerThread::AddEvent(this, TimeoutMs, true);
-//}
-
-void cTimerEvent::AddEvent(unsigned int TimeoutMs)
-{
- TRACEF("cTimerEvent::AddEvent");
- cTimerThread::AddEvent(this, TimeoutMs, true);
-}
-
-void cTimerEvent::Cancel(cTimerEvent *&event)
-{
- TRACEF("cTimerEvent::Cancel");
- cTimerThread::CancelEvent(event);
- event = NULL;
-}
-
-void cTimerEvent::CancelAll(void *Target)
-{
- TRACEF("cTimerEvent::CancelAll");
- cTimerThread::CancelEvent(NULL, Target);
-}
-
-
-
-
-
-
-
diff --git a/tools/timer.h b/tools/timer.h
deleted file mode 100644
index 2ee8724b..00000000
--- a/tools/timer.h
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * timer.h: Threaded timer class
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: timer.h,v 1.1 2006-06-03 10:04:28 phintuka Exp $
- *
- */
-
-#ifndef __XINELIBOUTPUT_TIMER_H
-#define __XINELIBOUTPUT_TIMER_H
-
-//
-// cTimerCallback : timer callback handler interface
-//
-class cTimerCallback {
- protected:
- virtual bool TimerEvent() = 0; // return false to cancel timer
-
- virtual void *TargetId() { return (void*)this; }
- virtual int size() { return sizeof(*this); }
- virtual bool is(void *data, int len)
- {
- return len==sizeof(*this) && TargetId()==data;
- }
-
- friend class cTimerThread;
-
- public:
- static void Set(cTimerCallback *, unsigned int TimeoutMs);
- static void Cancel(cTimerCallback *);
-
- virtual ~cTimerCallback();
-};
-
-//
-// cTimerEvent : base class for timer events
-//
-class cTimerEvent : protected cTimerCallback {
- private:
- cTimerEvent(cTimerEvent&);
-
- protected:
- cTimerEvent() {};
-
- virtual void AddEvent(unsigned int TimeoutMs);
-
- static void CancelAll(void *Target);
-
- template<class TCLASS> friend void CancelTimerEvents(TCLASS*);
- friend class cTimerThread;
-
- public:
- static void Cancel(cTimerEvent *&);
-};
-
-//
-// make gcc 3.4.5 happy
-//
-template<class TCLASS, class TRESULT>
-cTimerEvent *CreateTimerEvent(TCLASS *c, TRESULT (TCLASS::*fp)(void),
- unsigned int TimeoutMs);
-template<class TCLASS, class TRESULT, class TARG1>
-cTimerEvent *CreateTimerEvent(TCLASS *c, TRESULT (TCLASS::*fp)(TARG1),
- TARG1 arg1,
- unsigned int TimeoutMs);
-template<class TCLASS>
-cTimerEvent *CreateTimerEvent(TCLASS *c, void (TCLASS::*fp)(void),
- unsigned int TimeoutMs, bool runOnce = true);
-template<class TCLASS, class TARG1>
-cTimerEvent *CreateTimerEvent(TCLASS *c, void (TCLASS::*fp)(TARG1),
- TARG1 arg1,
- unsigned int TimeoutMs, bool runOnce = true);
-
-//
-// Timer event templates
-//
-
-template <class TCLASS, class TRESULT>
-class cTimerFunctorR0 : public cTimerEvent {
-
- public:
-
- protected:
- typedef TRESULT (TCLASS::*TFUNC)(void);
-
- cTimerFunctorR0(TCLASS *obj, TFUNC f, unsigned int TimeoutMs) :
- m_obj(obj), m_f(f)
- {
- AddEvent(TimeoutMs);
- }
-
- virtual ~cTimerFunctorR0() {};
-
- virtual bool TimerEvent(void)
- {
- return (*m_obj.*m_f)();
- }
-
- virtual void *TargetId() { return (void*)m_obj; }
- virtual int size() { return sizeof(*this); }
- virtual bool is(void *data, int len)
- {
- return sizeof(*this)==len && !memcmp(this,data,len);
- }
-
- private:
- TCLASS *m_obj;
- TFUNC m_f;
-
- friend cTimerEvent *CreateTimerEvent<TCLASS,TRESULT>(TCLASS*,TFUNC,unsigned int);
-};
-
-template <class TCLASS, class TRESULT, class TARG1>
-class cTimerFunctorR1 : public cTimerEvent {
-
- public:
-
- protected:
- typedef TRESULT (TCLASS::*TFUNC)(TARG1);
-
- cTimerFunctorR1(TCLASS *obj, TFUNC f, TARG1 arg1, unsigned int TimeoutMs) :
- m_obj(obj), m_f(f), m_arg1(arg1)
- {
- AddEvent(TimeoutMs);
- }
-
- virtual ~cTimerFunctorR1() {};
-
- virtual bool TimerEvent(void)
- {
- return (*m_obj.*m_f)(m_arg1);
- }
-
- virtual void *TargetId() { return (void*)m_obj; }
- virtual int size() { return sizeof(*this); }
- virtual bool is(void *data, int len)
- {
- return sizeof(*this)==len && !memcmp(this,data,len);
- }
-
- private:
- TCLASS *m_obj;
- TFUNC m_f;
- TARG1 m_arg1;
-
- friend cTimerEvent *CreateTimerEvent<TCLASS,TRESULT,TARG1>(TCLASS*,TFUNC,TARG1,unsigned int);
-};
-
-template <class TCLASS>
-class cTimerFunctor0 : public cTimerEvent {
-
- public:
-
- protected:
- typedef void (TCLASS::*TFUNC)(void);
-
- cTimerFunctor0(TCLASS *obj, TFUNC f,
- unsigned int TimeoutMs, bool runOnce) :
- m_obj(obj), m_f(f), m_runAgain(!runOnce)
- {
- AddEvent(TimeoutMs);
- }
-
- virtual ~cTimerFunctor0() {};
-
- virtual bool TimerEvent(void)
- {
- (*m_obj.*m_f)();
- return m_runAgain;
- }
-
- virtual void *TargetId() { return (void*)m_obj; }
- virtual int size() { return sizeof(*this); }
- virtual bool is(void *data, int len)
- {
- return sizeof(*this)==len && !memcmp(this,data,len);
- }
-
- private:
- TCLASS *m_obj;
- TFUNC m_f;
- bool m_runAgain;
-
- friend cTimerEvent *CreateTimerEvent<TCLASS>(TCLASS*,TFUNC,unsigned int,bool);
-};
-
-template <class TCLASS, class TARG1>
-class cTimerFunctor1 : public cTimerEvent {
-
- public:
-
- protected:
- typedef void (TCLASS::*TFUNC)(TARG1);
-
- cTimerFunctor1(TCLASS *obj, TFUNC f, TARG1 arg1,
- unsigned int TimeoutMs, bool runOnce) :
- m_obj(obj), m_f(f), m_arg1(arg1), m_runAgain(!runOnce)
- {
- AddEvent(TimeoutMs);
- }
-
- virtual ~cTimerFunctor1() {};
-
- virtual bool TimerEvent(void)
- {
- (*m_obj.*m_f)(m_arg1);
- return m_runAgain;
- }
-
- virtual void *TargetId() { return (void*)m_obj; }
- virtual int size() { return sizeof(*this); }
- virtual bool is(void *data, int len)
- {
- return sizeof(*this)==len && !memcmp(this,data,len);
- }
-
- private:
- TCLASS *m_obj;
- TFUNC m_f;
- TARG1 m_arg1;
- bool m_runAgain;
-
- friend cTimerEvent *CreateTimerEvent<TCLASS,TARG1>(TCLASS*,TFUNC,TARG1,unsigned int,bool);
-};
-
-//
-// Function templates for timer event creation and cancellation
-//
-
-template<class TCLASS, class TRESULT>
-cTimerEvent *CreateTimerEvent(TCLASS *c, TRESULT (TCLASS::*fp)(void),
- unsigned int TimeoutMs)
-{
- return new cTimerFunctorR0<TCLASS,TRESULT>(c,fp,TimeoutMs);
-}
-
-template<class TCLASS, class TRESULT, class TARG1>
-cTimerEvent *CreateTimerEvent(TCLASS *c, TRESULT (TCLASS::*fp)(TARG1),
- TARG1 arg1,
- unsigned int TimeoutMs)
-{
- return new cTimerFunctorR1<TCLASS,TRESULT,TARG1>(c,fp,arg1,TimeoutMs);
-}
-
-template<class TCLASS>
-cTimerEvent *CreateTimerEvent(TCLASS *c, void (TCLASS::*fp)(void),
- unsigned int TimeoutMs, bool runOnce = true)
-{
- return new cTimerFunctor0<TCLASS>(c,fp,TimeoutMs,runOnce);
-}
-
-template<class TCLASS, class TARG1>
-cTimerEvent *CreateTimerEvent(TCLASS *c, void (TCLASS::*fp)(TARG1),
- TARG1 arg1,
- unsigned int TimeoutMs, bool runOnce = true)
-{
- return new cTimerFunctor1<TCLASS,TARG1>(c,fp,arg1,TimeoutMs,runOnce);
-}
-
-template<class TCLASS>
-void CancelTimerEvents(TCLASS *c)
-{
- cTimerEvent::CancelAll((void*)c);
-}
-
-
-// usage:
-//
-// 'this' derived from cTimerHandler:
-// Set timer:
-// cTimerCallback::Set(this, TimeoutMs);
-// Cancel timer:
-// - return false from handler or
-// - call cTimerCallback::Cancel(this); or
-// - delete 'this' object
-//
-// any function of any class:
-// Set timer:
-// - cTimerEvent *event = CreateTimerEvent(...);
-// example:
-// CreateTimerEvent(this, &cXinelibDevice::TimerEvent, 1, 1000);
-// -> calls this->cXinelibDevice::TimerEvent(1) every second until stopped.
-// Cancel timer:
-// - if handler returns bool: return false from handler
-// - handler is type of void: timer runs only once
-// - call cTimerEvent::Cancel(event)
-// Cancel all timers for object:
-// - Call CancelTimerEvents(object)
-// - Call CancelTimerEvents(this)
-
-
-#endif // __XINELIBOUTPUT_TIMER_H
-
-
diff --git a/tools/ts.c b/tools/ts.c
deleted file mode 100644
index 3177bf5f..00000000
--- a/tools/ts.c
+++ /dev/null
@@ -1,694 +0,0 @@
-/*
- * ts.c: MPEG-TS
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: ts.c,v 1.11 2009-07-03 05:37:05 phintuka Exp $
- *
- */
-
-/*#define LOG_PCR*/
-/*#define LOG_PMT*/
-
-#include <inttypes.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef LOG_MODULENAME
-# define LOG_MODULENAME "[mpeg-ts ] "
-# define SysLogLevel iSysLogLevel
-# include "../logdefs.h"
-#endif
-
-#include "mpeg.h"
-#include "ts.h"
-#include "pes.h"
-
-#ifdef LOG_PMT
-# define LOGPMT LOGMSG
-#else
-# define LOGPMT(x...)
-#endif
-
-#ifdef LOG_PCR
-# define LOGPCR LOGMSG
-#else
-# define LOGPCR(x...)
-#endif
-
-
-/*
- * ts_compute_crc32()
- *
- * taken from xine-lib demux_ts.c
- */
-static uint32_t ts_compute_crc32(const uint8_t *data, uint32_t length, uint32_t crc32)
-{
- static uint32_t crc32_table[256];
- static uint init_done = 0;
-
- if (!init_done) {
- uint32_t i, j, k;
- init_done = 1;
- for (i = 0 ; i < 256 ; i++) {
- k = 0;
- for (j = (i << 24) | 0x800000 ; j != 0x80000000 ; j <<= 1)
- k = (k << 1) ^ (((k ^ j) & 0x80000000) ? 0x04c11db7 : 0);
- crc32_table[i] = k;
- }
- }
-
- uint32_t i;
- for(i = 0; i < length; i++)
- crc32 = (crc32 << 8) ^ crc32_table[(crc32 >> 24) ^ data[i]];
-
- return crc32;
-}
-
-/*
- * parse_pat()
- *
- * - parse PAT for PMT pid and program number
- *
- * modified from xine-lib demux_ts.c
- */
-int ts_parse_pat(pat_data_t *pat, const uint8_t *pkt)
-{
- const uint8_t *original_pkt = pkt;
-
- if (! ts_PAYLOAD_START(pkt)) {
- LOGMSG ("parse_pat: PAT without payload unit start indicator");
- return 0;
- }
-
- /* jump to payload */
- pkt += pkt[4]; /* pointer */
- if (pkt - original_pkt > TS_SIZE) {
- LOGMSG("parse_pat: PAT with invalid pointer");
- return 0;
- }
-
- uint section_syntax_indicator = ((pkt[6] >> 7) & 0x01) ;
- uint section_length = ((pkt[6] & 0x03) << 8) | pkt[7];
-/*uint transport_stream_id = (pkt[8] << 8) | pkt[9];*/
-/*uint version_number = (pkt[10] >> 1) & 0x1f;*/
- uint current_next_indicator = pkt[10] & 0x01;
- uint section_number = pkt[11];
- uint last_section_number = pkt[12];
- uint32_t crc32, calc_crc32;
-
- crc32 = pkt[section_length + 4] << 24;
- crc32 |= pkt[section_length + 5] << 16;
- crc32 |= pkt[section_length + 6] << 8;
- crc32 |= pkt[section_length + 7] ;
-
- if ((section_syntax_indicator != 1) || !(current_next_indicator)) {
- LOGMSG("parse_pat: ssi error");
- return 0;
- }
-
- if (pkt - original_pkt > TS_SIZE - 4 - 1 - 3 - (int)section_length) {
- LOGMSG("parse_pat: unsupported PAT does not fit to single TS packet");
- return 0;
- }
-
- if ((section_number != 0) || (last_section_number != 0)) {
- LOGMSG("parse_pat: unsoupported PAT consists of multiple (%d) sections", last_section_number);
- return 0;
- }
-
- /* Check CRC */
- calc_crc32 = ts_compute_crc32 (pkt + 5, section_length + 3 - 4, 0xffffffff);
- if (crc32 != calc_crc32) {
- LOGMSG("parse_pat: invalid CRC");
- return 0;
- }
-
- /*
- * Process all programs in the program loop
- */
-
- const uint8_t *program;
- uint program_count;
-
- program_count = 0;
- for (program = pkt + 13;
- program < pkt + 13 + section_length - 9;
- program += 4) {
- uint program_number = (program[0] << 8) | program[1];
- uint pmt_pid = ((program[2] & 0x1f) << 8) | program[3];
-
- /* skip NIT pids */
- if (program_number == 0x0000)
- continue;
-
- pat->program_number[program_count] = program_number;
- pat->pmt_pid[program_count] = pmt_pid;
-
- LOGDBG("PAT acquired count=%d programNumber=0x%04x pmtPid=0x%04x",
- program_count,
- pat->program_number[program_count],
- pat->pmt_pid[program_count]);
-
- program_count++;
- }
-
- pat->program_number[program_count] = 0;
-
- return program_count;
-}
-
-/*
- * ts_get_reg_desc()
- *
- * Find the registration code (tag=5) and return it as a uint32_t
- * This should return "AC-3" or 0x41432d33 for AC3/A52 audio tracks.
- *
- * taken from xine-lib demux_ts.c
- */
-static void ts_get_reg_desc(uint32_t *dest, const uint8_t *data, int length)
-{
- const unsigned char *d = data;
-
- while (d < (data + length)) {
- if (d[0] == 5 && d[1] >= 4) {
- *dest = (d[2] << 24) | (d[3] << 16) | (d[4] << 8) | d[5];
- LOGPMT("parse_pmt: found registration format identifier 0x%.4x", *dest);
- return;
- }
- d += 2 + d[1];
- }
- LOGPMT("pare_pmt: found no format id");
- *dest = 0;
-}
-
-/*
- * ts_parse_pmt()
- *
- * modified from xine-lib demux_ts.c
- */
-int ts_parse_pmt (pmt_data_t *pmt, uint program_no, const uint8_t *pkt)
-{
- const uint8_t *originalPkt = pkt;
- const uint8_t *ptr = NULL;
- uint pusi = ts_PAYLOAD_START(pkt);
-
- uint32_t section_syntax_indicator;
- uint32_t section_length = 0; /* to calm down gcc */
- uint32_t program_number;
- uint32_t version_number;
- uint32_t current_next_indicator;
- uint32_t section_number;
- uint32_t last_section_number;
- uint32_t program_info_length;
- uint32_t crc32;
- uint32_t calc_crc32;
- uint32_t coded_length;
- uint pid;
- uint8_t *stream;
- uint i;
- int count;
- uint8_t len;
- uint offset = 0;
-
- /*
- * A new section should start with the payload unit start
- * indicator set. We allocate some mem (max. allowed for a PM section)
- * to copy the complete section into one chunk.
- */
- if (pusi) {
- pkt += pkt[4]; /* pointer */
- offset = 1;
-
- if (pmt->pmt != NULL)
- free(pmt->pmt);
- pmt->pmt = (uint8_t *) calloc(4096, sizeof(uint8_t));
- pmt->pmt_write_ptr = pmt->pmt;
-
- section_syntax_indicator = (pkt[6] >> 7) & 0x01;
- section_length = ((pkt[6] << 8) | pkt[7]) & 0x03ff;
- program_number = (pkt[8] << 8) | pkt[9];
- version_number = (pkt[10] >> 1) & 0x1f;
- current_next_indicator = pkt[10] & 0x01;
- section_number = pkt[11];
- last_section_number = pkt[12];
-
- LOGPMT("PMT: section_syntax: %d", section_syntax_indicator);
- LOGPMT(" section_length: %d", section_length);
- LOGPMT(" program_number: %#.4x", program_number);
- LOGPMT(" version_number: %d", version_number);
- LOGPMT(" c/n indicator: %d", current_next_indicator);
- LOGPMT(" section_number: %d", section_number);
- LOGPMT(" last_section_number: %d", last_section_number);
-
- if ((section_syntax_indicator != 1) || !current_next_indicator) {
- LOGMSG("parse_pmt: ssi error");
- return 0;
- }
-
- if (program_number != program_no) {
- /* several programs can share the same PMT pid */
- LOGMSG("parse_pmt: program number %i, looking for %i", program_number, program_no);
- return 0;
- }
-
- if ((section_number != 0) || (last_section_number != 0)) {
- LOGMSG("parse_pmt: unsupported PMT (%d sections)", last_section_number);
- return 0;
- }
- }
-
- if (!pusi) {
- section_length = (pmt->pmt[1] << 8 | pmt->pmt[2]) & 0x03ff;
- version_number = (pkt[10] >> 1) & 0x1f;
- }
-
- count = ts_PAYLOAD_SIZE(originalPkt);
-
- ptr = originalPkt + offset + (TS_SIZE - count);
- len = count - offset;
- memcpy(pmt->pmt_write_ptr, ptr, len);
- pmt->pmt_write_ptr += len;
-
- if (pmt->pmt_write_ptr < pmt->pmt + section_length) {
- LOGPMT("parse_pmt: didn't get all PMT TS packets yet...");
- return 0;
- }
-
- if (!section_length) {
- free(pmt->pmt);
- pmt->pmt = NULL;
- LOGMSG("parse_pmt: zero-length section");
- return 0;
- }
-
- LOGPMT("parse_pmt: have all TS packets for the PMT section");
-
- crc32 = (uint32_t) pmt->pmt[section_length+3-4] << 24;
- crc32 |= (uint32_t) pmt->pmt[section_length+3-3] << 16;
- crc32 |= (uint32_t) pmt->pmt[section_length+3-2] << 8;
- crc32 |= (uint32_t) pmt->pmt[section_length+3-1] ;
-
- /* Check CRC. */
- calc_crc32 = ts_compute_crc32 (pmt->pmt, section_length + 3 - 4, 0xffffffff);
- if (crc32 != calc_crc32) {
- LOGMSG("parse_pmt: invalid CRC32");
- return 0;
- }
-
- if (crc32 == pmt->crc32 && version_number == pmt->version_number) {
- LOGPMT("parse_pmt: PMT with CRC32=%d already parsed. Skipping.", crc32);
- return 0;
- }
-
- LOGPMT("parse_pmt: new PMT, parsing...");
- pmt->crc32 = crc32;
- pmt->version_number = version_number;
-
- /* reset PIDs */
- pmt->audio_tracks_count = 0;
- pmt->spu_tracks_count = 0;
- pmt->video_pid = INVALID_PID;
-
- /* ES definitions start here */
- program_info_length = ((pmt->pmt[10] << 8) | pmt->pmt[11]) & 0x0fff;
-
- stream = &pmt->pmt[12] + program_info_length;
- coded_length = 13 + program_info_length;
- if (coded_length > section_length) {
- LOGMSG("parse_pmt: PMT with inconsistent progInfo length");
- return 0;
- }
- section_length -= coded_length;
-
-
- /*
- * Extract the elementary streams.
- */
- while (section_length > 0) {
- unsigned int stream_info_length;
-
- pid = ((stream[1] << 8) | stream[2]) & 0x1fff;
- stream_info_length = ((stream[3] << 8) | stream[4]) & 0x0fff;
- coded_length = 5 + stream_info_length;
- if (coded_length > section_length) {
- LOGMSG("parse_pmt: PMT with inconsistent streamInfo length");
- return 0;
- }
-
- switch (stream[0]) {
- case ISO_11172_VIDEO:
- case ISO_13818_VIDEO:
- case ISO_14496_PART2_VIDEO:
- case ISO_14496_PART10_VIDEO:
- LOGPMT("parse_pmt: video pid 0x%.4x type %2.2x", pid, stream[0]);
- if (pmt->video_pid == INVALID_PID) {
- pmt->video_pid = pid;
- pmt->video_type = (ts_stream_type)stream[0];
- }
- break;
-
- case ISO_11172_AUDIO:
- case ISO_13818_AUDIO:
- case ISO_13818_PART7_AUDIO:
- case ISO_14496_PART3_AUDIO:
- if (pmt->audio_tracks_count < TS_MAX_AUDIO_TRACKS) {
- int i, found = 0;
- for (i = 0; i < pmt->audio_tracks_count; i++) {
- if (pmt->audio_tracks[i].pid == pid) {
- found = 1;
- break;
- }
- }
- if (!found) {
- LOGPMT("parse_pmt: audio pid 0x%.4x type %2.2x", pid, stream[0]);
- pmt->audio_tracks[pmt->audio_tracks_count].pid = pid;
- pmt->audio_tracks[pmt->audio_tracks_count].type = (ts_stream_type)stream[0];
- /* ts_get_lang_desc(pmt->audio_tracks[pmt->audio_tracks_count].lang, */
- /* stream + 5, stream_info_length); */
- pmt->audio_tracks_count++;
- }
- }
- break;
-
- case ISO_13818_PRIVATE:
- case ISO_13818_TYPE_C:
- break;
-
- case ISO_13818_PES_PRIVATE:
- for (i = 5; i < coded_length; i += stream[i+1] + 2) {
- if ((stream[i] == 0x6a) && (pmt->audio_tracks_count < TS_MAX_AUDIO_TRACKS)) {
- int i, found = 0;
- for (i = 0; i < pmt->audio_tracks_count; i++) {
- if (pmt->audio_tracks[i].pid == pid) {
- found = 1;
- break;
- }
- }
- if (!found) {
- LOGPMT("parse_pmt: AC3 audio pid 0x%.4x type %2.2x", pid, stream[0]);
- pmt->audio_tracks[pmt->audio_tracks_count].pid = pid;
- pmt->audio_tracks[pmt->audio_tracks_count].type = (ts_stream_type)stream[0];
- /* demux_ts_get_lang_desc(pmt->audio_tracks[pmt->audio_tracks_count].lang, */
- /* stream + 5, stream_info_length); */
- pmt->audio_tracks_count++;
- break;
- }
- }
- /* DVBSUB */
- else if (stream[i] == 0x59) {
- uint pos;
- for (pos = i + 2;
- pos + 8 <= i + 2 + stream[i + 1]
- && pmt->spu_tracks_count < TS_MAX_SPU_TRACKS;
- pos += 8) {
- int no = pmt->spu_tracks_count;
-
- pmt->spu_tracks_count++;
-
- memcpy(pmt->spu_tracks[no].lang, &stream[pos], 3);
- pmt->spu_tracks[no].lang[3] = 0;
- pmt->spu_tracks[no].comp_page_id = (stream[pos + 4] << 8) | stream[pos + 5];
- pmt->spu_tracks[no].aux_page_id = (stream[pos + 6] << 8) | stream[pos + 7];
- pmt->spu_tracks[no].pid = pid;
-
- LOGPMT("parse_pmt: DVBSUB pid 0x%.4x: %s page %d %d type %2.2x", pid,
- pmt->spu_tracks[no].lang, pmt->spu_tracks[no].comp_page_id,
- pmt->spu_tracks[no].aux_page_id, stream[0]);
- }
- }
- }
- break;
-
- default:
-
- /* This following section handles all the cases where the audio track info is stored
- * in PMT user info with stream id >= 0x80
- * We first check that the stream id >= 0x80, because all values below that are
- * invalid if not handled above, then we check the registration format identifier
- * to see if it holds "AC-3" (0x41432d33) and if is does, we tag this as an audio stream.
- */
- if ((pmt->audio_tracks_count < TS_MAX_AUDIO_TRACKS) && (stream[0] >= 0x80) ) {
- int i, found = 0;
- for (i = 0; i < pmt->audio_tracks_count; i++) {
- if (pmt->audio_tracks[i].pid == pid) {
- found = 1;
- break;
- }
- }
- if (!found) {
- uint32_t format_identifier = 0;
- ts_get_reg_desc(&format_identifier, stream + 5, stream_info_length);
- /* If no format identifier, assume A52 */
- if ((format_identifier == 0x41432d33) || (format_identifier == 0)) {
- pmt->audio_tracks[pmt->audio_tracks_count].pid = pid;
- pmt->audio_tracks[pmt->audio_tracks_count].type = (ts_stream_type)stream[0];
- /* ts_get_lang_desc(pmt->audio_tracks[pmt->audio_tracks_count].lang, */
- /* stream + 5, stream_info_length); */
- pmt->audio_tracks_count++;
- break;
- }
- }
- } else {
- LOGPMT("parse_pmt: unknown stream_type: 0x%.2x pid: 0x%.4x", stream[0], pid);
- }
- break;
- }
- stream += coded_length;
- section_length -= coded_length;
- }
-
-
- /*
- * Get the current PCR PID.
- */
- pid = ((pmt->pmt[8] << 8) | pmt->pmt[9]) & 0x1fff;
- if (pmt->pcr_pid != pid) {
-
- if (pmt->pcr_pid == INVALID_PID)
- LOGPMT("parse_pmt: pcr pid 0x%.4x", pid);
- else
- LOGPMT("parse_pmt: pcr pid changed 0x%.4x", pid);
-
- pmt->pcr_pid = pid;
- }
-
- return 1;
-}
-
-/*
- * ts_get_pcr()
- */
-static int ts_get_pcr_1(const uint8_t *pkt, int64_t *ppcr)
-{
- if (!ts_ADAPT_FIELD_EXISTS(pkt)) {
- return 0;
- }
-
- if (ts_HAS_ERROR(pkt)) {
- LOGMSG("ts_get_pcr: transport error");
- return 0;
- }
-
- /* pcr flag ? */
- if (! (pkt[5] & 0x10))
- return 0;
-
- int64_t pcr;
- uint epcr;
-
- pcr = ((int64_t) pkt[6]) << 25;
- pcr += (int64_t) (pkt[7] << 17);
- pcr += (int64_t) (pkt[8] << 9);
- pcr += (int64_t) (pkt[9] << 1);
- pcr += (int64_t) ((pkt[10] & 0x80) >> 7);
-
- epcr = ((pkt[10] & 0x1) << 8) | pkt[11];
-
- LOGPCR("ts_get_pcr: PCR: %"PRId64", EPCR: %u", pcr, epcr);
- *ppcr = pcr;
- return 1;
-}
-
-int64_t ts_get_pcr(const uint8_t *pkt)
-{
- int64_t pcr = NO_PTS;
- ts_get_pcr_1(pkt, &pcr);
- return pcr;
-}
-
-int ts_get_pcr_n(const uint8_t *pkt, int npkt, int64_t *pcr)
-{
- pkt += TS_SIZE * npkt;
- while (npkt > 0) {
- npkt--;
- pkt -= TS_SIZE;
- if (ts_get_pcr_1(pkt, pcr))
- return 1;
- }
- return 0;
-}
-
-
-/*
- * ts_state_t
- */
-
-struct ts_state_s {
-
- uint8_t pusi_seen;
-
- uint8_t inside_pes; /* Scanning ES (PES start code seen and skipped) */
-
- uint32_t buf_len; /* bytes queued */
- uint32_t buf_size; /* buffer size */
- uint8_t buf[0]; /* payload: partial PES / video stream header etc. */
-};
-
-ts_state_t *ts_state_init(int buffer_size)
-{
- if (buffer_size < 8 * TS_SIZE)
- buffer_size = 8 * TS_SIZE;
-
- ts_state_t *ts = (ts_state_t*)calloc(1, sizeof(ts_state_t) + buffer_size);
- ts->buf_size = buffer_size;
- return ts;
-}
-
-void ts_state_reset(ts_state_t *ts)
-{
- int buf_size = ts->buf_size;
- memset(ts, 0, sizeof(ts_state_t));
- ts->buf_size = buf_size;
-}
-
-void ts_state_dispose(ts_state_t *ts)
-{
- free(ts);
-}
-
-/*
- * ts_add_payload()
- *
- * Add TS packet payload to buffer.
- * - PUSI resets the buffer
- * - all data before first PUSI is discarded
- */
-static int ts_add_payload(ts_state_t *ts, const uint8_t *data)
-{
- /* start from PUSI */
- if (!ts->pusi_seen) {
- if (!ts_PAYLOAD_START(data))
- return 0;
- ts->pusi_seen = 1;
- ts->buf_len = 0;
- }
-
- if (ts->buf_len >= ts->buf_size - TS_SIZE) {
- LOGMSG("ts_add_payload: buffer full");
- ts->buf_len -= TS_SIZE;
- memcpy(ts->buf, ts->buf+TS_SIZE, ts->buf_len);
- }
-
- int len = ts_PAYLOAD_SIZE(data);
- if (len > 0) {
- memcpy(ts->buf + ts->buf_len, ts_GET_PAYLOAD(data), len);
- ts->buf_len += len;
- }
-
- return ts->buf_len;
-}
-
-/*
- * ts_skip_payload()
- */
-static void ts_skip_payload(ts_state_t *ts, unsigned int n)
-{
- if (n < ts->buf_len) {
- ts->buf_len -= n;
- memcpy(ts->buf, ts->buf + n, ts->buf_len);
- } else {
- ts->buf_len = 0;
- }
-}
-
-/*
- * ts_scan_startcode()
- *
- * - discard all data until startcode (00 00 01) is found
- * - returns number of bytes left
- */
-static int ts_scan_startcode(ts_state_t *ts)
-{
- if (ts->buf_len > 2) {
- /* scan for PES or MPEG 00 00 01 */
- unsigned int i = 0, n = ts->buf_len - 2;
- while (i < n) {
- if (ts->buf[i+2] != 1)
- i += 3;
- else if(ts->buf[i+1])
- i += 2;
- else if(ts->buf[i])
- i++;
- else
- break;
- }
-
- /* skip data until start code */
- ts_skip_payload(ts, i);
- }
-
- return ts->buf_len;
-}
-
-/*
- * ts_get_pes()
- *
- * - scan for PES start
- * - return (PES) bytes queued
- */
-static int ts_get_pes(ts_state_t *ts, const uint8_t *data)
-{
- if (ts_add_payload(ts, data) > 0)
- return ts_scan_startcode(ts);
- return 0;
-}
-
-/*
- * ts_get_pts()
- */
-
-int64_t ts_get_pts(ts_state_t *ts, const uint8_t *data)
-{
- int64_t pts = NO_PTS;
- int cnt = ts_get_pes(ts, data);
-
- if (cnt > 14) {
- pts = pes_get_pts(ts->buf, ts->buf_len);
-
- if (pts < 0 && cnt > 2*TS_SIZE)
- ts_state_reset(ts);
- }
-
- return pts;
-}
-
-/*
- * ts_get_picture_type()
- */
-
-int ts_get_picture_type(ts_state_t *ts, const uint8_t *data, int h264)
-{
- int pic = NO_PICTURE;
- return pic;
-}
-
-/*
- * ts_get_video_size()
- */
-
-int ts_get_video_size(ts_state_t *ts, const uint8_t *data, video_size_t *size, int h264)
-{
- return 0;
-}
diff --git a/tools/ts.h b/tools/ts.h
deleted file mode 100644
index ca5ec516..00000000
--- a/tools/ts.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * ts.h: MPEG-TS header definitions
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: ts.h,v 1.11 2009-07-03 05:37:05 phintuka Exp $
- *
- */
-
-#ifndef _XINELIBOUTPUT_TS_H_
-#define _XINELIBOUTPUT_TS_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* Avoid warnings when included to VDR plugin */
-#undef TS_SYNC_BYTE
-#undef TS_SIZE
-#undef TS_PAYLOAD_EXISTS
-#undef TS_ADAPT_FIELD_EXISTS
-#undef TS_PAYLOAD_START
-#undef TS_ERROR
-#undef TS_PID_MASK_HI
-
-/*
- * Constants
- */
-
-#define TS_SYNC_BYTE 0x47
-#define TS_SIZE 188
-#define TS_ADAPT_FIELD_EXISTS 0x20
-#define TS_PAYLOAD_EXISTS 0x10
-#define TS_PAYLOAD_START 0x40
-#define TS_ERROR 0x80
-#define TS_PID_MASK_HI 0x1F
-
-#define ts_HAS_PAYLOAD(ts) ((ts)[3] & TS_PAYLOAD_EXISTS)
-#define ts_PAYLOAD_START(ts) ((ts)[1] & TS_PAYLOAD_START)
-#define ts_HAS_ERROR(ts) ((ts)[1] & TS_ERROR)
-#define ts_PID(ts) ((((ts)[1] & TS_PID_MASK_HI) << 8) + (ts)[2])
-#define ts_PAYLOAD_OFFSET(ts) (((ts)[3] & TS_ADAPT_FIELD_EXISTS) ? (ts)[4] + 5 : 4)
-
-#define ts_GET_PAYLOAD(ts) ((ts) + ts_PAYLOAD_OFFSET(ts))
-#define ts_PAYLOAD_SIZE(ts) (TS_SIZE - ts_PAYLOAD_OFFSET(ts))
-
-#define ts_ADAPT_FIELD_EXISTS(ts) ((ts)[3] & TS_ADAPT_FIELD_EXISTS)
-#define ts_ADAPT_FIELD_LENGTH(ts) (ts_ADAPT_FIELD_EXISTS(ts) ? (ts)[4] : 0)
-
-
-#define DATA_IS_TS(data) ((data)[0] == TS_SYNC_BYTE)
-
-
-typedef enum {
- ISO_11172_VIDEO = 0x01, /* ISO/IEC 11172 Video */
- ISO_13818_VIDEO = 0x02, /* ISO/IEC 13818-2 Video */
- ISO_11172_AUDIO = 0x03, /* ISO/IEC 11172 Audio */
- ISO_13818_AUDIO = 0x04, /* ISO/IEC 13818-3 Audi */
- ISO_13818_PRIVATE = 0x05, /* ISO/IEC 13818-1 private sections */
- ISO_13818_PES_PRIVATE = 0x06, /* ISO/IEC 13818-1 PES packets containing private data */
- ISO_13522_MHEG = 0x07, /* ISO/IEC 13512 MHEG */
- ISO_13818_DSMCC = 0x08, /* ISO/IEC 13818-1 Annex A DSM CC */
- ISO_13818_TYPE_A = 0x0a, /* ISO/IEC 13818-6 Multiprotocol encapsulation */
- ISO_13818_TYPE_B = 0x0b, /* ISO/IEC 13818-6 DSM-CC U-N Messages */
- ISO_13818_TYPE_C = 0x0c, /* ISO/IEC 13818-6 Stream Descriptors */
- ISO_13818_TYPE_D = 0x0d, /* ISO/IEC 13818-6 Sections (any type, including private data) */
- ISO_13818_AUX = 0x0e, /* ISO/IEC 13818-1 auxiliary */
- ISO_13818_PART7_AUDIO = 0x0f, /* ISO/IEC 13818-7 Audio with ADTS transport sytax */
- ISO_14496_PART2_VIDEO = 0x10, /* ISO/IEC 14496-2 Visual (MPEG-4) */
- ISO_14496_PART3_AUDIO = 0x11, /* ISO/IEC 14496-3 Audio with LATM transport syntax */
- ISO_14496_PART10_VIDEO = 0x1b, /* ISO/IEC 14496-10 Video (MPEG-4 part 10/AVC, aka H.264) */
- STREAM_VIDEO_MPEG = 0x80,
- STREAM_AUDIO_AC3 = 0x81,
- STREAM_DVBSUB = 0x100
-} ts_stream_type;
-
-
-/*
- * PAT
- */
-
-#define TS_MAX_PROGRAMS 64
-#define TS_MAX_PMTS 32
-#define TS_MAX_AUDIO_TRACKS 32
-#define TS_MAX_SPU_TRACKS 32
-
-typedef struct {
- int program_number[TS_MAX_PROGRAMS];
- uint16_t pmt_pid[TS_MAX_PROGRAMS];
-} pat_data_t;
-
-int ts_parse_pat(pat_data_t *pat_data, const uint8_t *ts_data);
-
-
-/*
- * PMT
- */
-
-#define INVALID_PID 0xffff
-
-typedef struct {
- uint8_t *pmt; /* raw data */
- uint8_t *pmt_write_ptr;
-
- uint32_t crc32;
- uint version_number;
-
- uint16_t pcr_pid;
- uint16_t video_pid;
- ts_stream_type video_type;
-
- uint8_t audio_tracks_count;
- uint8_t spu_tracks_count;
-
- struct {
- uint16_t pid;
- ts_stream_type type;
- /*uint8_t lang[8];*/
- } audio_tracks[TS_MAX_AUDIO_TRACKS];
-
- struct {
- uint16_t pid;
- uint8_t lang[8];
- uint16_t comp_page_id;
- uint16_t aux_page_id;
- } spu_tracks[TS_MAX_SPU_TRACKS];
-
-} pmt_data_t;
-
-/*
- * parse_pmt()
- *
- * returns 1 : PMT parsed and changed
- * 0 : error or unchanged pmt
- */
-int ts_parse_pmt(pmt_data_t *pmt, uint program_no, const uint8_t *ts_data);
-
-/*
- * PCR
- */
-
-int64_t ts_get_pcr(const uint8_t *data);
-int ts_get_pcr_n(const uint8_t *pkt, int npkt, int64_t *pcr);
-
-/*
- * TS->ES, simple ES parsers
- */
-
-typedef struct ts_state_s ts_state_t;
-struct video_size_s;
-
-ts_state_t *ts_state_init(int buffer_size);
-void ts_state_reset(ts_state_t *ts);
-void ts_state_dispose(ts_state_t *ts);
-
-int64_t ts_get_pts(ts_state_t *ts, const uint8_t *data);
-int ts_get_picture_type(ts_state_t *ts, const uint8_t *data, int h264);
-int ts_get_video_size(ts_state_t *ts, const uint8_t *data, struct video_size_s *size, int h264);
-
-
-#ifdef __cplusplus
-} /* extern "C" { */
-#endif
-
-#endif // _XINELIBOUTPUT_TS_H_
diff --git a/tools/udp_buffer.h b/tools/udp_buffer.h
deleted file mode 100644
index 6044b794..00000000
--- a/tools/udp_buffer.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * udp_buffer.h: Ring buffer for UDP/RTP streams
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: udp_buffer.h,v 1.6 2009-03-24 19:35:23 phintuka Exp $
- *
- */
-
-#ifndef __UDP_BUFFER_H
-#define __UDP_BUFFER_H
-
-#include <stdint.h>
-
-#include <vdr/config.h> // VDRVERSNUM
-
-#include "../xine_input_vdr_net.h" // frame headers
-#include "ts.h"
-
-#define UDP_BUFFER_SIZE 0x100 // 2^n
-#define UDP_BUFFER_MASK 0xff // 2^n - 1
-
-#if UDP_BUFFER_MASK != UDP_SEQ_MASK
-# error Buffer handling error !!!
-#endif
-
-
-class cUdpBackLog
-{
- friend class cUdpScheduler;
-
- private:
-
- cUdpBackLog(cUdpBackLog&);
-
- stream_rtp_header_impl_t *m_UdpBuffer[UDP_BUFFER_SIZE];
- int m_UdpBufLen[UDP_BUFFER_SIZE]; /* size of allocated memory, not frame */
- int m_PayloadSize[UDP_BUFFER_SIZE]; /* size of frame */
- unsigned int m_SeqNo; /* next (outgoing) sequence number */
- unsigned int m_RtpSeqNo; /* next (outgoing) RTP sequence number */
-
- protected:
-
- cUdpBackLog()
- {
- memset(m_UdpBuffer, 0, sizeof(stream_rtp_header_impl_t *)*UDP_BUFFER_SIZE);
- memset(m_UdpBufLen, 0, sizeof(int) * UDP_BUFFER_SIZE);
- memset(m_PayloadSize, 0, sizeof(int) * UDP_BUFFER_SIZE);
- m_SeqNo = 0;
- m_RtpSeqNo = random();
- }
-
- void Clear(int HowManyFrames)
- {
- // Clear n last frames from buffer.
- // (called to adjust sequence numbering when some
- // already allocated frames won't be sent)
- //
- // Note: Nothing is freed.
- // To completely reset buffer it must be deleted and re-created.
- //
- m_SeqNo = (m_SeqNo + UDP_BUFFER_SIZE - HowManyFrames) & UDP_BUFFER_MASK;
- }
-
- virtual ~cUdpBackLog()
- {
- for(int i=0; i<UDP_BUFFER_SIZE; i++)
- if(m_UdpBuffer[i]) {
- //m_UdpBufLen[i] = 0;
- delete[] m_UdpBuffer[i];
- m_UdpBuffer[i] = NULL;
- }
- }
-
- stream_rtp_header_impl_t *Get(int UdpSeqNo)
- {
- int BufIndex = UdpSeqNo & UDP_BUFFER_MASK;
- return m_UdpBuffer[BufIndex];
- }
-
- int PayloadSize(int UdpSeqNo)
- {
- int BufIndex = UdpSeqNo & UDP_BUFFER_MASK;
- return m_UdpBuffer[BufIndex] ? m_PayloadSize[BufIndex] : 0;
- }
-
- stream_rtp_header_impl_t *MakeFrame(uint64_t StreamPos,
- const uchar *Data, int DataLen)
- {
- int UdpPacketLen = DataLen + sizeof(stream_rtp_header_impl_t);
- int BufIndex = m_SeqNo & UDP_BUFFER_MASK;
-
- // old buffer too small ? free it
- if(m_UdpBuffer[BufIndex] && m_UdpBufLen[BufIndex] < UdpPacketLen) {
- delete[] m_UdpBuffer[BufIndex];
- m_UdpBuffer[BufIndex] = NULL;
- }
-
- // no buffer ? alloc it
- if(!m_UdpBuffer[BufIndex]) {
- m_UdpBuffer[BufIndex] = (stream_rtp_header_impl_t*)new uchar[UdpPacketLen];
- m_UdpBufLen[BufIndex] = UdpPacketLen;
- }
- m_PayloadSize[BufIndex] = DataLen;
-
- // Fill frame to buffer
- stream_rtp_header_impl_t *header = m_UdpBuffer[BufIndex];
-
- memcpy(header->payload, Data, DataLen);
-
- // RTP header
- header->rtp_hdr.raw[0] = RTP_VERSION_BYTE | RTP_HDREXT_BIT;
-#if VDRVERSNUM >= 10701
- if (DATA_IS_TS(Data))
- header->rtp_hdr.raw[1] = RTP_PAYLOAD_TYPE_TS;
- else
- header->rtp_hdr.raw[1] = RTP_PAYLOAD_TYPE_PES;
-#else
- header->rtp_hdr.raw[1] = RTP_PAYLOAD_TYPE_PES;
-#endif
- header->rtp_hdr.seq = htons(m_RtpSeqNo & 0xFFFF);
- /*header->rtp_hdr.ts = htonl((uint32_t)(RtpScr.Now() & 0xffffffff));*/
- /*header->rtp_hdr.ssrc = htonl(m_ssrc);*/
-
- // RTP header extension
- header->hdr_ext.hdr.size = htons(RTP_HEADER_EXT_X_SIZE);
- header->hdr_ext.hdr.type = htons(RTP_HEADER_EXT_X_TYPE);
-
- // UDP header
- header->hdr_ext.pos = htonull(StreamPos);
- header->hdr_ext.seq = htons(m_SeqNo);
-
- header->hdr_ext.padding1 = 0;
-
- m_RtpSeqNo = (m_RtpSeqNo + 1) & 0xFFFF;
- m_SeqNo = (m_SeqNo + 1) & UDP_SEQ_MASK;
-
- return header;
- }
-};
-
-
-#endif
diff --git a/tools/udp_pes_scheduler.c b/tools/udp_pes_scheduler.c
deleted file mode 100644
index 0de6997e..00000000
--- a/tools/udp_pes_scheduler.c
+++ /dev/null
@@ -1,945 +0,0 @@
-/*
- * udp_pes_scheduler.h: PES scheduler for UDP/RTP streams
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: udp_pes_scheduler.c,v 1.46 2009-07-02 10:38:29 phintuka Exp $
- *
- */
-
-//#define LOG_UDP_RATE
-//#define LOG_RESEND
-//#define LOG_SCR
-
-#define __STDC_FORMAT_MACROS
-#define __STDC_CONSTANT_MACROS
-#include <inttypes.h>
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-
-#include <vdr/config.h>
-#include <vdr/tools.h>
-#include <vdr/videodir.h>
-
-#include "../logdefs.h" // logging
-#include "../config.h" // configuration data
-#include "../xine_input_vdr_net.h" // frame headers and constants
-
-#include "pes.h"
-#include "udp_buffer.h"
-#include "udp_pes_scheduler.h"
-#include "time_pts.h"
-#include "cxsocket.h"
-#include "sap.h" // SAP - Session Announcement Protocol
-#include "sdp.h" // SDP - Session Description Protocol
-#include "rtcp.h" // RTCP
-
-
-#ifdef LOG_RESEND
-# define LOGRESEND LOGDBG
-#else
-# define LOGRESEND(x...)
-#endif
-
-#ifdef LOG_SCR
-# define LOGSCR LOGDBG
-#else
-# define LOGSCR(x...)
-#endif
-
-/*
- * constants
- */
-
-const uint MAX_QUEUE_SIZE = 64; // ~ 65 ms with typical DVB stream
-const uint MAX_LIVE_QUEUE_SIZE = (64+60); // ~ 100 ms with typical DVB stream
-const uint HARD_LIMIT = (4*1024); // ~ 40 Mbit/s === 4 Mb/s
-
-const uint MAX_BURST_BYTES = 32768; // 32 kb
-const uint MAX_BURST_FRAMES = 15; // 15 UDP packets
-
-const uint RTCP_MIN_INTERVAL = 45000; // 500 ms (pts units)
-
-// initial burst length after seek (500ms = ~13 video frames)
-const int64_t INITIAL_BURST_TIME = INT64_C(45000); // pts units (90kHz)
-
-// assume seek when when pts difference between two frames exceeds this (2,5 seconds)
-const int64_t JUMP_LIMIT_TIME = INT64_C(225000); // pts units (90kHz)
-
-const uint SCHEDULER_MIN_DELAY_MS = 3;
-const uint SCHEDULER_MAX_DELAY_MS = 20;
-
-
-typedef enum {
- eScrDetect,
- eScrFromAudio,
- eScrFromPS1,
- eScrFromVideo
-} ScrSource_t;
-
-
-cUdpScheduler::cUdpScheduler()
-{
-
- // Scheduler data
-
- m_CurrentAudioVtime = 0;
- m_CurrentVideoVtime = 0;
- m_MasterClock.Set(INT64_C(0));
-
- m_BurstBytes = 0;
- m_BurstFrames = 0;
-
- m_Master = false;
- m_TrickSpeed = false;
-
- // RTP
-
- srandom(time(NULL) ^ getpid());
-
- m_ssrc = random();
- LOGDBG("RTP SSRC: 0x%08x", m_ssrc);
- m_LastRtcpTime = 0;
- m_Frames = 0;
- m_Octets = 0;
- m_RtpScr.Set((int64_t)random());
-
- m_fd_sap = -1;
-
- // Queuing
-
- int i;
- for(i=0; i<MAX_UDP_HANDLES; i++)
- m_Handles[i] = -1;
-
- m_BackLog = new cUdpBackLog;
-
- m_QueueNextSeq = 0;
- m_QueuePending = 0;
-
- // Thread
-
- Start();
-}
-
-cUdpScheduler::~cUdpScheduler()
-{
- m_Lock.Lock();
-
- Cancel(-1);
- m_Cond.Broadcast();
- m_CondWait.Signal();
- m_Lock.Unlock();
-
- Cancel(3);
-
- if(m_fd_rtcp.open() || m_fd_rtp.open())
- Send_SAP(false);
-
- CLOSESOCKET(m_fd_sap);
-
- delete m_BackLog;
-}
-
-void cUdpScheduler::Scheduler_Sleep(int ms)
-{
- m_CondWait.Wait(ms);
- m_BurstBytes = 0;
- m_BurstFrames = 0;
-}
-
-bool cUdpScheduler::AddRtp(void)
-{
- cMutexLock ml(&m_Lock);
-
- if(m_fd_rtcp.open()) {
- LOGERR("cUdpScheduler::AddHandle: RTCP socket already open !");
- Send_SAP(false);
- m_fd_rtcp.close();
- }
-
- /* need new ssrc */
- m_ssrc = random();
- LOGDBG("RTP SSRC: 0x%08x", m_ssrc);
-
- //
- // RTP
- //
- if(! m_fd_rtp.create(cxSocket::estDGRAM)) {
- LOGERR("socket() failed (UDP/RTP multicast)");
- return false;
- }
-
- // Set buffer sizes
- m_fd_rtp.set_buffers(KILOBYTE(256), 2048);
-
- // Set multicast socket options
- if(!m_fd_rtp.set_multicast(xc.remote_rtp_ttl)) {
- m_fd_rtp.close();
- return false;
- }
-
- if(xc.remote_local_ip[0]) {
- struct sockaddr_in name;
- name.sin_family = AF_INET;
- name.sin_addr.s_addr = inet_addr(xc.remote_local_ip);
- if(name.sin_addr.s_addr == INADDR_NONE)
- LOGERR("Local address %s is invalid", xc.remote_local_ip);
- name.sin_port = htons(xc.remote_rtp_port);
- if (bind(m_fd_rtp.handle(), (struct sockaddr *)&name, sizeof(name)) < 0)
- LOGERR("bind(%s:%d) failed for udp/rtp multicast", xc.remote_local_ip, xc.remote_rtp_port);
-#if 0
- struct ip_mreqn mreqn;
- mreqn.imr_multiaddr.s_addr = inet_addr(xc.remote_rtp_addr);
- mreqn.imr_address.s_addr = inet_addr(xc.remote_local_ip); /* IP address of local interface */
- //mreqn.imr_ifindex = ; /* interface index */
- if(setsockopt(m_fd_rtp.handle(), IPPROTO_IP, IP_MULTICAST_IF, &mreqn, sizeof(mreqn)))
- LOGERR("setting multicast source address/interface failed");
-#endif
- }
-
- // Connect to multicast address
- if(!m_fd_rtp.connect(xc.remote_rtp_addr, xc.remote_rtp_port) &&
- errno != EINPROGRESS) {
- LOGERR("connect(fd_rtp) failed. Address=%s, port=%d",
- xc.remote_rtp_addr, xc.remote_rtp_port);
- m_fd_rtp.close();
- return false;
- }
-
- // Set to non-blocking mode
- m_fd_rtp.set_blocking(false);
-
- //
- // RTCP
- //
- if(! m_fd_rtcp.create(cxSocket::estDGRAM))
- LOGERR("socket() failed (RTCP multicast)");
-
- m_fd_rtcp.set_buffers(16384, 16384);
- if(!m_fd_rtcp.set_multicast(xc.remote_rtp_ttl))
- m_fd_rtcp.close();
-
- if(xc.remote_local_ip[0]) {
- struct sockaddr_in name;
- name.sin_family = AF_INET;
- name.sin_addr.s_addr = inet_addr(xc.remote_local_ip);
- name.sin_port = htons(xc.remote_rtp_port+1);
- if (bind(m_fd_rtcp.handle(), (struct sockaddr *)&name, sizeof(name)) < 0)
- LOGERR("bind(%s:%d) failed for udp/rtp multicast", xc.remote_local_ip, xc.remote_rtp_port);
-#if 0
- struct ip_mreqn mreqn;
- mreqn.imr_multiaddr.s_addr = inet_addr(xc.remote_rtp_addr);
- mreqn.imr_address.s_addr = inet_addr(xc.remote_local_ip); /* IP address of local interface */
- //mreqn.imr_ifindex = ; /* interface index */
- if(setsockopt(m_fd_rtp.handle(), IPPROTO_IP, IP_MULTICAST_IF, &mreqn, sizeof(mreqn)))
- LOGERR("setting multicast source address/interface failed");
-#endif
- }
-
- /* RTCP port (RFC 1889) */
- if(!m_fd_rtcp.connect(xc.remote_rtp_addr, xc.remote_rtp_port + 1) &&
- errno != EINPROGRESS) {
- LOGERR("connect(fd_rtcp) failed. Address=%s, port=%d",
- xc.remote_rtp_addr, xc.remote_rtp_port +
- (xc.remote_rtp_port&1)?-1:1);
- m_fd_rtcp.close();
- }
-
- // Set to non-blocking mode
- m_fd_rtcp.set_blocking(false);
-
- // Finished
-
- if(!AddHandle(m_fd_rtp))
- LOGERR("cUdpScheduler::AddHandle(fd_rtp) failed");
-
- Send_SAP(true);
-
- return true;
-}
-
-bool cUdpScheduler::AddHandle(int fd)
-{
- cMutexLock ml(&m_Lock);
-
- int i;
-
- for(i=0; i<MAX_UDP_HANDLES; i++)
- if(m_Handles[i] < 0 || m_Handles[i] == fd) {
- m_Handles[i] = fd;
-
- /* query socket send buffer size */
- m_wmem[i] = 0x10000; /* default to 64k */
- socklen_t l = sizeof(int);
- if(getsockopt(m_Handles[i], SOL_SOCKET, SO_SNDBUF, &m_wmem[i], &l))
- LOGERR("getsockopt(SO_SNDBUF) failed");
- m_wmem[i] /= 2; /* man 7 socket */
-
- m_Cond.Broadcast();
-
- return true;
- }
-
- return false;
-}
-
-void cUdpScheduler::RemoveRtp(void)
-{
- cMutexLock ml(&m_Lock);
-
- if(m_fd_rtp.open() || m_fd_rtcp.open()) {
- Send_SAP(false);
-
- RemoveHandle(m_fd_rtp);
-
- m_fd_rtp.close();
- m_fd_rtcp.close();
- CLOSESOCKET(m_fd_sap);
- }
-}
-
-void cUdpScheduler::RemoveHandle(int fd)
-{
- cMutexLock ml(&m_Lock);
-
- int i;
- for(i=0; i<MAX_UDP_HANDLES; i++)
- if(m_Handles[i] == fd)
- break;
-
- for(; i<MAX_UDP_HANDLES-1; i++)
- m_Handles[i] = m_Handles[i+1];
-
- m_Handles[MAX_UDP_HANDLES-1] = -1;
-
- if(m_Handles[0] < 0) {
- // No clients left ...
-
- // Flush all buffers
- m_QueueNextSeq = 0;
- m_QueuePending = 0;
-
- m_BackLogDeleteMutex.Lock();
- delete m_BackLog;
- m_BackLog = new cUdpBackLog;
- m_BackLogDeleteMutex.Unlock();
-
- m_Frames = 0;
- m_Octets = 0;
- }
-}
-
-int cUdpScheduler::Poll(int TimeoutMs, bool Master)
-{
- cMutexLock ml(&m_Lock);
-
- m_Master = Master;
-
- if(m_Handles[0] < 0) {
- // no clients, so we can eat all data we are given ...
- return DEFAULT_POLL_SIZE;
- }
-
- uint limit = m_Master ? MAX_QUEUE_SIZE : MAX_LIVE_QUEUE_SIZE;
- if(m_QueuePending >= limit) {
- uint64_t WaitEnd = cTimeMs::Now();
- if(TimeoutMs >= 0)
- WaitEnd += (uint64_t)TimeoutMs;
-
- while (cTimeMs::Now() < WaitEnd &&
- Running() &&
- m_QueuePending >= limit)
- m_Cond.TimedWait(m_Lock, 5);
- }
-
- return limit > m_QueuePending ? limit - m_QueuePending : 0;
-}
-
-bool cUdpScheduler::Flush(int TimeoutMs)
-{
- cMutexLock ml(&m_Lock);
-
- if(m_Handles[0] < 0)
- return true;
-
- if(m_QueuePending > 0) {
- uint64_t WaitEnd = cTimeMs::Now();
- if(TimeoutMs >= 0)
- WaitEnd += (uint64_t)TimeoutMs;
-
- while (cTimeMs::Now() < WaitEnd &&
- Running() &&
- m_QueuePending > 0)
- m_Cond.TimedWait(m_Lock, 5);
- }
- return m_QueuePending == 0;
-}
-
-void cUdpScheduler::Clear(void)
-{
- cMutexLock ml(&m_Lock);
-
- m_BackLog->Clear(m_QueuePending);
-
- m_QueuePending = 0;
- m_Cond.Broadcast();
-}
-
-void cUdpScheduler::Pause(bool On)
-{
- cMutexLock ml(&m_Lock);
-
- if(On)
- m_MasterClock.Pause();
- else
- m_MasterClock.Resume();
-
- m_TrickSpeed = false;
-}
-
-void cUdpScheduler::TrickSpeed(const int Multiplier)
-{
- cMutexLock ml(&m_Lock);
-
-#ifdef LOG_SCR
- if(Multiplier == 1 || Multiplier == -1) {
- LOGMSG("UDP clock --> normal");
- } else if(Multiplier < 0)
- LOGMSG("UDP clock --> %dx", -Multiplier);
- else
- LOGMSG("UDP clock --> 1/%d", Multiplier);
-#endif
-
- m_MasterClock.TrickSpeed(Multiplier);
-
- m_TrickSpeed = (Multiplier==-1 || Multiplier==1) ? false : true;
-}
-
-void cUdpScheduler::SetScrSpeed(const int Speed)
-{
- cMutexLock ml(&m_Lock);
-
- m_MasterClock.SetScrSpeed(Speed);
- m_RtpScr.SetScrSpeed(Speed);
-}
-
-bool cUdpScheduler::Queue(uint64_t StreamPos, const uchar *Data, int Length)
-{
- cMutexLock ml(&m_Lock);
-
- if(m_Handles[0] < 0)
- return true;
-
- uint limit = m_Master ? MAX_QUEUE_SIZE : MAX_LIVE_QUEUE_SIZE;
- if(m_QueuePending >= limit)
- return false;
-
- m_BackLog->MakeFrame(StreamPos, Data, Length);
- m_QueuePending++;
-
- m_Cond.Broadcast();
-
- return true;
-}
-
-void cUdpScheduler::QueuePadding(void)
-{
- cMutexLock ml(&m_Lock);
-
- if (m_Handles[0] < 0)
- return;
-
- if (m_QueuePending > 2)
- return;
-
- QueuePaddingInternal();
-
- m_Cond.Broadcast();
-}
-
-void cUdpScheduler::QueuePaddingInternal(void)
-{
- static unsigned const char Padding[] = {0x00,0x00,0x01,0xBE,0x00,0x02,0xff,0xff};
-
- int PrevSeq = (m_QueueNextSeq + UDP_BUFFER_SIZE - 1) & UDP_BUFFER_MASK;
- stream_rtp_header_impl_t *Frame = m_BackLog->Get(PrevSeq);
- if (Frame) {
- int PrevLen = m_BackLog->PayloadSize(PrevSeq);
- uint64_t Pos = ntohll(Frame->hdr_ext.pos) + PrevLen - 8;
- m_BackLog->MakeFrame(Pos, Padding, 8);
- } else
- m_BackLog->MakeFrame(0, Padding, 8);
-
- m_QueuePending++;
-}
-
-int cUdpScheduler::CalcElapsedVtime(int64_t pts, bool Audio)
-{
- int64_t diff = 0;
-
- if(!Audio) {
- diff = pts - m_CurrentVideoVtime;
- if(diff > JUMP_LIMIT_TIME || (-diff) > JUMP_LIMIT_TIME) { // 1 s (must be > GOP)
- // RESET
-#ifdef LOG_SCR
- LOGDBG("cUdpScheduler RESET (Video jump %lld->%lld)",
- m_CurrentVideoVtime, pts);
-#endif
- m_CurrentVideoVtime = pts;
-
- // Use video pts for sync only in audioless trickspeeds
- // (audio has smaller, constant and increasing intervals)
- if(m_TrickSpeed)
- m_MasterClock.Set(m_CurrentVideoVtime + INITIAL_BURST_TIME);
-
- return -1;
- }
- if(diff < 0) /* ignore small negative differences (B/P frames are sent out-of-order) */
- diff = 0;
- else
- m_CurrentVideoVtime = pts;
-
- } else if(Audio) {
- diff = pts - m_CurrentAudioVtime;
- if(diff < 0) diff = -diff;
- if(diff > JUMP_LIMIT_TIME) { // 1 sec
- // RESET
-#ifdef LOG_SCR
- LOGDBG("cUdpScheduler RESET (Audio jump %lld->%lld)",
- m_CurrentAudioVtime, pts);
-#endif
- m_CurrentAudioVtime = pts;
-
- // Use audio pts for sync (audio has constant and increasing intervals)
- m_MasterClock.Set(m_CurrentAudioVtime + INITIAL_BURST_TIME);
-
- return -1;
- }
- m_CurrentAudioVtime = pts;
- }
-
- return (int) diff;
-}
-
-void cUdpScheduler::Send_RTCP(void)
-{
- if(!m_fd_rtcp.open())
- return;
-
- uint64_t scr = m_RtpScr.Now();
-
- if(scr > (m_LastRtcpTime + RTCP_MIN_INTERVAL)) {
- uint8_t frame[2048], *content = frame;
- char hostname[64] = "";
- rtcp_packet_t *msg = (rtcp_packet_t *)content;
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- gethostname(hostname, sizeof(hostname)-1);
- hostname[sizeof(hostname)-1] = 0;
-
- // SR (Sender report)
- msg->hdr.raw[0] = 0x81; // RTP version = 2, Report count = 1 */
- msg->hdr.ptype = RTCP_SR;
- msg->hdr.length = htons(6); // length 6 dwords
-
- msg->sr.ssrc = htonl(m_ssrc);
- msg->sr.ntp_sec = htonl(tv.tv_sec + 0x83AA7E80);
- msg->sr.ntp_frac = htonl((uint32_t)((double)tv.tv_usec*(double)(1LL<<32)*1.0e-6));
- msg->sr.rtp_ts = htonl((uint32_t)(scr & 0xffffffff));
- msg->sr.psent = htonl((uint32_t)(m_Frames & 0xffffffff));
- msg->sr.osent = htonl((uint32_t)(m_Octets & 0xffffffff));
-
- content += sizeof(rtcp_common_t) + sizeof(rtcp_sr_t);
- msg = (rtcp_packet_t *)content;
-
- // SDES
- msg->hdr.raw[0] = 0x81; // RTP version = 2, Report count = 1 */
- msg->hdr.ptype = RTCP_SDES;
- msg->hdr.count = 1;
-
- msg->sdes.ssrc = m_ssrc;
- msg->sdes.item[0].type = RTCP_SDES_CNAME;
- sprintf(msg->sdes.item[0].data, "VDR@%s:%d%c%c%c",
- hostname[0] ? hostname : xc.remote_rtp_addr,
- xc.remote_rtp_port, 0, 0, 0);
- msg->sdes.item[0].length = strlen(msg->sdes.item[0].data);
- msg->hdr.length = htons(1 + 1 + ((msg->sdes.item[0].length - 2) + 3) / 4);
-
- content += sizeof(rtcp_common_t) + 4*ntohs(msg->hdr.length);
- msg = (rtcp_packet_t *)content;
-
- // Send
-#ifndef LOG_RTCP
- (void) m_fd_rtcp.send(frame, content - frame);
-#else
- LOGMSG("RTCP send (%d)", m_fd_rtcp.send(frame, content - frame));
- for(int i=0; i<content-frame; i+=16)
- LOGMSG("%02X %02X %02X %02X %02X %02X %02X %02X "
- "%02X %02X %02X %02X %02X %02X %02X %02X "
- " %c%c%c%c%c%c%c%c %c%c%c%c%c%c%c%c",
- frame[i+0],frame[i+1],frame[i+2],frame[i+3],
- frame[i+4],frame[i+5],frame[i+6],frame[i+7],
- frame[i+8],frame[i+9],frame[i+10],frame[i+11],
- frame[i+12],frame[i+13],frame[i+14],frame[i+15],
- frame[i+0],frame[i+1],frame[i+2],frame[i+3],
- frame[i+4],frame[i+5],frame[i+6],frame[i+7],
- frame[i+8],frame[i+9],frame[i+10],frame[i+11],
- frame[i+12],frame[i+13],frame[i+14],frame[i+15]);
-#endif
-
- m_LastRtcpTime = scr;
- }
-}
-
-
-void cUdpScheduler::Send_SAP(bool Announce)
-{
- if(!xc.remote_rtp_sap || !m_fd_rtp.open())
- return;
-
- char ip[64] = "";
- uint32_t local_addr = m_fd_rtp.get_local_address(ip);
-
- if(!local_addr)
- return;
-
- uint32_t payload_type = VDRVERSNUM > 10702 ? SDP_PAYLOAD_MPEG_TS : SDP_PAYLOAD_MPEG_PES;
- const char *sdp_descr = vdr_sdp_description(ip,
- 2001,
- xc.listen_port,
- xc.remote_rtp_addr,
- payload_type,
- m_ssrc,
- xc.remote_rtp_port,
- xc.remote_rtp_ttl);
- if(!sdp_descr)
- return;
-
-#if 1
- /* store copy of SDP data */
- if(m_fd_sap < 0) {
- cString fname = AddDirectory(VideoDirectory,
- cString::sprintf("xineliboutput@%s.sdp",
- ip));
- FILE *fp = fopen(fname, "w");
- if(fp) {
- fprintf(fp, "%s", sdp_descr);
- fclose(fp);
- }
- }
-#endif
-
- sap_pdu_t *pdu = sap_create_pdu(local_addr,
- Announce,
- (m_ssrc >> 16 | m_ssrc) & 0xffff,
- "application/sdp",
- sdp_descr);
-
- if(!sap_send_pdu(&m_fd_sap, pdu, 0))
- LOGERR("SAP/SDP announce failed");
- free(pdu);
-
- if(!Announce)
- CLOSESOCKET(m_fd_sap);
-}
-
-void cUdpScheduler::Schedule(const uchar *Data, int Length)
-{
- bool Audio = IS_AUDIO_PACKET(Data), Video = IS_VIDEO_PACKET(Data);
- int64_t pts = PES_HAS_PTS(Data) ? pes_get_pts(Data, Length) : INT64_C(-1);
- int elapsed = pts>0 ? CalcElapsedVtime(pts, Audio) : 0;
-
- if(elapsed > 0) {
- int64_t now = m_MasterClock.Now();
- LOGSCR("PTS: %lld (%s) elapsed %d ms (PID %02x)",
- pts, Video?"Video":Audio?"Audio":"?", pts_to_ms(elapsed), Data[3]);
-
- //
- // Detect discontinuity
- //
- if(Audio) {
- if(now > m_CurrentAudioVtime && (now - m_CurrentAudioVtime)>JUMP_LIMIT_TIME) {
- LOGSCR("cUdpScheduler MasterClock init (was in past)");
- m_MasterClock.Set(m_CurrentAudioVtime + INITIAL_BURST_TIME);
- } else if(now < m_CurrentAudioVtime && (m_CurrentAudioVtime-now)>JUMP_LIMIT_TIME) {
- LOGSCR("cUdpScheduler MasterClock init (was in future)");
- m_MasterClock.Set(m_CurrentAudioVtime + INITIAL_BURST_TIME);
- }
- }
-
- else if(Video && m_TrickSpeed) {
- if(now > m_CurrentVideoVtime && (now - m_CurrentVideoVtime)>JUMP_LIMIT_TIME) {
- LOGSCR("cUdpScheduler MasterClock init (was in past) - VIDEO");
- m_MasterClock.Set(m_CurrentVideoVtime + INITIAL_BURST_TIME);
- } else if(now < m_CurrentVideoVtime && (m_CurrentVideoVtime-now)>JUMP_LIMIT_TIME) {
- LOGSCR("cUdpScheduler MasterClock init (was in future) - VIDEO");
- m_MasterClock.Set(m_CurrentVideoVtime + INITIAL_BURST_TIME);
- }
- }
-
- //
- // Delay
- //
- uint delay_ms = 0;
- if(m_TrickSpeed ) {
- if(m_CurrentVideoVtime > now) {
- delay_ms = pts_to_ms(m_CurrentVideoVtime - now);
- LOGSCR("cUdpScheduler sleeping %d ms "
- "(time reference: %s, beat interval %d ms)",
- delay_ms, (Audio?"Audio PTS":"Video PTS"), pts_to_ms(elapsed));
- }
- } else {
- if(m_CurrentAudioVtime > now) {
- delay_ms = pts_to_ms(m_CurrentAudioVtime - now);
- LOGSCR("cUdpScheduler sleeping %d ms "
- "(time reference: %s, beat interval %d ms)",
- delay_ms, (Audio?"Audio PTS":"Video PTS"), pts_to_ms(elapsed));
- }
- }
-
- while (delay_ms > SCHEDULER_MIN_DELAY_MS) {
- if (delay_ms > SCHEDULER_MAX_DELAY_MS)
- delay_ms = SCHEDULER_MAX_DELAY_MS;
- LOGSCR(" -> cUdpScheduler sleeping %d ms ", delay_ms);
- Scheduler_Sleep(delay_ms);
- now = m_MasterClock.Now();
- delay_ms = pts_to_ms(m_CurrentVideoVtime - now);
- }
- }
-}
-
-void cUdpScheduler::Action(void)
-{
-#if 0
- {
- // Request real-time scheduling
- sched_param temp;
- temp.sched_priority = 2;
-
- if (!pthread_setschedparam(pthread_self(), SCHED_RR, &temp)) {
- LOGMSG("cUdpScheduler priority set successful SCHED_RR %d [%d,%d]",
- temp.sched_priority,
- sched_get_priority_min(SCHED_RR),
- sched_get_priority_max(SCHED_RR));
- } else {
- LOGMSG("cUdpScheduer: Can't set priority to SCHED_RR %d [%d,%d]",
- temp.sched_priority,
- sched_get_priority_min(SCHED_RR),
- sched_get_priority_max(SCHED_RR));
- }
- }
-#endif
-
- /* UDP Scheduler needs high priority */
- const int priority = -5;
- SetPriority(priority);
- errno = 0;
- if ((nice(priority) == -1) && errno)
- LOGDBG("cUdpScheduler: Can't nice to value: %d", priority);
-
- m_Lock.Lock();
-
- while (Running()) {
-
- if(m_Handles[0] < 0) {
- m_Cond.TimedWait(m_Lock, 5000);
- continue;
- }
-
- // Wait until we have outgoing data in queue
- if(m_QueuePending <= 0) {
- m_BurstFrames = m_BurstBytes = 0;
- m_Cond.TimedWait(m_Lock, 100);
- if(m_QueuePending <= 0) {
- // Still nothing...
- // Send padding frame once in 100ms so clients can detect
- // possible missing frames and server shutdown
- QueuePaddingInternal();
- }
- continue; // to check Running()
- }
-
- // Take next frame from queue
- stream_rtp_header_impl_t *frame = m_BackLog->Get(m_QueueNextSeq);
- int PayloadSize = m_BackLog->PayloadSize(m_QueueNextSeq);
- int UdpPacketLen = PayloadSize + sizeof(stream_udp_header_t);
- int RtpPacketLen = PayloadSize + sizeof(stream_rtp_header_impl_t);
-
- m_QueueNextSeq = (m_QueueNextSeq + 1) & UDP_BUFFER_MASK;
- m_QueuePending--;
-
- m_Cond.Broadcast();
- m_BackLogDeleteMutex.Lock(); /* ensure frame will not be deleted from queue */
- m_Lock.Unlock();
-
- // Schedule frame
- if(m_Master)
- Schedule(frame->payload, PayloadSize);
-
- // Need some bandwidth limit for ex. sequence of still frames when
- // moving cutting marks very fast (no audio or PTS available).
- // Hard limit for used bandwidth:
- // - ~1 frames/ms & 8kb/ms -> 8mb/s -> ~ 80 Mbit/s ( / client)
- // - max burst 15 frames or 32 kb
- m_BurstFrames ++;
- m_BurstBytes += PayloadSize;
- if (m_BurstFrames >= MAX_BURST_FRAMES && m_BurstBytes >= MAX_BURST_BYTES) {
- Scheduler_Sleep(4);
-#ifdef LOG_UDP_RATE
- static uint64_t dbg_timer = cTimeMs::Now();
- static int dbg_bytes = 0;
- dbg_bytes += bytes;
- if (dbg_timer + 60000 <= cTimeMs::Now()) {
- LOGDBG("UDP rate: %4d Kbps (queue %d)", dbg_bytes/(60*1024/8), m_QueuePending);
- dbg_bytes = 0;
- dbg_timer = cTimeMs::Now();
- }
-#endif
- }
-
- /* tag frame with ssrc and timestamp */
- frame->rtp_hdr.ts = htonl((uint32_t)(m_RtpScr.Now() & 0xffffffff));
- frame->rtp_hdr.ssrc = htonl(m_ssrc);
-
- /* deliver to all active sockets */
- for(int i=0; i<MAX_UDP_HANDLES && m_Handles[i]>=0; i++) {
-
- //
- // use TIOCOUTQ ioctl instead of poll/select.
- // - poll/select for UDP/RTP may return true even when queue
- // is (almost) full
- // - kernel silently drops frames it cant send
- // -> poll() + send() just causes frames to be dropped
- //
- uint size = 0;
- if(!ioctl(m_Handles[i], TIOCOUTQ, &size)) {
- if(size >= (m_wmem[i] - 2*RtpPacketLen)) {
- LOGMSG("cUdpScheduler: kernel transmit queue > ~%dkb (max %dkb) ! (master=%d)",
- (m_wmem[i] - 2*RtpPacketLen)/1024, m_wmem[i]/1024, m_Master);
- Scheduler_Sleep(2);
- }
- } else {
- if(m_QueuePending > (MAX_QUEUE_SIZE-5))
- LOGDBG("cUdpScheduler: kernel transmit queue > ~30kb ! (master=%d ; Queue=%d)",
- m_Master, m_QueuePending);
- Scheduler_Sleep(2);
- }
-
- if(m_Handles[i] == m_fd_rtp.handle()) {
- if(send(m_Handles[i], frame, RtpPacketLen, 0) <= 0)
- LOGERR("cUdpScheduler: UDP/RTP send() failed !");
- } else {
- /* UDP: send without rtp header */
- if(send(m_Handles[i],
- ((uint8_t*)frame) + sizeof(stream_rtp_header_impl_t) - sizeof(stream_udp_header_t),
- UdpPacketLen, 0) <= 0)
- LOGERR("cUdpScheduler: UDP send() failed !");
- }
- }
-
- m_BackLogDeleteMutex.Unlock(); /* release queue */
- m_Lock.Lock();
-
- m_Frames ++;
- m_Octets += PayloadSize;
- if(m_fd_rtcp.open() && (m_Frames & 0xff) == 1) { // every 256th frame
- Send_RTCP();
-#if 0
- if((m_Frames & 0xff00) == 0) // every 65536th frame (~ 2 min)
- Send_SAP();
-#else
- if((m_Frames & 0x0300) == 0) // every 1024th frame (~ 2...4 sec)
- Send_SAP();
-#endif
- }
- }
-
- m_Lock.Unlock();
-}
-
-void cUdpScheduler::ReSend(int fd, uint64_t Pos, int Seq1, int Seq2)
-{
- if(fd < 0) /* no re-send for RTP */
- return;
-
- struct {
- stream_udp_header_t hdr;
- char mem[64-sizeof(stream_udp_header_t)];
- } udp_ctrl = {{(uint64_t)INT64_C(-1), (uint16_t)-1}, {0}};
-
- // Handle buffer wrap
- if(Seq1 > Seq2)
- Seq2 += UDP_BUFFER_SIZE;
-
- cMutexLock ml(&m_Lock); // keeps also scheduler thread suspended ...
-
- if(Seq2-Seq1 > 64) {
- LOGDBG("cUdpScheduler::ReSend: requested range too large (%d-%d)",
- Seq1, Seq2);
-
- sprintf((char*)udp_ctrl.hdr.payload,
- "UDP MISSING %d-%d %" PRIu64,
- Seq1, (Seq2 & UDP_BUFFER_MASK), Pos);
- send(fd, &udp_ctrl, sizeof(udp_ctrl), 0);
- return;
- }
-
- // re-send whole range
- for(; Seq1 <= Seq2; Seq1++) {
-
- // Wait if kernel queue is full
- int size = 0;
- if(!ioctl(fd, TIOCOUTQ, &size))
- if(size > ((0x10000)/2 - 2048)) { // assume 64k kernel buffer
- LOGDBG("cUdpScheduler::ReSend: kernel transmit queue > ~30kb !");
- Scheduler_Sleep(2);
- }
-
- stream_rtp_header_impl_t *frame = m_BackLog->Get(Seq1);
-
- if(frame) {
- if(ntohull(frame->hdr_ext.pos) - Pos < 100000) {
- send(fd,
- ((uint8_t*)frame) + sizeof(stream_rtp_header_impl_t) - sizeof(stream_udp_header_t),
- m_BackLog->PayloadSize(Seq1) + sizeof(stream_udp_header_t),
- 0);
- LOGRESEND("cUdpScheduler::ReSend: %d (%d bytes) @%lld sent",
- Seq1, m_BackLog->PayloadSize(Seq1), Pos);
- Pos = ntohull(frame->hdr_ext.pos) + m_BackLog->PayloadSize(Seq1);
- continue;
- } else {
- // buffer has been lost long time ago...
- LOGRESEND("cUdpScheduler::ReSend: Requested position does not match "
- "(%lld ; has %lld)", Pos, ntohll(frame->hdr_ext.pos));
- }
- } else {
- LOGRESEND("cUdpScheduler::ReSend: %d @%lld missing", Seq1, Pos);
- }
-
- // buffer has been lost - send packet missing info
-
- LOGRESEND("cUdpScheduler::ReSend: missing %d-%d @%d (hdr 0x%llx 0x%x)",
- Seq1, Seq1, Pos, udp_ctrl.hdr.pos, udp_ctrl.hdr.seq);
-
- int Seq0 = Seq1;
- for(; Seq1 < Seq2; Seq1++) {
- stream_rtp_header_impl_t *frame = m_BackLog->Get(Seq1+1);
- if(frame && (ntohull(frame->hdr_ext.pos) - Pos < 100000))
- break;
- }
-
- sprintf((char*)udp_ctrl.hdr.payload,
- "UDP MISSING %d-%d %" PRIu64,
- Seq0, (Seq1 & UDP_BUFFER_MASK), Pos);
-
- send(fd, &udp_ctrl, sizeof(udp_ctrl), 0);
- }
-}
diff --git a/tools/udp_pes_scheduler.h b/tools/udp_pes_scheduler.h
deleted file mode 100644
index a889f728..00000000
--- a/tools/udp_pes_scheduler.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * udp_pes_scheduler.h: PES scheduler for UDP/RTP streams
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: udp_pes_scheduler.h,v 1.20 2009-07-02 10:38:29 phintuka Exp $
- *
- */
-
-#ifndef __UDP_PES_SCHEDULER_H
-#define __UDP_PES_SCHEDULER_H
-
-#include <stdint.h>
-
-#include <vdr/tools.h> // uchar
-#include <vdr/thread.h>
-
-#include "cxsocket.h"
-#include "time_pts.h"
-
-#define MAX_UDP_HANDLES 16
-
-class cUdpBackLog;
-
-class cUdpScheduler : public cThread
-{
- public:
-
- cUdpScheduler();
- virtual ~cUdpScheduler();
-
- // fd should be binded & connected to IP:PORT (local+remote) pair !
- bool AddHandle(int fd); /* UDP unicast */
- void RemoveHandle(int fd); /* UDP unicast */
- bool AddRtp(void); /* UDP/RTP multicast */
- void RemoveRtp(void); /* UDP/RTP multicast */
- bool AddHandle(cxSocket& s) { return AddHandle(s.handle()); }
- void RemoveHandle(cxSocket& s) { RemoveHandle(s.handle()); }
-
- bool Clients(void) { return m_Handles[0] >= 0; }
- int Poll(int TimeoutMs, bool Master);
- bool Queue(uint64_t StreamPos, const uchar *Data, int Length);
- void QueuePadding(void);
- void ReSend(int fd, uint64_t Pos, int Seq1, int Seq2);
-
- void Clear(void);
- bool Flush(int TimeoutMs);
-
- void Pause(bool On);
- void TrickSpeed(const int Multiplier);
- void SetScrSpeed(const int Speed = 90000);
-
- protected:
-
- // Signalling
-
- cCondVar m_Cond;
- cMutex m_Lock;
-
- // Clients
-
- int m_Handles[MAX_UDP_HANDLES];
- uint m_wmem[MAX_UDP_HANDLES]; /* kernel buffer size */
-
- cxSocket m_fd_rtp;
- cxSocket m_fd_rtcp;
-
- // Queue
-
- uint m_QueueNextSeq; /* next outgoing */
- uint m_QueuePending; /* outgoing queue size */
- cUdpBackLog *m_BackLog; /* queue for incoming data (not yet send) and retransmissions */
- cMutex m_BackLogDeleteMutex;
-
- // Scheduling
-
- cTimePts m_MasterClock; /* Current MPEG PTS (synchronized to current stream) */
- bool m_TrickSpeed; /* current (replay) speed */
- bool m_Master; /* if true, we are master metronom for playback */
-
- int64_t m_CurrentAudioVtime;
- int64_t m_CurrentVideoVtime;
-
- uint m_BurstBytes; /* number of bytes sent without sleeps */
- uint m_BurstFrames; /* number of frames sent without sleeps */
-
- cCondWait m_CondWait;
-
- int CalcElapsedVtime(int64_t pts, bool Audio);
- void Schedule(const uchar *Data, int Length);
- void Scheduler_Sleep(int ms);
- void QueuePaddingInternal(void);
-
- // RTP
-
- uint32_t m_ssrc; /* RTP synchronization source id */
- cTimePts m_RtpScr; /* 90 kHz monotonic time source for RTP timestamps */
-
- // RTCP
-
- uint64_t m_LastRtcpTime;
- uint32_t m_Frames;
- uint32_t m_Octets;
-
- void Send_RTCP(void);
-
- // SAP
-
- int m_fd_sap;
-
- void Send_SAP(bool Announce = true);
-
- // Thread
-
- virtual void Action(void);
-};
-
-#endif
diff --git a/tools/vdrdiscovery.c b/tools/vdrdiscovery.c
deleted file mode 100644
index e301056d..00000000
--- a/tools/vdrdiscovery.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * vdrdiscovery.c
- *
- * Simple broadcast protocol to search VDR with xineliboutput server
- * from (local) network.
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vdrdiscovery.c,v 1.9 2009-06-29 21:23:33 phintuka Exp $
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <poll.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <arpa/inet.h>
-
-#define LOG_MODULENAME "[discovery] "
-#include "../logdefs.h"
-
-#include "vdrdiscovery.h"
-
-/*
- * constants
- */
-
-#ifndef DISCOVERY_PORT
-# define DISCOVERY_PORT 37890
-#endif
-
-/* discovery protocol strings (v1.0) */
-#define DISCOVERY_1_0_HDR "VDR xineliboutput DISCOVERY 1.0" "\r\n"
-#define DISCOVERY_1_0_CLI "Client: %s:%d" "\r\n"
-#define DISCOVERY_1_0_SVR "Server port: %d" "\r\n"
-#define DISCOVERY_1_0_ADDR "Server address: %s" "\r\n"
-#define DISCOVERY_1_0_VERSION "Server version: " /*vdr-" VDRVERSION "\r\n\t"*/ \
- "xineliboutput-" XINELIBOUTPUT_VERSION "\r\n"
-
-/*
- *
- */
-
-static inline int discovery_init(int port)
-{
- int fd_discovery = -1;
- int iBroadcast = 1, iReuse = 1;
- struct sockaddr_in sin;
-
- if ((fd_discovery = socket(PF_INET, SOCK_DGRAM, 0/*IPPROTO_TCP*/)) < 0) {
- LOGERR("discovery_init: socket() failed");
- return -1;
- }
-
- if (setsockopt(fd_discovery, SOL_SOCKET, SO_BROADCAST, &iBroadcast, sizeof(int)) < 0)
- LOGERR("discovery_init: setsockopt(SO_BROADCAST) failed");
-
- if (setsockopt(fd_discovery, SOL_SOCKET, SO_REUSEADDR, &iReuse, sizeof(int)) < 0)
- LOGERR("discovery_init: setsockopt(SO_REUSEADDR) failed");
-
- sin.sin_family = AF_INET;
- sin.sin_port = htons(port);
- sin.sin_addr.s_addr = htonl(INADDR_BROADCAST);
-
- if (bind(fd_discovery, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
- LOGERR("discovery_init: bind() failed");
- close(fd_discovery);
- return -1;
- }
-
- return fd_discovery;
-}
-
-int udp_discovery_init(void)
-{
- return discovery_init(DISCOVERY_PORT);
-}
-
-static inline int udp_discovery_send(int fd_discovery, int port, char *msg)
-{
- struct sockaddr_in sin;
- int len = strlen(msg);
-
- sin.sin_family = AF_INET;
- sin.sin_port = htons(port);
- sin.sin_addr.s_addr = INADDR_BROADCAST;
-
- if(len != sendto(fd_discovery, msg, len, 0,
- (struct sockaddr *)&sin, sizeof(sin))) {
- LOGERR("UDP broadcast send failed (discovery)");
- return -1;
- }
-
- //LOGDBG("UDP broadcast send succeed (discovery)");
- return 0;
-}
-
-int udp_discovery_broadcast(int fd_discovery, int server_port, const char *server_address)
-{
- char *msg = NULL;
- int result;
-
- if(server_address && *server_address) {
- result = asprintf(&msg,
- DISCOVERY_1_0_HDR //"VDR xineliboutput DISCOVERY 1.0" "\r\n"
- DISCOVERY_1_0_SVR //"Server port: %d" "\r\n"
- DISCOVERY_1_0_ADDR //"Server Address: %d.%d.%d.%d \r\n"
- DISCOVERY_1_0_VERSION //"Server version: xineliboutput-" XINELIBOUTPUT_VERSION "\r\n"
- "\r\n",
- server_port, server_address);
- } else {
- result = asprintf(&msg,
- DISCOVERY_1_0_HDR //"VDR xineliboutput DISCOVERY 1.0" "\r\n"
- DISCOVERY_1_0_SVR //"Server port: %d" "\r\n"
- DISCOVERY_1_0_VERSION //"Server version: xineliboutput-" XINELIBOUTPUT_VERSION "\r\n"
- "\r\n",
- server_port);
- }
-
- if (result >= 0) {
- result = udp_discovery_send(fd_discovery, DISCOVERY_PORT, msg);
- free(msg);
- }
-
- return result;
-}
-
-static inline int udp_discovery_search(int fd_discovery, int port)
-{
- char *msg = NULL;
- int result;
-
- result = asprintf(&msg,
- DISCOVERY_1_0_HDR /* "VDR xineliboutput DISCOVERY 1.0" "\r\n" */
- DISCOVERY_1_0_CLI /* "Client: %s:%d" "\r\n" */
- "\r\n",
- "255.255.255.255",
- port);
-
- if (result >= 0) {
- result = udp_discovery_send(fd_discovery, port, msg);
- free(msg);
- }
-
- return result;
-}
-
-int udp_discovery_recv(int fd_discovery, char *buf, int timeout,
- struct sockaddr_in *source)
-{
- socklen_t sourcelen = sizeof(struct sockaddr_in);
- struct pollfd pfd;
- int err;
-
- pfd.fd = fd_discovery;
- pfd.events = POLLIN;
-
- errno = 0;
- err = poll(&pfd, 1, timeout);
- if(err < 1) {
- if(err < 0)
- LOGERR("broadcast poll error");
- return err;
- }
-
- memset(source, 0, sourcelen);
- memset(buf, 0, DISCOVERY_MSG_MAXSIZE);
-
- err = recvfrom(fd_discovery, buf, DISCOVERY_MSG_MAXSIZE-1, 0,
- (struct sockaddr *)source, &sourcelen);
-
- if(err <= 0)
- LOGDBG("fd_discovery recvfrom() error");
-
- return err;
-}
-
-int udp_discovery_is_valid_search(const char *buf)
-{
- static const char id_string[] = { DISCOVERY_1_0_HDR "Client:" };
-
- if(!strncmp(id_string, buf, strlen(id_string))) {
- LOGMSG("Received valid discovery message %s", buf);
- return 1;
- }
-
- LOGDBG("BROADCAST: %s", buf);
- return 0;
-}
-
-int udp_discovery_find_server(int *port, char *address)
-{
- static const char mystring[] = DISCOVERY_1_0_HDR "Server port: ";
- struct sockaddr_in from;
- char buf[DISCOVERY_MSG_MAXSIZE];
- int fd_discovery = -1;
- int trycount = 0;
- int err = 0;
-
- *port = DISCOVERY_PORT;
- strcpy(address, "vdr");
-
- if((fd_discovery = discovery_init(DISCOVERY_PORT)) < 0)
- return 0;
-
- while(err >= 0 && ++trycount < 4) {
-
- if((err = udp_discovery_search(fd_discovery, DISCOVERY_PORT) >= 0)) {
-
- errno = 0;
- while( (err = udp_discovery_recv(fd_discovery, buf, 500, &from)) > 0) {
-
- uint32_t tmp = ntohl(from.sin_addr.s_addr);
-
- buf[err] = 0;
- LOGDBG("Reveived broadcast: %d bytes from %d.%d.%d.%d \n%s",
- err,
- ((tmp>>24)&0xff), ((tmp>>16)&0xff),
- ((tmp>>8)&0xff), ((tmp)&0xff),
- buf);
- if(!strncmp(mystring, buf, strlen(mystring))) {
- char *iploc;
- LOGDBG("Valid discovery message");
- close(fd_discovery);
-
- // default: use broadcast source address
- sprintf(address, "%d.%d.%d.%d",
- ((tmp>>24)&0xff), ((tmp>>16)&0xff),
- ((tmp>>8)&0xff), ((tmp)&0xff));
-
- // Check if announce message includes alternative server address
- iploc = strstr(buf + strlen(mystring), "Server address: ");
- if(iploc) {
- uint32_t svraddr;
- iploc += strlen("Server address: ");
- svraddr = inet_addr(iploc);
- if(svraddr == INADDR_NONE) {
- LOGMSG("Server provided invalid address !");
- } else {
- svraddr = ntohl(svraddr);
- sprintf(address, "%d.%d.%d.%d",
- ((svraddr>>24)&0xff), ((svraddr>>16)&0xff),
- ((svraddr>>8)&0xff), ((svraddr)&0xff));
- LOGMSG("Replacing broadcast source address %d.%d.%d.%d "
- "with server-given address %s",
- ((tmp>>24)&0xff), ((tmp>>16)&0xff),
- ((tmp>>8)&0xff), ((tmp)&0xff),
- address);
- }
- }
-
- *port = -1;
- if(1 == sscanf(buf + strlen(mystring), "%d", port) &&
- *port >= 1000 && *port <= 0xffff)
- return 1;
- LOGMSG("Server-given port is invalid !");
- } else {
- LOGDBG("NOT valid discovery message");
- }
- }
- }
- }
-
- /* failed */
- close(fd_discovery);
- return 0;
-}
-
-
diff --git a/tools/vdrdiscovery.h b/tools/vdrdiscovery.h
deleted file mode 100644
index de612733..00000000
--- a/tools/vdrdiscovery.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * vdrdiscovery.h
- *
- * Simple broadcast protocol to search VDR with xineliboutput server
- * from (local) network.
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vdrdiscovery.h,v 1.5 2009-02-10 15:26:11 phintuka Exp $
- *
- */
-
-#ifndef _VDRDISCOVERY_H_
-#define _VDRDISCOVERY_H_
-
-#define DISCOVERY_MSG_MAXSIZE 1024
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct sockaddr_in;
-
-/*
- * Client interface
- */
-
-/*
- * udp_discovery_find_server()
- *
- * Search for server. Return address and port.
- * Returns 0 on success.
- */
-int udp_discovery_find_server(int *port, char *address);
-
-/*
- * Server interface
- */
-
-/*
- * udp_discovery_init()
- *
- * Initialize server socket. Return value is the socket file descriptor,
- * and can be used for polling.
- * Returns < 0 on error.
- */
-int udp_discovery_init(void);
-
-/*
- * udp_discovery_broadcast()
- *
- * Send server announcement.
- * Returns 0 on success.
- */
-int udp_discovery_broadcast(int fd_discovery, int server_port, const char *server_address);
-
-/*
- * udp_discovery_recv()
- *
- * Receive query or announcement.
- * Returns number of bytes received, <= 0 on error.
- * Result is null-terminated string, not more than DISCOVERY_MSG_MAXSIZE bytes.
- */
-int udp_discovery_recv(int fd_discovery, char *buf, int timeout,
- struct sockaddr_in *source);
-
-/*
- * udp_discovery_is_valid_search()
- *
- * Check if string is valid search message.
- * Returns 1 for valid messages, 0 for invalid messages.
- */
-int udp_discovery_is_valid_search(const char *buf);
-
-#ifdef __cplusplus
-};
-#endif
-
-
-#endif // _VDRDISCOVERY_H_
diff --git a/vdrlogo_32x32.c b/vdrlogo_32x32.c
deleted file mode 100644
index 00045db6..00000000
--- a/vdrlogo_32x32.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * vdrlogo_32x32.c: 32x32 logo icon
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vdrlogo_32x32.c,v 1.4 2009-05-27 09:39:08 phintuka Exp $
- *
- */
-
-/* GIMP RGBA C-Source image dump (vdrlogo_32x32.c) */
-
-typedef struct {
- const uint32_t width;
- const uint32_t height;
- const uint8_t pixel_data[32 * 32 * sizeof(uint32_t) + 1];
-} __attribute__((packed)) sxfe_32x32_icon_t;
-
-static const sxfe_32x32_icon_t vdrlogo_32x32 = {
- 32, 32, /*4,*/
- "\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\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"
- "\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\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"
- "\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\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"
- "\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\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"
- "\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\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
- "\214v\246\32<\31xcT5\210F\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\0sZ\226\37F$|^;\30yc;\30yc;\30ycC!~cY7\205U\231\210\265FL"
- ".\202c<\30yc;\30yc;\30yc;\30yc;\30yc;\30ycE\"\177cU4\200Jv^\227\14\0\0\0"
- "\0\0\0\0\0\0\0\0\0\243\224\304\10B\33z\354I!~\366\315\276\331\22\0\0\0\0"
- "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0R3\202a>\24z\367:\17y\377:\17x\377"
- ":\17x\377:\17x\377:\17y\377:\17|\377>\25{\377_C\204\377M*\200\377:\20x\377"
- ":\20x\377:\20w\377:\20w\377:\20w\377:\17x\377:\17y\377@\31|\357eH\215G\0"
- "\0\0\0\0\0\0\0\0\0\0\0R.\204\225;\17z\377tY\231e\0\0\0\0\0\0\0\0\0\0\0\0"
- "\0\0\0\0\0\0\0\0mT\223\40=\24z\373=\33n\377>!f\377lax\254f^n\211f]q\211e"
- "]r\220_Ov\254J*x\363;\17y\377cH\215\345gbjvgbjskfmsnipsqkrsoiv|^G|\274<\23"
- "y\377E\36~\352\272\252\320\21\0\0\0\0\0\0\0\0u\\\2261;\22z\377Y7\207\304"
- "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0O+\204\202;\21u\377M4t\370;\20y\377"
- "rf\207Y\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\227\256\"J(\177\341:\21{\377"
- "sZ\233J\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\342\340\343\1P*\203\266;"
- "\17x\377zi\220a\0\0\0\0\0\0\0\0\0\0\0\0K&\204\316A\32{\375\243\230\264\37"
- "\0\0\0\0\0\0\0\0\0\0\0\0\335\313\362\3C\34}\340M1t\370J&\177\251:\20x\377"
- "rf\207Y\0\0\0\0ddd\6\24\24\24\301\35\35\35\301ZZZ\22hL\217X;\17{\377[=\212"
- "\265\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0G!~\251:\17y\377se\205"
- "{\0\0\0\0\0\0\0\0\0\0\0\0W7\203g9\20z\377iM\221}\0\0\0\0\0\0\0\0\0\0\0\0"
- "\\;\215F:\20y\377eU{\250?\26y\230:\20x\377rf\207Y\0\0\0\0fgg$GB3\377NKF\377"
- "JJJ\177\231\205\264\21=\23x\377T2\201\360\335\337\320\1\0\0\0\0\0\0\0\0\0"
- "\0\0\0\236\213\273\17Y7\210i<\23y\372?\32o\377\222\216\227H\0\0\0\0\0\0\0"
- "\0\0\0\0\0\212t\252\15@\30}\364T2\207\330\351\343\345\1\0\0\0\0\0\0\0\0H"
- "#~\252=\31r\377\225\216\230E?\26y\230:\20x\377rf\207Y\0\0\0\0\222\217\220"
- "\"\260\2215\377\237\213K\377788\236\352\332\366\6F\36\201\377L'|\377H$\202"
- "\366@\30}\365@\30}\365A\27{\365=\23y\375;\17x\377;\31n\377j_w\254\327\322"
- "\326\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0I&\201\236>\24z\377\226\203\2617\0"
- "\0\0\0|b\242\24=\24{\367V@x\340\344\342\343\2?\26y\230:\20x\377rf\207Y\0"
- "\0\0\0TUU\236\353\352\353\377\355\354\354\377('(\366MJP2B\31}\377I'z\377"
- "bN\201\357T?v\365P8v\367<\27u\377:\21x\377UDq\330\177}\203]\333\335\332\2"
- "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0eM\222;;\20z\377aC\214\223\0\0\0"
- "\0L*\205n:\21w\377od}\202\0\0\0\0?\26y\230:\20x\377rf\207YY\\\\\40\230\230"
- "\232\372\364\365\365\377\366\366\366\377||}\3772-8\327:\17x\377U9}\372\337"
- "\342\332\3\0\0\0\0\340\340\330\2\203w\230TE\40z\365<\23{\367W7\210D\0\0\0"
- "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\327\305\357\1G\"}\330O,\203\353"
- "\336\322\347\6F\37~\321F&r\375\255\254\256$\0\0\0\0?\26y\230:\17x\377\200"
- "t\216c\262\222D\221\272\260\216\377\363\364\365\377\366\366\366\377\212\201"
- "^\3773#%\377:\17x\377[Hx\302\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0xb\232]<\24z"
- "\377>\27z\353\204l\242\36\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
- "R2\205t;\20z\377y`\231w;\21v\377`Nz\303\0\0\0\0\0\0\0\0@\27z\230:\17y\377"
- "\242\217r\245\355\272\21\377\310\240\20\377\331\326\323\377\324\324\324\377"
- "\311\231\37\377\337\257\25\377S-^\377|u\203e\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
- "\0\0\0\0\0\0_?\214\2539\20z\377M*\202\262\367\361\363\2\0\0\0\0\0\0\0\0\0"
- "\0\0\0\0\0\0\0\0\0\0\0\205o\246\27?\26{\371J$\177\370:\24s\377\202{\206`"
- "\0\0\0\0\0\0\0\0?\26z\230;\17x\377gG\200\325}QB\377\214\\C\377<\40L\377$"
- "\15H\377\207^\25\377V9,\377TM_\307\312\317\307\5\0\0\0\0\0\0\0\0\0\0\0\0"
- "\0\0\0\0\0\0\0\0\242\215\271\26I$\200\355;\20z\377_C\213Y\0\0\0\0\0\0\0\0"
- "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0M+\202\2619\20z\377P5u\361\313\314\307\15"
- "\0\0\0\0\0\0\0\0>\25x\231;\17y\377:\20y\377:\17y\377;\17y\3779\17z\377<\24"
- "p\377@)`\376bXo\262\266\264\253\26\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\0u\\\233`<\21y\377A\34|\351\205s\246\25\0\0\0\0\0\0\0\0"
- "\0\0\0\0\0\0\0\0\0\0\0\0\221\211\2319kct\217|y\206a\0\0\0\0\0\0\0\0\0\0\0"
- "\0\204y\215Mjcx\217kav\215lbx\217kar\215icr\205\202\202\204i\260\261\251"
- "&\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"
- "\360\355\347\3wo\202zj`u\215\217\220\223?\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\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\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\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\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\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\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\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\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\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
-};
-
diff --git a/vdrlogo_720x576.mpg b/vdrlogo_720x576.mpg
deleted file mode 100644
index 2ef0f3f4..00000000
--- a/vdrlogo_720x576.mpg
+++ /dev/null
Binary files differ
diff --git a/xine/adjustable_scr.c b/xine/adjustable_scr.c
deleted file mode 100644
index 4301e348..00000000
--- a/xine/adjustable_scr.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * adjustable_scr.c:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: adjustable_scr.c,v 1.2 2008-12-14 01:21:20 phintuka Exp $
- *
- */
-
-
-#include <xine/xine_internal.h>
-#include <xine/xineutils.h>
-#include <xine/metronom.h>
-
-#include "adjustable_scr.h"
-
-/*
- * SCR code is mostly copied from xine-lib (src/input/input_pvr.c)
- *
- *
- * Copyright (C) 2000-2005 the xine project
- * March 2003 - Miguel Freitas
- * This plugin was sponsored by 1Control
- *
- * This file is part of xine, a free video player.
- *
- * xine is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * xine is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- */
-
-typedef struct scr_impl_s scr_impl_t;
-
-struct scr_impl_s {
- union {
- scr_plugin_t scr;
- adjustable_scr_t ascr;
- };
-
- xine_t *xine;
-
- struct timeval cur_time;
- int64_t cur_pts;
- int xine_speed;
- int scr_speed_base;
- double speed_factor;
- double speed_tuning;
-
- pthread_mutex_t lock;
-
- struct timeval last_time;
-};
-
-/* Only call set_pivot when already mutex locked ! */
-static void set_pivot (scr_impl_t *this)
-{
- struct timeval tv;
- int64_t pts;
- double pts_calc;
-
- xine_monotonic_clock(&tv,NULL);
-
- pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor;
- pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6;
- pts = this->cur_pts + pts_calc;
-
- /* This next part introduces a one off inaccuracy
- * to the scr due to rounding tv to pts.
- */
- this->cur_time.tv_sec=tv.tv_sec;
- this->cur_time.tv_usec=tv.tv_usec;
- this->cur_pts=pts;
-
- this->last_time.tv_sec = tv.tv_sec;
- this->last_time.tv_usec = tv.tv_usec;
-
- return ;
-}
-
-/*
- * xine interface (scr_plugin_t)
- */
-
-static int scr_get_priority (scr_plugin_t *scr)
-{
- return 50; /* high priority */
-}
-
-static int scr_set_fine_speed (scr_plugin_t *scr, int speed)
-{
- scr_impl_t *this = (scr_impl_t*) scr;
-
- pthread_mutex_lock (&this->lock);
-
- set_pivot( this );
- this->xine_speed = speed;
- this->speed_factor = (double) speed * (double)this->scr_speed_base /*90000.0*/ /
- (1.0*XINE_FINE_SPEED_NORMAL) *
- this->speed_tuning;
-
- pthread_mutex_unlock (&this->lock);
-
- return speed;
-}
-
-static void scr_adjust (scr_plugin_t *scr, int64_t vpts)
-{
- scr_impl_t *this = (scr_impl_t*) scr;
- struct timeval tv;
-
- pthread_mutex_lock (&this->lock);
-
- xine_monotonic_clock(&tv,NULL);
- this->cur_time.tv_sec=tv.tv_sec;
- this->cur_time.tv_usec=tv.tv_usec;
- this->cur_pts = vpts;
-
- this->last_time.tv_sec = tv.tv_sec;
- this->last_time.tv_usec = tv.tv_usec;
-
- pthread_mutex_unlock (&this->lock);
-}
-
-static void scr_start (scr_plugin_t *scr, int64_t start_vpts)
-{
- scr_impl_t *this = (scr_impl_t*) scr;
-
- pthread_mutex_lock (&this->lock);
-
- xine_monotonic_clock(&this->cur_time, NULL);
- this->cur_pts = start_vpts;
-
- this->last_time.tv_sec = this->cur_time.tv_sec;
- this->last_time.tv_usec = this->cur_time.tv_usec;
-
- pthread_mutex_unlock (&this->lock);
-
- scr_set_fine_speed (&this->scr, XINE_FINE_SPEED_NORMAL);
-}
-
-static int64_t scr_get_current (scr_plugin_t *scr)
-{
- scr_impl_t *this = (scr_impl_t*) scr;
-
- struct timeval tv;
- int64_t pts;
- double pts_calc;
- pthread_mutex_lock (&this->lock);
-
- xine_monotonic_clock(&tv,NULL);
-
- pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor;
- pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6;
-
- pts = this->cur_pts + pts_calc;
-
- this->last_time.tv_sec = tv.tv_sec;
- this->last_time.tv_usec = tv.tv_usec;
-
- pthread_mutex_unlock (&this->lock);
-
- return pts;
-}
-
-static void scr_exit (scr_plugin_t *scr)
-{
- scr_impl_t *this = (scr_impl_t*) scr;
-
- pthread_mutex_destroy (&this->lock);
- free(this);
-}
-
-/*
- * adjusteble_scr_t
- */
-
-/*
- * speed_tuning()
- *
- * - fine-tune SCR speed. Actual speed is base_speed * factor.
- */
-static void adjustable_scr_speed_tuning (adjustable_scr_t *scr, double factor)
-{
- scr_impl_t *this = (scr_impl_t*) scr;
-
- pthread_mutex_lock (&this->lock);
-
- set_pivot( this );
- this->speed_tuning = factor;
- this->speed_factor = (double) this->xine_speed * (double)this->scr_speed_base /*90000.0*/ /
- (1.0*XINE_FINE_SPEED_NORMAL) *
- this->speed_tuning;
-
- pthread_mutex_unlock (&this->lock);
-}
-
-/*
- * speed_base()
- *
- * - set base speed of SCR (default is 90kHz)
- */
-static void adjustable_scr_speed_base (adjustable_scr_t *scr, int hz)
-{
- scr_impl_t *this = (scr_impl_t*) scr;
-
- pthread_mutex_lock (&this->lock);
-
- set_pivot( this );
- this->scr_speed_base = hz;
- this->speed_factor = (double) this->xine_speed * (double)this->scr_speed_base /*90000.0*/ /
- (1.0*XINE_FINE_SPEED_NORMAL) *
- this->speed_tuning;
-
- pthread_mutex_unlock (&this->lock);
-}
-
-/*
- * jump()
- *
- * - Move SCR 'pts' ticks forward
- */
-static void adjustable_scr_jump (adjustable_scr_t *scr, int pts)
-{
- scr_impl_t *this = (scr_impl_t*) scr;
-
- pthread_mutex_lock (&this->lock);
-
- set_pivot( this );
- this->cur_pts += pts;
-
- pthread_mutex_unlock (&this->lock);
-}
-
-/*
- * dispose()
- *
- * - unregister, stop and free resources
- */
-static void adjustable_scr_dispose(adjustable_scr_t *scr)
-{
- scr_impl_t *this = (scr_impl_t*)scr;
-
- /* unregister */
- if (this->xine)
- this->xine->clock->unregister_scr(this->xine->clock, &this->scr);
-
- /* exit and dispose */
- this->scr.exit(&this->scr);
-}
-
-/*
- * adjusteble_scr_start()
- *
- */
-adjustable_scr_t* adjustable_scr_start (xine_t *xine)
-{
- scr_impl_t *this;
-
- this = calloc(1, sizeof(scr_impl_t));
-
- /* xine scr plugin interface */
- this->scr.interface_version = 3;
- this->scr.set_fine_speed = scr_set_fine_speed;
- this->scr.get_priority = scr_get_priority;
- this->scr.adjust = scr_adjust;
- this->scr.start = scr_start;
- this->scr.get_current = scr_get_current;
- this->scr.exit = scr_exit;
-
- /* tuning / management interface */
- this->ascr.set_speed_tuning = adjustable_scr_speed_tuning;
- this->ascr.set_speed_base = adjustable_scr_speed_base;
- this->ascr.jump = adjustable_scr_jump;
- this->ascr.dispose = adjustable_scr_dispose;
-
- /* initialize */
-
- pthread_mutex_init (&this->lock, NULL);
-
- this->xine = xine;
- this->scr_speed_base = 90000;
-
- adjustable_scr_speed_tuning(&this->ascr, 1.0 );
- scr_set_fine_speed (&this->scr, XINE_SPEED_PAUSE);
-
- /* start and register */
-
- uint64_t time = xine->clock->get_current_time(xine->clock);
- this->scr.start(&this->scr, time);
-
- if (xine->clock->register_scr(xine->clock, &this->scr)) {
- scr_exit(&this->scr);
- return NULL;
- }
-
- return &this->ascr;
-}
diff --git a/xine/adjustable_scr.h b/xine/adjustable_scr.h
deleted file mode 100644
index 61707684..00000000
--- a/xine/adjustable_scr.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * adjustable_scr.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: adjustable_scr.h,v 1.1 2008-12-03 22:50:04 phintuka Exp $
- *
- */
-
-#ifndef XINELIBOUTPUT_ADJUSTABLE_SCR_H_
-#define XINELIBOUTPUT_ADJUSTABLE_SCR_H_
-
-/******************************* SCR *************************************
- *
- * unix System Clock Reference + fine tuning
- *
- * fine tuning is used to change playback speed in live mode
- * to keep in sync with mpeg source
- *************************************************************************/
-
-typedef struct adjustable_scr_s adjustable_scr_t;
-
-struct adjustable_scr_s {
- scr_plugin_t scr;
-
- void (*set_speed_tuning)(adjustable_scr_t *this, double factor);
- void (*set_speed_base) (adjustable_scr_t *this, int hz);
- void (*jump) (adjustable_scr_t *this, int pts);
-
- void (*dispose) (adjustable_scr_t *this);
-};
-
-adjustable_scr_t *adjustable_scr_start (xine_t *xine);
-
-
-#endif /* XINELIBOUTPUT_ADJUSTABLE_SCR_H_ */
diff --git a/xine/demux_xvdr.c b/xine/demux_xvdr.c
deleted file mode 100644
index b1387fd3..00000000
--- a/xine/demux_xvdr.c
+++ /dev/null
@@ -1,1209 +0,0 @@
-/*
- * Copyright (C) 2000-2006 the xine project
- *
- * This file is part of xine, a free video player.
- *
- * xine is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * xine is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * demultiplexer for xineliboutput (xvdr)
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <xine/xine_internal.h>
-#include <xine/xineutils.h>
-#include <xine/demux.h>
-
-#include "../xine_input_vdr_mrl.h"
-#include "../tools/mpeg.h"
-#include "../tools/h264.h"
-#include "../tools/pes.h"
-#include "../tools/ts.h"
-
-#include "ts2es.h"
-#include "demux_xvdr_tsdata.h"
-
-/*
- * features
- */
-
-#define VDR_SUBTITLES
-#define TEST_DVB_SPU
-
-/*
- * logging
- */
-
-static const char log_module_demux_xvdr[] = "[demux_vdr] ";
-#define LOG_MODULENAME log_module_demux_xvdr
-#define SysLogLevel iSysLogLevel
-
-#include "../logdefs.h"
-
-#define LOGSPU(x...)
-
-/*
- * constants
- */
-
-#define DISC_TRESHOLD 90000
-#define WRAP_THRESHOLD 120000
-#define PTS_AUDIO 0
-#define PTS_VIDEO 1
-
-
-/* redefine abs as macro to handle 64-bit diffs.
- i guess llabs may not be available everywhere */
-#define abs(x) ( ((x)<0) ? -(x) : (x) )
-
-typedef struct demux_xvdr_s {
- demux_plugin_t demux_plugin;
-
- xine_stream_t *stream;
- fifo_buffer_t *audio_fifo;
- fifo_buffer_t *video_fifo;
-
- input_plugin_t *input;
-
- ts_data_t *ts_data; /* MPEG-TS stuff */
-
- int64_t last_pts[2];
- int64_t last_vpts;
- int status;
- uint32_t video_type;
- uint32_t audio_type;
- uint32_t subtitle_type;
-
- /* current buf_element */
- int64_t pts;
- int64_t dts;
- uint32_t packet_len;
- uint8_t stream_id;
-
- uint8_t send_newpts : 1;
- uint8_t buf_flag_seek : 1;
- uint8_t ffmpeg_mpeg2_decoder : 1;
- uint8_t coreavc_h264_decoder : 1;
- uint8_t bih_posted : 1;
-} demux_xvdr_t ;
-
-typedef struct {
-
- demux_class_t demux_class;
-
- /* class-wide, global variables here */
-
- xine_t *xine;
- config_values_t *config;
-} demux_xvdr_class_t;
-
-
-static const char * get_decoder_name(xine_t *xine, int video_type)
-{
- int streamtype = (video_type >> 16) & 0xFF;
- plugin_node_t *node = xine->plugin_catalog->video_decoder_map[streamtype][0];
- if (node) {
- plugin_info_t *info = node->info;
- if (info)
- return info->id;
- }
- return "";
-}
-
-static void detect_video_decoders(demux_xvdr_t *this)
-{
- if (!strcmp(get_decoder_name(this->stream->xine, BUF_VIDEO_MPEG), "ffmpegvideo"))
- this->ffmpeg_mpeg2_decoder = 1;
- LOGMSG("Using decoder \"%s\" for mpeg2 video",
- this->ffmpeg_mpeg2_decoder ? "FFmpeg" : "libmpeg2");
-
- if (!strcmp(get_decoder_name(this->stream->xine, BUF_VIDEO_H264), "dshowserver"))
- this->coreavc_h264_decoder = 1;
- LOGMSG("Using decoder \"%s\" for H.264 video",
- this->coreavc_h264_decoder ? "dshowserver (CoreAVC)" : "FFmpeg");
-}
-
-static void demux_xvdr_parse_ts(demux_xvdr_t *this, buf_element_t *buf);
-static void demux_xvdr_parse_pes(demux_xvdr_t *this, buf_element_t *buf);
-
-static int32_t parse_video_stream(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf);
-static int32_t parse_audio_stream(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf);
-static int32_t parse_private_stream_1(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf);
-static int32_t parse_padding_stream(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf);
-
-static void pts_wrap_workaround(demux_xvdr_t *this, buf_element_t *buf, int video)
-{
- /* PTS wrap workaround */
- if (buf->pts >= 0) {
- if (video)
- this->last_vpts = buf->pts;
- else if (buf->pts > INT64_C( 0x40400000 ) &&
- this->last_vpts < INT64_C( 0x40000000 ) &&
- this->last_vpts > INT64_C( 0 )) {
- LOGMSG("VIDEO pts wrap before AUDIO, ignoring audio pts %" PRId64, buf->pts);
- buf->pts = INT64_C(0);
- }
- }
-}
-
-static void check_newpts(demux_xvdr_t *this, buf_element_t *buf, int video )
-{
- pts_wrap_workaround(this, buf, video);
-
- if (buf->pts) {
- int64_t diff = buf->pts - this->last_pts[video];
-
- if (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD)) {
-
- if (this->buf_flag_seek) {
- _x_demux_control_newpts(this->stream, buf->pts, BUF_FLAG_SEEK);
- this->buf_flag_seek = 0;
- } else {
- _x_demux_control_newpts(this->stream, buf->pts, 0);
- }
- this->send_newpts = 0;
-
- this->last_pts[1-video] = 0;
- }
-
- this->last_pts[video] = buf->pts;
- }
-}
-
-static void put_control_buf(fifo_buffer_t *buffer, fifo_buffer_t *pool, int cmd)
-{
- buf_element_t *buf = pool->buffer_pool_try_alloc(pool);
- if(buf) {
- buf->type = cmd;
- buffer->put(buffer, buf);
- }
-}
-
-/*
- * post_sequence_end()
- *
- * Add MPEG2 or H.264 sequence end code to fifo buffer
- */
-static void post_sequence_end(fifo_buffer_t *fifo, uint32_t video_type)
-{
- buf_element_t *buf = fifo->buffer_pool_try_alloc(fifo);
- if (buf) {
- buf->type = video_type;
- buf->size = 4;
- buf->decoder_flags = BUF_FLAG_FRAME_END;
- buf->content[0] = 0x00;
- buf->content[1] = 0x00;
- buf->content[2] = 0x01;
- buf->content[3] = (video_type == BUF_VIDEO_H264) ? NAL_END_SEQ : 0xB7;
- fifo->put(fifo, buf);
- }
-}
-
-/*
- * post_frame_end()
- *
- * Signal end of video frame to decoder.
- *
- * This function is used with:
- * - FFmpeg mpeg2 decoder
- * - FFmpeg and CoreAVC H.264 decoders
- * - NOT with libmpeg2 mpeg decoder
- */
-static void post_frame_end(demux_xvdr_t *this, buf_element_t *vid_buf)
-{
- buf_element_t *cbuf = this->video_fifo->buffer_pool_try_alloc (this->video_fifo) ?:
- this->audio_fifo->buffer_pool_try_alloc (this->audio_fifo);
-
- if (!cbuf) {
- LOGMSG("post_frame_end(): buffer_pool_try_alloc() failed, retrying");
- xine_usec_sleep (10*1000);
- cbuf = this->video_fifo->buffer_pool_try_alloc (this->video_fifo);
- if (!cbuf) {
- LOGERR("post_frame_end(): get_buf_element() failed !");
- return;
- }
- }
-
- cbuf->type = this->video_type;
- cbuf->decoder_flags = BUF_FLAG_FRAME_END;
-
- if (!this->bih_posted) {
- video_size_t size = {0};
- if (pes_get_video_size(vid_buf->content, vid_buf->size, &size, this->video_type == BUF_VIDEO_H264)) {
-
- /* reset decoder buffer */
- cbuf->decoder_flags |= BUF_FLAG_FRAME_START;
-
- /* Fill xine_bmiheader for CoreAVC / H.264 */
-
- if (this->video_type == BUF_VIDEO_H264 && this->coreavc_h264_decoder) {
- xine_bmiheader *bmi = (xine_bmiheader*) cbuf->content;
-
- cbuf->decoder_flags |= BUF_FLAG_HEADER;
- cbuf->decoder_flags |= BUF_FLAG_STDHEADER; /* CoreAVC: buffer contains bmiheader */
- cbuf->size = sizeof(xine_bmiheader);
-
- memset (bmi, 0, sizeof(xine_bmiheader));
-
- bmi->biSize = sizeof(xine_bmiheader);
- bmi->biWidth = size.width;
- bmi->biHeight = size.height;
-
- bmi->biPlanes = 1;
- bmi->biBitCount = 24;
- bmi->biCompression = 0x34363248;
- bmi->biSizeImage = 0;
- bmi->biXPelsPerMeter = size.pixel_aspect.num;
- bmi->biYPelsPerMeter = size.pixel_aspect.den;
- bmi->biClrUsed = 0;
- bmi->biClrImportant = 0;
- }
-
- /* Set aspect ratio for ffmpeg mpeg2 / CoreAVC H.264 decoder
- * (not for FFmpeg H.264 or libmpeg2 mpeg2 decoders)
- */
-
- if (size.pixel_aspect.num &&
- (this->video_type != BUF_VIDEO_H264 || this->coreavc_h264_decoder)) {
- cbuf->decoder_flags |= BUF_FLAG_HEADER;
- cbuf->decoder_flags |= BUF_FLAG_ASPECT;
- /* pixel ratio -> frame ratio */
- if (size.pixel_aspect.num > size.height) {
- cbuf->decoder_info[1] = size.pixel_aspect.num / size.height;
- cbuf->decoder_info[2] = size.pixel_aspect.den / size.width;
- } else {
- cbuf->decoder_info[1] = size.pixel_aspect.num * size.width;
- cbuf->decoder_info[2] = size.pixel_aspect.den * size.height;
- }
- }
-
- LOGDBG("post_frame_end: video width %d, height %d, pixel aspect %d:%d",
- size.width, size.height, size.pixel_aspect.num, size.pixel_aspect.den);
-
- this->bih_posted = 1;
- }
- }
-
- this->video_fifo->put (this->video_fifo, cbuf);
-}
-
-static void track_audio_stream_change(demux_xvdr_t *this, buf_element_t *buf)
-{
-#if !defined(BUF_CONTROL_RESET_TRACK_MAP)
-# warning xine-lib is older than 1.1.2. Multiple audio streams are not supported.
-#else
- if (this->audio_type != buf->type) {
- LOGDBG("audio stream changed: %08x -> %08x", this->audio_type, buf->type);
- this->audio_type = buf->type;
- put_control_buf(this->audio_fifo,
- this->audio_fifo,
- BUF_CONTROL_RESET_TRACK_MAP);
- }
-#endif
-}
-
-static void demux_xvdr_fwd_buf(demux_xvdr_t *this, buf_element_t *buf)
-{
- /* demuxed video --> video_fifo */
- if ((buf->type & BUF_MAJOR_MASK) == BUF_VIDEO_BASE) {
- this->video_type = buf->type;
- check_newpts (this, buf, PTS_VIDEO);
- this->video_fifo->put (this->video_fifo, buf);
- return;
- }
-
- /* demuxed audio --> audio_fifo */
- if ((buf->type & BUF_MAJOR_MASK) == BUF_AUDIO_BASE) {
- if (this->audio_fifo) {
- check_newpts (this, buf, PTS_AUDIO);
- track_audio_stream_change (this, buf);
- this->audio_fifo->put (this->audio_fifo, buf);
- } else {
- buf->free_buffer (buf);
- }
- return;
- }
-
- /* decoder flush --> video_fifo */
- if (buf->type == BUF_CONTROL_FLUSH_DECODER) {
- /* append sequence end code */
- post_sequence_end (this->video_fifo, this->video_type);
- this->video_fifo->put (this->video_fifo, buf);
- return;
- }
-
- /* control buffer --> both fifos */
- if ((buf->type & BUF_MAJOR_MASK) == BUF_CONTROL_BASE) {
- if (this->audio_fifo) {
- /* duplicate goes to audio fifo */
- buf_element_t *cbuf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
- cbuf->type = buf->type;
- cbuf->decoder_flags = buf->decoder_flags;
- memcpy (cbuf->decoder_info, buf->decoder_info, sizeof(cbuf->decoder_info));
- memcpy (cbuf->decoder_info_ptr, buf->decoder_info_ptr, sizeof(cbuf->decoder_info_ptr));
-
- this->audio_fifo->put (this->audio_fifo, cbuf);
- }
- this->video_fifo->put (this->video_fifo, buf);
- return;
- }
-
- LOGMSG("Unhandled buffer type %08x", buf->type);
- buf->free_buffer (buf);
-}
-
-static void demux_xvdr_parse_pack (demux_xvdr_t *this)
-{
- buf_element_t *buf = NULL;
- uint8_t *p;
-
- buf = this->input->read_block (this->input, this->video_fifo, 8128);
-
- if (!buf) {
- if (errno == EINTR)
- LOGMSG("input->read_block() was interrupted");
- else if (errno != EAGAIN)
- this->status = DEMUX_FINISHED;
- return;
- }
-
- /* If this is not a block for the demuxer, pass it
- * straight through. */
- if (buf->type != BUF_DEMUX_BLOCK) {
- ts_data_flush (this->ts_data);
- demux_xvdr_fwd_buf (this, buf);
- return;
- }
-
- p = buf->content; /* len = this->blocksize; */
- buf->decoder_flags = 0;
-
- if (DATA_IS_TS(p)) {
- demux_xvdr_parse_ts (this, buf);
- return;
- }
- if (DATA_IS_PES(p)) {
- demux_xvdr_parse_pes (this, buf);
- return;
- }
-
- LOGMSG("Header %02x %02x %02x (should be 0x000001 or 0x47)", p[0], p[1], p[2]);
- buf->free_buffer (buf);
- return;
-}
-
-static void demux_xvdr_parse_pes (demux_xvdr_t *this, buf_element_t *buf)
-{
- uint8_t *p = buf->content;
- int32_t result;
-
- this->stream_id = p[3];
-
- if (IS_VIDEO_PACKET(p)) {
- result = parse_video_stream(this, p, buf);
- } else if (IS_MPEG_AUDIO_PACKET(p)) {
- result = parse_audio_stream(this, p, buf);
- } else if (IS_PADDING_PACKET(p)) {
- result = parse_padding_stream(this, p, buf);
- } else if (IS_PS1_PACKET(p)) {
- result = parse_private_stream_1(this, p, buf);
- } else {
- LOGMSG("Unrecognised PES stream 0x%02x", this->stream_id);
- buf->free_buffer (buf);
- return;
- }
-
- if (result < 0) {
- return;
- }
-
- LOGMSG("error! freeing buffer.");
- buf->free_buffer (buf);
-}
-
-/*
- * demux_xvdr_parse_ts()
- *
- * MPEG-TS demuxing
- */
-static void demux_xvdr_parse_ts (demux_xvdr_t *this, buf_element_t *buf)
-{
- if (!this->ts_data)
- this->ts_data = calloc(1, sizeof(ts_data_t));
-
- ts_data_t *ts_data = this->ts_data;
-
- while (buf->size >= TS_SIZE) {
-
- unsigned int ts_pid = ts_PID(buf->content);
-
- /* parse PAT */
- if (ts_pid == 0) {
- pat_data_t pat;
-
- ts_data_flush(ts_data);
-
- if (ts_parse_pat(&pat, buf->content)) {
- ts_data->pmt_pid = pat.pmt_pid[0];
- ts_data->program_number = pat.program_number[0];
- LOGMSG("Got PAT, PMT pid = %d, program = %d", ts_data->pmt_pid, ts_data->program_number);
- }
- }
-
- /* parse PMT */
- else if (ts_pid == ts_data->pmt_pid) {
-
- ts_data_flush(ts_data);
-
- if (ts_parse_pmt(&ts_data->pmt, ts_data->program_number, buf->content)) {
-
- /* PMT changed, reset ts->es converters */
- LOGMSG("PMT changed");
- ts_data_ts2es_init(&ts_data, this->stream->video_fifo, this->stream->audio_fifo);
-
- this->video_type = (ts_data->pmt.video_type == ISO_14496_PART10_VIDEO) ?
- BUF_VIDEO_H264 : BUF_VIDEO_MPEG;
-
- /* Inform UI of channels changes */
- xine_event_t event;
- event.type = XINE_EVENT_UI_CHANNELS_CHANGED;
- event.data_length = 0;
- xine_event_send(this->stream, &event);
- }
- }
-
- /* demux video */
- else if (ts_pid == ts_data->pmt.video_pid) {
-
- if (ts_data->video) {
- buf_element_t *vbuf = ts2es_put(ts_data->video, buf->content);
- if (vbuf) {
- this->pts = vbuf->pts;
- check_newpts( this, vbuf, PTS_VIDEO );
-
- this->stream->video_fifo->put(this->stream->video_fifo, vbuf);
- }
- }
- }
-
- /* demux audio */
- else {
- int i, done = 0;
- for (i=0; i < ts_data->pmt.audio_tracks_count; i++)
- if (ts_pid == ts_data->pmt.audio_tracks[i].pid) {
- if (ts_data->audio[i]) {
- buf_element_t *abuf = ts2es_put(ts_data->audio[i], buf->content);
- if (abuf) {
- this->pts = abuf->pts;
- check_newpts( this, abuf, PTS_AUDIO );
- track_audio_stream_change (this, abuf);
-
- this->stream->audio_fifo->put(this->stream->audio_fifo, abuf);
- }
- }
- done = 1;
- break;
- }
-#if 0
- /* demux subtitles */
- if (!done)
- for (i=0; i < ts_data->pmt.spu_tracks_count; i++)
- if (ts_pid == ts_data->pmt.spu_tracks[i].pid) {
- if (ts_data->spu[i]) {
- buf_element_t *sbuf = ts2es_put(ts_data->spu[i], buf->content);
- if (sbuf)
- this->stream->video_fifo->put(this->stream->video_fifo, sbuf);
- }
- done = 1;
- break;
- }
-
- if (!done)
- LOGMSG("Got unknown TS packet, pid = %d", ts_pid);
-#endif
- }
-
- buf->content += TS_SIZE;
- buf->size -= TS_SIZE;
- }
-
- buf->free_buffer(buf);
-}
-
-static int32_t parse_padding_stream(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf)
-{
- buf->free_buffer (buf);
- return -1;
-}
-
-/* FIXME: Extension data is not parsed, and is also not skipped. */
-
-static int32_t parse_pes_for_pts(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf)
-{
- int32_t header_len;
-
- this->packet_len = p[4] << 8 | p[5];
-
- if ((p[6] & 0xC0) != 0x80 /* mpeg1 */) {
- header_len = 6;
- p += 6; /* packet_len -= 6; */
-
- while ((p[0] & 0x80) == 0x80) {
- p++;
- header_len++;
- this->packet_len--;
- }
-
- if ((p[0] & 0xc0) == 0x40) {
- /* STD_buffer_scale, STD_buffer_size */
- p += 2;
- header_len += 2;
- this->packet_len -= 2;
- }
-
- this->pts = 0;
- this->dts = 0;
-
- if ((p[0] & 0xf0) == 0x20) {
- this->pts = (int64_t)(p[ 0] & 0x0E) << 29 ;
- this->pts |= p[ 1] << 22 ;
- this->pts |= (p[ 2] & 0xFE) << 14 ;
- this->pts |= p[ 3] << 7 ;
- this->pts |= (p[ 4] & 0xFE) >> 1 ;
- p += 5;
- header_len+= 5;
- this->packet_len -=5;
- return header_len;
- } else if ((p[0] & 0xf0) == 0x30) {
- this->pts = (int64_t)(p[ 0] & 0x0E) << 29 ;
- this->pts |= p[ 1] << 22 ;
- this->pts |= (p[ 2] & 0xFE) << 14 ;
- this->pts |= p[ 3] << 7 ;
- this->pts |= (p[ 4] & 0xFE) >> 1 ;
-
- this->dts = (int64_t)(p[ 5] & 0x0E) << 29 ;
- this->dts |= p[ 6] << 22 ;
- this->dts |= (p[ 7] & 0xFE) << 14 ;
- this->dts |= p[ 8] << 7 ;
- this->dts |= (p[ 9] & 0xFE) >> 1 ;
-
- p += 10;
- header_len += 10;
- this->packet_len -= 10;
- return header_len;
- } else {
- p++;
- header_len++;
- this->packet_len--;
- return header_len;
- }
-
- } else { /* mpeg 2 */
-
-
- if ((p[6] & 0xC0) != 0x80) {
- LOGMSG("warning: PES header reserved 10 bits not found");
- buf->free_buffer(buf);
- return -1;
- }
-
-
- /* check PES scrambling_control */
- if ((p[6] & 0x30) != 0) {
- LOGMSG("encrypted PES ?");
- buf->free_buffer(buf);
- return -1;
- }
-
- if (p[7] & 0x80) { /* pts avail */
-
- this->pts = (int64_t)(p[ 9] & 0x0E) << 29 ;
- this->pts |= p[10] << 22 ;
- this->pts |= (p[11] & 0xFE) << 14 ;
- this->pts |= p[12] << 7 ;
- this->pts |= (p[13] & 0xFE) >> 1 ;
-
- } else
- this->pts = 0;
-
- if (p[7] & 0x40) { /* dts avail */
-
- this->dts = (int64_t)(p[14] & 0x0E) << 29 ;
- this->dts |= p[15] << 22 ;
- this->dts |= (p[16] & 0xFE) << 14 ;
- this->dts |= p[17] << 7 ;
- this->dts |= (p[18] & 0xFE) >> 1 ;
-
- } else
- this->dts = 0;
-
-
- header_len = p[8];
-
- this->packet_len -= header_len + 3;
- return header_len + 9;
- }
- return 0;
-}
-
-#if defined(TEST_DVB_SPU)
-/*
- * parse_dvb_spu()
- *
- * DVB subtitle stream demuxing
- */
-static int32_t parse_dvb_spu(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf, int substream_header_len)
-{
- uint spu_id = p[0] & 0x1f;
- _x_select_spu_channel(this->stream, spu_id);
-
-# ifdef VDR_SUBTITLES
- if (substream_header_len == 1) {
- p--;
- this->packet_len++;
- }
-# endif /* VDR_SUBTITLES */
-
- /* Skip substream header */
- p += substream_header_len;
- buf->content = p;
- buf->size = this->packet_len - substream_header_len;
-
- /* Special buffer when payload packet changes */
- if (this->pts > 0) {
- buf_element_t *cbuf = this->video_fifo->buffer_pool_alloc(this->video_fifo);
- int page_id = (*(p+4) << 8) | *(p+5);
-
- spu_dvb_descriptor_t *spu_descriptor = (spu_dvb_descriptor_t *) cbuf->content;
- memset(spu_descriptor, 0, sizeof(spu_dvb_descriptor_t));
- spu_descriptor->comp_page_id = page_id;
-
- cbuf->type = BUF_SPU_DVB + spu_id;
- cbuf->size = 0;
- cbuf->decoder_flags = BUF_FLAG_SPECIAL;
- cbuf->decoder_info[1] = BUF_SPECIAL_SPU_DVB_DESCRIPTOR;
- cbuf->decoder_info[2] = sizeof(spu_dvb_descriptor_t);
- cbuf->decoder_info_ptr[2] = spu_descriptor;
-
- this->video_fifo->put (this->video_fifo, cbuf);
- }
-
- buf->type = BUF_SPU_DVB + spu_id;
- buf->pts = this->pts;
- buf->decoder_info[2] = this->pts > 0 ? 0xffff : 0; /* hack - size unknown here (?) */
-
- this->video_fifo->put (this->video_fifo, buf);
-
- return -1;
-}
-
-int detect_dvb_spu(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf)
-{
- LOGSPU("%s%02x %02x %02x %02x %02x %02x %02x %02x",
- this->pts>0?"* ":" ",p[0], p[1], p[2], p[3],
- p[4], p[5], p[6], p[7]);
-
- /* If PES packet has PTS, it starts new subtitle (ES) packet. */
- if (this->pts > 0) {
- /* Reset SPU type */
- this->subtitle_type = 0;
- }
-
-# ifdef VDR_SUBTITLES
- /* Compatibility mode for old subtitles plugin */
- if (this->subtitle_type != BUF_SPU_DVD) {
- if ((buf->content[7] & 0x01) && (p[-3] & 0x81) == 0x01 && p[-2] == 0x81) {
- LOGDBG("DVB SPU: Old vdr-subtitles compability mode");
- return parse_dvb_spu(this, p, buf, 1);
- }
- }
-# endif /* VDR_SUBTITLES */
-
- /* Start of subtitle packet. Guess substream type */
- if (this->pts > 0) {
- if (p[4] == 0x20 && p[5] == 0x00 && (p[6] == 0x0f || p[4] == 0x0f)) {
- this->subtitle_type = BUF_SPU_DVB;
- LOGSPU(" -> DVB SPU");
- } else if (p[2] || (p[3] & 0xfe)) {
- this->subtitle_type = BUF_SPU_DVD;
- LOGSPU(" -> DVD SPU");
- } else {
- this->subtitle_type = BUF_SPU_DVD;
- LOGMSG(" -> DV? SPU -> DVD");
- }
- }
-
- /* DVD SPU ? */
- if (this->subtitle_type == BUF_SPU_DVD)
- return this->packet_len;
-
- /* DVB SPU */
- return parse_dvb_spu(this, p, buf, 4);
-}
-
-#endif /* TEST_DVB_SPU */
-
-static int32_t parse_private_stream_1(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf)
-{
- int track, spu_id;
- int32_t result;
-
- result = parse_pes_for_pts(this, p, buf);
- if (result < 0) return -1;
-
- p += result;
-
- /* SPU */
- if ((p[0] & 0xE0) == 0x20) {
- spu_id = (p[0] & 0x1f);
-
- if (this->pts <= 0 && !this->subtitle_type) {
- /* need whole ES packet (after seek etc.) */
- buf->free_buffer(buf);
- return -1;
- }
-
-#ifdef TEST_DVB_SPU
- if (detect_dvb_spu(this, p, buf) < 0)
- return -1;
-#endif /* TEST_DVB_SPU */
- this->subtitle_type = BUF_SPU_DVD;
-
- /* DVD SPU */
- buf->content = p+1;
- buf->size = this->packet_len-1;
-
- buf->type = BUF_SPU_DVD + spu_id;
- buf->decoder_flags |= BUF_FLAG_SPECIAL;
- buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE;
- buf->decoder_info[2] = SPU_DVD_SUBTYPE_PACKAGE;
- buf->pts = this->pts;
-
- this->video_fifo->put (this->video_fifo, buf);
-
- return -1;
- }
-
- if ((p[0]&0xF0) == 0x80) {
-
- track = p[0] & 0x0F; /* hack : ac3 track */
-
- buf->decoder_info[1] = p[1]; /* Number of frame headers */
- buf->decoder_info[2] = p[2] << 8 | p[3]; /* First access unit pointer */
-
- buf->content = p+4;
- buf->size = this->packet_len-4;
- if (track & 0x8) {
- buf->type = BUF_AUDIO_DTS + (track & 0x07); /* DVDs only have 8 tracks */
- } else {
- buf->type = BUF_AUDIO_A52 + track;
- }
- buf->pts = this->pts;
-
- if (this->audio_fifo) {
- check_newpts( this, buf, PTS_AUDIO );
- track_audio_stream_change (this, buf);
- this->audio_fifo->put (this->audio_fifo, buf);
- return -1;
- } else {
- buf->free_buffer(buf);
- return -1;
- }
-
- } else if ((p[0]&0xf0) == 0xa0) {
-
- int pcm_offset;
- int number_of_frame_headers;
- int first_access_unit_pointer;
- int audio_frame_number;
- int bits_per_sample;
- int sample_rate;
- int num_channels;
- int dynamic_range;
-
- /*
- * found in http://members.freemail.absa.co.za/ginggs/dvd/mpeg2_lpcm.txt
- * appears to be correct.
- */
-
- track = p[0] & 0x0F;
- number_of_frame_headers = p[1];
- /* unknown = p[2]; */
- first_access_unit_pointer = p[3];
- audio_frame_number = p[4];
-
- /*
- * 000 => mono
- * 001 => stereo
- * 010 => 3 channel
- * ...
- * 111 => 8 channel
- */
- num_channels = (p[5] & 0x7) + 1;
- sample_rate = p[5] & 0x10 ? 96000 : 48000;
- switch ((p[5]>>6) & 3) {
- case 3: /* illegal, use 16-bits? */
- default:
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "illegal lpcm sample format (%d), assume 16-bit samples\n", (p[5]>>6) & 3 );
- case 0: bits_per_sample = 16; break;
- case 1: bits_per_sample = 20; break;
- case 2: bits_per_sample = 24; break;
- }
- dynamic_range = p[6];
-
- /* send lpcm config byte */
- buf->decoder_flags |= BUF_FLAG_SPECIAL;
- buf->decoder_info[1] = BUF_SPECIAL_LPCM_CONFIG;
- buf->decoder_info[2] = p[5];
-
- pcm_offset = 7;
-
- buf->content = p+pcm_offset;
- buf->size = this->packet_len-pcm_offset;
- buf->type = BUF_AUDIO_LPCM_BE + track;
- buf->pts = this->pts;
-
- if (this->audio_fifo) {
- check_newpts( this, buf, PTS_AUDIO );
- track_audio_stream_change (this, buf);
- this->audio_fifo->put (this->audio_fifo, buf);
- return -1;
- } else {
- buf->free_buffer(buf);
- return -1;
- }
- }
-
- buf->free_buffer(buf);
- return -1;
-}
-
-/*
- * detect_h264()
- *
- * Detect video codec (MPEG2 or H.264)
- */
-static int detect_h264(uint8_t *data)
-{
- /* H.264 detection */
- if (data[0] == 0 && data[1] == 0 && data[2] == 1) {
- if (data[3] == NAL_AUD) {
- LOGMSG("H.264 scanner: Possible H.264 NAL AUD");
- return BUF_VIDEO_H264;
- }
- if (data[3] == 0) {
- LOGDBG("H.264 scanner: Possible MPEG2 start code PICTURE (0x00)");
- return BUF_VIDEO_MPEG;
- }
- if (data[3] >= 0x80) {
- LOGDBG("H.264 scanner: Possible MPEG2 start code (0x%02x)", data[3]);
- return BUF_VIDEO_MPEG;
- }
- LOGMSG("H.264 scanner: Unregonized header 00 00 01 %02x", data[3]);
- }
-
- return 0;
-}
-
-static int32_t parse_video_stream(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf)
-{
- int32_t result;
-
- result = parse_pes_for_pts(this, p, buf);
- if (result < 0) return -1;
-
- p += result;
-
- if (this->video_type == 0) {
- this->video_type = detect_h264(p);
- }
-
- buf->type = this->video_type ?: BUF_VIDEO_MPEG;
- buf->pts = this->pts;
- buf->decoder_info[0] = this->pts - this->dts;
-
- /* MPEG2 */
- if (this->video_type == BUF_VIDEO_MPEG) {
- /* Special handling for FFMPEG MPEG2 decoder */
- if (this->ffmpeg_mpeg2_decoder) {
- uint8_t type = pes_get_picture_type(buf->content, buf->size);
- if (type) {
- /* signal FRAME_END to decoder */
- post_frame_end(this, buf);
- /* for some reason ffmpeg mpeg2 decoder does not understand pts'es in B frames ?
- * (B-frame pts's are smaller than in previous P-frame)
- * Anyway, without this block of code B frames with pts are dropped. */
- if (type == B_FRAME)
- buf->pts = 0;
- }
- }
- }
-
- /* H.264 */
- else if (this->video_type == BUF_VIDEO_H264) {
- /* Access Unit Delimiter */
- if (IS_NAL_AUD(p))
- post_frame_end (this, buf);
-
- /* Check for end of still image.
- VDR ensures that H.264 still images end with an end of sequence NAL unit */
- if (buf->size > 4) {
- uint8_t *end = buf->content + buf->size;
- if (IS_NAL_END_SEQ(end-4)) {
- LOGMSG("post_frame_h264: Still frame ? (frame ends with end of sequence NAL unit)");
- buf->decoder_flags |= BUF_FLAG_FRAME_END;
- }
- }
- }
-
- buf->content = p;
- buf->size = this->packet_len;
-
- check_newpts( this, buf, PTS_VIDEO );
-
- this->video_fifo->put (this->video_fifo, buf);
-
- return -1;
-}
-
-static int32_t parse_audio_stream(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf)
-{
- int track;
- int32_t result;
-
- result = parse_pes_for_pts(this, p, buf);
- if (result < 0) return -1;
-
- p += result;
-
- track = this->stream_id & 0x1f;
-
- buf->content = p;
- buf->size = this->packet_len;
- buf->type = BUF_AUDIO_MPEG + track;
- buf->pts = this->pts;
-
- if (this->audio_fifo) {
- check_newpts( this, buf, PTS_AUDIO );
- track_audio_stream_change (this, buf);
- this->audio_fifo->put (this->audio_fifo, buf);
- } else {
- buf->free_buffer(buf);
- }
-
- return -1;
-}
-
-/*
- * interface
- */
-
-static int demux_xvdr_send_chunk (demux_plugin_t *this_gen)
-{
- demux_xvdr_t *this = (demux_xvdr_t *) this_gen;
-
- demux_xvdr_parse_pack(this);
-
- return this->status;
-}
-
-static void demux_xvdr_dispose (demux_plugin_t *this_gen)
-{
- demux_xvdr_t *this = (demux_xvdr_t *) this_gen;
-
- free (this);
-}
-
-static int demux_xvdr_get_status (demux_plugin_t *this_gen)
-{
- demux_xvdr_t *this = (demux_xvdr_t *) this_gen;
-
- return this->status;
-}
-
-static void demux_xvdr_send_headers (demux_plugin_t *this_gen)
-{
- demux_xvdr_t *this = (demux_xvdr_t *) this_gen;
-
- this->video_fifo = this->stream->video_fifo;
- this->audio_fifo = this->stream->audio_fifo;
-
- /*
- * send start buffer
- */
-
- _x_demux_control_start(this->stream);
-
- this->status = DEMUX_OK;
-
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE, 5000000);
-}
-
-
-static int demux_xvdr_seek (demux_plugin_t *this_gen,
- off_t start_pos, int start_time, int playing)
-{
- demux_xvdr_t *this = (demux_xvdr_t *) this_gen;
-
- /*
- * now start demuxing
- */
- this->send_newpts = 1;
- this->video_type = 0;
- this->audio_type = 0;
- this->subtitle_type = 0;
- this->bih_posted = 0;
- ts_data_dispose(&this->ts_data);
-
- if (!playing) {
-
- this->buf_flag_seek = 0;
- this->status = DEMUX_OK;
- this->last_pts[0] = 0;
- this->last_pts[1] = 0;
- } else {
- this->buf_flag_seek = 1;
- this->last_vpts = INT64_C(-1);
- _x_demux_flush_engine(this->stream);
- }
-
- return this->status;
-}
-
-/*
- * demux class
- */
-
-static int demux_xvdr_get_stream_length (demux_plugin_t *this_gen)
-{
- return 0;
-}
-
-static uint32_t demux_xvdr_get_capabilities(demux_plugin_t *this_gen)
-{
- return DEMUX_CAP_NOCAP;
-}
-
-static int demux_xvdr_get_optional_data(demux_plugin_t *this_gen,
- void *data, int data_type)
-{
- return DEMUX_OPTIONAL_UNSUPPORTED;
-}
-
-static demux_plugin_t *demux_xvdr_open_plugin (demux_class_t *class_gen,
- xine_stream_t *stream,
- input_plugin_t *input_gen)
-{
- input_plugin_t *input = (input_plugin_t *) input_gen;
- demux_xvdr_t *this;
- const char *mrl = input->get_mrl(input);
-
- if (strncmp(mrl, MRL_ID ":/", MRL_ID_LEN + 2 ) &&
- strncmp(mrl, MRL_ID "+pipe://", MRL_ID_LEN + 8) &&
- strncmp(mrl, MRL_ID "+tcp://", MRL_ID_LEN + 7) &&
- strncmp(mrl, MRL_ID "+udp://", MRL_ID_LEN + 7) &&
- strncmp(mrl, MRL_ID "+rtp://", MRL_ID_LEN + 7))
- return NULL;
-
- this = calloc(1, sizeof(demux_xvdr_t));
- this->stream = stream;
- this->input = input;
-
- this->demux_plugin.send_headers = demux_xvdr_send_headers;
- this->demux_plugin.send_chunk = demux_xvdr_send_chunk;
- this->demux_plugin.seek = demux_xvdr_seek;
- this->demux_plugin.dispose = demux_xvdr_dispose;
- this->demux_plugin.get_status = demux_xvdr_get_status;
- this->demux_plugin.get_stream_length = demux_xvdr_get_stream_length;
- this->demux_plugin.get_capabilities = demux_xvdr_get_capabilities;
- this->demux_plugin.get_optional_data = demux_xvdr_get_optional_data;
- this->demux_plugin.demux_class = class_gen;
-
- this->status = DEMUX_FINISHED;
-
- detect_video_decoders(this);
-
- return &this->demux_plugin;
-}
-
-#if DEMUXER_PLUGIN_IFACE_VERSION < 27
-static const char *demux_xvdr_get_description (demux_class_t *this_gen)
-{
- return MRL_ID " demux plugin";
-}
-
-static const char *demux_xvdr_get_identifier (demux_class_t *this_gen)
-{
- return MRL_ID;
-}
-
-static const char *demux_xvdr_get_extensions (demux_class_t *this_gen)
-{
- return NULL;
-}
-
-static const char *demux_xvdr_get_mimetypes (demux_class_t *this_gen)
-{
- return NULL;
-}
-
-static void demux_xvdr_class_dispose (demux_class_t *this_gen)
-{
- demux_xvdr_class_t *this = (demux_xvdr_class_t *) this_gen;
-
- free (this);
-}
-#endif
-
-void *demux_xvdr_init_class (xine_t *xine, void *data)
-{
- demux_xvdr_class_t *this;
-
- this = calloc(1, sizeof(demux_xvdr_class_t));
- this->config = xine->config;
- this->xine = xine;
-
- this->demux_class.open_plugin = demux_xvdr_open_plugin;
-#if DEMUXER_PLUGIN_IFACE_VERSION < 27
- this->demux_class.get_description = demux_xvdr_get_description;
- this->demux_class.get_identifier = demux_xvdr_get_identifier;
- this->demux_class.get_mimetypes = demux_xvdr_get_mimetypes;
- this->demux_class.get_extensions = demux_xvdr_get_extensions;
- this->demux_class.dispose = demux_xvdr_class_dispose;
-#else
- this->demux_class.description = N_("XVDR demux plugin");
- this->demux_class.identifier = MRL_ID;
- this->demux_class.mimetypes = NULL;
- this->demux_class.extensions =
- MRL_ID":/ "
- MRL_ID"+pipe:/ "
- MRL_ID"+tcp:/ "
- MRL_ID"+udp:/ "
- MRL_ID"+rtp:/ "
- MRL_ID"+slave:/";
- this->demux_class.dispose = default_demux_class_dispose;
-#endif
-
- return this;
-}
-
-
diff --git a/xine/demux_xvdr_tsdata.c b/xine/demux_xvdr_tsdata.c
deleted file mode 100644
index 38904a97..00000000
--- a/xine/demux_xvdr_tsdata.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * demux_xvdr_tsdata.h: data for MPEG-TS demuxer
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: demux_xvdr_tsdata.c,v 1.1 2009-02-24 19:50:42 phintuka Exp $
- *
- */
-
-#include <stdlib.h>
-
-#include <xine/buffer.h>
-
-#define LOG_MODULENAME "[demux_vdr] "
-#define SysLogLevel iSysLogLevel
-#include "../logdefs.h"
-
-#include "../tools/ts.h"
-#include "ts2es.h"
-
-#include "demux_xvdr_tsdata.h"
-
-static void ts_data_ts2es_reset(ts_data_t *ts_data)
-{
- int i;
-
- ts2es_dispose(ts_data->video);
- ts_data->video = NULL;
-
- for (i = 0; ts_data->audio[i]; i++) {
- ts2es_dispose(ts_data->audio[i]);
- ts_data->audio[i] = NULL;
- }
-
- for (i = 0; ts_data->spu[i]; i++) {
- ts2es_dispose(ts_data->spu[i]);
- ts_data->spu[i] = NULL;
- }
-}
-
-void ts_data_ts2es_init(ts_data_t **ts_data, fifo_buffer_t *video_fifo, fifo_buffer_t *audio_fifo)
-{
- if (*ts_data)
- ts_data_ts2es_reset(*ts_data);
- else
- *ts_data = calloc (1, sizeof(ts_data_t));
-
- ts_data_t *this = *ts_data;
- int i;
-
- if (video_fifo) {
- if (this->pmt.video_pid != INVALID_PID)
- this->video = ts2es_init(video_fifo, this->pmt.video_type, 0);
-
- for (i=0; i < this->pmt.spu_tracks_count; i++)
- this->spu[i] = ts2es_init(video_fifo, STREAM_DVBSUB, i);
- }
-
- if (audio_fifo) {
- for (i=0; i < this->pmt.audio_tracks_count; i++)
- this->audio[i] = ts2es_init(audio_fifo, this->pmt.audio_tracks[i].type, i);
- }
-}
-
-void ts_data_flush(ts_data_t *ts_data)
-{
- if (ts_data) {
- int i;
-
- if (ts_data->video)
- ts2es_flush(ts_data->video);
-
- for (i = 0; ts_data->audio[i]; i++)
- ts2es_flush(ts_data->audio[i]);
-
- for (i = 0; ts_data->spu[i]; i++)
- ts2es_flush(ts_data->spu[i]);
- }
-}
-
-void ts_data_dispose(ts_data_t **ts_data)
-{
- if (*ts_data) {
-
- ts_data_ts2es_reset(*ts_data);
-
- free(*ts_data);
- *ts_data = NULL;
- }
-}
diff --git a/xine/demux_xvdr_tsdata.h b/xine/demux_xvdr_tsdata.h
deleted file mode 100644
index 96a1b893..00000000
--- a/xine/demux_xvdr_tsdata.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * demux_xvdr_tsdata.h: data for MPEG-TS demuxer
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: demux_xvdr_tsdata.h,v 1.1 2009-02-24 19:50:42 phintuka Exp $
- *
- */
-
-#ifndef _DEMUX_XVDR_TSDATA_H_
-#define _DEMUX_XVDR_TSDATA_H_
-
-struct ts2es_s;
-
-struct ts_data_s {
- uint16_t pmt_pid;
- uint16_t program_number;
-
- pmt_data_t pmt;
-
- struct ts2es_s *video;
- struct ts2es_s *audio[TS_MAX_AUDIO_TRACKS];
- struct ts2es_s *spu[TS_MAX_SPU_TRACKS];
-};
-
-typedef struct ts_data_s ts_data_t;
-
-void ts_data_ts2es_init (ts_data_t **ts_data, fifo_buffer_t *video_fifo, fifo_buffer_t *audio_fifo);
-void ts_data_flush (ts_data_t *ts_data);
-void ts_data_dispose (ts_data_t **ts_data);
-
-
-#endif /* _DEMUX_XVDR_TSDATA_H_ */
diff --git a/xine/osd_manager.c b/xine/osd_manager.c
deleted file mode 100644
index a7d0d6b4..00000000
--- a/xine/osd_manager.c
+++ /dev/null
@@ -1,729 +0,0 @@
-/*
- * osd_manager.c:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: osd_manager.c,v 1.13 2009-06-02 14:17:05 phintuka Exp $
- *
- */
-
-#include <stdlib.h>
-#include <pthread.h>
-
-#define XINE_ENGINE_INTERNAL
-#include <xine/xine_internal.h>
-#include <xine/video_out.h>
-
-#include "../xine_osd_command.h"
-#include "../xine_input_vdr.h"
-
-#include "../tools/rle.h"
-
-#include "vo_props.h"
-#include "osd_manager.h"
-
-/*#define LOGOSD(x...) LOGMSG(x)*/
-#define LOGOSD(x...)
-
-static const char log_module_input_osd[] = "[input_osd] ";
-#define LOG_MODULENAME log_module_input_osd
-#define SysLogLevel iSysLogLevel
-
-#include "../logdefs.h"
-
-
-typedef struct {
- int handle; /* xine-lib overlay handle */
- osd_command_t cmd; /* Full OSD data: last OSD_Set_RLE event */
-
- uint16_t extent_width; /* output size this OSD was designed for */
- uint16_t extent_height;
-
- int64_t last_changed_vpts;
-} osd_data_t;
-
-typedef struct osd_manager_impl_s {
- osd_manager_t mgr;
-
- pthread_mutex_t lock;
- uint8_t ticket_acquired;
- xine_stream_t *stream;
-
- uint16_t video_width;
- uint16_t video_height;
- uint8_t vo_scaling;
-
- osd_data_t osd[MAX_OSD_OBJECT];
-
-} osd_manager_impl_t;
-
-/************************************* Tools ************************************/
-
-/*
- * acquire_ticket()
- */
-static void acquire_ticket(osd_manager_impl_t *this)
-{
- if (!this->ticket_acquired) {
- this->stream->xine->port_ticket->acquire(this->stream->xine->port_ticket, 1);
- this->ticket_acquired = 1;
- }
-}
-
-static void release_ticket(osd_manager_impl_t *this)
-{
- if (this->ticket_acquired) {
- this->stream->xine->port_ticket->release(this->stream->xine->port_ticket, 1);
- this->ticket_acquired = 0;
- }
-}
-
-/*
- * get_overlay_manager()
- */
-video_overlay_manager_t *get_ovl_manager(osd_manager_impl_t *this)
-{
- /* Get overlay manager. We need ticket ... */
- acquire_ticket(this);
- video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager(this->stream->video_out);
- if (!ovl_manager) {
- LOGMSG("Stream has no overlay manager !");
- return NULL;
- }
- return ovl_manager;
-}
-
-/*
- * palette_argb_to_ayuv()
- */
-
-#define saturate(x,min,max) ( (x)<(min) ? (min) : (x)>(max) ? (max) : (x))
-
-static void palette_argb_to_ayuv(xine_clut_t *clut, int colors)
-{
- if (clut && colors>0) {
- int c;
- for (c=0; c<colors; c++) {
- int R = clut[c].r;
- int G = clut[c].g;
- int B = clut[c].b;
- int Y = (( + 66*R + 129*G + 25*B + 0x80) >> 8) + 16;
- int CR = (( + 112*R - 94*G - 18*B + 0x80) >> 8) + 128;
- int CB = (( - 38*R - 74*G + 112*B + 0x80) >> 8) + 128;
- clut[c].y = saturate( Y, 16, 235);
- clut[c].cb = saturate(CB, 16, 240);
- clut[c].cr = saturate(CR, 16, 240);
- }
- }
-}
-
-/*
- * clear_osdcmd()
- *
- * - free allocated memory from osd_command_t
- */
-static void clear_osdcmd(osd_command_t *cmd)
-{
- free(cmd->data);
- cmd->data = NULL;
- free(cmd->palette);
- cmd->palette = NULL;
-}
-
-/*
- * osdcmd_to_overlay()
- *
- * - fill xine-lib vo_overlay_t from osd_command_t
- */
-static void osdcmd_to_overlay(vo_overlay_t *ovl, osd_command_t *cmd)
-{
- int i;
-
- ovl->rle = (rle_elem_t*)cmd->data;
- ovl->data_size = cmd->datalen;
- ovl->num_rle = cmd->datalen / 4;
-
- ovl->x = cmd->x;
- ovl->y = cmd->y;
- ovl->width = cmd->w;
- ovl->height = cmd->h;
-
- /* palette */
- for (i=0; i<cmd->colors; i++) {
- ovl->color[i] = (*(uint32_t*)(cmd->palette + i)) & 0x00ffffff;
- ovl->trans[i] = (cmd->palette[i].alpha + 0x7)/0xf;
- }
- ovl->rgb_clut = cmd->flags & OSDFLAG_YUV_CLUT ? 0 : 1;
-
- ovl->unscaled = cmd->flags & OSDFLAG_UNSCALED ? 1 : 0;
-
- ovl->hili_top = ovl->hili_bottom = ovl->hili_left = ovl->hili_right = -1;
-}
-
-/*
- * osdcmd_scale()
- *
- * Scale OSD_Set_RLE data
- * - modified fields: x, y, w, h, (RLE) data and datalen
- * - old RLE data is stored to osd_data_t *osd
- */
-static void osdcmd_scale(osd_manager_impl_t *this, osd_command_t *cmd,
- osd_data_t *osd, int output_width, int output_height)
-{
- LOGOSD("Size out of margins, rescaling rle image");
-
- /* new position and size */
- int new_x = cmd->x * this->video_width / osd->extent_width;
- int new_y = cmd->y * this->video_height / osd->extent_height;
- int x2 = cmd->x + cmd->w + 1;
- int y2 = cmd->y + cmd->h + 1;
- x2 = ((x2+1) * this->video_width - 1) / osd->extent_width;
- y2 = ((y2+1) * this->video_height - 1) / osd->extent_height;
- int new_w = x2 - new_x - 1;
- int new_h = y2 - new_y - 1;
-
- /* store original RLE data */
- osd->cmd.data = cmd->data;
- osd->cmd.datalen = cmd->datalen;
-
- /* scale */
- int rle_elems = cmd->datalen / sizeof(xine_rle_elem_t);
- cmd->data = rle_scale_nearest(cmd->data, &rle_elems, cmd->w, cmd->h,
- new_w, new_h);
- cmd->datalen = rle_elems * sizeof(xine_rle_elem_t);
-
- cmd->x = new_x;
- cmd->y = new_y;
- cmd->w = new_w;
- cmd->h = new_h;
-}
-
-/*
- * osd_exec_vpts()
- *
- * - calculate execution time (vpts) for OSD update
- */
-static int64_t osd_exec_vpts(osd_manager_impl_t *this, osd_command_t *cmd)
-{
- int64_t vpts = 0; /* now */
-
- /* calculate exec time */
- if (cmd->pts || cmd->delay_ms) {
- int64_t now = xine_get_current_vpts(this->stream);
-
- if (cmd->pts)
- vpts = cmd->pts + this->stream->metronom->get_option(this->stream->metronom, METRONOM_VPTS_OFFSET);
- else
- vpts = this->osd[cmd->wnd].last_changed_vpts + cmd->delay_ms*90;
-
- /* execution time must be in future */
- if (vpts < now)
- vpts = 0;
-
- /* limit delay to 5 seconds */
- if (vpts > now + 5*90000)
- vpts = vpts + 5*90000;
-
- LOGOSD("OSD Command %d scheduled to +%dms", cmd->cmd, (int)(vpts>now ? vpts-now : 0)/90);
- }
-
- return vpts;
-}
-
-/***************************** OSD command handlers *****************************/
-
-/*
- * exec_osd_size()
- *
- * - set the assumed full OSD size
- */
-static int exec_osd_size(osd_manager_impl_t *this, osd_command_t *cmd)
-{
- osd_data_t *osd = &this->osd[cmd->wnd];
- osd->extent_width = cmd->w;
- osd->extent_height = cmd->h;
-
- acquire_ticket(this);
-
- xine_video_port_t *video_out = this->stream->video_out;
- this->vo_scaling = 0;
- if (video_out->get_capabilities(video_out) & VO_CAP_OSDSCALING) {
- this->vo_scaling = 1;
- }
-
- return CONTROL_OK;
-}
-
-/*
- * exec_osd_nop()
- *
- * - update last changed time of an OSD window
- */
-static int exec_osd_nop(osd_manager_impl_t *this, osd_command_t *cmd)
-{
- this->osd[cmd->wnd].last_changed_vpts = xine_get_current_vpts(this->stream);
- return CONTROL_OK;
-}
-
-/*
- * exec_osd_flush()
- *
- * - commit all pending OSD events immediately
- */
-static int exec_osd_flush(osd_manager_impl_t *this, osd_command_t *cmd)
-{
- video_overlay_manager_t *ovl_manager = get_ovl_manager(this);
- if (!ovl_manager)
- return CONTROL_PARAM_ERROR;
-
- ovl_manager->flush_events(ovl_manager);
-
- return CONTROL_OK;
-}
-
-/*
- * exec_osd_close()
- *
- */
-static int exec_osd_close(osd_manager_impl_t *this, osd_command_t *cmd)
-{
- video_overlay_manager_t *ovl_manager = get_ovl_manager(this);
- osd_data_t *osd = &this->osd[cmd->wnd];
- int handle = osd->handle;
-
- if (cmd->flags & OSDFLAG_REFRESH) {
- LOGDBG("Ignoring OSD_Close(OSDFLAG_REFRESH)");
- return CONTROL_OK;
- }
-
- if (handle < 0) {
- LOGMSG("OSD_Close(%d): non-existing OSD !", cmd->wnd);
- return CONTROL_PARAM_ERROR;
- }
-
- if (!ovl_manager)
- return CONTROL_PARAM_ERROR;
-
- video_overlay_event_t ov_event = {0};
- ov_event.event_type = OVERLAY_EVENT_FREE_HANDLE;
- ov_event.vpts = osd_exec_vpts(this, cmd);
- ov_event.object.handle = handle;
-
- while (ovl_manager->add_event(ovl_manager, (void *)&ov_event) < 0) {
- LOGMSG("OSD_Close(%d): overlay manager queue full !", cmd->wnd);
- ovl_manager->flush_events(ovl_manager);
- }
-
- clear_osdcmd(&osd->cmd);
- osd->handle = -1;
- osd->extent_width = 720;
- osd->extent_height = 576;
- osd->last_changed_vpts = 0;
-
- return CONTROL_OK;
-}
-
-/*
- * exec_osd_set_rle()
- *
- */
-static int exec_osd_set_rle(osd_manager_impl_t *this, osd_command_t *cmd)
-{
- video_overlay_manager_t *ovl_manager = get_ovl_manager(this);
- video_overlay_event_t ov_event = {0};
- vo_overlay_t ov_overlay = {0};
- osd_data_t *osd = &this->osd[cmd->wnd];
- int use_unscaled = 0;
- int rle_scaled = 0;
- int unscaled_supported = 1;
- int handle = osd->handle;
-
- if (!ovl_manager)
- return CONTROL_PARAM_ERROR;
-
- this->stream->video_out->enable_ovl(this->stream->video_out, 1);
-
- /* get / allocate OSD handle */
- if (handle < 0) {
- handle = ovl_manager->get_handle(ovl_manager,0);
- osd->handle = handle;
- osd->extent_width = osd->extent_width ?: 720;
- osd->extent_height = osd->extent_height ?: 576;
- osd->last_changed_vpts = 0;
- }
-
- /* fill SHOW event */
- ov_event.event_type = OVERLAY_EVENT_SHOW;
- ov_event.vpts = osd_exec_vpts(this, cmd);
- ov_event.object.handle = handle;
- ov_event.object.overlay = &ov_overlay;
- ov_event.object.object_type = 1; /* menu */
-
- /* check for unscaled OSD capability and request */
- xine_video_port_t *video_out = this->stream->video_out;
- if (! (video_out->get_capabilities(video_out) & VO_CAP_UNSCALED_OVERLAY))
- unscaled_supported = 0;
- else if (cmd->flags & OSDFLAG_UNSCALED)
- use_unscaled = 1;
-
- /* store osd for later rescaling (done if video size changes) */
-
- clear_osdcmd(&osd->cmd);
-
- memcpy(&osd->cmd, cmd, sizeof(osd_command_t));
- osd->cmd.data = NULL;
- if (cmd->palette) {
- /* RGB -> YUV */
- if(!(cmd->flags & OSDFLAG_YUV_CLUT))
- palette_argb_to_ayuv(cmd->palette, cmd->colors);
- cmd->flags |= OSDFLAG_YUV_CLUT;
-
- osd->cmd.palette = malloc(sizeof(xine_clut_t)*cmd->colors);
- memcpy(osd->cmd.palette, cmd->palette, 4*cmd->colors);
- osd->cmd.flags |= OSDFLAG_YUV_CLUT;
- }
-
- /* request OSD scaling from video_out layer */
- this->vo_scaling = 0;
- if (video_out->get_capabilities(video_out) & VO_CAP_OSDSCALING) {
- video_out->set_property(video_out, VO_PROP_OSD_SCALING, cmd->scaling ? 1 : 0);
- this->vo_scaling = 1;
- }
-
- /* if video size differs from expected (VDR osd is designed for 720x576),
- scale osd to video size or use unscaled (display resolution)
- blending */
-
- /* scale OSD ? */
- if (!this->vo_scaling && !use_unscaled) {
- int w_diff = (this->video_width < ((osd->extent_width *242) >> 8) /* 95% */) ? -1 :
- (this->video_width > ((osd->extent_width *280) >> 8) /* 110% */) ? 1 : 0;
- int h_diff = (this->video_height < ((osd->extent_height*242) >> 8) /* 95% */) ? -1 :
- (this->video_height > ((osd->extent_height*280) >> 8) /* 110% */) ? 1 : 0;
-
- if (w_diff || h_diff) {
-
- /* unscaled OSD instead of downscaling ? */
- if (w_diff < 0 || h_diff < 0)
- if (cmd->flags & OSDFLAG_UNSCALED_LOWRES)
- if (0 < (use_unscaled = unscaled_supported))
- LOGOSD("Size out of margins, using unscaled overlay");
-
- if (!use_unscaled && cmd->scaling > 0) {
- osdcmd_scale(this, cmd, osd, this->video_width, this->video_height);
- rle_scaled = 1;
- }
- }
- }
-
- /* Scale unscaled OSD ? */
- if (!this->vo_scaling && use_unscaled && cmd->scaling > 0) {
- int win_width = video_out->get_property(video_out, VO_PROP_WINDOW_WIDTH);
- int win_height = video_out->get_property(video_out, VO_PROP_WINDOW_HEIGHT);
-
- if (win_width >= 360 && win_height >= 288) {
- if (win_width != osd->extent_width || win_height != osd->extent_height) {
- osdcmd_scale(this, cmd, osd, win_width, win_height);
- rle_scaled = 1;
- }
- }
- }
-
- /* fill ov_overlay */
- osdcmd_to_overlay(&ov_overlay, cmd);
- ov_overlay.unscaled = use_unscaled;
-
- /* tag this overlay */
- ov_overlay.hili_rgb_clut = VDR_OSD_MAGIC;
-
- /* fill extra data */
- const vdr_osd_extradata_t extra_data = {
- extent_width: osd->extent_width,
- extent_height: osd->extent_height,
- layer: cmd->layer,
- scaling: cmd->scaling
- };
- memcpy(ov_overlay.hili_color, &extra_data, sizeof(extra_data));
-
-#ifdef VO_CAP_CUSTOM_EXTENT_OVERLAY
- if (cmd->scaling && !rle_scaled) {
- ov_overlay.extent_width = osd->extent_width;
- ov_overlay.extent_height = osd->extent_height;
- }
-#endif
-
- /* if no scaling was required, we may still need to re-center OSD */
- if (!this->vo_scaling && !rle_scaled) {
- if (this->video_width != osd->extent_width)
- ov_overlay.x += (this->video_width - osd->extent_width)/2;
- if (this->video_height != osd->extent_height)
- ov_overlay.y += (this->video_height - osd->extent_height)/2;
- }
-
- /* store rle for later scaling (done if video size changes) */
- if (!rle_scaled /* if scaled, we already have a copy (original data) */ ) {
- osd->cmd.data = malloc(cmd->datalen);
- memcpy(osd->cmd.data, cmd->data, cmd->datalen);
- }
- cmd->data = NULL; /* we 'consume' data (ownership goes for xine-lib osd manager) */
-
- /* send event to overlay manager */
- while (ovl_manager->add_event(ovl_manager, (void *)&ov_event) < 0) {
- LOGMSG("OSD_Set_RLE(%d): overlay manager queue full !", cmd->wnd);
- ovl_manager->flush_events(ovl_manager);
- }
-
- osd->last_changed_vpts = ov_event.vpts ?: xine_get_current_vpts(this->stream);
-
- return CONTROL_OK;
-}
-
-/*
- * exec_osd_set_palette()
- *
- * - replace palette of an already existing OSD
- */
-static int exec_osd_set_palette(osd_manager_impl_t *this, osd_command_t *cmd)
-{
- osd_data_t *osd = &this->osd[cmd->wnd];
-
- if (!osd->cmd.data) {
- LOGMSG("OSD_SetPalette(%d): old RLE data missing !", cmd->wnd);
- return CONTROL_PARAM_ERROR;
- }
- if (!cmd->palette) {
- LOGMSG("OSD_SetPalette(%d): new palette missing !", cmd->wnd);
- return CONTROL_PARAM_ERROR;
- }
-
- /* use cached event to re-create Set_RLE command with modified palette */
- osd_command_t tmp;
- /* steal the original command */
- memcpy(&tmp, &osd->cmd, sizeof(osd_command_t));
- memset(&osd->cmd, 0, sizeof(osd_command_t));
-
- /* replace palette */
- tmp.cmd = OSD_Set_RLE;
- free(tmp.palette);
- tmp.palette = malloc(cmd->colors*sizeof(xine_rle_elem_t));
- memcpy(tmp.palette, cmd->palette, cmd->colors*sizeof(xine_rle_elem_t));
- tmp.colors = cmd->colors;
- tmp.pts = cmd->pts;
- tmp.delay_ms = cmd->delay_ms;
- tmp.flags |= cmd->flags & OSDFLAG_YUV_CLUT;
-
- /* redraw */
- int r = exec_osd_set_rle(this, &tmp);
- clear_osdcmd(&tmp);
- return r;
-}
-
-/*
- * exec_osd_move()
- *
- * - move existing OSD to new position
- */
-static int exec_osd_move(osd_manager_impl_t *this, osd_command_t *cmd)
-{
- osd_data_t *osd = &this->osd[cmd->wnd];
-
- if (!osd->cmd.data) {
- LOGMSG("OSD_Move(%d): old RLE data missing !", cmd->wnd);
- return CONTROL_PARAM_ERROR;
- }
- if (!osd->cmd.palette) {
- LOGMSG("OSD_Move(%d): old palette missing !", cmd->wnd);
- return CONTROL_PARAM_ERROR;
- }
-
- /* use cached event to re-create Set_RLE command with modified palette */
- osd_command_t tmp;
- /* steal the original command */
- memcpy(&tmp, &osd->cmd, sizeof(osd_command_t));
- memset(&osd->cmd, 0, sizeof(osd_command_t));
-
- /* replace position */
- tmp.cmd = OSD_Set_RLE;
- tmp.x = cmd->x;
- tmp.y = cmd->y;
- tmp.pts = cmd->pts;
- tmp.delay_ms = cmd->delay_ms;
-
- /* redraw */
- int r = exec_osd_set_rle(this, &tmp);
- clear_osdcmd(&tmp);
- return r;
-}
-
-/*
- * exec_osd_command_internal()
- */
-static int exec_osd_command_internal(osd_manager_impl_t *this, struct osd_command_s *cmd)
-{
- LOGOSD("exec_osd_command %d", cmd->cmd);
-
- switch (cmd->cmd) {
- case OSD_Nop: return exec_osd_nop(this, cmd);
- case OSD_Size: return exec_osd_size(this, cmd);
- case OSD_SetPalette: return exec_osd_set_palette(this, cmd);
- case OSD_Move: return exec_osd_move(this, cmd);
- case OSD_Flush: return exec_osd_flush(this, cmd);
- case OSD_Set_RLE: return exec_osd_set_rle(this, cmd);
- case OSD_Close: return exec_osd_close(this, cmd);
- case OSD_Set_YUV:
- /* TODO */
- LOGMSG("OSD_Set_YUV not implemented !");
- return CONTROL_PARAM_ERROR;
- }
-
- LOGMSG("Unknown OSD command %d", cmd->cmd);
- return CONTROL_PARAM_ERROR;
-}
-
-/****************************** Interface handlers ******************************/
-
-/*
- * exec_osd_command()
- *
- * - handler for VDR-based osd_command_t events
- */
-static int exec_osd_command(osd_manager_t *this_gen,
- struct osd_command_s *cmd, xine_stream_t *stream)
-{
- osd_manager_impl_t *this = (osd_manager_impl_t*)this_gen;
- int result;
-
- if (!cmd || !stream) {
- LOGMSG("exec_osd_command: Stream not initialized !");
- return CONTROL_DISCONNECTED;
- }
- if (cmd->wnd >= MAX_OSD_OBJECT) {
- LOGMSG("exec_osd_command: OSD window handle %d out of range !", cmd->wnd);
- return CONTROL_PARAM_ERROR;
- }
-
- if (pthread_mutex_lock(&this->lock)) {
- LOGERR("exec_osd_command: mutex lock failed");
- return CONTROL_DISCONNECTED;
- }
-
- this->stream = stream;
- result = exec_osd_command_internal(this, cmd);
-
- release_ticket(this);
-
- pthread_mutex_unlock(&this->lock);
-
- return result;
-}
-
-/*
- * video_size_changed()
- */
-static void video_size_changed(osd_manager_t *this_gen, xine_stream_t *stream, int width, int height)
-{
- osd_manager_impl_t *this = (osd_manager_impl_t*)this_gen;
- int i;
-
- if (!stream) {
- LOGMSG("video_size_changed: Stream not initialized !");
- return;
- }
-
- if (width < 1 || height < 1) {
- LOGMSG("video_size_changed: Invalid video size %dx%d", width, height);
- return;
- }
-
- if (pthread_mutex_lock(&this->lock)) {
- LOGERR("video_size_changed: mutex lock failed");
- return;
- }
-
- if (this->video_width == width && this->video_height == height) {
- pthread_mutex_unlock(&this->lock);
- return;
- }
-
- LOGOSD("New video size (%dx%d->%dx%d)", this->video_width, this->video_height, width, height);
-
- this->stream = stream;
- this->video_width = width;
- this->video_height = height;
-
- /* just call exec_osd_command for all stored osd's.
- scaling is done automatically if required. */
- if (!this->vo_scaling)
- for (i = 0; i < MAX_OSD_OBJECT; i++)
- if (this->osd[i].handle >= 0 &&
- this->osd[i].cmd.data &&
- this->osd[i].cmd.scaling > 0) {
- osd_command_t tmp;
- memcpy(&tmp, &this->osd[i].cmd, sizeof(osd_command_t));
- memset(&this->osd[i].cmd, 0, sizeof(osd_command_t));
-
- exec_osd_command_internal(this, &tmp);
-
- clear_osdcmd(&tmp);
- }
-
- release_ticket(this);
- pthread_mutex_unlock(&this->lock);
-}
-
-/*
- * osd_manager_dispose()
- */
-static void osd_manager_dispose(osd_manager_t *this_gen, xine_stream_t *stream)
-{
- osd_manager_impl_t *this = (osd_manager_impl_t*)this_gen;
- int i;
-
- while (pthread_mutex_destroy(&this->lock) == EBUSY) {
- LOGMSG("osd_manager_dispose: lock busy ...");
- pthread_mutex_lock(&this->lock);
- pthread_mutex_unlock(&this->lock);
- }
-
- /* close all */
- for (i=0; i<MAX_OSD_OBJECT; i++) {
- if (this->osd[i].handle >= 0) {
- osd_command_t cmd = {
- .cmd = OSD_Close,
- .wnd = i,
- };
- LOGOSD("Closing osd %d", i);
- exec_osd_close(this, &cmd);
- }
- }
-
- release_ticket(this);
-
- free(this);
-}
-
-/*
- * init_osd_manager()
- *
- * - exported
- */
-osd_manager_t *init_osd_manager(void)
-{
- osd_manager_impl_t *this = calloc(1, sizeof(osd_manager_impl_t));
- int i;
-
- this->mgr.command = exec_osd_command;
- this->mgr.dispose = osd_manager_dispose;
- this->mgr.video_size_changed = video_size_changed;
-
- pthread_mutex_init(&this->lock, NULL);
-
- this->video_width = 720;
- this->video_height = 576;
-
- for (i = 0; i < MAX_OSD_OBJECT; i++)
- this->osd[i].handle = -1;
-
- return &this->mgr;
-}
diff --git a/xine/osd_manager.h b/xine/osd_manager.h
deleted file mode 100644
index d71336ed..00000000
--- a/xine/osd_manager.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * osd_manager.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: osd_manager.h,v 1.1 2008-12-06 16:17:18 phintuka Exp $
- *
- */
-
-#ifndef XINELIBOUTPUT_OSD_MANAGER_H_
-#define XINELIBOUTPUT_OSD_MANAGER_H_
-
-/*
- * OSD manager executes OSD control messages from VDR.
- * - cache OSD data
- * - scale OSD when required
- * - re-scale OSD when video size changes
- * - generate xine overlay events
- */
-
-struct osd_command_s;
-
-typedef struct osd_manager_s osd_manager_t;
-
-struct osd_manager_s {
- int (*command)(osd_manager_t *, struct osd_command_s *, xine_stream_t *);
- void (*dispose)(osd_manager_t *, xine_stream_t *);
-
- void (*video_size_changed)(osd_manager_t *, xine_stream_t *, int width, int height);
-};
-
-osd_manager_t *init_osd_manager(void);
-
-
-#endif /* XINELIBOUTPUT_OSD_MANAGER_H_ */
diff --git a/xine/post.c b/xine/post.c
deleted file mode 100644
index 6c637634..00000000
--- a/xine/post.c
+++ /dev/null
@@ -1,901 +0,0 @@
-/*
- * Copyright (C) 2003 by Dirk Meyer
- *
- * This file is part of xine, a unix video player.
- *
- * xine is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * xine is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * The code is taken from xine-ui/src/xitk/post.c at changed to work with fbxine
- *
- * Modified for VDR xineliboutput plugin by Petri Hintukainen, 2006
- * - runtime re-configuration (load/unload, enable/disable)
- * - support for multiple streams
- * - support for mosaico post plugin (picture-in-picture)
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "post.h"
-
-#include <sys/types.h>
-#include <sys/syscall.h>
-#include <unistd.h>
-#include <errno.h>
-#include <syslog.h>
-
-#define LOG_MODULENAME "[xine-post] "
-#include "../logdefs.h"
-
-#define fe_t post_plugins_t
-
-typedef struct {
- xine_post_t *post;
- xine_post_api_t *api;
- xine_post_api_descr_t *descr;
- xine_post_api_parameter_t *param;
- char *param_data;
-
- int x;
- int y;
-
- int readonly;
-
- char **properties_names;
-} post_object_t;
-
-
-static int __pplugin_retrieve_parameters(post_object_t *pobj)
-{
- xine_post_in_t *input_api;
-
- if((input_api = (xine_post_in_t *) xine_post_input(pobj->post,
- "parameters"))) {
- xine_post_api_t *post_api;
- xine_post_api_descr_t *api_descr;
- xine_post_api_parameter_t *parm;
- int pnum = 0;
-
- post_api = (xine_post_api_t *) input_api->data;
-
- api_descr = post_api->get_param_descr();
-
- parm = api_descr->parameter;
- pobj->param_data = malloc(api_descr->struct_size);
-
- while(parm->type != POST_PARAM_TYPE_LAST) {
-
- post_api->get_parameters(pobj->post, pobj->param_data);
-
- if(!pnum)
- pobj->properties_names = (char **) calloc(2, sizeof(char *));
- else
- pobj->properties_names = (char **)
- realloc(pobj->properties_names, sizeof(char *) * (pnum + 2));
-
- pobj->properties_names[pnum] = strdup(parm->name);
- pobj->properties_names[pnum + 1] = NULL;
- pnum++;
- parm++;
- }
-
- pobj->api = post_api;
- pobj->descr = api_descr;
- pobj->param = api_descr->parameter;
-
- return 1;
- }
-
- return 0;
-}
-
-static void _pplugin_update_parameter(post_object_t *pobj)
-{
- pobj->api->set_parameters(pobj->post, pobj->param_data);
- pobj->api->get_parameters(pobj->post, pobj->param_data);
-}
-
-static void __pplugin_update_parameters(xine_post_t *post, char *args)
-{
- char *p;
- post_object_t pobj = {
- .post = post,
- };
-
- if(__pplugin_retrieve_parameters(&pobj)) {
- int i;
-
- if(pobj.properties_names && args && *args) {
- char *param;
-
- while((param = xine_strsep(&args, ",")) != NULL) {
-
- p = param;
-
- while((*p != '\0') && (*p != '='))
- p++;
-
- if(p && strlen(p)) {
- int param_num = 0;
-
- *p++ = '\0';
-
- while(pobj.properties_names[param_num]
- && strcasecmp(pobj.properties_names[param_num], param))
- param_num++;
-
- if(pobj.properties_names[param_num]) {
-
- pobj.param = pobj.descr->parameter;
- pobj.param += param_num;
- pobj.readonly = pobj.param->readonly;
-
- switch(pobj.param->type) {
- case POST_PARAM_TYPE_INT:
- if(!pobj.readonly) {
- if(pobj.param->enum_values) {
- char **values = pobj.param->enum_values;
- int i = 0;
-
- while(values[i]) {
- if(!strcasecmp(values[i], p)) {
- *(int *)(pobj.param_data + pobj.param->offset) = i;
- break;
- }
- i++;
- }
-
- if( !values[i] )
- *(int *)(pobj.param_data + pobj.param->offset) = (int) strtol(p, &p, 10);
- } else {
- *(int *)(pobj.param_data + pobj.param->offset) = (int) strtol(p, &p, 10);
- }
- _pplugin_update_parameter(&pobj);
- }
- break;
-
- case POST_PARAM_TYPE_DOUBLE:
- if(!pobj.readonly) {
- *(double *)(pobj.param_data + pobj.param->offset) = strtod(p, &p);
- _pplugin_update_parameter(&pobj);
- }
- break;
-
- case POST_PARAM_TYPE_CHAR:
- case POST_PARAM_TYPE_STRING:
- if(!pobj.readonly) {
- if(pobj.param->type == POST_PARAM_TYPE_CHAR) {
- int maxlen = pobj.param->size / sizeof(char);
-
- snprintf((char *)(pobj.param_data + pobj.param->offset), maxlen, "%s", p);
- _pplugin_update_parameter(&pobj);
- }
- else
- fprintf(stderr, "parameter type POST_PARAM_TYPE_STRING not supported yet.\n");
- }
- break;
-
- case POST_PARAM_TYPE_STRINGLIST: /* unsupported */
- if(!pobj.readonly)
- fprintf(stderr, "parameter type POST_PARAM_TYPE_STRINGLIST not supported yet.\n");
- break;
-
- case POST_PARAM_TYPE_BOOL:
- if(!pobj.readonly) {
- *(int *)(pobj.param_data + pobj.param->offset) = ((int) strtol(p, &p, 10)) ? 1 : 0;
- _pplugin_update_parameter(&pobj);
- }
- break;
- }
- } else {
- LOGMSG("Unknown post plugin parameter %s !", param);
- }
- }
- }
-
- i = 0;
-
- while(pobj.properties_names[i]) {
- free(pobj.properties_names[i]);
- i++;
- }
-
- free(pobj.properties_names);
- }
-
- free(pobj.param_data);
- }
-}
-
-/* -post <name>:option1=value1,option2=value2... */
-static post_element_t **pplugin_parse_and_load(fe_t *fe,
- int plugin_type,
- const char *pchain,
- int *post_elements_num)
-{
- post_element_t **post_elements = NULL;
-
- *post_elements_num = 0;
-
- if(pchain && strlen(pchain)) {
- char *post_chain, *freeme, *p;
-
- freeme = post_chain = strdup(pchain);
-
- while((p = xine_strsep(&post_chain, ";"))) {
-
- if(p && strlen(p)) {
- char *plugin, *args = NULL;
- xine_post_t *post;
-
- while(*p == ' ')
- p++;
-
- plugin = strdup(p);
-
- if((p = strchr(plugin, ':')))
- *p++ = '\0';
-
- if(p && (strlen(p) > 1))
- args = p;
-#if 0
- post = xine_post_init(fe->xine, plugin, 0,
- &fe->audio_port, &fe->video_port);
-#else
- if(plugin_type == XINE_POST_TYPE_VIDEO_COMPOSE) {
- post = xine_post_init(fe->xine, plugin, 2,
- &fe->audio_port, &fe->video_port);
- } else
- post = xine_post_init(fe->xine, plugin, 0,
- &fe->audio_port, &fe->video_port);
-#endif
-
- if (post && plugin_type) {
- if (post->type != plugin_type) {
- xine_post_dispose(fe->xine, post);
- post = NULL;
- }
- }
-
- if(post) {
-
- if(!(*post_elements_num))
- post_elements = (post_element_t **) calloc(2, sizeof(post_element_t *));
- else
- post_elements = (post_element_t **)
- realloc(post_elements, sizeof(post_element_t *) * ((*post_elements_num) + 2));
-
- post_elements[(*post_elements_num)] = calloc(1, sizeof(post_element_t));
- post_elements[(*post_elements_num)]->post = post;
- post_elements[(*post_elements_num)]->name = strdup(plugin);
-#if 1
- post_elements[(*post_elements_num)]->args = args ? strdup(args) : NULL;
- post_elements[(*post_elements_num)]->enable = 0;
-#endif
- (*post_elements_num)++;
- post_elements[(*post_elements_num)] = NULL;
-
- __pplugin_update_parameters(post, args);
- }
-
- free(plugin);
- }
- }
- free(freeme);
- }
-
- return post_elements;
-}
-
-void pplugin_parse_and_store_post(fe_t *fe, int plugin_type,
- const char *post_chain)
-{
- post_element_t ***_post_elements;
- int *_post_elements_num;
- post_element_t **posts = NULL;
- int num;
-
- switch(plugin_type) {
- case XINE_POST_TYPE_VIDEO_FILTER:
- _post_elements = &fe->post_video_elements;
- _post_elements_num = &fe->post_video_elements_num;
- break;
- case XINE_POST_TYPE_VIDEO_COMPOSE:
- _post_elements = &fe->post_pip_elements;
- _post_elements_num = &fe->post_pip_elements_num;
- break;
- case XINE_POST_TYPE_AUDIO_VISUALIZATION:
- _post_elements = &fe->post_vis_elements;
- _post_elements_num = &fe->post_vis_elements_num;
- break;
- default:
- _post_elements = &fe->post_audio_elements;
- _post_elements_num = &fe->post_audio_elements_num;
- break;
- }
-
- if((posts = pplugin_parse_and_load(fe, plugin_type, post_chain, &num))) {
- if(*_post_elements_num) {
- int i;
- int ptot = *_post_elements_num + num;
-
- *_post_elements = (post_element_t **) realloc(*_post_elements,
- sizeof(post_element_t *) * (ptot + 1));
- for(i = *_post_elements_num; i < ptot; i++)
- (*_post_elements)[i] = posts[i - *_post_elements_num];
-
- (*_post_elements)[i] = NULL;
- (*_post_elements_num) += num;
- }
- else {
- *_post_elements = posts;
- *_post_elements_num = num;
- }
-#if 1
- if(SysLogLevel > 2) {
- /* dump list of all loaded plugins */
- int ptot = *_post_elements_num;
- int i;
- char s[4096]="";
- for(i=0; i<ptot; i++)
- if((*_post_elements)[i])
- if(((*_post_elements)[i])->post) {
- if(((*_post_elements)[i])->enable)
- strcat(s, "*");
- if(((*_post_elements)[i])->name)
- strcat(s, ((*_post_elements)[i])->name);
- else
- strcat(s, "<no name!>");
- strcat(s, " ");
- }
- LOGDBG(" loaded plugins (type %d.%d): %s",
- (plugin_type>>16), (plugin_type&0xffff), s);
- }
-#endif
- }
-}
-
-
-void vpplugin_parse_and_store_post(fe_t *fe, const char *post_chain)
-{
- pplugin_parse_and_store_post(fe, XINE_POST_TYPE_VIDEO_FILTER, post_chain);
- pplugin_parse_and_store_post(fe, XINE_POST_TYPE_VIDEO_COMPOSE, post_chain);
-}
-
-
-void applugin_parse_and_store_post(fe_t *fe, const char *post_chain)
-{
- pplugin_parse_and_store_post(fe, XINE_POST_TYPE_AUDIO_FILTER, post_chain);
- pplugin_parse_and_store_post(fe, XINE_POST_TYPE_AUDIO_VISUALIZATION, post_chain);
-}
-
-
-static void _vpplugin_unwire(fe_t *fe)
-{
- xine_post_out_t *vo_source;
- vo_source = xine_get_video_source(fe->video_source);
- (void) xine_post_wire_video_port(vo_source, fe->video_port);
-}
-
-
-static void _applugin_unwire(fe_t *fe)
-{
- xine_post_out_t *ao_source;
- ao_source = xine_get_audio_source(fe->audio_source);
- (void) xine_post_wire_audio_port(ao_source, fe->audio_port);
-}
-
-
-static void _vpplugin_rewire_from_post_elements(fe_t *fe, post_element_t **post_elements, int post_elements_num)
-{
- if(post_elements_num) {
- xine_post_out_t *vo_source;
- int i = 0;
-
- for(i = (post_elements_num - 1); i >= 0; i--) {
- const char *const *outs = xine_post_list_outputs(post_elements[i]->post);
- const xine_post_out_t *vo_out = xine_post_output(post_elements[i]->post, (char *) *outs);
- if(i == (post_elements_num - 1)) {
- LOGDBG(" wiring %10s[out] -> [in]video_out", post_elements[i]->name);
- xine_post_wire_video_port((xine_post_out_t *) vo_out, fe->video_port);
- }
- else {
- const xine_post_in_t *vo_in;
- int err;
-
- /* look for standard input names */
- vo_in = xine_post_input(post_elements[i + 1]->post, "video");
- if( !vo_in )
- vo_in = xine_post_input(post_elements[i + 1]->post, "video in");
-
- LOGDBG(" wiring %10s[out] -> [in]%-10s ",
- post_elements[i]->name, post_elements[i+1]->name);
- err = xine_post_wire((xine_post_out_t *) vo_out,
- (xine_post_in_t *) vo_in);
- }
- }
-
- if(fe->post_pip_enable &&
- !strcmp(post_elements[0]->name, "mosaico") &&
- fe->pip_stream) {
- vo_source = xine_get_video_source(fe->pip_stream);
- LOGDBG(" wiring %10s[out] -> [in1]%-10s ", "pip stream", post_elements[0]->name);
- xine_post_wire_video_port(vo_source,
- post_elements[0]->post->video_input[1]);
- }
-
- vo_source = xine_get_video_source(fe->video_source);
- LOGDBG(" wiring %10s[out] -> [in]%-10s", "stream", post_elements[0]->name);
- xine_post_wire_video_port(vo_source,
- post_elements[0]->post->video_input[0]);
- }
-}
-
-
-static void _applugin_rewire_from_post_elements(fe_t *fe, post_element_t **post_elements, int post_elements_num)
-{
- if(post_elements_num) {
- xine_post_out_t *ao_source;
- int i = 0;
-
- for(i = (post_elements_num - 1); i >= 0; i--) {
- const char *const *outs = xine_post_list_outputs(post_elements[i]->post);
- const xine_post_out_t *ao_out = xine_post_output(post_elements[i]->post, (char *) *outs);
-
- if(i == (post_elements_num - 1)) {
- LOGDBG(" wiring %10s[out] -> [in]audio_out", post_elements[i]->name);
- xine_post_wire_audio_port((xine_post_out_t *) ao_out, fe->audio_port);
- }
- else {
- const xine_post_in_t *ao_in;
- int err;
-
- /* look for standard input names */
- ao_in = xine_post_input(post_elements[i + 1]->post, "audio");
- if( !ao_in )
- ao_in = xine_post_input(post_elements[i + 1]->post, "audio in");
-
- LOGDBG(" wiring %10s[out] -> [in]%-10s ",
- post_elements[i]->name, post_elements[i+1]->name);
- err = xine_post_wire((xine_post_out_t *) ao_out, (xine_post_in_t *) ao_in);
- }
- }
-
- ao_source = xine_get_audio_source(fe->audio_source);
- LOGDBG(" wiring %10s[out] -> [in]%-10s", "stream", post_elements[0]->name);
- xine_post_wire_audio_port(ao_source, post_elements[0]->post->audio_input[0]);
- }
-}
-
-static post_element_t **_pplugin_join_deinterlace_and_post_elements(fe_t *fe, int *post_elements_num)
-{
- post_element_t **post_elements;
- int i = 0, j = 0, n = 0, p = 0;
- static const char *order[] = {"autocrop", "thread", "tvtime", "swscale", NULL};
-
- *post_elements_num = 0;
- if( fe->post_video_enable )
- *post_elements_num += fe->post_video_elements_num;
-
- if( fe->post_pip_enable )
- *post_elements_num += fe->post_pip_elements_num;
-
- if( *post_elements_num == 0 )
- return NULL;
-
- post_elements = calloc( (*post_elements_num), sizeof(post_element_t *));
-
- if(fe->post_pip_enable)
- for( i = 0; i < fe->post_pip_elements_num; i++ ) {
- if(fe->post_pip_elements[i]->enable)
- post_elements[i+j-n] = fe->post_pip_elements[i];
- else
- n++;
- }
-
- if(fe->post_video_enable)
- for( j = 0; j < fe->post_video_elements_num; j++ ) {
- if(fe->post_video_elements[j]->enable) {
- post_elements[i+j-n] = fe->post_video_elements[j];
- } else
- n++;
- }
-
- *post_elements_num -= n;
- if( *post_elements_num == 0 ) {
- free(post_elements);
- return NULL;
- }
-
- /* in some special cases order is important. By default plugin order
- * in post plugin chain is post plugin loading order.
- * But, we want:
- *
- * 1. autocrop - less data to process for other plugins
- * - accepts only YV12
- * 2. deinterlace - blur etc. makes deinterlacing difficult.
- * - upscales chroma (YV12->YUY2) in some modes.
- * 3. anything else
- *
- * So let's move those two to beginning ...
- */
- n = 0;
- while(order[p]) {
- for(i = 0; i<*post_elements_num; i++)
- if(!strcmp(post_elements[i]->name, order[p])) {
- if(i != n) {
- post_element_t *tmp = post_elements[i];
- for(j=i; j>n; j--)
- post_elements[j] = post_elements[j-1];
- post_elements[n] = tmp;
- LOGDBG(" moved %s to post slot %d", order[p], n);
- }
- n++;
- break;
- }
- p++;
- }
-
- return post_elements;
-}
-
-static post_element_t **_pplugin_join_visualization_and_post_elements(fe_t *fe, int *post_elements_num)
-{
- post_element_t **post_elements;
- int i = 0, j = 0, n = 0;
-
- *post_elements_num = 0;
- if( fe->post_audio_enable )
- *post_elements_num += fe->post_audio_elements_num;
-
- if( fe->post_vis_enable )
- *post_elements_num += fe->post_vis_elements_num;
-
- if( *post_elements_num == 0 )
- return NULL;
-
- post_elements = calloc( (*post_elements_num), sizeof(post_element_t *));
-
- if(fe->post_audio_enable)
- for( j = 0; j < fe->post_audio_elements_num; j++ ) {
- if(fe->post_audio_elements[j]->enable)
- post_elements[i+j-n] = fe->post_audio_elements[j];
- else
- n++;
- }
-
- if(fe->post_vis_enable)
- for( i = 0; i < fe->post_vis_elements_num; i++ ) {
- if(fe->post_vis_elements[i]->enable)
- post_elements[i+j-n] = fe->post_vis_elements[i];
- else
- n++;
- }
-
- *post_elements_num -= n;
- if( *post_elements_num == 0 ) {
- free(post_elements);
- return NULL;
- }
-
- return post_elements;
-}
-
-static void _vpplugin_rewire(fe_t *fe)
-{
- static post_element_t **post_elements;
- int post_elements_num;
-
- post_elements = _pplugin_join_deinterlace_and_post_elements(fe, &post_elements_num);
-
- if( post_elements ) {
- _vpplugin_rewire_from_post_elements(fe, post_elements, post_elements_num);
-
- free(post_elements);
- }
-}
-
-static void _applugin_rewire(fe_t *fe)
-{
- static post_element_t **post_elements;
- int post_elements_num;
-
- post_elements = _pplugin_join_visualization_and_post_elements(fe, &post_elements_num);
-
- if( post_elements ) {
- _applugin_rewire_from_post_elements(fe, post_elements, post_elements_num);
-
- free(post_elements);
- }
-}
-
-void vpplugin_rewire_posts(fe_t *fe)
-{
- /*TRACELINE;*/
- _vpplugin_unwire(fe);
- _vpplugin_rewire(fe);
-}
-
-void applugin_rewire_posts(fe_t *fe)
-{
- /*TRACELINE;*/
- _applugin_unwire(fe);
- _applugin_rewire(fe);
-}
-
-static int _pplugin_enable_post(post_plugins_t *fe, const char *name,
- const char *args,
- post_element_t **post_elements,
- int post_elements_num,
- int *found)
-{
- int i, result = 0;
-
- for(i=0; i<post_elements_num; i++)
- if(post_elements[i])
- if(!strcmp(post_elements[i]->name, name)) {
- if(post_elements[i]->enable == 0) {
- post_elements[i]->enable = 1;
- result = 1;
- }
-
- *found = 1;
-
- if(args && *args) {
- if(post_elements[i]->enable != 2) {
- char *tmp = strdup(args);
- __pplugin_update_parameters(post_elements[i]->post, tmp);
- free(tmp);
- if(post_elements[i]->args)
- free(post_elements[i]->args);
- post_elements[i]->args = strdup(args);
- } else {
- LOGDBG(" * enable post %s, parameters fixed in command line.", name);
- LOGDBG(" requested: %s", args ? : "none");
- LOGDBG(" using : %s", post_elements[i]->args ? : "none");
- }
- }
- }
-
- return result;
-}
-
-static int _vpplugin_enable_post(post_plugins_t *fe, const char *name,
- const char *args, int *found)
-{
- int result = 0;
- if(!*found)
- result = _pplugin_enable_post(fe, name, args, fe->post_video_elements,
- fe->post_video_elements_num, found);
- if(!*found)
- result = _pplugin_enable_post(fe, name, args, fe->post_pip_elements,
- fe->post_pip_elements_num, found);
- return result;
-}
-
-static int _applugin_enable_post(post_plugins_t *fe, const char *name,
- const char *args, int *found)
-{
- int result = 0;
- if(!*found)
- result = _pplugin_enable_post(fe, name, args, fe->post_audio_elements,
- fe->post_audio_elements_num, found);
- if(!*found)
- result = _pplugin_enable_post(fe, name, args, fe->post_vis_elements,
- fe->post_vis_elements_num, found);
- return result;
-}
-
-static char * _pp_name_strdup(const char *initstr)
-{
- char *name = strdup(initstr), *pt;
-
- if(NULL != (pt = strchr(name, ':')))
- *pt = 0;
-
- return name;
-}
-
-static const char * _pp_args(const char *initstr)
-{
- char *pt = strchr(initstr, ':');
- if(pt && *(pt+1))
- return pt+1;
- return NULL;
-}
-
-int vpplugin_enable_post(post_plugins_t *fe, const char *initstr,
- int *found)
-{
- char *name = _pp_name_strdup(initstr);
- const char *args = _pp_args(initstr);
-
- int result = _vpplugin_enable_post(fe, name, args, found);
-
- LOGDBG(" * enable post %s --> %s, %s", name,
- *found ? "found" : "not found",
- result ? "enabled" : "no action");
-
- if(!*found) {
- LOGDBG(" * loading post %s", initstr);
- vpplugin_parse_and_store_post(fe, initstr);
- result = _vpplugin_enable_post(fe, name, NULL, found);
- LOGDBG(" * enable post %s --> %s, %s", name,
- *found ? "found" : "not found",
- result ? "enabled" : "no action");
- }
-
- if(result)
- _vpplugin_unwire(fe);
-
- free(name);
- return result;
-}
-
-int applugin_enable_post(post_plugins_t *fe, const char *initstr,
- int *found)
-{
- const char * args = _pp_args(initstr);
- char *name = _pp_name_strdup(initstr);
-
- int result = _applugin_enable_post(fe, name, args, found);
-
- LOGDBG(" * enable post %s --> %s, %s", name,
- *found ? "found" : "not found",
- result ? "enabled" : "no action");
-
- if(!*found) {
- LOGDBG(" * loading post %s", initstr);
- applugin_parse_and_store_post(fe, initstr);
- result = _applugin_enable_post(fe, name, NULL, found);
- LOGDBG(" * enable post %s --> %s, %s", name,
- *found ? "found" : "not found",
- result ? "enabled" : "no action");
- }
-
- if(result)
- _applugin_unwire(fe);
-
- free(name);
- return result;
-}
-
-static int _pplugin_disable_post(post_plugins_t *fe, const char *name,
- post_element_t **post_elements,
- int post_elements_num)
-{
- int i, result = 0;
- /*TRACELINE;*/
- if(post_elements)
- for(i = 0; i < post_elements_num; i++)
- if(post_elements[i])
- if(!name || !strcmp(post_elements[i]->name, name))
- if(post_elements[i]->enable == 1) {
- post_elements[i]->enable = 0;
- result = 1;
- }
- return result;
-}
-
-int vpplugin_disable_post(post_plugins_t *fe, const char *name)
-{
- /*TRACELINE;*/
- if(_pplugin_disable_post(fe, name, fe->post_video_elements,
- fe->post_video_elements_num) ||
- _pplugin_disable_post(fe, name, fe->post_pip_elements,
- fe->post_pip_elements_num)) {
- _vpplugin_unwire(fe);
- return 1;
- }
- return 0;
-}
-
-int applugin_disable_post(post_plugins_t *fe, const char *name)
-{
- /*TRACELINE;*/
- if(_pplugin_disable_post(fe, name, fe->post_audio_elements,
- fe->post_audio_elements_num) ||
- _pplugin_disable_post(fe, name, fe->post_vis_elements,
- fe->post_vis_elements_num)) {
- _applugin_unwire(fe);
- return 1;
- }
- return 0;
-}
-
-static int _pplugin_unload_post(post_plugins_t *fe, const char *name,
- post_element_t ***post_elements,
- int *post_elements_num)
-{
- /* does not unwrire plugins ! */
- int i, j, result = 0;
- /*TRACELINE;*/
-
- if(!*post_elements || !*post_elements_num)
- return 0;
-
- for(i=0; i < *post_elements_num; i++) {
- if((*post_elements)[i]) {
- if(!name || !strcmp((*post_elements)[i]->name, name)) {
-
- if((*post_elements)[i]->enable == 0 || !name) {
- xine_post_dispose(fe->xine, (*post_elements)[i]->post);
-
- free((*post_elements)[i]->name);
-
- if((*post_elements)[i]->args)
- free((*post_elements)[i]->args);
-
- free((*post_elements)[i]);
-
- for(j=i; j < *post_elements_num - 1; j++)
- (*post_elements)[j] = (*post_elements)[j+1];
-
- (*post_elements_num) --;
- (*post_elements)[(*post_elements_num)] = 0;
-
- result = 1;
- i--;
-
- } else {
- LOGDBG("Unload %s failed: plugin enabled and in use",
- (*post_elements)[i]->name);
- }
- }
- }
- }
-
- if(*post_elements_num <= 0) {
- if(*post_elements)
- free(*post_elements);
- *post_elements = NULL;
- }
-
- return result;
-}
-
-int vpplugin_unload_post(post_plugins_t *fe, const char *name)
-{
- int result = vpplugin_disable_post(fe, name);
-
- /* unload already disabled plugins too (result=0) */
- _pplugin_unload_post(fe, name, &fe->post_video_elements,
- &fe->post_video_elements_num);
- _pplugin_unload_post(fe, name, &fe->post_pip_elements,
- &fe->post_pip_elements_num);
-
- /* result indicates only unwiring condition, not unload result */
- return result;
-}
-
-int applugin_unload_post(post_plugins_t *fe, const char *name)
-{
- int result = applugin_disable_post(fe, name);
-
- /* unload already disabled plugins too (result=0) */
- _pplugin_unload_post(fe, name, &fe->post_audio_elements,
- &fe->post_audio_elements_num);
- _pplugin_unload_post(fe, name, &fe->post_vis_elements,
- &fe->post_vis_elements_num);
-
- /* result indicates only unwiring condition, not unload result */
- return result;
-}
-
-
-/* end of post.c */
-
diff --git a/xine/post.h b/xine/post.h
deleted file mode 100644
index 355e8e2c..00000000
--- a/xine/post.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2003 by Dirk Meyer
- *
- * This file is part of xine, a unix video player.
- *
- * xine is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * xine is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * Modified for xineliboutput by Petri Hintukainen, 2006
- *
- */
-
-#ifndef POST_HH
-#define POST_HH
-
-#include <xine.h>
-#include <xine/xine_internal.h>
-#include <xine/xineutils.h>
-#include <xine/plugin_catalog.h>
-
-typedef struct {
- xine_post_t *post;
- char *name;
- char *args;
- int enable; /* 0 - disabled, 1 - enabled, 2 - can't disable */
-} post_element_t;
-
-
-typedef struct post_plugins_s post_plugins_t;
-
-struct post_plugins_s {
-
- /* frontend data */
- char *static_post_plugins; /* post plugins from command line; always on */
- xine_stream_t *video_source; /* stream to take video from */
- xine_stream_t *audio_source; /* stream to take audio from */
- xine_stream_t *pip_stream; /* pip stream */
-
- /* xine */
- xine_t *xine;
- xine_video_port_t *video_port;
- xine_audio_port_t *audio_port;
-
- /* post.c internal use */
- int post_audio_elements_num;
- int post_video_elements_num;
- int post_vis_elements_num;
- int post_pip_elements_num;
-
- post_element_t **post_audio_elements;
- post_element_t **post_video_elements;
- post_element_t **post_vis_elements; /* supports only one */
- post_element_t **post_pip_elements; /* supports only one and two input */
-
- int post_audio_enable;
- int post_video_enable;
- int post_vis_enable;
- int post_pip_enable;
-};
-
-
-void vpplugin_rewire_posts(post_plugins_t *fe);
-void applugin_rewire_posts(post_plugins_t *fe);
-
-/* load and config post plugin(s) */
-/* post == "plugin:arg1=val1,arg2=val2;plugin2..." */
-void vpplugin_parse_and_store_post(post_plugins_t *fe, const char *post);
-void applugin_parse_and_store_post(post_plugins_t *fe, const char *post);
-
-/* enable (and load if not loaded), but don't rewire */
-/* result indicates only unwiring condition, not enable result */
-/* -> if result <> 0, something was enabled and post chain is unwired */
-int vpplugin_enable_post(post_plugins_t *fe, const char *name, int *found);
-int applugin_enable_post(post_plugins_t *fe, const char *name, int *found);
-
-/* disable (and unwire if found), but don't unload */
-/* result indicates only unwiring condition, not disable result */
-int vpplugin_disable_post(post_plugins_t *fe, const char *name);
-int applugin_disable_post(post_plugins_t *fe, const char *name);
-
-/* unload (and unwire) plugin(s) */
-/* result indicates only unwiring condition, not unload result */
-int vpplugin_unload_post(post_plugins_t *fe, const char *name);
-int applugin_unload_post(post_plugins_t *fe, const char *name);
-
-#endif
-
-/* end of post.h */
diff --git a/xine/post_util.h b/xine/post_util.h
deleted file mode 100644
index a539d31d..00000000
--- a/xine/post_util.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * post_util.h: post plugin utility functions
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: post_util.h,v 1.5 2008-12-14 00:52:35 phintuka Exp $
- *
- */
-
-#if POST_PLUGIN_IFACE_VERSION < 9
-# warning POST_PLUGIN_IFACE_VERSION < 9 not supported !
-#endif
-#if POST_PLUGIN_IFACE_VERSION > 10
-# warning POST_PLUGIN_IFACE_VERSION > 10 not supported !
-#endif
-
-/*
- * class util prototypes
- */
-
-static void *init_plugin(xine_t *xine, void *data);
-#if POST_PLUGIN_IFACE_VERSION < 10
-static char *get_identifier(post_class_t *class_gen);
-static char *get_description(post_class_t *class_gen);
-static void class_dispose(post_class_t *class_gen);
-#endif
-
-/* required from plugin: */
-static post_plugin_t *open_plugin(post_class_t *class_gen, int inputs,
- xine_audio_port_t **audio_target,
- xine_video_port_t **video_target);
-
-/*
- * plugin util prototypes
- */
-
-static int dispatch_draw(vo_frame_t *frame, xine_stream_t *stream);
-static int intercept_frame_yuy(post_video_port_t *port, vo_frame_t *frame);
-static int post_draw(vo_frame_t *frame, xine_stream_t *stream);
-#ifdef ENABLE_SLICED
-static void dispatch_slice(vo_frame_t *vo_img, uint8_t **src);
-#endif
-
-/* required from plugin: */
-static vo_frame_t *got_frame(vo_frame_t *frame);
-static void draw_internal(vo_frame_t *frame, vo_frame_t *new_frame);
-
-
-/*
- * class utils
- */
-
-static void *init_plugin(xine_t *xine, void *data)
-{
- post_class_t *class = calloc(1, sizeof(post_class_t));
-
- if (!class)
- return NULL;
-
- class->open_plugin = open_plugin;
-#if POST_PLUGIN_IFACE_VERSION < 10
- class->get_identifier = get_identifier;
- class->get_description = get_description;
- class->dispose = class_dispose;
-#else
- class->identifier = PLUGIN_ID;
- class->description = PLUGIN_DESCR;
- class->dispose = default_post_class_dispose;
-#endif
-
- return class;
-}
-
-#if POST_PLUGIN_IFACE_VERSION < 10
-static char *get_identifier(post_class_t *class_gen)
-{
- return PLUGIN_ID;
-}
-
-static char *get_description(post_class_t *class_gen)
-{
- return PLUGIN_DESCR;
-}
-
-static void class_dispose(post_class_t *class_gen)
-{
- free(class_gen);
-}
-#endif
-
-/*
- * plugin utils
- */
-
-#ifdef ENABLE_SLICED
-static void dispatch_slice(vo_frame_t *vo_img, uint8_t **src)
-{
- if (vo_img->next->proc_slice) {
- _x_post_frame_copy_down(vo_img, vo_img->next);
- vo_img->next->proc_slice(vo_img->next, src);
- _x_post_frame_copy_up(vo_img, vo_img->next);
- }
-}
-#endif
-
-static int dispatch_draw(vo_frame_t *frame, xine_stream_t *stream)
-{
- int skip;
- _x_post_frame_copy_down(frame, frame->next);
- skip = frame->next->draw(frame->next, stream);
- _x_post_frame_copy_up(frame, frame->next);
- return skip;
-}
-
-static int intercept_frame_yuy(post_video_port_t *port, vo_frame_t *frame)
-{
- return (frame->format == XINE_IMGFMT_YV12 || frame->format == XINE_IMGFMT_YUY2);
-}
-
-static int post_draw(vo_frame_t *frame, xine_stream_t *stream)
-{
- vo_frame_t *new_frame;
- int skip;
-
- if (frame->bad_frame)
- return dispatch_draw(frame, stream);
-
- new_frame = got_frame(frame);
-
- if (!new_frame)
- return dispatch_draw(frame, stream);
-
- _x_post_frame_copy_down(frame, new_frame);
-
- draw_internal(frame, new_frame);
-
- skip = new_frame->draw(new_frame, stream);
- _x_post_frame_copy_up(frame, new_frame);
- new_frame->free(new_frame);
-
- return skip;
-}
-
diff --git a/xine/ts2es.c b/xine/ts2es.c
deleted file mode 100644
index bf0ec7fb..00000000
--- a/xine/ts2es.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * ts2es.c: demux MPEG-TS -> ES
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: ts2es.c,v 1.1 2009-02-23 22:16:08 phintuka Exp $
- *
- */
-
-#include <stdlib.h>
-
-#include <xine/buffer.h>
-
-#include "../tools/ts.h"
-#include "../tools/pes.h"
-
-#include "ts2es.h"
-
-#define LOG_MODULENAME "[demux_vdr] "
-#define SysLogLevel iSysLogLevel
-#include "../logdefs.h"
-
-
-struct ts2es_s {
- fifo_buffer_t *fifo;
- uint32_t stream_type;
- uint32_t xine_buf_type;
-
- buf_element_t *buf;
- int pes_start;
- int64_t pts;
-};
-
-
-static void ts2es_parse_pes(ts2es_t *this)
-{
- if (!DATA_IS_PES(this->buf->content)) {
- LOGMSG("ts2es: payload not PES ?");
- return;
- }
-
- /* parse PES header */
- uint hdr_len = PES_HEADER_LEN(this->buf->content);
- uint8_t pes_pid = this->buf->content[3];
- uint pes_len = (this->buf->content[4] << 8) | this->buf->content[5];
-
- /* parse PTS */
- this->buf->pts = pes_get_pts(this->buf->content, this->buf->size);
- if(this->buf->pts >= 0)
- this->pts = this->buf->pts;
- else
- this->pts = 0;
-
- /* strip PES header */
- this->buf->content += hdr_len;
- this->buf->size -= hdr_len;
-
- /* parse substream header */
-
- if (pes_pid != PRIVATE_STREAM1)
- return;
-
- /* RAW AC3 audio ? -> do nothing */
- if (this->stream_type == STREAM_AUDIO_AC3) {
- this->xine_buf_type |= BUF_AUDIO_A52;
- this->buf->type = this->xine_buf_type;
- return;
- }
-
- /* AC3 syncword in beginning of PS1 payload ? */
- if (this->buf->content[0] == 0x0B &&
- this->buf->content[1] == 0x77) {
- /* --> RAW AC3 audio - do nothing */
- this->xine_buf_type |= BUF_AUDIO_A52;
- this->buf->type = this->xine_buf_type;
- return;
- }
-
- /* audio in PS1 */
- if (this->stream_type == ISO_13818_PES_PRIVATE) {
-
- if ((this->buf->content[0] & 0xf0) == 0x80) {
- /* AC3, strip substream header */
- this->buf->content += 4;
- this->buf->size -= 4;
- this->xine_buf_type |= BUF_AUDIO_A52;
- this->buf->type = this->xine_buf_type;
- return;
- }
-
- if ((this->buf->content[0] & 0xf0) == 0xa0) {
- /* PCM, strip substream header */
- int pcm_offset;
- for (pcm_offset=0; ++pcm_offset < this->buf->size-1 ; ) {
- if (this->buf->content[pcm_offset] == 0x01 &&
- this->buf->content[pcm_offset+1] == 0x80 ) { /* START */
- pcm_offset += 2;
- break;
- }
- }
- this->buf->content += pcm_offset;
- this->buf->size -= pcm_offset;
-
- this->xine_buf_type |= BUF_AUDIO_LPCM_BE;
- this->buf->type = this->xine_buf_type;
- return;
- }
-
- LOGMSG("ts2es: unhandled PS1 substream 0x%x", this->buf->content[0]);
- return;
- }
-
- /* DVB SPU */
- if (this->stream_type == STREAM_DVBSUB) {
- if (this->buf->content[0] != 0x20 ||
- this->buf->content[1] != 0x00)
- LOGMSG("ts2es: DVB SPU, invalid PES substream header");
- this->buf->decoder_info[2] = pes_len - hdr_len - 3 + 9;
- return;
- }
-}
-
-buf_element_t *ts2es_put(ts2es_t *this, uint8_t *data)
-{
- int bytes = ts_PAYLOAD_SIZE(data);
- int pusi = ts_PAYLOAD_START(data);
- buf_element_t *result = NULL;
-
- if (ts_HAS_ERROR(data)) {
- LOGDBG("ts2es: transport error");
- return NULL;
- }
- if (!ts_HAS_PAYLOAD(data)) {
- LOGDBG("ts2es: no payload, size %d", bytes);
- return NULL;
- }
-
- /* handle new payload unit */
- if (pusi) {
- this->pes_start = 1;
- if (this->buf) {
-
- this->buf->decoder_flags |= BUF_FLAG_FRAME_END;
- this->buf->pts = this->pts;
-
- result = this->buf;
- this->buf = NULL;
- }
- }
-
- /* need new buffer ? */
- if (!this->buf) {
- this->buf = this->fifo->buffer_pool_alloc(this->fifo);
- this->buf->type = this->xine_buf_type;
- this->buf->decoder_info[0] = 1;
- }
-
- /* strip ts header */
- data += TS_SIZE - bytes;
-
- /* copy payload */
- memcpy(this->buf->content + this->buf->size, data, bytes);
- this->buf->size += bytes;
-
- /* parse PES header */
- if (this->pes_start) {
- this->pes_start = 0;
-
- ts2es_parse_pes(this);
- }
-
- /* split large packets */
- if (this->buf->size > 2048) {
- this->buf->pts = this->pts;
-
- result = this->buf;
- this->buf = NULL;
- }
-
- return result;
-}
-
-void ts2es_flush(ts2es_t *this)
-{
- if (this->buf) {
-
- this->buf->decoder_flags |= BUF_FLAG_FRAME_END;
- this->buf->pts = this->pts;
-
- this->fifo->put (this->fifo, this->buf);
- this->buf = NULL;
- }
-}
-
-void ts2es_dispose(ts2es_t *data)
-{
- if (data) {
- if (data->buf)
- data->buf->free_buffer(data->buf);
- free(data);
- }
-}
-
-ts2es_t *ts2es_init(fifo_buffer_t *dst_fifo, ts_stream_type stream_type, uint stream_index)
-{
- ts2es_t *data = calloc(1, sizeof(ts2es_t));
- data->fifo = dst_fifo;
-
- data->stream_type = stream_type;
-
- switch(stream_type) {
- /* VIDEO (PES streams 0xe0...0xef) */
- case ISO_11172_VIDEO:
- case ISO_13818_VIDEO:
- case STREAM_VIDEO_MPEG:
- data->xine_buf_type = BUF_VIDEO_MPEG;
- break;
- case ISO_14496_PART2_VIDEO:
- data->xine_buf_type = BUF_VIDEO_MPEG4;
- break;
- case ISO_14496_PART10_VIDEO:
- data->xine_buf_type = BUF_VIDEO_H264;
- break;
-
- /* AUDIO (PES streams 0xc0...0xdf) */
- case ISO_11172_AUDIO:
- case ISO_13818_AUDIO:
- data->xine_buf_type = BUF_AUDIO_MPEG;
- break;
- case ISO_13818_PART7_AUDIO:
- case ISO_14496_PART3_AUDIO:
- data->xine_buf_type = BUF_AUDIO_AAC;
- break;
-
- /* AUDIO (PES stream 0xbd) */
- case ISO_13818_PES_PRIVATE:
- data->xine_buf_type = 0;
- /* detect from PES substream header */
- break;
-
- /* DVB SPU (PES stream 0xbd) */
- case STREAM_DVBSUB:
- data->xine_buf_type = BUF_SPU_DVB;
- break;
-
- /* RAW AC3 */
- case STREAM_AUDIO_AC3:
- data->xine_buf_type = BUF_AUDIO_A52;
- break;
-
- default:
- LOGMSG("ts2es: unknown stream type 0x%x", stream_type);
- break;
- }
-
- /* substream ID (audio/SPU) */
- data->xine_buf_type |= stream_index;
-
- return data;
-}
-
diff --git a/xine/ts2es.h b/xine/ts2es.h
deleted file mode 100644
index 8a5ab724..00000000
--- a/xine/ts2es.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * ts2es.h: demux MPEG-TS -> ES
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: ts2es.h,v 1.1 2009-02-23 22:16:08 phintuka Exp $
- *
- */
-
-#ifndef _DEMUX_XVDR_TS2ES_H_
-#define _DEMUX_XVDR_TS2ES_H_
-
-typedef struct ts2es_s ts2es_t;
-
-ts2es_t *ts2es_init (fifo_buffer_t *dst_fifo, ts_stream_type stream_type, uint stream_index);
-buf_element_t *ts2es_put (ts2es_t *ts2es, uint8_t *ts_packet);
-void ts2es_flush (ts2es_t *ts2es);
-void ts2es_dispose (ts2es_t *ts2es);
-
-#endif /* _DEMUX_XVDR_TS2ES_H_ */
diff --git a/xine/vo_hook.c b/xine/vo_hook.c
deleted file mode 100644
index 89190b9c..00000000
--- a/xine/vo_hook.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * vo_hook.c: Intercept video driver
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vo_hook.c,v 1.5 2009-05-09 16:05:06 phintuka Exp $
- *
- */
-
-#include <stdlib.h>
-
-#include <xine/video_out.h>
-
-#define LOG_MODULENAME "[xine-vo ] "
-#include "../logdefs.h"
-
-#include "vo_hook.h"
-#include "vo_post.h"
-
-/* This module supports only video driver interface version 21 */
-#if (VIDEO_OUT_DRIVER_IFACE_VERSION < 21)
-# error xine-lib VIDEO_OUT_DRIVER_IFACE_VERSION < 21
-#endif
-
-
-/*
- * default handlers
- *
- * - Forward function call to original driver
- */
-
-#define DEF_HANDLER3(RET, NAME, ARG1, ARG2, ARG3) \
-RET vo_def_##NAME (vo_driver_t *self, ARG1 a1, ARG2 a2, ARG3 a3) { \
- vo_driver_hook_t *this = (vo_driver_hook_t *) self; \
- return this->orig_driver-> NAME (this->orig_driver, a1, a2, a3); \
-}
-
-#define DEF_HANDLER2(RET, NAME, ARG1, ARG2) \
-RET vo_def_##NAME (vo_driver_t *self, ARG1 a1, ARG2 a2) { \
- vo_driver_hook_t *this = (vo_driver_hook_t *) self; \
- return this->orig_driver-> NAME (this->orig_driver, a1, a2); \
-}
-
-#define DEF_HANDLER1(RET, NAME, ARG1) \
-RET vo_def_##NAME (vo_driver_t *self, ARG1 a1) { \
- vo_driver_hook_t *this = (vo_driver_hook_t *) self; \
- return this->orig_driver-> NAME (this->orig_driver, a1); \
-}
-
-#define DEF_HANDLER0(RET, NAME) \
-RET vo_def_##NAME (vo_driver_t *self) { \
- vo_driver_hook_t *this = (vo_driver_hook_t *) self; \
- return this->orig_driver-> NAME (this->orig_driver); \
-}
-
-/*
- *
- */
-
-DEF_HANDLER0(uint32_t, get_capabilities);
-DEF_HANDLER0(vo_frame_t*, alloc_frame);
-
-void vo_def_update_frame_format (vo_driver_t *self, vo_frame_t *img,
- uint32_t width, uint32_t height,
- double ratio, int format, int flags)
-{
- vo_driver_hook_t *this = (vo_driver_hook_t *) self;
- return this->orig_driver-> update_frame_format (this->orig_driver, img, width, height, ratio, format, flags);
-}
-
-DEF_HANDLER1(void, display_frame, vo_frame_t * );
-DEF_HANDLER2(void, overlay_begin, vo_frame_t *, int );
-DEF_HANDLER2(void, overlay_blend, vo_frame_t *, vo_overlay_t * );
-DEF_HANDLER1(void, overlay_end, vo_frame_t *);
-DEF_HANDLER1(int, get_property, int);
-DEF_HANDLER2(int, set_property, int, int);
-DEF_HANDLER3(void, get_property_min_max, int, int*, int*);
-DEF_HANDLER2(int, gui_data_exchange, int, void * );
-DEF_HANDLER0(int, redraw_needed );
-
-void vo_def_dispose(vo_driver_t *self)
-{
- vo_driver_hook_t *this = (vo_driver_hook_t *) self;
- if (this->orig_driver)
- this->orig_driver->dispose(this->orig_driver);
- free(self);
-}
-
-/*
- * vo_def_hooks_init()
- *
- * initialize driver_hook_t with default handlers
- *
- */
-static void vo_proxy_hooks_init(vo_driver_t *drv, vo_driver_t *next_driver)
-{
- drv->get_capabilities = drv->get_capabilities ?: vo_def_get_capabilities;
- drv->alloc_frame = drv->alloc_frame ?: vo_def_alloc_frame;
- drv->update_frame_format = drv->update_frame_format ?: vo_def_update_frame_format;
- drv->display_frame = drv->display_frame ?: vo_def_display_frame;
-
- drv->get_property = drv->get_property ?: vo_def_get_property;
- drv->set_property = drv->set_property ?: vo_def_set_property;
- drv->get_property_min_max = drv->get_property_min_max ?: vo_def_get_property_min_max;
- drv->gui_data_exchange = drv->gui_data_exchange ?: vo_def_gui_data_exchange;
- drv->redraw_needed = drv->redraw_needed ?: vo_def_redraw_needed;
- drv->dispose = drv->dispose ?: vo_def_dispose;
-
- /* drop old default handlers for OSD (OSD handlers are optional) */
- if (drv->overlay_begin == vo_def_overlay_begin)
- drv->overlay_begin = NULL;
- if (drv->overlay_blend == vo_def_overlay_blend)
- drv->overlay_blend = NULL;
- if (drv->overlay_end == vo_def_overlay_end)
- drv->overlay_end = NULL;
-
- /* Set proxy handlers for OSD only if next driver has OSD handlers */
- if (!drv->overlay_begin && next_driver->overlay_begin)
- drv->overlay_begin = vo_def_overlay_begin;
- if (!drv->overlay_blend && next_driver->overlay_blend)
- drv->overlay_blend = vo_def_overlay_blend;
- if (!drv->overlay_end && next_driver->overlay_end)
- drv->overlay_end = vo_def_overlay_end;
-
- drv->node = next_driver->node; /* ??? used only by plugin_loader ? */
-}
-
-/*
- *
- */
-
-/* from xine-lib video_out.c */
-typedef struct {
- xine_video_port_t vo; /* public part */
- vo_driver_t *driver;
- /* ... */
-} vos_t;
-
-/*
- * wire_video_driver()
- *
- */
-int wire_video_driver(xine_video_port_t *video_port, vo_driver_t *hook)
-{
- vo_driver_t *vos_driver = ((vos_t*)video_port)->driver;
-
- if (video_port->driver != vos_driver) {
- LOGMSG("wire_video_driver() FAILED (vo_driver != vos_driver)");
- return 0;
- }
-
- /*LOGMSG("wire_video_driver: vo_driver == vos_driver");*/
-
- /* wire */
-
- /* set proxy handlers for undefined methods */
- vo_proxy_hooks_init(hook, video_port->driver);
-
- /* append original driver chain to new driver */
- ((vo_driver_hook_t *)hook)->orig_driver = video_port->driver;
-
- /* push new driver to start of driver chain */
- video_port->driver = hook;
- ((vos_t*)video_port)->driver = hook;
-
- return 1;
-}
-
-/*
- * unwire_video_driver()
- *
- */
-int unwire_video_driver(xine_video_port_t *video_port, vo_driver_t *hook_gen, vo_driver_t *video_out)
-{
- vo_driver_hook_t *hook = (vo_driver_hook_t*)hook_gen;
- vo_driver_hook_t *next = (vo_driver_hook_t*)video_port->driver;
-
- if (next == hook) {
- /* special handling for first entry */
- video_port->driver = next->orig_driver;
- /* need to patch video_port private driver pointer too ... */
- ((vos_t*)video_port)->driver = next->orig_driver;
- next->orig_driver = NULL;
- return 1;
- }
-
- vo_driver_hook_t *prev = next;
- while (next && next != hook && (vo_driver_t*)next != video_out) {
- prev = next;
- next = (vo_driver_hook_t*)next->orig_driver;
- }
-
- if (prev && next == hook) {
- prev->orig_driver = next->orig_driver;
- next->orig_driver = NULL;
- return 1;
- }
-
- return 0;
-}
diff --git a/xine/vo_hook.h b/xine/vo_hook.h
deleted file mode 100644
index 0de93fd0..00000000
--- a/xine/vo_hook.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * vo_hook.h: Intercept video driver
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vo_hook.h,v 1.3 2008-12-14 01:14:54 phintuka Exp $
- *
- */
-
-#ifndef _XINELIBOUTPUT_VO_HOOK_H
-#define _XINELIBOUTPUT_VO_HOOK_H
-
-#include <xine/video_out.h>
-
-/*
- * synchronous video post plugins
- * internal API
- */
-
-
-/*
- * vo_driver_hook_t
- *
- * Used as base for video driver hooks
- */
-
-typedef struct driver_hook_s {
- vo_driver_t vo; /* public part */
- vo_driver_t *orig_driver;
-} vo_driver_hook_t;
-
-/* proxy handlers: forward call to original driver */
-
-uint32_t vo_def_get_capabilities(vo_driver_t *self);
-int vo_def_get_property(vo_driver_t *self, int prop);
-int vo_def_set_property(vo_driver_t *self, int prop, int val);
-
-void vo_def_dispose(vo_driver_t *self);
-
-
-#endif /* _XINELIBOUTPUT_VO_HOOK_H */
diff --git a/xine/vo_osdreorder.c b/xine/vo_osdreorder.c
deleted file mode 100644
index 6fed9e3c..00000000
--- a/xine/vo_osdreorder.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * vo_osdreorder.c: OSD re-ordering video-out post plugin
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vo_osdreorder.c,v 1.1 2009-03-17 12:14:41 phintuka Exp $
- *
- */
-
-#include <stdlib.h>
-
-#include <xine/video_out.h>
-
-#include "vo_props.h"
-#include "vo_hook.h"
-
-/*
- * osdreorder_hook_t
- */
-typedef struct {
- vo_driver_hook_t h;
-
- /* currently showing OSDs in new drawing order */
- vo_overlay_t *overlay[50];
-
-} osdreorder_hook_t;
-
-/*
- *
- */
-
-static int osd_level(vo_overlay_t *overlay)
-{
- if (overlay->hili_rgb_clut != VDR_OSD_MAGIC /* not from vdr */) {
- return 9999;
- }
-
- /* VDR input plugin stores some control data in hili clut area */
- vdr_osd_extradata_t *data = (vdr_osd_extradata_t *)overlay->hili_color;
- return data->layer;
-}
-
-/*
- * interface
- */
-
-/*
- * override overlay_blend()
- */
-static void osdreorder_overlay_blend (vo_driver_t *self, vo_frame_t *frame, vo_overlay_t *overlay)
-{
- osdreorder_hook_t *this = (osdreorder_hook_t*)self;
- int my_level = osd_level(overlay);
- int i;
-
- /* search position */
- for (i = 0; this->overlay[i] && osd_level(this->overlay[i]) >= my_level; i++)
- ;
-
- /* make room */
- if (this->overlay[i])
- memmove(&this->overlay[i+1], &this->overlay[i], (49-i)*sizeof(vo_overlay_t*));
-
- this->overlay[i] = overlay;
- return;
-}
-
-/*
- * override overlay_end()
- */
-static void osdreorder_overlay_end (vo_driver_t *self, vo_frame_t *vo_img)
-{
- osdreorder_hook_t *this = (osdreorder_hook_t*)self;
- int i;
-
- for (i = 0; this->overlay[i]; i++) {
- this->h.orig_driver->overlay_blend(this->h.orig_driver, vo_img, this->overlay[i]);
- this->overlay[i] = NULL;
- }
-
- /* redirect */
- if (this->h.orig_driver->overlay_end)
- this->h.orig_driver->overlay_end(this->h.orig_driver, vo_img);
-}
-
-/*
- * init()
- */
-vo_driver_t *osd_reorder_init(void)
-{
- osdreorder_hook_t *this = calloc(1, sizeof(osdreorder_hook_t));
-
- /* OSD interface */
- this->h.vo.overlay_blend = osdreorder_overlay_blend;
- this->h.vo.overlay_end = osdreorder_overlay_end;
-
- return &this->h.vo;
-}
-
diff --git a/xine/vo_osdreorder.h b/xine/vo_osdreorder.h
deleted file mode 100644
index 15ec7a6b..00000000
--- a/xine/vo_osdreorder.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * vo_osdreorder.h: OSD re-ordering video-out post plugin
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vo_osdreorder.h,v 1.1 2009-03-17 12:14:41 phintuka Exp $
- *
- */
-
-#ifndef _XINELIBOUTPUT_VO_OSDREORDER_H
-#define _XINELIBOUTPUT_VO_OSDREORDER_H
-
-vo_driver_t *osd_reorder_init(void);
-
-#endif /* _XINELIBOUTPUT_VO_OSDREORDER_H */
diff --git a/xine/vo_osdscaler.c b/xine/vo_osdscaler.c
deleted file mode 100644
index d9562d9e..00000000
--- a/xine/vo_osdscaler.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- * vo_osdscaler.c: OSD scaling video-out post plugin
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vo_osdscaler.c,v 1.4 2009-05-27 08:37:06 phintuka Exp $
- *
- */
-
-#include <stdlib.h>
-
-#include <xine/video_out.h>
-#ifdef SWBLEND
-# include <xine/alphablend.h>
-#endif
-
-#define LOG_MODULENAME "[osdscaler] "
-#include "../logdefs.h"
-
-#include "vo_props.h"
-#include "vo_hook.h"
-
-/*#define LOGOSD(x...) LOGMSG(x)*/
-#define LOGOSD(x...)
-
-typedef rle_elem_t xine_rle_elem_t;
-
-#include "../tools/rle.h"
-
-
-/* Make sure our properties won't overlap with xine's properties */
-#if VO_NUM_PROPERTIES > VO_PROP_OSD_SCALING
-# error VO_NUM_PROPERTIES > VO_PROP_OSD_SCALING
-#endif
-
-#undef ABS
-#define ABS(x) ((x)<0?-(x):(x))
-
-
-/*
- * osd_data_t
- *
- * - cache scaled OSD data
- */
-
-typedef struct osd_data_s osd_data_t;
-
-struct osd_data_s {
- /* original source */
- vo_overlay_t *source;
-
- /* scaled overlay */
- uint8_t scaled : 1;
- vo_overlay_t ovl;
-
- /* for what output resolution overlay was scaled */
- uint16_t output_width;
- uint16_t output_height;
-
- /* linked list */
- osd_data_t *next;
-};
-
-/*
- * osd_data_dispose()
- *
- * - free() osd_data_t and all allocated memory
- */
-static void osd_data_dispose(osd_data_t *data)
-{
- if (data->scaled)
- free(data->ovl.rle);
- free(data);
-}
-
-/*
- * osd_data_clear()
- *
- * - free() whole linked list
- */
-static void osd_data_clear(osd_data_t *data)
-{
- if (data) {
- if (data->next)
- osd_data_clear(data->next);
- osd_data_dispose(data);
- }
-}
-
-/*
- * osd_data_remove()
- *
- * - remove (and free) specific osd_data_t item from linked list
- */
-static void osd_data_remove(osd_data_t **list, osd_data_t *data)
-{
- if (!list || !*list)
- return;
-
- /* special handling for list head */
- if (data == *list) {
- *list = data->next;
- free(data);
- return;
- }
-
- osd_data_t *it = *list;
- while (it) {
- if (data == it->next) {
- it->next = data->next;
- free(data);
- return;
- }
- it = it->next;
- }
-}
-
-/*
- * osd_data_init()
- *
- * - allocate and fill new osd_data_t
- *
- */
-static osd_data_t *osd_data_init(vo_overlay_t *ovl, osd_data_t *next,
- uint32_t factor_x, uint32_t factor_y)
-{
- osd_data_t *data = calloc(1, sizeof(osd_data_t));
-
- data->source = ovl;
- data->next = next;
-
- memcpy(&data->ovl, ovl, sizeof(vo_overlay_t));
-
- int num_rle = data->ovl.num_rle;
-
- /* new position and size */
- int x2 = ovl->x + ovl->width + 1;
- int y2 = ovl->y + ovl->height + 1;
- x2 = ((x2+1) * factor_x) >> 16;
- y2 = ((y2+1) * factor_y) >> 16;
- data->ovl.x = (ovl->x * factor_x) >> 16;
- data->ovl.y = (ovl->y * factor_y) >> 16;
- data->ovl.width = x2 - data->ovl.x - 1;
- data->ovl.height = y2 - data->ovl.y - 1;
-
- data->ovl.rle = (rle_elem_t*)
- rle_scale_nearest((struct xine_rle_elem_s*)ovl->rle, &num_rle,
- ovl->width, ovl->height,
- data->ovl.width, data->ovl.height);
- data->ovl.num_rle = num_rle;
- data->scaled = 1;
-
- LOGOSD("I: %d,%d %dx%d", ovl->x, ovl->y, ovl->width, ovl->height);
- LOGOSD("O: %d,%d %dx%d", data->ovl.x, data->ovl.y, data->ovl.width, data->ovl.height);
-
- return data;
-}
-
-/*
- * osdscaler_hook_t
- */
-typedef struct {
- vo_driver_hook_t h;
-
- /* configuration */
- uint8_t enable;
- uint8_t unscaled_supported;
- uint8_t custom_extent_supported;
- uint8_t argb_supported;
-
- /* current output */
- uint16_t output_width;
- uint16_t output_height;
- uint32_t factor_x; /* scaling factor << 16 */
- uint32_t factor_y;
- uint16_t x_move; /* OSD displacement */
- uint16_t y_move;
-
- /* currently showing OSDs - pre-scaled data */
- osd_data_t *active_osds;
-
-} osdscaler_hook_t;
-
-/*
- *
- */
-
-/*
- * override overlay_begin()
- */
-static void osdscaler_overlay_begin (vo_driver_t *self, vo_frame_t *frame, int changed)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t*)self;
-
- /* assume we're wired when called */
- if (!this->h.orig_driver) {
- LOGMSG("osdscaler_overlay_begin: assertion this->h.orig_driver failed !");
- abort();
- }
-
- /* re-scale all if OSD changed */
- if (changed) {
- LOGOSD("osdscaler_overlay_begin: changed = 1");
- osd_data_clear(this->active_osds);
- this->active_osds = NULL;
- this->unscaled_supported = (vo_def_get_capabilities(self) & VO_CAP_UNSCALED_OVERLAY);
- /* VO_CAP_OSDSCALING == VO_CAP_CUSTOM_EXTENT_OVERLAY */
- this->custom_extent_supported = (vo_def_get_capabilities(self) & VO_CAP_OSDSCALING);
- /* VO_CAP_ARGB == VO_CAP_ARGB_LAYER_OVERLAY */
- this->argb_supported = (vo_def_get_capabilities(self) & VO_CAP_ARGB);
- }
-
- /* redirect */
- if (this->h.orig_driver->overlay_begin)
- this->h.orig_driver->overlay_begin(this->h.orig_driver, frame, changed);
-}
-
-static int check_for_scaling(osdscaler_hook_t *this, vo_frame_t *frame, vo_overlay_t *overlay)
-{
- this->x_move = this->y_move = 0;
-
- if (!this->enable)
- return 0;
-
- /* check for VDR OSD */
- if (overlay->hili_rgb_clut != VDR_OSD_MAGIC /* not from vdr */) {
- LOGOSD("overlay: source not VDR");
- return 0;
- }
-
- /* VDR input plugin stores some control data in hili clut area */
- vdr_osd_extradata_t *data = (vdr_osd_extradata_t *)overlay->hili_color;
- int extent_width = data->extent_width;
- int extent_height = data->extent_height;
-
- if (!data->scaling)
- return 0;
-
-#if 0
- if (this->custom_extent_supported) {
- /* let the "real" video driver do scaling */
- return 0;
- }
-#else
-# ifdef VO_CAP_CUSTOM_EXTENT_OVERLAY
- /* disable VDPAU HW scaler */
- overlay->extent_width = 0;
- overlay->extent_height = 0;
-# endif
-#endif
-
- /* detect output size */
- if (overlay->unscaled && this->unscaled_supported) {
- this->output_width = vo_def_get_property((vo_driver_t*)this, VO_PROP_WINDOW_WIDTH);
- this->output_height = vo_def_get_property((vo_driver_t*)this, VO_PROP_WINDOW_HEIGHT);
- } else {
- this->output_width = frame->width;
- this->output_height = frame->height;
- /* check cropping */
- if (frame->crop_top > 0) this->output_height -= frame->crop_top;
- if (frame->crop_bottom > 0) this->output_height -= frame->crop_bottom;
- if (frame->crop_left > 0) this->output_width -= frame->crop_left;
- if (frame->crop_right > 0) this->output_width -= frame->crop_right;
- }
-
- /* check if scaling should be done */
- if (ABS(this->output_width - extent_width) > extent_width /20 ||
- ABS(this->output_height - extent_height) > extent_height/20 ) {
- LOGOSD("scaling required");
- this->factor_x = 0x10000 * this->output_width / extent_width;
- this->factor_y = 0x10000 * this->output_height / extent_height;
- return 1;
- }
-
- /* if no scaling was required, we may still need to re-center OSD */
- if(this->output_width != extent_width)
- this->x_move = (this->output_width - extent_width)/2;
- if(this->output_height != extent_height)
- this->y_move = (this->output_height - extent_height)/2;
-
- return 0;
-}
-
-static vo_overlay_t *scale_overlay(osdscaler_hook_t *this, vo_frame_t *frame, vo_overlay_t *overlay)
-{
- if (check_for_scaling(this, frame, overlay)) {
-
- /* find old scaled OSD */
- osd_data_t *scaled = this->active_osds;
- while (scaled && scaled->source != overlay)
- scaled = scaled->next;
-
- /* output size changed since last scaling (need to re-scale) ? */
- if (scaled &&
- (scaled->output_width != this->output_width ||
- scaled->output_height != this->output_height)) {
-
- LOGOSD("re-scaling required: output size changed %dx%d -> %dx%d",
- scaled->output_width, scaled->output_height, this->output_width, this->output_height);
-
- osd_data_remove(&this->active_osds, scaled);
- scaled = NULL;
- }
-
- /* not scaled found ? */
- if (!scaled) {
- LOGOSD("scaling OSD");
- scaled = this->active_osds = osd_data_init(overlay, this->active_osds,
- this->factor_x, this->factor_y);
- scaled->output_width = this->output_width;
- scaled->output_height = this->output_height;
- }
-
- /* override */
- overlay = &scaled->ovl;
- }
-
- return overlay;
-}
-
-
-/*
- * interface
- */
-
-/*
- * override overlay_blend()
- */
-static void osdscaler_overlay_blend (vo_driver_t *self, vo_frame_t *frame, vo_overlay_t *overlay)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t*)self;
-
- overlay = scale_overlay(this, frame, overlay);
-
- /* redirect */
- if (this->h.orig_driver->overlay_blend)
- this->h.orig_driver->overlay_blend(this->h.orig_driver, frame, overlay);
-}
-
-/*
- * override overlay_end()
- */
-static void osdscaler_overlay_end (vo_driver_t *self, vo_frame_t *vo_img)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t*)self;
-
- /* redirect */
- if (this->h.orig_driver->overlay_end)
- this->h.orig_driver->overlay_end(this->h.orig_driver, vo_img);
-}
-
-
-/*
- * Management interface
- */
-
-/*
- * override get_capabilities()
- */
-static uint32_t osdscaler_get_capabilities(vo_driver_t *self)
-{
- return vo_def_get_capabilities(self) |
- VO_CAP_OSDSCALING;
-}
-
-/*
- * override get_property()
- */
-static int osdscaler_get_property(vo_driver_t *self, int prop)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t*)self;
-
- switch (prop) {
- case VO_PROP_OSD_SCALING: return this->enable;
- default:;
- }
-
- return vo_def_get_property(self, prop);
-}
-
-/*
- * override set_property()
- */
-static int osdscaler_set_property(vo_driver_t *self, int prop, int val)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t*)self;
-
- switch (prop) {
- case VO_PROP_OSD_SCALING:
- if (this->enable != val) {
- LOGOSD("osdscaler_set_property: enable %d->%d", this->enable, val);
- this->enable = val?1:0;
- }
- return this->enable;
- }
-
- return vo_def_set_property(self, prop, val);
-}
-
-
-/*
- * dispose()
- */
-static void osdscaler_dispose(vo_driver_t *self)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t *) self;
-
- osd_data_clear(this->active_osds);
-
- vo_def_dispose(self);
-}
-
-
-/*
- * init()
- */
-vo_driver_t *osdscaler_init(void)
-{
- osdscaler_hook_t *this = calloc(1, sizeof(osdscaler_hook_t));
-
- /* OSD interface */
- this->h.vo.overlay_begin = osdscaler_overlay_begin;
- this->h.vo.overlay_blend = osdscaler_overlay_blend;
- this->h.vo.overlay_end = osdscaler_overlay_end;
-
- /* management interface */
- this->h.vo.get_capabilities = osdscaler_get_capabilities;
- this->h.vo.get_property = osdscaler_get_property;
- this->h.vo.set_property = osdscaler_set_property;
-
- this->h.vo.dispose = osdscaler_dispose;
-
- /* initialize data */
- this->enable = 0;
-
- return &this->h.vo;
-}
-
diff --git a/xine/vo_osdscaler.h b/xine/vo_osdscaler.h
deleted file mode 100644
index fe7d21d0..00000000
--- a/xine/vo_osdscaler.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * vo_osdscaler.h: OSD scaling video-out post plugin
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vo_osdscaler.h,v 1.1 2008-11-20 09:24:27 phintuka Exp $
- *
- */
-
-#ifndef _XINELIBOUTPUT_VO_OSDSCALER_H
-#define _XINELIBOUTPUT_VO_OSDSCALER_H
-
-vo_driver_t *osdscaler_init(void);
-
-#endif /* _XINELIBOUTPUT_VO_OSDSCALER_H */
diff --git a/xine/vo_post.h b/xine/vo_post.h
deleted file mode 100644
index 8ed7b076..00000000
--- a/xine/vo_post.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * vo_post.h: Intercept video driver
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vo_post.h,v 1.3 2008-12-14 01:19:21 phintuka Exp $
- *
- */
-
-#ifndef _XINELIBOUTPUT_VO_POST_H
-#define _XINELIBOUTPUT_VO_POST_H
-
-#include <xine/video_out.h>
-
-/*
- * synchronous video post plugins
- * public API
- */
-
-/* Wire / unwire hook chain to video port */
-int wire_video_driver(xine_video_port_t *video_port, vo_driver_t *hook);
-int unwire_video_driver(xine_video_port_t *video_port, vo_driver_t *hook, vo_driver_t *video_out);
-
-#endif /* _XINELIBOUTPUT_VO_POST_H */
diff --git a/xine/vo_props.h b/xine/vo_props.h
deleted file mode 100644
index dc377dfc..00000000
--- a/xine/vo_props.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * vo_props.h: Extended video-out capabilities and properties
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vo_props.h,v 1.4 2009-03-17 12:20:33 phintuka Exp $
- *
- */
-
-#ifndef XINELIBOUTPUT_VO_PROPS_H_
-#define XINELIBOUTPUT_VO_PROPS_H_
-
-/*
- * Extended vo capabilities
- */
-
-/* output can scale OSD */
-#ifdef VO_CAP_CUSTOM_EXTENT_OVERLAY
- /* xine-lib 1.2 */
-# define VO_CAP_OSDSCALING VO_CAP_CUSTOM_EXTENT_OVERLAY
-#else
-# define VO_CAP_OSDSCALING 0x01000000
-#endif
-
-/* Output can blend ARGB surfaces */
-#ifdef VO_CAP_ARGB_LAYER_OVERLAY
-# define VO_CAP_ARGB VO_CAP_ARGB_LAYER_OVERLAY
-#else
-# define VO_CAP_ARGB 0x02000000
-#endif
-
-
-/*
- * Extended vo properties
- */
-
-/* enable/disable OSD scaling */
-#define VO_PROP_OSD_SCALING 0x1001
-
-
-/*
- * VDR OSD tagging and extra data
- */
-
-/* VDR OSD , stored in overlay hili_rgb_clut member */
-#define VDR_OSD_MAGIC -9999
-
-/* VDR OSD extra data, stored in overlay hili clut data */
-typedef struct {
- /* extent of reference coordinate system */
- uint16_t extent_width;
- uint16_t extent_height;
- /* overlay layer */
- uint32_t layer;
- /* scaling: 0 - disable , 1...N - quality */
- uint8_t scaling;
-} vdr_osd_extradata_t;
-
-#endif /* XINELIBOUTPUT_VO_PROPS_H_ */
diff --git a/xine/xvdr_metronom.c b/xine/xvdr_metronom.c
deleted file mode 100644
index 1a2316ab..00000000
--- a/xine/xvdr_metronom.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * xvdr_metronom.c:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xvdr_metronom.c,v 1.1 2009-05-22 21:02:30 phintuka Exp $
- *
- */
-
-#include <stdlib.h>
-
-#include <xine/xine_internal.h>
-#include <xine/metronom.h>
-
-#define LOG_MODULENAME "[metronom ] "
-#define SysLogLevel iSysLogLevel
-#include "../logdefs.h"
-
-#define XVDR_METRONOM_COMPILE
-#include "xvdr_metronom.h"
-
-
-static void got_video_frame(metronom_t *metronom, vo_frame_t *frame)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
-
- this->video_frames++;
-
- if (this->frame_decoded)
- this->frame_decoded(this->handle, this->video_frames, this->audio_frames);
-
- return this->orig_metronom->got_video_frame (this->orig_metronom, frame);
-}
-
-static int64_t got_audio_samples(metronom_t *metronom, int64_t pts, int nsamples)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
-
- this->audio_frames++;
-
- if (this->frame_decoded)
- this->frame_decoded(this->handle, this->video_frames, this->audio_frames);
-
- return this->orig_metronom->got_audio_samples (this->orig_metronom, pts, nsamples);
-}
-
-/*
- * dummy hooks
- */
-
-static int64_t got_spu_packet(metronom_t *metronom, int64_t pts)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
- return this->orig_metronom->got_spu_packet(this->orig_metronom, pts);
-}
-
-static void handle_audio_discontinuity(metronom_t *metronom, int type, int64_t disc_off)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
- this->orig_metronom->handle_audio_discontinuity(this->orig_metronom, type, disc_off);
-}
-
-static void handle_video_discontinuity(metronom_t *metronom, int type, int64_t disc_off)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
- this->orig_metronom->handle_video_discontinuity(this->orig_metronom, type, disc_off);
-}
-
-static void set_audio_rate(metronom_t *metronom, int64_t pts_per_smpls)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
- this->orig_metronom->set_audio_rate(this->orig_metronom, pts_per_smpls);
-}
-
-static void set_option(metronom_t *metronom, int option, int64_t value)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
- this->orig_metronom->set_option(this->orig_metronom, option, value);
-}
-
-static int64_t get_option(metronom_t *metronom, int option)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
- return this->orig_metronom->get_option(this->orig_metronom, option);
-}
-
-static void set_master(metronom_t *metronom, metronom_t *master)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
- this->orig_metronom->set_master(this->orig_metronom, master);
-}
-
-static void metronom_exit(metronom_t *metronom)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
-
- LOGERR("xvdr_metronom: metronom_exit() called !");
-
- /* un-hook */
- this->stream->metronom = this->orig_metronom;
- this->orig_metronom = NULL;
- this->stream = NULL;
-
- this->orig_metronom->exit(this->orig_metronom);
-}
-
-/*
- * xvdr_metronom_t
- */
-
-static void xvdr_metronom_set_cb(xvdr_metronom_t *this,
- void (*cb)(void*, uint, uint),
- void *handle)
-{
- this->handle = handle;
- this->frame_decoded = cb;
-}
-
-static void xvdr_metronom_dispose(xvdr_metronom_t *this)
-{
- if (this->stream && this->orig_metronom)
- this->stream->metronom = this->orig_metronom;
-
- free(this);
-}
-
-static void xvdr_metronom_reset_frames(xvdr_metronom_t *this)
-{
- this->video_frames = this->audio_frames = 0;
-}
-
-/*
- * init
- */
-
-xvdr_metronom_t *xvdr_metronom_init(xine_stream_t *stream)
-{
- xvdr_metronom_t *this = calloc(1, sizeof(xvdr_metronom_t));
-
- this->stream = stream;
- this->orig_metronom = stream->metronom;
-
- this->set_cb = xvdr_metronom_set_cb;
- this->reset_frames = xvdr_metronom_reset_frames;
- this->dispose = xvdr_metronom_dispose;
-
- this->metronom.set_audio_rate = set_audio_rate;
- this->metronom.got_video_frame = got_video_frame;
- this->metronom.got_audio_samples = got_audio_samples;
- this->metronom.got_spu_packet = got_spu_packet;
- this->metronom.handle_audio_discontinuity = handle_audio_discontinuity;
- this->metronom.handle_video_discontinuity = handle_video_discontinuity;
- this->metronom.set_option = set_option;
- this->metronom.get_option = get_option;
- this->metronom.set_master = set_master;
-
- this->metronom.exit = metronom_exit;
-
- /* hook up to stream */
- this->stream->metronom = &this->metronom;
-
- return this;
-}
diff --git a/xine/xvdr_metronom.h b/xine/xvdr_metronom.h
deleted file mode 100644
index 21188f28..00000000
--- a/xine/xvdr_metronom.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * xvdr_metronom.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xvdr_metronom.h,v 1.1 2009-05-22 21:02:30 phintuka Exp $
- *
- */
-
-#ifndef XVDR_METRONOM_H
-#define XVDR_METRONOM_H
-
-typedef struct xvdr_metronom_s xvdr_metronom_t;
-
-struct xvdr_metronom_s {
- /* xine-lib metronom interface */
- metronom_t metronom;
-
- /* management interface */
- void (*set_cb) (xvdr_metronom_t *,
- void (*cb) (void *, uint, uint),
- void *);
- void (*reset_frames)(xvdr_metronom_t *);
- void (*dispose) (xvdr_metronom_t *);
-
- /* accumulated frame data */
- volatile uint video_frames;
- volatile uint audio_frames;
-
- /* private data */
-
-#ifdef XVDR_METRONOM_COMPILE
-
- /* original metronom */
- metronom_t *orig_metronom;
- xine_stream_t *stream;
-
- /* callback */
- void *handle;
- void (*frame_decoded)(void *handle, uint video_count, uint audio_count);
-
-#endif
-};
-
-xvdr_metronom_t *xvdr_metronom_init(xine_stream_t *);
-
-
-#endif /* XVDR_METRONOM_H */
diff --git a/xine_fbfe_frontend.c b/xine_fbfe_frontend.c
deleted file mode 100644
index b1394dec..00000000
--- a/xine_fbfe_frontend.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * xine_fbfe_frontend.c: Simple front-end, framebuffer functions
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xine_fbfe_frontend.c,v 1.45 2009-05-31 16:51:26 phintuka Exp $
- *
- */
-
-#include <inttypes.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#if defined(__linux__)
-# include <linux/kd.h>
-#endif
-
-#define LOG_MODULENAME "[vdr-fbfe] "
-#include "logdefs.h"
-
-#include "xine_frontend_internal.h"
-
-
-/*
- * data
- */
-
-typedef struct fbfe_s {
-
- /* function pointers / base class */
- union {
- frontend_t fe; /* generic frontend */
- fe_t x; /* xine frontend */
- };
-
- /* stored original handlers */
- int (*fe_xine_init)(frontend_t *this_gen, const char *audio_driver,
- const char *audio_port,
- const char *video_driver,
- int pes_buffers,
- const char *static_post_plugins,
- const char *config_file);
-
- /* display */
-/*char *modeline;*/
- int fd_tty;
-
- /* frontend */
- uint8_t fullscreen : 1;
-/*uint8_t vmode_switch : 1;*/
-
-} fbfe_t;
-
-static void fbfe_update_display_size(fe_t *this_gen)
-{
- fbfe_t *this = (fbfe_t*)this_gen;
- if(this->fullscreen && this->x.video_port) {
- this->x.width = this->x.video_port->get_property(this->x.video_port,
- VO_PROP_WINDOW_WIDTH);
- this->x.height = this->x.video_port->get_property(this->x.video_port,
- VO_PROP_WINDOW_HEIGHT);
- LOGDBG("Framebuffer size after initialization: %dx%d",
- this->x.width, this->x.height);
- }
-}
-
-/*
- * update_DFBARGS
- *
- * (optionally) add fbdev option to DFBARGS environment variable
- */
-static void update_DFBARGS(const char *fb_dev)
-{
- const char *env_old = getenv("DFBARGS");
- char *env_new = NULL;
-
- if (env_old) {
- char *env_tmp = strdup(env_old);
- char *head = strstr(env_tmp, "fbdev=");
-
- if (head) {
- char *tail = strchr(head, ',');
- if(head == env_tmp)
- head = NULL;
- else
- *head = 0;
- if(asprintf(&env_new, "%sfbdev=%s%s",
- head ? env_tmp : "", fb_dev, tail ? tail : "") < 0) {
- free(env_tmp);
- return;
- }
- } else {
- if(asprintf(&env_new, "fbdev=%s%s%s", fb_dev, env_tmp ? "," : "", env_tmp ?: "") < 0) {
- free(env_tmp);
- return;
- }
- }
- free(env_tmp);
-
- LOGMSG("replacing environment variable DFBARGS with %s (original was %s)",
- env_new, env_old);
-
- } else {
- if(asprintf(&env_new, "fbdev=%s", fb_dev) < 0)
- return;
-
- LOGMSG("setting environment variable DFBARGS to %s", env_new);
- }
-
- setenv("DFBARGS", env_new, 1);
- free(env_new);
-}
-
-/*
- * fbfe_display_open
- */
-static int fbfe_display_open(frontend_t *this_gen,
- int xpos, int ypos,
- int width, int height, int fullscreen, int hud,
- int modeswitch, const char *modeline, int aspect,
- fe_keypress_f keyfunc, int no_x_kbd, int gui_hotkeys,
- const char *video_port, int scale_video, int field_order,
- const char *aspect_controller, int window_id)
-{
- fbfe_t *this = (fbfe_t*)this_gen;
-
- if(!this)
- return 0;
-
- if(this->fd_tty >= 0)
- this->fe.fe_display_close(this_gen);
-
- if(keyfunc) {
- this->x.keypress = keyfunc;
- this->x.keypress("KBD", "");
- }
-
- LOGDBG("fbfe_display_open(width=%d, height=%d, fullscreen=%d, display=%s)",
- width, height, fullscreen, video_port);
-
- this->x.xpos = xpos;
- this->x.ypos = ypos;
- this->x.width = width;
- this->x.height = height;
- this->x.aspect = aspect;
-/*this->x.cropping = 0;*/
- this->x.field_order = field_order;
- this->x.scale_video = scale_video;
- this->x.overscan = 0;
- this->x.display_ratio = 1.0;
- this->x.aspect_controller = aspect_controller ? strdup(aspect_controller) : NULL;
-
- this->fullscreen = fullscreen;
-/*this->vmode_switch = modeswitch;*/
-/*this->modeline = strdup(modeline ?: "");*/
-
- /* setup xine FB visual */
- this->x.xine_visual_type = XINE_VISUAL_TYPE_FB;
- this->x.vis_fb.frame_output_cb = this->x.frame_output_handler;
- this->x.vis_fb.user_data = this;
-
- /* select framebuffer device ? */
- if(video_port && !strncmp(video_port, "/dev/", 5))
- this->x.video_port_name = strdup(video_port);
- else
- this->x.video_port_name = NULL;
-
- /* set console to graphics mode */
-#if defined(KDSETMODE) && defined(KD_GRAPHICS)
- if (isatty(STDIN_FILENO))
- this->fd_tty = dup(STDIN_FILENO);
- else
- this->fd_tty = open("/dev/tty", O_RDWR);
-
- if(this->fd_tty < 0)
- LOGERR("fbfe_display_open: error opening /dev/tty");
- else if (ioctl(this->fd_tty, KDSETMODE, KD_GRAPHICS) == -1)
- LOGERR("fbfe_display_open: failed to set /dev/tty to graphics mode");
-#else
-# warning No support for console graphics mode
- this->fd_tty = -1;
-#endif
-
- return 1;
-}
-
-/*
- * fbfe_display_config
- *
- * configure windows
- */
-static int fbfe_display_config(frontend_t *this_gen,
- int xpos, int ypos,
- int width, int height, int fullscreen,
- int modeswitch, const char *modeline,
- int aspect, int scale_video, int field_order)
-{
- fbfe_t *this = (fbfe_t*)this_gen;
-
- if(!this)
- return 0;
-
- this->x.xpos = xpos >= 0 ? xpos : this->x.xpos;
- this->x.ypos = ypos >= 0 ? ypos : this->x.ypos;
- this->x.width = width >= 0 ? width : this->x.width;
- this->x.height = height >= 0 ? height : this->x.height;
- this->x.aspect = aspect;
- this->x.scale_video = scale_video;
- this->x.field_order = field_order;
- this->fullscreen = fullscreen;
-/*this->vmode_switch = modeswitch;*/
-#if 0
- if(!modeswitch && strcmp(modeline, this->modeline)) {
- free(this->modeline);
- this->modeline = strdup(modeline ?: "");
- /* #warning XXX TODO - switch vmode */
- }
-#endif
-
- return 1;
-}
-
-static void fbfe_interrupt(frontend_t *this_gen)
-{
- /* stop fbfe_run() */
-}
-
-static int fbfe_run(frontend_t *this_gen)
-{
- fbfe_t *this = (fbfe_t*)this_gen;
-
- if (!this || this->fe.xine_is_finished(this_gen, 0) != FE_XINE_RUNNING)
- return 0;
-
- /* just sleep 500ms */
- select(0, NULL, NULL, NULL, &(struct timeval){ .tv_sec = 0, .tv_usec = 500*1000 });
-
- return 1;
-}
-
-static void fbfe_display_close(frontend_t *this_gen)
-{
- fbfe_t *this = (fbfe_t*)this_gen;
-
- if (!this)
- return;
-
- if (this->x.xine)
- this->fe.xine_exit(this_gen);
-
- if (this->fd_tty >= 0) {
-#if defined(KDSETMODE) && defined(KD_TEXT)
- if(ioctl(this->fd_tty, KDSETMODE, KD_TEXT) == -1)
- LOGERR("fbfe_display_close: failed to set /dev/tty to text mode");
-#endif
- close(this->fd_tty);
- this->fd_tty = -1;
- }
-
- free(this->x.video_port_name);
- this->x.video_port_name = NULL;
-
- free(this->x.aspect_controller);
- this->x.aspect_controller = NULL;
-#if 0
- free(this->modeline);
- this->modeline = NULL;
-#endif
-}
-
-static int fbfe_xine_init(frontend_t *this_gen, const char *audio_driver,
- const char *audio_port,
- const char *video_driver,
- int pes_buffers,
- const char *static_post_plugins,
- const char *config_file)
-{
- fbfe_t *this = (fbfe_t*)this_gen;
-
- if (video_driver && !strcmp(video_driver, "DirectFB"))
- update_DFBARGS(this->x.video_port_name);
-
- return this->fe_xine_init(this_gen, audio_driver, audio_port,
- video_driver, pes_buffers, static_post_plugins, config_file);
-}
-
-static frontend_t *fbfe_get_frontend(void)
-{
- fbfe_t *this = calloc(1, sizeof(fbfe_t));
-
- this->fd_tty = -1;
-
- init_fe((fe_t*)this);
-
- this->fe.fe_display_open = fbfe_display_open;
- this->fe.fe_display_config = fbfe_display_config;
- this->fe.fe_display_close = fbfe_display_close;
-
- this->fe.fe_run = fbfe_run;
- this->fe.fe_interrupt = fbfe_interrupt;
-
- this->x.update_display_size_cb = fbfe_update_display_size;
-
- /* override */
- this->fe_xine_init = this->fe.xine_init;
- this->fe.xine_init = fbfe_xine_init;
-
- return (frontend_t*)this;
-}
-
-/* ENTRY POINT */
-const fe_creator_f fe_creator __attribute__((visibility("default"))) = fbfe_get_frontend;
-
-
diff --git a/xine_frontend.c b/xine_frontend.c
deleted file mode 100644
index ff98270f..00000000
--- a/xine_frontend.c
+++ /dev/null
@@ -1,1854 +0,0 @@
-/*
- * xine_frontend.c:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xine_frontend.c,v 1.97 2009-03-17 12:16:23 phintuka Exp $
- *
- */
-
-#include "features.h"
-
-#include <inttypes.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#ifdef HAVE_LIBJPEG
-# ifdef boolean
-# define HAVE_BOOLEAN
-# endif
-# include <jpeglib.h>
-# undef boolean
-#endif
-
-#define XINE_ENGINE_INTERNAL
-#include <xine.h>
-#include <xine/xine_internal.h>
-
-#define LOG_MODULENAME "[vdr-fe] "
-#include "logdefs.h"
-
-#include "xine_frontend_internal.h"
-#include "xine/post.h"
-
-#include "xine/vo_post.h"
-#include "xine/vo_osdscaler.h"
-#include "xine/vo_osdreorder.h"
-
-#undef MIN
-#define MIN(a,b) ( (a) < (b) ? (a) : (b))
-#undef MAX
-#define MAX(a,b) ( (a) > (b) ? (a) : (b))
-
-
-static void intercept_video_driver(xine_video_port_t *video_port)
-{
- vo_driver_t *osdscaler = osdscaler_init();
- if (! wire_video_driver(video_port, osdscaler)) {
- LOGMSG("wire_video_driver() for osdscaler failed");
- osdscaler->dispose(osdscaler);
- }
-
- vo_driver_t *osdreorder = osd_reorder_init();
- if (! wire_video_driver(video_port, osdreorder)) {
- LOGMSG("wire_video_driver() for osdreorder failed");
- osdreorder->dispose(osdreorder);
- }
-}
-
-
-char *strn0cpy(char *dest, const char *src, int n)
-{
- char *s = dest;
- for ( ; --n && (*dest = *src) != 0; dest++, src++) ;
- *dest = 0;
- return s;
-}
-
-static int guess_cpu_count(void)
-{
- static int cores = -1;
- FILE *f;
-
- if(cores >= 0)
- return cores;
-
- cores = 0;
- if(NULL != (f = fopen("/proc/cpuinfo", "r"))) {
- char buf[256];
- while (NULL != fgets(buf, 255, f))
- sscanf(buf, "processor : %d", &cores);
- fclose(f);
- }
- cores++;
-
- if(cores > 1)
- LOGMSG("Detected %d CPUs", cores);
- else
- LOGDBG("Detected single CPU. Multithreaded decoding and post processing disabled.");
-
- return cores;
-}
-
-/*
- * list available plugins
- */
-
-static void list_plugins_type(xine_t *xine, const char *msg, typeof (xine_list_audio_output_plugins) list_func)
-{
- static xine_t *tmp_xine = NULL;
- if(!xine) {
- if(!tmp_xine)
- xine_init(tmp_xine = xine_new());
- xine = tmp_xine;
- }
- const char *const *list = list_func(xine);
-
- printf("%s", msg);
- while(list && *list)
- printf(" %s", *list++);
- printf("\n");
-}
-
-void list_xine_plugins(frontend_t *fe, int verbose)
-{
- fe_t *this = (fe_t *)fe;
-
- xine_t *tmp_xine = NULL;
- xine_t *xine = this ? this->xine : NULL;
-
- if (!xine)
- xine_init(xine = tmp_xine = xine_new());
-
- list_plugins_type (xine, "Available video drivers:", xine_list_video_output_plugins);
- list_plugins_type (xine, "Available audio drivers:", xine_list_audio_output_plugins);
- if (verbose) {
- list_plugins_type (xine, "Available post plugins: ", xine_list_post_plugins);
- list_plugins_type (xine, "Available input plugins:", xine_list_input_plugins);
- list_plugins_type (xine, "Available demux plugins:", xine_list_demuxer_plugins);
- list_plugins_type (xine, "Available audio decoder plugins:", xine_list_audio_decoder_plugins);
- list_plugins_type (xine, "Available video decoder plugins:", xine_list_video_decoder_plugins);
- list_plugins_type (xine, "Available SPU decoder plugins: ", xine_list_spu_plugins);
- }
-
- if (tmp_xine)
- xine_exit(tmp_xine);
-}
-
-/*
- * detect input plugin
- */
-
-static int find_input_plugin(fe_t *this)
-{
- if(!this->input_plugin) {
- if(!this->stream || !this->stream->input_plugin ||
- !this->stream->input_plugin->input_class || this->playback_finished) {
- LOGMSG("find_input_plugin: stream not initialized or playback finished !");
- usleep(100*1000);
- return 0;
- }
-#if XINE_VERSION_CODE < 10190
- if(strcmp(this->stream->input_plugin->input_class->get_identifier(
- this->stream->input_plugin->input_class),
- MRL_ID)) {
-#else
- if(strcmp(this->stream->input_plugin->input_class->identifier,
- MRL_ID)) {
-#endif
- LOGMSG("find_input_plugin: current xine input plugin is not " MRL_ID " !");
- return 0;
- }
- this->input_plugin = (vdr_input_plugin_if_t*)this->stream->input_plugin;
- }
- return 1;
-}
-
-static void *fe_control(frontend_t *this_gen, const char *cmd);
-
-/*
- * xine callbacks
- */
-
-static double fe_dest_pixel_aspect(const fe_t *this, double video_pixel_aspect,
- int video_width, int video_height)
-{
- /*int new_cropping = 0;*/
- double result = 1.0;
-
- if(!this->scale_video) {
-
- /*#warning what to do if scaling disabled ???*/
-
- /*return video_pixel_aspect;*/
- }
-
- switch(this->aspect) {
- /* Auto */
- default: {
- double correction =
- ((double)video_width/(double)video_height) /
- ((double)this->width/(double)this->height);
-
- result = video_pixel_aspect * correction;
- if(result > (16.9/9.0 * (double)this->height/
- (double)this->width))
- result = (16.0/9.0 * (double)this->height/
- (double)this->width);
- break;
- }
- /* Default */
- case 1: result = this->display_ratio; break;
-
- /* 4:3 */
- case 2: result = (4.0/3.0 * (double)this->height/(double)this->width); break;
- /* 16:9 */
- case 3: result = (16.0/9.0 * (double)this->height/(double)this->width); break;
- /* 16:10 */
- case 4: result = (16.0/10.0 * (double)this->height/(double)this->width); break;
- /* Pan&Scan */
- case 5: {
- double aspect_diff /*= video_pixel_aspect - 1.0*/;
- /* TODO */
- /* does not work (?) */
-aspect_diff=(video_pixel_aspect*(double)video_width/(double)video_height) - 4.0 / 3.0;
- if ((aspect_diff < 0.05) && (aspect_diff > -0.05)) {
- result = (4.0/3.0 * (double)this->height/(double)this->width);
- /*LOGDBG("diff: %f", aspect_diff);*/
- /*new_cropping = 1;*/
- } else {
- result = (16.0/9.0 * (double)this->height/(double)this->width);
- }
- /*result = (4.0/3.0 * (double)this->height/(double)this->width);*/
- break;
- }
- /* center cut-out */
- case 6: {
-/*#warning center cut-out mode not implemented*/
- break;
- }
-
- }
-#if 0
- if(this->cropping && !new_cropping) {
- LOGDBG("pan&scan CROP OFF");
- xine_set_param(this->stream, XINE_PARAM_VO_CROP_LEFT, 0);
- xine_set_param(this->stream, XINE_PARAM_VO_CROP_TOP, 72);
- xine_set_param(this->stream, XINE_PARAM_VO_CROP_RIGHT, 0);
- xine_set_param(this->stream, XINE_PARAM_VO_CROP_BOTTOM, 72);
- this->cropping = 0;
- }
- if(!this->cropping && new_cropping) {
- LOGDBG("pan&scan CROP ON");
- /*** Should set unscaled osd (or top & bottom will be cropped off) */
- xine_set_param(this->stream, XINE_PARAM_VO_CROP_LEFT, 0);
- xine_set_param(this->stream, XINE_PARAM_VO_CROP_TOP, 0);
- xine_set_param(this->stream, XINE_PARAM_VO_CROP_RIGHT, 0);
- xine_set_param(this->stream, XINE_PARAM_VO_CROP_BOTTOM, 0);
- this->cropping = 1;
- }
-#endif
-
- return result;
-}
-
-static void fe_frame_output_cb (void *data,
- int video_width, int video_height,
- double video_pixel_aspect,
- int *dest_x, int *dest_y,
- int *dest_width, int *dest_height,
- double *dest_pixel_aspect,
- int *win_x, int *win_y)
-{
- fe_t *this = (fe_t *)data;
-
- if (!this)
- return;
-
- *dest_width = this->width;
- *dest_height = this->height;
- *dest_x = 0;
-#ifndef HAVE_XV_FIELD_ORDER
- *dest_y = 0 + this->field_order;
-#else
- *dest_y = 0;
-#endif
-
-#if 1
- if(!this->scale_video) {
- if(video_height < this->height) {
- *dest_height = video_height;
- *dest_y = (this->height - video_height) / 2;
- }
- if(video_width < this->width) {
- *dest_width = video_width;
- *dest_x = (this->width - video_width) / 2;
- }
- }
-#endif
-
- *win_x = this->xpos;
- *win_y = this->ypos;
-
- *dest_pixel_aspect = this->dest_pixel_aspect(this, video_pixel_aspect,
- video_width, video_height);
-
-#if 0
- if(this->cropping) {
- *dest_pixel_aspect = *dest_pixel_aspect * (16.0/9.0)/(4.0/3.0);
- *dest_y = *dest_y - 72;
- *dest_height = *dest_height + 144;
- }
-#endif
-
-#if 0
- /* video_out cropping works better */
- if(this->overscan) {
- int crop_x = this->overscan * this->width / 100 / 2;
- int crop_y = this->overscan * this->height / 100 / 2;
- *dest_x -= crop_x;
- *dest_y -= crop_y;
- *dest_width += crop_x;
- *dest_height += crop_y;
- }
-#endif
-
- if(!this->stream)
- return;
-
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO,
- (int)(10000.0*video_pixel_aspect *
- ((double)video_width)/((double)video_height)));
- if(this->video_width != video_width ||
- this->video_height != video_height) {
- xine_format_change_data_t framedata = {
- .width = video_width,
- .height = video_height,
- .aspect = 0, /* TODO */
- .pan_scan = 0,
- };
- const xine_event_t event = {
- .type = XINE_EVENT_FRAME_FORMAT_CHANGE,
- .stream = this->stream,
- .data = &framedata,
- .data_length = sizeof(framedata),
- };
- xine_event_send(this->stream, &event);
- this->video_width = video_width;
- this->video_height = video_height;
-#if 0
- /* trigger forced redraw to make cropping changes effective */
- if(this->cropping)
- xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_X, 100);
-#endif
- }
-
- if(this->aspect_controller) {
- double video_aspect = (video_pixel_aspect * (double)video_width / (double)video_height);
- double aspect_diff = video_aspect - this->video_aspect;
- if ((aspect_diff > 0.05) || (aspect_diff < -0.05)) {
- char cmd[4096];
- if(snprintf(cmd, sizeof(cmd), "%s %d",
- this->aspect_controller, (int)(video_aspect * 10000.0))
- < sizeof(cmd)) {
- LOGDBG("Aspect ratio changed, executing %s", cmd);
- if(system(cmd) == -1)
- LOGERR("Executing /bin/sh -c %s failed", cmd);
- this->video_aspect = video_aspect;
- }
- }
- }
-}
-
-static void xine_event_cb (void *user_data, const xine_event_t *event)
-{
- fe_t *this = (fe_t *)user_data;
-
- switch (event->type) {
- /* in local mode: vdr stream / slave stream ; in remote mode: vdr stream only */
- case XINE_EVENT_UI_PLAYBACK_FINISHED:
- LOGMSG("xine_event_cb: XINE_EVENT_UI_PLAYBACK_FINISHED");
- if(this) {
- if(event->stream == this->stream)
- this->playback_finished = 1;
- } else {
- LOGMSG("xine_event_cb: NO USER DATA !");
- }
- break;
- default: break;
- }
-}
-
-/*
- * fe_xine_init
- *
- * initialize xine engine, initialize audio and video ports, setup stream
- */
-
-#define MONO 0
-#define STEREO 1
-#define HEADPHONES 2
-#define SURROUND21 3
-#define SURROUND3 4
-#define SURROUND4 5
-#define SURROUND41 6
-#define SURROUND5 7
-#define SURROUND51 8
-#define SURROUND6 9
-#define SURROUND61 10
-#define SURROUND71 11
-#define A52_PASSTHRU 12
-
-#define x_reg_num(x...) xine_config_register_num(this->xine, x)
-#define x_reg_str(x...) xine_config_register_string(this->xine, x)
-#define x_reg_enum(x...) xine_config_register_enum(this->xine, x)
-#define x_reg_bool(x...) xine_config_register_bool(this->xine, x)
-
-#define x_upd_num(x...) this->xine->config->update_num(this->xine->config, x)
-#define x_upd_str(x...) this->xine->config->update_string(this->xine->config, x)
-
-static void configure_audio_out(const fe_t *this, const char *audio_driver, const char *audio_port)
-{
- /*
- * alsa
- */
- if(audio_driver && audio_port && !strcmp("alsa", audio_driver) && strlen(audio_port) > 0) {
-
- /* define possible speaker arrangements */
- /* From xine audio_alsa_out.c ; must be synchronized ! */
- static char *speaker_arrangement[] =
- {"Mono 1.0", "Stereo 2.0", "Headphones 2.0", "Stereo 2.1",
- "Surround 3.0", "Surround 4.0", "Surround 4.1",
- "Surround 5.0", "Surround 5.1", "Surround 6.0",
- "Surround 6.1", "Surround 7.1", "Pass Through", NULL};
-
- x_reg_enum("audio.output.speaker_arrangement",
- STEREO,
- speaker_arrangement,
- _("speaker arrangement"),
- _("Select how your speakers are arranged, "
- "this determines which speakers xine uses for sound output. "
- "The individual values are:\n\n"
- "Mono 1.0: You have only one speaker.\n"
- "Stereo 2.0: You have two speakers for left and right channel.\n"
- "Headphones 2.0: You use headphones.\n"
- "Stereo 2.1: You have two speakers for left and right channel, and one "
- "subwoofer for the low frequencies.\n"
- "Surround 3.0: You have three speakers for left, right and rear channel.\n"
- "Surround 4.0: You have four speakers for front left and right and rear "
- "left and right channels.\n"
- "Surround 4.1: You have four speakers for front left and right and rear "
- "left and right channels, and one subwoofer for the low frequencies.\n"
- "Surround 5.0: You have five speakers for front left, center and right and "
- "rear left and right channels.\n"
- "Surround 5.1: You have five speakers for front left, center and right and "
- "rear left and right channels, and one subwoofer for the low frequencies.\n"
- "Surround 6.0: You have six speakers for front left, center and right and "
- "rear left, center and right channels.\n"
- "Surround 6.1: You have six speakers for front left, center and right and "
- "rear left, center and right channels, and one subwoofer for the low frequencies.\n"
- "Surround 7.1: You have seven speakers for front left, center and right, "
- "left and right and rear left and right channels, and one subwoofer for the "
- "low frequencies.\n"
- "Pass Through: Your sound system will receive undecoded digital sound from xine. "
- "You need to connect a digital surround decoder capable of decoding the "
- "formats you want to play to your sound card's digital output."),
- 10, NULL, NULL);
-
- x_reg_str("audio.device.alsa_default_device",
- "default",
- _("device used for mono output"),
- _("xine will use this alsa device "
- "to output mono sound.\n"
- "See the alsa documentation "
- "for information on alsa devices."),
- 10, NULL, NULL);
- x_reg_str("audio.device.alsa_front_device",
- "plug:front:default",
- _("device used for stereo output"),
- _("xine will use this alsa device "
- "to output stereo sound.\n"
- "See the alsa documentation "
- "for information on alsa devices."),
- 10, NULL, NULL);
- x_reg_str("audio.device.alsa_surround51_device",
- "plug:surround51:0",
- _("device used for 5.1-channel output"),
- _("xine will use this alsa device to output "
- "5 channel plus LFE (5.1) surround sound.\n"
- "See the alsa documentation for information "
- "on alsa devices."),
- 10, NULL, NULL);
- x_reg_str("audio.device.alsa_passthrough_device",
- "iec958:AES0=0x6,AES1=0x82,AES2=0x0,AES3=0x2",
- _("device used for 5.1-channel output"),
- _("xine will use this alsa device to output "
- "undecoded digital surround sound. This can "
- "be used be external surround decoders.\nSee the "
- "alsa documentation for information on alsa "
- "devices."),
- 10, NULL, NULL);
-
- x_upd_str("audio.device.alsa_front_device", audio_port);
- x_upd_str("audio.device.alsa_default_device", audio_port);
- x_upd_str("audio.device.alsa_surround51_device", audio_port);
- if(strstr(audio_port, "iec") ||
- strstr(audio_port, "spdif")) {
- x_upd_str("audio.device.alsa_passthrough_device", audio_port);
- x_upd_num("audio.output.speaker_arrangement", A52_PASSTHRU);
- } else {
- x_upd_num("audio.output.speaker_arrangement",
- strstr(audio_port, "surround") ? SURROUND51 : STEREO);
- }
- }
-
-
- /*
- * OSS
- */
- if(audio_driver && !strcmp("oss", audio_driver) && audio_port) {
- int devnum = -2;
- if(!strcmp("default", audio_port))
- devnum = -1;
- if(!strncmp("/dev/dsp", audio_port, 8) &&
- sscanf(audio_port+8, "%d", &devnum) < 1)
- devnum = -1;
- if(!strncmp("/dev/sound/dsp", audio_port, 14) &&
- sscanf(audio_port+14, "%d", &devnum) < 1)
- devnum = -1;
- if(devnum > -2) {
- x_reg_num("audio.device.oss_device_number", -1,
- _("OSS audio device number, -1 for none"),
- _("The full audio device name is created by concatenating the "
- "OSS device name and the audio device number.\n"
- "If you do not need a number because you are happy with "
- "your system's default audio device, set this to -1.\n"
- "The range of this value is -1 or 0-15. This setting is "
- "ignored, when the OSS audio device name is set to \"auto\"."),
- 10, NULL, NULL);
- x_upd_num("audio.device.oss_device_num", devnum);
- }
- }
-}
-
-static int fe_xine_init(frontend_t *this_gen, const char *audio_driver,
- const char *audio_port,
- const char *video_driver,
- int pes_buffers,
- const char *static_post_plugins,
- const char *config_file)
-{
- fe_t *this = (fe_t*)this_gen;
- post_plugins_t *posts = NULL;
-
- if(!this)
- return 0;
-
- /* check xine-lib version */
- if(!xine_check_version(1, 1, 0)) {
- LOGERR("xine-lib is too old, require at least xine library version 1.1.0\n");
- return FE_ERROR;
- }
-
-
- /*
- * init xine engine
- */
-
- if(this->xine)
- this->fe.xine_exit(this_gen);
-
- this->stream = NULL;
- this->video_port = NULL;
- this->audio_port = NULL;
- this->input_plugin = NULL;
-
- /* create a new xine and load config file */
- this->xine = xine_new();
- if(!this->xine)
- return 0;
-
- /* Set xine engine logging verbosity */
- this->xine->verbosity = (SysLogLevel>2);
-
- /*xine_register_log_cb(this->xine, xine_log_cb, this);*/
-
- free(this->configfile);
- this->configfile = NULL;
- if (config_file)
- this->configfile = strdup(config_file);
- else if(asprintf(&this->configfile, "%s%s", xine_get_homedir(),
- "/.xine/config_xineliboutput") < 0)
- return 0;
-
- xine_config_load (this->xine, this->configfile);
-
- x_reg_num ("engine.buffers.video_num_buffers",
- 500,
- _("number of video buffers"),
- _("The number of video buffers "
- "(each is 8k in size) "
- "xine uses in its internal queue. "
- "Higher values "
- "mean smoother playback for unreliable "
- "inputs, but "
- "also increased latency and memory "
- "consumption."),
- 20, NULL, NULL);
- x_reg_bool("gui.osd_use_unscaled",
- 0,
- _("Use unscaled OSD"),
- _("Use unscaled (full screen resolution) OSD if possible"),
- 10, NULL, NULL);
-
- xine_init (this->xine);
-
- x_upd_num("video.device.xv_double_buffer", 1);
- x_upd_num("engine.buffers.video_num_buffers", pes_buffers);
-
- if(this->video_port_name) {
- if(video_driver && !strcmp(video_driver, "fb"))
- x_upd_str("video.device.fb_device", this->video_port_name);
- }
-
- this->playback_finished = 0;
-
- /* create video port */
- if(video_driver && !strcmp(video_driver, "none"))
- this->video_port = xine_open_video_driver(this->xine,
- video_driver,
- XINE_VISUAL_TYPE_NONE,
- NULL);
- else if(video_driver && !strcmp(video_driver, "dxr3"))
- this->video_port = xine_open_video_driver(this->xine,
- video_driver,
- XINE_VISUAL_TYPE_X11,
- NULL);
- else if(video_driver && !strcmp(video_driver, "aadxr3"))
- this->video_port = xine_open_video_driver(this->xine,
- video_driver,
- XINE_VISUAL_TYPE_AA,
- NULL);
- else
- this->video_port = xine_open_video_driver(this->xine,
- video_driver,
- this->xine_visual_type,
- (void *) &(this->vis));
- if(!this->video_port) {
- LOGMSG("fe_xine_init: xine_open_video_driver(\"%s\") failed",
- video_driver?video_driver:"(NULL)");
- xine_exit(this->xine);
- return 0;
- }
-
- intercept_video_driver(this->video_port);
-
- this->video_port_none = NULL;
-
- /* re-configure display size (DirectFB driver changes display mode in init) */
- if(this->update_display_size_cb)
- this->update_display_size_cb(this);
-
- /* create audio port */
-
- if(audio_driver && audio_port)
- configure_audio_out(this, audio_driver, audio_port);
-
- if(audio_driver && !strcmp(audio_driver, "auto")) {
- this->audio_port = xine_open_audio_driver (this->xine, NULL, NULL);
-#if XINE_VERSION_CODE < 10190
- } else if(audio_driver && !strcmp(audio_driver, "none")) {
- this->audio_port = _x_ao_new_port (this->xine, NULL, 1);
- this->audio_port->set_property(this->audio_port, AO_PROP_DISCARD_BUFFERS, 1);
-#endif
- } else {
- this->audio_port = xine_open_audio_driver (this->xine, audio_driver, NULL);
- }
-
- if(!this->audio_port && (audio_driver && !!strcmp(audio_driver, "none"))) {
- LOGMSG("fe_xine_init: xine_open_audio_driver(\"%s%s%s\") failed",
- audio_driver?audio_driver:"(NULL)",
- audio_port?":":"", audio_port?audio_port:"");
- }
-
- this->audio_port_none = NULL;
-
- /* create stream */
-
- this->stream = xine_stream_new(this->xine, this->audio_port, this->video_port);
- this->slave_stream = NULL;
-
- if(!this->stream) {
- LOGMSG("fe_xine_init: xine_stream_new failed");
- xine_exit(this->xine);
- return 0;
- }
-
- /* event handling */
-
- this->event_queue = xine_event_new_queue (this->stream);
- xine_event_create_listener_thread (this->event_queue, xine_event_cb, this);
-
- if(!this->event_queue)
- LOGMSG("fe_xine_init: xine_event_new_queue failed");
-
- /* misc. config */
-
- this->pes_buffers = pes_buffers;
-
- posts = this->postplugins = calloc(1, sizeof(post_plugins_t));
- posts->xine = this->xine;
- posts->audio_port = this->audio_port;
- posts->video_port = this->video_port;
- posts->video_source = posts->audio_source = this->stream;
-
- /* multithreaded decoding / post processing */
-
- if(guess_cpu_count() > 1) {
- if(!xine_check_version(1,1,9))
- LOGMSG("FFmpeg multithreaded video decoding is not supported in xine-lib < 1.1.9");
- else
- LOGMSG("Enabling FFmpeg multithreaded video decoding");
-
- /* try to enable anyway, maybe someone is using patched 1.1.8 ... */
- x_upd_num("video.processing.ffmpeg_thread_count", guess_cpu_count());
-#if 0
- LOGMSG("Enabling multithreaded post processing");
- vpplugin_parse_and_store_post(posts, "thread");
-#endif
- }
-
- /* static post plugins from command-line */
-
- if(static_post_plugins && *static_post_plugins) {
- int i;
- LOGDBG("static post plugins (from command line): %s", static_post_plugins);
- posts->static_post_plugins = strdup(static_post_plugins);
- vpplugin_parse_and_store_post(posts, posts->static_post_plugins);
- applugin_parse_and_store_post(posts, posts->static_post_plugins);
-
- for(i=0; i<posts->post_audio_elements_num; i++)
- if(posts->post_audio_elements[i])
- posts->post_audio_elements[i]->enable = 2;
- for(i=0; i<posts->post_video_elements_num; i++)
- if(posts->post_video_elements[i])
- posts->post_video_elements[i]->enable = 2;
- posts->post_video_enable = 1;
- posts->post_audio_enable = 1;
- }
-
- this->video_width = this->video_height = 0;
-
- return 1;
-}
-
-/*
- * fe_xine_open
- *
- * open xine stream
- */
-
-static int fe_xine_open(frontend_t *this_gen, const char *mrl)
-{
- fe_t *this = (fe_t*)this_gen;
- int result = 0;
- char *url = NULL;
-
- if(!this)
- return 0;
-
- this->input_plugin = NULL;
- this->playback_finished = 1;
- this->terminate_key_pressed = 0;
-
- if (asprintf(&url, "%s#nocache", mrl ? : MRL_ID "://") < 0)
- return 0;
-
- result = xine_open(this->stream, url);
-
- if(!result) {
- LOGMSG("fe_xine_open: xine_open(\"%s\") failed", url);
- free(url);
- return 0;
- }
- free(url);
-
-#if 0
- this->xine->config->update_num(this->xine->config,
- "video.output.xv_double_buffer",
- 1);
-#endif
- x_upd_num("engine.buffers.video_num_buffers", this->pes_buffers);
-
- return result;
-}
-
-/*
- * post plugin handling
- *
- */
-
-#define POST_AUDIO_VIS 0
-#define POST_AUDIO 1
-#define POST_VIDEO 2
-#define POST_VIDEO_PIP 3
-
-
-static void init_dummy_ports(fe_t *this, int on)
-{
- if(!on) {
- if(this->slave_stream)
- LOGMSG("ERROR: init_dummy_ports(false) called while port is still in use !");
-
- if(this->audio_port_none)
- xine_close_audio_driver(this->xine, this->audio_port_none);
- this->audio_port_none = NULL;
- if(this->video_port_none)
- xine_close_video_driver(this->xine, this->video_port_none);
- this->video_port_none = NULL;
- } else {
- if(! this->audio_port_none)
-#if XINE_VERSION_CODE < 10190
- this->audio_port_none = _x_ao_new_port (this->xine, NULL, 1);
-#else
- this->audio_port_none = NULL;/*xine_new_framegrab_audio_port(this->xine);*/
-#endif
- if(this->audio_port_none)
- this->audio_port_none->set_property(this->audio_port_none, AO_PROP_DISCARD_BUFFERS, 1);
- /*LOGMSG("initialized dummy audio port %x", this->audio_port_none);*/
-#if 0
- if(! this->video_port_none)
- this->video_port_none =
- _x_vo_new_port(this->xine,
- _x_load_video_output_plugin(this->xine, "none",
- XINE_VISUAL_TYPE_NONE, NULL),
- 1);
- this->video_port_none->set_property(this->video_port_none, VO_PROP_DISCARD_FRAMES, 1);
-#endif
- }
-}
-
-static void fe_post_unwire(fe_t *this)
-{
- xine_post_out_t *vo_source = xine_get_video_source(this->stream);
- xine_post_out_t *ao_source = xine_get_audio_source(this->stream);
-
- if(this->slave_stream &&
- this->slave_stream == this->postplugins->audio_source) {
- LOGDBG("unwiring slave stream audio post plugins");
- init_dummy_ports(this, 1);
-
- if(ao_source && this->audio_port_none)
- (void) xine_post_wire_audio_port(ao_source, this->audio_port_none);
-
- ao_source = xine_get_audio_source(this->slave_stream);
- if(ao_source && this->audio_port)
- (void) xine_post_wire_audio_port(ao_source, this->audio_port);
-
- } else {
- LOGDBG("unwiring audio post plugins");
- init_dummy_ports(this, 0);
- if(ao_source && this->audio_port)
- (void) xine_post_wire_audio_port(ao_source, this->audio_port);
- }
-
- if(this->slave_stream &&
- this->slave_stream == this->postplugins->video_source) {
- LOGDBG("unwiring slave stream video post plugins");
- /*init_dummy_ports(this, 1);*/
- /*(void) xine_post_wire_video_port(vo_source, this->video_port_none);*/
-
- vo_source = xine_get_video_source(this->slave_stream);
- if(vo_source && this->video_port)
- (void) xine_post_wire_video_port(vo_source, this->video_port);
-
- } else {
- LOGDBG("unwiring video post plugins");
- /*init_dummy_ports(this, 0);*/
- if(vo_source && this->video_port)
- (void) xine_post_wire_video_port(vo_source, this->video_port);
- }
-}
-
-static void fe_post_rewire(const fe_t *this)
-{
- LOGDBG("re-wiring post plugins");
- vpplugin_rewire_posts(this->postplugins);
- applugin_rewire_posts(this->postplugins);
-}
-
-static void fe_post_unload(const fe_t *this)
-{
- LOGDBG("unloading post plugins");
- vpplugin_unload_post(this->postplugins, NULL);
- applugin_unload_post(this->postplugins, NULL);
-}
-
-static void fe_post_close(const fe_t *this, const char *name, int which)
-{
- post_plugins_t *posts = this->postplugins;
-
- if(!this)
- return;
-
- if(name && !strcmp(name, "AudioVisualization")) {
- name = NULL;
- which = POST_AUDIO_VIS;
- }
- if(name && !strcmp(name, "Pip")) {
- name = NULL;
- which = POST_VIDEO_PIP;
- }
-
- /* by name */
- if(name) {
- LOGDBG("closing post plugin: %s", name);
- if(applugin_unload_post(posts, name)) {
- /*LOGDBG(" * rewiring audio");*/
- applugin_rewire_posts(posts);
- return;
- }
- if(vpplugin_unload_post(posts, name)) {
- /*LOGDBG(" * rewiring video");*/
- vpplugin_rewire_posts(posts);
- return;
- }
- return;
- }
-
- /* by type */
- if(which == POST_AUDIO_VIS || which < 0) { /* audio visualization */
- if(posts->post_vis_elements_num &&
- posts->post_vis_elements &&
- posts->post_vis_elements[0]) {
- LOGDBG("Closing audio visualization post plugins");
- if(applugin_unload_post(posts, posts->post_vis_elements[0]->name)) {
- /*LOGDBG(" * rewiring audio");*/
- applugin_rewire_posts(posts);
- }
- }
- }
-
- if(which == POST_AUDIO || which < 0) { /* audio effect(s) */
- LOGDBG("Closing audio post plugins");
- if(applugin_disable_post(posts, NULL)) {
- /*LOGDBG(" * rewiring audio");*/
- applugin_rewire_posts(posts);
- }
- }
- if(which == POST_VIDEO || which < 0) { /* video effect(s) */
- LOGDBG("Closing video post plugins");
- if(vpplugin_unload_post(posts, NULL)) {
- /*LOGDBG(" * rewiring video");*/
- vpplugin_rewire_posts(posts);
- }
- }
-
- if(which == POST_VIDEO_PIP || which < 0) { /* Picture-In-Picture */
- if(posts->post_pip_elements_num &&
- posts->post_pip_elements &&
- posts->post_pip_elements[0]) {
- LOGDBG("Closing PIP (mosaico) post plugins");
- if(vpplugin_unload_post(posts, "mosaico")) {
- /*LOGDBG(" * rewiring video");*/
- vpplugin_rewire_posts(posts);
- }
- }
- }
-}
-
-static int get_opt_val(const char *s, const char *opt)
-{
- int val = -1;
- const char *pt = strstr(s, opt);
- if(pt)
- if(1 == sscanf(pt+strlen(opt)+1, "%d", &val))
- return val;
- return -1;
-}
-
-static void fe_post_open(const fe_t *this, const char *name, const char *args)
-{
- post_plugins_t *posts = this->postplugins;
- char initstr[1024];
- int found = 0;
-
- if(!this || !this->xine || !this->stream || !name)
- return;
-
- /* pip */
- if(!strcmp(name, "Pip")) {
- posts->post_pip_enable = 1;
- name = "mosaico";
- if(!posts->post_pip_elements ||
- !posts->post_vis_elements[0] ||
- !posts->post_vis_elements[0]->enable)
- LOGMSG("enabling picture-in-picture (\"%s:%s\") post plugin", name, args);
- }
-
- if(args) {
- snprintf(initstr, sizeof(initstr), "%s:%s", name, args);
- initstr[sizeof(initstr)-1] = 0;
- } else
- strn0cpy(initstr, name, sizeof(initstr));
-
- /* swscale aspect ratio */
- if (!strcmp(name, "swscale")) {
- char *pt = strstr(initstr, "output_aspect=auto");
- if (pt) {
- char tmp[16];
- double r = 0.0;
- pt += 14;
- switch(this->aspect) {
- case 0:
- case 1: /* */ r = this->display_ratio * (double)this->width / (double)this->height; break;
- case 2: /* 4:3 */ r = 4.0/3.0; break;
- case 3: /* 16:9 */ r = 16.0/9.0; break;
- case 4: /* 16:10 */ r = 16.0/10.0; break;
- }
- /* in finnish locale decimal separator is "," - same as post plugin parameter separator :( */
- sprintf(tmp, "%04d", (int)(r*1000.0));
- strncpy(pt, tmp, 4);
- }
- }
-
- LOGDBG("opening post plugin: %s", initstr);
-
- /* close old audio visualization plugin */
- if(!strcmp(name,"goom") ||
- !strcmp(name,"oscope") ||
- !strcmp(name,"fftscope") ||
- !strcmp(name,"fftgraph") ||
- !strcmp(name,"fooviz")) {
-
- /* close if changed */
- if(posts->post_vis_elements_num &&
- posts->post_vis_elements &&
- posts->post_vis_elements[0] &&
- strcmp(name, posts->post_vis_elements[0]->name)) {
-
- fe_post_close(this, NULL, POST_AUDIO_VIS);
- }
-
- if(!found && applugin_enable_post(posts, initstr, &found)) {
- posts->post_vis_enable = 1;
- applugin_rewire_posts(posts);
-
- // goom wants options thru config ...
- if(args && !strcmp(name,"goom")) {
- int val;
- if((val = get_opt_val(initstr, "fps")) > 0)
- x_upd_num ("effects.goom.fps", val );
- if((val = get_opt_val(initstr, "width")) > 0)
- x_upd_num ("effects.goom.width", val);
- if((val = get_opt_val(initstr, "height")) > 0)
- x_upd_num ("effects.goom.height", val);
- //if((val = get_opt_val(initstr, "csc_method"))>0)
- // this->xine->config->update_enum (this->xine->config, "effects.goom.csc_method", val);
- }
- }
-
- } else {
-
- /* video filters */
- if(strcmp(name, "audiochannel") &&
- strcmp(name, "volnorm") &&
- strcmp(name, "stretch") &&
- strcmp(name, "upmix_mono") &&
- strcmp(name, "upmix") &&
- vpplugin_enable_post(posts, initstr, &found)) {
-
- posts->post_video_enable = 1;
- vpplugin_rewire_posts(posts);
- }
-
- /* audio filters */
- if(!found && applugin_enable_post(posts, initstr, &found)) {
- posts->post_audio_enable = 1;
- applugin_rewire_posts(posts);
- }
- }
-
- if(!found)
- LOGMSG("Can't load post plugin %s", name);
- else
- LOGDBG("Post plugin %s loaded and wired", name);
-}
-
-static int fe_xine_play(frontend_t *this_gen)
-{
- fe_t *this = (fe_t*)this_gen;
-
- if(!this)
- return 0;
-
- fe_post_rewire(this);
-
- this->input_plugin = NULL;
- this->playback_finished = xine_play(this->stream, 0, 0) ? 0 : 1;
-
- if(!find_input_plugin(this))
- return -1;
-
- this->input_plugin->f.xine_input_event = this->keypress;
- this->input_plugin->f.fe_control = fe_control;
- this->input_plugin->f.fe_handle = this_gen;
-
- if(this->playback_finished)
- LOGMSG("Error playing " MRL_ID ":// !");
-
- return !this->playback_finished;
-}
-
-static int fe_xine_stop(frontend_t *this_gen)
-{
- fe_t *this = (fe_t*)this_gen;
-
- if(!this)
- return 0;
-
- this->input_plugin = NULL;
- this->playback_finished = 1;
-
- xine_stop(this->stream);
-
- fe_post_unwire(this);
-
- return 1;
-}
-
-static void fe_xine_close(frontend_t *this_gen)
-{
- fe_t *this = (fe_t*)this_gen;
-
- if(!this)
- return;
-
- if (this && this->xine) {
- if(this->input_plugin) {
- this->input_plugin->f.xine_input_event = NULL;
- this->input_plugin->f.fe_control = NULL;
- }
-
- fe_xine_stop(this_gen);
-
- fe_post_unload(this);
-
- xine_close(this->stream);
- if(this->postplugins->pip_stream)
- xine_close(this->postplugins->pip_stream);
- }
-}
-
-static void fe_xine_exit(frontend_t *this_gen)
-{
- fe_t *this = (fe_t*)this_gen;
-
- if (this && this->xine) {
-
- if(this->input_plugin || !this->playback_finished)
- fe_xine_close(this_gen);
- fe_post_unload(this);
-
- if(this->configfile) {
- xine_config_save (this->xine, this->configfile);
- free(this->configfile);
- this->configfile = NULL;
- }
- if(this->event_queue)
- xine_event_dispose_queue(this->event_queue);
- this->event_queue = NULL;
-
- if(this->stream)
- xine_dispose(this->stream);
- this->stream = NULL;
-
- if(this->postplugins->pip_stream)
- xine_dispose(this->postplugins->pip_stream);
- this->postplugins->pip_stream = NULL;
-
- if(this->slave_stream)
- xine_dispose(this->slave_stream);
- this->slave_stream = NULL;
-
- if(this->audio_port)
- xine_close_audio_driver(this->xine, this->audio_port);
- this->audio_port = NULL;
-
- init_dummy_ports(this, 0);
-
- if(this->video_port)
- xine_close_video_driver(this->xine, this->video_port);
- this->video_port = NULL;
-
- if(this->postplugins->static_post_plugins)
- free(this->postplugins->static_post_plugins);
- free(this->postplugins);
- this->postplugins = NULL;
-
- xine_exit(this->xine);
- this->xine = NULL;
- }
-}
-
-static void fe_free(frontend_t *this_gen)
-{
- if (this_gen) {
- fe_t *this = (fe_t*)this_gen;
- this->fe.fe_display_close(this_gen);
- free(this->configfile);
- free(this);
- }
-}
-
-static int fe_is_finished(frontend_t *this_gen, int slave_stream)
-{
- fe_t *this = (fe_t*)this_gen;
-
- if(!this || this->playback_finished)
- return FE_XINE_ERROR;
- if(this->terminate_key_pressed)
- return FE_XINE_EXIT;
-
- if(slave_stream) {
- if(!this->slave_stream || this->slave_playback_finished)
- return FE_XINE_EXIT;
- }
-
- return FE_XINE_RUNNING;
-}
-
-/************************** hooks to input plugin ****************************/
-
-/*
- * data/control from VDR
- */
-
-static int xine_control(frontend_t *this_gen, const char *cmd)
-{
- fe_t *this = (fe_t*)this_gen;
-
- if(!find_input_plugin(this))
- return -1;
-
- return this->input_plugin->f.push_input_control(this->input_plugin, cmd);
-}
-
-static int xine_osd_command(frontend_t *this_gen, struct osd_command_s *cmd) {
- fe_t *this = (fe_t*)this_gen;
-
- if(!find_input_plugin(this))
- return -1;
-
- return this->input_plugin->f.push_input_osd(this->input_plugin, cmd);
-}
-
-static int xine_queue_pes_packet(frontend_t *this_gen, const char *data, int len)
-{
- fe_t *this = (fe_t*)this_gen;
-
- if(!find_input_plugin(this))
- return 0/*-1*/;
-
- return this->input_plugin->f.push_input_write(this->input_plugin, data, len);
-}
-
-/*
- * control from frontend to xine/vdr
- */
-
-
-static int fe_send_input_event(frontend_t *this_gen, const char *map,
- const char *key, int repeat, int release)
-{
- fe_t *this = (fe_t*)this_gen;
-
- LOGDBG("Keypress: %s %s %s %s",
- map, key, repeat?"Repeat":"", release?"Release":"");
-
- /* local mode: --> vdr callback */
- if(this->keypress) {
- this->keypress(map, key);
- return FE_OK;
- }
-
- /* remote mode: --> input plugin --> vdr */
- if (find_input_plugin(this)) {
- if (this->input_plugin->f.post_vdr_event) {
- char *msg = NULL;
- if (map) {
- if (asprintf(&msg, "KEY %s %s %s %s\r\n", map, key,
- repeat?"Repeat":"", release?"Release":"") < 0)
- msg = NULL;
- } else {
- if (asprintf(&msg, "KEY %s\r\n", key) < 0)
- msg = NULL;
- }
-
- if (msg) {
- int r = this->input_plugin->f.post_vdr_event(this->input_plugin, msg);
- free(msg);
- if (r > 0)
- return FE_OK;
- }
- LOGMSG("fe_send_input_event: message KEY %s lost", key);
- return FE_ERROR;
- }
- }
-
- LOGMSG("fe_send_input_event: handler not set, event lost !");
- return FE_ERROR;
-}
-
-
-static int fe_send_event(frontend_t *this_gen, const char *data)
-{
- fe_t *this = (fe_t*)this_gen;
-
- if (!data)
- return FE_ERROR;
-
- if (!strcmp(data, "TOGGLE_FULLSCREEN")) {
- if(this->toggle_fullscreen_cb)
- this->toggle_fullscreen_cb(this);
-
- } else if (!strcmp(data, "QUIT")) {
- this->terminate_key_pressed = 1;
-
- } else if(!strcmp(data, "TOGGLE_DEINTERLACE")) {
- xine_set_param(this->stream, XINE_PARAM_VO_DEINTERLACE,
- xine_get_param(this->stream, XINE_PARAM_VO_DEINTERLACE) ? 0 : 1);
-
- } else if(!strncasecmp(data, "DEINTERLACE ", 12)) {
- xine_set_param(this->stream, XINE_PARAM_VO_DEINTERLACE, atoi(data+12) ? 1 : 0);
-
- } else {
- return fe_send_input_event(this_gen, NULL, data, 0, 0);
- }
-
- return FE_OK;
-}
-
-/*
- * Control messages from input plugin
- */
-static void *fe_control(frontend_t *this_gen, const char *cmd)
-{
- fe_t *this = (fe_t*)this_gen;
- post_plugins_t *posts;
-
- /*LOGDBG("fe_control(\"%s\")", cmd);*/
-
- if(!cmd || !this) {
- LOGMSG("fe_control(0x%lx,0x%lx) : invalid argument",
- (unsigned long int)this_gen, (unsigned long int)cmd);
- return NULL;
- }
-
- posts = this->postplugins;
-
- if(!posts) {
- LOGMSG("fe_control : this->posts == NULL");
- return NULL;
- }
-
- if(!strncmp(cmd, "SLAVE CLOSED", 16)) {
- /*LOGMSG("fe_control : slave closed");*/
- if(this->slave_stream)
- fe_control(this_gen, "SLAVE 0x0\r\n");
- init_dummy_ports(this, 0);
-
- } else if(!strncmp(cmd, "SLAVE 0x", 8)) {
- unsigned long pt;
- if(1 == sscanf(cmd+8, "%lx", &pt)) {
- xine_stream_t *slave_stream = (xine_stream_t*)pt;
- if(this->slave_stream != slave_stream) {
-
- fe_post_unwire(this);
-
- if(this->slave_stream) {
- /*xine_post_out_t *vo_source = xine_get_video_source(posts->slave_stream);*/
- if(this->slave_stream == this->postplugins->audio_source) {
- xine_post_out_t *ao_source = xine_get_audio_source(this->slave_stream);
- LOGMSG("unwiring slave stream from output");
- /*(void) xine_post_wire_video_port(vo_source, this->video_port_none);*/
- (void) xine_post_wire_audio_port(ao_source, this->audio_port_none);
- }
- }
-
- this->slave_stream = slave_stream;
-
- this->postplugins->video_source = this->postplugins->audio_source =
- this->slave_stream ?: this->stream;
- if(strstr(cmd, "Video")) /* video only, audio from VDR */
- this->postplugins->audio_source = this->stream;
- if(strstr(cmd, "Audio")) /* audio only, video from VDR */
- this->postplugins->video_source = this->stream;
-
- if(this->slave_stream)
- fe_post_unwire(this);
-
- fe_post_rewire(this);
- }
- this->slave_playback_finished = !slave_stream;
- }
-
- } else if(!strncmp(cmd, "ENDOFSTREAM", 11)) {
- if(this->slave_stream)
- this->slave_playback_finished = 1;
-
- } else if(!strncmp(cmd, "SUBSTREAM ", 10)) {
- unsigned int pid;
- int x, y, w, h;
- if(5 == sscanf(cmd+10, "0x%x %d %d %d %d", &pid, &x, &y, &w, &h)) {
- char mrl[256];
- if(!posts->pip_stream)
- posts->pip_stream = xine_stream_new(this->xine,
- this->audio_port,
- this->video_port);
- LOGMSG(" PIP %d: %dx%d @ (%d,%d)", pid & 0x0f, w, h, x, y);
- LOGMSG("create pip stream done");
- sprintf(mrl, MRL_ID "+slave://0x%lx#nocache",
- (unsigned long int)this);
- if(!xine_open(posts->pip_stream, mrl) ||
- !xine_play(posts->pip_stream, 0, 0)) {
- LOGERR(" pip stream open/play failed");
- } else {
- char params[64];
- sprintf(params, "pip_num=1,x=%d,y=%d,w=%d,h=%d", x,y,w,h);
- fe_post_open(this, "Pip", params);
- return posts->pip_stream;
- }
- }
- fe_post_close(this, NULL, POST_VIDEO_PIP);
- if(posts->pip_stream) {
- xine_close(posts->pip_stream);
- xine_dispose(posts->pip_stream);
- posts->pip_stream = NULL;
- }
- return NULL;
-
- } else if(!strncmp(cmd, "POST ", 5)) {
- char *name = strdup(cmd+5), *args = name, *pt;
-
- if(NULL != (pt=strchr(name, '\r')))
- *pt = 0;
- if(NULL != (pt=strchr(name, '\n')))
- *pt = 0;
-
- while(*args && *args != ' ') /* skip name */
- args++;
- if(*args /*== ' '*/)
- *args++ = 0;
-
- while(*args && *args == ' ') /* skip whitespace between name and args */
- args++;
-
- /*this->stream->xine->port_ticket->acquire(this->stream->xine->port_ticket, 0);*/
- /* - locks local frontend at startup */
- if(!strncmp(args, "On", 2)) {
- args += 2;
- while(*args == ' ')
- args++;
- /*LOGDBG(" POST: %s On \"%s\"", name, args);*/
- fe_post_open(this, name, args);
- } else if(!strncmp(args, "Off", 3)) {
- /*LOGDBG(" POST: %s Off (name len=%d), name => int = %d", name, strlen(name), atoi(name));*/
- if(strlen(name) == 1)
- fe_post_close(this, NULL, atoi(name));
- else
- fe_post_close(this, name, -1);
- } else {
- LOGMSG("fe_control: POST: unknown command %s", cmd);
- }
- /*this->stream->xine->port_ticket->release(this->stream->xine->port_ticket, 0);*/
- /* - locks local frontend at startup */
- free(name);
- return NULL;
-
- } else if(!strncmp(cmd, "GRAB ", 5)) {
- int quality, width, height, jpeg, size=0;
- jpeg = !strncmp(cmd+5,"JPEG",4);
- if(3 == sscanf(cmd+5+4, "%d %d %d", &quality, &width, &height)) {
- grab_data_t *result = (grab_data_t*)malloc(sizeof(grab_data_t));
- result->data = this->fe.grab((frontend_t*)this, &size,
- jpeg, quality, width, height);
- if(result->data && (result->size=size)>0)
- return result;
- free(result->data);
- free(result);
- }
-
- } else if(!strncmp(cmd, "OVERSCAN ", 9)) {
- int overscan;
- if(1 == sscanf(cmd+9, "%d", &overscan)) {
- int crop_x = overscan * this->width / 100 / 2;
- int crop_y = overscan * this->height / 100 / 2;
- this->overscan = overscan;
- xine_set_param(this->stream, XINE_PARAM_VO_CROP_LEFT, crop_x);
- xine_set_param(this->stream, XINE_PARAM_VO_CROP_TOP, crop_y);
- xine_set_param(this->stream, XINE_PARAM_VO_CROP_RIGHT, crop_x);
- xine_set_param(this->stream, XINE_PARAM_VO_CROP_BOTTOM, crop_y);
- /* trigger forced redraw to make changes effective */
- xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_X, 100);
- }
- }
-
-
- return NULL;
-}
-
-/*
- * --- RgbToJpeg -------------------------------------------------------------
- *
- * source: vdr-1.3.42, tools.c
- * modified to accept YUV data
- *
- * - move to xine_input_vdr ?
- */
-
-#ifdef HAVE_LIBJPEG
-
-#define JPEGCOMPRESSMEM 500000
-
-typedef struct tJpegCompressData_s {
- int size;
- unsigned char *mem;
-} tJpegCompressData;
-
-static void JpegCompressInitDestination(const j_compress_ptr cinfo)
-{
- tJpegCompressData *jcd = (tJpegCompressData *)cinfo->client_data;
- if (jcd) {
- cinfo->dest->free_in_buffer = jcd->size = JPEGCOMPRESSMEM;
- cinfo->dest->next_output_byte = jcd->mem =
- (unsigned char *)malloc(jcd->size);
- }
-}
-
-static boolean JpegCompressEmptyOutputBuffer(const j_compress_ptr cinfo)
-{
- tJpegCompressData *jcd = (tJpegCompressData *)cinfo->client_data;
- if (jcd) {
- int Used = jcd->size;
- jcd->size += JPEGCOMPRESSMEM;
- jcd->mem = (unsigned char *)realloc(jcd->mem, jcd->size);
- if (jcd->mem) {
- cinfo->dest->next_output_byte = jcd->mem + Used;
- cinfo->dest->free_in_buffer = jcd->size - Used;
- return TRUE;
- }
- }
- return FALSE;
-}
-
-static void JpegCompressTermDestination(const j_compress_ptr cinfo)
-{
- tJpegCompressData *jcd = (tJpegCompressData *)cinfo->client_data;
- if (jcd) {
- int Used = cinfo->dest->next_output_byte - jcd->mem;
- if (Used < jcd->size) {
- jcd->size = Used;
- jcd->mem = (unsigned char *)realloc(jcd->mem, jcd->size);
- }
- }
-}
-
-static vo_frame_t *yuy2_to_yv12_frame(xine_stream_t *stream, vo_frame_t *frame)
-{
- /* convert yuy12 frames to yv12 */
- if (frame->format == XINE_IMGFMT_YUY2) {
- stream->xine->port_ticket->acquire(stream->xine->port_ticket, 0);
- vo_frame_t *img = stream->video_out->get_frame (stream->video_out,
- frame->width, frame->height,
- frame->ratio, XINE_IMGFMT_YV12,
- VO_BOTH_FIELDS);
- stream->xine->port_ticket->release(stream->xine->port_ticket, 0);
-
- if (!img) {
- LOGMSG("yuy2_to_yv12_frame: get_frame failed");
- frame->free(frame);
- return NULL;
- }
-
- init_yuv_conversion();
- yuy2_to_yv12(frame->base[0], frame->pitches[0],
- img->base[0], img->pitches[0],
- img->base[1], img->pitches[1],
- img->base[2], img->pitches[2],
- frame->width, frame->height);
-
- frame->free(frame);
- return img;
- }
-
- return frame;
-}
-
-static char *frame_compress_jpeg(fe_t *this, int *size, int quality, vo_frame_t *frame)
-{
- struct jpeg_destination_mgr jdm;
- struct jpeg_compress_struct cinfo;
- struct jpeg_error_mgr jerr;
- tJpegCompressData jcd;
-
- /* convert yuy2 frames to yv12 */
- frame = yuy2_to_yv12_frame(this->stream, frame);
-
- /* Compress JPEG */
-
- jdm.init_destination = JpegCompressInitDestination;
- jdm.empty_output_buffer = JpegCompressEmptyOutputBuffer;
- jdm.term_destination = JpegCompressTermDestination;
-
- cinfo.err = jpeg_std_error(&jerr);
- jpeg_create_compress(&cinfo);
- cinfo.dest = &jdm;
-
- cinfo.client_data = &jcd;
- cinfo.image_width = frame->width;
- cinfo.image_height = frame->height;
-
- cinfo.input_components = 3;
- cinfo.in_color_space = JCS_YCbCr;
-
- switch (frame->format) {
- case XINE_IMGFMT_YV12: {
- JSAMPARRAY pp[3];
- JSAMPROW *rpY = (JSAMPROW*)malloc(sizeof(JSAMPROW) * frame->height);
- JSAMPROW *rpU = (JSAMPROW*)malloc(sizeof(JSAMPROW) * frame->height);
- JSAMPROW *rpV = (JSAMPROW*)malloc(sizeof(JSAMPROW) * frame->height);
- int k;
-
- jpeg_set_defaults(&cinfo);
- jpeg_set_quality(&cinfo, quality, TRUE);
- cinfo.raw_data_in = TRUE;
-
- jpeg_set_colorspace(&cinfo, JCS_YCbCr);
- cinfo.comp_info[0].h_samp_factor =
- cinfo.comp_info[0].v_samp_factor = 2;
- cinfo.comp_info[1].h_samp_factor =
- cinfo.comp_info[1].v_samp_factor =
- cinfo.comp_info[2].h_samp_factor =
- cinfo.comp_info[2].v_samp_factor = 1;
- jpeg_start_compress(&cinfo, TRUE);
-
- for (k = 0; k < frame->height; k+=2) {
- rpY[k] = frame->base[0] + k*frame->pitches[0];
- rpY[k+1] = frame->base[0] + (k+1)*frame->pitches[0];
- rpU[k/2] = frame->base[1] + (k/2)*frame->pitches[1];
- rpV[k/2] = frame->base[2] + (k/2)*frame->pitches[2];
- }
- for (k = 0; k < frame->height; k+=2*DCTSIZE) {
- pp[0] = &rpY[k];
- pp[1] = &rpU[k/2];
- pp[2] = &rpV[k/2];
- jpeg_write_raw_data(&cinfo, pp, 2*DCTSIZE);
- }
- free(rpY);
- free(rpU);
- free(rpV);
- break;
- }
-#if 0
- case XINE_IMGFMT_RGB: {
- JSAMPROW rp[height];
- int rs, k;
-
- cinfo.in_color_space = JCS_RGB;
-
- jpeg_set_defaults(&cinfo);
- jpeg_set_quality(&cinfo, quality, TRUE);
- jpeg_start_compress(&cinfo, TRUE);
-
- rs = frame->pitches[0];
- for (k = 0; k < height; k++)
- rp[k] = frame->base[0] + k*rs;
- jpeg_write_scanlines(&cinfo, rp, height);
- break;
- }
-#endif
- default:
- LOGMSG("fe_grab: grabbing failed (unsupported image format %d)",
- frame->format);
- break;
- }
-
- jpeg_finish_compress(&cinfo);
- jpeg_destroy_compress(&cinfo);
- frame->free(frame);
-
- *size = jcd.size;
- return (char*) jcd.mem;
-}
-
-#endif /* HAVE_LIBJPEG */
-
-static vo_frame_t *yv12_to_yuy2_frame(xine_stream_t *stream, vo_frame_t *frame)
-{
- /* convert yv12 frames to yuy2 */
- if (frame->format == XINE_IMGFMT_YV12) {
- stream->xine->port_ticket->acquire(stream->xine->port_ticket, 0);
- vo_frame_t *img = stream->video_out->get_frame (stream->video_out,
- frame->width, frame->height,
- frame->ratio, XINE_IMGFMT_YUY2,
- VO_BOTH_FIELDS);
- stream->xine->port_ticket->release(stream->xine->port_ticket, 0);
-
- if (!img) {
- LOGMSG("yv12_to_yuy2_frame: get_frame failed");
- frame->free(frame);
- return NULL;
- }
-
- init_yuv_conversion();
- yv12_to_yuy2(frame->base[0], frame->pitches[0],
- frame->base[1], frame->pitches[1],
- frame->base[2], frame->pitches[2],
- img->base[0], img->pitches[0],
- frame->width, frame->height,
- frame->progressive_frame);
-
- frame->free(frame);
- return img;
- }
-
- return frame;
-}
-
-#define YCBCR_TO_RGB( y, cb, cr, r, g, b ) \
- do { \
- int _y, _cb, _cr, _r, _g, _b; \
- _y = ((y) - 16) * 76309; \
- _cb = (cb) - 128; \
- _cr = (cr) - 128; \
- _r = (_y + _cr * 104597 + 0x8000) >> 16; \
- _g = (_y - _cb * 25675 - _cr * 53279 + 0x8000) >> 16; \
- _b = (_y + _cb * 132201 + 0x8000) >> 16; \
- (r) = (_r < 0) ? 0 : ((_r > 255) ? 255 : _r); \
- (g) = (_g < 0) ? 0 : ((_g > 255) ? 255 : _g); \
- (b) = (_b < 0) ? 0 : ((_b > 255) ? 255 : _b); \
-} while (0)
-
-static char *frame_compress_pnm(fe_t *this, int *size, vo_frame_t *frame)
-{
- /* ensure yuy2 */
- if (!(frame = yv12_to_yuy2_frame(this->stream, frame)))
- return NULL;
-
- /* convert to PNM */
-
- /* allocate memory for result */
- size_t bytes = frame->width * frame->height * 3;
- uint8_t *pnm = malloc(bytes + 64);
- if (!pnm) {
- LOGMSG("fe_grab: malloc failed");
- return NULL;
- }
-
- /* PNM header */
- sprintf((char*)pnm, "P6\n%d\n%d\n255\n", frame->width, frame->height);
- int hdrlen = strlen((char*)pnm);
- uint8_t *p = pnm + hdrlen;
- uint8_t *s = frame->base[0];
- int x, y;
-
- *size = bytes + hdrlen;
-
- /* convert to RGB */
- for (y=0; y < frame->height; y++) {
- for (x=0; x < frame->width; x+=2, s+=4, p+=6) {
- YCBCR_TO_RGB(s[0], s[1], s[3], p[0], p[1], p[2]);
- YCBCR_TO_RGB(s[2], s[1], s[3], p[3], p[4], p[5]);
- }
- s = frame->base[0] + y*frame->pitches[0];
- }
-
- return (char*)pnm;
-}
-
-static char *fe_grab(frontend_t *this_gen, int *size, int jpeg,
- int quality, int width, int height)
-{
- fe_t *this = (fe_t*)this_gen;
- vo_frame_t *frame;
-
-#ifndef HAVE_LIBJPEG
- if(jpeg) {
- LOGMSG("fe_grab: JPEG grab support was not compiled in");
- return 0;
- }
-#endif /* HAVE_LIBJPEG */
-
- if(!find_input_plugin(this))
- return 0;
-
- LOGDBG("fe_grab: grabbing %s %d %dx%d",
- jpeg ? "JPEG" : "PNM", quality, width, height);
-
- /* validate parameters */
- if ((quality < 0) || (quality > 100))
- quality = 100;
- width = (MIN(16, MAX(width, 1920)) + 1) & ~1; /* 16...1920, even */
- height = (MIN(16, MAX(width, 1200)) + 1) & ~1; /* 16...1200, even */
-
- /* get last frame */
- this->stream->xine->port_ticket->acquire(this->stream->xine->port_ticket, 0);
- frame = this->stream->video_out->get_last_frame (this->stream->video_out);
- if(frame)
- frame->lock(frame);
- this->stream->xine->port_ticket->release(this->stream->xine->port_ticket, 0);
-
- if(!frame) {
- LOGMSG("fe_grab: get_last_frame() failed");
- return NULL;
- }
-
- /* Scale image */
- if (frame->width != width || frame->height != height) {
- /* #warning TODO - scaling here */
- }
-
- if (!jpeg)
- return frame_compress_pnm(this, size, frame);
-
-#ifdef HAVE_LIBJPEG
- return frame_compress_jpeg(this, size, quality, frame);
-#else /* HAVE_LIBJPEG */
- return NULL;
-#endif
-}
-
-/*
- * init_fe()
- *
- * initialize function pointers
- */
-void init_fe(fe_t *fe)
-{
- fe->fe.xine_init = fe_xine_init;
- fe->fe.xine_open = fe_xine_open;
- fe->fe.xine_play = fe_xine_play;
- fe->fe.xine_stop = fe_xine_stop;
- fe->fe.xine_close = fe_xine_close;
- fe->fe.xine_exit = fe_xine_exit;
-
- fe->fe.fe_free = fe_free;
-
- fe->fe.xine_is_finished = fe_is_finished;
-
- fe->fe.xine_osd_command = xine_osd_command;
- fe->fe.xine_control = xine_control;
- fe->fe.xine_queue_pes_packet = xine_queue_pes_packet;
-
- fe->fe.grab = fe_grab;
-
- fe->fe.send_event = fe_send_event;
- fe->fe.send_input_event = fe_send_input_event;
-
- fe->dest_pixel_aspect = fe_dest_pixel_aspect;
- fe->frame_output_handler = fe_frame_output_cb;
-}
-
diff --git a/xine_frontend.h b/xine_frontend.h
deleted file mode 100644
index f588dc04..00000000
--- a/xine_frontend.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * xine_frontend.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xine_frontend.h,v 1.19 2009-05-31 16:51:25 phintuka Exp $
- *
- */
-
-#ifndef _XINE_FRONTEND_H
-#define _XINE_FRONTEND_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define FE_VERSION_STR XINELIBOUTPUT_VERSION /*"1.0.0pre1"*/
-
-typedef void (*fe_keypress_f)(const char *keymap, const char *name);
-
-typedef struct frontend_config_s frontend_config_t;
-typedef struct frontend_s frontend_t;
-
-struct osd_command_s;
-
-#if 0
-struct frontend_config_s {
- /* Display */
- int width;
- int height;
- int fullscreen;
- int modeswitch;
- char *modeline;
- int aspect;
-
- char *video_port;
-
- int scale_video;
- int field_order;
-
- fe_keypress_f keypresshandler;
-
- /* Xine engine */
- char *audio_driver;
- char *audio_port;
- char *video_driver;
- int pes_buffers;
- int priority;
-};
-#endif
-
-/* xine_is_finished return values */
-#define FE_XINE_RUNNING 0
-#define FE_XINE_ERROR -1
-#define FE_XINE_EXIT 1
-
-/* return values */
-#define FE_OK 1
-#define FE_ERROR 0
-
-struct frontend_s {
- /* Display */
- int (*fe_display_open)(frontend_t*,
- int xpos, int ypos,
- int winwidth, int winheight,
- int fullscreen, int hud, int modeswitch, const char *modeline,
- int aspect, fe_keypress_f keypresshandler,
- int no_x_kbd, int gui_hotkeys,
- const char *video_port,
- int scale_video, int field_order,
- const char *aspect_controller, int window_id);
- int (*fe_display_config)(frontend_t *,
- int xpos, int ypos,
- int width, int height,
- int fullscreen,
- int modeswitch, const char *modeline,
- int aspect, int scale_video, int field_order);
- void (*fe_display_close)(frontend_t*);
-
- /* Xine engine */
- int (*xine_init)(frontend_t*,
- const char *audio_driver,
- const char *audio_port,
- const char *video_driver,
- int pes_buffers,
- const char *static_post,
- const char *config_file);
- int (*xine_open)(frontend_t*, const char *mrl);
- int (*xine_play)(frontend_t*);
- int (*xine_stop)(frontend_t*);
- void (*xine_close)(frontend_t*);
- void (*xine_exit)(frontend_t*);
-
- /* Execution control */
- int (*fe_run)(frontend_t*);
- void (*fe_interrupt)(frontend_t*);
- void (*fe_free)(frontend_t*);
-
- int (*xine_is_finished)(frontend_t*, int slave_stream);
-
- /* Data transfer VDR -> frontend/xine */
- int (*xine_osd_command)(frontend_t*, struct osd_command_s *cmd);
- int (*xine_control)(frontend_t*, const char *cmd);
- int (*xine_queue_pes_packet)(frontend_t*, const char *data, int len);
-
- char *(*grab)(frontend_t*, int *size, int jpeg, int quality,
- int width, int height);
-
- /* events from frontend -> xine/vdr */
- int (*send_event)(frontend_t *fe, const char *data);
- int (*send_input_event)(frontend_t *fe,
- const char *map, const char *key,
- int repeat, int release);
-#if 0
- frontend_config_t config;
-#endif
-};
-
-typedef frontend_t *(*fe_creator_f)(void);
-
-void list_xine_plugins(frontend_t *fe, int verbose);
-
-
-#ifdef __cplusplus
-} /* extern "C" { */
-#endif
-
-#endif /* _XINE_FRONTEND_H */
-
diff --git a/xine_frontend_internal.h b/xine_frontend_internal.h
deleted file mode 100644
index 7409c867..00000000
--- a/xine_frontend_internal.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * xine_frontend_internal.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xine_frontend_internal.h,v 1.5 2008-11-14 23:31:37 phintuka Exp $
- *
- */
-
-#ifndef XINE_FRONTEND_INTERNAL_H
-#define XINE_FRONTEND_INTERNAL_H
-
-#include <xine.h>
-#include <xine/input_plugin.h>
-
-#include "xine_frontend.h"
-#include "xine_input_vdr.h"
-#include "xine/post.h"
-
-typedef struct fe_s {
- /* base class */
- frontend_t fe;
-
- /* from xine_frontend.c */
- double (*dest_pixel_aspect) (const struct fe_s *,
- double video_pixel_aspect,
- int video_width, int video_height);
- void (*frame_output_handler)(void *data,
- int video_width, int video_height,
- double video_pixel_aspect,
- int *dest_x, int *dest_y,
- int *dest_width, int *dest_height,
- double *dest_pixel_aspect,
- int *win_x, int *win_y);
-
- /* called from xine_frontend.c */
- void (*update_display_size_cb) (struct fe_s *);
- void (*toggle_fullscreen_cb) (struct fe_s *);
-
- /* vdr callbacks */
- fe_keypress_f keypress;
-
- /* xine stuff */
- xine_t *xine;
- xine_stream_t *stream;
- xine_stream_t *slave_stream;
- vdr_input_plugin_if_t *input_plugin;
- xine_video_port_t *video_port;
- xine_video_port_t *video_port_none;
- xine_audio_port_t *audio_port;
- xine_audio_port_t *audio_port_none;
- xine_event_queue_t *event_queue;
-
- post_plugins_t *postplugins;
- char *video_port_name; /* frame buffer device */
- char *aspect_controller; /* path to external HW aspect ratio controller */
- char *configfile; /* path of our config file */
-
- int xine_visual_type;
- union {
- void *vis;
- fb_visual_t vis_fb;
- x11_visual_t vis_x11;
- };
-
- /* frontend */
- double video_aspect; /* aspect ratio of video frame */
- double display_ratio; /* aspect ratio of video window */
- uint terminate_key_pressed;
- uint16_t xpos, ypos; /* position of video window */
- uint16_t width; /* size of video window */
- uint16_t height; /* */
- uint16_t video_width; /* size of video frame */
- uint16_t video_height; /* */
- uint16_t pes_buffers; /* max. number of PES packets in video fifo */
- uint8_t aspect; /* aspect ratio of video window (user setting) */
- uint8_t overscan; /* overscan in % (crop video borders) */
-/*uint8_t cropping : 1;*/
- uint8_t scale_video : 1; /* enable/disable all video scaling */
- uint8_t field_order : 1; /* invert top/bottom field order */
- uint8_t playback_finished : 1;
- uint8_t slave_playback_finished : 1;
-
-} fe_t;
-
-/* setup function pointers */
-void init_fe(fe_t *fe);
-
-char *strn0cpy(char *dest, const char *src, int n);
-
-#endif /* XINE_FRONTEND_INTERNAL_H */
diff --git a/xine_frontend_lirc.c b/xine_frontend_lirc.c
deleted file mode 100644
index 9b08da83..00000000
--- a/xine_frontend_lirc.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * xine_frontend_lirc.c: Forward (local) lirc keys to VDR (server)
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xine_frontend_lirc.c,v 1.21 2008-11-19 18:55:20 rofafor Exp $
- *
- */
-/*
- *
- * Almost directly copied from vdr-1.4.3-2 (lirc.c : cLircRemote)
- *
- */
-/*
- * lirc.c: LIRC remote control
- *
- * See the main source file 'vdr.c' for copyright information and
- * how to reach the author.
- *
- * LIRC support added by Carsten Koch <Carsten.Koch@icem.de> 2000-06-16.
- *
- */
-
-
-#include <stdint.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <netinet/in.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#define LOG_MODULENAME "[lirc] "
-#include "logdefs.h"
-
-#include "xine_frontend.h"
-#include "xine_frontend_lirc.h"
-
-
-#define REPEATDELAY 350 /* ms */
-#define REPEATFREQ 100 /* ms */
-#define REPEATTIMEOUT 500 /* ms */
-#define RECONNECTDELAY 3000 /* ms */
-
-#define LIRC_KEY_BUF 30
-#define LIRC_BUFFER_SIZE 128
-#define MIN_LIRCD_CMD_LEN 5
-
-/* static data */
-static pthread_t lirc_thread;
-static volatile char *lirc_device_name = NULL;
-static volatile int fd_lirc = -1;
-static int lirc_repeat_emu = 0;
-
-/* xine_frontend_main.c: */
-extern int gui_hotkeys;
-
-static uint64_t time_ms()
-{
- struct timeval t;
- if (gettimeofday(&t, NULL) == 0)
- return ((uint64_t)t.tv_sec) * 1000ULL + t.tv_usec / 1000ULL;
- return 0;
-}
-
-static uint64_t elapsed(uint64_t t)
-{
- return time_ms() - t;
-}
-
-static void lircd_connect(void)
-{
- struct sockaddr_un addr;
-
- if(fd_lirc >= 0) {
- close(fd_lirc);
- fd_lirc = -1;
- }
-
- if(!lirc_device_name) {
- LOGDBG("no lirc device given");
- return;
- }
-
- addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, (char*)lirc_device_name, sizeof(addr.sun_path));
- addr.sun_path[sizeof(addr.sun_path)-1] = 0;
-
- if ((fd_lirc = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
- LOGERR("lirc error: socket() < 0");
- return;
- }
-
- if (connect(fd_lirc, (struct sockaddr *)&addr, sizeof(addr))) {
- LOGERR("lirc error: connect(%s) < 0", lirc_device_name);
- close(fd_lirc);
- fd_lirc = -1;
- return;
- }
-}
-
-static void *lirc_receiver_thread(void *fe_gen)
-{
- frontend_t *fe = (frontend_t*)fe_gen;
- int timeout = -1;
- uint64_t FirstTime = time_ms();
- uint64_t LastTime = time_ms();
- char buf[LIRC_BUFFER_SIZE];
- char LastKeyName[LIRC_KEY_BUF] = "";
- int repeat = 0;
-
- LOGMSG("lirc forwarding started");
-
- const int priority = -1;
- errno = 0;
- if((nice(priority) == -1) && errno)
- LOGDBG("LIRC: Can't nice to value: %d", priority);
-
- lircd_connect();
-
- while(lirc_device_name && fd_lirc >= 0) {
- fd_set set;
- int ready, ret = -1;
- FD_ZERO(&set);
- FD_SET(fd_lirc, &set);
-
- pthread_testcancel();
- if (timeout >= 0) {
- struct timeval tv;
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
- ready = select(FD_SETSIZE, &set, NULL, NULL, &tv) > 0 && FD_ISSET(fd_lirc, &set);
- } else {
- ready = select(FD_SETSIZE, &set, NULL, NULL, NULL) > 0 && FD_ISSET(fd_lirc, &set);
- }
-
- pthread_testcancel();
- if(ready < 0) {
- LOGMSG("LIRC connection lost ?");
- break;
- }
-
- if(ready) {
-
- do {
- errno = 0;
- ret = read(fd_lirc, buf, sizeof(buf));
- pthread_testcancel();
- } while(ret < 0 && errno == EINTR);
-
- if (ret <= 0 ) {
- /* try reconnecting */
- LOGERR("LIRC connection lost");
- lircd_connect();
- while(lirc_device_name && fd_lirc < 0) {
- pthread_testcancel();
- sleep(RECONNECTDELAY/1000);
- lircd_connect();
- }
- if(fd_lirc >= 0)
- LOGMSG("LIRC reconnected");
- continue;
- }
-
- if (ret >= MIN_LIRCD_CMD_LEN) {
- unsigned int count;
- char KeyName[LIRC_KEY_BUF];
- LOGDBG("LIRC: %s", buf);
-
- if (sscanf(buf, "%*x %x %29s", &count, KeyName) != 2) {
- /* '29' in '%29s' is LIRC_KEY_BUF-1! */
- LOGMSG("unparseable lirc command: %s", buf);
- continue;
- }
-
- if(lirc_repeat_emu)
- if (strcmp(KeyName, LastKeyName) == 0 && elapsed(LastTime) < REPEATDELAY)
- count = repeat + 1;
-
- if (count == 0) {
- if (strcmp(KeyName, LastKeyName) == 0 && elapsed(FirstTime) < REPEATDELAY)
- continue; /* skip keys coming in too fast */
- if (repeat) {
- alarm(3);
- fe->send_input_event(fe, "LIRC", LastKeyName, 0, 1);
- alarm(0);
- }
-
- strcpy(LastKeyName, KeyName);
- repeat = 0;
- FirstTime = time_ms();
- timeout = -1;
- }
- else {
- if (elapsed(LastTime) < REPEATFREQ)
- continue; /* repeat function kicks in after a short delay */
-
- if (elapsed(FirstTime) < REPEATDELAY) {
- if(lirc_repeat_emu)
- LastTime = time_ms();
- continue; /* skip keys coming in too fast */
- }
- repeat = 1;
- timeout = REPEATDELAY;
- }
- LastTime = time_ms();
-
- if (gui_hotkeys) {
- if(!strcmp(KeyName, "Quit")) {
- fe->send_event(fe, "QUIT");
- break;
- }
- if(!strcmp(KeyName, "Fullscreen")) {
- if(!repeat)
- fe->send_event(fe, "TOGGLE_FULLSCREEN");
- continue;
- }
- if(!strcmp(KeyName, "Deinterlace")) {
- if(!repeat)
- fe->send_event(fe, "TOGGLE_DEINTERLACE");
- continue;
- }
- }
-
- alarm(3);
- fe->send_input_event(fe, "LIRC", KeyName, repeat, 0);
- alarm(0);
-
- }
- else if (repeat) { /* the last one was a repeat, so let's generate a release */
- if (elapsed(LastTime) >= REPEATTIMEOUT) {
- alarm(3);
- fe->send_input_event(fe, "LIRC", LastKeyName, 0, 1);
- alarm(0);
- repeat = 0;
- *LastKeyName = 0;
- timeout = -1;
- }
- }
-
- }
- }
-
-
- if(fd_lirc >= 0)
- close(fd_lirc);
- fd_lirc = -1;
- pthread_exit(NULL);
- return NULL; /* never reached */
-}
-
-void lirc_start(struct frontend_s *fe, char *lirc_dev, int repeat_emu)
-{
- if(lirc_dev) {
- int err;
- lirc_device_name = lirc_dev;
- lirc_repeat_emu = repeat_emu;
- if ((err = pthread_create (&lirc_thread,
- NULL, lirc_receiver_thread,
- (void*)fe)) != 0) {
- fprintf(stderr, "can't create new thread for lirc (%s)\n",
- strerror(err));
- }
- }
-}
-
-void lirc_stop(void)
-{
- if(lirc_device_name) {
- void *p;
- /*free(lirc_device_name);*/
- lirc_device_name = NULL;
- if(fd_lirc >= 0)
- close(fd_lirc);
- fd_lirc = -1;
- pthread_cancel (lirc_thread);
- pthread_join (lirc_thread, &p);
- }
-}
diff --git a/xine_frontend_lirc.h b/xine_frontend_lirc.h
deleted file mode 100644
index df3972a6..00000000
--- a/xine_frontend_lirc.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * xine_frontend_lirc.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xine_frontend_lirc.h,v 1.3 2008-11-13 22:58:40 phintuka Exp $
- *
- */
-
-#ifndef XINE_FRONTEND_LIRC_H
-#define XINE_FRONTEND_LIRC_H
-
-struct frontend_s;
-
-void lirc_start(struct frontend_s *fe, char *lirc_dev, int repeat_emu);
-void lirc_stop(void);
-
-#endif /* XINE_FRONTEND_LIRC_H */
diff --git a/xine_frontend_main.c b/xine_frontend_main.c
deleted file mode 100644
index 8c8fa81a..00000000
--- a/xine_frontend_main.c
+++ /dev/null
@@ -1,820 +0,0 @@
-/*
- * Simple main() routine for stand-alone frontends.
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xine_frontend_main.c,v 1.76 2009-05-31 18:53:32 phintuka Exp $
- *
- */
-
-#include "features.h"
-
-#include <stdio.h>
-#include <inttypes.h>
-#include <stdlib.h>
-#include <string.h>
-#include <poll.h>
-#include <errno.h>
-#include <termios.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <syslog.h>
-#include <getopt.h>
-#include <signal.h>
-
-#include <xine.h> /* xine_get_version */
-
-#define LOG_MODULENAME "[vdr-fe] "
-#include "logdefs.h"
-
-#include "xine_input_vdr_mrl.h"
-#include "xine_frontend.h"
-#include "tools/vdrdiscovery.h"
-#include "xine_frontend_lirc.h"
-
-/* static data */
-
-/* next symbol is dynamically linked from input plugin */
-int SysLogLevel __attribute__((visibility("default"))) = SYSLOGLEVEL_INFO; /* errors and info, no debug */
-
-volatile int last_signal = 0;
-int gui_hotkeys = 0;
-
-/*
- * stdin (keyboard/slave mode) reading
- */
-
-/* static data */
-pthread_t kbd_thread;
-struct termios tm, saved_tm;
-
-/*
- * read_key()
- *
- * Try to read single char from stdin.
- *
- * Returns: >=0 char readed
- * -1 nothing to read
- * -2 fatal error
- */
-#define READ_KEY_ERROR -2
-#define READ_KEY_EAGAIN -1
-static int read_key(void)
-{
- unsigned char ch;
- int err;
- struct pollfd pfd;
- pfd.fd = STDIN_FILENO;
- pfd.events = POLLIN;
-
- errno = 0;
- pthread_testcancel();
-
- if (1 == (err = poll(&pfd, 1, 50))) {
- pthread_testcancel();
-
- if (1 == (err = read(STDIN_FILENO, &ch, 1)))
- return (int)ch;
-
- if (err < 0)
- LOGERR("read_key: read(stdin) failed");
- else
- LOGERR("read_key: read(stdin) failed: no stdin");
- return READ_KEY_ERROR;
-
- } else if (err < 0 && errno != EINTR) {
- LOGERR("read_key: poll(stdin) failed");
- return READ_KEY_ERROR;
- }
-
- pthread_testcancel();
- return READ_KEY_EAGAIN;
-}
-
-/*
- * read_key_seq()
- *
- * Read a key sequence from stdin.
- * Key sequence is either normal key or escape sequence.
- *
- * Returns the key or escape sequence as uint64_t.
- */
-#define READ_KEY_SEQ_ERROR 0xffffffff
-static uint64_t read_key_seq(void)
-{
- /* from vdr, remote.c */
- uint64_t k = 0;
- int key1;
-
- if ((key1 = read_key()) >= 0) {
- k = key1;
- if (key1 == 0x1B) {
- /* Start of escape sequence */
- if ((key1 = read_key()) >= 0) {
- k <<= 8;
- k |= key1 & 0xFF;
- switch (key1) {
- case 0x4F: /* 3-byte sequence */
- if ((key1 = read_key()) >= 0) {
- k <<= 8;
- k |= key1 & 0xFF;
- }
- break;
- case 0x5B: /* 3- or more-byte sequence */
- if ((key1 = read_key()) >= 0) {
- k <<= 8;
- k |= key1 & 0xFF;
- switch (key1) {
- case 0x31 ... 0x3F: /* more-byte sequence */
- case 0x5B: /* strange, may apparently occur */
- do {
- if ((key1 = read_key()) < 0)
- break; /* Sequence ends here */
- k <<= 8;
- k |= key1 & 0xFF;
- } while (key1 != 0x7E);
- break;
- }
- }
- break;
- }
- }
- }
- }
-
- if (key1 == READ_KEY_ERROR)
- return READ_KEY_SEQ_ERROR;
-
- return k;
-}
-
-/*
- * kbd_receiver_thread()
- *
- * Read key(sequence)s from stdin and pass those to frontend.
- */
-
-static void kbd_receiver_thread_cleanup(void *arg)
-{
- int status;
- tcsetattr(STDIN_FILENO, TCSANOW, &saved_tm);
- status = system("setterm -cursor on");
- LOGMSG("Keyboard thread terminated");
-}
-
-static void *kbd_receiver_thread(void *fe_gen)
-{
- frontend_t *fe = (frontend_t*)fe_gen;
- uint64_t code = 0;
- char str[64];
- int status;
-
- status = system("setterm -cursor off");
- status = system("setterm -blank off");
-
- /* Set stdin to deliver keypresses without buffering whole lines */
- tcgetattr(STDIN_FILENO, &saved_tm);
- if (tcgetattr(STDIN_FILENO, &tm) == 0) {
- tm.c_iflag = 0;
- tm.c_lflag &= ~(ICANON | ECHO);
- tm.c_cc[VMIN] = 0;
- tm.c_cc[VTIME] = 0;
- tcsetattr(STDIN_FILENO, TCSANOW, &tm);
- }
-
- pthread_cleanup_push(kbd_receiver_thread_cleanup, NULL);
-
- do {
- alarm(0);
- errno = 0;
- code = read_key_seq();
- alarm(3); /* watchdog */
- if (code == 0)
- continue;
- if (code == READ_KEY_SEQ_ERROR)
- break;
- if (code == 27) {
- fe->send_event(fe, "QUIT");
- break;
- }
-
- if (gui_hotkeys) {
- if (code == 'f' || code == 'F') {
- fe->send_event(fe, "TOGGLE_FULLSCREEN");
- continue;
- } else if (code == 'd' || code == 'D') {
- fe->send_event(fe, "TOGGLE_DEINTERLACE");
- continue;
- }
- }
-
- snprintf(str, sizeof(str), "%016" PRIX64, code);
- fe->send_input_event(fe, "KBD", str, 0, 0);
-
- } while (fe->xine_is_finished(fe, 0) != FE_XINE_EXIT);
-
- alarm(0);
-
- LOGDBG("Keyboard thread terminating");
-
- pthread_cleanup_pop(1);
-
- pthread_exit(NULL);
- return NULL; /* never reached */
-}
-
-/*
- * slave_receiver_thread()
- *
- * Read slave mode commands from stdin
- * Interpret and execute valid commands
- */
-
-static void slave_receiver_thread_cleanup(void *arg)
-{
- /* restore terminal settings */
- tcsetattr(STDIN_FILENO, TCSANOW, &saved_tm);
- LOGDBG("Slave mode receiver terminated");
-}
-
-static void *slave_receiver_thread(void *fe_gen)
-{
- frontend_t *fe = (frontend_t*)fe_gen;
- char str[128], *pt;
-
- tcgetattr(STDIN_FILENO, &saved_tm);
-
- pthread_cleanup_push(slave_receiver_thread_cleanup, NULL);
-
- do {
- errno = 0;
- str[0] = 0;
-
- pthread_testcancel();
- if (!fgets(str, sizeof(str), stdin))
- break;
- pthread_testcancel();
-
- if (NULL != (pt = strchr(str, '\r')))
- *pt = 0;
- if (NULL != (pt = strchr(str, '\n')))
- *pt = 0;
-
- if (!strncasecmp(str, "QUIT", 4)) {
- fe->send_event(fe, "QUIT");
- break;
- }
- if (!strncasecmp(str, "FULLSCREEN", 10)) {
- fe->send_event(fe, "TOGGLE_FULLSCREEN");
- continue;
- }
- if (!strncasecmp(str, "DEINTERLACE ", 12)) {
- fe->send_event(fe, str);
- continue;
- }
- if (!strncasecmp(str, "HITK ", 5)) {
- fe->send_input_event(fe, NULL, str+5, 0, 0);
- continue;
- }
-
- LOGMSG("Unknown slave mode command: %s", str);
-
- } while (fe->xine_is_finished(fe, 0) != FE_XINE_EXIT);
-
- LOGDBG("Slave mode receiver terminating");
-
- pthread_cleanup_pop(1);
-
- pthread_exit(NULL);
- return NULL; /* never reached */
-}
-
-/*
- * kbd_start()
- *
- * Start keyboard/slave mode reader thread
- */
-static void kbd_start(frontend_t *fe, int slave_mode)
-{
- int err;
- if ((err = pthread_create (&kbd_thread,
- NULL,
- slave_mode ? slave_receiver_thread : kbd_receiver_thread,
- (void*)fe)) != 0) {
- fprintf(stderr, "Can't create new thread for keyboard (%s)\n",
- strerror(err));
- }
-}
-
-/*
- * kbd_stop()
- *
- * Stop keyboard/slave mode reader thread
- */
-static void kbd_stop(void)
-{
- void *p;
-
- pthread_cancel(kbd_thread);
- pthread_join(kbd_thread, &p);
-}
-
-/*
- * SignalHandler()
- */
-static void SignalHandler(int signum)
-{
- LOGMSG("caught signal %d", signum);
-
- switch (signum) {
- case SIGHUP:
- last_signal = signum;
- case SIGPIPE:
- break;
- default:
- if (last_signal) {
- LOGMSG("SignalHandler: exit(-1)");
- exit(-1);
- }
- last_signal = signum;
- break;
- }
-
- signal(signum, SignalHandler);
-}
-
-/*
- * strcatrealloc()
- */
-static char *strcatrealloc(char *dest, const char *src)
-{
- size_t l;
-
- if (!src || !*src)
- return dest;
-
- l = (dest ? strlen(dest) : 0) + strlen(src) + 1;
- if(dest) {
- dest = (char *)realloc(dest, l);
- strcat(dest, src);
- } else {
- dest = (char*)malloc(l);
- strcpy(dest, src);
- }
- return dest;
-}
-
-/*
- * static data
- */
-
-static const char help_str[] =
-"When server address is not given, server is searched from local network.\n"
-"If server is not found, localhost (127.0.0.1) is used as default.\n\n"
- " --help Show (this) help message\n"
- " --audio=audiodriver[:device] Select audio driver and optional port\n"
- " --video=videodriver[:device] Select video driver and optional port\n"
-#ifndef IS_FBFE
- " --display=displayaddress X11 display address\n"
- " --wid=id Use existing X11 window\n"
-#endif
- " --aspect=[auto|4:3|16:9|16:10|default]\n"
- " Display aspect ratio\n"
- " Use script to control HW aspect ratio:\n"
- " --aspect=auto:path_to_script\n"
- " --fullscreen Fullscreen mode\n"
-#ifdef HAVE_XRENDER
- " --hud Head Up Display OSD mode\n"
-#endif
- " --width=x Video window width\n"
- " --height=x Video window height\n"
- " --geometry=WxH[+X+Y] Set output window geometry (X style)\n"
- " --noscaling Disable all video scaling\n"
- " --post=name[:arg=val[,arg=val]] Load and use xine post plugin(s)\n"
- " examples:\n"
- " --post=upmix\n"
- " --post=upmix;tvtime:enabled=1,cheap_mode=1\n"
- " --lirc[=devicename] Use lirc input device\n"
- " Optional lirc socket name can be given\n"
- " --config=file Use config file (default: ~/.xine/config_xineliboutput).\n"
- " --verbose Verbose debug output\n"
- " --silent Silent mode (report only errors)\n"
- " --syslog Write all output to system log\n"
- " --nokbd Disable console keyboard input\n"
-#ifndef IS_FBFE
- " --noxkbd Disable X11 keyboard input\n"
-#endif
- " --hotkeys Enable frontend GUI hotkeys\n"
- " --daemon Run as daemon (disable keyboard,\n"
- " log to syslog and fork to background)\n"
- " --slave Enable slave mode (read commands from stdin)\n"
- " --reconnect Automatically reconnect when connection has been lost\n"
- " --tcp Use TCP transport\n"
- " --udp Use UDP transport\n"
- " --rtp Use RTP transport\n\n"
- " If no transport options are given, transports\n"
- " are tried in following order:\n"
- " local pipe, rtp, udp, tcp\n\n";
-
-static const char short_options[] = "HA:V:d:W:a:fg:Dw:h:nP:L:C:vsxlkobSRtur";
-
-static const struct option long_options[] = {
- { "help", no_argument, NULL, 'H' },
- { "audio", required_argument, NULL, 'A' },
- { "video", required_argument, NULL, 'V' },
- { "display", required_argument, NULL, 'd' },
- { "wid", required_argument, NULL, 'W' },
- { "aspect", required_argument, NULL, 'a' },
- { "fullscreen", no_argument, NULL, 'f' },
- { "geometry", required_argument, NULL, 'g' },
- { "hud", no_argument, NULL, 'D' },
- { "width", required_argument, NULL, 'w' },
- { "height", required_argument, NULL, 'h' },
- { "noscaling", no_argument, NULL, 'n' },
- { "post", required_argument, NULL, 'P' },
- { "lirc", optional_argument, NULL, 'L' },
- { "config", required_argument, NULL, 'C' },
-
- { "verbose", no_argument, NULL, 'v' },
- { "silent", no_argument, NULL, 's' },
- { "syslog", no_argument, NULL, 'l' },
- { "nokbd", no_argument, NULL, 'k' },
- { "noxkbd", no_argument, NULL, 'x' },
- { "hotkeys", no_argument, NULL, 'o' },
- { "daemon", no_argument, NULL, 'b' },
- { "slave", no_argument, NULL, 'S' },
-
- { "reconnect", no_argument, NULL, 'R' },
- { "tcp", no_argument, NULL, 't' },
- { "udp", no_argument, NULL, 'u' },
- { "rtp", no_argument, NULL, 'r' },
- { NULL }
-};
-
-#define PRINTF(x...) do { if(SysLogLevel>1) printf(x); } while(0)
-
-int main(int argc, char *argv[])
-{
- char *mrl = NULL, *gdrv = NULL, *adrv = NULL, *adev = NULL;
- int ftcp = 0, fudp = 0, frtp = 0, reconnect = 0, firsttry = 1;
- int fullscreen = 0, hud = 0, xpos = 0, ypos = 0, width = 720, height = 576;
- int scale_video = 1, aspect = 1;
- int daemon_mode = 0, nokbd = 0, noxkbd = 0, slave_mode = 0;
- char *video_port = NULL;
- int window_id = -1;
- int xmajor, xminor, xsub;
- int c;
- int xine_finished = FE_XINE_ERROR;
- frontend_t *fe = NULL;
- extern const fe_creator_f fe_creator;
- char *static_post_plugins = NULL;
- char *lirc_dev = NULL;
- char *aspect_controller = NULL;
- int repeat_emu = 0;
- char *exec_name = argv[0];
- char *config_file = NULL;
-
- LogToSysLog = 0;
-
- if (strrchr(argv[0],'/'))
- exec_name = strrchr(argv[0],'/')+1;
-
- xine_get_version(&xmajor, &xminor, &xsub);
- printf("%s %s (build with xine-lib %d.%d.%d, using xine-lib %d.%d.%d)\n\n",
- exec_name,
- FE_VERSION_STR,
- XINE_MAJOR_VERSION, XINE_MINOR_VERSION, XINE_SUB_VERSION,
- xmajor, xminor, xsub);
-
- /* Parse arguments */
- while ((c = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) {
- switch (c) {
- default:
- case 'H': printf("\nUsage: %s [options] [" MRL_ID "[+udp|+tcp|+rtp]:[//host[:port]]] \n"
- "\nAvailable options:\n", exec_name);
- printf("%s", help_str);
- list_xine_plugins(NULL, SysLogLevel>2);
- exit(0);
- case 'A': adrv = strdup(optarg);
- adev = strchr(adrv, ':');
- if (adev)
- *(adev++) = 0;
- PRINTF("Audio driver: %s\n",adrv);
- if (adev)
- PRINTF("Audio device: %s\n",adev);
- break;
- case 'V': gdrv = strdup(optarg);
- if (strchr(gdrv, ':')) {
- video_port = strchr(gdrv, ':');
- *video_port = 0;
- video_port++;
- PRINTF("Video port: %s\n",video_port);
- }
- PRINTF("Video driver: %s\n",gdrv);
- break;
-#ifndef IS_FBFE
- case 'W': window_id = atoi(optarg);
- break;
- case 'd': video_port = strdup(optarg);
- break;
- case 'x': noxkbd = 1;
- break;
-#endif
- case 'a': if (!strncmp(optarg, "auto", 4))
- aspect = 0;
- if (!strncmp(optarg, "4:3", 3))
- aspect = 2;
- if (!strncmp(optarg, "16:9", 4))
- aspect = 3;
- if (!strncmp(optarg, "16:10", 5))
- aspect = 4;
- if (aspect == 0 && optarg[4] == ':')
- aspect_controller = strdup(optarg+5);
- PRINTF("Aspect ratio: %s\n",
- aspect==0?"Auto":aspect==2?"4:3":aspect==3?"16:9":
- aspect==4?"16:10":"Default");
- if (aspect_controller)
- PRINTF("Using %s to switch aspect ratio\n",
- aspect_controller);
- break;
- case 'f': fullscreen=1;
- PRINTF("Fullscreen mode\n");
- break;
- case 'D': hud=1;
-#ifdef HAVE_XRENDER
- PRINTF("HUD OSD mode\n");
-#else
- PRINTF("HUD OSD not supported\n");
-#endif
- break;
- case 'w': width = atoi(optarg);
- PRINTF("Width: %d\n", width);
- break;
- case 'g': sscanf (optarg, "%dx%d+%d+%d", &width, &height, &xpos, &ypos);
- PRINTF("Geometry: %dx%d+%d+%d\n", width, height, xpos, ypos);
- break;
- case 'h': height = atoi(optarg);
- PRINTF("Height: %d\n", height);
- break;
- case 'n': scale_video = 0;
- PRINTF("Video scaling disabled\n");
- break;
- case 'P': if (static_post_plugins)
- strcatrealloc(static_post_plugins, ";");
- static_post_plugins = strcatrealloc(static_post_plugins, optarg);
- PRINTF("Post plugins: %s\n", static_post_plugins);
- break;
- case 'C': config_file = strdup(optarg);
- PRINTF("Config file: %s\n", config_file);
- break;
- case 'L': lirc_dev = strdup(optarg ? : "/dev/lircd");
- if (strstr((char*)lirc_dev, ",repeatemu")) {
- *strstr((char*)lirc_dev, ",repeatemu") = 0;
- repeat_emu = 1;
- }
- PRINTF("LIRC device: %s%s\n", lirc_dev,
- repeat_emu?", emulating key repeat":"");
- break;
- case 'v': SysLogLevel = (SysLogLevel<SYSLOGLEVEL_DEBUG) ? SYSLOGLEVEL_DEBUG : SysLogLevel+1;
- PRINTF("Verbose mode\n");
- break;
- case 's': SysLogLevel = 1;
- PRINTF("Silent mode\n");
- break;
- case 'S': slave_mode = 1;
- PRINTF("Slave mode\n");
- break;
- case 'l': LogToSysLog = 1;
- openlog(exec_name, LOG_PID|LOG_CONS, LOG_USER);
- break;
- case 'k': nokbd = 1;
- PRINTF("Keyboard input disabled\n");
- break;
- case 'o': gui_hotkeys = 1;
- PRINTF("GUI hotkeys enabled\n"
- " mapping keyboard f,F -> fullscreen toggle\n"
- " keyboard d,D -> deinterlace toggle\n"
- " LIRC Deinterlace -> deinterlace toggle\n"
- " LIRC Fullscreen -> fullscreen toggle\n"
- " LIRC Quit -> exit\n");
- break;
- case 'b': nokbd = daemon_mode = 1;
- PRINTF("Keyboard input disabled\n");
- break;
- case 'R': reconnect = 1;
- PRINTF("Automatic reconnection enabled\n");
- break;
- case 't': ftcp = 1;
- PRINTF("Protocol: TCP\n");
- break;
- case 'u': fudp = 1;
- PRINTF("Protocol: UDP\n");
- break;
- case 'r': frtp = 1;
- PRINTF("Protocol: RTP\n");
- break;
- case 1: printf("arg 1 (%s)\n", long_options[optind].name); exit(0);
- }
- }
-
- if (optind < argc) {
- mrl = strdup(argv[optind]);
- PRINTF("VDR Server: %s\n", mrl);
- while (++optind < argc)
- printf("Unknown argument: %s\n", argv[optind]);
- }
-
- PRINTF("\n");
-
-#if 1
- /* backward compability */
- if (mrl && ( !strncmp(mrl, MRL_ID ":tcp:", MRL_ID_LEN+5) ||
- !strncmp(mrl, MRL_ID ":udp:", MRL_ID_LEN+5) ||
- !strncmp(mrl, MRL_ID ":rtp:", MRL_ID_LEN+5) ||
- !strncmp(mrl, MRL_ID ":pipe:", MRL_ID_LEN+6)))
- mrl[4] = '+';
-#endif
-
- /* If server address not given, try to find server automatically */
- if (!mrl ||
- !strcmp(mrl, MRL_ID ":") ||
- !strcmp(mrl, MRL_ID "+tcp:") ||
- !strcmp(mrl, MRL_ID "+udp:") ||
- !strcmp(mrl, MRL_ID "+rtp:") ||
- !strcmp(mrl, MRL_ID "+pipe:")) {
- char address[1024] = "";
- int port = -1;
- PRINTF("VDR server not given, searching ...\n");
- if (udp_discovery_find_server(&port, &address[0])) {
- PRINTF("Found VDR server: host %s, port %d\n", address, port);
- if (mrl) {
- char *tmp = mrl;
- mrl = NULL;
- if (asprintf(&mrl, "%s//%s:%d", tmp, address, port) < 0)
- return -1;
- free(tmp);
- } else
- if (asprintf(&mrl, MRL_ID "://%s:%d", address, port) < 0)
- return -1;
- } else {
- PRINTF("---------------------------------------------------------------\n"
- "WARNING: MRL not given and server not found from local network.\n"
- " Trying to connect to default port on local host.\n"
- "---------------------------------------------------------------\n");
- mrl = strdup(MRL_ID "://127.0.0.1");
- }
- }
-
- if (mrl &&
- strncmp(mrl, MRL_ID ":", MRL_ID_LEN+1) &&
- strncmp(mrl, MRL_ID "+", MRL_ID_LEN+1)) {
- char *mrl2 = mrl;
- PRINTF("WARNING: MRL does not start with \'" MRL_ID ":\' (%s)", mrl);
- if (asprintf(&mrl, MRL_ID "://%s", mrl) < 0)
- return -1;
- free(mrl2);
- }
-
- {
- char *tmp = NULL, *mrl2 = mrl;
- if (frtp && !strstr(mrl, "rtp:"))
- tmp = strdup(MRL_ID "+rtp:");
- else if (fudp && !strstr(mrl, "udp:"))
- tmp = strdup(MRL_ID "+udp:");
- else if (ftcp && !strstr(mrl, "tcp:"))
- tmp = strdup(MRL_ID "+tcp:");
- if (tmp) {
- mrl = strcatrealloc(tmp, strchr(mrl, '/'));
- free(mrl2);
- }
- }
-
- if (daemon_mode) {
- PRINTF("Entering daemon mode\n\n");
- if (daemon(1, 0) == -1) {
- fprintf(stderr, "%s: %m\n", exec_name);
- LOGERR("daemon() failed");
- return -2;
- }
- }
-
- /* Create front-end */
- fe = (*fe_creator)();
- if (!fe) {
- fprintf(stderr, "Error initializing frontend\n");
- return -3;
- }
-
- /* Initialize display */
- if (!fe->fe_display_open(fe, xpos, ypos, width, height, fullscreen, hud, 0,
- "", aspect, NULL, noxkbd, gui_hotkeys,
- video_port, scale_video, 0,
- aspect_controller, window_id)) {
- fprintf(stderr, "Error opening display\n");
- fe->fe_free(fe);
- return -4;
- }
-
- /* Initialize xine */
- if (!fe->xine_init(fe, adrv, adev, gdrv, 250, static_post_plugins, config_file)) {
- fprintf(stderr, "Error initializing xine\n");
- list_xine_plugins(fe, SysLogLevel>2);
- fe->fe_free(fe);
- return -5;
- }
-
- if (SysLogLevel > 2)
- list_xine_plugins(fe, SysLogLevel>2);
-
- /* signal handlers */
-
- if (signal(SIGHUP, SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN);
- if (signal(SIGINT, SignalHandler) == SIG_IGN) signal(SIGINT, SIG_IGN);
- if (signal(SIGTERM, SignalHandler) == SIG_IGN) signal(SIGTERM, SIG_IGN);
- if (signal(SIGPIPE, SignalHandler) == SIG_IGN) signal(SIGPIPE, SIG_IGN);
-
- do {
-
- if (!firsttry) {
- PRINTF("Connection to server lost. Reconnecting after two seconds...\n");
- sleep(2);
- PRINTF("Reconnecting...\n");
- }
-
- /* Connect to VDR xineliboutput server */
- if (!fe->xine_open(fe, mrl)) {
- /*print_xine_log(((fe_t *)fe)->xine);*/
- if (!firsttry) {
- PRINTF("Error opening %s\n", mrl);
- continue;
- }
- fprintf(stderr, "Error opening %s\n", mrl);
- fe->fe_free(fe);
- return -6;
- }
-
- if (!fe->xine_play(fe)) {
- if (!firsttry) {
- PRINTF("Error playing %s\n", argv[1]);
- continue;
- }
- fprintf(stderr, "Error playing %s\n", argv[1]);
- fe->fe_free(fe);
- return -7;
- }
-
- if (firsttry) {
-
- /* Start LIRC forwarding */
- lirc_start(fe, lirc_dev, repeat_emu);
-
- /* Start keyboard listener thread */
- if (!nokbd) {
- PRINTF("\n\nPress Esc to exit\n\n");
- kbd_start(fe, slave_mode);
- }
- }
-
- /* Main loop */
-
- fflush(stdout);
- fflush(stderr);
-
- while (!last_signal && fe->fe_run(fe))
- ;
- xine_finished = fe->xine_is_finished(fe,0);
-
- fe->xine_close(fe);
- firsttry = 0;
-
- /* HUP reconnects */
- if (last_signal == SIGHUP)
- last_signal = 0;
-
- } while (!last_signal && xine_finished != FE_XINE_EXIT && reconnect);
-
- /* Clean up */
-
- PRINTF("Terminating...\n");
-
- fe->send_event(fe, "QUIT");
-
- /* stop input threads */
- lirc_stop();
- if (!nokbd)
- kbd_stop();
-
- fe->fe_free(fe);
-
- free(config_file);
- free(static_post_plugins);
- free(mrl);
- free(adrv);
- free(gdrv);
- free(video_port);
- free(aspect_controller);
- free(lirc_dev);
-
- return xine_finished==FE_XINE_EXIT ? 0 : 1;
-}
diff --git a/xine_input_vdr.c b/xine_input_vdr.c
deleted file mode 100644
index 2f7e35b0..00000000
--- a/xine_input_vdr.c
+++ /dev/null
@@ -1,5641 +0,0 @@
-/*
- * xine_input_vdr.c: xine VDR input plugin
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xine_input_vdr.c,v 1.273 2009-07-17 22:48:29 phintuka Exp $
- *
- */
-
-
-#define XINE_ENGINE_INTERNAL
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <poll.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <dlfcn.h>
-#include <sys/resource.h> /* setpriority() */
-#include <sys/stat.h>
-#include <syslog.h>
-
-#ifndef __APPLE__
-# define DVD_STREAMING_SPEED
-#endif
-
-#ifdef DVD_STREAMING_SPEED
-# include <linux/cdrom.h>
-# include <scsi/sg.h>
-#endif
-
-#include <xine/xine_internal.h>
-#include <xine/xineutils.h>
-#include <xine/input_plugin.h>
-#include <xine/plugin_catalog.h>
-#include <xine/io_helper.h>
-#include <xine/buffer.h>
-#include <xine/post.h>
-
-#ifndef XINE_VERSION_CODE
-# error XINE_VERSION_CODE undefined !
-#endif
-
-#if XINE_VERSION_CODE >= 10190
-# include "features.h"
-# ifdef HAVE_LIBAVUTIL
-# include <libavutil/mem.h>
-# else
-# error "plugin was configured without libavutil. It can't be compiled against xine-lib 1.2 !"
-# endif
-#endif
-
-#include "xine/adjustable_scr.h"
-#include "xine/osd_manager.h"
-
-#include "xine_input_vdr.h"
-#include "xine_input_vdr_net.h"
-#include "xine_osd_command.h"
-
-#include "tools/mpeg.h"
-#include "tools/pes.h"
-#include "tools/ts.h"
-
-/***************************** DEFINES *********************************/
-
-/*#define LOG_UDP*/
-/*#define LOG_OSD*/
-/*#define LOG_CMD*/
-/*#define LOG_SCR*/
-/*#define LOG_TRACE*/
-
-#define METRONOM_PREBUFFER_VAL (4 * 90000 / 25 )
-#define HD_BUF_NUM_BUFS (2048) /* 2k payload * 2048 = 4Mb , ~ 1 second */
-#define HD_BUF_ELEM_SIZE (2048+64)
-
-#define RADIO_MAX_BUFFERS 10
-
-#ifndef NOSIGNAL_IMAGE_FILE
-# define NOSIGNAL_IMAGE_FILE "/usr/share/vdr/xineliboutput/nosignal.mpv"
-#endif
-#ifndef NOSIGNAL_MAX_SIZE
-# define NOSIGNAL_MAX_SIZE 0x10000 /* 64k */
-#endif
-
-/*
- Note:
- I tried to set speed to something very small instead of full pause
- when pausing SCR but it didn't work in all systems.
- TEST_SCR_PAUSE replaces this by adding delay before stream
- is paused (pause is triggered by first received PES containing PTS).
- This should allow immediate processing of still frames and let video_out
- run in paused_loop when there is gap in feed (ex. channel can't be decrypted).
- Not running video_out in paused_loop caused very long delays in
- OSD updating in some setups.
-*/
-#define TEST_SCR_PAUSE
-
-/* picture-in-picture support */
-/*#define TEST_PIP 1*/
-
-
-#define CONTROL_BUF_BASE ( 0x0f000000) /* 0x0f000000 */
-#define CONTROL_BUF_BLANK (CONTROL_BUF_BASE|0x00010000) /* 0x0f010000 */
-#define CONTROL_BUF_CLEAR (CONTROL_BUF_BASE|0x00020000) /* 0x0f020000 */
-#define BUF_NETWORK_BLOCK (BUF_DEMUX_BLOCK |0x00010000) /* 0x05010000 */
-
-#define SPU_CHANNEL_NONE (-2)
-#define SPU_CHANNEL_AUTO (-1)
-
-/******************************* LOG ***********************************/
-
-#ifndef __APPLE__
-# include <linux/unistd.h> /* syscall(__NR_gettid) */
-#endif
-
-static const char log_module_input_vdr[] = "[input_vdr] ";
-#define LOG_MODULENAME log_module_input_vdr
-#define SysLogLevel iSysLogLevel
-
-#include "logdefs.h"
-
-int iSysLogLevel = 1; /* 0:none, 1:errors, 2:info, 3:debug */
-int bLogToSysLog = 0;
-int bSymbolsFound = 0;
-
-void x_syslog(int level, const char *module, const char *fmt, ...)
-{
- va_list argp;
- char buf[512];
- va_start(argp, fmt);
- vsnprintf(buf, sizeof(buf), fmt, argp);
- buf[sizeof(buf)-1] = 0;
-#ifdef __APPLE__
- if(!bLogToSysLog) {
- fprintf(stderr, "%s%s\n", module, buf);
- } else {
- syslog(level, "%s%s", module, buf);
- }
-#else
- if(!bLogToSysLog) {
- fprintf(stderr,"[%ld] %s%s\n", syscall(__NR_gettid), module, buf);
- } else {
- syslog(level, "[%ld] %s%s", syscall(__NR_gettid), module, buf);
- }
-#endif
- va_end(argp);
-}
-
-static void SetupLogLevel(void)
-{
- void *lib = NULL;
- if( !(lib = dlopen (NULL, RTLD_LAZY | RTLD_GLOBAL))) {
- LOGERR("Can't dlopen self: %s", dlerror());
- } else {
- int *pLogToSyslog = (int*)dlsym(lib, "LogToSysLog");
- int *pSysLogLevel = (int*)dlsym(lib, "SysLogLevel");
- bLogToSysLog = pLogToSyslog && *pLogToSyslog;
- iSysLogLevel = pSysLogLevel ? (*pSysLogLevel) : iSysLogLevel;
- LOGDBG("Symbol SysLogLevel %s : value %d",
- pSysLogLevel ? "found" : "not found", iSysLogLevel);
- LOGDBG("Symbol LogToSysLog %s : value %s",
- pLogToSyslog ? "found" : "not found", bLogToSysLog ? "yes" : "no");
- bSymbolsFound = pSysLogLevel && pLogToSyslog;
- dlclose(lib);
- }
-}
-
-#define LOG_UDP
-
-#ifdef LOG_SCR
-# define LOGSCR(x...) LOGMSG("SCR: " x)
-#else
-# define LOGSCR(x...)
-#endif
-#
-#ifdef LOG_OSD
-# define LOGOSD(x...) LOGMSG("OSD: " x)
-#else
-# define LOGOSD(x...)
-#endif
-#
-#ifdef LOG_UDP
-# define LOGUDP(x...) LOGMSG("UDP:" x)
-#else
-# define LOGUDP(x...)
-#endif
-#ifdef LOG_CMD
-# define LOGCMD(x...) LOGMSG("CMD:" x)
-#else
-# define LOGCMD(x...)
-#endif
-#ifdef LOG_TRACE
-# undef TRACE
-# define TRACE(x...) printf(x)
-#else
-# undef TRACE
-# define TRACE(x...)
-#endif
-
-
-/*#define DEBUG_LOCKING*/
-#ifdef DEBUG_LOCKING
-# include "tools/debug_mutex.h"
-#endif
-
-/******************************* DATA ***********************************/
-
-#define KILOBYTE(x) (1024 * (x))
-
-typedef struct udp_data_s udp_data_t;
-
-/* plugin class */
-typedef struct vdr_input_class_s {
- input_class_t input_class;
- xine_t *xine;
- char *mrls[ 2 ];
- int fast_osd_scaling;
- double scr_tuning_step;
-} vdr_input_class_t;
-
-/* input plugin */
-typedef struct vdr_input_plugin_s {
- union {
- vdr_input_plugin_if_t iface;
- struct {
- input_plugin_t input_plugin;
- vdr_input_plugin_funcs_t funcs;
- };
- };
-
- /* plugin */
- vdr_input_class_t *class;
- xine_stream_t *stream;
- xine_event_queue_t *event_queue;
- osd_manager_t *osd_manager;
-
- char *mrl;
-
- xine_stream_t *pip_stream;
- xine_stream_t *slave_stream;
- xine_event_queue_t *slave_event_queue;
- int autoplay_size;
-
- /* Sync */
- pthread_mutex_t lock;
- pthread_mutex_t vdr_entry_lock;
- pthread_cond_t engine_flushed;
-
- /* Playback */
- uint8_t read_timeouts; /* number of timeouts in read_block */
- uint8_t no_video : 1;
- uint8_t live_mode : 1;
- uint8_t still_mode : 1;
- uint8_t stream_start : 1;
- uint8_t loop_play : 1;
- uint8_t dvd_menu : 1;
- uint8_t hd_stream : 1; /* true if current stream is HD */
- uint8_t sw_volume_control : 1;
-
- /* SCR */
- adjustable_scr_t *scr;
- int speed_before_pause;
- int8_t scr_tuning;
- uint8_t fixed_scr : 1;
- uint8_t scr_live_sync : 1;
- uint8_t is_paused : 1;
- uint8_t is_trickspeed : 1;
-
- uint I_frames; /* amount of I-frames passed to demux */
- uint B_frames;
- uint P_frames;
-
- /* Network */
- pthread_t control_thread;
- pthread_t data_thread;
- pthread_mutex_t fd_control_lock;
- buf_element_t *read_buffer;
- int threads_initialized;
- volatile int control_running;
- volatile int fd_data;
- volatile int fd_control;
- uint8_t tcp, udp, rtp;
- udp_data_t *udp_data;
- int client_id;
- int token;
-
- /* buffer */
- fifo_buffer_t *block_buffer; /* blocks to be demuxed */
- fifo_buffer_t *buffer_pool; /* stream's video fifo */
- fifo_buffer_t *hd_buffer; /* more buffer for HD streams */
- fifo_buffer_t *iframe_buffer; /* buffer for cached I-frame */
- int saving_iframe;
- uint64_t discard_index; /* index of next byte to feed to demux;
- all data before this offset will
- be discarded */
- uint64_t discard_index_ds;
- int discard_frame;
- uint64_t guard_index; /* data before this offset will not be discarded */
- int guard_frame;
- uint64_t curpos; /* current position (demux side) */
- int curframe;
- int max_buffers; /* max no. of non-demuxed buffers */
-
- /* saved video properties */
- int video_properties_saved;
- int orig_hue;
- int orig_brightness;
- int orig_saturation;
- int orig_sharpness;
- int orig_noise_reduction;
- int orig_contrast;
- int orig_vo_aspect_ratio;
-
-} vdr_input_plugin_t;
-
-
-/***************************** UDP DATA *********************************/
-
-struct udp_data_s {
-
- /* Server address (used to validate incoming packets) */
- struct sockaddr_in server_address;
- uint32_t ssrc;
-
- /* receiving queue for re-ordering and re-transmissions */
- buf_element_t *queue[UDP_SEQ_MASK+1];
- uint64_t queue_input_pos; /* stream position of next incoming byte */
- uint16_t queued; /* count of frames in queue */
- uint16_t next_seq; /* expected sequence number of next incoming packet */
-
- uint16_t current_seq; /* sequence number of last received packet */
- uint8_t is_padding; /* true, if last received packet was padding packet */
-
- /* missing frames ratio statistics */
- int16_t missed_frames;
- int16_t received_frames;
-
- /* SCR adjust */
- uint8_t scr_jump_done;
-
- int resend_requested;
-};
-
-/* UDP sequence number handling */
-#define NEXTSEQ(x) ((x + 1) & UDP_SEQ_MASK)
-#define PREVSEQ(x) ((x + UDP_SEQ_MASK) & UDP_SEQ_MASK)
-#define INCSEQ(x) (x = NEXTSEQ(x))
-#define ADDSEQ(x,n) ((x + UDP_SEQ_MASK + 1 + n) & UDP_SEQ_MASK)
-
-#define UDP_SIGNAL_FULL_TRESHOLD 50 /* ~100ms with DVB mpeg2
- (2k-blocks @ 8 Mbps) */
-#define UDP_SIGNAL_NOT_FULL_TRESHOLD 100 /* ~200ms with DVB mpeg2
- (2k-blocks @ 8 Mbps) */
-
-static udp_data_t *init_udp_data(void)
-{
- udp_data_t *data = calloc(1, sizeof(udp_data_t));
-
- data->received_frames = -1;
-
- return data;
-}
-
-static void free_udp_data(udp_data_t *data)
-{
- int i;
-
- for(i=0; i<=UDP_SEQ_MASK; i++)
- if(data->queue[i]) {
- data->queue[i]->free_buffer(data->queue[i]);
- data->queue[i] = NULL;
- }
- free(data);
-}
-
-#if 0
-static void flush_udp_data(udp_data_t *data)
-{
- /* flush all data immediately even if there are gaps */
-}
-#endif
-
-/********************* cancellable mutex locking *************************/
-
-/*
- * mutex cleanup()
- *
- * Unlock mutex. Used as thread cleanup handler.
- */
-static void mutex_cleanup(void *arg)
-{
- pthread_mutex_unlock((pthread_mutex_t *)arg);
-}
-
-/*
- * mutex_lock_cancellable() / mutex_unlock_cancellable()
- *
- * mutex lock/unlock for cancellable sections
- *
- * - do not enter protected section if locking fails
- * - unlock mutex if thread is cancelled while holding the lock
- *
- * - lock/unlock must be used pairwise within the same lexical scope !
- *
- */
-#define mutex_lock_cancellable(mutex) \
- if (pthread_mutex_lock(mutex)) { \
- LOGERR("pthread_mutex_lock (%s) failed, skipping locked block !", #mutex); \
- } else { \
- pthread_cleanup_push(mutex_cleanup, (void*) mutex);
-
-#define mutex_unlock_cancellable(mutex) \
- if (pthread_mutex_unlock(mutex)) \
- LOGERR("pthread_mutex_unlock (%s) failed !", #mutex); \
- pthread_cleanup_pop(0); \
- }
-
-/******************************* SCR ***********************************/
-/*
- * SCR fine tuning
- *
- * fine tuning is used to change playback speed in live mode
- * to keep in sync with mpeg source
- *
- * SCR code is mostly copied from xine-lib (src/input/input_pvr.c)
- */
-
-#define SCR_TUNING_PAUSED -3
-#define SCR_TUNING_OFF 0
-
-#ifdef LOG_SCR
-static inline const char *scr_tuning_str(int value)
-{
- switch(value) {
- case 2: return "SCR +2";
- case 1: return "SCR +1";
- case SCR_TUNING_OFF: return "SCR +0";
- case -1: return "SCR -1";
- case -2: return "SCR -2";
- case SCR_TUNING_PAUSED: return "SCR PAUSED";
- default: break;
- }
- return "ERROR";
-}
-#endif
-
-static void scr_tuning_set_paused(vdr_input_plugin_t *this)
-{
- if(this->scr_tuning != SCR_TUNING_PAUSED &&
- !this->slave_stream &&
- !this->is_trickspeed) {
-
- this->scr_tuning = SCR_TUNING_PAUSED; /* marked as paused */
- if(this->scr)
- this->scr->set_speed_tuning(this->scr, 1.0);
-
- this->speed_before_pause = _x_get_fine_speed(this->stream);
-
-#ifdef TEST_SCR_PAUSE
- if(_x_get_fine_speed(this->stream) != XINE_SPEED_PAUSE)
- _x_set_fine_speed(this->stream, XINE_SPEED_PAUSE);
-#else
- _x_set_fine_speed(this->stream, 1000000 / 1000); /* -> speed to 0.1% */
-#endif
- this->I_frames = this->P_frames = this->B_frames = 0;
- }
-}
-
-static void reset_scr_tuning(vdr_input_plugin_t *this, int new_speed)
-{
- if(this->scr_tuning != SCR_TUNING_OFF) {
- this->scr_tuning = SCR_TUNING_OFF; /* marked as normal */
- if(this->scr)
- this->scr->set_speed_tuning(this->scr, 1.0);
-
- if(new_speed >= 0) {
- if(_x_get_fine_speed(this->stream) != new_speed) {
- _x_set_fine_speed(this->stream, XINE_FINE_SPEED_NORMAL);
- }
- this->scr->scr.set_fine_speed(&this->scr->scr, XINE_FINE_SPEED_NORMAL);
- }
- }
-}
-
-static void vdr_adjust_realtime_speed(vdr_input_plugin_t *this)
-{
- /*
- * Grab current buffer usage
- */
- int num_used = this->buffer_pool->size(this->buffer_pool) +
- this->block_buffer->size(this->block_buffer);
- int num_free = this->buffer_pool->num_free(this->buffer_pool);
- int scr_tuning = this->scr_tuning;
- /*int num_vbufs = 0;*/
-
- if(this->hd_stream && this->hd_buffer) {
- num_free += this->hd_buffer->num_free(this->hd_buffer);
- }
-
- if(this->stream->audio_fifo)
- num_used += this->stream->audio_fifo->size(this->stream->audio_fifo);
- num_free -= (this->buffer_pool->buffer_pool_capacity - this->max_buffers);
-
-#ifdef LOG_SCR
- /*
- * Trace current buffer and tuning status
- */
- {
- static int fcnt=0;
- if(!((fcnt++)%2500) ||
- (this->scr_tuning==SCR_TUNING_PAUSED && !(fcnt%10)) ||
- (this->no_video && !(fcnt%50))) {
- LOGSCR("Buffer %2d%% (%3d/%3d) %s",
- 100*num_used/(num_used+num_free),
- num_used, num_used+num_free,
- scr_tuning_str(this->scr_tuning));
- }
- }
-
- if(this->scr_tuning==SCR_TUNING_PAUSED) {
- if(_x_get_fine_speed(this->stream) != XINE_SPEED_PAUSE) {
- LOGMSG("ERROR: SCR PAUSED ; speed=%d bool=%d",
- _x_get_fine_speed(this->stream),
- (int)_x_get_fine_speed(this->stream) == XINE_SPEED_PAUSE);
- _x_set_fine_speed(this->stream, XINE_SPEED_PAUSE);
- }
- }
-#endif
-
- /*
- * SCR -> PAUSE
- * - If buffer is empty, pause SCR (playback) for a while
- */
- if( num_used < 1 &&
- scr_tuning != SCR_TUNING_PAUSED &&
- !this->no_video && !this->still_mode && !this->is_trickspeed) {
-#if 0
- this->class->xine->port_ticket->acquire(this->class->xine->port_ticket, 0);
- num_vbufs = this->stream->video_out->get_property(this->stream->video_out,
- VO_PROP_BUFS_IN_FIFO);
- this->class->xine->port_ticket->release(this->class->xine->port_ticket, 0);
- if(num_vbufs < 3) {
- LOGSCR("SCR paused by adjust_speed (vbufs=%d)", num_vbufs);
-#endif
- scr_tuning_set_paused(this);
-#if 0
- } else {
- LOGSCR("adjust_speed: no pause, enough vbufs queued (%d)", num_vbufs);
- }
-#endif
-
-
- /* SCR -> RESUME
- * - If SCR (playback) is currently paused due to previous buffer underflow,
- * revert to normal if buffer fill is > 66%
- */
- } else if( scr_tuning == SCR_TUNING_PAUSED) {
-/*
- #warning TODO:
- - Using amount of buffers is not good trigger as it depends on channel bitrate
- - Wait time is not not good trigger as it depends on tuner lock time
- -> maybe keep track of PTSes or wait until decoder has complete IBBBP frame sequence ?
- - First I-frame can be delivered as soon as it is decoded
- -> illusion of faster channel switches
-*/
-#if 0
- /* causes random freezes with some post plugins */
- this->class->xine->port_ticket->acquire(this->class->xine->port_ticket, 0);
- num_vbufs = this->stream->video_out->get_property(this->stream->video_out,
- VO_PROP_BUFS_IN_FIFO);
- this->class->xine->port_ticket->release(this->class->xine->port_ticket, 0);
-#endif
-
- if( num_used/2 > num_free
- || (this->no_video && num_used > 5)
- || this->still_mode
- || this->is_trickspeed
- || ( this->I_frames > 0
- && (this->I_frames > 2 || this->P_frames > 6 ))
- ) {
- LOGSCR("SCR tuning resetted by adjust_speed, "
- "I %d B %d P %d", this->I_frames, this->B_frames, this->P_frames);
-
- this->I_frames = 0;
- reset_scr_tuning(this, this->speed_before_pause);
- }
-
- /*
- * Adjust SCR rate
- * - Live data is coming in at rate defined by sending transponder,
- * there is no way to change it -> we must adapt to it
- * - when playing realtime (live) stream, adjust our SCR to keep
- * xine buffers half full. This efficiently synchronizes our SCR
- * to transponder SCR and prevents buffer under/overruns caused by
- * minor differences in clock speeds.
- * - if buffer is getting empty, slow don SCR by 0.5...1%
- * - if buffer is getting full, speed up SCR by 0.5...1%
- *
- * TODO: collect simple statistics and try to calculate more exact
- * clock rate difference to minimize SCR speed changes
- */
- } else if( _x_get_fine_speed(this->stream) == XINE_FINE_SPEED_NORMAL) {
-
- if(!this->scr_live_sync) {
- scr_tuning = SCR_TUNING_OFF;
-
- } else if(this->no_video) { /* radio stream ? */
- if( num_used >= (RADIO_MAX_BUFFERS-1))
- scr_tuning = +1; /* play faster */
- else if( num_used <= (RADIO_MAX_BUFFERS/3))
- scr_tuning = -1; /* play slower */
- else
- scr_tuning = SCR_TUNING_OFF;
- } else {
- if( num_used > 4*num_free && this->class->scr_tuning_step >= 0.001)
- scr_tuning = +2; /* play 1% faster */
- else if( num_used > 2*num_free )
- scr_tuning = +1; /* play .5% faster */
- else if( num_free > 4*num_used && this->class->scr_tuning_step >= 0.001) /* <20% */
- scr_tuning = -2; /* play 1% slower */
- else if( num_free > 2*num_used ) /* <33% */
- scr_tuning = -1; /* play .5% slower */
- else if( (scr_tuning > 0 && num_free > num_used) ||
- (scr_tuning < 0 && num_used > num_free) )
- scr_tuning = SCR_TUNING_OFF;
- }
-
- if( scr_tuning != this->scr_tuning ) {
- LOGSCR("scr_tuning: %s -> %s (buffer %d/%d) (tuning now %f%%)",
- scr_tuning_str(this->scr_tuning),
- scr_tuning_str(scr_tuning), num_used, num_free, this->class->scr_tuning_step * scr_tuning * 100.0);
- this->scr_tuning = scr_tuning;
-
- /* make it play .5% / 1% faster or slower */
- if(this->scr)
- this->scr->set_speed_tuning(this->scr, 1.0 + (this->class->scr_tuning_step * scr_tuning) );
- }
-
- /*
- * SCR -> NORMAL
- * - If we are in replay (or trick speed) mode, switch SCR tuning off
- * as we can always have complete control on incoming data rate
- */
- } else if( this->scr_tuning ) {
- reset_scr_tuning(this, -1);
- }
-}
-
-/******************************* TOOLS ***********************************/
-
-#ifndef MIN
-# define MIN(a,b) ((a)<(b)?(a):(b))
-#endif
-#ifndef MAX
-# define MAX(a,b) ((a)>(b)?(a):(b))
-#endif
-
-static char *strn0cpy(char *dest, const char *src, int n)
-{
- char *s = dest;
- for ( ; --n && (*dest = *src) != 0; dest++, src++) ;
- *dest = 0;
- return s;
-}
-
-static char *unescape_filename(const char *fn)
-{
- char *d = strdup(fn), *s = d, *result = d;
- while(*s && *s != '#') {
- if(s[0] == '%' && s[1] && s[2]) {
- unsigned int c;
- if (sscanf(s+1, "%02x", &c) == 1) {
- *d++ = (char)c;
- s += 3;
- continue;
- }
- }
- *d++ = *s++;
- }
- *d = 0;
- return result;
-}
-
-static void create_timeout_time(struct timespec *abstime, int timeout_ms)
-{
- struct timeval now;
- gettimeofday(&now, NULL);
- now.tv_usec += timeout_ms * 1000;
- while (now.tv_usec >= 1000000) { /* take care of an overflow */
- now.tv_sec++;
- now.tv_usec -= 1000000;
- }
- abstime->tv_sec = now.tv_sec;
- abstime->tv_nsec = now.tv_usec * 1000;
-}
-
-/**************************** socket I/O *********************************/
-
-/*
- * io_select_rd()
- *
- * - poll socket for read
- * - timeouts in 500 ms
- * - returns XIO_*
- */
-static int io_select_rd (int fd)
-{
- fd_set fdset, eset;
- int ret;
- struct timeval select_timeout;
-
- if(fd < 0)
- return XIO_ERROR;
-
- FD_ZERO (&fdset);
- FD_ZERO (&eset);
- FD_SET (fd, &fdset);
- FD_SET (fd, &eset);
-
- select_timeout.tv_sec = 0;
- select_timeout.tv_usec = 500*1000; /* 500 ms */
- errno = 0;
- ret = select (fd + 1, &fdset, NULL, &eset, &select_timeout);
-
- if (ret == 0)
- return XIO_TIMEOUT;
- if (ret < 0) {
- if (errno == EINTR || errno == EAGAIN)
- return XIO_TIMEOUT;
- return XIO_ERROR;
- }
-
- if (FD_ISSET(fd, &eset))
- return XIO_ERROR;
- if (FD_ISSET(fd, &fdset))
- return XIO_READY;
-
- return XIO_TIMEOUT;
-}
-
-/*
- * write_control_data()
- *
- * - write len bytes to control socket.
- * - returns number of bytes written, < 0 on error.
- *
- * NOTE: caller must hold fd_control lock !
- */
-static ssize_t write_control_data(vdr_input_plugin_t *this, const void *str, size_t len)
-{
- size_t ret, result = len;
-
- while (len > 0) {
-
- if (!this->control_running) {
- LOGERR("write_control aborted");
- return -1;
- }
-
- /* poll the socket */
- fd_set fdset, eset;
- struct timeval select_timeout;
- FD_ZERO (&fdset);
- FD_ZERO (&eset);
- FD_SET (this->fd_control, &fdset);
- FD_SET (this->fd_control, &eset);
- select_timeout.tv_sec = 0;
- select_timeout.tv_usec = 500*1000; /* 500 ms */
- errno = 0;
- if (1 != select (this->fd_control + 1, NULL, &fdset, &eset, &select_timeout) ||
- !FD_ISSET(this->fd_control, &fdset) ||
- FD_ISSET(this->fd_control, &eset)) {
- LOGERR("write_control failed (poll timeout or error)");
- this->control_running = 0;
- return -1;
- }
-
- if (!this->control_running) {
- LOGERR("write_control aborted");
- return -1;
- }
-
- errno = 0;
- ret = write (this->fd_control, str, len);
-
- if (ret <= 0) {
- if (ret == 0) {
- LOGMSG("write_control: disconnected");
- } else if (errno == EAGAIN) {
- LOGERR("write_control failed: EAGAIN");
- continue;
- } else if (errno == EINTR) {
- LOGERR("write_control failed: EINTR");
- pthread_testcancel();
- continue;
- } else {
- LOGERR("write_control failed");
- }
- this->control_running = 0;
- return -1;
- }
- len -= ret;
- str += ret;
- }
-
- return result;
-}
-
-/*
- * write_control()
- *
- * - write null-terminated string to control socket.
- * - returns number of bytes written, < 0 on error
- *
- * NOTE: caller should NOT hold fd_control lock !
- */
-static ssize_t write_control(vdr_input_plugin_t *this, const char *str)
-{
- ssize_t ret = -1;
- mutex_lock_cancellable (&this->fd_control_lock);
- ret = write_control_data(this, str, strlen(str));
- mutex_unlock_cancellable (&this->fd_control_lock);
- return ret;
-}
-
-/*
- * printf_control()
- *
- * - returns number of bytes written, < 0 on error
- *
- * NOTE: caller should NOT hold fd_control lock !
- */
-static ssize_t printf_control(vdr_input_plugin_t *this, const char *fmt, ...)
-{
- va_list argp;
- char buf[512];
- ssize_t result;
-
- va_start(argp, fmt);
- vsnprintf(buf, sizeof(buf), fmt, argp);
- buf[sizeof(buf)-1] = 0;
-
- result = write_control(this, buf);
-
- va_end(argp);
-
- return result;
-}
-
-/*
- * readline_control()
- *
- * - read CR/LF terminated string from control socket
- * - remove trailing CR/LF
- * - returns > 0 : length of string
- * = 0 : timeout
- * < 0 : error
- */
-static ssize_t readline_control(vdr_input_plugin_t *this, char *buf, size_t maxlen, int timeout)
-{
- int poll_result;
- ssize_t read_result;
- size_t total_bytes = 0;
-
- *buf = 0;
- while (total_bytes < maxlen - 1) {
-
- if (!this->control_running && timeout < 0)
- return -1;
-
- pthread_testcancel();
- poll_result = io_select_rd(this->fd_control);
- pthread_testcancel();
-
- if (!this->control_running && timeout < 0)
- return -1;
-
- if (poll_result == XIO_TIMEOUT) {
- if (timeout == 0)
- return 0;
- if (timeout > 0)
- timeout--;
- continue;
- }
- if (poll_result == XIO_ABORTED) {
- LOGERR("readline_control: XIO_ABORTED at [%u]", (uint)total_bytes);
- continue;
- }
- if (poll_result != XIO_READY /* == XIO_ERROR */) {
- LOGERR("readline_control: poll error at [%u]", (uint)total_bytes);
- return -1;
- }
-
- errno = 0;
- read_result = read (this->fd_control, buf + total_bytes, 1);
- pthread_testcancel();
-
- if (!this->control_running && timeout < 0)
- return -1;
-
- if (read_result <= 0) {
- if (read_result == 0)
- LOGERR("Control stream disconnected");
- else
- LOGERR("readline_control: read error at [%u]", (uint)total_bytes);
- if (read_result < 0 && (errno == EINTR || errno == EAGAIN))
- continue;
- return -1;
- }
-
- if (buf[total_bytes]) {
- if (buf[total_bytes] == '\r') {
- buf[total_bytes] = 0;
- } else if (buf[total_bytes] == '\n') {
- buf[total_bytes] = 0;
- break;
- } else {
- total_bytes ++;
- buf[total_bytes] = 0;
- }
- }
- TRACE("readline_control: %d bytes ... %s\n", len, buf);
- }
-
- TRACE("readline_control: %d bytes (max %d)\n", len, maxlen);
-
- return total_bytes;
-}
-
-/*
- * read_control()
- *
- * - read len bytes from control socket
- * - returns < 0 on error
- */
-static ssize_t read_control(vdr_input_plugin_t *this, uint8_t *buf, size_t len)
-{
- int poll_result;
- ssize_t num_bytes;
- size_t total_bytes = 0;
-
- while (total_bytes < len) {
-
- if (!this->control_running)
- return -1;
-
- pthread_testcancel();
- poll_result = io_select_rd(this->fd_control);
- pthread_testcancel();
-
- if (!this->control_running)
- return -1;
-
- if (poll_result == XIO_TIMEOUT) {
- continue;
- }
- if (poll_result == XIO_ABORTED) {
- LOGERR("read_control: XIO_ABORTED");
- continue;
- }
- if (poll_result == XIO_ERROR) {
- LOGERR("read_control: poll error");
- return -1;
- }
-
- errno = 0;
- num_bytes = read (this->fd_control, buf + total_bytes, len - total_bytes);
- pthread_testcancel();
-
- if (num_bytes <= 0) {
- if (this->control_running && num_bytes < 0)
- LOGERR("read_control read() error");
- return -1;
- }
- total_bytes += num_bytes;
- }
-
- return total_bytes;
-}
-
-/************************** BUFFER HANDLING ******************************/
-
-static void buffer_pool_free (buf_element_t *element)
-{
- fifo_buffer_t *this = (fifo_buffer_t *) element->source;
-
- pthread_mutex_lock (&this->buffer_pool_mutex);
-
- element->next = this->buffer_pool_top;
- this->buffer_pool_top = element;
-
- this->buffer_pool_num_free++;
- if (this->buffer_pool_num_free > this->buffer_pool_capacity) {
- LOGERR("xine-lib:buffer: There has been a fatal error: TOO MANY FREE's");
- _x_abort();
- }
-
- if(this->buffer_pool_num_free > 20)
- pthread_cond_signal (&this->buffer_pool_cond_not_empty);
-
- pthread_mutex_unlock (&this->buffer_pool_mutex);
-}
-
-static buf_element_t *fifo_buffer_try_get(fifo_buffer_t *fifo)
-{
- int i;
- buf_element_t *buf;
-
- pthread_mutex_lock (&fifo->mutex);
-
- if (fifo->first==NULL) {
- pthread_mutex_unlock (&fifo->mutex);
- return NULL;
- }
-
- buf = fifo->first;
-
- fifo->first = fifo->first->next;
- if (fifo->first==NULL)
- fifo->last = NULL;
-
- fifo->fifo_size--;
- fifo->fifo_data_size -= buf->size;
-
- for(i = 0; fifo->get_cb[i]; i++)
- fifo->get_cb[i](fifo, buf, fifo->get_cb_data[i]);
-
- pthread_mutex_unlock (&fifo->mutex);
-
- return buf;
-}
-
-static buf_element_t *fifo_buffer_timed_get(fifo_buffer_t *fifo, int timeout)
-{
- buf_element_t *buf = fifo_buffer_try_get (fifo);
-
- if (!buf) {
- struct timespec abstime;
- int result = 0;
- create_timeout_time (&abstime, timeout);
-
- mutex_lock_cancellable (&fifo->mutex);
- while (fifo->first == NULL && !result)
- result = pthread_cond_timedwait (&fifo->not_empty, &fifo->mutex, &abstime);
- mutex_unlock_cancellable (&fifo->mutex);
- buf = fifo_buffer_try_get (fifo);
- }
-
- return buf;
-}
-
-static void signal_buffer_pool_not_empty(vdr_input_plugin_t *this)
-{
- if (this->buffer_pool) {
- pthread_mutex_lock(&this->buffer_pool->buffer_pool_mutex);
- pthread_cond_broadcast(&this->buffer_pool->buffer_pool_cond_not_empty);
- pthread_mutex_unlock(&this->buffer_pool->buffer_pool_mutex);
- }
- if (this->hd_buffer) {
- pthread_mutex_lock(&this->hd_buffer->buffer_pool_mutex);
- pthread_cond_broadcast(&this->hd_buffer->buffer_pool_cond_not_empty);
- pthread_mutex_unlock(&this->hd_buffer->buffer_pool_mutex);
- }
-}
-
-static void signal_buffer_not_empty(vdr_input_plugin_t *this)
-{
- if(this->block_buffer) {
- pthread_mutex_lock(&this->block_buffer->mutex);
- pthread_cond_broadcast(&this->block_buffer->not_empty);
- pthread_mutex_unlock(&this->block_buffer->mutex);
- }
-}
-
-#if XINE_VERSION_CODE < 10190
-# define fifo_buffer_new(stream, n, s) _x_fifo_buffer_new(n, s)
-#else
-static fifo_buffer_t *fifo_buffer_new (xine_stream_t *stream, int num_buffers, uint32_t buf_size)
-{
- fifo_buffer_t *ref = stream->video_fifo;
- fifo_buffer_t *this;
- int i;
- unsigned char *multi_buffer;
-
- LOGDBG("fifo_buffer_new...");
- this = calloc(1, sizeof (fifo_buffer_t));
-
- this->first = NULL;
- this->last = NULL;
- this->fifo_size = 0;
- this->put = ref->put;
- this->insert = ref->insert;
- this->get = ref->get;
- this->clear = ref->clear;
- this->size = ref->size;
- this->num_free = ref->num_free;
- this->data_size = ref->data_size;
- this->dispose = ref->dispose;
- this->register_alloc_cb = ref->register_alloc_cb;
- this->register_get_cb = ref->register_get_cb;
- this->register_put_cb = ref->register_put_cb;
- this->unregister_alloc_cb = ref->unregister_alloc_cb;
- this->unregister_get_cb = ref->unregister_get_cb;
- this->unregister_put_cb = ref->unregister_put_cb;
- pthread_mutex_init (&this->mutex, NULL);
- pthread_cond_init (&this->not_empty, NULL);
-
- /*
- * init buffer pool, allocate nNumBuffers of buf_size bytes each
- */
-
- multi_buffer = this->buffer_pool_base = av_mallocz (num_buffers * buf_size);
-
- pthread_mutex_init (&this->buffer_pool_mutex, NULL);
- pthread_cond_init (&this->buffer_pool_cond_not_empty, NULL);
-
- this->buffer_pool_capacity = num_buffers;
- this->buffer_pool_buf_size = buf_size;
- this->buffer_pool_alloc = ref->buffer_pool_alloc;
- this->buffer_pool_try_alloc = ref->buffer_pool_try_alloc;
-
- for (i = 0; i<num_buffers; i++) {
- buf_element_t *buf;
-
- buf = calloc(1, sizeof (buf_element_t));
-
- buf->mem = multi_buffer;
- multi_buffer += buf_size;
-
- buf->max_size = buf_size;
- buf->free_buffer = buffer_pool_free;
- buf->source = this;
- buf->extra_info = malloc(sizeof(extra_info_t));
-
- buffer_pool_free (buf);
- }
-
- LOGDBG("fifo_buffer_new done.");
- return this;
-}
-#endif
-
-static void flush_all_fifos (vdr_input_plugin_t *this, int full)
-{
- if (this->read_buffer) {
- this->read_buffer->free_buffer(this->read_buffer);
- this->read_buffer = NULL;
- }
-
- if (this->udp_data) {
- int i;
- for (i = 0; i <= UDP_SEQ_MASK; i++)
- if (this->udp_data->queue[i]) {
- this->udp_data->queue[i]->free_buffer(this->udp_data->queue[i]);
- this->udp_data->queue[i] = NULL;
- }
- }
-
- if (full) {
- if (this->stream && this->stream->audio_fifo)
- this->stream->audio_fifo->clear(this->stream->audio_fifo);
- if (this->stream && this->stream->video_fifo)
- this->stream->video_fifo->clear(this->stream->video_fifo);
- }
-
- if (this->iframe_buffer)
- this->iframe_buffer->clear(this->iframe_buffer);
- if (this->block_buffer)
- this->block_buffer->clear(this->block_buffer);
- if (this->hd_buffer)
- this->hd_buffer->clear(this->hd_buffer);
-}
-
-static buf_element_t *get_buf_element(vdr_input_plugin_t *this, int size, int force)
-{
- buf_element_t *buf = NULL;
-
- /* HD buffer */
- if (this->hd_stream && size <= HD_BUF_ELEM_SIZE) {
- buf = this->hd_buffer->buffer_pool_try_alloc(this->hd_buffer);
- if (!force && !buf)
- return NULL;
- }
-
- /* limit max. buffered data */
- if(!force && !buf) {
- int buffer_limit = this->buffer_pool->buffer_pool_capacity - this->max_buffers;
- if (this->buffer_pool->buffer_pool_num_free < buffer_limit)
- return NULL;
- }
-
- /* get smallest possible buffer */
- if(!buf) {
- if(size < 8000)
- buf = this->buffer_pool->buffer_pool_try_alloc(this->buffer_pool);
- else if(size < 0xffff) {
- buf = this->block_buffer->buffer_pool_try_alloc(this->block_buffer);
- LOGDBG("get_buf_element: big PES (%d bytes) !", size);
- }
- else { /* len>64k */
- LOGDBG("get_buf_element: jumbo PES (%d bytes) !", size);
- }
- }
-
- /* final try from audio fifo */
- if(!buf)
- buf = this->stream->audio_fifo->buffer_pool_try_alloc(this->stream->audio_fifo);
-
- if(buf) {
- buf->content = buf->mem;
- buf->size = 0;
- buf->type = BUF_DEMUX_BLOCK;
- buf->pts = 0;
-
- buf->free_buffer = buffer_pool_free;
- }
-
- return buf;
-}
-
-static buf_element_t *get_buf_element_timed(vdr_input_plugin_t *this, int size, int timeout)
-{
- buf_element_t *buf = get_buf_element (this, size, 0);
- if (!buf) {
- int result = 0;
- fifo_buffer_t *fifo = this->hd_stream ? this->hd_buffer : this->buffer_pool;
- struct timespec abstime;
- create_timeout_time (&abstime, timeout);
-
- do {
- mutex_lock_cancellable (&fifo->buffer_pool_mutex);
- result = pthread_cond_timedwait (&fifo->buffer_pool_cond_not_empty, &fifo->buffer_pool_mutex, &abstime);
- mutex_unlock_cancellable (&fifo->buffer_pool_mutex);
- buf = get_buf_element (this, size, 0);
- } while (!buf && !result);
- }
- return buf;
-}
-
-static void strip_network_headers(vdr_input_plugin_t *this, buf_element_t *buf)
-{
- if (buf->type == BUF_NETWORK_BLOCK) {
- if (this->udp || this->rtp) {
- stream_udp_header_t *header = (stream_udp_header_t *)buf->content;
- this->curpos = header->pos;
- buf->content += sizeof(stream_udp_header_t);
- buf->size -= sizeof(stream_udp_header_t);
- } else {
- stream_tcp_header_t *header = (stream_tcp_header_t *)buf->content;
- this->curpos = header->pos;
- buf->content += sizeof(stream_tcp_header_t);
- buf->size -= sizeof(stream_tcp_header_t);
- }
- buf->type = BUF_DEMUX_BLOCK;
- }
-}
-
-static void put_control_buf(fifo_buffer_t *buffer, fifo_buffer_t *pool, int cmd)
-{
- buf_element_t *buf = pool->buffer_pool_try_alloc(pool);
- if(buf) {
- buf->type = cmd;
- buffer->put(buffer, buf);
- }
-}
-
-static void queue_blank_yv12(vdr_input_plugin_t *this)
-{
- int ratio = _x_stream_info_get(this->stream, XINE_STREAM_INFO_VIDEO_RATIO);
- double dratio;
-
- if(!this || !this->stream)
- return;
-
- if(ratio > 13300 && ratio < 13400) dratio = 4.0/3.0;
- else if(ratio > 17700 && ratio < 17800) dratio = 16.0/9.0;
- else if(ratio > 21000 && ratio < 22000) dratio = 2.11/1.0;
- else dratio = ((double)ratio)/10000.0;
-
- if(this->stream && this->stream->video_out) {
-
- vo_frame_t *img = NULL;
- int width = _x_stream_info_get(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH);
- int height = _x_stream_info_get(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT);
-
- if (width >= 360 && height >= 288 && width <= 1920 && height <= 1200) {
- this->class->xine->port_ticket->acquire(this->class->xine->port_ticket, 1);
- img = this->stream->video_out->get_frame (this->stream->video_out,
- width, height,
- dratio, XINE_IMGFMT_YV12,
- VO_BOTH_FIELDS);
- this->class->xine->port_ticket->release(this->class->xine->port_ticket, 1);
- } else {
- LOGMSG("queue_blank_yv12: invalid dimensions %dx%d in stream_info !", width, height);
- }
-
- if(img) {
- if(img->format == XINE_IMGFMT_YV12 && img->base[0] && img->base[1] && img->base[2]) {
- if(img->pitches[0] < width)
- width = img->pitches[0];
- if(img->width < width)
- width = img->width;
- if(img->height < height)
- height = img->height;
- memset( img->base[0], 0x00, width * height);
- memset( img->base[1], 0x80, width * height / 4 );
- memset( img->base[2], 0x80, width * height / 4 );
- img->duration = 3600;
- img->pts = 3600;
- img->bad_frame = 0;
- img->draw(img, this->stream);
- }
- img->free(img);
- }
- }
-
- this->still_mode = 0;
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HAS_STILL, this->still_mode);
-}
-
-static void queue_nosignal(vdr_input_plugin_t *this)
-{
-#define extern static
-#include "nosignal_720x576.c"
-#undef extern
- char *data = NULL, *tmp = NULL;
- int datalen = 0, pos = 0;
- buf_element_t *buf = NULL;
- char *path, *home;
-
- if(this->stream->video_fifo->num_free(this->stream->video_fifo) < 10) {
- LOGMSG("queue_nosignal: not enough free buffers (%d) !",
- this->stream->video_fifo->num_free(this->stream->video_fifo));
- return;
- }
-
- if(asprintf(&home,"%s/.xine/nosignal.mpg", xine_get_homedir()) < 0)
- return;
- int fd = open(path=home, O_RDONLY);
- if(fd<0) fd = open(path="/etc/vdr/plugins/xineliboutput/nosignal.mpg", O_RDONLY);
- if(fd<0) fd = open(path="/etc/vdr/plugins/xine/noSignal.mpg", O_RDONLY);
- if(fd<0) fd = open(path="/video/plugins/xineliboutput/nosignal.mpg", O_RDONLY);
- if(fd<0) fd = open(path="/video/plugins/xine/noSignal.mpg", O_RDONLY);
- if(fd<0) fd = open(path=NOSIGNAL_IMAGE_FILE, O_RDONLY);
- if(fd>=0) {
- tmp = data = malloc(NOSIGNAL_MAX_SIZE);
- datalen = read(fd, data, NOSIGNAL_MAX_SIZE);
- if(datalen==NOSIGNAL_MAX_SIZE) {
- LOGMSG("WARNING: custom \"no signal\" image %s too large", path);
- } else if(datalen<=0) {
- LOGERR("error reading %s", path);
- } else {
- LOGMSG("using custom \"no signal\" image %s", path);
- }
- close(fd);
- }
- free(home);
-
- if(datalen<=0) {
- data = (char*)&v_mpg_nosignal[0];
- datalen = v_mpg_nosignal_length;
- }
-
- /* need to reset decoder if video format is not the same */
- _x_demux_control_start(this->stream);
-
- while(pos < datalen) {
- buf = this->stream->video_fifo->buffer_pool_try_alloc(this->stream->video_fifo);
- if(buf) {
- buf->content = buf->mem;
- buf->size = MIN(datalen - pos, buf->max_size);
- buf->type = BUF_VIDEO_MPEG;
- xine_fast_memcpy(buf->content, &data[pos], buf->size);
- pos += buf->size;
- if(pos >= datalen)
- buf->decoder_flags |= BUF_FLAG_FRAME_END;
- this->stream->video_fifo->put(this->stream->video_fifo, buf);
- } else {
- LOGMSG("Error: queue_nosignal: no buffers !");
- break;
- }
- }
-
- put_control_buf(this->stream->video_fifo, this->stream->video_fifo, BUF_CONTROL_FLUSH_DECODER);
- put_control_buf(this->stream->video_fifo, this->stream->video_fifo, BUF_CONTROL_NOP);
-
- free(tmp);
-}
-
-
-/*************************** slave input (PIP stream) ********************/
-
-typedef struct fifo_input_plugin_s {
- input_plugin_t i;
- vdr_input_plugin_t *master;
- xine_stream_t *stream;
- fifo_buffer_t *buffer;
- fifo_buffer_t *buffer_pool;
- off_t pos;
-} fifo_input_plugin_t;
-
-static int fifo_open(input_plugin_t *this_gen)
-{ return 1; }
-static uint32_t fifo_get_capabilities (input_plugin_t *this_gen)
-{ return INPUT_CAP_BLOCK; }
-static uint32_t fifo_get_blocksize (input_plugin_t *this_gen)
-{ return 2 * 2048; }
-static off_t fifo_get_current_pos (input_plugin_t *this_gen)
-{ return -1; }
-static off_t fifo_get_length (input_plugin_t *this_gen)
-{ return -1; }
-static off_t fifo_seek (input_plugin_t *this_gen, off_t offset, int origin)
-{ return offset; }
-static int fifo_get_optional_data (input_plugin_t *this_gen, void *data, int data_type)
-{ return INPUT_OPTIONAL_UNSUPPORTED; }
-#if XINE_VERSION_CODE > 10103
-static const char* fifo_get_mrl (input_plugin_t *this_gen)
-#else
-static char* fifo_get_mrl (input_plugin_t *this_gen)
-#endif
-{ return MRL_ID "+slave:"; }
-
-#if XINE_VERSION_CODE < 10190
-static off_t fifo_read (input_plugin_t *this_gen, char *buf, off_t len)
-#else
-static off_t fifo_read (input_plugin_t *this_gen, void *buf, off_t len)
-#endif
-{
- int got = 0;
- LOGERR("fifo_input_plugin::fifo_read() not implemented !");
- exit(-1); /* assert(false); */
- return got;
-}
-
-static buf_element_t *fifo_read_block (input_plugin_t *this_gen,
- fifo_buffer_t *fifo, off_t todo)
-{
- fifo_input_plugin_t *this = (fifo_input_plugin_t *) this_gen;
- /*LOGDBG("fifo_read_block");*/
-
- while(!this->stream->demux_action_pending) {
- buf_element_t *buf = fifo_buffer_try_get(this->buffer);
- if(buf) {
- /* LOGDBG("fifo_read_block: got, return"); */
- return buf;
- }
- /* LOGDBG("fifo_read_block: no buf, poll..."); */
- /* poll(NULL, 0, 10); */
- xine_usec_sleep(5*1000);
- /* LOGDBG("fifo_read_block: poll timeout"); */
- }
-
- LOGDBG("fifo_read_block: return NULL !");
- errno = EAGAIN;
- return NULL;
-}
-
-static void fifo_dispose (input_plugin_t *this_gen)
-{
- fifo_input_plugin_t *this = (fifo_input_plugin_t *) this_gen;
- LOGDBG("fifo_dispose");
-
- if(this) {
- if(this->buffer)
- this->buffer->dispose(this->buffer);
- free(this);
- }
-}
-
-static input_plugin_t *fifo_class_get_instance (input_class_t *class_gen,
- xine_stream_t *stream,
- const char *data)
-{
- fifo_input_plugin_t *slave = calloc(1, sizeof(fifo_input_plugin_t));
- unsigned long int imaster;
- vdr_input_plugin_t *master;
- LOGDBG("fifo_class_get_instance");
-
- sscanf(data+15, "%lx", &imaster);
- master = (vdr_input_plugin_t*)imaster;
-
- slave->master = (vdr_input_plugin_t*)master;
- slave->stream = stream;
- slave->buffer_pool = stream->video_fifo;
- slave->buffer = fifo_buffer_new(stream, 4, 4096);
- slave->i.open = fifo_open;
- slave->i.get_mrl = fifo_get_mrl;
- slave->i.dispose = fifo_dispose;
- slave->i.input_class = class_gen;
- slave->i.get_capabilities = fifo_get_capabilities;
- slave->i.read = fifo_read;
- slave->i.read_block = fifo_read_block;
- slave->i.seek = fifo_seek;
- slave->i.get_current_pos = fifo_get_current_pos;
- slave->i.get_length = fifo_get_length;
- slave->i.get_blocksize = fifo_get_blocksize;
- slave->i.get_optional_data = fifo_get_optional_data;
-
- return (input_plugin_t*)slave;
-}
-
-
-/******************************** OSD ************************************/
-
-static xine_rle_elem_t *uncompress_osd_net(uint8_t *raw, int elems, int datalen)
-{
- xine_rle_elem_t *data = (xine_rle_elem_t*)malloc(elems*sizeof(xine_rle_elem_t));
- int i;
-
- /*
- * xine-lib rle format:
- * - palette index and length are uint16_t
- *
- * network format:
- * - palette entry is uint8_t
- * - length is uint8_t for lengths <=0x7f and uint16_t for lengths >0x7f
- * - high-order bit of first byte is used to signal size of length field:
- * bit=0 -> 7-bit, bit=1 -> 15-bit
- */
-
- for(i=0; i<elems; i++) {
- if((*raw) & 0x80) {
- data[i].len = ((*(raw++)) & 0x7f) << 8;
- data[i].len |= *(raw++);
- } else
- data[i].len = *(raw++);
- data[i].color = *(raw++);
- }
-
- return data;
-}
-
-/*
- * vdr_plugin_exec_osd_command()
- *
- * - entry point for VDR-based osd_command_t events
- */
-static int vdr_plugin_exec_osd_command(vdr_input_plugin_if_t *this_if,
- osd_command_t *cmd)
-{
- vdr_input_plugin_t *this = (vdr_input_plugin_t *) this_if;
-
- if (this->fd_control >= 0 && /* remote mode */
- this->funcs.intercept_osd /* frontend handles OSD */ ) {
- return this->funcs.intercept_osd(this->funcs.fe_handle, cmd) ? CONTROL_OK : CONTROL_DISCONNECTED;
- }
-
- return this->osd_manager->command(this->osd_manager, cmd, this->slave_stream ?: this->stream);
-}
-
-
-/******************************* Control *********************************/
-
-#if XINE_VERSION_CODE < 10111
-# define DEMUX_MUTEX_LOCK
-# define DEMUX_MUTEX_UNLOCK
-# define DEMUX_RESUME_SIGNAL
-#else
-# define DEMUX_MUTEX_LOCK pthread_mutex_lock(&stream->demux_mutex)
-# define DEMUX_MUTEX_UNLOCK pthread_mutex_unlock(&stream->demux_mutex)
-# define DEMUX_RESUME_SIGNAL pthread_cond_signal(&this->stream->demux_resume)
-#endif
-
-static void suspend_demuxer(vdr_input_plugin_t *this)
-{
- this->stream->demux_action_pending = 1;
- signal_buffer_not_empty(this);
- if(this->is_paused)
- LOGMSG("WARNING: called suspend_demuxer in paused mode !");
- pthread_mutex_lock( &this->stream->demux_lock );
- this->stream->demux_action_pending = 0;
- /* must be paired with resume_demuxer !!! */
-}
-
-static void resume_demuxer(vdr_input_plugin_t *this)
-{
- /* must be paired with suspend_demuxer !!! */
- DEMUX_RESUME_SIGNAL;
- pthread_mutex_unlock( &this->stream->demux_lock );
-}
-
-static void vdr_x_demux_control_newpts( xine_stream_t *stream, int64_t pts,
- uint32_t flags )
-{
- buf_element_t *buf;
-
- DEMUX_MUTEX_LOCK;
-
- buf = stream->video_fifo ? stream->video_fifo->buffer_pool_try_alloc (stream->video_fifo) : NULL;
- if(buf) {
- buf->type = BUF_CONTROL_NEWPTS;
- buf->decoder_flags = flags;
- buf->disc_off = pts;
- stream->video_fifo->put (stream->video_fifo, buf);
- } else {
- LOGMSG("vdr_x_demux_control_newpts: video fifo full !");
- }
-
- buf = stream->audio_fifo ? stream->audio_fifo->buffer_pool_try_alloc (stream->audio_fifo) : NULL;
- if (buf) {
- buf->type = BUF_CONTROL_NEWPTS;
- buf->decoder_flags = flags;
- buf->disc_off = pts;
- stream->audio_fifo->put (stream->audio_fifo, buf);
- } else {
- LOGMSG("vdr_x_demux_control_newpts: audio fifo full !");
- }
-
- DEMUX_MUTEX_UNLOCK;
-}
-
-static void vdr_flush_engine(vdr_input_plugin_t *this, uint64_t discard_index)
-{
- if(this->stream_start) {
- LOGMSG("vdr_flush_engine: stream_start, flush skipped");
- return;
- }
-
- if(this->curpos > discard_index) {
- if(this->curpos < this->guard_index) {
- LOGMSG("vdr_flush_engine: guard > curpos, flush skipped");
- return;
- }
- LOGMSG("vdr_flush_engine: %"PRIu64" < current position %"PRIu64", flush skipped",
- discard_index, this->curpos);
- return;
- }
-
- /* reset speed */
- if(xine_get_param(this->stream, XINE_PARAM_FINE_SPEED) <= 0) {
- LOGMSG("vdr_flush_engine: playback is paused <0>");
- xine_set_param(this->stream, XINE_PARAM_FINE_SPEED, XINE_FINE_SPEED_NORMAL);
- }
-
- /* suspend demuxer */
- this->stream->demux_action_pending = 1;
- pthread_cond_broadcast(&this->engine_flushed);
- if(pthread_mutex_unlock( &this->lock )) /* to let demuxer return from vdr_plugin_read_* */
- LOGERR("pthread_mutex_unlock failed !");
- suspend_demuxer(this);
- pthread_mutex_lock( &this->lock );
-
- reset_scr_tuning(this, this->speed_before_pause);
-
- /* reset speed again (adjust_realtime_speed might have set pause) */
- if(xine_get_param(this->stream, XINE_PARAM_FINE_SPEED) <= 0) {
- LOGMSG("vdr_flush_engine: playback is paused <1>");
- xine_set_param(this->stream, XINE_PARAM_FINE_SPEED, XINE_FINE_SPEED_NORMAL);
- }
-
-#if 0
- _x_demux_flush_engine (this->stream);
- /* warning: after clearing decoders fifos an absolute discontinuity
- * indication must be sent. relative discontinuities are likely
- * to cause "jumps" on metronom.
- */
-#else
- this->stream->demux_plugin->seek (this->stream->demux_plugin,
- 0, 0, this->stream->demux_thread_running);
-#endif
-
-#if XINE_VERSION_CODE < 10104
- /* disabled _x_demux_control_start as it causes alsa output driver to exit now and then ... */
-#else
- _x_demux_control_start(this->stream);
-#endif
- this->stream_start = 1;
- this->I_frames = this->B_frames = this->P_frames = 0;
- this->discard_index = discard_index;
-
- resume_demuxer(this);
-}
-
-static int set_deinterlace_method(vdr_input_plugin_t *this, const char *method_name)
-{
- int method = 0;
- if(!strncasecmp(method_name,"bob",3)) { method = 1;
- } else if(!strncasecmp(method_name,"weave",5)) { method = 2;
- } else if(!strncasecmp(method_name,"greedy",6)) { method = 3;
- } else if(!strncasecmp(method_name,"onefield",8)) { method = 4;
- } else if(!strncasecmp(method_name,"onefield_xv",11)) { method = 5;
- } else if(!strncasecmp(method_name,"linearblend",11)) { method = 6;
- } else if(!strncasecmp(method_name,"none",4)) { method = 0;
- } else if(!*method_name) { method = 0;
- } else if(!strncasecmp(method_name,"tvtime",6)) { method = -1;
- /* old deinterlacing system must be switched off.
- tvtime will be configured as all other post plugins with
- "POST tvtime ..." control message */
- } else return -2;
-
- this->class->xine->config->update_num(this->class->xine->config,
- "video.output.xv_deinterlace_method",
- method >= 0 ? method : 0);
- xine_set_param(this->stream, XINE_PARAM_VO_DEINTERLACE, method ? 1 : 0);
-
- return 0;
-}
-
-static int set_video_properties(vdr_input_plugin_t *this,
- int hue, int saturation,
- int brightness, int sharpness,
- int noise_reduction, int contrast,
- int vo_aspect_ratio)
-{
- pthread_mutex_lock(&this->lock);
-
- /* when changed first time, save original/default values */
- if(!this->video_properties_saved &&
- (hue>=0 || saturation>=0 || contrast>=0 || brightness>=0 ||
- sharpness>=0 || noise_reduction>=0 || vo_aspect_ratio>=0)) {
- this->video_properties_saved = 1;
- this->orig_hue = xine_get_param(this->stream,
- XINE_PARAM_VO_HUE );
- this->orig_saturation = xine_get_param(this->stream,
- XINE_PARAM_VO_SATURATION );
- this->orig_brightness = xine_get_param(this->stream,
- XINE_PARAM_VO_BRIGHTNESS );
-#ifdef XINE_PARAM_VO_SHARPNESS
- this->orig_sharpness = xine_get_param(this->stream,
- XINE_PARAM_VO_SHARPNESS );
-#endif
-#ifdef XINE_PARAM_VO_NOISE_REDUCTION
- this->orig_noise_reduction = xine_get_param(this->stream,
- XINE_PARAM_VO_NOISE_REDUCTION );
-#endif
- this->orig_contrast = xine_get_param(this->stream,
- XINE_PARAM_VO_CONTRAST );
- this->orig_vo_aspect_ratio = xine_get_param(this->stream,
- XINE_PARAM_VO_ASPECT_RATIO );
- }
-
- /* set new values, or restore default/original values */
- if(hue>=0 || this->video_properties_saved)
- xine_set_param(this->stream, XINE_PARAM_VO_HUE,
- hue>=0 ? hue : this->orig_hue );
- if(saturation>=0 || this->video_properties_saved)
- xine_set_param(this->stream, XINE_PARAM_VO_SATURATION,
- saturation>0 ? saturation : this->orig_saturation );
- if(brightness>=0 || this->video_properties_saved)
- xine_set_param(this->stream, XINE_PARAM_VO_BRIGHTNESS,
- brightness>=0 ? brightness : this->orig_brightness );
-#ifdef XINE_PARAM_VO_SHARPNESS
- if(sharpness>=0 || this->video_properties_saved)
- xine_set_param(this->stream, XINE_PARAM_VO_SHARPNESS,
- sharpness>=0 ? sharpness : this->orig_sharpness );
-#endif
-#ifdef XINE_PARAM_VO_NOISE_REDUCTION
- if(noise_reduction>=0 || this->video_properties_saved)
- xine_set_param(this->stream, XINE_PARAM_VO_NOISE_REDUCTION,
- noise_reduction>=0 ? noise_reduction : this->orig_noise_reduction );
-#endif
- if(contrast>=0 || this->video_properties_saved)
- xine_set_param(this->stream, XINE_PARAM_VO_CONTRAST,
- contrast>=0 ? contrast : this->orig_contrast );
- if(vo_aspect_ratio>=0 || this->video_properties_saved)
- xine_set_param(this->stream, XINE_PARAM_VO_ASPECT_RATIO,
- vo_aspect_ratio>=0 ? vo_aspect_ratio : this->orig_vo_aspect_ratio );
-
- if(hue<0 && saturation<0 && contrast<0 && brightness<0 && sharpness<0 && noise_reduction<0 && vo_aspect_ratio<0)
- this->video_properties_saved = 0;
-
- pthread_mutex_unlock(&this->lock);
- return 0;
-}
-
-static int set_live_mode(vdr_input_plugin_t *this, int onoff)
-{
- pthread_mutex_lock(&this->lock);
-
- if(this->live_mode != onoff) {
- config_values_t *config = this->class->xine->config;
- this->live_mode = onoff;
-
- this->stream->metronom->set_option(this->stream->metronom,
- METRONOM_PREBUFFER, METRONOM_PREBUFFER_VAL);
-
- if(this->live_mode || (this->fd_control >= 0 && !this->slave_stream))
- config->update_num(config, "audio.synchronization.av_sync_method", 1);
-#if 0
- /* does not work after playing music files (?) */
- else
- config->update_num(config, "audio.synchronization.av_sync_method", 0);
-#endif
-
- }
-
- /* set buffer usage limits */
- this->max_buffers = this->buffer_pool->buffer_pool_capacity;
- if(this->live_mode && this->fd_control < 0)
- this->max_buffers >>= 1;
- this->max_buffers -= 10;
-
- if(this->no_video)
- this->max_buffers = RADIO_MAX_BUFFERS;
-
- /* SCR tuning */
- if(this->live_mode) {
-#ifndef TEST_SCR_PAUSE
- LOGSCR("pause scr tuning by set_live_mode");
- scr_tuning_set_paused(this);
-#endif
- } else {
- LOGSCR("reset scr tuning by set_live_mode");
- reset_scr_tuning(this, this->speed_before_pause=XINE_FINE_SPEED_NORMAL);
- }
-
- this->still_mode = 0;
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HAS_STILL, this->still_mode);
-
- pthread_mutex_unlock(&this->lock);
-
- signal_buffer_pool_not_empty(this);
- return 0;
-}
-
-static int set_playback_speed(vdr_input_plugin_t *this, int speed)
-{
-/* speed:
- <0 - show each abs(n)'th frame (drop other frames)
- * no audio
- 0 - paused
- * audio back if mute != 0
- >0 - show each frame n times
- * no audio
- 1 - normal
-*/
- pthread_mutex_lock(&this->lock);
- this->is_paused = 0;
- if(speed == 0) {
- this->is_paused = 1;
- } else if(speed>64 || speed<-64) {
- pthread_mutex_unlock(&this->lock);
- return -2;
- }
-
- if(speed > 1 || speed < -1) {
- reset_scr_tuning(this, -1);
- this->is_trickspeed = 1;
- } else {
- this->is_trickspeed = 0;
- }
-
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HAS_STILL, this->still_mode || speed==0);
-
- if(speed>0)
- speed = this->speed_before_pause = XINE_FINE_SPEED_NORMAL/speed;
- else
- speed = this->speed_before_pause = XINE_FINE_SPEED_NORMAL*(-speed);
-
- if(this->scr_tuning != SCR_TUNING_PAUSED &&
- _x_get_fine_speed(this->stream) != speed) {
- _x_set_fine_speed (this->stream, speed);
- }
-
- if(this->slave_stream)
- _x_set_fine_speed (this->slave_stream, speed);
-
- pthread_mutex_unlock(&this->lock);
- return 0;
-}
-
-static void send_meta_info(vdr_input_plugin_t *this)
-{
- if(this->slave_stream) {
-
- /* send stream meta info */
- char *meta = NULL;
- char *title = (char *)xine_get_meta_info(this->slave_stream, XINE_META_INFO_TITLE);
- char *artist = (char *)xine_get_meta_info(this->slave_stream, XINE_META_INFO_ARTIST);
- char *album = (char *)xine_get_meta_info(this->slave_stream, XINE_META_INFO_ALBUM);
- char *tracknumber = (char *)xine_get_meta_info(this->slave_stream, XINE_META_INFO_TRACK_NUMBER);
-
- if(asprintf(&meta,
- "INFO METAINFO title=@%s@ artist=@%s@ album=@%s@ tracknumber=@%s@\r\n",
- title?:"", artist?:"", album?:"", tracknumber?:"") < 0)
- return;
-
- if(this->fd_control < 0)
- this->funcs.xine_input_event(meta, NULL);
- else
- write_control(this, meta);
-
- free(meta);
- }
-}
-
-#ifdef DVD_STREAMING_SPEED
-static void dvd_set_speed(const char *device, int speed)
-{
- /*
- * Original idea & code from mplayer-dev-eng mailing list:
- * Date: Sun, 17 Dec 2006 09:15:30 +0100
- * From: Tobias Diedrich <ranma@xxxxxxxxxxxx>
- * Subject: [MPlayer-dev-eng] Re: [PATCH] Add "-dvd-speed", use SET_STREAMING command to quieten DVD drives
- * (http://lists-archives.org/mplayer-dev-eng/14383-add-dvd-speed-use-set_streaming-command-to-quieten-dvd-drives.html)
- */
-#if defined(__linux__) && defined(SG_IO) && defined(GPCMD_SET_STREAMING)
- unsigned char buffer[28], cmd[16], sense[16];
- struct sg_io_hdr sghdr;
- struct stat st;
- int fd;
-
- /* remember previous device so we can restore default speed */
- static int dvd_speed = 0;
- static const char *dvd_dev = NULL;
- if (speed < 0 && dvd_speed == 0) return; /* we haven't touched the speed setting */
- if (!device) device = dvd_dev; /* use previous device */
- if (!device) return;
- if (!speed) return;
-
- if (stat(device, &st) == -1) return;
-
- if (!S_ISBLK(st.st_mode)) return; /* not a block device */
-
- if ((fd = open(device, O_RDWR | O_NONBLOCK)) == -1) {
- LOGMSG("set_dvd_speed: error opening DVD device %s for read/write", device);
- return;
- }
-
- memset(&sghdr, 0, sizeof(sghdr));
- memset(buffer, 0, sizeof(buffer));
- memset(sense, 0, sizeof(sense));
- memset(cmd, 0, sizeof(cmd));
-
- if(speed < 0) {
- /* restore default value */
- speed = 0;
- buffer[0] = 4; /* restore default */
- LOGMSG("Setting DVD streaming speed to <default>");
- } else {
- /* limit to <speed> KB/s */
- LOGMSG("Setting DVD streaming speed to %d", speed);
- }
-
- sghdr.interface_id = 'S';
- sghdr.timeout = 5000;
- sghdr.dxfer_direction = SG_DXFER_TO_DEV;
- sghdr.mx_sb_len = sizeof(sense);
- sghdr.dxfer_len = sizeof(buffer);
- sghdr.cmd_len = sizeof(cmd);
- sghdr.sbp = sense;
- sghdr.dxferp = buffer;
- sghdr.cmdp = cmd;
-
- cmd[0] = GPCMD_SET_STREAMING;
- cmd[10] = 28;
-
- buffer[8] = 0xff;
- buffer[9] = 0xff;
- buffer[10] = 0xff;
- buffer[11] = 0xff;
-
- buffer[12] = buffer[20] = (speed >> 24) & 0xff; /* <speed> kilobyte */
- buffer[13] = buffer[21] = (speed >> 16) & 0xff;
- buffer[14] = buffer[22] = (speed >> 8) & 0xff;
- buffer[15] = buffer[23] = speed & 0xff;
-
- buffer[18] = buffer[26] = 0x03; /* 1 second */
- buffer[19] = buffer[27] = 0xe8;
-
- if (ioctl(fd, SG_IO, &sghdr) < 0)
- LOGERR("Failed setting DVD streaming speed to %d", speed);
- else if(speed > 0)
- LOGMSG("DVD streaming speed set to %d", speed);
- else
- LOGMSG("DVD streaming speed set to <default>");
-
- dvd_speed = speed;
- dvd_dev = device;
- close(fd);
-#else
-# warning Changing DVD streaming speed not supported
-#endif
-}
-#endif
-
-static void vdr_event_cb (void *user_data, const xine_event_t *event);
-
-static void select_spu_channel(xine_stream_t *stream, int channel)
-{
- _x_select_spu_channel(stream, channel);
- if (channel == SPU_CHANNEL_NONE) {
- /* re-enable overlay for VDR OSD ... */
- if (stream->video_out) {
- pthread_mutex_lock (&stream->frontend_lock);
- stream->xine->port_ticket->acquire (stream->xine->port_ticket, 0);
-
- stream->video_out->enable_ovl (stream->video_out, 1);
-
- stream->xine->port_ticket->release (stream->xine->port_ticket, 0);
- pthread_mutex_unlock (&stream->frontend_lock);
- }
- }
-}
-
-static void dvd_menu_domain(vdr_input_plugin_t *this, int value)
-{
- if (value) {
- LOGDBG("dvd_menu_domain(1)");
- this->dvd_menu = 1;
- this->slave_stream->spu_channel_user = SPU_CHANNEL_AUTO;
- this->slave_stream->spu_channel = this->slave_stream->spu_channel_auto;
- } else {
- LOGDBG("dvd_menu_domain(0)");
- this->dvd_menu = 0;
- }
-}
-
-static int handle_control_playfile(vdr_input_plugin_t *this, const char *cmd)
-{
- const char *pt = cmd + 9;
- char filename[4096], av[256], *pav = av;
- int loop = 0, pos = 0, err = 0, avsize = sizeof(av)-2, mix_streams = 0;
-
- while(*pt==' ') pt++;
-
- if(!strncmp(pt, "Loop ", 5)) {
- loop = 1;
- pt += 5;
- while(*pt==' ') pt++;
- }
-
- pos = atoi(pt);
-
- while(*pt && *pt != ' ') pt++;
- while(*pt == ' ') pt++;
-
- /* audio visualization / audio/video mixing */
- while(*pt && *pt != ' ' && --avsize)
- *pav++ = *pt++;
- *pav = 0;
- while(*pt == ' ') pt++;
- mix_streams = (!strcmp(av, "Audio")) || (!strcmp(av, "Video"));
-
- strn0cpy(filename, pt, sizeof(filename));
-
- this->autoplay_size = -1;
-
- if(*filename) {
- int is_file_mrl = !strncmp(filename, "file:/", 6) ? 5 : 0;
- this->loop_play = 0;
-
- if(this->slave_stream)
- handle_control_playfile(this, "PLAYFILE 0");
-
- LOGMSG("PLAYFILE (Loop: %d, Offset: %ds, File: %s %s)",
- loop, pos, av, filename);
-
- /* check if it is really a file (not mrl) and try to access it */
- if(is_file_mrl || filename[0] == '/') {
- struct stat st;
- char *f = unescape_filename(filename);
- errno = 0;
- if(stat(f+is_file_mrl, &st)) {
- if(errno == EACCES || errno == ELOOP)
- LOGERR("Can't access file !");
- if(errno == ENOENT || errno == ENOTDIR)
- LOGERR("File not found !");
- if(this->fd_control >= 0) {
- char mrl[sizeof(filename)+256], mrlbase[256];
- char *host = strdup(strstr(this->mrl, "//")+2);
- char *port = strchr(host, ':');
- char *sub = strstr(filename, "#subtitle:");
- int iport = port ? atoi(port+1) : DEFAULT_VDR_PORT;
- if(port) *port = 0;
- if(sub) *sub = 0;
- snprintf(mrlbase, sizeof(mrlbase), "http://%s:%d/PLAYFILE",
- host?:"127.0.0.1", iport);
- sprintf(mrl, "%s%s", mrlbase, filename + is_file_mrl);
- if(sub) {
- sub += 10; /*strlen("#subtitle:");*/
- strcat(mrl, "#subtitle:");
- strcat(mrl, mrlbase);
- strcat(mrl, sub);
- }
- free(host);
- LOGMSG(" -> trying to stream from server (%s) ...", mrl);
- strn0cpy(filename, mrl, sizeof(filename));
- }
- }
- free(f);
- }
-
- if(!strcmp(filename,"dvd:/")) {
-#if 0
- /* input/media_helper.c */
- eject_media(0); /* DVD tray in */
-#endif
-#ifdef DVD_STREAMING_SPEED
- xine_cfg_entry_t device;
- if (xine_config_lookup_entry(this->class->xine,
- "media.dvd.device", &device))
- dvd_set_speed(device.str_value, 2700);
-#endif
- }
-#if XINE_VERSION_CODE < 10109
- else if(!strncmp(filename,"dvd:/", 5)) {
- /* DVD plugin 'bug': unescaping is not implemented ... */
- char *mrl = unescape_filename(filename);
- strn0cpy(filename, mrl, sizeof(filename));
- free(mrl);
- }
-#endif
-
- if(!this->slave_stream) {
- this->slave_stream = xine_stream_new(this->class->xine,
- this->stream->audio_out,
- this->stream->video_out);
- }
-
- if(!this->slave_event_queue) {
- this->slave_event_queue = xine_event_new_queue (this->slave_stream);
- xine_event_create_listener_thread (this->slave_event_queue,
- vdr_event_cb, this);
- }
- select_spu_channel(this->slave_stream, SPU_CHANNEL_AUTO);
- this->dvd_menu = 0;
-
- errno = 0;
- err = !xine_open(this->slave_stream, filename);
- if(err) {
- LOGERR("Error opening file ! (File not found ? Unknown format ?)");
- *filename = 0; /* this triggers stop */
- } else {
-#if 1
- if(this->stream->video_fifo->size(this->stream->video_fifo))
- LOGMSG("playfile: main stream video_fifo not empty ! (%d)",
- this->stream->video_fifo->size(this->stream->video_fifo));
-
- /* flush decoders and output fifos, close decoders and free frames. */
- _x_demux_control_start(this->stream);
- xine_usec_sleep(50*1000);
-
- /* keep our own demux happy while playing another stream */
- set_playback_speed(this, 1);
- this->live_mode = 1;
- set_live_mode(this, 0);
- set_playback_speed(this, 1);
- reset_scr_tuning(this, this->speed_before_pause = XINE_FINE_SPEED_NORMAL);
- this->slave_stream->metronom->set_option(this->slave_stream->metronom,
- METRONOM_PREBUFFER, 90000);
-#endif
-
- this->loop_play = loop;
- err = !xine_play(this->slave_stream, 0, 1000 * pos);
- if(err) {
- LOGMSG("Error playing file");
- *filename = 0; /* this triggers stop */
- } else {
- send_meta_info(this);
-
- if(this->funcs.fe_control) {
- char tmp[128];
- int has_video;
- sprintf(tmp, "SLAVE 0x%lx %s\r\n",
- (unsigned long int)this->slave_stream,
- mix_streams ? av : "");
- this->funcs.fe_control(this->funcs.fe_handle, tmp);
- has_video = _x_stream_info_get(this->slave_stream, XINE_STREAM_INFO_HAS_VIDEO);
- this->funcs.fe_control(this->funcs.fe_handle,
- has_video ? "NOVIDEO 1\r\n" : "NOVIDEO 0\r\n");
- if(!has_video && !mix_streams && *av && strcmp(av, "none")) {
- char str[128], *avopts;
- if(NULL != (avopts = strchr(av, ':')))
- *avopts++ = 0;
- else
- avopts = "";
- snprintf(str, sizeof(str), "POST %s On %s\r\n", av, avopts);
- str[sizeof(str)-1] = 0;
- this->funcs.fe_control(this->funcs.fe_handle, str);
- } else {
- this->funcs.fe_control(this->funcs.fe_handle, "POST 0 Off\r\n");
- }
- }
- }
- }
- }
-
- /* next code is also executed after failed open, so no "} else { " */
- if(!*filename) {
- LOGMSG("PLAYFILE <STOP>: Closing slave stream");
- this->loop_play = 0;
- if(this->slave_stream) {
- xine_stop(this->slave_stream);
-
- if (this->slave_event_queue) {
- xine_event_dispose_queue (this->slave_event_queue);
- this->slave_event_queue = NULL;
- }
-
- if(this->funcs.fe_control) {
- this->funcs.fe_control(this->funcs.fe_handle, "POST 0 Off\r\n");
- this->funcs.fe_control(this->funcs.fe_handle, "SLAVE 0x0\r\n");
- }
- xine_close(this->slave_stream);
- xine_dispose(this->slave_stream);
- this->slave_stream = NULL;
-
- if(this->funcs.fe_control)
- this->funcs.fe_control(this->funcs.fe_handle, "SLAVE CLOSED\r\n");
-
- _x_demux_control_start(this->stream);
-
-#ifdef DVD_STREAMING_SPEED
- dvd_set_speed(NULL, -1);
-#endif
- }
- }
-
- return err ? CONTROL_PARAM_ERROR : CONTROL_OK;
-}
-
-static int handle_control_grab(vdr_input_plugin_t *this, const char *cmd)
-{
- int quality, width, height, jpeg;
- jpeg = !strcmp(cmd+5,"JPEG");
-
- if(3 == sscanf(cmd+5+4, "%d %d %d", &quality, &width, &height)) {
-
- if(this->fd_control >= 0) {
-
- grab_data_t *data = NULL;
- LOGDBG("GRAB: jpeg=%d quality=%d w=%d h=%d", jpeg, quality, width, height);
-
- /* grab takes long time and we don't want to lose data connection
- or interrupt video ... */
- if(pthread_mutex_unlock(&this->vdr_entry_lock))
- LOGERR("pthread_mutex_unlock failed");
-
- if(this->funcs.fe_control)
- data = (grab_data_t*)(this->funcs.fe_control(this->funcs.fe_handle, cmd));
-
- if(data && data->size>0 && data->data) {
- char s[128];
- sprintf(s, "GRAB %d %lu\r\n", this->token, (unsigned long)data->size);
- mutex_lock_cancellable (&this->fd_control_lock);
- write_control_data(this, s, strlen(s));
- write_control_data(this, data->data, data->size);
- mutex_unlock_cancellable (&this->fd_control_lock);
- } else {
- /* failed */
- printf_control(this, "GRAB %d 0\r\n", this->token);
- }
-
- pthread_mutex_lock(&this->vdr_entry_lock);
-
- if(data) {
- free(data->data);
- free(data);
- }
-
- return CONTROL_OK;
- }
- }
-
- return CONTROL_PARAM_ERROR;
-}
-
-static int handle_control_substream(vdr_input_plugin_t *this, const char *cmd)
-{
- unsigned int pid;
- if(1 == sscanf(cmd, "SUBSTREAM 0x%x", &pid)) {
- pthread_mutex_lock(&this->lock);
-
- if(!this->funcs.fe_control)
- LOGERR("ERROR - no fe_control set !");
-
- if((pid & 0xf0) == 0xe0 && this->funcs.fe_control) { /* video 0...15 */
- if(!this->pip_stream) {
-LOGMSG("create pip stream %s", cmd);
- this->pip_stream =
- this->funcs.fe_control(this->funcs.fe_handle, cmd);
-LOGMSG(" pip stream created");
- }
- } else {
- /*} else if(audio) {*/
- if(this->pip_stream && this->funcs.fe_control) {
- LOGMSG("close pip stream");
-
- this->pip_stream = NULL;
- this->funcs.fe_control(this->funcs.fe_handle, cmd);
- /* xine_stop(this->pip_stream); */
- /* xine_close(this->pip_stream); */
- /* xine_dispose(this->pip_stream); */
- }
- }
- pthread_mutex_unlock(&this->lock);
- return CONTROL_OK;
- }
- return CONTROL_PARAM_ERROR;
-}
-
-static int handle_control_osdcmd(vdr_input_plugin_t *this)
-{
- osd_command_t osdcmd = {0};
- int err = CONTROL_OK;
-
- if (!this->control_running)
- return CONTROL_DISCONNECTED;
-
- /* read struct size first */
- size_t todo, expect = sizeof(osd_command_t);
- uint8_t *pt = (uint8_t*)&osdcmd;
- if (read_control(this, pt, sizeof(osdcmd.size)) != sizeof(osdcmd.size)) {
- LOGMSG("control: error reading OSDCMD data length");
- return CONTROL_DISCONNECTED;
- }
- pt += sizeof(osdcmd.size);
- expect -= sizeof(osdcmd.size);
- todo = osdcmd.size - sizeof(osdcmd.size);
-
- /* read data */
- size_t bytes = MIN(todo, expect);
- if (read_control(this, pt, bytes) != bytes) {
- LOGMSG("control: error reading OSDCMD data");
- return CONTROL_DISCONNECTED;
- }
-
- if (expect < todo) {
- /* server uses larger struct, discard rest of data */
- uint8_t dummy[todo-expect];
- LOGMSG("osd_command_t size %d, expected %d", (int)osdcmd.size, (int)expect);
- if (read_control(this, dummy, todo-expect) != todo-expect) {
- LOGMSG("control: error reading OSDCMD data (unknown part)");
- return CONTROL_DISCONNECTED;
- }
- }
-
- ntoh_osdcmd(osdcmd);
-
- /* read palette */
- if (osdcmd.palette && osdcmd.colors>0) {
- int bytes = sizeof(xine_clut_t)*(osdcmd.colors);
- osdcmd.palette = malloc(bytes);
- if (read_control(this, (unsigned char *)osdcmd.palette, bytes) != bytes) {
- LOGMSG("control: error reading OSDCMD palette");
- err = CONTROL_DISCONNECTED;
- }
- } else {
- osdcmd.palette = NULL;
- }
-
- /* read (RLE) data */
- if (err == CONTROL_OK && osdcmd.data && osdcmd.datalen>0) {
- osdcmd.data = (xine_rle_elem_t*)malloc(osdcmd.datalen);
- if(read_control(this, (unsigned char *)osdcmd.data, osdcmd.datalen)
- != osdcmd.datalen) {
- LOGMSG("control: error reading OSDCMD bitmap");
- err = CONTROL_DISCONNECTED;
- } else {
- uint8_t *raw = osdcmd.raw_data;
- osdcmd.data = uncompress_osd_net(raw, osdcmd.num_rle, osdcmd.datalen);
- osdcmd.datalen = osdcmd.num_rle*4;
- free(raw);
- }
- } else {
- osdcmd.data = NULL;
- }
-
- if (err == CONTROL_OK)
- err = vdr_plugin_exec_osd_command(&this->iface, &osdcmd);
-
- free(osdcmd.data);
- free(osdcmd.palette);
-
- return err;
-}
-
-/************************** Control from VDR ******************************/
-
-#define VDR_ENTRY_LOCK(ret...) \
- do { \
- if(pthread_mutex_lock(&this->vdr_entry_lock)) { \
- LOGERR("%s:%d: pthread_mutex_lock failed", __PRETTY_FUNCTION__, __LINE__); \
- return ret ; \
- } \
- } while(0)
-
-#define VDR_ENTRY_UNLOCK() \
- do { \
- if(pthread_mutex_unlock(&this->vdr_entry_lock)) { \
- LOGERR("%s:%d: pthread_mutex_unlock failed", __PRETTY_FUNCTION__, __LINE__); \
- } \
- } while(0)
-
-static const struct {
- const uint32_t type;
- const char name[28];
-} eventmap[] = {
- {XINE_EVENT_INPUT_UP, "XINE_EVENT_INPUT_UP"},
- {XINE_EVENT_INPUT_DOWN, "XINE_EVENT_INPUT_DOWN"},
- {XINE_EVENT_INPUT_LEFT, "XINE_EVENT_INPUT_LEFT"},
- {XINE_EVENT_INPUT_RIGHT, "XINE_EVENT_INPUT_RIGHT"},
- {XINE_EVENT_INPUT_SELECT, "XINE_EVENT_INPUT_SELECT"},
- {XINE_EVENT_INPUT_MENU1, "XINE_EVENT_INPUT_MENU1"},
- {XINE_EVENT_INPUT_MENU2, "XINE_EVENT_INPUT_MENU2"},
- {XINE_EVENT_INPUT_MENU3, "XINE_EVENT_INPUT_MENU3"},
- {XINE_EVENT_INPUT_MENU4, "XINE_EVENT_INPUT_MENU4"},
- {XINE_EVENT_INPUT_MENU5, "XINE_EVENT_INPUT_MENU5"},
- {XINE_EVENT_INPUT_NEXT, "XINE_EVENT_INPUT_NEXT"},
- {XINE_EVENT_INPUT_PREVIOUS,"XINE_EVENT_INPUT_PREVIOUS"},
-};
-
-/*
- * vdr_plugin_poll()
- *
- * Query buffer state
- * Returns amount of free PES buffer blocks in queue.
- */
-static int vdr_plugin_poll(vdr_input_plugin_t *this, int timeout_ms)
-{
- struct timespec abstime;
- int result = 0;
-
- /* Caller must have locked this->vdr_entry_lock ! */
-
- if(this->slave_stream) {
- LOGMSG("vdr_plugin_poll: called while playing slave stream !");
- return 1;
- }
-
- TRACE("vdr_plugin_poll (%d ms), buffer_pool: blocks=%d, bytes=%d",
- timeout_ms, this->buffer_pool->size(this->buffer_pool),
- this->buffer_pool->data_size(this->buffer_pool));
-
- pthread_mutex_lock (&this->buffer_pool->buffer_pool_mutex);
- result = this->buffer_pool->buffer_pool_num_free -
- (this->buffer_pool->buffer_pool_capacity - this->max_buffers);
- pthread_mutex_unlock (&this->buffer_pool->buffer_pool_mutex);
-
- if(timeout_ms > 0 && result <= 0) {
- if(timeout_ms > 250) {
- LOGMSG("vdr_plugin_poll: timeout too large (%d ms), forced to 250ms", timeout_ms);
- timeout_ms = 250;
- }
- create_timeout_time(&abstime, timeout_ms);
- pthread_mutex_lock(&this->lock);
- if(this->scr_tuning == SCR_TUNING_PAUSED) {
- LOGSCR("scr tuning reset by POLL");
- reset_scr_tuning(this,this->speed_before_pause);
- }
- pthread_mutex_unlock(&this->lock);
-
- signal_buffer_not_empty(this);
-
- VDR_ENTRY_UNLOCK();
-
- pthread_mutex_lock (&this->buffer_pool->buffer_pool_mutex);
- while(result <= 5) {
- if(pthread_cond_timedwait (&this->buffer_pool->buffer_pool_cond_not_empty,
- &this->buffer_pool->buffer_pool_mutex,
- &abstime) == ETIMEDOUT)
- break;
- result = this->buffer_pool->buffer_pool_num_free -
- (this->buffer_pool->buffer_pool_capacity - this->max_buffers);
- }
- pthread_mutex_unlock (&this->buffer_pool->buffer_pool_mutex);
- VDR_ENTRY_LOCK(0);
- }
-
- TRACE("vdr_plugin_poll returns, %d free (%d used, %d bytes)\n", result,
- this->buffer_pool->size(this->buffer_pool),
- this->buffer_pool->data_size(this->buffer_pool));
-
- /* handle priority problem in paused mode when
- data source has higher priority than control source */
- if(result <= 0) {
- result = 0;
- xine_usec_sleep(3*1000);
- }
-
- return result;
-}
-
-/*
- * vdr_plugin_flush()
- *
- * Flush all data from buffers to output devices.
- * Returns 0 when there is no data or frames in stream buffers.
- */
-static int vdr_plugin_flush(vdr_input_plugin_t *this, int timeout_ms)
-{
- struct timespec abstime;
- fifo_buffer_t *pool = this->buffer_pool;
- fifo_buffer_t *buffer = this->block_buffer;
- int result = 0, waitresult=0;
-
- /* Caller must have locked this->vdr_entry_lock ! */
-
- if(this->slave_stream) {
- LOGDBG("vdr_plugin_flush: called while playing slave stream !");
- return 0;
- }
-
- TRACE("vdr_plugin_flush (%d ms) blocks=%d+%d, frames=%d", timeout_ms,
- buffer->size(buffer), pool->size(pool),
- this->stream->video_out->get_property(this->stream->video_out,
- VO_PROP_BUFS_IN_FIFO));
-
- if(this->live_mode /*&& this->fd_control < 0*/) {
- /* No flush in live mode */
- return 1;
- }
-
- this->class->xine->port_ticket->acquire(this->class->xine->port_ticket, 1);
- result = MAX(0, pool->size(pool)) +
- MAX(0, buffer->size(buffer)) +
- this->stream->video_out->get_property(this->stream->video_out,
- VO_PROP_BUFS_IN_FIFO);
- this->class->xine->port_ticket->release(this->class->xine->port_ticket, 1);
-
- put_control_buf(buffer, pool, BUF_CONTROL_FLUSH_DECODER);
- put_control_buf(buffer, pool, BUF_CONTROL_NOP);
-
- if (result <= 0)
- return 0;
-
- create_timeout_time(&abstime, timeout_ms);
-
- while(result > 0 && waitresult != ETIMEDOUT) {
- TRACE("vdr_plugin_flush waiting (max %d ms), %d+%d buffers used, "
- "%d frames (rd pos=%" PRIu64 ")\n", timeout_ms,
- pool->size(pool), buffer->size(buffer),
- (int)this->stream->video_out->get_property(this->stream->video_out,
- VO_PROP_BUFS_IN_FIFO),
- this->curpos);
-
- pthread_mutex_lock(&pool->buffer_pool_mutex);
- waitresult = pthread_cond_timedwait (&pool->buffer_pool_cond_not_empty,
- &pool->buffer_pool_mutex, &abstime);
- pthread_mutex_unlock(&pool->buffer_pool_mutex);
-
- this->class->xine->port_ticket->acquire(this->class->xine->port_ticket, 1);
- result = MAX(0, pool->size(pool)) +
- MAX(0, buffer->size(buffer)) +
- this->stream->video_out->get_property(this->stream->video_out,
- VO_PROP_BUFS_IN_FIFO);
- this->class->xine->port_ticket->release(this->class->xine->port_ticket, 1);
- }
-
- TRACE("vdr_plugin_flush returns %d (%d+%d used, %d frames)\n", result,
- pool->size(pool), buffer->size(buffer),
- (int)this->stream->video_out->get_property(this->stream->video_out,
- VO_PROP_BUFS_IN_FIFO));
-
- return result;
-}
-
-/*
- * vdr_plugin_flush_remote()
- *
- * vdr_plugin_flush() Wrapper for remote mode
- * - wait for data in network buffers
- */
-static int vdr_plugin_flush_remote(vdr_input_plugin_t *this, int timeout_ms,
- uint64_t offset, int frame)
-{
- int r, live_mode;
-
- pthread_mutex_lock(&this->lock);
-
- live_mode = this->live_mode;
- this->live_mode = 0; /* --> 1 again when data arrives ... */
-
- LOGSCR("reset scr tuning by flush_remote");
- reset_scr_tuning(this, this->speed_before_pause);
-
- /* wait until all data has been received */
- while(this->curpos < offset && timeout_ms > 0) {
- TRACE("FLUSH: wait position (%" PRIu64 " ; need %" PRIu64 ")",
- this->curpos, offset);
- pthread_mutex_unlock(&this->lock);
- xine_usec_sleep(3*1000);
- pthread_mutex_lock(&this->lock);
- timeout_ms -= 3;
- }
-
- LOGSCR("reset scr tuning by flush_remote");
- reset_scr_tuning(this, this->speed_before_pause);
-
- pthread_mutex_unlock(&this->lock);
-
- r = vdr_plugin_flush(this, MAX(5, timeout_ms));
- printf_control(this, "RESULT %d %d\r\n", this->token, r);
-
- pthread_mutex_lock(&this->lock);
-
- this->live_mode = live_mode;
- this->stream->metronom->set_option(this->stream->metronom,
- METRONOM_PREBUFFER,
- METRONOM_PREBUFFER_VAL);
- this->guard_index = offset;
-
- pthread_mutex_unlock(&this->lock);
-
- return CONTROL_OK;
-}
-
-static int vdr_plugin_parse_control(vdr_input_plugin_if_t *this_if, const char *cmd)
-{
- vdr_input_plugin_t *this = (vdr_input_plugin_t *) this_if;
- int err = CONTROL_OK, i, j;
- int /*int32_t*/ tmp32 = 0;
- uint64_t tmp64 = 0ULL;
- xine_stream_t *stream = this->stream;
- static const char str_poll[] = "POLL";
- char *pt;
-
- VDR_ENTRY_LOCK(CONTROL_DISCONNECTED);
-
- LOGCMD("vdr_plugin_parse_control: %s", cmd);
-
- if( !memcmp(cmd, str_poll, 4) ||
- !strncasecmp(cmd, "POLL ", 5)) {
- tmp32 = atoi(cmd+5);
- if(tmp32 >= 0 && tmp32 < 1000) {
- if(this->fd_control >= 0) {
- printf_control(this, "POLL %d\r\n", vdr_plugin_poll(this, tmp32));
- } else {
- err = vdr_plugin_poll(this, tmp32);
- }
- } else {
- err = CONTROL_PARAM_ERROR;
- }
- VDR_ENTRY_UNLOCK();
- return err;
- }
-
- if(this->slave_stream)
- stream = this->slave_stream;
-
- if(NULL != (pt = strstr(cmd, "\r\n")))
- *((char*)pt) = 0; /* auts */
-
- /* very verbose logging ? */
- if (iSysLogLevel>3)
- LOGDBG("<control> %s",cmd);
-
- if(!strncasecmp(cmd, "OSDCMD", 6)) {
- err = handle_control_osdcmd(this);
-
- } else if(!strncasecmp(cmd, "VIDEO_PROPERTIES ", 17)) {
- int hue, saturation, brightness, sharpness, noise_reduction, contrast, vo_aspect_ratio;
- if(7 == sscanf(cmd+17, "%d %d %d %d %d %d %d",
- &hue, &saturation, &brightness, &sharpness, &noise_reduction, &contrast, &vo_aspect_ratio))
- err = set_video_properties(this, hue, saturation, brightness, sharpness, noise_reduction, contrast, vo_aspect_ratio);
- else
- err = CONTROL_PARAM_ERROR;
-
- } else if(!strncasecmp(cmd, "OVERSCAN ", 9)) {
- if(!this->funcs.fe_control)
- LOGMSG("No fe_control function! %s failed.", cmd);
- else
- this->funcs.fe_control(this->funcs.fe_handle, cmd);
-
- } else if(!strncasecmp(cmd, "VO_ASPECT ", 10)) {
- if(1 == sscanf(cmd+10, "%d", &tmp32)) {
- xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, tmp32);
- } else
- err = CONTROL_PARAM_ERROR;
-
- } else if(!strncasecmp(cmd, "DEINTERLACE ", 12)) {
- if(this->fd_control < 0)
- err = set_deinterlace_method(this, cmd+12);
-
- } else if(!strncasecmp(cmd, "EVENT ", 6)) {
- int i;
- char *pt = strchr(cmd, '\n');
- if(pt) *pt=0;
- pt = strstr(cmd+6, " CHAPTER");
- if(pt) {
- *pt = 0;
- this->class->xine->config->update_num(this->class->xine->config,
- "media.dvd.skip_behaviour", 1);
- }
- pt = strstr(cmd+6, " TITLE");
- if(pt) {
- *pt = 0;
- this->class->xine->config->update_num(this->class->xine->config,
- "media.dvd.skip_behaviour", 2);
- }
- for(i=0; i<sizeof(eventmap)/sizeof(eventmap[0]); i++)
- if(!strcmp(cmd+6, eventmap[i].name)) {
- xine_event_t ev = {
- .type = eventmap[i].type,
- .stream = this->slave_stream ?: this->stream,
- /* tag event to prevent circular input events
- (vdr -> here -> event_listener -> vdr -> ...) */
- .data = "VDR",
- .data_length = 4,
- };
- xine_event_send(ev.stream, &ev);
- break;
- }
-
- } else if(!strncasecmp(cmd, "VERSION ", 7)) {
- if(strncmp(XINELIBOUTPUT_VERSION " ", cmd+8,
- strlen(XINELIBOUTPUT_VERSION)+1)) {
- if(this->fd_control < 0) {
- /* Check should use protocol version.
- * In remote mode check is done in connect */
- LOGMSG("WARNING! xineplug_inp_xvdr.so and libvdr-xineliboutput.so "
- "are from different version (%s and %s)", XINELIBOUTPUT_VERSION, cmd+8);
- LOGMSG("Re-install plugin !");
- /*abort();*/
- }
- }
-
- } else if(!strncasecmp(cmd, "HDMODE ", 7)) {
- if(1 == sscanf(cmd+7, "%d", &tmp32)) {
- pthread_mutex_lock(&this->lock);
- if(tmp32) {
- if(!this->hd_buffer)
- this->hd_buffer = fifo_buffer_new(this->stream, HD_BUF_NUM_BUFS, HD_BUF_ELEM_SIZE);
- this->hd_stream = 1;
- } else {
- this->hd_stream = 0;
- }
- pthread_mutex_unlock(&this->lock);
- }
-
- } else if(!strncasecmp(cmd, "NOVIDEO ", 8)) {
- if(1 == sscanf(cmd+8, "%d", &tmp32)) {
- pthread_mutex_lock(&this->lock);
- this->no_video = tmp32;
- if(this->no_video) {
- this->max_buffers = RADIO_MAX_BUFFERS;
- } else {
- this->max_buffers = this->buffer_pool->buffer_pool_capacity;
- if(!this->live_mode && this->fd_control < 0)
- this->max_buffers >>= 1;
- this->max_buffers -= 10;
- }
- pthread_mutex_unlock(&this->lock);
- } else
- err = CONTROL_PARAM_ERROR;
-
- signal_buffer_pool_not_empty(this);
-
- } else if(!strncasecmp(cmd, "DISCARD ", 8)) {
- if(2 == sscanf(cmd+8, "%" PRIu64 " %d", &tmp64, &tmp32)) {
- pthread_mutex_lock(&this->lock);
- if(this->discard_index < tmp64) {
- this->discard_frame = tmp32;
- vdr_flush_engine(this, tmp64);
- this->discard_index = tmp64;
- } else if(this->discard_index != tmp64) {
- LOGMSG("Ignoring delayed control message %s", cmd);
- }
- pthread_cond_broadcast(&this->engine_flushed);
- pthread_mutex_unlock(&this->lock);
- } else
- err = CONTROL_PARAM_ERROR;
-
- } else if(!strncasecmp(cmd, "STREAMPOS ", 10)) {
- if(1 == sscanf(cmd+10, "%" PRIu64, &tmp64)) {
- pthread_mutex_lock(&this->lock);
- vdr_flush_engine(this, tmp64);
- this->curpos = tmp64;
- this->discard_index = this->curpos;
- this->guard_index = 0;
- pthread_mutex_unlock(&this->lock);
- } else
- err = CONTROL_PARAM_ERROR;
-
- } else if(!strncasecmp(cmd, "TRICKSPEED ", 11)) {
- err = (1 == sscanf(cmd+11, "%d", &tmp32)) ?
- set_playback_speed(this, tmp32) :
- CONTROL_PARAM_ERROR;
-
- } else if(!strncasecmp(cmd, "STILL ", 6)) {
- pthread_mutex_lock(&this->lock);
- /*if(this->fd_control >= 0) {*/
- if(1 == sscanf(cmd+6, "%d", &tmp32)) {
- this->still_mode = tmp32;
- if(this->still_mode)
- reset_scr_tuning(this, this->speed_before_pause);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HAS_STILL, this->still_mode);
- this->stream_start = 1;
- } else
- err = CONTROL_PARAM_ERROR;
- /*}*/
- pthread_mutex_unlock(&this->lock);
-
- } else if(!strncasecmp(cmd, "SCR ", 4)) {
- pthread_mutex_lock(&this->lock);
- if(1 == sscanf(cmd, "SCR Sync %d", &tmp32)) {
- this->scr_live_sync = 1;
- this->scr->set_speed_base(this->scr, tmp32);
- }
- else if(1 == sscanf(cmd, "SCR NoSync %d", &tmp32)) {
- this->scr_live_sync = 0;
- this->scr->set_speed_base(this->scr, tmp32);
- reset_scr_tuning(this, -1);
- }
- pthread_mutex_unlock(&this->lock);
-
- } else if(!strncasecmp(cmd, "LIVE ", 5)) {
- this->still_mode = 0;
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HAS_STILL, this->still_mode);
- err = (1 == sscanf(cmd+5, "%d", &tmp32)) ?
- set_live_mode(this, tmp32) : -2 ;
-
- } else if(!strncasecmp(cmd, "MASTER ", 7)) {
- if(1 == sscanf(cmd+7, "%d", &tmp32))
- this->fixed_scr = tmp32 ? 1 : 0;
- else
- err = CONTROL_PARAM_ERROR;
-
- } else if(!strncasecmp(cmd, "VOLUME ", 7)) {
- if(1 == sscanf(cmd+7, "%d", &tmp32)) {
- int sw = strstr(cmd, "SW") ? 1 : 0;
- if(!sw) {
- xine_set_param(stream, XINE_PARAM_AUDIO_VOLUME, tmp32);
- xine_set_param(stream, XINE_PARAM_AUDIO_MUTE, tmp32<=0 ? 1 : 0);
- } else {
- xine_set_param(stream, XINE_PARAM_AUDIO_AMP_LEVEL, tmp32);
- xine_set_param(stream, XINE_PARAM_AUDIO_AMP_MUTE, tmp32<=0 ? 1 : 0);
- }
- if(sw != this->sw_volume_control) {
- this->sw_volume_control = sw;
- if(sw) {
- xine_set_param(stream, XINE_PARAM_AUDIO_MUTE, 0);
- } else {
- xine_set_param(stream, XINE_PARAM_AUDIO_AMP_LEVEL, 100);
- xine_set_param(stream, XINE_PARAM_AUDIO_AMP_MUTE, 0);
- }
- }
- } else
- err = CONTROL_PARAM_ERROR;
-
- } else if(!strncasecmp(cmd, "AUDIOCOMPRESSION ",17)) {
- if(1 == sscanf(cmd+17, "%d", &tmp32)) {
- xine_set_param(stream, XINE_PARAM_AUDIO_COMPR_LEVEL, tmp32);
- } else
- err = CONTROL_PARAM_ERROR;
-
- } else if(!strncasecmp(cmd, "AUDIOSURROUND ",14)) {
- if(1 == sscanf(cmd+14, "%d", &tmp32)) {
- this->class->xine->config->update_num(this->class->xine->config,
- "audio.a52.surround_downmix", tmp32?1:0);
- } else
- err = CONTROL_PARAM_ERROR;
-
- } else if(!strncasecmp(cmd, "SPEAKERS ",9)) {
- if(1 == sscanf(cmd+9, "%d", &tmp32)) {
- this->class->xine->config->update_num(this->class->xine->config,
- "audio.output.speaker_arrangement", tmp32);
- } else
- err = CONTROL_PARAM_ERROR;
-
- } else if(!strncasecmp(cmd, "EQUALIZER ", 10)) {
- int eqs[XINE_PARAM_EQ_16000HZ - XINE_PARAM_EQ_30HZ + 2] = {0};
- sscanf(cmd+10,"%d %d %d %d %d %d %d %d %d %d",
- eqs,eqs+1,eqs+2,eqs+3,eqs+4,eqs+5,eqs+6,eqs+7,eqs+8,eqs+9);
- for(i=XINE_PARAM_EQ_30HZ,j=0; i<=XINE_PARAM_EQ_16000HZ; i++,j++)
- xine_set_param(stream, i, eqs[j]);
-
- } else if(!strncasecmp(cmd, "AUDIOSTREAM ", 12)) {
- if(!this->slave_stream) {
-#if 0
- int ac3 = strncmp(cmd+12, "AC3", 3) ? 0 : 1;
- if(1 == sscanf(cmd+12 + 4*ac3, "%d", &tmp32)) {
- pthread_mutex_lock(&this->lock);
- this->audio_stream_id = tmp32;
- pthread_mutex_unlock(&this->lock);
- } else {
- err = CONTROL_PARAM_ERROR;
- }
-#endif
- } else {
- if(1 == sscanf(cmd+12, "AC3 %d", &tmp32)) {
- tmp32 &= 0xff;
- LOGDBG("Audio channel -> [%d]", tmp32);
- xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, tmp32);
- }
- LOGDBG("Audio channel selected: [%d]", _x_get_audio_channel (stream));
- }
-
- } else if(!strncasecmp(cmd, "SPUSTREAM ", 10)) {
- int old_ch = _x_get_spu_channel(stream);
- int max_ch = xine_get_stream_info(stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL);
- int ch = old_ch;
- int ch_auto = strstr(cmd+10, "auto") ? 1 : 0;
- int is_dvd = 0;
-
- if (this->slave_stream && this->slave_stream->input_plugin) {
- const char *mrl = this->slave_stream->input_plugin->get_mrl(this->slave_stream->input_plugin);
- is_dvd = !strncmp(mrl, "dvd:/", 5);
- }
-
- if(strstr(cmd+10, "NEXT"))
- ch = ch < max_ch ? ch+1 : -2;
- else if(strstr(cmd+10, "PREV"))
- ch = ch > -2 ? ch-1 : max_ch-1;
- else if(1 == sscanf(cmd+10, "%d", &tmp32)) {
- ch = tmp32;
- } else if(cmd[10] && cmd[11] && (cmd[12] < 'a' || cmd[12] > 'z')) {
- /* ISO 639-1 language code */
- const char spu_lang[3] = {cmd[10], cmd[11], 0};
- LOGMSG("Preferred SPU language: %s", spu_lang);
- this->class->xine->config->update_string(this->class->xine->config,
- "media.dvd.language", spu_lang);
- ch = old_ch = 0;
- } else
- err = CONTROL_PARAM_ERROR;
-
- if (old_ch == SPU_CHANNEL_AUTO)
- old_ch = stream->spu_channel_auto;
-
- if (ch != old_ch) {
- if (is_dvd && ch_auto && stream->spu_channel_user == SPU_CHANNEL_AUTO) {
- LOGDBG("Automatic SPU channel %d->%d ignored", old_ch, ch);
- } else {
- LOGDBG("Forced SPU channel %d->%d", old_ch, ch);
- select_spu_channel(stream, ch);
- }
- LOGDBG("SPU channel selected: [%d]", _x_get_spu_channel (stream));
- }
-
- } else if(!strncasecmp(cmd, "AUDIODELAY ", 11)) {
- if(1 == sscanf(cmd+11, "%d", &tmp32))
- xine_set_param(stream, XINE_PARAM_AV_OFFSET, tmp32*90000/1000);
- else
- err = CONTROL_PARAM_ERROR;
-
- } else if(!strncasecmp(cmd, "SYNC ", 5)) {
- if(this->fd_control >= 0)
- write_control(this, cmd);
-
- } else if(!strncasecmp(cmd, "GETSTC", 6)) {
- int64_t pts = xine_get_current_vpts(stream) -
- stream->metronom->get_option(stream->metronom,
- METRONOM_VPTS_OFFSET);
- if(this->fd_control >= 0) {
- printf_control(this, "STC %" PRId64 "\r\n", pts);
- } else {
- *((int64_t *)cmd) = pts;
- }
-
- } else if(!strncasecmp(cmd, "FLUSH ", 6)) {
- if(1 == sscanf(cmd+6, "%d", &tmp32)) {
- if(this->fd_control >= 0) {
- uint32_t frame = 0;
- tmp64 = 0ULL;
- tmp32 = 0;
- sscanf(cmd+6, "%d %" PRIu64 " %d", &tmp32, &tmp64, &frame);
- err = vdr_plugin_flush_remote(this, tmp32, tmp64, frame);
- } else {
- err = vdr_plugin_flush(this, tmp32);
- }
- } else
- err = CONTROL_PARAM_ERROR;
-
- } else if(!strncasecmp(cmd, "TOKEN ", 6)) {
- if(1 == sscanf(cmd+6, "%d", &tmp32))
- this->token = tmp32;
- else
- err = CONTROL_PARAM_ERROR;
-
- } else if(!strncasecmp(cmd, "SUBSTREAM ", 9)) {
- err = handle_control_substream(this, cmd);
-
- } else if(!strncasecmp(cmd, "POST ", 5)) {
- /* lock demuxer thread out of adjust_realtime_speed */
- pthread_mutex_lock(&this->lock);
- if(!this->funcs.fe_control)
- LOGMSG("No fe_control function! %s failed.", cmd);
- else
- this->funcs.fe_control(this->funcs.fe_handle, cmd);
- pthread_mutex_unlock(&this->lock);
-
- } else if(!strncasecmp(cmd, "PLAYFILE ", 9)) {
- err = handle_control_playfile(this, cmd);
- if(this->fd_control >= 0) {
- printf_control(this, "RESULT %d %d\r\n", this->token, err);
- err = CONTROL_OK;
- }
-
- } else if(!strncasecmp(cmd, "SEEK ", 5)) {
- if(this->slave_stream) {
- int pos_stream=0, pos_time=0, length_time=0;
- xine_get_pos_length(this->slave_stream,
- &pos_stream, &pos_time, &length_time);
- if(cmd[5]=='+')
- pos_time += atoi(cmd+6) * 1000;
- else if(cmd[5]=='-')
- pos_time -= atoi(cmd+6) * 1000;
- else
- pos_time = atoi(cmd+5) * 1000;
- err = xine_play (this->slave_stream, 0, pos_time);
- if(this->fd_control >= 0)
- err = CONTROL_OK;
- }
-
- } else if(!strncasecmp(cmd, "GETLENGTH", 9)) {
- int pos_stream=0, pos_time=0, length_time=0;
- xine_get_pos_length(stream, &pos_stream, &pos_time, &length_time);
- err = length_time/*/1000*/;
- if(this->fd_control >= 0) {
- printf_control(this, "RESULT %d %d\r\n", this->token, err);
- err = CONTROL_OK;
- }
-
- } else if(!strncasecmp(cmd, "GETAUTOPLAYSIZE", 15)) {
-
- if (cmd[15]==' ' && cmd[16]) {
- /* query from specific input plugin */
- const char *cls_name = cmd + 16;
- this->autoplay_size = 0;
- if (! xine_get_browse_mrls (stream->xine,
- cls_name,
- NULL, &this->autoplay_size))
- /* try older method */
- xine_get_autoplay_mrls(stream->xine, cls_name, &this->autoplay_size);
- }
-
- if(this->autoplay_size < 0) {
- char **list;
- if(this->slave_stream &&
- this->slave_stream->input_plugin &&
- this->slave_stream->input_plugin->input_class)
- list = this->slave_stream->input_plugin->input_class->
- get_autoplay_list(this->slave_stream->input_plugin->input_class, &this->autoplay_size);
- }
- err = this->autoplay_size;
- if(this->fd_control >= 0) {
- printf_control(this, "RESULT %d %d\r\n", this->token, err);
- err = CONTROL_OK;
- }
-
- } else if(!strncasecmp(cmd, "GETPOS", 6)) {
- int pos_stream=0, pos_time=0, length_time=0;
- xine_get_pos_length(stream, &pos_stream, &pos_time, &length_time);
- err = pos_time/*/1000*/;
- if(this->fd_control >= 0) {
- printf_control(this, "RESULT %d %d\r\n", this->token, err);
- err = CONTROL_OK;
- }
-
- } else if(!strncasecmp(cmd, "SUBTITLES ", 10)) {
- if(this->slave_stream) {
- int vpos = 0;
- if(1 == sscanf(cmd+10, "%d", &vpos))
- this->class->xine->config->update_num(this->class->xine->config,
- "subtitles.separate.vertical_offset", vpos);
- else
- err = CONTROL_PARAM_ERROR;
- }
-
- } else if(!strncasecmp(cmd, "EXTSUBSIZE ", 11)) {
- int size = 0;
- if(1 == sscanf(cmd+11, "%d", &size))
- /* size of separate subtitles :
- -1 = xine default
- 0...6 = { tiny small normal large very large huge } */
- this->class->xine->config->update_num(this->class->xine->config,
- "subtitles.separate.subtitle_size", size);
- else
- err = CONTROL_PARAM_ERROR;
-
- } else if(!strncasecmp(cmd, "GRAB ", 5)) {
- handle_control_grab(this, cmd);
-
- /* next ones need to be synchronized to data stream */
- } else if(!strncasecmp(cmd, "BLANK", 5)) {
- put_control_buf(this->block_buffer, this->buffer_pool, CONTROL_BUF_BLANK);
-
- } else if(!strncasecmp(cmd, "CLEAR", 5)) {
- /* #warning should be delayed and executed in read_block */
-
- } else {
- LOGMSG("unknown control %s", cmd);
- err = CONTROL_UNKNOWN;
- }
-
- LOGCMD("vdr_plugin_parse_control: DONE (%d): %s", err, cmd);
-
- VDR_ENTRY_UNLOCK();
-
- return err;
-}
-
-static void *vdr_control_thread(void *this_gen)
-{
- vdr_input_plugin_t *this = (vdr_input_plugin_t *) this_gen;
- char line[8128];
- int err;
- int counter = 100;
-
- LOGDBG("Control thread started");
-
- /*(void)nice(-1);*/
-
- /* wait until state changes from open to play */
- while(bSymbolsFound && counter>0 && ! this->funcs.fe_control) {
- xine_usec_sleep(50*1000);
- counter--;
- }
-
- write_control(this, "CONFIG\r\n");
-
- while(this->control_running) {
-
- /* read next command */
- line[0] = 0;
- pthread_testcancel();
- if((err=readline_control(this, line, sizeof(line)-1, -1)) <= 0) {
- if(err < 0)
- break;
- continue;
- }
- LOGCMD("Received command %s",line);
- pthread_testcancel();
-
- if(!this->control_running)
- break;
-
- /* parse */
- switch(err = vdr_plugin_parse_control(&this->iface, line)) {
- case CONTROL_OK:
- break;
- case CONTROL_UNKNOWN:
- LOGMSG("unknown control message %s", line);
- break;
- case CONTROL_PARAM_ERROR:
- LOGMSG("invalid parameter in control message %s", line);
- break;
- case CONTROL_DISCONNECTED:
- LOGMSG("control stream read error - disconnected ?");
- this->control_running = 0;
- break;
- default:
- LOGMSG("parse_control failed with result: %d", err);
- break;
- }
- }
-
- if(this->control_running)
- write_control(this, "CLOSE\r\n");
- this->control_running = 0;
-
- if(this->slave_stream)
- xine_stop(this->slave_stream);
-
- LOGDBG("Control thread terminated");
- pthread_exit(NULL);
-}
-
-/**************************** Control to VDR ********************************/
-
-static void slave_track_maps_changed(vdr_input_plugin_t *this)
-{
- char tracks[1024], lang[128];
- int i, current, n = 0;
- size_t cnt;
-
- /* DVD title and menu domain detection */
-#ifdef XINE_STREAM_INFO_DVD_TITLE_NUMBER
- i = _x_stream_info_get(this->slave_stream, XINE_STREAM_INFO_DVD_TITLE_NUMBER);
- if(i >= 0) {
- if (i == 0)
- dvd_menu_domain(this, 1);
- sprintf(tracks, "INFO DVDTITLE %d\r\n", i);
- if(this->funcs.xine_input_event)
- this->funcs.xine_input_event(tracks, NULL);
- else
- write_control(this, tracks);
- LOGDBG("%s", tracks);
- }
-#endif
-
- /* Audio tracks */
-
- strcpy(tracks, "INFO TRACKMAP AUDIO ");
- cnt = strlen(tracks);
- current = xine_get_param(this->slave_stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL);
- for(i=0; i<32 && cnt<sizeof(tracks)-32; i++)
- if(xine_get_audio_lang(this->slave_stream, i, lang)) {
- while(lang[0]==' ') strcpy(lang, lang+1);
- cnt += snprintf(tracks+cnt, sizeof(tracks)-cnt-32,
- "%s%d:%s ", i==current?"*":"", i, lang);
- n++;
- }
- tracks[sizeof(tracks)-1] = 0;
- if(n>1)
- LOGDBG("%s", tracks);
-
- if(this->funcs.xine_input_event) {
- /* local mode: -> VDR */
- this->funcs.xine_input_event(tracks, NULL);
- } else {
- /* remote mode: -> connection -> VDR */
- strcpy(tracks+cnt, "\r\n");
- write_control(this, tracks);
- }
-
- /* DVD SPU tracks */
-
- n = 0;
- strcpy(tracks, "INFO TRACKMAP SPU ");
- cnt = strlen(tracks);
- current = _x_get_spu_channel (this->slave_stream);
- if(current < 0) {
- /* -2 == none, -1 == auto */
- cnt += snprintf(tracks+cnt, sizeof(tracks)-cnt-32,
- "*%d:%s ", current,
- current==SPU_CHANNEL_NONE ? "none" : "auto");
- n++;
- if(current == SPU_CHANNEL_AUTO)
- current = this->slave_stream->spu_channel_auto;
- }
- for(i=0; i<32 && cnt<sizeof(tracks)-32; i++)
- if(xine_get_spu_lang(this->slave_stream, i, lang)) {
- while(lang[0]==' ') strcpy(lang, lang+1);
- cnt += snprintf(tracks+cnt, sizeof(tracks)-cnt-32,
- "%s%d:%s ", i==current?"*":"", i, lang);
- n++;
- }
- tracks[sizeof(tracks)-1] = 0;
- if(n>1)
- LOGDBG("%s", tracks);
-
- if(this->funcs.xine_input_event) {
- this->funcs.xine_input_event(tracks, NULL);
- } else {
- strcpy(tracks+cnt, "\r\n");
- write_control(this, tracks);
- }
-}
-
-/* Map some xine input events to vdr input (remote key names) */
-static const struct {
- const uint32_t event;
- const char name[12];
-} vdr_keymap[] = {
- {XINE_EVENT_INPUT_NEXT, "Next"},
- {XINE_EVENT_INPUT_PREVIOUS, "Previous"},
-
- {XINE_EVENT_INPUT_DOWN, "Down"},
- {XINE_EVENT_INPUT_UP, "Up"},
- {XINE_EVENT_INPUT_LEFT, "Left"},
- {XINE_EVENT_INPUT_RIGHT, "Right"},
- {XINE_EVENT_INPUT_SELECT, "Ok"},
-
- {XINE_EVENT_INPUT_MENU1, "Menu"},
- {XINE_EVENT_INPUT_MENU2, "Red"},
- {XINE_EVENT_INPUT_MENU3, "Green"},
- {XINE_EVENT_INPUT_MENU4, "Yellow"},
- {XINE_EVENT_INPUT_MENU5, "Blue"},
- {XINE_EVENT_INPUT_NUMBER_0, "0"},
- {XINE_EVENT_INPUT_NUMBER_1, "1"},
- {XINE_EVENT_INPUT_NUMBER_2, "2"},
- {XINE_EVENT_INPUT_NUMBER_3, "3"},
- {XINE_EVENT_INPUT_NUMBER_4, "4"},
- {XINE_EVENT_INPUT_NUMBER_5, "5"},
- {XINE_EVENT_INPUT_NUMBER_6, "6"},
- {XINE_EVENT_INPUT_NUMBER_7, "7"},
- {XINE_EVENT_INPUT_NUMBER_8, "8"},
- {XINE_EVENT_INPUT_NUMBER_9, "9"},
-
-#if defined(XINE_EVENT_VDR_RED)
- {XINE_EVENT_VDR_BACK, "Back"},
- {XINE_EVENT_VDR_CHANNELPLUS, "Channel+"},
- {XINE_EVENT_VDR_CHANNELMINUS, "Channel-"},
- {XINE_EVENT_VDR_RED, "Red"},
- {XINE_EVENT_VDR_GREEN, "Green"},
- {XINE_EVENT_VDR_YELLOW, "Yellow"},
- {XINE_EVENT_VDR_BLUE, "Blue"},
- {XINE_EVENT_VDR_PLAY, "Play"},
- {XINE_EVENT_VDR_PAUSE, "Pause"},
- {XINE_EVENT_VDR_STOP, "Stop"},
- {XINE_EVENT_VDR_RECORD, "Record"},
- {XINE_EVENT_VDR_FASTFWD, "FastFwd"},
- {XINE_EVENT_VDR_FASTREW, "FastRew"},
- {XINE_EVENT_VDR_POWER, "Power"},
- {XINE_EVENT_VDR_SCHEDULE, "Schedule"},
- {XINE_EVENT_VDR_CHANNELS, "Channels"},
- {XINE_EVENT_VDR_TIMERS, "Timers"},
- {XINE_EVENT_VDR_RECORDINGS, "Recordings"},
- {XINE_EVENT_VDR_SETUP, "Setup"},
- {XINE_EVENT_VDR_COMMANDS, "Commands"},
- {XINE_EVENT_VDR_USER1, "User1"},
- {XINE_EVENT_VDR_USER2, "User2"},
- {XINE_EVENT_VDR_USER3, "User3"},
- {XINE_EVENT_VDR_USER4, "User4"},
- {XINE_EVENT_VDR_USER5, "User5"},
- {XINE_EVENT_VDR_USER6, "User6"},
- {XINE_EVENT_VDR_USER7, "User7"},
- {XINE_EVENT_VDR_USER8, "User8"},
- {XINE_EVENT_VDR_USER9, "User9"},
- {XINE_EVENT_VDR_VOLPLUS, "Volume+"},
- {XINE_EVENT_VDR_VOLMINUS, "Volume-"},
- {XINE_EVENT_VDR_MUTE, "Mute"},
- {XINE_EVENT_VDR_AUDIO, "Audio"},
-#endif
-#if defined(XINE_EVENT_VDR_INFO)
- {XINE_EVENT_VDR_INFO, "Info"},
-#endif
-#if defined(XINE_EVENT_VDR_SUBTITLES)
- {XINE_EVENT_VDR_SUBTITLES, "Subtitles"},
-#endif
-};
-
-static void vdr_event_cb (void *user_data, const xine_event_t *event)
-{
- vdr_input_plugin_t *this = (vdr_input_plugin_t *)user_data;
- int i;
-
- for (i = 0; i < sizeof(vdr_keymap) / sizeof(vdr_keymap[0]); i++) {
- if (event->type == vdr_keymap[i].event) {
- if (event->data && event->data_length == 4 &&
- !strncmp(event->data, "VDR", 4)) {
- /*LOGMSG("Input event created by self, ignoring");*/
- return;
- }
- LOGDBG("XINE_EVENT (input) %d --> %s",
- event->type, vdr_keymap[i].name);
-
- if (this->fd_control >= 0) {
- /* remote mode: -> input_plugin -> connection -> VDR */
- printf_control(this, "KEY %s\r\n", vdr_keymap[i].name);
- }
- if (this->funcs.xine_input_event) {
- /* local mode: -> VDR */
- this->funcs.xine_input_event(NULL, vdr_keymap[i].name);
- }
- return;
- }
- }
-
- switch (event->type) {
- case XINE_EVENT_UI_SET_TITLE:
- if(event->stream==this->slave_stream) {
- char msg[256], titlen[64] = "";
- xine_ui_data_t *data = (xine_ui_data_t *)event->data;
- LOGMSG("XINE_EVENT_UI_SET_TITLE: %s", data->str);
-
-#ifdef XINE_STREAM_INFO_DVD_TITLE_NUMBER
- int tt = _x_stream_info_get(this->slave_stream,XINE_STREAM_INFO_DVD_TITLE_NUMBER);
- snprintf(titlen, sizeof(titlen), "INFO DVDTITLE %d\r\n", tt);
- if (tt == 0)
- dvd_menu_domain(this, 1);
-#endif
- snprintf(msg, sizeof(msg), "INFO TITLE %s\r\n%s", data->str, titlen);
- msg[sizeof(msg)-1] = 0;
- if(this->funcs.xine_input_event)
- this->funcs.xine_input_event(msg, NULL);
- else
- write_control(this, msg);
- break;
- }
-
- case XINE_EVENT_UI_NUM_BUTTONS:
- if (event->stream == this->slave_stream) {
- xine_ui_data_t *data = (xine_ui_data_t*)event->data;
- char msg[64];
- dvd_menu_domain(this, data->num_buttons > 0);
- snprintf(msg, sizeof(msg), "INFO DVDBUTTONS %d\r\n", data->num_buttons);
- msg[sizeof(msg)-1] = 0;
- if (this->funcs.xine_input_event)
- this->funcs.xine_input_event(msg, NULL);
- else
- write_control(this, msg);
- break;
- }
-
- case XINE_EVENT_UI_CHANNELS_CHANGED:
- if(event->stream==this->slave_stream)
- slave_track_maps_changed(this);
- break;
-
- case XINE_EVENT_FRAME_FORMAT_CHANGE:
- {
- xine_format_change_data_t *frame_change =
- (xine_format_change_data_t *)event->data;
- LOGOSD("XINE_EVENT_FRAME_FORMAT_CHANGE (%dx%d, aspect=%d)",
- frame_change->width, frame_change->height,
- frame_change->aspect);
- if (!frame_change->aspect) /* from frontend */
- this->osd_manager->video_size_changed(this->osd_manager, event->stream,
- frame_change->width, frame_change->height);
-#if 0
- if(frame_change->aspect)
- queue_blank_yv12(this);
-#endif
- }
- break;
-
- case XINE_EVENT_UI_PLAYBACK_FINISHED:
- if(event->stream == this->stream) {
- LOGMSG("XINE_EVENT_UI_PLAYBACK_FINISHED");
- this->control_running = 0;
-#if 1
- if(iSysLogLevel > 2) {
- /* dump whole xine log as we should not be here ... */
- xine_t *xine = this->class->xine;
- int i, j;
- int logs = xine_get_log_section_count(xine);
- const char * const * names = xine_get_log_names(xine);
- for(i=0; i<logs; i++) {
-#if XINE_VERSION_CODE < 10105
- const char * const * lines = xine_get_log(xine, i);
-#else
- char * const * lines = xine_get_log(xine, i);
-#endif
- if(lines[0]) {
- printf("\nLOG: %s\n",names[i]);
- for(j=0; lines[j] && *lines[j]; j++)
- printf(" %2d: %s", j, lines[j]);
- }
- }
- }
-#endif
- } else if(event->stream == this->slave_stream) {
- LOGMSG("XINE_EVENT_UI_PLAYBACK_FINISHED (slave stream)");
- if(this->fd_control >= 0) {
- write_control(this, "ENDOFSTREAM\r\n");
- } else {
- if(this->funcs.fe_control)
- this->funcs.fe_control(this->funcs.fe_handle, "ENDOFSTREAM\r\n");
-#if 0
- if(!this->loop_play) {
- /* forward to vdr-fe (listening only VDR stream events) */
- xine_event_t event = {
- .type = XINE_EVENT_UI_PLAYBACK_FINISHED,
- .data_length = 0,
- };
- xine_event_send (this->stream, &event);
- } else {
-# if 0
- xine_usec_sleep(500*1000);
- xine_play(this->slave_stream, 0, 0);
-# endif
- }
-#endif
- }
- }
- break;
-
- default:
- LOGCMD("Got an xine event, type 0x%08x", event->type);
- break;
- }
-}
-
-/**************************** Data Stream *********************************/
-
-/*
- * wait_stream_sync()
- *
- * Wait until data and control streams have reached the same sync point.
- * - wait_stream_sync() is called only from data thread.
- * - data stream handling is suspended until control stream has
- * reached the same sync point (and xine engine has been flushed).
- *
- * Function is interrupred when
- * - control thread has been terminated
- * - demux_action_pending signal is set
- *
- * return value:
- * 1: Both streams have reached the same sync point
- * 0: timeout (errno = EAGAIN) or
- * interrupted (errno = EINTR) or
- * disconnected (errno = ENOTCONN)
- */
-static int wait_stream_sync(vdr_input_plugin_t *this)
-{
- int counter = 100;
-
- mutex_lock_cancellable(&this->lock);
-
- if (this->discard_index < this->discard_index_ds)
- LOGDBG("wait_stream_sync: waiting for engine_flushed condition %"PRIu64"<%"PRIu64,
- this->discard_index, this->discard_index_ds);
-
- while(this->control_running &&
- this->discard_index < this->discard_index_ds &&
- /*!this->stream->demux_action_pending &&*/
- --counter > 0) {
- struct timespec abstime;
- create_timeout_time(&abstime, 10);
- pthread_cond_timedwait(&this->engine_flushed, &this->lock, &abstime);
- }
-
- mutex_unlock_cancellable(&this->lock);
-
- if (this->discard_index == this->discard_index_ds) {
- LOGDBG("wait_stream_sync: streams synced at %"PRIu64"/%"PRIu64,
- this->discard_index_ds, this->discard_index);
- return 0;
- }
-
- if (!this->control_running) {
- errno = ENOTCONN;
- }
- else if (this->stream->demux_action_pending) {
- LOGMSG("wait_stream_sync: demux_action_pending set");
- errno = EINTR;
- }
- else if (counter <= 0) {
- LOGMSG("wait_stream_sync: Timed out ! diff %"PRIu64, this->discard_index - this->discard_index_ds);
- errno = EAGAIN;
- }
-
- return 1;
-}
-
-static void data_stream_parse_control(vdr_input_plugin_t *this, char *cmd)
-{
- char *tmp;
-
- cmd[64] = 0;
- if(NULL != (tmp=strchr(cmd, '\r')))
- *tmp = '\0';
- if(NULL != (tmp=strchr(cmd, '\n')))
- *tmp = '\0';
-
- if(!strncasecmp(cmd, "DISCARD ", 8)) {
- uint64_t index;
- if(1 == sscanf(cmd+8, "%" PRIu64, &index)) {
-
- this->discard_index_ds = index;
-
- this->block_buffer->clear(this->block_buffer);
-
- wait_stream_sync(this);
- }
- return;
-
- } else if(!strncasecmp(cmd, "BLANK", 5)) {
- put_control_buf(this->block_buffer, this->buffer_pool, CONTROL_BUF_BLANK);
- return;
- }
-
- LOGMSG("Unexpected data_stream_parse_control(%s)", cmd);
- vdr_plugin_parse_control(&this->iface, cmd);
-}
-
-/*
- * vdr_plugin_read_block_tcp()
- *
- * - Read single transport block from socket / pipe.
- *
- * Returns NULL if read failed or data is not available.
- * (sets errno to EAGAIN, EINTR or ENOTCONN)
- *
- */
-static buf_element_t *vdr_plugin_read_block_tcp(vdr_input_plugin_t *this)
-{
- buf_element_t *read_buffer = this->read_buffer;
- int todo = sizeof(stream_tcp_header_t);
- int warnings = 0;
- int result, n;
-
- if (read_buffer && read_buffer->size >= sizeof(stream_tcp_header_t))
- todo += ((stream_tcp_header_t *)read_buffer->content)->len;
-
- while (XIO_READY == (result = _x_io_select(this->stream, this->fd_data, XIO_READ_READY, 100))) {
-
- pthread_testcancel();
- if (!this->control_running || this->fd_data < 0) {
- errno = ENOTCONN;
- return NULL;
- }
-
- /* Allocate buffer */
- if (!read_buffer) {
- this->read_buffer = read_buffer = get_buf_element_timed(this, 2048+sizeof(stream_tcp_header_t), 100);
- if (!read_buffer) {
- /* do not drop any data here ; dropping is done only at server side. */
- if (!this->is_paused && !warnings)
- LOGDBG("TCP: fifo buffer full");
- warnings++;
- continue; /* must call select to check fd for errors / closing */
- }
-
- /* read the header first */
- todo = sizeof(stream_tcp_header_t);
- read_buffer->size = 0;
- warnings = 0;
- }
-
- /* Read data */
- errno = 0;
- n = read(this->fd_data, read_buffer->content + read_buffer->size, todo - read_buffer->size);
- if (n <= 0) {
- if (!n || (errno != EINTR && errno != EAGAIN)) {
- if (n < 0 && this->fd_data >= 0)
- LOGERR("TCP read error (data stream %d : %d)", this->fd_data, n);
- if (n == 0)
- LOGMSG("Data stream disconnected");
- errno = ENOTCONN;
- }
- /* errno == EINTR || errno == EAGAIN || errno == ENOTCONN */
- return NULL;
- }
-
- read_buffer->size += n;
-
- /* Header complete ? */
- if (read_buffer->size == sizeof(stream_tcp_header_t)) {
- stream_tcp_header_t *hdr = ((stream_tcp_header_t *)read_buffer->content);
- hdr->len = ntohl(hdr->len);
- hdr->pos = ntohull(hdr->pos);
-
- todo += hdr->len;
-
- if (todo + read_buffer->size >= read_buffer->max_size) {
- LOGMSG("TCP: Buffer too small (%d ; incoming frame %d bytes)",
- read_buffer->max_size, todo + read_buffer->size);
- errno = ENOTCONN;
- return NULL;
- }
- }
-
- /* Buffer complete ? */
- if (read_buffer->size >= todo) {
- stream_tcp_header_t *hdr = ((stream_tcp_header_t *)read_buffer->content);
- if (hdr->pos == (uint64_t)(-1ULL) /*0xffffffff ffffffff*/) {
- /* control data */
- uint8_t *pkt_data = read_buffer->content + sizeof(stream_tcp_header_t);
- if (!DATA_IS_TS(pkt_data) && pkt_data[0]) { /* -> can't be pes or ts frame */
- data_stream_parse_control(this, (char*)pkt_data);
-
- read_buffer->free_buffer(read_buffer);
- this->read_buffer = NULL;
- errno = EAGAIN;
- return NULL;
- }
- }
-
- /* frame ready */
- read_buffer->type = BUF_NETWORK_BLOCK;
- this->read_buffer = NULL;
- return read_buffer;
- }
- }
-
- errno = (result == XIO_TIMEOUT) ? EAGAIN :
- (result == XIO_ABORTED) ? EINTR :
- ENOTCONN;
- return NULL;
-}
-
-static int vdr_plugin_read_net_tcp(vdr_input_plugin_t *this)
-{
- buf_element_t *buf = vdr_plugin_read_block_tcp(this);
- if (buf) {
- this->block_buffer->put(this->block_buffer, buf);
- return XIO_READY;
- }
- if (errno == EAGAIN || errno == EINTR)
- return XIO_TIMEOUT;
- return XIO_ERROR;
-}
-
-/*
- * read_socket_udp()
- *
- * - Read single transport block from datagram socket
- *
- * Returns NULL if read failed or data is not available.
- * (sets errno to EAGAIN, EINTR or ENOTCONN)
- *
- */
-static buf_element_t *read_socket_udp(vdr_input_plugin_t *this)
-{
- /*
- * poll for incoming data
- */
-
- int result = _x_io_select(this->stream, this->fd_data, XIO_READ_READY, 100);
-
- if (!this->control_running) {
- errno = ENOTCONN;
- return NULL;
- }
- if (result != XIO_READY) {
- if (result == XIO_ERROR)
- LOGERR("read_socket_udp(): select() failed");
-
- errno = (result == XIO_TIMEOUT) ? EAGAIN :
- (result == XIO_ABORTED) ? EINTR :
- ENOTCONN;
- return NULL;
- }
-
- pthread_testcancel();
-
- /*
- * allocate buffer
- */
-
- udp_data_t *udp = this->udp_data;
- buf_element_t *read_buffer = get_buf_element_timed(this, 2048+sizeof(stream_rtp_header_impl_t), 100);
-
- if (!read_buffer) {
- /* if queue is full, skip (video) frame.
- Waiting longer for free buffers just makes things worse ... */
- if (!this->is_paused) {
- LOGDBG("UDP Fifo buffer full !");
- if (this->scr && !udp->scr_jump_done) {
- this->scr->jump (this->scr, 40*90);
- LOGMSG("SCR jump: +40 ms (live=%d, tuning=%d)", this->live_mode, this->scr_tuning);
- udp->scr_jump_done = 50;
- }
- }
- errno = EAGAIN;
- return NULL;
- }
-
- if (udp->scr_jump_done)
- udp->scr_jump_done --;
-
- /*
- * Receive frame from socket and check for errors
- */
-
- struct sockaddr_in server_address;
- socklen_t address_len = sizeof(server_address);
-
- int n = recvfrom(this->fd_data, read_buffer->mem,
- read_buffer->max_size, MSG_TRUNC,
- &server_address, &address_len);
- if (n <= 0) {
- if (!n || (errno != EINTR && errno != EAGAIN)) {
- LOGERR("read_socket_udp(): recvfrom() failed");
- errno = ENOTCONN;
- }
- read_buffer->free_buffer(read_buffer);
- /* errno == EAGAIN || errno == EINTR || errno == ENOTCONN */
- return NULL;
- }
-
- /*
- * check source address
- */
-
- if ((server_address.sin_addr.s_addr !=
- udp->server_address.sin_addr.s_addr) ||
- server_address.sin_port != udp->server_address.sin_port) {
-#ifdef LOG_UDP
- uint32_t tmp_ip = ntohl(server_address.sin_addr.s_addr);
- LOGUDP("Received data from unknown sender: %d.%d.%d.%d:%d",
- ((tmp_ip>>24)&0xff), ((tmp_ip>>16)&0xff),
- ((tmp_ip>>8)&0xff), ((tmp_ip)&0xff),
- server_address.sin_port);
-#endif
- read_buffer->free_buffer(read_buffer);
- errno = EAGAIN;
- return NULL;
- }
-
- /*
- * Check if frame size is valid
- */
-
- if (this->rtp) {
- if (n < sizeof(stream_rtp_header_impl_t)) {
- LOGMSG("received invalid RTP packet (too short)");
- read_buffer->free_buffer(read_buffer);
- errno = EAGAIN;
- return NULL;
- }
- }
- else if (n < sizeof(stream_udp_header_t)) {
- LOGMSG("received invalid UDP packet (too short)");
- read_buffer->free_buffer(read_buffer);
- errno = EAGAIN;
- return NULL;
- }
-
- if (n > read_buffer->max_size) {
- LOGMSG("received too large UDP packet (%d bytes, buffer is %d bytes)", n, read_buffer->max_size);
- read_buffer->free_buffer(read_buffer);
- errno = EAGAIN;
- return NULL;
- }
-
- /*
- *
- */
-
- read_buffer->size = n;
- read_buffer->type = BUF_NETWORK_BLOCK;
-
- return read_buffer;
-}
-
-static buf_element_t *udp_parse_header(buf_element_t *read_buffer, int rtp)
-{
- if (rtp) {
-
- /* check if RTP header is valid. If not, assume UDP without RTP. */
- stream_rtp_header_impl_t *rtp_pkt = (stream_rtp_header_impl_t*)read_buffer->content;
- if (rtp_pkt->rtp_hdr.raw[0] == (RTP_VERSION_BYTE | RTP_HDREXT_BIT) &&
- ( rtp_pkt->rtp_hdr.raw[1] == RTP_PAYLOAD_TYPE_PES ||
- rtp_pkt->rtp_hdr.raw[1] == RTP_PAYLOAD_TYPE_TS ) &&
- rtp_pkt->hdr_ext.hdr.size == htons(RTP_HEADER_EXT_X_SIZE) &&
- rtp_pkt->hdr_ext.hdr.type == htons(RTP_HEADER_EXT_X_TYPE)) {
-
- /* strip RTP header but leave UDP header (carried inside RTP header extension) */
- read_buffer->content += sizeof(stream_rtp_header_impl_t) - sizeof(stream_udp_header_t);
- read_buffer->size -= sizeof(stream_rtp_header_impl_t) - sizeof(stream_udp_header_t);
- }
- }
-
- stream_udp_header_t *pkt = (stream_udp_header_t*)read_buffer->content;
-
- pkt->seq = ntohs(pkt->seq);
- pkt->pos = ntohull(pkt->pos);
-
- return read_buffer;
-}
-
-static buf_element_t *udp_check_packet(buf_element_t *read_buffer)
-{
- stream_udp_header_t *pkt = (stream_udp_header_t*)read_buffer->content;
- uint8_t *pkt_data = read_buffer->content + sizeof(stream_udp_header_t);
-
- /* Check for MPEG-TS sync byte or PES header */
- if (read_buffer->size > sizeof(stream_udp_header_t) &&
- !DATA_IS_TS(pkt_data) &&
- (pkt_data[0] || pkt_data[1] || pkt_data[2] != 1)) {
- LOGMSG("received invalid UDP packet (TS sync byte or PES header missing)");
- read_buffer->free_buffer(read_buffer);
- return NULL;
- }
-
- /* Check if header is valid */
- if (pkt->seq > UDP_SEQ_MASK) {
- LOGMSG("received invalid UDP packet (sequence number too big)");
- read_buffer->free_buffer(read_buffer);
- return NULL;
- }
-
- return read_buffer;
-}
-
-static buf_element_t *udp_parse_control(vdr_input_plugin_t *this, buf_element_t *read_buffer)
-{
- stream_udp_header_t *pkt = (stream_udp_header_t*)read_buffer->content;
- uint8_t *pkt_data = read_buffer->content + sizeof(stream_udp_header_t);
-
- /* Check for control messages */
- if (/*pkt->seq == (uint16_t)(-1) &&*/ /*0xffff*/
- pkt->pos == (uint64_t)(-1ULL) && /*0xffffffff ffffffff*/
- pkt_data[0]) { /* -> can't be PES frame */
- pkt_data[64] = 0;
-
- if (!strncmp((char*)pkt_data, "UDP MISSING", 11)) {
- /* Re-send failed */
- int seq1 = 0;
- int seq2 = 0;
- uint64_t rpos = UINT64_C(0);
- udp_data_t *udp = this->udp_data;
-
- sscanf(((char*)pkt_data)+12, "%d-%d %" PRIu64,
- &seq1, &seq2, &rpos);
- read_buffer->size = sizeof(stream_udp_header_t);
- read_buffer->type = BUF_NETWORK_BLOCK;
- pkt->pos = rpos;
- LOGUDP("Got UDP MISSING %d-%d (currseq=%d)", seq1, seq2, udp->next_seq);
-
- if (seq1 == udp->next_seq) {
- /* this is the one we are expecting ... */
- int n = ADDSEQ(seq2 + 1, -seq1);
- udp->missed_frames += n;
- seq2 &= UDP_SEQ_MASK;
- pkt->seq = seq2;
- udp->next_seq = seq2;
- LOGUDP(" accepted: now currseq %d", udp->next_seq);
- /* -> drop frame thru as empty ; it will trigger queue to continue */
-
- } else {
- LOGUDP(" UDP packet rejected: not expected seq ???");
-
- read_buffer->free_buffer(read_buffer);
- return NULL;
- }
-
- } else {
- data_stream_parse_control(this, (char*)pkt_data);
-
- read_buffer->free_buffer(read_buffer);
- return NULL;
- }
- }
-
- return read_buffer;
-}
-
-static buf_element_t *udp_process_queue(vdr_input_plugin_t *this)
-{
- udp_data_t *udp = this->udp_data;
-
- if (udp->queued <= 0)
- return NULL;
-
- /*
- * Stay inside receiving window:
- * if window exceeded, skip missing frames
- */
-
- if (udp->queued > ((UDP_SEQ_MASK+1)>>2)) {
-#ifdef LOG_UDP
- int start = udp->next_seq;
-#endif
- while (!udp->queue[udp->next_seq]) {
- INCSEQ(udp->next_seq);
- udp->missed_frames++;
- }
- udp->resend_requested = 0;
- LOGUDP("Re-ordering window exceeded, skipped missed frames %d-%d",
- start, udp->next_seq-1);
- }
-
- /*
- * flush all packets when idle padding found
- */
-
- if (udp->is_padding && udp->queued > 0)
- while (!udp->queue[udp->next_seq]) {
- INCSEQ(udp->next_seq);
- udp->missed_frames++;
- }
-
- /*
- * return next packet if available
- */
-
- while (udp->queued > 0 && udp->queue[udp->next_seq]) {
- buf_element_t *buf = NULL;
- stream_udp_header_t *pkt = (stream_udp_header_t*)udp->queue[udp->next_seq]->content;
- udp->queue_input_pos = pkt->pos + udp->queue[udp->next_seq]->size - sizeof(stream_udp_header_t);
- if (udp->queue[udp->next_seq]->size > sizeof(stream_udp_header_t))
- buf = udp->queue[udp->next_seq];
- else
- udp->queue[udp->next_seq]->free_buffer(udp->queue[udp->next_seq]);
-
- udp->queue[udp->next_seq] = NULL;
- udp->queued --;
- INCSEQ(udp->next_seq);
-
- if (udp->resend_requested)
- udp->resend_requested --;
-
- /* flush all packets when idle padding found */
- if (udp->is_padding && udp->queued > 0)
- while (!udp->queue[udp->next_seq]) {
- INCSEQ(udp->next_seq);
- udp->missed_frames++;
- }
-
- if (buf)
- return buf;
- }
-
- errno = EAGAIN;
- return NULL;
-}
-
-static void udp_process_resend(vdr_input_plugin_t *this)
-{
- udp_data_t *udp = this->udp_data;
-
- /* no new resend requests until previous has been completed or failed */
- if (udp->resend_requested)
- return;
-
- /* If frames are missing, request re-send */
- if (NEXTSEQ(udp->current_seq) != udp->next_seq && udp->queued) {
-
- int max_req = 20;
-
- while (!udp->queue[udp->current_seq] && --max_req > 0)
- INCSEQ(udp->current_seq);
-
- printf_control(this, "UDP RESEND %d-%d %" PRIu64 "\r\n",
- udp->next_seq, PREVSEQ(udp->current_seq),
- udp->queue_input_pos);
-
- udp->resend_requested =
- (udp->current_seq + (UDP_SEQ_MASK+1) - udp->next_seq) & UDP_SEQ_MASK;
-
- LOGUDP("%d-%d missing, requested re-send for %d frames",
- udp->next_seq, PREVSEQ(udp->current_seq), udp->resend_requested);
- }
-}
-
-/*
- * vdr_plugin_read_block_udp()
- *
- * - Get next UDP transport block from (socket)/queue.
- *
- * Returns NULL if read failed or data is not available.
- * (sets errno to EAGAIN, EINTR or ENOTCONN)
- *
- */
-static buf_element_t *vdr_plugin_read_block_udp(vdr_input_plugin_t *this)
-{
- udp_data_t *udp = this->udp_data;
-
- while (this->control_running && this->fd_data >= 0) {
-
- buf_element_t *read_buffer;
-
- /* return next packet from reordering queue (if any) */
- if (NULL != (read_buffer = udp_process_queue(this)))
- return read_buffer;
-
- /* poll + read socket */
- if ( ! (read_buffer = read_socket_udp(this)))
- return NULL;
-
- if (! (read_buffer = udp_parse_header(read_buffer, this->rtp)) ||
- ! (read_buffer = udp_parse_control(this, read_buffer)) ||
- ! (read_buffer = udp_check_packet(read_buffer))) {
- errno = EAGAIN;
- return NULL;
- }
-
- /*
- * handle re-ordering and retransmissios
- */
-
- stream_udp_header_t *pkt = (stream_udp_header_t*)read_buffer->content;
- uint8_t *pkt_data = read_buffer->content + sizeof(stream_udp_header_t);
-
- udp->current_seq = pkt->seq & UDP_SEQ_MASK;
- udp->is_padding = DATA_IS_PES(pkt_data) && IS_PADDING_PACKET(pkt_data);
-
- /* first received frame initializes sequence counter */
- if (udp->received_frames == -1) {
- udp->next_seq = udp->current_seq;
- udp->received_frames = 0;
- }
-
- /* check if received sequence number is inside allowed window
- (half of whole range) */
-
- if (ADDSEQ(udp->current_seq, -udp->next_seq) > ((UDP_SEQ_MASK+1) >> 1)/*0x80*/) {
- struct sockaddr_in sin;
- LOGUDP("Received SeqNo out of window (%d ; [%d..%d])",
- udp->current_seq, udp->next_seq,
- (udp->next_seq+((UDP_SEQ_MASK+1) >> 1)/*0x80*/) & UDP_SEQ_MASK);
- /* reset link */
- LOGDBG("UDP: resetting link");
- memcpy(&sin, &udp->server_address, sizeof(sin));
- free_udp_data(udp);
- udp = this->udp_data = init_udp_data();
- memcpy(&udp->server_address, &sin, sizeof(sin));
- read_buffer->free_buffer(read_buffer);
- errno = EAGAIN;
- return NULL;
- }
-
- /* Add received frame to incoming queue */
- if (udp->queue[udp->current_seq]) {
- /* Duplicate packet or lot of dropped packets */
- LOGUDP("Got duplicate or window exceeded ? (queue slot %d in use) !",
- udp->current_seq);
- udp->queue[udp->current_seq]->free_buffer(udp->queue[udp->current_seq]);
- udp->queue[udp->current_seq] = NULL;
- if (!udp->queued)
- LOGERR("UDP queue corrupt !!!");
- else
- udp->queued--;
- }
-
- udp->queue[udp->current_seq] = read_buffer;
- read_buffer = NULL;
- udp->queued ++;
-
- /* return next packet from queue (if any) */
- if (NULL != (read_buffer = udp_process_queue(this)))
- return read_buffer;
-
- udp_process_resend(this);
-
-#ifdef LOG_UDP
- /* Link quality statistics */
- udp->received_frames++;
- if (udp->received_frames >= 1000) {
- if (udp->missed_frames)
- LOGUDP("packet loss %d.%d%% (%4d/%4d)",
- udp->missed_frames*100/udp->received_frames,
- (udp->missed_frames*1000/udp->received_frames)%10,
- udp->missed_frames, udp->received_frames);
- udp->missed_frames = udp->received_frames = 0;
- }
-#endif
- }
-
- errno = ENOTCONN;
- return NULL;
-}
-
-static int vdr_plugin_read_net_udp(vdr_input_plugin_t *this)
-{
- buf_element_t *buf = vdr_plugin_read_block_udp(this);
- if (buf) {
- this->block_buffer->put(this->block_buffer, buf);
- return XIO_READY;
- }
- if (errno == EAGAIN || errno == EINTR)
- return XIO_TIMEOUT;
- return XIO_ERROR;
-}
-
-static void *vdr_data_thread(void *this_gen)
-{
- vdr_input_plugin_t *this = (vdr_input_plugin_t *) this_gen;
-
- LOGDBG("Data thread started");
-
- const int priority = -1;
- errno = 0;
- if((nice(priority) == -1) && errno)
- LOGDBG("Data thread: Can't nice to value: %d", priority);
-
- if(this->udp || this->rtp) {
- while(this->control_running) {
- if(vdr_plugin_read_net_udp(this) == XIO_ERROR)
- break;
- pthread_testcancel();
- }
- } else {
- while(this->control_running) {
- if(vdr_plugin_read_net_tcp(this) == XIO_ERROR)
- break;
- pthread_testcancel();
- }
- }
-
- this->control_running = 0;
- LOGDBG("Data thread terminated");
- pthread_exit(NULL);
-}
-
-#ifdef TEST_PIP
-static int write_slave_stream(vdr_input_plugin_t *this, const char *data, int len)
-{
- fifo_input_plugin_t *slave;
- buf_element_t *buf;
-
- TRACE("write_slave_stream (%d bytes)", len);
-
- if(!this->pip_stream) {
- LOGMSG("Detected new video stream 0x%X", (unsigned int)data[3]);
- LOGMSG(" no xine stream yet, trying to create ...");
- vdr_plugin_parse_control((input_plugin_t*)this, "SUBSTREAM 0xE1 50 50 288 196");
- }
- if(!this->pip_stream) {
- LOGMSG(" pip substream: no stream !");
- return -1;
- }
- /*LOGMSG(" pip substream open, queuing data");*/
-
- slave = (fifo_input_plugin_t*)this->pip_stream->input_plugin;
- if(!slave) {
- LOGMSG(" pip substream: no input plugin !");
- return len;
- }
-
- if(slave->buffer_pool->num_free(slave->buffer_pool) < 20) {
- /*LOGMSG(" pip substream: fifo almost full !");*/
- xine_usec_sleep(3000);
- return 0;
- }
- buf = slave->buffer_pool->buffer_pool_try_alloc(slave->buffer_pool);
- if(!buf) {
- LOGMSG(" pip substream: fifo full !");
- return 0;
- }
- if(len > buf->max_size) {
- LOGMSG(" pip substream: buf too small");
- buf->free_buffer(buf);
- return len;
- }
-
- buf->content = buf->mem;
- buf->size = len;
- buf->type = BUF_DEMUX_BLOCK;
- xine_fast_memcpy(buf->content, data, len);
- slave->buffer->put(slave->buffer, buf);
- return len;
-}
-#endif
-
-static int vdr_plugin_write(vdr_input_plugin_if_t *this_if, const char *data, int len)
-{
- vdr_input_plugin_t *this = (vdr_input_plugin_t *) this_if;
- buf_element_t *buf = NULL;
- static int overflows = 0;
-
- if(this->slave_stream)
- return len;
-
-#ifdef TEST_PIP
- /* some (older?) VDR recordings have video PID != 0xE0 ... */
-
- /* slave (PES) */
- if(!buf[0] && ((uint8_t*)data)[3] > 0xe0 && ((uint8_t*)data)[3] <= 0xef)
- return write_slave_stream(this, data, len);
-#endif
-
- TRACE("vdr_plugin_write (%d bytes)", len);
-
- VDR_ENTRY_LOCK(0);
-
- buf = get_buf_element(this, len, 0);
- if(!buf) {
- /* need counter to filter non-fatal overflows
- (VDR is not polling for every PES packet) */
- if(overflows++ > 1)
- LOGMSG("vdr_plugin_write: buffer overflow ! (%d bytes)", len);
- VDR_ENTRY_UNLOCK();
- xine_usec_sleep(5*1000);
- errno = EAGAIN;
- return 0; /* EAGAIN */
- }
- overflows = 0;
-
- if(len > buf->max_size) {
- LOGMSG("vdr_plugin_write: PES too long (%d bytes, max size "
- "%d bytes), data ignored !", len, buf->max_size);
- buf->free_buffer(buf);
-/* curr_pos will be invalid when this point is reached ! */
- VDR_ENTRY_UNLOCK();
- return len;
- }
-
- buf->size = len;
- xine_fast_memcpy(buf->content, data, len);
- this->block_buffer->put(this->block_buffer, buf);
-
- VDR_ENTRY_UNLOCK();
-
- TRACE("vdr_plugin_write returns %d", len);
-
- return len;
-}
-
-/*
- * vdr_plugin_keypress()
- *
- * - Called by frontend
- * - forward (input) events to VDR
- *
- * It is safe to cancel thread while this function is being executed.
- */
-static int post_vdr_event(vdr_input_plugin_if_t *this_if, const char *msg)
-{
- vdr_input_plugin_t *this = (vdr_input_plugin_t *) this_if;
-
- if (msg && this->fd_control >= 0)
- return write_control (this, msg);
-
- LOGMSG("post_vdr_event: error ! \"%s\" not delivered.", msg ?: "<null>");
- return -1;
-}
-
-
-/******************************* Plugin **********************************/
-
-#if XINE_VERSION_CODE < 10190
-static off_t vdr_plugin_read (input_plugin_t *this_gen, char *buf_gen, off_t len)
-#else
-static off_t vdr_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t len)
-#endif
-{
- memset(buf_gen, 0, len);
- return 0;
-}
-
-/*#define CACHE_FIRST_IFRAME*/
-#ifdef CACHE_FIRST_IFRAME
-# include "cache_iframe.c"
-#endif
-
-/*
- * update_frames()
- *
- * Update frame type counters.
- * Collected information is used to start replay when enough data has been buffered
- */
-static uint8_t update_frames(vdr_input_plugin_t *this, const uint8_t *data, int len)
-{
- uint8_t type = pes_get_picture_type(data, len);
-
- if (!this->I_frames)
- this->P_frames = this->B_frames = 0;
-
- switch (type) {
- case I_FRAME: this->I_frames++; LOGSCR("I"); break;
- case P_FRAME: this->P_frames++; LOGSCR("P"); break;
- case B_FRAME: this->B_frames++; LOGSCR("B"); break;
- default: break;
- }
- return type;
-}
-
-/*
- * Preprocess buffer before passing it to demux
- * - handle discard
- * - handle display blanking
- * - handle stream start
- * - strip network headers
- */
-static buf_element_t *preprocess_buf(vdr_input_plugin_t *this, buf_element_t *buf)
-{
- /* internal control bufs */
- if(buf->type == CONTROL_BUF_BLANK) {
-
- pthread_mutex_lock(&this->lock);
- if(!this->stream_start) {
- LOGMSG("BLANK in middle of stream! bufs queue %d , video_fifo %d",
- this->block_buffer->fifo_size,
- this->stream->video_fifo->fifo_size);
- } else {
- vdr_x_demux_control_newpts(this->stream, 0, BUF_FLAG_SEEK);
- queue_blank_yv12(this);
- }
- pthread_mutex_unlock(&this->lock);
-
- buf->free_buffer(buf);
- return NULL;
- }
-
- /* control buffers go always to demuxer */
- if ((buf->type & BUF_MAJOR_MASK) == BUF_CONTROL_BASE)
- return buf;
-
- pthread_mutex_lock(&this->lock);
-
- /* Update stream position and remove network headers */
- strip_network_headers(this, buf);
-
- /* Update stream position */
- if ((buf->type & BUF_MAJOR_MASK) == BUF_DEMUX_BLOCK) {
- this->curpos += buf->size;
- this->curframe ++;
- } else {
- if ((buf->type & BUF_MAJOR_MASK) == BUF_VIDEO_BASE) {
- /* demuxed video */
- pthread_mutex_unlock(&this->lock);
- this->stream->video_fifo->put(this->stream->video_fifo, buf);
- return NULL;
- }
- LOGMSG("!!! curpos not updated for unregonized buffer type 0x%x !!!", buf->type);
- }
-
- /* Handle discard */
- if (this->discard_index > this->curpos && this->guard_index < this->curpos) {
- pthread_mutex_unlock(&this->lock);
- buf->free_buffer(buf);
- return NULL;
- }
-
- /* ignore UDP/RTP "idle" padding */
- if (!DATA_IS_TS(buf->content) && IS_PADDING_PACKET(buf->content)) {
- pthread_mutex_unlock(&this->lock);
- return buf;
- }
-
- /* Send current PTS ? */
- if (this->stream_start) {
- this->stream_start = 0;
- pthread_mutex_lock (&this->stream->first_frame_lock);
- this->stream->first_frame_flag = 2;
- pthread_mutex_unlock (&this->stream->first_frame_lock);
- }
-
- pthread_mutex_unlock(&this->lock);
- return buf;
-}
-
-/*
- * Postprocess buffer before passing it to demuxer
- * - Signal new pts upstream after stream changes
- * - Special handling for still images
- * - Count video frames for SCR tuning
- * - Special handling for ffmpeg mpeg2 video decoder
- */
-static void postprocess_buf(vdr_input_plugin_t *this, buf_element_t *buf, int need_pause)
-{
-#ifdef CACHE_FIRST_IFRAME
- cache_iframe(this, buf);
-#endif
-
- if (buf->type != BUF_DEMUX_BLOCK || DATA_IS_TS(buf->content))
- return;
-
-#ifdef TEST_SCR_PAUSE
- if(need_pause)
- scr_tuning_set_paused(this);
-#endif
-
- /* generated still images start with empty video PES, PTS = 0.
- Reset metronom pts so images will be displayed */
- if(this->still_mode && buf->size == 14) {
- int64_t pts = pes_get_pts(buf->content, buf->size);
- if(pts==0) {
- vdr_x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK);
- /* delay frame 10ms (9000 ticks) */
- /*buf->content[12] = (uint8_t)((10*90) >> 7);*/
- }
- }
-
- /* Count video frames for SCR tuning algorithm */
- if(this->live_mode && this->I_frames < 4)
- if(IS_VIDEO_PACKET(buf->content) && buf->size > 32)
- update_frames(this, buf->content, buf->size);
-}
-
-static void handle_disconnect(vdr_input_plugin_t *this)
-{
- LOGMSG("read_block: no data source, returning NULL");
-
- flush_all_fifos (this, 0);
-
- set_playback_speed(this, 1);
- this->live_mode = 0;
- reset_scr_tuning(this, XINE_FINE_SPEED_NORMAL);
- this->stream->emergency_brake = 1;
-
- this->control_running = 0;
- errno = ENOTCONN;
-}
-
-static int adjust_scr_speed(vdr_input_plugin_t *this)
-{
- int need_pause = 0;
-
- if(pthread_mutex_lock(&this->lock)) {
- LOGERR("adjust_scr_speed: pthread_mutex_lock failed");
- return 0;
- }
-
- if( (!this->live_mode && (this->fd_control < 0 ||
- this->fixed_scr)) ||
- this->slave_stream) {
- if(this->scr_tuning)
- reset_scr_tuning(this, this->speed_before_pause);
- } else {
-#ifdef TEST_SCR_PAUSE
- if(this->stream_start) {
- reset_scr_tuning(this, this->speed_before_pause);
- need_pause = 1;
- } else {
- vdr_adjust_realtime_speed(this);
- }
-#else
- vdr_adjust_realtime_speed(this);
-#endif
- }
- pthread_mutex_unlock(&this->lock);
-
- return need_pause;
-}
-
-static buf_element_t *vdr_plugin_read_block (input_plugin_t *this_gen,
- fifo_buffer_t *fifo, off_t todo)
-{
- vdr_input_plugin_t *this = (vdr_input_plugin_t *) this_gen;
- buf_element_t *buf = NULL;
- int need_pause = 0;
-
- TRACE("vdr_plugin_read_block");
-
- if (this->slave_stream) {
- xine_usec_sleep(50*1000);
- if (this->slave_stream) {
- errno = EAGAIN;
- return NULL;
- }
- }
-
- do {
-
- /* check for disconnection/termination */
- if (!this->funcs.push_input_write /* reading from socket */ &&
- !this->control_running) {
- /* disconnected ? */
- handle_disconnect(this);
- return NULL;
- }
-
- /* Return immediately if demux_action_pending flag is set */
- if (this->stream->demux_action_pending) {
- errno = EINTR;
- return NULL;
- }
-
-#ifdef CACHE_FIRST_IFRAME
- if (NULL != (buf = get_cached_iframe(this)))
- return buf;
-#endif
-
- /* adjust SCR speed */
- need_pause = adjust_scr_speed(this);
-
- /* get next buffer */
- buf = fifo_buffer_timed_get(this->block_buffer, 100);
-
- if (!buf) {
- if (!this->is_paused &&
- !this->still_mode &&
- !this->is_trickspeed &&
- !this->slave_stream &&
- this->stream->video_fifo->fifo_size <= 0) {
-
- this->read_timeouts++;
- if (this->read_timeouts > 80) {
- LOGMSG("No data in 8 seconds, queuing no signal image");
- queue_nosignal(this);
- this->read_timeouts = 0;
- }
- } else {
- this->read_timeouts = 0;
- }
- errno = this->stream->demux_action_pending ? EINTR : EAGAIN;
- return NULL;
- }
- this->read_timeouts = 0;
-
- if (! (buf = preprocess_buf(this, buf)))
- continue;
-
- } while (!buf);
-
- postprocess_buf(this, buf, need_pause);
-
- TRACE("vdr_plugin_read_block: return data, pos end = %" PRIu64, this->curpos);
- return buf;
-}
-
-static off_t vdr_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin)
-{
- return -1;
-}
-
-static off_t vdr_plugin_get_length (input_plugin_t *this_gen)
-{
- return -1;
-}
-
-static uint32_t vdr_plugin_get_capabilities (input_plugin_t *this_gen)
-{
- return
-#ifdef INPUT_CAP_NOCACHE
- INPUT_CAP_NOCACHE |
-#endif
- INPUT_CAP_BLOCK;
-}
-
-static uint32_t vdr_plugin_get_blocksize (input_plugin_t *this_gen)
-{
- return 2048;
-}
-
-static off_t vdr_plugin_get_current_pos (input_plugin_t *this_gen)
-{
- vdr_input_plugin_t *this = (vdr_input_plugin_t *) this_gen;
- return this->discard_index > this->curpos ? this->discard_index : this->curpos;
-}
-
-static void vdr_plugin_dispose (input_plugin_t *this_gen)
-{
- vdr_input_plugin_t *this = (vdr_input_plugin_t *) this_gen;
- int local;
- int fd = -1, fc = -1;
-
- if(!this_gen)
- return;
-
- LOGDBG("vdr_plugin_dispose");
-
- /* stop slave stream */
- if (this->slave_stream) {
- LOGMSG("dispose: Closing slave stream");
- if (this->slave_event_queue)
- xine_event_dispose_queue (this->slave_event_queue);
- this->slave_event_queue = NULL;
- if(this->funcs.fe_control) {
- this->funcs.fe_control(this->funcs.fe_handle, "POST 0 Off\r\n");
- this->funcs.fe_control(this->funcs.fe_handle, "SLAVE 0x0\r\n");
- }
- xine_stop(this->slave_stream);
- xine_close(this->slave_stream);
- xine_dispose(this->slave_stream);
- this->slave_stream = NULL;
- }
-
- if(this->fd_control>=0)
- write_control(this, "CLOSE\r\n");
-
- this->control_running = 0;
-
- local = this->funcs.push_input_write ? 1 : 0;
- memset(&this->funcs, 0, sizeof(this->funcs));
-
- /* shutdown sockets */
- if(!local) {
- struct linger {
- int l_onoff; /* linger active */
- int l_linger; /* how many seconds to linger for */
- } l = {0,0};
-
- fd = this->fd_data;
- fc = this->fd_control;
-
- if(fc >= 0) {
- LOGDBG("Shutdown control");
- setsockopt(fc, SOL_SOCKET, SO_LINGER, &l, sizeof(struct linger));
- shutdown(fc, SHUT_RDWR);
- }
-
- if(fd >= 0 && this->tcp) {
- LOGDBG("Shutdown data");
- setsockopt(fc, SOL_SOCKET, SO_LINGER, &l, sizeof(struct linger));
- shutdown(fd, SHUT_RDWR);
- }
- }
-
- /* threads */
- if(!local && this->threads_initialized) {
- void *p;
- LOGDBG("Cancel control thread ...");
- /*pthread_cancel(this->control_thread);*/
- pthread_join (this->control_thread, &p);
- LOGDBG("Cancel data thread ...");
- /*pthread_cancel(this->data_thread);*/
- pthread_join (this->data_thread, &p);
- LOGDBG("Threads joined");
- }
-
- /* event queue(s) and listener threads */
- LOGDBG("Disposing event queues");
- if (this->event_queue) {
- xine_event_dispose_queue (this->event_queue);
- this->event_queue = NULL;
- }
-
- pthread_cond_broadcast(&this->engine_flushed);
- while(pthread_cond_destroy(&this->engine_flushed) == EBUSY) {
- LOGMSG("discard_signal busy !");
- pthread_cond_broadcast(&this->engine_flushed);
- xine_usec_sleep(10);
- }
-
- /* destroy mutexes (keep VDR out) */
- LOGDBG("Destroying mutexes");
- while(pthread_mutex_destroy(&this->vdr_entry_lock) == EBUSY) {
- LOGMSG("vdr_entry_lock busy ...");
- pthread_mutex_lock(&this->vdr_entry_lock);
- pthread_mutex_unlock(&this->vdr_entry_lock);
- }
- while(pthread_mutex_destroy(&this->lock) == EBUSY) {
- LOGMSG("lock busy ...");
- pthread_mutex_lock(&this->lock);
- pthread_mutex_unlock(&this->lock);
- }
- while(pthread_mutex_destroy(&this->fd_control_lock) == EBUSY) {
- LOGMSG("fd_control_lock busy ...");
- pthread_mutex_lock(&this->fd_control_lock);
- pthread_mutex_unlock(&this->fd_control_lock);
- }
-
- signal_buffer_pool_not_empty(this);
- signal_buffer_not_empty(this);
-
- /* close sockets */
- if(!local) {
- LOGDBG("Closing data connection");
- if(fd >= 0)
- if(close(fd))
- LOGERR("close(fd_data) failed");
- LOGDBG("Closing control connection");
- if(fc >= 0)
- if(close(fc))
- LOGERR("close(fd_control) failed");
- this->fd_data = this->fd_control = -1;
- LOGMSG("Connections closed.");
- }
-
- /* OSD */
- if (this->osd_manager) {
- this->osd_manager->dispose(this->osd_manager, this->stream);
- this->osd_manager = NULL;
- }
-
- /* restore video properties */
- if(this->video_properties_saved)
- set_video_properties(this, -1,-1,-1,-1,-1, -1, -1); /* restore defaults */
-
- signal_buffer_pool_not_empty(this);
- signal_buffer_not_empty(this);
-
- /* SCR */
- if (this->scr)
- this->scr->dispose(this->scr);
-
- free (this->mrl);
-
- if(this->udp_data)
- free_udp_data(this->udp_data);
-
- /* fifos */
- LOGDBG("Disposing fifos");
-
- /* need to get all buffer elements back before disposing own buffers ... */
- flush_all_fifos (this, 1);
-
- if (this->iframe_buffer)
- this->iframe_buffer->dispose(this->iframe_buffer);
- if (this->block_buffer)
- this->block_buffer->dispose(this->block_buffer);
- if (this->hd_buffer)
- this->hd_buffer->dispose(this->hd_buffer);
-
- free (this);
- LOGDBG("dispose done.");
-}
-
-#if XINE_VERSION_CODE > 10103
-static const char* vdr_plugin_get_mrl (input_plugin_t *this_gen)
-#else
-static char* vdr_plugin_get_mrl (input_plugin_t *this_gen)
-#endif
-{
- vdr_input_plugin_t *this = (vdr_input_plugin_t *) this_gen;
- return this->mrl;
-}
-
-static int vdr_plugin_get_optional_data (input_plugin_t *this_gen,
- void *data, int data_type)
-{
-#ifdef INPUT_OPTIONAL_DATA_DEMUXER
- if (data_type == INPUT_OPTIONAL_DATA_DEMUXER) {
- static const char demux_name[] = "xvdr";
- *((const char **)data) = demux_name;
- return INPUT_OPTIONAL_SUCCESS;
- }
-#endif
- return INPUT_OPTIONAL_UNSUPPORTED;
-}
-
-static int vdr_plugin_open(input_plugin_t *this_gen)
-{
- vdr_input_plugin_t *this = (vdr_input_plugin_t *) this_gen;
- xine_t *xine = this->class->xine;
-
- this->event_queue = xine_event_new_queue (this->stream);
- xine_event_create_listener_thread (this->event_queue, vdr_event_cb, this);
-
- this->buffer_pool = this->stream->video_fifo;
-
- /* enable resample method */
- xine->config->update_num(xine->config, "audio.synchronization.av_sync_method", 1);
-
- /* register our own scr provider */
- this->scr = adjustable_scr_start(this->class->xine);
- if (!this->scr)
- LOGMSG("adjustable_scr_start() FAILED !");
- this->scr_live_sync = 1;
-
- this->scr_tuning = SCR_TUNING_OFF;
- this->curpos = 0;
-
- /* buffer */
- this->block_buffer = fifo_buffer_new(this->stream, 4, 0x10000+64); /* dummy buf to be used before first read and for big PES frames */
-
- /* OSD */
- this->osd_manager = init_osd_manager();
-
- /* sync */
- pthread_mutex_init (&this->lock, NULL);
- pthread_mutex_init (&this->vdr_entry_lock, NULL);
- pthread_mutex_init (&this->fd_control_lock, NULL);
- pthread_cond_init (&this->engine_flushed, NULL);
-
- return 1;
-}
-
-static int vdr_plugin_open_local (input_plugin_t *this_gen)
-{
- LOGDBG("vdr_plugin_open_local");
- return vdr_plugin_open(this_gen);
-}
-
-static void set_recv_buffer_size(int fd, int max_buf)
-{
- /* try to have larger receiving buffer */
-
- /*while(max_buf) {*/
- if(setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &max_buf, sizeof(int)) < 0) {
- LOGERR("setsockopt(SO_RCVBUF,%d) failed", max_buf);
- /*max_buf >>= 1;*/
- } else {
- unsigned int tmp = 0, len = sizeof(int);;
- if(getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &tmp, &len) < 0) {
- LOGERR("getsockopt(SO_RCVBUF,%d) failed", max_buf);
- /*max_buf >>= 1;*/
- } else if(tmp != 2*max_buf) {
- LOGDBG("setsockopt(SO_RCVBUF): got %d bytes", tmp);
- /*max_buf >>= 1;*/
- }
- }
- /*}*/
- max_buf = 256;
- /* not going to send anything, so shrink send buffer ... */
- setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(int));
-}
-
-static int alloc_udp_data_socket(int firstport, int trycount, int *port)
-{
- int fd, one = 1;
- struct sockaddr_in name;
-
- name.sin_family = AF_INET;
- name.sin_port = htons(firstport);
- name.sin_addr.s_addr = htonl(INADDR_ANY);
-
- fd = socket(PF_INET, SOCK_DGRAM, 0/*IPPROTO_UDP*/);
-
- set_recv_buffer_size(fd, KILOBYTE(512));
-
- if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int)) < 0)
- LOGERR("UDP data stream: setsockopt(SO_REUSEADDR) failed");
-
- while(bind(fd, (struct sockaddr *)&name, sizeof(name)) < 0) {
- if(!--trycount) {
- LOGMSG("UDP Data stream: bind error, no free port found");
- close(fd);
- return -1;
- }
- LOGERR("UDP Data stream: bind error, port %d: %s",
- name.sin_port, strerror(errno));
- name.sin_port = htons(++firstport);
- }
-
- *port = ntohs(name.sin_port);
- return fd;
-}
-
-static int connect_control_stream(vdr_input_plugin_t *this, const char *host,
- int port, int *client_id)
-{
- char tmpbuf[256];
- int fd_control;
- int saved_fd = this->fd_control, one = 1;
-
- /* Connect to server */
- this->fd_control = fd_control = _x_io_tcp_connect(this->stream, host, port);
-
- if(fd_control < 0 ||
- XIO_READY != _x_io_tcp_connect_finish(this->stream, this->fd_control,
- 3000)) {
- LOGERR("Can't connect to tcp://%s:%d", host, port);
- close(fd_control);
- this->fd_control = saved_fd;
- return -1;
- }
-
- set_recv_buffer_size(fd_control, KILOBYTE(128));
-
- /* request control connection */
- if(_x_io_tcp_write(this->stream, fd_control, "CONTROL\r\n", 9) < 0) {
- LOGERR("Control stream write error");
- return -1;
- }
-
- /* Check server greeting */
- if(readline_control(this, tmpbuf, sizeof(tmpbuf)-1, 4) <= 0) {
- LOGMSG("Server not replying");
- close(fd_control);
- this->fd_control = saved_fd;
- return -1;
- }
- LOGMSG("Server greeting: %s", tmpbuf);
- if(!strncmp(tmpbuf, "Access denied", 13)) {
- LOGMSG("Maybe host address is missing from server-side svdrphosts.conf ?");
- close(fd_control);
- this->fd_control = saved_fd;
- return -1;
- }
- if(!strstr(tmpbuf, "VDR-") || !strstr(tmpbuf, "xineliboutput-") || !strstr(tmpbuf, "READY")) {
- LOGMSG("Unregonized greeting !");
- close(fd_control);
- this->fd_control = saved_fd;
- return -1;
- }
- /* Check server xineliboutput version */
- if(!strstr(tmpbuf, "xineliboutput-" XINELIBOUTPUT_VERSION " ")) {
- LOGMSG("-----------------------------------------------------------------");
- LOGMSG("WARNING: Client and server versions of xinelibout are different !");
- LOGMSG(" Client version (xine_input_vdr.so) is " XINELIBOUTPUT_VERSION);
- LOGMSG("-----------------------------------------------------------------");
- }
-
- /* Store our client-id */
- if(readline_control(this, tmpbuf, sizeof(tmpbuf)-1, 4) > 0 &&
- !strncmp(tmpbuf, "CLIENT-ID ", 10)) {
- LOGDBG("Got Client-ID: %s", tmpbuf+10);
- if(client_id)
- if(1 != sscanf(tmpbuf+10, "%d", client_id))
- *client_id = -1;
- } else {
- LOGMSG("Warning: No Client-ID !");
- if(*client_id)
- *client_id = -1;
- }
-
- /* set socket to non-blocking mode */
- fcntl (fd_control, F_SETFL, fcntl (fd_control, F_GETFL) | O_NONBLOCK);
-
- /* set control socket to deliver data immediately
- instead of waiting for full TCP segments */
- setsockopt(fd_control, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(int));
-
- this->fd_control = saved_fd;
- return fd_control;
-}
-
-
-static int connect_rtp_data_stream(vdr_input_plugin_t *this)
-{
- char cmd[256];
- unsigned int ip0, ip1, ip2, ip3, port;
- int fd=-1, one = 1, retries = 0, n;
- struct sockaddr_in multicastAddress;
- struct ip_mreq mreq;
- struct sockaddr_in server_address, sin;
- socklen_t len = sizeof(sin);
- stream_rtp_header_impl_t tmp_rtp;
-
- /* get server IP address */
- if(getpeername(this->fd_control, (struct sockaddr *)&server_address, &len)) {
- LOGERR("getpeername(fd_control) failed");
- /* close(fd); */
- return -1;
- }
-
- /* request RTP data transport from server */
-
- LOGDBG("Requesting RTP transport");
- if(_x_io_tcp_write(this->stream, this->fd_control, "RTP\r\n", 5) < 0) {
- LOGERR("Control stream write error");
- return -1;
- }
-
- cmd[0] = 0;
- if(readline_control(this, cmd, sizeof(cmd)-1, 4) < 8 ||
- strncmp(cmd, "RTP ", 4)) {
- LOGMSG("Server does not support RTP ? (%s)", cmd);
- return -1;
- }
-
- LOGDBG("Got: %s", cmd);
- if(5 != sscanf(cmd, "RTP %u.%u.%u.%u:%u", &ip0, &ip1, &ip2, &ip3, &port) ||
- ip0>0xff || ip1>0xff || ip2>0xff || ip3>0xff || port>0xffff) {
- LOGMSG("Server does not support RTP ? (%s)", cmd);
- return -1;
- }
-
- LOGMSG("Connecting (data) to rtp://@%u.%u.%u.%u:%u ...",
- ip0, ip1, ip2, ip3, port);
- multicastAddress.sin_family = AF_INET;
- multicastAddress.sin_port = htons(port);
- multicastAddress.sin_addr.s_addr = htonl((ip0<<24)|(ip1<<16)|(ip2<<8)|ip3);
-
- if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- LOGERR("socket() failed");
- return -1;
- }
- set_recv_buffer_size(fd, KILOBYTE(512));
-
- if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int)) < 0) {
- LOGERR("setsockopt(SO_REUSEADDR) failed");
- close(fd);
- return -1;
- }
-
- if(bind(fd, (struct sockaddr *)&multicastAddress,
- sizeof(multicastAddress)) < 0) {
- LOGERR("bind() to multicast address failed");
- close(fd);
- return -1;
- }
-
- /* Join to multicast group */
-
- memset(&mreq, 0, sizeof(mreq));
- mreq.imr_multiaddr.s_addr = multicastAddress.sin_addr.s_addr;
- mreq.imr_interface.s_addr = htonl(INADDR_ANY);
- /*mreq.imr_ifindex = 0;*/
- if(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) {
- LOGERR("setsockopt(IP_ADD_MEMBERSHIP) failed. No multicast in kernel?");
- close(fd);
- return -1;
- }
-
-retry_select:
-
- /* wait until server sends first RTP packet */
-
- if( XIO_READY != io_select_rd(fd)) {
- LOGDBG("Requesting RTP transport: RTP poll timeout");
- if(++retries < 10) {
- LOGDBG("Requesting RTP transport");
- if(_x_io_tcp_write(this->stream, this->fd_control, "RTP\r\n", 5) < 0) {
- LOGERR("Control stream write error");
- close(fd);
- return -1;
- }
- goto retry_select;
- }
- LOGMSG("Data stream connection timed out (RTP)");
- close(fd);
- return -1;
- }
-
-retry_recvfrom:
-
- /* check sender address */
-
- n = recvfrom(fd, &tmp_rtp, sizeof(tmp_rtp), 0, &sin, &len);
- if(sin.sin_addr.s_addr != server_address.sin_addr.s_addr) {
- uint32_t tmp_ip = ntohl(sin.sin_addr.s_addr);
- LOGMSG("Received UDP/RTP multicast from unknown sender: %d.%d.%d.%d:%d",
- ((tmp_ip>>24)&0xff), ((tmp_ip>>16)&0xff),
- ((tmp_ip>>8)&0xff), ((tmp_ip)&0xff),
- sin.sin_port);
-
- if(XIO_READY == _x_io_select(this->stream, fd, XIO_READ_READY, 0))
- goto retry_recvfrom;
- if(++retries < 4)
- goto retry_select;
- close(fd);
- return -1;
- }
-
- /* Succeed */
-
- this->udp_data = init_udp_data();
-
- /* store server address */
- memcpy(&this->udp_data->server_address, &sin, sizeof(sin));
- this->udp_data->ssrc = tmp_rtp.rtp_hdr.ssrc;
-
- return fd;
-}
-
-
-static int connect_udp_data_stream(vdr_input_plugin_t *this)
-{
- char cmd[256];
- struct sockaddr_in server_address, sin;
- socklen_t len = sizeof(sin);
- uint32_t tmp_ip;
- stream_udp_header_t tmp_udp;
- int n, retries = 0, port = -1, fd = -1;
-
- /* get server IP address */
- if(getpeername(this->fd_control, (struct sockaddr *)&server_address, &len)) {
- LOGERR("getpeername(fd_control) failed");
- /* close(fd); */
- return -1;
- }
- tmp_ip = ntohl(server_address.sin_addr.s_addr);
-
- LOGDBG("VDR server address: %d.%d.%d.%d",
- ((tmp_ip>>24)&0xff), ((tmp_ip>>16)&0xff),
- ((tmp_ip>>8)&0xff), ((tmp_ip)&0xff));
-
- /* allocate UDP socket */
- if((fd = alloc_udp_data_socket(DEFAULT_VDR_PORT, 20, &port)) < 0)
- return -1;
- /*LOGDBG("my UDP port is: %d", port);*/
-
-retry_request:
-
- /* request UDP data transport from server */
-
- LOGDBG("Requesting UDP transport");
- sprintf(cmd, "UDP %d\r\n", port);
- if(_x_io_tcp_write(this->stream, this->fd_control, cmd, strlen(cmd)) < 0) {
- LOGERR("Control stream write error");
- close(fd);
- return -1;
- }
-
- cmd[0] = 0;
- if(readline_control(this, cmd, sizeof(cmd)-1, 4) < 6 ||
- strncmp(cmd, "UDP OK", 6)) {
- LOGMSG("Server does not support UDP ? (%s)", cmd);
- return -1;
- }
-
-retry_select:
-
- /* wait until server sends first UDP packet */
-
- if( XIO_READY != io_select_rd(fd)) {
- LOGDBG("Requesting UDP transport: UDP poll timeout");
- if(++retries < 4)
- goto retry_request;
- LOGMSG("Data stream connection timed out (UDP)");
- close(fd);
- return -1;
- }
-
-retry_recvfrom:
-
- /* check sender address */
-
- n = recvfrom(fd, &tmp_udp, sizeof(tmp_udp), 0, &sin, &len);
- if(sin.sin_addr.s_addr != server_address.sin_addr.s_addr) {
- tmp_ip = ntohl(sin.sin_addr.s_addr);
- LOGMSG("Received UDP packet from unknown sender: %d.%d.%d.%d:%d",
- ((tmp_ip>>24)&0xff), ((tmp_ip>>16)&0xff),
- ((tmp_ip>>8)&0xff), ((tmp_ip)&0xff),
- sin.sin_port);
-
- if(XIO_READY == _x_io_select(this->stream, fd, XIO_READ_READY, 0))
- goto retry_recvfrom;
- if(++retries < 4)
- goto retry_select;
- close(fd);
- return -1;
- }
-
- /* Succeed */
-
- this->udp_data = init_udp_data();
-
- /* store server address */
- memcpy(&this->udp_data->server_address, &sin, sizeof(sin));
-
- return fd;
-}
-
-static int connect_tcp_data_stream(vdr_input_plugin_t *this, const char *host,
- int port)
-{
- struct sockaddr_in sinc;
- socklen_t len = sizeof(sinc);
- uint32_t ipc;
- char tmpbuf[256];
- int fd_data, n;
-
- /* Connect to server */
- fd_data = _x_io_tcp_connect(this->stream, host, port);
-
- if(fd_data < 0 ||
- XIO_READY != _x_io_tcp_connect_finish(this->stream, fd_data, 3000)) {
- LOGERR("Can't connect to tcp://%s:%d", host, port);
- close(fd_data);
- return -1;
- }
-
- set_recv_buffer_size(fd_data, KILOBYTE(128));
-
- /* request data connection */
-
- getsockname(this->fd_control, (struct sockaddr *)&sinc, &len);
- ipc = ntohl(sinc.sin_addr.s_addr);
- sprintf(tmpbuf,
- "DATA %d 0x%x:%u %d.%d.%d.%d\r\n",
- this->client_id,
- (unsigned int)ipc,
- (unsigned int)ntohs(sinc.sin_port),
- ((ipc>>24)&0xff), ((ipc>>16)&0xff), ((ipc>>8)&0xff), ((ipc)&0xff)
- );
- if(_x_io_tcp_write(this->stream, fd_data, tmpbuf, strlen(tmpbuf)) < 0) {
- LOGERR("Data stream write error (TCP)");
- } else if( XIO_READY != io_select_rd(fd_data)) {
- LOGERR("Data stream poll failed (TCP)");
- } else if((n=read(fd_data, tmpbuf, sizeof(tmpbuf))) <= 0) {
- LOGERR("Data stream read failed (TCP)");
- } else if(n<6 || strncmp(tmpbuf, "DATA\r\n", 6)) {
- tmpbuf[n] = 0;
- LOGMSG("Server does not support TCP ? (%s)", tmpbuf);
- } else {
- /* succeed */
- /* set socket to non-blocking mode */
- fcntl (fd_data, F_SETFL, fcntl (fd_data, F_GETFL) | O_NONBLOCK);
- return fd_data;
- }
-
- close(fd_data);
- return -1;
-}
-
-static int connect_pipe_data_stream(vdr_input_plugin_t *this)
-{
- char tmpbuf[256];
- int fd_data = -1;
-
- /* check if IP address matches */
- if(!strstr(this->mrl, "127.0.0.1")) {
- struct sockaddr_in sinc;
- struct sockaddr_in sins;
- socklen_t len = sizeof(sinc);
- getsockname(this->fd_control, &sinc, &len);
- getpeername(this->fd_control, &sins, &len);
- if(sinc.sin_addr.s_addr != sins.sin_addr.s_addr) {
- LOGMSG("connect_pipe_data_stream: client ip=0x%x != server ip=0x%x !",
- (unsigned int)sinc.sin_addr.s_addr, (unsigned int)sins.sin_addr.s_addr);
-#if 0
- return -1;
-#endif
- }
- }
-
- _x_io_tcp_write(this->stream, this->fd_control, "PIPE\r\n", 6);
-
- if(readline_control(this, tmpbuf, sizeof(tmpbuf), 4) <= 0) {
- LOGMSG("Pipe request failed");
- } else if(strncmp(tmpbuf, "PIPE /", 6)) {
- LOGMSG("Server does not support pipes ? (%s)", tmpbuf);
- } else {
-
- LOGMSG("Connecting (data) to pipe://%s", tmpbuf+5);
- if((fd_data = open(tmpbuf+5, O_RDONLY|O_NONBLOCK)) < 0) {
- if(errno == ENOENT)
- LOGMSG("Pipe not found");
- else
- LOGERR("Pipe opening failed");
- } else {
- _x_io_tcp_write(this->stream, this->fd_control, "PIPE OPEN\r\n", 11);
- if(readline_control(this, tmpbuf, sizeof(tmpbuf)-1, 4) >6 &&
- !strncmp(tmpbuf, "PIPE OK", 7)) {
- fcntl (fd_data, F_SETFL, fcntl (fd_data, F_GETFL) | O_NONBLOCK);
- return fd_data;
- }
- LOGMSG("Data stream connection failed (PIPE)");
- }
- }
-
- close(fd_data);
- return -1;
-}
-
-static int vdr_plugin_open_net (input_plugin_t *this_gen)
-{
- vdr_input_plugin_t *this = (vdr_input_plugin_t *) this_gen;
- char tmpbuf[256];
- int err;
-
- LOGDBG("vdr_plugin_open_net %s", this->mrl);
-
- if(strchr(this->mrl, '#'))
- *strchr(this->mrl, '#') = 0;
- if((!strncasecmp(this->mrl, MRL_ID "+tcp://", MRL_ID_LEN+7) && (this->tcp=1)) ||
- (!strncasecmp(this->mrl, MRL_ID "+udp://", MRL_ID_LEN+7) && (this->udp=1)) ||
- (!strncasecmp(this->mrl, MRL_ID "+rtp://", MRL_ID_LEN+7) && (this->rtp=1)) ||
- (!strncasecmp(this->mrl, MRL_ID "+pipe://", MRL_ID_LEN+8)) ||
- (!strncasecmp(this->mrl, MRL_ID ":tcp://", MRL_ID_LEN+7) && (this->tcp=1)) ||
- (!strncasecmp(this->mrl, MRL_ID ":udp://", MRL_ID_LEN+7) && (this->udp=1)) ||
- (!strncasecmp(this->mrl, MRL_ID ":rtp://", MRL_ID_LEN+7) && (this->rtp=1)) ||
- (!strncasecmp(this->mrl, MRL_ID ":pipe://", MRL_ID_LEN+8)) ||
- (!strncasecmp(this->mrl, MRL_ID "://", MRL_ID_LEN+3))) {
-
- char *phost = strdup(strstr(this->mrl, "//") + 2);
- char host[256];
- char *port = strchr(phost, ':');
- int iport;
- int one = 1;
- if(port) *port++ = 0;
- iport = port ? atoi(port) : DEFAULT_VDR_PORT;
- strn0cpy(host, phost, 254);
- /*host[sizeof(host)-1] = 0;*/
- free(phost);
- /* TODO: use multiple input plugins - tcp/udp/file */
-
- /* connect control stream */
-
- LOGMSG("Connecting (control) to tcp://%s:%d ...", host, iport);
- this->fd_control = connect_control_stream(this, host, iport,
- &this->client_id);
- if (this->fd_control < 0) {
- LOGERR("Can't connect to tcp://%s:%d", host, iport);
- return 0;
- }
- setsockopt(this->fd_control, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(int));
-
- LOGMSG("Connected (control) to tcp://%s:%d", host, iport);
-
- /* connect data stream */
-
- /* try pipe ? */
-
- if(!this->tcp && !this->udp && !this->rtp) {
- if((this->fd_data = connect_pipe_data_stream(this)) < 0) {
- LOGMSG("Data stream connection failed (PIPE)");
- } else {
- this->tcp = this->udp = this->tcp = 0;
- LOGMSG("Data stream connected (PIPE)");
- }
- }
-
- /* try RTP ? */
-
- if(this->fd_data < 0 && !this->udp && !this->tcp) {
- /* flush control buffer (if PIPE was tried first) */
- while(0 < read(this->fd_control, tmpbuf, 255)) ;
- if((this->fd_data = connect_rtp_data_stream(this)) < 0) {
- LOGMSG("Data stream connection failed (RTP)");
- this->rtp = 0;
- } else {
- this->rtp = 1;
- this->tcp = this->udp = 0;
- LOGMSG("Data stream connected (RTP)");
- }
- }
-
- /* try UDP ? */
-
- if(this->fd_data < 0 && !this->tcp) {
- LOGMSG("Connecting (data) to udp://%s ...", host);
- /* flush control buffer (if RTP was tried first) */
- while(0 < read(this->fd_control, tmpbuf, 255)) ;
- if((this->fd_data = connect_udp_data_stream(this)) < 0) {
- LOGMSG("Data stream connection failed (UDP)");
- this->udp = 0;
- } else {
- this->udp = 1;
- this->tcp = this->rtp = 0;
- LOGMSG("Data stream connected (UDP)");
- }
- }
-
- /* fall back to TCP ? */
-
- if(this->fd_data < 0) {
- LOGMSG("Connecting (data) to tcp://%s:%d ...", host, iport);
- this->tcp = 0;
- if((this->fd_data = connect_tcp_data_stream(this, host, iport)) < 0) {
- LOGMSG("Data stream connection failed (TCP)");
- this->tcp = 0;
- } else {
- this->tcp = 1;
- }
- if(this->tcp) {
- /* succeed */
- this->rtp = this->udp = 0;
- LOGMSG("Data stream connected (TCP)");
- } else {
- /* failed */
- close(this->fd_data);
- close(this->fd_control);
- this->fd_control = this->fd_data = -1;
- return 0;
- }
- }
-
- } else {
- LOGMSG("Unknown mrl (%s)", this->mrl);
- return 0;
- }
-
- if(!vdr_plugin_open(this_gen))
- return 0;
-
- queue_nosignal(this);
-
- this->control_running = 1;
- if ((err = pthread_create (&this->control_thread,
- NULL, vdr_control_thread, (void*)this)) != 0) {
- LOGERR("Can't create new thread");
- return 0;
- }
- if ((err = pthread_create (&this->data_thread,
- NULL, vdr_data_thread, (void*)this)) != 0) {
- LOGERR("Can't create new thread");
- return 0;
- }
-
- this->class->xine->port_ticket->acquire(this->class->xine->port_ticket, 1);
- if(!(this->stream->video_out->get_capabilities(this->stream->video_out) &
- VO_CAP_UNSCALED_OVERLAY))
- LOGMSG("WARNING: Video output driver reports it does not support unscaled overlays !");
- this->class->xine->port_ticket->release(this->class->xine->port_ticket, 1);
-
- this->threads_initialized = 1;
- return 1;
-}
-
-/**************************** Plugin class *******************************/
-/* Callback on default mrl change */
-static void vdr_class_default_mrl_change_cb(void *data, xine_cfg_entry_t *cfg)
-{
- vdr_input_class_t *class = (vdr_input_class_t *) data;
-
- class->mrls[0] = cfg->str_value;
-}
-
-/* callback on scr tuning step change */
-static void vdr_class_scr_tuning_step_cb(void *data, xine_cfg_entry_t *cfg)
-{
- vdr_input_class_t *class = (vdr_input_class_t *) data;
-
- class->scr_tuning_step = cfg->num_value / 1000000.0;
-}
-
-/* callback on OSD scaling mode change */
-static void vdr_class_fast_osd_scaling_cb(void *data, xine_cfg_entry_t *cfg)
-{
- vdr_input_class_t *class = (vdr_input_class_t *) data;
-
- class->fast_osd_scaling = cfg->num_value;
-}
-
-static input_plugin_t *vdr_class_get_instance (input_class_t *class_gen,
- xine_stream_t *stream,
- const char *data)
-{
- vdr_input_class_t *class = (vdr_input_class_t *) class_gen;
- vdr_input_plugin_t *this;
- char *mrl = (char *) data;
- int local_mode;
-
- LOGDBG("vdr_class_get_instance");
-
- if (strncasecmp (mrl, MRL_ID ":", MRL_ID_LEN+1) &&
- strncasecmp (mrl, MRL_ID "+", MRL_ID_LEN+1))
- return NULL;
-
- if(!strncasecmp(mrl, MRL_ID "+slave://0x", MRL_ID_LEN+11)) {
- LOGMSG("vdr_class_get_instance: slave stream requested");
- return fifo_class_get_instance(class_gen, stream, data);
- }
-
- this = calloc(1, sizeof(vdr_input_plugin_t));
-
- this->stream = stream;
- this->mrl = strdup(mrl);
- this->class = class;
-
- this->fd_data = -1;
- this->fd_control = -1;
-
- this->stream_start = 1;
- this->max_buffers = 10;
- this->autoplay_size = -1;
-
- local_mode = ( (!strncasecmp(mrl, MRL_ID "://", MRL_ID_LEN+3)) &&
- (strlen(mrl)==7))
- || (!strncasecmp(mrl, MRL_ID ":///", MRL_ID_LEN+4));
-
- if(!bSymbolsFound) {
- /* not running under VDR or vdr-sxfe/vdr-fbfe */
- if(local_mode) {
- LOGDBG("vdr or vdr-??fe not detected, forcing remote mode");
- local_mode = 0;
- }
- if(!strcasecmp(mrl, MRL_ID ":") ||
- !strcasecmp(mrl, MRL_ID ":/") ||
- !strcasecmp(mrl, MRL_ID "://") ||
- !strcasecmp(mrl, MRL_ID ":///")) {
- /* default to local host */
- free(this->mrl);
- this->mrl = strdup(MRL_ID "://127.0.0.1");
- LOGMSG("Changed mrl from %s to %s", mrl, this->mrl);
- }
- }
-
- this->input_plugin.open = local_mode ? vdr_plugin_open_local
- : vdr_plugin_open_net;
- this->input_plugin.get_mrl = vdr_plugin_get_mrl;
- this->input_plugin.dispose = vdr_plugin_dispose;
- this->input_plugin.input_class = class_gen;
-
- this->input_plugin.get_capabilities = vdr_plugin_get_capabilities;
- this->input_plugin.read = vdr_plugin_read;
- this->input_plugin.read_block = vdr_plugin_read_block;
- this->input_plugin.seek = vdr_plugin_seek;
- this->input_plugin.get_current_pos = vdr_plugin_get_current_pos;
- this->input_plugin.get_length = vdr_plugin_get_length;
- this->input_plugin.get_blocksize = vdr_plugin_get_blocksize;
- this->input_plugin.get_optional_data = vdr_plugin_get_optional_data;
-
- if(local_mode) {
- this->funcs.push_input_write = vdr_plugin_write;
- this->funcs.push_input_control= vdr_plugin_parse_control;
- this->funcs.push_input_osd = vdr_plugin_exec_osd_command;
- /*this->funcs.xine_input_event= NULL; -- frontend sets this */
- } else {
- this->funcs.post_vdr_event = post_vdr_event;
- }
-
- LOGDBG("vdr_class_get_instance done.");
- return &this->input_plugin;
-}
-
-/*
- * vdr input plugin class stuff
- */
-
-#if INPUT_PLUGIN_IFACE_VERSION < 18
-#if XINE_VERSION_CODE > 10103
-static const char *vdr_class_get_description (input_class_t *this_gen)
-#else
-static char *vdr_class_get_description (input_class_t *this_gen)
-#endif
-{
- return _("VDR (Video Disk Recorder) input plugin");
-}
-
-static const char *vdr_class_get_identifier (input_class_t *this_gen)
-{
- return MRL_ID;
-}
-#endif
-
-static char **vdr_plugin_get_autoplay_list(input_class_t *this_gen, int *num_files)
-{
- vdr_input_class_t *this = (vdr_input_class_t *)this_gen;
- *num_files = 1;
-
- return this->mrls;
-}
-
-static void vdr_class_dispose (input_class_t *this_gen)
-{
- vdr_input_class_t *this = (vdr_input_class_t *) this_gen;
- config_values_t *config = this->xine->config;
-
- config->unregister_callback(config, "media." MRL_ID ".default_mrl");
- config->unregister_callback(config, "media." MRL_ID ".osd.fast_scaling");
- config->unregister_callback(config, "media." MRL_ID ".scr_tuning_step");
- free (this);
-}
-
-static void *input_xvdr_init_class (xine_t *xine, void *data)
-{
- vdr_input_class_t *this;
- config_values_t *config = xine->config;
-
- SetupLogLevel();
-
- if(!bSymbolsFound) {
- if(xine->verbosity > 0) {
- iSysLogLevel = xine->verbosity + 1;
- LOGMSG("detected verbose logging xine->verbosity=%d, setting log level to %d:%s",
- xine->verbosity, iSysLogLevel,
- (iSysLogLevel < 1) ? "NONE" :
- (iSysLogLevel < 2) ? "ERRORS" :
- (iSysLogLevel < 3) ? "INFO" :
- (iSysLogLevel < 4) ? "DEBUG" :
- "VERBOSE DEBUG");
- }
- }
-
- this = calloc(1, sizeof (vdr_input_class_t));
-
- this->xine = xine;
-
- this->mrls[ 0 ] = config->register_string(config,
- "media." MRL_ID ".default_mrl",
- MRL_ID "://127.0.0.1#nocache;demux:mpeg_block",
- _("default VDR host"),
- _("The default VDR host"),
- 10, vdr_class_default_mrl_change_cb, (void *)this);
- this->mrls[ 1 ] = 0;
-
- this->fast_osd_scaling = config->register_bool(config,
- "media." MRL_ID ".fast_osd_scaling", 0,
- _("Fast (low-quality) OSD scaling"),
- _("Enable fast (lower quality) OSD scaling.\n"
- "Default is to use (slow) linear interpolation "
- "to calculate pixels and full palette re-allocation "
- "to optimize color palette.\n"
- "Fast method only duplicates/removes rows and columns "
- "and does not modify palette."),
- 10, vdr_class_fast_osd_scaling_cb,
- (void *)this);
-
- this->scr_tuning_step = config->register_num(config,
- "media." MRL_ID ".scr_tuning_step", 5000,
- _("SRC tuning step"),
- _("SCR tuning step width unit %1000000."),
- 10, vdr_class_scr_tuning_step_cb,
- (void *)this) / 1000000.0;
-
- this->input_class.get_instance = vdr_class_get_instance;
-#if INPUT_PLUGIN_IFACE_VERSION < 18
- this->input_class.get_identifier = vdr_class_get_identifier;
- this->input_class.get_description = vdr_class_get_description;
-#else
- this->input_class.identifier = MRL_ID;
- this->input_class.description = N_("VDR (Video Disk Recorder) input plugin");
-#endif
- this->input_class.get_autoplay_list = vdr_plugin_get_autoplay_list;
- this->input_class.dispose = vdr_class_dispose;
-
- LOGDBG("init class succeeded");
-
- return this;
-}
-
-/*
- * demuxer (xine/demux_xvdr.c)
- */
-
-void *demux_xvdr_init_class (xine_t *xine, void *data);
-
-static const demuxer_info_t demux_info_xvdr = {
- 100 /* priority */
-};
-
-/*
- * exported plugin catalog entry
- */
-
-const plugin_info_t xine_plugin_info[] __attribute__((visibility("default"))) = {
- /* type, API, "name", version, special_info, init_function */
- { PLUGIN_INPUT, INPUT_PLUGIN_IFACE_VERSION, MRL_ID, XINE_VERSION_CODE, NULL, input_xvdr_init_class },
-
- { PLUGIN_DEMUX, DEMUXER_PLUGIN_IFACE_VERSION, MRL_ID, XINE_VERSION_CODE, &demux_info_xvdr, demux_xvdr_init_class },
-
- { PLUGIN_NONE, 0, "", 0, NULL, NULL }
-};
-
-const plugin_info_t *xine_plugin_info_xvdr = xine_plugin_info;
-
-
diff --git a/xine_input_vdr.h b/xine_input_vdr.h
deleted file mode 100644
index 1039ca8c..00000000
--- a/xine_input_vdr.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * xine_input_vdr.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xine_input_vdr.h,v 1.10 2009-02-25 14:34:24 phintuka Exp $
- *
- */
-
-#ifndef __XINE_INPUT_VDR_H_
-#define __XINE_INPUT_VDR_H_
-
-#if defined __cplusplus
-extern "C" {
-#endif
-
-#include <xine/input_plugin.h>
-
-#include "xine_input_vdr_mrl.h"
-
-struct input_plugin_s;
-struct vdr_input_plugin_if_s;
-struct osd_command_s;
-struct frontend_s;
-
-typedef struct vdr_input_plugin_funcs_s {
- /* VDR --> input plugin (only local mode) */
- int (*push_input_write) (struct vdr_input_plugin_if_s *, const char *, int);
- int (*push_input_control)(struct vdr_input_plugin_if_s *, const char *);
- int (*push_input_osd) (struct vdr_input_plugin_if_s *, struct osd_command_s *);
-
- /* input plugin --> frontend (only local mode) */
- void (*xine_input_event) (const char *, const char *);
-
- /* input plugin --> frontend (remote mode) */
- int (*intercept_osd) (struct frontend_s *, struct osd_command_s *);
-
- /* input plugin --> frontend */
- void *(*fe_control) (struct frontend_s *, const char *);
- struct frontend_s *fe_handle;
-
- /* frontend --> input plugin (remote mode) */
- int (*post_vdr_event) (struct vdr_input_plugin_if_s *, const char *);
-} vdr_input_plugin_funcs_t;
-
-typedef struct vdr_input_plugin_if_s {
- input_plugin_t input_plugin;
- vdr_input_plugin_funcs_t f;
-} vdr_input_plugin_if_t;
-
-#define CONTROL_OK 0
-#define CONTROL_UNKNOWN -1
-#define CONTROL_PARAM_ERROR -2
-#define CONTROL_DISCONNECTED -3
-
-typedef struct grab_data_s {
- size_t size;
- char *data;
-} grab_data_t;
-
-#if defined __cplusplus
-}
-#endif
-
-
-#endif /*__XINE_INPUT_VDR_H_*/
-
diff --git a/xine_input_vdr_mrl.h b/xine_input_vdr_mrl.h
deleted file mode 100644
index 9924d5cc..00000000
--- a/xine_input_vdr_mrl.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * xine_input_vdr_mrl.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xine_input_vdr_mrl.h,v 1.1 2008-11-11 23:46:41 phintuka Exp $
- *
- */
-
-#ifndef XINE_INPUT_VDR_MRL_H
-#define XINE_INPUT_VDR_MRL_H
-
-# ifndef MRL_ID
-
-# define MRL_ID "xvdr"
-
-# undef MRL_ID_LEN
-# define MRL_ID_LEN 4
-
-# endif
-
-#endif
diff --git a/xine_input_vdr_net.h b/xine_input_vdr_net.h
deleted file mode 100644
index adb389aa..00000000
--- a/xine_input_vdr_net.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * xine_input_vdr_net.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xine_input_vdr_net.h,v 1.11 2009-03-24 19:35:22 phintuka Exp $
- *
- */
-
-#ifndef __XINE_INPUT_VDR_NET_H_
-#define __XINE_INPUT_VDR_NET_H_
-
-#include <arpa/inet.h>
-#ifdef __APPLE__
-# include <machine/endian.h>
-#else
-# include <endian.h>
-#endif
-
-#ifndef PACKED
-# define PACKED __attribute__((packed))
-#endif
-
-#include "tools/rtp.h" /* generic RTP headers */
-
-
-/*
- * Default port(s)
- */
-
-#ifndef DEFAULT_VDR_PORT
-# define DEFAULT_VDR_PORT 37890
-#endif
-
-/*
- * Byte-order conversions
- */
-
-#if __BYTE_ORDER == __BIG_ENDIAN
-#elif __BYTE_ORDER == __LITTLE_ENDIAN
-#else
-# error __BYTE_ORDER not defined !
-#endif
-
-#if __BYTE_ORDER == __BIG_ENDIAN
-# define ntohll(val) (val)
-# define htonll(val) (val)
-# define ntohull(val) (val)
-# define htonull(val) (val)
-#else
-# define ntohll(val) ((int64_t)ntohull((uint64_t)val))
-# define htonll(val) ((int64_t)htonull((uint64_t)val))
-# define ntohull(val) \
- ((uint64_t) ntohl((uint32_t)((val) >> 32)) | \
- (uint64_t) ntohl((uint32_t)(val)) << 32)
-# define htonull(val) \
- ((uint64_t) htonl((uint32_t)((val) >> 32)) | \
- (uint64_t) htonl((uint32_t)(val)) << 32)
-#endif
-
-
-/*
- * Network packet headers
- */
-
-#if defined __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * TCP / PIPE
- */
-
-typedef struct stream_tcp_header {
- uint64_t pos; /* stream position of first byte */
- uint32_t len; /* length of following PES packet */
-
- uint8_t payload[0];
-
-} PACKED stream_tcp_header_t;
-
-
-/*
- * UDP
- */
-
-typedef struct stream_udp_header {
- uint64_t pos; /* stream position of first byte */
- /* -1ULL and first bytes of frame != 00 00 01 */
- /* --> embedded control stream data */
- uint16_t seq; /* packet sequence number
- (for re-ordering and detecting missing packets) */
-
- uint8_t payload[0];
-
-} PACKED stream_udp_header_t;
-
-#define UDP_SEQ_MASK 0xff
-
-
-/*
- * RTP
- */
-
-/* xineliboutput RTP header extension */
-typedef struct stream_rtp_header_ext_x {
-
- stream_rtp_header_ext_t hdr;
-
- union {
- uint8_t raw[12]; /* 3 DWORDs */
- uint32_t rawd[3];
-
- union {
-
- struct {
- uint16_t padding0; /* must be padded to full DWORDs */
- stream_udp_header_t udphdr;
- } PACKED;
-
- struct {
- uint16_t padding1; /* must be padded to full DWORDs */
-
- uint64_t pos;
- uint16_t seq;
- } PACKED;
-
- } PACKED;
- } PACKED;
-
- uint8_t payload[0];
-
-} PACKED stream_rtp_header_ext_x_t;
-
-
-/* xineliboutput RTP header */
-typedef struct stream_rtp_header_impl {
-
- stream_rtp_header_t rtp_hdr;
- stream_rtp_header_ext_x_t hdr_ext;
-
- uint8_t payload[0];
-
-} PACKED stream_rtp_header_impl_t;
-
-
-#define RTP_VERSION 2
-#define RTP_MARKER_BIT 0x80
-#define RTP_HDREXT_BIT 0x10
-#define RTP_PAYLOAD_TYPE_PES 96 /* application */
-#define RTP_PAYLOAD_TYPE_TS 33 /* MPEG-TS */
-
-#define RTP_VERSION_BYTE (RTP_VERSION<<6)
-#define RTP_PAYLOAD_TYPE_PES_M (RTP_PAYLOAD_TYPE_PES|RTP_MARKER_BIT)
-#define RTP_PAYLOAD_TYPE_TS_M (RTP_PAYLOAD_TYPE_TS |RTP_MARKER_BIT)
-
-#define RTP_HEADER_EXT_X_SIZE 3 /* dwords, not counting stream_rtp_header_ext_t */
-#define RTP_HEADER_EXT_X_TYPE 0x54d3
-
-
-#if defined __cplusplus
-}
-#endif
-
-
-#endif /*__XINE_INPUT_VDR_NET_H_*/
-
diff --git a/xine_osd_command.h b/xine_osd_command.h
deleted file mode 100644
index 7988b0fb..00000000
--- a/xine_osd_command.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * xine_osd_command.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xine_osd_command.h,v 1.14 2008-12-19 15:08:19 phintuka Exp $
- *
- */
-
-#ifndef __XINE_OSD_COMMAND_H_
-#define __XINE_OSD_COMMAND_H_
-
-#ifndef PACKED
-# define PACKED __attribute__((packed))
-#endif
-
-
-#define MAX_OSD_OBJECT 50
-
-#if defined __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- OSD_Nop = 0, /* Do nothing ; used to initialize delay_ms counter */
- OSD_Size = 1, /* Set size of VDR OSD area (usually 720x576) */
- OSD_Set_RLE = 2, /* Create/update OSD window. Data is rle-compressed. */
- OSD_SetPalette = 3, /* Modify palette of already created OSD window */
- OSD_Move = 4, /* Change x/y position of already created OSD window */
- OSD_Close = 5, /* Close OSD window */
- OSD_Set_YUV = 6, /* Create/update OSD window. Data is in YUV420 format. */
- OSD_Commit = 7, /* All OSD areas have been updated, commit changes to display */
- OSD_Flush = 8 /* Flush all pending OSD operations immediately */
-} osd_command_id_t;
-
-#define OSDFLAG_YUV_CLUT 0x01 /* palette is in YUV format */
-#define OSDFLAG_REFRESH 0x02 /* OSD data refresh for new config, clients, etc. - no changes in bitmap */
-#define OSDFLAG_UNSCALED 0x04 /* xine-lib unscaled (hardware) blending */
-#define OSDFLAG_UNSCALED_LOWRES 0x08 /* unscaled blending when video resolution < .95 * 720x576 */
-
-#define OSDFLAG_TOP_LAYER 0x10 /* window is part of top layer OSD */
-
-typedef struct xine_clut_s {
- union {
- uint8_t cb /*: 8*/;
- uint8_t g;
- };
- union {
- uint8_t cr /*: 8*/;
- uint8_t b;
- };
- union {
- uint8_t y /*: 8*/;
- uint8_t r;
- };
- uint8_t alpha /*: 8*/;
-} PACKED xine_clut_t; /* from xine, alphablend.h */
-
-typedef struct xine_rle_elem_s {
- uint16_t len;
- uint16_t color;
-} PACKED xine_rle_elem_t; /* from xine */
-
-typedef struct osd_rect_s {
- uint16_t x1;
- uint16_t y1;
- uint16_t x2;
- uint16_t y2;
-} osd_rect_t;
-
-typedef struct osd_command_s {
- uint8_t size; /* size of osd_command_t struct */
-
- uint8_t cmd; /* osd_command_id_t */
-
- uint8_t wnd; /* OSD window handle */
- uint8_t layer; /* OSD layer */
-
- int64_t pts; /* execute at given pts */
- uint32_t delay_ms; /* execute 'delay_ms' ms after previous command (for same window). */
-
- uint16_t x; /* window position, x */
- uint16_t y; /* window position, y */
- uint16_t w; /* window width */
- uint16_t h; /* window height */
-
- uint32_t datalen; /* size of image data, in bytes */
- uint32_t num_rle;
- union {
- xine_rle_elem_t *data; /* RLE compressed image */
- uint8_t *raw_data;
- uint64_t dummy01;
- };
- uint32_t colors; /* palette size */
- union {
- xine_clut_t *palette; /* palette (YCrCb) */
- uint64_t dummy02;
- };
-
- osd_rect_t dirty_area;
- uint8_t flags;
- uint8_t scaling;
-
-} PACKED osd_command_t;
-
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-# define hton_osdcmd(cmdP) \
- do { \
- cmdP.pts = htonll(cmdP.pts); \
- cmdP.delay_ms = htonl (cmdP.delay_ms); \
- cmdP.x = htons (cmdP.x); \
- cmdP.y = htons (cmdP.y); \
- cmdP.w = htons (cmdP.w); \
- cmdP.h = htons (cmdP.h); \
- cmdP.datalen = htonl (cmdP.datalen); \
- cmdP.num_rle = htonl (cmdP.num_rle); \
- cmdP.colors = htonl (cmdP.colors); \
- cmdP.dirty_area.x1 = htons(cmdP.dirty_area.x1); \
- cmdP.dirty_area.y1 = htons(cmdP.dirty_area.y1); \
- cmdP.dirty_area.x2 = htons(cmdP.dirty_area.x2); \
- cmdP.dirty_area.y2 = htons(cmdP.dirty_area.y2); \
- } while(0)
-
-# define ntoh_osdcmd(cmdP) \
- do { \
- cmdP.pts = ntohll(cmdP.pts); \
- cmdP.delay_ms = ntohl (cmdP.delay_ms); \
- cmdP.x = ntohs (cmdP.x); \
- cmdP.y = ntohs (cmdP.y); \
- cmdP.w = ntohs (cmdP.w); \
- cmdP.h = ntohs (cmdP.h); \
- cmdP.datalen = ntohl (cmdP.datalen); \
- cmdP.num_rle = ntohl (cmdP.num_rle); \
- cmdP.colors = ntohl (cmdP.colors); \
- cmdP.dirty_area.x1 = ntohs(cmdP.dirty_area.x1); \
- cmdP.dirty_area.y1 = ntohs(cmdP.dirty_area.y1); \
- cmdP.dirty_area.x2 = ntohs(cmdP.dirty_area.x2); \
- cmdP.dirty_area.y2 = ntohs(cmdP.dirty_area.y2); \
- } while(0)
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-# define hton_osdcmd(cmd) do {} while(0)
-# define ntoh_osdcmd(cmd) do {} while(0)
-
-#else
-# error __BYTE_ORDER undefined !
-#endif
-
-
-#if defined __cplusplus
-}
-#endif
-
-#endif /*__XINE_OSD_COMMAND_H_*/
diff --git a/xine_post_audiochannel.c b/xine_post_audiochannel.c
deleted file mode 100644
index 9326162b..00000000
--- a/xine_post_audiochannel.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * xine_post_audiochannel.c: xine post plugin
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xine_post_audiochannel.c,v 1.6 2008-05-22 09:56:02 phintuka Exp $
- *
- */
-
-/*
- * Copyright (C) 2006 the xine project
- *
- * This file is part of xine, a free video player.
- *
- * xine is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * xine is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * $Id:
- *
- * audio channel selection post plugin by Petri Hintukainen 01/09/2006
- * based on upmix.c
- *
- * Removes left or right channel from stereo audio track
- * and fills both channels with same data.
- * This is useful with some bi-lingual DVB transmissions where
- * two different languages are sent on same (stereo) audio track.
- *
- */
-
-#include <xine/xine_internal.h>
-#include <xine/post.h>
-
-
-typedef struct audioch_parameters_s {
- int channel;
-} audioch_parameters_t;
-
-START_PARAM_DESCR(audioch_parameters_t)
-PARAM_ITEM(POST_PARAM_TYPE_BOOL, channel, NULL, 0, 1, 0,
- "select channel (0=left, 1=right)")
-END_PARAM_DESCR(audioch_param_descr)
-
-
-typedef struct audioch_post_plugin_s
-{
- post_plugin_t post_plugin;
- xine_post_in_t parameter_input;
-
- /* Config */
- int channel; /* 0 - left, 1 - right */
-
- /* Data */
- int channels;
-
-} audioch_post_plugin_t;
-
-
-/*
- * Port functions
- */
-#if XINE_VERSION_CODE < 10200
-static int audioch_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream,
- uint32_t bits, uint32_t rate, int mode)
-#else
-static int audioch_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream,
- ao_format_t format)
-#endif
-{
- post_audio_port_t *port = (post_audio_port_t *)port_gen;
- audioch_post_plugin_t *this = (audioch_post_plugin_t *)port->post;
-
- _x_post_rewire(&this->post_plugin);
- _x_post_inc_usage(port);
-
- port->stream = stream;
-#if XINE_VERSION_CODE < 10200
- port->bits = bits;
- port->rate = rate;
- port->mode = mode;
-
- this->channels = _x_ao_mode2channels(mode);
-
- return port->original_port->open(port->original_port, stream, bits, rate, mode );
-#else
- port->format = format;
-
- this->num_channels = _x_ao_mode2channels(format.mode);
-
- return port->original_port->open(port->original_port, stream, format);
-#endif
-
-
-}
-
-static void audioch_port_put_buffer (xine_audio_port_t *port_gen,
- audio_buffer_t *buf, xine_stream_t *stream)
-{
- post_audio_port_t *port = (post_audio_port_t *)port_gen;
- audioch_post_plugin_t *this = (audioch_post_plugin_t *)port->post;
- int i;
-
- if(this->channels == 2) {
-#if XINE_VERSION_CODE < 10200
- int step = buf->format.bits / 8;
-#else
- int step = sample_bytes_table[buf->format.sample_format];
-#endif
- audio_buffer_t *newbuf = port->original_port->get_buffer(port->original_port);
- newbuf->num_frames = buf->num_frames;
- newbuf->vpts = buf->vpts;
- newbuf->frame_header_count = buf->frame_header_count;
- newbuf->first_access_unit = buf->first_access_unit;
-#if XINE_VERSION_CODE < 10200
- newbuf->format.bits = buf->format.bits;
- newbuf->format.rate = buf->format.rate;
- newbuf->format.mode = buf->format.mode;
-#else
- newbuf->format = buf->format;
-#endif
- _x_extra_info_merge( newbuf->extra_info, buf->extra_info);
-
- switch(step) {
- case 1:
- for(i=0; i<buf->num_frames; i++)
- newbuf->mem[i*2+1] = newbuf->mem[i*2] = buf->mem[i*2+this->channel];
- break;
- case 2:
- for(i=0; i<buf->num_frames; i++)
- ((uint16_t*)newbuf->mem)[i*2+1] =
- ((uint16_t*)newbuf->mem)[i*2] = ((uint16_t*)buf->mem)[i*2+this->channel];
- break;
- case 3:
- for(i=0; i<buf->num_frames*3; i+=3) {
- newbuf->mem[i*2+0] = newbuf->mem[i*2+3] = buf->mem[i*2+0+3*this->channel];
- newbuf->mem[i*2+1] = newbuf->mem[i*2+4] = buf->mem[i*2+1+3*this->channel];
- newbuf->mem[i*2+2] = newbuf->mem[i*2+5] = buf->mem[i*2+2+3*this->channel];
- }
- break;
- case 4:
- for(i=0; i<buf->num_frames; i++)
- ((uint32_t*)newbuf->mem)[i*2+1] =
- ((uint32_t*)newbuf->mem)[i*2] = ((uint32_t*)buf->mem)[i*2+this->channel];
- break;
- default: /* ??? */
- memcpy(newbuf->mem, buf->mem, buf->num_frames*2*buf->format.bits);
- break;
- }
-
- /* pass data to original port */
- port->original_port->put_buffer(port->original_port, newbuf, stream );
-
- /* free data from origial buffer */
- buf->num_frames=0; /* UNDOCUMENTED, but hey, it works! Force old audio_out buffer free. */
- }
-
- port->original_port->put_buffer(port->original_port, buf, stream );
-}
-
-/*
- * Parameter functions
- */
-
-static xine_post_api_descr_t *audioch_get_param_descr(void)
-{
- return &audioch_param_descr;
-}
-
-static int audioch_set_parameters(xine_post_t *this_gen, void *param_gen)
-{
- audioch_post_plugin_t *this = (audioch_post_plugin_t *)this_gen;
- audioch_parameters_t *param = (audioch_parameters_t *)param_gen;
-
- this->channel = param->channel;
- return 1;
-}
-
-static int audioch_get_parameters(xine_post_t *this_gen, void *param_gen)
-{
- audioch_post_plugin_t *this = (audioch_post_plugin_t *)this_gen;
- audioch_parameters_t *param = (audioch_parameters_t *)param_gen;
-
- param->channel = this->channel;
- return 1;
-}
-
-static char *audioch_get_help(void) {
- return _("The audiochannel plugin is meant to take stereo audio and \n"
- "remove left or right channel by replacing both channels \n"
- "with the same data. \n"
- "\n"
- "Parameters \n"
- " channel: Select channel (left=0, right=1) \n"
- "\n"
- );
-}
-
-
-/*
- * Open / Close
- */
-
-static void audioch_dispose(post_plugin_t *this_gen)
-{
- if (_x_post_dispose(this_gen))
- free(this_gen);
-}
-
-static post_plugin_t *audioch_open_plugin(post_class_t *class_gen,
- int inputs,
- xine_audio_port_t **audio_target,
- xine_video_port_t **video_target)
-{
- audioch_post_plugin_t *this = calloc(1, sizeof(audioch_post_plugin_t));
- post_in_t *input;
- post_out_t *output;
- post_audio_port_t *port;
- xine_post_in_t *input_param;
-
- static xine_post_api_t post_api =
- { audioch_set_parameters, audioch_get_parameters,
- audioch_get_param_descr, audioch_get_help };
-
- if (!this || !audio_target || !audio_target[0] ) {
- free(this);
- return NULL;
- }
-
- _x_post_init(&this->post_plugin, 1, 0);
-
- port = _x_post_intercept_audio_port(&this->post_plugin,
- audio_target[ 0 ],
- &input, &output);
-
- port->new_port.open = audioch_port_open;
- port->new_port.put_buffer = audioch_port_put_buffer;
-
- input->xine_in.name = "audio in";
- output->xine_out.name = "audio out";
-
- this->post_plugin.xine_post.audio_input[ 0 ] = &port->new_port;
- this->post_plugin.dispose = audioch_dispose;
-
- input_param = &this->parameter_input;
- input_param->name = "parameters";
- input_param->type = XINE_POST_DATA_PARAMETERS;
- input_param->data = &post_api;
-#if XINE_VERSION_CODE >= 10102
- xine_list_push_back(this->post_plugin.input, input_param);
-#else
- xine_list_append_content(this->post_plugin.input, input_param);
-#endif
-
- this->channel = 0;
-
- this->channels = 0;
-
- return &this->post_plugin;
-}
-
-/*
- * Plugin class
- */
-
-#if POST_PLUGIN_IFACE_VERSION < 10
-static char *audioch_get_identifier(post_class_t *class_gen)
-{
- return "audiochannel";
-}
-
-static char *audioch_get_description(post_class_t *class_gen)
-{
- return "Select audio channel";
-}
-
-static void audioch_class_dispose(post_class_t *class_gen)
-{
- free(class_gen);
-}
-#endif
-
-static void *audioch_init_plugin(xine_t *xine, void *data)
-{
- post_class_t *class = calloc(1, sizeof(post_class_t));
-
- if(!class)
- return NULL;
-
- class->open_plugin = audioch_open_plugin;
-#if POST_PLUGIN_IFACE_VERSION < 10
- class->get_identifier = audioch_get_identifier;
- class->get_description = audioch_get_description;
- class->dispose = audioch_class_dispose;
-#else
- class->identifier = "audiochannel";
- class->description = N_("Select audio channel");
- class->dispose = default_post_class_dispose;
-#endif
-
- return class;
-}
-
-static post_info_t audioch_info = { XINE_POST_TYPE_AUDIO_FILTER };
-
-#ifndef NO_INFO_EXPORT
-plugin_info_t xine_plugin_info[] __attribute__((visibility("default"))) =
-{
- /* type, API, "name", version, special_info, init_function */
- { PLUGIN_POST, POST_PLUGIN_IFACE_VERSION, "audiochannel", XINE_VERSION_CODE, &audioch_info, &audioch_init_plugin },
- { PLUGIN_NONE, 0, "", 0, NULL, NULL }
-};
-#endif
diff --git a/xine_post_autocrop.c b/xine_post_autocrop.c
deleted file mode 100644
index 014bb95e..00000000
--- a/xine_post_autocrop.c
+++ /dev/null
@@ -1,1617 +0,0 @@
-/*
- * xine_post_autocrop.c: xine post plugin
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xine_post_autocrop.c,v 1.15 2008-11-01 07:07:12 phintuka Exp $
- *
- */
-
-/*
- * Copyright (C) 2006 the xine project
- *
- * This file is part of xine, a free video player.
- *
- * xine is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * xine is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- *
- * autocrop video filter by Petri Hintukainen 25/03/2006
- *
- * Automatically crop 4:3 letterbox frames to 16:9
- *
- * based on expand.c
- *
- *
- * TODO:
- * - more reliable border detection, including channel logo detection
- * - OSD re-positioning (?)
- *
- */
-
-#include <stdint.h>
-
-#include <xine/xine_internal.h>
-#include <xine/post.h>
-
-/*
- * Configuration
- */
-
-/*#define USE_CROP / * Crop frame in video_out instead of copying */
-/*#define MARK_FRAME Draw markers on detected boundaries */
-/*#define ENABLE_64BIT 1 Force using of 64-bit routines */
-/*#undef __MMX__ Disable MMX */
-/*#undef __SSE__ Disable SSE */
-/*#define FILTER2 Tighter Y-filter */
-
-# if defined(__SSE__)
-# warning Compiling with SSE support
-# include <xmmintrin.h>
-# elif defined(__MMX__)
-# warning Compiling with MMX support
-# include <mmintrin.h>
-# endif
-
-#if defined(__WORDSIZE)
-# if __WORDSIZE == 64
-# warning Compiling with 64-bit integer support
-# define ENABLE_64BIT (sizeof(int) > 32)
-# endif
-#endif
-
-/*#define TRACE printf*/
-#define TRACE(x...) do {} while(0)
-#define INFO printf
-
-
-/*
- * Constants
- */
-
-#define YNOISEFILTER (0xE0U)
-#define YSHIFTUP (0x05U)
-#define UVBLACK (0x80U)
-#define UVSHIFTUP (0x03U)
-#define UVNOISEFILTER (0xF8U)
-
-/* YV12 */
-#define YNOISEFILTER32 (YNOISEFILTER * 0x01010101U)
-#define YSHIFTUP32 (YSHIFTUP * 0x01010101U)
-#define UVBLACK32 (UVBLACK * 0x01010101U)
-#define UVSHIFTUP32 (UVSHIFTUP * 0x01010101U)
-#define UVNOISEFILTER32 (UVNOISEFILTER * 0x01010101U)
-
-#define YNOISEFILTER64 (YNOISEFILTER * UINT64_C(0x0101010101010101))
-#define YSHIFTUP64 (YSHIFTUP * UINT64_C(0x0101010101010101))
-#define UVBLACK64 (UVBLACK * UINT64_C(0x0101010101010101))
-#define UVSHIFTUP64 (UVSHIFTUP * UINT64_C(0x0101010101010101))
-#define UVNOISEFILTER64 (UVNOISEFILTER * UINT64_C(0x0101010101010101))
-
-/* YUY2 */
-/* TODO: should use normal/inverse order based on endianess */
-#if 0
-#define YUY2BLACK32 (UVBLACK * 0x00010001U)
-#define YUY2SHIFTUP32 (UVSHIFTUP * 0x00010001U)
-#define YUY2NOISEFILTER32 ((YNOISEFILTER * 0x01000100U)|(UVNOISEFILTER * 0x00010001U))
-#else
-#define YUY2BLACK32 (UVBLACK * 0x01000100U)
-#define YUY2SHIFTUP32 (UVSHIFTUP * 0x01000100U)
-#define YUY2NOISEFILTER32 ((YNOISEFILTER * 0x00010001U)|(UVNOISEFILTER * 0x01000100U))
-#endif
-
-#define YUY2BLACK64 (YUY2BLACK32 * UINT64_C(0x0000000100000001))
-#define YUY2SHIFTUP64 (YUY2SHIFTUP32 * UINT64_C(0x0000000100000001))
-#define YUY2NOISEFILTER64 (YUY2NOISEFILTER32 * UINT64_C(0x0000000100000001))
-
-#ifdef FILTER2
-/* tighter Y-filter: original black threshold is 0x1f ; here it is 0x1f - 0x0b = 0x14 */
-# define YUY2SHIFTUP32 ((UVSHIFTUP * 0x00010001U)|(YSHIFTUP * 0x01000100U))
-# undef __SSE__
-#endif
-
-
-#define START_TIMER_INIT (25) /* 1 second, unit: frames */
-#define HEIGHT_LIMIT_LIFETIME (60*25) /* 1 minute, unit: frames */
-
-#define LOGOSKIP (frame->width/4) /* skip logo (Y, top-left or top-right quarter) */
-
-/*
- * Plugin
- */
-
-typedef struct autocrop_parameters_s {
- int enable_autodetect;
- int enable_subs_detect;
- int soft_start;
- int stabilize;
-} autocrop_parameters_t;
-
-START_PARAM_DESCR(autocrop_parameters_t)
-PARAM_ITEM(POST_PARAM_TYPE_BOOL, enable_autodetect, NULL, 0, 1, 0,
- "enable automatic border detecton")
-PARAM_ITEM(POST_PARAM_TYPE_BOOL, enable_subs_detect, NULL, 0, 1, 0,
- "enable automatic subtitle detecton")
-PARAM_ITEM(POST_PARAM_TYPE_BOOL, soft_start, NULL, 0, 1, 0,
- "enable soft start of cropping")
-PARAM_ITEM(POST_PARAM_TYPE_BOOL, stabilize, NULL, 0, 1, 0,
- "stabilize cropping to 14:9, 16:9, (16:9+subs), 20:9, (20:9+subs)")
-END_PARAM_DESCR(autocrop_param_descr)
-
-
-typedef struct autocrop_post_plugin_s
-{
- post_plugin_t post_plugin;
-
- xine_post_in_t parameter_input;
-
- /* setup */
- int autodetect;
- int subs_detect;
- int soft_start;
- int stabilize;
-
- /* Current cropping status */
- int cropping_active;
-
- /* Detected bars */
- int start_line;
- int end_line;
- int crop_total;
-
- /* Previously detected bars
- - eliminate jumping if there is some noise at bar boundaries:
- don't change cropped area unless it has been stable for
- some time */
- int prev_start_line;
- int prev_end_line;
-
- /* Delayed start for cropping */
- int start_timer;
- int stabilize_timer;
-
- /* Last seen frame */
- int prev_height;
- int prev_width;
- int64_t prev_pts;
-
- /* eliminate jumping when when there are subtitles inside bottom bar:
- - when cropping is active and one frame has larger end_line
- than previous, we enlarge frame.
- - after this, cropping is not resetted to previous value unless
- bottom bar has been empty for certain time */
- int height_limit_active; /* true if detected possible subtitles in bottom area */
- int height_limit; /* do not crop bottom above this value (bottom of subtitles) */
- int height_limit_timer; /* counter how many following frames must have black
- bottom bar until returning to full cropping
- (used to reset height_limit when there are no subtitles) */
-} autocrop_post_plugin_t;
-
-
-/*
- * Black bar detection
- *
- * Detect black lines with simple noise filtering.
- * Line is "black" if Y-valus are less than 0x20 and
- * U/V values inside range 0x7d...0x84.
- * ~ 32 first and last pixels are not checked.
- *
- */
-
-static int blank_line_Y_C(uint8_t *data, int length);
-static int blank_line_UV_C(uint8_t *data, int length);
-static int blank_line_YUY2_C(uint8_t *data, int length);
-#if defined(ENABLE_64BIT)
-static int blank_line_Y_C64(uint8_t *data, int length);
-static int blank_line_UV_C64(uint8_t *data, int length);
-static int blank_line_YUY2_C64(uint8_t *data, int length);
-#endif
-#if defined(__MMX__)
-static int blank_line_Y_mmx(uint8_t *data, int length);
-static int blank_line_UV_mmx(uint8_t *data, int length);
-static int blank_line_YUY2_mmx(uint8_t *data, int length);
-#endif
-#if defined(__SSE__)
-static int blank_line_Y_sse(uint8_t *data, int length);
-static int blank_line_UV_sse(uint8_t *data, int length);
-static int blank_line_YUY2_sse(uint8_t *data, int length);
-#endif
-
-static int blank_line_Y_INIT(uint8_t *data, int length);
-static int blank_line_UV_INIT(uint8_t *data, int length);
-static int blank_line_YUY2_INIT(uint8_t *data, int length);
-
-static void autocrop_init_mm_accel(void);
-
-int (*blank_line_Y)(uint8_t *data, int length) = blank_line_Y_INIT;
-int (*blank_line_UV)(uint8_t *data, int length) = blank_line_UV_INIT;
-int (*blank_line_YUY2)(uint8_t *data, int length) = blank_line_YUY2_INIT;
-
-static int blank_line_Y_C(uint8_t *data, int length)
-{
- uint32_t *data32 = (uint32_t*)((((long int)data) + 32 + 3) & (~3)), r = 0;
-
- length -= 64; /* skip borders (2 x 32 pixels) */
- length /= 4; /* 4 bytes / loop */
-
-#ifdef FILTER2
- while(length) {
- /* shiftdown needs saturated unsigned element-wise substraction, available only in MMX ...*/
- /* -> use shiftup and looser noise filter for same result. */
- /* this needs special handling for large values */
- r = r | data32[--length]; /* this catches large values (0xf9 : 0xf9+0x7=0x100 === black) */
- r = r | (data32[length] + YSHIFTUP32); /* this catches small walues (0x1d...0x1f) */
- }
-#else
- while(length)
- r = r | data32[--length];
-#endif
-
- return !(r & YNOISEFILTER32);
-}
-
-static int blank_line_UV_C(uint8_t *data, int length)
-{
- uint32_t *data32 = (uint32_t*)((((long int)data) + 16 + 3) & (~3));
- uint32_t r1 = 0, r2 = 0;
-
- length -= 32; /* skip borders (2 x 32 pixels, 2 pix/byte) */
- length /= 4; /* 2 x 4 bytes / loop */
-
- while(length>0) {
- r1 = r1 | ((data32[--length] + UVSHIFTUP32) ^ UVBLACK32);
- r2 = r2 | ((data32[--length] + UVSHIFTUP32) ^ UVBLACK32);
- }
- return !((r1|r2) & (UVNOISEFILTER32));
-}
-
-#if defined(ENABLE_64BIT)
-static int blank_line_Y_C64(uint8_t *data, int length)
-{
- uint64_t *data64 = (uint64_t*)((((long int)data) + 32 + 7) & (~7)), r = 0;
-
- length -= 64; /* skip borders (2 x 32 pixels) */
- length /= 8; /* 8 bytes / loop */
-
-#ifdef FILTER2
- while(length) {
- r = r | data64[--length];
- r = r | (data64[length] + YSHIFTUP64);
- }
-#else
- while(length)
- r = r | data64[--length];
-#endif
-
- return !(r & YNOISEFILTER64);
-}
-#endif
-
-#if defined(ENABLE_64BIT)
-static int blank_line_UV_C64(uint8_t *data, int length)
-{
- uint64_t *data64 = (uint64_t*)((((long int)data) + 16 + 7) & (~7));
- uint64_t r1 = UINT64_C(0), r2 = UINT64_C(0);
-
- length -= 32; /* skip borders (2x32 pixels, 2 pix/byte) */
- length /= 8; /* 2 x 8 bytes / loop */
-
- while(length>0) {
- r1 = r1 | ((data64[--length] + UVSHIFTUP64) ^ UVBLACK64);
- r2 = r2 | ((data64[--length] + UVSHIFTUP64) ^ UVBLACK64);
- }
- return !((r1|r2) & (UVNOISEFILTER64));
-}
-#endif
-
-
-#if defined(__MMX__)
-typedef union {
- uint32_t u32[2];
- __m64 m64;
-} __attribute__((__aligned__ (8))) __m64_wrapper;
-#endif
-
-#if defined(__MMX__)
- int blank_line_Y_mmx(uint8_t *data, int length)
-{
-#ifdef FILTER2
- static const __m64_wrapper mask = {{YNOISEFILTER32, YNOISEFILTER32}};
- static const __m64_wrapper gshift = {{YSHIFTUP32, YSHIFTUP32}};
- register __m64 sum, sum2, shift = gshift.m64, val;
-#else
- static const __m64_wrapper mask = {{YNOISEFILTER32, YNOISEFILTER32}};
- register __m64 sum;
-#endif
- __m64 *data64 = (__m64*)(((long int)(data + 32 + 7)) & (~7));
-
- /*sum = _m_pxor(sum,sum);*/
- __asm__("pxor %0,%0" : "=y"(sum));
-
- length -= 64; /* skip borders (2 x 32 pixels) */
- length /= 8; /* 8 bytes / loop */
-
-#ifdef FILTER2
- __asm__("pxor %0,%0" : "=y"(sum2));
- while(length) {
- val = data64[--length];
- sum = _m_por(sum, val);
- sum2 = _m_por(sum2, _m_paddb(val, shift));
- }
- sum = _m_por(sum, sum2);
-#else
- while(length)
- sum = _m_por(sum, data64[--length]);
-#endif
-
- sum = _m_pand(sum, mask.m64);
- return 0 == _m_to_int(_m_packsswb(sum, sum));
-}
-#endif
-
-#if defined(__MMX__)
-static int blank_line_UV_mmx(uint8_t *data, int length)
-{
- static const __m64_wrapper gm_03 = {{UVSHIFTUP32, UVSHIFTUP32}};
- static const __m64_wrapper gm_f8 = {{UVNOISEFILTER32, UVNOISEFILTER32}};
- static const __m64_wrapper gm_80 = {{UVBLACK32, UVBLACK32}};
- __m64 *data64 = (__m64*)(((long int)(data) + 16 + 7) & (~7));
- register __m64 sum1, sum2, m_03, /*m_f8,*/ m_80;
-
- /*sum1 = _m_pxor(sum1, sum1); sum1 = _mm_setzero_si64(); */
- /*sum2 = _m_pxor(sum2, sum2); sum2 = _mm_setzero_si64(); */
- __asm__("pxor %0,%0" : "=y"(sum1));
- __asm__("pxor %0,%0" : "=y"(sum2));
-
- /* fetch static data to MMX registers */
- m_03 = gm_03.m64;
- /*m_f8 = gm_f8.m64;*/
- m_80 = gm_80.m64;
-
- length -= 32; /* skip borders (2 x 32 pixels, 2pix/byte) */
- length /= 8; /* 8 bytes / vector */
-
- do {
- /* process two 8-byte vectors */
- sum1 = _m_por(sum1,
- /* grab every byte that is not black (x ^ 0x80 != 0) */
- _m_pxor(
- /* filter noise: U/V of each "black" pixel should be 0x7d..0x84
- -> each black pixel should be 0x80 after (x+3) & 0xf8 */
- /*_m_pand(*/
- /* each black pixel should be 0x80..0x87 after adding 3 */
- _m_paddb(
- data64[length-1],
- m_03)/*,
- m_f8)*/,
- m_80));
- sum2 = _m_por(sum2,
- _m_pxor(
- /*_m_pand( */
- _m_paddb(
- data64[length-2],
- m_03)/*,
- m_f8)*/,
- m_80));
- length -= 2;
- } while(length>0);
-
- /* combine two result vectors (or), filter noise (and) */
- sum1 = _m_pand(_m_por(sum1,
- sum2),
- gm_f8.m64);
- /* result vector of black line is 0 */
- return 0 == _m_to_int(_m_packsswb(sum1, sum1));
-}
-#endif
-
-#if defined(__SSE__)
-typedef union {
- uint32_t u32[4];
- __m128 m128;
-} __attribute((__aligned__ (16))) __m128_wrapper;
-#endif
-
-#if defined(__SSE__)
-static int blank_line_Y_sse(uint8_t *data, int length)
-{
- static const __m128_wrapper gmask = {{YNOISEFILTER32, YNOISEFILTER32,
- YNOISEFILTER32, YNOISEFILTER32}};
- __m128 *data128 = (__m128*)(((long int)(data) + 32 + 15) & (~15));
- register __m128 sum1, sum2, zero, mask;
-
- length -= 64; /* skip borders (2 x 32 pixels) */
- length /= 16; /* 16 bytes / loop */
-
- /* Start prefetching data to CPU cache */
- _mm_prefetch(data128+length-1, _MM_HINT_NTA);
- _mm_prefetch(data128+length-3, _MM_HINT_NTA);
-
- /*
- * Process in two paraller loops, one 16 byte vector / each sub-loop
- * - grabs bytes with value larger than treshold
- */
-
- zero = _mm_setzero_ps();
- mask = gmask.m128;
- sum1 = zero;
- sum2 = zero;
-
- do {
- _mm_prefetch(data128+length-5, _MM_HINT_NTA);
- sum1 = _mm_or_ps(sum1, data128[--length]);
- sum2 = _mm_or_ps(sum2, data128[--length]);
- } while(length>0);
-
- return 0x0f == _mm_movemask_ps(_mm_cmpeq_ps(_mm_and_ps(_mm_or_ps(sum1,
- sum2),
- gmask.m128),
- _mm_setzero_ps()));
-}
-#endif
-
-#if defined(__SSE__)
-static int blank_line_UV_sse(uint8_t *data, int length)
-{
- uint8_t *top = data + length - 1;
- do {
- _mm_prefetch(top, _MM_HINT_NTA);
- _mm_prefetch(top-32, _MM_HINT_NTA);
- _mm_prefetch(top-64, _MM_HINT_NTA);
- _mm_prefetch(top-72, _MM_HINT_NTA);
- top -= 128;
- } while(top >= data);
-
- return blank_line_UV_mmx(data, length);
-}
-#endif
-
-static int blank_line_YUY2_C(uint8_t *data, int length)
-{
- uint32_t *data32 = (uint32_t*)((((long int)data) + 64 + 3) & (~3));
- uint32_t r1 = 0, r2 = 0;
-
- length -= 128; /* skip borders (2 x 32 pixels, 2 bytes/pixel) */
- length /= 4; /* 2 x 4 bytes / loop */
-
- while(length) {
- r1 = r1 | ((data32[--length] + YUY2SHIFTUP32) ^ YUY2BLACK32);
- r2 = r2 | ((data32[--length] + YUY2SHIFTUP32) ^ YUY2BLACK32);
- }
- return !((r1|r2) & YUY2NOISEFILTER32);
-}
-
-#if defined(ENABLE_64BIT)
-static int blank_line_YUY2_C64(uint8_t *data, int length)
-{
- uint64_t *data64 = (uint64_t*)((((long int)data) + 64 + 7) & (~7));
- uint64_t r1 = 0, r2 = 0;
-
- length -= 128; /* skip borders (2 x 32 pixels, 2 bytes/pixel) */
- length /= 8; /* 2 x 8 bytes / loop */
-
- while(length) {
- r1 = r1 | ((data64[--length] + YUY2SHIFTUP64) ^ YUY2BLACK64);
- r2 = r2 | ((data64[--length] + YUY2SHIFTUP64) ^ YUY2BLACK64);
- }
- return !((r1|r2) & YUY2NOISEFILTER64);
-}
-#endif
-
-#if defined(__MMX__)
-static int blank_line_YUY2_mmx(uint8_t *data, int length)
-{
- /* not implemented */
-
-# if !defined(ENABLE_64BIT)
- return blank_line_YUY2_C(data, length);
-# else
- return blank_line_YUY2_C64(data, length);
-# endif
-}
-#endif
-
-#if defined(__SSE__)
-static int blank_line_YUY2_sse(uint8_t *data, int length)
-{
- uint8_t *top = data + length - 1;
- do {
- _mm_prefetch(top, _MM_HINT_NTA);
- _mm_prefetch(top-32, _MM_HINT_NTA);
- _mm_prefetch(top-64, _MM_HINT_NTA);
- _mm_prefetch(top-72, _MM_HINT_NTA);
- top -= 128;
- } while(top >= data);
-
- return blank_line_YUY2_mmx(data, length);
-}
-#endif
-
-static void autocrop_init_mm_accel(void)
-{
- blank_line_Y = blank_line_Y_C;
- blank_line_UV = blank_line_UV_C;
- blank_line_YUY2 = blank_line_YUY2_C;
-
-#if defined(__SSE__)
- if(xine_mm_accel() & MM_ACCEL_X86_SSE) {
- INFO("autocrop_init_mm_accel: using SSE\n");
- blank_line_Y = blank_line_Y_sse;
- blank_line_UV = blank_line_UV_sse;
- blank_line_YUY2 = blank_line_YUY2_sse;
- return;
- }
-#endif
-#if defined(ENABLE_64BIT)
- if(ENABLE_64BIT) {
- INFO("autocrop_init_mm_accel: using 64-bit integer operations\n");
- blank_line_Y = blank_line_Y_C64;
- blank_line_UV = blank_line_UV_C64;
- blank_line_YUY2 = blank_line_YUY2_C64;
- return;
- }
-#endif
-#if defined(__MMX__)
- if(xine_mm_accel() & MM_ACCEL_X86_MMX) {
- /* mmx not faster than normal x64 (?) */
- INFO("autocrop_init_mm_accel: using MMX\n");
- blank_line_Y = blank_line_Y_mmx;
- blank_line_UV = blank_line_UV_mmx;
- blank_line_YUY2 = blank_line_YUY2_mmx;
- return;
- }
-#endif
- INFO("autocrop_init_mm_accel: no compatible acceleration methods found\n");
-}
-
-static int blank_line_Y_INIT(uint8_t *data, int length)
-{
- autocrop_init_mm_accel();
- return (*blank_line_Y)(data, length);
-}
-
-static int blank_line_UV_INIT(uint8_t *data, int length)
-{
- autocrop_init_mm_accel();
- return (*blank_line_UV)(data, length);
-}
-
-static int blank_line_YUY2_INIT(uint8_t *data, int length)
-{
- autocrop_init_mm_accel();
- return (*blank_line_YUY2)(data, length);
-}
-
-/*
- * Analyze frame
- * - if frame needs cropping set crop_top & crop_bottom
- */
-
-#ifdef MARK_FRAME
-int dbg_top=0, dbg_bottom=0;
-#endif
-
-static int analyze_frame_yv12(vo_frame_t *frame, int *crop_top, int *crop_bottom)
-{
- int y;
- int ypitch = frame->pitches[0];
- int upitch = frame->pitches[1];
- int vpitch = frame->pitches[2];
- uint8_t *ydata = frame->base[0];
- uint8_t *udata = frame->base[1];
- uint8_t *vdata = frame->base[2];
- int max_crop = (frame->height / 4) / 2; /* 4:3 --> 16:9 */
-
- /* from top -> down */
- ydata += 8 * ypitch; /* skip 8 first lines */
- udata += 4 * upitch;
- vdata += 4 * vpitch;
- for(y = 8; y <= max_crop *2 /* *2 = 20:9+subs -> 16:9 */ ; y += 2) {
- if( ! ( blank_line_UV(udata, (frame->width-LOGOSKIP)/2) ||
- blank_line_UV(udata+LOGOSKIP/2, (frame->width-LOGOSKIP)/2) ) ||
- ! ( blank_line_UV(vdata, (frame->width-LOGOSKIP)/2) ||
- blank_line_UV(vdata+LOGOSKIP/2, (frame->width-LOGOSKIP)/2) ) ||
- ! ( blank_line_Y( ydata, (frame->width-LOGOSKIP) ) ||
- blank_line_Y( ydata+LOGOSKIP, (frame->width-LOGOSKIP) ) ) ||
- ! ( blank_line_Y( ydata+ypitch, (frame->width-LOGOSKIP) ) ||
- blank_line_Y( ydata+ypitch+LOGOSKIP,(frame->width-LOGOSKIP) ) )) {
- break;
- } else {
- ydata += 2 * ypitch;
- udata += upitch;
- vdata += vpitch;
- }
- }
- *crop_top = y>8 ? y : 0;
-
- /* from bottom -> up */
- ydata = frame->base[0] + ((frame->height-4) -1 ) * ypitch;
- udata = frame->base[1] + ((frame->height-4)/2 -1 ) * upitch;
- vdata = frame->base[2] + ((frame->height-4)/2 -1 ) * vpitch;
- for(y = frame->height - 5; y >= frame->height-max_crop; y -=2 ) {
- if( ! blank_line_Y(ydata, frame->width) ||
- ! blank_line_Y(ydata-ypitch, frame->width) ||
- ! blank_line_UV(udata, frame->width/2) ||
- ! blank_line_UV(vdata, frame->width/2)) {
- break;
- } else {
- ydata -= 2*ypitch;
- udata -= upitch;
- vdata -= vpitch;
- }
- }
- *crop_bottom = y;
-
- /* test for black in center - don't crop if frame is empty */
- if(*crop_top >= max_crop*2 && *crop_bottom <= frame->height-max_crop) {
- ydata = frame->base[0] + (frame->height/2)*ypitch;
- udata = frame->base[1] + (frame->height/4)*upitch;
- vdata = frame->base[2] + (frame->height/4)*vpitch;
- if( blank_line_Y(ydata, frame->width) &&
- blank_line_Y(ydata-ypitch, frame->width) &&
- blank_line_UV(udata, frame->width/2) &&
- blank_line_UV(vdata, frame->width/2)) {
- TRACE("not cropping black frame\n");
-#if 0
- *crop_top = 0;
- *crop_bottom = frame->height - 1;
-#else
- return 0;
-#endif
- }
- }
- return 1;
-}
-
-static int analyze_frame_yuy2(vo_frame_t *frame, int *crop_top, int *crop_bottom)
-{
- int y;
- int pitch = frame->pitches[0];
- uint8_t *data = frame->base[0];
- int max_crop = (frame->height / 4) / 2; /* 4:3 --> 16:9 */
-
- /* from top -> down */
- data += 6 * pitch; /* skip 6 first lines */
- for(y = 6; y <= max_crop *2 /* *2 = 20:9+subs -> 16:9 */ ; y ++)
- if( ! ( blank_line_YUY2(data, (frame->width-LOGOSKIP)*2) ||
- blank_line_YUY2(data+2*LOGOSKIP, (frame->width-LOGOSKIP)*2)))
- break;
- else
- data += pitch;
-
- *crop_top = y;
-
- /* from bottom -> up */
- data = frame->base[0] + ((frame->height-4) -1 ) * pitch;
- for(y = frame->height - 5; y >= frame->height-max_crop; y -- )
- if( ! blank_line_YUY2(data, frame->width * 2))
- break;
- else
- data -= pitch;
-
- *crop_bottom = y;
-
- /* test for black in center - don't crop if frame is empty */
- if(*crop_top >= max_crop*2 && *crop_bottom <= frame->height-max_crop) {
- data = frame->base[0] + (frame->height/2)*pitch;
- if( blank_line_YUY2(data, frame->width * 2)) {
- TRACE("not cropping black frame\n");
-#if 0
- *crop_top = 0;
- *crop_bottom = frame->height - 1;
-#else
- return 0;
-#endif
- }
- }
-
- return 1;
-}
-
-static void analyze_frame(vo_frame_t *frame, int *crop_top, int *crop_bottom)
-{
- post_video_port_t *port = (post_video_port_t *)frame->port;
- autocrop_post_plugin_t *this = (autocrop_post_plugin_t *)port->post;
- int result;
-
- if(frame->format == XINE_IMGFMT_YV12)
- result = analyze_frame_yv12(frame, crop_top, crop_bottom);
- else /*if(frame->format == XINE_IMGFMT_YUY2)*/
- result = analyze_frame_yuy2(frame, crop_top, crop_bottom);
-
-#if defined(__MMX__)
- _mm_empty();
-#endif
-
- if(!result)
- return;
-
-#ifdef MARK_FRAME
- dbg_top = *crop_top; dbg_bottom = *crop_bottom;
-#endif
-
- if(this->stabilize) {
- int bottom = frame->height - *crop_bottom;
- int wide = 0;
-
- /* bottom bar size */
- if(bottom < frame->height/32) {
- TRACE("bottom: %d -> 4:3 ", *crop_bottom);
- *crop_bottom = frame->height - 1; /* no cropping */
- } else if(bottom < frame->height*3/32) {
- TRACE("bottom: %d -> 14:9 (%d) ", *crop_bottom, frame->height * 15 / 16 - 1);
- *crop_bottom = frame->height * 15 / 16 - 1; /* 14:9 */
- } else if(bottom < frame->height*3/16) {
- TRACE("bottom: %d -> 16:9 (%d) ", *crop_bottom, frame->height * 7 / 8 - 1);
- *crop_bottom = frame->height * 7 / 8 - 1; /* 16:9 */
- wide = 1;
- } else {
- TRACE("bottom: %d -> 20:9 (%d) ", *crop_bottom, frame->height * 3 / 4 - 1);
- *crop_bottom = frame->height * 3 / 4 - 1; /* 20:9 */
- wide = 2;
- }
-
- /* top bar size */
- if(*crop_top < frame->height/32) {
- TRACE("top: %3d -> 4:3 \n", *crop_top);
- *crop_top = 0; /* no cropping */
- } else if(*crop_top < frame->height*3/32) {
- TRACE("top: %3d -> 14:9 (%d)\n", *crop_top, frame->height / 16);
- *crop_top = frame->height / 16; /* 14:9 */
- } else if(*crop_top < frame->height*3/16 || wide) {
- TRACE("top: %3d -> 16:9 (%d)\n", *crop_top, frame->height / 8);
- *crop_top = frame->height / 8; /* 16:9 */
- } else {
- TRACE("top: %3d -> 20:9 (%d)\n", *crop_top, frame->height / 4);
- *crop_top = frame->height / 4; /* 20:9 */
- wide++;
- }
- switch(wide) {
- case 3: *crop_top -= frame->height / 8;
- if(*crop_top < 0)
- *crop_top = 0;
- TRACE(" wide -> center top\n");
- case 2: *crop_bottom += frame->height / 8;
- if(*crop_bottom >= frame->height)
- *crop_bottom = frame->height-1;
- TRACE(" wide -> center bottom\n");
- }
-
- } else {
-
- if(*crop_top > (frame->height/8 *2)) /* *2 --> 20:9 -> 16:9 + subtitles */
- *crop_top = frame->height/8 *2 ;
- if(*crop_bottom < (frame->height*7/8))
- *crop_bottom = frame->height*7/8;
-
- if(*crop_top > (frame->height/8)) {
- /* if wider than 16:9, prefer cropping top if subtitles are inside bottom bar */
- if(*crop_top + (frame->height - *crop_bottom) > frame->height/4) {
- int diff = *crop_top + (frame->height - *crop_bottom) - frame->height/4;
- diff &= ~1;
- TRACE("balance: %d,%d -> %d,%d\n",
- *crop_top, *crop_bottom,
- *crop_top, *crop_bottom + diff);
-#if 0
- /* this moves image to top (crop only top) */
- *crop_bottom += diff;
-#endif
-#if 0
- /* this moves image to center */
- /* may cause problems with subtitles ... */
- *crop_top -= diff;
-#endif
-#if 1
- /* this moves image to center when there are no
- detected subtitles inside bottom bar */
- if(this->height_limit_active) {
- int reserved = this->height_limit - *crop_bottom;
- if(reserved>0) {
- *crop_bottom += reserved;
- diff -= reserved;
- }
- }
- *crop_top -= diff;
-#endif
-#if 0
- /* do nothing - image will be centered in video out.
- - problems with subtitles using unscaled OSD */
-#endif
- }
- }
-
- /* stay inside frame and forget very small bars */
- if(*crop_top <= 8)
- *crop_top = 0;
- if(*crop_bottom >= (frame->height-6))
- *crop_bottom = frame->height;
-
- if(*crop_top < frame->height/12 || *crop_bottom > frame->height*11/12) {
- /* Small bars -> crop only detected borders */
- if(*crop_top || *crop_bottom < frame->height-1) {
- TRACE("Small bars -> <16:9 : start_line = %d end_line = %d (%s%d t%d)\n",
- *crop_top, *crop_bottom,
- this->height_limit_active ? "height limit " : "",
- this->height_limit,
- this->height_limit_active ? this->height_limit_timer : 0);
- }
- } else {
- /* Large bars -> crop to 16:9 */
- TRACE("Large bars -> 16:9 : start_line = %d end_line = %d (%s%d t%d)\n",
- *crop_top, *crop_bottom,
- this->height_limit_active ? "height limit " : "",
- this->height_limit,
- this->height_limit_active ? this->height_limit_timer : 0);
- if(*crop_top < frame->height / 8)
- *crop_top = frame->height / 8;
- if(*crop_bottom < frame->height * 7 / 8)
- *crop_bottom = frame->height * 7 / 8;
- }
- }
-
- /* adjust start and stop to even lines */
- (*crop_top) = (*crop_top) & (~1);
- (*crop_bottom) = (*crop_bottom + 1) & (~1);
-}
-
-#ifdef MARK_FRAME
-static void mark_frame_yv12(autocrop_post_plugin_t *this,
- vo_frame_t *frame, int *crop_top, int *crop_bottom)
-{
- int ypitch = frame->pitches[0];
- int upitch = frame->pitches[1];
- int vpitch = frame->pitches[2];
- uint8_t *ydata = frame->base[0];
- uint8_t *udata = frame->base[1];
- uint8_t *vdata = frame->base[2];
-
- /* draw markers to detected boundaries and expected boundaries */
- if(*crop_top > 4 && *crop_top < 200) {
- ydata = frame->base[0] + ((*crop_top)-2)*ypitch;
- udata = frame->base[1] + ((*crop_top)/2 -1)*upitch;
- memset(ydata, 0xff, frame->width/10);
- memset(ydata+ypitch, 0xff, frame->width/10);
- memset(udata, 0xff, frame->width/2/10);
-
- if(dbg_top < *crop_top) dbg_top = *crop_top;
- ydata = frame->base[0] + ((dbg_top - *crop_top))*ypitch;
- udata = frame->base[1] + ((dbg_top - *crop_top)/2)*upitch;
- memset(ydata, 0x80, frame->width/2);
- memset(ydata+ypitch, 0x80, frame->width/2);
- memset(udata, 0xff, frame->width/2/2);
- }
- if(*crop_bottom > 300) {
- if(*crop_bottom < frame->height - 2) {
- ydata = frame->base[0] + (*crop_bottom + 2)*ypitch;
- udata = frame->base[1] + ((*crop_bottom)/2)*upitch;
- memset(ydata, 0xff, frame->width);
- memset(ydata+ypitch, 0xff, frame->width);
- memset(udata, 0xff, frame->width/2);
- }
- if(dbg_bottom - *crop_top - 2 < frame->height) {
- ydata = frame->base[0] + (dbg_bottom - *crop_top - 2)*ypitch;
- udata = frame->base[1] + (dbg_bottom - *crop_top - 2)/2*upitch;
- memset(ydata, 0x80, frame->width/2);
- memset(ydata+ypitch, 0xff, frame->width/2);
- memset(udata, 0xff, frame->width/2/2);
- }
- }
- if(frame->height > 500) {
- /* TODO: use frame height instead of assuming 576 ... -> 72 */
- vdata = frame->base[2] + ((72-*crop_top)/2)*vpitch;
-vdata = frame->base[2] + (72/2)*vpitch;
- memset(vdata, 0xff, frame->width/2);
- vdata = frame->base[2] + ((frame->height-72+(576-*crop_bottom))/2)*vpitch;
-vdata = frame->base[2] + ((frame->height-72)/2)*vpitch;
- memset(vdata, 0xff, frame->width/2);
- }
-}
-#endif
-
-/*
- * crop frame by copying
- */
-#ifndef USE_CROP
-static int crop_copy_yv12(vo_frame_t *frame, xine_stream_t *stream)
-{
- post_video_port_t *port = (post_video_port_t *)frame->port;
- autocrop_post_plugin_t *this = (autocrop_post_plugin_t *)port->post;
- vo_frame_t *new_frame;
-
- int y, result;
- int yp = frame->pitches[0], yp2;
- int up = frame->pitches[1], up2;
- int vp = frame->pitches[2], vp2;
- uint8_t *ydata = frame->base[0], *ydata2;
- uint8_t *udata = frame->base[1], *udata2;
- uint8_t *vdata = frame->base[2], *vdata2;
-
- int new_height;
- float new_ratio;
-
- /* top bar */
- ydata += this->start_line * yp;
- udata += (this->start_line/2) * up;
- vdata += (this->start_line/2) * vp;
-
- new_height = this->end_line - this->start_line;
- new_ratio = 12.0/9.0 * ((float)frame->height / (float)new_height);
-
- new_frame = port->original_port->get_frame(port->original_port,
- frame->width, new_height,
- new_ratio, frame->format,
- frame->flags | VO_BOTH_FIELDS);
-
- /* ??? */
- frame->ratio = new_frame->ratio;
-
- _x_post_frame_copy_down(frame, new_frame);
-
- yp2 = new_frame->pitches[0];
- up2 = new_frame->pitches[1];
- vp2 = new_frame->pitches[2];
- ydata2 = new_frame->base[0];
- udata2 = new_frame->base[1];
- vdata2 = new_frame->base[2];
-
- /*
- TODO:
- save channel logo mask (from top)
- - no changes in 3 sec -> next time crop it out ...
- */
-
- for(y=0; y < new_height/2; y++) {
- xine_fast_memcpy(ydata2, ydata, frame->width);
- ydata += yp;
- ydata2 += yp2;
- xine_fast_memcpy(ydata2, ydata, frame->width);
- ydata += yp;
- ydata2 += yp2;
- xine_fast_memcpy(udata2, udata, frame->width/2);
- udata += up;
- udata2 += up2;
- xine_fast_memcpy(vdata2, vdata, frame->width/2);
- vdata += vp;
- vdata2 += vp2;
- }
-
-#ifdef MARK_FRAME
- mark_frame_yv12(this, new_frame, &this->start_line, &this->end_line);
-#endif
-
- result = new_frame->draw(new_frame, stream);
- _x_post_frame_copy_up(frame, new_frame);
- new_frame->free(new_frame);
-
- return result;
-}
-
-static int crop_copy_yuy2(vo_frame_t *frame, xine_stream_t *stream)
-{
- post_video_port_t *port = (post_video_port_t *)frame->port;
- autocrop_post_plugin_t *this = (autocrop_post_plugin_t *)port->post;
- vo_frame_t *new_frame;
-
- int y, result;
- int p = frame->pitches[0], p2;
- uint8_t *data = frame->base[0], *data2;
-
- int new_height;
- float new_ratio;
-
- /* top bar */
- data += this->start_line * p;
-
- new_height = this->end_line - this->start_line;
- new_ratio = 12.0/9.0 * ((float)frame->height / (float)new_height);
- new_frame = port->original_port->get_frame(port->original_port,
- frame->width, new_height,
- new_ratio, frame->format,
- frame->flags | VO_BOTH_FIELDS);
- /* ??? */
- frame->ratio = new_frame->ratio;
-
- _x_post_frame_copy_down(frame, new_frame);
-
- p2 = new_frame->pitches[0];
- data2 = new_frame->base[0];
-
- for(y=0; y < new_height; y++) {
- xine_fast_memcpy(data2, data, frame->width);
- data += p;
- data2 += p2;
- }
-
- result = new_frame->draw(new_frame, stream);
- _x_post_frame_copy_up(frame, new_frame);
- new_frame->free(new_frame);
-
- return result;
-}
-
-#endif
-
-/*
- * crop frame without copying
- */
-#ifdef USE_CROP
-static int crop_nocopy(vo_frame_t *frame, xine_stream_t *stream)
-{
- post_video_port_t *port = (post_video_port_t *)frame->port;
- autocrop_post_plugin_t *this = (autocrop_post_plugin_t *)port->post;
- int skip;
- double new_ratio = frame->ratio;
- int new_height;
-
- if(this->cropping_active) {
- frame->crop_top += this->start_line;
- frame->crop_bottom += (frame->height + 1 - this->end_line);
-
- TRACE("crop_nocopy: top ->%d bottom ->%d\n", frame->crop_top, frame->crop_bottom);
-
- new_height = this->end_line - this->start_line;
- new_ratio = 12.0/9.0 * ((float)frame->height / (float)new_height);
- }
-
- _x_post_frame_copy_down(frame, frame->next);
-
- /* ??? */
- frame->ratio = new_ratio;
-
- skip = frame->next->draw(frame->next, stream);
- TRACE("crop: top %d, bottom %d\n", frame->crop_top, frame->crop_bottom);
- _x_post_frame_copy_up(frame, frame->next);
-
- return skip;
-}
-#endif
-
-/*
- * Frame handling
- */
-
-static int autocrop_draw(vo_frame_t *frame, xine_stream_t *stream)
-{
- post_video_port_t *port = (post_video_port_t *)frame->port;
- autocrop_post_plugin_t *this = (autocrop_post_plugin_t *)port->post;
- int result;
- int detected_start, detected_end;
-
- if(!this->autodetect) {
- this->start_line = frame->height/8;
- this->end_line = frame->height*7/8;
- this->crop_total = frame->height/4;
-#ifdef USE_CROP
- return crop_nocopy(frame, stream);
-#else
- if(frame->format == XINE_IMGFMT_YV12)
- return crop_copy_yv12(frame, stream);
- else /*if(frame->format == XINE_IMGFMT_YUY2)*/
- return crop_copy_yuy2(frame, stream);
-#endif
- }
-
- /* use pts jumps to track stream changes (and seeks) */
- if(frame->pts > 0) {
- if(this->prev_pts>0) {
- int64_t dpts = frame->pts - this->prev_pts;
- if(dpts < INT64_C(-30*90000) || dpts > INT64_C(30*90000)) { /* 30 sec */
- if(this->height_limit_active) {
- this->height_limit_timer = START_TIMER_INIT;
- TRACE("short pts jump resetted height limit");
- }
- }
- if(dpts < INT64_C(-30*60*90000) || dpts > INT64_C(30*60*90000)) { /* 30 min */
- this->cropping_active = 0;
- TRACE("long pts jump resetted cropping");
- }
- }
- this->prev_pts = frame->pts;
- }
-
- /* reset ? */
- if(! this->cropping_active) {
- this->prev_start_line = 0;
- this->prev_end_line = frame->height;
- this->start_timer = START_TIMER_INIT;
- this->prev_pts = -1;
- if(this->height_limit_active) {
- TRACE("height limit reset (no cropping)");
- }
- this->height_limit_active = 0;
- this->height_limit = frame->height;
- }
-
- /* only 4:3 YV12 frames are cropped */
- if(frame->ratio != 4.0/3.0 || (frame->format != XINE_IMGFMT_YV12 &&
- frame->format != XINE_IMGFMT_YUY2)) {
- this->cropping_active = 0;
-
- } else if(frame->bad_frame) {
-
- /* check for letterbox borders only from I-frames */
- } else if(frame->picture_coding_type == 1/*XINE_PICT_I_TYPE*/) {
-
- analyze_frame(frame, &this->start_line, &this->end_line);
-
- /* ignore very small bars */
- if(this->start_line > 10 || this->end_line < frame->height - 10)
- this->cropping_active = 1;
- else
- this->cropping_active = 0;
-
- this->prev_height = frame->height;
- this->prev_width = frame->width;
-
- /* no change unless same values for several frames */
- if(this->stabilize &&
- (this->start_line != this->prev_start_line ||
- this->end_line != this->prev_end_line)) {
- if(this->stabilize_timer)
- this->stabilize_timer--;
- else
- this->stabilize_timer = 4;
- if(this->stabilize_timer) {
- TRACE("stabilize start_line: %d -> %d, end_line %d -> %d\n",
- this->start_line, this->prev_start_line,
- this->end_line, this->prev_end_line);
- this->start_line = this->prev_start_line;
- this->end_line = this->prev_end_line;
- }
- }
-
- } else {
- /* reset when format changes */
- if(frame->height != this->prev_height)
- this->cropping_active = 0;
- if(frame->width != this->prev_width)
- this->cropping_active = 0;
- }
-
- /* update timers */
- if(this->start_timer)
- this->start_timer--;
-
- if(this->height_limit_timer) {
- if (! --this->height_limit_timer) {
- this->height_limit_active = 0;
- this->height_limit = frame->height;
- TRACE("height limit timer expired");
- }
- }
-
- /* no cropping to be done ? */
- if (/*frame->bad_frame ||*/ !this->cropping_active || this->start_timer>0) {
- _x_post_frame_copy_down(frame, frame->next);
- result = frame->next->draw(frame->next, stream);
- _x_post_frame_copy_up(frame, frame->next);
- return result;
- }
-
- /* "soft start" and border stabilization */
- detected_start = this->start_line;
- detected_end = this->end_line;
- if(this->soft_start) {
- if(this->prev_start_line != this->start_line) {
- int diff = this->prev_start_line - this->start_line;
- if(diff < -4) diff = -4;
- else if(diff > 4) diff = 4;
- else diff = 0;
- this->start_line = this->prev_start_line - diff;
- }
- if(this->prev_end_line != this->end_line) {
- int diff = this->prev_end_line - this->end_line;
- if(diff < -4) diff = -4;
- else if(diff > 4) diff = 4;
- else diff = 0;
- this->end_line = this->prev_end_line - diff;
- }
- }
-
- /* handle fixed subtitles inside bottom bar */
- if(this->subs_detect) {
- if(abs(this->prev_start_line - this->start_line) > 5 ) {
- /* reset height limit if top bar changes */
- TRACE("height limit reset, top bar moved from %d -> %d\n",
- this->prev_start_line, this->start_line);
- this->height_limit_active = 0;
- this->height_limit = frame->height;
- this->height_limit_timer = 0;
- }
- if (this->end_line > this->prev_end_line) {
- if(!this->height_limit_active ||
- this->height_limit < this->end_line) {
- /* start or increase height limit */
- TRACE("height limit %d -> %d (%d secs)\n",
- this->height_limit, this->end_line,
- HEIGHT_LIMIT_LIFETIME/25);
- this->height_limit = this->end_line;
- this->height_limit_timer = HEIGHT_LIMIT_LIFETIME;
- this->height_limit_active = 1;
- }
- if(this->height_limit_active &&
- this->height_limit_timer < HEIGHT_LIMIT_LIFETIME/4) {
- /* keep heigh limit timer running */
- TRACE("height_limit_timer increment (still needed)\n");
- this->height_limit_timer = HEIGHT_LIMIT_LIFETIME/2;
- }
- }
- }
-
- this->prev_start_line = this->start_line;
- this->prev_end_line = this->end_line;
-
- if(this->subs_detect) {
- if(this->height_limit_active) {
- /* apply height limit */
- if(this->end_line < this->height_limit)
- this->end_line = this->height_limit;
- } else {
- this->height_limit = frame->height;
- }
- }
-
- /*
- * do cropping
- * - using frame->crop_... does not seem to work with my xv and xine-lib-1.1.1.
- * - maybe cropping could be done by adjusting y/u/v data pointers
- * and height of frame ?
- * -> no time-consuming copying
- */
-#ifdef USE_CROP
- result = crop_nocopy(frame, stream);
-#else
- if(frame->format == XINE_IMGFMT_YV12)
- result = crop_copy_yv12(frame, stream);
- else /*if(frame->format == XINE_IMGFMT_YUY2)*/
- result = crop_copy_yuy2(frame, stream);
-#endif
- this->crop_total = this->start_line + frame->height - this->end_line;
-
- /* forget stabilized values */
- this->start_line = detected_start;
- this->end_line = detected_end;
-
- return result;
-}
-
-#ifdef USE_CROP
-static vo_frame_t *autocrop_get_frame(xine_video_port_t *port_gen,
- uint32_t width, uint32_t height,
- double ratio, int format, int flags)
-{
- post_video_port_t *port = (post_video_port_t *)port_gen;
- post_plugin_t *this_gen = port->post;
- autocrop_post_plugin_t *this = (autocrop_post_plugin_t *)this_gen;
- vo_frame_t *frame;
-
- _x_post_rewire(this_gen);
-
- if (ratio <= 0.0)
- if(height > 1)
- ratio = (double)width / (double)height;
-
- if (this->cropping_active &&
- ratio == 4.0/3.0 && (format == XINE_IMGFMT_YV12 ||
- format == XINE_IMGFMT_YUY2)) {
- int new_height = this->end_line+2 - this->start_line;
- float new_ratio = 12.0/9.0 * ((float)height / (float)new_height);
-
- frame = port->original_port->get_frame(port->original_port,
- width, height,
- new_ratio, format, flags);
- _x_post_inc_usage(port);
- frame = _x_post_intercept_video_frame(frame, port);
-
- frame->ratio = ratio;
- return frame;
- }
-
- return port->original_port->get_frame(port->original_port,
- width, height,
- ratio, format, flags);
-}
-#endif
-
-static int autocrop_intercept_frame(post_video_port_t *port, vo_frame_t *frame)
-{
- autocrop_post_plugin_t *this = (autocrop_post_plugin_t *)port->post;
-
- /* Crop only SDTV YV12 4:3 frames ... */
- int intercept = ((frame->format == XINE_IMGFMT_YV12 ||
- frame->format == XINE_IMGFMT_YUY2) &&
- frame->ratio == 4.0/3.0 &&
- frame->width >= 480 && frame->width <= 768 &&
- frame->height >= 288 && frame->height <= 576);
- if(!intercept) {
- this->height_limit_active = 0;
- this->crop_total = 0;
- this->cropping_active = 0;
- }
-
- return intercept;
-}
-
-static int autocrop_intercept_ovl(post_video_port_t *port)
-{
- autocrop_post_plugin_t *this = (autocrop_post_plugin_t *)port->post;
-
- if (!this->cropping_active)
- return 0;
-
- return 1;
-}
-
-static int32_t autocrop_overlay_add_event(video_overlay_manager_t *this_gen, void *event_gen)
-{
- post_video_port_t *port = _x_post_ovl_manager_to_port(this_gen);
- autocrop_post_plugin_t *this = (autocrop_post_plugin_t *)port->post;
- video_overlay_event_t *event = (video_overlay_event_t *)event_gen;
- int caps;
-
- if(this->cropping_active && this->crop_total>10) {
- if (event->event_type == OVERLAY_EVENT_SHOW) {
- switch (event->object.object_type) {
- case 0:
- /* regular subtitle */
- /* Subtitle overlays must be coming somewhere inside xine engine */
-
- caps = port->stream->video_out->get_capabilities (port->stream->video_out);
-#ifdef USE_CROP
- if(caps & VO_CAP_CROP) {
- if(! event->object.overlay->unscaled || !(caps & VO_CAP_UNSCALED_OVERLAY)) {
- event->object.overlay->y -= this->crop_total;
- }
- } else {
- /* object is moved crop_top amount in video_out */
- if(event->object.overlay->unscaled && (caps & VO_CAP_UNSCALED_OVERLAY)) {
- /* cancel incorrect move that will be done in video_out */
- event->object.overlay->y += this->start_line;
- } else {
- /* move crop_bottom pixels up */
- event->object.overlay->y -= (this->crop_total - this->start_line);
- }
- }
-
- /* when using cropping overlays are moved in video_out */
- INFO("autocrop_overlay_add_event: subtitle event untouched\n");
-#else
- /* when cropping here subtitles coming from inside of xine must be re-positioned */
- if(! event->object.overlay->unscaled || !(caps & VO_CAP_UNSCALED_OVERLAY)) {
- event->object.overlay->y -= this->crop_total;
- INFO("autocrop_overlay_add_event: subtitle event moved up\n");
- }
-#endif
- break;
- case 1:
- /* menu overlay */
- /* All overlays coming from VDR have this type */
- {
-#ifdef DVDTEST
- int dvd_menu = 0;
- if (stream->input_plugin) {
- if (stream->input_plugin->get_capabilities (stream->input_plugin) &
- INPUT_CAP_SPULANG) {
- *((int *)lang) = 0; /* channel */
- if (stream->input_plugin->get_optional_data (stream->input_plugin, lang,
- INPUT_OPTIONAL_DATA_SPULANG)
- == INPUT_OPTIONAL_SUCCESS)
- if(!strcmp(lang, "menu"))
- dvd_menu = 1; /* -> cropping off */
- /* should turn on when not in menu ... -> where ? */
- }
- }
-#endif
-#ifdef USE_CROP
- if(!event->object.overlay->unscaled) {
- event->object.overlay->y += this->start_line;//crop_total;
- } else {
- caps = port->stream->video_out->get_capabilities (port->stream->video_out);
- if(!(caps & VO_CAP_UNSCALED_OVERLAY))
- event->object.overlay->y += this->start_line;//crop_total;
- }
-#endif
- }
- break;
- }
- }
- }
-
- return port->original_manager->add_event(port->original_manager, event_gen);
-}
-
-
-/*
- * Parameter functions
- */
-
-static xine_post_api_descr_t *autocrop_get_param_descr(void)
-{
- return &autocrop_param_descr;
-}
-
-static int autocrop_set_parameters(xine_post_t *this_gen, void *param_gen)
-{
- autocrop_post_plugin_t *this = (autocrop_post_plugin_t *)this_gen;
- autocrop_parameters_t *param = (autocrop_parameters_t *)param_gen;
-
- this->autodetect = param->enable_autodetect;
- this->subs_detect = param->enable_subs_detect;
- this->soft_start = param->soft_start;
- this->stabilize = param->stabilize;
- TRACE("autocrop_set_parameters: "
- "auto=%d subs=%d soft=%d stabilize=%d\n",
- this->autodetect, this->subs_detect,
- this->soft_start, this->stabilize);
- return 1;
-}
-
-static int autocrop_get_parameters(xine_post_t *this_gen, void *param_gen)
-{
- autocrop_post_plugin_t *this = (autocrop_post_plugin_t *)this_gen;
- autocrop_parameters_t *param = (autocrop_parameters_t *)param_gen;
-
- TRACE("autocrop_get_parameters: "
- "auto=%d subs=%d soft=%d stabilize=%d\n",
- this->autodetect, this->subs_detect,
- this->soft_start, this->stabilize);
- param->enable_autodetect = this->autodetect;
- param->enable_subs_detect = this->subs_detect;
- param->soft_start = this->soft_start;
- param->stabilize = this->stabilize;
- return 1;
-}
-
-static char *autocrop_get_help(void) {
- return _("The autocrop plugin is meant to take 4:3 letterboxed frames and "
- "convert them to 16:9 by removing black bars on the top and bottom "
- "of the frame.\n"
- "\n"
- "Parameters\n"
- " enable_autodetect: Enable automatic letterbox detection\n"
- " enable_subs_detect: Enable automatic subtitle detection inside bottom bar\n"
- " soft_start: Enable soft start of cropping\n"
- " stabilize: Stabilize cropping to\n"
- " 14:9, 16:9, (16:9+subs), 20:9, (20:9+subs)\n"
- "\n"
- );
-}
-
-
-/*
- * Open/close
- */
-
-static void autocrop_dispose(post_plugin_t *this_gen)
-{
- if (_x_post_dispose(this_gen))
- free(this_gen);
-}
-
-static post_plugin_t *autocrop_open_plugin(post_class_t *class_gen,
- int inputs,
- xine_audio_port_t **audio_target,
- xine_video_port_t **video_target)
-{
- if (video_target && video_target[ 0 ]) {
- autocrop_post_plugin_t *this = calloc(1, sizeof(autocrop_post_plugin_t));
- post_in_t *input;
- post_out_t *output;
- post_video_port_t *port;
- xine_post_in_t *input_param;
-
- static xine_post_api_t post_api =
- { autocrop_set_parameters, autocrop_get_parameters,
- autocrop_get_param_descr, autocrop_get_help };
-
- if (this) {
- _x_post_init(&this->post_plugin, 0, 1);
-
- port = _x_post_intercept_video_port(&this->post_plugin,
- video_target[ 0 ],
- &input, &output);
-
- input->xine_in.name = "video in";
- output->xine_out.name = "video out";
-
- port->intercept_ovl = autocrop_intercept_ovl;
- port->new_manager->add_event = autocrop_overlay_add_event;
- port->intercept_frame = autocrop_intercept_frame;
-#ifdef USE_CROP
- port->new_port.get_frame = autocrop_get_frame;
-#endif
- port->new_frame->draw = autocrop_draw;
-
- this->post_plugin.xine_post.video_input[ 0 ] = &port->new_port;
- this->post_plugin.dispose = autocrop_dispose;
-
- input_param = &this->parameter_input;
- input_param->name = "parameters";
- input_param->type = XINE_POST_DATA_PARAMETERS;
- input_param->data = &post_api;
-#if XINE_VERSION_CODE >= 10102
- xine_list_push_back(this->post_plugin.input, input_param);
-#else
- xine_list_append_content(this->post_plugin.input, input_param);
-#endif
- this->cropping_active = 0;
- this->autodetect = 1;
- this->subs_detect = 1;
- this->soft_start = 1;
- this->stabilize = 1;
- this->start_line = 0;
- this->end_line = 576;
-
- this->prev_start_line = 0;
- this->prev_end_line = 576;
-
- return &this->post_plugin;
- }
- }
-
- return NULL;
-}
-
-
-/*
- * Plugin class
- */
-
-#if POST_PLUGIN_IFACE_VERSION < 10
-static char *autocrop_get_identifier(post_class_t *class_gen)
-{
- return "autocrop";
-}
-
-static char *autocrop_get_description(post_class_t *class_gen)
-{
- return "Crop letterboxed 4:3 video to 16:9";
-}
-
-static void autocrop_class_dispose(post_class_t *class_gen)
-{
- free(class_gen);
-}
-#endif
-
-static void *autocrop_init_plugin(xine_t *xine, void *data)
-{
- post_class_t *class = calloc(1, sizeof(post_class_t));
-
- if(class) {
- class->open_plugin = autocrop_open_plugin;
-#if POST_PLUGIN_IFACE_VERSION < 10
- class->get_identifier = autocrop_get_identifier;
- class->get_description = autocrop_get_description;
- class->dispose = autocrop_class_dispose;
-#else
- class->identifier = "autocrop";
- class->description = N_("Crop letterboxed 4:3 video to 16:9");
- class->dispose = default_post_class_dispose;
-#endif
- }
-
- return class;
-}
-
-
-static post_info_t info = { XINE_POST_TYPE_VIDEO_FILTER };
-
-const plugin_info_t xine_plugin_info[] __attribute__((visibility("default"))) =
-{
- /* type, API, "name", version, special_info, init_function */
- { PLUGIN_POST, POST_PLUGIN_IFACE_VERSION, "autocrop", XINE_VERSION_CODE, &info, &autocrop_init_plugin },
- { PLUGIN_NONE, 0, "", 0, NULL, NULL }
-};
diff --git a/xine_post_swscale.c b/xine_post_swscale.c
deleted file mode 100644
index 9e5be7c2..00000000
--- a/xine_post_swscale.c
+++ /dev/null
@@ -1,1730 +0,0 @@
-/*
- * Copyright (C) 2000-2007 the xine project
- *
- * This file is part of xine, a free video player.
- *
- * xine is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * xine is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * $Id: xine_post_swscale.c,v 1.9 2008-12-13 14:24:03 phintuka Exp $
- *
- * Simple (faster) resize for avisynth
- * Copyright (C) 2002 Tom Barry
- *
- * Very simple 2 tap linear interpolation.
- * It is unfiltered which means it will not soften much.
- *
- * WarpedResize will do a non-linear stretch/squeeze in both the horizontal
- * and vertical dimensions. This can be useful when you want to change the
- * aspect ratio of a video clip and have it mostly distorted at the
- * top, bottom, and side edges.
- *
- *
- * Ported to linux/xine by Petri Hintukainen <phintuka@users.sourceforge.net>
- * - Added x86_64 support
- * - Added PIC support (do not clobber ebx in x86, access only local variables from asm)
- * - Fixed yv12 stretched warp tables generation
- */
-
-#include <xine/xine_internal.h>
-#include <xine/post.h>
-
-/*#define DBG(x...)*/
-#define DBG(x...) fprintf(stderr, "post_warp: " x)
-
-/*#define STREAMING_STORE_TMP*/
-/*#define STREAMING_STORE*/
-/*#define PREFETCH*/
-/* streaming store and prefetch seems to be slower ...
- * Tested with P3 (128M L2) and C2D (4M L2).
- * Maybe access pattern is enough simple for HW prefetchers.
- */
-
-/*#define VANILLA*/
-
-/*
- * This function accepts a position from 0 to 1 and warps it, to 0 through 1 based
- * upon the wFact var. The warp equations are designed to:
- *
- * * Always be rising but yield results from 0 to 1
- *
- * * Have a first derivative that doesn't go to 0 or infinity, at least close
- * to the center of the screen
- *
- * * Have a curvature (absolute val of 2nd derivative) that is small in the
- * center and smoothly rises towards the edges. We would like the curvature
- * to be everywhere = 0 when the warp factor = 1
- */
-static double WarpFactor(double position, double wFact)
-{
- double x;
- double z;
- double w;
- x = 2 * (position - .5);
- if (1) /*(wFact < 1.0)*/
- /* For warp factor < 1 the warp is calculated as (1-w) * x^3 + w *x, centered
- *
- * The warp is calculated as z = (1 - w) * x^3 + w * x, centered
- * around .5 and ranging from 0 to 1. After some tinkering this seems
- * to give decent values and derivatives at the right places.
- */
- w = 2.0 - wFact; /* reverse parm for compat with initial release */
-
- if (x < 0.0) {
- z = -(1 - w) * x*x*x - w * x; /* -1 < x < 0, wFact < 1 */
- return .5 - .5 * z;
- } else {
- z = (1 - w) * x*x*x + w * x; /* -1 < x < 0, wFact < 1 */
- return .5 + .5 * z; /* amts to same formula as above for now */
- }
-}
-
-/*
- * YV12
- *
- * For each horizontal output pair of pixels there is are 2 qword masks followed by 2 int
- * offsets. The 2 masks are the weights to be used for the luma and chroma, respectively.
- * Each mask contains LeftWeight1, RightWeight1, LeftWeight2, RightWeight2. So a pair of pixels
- * will later be processed each pass through the horizontal resize loop. I think with my
- * current math the Horizontal Luma and Chroma contains the same values but since I may have screwed it
- * up I'll leave it this way for now. Vertical chroma is different.
- *
- * Note - try just using the luma calcs for both, seem to be the same.
- *
- * The weights are scaled 0-256 and the left and right weights will sum to 256 for each pixel.
- */
-static void init_tables_yv12(int newwidth, int newheight, int oldwidth, int oldheight,
- int Interlaced, double hWarp, double vWarp,
- uint32_t *hControl, uint32_t *vOffsets, uint32_t *vWeights,
- uint32_t *hControlUV, uint32_t *vOffsetsUV, uint32_t *vWeightsUV)
-{
- int i;
- int j;
- int k;
- int wY1;
- int wY2;
- DBG("init_yv12: %dx%d->%dx%d hWarp %1.3lf vWarp %1.3lf\n",
- oldwidth, oldheight, newwidth, newheight, hWarp, vWarp);
-
- /* First set up horizontal table, use for both luma & chroma since
- * it seems to have the same equation.
- * We will geneerate these values in pairs, mostly because that's the way
- * I wrote it for YUY2 above.
- */
-
- for(i=0; i < newwidth; i+=2) {
- /* first make even pixel control */
- if (hWarp==1) /*if no warp factor */
- j = i * 256 * (oldwidth-1) / (newwidth-1);
- else /* stretch and warp somehow */
- j = (int) (256 * WarpFactor(i / (newwidth-1.0), hWarp) * (oldwidth-1));
-
- k = j>>8;
- wY2 = j - (k << 8); /* luma weight of right pixel */
- wY1 = 256 - wY2; /* luma weight of left pixel */
-
- if (k > oldwidth - 2) {
- hControl[i*3+4] = oldwidth - 1; /* point to last byte */
- hControl[i*3] = 0x00000100; /* use 100% of rightmost Y */
- } else {
- hControl[i*3+4] = k; /* pixel offset */
- hControl[i*3] = wY2 << 16 | wY1; /* luma weights */
- }
-
- /* now make odd pixel control */
- if (hWarp==1) /* if no warp factor */
- j = (i+1) * 256 * (oldwidth-1) / (newwidth-1);
- else /* stretch and warp somehow */
- j = (int) (256 * WarpFactor((i+1) / (newwidth-1.0), hWarp) * (oldwidth-1));
-
- k = j>>8;
- wY2 = j - (k << 8); /* luma weight of right pixel */
- wY1 = 256 - wY2; /* luma weight of left pixel */
-
- if (k > oldwidth - 2) {
- hControl[i*3+5] = oldwidth - 1; /* point to last byte */
- hControl[i*3+1] = 0x00000100; /* use 100% of rightmost Y */
- } else {
- hControl[i*3+5] = k; /* pixel offset */
- hControl[i*3+1] = wY2 << 16 | wY1; /* luma weights */
- }
- }
-
- hControl[newwidth*3+4] = 2 * (oldwidth-1); /* give it something to prefetch at end */
- hControl[newwidth*3+5] = 2 * (oldwidth-1); /* " */
-#ifndef VANILLA
- // UV
- for(i=0; i < newwidth/2; i+=2) {
- /* first make even pixel control */
- if (hWarp==1) /*if no warp factor */
- j = i * 256 * (oldwidth/2-1) / (newwidth/2-1);
- else /* stretch and warp somehow */
- j = (int) (256 * WarpFactor(i / (newwidth/2-1.0), hWarp) * (oldwidth/2-1));
-
- k = j>>8;
- wY2 = j - (k << 8); /* luma weight of right pixel */
- wY1 = 256 - wY2; /* luma weight of left pixel */
-
- if (k > oldwidth/2 - 2) {
- hControlUV[i*3+4] = oldwidth/2 - 1; /* point to last byte */
- hControlUV[i*3] = 0x00000100; /* use 100% of rightmost Y */
- } else {
- hControlUV[i*3+4] = k; /* pixel offset */
- hControlUV[i*3] = wY2 << 16 | wY1; /* luma weights */
- }
-
- /* now make odd pixel control */
- if (hWarp==1) /* if no warp factor */
- j = (i+1) * 256 * (oldwidth/2-1) / (newwidth/2-1);
- else /* stretch and warp somehow */
- j = (int) (256 * WarpFactor((i+1) / (newwidth/2-1.0), hWarp) * (oldwidth/2-1));
-
- k = j>>8;
- wY2 = j - (k << 8); /* luma weight of right pixel */
- wY1 = 256 - wY2; /* luma weight of left pixel */
-
- if (k > oldwidth/2 - 2) {
- hControlUV[i*3+5] = oldwidth/2 - 1; /* point to last byte */
- hControlUV[i*3+1] = 0x00000100; /* use 100% of rightmost Y */
- } else {
- hControlUV[i*3+5] = k; /* pixel offset */
- hControlUV[i*3+1] = wY2 << 16 | wY1; /* luma weights */
- }
- }
-
- hControlUV[newwidth/2*3+4] = (oldwidth/2-1); /* give it something to prefetch at end */
- hControlUV[newwidth/2*3+5] = (oldwidth/2-1); /* " */
-#endif
-
- /* Next set up vertical tables. The offsets are measured in lines and will be mult */
- /* by the source pitch later . */
-
- /* For YV12 we need separate Luma and chroma tables */
-
- /* First Luma Table */
- for(i=0; i< newheight; ++i) {
- if (vWarp==1) /* if no warp factor */
- j = i * 256 * (oldheight-1) / (newheight-1);
- else /* stretch and warp somehow */
- j = (int) (256 * WarpFactor(i / (newheight-1.0), vWarp) * (oldheight-1));
-
- if (Interlaced) { /* do hard way? */
- if (i%2) { /* is odd output line? */
- if (j < 256) { /* before 1st odd input line */
- vOffsets[i] = 1; /* all from line 1 */
- vWeights[i] = 0; /* weight to give to 2nd line */
- } else {
- k = (((j-256) >> 9) << 1) + 1; /* next lowest odd line */
- vOffsets[i] = k;
- wY2 = j - (k << 8);
- vWeights[i] = wY2 >> 1; /* weight to give to 2nd line */
- }
- } else { /* is even output line */
- k = (j >> 9) << 1; /* next lower even line */
- vOffsets[i] = k;
- wY2 = j - (k << 8);
- vWeights[i] = wY2 >> 1; /* weight to give to 2nd line */
- }
- } else { /* simple way, do as progressive */
- k = j >> 8;
- vOffsets[i] = k;
- wY2 = j - (k << 8);
- vWeights[i] = wY2; /* weight to give to 2nd line */
- }
- }
-
- /* Vertical table for chroma */
- for(i=0; i< newheight/2; ++i) {
- if (vWarp==1) /* if no warp factor */
-#ifdef VANILLA
- j = (int) ( (i+.25) * 256 * (oldheight-1) / (newheight-1.0) - 64 );
-#else
- j = (int) ( (i+.25) * 256 * (oldheight/2-1) / (newheight/2-1.0) - 64 );
-#endif
- else /* stretch and warp somehow */
-#ifdef VANILLA
- j = (int) (256 * WarpFactor( (i+.25) / (newheight-1.0), vWarp) * (oldheight-1.0) );
-#else
- j = (int) (256 * WarpFactor( (i+.25) / (newheight/2 - 1.0), vWarp) * (oldheight/2 - 1.0) );
-#endif
-#ifndef VANILLA
- if(j<0) j=0;
-#endif
- if (Interlaced) { /* do hard way? */
- if (i%2) { /* is odd output line? */
- if (j < 256) { /* before 1st odd input line */
- vOffsetsUV[i] = 1; /* all from line 1 */
- vWeightsUV[i] = 0; /* weight to give to 2nd line */
- } else {
- k = (((j-256) >> 9) << 1) + 1; /* next lowest odd line */
- vOffsetsUV[i] = k;
- wY2 = j - (k << 8);
- vWeightsUV[i] = wY2 >> 1; /* weight to give to 2nd line */
- }
- } else { /* is even output line */
-#ifdef VANILLA
- k = (j >> 9) << 1; /* next lower even line */
- vOffsetsUV[i] = k;
- wY2 = j - (k << 8);
- vWeightsUV[i] = wY2 >> 1; /* weight to give to 2nd line */
-#else
- k = (j / 512) << 1; /* next lower even line */
- vOffsetsUV[i] = k;
- wY2 = j - (k << 8);
- vWeightsUV[i] = wY2 >> 1; /* weight to give to 2nd line */
-#endif
- }
- } else { /* simple way, do as progressive */
-#ifdef VANILLA
- k = j >> 8;
-#else
- k = j / 256; /* j >> 8; does not work right if -256 < j < 0 */
-#endif
- vOffsetsUV[i] = k;
- wY2 = j - (k << 8);
- vWeightsUV[i] = wY2; /* weight to give to 2nd line */
- }
- }
-}
-
-/*
- * YUY2
- *
- * For each horizontal output pair of pixels there is are 2 qword masks followed by 2 int
- * offsets. The 2 masks are the weights to be used for the luma and chroma, respectively.
- * Each mask contains LeftWeight1, RightWeight1, LeftWeight2, RightWeight2. So a pair of pixels
- * will later be processed each pass through the horizontal resize loop.
- *
- * The weights are scaled 0-256 and the left and right weights will sum to 256 for each pixel.
- */
-static void init_tables_yuy2(int newwidth, int newheight, int oldwidth, int oldheight,
- int Interlaced, double hWarp, double vWarp,
- uint32_t *hControl, uint32_t *vOffsets, uint32_t *vWeights )
-{
- int i;
- int j;
- int k;
- int wY1;
- int wY2;
- int wUV1;
- int wUV2;
- DBG("init_yuy2: %dx%d->%dx%d hWarp %1.3lf vWarp %1.3lf\n",
- oldwidth, oldheight, newwidth, newheight, hWarp, vWarp);
-
- /* First set up horizontal table */
- for(i=0; i < newwidth; i+=2) {
- /* first make even pixel control */
- if (hWarp==1) /* if no warp factor */
- j = i * 256 * (oldwidth-1) / (newwidth-1);
- else /* stretch and warp somehow */
- j = (int) (256 * WarpFactor(i / (newwidth-1.0), hWarp) * (oldwidth-1));
-
- k = j>>8;
- wY2 = j - (k << 8); /* luma weight of right pixel */
- wY1 = 256 - wY2; /* luma weight of left pixel */
- wUV2 = (k%2) ? 128 + (wY2 >> 1) : wY2 >> 1;
- wUV1 = 256 - wUV2;
-
- if (k > oldwidth - 2) {
- hControl[i*3+4] = oldwidth - 1; /* point to last byte */
- hControl[i*3] = 0x00000100; /* use 100% of rightmost Y */
- hControl[i*3+2] = 0x00000100; /* use 100% of rightmost U */
- } else {
- hControl[i*3+4] = k; /* pixel offset */
- hControl[i*3] = wY2 << 16 | wY1; /* luma weights */
- hControl[i*3+2] = wUV2 << 16 | wUV1; /* chroma weights */
- }
-
- /* now make odd pixel control */
- if (hWarp==1) /* if no warp factor */
- j = (i+1) * 256 * (oldwidth-1) / (newwidth-1);
- else /* stretch and warp somehow */
- j = (int) (256 * WarpFactor((i+1) / (newwidth-1.0), hWarp) * (oldwidth-1));
-
- k = j>>8;
- wY2 = j - (k << 8); /* luma weight of right pixel */
- wY1 = 256 - wY2; /* luma weight of left pixel */
- wUV2 = (k%2) ? 128 + (wY2 >> 1) : wY2 >> 1;
- wUV1 = 256 - wUV2;
-
- if (k > oldwidth - 2) {
- hControl[i*3+5] = oldwidth - 1; /* point to last byte */
- hControl[i*3+1] = 0x00000100; /* use 100% of rightmost Y */
- hControl[i*3+3] = 0x00000100; /* use 100% of rightmost V */
- } else {
- hControl[i*3+5] = k; /* pixel offset */
- hControl[i*3+1] = wY2 << 16 | wY1; /* luma weights */
- /* hControl[i*3+3] = wUV2 << 16 | wUV1; // chroma weights */
- /* horiz chroma weights should be same as for even pixel - trbarry 09/16/2002 */
- hControl[i*3+3] = hControl[i*3+2]; /* chroma weights */
- }
- }
-
- hControl[newwidth*3+4] = 2 * (oldwidth-1); /* give it something to prefetch at end */
- hControl[newwidth*3+5] = 2 * (oldwidth-1);
-
- /* Next set up vertical table. The offsets are measured in lines and will be mult */
- /* by the source pitch later */
- for(i=0; i< newheight; ++i) {
- if (vWarp==1) /* if no warp factor */
- j = i * 256 * (oldheight-1) / (newheight-1);
- else /* stretch and warp somehow */
- j = (int) (256 * WarpFactor(i / (newheight-1.0), vWarp) * (oldheight-1));
-
- if (Interlaced) { /* do hard way? */
- if (i%2) { /* is odd output line? */
- if (j < 256) { /* before 1st odd input line */
- vOffsets[i] = 1; /* all from line 1 */
- vWeights[i] = 0; /* weight to give to 2nd line */
- } else {
- k = (((j-256) >> 9) << 1) + 1; /* next lowest odd line */
- vOffsets[i] = k;
- wY2 = j - (k << 8);
- vWeights[i] = wY2 >> 1; /* weight to give to 2nd line */
- }
- } else { /* is even output line */
- k = (j >> 9) << 1; /* next lower even line */
- vOffsets[i] = k;
- wY2 = j - (k << 8);
- vWeights[i] = wY2 >> 1; /* weight to give to 2nd line */
- }
- } else { /* simple way, do as progressive */
- k = j >> 8;
- vOffsets[i] = k;
- wY2 = j - (k << 8);
- vWeights[i] = wY2; /* weight to give to 2nd line */
- }
- }
-}
-
-/* Register allocation */
-/* index/counter registers (REGA, REGC) are loaded from 32bit vars/arrays ! */
-#define REGEA "eax"
-#define REGEB "ebx"
-#if defined(__x86_64__)
-# define REGA "rax"
-# define REGB "rbx"
-# define REGC "ecx"
-# define REGD "rdx"
-# define REGDI "rdi"
-# define REGSI "rsi"
-#elif defined(__i386__)
-# define REGA "eax"
-# define REGB "ebx"
-# define REGC "ecx"
-# define REGD "edx"
-# define REGDI "edi"
-# define REGSI "esi"
-#endif
-
-/* variables accessed from assembler code */
-#define _FPround1 "%0"
-#define _vWeight1 "%1"
-#define _vWeight2 "%2"
-#define _YMask "%3"
-#define _src_row_size "%4"
-#define _EndOffset "%5"
-#define _pControl "%6"
-#define _row_size "%7"
-#define _vWorkYW "%8"
-#define _dstp "%9"
-#define _vWorkUVW "%10"
-#define _FPround2 "%11"
-#define _srcp1 "%12"
-#define _srcp2 "%13"
-#if !defined(__x86_64__)
-#define _oldbx "%14"
-#define _SSEMMXenabledW "%15"
-#define _SSE2enabledW "%16"
-#endif
-
-/* Labels */
-#define vMaybeSSEMMX "1"
-#define LessThan8 "2"
-#define LessThan4 "3"
-#define AllDone "4"
-#define LastOne "5"
-#define vLoopSSE2_Fetch "6"
-#define vLoopSSE2 "7"
-#define vLoopSSEMMX_Fetch "8"
-#define vLoopSSEMMX "9"
-#define vLoopMMX "10"
-#define MoreSpareChange "11"
-#define DoHorizontal "12"
-#define hLoopMMX "13"
-#define hLoopMMXSSE "14"
-
-
-/* structure for mmx constants */
-typedef union {
- uint64_t uq[1]; /* Unsigned Quadword */
- uint32_t ud[2]; /* Unsigned Doubleword */
-} ATTR_ALIGN(16) mmx_t;
-
-/* structure for sse2 constants */
-typedef union {
- uint64_t uq[2]; /* Unsigned Quadword */
- uint32_t ud[4]; /* Unsigned Doubleword */
-} ATTR_ALIGN(16) sse2_t;
-
-
-static int do_warp_yuy2(uint8_t *dst, const uint8_t *src,
- const int dst_pitch, const int src_pitch,
- const int dst_width, const int dst_height,
- const int src_width, const int src_height,
- const int Interlaced, const uint32_t * const hControl,
- const uint32_t * const vOffsets, const uint32_t * const vWeights,
- uint32_t *vWorkY, uint32_t *vWorkUV,
- int dst_start)
-{
-#if defined(__i386__) || defined(__x86_64__)
- sse2_t YMask = {uq:{UINT64_C(0x00ff00ff00ff00ff),UINT64_C(0x00ff00ff00ff00ff)}}; /* keeps only luma */
- sse2_t FPround1 = {uq:{UINT64_C(0x0080008000800080),UINT64_C(0x0080008000800080)}}; /* round words */
- sse2_t FPround2 = {uq:{UINT64_C(0x0000008000000080),UINT64_C(0x0000008000000080)}}; /* round dwords */
- sse2_t vWeight1;
- sse2_t vWeight2;
-
- const uint32_t *pControl = &hControl[0];
- const uint32_t *vWorkYW = vWorkY;
- const uint32_t *vWorkUVW = vWorkUV;
- const uint8_t *srcp = src;
- const uint8_t *srcp1;
- const uint8_t *srcp2;
- uint8_t *dstp = dst + dst_pitch*dst_start;
-
- const uint32_t src_row_size = src_width * 2;
- const uint32_t row_size = dst_width * 2;
- const uint32_t EndOffset = src_row_size / 2;
-
-#if !defined(__x86_64__)
- const int accel = xine_mm_accel();
- const uint32_t SSE2enabledW = !!(accel & MM_ACCEL_X86_SSE2); /* in local storage for asm */
- const uint32_t SSEMMXenabledW = !!(accel & MM_ACCEL_X86_MMXEXT); /* in local storage for asm */
- long int oldbx;
-#endif
- int y;
-
- for (y = dst_start; y < dst_height; y++) {
-
- if(vOffsets[y] >= src_height) {
- /* slice completed */
- /*DBG("do_warp_yuy2: max input height reached: need line %d, height %d\n -> Returning next output line: %d\n",
- vOffsets[y], src_height, y);*/
- return y;
- }
-
- vWeight1.ud[0] = vWeight1.ud[1] = vWeight1.ud[2] = vWeight1.ud[3] =
- (256-vWeights[y]) << 16 | (256-vWeights[y]);
- vWeight2.ud[0] = vWeight2.ud[1] = vWeight2.ud[2] = vWeight2.ud[3] =
- vWeights[y] << 16 | vWeights[y];
-
- srcp1 = srcp + vOffsets[y] * src_pitch;
- if (Interlaced)
- srcp2 = (y < dst_height-2) ? srcp1 + 2 * src_pitch : srcp1;
- else
- srcp2 = (y < dst_height-1) ? srcp1 + src_pitch : srcp1;
-
- __asm__ __volatile__ (
-#if !defined(__x86_64__)
- /* store ebx (PIC) */
- "mov %%"REGB", "_oldbx" \n\t"
-#endif
- "movl "_src_row_size", %%"REGC" \n\t"
- "shrl $3, %%"REGC" \n\t" /* 8 bytes a time */
- "mov "_srcp1", %%"REGSI" \n\t" /* top of 2 src lines to get */
- "mov "_srcp2", %%"REGD" \n\t" /* next " */
- "mov "_vWorkYW", %%"REGDI" \n\t" /* luma work destination line */
- "mov "_vWorkUVW", %%"REGB" \n\t" /* luma work destination line */
- "xor %%"REGA", %%"REGA" \n\t"
-#if !defined(__x86_64__)
- /* Let's check here to see if we are on a P4 or higher and can use SSE2 instructions.
- * This first loop is not the performance bottleneck anyway but it is trivial to tune
- * using SSE2 if we have proper alignment.
- */
- "testl $1, "_SSE2enabledW" \n\t" /* is SSE2 supported?*/
- "jz "vMaybeSSEMMX"f \n\t" /* n, can't do anyway*/
-#endif
- "cmpl $2, %%"REGC" \n\t" /* we have at least 16 bytes, 2 qwords? */
- "jl "vMaybeSSEMMX"f \n\t" /* n, don't bother*/
-
- "shrl $1, %%"REGC" \n\t" /* do 16 bytes at a time instead*/
- "decl %%"REGC" \n" /* jigger loop ct */
-
- ".align 16 \n\t"
-
- "movdqa "_FPround1", %%xmm0 \n\t"
- "movdqa "_vWeight1", %%xmm5 \n\t"
- "movdqa "_vWeight2", %%xmm6 \n\t"
- "movdqa "_YMask", %%xmm7 \n"
-
- ""vLoopSSE2_Fetch": \n\t"
-#ifdef PREFETCH
- " prefetcht0 16(%%"REGSI", %%"REGA", 2) \n\t"
- " prefetcht0 16(%%"REGD", %%"REGA", 2) \n"
-#endif
- ""vLoopSSE2": \n\t"
- " movdqu (%%"REGSI", %%"REGA", 2), %%xmm1 \n\t" /* top of 2 lines to interpolate */
- " movdqu (%%"REGD", %%"REGA", 2), %%xmm2 \n\t" /* 2nd of 2 lines */
-
- " movdqa %%xmm1, %%xmm3 \n\t" /* get chroma bytes */
- " pand %%xmm7, %%xmm1 \n\t" /* keep only luma */
- " psrlw $8, %%xmm3 \n\t" /* right just chroma */
- " pmullw %%xmm5, %%xmm1 \n\t" /* mult by weighting factor */
- " pmullw %%xmm5, %%xmm3 \n\t" /* mult by weighting factor */
-
- " movdqa %%xmm2, %%xmm4 \n\t" /* get chroma bytes */
- " pand %%xmm7, %%xmm2 \n\t" /* keep only luma */
- " psrlw $8, %%xmm4 \n\t" /* right just chroma */
- " pmullw %%xmm6, %%xmm2 \n\t" /* mult by weighting factor */
- " pmullw %%xmm6, %%xmm4 \n\t" /* mult by weighting factor */
-
- " paddw %%xmm2, %%xmm1 \n\t" /* combine lumas */
- " paddusw %%xmm0, %%xmm1 \n\t" /* round */
- " psrlw $8, %%xmm1 \n\t" /* right adjust luma */
-#ifdef STREAMING_STORE_TMP
- " movntdq %%xmm1, (%%"REGDI", %%"REGA", 2) \n\t" /* save lumas in our work area */
-#else
- " movdqu %%xmm1, (%%"REGDI", %%"REGA", 2) \n\t" /* save lumas in our work area */
-#endif
- " paddw %%xmm4, %%xmm3 \n\t" /* combine chromas */
- " paddusw %%xmm0, %%xmm3 \n\t" /* round */
- " psrlw $8, %%xmm3 \n\t" /* right adjust chroma */
- " packuswb %%xmm3, %%xmm3 \n\t" /* pack UV's into low dword */
- " movdq2q %%xmm3, %%mm1 \n\t" /* save in our work area */
-#ifdef STREAMING_STORE_TMP
- " movntq %%mm1, (%%"REGB", %%"REGA") \n\t" /* save in our work area */
-#else
- " movq %%mm1, (%%"REGB", %%"REGA") \n\t" /* save in our work area */
-#endif
- " lea 8(%%"REGA"), %%"REGA" \n\t"
- " decl %%"REGC" \n\t"
-
- " jg "vLoopSSE2_Fetch"b \n\t" /* if not on last one loop, prefetch */
- " jz "vLoopSSE2"b \n\t" /* or just loop, or not */
-
- /* done with our SSE2 fortified loop but we may need to pick up the spare change */
-#ifdef STREAMING_STORE_TMP
- " sfence \n\t"
-#endif
- " movl "_src_row_size", %%"REGC" \n\t" /* get count again */
- " andl $15, %%"REGC" \n\t" /* just need mod 16 */
-
- " movq "_YMask", %%mm7 \n\t" /* useful luma mask constant - lazy dupl init */
- " movq "_vWeight1", %%mm5 \n\t"
- " movq "_vWeight2", %%mm6 \n\t"
- " movq "_FPround1", %%mm0 \n\t" /* useful rounding constant */
-
- " shrl $3, %%"REGC" \n\t" /* 8 bytes at a time, any? */
- " jz "MoreSpareChange"f \n" /* n, did them all */
-
- /* Let's check here to see if we are on a P2 or Athlon and can use SSEMMX instructions.
- * This first loop is not the performance bottleneck anyway but it is trivial to tune
- * using SSE if we have proper alignment.
- */
- ""vMaybeSSEMMX": \n\t"
-
- " movq "_YMask", %%mm7 \n\t" /* useful luma mask constant - lazy dupl init */
- " movq "_vWeight1", %%mm5 \n\t"
- " movq "_vWeight2", %%mm6 \n\t"
- " movq "_FPround1", %%mm0 \n\t" /* useful rounding constant */
-#if !defined(__x86_64__)
- " testl $1, "_SSEMMXenabledW" \n\t" /* MMXEXTsupported? */
- " jz "vLoopMMX"f \n\t" /* n, can't do anyway */
-#endif
- " decl %%"REGC" \n" /* jigger loop ctr */
-
- ".align 16 \n"
- ""vLoopSSEMMX_Fetch": \n\t"
-#ifdef PREFETCH
- " prefetcht0 8(%%"REGSI", %%"REGA", 2) \n\t"
- " prefetcht0 8(%%"REGD", %%"REGA", 2) \n"
-#endif
- ""vLoopSSEMMX": \n\t"
- " movq (%%"REGSI", %%"REGA", 2), %%mm1 \n\t" /* top of 2 lines to interpolate */
- " movq (%%"REGD", %%"REGA", 2), %%mm2 \n\t" /* 2nd of 2 lines */
-
- " movq %%mm1, %%mm3 \n\t" /* copy top bytes */
- " pand %%mm7, %%mm1 \n\t" /* keep only luma */
- " pxor %%mm1, %%mm3 \n\t" /* keep only chroma */
- " psrlw $8, %%mm3 \n\t" /* right just chroma */
- " pmullw %%mm5, %%mm1 \n\t" /* mult by weighting factor */
- " pmullw %%mm5, %%mm3 \n\t" /* mult by weighting factor */
-
- " movq %%mm2, %%mm4 \n\t" /* copy 2nd bytes */
- " pand %%mm7, %%mm2 \n\t" /* keep only luma */
- " pxor %%mm2, %%mm4 \n\t" /* keep only chroma */
- " psrlw $8, %%mm4 \n\t" /* right just chroma */
- " pmullw %%mm6, %%mm2 \n\t" /* mult by weighting factor */
- " pmullw %%mm6, %%mm4 \n\t" /* mult by weighting factor */
-
- " paddw %%mm2, %%mm1 \n\t" /* combine lumas */
- " paddusw %%mm0, %%mm1 \n\t" /* round */
- " psrlw $8, %%mm1 \n\t" /* right adjust luma */
-#ifdef STREAMING_STORE_TMP
- " movntq %%mm1, (%%"REGDI", %%"REGA", 2) \n\t" /* save lumas in our work area */
-#else
- " movq %%mm1, (%%"REGDI", %%"REGA", 2) \n\t" /* save lumas in our work area */
-#endif
- " paddw %%mm4, %%mm3 \n\t" /* combine chromas */
- " paddusw %%mm0, %%mm3 \n\t" /* round */
- " psrlw $8, %%mm3 \n\t" /* right adjust chroma */
- " packuswb %%mm3, %%mm3 \n\t" /* pack UV's into low dword */
- " movd %%mm3, (%%"REGB", %%"REGA") \n\t" /* save in our work area */
-
- " lea 4(%%"REGA"), %%"REGA" \n\t"
- " decl %%"REGC" \n\t"
- " jg "vLoopSSEMMX_Fetch"b \n\t" /* if not on last one loop, prefetch */
- " jz "vLoopSSEMMX"b \n\t" /* or just loop, or not */
-#ifdef STREAMING_STORE_TMP
- " sfence \n\t"
-#endif
- " jmp "MoreSpareChange"f \n" /* all done with vertical */
-
- ".align 16 \n"
- ""vLoopMMX": \n\t"
-
- " movq (%%"REGSI", %%"REGA", 2), %%mm1 \n\t" /* top of 2 lines to interpolate */
- " movq (%%"REGD", %%"REGA", 2), %%mm2 \n\t" /* 2nd of 2 lines */
-
- " movq %%mm1, %%mm3 \n\t" /* copy top bytes */
- " pand %%mm7, %%mm1 \n\t" /* keep only luma */
- " pxor %%mm1, %%mm3 \n\t" /* keep only chroma */
- " psrlw $8, %%mm3 \n\t" /* right just chroma */
- " pmullw %%mm5, %%mm1 \n\t" /* mult by weighting factor */
- " pmullw %%mm5, %%mm3 \n\t" /* mult by weighting factor */
-
- " movq %%mm2, %%mm4 \n\t" /* copy 2nd bytes */
- " pand %%mm7, %%mm2 \n\t" /* keep only luma */
- " pxor %%mm2, %%mm4 \n\t" /* keep only chroma */
- " psrlw $8, %%mm4 \n\t" /* right just chroma */
- " pmullw %%mm6, %%mm2 \n\t" /* mult by weighting factor */
- " pmullw %%mm6, %%mm4 \n\t" /* mult by weighting factor */
-
- " paddw %%mm2, %%mm1 \n\t" /* combine lumas */
- " paddusw %%mm0, %%mm1 \n\t" /* round */
- " psrlw $8, %%mm1 \n\t" /* right adjust luma */
- " movq %%mm1, (%%"REGDI", %%"REGA", 2) \n\t" /* save lumas in our work area */
-
- " paddw %%mm4, %%mm3 \n\t" /* combine chromas */
- " paddusw %%mm0, %%mm3 \n\t" /* round */
- " psrlw $8, %%mm3 \n\t" /* right adjust chroma */
- " packuswb %%mm3, %%mm3 \n\t" /* pack UV's into low dword */
- " movd %%mm3, (%%"REGB", %%"REGA") \n\t" /* save in our work area */
-
- " lea 4(%%"REGA"), %%"REGA" \n\t"
- " loop "vLoopMMX"b \n"
-
- /* Add a little code here to check if we have 2 more pixels to do and, if so, make one
- * more pass thru vLoopMMX. We were processing in multiples of 4 pixels and alway have
- * an even number so there will never be more than 2 left. trbarry 7/29/2002
- */
- ""MoreSpareChange": \n\t"
-
- " cmpl "_EndOffset", %%"REGEA" \n\t" /* did we get them all */
- " jnl "DoHorizontal"f \n\t" /* yes, else have 2 left */
- " movl $1, %%"REGC" \n\t" /* jigger loop ct */
- " sub $2, %%"REGA" \n\t" /* back up 2 pixels (4 bytes, but eax carried as 1/2) */
- " jmp "vLoopMMX"b \n"
-
- /* We've taken care of the vertical scaling, now do horizontal */
- ""DoHorizontal": \n\t"
-
- " movq "_YMask", %%mm7 \n\t" /* useful 0U0U.. mask constant */
- " movq "_FPround2", %%mm6 \n\t" /* useful rounding constant, dwords */
- " mov "_pControl", %%"REGSI" \n\t" /* @ horiz control bytes */
- " movl "_row_size", %%"REGC" \n\t"
- " shrl $2, %%"REGC" \n\t" /* bytes a time, 2 pixels */
- " mov "_vWorkYW", %%"REGD" \n\t" /* our luma data, as 0Y0Y 0Y0Y.. */
- " mov "_dstp", %%"REGDI" \n\t" /* the destination line */
- " mov "_vWorkUVW", %%"REGB" \n" /* chroma data, as UVUV UVUV... */
-
- ".align 16 \n"
- ""hLoopMMX": \n\t"
-
- /* x86_64: must use movl (accessing table of uint32's) */
- " movl 16(%%"REGSI"), %%"REGEA" \n\t" /* get data offset in pixels, 1st pixel pair */
- " movd (%%"REGD", %%"REGA", 2), %%mm0 \n\t" /* copy luma pair */
- " shr $1, %%"REGA" \n\t" /* div offset by 2 */
- " movd (%%"REGB", %%"REGA", 2), %%mm1 \n\t" /* copy UV pair VUVU */
- " psllw $8, %%mm1 \n\t" /* shift out V, keep 0000U0U0 */
-
- /* we need to use both even and odd croma from same location - trb 9/2002 */
- " punpckldq (%%"REGB", %%"REGA", 2), %%mm1 \r\n" /* copy UV pair VUVU */
- " psrlw $8, %%mm1 \r\n" /* shift out U0, keep 0V0V 0U0U */
- " movl 20(%%"REGSI"), %%"REGEA" \r\n" /* get data offset in pixels, 2nd pixel pair */
- " punpckldq (%%"REGD", %%"REGA", 2), %%mm0 \r\n" /* copy luma pair */
-
- " pmaddwd (%%"REGSI"), %%mm0 \r\n" /* mult and sum lumas by ctl weights */
- " paddusw %%mm6, %%mm0 \r\n" /* round */
- " psrlw $8, %%mm0 \r\n" /* right just 2 luma pixel value 000Y,000Y */
-
- " pmaddwd 8(%%"REGSI"), %%mm1 \r\n" /* mult and sum chromas by ctl weights */
- " paddusw %%mm6, %%mm1 \r\n" /* round */
- " pslld $8, %%mm1 \r\n" /* shift into low bytes of different words */
- " pand %%mm7, %%mm1 \r\n" /* keep only 2 chroma values 0V00,0U00 */
- " por %%mm1, %%mm0 \r\n" /* combine luma and chroma, 0V0Y,0U0Y */
- " packuswb %%mm0, %%mm0 \r\n" /* pack all into low dword, xxxxVYUY */
- " movd %%mm0, (%%"REGDI") \n\t" /* done with 2 pixels */
-
- " lea 24(%%"REGSI"), %%"REGSI" \n\t" /* bump to next control bytest */
- " lea 4(%%"REGDI"), %%"REGDI" \n\t" /* bump to next output pixel addr */
-
- " loop "hLoopMMX"b \n\t" /* loop for more */
-
- "emms \n\t"
- /* done with one line */
-
-#if !defined(__x86_64__)
- "mov "_oldbx", %%"REGB" \n\t"
-#endif
- ::
- "m" /*0*/(FPround1),
- "m" /*1*/(vWeight1),
- "m" /*2*/(vWeight2),
- "m" /*3*/(YMask),
- "m" /*4*/(src_row_size),
- "m" /*5*/(EndOffset),
- "m" /*6*/(pControl),
- "m" /*7*/(row_size),
- "m" /*8*/(vWorkYW),
- "m" /*9*/(dstp),
- "m" /*10*/(vWorkUVW),
- "m" /*11*/(FPround2),
- "m" /*12*/(srcp1),
- "m" /*13*/(srcp2)
-#if !defined(__x86_64__)
- ,
- "m" /*14*/(oldbx),
- "m" /*15*/(SSEMMXenabledW),
- "m" /*16*/(SSE2enabledW)
- : REGA, /*REGB,*/ REGC, REGD, REGSI, REGDI
-#else
- : REGA, REGB, REGC, REGD, REGSI, REGDI
-#endif
- );
-
- dstp += dst_pitch;
- }
-#endif
- return 0;
-}
-
-static int do_warp_yv12(uint8_t *dst, const uint8_t * const src,
- const int dst_pitch, const int src_pitch,
- const int dst_width, const int dst_height,
- const int src_width, const int src_height,
- const int Interlaced, const uint32_t * const hControl,
- const uint32_t * vOffsets, const uint32_t * vWeights,
- uint32_t *vWorkY, int dst_start)
-{
-#if defined(__i386__) || defined(__x86_64__)
- sse2_t FPround1 = {uq:{UINT64_C(0x0080008000800080),UINT64_C(0x0080008000800080)}}; /* round words */
- sse2_t FPround2 = {uq:{UINT64_C(0x0000008000000080),UINT64_C(0x0000008000000080)}}; /* round dwords */
- sse2_t vWeight1;
- sse2_t vWeight2;
-
- const uint32_t *pControl = &hControl[0];
- const uint32_t *vWorkYW = vWorkY;
- const uint8_t *srcp = src;
- const uint8_t *srcp1;
- const uint8_t *srcp2;
- uint8_t *dstp = dst + dst_pitch*dst_start;
-
- const uint32_t src_row_size = src_width;
- const uint32_t row_size = dst_width;
-
-#if !defined(__x86_64__)
- const int accel = xine_mm_accel();
- const uint32_t SSE2enabledW = !!(accel & MM_ACCEL_X86_SSE2); /* in local storage for asm */
- const uint32_t SSEMMXenabledW = !!(accel & MM_ACCEL_X86_MMXEXT); /* in local storage for asm */
- long int oldbx;
-#endif
- int y;
-
- /* Operation in sliced mode:
- * - continue until required next source line is out of slice
- * - return next output line
- * - at next call, continue from next souce line
- */
-
- for (y = dst_start; y < dst_height; y++) {
- if(vOffsets[y] >= src_height) {
- /* slice completed */
- /*DBG("do_warp_yv12: max input height reached: need line %d, height %d\n -> Returning next output line: %d , start was %d\n",
- (int)vOffsets[y], (int)src_height, (int)y, (int)dst_start);*/
- return y;
- }
-
- vWeight1.ud[0] = vWeight1.ud[1] = vWeight1.ud[2] = vWeight1.ud[3] =
- (256-vWeights[y]) << 16 | (256-vWeights[y]);
- vWeight2.ud[0] = vWeight2.ud[1] = vWeight2.ud[2] = vWeight2.ud[3] =
- vWeights[y] << 16 | vWeights[y];
-
- srcp1 = srcp + vOffsets[y] * src_pitch;
-
- if (Interlaced)
- srcp2 = (y < dst_height-2) ? srcp1 + 2 * src_pitch : srcp1;
- else
- srcp2 = (y < dst_height-1) ? srcp1 + src_pitch : srcp1;
-
- __asm__ __volatile__(
- "movl "_src_row_size", %%"REGC" \n\t"
- "shr $3, %%"REGC" \n\t" /* 8 bytes a time */
- "mov "_srcp1", %%"REGSI" \n\t" /* top of 2 src lines to get */
- "mov "_srcp2", %%"REGD" \n\t" /* next " */
- "mov "_vWorkYW", %%"REGDI" \n\t" /* luma work destination line */
- "xor %%"REGA", %%"REGA" \n\t"
-#if !defined(__x86_64__)
- /* Let's check here to see if we are on a P4 or higher and can use SSE2 instructions.
- * This first loop is not the performance bottleneck anyway but it is trivial to tune
- * using SSE2 if we have proper alignment.
- */
- "testl $1, "_SSE2enabledW" \n\t" /* is SSE2 supported? */
- "jz "vMaybeSSEMMX"f \n\t" /* n, can't do anyway */
-#endif
- "cmpl $2, %%"REGC" \n\t" /* we have at least 16 byts, 2 qwords? */
- "jl "vMaybeSSEMMX"f \n\t" /* n, don't bother */
-
- "mov %%"REGSI", %%"REGB" \n\t"
- "or %%"REGD", %%"REGB" \n\t"
- "test $15, %%"REGB" \n\t" /* both src rows 16 byte aligned? */
- "jnz "vMaybeSSEMMX"f \n\t" /* n, don't use sse2 */
-
- "shr $1, %%"REGC" \n\t" /* do 16 bytes at a time instead */
- "dec %%"REGC" \n\t" /* jigger loop ct */
-
- "movdqa "_FPround1", %%xmm0 \n\t"
- "movdqa "_vWeight1", %%xmm5 \n\t"
- "movdqa "_vWeight2", %%xmm6 \n\t"
- "pxor %%xmm7, %%xmm7 \n"
-
- ".align 16 \n"
- ""vLoopSSE2_Fetch": \n\t"
-#ifdef PREFETCH
- " prefetcht0 16(%%"REGSI", %%"REGA", 2) \n\t"
- " prefetcht0 16(%%"REGD", %%"REGA", 2) \n"
-#endif
- ""vLoopSSE2": \n\t"
- /* we're already checked pointers to be on dqword aligned */
- " movdqa (%%"REGSI", %%"REGA"), %%xmm1 \n\t" /* top of 2 lines to interpolate */
- " movdqa (%%"REGD", %%"REGA"), %%xmm3 \n\t" /* 2nd of 2 lines */
- " movdqa %%xmm1, %%xmm2 \n\t"
- " movdqa %%xmm3, %%xmm4 \n\t"
-
- " punpcklbw %%xmm7, %%xmm1 \n\t" /* make words */
- " punpckhbw %%xmm7, %%xmm2 \n\t" /* " */
- " punpcklbw %%xmm7, %%xmm3 \n\t" /* " */
- " punpckhbw %%xmm7, %%xmm4 \n\t" /* " */
-
- " pmullw %%xmm5, %%xmm1 \n\t" /* mult by top weighting factor */
- " pmullw %%xmm5, %%xmm2 \n\t" /* " */
- " pmullw %%xmm6, %%xmm3 \n\t" /* mult by bot weighting factor */
- " pmullw %%xmm6, %%xmm4 \n\t" /* " */
-
- " paddw %%xmm3, %%xmm1 \n\t" /* combine lumas low */
- " paddw %%xmm4, %%xmm2 \n\t" /* combine lumas high */
-
- " paddusw %%xmm0, %%xmm1 \n\t" /* round */
- " paddusw %%xmm0, %%xmm2 \n\t" /* round */
-
- " psrlw $8, %%xmm1 \n\t" /* right adjust luma */
- " psrlw $8, %%xmm2 \n\t" /* right adjust luma */
-
- " packuswb %%xmm2, %%xmm1 \n\t" /* pack words to our 16 byte answer */
-#ifdef STREAMING_STORE_TMP
- " movntdq %%xmm1, (%%"REGDI", %%"REGA") \n\t" /* save lumas in our work area */
-#else
- " movdqu %%xmm1, (%%"REGDI", %%"REGA") \n\t" /* save lumas in our work area */
-#endif
- " lea 16(%%"REGA"), %%"REGA" \n\t"
- " decl %%"REGC" \n\t"
-
- " jg "vLoopSSE2_Fetch"b \n\t" /* if not on last one loop, prefetch */
- " jz "vLoopSSE2"b \n\t" /* or just loop, or not */
-
- /* done with our SSE2 fortified loop but we may need to pick up the spare change */
-#ifdef STREAMING_STORE_TMP
- " sfence \n\t"
-#endif
- " movl "_src_row_size", %%"REGC" \n\t" /* get count again */
- " andl $15, %%"REGC" \n\t" /* just need mod 16 */
- " movq "_vWeight1", %%mm5 \n\t"
- " movq "_vWeight2", %%mm6 \n\t"
- " movq "_FPround1", %%mm0 \n\t" /* useful rounding constant */
-
- " shrl $3, %%"REGC" \n\t" /* 8 bytes at a time, any? */
- " jz "MoreSpareChange"f \n" /* n, did them all */
-
- /* Let's check here to see if we are on a P2 or Athlon and can use SSEMMX instructions.
- * This first loop is not the performance bottleneck anyway but it is trivial to tune
- * using SSE if we have proper alignment.
- */
- ""vMaybeSSEMMX": \n\t"
-
- " movq "_vWeight1", %%mm5 \n\t"
- " movq "_vWeight2", %%mm6 \n\t"
- " movq "_FPround1", %%mm0 \n\t" /* useful rounding constant */
- " pxor %%mm7, %%mm7 \n\t"
-#if !defined(__x86_64__)
- " testl $1, "_SSEMMXenabledW" \n\t"/* MMXEXTsupported? */
- " jz "vLoopMMX"f \n\t" /* n, can't do anyway */
-#endif
- " decl %%"REGC" \n" /* jigger loop ctr */
-
- ".align 16 \n"
- ""vLoopSSEMMX_Fetch": \n\t"
-#ifdef PREFETCH
- " prefetcht0 8(%%"REGSI", %%"REGA") \n\t"
- " prefetcht0 8(%%"REGD", %%"REGA") \n"
-#endif
- ""vLoopSSEMMX": \n\t"
-
- " movq (%%"REGSI", %%"REGA"), %%mm1 \n\t" /* top of 2 lines to interpolate */
- " movq (%%"REGD", %%"REGA"), %%mm3 \n\t" /* 2nd of 2 lines */
-
- " movq %%mm1, %%mm2 \n\t"
- " movq %%mm3, %%mm4 \n\t"
-
- " punpcklbw %%mm7, %%mm1 \n\t" /* make words */
- " punpckhbw %%mm7, %%mm2 \n\t" /* " */
- " punpcklbw %%mm7, %%mm3 \n\t" /* " */
- " punpckhbw %%mm7, %%mm4 \n\t" /* " */
-
- " pmullw %%mm5, %%mm1 \n\t" /* mult by top weighting factor */
- " pmullw %%mm5, %%mm2 \n\t" /* " */
- " pmullw %%mm6, %%mm3 \n\t" /* mult by bot weighting factor */
- " pmullw %%mm6, %%mm4 \n\t" /* " */
-
- " paddw %%mm3, %%mm1 \n\t" /* combine lumas low */
- " paddw %%mm4, %%mm2 \n\t" /* combine lumas high */
-
- " paddusw %%mm0, %%mm1 \n\t" /* round */
- " paddusw %%mm0, %%mm2 \n\t" /* round */
-
- " psrlw $8, %%mm1 \n\t" /* right adjust luma */
- " psrlw $8, %%mm2 \n\t" /* right adjust luma */
-
- " packuswb %%mm2, %%mm1 \n\t" /* pack words to our 8 byte answer */
-#ifdef STREAMING_STORE_TMP
- " movntq %%mm1, (%%"REGDI", %%"REGA") \n\t" /* save lumas in our work area */
-#else
- " movq %%mm1, (%%"REGDI", %%"REGA") \n\t" /* save lumas in our work area */
-#endif
- " lea 8(%%"REGA"), %%"REGA" \n\t"
- " decl %%"REGC" \n\t"
-
- " jg "vLoopSSEMMX_Fetch"b \n\t" /* if not on last one loop, prefetch */
- " jz "vLoopSSEMMX"b \n\t" /* or just loop, or not */
-#ifdef STREAMING_STORE_TMP
- " sfence \n\t"
-#endif
- " jmp "MoreSpareChange"f \n" /* all done with vertical */
-
- ".align 16 \n"
- ""vLoopMMX": \n\t"
-
- " movq (%%"REGSI", %%"REGA"), %%mm1 \n\t" /* top of 2 lines to interpolate */
- " movq (%%"REGD", %%"REGA"), %%mm3 \n\t" /* 2nd of 2 lines */
-
- " movq %%mm1, %%mm2 \n\t"
- " movq %%mm3, %%mm4 \n\t"
-
- " punpcklbw %%mm7, %%mm1 \n\t" /* make words */
- " punpckhbw %%mm7, %%mm2 \n\t" /* " */
- " punpcklbw %%mm7, %%mm3 \n\t" /* " */
- " punpckhbw %%mm7, %%mm4 \n\t" /* " */
-
- " pmullw %%mm5, %%mm1 \n\t" /* mult by top weighting factor */
- " pmullw %%mm5, %%mm2 \n\t" /* " */
- " pmullw %%mm6, %%mm3 \n\t" /* mult by bot weighting factor */
- " pmullw %%mm6, %%mm4 \n\t" /* " */
-
- " paddw %%mm3, %%mm1 \n\t" /* combine lumas low */
- " paddw %%mm4, %%mm2 \n\t" /* combine lumas high */
-
- " paddusw %%mm0, %%mm1 \n\t" /* round */
- " paddusw %%mm0, %%mm2 \n\t" /* round */
-
- " psrlw $8, %%mm1 \n\t" /* right adjust luma */
- " psrlw $8, %%mm2 \n\t" /* right adjust luma */
-
- " packuswb %%mm2, %%mm1 \n\t" /* pack words to our 8 byte answer */
- " movq %%mm1, (%%"REGDI", %%"REGA") \n\t" /* save lumas in our work area */
-
- " lea 8(%%"REGA"), %%"REGA" \n\t"
- " loop "vLoopMMX"b \n"
-
- /* Add a little code here to check if we have more pixels to do and, if so, make one
- * more pass thru vLoopMMX. We were processing in multiples of 8 pixels and alway have
- * an even number so there will never be more than 7 left.
- */
- ""MoreSpareChange": \n\t"
-
- " cmpl "_src_row_size", %%"REGEA" \n\t" /* did we get them all */
- " jnl "DoHorizontal"f \n\t" /* yes, else have 2 left */
- " movl $1, %%"REGC" \n\t" /* jigger loop ct */
- " movl "_src_row_size", %%"REGEA" \n\t"
- " sub $8, %%"REGA" \n\t" /* back up to last 8 pixels */
- " jmp "vLoopMMX"b \n"
-
- /* We've taken care of the vertical scaling, now do horizontal */
- ""DoHorizontal": \n\t"
- " pxor %%mm7, %%mm7 \n\t"
- " movq "_FPround2", %%mm6 \n\t" /* useful rounding constant, dwords */
- " mov "_pControl", %%"REGSI" \n\t" /* @ horiz control bytes */
- " movl "_row_size", %%"REGC" \n\t"
- " shrl $2, %%"REGC" \n\t" /* 4 bytes a time, 4 pixels */
- " mov "_vWorkYW", %%"REGD" \n\t" /* our luma data, as 0Y0Y 0Y0Y.. */
- " mov "_dstp", %%"REGDI" \n\t" /* the destination line */
-#if !defined(__x86_64__)
- " testl $1, "_SSEMMXenabledW" \n\t" /* MMXEXTsupported? */
- " jz "hLoopMMX"f \n\t" /* n, can't do anyway */
-#endif
- /* With SSE support we will make 8 pixels (from 8 pairs) at a time */
- " shrl $1, %%"REGC" \n\t" /* 8 bytes a time instead of 4 */
- " jz "LessThan8"f \n"
-
- ".align 16 \n"
- ""hLoopMMXSSE": \n\t"
-
-
- /* handle first 2 pixels */
- /* phi: must use movl here (x86_64, reading from table of uint_32's) */
- " movl 16(%%"REGSI"), %%"REGEA" \n\t" /* get data offset in pixels, 1st pixel pair */
- " movl 20(%%"REGSI"), %%"REGEB" \r\n" /* get data offset in pixels, 2nd pixel pair */
-
- " movd (%%"REGD", %%"REGA"), %%mm0 \n\t" /* copy luma pair 0000xxYY */
- " punpcklwd (%%"REGD", %%"REGB"), %%mm0 \r\n" /* 2nd luma pair, now xxxxYYYY */
- " punpcklbw %%mm7, %%mm0 \n\t" /* make words out of bytes, 0Y0Y0Y0Y */
- " movl 16+24(%%"REGSI"), %%"REGEA" \n\t" /* get data offset in pixels, 3st pixel pair */
- " movl 20+24(%%"REGSI"), %%"REGEB" \r\n" /* get data offset in pixels, 4nd pixel pair */
- " pmaddwd (%%"REGSI"), %%mm0 \n\t" /* mult and sum lumas by ctl weights */
- " paddusw %%mm6, %%mm0 \n\t" /* round */
- " psrlw $8, %%mm0 \n\t" /* right just 4 luma pixel value 0Y0Y0Y0Y */
-
- /* handle 3rd and 4th pixel pairs */
- " movd (%%"REGD", %%"REGA"), %%mm1 \n\t" /* copy luma pair 0000xxYY */
- " punpcklwd (%%"REGD", %%"REGB"), %%mm1 \r\n" /* 2nd luma pair, now xxxxYYYY */
- " punpcklbw %%mm7, %%mm1 \n\t" /* make words out of bytes, 0Y0Y0Y0Y */
- " movl 16+48(%%"REGSI"), %%"REGEA" \n\t" /* get data offset in pixels, 5st pixel pair */
- " movl 20+48(%%"REGSI"), %%"REGEB" \r\n" /* get data offset in pixels, 6nd pixel pair */
- " pmaddwd 24(%%"REGSI"), %%mm1 \n\t" /* mult and sum lumas by ctl weights */
- " paddusw %%mm6, %%mm1 \n\t" /* round */
- " psrlw $8, %%mm1 \n\t" /* right just 4 luma pixel value 0Y0Y0Y0Y */
-
- /* handle 5th and 6th pixel pairs */
- " movd (%%"REGD", %%"REGA"), %%mm2 \n\t" /* copy luma pair 0000xxYY */
- " punpcklwd (%%"REGD", %%"REGB"), %%mm2 \r\n" /* 2nd luma pair, now xxxxYYYY */
- " punpcklbw %%mm7, %%mm2 \n\t" /* make words out of bytes, 0Y0Y0Y0Y */
- " movl 16+72(%%"REGSI"), %%"REGEA" \n\t" /* get data offset in pixels, 7st pixel pair */
- " movl 20+72(%%"REGSI"), %%"REGEB" \r\n" /* get data offset in pixels, 8nd pixel pair */
- " pmaddwd 48(%%"REGSI"), %%mm2 \n\t" /* mult and sum lumas by ctl weights */
- " paddusw %%mm6, %%mm2 \n\t" /* round */
- " psrlw $8, %%mm2 \n\t" /* right just 4 luma pixel value 0Y0Y0Y0Y */
-
- /* handle 7th and 8th pixel pairs */
- " movd (%%"REGD", %%"REGA"), %%mm3 \n\t" /* copy luma pair 0000xxYY */
- " punpcklwd (%%"REGD", %%"REGB"), %%mm3 \r\n" /* 2nd luma pair, now xxxxYYYY */
- " punpcklbw %%mm7, %%mm3 \n\t" /* make words out of bytes, 0Y0Y0Y0Y */
- " pmaddwd 72(%%"REGSI"), %%mm3 \n\t" /* mult and sum lumas by ctl weights */
- " paddusw %%mm6, %%mm3 \n\t" /* round */
- " psrlw $8, %%mm3 \n\t" /* right just 4 luma pixel value 0Y0Y0Y0Y */
-
- /* combine, store, and loop */
- " packuswb %%mm1, %%mm0 \n\t" /* pack into qword, 0Y0Y0Y0Y */
- " packuswb %%mm3, %%mm2 \n\t" /* pack into qword, 0Y0Y0Y0Y */
- " packuswb %%mm2, %%mm0 \n\t" /* and again into YYYYYYYY */
-#ifdef STREAMING_STORE
- " movntq %%mm0, (%%"REGDI") \n\t" /* done with 4 pixels */
-#else
- " movq %%mm0, (%%"REGDI") \n\t" /* done with 4 pixels */
-#endif
-
- " lea 96(%%"REGSI"), %%"REGSI" \n\t"
- " lea 8(%%"REGDI"), %%"REGDI" \n\t"
- " decl %%"REGC" \n\t"
- " jg "hLoopMMXSSE"b \n\t" /* loop for more */
-#ifdef STREAMING_STORE
- " sfence \n"
-#endif
- ""LessThan8": \n\t"
- " movl "_row_size", %%"REGC" \n\t"
- " andl $7, %%"REGC" \n\t" /* we have done all but maybe this */
- " shrl $2, %%"REGC" \n\t" /* now do only 4 bytes at a time */
- " jz "LessThan4"f \n"
-
- ".align 16 \n"
- ""hLoopMMX": \n\t"
-
- /* handle first 2 pixels */
- " movl 16(%%"REGSI"), %%"REGEA" \n\t" /* get data offset in pixels, 1st pixel pair */
- " movl 20(%%"REGSI"), %%"REGEB" \r\n" /* get data offset in pixels, 2nd pixel pair */
- " movd (%%"REGD", %%"REGA"), %%mm0 \n\t" /* copy luma pair 0000xxYY */
- " punpcklwd (%%"REGD", %%"REGB"), %%mm0 \r\n" /* 2nd luma pair, now xxxxYYYY */
- " punpcklbw %%mm7, %%mm0 \n\t" /* make words out of bytes, 0Y0Y0Y0Y */
- " movl 16+24(%%"REGSI"), %%"REGEA" \n\t" /* get data offset in pixels, 3st pixel pair */
- " movl 20+24(%%"REGSI"), %%"REGEB" \r\n" /* get data offset in pixels, 4nd pixel pair */
- " pmaddwd (%%"REGSI"), %%mm0 \n\t" /* mult and sum lumas by ctl weights */
- " paddusw %%mm6, %%mm0 \n\t" /* round */
- " psrlw $8, %%mm0 \n\t" /* right just 4 luma pixel value 0Y0Y0Y0Y */
-
- /* handle 3rd and 4th pixel pairs */
- " movd (%%"REGD", %%"REGA"), %%mm1 \n\t" /* copy luma pair 0000xxYY */
- " punpckldq (%%"REGD", %%"REGB"), %%mm1 \r\n" /* 2nd luma pair, now xxxxYYYY */
- " punpcklbw %%mm7, %%mm1 \n\t" /* make words out of bytes, 0Y0Y0Y0Y */
- " pmaddwd 24(%%"REGSI"), %%mm1 \n\t" /* mult and sum lumas by ctl weights */
- " paddusw %%mm6, %%mm1 \n\t" /* round */
- " psrlw $8, %%mm1 \n\t" /* right just 4 luma pixel value 0Y0Y0Y0Y */
-
- /* combine, store, and loop */
- " packuswb %%mm1, %%mm0 \n\t" /* pack into qword, 0Y0Y0Y0Y */
- " packuswb %%mm7, %%mm0 \n\t" /* and again into 0000YYYY */
- " movd %%mm0, (%%"REGDI") \n\t" /* done with 4 pixels */
- " lea 48(%%"REGSI"), %%"REGSI" \n\t"
- " lea 4(%%"REGDI"), %%"REGDI" \n\t"
-
- " loop "hLoopMMX"b \n" /* loop for more */
-
- /* test to see if we have a mod 4 size row, if not then more spare change */
- ""LessThan4": \n\t"
- " movl "_row_size", %%"REGC" \n\t"
- " andl $3, %%"REGC" \n\t" /* remainder side mod 4 */
- " cmpl $2, %%"REGC" \n\t"
- " jl "LastOne"f \n\t" /* none, none */
-
- /* handle 2 more pixels */
- " movl 16(%%"REGSI"), %%"REGEA" \n\t" /* get data offset in pixels, 1st pixel pair */
- " movl 20(%%"REGSI"), %%"REGEB" \r\n" /* get data offset in pixels, 2nd pixel pair */
- " movd (%%"REGD", %%"REGA"), %%mm0 \n\t" /* copy luma pair 0000xxYY */
- " punpcklwd (%%"REGD", %%"REGB"), %%mm0 \r\n" /* 2nd luma pair, now xxxxYYYY */
- " punpcklbw %%mm7, %%mm0 \n\t" /* make words out of bytes, 0Y0Y0Y0Y */
-
- " pmaddwd (%%"REGSI"), %%mm0 \n\t" /* mult and sum lumas by ctl weights */
- " paddusw %%mm6, %%mm0 \n\t" /* round */
- " psrlw $8, %%mm0 \n\t" /* right just 4 luma pixel value 0Y0Y0Y0Y */
- " packuswb %%mm7, %%mm0 \n\t" /* pack into qword, 00000Y0Y */
- " packuswb %%mm7, %%mm0 \n\t" /* and again into 000000YY */
- " movd %%mm0, (%%"REGDI") \n\t" /* store, we are guarrenteed room in buffer (8 byte mult) */
- " subl $2, %%"REGC" \n\t"
-
- " lea 24(%%"REGSI"), %%"REGSI" \n\t" /* bump to next control bytes */
- " lea 2(%%"REGDI"), %%"REGDI" \n" /* bump to next output pixel addr */
-
- /* maybe one last pixel */
- ""LastOne": \n\t"
- " cmpl $0, %%"REGC" \r\n" /* still more ? */
- " jz "AllDone"f \r\n" /* n, done */
- " movl 16(%%"REGSI"), %%"REGEA" \n\t" /* get data offset in pixels, 1st pixel pair */
- " movd (%%"REGD", %%"REGA"), %%mm0 \n\t" /* copy luma pair 0000xxYY */
- " punpcklbw %%mm7, %%mm0 \n\t" /* make words out of bytes, 0Y0Y0Y0Y */
-
- " pmaddwd (%%"REGSI"), %%mm0 \n\t" /* mult and sum lumas by ctl weights */
- " paddusw %%mm6, %%mm0 \n\t" /* round */
- " psrlw $8, %%mm0 \n\t" /* right just 4 luma pixel value 0Y0Y0Y0Y */
- " movd %%mm0, %%"REGEA" \n\t"
- " movb %%al, (%%"REGDI") \n" /* store last one */
-
- ""AllDone": \n\t"
- " emms \n\t"
-#if !defined(__x86_64__)
- "mov "_oldbx", %%"REGB" \n\t"
-#endif
- ::
- "m" /*0*/(FPround1),
- "m" /*1*/(vWeight1),
- "m" /*2*/(vWeight2),
- "m" /*3*/(y/*YMask[0]*/),
- "m" /*4*/(src_row_size),
- "m" /*5*/(y/*EndOffset*/),
- "m" /*6*/(pControl),
- "m" /*7*/(row_size),
- "m" /*8*/(vWorkYW),
- "m" /*9*/(dstp),
- "m" /*10*/(y/*vWorkUVW*/),
- "m" /*11*/(FPround2),
- "m" /*12*/(srcp1),
- "m" /*13*/(srcp2)
-#if !defined(__x86_64__)
- ,
- "m" /*14*/(oldbx),
- "m" /*15*/(SSEMMXenabledW),
- "m" /*16*/(SSE2enabledW)
- : REGA, /*REGB,*/ REGC, REGD, REGSI, REGDI
-#else
- : REGA, REGB, REGC, REGD, REGSI, REGDI
-#endif
- );
-
- dstp += dst_pitch;
- }
-#endif
- return 0;
-}
-
-/*
- * tools
- */
-
-#ifndef ALIGN
-# define ALIGN(b,p) ((void*)((((unsigned long)(p)) + (b)-1) & (~((b)-1))))
-#endif
-#ifndef MIN
-# define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-#ifndef MAX
-# define MAX(a,b) ((a) > (b) ? (a) : (b))
-#endif
-#ifndef FABS
-# define FABS(x) ((x) < 0.0 ? -(x) : (x))
-#endif
-
-/*
- * xine plugin
- */
-
-#define PLUGIN_ID "warp"
-#define PLUGIN_DESCR "(non-)linear software scaling post plugin";
-#define PLUGIN_T warp_plugin_t
-/*#define POST_THREADS*/
-/*#define POST_SLICES*/
-#include "xine/post_util.h"
-
-
-/* plugin class initialization function */
-void *warp_init_plugin(xine_t *xine, void *);
-
-/* plugin class functions */
-static post_plugin_t *open_plugin(post_class_t *class_gen, int inputs,
- xine_audio_port_t **audio_target,
- xine_video_port_t **video_target);
-
-/* plugin instance functions */
-static void warp_dispose(post_plugin_t *this_gen);
-
-/* vo_frame functions */
-static vo_frame_t *got_frame(vo_frame_t *frame);
-static void draw_internal(vo_frame_t *frame, vo_frame_t *new_frame);
-
-
-/* parameter functions */
-static xine_post_api_descr_t *warp_get_param_descr(void);
-static int warp_set_parameters(xine_post_t *this_gen, void *param_gen);
-static int warp_get_parameters(xine_post_t *this_gen, void *param_gen);
-static char *warp_get_help(void);
-
-
-typedef struct warp_parameters_s {
- int output_width;
- int output_height;
- double output_aspect;
- int no_downscaling;
-} warp_parameters_t;
-
-START_PARAM_DESCR(warp_parameters_t)
-PARAM_ITEM(POST_PARAM_TYPE_INT, output_width, NULL, 640, 1920, 0,
- "output video width")
-PARAM_ITEM(POST_PARAM_TYPE_INT, output_height, NULL, 480, 1080, 0,
- "output video height")
-PARAM_ITEM(POST_PARAM_TYPE_DOUBLE, output_aspect, NULL, 1, 3, 0,
- "output video aspect ratio")
-PARAM_ITEM(POST_PARAM_TYPE_BOOL, no_downscaling,NULL, 0, 1, 0,
- "disable downscaling")
-END_PARAM_DESCR(warp_param_descr)
-
-
-typedef struct {
- post_plugin_t post;
-
- xine_post_in_t parameter_input;
-
- /* User config (changes to actual config are delayed) */
- warp_parameters_t config;
-
- /* Current config */
- int enable;
- int output_width;
- int output_height;
- double output_aspect;
- double factor_x;
- double factor_y;
-
- /* Last seen input frame */
- int input_width;
- int input_height;
- int input_format;
- int input_interlaced;
- double input_aspect;
-
- /* working buffers */
- uint32_t *vWorkY;
- uint32_t *vWorkUV;
-
- /* scaling tables */
- uint32_t *hControl;
- uint32_t *hControlUV;
- uint32_t *vOffsets;
- uint32_t *vOffsetsUV;
- uint32_t *vWeights;
- uint32_t *vWeightsUV;
-
- /* memory for work areas and scaling tables */
- void *pMem;
-
-} warp_plugin_t;
-
-/*
- *
- */
-
-static void init_tables(warp_plugin_t *this)
-{
-#define BP(x) ((uint8_t*)(x))
- /* allocate memory for scaling tables and workspace */
- free(this->pMem);
- this->pMem = malloc(this->input_width*3 + this->output_width*sizeof(uint32_t)*3*2 +
- this->output_height*sizeof(uint32_t)*4 + 2*9*128);
-
- /* - aligned for P4 cache line */
- this->vWorkY = (uint32_t*)ALIGN(128, this->pMem);
- this->vWorkUV = (uint32_t*)ALIGN(128, BP(this->vWorkY) + this->input_width*2 + 128);
- this->hControl = (uint32_t*)ALIGN(128, BP(this->vWorkUV) + this->input_width + 128);
- this->vOffsets = (uint32_t*)ALIGN(128, BP(this->hControl) + this->output_width * sizeof(uint32_t) * 3 + 128);
- this->vWeights = (uint32_t*)ALIGN(128, BP(this->vOffsets) + this->output_height * sizeof(uint32_t) + 128);
-
- if (this->input_format == XINE_IMGFMT_YV12) {
- this->vOffsetsUV = (uint32_t*)ALIGN(128, BP(this->vWeights) + this->output_height * sizeof(uint32_t) + 128);
- this->vWeightsUV = (uint32_t*)ALIGN(128, BP(this->vOffsetsUV) + this->output_height * sizeof(uint32_t) + 128);
- this->hControlUV = (uint32_t*)ALIGN(128, BP(this->vWeightsUV) + this->output_height * sizeof(uint32_t) + 128);
-
- init_tables_yv12(this->output_width, this->output_height,
- this->input_width, this->input_height,
- this->input_interlaced, this->factor_x, this->factor_y,
- this->hControl, this->vOffsets, this->vWeights,
- this->hControlUV, this->vOffsetsUV, this->vWeightsUV );
-
- } else if (this->input_format == XINE_IMGFMT_YUY2) {
-
- init_tables_yuy2(this->output_width, this->output_height,
- this->input_width, this->input_height,
- this->input_interlaced, this->factor_x, this->factor_y,
- this->hControl, this->vOffsets, this->vWeights );
- }
-}
-
-static void calculate_factors(warp_plugin_t *this)
-{
- /* try to guess amount to stretch/shrink */
- double adiff = this->input_aspect - this->output_aspect;
- this->factor_x = 1.0;
- this->factor_y = 1.0;
-
- if (adiff > 0.1) {
-
- if (adiff > 0.1 + ((16.0-12.0)/9.0)) {
- /* >16:9 -> >4:3 */
- DBG("aspect ratio diff %1.3lf > 0 : too large !\n", adiff);
- this->factor_x = 0.95;
- this->factor_y = 1.15;
- this->output_aspect += (adiff - 4.0/9.0);
- DBG(" changing target ratio to %3.1lf\n", this->output_aspect);
- } else {
- /* 16:9 ... 12:9 -> 4:3 */
- DBG("aspect ratio diff %1.3lf > 0 : 16.9...12:9 -> 4:3\n", adiff);
- this->factor_x = 1.0 - 0.05 * adiff * 9.0/4.0;
- this->factor_y = 1.0 + 0.15 * adiff * 9.0/4.0;
- }
-
- } else if (adiff < -0.1) {
-
- if(adiff < -0.1-((16.0-12.0)/9.0)) {
- /* <4:3 -> <16:9 */
- DBG("aspect ratio diff %1.3lf > 0 : too large !\n", adiff);
- this->factor_x = 1.05;
- this->factor_y = 0.85;
- this->output_aspect += (adiff + 4.0/9.0);
- DBG(" changing target ratio to %3.1lf\n", this->output_aspect);
- } else {
- /* 4:3...16:9 -> 16:9 */
- DBG("aspect ratio diff %1.3lf < 0 : 4:3...16:9 -> 16:9\n", adiff);
- this->factor_x = 1.0 + 0.05 * adiff * 9.0/4.0;
- this->factor_y = 1.0 - 0.15 * adiff * 9.0/4.0;
- }
-
- } else {
- DBG("aspect ratio matches, no warp\n");
- this->factor_x = 1.0;
- this->factor_y = 1.0;
- }
-
- DBG("factor_x = %1.3lf factor_y = %1.3lf output ratio = %1.3lf\n",
- this->factor_x, this->factor_y, this->output_aspect);
-}
-
-/*
- *
- */
-
-void *warp_init_plugin(xine_t *xine, void *data)
-{
-#if !defined(__x86_64__)
- /* Need at least MMX */
- if (!(xine_mm_accel() & MM_ACCEL_X86_MMX)) {
- fprintf(stderr, "warp_init_plugin: ERROR: at least MMX required\n");
- return NULL;
- }
-#endif
-
- return init_plugin(xine, data);
-}
-
-static post_plugin_t *open_plugin(post_class_t *class_gen, int inputs,
- xine_audio_port_t **audio_target,
- xine_video_port_t **video_target)
-{
- warp_plugin_t *this = calloc(1, sizeof(warp_plugin_t));
- post_plugin_t *this_gen = (post_plugin_t *) this;
- post_in_t *input;
- post_out_t *output;
- xine_post_in_t *input_param;
- post_video_port_t *port;
-
- static xine_post_api_t post_api =
- { warp_set_parameters, warp_get_parameters, warp_get_param_descr, warp_get_help };
-
- if (!this || !video_target || !video_target[0]) {
- free(this);
- return NULL;
- }
-
- _x_post_init(this_gen, 0, 1);
-
- port = _x_post_intercept_video_port(this_gen, video_target[0], &input, &output);
- port->intercept_frame = intercept_frame_yuy;
- port->new_frame->draw = post_draw;
- input->xine_in.name = "video";
- output->xine_out.name = "video (scaled)";
- this_gen->xine_post.video_input[0] = &port->new_port;
-
- this_gen->dispose = warp_dispose;
-
- input_param = &this->parameter_input;
- input_param->name = "parameters";
- input_param->type = XINE_POST_DATA_PARAMETERS;
- input_param->data = &post_api;
- xine_list_push_back(this_gen->input, input_param);
-
- this->config.output_aspect = 0.0; /* -> do not change aspect ratio */
- this->config.output_width = 0; /* -> do not change width */
- this->config.output_height = 0; /* -> do not change height */
- this->config.no_downscaling = 0;
-
- this->input_width = 0; /* not known yet, triggers initialization later */
- this->input_height = 0;
-
- return this_gen;
-}
-
-static void warp_dispose(post_plugin_t *this_gen)
-{
- if (_x_post_dispose(this_gen)) {
- warp_plugin_t *this = (warp_plugin_t *) this_gen;
-
- DBG("dispose\n");
-
- free(this->pMem);
- free(this);
- }
-}
-
-static vo_frame_t *got_frame(vo_frame_t *frame)
-{
- post_video_port_t *port = (post_video_port_t *)frame->port;
- warp_plugin_t *this = (warp_plugin_t *)port->post;
- double adiff = this->input_aspect - frame->ratio;
-
- if (this->input_width != frame->width || this->input_height != frame->height ||
- this->input_format != frame->format || FABS(adiff)>0.1 ||
- this->input_interlaced != !!(frame->flags & VO_INTERLACED_FLAG)) {
-
- DBG("detected frame format change: %dx%d -> %dx%d, interlaced %d->%d, aspect %1.3lf->%1.3lf, %s->%s\n",
- this->input_width, this->input_height, frame->width, frame->height,
- this->input_interlaced, !!(frame->flags & VO_INTERLACED_FLAG),
- this->input_aspect, frame->ratio,
- this->input_format==XINE_IMGFMT_YV12 ? "yv12":"yuy2",
- frame->format==XINE_IMGFMT_YV12 ? "yv12":"yuy2" );
-
- /* free tables and buffers */
- free(this->pMem);
- this->pMem = NULL;
-
- /* remember frame properties to detect changes in video format */
- this->input_width = frame->width;
- this->input_height = frame->height;
- this->input_format = frame->format;
- this->input_aspect = frame->ratio;
- this->input_interlaced = !!(frame->flags & VO_INTERLACED_FLAG);
-
- /* re-configure target size and aspect ratio */
- this->output_aspect = this->config.output_aspect ?: frame->ratio;
- if (!this->config.no_downscaling) {
- this->output_width = this->config.output_width ?: frame->width;
- this->output_height = this->config.output_height ?: frame->height;
- } else {
- this->output_width = MAX(this->config.output_width, frame->width);
- this->output_height = MAX(this->config.output_height, frame->height);
- }
-
- /* calculate warp function factors */
- calculate_factors(this);
-
- adiff = this->input_aspect - this->output_aspect;
- if(this->output_width == frame->width &&
- this->output_height == frame->height &&
- adiff < 0.1 &&
- adiff > -0.1 ) {
- this->enable = 0;
- DBG("--> nothing to do, disabling processing for now\n");
- return NULL;
- }
-
- this->enable = 1;
-
- init_tables(this);
- }
-
- if (!this->enable)
- return NULL;
-
- return port->original_port->get_frame(port->original_port,
- this->output_width, this->output_height,
- this->output_aspect, frame->format,
- frame->flags | VO_BOTH_FIELDS);
-}
-
-static void draw_internal(vo_frame_t *frame, vo_frame_t *new_frame)
-{
- post_video_port_t *port = (post_video_port_t *)frame->port;
- warp_plugin_t *this = (warp_plugin_t *)port->post;
- int proc_height = frame->height;
-
- if (frame->format == XINE_IMGFMT_YV12) {
-
- do_warp_yv12(new_frame->base[0], frame->base[0],
- new_frame->pitches[0], frame->pitches[0],
- this->output_width, this->output_height,
- frame->width, proc_height,
- this->input_interlaced,
- this->hControl, this->vOffsets, this->vWeights,
- this->vWorkY,
- 0);
- proc_height /= 2;
- do_warp_yv12(new_frame->base[1], frame->base[1],
- new_frame->pitches[1], frame->pitches[1],
- this->output_width/2, this->output_height/2,
- frame->width/2, proc_height,
- this->input_interlaced,
- this->hControlUV, this->vOffsetsUV, this->vWeightsUV,
- this->vWorkUV,
- 0);
- do_warp_yv12(new_frame->base[2], frame->base[2],
- new_frame->pitches[2], frame->pitches[2],
- this->output_width/2, this->output_height/2,
- frame->width/2, proc_height,
- this->input_interlaced,
- this->hControlUV, this->vOffsetsUV, this->vWeightsUV,
- this->vWorkUV,
- 0);
-
- } else if (frame->format == XINE_IMGFMT_YUY2) {
- do_warp_yuy2(new_frame->base[0], frame->base[0],
- new_frame->pitches[0], frame->pitches[0],
- this->output_width, this->output_height,
- frame->width, proc_height,
- this->input_interlaced,
- this->hControl, this->vOffsets, this->vWeights,
- this->vWorkY, this->vWorkUV,
- 0);
- }
-}
-
-/*
- * parameter functions
- */
-
-static xine_post_api_descr_t *warp_get_param_descr(void)
-{
- return &warp_param_descr;
-}
-
-static int warp_set_parameters(xine_post_t *this_gen, void *param_gen)
-{
- warp_plugin_t *this = (warp_plugin_t *)this_gen;
- warp_parameters_t *params = (warp_parameters_t *)param_gen;
-
- memcpy(&this->config, params, sizeof(warp_parameters_t));
- this->input_width = this->input_height = 0;
-
- if(this->config.output_aspect > 999)
- this->config.output_aspect /= 1000.0;
-
- DBG("warp_set_parameters: "
- "output_width=%d, output_height=%d, output_aspect=%4.3lf, no_downscaling=%d\n",
- this->config.output_width, this->config.output_height, this->config.output_aspect,
- this->config.no_downscaling);
-
- return 1;
-}
-
-static int warp_get_parameters(xine_post_t *this_gen, void *param_gen)
-{
- warp_plugin_t *this = (warp_plugin_t *)this_gen;
- warp_parameters_t *params = (warp_parameters_t *)param_gen;
-
- DBG("warp_get_parameters\n");
- memcpy(params, &this->config, sizeof(warp_parameters_t));
-
- return 1;
-}
-
-static char *warp_get_help(void) {
- return _(
- "The warp plugin scales video to another resolution. "
- "It supports non-linear stretching to change video aspect ratio. "
- "\n"
- "Parameters\n"
- " output_width: Scale video to width\n"
- " (0 -> do not change video width)\n"
- " output_height: Scale video to height\n"
- " (0 -> do not change video height)\n"
- " output_aspect: Adjust aspect ratio using non-linear scaling\n"
- " (0 -> do not change video aspect ratio)\n"
- " no_downscaling: Do not downscale video\n"
- "\n"
- );
-}
-
-
-/*
- * plugin info
- */
-
-static post_info_t info = { XINE_POST_TYPE_VIDEO_FILTER };
-
-const plugin_info_t xine_plugin_info[] __attribute__((visibility("default"))) =
-{
- /* type, API, "name", version, special_info, init_function */
- { PLUGIN_POST, POST_PLUGIN_IFACE_VERSION, "warp", XINE_VERSION_CODE, &info, &warp_init_plugin },
- { PLUGIN_POST, POST_PLUGIN_IFACE_VERSION, "swscale", XINE_VERSION_CODE, &info, &warp_init_plugin },
- { PLUGIN_NONE, 0, "", 0, NULL, NULL }
-};
diff --git a/xine_sxfe_frontend.c b/xine_sxfe_frontend.c
deleted file mode 100644
index a3221429..00000000
--- a/xine_sxfe_frontend.c
+++ /dev/null
@@ -1,1779 +0,0 @@
-/*
- * xine_sxfe_frontend.c: Simple front-end, X11 functions
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xine_sxfe_frontend.c,v 1.112 2009-05-31 19:25:03 phintuka Exp $
- *
- */
-
-/*#define HAVE_XF86VIDMODE*/
-#include "features.h"
-
-#include <poll.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <math.h>
-
-/* X11 */
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/keysym.h>
-#include <X11/Xutil.h>
-#ifdef HAVE_XSHM
-# include <X11/extensions/XShm.h>
-#endif
-#ifdef HAVE_XRENDER
-# include <X11/extensions/Xrender.h>
-#endif
-#ifdef HAVE_XF86VIDMODE
-# include <X11/extensions/xf86vmode.h>
-#endif
-#ifdef HAVE_XDPMS
-# include <X11/extensions/dpms.h>
-#endif
-#ifdef HAVE_XINERAMA
-# include <X11/extensions/Xinerama.h>
-#endif
-
-#include <xine.h>
-
-#define LOG_MODULENAME "[vdr-sxfe] "
-#include "logdefs.h"
-
-#include "xine_osd_command.h"
-#include "xine_frontend_internal.h"
-
-#ifdef HAVE_DBUS_GLIB_1
-# include "tools/gnome_screensaver.h"
-#endif
-
-#ifndef WIN_LAYER_NORMAL
- #define WIN_LAYER_NORMAL 4
-#endif
-#ifndef WIN_LAYER_ONTOP
- #define WIN_LAYER_ONTOP 6
-#endif
-
-#define MWM_HINTS_DECORATIONS (1L << 1)
-#define PROP_MWM_HINTS_ELEMENTS 5
-typedef struct _mwmhints {
- uint32_t flags;
- uint32_t functions;
- uint32_t decorations;
- int32_t input_mode;
- uint32_t status;
-} MWMHints;
-
-#ifdef HAVE_XRENDER
-/* HUD Scaling */
-typedef struct _xrender_surf
-{
- Visual *vis;
- Drawable draw;
- Picture pic;
- uint16_t w, h;
- uint8_t depth;
- uint8_t allocated : 1;
-} Xrender_Surf;
-#endif /* HAVE_XRENDER */
-
-/*
- * data
- */
-
-typedef struct sxfe_s {
-
- /* function pointers / base class */
- union {
- frontend_t fe; /* generic frontend */
- fe_t x; /* xine frontend */
- };
-
- /* stored original handlers */
- int (*fe_xine_open)(frontend_t *this_gen, const char *mrl);
- int (*fe_xine_play)(frontend_t *this_gen);
-
-
- /* X11 */
- Display *display;
- Window window[2];
- int screen;
- int window_id; /* output to another window */
- int completion_event;
-#ifdef HAVE_XF86VIDMODE
- int XF86_modelines_count;
- XF86VidModeModeInfo** XF86_modelines;
-#endif
- Time prev_click_time; /* time of previous mouse button click (grab double clicks) */
-#ifdef HAVE_XDPMS
- BOOL dpms_state;
-#endif
-
- /* Atoms */
- Atom xa_SXFE_INTERRUPT;
- Atom xa_WM_DELETE_WINDOW;
- Atom xa_MOTIF_WM_HINTS;
- Atom xa_WIN_LAYER;
- Atom xa_WIN_STATE;
- Atom xa_NET_ACTIVE_WINDOW;
- Atom xa_NET_WM_STATE;
- Atom xa_NET_WM_STATE_ADD;
- Atom xa_NET_WM_STATE_DEL;
- Atom xa_NET_WM_STATE_ABOVE;
- Atom xa_NET_WM_STATE_STICKY;
- Atom xa_NET_WM_STATE_FULLSCREEN;
- Atom xa_NET_WM_STATE_STAYS_ON_TOP;
-
- int xinerama_screen; /* current xinerama screen, -1 = auto */
- uint16_t xinerama_x; /* left-top position of current xinerama screen */
- uint16_t xinerama_y;
- uint16_t origwidth; /* saved window-mode window size */
- uint16_t origheight;
- uint16_t origxpos; /* saved window-mode window position */
- uint16_t origypos;
- uint16_t dragging_x;
- uint16_t dragging_y;
-
- uint8_t fullscreen : 1;
-/*uint8_t vmode_switch : 1;*/
- uint8_t fullscreen_state_forced : 1;
- uint8_t stay_above : 1;
- uint8_t no_border : 1;
- uint8_t check_move : 1;
- uint8_t dragging : 1;
- uint8_t hud : 1;
- uint8_t gui_hotkeys : 1;
- uint8_t no_x_kbd : 1;
-
- /* HUD stuff */
-#ifdef HAVE_XRENDER
- XImage *hud_img;
- Visual *hud_vis;
- Xrender_Surf *surf_win;
- Xrender_Surf *surf_img;
- uint32_t *hud_img_mem;
- GC gc;
- Window hud_window;
-# ifdef HAVE_XSHM
- XShmSegmentInfo hud_shminfo;
-# endif
-
- uint16_t osd_width;
- uint16_t osd_height;
-#endif /* HAVE_XRENDER */
-
-} sxfe_t;
-
-
-#define DOUBLECLICK_TIME 500 // ms
-
-#define OSD_DEF_WIDTH 720
-#define OSD_DEF_HEIGHT 576
-#define HUD_MAX_WIDTH 1920
-#define HUD_MAX_HEIGHT 1080
-
-static void sxfe_dest_size_cb (void *data,
- int video_width, int video_height, double video_pixel_aspect,
- int *dest_width, int *dest_height, double *dest_pixel_aspect)
-{
- fe_t *this = (fe_t *)data;
-
- if (!this)
- return;
-
- *dest_width = this->width;
- *dest_height = this->height;
-
- *dest_pixel_aspect = this->dest_pixel_aspect(this, video_pixel_aspect,
- video_width, video_height);
-}
-
-static void init_atoms(sxfe_t *this)
-{
- if (this->xa_SXFE_INTERRUPT == None) {
- this->xa_SXFE_INTERRUPT = XInternAtom(this->display, "SXFE_INTERRUPT", False);
- this->xa_WM_DELETE_WINDOW = XInternAtom(this->display, "WM_DELETE_WINDOW", False);
- this->xa_MOTIF_WM_HINTS = XInternAtom(this->display, "_MOTIF_WM_HINTS", False);
- this->xa_WIN_LAYER = XInternAtom(this->display, "_WIN_LAYER", False);
- this->xa_WIN_STATE = XInternAtom(this->display, "_WIN_STATE", False);
- this->xa_NET_ACTIVE_WINDOW = XInternAtom(this->display, "_NET_ACTIVE_WINDOW", False);
- this->xa_NET_WM_STATE = XInternAtom(this->display, "_NET_WM_STATE", False);
- this->xa_NET_WM_STATE_ADD = XInternAtom(this->display, "_NET_WM_STATE_ADD", False);
- this->xa_NET_WM_STATE_DEL = XInternAtom(this->display, "_NET_WM_STATE_DEL", False);
- this->xa_NET_WM_STATE_ABOVE = XInternAtom(this->display, "_NET_WM_STATE_ABOVE", False);
- this->xa_NET_WM_STATE_STICKY= XInternAtom(this->display, "_NET_WM_STATE_STICKY", False);
- this->xa_NET_WM_STATE_FULLSCREEN = XInternAtom(this->display, "_NET_WM_STATE_FULLSCREEN", False);
- this->xa_NET_WM_STATE_STAYS_ON_TOP = XInternAtom(this->display, "_NET_WM_STATE_STAYS_ON_TOP", False);
- }
-}
-
-static void set_fs_size_hint(sxfe_t *this)
-{
- XSizeHints hint;
- hint.flags = USSize | USPosition | PPosition | PSize;
- hint.x = this->xinerama_x;
- hint.y = this->xinerama_y;
- hint.width = this->x.width;
- hint.height = this->x.height;
- XLockDisplay(this->display);
- XSetNormalHints(this->display, this->window[1], &hint);
- XUnlockDisplay(this->display);
-}
-
-/* set_border
- *
- * Set/remove window border
- *
- */
-static void set_border(sxfe_t *this, Window window, int border)
-{
- MWMHints mwmhints = {
- .flags = MWM_HINTS_DECORATIONS,
- .decorations = border ? 1 : 0,
- };
-
- if(this->window_id > 0)
- return;
-
- XLockDisplay(this->display);
- XChangeProperty(this->display, window,
- this->xa_MOTIF_WM_HINTS, this->xa_MOTIF_WM_HINTS, 32,
- PropModeReplace, (unsigned char *) &mwmhints,
- PROP_MWM_HINTS_ELEMENTS);
- XUnlockDisplay(this->display);
-}
-
-static void set_fullscreen_props(sxfe_t *this)
-{
- XEvent ev;
-
- if(this->window_id > 0)
- return;
-
- set_fs_size_hint(this);
-
- /* no border in fullscreen window */
- set_border(this, this->window[1], 0);
-
- memset(&ev, 0, sizeof(ev));
- ev.type = ClientMessage;
- ev.xclient.type = ClientMessage;
- ev.xclient.message_type = this->xa_NET_WM_STATE;
- ev.xclient.display = this->display;
- ev.xclient.window = this->window[1];
- ev.xclient.format = 32;
- ev.xclient.data.l[0] = 1;
- /*ev.xclient.data.l[0] = this->atom_state_add;*/
-
- /* _NET_WM_STATE_FULLSCREEN */
- XLockDisplay(this->display);
- ev.xclient.data.l[1] = this->xa_NET_WM_STATE_FULLSCREEN;
- XSendEvent(this->display, DefaultRootWindow(this->display), False,
- SubstructureNotifyMask|SubstructureRedirectMask, &ev);
- XUnlockDisplay(this->display);
-
- /* _NET_WM_STATE_ABOVE */
- XLockDisplay(this->display);
- ev.xclient.data.l[1] = this->xa_NET_WM_STATE_ABOVE;
- XSendEvent(this->display, DefaultRootWindow(this->display), False,
- SubstructureNotifyMask|SubstructureRedirectMask, &ev);
- XUnlockDisplay(this->display);
-
- /* _NET_WM_STATE_ON_TOP */
- XLockDisplay(this->display);
- ev.xclient.data.l[1] = this->xa_NET_WM_STATE_STAYS_ON_TOP;
- XSendEvent(this->display, DefaultRootWindow(this->display), False,
- SubstructureNotifyMask|SubstructureRedirectMask, &ev);
- XUnlockDisplay(this->display);
-
- /* _NET_ACTIVE_WINDOW */
- XLockDisplay(this->display);
- ev.xclient.message_type = this->xa_NET_ACTIVE_WINDOW;
- ev.xclient.data.l[0] = 0;
- ev.xclient.data.l[1] = 0;
- XSendEvent(this->display, DefaultRootWindow(this->display), False,
- SubstructureNotifyMask|SubstructureRedirectMask, &ev);
- XUnlockDisplay(this->display);
-}
-
-static void update_window_title(sxfe_t *this)
-{
- XLockDisplay(this->display);
-
- if (!this->x.keypress) { /* handler is set only in local mode */
- char *name = NULL;
- if (XFetchName(this->display, this->window[0], &name) && name) {
- char *newname = NULL;
- if (strstr(name, " (top)"))
- *strstr(name, " (top)") = 0;
- if (this->stay_above)
- if (asprintf(&newname, "%s (top)", name) < 0)
- newname = NULL;
- XStoreName(this->display, this->window[0], newname ?: name);
- XStoreName(this->display, this->window[1], newname ?: name);
- XFree(name);
- free(newname);
- } else {
- XStoreName(this->display, this->window[0], this->stay_above ? "VDR - (top)" : "VDR");
- XStoreName(this->display, this->window[1], this->stay_above ? "VDR - (top)" : "VDR");
- }
- } else {
- XStoreName(this->display, this->window[0], this->stay_above ? "Local VDR (top)" : "Local VDR");
- XStoreName(this->display, this->window[1], this->stay_above ? "Local VDR (top)" : "Local VDR");
- }
- XUnlockDisplay(this->display);
-}
-
-static void set_above(sxfe_t *this, int stay_above)
-{
- XEvent ev;
- long propvalue[1];
-
- if(this->window_id > 0)
- return;
-
- if(this->stay_above != stay_above) {
- this->stay_above = stay_above;
- /* Update window title */
- update_window_title(this);
- }
-
- memset(&ev, 0, sizeof(ev));
- ev.type = ClientMessage;
- ev.xclient.type = ClientMessage;
- ev.xclient.message_type = this->xa_NET_WM_STATE;
- ev.xclient.display = this->display;
- ev.xclient.window = this->window[0];
- ev.xclient.format = 32;
- ev.xclient.data.l[0] = stay_above ? 1:0; /*this->atom_state_add : this->atom_state_del;*/
-
- /* _NET_WM_STATE_ABOVE */
- XLockDisplay(this->display);
- ev.xclient.data.l[1] = this->xa_NET_WM_STATE_ABOVE;
- XSendEvent(this->display, DefaultRootWindow(this->display), False,
- SubstructureNotifyMask|SubstructureRedirectMask, &ev);
- XUnlockDisplay(this->display);
-
- /* _NET_WM_STATE_STAYS_ON_TOP */
- XLockDisplay(this->display);
- ev.xclient.data.l[1] = this->xa_NET_WM_STATE_STAYS_ON_TOP;
- XSendEvent(this->display, DefaultRootWindow(this->display), False,
- SubstructureNotifyMask|SubstructureRedirectMask, &ev);
- XUnlockDisplay(this->display);
-
- /* _NET_WM_STATE_STICKY */
- XLockDisplay(this->display);
- ev.xclient.data.l[1] = this->xa_NET_WM_STATE_STICKY;
- XSendEvent(this->display, DefaultRootWindow(this->display), False,
- SubstructureNotifyMask|SubstructureRedirectMask, &ev);
- XUnlockDisplay(this->display);
-
- /* _WIN_LAYER */
- propvalue[0] = stay_above ? WIN_LAYER_ONTOP : WIN_LAYER_NORMAL;
- XLockDisplay(this->display);
- XChangeProperty(this->display, this->window[0], this->xa_WIN_LAYER,
- XA_CARDINAL, 32, PropModeReplace, (unsigned char *)propvalue,
- 1);
- XUnlockDisplay(this->display);
-
-#if 0
- /* sticky */
- memset(&ev, 0, sizeof(ev));
- ev.xclient.type = ClientMessage;
- ev.xclient.message_type = this->xa_WIN_STATE;
- ev.xclient.display = this->display;
- ev.xclient.window = this->window[0];
- ev.xclient.format = 32;
- ev.xclient.data.l[0] = (1<<0);
- ev.xclient.data.l[1] = (stay_above?(1<<0):0);
- XSendEvent(this->display, DefaultRootWindow(this->display), False,
- SubstructureNotifyMask|SubstructureRedirectMask, &ev);
-#endif
-#if 0
- /* on top */
- memset(&ev, 0, sizeof(ev));
- ev.xclient.type = ClientMessage;
- ev.xclient.message_type = this->xa_WIN_LAYER;
- ev.xclient.display = this->display;
- ev.xclient.window = this->window[0];
- ev.xclient.format = 32;
- ev.xclient.data.l[0] = (stay_above?10:6);
- XSendEvent(this->display, DefaultRootWindow(this->display), False,
- SubstructureNotifyMask|SubstructureRedirectMask, &ev);
-#endif
-#if 0
- /* layer */
- XClientMessageEvent xev;
-
- memset(&xev, 0, sizeof(xev));
- xev.type = ClientMessage;
- xev.display = this->display;
- xev.window = this->window[0];
- xev.message_type = this->xa_WIN_LAYER;
- xev.format = 32;
- xev.data.l[0] = 10;
- xev.data.l[1] = CurrentTime;
- XSendEvent(this->display, DefaultRootWindow(this->display), False,
- SubstructureNotifyMask, (XEvent *) & xev);
-
- XMapRaised(this->display, this->window[0]);
-#endif
-#if 0
- xine_port_send_gui_data(this->video_port, XINE_GUI_SEND_DRAWABLE_CHANGED,
- (void*) this->window[this->fullscreen ? 1 : 0]);
-#endif
-}
-
-/*
- * set_cursor
- *
- * Disable mouse cursor in video window (set transparent cursor)
- */
-static void set_cursor(Display *dpy, Window win, const int enable)
-{
- if(enable)
- XDefineCursor(dpy, win, None);
- else {
- /* no cursor */
- const char bm_no_data[] = { 0,0,0,0, 0,0,0,0 };
- Cursor no_ptr;
- XColor black, dummy;
- Pixmap bm_no = XCreateBitmapFromData(dpy, win, bm_no_data, 8, 8);
- XAllocNamedColor(dpy, DefaultColormapOfScreen(DefaultScreenOfDisplay(dpy)),
- "black", &black, &dummy);
- no_ptr = XCreatePixmapCursor(dpy, bm_no, bm_no, &black, &black, 0, 0);
- XDefineCursor(dpy, win, None);
- XDefineCursor(dpy, win, no_ptr);
- }
-}
-
-static void update_xinerama_info(sxfe_t *this)
-{
-#ifdef HAVE_XINERAMA
- int screen = this->xinerama_screen;
- this->xinerama_x = this->xinerama_y = 0;
- XLockDisplay(this->display);
- if(screen >= -1 && XineramaIsActive(this->display)) {
- XineramaScreenInfo *screens;
- int num_screens;
- screens = XineramaQueryScreens(this->display, &num_screens);
- if(screen >= num_screens)
- screen = num_screens - 1;
- if(screen == -1) {
- const int x = this->origxpos + this->origwidth / 2;
- const int y = this->origypos + this->origheight / 2;
- for(screen = num_screens - 1; screen > 0; screen--) {
- const int x0 = screens[screen].x_org;
- const int y0 = screens[screen].y_org;
- const int x1 = x0 + screens[screen].width;
- const int y1 = y0 + screens[screen].height;
- if(x0 <= x && x <= x1 && y0 <= y && y <= y1)
- break;
- }
- }
- if (screen < 0)
- screen = 0;
- this->xinerama_x = screens[screen].x_org;
- this->xinerama_y = screens[screen].y_org;
- this->x.width = screens[screen].width;
- this->x.height = screens[screen].height;
-
- XFree(screens);
- }
- XUnlockDisplay(this->display);
-#endif
-}
-
-/*
- * update_screen_size
- *
- * Update screen size (= size of fullscreen window)
- */
-static void update_screen_size(sxfe_t *this)
-{
- this->x.width = DisplayWidth(this->display, this->screen);
- this->x.height = DisplayHeight(this->display, this->screen);
- update_xinerama_info(this);
-}
-
-/*
- * HUD OSD stuff
- */
-
-#ifdef HAVE_XRENDER
-static Xrender_Surf * xrender_surf_new(Display *dpy, Drawable draw, Visual *vis,
- int w, int h, int alpha)
-{
- Xrender_Surf *rs;
- XRenderPictFormat *fmt;
- XRenderPictureAttributes att;
-
- rs = calloc(1, sizeof (Xrender_Surf));
-
- fmt = XRenderFindStandardFormat(dpy, alpha ? PictStandardARGB32 : PictStandardRGB24);
- rs->w = w;
- rs->h = h;
- rs->depth = fmt->depth;
- rs->vis = vis;
- rs->draw = XCreatePixmap(dpy, draw, w, h, fmt->depth);
- att.dither = 1;
- att.component_alpha = 1;
- att.repeat = 0;
- rs->pic = XRenderCreatePicture(dpy, rs->draw, fmt, CPRepeat | CPDither | CPComponentAlpha, &att);
- rs->allocated = 1;
- return rs;
-}
-
-static void xrender_surf_blend(Display *dpy, Xrender_Surf *src, Xrender_Surf *dst,
- int x, int y, int w, int h,
- XDouble scale_x, XDouble scale_y, int smooth)
-{
- XTransform xf;
-
- if(!scale_x)
- scale_x = 1;
- if(!scale_y)
- scale_y = 1;
-
- xf.matrix[0][0] = XDoubleToFixed(1.0 / scale_x); xf.matrix[0][1] = 0; xf.matrix[0][2] = 0;
- xf.matrix[1][0] = 0; xf.matrix[1][1] = XDoubleToFixed(1.0 / scale_y); xf.matrix[1][2] = 0;
- xf.matrix[2][0] = 0; xf.matrix[2][1] = 0; xf.matrix[2][2] = XDoubleToFixed(1.0);
- XRenderSetPictureFilter(dpy, src->pic, smooth ? "bilinear" : "nearest", NULL, 0);
- XRenderSetPictureTransform(dpy, src->pic, &xf);
- x = (int)ceil((double)(x>0?x-1:0) * scale_x);
- y = (int)ceil((double)(y>0?y-1:0) * scale_y);
- w = (int)floor((double)(w+2) * scale_x);
- h = (int)floor((double)(h+2) * scale_y);
- XRenderComposite(dpy, PictOpSrc, src->pic, None, dst->pic, x, y, 0, 0, x, y, w, h);
-}
-
-static Xrender_Surf * xrender_surf_adopt(Display *dpy, Drawable draw, Visual *vis, int w, int h)
-{
- Xrender_Surf *rs;
- XRenderPictFormat *fmt;
- XRenderPictureAttributes att;
-
- rs = calloc(1, sizeof(Xrender_Surf));
-
- fmt = XRenderFindVisualFormat(dpy, vis);
- rs->w = w;
- rs->h = h;
- rs->depth = fmt->depth;
- rs->vis = vis;
- rs->draw = draw;
- att.dither = 1;
- att.component_alpha = 1;
- att.repeat = 0;
- rs->pic = XRenderCreatePicture(dpy, rs->draw, fmt, CPRepeat | CPDither | CPComponentAlpha, &att);
- rs->allocated = 0;
- return rs;
-}
-
-static void xrender_surf_free(Display *dpy, Xrender_Surf *rs)
-{
- if(rs->allocated)
- XFreePixmap(dpy, rs->draw);
- XRenderFreePicture(dpy, rs->pic);
- free(rs);
-}
-
-static Visual *find_argb_visual(Display *dpy, int scr)
-{
- XVisualInfo *xvi, template;
- int nvi, i;
- XRenderPictFormat *format;
- Visual *visual;
-
- template.screen = scr;
- template.depth = 32;
- template.class = TrueColor;
- xvi = XGetVisualInfo(dpy, VisualScreenMask | VisualDepthMask |
- VisualClassMask, &template, &nvi);
-
- if(!xvi) {
- LOGERR("find_argb_visual: XGetVisualInfo failed (no xvi)");
- return 0;
- }
-
- visual = 0;
- for(i = 0; i < nvi; i++) {
- LOGDBG("find_argb_visual: iteration %d of %d", i, nvi);
- format = XRenderFindVisualFormat(dpy, xvi[i].visual);
- if((format->type == PictTypeDirect) && format->direct.alphaMask) {
- visual = xvi[i].visual;
- break;
- }
- }
-
- XFree(xvi);
-
- if(!visual)
- LOGERR("find_argb_visual: No visual found");
-
- return visual;
-}
-
-static void hud_fill_img_memory(uint32_t* dst, const struct osd_command_s *cmd)
-{
- int i, pixelcounter = 0;
- int idx = cmd->y * HUD_MAX_WIDTH + cmd->x;
-
- for(i = 0; i < cmd->num_rle; ++i) {
- const uint8_t alpha = (cmd->palette + (cmd->data + i)->color)->alpha;
- const uint8_t r = (cmd->palette + (cmd->data + i)->color)->r;
- const uint8_t g = (cmd->palette + (cmd->data + i)->color)->g;
- const uint8_t b = (cmd->palette + (cmd->data + i)->color)->b;
- int j, finalcolor = 0;
- finalcolor |= ((alpha << 24) & 0xFF000000);
- finalcolor |= ((r << 16) & 0x00FF0000);
- finalcolor |= ((g << 8) & 0x0000FF00);
- finalcolor |= (b & 0x000000FF);
-
- for(j = 0; j < (cmd->data + i)->len; ++j) {
- if(pixelcounter >= cmd->w) {
- idx += HUD_MAX_WIDTH - pixelcounter;
- pixelcounter = 0;
- }
- dst[idx++] = finalcolor;
- ++pixelcounter;
- }
- }
-}
-
-static int hud_osd_command(frontend_t *this_gen, struct osd_command_s *cmd)
-{
- sxfe_t *this = (sxfe_t*)this_gen;
- if(this && this->hud && cmd) {
- XLockDisplay(this->display);
- switch(cmd->cmd) {
- case OSD_Nop: /* Do nothing ; used to initialize delay_ms counter */
- LOGDBG("HUD osd NOP");
- break;
-
- case OSD_Size: /* Set size of VDR OSD area */
- LOGDBG("HUD Set Size");
- this->osd_width = (cmd->w > 0) ? cmd->w : OSD_DEF_WIDTH;
- this->osd_height = (cmd->h > 0) ? cmd->h : OSD_DEF_HEIGHT;
-
- XSetForeground(this->display, this->gc, 0x00000000);
- XFillRectangle(this->display, this->surf_img->draw, this->gc,
- 0, 0, this->osd_width+2, this->osd_height+2);
- XFlush(this->display);
- break;
-
- case OSD_Set_RLE: /* Create/update OSD window. Data is rle-compressed. */
- LOGDBG("HUD Set RLE");
- if (!(cmd->flags & OSDFLAG_TOP_LAYER))
- break;
-#ifdef HAVE_XSHM
- if(this->completion_event != -1) {
- hud_fill_img_memory((uint32_t*)(this->hud_img->data), cmd);
- if(!cmd->scaling) {
- /* Place image directly onto hud window */
- XShmPutImage(this->display, this->hud_window, this->gc, this->hud_img,
- cmd->x + cmd->dirty_area.x1, cmd->y + cmd->dirty_area.y1,
- cmd->x + cmd->dirty_area.x1, cmd->y + cmd->dirty_area.y1,
- cmd->dirty_area.x2 - cmd->dirty_area.x1 + 1,
- cmd->dirty_area.y2 - cmd->dirty_area.y1 + 1,
- False);
- } else {
- /* Place image onto Xrender surface which will be blended onto hud window */
- XShmPutImage(this->display, this->surf_img->draw, this->gc, this->hud_img,
- cmd->x + cmd->dirty_area.x1, cmd->y + cmd->dirty_area.y1,
- cmd->x + cmd->dirty_area.x1, cmd->y + cmd->dirty_area.y1,
- cmd->dirty_area.x2 - cmd->dirty_area.x1 + 1,
- cmd->dirty_area.y2 - cmd->dirty_area.y1 + 1,
- False);
- xrender_surf_blend(this->display, this->surf_img, this->surf_win,
- cmd->x + cmd->dirty_area.x1, cmd->y + cmd->dirty_area.y1,
- cmd->dirty_area.x2 - cmd->dirty_area.x1 + 1,
- cmd->dirty_area.y2 - cmd->dirty_area.y1 + 1,
- (XDouble)this->x.width / (XDouble)this->osd_width,
- (XDouble)this->x.height / (XDouble)this->osd_height,
- (cmd->scaling & 2)); // Note: HUD_SCALING_BILINEAR=2
- }
- }
- else
-#endif
- {
- hud_fill_img_memory(this->hud_img_mem, cmd);
- if(!cmd->scaling) {
- /* Place image directly onto hud window (always unscaled) */
- XPutImage(this->display, this->hud_window, this->gc, this->hud_img,
- cmd->x + cmd->dirty_area.x1, cmd->y + cmd->dirty_area.y1,
- cmd->x + cmd->dirty_area.x1, cmd->y + cmd->dirty_area.y1,
- cmd->dirty_area.x2 - cmd->dirty_area.x1 + 1,
- cmd->dirty_area.y2 - cmd->dirty_area.y1 + 1);
- } else {
- /* Place image onto Xrender surface which will be blended onto hud window */
- XPutImage(this->display, this->surf_img->draw, this->gc, this->hud_img,
- cmd->x + cmd->dirty_area.x1, cmd->y + cmd->dirty_area.y1,
- cmd->x + cmd->dirty_area.x1, cmd->y + cmd->dirty_area.y1,
- cmd->dirty_area.x2 - cmd->dirty_area.x1 + 1,
- cmd->dirty_area.y2 - cmd->dirty_area.y1 + 1);
- xrender_surf_blend(this->display, this->surf_img, this->surf_win,
- cmd->x + cmd->dirty_area.x1, cmd->y + cmd->dirty_area.y1,
- cmd->dirty_area.x2 - cmd->dirty_area.x1 + 1,
- cmd->dirty_area.y2 - cmd->dirty_area.y1 + 1,
- (XDouble)this->x.width / (XDouble)this->osd_width,
- (XDouble)this->x.height / (XDouble)this->osd_height,
- (cmd->scaling & 2)); // Note: HUD_SCALING_BILINEAR=2
- }
- }
- break;
-
- case OSD_SetPalette: /* Modify palette of already created OSD window */
- LOGDBG("HUD osd SetPalette");
- break;
-
- case OSD_Move: /* Change x/y position of already created OSD window */
- LOGDBG("HUD osd Move");
- break;
-
- case OSD_Set_YUV: /* Create/update OSD window. Data is in YUV420 format. */
- LOGDBG("HUD osd set YUV");
- break;
-
- case OSD_Close: /* Close OSD window */
- LOGDBG("HUD osd Close");
- if (!(cmd->flags & OSDFLAG_TOP_LAYER))
- break;
- XSetForeground(this->display, this->gc, 0x00000000);
- XFillRectangle(this->display, this->hud_window, this->gc,
- 0, 0, this->x.width, this->x.height);
- XFillRectangle(this->display, this->surf_img->draw, this->gc,
- 0, 0, this->osd_width+2, this->osd_height+2);
- XFlush(this->display);
- break;
-
- default:
- LOGDBG("hud_osd_command: unknown osd command");
- break;
- }
- XUnlockDisplay(this->display);
- }
- return 1;
-}
-
-static int hud_osd_open(sxfe_t *this)
-{
- if(this && this->hud) {
- int dummy;
-
- XLockDisplay(this->display);
-
- LOGDBG("opening HUD OSD window...");
-
- if(!XRenderQueryExtension(this->display, &dummy, &dummy)) {
- LOGMSG("hud_osd_open: ERROR: XRender extension not available.");
- LOGMSG("XRender extension must be enabled in X configuration (xorg.conf etc.)");
- this->hud = 0;
- XUnlockDisplay(this->display);
- return 1;
- }
-
- this->hud_vis = find_argb_visual(this->display, DefaultScreen(this->display));
- if(!this->hud_vis) {
- LOGMSG("find_argb_visual() failed. HUD OSD disabled.");
- this->hud = 0;
- XUnlockDisplay(this->display);
- return 1;
- }
-
- Colormap hud_colormap = XCreateColormap(this->display,
- RootWindow(this->display, DefaultScreen(this->display)),
- this->hud_vis, AllocNone);
-
- XSetWindowAttributes attributes;
- attributes.override_redirect = True;
- attributes.background_pixel = 0x00000000;
- attributes.border_pixel = 0;
- attributes.colormap = hud_colormap;
- attributes.backing_store = Always;
-
- this->hud_window = XCreateWindow(this->display, DefaultRootWindow(this->display),
- this->x.xpos, this->x.ypos,
- this->x.width, this->x.height,
- 0, 32, InputOutput, this->hud_vis,
- CWBackPixel | CWBorderPixel |
- CWOverrideRedirect | CWColormap,
- &attributes);
-
- XSelectInput(this->display, this->hud_window,
- StructureNotifyMask |
- ExposureMask |
- KeyPressMask |
- ButtonPressMask |
- FocusChangeMask);
-
- XStoreName(this->display, this->hud_window, "HUD");
- this->gc = XCreateGC(this->display, this->hud_window, 0, NULL);
-
-#ifdef HAVE_XSHM
- if(this->completion_event != -1) {
- this->hud_img = XShmCreateImage(this->display, this->hud_vis, 32, ZPixmap, NULL, &(this->hud_shminfo),
- HUD_MAX_WIDTH, HUD_MAX_HEIGHT);
-
- this->hud_shminfo.shmid = shmget(IPC_PRIVATE, this->hud_img->bytes_per_line * this->hud_img->height,
- IPC_CREAT | 0777);
-
- this->hud_shminfo.shmaddr = this->hud_img->data = shmat(this->hud_shminfo.shmid, 0, 0);
- this->hud_shminfo.readOnly = True;
-
- XShmAttach(this->display, &(this->hud_shminfo));
- }
- else
-#endif
- {
- /* Fall-back to traditional memory */
- LOGMSG("hud_osd_open: XShm not available, falling back to normal (slow) memory");
- this->hud_img_mem = malloc(4 * HUD_MAX_WIDTH * HUD_MAX_HEIGHT);
- this->hud_img = XCreateImage(this->display, this->hud_vis, 32, ZPixmap, 0, (char*)this->hud_img_mem,
- HUD_MAX_WIDTH, HUD_MAX_HEIGHT, 32, 0);
- }
-
- this->surf_win = xrender_surf_adopt(this->display, this->hud_window, this->hud_vis, HUD_MAX_WIDTH, HUD_MAX_HEIGHT);
- this->surf_img = xrender_surf_new(this->display, this->hud_window, this->hud_vis, HUD_MAX_WIDTH, HUD_MAX_HEIGHT, 1);
-
- XUnlockDisplay(this->display);
-
- this->fe.xine_osd_command = hud_osd_command;
- }
- return 1;
-}
-
-/*
- * hud_osd_resize
- *
- * - Move and resize HUD along with main or fullscreen window
- */
-static void hud_osd_resize(sxfe_t *this, Window video_window, int width, int height)
-{
- if(this->hud) {
- if(video_window == this->window[0]) {
- int hud_x, hud_y;
- Window tmp_win;
- XLockDisplay(this->display);
- XTranslateCoordinates(this->display, this->window[0],
- DefaultRootWindow(this->display),
- 0, 0, &hud_x, &hud_y, &tmp_win);
- XResizeWindow(this->display, this->hud_window, width, height);
- XMoveWindow(this->display, this->hud_window, hud_x, hud_y);
- set_cursor(this->display, this->hud_window, 1);
- XUnlockDisplay(this->display);
- } else if(video_window == this->window[1]) {
- XLockDisplay(this->display);
- XResizeWindow(this->display, this->hud_window, width, height);
- XMoveWindow(this->display, this->hud_window, 0, 0);
- set_cursor(this->display, this->hud_window, 0);
- XUnlockDisplay(this->display);
- }
- }
-}
-
-/*
- * hud_osd_focus
- *
- * - show / hide HUD OSD window
- */
-static void hud_osd_focus(sxfe_t *this, XFocusChangeEvent *fev)
-{
- if(this && this->hud)
- if(fev->window == this->window[0] || fev->window == this->window[1]) {
-
- XLockDisplay(this->display);
-
- if(fev->type == FocusIn)
- /* Show HUD again if sxfe window receives focus */
- XMapWindow(this->display, this->hud_window);
-
- else if(fev->type == FocusOut)
- /* Dismiss HUD window if focusing away from frontend window */
- XUnmapWindow(this->display, this->hud_window);
-
- XUnlockDisplay(this->display);
- }
-}
-
-static void hud_osd_close(sxfe_t *this)
-{
- if(this && this->hud) {
- XLockDisplay(this->display);
- LOGDBG("closing hud window...");
-
-#ifdef HAVE_XSHM
- if(this->completion_event != -1) {
- XShmDetach(this->display, &(this->hud_shminfo));
- XDestroyImage(this->hud_img);
- shmdt(this->hud_shminfo.shmaddr);
- shmctl(this->hud_shminfo.shmid, IPC_RMID, 0);
- }
- else
-#endif
- XDestroyImage(this->hud_img);
-
- if(this->surf_img)
- xrender_surf_free(this->display, this->surf_img);
- if(this->surf_win)
- xrender_surf_free(this->display, this->surf_win);
-
- XDestroyWindow(this->display, this->hud_window);
- XUnlockDisplay(this->display);
- }
-}
-#endif /* HAVE_XRENDER */
-
-/*
- * disable_DPMS
- */
-static void disable_DPMS(sxfe_t *this)
-{
-#ifdef HAVE_XDPMS
- int dpms_dummy;
- XLockDisplay(this->display);
- if (DPMSQueryExtension(this->display, &dpms_dummy, &dpms_dummy) && DPMSCapable(this->display)) {
- CARD16 dpms_level;
- DPMSInfo(this->display, &dpms_level, &this->dpms_state);
- DPMSDisable(this->display);
- } else {
- LOGMSG("disable_DPMS: DPMS unavailable");
- }
- XUnlockDisplay(this->display);
-#endif
-}
-
-/*
- * open_display
- *
- * Try to connect to X server, in order
- * 1) user-given display
- * 2) DISPLAY environment variable
- * 3) default display
- * 4) :0.0
- * 5) 127.0.0.1:0.0
- */
-static int open_display(sxfe_t *this, const char *video_port)
-{
- if (video_port && strlen(video_port)>2) {
- if (!(this->display = XOpenDisplay(video_port)))
- LOGERR("sxfe_display_open: failed to connect to X server (%s)",
- video_port);
- }
-
- if (!this->display) {
- if (NULL!=(video_port=getenv("DISPLAY")) && !(this->display = XOpenDisplay(video_port)))
- LOGERR("sxfe_display_open: failed to connect to X server (%s)",
- video_port);
- }
-
- if (!this->display) {
- this->display = XOpenDisplay(NULL);
- }
-
- if (!this->display) {
- if (!(this->display = XOpenDisplay(":0.0")))
- LOGERR("sxfe_display_open: failed to connect to X server (:0.0)");
- }
-
- if (!this->display) {
- if (!(this->display = XOpenDisplay("127.0.0.1:0.0")))
- LOGERR("sxfe_display_open: failed to connect to X server (127.0.0.1:0.0");
- }
-
- if (!this->display) {
- LOGERR("sxfe_display_open: failed to connect to X server.");
- LOGMSG("If X server is running, try running \"xhost +\" in xterm window");
- return 0;
- }
-
- return 1;
-}
-
-/*
- * set_icon
- */
-static void set_icon(sxfe_t *this)
-{
-# include "vdrlogo_32x32.c"
- XLockDisplay(this->display);
-#if defined(__WORDSIZE) && (__WORDSIZE == 32)
- /* Icon */
- XChangeProperty(this->display, this->window[0],
- XInternAtom(this->display, "_NET_WM_ICON", False),
- XA_CARDINAL, 32, PropModeReplace,
- (unsigned char *) &vdrlogo_32x32,
- 2 + vdrlogo_32x32.width*vdrlogo_32x32.height);
-#else
- long q[2+32*32];
- uint32_t *p = (uint32_t*)&vdrlogo_32x32;
- int i;
- for (i = 0; i < 2 + vdrlogo_32x32.width*vdrlogo_32x32.height; i++)
- q[i] = p[i];
- XChangeProperty(this->display, this->window[0],
- XInternAtom(this->display, "_NET_WM_ICON", False),
- XA_CARDINAL, 32, PropModeReplace,
- (unsigned char *) q,
- 2 + vdrlogo_32x32.width*vdrlogo_32x32.height);
-#endif
- XUnlockDisplay(this->display);
-}
-
-/*
- * detect_display_ratio
- *
- * Calculate display aspect ratio
- */
-static double detect_display_ratio(Display *dpy, int screen)
-{
- double res_h = DisplayWidth (dpy, screen) * 1000.0 / DisplayWidthMM (dpy, screen);
- double res_v = DisplayHeight (dpy, screen) * 1000.0 / DisplayHeightMM (dpy, screen);
-
- double display_ratio = res_v / res_h;
- double diff = display_ratio - 1.0;
-
- if ((diff < 0.01) && (diff > -0.01))
- display_ratio = 1.0;
-
- LOGDBG("Display size : %d x %d mm",
- DisplayWidthMM (dpy, screen),
- DisplayHeightMM (dpy, screen));
- LOGDBG(" %d x %d pixels",
- DisplayWidth (dpy, screen),
- DisplayHeight (dpy, screen));
- LOGDBG(" %ddpi / %ddpi",
- (int)(res_v/1000*25.4), (int)(res_h/1000*25.4));
- LOGDBG("Display ratio: %f/%f = %f", res_v, res_h, display_ratio);
-
- return display_ratio;
-}
-
-/*
- * create_windows
- *
- * Create and initialize fullscreen and windowed mode X11 windows
- * - Borderless fullscreen window
- * - Set window title and icon
- */
-static void create_windows(sxfe_t *this)
-{
- XLockDisplay(this->display);
- /* create and display our video window */
- this->window[0] = XCreateSimpleWindow (this->display,
- DefaultRootWindow(this->display),
- this->x.xpos, this->x.ypos,
- this->x.width, this->x.height,
- 1, 0, 0);
- this->window[1] = XCreateSimpleWindow(this->display, XDefaultRootWindow(this->display),
- this->xinerama_x, this->xinerama_y,
- this->x.width, this->x.height,
- 0, 0, 0);
-
- /* full-screen window */
- set_fullscreen_props(this);
-
- /* Window hint */
- XClassHint *classHint = XAllocClassHint();
- if(classHint) {
- classHint->res_name = "VDR";
- classHint->res_class = "VDR";
- XSetClassHint(this->display, this->window[0], classHint);
- XSetClassHint(this->display, this->window[1], classHint);
- XFree(classHint);
- }
-
- /* Window name */
- const char *initial_title = (!this->x.keypress) ? "Connecting to VDR ..." : "Local VDR";
- XStoreName(this->display, this->window[0], initial_title);
- XStoreName(this->display, this->window[1], initial_title);
-
- /* Icon */
- set_icon(this);
- XUnlockDisplay(this->display);
-}
-
-/*
- * sxfe_display_open
- *
- * connect to X server, create windows
- */
-static int sxfe_display_open(frontend_t *this_gen,
- int xpos, int ypos,
- int width, int height, int fullscreen, int hud,
- int modeswitch, const char *modeline, int aspect,
- fe_keypress_f keyfunc, int no_x_kbd, int gui_hotkeys,
- const char *video_port, int scale_video, int field_order,
- const char *aspect_controller, int window_id)
-{
- sxfe_t *this = (sxfe_t*)this_gen;
-
- if(this->display)
- this->fe.fe_display_close(this_gen);
-
- if(keyfunc) {
- this->x.keypress = keyfunc;
- this->x.keypress("XKeySym", ""); /* triggers learning mode */
- }
-
- LOGDBG("sxfe_display_open(width=%d, height=%d, fullscreen=%d, display=%s)",
- width, height, fullscreen, video_port);
-
- if(hud) {
-#ifdef HAVE_XRENDER
- LOGDBG("sxfe_display_open: Enabling HUD OSD");
- this->hud = hud;
- this->osd_width = OSD_DEF_WIDTH;
- this->osd_height = OSD_DEF_HEIGHT;
-#else
- LOGMSG("sxfe_display_open: Application was compiled without XRender support. HUD OSD disabled.");
-#endif
- }
-
- this->x.xpos = xpos;
- this->x.ypos = ypos;
- this->x.width = width;
- this->x.height = height;
- this->x.aspect = aspect;
-/*this->x.cropping = 0;*/
- this->x.overscan = 0;
- this->x.scale_video = scale_video;
- this->x.field_order = field_order ? 1 : 0;
- this->x.aspect_controller = aspect_controller ? strdup(aspect_controller) : NULL;
-
- this->origxpos = 0;
- this->origypos = 0;
- this->origwidth = width>0 ? width : OSD_DEF_WIDTH;
- this->origheight = height>0 ? height : OSD_DEF_HEIGHT;
-
- this->check_move = 0;
- this->dragging = 0;
- this->dragging_x = 0;
- this->dragging_y = 0;
-
- this->fullscreen = fullscreen;
-/*this->vmode_switch = modeswitch;*/
- this->fullscreen_state_forced = 0;
-/*this->modeline = strdup(modeline ?: "");*/
- this->window_id = window_id;
-
- this->xinerama_screen = -1;
-
- this->gui_hotkeys = gui_hotkeys;
- this->no_x_kbd = no_x_kbd ? 1 : 0;
-
- /*
- * init x11 stuff
- */
-
- if (!XInitThreads ()) {
- LOGERR("sxfe_display_open: XInitThreads failed");
- free(this);
- return 0;
- }
-
- if (!open_display(this, video_port))
- return 0;
-
- XLockDisplay (this->display);
-
- this->screen = DefaultScreen(this->display);
-
- /* #warning sxfe_display_open: TODO: switch vmode */
-
- /* completion event */
- this->completion_event = -1;
-#ifdef HAVE_XSHM
- if (XShmQueryExtension (this->display) == True) {
- this->completion_event = XShmGetEventBase (this->display) + ShmCompletion;
- }
-#endif
-
- init_atoms(this);
-
- if(fullscreen)
- update_screen_size(this);
-
- /* Output to existing window ? (embedded to another app) */
- if(this->window_id > 0) {
- LOGMSG("sxfe_display_open(): Using X11 window %d for output", this->window_id);
- this->window[0] = this->window[1] = (Window)this->window_id;
- XUnmapWindow(this->display, this->window[0]);
- } else {
- create_windows(this);
- }
-
- /* Select input */
- XSelectInput (this->display, this->window[0],
- StructureNotifyMask |
- ExposureMask |
- KeyPressMask |
- ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
- FocusChangeMask);
- XSelectInput (this->display, this->window[1],
- StructureNotifyMask |
- ExposureMask |
- KeyPressMask |
- ButtonPressMask |
- FocusChangeMask);
-
- /* Map current window */
- XMapRaised (this->display, this->window[this->fullscreen ? 1 : 0]);
- XMoveWindow(this->display, this->window[0], this->x.xpos, this->x.ypos);
-
- /* determine display aspect ratio */
- this->x.display_ratio = detect_display_ratio(this->display, this->screen);
-
- /* we want to get notified if user closes the window */
- XSetWMProtocols(this->display, this->window[this->fullscreen ? 1 : 0], &(this->xa_WM_DELETE_WINDOW), 1);
-
- /* Hide cursor */
- if(this->window_id <= 0)
- set_cursor(this->display, this->window[1], 0);
-
- /* No screen saver */
- /* #warning TODO: suspend --> activate blank screen saver / DPMS display off ? */
- XSetScreenSaver(this->display, 0, 0, DefaultBlanking, DefaultExposures);
-
- /* Disable DPMS */
- disable_DPMS(this);
-
-#ifdef HAVE_DBUS_GLIB_1
- /* Disable GNOME screensaver */
- gnome_screensaver_control(0);
-#endif
-
- /* setup xine visual type */
- this->x.xine_visual_type = XINE_VISUAL_TYPE_X11;
- this->x.vis_x11.display = this->display;
- this->x.vis_x11.screen = this->screen;
- this->x.vis_x11.d = this->window[this->fullscreen ? 1 : 0];
- this->x.vis_x11.dest_size_cb = sxfe_dest_size_cb;
- this->x.vis_x11.frame_output_cb = this->x.frame_output_handler;
- this->x.vis_x11.user_data = this;
-
- set_fullscreen_props(this);
-
- XUnlockDisplay (this->display);
-#ifdef HAVE_XRENDER
- return hud_osd_open(this);
-#else
- return 1;
-#endif
-}
-
-/*
- * sxfe_display_config
- *
- * configure windows
- */
-static int sxfe_display_config(frontend_t *this_gen,
- int xpos, int ypos,
- int width, int height, int fullscreen,
- int modeswitch, const char *modeline,
- int aspect, int scale_video,
- int field_order)
-{
- sxfe_t *this = (sxfe_t*)this_gen;
-
- if(this->fullscreen_state_forced)
- fullscreen = this->fullscreen ? 1 : 0;
-
- if(!fullscreen && (this->x.width != width || this->x.height != height)) {
- this->x.width = width;
- this->x.height = height;
-
- XLockDisplay(this->display);
- XResizeWindow(this->display, this->window[0], this->x.width, this->x.height);
- XUnlockDisplay(this->display);
- if(!fullscreen && !this->fullscreen)
- xine_port_send_gui_data(this->x.video_port, XINE_GUI_SEND_DRAWABLE_CHANGED,
- (void*) this->window[0]);
- }
-
- if(fullscreen)
- update_screen_size(this);
-
- if(fullscreen != this->fullscreen) {
- Window tmp_win;
- int tmp_x, tmp_y;
- XLockDisplay(this->display);
- XUnmapWindow(this->display, this->window[this->fullscreen ? 1 : 0]);
- this->fullscreen = fullscreen ? 1 : 0;
- if(fullscreen)
- set_fullscreen_props(this);
- else
- set_above(this, this->stay_above);
- XMapRaised(this->display, this->window[this->fullscreen ? 1 : 0]);
- if(!fullscreen) {
- XResizeWindow(this->display, this->window[0], this->x.width, this->x.height);
- XMoveWindow(this->display, this->window[0], this->x.xpos, this->x.ypos);
- LOGDBG("sxfe_display_config: XMoveWindow called with x=%d and y=%d",
- this->x.xpos, this->x.ypos);
- this->check_move = 1;
- set_above(this, this->stay_above);
- } else {
- set_fullscreen_props(this);
- XResizeWindow(this->display, this->window[1], this->x.width, this->x.height);
- XMoveWindow(this->display, this->window[1], this->xinerama_x, this->xinerama_y);
- }
- XSync(this->display, False);
- if(XTranslateCoordinates(this->display, this->window[this->fullscreen ? 1 : 0],
- DefaultRootWindow(this->display),
- 0, 0, &tmp_x, &tmp_y, &tmp_win)) {
- this->x.xpos = tmp_x;
- this->x.ypos = tmp_y;
- }
- XUnlockDisplay(this->display);
- xine_port_send_gui_data(this->x.video_port, XINE_GUI_SEND_DRAWABLE_CHANGED,
- (void*) this->window[this->fullscreen ? 1 : 0]);
- }
-
-#if 0
- if(!modeswitch && strcmp(modeline, this->modeline)) {
- free(this->modeline);
- this->modeline = strdup(modeline ?: "");
- /* #warning TODO - switch vmode */
- }
-#endif
-
-/*this->vmode_switch = modeswitch;*/
- this->x.aspect = aspect;
- this->x.scale_video = scale_video;
- this->x.field_order = field_order ? 1 : 0;
-
- return 1;
-}
-
-static void sxfe_toggle_fullscreen(fe_t *this_gen)
-{
- sxfe_t *this = (sxfe_t*)this_gen;
-
- int force = this->fullscreen_state_forced;
- this->fullscreen_state_forced = 0;
-
- if(!this->fullscreen) {
- this->origwidth = this->x.width;
- this->origheight = this->x.height;
- this->origxpos = this->x.xpos;
- this->origypos = this->x.ypos;
- } else {
- this->x.xpos = this->origxpos;
- this->x.ypos = this->origypos;
- }
-
- this->fe.fe_display_config((frontend_t*)this, -1, -1, this->origwidth, this->origheight,
- this->fullscreen ? 0 : 1,
- 0/*this->vmode_switch*/, NULL/*this->modeline*/,
- this->x.aspect, this->x.scale_video, this->x.field_order);
-
- this->fullscreen_state_forced = !force;
-}
-
-/*
- * X event loop
- */
-
-/*
- * sxfe_interrupt
- *
- * - Interrupt X event loop (sxfe_run)
- *
- */
-static void sxfe_interrupt(frontend_t *this_gen)
-{
- sxfe_t *this = (sxfe_t*)this_gen;
-
- XClientMessageEvent event = {
- .type = ClientMessage,
- .display = this->display,
- .window = this->window[this->fullscreen ? 1 : 0],
- .message_type = this->xa_SXFE_INTERRUPT,
- .format = 32,
- };
- XLockDisplay (this->display);
- if(!XSendEvent(event.display, event.window, 1, /*KeyPressMask*/0, (XEvent *)&event))
- LOGERR("sxfe_interrupt: XSendEvent(ClientMessage) FAILED\n");
-
- XFlush(this->display);
- XUnlockDisplay (this->display);
-}
-
-/*
- * XKeyEvent handler
- *
- */
-static void XKeyEvent_handler(sxfe_t *this, XKeyEvent *kev)
-{
- if(kev->keycode) {
- KeySym ks;
- char buffer[20];
- XComposeStatus status;
- const char *fe_event = NULL;
-
- XLockDisplay (this->display);
- XLookupString(kev, buffer, sizeof(buffer), &ks, &status);
- XUnlockDisplay (this->display);
-
- switch(ks) {
- case XK_f:
- case XK_F:
- if (this->gui_hotkeys)
- fe_event = "TOGGLE_FULLSCREEN";
- break;
- case XK_d:
- case XK_D:
- if (this->gui_hotkeys)
- fe_event = "TOGGLE_DEINTERLACE";
- break;
- case XK_Escape:
- if (!this->x.keypress) /* ESC exits only in remote mode */
- fe_event = "QUIT";
- break;
- default:;
- }
- if (fe_event)
- this->x.fe.send_event((frontend_t*)this, fe_event);
- else if (!this->no_x_kbd)
- this->x.fe.send_input_event((frontend_t*)this, "XKeySym", XKeysymToString(ks), 0, 0);
- }
-}
-
-/*
- * XConfigureEvent handler
- *
- */
-static void XConfigureEvent_handler(sxfe_t *this, XConfigureEvent *cev)
-{
- /* Move and resize HUD along with main or fullscreen window */
-#ifdef HAVE_XRENDER
- if(this->hud)
- hud_osd_resize(this, cev->window, cev->width, cev->height);
-#endif
-
- /* update video window size */
- this->x.width = cev->width;
- this->x.height = cev->height;
-
- if(this->window[0] == cev->window && this->check_move) {
- LOGDBG("ConfigureNotify reveived with x=%d, y=%d, check_move=%d",
- cev->x, cev->y, this->check_move);
- this->check_move = 0;
- if(this->x.xpos != cev->x && this->x.ypos != cev->y) {
- XLockDisplay (this->display);
- XMoveWindow(this->display, this->window[0], cev->x, cev->y);
- XUnlockDisplay (this->display);
- }
- }
-
- if ((cev->x == 0) && (cev->y == 0)) {
- if(!this->fullscreen) {
- int tmp_x, tmp_y;
- Window tmp_win;
- XLockDisplay(this->display);
- if(XTranslateCoordinates(this->display, cev->window,
- DefaultRootWindow(this->display),
- 0, 0, &tmp_x, &tmp_y, &tmp_win)) {
- this->x.xpos = tmp_x;
- this->x.ypos = tmp_y;
- }
- XUnlockDisplay(this->display);
- }
- } else {
- if(!this->fullscreen) {
- /* update video window position */
- this->x.xpos = cev->x;
- this->x.ypos = cev->y;
- }
- }
-}
-
-/*
- * XMotionEvent handler
- *
- * Track mouse movement when Button1 is pressed down
- * - enable window dragging: user can simply drag window around screen
- * - useful when window is borderless (no title bar)
- */
-static void XMotionEvent_handler(sxfe_t *this, XMotionEvent *mev)
-{
- if(this->dragging && !this->fullscreen) {
- Window tmp_win;
- int xpos, ypos;
-
- XLockDisplay(this->display);
-
- while(XCheckMaskEvent(this->display, ButtonMotionMask, (XEvent*)mev));
-
- XTranslateCoordinates(this->display, this->window[0],
- DefaultRootWindow(this->display),
- 0, 0, &xpos, &ypos, &tmp_win);
-
- this->x.xpos = (xpos += mev->x_root - this->dragging_x);
- this->x.ypos = (ypos += mev->y_root - this->dragging_y);
- this->dragging_x = mev->x_root;
- this->dragging_y = mev->y_root;
-
- XMoveWindow(this->display, this->window[0], xpos, ypos);
- LOGDBG("MotionNotify: XMoveWindow called with x=%d and y=%d", xpos, ypos);
-
- XUnlockDisplay(this->display);
- }
-}
-
-/*
- * XButtonEvent handler
- *
- * - Double click switches between windowed and fullscreen mode
- * - Window can be moved by dragging it
- * - Right mouse button switches window state:
- * normal window -> borderless window -> always on top -> ...
- */
-static void XButtonEvent_handler(sxfe_t *this, XButtonEvent *bev)
-{
- switch(bev->button) {
- case Button1:
- /* Double-click toggles between fullscreen and windowed mode */
- if(bev->time - this->prev_click_time < DOUBLECLICK_TIME) {
- /* Toggle fullscreen */
- sxfe_toggle_fullscreen((fe_t*)this);
- this->prev_click_time = 0; /* don't react to third click ... */
- } else {
- this->prev_click_time = bev->time;
- if(!this->fullscreen && this->no_border && !this->dragging) {
- /* start dragging window */
- this->dragging = 1;
- this->dragging_x = bev->x_root;
- this->dragging_y = bev->y_root;
- }
- }
- break;
-
- case Button3:
- /* Toggle border and stacking */
- if(!this->fullscreen) {
- if(!this->stay_above) {
- set_above(this, 1);
- } else if(!this->no_border) {
- set_border(this, this->window[0], 0);
- this->no_border = 1;
- } else {
- set_border(this, this->window[0], 1);
- this->no_border = 0;
- set_above(this, 0);
- }
- }
- break;
- }
-}
-
-/*
- * sxfe_run
- *
- * - main X event loop
- */
-static int sxfe_run(frontend_t *this_gen)
-{
- sxfe_t *this = (sxfe_t*)this_gen;
-
- /* poll X server (connection socket).
- * (XNextEvent will block until events are queued).
- * We want to use timeout, blocking for long time usually causes vdr
- * watchdog to emergency exit ...
- */
- if (! XPending(this->display)) {
- struct pollfd pfd = {
- .fd = ConnectionNumber(this->display),
- .events = POLLIN,
- };
- if (poll(&pfd, 1, 50) < 1 || !(pfd.revents & POLLIN)) {
- return 1;
- }
- }
-
- while (XPending(this->display) > 0) {
-
- XEvent event;
-
- XLockDisplay (this->display);
- XNextEvent (this->display, &event);
- XUnlockDisplay (this->display);
-
- switch (event.type) {
- case Expose:
- if (event.xexpose.count == 0)
- xine_port_send_gui_data (this->x.video_port, XINE_GUI_SEND_EXPOSE_EVENT, &event);
- break;
-
- case ConfigureNotify:
- XConfigureEvent_handler(this, (XConfigureEvent *) &event);
- break;
-
-#ifdef HAVE_XRENDER
- case FocusIn:
- case FocusOut:
- hud_osd_focus(this, (XFocusChangeEvent *) &event);
- break;
-#endif
-
- case ButtonRelease:
- this->dragging = 0;
- break;
-
- case MotionNotify:
- XMotionEvent_handler(this, (XMotionEvent *) &event);
- break;
-
- case ButtonPress:
- XButtonEvent_handler(this, (XButtonEvent *) &event);
- break;
-
- case KeyPress:
- case KeyRelease:
- XKeyEvent_handler(this, (XKeyEvent *) &event);
- break;
-
- case ClientMessage:
- {
- XClientMessageEvent *cmessage = (XClientMessageEvent *) &event;
- if ( cmessage->message_type == this->xa_SXFE_INTERRUPT )
- LOGDBG("ClientMessage: sxfe_interrupt");
-
- if ( cmessage->data.l[0] == this->xa_WM_DELETE_WINDOW ) {
- /* we got a window deletion message from out window manager.*/
- LOGDBG("ClientMessage: WM_DELETE_WINDOW");
-
- this->x.fe.send_event((frontend_t*)this, "QUIT");
- }
- break;
- }
- }
-
- if (event.type == this->completion_event)
- xine_port_send_gui_data (this->x.video_port, XINE_GUI_SEND_COMPLETION_EVENT, &event);
- }
-
- return !this->x.fe.xine_is_finished((frontend_t*)this, 0);
-}
-
-static void sxfe_display_close(frontend_t *this_gen)
-{
- sxfe_t *this = (sxfe_t*)this_gen;
-
- if(!this)
- return;
-
- if(this->x.xine)
- this->fe.xine_exit(this_gen);
-
- if(this->display) {
-
-#ifdef HAVE_XRENDER
- hud_osd_close(this);
-#endif
-
-#ifdef HAVE_DBUS_GLIB_1
- /* Restore GNOE screensaver */
- gnome_screensaver_control(1);
-#endif
-
-#ifdef HAVE_XDPMS
- if(this->dpms_state)
- DPMSEnable(this->display);
-#endif
- if(this->window_id <= 0) {
- XLockDisplay(this->display);
- XUnmapWindow(this->display, this->window[this->fullscreen ? 1 : 0]);
- XDestroyWindow(this->display, this->window[0]);
- XDestroyWindow(this->display, this->window[1]);
- XUnlockDisplay(this->display);
- }
- XCloseDisplay (this->display);
- this->display = NULL;
- }
-
- free(this->x.aspect_controller);
- this->x.aspect_controller = NULL;
-#if 0
- free(this->modeline);
- this->modeline = NULL;
-#endif
-}
-
-/*
- * sxfe_xine_open
- *
- * Override fe_xine_open:
- * - Set window name: append remote host address to title bar text
- */
-static int sxfe_xine_open(frontend_t *this_gen, const char *mrl)
-{
- sxfe_t *this = (sxfe_t*)this_gen;
-
- int result = this->fe_xine_open(this_gen, mrl);
-
- if(result && mrl && !strncmp(mrl, MRL_ID, MRL_ID_LEN) && strstr(mrl, "//")) {
- char *name = NULL, *end;
- if (asprintf(&name, "VDR - %s", strstr(mrl, "//")+2) >= 0) {
- if (NULL != (end = strstr(name, ":37890")) || /* hide only default port */
- NULL != (end = strchr(name, '#'))) /* hide attributes */
- *end = 0;
- XStoreName(this->display, this->window[0], name);
- XStoreName(this->display, this->window[1], name);
- free(name);
- }
- }
-
- return result;
-}
-
-static int sxfe_xine_play(frontend_t *this_gen)
-{
- sxfe_t *this = (sxfe_t*)this_gen;
-
- int result = this->fe_xine_play(this_gen);
-
-#ifdef HAVE_XRENDER
- if (result && this->x.input_plugin && this->hud) {
- LOGDBG("sxfe_xine_play: Enabling HUD OSD");
- this->x.input_plugin->f.fe_handle = this_gen;
- this->x.input_plugin->f.intercept_osd = hud_osd_command;
- }
-#endif /* HAVE_XRENDER */
-
- return result;
-}
-
-static frontend_t *sxfe_get_frontend(void)
-{
- sxfe_t *this = calloc(1, sizeof(sxfe_t));
-
- init_fe((fe_t*)this);
-
- this->window_id = -1;
-
- this->fe.fe_display_open = sxfe_display_open;
- this->fe.fe_display_config = sxfe_display_config;
- this->fe.fe_display_close = sxfe_display_close;
-
- this->fe.fe_run = sxfe_run;
- this->fe.fe_interrupt = sxfe_interrupt;
-
- this->x.toggle_fullscreen_cb = sxfe_toggle_fullscreen;
-
- /* override */
-
- this->fe_xine_open = this->fe.xine_open;
- this->fe_xine_play = this->fe.xine_play;
-
- this->fe.xine_open = sxfe_xine_open;
- this->fe.xine_play = sxfe_xine_play;
-
- return (frontend_t*)this;
-}
-
-/* ENTRY POINT */
-const fe_creator_f fe_creator __attribute__((visibility("default"))) = sxfe_get_frontend;
-
-
-
diff --git a/xineliboutput.c b/xineliboutput.c
deleted file mode 100644
index fbd5b1b4..00000000
--- a/xineliboutput.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * vdr-xineliboutput: xine-lib based output device plugin for VDR
- *
- * Copyright (C) 2003-2008 Petri Hintukainen <phintuka@users.sourceforge.net>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * xineliboutput.c: VDR Plugin interface
- *
- * $Id: xineliboutput.c,v 1.38 2009-03-12 17:29:13 rofafor Exp $
- *
- */
-
-#include "features.h"
-
-#include <vdr/plugin.h>
-#include <vdr/i18n.h>
-
-#include "logdefs.h"
-#include "config.h"
-#include "device.h"
-#include "setup_menu.h"
-#include "menu.h"
-#include "media_player.h"
-
-#if defined(APIVERSNUM) && (APIVERSNUM < 10600)
-# error VDR API versions < 1.6.0 are not supported !
-#endif
-
-//---------------------------------plugin-------------------------------------
-
-static const char *VERSION = "1.0.90-cvs";
-static const char *DESCRIPTION = trNOOP("X11/xine-lib output plugin");
-static const char *MAINMENUENTRY = trNOOP("Media Player");
-
-cOsdObject *g_PendingMenuAction = NULL;
-
-class cPluginXinelibOutput : public cPlugin
-{
- private:
- // Add any member variables or functions you may need here.
-
- public:
- cPluginXinelibOutput(void);
- virtual ~cPluginXinelibOutput();
-
- virtual const char *Version(void) { return VERSION; }
- virtual const char *Description(void) { return tr(DESCRIPTION); }
- virtual const char *CommandLineHelp(void);
-
- virtual bool ProcessArgs(int argc, char *argv[]);
- virtual bool Initialize(void);
- virtual bool Start(void);
- virtual void Stop(void);
- //virtual void Housekeeping(void);
- virtual void MainThreadHook();
- //virtual cString Active(void);
- //virtual time_t WakeupTime(void);
-
- virtual const char *MainMenuEntry(void) { return xc.hide_main_menu ? NULL : tr(MAINMENUENTRY); }
- virtual cOsdObject *MainMenuAction(void);
-
- virtual cMenuSetupPage *SetupMenu(void);
- virtual bool SetupParse(const char *Name, const char *Value);
-
- virtual bool Service(const char *Id, void *Data = NULL);
- virtual const char **SVDRPHelpPages(void);
- virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode);
-};
-
-cPluginXinelibOutput::cPluginXinelibOutput(void)
-{
- // Initialize any member variables here.
- // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
- // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
-}
-
-cPluginXinelibOutput::~cPluginXinelibOutput()
-{
- // Clean up after yourself!
- cXinelibDevice::Dispose();
-}
-
-
-const char cmdLineHelp[] =
-" -l NAME --local=NAME Use local frontend NAME\n"
-" Supported frontends:\n"
-" sxfe (X11)\n"
-" fbfe (framebuffer)\n"
-" none (only remote frontends)\n"
-" -r PORT --remote=PORT Listen PORT for remote clients\n"
-" (default "LISTEN_PORT_S")\n"
-" none or 0 disables remote mode\n"
-" Also local interface address can be specified:\n"
-" --remote=<ip>:<port> (default is all interfaces)\n"
-" -A NAME --audio=NAME Use audio driver NAME for local frontend\n"
-" Supported values:\n"
-" auto, alsa, oss, esound, none\n"
-" -V NAME --video=NAME Use video driver NAME for local frontend\n"
-" Supported values:\n"
-" for sxfe: auto, x11, xshm, xv, xvmc, xxmc,\n"
-" vidix, sdl, opengl, none\n"
-" for fbfe: auto, fb, DirectFB, vidixfb,\n"
-" sdl, dxr3, aadxr3, none\n"
-#if 0
-" -m M --modeline=M Use modeline M for local frontend\n"
-" (example: )\n"
-#endif
-" -f --fullscreen Fullscreen mode (X11)\n"
-#ifdef HAVE_XRENDER
-" -D --hud Head Up Display OSD (X11)\n"
-#endif
-" -w --width=x Window width\n"
-" -h --height=x Window width\n"
-" -d DISP --display=DISP Use X11 display DISP\n"
-" (or framebuffer device name)\n"
-" -P NAME --post=NAME Use xine post plugin NAME\n"
-" format: pluginname[:arg=val[,arg=val]][,...]\n"
-" example: \n"
-" --post=upmix;tvtime:enabled=1,cheap_mode=1\n"
-" -p --primary Force xineliboutput to be primary device when\n"
-" there are active frontend(s)\n"
-" -c --exit-on-close Exit vdr when local frontend window is closed\n"
-;
-
-const char *cPluginXinelibOutput::CommandLineHelp(void)
-{
- // Return a string that describes all known command line options.
- return cmdLineHelp;
-}
-
-bool cPluginXinelibOutput::ProcessArgs(int argc, char *argv[])
-{
- // Implement command line argument processing here if applicable.
- return xc.ProcessArgs(argc, argv);
-}
-
-bool cPluginXinelibOutput::Initialize(void)
-{
- // Initialize any background activities the plugin shall perform.
- TRACEF("cPluginXinelibOutput::Initialize");
-
- cXinelibDevice::Instance();
- return true;
-}
-
-bool cPluginXinelibOutput::Start(void)
-{
- // Start any background activities the plugin shall perform.
- TRACEF("cPluginXinelibOutput::Start");
- return cXinelibDevice::Instance().StartDevice();
-}
-
-void cPluginXinelibOutput::MainThreadHook(void)
-{
- TRACEF("cPluginXinelibOutput::MainThreadHook");
- return cXinelibDevice::Instance().MainThreadHook();
-}
-
-void cPluginXinelibOutput::Stop(void)
-{
- // Start any background activities the plugin shall perform.
- TRACEF("cPluginXinelibOutput::Stop");
- return cXinelibDevice::Instance().StopDevice();
-}
-
-cOsdObject *cPluginXinelibOutput::MainMenuAction(void)
-{
- // Perform the action when selected from the main VDR menu.
- TRACEF("cPluginXinelibOutput::MainMenuAction");
-
- if(xc.main_menu_mode == CloseOsd) {
- xc.main_menu_mode = ShowMenu;
- return NULL;
- }
-
- if(g_PendingMenuAction) {
- cOsdObject *tmp = g_PendingMenuAction;
- g_PendingMenuAction = NULL;
- return tmp;
- }
-
- if(xc.hide_main_menu)
- return NULL;
-
-#ifdef HAVE_XV_FIELD_ORDER
- xc.field_order = xc.field_order ? 0 : 1;
- cXinelibDevice::Instance().ConfigureWindow(xc.fullscreen, xc.width, xc.height,
- xc.modeswitch, xc.modeline, xc.display_aspect,
- xc.scale_video, xc.field_order);
-#endif
- return new cMenuXinelib();
-}
-
-cMenuSetupPage *cPluginXinelibOutput::SetupMenu(void)
-{
- // Return a setup menu in case the plugin supports one.
- TRACEF("cPluginXinelibOutput::SetupMenu");
- return new cMenuSetupXinelib();
-}
-
-bool cPluginXinelibOutput::SetupParse(const char *Name, const char *Value)
-{
- // Parse your own setup parameters and store their values.
- return xc.SetupParse(Name, Value);
-}
-
-bool cPluginXinelibOutput::Service(const char *Id, void *Data)
-{
- if(Id) {
- char *CData = (char*)Data;
-
- if(!strcmp(Id, "MediaPlayer-1.0")) {
- if(CData && *CData) {
- LOGMSG("Service(%s, %s)", Id, CData);
- cControl::Launch(new cXinelibPlayerControl(ShowFiles, CData));
- return true;
- }
- LOGMSG("Service(%s) -> true", Id);
- return true;
- }
-
- else if(!strcmp(Id, "MusicPlayer-1.0")) {
- if(CData && *CData) {
- LOGMSG("Service(%s, %s)", Id, CData);
- cControl::Launch(new cXinelibPlayerControl(ShowMusic, CData));
- return true;
- }
- LOGMSG("Service(%s) -> true", Id);
- return true;
- }
-
- else if(!strcmp(Id, "DvdPlayer-1.0")) {
- if(Data && *CData) {
- LOGMSG("Service(%s, %s)", Id, CData);
- cControl::Launch(new cXinelibDvdPlayerControl(CData));
- return true;
- }
- LOGMSG("Service(%s) -> true", Id);
- return true;
- }
-
- else if(!strcmp(Id, "ImagePlayer-1.0")) {
- if(CData && *CData) {
- LOGMSG("Service(%s, %s)", Id, CData);
- char **list = new char*[2];
- list[0] = strdup(CData);
- list[1] = NULL;
- cControl::Launch(new cXinelibImagesControl(list, 0, 1));
- return true;
- }
- LOGMSG("Service(%s) -> true", Id);
- return true;
- }
-
- }
- return false;
-}
-
-const char **cPluginXinelibOutput::SVDRPHelpPages(void)
-{
- static const char *HelpPages[] = {
- "PMDA <file>\n"
- " Play media file.",
- "PDVD <file>\n"
- " Play DVD disc.",
- "PMSC <file>\n"
- " Play music file.",
- "PIMG <file>\n"
- " Play/show image file.",
- "QMSC <file>\n"
- " Queue music file to playlist.",
- NULL
- };
- return HelpPages;
-}
-
-cString cPluginXinelibOutput::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode)
-{
- if(strcasecmp(Command, "PMDA") == 0) {
- if(*Option) {
- LOGMSG("SVDRP(%s, %s)", Command, Option);
- cControl::Launch(new cXinelibPlayerControl(ShowFiles, Option));
- return cString("Playing video file");
- } else {
- ReplyCode = 550; // Requested action not taken
- }
- }
-
- else if(strcasecmp(Command, "PDVD") == 0) {
- if(*Option) {
- LOGMSG("SVDRP(%s, %s)", Command, Option);
- cControl::Launch(new cXinelibDvdPlayerControl(Option));
- return cString("Playing DVD disc");
- } else {
- ReplyCode = 550; // Requested action not taken
- }
- }
-
- else if(strcasecmp(Command, "PMSC") == 0) {
- if(*Option) {
- LOGMSG("SVDRP(%s, %s)", Command, Option);
- cControl::Launch(new cXinelibPlayerControl(ShowMusic, Option));
- return cString("Playing music file");
- } else {
- ReplyCode = 550; // Requested action not taken
- }
- }
-
- else if(strcasecmp(Command, "PIMG") == 0) {
- if(*Option) {
- char **list = new char*[2];
- list[0] = strdup(Option);
- list[1] = NULL;
- LOGMSG("SVDRP(%s, %s)", Command, Option);
- cControl::Launch(new cXinelibImagesControl(list, 0, 1));
- return cString("Showing image file");
- } else {
- ReplyCode = 550; // Requested action not taken
- }
- }
-
- else if(strcasecmp(Command, "QMSC") == 0) {
- if(*Option) {
- LOGMSG("SVDRP(%s, %s)", Command, Option);
- cXinelibPlayerControl::Queue(Option);
- return cString("Queueing music file");
- } else {
- ReplyCode = 550; // Requested action not taken
- }
- }
-
- return NULL;
-}
-
-extern "C"
-void *VDRPluginCreator(void) __attribute__((visibility("default")));
-
-VDRPLUGINCREATOR(cPluginXinelibOutput); // Don't touch this!