diff --git a/veejay-current/plugin-packs/lvdshared/AUTHORS b/veejay-current/plugin-packs/lvdshared/AUTHORS new file mode 100644 index 00000000..6a19fba9 --- /dev/null +++ b/veejay-current/plugin-packs/lvdshared/AUTHORS @@ -0,0 +1,9 @@ + + +authors: +====================== + + Niels Elburg + + + diff --git a/veejay-current/plugin-packs/lvdshared/COPYING b/veejay-current/plugin-packs/lvdshared/COPYING new file mode 100644 index 00000000..223ede7d --- /dev/null +++ b/veejay-current/plugin-packs/lvdshared/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +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 and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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 with +this License. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/veejay-current/plugin-packs/lvdshared/ChangeLog b/veejay-current/plugin-packs/lvdshared/ChangeLog new file mode 100644 index 00000000..e69de29b diff --git a/veejay-current/plugin-packs/lvdshared/Makefile.am b/veejay-current/plugin-packs/lvdshared/Makefile.am new file mode 100644 index 00000000..4b530378 --- /dev/null +++ b/veejay-current/plugin-packs/lvdshared/Makefile.am @@ -0,0 +1,46 @@ +# Process with automake to produce Makefile.in + +SUBDIRS = plugins + +# +# Add any non autoconf'd files here, extra readmes and other misc +# info to be copied into the dist +# +EXTRA_DIST = \ + autogen.sh\ + depcomp \ + autogen.sh + +DISTCLEANFILES = \ + confdefs.h \ + config.cache \ + config.status \ + config.log + + +MAINTAINERCLEANFILES = \ + compile \ + depcomp \ + install-sh \ + missing \ + mkinstalldirs \ + Makefile.in \ + aclocal.m4 \ + config.guess \ + config.h.in \ + config.sub \ + configure \ + ltmain.sh \ + stamp-h.in + +## make rpms +rpm: Makefile + $(MAKE) dist + rpmbuild -ta --clean $(PACKAGE)-$(VERSION).tar.gz + +## make debs +deb: Makefile dist + -chmod -R +w $(PACKAGE)-$(VERSION) + rm -rf $(PACKAGE)-$(VERSION) + tar xzf $(PACKAGE)-$(VERSION).tar.gz + cd $(PACKAGE)-$(VERSION); dpkg-buildpackage -rfakeroot diff --git a/veejay-current/plugin-packs/lvdshared/NEWS b/veejay-current/plugin-packs/lvdshared/NEWS new file mode 100644 index 00000000..e69de29b diff --git a/veejay-current/plugin-packs/lvdshared/README b/veejay-current/plugin-packs/lvdshared/README new file mode 100644 index 00000000..c25f73d9 --- /dev/null +++ b/veejay-current/plugin-packs/lvdshared/README @@ -0,0 +1,14 @@ + +Veejay's crop +------------------------- + +RUNNING: + +run the autogen.sh script in the source folder, +then run ./configure, make and make install + +run veejay + +----- + + diff --git a/veejay-current/plugin-packs/lvdshared/autogen.sh b/veejay-current/plugin-packs/lvdshared/autogen.sh new file mode 100755 index 00000000..5331cd99 --- /dev/null +++ b/veejay-current/plugin-packs/lvdshared/autogen.sh @@ -0,0 +1,26 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. + +# if you use autoconf 2.64 or earlier, +# you may have to create the m4 directory yourself +# + + + +## remove the '#' in front of the line for 'autoreconf' + +######################################## +## newer distributions, ubuntu 11. etc +######################################## + +if [ ! -d m4 ]; then + mkdir m4 +fi + +autoreconf -v -fi -I m4 + +######################################### +## slackware 13.1 and older +######################################### + +#autoreconf -v -fi diff --git a/veejay-current/plugin-packs/lvdshared/configure.ac b/veejay-current/plugin-packs/lvdshared/configure.ac new file mode 100644 index 00000000..150508ba --- /dev/null +++ b/veejay-current/plugin-packs/lvdshared/configure.ac @@ -0,0 +1,351 @@ +dnl Process this file with autoconf to produce a configure script. +dnl AC_INIT +AC_INIT([lvdshared-plugin],[0.0.1],[veejay-users@lists.sourceforge.net]) +AC_PREREQ(2.57) +AC_CONFIG_SRCDIR([plugins/lvd_shmin.c]) + +LVDGMICMAJOR_VERSION=0 +LVDGMICMINOR_VERSION=0 +LVDGMICMICRO_VERSION=1 +LVDGMICVERSION=$LVDGMICMAJOR_VERSION.$LVDGMICMINOR_VERSION.$LVDGMICMICRO_VERSION +LVDGMICCODENAME="Livido shared resources - build $LVDGMICMINOR_VERSION $LVDGMICMICRO_VERSION" +AC_CONFIG_HEADERS([config.h]) + +AC_CANONICAL_HOST +AC_CANONICAL_TARGET +AC_CONFIG_MACRO_DIR([m4]) +AM_INIT_AUTOMAKE([1.7]) +AM_MAINTAINER_MODE + +AC_DEFINE(VEEJAYUTIL,1,[Building Livido VJ-share plugins]) +AC_DEFINE(HAVE_CONFIG_H,1,[Include config.h]) +# libtool versioning +LT_RELEASE=$LVDGMICMAJOR_VERSION.$LVDGMICMINOR_VERSION +LT_CURRENT=$LVDGMICMICRO_VERSION +LT_REVISION=$LVDGMICMICRO_VERSION +LT_AGE=$LVDGMICMICRO_VERSION +AC_SUBST(LT_RELEASE) +AC_SUBST(LT_CURRENT) +AC_SUBST(LT_REVISION) +AC_SUBST(LT_AGE) +dnl ********************************************************************** +dnl Options + +AC_CONFIG_MACRO_DIR([m4]) + +dnl kill CFLAGS +CFLAGS="" +AC_ARG_ENABLE(strict, + AC_HELP_STRING([--enable-strict], + [Compile in paranoia assertion checking])) +AC_ARG_ENABLE(debug, + AC_HELP_STRING([--enable-debug], + [Compile in debugging information])) +AC_ARG_ENABLE(profile, + AC_HELP_STRING([--enable-profiling], + [Compile in profiling information])) +AC_ARG_ENABLE(compile-warnings, + AC_HELP_STRING([--enable-compile-warnings], + [Turn on compiler warnings.])) +AC_ARG_ENABLE(warnings_as_errors, + AC_HELP_STRING([--enable-warnings_as_errors], + [Compiler warnings are errors.])) +AC_ARG_ENABLE(simd-accel, + AC_HELP_STRING([--enable-simd-accel], + [use SIMD multimedia instructions such as MMX, AltiVec, etc.if possible])) +AC_ARG_WITH(extra-cflags, + AC_HELP_STRING([--with-extra-cflags=flags], + [Options to be added to CFLAGS (optional)])) + + +user_specified_target= +AC_ARG_WITH(arch-target, AS_HELP_STRING( [--with-arch-target=CPU_TYPE], + [Set a specific sub-architecture (defaults to native)]), + [ user_specified_target="$withval" ]) + + + +AC_GNU_SOURCE + +dnl Initialize libtool +AC_PROG_LIBTOOL + +dnl Checks for programs. +AC_PROG_AWK +AC_PROG_CC +AM_PROG_CC_STDC +AC_PROG_YACC +AM_PROG_LEX +AC_PROG_CXX +AC_PROG_INSTALL +AC_PROG_LN_S +AC_C_BIGENDIAN +AC_C_CONST +AC_C_INLINE +AC_SYS_LARGEFILE + +dnl configure AS and ASFLAGS... +AM_PROG_AS + +AC_CHECK_HEADERS([fenv.h stdint.h inttypes.h sys/types.h alloca.h]) + +dnl AX_PREFIXED_DEFINE([VEEJAY], [HAVE_STDINT_H]) +dnl AX_PREFIXED_DEFINE([VEEJAY], [HAVE_INTTYPES_H]) + +AC_CHECK_FUNCS([posix_memalign memalign fmax lround pow bzero gettimeofday memset mmap strndup strstr strncasecmp]) +AC_CHECK_FUNCS([sched_get_priority_max]) +AC_CHECK_FUNCS([select socket getpagesize memcpy]) + +AC_CHECK_FUNC(getopt_long, + [AC_DEFINE(HAVE_GETOPT_LONG, 1, [long getopt support])], + [ # FreeBSD and BSD/OS have a gnugetopt library for this: + AC_CHECK_LIB([gnugetopt], [getopt_long], + [AC_DEFINE(HAVE_GETOPT_LONG, 1, + [long getopt support]) + LIBGETOPT_LIB="-lgnugetopt"]) + ]) + +AC_CHECK_SIZEOF([int]) +AC_CHECK_SIZEOF([long int]) +AC_CHECK_SIZEOF([size_t]) +AC_CHECK_SIZEOF([float]) + + +PKG_CHECK_MODULES(LIBAVUTIL, [libavutil >= 49.7.0],have_avutil=true,have_avutil=false) + +if test x$have_avutil = xtrue; +then + AC_DEFINE( BASE64_AVUTIL,1,[Use avutil base64]) +fi + +AC_SUBST(LIBAVUTIL_CFLAGS) +AC_SUBST(LIBAVUTIL_LIBS) + +AC_SUBST(LIBGETOPT_LIB) + +AC_TYPE_SIGNAL + +AC_MSG_NOTICE([The host is $host $host_cpu $host_vendor $host_os .]) + +dnl ********************************************************************* +dnl Test whether we're linux or not. If so, define HAVE_V4L and build the +dnl video4linux/hardware dependent tools. Else, undefine HAVE_V4L +have_v4l=false +have_linux=false +have_darwin=false +case $host in + *-*-linux*) + AC_CHECK_HEADER(linux/version.h, + [have_linux=true + AC_DEFINE(HAVE_LINUX,,[Linux platform]) + ], + [AC_MSG_ERROR([version.h not found - please install the linux kernel headers]) + ]) + LIBM_LIBS="-lm" + ;; + *-apple-darwin*) + AC_DEFINE(HAVE_DARWIN,1,[MAC OS X Darin]) + dnl OS-X/Darwin needs no-cpp-precomp + CFLAGS="$CFLAGS -no-cpp-precomp" + have_darwin=true + LIBM_LIBS="" + ;; + *) + AC_MSG_WARN([Alien platform - Good Luck!]) + LIBM_LIBS="" + ;; +esac + + +dnl ====== check for PKG_CONFIG_PATH +if test x"$PKG_CONFIG_PATH" = x ; then + AC_MSG_NOTICE([The PKG_CONFIG_PATH variable was not set]) + AC_MSG_NOTICE([You should set it to the directories that contain the .pc files]) + PKG_CONFIG_PATH=/usr/lib/pkgconfig +fi + + +AC_SUBST(LIBM_LIBS) + +have_dl_dlopen=false +AC_CHECK_LIB(dl,dlopen) +if test "$ac_cv_lib_dl_dlopen" = "yes"; then + AC_DEFINE(HAVE_DL_DLOPEN,,[Compile with dlopen support]) + have_dl_dlopen=true +fi + + +AC_MSG_CHECKING(whether to compile in debugging information) +debugCFLAGS="" +if test "x$enable_debug" = "xyes" ; then + debugCFLAGS="-g" + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi +AC_MSG_CHECKING(whether to compile in profiling information) +if test "x$enable_profiling" = "xyes" ; then + debugCFLAGS="$debugCFLAGS -fprofile-arcs -ftest-coverage" + DEBUGLIBS="-lgcov" + AC_SUBST(DEBUGLIBS) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +AC_MSG_CHECKING([Architecture]) +case $host_cpu in + i[[3-7]]86) + AC_DEFINE(HAVE_X86CPU,1, [Compiling for x86 architecture CPU]) + AC_DEFINE(ARCH_X86,1,[Compiling for x86 architecture]) + have_x86cpu=true + + PROGRAM_NOPIC="-fno-PIC" + + dnl If the host is pentium, align on double word boundary + case $host_cpu in + i686) + CFLAGS="-ffast-math -O3 -ftree-vectorize" + ;; + *) + ;; + esac + + ;; + x86_64*|k8-*) + AC_DEFINE(HAVE_X86_CPU,1, [Compiling for x86-64 architecture CPU]) + AC_DEFINE(ARCH_X86_64,1, [Compiling for x86-64 architecture CPU]) + have_x86cpu=true + have_x86_64cpu=true + CFLAGS="-m64 -fPIC -DPIC -ftree-vectorize -O3 -ffast-math" + ;; + powerpc | powerpc64) + AC_DEFINE(HAVE_PPCCPU,1, [Compiling for PowerPC CPU]) + AC_DEFINE(ARCH_PPC,1,[Compiling for PowerPC]) + have_ppccpu=true + + case $host in + *-apple-darwin*) + PROGRAM_NOPIC="-mdynamic-no-pic" # dynamic-no-pic is an Apple gcc option + + ;; + *) + PROGRAM_NOPIC="" + ;; + esac + ;; + mips | mipsel) + AC_DEFINE(ARCH_MIPS,,[Compiling for MIPS CPU]) + AC_DEFINE(HAVE_MIPS,,[Compiling for MIPS CPU]) + have_mips=true + AC_MSG_CHECKING([if we are compiling on playstation2 hardware]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], + [[#include + #include + ]])], + [have_ps2=true], + [have_ps2=false]) + + if test x$have_ps2 = xtrue ; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PS2,1,[Compile for playstation2]) + else + AC_MSG_RESULT(no) + fi + + ;; + *) + AC_MSG_RESULT([unknown]) + ;; +esac + +AC_SUBST(PROGRAM_NOPIC) + + +AC_DEFINE_UNQUOTED(HAVE_FFMPEG_UNINSTALLED,, + [Defined if building against uninstalled FFmpeg source]) + +PKG_CHECK_MODULES(LIBAVUTIL, [libavutil >= 49.7.0],have_avutil=true,have_avutil=false) +PKG_CHECK_MODULES(LIBSWSCALE,[libswscale >= 0.7.1],have_swscale=true,have_swscale=false) +if test x$have_swscale = xfalse; +then + AC_MSG_ERROR([libswscale not found.]) +fi +if test x$have_avutil = xfalse; +then + AC_MSG_ERROR([libavutil not found.]) +fi + +FFMPEG_CFLAGS="${LIBAVUTIL_CFLAGS} ${LIBSWSCALE_CFLAGS}" +FFMPEG_LIBS="${LIBAVUTIL_LIBS} ${LIBSWSCALE_LIBS}" +AC_SUBST(FFMPEG_CFLAGS) +AC_SUBST(FFMPEG_LIBS) + + + +AC_MSG_RESULT($CFLAGS) + +CFLAGS="$ARCHFLAGS $CFLAGS" +CXXFLAGS="$ARCHFLAGS $CXXFLAGS" + + +if test "x${GCC}" != "xyes" ; then + enable_compile_warnings=no +fi + +AC_MSG_CHECKING(what warning flags to pass to the C compiler) +warnCFLAGS= +warnCXXFLAGS= +if test "x$enable_compile_warnings" != "xno" ; then + if test "x$GCC" = "xyes" ; then + case "$CFLAGS" in + *-Wall*) ;; + *) warnCFLAGS="-Wall -Wunused " ;; + esac + if test "x$enable_compile_warnings" = "xyes" ; then + warnCFLAGS="$warnCFLAGS -Wmissing-prototypes -Wundef -Wshadow -Wbad-function-cast -Wconversion -Wpadded -Wunreachable-code -Wmissing-declarations -Wpointer-arith -Wcast-align -Wwrite-strings -Wcast-qual" + warnCXXFLAGS="$warnCXXFLAGS -Wmissing-prototypes -Wpointer-arith -Wcast-align -Wwrite-strings -Wcast-qual" + fi + if test "x$enable_warnings_as_errors" = "xyes" ; then + warnCFLAGS="$warnCFLAGS -Werror" + warnCXXFLAGS="$warnCXXFLAGS -Werror" + fi + fi +fi + +if test "x$cflags_set" != "xyes" ; then + if test "x$enable_debug" = "xyes" ; then + CFLAGS="$debugCFLAGS $warnCFLAGS $CFLAGS" + else + CFLAGS="$CFLAGS $warnCFLAGS -DSILENT" + fi + CXXFLAGS="$CXXFLAGS $warnCXXFLAGS" + cflags_set=yes +fi + + +if test x"$with_extra_cflags" != "x"; then + CFLAGS="$CFLAGS $with_extra_cflags" + CXXFLAGS="$CXXFLAGS $with_extra_cflags" +fi + +AC_CONFIG_FILES([ +Makefile +plugins/Makefile +]) +AC_OUTPUT + +AC_DEFINE(VERSION, ${VERSION}) + +AC_MSG_NOTICE([]) +AC_MSG_NOTICE([ Livido shared resources ${VERSION} build configuration :]) +AC_MSG_NOTICE([]) +AC_MSG_NOTICE([ Compiler flags: $CFLAGS]) +AC_MSG_NOTICE([]) +AC_MSG_NOTICE([ Architecture: ${host_cpu} ]) +AC_MSG_NOTICE([]) +AC_MSG_NOTICE([ - FFmpeg/AV Swscaler : ${have_swscale} ]) +AC_MSG_NOTICE([ - FFmpeg/AV AVUtil : ${have_avutil} ]) +if test "$have_linux" = "true" ; then +AC_MSG_NOTICE([ Platform: Linux]) +fi diff --git a/veejay-current/plugin-packs/lvdshared/plugins/Makefile.am b/veejay-current/plugin-packs/lvdshared/plugins/Makefile.am new file mode 100644 index 00000000..9e4f2a5c --- /dev/null +++ b/veejay-current/plugin-packs/lvdshared/plugins/Makefile.am @@ -0,0 +1,28 @@ +lividoplugin_LTLIBRARIES = lvd_shmin.la lvd_shmout.la + +lvd_shmin_la_SOURCES = lvd_shmin.c +lvd_shmout_la_SOURCES = lvd_shmout.c + +INCLUDES=$(FFMPEG_CFLAGS) -I$(top_srcdir)/lvdshm +AM_CFLAGS=-I@top_srcdir@/include $(OPTCFLAGS) -DSILENT +AM_LDFLAGS=-module -avoid-version -lm -export-dynamic -lgmic -lstdc++ -DDYNAMIC -rdynamic $(FFMPEG_LIBS) +AM_LIBTOOLFLAGS = --tag=disable-static + +lividoplugindir = @libdir@/livido-plugins +liblvdgmicdir= @libdir@/livido-plugins + +install-lividopluginLTLIBRARIES:$(lividoplugin_LTLIBRARIES) + mkdir -p $(DESTDIR)/$(lividoplugindir) + list='$(lividoplugin_LTLIBRARIES)'; \ + for file in $$list; do \ + sofile=`basename $$file .la`.so; \ + $(INSTALL_PROGRAM) .libs/$$sofile $(DESTDIR)/$(lividoplugindir);\ + done + +uninstall-lividopluginLTLIBRARIES: + list='$(lividoplugin_LTLIBRARIES)'; \ + for file in $$list; do \ + sofile=`basename $$file .la`.so; \ + rm -f $(DESTDIR)/$(lividoplugindir)/$$sofile; \ + done + diff --git a/veejay-current/plugin-packs/lvdshared/plugins/livido-utils.c b/veejay-current/plugin-packs/lvdshared/plugins/livido-utils.c new file mode 100644 index 00000000..249d14a8 --- /dev/null +++ b/veejay-current/plugin-packs/lvdshared/plugins/livido-utils.c @@ -0,0 +1,358 @@ +/* LiViDO is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + LiViDO 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this source code; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + LiViDO is developed by: + + Niels Elburg - http://veejay.sf.net + + Gabriel "Salsaman" Finch - http://lives.sourceforge.net + + Denis "Jaromil" Rojo - http://freej.dyne.org + + Tom Schouten - http://zwizwa.fartit.com + + Andraz Tori - http://cvs.cinelerra.org + + reviewed with suggestions and contributions from: + + Silvano "Kysucix" Galliani - http://freej.dyne.org + + Kentaro Fukuchi - http://megaui.net/fukuchi + + Jun Iio - http://www.malib.net + + Carlo Prelz - http://www2.fluido.as:8080/ + +*/ + +/* (C) Gabriel "Salsaman" Finch, 2005 */ + + +///////////////////////////////////////////////////////////////// + +#include +#include +#include "livido.h" + +int livido_has_property (livido_port_t *port, const char *key) { + if (livido_property_get(port,key,0,NULL)==LIVIDO_ERROR_NOSUCH_PROPERTY) return 0; + return 1; +} + +///////////////////////////////////////////////////////////////// +// property setters + +int livido_set_int_value (livido_port_t *port, const char *key, int value) { + // returns a LIVIDO_ERROR + return livido_property_set (port,key,LIVIDO_ATOM_TYPE_INT,1,&value); +} + +int livido_set_double_value (livido_port_t *port, const char *key, double value) { + // returns a LIVIDO_ERROR + return livido_property_set (port,key,LIVIDO_ATOM_TYPE_DOUBLE,1,&value); +} + +int livido_set_boolean_value (livido_port_t *port, const char *key, int value) { + // returns a LIVIDO_ERROR + return livido_property_set (port,key,LIVIDO_ATOM_TYPE_BOOLEAN,1,&value); +} + +int livido_set_string_value (livido_port_t *port, const char *key, char *value) { + // returns a LIVIDO_ERROR + return livido_property_set (port,key,LIVIDO_ATOM_TYPE_STRING,1,&value); +} + +int livido_set_portptr_value (livido_port_t *port, const char *key, void *value) { + // returns a LIVIDO_ERROR + return livido_property_set (port,key,LIVIDO_ATOM_TYPE_PORTPTR,1,&value); +} + +int livido_set_voidptr_value (livido_port_t *port, const char *key, void *value) { + // returns a LIVIDO_ERROR + return livido_property_set (port,key,LIVIDO_ATOM_TYPE_VOIDPTR,1,&value); +} + + +/////////// these functions need a size //////////// + + +////////////////////////////////////////////////////////////////////////////////////////////////// +// general property getter + +inline int livido_get_value (livido_port_t *port, const char *key, void *value) { + // returns a LIVIDO_ERROR + return livido_property_get( port, key, 0, value); +} + +//////////////////////////////////////////////////////////// + +int livido_get_int_value (livido_port_t *port, const char *key, int *error) { + int retval=0; + if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_INT) { + *error=LIVIDO_ERROR_WRONG_ATOM_TYPE; + return retval; + } + else *error=livido_get_value (port,key,&retval); + return retval; +} + +double livido_get_double_value (livido_port_t *port, const char *key, int *error) { + double retval=0.; + if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_DOUBLE) { + *error=LIVIDO_ERROR_WRONG_ATOM_TYPE; + return retval; + } + *error=livido_get_value (port,key,&retval); + return retval; +} + +int livido_get_boolean_value (livido_port_t *port, const char *key, int *error) { + int retval=0; + if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_BOOLEAN) { + *error=LIVIDO_ERROR_WRONG_ATOM_TYPE; + return retval; + } + *error=livido_get_value (port,key,&retval); + return retval; +} + +char *livido_get_string_value (livido_port_t *port, const char *key, int *error) { + char *retval=NULL; + if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_STRING) { + *error=LIVIDO_ERROR_WRONG_ATOM_TYPE; + return NULL; + } + if ((retval=(char *)livido_malloc(livido_property_element_size(port,key,0)+1))==NULL) { + *error=LIVIDO_ERROR_MEMORY_ALLOCATION; + return NULL; + } + if ((*error=livido_get_value (port,key,&retval))!=LIVIDO_NO_ERROR) { + livido_free (retval); + return NULL; + } + return retval; +} + +void *livido_get_voidptr_value (livido_port_t *port, const char *key, int *error) { + void *retval=NULL; + if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_VOIDPTR) { + *error=LIVIDO_ERROR_WRONG_ATOM_TYPE; + return retval; + } + *error=livido_get_value (port,key,&retval); + return retval; +} + +livido_port_t *livido_get_portptr_value (livido_port_t *port, const char *key, int *error) { + livido_port_t *retval=NULL; + if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_PORTPTR) { + *error=LIVIDO_ERROR_WRONG_ATOM_TYPE; + return retval; + } + *error=livido_get_value (port,key,&retval); + return retval; +} + + +//////////////////////////////////////////////////////////// + +int *livido_get_int_array (livido_port_t *port, const char *key, int *error) { + int i; + int num_elems; + int *retval; + + if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_INT) { + *error=LIVIDO_ERROR_WRONG_ATOM_TYPE; + return NULL; + } + + if ((num_elems=livido_property_num_elements (port,key))==0) return NULL; + + if ((retval=(int *)livido_malloc(num_elems*sizeof(int)))==NULL) { + *error=LIVIDO_ERROR_MEMORY_ALLOCATION; + return NULL; + } + + for (i=0;i=0;i--) livido_free(retval[i]); + *error=LIVIDO_ERROR_MEMORY_ALLOCATION; + livido_free (retval); + return NULL; + } + if ((*error=livido_property_get(port, key, i, &retval[i]))!=LIVIDO_NO_ERROR) { + for (--i;i>=0;i--) livido_free(retval[i]); + livido_free (retval); + return NULL; + } + } + return retval; +} + +void **livido_get_voidptr_array (livido_port_t *port, const char *key, int *error) { + int i; + int num_elems; + void **retval; + + if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_VOIDPTR) { + *error=LIVIDO_ERROR_WRONG_ATOM_TYPE; + return NULL; + } + + if ((num_elems=livido_property_num_elements (port,key))==0) return NULL; + + if ((retval=(void **)livido_malloc(num_elems*sizeof(void *)))==NULL) { + *error=LIVIDO_ERROR_MEMORY_ALLOCATION; + return NULL; + } + + for (i=0;i + + +#ifdef IS_LIVIDO_PLUGIN +typedef void livido_port_t; +#endif +#define LIVIDO_API_VERSION 103 +#define LIVIDO_PALETTE_RGB888 1 +#define LIVIDO_PALETTE_RGB24 1 +#define LIVIDO_PALETTE_BGR888 2 +#define LIVIDO_PALETTE_BGR24 2 +#define LIVIDO_PALETTE_RGBA8888 3 +#define LIVIDO_PALETTE_RGBA32 3 +#define LIVIDO_PALETTE_ARGB8888 4 +#define LIVIDO_PALETTE_ARGB32 4 + +#define LIVIDO_PALETTE_RGBFLOAT 5 +#define LIVIDO_PALETTE_ARGBFLOAT 6 + +#define LIVIDO_PALETTE_RGB48BE 7 +#define LIVIDO_PALETTE_RGB48LE 8 +#define LIVIDO_PALETTE_YUV444P16LE 9 +#define LIVIDO_PALETTE_YUV444P16BE 10 +#define LIVIDO_PALETTE_YUV422P16LE 11 +#define LIVIDO_PALETTE_YUV422P16BE 12 +#define LIVIDO_PALETTE_YUV422P 513 +#define LIVIDO_PALETTE_YV16 513 +#define LIVIDO_PALETTE_YUV420P 514 +#define LIVIDO_PALETTE_YV12 514 +#define LIVIDO_PALETTE_YVU420P 515 +#define LIVIDO_PALETTE_I420 515 + +#define LIVIDO_PALETTE_YUV444P 516 +#define LIVIDO_PALETTE_YUV4444P 517 +#define LIVIDO_PALETTE_YUV444P16 523 +#define LIVIDO_PALETTE_YUYV8888 518 +#define LIVIDO_PALETTE_UYVY8888 519 +#define LIVIDO_PALETTE_YUV411 520 +#define LIVIDO_PALETTE_YUV888 521 +#define LIVIDO_PALETTE_YUVA8888 522 +#define LIVIDO_PALETTE_A1 1025 +#define LIVIDO_PALETTE_A8 1026 +#define LIVIDO_PALETTE_A16 1028 +#define LIVIDO_PALETTE_AFLOAT 1027 + +/** + *Plugin is not realtime capable + */ +#define LIVIDO_FILTER_NON_REALTIME (1<<0) +/** + *Plugin processes inplace + */ +#define LIVIDO_FILTER_CAN_DO_INPLACE (1<<1) +/** + *Plugin keeps internal state + */ +#define LIVIDO_FILTER_NON_STATELESS (1<<2) +/** + *Plugin is parallelizable (host is allowed to run it in parallel) + */ +#define LIVIDO_FILTER_IS_PARALLELIZABLE (1<<4) + +/** + * Error messages + */ +#define LIVIDO_NO_ERROR 0 +#define LIVIDO_ERROR_MEMORY_ALLOCATION 1 +#define LIVIDO_ERROR_PROPERTY_READONLY 2 +#define LIVIDO_ERROR_NOSUCH_ELEMENT 3 +#define LIVIDO_ERROR_NOSUCH_PROPERTY 4 +#define LIVIDO_ERROR_WRONG_ATOM_TYPE 5 +#define LIVIDO_ERROR_TOO_MANY_INSTANCES 6 +#define LIVIDO_ERROR_HARDWARE 7 +#define LIVIDO_ERROR_PORT 8 +#define LIVIDO_ERROR_NO_OUTPUT_CHANNELS 9 +#define LIVIDO_ERROR_NO_INPUT_CHANNELS 10 +#define LIVIDO_ERROR_NO_INPUT_PARAMETERS 11 +#define LIVIDO_ERROR_NO_OUTPUT_PARAMETERS 12 +#define LIVIDO_ERROR_ENVIRONMENT 13 +#define LIVIDO_ERROR_RESOURCE 14 +#define LIVIDO_ERROR_INTERNAL 15 + +/** + * Primitives + */ +#define LIVIDO_ATOM_TYPE_INT 1 +#define LIVIDO_ATOM_TYPE_DOUBLE 2 +#define LIVIDO_ATOM_TYPE_BOOLEAN 3 +#define LIVIDO_ATOM_TYPE_STRING 4 +#define LIVIDO_ATOM_TYPE_VOIDPTR 65 +#define LIVIDO_ATOM_TYPE_PORTPTR 66 + +/** + * Port types + */ +#define LIVIDO_PORT_TYPE_PLUGIN_INFO 1 +#define LIVIDO_PORT_TYPE_FILTER_CLASS 2 +#define LIVIDO_PORT_TYPE_FILTER_INSTANCE 3 +#define LIVIDO_PORT_TYPE_CHANNEL_TEMPLATE 4 +#define LIVIDO_PORT_TYPE_PARAMETER_TEMPLATE 5 +#define LIVIDO_PORT_TYPE_CHANNEL 6 +#define LIVIDO_PORT_TYPE_PARAMETER 7 +#define LIVIDO_PORT_TYPE_GUI 8 + +typedef int (*livido_init_f) (livido_port_t * filter_instance); +typedef int (*livido_process_f) (livido_port_t * filter_instance,double timestamp); +typedef int (*livido_deinit_f) (livido_port_t * filter_instance); + +typedef void *(*livido_malloc_f) (size_t size); +typedef void (*livido_free_f) (void *ptr); +typedef void *(*livido_memset_f) (void *s, int c, size_t n); +typedef void *(*livido_memcpy_f) (void *dest, const void *src, size_t n); +typedef livido_port_t *(*livido_port_new_f) (int); +typedef void (*livido_port_free_f) (livido_port_t * port); +typedef int (*livido_property_set_f) (livido_port_t *, const char *, int, int, void *); +typedef int (*livido_property_get_f) (livido_port_t *, const char *, int, void *); +typedef int (*livido_property_num_elements_f) (livido_port_t *, const char *); +typedef int (*livido_property_atom_type_f) (livido_port_t *, const char *); +typedef size_t(*livido_property_element_size_f) (livido_port_t *, const char *, const int); +typedef char **(*livido_list_properties_f) (livido_port_t *); +typedef int (*livido_keyframe_get_f)(livido_port_t *port, long pos, int dir ); +typedef int (*livido_keyframe_put_f)(livido_port_t *port, long pos, int dir ); + +typedef struct +{ + void (*f)(); +} livido_setup_t; + +typedef livido_port_t *(*livido_setup_f) (const livido_setup_t list[], int ); + +#define LIVIDO_PLUGIN \ +static livido_port_t *(*livido_port_new) (int) = 0;\ +static void (*livido_port_free) (livido_port_t * port) = 0;\ +static int (*livido_property_set) (livido_port_t * port,const char *key, int atom_type, int num_elems, void *value) = 0;\ +static int (*livido_property_get) (livido_port_t * port,const char *key, int idx, void *value) = 0;\ +static int (*livido_property_num_elements) (livido_port_t * port,const char *key) = 0;\ +static int (*livido_property_atom_type) (livido_port_t * port,const char *key) = 0;\ +static size_t(*livido_property_element_size) (livido_port_t * port,const char *key, const int idx) = 0;\ +static char **(*livido_list_properties) (livido_port_t * port) = 0;\ +static void *(*livido_malloc) (size_t size) = 0;\ +static void (*livido_free) (void *ptr) = 0;\ +static void *(*livido_memset) (void *s, int c, size_t n) = 0;\ +static void *(*livido_memcpy) (void *dest, const void *src, size_t n) = 0;\ +static int (*livido_keyframe_get)(livido_port_t *port, long pos, int dir) = 0;\ +static int (*livido_keyframe_put)(livido_port_t *port, long pos, int dir) = 0; \ + +/* Using void* to pass base address of function, needs explicit typecast and host must match ordering */ +#define LIVIDO_IMPORT(list) \ +{\ + livido_malloc = (livido_malloc_f) list[0].f;\ + livido_free = (livido_free_f) list[1].f;\ + livido_memset = (livido_memset_f) list[2].f;\ + livido_memcpy = (livido_memcpy_f) list[3].f;\ + livido_port_new = (livido_port_new_f) list[4].f;\ + livido_port_free = (livido_port_free_f) list[5].f;\ + livido_property_set = (livido_property_set_f) list[6].f;\ + livido_property_get = (livido_property_get_f) list[7].f;\ + livido_property_num_elements = (livido_property_num_elements_f) list[8].f;\ + livido_property_atom_type = (livido_property_atom_type_f) list[9].f;\ + livido_property_element_size = (livido_property_element_size_f) list[10].f;\ + livido_list_properties = (livido_list_properties_f) list[11].f;\ + livido_keyframe_get = (livido_keyframe_get_f) list[12].f;\ + livido_keyframe_put = (livido_keyframe_put_f) list[13].f;\ +} + +LIVIDO_END_DECLS +#endif// #ifndef __LIVIDO_H_ diff --git a/veejay-current/veejay-server/livido-plugins/lvd_shmin.c b/veejay-current/plugin-packs/lvdshared/plugins/lvd_shmin.c similarity index 96% rename from veejay-current/veejay-server/livido-plugins/lvd_shmin.c rename to veejay-current/plugin-packs/lvdshared/plugins/lvd_shmin.c index d7def473..c35b2147 100644 --- a/veejay-current/veejay-server/livido-plugins/lvd_shmin.c +++ b/veejay-current/plugin-packs/lvdshared/plugins/lvd_shmin.c @@ -40,7 +40,7 @@ #include #include -#include "../libplugger/specs/livido.h" +#include "livido.h" LIVIDO_PLUGIN #include "utils.h" #include "livido-utils.c" @@ -63,6 +63,8 @@ static inline int lvd_to_ffmpeg( int lvd, int fr ) { return PIX_FMT_RGB24; case LIVIDO_PALETTE_RGBA32: return PIX_FMT_RGBA; + case LIVIDO_PALETTE_YUV444P: + return PIX_FMT_YUV444P; default: if( fr ) return PIX_FMT_YUVJ422P; @@ -88,7 +90,6 @@ livido_init_f init_instance( livido_port_t *my_instance ) snprintf(path,sizeof(path)-1, "%s/.veejay/veejay.shm", home ); int fd = open( path, O_RDWR ); if(fd <= 0) { - printf("no env var VEEJAY_SHMID set and no file '%s' found!\n",path ); return LIVIDO_ERROR_ENVIRONMENT; } char buf[256]; @@ -263,6 +264,12 @@ livido_process_f process_instance( livido_port_t *my_instance, double timecode strides[2] = strides[1]; in[1] = in[0] + ( srcW * srcH ); in[2] = in[1] + ( (srcW>>1) * srcH); + } else if ( srcFormat == PIX_FMT_YUV444P || srcFormat == PIX_FMT_YUVJ444P ) { + strides[0] = srcW; + strides[1] = srcW; + strides[2] = srcW; + in[1] = in[0] + (srcW * srcH); + in[2] = in[1] + (srcW * srcH); } sws_scale( sws, (const uint8_t *const *)in, strides,0, srcH,(uint8_t * const*) O, dst_strides ); @@ -272,7 +279,6 @@ livido_process_f process_instance( livido_port_t *my_instance, double timecode return LIVIDO_ERROR_RESOURCE; } - return LIVIDO_NO_ERROR; } diff --git a/veejay-current/veejay-server/livido-plugins/lvd_shmout.c b/veejay-current/plugin-packs/lvdshared/plugins/lvd_shmout.c similarity index 99% rename from veejay-current/veejay-server/livido-plugins/lvd_shmout.c rename to veejay-current/plugin-packs/lvdshared/plugins/lvd_shmout.c index c6317399..975125e9 100644 --- a/veejay-current/veejay-server/livido-plugins/lvd_shmout.c +++ b/veejay-current/plugin-packs/lvdshared/plugins/lvd_shmout.c @@ -48,7 +48,7 @@ how to setup: #include #include #include -#include "../libplugger/specs/livido.h" +#include "livido.h" LIVIDO_PLUGIN #include "utils.h" #include "livido-utils.c" diff --git a/veejay-current/plugin-packs/lvdshared/plugins/utils.h b/veejay-current/plugin-packs/lvdshared/plugins/utils.h new file mode 100644 index 00000000..9412f125 --- /dev/null +++ b/veejay-current/plugin-packs/lvdshared/plugins/utils.h @@ -0,0 +1,279 @@ +#ifndef LVDUTILSFX +#define LVDUTILSFX + +#include +#include +#ifdef STRICT_CHECKING +#include +#endif + +#include + +#ifdef ARCH_X86 +#define fast_sin(d,x) asm("fsin" : "=t" (d) : "0" (x)) +#define fast_cos(d,x) asm("fcos" : "=t" (d) : "0" (x)) +#define fast_sqrt(res,x) asm ("fsqrt" : "=t" (res) : "0" (x)) +#define sin_cos(si, co, x) asm ("fsincos" : "=t" (co), "=u" (si) : "0" (x)) +#else +#define fast_sin(d,x) d = sin(x) +#define fast_cos(d,x) d = cos(x) +#define fast_sqrt( res,x ) res = sqrt(x) +#define sin_cos(si, co, x) si = sin(x); co = cos(x) + +#endif +static inline int myround(float n) +{ + if (n >= 0) + return (int)(n + 0.5); + else + return (int)(n - 0.5); +} + +#define _rgb2yuv(r,g,b,y,u,v)\ + {\ + float Ey = (0.299 * (float)r) + (0.587 * (float)g) + (0.114 * (float) b);\ + float Eu = (-0.168736 * (float)r) - (0.331264 * (float)g) + (0.500 * (float)b) + 128.0;\ + float Ev = (0.500 * (float)r) - (0.418688 * (float)g) - (0.081312 * (float)b)+ 128.0;\ + y = myround(Ey);\ + u = myround(Eu);\ + v = myround(Ev);\ + if( y > 0xff ) y = 0xff ; else if ( y < 0 ) y = 0;\ + if( u > 0xff ) u = 0xff ; else if ( u < 0 ) u = 0;\ + if( v > 0xff ) v = 0xff ; else if ( v < 0 ) v = 0;\ + } + + +#ifdef USE_MATRIX_PLACEMENT +typedef struct +{ + int w; + int h; +} matrix_t; + +typedef matrix_t (*matrix_f)(int i, int s, int w, int h); +static matrix_t matrix_placementA(int photoindex, int size, int w , int h); +static matrix_t matrix_placementB(int photoindex, int size, int w , int h); +static matrix_f get_matrix_func(int type); + +static matrix_t matrix_placementA(int photoindex, int size, int w , int h) +{ + matrix_t m; + m.w = (photoindex % size) * (w/size); + m.h = (photoindex / size) * (h/size); + return m; +} + +static matrix_t matrix_placementB(int photoindex, int size, int w , int h) +{ + matrix_t m; + m.w = (photoindex/size) * (w/size); + m.h = (photoindex % size) * (h/size); + return m; +} + +static matrix_t matrix_placementC(int photoindex, int size, int w , int h) +{ + matrix_t m; + int n = size*size-1; + m.w = ((n-photoindex) % size) * (w/size); + m.h = ((n-photoindex) / size) * (h/size); + return m; +} + +static matrix_t matrix_placementD(int photoindex, int size, int w , int h) +{ + matrix_t m; + int n = size*size-1; + m.w = ((n-photoindex) / size) * (w/size); + m.h = ((n-photoindex) % size) * (h/size); + return m; +} + +static matrix_f get_matrix_func(int type) +{ + if(type==0) + return &matrix_placementA; + if(type==1) + return &matrix_placementB; + if(type==2) + return &matrix_placementC; + return &matrix_placementD; +} +#endif + +static int power_of(int size) +{ + int power = 1; + while( size-- ) + power *= 2; + + return power; +} + +static int max_power(int w) +{ + int i=1; + while(power_of(i) < w) + i++; + return i; +} + +static uint8_t _dilate_kernel3x3( uint8_t *kernel, uint8_t img[9]) +{ + register int x; + for(x = 0; x < 9; x ++ ) + if((kernel[x] * img[x]) > 0 ) + return 0xff; + return 0; +} +static uint8_t _erode_kernel3x3( uint8_t *kernel, uint8_t img[9]) +{ + register int x; + /* consider all background pixels (0) in input image */ + for(x = 0; x < 9; x ++ ) + if(kernel[x] && img[x] == 0 ) + return 0; + return 0xff; +} +static int lvd_is_yuv444( int palette ) +{ + if( palette == LIVIDO_PALETTE_YUV444P ) + return 1; + return 0; +} + +static int lvd_uv_plane_len( int palette, int w, int h ) +{ + switch(palette) + { + case LIVIDO_PALETTE_YUV422P: + return ( (w * h)/2 ); + break; + case LIVIDO_PALETTE_YUV420P: + return ( (w/2) * (h/2) ); + break; + case LIVIDO_PALETTE_YUV444P: + return (w*h); + break; + default: + break; + + } + return 0; +} + +static int lvd_uv_dimensions( int palette, int w, int h, int *uw, int *uh ) +{ + switch(palette) + { + case LIVIDO_PALETTE_YUV422P: + *uw = w; + *uh = h/2; + return 1; + break; + case LIVIDO_PALETTE_YUV420P: + *uw = w/2; + *uh = h/2; + return 1; + break; + case LIVIDO_PALETTE_YUV444P: + *uw = w; + *uh = h; + return 1; + break; + default: + break; + + } + return 0; + +} + +static double lvd_extract_param_number( livido_port_t *instance, const char *pname, int n ) +{ + double pn = 0.0; + livido_port_t *c = NULL; + if( livido_property_get( instance, pname,n, &c ) != LIVIDO_NO_ERROR ) + return pn; + + if( livido_property_get( c, "value", 0, &pn ) != LIVIDO_NO_ERROR ) + return pn; + return pn; +} + + +static int lvd_extract_param_index( livido_port_t *instance, const char *pname, int n ) +{ + int pn = 0; + livido_port_t *c = NULL; + if( livido_property_get( instance, pname,n, &c ) != LIVIDO_NO_ERROR ) + return 0; + + if( livido_property_get( c, "value", 0, &pn ) != LIVIDO_NO_ERROR ) + return 0; + + return pn; +} + +static int lvd_extract_param_boolean( livido_port_t *instance, const char *pname, int n ) +{ + int pn = 0; + livido_port_t *c = NULL; + if( livido_property_get( instance, pname,n, &c ) != LIVIDO_NO_ERROR ) + return pn; + + if( livido_property_get( c, "value", 0, &pn ) != LIVIDO_NO_ERROR ) + return pn; + return pn; +} +static void lvd_set_param_number( livido_port_t *instance, const char *pname,int id, double num ) +{ + livido_port_t *c = NULL; + if( livido_property_get( instance, pname,id, &c ) != LIVIDO_NO_ERROR ) + return; + livido_property_set( c, "value",LIVIDO_ATOM_TYPE_DOUBLE, 1, &num ); +} + +static void lvd_extract_dimensions( livido_port_t *instance,const char *name, int *w, int *h ) +{ + livido_port_t *channel = NULL; + if( livido_property_get( instance, name, 0, &channel ) != LIVIDO_NO_ERROR ) + return; + livido_property_get( channel, "width", 0, w ); + livido_property_get( channel, "height",0, h ); +} + +static int lvd_extract_channel_values( livido_port_t *instance, + const char *pname, + int n, + int *w, + int *h, + uint8_t **pixel_data, + int *palette ) +{ + livido_port_t *c = NULL; + int error = livido_property_get( instance, pname,n, &c ); + if( error != LIVIDO_NO_ERROR ) + return error; + + error = livido_property_get( c, "width", 0,w ); + if( error != LIVIDO_NO_ERROR ) + return error; + error = livido_property_get( c, "height",0,h ); + if( error != LIVIDO_NO_ERROR ) + return error; + error = livido_property_get( c, "current_palette",0, palette ); + if( error != LIVIDO_NO_ERROR ) + return error; + + int i = 0; + for( i = 0; i <4 ; i ++ ) + { + error = livido_property_get( c, "pixel_data", i, &(pixel_data[i])); + if( error != LIVIDO_NO_ERROR ) + return error; + } + return LIVIDO_NO_ERROR; +} + +#endif diff --git a/veejay-current/veejay-client/configure.ac b/veejay-current/veejay-client/configure.ac index 737a59e6..bc94f808 100644 --- a/veejay-current/veejay-client/configure.ac +++ b/veejay-current/veejay-client/configure.ac @@ -1,12 +1,12 @@ dnl Process this file with autoconf to produce a configure script. dnl AC_INIT -AC_INIT([reloaded],[1.5.57],[nwelburg@gmail.com]) +AC_INIT([reloaded],[1.5.58],[nwelburg@gmail.com]) AC_PREREQ(2.57) AC_CONFIG_SRCDIR([src/gveejay.c]) RELOADED_MAJOR_VERSION=1 RELOADED_MINOR_VERSION=5 -RELOADED_MICRO_VERSION=57 +RELOADED_MICRO_VERSION=58 RELOADED_VERSION=$VEEJAY_MAJOR_VERSION.$VEEJAY_MINOR_VERSION.$VEEJAY_MICRO_VERSION RELOADED_CODENAME="Reloaded - build $RELOADED_MAJOR_VERSION $RELOADED_MINOR_VERSION $RELOADED_MICRO_VERSION" AC_CONFIG_HEADERS([config.h]) @@ -634,10 +634,6 @@ if test x"$with_extra_cflags" != "x"; then CXXFLAGS="$CXXFLAGS $with_extra_cflags" fi -reloaded_datadir="${datarootdir}/reloaded" -AC_SUBST(reloaded_datadir) -sh gveejay-paths.sh > gveejay-paths.h - glib_modules="glib-2.0 >= 2.4" PKG_CHECK_MODULES(GLIB, [$glib_modules]) AC_SUBST(GLIB_CFLAGS) @@ -653,6 +649,8 @@ PKG_CHECK_MODULES(GLADE, [$libglade_modules]) AC_SUBST(GLADE_CFLAGS) AC_SUBST(GLADE_LIBS) +reloaded_datadir="${datarootdir}/reloaded" +AC_SUBST(reloaded_datadir) dnl ********************************************************************** dnl Output a Makefile or two and the lib/header descriptor script @@ -664,6 +662,8 @@ gveejay-paths.sh ]) AC_OUTPUT +sh gveejay-paths.sh > gveejay-paths.h + AC_DEFINE(VERSION, ${VERSION}) AC_MSG_NOTICE([]) diff --git a/veejay-current/veejay-client/share/gveejay.reloaded.glade b/veejay-current/veejay-client/share/gveejay.reloaded.glade index c54215ed..118163f8 100644 --- a/veejay-current/veejay-client/share/gveejay.reloaded.glade +++ b/veejay-current/veejay-client/share/gveejay.reloaded.glade @@ -8864,8 +8864,8 @@ YUV (current) - False - False + True + True 0 @@ -12031,7 +12031,7 @@ YUV (current) - True + False True 1 diff --git a/veejay-current/veejay-client/src/callback.c b/veejay-current/veejay-client/src/callback.c index 202a8cc2..e201e52a 100644 --- a/veejay-current/veejay-client/src/callback.c +++ b/veejay-current/veejay-client/src/callback.c @@ -2607,6 +2607,7 @@ void on_sampleadd_clicked(GtkWidget *widget, gpointer user_data) if(filename) { multi_vims( VIMS_EDITLIST_ADD_SAMPLE, "%d %s", 0, filename ); + g_free(filename); } } diff --git a/veejay-current/veejay-client/src/gtkcolorsel.c b/veejay-current/veejay-client/src/gtkcolorsel.c index 90ed430d..cc84e0f8 100644 --- a/veejay-current/veejay-client/src/gtkcolorsel.c +++ b/veejay-current/veejay-client/src/gtkcolorsel.c @@ -1847,7 +1847,14 @@ gtk_color_selection_class_init (GtkColorSelectionClass *klass) P_("The current opacity value (0 fully transparent, 65535 fully opaque)"), 0, 65535, 65535, G_PARAM_READABLE | G_PARAM_WRITABLE)); - + + + gtk_settings_install_property (g_param_spec_string ("gtk-color-selection-palette", + P_("Custom palette"), + P_("Palette to use in the color selector"), + default_colors, + G_PARAM_READWRITE)); + color_selection_signals[COLOR_CHANGED] = g_signal_new ("color_changed", G_OBJECT_CLASS_TYPE (object_class), @@ -1857,11 +1864,6 @@ gtk_color_selection_class_init (GtkColorSelectionClass *klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - gtk_settings_install_property (g_param_spec_string ("gtk-color-selection-palette", - P_("Custom palette"), - P_("Palette to use in the color selector"), - default_colors, - G_PARAM_READWRITE)); } /* widget functions */ diff --git a/veejay-current/veejay-client/src/gveejay.c b/veejay-current/veejay-client/src/gveejay.c index 051b35df..934d89b4 100644 --- a/veejay-current/veejay-client/src/gveejay.c +++ b/veejay-current/veejay-client/src/gveejay.c @@ -42,11 +42,13 @@ static int gveejay_theme = 0; // set to 1 to load with the default reloaded them static int verbosity = 0; static int col = 0; static int row = 0; -static int n_tracks = 4; +static int n_tracks = 7; static int launcher = 0; static int preview = 0; // off static int use_threads = 0; static char midi_file[1024]; +static int beta = 0; +static int auto_connect = 0; static int geom_[2] = { -1 , -1}; static struct { @@ -75,6 +77,8 @@ static void usage(char *progname) printf( "-V\t\tShow version, data directory and exit.\n"); printf( "-m \tMIDI configuration file.\n"); printf( "-g\t\t\tWindow position on screen.\n"); + printf( "-b\t\tEnable beta features.\n"); + printf( "-a\t\tAuto-connect to local running veejays.\n"); printf( "\n\n"); exit(-1); } @@ -100,7 +104,7 @@ static int set_option( const char *name, char *value ) } else if (strcmp(name, "X") == 0 ) { - n_tracks = atoi(optarg); + n_tracks = 1 + atoi(optarg); if( n_tracks < 1 || n_tracks > mt_get_max_tracks() ) n_tracks = 1; } @@ -149,9 +153,15 @@ static int set_option( const char *name, char *value ) err++; } } - else - err++; - return err; + else if (strcmp(name,"b") == 0 || strcmp(name, "beta" ) == 0 ) { + beta = 1; + } + else if (strcmp(name,"a") == 0 ) { + auto_connect = 1; + } + else + err++; + return err; } static volatile gulong g_trap_free_size = 0; static struct timeval time_last_; @@ -216,7 +226,7 @@ int main(int argc, char *argv[]) { // default host to connect to snprintf(hostname,sizeof(hostname), "127.0.0.1"); - while( ( n = getopt( argc, argv, "s:h:p:tnvHf:X:P:Vl:T:m:g:")) != EOF ) + while( ( n = getopt( argc, argv, "s:h:p:tabnvHfX:P:Vl:T:m:g:")) != EOF ) { sprintf(option, "%c", n ); err += set_option( option, optarg); @@ -243,7 +253,7 @@ int main(int argc, char *argv[]) { register_signals(); - vj_gui_init( skins[selected_skin].file, launcher, hostname, port_num, use_threads, load_midi, midi_file ); + vj_gui_init( skins[selected_skin].file, launcher, hostname, port_num, use_threads, load_midi, midi_file,beta,auto_connect); vj_gui_style_setup(); diff --git a/veejay-current/veejay-client/src/multitrack.c b/veejay-current/veejay-client/src/multitrack.c index 3f001eaa..443f7581 100644 --- a/veejay-current/veejay-client/src/multitrack.c +++ b/veejay-current/veejay-client/src/multitrack.c @@ -95,21 +95,29 @@ typedef struct int ph; } multitracker_t; -static volatile int MAX_TRACKS = 2; -static void *parent__ = NULL; +static int MAX_TRACKS = 8; /* MASTER (current) + Track 1 to 6 */ +static void *parent__ = NULL; -static int mt_new_connection_dialog(multitracker_t *mt, char *hostname,int len, int *port_num); -static void add_buttons( sequence_view_t *p, sequence_view_t *seqv , GtkWidget *w); -static void add_buttons2( sequence_view_t *p, sequence_view_t *seqv , GtkWidget *w); +static char *mt_new_connection_dialog(multitracker_t *mt, int *port_num, int *error); +static void add_buttons( sequence_view_t *p, sequence_view_t *seqv , GtkWidget *w); +static void add_buttons2( sequence_view_t *p, sequence_view_t *seqv , GtkWidget *w); static sequence_view_t *new_sequence_view( void *vp, int num ); -static void update_pos( void *data, gint total, gint current ); -static gboolean seqv_mouse_press_event ( GtkWidget *w, GdkEventButton *event, gpointer user_data); +static void update_pos( void *data, gint total, gint current ); +static gboolean seqv_mouse_press_event ( GtkWidget *w, GdkEventButton *event, gpointer user_data); extern GdkPixbuf *vj_gdk_pixbuf_scale_simple( GdkPixbuf *src, int dw, int dh, GdkInterpType inter_type ); extern void gtk_widget_set_size_request__( GtkWidget *w, gint iw, gint h, const char *f, int line ); #define gtk_widget_set_size_request_(a,b,c) gtk_widget_set_size_request(a,b,c) +int mt_set_max_tracks(int mt) +{ + if( mt < 0 || mt > __MAX_TRACKS) + return 0; + MAX_TRACKS = mt; + return 1; +} + int mt_get_max_tracks() { return __MAX_TRACKS; @@ -737,7 +745,7 @@ void *multitrack_sync( void * mt ) return (void*)s; } -static int mt_new_connection_dialog(multitracker_t *mt, char *hostname,int len, int *port_num) +static char *mt_new_connection_dialog(multitracker_t *mt, int *port_num, int *error) { GtkWidget *dialog = gtk_dialog_new_with_buttons( "Connect to a Veejay", @@ -780,15 +788,18 @@ static int mt_new_connection_dialog(multitracker_t *mt, char *hostname,int len, if( res == GTK_RESPONSE_ACCEPT ) { - const gchar *host = gtk_entry_get_text( GTK_ENTRY( text_entry ) ); + const char *host = gtk_entry_get_text( GTK_ENTRY( text_entry ) ); gint port = gtk_spin_button_get_value( GTK_SPIN_BUTTON(num_entry )); - strncpy( hostname, host, len ); *port_num = port; + *error = 0; + return strdup(host); } gtk_widget_destroy( dialog ); - return res; + *error = res; + *port_num = 0; + return NULL; } void *multitrack_new( @@ -802,14 +813,9 @@ void *multitrack_new( gint max_h, GtkWidget *main_preview_area, void *infog, - int threads, - int num_tracks) + int threads) { - multitracker_t *mt = NULL; - - MAX_TRACKS = num_tracks; - - mt = (multitracker_t*) vj_calloc(sizeof(multitracker_t)); + multitracker_t *mt = (multitracker_t*) vj_calloc(sizeof(multitracker_t)); mt->view = (sequence_view_t**) vj_calloc(sizeof(sequence_view_t*) * MAX_TRACKS ); mt->preview = NULL; mt->main_window = win; @@ -852,28 +858,29 @@ int multitrack_add_track( void *data ) { multitracker_t *mt = (multitracker_t*) data; int res = 0; - char *hostname = vj_calloc( 100 ); - int port_num = 0; + int port_num = 0; + int error = 0; - if( mt_new_connection_dialog( mt, hostname, 100, &port_num ) == GTK_RESPONSE_ACCEPT ) + char *hostname = mt_new_connection_dialog( mt,&port_num,&error ); + if( error || hostname == NULL ) { + return res; + } + + int track = 0; + + if( gvr_track_connect( mt->preview, hostname, port_num, &track ) ) { - int track = 0; - - if( gvr_track_connect( mt->preview, hostname, port_num, &track ) ) - { - status_print( mt, "Connection established with veejay runnning on %s port %d", - hostname, port_num ); - if( gveejay_user_preview() ) - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mt->view[track]->toggle), TRUE ); - gtk_widget_set_sensitive_(GTK_WIDGET(mt->view[track]->panel), TRUE ); - gtk_widget_set_sensitive_(GTK_WIDGET(mt->view[track]->toggle), TRUE ); - - res = 1; - } - else - { - status_print( mt, "Unable to open connection with %s : %d", hostname, port_num ); - } + status_print( mt, "Connection established with veejay runnning on %s port %d", hostname, port_num ); + if( gveejay_user_preview() ) + gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mt->view[track]->toggle), TRUE ); + gtk_widget_set_sensitive_(GTK_WIDGET(mt->view[track]->panel), TRUE ); + gtk_widget_set_sensitive_(GTK_WIDGET(mt->view[track]->toggle), TRUE ); + + res = 1; + } + else + { + status_print( mt, "Unable to open connection with %s : %d", hostname, port_num ); } free( hostname ); diff --git a/veejay-current/veejay-client/src/multitrack.h b/veejay-current/veejay-client/src/multitrack.h index e8b04290..8610484e 100644 --- a/veejay-current/veejay-client/src/multitrack.h +++ b/veejay-current/veejay-client/src/multitrack.h @@ -4,55 +4,28 @@ void *multitrack_new( void (*f)(int,char*,int), int (*g)(GdkPixbuf *, GdkPixbuf *, GtkImage *), - GtkWidget *win, - GtkWidget *box, - GtkWidget *msg, - GtkWidget *button, - gint max_w, - gint max_h, - GtkWidget *main_preview_area, - void *gui, - int threads, - int max_tracks); + GtkWidget *win,GtkWidget *box,GtkWidget *msg,GtkWidget *button, + gint max_w,gint max_h, + GtkWidget *main_preview_area,void *gui,int threads); - -void multitrack_set_logo(void *data , GtkWidget *img); - -int multitrack_add_track( void *data ); - -void multitrack_close_track( void *data ); - -int multrack_audoadd( void *data, char *hostname, int port_num ); - -void multitrack_release_track(void *data, int id, int release_this ); - -void multitrack_bind_track( void *data, int id, int bind_this ); - -void multitrack_sync_simple_cmd2( void *data, int vims, int arg ); - - -void *multitrack_sync( void * mt ); - -void multitrack_configure( void *data, float fps, int video_width, int video_height, int *bw, int *bh ); - - -void multitrack_get_preview_dimensions( int w , int h, int *dst_w, int *dst_h ); - -void multitrack_update_sequence_image( void *data , int track, GdkPixbuf *img ); - -int update_multitrack_widgets( void *data, int *array, int track ); - -int multitrack_locked( void *data); - -void multitrack_toggle_preview( void *data, int track_id, int status, GtkWidget *img ); - -void multitrack_set_quality( void *data , int quality ); - -void multitrack_sync_start(void *data); - -void multitrack_sync_simple_cmd( void *data, int vims, int arg ); - -void multitrack_resize( void *m , int w, int h ); +void multitrack_set_logo(void *data , GtkWidget *img); +int multitrack_add_track( void *data ); +void multitrack_close_track( void *data ); +int multrack_audoadd( void *data, char *hostname, int port_num ); +void multitrack_release_track(void *data, int id, int release_this ); +void multitrack_bind_track( void *data, int id, int bind_this ); +void multitrack_sync_simple_cmd2( void *data, int vims, int arg ); +void *multitrack_sync( void * mt ); +void multitrack_configure( void *data, float fps, int video_width, int video_height, int *bw, int *bh ); +void multitrack_get_preview_dimensions( int w , int h, int *dst_w, int *dst_h ); +void multitrack_update_sequence_image( void *data , int track, GdkPixbuf *img ); +int update_multitrack_widgets( void *data, int *array, int track ); +int multitrack_locked( void *data); +void multitrack_toggle_preview( void *data, int track_id, int status, GtkWidget *img ); +void multitrack_set_quality( void *data , int quality ); +void multitrack_sync_start(void *data); +void multitrack_sync_simple_cmd( void *data, int vims, int arg ); +void multitrack_resize( void *m , int w, int h ); #endif diff --git a/veejay-current/veejay-client/src/vj-api.c b/veejay-current/veejay-client/src/vj-api.c index 9a7480a0..52185d1d 100644 --- a/veejay-current/veejay-client/src/vj-api.c +++ b/veejay-current/veejay-client/src/vj-api.c @@ -555,7 +555,6 @@ static GtkWidget *cali_sourcetree = NULL; static GtkListStore *cali_sourcestore = NULL; static GtkTreeModel *cali_sourcemodel = NULL; -static int num_tracks_ = 2; /* global pointer to the editlist-tree */ static GtkWidget *editlist_tree = NULL; static GtkListStore *editlist_store = NULL; @@ -610,6 +609,7 @@ static void setup_tree_text_column( const char *tree_name, int type, const char static void setup_tree_pixmap_column( const char *tree_name, int type, const char *title ); gchar *_utf8str( const char *c_str ); static gchar *recv_vims(int len, int *bytes_written); +static gchar *recv_vims_args(int slen, int *bytes_written, int *arg0, int *arg1); static GdkPixbuf * update_pixmap_kf( int status ); static GdkPixbuf * update_pixmap_entry( int status ); static gboolean @@ -653,6 +653,8 @@ static void indicate_sequence( gboolean active, sequence_gui_slot_t *slot ); static void set_textview_buffer(const char *name, gchar *utf8text); void interrupt_cb(); int get_and_draw_frame(int type, char *wid_name); +GdkPixbuf *vj_gdk_pixbuf_scale_simple( GdkPixbuf *src, int dw, int dh, GdkInterpType inter_type ); + void reset_cali_images( int type, char *wid_name ); GtkWidget *glade_xml_get_widget_( GladeXML *m, const char *name ) @@ -2030,6 +2032,92 @@ void donatenow(); void reportbug(); void update_gui(); + +int veejay_get_sample_image(int id, int type, int wid, int hei) +{ + multi_vims( VIMS_GET_SAMPLE_IMAGE, "%d %d %d %d", id, type, wid, hei ); + uint8_t *data_buffer = (uint8_t*) vj_malloc( sizeof(uint8_t) * wid * hei * 3); + int sample_id = 0; + int sample_type =0; + gint bw = 0; + gchar *data = recv_vims_args( 12, &bw, &sample_id, &sample_type ); + if( data == NULL || bw <= 0 ) + { + veejay_msg(VEEJAY_MSG_WARNING, "Can't get a preview image! Only got %d bytes", bw); + if( data_buffer ) + free(data_buffer); + if( data ) + free(data); + return 0; + } + + int expected_len = (wid * hei); + expected_len += (wid*hei/4); + expected_len += (wid*hei/4); + + if( bw != expected_len ) + { + if(data_buffer) + free(data_buffer); + if( data ) + free(data); + return 0; + } + + uint8_t *in = data; + uint8_t *out = data_buffer; + + VJFrame *src1 = yuv_yuv_template( in, in + (wid * hei), in + (wid * hei) + (wid*hei)/4,wid,hei,PIX_FMT_YUV420P ); + VJFrame *dst1 = yuv_rgb_template( out, wid,hei,PIX_FMT_BGR24 ); + + yuv_convert_any_ac( src1, dst1, src1->format, dst1->format ); + + GdkPixbuf *img = gdk_pixbuf_new_from_data( + out, + GDK_COLORSPACE_RGB, + FALSE, + 8, + wid, + hei, + wid*3, + NULL, + NULL ); + +/* int poke_slot= 0; int bank_page = 0; + verify_bank_capacity( &bank_page , &poke_slot, sample_id, sample_type); + if(bank_page >= 0 ) + { + if( info->sample_banks[bank_page]->slot[poke_slot]->sample_id <= 0 ) + { + sample_slot_t *tmp_slot = create_temporary_slot(poke_slot,sample_id,sample_type, "PREVIEW","00:00:00" ); + add_sample_to_sample_banks(bank_page, tmp_slot ); + free_slot(tmp_slot); + } + } */ + + sample_slot_t *slot = find_slot_by_sample( sample_id, sample_type ); + sample_gui_slot_t *gui_slot = find_gui_slot_by_sample( sample_id, sample_type ); + + if( slot && gui_slot ) + { + slot->pixbuf = vj_gdk_pixbuf_scale_simple(img,wid,hei, GDK_INTERP_NEAREST); + gtk_image_set_from_pixbuf_( GTK_IMAGE( gui_slot->image ), slot->pixbuf ); + g_object_unref( slot->pixbuf ); + } + + free(data_buffer); + free(data); + g_object_unref(img); + + free(src1); + free(dst1); + + + return bw; +} + + + #include "callback.c" enum { @@ -2130,6 +2218,31 @@ static void single_vims(int id) reloaded_schedule_restart(); } +static gchar *recv_vims_args(int slen, int *bytes_written, int *arg0, int *arg1) +{ + int tmp_len = slen+1; + unsigned char tmp[tmp_len]; + veejay_memset(tmp,0,sizeof(tmp)); + int ret = vj_client_read( info->client, V_CMD, tmp, slen ); + if( ret == -1 ) + reloaded_schedule_restart(); + int len = 0; + if( sscanf( (char*)tmp, "%06d", &len ) != 1 ) + return NULL; + if( sscanf( (char*)tmp + 6, "%04d", arg0 ) != 1 ) + return NULL; + if( sscanf( (char*)tmp + 10, "%02d", arg1) != 1 ) + return NULL; + unsigned char *result = NULL; + if( ret <= 0 || len <= 0 || slen <= 0) + return (gchar*)result; + result = (unsigned char*) vj_calloc(sizeof(unsigned char) * (len + 1) ); + *bytes_written = vj_client_read( info->client, V_CMD, result, len ); + if( *bytes_written == -1 ) + reloaded_schedule_restart(); + return (gchar*) result; +} + static gchar *recv_vims(int slen, int *bytes_written) @@ -4232,18 +4345,9 @@ static void load_samplelist_info(gboolean with_reset_slotselection) strncpy( line, fxtext + offset, len ); int values[4] = { 0,0,0,0 }; -#ifdef STRICT_CHECKING - veejay_msg( VEEJAY_MSG_DEBUG, "[%s]", line); - int res = sscanf( line, "%05d%09d%09d%03d", - &values[0], &values[1], &values[2], &values[3]); - veejay_msg(VEEJAY_MSG_DEBUG, - "%d , %d, %d, %d res=%d",values[0],values[1], - values[2],values[3],res ); - assert( res == 4 ); -#else sscanf( line, "%05d%09d%09d%03d", &values[0], &values[1], &values[2], &values[3]); -#endif + strncpy( descr, line + 5 + 9 + 9 + 3 , values[3] ); gchar *title = _utf8str( descr ); gchar *timecode = format_selection_time( 0,(values[2]-values[1]) ); @@ -4258,12 +4362,16 @@ static void load_samplelist_info(gboolean with_reset_slotselection) sample_slot_t *tmp_slot = create_temporary_slot(poke_slot,int_id,0, title,timecode ); add_sample_to_sample_banks(bank_page, tmp_slot ); free_slot(tmp_slot); - n_slots ++; + n_slots ++; + + veejay_get_sample_image( int_id, 0, info->image_dimensions[0], info->image_dimensions[1] ); + } else { - update_sample_slot_data( bank_page, poke_slot, int_id,0,title,timecode); - } + update_sample_slot_data( bank_page, poke_slot, int_id,0,title,timecode); + } + } if( info->status_tokens[CURRENT_ID] == values[0] && info->status_tokens[PLAY_MODE] == 0 ) put_text( "entry_samplename", title ); @@ -5572,7 +5680,7 @@ void find_user_themes(int theme) } else { - veejay_msg(VEEJAY_MSG_WARNING, "%s/%s does not contain a gveejay.rc file", theme_dir,name); + veejay_msg(VEEJAY_MSG_WARNING, "Cannot read %s/%s/gveejay.rc", theme_dir,name); } g_free(test_file); } @@ -6458,12 +6566,13 @@ gui_client_event_signal(GtkWidget *widget, GdkEventClient *event, return FALSE; } -void vj_gui_set_debug_level(int level, int preview_p, int pw, int ph ) +void vj_gui_set_debug_level(int level, int n_tracks, int pw, int ph ) { veejay_set_debug_level( level ); vims_verbosity = level; - num_tracks_ = preview_p; + + mt_set_max_tracks(n_tracks); } int vj_gui_get_preview_priority(void) @@ -6738,7 +6847,7 @@ void vj_gui_set_geom( int x, int y ) geo_pos_[1] = y; } -void vj_gui_init(char *glade_file, int launcher, char *hostname, int port_num, int use_threads, int load_midi , char *midi_file) +void vj_gui_init(char *glade_file, int launcher, char *hostname, int port_num, int use_threads, int load_midi , char *midi_file, int beta, int auto_connect) { int i; char text[100]; @@ -6906,8 +7015,13 @@ void vj_gui_init(char *glade_file, int launcher, char *hostname, int port_num, ph, img_wid, (void*) gui, - use_threads, - num_tracks_); + use_threads); + + if( auto_connect ) { + for( i = 4490; i < 9999; i+= 1000 ) { + multrack_audoadd( gui->mt, "localhost", i); + } + } if( theme_list ) { @@ -6941,6 +7055,11 @@ void vj_gui_init(char *glade_file, int launcher, char *hostname, int port_num, GtkWidget *srtbox = glade_xml_get_widget( info->main_window, "combobox_textsrt"); set_tooltip_by_widget( srtbox, tooltips[TOOLTIP_SRTSELECT].text); + if(!beta) { + GtkWidget *ww = glade_xml_get_widget_( info->main_window, crappy_design[ui_skin_].name ); + GtkWidget *srtpad = gtk_notebook_get_nth_page(GTK_NOTEBOOK(ww),4); + gtk_widget_hide(srtpad); + } update_spin_range( "spin_framedelay", 1, MAX_SLOW, 0); update_spin_range( "spin_samplespeed", -25,25,1); @@ -7507,14 +7626,28 @@ void setup_samplebank(gint num_cols, gint num_rows, GtkWidget *pad, int *idx, in pad, &result ); + result.width -= ( num_rows * 16); result.height -= ( num_cols * 16); + gint image_width = result.width / num_rows; + gint image_height = result.height / num_cols; float ratio = (float) info->el.height / (float) info->el.width; + + // ratio = (float) info->el.width / (float) info->el.height; - gfloat w = image_width; - gfloat h = image_width * ratio; + gfloat w = 0.0f; + gfloat h = 0.0f; + + if( info->el.width > info->el.height ) { + w = image_width; + h = image_width * ratio; + } + else { + w = image_height * ratio; + h = image_height; + } *idx = (int)w; *idy = (int)h; diff --git a/veejay-current/veejay-client/src/vj-api.h b/veejay-current/veejay-client/src/vj-api.h index 48534da3..66ec1852 100644 --- a/veejay-current/veejay-client/src/vj-api.h +++ b/veejay-current/veejay-client/src/vj-api.h @@ -22,7 +22,7 @@ int veejay_tick(); void *get_ui_info(); void vj_gui_set_geom(int x, int y); -void vj_gui_init(char *glade_file, int launcher, char *hostname, int port_num, int threads,int load_midi, char *midi_file); +void vj_gui_init(char *glade_file, int launcher, char *hostname, int port_num, int threads,int load_midi, char *midi_file, int beta, int auto_connect); int vj_gui_reconnect( char *host, char *group, int port); void vj_gui_free(); void vj_fork_or_connect_veejay(); diff --git a/veejay-current/veejay-server/configure.ac b/veejay-current/veejay-server/configure.ac index 6f5af20d..f754558f 100644 --- a/veejay-current/veejay-server/configure.ac +++ b/veejay-current/veejay-server/configure.ac @@ -1,12 +1,12 @@ dnl Process this file with autoconf to produce a configure script. dnl AC_INIT -AC_INIT([veejay],[1.5.57],[http://www.veejayhq.net]) +AC_INIT([veejay],[1.5.58],[http://www.veejayhq.net]) AC_PREREQ(2.57) AC_CONFIG_SRCDIR([veejay/veejay.c]) VEEJAY_MAJOR_VERSION=1 VEEJAY_MINOR_VERSION=5 -VEEJAY_MICRO_VERSION=57 +VEEJAY_MICRO_VERSION=58 VEEJAY_VERSION=$VEEJAY_MAJOR_VERSION.$VEEJAY_MINOR_VERSION.$VEEJAY_MICRO_VERSION VEEJAY_CODENAME="Veejay Classic - build $VEEJAY_MINOR_VERSION $VEEJAY_MICRO_VERSION" AC_CONFIG_HEADERS([config.h]) @@ -107,10 +107,6 @@ AC_ARG_WITH(jpeg-mmx, AC_ARG_WITH(v4l2, AC_HELP_STRING([--without-v4l2],[Do not use Video4Linux]), [], [with_v4l2=yes]) -AC_ARG_WITH(libresample, - AC_HELP_STRING([--without-libresample], [Do not use libresample.]), - [], [with_libresample=yes]) - arch_target="auto" AC_ARG_WITH(arch-target, AS_HELP_STRING( [--with-arch-target=generic or auto], [Build a generic binary or auto-detect current cpu type (defaults to auto-detect)]), @@ -794,17 +790,6 @@ if test x$have_pixbuf != xtrue ; then AC_MSG_ERROR([Cannot find the gtk-2.0-dev / gdk pixbuf library.]) fi - -dnl FIXME check for libdv see issue 12 -have_libresample=true -if test x$with_libresample != xno ; then - have_libresample=false -fi - -if test x$have_libresample != xtrue ; then - AC_DEFINE(HAVE_LIBRESAMPLE,1,[use libresample]) -fi - dnl ********************************************************************* dnl Check for libdv dnl (creates LIBDV_CFLAGS, LIBDV_LIBS; defines HAVE_LIBDV) @@ -1136,6 +1121,7 @@ thirdparty/bio2jack/Makefile thirdparty/libhash/Makefile thirdparty/liblzo/Makefile thirdparty/libOSC/Makefile +thirdparty/libresample/Makefile libvjmsg/Makefile libvevo/Makefile libvjmem/Makefile diff --git a/veejay-current/veejay-server/libplugger/livido-loader.c b/veejay-current/veejay-server/libplugger/livido-loader.c index dee4443c..6acd5f2f 100644 --- a/veejay-current/veejay-server/libplugger/livido-loader.c +++ b/veejay-current/veejay-server/libplugger/livido-loader.c @@ -863,12 +863,16 @@ void *livido_plug_init(void *plugin,int w, int h, int base_fmt_ ) { shmid = vj_shm_get_id(); //@ put in HOST value vevo_property_set( filter_instance,"HOST_shmid", VEVO_ATOM_TYPE_INT,1,&shmid ); - veejay_msg( VEEJAY_MSG_INFO, "Told plugin my Shared Memory ID"); + veejay_msg( VEEJAY_MSG_INFO, "Hooking up plugin to shared resource %d", shmid); } if( (*init_f)( (livido_port_t*) filter_instance ) != LIVIDO_NO_ERROR ) { - veejay_msg(0, "Error while initializing Livido filter"); livido_port_recursive_free( filter_instance ); + + char *plugin_name = get_str_vevo( filter_templ, "name" ); + veejay_msg(VEEJAY_MSG_WARNING, "Unable to initialize LiViDO plugin '%s'", plugin_name); + if(plugin_name) + free(plugin_name); return NULL; } @@ -1263,6 +1267,7 @@ void* deal_with_livido( void *handle, const char *name, int w, int h ) if( compiled_as < LIVIDO_API_VERSION ) { veejay_msg(VEEJAY_MSG_WARNING, "I am using a newer LiViDO API. Overwrite your livido.h from libplugger/specs/livido.h and recompile your plugins."); + veejay_msg(VEEJAY_MSG_ERROR, "Plugin %s was compiled for LiViDO-%d, current is %d", plugin_name,compiled_as, LIVIDO_API_VERSION ); free(plugin_name); return NULL; } diff --git a/veejay-current/veejay-server/libplugger/plugload.c b/veejay-current/veejay-server/libplugger/plugload.c index 88080359..da73553e 100644 --- a/veejay-current/veejay-server/libplugger/plugload.c +++ b/veejay-current/veejay-server/libplugger/plugload.c @@ -199,14 +199,12 @@ static int add_to_plugin_list( const char *path ) if(!handle) { - veejay_msg(0,"Plugin '%s' error '%s'", fullname, - dlerror() ); + veejay_msg(0,"Plugin '%s' error '%s'", fullname, dlerror() ); continue; } char *bname = basename( fullname ); char *basename = vj_strdup( bname ); void *plugin = NULL; - veejay_msg(VEEJAY_MSG_DEBUG, "Loading %s",fullname ); if(dlsym( handle, "plugMain" ) && sizeof(long) == 4) { @@ -241,7 +239,7 @@ static int add_to_plugin_list( const char *path ) dlclose(handle); } else{ dlclose(handle); - veejay_msg(VEEJAY_MSG_DEBUG, "%s is not compatible.", fullname ); + veejay_msg(VEEJAY_MSG_DEBUG, "Incompatible plugin %s skipped", fullname ); } if( plugin ) { @@ -545,21 +543,16 @@ int plug_sys_detect_plugins(void) //@ For every time there is a void* passed as int a gremlin will be happy if( sizeof(long) == 4 ) { if( n_ff_ > 0 ) { - veejay_msg(VEEJAY_MSG_INFO, "FreeFrame - cross-platform real-time video effects (http://freeframe.sourceforge.net)"); - veejay_msg(VEEJAY_MSG_INFO, " found %d FreeFrame %s", n_ff_ , n_ff_ == 1 ? "plugin" : "plugins" ); + veejay_msg(VEEJAY_MSG_INFO, "FreeFrame - %d plugins # cross-platform real-time video effects (http://freeframe.sourceforge.net)", n_ff_); } } if( n_fr_ > 0 ) { - veejay_msg(VEEJAY_MSG_INFO, "frei0r - a minimalistic plugin API for video effects (http://www.piksel.org/frei0r)"); - veejay_msg(VEEJAY_MSG_INFO, " found %d frei0r %s", - n_fr_ , n_fr_ == 1 ? "plugin" : "plugins" ); + veejay_msg(VEEJAY_MSG_INFO, "frei0r - %d plugins # a minimalistic plugin API for video effects (http://www.piksel.org/frei0r)", n_fr_); } if( n_lvd_ > 0 ) { - veejay_msg(VEEJAY_MSG_INFO, "Livido - (Linux) Video Dynamic Objects" ); - veejay_msg(VEEJAY_MSG_INFO, " found %d Livido %s", - n_lvd_, n_lvd_ == 1 ? "plugin" :"plugins" ); + veejay_msg(VEEJAY_MSG_INFO, "Livido - %d plugins # (Linux) Video Dynamic Objects",n_lvd_ ); } plug_print_all(); @@ -800,7 +793,9 @@ void *plug_activate( int fx_id ) void *instance = instantiate_plugin( index_map_[fx_id], base_width_,base_height_); if( instance == NULL ) { - veejay_msg(0, "Error instantiating plugin."); + char *plugname = plug_get_name( fx_id ); + veejay_msg(VEEJAY_MSG_DEBUG, "Instantiating plugin '%s' failed due to an error", plugname); + if(plugname) free(plugname); return NULL; } return instance; @@ -839,7 +834,7 @@ void plug_print_all() { int n; int x=0; - for(n = 0; n < index_ ; n ++ ) + /*for(n = 0; n < index_ ; n ++ ) { char *fx_name = plug_get_name(n); if(fx_name) @@ -851,9 +846,12 @@ void plug_print_all() } if( x < n ) { - veejay_msg(VEEJAY_MSG_INFO, "Loaded %d/%d plugins", x,n ); + veejay_msg(VEEJAY_DEBUG_INFO, "Loaded %d/%d plugins", x,n ); } - veejay_msg(VEEJAY_MSG_INFO, "Loaded %d plugins in total",n); + */ + + veejay_msg(VEEJAY_MSG_INFO, "FX engine ready. Loaded %d plugins and %d built-ins (%d in total)", + n,vj_effect_max_effects(),vj_effect_max_effects()+n); } diff --git a/veejay-current/veejay-server/libstream/vj-net.c b/veejay-current/veejay-server/libstream/vj-net.c index b9967a01..b38b8ba5 100644 --- a/veejay-current/veejay-server/libstream/vj-net.c +++ b/veejay-current/veejay-server/libstream/vj-net.c @@ -81,13 +81,20 @@ static void net_delay(long ms, long sec ) clock_nanosleep( CLOCK_REALTIME,0, &ts, NULL ); } +static int my_screen_id = -1; +void net_set_screen_id(int id) +{ + my_screen_id = id; + veejay_msg(VEEJAY_MSG_DEBUG,"Network stream bound to screen %d", id ); +} + void *reader_thread(void *data) { vj_tag *tag = (vj_tag*) data; threaded_t *t = tag->priv; char buf[16]; - snprintf(buf,sizeof(buf)-1, "%03d:;", VIMS_GET_FRAME); + snprintf(buf,sizeof(buf)-1, "%03d:%d;", VIMS_GET_FRAME, my_screen_id); int retrieve = 0; int success = 0; @@ -299,9 +306,13 @@ int net_thread_get_frame( vj_tag *tag, uint8_t *buffer[3] ) if( PIX_FMT_YUV420P == t->in_fmt || PIX_FMT_YUVJ420P == t->in_fmt ) buvlen = b_len/4; - else + else if ( PIX_FMT_YUV444P == t->in_fmt || PIX_FMT_YUVJ444P == t->in_fmt ) { + buvlen = b_len; + } + else { buvlen = b_len/2; - + } + if( t->a == NULL ) t->a = yuv_yuv_template( t->buf, t->buf + b_len, t->buf+ b_len+ buvlen,t->in_w,t->in_h, t->in_fmt); diff --git a/veejay-current/veejay-server/libstream/vj-net.h b/veejay-current/veejay-server/libstream/vj-net.h index fe4c7831..dd1f54fd 100644 --- a/veejay-current/veejay-server/libstream/vj-net.h +++ b/veejay-current/veejay-server/libstream/vj-net.h @@ -27,5 +27,5 @@ void net_thread_remote(void *priv, void *p ); int net_thread_get_frame( vj_tag *tag, uint8_t *buffer[3]); void net_thread_exit(vj_tag *tag); void *net_threader(VJFrame *frame); - +void net_set_screen_id(int id); #endif diff --git a/veejay-current/veejay-server/libstream/vj-tag.c b/veejay-current/veejay-server/libstream/vj-tag.c index b51b04a7..3a895c1d 100644 --- a/veejay-current/veejay-server/libstream/vj-tag.c +++ b/veejay-current/veejay-server/libstream/vj-tag.c @@ -1054,7 +1054,6 @@ int _vj_tag_new_unicap( vj_tag * tag, int stream_nr, int width, int height, int strcpy( tag->source_name, filename ); } else { - veejay_msg(VEEJAY_MSG_ERROR, "Failed to initialize generator '%s'",filename); free(tag->source_name); free(tag); return -1; diff --git a/veejay-current/veejay-server/libvje/effects/chromascratcher.c b/veejay-current/veejay-server/libvje/effects/chromascratcher.c index 89a974a3..fa89166c 100644 --- a/veejay-current/veejay-server/libvje/effects/chromascratcher.c +++ b/veejay-current/veejay-server/libvje/effects/chromascratcher.c @@ -88,10 +88,6 @@ void chromascratcher_free() { void chromastore_frame(VJFrame *src, int w, int h, int n, int no_reverse) { int strides[4] = { (w * h), (w*h), (w*h) , 0 }; - uint8_t *Y = src->data[0]; - uint8_t *Cb= src->data[1]; - uint8_t *Cr= src->data[2]; - uint8_t *dest[4] = { cframe[0] + (w*h*cnframe), cframe[1] + (w*h*cnframe), diff --git a/veejay-current/veejay-server/libvje/effects/complexsync.c b/veejay-current/veejay-server/libvje/effects/complexsync.c index 900855a4..8d3d7dc0 100644 --- a/veejay-current/veejay-server/libvje/effects/complexsync.c +++ b/veejay-current/veejay-server/libvje/effects/complexsync.c @@ -71,23 +71,18 @@ void complexsync_free() { void complexsync_apply(VJFrame *frame, VJFrame *frame2, int width, int height, int val) { - const int len = frame->len; uint8_t *Y = frame->data[0]; uint8_t *Cb = frame->data[1]; uint8_t *Cr = frame->data[2]; int region = width * val; - - int strides[4] = { region, region, region, 0 }; int planes[4] = { len, len, len, 0 }; - int i; - vj_frame_copy( frame->data, c_outofsync_buffer, planes ); vj_frame_copy( frame2->data, frame->data, planes ); - if( (len - region) > 0) + if( (len - region) > 0) { uint8_t *dest[4] = { Y + region, Cb + region, Cr + region, NULL }; int dst_strides[4] = { len - region, len - region, len - region,0 }; diff --git a/veejay-current/veejay-server/libvje/effects/keyselect.c b/veejay-current/veejay-server/libvje/effects/keyselect.c index bae3058f..b9747390 100644 --- a/veejay-current/veejay-server/libvje/effects/keyselect.c +++ b/veejay-current/veejay-server/libvje/effects/keyselect.c @@ -141,9 +141,8 @@ void keyselect_apply( VJFrame *frame, VJFrame *frame2, int width, int height, int i_angle, int r, int g, int b, int mode, int i_noise) { - - uint8_t *fg_y, *fg_cb, *fg_cr; - uint8_t *bg_y; + uint8_t *fg_y, *fg_cb, *fg_cr; + uint8_t *bg_y, *bg_cb, *bg_cr; int accept_angle_tg, accept_angle_ctg, one_over_kc; int kfgy_scale, kg; int cb, cr; @@ -157,8 +156,7 @@ void keyselect_apply( VJFrame *frame, VJFrame *frame2, int width, uint8_t *Cb= frame->data[1]; uint8_t *Cr= frame->data[2]; uint8_t *Y2 = frame2->data[0]; - uint8_t *Cb2= frame2->data[1]; - uint8_t *Cr2= frame2->data[2]; + int iy=pixel_Y_lo_,iu=128,iv=128; _rgb2yuv( r,g,b, iy,iu,iv ); _y = (float) iy; @@ -185,7 +183,9 @@ void keyselect_apply( VJFrame *frame, VJFrame *frame2, int width, fg_cb = Cb; fg_cr = Cr; /* 2005: swap these !! */ - bg_y = Y2; + bg_y = frame2->data[0]; + bg_cb = frame2->data[1]; + bg_cr = frame2->data[2]; for (pos = (width * height); pos != 0; pos--) { short xx, yy; @@ -226,10 +226,14 @@ void keyselect_apply( VJFrame *frame, VJFrame *frame2, int width, val = (yy * yy) + (kg * kg); if (val < (noise_level * noise_level)) { - kbg = 255; + kbg = 255; } - val = (Y[pos] + (kbg * bg_y[pos])) >> 8; - Y[pos] = blend_pixel( val, fg_y[pos] ); + + val = (Y[pos] + (kbg * bg_y[pos])) >> 8; + + Y[pos] = blend_pixel( val, fg_y[pos] ); + Cb[pos] = (Cb[pos] + (kbg * bg_cb[pos])) >> 8; + Cr[pos] = (Cr[pos] + (kbg * bg_cr[pos])) >> 8; } } diff --git a/veejay-current/veejay-server/libvje/effects/lumakey.c b/veejay-current/veejay-server/libvje/effects/lumakey.c index f052deb5..7e287acc 100644 --- a/veejay-current/veejay-server/libvje/effects/lumakey.c +++ b/veejay-current/veejay-server/libvje/effects/lumakey.c @@ -102,14 +102,14 @@ void lumakey_smooth(uint8_t * yuv1[3], uint8_t * yuv2[3], int width, uint8_t a1, a2; unsigned int op0, op1; uint8_t Y, Cb, Cr; - unsigned int soft0, soft1; + // unsigned int soft0, soft1; unsigned int t2, t3; uint8_t p1, p2; op1 = (opacity > 255) ? 255 : opacity; op0 = 255 - op1; - soft0 = 255 / distance; - soft1 = 255 - soft0; +// soft0 = 255 / distance; +// soft1 = 255 - soft0; t2 = threshold - distance; // 0 - 4 t3 = threshold2 + distance; // 3 + 4 @@ -222,13 +222,13 @@ void lumakey_smooth_white(uint8_t * yuv1[3], uint8_t * yuv2[3], int width, uint8_t a1, a2; unsigned int op0, op1; uint8_t Y, Cb, Cr; - unsigned int soft0, soft1; +// unsigned int soft0, soft1; unsigned int t2, t3; op1 = (opacity > 255) ? 255 : opacity; op0 = 255 - op1; - soft0 = 255 / distance; - soft1 = 255 - soft0; +// soft0 = 255 / distance; +// soft1 = 255 - soft0; t2 = threshold - distance; t3 = threshold2 + distance; diff --git a/veejay-current/veejay-server/libvje/effects/photoplay.c b/veejay-current/veejay-server/libvje/effects/photoplay.c index a617fe82..84e6e336 100644 --- a/veejay-current/veejay-server/libvje/effects/photoplay.c +++ b/veejay-current/veejay-server/libvje/effects/photoplay.c @@ -38,7 +38,7 @@ vj_effect *photoplay_init(int w, int h) ve->limits[0][2] = 0; ve->limits[1][2] = 3; // mode ve->defaults[0] = 2; - ve->defaults[1] = 1; + ve->defaults[1] = 2; // higher value takes less cpu ve->defaults[2] = 1; ve->description = "Photoplay (timestretched mosaic)"; ve->sub_format = 1; @@ -154,10 +154,10 @@ static void take_photo( uint8_t *plane, uint8_t *dst_plane, int w, int h, int in } } // still problem here! - if(sum > 0) + // if(sum > 0) dst_plane[(dst_y*box_width)+dst_x] = sum / (step_y*step_x); - else - dst_plane[(dst_y*box_width)+dst_x] = pixel_Y_lo_; + // else + // dst_plane[(dst_y*box_width)+dst_x] = pixel_Y_lo_; dst_x++; } diff --git a/veejay-current/veejay-server/libvje/effects/rgbkey.c b/veejay-current/veejay-server/libvje/effects/rgbkey.c index 66f9da61..3daa89c3 100644 --- a/veejay-current/veejay-server/libvje/effects/rgbkey.c +++ b/veejay-current/veejay-server/libvje/effects/rgbkey.c @@ -219,7 +219,7 @@ void rgbkey_apply2(VJFrame *frame, VJFrame *frame2, int width, uint8_t *Cb= frame->data[1]; uint8_t *Cr= frame->data[2]; uint8_t *Y2 = frame2->data[0]; - int8_t *Cb2= frame2->data[1]; + uint8_t *Cb2= frame2->data[1]; uint8_t *Cr2= frame2->data[2]; uint8_t iy,iu,iv; diff --git a/veejay-current/veejay-server/libvje/effects/scratcher.c b/veejay-current/veejay-server/libvje/effects/scratcher.c index c43097b3..9398c8b1 100644 --- a/veejay-current/veejay-server/libvje/effects/scratcher.c +++ b/veejay-current/veejay-server/libvje/effects/scratcher.c @@ -88,9 +88,6 @@ void store_frame(VJFrame *src, int w, int h, int n, int no_reverse) { int uv_len = src->uv_len; int strides[4] = { (w * h), uv_len, uv_len , 0 }; - uint8_t *Y = src->data[0]; - uint8_t *Cb= src->data[1]; - uint8_t *Cr= src->data[2]; uint8_t *dest[4] = { frame[0] + (w*h*nframe), @@ -132,7 +129,6 @@ void scratcher_apply(VJFrame *src, { unsigned int len = src->len; - unsigned int op1 = (opacity > 255) ? 255 : opacity; int offset = len * nframe; int uv_len = src->uv_len; int uv_offset = uv_len * nframe; diff --git a/veejay-current/veejay-server/libvjnet/vj-server.c b/veejay-current/veejay-server/libvjnet/vj-server.c index 7f33b468..5eb2188a 100644 --- a/veejay-current/veejay-server/libvjnet/vj-server.c +++ b/veejay-current/veejay-server/libvjnet/vj-server.c @@ -63,6 +63,8 @@ typedef struct int type; } vj_proto; +static int default_timeout_sec = 10; + /* Message buffer is 4 MB per client per frame tick, this should be large enough to hold most KF packets */ #define VJ_MAX_PENDING_MSG 4096 @@ -295,6 +297,20 @@ static int _vj_server_classic(vj_server *vjs, int port_offset) return 0; } + struct timeval timeout; + timeout.tv_sec = default_timeout_sec; + timeout.tv_usec = 0; + + if( setsockopt( vjs->handle, SOL_SOCKET, SO_RCVTIMEO, (char*) &timeout, sizeof(timeout) ) == -1) + { + veejay_msg(0, "Cannot set receive timeout"); + } + + if( setsockopt( vjs->handle, SOL_SOCKET, SO_SNDTIMEO, (char*) &timeout, sizeof(timeout) ) == -1) + { + veejay_msg(0,"Cannot set send timeout"); + } + link = (vj_link **) vj_malloc(sizeof(vj_link *) * VJ_MAX_CONNECTIONS); if(!link) { @@ -399,6 +415,18 @@ vj_server *vj_server_alloc(int port_offset, char *mcast_group_name, int type, si veejay_msg(VEEJAY_MSG_DEBUG, "env VEEJAY_LOG_NET_IO=logfile not set"); } + char *timeout = getenv("VEEJAY_NET_TIMEOUT"); + if(timeout != NULL ) { + default_timeout_sec = atoi(timeout); + if( default_timeout_sec < 0 || default_timeout_sec > 65535 ) { + veejay_msg(VEEJAY_MSG_ERROR, "env VEEJAY_NET_TIMEOUT value must be between 0 and 65535" ); + default_timeout_sec = 10; + } + } + else { + veejay_msg(VEEJAY_MSG_DEBUG,"env VEEJAY_NET_TIMEOUT=seconds not set"); + } + if( mcast_group_name != NULL ) { /* setup multicast socket */ vjs->use_mcast = 1; diff --git a/veejay-current/veejay-server/libyuv/yuvconv.c b/veejay-current/veejay-server/libyuv/yuvconv.c index 5bf45e37..e4631ef2 100644 --- a/veejay-current/veejay-server/libyuv/yuvconv.c +++ b/veejay-current/veejay-server/libyuv/yuvconv.c @@ -1094,11 +1094,7 @@ void* yuv_init_swscaler(VJFrame *src, VJFrame *dst, sws_template *tmpl, int cpu_ if(s)free(s); return NULL; } - else - { - veejay_msg(VEEJAY_MSG_DEBUG, "sws context: %dx%d in %d -> %dx%d in %d", - src->width,src->height,src->format, dst->width,dst->height,dst->format ); - } + return ((void*)s); } diff --git a/veejay-current/veejay-server/livido-plugins/Makefile.am b/veejay-current/veejay-server/livido-plugins/Makefile.am index 1f0d285e..f24f88a7 100644 --- a/veejay-current/veejay-server/livido-plugins/Makefile.am +++ b/veejay-current/veejay-server/livido-plugins/Makefile.am @@ -1,7 +1,7 @@ lividoplugin_LTLIBRARIES = lvd_solid.la \ lvd_colortone.la \ lvd_displaywall.la \ - lvd_stroboscope.la + lvd_stroboscope.la lvd_solid_la_SOURCES = lvd_solid.c lvd_colortone_la_SOURCES = lvd_colortone.c diff --git a/veejay-current/veejay-server/man/veejay.1 b/veejay-current/veejay-server/man/veejay.1 index 8daf3d4e..8506b667 100644 --- a/veejay-current/veejay-server/man/veejay.1 +++ b/veejay-current/veejay-server/man/veejay.1 @@ -225,11 +225,14 @@ Delay key repeat in ms .B VEEJAY_FULLSCREEN Fullscreen (1) or windowed (0) mode .TP -.B VEEJAY_SCREEN_GEOMETRY -Specifiy a geometry for veejay to position the video window. Use this feature to specificy where a video window appears in TwinView or One Big Desktop +.B VEEJAY_DESKTOP_GEOMETRY +Specifiy the desktop geometry for veejay to position the video window. Use this feature to specificy where a video window appears in TwinView or One Big Desktop .TP -.B VEEJAY_SCREEN_SIZE -Specifiy the size of the video window. +.B VEEJAY_VIDEO_SIZE +Specifiy the size of the video window (inside VEEJAY_DESKTOP_GEOMETRY) +.TP +.B VEEJAY_VIDEO_POSITION +Specificy the position of the video window (inside VEEJAY_DESKTOP_GEOMETRY) .TP .B VEEJAY_DEFAULT_CHANNEL Specify the default video4linux channel id @@ -244,10 +247,10 @@ MMap size per loaded video file Set this to "CLASSIC" if you want to startup in low resolution .B Examples .TP -.B VEEJAY_SCREEN_GEOMETRY=2624x1024+1600x0 -The video window will be displayed on the second screen, first screen is 1600 pixels wide. Specify this and VEEJAY_SCREEN_SIZE to create a borderless video window for use on one of your monitors in TwinView or One Big Desktop mode. +.B VEEJAY_DESKTOP_GEOMETRY=2624x1024+1600x0 +The video window will be displayed on the second screen, first screen is 1600 pixels wide. Specify this and VEEJAY_VIDEO_SIZE to create a borderless video window for use on one of your monitors in TwinView or One Big Desktop mode. .TP -.B VEEJAY_SCREEN_SIZE=1024x768 +.B VEEJAY_VIDEO_SIZE=1024x768 The second screen is 1024x768, the video window will appear fullscreen .TP .B VEEJAY_DEFAULT_CHANNEL diff --git a/veejay-current/veejay-server/test/startup/veejay.env.bash b/veejay-current/veejay-server/test/startup/veejay.env.bash index 0574fa29..56b9e103 100644 --- a/veejay-current/veejay-server/test/startup/veejay.env.bash +++ b/veejay-current/veejay-server/test/startup/veejay.env.bash @@ -11,8 +11,9 @@ export SDL_VIDEO_HWACCEL=1 # setup video window on secundary monitor (twinview desktop) # desktop=2526x1024, second screen starts at 1600, size is 1024x768 -export VEEJAY_SCREEN_GEOMETRY=2624x1024+1600x0 -export VEEJAY_SCREEN_SIZE=1024x768 +export VEEJAY_DESKTOP_GEOMETRY=2624x1024+1600x0 +export VEEJAY_VIDEO_SIZE=1024x768 +export VEEJAY_VIDEO_POSITION=0x0 # highest possible quest export VEEJAY_PERFORMANCE=quality diff --git a/veejay-current/veejay-server/thirdparty/Makefile.am b/veejay-current/veejay-server/thirdparty/Makefile.am index 39b8c10f..952e0cdb 100644 --- a/veejay-current/veejay-server/thirdparty/Makefile.am +++ b/veejay-current/veejay-server/thirdparty/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = aclib bio2jack libhash liblzo libOSC +SUBDIRS = aclib bio2jack libhash liblzo libOSC libresample if !HAVE_MJPEGTOOLS SUBDIRS += mjpegtools diff --git a/veejay-current/veejay-server/thirdparty/libresample/Makefile.am b/veejay-current/veejay-server/thirdparty/libresample/Makefile.am new file mode 100644 index 00000000..84ea55b5 --- /dev/null +++ b/veejay-current/veejay-server/thirdparty/libresample/Makefile.am @@ -0,0 +1,13 @@ +# Makefile for veejay +MAINTAINERCLEANFILES = Makefile.in +AM_CFLAGS = $(OP_CFLAGS) + +AM_CPPFLAGS = -I$(top_srcdir) -I$(includedir) \ + -I$(top_srcdir)/thirdparty \ + -I$(top_srcdir)/vjmem \ + -I$(top_srcdir)/vjmsg + +RESAMPLE_LIB_FILE = libresample.la +noinst_LTLIBRARIES = $(RESAMPLE_LIB_FILE) +libresample_la_SOURCES = audioconvert.c resample.c resample2.c +EXTRA_DIST= diff --git a/veejay-current/veejay-server/thirdparty/libresample/audioconvert.c b/veejay-current/veejay-server/thirdparty/libresample/audioconvert.c new file mode 100644 index 00000000..e71e912c --- /dev/null +++ b/veejay-current/veejay-server/thirdparty/libresample/audioconvert.c @@ -0,0 +1,116 @@ +/* + * audio conversion + * Copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * audio conversion + * @author Michael Niedermayer + */ + +#include +#include +#include +#include +#include + +struct AVAudioConvert { + int in_channels, out_channels; + int fmt_pair; +}; + +AVAudioConvert *av_audio_convert_alloc(enum AVSampleFormat out_fmt, int out_channels, + enum AVSampleFormat in_fmt, int in_channels, + const float *matrix, int flags) +{ + AVAudioConvert *ctx; + if (in_channels!=out_channels) + return NULL; /* FIXME: not supported */ + ctx = av_malloc(sizeof(AVAudioConvert)); + if (!ctx) + return NULL; + ctx->in_channels = in_channels; + ctx->out_channels = out_channels; + ctx->fmt_pair = out_fmt + AV_SAMPLE_FMT_NB*in_fmt; + return ctx; +} + +void av_audio_convert_free(AVAudioConvert *ctx) +{ + av_free(ctx); +} + +int av_audio_convert(AVAudioConvert *ctx, + void * const out[6], const int out_stride[6], + const void * const in[6], const int in_stride[6], int len) +{ + int ch; + + //FIXME optimize common cases + + for(ch=0; chout_channels; ch++){ + const int is= in_stride[ch]; + const int os= out_stride[ch]; + const uint8_t *pi= in[ch]; + uint8_t *po= out[ch]; + uint8_t *end= po + os*len; + if(!out[ch]) + continue; + +#define CONV(ofmt, otype, ifmt, expr)\ +if(ctx->fmt_pair == ofmt + AV_SAMPLE_FMT_NB*ifmt){\ + do{\ + *(otype*)po = expr; pi += is; po += os;\ + }while(po < end);\ +} + +//FIXME put things below under ifdefs so we do not waste space for cases no codec will need +//FIXME rounding ? + + CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_U8 , *(const uint8_t*)pi) + else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<8) + else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<24) + else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7))) + else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7))) + else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80) + else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi) + else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi<<16) + else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15))) + else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15))) + else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S32, (*(const int32_t*)pi>>24) + 0x80) + else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi>>16) + else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi) + else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1U<<31))) + else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1U<<31))) + else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8( lrintf(*(const float*)pi * (1<<7)) + 0x80)) + else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16( lrintf(*(const float*)pi * (1<<15)))) + else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float*)pi * (1U<<31)))) + else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_FLT, *(const float*)pi) + else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_FLT, *(const float*)pi) + else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8( lrint(*(const double*)pi * (1<<7)) + 0x80)) + else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16( lrint(*(const double*)pi * (1<<15)))) + else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double*)pi * (1U<<31)))) + else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_DBL, *(const double*)pi) + else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_DBL, *(const double*)pi) + else return -1; + } + return 0; +} + diff --git a/veejay-current/veejay-server/thirdparty/libresample/audioconvert.h b/veejay-current/veejay-server/thirdparty/libresample/audioconvert.h new file mode 100644 index 00000000..4b2c6d2b --- /dev/null +++ b/veejay-current/veejay-server/thirdparty/libresample/audioconvert.h @@ -0,0 +1,77 @@ +/* + * audio conversion + * Copyright (c) 2006 Michael Niedermayer + * Copyright (c) 2008 Peter Ross + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AUDIOCONVERT_H +#define AVCODEC_AUDIOCONVERT_H + +/** + * @file + * Audio format conversion routines + * This interface is deprecated and will be dropped in a future + * version. You should use the libswresample library instead. + */ + +#include +#include +#include + +struct AVAudioConvert; +typedef struct AVAudioConvert AVAudioConvert; + +/** + * Create an audio sample format converter context + * @param out_fmt Output sample format + * @param out_channels Number of output channels + * @param in_fmt Input sample format + * @param in_channels Number of input channels + * @param[in] matrix Channel mixing matrix (of dimension in_channel*out_channels). Set to NULL to ignore. + * @param flags See AV_CPU_FLAG_xx + * @return NULL on error + * @deprecated See libswresample + */ + +AVAudioConvert *av_audio_convert_alloc(enum AVSampleFormat out_fmt, int out_channels, + enum AVSampleFormat in_fmt, int in_channels, + const float *matrix, int flags); + +/** + * Free audio sample format converter context + * @deprecated See libswresample + */ + +void av_audio_convert_free(AVAudioConvert *ctx); + +/** + * Convert between audio sample formats + * @param[in] out array of output buffers for each channel. set to NULL to ignore processing of the given channel. + * @param[in] out_stride distance between consecutive output samples (measured in bytes) + * @param[in] in array of input buffers for each channel + * @param[in] in_stride distance between consecutive input samples (measured in bytes) + * @param len length of audio frame size (measured in samples) + * @deprecated See libswresample + */ + +int av_audio_convert(AVAudioConvert *ctx, + void * const out[6], const int out_stride[6], + const void * const in[6], const int in_stride[6], int len); + +#endif /* AVCODEC_AUDIOCONVERT_H */ diff --git a/veejay-current/veejay-server/thirdparty/libresample/common.h b/veejay-current/veejay-server/thirdparty/libresample/common.h new file mode 100644 index 00000000..3e17f99f --- /dev/null +++ b/veejay-current/veejay-server/thirdparty/libresample/common.h @@ -0,0 +1,8 @@ +#ifndef RESAMPLE_STRUCT +#define RESAMPLE_STRUCT +struct ReSampleContext; +struct AVResampleContext; + +typedef struct ReSampleContext ReSampleContext; +#endif + diff --git a/veejay-current/veejay-server/thirdparty/libresample/resample.c b/veejay-current/veejay-server/thirdparty/libresample/resample.c new file mode 100644 index 00000000..4fa51b95 --- /dev/null +++ b/veejay-current/veejay-server/thirdparty/libresample/resample.c @@ -0,0 +1,465 @@ +/* + * samplerate conversion for both audio and video + * Copyright (c) 2000 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * samplerate conversion for both audio and video + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#define MAX_CHANNELS 8 + +struct AVResampleContext; + +static const char *context_to_name(void *ptr) +{ + return "audioresample"; +} + +static const AVOption options[] = {{NULL}}; +static const AVClass audioresample_context_class = { + "ReSampleContext", context_to_name, options, LIBAVUTIL_VERSION_INT +}; + +struct ReSampleContext { + struct AVResampleContext *resample_context; + short *temp[MAX_CHANNELS]; + int temp_len; + float ratio; + /* channel convert */ + int input_channels, output_channels, filter_channels; + AVAudioConvert *convert_ctx[2]; + enum AVSampleFormat sample_fmt[2]; ///< input and output sample format + unsigned sample_size[2]; ///< size of one sample in sample_fmt + short *buffer[2]; ///< buffers used for conversion to S16 + unsigned buffer_size[2]; ///< sizes of allocated buffers + short *bufin[MAX_CHANNELS]; + short *bufout[MAX_CHANNELS]; + +}; + +/* n1: number of samples */ +static void stereo_to_mono(short *output, short *input, int n1) +{ + short *p, *q; + int n = n1; + + p = input; + q = output; + while (n >= 4) { + q[0] = (p[0] + p[1]) >> 1; + q[1] = (p[2] + p[3]) >> 1; + q[2] = (p[4] + p[5]) >> 1; + q[3] = (p[6] + p[7]) >> 1; + q += 4; + p += 8; + n -= 4; + } + while (n > 0) { + q[0] = (p[0] + p[1]) >> 1; + q++; + p += 2; + n--; + } +} + +/* n1: number of samples */ +static void mono_to_stereo(short *output, short *input, int n1) +{ + short *p, *q; + int n = n1; + int v; + + p = input; + q = output; + while (n >= 4) { + v = p[0]; q[0] = v; q[1] = v; + v = p[1]; q[2] = v; q[3] = v; + v = p[2]; q[4] = v; q[5] = v; + v = p[3]; q[6] = v; q[7] = v; + q += 8; + p += 4; + n -= 4; + } + while (n > 0) { + v = p[0]; q[0] = v; q[1] = v; + q += 2; + p += 1; + n--; + } +} + +/* +5.1 to stereo input: [fl, fr, c, lfe, rl, rr] +- Left = front_left + rear_gain * rear_left + center_gain * center +- Right = front_right + rear_gain * rear_right + center_gain * center +Where rear_gain is usually around 0.5-1.0 and + center_gain is almost always 0.7 (-3 dB) +*/ +static void surround_to_stereo(short **output, short *input, int channels, int samples) +{ + int i; + short l, r; + + for (i = 0; i < samples; i++) { + int fl,fr,c,rl,rr; + fl = input[0]; + fr = input[1]; + c = input[2]; + // lfe = input[3]; + rl = input[4]; + rr = input[5]; + + l = av_clip_int16(fl + (0.5 * rl) + (0.7 * c)); + r = av_clip_int16(fr + (0.5 * rr) + (0.7 * c)); + + /* output l & r. */ + *output[0]++ = l; + *output[1]++ = r; + + /* increment input. */ + input += channels; + } +} + +static void deinterleave(short **output, short *input, int channels, int samples) +{ + int i,j; + for (i = 0; i < samples; i++) { + for (j = 0; j < channels; j++) { + *output[j]++ = *input++; + } + } +} + +static void interleave(short *output, short **input, int channels, int samples) +{ + int i,j; + for (i = 0; i < samples; i++) { + int j; + for (j = 0; j < channels; j++) { + *output++ = *input[j]++; + } + } +} + +static void ac3_5p1_mux(short *output, short *input1, short *input2, int n) +{ + int i; + short l, r; + + for (i = 0; i < n; i++) { + l = *input1++; + r = *input2++; + *output++ = l; /* left */ + *output++ = (l / 2) + (r / 2); /* center */ + *output++ = r; /* right */ + *output++ = 0; /* left surround */ + *output++ = 0; /* right surroud */ + *output++ = 0; /* low freq */ + } +} + +#define SUPPORT_RESAMPLE(ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8) \ + ch8<<7 | ch7<<6 | ch6<<5 | ch5<<4 | ch4<<3 | ch3<<2 | ch2<<1 | ch1<<0 + +static const uint8_t supported_resampling[MAX_CHANNELS] = { + // output ch: 1 2 3 4 5 6 7 8 + SUPPORT_RESAMPLE(1, 1, 0, 0, 0, 0, 0, 0), // 1 input channel + SUPPORT_RESAMPLE(1, 1, 0, 0, 0, 1, 0, 0), // 2 input channels + SUPPORT_RESAMPLE(0, 0, 1, 0, 0, 0, 0, 0), // 3 input channels + SUPPORT_RESAMPLE(0, 0, 0, 1, 0, 0, 0, 0), // 4 input channels + SUPPORT_RESAMPLE(0, 0, 0, 0, 1, 0, 0, 0), // 5 input channels + SUPPORT_RESAMPLE(0, 1, 0, 0, 0, 1, 0, 0), // 6 input channels + SUPPORT_RESAMPLE(0, 0, 0, 0, 0, 0, 1, 0), // 7 input channels + SUPPORT_RESAMPLE(0, 0, 0, 0, 0, 0, 0, 1), // 8 input channels +}; + +void *vj_av_audio_resample_init(int output_channels, int input_channels, + int output_rate, int input_rate, + enum AVSampleFormat sample_fmt_out, + enum AVSampleFormat sample_fmt_in, + int filter_length, int log2_phase_count, + int linear, double cutoff) +{ + ReSampleContext *s; + + if (input_channels > MAX_CHANNELS) { + av_log(NULL, AV_LOG_ERROR, + "Resampling with input channels greater than %d is unsupported.\n", + MAX_CHANNELS); + return NULL; + } + if (!(supported_resampling[input_channels-1] & (1<<(output_channels-1)))) { + int i; + av_log(NULL, AV_LOG_ERROR, "Unsupported audio resampling. Allowed " + "output channels for %d input channel%s", input_channels, + input_channels > 1 ? "s:" : ":"); + for (i = 0; i < MAX_CHANNELS; i++) + if (supported_resampling[input_channels-1] & (1<ratio = (float)output_rate / (float)input_rate; + + s->input_channels = input_channels; + s->output_channels = output_channels; + + s->filter_channels = s->input_channels; + if (s->output_channels < s->filter_channels) + s->filter_channels = s->output_channels; + + s->sample_fmt[0] = sample_fmt_in; + s->sample_fmt[1] = sample_fmt_out; + s->sample_size[0] = av_get_bytes_per_sample(s->sample_fmt[0]); + s->sample_size[1] = av_get_bytes_per_sample(s->sample_fmt[1]); + + int i; + int nb_samples = 256 * 1024; + for (i = 0; i < s->filter_channels; i++) { + s->bufin[i] = av_malloc_array(nb_samples, sizeof(short)); + s->bufout[i] = av_malloc_array(nb_samples, sizeof(short)); + + if (!s->bufin[i] || !s->bufout[i]) { + av_log(s->resample_context, AV_LOG_ERROR, "Could not allocate buffer\n"); + return NULL; + } + } + + if (s->sample_fmt[0] != AV_SAMPLE_FMT_S16) { + if (!(s->convert_ctx[0] = av_audio_convert_alloc(AV_SAMPLE_FMT_S16, 1, + s->sample_fmt[0], 1, NULL, 0))) { + av_log(s, AV_LOG_ERROR, + "Cannot convert %s sample format to s16 sample format\n", + av_get_sample_fmt_name(s->sample_fmt[0])); + av_free(s); + return NULL; + } + } + + if (s->sample_fmt[1] != AV_SAMPLE_FMT_S16) { + if (!(s->convert_ctx[1] = av_audio_convert_alloc(s->sample_fmt[1], 1, + AV_SAMPLE_FMT_S16, 1, NULL, 0))) { + av_log(s, AV_LOG_ERROR, + "Cannot convert s16 sample format to %s sample format\n", + av_get_sample_fmt_name(s->sample_fmt[1])); + av_audio_convert_free(s->convert_ctx[0]); + av_free(s); + return NULL; + } + } + + s->resample_context = vj_av_resample_init(output_rate, input_rate, + filter_length, log2_phase_count, + linear, cutoff); + + *(const AVClass**)s->resample_context = &audioresample_context_class; + + return (void*) s; +} + +/* resample audio. 'nb_samples' is the number of input samples */ +/* XXX: optimize it ! */ +int vj_audio_resample(void *ptr, short *output, short *input, int nb_samples) +{ + ReSampleContext *s = (ReSampleContext*) ptr; + int i, nb_samples1; + short **bufin = s->bufin; + short **bufout = s->bufout; +// short *bufin[MAX_CHANNELS]; +// short *bufout[MAX_CHANNELS]; + short *buftmp2[MAX_CHANNELS], *buftmp3[MAX_CHANNELS]; + short *output_bak = NULL; + int lenout; + + if (s->input_channels == s->output_channels && s->ratio == 1.0 && 0) { + /* nothing to do */ + memcpy(output, input, nb_samples * s->input_channels * sizeof(short)); + return nb_samples; + } + + if (s->sample_fmt[0] != AV_SAMPLE_FMT_S16) { + int istride[1] = { s->sample_size[0] }; + int ostride[1] = { 2 }; + const void *ibuf[1] = { input }; + void *obuf[1]; + unsigned input_size = nb_samples * s->input_channels * 2; + + if (!s->buffer_size[0] || s->buffer_size[0] < input_size) { + av_free(s->buffer[0]); + s->buffer_size[0] = input_size; + s->buffer[0] = av_malloc(s->buffer_size[0]); + if (!s->buffer[0]) { + av_log(s->resample_context, AV_LOG_ERROR, "Could not allocate buffer\n"); + return 0; + } + } + + obuf[0] = s->buffer[0]; + + if (av_audio_convert(s->convert_ctx[0], obuf, ostride, + ibuf, istride, nb_samples * s->input_channels) < 0) { + av_log(s->resample_context, AV_LOG_ERROR, + "Audio sample format conversion failed\n"); + return 0; + } + + input = s->buffer[0]; + } + + lenout= 2*s->output_channels*nb_samples * s->ratio + 16; + + if (s->sample_fmt[1] != AV_SAMPLE_FMT_S16) { + int out_size = lenout * av_get_bytes_per_sample(s->sample_fmt[1]) * + s->output_channels; + output_bak = output; + + if (!s->buffer_size[1] || s->buffer_size[1] < out_size) { + av_free(s->buffer[1]); + s->buffer_size[1] = out_size; + s->buffer[1] = av_malloc(s->buffer_size[1]); + if (!s->buffer[1]) { + av_log(s->resample_context, AV_LOG_ERROR, "Could not allocate buffer\n"); + return 0; + } + } + + output = s->buffer[1]; + } + + /* XXX: move those malloc to resample init code */ + for (i = 0; i < s->filter_channels; i++) { + //bufin[i] = av_malloc_array((nb_samples + s->temp_len), sizeof(short)); + //bufout[i] = av_malloc_array(lenout, sizeof(short)); + + if (!bufin[i] || !bufout[i]) { + av_log(s->resample_context, AV_LOG_ERROR, "Could not allocate buffer\n"); + nb_samples1 = 0; + goto fail; + } + + memcpy(bufin[i], s->temp[i], s->temp_len * sizeof(short)); + buftmp2[i] = bufin[i] + s->temp_len; + } + + if (s->input_channels == 2 && s->output_channels == 1) { + buftmp3[0] = output; + stereo_to_mono(buftmp2[0], input, nb_samples); + } else if (s->output_channels >= 2 && s->input_channels == 1) { + buftmp3[0] = bufout[0]; + memcpy(buftmp2[0], input, nb_samples * sizeof(short)); + } else if (s->input_channels == 6 && s->output_channels ==2) { + buftmp3[0] = bufout[0]; + buftmp3[1] = bufout[1]; + surround_to_stereo(buftmp2, input, s->input_channels, nb_samples); + } else if (s->output_channels >= s->input_channels && s->input_channels >= 2) { + for (i = 0; i < s->input_channels; i++) { + buftmp3[i] = bufout[i]; + } + deinterleave(buftmp2, input, s->input_channels, nb_samples); + } else { + buftmp3[0] = output; + memcpy(buftmp2[0], input, nb_samples * sizeof(short)); + } + + nb_samples += s->temp_len; + + /* resample each channel */ + nb_samples1 = 0; /* avoid warning */ + for (i = 0; i < s->filter_channels; i++) { + int consumed; + int is_last = i + 1 == s->filter_channels; + + nb_samples1 = vj_av_resample(s->resample_context, buftmp3[i], bufin[i], + &consumed, nb_samples, lenout, is_last); + s->temp_len = nb_samples - consumed; + s->temp[i] = av_realloc_array(s->temp[i], s->temp_len, sizeof(short)); + memcpy(s->temp[i], bufin[i] + consumed, s->temp_len * sizeof(short)); + } + + if (s->output_channels == 2 && s->input_channels == 1) { + mono_to_stereo(output, buftmp3[0], nb_samples1); + } else if (s->output_channels == 6 && s->input_channels == 2) { + ac3_5p1_mux(output, buftmp3[0], buftmp3[1], nb_samples1); + } else if ((s->output_channels == s->input_channels && s->input_channels >= 2) || + (s->output_channels == 2 && s->input_channels == 6)) { + interleave(output, buftmp3, s->output_channels, nb_samples1); + } + + if (s->sample_fmt[1] != AV_SAMPLE_FMT_S16) { + int istride[1] = { 2 }; + int ostride[1] = { s->sample_size[1] }; + const void *ibuf[1] = { output }; + void *obuf[1] = { output_bak }; + + if (av_audio_convert(s->convert_ctx[1], obuf, ostride, + ibuf, istride, nb_samples1 * s->output_channels) < 0) { + av_log(s->resample_context, AV_LOG_ERROR, + "Audio sample format conversion failed\n"); + return 0; + } + } + +fail: + /* for (i = 0; i < s->filter_channels; i++) { + av_free(bufin[i]); + av_free(bufout[i]); + } */ + + return nb_samples1; +} + +void vj_audio_resample_close(void *ptr) +{ + ReSampleContext *s = (ReSampleContext*) ptr; + int i; + vj_av_resample_close(s->resample_context); + for (i = 0; i < s->filter_channels; i++) + av_freep(&s->temp[i]); + av_freep(&s->buffer[0]); + av_freep(&s->buffer[1]); + av_audio_convert_free(s->convert_ctx[0]); + av_audio_convert_free(s->convert_ctx[1]); + for (i = 0; i < s->filter_channels; i++) { + av_free(s->bufin[i]); + av_free(s->bufout[i]); + } + + av_free(s); +} + diff --git a/veejay-current/veejay-server/thirdparty/libresample/resample.h b/veejay-current/veejay-server/thirdparty/libresample/resample.h new file mode 100644 index 00000000..71affa93 --- /dev/null +++ b/veejay-current/veejay-server/thirdparty/libresample/resample.h @@ -0,0 +1,50 @@ +/* + * samplerate conversion for both audio and video + * Copyright (c) 2000 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +/* libav only has libavresample + * ffmpeg has both libavresample and libswresample + * + * backport obsolete resampler to veejay + * + */ + +#ifndef AV_RESAMPLER +#define AV_RESAMPLER + +void *vj_av_resample_init(int out_rate, int in_rate, int filter_size, int phase_shift, int linear, double cutoff); + +void vj_av_resample_close(void *ptr); + +int vj_av_resample(void *ptr, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx); + +void *vj_av_audio_resample_init(int output_channels, int input_channels, + int output_rate, int input_rate, + enum AVSampleFormat sample_fmt_out, + enum AVSampleFormat sample_fmt_in, + int filter_length, int log2_phase_count, + int linear, double cutoff); + +int vj_audio_resample(void *s, short *output, short *input, int nb_samples); + + +void vj_audio_resample_close(void *s); +#endif diff --git a/veejay-current/veejay-server/thirdparty/libresample/resample2.c b/veejay-current/veejay-server/thirdparty/libresample/resample2.c new file mode 100644 index 00000000..a54bee15 --- /dev/null +++ b/veejay-current/veejay-server/thirdparty/libresample/resample2.c @@ -0,0 +1,317 @@ +/* + * audio resampling + * Copyright (c) 2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * audio resampling + * @author Michael Niedermayer + */ + +#include +#include +#include + +#ifndef CONFIG_RESAMPLE_HP +#define FILTER_SHIFT 15 + +#define FELEM int16_t +#define FELEM2 int32_t +#define FELEML int64_t +#define FELEM_MAX INT16_MAX +#define FELEM_MIN INT16_MIN +#define WINDOW_TYPE 9 +#elif !defined(CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE) +#define FILTER_SHIFT 30 + +#define FELEM int32_t +#define FELEM2 int64_t +#define FELEML int64_t +#define FELEM_MAX INT32_MAX +#define FELEM_MIN INT32_MIN +#define WINDOW_TYPE 12 +#else +#define FILTER_SHIFT 0 + +#define FELEM double +#define FELEM2 double +#define FELEML double +#define WINDOW_TYPE 24 +#endif + + +typedef struct AVResampleContext{ + const AVClass *av_class; + FELEM *filter_bank; + int filter_length; + int ideal_dst_incr; + int dst_incr; + int index; + int frac; + int src_incr; + int compensation_distance; + int phase_shift; + int phase_mask; + int linear; +}AVResampleContext; + +/** + * 0th order modified bessel function of the first kind. + */ +static double bessel(double x){ + double v=1; + double lastv=0; + double t=1; + int i; + + x= x*x/4; + for(i=1; v != lastv; i++){ + lastv=v; + t *= x/(i*i); + v += t; + } + return v; +} + +/** + * Build a polyphase filterbank. + * @param factor resampling factor + * @param scale wanted sum of coefficients for each filter + * @param type 0->cubic, 1->blackman nuttall windowed sinc, 2..16->kaiser windowed sinc beta=2..16 + * @return 0 on success, negative on error + */ +static int build_filter(FELEM *filter, double factor, int tap_count, int phase_count, int scale, int type){ + int ph, i; + double x, y, w; + double *tab = av_malloc_array(tap_count, sizeof(*tab)); + const int center= (tap_count-1)/2; + + if (!tab) + return AVERROR(ENOMEM); + + /* if upsampling, only need to interpolate, no filter */ + if (factor > 1.0) + factor = 1.0; + + for(ph=0;phphase_shift= phase_shift; + c->phase_mask= phase_count-1; + c->linear= linear; + + c->filter_length= FFMAX((int)ceil(filter_size/factor), 1); + c->filter_bank= av_mallocz_array(c->filter_length, (phase_count+1)*sizeof(FELEM)); + if (!c->filter_bank) + goto error; + if (build_filter(c->filter_bank, factor, c->filter_length, phase_count, 1<filter_bank[c->filter_length*phase_count+1], c->filter_bank, (c->filter_length-1)*sizeof(FELEM)); + c->filter_bank[c->filter_length*phase_count]= c->filter_bank[c->filter_length - 1]; + + if(!av_reduce(&c->src_incr, &c->dst_incr, out_rate, in_rate * (int64_t)phase_count, INT32_MAX/2)) + goto error; + c->ideal_dst_incr= c->dst_incr; + + c->index= -phase_count*((c->filter_length-1)/2); + + return (void*) c; +error: + av_free(c->filter_bank); + av_free(c); + return NULL; +} + +void vj_av_resample_close(void *ptr){ + AVResampleContext *c = (AVResampleContext*) ptr; + av_freep(&c->filter_bank); + av_freep(&c); +} + +void vj_av_resample_compensate(AVResampleContext *c, int sample_delta, int compensation_distance){ +// sample_delta += (c->ideal_dst_incr - c->dst_incr)*(int64_t)c->compensation_distance / c->ideal_dst_incr; + c->compensation_distance= compensation_distance; + c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr * (int64_t)sample_delta / compensation_distance; +} + +int vj_av_resample(void *ptr, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx){ + AVResampleContext *c = (AVResampleContext*) ptr; + int dst_index, i; + int index= c->index; + int frac= c->frac; + int dst_incr_frac= c->dst_incr % c->src_incr; + int dst_incr= c->dst_incr / c->src_incr; + int compensation_distance= c->compensation_distance; + + if(compensation_distance == 0 && c->filter_length == 1 && c->phase_shift==0){ + int64_t index2= ((int64_t)index)<<32; + int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr; + dst_size= FFMIN(dst_size, (src_size-1-index) * (int64_t)c->src_incr / c->dst_incr); + + for(dst_index=0; dst_index < dst_size; dst_index++){ + dst[dst_index] = src[index2>>32]; + index2 += incr; + } + index += dst_index * dst_incr; + index += (frac + dst_index * (int64_t)dst_incr_frac) / c->src_incr; + frac = (frac + dst_index * (int64_t)dst_incr_frac) % c->src_incr; + }else{ + for(dst_index=0; dst_index < dst_size; dst_index++){ + FELEM *filter= c->filter_bank + c->filter_length*(index & c->phase_mask); + int sample_index= index >> c->phase_shift; + FELEM2 val=0; + + if(sample_index < 0){ + for(i=0; ifilter_length; i++) + val += src[FFABS(sample_index + i) % src_size] * filter[i]; + }else if(sample_index + c->filter_length > src_size){ + break; + }else if(c->linear){ + FELEM2 v2=0; + for(i=0; ifilter_length; i++){ + val += src[sample_index + i] * (FELEM2)filter[i]; + v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_length]; + } + val+=(v2-val)*(FELEML)frac / c->src_incr; + }else{ + for(i=0; ifilter_length; i++){ + val += src[sample_index + i] * (FELEM2)filter[i]; + } + } + +#ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE + dst[dst_index] = av_clip_int16(lrintf(val)); +#else + val = (val + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT; + dst[dst_index] = (unsigned)(val + 32768) > 65535 ? (val>>31) ^ 32767 : val; +#endif + + frac += dst_incr_frac; + index += dst_incr; + if(frac >= c->src_incr){ + frac -= c->src_incr; + index++; + } + + if(dst_index + 1 == compensation_distance){ + compensation_distance= 0; + dst_incr_frac= c->ideal_dst_incr % c->src_incr; + dst_incr= c->ideal_dst_incr / c->src_incr; + } + } + } + *consumed= FFMAX(index, 0) >> c->phase_shift; + if(index>=0) index &= c->phase_mask; + + if(compensation_distance){ + compensation_distance -= dst_index; + } + if(update_ctx){ + c->frac= frac; + c->index= index; + c->dst_incr= dst_incr_frac + c->src_incr*dst_incr; + c->compensation_distance= compensation_distance; + } + + return dst_index; +} + diff --git a/veejay-current/veejay-server/veejay/Makefile.am b/veejay-current/veejay-server/veejay/Makefile.am index 43446a63..8548eecd 100644 --- a/veejay-current/veejay-server/veejay/Makefile.am +++ b/veejay-current/veejay-server/veejay/Makefile.am @@ -35,7 +35,7 @@ lib_LTLIBRARIES = $(VEEJAY_LIB_FILE) libveejay_la_SOURCES = jpegutils.c vj-misc.c vj-task.c \ vj-osc.c vjkf.c vj-event.c vj-eventman.c vj-perform.c \ x11misc.c vj-shm.c vj-sdl.c vj-sdl-font.c vj-dfb.c vj-viewport.c vj-composite.c \ - vj-font.c vj-pjack.c vj-share.c liblavplayvj.c + vj-font.c vj-pjack.c vj-share.c vj-split.c liblavplayvj.c libveejay_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ -release $(LT_RELEASE) -no-undefined -export-dynamic $(DEBUGLIBS) @@ -47,6 +47,7 @@ libveejay_la_LIBADD = \ -L$(top_builddir)/thirdparty/libhash -lhash \ -L$(top_builddir)/thirdparty/liblzo -lvjlzo \ -L$(top_builddir)/thirdparty/libOSC -lOSC \ + -L$(top_builddir)/thirdparty/libresample -lresample \ -L$(top_builddir)/libvjmsg -lvjmsg \ -L$(top_builddir)/libvjmem -lvjmem \ -L$(top_builddir)/libvje -lvje \ @@ -84,7 +85,7 @@ veejay_headers = vims.h jpegutils.h vevo.h vj-composite.h vj-jack.h \ vj-OSC.h vj-viewport.h lav_common.h vims.h vj-dfb.h \ vjkf.h vj-perform.h vj-viewport-xml.h libveejay.h \ vj-audio.h vj-event.h vj-lib.h vj-plug.h x11misc.h \ - veejay.h vj-bjack.h vj-font.h vj-misc.h vj-sdl.h vj-task.h + veejay.h vj-bjack.h vj-font.h vj-misc.h vj-sdl.h vj-task.h vj-split.h veejay_SOURCES = veejay.c ${veejay_headers} veejay_LDADD = libveejay.la @LIBGETOPT_LIB@ diff --git a/veejay-current/veejay-server/veejay/liblavplayvj.c b/veejay-current/veejay-server/veejay/liblavplayvj.c index 95d5fca3..5cc2cb32 100644 --- a/veejay-current/veejay-server/veejay/liblavplayvj.c +++ b/veejay-current/veejay-server/veejay/liblavplayvj.c @@ -91,6 +91,7 @@ #include #include #include +#include #include #include #ifdef HAVE_SDL_TTF @@ -444,7 +445,7 @@ int veejay_free(veejay_t * info) if(info->mask) free(info->mask); if(info->rlinks) free(info->rlinks); if(info->rmodes) free(info->rmodes ); - + if(info->splitted_screens) free(info->splitted_screens); free(settings); free(info); @@ -956,6 +957,11 @@ static int veejay_screen_update(veejay_t * info ) vj_vloopback_write_pipe( info->vloopback ); } + if( info->splitter ) { + vj_split_render( info->splitter ); + } + + #ifdef HAVE_JPEG #ifdef USE_GDK_PIXBUF if (info->uc->hackme == 1) @@ -1277,12 +1283,13 @@ void veejay_check_homedir(void *arg) struct statfs ts; if( statfs( tmp, &ts ) != 0 ) { - veejay_msg(VEEJAY_MSG_WARNING,"No plugins.cfg found (see DOC/HowtoPlugins)"); + veejay_msg(VEEJAY_MSG_WARNING,"No plugin configuration file found in [%s] (see DOC/HowtoPlugins)",tmp); } snprintf(tmp,sizeof(tmp), "%s/viewport.cfg", path); if( statfs( tmp, &ts ) != 0 ) { - veejay_msg(VEEJAY_MSG_WARNING,"No viewport.cfg found (start veejay with -D -w -h and press CTRL-V to setup viewport)"); + veejay_msg(VEEJAY_MSG_WARNING,"No projection mapping file found in [%s]", tmp); + veejay_msg(VEEJAY_MSG_WARNING,"Press CTRL-s to setup then CTRL-h for help. Press CTRL-s again to exit, CTRL-p to switch"); } } @@ -1763,6 +1770,14 @@ int veejay_init(veejay_t * info, int x, int y,char *arg, int def_tags, int gen_t return -1; } + if(info->settings->splitscreen) { + char split_cfg[1024]; + snprintf(split_cfg,sizeof(split_cfg),"%s/splitscreen.cfg", info->homedir ); + + vj_split_set_master( info->uc->port ); + + info->splitter = vj_split_new_from_file( split_cfg, info->video_output_width,info->video_output_height, PIX_FMT_YUV444P ); + } if(info->settings->composite) { @@ -1852,8 +1867,6 @@ int veejay_init(veejay_t * info, int x, int y,char *arg, int def_tags, int gen_t info->audio = NO_AUDIO; } - veejay_msg(VEEJAY_MSG_INFO, - "Initialized %d Image- and Video Effects", vj_effect_max_effects()); vj_effect_initialize( info->video_output_width,info->video_output_height,full_range); if(info->dump) @@ -2184,7 +2197,6 @@ static void veejay_playback_cycle(veejay_t * info) editlist *el = info->edit_list; struct mjpeg_sync bs; struct timespec time_now; - struct timespec time_last; double tdiff1=0.0, tdiff2=0.0; int first_free, skipv, skipa, skipi, nvcorr,frame; long ts, te; @@ -2530,11 +2542,30 @@ static void *veejay_playback_thread(void *data) } if(info->osc) vj_osc_free(info->osc); - + + if( info->shm ) { + vj_shm_stop(info->shm); + vj_shm_free(info->shm); + } + if( info->splitter ) { + vj_split_free(info->splitter); + } + + if( info->y4m ) { + vj_yuv_stream_stop_write( info->y4m ); + vj_yuv4mpeg_free(info->y4m ); + info->y4m = NULL; + } + + if( info->vloopback ) { + vj_vloopback_close( info->vloopback ); + info->vloopback = NULL; + + } + #ifdef HAVE_SDL for ( i = 0; i < MAX_SDL_OUT ; i ++ ) - if( info->sdl[i] ) - { + if( info->sdl[i] ) { #ifndef X_DISPLAY_MISSING if(info->sdl[i]->display) x11_enable_screensaver( info->sdl[i]->display); @@ -2545,22 +2576,12 @@ static void *veejay_playback_thread(void *data) vj_sdl_quit(); #endif #ifdef HAVE_DIRECTFB - if( info->dfb ) - { + if( info->dfb ) { vj_dfb_free(info->dfb); free(info->dfb); } #endif - if( info->y4m ) { - vj_yuv_stream_stop_write( info->y4m ); - vj_yuv4mpeg_free(info->y4m ); - info->y4m = NULL; - } - if( info->vloopback ) { - vj_vloopback_close( info->vloopback ); - info->vloopback = NULL; - } /* #ifdef HAVE_GL #ifndef X_DISPLAY_MISSING @@ -2573,17 +2594,11 @@ static void *veejay_playback_thread(void *data) #endif */ - #ifdef HAVE_FREETYPE vj_font_destroy( info->font ); vj_font_destroy( info->osd ); #endif - if( info->shm ) { - vj_shm_stop(info->shm); - vj_shm_free(info->shm); - } - veejay_msg(VEEJAY_MSG_DEBUG,"Exiting playback thread"); vj_perform_free(info); @@ -2798,9 +2813,10 @@ veejay_t *veejay_malloc() info->no_bezerk = 1; info->nstreams = 1; info->stream_outformat = -1; - info->rlinks = (int*) vj_calloc(sizeof(int) * VJ_MAX_CONNECTIONS ); - info->rmodes = (int*) vj_calloc(sizeof(int) * VJ_MAX_CONNECTIONS ); - info->settings->currently_processed_entry = -1; + info->rlinks = (int*) vj_malloc(sizeof(int) * VJ_MAX_CONNECTIONS ); + info->rmodes = (int*) vj_malloc(sizeof(int) * VJ_MAX_CONNECTIONS ); + info->splitted_screens = (int*) vj_malloc( sizeof(int) * VJ_MAX_CONNECTIONS ); + info->settings->currently_processed_entry = -1; info->settings->first_frame = 1; info->settings->state = LAVPLAY_STATE_PLAYING; info->settings->composite = 1; @@ -2817,6 +2833,7 @@ veejay_t *veejay_malloc() for( i =0; i < VJ_MAX_CONNECTIONS ; i ++ ) { info->rlinks[i] = -1; info->rmodes[i] = -1; + info->splitted_screens[i] = -1; } veejay_memset(info->action_file[0],0,sizeof(info->action_file[0])); diff --git a/veejay-current/veejay-server/veejay/veejay.c b/veejay-current/veejay-server/veejay/veejay.c index a99ea09a..8b54360f 100644 --- a/veejay-current/veejay-server/veejay/veejay.c +++ b/veejay-current/veejay-server/veejay/veejay.c @@ -310,6 +310,8 @@ static void Usage(char *progname) " -S/--scene-detection \tCreate new samples based on scene detection threshold \n"); fprintf(stderr, " -M/--dynamic-fx-chain\t\tDo not keep FX chain buffers in RAM (default off)\n"); + fprintf(stderr, + " /--split-screen\t\tLoad split screen configuration\n"); fprintf(stderr," -q/--quit \t\t\tQuit at end of file\n"); fprintf(stderr,"\n\n"); } @@ -536,11 +538,15 @@ static int set_option(const char *name, char *value) { info->dummy->active = 1; // enable DUMMY MODE } - else if (strcmp(name, "dynamic-fx-chain" ) == 0 || strcmp(name, "M" ) == 0 ) + else if (strcmp(name, "dynamic-fx-chain" ) == 0 || strcmp(name, "M" ) == 0 ) { info->uc->ram_chain = 0; } - else + else if (strcmp(name, "split-screen" ) == 0 ) + { + info->settings->splitscreen = 1; + } + else nerr++; /* unknown option - error */ return nerr; @@ -609,6 +615,7 @@ static int check_command_line_options(int argc, char *argv[]) {"scene-detection",1,0,0}, {"dynamic-fx-chain",0,0,0}, {"pace-correction",1,0,0}, + {"split-screen",0,0,0}, {0, 0, 0, 0} }; #endif @@ -763,7 +770,7 @@ int main(int argc, char **argv) vj_osc_allocate(VJ_PORT+2); vj_event_dump(); vj_effect_dump(); - fprintf(stdout, "Environment variables:\n\tSDL_VIDEO_HWACCEL\t\tSet to 1 to use SDL video hardware accel (default=on)\n\tVEEJAY_PERFORMANCE\t\tSet to \"quality\" or \"fastest\" (default is fastest)\n\tVEEJAY_AUTO_SCALE_PIXELS\tSet to 1 to convert between CCIR 601 and JPEG automatically (default=dont care)\n\tVEEJAY_INTERPOLATE_CHROMA\tSet to 1 if you wish to interpolate every chroma sample when scaling (default=0)\n\tVEEJAY_SDL_KEY_REPEAT_INTERVAL\tinterval of key pressed to repeat while pressed down.\n\tVEEJAY_PLAYBACK_CACHE\t\tSample cache size in MB\n\tVEEJAY_SDL_KEY_REPEAT_DELAY\tDelay key repeat in ms\n\tVEEJAY_FULLSCREEN\t\tStart in fullscreen (1) or windowed (0) mode\n\tVEEJAY_SCREEN_GEOMETRY\t\tSpecifiy a geometry for veejay to position the video window.\n\tVEEJAY_SCREEN_SIZE\t\tSize of video window, defaults to full screen size.\n\tVEEJAY_RUN_MODE\t\t\tRun in \"classic\" (352x288 Dummy) or default (720x576). \n"); + fprintf(stdout, "Environment variables:\n\tSDL_VIDEO_HWACCEL\t\tSet to 1 to use SDL video hardware accel (default=on)\n\tVEEJAY_PERFORMANCE\t\tSet to \"quality\" or \"fastest\" (default is fastest)\n\tVEEJAY_AUTO_SCALE_PIXELS\tSet to 1 to convert between CCIR 601 and JPEG automatically (default=dont care)\n\tVEEJAY_INTERPOLATE_CHROMA\tSet to 1 if you wish to interpolate every chroma sample when scaling (default=0)\n\tVEEJAY_SDL_KEY_REPEAT_INTERVAL\tinterval of key pressed to repeat while pressed down.\n\tVEEJAY_PLAYBACK_CACHE\t\tSample cache size in MB\n\tVEEJAY_SDL_KEY_REPEAT_DELAY\tDelay key repeat in ms\n\tVEEJAY_FULLSCREEN\t\tStart in fullscreen (1) or windowed (0) mode\n\tVEEJAY_DESKTOP_GEOMETRY\t\tSpecifiy a geometry for veejay to position the video window.\n\tVEEJAY_VIDEO_POSITION\t\tPosition of video window\n\tVEEJAY_VIDEO_SIZE\t\tSize of video window, defaults to full screen size.\n\tVEEJAY_RUN_MODE\t\t\tRun in \"classic\" (352x288 Dummy) or default (720x576). \n"); fprintf(stdout,"\tVEEJAY_V4L2_NO_THREADING\tSet to 1 to query frame in main-loop\n"); fprintf(stdout,"\tVEEJAY_MULTITHREAD_TASKS\tSet the number of parallel tasks (multithreading) to use (default is equal to the number of cpu-cores)\n"); fprintf(stdout,"\tVEEJAY_PAUSE_EVERYTHING\t\tIf set to 1, video is paused but rendering continues. If set to 0, rendering pauses as well\n"); diff --git a/veejay-current/veejay-server/veejay/vims.h b/veejay-current/veejay-server/veejay/vims.h index ec098c8e..f4db9951 100644 --- a/veejay-current/veejay-server/veejay/vims.h +++ b/veejay-current/veejay-server/veejay/vims.h @@ -65,7 +65,10 @@ enum { VIMS_WORKINGDIR = 421, VIMS_SAMPLE_STACK = 422, VIMS_GET_IMAGE = 423, + VIMS_GET_SHM_EXT = 424, VIMS_GET_SHM = 425, + VIMS_GET_SPLIT_IMAGE = 426, + VIMS_GET_SAMPLE_IMAGE = 427, VIMS_CHAIN_GET_PARAMETERS = 435, VIMS_SET_VOLUME = 300, VIMS_FULLSCREEN = 301, @@ -119,6 +122,7 @@ enum { VIMS_VIDEO_MCAST_STOP = 23, VIMS_VIDEO_SET_SPEEDK = 24, VIMS_EDITLIST_PASTE_AT = 50, + VIMS_SPLIT_CONNECT_SHM = 60, VIMS_SHM_WRITER = 25, VIMS_EDITLIST_COPY = 51, VIMS_EDITLIST_DEL = 52, diff --git a/veejay-current/veejay-server/veejay/vj-composite.c b/veejay-current/veejay-server/veejay/vj-composite.c index dfa005ed..36c44a8b 100644 --- a/veejay-current/veejay-server/veejay/vj-composite.c +++ b/veejay-current/veejay-server/veejay/vj-composite.c @@ -39,7 +39,7 @@ #include #include #endif - +#include #include #include #ifdef HAVE_GL @@ -140,13 +140,11 @@ void *composite_init( int pw, int ph, int iw, int ih, const char *homedir, int s c->back1 = NULL; - veejay_msg(VEEJAY_MSG_INFO, "Configuring projection:"); - veejay_msg(VEEJAY_MSG_INFO, "\tSoftware scaler : %s", yuv_get_scaler_name(zoom_type) ); - veejay_msg(VEEJAY_MSG_INFO, "\tVideo resolution : %dx%d", iw,ih ); - veejay_msg(VEEJAY_MSG_INFO, "\tScreen resolution: %dx%d", pw,ph ); - veejay_msg(VEEJAY_MSG_INFO, "\tStatus : %s", - (vp1_enabled ? "Active":"Inactive")); - veejay_msg(VEEJAY_MSG_INFO, "Press Middle-Mouse button to activate setup."); + veejay_msg(VEEJAY_MSG_DEBUG, "\tSoftware scaler : %s", yuv_get_scaler_name(zoom_type) ); + veejay_msg(VEEJAY_MSG_DEBUG, "\tVideo resolution : %dx%d", iw,ih ); + veejay_msg(VEEJAY_MSG_DEBUG, "\tScreen resolution: %dx%d", pw,ph ); + veejay_msg(VEEJAY_MSG_DEBUG, "\tStatus : %s",(vp1_enabled ? "Active":"Inactive")); + *vp1_e = (vp1_enabled ? 1 : 2); char *gf_instr = getenv( "VEEJAY_ORIGINAL_FRAME" ); @@ -172,7 +170,6 @@ void *composite_clone( void *compiz ) if(!c) return NULL; void *v = viewport_clone(c->vp1,c->img_width,c->img_height); viewport_reconfigure(v); - return v; } @@ -228,6 +225,7 @@ void composite_set_ui(void *compiz, int status ) viewport_set_ui( c->vp1, status ); } + void composite_add_to_config( void *compiz, void *vc, int which_vp ) { composite_t *c = (composite_t*) compiz; @@ -345,7 +343,24 @@ void composite_blit_yuyv( void *compiz, uint8_t *in[4], uint8_t *yuyv, int which viewport_produce_full_img_yuyv( c->vp1,c->proj_plane,yuyv); return; } +} +void composite_process_divert( void *compiz,uint8_t *in[4], VJFrame *out, void *splitter, int which_vp ) +{ + composite_t *c = (composite_t*) compiz; + int vp1_active = viewport_active(c->vp1); + + if( vp1_active && which_vp == 2 ) { + vj_split_process( splitter, out ); + } + else if( which_vp == 2 ) { + viewport_produce_full_img(c->vp1,c->proj_plane,out->data); + vj_split_process( splitter, out ); + } + else if ( which_vp == 1 && !vp1_active ) { + viewport_produce_full_img(c->vp1,c->proj_plane,out->data); + vj_split_process( splitter, out ); + } } //@OBSOLETE diff --git a/veejay-current/veejay-server/veejay/vj-composite.h b/veejay-current/veejay-server/veejay/vj-composite.h index 51aee7fa..c5f3ebf5 100644 --- a/veejay-current/veejay-server/veejay/vj-composite.h +++ b/veejay-current/veejay-server/veejay/vj-composite.h @@ -36,6 +36,7 @@ int composite_process(void *compiz, VJFrame *output, VJFrame *input, int which_v void composite_blit_ycbcr( void *compiz,uint8_t *in[4], int which_vp, void *gl ); +void composite_process_divert( void *compiz, uint8_t *in[4], VJFrame *out, void *splitter, int setting ); void composite_blit_yuyv( void *compiz,uint8_t *in[4], uint8_t *yuyv, int which_vp ); diff --git a/veejay-current/veejay-server/veejay/vj-event.c b/veejay-current/veejay-server/veejay/vj-event.c index b7d02ecf..e6cbd3a5 100644 --- a/veejay-current/veejay-server/veejay/vj-event.c +++ b/veejay-current/veejay-server/veejay/vj-event.c @@ -72,9 +72,12 @@ #include #endif +#include + static int use_bw_preview_ = 0; static int _last_known_num_args = 0; static hash_t *BundleHash = NULL; +static uint8_t *sample_image_buffer = NULL; static int vj_event_valid_mode(int mode) { switch(mode) { @@ -2589,7 +2592,10 @@ void vj_event_destroy() if(keyboard_events) vj_event_destroy_hash( keyboard_events ); #endif if(BundleHash) vj_event_destroy_bundles( BundleHash ); - + + if(sample_image_buffer) + free(sample_image_buffer); + vj_picture_free(); vj_event_vevo_free(); @@ -9059,6 +9065,38 @@ void vj_event_send_chain_list ( void *ptr, const char format[], va_list ap ) SEND_MSG(v, s_print_buf); free(s_print_buf); } +void vj_event_send_shm_info( void *ptr, const char format[], va_list ap) +{ + int args[1] = { -1 }; + char *str = NULL; + veejay_t *v = (veejay_t*)ptr; + P_A(args,str,format,ap); + + net_set_screen_id( args[0] ); + + char *msg = get_print_buf(128); + snprintf( msg, 128, + "%d %d %d %d", + v->video_output_width, + v->video_output_height, + v->pixel_format, + vj_shm_get_my_id( v->shm ) ); + + int msg_len = strlen(msg); + char *tmp = get_print_buf(1 + msg_len + 3); + + sprintf( tmp, "%03zu%s",msg_len, msg ); + + SEND_MSG(v,tmp); + free(msg); + free(tmp); + + if( args[0] >= 0 ) { + veejay_msg(VEEJAY_MSG_INFO, "Binding this instance to screen %d of remote", + args[0]); + } +} + void vj_event_send_video_information ( void *ptr, const char format[], va_list ap ) { @@ -9122,23 +9160,23 @@ void vj_event_send_editlist ( void *ptr, const char format[], va_list ap ) void vj_event_send_frame ( void *ptr, const char format[], va_list ap ) { veejay_t *v = (veejay_t*) ptr; - int i = 0; - int ok = 0; - for( i = 0; i < 8; i ++ ) { - if( v->uc->current_link == v->rlinks[i] ) { - veejay_msg(VEEJAY_MSG_DEBUG, "Someone grabbed two beers at once!"); - } - if( v->rlinks[i] == -1 ) { - v->rlinks[i] = v->uc->current_link; //@ queue. used in vj_perform_send_primary_frame_s2 - ok = 1; - break; - } + int args[1] = { -1 }; + char *str = NULL; + + if( v->splitter ) { + P_A(args,str,format,ap); } - if( !ok ) { - veejay_msg(0, "No more video stream connections allowed, limited to 8"); - SEND_MSG(v,"00000000000000000000"); - return; + int i = 0; + + for( i = 0; i < VJ_MAX_CONNECTIONS; i ++ ) { + if( v->rlinks[i] == -1 ) { + v->rlinks[i] = v->uc->current_link; + if( v->splitter ) { + v->splitted_screens[ i ] = args[0]; + } + break; + } } if (!v->settings->is_dat ) @@ -9733,11 +9771,34 @@ void vj_event_connect_shm( void *ptr, const char format[], va_list ap ) int32_t key = vj_share_pull_master( v->shm,"127.0.0.1", args[0] ); int id = veejay_create_tag( v, VJ_TAG_TYPE_GENERATOR, "lvd_shmin.so", v->nstreams, key,0); + if( id <= 0 ) { + veejay_msg(0, "Unable to connect to shared resource id %d", key ); + } +} + +void vj_event_connect_split_shm( void *ptr, const char format[], va_list ap ) +{ + veejay_t *v = (veejay_t*) ptr; + int args[2]; + char *str = NULL; + P_A(args,str,format,ap); + + int32_t key = args[0]; + int safe_key = vj_shm_get_id(); + + vj_shm_set_id( key ); + + veejay_msg(VEEJAY_MSG_INFO,"Shared memory resource %x (%d)", key,key); + + int id = veejay_create_tag( v, VJ_TAG_TYPE_GENERATOR, "lvd_shmin.so", v->nstreams, 0, key); + + vj_shm_set_id( safe_key ); if( id <= 0 ) { veejay_msg(0, "Unable to connect to shared resource id %d", key ); } + veejay_change_playback_mode(v, VJ_PLAYBACK_MODE_TAG ,id); } #ifdef HAVE_FREETYPE @@ -10433,4 +10494,106 @@ void vj_event_set_macro_status( void *ptr, const char format[], va_list ap ) } } +void vj_event_get_sample_image ( void *ptr, const char format[], va_list ap ) +{ + veejay_t *v = (veejay_t*)ptr; + int args[4]; + char *str = NULL; + + P_A(args,str,format,ap); + + int max_w = vj_perform_preview_max_width(); + int max_h = vj_perform_preview_max_height(); + + int w = args[2]; + int h = args[3]; + + int type = args[1]; + + if(args[0] == -1 && type == 0) + args[0] = sample_size() - 1; + else if (args[0] == -1 && type != 0 ) + args[0] = vj_tag_size() - 1; + + if( args[0] == 0) + args[0] = v->uc->sample_id; + + int id = args[0]; + + int startFrame = (type == 0 ? 0 : -1); + + if( w <= 0 || h <= 0 || w >= max_w || h >= max_h ) + { + veejay_msg(0, "Invalid image dimension %dx%d requested (max is %dx%d)",w,h,max_w,max_h ); + SEND_MSG(v, "000000000000" ); + return; + } + + int dstlen = 0; + + editlist *el = ( type == VJ_PLAYBACK_MODE_SAMPLE ? sample_get_editlist(id) : v->edit_list ); + if( el == NULL && type == VJ_PLAYBACK_MODE_SAMPLE ) { + veejay_msg(0, "No such sample %d", id ); + SEND_MSG(v, "000000000000" ); + return; + } + + uint8_t *img[4] = { 0 }; + if( sample_image_buffer == NULL ) { + sample_image_buffer = (uint8_t*) vj_malloc( sizeof(uint8_t) * v->video_output_width * v->video_output_height * 4); + } + if( sample_image_buffer == NULL ) { + veejay_msg(0, "Not enough memory", id ); + SEND_MSG(v, "000000000000" ); + return; + } + + img[0] = sample_image_buffer; + img[1] = img[0] + v->video_output_width * v->video_output_height; + img[2] = img[1] + v->video_output_width * v->video_output_height; + + if( startFrame >= 0 ) { + int ret = vj_el_get_video_frame( el, startFrame, img ); + if( ret == 0 ) { + veejay_msg(VEEJAY_MSG_WARNING,"Unable to decode frame 1"); + SEND_MSG(v, "000000000000" ); + return; + } + } + else { + //FIXME preview from streamed video + SEND_MSG(v, "000000000000" ); + return; + } + + VJFrame *frame = yuv_yuv_template( img[0],img[1],img[2], v->video_output_width, v->video_output_height, + get_ffmpeg_pixfmt( v->pixel_format )); + + if( use_bw_preview_ ) { + vj_fastbw_picture_save_to_mem( + frame, + w, + h, + frame->format ); + + dstlen = w * h; + } + else { + vj_fast_picture_save_to_mem( + frame, + w, + h, + frame->format ); + dstlen = (w * h) + ((w*h)/4) + ((w*h)/4); + } + + char header[16]; + snprintf( header,sizeof(header), "%06d%04d%2d", dstlen, args[0],args[1] ); + SEND_DATA(v, header, 12 ); + SEND_DATA(v, vj_perform_get_preview_buffer(), dstlen ); + + free(frame); + +} + diff --git a/veejay-current/veejay-server/veejay/vj-event.h b/veejay-current/veejay-server/veejay/vj-event.h index 315b1d45..10d27951 100644 --- a/veejay-current/veejay-server/veejay/vj-event.h +++ b/veejay-current/veejay-server/veejay/vj-event.h @@ -309,5 +309,7 @@ void vj_event_cali_write_file( void *ptr, const char format[], va_list ap ); void vj_event_stream_new_cali( void *ptr, const char format[], va_list ap ); void vj_event_get_cali_image ( void *ptr, const char format[], va_list ap ); void vj_event_sub_render( void *ptr, const char format[], va_list ap ); - +void vj_event_send_shm_info( void *ptr, const char format[], va_list ap); +void vj_event_connect_split_shm( void *ptr, const char format[], va_list ap ); +void vj_event_get_sample_image(void *ptr,const char format[],va_list ap ); #endif diff --git a/veejay-current/veejay-server/veejay/vj-eventman.c b/veejay-current/veejay-server/veejay/vj-eventman.c index 4a1365e6..8b83388b 100644 --- a/veejay-current/veejay-server/veejay/vj-eventman.c +++ b/veejay-current/veejay-server/veejay/vj-eventman.c @@ -2133,7 +2133,7 @@ void vj_init_vevo_events(void) #ifdef USE_SWSCALER index_map_[VIMS_RGB24_IMAGE] = _new_event( "%d %d", - VIMS_REQUIRE_ALL_PARAMS, + VIMS_RGB24_IMAGE, "GUI: Get preview image (raw RGB24)", vj_event_get_scaled_image, 2, @@ -2143,12 +2143,11 @@ void vj_init_vevo_events(void) "Height", 0, NULL ); - #else #ifdef USE_GDK_PIXBUF index_map_[VIMS_RGB24_IMAGE] = _new_event( "%d %d", - VIMS_REQUIRE_ALL_PARAMS, + VIMS_RGB24_IMAGE, "GUI: Get preview image (raw RGB24)", vj_event_get_scaled_image, 2, @@ -2193,6 +2192,23 @@ void vj_init_vevo_events(void) NULL ); #endif #endif + index_map_[VIMS_GET_SAMPLE_IMAGE] = _new_event( + "%d %d %d %d", + VIMS_GET_SAMPLE_IMAGE, + "GUI: Get preview image from sample (raw RGB24)", + vj_event_get_sample_image, + 4, + VIMS_ALLOW_ANY, + "ID", + 0, + "Type", + 0, + "Width", + 0, + "Height", + 0, + NULL ); + index_map_[VIMS_CHAIN_TOGGLE_ALL] = _new_event( "%d", VIMS_CHAIN_TOGGLE_ALL, @@ -2445,12 +2461,14 @@ void vj_init_vevo_events(void) VIMS_ALLOW_ANY , NULL ); index_map_[VIMS_GET_FRAME] = _new_event( - NULL, + "%d", VIMS_GET_FRAME, "TCP: Send a frame to a connected veejay client", vj_event_send_frame, - 0, + 1, VIMS_ALLOW_ANY, + "Screen ID", + -1, NULL ); index_map_[ VIMS_SUB_RENDER ] = _new_event( @@ -2882,7 +2900,7 @@ void vj_init_vevo_events(void) 0, "greyscale", 0, - NULL ); + NULL ); index_map_[ VIMS_SHM_WRITER ] = _new_event( "%d", @@ -2905,6 +2923,28 @@ void vj_init_vevo_events(void) "Not used yet", 0, NULL ); + index_map_[ VIMS_GET_SHM_EXT ] = _new_event( + "%d", + VIMS_GET_SHM_EXT, + "Write back veejay shared resource info", + vj_event_send_shm_info, + 1, + VIMS_ALLOW_ANY, + "Screen ID", + 0, + NULL ); + + index_map_[ VIMS_SPLIT_CONNECT_SHM ] = _new_event( + "%d", + VIMS_SPLIT_CONNECT_SHM, + "Display splitted screen resource", + vj_event_connect_split_shm, + 1, + VIMS_ALLOW_ANY, + "Key", + 0, + NULL ); + #endif } diff --git a/veejay-current/veejay-server/veejay/vj-lib.h b/veejay-current/veejay-server/veejay/vj-lib.h index 244aaacd..e2eebc04 100644 --- a/veejay-current/veejay-server/veejay/vj-lib.h +++ b/veejay-current/veejay-server/veejay/vj-lib.h @@ -199,6 +199,7 @@ typedef struct { int hold_status; int auto_mute; int pace_correction; + int splitscreen; } video_playback_setup; typedef struct { @@ -326,6 +327,7 @@ typedef struct { void *viewport; void *composite; void *composite2; + void *splitter; int use_vp; int use_proj; int frontback; @@ -336,6 +338,7 @@ typedef struct { int sz; int audio_running; int *rlinks; + int *splitted_screens; int *rmodes; int pause_render; void *shm; diff --git a/veejay-current/veejay-server/veejay/vj-perform.c b/veejay-current/veejay-server/veejay/vj-perform.c index 56431e7b..1dc613cb 100644 --- a/veejay-current/veejay-server/veejay/vj-perform.c +++ b/veejay-current/veejay-server/veejay/vj-perform.c @@ -57,6 +57,8 @@ #include #include #include +#include +#include #define PERFORM_AUDIO_SIZE 16384 @@ -124,15 +126,13 @@ static size_t pribuf_len = 0; static uint8_t *socket_buffer = NULL; static uint8_t *fx_chain_buffer = NULL; static size_t fx_chain_buflen = 0; -static int sbic = 0; static ycbcr_frame *record_buffer = NULL; // needed for recording invisible streams static VJFrame *helper_frame = NULL; static int vj_perform_record_buffer_init(); static void vj_perform_record_buffer_free(); -#ifdef HAVE_LIBRESAMPLE -static ReSampleContext *resample_context[(MAX_SPEED+1)]; -static ReSampleContext *downsample_context[(MAX_SPEED+1)]; -#endif +static void *resample_context[(MAX_SPEED+1)]; +static void *downsample_context[(MAX_SPEED+1)]; + static int last_rate_[2] = { 0, 0 }; static const char *intro = "A visual instrument for GNU/Linux\n"; @@ -808,14 +808,12 @@ static void vj_perform_close_audio() { int i; for(i=0; i <= MAX_SPEED; i ++) { -#ifdef HAVE_LIBRESAMPLE if(resample_context[i]) - audio_resample_close( resample_context[i] ); + vj_audio_resample_close( resample_context[i] ); if(downsample_context[i]) - audio_resample_close( downsample_context[i]); + vj_audio_resample_close( downsample_context[i]); resample_context[i] = NULL; downsample_context[i] = NULL; -#endif } #endif @@ -867,42 +865,40 @@ int vj_perform_init_audio(veejay_t * info) { int out_rate = (info->edit_list->audio_rate * (i+2)); int down_rate = (info->edit_list->audio_rate / (i+2)); -#ifdef HAVE_LIBRESAMPLE - resample_context[i] = av_audio_resample_init( + resample_context[i] = vj_av_audio_resample_init( info->edit_list->audio_chans, info->edit_list->audio_chans, info->edit_list->audio_rate, out_rate, SAMPLE_FMT_S16, SAMPLE_FMT_S16, + 2, MAX_SPEED, - MAX_SPEED, - 0, - 0.8 + 1, + 1.0 ); if(!resample_context[i]) { veejay_msg(VEEJAY_MSG_ERROR, "Cannot initialize audio upsampler for speed %d", i); return 0; } - downsample_context[i] = av_audio_resample_init( + downsample_context[i] = vj_av_audio_resample_init( info->edit_list->audio_chans, info->edit_list->audio_chans, info->edit_list->audio_rate, down_rate, SAMPLE_FMT_S16, SAMPLE_FMT_S16, + 2, MAX_SPEED, - MAX_SPEED, - 0, - 0.8 ); + 1, + 1.0 ); if(!downsample_context[i]) { veejay_msg(VEEJAY_MSG_WARNING, "Cannot initialize audio downsampler for dup %d",i); return 0; } -#endif } return 1; @@ -1164,10 +1160,10 @@ static void long2str(uint8_t *dst, uint32_t n) dst[3] = (n>>24)&0xff; } -static uint32_t vj_perform_compress_frame( veejay_t *info, uint8_t *dst, uint32_t *p1_len, uint32_t *p2_len, uint32_t *p3_len) +static uint32_t vj_perform_compress_frame( veejay_t *info, uint8_t *dst, uint32_t *p1_len, uint32_t *p2_len, uint32_t *p3_len, VJFrame *frame) { - const int len = info->effect_frame1->width * info->effect_frame1->height; - const int uv_len = info->effect_frame1->uv_len; + const int len = frame->len; + const int uv_len = frame->uv_len; uint8_t *dstI = dst + 16; if(lzo_ == NULL ) { @@ -1178,7 +1174,7 @@ static uint32_t vj_perform_compress_frame( veejay_t *info, uint8_t *dst, uint32_ } } - int i = lzo_compress( lzo_ , primary_buffer[info->out_buf]->Y, dstI, p1_len, len ); + int i = lzo_compress( lzo_ , frame->data[0], dstI, p1_len, len ); if( i == 0 ) { veejay_msg(VEEJAY_MSG_ERROR, "Unable to compress Y plane"); @@ -1187,7 +1183,7 @@ static uint32_t vj_perform_compress_frame( veejay_t *info, uint8_t *dst, uint32_ uint32_t size1 = ( *p1_len ); dstI = dst + 16 + (sizeof(uint8_t) * size1 ); - i = lzo_compress( lzo_, primary_buffer[info->out_buf]->Cb, dstI, p2_len, uv_len ); + i = lzo_compress( lzo_, frame->data[1], dstI, p2_len, uv_len ); if( i == 0 ) { veejay_msg(VEEJAY_MSG_ERROR, "Unable to compress U plane"); @@ -1197,7 +1193,7 @@ static uint32_t vj_perform_compress_frame( veejay_t *info, uint8_t *dst, uint32_ uint32_t size2 = ( *p2_len ); dstI = dst + 16 + size1 + size2; - i = lzo_compress( lzo_, primary_buffer[info->out_buf]->Cr, dstI, p3_len, uv_len ); + i = lzo_compress( lzo_, frame->data[2], dstI, p3_len, uv_len ); if( i == 0 ) { veejay_msg(VEEJAY_MSG_ERROR, "Unable to compress V plane"); @@ -1216,89 +1212,134 @@ static uint32_t vj_perform_compress_frame( veejay_t *info, uint8_t *dst, uint32_ void vj_perform_done_s2( veejay_t *info ) { - sbic = 0; info->settings->unicast_frame_sender = 0; } +static int vj_perform_compress_primary_frame_s2(veejay_t *info,VJFrame *frame ) +{ + char info_line[128]; + int data_len = 44; + int sp_w = frame->width; + int sp_h = frame->height; + int sp_uvlen = frame->uv_len; + int sp_len = frame->len; + int sp_format = frame->format; + uint32_t planes[4] = { 0 }; + + if(socket_buffer == NULL ) { + socket_buffer = vj_malloc(RUP8(data_len + (frame->len * 4 ))); + if(socket_buffer == NULL) { + return 0; + } + } + veejay_memset(info_line, 0, sizeof(info_line) ); + uint8_t *sbuf = socket_buffer + (sizeof(uint8_t) * data_len ); + + int compr_ok = vj_perform_compress_frame(info,sbuf, &planes[0], &planes[1], &planes[2], frame); + int total = planes[0] + planes[1] + planes[2] + 16; + if( compr_ok == 0 ) { + planes[0] = sp_len; + planes[1] = sp_uvlen; + planes[2] = planes[1]; + total = 0; + } + + /* peer to peer connection */ + sprintf(info_line, + "%04d%04d%04d%08d%08d%08d%08d", + sp_w, + sp_h, + sp_format, + total, + planes[0], + planes[1], + planes[2] ); + + veejay_memcpy( socket_buffer, info_line, 44 ); + + if( compr_ok == 0 ) + { + if(!info->splitter) { + veejay_memcpy( socket_buffer + 44 , frame->data[0], sp_len); + veejay_memcpy( socket_buffer + 44 + sp_len,frame->data[1], sp_uvlen ); + veejay_memcpy( socket_buffer + 44 + sp_len + sp_uvlen,frame->data[2],sp_uvlen ); + } + else + { + veejay_memcpy( socket_buffer + 44, frame->data[0], sp_len + sp_uvlen + sp_uvlen); + } + data_len += 16 + sp_len + sp_uvlen + sp_uvlen; + + } + else { + data_len += 16 + planes[0] + planes[1] + planes[2]; + } + + return data_len; +} + int vj_perform_send_primary_frame_s2(veejay_t *info, int mcast, int to_mcast_link_id) { - char info_line[128]; - int compr_ok = 0; - uint32_t planes[3] = {0}; - int data_len = 44; - - memset(info_line, 0, sizeof(info_line) ); - - if(socket_buffer == NULL ) - socket_buffer = vj_malloc( - RUP8( info->effect_frame1->width * info->effect_frame1->height * 3 ) - ); - - uint8_t *sbuf = socket_buffer + (sizeof(uint8_t) * data_len ); - - if( sbic == 0 ) { - compr_ok = vj_perform_compress_frame(info,sbuf, &planes[0], &planes[1], &planes[2]); - int total = planes[0] + planes[1] + planes[2] + 16; - if( compr_ok == 0 ) { - planes[0] = info->effect_frame1->width * info->effect_frame1->height; - planes[1] = info->effect_frame1->uv_len; - planes[2] = planes[1]; - veejay_msg(VEEJAY_MSG_WARNING, "Failed to compress frame, sending raw planes: [%d,%d,%d]", - planes[0],planes[1],planes[2] ); - total = 0; - } - sbic = 1; - /* peer to peer connection */ - sprintf(info_line, - "%04d%04d%04d%08d%08d%08d%08d", - info->effect_frame1->width, - info->effect_frame1-> - height,info->effect_frame1->format, - total, - planes[0], - planes[1], - planes[2] ); - - veejay_memcpy( socket_buffer, info_line, 44 ); - if( compr_ok == 0 ) - { - veejay_memcpy( socket_buffer + 44 , primary_buffer[info->out_buf]->Y, info->effect_frame1->len ); - veejay_memcpy( socket_buffer + 44 + info->effect_frame1->len, - primary_buffer[info->out_buf]->Cb, info->effect_frame1->uv_len ); - veejay_memcpy( socket_buffer + 44 + info->effect_frame1->len + info->effect_frame1->uv_len, - primary_buffer[info->out_buf]->Cr, info->effect_frame1->uv_len ); - data_len += 16 + info->effect_frame1->len + (info->effect_frame1->uv_len * 2); - } else { - data_len += 16 + planes[0] + planes[1] + planes[2]; - } - } - - int id = (mcast ? 2: 3); - int __socket_len = data_len; int i; + + if( info->splitter ) { + for ( i = 0; i < VJ_MAX_CONNECTIONS ; i ++ ) { + if( info->rlinks[i] >= 0 ) { + int link_id = info->rlinks[i]; + if( link_id == -1 ) + continue; - if(!mcast) - { - for( i = 0; i < 8 ; i++ ) { - if( info->rlinks[i] != -1 ) { - if(vj_server_send_frame( info->vjs[id], info->rlinks[i], socket_buffer, __socket_len, - info->effect_frame1, info->real_fps )<=0) - { - _vj_server_del_client( info->vjs[id], info->rlinks[i] ); + int screen_id = info->splitted_screens[ i ]; + if( screen_id < 0 ) + continue; + + VJFrame *frame = vj_split_get_screen( info->splitter, screen_id ); + int data_len = vj_perform_compress_primary_frame_s2( info, frame ); + + if( vj_server_send_frame( info->vjs[3], link_id, socket_buffer,data_len, frame, info->real_fps ) <= 0 ) { + _vj_server_del_client( info->vjs[3], link_id ); } - info->rlinks[i] = -1; - } - } - } - else - { - if(vj_server_send_frame( info->vjs[id], to_mcast_link_id, socket_buffer, __socket_len, - info->effect_frame1, info->real_fps )<=0) - { - veejay_msg(VEEJAY_MSG_DEBUG, "Error sending multicast frame."); - } - } + info->rlinks[i] = -1; + info->splitted_screens[i] = -1; + } + } + } + else { + VJFrame fxframe; + veejay_memcpy(&fxframe, info->effect_frame1, sizeof(VJFrame)); + + VJFrame *frame = &fxframe; + fxframe.data[0] = primary_buffer[info->out_buf]->Y; + fxframe.data[1] = primary_buffer[info->out_buf]->Cb; + fxframe.data[2] = primary_buffer[info->out_buf]->Cr; + + int data_len = vj_perform_compress_primary_frame_s2( info,frame ); + + int id = (mcast ? 2: 3); + + if(!mcast) + { + for( i = 0; i < VJ_MAX_CONNECTIONS; i++ ) { + if( info->rlinks[i] != -1 ) { + if(vj_server_send_frame( info->vjs[id], info->rlinks[i], socket_buffer, data_len, + frame, info->real_fps )<=0) + { + _vj_server_del_client( info->vjs[id], info->rlinks[i] ); + } + info->rlinks[i] = -1; + } + } + } + else + { + if(vj_server_send_frame( info->vjs[id], to_mcast_link_id, socket_buffer, data_len, + frame, info->real_fps )<=0) + { + veejay_msg(VEEJAY_MSG_DEBUG, "Error sending multicast frame."); + } + } + } return 1; } @@ -1702,11 +1743,7 @@ int vj_perform_fill_audio_buffers(veejay_t * info, uint8_t *audio_buf, uint8_t * //@ clip sc into range, there isn't a resampler for every speed if( sc < 0 ) sc = 0; else if ( sc > MAX_SPEED ) sc = MAX_SPEED; -#ifdef HAVE_LIBRESAMPLE - n_samples = audio_resample( resample_context[sc],(short*) audio_buf, (short*) sambuf, n_samples ); -#else - n_samples = 0; -#endif + n_samples = vj_audio_resample( resample_context[sc],(short*) audio_buf, (short*) sambuf, n_samples ); } } else if( speed == 0 ) { n_samples = len = pred_len; @@ -1742,13 +1779,9 @@ int vj_perform_fill_audio_buffers(veejay_t * info, uint8_t *audio_buf, uint8_t * int sc = max_sfd - 2; if( sc < 0 ) sc = 0; else if ( sc > MAX_SPEED ) sc = MAX_SPEED; -#ifdef HAVE_LIBRESAMPLE // @ resample buffer - n_samples = audio_resample( downsample_context[ sc ], + n_samples = vj_audio_resample( downsample_context[ sc ], (short*) down_sample_buffer,(short*) audio_buf, n_samples ); -#else - n_samples = 0; -#endif *sampled_down = n_samples / max_sfd; val = n_samples / max_sfd; n_samples = val; @@ -3265,15 +3298,26 @@ static void vj_perform_finish_render( veejay_t *info, video_playback_setup *sett if( settings->composite ) { VJFrame out; veejay_memcpy( &out, info->effect_frame1, sizeof(VJFrame)); + int curfmt = out.format; if( out.ssm ) + { out.format = (info->pixel_format == FMT_422F ? PIX_FMT_YUVJ444P : PIX_FMT_YUV444P ); - + } + + if(!frame->ssm) { chroma_supersample(settings->sample_mode,frame,pri ); frame->ssm = 1; - } + frame->uv_len = frame->len; + frame->format = out.format; + } composite_process(info->composite,&out,info->effect_frame1,settings->composite,frame->format); + + if( settings->splitscreen ) { + composite_process_divert(info->composite,out.data,frame, info->splitter, settings->composite ); + } + // draw font/qr in transformed image if(osd_text ) { VJFrame *tst = composite_get_draw_buffer( info->composite ); @@ -3286,8 +3330,22 @@ static void vj_perform_finish_render( veejay_t *info, video_playback_setup *sett free(tst); } } + + if( frame->ssm ) { + frame->uv_len = frame->uv_width * frame->uv_height; + frame->format = curfmt; + } } else { + + if(settings->splitscreen ) { + if(!frame->ssm) { + chroma_supersample(settings->sample_mode,frame,pri ); + frame->ssm = 1; + } + vj_split_process( info->splitter, frame ); + } + if( osd_text ) vj_font_render_osd_status(info->osd,frame,osd_text,placement); if(more_text) @@ -3298,6 +3356,7 @@ static void vj_perform_finish_render( veejay_t *info, video_playback_setup *sett qrbitcoin_draw( frame, info->homedir, frame->height/4,frame->height/4, frame->format ); } } + if( osd_text) free(osd_text); if( more_text) diff --git a/veejay-current/veejay-server/veejay/vj-sdl.c b/veejay-current/veejay-server/veejay/vj-sdl.c index ea65ab67..e85e5c38 100644 --- a/veejay-current/veejay-server/veejay/vj-sdl.c +++ b/veejay-current/veejay-server/veejay/vj-sdl.c @@ -68,7 +68,7 @@ static int wm_fullscreen(int action, Display *disp, Window *win) { return 1; } */ -static void vj_sdl_move( vj_sdl *vjsdl , int scaled_width, int scaled_height, int x, int y ) +static void vj_sdl_move( vj_sdl *vjsdl , int display_wid, int display_hei, int scaled_width, int scaled_height, int x, int y ) { //@ sw_scale_width is misleading ; it lets SDL use the BES if (scaled_width) @@ -76,25 +76,23 @@ static void vj_sdl_move( vj_sdl *vjsdl , int scaled_width, int scaled_height, in if (scaled_height) vjsdl->sw_scale_height = scaled_height; - int my_bpp = SDL_VideoModeOK( vjsdl->sw_scale_width, vjsdl->sw_scale_height,24, - vjsdl->flags[1] ); + int my_bpp = SDL_VideoModeOK( display_wid, display_hei,24, vjsdl->flags[1] ); if(!my_bpp) { veejay_msg(VEEJAY_MSG_DEBUG, "Requested depth not supported"); return; } - vjsdl->screen = SDL_SetVideoMode( vjsdl->sw_scale_width, vjsdl->sw_scale_height,my_bpp, - vjsdl->flags[1]); + vjsdl->screen = SDL_SetVideoMode( display_wid, display_hei,my_bpp,vjsdl->flags[1]); - vjsdl->rectangle.x = 0; - vjsdl->rectangle.y = 0; + vjsdl->rectangle.x = x; + vjsdl->rectangle.y = y; vjsdl->rectangle.w = scaled_width; vjsdl->rectangle.h = scaled_height; - veejay_msg(VEEJAY_MSG_INFO, "Changed video window to size %d x %d", - vjsdl->sw_scale_width,vjsdl->sw_scale_height); + veejay_msg(VEEJAY_MSG_INFO, "Changed video window to size %d x %d (%dx%d+%dx%d)", display_wid, display_hei, + scaled_width,scaled_height,x,y); } vj_sdl *vj_sdl_allocate(int width, int height, int fmt, int use_key, int use_mouse, int show_cursor) @@ -221,14 +219,18 @@ int vj_sdl_init(int ncpu, vj_sdl * vjsdl, int scaled_width, int scaled_height, c int manual_positioning = 0; /* setup with no window, scale to some wxh+0x0 on fs */ - char *veejay_screen_geom = getenv( "VEEJAY_SCREEN_GEOMETRY" ); - char *veejay_screen_size = getenv( "VEEJAY_SCREEN_SIZE" ); - if( veejay_screen_geom && veejay_screen_size ) { + char *veejay_screen_geom = getenv( "VEEJAY_DESKTOP_GEOMETRY" ); + char *veejay_screen_size = getenv( "VEEJAY_VIDEO_SIZE" ); + char *veejay_screen_pos = getenv( "VEEJAY_VIDEO_POSITION"); + + /* FIXME: check if changes are ok for BigDesktop configurations */ + + if( veejay_screen_geom && veejay_screen_size && veejay_screen_pos ) { extra_flags = extra_flags | SDL_NOFRAME; manual_positioning = 1; } else { extra_fs_flags = SDL_FULLSCREEN; - veejay_msg(VEEJAY_MSG_DEBUG, "env VEEJAY_SCREEN_GEOMETRY and VEEJAY_SCREEN_SIZE not set"); + veejay_msg(VEEJAY_MSG_DEBUG, "env VEEJAY_VIDEO_POSITION, VEEJAY_DESKTOP_GEOMETRY and VEEJAY_VIDEO_SIZE not set"); } #ifdef HAVE_SDL_TTF vjsdl->font = vj_sdl_font_init(); @@ -402,19 +404,21 @@ int vj_sdl_init(int ncpu, vj_sdl * vjsdl, int scaled_width, int scaled_height, c int use_geom = 0; int use_size = 0; int offset_x=0,offset_y=0; + int pos_x=0,pos_y=0; if( veejay_screen_geom ) if( sscanf( veejay_screen_geom, "%dx%d+%dx%d",&new_w,&new_h,&new_x,&new_y) == 4 ) use_geom = 1; - if( veejay_screen_size ) - if( sscanf( veejay_screen_size,"%dx%d",&vid_w,&vid_h) == 2 ) - use_size = 1; + if( veejay_screen_size ) { + if( sscanf( veejay_screen_size,"%dx%d",&vid_w,&vid_h) == 2 ) + use_size = 1; + } if( veejay_screen_size && !use_size ) { veejay_msg(VEEJAY_MSG_ERROR, - "Invalid syntax for VEEJAY_SCREEN_SIZE, use \"x\""); + "Invalid syntax for VEEJAY_VIDEO_SIZE, use \"x\""); veejay_msg(VEEJAY_MSG_ERROR, - " for example: VEEJAY_SCREEN_SIZE=1024x768"); + " for example: VEEJAY_VIDEO_SIZE=1024x768"); } if(!use_size) { @@ -425,38 +429,42 @@ int vj_sdl_init(int ncpu, vj_sdl * vjsdl, int scaled_width, int scaled_height, c } if( veejay_screen_geom && !use_geom) { veejay_msg(VEEJAY_MSG_ERROR, - "Invalid syntax for VEEJAY_SCREEN_GEOMETRY, use\"x+x\""); + "Invalid syntax for VEEJAY_DESKTOP_GEOMETRY, use\"x+x\""); veejay_msg(VEEJAY_MSG_ERROR, - " for example: VEEJAY_SCREEN_GEOMETRY=2624x1024+1600+0 for TwinView/One Big Desktop"); + " for example: VEEJAY_DESKTOP_GEOMETRY=2624x1024+1600+0 for TwinView/One Big Desktop"); veejay_msg(VEEJAY_MSG_ERROR, - " VEEJAY_SCREEN_GEOMETRY=0x0+0+0 for Single Screen Desktops"); + " VEEJAY_DESKTOP_GEOMETRY=0x0+0+0 for Single Screen Desktops"); } + if( veejay_screen_pos ) { + if( sscanf( veejay_screen_pos, "%dx%d", &pos_x, &pos_y ) != 2 ) { + veejay_msg(VEEJAY_MSG_ERROR, "Invalid syntax for VEEJAY_VIDEO_POSITION, use \"x\""); + } + } + + int display_wid = new_w; //DisplayWidth( vjsdl->display, screen ); + int display_hei = new_h; //DisplayHeight( vjsdl->display, screen ); if( fs == 1 ) { - scaled_width = DisplayWidth( vjsdl->display,screen); - scaled_height= DisplayHeight( vjsdl->display,screen); - /* if( use_geom ) { - scaled_width = new_w; - scaled_height = new_h; - }*/ + scaled_width = display_wid; + scaled_height= display_hei; } + if( use_geom ) { offset_x = new_x; offset_y = new_y; - veejay_msg(VEEJAY_MSG_DEBUG, "VEEJAY_SCREEN_GEOMETRY: %dx%d+%dx%d", new_w,new_h,new_x,new_y); + veejay_msg(VEEJAY_MSG_DEBUG, "VEEJAY_DESKTOP_GEOMETRY: %dx%d+%dx%d", new_w,new_h,new_x,new_y); } if( use_size ) { scaled_width = vid_w; scaled_height = vid_h; - veejay_msg(VEEJAY_MSG_DEBUG, "VEEJAY_SCREEN_SIZE: %dx%d", vid_w,vid_h); + veejay_msg(VEEJAY_MSG_DEBUG, "VEEJAY_VIDEO_SIZE: %dx%d", vid_w,vid_h); } veejay_msg(VEEJAY_MSG_INFO, "Size of video window: %dx%d", scaled_width,scaled_height); veejay_msg(VEEJAY_MSG_INFO, "Position : %dx%d", new_x, new_y ); - veejay_msg(VEEJAY_MSG_INFO, "Display size : %dx%d", DisplayWidth(vjsdl->display,screen), - DisplayHeight(vjsdl->display,screen)); + veejay_msg(VEEJAY_MSG_INFO, "Display size : %dx%d", display_wid,display_hei); if( wminfo.subsystem == SDL_SYSWM_X11 ) { @@ -476,27 +484,21 @@ int vj_sdl_init(int ncpu, vj_sdl * vjsdl, int scaled_width, int scaled_height, c wminfo.info.x11.unlock_func(); if(children) free(children); } - vj_sdl_move( vjsdl, scaled_width,scaled_height,new_x,new_y ); + vj_sdl_move( vjsdl, display_wid, display_hei, scaled_width,scaled_height,pos_x,pos_y ); } } - SDL_WM_SetCaption(caption, NULL); + SDL_WM_SetCaption(caption, NULL); if (!vj_sdl_unlock(vjsdl)) return 0; - - /* - we can draw something on the raw surface. - */ - - if(show) + if(show) { - SDL_UpdateRect(vjsdl->screen, 0, 0, vjsdl->rectangle.w, - vjsdl->rectangle.h); + SDL_UpdateRect(vjsdl->screen, 0, 0, vjsdl->rectangle.w, + vjsdl->rectangle.h); } - vjsdl->fs = fs; SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); diff --git a/veejay-current/veejay-server/veejay/vj-share.c b/veejay-current/veejay-server/veejay/vj-share.c index d487c317..229bf859 100644 --- a/veejay-current/veejay-server/veejay/vj-share.c +++ b/veejay-current/veejay-server/veejay/vj-share.c @@ -2,7 +2,7 @@ /* * Linux VeeJay * - * Copyright(C)2002-2011 Niels Elburg + * Copyright(C)2002-2015 Niels Elburg * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -81,7 +81,7 @@ static void vj_flush(vj_client *sayvims,int frames) { int32_t vj_share_pull_master( void *shm, char *master_host, int master_port ) { - unsigned char tmp[64]; + char tmp[64]; vj_client *c = vj_share_connect( master_host, master_port ); if(!c) { veejay_msg(0, "Error connecting to %s:%d",master_host, master_port ); @@ -92,7 +92,7 @@ int32_t vj_share_pull_master( void *shm, char *master_host, int master_port ) vj_client_send( c, V_CMD, (unsigned char*)"425:0;" ); - vj_client_read( c, V_CMD, tmp, 16 ); //@ get SHM id from + vj_client_read( c, V_CMD, (unsigned char*) tmp, 16 ); //@ get SHM id from vj_flush(c,1); @@ -115,4 +115,94 @@ int32_t vj_share_pull_master( void *shm, char *master_host, int master_port ) return key; } +int vj_share_get_info( char *host, int port, int *width, int *height, int *format, int *key, int screen_id ) +{ + char tmp[128]; + vj_client *c = vj_share_connect( host, port ); + if(!c) { + veejay_msg(0, "Error connecting to %s:%d",host,port ); + return 0; + } + + snprintf(tmp,sizeof(tmp),"%03d:%d;", VIMS_GET_SHM_EXT, screen_id ); + vj_client_send( c, V_CMD, (unsigned char*) tmp ); + + memset(tmp,0,sizeof(tmp)); + vj_client_read( c, V_CMD, (unsigned char*) tmp, 3 ); //@ get SHM id from + + int msg_len = 0; + if( sscanf( tmp, "%d", &msg_len ) ) { + + vj_client_read( c, V_CMD, (unsigned char*) tmp, msg_len ); + + sscanf( tmp, "%d %d %d %d", + width,height,format,key ); + } + vj_client_close( c ); + + vj_client_free( c ); + + return 1; +} + + +int vj_share_start_slave( char *host, int port, int shm_id) +{ + char tmp[64]; + vj_client *c = vj_share_connect( host,port ); + if(!c) { + veejay_msg(0, "Error connecting to %s:%d",host, port ); + return 0; + } + + snprintf( tmp,sizeof(tmp), "%03d:%d;", VIMS_SPLIT_CONNECT_SHM, shm_id ); + + vj_client_send( c, V_CMD, (unsigned char*) tmp ); + + vj_client_close( c ); + + vj_client_free( c ); + + return 1; +} + +int vj_share_start_net( char *host, int port, char *master_host, int master_port) +{ + char tmp[64]; + vj_client *c = vj_share_connect( host,port ); + if(!c) { + veejay_msg(0, "Error connecting to %s:%d",host, port ); + return 0; + } + + snprintf( tmp,sizeof(tmp), "%03d:%d %s;",VIMS_STREAM_NEW_UNICAST,master_port, master_host ); + + vj_client_send( c, V_CMD, (unsigned char*) tmp ); + + vj_client_close( c ); + + vj_client_free( c ); + + return 1; +} + +int vj_share_play_last( char *host, int port ) +{ + char tmp[64]; + vj_client *c = vj_share_connect( host,port ); + if(!c) { + veejay_msg(0, "Error connecting to %s:%d",host, port ); + return 0; + } + + snprintf( tmp,sizeof(tmp), "%03d:-1;",VIMS_STREAM_SELECT ); + + vj_client_send( c, V_CMD, (unsigned char*) tmp ); + + vj_client_close( c ); + + vj_client_free( c ); + + return 1; +} diff --git a/veejay-current/veejay-server/veejay/vj-share.h b/veejay-current/veejay-server/veejay/vj-share.h index 0d84e571..81860aa9 100644 --- a/veejay-current/veejay-server/veejay/vj-share.h +++ b/veejay-current/veejay-server/veejay/vj-share.h @@ -1,6 +1,11 @@ #ifndef VJSHARE #define VJSHARE -int32_t vj_share_pull_master( void *shm, char *master_host, int master_port ); +int32_t vj_share_pull_master( void *shm, char *master_host, int master_port ); +int vj_share_get_info( char *host, int port, int *width, int *height, int *format, int *key, int screen_id ); +int vj_share_start_slave( char *host, int port, int shm_id); + +int vj_share_start_net( char *host, int port, char *master_host, int master_port); +int vj_share_play_last( char *host, int port ); #endif diff --git a/veejay-current/veejay-server/veejay/vj-shm.c b/veejay-current/veejay-server/veejay/vj-shm.c index 9e2ac935..cd84671e 100644 --- a/veejay-current/veejay-server/veejay/vj-shm.c +++ b/veejay-current/veejay-server/veejay/vj-shm.c @@ -147,26 +147,20 @@ int vj_shm_read( void *vv , uint8_t *dst[4] ) vj_shared_data *data = (vj_shared_data*) v->sms; int res = pthread_rwlock_rdlock( &data->rwlock ); if( res == -1 ) { - // veejay_msg(0, "%s",strerror(errno)); - return -1; + veejay_msg(0, "%s",strerror(errno)); + return 0; } uint8_t *ptr = ( (uint8_t*) v->sms ) + HEADER_LENGTH; int len = data->header[0] * data->header[1]; //@ - int uv_len = len / 2; - - uint8_t *in[4] = { ptr, ptr + len, ptr + len + uv_len,NULL }; - int strides[4] = { len, uv_len, uv_len,0 }; + uint8_t *in[4] = { ptr, ptr + len, ptr + len + len,NULL }; + int strides[4] = { len, len, len,0 }; vj_frame_copy( in, dst, strides ); -// veejay_memcpy( dst[0], ptr, len ); -// veejay_memcpy( dst[1], ptr + len, uv_len ); -// veejay_memcpy( dst[2], ptr + len + uv_len, uv_len ); - res = pthread_rwlock_unlock( &data->rwlock ); if( res == -1 ) { - // veejay_msg(0, "%s",strerror(errno)); - return -1; + veejay_msg(0, "%s",strerror(errno)); + return 0; } return 0; @@ -207,29 +201,29 @@ int vj_shm_write( void *vv, uint8_t *frame[4], int plane_sizes[4] ) return 0; } -/* -void *vj_shm_new_slave(int shm_id) -{ - int rc = 0; - if( shm_id <= 0 ) { - char *env_id = getenv( "VEEJAY_SHMID" ); - if( env_id == NULL ) { - veejay_msg(0, "Failed to get SHMID, set VEEJAY_SHMID"); - return NULL; - } - shm_id = atoi( env_id ); +void vj_shm_free_slave(void *slave) +{ + vj_shm_t *v = (vj_shm_t*) slave; + + if( shmdt( v->sms ) ) { + veejay_msg(0, "Error detaching from shared resource" ); } + free(v); +} + +void *vj_shm_new_slave(int shm_id) +{ veejay_msg(VEEJAY_MSG_INFO, "Trying SHM_ID %d", shm_id ); - int r = shmget( shm_id, 0, 0666 ); + int r = shmget( shm_id, 0, 0400 ); if( r == -1 ) { veejay_msg(0, "SHM ID '%d' gives error: %s", shm_id, strerror(errno)); return NULL; } - void *ptr = shmat( r, NULL, 0 ); + char *ptr = shmat( r, NULL, 0 ); if( ptr == (char*) (-1) ) { veejay_msg(0, "failed to attach to shared memory %d", shm_id ); @@ -239,7 +233,13 @@ void *vj_shm_new_slave(int shm_id) vj_shm_t *v = (vj_shm_t*) vj_calloc(sizeof( vj_shm_t*)); v->sms = ptr; - //vj_shared_data *data = (vj_shared_data*) &(ptr[0]); + vj_shared_data *data = (vj_shared_data*) &(ptr[0]); + + int palette = data->header[5]; + int width = data->header[0]; + int height = data->header[1]; + + veejay_msg(0, "SHM IN: %d, %d, %d", palette, width,height); v->shm_id = shm_id; @@ -247,7 +247,7 @@ void *vj_shm_new_slave(int shm_id) veejay_msg(VEEJAY_MSG_INFO, "Attached to shared memory segment %d", shm_id ); return v; -}*/ +} static int vj_shm_file_ref_use_this( char *path ) { struct stat inf; @@ -271,8 +271,7 @@ static int vj_shm_file_ref( vj_shm_t *v, const char *homedir ) } if(tries == 0xff) { - veejay_msg(0, "Run out of veejay_shm_out files, cat the files and ipcs/ipcrm any shared memory resources left over by previous processes"); - veejay_msg(0, " --> %s", homedir ); + veejay_msg(0,"Ran out of veejay_shm_out files, please remove them from %s", homedir); return 0; } @@ -282,7 +281,7 @@ static int vj_shm_file_ref( vj_shm_t *v, const char *homedir ) return 0; } - key_t key = ftok( path, tries ); //@ whatever + key_t key = ftok( path, 128 ); if( key == -1 ) { return 0; } @@ -293,7 +292,7 @@ static int vj_shm_file_ref( vj_shm_t *v, const char *homedir ) v->key = key; v->file = strdup( path ); - veejay_msg(VEEJAY_MSG_DEBUG, " --> %s ", path ); + veejay_msg(VEEJAY_MSG_DEBUG, "SHM resource file written to %s ", path ); return 1; } diff --git a/veejay-current/veejay-server/veejay/vj-shm.h b/veejay-current/veejay-server/veejay/vj-shm.h index 68f36e73..57d99ae4 100644 --- a/veejay-current/veejay-server/veejay/vj-shm.h +++ b/veejay-current/veejay-server/veejay/vj-shm.h @@ -23,6 +23,7 @@ #define VJ_SHM int vj_shm_write( void *vv, uint8_t *frame[3], int plane_sizes[3] ); void *vj_shm_new_slave(int shm_id); +void vj_shm_free_slave(void *vv); void *vj_shm_new_master(const char *homedir, VJFrame *frame); int vj_shm_read( void *vv, uint8_t *dst[3] ); int vj_shm_stop( void *vv ); diff --git a/veejay-current/veejay-server/veejay/vj-split.c b/veejay-current/veejay-server/veejay/vj-split.c new file mode 100644 index 00000000..af869c17 --- /dev/null +++ b/veejay-current/veejay-server/veejay/vj-split.c @@ -0,0 +1,655 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RUP8(num)(((num)+8)&~8) +#define LOCALHOST "127.0.0.1" +#define SHM_ADDR_OFFSET 4096 + +/** + * view port of screen + */ +typedef struct +{ + int width; /* src dimensions */ + int height; + + int left; /* crop */ + int right; + int top; + int bottom; + + void *shm; /* box client type */ + void *net; + + int edge_v; /* edge blending vertical distance in pixels */ + int edge_h; /* edge blending horizontal distance in pixels */ + + uint8_t *data; +} v_screen_t; + +typedef struct +{ + VJFrame **frames; /* destination frame */ + v_screen_t **screens; /* screens */ + int n_screens; /* nr of screens */ + int current_id; /* auto identifier */ + int rows; + int columns; + int off_x; + int off_y; +} vj_split_t; + +typedef struct +{ + int resource_id; + pthread_rwlock_t rwlock; + int header[8]; +} vj_shared_data; + +typedef struct +{ + int shm_id; + char *sms; + key_t key; + pthread_rwlock_t rwlock; + vj_shared_data *data; +} vj_split_shm_t; + +typedef struct +{ + int started; + char *hostname; + int port; +} vj_split_net_t; + +static char *server_ip = NULL; +static int server_port = 0; + +void vj_split_set_master(int port) +{ + server_ip = vj_server_my_ip(); + server_port = port; +} + + +static void *vj_split_net_new( char *hostname, int port, int w, int h) +{ + vj_split_net_t *net = (vj_split_net_t*) vj_calloc(sizeof(vj_split_net_t)); + if(!net) + return NULL; + net->hostname = strdup(hostname); + net->port = port; + return (void*) net; +} + +static void *vj_split_shm_new(key_t key, int w, int h) +{ + vj_split_shm_t *shm = NULL; + if( key < 0 ) { + veejay_msg(VEEJAY_MSG_ERROR,"Already in use"); + return NULL; + } + + long shm_size = (w*h*4); + int id = shmget( key, shm_size, IPC_CREAT | 0666 ); + if( id == -1 ) { + veejay_msg(VEEJAY_MSG_ERROR,"Failed to access shared resource %d", key ); + return NULL; + } + + char *sms = shmat( id, NULL, 0 ); + if( sms == NULL || sms == (char*) (-1)) { + veejay_msg(VEEJAY_MSG_ERROR,"Failed to attach to shared resource %d",key); + return NULL; + } + + shm = (vj_split_shm_t*) vj_malloc(sizeof(vj_split_shm_t)); + shm->shm_id = id; + shm->sms = sms; + shm->key = key; + + veejay_memset( shm->sms, 0, SHM_ADDR_OFFSET + (w * h) ); + veejay_memset( shm->sms + SHM_ADDR_OFFSET + (w*h),128, w*h*2); + + shm->data = (vj_shared_data*) &(shm->sms[0]); + + shm->data->header[0] = w; + shm->data->header[1] = h; + shm->data->header[2] = w; + shm->data->header[3] = w; + shm->data->header[4] = w; + shm->data->header[5] = LIVIDO_PALETTE_YUV444P; + + pthread_rwlockattr_t rw_lock_attr; + + int ret = pthread_rwlockattr_init( &rw_lock_attr); + if( ret == -1 ) { + veejay_msg(VEEJAY_MSG_ERROR, "Failed to acquire rwlock on shared resource %d", key ); + shmctl( shm->shm_id, IPC_RMID, NULL ); + free(shm); + return NULL; + } + + ret = pthread_rwlockattr_setpshared( &rw_lock_attr, PTHREAD_PROCESS_SHARED ); + if( ret == -1 ) { + veejay_msg(VEEJAY_MSG_ERROR, "Failed to set PTHREAD_PROCESS_SHARED"); + shmctl( shm->shm_id, IPC_RMID, NULL ); + free(shm); + return NULL; + } + + ret = pthread_rwlock_init( &(shm->data->rwlock), &rw_lock_attr); + if( ret == -1) { + veejay_msg(VEEJAY_MSG_ERROR, "Failed to initialize rw-lock" ); + shmctl( shm->shm_id, IPC_RMID, NULL ); + free(shm); + return NULL; + } + + return (void*) shm; +} + +static void vj_split_shm_destroy(vj_split_shm_t *shm) +{ + vj_shared_data *data = (vj_shared_data*) shm->sms; + + int res = pthread_rwlock_destroy( &(data->rwlock) ); + if(res == -1) { + veejay_msg(VEEJAY_MSG_ERROR,"Failed to destroy rw lock"); + } + + res = shmctl( shm->shm_id, IPC_RMID, NULL ); + if( res == -1 ) { + veejay_msg(VEEJAY_MSG_ERROR,"Failed to remove shared memory segment %x:%d", shm->key,shm->shm_id); + } + + free(shm); +} + +void *vj_split_new_from_file(char *filename, int out_w, int out_h, int vfmt) +{ + FILE *f; + + f = fopen( filename,"r" ); + if( f == NULL ) { + veejay_msg(VEEJAY_MSG_WARNING, "No split screen configured in %s", filename); + return NULL; + } + + char hostname[1024]; + int row=0,col=0,port=0; + int max_col=0,max_row=0; + + void *split = NULL; + + veejay_msg(VEEJAY_MSG_INFO,"Splitted screens configured in %s", filename ); + + while( !feof(f) ) { + + if( fscanf(f,"screen=%dx%d\n", &max_row,&max_col ) ) { + if( (max_row * max_col) > 0 ) { + split = vj_split_init( max_row, max_col ); + } + else { + veejay_msg(VEEJAY_MSG_ERROR,"Invalid row/columns in configuration file" ); + fclose(f); + return NULL; + } + } + + if( fscanf(f,"row=%d col=%d port=%d hostname=%s\n", + &row,&col,&port,hostname) ) { + + if(!split) { + veejay_msg(VEEJAY_MSG_ERROR,"Screen not intialized"); + fclose(f); + return NULL; + } + + vj_split_add_screen( split, hostname, port, row,col, out_w, out_h, vfmt ); + } + } + + fclose(f); + + return split; +} + +/** + * initialize splitted screens + */ +void *vj_split_init( int r, int c ) +{ + vj_split_t *x = (vj_split_t*) vj_calloc( sizeof(vj_split_t) ); + x->frames = (VJFrame**) vj_calloc( sizeof(VJFrame*) * r * c ); + x->screens = (v_screen_t**) vj_calloc( sizeof(v_screen_t*) * r * c ); + x->n_screens = r * c; + x->current_id = 0; + x->rows = r; + x->columns = c; + return (void*) x; +} + +static void vj_split_free_screen( vj_split_t *x, int screen_id ) +{ + if( x->screens[ screen_id ] ) { + + if( x->screens[ screen_id ]->shm ) { + vj_split_shm_destroy( x->screens[ screen_id ]->shm ); + x->screens[ screen_id ]->shm = NULL; + } + + if( x->screens[ screen_id ]->net ) { + vj_split_net_t *net = (vj_split_net_t*) x->screens[ screen_id ]->net; + free(net->hostname); + free(net); + net = NULL; + } + + if(x->screens[screen_id]->data) { + free(x->screens[screen_id]->data); + x->screens[screen_id]->data = NULL; + } + free(x->screens[screen_id]); + x->screens[screen_id] = NULL; + } + + if( x->frames[ screen_id ] ) { + free(x->frames[screen_id]); + x->frames[screen_id] = NULL; + } +} +/** + * free splitted screens + */ +void vj_split_free( void *ptr ) +{ + vj_split_t *x = (vj_split_t*) ptr; + int i; + for( i = 0; i < x->n_screens; i ++ ) { + vj_split_free_screen( x, i ); + } + free(x->frames); + free(x->screens); + free(x); + + x = NULL; +} + +static int vj_split_shm_get( vj_split_shm_t *shm ) +{ + return shm->key; +} + +/** + * create a new splitted screen + * wid,hei,fmt are from input source + */ +static int vj_split_allocate_screen( void *ptr, int screen_id, int wid, int hei,int fmt ) +{ + vj_split_t *x = (vj_split_t*) ptr; + vj_split_free_screen(x, screen_id); + + v_screen_t *box = (v_screen_t*) vj_calloc(sizeof(v_screen_t)); + if( box == NULL ) + return 0; + + x->screens[screen_id] = box; + + VJFrame *dst = yuv_yuv_template( NULL, NULL, NULL, wid,hei,fmt ); + if( dst == NULL ) { + return 0; + } + + box->data = (uint8_t*) vj_malloc( sizeof(uint8_t) * RUP8(dst->len*3)); + + dst->data[0] = box->data; + dst->data[1] = box->data + dst->len; + dst->data[2] = box->data + dst->len + dst->len; + + vj_frame_clear1( dst->data[0], 0, dst->len ); + vj_frame_clear1( dst->data[1], 128, dst->len + dst->len ); + + x->frames[ screen_id ] = dst; + + return 1; +} + +/** + * configure this screen + * + * screen may edge blend by edge_x x edge_y + * screen is w x h pixels in size + * FIXME: x,y unused + */ +int vj_split_configure_screen( void *ptr, int screen_id, int edge_x, int edge_y, int left, int right, int top, int bottom, int w, int h ) +{ + vj_split_t *x = (vj_split_t*) ptr; + v_screen_t *box = x->screens[screen_id]; + + box->edge_h = edge_x; + box->edge_v = edge_y; + box->width = w; + box->height = h; + + box->left = left; + box->right= right; + box->top = top; + box->bottom = bottom; + + return 1; +} + +static char *get_self() +{ + char *path = vj_malloc( 1024 ); + if( path == NULL ) + return NULL; + if( readlink("/proc/self/exe", path, 1024 ) == -1 ) { + free(path); + return NULL; + } + return path; +} +/** + * get shared memory key + */ +static key_t vj_split_suggest_key(int screen_id) +{ + char *progname = get_self(); + if(progname == NULL) + return 0; + + key_t key = ftok( progname, screen_id ); + free(progname); + return key; +} + +/** + * Add a new splitted screen + * + * This routine queries another veejay for its output dimensions and allocates a new screen + * with this information. + * + */ +int vj_split_add_screen( void *ptr, char *hostname, int port, int row, int col, int out_w, int out_h, int fmt ) +{ + vj_split_t *x = (vj_split_t*) ptr; + int use_shm = 0; + + if( strcmp(hostname,"localhost") == 0 || strcmp( hostname,LOCALHOST)== 0 ) { + use_shm = 1; + } + + int w = 0, h = 0, format = 0, rkey = 0; + int screen_id = (x->columns * row) + col; + + int ret = vj_share_get_info( hostname, port, &w, &h, &format, &rkey, screen_id ); + if( ret == 0 ) { + veejay_msg(VEEJAY_MSG_ERROR,"Unable to get screen info from veejay on port %d", port ); + return 0; + } + + ret = vj_split_allocate_screen( ptr, screen_id, w, h, fmt ); + if(ret == 0) { + veejay_msg(VEEJAY_MSG_ERROR,"Screen %d configuration error", screen_id ); + return 0; + } + else { + x->current_id = screen_id; + } + + x->off_y = (h * row); + x->off_x = (w * col); + + int left = x->off_x; + int right = left + w; + int top = x->off_y; + int bottom = top + h; + key_t key = 0; + + if( use_shm ) { + v_screen_t *box = x->screens[ screen_id ]; + box->shm = vj_split_shm_new( vj_split_suggest_key(screen_id), w, h ); + if(box->shm == NULL ) { + veejay_msg(VEEJAY_MSG_ERROR, "Failed to setup shared resource with %s:%d",hostname,port ); + vj_split_free_screen( ptr, screen_id ); + return 0; + } + + key = vj_split_shm_get( (vj_split_shm_t*) box->shm ); + + if( vj_share_start_slave( hostname, port, key) == 0 ) { + veejay_msg(VEEJAY_MSG_ERROR, "Failed to communicate with %s:%d", hostname,port ); + vj_split_free_screen( ptr, screen_id ); + return 0; + } + } + else { + v_screen_t *box = x->screens[ screen_id ]; + box->net = vj_split_net_new( hostname, port, w, h ); + if(box->net == NULL ) { + veejay_msg(VEEJAY_MSG_ERROR, "Failed to setup networked resource with %s:%d", hostname,port ); + vj_split_free_screen(ptr, screen_id); + return 0; + } + + if( vj_share_start_net( hostname,port, server_ip, server_port ) == 0 ) { + veejay_msg(VEEJAY_MSG_ERROR, "Failed to communicate with %s:%d", hostname,port ); + vj_split_free_screen( ptr, screen_id ); + return 0; + } + } + + veejay_msg(VEEJAY_MSG_INFO, + "Screen #%d configuration:",screen_id); + veejay_msg(VEEJAY_MSG_INFO,"\tSize: %dx%d", w,h); + veejay_msg(VEEJAY_MSG_INFO,"\tType: %s", (use_shm == 1 ? "shared memory" : "network" )); + if(use_shm) { + veejay_msg(VEEJAY_MSG_INFO,"\tshm_id: %d (%x)", key,key); + } + veejay_msg(VEEJAY_MSG_INFO,"\tHost: %s:%d", hostname,port ); + veejay_msg(VEEJAY_MSG_INFO,"\tRegion: x0=%d,x1=%d y0=%d,y1=%d",left,right,top,bottom ); + + return vj_split_configure_screen( ptr, screen_id, 0,0,left,right,top,bottom,w,h ); +} + +/** + * copy rectangle [left,right,top,bottom] + */ +#ifdef HAVE_ASM_MMX +static void vj_split_copy_plane_mmx( uint8_t *D, uint8_t *S, int left, int right, int top, int bottom, int w, int h ) +{ + int y = top; + int nxt = 0; + + for( y = top; y < bottom; y ++ ) { + + uint8_t *from = S + (y * w + left); + uint8_t *to = D + nxt; + int len = (right - left); + int i = len >> 6; + len &= 63; + + for( ; i > 0; i -- ) { + __asm__ __volatile__ ( + "movq (%0), %%mm0\n" + "movq 8(%0), %%mm1\n" + "movq 16(%0), %%mm2\n" + "movq 24(%0), %%mm3\n" + "movq 32(%0), %%mm4\n" + "movq 40(%0), %%mm5\n" + "movq 48(%0), %%mm6\n" + "movq 56(%0), %%mm7\n" + "movq %%mm0, (%1)\n" + "movq %%mm1, 8(%1)\n" + "movq %%mm2, 16(%1)\n" + "movq %%mm3, 24(%1)\n" + "movq %%mm4, 32(%1)\n" + "movq %%mm5, 40(%1)\n" + "movq %%mm6, 48(%1)\n" + "movq %%mm7, 56(%1)\n" + + :: "r" (from), "r" (to) : "memory" ); + + from += 64; + to += 64; + } + + __asm__ __volatile__( "emms" ::: "memory" ); + + if( len ) { + register uintptr_t dummy; + __asm__ __volatile__( + "rep; movsb" + : "=&D"(to),"=&S"(from),"=&c"(dummy) + : "0"(to),"1"(from),"2"(len) + : "memory" ); + } + + nxt += (right-left); + } +} +#endif + +static void vj_split_copy_plane( uint8_t *D, uint8_t *S, int left, int right, int top, int bottom, int w, int h ) +{ + int y = top; + int dh = bottom; + int x = 0; + int nxt = 0; +#ifndef HAVE_ASM_MMX + for( y = top; y < dh; y ++ ) { + for( x = left; x < right; x ++ ) { + D[nxt] = S[ y * w + x]; + nxt++; + } + } +#else + vj_split_copy_plane_mmx( D,S,left,right,top,bottom,w,h ); +#endif +} + +/** + * cut a region of interest to a new image + */ +static void vj_split_copy_region( VJFrame *src, VJFrame *dst, v_screen_t *box ) +{ + vj_split_copy_plane( dst->data[0], src->data[0], box->left, box->right, box->top, box->bottom, + src->width, src->height ); + vj_split_copy_plane( dst->data[1], src->data[1], box->left, box->right, box->top, box->bottom, + src->width, src->height ); + vj_split_copy_plane( dst->data[2], src->data[2], box->left, box->right, box->top, box->bottom, + src->width, src->height ); +} + +/** + * lock shared resource, copy pixel blob, unlock shared resource + */ +static int vj_split_push_shm( v_screen_t *screen, VJFrame *frame) +{ + vj_split_shm_t *shm = (vj_split_shm_t*) screen->shm; + + unsigned char *addr = (unsigned char*) shm->sms; + vj_shared_data *data = (vj_shared_data*) shm->sms; + + int res = pthread_rwlock_wrlock( &(data->rwlock) ); + if( res == -1 ) { + veejay_msg(VEEJAY_MSG_ERROR,"Unable to acquire lock on shared resource"); + return 0; + } + + if( data->header[1] != screen->height || data->header[0] != screen->width ) { + veejay_msg(VEEJAY_MSG_ERROR,"Shared resource does not have matching video resolution"); + pthread_rwlock_unlock( &(data->rwlock) ); + return 0; + } + + uint8_t *offset = addr + SHM_ADDR_OFFSET; + uint8_t *Y = offset; + uint8_t *U = Y + (screen->width * screen->height); + uint8_t *V = U + (screen->width * screen->height); + + veejay_memcpy( Y, frame->data[0], frame->len ); + veejay_memcpy( U, frame->data[1], frame->len ); + veejay_memcpy( V, frame->data[2], frame->len ); + + res = pthread_rwlock_unlock( &(data->rwlock)); + if( res == -1 ) { + veejay_msg(VEEJAY_MSG_ERROR,"Failed to unlock shared resource" ); + return 0; + } + + return 1; +} + +/** + * split the image in src to N screens + */ +void vj_split_process( void *ptr, VJFrame *src ) +{ + vj_split_t *x = (vj_split_t*) ptr; + int i; + + for( i = 0; i < x->n_screens; i ++ ) { + if( x->frames[i] == NULL || x->screens[i] == NULL ) + continue; + + vj_split_copy_region( src, x->frames[i], x->screens[i] ); + + if( x->screens[i]->net ) { + vj_split_net_t *net = (vj_split_net_t*) x->screens[i]->net; + if(net->started == 0) { + net->started = vj_share_play_last( net->hostname, net->port ); + } + } + } +} + +/** + * write the screens to the clients + */ +void vj_split_render( void *ptr ) +{ + vj_split_t *x = (vj_split_t*) ptr; + int i; + + for( i = 0; i < x->n_screens; i ++ ) { + if( x->frames[i] == NULL || x->screens[i] == NULL ) + continue; + VJFrame *dst = x->frames[i]; + + if( x->screens[i]->shm ) { + if( vj_split_push_shm( x->screens[i], dst ) == 0 ) { + vj_split_free_screen( ptr, i ); + } + } + } +} + +VJFrame *vj_split_get_screen(void *ptr, int screen_id) +{ + vj_split_t *x = (vj_split_t*) ptr; + if( screen_id < 0 || screen_id >= x->n_screens) + return NULL; + + return x->frames[ screen_id ]; +} diff --git a/veejay-current/veejay-server/veejay/vj-split.h b/veejay-current/veejay-server/veejay/vj-split.h new file mode 100644 index 00000000..eb3da29a --- /dev/null +++ b/veejay-current/veejay-server/veejay/vj-split.h @@ -0,0 +1,35 @@ +/* + * Linux VeeJay + * + * Copyright(C)2015 Niels Elburg + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License , or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 , USA. + */ + +#ifndef V_SPLITSCREEN_H +#define V_SPLITSCREEN_H + + +void *vj_split_new_from_file(char *filename, int w, int h, int fmt); +void vj_split_render( void *ptr ); +void vj_split_process( void *ptr, VJFrame *src ); +int vj_split_auto_configure_screen( void *ptr ); +int vj_split_add_screen( void *ptr,char *hostname, int port, int row, int col, int out_w, int out_h, int fmt ); +int vj_split_configure_screen( void *ptr, int screen_id, int edge_x, int edge_y, int left, int right, int top, int bottom, int w, int h ); +void vj_split_free( void *ptr ); +void *vj_split_init(int r, int c ); +void vj_split_set_master(int port); +VJFrame *vj_split_get_screen(void *ptr, int screen_id); +#endif diff --git a/veejay-current/veejay-server/veejay/vj-viewport.c b/veejay-current/veejay-server/veejay/vj-viewport.c index 828523e3..bb05428c 100644 --- a/veejay-current/veejay-server/veejay/vj-viewport.c +++ b/veejay-current/veejay-server/veejay/vj-viewport.c @@ -136,7 +136,7 @@ typedef struct int32_t tx1,tx2,ty1,ty2; int32_t ttx1,ttx2,tty1,tty2; int mode; - int32_t *buf; +// int32_t *buf; void *sender; uint32_t seq_id; ui_t *ui; @@ -1289,7 +1289,7 @@ void viewport_destroy( void *data ) if( v->map ) free( v->map ); if( v->help ) free( v->help ); if( v->homedir) free(v->homedir); - if( v->buf ) free(v->buf); +// if( v->buf ) free(v->buf); if( v->ui ) { if( v->ui->scaler ) yuv_free_swscaler(v->ui->scaler); @@ -1458,9 +1458,9 @@ void *viewport_get_configuration(void *vv ) o->h0 = v->h0; o->x1 = v->x1; o->x2 = v->x2; - o->x3 = v->x3; - o->x4 = v->x4; - o->y1 = v->y1; + o->x3 = v->x3; + o->x4 = v->x4; + o->y1 = v->y1; o->y2 = v->y2; o->y3 = v->y3; o->y4 = v->y4; @@ -1607,13 +1607,10 @@ void *viewport_init(int x0, int y0, int w0, int h0, int w, int h, int iw, int ih vc->y0 = vc->y0 * sy; vc->w0 = vc->w0 * sx; vc->h0 = vc->h0 * sy; - veejay_msg(VEEJAY_MSG_INFO,"\tQuad : %dx%d+%dx%d",vc->x0,vc->y0,vc->w0,vc->h0 ); - } else { - veejay_msg(VEEJAY_MSG_WARNING, "No or invalid viewport configuration file in %s", homedir ); - veejay_msg(VEEJAY_MSG_WARNING, "Using default values"); - veejay_msg(VEEJAY_MSG_INFO,"\tBacking : %dx%d",w,h); - veejay_msg(VEEJAY_MSG_INFO,"\tRectangle: %dx%d+%dx%d",x0,y0,w0,h0); - } + veejay_msg(VEEJAY_MSG_DEBUG,"\tQuad : %dx%d+%dx%d",vc->x0,vc->y0,vc->w0,vc->h0 ); + } + veejay_msg(VEEJAY_MSG_DEBUG,"\tBacking : %dx%d",w,h); + veejay_msg(VEEJAY_MSG_DEBUG,"\tRectangle: %dx%d+%dx%d",x0,y0,w0,h0); viewport_t *v = (viewport_t*) vj_calloc(sizeof(viewport_t)); v->usermouse[0] = 0.0; @@ -1639,7 +1636,7 @@ void *viewport_init(int x0, int y0, int w0, int h0, int w, int h, int iw, int ih { res = viewport_configure (v, 29.0, 28.0, 70.0, 30.0, - 70.0, 66.0, + 70.0, 66.0, 30.0, 69.0, x0,y0,w0,h0, @@ -1701,7 +1698,7 @@ void *viewport_init(int x0, int y0, int w0, int h0, int w, int h, int iw, int ih // calculate initial view viewport_process( v ); - v->buf = vj_calloc( sizeof(int32_t) * 50000 ); +// v->buf = vj_calloc( sizeof(int32_t) * 50000 ); free(vc); if(v->grid_resolution > 0) @@ -1775,7 +1772,7 @@ void *viewport_clone(void *vv, int new_w, int new_h ) viewport_process( q ); - q->buf = vj_calloc( sizeof(int32_t) * 50000 ); +// q->buf = vj_calloc( sizeof(int32_t) * 50000 ); veejay_msg(VEEJAY_MSG_INFO,"\tConfiguring input:"); veejay_msg(VEEJAY_MSG_INFO, "\tPoints :\t(1) %fx%f (2) %fx%f", q->x1,q->y1,q->x2,q->y2); veejay_msg(VEEJAY_MSG_INFO, "\t :\t(3) %fx%f (4) %fx%f", q->x2,q->y2,q->x3,q->y3); @@ -1806,7 +1803,6 @@ static viewport_config_t *viewport_load_settings( const char *dir, int mode ) FILE *fd = fopen( path, "r" ); if(!fd) { - veejay_msg(0, "Unable to open file %s",path); free(vc); return NULL; } @@ -1815,7 +1811,6 @@ static viewport_config_t *viewport_load_settings( const char *dir, int mode ) if( len <= 0 ) { - veejay_msg(0, "%s is empty", path); free(vc); return NULL; } @@ -1854,14 +1849,14 @@ static viewport_config_t *viewport_load_settings( const char *dir, int mode ) if( n != 21 ) { - veejay_msg(0, "Unable to read %s (file is %d bytes)",path, len ); + veejay_msg(VEEJAY_MSG_ERROR, "Parse error in %s",path ); free(vc); free(buf); return NULL; } free(buf); - veejay_msg(VEEJAY_MSG_INFO, "Projection configuration:"); + veejay_msg(VEEJAY_MSG_INFO, "Projection mapping configuration [%s]", path); veejay_msg(VEEJAY_MSG_INFO, "\tBehaviour:\t%s", (vc->reverse ? "Forward" : "Projection") ); veejay_msg(VEEJAY_MSG_INFO, "\tPoints :\t(1) %fx%f (2) %fx%f", vc->x1,vc->y1,vc->x2,vc->y2); veejay_msg(VEEJAY_MSG_INFO, "\t :\t(3) %fx%f (4) %fx%f", vc->x2,vc->y2,vc->x3,vc->y3); @@ -1904,7 +1899,7 @@ void viewport_save_settings( void *ptr, int frontback ) v->saved_h, v->marker_size, v->grid_mode, - v->initial_active ); + v->initial_active ); int res = fwrite( content, strlen(content), 1, fd ); @@ -2751,10 +2746,8 @@ static void viewport_translate_frame(void *data, uint8_t *plane ) plane[ (dy + y ) * w + dx + x ] = img[ y * u->sw + x ]; } } - } - static void viewport_draw_marker(viewport_t *v, int x, int y, int w, int h, uint8_t *plane ) { int x1 = x - v->marker_size; @@ -2959,35 +2952,29 @@ void viewport_draw_interface_color( void *vdata, uint8_t *img[3] ) viewport_draw_col( v, img[0],img[1],img[2] ); } - void viewport_produce_full_img( void *vdata, uint8_t *img[3], uint8_t *out_img[3] ) { viewport_t *v = (viewport_t*) vdata; - const int len = v->w * v->h; - register const int w = v->w; - register uint32_t i,n; + const int w = v->w; + uint32_t i,n; const int32_t *map = v->map; - uint8_t *inY = img[0]; - uint8_t *inU = img[1]; - uint8_t *inV = img[2]; + const uint8_t *inY = (const uint8_t*) img[0]; + const uint8_t *inU = (const uint8_t*)img[1]; + const uint8_t *inV = (const uint8_t*)img[2]; uint8_t *outY = out_img[0]; uint8_t *outU = out_img[1]; - uint8_t *outV = out_img[2]; - inY[len+1] = 0; - inU[len+1] = 128; - inV[len+1] = 128; + uint8_t *outV = out_img[2]; - register const int32_t tx1 = v->ttx1; - register const int32_t tx2 = v->ttx2; - register const int32_t ty1 = v->tty1; - register const int32_t ty2 = v->tty2; - int x,y; + const int32_t tx1 = v->ttx1; + const int32_t tx2 = v->ttx2; + const int32_t ty1 = v->tty1; + const int32_t ty2 = v->tty2; - y = ty1 * w; - - vj_frame_clear1( outY,0,len); - vj_frame_clear1( outU,128,len); - vj_frame_clear1( outV,128,len); + int x; + int y = ty1 * w; + + vj_frame_clear1( out_img[0], 0, v->w * v->h ); + vj_frame_clear1( out_img[1], 128, v->w * v->h * 2 ); for( y = ty1; y < ty2; y ++ ) { @@ -3000,8 +2987,6 @@ void viewport_produce_full_img( void *vdata, uint8_t *img[3], uint8_t *out_img[3 outV[i] = inV[n]; } } - y = (v->h - ty2 ) * w; - x = ty2 * w; } void viewport_produce_bw_img( void *vdata, uint8_t *img[3], uint8_t *out_img[3], int Yonly) @@ -3011,8 +2996,6 @@ void viewport_produce_bw_img( void *vdata, uint8_t *img[3], uint8_t *out_img[3], return; } - - viewport_t *v = (viewport_t*) vdata; const int len = v->w * v->h; register const int w = v->w; @@ -3029,7 +3012,8 @@ void viewport_produce_bw_img( void *vdata, uint8_t *img[3], uint8_t *out_img[3], int x,y; y = ty1 * w; - veejay_memset( outY,0,len); + + vj_frame_clear1( outY,0,len); for( y = ty1; y < ty2; y ++ ) { @@ -3044,56 +3028,47 @@ void viewport_produce_bw_img( void *vdata, uint8_t *img[3], uint8_t *out_img[3], x = ty2 * w; } -#define pack_yuyv_4pixel( y0,u0,y1,v0 ) (\ - ( (int) y0 ) & 0xff ) +\ - ( (((int) (u0>>1) ) & 0xff) << 8) +\ - ( ((((int) y1) & 0xff) << 16 )) +\ - ( ((((int) (v0>>1)) & 0xff) << 24 )) - -#define pack_yuyv_pixel( y0,u0,u1,y1,v0,v1 ) (\ - ( (int) y0 ) & 0xff ) +\ - ( (((int) ((u0+u1)>>1) ) & 0xff) << 8) +\ - ( ((((int) y1) & 0xff) << 16 )) +\ - ( ((((int) ((v0+v1)>>1)) & 0xff) << 24 )) +#define pack_yuyv_pixel( y0,u0,u1,y1,v0,v1 )\ + ( y0 ) +\ + ( ((u0+u1)>>1)<< 8) +\ + ( (y1 << 16 )) +\ + ( ((v0+v1)>>1)<< 24 ) void viewport_produce_full_img_yuyv( void *vdata, uint8_t *img[3], uint8_t *out_img ) { viewport_t *v = (viewport_t*) vdata; - const int len = v->w * v->h; const int32_t *map = v->map; - register uint8_t *inY = img[0]; - register uint8_t *inU = img[1]; - register uint8_t *inV = img[2]; - register uint32_t *plane_yuyv = (uint32_t*)out_img; - register const int32_t tx1 = v->ttx1; - register const int32_t tx2 = v->ttx2; - register const int32_t ty1 = v->tty1; - register const int32_t ty2 = v->tty2; - register const int w = v->w; - register const int uw = v->w >> 1; - register uint32_t i,x,y; - register int32_t n,m; + const uint8_t *inY = (const uint8_t*) img[0]; + const uint8_t *inU = (const uint8_t*) img[1]; + const uint8_t *inV = (const uint8_t*) img[2]; + const int32_t tx1 = v->ttx1; + const int32_t tx2 = v->ttx2; + const int32_t ty1 = v->tty1; + const int32_t ty2 = v->tty2; + const int w = v->w; + const int uw = v->w >> 1; + + uint32_t *plane_yuyv = (uint32_t*)out_img; + uint32_t i,x,y; + int32_t n,m; - inY[len+1] = 0; // "out of range" pixel value - inU[len+1] = 128; - inV[len+1] = 128; + img[0][v->w * v->h +1] = 0; // "out of range" pixel value + img[1][v->w * v->h +1] = 128; + img[2][v->w * v->h+1] = 128; - yuyv_plane_clear( len*2, plane_yuyv); + yuyv_plane_clear( v->w * v->h * 2, plane_yuyv); for( y = ty1 ; y < ty2; y ++ ) { for( x = tx1; x < tx2; x += 2 ) - { // 4 YUYV pixels out, 8 Y in, 16 UV in + { // 2 YUYV pixels out, 2 Y in, 4 UV in i = y * w ; n = map[ i + x ]; m = map[ i + x + 1]; - plane_yuyv[y * uw + ( (x+1)>>1)] = pack_yuyv_pixel( inY[n], inU[n], inU[m], - inY[m], inV[n], inV[m] ); - + plane_yuyv[y * uw + ( (x+1)>>1)] = pack_yuyv_pixel( inY[n],inU[n],inU[m],inY[m],inV[n],inV[m] ); } } - } void viewport_produce_full_img_packed( void *vdata, uint8_t *img[3], uint8_t *out_img ) @@ -3151,9 +3126,9 @@ void viewport_render( void *vdata, uint8_t *in[3], uint8_t *out[3],int width, in uint8_t *inY = in[0]; uint8_t *inU = in[1]; uint8_t *inV = in[2]; - uint8_t *outY = out[0]; - uint8_t *outU = out[1]; - uint8_t *outV = out[2]; + uint8_t *outY = out[0]; + uint8_t *outU = out[1]; + uint8_t *outV = out[2]; inY[len+1] = 0; inU[len+1] = 128; diff --git a/veejay-current/veejay-server/veejay/vj-viewport.h b/veejay-current/veejay-server/veejay/vj-viewport.h index c181cd86..ff9d409d 100644 --- a/veejay-current/veejay-server/veejay/vj-viewport.h +++ b/veejay-current/veejay-server/veejay/vj-viewport.h @@ -63,6 +63,6 @@ int viewport_get_initial_active( void *vv ); char *viewport_get_my_help(void *vv); int viewport_finetune_coord(void *data, int screen_width, int screen_height,int inc_x, int inc_y); void viewport_save_settings( void *v, int frontback ); - +void viewport_produce_full_img( void *vdata, uint8_t *img[3], uint8_t *out_img[3] ); #endif