diff options
97 files changed, 29709 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aed6cab --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +build_log +*.log +*.pyc +usr +opt +*.o +*.os +*.exe +packages +binaries +*.ipk +*~ +*.lo +*.la +.deps +.libs +Makefile +Makefile.in +build-stamp +config.h +config.status +debian/files +debian/*.substvars +debian/*.install +debian/*.debhelper +debian/gst-plugins-s5pc2xx-dbg/ +debian/gst-plugins-s5pc2xx/ +libtool +src/Makefile +src/Makefile.in +stamp-h1 +aclocal.m4 +config.guess +config.h.in +config.sub +configure +ltmain.sh +m4/libtool.m4 +m4/ltoptions.m4 +m4/ltsugar.m4 +m4/ltversion.m4 @@ -0,0 +1,3 @@ +Jeongmo Yang <jm80.yang@samsung.com> +Sangchul Lee <sc11.lee@samsung.com> +Jonghyuk Choi <jhchoi.choi@samsung.com> @@ -0,0 +1,503 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[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. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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.1 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..454fa1b --- /dev/null +++ b/Makefile.am @@ -0,0 +1,14 @@ +ACLOCAL_AMFLAGS = -I m4 + +SUBDIRS = \ + common \ + camerasrc + +DIST_SUBDIRS = \ + camerasrc + +EXTRA_DIST = \ + configure.ac autogen.sh depcomp + +check: check-exports + diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..d4c6d40 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# you can either set the environment variables AUTOCONF and AUTOMAKE +# to the right versions, or leave them unset and get the RedHat 7.3 defaults + +aclocal -I m4 -I common/m4 +libtoolize --copy --force +autoheader +autoconf +automake --add-missing --copy --foreign + +echo "Now type 'make' to compile $package." + diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..eb00e1a --- /dev/null +++ b/build.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +### WARNING: DO NOT CHANGE CODES from HERE !!! ### +#import setup +cd `dirname $0` +_PWD=`pwd` +pushd ./ > /dev/null +while [ ! -f "./xo-setup.conf" ] +do + cd ../ + SRCROOT=`pwd` + if [ "$SRCROOT" == "/" ]; then + echo "Cannot find xo-setup.conf !!" + exit 1 + fi +done +popd > /dev/null +. ${SRCROOT}/xo-setup.conf +cd ${_PWD} +### WARNING: DO NOT CHANGE CODES until HERE!!! ### + +export VERSION=1.0 + +CFLAGS="${CFLAGS}" + +if [ "$ARCH" == "arm" ]; then + CFLAGS="${CFLAGS} -g -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\"" +else + exit 0 + CFLAGS="${CFLAGS}" +fi + +if [ $1 ]; +then + run make $1 || exit 1 +else + run ./autogen.sh || exit 1 + + if [ "$ARCH" == "arm" ]; + then + BUILDOPTION="" + else + BUILDOPTION="" + fi + + if [[ "x$MACHINE" == "xprotector" && "x$DISTRO" == "xvodafone" ]]; + then + BUILDOPTION="" + fi + + run ./configure --prefix=$PREFIX $BUILDOPTION || exit 1 + run make || exit 1 + run make install || exit 1 + run make_pkg.sh || exit 1 +fi + + diff --git a/camerasrc/Makefile.am b/camerasrc/Makefile.am new file mode 100644 index 0000000..d46fc5c --- /dev/null +++ b/camerasrc/Makefile.am @@ -0,0 +1,10 @@ +# Copyright (c) 2006 Software Laboratory, SAMSUNG Electronics, Inc. +# All rights reserved. +# +# This software is the confidential and proprietary information of +# SAMSUNG Electronics, Inc. ("Confidential Information"). +# You shall not disclose such Confidential Information and shall use it +# only in accordance with the terms of the license agreement you entered into +# with SAMSUNG Electronics. + +SUBDIRS = src diff --git a/camerasrc/src/Makefile.am b/camerasrc/src/Makefile.am new file mode 100644 index 0000000..ecec7e7 --- /dev/null +++ b/camerasrc/src/Makefile.am @@ -0,0 +1,30 @@ +# plugindir is set in configure + +plugin_LTLIBRARIES = libgstcamerasrc.la + +# sources used to compile this plug-in +libgstcamerasrc_la_SOURCES = gstcamerasrccontrol.c \ + gstcamerasrccolorbalance.c \ + camerasrc.c \ + camerasrc-internal.c \ + gstcamerasrc.c + +libgstcamerasrc_la_CFLAGS = $(GST_CFLAGS) \ + $(GST_BASE_CFLAGS) \ + $(GST_VIDEO_FLAGS) \ + $(MMTA_CFLAGS) \ + -I$(srcdir)/include \ + $(GST_INTERFACES_CFLAGS) + + +libgstcamerasrc_la_LIBADD = $(GST_LIBS) \ + $(GST_BASE_LIBS) \ + $(GST_VIDEO_LIBS) \ + $(MMTA_LIBS) \ + -ldl -lpthread -lrt -lm \ + $(GST_INTERFACES_LIBS) + +libgstcamerasrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) + +libgstcamerasrc_la_CPPFLAGS = -I$(srcdir)/include + diff --git a/camerasrc/src/camerasrc-internal.c b/camerasrc/src/camerasrc-internal.c new file mode 100644 index 0000000..e820bd9 --- /dev/null +++ b/camerasrc/src/camerasrc-internal.c @@ -0,0 +1,1463 @@ +/* + * camerasrc + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang <jm80.yang@samsung.com> + * + * 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.1 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., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include <math.h> +#include "camerasrc-internal.h" + +/*#define USE_IOCTL_DEBUG*/ +#if defined (USE_IOCTL_DEBUG) +static char* get_request_name(int request, char* res_str) { + switch (request) { + case VIDIOC_QBUF: + sprintf(res_str, "[VIDIOC_QBUF]"); + break; + case VIDIOC_DQBUF: + sprintf(res_str, "[VIDIOC_DQBUF]"); + break; + case VIDIOC_S_INPUT: + sprintf(res_str, "[VIDIOC_S_INPUT]"); + break; + case VIDIOC_G_INPUT: + sprintf(res_str, "[VIDIOC_G_INPUT]"); + break; + case VIDIOC_S_PARM: + sprintf(res_str, "[VIDIOC_S_PARM]"); + break; + case VIDIOC_G_PARM: + sprintf(res_str, "[VIDIOC_G_PARM]"); + break; + case VIDIOC_S_FMT: + sprintf(res_str, "[VIDIOC_S_FMT]"); + break; + case VIDIOC_G_FMT: + sprintf(res_str, "[VIDIOC_G_FMT]"); + break; + case VIDIOC_REQBUFS: + sprintf(res_str, "[VIDIOC_REQBUFS]"); + break; + case VIDIOC_QUERYBUF: + sprintf(res_str, "[VIDIOC_QUERYBUF]"); + break; + case VIDIOC_STREAMON: + sprintf(res_str, "[VIDIOC_STREAMON]"); + break; + case VIDIOC_STREAMOFF: + sprintf(res_str, "[VIDIOC_STREAMOFF]"); + break; + case VIDIOC_S_CTRL: + sprintf(res_str, "[VIDIOC_S_CTRL] "); + break; + case VIDIOC_G_CTRL: + sprintf(res_str, "[VIDIOC_G_CTRL]"); + break; + case VIDIOC_ENUMINPUT: + sprintf(res_str, "[VIDIOC_ENUMINPUT]"); + break; + case VIDIOC_S_JPEGCOMP: + sprintf(res_str, "[VIDIOC_S_JPEGCOMP]"); + break; + case VIDIOC_G_JPEGCOMP: + sprintf(res_str, "[VIDIOC_G_JPEGCOMP]"); + break; + /* Extension */ + case VIDIOC_S_STROBE: + sprintf(res_str, "[VIDIOC_S_STROBE]"); + break; + case VIDIOC_G_STROBE: + sprintf(res_str, "[VIDIOC_G_STROBE]"); + break; + case VIDIOC_S_RECOGNITION: + sprintf(res_str, "[VIDIOC_S_RECOGNITION]"); + break; + case VIDIOC_G_RECOGNITION: + sprintf(res_str, "[VIDIOC_G_RECOGNITION]"); + break; + case VIDIOC_G_EXIF: + sprintf(res_str, "[VIDIOC_G_EXIF]"); + break; + default: + sprintf(res_str, "[UNKNOWN IOCTL(%x)]", request); + break; + } + + return 0; +} + +#define PRINT_IOCTL_INFO(request, arg) {\ + char res_str[255];\ + get_request_name(request, res_str);\ + camsrc_info("[request : %s, argument address : %x]", res_str, arg);\ +} +#else + +#define PRINT_IOCTL_INFO(request, arg) + +#endif + + +#define LOCK(x) {\ + if(0 != pthread_mutex_lock(&(x->mutex))) {\ + camsrc_error("Mutex lock error");\ + camsrc_assert(0);\ + }\ +} + +#define UNLOCK(x) {\ + if(0 != pthread_mutex_unlock(&(x->mutex))) {\ + camsrc_error("Mutex unlock error");\ + camsrc_assert(0);\ + }\ +} + +#define AF_MUT_LOCK(p) {\ + if(0 != pthread_mutex_lock(&(p->af_mutex))) {\ + camsrc_error("AF Mutex locking error");\ + camsrc_assert(0);\ + }\ +} + +#define AF_MUT_UNLOCK(p) {\ + if(0 != pthread_mutex_unlock(&(p->af_mutex))) {\ + camsrc_error("AF Mutex unlocking error");\ + camsrc_assert(0);\ + }\ +} + +#define SET_CTRL_VAL(cid, in_value) {\ + int err = CAMERASRC_ERR_UNKNOWN;\ + struct v4l2_control control;\ + control.id = cid;\ + control.value = in_value;\ + camsrc_info("[VIDIOC_S_CTRL] >> [%x] request with value %d", cid, in_value); \ + err = _camerasrc_ioctl(handle, VIDIOC_S_CTRL, &control);\ + if(err != CAMERASRC_SUCCESS) {\ + return err;\ + }\ +} + +#define GET_CTRL_VAL(cid, ret_value) {\ + int err = CAMERASRC_ERR_UNKNOWN;\ + struct v4l2_control control;\ + control.id = cid;\ + err = _camerasrc_ioctl(handle, VIDIOC_G_CTRL, &control);\ + if(err != CAMERASRC_SUCCESS) {\ + return err;\ + }\ + ret_value = control.value;\ + camsrc_info("[VIDIOC_G_CTRL] << [%x] request with value %d", cid, ret_value); \ +} + +#define SET_CTRL_VAL_ERR(cid, in_value, err) {\ + struct v4l2_control control;\ + control.id = cid;\ + control.value = in_value;\ + camsrc_info("[VIDIOC_S_CTRL] >> [%x] request with value %d", cid, in_value); \ + _camerasrc_ioctl_with_err(handle, VIDIOC_S_CTRL, &control, &err);\ +} + +#define GET_CTRL_VAL_ERR(cid, ret_value, err) {\ + struct v4l2_control control;\ + control.id = cid;\ + _camerasrc_ioctl_with_err(handle, VIDIOC_G_CTRL, &control, &err);\ + ret_value = control.value;\ + camsrc_info("[VIDIOC_G_CTRL] << [%x] request with value %d", cid, ret_value); \ +} + +/* AF function */ +static int _camerasrc_start_autofocusing(camerasrc_handle_t *handle); +static int _camerasrc_stop_autofocusing(camerasrc_handle_t *handle); +static int _camerasrc_destroy_autofocusing(camerasrc_handle_t *handle); +static int _camerasrc_release_autofocusing(camerasrc_handle_t *handle); + + +int static af_retry_cnt = 0; + +static int _camerasrc_ioctl(camerasrc_handle_t *handle, int request, void *arg) +{ + int fd = handle->dev_fd; + int err; + int nAgain = 10; + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + + LOCK(handle); + + if (handle->check_esd == 1) { + camsrc_warning("ESD shock occured. All device control will success"); + UNLOCK(handle); + return CAMERASRC_SUCCESS; + } + + if (handle->dev_fd == CAMERASRC_DEV_FD_EMERGENCY_CLOSED) { + camsrc_warning("Device emergency closed. All device control will success"); + UNLOCK(handle); + return CAMERASRC_SUCCESS; + } + + PRINT_IOCTL_INFO(request, arg); + +again: + do { + err = ioctl (fd, request, arg); + } while (-1 == err && EINTR == errno); + + if (err != 0) { + handle->errnum = errno; + err = errno; + strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("ioctl[%x] err : %s", request, err_msg); + if (err == EEXIST) { + camsrc_info("EEXIST occured, but can go."); + err = 0; + } else if (err == ENOENT) { + camsrc_info("ENOENT occured, but can go."); + err = 0; +#if defined (ENABLE_Q_ERROR) +#warning "ENABLE_Q_ERROR enabled" + } else if (request == VIDIOC_DQBUF) { + goto DQ_ERROR; + } else if (request == VIDIOC_QBUF) { + goto ENQ_ERROR; +#endif + } else if (err == EINVAL) { + camsrc_error("EINVAL occured, Shutdown"); + UNLOCK(handle); + return CAMERASRC_ERR_INVALID_PARAMETER; + } else if (err == EBUSY) { + camsrc_error("EBUSY occured, Shutdown"); + UNLOCK(handle); + return CAMERASRC_ERR_PRIVILEGE; + } else if (err == EAGAIN && nAgain--) { + goto again; + } else { + /* Why does this return SUCCESS? */ + camsrc_error("Unhandled exception occured on IOCTL"); + } + } + + UNLOCK(handle); + + return CAMERASRC_SUCCESS; + +#if defined (ENABLE_Q_ERROR) +DQ_ERROR: + camsrc_error("DQ Frame error occured"); + printf("DQ Frame error occured"); + UNLOCK(handle); + return CAMERASRC_ERR_INTERNAL; + +ENQ_ERROR: + camsrc_error("Q Frame error occured"); + printf("Q Frame error occured"); + UNLOCK(handle); + return CAMERASRC_ERR_INTERNAL; +#endif +} + + +static int _camerasrc_ioctl_with_err(camerasrc_handle_t *handle, int request, void *arg, int *error) +{ + int fd = handle->dev_fd; + int err; + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + + LOCK(handle); + + *error = 0; + + if (handle->check_esd == 1) { + camsrc_warning("ESD shock occured. All device control will success"); + UNLOCK(handle); + return CAMERASRC_SUCCESS; + } + + if (handle->dev_fd == CAMERASRC_DEV_FD_EMERGENCY_CLOSED) { + camsrc_warning("Device emergency closed. All device control will success"); + UNLOCK(handle); + return CAMERASRC_SUCCESS; + } + + PRINT_IOCTL_INFO(request, arg); + + do { + err = ioctl (fd, request, arg); + } while (-1 == err && EINTR == errno); + + if (err != 0) { + handle->errnum = errno; + *error = errno; + strerror_r(*error, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("ioctl[%x] err : %s", request, err_msg); + UNLOCK(handle); + return CAMERASRC_ERR_IO_CONTROL; + } + + UNLOCK(handle); + + return CAMERASRC_SUCCESS; +} + + +static int _camerasrc_ioctl_once(camerasrc_handle_t *handle, int request, void *arg) +{ + int fd = handle->dev_fd; + int err = -1; + int nAgain = 10; + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + + LOCK(handle); + + if (handle->check_esd == 1) { + camsrc_warning("ESD shock occured. All device control will success"); + UNLOCK(handle); + return CAMERASRC_SUCCESS; + } + + if (handle->dev_fd == CAMERASRC_DEV_FD_EMERGENCY_CLOSED) { + camsrc_warning("Device emergency closed. All device control will success"); + UNLOCK(handle); + return CAMERASRC_SUCCESS; + } + + PRINT_IOCTL_INFO(request, arg); + +again: + err = ioctl (fd, request, arg); + + if (err != 0) { + handle->errnum = errno; + err = errno; + strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("ioctl[%x] err : %s", request, err_msg); + if (err == EEXIST) { + camsrc_info("EEXIST occured, but can go."); + err = 0; + } else if (err == ENOENT) { + camsrc_info("ENOENT occured, but can go."); + err = 0; +#if defined (ENABLE_Q_ERROR) +#warning "ENABLE_Q_ERROR enabled" + } else if (request == VIDIOC_DQBUF) { + goto DQ_ERROR; + } else if (request == VIDIOC_QBUF) { + goto ENQ_ERROR; +#endif + } else if (err == EINVAL) { + camsrc_error("EINVAL occured, Shutdown"); + UNLOCK(handle); + return CAMERASRC_ERR_INVALID_PARAMETER; + } else if (err == EAGAIN && nAgain--) { + goto again; + } else { + camsrc_error("Unhandled exception occured on IOCTL"); + } + } + + UNLOCK(handle); + + return CAMERASRC_SUCCESS; + +#if defined (ENABLE_Q_ERROR) +DQ_ERROR: + camsrc_error("DQ Frame error occured"); + printf("DQ Frame error occured"); + UNLOCK(handle); + return CAMERASRC_ERR_INTERNAL; + +ENQ_ERROR: + camsrc_error("Q Frame error occured"); + printf("Q Frame error occured"); + UNLOCK(handle); + return CAMERASRC_ERR_INTERNAL; +#endif +} + + +static int _camerasrc_skip_frame(camerasrc_handle_t *handle, long int timeout, int skip_frame) +{ + camerasrc_handle_t *p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + fd_set fds; + struct timeval tv; + int r; + int skip_frame_num = skip_frame; + + camsrc_error("enter"); + + p = handle; + + while (skip_frame_num--) { + camsrc_error("SKIP FRAME #%d", skip_frame-skip_frame_num+1); + + struct v4l2_buffer buf; + + FD_ZERO (&fds); + FD_SET (p->dev_fd, &fds); + + camsrc_error("************Still capture wait frame start"); + + /* Timeout. */ + tv.tv_sec = (long int)timeout/1000; + tv.tv_usec = timeout - tv.tv_sec * 1000; + + r = select (p->dev_fd + 1, &fds, NULL, NULL, &tv); + + if (-1 == r) { + if (EINTR == errno) { + return CAMERASRC_SUCCESS; + } + camsrc_error("select() failed."); + return CAMERASRC_ERR_INTERNAL; + } + + if (0 == r) { + camsrc_error("select() timeout."); + return CAMERASRC_ERR_DEVICE_WAIT_TIMEOUT; + } + + /**@note from samsung camera sample. *****************************************/ + /*SKIP FRAME START*/ + CLEAR(buf); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = p->buffer_idx; + + if (-1 == _camerasrc_ioctl (p, VIDIOC_DQBUF, &buf)) { + switch (errno) { + case EAGAIN: + camsrc_info("VIDIOC_DQBUF [EAGAIN]"); + return CAMERASRC_SUCCESS; + case EIO: + /* Could ignore EIO, see spec. */ + /* fall through */ + camsrc_info("VIDIOC_DQBUF [EIO]"); + default: + camsrc_info("VIDIOC_DQBUF [%d]", errno); + return CAMERASRC_ERR_IO_CONTROL; + } + } + + if (-1 == _camerasrc_ioctl (p, VIDIOC_QBUF, &buf)) { + return CAMERASRC_ERR_IO_CONTROL; + } + } + + camsrc_error("leave"); + err = CAMERASRC_SUCCESS; + + return err; +} + +static int _camerasrc_init_autofocusing_mode(camerasrc_handle_t *handle) +{ + int ctrl_id = V4L2_CID_FOCUS_AUTO_MODE; + int mode; + + camsrc_info("enter"); + + if (handle->af_status == CAMERASRC_AUTO_FOCUS_STATUS_ONGOING) { + camsrc_info("Dev BUSY. Init failed."); + return CAMERASRC_ERR_INVALID_STATE; + } + + switch (handle->cur_af_mode) { + case CAMERASRC_AF_MODE_AUTO: + mode = V4L2_FOCUS_AUTO_NORMAL; + camsrc_info("ON AUTOFOCUSING...BY AUTO"); + break; + case CAMERASRC_AF_MODE_MANUAL: + ctrl_id = V4L2_CID_FOCUS_MODE; + mode = V4L2_FOCUS_MODE_MANUAL; + camsrc_info("ON AUTOFOCUSING...BY MANUAL"); + break; + case CAMERASRC_AF_MODE_CONTINUOUS: + mode = V4L2_FOCUS_AUTO_CONTINUOUS; + camsrc_info("ON AUTOFOCUSING...BY CONTINUOUS"); + if (handle->format.pix_format != CAMERASRC_PIX_NV12 && + handle->format.pix_format != CAMERASRC_PIX_SN12) { + camsrc_info("DO NOT CONTINUOUS AF when NV12 or SN12 format"); + return CAMERASRC_SUCCESS; + } + break; + case CAMERASRC_AF_MODE_TOUCH_AUTO: + mode = V4L2_FOCUS_AUTO_RECTANGLE; + camsrc_info("ON AUTOFOCUSING...BY TOUCH AUTO"); + break; + case CAMERASRC_AF_MODE_PAN: + camsrc_warning("PAN MODE focusing is not supported."); + default: + camsrc_warning("Unsupported AF mode[%d]", handle->cur_af_mode ); + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + } + + /* MACRO is prior than other setting. FIXME */ + if (handle->cur_af_range == CAMERASRC_AF_RANGE_MACRO) { + mode = V4L2_FOCUS_AUTO_MACRO; + camsrc_info("ON AUTOFOCUSING...BY MACRO"); + } + + SET_CTRL_VAL(ctrl_id, mode); + + /* Start AF if continuous mode and preview is running */ + if (mode == V4L2_FOCUS_AUTO_CONTINUOUS && + handle->cur_state >= CAMERASRC_STATE_PREVIEW) { + _camerasrc_start_autofocusing(handle); + } + + return CAMERASRC_SUCCESS; +} + +static void __CAMERASRC_FUJITSU_GET_AF_CTRL_VAL(camerasrc_handle_t* handle, int* status) +{ + int err = 0; + + if (af_retry_cnt >= (int)CAMERASRC_AF_TOTALTIME/CAMERASRC_AF_INTERVAL) { + *status = CAMERASRC_SENSOR_AF_STATUS_FAILED; + af_retry_cnt = 0; + return; + } else { + af_retry_cnt++; + camsrc_info("retry count = %d", af_retry_cnt); + } + + SET_CTRL_VAL_ERR(V4L2_CID_CAMERA_SET_AUTO_FOCUS, 1, err); + switch (err) { + case 0: + camsrc_info("Succeeded"); + *status = CAMERASRC_SENSOR_AF_STATUS_FOCUSED; + af_retry_cnt = 0; + break; + case EBUSY: + camsrc_info("Busy"); + *status = CAMERASRC_SENSOR_AF_STATUS_ONGOING; + break; + default: + camsrc_info("Failed"); + *status = CAMERASRC_SENSOR_AF_STATUS_FAILED; + af_retry_cnt = 0; + break; + } + + return; +} + +static void* _camerasrc_run_autofocusing(camerasrc_handle_t *handle) +{ + int err = 0; + int sensor_status = 0; + + camsrc_info("enter"); + + while(1) { + AF_MUT_LOCK(handle); + switch (handle->af_cmd) { + case CAMERASRC_AUTO_FOCUS_CMD_START: + { + camsrc_info("AF CMD:START"); + __CAMERASRC_FUJITSU_GET_AF_CTRL_VAL(handle, &sensor_status); + + switch (sensor_status) { + case CAMERASRC_SENSOR_AF_STATUS_ONGOING: + camsrc_info("FOCUSING. IN PROGRESS..."); + handle->af_status = CAMERASRC_AUTO_FOCUS_STATUS_ONGOING; + break; + case CAMERASRC_SENSOR_AF_STATUS_FOCUSED: /* focus operation success. Go to Null. */ + camsrc_info("FOCUSED. stop autofocusing..."); + + handle->af_status = CAMERASRC_AUTO_FOCUS_STATUS_RELEASED; + handle->af_cmd = CAMERASRC_AUTO_FOCUS_CMD_NULL; + + CAMERASRC_SET_STATE(handle, CAMERASRC_STATE_PREVIEW); + + if (handle->af_cb != NULL) { + if (handle->af_usr_data != NULL) { + handle->af_cb(handle, CAMERASRC_AUTO_FOCUS_RESULT_FOCUSED, handle->af_usr_data); + } else { + handle->af_cb(handle, CAMERASRC_AUTO_FOCUS_RESULT_FOCUSED, NULL); + } + } + + AF_MUT_UNLOCK(handle); + continue; + case CAMERASRC_SENSOR_AF_STATUS_FAILED: /* focus operation failed. Set stop and go to NULL. */ + camsrc_info("FOCUSING FAILED"); + + if (handle->cur_af_mode != CAMERASRC_AF_MODE_CONTINUOUS ) { + SET_CTRL_VAL_ERR(V4L2_CID_CAMERA_SET_AUTO_FOCUS, 0, err); + camsrc_info("Stopping AF done. err = %d", err); + } + + handle->af_status = CAMERASRC_AUTO_FOCUS_STATUS_RELEASED; + handle->af_cmd = CAMERASRC_AUTO_FOCUS_CMD_NULL; + + CAMERASRC_SET_STATE(handle, CAMERASRC_STATE_PREVIEW); + + if (handle->af_cb != NULL) { + if(handle->af_usr_data != NULL) { + handle->af_cb(handle, CAMERASRC_AUTO_FOCUS_RESULT_FAILED, handle->af_usr_data); + } else { + handle->af_cb(handle, CAMERASRC_AUTO_FOCUS_RESULT_FAILED, NULL); + } + } + + AF_MUT_UNLOCK(handle); + continue; + default: + camsrc_error("Unrecognizable status"); + break; + } + break; + } + case CAMERASRC_AUTO_FOCUS_CMD_STOP: + { + camsrc_info("AF CMD:STOP"); + SET_CTRL_VAL_ERR(V4L2_CID_CAMERA_SET_AUTO_FOCUS, 0, err); + handle->af_status = CAMERASRC_AUTO_FOCUS_STATUS_RELEASED; + handle->af_cmd = CAMERASRC_AUTO_FOCUS_CMD_NULL; + camsrc_info("Stopping AF done. err = %d", err); + AF_MUT_UNLOCK(handle); + continue; + } + case CAMERASRC_AUTO_FOCUS_CMD_KILL: + { + camsrc_info("AF CMD:KILL"); + + SET_CTRL_VAL_ERR(V4L2_CID_CAMERA_SET_AUTO_FOCUS, 0, err); + camsrc_info("Stopping AF done. err = %d", err); + + handle->af_status = CAMERASRC_AUTO_FOCUS_STATUS_RELEASED; + handle->af_cmd = CAMERASRC_AUTO_FOCUS_CMD_NULL; + + AF_MUT_UNLOCK(handle); + goto OUT_OF_LOOP; + } + case CAMERASRC_AUTO_FOCUS_CMD_NULL: + default: + { + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + camsrc_info("AF CMD:NULL...."); + err = pthread_cond_wait(&handle->af_wait_cond, &handle->af_mutex); + if (err) { + strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("AF CMD pthread_cond_wait - err:(%s)", err_msg); + } + + af_retry_cnt = 0; + + /* Start AF delay for AE */ + if (handle->af_cmd == CAMERASRC_AUTO_FOCUS_CMD_START) { + struct timeval cur_time; + int sec = 0; + int usec = 0; + int diff = 0; /* msec */ + int sleep_time = 0; /* usec */ + + SET_CTRL_VAL_ERR(V4L2_CID_CAMERA_SET_AUTO_FOCUS, 0, err); + + camsrc_info("Check set AF area Time(Delay:%d)", CAMERASRC_AF_DELAY_AFTER_SET_AF_AREA); + + if (handle->set_af_area_time.tv_sec != 0) { + gettimeofday(&cur_time, NULL); + sec = cur_time.tv_sec - handle->set_af_area_time.tv_sec; + usec = cur_time.tv_usec - handle->set_af_area_time.tv_usec; + + camsrc_info("diff sec:%d, usec:%d", sec, usec); + diff = (sec * 1000) + (usec / 1000); + + /* Skip sleep if diff is less than zero or greater than minimum exposure time */ + if (diff < 0 || diff > CAMERASRC_AF_DELAY_AFTER_SET_AF_AREA) { + camsrc_info("no need to sleep(diff: %d ms)", diff); + } else { + sleep_time = (CAMERASRC_AF_DELAY_AFTER_SET_AF_AREA - diff) * 1000; + camsrc_info("usleep(%d)", sleep_time); + usleep(sleep_time); + } + } + } + + AF_MUT_UNLOCK(handle); + continue; + } + } + + AF_MUT_UNLOCK(handle); + usleep(CAMERASRC_AF_INTERVAL); + } + +OUT_OF_LOOP: + camsrc_info("AF thread is finished."); + return NULL; +} + +static int _camerasrc_start_autofocusing(camerasrc_handle_t *handle) +{ + int err; + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + camsrc_info("enter"); + + AF_MUT_LOCK(handle); + + handle->af_cmd = CAMERASRC_AUTO_FOCUS_CMD_START; + err = pthread_cond_signal(&handle->af_wait_cond); + if (err) { + strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_info("AF wait cond err(%s)", err_msg); + } + + AF_MUT_UNLOCK(handle); + + return CAMERASRC_SUCCESS; +} + +static int _camerasrc_stop_autofocusing(camerasrc_handle_t *handle) +{ + int err; + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + + camsrc_info("enter"); + + AF_MUT_LOCK(handle); + + handle->af_cmd = CAMERASRC_AUTO_FOCUS_CMD_STOP; + err = pthread_cond_signal(&handle->af_wait_cond); + if (err) { + strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_info("AF wait cond err(%s)", err_msg); + } + + AF_MUT_UNLOCK(handle); + + return CAMERASRC_SUCCESS; +} + +static int _camerasrc_destroy_autofocusing(camerasrc_handle_t *handle) +{ + int err; + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + camsrc_info("enter"); + + AF_MUT_LOCK(handle); + + handle->af_cmd = CAMERASRC_AUTO_FOCUS_CMD_KILL; + err = pthread_cond_signal(&handle->af_wait_cond); + if (err) { + strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_info("AF wait cond err(%s)", err_msg); + } + + AF_MUT_UNLOCK(handle); + + return CAMERASRC_SUCCESS; +} + +static int _camerasrc_release_autofocusing(camerasrc_handle_t *handle) +{ + int err; + camsrc_info("enter"); + + SET_CTRL_VAL_ERR(V4L2_CID_CAMERA_SET_AUTO_FOCUS, 0, err); + + return CAMERASRC_SUCCESS; +} + +static int _camerasrc_copy_frame(camerasrc_handle_t *handle, camerasrc_buffer_t *src_buffer, camerasrc_buffer_t *dst_buffer, int isThumbnail) +{ + if (handle == NULL || src_buffer == NULL || dst_buffer == NULL) { + camsrc_error("handle[%p], src_buffer[%p], dst_buffer[%p]", + handle, src_buffer, dst_buffer); + return CAMERASRC_ERR_NULL_POINTER; + } + + if (src_buffer->start == NULL || dst_buffer->start == NULL) { + camsrc_error("src_buffer->start[%p], dst_buffer->start[%p]", + src_buffer->start, dst_buffer->start); + return CAMERASRC_ERR_NULL_POINTER; + } + + if (handle->format.colorspace == CAMERASRC_COL_RAW) { + int cpy_len; + + if (handle->format.pix_format == CAMERASRC_PIX_YUV422P || + handle->format.pix_format == CAMERASRC_PIX_YUY2 || + handle->format.pix_format == CAMERASRC_PIX_UYVY) { + cpy_len = (YUV422_SIZE(handle)>=src_buffer->length)?src_buffer->length:YUV422_SIZE(handle); + } else if (handle->format.pix_format == CAMERASRC_PIX_YUV420P || + handle->format.pix_format == CAMERASRC_PIX_YUV420 || + handle->format.pix_format == CAMERASRC_PIX_NV12) { + cpy_len = (YUV420_SIZE(handle)>=src_buffer->length)?src_buffer->length:YUV420_SIZE(handle); + } else { + camsrc_error("UNSUPPORTED format [%x]", handle->format.pix_format ); + return CAMERASRC_ERR_INVALID_FORMAT; + } + +#if defined (USE_FRAME_COPY_BOUNDARY_CHECK) + camsrc_info("Boundary check %p ~ %p ... [length = %d] ", dst_buffer->start, dst_buffer->start+cpy_len, cpy_len); + memset(dst_buffer->start, 0, cpy_len); + camsrc_info("Boundary check OK"); +#endif + + camsrc_info("RAW frame dequeing..."); + dst_buffer->length = cpy_len; + + if (handle->format.pix_format == CAMERASRC_PIX_SN12) { + camsrc_error("Can't copy the frame with SN12 option"); + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + } else if (handle->format.pix_format == CAMERASRC_PIX_ST12) { + camsrc_error("Can't copy the frame with ST12 option"); + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + } + + camsrc_error("format[%d] copy occured. copy len = %d", handle->format.pix_format, cpy_len); + memcpy(dst_buffer->start, src_buffer->start, cpy_len ); + } else if (handle->format.colorspace == CAMERASRC_COL_JPEG) { +#if defined (USE_FRAME_COPY_BOUNDARY_CHECK) + camsrc_info("Boundary check %p ~ %p ...", dst_buffer->start, dst_buffer->start+src_buffer->length); + memset(dst_buffer->start, 0, src_buffer->length); + camsrc_info("Boundary check OK"); +#endif + + if (!isThumbnail) { + if (src_buffer->length <= 0) { + camsrc_error("length[%d] is too small", src_buffer->length ); + return CAMERASRC_ERR_INVALID_VALUE; + } + + dst_buffer->length = src_buffer->length; + camsrc_info("JPEG main frame copy... img length = %d", dst_buffer->length); + memcpy(dst_buffer->start, src_buffer->start, dst_buffer->length); + camsrc_info("JPEG main frame copy done."); + } else { + if (handle->format.pix_format == CAMERASRC_PIX_RGGB8) { + /* JPEG + JPEG */ + if (src_buffer->length <= 0) { + camsrc_error("length[%d] is too small", src_buffer->length ); + return CAMERASRC_ERR_INVALID_VALUE; + } + + dst_buffer->length = src_buffer->length; + camsrc_info("JPEG thm frame(JPEG) copy... img length = %d", dst_buffer->length); + memcpy(dst_buffer->start, src_buffer->start, dst_buffer->length); + camsrc_info("JPEG thm frame(JPEG) copy done."); + } else if (handle->format.pix_format == CAMERASRC_PIX_RGGB10) { + /* JPEG + YUV */ + dst_buffer->length = CAMERASRC_YUV_THMBNL_SIZE; + camsrc_info("JPEG thm frame(YUV) copy... img length = %d", CAMERASRC_YUV_THMBNL_SIZE); + memcpy(dst_buffer->start, src_buffer->start, CAMERASRC_YUV_THMBNL_SIZE); + camsrc_info("JPEG thm frame(YUV) copy done."); + } else { + camsrc_info("Unknown format [%d]", handle->format.pix_format ); + return CAMERASRC_ERR_INVALID_FORMAT; + } + } + } + + return CAMERASRC_SUCCESS; +} + + +static int _camerasrc_set_thumbnail_size(camerasrc_handle_t *handle) +{ + camsrc_info("enter"); + + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +} + +static int _camerasrc_start_facedetection (camerasrc_handle_t *handle) +{ + camsrc_info("enter"); + camsrc_info("FACE DETECTION START!"); + SET_CTRL_VAL(V4L2_CID_FACE_DETECTION, CAM_FACE_DETECTION_ON); + camsrc_info("leave"); + return CAMERASRC_SUCCESS; +} + + +static int _camerasrc_stop_facedetection (camerasrc_handle_t *handle) +{ + camsrc_info("enter"); + camsrc_info("FACE DETECTION STOP!"); + SET_CTRL_VAL(V4L2_CID_FACE_DETECTION, CAM_FACE_DETECTION_OFF); + camsrc_info("leave"); + return CAMERASRC_SUCCESS; +} + + +static int _camerasrc_check_emp_shock(camerasrc_handle_t *handle, int *check_val) +{ + camsrc_info("enter"); + int ret_value = 0; + + GET_CTRL_VAL(V4L2_CID_ESD_INT, ret_value); + *check_val = ret_value; + + camsrc_info("leave"); + return CAMERASRC_SUCCESS; +} + + +static int _camerasrc_get_frame_data(camerasrc_handle_t *handle, camerasrc_frame_data_t *data) +{ + /*camsrc_info("enter");*/ + int err = CAMERASRC_ERR_UNKNOWN; + struct v4l2_control control; + + /* Get Y physical address */ + /*camsrc_info("[VIDIOC_G_CTRL] << [V4L2_CID_PADDR_Y] request with value");*/ + control.id = V4L2_CID_PADDR_Y; + control.value = data->index; + err = _camerasrc_ioctl(handle, VIDIOC_S_CTRL, &control); + if (err != CAMERASRC_SUCCESS) { + return err; + } + + data->phyAddrY = control.value; + + /* Get CbCr physical address */ + /*camsrc_info("[VIDIOC_G_CTRL] << [V4L2_CID_PADDR_CBCR] request with value");*/ + control.id = V4L2_CID_PADDR_CBCR; + control.value = data->index; + err = _camerasrc_ioctl(handle, VIDIOC_S_CTRL, &control); + if (err != CAMERASRC_SUCCESS) { + return err; + } + + data->phyAddrCbCr = control.value; + + /* Distance between Y ptr and CbCr ptr of virtual address is same with that of Physical one. */ + data->virAddrY = (unsigned int)handle->buffer[data->index].start; + data->virAddrCbCr = data->virAddrY + (data->phyAddrCbCr - data->phyAddrY); + + /*camsrc_info("virAddrY(%p), virAddrCbCr(%p)", data->virAddrY, data->virAddrCbCr);*/ + + return CAMERASRC_SUCCESS; +} + + +static void _dump_exif_info(camerasrc_exif_t *exif_struct) +{ + camsrc_info("== Dynamic value =="); + camsrc_info("unsigned int exposure_time_numerator = %d", exif_struct->exposure_time_numerator); + camsrc_info("unsigned int exposure_time_denominator = %d", exif_struct->exposure_time_denominator); + camsrc_info("int shutter_speed_numerator = %d", exif_struct->shutter_speed_numerator); + camsrc_info("int shutter_speed_denominator = %d", exif_struct->shutter_speed_denominator); + camsrc_info("int brigtness_numerator = %d", exif_struct->brigtness_numerator); + camsrc_info("int brightness_denominator = %d", exif_struct->brightness_denominator); + camsrc_info("unsigned short int iso = %d", exif_struct->iso); + camsrc_info("unsigned short int flash = %d", exif_struct->flash); + camsrc_info("int metering_mode = %d", exif_struct->metering_mode); + camsrc_info("int exif_image_width = %d", exif_struct->exif_image_width); + camsrc_info("int exif_image_height = %d", exif_struct->exif_image_height); + camsrc_info("int exposure_bias_in_APEX = %d", exif_struct->exposure_bias_in_APEX); + camsrc_info("int software_used = %d", exif_struct->software_used); + camsrc_info("int focal_len_numerator = %d", exif_struct->focal_len_numerator); + camsrc_info("int focal_len_denominator = %d", exif_struct->focal_len_denominator); + camsrc_info("int aperture_f_num_numerator = %d", exif_struct->aperture_f_num_numerator); + camsrc_info("int aperture_f_num_denominator = %d", exif_struct->aperture_f_num_denominator); + camsrc_info("int aperture_in_APEX = %d", exif_struct->aperture_in_APEX); + camsrc_info("int max_lens_aperture_in_APEX = %d", exif_struct->max_lens_aperture_in_APEX); + + camsrc_info("== Fixed value =="); + camsrc_info("int component_configuration = %x", exif_struct->component_configuration); + camsrc_info("int colorspace = %d", exif_struct->colorspace); + + return; +} + + +static int _camerasrc_get_exif_info (camerasrc_handle_t *handle, camerasrc_exif_t *exif_struct) +{ + int photometry_mode = V4L2_PHOTOMETRY_MULTISEG; + + if (exif_struct == NULL) { + return CAMERASRC_ERR_INVALID_PARAMETER; + } + + /** Dynamic value **/ + + /* exposure time */ + GET_CTRL_VAL(V4L2_CID_CAMERA_EXIF_EXPTIME, exif_struct->exposure_time_numerator); + exif_struct->exposure_time_denominator = 1; + + /* shutter speed */ + GET_CTRL_VAL(V4L2_CID_CAMERA_EXIF_TV, exif_struct->shutter_speed_numerator); + exif_struct->shutter_speed_denominator = 1; + + /* brightness */ + GET_CTRL_VAL(V4L2_CID_CAMERA_EXIF_BV, exif_struct->brigtness_numerator); + exif_struct->brightness_denominator = 1; + + /* iso */ + GET_CTRL_VAL(V4L2_CID_CAMERA_EXIF_ISO, exif_struct->iso); + ISO_APPROXIMATE_VALUE(exif_struct->iso, exif_struct->iso); + + /* flash */ + GET_CTRL_VAL(V4L2_CID_CAMERA_EXIF_FLASH, exif_struct->flash); + + /* image size */ + exif_struct->exif_image_width = handle->format.img_size.dim.width; + exif_struct->exif_image_height = handle->format.img_size.dim.height; + + /*FIXME focal length - Set fixed value at gst_camerasrc_control_get_exif_info function */ + exif_struct->focal_len_numerator = 1; + exif_struct->focal_len_denominator = 1; + + /*FIXME f number - Set fixed value at gst_camerasrc_control_get_exif_info function */ + exif_struct->aperture_f_num_numerator = 1; + exif_struct->aperture_f_num_denominator = 1; + + /* FIXME APEX */ + exif_struct->aperture_in_APEX \ + = CAMERASRC_EXIF_APERTURE_VALUE_IN_APEX(exif_struct->aperture_f_num_numerator, exif_struct->aperture_f_num_denominator); + exif_struct->max_lens_aperture_in_APEX = 1; + /*= CAMERASRC_EXIF_APERTURE_VALUE_IN_APEX(exif_info.max_aperture_f_num_numerator, exif_info.max_aperture_f_num_denominator);*/ + exif_struct->exposure_bias_in_APEX = exif_struct->aperture_in_APEX \ + + CAMERASRC_EXIF_SHUTTERSPEED_VALUE_IN_APEX(exif_struct->exposure_time_numerator, exif_struct->exposure_time_denominator); + + /* Get the value using CID */ + /* Not implemented yet + GET_CTRL_VAL(V4L2_CID_FW_VERSION, exif_struct->software_used); + */ + GET_CTRL_VAL(V4L2_CID_PHOTOMETRY, photometry_mode); + PHOTOMETRY_MODE_TO_METERING_MODE(photometry_mode, exif_struct->metering_mode); + + /** Fixed value **/ + exif_struct->component_configuration = _CAMERASRC_EXIF_COMP_CONF; + exif_struct->colorspace = _CAMERASRC_EXIF_COLORSPACE; + + _dump_exif_info(exif_struct); + + return CAMERASRC_SUCCESS; +} + +static int fd_on = 0; + +static int _camerasrc_set_cmd(camerasrc_handle_t *handle, _camsrc_cmd_t cmd, void *value) +{ + int err = CAMERASRC_ERR_UNKNOWN; + struct v4l2_jpegcompression comp_arg; + + switch (cmd) { + case _CAMERASRC_CMD_STROBE_MODE: + { + camerasrc_strobe_mode_t *mode = (camerasrc_strobe_mode_t*)value; + + camsrc_info("[_CAMERASRC_CMD_STROBE_MODE] cmd set value %d", *mode ); + + SET_CTRL_VAL(V4L2_CID_CAMERA_FLASH_MODE, *mode); + } + break; + case _CAMERASRC_CMD_FACEDETECTION: + { + int err = CAMERASRC_ERR_UNKNOWN; + struct v4l2_recognition recog; + + camsrc_info("[_CAMERASRC_CMD_FACEDETECTION] cmd set"); + if (((int)value) == _CAMERASRC_FACEDETECTION_START) { + camsrc_info("[_CAMERASRC_CMD_FACEDETECTION] start"); + recog.mode = V4L2_RECOGNITION_MODE_ON; + recog.pattern = V4L2_RECOG_PATTERN_FACE; + recog.obj_num = 10; + /*recog.detect_idx = 0;*/ + recog.action= V4L2_RECOGNITION_ACTION_NONE; + fd_on = 1; + } else if (((int)value) == _CAMERASRC_FACEDETECTION_STOP) { + camsrc_error("[_CAMERASRC_CMD_FACEDETECTION] stop"); + recog.mode = V4L2_RECOGNITION_MODE_OFF; + recog.pattern = V4L2_RECOG_PATTERN_FACE; + recog.obj_num = 10; + /*recog.detect_idx = 0;*/ + recog.action= V4L2_RECOGNITION_ACTION_NONE; + fd_on = 0; + } else { + camsrc_error("[_CAMERASRC_CMD_FACEDETECTION] not support cmd"); + } + + err = _camerasrc_ioctl(handle, VIDIOC_S_RECOGNITION, &recog); + if (err != CAMERASRC_SUCCESS) { + goto ERROR; + } + } + break; + case _CAMERASRC_CMD_SHUTTER_SPEED: + /* WRITEME */ + camsrc_info("[_CAMERASRC_CMD_SHUTTER_SPEED] cmd set"); + break; + case _CAMERASRC_CMD_JPEG_LENGTH: + /* WRITEME */ + camsrc_info("[_CAMERASRC_CMD_JPEG_LENGTH] cmd set"); + break; + case _CAMERASRC_CMD_JPEG_THMBNL_LENGTH: + camsrc_info("[_CAMERASRC_CMD_JPEG_THMBNL_LENGTH] cmd set"); + err = _camerasrc_set_thumbnail_size(handle); + if (err != CAMERASRC_SUCCESS) { + goto ERROR; + } + break; + case _CAMERASRC_CMD_EXPOSURE_VALUE: + camsrc_info("[_CAMERASRC_CMD_EXPOSURE_VALUE] cmd set"); + /* WRITEME */ + break; + case _CAMERASRC_CMD_ESD_CHECK: + camsrc_info("[_CAMERASRC_CMD_ESD_CHECK] cmd set"); + /* WRITEME */ + break; + case _CAMERASRC_CMD_CTRL: + camsrc_info("[_CAMERASRC_CMD_CTRL] cmd set"); + SET_CTRL_VAL(_CAMERASRC_GET_CID(((_camerasrc_ctrl_t *) value)->cid, handle->cur_dev_id), ((_camerasrc_ctrl_t *) value)->value); + break; + case _CAMERASRC_CMD_SUPPORT_EMBED_EXIF: + /* WRITEME */ + camsrc_info("[_CAMERASRC_CMD_SUPPORT_EMBED_EXIF] cmd set"); + break; + case _CAMERASRC_CMD_SUPPORT_JPEG_ENCODING: + camsrc_warning("[_CAMERASRC_CMD_SUPPORT_JPEG_ENCODING] cmd set isn't supported"); + break; + case _CAMERASRC_CMD_AF_CONTROL: + /* WRITEME */ + camsrc_info("[_CAMERASRC_CMD_AF_CONTROL] cmd set(value=%d)", value); + + /* FIXME : Please fix whole AF implementation!!! */ + switch ((int)value) { + case _CAMERASRC_AF_START: + _camerasrc_start_autofocusing(handle); + break; + case _CAMERASRC_AF_STOP: + _camerasrc_stop_autofocusing(handle); + break; + case _CAMERASRC_AF_DESTROY: + _camerasrc_destroy_autofocusing(handle); + break; + case _CAMERASRC_AF_RELEASE: + case _CAMERASRC_AF_INIT: + default: + _camerasrc_init_autofocusing_mode(handle); + break; + } + break; + case _CAMERASRC_CMD_AF_AREA: + { + camerasrc_rect_t *rect = (camerasrc_rect_t *)value; + + camsrc_info("[_CAMERASRC_CMD_AF_AREA] cmd set (%d,%d,%dx%d)", + rect->x, rect->y, rect->width, rect->height); + + SET_CTRL_VAL(V4L2_CID_FOCUS_AUTO_RECTANGLE_LEFT, rect->x); + SET_CTRL_VAL(V4L2_CID_FOCUS_AUTO_RECTANGLE_TOP, rect->y); + SET_CTRL_VAL(V4L2_CID_FOCUS_AUTO_RECTANGLE_WIDTH, 0);/*rect->width); Not supported */ + SET_CTRL_VAL(V4L2_CID_FOCUS_AUTO_RECTANGLE_HEIGHT, 0);/*rect->height); Not supported */ + + if (gettimeofday(&handle->set_af_area_time, NULL) == 0) { + camsrc_info("[_CAMERASRC_CMD_AF_AREA] Get Time Success" ); + } else { + handle->set_af_area_time.tv_sec = 0; + handle->set_af_area_time.tv_usec = 0; + camsrc_warning("[_CAMERASRC_CMD_AF_AREA] Get Time Failed" ); + } + break; + } + case _CAMERASRC_CMD_FRAME_DATA: + /* WRITEME */ + camsrc_info("[_CAMERASRC_CMD_FRAME_DATA] cmd set"); + break; + case _CAMERASRC_CMD_EXIF_INFO: + /* WRITEME */ + camsrc_info("[_CAMERASRC_CMD_EXIF_INFO] cmd set"); + break; + case _CAMERASRC_CMD_CHECK_ESD: + /* WRITEME */ + camsrc_info("[_CAMERASRC_CMD_CHECK_ESD] cmd set"); + break; + case _CAMERASRC_CMD_JPEG_COMPRESS_RATIO: + /* WRITEME */ + camsrc_info("[_CAMERASRC_CMD_JPEG_COMPRESS_RATIO] cmd set, val = %d", (int)(*((unsigned int*) value))); + if (handle->cur_dev_id == CAMERASRC_DEV_ID_PRIMARY) { + comp_arg.quality = (int)(*((unsigned int*) value)); + err = _camerasrc_ioctl(handle, VIDIOC_S_JPEGCOMP, &comp_arg); + if (err != CAMERASRC_SUCCESS) { + goto ERROR; + } + } else if (handle->cur_dev_id == CAMERASRC_DEV_ID_SECONDARY) { + err = CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + goto ERROR; + } + break; + case _CAMERASRC_CMD_ROTATION: + { + int *rotate = (int *)value; + camsrc_info("[_CAMERASRC_CMD_ROTATION] cmd set : %d", *rotate); + SET_CTRL_VAL(V4L2_CID_ROTATION, (int)*rotate); + } + break; + case _CAMERASRC_CMD_SENSOR_MODE: + { + camerasrc_sensor_mode_t *mode = (camerasrc_sensor_mode_t *)value; + camsrc_info("[_CAMERASRC_CMD_SENSOR_MODE] cmd set : %d", *mode); + SET_CTRL_VAL(V4L2_CID_CAMERA_SENSOR_MODE, (int)*mode); + } + break; + case _CAMERASRC_CMD_VFLIP: + { + int *vflip = (int *)value; + camsrc_info("[_CAMERASRC_CMD_VFLIP] cmd set : %d", *vflip); + SET_CTRL_VAL(V4L2_CID_VFLIP, (int)*vflip); + } + break; + case _CAMERASRC_CMD_HFLIP: + { + int *hflip = (int *)value; + camsrc_info("[_CAMERASRC_CMD_HFLIP] cmd set : %d", *hflip); + SET_CTRL_VAL(V4L2_CID_HFLIP, (int)*hflip); + } + break; + default: + camsrc_error("[_CAMERASRC_CMD_UNKNOWN] cmd set"); + err = CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + goto ERROR; + } + + return CAMERASRC_SUCCESS; + +ERROR: + camsrc_error("cmd execution error occured"); + + return err; +} + +static int _camerasrc_get_cmd(camerasrc_handle_t *handle, _camsrc_cmd_t cmd, void *value) +{ + int err = CAMERASRC_ERR_UNKNOWN; + struct v4l2_jpegcompression comp_arg; + + if (!value) { + camsrc_error("value is NULL"); + return CAMERASRC_ERR_NULL_POINTER; + } + + switch (cmd) { + case _CAMERASRC_CMD_SUPPORT_EMBED_EXIF: + camsrc_info("[_CAMERASRC_CMD_SUPPORT_EMBED_EXIF] cmd get"); + *((int*)value) = _CAMERASRC_CMD_SUPPORT_EMBED_EXIF_DEF; + break; + case _CAMERASRC_CMD_SUPPORT_JPEG_ENCODING: + camsrc_info("[_CAMERASRC_CMD_SUPPORT_JPEG_ENCODING] cmd get(cur_dev_id=%d)", handle->cur_dev_id); + if (handle->cur_dev_id == CAMERASRC_DEV_ID_PRIMARY) { + *((int*)value) = 1; + } else { + *((int*)value) = 0; + } + break; + case _CAMERASRC_CMD_STROBE_MODE: + { + camerasrc_strobe_mode_t mode; + + GET_CTRL_VAL(V4L2_CID_CAMERA_FLASH_MODE, mode); + *((camerasrc_strobe_mode_t*)value) = mode; + + camsrc_info("[_CAMERASRC_CMD_STROBE_MODE] cmd get - %d", mode); + } + break; + case _CAMERASRC_CMD_FACEDETECTION: + camsrc_info("[_CAMERASRC_CMD_FACEDETECTION] cmd get - %d", fd_on); + *(int *)value = fd_on; + break; + case _CAMERASRC_CMD_SHUTTER_SPEED: + /* WRITEME */ + camsrc_info("[_CAMERASRC_CMD_SHUTTER_SPEED] cmd get"); + break; + case _CAMERASRC_CMD_JPEG_LENGTH: + { + int err = CAMERASRC_ERR_UNKNOWN; + struct v4l2_control ctrl; + + ctrl.id = V4L2_CID_CAM_JPEG_MAIN_SIZE; + err = _camerasrc_ioctl( handle, VIDIOC_G_CTRL, &ctrl ); + if (err != CAMERASRC_SUCCESS) { + *((int*)value) = 0; + goto ERROR; + } + + *((int*)value) = ctrl.value; + camsrc_info("[_CAMERASRC_CMD_JPEG_LENGTH] cmd get"); + break; + } + case _CAMERASRC_CMD_JPEG_THMBNL_LENGTH: + { + int err = CAMERASRC_ERR_UNKNOWN; + struct v4l2_control ctrl; + + ctrl.id = V4L2_CID_CAM_JPEG_THUMB_SIZE; + err = _camerasrc_ioctl( handle, VIDIOC_G_CTRL, &ctrl ); + if (err != CAMERASRC_SUCCESS) { + *((int*)value) = 0; + goto ERROR; + } + + *((int*)value) = ctrl.value; + camsrc_info("[_CAMERASRC_CMD_JPEG_THMBNL_LENGTH] cmd get : %d", *((int*)value)); + break; + } + case _CAMERASRC_CMD_JPEG_THMBNL_OFFSET: + { + int err = CAMERASRC_ERR_UNKNOWN; + struct v4l2_control ctrl; + ctrl.id = V4L2_CID_CAM_JPEG_THUMB_OFFSET; + + err = _camerasrc_ioctl( handle, VIDIOC_G_CTRL, &ctrl ); + if(err != CAMERASRC_SUCCESS) + { + *((int*)value) = 0; + goto ERROR; + } + + *((int*)value) = ctrl.value; + camsrc_info("[_CAMERASRC_CMD_JPEG_THMBNL_OFFSET] cmd get : %x", *((int*)value)); + break; + } + case _CAMERASRC_CMD_JPEG_SCRNL_LENGTH: + { + int err = CAMERASRC_ERR_UNKNOWN; + struct v4l2_control ctrl; + ctrl.id = V4L2_CID_CAM_JPEG_POSTVIEW_SIZE; + + err = _camerasrc_ioctl(handle, VIDIOC_G_CTRL, &ctrl); + if (err != CAMERASRC_SUCCESS) { + *((int*)value) = 0; + goto ERROR; + } + + *((int*)value) = ctrl.value; + camsrc_info("[_CAMERASRC_CMD_JPEG_SCRNL_LENGTH] cmd get : %x", *((int*)value)); + break; + } + case _CAMERASRC_CMD_JPEG_SCRNL_OFFSET: + { + int err = CAMERASRC_ERR_UNKNOWN; + struct v4l2_control ctrl; + ctrl.id = V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET; + + err = _camerasrc_ioctl( handle, VIDIOC_G_CTRL, &ctrl ); + if (err != CAMERASRC_SUCCESS) { + *((int*)value) = 0; + goto ERROR; + } + + *((int*)value) = ctrl.value; + camsrc_info("[_CAMERASRC_CMD_JPEG_SCRNL_OFFSET] cmd get : %x", *((int*)value)); + break; + } + case _CAMERASRC_CMD_EXPOSURE_VALUE: + /* WRITEME */ + camsrc_info("[_CAMERASRC_CMD_EXPOSURE_VALUE] cmd get"); + break; + case _CAMERASRC_CMD_ESD_CHECK: + /* WRITEME */ + camsrc_info("[_CAMERASRC_CMD_ESD_CHECK] cmd get"); + break; + case _CAMERASRC_CMD_CTRL: + camsrc_info("[_CAMERASRC_CMD_CTRL] cmd get"); + GET_CTRL_VAL(_CAMERASRC_GET_CID(((_camerasrc_ctrl_t *) value)->cid, handle->cur_dev_id), ((_camerasrc_ctrl_t *) value)->value); + break; + case _CAMERASRC_CMD_AF_CONTROL: + /* WRITEME */ + camsrc_info("[_CAMERASRC_CMD_AF_CONTROL] cmd get"); + break; + case _CAMERASRC_CMD_AF_AREA: + { + camerasrc_rect_t* rect = (camerasrc_rect_t*)value; + + GET_CTRL_VAL(V4L2_CID_FOCUS_AUTO_RECTANGLE_LEFT, rect->x); + GET_CTRL_VAL(V4L2_CID_FOCUS_AUTO_RECTANGLE_TOP, rect->y); + GET_CTRL_VAL(V4L2_CID_FOCUS_AUTO_RECTANGLE_WIDTH, rect->width); + GET_CTRL_VAL(V4L2_CID_FOCUS_AUTO_RECTANGLE_HEIGHT, rect->height); + + camsrc_info("[_CAMERASRC_CMD_AF_AREA] cmd get (%d,%d,%dx%d)", + rect->x, rect->y, rect->width, rect->height); + break; + } + case _CAMERASRC_CMD_FRAME_DATA: + /* WRITEME */ + /*camsrc_info("[_CAMERASRC_CMD_FRAME_DATA] cmd get");*/ + err = _camerasrc_get_frame_data(handle, (camerasrc_frame_data_t*)value); + if (err != CAMERASRC_SUCCESS) { + goto ERROR; + } + break; + case _CAMERASRC_CMD_EXIF_INFO: + camsrc_info("[_CAMERASRC_CMD_EXIF_INFO] cmd get"); + err = _camerasrc_get_exif_info (handle, (camerasrc_exif_t*)value); + if (err != CAMERASRC_SUCCESS) { + goto ERROR; + } + break; + case _CAMERASRC_CMD_CHECK_ESD: + camsrc_info("[_CAMERASRC_CMD_CHECK_ESD] cmd get"); + GET_CTRL_VAL(V4L2_CID_ESD_INT, *((int *) value)); + break; + case _CAMERASRC_CMD_JPEG_COMPRESS_RATIO: + camsrc_info("[_CAMERASRC_CMD_JPEG_COMPRESS_RATIO] cmd get"); + err = _camerasrc_ioctl(handle, VIDIOC_G_JPEGCOMP, &comp_arg); + if (err != CAMERASRC_SUCCESS) { + goto ERROR; + } + *((unsigned int*)value) = (int)comp_arg.quality; + break; + case _CAMERASRC_CMD_ROTATION: + camsrc_info("[_CAMERASRC_CMD_ROTATION] cmd get"); + GET_CTRL_VAL(V4L2_CID_ROTATION, *(int*)value); + break; + case _CAMERASRC_CMD_SENSOR_MODE: + camsrc_info("[_CAMERASRC_CMD_SENSOR_MODE] cmd get"); + GET_CTRL_VAL(V4L2_CID_CAMERA_SENSOR_MODE, *(int*)value); + break; + case _CAMERASRC_CMD_VFLIP: + camsrc_info("[_CAMERASRC_CMD_VFLIP] cmd get"); + GET_CTRL_VAL(V4L2_CID_VFLIP, *(int*)value); + break; + case _CAMERASRC_CMD_HFLIP: + camsrc_info("[_CAMERASRC_CMD_HFLIP] cmd get"); + GET_CTRL_VAL(V4L2_CID_HFLIP, *(int*)value); + break; + default: + camsrc_error("[_CAMERASRC_CMD_UNKNOWN] cmd get"); + err = CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + goto ERROR; + } + + return CAMERASRC_SUCCESS; + +ERROR: + camsrc_error("cmd execution error occured"); + + return err; +} + +static const CAMERASRC_DEV_DEPENDENT_MISC_FUNC dev_misc_functions = { + ._ioctl = _camerasrc_ioctl, + ._ioctl_once = _camerasrc_ioctl_once, + ._run_autofocusing = _camerasrc_run_autofocusing, + ._skip_frame = _camerasrc_skip_frame, + ._copy_frame = _camerasrc_copy_frame, + ._set_cmd = _camerasrc_set_cmd, + ._get_cmd = _camerasrc_get_cmd, +}; + +const CAMERASRC_DEV_DEPENDENT_MISC_FUNC *dev_misc_func = &dev_misc_functions; diff --git a/camerasrc/src/camerasrc.c b/camerasrc/src/camerasrc.c new file mode 100644 index 0000000..00d5de9 --- /dev/null +++ b/camerasrc/src/camerasrc.c @@ -0,0 +1,4870 @@ +/* + * camerasrc + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang <jm80.yang@samsung.com> + * + * 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.1 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., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "camerasrc-common.h" +#include "camerasrc-internal.h" +#include <semaphore.h> + +#define BUF_LEN 64 +#define ITLV_DATA_INFO_OFFSET 0x1000 +#define EMBEDDED_OFFSET (2040*2+4) + +/* extended V4L2 API */ +#ifndef V4L2_PIX_FMT_INTERLEAVED +#define V4L2_PIX_FMT_INTERLEAVED v4l2_fourcc('I', 'T', 'L', 'V') +#endif /* V4L2_PIX_FMT_INTERLEAVED */ + +#ifndef V4L2_CID_IS_S_SCENARIO_MODE +#define V4L2_CID_IS_S_SCENARIO_MODE (V4L2_CID_FIMC_IS_BASE + 15) +#define V4L2_CID_IS_S_FORMAT_SCENARIO (V4L2_CID_FIMC_IS_BASE + 16) +enum scenario_mode { + IS_MODE_PREVIEW_STILL, + IS_MODE_PREVIEW_VIDEO, + IS_MODE_CAPTURE_STILL, + IS_MODE_CAPTURE_VIDEO, + IS_MODE_MAX +}; +#endif /* V4L2_CID_IS_S_SCENARIO_MODE */ + +#ifndef V4L2_CID_EMBEDDEDDATA_ENABLE +#define V4L2_CID_EMBEDDEDDATA_ENABLE (V4L2_CID_PRIVATE_BASE + 130) +#endif /* V4L2_CID_EMBEDDEDDATA_ENABLE */ + +/* + * LOCAL DEFINITIONS + */ +#ifndef EXPORT_API +#define EXPORT_API __attribute__((__visibility__("default"))) +#endif + +#define LOCK(p) {\ + if(0 != pthread_mutex_lock(&(p->mutex))) {\ + camsrc_error("Mutex locking error");\ + camsrc_assert(0);\ + }\ +} + +#define UNLOCK(p) {\ + if(0 != pthread_mutex_unlock(&(p->mutex))) {\ + camsrc_error("Mutex unlocking error");\ + camsrc_assert(0);\ + }\ +} + +extern const CAMERASRC_DEV_DEPENDENT_MISC_FUNC *dev_misc_func; + +/** proto type of internal function **/ +int _camerasrc_get_JPG_length(camerasrc_handle_t *handle); +int _camerasrc_get_thumbnail_JPG_length(camerasrc_handle_t *handle); +int _camerasrc_get_thumbnail_JPG_offset(camerasrc_handle_t *handle); +int _camerasrc_get_screennail_JPG_length(camerasrc_handle_t *handle); +int _camerasrc_get_screennail_JPG_offset(camerasrc_handle_t *handle); +int _camerasrc_set_thumbnail_size(camerasrc_handle_t *handle); +int _camerasrc_check_emp_shock(camerasrc_handle_t *handle, int *check_val); +int _camerasrc_set_jpeg_compress_ratio(camerasrc_handle_t *handle, unsigned int quality); +int _camerasrc_ioctl(camerasrc_handle_t *handle, int request, void *arg); +int _camerasrc_ioctl_once(camerasrc_handle_t *handle, int request, void *arg); +void *_camerasrc_run_autofocusing(camerasrc_handle_t *handle); +int _camerasrc_skip_frame(camerasrc_handle_t *handle, long int timeout, int skip_frame); + +/**** A U T O F O C U S I N G F U N C T I O N S ****/ +int _camerasrc_set_autofocusing_area(camerasrc_handle_t *handle, camerasrc_rect_t *rect); +int _camerasrc_get_autofocusing_area(camerasrc_handle_t *handle, camerasrc_rect_t *rect); +int _camerasrc_start_autofocusing(camerasrc_handle_t *handle); +int _camerasrc_stop_autofocusing(camerasrc_handle_t *handle); +int _camerasrc_release_autofocusing(camerasrc_handle_t *handle); +int _camerasrc_destroy_autofocusing(camerasrc_handle_t *handle); +int _camerasrc_init_autofocusing_mode(camerasrc_handle_t *handle); + +int _camerasrc_get_frame_data(camerasrc_handle_t *handle, camerasrc_frame_data_t *data); +int _camerasrc_get_exif_info(camerasrc_handle_t *handle, camerasrc_buffer_t *exif_string); +int _camerasrc_copy_frame(camerasrc_handle_t *handle, camerasrc_buffer_t *src_buffer, camerasrc_buffer_t *dst_buffer, int isThumbnail); +int _camerasrc_query_ctrl_menu(camerasrc_handle_t *handle, struct v4l2_queryctrl queryctrl, camerasrc_ctrl_info_t *ctrl_info); + + +#if 1 +typedef struct { + char *key_path; + int key_prefix; +} camerasrc_sync_param_t; + +int camsrc_create_sync(const camerasrc_sync_param_t *param) +{ + sem_t *sem = NULL; + + sem = sem_open(param->key_path, O_CREAT, 0666, 1); + if (sem == SEM_FAILED) { + switch (errno) { + case EACCES: + camsrc_error("The semaphore already exist, but caller does not have permission %s", param->key_path); + break; + case ENOMEM: + camsrc_error("Insufficient memory"); + break; + case ENFILE: + camsrc_error("Too many open files in system"); + break; + default: + camsrc_critical("Semaphore create fail! (name:%s, errno %d)", param->key_path, errno); + } + + return CAMERASRC_ERR_INTERNAL; + } + + return CAMERASRC_SUCCESS; +} + +int camsrc_remove_sync(const camerasrc_sync_param_t *param) +{ + int err = 0; + + err = sem_unlink(param->key_path); + if (err == -1) { + camsrc_critical("Semaphore destroy Fail! (name:%s, errno %d)", param->key_path, errno); + return CAMERASRC_ERR_INTERNAL; + } + + return CAMERASRC_SUCCESS; +} + +int camsrc_lock_sync(const camerasrc_sync_param_t *param) +{ + sem_t *sem = NULL; + int ret; + int err = CAMERASRC_SUCCESS; + int sem_value = -1; + struct timespec wait_time; + + sem = sem_open(param->key_path, O_CREAT, 0666, 1); + if (sem == SEM_FAILED) + { + camsrc_critical("Semaphore open Fail! (name:%s, errno %d)", param->key_path, errno); + return CAMERASRC_ERR_INTERNAL; + } + +retry_lock: + wait_time.tv_sec = (long int)(time(NULL)) + 6; + wait_time.tv_nsec = 0; + + ret = sem_timedwait(sem, &wait_time); + if (ret == -1) { + switch (errno) { + case EINTR: + camsrc_critical("Lock RETRY LOCK"); + goto retry_lock; + break; + case EINVAL: + camsrc_critical("Invalid semaphore"); + err = CAMERASRC_ERR_INTERNAL; + break; + case EAGAIN: + camsrc_critical("EAGAIN"); + err = CAMERASRC_ERR_INTERNAL; + break; + case ETIMEDOUT: + camsrc_critical("sem_wait leached %d seconds timeout.", 6); + /* Recovery of sem_wait lock....in abnormal condition */ + if (0 == sem_getvalue(sem, &sem_value)) { + camsrc_critical("%s sem value is %d",param->key_path, sem_value); + if (sem_value == 0) { + ret = sem_post(sem); + if (ret == -1) { + camsrc_critical("sem_post error %s : %d", param->key_path, sem_value); + } else { + camsrc_critical("lock recovery success...try lock again"); + goto retry_lock; + } + } else { + camsrc_critical("sem value is not 0. but failed sem_timedwait so retry.. : %s",param->key_path); + usleep(5); + goto retry_lock; + } + } else { + camsrc_critical("sem_getvalue failed : %s",param->key_path); + } + err = CAMERASRC_ERR_INTERNAL; + break; + } + } + sem_close(sem); + return err; +} + +int camsrc_unlock_sync(const camerasrc_sync_param_t *param) +{ + sem_t *sem = NULL; + int ret; + int err = CAMERASRC_SUCCESS; + + sem = sem_open(param->key_path, O_CREAT, 0666, 1); + if (sem == SEM_FAILED) { + camsrc_critical("Semaphore open Fail! (name:%s, errno %d)", param->key_path, errno); + return CAMERASRC_ERR_INTERNAL; + } + + ret = sem_post(sem); + if (ret == -1) { + camsrc_critical("UNLOCK FAIL"); + err = CAMERASRC_ERR_INTERNAL; + } + + sem_close(sem); + return err; +} +#endif + + +#if defined(USE_CAMERASRC_FRAME_DUMP) +#define WRITE_UNIT 4096 +static int seq_no = 0; + +static void write_buffer_into_path(camerasrc_buffer_t *buffer, char *path, char *name) +{ + int fd = -1; + int write_len = 0; + char temp_fn[255]; + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + + sprintf(temp_fn, "%s/%s", path, name); + + fd = open(temp_fn, O_CREAT | O_WRONLY | O_SYNC); + + if(fd == -1) { + strerror_r(errno, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("OPEN ERR!!!! : %s", err_msg); + camsrc_assert(0); + } else { + camsrc_info("Open success, FD = %d, seq = %d", fd, seq_no); + } + + int write_remain = buffer->length; + int offset = 0; + + while (write_remain > 0) { + write_len = write(fd, buffer->start + offset, write_remain<WRITE_UNIT?write_remain:WRITE_UNIT); + if (write_len < 0) { + strerror_r(errno, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("WRITE ERR!!!! : %s", err_msg); + camsrc_assert(0); + } else { + write_remain -= write_len; + offset+= write_len; + camsrc_info("%d written, %d left", write_len, write_remain); + } + } + + close(fd); +} +#endif + +#define CAMERASRC_SET_CMD(cmd, value) _camerasrc_set_cmd(handle, cmd, (void*)value); +#define CAMERASRC_GET_CMD(cmd, value) _camerasrc_get_cmd(handle, cmd, (void*)value); + + +static int _camerasrc_set_cmd(camsrc_handle_t handle, _camsrc_cmd_t cmd, void *value) +{ + camerasrc_handle_t *p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (dev_misc_func->_set_cmd == NULL) { + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + } + + err = dev_misc_func->_set_cmd(p, cmd, value); + + return err; +} + +static int _camerasrc_get_cmd(camsrc_handle_t handle, _camsrc_cmd_t cmd, void *value) +{ + camerasrc_handle_t *p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + if(handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if(dev_misc_func->_get_cmd == NULL) + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + + err = dev_misc_func->_get_cmd(p, cmd, value); + + return err; +} + + +int camerasrc_support_embed_exif(camsrc_handle_t handle, int* support_exif) +{ + int err = CAMERASRC_ERR_UNKNOWN; + + err = CAMERASRC_GET_CMD(_CAMERASRC_CMD_SUPPORT_EMBED_EXIF, support_exif); + if(err != CAMERASRC_SUCCESS) *support_exif = -1; + + return err; +} + + +int camerasrc_support_jpeg_encoding(camsrc_handle_t handle, int *support_jpeg_encoding) +{ + int err = CAMERASRC_ERR_UNKNOWN; + + err = CAMERASRC_GET_CMD(_CAMERASRC_CMD_SUPPORT_JPEG_ENCODING, support_jpeg_encoding); + if (err != CAMERASRC_SUCCESS) { + *support_jpeg_encoding = 0; + } + + return err; +} + + +int camerasrc_get_screennail_buffer(camsrc_handle_t handle, camerasrc_buffer_t *scrnl_buf) +{ + camerasrc_handle_t *p = NULL; + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + if (scrnl_buf == NULL) { + camsrc_error("scrnl_buf is null"); + return CAMERASRC_ERR_INVALID_PARAMETER; + } + + p = CAMERASRC_HANDLE(handle); + + scrnl_buf->start = p->scrnl_buf.start; + scrnl_buf->length = p->scrnl_buf.length; + + camsrc_info("screennail ptr[%p],length[%d]", scrnl_buf->start, scrnl_buf->length); + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_start_facedetection(camsrc_handle_t handle) +{ + return CAMERASRC_SET_CMD(_CAMERASRC_CMD_FACEDETECTION, _CAMERASRC_FACEDETECTION_START); +} + + +int camerasrc_stop_facedetection(camsrc_handle_t handle) +{ + return CAMERASRC_SET_CMD(_CAMERASRC_CMD_FACEDETECTION, _CAMERASRC_FACEDETECTION_STOP); +} + + +int camerasrc_get_facedetection(camsrc_handle_t handle, int *is_detecting) +{ + return CAMERASRC_GET_CMD(_CAMERASRC_CMD_FACEDETECTION, is_detecting); +} + + +int camerasrc_set_shutter_speed(camsrc_handle_t handle, camerasrc_frac_t frac) +{ + return CAMERASRC_SET_CMD(_CAMERASRC_CMD_SHUTTER_SPEED, &frac); +} + + +int camerasrc_get_shutter_speed(camsrc_handle_t handle, camerasrc_frac_t *frac) +{ + return CAMERASRC_GET_CMD(_CAMERASRC_CMD_SHUTTER_SPEED, frac); +} + + +int camerasrc_set_exposure_value(camsrc_handle_t handle, camerasrc_frac_t frac) +{ + return CAMERASRC_SET_CMD(_CAMERASRC_CMD_EXPOSURE_VALUE, &frac); +} + + +int camerasrc_get_exposure_value(camsrc_handle_t handle, camerasrc_frac_t *frac) +{ + return CAMERASRC_GET_CMD(_CAMERASRC_CMD_EXPOSURE_VALUE, frac); +} + + +int camerasrc_set_strobe_mode(camsrc_handle_t handle, camerasrc_strobe_mode_t mode) +{ + return CAMERASRC_SET_CMD(_CAMERASRC_CMD_STROBE_MODE, &mode); +} + + +int camerasrc_get_strobe_mode(camsrc_handle_t handle, camerasrc_strobe_mode_t *mode) +{ + return CAMERASRC_GET_CMD(_CAMERASRC_CMD_STROBE_MODE, mode); +} + + +int camerasrc_set_control(camsrc_handle_t handle, camerasrc_ctrl_t ctrl_id, int value) +{ + _camerasrc_ctrl_t ctrl; + + CLEAR(ctrl); + + ctrl.cid = ctrl_id; + ctrl.value = value; + + return CAMERASRC_SET_CMD(_CAMERASRC_CMD_CTRL, &ctrl); +} + + +int camerasrc_get_control(camsrc_handle_t handle, camerasrc_ctrl_t ctrl_id, int *value) +{ + int err = CAMERASRC_ERR_UNKNOWN; + _camerasrc_ctrl_t ctrl; + + CLEAR(ctrl); + + ctrl.cid = ctrl_id; + + err = CAMERASRC_GET_CMD(_CAMERASRC_CMD_CTRL, &ctrl); + if (err != CAMERASRC_SUCCESS) { + return err; + } + + *value = ctrl.value; + + return err; +} + + +int camerasrc_query_control(camsrc_handle_t handle, camerasrc_ctrl_t ctrl_id, camerasrc_ctrl_info_t *ctrl_info) +{ + struct v4l2_queryctrl queryctrl; + + if (ctrl_id < CAMERASRC_CTRL_BRIGHTNESS || ctrl_id >= CAMERASRC_CTRL_NUM) { + camsrc_warning("invalid ctrl_id [%d]", ctrl_id); + return CAMERASRC_ERR_INVALID_PARAMETER; + } + + CLEAR(queryctrl); + + queryctrl.id = _CAMERASRC_GET_CID(ctrl_id, CAMERASRC_HANDLE(handle)->cur_dev_id); + if (queryctrl.id == -1 ) { + camsrc_warning("not supported ctrl_id [%d]", ctrl_id); + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + } + + if (0 == _camerasrc_ioctl( handle, VIDIOC_QUERYCTRL, &queryctrl)) { + if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) { + camsrc_info("ID [%8x] disabled", queryctrl.id); + } + + ctrl_info->v4l2_ctrl_id = queryctrl.id; + ctrl_info->camsrc_ctrl_id = ctrl_id; + + switch (queryctrl.type) { + case V4L2_CTRL_TYPE_INTEGER: + ctrl_info->ctrl_type = CTRL_TYPE_RANGE; + break; + case V4L2_CTRL_TYPE_BOOLEAN: + ctrl_info->ctrl_type = CTRL_TYPE_BOOL; + break; + case V4L2_CTRL_TYPE_MENU: + ctrl_info->ctrl_type = CTRL_TYPE_ARRAY; + _camerasrc_query_ctrl_menu (handle, queryctrl, ctrl_info); + break; + default: + ctrl_info->ctrl_type = CTRL_TYPE_UNKNOWN; + break; + } + + memcpy(ctrl_info->ctrl_name, queryctrl.name, MAX_SZ_CTRL_NAME_STRING); + ctrl_info->min = queryctrl.minimum; + ctrl_info->max = queryctrl.maximum; + ctrl_info->step = queryctrl.step; + ctrl_info->default_val = queryctrl.default_value; + + camsrc_info("Control name : %s, type %d, min %d, max %d, step %d, default %d", + queryctrl.name, queryctrl.type, + queryctrl.minimum, queryctrl.maximum, + queryctrl.step, queryctrl.default_value); + } else { + camsrc_error("VIDIOC_QUERYCTRL error"); + + return CAMERASRC_ERR_IO_CONTROL; + } + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_support_control(camsrc_handle_t handle, camerasrc_ctrl_t ctrl_id) +{ + return CAMERASRC_SUCCESS; +} + + +int _camerasrc_get_JPG_length(camerasrc_handle_t *handle) +{ + int jpg_length; + + CAMERASRC_GET_CMD(_CAMERASRC_CMD_JPEG_LENGTH, &jpg_length); + + return jpg_length; +} + + +int _camerasrc_get_thumbnail_JPG_length(camerasrc_handle_t *handle) +{ + int jpg_length; + + CAMERASRC_GET_CMD(_CAMERASRC_CMD_JPEG_THMBNL_LENGTH, &jpg_length); + + return jpg_length; +} + + +int _camerasrc_get_thumbnail_JPG_offset(camerasrc_handle_t *handle) +{ + int thumb_offset; + + CAMERASRC_GET_CMD(_CAMERASRC_CMD_JPEG_THMBNL_OFFSET, &thumb_offset); + + return thumb_offset; +} + + +int _camerasrc_get_screennail_JPG_length(camerasrc_handle_t *handle) +{ + int length; + + CAMERASRC_GET_CMD(_CAMERASRC_CMD_JPEG_SCRNL_LENGTH, &length); + + return length; +} + + +int _camerasrc_get_screennail_JPG_offset(camerasrc_handle_t *handle) +{ + int offset; + + CAMERASRC_GET_CMD(_CAMERASRC_CMD_JPEG_SCRNL_OFFSET, &offset); + + return offset; +} + + +int _camerasrc_set_thumbnail_size(camerasrc_handle_t *handle) +{ + return CAMERASRC_SET_CMD(_CAMERASRC_CMD_JPEG_THMBNL_LENGTH, NULL); +} + + +int _camerasrc_check_emp_shock(camerasrc_handle_t *handle, int *check_val) +{ + return CAMERASRC_GET_CMD(_CAMERASRC_CMD_ESD_CHECK, check_val); +} + + +int _camerasrc_set_jpeg_compress_ratio(camerasrc_handle_t *handle, unsigned int quality) +{ + return CAMERASRC_SET_CMD(_CAMERASRC_CMD_JPEG_COMPRESS_RATIO, &quality); +} + + +int _camerasrc_ioctl(camerasrc_handle_t *handle, int request, void *arg) +{ + if (dev_misc_func->_ioctl == NULL) { +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + } + + return dev_misc_func->_ioctl(handle, request, arg); +} + + +int _camerasrc_ioctl_once(camerasrc_handle_t *handle, int request, void *arg) +{ + if (dev_misc_func->_ioctl_once == NULL) { +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + } + + return dev_misc_func->_ioctl_once(handle, request, arg); +} + + +void *_camerasrc_run_autofocusing(camerasrc_handle_t *handle) +{ + if (dev_misc_func->_run_autofocusing != NULL) { + dev_misc_func->_run_autofocusing(handle); + } + + return NULL; +} + + +int _camerasrc_skip_frame(camerasrc_handle_t *handle, long int timeout, int skip_frame) +{ + if (dev_misc_func->_skip_frame == NULL) { +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + } + + return dev_misc_func->_skip_frame(handle, timeout, skip_frame); +} + +/**** A U T O F O C U S I N G F U N C T I O N S ****/ +int _camerasrc_set_autofocusing_area(camerasrc_handle_t *handle, camerasrc_rect_t *rect) +{ + return CAMERASRC_SET_CMD(_CAMERASRC_CMD_AF_AREA, rect); +} + +int _camerasrc_get_autofocusing_area(camerasrc_handle_t *handle, camerasrc_rect_t *rect) +{ + return CAMERASRC_GET_CMD(_CAMERASRC_CMD_AF_AREA, rect); +} + +int _camerasrc_start_autofocusing(camerasrc_handle_t *handle) +{ + return CAMERASRC_SET_CMD(_CAMERASRC_CMD_AF_CONTROL, _CAMERASRC_AF_START); +} + +int _camerasrc_stop_autofocusing(camerasrc_handle_t *handle) +{ + return CAMERASRC_SET_CMD(_CAMERASRC_CMD_AF_CONTROL, _CAMERASRC_AF_STOP); +} + +int _camerasrc_release_autofocusing(camerasrc_handle_t *handle) +{ + return CAMERASRC_SET_CMD(_CAMERASRC_CMD_AF_CONTROL, _CAMERASRC_AF_RELEASE); +} + +int _camerasrc_destroy_autofocusing(camerasrc_handle_t *handle) +{ + return CAMERASRC_SET_CMD(_CAMERASRC_CMD_AF_CONTROL, _CAMERASRC_AF_DESTROY); +} + +int _camerasrc_init_autofocusing_mode(camerasrc_handle_t *handle) +{ + return CAMERASRC_SET_CMD(_CAMERASRC_CMD_AF_CONTROL, _CAMERASRC_AF_INIT); +} + + +int _camerasrc_get_frame_data(camerasrc_handle_t *handle, camerasrc_frame_data_t *data) +{ + return CAMERASRC_GET_CMD(_CAMERASRC_CMD_FRAME_DATA, data); +} + +int _camerasrc_get_exif_info(camerasrc_handle_t *handle, camerasrc_buffer_t *exif_string) +{ + return CAMERASRC_GET_CMD(_CAMERASRC_CMD_EXIF_INFO, exif_string); +} + + +int _camerasrc_copy_frame(camerasrc_handle_t *handle, camerasrc_buffer_t *src_buffer, camerasrc_buffer_t *dst_buffer, int isThumbnail) +{ + if (dev_misc_func->_copy_frame == NULL) { +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + } + + return dev_misc_func->_copy_frame(handle, src_buffer, dst_buffer, isThumbnail); +} + + + +static int _camerasrc_chk_opened(char *conf_filename) +{ + camsrc_info("enter"); + + char buf[CAMERASRC_MAX_FILENAME_LEN] = {'\0',}; + char proc_buf[CAMERASRC_MAX_FILENAME_LEN] = {'\0',}; + int fd = -1; + int len = 0; + int buf_len = 0; + int pid = 0; + char access[9]; + int err_fd = -1; + int err = CAMERASRC_SUCCESS; + + fd = open(conf_filename, O_RDONLY); + if (fd == -1 && errno == ENOENT) { + camsrc_info("File not exist!!, first open from this boot. open..."); + return CAMERASRC_SUCCESS; + } else if (fd == -1 && errno != ENOENT) { + camsrc_info("File open error. log file open error!"); + return CAMERASRC_ERR_INTERNAL; + } else { + camsrc_info("Dev has been opened. start check..."); + } + + len = read(fd, buf, CAMERASRC_MAX_FILENAME_LEN); + sscanf(buf, "%2d:%5d:%64s", &buf_len, &pid, access); + + camsrc_info("%d : %d : %s", buf_len, pid, access); + if (buf_len == 0) { + camsrc_info("Wrong written check file!"); + close(fd); + + return CAMERASRC_ERR_INTERNAL; + } + + if (!strcmp(access, CAMERASRC_DEV_RELEASED_STR)) { + camsrc_info("Has opened but closed properly!"); + close(fd); + + return CAMERASRC_SUCCESS; + } + + if (pid == getpid()) { + camsrc_info("Double open!! You can't go. Investigate the PID's FD list"); + close(fd); + + return CAMERASRC_ERR_DEVICE_BUSY; + } + + snprintf(proc_buf, CAMERASRC_MAX_FILENAME_LEN, "/proc/%d", pid); + err_fd = open(proc_buf, O_RDONLY | O_NONBLOCK, 0); + if (err_fd == -1) { + camsrc_info("The proc node [%s] are not exist it's fake node", proc_buf); + err = CAMERASRC_SUCCESS; + } else { + camsrc_info("The proc node [%s] are loaded. almost opened...", proc_buf); + close(err_fd); + + err = CAMERASRC_ERR_DEVICE_BUSY; + } + + close(fd); + + return err; +} + + +static int __camerasrc_open_device(camerasrc_handle_t *p) +{ + #define MAX_DEVICE_COUNT 4 + + int i = 0; + int ret = CAMERASRC_ERR_DEVICE_NOT_FOUND; + char device_name[MAX_SZ_DEV_NAME_STRING] = {'\0',}; + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + struct v4l2_capability capability; + + for (i = 0 ; i < MAX_DEVICE_COUNT ; i++) { + snprintf(device_name, MAX_SZ_DEV_NAME_STRING, "%s%d", CAMERASRC_DEV_NODE_PREFIX, i); + camsrc_info("try to open %s", device_name); + + p->dev_fd = open(device_name, O_RDWR | O_NONBLOCK, 0); + if (p->dev_fd < 0) { + /* open failed */ + strerror_r(errno, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("Device open fail [%d][%s]", errno, err_msg); + + switch (errno) { + case EBUSY: + ret = CAMERASRC_ERR_DEVICE_BUSY; + break; + case ENOENT: + case ENODEV: + ret = CAMERASRC_ERR_DEVICE_NOT_FOUND; + break; + default: + ret = CAMERASRC_ERR_DEVICE_OPEN; + break; + } + + break; + } else { + int ioctl_ret = 0; + + camsrc_info("opened device fd %d", p->dev_fd); + + /* open success and check capabilities */ + ioctl_ret = _camerasrc_ioctl((camerasrc_handle_t *)p, VIDIOC_QUERYCAP, &capability); + if (ioctl_ret == CAMERASRC_SUCCESS) { + /* succeeded : VIDIOC_QUERYCAP */ + camsrc_info("capabilities %x", capability.capabilities); + if (capability.capabilities & V4L2_CAP_VIDEO_CAPTURE) { + camsrc_info("found capture device %s", device_name); + return CAMERASRC_SUCCESS; + } + } else { + camsrc_warning("VIDIOC_QUERYCAP error %x", ioctl_ret); + } + + close(p->dev_fd); + p->dev_fd = -1; + } + } + + camsrc_error("failed to find capture device %x", ret); + + return ret; +} + +static int _camerasrc_seamless_record_onaccess_open(char *conf_filename, camerasrc_handle_t *p) +{ + camsrc_info("enter"); + + int fd = -1; + int len = 0; + int ret = CAMERASRC_SUCCESS; + char buf[BUF_LEN]; + char tot_buf[BUF_LEN]; + camerasrc_sync_param_t syncparam = {CAMERASRC_SYNC_KEY_PATH, CAMERASRC_SYNC_KEY_PREFIX}; + + camsrc_lock_sync(&syncparam); + + if (p->dev_fd == -1) { + ret = __camerasrc_open_device(p); + if (ret != CAMERASRC_SUCCESS) { + camsrc_error("open failed %x", ret); + camsrc_unlock_sync(&syncparam); + return ret; + } + + p->is_async_open = 0; + } else { + p->is_async_open = 1; + } + + /* Write open status */ + fd = open(conf_filename, O_RDWR | O_NONBLOCK | O_CREAT, 0666); + if (fd == -1) { + camsrc_info("failed to open ", conf_filename); + /* Release camera device */ + close(p->dev_fd); + p->dev_fd = -1; + return CAMERASRC_ERR_INTERNAL; + } + + /** + * record like below format + * A : (integer) length of this info without this number and semicolon + * B : (integer) Process ID of process that open the device + * C : (string) Status of camera device. ONACCESS / RELEASED (9 words) + * format : "%d:%d:%s", A, B, C + */ + len = snprintf(buf, BUF_LEN, "%d:%s", getpid(), CAMERASRC_DEV_ON_ACCESS_STR); + len = snprintf(tot_buf, BUF_LEN, "%d:%s", len, buf); + tot_buf[len] = '\0'; + len = write(fd, tot_buf, len+1); + + close(fd); + fd = -1; + + camsrc_unlock_sync(&syncparam); + + return CAMERASRC_SUCCESS; +} + + +static int _camerasrc_seamless_delete_onaccess(char *conf_filename, camerasrc_handle_t *p) +{ + camsrc_info("enter"); + + int fd = p->dev_fd; + int chk_fd = 0; + int len = 0; + int err = CAMERASRC_ERR_UNKNOWN; + char buf[BUF_LEN]; + char tot_buf[BUF_LEN]; + camerasrc_sync_param_t param = {CAMERASRC_SYNC_KEY_PATH, CAMERASRC_SYNC_KEY_PREFIX}; + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + + camsrc_info("Start delete..."); + + /* TODO : Semaphore lock */ + camsrc_lock_sync(¶m); + + if (!(p->is_async_open)) { + close(fd); + } + + chk_fd = open(conf_filename, O_WRONLY | O_NONBLOCK); + if (chk_fd == -1) { + camsrc_info("FD = %d", fd); + return CAMERASRC_ERR_INTERNAL; + } + + len = snprintf(buf, BUF_LEN, "%d:%s", getpid(), CAMERASRC_DEV_RELEASED_STR); + camsrc_info("using string : %s", buf); + + len = snprintf(tot_buf, BUF_LEN, "%d:%s", len, buf); + camsrc_info("write string final : %s", tot_buf); + + len = write(chk_fd, tot_buf, len); + if (len == -1) { + strerror_r(errno, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_info("WRITE ERROR!!!!, error = %s, fd = %d", err_msg, chk_fd); + } + + close(chk_fd); + + camsrc_unlock_sync(¶m); + /* TODO : Semaphore unlock */ + err = CAMERASRC_SUCCESS; + camsrc_info("End delete..."); + + return err; +} + + +static int _camerasrc_initialize_handle(camerasrc_handle_t *handle) +{ + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + /* Initialize handle variables */ + handle->buffer = NULL; + handle->is_async_open = 0; + handle->dev_fd = -1; + handle->cur_dev_id = CAMERASRC_DEV_ID_UNKNOWN; + handle->check_esd = 0; + handle->is_preset = 0; + handle->resolution = 0; + handle->buffer_idx = 0; + handle->num_buffers = 0; + handle->buffer = NULL; + handle->present_buf = NULL; + handle->io_method = CAMERASRC_IO_METHOD_MMAP; + handle->af_status = CAMERASRC_AUTO_FOCUS_STATUS_RELEASED; + handle->af_cmd = CAMERASRC_AUTO_FOCUS_CMD_NULL; + handle->cur_af_mode = CAMERASRC_AF_MODE_AUTO; + handle->cur_af_range = CAMERASRC_AF_RANGE_NORMAL; + handle->af_usr_data = NULL; + handle->skip_frame_func = NULL; + handle->isAutoexposure = 1; + handle->af_cb = NULL; + handle->first_frame = 1; + handle->af_init_called = 0; + handle->hold_af_after_capturing = 0; + + if (gettimeofday(&handle->set_af_area_time, NULL) != 0) { + handle->set_af_area_time.tv_sec = 0; + handle->set_af_area_time.tv_usec = 0; + camsrc_warning("[init handle] gettimeofday Failed"); + } + + CLEAR(handle->queued_buf_list); + CLEAR(handle->format); + + return CAMERASRC_SUCCESS; +} + + +static int _camerasrc_wait_frame_available(camerasrc_handle_t *handle, long int timeout) +{ + camerasrc_handle_t *p = handle; + fd_set fds; + struct timeval tv; + int r; + +#if defined (USE_SKIP_FRAME) + int skip_frame = CAMERASRC_JPG_STILL_SKIP_FRAME; +#endif + + if (p->dev_fd == CAMERASRC_DEV_FD_EMERGENCY_CLOSED) { + /* Wait time FPS time */ + if (p->timeperframe.denominator == 0 && p->timeperframe.numerator == 0) { + usleep((int)1000000/30); /* supposed to 1/30 sec */ + } else { + usleep((int)(1000000 * p->timeperframe.numerator / p->timeperframe.denominator)); + } + + camsrc_info("Device emergency closed. wait will return proper time"); + + return CAMERASRC_SUCCESS; + } + + /** + * @note In preview or video mode, skip_frame_func, signaling_func will be NULL + * If unnecessary, just input them to NULL in start_still/preview/video_stream() + */ + + FD_ZERO(&fds); + FD_SET(p->dev_fd, &fds); + + /* skip frame */ +#if defined (USE_SKIP_FRAME) + if(p->skip_frame_func != NULL) { + camsrc_info("Skip frame function enabled!"); + err = p->skip_frame_func(p, timeout, skip_frame); + } +#endif + + /* set timeout */ + tv.tv_sec = (long int)timeout/1000; + tv.tv_usec = timeout * 1000 - tv.tv_sec * 1000000; + + /* select waiting */ + r = select(p->dev_fd + 1, &fds, NULL, NULL, &tv); + if (-1 == r) { + if (EINTR == errno) { + return CAMERASRC_SUCCESS; + } + camsrc_error("select() failed."); + + return CAMERASRC_ERR_INTERNAL; + } + + if (0 == r) { + return CAMERASRC_ERR_DEVICE_WAIT_TIMEOUT; + } + + return CAMERASRC_SUCCESS; +} + + +struct v4l2_buffer *_camerasrc_get_correct_buf(camerasrc_handle_t *handle, struct v4l2_buffer *queued_buf_list, camerasrc_buffer_t *buffer) +{ + unsigned int num_buffers = 0; + int cnt = 0; + camerasrc_get_num_buffer(handle, &num_buffers); + + for (cnt = 0 ; cnt < num_buffers ; cnt++) { + if (queued_buf_list[cnt].m.userptr == (unsigned long)buffer->start) { + return &(queued_buf_list[cnt]); + } + } + + return NULL; +} + + +static int _camerasrc_queue_buffer(camerasrc_handle_t *handle, int buf_index, camerasrc_buffer_t *buffer) +{ + camerasrc_handle_t *p = handle; + struct v4l2_buffer vbuf; + struct v4l2_buffer *pvbuf; + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + + if (p->dev_fd == CAMERASRC_DEV_FD_EMERGENCY_CLOSED) { + camsrc_info("Device emergency closed. Q will return successfully"); + return CAMERASRC_SUCCESS; + } + + if (buf_index >= p->num_buffers) { + camsrc_info("Late buffer won't be queued, buf_index = %d, p->num_buffers = %d", buf_index, p->num_buffers); + return CAMERASRC_SUCCESS; + } + + CLEAR(vbuf); + + switch (p->io_method) { + case CAMERASRC_IO_METHOD_MMAP: + if (p->buffer[buf_index].queued_status == CAMERASRC_BUFFER_QUEUED) { + camsrc_info("buffer[index:%d] is already queued. return success.", buf_index); + return CAMERASRC_SUCCESS; + } + + vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vbuf.memory = V4L2_MEMORY_MMAP; + vbuf.index = buf_index; + pvbuf = &vbuf; + break; + case CAMERASRC_IO_METHOD_USRPTR: + if (&(p->queued_buf_list[buf_index])) { + pvbuf = _camerasrc_get_correct_buf(handle, p->queued_buf_list, buffer); + } + + if (pvbuf == NULL) { + camsrc_error("Wrong address tried to queueing!, It'll be queued as input index.."); + pvbuf = &(p->queued_buf_list[buf_index]); + } + break; + case CAMERASRC_IO_METHOD_READ: + default: + camsrc_error("Device not support that io-method"); +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + } + + if (CAMERASRC_STATE(handle) == CAMERASRC_STATE_READY) { + camsrc_warning("Q after ready state will success"); + return CAMERASRC_SUCCESS; + } + + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_QBUF, pvbuf)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_info("VIDIOC_QBUF failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + + LOCK(p); + if (p->io_method == CAMERASRC_IO_METHOD_MMAP) { + p->buffer[buf_index].queued_status = CAMERASRC_BUFFER_QUEUED; + p->queued_buffer_count++; + } + UNLOCK(p); + + return CAMERASRC_SUCCESS; +} + + +static int _camerasrc_get_proper_index(camerasrc_handle_t *handle, void *data) +{ + int i = 0; + + for (i = 0; i < handle->num_buffers; i++) { + if (handle->buffer[i].start == data) { + return i; + } + } + + camsrc_info("Index NOT found. new buffer... go to error"); + + return -1; +} + + +static int _camerasrc_dequeue_buffer(camerasrc_handle_t *handle, int *buf_index, camerasrc_buffer_t *buffer, camerasrc_buffer_t *thm_buffer) +{ + camerasrc_handle_t *p = handle; + int err = CAMERASRC_ERR_UNKNOWN; + struct v4l2_buffer vbuf; + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + + if (p->dev_fd == CAMERASRC_DEV_FD_EMERGENCY_CLOSED) { + buf_index = 0; + buffer = &p->alter_frame; + buffer = NULL; + camsrc_info("Device emergency closed. DQ return fake frame"); + return CAMERASRC_SUCCESS; + } + + switch(p->io_method) { + case CAMERASRC_IO_METHOD_MMAP: + CLEAR(vbuf); + vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vbuf.memory = V4L2_MEMORY_MMAP; + break; + case CAMERASRC_IO_METHOD_USRPTR: + CLEAR(vbuf); + vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vbuf.memory = V4L2_MEMORY_USERPTR; + break; + case CAMERASRC_IO_METHOD_READ: + default: + camsrc_error("Device not support that io-method"); +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + } + + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_DQBUF, &vbuf)) { + switch (p->errnum) { + case EAGAIN: + camsrc_info("VIDIOC_DQBUF [EAGAIN]"); + return CAMERASRC_SUCCESS; + case EIO: + /* Could ignore EIO, see spec. */ + /* fall through */ + camsrc_info("VIDIOC_DQBUF [EIO]"); + break; + case EINVAL: + camsrc_info("VIDIOC_DQBUF [EINVAL]"); + printf("VIDIOC_DQBUF [EINVAL]"); + return CAMERASRC_ERR_INVALID_VALUE; + default: + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_info("VIDIOC_DQBUF [%s]", err_msg); + break; + } + } + + /* A F I N I T */ + if (CAMERASRC_STATE(p) == CAMERASRC_STATE_PREVIEW && + p->first_frame && _CAMERASRC_SUPPORT_AF(p->cur_dev_id)) { + camsrc_info("AF init at first frame, hold_Af %d", p->hold_af_after_capturing); + if (!(p->af_init_called) || !(p->hold_af_after_capturing)) { + err = _camerasrc_init_autofocusing_mode(p); + if (err != CAMERASRC_SUCCESS) { + camsrc_warning("AF init failed"); + } else { + p->af_init_called = 1; + } + } else { + camsrc_info("AF init SKIP!"); + } + + p->first_frame = 0; + } + + if (CAMERASRC_STATE(p) == CAMERASRC_STATE_PREVIEW || CAMERASRC_STATE(p) == CAMERASRC_STATE_VIDEO || + (CAMERASRC_STATE(p) == CAMERASRC_STATE_STILL && p->format.colorspace == CAMERASRC_COL_RAW) || + (CAMERASRC_STATE(p) == CAMERASRC_STATE_AF_IN_PROGRESS && p->format.colorspace == CAMERASRC_COL_RAW)) { + switch(p->io_method) { + case CAMERASRC_IO_METHOD_MMAP: + *buf_index = vbuf.index; + buffer->start = p->buffer[vbuf.index].start; + LOCK(p); + p->buffer[vbuf.index].queued_status = CAMERASRC_BUFFER_DEQUEUED; + p->queued_buffer_count--; + UNLOCK(p); +#if 1 + switch (p->format.pix_format ) { + case CAMERASRC_PIX_YUV422P: + case CAMERASRC_PIX_YUY2: + case CAMERASRC_PIX_UYVY: + case CAMERASRC_PIX_RGB565: + buffer->length = YUV422_SIZE(p); + break; + case CAMERASRC_PIX_YUV420P: + case CAMERASRC_PIX_SN12: + case CAMERASRC_PIX_ST12: + case CAMERASRC_PIX_NV12: + buffer->length = YUV420_SIZE(p); + break; + case CAMERASRC_PIX_INTERLEAVED: + { + unsigned char *p_size_info = NULL; +#if 0 + if (vbuf.index == 2) { + FILE *fp = fopen("./test2.dump", "w+"); + fwrite(buffer->start, p->buffer[vbuf.index].length, 1, fp); + fflush(fp); + fclose(fp); + } +#endif + p_size_info = (unsigned char *)(buffer->start + (p->buffer[vbuf.index].length - ITLV_DATA_INFO_OFFSET)); + buffer->length = (unsigned int)(p_size_info[EMBEDDED_OFFSET]<<24) + (p_size_info[EMBEDDED_OFFSET+1]<<16) + (p_size_info[EMBEDDED_OFFSET+2]<<8) + p_size_info[EMBEDDED_OFFSET+3]; + camsrc_info("total %d, addr %x, data size %d", + (int)(p->buffer[vbuf.index].length), buffer->start, buffer->length); + break; + } + case CAMERASRC_PIX_RGGB10: + case CAMERASRC_PIX_RGGB8: + default: + buffer->length = -1; + break; + } +#else + buffer->length = vbuf.bytesused; +#endif + break; + case CAMERASRC_IO_METHOD_USRPTR: + { + int i = 0; + int dequeued = 0; + + for (i = 0; i < p->present_buf->num_buffer; ++i) { +#if defined (USE_USERPTR_DEBUG) + camsrc_info("buffers[%d].start: %p", i, p->buffer[i].start); + camsrc_info("buffers[%d].length: %d", i, p->buffer[i].length); + camsrc_info("buf.m.userptr: %p", vbuf.m.userptr); + camsrc_info("buf.length: %d", vbuf.length); +#endif + if (vbuf.m.userptr == (unsigned long) p->buffer[i].start) { + dequeued = 1; + break; + } + } + + if (!dequeued) { + camsrc_error("Dequeued buffer not matched to user ptr!"); + return CAMERASRC_ERR_IO_CONTROL; + } + + *buf_index = _camerasrc_get_proper_index(p, (void*)vbuf.m.userptr); + buffer->start = (unsigned char*)vbuf.m.userptr; + buffer->length = vbuf.length; + + break; + } + case CAMERASRC_IO_METHOD_READ: + default: + camsrc_error("Device not support that io-method"); +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + break; + } + } else if (CAMERASRC_STATE(p) == CAMERASRC_STATE_STILL && p->format.colorspace == CAMERASRC_COL_JPEG) { + /* JPEG Capture */ + switch (p->io_method) { + case CAMERASRC_IO_METHOD_MMAP: + camsrc_info("JPEG frame dequeueing.."); + *buf_index = vbuf.index; + buffer->start = p->buffer[vbuf.index].start; + buffer->length = _camerasrc_get_JPG_length(p); + LOCK(p); + p->buffer[vbuf.index].queued_status = CAMERASRC_BUFFER_DEQUEUED; + p->queued_buffer_count--; + UNLOCK(p); + camsrc_info("JPEG frame length = %d", buffer->length); + /* If splitted thumbnail jpeg, it should know about both sizes */ + if (thm_buffer != NULL) { + if(p->format.pix_format == CAMERASRC_PIX_RGGB10) { + thm_buffer->start = p->buffer[vbuf.index].start + CAMERASRC_RAW_STILL_THUMBNAIL_OFFSET; + thm_buffer->length = CAMERASRC_YUV_THMBNL_SIZE; + camsrc_info("Thumbnail JPEG frame length = %d", thm_buffer->length); + } + else if(p->format.pix_format == CAMERASRC_PIX_RGGB8) { + unsigned int thumb_offset = 0, thumb_length = 0; + + thumb_offset = _camerasrc_get_thumbnail_JPG_offset(p); + thumb_length = _camerasrc_get_thumbnail_JPG_length(p); + + if( thumb_offset == 0 || thumb_length == 0 ) + { + thm_buffer->start = NULL; + thm_buffer->length = 0; + camsrc_info("Get Thumbnail JPEG frame failed.(offset:0x%x,length:%d)", thumb_offset, thumb_length); + } + else + { + thm_buffer->start = p->buffer[vbuf.index].start + thumb_offset; + thm_buffer->length = thumb_length; + camsrc_info("Thumbnail JPEG frame %p (offset 0x%x, length %d)", thm_buffer->start, thumb_offset, thumb_length); + } + } + else { + camsrc_error("Unknown image format... "); +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + } + } + + /* Get screennail buffer */ + p->scrnl_buf.start = p->buffer[vbuf.index].start + _camerasrc_get_screennail_JPG_offset(p); + p->scrnl_buf.length = _camerasrc_get_screennail_JPG_length(p); + + /** + * In some module(or along firmware), it doesn't support jpg image + * splitted with thumbnail And its size always reported as bytesused field. + * "buffer->length == 0" means it won't support splitted jpg output + */ + camsrc_info("buffer->length = %d, vbuf.bytesused=%d", buffer->length, vbuf.bytesused); + if (buffer->length == 0) { + camsrc_info("it'll be copied as size = %d", vbuf.bytesused); + buffer->length = vbuf.bytesused; + } + + break; + case CAMERASRC_IO_METHOD_USRPTR: + { + int i = 0; + int dequeued = 0; + + for (i = 0; i < p->present_buf->num_buffer; ++i) { +#if defined (USE_USERPTR_DEBUG) + camsrc_info("buffers[%d].start: %d", i, p->buffer[i].start); + camsrc_info("buffers[%d].length: %d", i, p->buffer[i].length); + camsrc_info("buf.m.userptr: %d", vbuf.m.userptr); + camsrc_info("buf.length: %d", vbuf.length); +#endif + if (vbuf.m.userptr == (unsigned long) p->buffer[i].start) { + dequeued = 1; + break; + } + } + + if (!dequeued) { + camsrc_error("Dequeued buffer not matched to user ptr!"); + return CAMERASRC_ERR_IO_CONTROL; + } + + camsrc_info("JPEG frame dequeueing.."); + *buf_index = vbuf.index; + buffer->start = (unsigned char*)vbuf.m.userptr; + buffer->length = _camerasrc_get_JPG_length(p); + if (buffer->length == 0) { + return CAMERASRC_ERR_INVALID_PARAMETER; + } + camsrc_info("JPEG frame length = %d", buffer->length); + + if (thm_buffer != NULL) { + if (p->format.pix_format == CAMERASRC_PIX_RGGB10) { + /* JPEG + YUV thumbnail */ + thm_buffer->start = p->buffer[i].start + CAMERASRC_RAW_STILL_THUMBNAIL_OFFSET; + thm_buffer->length = CAMERASRC_YUV_THMBNL_SIZE; + camsrc_info("Thumbnail JPEG frame length = %d", thm_buffer->length); + } else if(p->format.pix_format == CAMERASRC_PIX_RGGB8) { + /* JPEG + JPEG thumbnail */ + thm_buffer->start = p->buffer[i].start + CAMERASRC_JPG_STILL_THUMBNAIL_OFFSET; + thm_buffer->length = _camerasrc_get_thumbnail_JPG_length(p); + if (buffer->length == 0) { + return CAMERASRC_ERR_INVALID_PARAMETER; + } + camsrc_info("Thumbnail JPEG frame length = %d", thm_buffer->length); + } else { + camsrc_error("Unknown image format... "); +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + } + } + break; + } + case CAMERASRC_IO_METHOD_READ: + default: + camsrc_error("Device not support that io-method"); +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + break; + } + } else { + camsrc_error("Invalid state transition"); + return CAMERASRC_ERR_INVALID_STATE; + } + + return CAMERASRC_SUCCESS; +} + +static int _camerasrc_dump_format(camsrc_handle_t handle); + +/**** M A I N O P E R A T I O N ****/ +int camerasrc_create(camsrc_handle_t *phandle) +{ + camerasrc_handle_t *p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + + camsrc_info("enter"); + + if (phandle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = (camerasrc_handle_t *)malloc(sizeof(camerasrc_handle_t)); + if(p == NULL) { + camsrc_error("malloc fail"); + return CAMERASRC_ERR_ALLOCATION; + } + + memset(p, '\0', sizeof(camerasrc_handle_t)); + + /* STATE TO MEANINGFUL STATE */ + p->cur_state = CAMERASRC_STATE_NONE; + CAMERASRC_SET_STATE(p, CAMERASRC_STATE_CREATED); + CAMERASRC_SET_PHASE(p, CAMERASRC_PHASE_NON_RUNNING); + camsrc_info("Transit to non-running phase"); + + /* INIT VARIABLES */ + err = _camerasrc_initialize_handle(p); + if(err != CAMERASRC_SUCCESS) { + camsrc_error("Invalid handle"); + return CAMERASRC_ERR_INVALID_HANDLE; + } + + err = pthread_mutex_init(&(p->mutex), NULL); + if(err) { + strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_info("Mutex creating status : %s", err_msg); + } + + err = pthread_mutex_init(&(p->af_mutex), NULL); + if(err) { + strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_info("AF Mutex creating status : %s", err_msg); + } + + err = pthread_cond_init(&(p->af_wait_cond), NULL); + if(err) { + strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_info("AF Condition creating status : %s", err_msg); + } + + camsrc_info("Thread creation start.."); + err = pthread_create(&p->focusing_thread, NULL, (void*)_camerasrc_run_autofocusing, p); + if(err) { + strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_info("AF Thread creating status : %s", err_msg); + } + + camsrc_info("Thread creation end.."); + + *phandle = (camsrc_handle_t)p; + err = CAMERASRC_SUCCESS; + return err; +} + + +int camerasrc_destroy(camsrc_handle_t handle) +{ + camerasrc_handle_t* p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + + camsrc_info("enter"); + + if(handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if(CAMERASRC_STATE(p) != CAMERASRC_STATE_UNREALIZED) { + camsrc_warning("Invalid state transition"); + } + + /* Remove AF thread */ + _camerasrc_destroy_autofocusing(p); + + camsrc_info("Thread join wait start.."); + err = pthread_join(p->focusing_thread, NULL); + if(err) { + strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_info("AF Thread join status : %s", err_msg); + } + + camsrc_info("Thread join wait end.."); + + err = pthread_cond_destroy(&p->af_wait_cond); + if(err) { + strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_info("AF Condition destroying error : %s", err_msg); + } + + err = pthread_mutex_destroy(&(p->af_mutex)); + if(err) { + strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_info("AF Mutex destroying error : %s", err_msg); + } + + err = pthread_mutex_destroy(&(p->mutex)); + if(err) { + strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_info("Mutex destroying error : %s", err_msg); + } + + free((void*)p); + handle = NULL; + err = CAMERASRC_SUCCESS; + return err; +} + + +int camerasrc_close_device(camsrc_handle_t handle) +{ + camerasrc_handle_t* p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if(handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + p->is_async_open = 0; + +#if defined(USE_OPEN_CHK) + if(!CAMERASRC_IS_DEV_CLOSED(p)) { + err = _camerasrc_seamless_delete_onaccess(CAMERASRC_OPENED_CHK_FILENAME, p); + if(err != CAMERASRC_SUCCESS) { + return CAMERASRC_ERR_INTERNAL; + } + p->dev_fd = CAMERASRC_DEV_FD_EMERGENCY_CLOSED; + } +#else + if(!CAMERASRC_IS_DEV_CLOSED(p)) { + + if( !(p->is_async_open) ) { + close(p->dev_fd); + } + + p->dev_fd = CAMERASRC_DEV_FD_EMERGENCY_CLOSED; + } + /* prepare "Kagemusha" frame data */ + LOCK(p); + memcpy(p->alter_frame.start, p->buffer[0].start, p->alter_frame.length); + UNLOCK(p); +#endif + return CAMERASRC_SUCCESS; +} + + +int camerasrc_get_state(camsrc_handle_t handle, camerasrc_state_t* state) +{ + camerasrc_handle_t* p = NULL; + + if(handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + *state = CAMERASRC_STATE(p); + return CAMERASRC_SUCCESS; +} + + +int camerasrc_realize(camsrc_handle_t handle) +{ + camerasrc_handle_t* p = NULL; + int ret = CAMERASRC_SUCCESS; + + camerasrc_sync_param_t param = {CAMERASRC_SYNC_KEY_PATH, CAMERASRC_SYNC_KEY_PREFIX}; + mode_t mask = 0; + + camsrc_info("enter"); + + if(handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + /* STATE OR PHASE CHECKING */ + if(CAMERASRC_STATE(p) == CAMERASRC_STATE_REALIZED) { + return CAMERASRC_SUCCESS; + } + if(CAMERASRC_STATE(p) != CAMERASRC_STATE_CREATED && + CAMERASRC_STATE(p) != CAMERASRC_STATE_UNREALIZED) { + camsrc_warning("Invalid state transition"); + } + + mask = umask(0); + + /* CREATE SEMAPHORE */ + camsrc_create_sync(¶m); + + /* O P E N D E V I C E */ +#if defined(USE_OPEN_CHK) + ret = _camerasrc_chk_opened(CAMERASRC_OPENED_CHK_FILENAME); + if (ret == CAMERASRC_SUCCESS) { + ret = _camerasrc_seamless_record_onaccess_open(CAMERASRC_OPENED_CHK_FILENAME, p); + if (ret != CAMERASRC_SUCCESS) { + camsrc_error("_camerasrc_seamless_record_onaccess_open failed %x", ret); + } + } +#else /* USE_OPEN_CHK */ + if (!CAMERASRC_IS_DEV_CLOSED(p)) { + ret = __camerasrc_open_device(p); + if (ret != CAMERASRC_SUCCESS) { + camsrc_error("camera open failed %x", ret); + } else { + p->is_async_open = 0; + } + } else { + p->is_async_open = 1; + } +#endif /* USE_OPEN_CHK */ + + umask(mask); + + if (ret == CAMERASRC_SUCCESS) { + CAMERASRC_SET_STATE(p, CAMERASRC_STATE_REALIZED); + } + + return ret; +} + + +int camerasrc_unrealize(camsrc_handle_t handle) +{ + camerasrc_handle_t* p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if(handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if(CAMERASRC_STATE(p) == CAMERASRC_STATE_UNREALIZED || + CAMERASRC_STATE(p) == CAMERASRC_STATE_DESTROYED) { + return CAMERASRC_SUCCESS; + } + if(CAMERASRC_STATE(p) != CAMERASRC_STATE_READY) { + camsrc_warning("Invalid state transition"); + } + +#if defined(USE_OPEN_CHK) + if(!CAMERASRC_IS_DEV_CLOSED(p)) { + err = _camerasrc_seamless_delete_onaccess(CAMERASRC_OPENED_CHK_FILENAME, p); + if(err != CAMERASRC_SUCCESS) { + return CAMERASRC_ERR_INTERNAL; + } + } +#else /* USE_OPEN_CHK */ + if(!CAMERASRC_IS_DEV_CLOSED(p)) { + + if( !(p->is_async_open) ) { + close(p->dev_fd); + } + } +#endif /* USE_OPEN_CHK */ + + p->dev_fd = -1; + p->check_esd = 0; + + CAMERASRC_SET_STATE(p, CAMERASRC_STATE_UNREALIZED); + CAMERASRC_SET_PHASE(p, CAMERASRC_PHASE_NON_RUNNING); + camsrc_info("Transit to non-running phase"); + err = CAMERASRC_SUCCESS; + return err; +} + + +int camerasrc_start(camsrc_handle_t handle) +{ + camerasrc_handle_t* p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if(handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + /* STATE OR PHASE CHECKING */ + if(CAMERASRC_STATE(p) == CAMERASRC_STATE_READY) { + return CAMERASRC_SUCCESS; + } + if(CAMERASRC_STATE(p) != CAMERASRC_STATE_REALIZED) { + camsrc_warning("Invalid state transition"); + } + + CAMERASRC_SET_STATE(p, CAMERASRC_STATE_READY); + CAMERASRC_SET_PHASE(p, CAMERASRC_PHASE_RUNNING); + + camsrc_info("Transit to running phase"); + err = CAMERASRC_SUCCESS; + return err; +} + + +int camerasrc_present_usr_buffer(camsrc_handle_t handle, camerasrc_usr_buf_t *present_buf, camerasrc_io_method_t io_method) +{ + camerasrc_handle_t *p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_STATE(p) != CAMERASRC_STATE_READY) { + camsrc_warning("Invalid state transition"); + } + + switch(io_method) { + case CAMERASRC_IO_METHOD_MMAP: + camsrc_info("MMAP mode"); + if (present_buf != NULL) { + camsrc_error("present_buf should be NULL in MMAP Mode"); +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + } + p->io_method = CAMERASRC_IO_METHOD_MMAP; + break; + case CAMERASRC_IO_METHOD_USRPTR: + camsrc_info("USRPTR mode"); + if (present_buf == NULL) { + camsrc_error("present_buf should NOT be NULL in USRPTR Mode"); + return CAMERASRC_ERR_ALLOCATION; + } + + if (present_buf->num_buffer > CAMERASRC_USRPTR_MAX_BUFFER_NUM) { + camsrc_warning("Use up tp MAX %d buffer only", CAMERASRC_USRPTR_MAX_BUFFER_NUM); + present_buf->num_buffer = CAMERASRC_USRPTR_MAX_BUFFER_NUM; + } + p->present_buf = present_buf; + p->io_method = CAMERASRC_IO_METHOD_USRPTR; + break; + case CAMERASRC_IO_METHOD_READ: + default: +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + break; + } + + err = CAMERASRC_SUCCESS; + return err; +} + + +int camerasrc_get_num_buffer(camsrc_handle_t handle, unsigned int *num_buffer) +{ + camerasrc_handle_t *p = NULL; + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + camerasrc_state_t state = CAMERASRC_STATE_NONE; + camerasrc_get_state(handle, &state); + + switch(state) { + case CAMERASRC_STATE_NONE: + case CAMERASRC_STATE_CREATED: + case CAMERASRC_STATE_REALIZED: + case CAMERASRC_STATE_READY: + case CAMERASRC_STATE_UNREALIZED: + case CAMERASRC_STATE_DESTROYED: + camsrc_warning("Current buffer number not initialized."); + *num_buffer = 0; + break; + case CAMERASRC_STATE_PREVIEW: + case CAMERASRC_STATE_STILL: + case CAMERASRC_STATE_VIDEO: + case CAMERASRC_STATE_AF_IN_PROGRESS: + *num_buffer = p->num_buffers; + break; + default: + camsrc_error("Unknown state"); + *num_buffer = -1; + return CAMERASRC_ERR_INVALID_STATE; + } + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_get_io_method(camsrc_handle_t handle, camerasrc_io_method_t* io_method) +{ + camerasrc_handle_t *p = NULL; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + *io_method = p->io_method; + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_start_still_stream(camsrc_handle_t handle) +{ + camerasrc_handle_t* p = NULL; + struct v4l2_streamparm vstreamparm; + struct v4l2_format vformat; + struct v4l2_requestbuffers vreq_bufs; + enum v4l2_buf_type vtype; + int cnt = 0; + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_STATE(p) == CAMERASRC_STATE_STILL) { + return CAMERASRC_SUCCESS; + } + + if (CAMERASRC_STATE(p) != CAMERASRC_STATE_READY) { + camsrc_warning("Invalid state transition"); + } + + /* S T I L L M O D E S E T T I N G */ + /* + * If driver can control thmbnl size, we do that here, if not support, it's OK + * Driver should change jpeg compress ration before start stream + */ + CLEAR(vstreamparm); + vstreamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + __ta__( " Stillshot VIDIOC_G_PARM", + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_G_PARM, &vstreamparm)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_G_PARAM failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + ); + + if (p->format.is_highquality_mode == 1) { + camsrc_info("High quality frame will be captured"); + vstreamparm.parm.capture.capturemode = V4L2_MODE_HIGHQUALITY; + } else if(p->format.is_highquality_mode == 0) { + camsrc_info("Normal quality frame will be captured"); + vstreamparm.parm.capture.capturemode = 0; + } else { + camsrc_info("Quality not initialized, or incorrect value. set high quality..."); + vstreamparm.parm.capture.capturemode = V4L2_MODE_HIGHQUALITY; + } + + vstreamparm.parm.capture.timeperframe.numerator = p->timeperframe.numerator; + vstreamparm.parm.capture.timeperframe.denominator = p->timeperframe.denominator; + camsrc_info("[FPS] timeperframe.numerator = %d", p->timeperframe.numerator); + camsrc_info("[FPS] timeperframe.denominator = %d", p->timeperframe.denominator); + camsrc_info("[QUA] vstreamparm.parm.capture.capturemode = %d", vstreamparm.parm.capture.capturemode); + __ta__( " Stillshot VIDIOC_S_PARM", + if(CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_S_PARM, &vstreamparm)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_S_PARAM failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + ); + + /* S T I L L F O R M A T S E T T I N G */ + CLEAR(vformat); + _camerasrc_dump_format(p); + vformat.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + switch (p->format.pix_format) { + case CAMERASRC_PIX_YUV420P: + camsrc_info("420P capture activated.."); + vformat.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; + break; + case CAMERASRC_PIX_YUV422P: + camsrc_info("422P capture activated.."); + vformat.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P; + break; + case CAMERASRC_PIX_SN12: + case CAMERASRC_PIX_NV12: + camsrc_info("NV12(SN12) capture activated.."); + vformat.fmt.pix.pixelformat = V4L2_PIX_FMT_NV12; + break; + case CAMERASRC_PIX_ST12: + camsrc_info("NV12T capture activated.."); + vformat.fmt.pix.pixelformat = V4L2_PIX_FMT_NV12T; + break; + case CAMERASRC_PIX_YUY2: + camsrc_info("YUY2 capture activated.."); + vformat.fmt.pix.pixelformat = CAMERASRC_V4L2_PREVIEW_PIX_FMT_DEFAULT; + break; + /* Kessler capture path */ + case CAMERASRC_PIX_RGGB8: + camsrc_info("JPEG+JPEG capture activated.."); + vformat.fmt.pix.pixelformat = CAMERASRC_V4L2_JPEG_CAPTURE_PIX_FMT_DEFAULT; + break; + case CAMERASRC_PIX_RGGB10: + camsrc_info("JPEG+YUV capture activated.."); + vformat.fmt.pix.pixelformat = CAMERASRC_V4L2_JPG_YUV_CAPTURE_PIX_FMT_DEFAULT; + break; + default: + camsrc_error("Not supported format!"); + break; + } + + camsrc_info("JPG unified size capture avtivated!"); + vformat.fmt.pix.width = p->format.img_size.dim.width; /*capture width*/ + vformat.fmt.pix.height = p->format.img_size.dim.height; /*capture height*/ + vformat.fmt.pix_mp.field = V4L2_FIELD_NONE; + __ta__( " Stillshot VIDIOC_S_FMT", + if(CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_S_FMT, &vformat)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_S_FMT failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + ); + + camsrc_info("Stillshot VIDIOC_S_FMT done"); + + CLEAR(vreq_bufs); + + /* M E M O R Y M A P P I N G */ + switch (p->io_method) { + case CAMERASRC_IO_METHOD_MMAP: + camsrc_info("MMAP mode"); + + if (vformat.fmt.pix.pixelformat == CAMERASRC_V4L2_JPEG_CAPTURE_PIX_FMT_DEFAULT ) { + vreq_bufs.count = CAMERASRC_STILL_BUFFER_NUM; + } else { + vreq_bufs.count = CAMERASRC_PREVIEW_BUFFER_NUM; + } + vreq_bufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vreq_bufs.memory = V4L2_MEMORY_MMAP; + + camsrc_info("VIDIOC_REQBUFS count:%d, type:%d, memory:%d", + vreq_bufs.count, vreq_bufs.type, vreq_bufs.memory); + + __ta__( " Stillshot VIDIOC_REQBUFS", + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_REQBUFS, &vreq_bufs)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_REQBUFS failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + ); + + camsrc_info("Stillshot VIDIOC_REQBUFS done"); + camsrc_assert(vreq_bufs.count >= 1); + + p->num_buffers = vreq_bufs.count; + p->buffer = calloc (vreq_bufs.count, sizeof (camerasrc_buffer_t)); + + if (!p->buffer) { + camsrc_error("calloc() failed"); + return CAMERASRC_ERR_ALLOCATION; + } + + __ta__( " Stillshot VIDIOC_QUERYBUF,mmap", + for (p->buffer_idx = 0 ; p->buffer_idx < vreq_bufs.count ; ++(p->buffer_idx)) { + struct v4l2_buffer vbuf; + CLEAR(vbuf); + + vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vbuf.memory = V4L2_MEMORY_MMAP; + vbuf.index = p->buffer_idx; + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_QUERYBUF, &vbuf)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_QUERYBUF failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + + p->buffer[p->buffer_idx].length = vbuf.length; + p->buffer[p->buffer_idx].start = mmap(NULL /* start anywhere */, + vbuf.length, + PROT_READ | PROT_WRITE, + MAP_SHARED, + p->dev_fd, vbuf.m.offset); + if (MAP_FAILED == p->buffer[p->buffer_idx].start) { + camsrc_error("mmap failed."); + return CAMERASRC_ERR_ALLOCATION; + } + + camsrc_info("MMAP BUF: addr[%p] size[%d]", + p->buffer[p->buffer_idx].start, p->buffer[p->buffer_idx].length); + } + ); + + camsrc_info("Stillshot VIDIOC_QUERYBUF and mmap done"); + break; + + case CAMERASRC_IO_METHOD_USRPTR: + camsrc_info("USRPTR mode"); + + vreq_bufs.count = p->present_buf->num_buffer; + vreq_bufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vreq_bufs.memory = V4L2_MEMORY_USERPTR; + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_REQBUFS, &vreq_bufs)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_REQBUFS failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + + camsrc_assert(vreq_bufs.count >= 1); + + p->num_buffers = vreq_bufs.count; + p->buffer = calloc (vreq_bufs.count, sizeof (camerasrc_buffer_t)); + + if (!p->buffer) { + camsrc_error("calloc() failed"); + return CAMERASRC_ERR_ALLOCATION; + } + + if (!p->present_buf->present_buffer) { + camsrc_error("No Usrptr buffer presented!"); + return CAMERASRC_ERR_ALLOCATION; + } + + for (p->buffer_idx = 0; p->buffer_idx < vreq_bufs.count; ++(p->buffer_idx)) { + p->buffer[p->buffer_idx].length = p->present_buf->present_buffer[p->buffer_idx].length; + p->buffer[p->buffer_idx].start = p->present_buf->present_buffer[p->buffer_idx].start; + + if (!p->buffer[p->buffer_idx].start) { + camsrc_error("presented usrptr buffer is NULL"); + return CAMERASRC_ERR_ALLOCATION; + } + + camsrc_info("USERPTR BUF: addr[%p] size[%d]", + p->buffer[p->buffer_idx].start, p->buffer[p->buffer_idx].length); + } + break; + + case CAMERASRC_IO_METHOD_READ: + default: + camsrc_error("Device not support that io-method"); +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + break; + } + + /* calibrate rotation - kernel of c210 could not support V4L2_CID_PHYSICAL_ROTATION */ + if (p->cur_dev_id == CAMERASRC_DEV_ID_SECONDARY) { + p->format.rotation += 180; + p->format.rotation = p->format.rotation % 360; + camsrc_info("Calibrate rotate : secondary camera +180 degree"); + } + + /* Rotation set */ + __ta__( " _CAMERASRC_CMD_ROTATION", + CAMERASRC_SET_CMD(_CAMERASRC_CMD_ROTATION, &(p->format.rotation)); + ); + + /* Sensor flip */ + __ta__( " _CAMERASRC_CMD_VFLIP", + CAMERASRC_SET_CMD(_CAMERASRC_CMD_VFLIP, &(p->vflip)); + ); + + __ta__( " _CAMERASRC_CMD_HFLIP", + CAMERASRC_SET_CMD(_CAMERASRC_CMD_HFLIP, &(p->hflip)); + ); + + /* set JPEG quality */ + if (p->format.pix_format == CAMERASRC_PIX_RGGB8) { + int err = CAMERASRC_ERR_UNKNOWN; + struct v4l2_control control; + + control.id = V4L2_CID_CAM_JPEG_QUALITY; + control.value = p->format.quality; + camsrc_info("[VIDIOC_S_CTRL] V4L2_CID_CAM_JPEG_QUALITY -> %d", control.value); + __ta__( " Stillshot V4L2_CID_CAM_JPEG_QUALITY", + err = _camerasrc_ioctl(p, VIDIOC_S_CTRL, &control); + ); + if (err != CAMERASRC_SUCCESS) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("V4L2_CID_CAMERA_CAPTURE failed : %s", err_msg); + return err; + } + } + + /* A C T U A L S T A R T S T R E A M */ + switch(p->io_method) { + case CAMERASRC_IO_METHOD_MMAP: + camsrc_info("MMAP mode"); + + p->queued_buffer_count = 0; + for (cnt = 0; cnt < p->num_buffers; cnt++) { + struct v4l2_buffer lvbuf; + CLEAR(lvbuf); + + lvbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + lvbuf.memory = V4L2_MEMORY_MMAP; + lvbuf.index = cnt; + __ta__( " Stillshot VIDIOC_QBUF", + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_QBUF, &lvbuf)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_QBUF failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + ); + + LOCK(p); + p->buffer[lvbuf.index].queued_status = CAMERASRC_BUFFER_QUEUED; + p->queued_buffer_count++; + UNLOCK(p); + } + + camsrc_info("Stillshot VIDIOC_QBUF done"); + + vtype = V4L2_BUF_TYPE_VIDEO_CAPTURE; + __ta__( " Stillshot VIDIOC_STREAMON", + if( CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_STREAMON, &vtype)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_STREAMON failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + ); + camsrc_info("Stillshot VIDIOC_STREAMON done"); + break; + + case CAMERASRC_IO_METHOD_USRPTR: + camsrc_info("USRPTR mode"); + for (cnt = 0; cnt < p->present_buf->num_buffer; cnt++) { + struct v4l2_buffer lvbuf; + CLEAR(lvbuf); + + lvbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + lvbuf.memory = V4L2_MEMORY_USERPTR; + lvbuf.index = cnt; + lvbuf.m.userptr = (unsigned long)p->buffer[cnt].start; + lvbuf.length = p->buffer[cnt].length; + + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_QBUF, &lvbuf)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_QBUF failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + } + + camsrc_info("Stillshot VIDIOC_QBUF done"); + + vtype = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_STREAMON, &vtype)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_STREAMON failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + camsrc_info("Stillshot VIDIOC_STREAMON done"); + break; + + case CAMERASRC_IO_METHOD_READ: + default: + camsrc_error("Device not support that io-method"); +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + break; + } + + /* C210 Legacy V4L2 API for capture */ + if (p->format.pix_format == CAMERASRC_PIX_RGGB8) { + int err = CAMERASRC_ERR_UNKNOWN; + struct v4l2_control control; + + control.id = V4L2_CID_CAMERA_CAPTURE; + control.value = 0; + camsrc_info("[VIDIOC_S_CTRL] V4L2_CID_CAMERA_CAPTURE -> 0"); + __ta__( " Stillshot V4L2_CID_CAMERA_CAPTURE", + err = _camerasrc_ioctl(p, VIDIOC_S_CTRL, &control); + ); + if (err != CAMERASRC_SUCCESS) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("V4L2_CID_CAMERA_CAPTURE failed : %s", err_msg); + return err; + } + } + + + LOCK(p); + __ta__( " Stillshot skip_frame_func", + if (_CAMERASRC_NEED_MISC_FUNCTION(p->cur_dev_id, CAMERASRC_OP_CAPTURE, p->format.colorspace, CAMERASRC_MISC_SKIP_FRAME)) { + p->skip_frame_func = (camerasrc_skip_frame_func_t)_camerasrc_skip_frame; + } else { + p->skip_frame_func = NULL; + } + ); + UNLOCK(p); + +#if defined(USE_SKIP_FRAME_AT_RAW_FRAME) + /*< If YUV capture, */ + if (!p->format.is_highquality_mode) { + if (p->skip_frame_func != NULL) { + p->skip_frame_func(p, 5000, 3); + } + } +#endif + + CAMERASRC_SET_STATE(p, CAMERASRC_STATE_STILL); + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_start_preview_stream(camsrc_handle_t handle) +{ + camerasrc_handle_t* p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + struct v4l2_streamparm vstreamparm; + struct v4l2_format vformat; + struct v4l2_requestbuffers vreq_bufs; + struct v4l2_control control; + enum v4l2_buf_type vtype; + int cnt = 0; + int preview_width = 0; + int preview_height = 0; +/* + int capture_width = 0; + int capture_height = 0; +*/ + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + /* STATE OR PHASE CHECKING */ + if(CAMERASRC_STATE(p) == CAMERASRC_STATE_PREVIEW) { + return CAMERASRC_SUCCESS; + } + if(CAMERASRC_STATE(p) != CAMERASRC_STATE_READY) { + camsrc_warning("Invalid state transition"); + } + + /* P R E V I E W M O D E S E T T I N G */ + CLEAR(vstreamparm); + vstreamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + __ta__( " VIDIOC_G_PARM", + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_G_PARM, &vstreamparm)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_G_PARAM failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + ); + + vstreamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + if ((vstreamparm.parm.capture.timeperframe.numerator != p->timeperframe.numerator) || + (vstreamparm.parm.capture.timeperframe.denominator != p->timeperframe.denominator) || + ((p->format.is_highquality_mode == 1) &&(vstreamparm.parm.capture.capturemode != V4L2_MODE_HIGHQUALITY)) || + ((p->format.is_highquality_mode == 0) &&(vstreamparm.parm.capture.capturemode != 0))) { + if (p->format.is_highquality_mode == 1) { + camsrc_info("High quality frame will be captured"); + vstreamparm.parm.capture.capturemode = V4L2_MODE_HIGHQUALITY; + } else if (p->format.is_highquality_mode == 0) { + camsrc_info("Normal quality frame will be captured"); + vstreamparm.parm.capture.capturemode = 0; + } else { + camsrc_info("Quality not initialized, or incorrect value. set normal quality..."); + vstreamparm.parm.capture.capturemode = 0; + } + + vstreamparm.parm.capture.timeperframe.numerator = p->timeperframe.numerator; + vstreamparm.parm.capture.timeperframe.denominator = p->timeperframe.denominator; + + camsrc_info("[FPS] timeperframe.numerator = %d", p->timeperframe.numerator); + camsrc_info("[FPS] timeperframe.denominator = %d", p->timeperframe.denominator); + camsrc_info("[QUA] vstreamparm.parm.capture.capturemode = %d", vstreamparm.parm.capture.capturemode); + + __ta__( " VIDIOC_S_PARM", + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_S_PARM, &vstreamparm)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_S_PARAM failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + ); + } + + /* P R E V I E W F O R M A T S E T T I N G */ + if (!(p->format.pix_format == CAMERASRC_PIX_YUV422P || p->format.pix_format == CAMERASRC_PIX_YUV420P || + p->format.pix_format == CAMERASRC_PIX_SN12 || p->format.pix_format == CAMERASRC_PIX_ST12 || + p->format.pix_format == CAMERASRC_PIX_NV12 || p->format.pix_format == CAMERASRC_PIX_YUY2 || + p->format.pix_format == CAMERASRC_PIX_UYVY || p->format.pix_format == CAMERASRC_PIX_INTERLEAVED) ) { + camsrc_error("Invalid output format."); + return CAMERASRC_ERR_INVALID_FORMAT; + } + + if (p->format.colorspace != CAMERASRC_COL_RAW) { + camsrc_error("Invalid store method."); + return CAMERASRC_ERR_INVALID_PARAMETER; + } + + err = _camerasrc_dump_format(handle); + if (err != CAMERASRC_SUCCESS) { + camsrc_error("Format dump error"); + return err; + } + + preview_width = p->format.img_size.dim.width; + preview_height = p->format.img_size.dim.height; + + CLEAR(vformat); + vformat.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vformat.fmt.pix.width = preview_width; + vformat.fmt.pix.height = preview_height; + vformat.fmt.pix.field = V4L2_FIELD_NONE; + + switch (p->format.pix_format) { + case CAMERASRC_PIX_YUV422P: + vformat.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P; + vformat.fmt.pix.bytesperline = preview_width << 1; + vformat.fmt.pix.sizeimage = (preview_width * preview_height) << 1; + break; + case CAMERASRC_PIX_YUY2: + vformat.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; + vformat.fmt.pix.bytesperline = preview_width << 1; + vformat.fmt.pix.sizeimage = (preview_width * preview_height) << 1; + break; + case CAMERASRC_PIX_UYVY: + vformat.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY; + vformat.fmt.pix.bytesperline = preview_width << 1; + vformat.fmt.pix.sizeimage = (preview_width * preview_height) << 1; + break; + case CAMERASRC_PIX_YUV420P: + vformat.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; + vformat.fmt.pix.bytesperline = (preview_width * 3) >> 1; + vformat.fmt.pix.sizeimage = (preview_width * preview_height * 3) >> 1; + break; + case CAMERASRC_PIX_NV12: + case CAMERASRC_PIX_SN12: + vformat.fmt.pix.pixelformat = V4L2_PIX_FMT_NV12; + vformat.fmt.pix.bytesperline = (preview_width * 3) >> 1; + vformat.fmt.pix.sizeimage = (preview_width * preview_height * 3) >> 1; + break; + case CAMERASRC_PIX_ST12: + vformat.fmt.pix.pixelformat = V4L2_PIX_FMT_NV12T; + vformat.fmt.pix.bytesperline = (preview_width * 3) >> 1; + vformat.fmt.pix.sizeimage = (preview_width * preview_height * 3) >> 1; + break; + case CAMERASRC_PIX_INTERLEAVED: /* JPEG + YUYV */ + vformat.fmt.pix.pixelformat = V4L2_PIX_FMT_INTERLEAVED; + vformat.fmt.pix.priv = V4L2_PIX_FMT_MODE_PREVIEW; + vformat.fmt.pix.field = IS_MODE_PREVIEW_STILL; + /* TODO: Set JPEG size */ + /* ... */ + break; + default: + camsrc_error("Invalid output format."); + break; + } + + camsrc_info("==========================================="); + camsrc_info("| Request output width = %d", vformat.fmt.pix.width); + camsrc_info("| Request output height = %d", vformat.fmt.pix.height); + camsrc_info("| Request output field = %d", vformat.fmt.pix.field); + camsrc_info("| Request output pixel format = %d", vformat.fmt.pix.pixelformat); + camsrc_info("| Request output bytesperline = %d", vformat.fmt.pix.bytesperline); + camsrc_info("| Request output image size = %d", vformat.fmt.pix.sizeimage); + camsrc_info("==========================================="); + + __ta__( " VIDIOC_S_FMT", + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_S_FMT, &vformat)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_S_FMT failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + ); + + control.id = V4L2_CID_CACHEABLE; + if (p->format.pix_format == CAMERASRC_PIX_INTERLEAVED) { + control.value = 1; + } else { + control.value = 0; + } + camsrc_info("[VIDIOC_S_CTRL] V4L2_CID_CACHEABLE -> %d", control.value); + __ta__( " VIDIOC_S_CTRL: V4L2_CID_CACHEABLE", + err = _camerasrc_ioctl(p, VIDIOC_S_CTRL, &control); + ); + if (err != CAMERASRC_SUCCESS) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("V4L2_CID_CACHEABLE failed : %s", err_msg); + return err; + } + + control.id = V4L2_CID_EMBEDDEDDATA_ENABLE; + if (p->format.pix_format == CAMERASRC_PIX_INTERLEAVED) { + control.value = 1; + } else { + control.value = 0; + } + camsrc_info("[VIDIOC_S_CTRL] V4L2_CID_EMBEDDEDDATA_ENABLE -> %d", control.value); + __ta__( " VIDIOC_S_CTRL: V4L2_CID_EMBEDDEDDATA_ENABLE", + err = _camerasrc_ioctl(p, VIDIOC_S_CTRL, &control); + ); + if (err != CAMERASRC_SUCCESS) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("V4L2_CID_EMBEDDEDDATA_ENABLE failed : %s", err_msg); + return err; + } + + /* Prepare alter format frame */ + __ta__( " camerasrc_query_img_buf_size", + camerasrc_query_img_buf_size(p, &(p->alter_frame.length), NULL); + ); + p->alter_frame.start = (unsigned char*) malloc(p->alter_frame.length); + if (p->alter_frame.start == NULL) { + camsrc_error("alter_frame alloc failed."); + return CAMERASRC_ERR_ALLOCATION; + } + + /* M E M O R Y M A P P I N G */ + CLEAR(vreq_bufs); + switch(p->io_method) { + case CAMERASRC_IO_METHOD_MMAP: + camsrc_info("MMAP mode"); + vreq_bufs.count = CAMERASRC_PREVIEW_BUFFER_NUM; + vreq_bufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vreq_bufs.memory = V4L2_MEMORY_MMAP; + camsrc_info("MMAP mode (bufs.count:%d)", vreq_bufs.count); + __ta__( " VIDIOC_REQBUFS", + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_REQBUFS, &vreq_bufs)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_REQBUFS failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + ); + camsrc_assert(vreq_bufs.count >= 1); + + p->num_buffers = vreq_bufs.count; + p->buffer = calloc (vreq_bufs.count, sizeof (camerasrc_buffer_t)); + if (!p->buffer) { + camsrc_error("calloc() failed"); + return CAMERASRC_ERR_ALLOCATION; + } + + for (p->buffer_idx = 0; p->buffer_idx < vreq_bufs.count; ++(p->buffer_idx)) { + struct v4l2_buffer vbuf; + CLEAR(vbuf); + vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vbuf.memory = V4L2_MEMORY_MMAP; + vbuf.index = p->buffer_idx; + + __ta__( " VIDIOC_QUERYBUF", + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_QUERYBUF, &vbuf)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_QUERYBUF failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + ); + + __ta__( " mmap", + p->buffer[p->buffer_idx].length = vbuf.length; + p->buffer[p->buffer_idx].start = mmap(NULL /* start anywhere */, + vbuf.length, + PROT_READ | PROT_WRITE, + MAP_SHARED, + p->dev_fd, vbuf.m.offset); + ); + if (MAP_FAILED == p->buffer[p->buffer_idx].start) { + camsrc_error("mmap failed."); + return CAMERASRC_ERR_ALLOCATION; + } + + GST_INFO("buffer index %d, addr %x, length %d", + p->buffer_idx, p->buffer[p->buffer_idx].start, p->buffer[p->buffer_idx].length); + + switch (p->format.pix_format) { + case CAMERASRC_PIX_YUV422P: + case CAMERASRC_PIX_YUY2: + case CAMERASRC_PIX_UYVY: + if (p->buffer[p->buffer_idx].length < p->format.img_size.dim.width * p->format.img_size.dim.height * 2) { + camsrc_error("format[%d] device insufficient memory.", p->format.pix_format); + } + break; + case CAMERASRC_PIX_YUV420P: + case CAMERASRC_PIX_NV12: + if (p->buffer[p->buffer_idx].length < (p->format.img_size.dim.width * p->format.img_size.dim.height * 3 / 2)) { + camsrc_error("format[%d] device insufficient memory.", p->format.pix_format); + } + break; + case CAMERASRC_PIX_SN12: + case CAMERASRC_PIX_ST12: + if (p->buffer[p->buffer_idx].length < (p->format.img_size.dim.width * p->format.img_size.dim.height)) { + camsrc_error("SN12,ST12: device insufficient memory."); + } + break; + case CAMERASRC_PIX_INTERLEAVED: + if (p->buffer[p->buffer_idx].length < (p->format.img_size.dim.width * p->format.img_size.dim.height)) { + camsrc_error("INTERLEAVED: device insufficient memory."); + } + break; + default: + camsrc_error("Not supported format[%d]", p->format.pix_format); + break; + } + + camsrc_info("MMAP BUF: addr[%p] size[%d]", + p->buffer[p->buffer_idx].start, p->buffer[p->buffer_idx].length); + } + break; + case CAMERASRC_IO_METHOD_USRPTR: + camsrc_info("USRPTR mode"); + + vreq_bufs.count = p->present_buf->num_buffer; + vreq_bufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vreq_bufs.memory = V4L2_MEMORY_USERPTR; + __ta__( " VIDIOC_REQBUFS", + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_REQBUFS, &vreq_bufs)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_REQBUFS failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + ); + camsrc_assert(vreq_bufs.count >= 1); + + p->num_buffers = vreq_bufs.count; + p->buffer = calloc (vreq_bufs.count, sizeof (camerasrc_buffer_t)); + + if(!p->buffer) { + camsrc_error("calloc() failed"); + return CAMERASRC_ERR_ALLOCATION; + } + + if(!p->present_buf->present_buffer) { + camsrc_error("No Usrptr buffer presented!"); + return CAMERASRC_ERR_ALLOCATION; + } + + for (p->buffer_idx = 0; p->buffer_idx < vreq_bufs.count; ++(p->buffer_idx)) { + p->buffer[p->buffer_idx].length = p->present_buf->present_buffer[p->buffer_idx].length; + p->buffer[p->buffer_idx].start = p->present_buf->present_buffer[p->buffer_idx].start; + + if (!p->buffer[p->buffer_idx].start) { + camsrc_error("presented usrptr buffer is NULL"); + return CAMERASRC_ERR_ALLOCATION; + } + + camsrc_info("USERPTR BUF: addr[%p] size[%d]", + p->buffer[p->buffer_idx].start, p->buffer[p->buffer_idx].length); + } + break; + case CAMERASRC_IO_METHOD_READ: + default: + camsrc_error("Device not support that io-method"); +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + break; + } + + /* A C T U A L S T A R T S T R E A M */ + switch(p->io_method) { + case CAMERASRC_IO_METHOD_MMAP: + camsrc_info("MMAP mode"); + + p->queued_buffer_count = 0; + for (cnt = 0; cnt < p->num_buffers; cnt++) { + struct v4l2_buffer lvbuf; + CLEAR(lvbuf); + + lvbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + lvbuf.memory = V4L2_MEMORY_MMAP; + lvbuf.index = cnt; + __ta__( " VIDIOC_QBUF", + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_QBUF, &lvbuf)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_QBUF failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + ); + + LOCK(p); + p->buffer[lvbuf.index].queued_status = CAMERASRC_BUFFER_QUEUED; + p->queued_buffer_count++; + UNLOCK(p); + } + break; + case CAMERASRC_IO_METHOD_USRPTR: + camsrc_info("USRPTR mode"); + + for (cnt = 0; cnt < p->present_buf->num_buffer; cnt++) { + struct v4l2_buffer lvbuf; + CLEAR(lvbuf); + + lvbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + lvbuf.memory = V4L2_MEMORY_USERPTR; + lvbuf.index = cnt; + lvbuf.m.userptr = (unsigned long)p->buffer[cnt].start; + lvbuf.length = p->buffer[cnt].length; + __ta__( " VIDIOC_QBUF", + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_QBUF, &lvbuf)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_QBUF failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + ); + + camsrc_info("QBUF Address [%d] %p", lvbuf.index, (void*)lvbuf.m.userptr); + + memcpy(&(p->queued_buf_list[cnt]), &lvbuf, sizeof(struct v4l2_buffer)); + } + break; + case CAMERASRC_IO_METHOD_READ: + default: + camsrc_error("Device not support that io-method"); +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + break; + } + + /* calibrate rotation - kernel of c210 could not support V4L2_CID_PHYSICAL_ROTATION */ + if (p->cur_dev_id == CAMERASRC_DEV_ID_SECONDARY) { + p->format.rotation += 180; + p->format.rotation = p->format.rotation % 360; + camsrc_info("Calibrate rotate : secondary camera +180 degree"); + } + + /* Rotation set */ + __ta__( " _CAMERASRC_CMD_ROTATION", + CAMERASRC_SET_CMD(_CAMERASRC_CMD_ROTATION, &(p->format.rotation)); + ); +#if USE_SENSOR_MODE + /* Sensor mode Set */ + __ta__( " _CAMERASRC_CMD_SENSOR_MODE", + CAMERASRC_SET_CMD(_CAMERASRC_CMD_SENSOR_MODE, &(p->sensor_mode)); + ); +#endif + /* Sensor flip */ + __ta__( " _CAMERASRC_CMD_VFLIP", + CAMERASRC_SET_CMD(_CAMERASRC_CMD_VFLIP, &(p->vflip)); + ); + __ta__( " _CAMERASRC_CMD_HFLIP", + CAMERASRC_SET_CMD(_CAMERASRC_CMD_HFLIP, &(p->hflip)); + ); + + vtype = V4L2_BUF_TYPE_VIDEO_CAPTURE; + __ta__( " VIDIOC_STREAMON", + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_STREAMON, &vtype)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_STREAMON failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + ); + + /* For noti that it is first frame DQ */ + p->first_frame = 1; + + LOCK(p); + if (_CAMERASRC_NEED_MISC_FUNCTION(p->cur_dev_id, CAMERASRC_OP_PREVIEW, p->format.colorspace, CAMERASRC_MISC_SKIP_FRAME)) { + p->skip_frame_func = (camerasrc_skip_frame_func_t)_camerasrc_skip_frame; + } else { + p->skip_frame_func = NULL; + } + UNLOCK(p); + +#if defined(USE_SKIP_FRAME_AT_RAW_FRAME) + if(p->skip_frame_func != NULL) + p->skip_frame_func(p, 5000, 3); +#endif + + for (cnt = 0; cnt < p->num_buffers; cnt++) { + camsrc_info("MMAP/USRPTR BUF: addr[%p] size[%d]", p->buffer[cnt].start, p->buffer[cnt].length); + } + + CAMERASRC_SET_STATE(p, CAMERASRC_STATE_PREVIEW); + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_query_img_buf_size(camsrc_handle_t handle, unsigned int* main_img_size, unsigned int* thm_img_size) +{ + camerasrc_handle_t* p = NULL; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_STATE(p) != CAMERASRC_STATE_STILL && + CAMERASRC_STATE(p) != CAMERASRC_STATE_PREVIEW && + CAMERASRC_STATE(p) != CAMERASRC_STATE_VIDEO) { + camsrc_warning("Invalid state transition"); + } + + camsrc_info("Start to set format"); + + if (p->format.colorspace == CAMERASRC_COL_RAW && + (p->format.pix_format == CAMERASRC_PIX_YUV422P || + p->format.pix_format == CAMERASRC_PIX_YUY2 || + p->format.pix_format == CAMERASRC_PIX_UYVY || + p->format.pix_format == CAMERASRC_PIX_INTERLEAVED)) { + *main_img_size = p->format.img_size.dim.width * p->format.img_size.dim.height * 2; + if (thm_img_size != NULL) { + *thm_img_size = 0; + } + camsrc_info("422 RAW!! WIDTH = %d, HEIGHT=%d, SIZE = %d", + p->format.img_size.dim.width, p->format.img_size.dim.height, *main_img_size); + } else if (p->format.colorspace == CAMERASRC_COL_RAW && + (p->format.pix_format == CAMERASRC_PIX_YUV420P || + p->format.pix_format == CAMERASRC_PIX_SN12 || + p->format.pix_format == CAMERASRC_PIX_ST12 || + p->format.pix_format == CAMERASRC_PIX_NV12)) { + /*Kessler preview path*/ + *main_img_size = p->format.img_size.dim.width * p->format.img_size.dim.height * 3 / 2; + if (thm_img_size != NULL) { + *thm_img_size = 0; + } + camsrc_info("420 RAW!! WIDTH = %d, HEIGHT=%d, SIZE = %d", + p->format.img_size.dim.width, p->format.img_size.dim.height, *main_img_size); + } else if (p->format.colorspace == CAMERASRC_COL_JPEG) { + if (p->format.pix_format == CAMERASRC_PIX_RGGB10) { + camsrc_info("JPG + YUV Mode enabled."); + *main_img_size = CAMERASRC_JPG_STILL_H_SYNC * CAMERASRC_JPG_STILL_V_SYNC; + if (thm_img_size != NULL) { + *thm_img_size = 320 * 240 * 2; + } + } else if (p->format.pix_format == CAMERASRC_PIX_RGGB8) { + /*Kessler capture path*/ + camsrc_info("JPG + JPG Mode enabled."); + *main_img_size = CAMERASRC_JPG_STILL_H_SYNC * CAMERASRC_JPG_STILL_V_SYNC; + if (thm_img_size != NULL) { + *thm_img_size = CAMERASRC_JPG_STILL_H_SYNC * CAMERASRC_JPG_STILL_V_SYNC - CAMERASRC_JPG_STILL_THUMBNAIL_OFFSET; + } + } else { + camsrc_error("Unknown image format..."); +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + } + + camsrc_info("JPEG!! WIDTH = %d, HEIGHT=%d, SIZE = %d", + p->format.img_size.dim.width, p->format.img_size.dim.height, *main_img_size); + } else { + camsrc_error("Unknown format set. can't go any more"); + camsrc_assert(0); + } + + camsrc_info("leave.."); + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_stop_stream(camsrc_handle_t handle) +{ + camerasrc_handle_t *p = NULL; + enum v4l2_buf_type type; + int cnt = 0; + int try_count = 0; + camerasrc_auto_focus_status_t af_status = 0; + struct v4l2_requestbuffers vreq_bufs; + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + + camsrc_info("enter"); + + if(handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_STATE(p) == CAMERASRC_STATE_READY) { + return CAMERASRC_SUCCESS; + } + + if (CAMERASRC_STATE(p) != CAMERASRC_STATE_STILL && + CAMERASRC_STATE(p) != CAMERASRC_STATE_PREVIEW && + CAMERASRC_STATE(p) != CAMERASRC_STATE_VIDEO && + CAMERASRC_STATE(p) != CAMERASRC_STATE_AF_IN_PROGRESS) { + camsrc_warning("Stop stream called [STREAM-NOT-STARTED STATE]"); + } + + camsrc_info("Change to READY state first for preventing to check Q/DQ after stop"); + CAMERASRC_SET_STATE(p, CAMERASRC_STATE_READY); + + LOCK(p); + p->timeperframe.denominator = 0; + p->timeperframe.numerator = 0; + p->first_frame = 1; + UNLOCK(p); + +#ifdef STOP_AF_BEFORE_STREAMOFF + _camerasrc_stop_autofocusing(p); + + /* Wait for AF stop done */ + try_count = 0; + __ta__( " camerasrc_stop_stream:Wait for AF release", + while (try_count++ < CAMERASRC_AF_TOTALTIME/CAMERASRC_AF_STOP_INTERVAL) { + usleep( CAMERASRC_AF_STOP_INTERVAL ); + camerasrc_get_autofocusing_status(p, &af_status); + if (af_status == CAMERASRC_AUTO_FOCUS_STATUS_RELEASED) { + camsrc_info("AF Stop done"); + break; + } + } + ); +#endif /* STOP_AF_BEFORE_STREAMOFF */ + + /* S T O P S T R E A M */ + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + __ta__( " camerasrc_stop_stream:VIDIOC_STREAMOFF", + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_STREAMOFF, &type)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_STREAMOFF failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + ); + + /* M E M O R Y U N M A P P I N G & F R E E */ + switch(p->io_method) { + case CAMERASRC_IO_METHOD_MMAP: + camsrc_info("Init io method to MMAP mode"); + for (cnt = 0; cnt < p->num_buffers; ++cnt) { + if (-1 == munmap (p->buffer[cnt].start,p->buffer[cnt].length)) { + camsrc_error("MUNMAP failed."); + return CAMERASRC_ERR_INTERNAL; + } + + p->buffer[cnt].start = NULL; + p->buffer[cnt].length = 0; + } + break; + case CAMERASRC_IO_METHOD_USRPTR: + camsrc_info("User ptr mode don't need munmap"); + break; + case CAMERASRC_IO_METHOD_READ: + default: + camsrc_error("Device not support that io-method"); +#if USE_NOT_SUPPORT_ERR + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; +#else + return CAMERASRC_SUCCESS; +#endif + } + + /* release buffer */ + CLEAR(vreq_bufs); + vreq_bufs.count = 0; + vreq_bufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vreq_bufs.memory = V4L2_MEMORY_MMAP; + if (CAMERASRC_SUCCESS != _camerasrc_ioctl(p, VIDIOC_REQBUFS, &vreq_bufs)) { + strerror_r(p->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_REQBUFS failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + + /* RETURN BUFFER MANAGE MODE TO DEFAULT */ + p->io_method = CAMERASRC_IO_METHOD_MMAP; + p->present_buf = NULL; + + if (p->buffer != NULL) { + free(p->buffer); + } + + if (p->alter_frame.start != NULL) { + free(p->alter_frame.start); + } + + p->buffer = NULL; + p->alter_frame.start = NULL; + + p->buffer_idx = 0; + p->num_buffers = 0; + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_wait_frame_available(camsrc_handle_t handle, long int timeout) +{ + camerasrc_handle_t *p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_STATE(p) != CAMERASRC_STATE_STILL && + CAMERASRC_STATE(p) != CAMERASRC_STATE_PREVIEW && + CAMERASRC_STATE(p) != CAMERASRC_STATE_VIDEO && + CAMERASRC_STATE(p) != CAMERASRC_STATE_AF_IN_PROGRESS) { + camsrc_warning("Invalid state transition" ); + } + + if ( p->queued_buffer_count > 0 ) { + /*camsrc_info( CAMERASRC, "Current queue count : %d", p->queued_buffer_count );*/ + err = _camerasrc_wait_frame_available(p, timeout); + } else { + camsrc_warning("queued_buffer_count[%d] is unavailable. sleep 100 ms and try again...", p->queued_buffer_count ); + usleep( 100000 ); + err = CAMERASRC_ERR_INVALID_STATE; + } + + return err; +} + + +int camerasrc_check_esd_shock(camsrc_handle_t *handle, int *check_val) +{ + camerasrc_handle_t* p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if(handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + printf("start _camerasrc_check_emp_shock"); + *check_val = 0; + err = _camerasrc_check_emp_shock(p, check_val); + printf("check_val = %d", *check_val); + printf("end _camerasrc_check_emp_shock"); + + return err; +} + + +int camerasrc_queue_buffer(camsrc_handle_t handle, int buf_index, camerasrc_buffer_t *buffer) +{ + camerasrc_handle_t *p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_STATE(p) != CAMERASRC_STATE_STILL && + CAMERASRC_STATE(p) != CAMERASRC_STATE_PREVIEW && + CAMERASRC_STATE(p) != CAMERASRC_STATE_VIDEO && + CAMERASRC_STATE(p) != CAMERASRC_STATE_AF_IN_PROGRESS ) { + camsrc_warning("Invalid state transition"); + } + + err = _camerasrc_queue_buffer(p, buf_index, buffer); + + return err; +} + + +int camerasrc_dequeue_buffer(camsrc_handle_t handle, int *buf_index, camerasrc_buffer_t *buffer, camerasrc_buffer_t *thm_buffer) +{ + camerasrc_handle_t *p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_STATE(p) != CAMERASRC_STATE_STILL && + CAMERASRC_STATE(p) != CAMERASRC_STATE_PREVIEW && + CAMERASRC_STATE(p) != CAMERASRC_STATE_VIDEO && + CAMERASRC_STATE(p) != CAMERASRC_STATE_AF_IN_PROGRESS) { + camsrc_warning("Invalid state transition"); + } + + err = _camerasrc_dequeue_buffer(p, buf_index, buffer, thm_buffer); + + return err; +} + + +int camerasrc_read_frame(camsrc_handle_t handle, camerasrc_buffer_t *main_img_buffer, camerasrc_buffer_t *thm_img_buffer, int *buffer_index) +{ + camerasrc_handle_t* p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("ENTER"); + + if (!handle || !main_img_buffer || !thm_img_buffer || !buffer_index) { + camsrc_error("handle(%p)main(%p)thm(%p)index(%p) is null", + handle, main_img_buffer, thm_img_buffer, buffer_index); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_STATE(p) != CAMERASRC_STATE_STILL && + CAMERASRC_STATE(p) != CAMERASRC_STATE_PREVIEW && + CAMERASRC_STATE(p) != CAMERASRC_STATE_VIDEO && + CAMERASRC_STATE(p) != CAMERASRC_STATE_AF_IN_PROGRESS) { + camsrc_warning("Invalid state transition"); + } + +#ifndef DUMMY_OUTPUT + __ta__( " Stillshot select()", + err = _camerasrc_wait_frame_available(p, CAMERASRC_TIMEOUT_CRITICAL_VALUE); + ); + if (err != CAMERASRC_SUCCESS) { + camsrc_error("Frame waiting error, [%x]", err); + return err; + } + + /* Buffer DQ */ + __ta__( " Stillshot VIDIOC_DQBUF", + err = _camerasrc_dequeue_buffer(p, buffer_index, main_img_buffer, thm_img_buffer); + ); + if (err != CAMERASRC_SUCCESS) { + camsrc_error("Dequeue frame error, [%x]", err); + return err; + } +#endif + + camsrc_info("DEQUEUED Index : %d", *buffer_index); + +#if defined(USE_CAMERASRC_FRAME_DUMP) + printf("******************in buf len = %d", inner_main_buffer.length); + write_buffer_into_path(&inner_main_buffer, CAMERASRC_FRAME_DUMP_PATH, "main.jpg"); +#endif + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_set_focused_callback(camsrc_handle_t handle, camerasrc_callback_t cb, void *usr_data) +{ + camerasrc_handle_t *p = NULL; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_STATE(p) != CAMERASRC_STATE_REALIZED && + CAMERASRC_STATE(p) != CAMERASRC_STATE_READY) { + camsrc_warning("Invalid state transition"); + } + + LOCK(p); + p->af_cb = cb; + if (usr_data != NULL) { + p->af_usr_data = usr_data; + } + UNLOCK(p); + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_set_autofocusing_area(camsrc_handle_t handle, camerasrc_rect_t *rect) +{ + camerasrc_handle_t *p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_PHASE(p) != CAMERASRC_PHASE_RUNNING) { + camsrc_warning("Invalid state transition"); + } + + err = _camerasrc_set_autofocusing_area(p, rect); + + if (err != CAMERASRC_SUCCESS) { + camsrc_error("Set autofocusing area error"); + return err; + } + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_get_autofocusing_area(camsrc_handle_t handle, camerasrc_rect_t *rect) +{ + camerasrc_handle_t *p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_PHASE(p) != CAMERASRC_PHASE_RUNNING) { + camsrc_warning("Invalid state transition"); + } + + err = _camerasrc_get_autofocusing_area(p, rect); + + if (err != CAMERASRC_SUCCESS) { + camsrc_error("Get autofocusing area error"); + return err; + } + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_start_autofocusing(camsrc_handle_t handle) +{ + camerasrc_handle_t *p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (!(CAMERASRC_STATE(p) == CAMERASRC_STATE_PREVIEW || + CAMERASRC_STATE(p) == CAMERASRC_STATE_VIDEO || + CAMERASRC_STATE(p) == CAMERASRC_STATE_AF_IN_PROGRESS)) { + camsrc_error("Invalid state [%d]", CAMERASRC_STATE(p)); + return CAMERASRC_ERR_INVALID_STATE; + } + + /* START AF */ + err = _camerasrc_start_autofocusing(p); + + if (err != CAMERASRC_SUCCESS) { + camsrc_error("Create autofocusing thread error"); + return err; + } + + camsrc_info("Set state to [AF-IN-PROGRESS]!!"); + CAMERASRC_SET_STATE(p, CAMERASRC_STATE_AF_IN_PROGRESS); + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_stop_autofocusing(camsrc_handle_t handle) +{ + camerasrc_handle_t *p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (!(CAMERASRC_STATE(p) == CAMERASRC_STATE_PREVIEW || + CAMERASRC_STATE(p) == CAMERASRC_STATE_VIDEO || + CAMERASRC_STATE(p) == CAMERASRC_STATE_AF_IN_PROGRESS)) { + camsrc_error("Invalid state [%d]", CAMERASRC_STATE(p)); + return CAMERASRC_ERR_INVALID_STATE; + } + + /* STOP AF */ + camsrc_info("AF_STOP called!!"); + err = _camerasrc_stop_autofocusing(p); + if (err != CAMERASRC_SUCCESS) { + camsrc_error("Stop autofocusing error"); + return err; + } + + if (CAMERASRC_STATE(p) > CAMERASRC_STATE_READY) { + camsrc_info("Set state to [PREVIEW] again!!"); + CAMERASRC_SET_STATE(p, CAMERASRC_STATE_PREVIEW); + } else { + camsrc_info("Do not change state"); + } + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_release_autofocusing(camsrc_handle_t handle) +{ + camerasrc_handle_t *p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_STATE(p) != CAMERASRC_STATE_PREVIEW && + CAMERASRC_STATE(p) != CAMERASRC_STATE_VIDEO && + CAMERASRC_STATE(p) != CAMERASRC_STATE_AF_IN_PROGRESS) { + return CAMERASRC_SUCCESS; + } + + /* STOP AF */ + camsrc_info("AF_RELEASE called!!"); + err = _camerasrc_release_autofocusing(p); + if (err != CAMERASRC_SUCCESS) { + camsrc_error("Stop autofocusing error"); + return err; + } + + camsrc_info("Set state to [PREVIEW] again!!"); + CAMERASRC_SET_STATE(p, CAMERASRC_STATE_PREVIEW); + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_init_autofocusing_mode(camsrc_handle_t handle, camerasrc_af_mode_t af_mode, camerasrc_af_scan_range_t af_range) +{ + camerasrc_handle_t *p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_STATE(p) != CAMERASRC_STATE_PREVIEW) { + camsrc_warning("Invalid state transition"); + } + + p->cur_af_mode = af_mode; + p->cur_af_range = af_range; + + err = _camerasrc_init_autofocusing_mode(p); + if (err != CAMERASRC_SUCCESS) { + camsrc_error("Init autofocusing mode error"); + return err; + } + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_get_autofocusing_mode(camsrc_handle_t handle, camerasrc_af_mode_t *af_mode, camerasrc_af_scan_range_t *af_range) +{ + camerasrc_handle_t *p = NULL; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (af_mode) { + *af_mode = p->cur_af_mode; + } + + if (af_range) { + *af_range = p->cur_af_range; + } + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_get_autofocusing_status(camsrc_handle_t handle, camerasrc_auto_focus_status_t *af_status) +{ + camerasrc_handle_t *p = NULL; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + if (af_status == NULL) { + camsrc_error("*af_status is NULL"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + *af_status = p->af_status; + + camsrc_info("[camerasrc_get_autofocusing_status] %d", *af_status); + + return CAMERASRC_SUCCESS; +} + +/**** M I S C E L L A N E O U S O P E R A T I O N ****/ + +/**** I N P U T ( C A M D E V I C E ) O P E R A T I O N ****/ + +int camerasrc_get_input(camsrc_handle_t handle, camerasrc_dev_id_t *id) +{ + camerasrc_handle_t *p = NULL; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_PHASE(p) != CAMERASRC_PHASE_RUNNING) { + camsrc_warning("Invalid phase"); + } + + *id = p->cur_dev_id; + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_set_input(camsrc_handle_t handle, camerasrc_dev_id_t camera_id) +{ + camerasrc_handle_t *p = NULL; + struct v4l2_control control; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_STATE(p) != CAMERASRC_STATE_READY) { + camsrc_error("Invalid state"); + return CAMERASRC_ERR_INVALID_STATE; + } + + if (p->cur_dev_id == camera_id) { + return CAMERASRC_SUCCESS; + } + + camsrc_info("Set Index to %d", _CAMERASRC_GET_DEV_INDEX(camera_id)); + + err = _camerasrc_ioctl(p, VIDIOC_S_INPUT, &(_CAMERASRC_GET_DEV_INDEX(camera_id))); + if (CAMERASRC_SUCCESS != err) { + camsrc_error("[***DEBUG] ERROR SET INPUT to %dth DEVICE", _CAMERASRC_GET_DEV_INDEX(camera_id)); + return CAMERASRC_ERR_IO_CONTROL; + } else { + camsrc_info("[***DEBUG] SET INPUT OK!!! to %dth DEVICE", _CAMERASRC_GET_DEV_INDEX(camera_id)); + camsrc_info("return value of ioctl VIDIOC_S_INPUT = %d", err); + } + + p->cur_dev_id = camera_id; + + /* check physical rotation of camera lens */ + #ifndef V4L2_CID_PHYSICAL_ROTATION + #define V4L2_CID_PHYSICAL_ROTATION (V4L2_CID_PRIVATE_BASE + 300) + #endif /* V4L2_CID_PHYSICAL_ROTATION */ + + control.id = V4L2_CID_PHYSICAL_ROTATION; + _camerasrc_ioctl(handle, VIDIOC_G_CTRL, &control); + if(CAMERASRC_SUCCESS != _camerasrc_ioctl(handle, VIDIOC_G_CTRL, &control)) { + camsrc_warning("failed to get rotation of lens"); + p->lens_rotation = -1; + } else { + p->lens_rotation = control.value; + camsrc_info("lens rotation %d", p->lens_rotation); + } + + return err; +} + +/**** O U T P U T C O N T R O L O P E R A T I O N ****/ + +int camerasrc_set_timeperframe(camsrc_handle_t handle, camerasrc_frac_t *frac) +{ + camerasrc_handle_t *p = NULL; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_PHASE(p) != CAMERASRC_PHASE_RUNNING) { + camsrc_warning("Invalid phase, but can go"); + } + + camsrc_info("Numerator = %d, Denominator = %d", frac->numerator, frac->denominator); + + LOCK(p); + p->timeperframe.numerator = frac->numerator; + p->timeperframe.denominator = frac->denominator; + UNLOCK(p); + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_set_format(camsrc_handle_t handle, camerasrc_format_t *fmt) +{ + camerasrc_handle_t *p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_STATE(p) != CAMERASRC_STATE_READY) { + camsrc_error("Invalid state"); + } + + err = _camerasrc_dump_format(handle); + if (err != CAMERASRC_SUCCESS) { + camsrc_error("Format dump error"); + return err; + } + + CLEAR(p->format); + + p->format.colorspace = fmt->colorspace; + p->format.bytesperline = fmt->bytesperline; + p->format.img_size.dim.width = fmt->img_size.dim.width; + p->format.img_size.dim.height = fmt->img_size.dim.height; + p->format.thumb_size.dim.width = fmt->thumb_size.dim.width; + p->format.thumb_size.dim.height= fmt->thumb_size.dim.height; + p->format.is_highquality_mode = fmt->is_highquality_mode; + p->format.pix_format = fmt->pix_format; + p->format.quality = fmt->quality; + p->format.sizeimage = fmt->sizeimage; + p->format.rotation = fmt->rotation; + p->is_preset = 0; + + switch (fmt->pix_format) { + case CAMERASRC_PIX_YUV422P: + p->format.num_planes = 3; + break; + case CAMERASRC_PIX_YUV420P: + p->format.num_planes = 3; + break; + case CAMERASRC_PIX_YUV420: + p->format.num_planes = 2; + break; + case CAMERASRC_PIX_SN12: + p->format.num_planes = 2; + break; + case CAMERASRC_PIX_ST12: + p->format.num_planes = 2; + break; + case CAMERASRC_PIX_NV12: + p->format.num_planes = 2; + break; + case CAMERASRC_PIX_YUY2: + p->format.num_planes = 1; + break; + case CAMERASRC_PIX_UYVY: + p->format.num_planes = 1; + break; + case CAMERASRC_PIX_RGGB8: + p->format.num_planes = 1; + break; + case CAMERASRC_PIX_RGGB10: + p->format.num_planes = 1; + break; + case CAMERASRC_PIX_RGB565: + p->format.num_planes = 1; + break; + default: + p->format.num_planes = 3; + camsrc_error("Invalid output format."); + break; + } + + err = _camerasrc_dump_format(handle); + if (err != CAMERASRC_SUCCESS) { + camsrc_error("Format dump error"); + return err; + } + + camsrc_info("leave"); + + return err; +} + + +int camerasrc_get_format(camsrc_handle_t handle, camerasrc_format_t *fmt) +{ + camerasrc_handle_t *p = NULL; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_PHASE(p) != CAMERASRC_PHASE_RUNNING) { + camsrc_warning("Invalid phase"); + } + + memcpy(fmt, &(p->format), sizeof(camerasrc_format_t)); + + camsrc_info("leave"); + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_try_format(camsrc_handle_t handle, camerasrc_format_t *fmt) +{ + camerasrc_handle_t *p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_STATE(p) != CAMERASRC_STATE_READY) { + camsrc_error("Invalid state"); + return CAMERASRC_ERR_INVALID_STATE; + } + + /* size limitaion check */ + if (fmt->img_size.dim.width < 0 || fmt->img_size.dim.width > CAMERASRC_MAX_WIDTH) { + camsrc_info("Invalid width"); + return CAMERASRC_ERR_INVALID_PARAMETER; + } + if (fmt->img_size.dim.height < 0 || fmt->img_size.dim.height > CAMERASRC_MAX_HEIGHT) { + camsrc_info("Invalid height"); + return CAMERASRC_ERR_INVALID_PARAMETER; + } + + /* check pixel number & colorspace are in bound */ + if (fmt->pix_format < 0 || fmt->pix_format >= CAMERASRC_PIX_NUM) { + camsrc_info("Invalid pixel format"); + return CAMERASRC_ERR_INVALID_PARAMETER; + } + if (fmt->colorspace < 0 || fmt->colorspace >= CAMERASRC_COL_NUM) { + camsrc_info("Invalid colorspace"); + return CAMERASRC_ERR_INVALID_PARAMETER; + } + + /* colorspace & pixel format combinability check */ + if (_CAMERASRC_MATCH_COL_TO_PIX(p->cur_dev_id, fmt->colorspace, fmt->pix_format, CAMERASRC_QUALITY_HIGH) || + _CAMERASRC_MATCH_COL_TO_PIX(p->cur_dev_id, fmt->colorspace, fmt->pix_format, CAMERASRC_QUALITY_NORMAL)) { + err = CAMERASRC_SUCCESS; + } else { + camsrc_info("UNAVAILABLE SETTING"); + err = CAMERASRC_ERR_INVALID_PARAMETER; + } + + camsrc_info("leave"); + + return err; +} + + +int camerasrc_get_frame_data(camsrc_handle_t handle, camerasrc_frame_data_t *data) +{ + camerasrc_handle_t *p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_PHASE(p) != CAMERASRC_PHASE_RUNNING) { + camsrc_warning("Invalid state transition"); + } + + err = _camerasrc_get_frame_data(p, data); + if (err != CAMERASRC_SUCCESS) { + camsrc_error("toggle auto exposure failed"); + return err; + } + + return err; +} + + +static int _camerasrc_dump_format(camsrc_handle_t handle) +{ + camerasrc_handle_t *p = NULL; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + camsrc_info("---------FORMAT SETTING DUMP--------"); + camsrc_info("- Image size : %d x %d", p->format.img_size.dim.width, p->format.img_size.dim.height); + camsrc_info("- Thumbnail size : %d x %d", p->format.thumb_size.dim.width, p->format.thumb_size.dim.height); + camsrc_info("- Pixel format : %d", p->format.pix_format); + camsrc_info("- Bytes per line : %d", p->format.bytesperline); + camsrc_info("- Image size in bytes : %d", p->format.sizeimage); + camsrc_info("- Colorspace : %d", p->format.colorspace); + camsrc_info("- Rotation : %d", p->format.rotation); + camsrc_info("------------------------------------"); + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_get_exif_info(camsrc_handle_t handle, camerasrc_exif_t *exif_struct) +{ + camerasrc_handle_t* p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + if (CAMERASRC_PHASE(p) != CAMERASRC_PHASE_RUNNING) { + camsrc_warning("Invalid state transition"); + } + + err = _camerasrc_get_exif_info(p, (camerasrc_buffer_t*)exif_struct); + if (err != CAMERASRC_SUCCESS) { + camsrc_error("Get exif information string failed"); + } + + return err; +} + + +int camerasrc_device_is_open(camsrc_handle_t handle) +{ + camerasrc_handle_t *p = handle; + + if (p) { + if (p->dev_fd > 0) { + return TRUE; + } + } + + return FALSE; +} + + +int camerasrc_set_videofd(camsrc_handle_t handle, int videofd) +{ + camerasrc_handle_t *p = handle; + + if (p) { + p->dev_fd = videofd; + return CAMERASRC_SUCCESS; + } else { + return CAMERASRC_ERR_INVALID_HANDLE; + } +} + + +int camerasrc_set_af_hold_after_capture(camsrc_handle_t handle, int hold_af) +{ + camerasrc_handle_t *p = NULL; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + p->hold_af_after_capturing = hold_af; + + camsrc_info("leave"); + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_set_sensor_mode(camsrc_handle_t handle, int mode) +{ + camerasrc_handle_t *p = NULL; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + p->sensor_mode = mode; + + camsrc_info("leave"); + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_set_vflip(camsrc_handle_t handle, int vflip) +{ + camerasrc_handle_t *p = NULL; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + p->vflip = vflip; + + if (CAMERASRC_STATE(p) > CAMERASRC_STATE_READY) { + CAMERASRC_SET_CMD(_CAMERASRC_CMD_VFLIP, &(p->vflip)); + } + + camsrc_info("leave"); + + return CAMERASRC_SUCCESS; +} + + +int camerasrc_set_hflip(camsrc_handle_t handle, int hflip) +{ + camerasrc_handle_t *p = NULL; + + camsrc_info("enter"); + + if (handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + p->hflip = hflip; + if (CAMERASRC_STATE(p) > CAMERASRC_STATE_READY) { + CAMERASRC_SET_CMD(_CAMERASRC_CMD_HFLIP, &(p->hflip)); + } + + camsrc_info("leave"); + + return CAMERASRC_SUCCESS; +} + + +/* For Query functionalities */ +int camerasrc_read_basic_dev_info(camerasrc_dev_id_t dev_id, camerasrc_caps_info_t* caps_info) +{ + int err = CAMERASRC_ERR_UNKNOWN; + int nread = 0; + char* store_path = NULL; + FILE *fp = NULL; + + camsrc_info("enter"); + + if(dev_id == CAMERASRC_DEV_ID_PRIMARY) + store_path = CAMERASRC_PRIMARY_BASIC_INFO_PATH; + else if (dev_id == CAMERASRC_DEV_ID_SECONDARY) + store_path = CAMERASRC_SECONDARY_BASIC_INFO_PATH; + else + { + camsrc_error("Unsupported device ID"); + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + } + + fp = fopen(store_path, "rb"); + if(fp) + { + fseek(fp, 0, SEEK_SET); + nread = fread(caps_info, 1, sizeof(camerasrc_caps_info_t), fp); + camsrc_info("Need to be read : %d / Actual read : %d", sizeof(camerasrc_caps_info_t), nread); + fclose(fp); + } + else + return CAMERASRC_ERR_ALLOCATION; + + err = CAMERASRC_SUCCESS; + camsrc_info("leave"); + return err; +} + + +int camerasrc_read_misc_dev_info(camerasrc_dev_id_t dev_id, camerasrc_ctrl_list_info_t* ctrl_info) +{ + int err = CAMERASRC_ERR_UNKNOWN; + camsrc_info("enter"); + + int nread = 0; + FILE *fp = NULL; + char* store_path = NULL; + + if(dev_id == CAMERASRC_DEV_ID_PRIMARY) + store_path = CAMERASRC_PRIMARY_MISC_INFO_PATH; + else if (dev_id == CAMERASRC_DEV_ID_SECONDARY) + store_path = CAMERASRC_SECONDARY_MISC_INFO_PATH; + else + { + camsrc_error("Unsupported device ID"); + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + } + + fp = fopen(store_path, "rb"); + if(fp) + { + fseek(fp, 0, SEEK_SET); + nread = fread(ctrl_info, 1, sizeof(camerasrc_ctrl_list_info_t), fp); + camsrc_info("Need to be read : %d / Actual read : %d", sizeof(camerasrc_ctrl_list_info_t), nread); + fclose(fp); + } + else + return CAMERASRC_ERR_ALLOCATION; + + err = CAMERASRC_SUCCESS; + camsrc_info("leave"); + return err; +} + + +int camerasrc_read_extra_dev_info(camerasrc_dev_id_t dev_id, camerasrc_extra_info_t* extra_info) +{ + int err = CAMERASRC_ERR_UNKNOWN; + camsrc_info("enter"); + + int nread = 0; + FILE *fp = NULL; + char* store_path = NULL; + + if(dev_id == CAMERASRC_DEV_ID_PRIMARY) + store_path = CAMERASRC_PRIMARY_EXTRA_INFO_PATH; + else if (dev_id == CAMERASRC_DEV_ID_SECONDARY) + store_path = CAMERASRC_SECONDARY_EXTRA_INFO_PATH; + else + { + camsrc_error("Unsupported device ID"); + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + } + + fp = fopen(store_path, "rb"); + if(fp) + { + fseek(fp, 0, SEEK_SET); + nread = fread(extra_info, 1, sizeof(camerasrc_extra_info_t), fp); + camsrc_info("Need to be read : %d / Actual read : %d", sizeof(camerasrc_extra_info_t), nread); + fclose(fp); + } + else + return CAMERASRC_ERR_ALLOCATION; + + err = CAMERASRC_SUCCESS; + camsrc_info("leave"); + return err; +} + + +int camerasrc_write_basic_dev_info(camsrc_handle_t handle, camerasrc_caps_info_t* caps_info) +{ + camerasrc_handle_t* p = NULL; + char* store_path = NULL; + FILE *fp = NULL; + + camsrc_info("enter"); + + if(handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + int nwrite = 0; + + if(p->cur_dev_id == CAMERASRC_DEV_ID_PRIMARY) + { + camsrc_info("Primary(Mega) camera capabilities info will be written.."); + store_path = CAMERASRC_PRIMARY_BASIC_INFO_PATH; + } + else if (p->cur_dev_id == CAMERASRC_DEV_ID_SECONDARY) + { + camsrc_info("Secondary(VGA) camera capabilities info will be written.."); + store_path = CAMERASRC_SECONDARY_BASIC_INFO_PATH; + } + else + { + camsrc_error("Unsupported device ID"); + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + } + camsrc_info("PATH = %s", store_path); + + fp = fopen(store_path, "wb"); + if(fp) + { + fseek(fp, 0, SEEK_SET); + nwrite = fwrite(caps_info, 1, sizeof(camerasrc_caps_info_t), fp); + camsrc_info("Need to be written : %d / Actual written : %d", sizeof(camerasrc_caps_info_t), nwrite); + fclose(fp); + } + else + return CAMERASRC_ERR_ALLOCATION; + + camsrc_info("leave"); + return CAMERASRC_SUCCESS; +} + + +int camerasrc_write_misc_dev_info(camsrc_handle_t handle, camerasrc_ctrl_list_info_t* ctrl_info) +{ + camerasrc_handle_t* p = NULL; + + camsrc_info("enter"); + + if(handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + int nwrite = 0; + FILE *fp = NULL; + + char* store_path = NULL; + + if(p->cur_dev_id == CAMERASRC_DEV_ID_PRIMARY) + { + camsrc_info("Primary(Mega) camera controls info will be written.."); + store_path = CAMERASRC_PRIMARY_MISC_INFO_PATH; + } + else if (p->cur_dev_id == CAMERASRC_DEV_ID_SECONDARY) + { + camsrc_info("Secondary(VGA) camera controls info will be written.."); + store_path = CAMERASRC_SECONDARY_MISC_INFO_PATH; + } + else + { + camsrc_error("Unsupported device ID"); + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + } + + fp = fopen(store_path, "wb"); + if(fp) + { + fseek(fp, 0, SEEK_SET); + nwrite = fwrite(ctrl_info, 1, sizeof(camerasrc_ctrl_list_info_t), fp); + camsrc_info("Need to be written : %d / Actual written : %d", sizeof(camerasrc_ctrl_list_info_t), nwrite); + fclose(fp); + } + else + return CAMERASRC_ERR_ALLOCATION; + + camsrc_info("leave"); + return CAMERASRC_SUCCESS; +} + + +int camerasrc_write_extra_dev_info(camsrc_handle_t handle, camerasrc_extra_info_t* extra_info) +{ + camerasrc_handle_t* p = NULL; + + camsrc_info("enter"); + + if(handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + int nwrite = 0; + FILE *fp = NULL; + + char* store_path = NULL; + + if(p->cur_dev_id == CAMERASRC_DEV_ID_PRIMARY) + { + camsrc_info("Primary(Mega) extra controls info will be written.."); + store_path = CAMERASRC_PRIMARY_EXTRA_INFO_PATH; + } + else if (p->cur_dev_id == CAMERASRC_DEV_ID_SECONDARY) + { + camsrc_info("Secondary(VGA) extra controls info will be written.."); + store_path = CAMERASRC_SECONDARY_EXTRA_INFO_PATH; + } + else + { + camsrc_error("Unsupported device ID"); + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + } + + fp = fopen(store_path, "wb"); + if(fp) + { + fseek(fp, 0, SEEK_SET); + nwrite = fwrite(extra_info, 1, sizeof(camerasrc_extra_info_t), fp); + camsrc_info("Need to be written : %d / Actual written : %d", sizeof(camerasrc_extra_info_t), nwrite); + fclose(fp); + } + else + return CAMERASRC_ERR_ALLOCATION; + + camsrc_info("leave"); + return CAMERASRC_SUCCESS; +} + +void _camerasrc_add_total_resolution_info( camerasrc_caps_info_t* caps_info, int fcc_use, int width, int height ) +{ + int i = 0; + + if( 1 || fcc_use == CAMERASRC_FCC_USE_REC_PREVIEW + || fcc_use == CAMERASRC_FCC_USE_CAP_PREVIEW ) + { + for( i = 0 ; i < caps_info->num_preview_resolution ; i++ ) + { + if( caps_info->preview_resolution_width[i] == width + && caps_info->preview_resolution_height[i] == height ) + { + camsrc_info("preview resolution[%dx%d] is already existed.", width, height); + return; + } + } + + caps_info->preview_resolution_width[i] = width; + caps_info->preview_resolution_height[i] = height; + caps_info->num_preview_resolution++; + + camsrc_info("preview resolution[%dx%d] is added.", width, height); + } + else if( fcc_use == CAMERASRC_FCC_USE_NORMAL_CAPTURE + || fcc_use == CAMERASRC_FCC_USE_CONT_CAPTURE ) + { + for( i = 0 ; i < caps_info->num_capture_resolution ; i++ ) + { + if( caps_info->capture_resolution_width[i] == width + && caps_info->capture_resolution_height[i] == height ) + { + camsrc_info("capture resolution[%dx%d] is already existed.", width, height); + return; + } + } + + caps_info->capture_resolution_width[i] = width; + caps_info->capture_resolution_height[i] = height; + caps_info->num_capture_resolution++; + + camsrc_info("capture resolution[%dx%d] is added.", width, height); + } + + return; +} + +void _camerasrc_add_total_fps( camerasrc_caps_info_t* caps_info, int numerator, int denominator ) +{ + int i = 0; + + for( i = 0 ; i < caps_info->num_fps ; i++ ) + { + if( caps_info->fps[i].numerator == numerator + && caps_info->fps[i].denominator == denominator ) + { + camsrc_info("fps[%d/%d] is already existed.", numerator, denominator); + return; + } + } + + caps_info->fps[caps_info->num_fps].numerator = numerator; + caps_info->fps[caps_info->num_fps].denominator = denominator; + caps_info->num_fps++; + + camsrc_info("fps[%d/%d] is added.", numerator, denominator); + + return; +} + +int _camerasrc_query_pixfmt_timeperframe(camerasrc_handle_t* handle, camerasrc_caps_info_t* caps_info, int fmt_index, int resolution_index ) +{ + int tpf_cnt = 0; + struct v4l2_frmivalenum vfrmivalenum; + unsigned int fcc = 0; + camerasrc_resolution_t* resolutions = NULL; + + if( !handle || !caps_info ) + { + camsrc_info("handle[%p] or caps_info[%p] is NULL.", handle, caps_info); + return CAMERASRC_ERR_NULL_POINTER; + } + + if( 0 > fmt_index || 0 > resolution_index ) + { + camsrc_info("some index is too small. fmt_index[%d], resolution_index[%d]", + fmt_index, resolution_index); + return CAMERASRC_ERR_RANGE_UNDER; + } + + fcc = caps_info->fmt_desc[fmt_index].fcc; + resolutions = &(caps_info->fmt_desc[fmt_index].resolutions[resolution_index]); + + /* + *How many resolutions are supported in this format + */ + CLEAR(vfrmivalenum); + vfrmivalenum.index = tpf_cnt; + vfrmivalenum.pixel_format = fcc; + vfrmivalenum.width = resolutions->w; + vfrmivalenum.height = resolutions->h; + + while(0 == _camerasrc_ioctl(handle, VIDIOC_ENUM_FRAMEINTERVALS, &vfrmivalenum)) + { + resolutions->tpf[tpf_cnt].num = vfrmivalenum.discrete.numerator; + resolutions->tpf[tpf_cnt].den = vfrmivalenum.discrete.denominator; + tpf_cnt++; + + _camerasrc_add_total_fps( caps_info, vfrmivalenum.discrete.denominator, vfrmivalenum.discrete.numerator ); + } + + if(tpf_cnt == 0) + { + camsrc_info("No timeperframe supported. driver may not support to query"); + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + } + + resolutions->num_avail_tpf = tpf_cnt; + + return CAMERASRC_SUCCESS; +} + +int _camerasrc_query_pixfmt_resolution(camerasrc_handle_t* handle, camerasrc_caps_info_t* caps_info, int fmt_index ) +{ + int res_cnt = 0; + int err = CAMERASRC_ERR_UNKNOWN; + struct v4l2_frmsizeenum vfrmszenum; + camerasrc_fmt_desc_t* fmt_desc = NULL; + + if( !handle || !caps_info ) + { + camsrc_info("handle[%p] or caps_info[%p] is NULL.", handle, caps_info); + return CAMERASRC_ERR_NULL_POINTER; + } + + if( 0 > fmt_index ) + { + camsrc_info("fmt_index[%d] is too small.", fmt_index); + return CAMERASRC_ERR_RANGE_UNDER; + } + + fmt_desc = &caps_info->fmt_desc[fmt_index]; + + /* + *How many resolutions are supported in this format + */ + CLEAR(vfrmszenum); + vfrmszenum.index = res_cnt; + vfrmszenum.pixel_format = fmt_desc->fcc; + while(0 == _camerasrc_ioctl(handle, VIDIOC_ENUM_FRAMESIZES, &vfrmszenum)) + { + fmt_desc->resolutions[res_cnt].w = vfrmszenum.discrete.width; + fmt_desc->resolutions[res_cnt].h = vfrmszenum.discrete.height; + + _camerasrc_add_total_resolution_info( caps_info, caps_info->fmt_desc[fmt_index].fcc_use, + vfrmszenum.discrete.width, vfrmszenum.discrete.height ); + + err = _camerasrc_query_pixfmt_timeperframe(handle, caps_info, fmt_index, res_cnt); + if(err != CAMERASRC_SUCCESS) + { + camsrc_info("timeperframe querying error, err = %d", err); + return err; + } + + res_cnt++; + vfrmszenum.index = res_cnt; + } + + if(res_cnt == 0) + { + camsrc_info("No resolution supported in fcc[0x%8x]. driver may not support to query", fmt_desc->fcc); + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + } + + fmt_desc->num_resolution = res_cnt; + + return CAMERASRC_SUCCESS; +} + +int _camerasrc_query_basic_dev_info(camerasrc_handle_t* handle, camerasrc_caps_info_t* caps_info) { + struct v4l2_fmtdesc vfmtdesc; + struct v4l2_input vinput; + int err = CAMERASRC_ERR_UNKNOWN; + int fmt_cnt = 0; + char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',}; + + caps_info->num_preview_resolution = 0; + caps_info->num_capture_resolution = 0; + caps_info->num_preview_fmt = 0; + caps_info->num_capture_fmt = 0; + caps_info->num_fps = 0; + + /* + * Count how many formats are supported in this dev + */ + CLEAR(vfmtdesc); + CLEAR(vinput); + + /* + * What name of module is selected? + */ + if(CAMERASRC_SUCCESS != _camerasrc_ioctl(handle, VIDIOC_ENUMINPUT, &vinput)) { + strerror_r(handle->errnum, err_msg, CAMERASRC_ERRMSG_MAX_LEN); + camsrc_error("VIDIOC_ENUMINPUT failed : %s", err_msg); + return CAMERASRC_ERR_IO_CONTROL; + } + memcpy(caps_info->dev_name, vinput.name, 32); + + vfmtdesc.index = 0; + vfmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + while(0 == _camerasrc_ioctl(handle, VIDIOC_ENUM_FMT, &vfmtdesc)) + { + camsrc_info("pixelformat \"%c%c%c%c\"(%8x) detected", + (char)(vfmtdesc.pixelformat >> 0), + (char)(vfmtdesc.pixelformat >> 8), + (char)(vfmtdesc.pixelformat >> 16), + (char)(vfmtdesc.pixelformat >> 24), + vfmtdesc.pixelformat); + caps_info->fmt_desc[fmt_cnt].fcc = vfmtdesc.pixelformat; + /* + * Along the description of the format, we seperate them into each usecase + */ + camsrc_info("description \"%s\"", vfmtdesc.description ); + if(!strcmp("rec_prev", (const char*)(vfmtdesc.description))) + { + caps_info->fmt_desc[fmt_cnt].fcc_use = CAMERASRC_FCC_USE_REC_PREVIEW; + caps_info->preview_fmt[caps_info->num_preview_fmt] = vfmtdesc.pixelformat; + caps_info->num_preview_fmt++; + } + else if(!strcmp("cap_prev", (const char*)(vfmtdesc.description))) + { + caps_info->fmt_desc[fmt_cnt].fcc_use = CAMERASRC_FCC_USE_CAP_PREVIEW; + caps_info->preview_fmt[caps_info->num_preview_fmt] = vfmtdesc.pixelformat; + caps_info->num_preview_fmt++; + } + else if(!strcmp("recording", (const char*)(vfmtdesc.description))) + { + caps_info->fmt_desc[fmt_cnt].fcc_use = CAMERASRC_FCC_USE_RECORDING; + } + else if(!strcmp("capture", (const char*)(vfmtdesc.description))) + { + caps_info->fmt_desc[fmt_cnt].fcc_use = CAMERASRC_FCC_USE_NORMAL_CAPTURE; + caps_info->capture_fmt[caps_info->num_capture_fmt] = vfmtdesc.pixelformat; + caps_info->num_capture_fmt++; + } + else if(!strcmp("cont_cap", (const char*)(vfmtdesc.description))) + { + caps_info->fmt_desc[fmt_cnt].fcc_use = CAMERASRC_FCC_USE_CONT_CAPTURE; + caps_info->capture_fmt[caps_info->num_capture_fmt] = vfmtdesc.pixelformat; + caps_info->num_capture_fmt++; + } + else + { + caps_info->fmt_desc[fmt_cnt].fcc_use = CAMERASRC_FCC_USE_NONE; + } + err = _camerasrc_query_pixfmt_resolution(handle, caps_info, fmt_cnt); + if(err != CAMERASRC_SUCCESS) + { + camsrc_info("pixel format querying error, err = %x", err); + } + fmt_cnt++; + vfmtdesc.index = fmt_cnt; + vfmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + } + + + /* + * memory allocation as counted num + */ + camsrc_info("Total supported format = %d", fmt_cnt); + caps_info->num_fmt_desc = fmt_cnt; + + /* + * If no formats supported + */ + if(fmt_cnt == 0) + { + camsrc_info("no format supported"); + return CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + } + return CAMERASRC_SUCCESS; +} + + +int camerasrc_query_basic_dev_info(camsrc_handle_t handle, camerasrc_caps_info_t* caps_info) { + camerasrc_handle_t* p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if(handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + err = _camerasrc_query_basic_dev_info(p, caps_info); + + err = CAMERASRC_SUCCESS; + camsrc_info("leave"); + + return err; +} + +int _camerasrc_query_ctrl_menu (camerasrc_handle_t* handle, struct v4l2_queryctrl queryctrl, camerasrc_ctrl_info_t* ctrl_info) +{ + struct v4l2_querymenu querymenu; + + camsrc_info(" Menu items:"); + + memset (&querymenu, 0, sizeof (querymenu)); + querymenu.id = queryctrl.id; + + for (querymenu.index = queryctrl.minimum; + querymenu.index <= queryctrl.maximum; + querymenu.index++) { + if (0 == _camerasrc_ioctl (handle, VIDIOC_QUERYMENU, &querymenu)) { + camsrc_info(" menu name : %s", querymenu.name); + ctrl_info->ctrl_menu[querymenu.index].menu_index = querymenu.index; + memcpy(&(ctrl_info->ctrl_menu[querymenu.index].menu_name), querymenu.name, 32); + } else { + camsrc_error("VIDIOC_QUERYMENU error"); + return CAMERASRC_ERR_IO_CONTROL; + } + } + return CAMERASRC_SUCCESS; +} + +static int _find_camsrc_ctrl_id(camerasrc_handle_t* handle, int v4l2_cid) +{ + int i = 0; + int tmp_id = 0; + for(i=0; i<CAMERASRC_CTRL_NUM; i++) + { + tmp_id = _CAMERASRC_GET_CID(i, handle->cur_dev_id); + if(tmp_id == v4l2_cid) + return i; + } + + return -1; +} + +int _camerasrc_query_misc_dev_info(camerasrc_handle_t* handle, camerasrc_ctrl_list_info_t* ctrl_list_info) +{ + struct v4l2_queryctrl queryctrl; + + int i = 0; + int ctrl_cnt = 0; + + + camsrc_info("QUERY_BASE "); + for (i = CAMERASRC_CTRL_BRIGHTNESS; i < CAMERASRC_CTRL_NUM; i++) { + queryctrl.id = _CAMERASRC_GET_CID(i, handle->cur_dev_id); + if(queryctrl.id == -1) + { + continue; + } + if (0 == _camerasrc_ioctl (handle, VIDIOC_QUERYCTRL, &queryctrl)) { + if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) + { + camsrc_info("ID [%8x] disabled", queryctrl.id); + /*continue;*/ + } + camsrc_info("Control %s", queryctrl.name); + ctrl_list_info->ctrl_info[ctrl_cnt].v4l2_ctrl_id = queryctrl.id; + ctrl_list_info->ctrl_info[ctrl_cnt].camsrc_ctrl_id = i; + if(ctrl_list_info->ctrl_info[ctrl_cnt].camsrc_ctrl_id == -1) + { + camsrc_warning("This control is not included in camsrc ctrl ID error"); + } + switch(queryctrl.type) + { + case V4L2_CTRL_TYPE_INTEGER: + ctrl_list_info->ctrl_info[ctrl_cnt].ctrl_type = CTRL_TYPE_RANGE; + break; + case V4L2_CTRL_TYPE_BOOLEAN: + ctrl_list_info->ctrl_info[ctrl_cnt].ctrl_type = CTRL_TYPE_BOOL; + break; + case V4L2_CTRL_TYPE_MENU: + ctrl_list_info->ctrl_info[ctrl_cnt].ctrl_type = CTRL_TYPE_ARRAY; + _camerasrc_query_ctrl_menu (handle, queryctrl, &(ctrl_list_info->ctrl_info[ctrl_cnt])); + break; + default: + ctrl_list_info->ctrl_info[ctrl_cnt].ctrl_type = CTRL_TYPE_UNKNOWN; + break; + } + memcpy(ctrl_list_info->ctrl_info[ctrl_cnt].ctrl_name,queryctrl.name, 32); + ctrl_list_info->ctrl_info[ctrl_cnt].min = queryctrl.minimum; + ctrl_list_info->ctrl_info[ctrl_cnt].max = queryctrl.maximum; + ctrl_list_info->ctrl_info[ctrl_cnt].step = queryctrl.step; + ctrl_list_info->ctrl_info[ctrl_cnt].default_val = queryctrl.default_value; + camsrc_info("Control %s", queryctrl.name); + } else { + if (errno == EINVAL) + continue; + camsrc_error("VIDIOC_QUERYCTRL error"); + return CAMERASRC_ERR_IO_CONTROL; + } + ctrl_cnt++; + } + ctrl_list_info->num_ctrl_list_info = ctrl_cnt; + return CAMERASRC_SUCCESS; +} + + +int camerasrc_query_misc_dev_info(camsrc_handle_t handle, camerasrc_ctrl_list_info_t* ctrl_list_info) +{ + camerasrc_handle_t* p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if(handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + err = _camerasrc_query_misc_dev_info(p, ctrl_list_info); + + err = CAMERASRC_SUCCESS; + + camsrc_info("leave"); + + return err; +} + + +int camerasrc_query_misc_dev_ctrl_info(camsrc_handle_t handle, camerasrc_ctrl_t ctrl_id, camerasrc_ctrl_info_t* ctrl_info) +{ + struct v4l2_queryctrl queryctrl; + + CLEAR(queryctrl); + + queryctrl.id = _CAMERASRC_GET_CID(ctrl_id, CAMERASRC_HANDLE(handle)->cur_dev_id); + if (0 == _camerasrc_ioctl (handle, VIDIOC_QUERYCTRL, &queryctrl)) { + if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) + { + camsrc_info("ID [%8x] disabled", queryctrl.id); + } + camsrc_info("Control %s", queryctrl.name); + ctrl_info->v4l2_ctrl_id = queryctrl.id; + ctrl_info->camsrc_ctrl_id = ctrl_id; + if(ctrl_info->camsrc_ctrl_id == -1) + { + camsrc_warning("This control is not included in camsrc ctrl ID error"); + } + switch(queryctrl.type) + { + case V4L2_CTRL_TYPE_INTEGER: + ctrl_info->ctrl_type = CTRL_TYPE_RANGE; + break; + case V4L2_CTRL_TYPE_BOOLEAN: + ctrl_info->ctrl_type = CTRL_TYPE_BOOL; + break; + case V4L2_CTRL_TYPE_MENU: + ctrl_info->ctrl_type = CTRL_TYPE_ARRAY; + _camerasrc_query_ctrl_menu (handle, queryctrl, ctrl_info); + break; + default: + ctrl_info->ctrl_type = CTRL_TYPE_UNKNOWN; + break; + } + memcpy(ctrl_info->ctrl_name,queryctrl.name, MAX_SZ_CTRL_NAME_STRING); + ctrl_info->min = queryctrl.minimum; + ctrl_info->max = queryctrl.maximum; + ctrl_info->step = queryctrl.step; + ctrl_info->default_val = queryctrl.default_value; + camsrc_info("Control %s", queryctrl.name); + } else { + camsrc_error("VIDIOC_QUERYCTRL error"); + return CAMERASRC_ERR_IO_CONTROL; + } + return CAMERASRC_SUCCESS; +} + + +int camerasrc_dump_misc_dev_info(camsrc_handle_t handle, camerasrc_ctrl_list_info_t* ctrl_list_info) +{ + camsrc_info("enter"); + int i=0; + int j=0; + + camsrc_info("============================================================"); + for(i = 0; i < ctrl_list_info->num_ctrl_list_info; i++) + { + camsrc_info("[camsrc ID : %d] [v4l2 ID : 0x%08x] Control name = %s", ctrl_list_info->ctrl_info[i].camsrc_ctrl_id, ctrl_list_info->ctrl_info[i].v4l2_ctrl_id, ctrl_list_info->ctrl_info[i].ctrl_name); + camsrc_info(" Control type = %d", ctrl_list_info->ctrl_info[i].ctrl_type); + camsrc_info(" Min = %d / Max = %d / Step = %d / default = %d", ctrl_list_info->ctrl_info[i].min, ctrl_list_info->ctrl_info[i].max, ctrl_list_info->ctrl_info[i].step, ctrl_list_info->ctrl_info[i].default_val); + if(ctrl_list_info->ctrl_info[i].ctrl_type == CTRL_TYPE_ARRAY) + { + camsrc_info("\t\t - Menu list"); + for(j = ctrl_list_info->ctrl_info[i].min; j <= ctrl_list_info->ctrl_info[i].max; j++) + { + camsrc_info("\t\t * %s", ctrl_list_info->ctrl_info[i].ctrl_menu[j].menu_name); + } + } + } + camsrc_info("============================================================"); + camsrc_info("leave"); + return CAMERASRC_SUCCESS; +} + + +int camerasrc_dump_basic_dev_info(camsrc_handle_t handle, camerasrc_caps_info_t* caps_info) { + camsrc_info("enter"); + int i,j,k; + + camsrc_info("==============================================================="); + for(i = 0; i< caps_info->num_fmt_desc; i++) + { + camsrc_info("Supported fourcc = \"%c%c%c%c\" (0x%08x) num of resolution = %d", + (char)(caps_info->fmt_desc[i].fcc >> 0), + (char)(caps_info->fmt_desc[i].fcc >> 8), + (char)(caps_info->fmt_desc[i].fcc >> 16), + (char)(caps_info->fmt_desc[i].fcc >> 24), + caps_info->fmt_desc[i].fcc, + caps_info->fmt_desc[i].num_resolution); + for(j=0; j<caps_info->fmt_desc[i].num_resolution; j++) + { + camsrc_info("\tresolution = %d x %d, num of tpf = %d", + caps_info->fmt_desc[i].resolutions[j].w, caps_info->fmt_desc[i].resolutions[j].h, + caps_info->fmt_desc[i].resolutions[j].num_avail_tpf); + for(k=0; k<caps_info->fmt_desc[i].resolutions[j].num_avail_tpf; k++) + { + camsrc_info("\t\ttimeperframe = %d / %d", caps_info->fmt_desc[i].resolutions[j].tpf[k].num, caps_info->fmt_desc[i].resolutions[j].tpf[k].den); + } + } + } + camsrc_info("==============================================================="); + camsrc_info("total supported preview resolution"); + for( i = 0 ; i < caps_info->num_preview_resolution ; i++ ) + { + camsrc_info("%5dx%5d", caps_info->preview_resolution_width[i], caps_info->preview_resolution_height[i]); + + } + camsrc_info("==============================================================="); + camsrc_info("total supported capture resolution"); + for( i = 0 ; i < caps_info->num_capture_resolution ; i++ ) + { + camsrc_info("%5dx%5d", caps_info->capture_resolution_width[i], caps_info->capture_resolution_height[i]); + + } + camsrc_info("==============================================================="); + camsrc_info("total supported preview fourcc"); + for( i = 0 ; i < caps_info->num_preview_fmt ; i++ ) + { + camsrc_info("\"%c%c%c%c\" (0x%08x)", + (char)(caps_info->preview_fmt[i]), + (char)(caps_info->preview_fmt[i]>>8), + (char)(caps_info->preview_fmt[i]>>16), + (char)(caps_info->preview_fmt[i]>>24), + caps_info->preview_fmt[i]); + } + camsrc_info("==============================================================="); + camsrc_info("total supported capture fourcc"); + for( i = 0 ; i < caps_info->num_capture_fmt ; i++ ) + { + camsrc_info("\"%c%c%c%c\" (0x%08x)", + (char)(caps_info->capture_fmt[i]), + (char)(caps_info->capture_fmt[i]>>8), + (char)(caps_info->capture_fmt[i]>>16), + (char)(caps_info->capture_fmt[i]>>24), + caps_info->capture_fmt[i]); + } + camsrc_info("==============================================================="); + camsrc_info("total supported fps"); + for( i = 0 ; i < caps_info->num_fps ; i++ ) + { + camsrc_info("%3d/%3d", caps_info->fps[i].numerator, caps_info->fps[i].denominator); + } + camsrc_info("==============================================================="); + camsrc_info("leave"); + return CAMERASRC_SUCCESS; +} + + +int camerasrc_dump_extra_dev_info(camsrc_handle_t handle, camerasrc_extra_info_t* extra_info) +{ + camsrc_info("enter"); + camsrc_info("==============================================================="); + camsrc_info(" Strobe can support below"); + if (extra_info->strobe_caps == CAMERASRC_STROBE_CAP_NONE) { + camsrc_info(" - Strobe Support Nothing"); + } else { + if (extra_info->strobe_caps & CAMERASRC_STROBE_CAP_OFF) + camsrc_info(" - Always off mode"); + if (extra_info->strobe_caps & CAMERASRC_STROBE_CAP_ON) + camsrc_info(" - Always on mode"); + if (extra_info->strobe_caps & CAMERASRC_STROBE_CAP_AUTO) + camsrc_info(" - Auto mode"); + if (extra_info->strobe_caps & CAMERASRC_STROBE_CAP_REDEYE) + camsrc_info(" - Redeye reduction mode"); + if (extra_info->strobe_caps & CAMERASRC_STROBE_CAP_SLOWSYNC) + camsrc_info(" - Slow sync mode"); + if (extra_info->strobe_caps & CAMERASRC_STROBE_CAP_FRONT_CURTAIN) + camsrc_info(" - Front curtain mode"); + if (extra_info->strobe_caps & CAMERASRC_STROBE_CAP_REAR_CURTAIN) + camsrc_info(" - Rear curtain mode"); + if (extra_info->strobe_caps & CAMERASRC_STROBE_CAP_PERMANENT) + camsrc_info(" - Permanent mode"); + if (extra_info->strobe_caps & CAMERASRC_STROBE_CAP_EXTERNAL) + camsrc_info(" - External strobe mode"); + } + + if (extra_info->detection_caps) { + camsrc_info(" Facedetection can be supported"); + } else { + camsrc_info(" Facedetection can't be supported"); + } + + camsrc_info("==============================================================="); + camsrc_info("leave"); + + return CAMERASRC_SUCCESS; +} + +static int _camerasrc_query_extra_dev_info(camerasrc_handle_t* handle, camerasrc_extra_info_t* extra_info) +{ + struct v4l2_capability capability; + + if (0 == _camerasrc_ioctl (handle, VIDIOC_QUERYCAP, &capability)) { + camsrc_info("VIDIOC_QUERYCAP result [0x%08x]", capability.capabilities); + if((capability.capabilities & V4L2_CAP_STROBE) != 0) + { + /* Strobe supported */ + struct v4l2_strobe strobecaps; + if (0 == _camerasrc_ioctl (handle, VIDIOC_G_STROBE, &strobecaps)) + { + extra_info->strobe_caps = strobecaps.capabilities; + } + else + { + camsrc_error("VIDIOC_G_STROBE error"); + return CAMERASRC_ERR_IO_CONTROL; + } + } + else + { + /* Strobe NOT supported */ + camsrc_error("STROBE not supported"); + extra_info->strobe_caps = 0; + } + + if((capability.capabilities & V4L2_CAP_OBJ_RECOGNITION) != 0) + { + /* Recognition supported */ + extra_info->detection_caps = 1; + } + else + { + camsrc_error("FACEDETECTION not supported"); + extra_info->detection_caps = 0; + /* Recognition NOT supported */ + } + + return CAMERASRC_SUCCESS; + } else { + camsrc_error("VIDIOC_QUERYCAP error"); + + return CAMERASRC_ERR_IO_CONTROL; + } +} + + +int camerasrc_query_extra_dev_info(camsrc_handle_t handle, camerasrc_extra_info_t* extra_info) +{ + camerasrc_handle_t* p = NULL; + int err = CAMERASRC_ERR_UNKNOWN; + + camsrc_info("enter"); + + if(handle == NULL) { + camsrc_error("handle is null"); + return CAMERASRC_ERR_NULL_POINTER; + } + + p = CAMERASRC_HANDLE(handle); + + err = _camerasrc_query_extra_dev_info(p, extra_info); + + err = CAMERASRC_SUCCESS; + camsrc_info("leave"); + + return err; +} + +/* END For Query functionalities */ diff --git a/camerasrc/src/gstcamerasrc.c b/camerasrc/src/gstcamerasrc.c new file mode 100644 index 0000000..9871741 --- /dev/null +++ b/camerasrc/src/gstcamerasrc.c @@ -0,0 +1,3894 @@ +/* + * camerasrc + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang <jm80.yang@samsung.com> + * + * 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.1 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., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/gst.h> +#include <gst/gstutils.h> +#include <glib-object.h> +#include <unistd.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sched.h> /* sched_yield() */ + +#include "gstcamerasrc.h" +#include "gstcamerasrccontrol.h" +#include "gstcamerasrccolorbalance.h" + + +/****************************************************************************** + * Definitions + *******************************************************************************/ +GST_DEBUG_CATEGORY (camerasrc_debug); +#define GST_CAT_DEFAULT camerasrc_debug + +#define USE_FRAME_SAFETY_MARGIN + +#if defined (USE_FRAME_SAFETY_MARGIN) +#define FRAME_SAFETY_MARGIN 4096 +#else +#define FRAME_SAFETY_MARGIN 0 +#endif + +#ifndef YUV422_SIZE +#define YUV422_SIZE(width,height) ( ((width)*(height)) << 1 ) +#endif + +#ifndef YUV420_SIZE +#define YUV420_SIZE(width,height) ( ((width)*(height)*3) >> 1 ) +#endif + +#define SCMN_CS_YUV420 1 /* Y:U:V 4:2:0 */ +#define SCMN_CS_I420 SCMN_CS_YUV420 /* Y:U:V */ +#define SCMN_CS_NV12 6 +#define SCMN_CS_NV12_T64X32 11 /* 64x32 Tiled NV12 type */ +#define SCMN_CS_UYVY 100 +#define SCMN_CS_YUYV 101 +#define SCMN_CS_YUY2 SCMN_CS_YUYV + +/* max channel count *********************************************************/ +#define SCMN_IMGB_MAX_PLANE (4) + +/* image buffer definition *************************************************** + + +------------------------------------------+ --- + | | ^ + | a[], p[] | | + | +---------------------------+ --- | | + | | | ^ | | + | |<---------- w[] ---------->| | | | + | | | | | | + | | | | + | | | h[] | e[] + | | | | + | | | | | | + | | | | | | + | | | v | | + | +---------------------------+ --- | | + | | v + +------------------------------------------+ --- + + |<----------------- s[] ------------------>| +*/ + +typedef struct +{ + /* width of each image plane */ + int w[SCMN_IMGB_MAX_PLANE]; + /* height of each image plane */ + int h[SCMN_IMGB_MAX_PLANE]; + /* stride of each image plane */ + int s[SCMN_IMGB_MAX_PLANE]; + /* elevation of each image plane */ + int e[SCMN_IMGB_MAX_PLANE]; + /* user space address of each image plane */ + void *a[SCMN_IMGB_MAX_PLANE]; + /* physical address of each image plane, if needs */ + void *p[SCMN_IMGB_MAX_PLANE]; + /* color space type of image */ + int cs; + /* left postion, if needs */ + int x; + /* top position, if needs */ + int y; + /* to align memory */ + int __dummy2; + /* arbitrary data */ + int data[16]; +} SCMN_IMGB; + +#if !defined (PAGE_SHIFT) + #define PAGE_SHIFT sysconf(_SC_PAGESIZE) +#endif +#if !defined (PAGE_SIZE) + #define PAGE_SIZE (1UL << PAGE_SHIFT) +#endif +#if !defined (PAGE_MASK) + #define PAGE_MASK (~(PAGE_SIZE-1)) +#endif +#if !defined (PAGE_ALIGN) + #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) +#endif + +#define ALIGN_SIZE_I420 (1024<<2) +#define ALIGN_SIZE_NV12 (1024<<6) +#define CAMERASRC_ALIGN(addr,size) (((addr)+((size)-1))&(~((size)-1))) + +#if !defined (CLEAR) + #define CLEAR(x) memset(&(x), 0, sizeof(x)) +#endif + + +/* Enables */ +#define _ENABLE_CAMERASRC_DEBUG 0 + +/* Local definitions */ +#define _DEFAULT_WIDTH 320 +#define _DEFAULT_HEIGHT 240 +#define _DEFAULT_FPS 30 +#define _DEFAULT_HIGH_SPEED_FPS 0 +#define _DEFAULT_FPS_AUTO FALSE +#define _DEFAULT_PIX_FORMAT CAMERASRC_PIX_UYVY +#define _DEFAULT_FOURCC GST_MAKE_FOURCC ('J', 'P', 'E', 'G') +#define _DEFAULT_COLORSPACE CAMERASRC_COL_RAW +#define _DEFAULT_CAMERA_ID CAMERASRC_DEV_ID_PRIMARY + +/* mmap/pad-alloc related definition */ +#define _DEFAULT_NUM_LIVE_BUFFER 0 +#define _DEFAULT_BUFFER_COUNT 0 +#define _ALLOWED_GAP_BTWN_BUF 5 /* Allowed gap between circulation count of each buffer and that of average buffer */ +#define _DEFAULT_BUFFER_RUNNING FALSE +#define _DEFAULT_DEQUE_WAITINGTIME 200 /* msec */ +#define _MINIMUM_REMAINING_V4L2_QBUF 1 /* minimum number of buffer that should remain in the v4l2 driver */ + +#define _FD_DEFAULT (-1) +#define _FD_MIN (-1) +#define _FD_MAX (1<<15) /* 2^15 == 32768 */ + +#define _DEFAULT_CAP_QUALITY GST_CAMERASRC_QUALITY_HIGH +#define _DEFAULT_CAP_JPG_QUALITY 95 +#define _DEFAULT_CAP_WIDTH 1600 +#define _DEFAULT_CAP_HEIGHT 1200 +#define _DEFAULT_CAP_COUNT 1 +#define _DEFAULT_CAP_INTERVAL 0 +#define _DEFAULT_CAP_PROVIDE_EXIF FALSE +#define _DEFAULT_ENABLE_ZSL_MODE FALSE +#define _DEFAULT_DO_FACE_DETECT FALSE +#define _DEFAULT_DO_AF FALSE +#define _DEFAULT_SIGNAL_AF FALSE +#define _DEFAULT_SIGNAL_STILL_CAPTURE FALSE +#define _DEFAULT_PREVIEW_WIDTH _DEFAULT_WIDTH +#define _DEFAULT_PREVIEW_HEIGHT _DEFAULT_HEIGHT +#define _DEFAULT_KEEPING_BUFFER 0 +#define _DEFAULT_USE_PAD_ALLOC FALSE +#define _DEFAULT_NUM_ALLOC_BUF 6 +#define _DEFAULT_SCRNL_FOURCC GST_MAKE_FOURCC('N','V','1','2') +#define _MAX_NUM_ALLOC_BUF 100 +#define _MAX_TRIAL_WAIT_FRAME 25 +#define _PAD_ALLOC_RETRY_PERIOD 25 +#define _MAX_PAD_ALLOC_RETRY_COUNT 300 +#define _CONTINUOUS_SHOT_MARGIN 50 /* msec */ +#define _PREVIEW_BUFFER_WAIT_TIMEOUT 2000000 /* usec */ + +/*FIXME*/ +#define _THUMBNAIL_WIDTH 320 +#define _THUMBNAIL_HEIGHT 240 + +#define GST_TYPE_CAMERASRC_BUFFER (gst_camerasrc_buffer_get_type()) +#define GST_IS_CAMERASRC_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_CAMERASRC_BUFFER)) +#define GST_CAMERASRC_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_CAMERASRC_BUFFER, GstCameraBuffer)) +#define GST_TYPE_CAMERASRC_QUALITY (gst_camerasrc_quality_get_type()) + + +/* Enumerations */ +enum { + /*signal*/ + SIGNAL_STILL_CAPTURE, + SIGNAL_NEGO_COMPLETE, + /*SIGNAL_REGISTER_TROUBLE,*/ + LAST_SIGNAL +}; + +enum { + ARG_0, + /* camera */ + ARG_CAMERA_HIGH_SPEED_FPS, + ARG_CAMERA_AUTO_FPS, + ARG_CAMERA_ID, + ARG_CAMERA_EXT_VIDEO_FD, + + /* capture */ + ARG_CAMERA_CAPTURE_FOURCC, + ARG_CAMERA_CAPTURE_QUALITY, + ARG_CAMERA_CAPTURE_WIDTH, + ARG_CAMERA_CAPTURE_HEIGHT, + ARG_CAMERA_CAPTURE_INTERVAL, + ARG_CAMERA_CAPTURE_COUNT, + ARG_CAMERA_CAPTURE_JPG_QUALITY, + ARG_CAMERA_CAPTURE_PROVIDE_EXIF, + + /* signal */ + ARG_SIGNAL_STILLCAPTURE, + ARG_REQ_NEGOTIATION, + + ARG_USE_PAD_ALLOC, + ARG_NUM_ALLOC_BUF, + ARG_OPERATION_STATUS, + ARG_HOLD_AF_AFTER_CAPTURE, + ARG_FAKE_ESD, + ARG_SENSOR_MODE, + ARG_VFLIP, + ARG_HFLIP, + ARG_NUM, +}; + +enum { + VIDEO_IN_MODE_UNKNOWN, + VIDEO_IN_MODE_PREVIEW, + VIDEO_IN_MODE_VIDEO, + VIDEO_IN_MODE_CAPTURE, +}; + +/* Structures */ +typedef struct { + gint index; + gint buffer_data_index; + GstCameraSrc *camerasrc; +} GST_CAMERASRC_BUFFER_DATA; + +static void gst_camerasrc_uri_handler_init (gpointer g_iface, gpointer iface_data); + +/* Local variables */ +static GstBufferClass *camera_buffer_parent_class = NULL; + +static guint gst_camerasrc_signals[LAST_SIGNAL] = { 0 }; + +/* For pad_alloc architecture */ +static camerasrc_usr_buf_t g_present_buf; + +#if _ENABLE_CAMERASRC_DEBUG +static unsigned int g_preview_frame_cnt; +#endif + +/* Element template variables */ +static GstStaticPadTemplate src_factory = + GST_STATIC_PAD_TEMPLATE("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS("video/x-raw-yuv," + "format = (fourcc) { UYVY }, " + "width = (int) [ 1, 4096 ], " + "height = (int) [ 1, 4096 ]; " + "video/x-raw-yuv," + "format = (fourcc) { YU12 }, " + "width = (int) [ 1, 4096 ], " + "height = (int) [ 1, 4096 ]; " + "video/x-raw-yuv," + "format = (fourcc) { I420 }, " + "width = (int) [ 1, 4096 ], " + "height = (int) [ 1, 4096 ]; " + "video/x-raw-yuv," + "format = (fourcc) { NV12 }, " + "width = (int) [ 1, 4096 ], " + "height = (int) [ 1, 4096 ]; " + "video/x-raw-yuv," + "format = (fourcc) { SN12 }, " + "width = (int) [ 1, 4096 ], " + "height = (int) [ 1, 4096 ]; " + "video/x-raw-yuv," + "format = (fourcc) { ST12 }, " + "width = (int) [ 1, 4096 ], " + "height = (int) [ 1, 4096 ]; " + "video/x-raw-yuv," + "format = (fourcc) { YUY2 }, " + "width = (int) [ 1, 4096 ], " + "height = (int) [ 1, 4096 ]; " + "video/x-raw-yuv," + "format = (fourcc) { YUYV }, " + "width = (int) [ 1, 4096 ], " + "height = (int) [ 1, 4096 ]; " + "video/x-raw-yuv," + "format = (fourcc) { SUYV }, " + "width = (int) [ 1, 4096 ], " + "height = (int) [ 1, 4096 ]; " + "video/x-raw-yuv," + "format = (fourcc) { SUY2 }, " + "width = (int) [ 1, 4096 ], " + "height = (int) [ 1, 4096 ]; " + "video/x-raw-yuv," + "format = (fourcc) { SYVY }, " + "width = (int) [ 1, 4096 ], " + "height = (int) [ 1, 4096 ]; " + "video/x-raw-yuv," + "format = (fourcc) { S420 }, " + "width = (int) [ 1, 4096 ], " + "height = (int) [ 1, 4096 ]; " + "video/x-raw-rgb," + "width = (int) [ 1, 4096 ], " + "height = (int) [ 1, 4096 ]")); + +static GstElementDetails camerasrc_details = { + "Camera Source GStreamer Plug-in", + "Src/Video", + "camera src for videosrc based GStreamer Plug-in", + "" +}; + + + +/* Local static functions */ +static void gst_camerasrc_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); +static void gst_camerasrc_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); + +static gboolean gst_camerasrc_src_start(GstBaseSrc *src); +static gboolean gst_camerasrc_src_stop(GstBaseSrc *src); +static gboolean gst_camerasrc_start(GstCameraSrc *camerasrc); + +static GstFlowReturn gst_camerasrc_src_create(GstPushSrc *src, GstBuffer **buffer); +static GstFlowReturn gst_camerasrc_read_capture(GstCameraSrc *camerasrc, GstBuffer **buffer, int command); +static GstFlowReturn gst_camerasrc_read_preview_mmap(GstCameraSrc *camerasrc, GstBuffer **buffer); +static GstFlowReturn gst_camerasrc_read_preview_pad_alloc(GstCameraSrc *camerasrc, GstBuffer **buffer); +static unsigned char *gst_camerasrc_make_metadata_for_nonlinear_buffer(GstCameraSrc *avsysvideosrc, guint32 index); + +static GstStateChangeReturn gst_camerasrc_change_state(GstElement *element, GstStateChange transition); +static GstCaps *gst_camerasrc_get_caps(GstBaseSrc *src); +static gboolean gst_camerasrc_set_caps(GstBaseSrc *src, GstCaps *caps); +static gboolean gst_camerasrc_get_caps_info(GstCameraSrc *camerasrc, GstCaps *caps, guint *size); +static gboolean gst_camerasrc_fill_ctrl_list(GstCameraSrc *camerasrc); +static gboolean gst_camerasrc_empty_ctrl_list(GstCameraSrc *camerasrc); +static void gst_camerasrc_finalize(GObject *object); + +static gboolean gst_camerasrc_device_is_open(GstCameraSrc *camerasrc); +static gboolean gst_camerasrc_get_timeinfo(GstCameraSrc *camerasrc, GstBuffer *buffer); +static int get_proper_index(GstCameraSrc *camerasrc, GstBuffer *pad_alloc_buffer); + +static gboolean gst_camerasrc_capture_start(GstCameraSrc *camerasrc); +static gboolean gst_camerasrc_capture_stop(GstCameraSrc *camerasrc); + +static GstCameraBuffer *gst_camerasrc_buffer_new(GstCameraSrc *camerasrc); +static GType gst_camerasrc_buffer_get_type(void); +static void gst_camerasrc_buffer_class_init(gpointer g_class, gpointer class_data); +static void gst_camerasrc_buffer_finalize(GstCameraBuffer *buffer); +static void gst_camerasrc_buffer_free(gpointer data); +static void gst_camerasrc_buffer_trace(GstCameraSrc *camerasrc); +static void gst_camerasrc_error_handler(GstCameraSrc *camerasrc, int ret); + +/* Util functions */ +static void GenerateYUV420BlackFrame(unsigned char *buf, int buf_size, int width, int height); +static void GenerateYUV422BlackFrame(unsigned char *buf, int buf_size, int width, int height); +static gboolean GenerateST12BlackFrame(GstCameraSrc *camerasrc, unsigned char *buf, int buf_size, int width, int height); +static unsigned long gst_get_current_time(void); +static gboolean _gst_camerasrc_get_frame_size(int fourcc, int width, int height, unsigned int *outsize); +static gboolean _gst_camerasrc_get_raw_pixel_info(int fourcc, int *pix_format, int *colorspace); +static gboolean _gst_camerasrc_get_normal_buffer(GstCameraSrc *camerasrc, int fourcc, + unsigned char *base_buf, int width, int height, + unsigned char **new_buf, unsigned int *length); +#if _ENABLE_CAMERASRC_DEBUG +static int __util_write_file(char *filename, void *data, int size); +#endif /* _ENABLE_CAMERASRC_DEBUG */ +static gboolean gst_camerasrc_negotiate (GstBaseSrc * basesrc); + +GST_IMPLEMENT_CAMERASRC_COLOR_BALANCE_METHODS(GstCameraSrc, gst_camera_src); +GST_IMPLEMENT_CAMERASRC_CONTROL_METHODS(GstCameraSrc, gst_camera_src); + + +/****************************************************************************** + * Implementations + *******************************************************************************/ +static void gst_camerasrc_error_handler(GstCameraSrc *camerasrc, int ret) +{ + switch (ret) { + case CAMERASRC_SUCCESS: + break; + case CAMERASRC_ERR_IO_CONTROL: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, FAILED, ("IO control error"), GST_ERROR_SYSTEM); + break; + case CAMERASRC_ERR_DEVICE_OPEN: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, OPEN_READ_WRITE, ("camera open failed"), GST_ERROR_SYSTEM); + break; + case CAMERASRC_ERR_DEVICE_BUSY: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, BUSY, ("camera device busy"), GST_ERROR_SYSTEM); + break; + case CAMERASRC_ERR_DEVICE_NOT_FOUND: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, NOT_FOUND, ("camera device not found"), GST_ERROR_SYSTEM); + break; + case CAMERASRC_ERR_DEVICE_UNAVAILABLE: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, OPEN_READ, ("camera device unavailable"), GST_ERROR_SYSTEM); + break; + case CAMERASRC_ERR_DEVICE_WAIT_TIMEOUT: + gst_camerasrc_buffer_trace(camerasrc); + GST_ELEMENT_ERROR(camerasrc, RESOURCE, TOO_LAZY, (("Timeout[live_buffers=%d]"), camerasrc->num_live_buffers), GST_ERROR_SYSTEM); + break; + case CAMERASRC_ERR_DEVICE_NOT_SUPPORT: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, SETTINGS, ("Not supported"), GST_ERROR_SYSTEM); + break; + case CAMERASRC_ERR_ALLOCATION: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, SETTINGS, ("memory allocation failed"), GST_ERROR_SYSTEM); + break; + case CAMERASRC_ERR_SECURITY_SERVICE: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, FAILED, ("Security service failed"), GST_ERROR_SYSTEM); + break; + default: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, SEEK, (("General video device error[ret=%x]"), ret), GST_ERROR_SYSTEM); + break; + } + + return; +} + +static gboolean gst_camerasrc_iface_supported(GstImplementsInterface *iface, GType iface_type) +{ + g_assert(iface_type == GST_TYPE_CAMERA_CONTROL || + iface_type == GST_TYPE_COLOR_BALANCE); + + return TRUE; +} + + +static void gst_camerasrc_interface_init(GstImplementsInterfaceClass *klass) +{ + /* + * default virtual functions + */ + klass->supported = gst_camerasrc_iface_supported; +} + + +void gst_camerasrc_init_interfaces(GType type) +{ + static const GInterfaceInfo urihandler_info = { + gst_camerasrc_uri_handler_init, + NULL, + NULL + }; + + static const GInterfaceInfo cameraiface_info = { + (GInterfaceInitFunc)gst_camerasrc_interface_init, + NULL, + NULL, + }; + + static const GInterfaceInfo camerasrc_control_info = { + (GInterfaceInitFunc)gst_camera_src_control_interface_init, + NULL, + NULL, + }; + + static const GInterfaceInfo camerasrc_color_balance_info = { + (GInterfaceInitFunc)gst_camera_src_color_balance_interface_init, + NULL, + NULL, + }; + + g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info); + g_type_add_interface_static(type, GST_TYPE_IMPLEMENTS_INTERFACE, &cameraiface_info); + g_type_add_interface_static(type, GST_TYPE_CAMERA_CONTROL, &camerasrc_control_info); + g_type_add_interface_static(type, GST_TYPE_COLOR_BALANCE, &camerasrc_color_balance_info); +} + + +static GType gst_camerasrc_quality_get_type(void) +{ + static GType camerasrc_quality_type = 0; + static const GEnumValue quality_types[] = { + {GST_CAMERASRC_QUALITY_LOW, "Low quality", "low"}, + {GST_CAMERASRC_QUALITY_HIGH, "High quality", "high"}, + {0, NULL, NULL} + }; + + if (!camerasrc_quality_type) { + camerasrc_quality_type = g_enum_register_static ("GstCameraSrcQuality", quality_types); + } + return camerasrc_quality_type; +} + +/* VOID:OBJECT,OBJECT (generated by 'glib-genmarshal') */ +#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +void gst_camerasrc_VOID__OBJECT_OBJECT(GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT)(gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer arg_3, + gpointer data2); + register GMarshalFunc_VOID__OBJECT_OBJECT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA(closure)) { + data1 = closure->data; + data2 = g_value_peek_pointer(param_values + 0); + } else { + data1 = g_value_peek_pointer(param_values + 0); + data2 = closure->data; + } + + callback = (GMarshalFunc_VOID__OBJECT_OBJECT)(marshal_data ? marshal_data : cc->callback); + + callback(data1, + g_marshal_value_peek_object(param_values + 1), + g_marshal_value_peek_object(param_values + 2), + g_marshal_value_peek_object(param_values + 3), + data2); +} + + +/* use following BOILERPLATE MACRO as _get_type entry */ +GST_BOILERPLATE_FULL(GstCameraSrc, gst_camerasrc, GstPushSrc, GST_TYPE_PUSH_SRC, gst_camerasrc_init_interfaces); + + +static int gst_camerasrc_af_cb(camsrc_handle_t handle, int state, void *usr_param) +{ + GstCameraSrc *camerasrc = (GstCameraSrc *)usr_param; + GstMessage *m = NULL; + GstStructure *s = NULL; + + MMTA_ACUM_ITEM_END("AutoFocus operating time", FALSE); + + GST_INFO_OBJECT(camerasrc, "autofocus callback: state [%d]", state); + + s = gst_structure_new("camerasrc-AF", + "focus-state", G_TYPE_INT, state, + NULL); + m = gst_message_new_element(GST_OBJECT(camerasrc), s); + gst_element_post_message(GST_ELEMENT(camerasrc), m); + + return CAMERASRC_SUCCESS; +} + + +static gboolean gst_camerasrc_create(GstCameraSrc *camerasrc) +{ + int ret = 0; + + /*create handle*/ + __ta__(" camerasrc_create", + ret = camerasrc_create(&(camerasrc->v4l2_handle)); + ); + if (ret != CAMERASRC_SUCCESS) { + GST_ERROR_OBJECT(camerasrc, "camerasrc_create() failed. errcode = 0x%08X", ret); + goto _ERROR; + } + + GST_INFO_OBJECT (camerasrc, "camerasrc_create() done"); + + if (camerasrc->external_videofd != _FD_DEFAULT) { + __ta__(" camerasrc_set_videofd", + camerasrc_set_videofd(camerasrc->v4l2_handle,camerasrc->external_videofd); + ); + } + + /*CAMERASRC CAM: realize*/ + __ta__(" camerasrc_realize", + ret = camerasrc_realize(camerasrc->v4l2_handle); + ); + if (ret != CAMERASRC_SUCCESS) { + goto _ERROR; + } + + GST_INFO_OBJECT (camerasrc, "camerasrc_realize() done"); + + /*CAMERASRC CAM: start*/ + __ta__(" camerasrc_start", + ret = camerasrc_start(camerasrc->v4l2_handle); + ); + if (ret != CAMERASRC_SUCCESS) { + GST_ERROR_OBJECT(camerasrc, "camerasrc_start() failed. errcode = 0x%x", ret); + goto _ERROR; + } + + /*CAMERASRC CAM: set camera device id*/ + /**@note if realized, iput device can't change!*/ + __ta__(" camerasrc_set_input", + ret = camerasrc_set_input(camerasrc->v4l2_handle, camerasrc->camera_id); + ); + if (ret != CAMERASRC_SUCCESS) { + GST_ERROR_OBJECT(camerasrc, "camerasrc_set_input() failed. errcode = 0x%x", ret); + goto _ERROR; + } + + if (!gst_camerasrc_fill_ctrl_list(camerasrc)) { + GST_WARNING_OBJECT(camerasrc, "Can't fill v4l2 control list."); + } + + return TRUE; + + _ERROR: + gst_camerasrc_error_handler(camerasrc, ret); + + return FALSE; +} + + +static gboolean gst_camerasrc_destroy(GstCameraSrc *camerasrc) +{ + GST_INFO_OBJECT (camerasrc, "ENTERED"); + + if (camerasrc->v4l2_handle) { + /*Empty control list */ + gst_camerasrc_empty_ctrl_list(camerasrc); + + /*CAMERASRC CAM: stop stream*/ + /*CAMERASRC CAM: unrealize*/ + GST_INFO_OBJECT(camerasrc, "camerasrc_unrealize() calling..."); + camerasrc_unrealize(camerasrc->v4l2_handle); + + /*CAMERASRC CAM: destroy*/ + GST_INFO_OBJECT(camerasrc, "camerasrc_destroy() calling..."); + camerasrc_destroy(camerasrc->v4l2_handle); + camerasrc->v4l2_handle = NULL; + GST_INFO_OBJECT(camerasrc, "AV cam destroyed."); + camerasrc->mode = VIDEO_IN_MODE_UNKNOWN; + } + + GST_INFO_OBJECT(camerasrc, "LEAVED"); + + return TRUE; +} + + +static gboolean gst_camerasrc_fill_ctrl_list(GstCameraSrc *camerasrc) +{ + int n = 0; + camerasrc_ctrl_info_t ctrl_info; + + g_return_val_if_fail(camerasrc, FALSE); + g_return_val_if_fail(camerasrc->v4l2_handle, FALSE); + + GST_DEBUG_OBJECT(camerasrc, "ENTERED"); + + for (n = CAMERASRC_CTRL_BRIGHTNESS ; n < CAMERASRC_CTRL_NUM ; n++) { + GstCameraSrcColorBalanceChannel *camerasrc_color_channel = NULL; + GstColorBalanceChannel *color_channel = NULL; + + GstCamerasrcControlChannel *camerasrc_control_channel = NULL; + GstCameraControlChannel *control_channel = NULL; + + gint channel_type; + + memset(&ctrl_info, 0x0, sizeof(camerasrc_ctrl_info_t)); + + if (camerasrc_query_control(camerasrc->v4l2_handle, n, &ctrl_info) != CAMERASRC_SUCCESS) { + /* TODO: */ + } + + switch (n) { + case CAMERASRC_CTRL_BRIGHTNESS: + case CAMERASRC_CTRL_CONTRAST: + case CAMERASRC_CTRL_WHITE_BALANCE: + case CAMERASRC_CTRL_COLOR_TONE: + case CAMERASRC_CTRL_PARTCOLOR_SRC: + case CAMERASRC_CTRL_PARTCOLOR_DST: + case CAMERASRC_CTRL_PARTCOLOR_MODE: + case CAMERASRC_CTRL_SATURATION: + case CAMERASRC_CTRL_SHARPNESS: + channel_type = INTERFACE_COLOR_BALANCE; + break; + case CAMERASRC_CTRL_DIGITAL_ZOOM: + case CAMERASRC_CTRL_OPTICAL_ZOOM: + case CAMERASRC_CTRL_PROGRAM_MODE: + case CAMERASRC_CTRL_FLIP: + case CAMERASRC_CTRL_ANTI_HANDSHAKE: + case CAMERASRC_CTRL_WIDE_DYNAMIC_RANGE: + channel_type = INTERFACE_CAMERA_CONTROL; + break; + default: + channel_type = INTERFACE_NONE; + continue; + } + + if (channel_type == INTERFACE_COLOR_BALANCE) { + camerasrc_color_channel = g_object_new(GST_TYPE_CAMERASRC_COLOR_BALANCE_CHANNEL, NULL); + color_channel = GST_COLOR_BALANCE_CHANNEL(camerasrc_color_channel); + + color_channel->label = g_strdup((const gchar *)camerasrc_ctrl_label[n]); + camerasrc_color_channel->id = n; + color_channel->min_value = ctrl_info.min; + color_channel->max_value = ctrl_info.max; + + camerasrc->colors = g_list_append(camerasrc->colors, (gpointer)color_channel); + GST_INFO_OBJECT(camerasrc, "Adding Color Balance Channel %s (%x)", + color_channel->label, camerasrc_color_channel->id); + } else { /* if( channel_type == INTERFACE_CAMERA_CONTROL ) */ + camerasrc_control_channel = g_object_new(GST_TYPE_CAMERASRC_CONTROL_CHANNEL, NULL); + control_channel = GST_CAMERA_CONTROL_CHANNEL(camerasrc_control_channel); + + control_channel->label = g_strdup((const gchar *)camerasrc_ctrl_label[n]); + camerasrc_control_channel->id = n; + control_channel->min_value = ctrl_info.min; + control_channel->max_value = ctrl_info.max; + + camerasrc->camera_controls = g_list_append(camerasrc->camera_controls, (gpointer)control_channel); + GST_INFO_OBJECT(camerasrc, "Adding Camera Control Channel %s (%x)", + control_channel->label, camerasrc_control_channel->id); + } + } + + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + + return TRUE; +} + + +static gboolean gst_camerasrc_empty_ctrl_list(GstCameraSrc *camerasrc) +{ + g_return_val_if_fail(camerasrc, FALSE); + + GST_DEBUG_OBJECT (camerasrc, "ENTERED"); + + g_list_foreach(camerasrc->colors, (GFunc)g_object_unref, NULL); + g_list_free(camerasrc->colors); + camerasrc->colors = NULL; + + g_list_foreach(camerasrc->camera_controls, (GFunc)g_object_unref, NULL); + g_list_free(camerasrc->camera_controls); + camerasrc->camera_controls = NULL; + + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + + return TRUE; +} + + +static GstFlowReturn gst_camerasrc_prepare_preview(GstCameraSrc *camerasrc, int buf_num) +{ + int page_size = getpagesize(); + int buffer_size = 0; + int i = 0; + int ret = 0; + unsigned int main_buf_sz = 0; + unsigned int thumb_buf_sz = 0; + GstCaps *negotiated_caps = gst_pad_get_negotiated_caps(GST_BASE_SRC_PAD(camerasrc)); + + g_return_val_if_fail(buf_num <= MAX_USR_BUFFER_NUM, GST_FLOW_ERROR); + + camerasrc_query_img_buf_size(camerasrc->v4l2_handle, &main_buf_sz, &thumb_buf_sz); + + buffer_size = (main_buf_sz + page_size - 1) & ~(page_size - 1); + + g_present_buf.present_buffer = calloc(buf_num, sizeof(camerasrc_buffer_t)); + + for (i = 0 ; i < buf_num ; i++) { + GST_INFO_OBJECT (camerasrc,"pad_alloc called"); + ret = gst_pad_alloc_buffer(GST_BASE_SRC_PAD (camerasrc), + 0, + main_buf_sz, + negotiated_caps, + &(camerasrc->usr_buffer[i])); + + if (!GST_IS_BUFFER(camerasrc->usr_buffer[i])) { + GST_INFO_OBJECT (camerasrc, "[%d] NOT BUFFER!!?", i); + } + if (ret != GST_FLOW_OK) { + GST_ERROR_OBJECT (camerasrc, "gst_pad_alloc_buffer failed. [%d]", ret); + return ret; + } + + GST_INFO_OBJECT(camerasrc, "Alloced Size %d, Alloced address %p", + GST_BUFFER_SIZE(camerasrc->usr_buffer[i]), + GST_BUFFER_DATA(camerasrc->usr_buffer[i])); + + g_present_buf.present_buffer[i].start = GST_BUFFER_DATA(camerasrc->usr_buffer[i]); + g_present_buf.present_buffer[i].length = buffer_size; + } + + g_present_buf.num_buffer = buf_num; + + gst_caps_unref(negotiated_caps); + negotiated_caps = NULL; + + ret = camerasrc_present_usr_buffer(camerasrc->v4l2_handle, &g_present_buf, CAMERASRC_IO_METHOD_USRPTR); + if (ret != CAMERASRC_SUCCESS) { + GST_ERROR_OBJECT(camerasrc, "camerasrc_present_usr_buffer failed ret = %x", ret); + } else { + GST_INFO_OBJECT(camerasrc, "present_buffer success"); + } + + /*CAMERASRC CAM: start video preview*/ + ret = camerasrc_start_preview_stream(camerasrc->v4l2_handle); + if (ret != CAMERASRC_SUCCESS) { + GST_ERROR_OBJECT (camerasrc, "camerasrc_start_preview_stream() failed. errcode = 0x%08X", ret); + gst_camerasrc_error_handler(camerasrc, ret); + + return GST_FLOW_ERROR; + } + + GST_INFO_OBJECT(camerasrc, "camerasrc_start_preview_stream() done"); + + camerasrc->buffer_running = TRUE; + camerasrc->buffer_count = buf_num; + camerasrc->first_invokation = TRUE; + + return GST_FLOW_OK; +} + + +static gboolean gst_camerasrc_start(GstCameraSrc *camerasrc) +{ + int ret = 0; + + camerasrc_format_t fmt; + camerasrc_frac_t frac; + + GST_DEBUG_OBJECT(camerasrc, "ENTERED"); + +#ifdef _SPEED_UP_RAW_CAPTURE + /* check if from no stream change capture */ + if (camerasrc->mode == VIDEO_IN_MODE_CAPTURE && + camerasrc->cap_stream_diff == FALSE) { + camerasrc->buffer_running = TRUE; + goto _READY_DONE; + } + + camerasrc->cap_stream_diff = FALSE; +#endif + + /**@note do not setting at camer starting time*/ + /*CAMERASRC CAM: set FILTER (by default value)*/ + + /*CAMERASRC CAM: callback*/ + camerasrc_set_focused_callback(camerasrc->v4l2_handle, gst_camerasrc_af_cb, camerasrc); + + CLEAR(fmt); + CLEAR(frac); + + /*CAMERASRC CAM: format*/ + fmt.pix_format = camerasrc->pix_format; + fmt.colorspace = camerasrc->colorspace; + fmt.is_highquality_mode = 0; /*Fixed. if preview mode, set 0*/ + fmt.rotation = camerasrc->rotate; + + /*CAMERASRC CAM: set resolution - Do not care about rotation */ + CAMERASRC_SET_SIZE_BY_DIMENSION(fmt, camerasrc->width, camerasrc->height); + + /*CAMERASRC CAM: set format*/ + GST_INFO_OBJECT(camerasrc, "pix [%dx%d] fps %d, format %d, colorspace %d, rotation %d", + camerasrc->width, camerasrc->height, camerasrc->fps, + fmt.pix_format, fmt.colorspace, fmt.rotation); + ret = camerasrc_set_format(camerasrc->v4l2_handle, &fmt); + if (ret != CAMERASRC_SUCCESS) { + GST_ERROR_OBJECT (camerasrc, "camerasrc_set_format() failed. errcode = 0x%08X", ret); + goto _ERROR; + } + + /*CAMERASRC CAM: set fps*/ + if (camerasrc->fps_auto) { + /*if fps is zero, auto fps mode*/ + frac.numerator = 0; + frac.denominator = 1; + GST_INFO_OBJECT (camerasrc, "FPS auto(%d)", camerasrc->fps_auto); + } else if (camerasrc->high_speed_fps <= 0) { + if (camerasrc->fps <= 0) { + /*if fps is zero, auto fps mode*/ + frac.numerator = 0; + frac.denominator = 1; + } else { + frac.numerator = 1; + frac.denominator = camerasrc->fps; + } + } else { + GST_INFO_OBJECT(camerasrc, "high speed recording(%d)", camerasrc->high_speed_fps); + frac.numerator = 1; + frac.denominator = camerasrc->high_speed_fps; + } + + ret = camerasrc_set_timeperframe(camerasrc->v4l2_handle, &frac); + if (ret != CAMERASRC_SUCCESS) { + GST_ERROR_OBJECT(camerasrc, "camerasrc_set_timeperframe() failed. errcode = 0x%x", ret); + goto _ERROR; + } + GST_INFO_OBJECT (camerasrc, "camerasrc_set_timeperframe() done"); + + camerasrc->buffer_running = TRUE; + + if ((camerasrc->use_pad_alloc == FALSE)) { + /*CAMERASRC CAM: Set Sensor mode*/ + camerasrc_set_sensor_mode(camerasrc->v4l2_handle, camerasrc->sensor_mode); + + /*CAMERASRC CAM: Set flip*/ + camerasrc_set_vflip(camerasrc->v4l2_handle, camerasrc->vflip); + camerasrc_set_hflip(camerasrc->v4l2_handle, camerasrc->hflip); + + /*CAMERASRC CAM: start video preview*/ + __ta__(" camerasrc_start_preview_stream", + ret = camerasrc_start_preview_stream(camerasrc->v4l2_handle); + ); + if (ret != CAMERASRC_SUCCESS) { + GST_ERROR_OBJECT(camerasrc, "camerasrc_start_preview_stream() failed. errcode = 0x%x", ret); + camerasrc->buffer_running = FALSE; + goto _ERROR; + } + + GST_INFO_OBJECT(camerasrc, "camerasrc_start_preview_stream() done"); + + ret = camerasrc_get_num_buffer(camerasrc->v4l2_handle, &(camerasrc->buffer_count)); + if (ret != CAMERASRC_SUCCESS) { + GST_ERROR_OBJECT(camerasrc, "camerasrc_get_num_buffer() failed. errcode = 0x%x", ret); + goto _ERROR; + } + + GST_INFO_OBJECT(camerasrc, "buffer number %d", camerasrc->buffer_count); +#ifdef _SPEED_UP_RAW_CAPTURE + camerasrc->cap_stream_diff = FALSE; +#endif + } + +#ifdef _SPEED_UP_RAW_CAPTURE +_READY_DONE: +#endif + camerasrc->mode = VIDEO_IN_MODE_PREVIEW; + camerasrc->current_buffer_data_index = (camerasrc->current_buffer_data_index + 1)%10; + + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + + return TRUE; + +_ERROR: + gst_camerasrc_error_handler(camerasrc, ret); + + /* Stop stream */ + camerasrc_stop_stream(camerasrc->v4l2_handle); + + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + + return FALSE; +} + + +static gboolean gst_camerasrc_stop(GstCameraSrc *camerasrc) +{ + camerasrc_io_method_t io_method; + + GST_DEBUG_OBJECT (camerasrc, "ENTERED"); + + if (camerasrc->v4l2_handle) { + /* CAMERASRC CAM: stop stream */ + /* To guarantee buffers are valid before finishing */ + GMutex *lock_mutex = NULL; + + if (camerasrc->use_pad_alloc == FALSE) { + lock_mutex = camerasrc->buffer_lock; + } else { + lock_mutex = camerasrc->pad_alloc_mutex; + } + + g_mutex_lock(lock_mutex); + while (camerasrc->num_live_buffers > _DEFAULT_KEEPING_BUFFER) { + GTimeVal abstimeout; + GST_INFO_OBJECT(camerasrc, "Wait until all live buffers are relased. (Tot=%d, Live=%d)", + camerasrc->buffer_count, camerasrc->num_live_buffers); + + g_get_current_time(&abstimeout); + g_time_val_add(&abstimeout, _PREVIEW_BUFFER_WAIT_TIMEOUT); + + if (!g_cond_timed_wait(camerasrc->buffer_cond, lock_mutex, &abstimeout)) { + GST_ERROR_OBJECT(camerasrc, "Buffer wait timeout[%d usec].(Live=%d) Skip waiting...", + _PREVIEW_BUFFER_WAIT_TIMEOUT, camerasrc->num_live_buffers); + gst_camerasrc_buffer_trace(camerasrc); + break; + } else { + GST_INFO_OBJECT(camerasrc, "Signal received."); + } + } + g_mutex_unlock(lock_mutex); + GST_INFO_OBJECT(camerasrc, "Waiting free buffer finished. (Live=%d)", camerasrc->num_live_buffers); + + camerasrc_stop_stream(camerasrc->v4l2_handle); + + camerasrc->buffer_running = FALSE; + camerasrc->mode = VIDEO_IN_MODE_UNKNOWN; + + /* If I/O method is Usrptr, it uses usr_buffer that is member of camerasrc structure */ + /* It must be unreffed when it stops */ + + camerasrc_get_io_method(camerasrc->v4l2_handle, &io_method); + switch (io_method) { + case CAMERASRC_IO_METHOD_MMAP: + break; + case CAMERASRC_IO_METHOD_USRPTR: + if (g_present_buf.present_buffer) { + free(g_present_buf.present_buffer); + g_present_buf.present_buffer = NULL; + } + break; + case CAMERASRC_IO_METHOD_READ: + default: + break; + } + } + + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + + return TRUE; +} + + +static gboolean gst_camerasrc_capture_start(GstCameraSrc *camerasrc) +{ + /*CAMERASRC CAM*/ + int ret = 0; + char *pfourcc = NULL; + camerasrc_format_t fmt; + camerasrc_frac_t frac; + + GST_INFO_OBJECT(camerasrc, "ENTERED"); + + if (camerasrc->mode == VIDEO_IN_MODE_PREVIEW) { + /* To guarantee buffers are valid before finishing. */ + __ta__( " wait for buffer in gst_camerasrc_capture_start", + if (camerasrc->use_pad_alloc == FALSE) { + g_mutex_lock(camerasrc->buffer_lock); + while (camerasrc->num_live_buffers > _DEFAULT_KEEPING_BUFFER) { + GTimeVal abstimeout; + GST_INFO_OBJECT(camerasrc, "Wait until all live buffers are relased. (Tot=%d, Live=%d)", + camerasrc->buffer_count, camerasrc->num_live_buffers); + + g_get_current_time(&abstimeout); + g_time_val_add(&abstimeout, _PREVIEW_BUFFER_WAIT_TIMEOUT); + + if (!g_cond_timed_wait(camerasrc->buffer_cond, camerasrc->buffer_lock, &abstimeout)) { + GST_ERROR_OBJECT(camerasrc, "Buffer wait timeout[%d usec].(Live=%d) Skip waiting...", + _PREVIEW_BUFFER_WAIT_TIMEOUT, camerasrc->num_live_buffers); + gst_camerasrc_buffer_trace(camerasrc); + break; + } else { + GST_INFO_OBJECT(camerasrc, "Signal received."); + } + } + g_mutex_unlock(camerasrc->buffer_lock); + GST_INFO_OBJECT(camerasrc, "Waiting free buffer is finished. (Live=%d)", camerasrc->num_live_buffers); + } + ); + +#ifdef _SPEED_UP_RAW_CAPTURE + /* Skip restart stream if format/width/height are all same */ + if (camerasrc->fourcc == camerasrc->cap_fourcc && + camerasrc->width == camerasrc->cap_width && + camerasrc->height == camerasrc->cap_height) { + GST_INFO_OBJECT(camerasrc, "fourcc, width and height is same. Skip restarting stream."); + goto _CAPTURE_READY_DONE; + } + + camerasrc->cap_stream_diff = TRUE; +#endif + + /*CAMERASRC CAM: stop stream*/ + __ta__( " camerasrc_stop_stream in gst_camerasrc_capture_start", + camerasrc_stop_stream(camerasrc->v4l2_handle); + ); + + GST_INFO_OBJECT (camerasrc, "camerasrc_stop_stream() done"); + camerasrc->buffer_running = FALSE; + + pfourcc = (char*)&camerasrc->cap_fourcc; + GST_INFO_OBJECT(camerasrc, "CAPTURE: Size[%dx%d], fourcc(%c%c%c%c) quality[%d] interval[%d] count[%d]", + camerasrc->cap_width, camerasrc->cap_height, + pfourcc[0], pfourcc[1], pfourcc[2], pfourcc[3], + camerasrc->cap_quality, camerasrc->cap_interval, camerasrc->cap_count); + + /*START STILL CAPTURE*/ + + /*set current video info*/ + + memset(&fmt, 0x00, sizeof (camerasrc_format_t)); + + /*CAMERASRC CAM: set format*/ + CAMERASRC_SET_SIZE_BY_DIMENSION(fmt, camerasrc->cap_width, camerasrc->cap_height); + + _gst_camerasrc_get_raw_pixel_info(camerasrc->cap_fourcc, &(fmt.pix_format), &(fmt.colorspace)); + fmt.rotation = 0; + + if (camerasrc->cap_fourcc == GST_MAKE_FOURCC('J', 'P', 'E', 'G') || + camerasrc->cap_fourcc == GST_MAKE_FOURCC('j', 'p', 'e', 'g')) { + fmt.quality = camerasrc->cap_jpg_quality; + fmt.is_highquality_mode = camerasrc->cap_quality; /*must be 1*/ + } else { + fmt.is_highquality_mode = camerasrc->cap_quality; /*0 or 1 (default: 0)*/ + } + + /*CAMERASRC CAM: format*/ + ret = camerasrc_set_format(camerasrc->v4l2_handle, &fmt); + if (ret != CAMERASRC_SUCCESS) { + GST_ERROR_OBJECT(camerasrc, "camerasrc_set_format() failed. errcode = 0x%x", ret); + goto _ERROR; + } + GST_INFO_OBJECT(camerasrc, "camerasrc_set_format() done"); + + if (camerasrc->fps_auto || camerasrc->fps <= 0) { + /*if fps is zero, auto fps mode*/ + frac.numerator = 0; + frac.denominator = 1; + GST_INFO_OBJECT (camerasrc, "FPS auto"); + } else { + frac.numerator = 1; + frac.denominator = camerasrc->fps; + GST_INFO_OBJECT (camerasrc, "FPS (%d)", camerasrc->fps); + } + + ret = camerasrc_set_timeperframe(camerasrc->v4l2_handle, &frac); + if (ret != CAMERASRC_SUCCESS) { + GST_ERROR_OBJECT(camerasrc, "camerasrc_set_timeperframe() failed. errcode = 0x%x", ret); + goto _ERROR; + } + GST_INFO_OBJECT (camerasrc, "camerasrc_set_timeperframe() done"); + + /*CAMERASRC CAM: start stream*/ + __ta__( " camerasrc_start_still_stream", + ret = camerasrc_start_still_stream(camerasrc->v4l2_handle); + ); + if (ret != CAMERASRC_SUCCESS) { + GST_ERROR_OBJECT(camerasrc, "camerasrc_start_still_stream() failed. errcode = 0x%x", ret); + goto _ERROR; + } + GST_INFO_OBJECT(camerasrc, "camerasrc_start_still_stream() done"); + + camerasrc->buffer_running = TRUE; + + /*CAMERASRC CAM: set fps*/ + /*TODO: maybe do not works!*/ + +#ifdef _SPEED_UP_RAW_CAPTURE +_CAPTURE_READY_DONE: +#endif + + g_mutex_lock(camerasrc->jpg_mutex); + camerasrc->cap_next_time = 0UL; + g_mutex_unlock(camerasrc->jpg_mutex); + camerasrc->cap_count_current = 0; + + /* end change to capture mode*/ + camerasrc->mode = VIDEO_IN_MODE_CAPTURE; + + GST_INFO_OBJECT(camerasrc, "CAPTURE STARTED!"); + } else { + GST_WARNING_OBJECT(camerasrc, "Wrong state[%d]!", camerasrc->mode); + } + + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + + return TRUE; + +_ERROR: + gst_camerasrc_error_handler(camerasrc, ret); + + return FALSE; +} + + +static gboolean gst_camerasrc_capture_stop(GstCameraSrc *camerasrc) +{ + GST_DEBUG_OBJECT(camerasrc, "ENTERED"); + + if (camerasrc->mode == VIDEO_IN_MODE_CAPTURE) { +#ifdef _SPEED_UP_RAW_CAPTURE + if (camerasrc->cap_stream_diff) { + /*CAMERASRC CAM: stop stream*/ + camerasrc_stop_stream(camerasrc->v4l2_handle); + camerasrc->buffer_running = FALSE; + + GST_INFO_OBJECT(camerasrc, "camerasrc_stop_stream() done"); + } else { + GST_INFO_OBJECT(camerasrc, "no need to stop stream(capture format==preview format)"); + } +#else + /*CAMERASRC CAM: stop stream*/ + camerasrc_stop_stream(camerasrc->v4l2_handle); + camerasrc->buffer_running = FALSE; + + GST_INFO_OBJECT(camerasrc, "camerasrc_stop_stream() done"); +#endif + GST_INFO_OBJECT(camerasrc, "CAPTURE STOPPED!"); + } + + GST_DEBUG_OBJECT (camerasrc, "LEAVED"); + + return TRUE; +} + + +static GstFlowReturn gst_camerasrc_read_preview_mmap(GstCameraSrc *camerasrc, GstBuffer **buffer) +{ + int ret = 0; + int v4l2_buffer_index = 0; + guint i = 0; + unsigned int isize = 0; + unsigned char *pData = NULL; + void *buf = NULL; + camerasrc_buffer_t main_buf; + GstCameraBuffer *vid_buf = NULL; + + /*alloc main buffer*/ + vid_buf = gst_camerasrc_buffer_new(camerasrc); + buf = (GstCameraBuffer *)vid_buf; + + g_mutex_lock(camerasrc->buffer_lock); + GST_LOG_OBJECT(camerasrc, "After lock(buffer live %d, total %d)", + camerasrc->num_live_buffers, camerasrc->buffer_count); + + for (i = 0 ; i < _MAX_TRIAL_WAIT_FRAME ; i++) { + /* Wait frame */ + __ta__( " camerasrc_wait_frame_available", + ret = camerasrc_wait_frame_available(camerasrc->v4l2_handle, _DEFAULT_DEQUE_WAITINGTIME); + ); + if (ret != CAMERASRC_SUCCESS) { + if (ret == CAMERASRC_ERR_DEVICE_WAIT_TIMEOUT && i < (_MAX_TRIAL_WAIT_FRAME - 1)) { + GST_ERROR_OBJECT(camerasrc, "SELECT TIMEOUT!!! Retry..(pad_alloc %d, live %d)", + camerasrc->use_pad_alloc, camerasrc->num_live_buffers); + continue; + } + + if (ret == CAMERASRC_ERR_DEVICE_UNAVAILABLE) { + GST_ERROR_OBJECT(camerasrc, "register trouble error!! [%x]", ret); + /*g_signal_emit (G_OBJECT (camerasrc), gst_camerasrc_signals[SIGNAL_REGISTER_TROUBLE], (GQuark)NULL);*/ + g_mutex_unlock(camerasrc->buffer_lock); + gst_camerasrc_error_handler(camerasrc, ret); + + return GST_FLOW_ERROR; + } else if (ret == CAMERASRC_ERR_INVALID_STATE && (i < _MAX_TRIAL_WAIT_FRAME - 1)) { + GST_WARNING_OBJECT(camerasrc, "try again..."); + } else { + GST_ERROR_OBJECT(camerasrc, "Frame waiting error[%x]", ret); + g_mutex_unlock(camerasrc->buffer_lock); + gst_camerasrc_error_handler(camerasrc, ret); + + return GST_FLOW_ERROR; + } + } else { + GST_LOG_OBJECT(camerasrc, "select success, do DQBUF"); + break; + } + } + + /* Buffer DQ */ + __ta__( " camerasrc_dequeue_buffer", + ret = camerasrc_dequeue_buffer(camerasrc->v4l2_handle, &v4l2_buffer_index, &main_buf, NULL); + ); + if (ret != CAMERASRC_SUCCESS) { + GST_ERROR_OBJECT(camerasrc, "Dequeue frame error[%x]", ret); + g_mutex_unlock(camerasrc->buffer_lock); + gst_camerasrc_error_handler(camerasrc, ret); + + return GST_FLOW_ERROR; + } + + camerasrc->num_live_buffers++; + GST_LOG_OBJECT (camerasrc, "after : DQBUF (index %d, live bufs %d)", + v4l2_buffer_index, camerasrc->num_live_buffers); + + g_mutex_unlock (camerasrc->buffer_lock); + + if (camerasrc->fourcc == GST_MAKE_FOURCC('S','N','1','2') || + camerasrc->fourcc == GST_MAKE_FOURCC('S','T','1','2') || + camerasrc->fourcc == GST_MAKE_FOURCC('S','U','Y','V') || + camerasrc->fourcc == GST_MAKE_FOURCC('S','U','Y','2') || + camerasrc->fourcc == GST_MAKE_FOURCC('S','Y','V','Y') || + camerasrc->fourcc == GST_MAKE_FOURCC('S','4','2','0')) { + /* for physical address */ + GST_BUFFER_MALLOCDATA(vid_buf) = gst_camerasrc_make_metadata_for_nonlinear_buffer(camerasrc, v4l2_buffer_index); + + /* for virtual address - GST_BUFFER_DATA and SIZE */ + pData = main_buf.start; + isize = main_buf.length; + } else if (camerasrc->fourcc == GST_MAKE_FOURCC('I','4','2','0') || + camerasrc->fourcc == GST_MAKE_FOURCC('N','V','1','2')) { + ret = _gst_camerasrc_get_normal_buffer(camerasrc, camerasrc->fourcc, + main_buf.start, camerasrc->width, camerasrc->height, + &pData, &isize); + if (ret == FALSE) { + g_mutex_unlock( camerasrc->buffer_lock ); + return GST_FLOW_ERROR; + } + + vid_buf->is_alloc_data = TRUE; + } else { + pData = main_buf.start; + isize = main_buf.length; + } + + GST_BUFFER_DATA(vid_buf) = pData; + GST_BUFFER_SIZE(vid_buf) = isize; + vid_buf->v4l2_buffer_index = v4l2_buffer_index; + + if (camerasrc->firsttime) { + /** Because of basesrc negotiation , "framerate" field is needed. */ + int fps_nu = 0; + int fps_de = 0; + int af_mode = CAMERASRC_AF_MODE_AUTO; + int af_range = CAMERASRC_AF_RANGE_NORMAL; + gchar *caps_string = NULL; + GstCaps *caps = NULL; + + if (camerasrc->fps <= 0) { + /*if fps is zero, auto fps mode*/ + fps_nu = 0; + fps_de = 1; + } else { + fps_nu = 1; + fps_de = camerasrc->fps; + } + + GST_INFO_OBJECT(camerasrc, "FPS auto[%d], FPS[%d], High speed FPS[%d]", + camerasrc->fps_auto, camerasrc->fps, camerasrc->high_speed_fps); + + caps = gst_caps_new_simple("video/x-raw-yuv", + "format", GST_TYPE_FOURCC, camerasrc->fourcc, + "width", G_TYPE_INT, camerasrc->width, + "height", G_TYPE_INT, camerasrc->height, + "framerate", GST_TYPE_FRACTION, fps_de, fps_nu, + NULL); + if (caps == NULL) { + GST_ERROR_OBJECT(camerasrc, "failed to alloc caps"); + gst_buffer_unref((GstBuffer *)vid_buf); + vid_buf = NULL; + buf = NULL; + return GST_FLOW_ERROR; + } + + if (camerasrc->use_rotate_caps) { + gst_caps_set_simple(caps, "rotate", G_TYPE_INT, camerasrc->rotate, NULL); + } + + GST_BUFFER_CAPS(buf) = caps; + + caps_string = gst_caps_to_string(caps); + GST_INFO_OBJECT(camerasrc, "PREVIEW MODE first time [%dx%d], rotate[%d], caps[%s]", + camerasrc->width, camerasrc->height, camerasrc->rotate, caps_string); + if (caps_string) { + g_free(caps_string); + caps_string = NULL; + } + + if (camerasrc->fourcc == GST_MAKE_FOURCC('N','V','1','2') || + camerasrc->fourcc == GST_MAKE_FOURCC('S','N','1','2')) { + /* Start Focusing when Continuous AF */ + camerasrc_get_autofocusing_mode(camerasrc->v4l2_handle, &af_mode, &af_range); + if (af_mode == CAMERASRC_AF_MODE_CONTINUOUS) { + GST_INFO_OBJECT(camerasrc, "This is (NV12 or SN12) and Continuous AF mode. Start AF"); + camerasrc_start_autofocusing(camerasrc->v4l2_handle); + } + } + + camerasrc->firsttime = FALSE; + } + + gst_camerasrc_get_timeinfo(camerasrc, (GstBuffer*)vid_buf); + + *buffer = (GstBuffer*)vid_buf; + + /*GST_DEBUG_OBJECT(camerasrc, "refcount: %d", GST_OBJECT_REFCOUNT(*buffer));*/ + +#if _ENABLE_CAMERASRC_DEBUG + g_preview_frame_cnt++; +#endif + + return GST_FLOW_OK; +} + + +static GstFlowReturn gst_camerasrc_read_preview_pad_alloc(GstCameraSrc *camerasrc, GstBuffer **buffer) +{ + int ret = 0; + int v4l2_buffer_index = 0; + int is_esd = 0; + guint cnt_again = _MAX_PAD_ALLOC_RETRY_COUNT; + void *buf = NULL; + camerasrc_buffer_t main_buf; + GstBuffer *gst_buf = NULL; + GST_CAMERASRC_BUFFER_DATA *buffer_data = NULL; + + /*alloc main buffer*/ + gst_buf = *buffer; + buf = (GstBuffer *)gst_buf; + + g_mutex_lock(camerasrc->buffer_lock); + GST_LOG_OBJECT(camerasrc, "After lock(lvn %d, buf cnt %d)", camerasrc->num_live_buffers, camerasrc->buffer_count); + +AGAIN: + g_mutex_lock (camerasrc->pad_alloc_mutex); + while (!g_queue_is_empty(camerasrc->pad_alloc_list) && !camerasrc->first_invokation) { + int pad_alloc_index = -1; + int proper_index = -1; + camerasrc_buffer_t camerasrc_buffer; + GstBuffer *pad_alloc_buffer; + GstCaps *negotiated_caps = NULL; + + g_mutex_unlock (camerasrc->pad_alloc_mutex); + + camerasrc_buffer.start = NULL; + camerasrc_buffer.length = 0; + + g_mutex_lock (camerasrc->pad_alloc_mutex); + pad_alloc_index = (int)g_queue_pop_head(camerasrc->pad_alloc_list); + g_mutex_unlock (camerasrc->pad_alloc_mutex); + sched_yield(); + GST_LOG_OBJECT (camerasrc, "Index queue have item. pad_alloc_index = %d", pad_alloc_index); + + negotiated_caps = gst_pad_get_negotiated_caps (GST_BASE_SRC_PAD (camerasrc)); + + /* pad allocation from sink(or any where) */ + ret = gst_pad_alloc_buffer(GST_BASE_SRC_PAD (camerasrc), + 0, + camerasrc->main_buf_sz, + negotiated_caps, + &pad_alloc_buffer); + if (ret != GST_FLOW_OK) { + GST_ERROR_OBJECT(camerasrc, "Pad alloc fail, ret = [%d]", ret); + g_cond_signal(camerasrc->buffer_cond); + g_mutex_unlock(camerasrc->buffer_lock); + gst_caps_unref(negotiated_caps); + + return ret; + } + + proper_index = get_proper_index(camerasrc, pad_alloc_buffer); + if (proper_index == -1) { + GST_INFO_OBJECT(camerasrc, "Proper index doesn't exist"); + g_mutex_unlock(camerasrc->buffer_lock); + + return GST_FLOW_ERROR; + } + + if (proper_index != pad_alloc_index) { + GST_LOG_OBJECT(camerasrc, "Proper index different from pad_alloc_index, proper_index = %d, pad_alloc_index = %d", + proper_index, pad_alloc_index); + } + + GST_LOG_OBJECT(camerasrc, "gst_pad_alloc_buffer called. index = %d, GstBuffer address = %p", + proper_index, &(camerasrc->usr_buffer[pad_alloc_index])); + + camerasrc->usr_buffer[proper_index] = pad_alloc_buffer; + + camerasrc_buffer.start = GST_BUFFER_DATA(GST_BUFFER(camerasrc->usr_buffer[proper_index])); + camerasrc_buffer.length = GST_BUFFER_SIZE(GST_BUFFER(camerasrc->usr_buffer[proper_index])); + + camerasrc_buffer.length = PAGE_ALIGN(camerasrc_buffer.length); + + if (!camerasrc_buffer.start) { + GST_ERROR_OBJECT(camerasrc, "Data for queueing is not available one, data = %p", camerasrc_buffer.start); + g_cond_signal(camerasrc->buffer_cond); + g_mutex_unlock(camerasrc->buffer_lock); + + return GST_FLOW_ERROR; + } + + if (camerasrc_buffer.length <= 0) { + GST_ERROR_OBJECT(camerasrc, "Length for queueing is not available one, data = %d", camerasrc_buffer.length); + g_cond_signal(camerasrc->buffer_cond); + g_mutex_unlock(camerasrc->buffer_lock); + + return GST_FLOW_ERROR; + } + + ret = camerasrc_queue_buffer(camerasrc->v4l2_handle, proper_index, &camerasrc_buffer); + if (ret != CAMERASRC_SUCCESS) { + GST_ERROR_OBJECT(camerasrc, "Queue frame error, [%x]", ret); + g_cond_signal(camerasrc->buffer_cond); + g_mutex_unlock(camerasrc->buffer_lock); + gst_caps_unref(negotiated_caps); + + return GST_FLOW_ERROR; + } + + gst_caps_unref(negotiated_caps); + + g_cond_signal(camerasrc->buffer_cond); + GST_LOG_OBJECT(camerasrc, "QBUF : [idx=%d, lvn=%d]", proper_index, camerasrc->num_live_buffers); + g_mutex_lock(camerasrc->pad_alloc_mutex); + } + + g_mutex_unlock(camerasrc->pad_alloc_mutex); + + ret = camerasrc_wait_frame_available(camerasrc->v4l2_handle, _PAD_ALLOC_RETRY_PERIOD); + if (ret == CAMERASRC_ERR_DEVICE_WAIT_TIMEOUT) { + if (cnt_again--) { + if ((cnt_again % 100) == 0) { + GST_LOG_OBJECT (camerasrc, "Check ESD......"); + + is_esd = 0; + ret = camerasrc_check_esd_shock(camerasrc->v4l2_handle, &is_esd); + if (is_esd) { + /* ESD situation */ + GST_LOG_OBJECT(camerasrc, "ESD situation. device reset preview"); + GST_LOG_OBJECT(camerasrc, "register trouble error!! [%x]", CAMERASRC_ERR_DEVICE_UNAVAILABLE); + g_mutex_unlock(camerasrc->buffer_lock); + + gst_camerasrc_error_handler(camerasrc, CAMERASRC_ERR_DEVICE_UNAVAILABLE); + + return GST_FLOW_ERROR; + } + } + goto AGAIN; + } else { + GST_LOG_OBJECT (camerasrc, "Check ESD......"); + + is_esd = 0; + ret = camerasrc_check_esd_shock(camerasrc->v4l2_handle, &is_esd); + if (!is_esd) { + /* Not ESD situation */ + GST_LOG_OBJECT(camerasrc, "Not ESD situation. normal timeout"); + g_mutex_unlock(camerasrc->buffer_lock); + + gst_camerasrc_error_handler(camerasrc, CAMERASRC_ERR_DEVICE_WAIT_TIMEOUT); + + return GST_FLOW_WRONG_STATE; + } else { + /* ESD situation */ + GST_LOG_OBJECT(camerasrc, "ESD situation. device reset preview"); + GST_LOG_OBJECT(camerasrc, "register trouble error!! [%x]", CAMERASRC_ERR_DEVICE_UNAVAILABLE); + g_mutex_unlock(camerasrc->buffer_lock); + + gst_camerasrc_error_handler(camerasrc, CAMERASRC_ERR_DEVICE_UNAVAILABLE); + + return GST_FLOW_ERROR; + } + + GST_ERROR_OBJECT(camerasrc, "Time out retried [%d] times %d", _MAX_PAD_ALLOC_RETRY_COUNT - cnt_again + 1); + } + } else if (ret != CAMERASRC_SUCCESS) { + g_mutex_unlock(camerasrc->buffer_lock); + GST_ERROR_OBJECT(camerasrc, "camerasrc_wait_frame_available error [%x]", ret); + + return GST_FLOW_ERROR; + } + + /* Buffer DQ */ + __ta__( " camerasrc_dequeue_buffer", + ret = camerasrc_dequeue_buffer(camerasrc->v4l2_handle, &v4l2_buffer_index, &main_buf, NULL); + ); + if (ret != CAMERASRC_SUCCESS) { + GST_ERROR_OBJECT(camerasrc, "Dequeue frame error, [%x]", ret); + g_mutex_unlock(camerasrc->buffer_lock); + gst_camerasrc_error_handler(camerasrc, ret); + + return GST_FLOW_ERROR; + } + + camerasrc->num_live_buffers++; + GST_LOG_OBJECT(camerasrc, "after : DQBUF (index %d, live number %d)", + v4l2_buffer_index, camerasrc->num_live_buffers); + g_mutex_unlock(camerasrc->buffer_lock); + + /* For camera state stopped */ + gst_buf = camerasrc->usr_buffer[v4l2_buffer_index]; + if (gst_buf == NULL) { + GST_ERROR_OBJECT(camerasrc, "camerasrc->usr_buffer[v4l2_buffer_index] NULL"); + return GST_FLOW_WRONG_STATE; + } + + GST_LOG_OBJECT(camerasrc, "Start to set up buffer free structure"); + + buffer_data = g_malloc(sizeof(GST_CAMERASRC_BUFFER_DATA)); + if (buffer_data == NULL) { + GST_ERROR_OBJECT(camerasrc, "buffer_data NULL"); + return GST_FLOW_WRONG_STATE; + } + + buffer_data->camerasrc = camerasrc; + buffer_data->index = v4l2_buffer_index; + buffer_data->buffer_data_index = camerasrc->current_buffer_data_index; + + GST_BUFFER_DATA(gst_buf) = main_buf.start; + GST_BUFFER_SIZE(gst_buf) = main_buf.length; + GST_BUFFER_MALLOCDATA(gst_buf) = (guint8 *)buffer_data; + GST_BUFFER_FREE_FUNC(gst_buf) = gst_camerasrc_buffer_free; + + GST_LOG_OBJECT(camerasrc, "End to set up buffer free structure"); + + + if (camerasrc->firsttime) { + /* Because of basesrc negotiation , "framerate" field is needed. */ + int fps_nu = 0; + int fps_de = 0; + gchar *caps_string = NULL; + GstCaps *caps = NULL; + + if (camerasrc->fps <= 0) { + /*if fps is zero, auto fps mode*/ + fps_nu = 0; + fps_de = 1; + } else { + fps_nu = 1; + fps_de = camerasrc->fps; + } + + GST_INFO_OBJECT(camerasrc, "FPS auto[%d], FPS[%d], High speed FPS[%d]", + camerasrc->fps_auto, camerasrc->fps, camerasrc->high_speed_fps); + + caps = gst_caps_new_simple("video/x-raw-yuv", + "format", GST_TYPE_FOURCC, camerasrc->fourcc, + "width", G_TYPE_INT, camerasrc->width, + "height", G_TYPE_INT, camerasrc->height, + "framerate", GST_TYPE_FRACTION, fps_de, fps_nu, + NULL); + if (caps == NULL) { + GST_ERROR_OBJECT(camerasrc, "failed to alloc caps"); + return GST_FLOW_ERROR; + } + + if (camerasrc->use_rotate_caps) { + gst_caps_set_simple(caps, "rotate", G_TYPE_INT, camerasrc->rotate, NULL); + } + + GST_BUFFER_CAPS(gst_buf) = caps; + + caps_string = gst_caps_to_string(caps); + GST_INFO_OBJECT (camerasrc, "PREVIEW MODE first time [%dx%d], rotate[%d], caps[%s]", + camerasrc->width, camerasrc->height, camerasrc->rotate, caps_string); + if (caps_string) { + g_free(caps_string); + caps_string = NULL; + } + + camerasrc->firsttime = FALSE; + } + + gst_camerasrc_get_timeinfo(camerasrc, gst_buf); + + *buffer = gst_buf; + + g_mutex_lock (camerasrc->pad_alloc_mutex); + if (camerasrc->first_invokation) { + GST_INFO_OBJECT(camerasrc, "[DEBUG] Check something in pad_alloc_list"); + g_mutex_unlock (camerasrc->pad_alloc_mutex); + g_mutex_lock (camerasrc->pad_alloc_mutex); + + while (!g_queue_is_empty(camerasrc->pad_alloc_list)) { + g_mutex_unlock(camerasrc->pad_alloc_mutex); + g_mutex_lock(camerasrc->pad_alloc_mutex); + + /* Remove all item */ + + g_queue_pop_head(camerasrc->pad_alloc_list); + GST_INFO_OBJECT(camerasrc, "[DEBUG] Something is in pad_alloc_list before first frame. remove it!"); + + g_mutex_unlock(camerasrc->pad_alloc_mutex); + g_mutex_lock(camerasrc->pad_alloc_mutex); + } + + g_mutex_unlock(camerasrc->pad_alloc_mutex); + g_mutex_lock(camerasrc->pad_alloc_mutex); + camerasrc->first_invokation = FALSE; + } + g_mutex_unlock (camerasrc->pad_alloc_mutex); + +#if _ENABLE_CAMERASRC_DEBUG + g_preview_frame_cnt++; +#endif + + return GST_FLOW_OK; +} + + +static GstFlowReturn gst_camerasrc_draw_black_preview(GstCameraSrc *camerasrc, GstBuffer **buffer) +{ + int fps_nu = 0; + int fps_de = 0; + guint fakebuflen = 0; + GstBuffer *gst_buf = NULL; + + /*alloc main buffer*/ + if (camerasrc->fourcc == GST_MAKE_FOURCC('Y','U','Y','2')) { + fakebuflen = camerasrc->width * camerasrc->height * 2; + gst_buf = gst_buffer_new_and_alloc(fakebuflen); + GenerateYUV422BlackFrame(GST_BUFFER_MALLOCDATA(gst_buf), fakebuflen, camerasrc->width , camerasrc->height); + } else if (camerasrc->fourcc == GST_MAKE_FOURCC ('I','4','2','0') || + camerasrc->fourcc == GST_MAKE_FOURCC ('Y', 'U', '1', '2')) { + fakebuflen = camerasrc->width * camerasrc->height * 3 / 2; + gst_buf = gst_buffer_new_and_alloc(fakebuflen); + GenerateYUV420BlackFrame(GST_BUFFER_MALLOCDATA(gst_buf), fakebuflen, camerasrc->width , camerasrc->height); + } else { + GST_DEBUG_OBJECT(camerasrc, "Wrong fourcc(%x)", camerasrc->fourcc); + return GST_FLOW_OK; + } + + GST_DEBUG_OBJECT(camerasrc, "gst_camerasrc_draw_black_preview (data=%p, len=%d)", + GST_BUFFER_MALLOCDATA(gst_buf), fakebuflen); + /** + Because of basesrc negotiation , "framerate" field is needed. + */ + if (camerasrc->fps <= 0) { + /*if fps is zero, auto fps mod e*/ + fps_nu = 0; + fps_de = 1; + } else { + fps_nu = 1; + fps_de = camerasrc->fps; + } + + GST_INFO_OBJECT(camerasrc, "FPS auto[%d], FPS[%d], High speed FPS[%d]", + camerasrc->fps_auto, camerasrc->fps, camerasrc->high_speed_fps); + + GST_BUFFER_CAPS(gst_buf) = gst_caps_new_simple("video/x-raw-yuv", + "format", GST_TYPE_FOURCC, camerasrc->fourcc, + "width", G_TYPE_INT, camerasrc->width, + "height", G_TYPE_INT, camerasrc->height, + "framerate", GST_TYPE_FRACTION, fps_de, fps_nu, + NULL); + + GST_DEBUG_OBJECT(camerasrc, "PREVIEW MODE first time [%d] [%d]", camerasrc->width, camerasrc->height); + gst_camerasrc_get_timeinfo(camerasrc, gst_buf); + + *buffer = gst_buf; + return GST_FLOW_OK; +} + + +static GstFlowReturn gst_camerasrc_read_capture(GstCameraSrc *camerasrc, GstBuffer **buffer, int command) +{ + int ret; + int buffer_index = 0; + unsigned long cur_time; + gboolean is_jpeg = FALSE; + + static gboolean get_stop_command = FALSE; + static gboolean get_stop_multi_command = FALSE; + + GstCameraBuffer *buf = NULL; /*output buffer for preview*/ + GstBuffer *buf_cap_signal1 = NULL; /*output main buffer for capture signal*/ + GstBuffer *buf_cap_signal2 = NULL; /*output thumbnail buffer for capture signal*/ + GstBuffer *buf_cap_signal3 = NULL; /*output screennail buffer for capture signal*/ + + camerasrc_buffer_t main_buf = {0, NULL, 0}; /*original size buffer*/ + camerasrc_buffer_t thumb_buf = {0, NULL, 0}; /*thumbnail size buffer*/ + camerasrc_buffer_t scrnl_buf = {0, NULL, 0}; /*screennail size buffer*/ + + GST_DEBUG_OBJECT(camerasrc, "ENTERED. Command[%d]", command); + + GST_INFO_OBJECT(camerasrc, "src size[%dx%d], capture size[%dx%d]", + camerasrc->width, camerasrc->height, + camerasrc->cap_width, camerasrc->cap_height ); + + if (command == GST_CAMERA_CONTROL_CAPTURE_COMMAND_STOP) { + get_stop_command = TRUE; + } else if (command == GST_CAMERA_CONTROL_CAPTURE_COMMAND_STOP_MULTISHOT) { + get_stop_multi_command = TRUE; + } + + GST_INFO_OBJECT(camerasrc, "cnt current:%d, reverse:%d, stop cmd:%d, multi stop cmd:%d", + camerasrc->cap_count_reverse, camerasrc->cap_count_current, + get_stop_command, get_stop_multi_command); + + while (TRUE) { + if (camerasrc->cap_count_reverse == 0 || + ((get_stop_command || get_stop_multi_command) && + camerasrc->cap_count_current != 0 )) { + g_mutex_lock(camerasrc->mutex); + + GST_INFO_OBJECT(camerasrc, "Capture finished."); + + __ta__( " capture: gst_camerasrc_capture_stop", + gst_camerasrc_capture_stop(camerasrc); + ); + if (get_stop_command == FALSE) { + if (!g_queue_is_empty(camerasrc->command_list)) { + command = (int)g_queue_pop_head(camerasrc->command_list); + GST_INFO_OBJECT(camerasrc, "Pop command [%d]", command); + if (command == GST_CAMERA_CONTROL_CAPTURE_COMMAND_STOP) { + get_stop_command = TRUE; + } + } + + if (get_stop_command == FALSE) { + GST_INFO_OBJECT(camerasrc, "Start : Wait for Capture stop signal"); + __ta__( " capture: wait for cond after image capture", + g_cond_wait(camerasrc->cond, camerasrc->mutex); + ); + GST_INFO_OBJECT(camerasrc, "End : Wait for Capture stop signal"); + } + } + + __ta__(" capture: gst_camerasrc_start", + gst_camerasrc_start(camerasrc); + ); + + __ta__(" capture: one gst_camerasrc_read_preview_mmap", + ret = gst_camerasrc_read_preview_mmap(camerasrc, buffer); + ); + + get_stop_command = FALSE; + get_stop_multi_command = FALSE; + + g_mutex_unlock(camerasrc->mutex); + + MMTA_ACUM_ITEM_END( " Shot to Shot in gstcamerasrc", FALSE); + + return ret; + } + + if (camerasrc->cap_fourcc == GST_MAKE_FOURCC('J','P','E','G') || + camerasrc->cap_fourcc == GST_MAKE_FOURCC('j','p','e','g')) { + is_jpeg = TRUE; + } else { + is_jpeg = FALSE; + } + + /** + *@important JPEG still: always same image generated by camerasrc_read_frame. + * if you want to multi shot, set YUV format ! + */ + __ta__(" camerasrc_read_frame:select,DQ,Copy,Q", + ret = camerasrc_read_frame(camerasrc->v4l2_handle, &main_buf, &thumb_buf, &buffer_index); + ); + if (ret != CAMERASRC_SUCCESS) { + if (ret == CAMERASRC_ERR_DEVICE_UNAVAILABLE) { + GST_ERROR_OBJECT (camerasrc, "Video src device return register trouble error!! [%x]", ret); + /*g_signal_emit (G_OBJECT (camerasrc), gst_camerasrc_signals[SIGNAL_REGISTER_TROUBLE], (GQuark)NULL);*/ + gst_camerasrc_error_handler(camerasrc, ret); + return GST_FLOW_ERROR; + } else { + GST_ERROR_OBJECT (camerasrc, "camerasrc_read_frame() failed. [ret = 0x%08X]", ret); + GST_ERROR_OBJECT (camerasrc, "return GST_FLOW_ERROR"); + /* should stop capture; */ + /*retrun EOS*/ + *buffer = NULL; + gst_camerasrc_error_handler(camerasrc, ret); + + return GST_FLOW_ERROR; + } + } + + /* Get screennail buffer */ + scrnl_buf.start = NULL; + scrnl_buf.length = 0; + camerasrc_get_screennail_buffer(camerasrc->v4l2_handle, &scrnl_buf); + + GST_INFO_OBJECT(camerasrc, "main(%p,%d), thumb(%p,%d), scrnl(%p,%d)", + main_buf.start, main_buf.length, + thumb_buf.start, thumb_buf.length, + scrnl_buf.start, scrnl_buf.length); + +CHECK_CAPTURE_INTERVAL: + /* get shot time */ + cur_time = gst_get_current_time(); + + if (camerasrc->cap_next_time == 0UL) { + camerasrc->cap_next_time = cur_time; + } + + if (camerasrc->cap_count_reverse > 0 && camerasrc->cap_next_time <= cur_time) { + GST_INFO_OBJECT(camerasrc, "CHECK: reverse capture count: %d, next time:%lu current time:%lu", + camerasrc->cap_count_reverse, camerasrc->cap_next_time, cur_time); + + camerasrc->cap_next_time = cur_time + camerasrc->cap_interval; + camerasrc->cap_count_reverse--; + camerasrc->cap_count_current++; + + /* alloc buffer for capture callback */ + buf_cap_signal1 = gst_buffer_new (); + + /* make buffers for capture callback and display(raw format) */ + if (is_jpeg) { + GST_INFO_OBJECT (camerasrc, "JPEG CAPTURE MODE"); + + GST_BUFFER_DATA(buf_cap_signal1) = main_buf.start; + GST_BUFFER_SIZE(buf_cap_signal1) = main_buf.length; + GST_BUFFER_CAPS(buf_cap_signal1) = gst_caps_new_simple("image/jpeg", + "width", G_TYPE_INT, camerasrc->cap_width, + "height", G_TYPE_INT, camerasrc->cap_height, + NULL); + + if (thumb_buf.start) { + buf_cap_signal2 = gst_buffer_new(); + GST_BUFFER_DATA(buf_cap_signal2) = thumb_buf.start; + GST_BUFFER_SIZE(buf_cap_signal2) = thumb_buf.length; + GST_BUFFER_CAPS(buf_cap_signal2) = gst_caps_new_simple("image/jpeg", + "width", G_TYPE_INT, _THUMBNAIL_WIDTH, + "height", G_TYPE_INT, _THUMBNAIL_HEIGHT, + NULL); + } else { + buf_cap_signal2 = NULL; + } + + if (scrnl_buf.start && scrnl_buf.length > 0) { + buf_cap_signal3 = gst_buffer_new(); + GST_BUFFER_DATA(buf_cap_signal3) = scrnl_buf.start; + GST_BUFFER_SIZE(buf_cap_signal3) = scrnl_buf.length; + GST_BUFFER_CAPS(buf_cap_signal3) = gst_caps_new_simple("video/x-raw-yuv", + "format", GST_TYPE_FOURCC, _DEFAULT_SCRNL_FOURCC, + "width", G_TYPE_INT, camerasrc->width, + "height", G_TYPE_INT, camerasrc->height, + NULL); + } else { + buf_cap_signal3 = NULL; + } + + *buffer = NULL; + } else { + unsigned char *pMetaData = NULL; + + GST_INFO_OBJECT (camerasrc, "RAW CAPTURE MODE"); + + /*alloc main buffer*/ + buf = gst_camerasrc_buffer_new(camerasrc);; + if (buf == NULL) { + GST_ERROR_OBJECT(camerasrc, "Buffer alloc failed."); + *buffer = NULL; + gst_camerasrc_error_handler(camerasrc, CAMERASRC_ERR_ALLOCATION); + return GST_FLOW_ERROR; + } + + pMetaData = gst_camerasrc_make_metadata_for_nonlinear_buffer(camerasrc, buffer_index); + if (!pMetaData) { + GST_ERROR_OBJECT(camerasrc, "Error on making metadata"); + } + + GST_BUFFER_MALLOCDATA(buf) = pMetaData; + buf->v4l2_buffer_index = buffer_index; + + if (camerasrc->cap_fourcc == GST_MAKE_FOURCC('I','4','2','0') || + camerasrc->cap_fourcc == GST_MAKE_FOURCC('S','4','2','0') || + camerasrc->cap_fourcc == GST_MAKE_FOURCC('N','V','1','2') || + camerasrc->cap_fourcc == GST_MAKE_FOURCC('S','N','1','2')) { + ret = _gst_camerasrc_get_normal_buffer(camerasrc, camerasrc->cap_fourcc, + main_buf.start, camerasrc->cap_width, camerasrc->cap_height, + &GST_BUFFER_DATA(buf), &GST_BUFFER_SIZE(buf)); + if (ret == FALSE) { + g_mutex_unlock( camerasrc->buffer_lock ); + return GST_FLOW_ERROR; + } + + buf->is_alloc_data = TRUE; + } else { + GST_BUFFER_DATA(buf) = main_buf.start; + GST_BUFFER_SIZE(buf) = main_buf.length; + } + + *buffer = (GstBuffer *)buf; + GST_INFO_OBJECT(camerasrc, "BUF for PREVIEW: addr %p size %d", + GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); + + GST_BUFFER_DATA(buf_cap_signal1) = GST_BUFFER_DATA(buf); + GST_BUFFER_SIZE(buf_cap_signal1) = GST_BUFFER_SIZE(buf); + GST_BUFFER_CAPS(buf_cap_signal1) = gst_caps_new_simple("video/x-raw-yuv", + "format", GST_TYPE_FOURCC, camerasrc->cap_fourcc, + "width", G_TYPE_INT, camerasrc->cap_width, + "height", G_TYPE_INT, camerasrc->cap_height, + NULL); + buf_cap_signal2 = NULL; + buf_cap_signal3 = NULL; + } + + /*call signal*/ + GST_INFO_OBJECT (camerasrc, "CALL: capture callback"); + + g_signal_emit( G_OBJECT (camerasrc), + gst_camerasrc_signals[SIGNAL_STILL_CAPTURE], + 0, + buf_cap_signal1, + buf_cap_signal2, + buf_cap_signal3 ); + + GST_INFO_OBJECT (camerasrc, "RETURN: capture callback"); + + if (is_jpeg || + (!is_jpeg && (camerasrc->fourcc != camerasrc->cap_fourcc || + camerasrc->width != camerasrc->cap_width || + camerasrc->height != camerasrc->cap_height))) { + /* Queue buffer */ + camerasrc_queue_buffer(camerasrc->v4l2_handle, buffer_index, &main_buf); + + /* release buffer */ + if (*buffer) { + gst_buffer_unref(*buffer); + *buffer = NULL; + } + } else { + camerasrc->num_live_buffers++; + /*escape loop for passing buffer to videosink*/ + break; + } + } else { + if (camerasrc->cap_next_time < cur_time + _CONTINUOUS_SHOT_MARGIN) { + GST_DEBUG_OBJECT(camerasrc, "check again time"); + usleep((camerasrc->cap_next_time - cur_time) * 1000); + goto CHECK_CAPTURE_INTERVAL; + } + + /* RAW capture buffer should be reach here */ + camerasrc_queue_buffer(camerasrc->v4l2_handle, buffer_index, &main_buf); + + /* Skip passing this buffer */ + *buffer = NULL; + + GST_DEBUG_OBJECT(camerasrc, "Skip pssing this buffer"); + break; + } + } + + GST_DEBUG_OBJECT (camerasrc, "LEAVED"); + + return GST_FLOW_OK; +} + + +static GstFlowReturn gst_camerasrc_read(GstCameraSrc *camerasrc, GstBuffer **buffer) +{ + int err = 0; + int command = GST_CAMERA_CONTROL_CAPTURE_COMMAND_NONE; + GstFlowReturn ret = GST_FLOW_OK; + camerasrc_state_t state = CAMERASRC_STATE_NONE; + + g_mutex_lock(camerasrc->mutex); + + if (!g_queue_is_empty(camerasrc->command_list)) { + command = (int)g_queue_pop_head(camerasrc->command_list); + GST_INFO_OBJECT(camerasrc, "popped cmd : %d", command); + } + + /* Normal Capture Routine */ + if (command == GST_CAMERA_CONTROL_CAPTURE_COMMAND_START) { + MMTA_ACUM_ITEM_BEGIN(" Shot to Shot in gstcamerasrc", FALSE); + __ta__(" gst_camerasrc_capture_start", + gst_camerasrc_capture_start(camerasrc); + ); + } + + g_mutex_unlock(camerasrc->mutex); + + switch (camerasrc->mode) { + case VIDEO_IN_MODE_PREVIEW: + case VIDEO_IN_MODE_VIDEO: + if (camerasrc->use_pad_alloc == TRUE) { + err = camerasrc_get_state(camerasrc->v4l2_handle, &state); + + if (state == CAMERASRC_STATE_READY) { + GST_INFO_OBJECT (camerasrc,"Prepare buffer"); + ret = gst_camerasrc_prepare_preview(camerasrc, camerasrc->num_alloc_buf); + } + } + + if (camerasrc->use_pad_alloc == TRUE) { + __ta__(" gst_camerasrc_read_preview_pad_alloc", + ret = gst_camerasrc_read_preview_pad_alloc(camerasrc, buffer); + ); + } else { + __ta__(" gst_camerasrc_read_preview_mmap", + ret = gst_camerasrc_read_preview_mmap(camerasrc, buffer); + ) + } + break; + case VIDEO_IN_MODE_CAPTURE: + __ta__( " gst_camerasrc_read_capture", + ret = gst_camerasrc_read_capture(camerasrc, buffer, command); + ); + break; + case VIDEO_IN_MODE_UNKNOWN: + default: + ret = GST_FLOW_ERROR; + GST_ERROR_OBJECT (camerasrc, "can't reach statement.[camerasrc->mode=%d]", camerasrc->mode); + break; + } + + if (!buffer || !(*buffer) || !GST_IS_BUFFER(*buffer)) { + /* To avoid seg fault, make dummy buffer. */ + GST_WARNING_OBJECT (camerasrc, "Make a dummy buffer"); + *buffer = gst_buffer_new(); + GST_BUFFER_DATA(*buffer) = NULL; + GST_BUFFER_SIZE(*buffer) = 0; + } + + return ret; +} + + +/* Buffer related functions */ +static void gst_camerasrc_buffer_pad_alloc_qbuf(GstCameraBuffer *buffer) +{ + int ret = 0; + gint index = 0; + GstCaps *negotiated_caps = NULL; + GstBuffer *queue_buf = NULL; + GstCameraSrc *camerasrc = NULL; + camerasrc_buffer_t camerasrc_buffer; + + if (buffer) { + camerasrc = buffer->camerasrc; + } else { + GST_ERROR("buffer is NULL"); + return; + } + + if (camerasrc) { + negotiated_caps = gst_pad_get_negotiated_caps(GST_BASE_SRC_PAD(camerasrc)); + } else { + GST_ERROR("camerasrc is NULL"); + return; + } + + index = buffer->v4l2_buffer_index; + + GST_LOG_OBJECT(camerasrc, "pad alloc qbuf"); + + ret = gst_pad_alloc_buffer(GST_BASE_SRC_PAD (camerasrc), + 0, + camerasrc->main_buf_sz, + negotiated_caps, + &queue_buf); + if (!GST_IS_BUFFER(queue_buf)) { + GST_INFO_OBJECT (camerasrc, "[DEBUG] NOT BUFFER!!?"); + } + + if (ret != GST_FLOW_OK) { + GST_ERROR_OBJECT(camerasrc, "gst_pad_alloc_buffer failed. [%d]", ret); + return; + } else { + GST_LOG_OBJECT(camerasrc, "Alloced Size = %dAlloced address : %p", + GST_BUFFER_SIZE(GST_BUFFER(queue_buf)), GST_BUFFER_DATA(GST_BUFFER(queue_buf))); + } + + gst_caps_unref(negotiated_caps); + negotiated_caps = NULL; + + camerasrc_buffer.start = GST_BUFFER_DATA(GST_BUFFER(queue_buf)); + camerasrc_buffer.length = GST_BUFFER_SIZE(GST_BUFFER(queue_buf)); + ret = camerasrc_queue_buffer(camerasrc->v4l2_handle, index, &camerasrc_buffer); + if (ret != CAMERASRC_SUCCESS) { + GST_ERROR_OBJECT(camerasrc, "QBUF error, [%x]", ret); + return; + } else { + GST_LOG_OBJECT (camerasrc, "QBUF : [idx=%d]", index); + } + + return; +} + + +static void gst_camerasrc_buffer_mmap_qbuf(GstCameraBuffer *buffer) +{ + int ret = 0; + gint index = 0; + GstCameraSrc *camerasrc = NULL; + camerasrc_buffer_t camerasrc_buffer; + + camerasrc = buffer->camerasrc; + index = buffer->v4l2_buffer_index; + + ret = camerasrc_queue_buffer(camerasrc->v4l2_handle, index, &camerasrc_buffer); + if (ret != CAMERASRC_SUCCESS) { + GST_ERROR_OBJECT(camerasrc, "QBUF error, [%x]", ret); + } else { + GST_LOG_OBJECT(camerasrc, "QBUF : [idx=%d]", index); + } + + return; +} + +static void gst_camerasrc_buffer_finalize(GstCameraBuffer *buffer) +{ + gint index = 0; + GstCameraSrc *camerasrc = NULL; + + camerasrc = buffer->camerasrc; + index = buffer->v4l2_buffer_index; + + GST_LOG_OBJECT(camerasrc, "finalizing buffer %p, %d [%" + GST_TIME_FORMAT " dur %" GST_TIME_FORMAT "]", buffer, index, + GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)), + GST_TIME_ARGS(GST_BUFFER_DURATION(buffer))); + + if (camerasrc->buffer_running) { + /* Buffer Q again */ + if (camerasrc->use_pad_alloc == TRUE){ + gst_camerasrc_buffer_pad_alloc_qbuf(buffer); + } else { + gst_camerasrc_buffer_mmap_qbuf(buffer); + } + } else { + GST_INFO_OBJECT(camerasrc, "It is not running. skip QBUF"); + } + + camerasrc->num_live_buffers--; + g_cond_signal(camerasrc->buffer_cond); + GST_LOG_OBJECT(camerasrc, "QBUF : [idx=%d, lvn=%d]", index, camerasrc->num_live_buffers); + + if (buffer->is_alloc_data) { + GST_DEBUG("free allocated data %p", GST_BUFFER_DATA(buffer)); + if (GST_BUFFER_DATA(buffer)) { + free(GST_BUFFER_DATA(buffer)); + GST_BUFFER_DATA(buffer) = NULL; + } + + buffer->is_alloc_data = FALSE; + } + + if (GST_BUFFER_MALLOCDATA(buffer)) { + free(GST_BUFFER_MALLOCDATA(buffer)); + GST_BUFFER_MALLOCDATA(buffer) = NULL; + } + + gst_object_unref(camerasrc); + + if (GST_MINI_OBJECT_CLASS (camera_buffer_parent_class)->finalize) { + GST_MINI_OBJECT_CLASS (camera_buffer_parent_class)->finalize (GST_MINI_OBJECT(buffer)); + } + + return; +} + + +static void gst_camerasrc_buffer_class_init(gpointer g_class, gpointer class_data) +{ + GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS(g_class); + + camera_buffer_parent_class = g_type_class_peek_parent(g_class); + mini_object_class->finalize = (GstMiniObjectFinalizeFunction)gst_camerasrc_buffer_finalize; +} + + +static GType gst_camerasrc_buffer_get_type(void) +{ + static GType _gst_camerasrc_buffer_type; + + if (G_UNLIKELY(_gst_camerasrc_buffer_type == 0)) { + static const GTypeInfo camera_buffer_info = { + sizeof (GstBufferClass), + NULL, + NULL, + gst_camerasrc_buffer_class_init, + NULL, + NULL, + sizeof (GstCameraBuffer), + 0, + NULL, + NULL + }; + + _gst_camerasrc_buffer_type = g_type_register_static(GST_TYPE_BUFFER, + "GstCameraBuffer", + &camera_buffer_info, 0); + } + + return _gst_camerasrc_buffer_type; +} + + +static GstCameraBuffer *gst_camerasrc_buffer_new(GstCameraSrc *camerasrc) +{ + GstCameraBuffer *ret = NULL; + + ret = (GstCameraBuffer *)gst_mini_object_new(GST_TYPE_CAMERASRC_BUFFER); + + GST_LOG_OBJECT(camerasrc, "creating buffer : %p", ret); + + ret->camerasrc = gst_object_ref(GST_OBJECT(camerasrc)); + ret->is_alloc_data = FALSE; + + return ret; +} + + +static void gst_camerasrc_buffer_free(gpointer data) +{ + GST_CAMERASRC_BUFFER_DATA *buffer_data = (GST_CAMERASRC_BUFFER_DATA *)data; + + GST_LOG_OBJECT(buffer_data->camerasrc, "freeing buffer with %p %d", + buffer_data->camerasrc, buffer_data->index); + + g_mutex_lock(buffer_data->camerasrc->pad_alloc_mutex); + + if (buffer_data->buffer_data_index == buffer_data->camerasrc->current_buffer_data_index) { + GST_LOG_OBJECT(buffer_data->camerasrc, "Push index [%d] to pad_alloc_list", buffer_data->index); + g_queue_push_tail(buffer_data->camerasrc->pad_alloc_list, (gpointer)buffer_data->index); + } else { + GST_WARNING_OBJECT(buffer_data->camerasrc, "Skip Pushing index [%d] to pad_alloc_list.", buffer_data->index ); + GST_WARNING_OBJECT(buffer_data->camerasrc, "buffer_data_index [%d], current_buffer_data_index [%d]", + buffer_data->buffer_data_index, + buffer_data->camerasrc->current_buffer_data_index); + } + + buffer_data->camerasrc->num_live_buffers--; + + g_mutex_unlock(buffer_data->camerasrc->pad_alloc_mutex); + g_cond_signal(buffer_data->camerasrc->buffer_cond); + + buffer_data->camerasrc = NULL; + buffer_data->index = -1; + + /* Free data argument */ + g_free(data); + + return; +} + + +static void gst_camerasrc_buffer_trace(GstCameraSrc *camerasrc) +{ + int i = 0; + GstBuffer *buf = NULL; + + if (!camerasrc) { + GST_ERROR_OBJECT(camerasrc, "Element is NULL"); + return; + } + + for (i = 0 ; i < camerasrc->num_alloc_buf ; i ++) { + buf = camerasrc->usr_buffer[i]; + if (GST_IS_BUFFER(buf)) { + GST_ELEMENT_WARNING(camerasrc, RESOURCE, FAILED, + NULL, (("Chainfunc of buf[%d]=%s()"), i, + GST_DEBUG_FUNCPTR_NAME(buf->_gst_reserved[0]))); + } else { + GST_ELEMENT_WARNING(camerasrc, RESOURCE, FAILED, + NULL, (("buf[%d] is not GstBuffer"), i)); + } + } + + return; +} + + +static unsigned char *gst_camerasrc_make_metadata_for_nonlinear_buffer(GstCameraSrc *camerasrc, guint32 index) +{ + unsigned char *meta_string = NULL; + camerasrc_frame_data_t data; + SCMN_IMGB *psimgb = NULL; + + /*GST_LOG_OBJECT (camerasrc, "index[%d],pix_format[%x]", index, camerasrc->fourcc);*/ + + psimgb = (SCMN_IMGB *)malloc(sizeof(SCMN_IMGB)); + if (psimgb == NULL) { + GST_ERROR_OBJECT(camerasrc, "failed to alloc SCMN_IMGB"); + return NULL; + } + + memset(psimgb, 0x00, sizeof(SCMN_IMGB)); + + data.index = index; + camerasrc_get_frame_data(camerasrc->v4l2_handle, &data); + + psimgb->p[0] = (void *)data.phyAddrY; + psimgb->a[0] = (void *)data.virAddrY; + psimgb->p[1] = (void *)data.phyAddrCbCr; + psimgb->a[1] = (void *)data.virAddrCbCr; + + psimgb->w[0] = camerasrc->width; + psimgb->h[0] = camerasrc->height; + + if (camerasrc->fourcc == GST_MAKE_FOURCC('S','T','1','2')) { + psimgb->cs = SCMN_CS_NV12; + psimgb->w[1] = camerasrc->width; + psimgb->h[1] = camerasrc->height >> 1; + + psimgb->s[0] = GST_ROUND_UP_16(psimgb->w[0]); + psimgb->e[0] = GST_ROUND_UP_16(psimgb->h[0]); + psimgb->s[1] = GST_ROUND_UP_16(psimgb->w[1]); + psimgb->e[1] = GST_ROUND_UP_16(psimgb->h[1]); + } else { + if (camerasrc->fourcc == GST_MAKE_FOURCC('S','N','1','2')) { + psimgb->cs = SCMN_CS_NV12_T64X32; + psimgb->w[1] = camerasrc->width; + psimgb->h[1] = camerasrc->height >> 1; + } else if (camerasrc->fourcc == GST_MAKE_FOURCC('S','U','Y','V')) { + psimgb->cs = SCMN_CS_YUYV; + } else if (camerasrc->fourcc == GST_MAKE_FOURCC('S','U','Y','2')) { + psimgb->cs = SCMN_CS_YUY2; + } else if (camerasrc->fourcc == GST_MAKE_FOURCC('S','Y','V','Y')) { + psimgb->cs = SCMN_CS_UYVY; + } else if (camerasrc->fourcc == GST_MAKE_FOURCC('S','4','2','0')) { + guint offset = 0; + + psimgb->cs = SCMN_CS_I420; + offset = CAMERASRC_ALIGN(camerasrc->width * camerasrc->height >> 2, ALIGN_SIZE_I420); + psimgb->p[2] = (void *)(data.phyAddrCbCr + offset); + psimgb->a[2] = (void *)(data.virAddrCbCr + offset); + + psimgb->w[1] = psimgb->w[2] = camerasrc->width; + psimgb->h[1] = psimgb->h[2] = camerasrc->height >> 2; + } else { + GST_WARNING_OBJECT (camerasrc, "Unknown pixel format."); + } + + psimgb->s[0] = psimgb->w[0]; + psimgb->e[0] = psimgb->h[0]; + psimgb->s[1] = psimgb->w[1]; + psimgb->e[1] = psimgb->h[1]; + psimgb->s[2] = psimgb->w[2]; + psimgb->e[2] = psimgb->h[2]; + } + + /*GST_LOG_OBJECT(camerasrc, "index[%d],Plane0[%p],Plane1[%p],Plane2[%p]", + index, psimgb->p[0], psimgb->p[1], psimgb->p[2]);*/ + meta_string = (unsigned char*)psimgb; + + return meta_string; +} + + +static gboolean gst_camerasrc_device_is_open(GstCameraSrc *camerasrc) +{ + return camerasrc_device_is_open((camsrc_handle_t)camerasrc->v4l2_handle); +} + + +static gboolean gst_camerasrc_get_timeinfo(GstCameraSrc *camerasrc, GstBuffer *buffer) +{ + int fps_nu = 0; + int fps_de = 0; + GstClock *clock = NULL; + GstClockTime timestamp = GST_CLOCK_TIME_NONE; + GstClockTime duration = GST_CLOCK_TIME_NONE; + + if (!camerasrc || !buffer) { + GST_WARNING_OBJECT (camerasrc, "Invalid pointer [hadle:%p, buffer:%p]", camerasrc, buffer); + return FALSE; + } + + /* timestamps, LOCK to get clock and base time. */ + clock = GST_ELEMENT_CLOCK(camerasrc); + if (clock) { + /* the time now is the time of the clock minus the base time */ + gst_object_ref(clock); + timestamp = gst_clock_get_time(clock) - GST_ELEMENT(camerasrc)->base_time; + gst_object_unref(clock); + + /* if we have a framerate adjust timestamp for frame latency */ + if (camerasrc->fps_auto) { + /*if fps is zero, auto fps mode*/ + duration = GST_CLOCK_TIME_NONE; + } else { + if (camerasrc->fps <= 0) { + /*if fps is zero, auto fps mode*/ + fps_nu = 0; + fps_de = 1; + } else { + fps_nu = 1; + fps_de = camerasrc->fps; + } + + if (fps_nu > 0 && fps_de > 0) { + GstClockTime latency; + + latency = gst_util_uint64_scale_int(GST_SECOND, fps_nu, fps_de); + duration = latency; + } + } + } else { + /* no clock, can't set timestamps */ + timestamp = GST_CLOCK_TIME_NONE; + } + + GST_BUFFER_TIMESTAMP(buffer) = timestamp; + GST_BUFFER_DURATION(buffer) = duration; +/* + GST_INFO_OBJECT(camerasrc, "[%"GST_TIME_FORMAT" dur %" GST_TIME_FORMAT "]", + GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)), + GST_TIME_ARGS(GST_BUFFER_DURATION(buffer))); +*/ + + return TRUE; +} + + +static int get_proper_index(GstCameraSrc *camerasrc, GstBuffer *pad_alloc_buffer) +{ + int temp_idx = 0; + + while (GST_BUFFER_DATA(GST_BUFFER(pad_alloc_buffer)) != g_present_buf.present_buffer[temp_idx++].start) { + if (temp_idx >= camerasrc->num_alloc_buf) { + return -1; + } + } + + return temp_idx - 1; /* -1 is caused that it already increased in ++ */ +} + + +/* Gstreamer general functions */ +static gboolean gst_camerasrc_src_start(GstBaseSrc *src) +{ + int ret = TRUE; + GstCameraSrc *camerasrc = GST_CAMERA_SRC (src); + + GST_DEBUG_OBJECT(camerasrc, "ENTERED"); + +#if _ENABLE_CAMERASRC_DEBUG + g_preview_frame_cnt = 0; +#endif + + camerasrc->firsttime = TRUE; + /* 'gst_camerasrc_set_caps' will call gst_camerasrc_start(). So skip to call it. */ + /*ret = gst_camerasrc_start(camerasrc);*/ + + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + + return ret; +} + + +static gboolean gst_camerasrc_src_stop(GstBaseSrc *src) +{ + int ret = 0; + GstCameraSrc *camerasrc = GST_CAMERA_SRC(src); + + GST_DEBUG_OBJECT (camerasrc, "ENTERED"); + + ret = gst_camerasrc_stop(camerasrc); + + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + + return TRUE; +} + + +static GstFlowReturn gst_camerasrc_src_create(GstPushSrc *src, GstBuffer **buffer) +{ + GstCameraSrc *camerasrc = GST_CAMERA_SRC (src); + GstFlowReturn ret; + + /*GST_DEBUG_OBJECT(camerasrc, "ENTERED");*/ + + if (camerasrc->req_negotiation) { + GST_INFO_OBJECT(camerasrc, "negotiation start"); + + GST_BASE_SRC_GET_CLASS(camerasrc)->negotiate(GST_BASE_SRC(camerasrc)); + camerasrc->req_negotiation = FALSE; + g_signal_emit(G_OBJECT(camerasrc), gst_camerasrc_signals[SIGNAL_NEGO_COMPLETE], (GQuark)NULL); + + GST_INFO_OBJECT (camerasrc, "negotiation stop"); + } + + __ta__(" gst_camerasrc_read", + ret = gst_camerasrc_read(camerasrc, buffer); + ) + /*GST_DEBUG_OBJECT (camerasrc, "LEAVED");*/ + + return ret; +} + + +static void gst_camerasrc_set_property(GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + int tmp = 0; + GstCameraSrc *camerasrc = NULL; + + g_return_if_fail(GST_IS_CAMERA_SRC(object)); + camerasrc = GST_CAMERA_SRC(object); + + switch (prop_id) { + case ARG_REQ_NEGOTIATION: + camerasrc->req_negotiation = g_value_get_boolean(value); + break; + case ARG_CAMERA_HIGH_SPEED_FPS: + tmp = g_value_get_int(value); + camerasrc->high_speed_fps = tmp; + break; + case ARG_CAMERA_AUTO_FPS: + camerasrc->fps_auto = g_value_get_boolean(value); + GST_DEBUG_OBJECT(camerasrc, "Set AUTO_FPS:%d", camerasrc->fps_auto); + break; + case ARG_CAMERA_ID: + camerasrc->camera_id = g_value_get_int(value); + break; + case ARG_CAMERA_EXT_VIDEO_FD: + camerasrc->external_videofd = g_value_get_int(value); + break; + case ARG_CAMERA_CAPTURE_FOURCC: + camerasrc->cap_fourcc = g_value_get_uint(value); + break; + case ARG_CAMERA_CAPTURE_QUALITY: + camerasrc->cap_quality = g_value_get_enum(value); + break; + case ARG_CAMERA_CAPTURE_WIDTH: + camerasrc->cap_width = g_value_get_int(value); + break; + case ARG_CAMERA_CAPTURE_HEIGHT: + camerasrc->cap_height = g_value_get_int(value); + break; + case ARG_CAMERA_CAPTURE_INTERVAL: + camerasrc->cap_interval = g_value_get_int(value); + break; + case ARG_CAMERA_CAPTURE_COUNT: + tmp = g_value_get_int(value); + camerasrc->cap_count = tmp; + g_mutex_lock(camerasrc->jpg_mutex); + camerasrc->cap_count_reverse = tmp; + g_mutex_unlock(camerasrc->jpg_mutex); + GST_INFO("SET reverse capture count: %d", camerasrc->cap_count_reverse); + break; + case ARG_CAMERA_CAPTURE_JPG_QUALITY: + camerasrc->cap_jpg_quality = g_value_get_int(value); + GST_INFO("SET jpeg compress ratio : %d", camerasrc->cap_jpg_quality); + break; + case ARG_SIGNAL_STILLCAPTURE: + camerasrc->signal_still_capture = g_value_get_boolean(value); + break; + case ARG_USE_PAD_ALLOC: + camerasrc->use_pad_alloc = g_value_get_boolean(value); + break; + case ARG_NUM_ALLOC_BUF: + camerasrc->num_alloc_buf = g_value_get_int(value); + break; + case ARG_HOLD_AF_AFTER_CAPTURE: + camerasrc->hold_af_after_capturing = g_value_get_boolean(value); + camerasrc_set_af_hold_after_capture(camerasrc->v4l2_handle, (int)camerasrc->hold_af_after_capturing); + break; + case ARG_SENSOR_MODE: + camerasrc->sensor_mode = g_value_get_int(value); + break; + case ARG_VFLIP: + camerasrc->vflip = g_value_get_boolean(value); + break; + case ARG_HFLIP: + camerasrc->hflip = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + + +static void gst_camerasrc_get_property(GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + GstCameraSrc *camerasrc; + + g_return_if_fail(GST_IS_CAMERA_SRC(object)); + camerasrc = GST_CAMERA_SRC(object); + + switch (prop_id) { + case ARG_REQ_NEGOTIATION: + g_value_set_boolean(value, camerasrc->req_negotiation); + break; + case ARG_CAMERA_HIGH_SPEED_FPS: + g_value_set_int(value, camerasrc->high_speed_fps); + break; + case ARG_CAMERA_AUTO_FPS: + g_value_set_boolean(value, camerasrc->fps_auto); + break; + case ARG_CAMERA_ID: + g_value_set_int(value, camerasrc->camera_id); + break; + case ARG_CAMERA_EXT_VIDEO_FD: + g_value_set_int(value, camerasrc->external_videofd); + break; + case ARG_CAMERA_CAPTURE_FOURCC: + g_value_set_uint(value, camerasrc->cap_fourcc); + break; + case ARG_CAMERA_CAPTURE_QUALITY: + g_value_set_enum(value, camerasrc->cap_quality); + break; + case ARG_CAMERA_CAPTURE_WIDTH: + g_value_set_int(value, camerasrc->cap_width); + break; + case ARG_CAMERA_CAPTURE_HEIGHT: + g_value_set_int(value, camerasrc->cap_height); + break; + case ARG_CAMERA_CAPTURE_INTERVAL: + g_value_set_int(value, camerasrc->cap_interval); + break; + case ARG_CAMERA_CAPTURE_COUNT: + g_value_set_int(value, camerasrc->cap_count); + break; + case ARG_CAMERA_CAPTURE_JPG_QUALITY: + g_value_set_int(value, camerasrc->cap_jpg_quality); + GST_INFO("GET jpeg compress ratio : %d", camerasrc->cap_jpg_quality); + break; + case ARG_CAMERA_CAPTURE_PROVIDE_EXIF: + camerasrc_support_embed_exif(camerasrc->v4l2_handle, &(camerasrc->cap_provide_exif)); + g_value_set_boolean(value, camerasrc->cap_provide_exif); + GST_INFO("Is Exif provided? : %d", camerasrc->cap_provide_exif); + break; + case ARG_SIGNAL_STILLCAPTURE: + g_value_set_boolean(value, camerasrc->signal_still_capture); + break; + case ARG_USE_PAD_ALLOC: + g_value_set_boolean(value, camerasrc->use_pad_alloc); + break; + case ARG_NUM_ALLOC_BUF: + g_value_set_int(value, camerasrc->num_alloc_buf); + break; + case ARG_OPERATION_STATUS: + g_value_set_int(value, 0); + gst_camerasrc_buffer_trace(camerasrc); + break; + case ARG_HOLD_AF_AFTER_CAPTURE: + g_value_set_boolean(value, camerasrc->hold_af_after_capturing); + break; + case ARG_SENSOR_MODE: + g_value_set_int(value, camerasrc->sensor_mode); + break; + case ARG_VFLIP: + g_value_set_boolean(value, camerasrc->vflip); + break; + case ARG_HFLIP: + g_value_set_boolean(value, camerasrc->hflip); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + + +static GstStateChangeReturn gst_camerasrc_change_state(GstElement *element, GstStateChange transition) +{ + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + GstCameraSrc *camerasrc; + camerasrc = GST_CAMERA_SRC (element); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: NULL -> READY"); + __ta__(" gst_camerasrc_create", + if (!gst_camerasrc_create(camerasrc)){ + goto statechange_failed; + } + ); + break; + case GST_STATE_CHANGE_READY_TO_PAUSED: + GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: READY -> PAUSED"); + ret = GST_STATE_CHANGE_NO_PREROLL; + break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: PAUSED -> PLAYING"); + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition); + if (ret == GST_STATE_CHANGE_FAILURE){ + return ret; + } + + switch (transition) { + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: PLAYING -> PAUSED"); + ret = GST_STATE_CHANGE_NO_PREROLL; + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: PAUSED -> READY"); + break; + case GST_STATE_CHANGE_READY_TO_NULL: + GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: READY -> NULL"); + __ta__(" gst_camerasrc_destroy", + if (!gst_camerasrc_destroy(camerasrc)){ + goto statechange_failed; + } + ); + break; + default: + break; + } + + return ret; + + statechange_failed: + /* subclass must post a meaningfull error message */ + GST_ERROR_OBJECT(camerasrc, "state change failed"); + + return GST_STATE_CHANGE_FAILURE; +} + + +static void gst_camerasrc_finalize(GObject *object) +{ + GstCameraSrc *camerasrc = GST_CAMERA_SRC(object); + +#if _ENABLE_CAMERASRC_DEBUG + GST_INFO_OBJECT(camerasrc, "total [%u] preview frame(s) outputed.",g_preview_frame_cnt); +#endif + + g_mutex_free(camerasrc->jpg_mutex); + g_mutex_free(camerasrc->mutex); + g_cond_free(camerasrc->cond); + g_mutex_free(camerasrc->buffer_lock); + g_cond_broadcast(camerasrc->buffer_cond); + g_cond_free(camerasrc->buffer_cond); + + if (camerasrc->command_list != NULL) { + g_queue_free(camerasrc->command_list); + camerasrc->command_list = NULL; + } + + G_OBJECT_CLASS(parent_class)->finalize(object); +} + + +void gst_camerasrc_set_capture_command(GstCameraSrc *camerasrc, GstCameraControlCaptureCommand cmd) +{ + gboolean is_zsl = FALSE; + + if (camerasrc == NULL) { + GST_ERROR_OBJECT(camerasrc, "camerasrc is NULL"); + return; + } + + GST_INFO_OBJECT(camerasrc, "ENTERED"); + + g_mutex_lock(camerasrc->mutex); + + /* Do not push command when ZSL mode */ + if (!is_zsl) { + g_queue_push_tail(camerasrc->command_list, (gpointer)cmd); + GST_INFO_OBJECT(camerasrc, "ACTION: Push capture command [%d] finished.", cmd); + } + + if (cmd == GST_CAMERA_CONTROL_CAPTURE_COMMAND_STOP) { + g_cond_signal(camerasrc->cond); + GST_INFO_OBJECT(camerasrc, "Send signal for CAPTURE STOP"); + } + + g_mutex_unlock(camerasrc->mutex); + + return; +} + + +static gboolean gst_camerasrc_negotiate (GstBaseSrc * basesrc) +{ + GstCaps *thiscaps; + GstCaps *caps = NULL; + GstCaps *peercaps = NULL; + gboolean result = FALSE; + GstStructure *s; + GstCameraSrc *camerasrc = GST_CAMERA_SRC(basesrc); + + GST_INFO_OBJECT(camerasrc, "ENTERED"); + /* first see what is possible on our source pad */ + thiscaps = gst_pad_get_caps (GST_BASE_SRC_PAD (basesrc)); + GST_DEBUG_OBJECT (basesrc, "caps of src: %" GST_PTR_FORMAT, thiscaps); + + /* nothing or anything is allowed, we're done */ + if (thiscaps == NULL || gst_caps_is_any (thiscaps)) + goto no_nego_needed; + + /* get the peer caps */ + peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc)); + GST_DEBUG_OBJECT (basesrc, "caps of peer: %" GST_PTR_FORMAT, peercaps); + //LOG_CAPS (basesrc, peercaps); + if (peercaps && !gst_caps_is_any (peercaps)) { + GstCaps *icaps = NULL; + int i; + + /* Prefer the first caps we are compatible with that the peer proposed */ + for (i = 0; i < gst_caps_get_size (peercaps); i++) { + /* get intersection */ + GstCaps *ipcaps = gst_caps_copy_nth (peercaps, i); + + icaps = gst_caps_intersect (thiscaps, ipcaps); + gst_caps_unref (ipcaps); + + if (!gst_caps_is_empty (icaps)) + break; + + gst_caps_unref (icaps); + icaps = NULL; + } + + GST_DEBUG_OBJECT (basesrc, "intersect: %" GST_PTR_FORMAT, icaps); + if (icaps) { + /* If there are multiple intersections pick the one with the smallest + * resolution strictly bigger than the first peer caps */ + if (gst_caps_get_size (icaps) > 1) { + s = gst_caps_get_structure (peercaps, 0); + int best = 0; + int twidth, theight; + int width = G_MAXINT, height = G_MAXINT; + + if (gst_structure_get_int (s, "width", &twidth) + && gst_structure_get_int (s, "height", &theight)) { + + /* Walk the structure backwards to get the first entry of the + * smallest resolution bigger (or equal to) the preferred resolution) + */ + for (i = gst_caps_get_size (icaps) - 1; i >= 0; i--) { + GstStructure *is = gst_caps_get_structure (icaps, i); + int w, h; + + if (gst_structure_get_int (is, "width", &w) + && gst_structure_get_int (is, "height", &h)) { + if (w >= twidth && w <= width && h >= theight && h <= height) { + width = w; + height = h; + best = i; + } + } + } + } + + caps = gst_caps_copy_nth (icaps, best); + gst_caps_unref (icaps); + } else { + caps = icaps; + } + } + gst_caps_unref (thiscaps); + gst_caps_unref (peercaps); + } else { + /* no peer or peer has ANY caps, work with our own caps then */ + caps = thiscaps; + } + if (caps) { + caps = gst_caps_make_writable (caps); + gst_caps_truncate (caps); + + /* now fixate */ + if (!gst_caps_is_empty (caps)) { + gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps); + GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, caps); + + if (gst_caps_is_any (caps)) { + /* hmm, still anything, so element can do anything and + * nego is not needed */ + result = TRUE; + } else if (gst_caps_is_fixed (caps)) { + /* yay, fixed caps, use those then */ + if (gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps)) + result = TRUE; + } + } + gst_caps_unref (caps); + } + return result; + +no_nego_needed: + { + GST_DEBUG_OBJECT (basesrc, "no negotiation needed"); + if (thiscaps) + gst_caps_unref (thiscaps); + return TRUE; + } +} + + +static GstCaps *gst_camerasrc_get_caps(GstBaseSrc *src) +{ + GstCameraSrc *camerasrc = GST_CAMERA_SRC(src); + GstCaps *ret = NULL; + + GST_DEBUG_OBJECT(camerasrc, "ENTERED"); + + if (camerasrc->mode == VIDEO_IN_MODE_UNKNOWN) { + GST_INFO_OBJECT(camerasrc, "Unknown mode. Just return template caps."); + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + + return gst_caps_copy(gst_pad_get_pad_template_caps(GST_BASE_SRC_PAD(camerasrc))); + } + + /*FIXME: Using "VIDIOC_ENUM_FMT".*/ + ret = gst_caps_copy(gst_pad_get_pad_template_caps(GST_BASE_SRC_PAD(camerasrc))); + + GST_INFO_OBJECT(camerasrc, "probed caps: %x", ret); + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + + return ret; +} + + +static gboolean _gst_camerasrc_get_raw_pixel_info(int fourcc, int *pix_format, int *colorspace) +{ + switch (fourcc) { + case GST_MAKE_FOURCC('I','4','2','0'): /* V4L2_PIX_FMT_YUV420 */ + case GST_MAKE_FOURCC('I','Y','U','V'): + case GST_MAKE_FOURCC('Y','U','1','2'): + case GST_MAKE_FOURCC('S','4','2','0'): + *pix_format = CAMERASRC_PIX_YUV420P; + *colorspace = CAMERASRC_COL_RAW; + break; + case GST_MAKE_FOURCC('Y','U','Y','V'): /* V4L2_PIX_FMT_YUYV */ + case GST_MAKE_FOURCC('Y','U','Y','2'): /* V4L2_PIX_FMT_YUYV */ + case GST_MAKE_FOURCC('S','U','Y','V'): + case GST_MAKE_FOURCC('S','U','Y','2'): + *pix_format = CAMERASRC_PIX_YUY2; + *colorspace = CAMERASRC_COL_RAW; + break; + case GST_MAKE_FOURCC('U','Y','V','Y'): /* V4L2_PIX_FMT_UYVY */ + case GST_MAKE_FOURCC('S','Y','V','Y'): /* V4L2_PIX_FMT_UYVY */ + *pix_format = CAMERASRC_PIX_UYVY; + *colorspace = CAMERASRC_COL_RAW; + break; + case GST_MAKE_FOURCC('4','2','2','P'): /* V4L2_PIX_FMT_YUV422P */ + case GST_MAKE_FOURCC('Y','4','2','B'): /* V4L2_PIX_FMT_YUV422P */ + *pix_format = CAMERASRC_PIX_YUV422P; + *colorspace = CAMERASRC_COL_RAW; + break; + case GST_MAKE_FOURCC('N','V','1','2'): /* V4L2_PIX_FMT_NV12 */ + *pix_format = CAMERASRC_PIX_NV12; + *colorspace = CAMERASRC_COL_RAW; + break; + case GST_MAKE_FOURCC('S','N','1','2'): /* V4L2_PIX_FMT_NV12 non-linear */ + *pix_format = CAMERASRC_PIX_SN12; + *colorspace = CAMERASRC_COL_RAW; + break; + case GST_MAKE_FOURCC('S','T','1','2'): /* V4L2_PIX_FMT_NV12 tiled non-linear */ + *pix_format = CAMERASRC_PIX_ST12; + *colorspace = CAMERASRC_COL_RAW; + break; + case GST_MAKE_FOURCC('J','P','E','G'): + case GST_MAKE_FOURCC('j','p','e','g'): + *pix_format = CAMERASRC_PIX_RGGB8; + *colorspace = CAMERASRC_COL_JPEG; + break; + case GST_MAKE_FOURCC('Y','4','1','P'): /* V4L2_PIX_FMT_Y41P */ + case GST_MAKE_FOURCC('N','V','2','1'): /* V4L2_PIX_FMT_NV21 */ + case GST_MAKE_FOURCC('Y','4','1','B'): /* V4L2_PIX_FMT_YUV411P */ + case GST_MAKE_FOURCC('Y','V','1','2'): /* V4L2_PIX_FMT_YVU420 */ + default: + /* ERROR */ + *pix_format = CAMERASRC_PIX_NONE; + *colorspace = CAMERASRC_COL_NONE; + break; + } + + return TRUE; +} + + +static gboolean _gst_camerasrc_get_frame_size(int fourcc, int width, int height, unsigned int *outsize) +{ + switch (fourcc) { + case GST_MAKE_FOURCC('I','4','2','0'): /* V4L2_PIX_FMT_YUV420 */ + case GST_MAKE_FOURCC('I','Y','U','V'): + case GST_MAKE_FOURCC('Y','U','1','2'): + case GST_MAKE_FOURCC('Y','V','1','2'): + case GST_MAKE_FOURCC('S','4','2','0'): /* V4L2_PIX_FMT_NV12 tiled non-linear */ + *outsize = GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height); + *outsize += 2 * ((GST_ROUND_UP_8 (width) / 2) * (GST_ROUND_UP_2 (height) / 2)); + break; + case GST_MAKE_FOURCC('Y','U','Y','V'): /* V4L2_PIX_FMT_YUYV */ + case GST_MAKE_FOURCC('Y','U','Y','2'): /* V4L2_PIX_FMT_YUYV */ + case GST_MAKE_FOURCC('S','U','Y','V'): + case GST_MAKE_FOURCC('S','U','Y','2'): + case GST_MAKE_FOURCC('U','Y','V','Y'): /* V4L2_PIX_FMT_UYVY */ + case GST_MAKE_FOURCC('S','Y','V','Y'): /* V4L2_PIX_FMT_UYVY */ + case GST_MAKE_FOURCC('4','2','2','P'): /* V4L2_PIX_FMT_YUV422P */ + case GST_MAKE_FOURCC('Y','4','2','B'): /* V4L2_PIX_FMT_YUV422P */ + case GST_MAKE_FOURCC('Y','4','1','P'): /* V4L2_PIX_FMT_Y41P */ + *outsize = (GST_ROUND_UP_2 (width) * 2) * height; + break; + case GST_MAKE_FOURCC('Y','4','1','B'): /* V4L2_PIX_FMT_YUV411P */ + *outsize = GST_ROUND_UP_4 (width) * height; + *outsize += 2 * ((GST_ROUND_UP_8 (width) / 4) * height); + break; + case GST_MAKE_FOURCC('N','V','1','2'): /* V4L2_PIX_FMT_NV12 */ + case GST_MAKE_FOURCC('N','V','2','1'): /* V4L2_PIX_FMT_NV21 */ + case GST_MAKE_FOURCC('S','N','1','2'): /* V4L2_PIX_FMT_NV12 non-linear */ + case GST_MAKE_FOURCC('S','T','1','2'): /* V4L2_PIX_FMT_NV12 tiled non-linear */ + *outsize = GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height); + *outsize += (GST_ROUND_UP_4 (width) * height) / 2; + break; + case GST_MAKE_FOURCC('J','P','E','G'): + case GST_MAKE_FOURCC('j','p','e','g'): + /* jpeg size can't be calculated here. */ + *outsize = 0; + break; + default: + /* unkown format!! */ + *outsize = 0; + break; + } + + return TRUE; +} + +static gboolean _gst_camerasrc_get_normal_buffer(GstCameraSrc *camerasrc, int fourcc, + unsigned char *base_buffer, int width, int height, + unsigned char **new_buffer, unsigned int *new_buffer_length) +{ + unsigned char *copy_data = NULL; + guint length_Y = 0; + + if (camerasrc == NULL || base_buffer == NULL || + new_buffer == NULL || new_buffer_length == NULL) { + GST_WARNING_OBJECT(camerasrc, "something is NULL(%p,%p,%p,%p)", + camerasrc, base_buffer, new_buffer, new_buffer_length); + return FALSE; + } + + switch (fourcc) { + case GST_MAKE_FOURCC('I','4','2','0'): + case GST_MAKE_FOURCC('S','4','2','0'): + { + guint length_Cb = 0; + guint length_Cr = 0; + guint offset_Cb = 0; + guint offset_Cr = 0; + + length_Y = width * height; + length_Cb = length_Cr = (width * height) >> 2; + + copy_data = (unsigned char*)malloc(length_Y + length_Cb + length_Cr); + if (copy_data == NULL) { + GST_ERROR_OBJECT(camerasrc, "New buffer data ALLOC FAILED"); + gst_camerasrc_error_handler(camerasrc, CAMERASRC_ERR_ALLOCATION); + return FALSE; + } + + offset_Cb = CAMERASRC_ALIGN(length_Y, ALIGN_SIZE_I420); + offset_Cr = offset_Cb + CAMERASRC_ALIGN(length_Cb, ALIGN_SIZE_I420); + + memcpy(copy_data, base_buffer, length_Y); + memcpy(copy_data + length_Y, base_buffer + offset_Cb, length_Cb); + memcpy(copy_data + length_Y + length_Cb, base_buffer + offset_Cr, length_Cr); + + *new_buffer = copy_data; + *new_buffer_length = length_Y + length_Cb + length_Cr; + + GST_DEBUG_OBJECT(camerasrc, "Total(0x%x), I420(S420) length Y(0x%x),Cb(0x%x),Cr(0x%x), offset Cb(0x%x),Cr(0x%x)", + *new_buffer_length, length_Y, length_Cb, length_Cr, offset_Cb, offset_Cr); + break; + } + case GST_MAKE_FOURCC('N','V','1','2'): + case GST_MAKE_FOURCC('S','N','1','2'): + { + guint length_CbCr = 0; + guint offset_CbCr = 0; + + length_Y = width * height; + length_CbCr = (width * height) >> 1; + + copy_data = (unsigned char*)malloc(length_Y + length_CbCr); + if (copy_data == NULL) { + GST_ERROR_OBJECT(camerasrc, "New buffer data ALLOC FAILED"); + gst_camerasrc_error_handler(camerasrc, CAMERASRC_ERR_ALLOCATION); + return FALSE; + } + + offset_CbCr = CAMERASRC_ALIGN(length_Y, ALIGN_SIZE_NV12); + + memcpy(copy_data, base_buffer, length_Y); + memcpy(copy_data + length_Y, base_buffer + offset_CbCr, length_CbCr); + + *new_buffer = copy_data; + *new_buffer_length = length_Y + length_CbCr; + + GST_DEBUG_OBJECT(camerasrc, "Total(0x%x), NV12(SN12) length Y(0x%x),CbCr(0x%x), offset CbCr(0x%x)", + *new_buffer_length, length_Y, length_CbCr, offset_CbCr); + break; + } + default: + { + char *pfourcc = (char*)&fourcc; + GST_WARNING_OBJECT(camerasrc, "Unknown fourcc(%c%c%c%c)", + pfourcc[0], pfourcc[1], pfourcc[2], pfourcc[3]); + *new_buffer = NULL; + *new_buffer_length = 0; + return FALSE; + } + } + + GST_DEBUG_OBJECT(camerasrc, "Done."); + + return TRUE; +} + + +static gboolean gst_camerasrc_get_caps_info(GstCameraSrc *camerasrc, GstCaps *caps, guint *size) +{ + gint fps_n = 0; + gint fps_d = 0; + gint w = 0; + gint h = 0; + gint rot = 0; + gchar *caps_string = NULL; + const gchar *mimetype; + const GValue *framerate; + GstStructure *structure = NULL; + + GST_INFO_OBJECT(camerasrc, "ENTERED Collect data for given caps.(caps:%x)", caps); + + structure = gst_caps_get_structure(caps, 0); + + if (!gst_structure_get_int(structure, "width", &w)) { + goto _caps_info_failed; + } + + if (!gst_structure_get_int(structure, "height", &h)) { + goto _caps_info_failed; + } + + if (!gst_structure_get_int(structure, "rotate", &rot)) { + GST_WARNING_OBJECT(camerasrc, "Failed to get rotate info in caps. set default 0."); + camerasrc->use_rotate_caps = FALSE; + } else { + GST_INFO_OBJECT(camerasrc, "Succeed to get rotate[%d] info in caps", rot); + camerasrc->use_rotate_caps = TRUE; + } + + /* set default size if there is no capsfilter */ + if (w == 1) { + w = _DEFAULT_WIDTH * 2; + } + + if (h == 1) { + h = _DEFAULT_HEIGHT * 2; + } + + camerasrc->width = w; + camerasrc->height = h; + camerasrc->rotate = rot; + + framerate = gst_structure_get_value(structure, "framerate"); + if (!framerate) { + GST_INFO("Set FPS as default"); + + /* set default fps if framerate is not existed in caps */ + fps_n = _DEFAULT_FPS; + fps_d = 1; + } else { + fps_n = gst_value_get_fraction_numerator(framerate); + fps_d = gst_value_get_fraction_denominator(framerate); + + /* numerator and denominator should be bigger than zero */ + if (fps_n <= 0) { + GST_WARNING("numerator of FPS is %d. make it default(15).", fps_n); + fps_n = _DEFAULT_FPS; + } + + if (fps_d <= 0) { + GST_WARNING("denominator of FPS is %d. make it 1.", fps_d); + fps_d = 1; + } + } + + camerasrc->fps = (int)((float)fps_n / (float)fps_d); + + mimetype = gst_structure_get_name (structure); + + *size = 0; + + if (!strcmp(mimetype, "video/x-raw-yuv")) { + gst_structure_get_fourcc(structure, "format", &camerasrc->fourcc); + if (camerasrc->fourcc == 0) { + GST_INFO_OBJECT(camerasrc, "Getting fourcc is zero."); + goto _caps_info_failed; + } + + _gst_camerasrc_get_frame_size(camerasrc->fourcc, w, h, size); + _gst_camerasrc_get_raw_pixel_info(camerasrc->fourcc, &(camerasrc->pix_format), &(camerasrc->colorspace)); + } else if (!strcmp (mimetype, "video/x-raw-rgb")) { + gint depth = 0; + gint endianness = 0; + gint r_mask = 0; + + gst_structure_get_int(structure, "depth", &depth); + gst_structure_get_int(structure, "endianness", &endianness); + gst_structure_get_int(structure, "red_mask", &r_mask); + + switch (depth) { + case 8: /* V4L2_PIX_FMT_RGB332 */ + camerasrc->pix_format = CAMERASRC_PIX_RGGB8; + camerasrc->colorspace = CAMERASRC_COL_RAW; + break; + case 15: /* V4L2_PIX_FMT_RGB555 : V4L2_PIX_FMT_RGB555X */ + camerasrc->pix_format = CAMERASRC_PIX_NONE; + camerasrc->colorspace = CAMERASRC_COL_NONE; + break; + case 16: /* V4L2_PIX_FMT_RGB565 : V4L2_PIX_FMT_RGB565X */ + camerasrc->pix_format = CAMERASRC_PIX_NONE; + camerasrc->colorspace = CAMERASRC_COL_NONE; + break; + case 24: /* V4L2_PIX_FMT_BGR24 : V4L2_PIX_FMT_RGB24 */ + camerasrc->pix_format = CAMERASRC_PIX_NONE; + camerasrc->colorspace = CAMERASRC_COL_NONE; + break; + case 32: /* V4L2_PIX_FMT_BGR32 : V4L2_PIX_FMT_RGB32 */ + camerasrc->pix_format = CAMERASRC_PIX_NONE; + camerasrc->colorspace = CAMERASRC_COL_NONE; + break; + } + } else if (strcmp(mimetype, "video/x-dv") == 0) { /* V4L2_PIX_FMT_DV */ + camerasrc->pix_format = CAMERASRC_PIX_NONE; + camerasrc->colorspace = CAMERASRC_COL_NONE; + } else if (strcmp(mimetype, "image/jpeg") == 0) { /* V4L2_PIX_FMT_JPEG */ + camerasrc->pix_format = CAMERASRC_PIX_RGGB8; /* default */ + camerasrc->colorspace = CAMERASRC_COL_JPEG; + } + + caps_string = gst_caps_to_string(caps); + GST_INFO_OBJECT(camerasrc, "pixformat %d, colorspace %d, size %d, caps : [%s]", + camerasrc->pix_format, camerasrc->colorspace, *size, caps_string); + if (caps_string) { + g_free(caps_string); + caps_string = NULL; + } + + return TRUE; + +_caps_info_failed: + GST_INFO_OBJECT(camerasrc, "Failed to get caps info."); + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + return FALSE; +} + + +static gboolean gst_camerasrc_set_caps(GstBaseSrc *src, GstCaps *caps) +{ + guint size; + GstCameraSrc *camerasrc = NULL; + + camerasrc = GST_CAMERA_SRC(src); + + GST_INFO_OBJECT(camerasrc, "ENTERED"); + + if (camerasrc->mode == VIDEO_IN_MODE_PREVIEW || + camerasrc->mode == VIDEO_IN_MODE_VIDEO) { + GST_INFO_OBJECT(camerasrc, "Proceed set_caps"); + __ta__(" gst_camerasrc_stop", + if (!gst_camerasrc_stop(camerasrc)) { + GST_INFO_OBJECT(camerasrc, "Cam sensor stop failed."); + } + ); + } else if (camerasrc->mode == VIDEO_IN_MODE_CAPTURE) { + GST_ERROR_OBJECT(camerasrc, "A mode of avsystem camera is capture. Not to proceed set_caps."); + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + return FALSE; + } else { + GST_INFO_OBJECT(camerasrc, "A mode of avsystem camera is unknown[%d]. Proceed set_caps.", camerasrc->mode); + } + + /* we want our own v4l2 type of fourcc codes */ + if (!gst_camerasrc_get_caps_info(camerasrc, caps, &size)) { + GST_INFO_OBJECT(camerasrc, "can't get capture information from caps %x", caps); + return FALSE; + } + + __ta__(" gst_camerasrc_start", + if (!gst_camerasrc_start(camerasrc)) { + GST_INFO_OBJECT (camerasrc, "Cam sensor start failed."); + } + ); + + GST_INFO_OBJECT (camerasrc, "LEAVED"); + + return TRUE; +} + + +static void gst_camerasrc_base_init(gpointer klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS(klass); + + GST_DEBUG_CATEGORY_INIT(camerasrc_debug, "camerasrc", 0, "camerasrc element"); + + GST_INFO("ENTERED"); + + gst_element_class_add_pad_template(element_class, gst_static_pad_template_get (&src_factory)); + gst_element_class_set_details(element_class, &camerasrc_details); + + GST_INFO("LEAVED"); +} + + +static void gst_camerasrc_class_init(GstCameraSrcClass *klass) +{ + GObjectClass *gobject_class; + GstElementClass *element_class; + GstBaseSrcClass *basesrc_class; + GstPushSrcClass *pushsrc_class; + + GST_DEBUG("ENTERED"); + + gobject_class = G_OBJECT_CLASS(klass); + element_class = GST_ELEMENT_CLASS(klass); + basesrc_class = GST_BASE_SRC_CLASS(klass); + pushsrc_class = GST_PUSH_SRC_CLASS(klass); + + gobject_class->set_property = gst_camerasrc_set_property; + gobject_class->get_property = gst_camerasrc_get_property; + gobject_class->finalize = gst_camerasrc_finalize; + element_class->change_state = gst_camerasrc_change_state; + basesrc_class->start = gst_camerasrc_src_start; + basesrc_class->stop = gst_camerasrc_src_stop; + basesrc_class->get_caps = gst_camerasrc_get_caps; + basesrc_class->set_caps = gst_camerasrc_set_caps; + basesrc_class->negotiate = gst_camerasrc_negotiate; + pushsrc_class->create = gst_camerasrc_src_create; + + g_object_class_install_property(gobject_class, ARG_REQ_NEGOTIATION, + g_param_spec_boolean("req-negotiation", "Request re-negotiation", + "Request to negotiate while on playing", + FALSE, + G_PARAM_READWRITE)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_HIGH_SPEED_FPS, + g_param_spec_int("high-speed-fps", "Fps for high speed recording", + "If this value is 0, the element doesn't activate high speed recording.", + 0, G_MAXINT, _DEFAULT_HIGH_SPEED_FPS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_AUTO_FPS, + g_param_spec_boolean("fps-auto", "FPS Auto", + "Field for auto fps setting", + _DEFAULT_FPS_AUTO, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_EXT_VIDEO_FD, + g_param_spec_int("extern_videofd", "External video file descriptor", + "External video file descriptor", + _FD_MIN, _FD_MAX, _FD_MIN, + G_PARAM_READWRITE)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_ID, + g_param_spec_int("camera-id", "index number of camera to activate", + "index number of camera to activate", + _FD_MIN, _FD_MAX, 0, + G_PARAM_READWRITE)); + + /*Capture*/ + g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_FOURCC, + g_param_spec_uint("capture-fourcc", "Capture format", + "Fourcc value for capture format", + 0, G_MAXUINT, 0, + G_PARAM_READWRITE)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_QUALITY, + g_param_spec_enum("capture-quality", "Capture quality", + "Quality of capture image (JPEG: 'high', RAW: 'high' or 'low')", + GST_TYPE_CAMERASRC_QUALITY, _DEFAULT_CAP_QUALITY, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_WIDTH, + g_param_spec_int("capture-width", "Capture width", + "Width for camera size to capture", + 0, G_MAXINT, _DEFAULT_CAP_WIDTH, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_HEIGHT, + g_param_spec_int("capture-height", "Capture height", + "Height for camera size to capture", + 0, G_MAXINT, _DEFAULT_CAP_HEIGHT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_INTERVAL, + g_param_spec_int("capture-interval", "Capture interval", + "Interval time to capture (millisecond)", + 0, G_MAXINT, _DEFAULT_CAP_INTERVAL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_COUNT, + g_param_spec_int("capture-count", "Capture count", + "Capture conut for multishot", + 1, G_MAXINT, _DEFAULT_CAP_COUNT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_JPG_QUALITY, + g_param_spec_int("capture-jpg-quality", "JPEG Capture compress ratio", + "Quality of capture image compress ratio", + 1, 100, _DEFAULT_CAP_JPG_QUALITY, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_PROVIDE_EXIF, + g_param_spec_boolean("provide-exif", "Whether EXIF is provided", + "Does capture provide EXIF?", + _DEFAULT_CAP_PROVIDE_EXIF, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_SIGNAL_STILLCAPTURE, + g_param_spec_boolean("signal-still-capture", "Signal still capture", + "Send a signal before pushing the buffer", + _DEFAULT_SIGNAL_STILL_CAPTURE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_USE_PAD_ALLOC, + g_param_spec_boolean("use-pad-alloc", "Use pad alloc", + "Use gst_pad_alloc_buffer() for image frame buffer", + _DEFAULT_USE_PAD_ALLOC, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_NUM_ALLOC_BUF, + g_param_spec_int("num-alloc-buf", "Number alloced buffer", + "Number of buffer to alloc using gst_pad_alloc_buffer()", + 1, _MAX_NUM_ALLOC_BUF, _DEFAULT_NUM_ALLOC_BUF, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_OPERATION_STATUS, + g_param_spec_int("operation-status", "Check operation status of camerasrc", + "This value has bit flags that describe current operation status.", + G_MININT, G_MAXINT, 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_HOLD_AF_AFTER_CAPTURE, + g_param_spec_boolean("hold-af-after-capturing", "Hold af after capturing", + "Hold af position after capturing", + FALSE, G_PARAM_READWRITE)); + + g_object_class_install_property(gobject_class, ARG_FAKE_ESD, + g_param_spec_boolean("fake-esd", "Fake ESD generate", + "Generate fake esd situation", + FALSE, G_PARAM_READWRITE)); + + g_object_class_install_property(gobject_class, ARG_SENSOR_MODE, + g_param_spec_int("sensor-mode", "Sensor mode", + "Set sensor mode as CAMERA or MOVIE(camcorder)", + CAMERASRC_SENSOR_MODE_CAMERA, CAMERASRC_SENSOR_MODE_MOVIE, CAMERASRC_SENSOR_MODE_CAMERA, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_VFLIP, + g_param_spec_boolean("vflip", "Flip vertically", + "Flip camera input vertically", + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_HFLIP, + g_param_spec_boolean("hflip", "Flip horizontally", + "Flip camera input horizontally", + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstCameraSrc::still-capture: + * @camerasrc: the camerasrc instance + * @buffer: the buffer that will be pushed - Main + * @buffer: the buffer that will be pushed - Thumbnail + * @buffer: the buffer that will be pushed - Screennail + * + * This signal gets emitted before sending the buffer. + */ + gst_camerasrc_signals[SIGNAL_STILL_CAPTURE] = + g_signal_new("still-capture", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GstCameraSrcClass, still_capture), + NULL, + NULL, + gst_camerasrc_VOID__OBJECT_OBJECT, + G_TYPE_NONE, + 3, /* Number of parameter */ + GST_TYPE_BUFFER, /* Main image buffer */ + GST_TYPE_BUFFER, /* Thumbnail image buffer */ + GST_TYPE_BUFFER); /* Screennail image buffer */ + + + /* wh01.cho:req-negotiation:+:To notify user of camerasrc, after changing resolution. */ + /** + * GstCameraSrc::nego-complete: + * @camerasrc: the camerasrc instance + * @start: when re-negotiation is finished. + * + */ + gst_camerasrc_signals[SIGNAL_NEGO_COMPLETE] = + g_signal_new("nego-complete", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GstCameraSrcClass, nego_complete), + NULL, + NULL, + gst_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + GST_DEBUG("LEAVED"); +} + + +static void gst_camerasrc_init(GstCameraSrc *camerasrc, GstCameraSrcClass *klass) +{ + GST_DEBUG_OBJECT (camerasrc, "ENTERED"); + + camerasrc->v4l2_handle = NULL; + camerasrc->mode = VIDEO_IN_MODE_UNKNOWN; + camerasrc->firsttime = TRUE; + camerasrc->main_buf_sz = 0; + camerasrc->cap_count_current = -1; + camerasrc->cap_count_reverse = _DEFAULT_CAP_COUNT; + camerasrc->cap_next_time = 0UL; + camerasrc->command_list = g_queue_new (); + camerasrc->cond = g_cond_new (); + camerasrc->mutex = g_mutex_new (); + + /*camera*/ + camerasrc->width = _DEFAULT_WIDTH; + camerasrc->height = _DEFAULT_HEIGHT; + camerasrc->fps = _DEFAULT_FPS; + camerasrc->rotate = 0; + camerasrc->use_rotate_caps = FALSE; + camerasrc->high_speed_fps = _DEFAULT_HIGH_SPEED_FPS; + camerasrc->fps_auto = _DEFAULT_FPS_AUTO; + camerasrc->pix_format = _DEFAULT_PIX_FORMAT; + camerasrc->colorspace = _DEFAULT_COLORSPACE; + camerasrc->fourcc = _DEFAULT_FOURCC; + camerasrc->req_negotiation = FALSE; + camerasrc->num_live_buffers = _DEFAULT_NUM_LIVE_BUFFER; + camerasrc->buffer_count = _DEFAULT_BUFFER_COUNT; + camerasrc->buffer_running = _DEFAULT_BUFFER_RUNNING; + camerasrc->buffer_lock = g_mutex_new (); + camerasrc->buffer_cond = g_cond_new (); + camerasrc->bfirst = TRUE; + camerasrc->pad_alloc_list = g_queue_new (); + camerasrc->pad_alloc_mutex = g_mutex_new (); + camerasrc->current_buffer_data_index = 0; + camerasrc->sensor_mode = CAMERASRC_SENSOR_MODE_CAMERA; + camerasrc->vflip = 0; + camerasrc->hflip = 0; + + /* Initialize usr buffer to be alloced by sink to NULL */ + { + int i = 0; + for(i = 0; i < MAX_USR_BUFFER_NUM; i++) { + camerasrc->usr_buffer[i] = NULL; + } + } + camerasrc->use_pad_alloc = FALSE; + camerasrc->num_alloc_buf = 0; + camerasrc->camera_id = _DEFAULT_CAMERA_ID; + + /*capture*/ + camerasrc->cap_fourcc = _DEFAULT_FOURCC; + camerasrc->cap_quality = _DEFAULT_CAP_QUALITY; + camerasrc->cap_width = _DEFAULT_CAP_WIDTH; + camerasrc->cap_height = _DEFAULT_CAP_HEIGHT; + camerasrc->cap_interval = _DEFAULT_CAP_INTERVAL; + camerasrc->cap_count = _DEFAULT_CAP_COUNT; + camerasrc->cap_jpg_quality = _DEFAULT_CAP_JPG_QUALITY; + camerasrc->cap_provide_exif = _DEFAULT_CAP_PROVIDE_EXIF; + camerasrc->signal_still_capture = _DEFAULT_SIGNAL_STILL_CAPTURE; + camerasrc->hold_af_after_capturing = FALSE; + camerasrc->create_jpeg = FALSE; + camerasrc->jpg_mutex = g_mutex_new(); + camerasrc->first_invokation = TRUE; + camerasrc->external_videofd = _FD_DEFAULT; + +#ifdef _SPEED_UP_RAW_CAPTURE + camerasrc->cap_stream_diff = FALSE; +#endif /* _SPEED_UP_RAW_CAPTURE */ + + /* we operate in time */ + gst_base_src_set_format(GST_BASE_SRC(camerasrc), GST_FORMAT_TIME); + gst_base_src_set_live(GST_BASE_SRC(camerasrc), TRUE); + gst_base_src_set_do_timestamp(GST_BASE_SRC(camerasrc), TRUE); + + GST_DEBUG("LEAVED"); +} + + +static void GenerateYUV420BlackFrame(unsigned char *buf, int buf_size, int width, int height) +{ + int i; + int y_len = 0; + int yuv_len = 0; + + y_len = width * height; + yuv_len = (width * height * 3) >> 1; + + if (buf_size < yuv_len) { + return; + } + + if (width % 4) { + for (i = 0 ; i < y_len ; i++) { + buf[i] = 0x10; + } + + for ( ; i < yuv_len ; i++) { + buf[i] = 0x80; + } + } else { + /* faster way */ + int *ibuf = NULL; + short *sbuf = NULL; + ibuf = (int *)buf; + + for (i = 0 ; i < y_len / 4 ; i++) { + ibuf[i] = 0x10101010; /* set YYYY */ + } + + sbuf = (short*)(&buf[y_len]); + + for (i = 0 ; i < (yuv_len - y_len) / 2 ; i++) { + sbuf[i] = 0x8080; /* set UV */ + } + } + + return; +} + + +static void GenerateYUV422BlackFrame(unsigned char *buf, int buf_size, int width, int height) +{ + /* YUYV */ + int i; + int yuv_len = 0; + int *ibuf = NULL; + + ibuf = (int *)buf; + + yuv_len = (width * height * 2); + + if (buf_size < yuv_len) { + return; + } + + for (i = 0 ; i < yuv_len / 4 ; i++) { + ibuf[i] = 0x80108010; /* YUYV -> 0xVYUY */ + } + + return; +} + + +static gboolean GenerateST12BlackFrame(GstCameraSrc *camerasrc, unsigned char *buf, int buf_size, int width, int height) +{ + int i; + int y_len = 0; + int yuv_len = 0; + int ystride = 0; + int uvstride = 0; + int yelevation = 0; + int uvelevation = 0; + gboolean boolret = TRUE; + unsigned char *blkframe = NULL; + + /* Calculation of stride. need to be confirmation from driver team */ + if ((width % 128) != 0 ) { + ystride = width + (128 - (width % 128)); + uvstride = ystride; + } else { + ystride = width; + uvstride = width; + } + + /* Calculation of elevation. need to be confirmation from driver team */ + /* Y elevation */ + if ((height % 32) != 0) { + yelevation= height + (32 - (height % 32)); + } else { + yelevation = height; + } + /* UV elevation */ + if (((height >>1) % 32) != 0) { + uvelevation = (height >> 1) + (32 - ((height >> 1) % 32)); + } else { + uvelevation = (height >> 1); + } + + GST_DEBUG("ystride = %d and uvstride = %d", ystride, uvstride); + GST_DEBUG("yelevation = %d and uvelevation = %d", yelevation, uvelevation); + + y_len = ystride * yelevation; + yuv_len = y_len + uvstride * uvelevation; + + /* Generate black frame */ + blkframe = (unsigned char*)g_malloc(yuv_len); + + if (blkframe == NULL) { + GST_ERROR ("ST12Blk: Failed to allocate memory..."); + boolret = FALSE; + goto FINISH; + } + + for (i = 0 ; i < y_len ; i++) { + blkframe [i] = 0x10; + } + + for (; i < yuv_len ; i++) { + blkframe [i] = 0x80; + } + + +FINISH: + if (blkframe != NULL) { + g_free (blkframe); + } + + return boolret; + +} + + +static unsigned long gst_get_current_time(void) +{ + struct timeval lc_time; + + gettimeofday(&lc_time, NULL); + + return ((unsigned long)(lc_time.tv_sec * 1000L) + (unsigned long)(lc_time.tv_usec / 1000L)); +} + + +#if _ENABLE_CAMERASRC_DEBUG +#include <stdio.h> +static int __util_write_file(char *filename, void *data, int size) +{ + FILE *fp = NULL; + + fp = fopen(filename, "wb"); + if (!fp) { + return FALSE; + } + + fwrite(data, 1, size, fp); + fclose(fp); + + return TRUE; +} +#endif + + +static gboolean plugin_init(GstPlugin *plugin) +{ + gboolean error; + + error = gst_element_register(plugin, "camerasrc", GST_RANK_PRIMARY + 100, GST_TYPE_CAMERA_SRC); + + return error; +} + + +GST_PLUGIN_DEFINE(GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "camerasrc", + "Camera source plug-in", + plugin_init, + PACKAGE_VERSION, + "LGPL", + "Samsung Electronics Co", + "http://www.samsung.com") + +/* GstURIHandler interface */ +static GstURIType gst_camerasrc_uri_get_type (void) +{ + return GST_URI_SRC; +} + +static gchar ** gst_camerasrc_uri_get_protocols (void) +{ + static gchar *protocols[] = { (char *) "camera", NULL }; + return protocols; +} + +static const gchar * gst_camerasrc_uri_get_uri (GstURIHandler * handler) +{ + GstCameraSrc *camerasrc = GST_CAMERA_SRC (handler); + + gchar uri[256]; + g_snprintf (uri, sizeof (uri), "camera://0"); + return g_intern_string (uri); +} + +static gboolean gst_camerasrc_uri_set_uri (GstURIHandler * handler, const gchar * uri) +{ + GstCameraSrc *camerasrc = GST_CAMERA_SRC (handler); + const gchar *device = "0"; + if (strcmp (uri, "camera://") != 0) { + device = uri + 9; + } + g_object_set (camerasrc, "camera-id", atoi(device), NULL); + + return TRUE; +} + + +static void gst_camerasrc_uri_handler_init (gpointer g_iface, gpointer iface_data) +{ + GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface; + + iface->get_type = gst_camerasrc_uri_get_type; + iface->get_protocols = gst_camerasrc_uri_get_protocols; + iface->get_uri = gst_camerasrc_uri_get_uri; + iface->set_uri = gst_camerasrc_uri_set_uri; +} +/* EOF */ diff --git a/camerasrc/src/gstcamerasrccolorbalance.c b/camerasrc/src/gstcamerasrccolorbalance.c new file mode 100644 index 0000000..242f9db --- /dev/null +++ b/camerasrc/src/gstcamerasrccolorbalance.c @@ -0,0 +1,117 @@ +/* + * camerasrc + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang <jm80.yang@samsung.com> + * + * 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.1 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., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/gst.h> +#include "gstcamerasrccolorbalance.h" + +GST_BOILERPLATE( GstCameraSrcColorBalanceChannel, + gst_camerasrc_color_balance_channel, + GstColorBalanceChannel, + GST_TYPE_COLOR_BALANCE_CHANNEL ); + +#ifndef GST_CAT_DEFAULT +GST_DEBUG_CATEGORY_EXTERN(camerasrc_debug); +#define GST_CAT_DEFAULT camerasrc_debug +#endif /* GST_CAT_DEFAULT */ + +static void +gst_camerasrc_color_balance_channel_base_init( gpointer g_class ) +{ +} + +static void +gst_camerasrc_color_balance_channel_class_init( GstCameraSrcColorBalanceChannelClass* klass ) +{ +} + +static void +gst_camerasrc_color_balance_channel_init( GstCameraSrcColorBalanceChannel* camerasrc_color_channel, GstCameraSrcColorBalanceChannelClass* klass ) +{ + camerasrc_color_channel->id = (guint32) - 1; +} + +static G_GNUC_UNUSED gboolean +gst_camerasrc_color_balance_contains_channel( GstCameraSrc* camerasrc, GstCameraSrcColorBalanceChannel* camerasrc_color_channel ) +{ + const GList *item; + + for( item = camerasrc->colors ; item != NULL ; item = item->next ) + { + if (item->data == camerasrc_color_channel) + return TRUE; + } + + return FALSE; +} + +const GList * +gst_camerasrc_color_balance_list_channels( GstCameraSrc* camerasrc ) +{ + return camerasrc->colors; +} + +void +gst_camerasrc_color_balance_set_value( GstCameraSrc* camerasrc, GstColorBalanceChannel* color_channel, gint value ) +{ + int error = CAMERASRC_ERR_UNKNOWN; + + GstCameraSrcColorBalanceChannel *camerasrc_color_channel = GST_CAMERASRC_COLOR_BALANCE_CHANNEL( color_channel ); + + /* assert that we're opened and that we're using a known item */ + g_return_if_fail( camerasrc ); + g_return_if_fail( gst_camerasrc_color_balance_contains_channel( camerasrc, camerasrc_color_channel ) ); + + error = camerasrc_set_control( camerasrc->v4l2_handle, camerasrc_color_channel->id, value ); + + if( error != CAMERASRC_SUCCESS ) + { + GST_WARNING("Failed to Set ColorBalance[%s],value[%d]", camerasrc_color_channel->parent.label, value); + } +} + +gint +gst_camerasrc_color_balance_get_value( GstCameraSrc* camerasrc, GstColorBalanceChannel* color_channel ) +{ + int error, value; + GstCameraSrcColorBalanceChannel *camerasrc_color_channel = GST_CAMERASRC_COLOR_BALANCE_CHANNEL( color_channel ); + + /* assert that we're opened and that we're using a known item */ + g_return_val_if_fail( camerasrc, FALSE ); + g_return_val_if_fail( gst_camerasrc_color_balance_contains_channel( camerasrc, camerasrc_color_channel ), FALSE ); + + error = camerasrc_get_control( camerasrc->v4l2_handle, camerasrc_color_channel->id, &value ); + + if( error != CAMERASRC_SUCCESS ) + { + GST_WARNING("Failed to Get ColorBalance[%s].", camerasrc_color_channel->parent.label); + return FALSE; + } + + return value; +} + + diff --git a/camerasrc/src/gstcamerasrccontrol.c b/camerasrc/src/gstcamerasrccontrol.c new file mode 100644 index 0000000..2cb910f --- /dev/null +++ b/camerasrc/src/gstcamerasrccontrol.c @@ -0,0 +1,1098 @@ +/* + * camerasrc + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang <jm80.yang@samsung.com> + * + * 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.1 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., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/gst.h> +#include "gstcamerasrccontrol.h" +#include "camerasrc-common.h" + +#define gst_camerasrc_debug(fmt, args...) GST_INFO(fmt, ##args) + +#define CAMERA_CONTROL_AF_STOP_TOTALTIME 2000000 +#define CAMERA_CONTROL_AF_STOP_INTERVAL 20000 + +GST_BOILERPLATE (GstCamerasrcControlChannel, + gst_camerasrc_control_channel, + GstCameraControlChannel, GST_TYPE_CAMERA_CONTROL_CHANNEL); + + +static void +gst_camerasrc_control_channel_base_init( gpointer g_class ) +{ + gst_camerasrc_debug( "" ); +} + +static void +gst_camerasrc_control_channel_class_init( GstCamerasrcControlChannelClass* klass ) +{ + gst_camerasrc_debug( "" ); +} + +static void +gst_camerasrc_control_channel_init( GstCamerasrcControlChannel* control_channel, GstCamerasrcControlChannelClass* klass ) +{ + gst_camerasrc_debug( "" ); + + control_channel->id = (guint32) - 1; +} + +static G_GNUC_UNUSED gboolean +gst_camerasrc_control_contains_channel( GstCameraSrc* camerasrc, GstCamerasrcControlChannel* camerasrc_control_channel ) +{ + gst_camerasrc_debug( "" ); + + const GList* item; + + for( item = camerasrc->camera_controls ; item != NULL ; item = item->next ) + { + if( item->data == camerasrc_control_channel ) + { + return TRUE; + } + } + + return FALSE; +} + +const GList* +gst_camerasrc_control_list_channels( GstCameraSrc* camerasrc ) +{ + gst_camerasrc_debug( "" ); + + return camerasrc->camera_controls; +} + +gboolean +gst_camerasrc_control_set_value( GstCameraSrc* camerasrc, GstCameraControlChannel *control_channel, gint value ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + GstCamerasrcControlChannel *camerasrc_control_channel = GST_CAMERASRC_CONTROL_CHANNEL( control_channel ); + + g_return_val_if_fail( camerasrc, FALSE ); + g_return_val_if_fail( gst_camerasrc_control_contains_channel( camerasrc, camerasrc_control_channel ), FALSE ); + + error = camerasrc_set_control( camerasrc->v4l2_handle, camerasrc_control_channel->id, value ); + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to set value. Ctrl-id [%d], value [%d], err code [%d]", camerasrc_control_channel->id, value, error ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_get_value( GstCameraSrc* camerasrc, GstCameraControlChannel *control_channel, gint *value ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + GstCamerasrcControlChannel *camerasrc_control_channel = GST_CAMERASRC_CONTROL_CHANNEL( control_channel ); + + g_return_val_if_fail( camerasrc, FALSE ); + g_return_val_if_fail( gst_camerasrc_control_contains_channel( camerasrc, camerasrc_control_channel ), FALSE ); + + error = camerasrc_get_control( camerasrc->v4l2_handle, camerasrc_control_channel->id, value ); + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to get control value. Ctrl-id [%d], err code[%x]", camerasrc_control_channel->id, error ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_set_exposure( GstCameraSrc* camerasrc, gint type, gint value1, gint value2 ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + camerasrc_frac_t frac; + + g_return_val_if_fail( camerasrc, FALSE ); + + /* TODO : F number */ + switch( type ) + { + case GST_CAMERA_CONTROL_F_NUMBER: + error = CAMERASRC_SUCCESS; + break; + case GST_CAMERA_CONTROL_SHUTTER_SPEED: + frac.numerator = value1; + frac.denominator = value2; + __ta__(" camerasrc_set_shutter_speed", + error = camerasrc_set_shutter_speed( camerasrc->v4l2_handle, frac ); + ) + break; + case GST_CAMERA_CONTROL_ISO: + __ta__(" camerasrc_set_iso_value", + error = camerasrc_set_control( camerasrc->v4l2_handle, CAMERASRC_CTRL_ISO, value1 ); + ) + break; + case GST_CAMERA_CONTROL_PROGRAM_MODE: + __ta__(" camerasrc_set_control", + error = camerasrc_set_control( camerasrc->v4l2_handle, CAMERASRC_CTRL_PROGRAM_MODE, value1 ); + ) + break; + case GST_CAMERA_CONTROL_EXPOSURE_MODE: + __ta__(" camerasrc_set_exposure_mode", + error = camerasrc_set_control( camerasrc->v4l2_handle, CAMERASRC_CTRL_PHOTOMETRY, value1 ); + ) + break; + case GST_CAMERA_CONTROL_EXPOSURE_VALUE: + frac.numerator = value1; + frac.denominator = value2; + __ta__(" camerasrc_set_exposure_value", + error = camerasrc_set_exposure_value( camerasrc->v4l2_handle, frac ); + ) + break; + default: + gst_camerasrc_debug( "Not supported type." ); + return FALSE; + } + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to set exposure. Type[%d],value1[%d],value2[%d],err code[%x]", type, value1, value2, error ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_get_exposure( GstCameraSrc* camerasrc, gint type, gint* value1, gint* value2 ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + camerasrc_frac_t frac; + + g_return_val_if_fail( camerasrc, FALSE ); + + /* TODO : F number */ + switch( type ) + { + case GST_CAMERA_CONTROL_F_NUMBER: + break; + case GST_CAMERA_CONTROL_SHUTTER_SPEED: + error = camerasrc_get_shutter_speed( camerasrc->v4l2_handle, &frac ); + if( error == CAMERASRC_SUCCESS ) + { + *value1 = frac.numerator; + *value2 = frac.denominator; + } + break; + case GST_CAMERA_CONTROL_ISO: + error = camerasrc_get_control( camerasrc->v4l2_handle, CAMERASRC_CTRL_ISO, value1 ); + break; + case GST_CAMERA_CONTROL_PROGRAM_MODE: + error = camerasrc_get_control( camerasrc->v4l2_handle, CAMERASRC_CTRL_PROGRAM_MODE, value1 ); + break; + case GST_CAMERA_CONTROL_EXPOSURE_MODE: + error = camerasrc_get_control( camerasrc->v4l2_handle, CAMERASRC_CTRL_PHOTOMETRY, value1 ); + break; + case GST_CAMERA_CONTROL_EXPOSURE_VALUE: + error = camerasrc_get_exposure_value( camerasrc->v4l2_handle, &frac ); + if( error == CAMERASRC_SUCCESS ) + { + *value1 = frac.numerator; + *value2 = frac.denominator; + } + break; + default: + gst_camerasrc_debug( "Not supported type." ); + return FALSE; + } + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to get exposure. Type [%d]", type ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_set_capture_mode( GstCameraSrc* camerasrc, gint type, gint value ) +{ + /* TODO : single/multishot select(capture mode), output mode, frame count, JPEG quality */ + + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + switch( type ) + { + case GST_CAMERA_CONTROL_CAPTURE_MODE: + break; + case GST_CAMERA_CONTROL_OUTPUT_MODE: + break; + case GST_CAMERA_CONTROL_FRAME_COUNT: + break; + case GST_CAMERA_CONTROL_JPEG_QUALITY: + break; + default: + gst_camerasrc_debug( "Not supported type." ); + return FALSE; + } + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to set capture mode. Type[%d],value[%d],err code[%x]", type, value, error ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_get_capture_mode( GstCameraSrc* camerasrc, gint type, gint *value ) +{ + /* TODO : single/multishot select(capture mode), output mode, frame count, JPEG quality */ + + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + switch( type ) + { + case GST_CAMERA_CONTROL_CAPTURE_MODE: + break; + case GST_CAMERA_CONTROL_OUTPUT_MODE: + break; + case GST_CAMERA_CONTROL_FRAME_COUNT: + break; + case GST_CAMERA_CONTROL_JPEG_QUALITY: + break; + default: + gst_camerasrc_debug( "Not supported type." ); + return FALSE; + } + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to set capture mode. Type[%d],value[%d],err code[%x]", type, value, error ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_set_strobe( GstCameraSrc* camerasrc, gint type, gint value ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + switch( type ) + { + case GST_CAMERA_CONTROL_STROBE_MODE: + error = camerasrc_set_strobe_mode( camerasrc->v4l2_handle, value ); + break; + case GST_CAMERA_CONTROL_STROBE_CONTROL: + case GST_CAMERA_CONTROL_STROBE_CAPABILITIES: + case GST_CAMERA_CONTROL_STROBE_STATUS: + case GST_CAMERA_CONTROL_STROBE_EV: + default: + gst_camerasrc_debug( "Not supported type[%d], return CAMERASRC_ERR_DEVICE_NOT_SUPPORT.", type ); + error = CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + break; + } + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to set strobe. Type[%d],value[%d],err code[%x]", type, value, error ); + return FALSE; + } + + gst_camerasrc_debug( "Succeed to set strobe. Type[%d],value[%d]", type, value ); + + return TRUE; +} + +gboolean +gst_camerasrc_control_get_strobe( GstCameraSrc* camerasrc, gint type, gint* value ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + switch( type ) + { + case GST_CAMERA_CONTROL_STROBE_MODE: + error = camerasrc_get_strobe_mode( camerasrc->v4l2_handle, (camerasrc_strobe_mode_t *)value ); + break; + case GST_CAMERA_CONTROL_STROBE_CONTROL: + case GST_CAMERA_CONTROL_STROBE_CAPABILITIES: + case GST_CAMERA_CONTROL_STROBE_STATUS: + case GST_CAMERA_CONTROL_STROBE_EV: + default: + gst_camerasrc_debug( "Not supported type[%d].", type ); + error = CAMERASRC_ERR_DEVICE_NOT_SUPPORT; + break; + } + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to get strobe. Type[%d],err code[%x]", type, error ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_set_detect( GstCameraSrc* camerasrc, gint type, gint value ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + /* TODO : detection number, focus select, select number, detect status */ + switch( type ) + { + case GST_CAMERA_CONTROL_FACE_DETECT_MODE: + if( value == 0 ) + { + error = camerasrc_stop_facedetection(camerasrc->v4l2_handle ); + } + else if( value == 1 ) + { + error = camerasrc_start_facedetection(camerasrc->v4l2_handle ); + } + break; + case GST_CAMERA_CONTROL_FACE_DETECT_NUMBER: + break; + case GST_CAMERA_CONTROL_FACE_FOCUS_SELECT: + break; + case GST_CAMERA_CONTROL_FACE_SELECT_NUMBER: + break; + case GST_CAMERA_CONTROL_FACE_DETECT_STATUS: + break; + default: + gst_camerasrc_debug( "Not supported type." ); + return FALSE; + } + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to set detect. Type[%d],value[%d],err code[%x]", type, value, error ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_get_detect( GstCameraSrc* camerasrc, gint type, gint *value ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + /* TODO : detection number, focus select, select number, detect status */ + switch( type ) + { + case GST_CAMERA_CONTROL_FACE_DETECT_MODE: + error = camerasrc_get_facedetection(camerasrc->v4l2_handle, value); + break; + case GST_CAMERA_CONTROL_FACE_DETECT_NUMBER: + break; + case GST_CAMERA_CONTROL_FACE_FOCUS_SELECT: + break; + case GST_CAMERA_CONTROL_FACE_SELECT_NUMBER: + break; + case GST_CAMERA_CONTROL_FACE_DETECT_STATUS: + break; + default: + gst_camerasrc_debug( "Not supported type." ); + return FALSE; + } + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to get detect. Type[%d],err code[%x]", type, error ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_set_zoom( GstCameraSrc* camerasrc, gint type, gint value ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + switch( type ) + { + case GST_CAMERA_CONTROL_DIGITAL_ZOOM: + error = camerasrc_set_control (camerasrc->v4l2_handle, CAMERASRC_CTRL_DIGITAL_ZOOM, value ); + break; + case GST_CAMERA_CONTROL_OPTICAL_ZOOM: + error = camerasrc_set_control (camerasrc->v4l2_handle, CAMERASRC_CTRL_OPTICAL_ZOOM, value ); + break; + default: + gst_camerasrc_debug( "Not supported type." ); + return FALSE; + } + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to set zoom. Type[%d],value[%d],err code[%x]", type, value, error ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_get_zoom( GstCameraSrc* camerasrc, gint type, gint *value ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + switch( type ) + { + case GST_CAMERA_CONTROL_DIGITAL_ZOOM: + error = camerasrc_get_control (camerasrc->v4l2_handle, CAMERASRC_CTRL_DIGITAL_ZOOM, value ); + break; + case GST_CAMERA_CONTROL_OPTICAL_ZOOM: + error = camerasrc_get_control (camerasrc->v4l2_handle, CAMERASRC_CTRL_OPTICAL_ZOOM, value ); + break; + default: + gst_camerasrc_debug( "Not supported type." ); + return FALSE; + } + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to get zoom. Type[%d],err code[%x]", type, error ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_set_focus( GstCameraSrc* camerasrc, gint focus_mode, gint focus_range ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + error = camerasrc_init_autofocusing_mode( camerasrc->v4l2_handle, focus_mode, focus_range ); + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to set AF mode." ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_get_focus( GstCameraSrc* camerasrc, gint *focus_mode, gint *focus_range ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + error = camerasrc_get_autofocusing_mode(camerasrc->v4l2_handle, (camerasrc_af_mode_t *)focus_mode, (camerasrc_af_scan_range_t *)focus_range); + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to get AF mode." ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_start_auto_focus( GstCameraSrc* camerasrc ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + MMTA_ACUM_ITEM_BEGIN( "AutoFocus operating time", FALSE ); + + error = camerasrc_start_autofocusing( camerasrc->v4l2_handle ); + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to start AF. error[%x]", error ); + return FALSE; + } + else + { + gst_camerasrc_debug( "Succeeded to start AF." ); + return TRUE; + } +} + +gboolean +gst_camerasrc_control_stop_auto_focus( GstCameraSrc* camerasrc ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + int try_count = 0; + camerasrc_auto_focus_status_t af_status = CAMERASRC_AUTO_FOCUS_STATUS_RELEASED; + + g_return_val_if_fail( camerasrc, FALSE ); + + error = camerasrc_stop_autofocusing( camerasrc->v4l2_handle ); + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to stop autofocus." ); + return FALSE; + } + + while( try_count++ < CAMERA_CONTROL_AF_STOP_TOTALTIME/CAMERA_CONTROL_AF_STOP_INTERVAL ) + { + error = camerasrc_get_autofocusing_status( camerasrc->v4l2_handle, &af_status ); + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to get af status.(%x)", error ); + return FALSE; + } + + if( af_status == CAMERASRC_AUTO_FOCUS_STATUS_RELEASED ) + { + gst_camerasrc_debug( "AF Stop done. try count[%d]", try_count ); + break; + } + + usleep( CAMERA_CONTROL_AF_STOP_INTERVAL ); + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_set_focus_level( GstCameraSrc* camerasrc, gint focus_level ) +{ + /* TODO : */ + + gst_camerasrc_debug( "Not support" ); + return FALSE; +} + +gboolean +gst_camerasrc_control_get_focus_level( GstCameraSrc* camerasrc, gint *focus_level ) +{ + /* TODO : */ + + gst_camerasrc_debug( "Not support" ); + return FALSE; +} + +gboolean +gst_camerasrc_control_set_auto_focus_area( GstCameraSrc* camerasrc, GstCameraControlRectType rect ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + camerasrc_rect_t camerasrc_rect = { 0, 0, 0, 0 }; + + g_return_val_if_fail( camerasrc, FALSE ); + + if (camerasrc->camera_id == CAMERASRC_DEV_ID_SECONDARY) { + GST_INFO_OBJECT(camerasrc, "It's secondary camera. Skip setting..."); + return TRUE; + } + + camerasrc_rect.x = rect.x; + camerasrc_rect.y = rect.y; + camerasrc_rect.width = rect.width; + camerasrc_rect.height = rect.height; + + GST_INFO_OBJECT(camerasrc, "Set AF area %d,%d,%dx%d", + camerasrc_rect.x, camerasrc_rect.y, + camerasrc_rect.width, camerasrc_rect.height); + + error = camerasrc_set_autofocusing_area( camerasrc->v4l2_handle, &camerasrc_rect ); + + if( error != CAMERASRC_SUCCESS ) + { + GST_ERROR_OBJECT(camerasrc, "Failed to set auto focus area."); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_get_auto_focus_area( GstCameraSrc* camerasrc, GstCameraControlRectType* rect ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + camerasrc_rect_t camerasrc_rect = { 0, 0, 0, 0 }; + + g_return_val_if_fail( camerasrc, FALSE ); + g_return_val_if_fail( rect, FALSE ); + + error = camerasrc_get_autofocusing_area( camerasrc->v4l2_handle, &camerasrc_rect ); + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to get auto focus area." ); + + rect->x = rect->y = -1; + rect->width = rect->height = -1; + + return FALSE; + } + + rect->x = camerasrc_rect.x; + rect->y = camerasrc_rect.y; + rect->width = camerasrc_rect.width; + rect->height = camerasrc_rect.height; + + return TRUE; +} + +gboolean +gst_camerasrc_control_set_wdr( GstCameraSrc* camerasrc, gint value ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + error = camerasrc_set_control (camerasrc->v4l2_handle, CAMERASRC_CTRL_WIDE_DYNAMIC_RANGE, value ); + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to set wdr. value[%d],err code[%x]", value, error ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_get_wdr( GstCameraSrc* camerasrc, gint* value ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + error = camerasrc_get_control (camerasrc->v4l2_handle, CAMERASRC_CTRL_WIDE_DYNAMIC_RANGE, value ); + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to get wdr. err code[%x]", error ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_set_ahs( GstCameraSrc* camerasrc, gint value ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + error = camerasrc_set_control (camerasrc->v4l2_handle, CAMERASRC_CTRL_ANTI_HANDSHAKE, value ); + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to set ahs. value[%d],err code[%x]", value, error ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_get_ahs( GstCameraSrc* camerasrc, gint* value ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + error = camerasrc_get_control (camerasrc->v4l2_handle, CAMERASRC_CTRL_ANTI_HANDSHAKE, value ); + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to get ahs. err code[%x]", error ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_set_part_color( GstCameraSrc* camerasrc, gint type, gint value ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + switch( type ) + { + case GST_CAMERA_CONTROL_PART_COLOR_SRC: + error = camerasrc_set_control( camerasrc->v4l2_handle, CAMERASRC_CTRL_PARTCOLOR_SRC, value ); + break; + case GST_CAMERA_CONTROL_PART_COLOR_DST: + error = camerasrc_set_control( camerasrc->v4l2_handle, CAMERASRC_CTRL_PARTCOLOR_DST, value ); + break; + case GST_CAMERA_CONTROL_PART_COLOR_MODE: + error = camerasrc_set_control( camerasrc->v4l2_handle, CAMERASRC_CTRL_PARTCOLOR_MODE, value ); + break; + default: + gst_camerasrc_debug( "Not supported type." ); + return FALSE; + } + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to set part color. Type[%d],value[%d],err code[%x]", type, value, error ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_get_part_color( GstCameraSrc* camerasrc, gint type, gint* value ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + switch( type ) + { + case GST_CAMERA_CONTROL_PART_COLOR_SRC: + error = camerasrc_get_control( camerasrc->v4l2_handle, CAMERASRC_CTRL_PARTCOLOR_SRC, value ); + break; + case GST_CAMERA_CONTROL_PART_COLOR_DST: + error = camerasrc_get_control( camerasrc->v4l2_handle, CAMERASRC_CTRL_PARTCOLOR_DST, value ); + break; + case GST_CAMERA_CONTROL_PART_COLOR_MODE: + error = camerasrc_get_control( camerasrc->v4l2_handle, CAMERASRC_CTRL_PARTCOLOR_MODE, value ); + break; + default: + gst_camerasrc_debug( "Not supported type." ); + return FALSE; + } + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to get part color. Type[%d],err code[%x]", type, error ); + return FALSE; + } + + return TRUE; +} + +gboolean +gst_camerasrc_control_get_exif_info( GstCameraSrc* camerasrc, GstCameraControlExifInfo* info ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + camerasrc_exif_t exif_struct; + + g_return_val_if_fail( camerasrc, FALSE ); + + error = camerasrc_get_exif_info( camerasrc->v4l2_handle, &exif_struct ); + + if( error != CAMERASRC_SUCCESS ) + { + gst_camerasrc_debug( "Failed to get exif info. err code[%x]", error ); + return FALSE; + } + + /* Dynamic value */ + info->exposure_time_numerator = exif_struct.exposure_time_numerator; + info->exposure_time_denominator = exif_struct.exposure_time_denominator; + info->shutter_speed_numerator = exif_struct.shutter_speed_numerator; + info->shutter_speed_denominator = exif_struct.shutter_speed_denominator; + info->brigtness_numerator = exif_struct.brigtness_numerator; + info->brightness_denominator = exif_struct.brightness_denominator; + info->iso = exif_struct.iso; + info->flash = exif_struct.flash; + info->metering_mode = exif_struct.metering_mode; + info->exif_image_width = exif_struct.exif_image_width; + info->exif_image_height = exif_struct.exif_image_height; + info->software_used = exif_struct.software_used; + info->exposure_bias_in_APEX = exif_struct.exposure_bias_in_APEX; + + /* Fixed value */ + info->component_configuration = exif_struct.component_configuration; + info->colorspace = exif_struct.colorspace; + info->max_lens_aperture_in_APEX = exif_struct.max_lens_aperture_in_APEX; + + /*FIXME*/ + if (camerasrc->camera_id == CAMERASRC_DEV_ID_PRIMARY) { + info->focal_len_numerator = CAMERASRC_PRIMARY_FOCAL_LEGNTH_NUM; + info->focal_len_denominator = CAMERASRC_PRIMARY_FOCAL_LEGNTH_DENOM; + info->aperture_f_num_numerator = CAMERASRC_PRIMARY_F_NUMBER_NUM; + info->aperture_f_num_denominator = CAMERASRC_PRIMARY_F_NUMBER_DENOM; + } else { + info->focal_len_numerator = CAMERASRC_SECONDARY_FOCAL_LEGNTH_NUM; + info->focal_len_denominator = CAMERASRC_SECONDARY_FOCAL_LEGNTH_DENOM; + info->aperture_f_num_numerator = CAMERASRC_SECONDARY_F_NUMBER_NUM; + info->aperture_f_num_denominator = CAMERASRC_SECONDARY_F_NUMBER_DENOM; + } + info->aperture_in_APEX = CAMERASRC_EXIF_APERTURE_VALUE_IN_APEX(info->aperture_f_num_numerator, info->aperture_f_num_denominator); + + return TRUE; +} + +gboolean gst_camerasrc_control_get_basic_dev_info ( GstCameraSrc* camerasrc, gint dev_id, GstCameraControlCapsInfoType* info ) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + /** + * Just implementation issue, but at this time, we assume + * GstCameraControlCapsInfoType is exactly same with camerasrc_caps_info_t + * For performance. + * Here is plugin code. we can do like this? + */ +#if 1 + error = camerasrc_read_basic_dev_info(dev_id, (camerasrc_caps_info_t*)info); + if(error != CAMERASRC_SUCCESS) + { + return FALSE; + } +#else + int i, j, k; + camerasrc_caps_info_t caps_info; + + error = camerasrc_read_basic_dev_info(dev_id, &caps_info); + if(error != CAMERASRC_SUCCESS) + { + return FALSE; + } + + if(caps_info.num_fmt_desc != 0) + { + info->num_fmt_desc = caps_info.num_fmt_desc; + for (i=0; i<caps_info.num_fmt_desc; i++) { + if(caps_info.fmt_desc[i].num_resolution != 0) + { + info->fmt_desc[i].fcc = caps_info.fmt_desc[i].fcc; + info->fmt_desc[i].num_resolution = caps_info.fmt_desc[i].num_resolution; + for (j=0; j<caps_info.fmt_desc[i].num_resolution; j++) + { + if(caps_info.fmt_desc[i].resolutions[j].num_avail_tpf != 0) + { + info->fmt_desc[i].resolutions[j].w = caps_info.fmt_desc[i].resolutions[j].w; + info->fmt_desc[i].resolutions[j].h = caps_info.fmt_desc[i].resolutions[j].h; + info->fmt_desc[i].resolutions[j].num_avail_tpf = caps_info.fmt_desc[i].resolutions[j].num_avail_tpf; + for(k=0; k< caps_info.fmt_desc[i].resolutions[j].num_avail_tpf; k++) + { + info->fmt_desc[i].resolutions[j].tpf[k].num = caps_info.fmt_desc[i].resolutions[j].tpf[k].num; + info->fmt_desc[i].resolutions[j].tpf[k].den = caps_info.fmt_desc[i].resolutions[j].tpf[k].den; + } + } + else + { + /* No available timeperframe */ + return FALSE; + } + } + } + else + { + /* No available resolution set */ + return FALSE; + } + } + } + else + { + /* No available image format(fourcc) */ + return FALSE; + } +#endif + return TRUE; +} + +gboolean gst_camerasrc_control_get_misc_dev_info( GstCameraSrc* camerasrc, gint dev_id, GstCameraControlCtrlListInfoType * info) +{ + gst_camerasrc_debug( "" ); + + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + /** + * Just implementation issue, but at this time, we assume + * GstCameraControlCtrlListInfoType is exactly same with camerasrc_ctrl_list_info_t + * For performance. + * Here is plugin code. we can do like this? + */ +#if 1 + error = camerasrc_read_misc_dev_info(dev_id, (camerasrc_ctrl_list_info_t*)info); + if(error != CAMERASRC_SUCCESS) + { + return FALSE; + } +#else + int i, j; + camerasrc_ctrl_list_info_t ctrl_info; + + error = camerasrc_read_misc_dev_info(dev_id, &ctrl_info); + if(error != CAMERASRC_SUCCESS) + { + return FALSE; + } + + if(ctrl_info.num_ctrl_list_info != 0) + { + info->num_ctrl_list_info = ctrl_info.num_ctrl_list_info; + for(i=0; i< ctrl_info.num_ctrl_list_info; i++) + { + info->ctrl_info[i].camerasrc_ctrl_id = ctrl_info.ctrl_info[i].camerasrc_ctrl_id; + info->ctrl_info[i].v4l2_ctrl_id = ctrl_info.ctrl_info[i].v4l2_ctrl_id; + info->ctrl_info[i].ctrl_type = ctrl_info.ctrl_info[i].ctrl_type; + info->ctrl_info[i].max = ctrl_info.ctrl_info[i].max; + info->ctrl_info[i].min = ctrl_info.ctrl_info[i].min; + info->ctrl_info[i].step = ctrl_info.ctrl_info[i].step; + info->ctrl_info[i].default_val = ctrl_info.ctrl_info[i].default_val; + info->ctrl_info[i].num_ctrl_menu = ctrl_info.ctrl_info[i].num_ctrl_menu; + memcpy(info->ctrl_info[i].ctrl_name,ctrl_info.ctrl_info[i].ctrl_name,MAX_SZ_CTRL_NAME_STRING); + if(ctrl_info.ctrl_info[i].ctrl_type == CTRL_TYPE_ARRAY && ctrl_info.ctrl_info[i].num_ctrl_menu != 0) + { + for(j=0; j<ctrl_info.ctrl_info[i].num_ctrl_menu; j++) + { + info->ctrl_info[i].ctrl_menu[j].menu_index = ctrl_info.ctrl_info[i].ctrl_menu[j].menu_index; + memcpy(info->ctrl_info[i].ctrl_menu[j].menu_name, ctrl_info.ctrl_info[i].ctrl_menu[j].menu_name, MAX_SZ_CTRL_NAME_STRING); + } + } + else + { + /* Not a menu type or not available menus */ + return FALSE; + } + } + } + else + { + /* Not avaliable controls */ + return FALSE; + } +#endif + return TRUE; +} + +gboolean gst_camerasrc_control_get_extra_dev_info( GstCameraSrc* camerasrc, gint dev_id, GstCameraControlExtraInfoType * info) +{ + int error = CAMERASRC_ERROR; + + g_return_val_if_fail( camerasrc, FALSE ); + + gst_camerasrc_debug( "" ); + + /** + * Just implementation issue, but at this time, we assume + * GstCameraControlCtrlListInfoType is exactly same with camerasrc_ctrl_list_info_t + * For performance. + * Here is plugin code. we can do like this? + */ + + error = camerasrc_read_extra_dev_info(dev_id, (camerasrc_extra_info_t*)info); + if(error != CAMERASRC_SUCCESS) + { + return FALSE; + } + + return TRUE; +} + +void gst_camerasrc_control_set_capture_command( GstCameraSrc* camerasrc, GstCameraControlCaptureCommand cmd ) +{ + gst_camerasrc_debug( "" ); + + if( camerasrc == NULL ) + { + gst_camerasrc_debug( "camerasrc is NULL" ); + return; + } + + gst_camerasrc_set_capture_command( camerasrc, cmd ); + + return; +} diff --git a/camerasrc/src/include/camerasrc-common.h b/camerasrc/src/include/camerasrc-common.h new file mode 100644 index 0000000..207cdd3 --- /dev/null +++ b/camerasrc/src/include/camerasrc-common.h @@ -0,0 +1,408 @@ +/* + * camerasrc + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang <jm80.yang@samsung.com> + * + * 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.1 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., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __CAMERASRC_COMMON_H__ +#define __CAMERASRC_COMMON_H__ + +#include <stdio.h> +#include <malloc.h> +#include <pthread.h> +#include <errno.h> /*EXXX*/ +#include <sys/ioctl.h> /*ioctl*/ +#include <string.h> /*memcpy*/ + +#include <sys/types.h> /*open*/ +#include <sys/stat.h> +#include <fcntl.h> + +#include <unistd.h> /*mmap*/ +#include <sys/mman.h> /*alloc series, free..*/ +#include <sys/time.h> /*gettimeofday*/ +#include <math.h> /*log2*/ +#include <gst/gst.h> + +#undef __ASM_ARM_TYPES_H +#undef __ASSEMBLY_ +#undef _I386_TYPES_H + +#include <asm/types.h> +#include <linux/videodev2.h> /* V4L2 APIs */ +#include <linux/videodev2_exynos_camera.h> +#include <linux/videodev2_exynos_media.h> + +#include "camerasrc.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Memory utility definitions + */ +#if !defined (PAGE_SHIFT) + #define PAGE_SHIFT sysconf(_SC_PAGESIZE) +#endif +#if !defined (PAGE_SIZE) + #define PAGE_SIZE (1UL << PAGE_SHIFT) +#endif +#if !defined (PAGE_MASK) + #define PAGE_MASK (~(PAGE_SIZE-1)) +#endif + +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) +#define CLEAR(x) memset (&(x), 0, sizeof (x)) + +#define CAMERASRC_MAX_WIDTH 2560 +#define CAMERASRC_MAX_HEIGHT 1920 +#define CAMERASRC_CID_NOT_SUPPORT -1 +#define CAMERASRC_USRPTR_MAX_BUFFER_NUM 12 +#define CAMERASRC_MAX_FILENAME_LEN 255 +#define CAMERASRC_DEV_NODE_PREFIX "/dev/video" +#define CAMERASRC_DEV_FD_INIT -1 +#define CAMERASRC_DEV_ON_ACCESS_STR "ONACCESS" +#define CAMERASRC_DEV_RELEASED_STR "RELEASED" +#define CAMERASRC_OPENED_CHK_FILENAME "/tmp/.dev_chk" +#define CAMERASRC_THREAD_KILL -999 +#define CAMERASRC_DEV_FD_EMERGENCY_CLOSED -999 +#define CAMERASRC_ERRMSG_MAX_LEN 128 +#define CAMERASRC_FRAME_DUMP_PATH "/tmp/" +#define CAMERASRC_DBG_SCRIPT_PATH "/mnt/mmc/cam_dbg_script" +#define CAMERASRC_PRIMARY_BASIC_INFO_PATH "/tmp/.camprimarybasicinfo" +#define CAMERASRC_PRIMARY_MISC_INFO_PATH "/tmp/.camprimarymiscinfo" +#define CAMERASRC_PRIMARY_EXTRA_INFO_PATH "/tmp/.camprimaryextrainfo" +#define CAMERASRC_SECONDARY_BASIC_INFO_PATH "/tmp/.camsecondarybasicinfo" +#define CAMERASRC_SECONDARY_MISC_INFO_PATH "/tmp/.camsecondarymiscinfo" +#define CAMERASRC_SECONDARY_EXTRA_INFO_PATH "/tmp/.camsecondaryextrainfo" +#define CAMERASRC_MAX_IMAGE_BUFFER_PLANES 3 + +#define USE_OPEN_CHK /*< Using open check with temporary file */ +#define USE_SENSOR_MODE 1 +/*#define USE_SKIP_FRAME*/ /*< Skip frame toggle */ +/*#define USE_IOCTL_DEBUG*/ /*< For debugging ioctl name, argument, address, etc */ +/*#define USE_FRAME_COPY_BOUNDARY_CHECK*/ /*< Copy boundary checks occurs seg fault when overrun */ +/*#define USE_SKIP_FRAME_AT_RAW_FRAME*/ /*< In pumping raw frame, initial 2-3 frames are darker. so skip it */ +/*#define USE_CAMERASRC_FRAME_DUMP*/ /*< Debug system annoying me. Use printf!!!! */ +/*#define USE_USERPTR_DEBUG*/ +/*#define ENABLE_Q_ERROR*/ + +#ifndef GST_CAT_DEFAULT +GST_DEBUG_CATEGORY_EXTERN(camerasrc_debug); +#define GST_CAT_DEFAULT camerasrc_debug +#endif /* GST_CAT_DEFAULT */ + + +#define camsrc_info(msg, args...) GST_INFO(msg, ##args) +#define camsrc_warning(msg, args...) GST_WARNING(msg, ##args) +#define camsrc_error(msg, args...) GST_ERROR(msg, ##args) +#define camsrc_critical(msg, args...) GST_ERROR(msg, ##args) +#define camsrc_assert(condition) { \ + if (!(condition)) { \ + GST_ERROR("failed [%s]", #condition); \ + } \ +} + +/* + * Values for internal + */ +enum camerasrc_op_mode_t { + CAMERASRC_OP_PREVIEW = 0, + CAMERASRC_OP_CAPTURE, + CAMERASRC_OP_VIDEO, + CAMERASRC_OP_REGISTER_VALUE, + CAMERASRC_OP_NUM, +}; + +/* + * Values for internal + */ +enum camerasrc_ctrl_property_t{ + CAMERASRC_CTRL_SUPPORT = 0, + CAMERASRC_CTRL_MAX_VALUE, + CAMERASRC_CTRL_MIN_VALUE, + CAMERASRC_CTRL_CID_VALUE, + CAMERASRC_CTRL_CURRENT_VALUE, + CAMERASRC_CTRL_PROPERTY_NUM, +}; + +/* + * Values for internal + */ +enum camerasrc_quality_t{ + CAMERASRC_QUALITY_NORMAL = 0, + CAMERASRC_QUALITY_HIGH, + CAMERASRC_QUALITY_NUM, +}; + +enum camerasrc_dev_recog_t{ + CAMERASRC_DEV_RECOG_ID = 0, + CAMERASRC_DEV_RECOG_INDEX, + CAMERASRC_DEV_RECOG_NUM, +}; + +/** + * Phase, camerasrc consist of two phase, running and non-running. + */ +typedef enum { + CAMERASRC_PHASE_RUNNING = 0, + CAMERASRC_PHASE_NON_RUNNING, + CAMERASRC_PHASE_NUM, +} _camerasrc_phase_t; + +typedef enum { + CAMERASRC_MISC_STILL_SIGNAL = 0, + CAMERASRC_MISC_SKIP_FRAME, + CAMERASRC_MISC_FUNC_NUM, +} _camerasrc_misc_func_t; + +typedef enum{ + _CAMERASRC_CMD_AF_CONTROL = 0, + _CAMERASRC_CMD_AF_AREA, + _CAMERASRC_CMD_STROBE_MODE, + _CAMERASRC_CMD_FACEDETECTION, + _CAMERASRC_CMD_SHUTTER_SPEED, + _CAMERASRC_CMD_SUPPORT_EMBED_EXIF, + _CAMERASRC_CMD_SUPPORT_JPEG_ENCODING, + _CAMERASRC_CMD_CHECK_ESD, + _CAMERASRC_CMD_JPEG_COMPRESS_RATIO, + _CAMERASRC_CMD_JPEG_LENGTH, + _CAMERASRC_CMD_JPEG_THMBNL_LENGTH, + _CAMERASRC_CMD_JPEG_THMBNL_OFFSET, + _CAMERASRC_CMD_JPEG_SCRNL_LENGTH, + _CAMERASRC_CMD_JPEG_SCRNL_OFFSET, + _CAMERASRC_CMD_EXPOSURE_VALUE, + _CAMERASRC_CMD_ESD_CHECK, + _CAMERASRC_CMD_FRAME_DATA, + _CAMERASRC_CMD_EXIF_INFO, + _CAMERASRC_CMD_CTRL, + _CAMERASRC_CMD_ROTATION, + _CAMERASRC_CMD_SENSOR_MODE, + _CAMERASRC_CMD_VFLIP, + _CAMERASRC_CMD_HFLIP, + _CAMERASRC_CMD_NUM, +}_camsrc_cmd_t; + +typedef struct{ + int cid; + int value; +} _camerasrc_ctrl_t; + +enum { + _CAMERASRC_FACEDETECTION_START = 0, + _CAMERASRC_FACEDETECTION_STOP, + _CAMERASRC_FACEDETECTION_NUM, +}; + +enum { + _CAMERASRC_AF_START = 0, + _CAMERASRC_AF_STOP, + _CAMERASRC_AF_RELEASE, + _CAMERASRC_AF_INIT, + _CAMERASRC_AF_DESTROY, +}; + +// U T I L I T Y D E F I N I T I O N +/** + * Mapping device index - Device ID + */ +#define _CAMERASRC_GET_DEV_INDEX(dev_id) _camerasrc_dev_index[dev_id][CAMERASRC_DEV_RECOG_INDEX] +#define _CAMERASRC_GET_DEV_ID(dev_idx) _camerasrc_dev_index[dev_idx][CAMERASRC_DEV_RECOG_ID] + +/** + * For colorspace - pixel format combinability check + */ +#define _CAMERASRC_MATCH_COL_TO_PIX(dev_id, colorspace, pixel_fmt, quality) _camerasrc_match_col_to_pix[dev_id][colorspace][pixel_fmt][quality] + +/** + * For control capability check + */ +#define _CAMERASRC_CHK_SUPPORT_CONTROL(ctrl_id, dev_id) _camerasrc_ctrl_list[dev_id][ctrl_id][CAMERASRC_CTRL_SUPPORT] +#define _CAMERASRC_MAX_VALUE(ctrl_id, dev_id) _camerasrc_ctrl_list[dev_id][ctrl_id][CAMERASRC_CTRL_MAX_VALUE] +#define _CAMERASRC_MIN_VALUE(ctrl_id, dev_id) _camerasrc_ctrl_list[dev_id][ctrl_id][CAMERASRC_CTRL_MIN_VALUE] +#define _CAMERASRC_GET_CID(ctrl_id, dev_id) _camerasrc_ctrl_list[dev_id][ctrl_id][CAMERASRC_CTRL_CID_VALUE] +#define _CAMERASRC_GET_CURRENT_VALUE(ctrl_id, dev_id) _camerasrc_ctrl_list[dev_id][ctrl_id][CAMERASRC_CTRL_CURRENT_VALUE] +#define _CAMERASRC_SET_CURRENT_VALUE(ctrl_id, dev_id, value) _camerasrc_ctrl_list[dev_id][ctrl_id][CAMERASRC_CTRL_CURRENT_VALUE] = value + +/** + * Need miscellaneous function on operation? + */ +#define _CAMERASRC_NEED_MISC_FUNCTION(dev_id, operation, colorspace, misc_func) _camerasrc_misc_func_list[dev_id][operation][colorspace][misc_func] +#define _CAMERASRC_SUPPORT_AF(dev_id) _camerasrc_af_support[dev_id] + +/** + * Utility definitions + */ +#define CAMERASRC_SET_STATE(handle, state) { \ + handle->prev_state = handle->cur_state; \ + handle->cur_state = state; \ + camsrc_info("Set state [%d] -> [%d]", handle->prev_state, handle->cur_state); \ +} +#define CAMERASRC_SET_PHASE(handle, phase) handle->cur_phase = phase; +#define CAMERASRC_STATE(handle) (handle->cur_state) +#define CAMERASRC_PREV_STREAM_STATE(handle) -1 +#define CAMERASRC_PHASE(handle) (handle->cur_phase) +#define CAMERASRC_HANDLE(handle) ((camerasrc_handle_t*) handle) +#define CAMERASRC_CURRENT_DEV_ID(handle) (handle->dev_id) +#define CAMERASRC_IS_DEV_CLOSED(p) (p->dev_fd == -1 || p->dev_fd == CAMERASRC_DEV_FD_EMERGENCY_CLOSED) + +#define YUV422_SIZE(handle) ((handle->format.img_size.dim.height * handle->format.img_size.dim.width) << 1) +#define YUV420_SIZE(handle) ((handle->format.img_size.dim.height * handle->format.img_size.dim.width * 3) >> 1) +#define RGB565_SIZE(handle) ((handle->format.img_size.dim.height * handle->format.img_size.dim.width) << 1) + +#define ISO_APPROXIMATE_VALUE(iso_in, iso_approximated) { \ + if(iso_in > 8.909 && iso_in <= 11.22) iso_approximated = 10; \ + else if(iso_in > 11.22 && iso_in <= 14.14) iso_approximated = 12; \ + else if(iso_in > 14.14 && iso_in <= 17.82) iso_approximated = 16; \ + else if(iso_in > 17.82 && iso_in <= 22.45) iso_approximated = 20; \ + else if(iso_in > 22.45 && iso_in <= 28.28) iso_approximated = 25; \ + else if(iso_in > 28.28 && iso_in <= 35.64) iso_approximated = 32; \ + else if(iso_in > 35.64 && iso_in <= 44.90) iso_approximated = 40; \ + else if(iso_in > 44.90 && iso_in <= 56.57) iso_approximated = 50; \ + else if(iso_in > 56.57 && iso_in <= 71.27) iso_approximated = 64; \ + else if(iso_in > 71.27 && iso_in <= 89.09) iso_approximated = 80; \ + else if(iso_in > 89.09 && iso_in <= 112.2) iso_approximated = 100; \ + else if(iso_in > 112.2 && iso_in <= 141.4) iso_approximated = 125; \ + else if(iso_in > 141.4 && iso_in <= 178.2) iso_approximated = 160; \ + else if(iso_in > 178.2 && iso_in <= 224.5) iso_approximated = 200; \ + else if(iso_in > 224.5 && iso_in <= 282.8) iso_approximated = 250; \ + else if(iso_in > 282.8 && iso_in <= 356.4) iso_approximated = 320; \ + else if(iso_in > 356.4 && iso_in <= 449.0) iso_approximated = 400; \ + else if(iso_in > 449.0 && iso_in <= 565.7) iso_approximated = 500; \ + else if(iso_in > 565.7 && iso_in <= 712.7) iso_approximated = 640; \ + else if(iso_in > 712.7 && iso_in <= 890.9) iso_approximated = 800; \ + else if(iso_in > 890.9 && iso_in <= 1122) iso_approximated = 1000; \ + else if(iso_in > 1122 && iso_in <= 1414) iso_approximated = 1250; \ + else if(iso_in > 1414 && iso_in <= 1782) iso_approximated = 1600; \ + else if(iso_in > 1782 && iso_in <= 2245) iso_approximated = 2000; \ + else if(iso_in > 2245 && iso_in <= 2828) iso_approximated = 2500; \ + else if(iso_in > 2828 && iso_in <= 3564) iso_approximated = 3200; \ + else if(iso_in > 3564 && iso_in <= 4490) iso_approximated = 4000; \ + else if(iso_in > 4490 && iso_in <= 5657) iso_approximated = 5000; \ + else if(iso_in > 5657 && iso_in <= 7127) iso_approximated = 6400; \ + else if(iso_in > 7127 && iso_in <= 8909) iso_approximated = 8000; \ + else { \ + camsrc_warning("Invalid parameter(Maybe kernel failure).. give default value, 100");\ + iso_approximated = 100;\ + }\ +} + +#define PHOTOMETRY_MODE_TO_METERING_MODE(photometry_mode, metering_mode) { \ + if(photometry_mode == V4L2_PHOTOMETRY_MULTISEG) metering_mode = 1; \ + else if (photometry_mode == V4L2_PHOTOMETRY_CWA) metering_mode = 2; \ + else if (photometry_mode == V4L2_PHOTOMETRY_SPOT) metering_mode = 3; \ + else if (photometry_mode == V4L2_PHOTOMETRY_AFSPOT) metering_mode = 3; \ + else metering_mode = 1; \ +} + +#define CAMERASRC_EXIF_SHUTTERSPEED_VALUE_IN_APEX(NUM, DEN) (int)(-(log2((double)((double)NUM/(double)DEN)))) +#define CAMERASRC_EXIF_APERTURE_VALUE_IN_APEX(NUM, DEN) (int)(2 * (log2((double)((double)NUM/(double)DEN)))) + + +typedef void *(*camerasrc_signal_func_t) (camsrc_handle_t handle); +typedef int (*camerasrc_skip_frame_func_t) (camsrc_handle_t handle, long int timeout, int skip_frame); + +typedef struct _camerasrc_handle_t { + int is_async_open; + + /* device information */ + int dev_fd; + int cur_dev_id; + camerasrc_buffer_t alter_frame; + int check_esd; + int errnum; + int lens_rotation; /* physical rotation of lens */ + + /* state information */ + int prev_stream_state; + int prev_state; + int cur_state; + int cur_phase; + + /* image format information */ + int is_highquality; + int is_preset; + camerasrc_resol_name_t resolution; + camerasrc_format_t format; + + /* buffer information */ + camerasrc_io_method_t io_method; + camerasrc_usr_buf_t *present_buf; + int buffer_idx; + int num_buffers; + int queued_buffer_count; + int first_frame; + struct v4l2_buffer queued_buf_list[CAMERASRC_USRPTR_MAX_BUFFER_NUM]; + camerasrc_buffer_t *buffer; + camerasrc_buffer_t scrnl_buf; /* screennail buffer of captured JPEG image */ + + /* autofocusing information */ + camerasrc_af_mode_t cur_af_mode; + camerasrc_af_scan_range_t cur_af_range; + camerasrc_callback_t af_cb; + pthread_t focusing_thread; + pthread_cond_t af_wait_cond; + camerasrc_auto_focus_status_t af_status; + camerasrc_auto_focus_cmd_t af_cmd; + int af_dev_val; + void *af_usr_data; + int hold_af_after_capturing; + int af_init_called; /* whether af init was called after device open. */ + struct timeval set_af_area_time; /* for AF start delay after set AF area */ + + /* Jpg Still information */ + camerasrc_skip_frame_func_t skip_frame_func; + + /* Shutter & exposure value */ + int isAutoexposure; + + /* fps */ + camerasrc_frac_t timeperframe; + + /* sensor mode */ + camerasrc_sensor_mode_t sensor_mode; + + /* flip */ + int vflip; + int hflip; + + /* thread safe mechanism */ + pthread_mutex_t mutex; + pthread_mutex_t af_mutex; + pthread_cond_t cond; +} camerasrc_handle_t; + +typedef struct { + int (*_ioctl) (camerasrc_handle_t *handle, int request, void *arg); + int (*_ioctl_once) (camerasrc_handle_t *handle, int request, void *arg); + void *(*_run_autofocusing) (camerasrc_handle_t *handle); + int (*_skip_frame) (camerasrc_handle_t *handle, long int timeout, int skip_frame); + int (*_copy_frame) (camerasrc_handle_t *handle, camerasrc_buffer_t *src_buffer, camerasrc_buffer_t *dst_buffer, int isThumbnail); + int (*_set_cmd) (camerasrc_handle_t *handle, _camsrc_cmd_t cmd, void *value); + int (*_get_cmd) (camerasrc_handle_t *handle, _camsrc_cmd_t cmd, void *value); +} CAMERASRC_DEV_DEPENDENT_MISC_FUNC; + +#ifdef __cplusplus +} +#endif + +#endif /*__CAMERASRC_COMMON_H__*/ diff --git a/camerasrc/src/include/camerasrc-error.h b/camerasrc/src/include/camerasrc-error.h new file mode 100644 index 0000000..4ea8c7f --- /dev/null +++ b/camerasrc/src/include/camerasrc-error.h @@ -0,0 +1,140 @@ +/* + * camerasrc + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang <jm80.yang@samsung.com> + * + * 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.1 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., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __CAMERASRC_ERROR_H__ +#define __CAMERASRC_ERROR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * CAMSRC CLASS + */ +#define CAMERASRC_SUCCESS (0x00000000) /**< No Error */ +#define CAMERASRC_ERROR (0x80000000) /**< Error Class */ +#define CAMERASRC_WARING (0x70000000) /**< Waring Class */ + +/* + * Detail enumeration + */ +enum { + CAMSRC_IN_UNKNOWN = 0, + CAMSRC_IN_PARAMETER, + CAMSRC_IN_HANDLE, + CAMSRC_IN_POINTER, + CAMSRC_IN_VALUE, + CAMSRC_IN_OVERRUN, + CAMSRC_IN_UNDERRUN, + CAMSRC_IN_RANGE_OVER, + CAMSRC_IN_RANGE_UNDER, + CAMSRC_IN_MODE, + CAMSRC_IN_FORMAT, + CAMSRC_IN_CHANNEL, + CAMSRC_IN_SAMPLERATE, + CAMSRC_IN_LAYER, + CAMSRC_IN_ROTATE, + CAMSRC_IN_ALLOC, + CAMSRC_IN_INTERNAL, + /*Extra state for camera*/ + CAMSRC_IN_IO_CONTROL, + CAMSRC_IN_DEVICE_OPEN, + CAMSRC_IN_DEVICE_BUSY, + CAMSRC_IN_DEVICE_NOT_FOUND, + CAMSRC_IN_DEVICE_REGISTER_TROUBLE, + CAMSRC_IN_WAIT_RES, + CAMSRC_IN_SUPPORT, + CAMSRC_IN_STATE, + CAMSRC_IN_PRIVILEGE, + CAMSRC_IN_SECURITY_SERVICE, +}; + +/* + * CAMERASRC_WARNING + */ +#define CAMERASRC_WAR_INVALID_PARAMETER (CAMERASRC_WARING | CAMSRC_IN_PARAMETER) +#define CAMERASRC_WAR_INVALID_HANDLE (CAMERASRC_WARING | CAMSRC_IN_HANDLE) +#define CAMERASRC_WAR_INVALID_VALUE (CAMERASRC_WARING | CAMSRC_IN_VALUE) +#define CAMERASRC_WAR_INVALID_MODE (CAMERASRC_WARING | CAMSRC_IN_MODE) +#define CAMERASRC_WAR_INVALID_FORMAT (CAMERASRC_WARING | CAMSRC_IN_FORMAT) +#define CAMERASRC_WAR_INVALID_CHANNEL (CAMERASRC_WARING | CAMSRC_IN_CHANNEL) +#define CAMERASRC_WAR_INVALID_SAMPLERATE (CAMERASRC_WARING | CAMSRC_IN_SAMPLERATE) +#define CAMERASRC_WAR_INVALID_LAYER (CAMERASRC_WARING | CAMSRC_IN_LAYER) +#define CAMERASRC_WAR_INVALID_ROTATE (CAMERASRC_WARING | CAMSRC_IN_ROTATE) +#define CAMERASRC_WAR_NULL_POINTER (CAMERASRC_WARING | CAMSRC_IN_POINTER) +#define CAMERASRC_WAR_UNDERRUN (CAMERASRC_WARING | CAMSRC_IN_UNDERRUN) +#define CAMERASRC_WAR_OVERRUN (CAMERASRC_WARING | CAMSRC_IN_OVERRUN) +#define CAMERASRC_WAR_RANGE_OVER (CAMERASRC_WARING | CAMSRC_IN_RANGE_OVER) +#define CAMERASRC_WAR_RANGE_UNDER (CAMERASRC_WARING | CAMSRC_IN_RANGE_UNDER) +#define CAMERASRC_WAR_ALLOCATION (CAMERASRC_WARING | CAMSRC_IN_ALLOC) +#define CAMERASRC_WAR_INTERNAL (CAMERASRC_WARING | CAMSRC_IN_INTERNAL) +/*Extra warning for camera*/ +#define CAMERASRC_WAR_IO_CONTROL (CAMERASRC_WARING | CAMSRC_IN_IO_CONTROL) +#define CAMERASRC_WAR_DEVICE_OPEN (CAMERASRC_WARING | CAMSRC_IN_DEVICE_OPEN) +#define CAMERASRC_WAR_DEVICE_BUSY (CAMERASRC_WARING | CAMSRC_IN_DEVICE_BUSY) +#define CAMERASRC_WAR_DEVICE_NOT_FOUND (CAMERASRC_WARING | CAMSRC_IN_DEVICE_NOT_FOUND) +#define CAMERASRC_WAR_DEVICE_UNAVAILABLE (CAMERASRC_WARING | CAMSRC_IN_DEVICE_REGISTER_TROUBLE) +#define CAMERASRC_WAR_DEVICE_WAIT_TIMEOUT (CAMERASRC_WARING | CAMSRC_IN_WAIT_RES) +#define CAMERASRC_WAR_DEVICE_NOT_SUPPORT (CAMERASRC_WARING | CAMSRC_IN_SUPPORT) +#define CAMERASRC_WAR_INVALID_STATE_TRANSITION (CAMERASRC_WARING | CAMSRC_IN_STATE) + +/** + * CAMERASRC_ERROR + */ +#define CAMERASRC_ERR_INVALID_PARAMETER (CAMERASRC_ERROR | CAMSRC_IN_PARAMETER) +#define CAMERASRC_ERR_INVALID_HANDLE (CAMERASRC_ERROR | CAMSRC_IN_HANDLE) +#define CAMERASRC_ERR_INVALID_VALUE (CAMERASRC_ERROR | CAMSRC_IN_VALUE) +#define CAMERASRC_ERR_INVALID_MODE (CAMERASRC_ERROR | CAMSRC_IN_MODE) +#define CAMERASRC_ERR_INVALID_FORMAT (CAMERASRC_ERROR | CAMSRC_IN_FORMAT) +#define CAMERASRC_ERR_INVALID_CHANNEL (CAMERASRC_ERROR | CAMSRC_IN_CHANNEL) +#define CAMERASRC_ERR_INVALID_SAMPLERATE (CAMERASRC_ERROR | CAMSRC_IN_SAMPLERATE) +#define CAMERASRC_ERR_INVALID_LAYER (CAMERASRC_ERROR | CAMSRC_IN_LAYER) +#define CAMERASRC_ERR_INVALID_ROTATE (CAMERASRC_ERROR | CAMSRC_IN_ROTATE) +#define CAMERASRC_ERR_NULL_POINTER (CAMERASRC_ERROR | CAMSRC_IN_POINTER) +#define CAMERASRC_ERR_UNDERRUN (CAMERASRC_ERROR | CAMSRC_IN_UNDERRUN) +#define CAMERASRC_ERR_OVERRUN (CAMERASRC_ERROR | CAMSRC_IN_OVERRUN) +#define CAMERASRC_ERR_RANGE_OVER (CAMERASRC_ERROR | CAMSRC_IN_RANGE_OVER) +#define CAMERASRC_ERR_RANGE_UNDER (CAMERASRC_ERROR | CAMSRC_IN_RANGE_UNDER) +#define CAMERASRC_ERR_ALLOCATION (CAMERASRC_ERROR | CAMSRC_IN_ALLOC) +#define CAMERASRC_ERR_INTERNAL (CAMERASRC_ERROR | CAMSRC_IN_INTERNAL) +#define CAMERASRC_ERR_UNKNOWN (CAMERASRC_ERROR | CAMSRC_IN_UNKNOWN) /**< unknown error */ +/*Extra warning for camera*/ +#define CAMERASRC_ERR_IO_CONTROL (CAMERASRC_ERROR | CAMSRC_IN_IO_CONTROL) +#define CAMERASRC_ERR_DEVICE_OPEN (CAMERASRC_ERROR | CAMSRC_IN_DEVICE_OPEN) +#define CAMERASRC_ERR_DEVICE_BUSY (CAMERASRC_ERROR | CAMSRC_IN_DEVICE_BUSY) +#define CAMERASRC_ERR_DEVICE_NOT_FOUND (CAMERASRC_ERROR | CAMSRC_IN_DEVICE_NOT_FOUND) +#define CAMERASRC_ERR_DEVICE_UNAVAILABLE (CAMERASRC_ERROR | CAMSRC_IN_DEVICE_REGISTER_TROUBLE) +#define CAMERASRC_ERR_DEVICE_WAIT_TIMEOUT (CAMERASRC_ERROR | CAMSRC_IN_WAIT_RES) +#define CAMERASRC_ERR_DEVICE_NOT_SUPPORT (CAMERASRC_ERROR | CAMSRC_IN_SUPPORT) +#define CAMERASRC_ERR_INVALID_STATE (CAMERASRC_ERROR | CAMSRC_IN_STATE) +#define CAMERASRC_ERR_PRIVILEGE (CAMERASRC_ERROR | CAMSRC_IN_PRIVILEGE) +#define CAMERASRC_ERR_SECURITY_SERVICE (CAMERASRC_ERROR | CAMSRC_IN_SECURITY_SERVICE) + + +#define CAMERASRC_IS_FAIL(_A_) (CAMERASRC_ERROR & (_A_)) + +#ifdef __cplusplus +} +#endif + +#endif /* __CAMERASRC_ERROR_H__ */ diff --git a/camerasrc/src/include/camerasrc-internal.h b/camerasrc/src/include/camerasrc-internal.h new file mode 100644 index 0000000..6b97589 --- /dev/null +++ b/camerasrc/src/include/camerasrc-internal.h @@ -0,0 +1,247 @@ +/* + * camerasrc + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang <jm80.yang@samsung.com> + * + * 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.1 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., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __CAMERASRC_INTERNAL_H__ +#define __CAMERASRC_INTERNAL_H__ + +#include "camerasrc-common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Video 4 linux control ID definitions (Extended by kernel team) + * extended pixel format for V4l2 + */ + + +/** + * Miscellaneous camera-dependent definitions + */ +#define CAMERASRC_DEV_INDEX_MAX 2 +#define CAMERASRC_AF_TOTALTIME 5000000 +#define CAMERASRC_AF_INTERVAL 20000 +#define CAMERASRC_AF_STOP_INTERVAL 10000 +#define CAMERASRC_MEGA_DEV_NAME "/dev/video0" +#define CAMERASRC_VGA_DEV_NAME "/dev/video0" +#define CAMERASRC_JPG_STILL_H_SYNC 2048 +#define CAMERASRC_JPG_STILL_V_SYNC 2048 +#define CAMERASRC_JPG_STILL_SKIP_FRAME 0 +#define CAMERASRC_RAW_STILL_THUMBNAIL_OFFSET 1689600 +#define CAMERASRC_JPG_STILL_THUMBNAIL_OFFSET 0x1bd000 +#define CAMERASRC_MAX_MAIN_JPEG_SIZE CAMERASRC_JPG_STILL_H_SYNC * CAMERASRC_JPG_STILL_V_SYNC /* 0x1bd000 */ +#define CAMERASRC_MAX_THM_JPEG_SIZE 0 +#define CAMERASRC_PREVIEW_BUFFER_NUM 6 +#define CAMERASRC_VIDEO_BUFFER_NUM 7 +#define CAMERASRC_STILL_BUFFER_NUM 1 +#define CAMERASRC_YUV_THMBNL_SIZE 320 * 240 * 2 +#define CAMERASRC_TIMEOUT_CRITICAL_VALUE 5000 +#define CAMERASRC_PRE_AF_INTERVAL 0 +#define CAMERASRC_REGISTER_SET_RETRY_NO 200 +#define CAMERASRC_V4L2_PREVIEW_PIX_FMT_DEFAULT V4L2_PIX_FMT_YUYV +#define CAMERASRC_V4L2_JPEG_CAPTURE_PIX_FMT_DEFAULT V4L2_PIX_FMT_JPEG +#define CAMERASRC_V4L2_JPG_YUV_CAPTURE_PIX_FMT_DEFAULT V4L2_PIX_FMT_MJPEG +#define CAMERASRC_V4L2_RGB_CAPTURE_PIX_FMT_DEFAULT V4L2_PIX_FMT_RGB565 + +#define CAMERASRC_SYNC_KEY_PATH "FUJITSU_M5MOLS" +#define CAMERASRC_SYNC_KEY_PREFIX 0x55 + +#define CAMERASRC_AF_DELAY_AFTER_SET_AF_AREA 350 /* msec */ + +#define _CAMERASRC_EXIF_COMP_CONF (0x00000000) | (0x00000001) | (0x00000002 << 8) | (0x00000003 << 16) /* Y Cb Cr - */ +#define _CAMERASRC_EXIF_COLORSPACE 0x00000001 +#define _CAMERASRC_EXIF_FOCAL_LEN_NUM 454 +#define _CAMERASRC_EXIF_FOCAL_LEN_DEN 100 +#define _CAMERASRC_EXIF_F_NUM_NUM 28 +#define _CAMERASRC_EXIF_F_NUM_DEN 10 +#define _CAMERASRC_EXIF_MAX_F_NUM_NUM_IN_APEX 3 + +#define _CAMERASRC_CMD_SUPPORT_EMBED_EXIF_DEF 0 + +/* + * |------------------------------------------------------------| + * | | Primary | Secondary | Extension| Unknown | + * |------------------------------------------------------------| + * | Index | 2 | 1 | 0 | -1 | + * |------------------------------------------------------------| + * + * |------------------------------------------------------------| + * | | 0 | 1 | 2 | 3 | + * |------------------------------------------------------------| + * | ID | Unknown | Secondary | Primary | Extension | + * |------------------------------------------------------------| + */ + +static int _camerasrc_dev_index[CAMERASRC_DEV_ID_NUM][CAMERASRC_DEV_RECOG_NUM] = +{ + {CAMERASRC_DEV_ID_SECONDARY, 0}, + {CAMERASRC_DEV_ID_PRIMARY, 1}, + {CAMERASRC_DEV_ID_EXTENSION, 2}, + {CAMERASRC_DEV_ID_UNKNOWN, -1}, +}; + + +/** + * preset size index + * |-------------------------------------------------------------------------| + * | | | YUV422P | YUV420P | SRGGB8 | SRGGB10 | + * |-------------------------------------------------------------------------| + * | | Highquality | O | X | X | X | + * | RAW |-----------------------------------------------------------| + * | | Normal | O | X | X | X | + * |-------------------------------------------------------------------------| + * | | Highquality | X | X | O | X | + * | JPEG |-----------------------------------------------------------| + * | | Normal | X | X | X | X | + * |-------------------------------------------------------------------------| + */ +static char _camerasrc_match_col_to_pix[CAMERASRC_DEV_ID_EXTENSION][CAMERASRC_COL_NUM][CAMERASRC_PIX_NUM][CAMERASRC_QUALITY_NUM] = +{ + {/*SECONDARY*/ + /*422P, 420P, SRGGB8, SRGGB10*/ + {{0x1,0x0}, {0x0,0x0}, {0x0,0x0}, {0x0,0x0}}, /**< RAW */ + {{0x0,0x0}, {0x0,0x0}, {0x0,0x0}, {0x0,0x0}}, /**< JPG */ + }, + {/*PRIMARY*/ + /*422P, 420P, SRGGB8, SRGGB10 */ + {{0x1,0x0}, {0x0,0x0}, {0x0,0x0}, {0x0,0x0}}, /**< RAW */ + {{0x0,0x0}, {0x0,0x0}, {0x0,0x1}, {0x0,0x1}}, /**< JPG */ + }, +}; /* {Normal quality, High quality} */ + +/* + * |--------------------------------------------------------------------------------| + * | | Support | MAX value | MIN value | CID | + * |--------------------------------------------------------------------------------| + * | Brightness | 1 | 8 | 0 | V4L2_CID_BRIGHTNESS | + * |--------------------------------------------------------------------------------| + * | Contrast | 1 | 9 | 0 | -1 | + * |--------------------------------------------------------------------------------| + * | Digital zoom | 1 | 100 | 0 | V4L2_CID_BASE+29 | + * |--------------------------------------------------------------------------------| + * | Optical zoom | 0 | -1 | -1 | -1 | + * |--------------------------------------------------------------------------------| + * | White balance | 1 | 9 | 0 | V4L2_CID_DO_WHITE_BALANCE | + * |--------------------------------------------------------------------------------| + * | Color tone | 1 | 14 | 0 | V4L2_CID_BASE+28 | + * |--------------------------------------------------------------------------------| + * | Program mode | 0 | -1 | -1 | -1 | + * |--------------------------------------------------------------------------------| + * | Flip | 1 | 1 | 0 | V4L2_CID_FLIP | + * |--------------------------------------------------------------------------------| + * | Flash | 1 | 2 | 0 | V4L2_CID_BASE+32 | + * |--------------------------------------------------------------------------------| + */ + +/* CUSTOM V4L2 CONTROL ID DEFINITIONS */ + +#define CAM_AF_STATUS_ONGOING 0 +#define CAM_AF_STATUS_FOCUSED 1 +#define CAM_AF_STATUS_FAILED 2 + +enum { + CAMERASRC_SENSOR_AF_STATUS_ONGOING = CAM_AF_STATUS_ONGOING, + CAMERASRC_SENSOR_AF_STATUS_FOCUSED = CAM_AF_STATUS_FOCUSED, + CAMERASRC_SENSOR_AF_STATUS_FAILED = CAM_AF_STATUS_FAILED +}; + +/* FACE_DETECTION CMD & STATUS */ +#define V4L2_CID_FACE_DETECTION (V4L2_CID_PRIVATE_BASE + 38) + +#define CAM_FACE_DETECTION_OFF 0 +#define CAM_FACE_DETECTION_ON 1 + +/* ESD INTERRUPT CHECK */ +/*To read interrupt status of "Data output stop from sensor"*/ +#define V4L2_CID_ESD_INT (V4L2_CID_PRIVATE_BASE + 40) + +#define CAM_ESD_INT_NORMAL 0 +#define CAM_ESD_INT_TROUBLE 1 + + +/* CUSTOM V4L2 CONTROL ID DEFINITIONS (END) */ +static int _camerasrc_ctrl_list[CAMERASRC_DEV_ID_EXTENSION][CAMERASRC_CTRL_NUM][CAMERASRC_CTRL_PROPERTY_NUM] = +{ /* { SUPPORT, MAX_VALUE, MIN_VALUE, CID, CURRENT_VALUE } */ + { /* Primary camera */ + {-1, 4, -4, V4L2_CID_EXPOSURE, 0}, /* Brightness */ + {-1, 3, -3, V4L2_CID_CONTRAST, 0}, /* Contrast */ + {-1, 30, 0, V4L2_CID_CAMERA_ZOOM, 0}, /* Digital zoom */ + {0, -1, -1, -1, -1}, /* Optical zoom */ + {-1, CAMERASRC_WHITEBALANCE_HORIZON, CAMERASRC_WHITEBALANCE_AUTO, V4L2_CID_WHITE_BALANCE_PRESET, CAMERASRC_WHITEBALANCE_AUTO}, /* White balance */ + {-1, CAMERASRC_COLORTONE_ANTIQUE, CAMERASRC_COLORTONE_NONE, V4L2_CID_COLORFX, CAMERASRC_COLORTONE_NONE}, /* Colortone */ + {-1, CAMERASRC_PROGRAM_MODE_BACK_LIGHT, CAMERASRC_PROGRAM_MODE_NORMAL, V4L2_CID_CAMERA_SCENE_MODE, CAMERASRC_PROGRAM_MODE_NORMAL}, /* program mode */ + {0, -1, -1, -1, -1}, /* Flip. V4L2_CID_VFLIP/HFLIP */ + {0, -1, -1, -1, -1}, /* PARTCOLOR_SRC */ + {0, -1, -1, -1, -1}, /* PARTCOLOR_DST */ + {0, -1, -1, -1, -1}, /* PARTCOLOR_MODE */ + {-1, 3, 0, V4L2_CID_CAM_STABILIZE, 0}, /* ANTI_HANDSHAKE */ + {-1, 2, 0, V4L2_CID_CAM_DR, 0}, /* WIDE_DYNAMIC_RANGE */ + {-1, 3, -3, V4L2_CID_SATURATION, 0}, /* SATURATION */ + {-1, 3, -3, V4L2_CID_SHARPNESS, 0}, /* SHARPNESS */ + {-1, -1, -1, V4L2_CID_CAMERA_ISO, -1}, /* ISO */ + {-1, -1, -1, V4L2_CID_CAMERA_METERING, -1}, /* PHOTOMETRY */ + }, + { /* Secondary camera */ + {0, -1, -1, V4L2_CID_CAMERA_BRIGHTNESS, -1}, /* Brightness */ + {0, -1, -1, V4L2_CID_CONTRAST, -1}, /* Contrast */ + {0, -1, -1, V4L2_CID_ZOOM_ABSOLUTE, -1}, /* Digital zoom */ + {0, -1, -1, -1, -1}, /* Optical zoom */ + {0, -1, -1, V4L2_CID_WHITE_BALANCE_PRESET, -1},/* White balance */ + {0, -1, -1, V4L2_CID_COLORFX, -1}, /* Colortone */ + {0, -1, -1, V4L2_CID_CAMERA_SCENE_MODE, -1}, /* program mode */ + {0, -1, -1, -1, -1}, /* Flip */ + {0, -1, -1, -1, -1}, /* PARTCOLOR_SRC */ + {0, -1, -1, -1, -1}, /* PARTCOLOR_DST */ + {0, -1, -1, -1, -1}, /* PARTCOLOR_MODE */ + {0, -1, -1, V4L2_CID_CAM_STABILIZE, -1}, /* ANTI_HANDSHAKE */ + {0, -1, -1, V4L2_CID_CAM_DR, -1}, /* WIDE_DYNAMIC_RANGE */ + {0, -1, -1, V4L2_CID_SATURATION, -1}, /* SATURATION */ + {0, -1, -1, V4L2_CID_SHARPNESS, -1}, /* SHARPNESS */ + {0, -1, -1, V4L2_CID_CAMERA_ISO, -1}, /* ISO */ + {0, -1, -1, V4L2_CID_CAMERA_METERING, -1}, /* PHOTOMETRY */ + }, +}; + +static char _camerasrc_misc_func_list[CAMERASRC_DEV_ID_EXTENSION][CAMERASRC_OP_REGISTER_VALUE][CAMERASRC_COL_NUM][CAMERASRC_MISC_FUNC_NUM] = +{ + {/*Primary*/ + /*Raw, JPG*/ + {{0x0,0x1}, {0x0,0x0}}, /*Preview*/ + {{0x0,0x1}, {0x0,0x0}}, /*Capture*/ + {{0x0,0x1}, {0x0,0x0}}, /*Video*/ + }, + {/*Secondary*/ + {{0x0,0x0}, {0x0,0x0}}, /*Preview*/ + {{0x0,0x0}, {0x0,0x0}}, /*Capture*/ + {{0x0,0x0}, {0x0,0x0}}, /*Video*/ + }/*{{Signal,Skip}, {Signal,Skip}}*/ +}; + +static int _camerasrc_af_support[CAMERASRC_DEV_ID_NUM] = {1, 0, 0, 0}; + +#ifdef __cplusplus +} +#endif + +#endif /*__CAMERASRC_INTERNAL_H__*/ diff --git a/camerasrc/src/include/camerasrc.h b/camerasrc/src/include/camerasrc.h new file mode 100644 index 0000000..2917f29 --- /dev/null +++ b/camerasrc/src/include/camerasrc.h @@ -0,0 +1,1488 @@ +/* + * camerasrc + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang <jm80.yang@samsung.com> + * + * 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.1 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., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __CAMERASRC_H__ +#define __CAMERASRC_H__ + +#include <stdint.h> /* to use uint64_t */ +#include <camerasrc-error.h> +#include <mm_ta.h> +#ifdef __cplusplus +extern "C" { +#endif + +/* GENERAL DEFINITIONS */ +/** + * Type definition of av camera src handle. + */ +typedef void *camsrc_handle_t; + + +/* ENUMERATION DEFINITIONS */ +/*! @enum camerasrc_state_t + * @brief Enumeration type for state transition + */ +typedef enum { + CAMERASRC_STATE_NONE = 0, + CAMERASRC_STATE_CREATED, + CAMERASRC_STATE_REALIZED, + CAMERASRC_STATE_READY, + CAMERASRC_STATE_PREVIEW, + CAMERASRC_STATE_STILL, + CAMERASRC_STATE_VIDEO, + CAMERASRC_STATE_UNREALIZED, + CAMERASRC_STATE_DESTROYED, + CAMERASRC_STATE_AF_IN_PROGRESS, +}camerasrc_state_t; + +/*! @enum camerasrc_dev_id_t + * @brief Enumeration type for camera device ID + * + * Devices will be managed by this IDs. (Independent with device index of V4L2) + */ +typedef enum { + CAMERASRC_DEV_ID_PRIMARY, /**< Higher resolution camera*/ + CAMERASRC_DEV_ID_SECONDARY, /**< Lower resolution camera*/ + CAMERASRC_DEV_ID_EXTENSION, /**< reserved for extension*/ + CAMERASRC_DEV_ID_UNKNOWN, /**< reserved for extension*/ + CAMERASRC_DEV_ID_NUM, /**< Number of IDs*/ +}camerasrc_dev_id_t; + +typedef enum { + CAMERASRC_COLOR_VIOLET = 0, + CAMERASRC_COLOR_PURPLE, + CAMERASRC_COLOR_MAGENTA_1, + CAMERASRC_COLOR_MAGENTA_2, + CAMERASRC_COLOR_RED_1, + CAMERASRC_COLOR_RED_2, + CAMERASRC_COLOR_BROWN, + CAMERASRC_COLOR_YELLOW, + CAMERASRC_COLOR_GREEN_1, + CAMERASRC_COLOR_GREEN_2, + CAMERASRC_COLOR_GREEN_3, + CAMERASRC_COLOR_GREEN_4, + CAMERASRC_COLOR_COBALT_BLUE, + CAMERASRC_COLOR_CYAN, + CAMERASRC_COLOR_BLUE_1, + CAMERASRC_COLOR_BLUE_2, + CAMERASRC_COLOR_GRAY, + CAMERASRC_COLOR_NUM, +}camerasrc_color_t; + +typedef enum { + CAMERASRC_PARTCOLOR_MODE_NONE = 0, + CAMERASRC_PARTCOLOR_MODE_SWAP, + CAMERASRC_PARTCOLOR_MODE_ACCENT, + CAMERASRC_PARTCOLOR_MODE_NUM, +}camerasrc_partcolor_mode_t; + +/*! @enum camerasrc_ctrl_t + * @brief Enumeration type for camera controls + * + * Special control entries for camera effects + * + * @remark Strobo can be controlled by this entry and ::camerasrc_set_strobo_status + */ +typedef enum { + CAMERASRC_CTRL_BRIGHTNESS = 0, /**< Brightness control entry*/ + CAMERASRC_CTRL_CONTRAST, /**< Contrast control entry*/ + CAMERASRC_CTRL_DIGITAL_ZOOM, /**< Digital zoom control entry*/ + CAMERASRC_CTRL_OPTICAL_ZOOM, /**< Optical zoom control entry*/ + CAMERASRC_CTRL_WHITE_BALANCE, /**< White balance control entry*/ + CAMERASRC_CTRL_COLOR_TONE, /**< Color tone control entry*/ + CAMERASRC_CTRL_PROGRAM_MODE, /**< Program mode control entry*/ + CAMERASRC_CTRL_FLIP, /**< Flip control entry*/ + CAMERASRC_CTRL_PARTCOLOR_SRC, /**< Partcolor effect source */ + CAMERASRC_CTRL_PARTCOLOR_DST, /**< Partcolor effect destination */ + CAMERASRC_CTRL_PARTCOLOR_MODE, /**< Partcolor effect mode */ + CAMERASRC_CTRL_ANTI_HANDSHAKE, /**< Anti-handshake control, 0:OFF / 1:ON / 2:AUTO / 3:MOVIE */ + CAMERASRC_CTRL_WIDE_DYNAMIC_RANGE, /**< wide dynamic control, 0:OFF / 1:ON / 2:AUTO */ + CAMERASRC_CTRL_SATURATION, /**< Saturation value control */ + CAMERASRC_CTRL_SHARPNESS, /**< Sharpness value control */ + CAMERASRC_CTRL_ISO, /**< Sensor sensitivity*/ + CAMERASRC_CTRL_PHOTOMETRY, /**< Exposure mode*/ + CAMERASRC_CTRL_NUM, /**< Number of Controls*/ +}camerasrc_ctrl_t; + +/*! @enum camerasrc_af_mode_t + * @brief AF operation mode + */ +typedef enum { + CAMERASRC_AF_MODE_AUTO = 0, /**< Auto Focus */ + CAMERASRC_AF_MODE_MANUAL, /**< Manual Focus */ + CAMERASRC_AF_MODE_PAN, /**< Pan Focus */ + CAMERASRC_AF_MODE_TOUCH_AUTO, /**< Touch Auto Focus */ + CAMERASRC_AF_MODE_CONTINUOUS, /**< Continuous Focus */ + CAMERASRC_AF_MODE_NUM, /**< Number of AF modes */ +}camerasrc_af_mode_t; + +/*! @enum camerasrc_af_scan_range_t + * @brief AF scan range + * AF scan range + */ +typedef enum { + CAMERASRC_AF_RANGE_NORMAL = 0, /**< Scan autofocus in normal range */ + CAMERASRC_AF_RANGE_MACRO, /**< Scan autofocus in macro range(close distance) */ + CAMERASRC_AF_RANGE_FULL, /**< Scan autofocus in full range(all range scan, limited by dev spec) */ + CAMERASRC_AF_RANGE_NUM, /**< Number of AF range types */ +}camerasrc_af_scan_range_t; + +/*! @enum camerasrc_resol_name_t + * @brief Enumeration type of resolution settings based on traditional resolution name + * Means pixel order of contents. + * @remark In the Grandprix, only YUV422P & RGGB8 is used + */ +typedef enum { + CAMERASRC_RESOL_QQCIF = 0, /**< 88 x 72 */ + CAMERASRC_RESOL_QQVGA, /**< 160 x 120 */ + CAMERASRC_RESOL_QCIF, /**< 176 x 144 */ + CAMERASRC_RESOL_QVGA, /**< 320 x 240 */ + CAMERASRC_RESOL_CIF, /**< 352 x 288 */ + CAMERASRC_RESOL_VGA, /**< 640 x 480 */ + CAMERASRC_RESOL_WVGA, /**< 800 x 480 */ + CAMERASRC_RESOL_SVGA, /**< 800 x 600 */ + CAMERASRC_RESOL_WSXGA, /**< 1280 x 960 (1M) */ + CAMERASRC_RESOL_UXGA, /**< 1600 x 1200 (2M) */ + CAMERASRC_RESOL_QXGA, /**< 2048 x 1536 (3M) */ + CAMERASRC_RESOL_WQSXGA, /**< 2560 x 1920 (5M) */ + CAMERASRC_RESOL_720P, /**< 1280 x 720 (720P) */ + CAMERASRC_RESOL_WQVGA, /**< 400 x 240 */ + CAMERASRC_RESOL_RQVGA, /**< 240 x 320 */ + CAMERASRC_RESOL_RWQVGA, /**< 240 x 400 */ + CAMERASRC_RESOL_QVGA_60FPS, /**< 320 x 240 60FPS(Slow motion I) */ + CAMERASRC_RESOL_QVGA_120FPS, /**< 320 x 240 60FPS(Slow motion II) */ + CAMERASRC_RESOL_NUM, +}camerasrc_resol_name_t; + +/*! @enum camerasrc_pix_format_t + * @brief Means order of pixel of contents + * Means pixel order of contents. + * @remark In the Grandprix, only YUV422P & RGGB8 is used + */ +typedef enum { + CAMERASRC_PIX_NONE = -1, /**< Default value or Not supported */ + CAMERASRC_PIX_YUV422P = 0, /**< Pixel format like YYYYYYYYUUUUVVVV*/ + CAMERASRC_PIX_YUV420P, /**< Pixel format like YYYYYYYYUUVV*/ + CAMERASRC_PIX_YUV420, /**< Pixel format like YYYYYYYYUVUV*/ + CAMERASRC_PIX_SN12, /**< YUV420 (interleaved, non-linear) */ + CAMERASRC_PIX_ST12, /**< YUV420 (interleaved, tiled, non-linear) */ + CAMERASRC_PIX_YUY2, /**< YUV 4:2:2 as for UYVY but with different component ordering within the u_int32 macropixel */ + CAMERASRC_PIX_RGGB8, /**< Raw RGB Pixel format like CCD order, a pixel consists of 8 bits, Actually means JPEG + JPEG image output */ + CAMERASRC_PIX_RGGB10, /**< Raw RGB Pixel format like CCD order, a pixel consists of 10 bits, Actually means JPEG + YUV image output */ + CAMERASRC_PIX_RGB565, /**< Raw RGB Pixel format like CCD order, a pixel consists of 10 bits, Actually means JPEG + YUV image output */ + CAMERASRC_PIX_UYVY, /**< YUV 4:2:2 */ + CAMERASRC_PIX_NV12, /**< YUV 4:2:0, 8-bit Y plane followed by an interleaved U/V plane with 2x2 subsampling */ + CAMERASRC_PIX_INTERLEAVED, /**< JPEG/YUYV interleaved data format for zero shutter lag */ + CAMERASRC_PIX_NUM, /**< Number of pixel formats*/ +}camerasrc_pix_format_t; + +/*! @enum camerasrc_colorspace_t + * @brief Means stored order or compressed status of image. + * Means stored order or compressed status of image. supplements of camerasrc_pix_format_t + * + * @note RAW means RGB/YUV pixel data, JPEG means compressed JPG file with marker information(header) + */ +typedef enum { + CAMERASRC_COL_NONE = -1, /**< Default value or Not supported */ + CAMERASRC_COL_RAW, /**< Non-compressed RGB/YUV pixel data*/ + CAMERASRC_COL_JPEG, /**< Compressed jpg data*/ + CAMERASRC_COL_NUM, /**< Number of colorspace data*/ +}camerasrc_colorspace_t; + +/*! @enum camerasrc_auto_focus_status_t + * @brief AF status + * AF status + */ +typedef enum { + CAMERASRC_AUTO_FOCUS_STATUS_RELEASED, /**< AF status released.*/ + CAMERASRC_AUTO_FOCUS_STATUS_ONGOING, /**< AF in progress*/ + CAMERASRC_AUTO_FOCUS_STATUS_NUM, /**< Number of AF status*/ +}camerasrc_auto_focus_status_t; + +/*! @enum camerasrc_auto_focus_cmd_t + * @brief AF status + * AF status + */ +typedef enum { + CAMERASRC_AUTO_FOCUS_CMD_NULL, /**< Null command.*/ + CAMERASRC_AUTO_FOCUS_CMD_START, /**< Start AF.*/ + CAMERASRC_AUTO_FOCUS_CMD_STOP, /**< Stop AF.*/ + CAMERASRC_AUTO_FOCUS_CMD_KILL, /**< Kill AF thread.*/ + CAMERASRC_AUTO_FOCUS_CMD_NUM, /**< Number of AF command*/ +}camerasrc_auto_focus_cmd_t; + +/*! @enum camerasrc_auto_focus_result_t + * @brief AF status + * AF status + */ +typedef enum { + CAMERASRC_AUTO_FOCUS_RESULT_FOCUSED = 2, /**< Focused.*/ + CAMERASRC_AUTO_FOCUS_RESULT_FAILED, /**< AF failed.*/ + CAMERASRC_AUTO_FOCUS_RESULT_NUM, /**< Number of AF result*/ +}camerasrc_auto_focus_result_t; + +/*! @enum camerasrc_ae_lock_t + * @brief + */ +typedef enum { + CAMERASRC_AE_LOCK = 0, + CAMERASRC_AE_UNLOCK, + CAMERASRC_AE_NUM, +}camerasrc_ae_lock_t; + +/*! @enum camerasrc_io_method_t + * @brief + */ +typedef enum { + CAMERASRC_IO_METHOD_READ= 0, + CAMERASRC_IO_METHOD_MMAP, + CAMERASRC_IO_METHOD_USRPTR, + CAMERASRC_IO_METHOD_NUM, +}camerasrc_io_method_t; + +/*! @enum camerasrc_buffer_queued_status + * @brief + */ +typedef enum { + CAMERASRC_BUFFER_QUEUED = 0, + CAMERASRC_BUFFER_DEQUEUED = 1, +}camerasrc_buffer_queued_status; + + +/* STRUCTURE DEFINITIONS */ + +typedef struct _camerasrc_rect_t { + int x; + int y; + int width; + int height; +} camerasrc_rect_t; + +/*! @struct camsrc_frac_t + * @brief Time per frame or frame per second will be expressed by this structure + * Time per frame or frame per second will be expressed by this structure + */ +typedef struct _camerasrc_frac_t { + int numerator; /**< Upper number of fraction*/ + int denominator; /**< Lower number of fraction*/ +} camerasrc_frac_t; + +/*! @struct camerasrc_buffer_t + * @brief data buffer + * Image data buffer + */ +typedef struct _camerasrc_buffer_t { + unsigned int length; /**< Size of stored data*/ + unsigned char* start; /**< Start address of data*/ + camerasrc_buffer_queued_status queued_status; /**< Queued or Dequeued status */ +} camerasrc_buffer_t; + +/*! @struct camerasrc_usr_buf_t + * @brief data buffer set to present usrptr buffer to camsrctem + * Image data buffer set + */ +typedef struct { + camerasrc_buffer_t* present_buffer; + unsigned int num_buffer; +} camerasrc_usr_buf_t; + +/*! @struct camerasrc_dimension_t + * @brief For non-regular size resolution + * width and height can be set independently + */ +typedef struct _camerasrc_dimension_t { + int width; + int height; +} camerasrc_dimension_t; + +/*! @union camerasrc_size_t + * @brief Size can be expressed by resolution name(predefined) and dimension(x, y) + */ +typedef union _camerasrc_size_t { + camerasrc_resol_name_t res; /**< Predefined resolution name */ + camerasrc_dimension_t dim; /**< Dimensional expression */ +} camerasrc_size_t; + +/*! @struct camerasrc_format_t + * @brief Format description structure + * in/output format description structure just like v4l2_format + */ +typedef struct _camerasrc_format_t { + camerasrc_size_t img_size; + camerasrc_size_t thumb_size; /**< Thumbnail size. Only effective with CAMERASRC_PIX_RGGB8 or CAMERASRC_PIX_RGGB10 */ + camerasrc_pix_format_t pix_format; /**< pixel order format*/ + int num_planes; /**< bytes per a line*/ + int bytesperline; /**< bytes per a line*/ + int sizeimage; /**< size of whole image*/ + camerasrc_colorspace_t colorspace; /**< stored status of image*/ + unsigned int quality; /**< jpeg compress ratio*/ + unsigned int is_highquality_mode; /**< picture quality is high or normal */ + int rotation; /**< Rotation angle of camera input */ +} camerasrc_format_t; + +typedef struct _camerasrc_ctrl_query_t { + int support; /**<1: support, 0: Not support, -1: extra support(Non v4l2)*/ + int max; /**<Integer max value(includes enums)*/ + int min; /**<Integer min value(includes enums)*/ +}camerasrc_ctrl_query_t; + +typedef struct _camerasrc_exif_t { + /* Dynamic value */ + unsigned int exposure_time_numerator; /**< Exposure time, given in seconds */ + unsigned int exposure_time_denominator; + int shutter_speed_numerator; /**< Shutter speed, given in APEX(Additive System Photographic Exposure) */ + int shutter_speed_denominator; + int brigtness_numerator; /**< Value of brightness, before firing flash, given in APEX value */ + int brightness_denominator; + unsigned short int iso; /**< Sensitivity value of sensor */ + unsigned short int flash; /**< Whether flash is fired(1) or not(0) */ + int metering_mode; /**< metering mode in EXIF 2.2 */ + int exif_image_width; /**< Size of image */ + int exif_image_height; + int exposure_bias_in_APEX; /**< Exposure bias in APEX standard */ + int software_used; /**< Firmware S/W version */ + int focal_len_numerator; /**< Lens focal length (f = 4.5mm) */ + int focal_len_denominator; + int aperture_f_num_numerator; /**< Aperture value (f_num = 2.8) */ + int aperture_f_num_denominator; + int aperture_in_APEX; /**< Aperture value in APEX standard */ + int max_lens_aperture_in_APEX; /**< Max aperture value in APEX standard */ + + /* Fixed value */ + int component_configuration; /**< color components arrangement (YCbCr = 1230) */ + int colorspace; /**< colorspace information (sRGB=1) */ +}camerasrc_exif_t; + +typedef struct _camerasrc_frame_data_t { + int index; + unsigned int phyAddrY; + unsigned int phyAddrCbCr; + unsigned int virAddrY; + unsigned int virAddrCbCr; +}camerasrc_frame_data_t; + +/* JPEG/YUV interleaved data */ +#define INTERLEAVED_JPEG_MAX_SIZE (1024*1024*6) /* 6 Mbyte */ + +/* Fixed focal length and aperture f-number */ +#define CAMERASRC_PRIMARY_FOCAL_LEGNTH_NUM 397 +#define CAMERASRC_PRIMARY_FOCAL_LEGNTH_DENOM 100 +#define CAMERASRC_PRIMARY_F_NUMBER_NUM 265 +#define CAMERASRC_PRIMARY_F_NUMBER_DENOM 100 +#define CAMERASRC_SECONDARY_FOCAL_LEGNTH_NUM 273 +#define CAMERASRC_SECONDARY_FOCAL_LEGNTH_DENOM 100 +#define CAMERASRC_SECONDARY_F_NUMBER_NUM 28 +#define CAMERASRC_SECONDARY_F_NUMBER_DENOM 10 + +/* For Query functionalities + For Querying capabilities */ +/*! Use static size of structures for querying because of performance + */ + +#define MAX_NUM_FMT_DESC 32 +#define MAX_NUM_RESOLUTION 32 +#define MAX_NUM_AVAILABLE_TPF 16 +#define MAX_NUM_AVAILABLE_FPS 16 +#define MAX_NUM_CTRL_LIST_INFO 64 +#define MAX_NUM_CTRL_MENU 64 +#define MAX_SZ_CTRL_NAME_STRING 32 +#define MAX_SZ_DEV_NAME_STRING 32 + +enum{ + CAMERASRC_FCC_USE_NONE = 0x00000001, + CAMERASRC_FCC_USE_REC_PREVIEW = 0x00000010, + CAMERASRC_FCC_USE_CAP_PREVIEW = 0x00000100, + CAMERASRC_FCC_USE_RECORDING = 0x00001000, + CAMERASRC_FCC_USE_NORMAL_CAPTURE = 0x00010000, + CAMERASRC_FCC_USE_CONT_CAPTURE = 0x00100000, + CAMERASRC_FCC_USE_NUM = 6, +}; + +/*! @struct camerasrc_tpf_frac_t + * @brief For timeperframe as fraction type + * Elapse time consumed by one frame, reverse of FPS + */ +typedef struct { + int num; + int den; +}camerasrc_tpf_frac_t; + +/*! @struct camerasrc_resolution_t + * @brief For querying supported resolutions + */ +typedef struct { + int w; + int h; + + /* Available time per frame(tpf) as each pixelformat */ + int num_avail_tpf; + camerasrc_tpf_frac_t tpf[MAX_NUM_AVAILABLE_TPF]; +} camerasrc_resolution_t; + +/*! @struct camerasrc_fmt_desc_t + * @brief For querying supported format type + */ +typedef struct { + /* fourcc name of each pixelformat */ + unsigned int fcc; + int fcc_use; + + /* Available resolutions as each pixelformat */ + int num_resolution; + camerasrc_resolution_t resolutions[MAX_NUM_RESOLUTION]; +} camerasrc_fmt_desc_t; + +/*! @struct camerasrc_caps_info_t + * @brief For querying image input capabilities + */ +typedef struct { + char dev_name[MAX_SZ_DEV_NAME_STRING]; + camerasrc_dev_id_t input_id; + int num_fmt_desc; + camerasrc_fmt_desc_t fmt_desc[MAX_NUM_FMT_DESC]; + + int num_preview_resolution; + int preview_resolution_width[MAX_NUM_RESOLUTION]; + int preview_resolution_height[MAX_NUM_RESOLUTION]; + + int num_capture_resolution; + int capture_resolution_width[MAX_NUM_RESOLUTION]; + int capture_resolution_height[MAX_NUM_RESOLUTION]; + + int num_preview_fmt; + unsigned int preview_fmt[MAX_NUM_FMT_DESC]; + + int num_capture_fmt; + unsigned int capture_fmt[MAX_NUM_FMT_DESC]; + + int num_fps; + camerasrc_frac_t fps[MAX_NUM_AVAILABLE_FPS]; +} camerasrc_caps_info_t; + +/* For Querying controls */ +enum { + CTRL_TYPE_RANGE = 0, /**< Integer, range type */ + CTRL_TYPE_BOOL, /**< Boolean type, 1 equals positive and 0 is negative */ + CTRL_TYPE_ARRAY, /**< Array type, also called menu type. each integer(enumeration) value can be set */ + CTRL_TYPE_UNKNOWN, /**< Unknown type, for error control */ + CTRL_TYPE_NUM, +}; + +/*! @struct camerasrc_ctrl_menu_t + * @brief For querying menu of specified controls + */ +typedef struct { + int menu_index; /**< What number is used for accessing this menu */ + char menu_name[MAX_SZ_CTRL_NAME_STRING]; /**< name of each menu */ +}camerasrc_ctrl_menu_t; + +/*! @struct camerasrc_ctrl_info_t + * @brief For querying controls detail + */ +typedef struct { + camerasrc_ctrl_t camsrc_ctrl_id; /**< camsrc camera control ID for controlling this */ + int v4l2_ctrl_id; /**< v4l2 ctrl id, user not need to use this. see @struct camerasrc_ctrl_t */ + int ctrl_type; /**< Type of this control */ + char ctrl_name[MAX_SZ_CTRL_NAME_STRING]; /**< Name of this control */ + int min; /**< minimum value */ + int max; /**< maximum value */ + int step; /**< unit of the values */ + int default_val; /**< Default value of the array or range */ + int num_ctrl_menu; /**< In the case of array type control, number of supported menu information */ + camerasrc_ctrl_menu_t ctrl_menu[MAX_NUM_CTRL_MENU]; /**< @struct camerasrc_ctrl_menu_t for detailed each menu information*/ +} camerasrc_ctrl_info_t; + +/*! @struct camerasrc_ctrl_list_info_t + * @brief For querying controls + */ +typedef struct { + int num_ctrl_list_info; /**< Number of supported controls */ + camerasrc_ctrl_info_t ctrl_info[MAX_NUM_CTRL_LIST_INFO]; /**< @struct camerasrc_ctrl_info_t for each control information */ +} camerasrc_ctrl_list_info_t; + + +/* capabilities field */ +#define CAMERASRC_STROBE_CAP_NONE 0x0000 /* No strobe supported */ +#define CAMERASRC_STROBE_CAP_OFF 0x0001 /* Always flash off mode */ +#define CAMERASRC_STROBE_CAP_ON 0x0002 /* Always use flash light mode */ +#define CAMERASRC_STROBE_CAP_AUTO 0x0004 /* Flashlight works automatic */ +#define CAMERASRC_STROBE_CAP_REDEYE 0x0008 /* Red-eye reduction */ +#define CAMERASRC_STROBE_CAP_SLOWSYNC 0x0010 /* Slow sync */ +#define CAMERASRC_STROBE_CAP_FRONT_CURTAIN 0x0020 /* Front curtain */ +#define CAMERASRC_STROBE_CAP_REAR_CURTAIN 0x0040 /* Rear curtain */ +#define CAMERASRC_STROBE_CAP_PERMANENT 0x0080 /* keep turned on until turning off */ +#define CAMERASRC_STROBE_CAP_EXTERNAL 0x0100 /* use external strobe */ + +typedef struct _camerasrc_extra_info_t{ + unsigned int strobe_caps; /**< Use above caps field */ + unsigned int detection_caps; /**< Just boolean */ + unsigned int reserved[4]; +} camerasrc_extra_info_t; +/* END For Query functionalities */ + +/*! @def CAMERASRC_SET_SIZE_BY_DIMENSION + * @brief Utility definitions for setting non-regular size + */ +#define CAMERASRC_SET_SIZE_BY_DIMENSION(format, img_width, img_height) { \ + format.img_size.dim.width = img_width; \ + format.img_size.dim.height = img_height; \ +} + + +/* CALLBACK DEFINITIONS */ +/*! @typedef camerasrc_callback_t + * @brief Called back when auto-focusing returns + * This callback will be called when the lens properly auto-focused + */ +typedef int (*camerasrc_callback_t) (camsrc_handle_t handle, int state, void* usr_data); + +/* Static variables */ +/** + * Label for camera control. This static variable has a label for each of camerasrc_ctrl_t enumeration. + * When enumeration of camerasrc_ctrl_t is increased, this variable should be increased, too. + * This string could be used as a key by user. + * Reference : camerasrc_ctrl_t, _camerasrc_ctrl_list + */ + +static char *camerasrc_ctrl_label[CAMERASRC_CTRL_NUM] = +{ + "brightness", /**< label for CAMERASRC_CTRL_BRIGHTNESS */ + "contrast", /**< label for CAMERASRC_CTRL_CONTRAST */ + "digital zoom", /**< label for CAMERASRC_CTRL_DIGITAL_ZOOM */ + "optical zoom", /**< label for CAMERASRC_CTRL_OPTICAL_ZOOM */ + "white balance", /**< label for CAMERASRC_CTRL_WHITE_BALANCE */ + "color tone", /**< label for CAMERASRC_CTRL_COLOR_TONE */ + "program mode", /**< label for CAMERASRC_CTRL_PROGRAM_MODE */ + "flip", /**< label for CAMERASRC_CTRL_FLIP */ + "partcolor src", /**< label for CAMERASRC_CTRL_PARTCOLOR_SRC */ + "partcolor dst", /**< label for CAMERASRC_CTRL_PARTCOLOR_DST */ + "partcolor mode", /**< label for CAMERASRC_CTRL_PARTCOLOR_MODE */ + "anti handshake", /**< label for CAMERASRC_CTRL_ANTI_HANDSHAKE */ + "wide dynamic range", /**< label for CAMERASRC_CTRL_WIDE_DYNAMIC_RANGE */ + "saturation", /**< label for CAMERASRC_CTRL_SATURATION */ + "sharpness", /**< label for CAMERASRC_CTRL_SHARPNESS */ + "iso", /**< label for CAMERASRC_CTRL_ISO */ + "photometry", /**< label for CAMERASRC_CTRL_PHOTOMETRY */ +}; + +/* FUNCTION DEFINITIONS */ + +/**** M A I N O P E R A T I O N ****/ + +/** + * allocate the handle, set initial state & settings + * + * @param[in] phandle ::camsrc_handle_t camerasrc context handle to be created + * @return Success on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t code + * @see camerasrc_destroy + * @note State transition : [CAMERASRC_STATE_NONE] => [CAMERASRC_STATE_CREATED] + * Phase description : Non-running phase + */ +int camerasrc_create(camsrc_handle_t *phandle); + +/** + * proceed fd close, other finalization routines + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * + * @return Success on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t code + * + * @see <camerasrc_create> + * + * @note State transition : [CAMERASRC_STATE_UNREALIZED] => [CAMERASRC_STATE_DESTROYED] + * Phase description : Non-running phase + */ +int camerasrc_destroy(camsrc_handle_t handle); + +/** + * free device context handle, other finalization routines + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @return Success on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t code + * @see camerasrc_create + * @note State transition : [CAMERASRC_STATE_UNREALIZED] => [CAMERASRC_STATE_DESTROYED] + * Phase description : Non-running phase + */ +int camerasrc_close_device(camsrc_handle_t handle); + +/** + * Get the state of camerasrc context handle + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[out] state ::camerasrc_state_t camerasrc context current state + * @return Success on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t code + * + */ +int camerasrc_get_state(camsrc_handle_t handle, camerasrc_state_t* state); + +/** + * Allocate the device context handle, open device node and do the miscellaneous settings + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @return Success on ::camerasrc_handle_t or returns NULL code, and displays debug message + * @see camerasrc_unrealize + * @note State transition : [CAMERASRC_STATE_CREATED] => [CAMERASRC_STATE_REALIZED] + * Phase description : Non-running phase + * device name can be dependent on kernel module + */ +int camerasrc_realize(camsrc_handle_t handle); + +/** + * Deallocate the device structure of buffers, close device + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @return Success on ::camerasrc_handle_t or returns NULL code, and displays debug message + * @see camerasrc_realize + * @note State transition : [CAMERASRC_STATE_READY] => [CAMERASRC_STATE_UNREALIZED] + * Phase description : Transit to Non-running phase + */ +int camerasrc_unrealize(camsrc_handle_t handle); + +/** + * Prepare Handle to be ready to capture + * Can change settings like below at this state + * - camera device ID setting + * - color format setting + * - image size setting + * - image storing method + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @return Success on ::camerasrc_handle_t or returns NULL code, and displays debug message + * @see camerasrc_stop + * @note State transition : [CAMERASRC_STATE_REALIZED] => [CAMERASRC_STATE_READY] + * Phase description : Running phase + */ +int camerasrc_start(camsrc_handle_t handle); + +/** + * Present user buffer to camerasrc and force to use that buffer. + * After calling this API, all core routine of camerasrc camera will use + * User pointer method for managing buffers. + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[in] present_buf ::camerasrc_usr_buf_t Buffer set to present to camerasrc + * @param[in] io_method ::camerasrc_io_method_t Enum type represent to IO method + * @return Success on ::camsrc_handle_t or returns NULL code, and displays debug message + * @see camerasrc_io_method_t + * + */ +int camerasrc_present_usr_buffer(camsrc_handle_t handle, camerasrc_usr_buf_t* present_buf, camerasrc_io_method_t io_method); + +/** + * Get total number of buffer which managed in camerasrc currently. + * If this called, it will return default number of buffer in MMAP mode. + * but use this API after calling ::camerasrc_present_usr_buffer , It will + * return User specfied buffer number. + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[in] num_buffer Number of buffer that's managed in camerasrc currently + * @return Success on ::camsrc_handle_t or returns NULL code, and displays debug message + * @see camerasrc_io_method_t + * + */ +int camerasrc_get_num_buffer(camsrc_handle_t handle, unsigned int* num_buffer); + +/** + * Get Input/Output method which is used when access camera driver + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[in] io_method ::camerasrc_io_method_t method enum value + * @return Success on ::camsrc_handle_t or returns NULL code, and displays debug message + * @see camerasrc_io_method_t + * + */ +int camerasrc_get_io_method(camsrc_handle_t handle, camerasrc_io_method_t* io_method); + +/** + * Inner ring buffer start refreshing. refresh process occurs asynchronously, and + * ::camerasrc_wait_frame_available function can anounce when it is available. + * + * Camera is grabbing High quality, maybe low speed frame(dependent on device) + * - Cant approach the [AF] state + * - preview frames arent always automatically fed. If not, must request repeatedly + * - If device supports continuous focusing, it can be enabled at this state in case + * of multishot. + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * @note State transition : [CAMERASRC_STATE_READY] => [CAMERASRC_STATE_STILL] + * Phase description : Running phase + */ +int camerasrc_start_still_stream(camsrc_handle_t handle); + +/** + * Inner ring buffer start refreshing. refresh process occurs asynchronously, and + * ::camerasrc_wait_frame_available function can anounce when it is available. + * + * Camera is grabbing low quality, high speed frame + * - Can attempt the [AF] state only at this state + * - preview frames are always automatically fed + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * @note State transition : [CAMERASRC_STATE_READY] => [CAMERASRC_STATE_PREVIEW] + * Phase description : Running phase + */ +int camerasrc_start_preview_stream(camsrc_handle_t handle); + +/** + * Stop frame refreshing. Ring buffers don't be refreshed any more + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @return Success on ::camerasrc_handle_t or returns NULL code, and displays debug message + * @see camerasrc_stop + * @note State transition : [CAMERASRC_STATE_STILL/PREVIEW/VIDEO] => [CAMERASRC_STATE_READY] + * Phase description : Running phase + */ +int camerasrc_stop_stream(camsrc_handle_t handle); + +/** + * Query image buffer size. buffer allocation guide function. + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[out] main_img_size main image maximum size + * @param[out] thm_img_size thumb nail image maximum size + * @return Success on ::camsrc_handle_t or returns NULL code, and displays debug message + * + */ +int camerasrc_query_img_buf_size(camsrc_handle_t handle, unsigned int* main_img_size, unsigned int* thm_img_size); + +/** + * non-busy waiting function for image frame available + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[in] timeout main image maximum size + * @return Success on ::camsrc_handle_t or returns NULL code, and displays debug message + * + */ +int camerasrc_wait_frame_available(camsrc_handle_t handle, long int timeout); + +/** + * Check emp shock status + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[out] check_val + * @return Success on ::camsrc_handle_t or returns NULL code, and displays debug message + * + */ +int camerasrc_check_esd_shock(camsrc_handle_t *handle, int *check_val); + +/** + * Queue(in user space, almost same with free buffer) buffer to dev's ring buffer + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @param[in] buffer ::camerasrc_buffer_t buffer + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * + */ +int camerasrc_queue_buffer(camsrc_handle_t handle, int buf_index, camerasrc_buffer_t *buffer); + +/** + * Dequeue(Pop) buffer from v4l2 driver to usr space. + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[out] buf_index main buffer index number to be dequeued. + * @param[out] buffer main image buffer + * @param[out] thm_buffer thumbnail image buffer + * @return Success on ::camsrc_handle_t or returns NULL code, and displays debug message + * + */ +int camerasrc_dequeue_buffer(camsrc_handle_t handle, int *buf_index, camerasrc_buffer_t *buffer, camerasrc_buffer_t *thm_buffer); + +/** + * Read frame from camera device. + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[out] buffer ::camerasrc_buffer_t main image buffer to be get. + * @param[out] thm_buffer ::camerasrc_buffer_t thumbnail image buffer to be get. + * @param[out] buffer_index ::int v4l2 buffer index. + * @note if thm_buffer is NULL, thumbnail image will be discarded + * + */ +int camerasrc_read_frame(camsrc_handle_t handle, camerasrc_buffer_t *main_img_buffer, camerasrc_buffer_t *thm_img_buffer, int *buffer_index); + +/** + * Get screennail buffer + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[out] scrnl_buf ::camerasrc_buffer_t screennail buffer to be gotten + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + */ +int camerasrc_get_screennail_buffer(camsrc_handle_t handle, camerasrc_buffer_t *scrnl_buf); + +/** + * Set autofocus callback. ::camerasrc_callback_t type defined function can be set + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @param[in] cb ::camerasrc_callback_t callback after focusing over + * @param[in] use_data ::void * user data pointer that will be passed to callback + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * @note Callback function can be set on READY or REALIZED state + * + */ +int camerasrc_set_focused_callback(camsrc_handle_t handle, camerasrc_callback_t cb, void *usr_data); + +/** + * Set autofocusing area. autofocusing will be performed refer this rect of the preview + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[in] rect ::camerasrc_rect_t rectangle area for auto focusing + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + */ +int camerasrc_set_autofocusing_area(camsrc_handle_t handle, camerasrc_rect_t* rect); + +/** + * Get autofocusing area. + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[out] rect ::camerasrc_rect_t rectangle area for auto focusing + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + */ +int camerasrc_get_autofocusing_area(camsrc_handle_t handle, camerasrc_rect_t* rect); + +/** + * Start auto focusing with ::camerasrc_af_mode. After ::interval time, call the callback + * function with ::camerasrc_af_status value. + * Auto-focus is in progress. Cant return preview state + * before time-out, success, call camerasrc_autofocus_stop + * - If focused, focus status will be locked at preview state + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @param[in] af_mode Auto focusing operation mode see ::camerasrc_af_mode + * @param[in] interval interval time in millisecond + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * @note State transition : [CAMERASRC_STATE_PREVIEW] => [CAMERASRC_STATE_AF_IN_PROGRESS] + * Phase description : Running phase + */ +int camerasrc_start_autofocusing(camsrc_handle_t handle); + +/** + * Stop auto focusing + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * @note State transition : [CAMERASRC_STATE_AF_IN_PROGRESS] => [CAMERASRC_STATE_PREVIEW] + * Phase description : Running phase + */ +int camerasrc_stop_autofocusing(camsrc_handle_t handle); + +/** + * Release auto focusing + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * @note State transition : [CAMERASRC_STATE_AF_IN_PROGRESS] => [CAMERASRC_STATE_PREVIEW] + * Phase description : Running phase + */ +int camerasrc_release_autofocusing(camsrc_handle_t handle); + +/** + * Initialize auto focusing mode to specified focal length + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[in] af_mode ::camerasrc_af_mode_t Auto focusing mode + * @param[in] af_range ::camerasrc_af_scan_range_t Auto focusing range + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + */ +int camerasrc_init_autofocusing_mode(camsrc_handle_t handle, camerasrc_af_mode_t af_mode, camerasrc_af_scan_range_t af_range); + +/** + * Get current auto focusing mode + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[out] af_mode ::camerasrc_af_mode_t Auto focusing mode + * @param[out] af_range ::camerasrc_af_scan_range_t Auto focusing range + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + */ +int camerasrc_get_autofocusing_mode(camsrc_handle_t handle, camerasrc_af_mode_t* af_mode, camerasrc_af_scan_range_t* af_range); + +/** + * Get current auto focusing status + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[out] af_status ::camerasrc_auto_focus_status_t Auto focusing status + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * + */ +int camerasrc_get_autofocusing_status(camsrc_handle_t handle, camerasrc_auto_focus_status_t* af_status); +/**** M I S C E L L A N E O U S O P E R A T I O N ****/ + +/**** I N P U T ( C A M D E V I C E ) O P E R A T I O N ****/ + +/** + * Get input camera ID just like ioctl (fd, VIDIOC_G_INPUT, &index) + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @param[out] id Camera ID currently set + * @return Success on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * @note This function is only effective at CAMERASRC_PHASE_RUNNING + */ +int camerasrc_get_input(camsrc_handle_t handle, camerasrc_dev_id_t* camera_id); + +/** + * Set input camera ID just like ioctl (fd, VIDIOC_S_INPUT, &index) + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @param[out] camera_id Camera ID currently set + * @return Success on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * @note This function is only effective at CAMERASRC_STATE_READY + * If you use set_input(), handle will be initiated. + */ +int camerasrc_set_input(camsrc_handle_t handle, camerasrc_dev_id_t camera_id); + + +/**** E F F E C T C O N T R O L O P E R A T I O N ****/ + +/** + * Check support controls with ::camerasrc_ctrl_t ID + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[in] ctrl_id control ID to be checked + * @param[out] ctrl_info control information to be got + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + */ +int camerasrc_query_control(camsrc_handle_t handle, camerasrc_ctrl_t ctrl_id, camerasrc_ctrl_info_t* ctrl_info); + +/** + * Check support controls with ::camerasrc_ctrl_t ID + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[in] ctrl_id control ID to be checked + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + */ +int camerasrc_support_control(camsrc_handle_t handle, camerasrc_ctrl_t ctrl_id); + +/** + * Start facedetection + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * @note State transition : [CAMERASRC_STATE_AF_IN_PROGRESS] => [CAMERASRC_STATE_PREVIEW] + * Phase description : Running phase + */ +int camerasrc_start_facedetection(camsrc_handle_t handle); + +/** + * Stop face detection + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * @note State transition : [CAMERASRC_STATE_AF_IN_PROGRESS] => [CAMERASRC_STATE_PREVIEW] + * Phase description : Running phase + */ +int camerasrc_stop_facedetection(camsrc_handle_t handle); + +/** + * Get face detection status + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[out] is_detecting whether it is detecting or not + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * @note State transition : [CAMERASRC_STATE_AF_IN_PROGRESS] => [CAMERASRC_STATE_PREVIEW] + * Phase description : Running phase + */ +int camerasrc_get_facedetection(camsrc_handle_t handle, int* is_detecting); + +/** + * Control miscellaneous settings through ::camerasrc_ctrl_t IDs + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[in] ctrl_id control ID to be checked + * @param[in] value value to be set + * @return Success on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * @note This function is only effective at CAMERASRC_STATE_READY + */ +int camerasrc_set_control(camsrc_handle_t handle, camerasrc_ctrl_t ctrl_id, int value); + +/** + * Get the value of miscellaneous settings through ::camerasrc_ctrl_t IDs + * + * @param[in] handle ::camsrc_handle_t camerasrc context handle + * @param[in] ctrl_id control ID to be checked + * @param[out] value value to be stored + * @return Success on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * @note This function is only effective at CAMERASRC_STATE_READY + */ +int camerasrc_get_control(camsrc_handle_t handle, camerasrc_ctrl_t ctrl_id, int* value); + +/**** O U T P U T C O N T R O L O P E R A T I O N ****/ + +/** + * Control frame refresh rate setting + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @param[in] frac ::camsrc_frac_t time per frame + * @return Success on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * @note This function is only effective at CAMERASRC_STATE_READY + */ +int camerasrc_set_timeperframe(camsrc_handle_t handle, camerasrc_frac_t* frac); + +/** + * Set output format of camera device just like ioctl VIDIOC_S_FMT + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @param[in] fmt ::camerasrc_format_t output format description to be set + * @return Success on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * @note This function is only effective at CAMERASRC_STATE_READY. + * device dependent function. + */ +int camerasrc_set_format(camsrc_handle_t handle, camerasrc_format_t* fmt); + +/** + * Get output format of camera device just like ioctl VIDIOC_G_FMT + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @param[in] fmt ::camerasrc_format_t output format description to be set + * @return Success on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * @note This function is only effective at CAMERASRC_PHASE_RUNNING + */ +int camerasrc_get_format(camsrc_handle_t handle, camerasrc_format_t* fmt); + +/** + * Try output format of camera device just like ioctl VIDIOC_TRY_FMT + * In this function, it doesn't change any format, only just try. just test + * the combinations of format setting + * + * @param[in] handle ::camerasrc_handle_t camerasrc context handle + * @param[in] fmt ::camerasrc_format_t output format description to be set + * @return Success on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + * @note This function is only effective at CAMERASRC_STATE_READY. + * device dependent function. + */ +int camerasrc_try_format(camsrc_handle_t handle, camerasrc_format_t* fmt); + +/** + * Get virtual/physical address of data frame + * + * @param[in] handle ::camsrc_handle_t handle + * @param[in] ae_lock ::camerasrc_ae_lock_t Auto exposure lock/unlock + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_get_frame_data(camsrc_handle_t handle, camerasrc_frame_data_t * data); + +/**** S H U T T E R S P E E D & A P E R T U R E M O D U L A T I O N ****/ +/** + * Get exif string to be combined with jpg image from camerasrc + * + * @param[in] handle ::camsrc_handle_t handle + * @param[out] exif_string exif information string + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_get_exif_info(camsrc_handle_t handle, camerasrc_exif_t* exif_struct); + +/** + * Check whether camera device is opened + * + * @param[in] handle ::camsrc_handle_t handle + * @return 0 when camera is not opened else return non-zero value. + */ + int camerasrc_device_is_open(camsrc_handle_t handle); + +/** + * Set the camera device file decriptor + + * @param[in] handle ::camsrc_handle_t handle + * @param[in] videofd ::file descriptor of camera device + * @return Success on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + */ +int camerasrc_set_videofd(camsrc_handle_t handle,int videofd); + +/** + * Set AF behaviour after capturing + + * @param[in] handle ::camsrc_handle_t handle + * @param[in] hold_af ::whether holding af after capturing + * @return Success on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + */ +int camerasrc_set_af_hold_after_capture(camsrc_handle_t handle, int hold_af); + +/** + * Set Sensor mode to camera driver + + * @param[in] handle ::camsrc_handle_t handle + * @param[in] sensor_mode ::int mode + * @return Success on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + */ +int camerasrc_set_sensor_mode(camsrc_handle_t handle, int mode); + +/** + * Set vflip to camera driver + + * @param[in] handle ::camsrc_handle_t handle + * @param[in] vflip ::int vflip + * @return Success on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + */ +int camerasrc_set_vflip(camsrc_handle_t handle, int vflip); + +/** + * Set hflip to camera driver + + * @param[in] handle ::camsrc_handle_t handle + * @param[in] hflip ::int hflip + * @return Success on CAMERASRC_ERR_NONE or returns with ::camerasrc_error_t error code + */ +int camerasrc_set_hflip(camsrc_handle_t handle, int hflip); + +/* W I L L B E D E P R E C A T E D */ + +/*! @enum camerasrc_colortone_t + * @brief Enumeration type for camera colortone + * + * Colortone entries for camera effects. This can be used with CAMERASRC_CTRL_COLOR_TONE + * This values are defined for utility. It's dependent on the device/camera module. + */ +typedef enum { + CAMERASRC_COLORTONE_NONE = 0, + CAMERASRC_COLORTONE_NEGATIVE, + CAMERASRC_COLORTONE_SOLARIZATION_1, + CAMERASRC_COLORTONE_SOLARIZATION_2, + CAMERASRC_COLORTONE_SOLARIZATION_3, + CAMERASRC_COLORTONE_SOLARIZATION_4, + CAMERASRC_COLORTONE_EMBOSS, + CAMERASRC_COLORTONE_OUTLINE, + CAMERASRC_COLORTONE_AQUA, + CAMERASRC_COLORTONE_SEPHIA, + CAMERASRC_COLORTONE_GRAY, + CAMERASRC_COLORTONE_B_N_W, + CAMERASRC_COLORTONE_RED, + CAMERASRC_COLORTONE_GREEN, + CAMERASRC_COLORTONE_BLUE, + CAMERASRC_COLORTONE_ANTIQUE, + CAMERASRC_COLORTONE_SKETCH1, + CAMERASRC_COLORTONE_SKETCH2, + CAMERASRC_COLORTONE_SKETCH3, + CAMERASRC_COLORTONE_SKETCH4, + CAMERASRC_COLORTONE_NUM, +}camerasrc_colortone_t; + +/*! @enum camerasrc_program_mode_t + * @brief Enumeration type for preset program mode + * + * WRITEME + */ +typedef enum { + CAMERASRC_PROGRAM_MODE_NORMAL = 0, + CAMERASRC_PROGRAM_MODE_PORTRAIT, + CAMERASRC_PROGRAM_MODE_LANDSCAPE, + CAMERASRC_PROGRAM_MODE_SPORTS, + CAMERASRC_PROGRAM_MODE_PARTY_N_INDOOR, + CAMERASRC_PROGRAM_MODE_BEACH_N_INDOOR, + CAMERASRC_PROGRAM_MODE_SUNSET, + CAMERASRC_PROGRAM_MODE_DUSK_N_DAWN, + CAMERASRC_PROGRAM_MODE_FALL_COLOR, + CAMERASRC_PROGRAM_MODE_NIGHT_SCENE, + CAMERASRC_PROGRAM_MODE_FIREWORK, + CAMERASRC_PROGRAM_MODE_TEXT, + CAMERASRC_PROGRAM_MODE_SHOW_WINDOW, + CAMERASRC_PROGRAM_MODE_CANDLE_LIGHT, + CAMERASRC_PROGRAM_MODE_BACK_LIGHT, + CAMERASRC_PROGRAM_MODE_NUM, +}camerasrc_program_mode_t; + +/*! @enum camerasrc_whitebalance_t + * @brief Enumeration type for preset whitebalance + * + * WRITEME + */ +typedef enum { + CAMERASRC_WHITEBALANCE_AUTO = 0, + CAMERASRC_WHITEBALANCE_INCANDESCENT, + CAMERASRC_WHITEBALANCE_FLUORESCENT, + CAMERASRC_WHITEBALANCE_DAYLIGHT, + CAMERASRC_WHITEBALANCE_CLOUDY, + CAMERASRC_WHITEBALANCE_SHADE, + CAMERASRC_WHITEBALANCE_HORIZON, + CAMERASRC_WHITEBALANCE_FLASH, + CAMERASRC_WHITEBALANCE_CUSTOM, + CAMERASRC_WHITEBALANCE_NUM, +}camerasrc_whitebalance_t; + +/** + * Enumerations for flip. + */ +typedef enum { + CAMERASRC_FILP_NONE = 0, /**< Not flipped */ + CAMERASRC_FILP_VERTICAL, /**< Flip vertically */ + CAMERASRC_FILP_HORIZONTAL, /**< Flip horizontally */ + CAMERASRC_FILP_NUM, /**< Number of flip status */ +}camerasrc_flip_t; + +/*! @enum camerasrc_strobo_status_t + * @brief strobo status + * strobo status + */ +typedef enum { + CAMERASRC_STROBO_STATUS_BANNED = 0, /**< strobo off*/ + CAMERASRC_STROBO_STATUS_FORCE_ON, /**< strobo on.*/ + CAMERASRC_STROBO_STATUS_AUTO, /**< control strobo automatically*/ + CAMERASRC_STROBO_STATUS_MOVIE_ON, /**< control strobo automatically*/ + CAMERASRC_STROBO_STATUS_NUM, /**< Number of AF status*/ +}camerasrc_strobo_status_t; +/*! @enum camerasrc_strobe_mode_t + * @brief strobe mode + * strobe mode + */ +typedef enum { + CAMERASRC_STROBE_MODE_OFF = 1, /**< off */ + CAMERASRC_STROBE_MODE_AUTO, /**< auto */ + CAMERASRC_STROBE_MODE_ON, /**< on */ + CAMERASRC_STROBE_MODE_PERMANENT, /**< permanent */ + CAMERASRC_STROBE_MODE_NUM, /**< Number of strobe mode */ +}camerasrc_strobe_mode_t; + +/*! @enum camerasrc_ae_mode_t + * @brief Auto exposure mode + * Auto exposure operation mode + */ +typedef enum { + CAMERASRC_AE_MODE_OFF = 0, + CAMERASRC_AE_MODE_ALL, + CAMERASRC_AE_MODE_CENTER_WEIGHTED_AVR_1, + CAMERASRC_AE_MODE_CENTER_WEIGHTED_AVR_2, + CAMERASRC_AE_MODE_CENTER_WEIGHTED_AVR_3, + CAMERASRC_AE_MODE_SPOT_1, + CAMERASRC_AE_MODE_SPOT_2, + CAMERASRC_AE_MODE_CUSTOM_1, + CAMERASRC_AE_MODE_CUSTOM_2, +} camerasrc_ae_mode_t; + +/*! @enum camerasrc_iso_t + * @brief Reserved iso number in definition + * Traditionally predefined ISO values + */ +typedef enum { + CAMERASRC_ISO_AUTO = 0, + CAMERASRC_ISO_50, + CAMERASRC_ISO_100, + CAMERASRC_ISO_200, + CAMERASRC_ISO_400, + CAMERASRC_ISO_800, + CAMERASRC_ISO_1600, + CAMERASRC_ISO_3200, +} camerasrc_iso_t; + +/*! @enum camerasrc_sensor_mode_t + * @brief Sensor mode in driver + * Sensor mode + */ +typedef enum { + CAMERASRC_SENSOR_MODE_CAMERA = 0, + CAMERASRC_SENSOR_MODE_MOVIE, +} camerasrc_sensor_mode_t; + +/*! @def CAMERASRC_SET_SIZE_BY_PRESET_RESOLUTION + * @brief Utility definitions for setting regular size with ::camerasrc_resol_name_t + */ +#define CAMERASRC_SET_SIZE_BY_PRESET_RESOLUTION(format, resolution) { \ + memset(&(format.img_size), 0, sizeof(camerasrc_size_t)); \ + format.img_size.res = resolution; \ +} + +/** + * Set the mode of strobe + * + * @param[in] handle ::camsrc_handle_t handle + * @param[in] mode ::camerasrc_strobe_mode_t mode of strobe + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_set_strobe_mode(camsrc_handle_t handle, camerasrc_strobe_mode_t mode); + +/** + * Get the mode of strobe + * + * @param[in] handle ::camsrc_handle_t handle + * @param[out] mode ::camerasrc_strobe_mode_t mode of strobe + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_get_strobe_mode(camsrc_handle_t handle, camerasrc_strobe_mode_t* mode); + +/** + * Set the mode of auto-exposure processing + * + * @param[in] handle ::camsrc_handle_t handle + * @param[in] ae_mode ::camerasrc_ae_mode_t AE mode to be set + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_set_exposure_mode(camsrc_handle_t handle, camerasrc_ae_mode_t ae_mode); + +/** + * Get the mode of auto-exposure processing + * + * @param[in] handle ::camsrc_handle_t handle + * @param[out] ae_mode ::camerasrc_ae_mode_t AE mode to be got + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_get_exposure_mode(camsrc_handle_t handle, camerasrc_ae_mode_t* ae_mode); + +/** + * Set the shutter speed + * + * @param[in] handle ::camsrc_handle_t handle + * @param[in] frac ::camerasrc_frac_t shutter speed to be set + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_set_shutter_speed(camsrc_handle_t handle, camerasrc_frac_t frac); + +/** + * Get the shutter speed + * + * @param[in] handle ::camsrc_handle_t handle + * @param[out] frac ::camerasrc_frac_t shutter speed to be got + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_get_shutter_speed(camsrc_handle_t handle, camerasrc_frac_t* frac); + +/** + * Set the exposure value + * + * @param[in] handle ::camsrc_handle_t handle + * @param[in] frac ::camerasrc_frac_t exposure value to be set + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_set_exposure_value(camsrc_handle_t handle, camerasrc_frac_t frac); + +/** + * Get the exposure value + * + * @param[in] handle ::camsrc_handle_t handle + * @param[out] frac ::camerasrc_frac_t exposure value to be got + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_get_exposure_value(camsrc_handle_t handle, camerasrc_frac_t* frac); + +/** + * Check whether supports exif embed in jpg or not + * + * @param[in] handle ::camsrc_handle_t handle + * @param[out] support_exif ::if supports, returns 1 or 0 + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_support_embed_exif(camsrc_handle_t handle, int* support_exif); + +/** + * Check whether supports jpeg encoding inside camera driver + * + * @param[in] handle ::camsrc_handle_t handle + * @param[out] support_jpeg_encoding ::if supports, returns 1. If not, return 0 + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_support_jpeg_encoding(camsrc_handle_t handle, int* support_jpeg_encoding); + + + +/* For Query functionalities */ +/** + * Query basic device info of device + * + * @param[in] handle ::camsrc_handle_t handle + * @param[out] camerasrc_caps_info_t device information structure + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_read_basic_dev_info(camerasrc_dev_id_t dev_id, camerasrc_caps_info_t* caps_info); + +/** + * Query miscellaneous device info(effect, WB, preset values, etc.) of device + * + * @param[in] handle ::camsrc_handle_t handle + * @param[out] camerasrc_ctrl_list_info_t device capabilities structure + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_read_misc_dev_info(camerasrc_dev_id_t dev_id, camerasrc_ctrl_list_info_t* ctrl_info); + +/** + * Query extra device info(face detection, strobe, etc.) of device + * + * @param[in] handle ::camsrc_handle_t handle + * @param[out] camerasrc_extra_info_t device capabilities structure + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_read_extra_dev_info(camerasrc_dev_id_t dev_id, camerasrc_extra_info_t* extra_info); + +/** + * Record miscellaneous device info(effect, WB, preset values, etc.) of device + * + * @param[in] handle ::camsrc_handle_t handle + * @param[in] camerasrc_ctrl_list_info_t device capabilities structure + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_write_basic_dev_info(camsrc_handle_t handle, camerasrc_caps_info_t* caps_info); + +/** + * Record miscellaneous device info(effect, WB, preset values, etc.) of device + * + * @param[in] handle ::camsrc_handle_t handle + * @param[in] camerasrc_ctrl_list_info_t device capabilities structure + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_write_misc_dev_info(camsrc_handle_t handle, camerasrc_ctrl_list_info_t* ctrl_info); + +/** + * Record extra device info(face detection, strobe, etc.) of device + * + * @param[in] handle ::camsrc_handle_t handle + * @param[out] camerasrc_extra_info_t device capabilities structure + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_write_extra_dev_info(camsrc_handle_t handle, camerasrc_extra_info_t* extra_info); + +/** + * Query to device driver about basic device info + * + * @param[in] handle ::camsrc_handle_t handle + * @param[out] camerasrc_ctrl_list_info_t device capabilities structure + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_query_basic_dev_info(camsrc_handle_t handle, camerasrc_caps_info_t* caps_info); + +/** + * Query to device driver about miscellaneous device info(effect, WB, preset values, etc.) of device + * + * @param[in] handle ::camsrc_handle_t handle + * @param[out] camerasrc_ctrl_list_info_t device capabilities structure + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_query_misc_dev_info(camsrc_handle_t handle, camerasrc_ctrl_list_info_t* ctrl_list_info); +int camerasrc_query_misc_dev_ctrl_info(camsrc_handle_t handle, camerasrc_ctrl_t ctrl_id, camerasrc_ctrl_info_t* ctrl_info); + +/** + * Query to device driver about extra device info(face detection, strobe, etc.) of device + * + * @param[in] handle ::camsrc_handle_t handle + * @param[out] camerasrc_extra_info_t device capabilities structure + * @return Success(Support) on CAMERASRC_ERR_NONE or returns with ::camerasrc_error error code + */ +int camerasrc_query_extra_dev_info(camsrc_handle_t handle, camerasrc_extra_info_t* extra_info); + +/** + * Dump functions for debugging + */ +int camerasrc_dump_basic_dev_info(camsrc_handle_t handle, camerasrc_caps_info_t* caps_info); +int camerasrc_dump_misc_dev_info(camsrc_handle_t handle, camerasrc_ctrl_list_info_t* ctrl_list_info); +int camerasrc_dump_extra_dev_info(camsrc_handle_t handle, camerasrc_extra_info_t* extra_info); +/* END For Query functionalities */ + +#ifdef __cplusplus +} +#endif + +#endif /*__CAMERASRC_H__*/ diff --git a/camerasrc/src/include/gstcamerasrc.h b/camerasrc/src/include/gstcamerasrc.h new file mode 100644 index 0000000..61b3c28 --- /dev/null +++ b/camerasrc/src/include/gstcamerasrc.h @@ -0,0 +1,175 @@ +/* + * camerasrc + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang <jm80.yang@samsung.com> + * + * 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.1 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., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __GSTCAMERASRC_H__ +#define __GSTCAMERASRC_H__ + +#include <gst/gst.h> +#include <gst/base/gstpushsrc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <gst/interfaces/colorbalance.h> +#include <gst/interfaces/cameracontrol.h> + +#include "camerasrc.h" + +#ifndef _SPEED_UP_RAW_CAPTURE +/* Disabled now +#define _SPEED_UP_RAW_CAPTURE +*/ +#endif /* _SPEED_UP_RAW_CAPTURE */ + +G_BEGIN_DECLS +#define GST_TYPE_CAMERA_SRC (gst_camerasrc_get_type()) +#define GST_CAMERA_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CAMERA_SRC,GstCameraSrc)) +#define GST_CAMERA_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CAMERA_SRC,GstCameraSrcClass)) +#define GST_IS_CAMERA_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CAMERA_SRC)) +#define GST_IS_CAMERA_SRC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CAMERA_SRC)) + + +/** + * Quality. + */ +typedef enum { + GST_CAMERASRC_QUALITY_LOW, /**< Low quality */ + GST_CAMERASRC_QUALITY_HIGH, /**< High quality */ +} GstCameraSrcQuality; + +#define MAX_USR_BUFFER_NUM 12 + +typedef struct _GstCameraSrc GstCameraSrc; +typedef struct _GstCameraSrcClass GstCameraSrcClass; +typedef struct _GstCameraBuffer GstCameraBuffer; + +/* global info */ +struct _GstCameraBuffer { + GstBuffer buffer; + int v4l2_buffer_index; + GstCameraSrc *camerasrc; + gboolean is_alloc_data; +}; + +struct _GstCameraSrc +{ + GstPushSrc element; + + /*private*/ + void *v4l2_handle; /**< video4linux2 handle */ + int mode; + int sensor_mode; /**< sensor mode - camera or movie(camcorder) */ + gboolean vflip; /**< flip camera input vertically */ + gboolean hflip; /**< flip camera input horizontally */ + gboolean firsttime; + + int main_buf_sz; + int cap_count_current; /**< current capture count */ + int cap_count_reverse; /**< current capture count (reverse counting) */ + unsigned long cap_next_time; /**< next shot time for capture */ + GQueue *command_list; /**< Command list(Start capture, Stop capture) queue */ + + GCond *cond; + GMutex *mutex; + + /*camera property*/ + int width; /**< Width */ + int height; /**< Height */ + int fps; /**< Video source fps */ + + guint32 fourcc; /**< Four CC */ + int pix_format; /**< Image format of video source */ + int colorspace; /**< Colorspace of video source */ + int high_speed_fps; /**< Video source fps for high speed recording */ + gboolean fps_auto; /**< Auto Video source fps */ + + gboolean req_negotiation; /**< Video source fps for high speed recording */ + int camera_id; + int rotate; /**< Video source rotate */ + gboolean use_rotate_caps; /**< Use or not rotate value in caps */ + int external_videofd; /**< video FD from external module */ + + GCond *buffer_cond; + GMutex *buffer_lock; + gboolean buffer_running; /* with lock */ + gint num_live_buffers; /* with lock */ + guint buffer_count; + gboolean bfirst; /* temp */ +#ifdef _SPEED_UP_RAW_CAPTURE + gboolean cap_stream_diff; /* whether preview and capture streams are different each other */ +#endif + GQueue *pad_alloc_list; + GMutex *pad_alloc_mutex; + gint current_buffer_data_index; + gboolean first_invokation; + + GstBuffer *usr_buffer[MAX_USR_BUFFER_NUM]; + gboolean use_pad_alloc; + guint num_alloc_buf; + + /* Colorbalance , CameraControl interface */ + GList *colors; + GList *camera_controls; + + + /*capture property*/ + guint32 cap_fourcc; /**< gstreamer fourcc value(GST_MAKE_FOURCC format) for raw capturing */ + GstCameraSrcQuality cap_quality; /**< Capture quality */ + int cap_width; /**< Capture width */ + int cap_height; /**< Capture height */ + int cap_interval; /**< Capture interval */ + int cap_count; /**< Capture count */ + int cap_jpg_quality; /**< Capture quality for jpg compress ratio */ + gboolean cap_provide_exif; /**< Is exif provided? */ + + /*etc property*/ + gboolean signal_still_capture; /**< enable still capture signal */ + gboolean hold_af_after_capturing; /**< Whether to hold af after capturing */ + gboolean create_jpeg; + GMutex *jpg_mutex; +}; + +struct _GstCameraSrcClass { + GstPushSrcClass parent_class; + /* signals */ + void (*still_capture) (GstElement *element, GstBuffer *main, GstBuffer *sub, GstBuffer *scrnl); + void (*nego_complete) (GstElement *element); + void (*register_trouble) (GstElement *element); +}; + +typedef enum { + INTERFACE_NONE, + INTERFACE_COLOR_BALANCE, + INTERFACE_CAMERA_CONTROL, +} GstInterfaceType; + + +void gst_camerasrc_set_capture_command(GstCameraSrc* camerasrc, GstCameraControlCaptureCommand cmd); + + +GType gst_camerasrc_get_type(void); + +G_END_DECLS + +#endif /* __GSTCAMERASRC_H__ */ diff --git a/camerasrc/src/include/gstcamerasrccolorbalance.h b/camerasrc/src/include/gstcamerasrccolorbalance.h new file mode 100644 index 0000000..0edeb46 --- /dev/null +++ b/camerasrc/src/include/gstcamerasrccolorbalance.h @@ -0,0 +1,93 @@ +/* + * camerasrc + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang <jm80.yang@samsung.com> + * + * 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.1 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., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __GST_CAMERASRC_COLOR_BALANCE_H__ +#define __GST_CAMERASRC_COLOR_BALANCE_H__ + +#include <gst/gst.h> +#include <gst/interfaces/colorbalance.h> +#include "gstcamerasrc.h" + +G_BEGIN_DECLS + +#define GST_TYPE_CAMERASRC_COLOR_BALANCE_CHANNEL (gst_camerasrc_color_balance_channel_get_type ()) +#define GST_CAMERASRC_COLOR_BALANCE_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CAMERASRC_COLOR_BALANCE_CHANNEL, GstCameraSrcColorBalanceChannel)) +#define GST_CAMERASRC_COLOR_BALANCE_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CAMERASRC_COLOR_BALANCE_CHANNEL, GstCameraSrcColorBalanceChannelClass)) +#define GST_IS_CAMERASRC_COLOR_BALANCE_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CAMERASRC_COLOR_BALANCE_CHANNEL)) +#define GST_IS_CAMERASRC_COLOR_BALANCE_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CAMERASRC_COLOR_BALANCE_CHANNEL)) + +typedef struct _GstCameraSrcColorBalanceChannel { + GstColorBalanceChannel parent; + + guint32 id; +} GstCameraSrcColorBalanceChannel; + +typedef struct _GstCameraSrcColorBalanceChannelClass { + GstColorBalanceChannelClass parent; +} GstCameraSrcColorBalanceChannelClass; + +GType gst_camerasrc_color_balance_channel_get_type( void ); + +const GList *gst_camerasrc_color_balance_list_channels( GstCameraSrc* camerasrc ); +void gst_camerasrc_color_balance_set_value( GstCameraSrc* camerasrc, GstColorBalanceChannel* color_channel, gint value ); +gint gst_camerasrc_color_balance_get_value( GstCameraSrc* camerasrc, GstColorBalanceChannel* color_channel ); + +#define GST_IMPLEMENT_CAMERASRC_COLOR_BALANCE_METHODS( Type, interface_as_function ) \ + \ +static const GList* \ +interface_as_function ## _color_balance_list_channels( GstColorBalance* balance ) \ +{ \ + Type *this = (Type*) balance; \ + return gst_camerasrc_color_balance_list_channels( this ); \ +} \ + \ +static void \ +interface_as_function ## _color_balance_set_value( GstColorBalance* balance, \ + GstColorBalanceChannel* color_channel, \ + gint value ) \ +{ \ + Type *this = (Type*) balance; \ + return gst_camerasrc_color_balance_set_value( this, color_channel, value ); \ +} \ + \ +static gint \ +interface_as_function ## _color_balance_get_value( GstColorBalance* balance, \ + GstColorBalanceChannel* color_channel )\ +{ \ + Type *this = (Type*) balance; \ + return gst_camerasrc_color_balance_get_value( this, color_channel ); \ +} \ + \ +void \ +interface_as_function ## _color_balance_interface_init( GstColorBalanceClass* klass ) \ +{ \ + GST_COLOR_BALANCE_TYPE( klass ) = GST_COLOR_BALANCE_HARDWARE; \ + \ + /* default virtual functions */ \ + klass->list_channels = interface_as_function ## _color_balance_list_channels; \ + klass->set_value = interface_as_function ## _color_balance_set_value; \ + klass->get_value = interface_as_function ## _color_balance_get_value; \ +} + +#endif /* __GST_CAMERASRC_COLOR_BALANCE_H__ */ + diff --git a/camerasrc/src/include/gstcamerasrccontrol.h b/camerasrc/src/include/gstcamerasrccontrol.h new file mode 100644 index 0000000..c4ce913 --- /dev/null +++ b/camerasrc/src/include/gstcamerasrccontrol.h @@ -0,0 +1,384 @@ +/* + * camerasrc + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang <jm80.yang@samsung.com> + * + * 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.1 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., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __GST_CAMERASRC_CONTROL_H__ +#define __GST_CAMERASRC_CONTROL_H__ + +#include <gst/gst.h> +#include <gst/interfaces/cameracontrol.h> +#include "gstcamerasrc.h" + +G_BEGIN_DECLS + +#define GST_TYPE_CAMERASRC_CONTROL_CHANNEL (gst_camerasrc_control_channel_get_type ()) +#define GST_CAMERASRC_CONTROL_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CAMERASRC_CONTROL_CHANNEL, GstCamerasrcControlChannel)) +#define GST_CAMERASRC_CONTROL_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CAMERASRC_CONTROL_CHANNEL, GstCamerasrcControlChannelClass)) +#define GST_IS_CAMERASRC_CONTROL_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CAMERASRC_CONTROL_CHANNEL)) +#define GST_IS_CAMERASRC_CONTROL_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CAMERASRC_CONTROL_CHANNEL)) + +typedef struct _GstCamerasrcControlChannel { +GstCameraControlChannel parent; +guint32 id; +} GstCamerasrcControlChannel; + +typedef struct _GstCamerasrcControlChannelClass { +GstCameraControlChannelClass parent; +} GstCamerasrcControlChannelClass; + +GType gst_camerasrc_control_channel_get_type( void ); + +const GList*gst_camerasrc_control_list_channels( GstCameraSrc* camera_src ); + +gboolean gst_camerasrc_control_set_value ( GstCameraSrc* camera_src, GstCameraControlChannel* control_channel, gint value ); +gboolean gst_camerasrc_control_get_value ( GstCameraSrc* camera_src, GstCameraControlChannel* control_channel, gint* value ); +gboolean gst_camerasrc_control_set_exposure ( GstCameraSrc* camera_src, gint type, gint value1, gint value2 ); +gboolean gst_camerasrc_control_get_exposure ( GstCameraSrc* camera_src, gint type, gint* value1, gint* value2 ); +gboolean gst_camerasrc_control_set_capture_mode ( GstCameraSrc* camera_src, gint type, gint value ); +gboolean gst_camerasrc_control_get_capture_mode ( GstCameraSrc* camera_src, gint type, gint* value ); +gboolean gst_camerasrc_control_set_strobe ( GstCameraSrc* camera_src, gint type, gint value ); +gboolean gst_camerasrc_control_get_strobe ( GstCameraSrc* camera_src, gint type, gint *value ); +gboolean gst_camerasrc_control_set_detect ( GstCameraSrc* camera_src, gint type, gint value ); +gboolean gst_camerasrc_control_get_detect ( GstCameraSrc* camera_src, gint type, gint* value ); +gboolean gst_camerasrc_control_set_zoom ( GstCameraSrc* camera_src, gint type, gint value ); +gboolean gst_camerasrc_control_get_zoom ( GstCameraSrc* camera_src, gint type, gint* value ); +gboolean gst_camerasrc_control_set_focus ( GstCameraSrc* camera_src, gint mode, gint range ); +gboolean gst_camerasrc_control_get_focus ( GstCameraSrc* camera_src, gint* mode, gint* range ); +gboolean gst_camerasrc_control_start_auto_focus ( GstCameraSrc* camera_src ); +gboolean gst_camerasrc_control_stop_auto_focus ( GstCameraSrc* camera_src ); +gboolean gst_camerasrc_control_set_focus_level ( GstCameraSrc* camera_src, gint manual_level ); +gboolean gst_camerasrc_control_get_focus_level ( GstCameraSrc* camera_src, gint* manual_level ); +gboolean gst_camerasrc_control_set_auto_focus_area( GstCameraSrc* camera_src, GstCameraControlRectType rect ); +gboolean gst_camerasrc_control_get_auto_focus_area( GstCameraSrc* camera_src, GstCameraControlRectType* rect ); +gboolean gst_camerasrc_control_set_wdr ( GstCameraSrc* camera_src, gint value ); +gboolean gst_camerasrc_control_get_wdr ( GstCameraSrc* camera_src, gint* value ); +gboolean gst_camerasrc_control_set_ahs ( GstCameraSrc* camera_src, gint value ); +gboolean gst_camerasrc_control_get_ahs ( GstCameraSrc* camera_src, gint* value ); +gboolean gst_camerasrc_control_set_part_color ( GstCameraSrc* camera_src, gint type, gint value ); +gboolean gst_camerasrc_control_get_part_color ( GstCameraSrc* camera_src, gint type, gint* value ); +gboolean gst_camerasrc_control_get_exif_info ( GstCameraSrc* camera_src, GstCameraControlExifInfo* info ); +gboolean gst_camerasrc_control_get_basic_dev_info ( GstCameraSrc* camera_src, gint dev_id, GstCameraControlCapsInfoType* info ); +gboolean gst_camerasrc_control_get_misc_dev_info ( GstCameraSrc* camera_src, gint dev_id, GstCameraControlCtrlListInfoType* info ); +gboolean gst_camerasrc_control_get_extra_dev_info ( GstCameraSrc* camera_src, gint dev_id, GstCameraControlExtraInfoType* info ); +void gst_camerasrc_control_set_capture_command( GstCameraSrc* camera_src, GstCameraControlCaptureCommand cmd ); + +#define GST_IMPLEMENT_CAMERASRC_CONTROL_METHODS(Type, interface_as_function) \ + \ +static const GList* \ +interface_as_function ## _control_list_channels( GstCameraControl* control ) \ +{ \ + Type* this = (Type*) control; \ + return gst_camerasrc_control_list_channels( this ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_value( GstCameraControl* control, \ + GstCameraControlChannel* control_channel, gint value ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_set_value( this, control_channel, value ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_value( GstCameraControl* control, \ + GstCameraControlChannel* control_channel, gint* value ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_get_value( this, control_channel, value ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_exposure( GstCameraControl* control, \ + gint type, gint value1, gint value2 ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_set_exposure( this, type, value1, value2 ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_exposure( GstCameraControl* control, \ + gint type, gint* value1, gint* value2 ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_get_exposure( this, type, value1, value2 ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_capture_mode( GstCameraControl* control, \ + gint type, gint value ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_set_capture_mode( this, type, value ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_capture_mode( GstCameraControl* control, \ + gint type, gint* value ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_get_capture_mode( this, type, value ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_strobe( GstCameraControl* control, \ + gint type, gint value ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_set_strobe( this, type, value ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_strobe( GstCameraControl* control, \ + gint type, gint* value ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_get_strobe( this, type, value ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_detect( GstCameraControl* control, \ + gint type, gint value ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_set_detect( this, type, value ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_detect( GstCameraControl* control, \ + gint type, gint* value ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_get_detect( this, type, value ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_zoom( GstCameraControl* control, \ + gint type, gint value ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_set_zoom( this, type, value ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_zoom( GstCameraControl* control, \ + gint type, gint* value ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_get_zoom( this, type, value ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_focus( GstCameraControl* control, \ + gint focus_mode, gint focus_range ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_set_focus( this, focus_mode, focus_range ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_focus( GstCameraControl* control, \ + gint* focus_mode, gint* focus_range ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_get_focus( this, focus_mode, focus_range ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_start_auto_focus( GstCameraControl* control) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_start_auto_focus( this ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_stop_auto_focus( GstCameraControl* control) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_stop_auto_focus( this ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_focus_level( GstCameraControl* control, \ + gint focus_level ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_set_focus_level( this, focus_level ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_focus_level( GstCameraControl* control, \ + gint* focus_level ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_get_focus_level( this, focus_level ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_auto_focus_area( GstCameraControl* control, \ + GstCameraControlRectType rect ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_set_auto_focus_area( this, rect ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_auto_focus_area( GstCameraControl* control, \ + GstCameraControlRectType* rect ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_get_auto_focus_area( this, rect ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_wdr( GstCameraControl* control, \ + gint value ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_set_wdr( this, value ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_wdr( GstCameraControl* control, \ + gint* value ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_get_wdr( this, value ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_ahs( GstCameraControl* control, \ + gint value ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_set_ahs( this, value ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_ahs( GstCameraControl* control, \ + gint* value ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_get_ahs( this, value ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_part_color( GstCameraControl* control, \ + gint type, gint value ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_set_part_color( this, type, value ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_part_color( GstCameraControl* control, \ + gint type, gint* value ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_get_part_color( this, type, value ); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_exif_info( GstCameraControl* control, \ + GstCameraControlExifInfo* info ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_get_exif_info( this, info); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_basic_dev_info( GstCameraControl* control, \ + gint dev_id, \ + GstCameraControlCapsInfoType* info ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_get_basic_dev_info( this, dev_id, info); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_misc_dev_info( GstCameraControl* control, \ + gint dev_id, \ + GstCameraControlCtrlListInfoType* info ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_get_misc_dev_info( this, dev_id, info); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_extra_dev_info( GstCameraControl* control, \ + gint dev_id, \ + GstCameraControlExtraInfoType* info ) \ +{ \ + Type* this = (Type*)control; \ + return gst_camerasrc_control_get_extra_dev_info( this, dev_id, info); \ +} \ + \ +static void \ +interface_as_function ## _control_set_capture_command( GstCameraControl* control, \ + GstCameraControlCaptureCommand cmd ) \ +{ \ + Type* this = (Type*)control; \ + gst_camerasrc_control_set_capture_command( this, cmd ); \ + return; \ +} \ + \ +void \ +interface_as_function ## _control_interface_init( GstCameraControlClass *klass ) \ +{ \ + GST_CAMERA_CONTROL_TYPE( klass ) = GST_CAMERA_CONTROL_HARDWARE; \ + \ + /* default virtual functions */ \ + klass->list_channels = interface_as_function ## _control_list_channels; \ + klass->set_value = interface_as_function ## _control_set_value; \ + klass->get_value = interface_as_function ## _control_get_value; \ + klass->set_exposure = interface_as_function ## _control_set_exposure; \ + klass->get_exposure = interface_as_function ## _control_get_exposure; \ + klass->set_capture_mode = interface_as_function ## _control_set_capture_mode; \ + klass->get_capture_mode = interface_as_function ## _control_get_capture_mode; \ + klass->set_strobe = interface_as_function ## _control_set_strobe; \ + klass->get_strobe = interface_as_function ## _control_get_strobe; \ + klass->set_detect = interface_as_function ## _control_set_detect; \ + klass->get_detect = interface_as_function ## _control_get_detect; \ + klass->set_zoom = interface_as_function ## _control_set_zoom; \ + klass->get_zoom = interface_as_function ## _control_get_zoom; \ + klass->set_focus = interface_as_function ## _control_set_focus; \ + klass->get_focus = interface_as_function ## _control_get_focus; \ + klass->start_auto_focus = interface_as_function ## _control_start_auto_focus; \ + klass->stop_auto_focus = interface_as_function ## _control_stop_auto_focus; \ + klass->set_focus_level = interface_as_function ## _control_set_focus_level; \ + klass->get_focus_level = interface_as_function ## _control_get_focus_level; \ + klass->set_auto_focus_area = interface_as_function ## _control_set_auto_focus_area; \ + klass->get_auto_focus_area = interface_as_function ## _control_get_auto_focus_area; \ + klass->set_wdr = interface_as_function ## _control_set_wdr; \ + klass->get_wdr = interface_as_function ## _control_get_wdr; \ + klass->set_ahs = interface_as_function ## _control_set_ahs; \ + klass->get_ahs = interface_as_function ## _control_get_ahs; \ + klass->set_part_color = interface_as_function ## _control_set_part_color; \ + klass->get_part_color = interface_as_function ## _control_get_part_color; \ + klass->get_exif_info = interface_as_function ## _control_get_exif_info; \ + klass->get_basic_dev_info = interface_as_function ## _control_get_basic_dev_info; \ + klass->get_misc_dev_info = interface_as_function ## _control_get_misc_dev_info; \ + klass->get_extra_dev_info = interface_as_function ## _control_get_extra_dev_info; \ + klass->set_capture_command = interface_as_function ## _control_set_capture_command; \ + \ +} + +#endif /* __GST_CAMERASRC_CONTROL_H__ */ diff --git a/common/ChangeLog b/common/ChangeLog new file mode 100755 index 0000000..72f093a --- /dev/null +++ b/common/ChangeLog @@ -0,0 +1,1343 @@ +2008-03-07 Edward Hervey <edward.hervey@collabora.co.uk> + + * m4/gtk-doc.m4: (GTK_DOC_CHECK): + The previous commit to this file by Stefan Kost mentionned checking for + SED, but NOT checking for gtkdoc-check (wth is that doing there ??). + Therefore, removing the check for gtkdoc-check + +2008-03-03 David Schleef <ds@schleef.org> + + * m4/ax_create_stdint_h.m4: Oops, checked in the wrong copy of + this file. (Update from upstream) + +2008-03-03 David Schleef <ds@schleef.org> + + * m4/ax_create_stdint_h.m4: Update from upstream. Fixes a bug + compiling with MSVC. + +2008-03-03 Edward Hervey <edward.hervey@collabora.co.uk> + + * m4/pkg.m4: + Allow override of pkg-config results, as proposed by configure --help. + This is in fact just a backport from upstream pkg.m4. + Fixes #518892 + +2008-03-03 Peter Kjellerstedt <pkj@axis.com> + + * ChangeLog: + Changelog surgery of my previous commit to add bugzilla reference. + * m4/gst-args.m4: + Add AG_GST_CHECK_PLUGIN and AG_GST_DISABLE_PLUGIN to make it easier + to include and exclude plug-ins without external references, i.e., + plug-ins listed in GST_PLUGINS_SELECTED. (#498222) + +2008-03-03 Sebastian Dröge <slomo@circular-chaos.org> + + * gst.supp: + Add another glibc suppression. + +2008-02-29 Peter Kjellerstedt <pkj@axis.com> + + * m4/gst-feature.m4: + Make the comment before defines generated via AG_GST_CHECK_FEATURE + look nicer. (#498222) + +2008-02-26 Jan Schmidt <jan.schmidt@sun.com> + + * m4/Makefile.am: + * m4/as-gcc-inline-assembly.m4: + Add Dave Schleef's GCC inline assembly detection macro + for using in gst-plugins-good in the goom 2k4 plugin. + +2008-02-25 Andy Wingo <wingo@pobox.com> + + * gst-autogen.sh: Instead of only passing certain arguments to + configure, pass anything that we didn't handle. Much friendlier. + Fixes #34412. + +2008-02-23 Jan Schmidt <Jan.Schmidt@sun.com> + + * m4/gst-error.m4: + Store the detected compiler flags into ERROR_CFLAGS rather than + ERROR_CXXFLAGS, and use the macro that checks the C compiler, not + the C++ one. + +2008-02-23 Tim-Philipp Müller <tim at centricular dot net> + + * m4/gst-error.m4: + Reflow checks for additional warning flags so they're not + nested, which fixes the result reporting in the configure + output. + +2008-02-22 Tim-Philipp Müller <tim at centricular dot net> + + * m4/as-compiler-flag.m4: + Add AS_CXX_COMPILER_FLAG + + * m4/gst-error.m4: + Add AG_GST_SET_ERROR_CXXFLAGS (Forte bits need testing) + +2008-02-22 Tim-Philipp Müller <tim at centricular dot net> + + * gtk-doc-plugins.mak: + Add 'check-inspected-versions' target; this helps identify + files that should have been removed or where the version + number should (ideally) be updated before a release + (which doesn't happen automatically if the releaser doesn't + build that plugin locally). Not adding at a distcheck hook + yet though, because it's not really that important and would + probably also be a problem on buildbots. + +2008-02-22 Sebastian Dröge <slomo@circular-chaos.org> + + * gst.supp: + Add even more glibc 2.7 suppressions. + +2008-02-22 Sebastian Dröge <slomo@circular-chaos.org> + + * gst.supp: + Add another suppression for GLib caching some values after + the first call. + +2008-02-12 Sebastian Dröge <slomo@circular-chaos.org> + + Patch by: + Tim Mooney <mooney at dogbert dot cc dot ndsu dot nodak dot edu> + + * m4/gst-error.m4: + Use no%E_MACRO_REDEFINED on Solaris to prevent compiler warnings. + Fixes bug #515905. + +2008-02-11 Sebastian Dröge <slomo@circular-chaos.org> + + * gst.supp: + Add a few more glibc 2.7 suppressions to make the avisubtitle unit + test valgrind clean. Fixes bug #515703. + +2008-02-08 Stefan Kost <ensonic@users.sf.net> + + * ChangeLog: + Changelog surgery for last commit. + +2008-02-08 Stefan Kost <ensonic@users.sf.net> + + * m4/gtk-doc.m4: + Conditionally check for SED. Also sync a bit with upstream macro. + +2008-02-08 Stefan Kost <ensonic@users.sf.net> + + * gtk-doc-plugins.mak: + * gtk-doc.mak: + Use '$(SED)' instead of 'sed'. Don't use -i for in-place as its gnu + only, move to a temp file instead. + +2008-02-06 Stefan Kost <ensonic@users.sf.net> + + * gtk-doc-plugins.mak: + * gtk-doc.mak: + As our docs are versioned, we need to patch the index.sgml file to have + correct paths there, unless we also want to fork gtk-doc's xsl (which + we don't). This hopefully fixes xrefs between modules. + +2008-02-02 Sebastian Dröge <slomo@circular-chaos.org> + + * m4/gst-feature.m4: + Use printf instead of echo as "echo -e" isn't POSIX and doesn't work + with strict POSIX shells like tcsh or dash and also not every platform + has a /bin/echo that supports it. + +2008-01-24 Stefan Kost <ensonic@users.sf.net> + + * ChangeLog: + ChangeLog surgery. + + * gstdoc-scangobj: + Sync the object scanner with gtk-doc fixes. Update args and hierarchy + files. + +2008-01-20 Sebastian Dröge <slomo@circular-chaos.org> + + * check.mak: + * coverage/lcov.mak: + * gtk-doc-plugins.mak: + * release.mak: + Use $(MAKE) instead of make to fix the build if GNU make is called + something else on the system. + + * m4/as-docbook.m4: + Fix path for docbook.xsl if we have no /etc/xml/catalog and add a + docbook-xsl search path for FreeBSD. + +2008-01-18 Sebastian Dröge <slomo@circular-chaos.org> + + * gst.supp: + Add a suppression for a glibc bug: + http://valgrind.org/docs/manual/faq.html#faq.exit_errors> + +2008-01-18 Sebastian Dröge <slomo@circular-chaos.org> + + * gst.supp: + Add some more glibc 2.7 suppressions and make the GLib suppressions + for the home/tmp/etc directory caching a bit more generic. + +2008-01-18 Sebastian Dröge <slomo@circular-chaos.org> + + * gst.supp: + Add some glibc 2.7 supressions as found on Debian/unstable. + +2008-01-14 Jan Schmidt <jan.schmidt@sun.com> + + * download-translations: + Apparently I have problems with leaving things commented out when + I edit shell scripts. + +2008-01-12 Jan Schmidt <Jan.Schmidt@sun.com> + + * download-translations: + Remove bash-isms + +2008-01-12 Jan Schmidt <Jan.Schmidt@sun.com> + + * check-exports: + Restore the cleanup rm of our tmp file which I didn't mean to leave + commented out. + +2008-01-12 Jan Schmidt <Jan.Schmidt@sun.com> + + * check-exports: + Fixes to make check-export work on both Solaris and Linux + + * m4/gst-error.m4: + Disable extra warning category (argument mismatch) as an error + on Forte, as it prevents the libcheck fail_if macros from compiling. + + * win32.mak: + Substitute the GStreamer version so things will keep working in 0.11 + +2008-01-11 Tim-Philipp Müller <tim at centricular dot net> + + Patch by: Peter Kjellerstedt <pkj axis com> + + * m4/gst-glib2.m4: + * m4/gst-libxml2.m4: + Improve/fix output from configure if either glib-2.0 or + libxml2 are not installed (#498222). + +2008-01-09 Stefan Kost <ensonic@users.sf.net> + + * coverage/lcov.mak: + Update coverage make-rules: use them conditionaly, use libtool mode + and use lcov to cleanup. + +2007-12-18 Sebastian Dröge <slomo@circular-chaos.org> + + * glib-gen.mak: + Also use #include "header" instead of #include <header> for the + headers that were used to generate the source files for the same + reason as below. + + Remove whitespace before #include. + +2007-12-18 Sebastian Dröge <slomo@circular-chaos.org> + + * glib-gen.mak: + Use #include "header" instead of #include <header> for the generated + enum C files as the file will always be in the same directory and + some compilers seem to be a bit strict about that unless . is added + to the include path. + + Include all headers that were used to generate the source files in + the C file as they're used there. + +2007-12-17 Tim-Philipp Müller <tim at centricular dot net> + + * win32.mak: (win32), (win32defs), (win32crlf): + Make check for CR LF in Visual C++ 6.0 project files + work, based on patch by David Schleef (#496722, #393626). + +2007-12-17 Tim-Philipp Müller <tim at centricular dot net> + + * Makefile.am: + Don't forget to dist the new win32.mak. + +2007-12-17 Tim-Philipp Müller <tim at centricular dot net> + + * win32.mak: (win32), (win32defs): + Move common win32 Makefile foo into this new file. + +2007-12-15 Stefan Kost <ensonic@users.sf.net> + + * gtk-doc-plugins.mak: + * gtk-doc.mak: + We should have never forked this that much :/. + +2007-12-13 Tim-Philipp Müller <tim at centricular dot net> + + * check-exports: + Fix build on the ppc64 build bot. + +2007-12-13 Tim-Philipp Müller <tim at centricular dot net> + + * check-exports: + Suppress more unintentional exports (too much hassle to rename them, + since the win32 project files would need changing too). + +2007-12-12 Tim-Philipp Müller <tim at centricular dot net> + + * Makefile.am: + check-exports should be disted. + +2007-12-12 Tim-Philipp Müller <tim at centricular dot net> + + * check-exports: + Add quick'n'dirty script to check the exported symbols of a library + against the symbols in the corresponding .def file (#493983). Based + on script by Ole André Vadla RavnÃ¥s. + +2007-11-06 Jan Schmidt <jan.schmidt@sun.com> + + * gtk-doc-plugins.mak: + Fix distcheck by making sure the types files are treated like the + other gtkdoc-scangobj generated files. + +2007-09-21 Sebastian Dröge <slomo@circular-chaos.org> + + * m4/gst-args.m4: + Let the AG_GST_ARG_ENABLE_EXPERIMENTAL macro default to disable + building of experimental plugins. Nobody uses it yet and the + --enable--experimental stuff from gst-plugins-good defaults to + disable too. + +2007-09-06 Tim-Philipp Müller <tim at centricular dot net> + + * gtk-doc-plugins.mak: + Just use the normal 'check' target and avoid a circular + dependency. + +2007-09-06 Tim-Philipp Müller <tim at centricular dot net> + + * gtk-doc-plugins.mak: + Add rule to error out if .hierarchy file contains tabs. + +2007-08-20 Tim-Philipp Müller <tim at centricular dot net> + + * download-translations: + * po.mak: + If there are new languages, they need to be added to po/LINGUAS. + +2007-08-20 Tim-Philipp Müller <tim at centricular dot net> + + * download-translations: + * po.mak: + Fix up 'download-po' a bit, so that we find new translations + for languages that aren't in our po/LINGUAS file yet too. + +2007-07-16 Jan Schmidt <thaytan@mad.scientist.com> + + * gst.supp: + Add a suppression for GLib caching the tmp dir seen on an + Ubuntu Feisty system. + +2007-07-13 Jan Schmidt <thaytan@mad.scientist.com> + + * m4/gst-feature.m4: + If we want to use 'echo -e', call /bin/echo instead of the shell's + since -e is a bash extension, and our /bin/sh might not be being + provided by bash. + +2007-07-01 Thomas Vander Stichele <thomas at apestaart dot org> + + * po.mak: + Translation project has moved. Also, no idea how this used to + work given that we weren't downloading a .po file. + +2007-06-25 Stefan Kost <ensonic@users.sf.net> + + * gst-xmlinspect.py: + * plugins.xsl: + Also extract element caps for plugin-docs. Fixes parts of #117692. + +2007-06-21 Tim-Philipp Müller <tim at centricular dot net> + + Patch by: Andreas Schwab + + * m4/gst-feature.m4: + Fix quoting (#449493). + +2007-06-10 Sebastian Dröge <slomo@circular-chaos.org> + + * m4/gst-parser.m4: + Only generate the parser if bison >= 1.875 _and_ flex >= 2.5.31 is + installed and use pre-generated sources otherwise. Fixes bug #444820. + +2007-05-11 Michael Smith <msmith@fluendo.com> + + * gst.supp: + Suppression variant for our good friend the TLS leak, this time for + Ubuntu Feisty/x86. + +2007-05-09 Tim-Philipp Müller <tim at centricular dot net> + + * gtk-doc-plugins.mak: + Fix make distcheck again; change some spaces to tabs in makefile. + +2007-04-29 Thomas Vander Stichele <thomas at apestaart dot org> + + * gtk-doc-plugins.mak (-module): + Error out when the html build step gives warnings, so they get + fixed properly. + +2007-04-23 Stefan Kost <ensonic@users.sf.net> + + * m4/gst-feature.m4: + Add macro AG_GST_PARSE_SUBSYSTEM_DISABLES that checks the defines in + the configuration header and AC_DEFINES the setings. + +2007-04-19 Sebastian Dröge <slomo@circular-chaos.org> + + Patch by: Vincent Torri <vtorri at univ-evry dot fr> + + * m4/gst-parser.m4: + Put the AC_MSG_RESULT output in brackets to get it properly written to + the terminal. + +2007-04-18 Sebastian Dröge <slomo@circular-chaos.org> + + * m4/gst-parser.m4: + Check for flex >= 2.5.31 and set GENERATE_PARSER if we have at least + that version. Otherwise use pre-generated parser sources as we can't + raise the required flex version. HAVE_MT_SAVE_FLEX is obsolete now + as we use a new enough flex version anyway. First part of #349180 + +2007-04-10 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-check.m4: + Allow pre-setting the GST(PB)_TOOLS/PLUGINS_DIR variables to help + builds against older GStreamer. + +2007-03-25 Sebastian Dröge <slomo@circular-chaos.org> + + * m4/gst-parser.m4: + Fix the flex version check. It ignored the micro version before. + +2007-03-09 Jan Schmidt <thaytan@mad.scientist.com> + + * check.mak: + Use the same timeout when generating valgrind suppressions as + running the valgrind test. + + * gst.supp: + Add some more suppressions and stuff. + +2007-03-08 Jan Schmidt <thaytan@mad.scientist.com> + + * check.mak: + Make sure GSlice is disabled when building suppressions too. + + * gst.supp: + Add around *850* lines of suppressions for one-time initialisations + inside libasound and gconf/bonobo/ORBit. I feel so dirty. + +2007-03-07 Jan Schmidt <thaytan@mad.scientist.com> + + * gst.supp: + add a suppression for this GConf flup on the FC5 buildbot. + +2007-03-06 Jan Schmidt <thaytan@mad.scientist.com> + + * gst.supp: + Make the suppression a little more generic, to catch the FC5 + backtrace too. + +2007-03-06 Jan Schmidt <thaytan@mad.scientist.com> + + * gst.supp: + Add a suppression for libcdio 0.76. It leaks an internal struct + when the CD-ROM device is not accessible. + +2007-02-28 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-arch.m4: + Move a line that was in the wrong macro + +2007-02-28 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst.m4: + Add + * m4/gst-arch.m4: + * m4/gst-args.m4: + * m4/gst-check.m4: + * m4/gst-debuginfo.m4: + * m4/gst-default.m4: + * m4/gst-doc.m4: + * m4/gst-error.m4: + * m4/gst-feature.m4: + * m4/gst-function.m4: + * m4/gst-gettext.m4: + * m4/gst-glib2.m4: + * m4/gst-libxml2.m4: + * m4/gst-parser.m4: + * m4/gst-plugin-docs.m4: + * m4/gst-plugindir.m4: + * m4/gst-valgrind.m4: + * m4/gst-x11.m4: + Convert all macros to use AG_GST style so we can properly warn + when they're missing if configure.ac calls AG_GST_INIT + Will require update in all GStreamer modules. + +2007-02-11 Stefan Kost <ensonic@users.sf.net> + + * m4/gst-args.m4: + Remove 'enable' from configure switch description as this leads to + confusing lines like "disable enable builing ...". + * m4/gst-feature.m4: + Fix comment to sound less horrible. + +2007-02-07 Tim-Philipp Müller <tim at centricular dot net> + + Patch by: Will Newton <will.newton gmail com> + + * m4/gst-check.m4: + Use $PKG_CONFIG rather than pkg-config directly, the one in our path + might not be the one we want, like when cross-compiling. Also, other + macros such as PKG_CHECK_MODULES use $PKG_CONFIG, so we should + probably too just for consistency. Fixes #405288. + +2007-01-08 Tim-Philipp Müller <tim at centricular dot net> + + * m4/gst-parser.m4: + Need to use double square brackets again so m4 doesn't remove them + (fixes #378931). + + * m4/gst-args.m4: + Use double square brackets here as well, for the same reason. + +2007-01-05 Tim-Philipp Müller <tim at centricular dot net> + + * m4/gst-parser.m4: + Use 'sed' rather than 'tr' to strip trailing letters from version + numbers, since 'tr' might not be available and we know sed is + (#378931). + +2006-10-21 Tim-Philipp Müller <tim at centricular dot net> + + * check.mak: + Increase default timeout under valgrind, 60 is just too short and + some tests take a bit longer these days and not everyone has a + beefy machine. + +2006-09-29 Michael Smith <msmith@fluendo.com> + + * gst.supp: + More suppressions for edgy. + +2006-09-28 Jan Schmidt <thaytan@mad.scientist.com> + + * m4/gst-glib2.m4: + Use gmodule-no-export-2.0.pc instead of gmodule-2.0.pc - we neither + want nor need --export-dynamic (which ends up making us export a bunch + of unneeded symbols) + +2006-09-14 Tim-Philipp Müller <tim at centricular dot net> + + * gst.supp: + Some suppressions for the more recent ld.so in ubuntu edgy. + +2006-08-23 Tim-Philipp Müller <tim at centricular dot net> + + * gst.supp: + Shorten function trail so the suppression works on + my ubuntu dapper system with core cvs as well. + +2006-07-28 Jan Schmidt <thaytan@mad.scientist.com> + + * gst.supp: + Extra suppressions from my Ubuntu x86_64 machine + +2006-07-24 Tim-Philipp Müller <tim at centricular dot net> + + Patch by: Frederic Peters <fpeters at entrouvert com> + + * m4/gst-parser.m4: + Need to double square brackets in .m4 files. Should fix bison + version detection with version numbers like 1.23a (#348354). + +2006-07-24 Jan Schmidt <thaytan@mad.scientist.com> + + * check.mak: + Valgrind fails to find tests written in tests/check/ directly (rather + than a subdir) - because valgrind gets run with a filename that + doesn't contain a relative path, it goes searching /usr/bin instead. + Run with ./.... to make things work either way. + + * gtk-doc-plugins.mak: + Add $(top_builddir)/src as a place to look for plugins + when building too, since that's where gst-template keeps things + +2006-07-23 Stefan Kost <ensonic@users.sf.net> + + Patch by: Frederic Peters <fpeters@entrouvert.com> + + * m4/gst-parser.m4: + Fix bison detection (#348354) + +2006-07-21 Stefan Kost <ensonic@users.sf.net> + + * m4/gst-parser.m4: + check for bison and flex + +2006-07-13 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-plugin-docs.m4: + remove the configure argument for enabling plugin doc build; + having gtk-doc enabled and pyxml present is enough of a trigger + +2006-07-03 Thomas Vander Stichele <thomas at apestaart dot org> + + * coverage/lcov.mak: + fix up rules to work with gst-python as well + run "make lcov" to test and generate the reports + run "make lcov-reset" to redo it after that + +2006-07-02 Thomas Vander Stichele <thomas at apestaart dot org> + + * Makefile.am: + * check.mak: + add an inspect target that inspects every element feature, + so we can have that added for coverage + * coverage/lcov.mak: + add support for lcov + +2006-07-02 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-args.m4: + when building with gcov, reset CFLAGS and friends to O0 + +2006-07-02 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-args.m4: + Find the gcov that matches the gcc version + Only allow gcov if we use gcc + +2006-07-02 Thomas Vander Stichele <thomas at apestaart dot org> + + * Makefile.am: + * coverage/coverage-report-entry.pl: + * coverage/coverage-report.pl: + * coverage/coverage-report.xsl: + copy coverage reporting files from dbus + +2006-07-01 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-args.m4: + libtool strips gcov's -f flags, so libgcov does not get + linked in. Setting GCOV_LIBS with -lgcov fixes libtool's + stripping + also show what pkg-config-path we set + +2006-06-22 Tim-Philipp Müller <tim at centricular dot net> + + Patch by: Peter Kjellerstedt <pkj at axis com> + + * m4/gst-feature.m4: + Show list of plugins without external dependencies that + will not be built as well (#344136). + +2006-06-15 Tim-Philipp Müller <tim at centricular dot net> + + * m4/gst-plugin-docs.m4: + add GST_PLUGIN_DOCS, which checks for everything needed + to build the plugin docs (namely gtk-doc and pyxml); also + adds a new --enable-plugin-docs configure switch; will + set ENABLE_PLUGIN_DOCS conditional for use in Makefile.am + files (see #344039). + +2006-06-11 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-check.m4: + add GST_PKG_CHECK_MODULES, which in the normal case of checking + for a dependency lib for a plug-in only needs two arguments + to do the right thing. + * m4/gst-feature.m4: + clean up output a little of feature checking; also deal with + non-plug-in feature checks + * m4/Makefile.am: + * m4/gst-gstreamer.m4: + remove this file; it's a useless check + +2006-06-06 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-arch.m4: + add PPC64 so we can have separate structure sizes for it + +2006-06-05 Edward Hervey <edward@fluendo.com> + + * gtk-doc.mak: + Check for the proper .devhelp2 file to remove. + +2006-05-31 Thomas Vander Stichele <thomas at apestaart dot org> + + * gtk-doc.mak: + allow a magic variable to suppress errors from docbuilding + +2006-05-30 Thomas Vander Stichele <thomas (at) apestaart (dot) org> + + * gtk-doc.mak: + error out if gtkdoc-mktmpl finds unused declarations + +2006-05-28 Edward Hervey <edward@fluendo.com> + + * gst.supp: + Reverting previous commit. That's good to know, Edward, but why ? + +2006-05-28 Edward Hervey <edward@fluendo.com> + + * gst.supp: + Added suppresion for memleak in g_option_context_parse on fc5-64 + +2006-05-19 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-check.m4: + set GSTPB_PLUGINS_DIR just like GST_PLUGINS_DIR + +2006-05-18 Tim-Philipp Müller <tim at centricular dot net> + + * check.mak: + Fix 'make help' in check directories, it should be + 'valgrind.gen-suppressions' not 'valgrind-gen-suppressions' + (not changing target to match help string on purpose to keep + scripts etc. functional). + +2006-05-18 Thomas Vander Stichele <thomas at apestaart dot org> + + Patch by: Peter Kjellerstedt + + * m4/gst-arch.m4: + add support for CRIS and CRISv32. + +2006-05-17 Jan Schmidt <thaytan@mad.scientist.com> + + * m4/gst-args.m4: + Fix the macros for command-line supplied package and origin names + so they don't end up being configure as "" (Fixes #341479) + +2006-05-14 Jan Schmidt <thaytan@mad.scientist.com> + + * gtk-doc.mak: + Add uninstall rule to remove .devhelp2 files. + +2006-05-09 Edward Hervey <edward@fluendo.com> + + * gst.supp: + Add suppression for GSlice version of + g_type_init calloc leak + +2006-04-05 Michael Smith <msmith@fluendo.com> + + * gst.supp: + Delete a bogus suppression for the registry code. + Generalise a suppression for a glib bug (see #337404) + +2006-04-04 Michael Smith <msmith@fluendo.com> + + * gst.supp: + Add a leak suppression: the existing glibc-doesn't-free-TLS one + wasn't triggering here. + +2006-04-04 Michael Smith <msmith@fluendo.com> + + * gst.supp: + Add some minimally-neccesary suppressions for my x86/dapper system. + +2006-04-01 Thomas Vander Stichele <thomas at apestaart dot org> + + * plugins.xsl: + Do not display an origin link if origin does not start with http + See #323798 + +2006-04-01 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-args.m4: + * m4/gst-feature.m4: + add more macros + * m4/gst-x11.m4: + X11-related checks + +2006-04-01 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/as-version.m4: + newer version + * m4/gst-args.m4: + * m4/gst-doc.m4: + update and add other macros to be shared across projects + +2006-03-24 Thomas Vander Stichele <thomas at apestaart dot org> + + * gst.supp: + add a suppression for g_parse_debug_string + +2006-03-23 Stefan Kost <ensonic@users.sf.net> + + * gstdoc-scangobj: + sync fully with gtkdoc-0.15 + +2006-03-23 Stefan Kost <ensonic@users.sf.net> + + * gstdoc-scangobj: + * gtk-doc.mak: + sync a little with gtk-doc mainline + +2006-03-17 Wim Taymans <wim@fluendo.com> + + * gst.supp: + add another clone suppression + change all glibc suppressions to match 2.3.* + +2006-03-09 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/check.m4: + fix test so it actually works when the normal check is used + over debian's/ubuntu's + +2006-03-08 Jan Schmidt <thaytan@mad.scientist.com> + + * check.mak: + Set G_SLICE=always-malloc when valgrinding tests + (closes #333272) + +2006-02-21 Jan Schmidt <thaytan@mad.scientist.com> + + * m4/gst-glib2.m4: + Fix debug output when the GLib version prerequisite is not found + +2006-02-13 Andy Wingo <wingo@pobox.com> + + * m4/check.m4: Hack around Debian/Ubuntu's broken installation of + the PIC version of check as libcheck_pic.a. Should work with + cross-compilation too. Grr. + +2006-02-06 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-default.m4: + switch to auto* sinks for defaults + +2006-02-02 Wim Taymans <wim@fluendo.com> + + * check.mak: + add a .valgrind.gen-suppressions target to aid in generating + suppressions + * gst.supp: + add more repressions from my debian glibc as of today + +2006-02-02 Thomas Vander Stichele <thomas at apestaart dot org> + + * gtk-doc-plugins.mak: + only add srcdir/gst if it exists + +2006-01-30 Thomas Vander Stichele <thomas at apestaart dot org> + + * release.mak: + don't complain about disted enums in win32 + +2006-01-20 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-check.m4: + AC_SUBST CFLAGS and LIBS + do a non-command because something is stripping out our AC_SUBST + +2006-01-20 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-args.m4: + * m4/gst-valgrind.m4: + properly give a "no" result manually when providing a + not-found action to fix configure output + +2006-01-20 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/pkg.m4: + update with a more recent version + +2006-01-07 Thomas Vander Stichele <thomas at apestaart dot org> + + * gettext.patch: + make Makefile depend on LINGUAS, so rebuilds work when adding + a language + +2006-01-03 Michael Smith <msmith@fluendo.com> + + * check.mak: + Clarify error message from valgrind test runs. + +2005-12-16 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-arch.m4: + define HOST_CPU + +2005-11-29 Thomas Vander Stichele <thomas at apestaart dot org> + + * check.mak: + add a valgrind-forever target for tests + +2005-11-28 Thomas Vander Stichele <thomas at apestaart dot org> + + * check.mak: + when a "make test.check" run fails, make it rerun the test with + at least debug level 2 + +2005-11-14 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/Makefile.am: + * m4/gst-check.m4: + fix check for base plugins + * m4/gst-default.m4: + add m4 to set default elements + +2005-10-18 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-check.m4: + check for tools correctly + +2005-10-18 Thomas Vander Stichele <thomas at apestaart dot org> + + * gtk-doc.mak: + only enable breaking on new API when make distcheck passes, + not before + +2005-10-18 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-check.m4: + Resurrect Julien's dead body and wipe his mind clean + +2005-10-18 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-check.m4: + Kill Julien + +2005-10-17 Julien MOUTTE <julien@moutte.net> + + * m4/gst-check.m4: I know Thomas will kill me but this + ifelse statement seems incorrect as it is always setting + required to "yes". With this one it seems to work. Fixes + build of gst-plugins-base on my setup where gstreamer-check + is definitely not present/required. + +2005-10-18 Stefan Kost <ensonic@users.sf.net> + + * gtk-doc.mak: + make build break on new api that has not been added to the + sections file + +2005-10-17 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-glib2.m4: + * m4/Makefile.am: + * m4/gst-check.m4: + add macro for easy checks for GStreamer libs + +2005-10-16 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-glib2.m4: + update, warn in error cases + +2005-10-16 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-error.m4: + add GST_SET_DEFAULT_LEVEL + +2005-10-16 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/Makefile.am: + * m4/gst-gettext.m4: + remove the AM_GNU_GETTEXT* calls, they need to be in configure.ac + * m4/gst-glib2.m4: + clean up and re-use in core soon + * m4/gst-plugindir.m4: + macro to set up PLUGINDIR and plugindir define/var + +2005-10-15 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/Makefile.am: + * m4/gst-gettext.m4: + add macro for setting up gettext + +2005-10-15 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-args.m4: + add some .m4's for argument checking that can be shared among modules + +2005-10-15 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/as-libtool.m4: + set _LT_LDFLAGS + * m4/gst-libxml2.m4: + document + +2005-10-15 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-arch.m4: + indent a little + add AC_REQUIRE + * m4/gst-error.m4: + clean up + +2005-10-12 Thomas Vander Stichele <thomas at apestaart dot org> + + * gst-autogen.sh: + update version detection expression to catch stuff like + Libtool (libtool15) 1.5.0 + +2005-10-11 Thomas Vander Stichele <thomas at apestaart dot org> + + * gst.supp: + commit 6 new suppressions related to g_module_open; can these + really not be folded into one ? + +2005-10-11 Edward Hervey <edward@fluendo.com> + + * gst.supp: + made the <g_type_init calloc 2> suppression more generic + Added pthread memleak suppresions + Added nss_parse_* memleak suppresion (used by g_option_context_parse) + +2005-10-11 Thomas Vander Stichele <thomas at apestaart dot org> + + * check.mak: + be more strict, more leak resolution + * gst.supp: + clean up the g_type_init suppressions + +2005-10-07 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/Makefile.am: + * m4/gst-valgrind.m4: + put the valgrind detection in an .m4 + +2005-09-29 Thomas Vander Stichele <thomas at apestaart dot org> + + * check.mak: + add some more targets, like "help", but also more intensive tests + +2005-09-23 Thomas Vander Stichele <thomas at apestaart dot org> + + * gtk-doc.mak: + make certain doc warnings fatal so people maintain docs again + +2005-09-23 Thomas Vander Stichele <thomas at apestaart dot org> + + * Makefile.am: + * gtk-doc-plugins.mak: + * scangobj-merge.py: + merge additions from the .signals.new and .args.new file in + the original ones, only updating if necessary + +2005-09-23 Thomas Vander Stichele <thomas at apestaart dot org> + + * gst-xmlinspect.py: + * gstdoc-scangobj: + * gtk-doc-plugins.mak: + fix properly for new API; make update in plugins dir now works + +2005-09-20 Thomas Vander Stichele <thomas at apestaart dot org> + + * gst-xmlinspect.py: + * gstdoc-scangobj: + some fixes for new API + * gtk-doc-plugins.mak: + set environment properly + +2005-09-17 David Schleef <ds@schleef.org> + + * gtk-doc-plugins.mak: Use new environment variables. + +2005-09-16 Michael Smith <msmith@fluendo.com> + + * gstdoc-scangobj: + Make the scanobj code reflect registry/plugin API changes + +2005-09-15 Thomas Vander Stichele <thomas at apestaart dot org> + + * gtk-doc-plugins.mak: + split out scanobj step (which will be run by doc maintainer) + from scan step (which will be run on every build) + clean up some of the commands for make distcheck + +2005-09-15 Thomas Vander Stichele <thomas at apestaart dot org> + + * gtk-doc-plugins.mak: + * mangle-tmpl.py: + first stab at reorganizing the plugins build so we can maintain + element docs + +2005-09-14 David Schleef <ds@schleef.org> + + * as-libtool.mak: Remove + * m4/as-libtool.m4: The libtool bug that this worked around has + been fixed. + * m4/as-version.m4: Don't define GST_RELEASE, since it causes + config.h to be regenerated needlessly, and we don't use it. + +2005-09-14 Thomas Vander Stichele <thomas at apestaart dot org> + + * gtk-doc-plugins.mak: + error out on inspect failure + +2005-09-14 Michael Smith <msmith@fluendo.com> + + * glib-gen.mak: + Don't call glib-mkenums with arguments that confuse/break MinGW, + fixes 316155. + +2005-09-03 Thomas Vander Stichele <thomas at apestaart dot org> + + * gtk-doc-plugins.mak: + * gtk-doc.mak: + * m4/gst-doc.m4: + separate out gtk-doc and docbook stuff + have two separate --enable configure flags + +2005-08-26 Thomas Vander Stichele <thomas at apestaart dot org> + + * check.mak: + add a .gdb target; rebuild registry for each target, otherwise + a code rebuild always triggers a reg rebuild, and it's just too + annoying + * gstdoc-scangobj: + +2005-08-21 Thomas Vander Stichele <thomas at apestaart dot org> + + * check.mak: + separate out REGISTRY_ENVIRONMENT; we want to use that from + our valgrind runs, but we also want TESTS_ENVIRONMENT to contain + everything that the first test, gst-register, needs + +2005-08-21 Thomas Vander Stichele <thomas at apestaart dot org> + + * check.mak: + parse output of valgrind and check for definitely lost, and error + out; somehow I was led to believe valgrind returns non-zero for + leaks, but I can't make it do that, so let's parse + +2005-08-20 Thomas Vander Stichele <thomas at apestaart dot org> + + * check.mak: + for some weird reason valgrind does not report actual memleaks + if GST_PLUGIN_PATH is set to anything but the core gstreamer dir + while valgrind is running. Since the registry is going to go + anyway, I don't want to waste any more time on this; I just run + valgrind without GST_PLUGIN_PATH set. Since the registry loading + doesn't check if GST_PLUGIN_PATH got changed as a reason to rebuild + the registry, that's actually fine. + +2005-08-15 Thomas Vander Stichele <thomas at apestaart dot org> + + * mangle-tmpl.py: + keep original Long_Description; only insert an include if it's + not already the first line in there + * plugins.xsl: + output more information for plugins, including an origin hyperlink + +2005-08-15 Thomas Vander Stichele <thomas at apestaart dot org> + + * gst-xmlinspect.py: + a first stab at inspecting plugins and outputting an xml description + * gtk-doc-plugins.mak: + a gtk-doc using snippet for plugins documentation + * plugins.xsl: + a stylesheet to convert gst-xmlinspect.py output to docbook output + for inclusion in the gtk-doc stuff + +2005-07-20 Ronald S. Bultje <rbultje@ronald.bitfreak.net> + + * m4/gst-doc.m4: + s/pdf/eps/ in test for whether we output EPS images (#309379). + +2005-07-18 Andy Wingo <wingo@pobox.com> + + * m4/as-libtool-tags.m4: Ooh, backported from libtool 1.6. Much + better. Thanks, Paolo Bonzini! + + * m4/Makefile.am (EXTRA_DIST): + * m4/as-libtool-tags.m4: New file, tries to disable some CXX and + fortran checks. + +2005-07-08 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-error.m4: + add macro to set ERROR_CFLAGS + +2005-06-30 Jan Schmidt <thaytan@mad.scientist.com> + + * gst-autogen.sh: + Remove the old autoregen.sh if it exists before recreating it, + to prevent confusing any shell process that might be reading it + currently. + +2005-06-29 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gtk-doc.m4: + added + +2005-06-03 Stefan Kost <ensonic@users.sf.net> + + * gst-autogen.sh: create autoregen.sh *before* shifting the options + +2005-05-17 Thomas Vander Stichele <thomas at apestaart dot org> + + * gst-autogen.sh: only update autoregen.sh on actual runs + +2005-03-11 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/check.m4: m4 from the check unit test suite + +2004-12-14 David Schleef <ds@schleef.org> + + * m4/gst-arch.m4: remove MMX stuff, since it doesn't work and + isn't needed anywhere + +2004-12-08 Thomas Vander Stichele <thomas at apestaart dot org> + + * gst-autogen.sh: + allow failure command to be run so we can clean upfrom autopoint + +2004-09-03 Zeeshan Ali Khattak <zeenix@gmail.com> + * m4/gst-feature.m4: Trying to correct the GST_CHECK_CONFIGPROG macro + +2004-07-21 Benjamin Otte <otte@gnome.org> + + * m4/.cvsignore: exciting updates for libtool m4 files + +2004-07-12 David Schleef <ds@schleef.org> + + * m4/as-objc.m4: Add a macro to test for objective C + +2004-06-12 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-feature.m4: + not all of them support --plugin-libs, so redirect stderr + +2004-06-12 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/as-scrub-include.m4: + sync with upstream to 0.1.4. Fixes #132440 + +2004-06-07 Benjamin Otte <otte@gnome.org> + + * m4/gst-feature.m4: + write a big marker into configure output when checking next plugin + to allow easier parsing of why plugins are(n't) built. + +2004-06-01 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/as-compiler-flag.m4: + * m4/as-compiler.m4: + * m4/as-libtool.m4: + * m4/as-version.m4: + sync with upstream, change sticky options to -ko + +2004-05-24 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/as-scrub-include.m4: synced with upstream + +2004-05-03 Thomas Vander Stichele <thomas at apestaart dot org> + + * po.mak: + snippet for updating .po files + +2004-03-18 Thomas Vander Stichele <thomas at apestaart dot org> + + * Makefile.am: + * m4/Makefile.am: + integrate these with the dist + +2004-03-17 Thomas Vander Stichele <thomas at apestaart dot org> + + * release.mak: add a release target + +2004-03-09 Thomas Vander Stichele <thomas at apestaart dot org> + + patch by: Stephane Loeuillet + + * m4/ax_create_stdint_h.m4: + use head -n instead of head - (#136500) + +2004-03-05 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-doc.m4: don't build PS without dvips binary + +2004-02-22 Julio M. Merino Vidal <jmmv@menta.net> + + reviewed by: Benjamin Otte <otte@gnome.org> + + * m4/as-docbook.m4: + don't use == operator with test(1) (fixes #135115) + +2004-02-16 Thomas Vander Stichele <thomas at apestaart dot org> + + * common/m4/gst-arch.m4: x86_64 is x86 too (clue from Fedora 2 test) + +2004-02-13 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-feature.m4: + remove AM_CONDITIONAL for the subsystem since automake 1.6.x + requires that call be in configure.ac + +2004-02-13 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-libxml2.m4: + take required version as argument, and default to 2.4.9 if not + specified + +2004-02-12 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/gst-feature.m4: + rename and fix up GST_CHECK_DISABLE_SUBSYSTEM + +2004-02-11 Thomas Vander Stichele <thomas at apestaart dot org> + + * common/m4/as-ac-expand.m4: + * common/m4/as-auto-alt.m4: + * common/m4/as-compiler-flag.m4: + * common/m4/as-compiler.m4: + * common/m4/as-docbook.m4: + * common/m4/as-libtool.m4: + * common/m4/as-scrub-include.m4: + * common/m4/as-version.m4: + * common/m4/glib-gettext.m4: + * common/m4/gst-arch.m4: + * common/m4/gst-debuginfo.m4: + * common/m4/gst-doc.m4: + * common/m4/gst-feature.m4: + * common/m4/gst-function.m4: + * common/m4/gst-glib2.m4: + * common/m4/gst-gstreamer.m4: + * common/m4/gst-libxml2.m4: + * common/m4/gst-makecontext.m4: + * common/m4/gst-mcsc.m4: + * common/m4/pkg.m4: + fix underquoted macros as reported by automake 1.8.x (#133800) + +2004-02-11 Johan Dahlin <johan@gnome.org> + + * gst-autogen.sh: Use A-Z instead of A-z in sed expression to + avoid a warning + +2004-02-05 Thomas Vander Stichele <thomas (at) apestaart (dot) org> + + * m4/gst-doc.m4: + we use --output-format=xml and --ingnore-files options to + gtkdoc-mkdb, which got added between 0.9 and 1.0 + +2004-02-04 Thomas Vander Stichele <thomas at apestaart dot org> + + * m4/as-libtool.m4: remove AM_PROG_LIBTOOL so it can move back + to configure.ac to shut up libtoolize + +2004-02-03 Thomas Vander Stichele <thomas at apestaart dot org> + + * glib-gen.mak: added; used to generate enums and marshal code + +2004-01-13 Thomas Vander Stichele <thomas at apestaart dot org> + + * gettext.patch: added; used by autogen.sh to make sure + GETTEXT_PACKAGE is understood from po/Makefile.in.in -> po/Makefile.in + diff --git a/common/Makefile.am b/common/Makefile.am new file mode 100755 index 0000000..cac4ff5 --- /dev/null +++ b/common/Makefile.am @@ -0,0 +1,16 @@ +SUBDIRS = m4 + +EXTRA_DIST = \ + ChangeLog \ + gettext.patch \ + glib-gen.mak gtk-doc.mak upload.mak release.mak win32.mak \ + gst-autogen.sh \ + check-exports \ + c-to-xml.py gst-xmlinspect.py mangle-tmpl.py scangobj-merge.py \ + gtk-doc-plugins.mak \ + plugins.xsl gstdoc-scangobj \ + gst.supp check.mak \ + coverage/lcov.mak \ + coverage/coverage-report.pl \ + coverage/coverage-report.xsl \ + coverage/coverage-report-entry.pl diff --git a/common/c-to-xml.py b/common/c-to-xml.py new file mode 100755 index 0000000..8448fd2 --- /dev/null +++ b/common/c-to-xml.py @@ -0,0 +1,34 @@ +# -*- Mode: Python -*- +# vi:si:et:sw=4:sts=4:ts=4 + +""" +Convert a C program to valid XML to be included in docbook +""" + +import sys +import os +from xml.sax import saxutils + +def main(): + if len(sys.argv) == 1: + sys.stderr.write("Please specify a source file to convert") + sys.exit(1) + source = sys.argv[1] + + if not os.path.exists(source): + sys.stderr.write("%s does not exist.\n" % source) + sys.exit(1) + + content = open(source, "r").read() + + # print header + print '<?xml version="1.0"?>' + print '<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">' + print + print '<programlisting>' + + # print content + print saxutils.escape(content).encode('UTF-8') + print '</programlisting>' + +main() diff --git a/common/check-exports b/common/check-exports new file mode 100755 index 0000000..16df41f --- /dev/null +++ b/common/check-exports @@ -0,0 +1,71 @@ +#!/bin/sh +# check-exports +# +# quick'n'dirty script that retrieves the list of exported symbols of a given +# library using 'nm', and compares that against the list of symbols-to-export +# of our win32/common/libfoo.def files. + +if [ $# -ne 2 ]; then + echo "Usage: $0 library.def library.so" + exit 1 +fi + +def_path="$1" +def_name="$(basename $def_path)" +lib_path="$2" + +lib_result="`mktemp /tmp/defname.XXXXXX`" + +LC_ALL=C +export LC_ALL + +# On Solaris, add -p to get the correct output format +NMARGS= +if nm -V 2>&1 |grep Solaris > /dev/null; then + NMARGS=-p +fi + +# FIXME 0.11: in 0.11, we should change the export filter to only export +# _gst_foo, but not __gst_foo (we can't change this now, since we added +# __gst_debug_min and __gst_debug_enabled at some point and need to keep +# ABI compatibility). So below we special-case some symbols that shouldn't +# really be exported, either because we're too lazy to rename them to something +# that's not exported (like the _gst_parse_* stuff) or because we had them in +# public headers at some point although they shouldn't be and so we need to +# keep them exported now (like _gst_debug_init, +# __gst_element_factory_add_interface or +# __gst_element_factory_add_static_pad_template). We suppress them here to +# make sure they're at least not exported in the windows msvc build (they +# were never in the .def file, so they never got exported). +# _end is special cased because for some reason it is reported as an exported +# BSS symbol, unlike on linux where it's a local absolute symbol. +nm $NMARGS $lib_path | awk \ + '{ + if ($3 !~ /^_gst_parse_yy/ && \ + $3 !~ /^_gst_[a-z]*_init/ && \ + $3 !~ /^_gst_parse_launch/ && \ + $3 !~ /^__gst_element_details_/ && \ + $3 !~ /^__gst_element_factory_add_/ && \ + $3 !~ /^gst_interfaces_marshal/ && \ + $3 ~ /^[_]*(gst_|Gst|GST_).*/) + { + if ($2 ~ /^[BSDG]$/) + print "\t" $3 " DATA" + else if ($2 == "T") + print "\t" $3 + } + }' | sort | awk '{ if (NR == 1) print "EXPORTS"; print $0; }' \ + > $lib_result + +diffoutput=`diff -u $def_path $lib_result` + +rm $lib_result + +if test "x$diffoutput" = "x"; then + exit 0; +else + echo -n "$diffoutput" >&2 + echo >&2 + exit 1; +fi + diff --git a/common/check.mak b/common/check.mak new file mode 100755 index 0000000..d31569f --- /dev/null +++ b/common/check.mak @@ -0,0 +1,149 @@ +clean-local-check: + for i in `find . -name ".libs" -type d`; do \ + rm -rf $$i; \ + done + +if HAVE_VALGRIND +# hangs spectacularly on some machines, so let's not do this by default yet +check-valgrind: + $(MAKE) valgrind +else +check-valgrind: + @true +endif + +LOOPS = 10 + +# run any given test by running make test.check +# if the test fails, run it again at at least debug level 2 +%.check: % + @$(TESTS_ENVIRONMENT) \ + CK_DEFAULT_TIMEOUT=20 \ + $* || \ + $(TESTS_ENVIRONMENT) \ + GST_DEBUG=$$GST_DEBUG,*:2 \ + CK_DEFAULT_TIMEOUT=20 \ + $* + +# run any given test in a loop +%.torture: % + @for i in `seq 1 $(LOOPS)`; do \ + $(TESTS_ENVIRONMENT) \ + CK_DEFAULT_TIMEOUT=20 \ + $*; done + +# run any given test in an infinite loop +%.forever: % + @while true; do \ + $(TESTS_ENVIRONMENT) \ + CK_DEFAULT_TIMEOUT=20 \ + $* || break; done + +# valgrind any given test by running make test.valgrind +%.valgrind: % + $(TESTS_ENVIRONMENT) \ + CK_DEFAULT_TIMEOUT=360 \ + G_SLICE=always-malloc \ + libtool --mode=execute \ + $(VALGRIND_PATH) -q \ + $(foreach s,$(SUPPRESSIONS),--suppressions=$(s)) \ + --tool=memcheck --leak-check=full --trace-children=yes \ + --leak-resolution=high --num-callers=20 \ + ./$* 2>&1 | tee valgrind.log + @if grep "==" valgrind.log > /dev/null 2>&1; then \ + rm valgrind.log; \ + exit 1; \ + fi + @rm valgrind.log + +# valgrind any given test and generate suppressions for it +%.valgrind.gen-suppressions: % + $(TESTS_ENVIRONMENT) \ + CK_DEFAULT_TIMEOUT=360 \ + G_SLICE=always-malloc \ + libtool --mode=execute \ + $(VALGRIND_PATH) -q \ + $(foreach s,$(SUPPRESSIONS),--suppressions=$(s)) \ + --tool=memcheck --leak-check=full --trace-children=yes \ + --leak-resolution=high --num-callers=20 \ + --gen-suppressions=all \ + ./$* 2>&1 | tee suppressions.log + +# valgrind any given test until failure by running make test.valgrind-forever +%.valgrind-forever: % + @while $(MAKE) $*.valgrind; do \ + true; done + +# gdb any given test by running make test.gdb +%.gdb: % + $(TESTS_ENVIRONMENT) \ + CK_FORK=no \ + libtool --mode=execute \ + gdb $* + +# torture tests +torture: $(TESTS) + -rm test-registry.xml + @echo "Torturing tests ..." + for i in `seq 1 $(LOOPS)`; do \ + $(MAKE) check || \ + (echo "Failure after $$i runs"; exit 1) || \ + exit 1; \ + done + @banner="All $(LOOPS) loops passed"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo $$dashes; echo $$banner; echo $$dashes + +# forever tests +forever: $(TESTS) + -rm test-registry.xml + @echo "Forever tests ..." + while true; do \ + $(MAKE) check || \ + (echo "Failure"; exit 1) || \ + exit 1; \ + done + +# valgrind all tests +valgrind: $(TESTS) + @echo "Valgrinding tests ..." + @failed=0; \ + for t in $(filter-out $(VALGRIND_TESTS_DISABLE),$(TESTS)); do \ + $(MAKE) $$t.valgrind; \ + if test "$$?" -ne 0; then \ + echo "Valgrind error for test $$t"; \ + failed=`expr $$failed + 1`; \ + whicht="$$whicht $$t"; \ + fi; \ + done; \ + if test "$$failed" -ne 0; then \ + echo "$$failed tests had leaks or errors under valgrind:"; \ + echo "$$whicht"; \ + false; \ + fi + +# inspect every plugin feature +GST_INSPECT = $(GST_TOOLS_DIR)/gst-inspect-$(GST_MAJORMINOR) +inspect: + @echo "Inspecting features ..." + for e in `$(TESTS_ENVIRONMENT) $(GST_INSPECT) | head -n -2 \ + | cut -d: -f2`; \ + do echo Inspecting $$e; \ + $(GST_INSPECT) $$e > /dev/null 2>&1; done + +help: + @echo "make check -- run all checks" + @echo "make torture -- run all checks $(LOOPS) times" + @echo "make (dir)/(test).check -- run the given check once" + @echo "make (dir)/(test).forever -- run the given check forever" + @echo "make (dir)/(test).torture -- run the given check $(LOOPS) times" + @echo + @echo "make (dir)/(test).gdb -- start up gdb for the given test" + @echo + @echo "make valgrind -- valgrind all tests" + @echo "make (dir)/(test).valgrind -- valgrind the given test" + @echo "make (dir)/(test).valgrind-forever -- valgrind the given test forever" + @echo "make (dir)/(test).valgrind.gen-suppressions -- generate suppressions" + @echo " and save to suppressions.log" + @echo "make inspect -- inspect all plugin features" + diff --git a/common/coverage/coverage-report-entry.pl b/common/coverage/coverage-report-entry.pl new file mode 100755 index 0000000..8f653af --- /dev/null +++ b/common/coverage/coverage-report-entry.pl @@ -0,0 +1,70 @@ +#!/usr/bin/perl +# +# Copyright (C) 2006 Daniel Berrange +# +# 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 + + +print <<EOF; +<html> +<head> +<title>Coverage report for $ARGV[0]</title> +<style type="text/css"> + span.perfect { + background: rgb(0,255,0); + } + span.terrible { + background: rgb(255,0,0); + } +</style> +</head> +<body> +<h1>Coverage report for $ARGV[0]</h1> + +<pre> +EOF + + +while (<>) { + s/&/&/g; + s/</</g; + s/>/>/g; + + if (/^\s*function (\S+) called (\d+) returned \d+% blocks executed \d+%/) { + my $class = $2 > 0 ? "perfect" : "terrible"; + $_ = "<span class=\"$class\" id=\"" . $1 . "\">$_</span>"; + } elsif (/^\s*branch\s+\d+\s+taken\s+(\d+)%\s+.*$/) { + my $class = $1 > 0 ? "perfect" : "terrible"; + $_ = "<span class=\"$class\">$_</span>"; + } elsif (/^\s*branch\s+\d+\s+never executed.*$/) { + my $class = "terrible"; + $_ = "<span class=\"$class\">$_</span>"; + } elsif (/^\s*call\s+\d+\s+never executed.*$/) { + my $class = "terrible"; + $_ = "<span class=\"$class\">$_</span>"; + } elsif (/^\s*call\s+\d+\s+returned\s+(\d+)%.*$/) { + my $class = $1 > 0 ? "perfect" : "terrible"; + $_ = "<span class=\"$class\">$_</span>"; + } + + + print; +} + +print <<EOF; +</pre> +</body> +</html> +EOF diff --git a/common/coverage/coverage-report.pl b/common/coverage/coverage-report.pl new file mode 100755 index 0000000..046bc37 --- /dev/null +++ b/common/coverage/coverage-report.pl @@ -0,0 +1,125 @@ +#!/usr/bin/perl +# +# Copyright (C) 2006 Daniel Berrange +# +# 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 + +use warnings; +use strict; + +my %coverage = ( functions => {}, files => {} ); + +my %filemap; + +my $type; +my $name; + +my @functions; + +while (<>) { + if (/^Function '(.*)'\s*$/) { + $type = "function"; + $name = $1; + $coverage{$type}->{$name} = {}; + push @functions, $name; + } elsif (/^File '(.*?)'\s*$/) { + $type = "file"; + $name = $1; + $coverage{$type}->{$name} = {}; + + foreach my $func (@functions) { + $coverage{"function"}->{$func}->{file} = $name; + } + @functions = (); + } elsif (/^Lines executed:(.*)%\s*of\s*(\d+)\s*$/) { + $coverage{$type}->{$name}->{lines} = $2; + $coverage{$type}->{$name}->{linesCoverage} = $1; + } elsif (/^Branches executed:(.*)%\s*of\s*(\d+)\s*$/) { + $coverage{$type}->{$name}->{branches} = $2; + $coverage{$type}->{$name}->{branchesCoverage} = $1; + } elsif (/^Taken at least once:(.*)%\s*of\s*(\d+)\s*$/) { + $coverage{$type}->{$name}->{conds} = $2; + $coverage{$type}->{$name}->{condsCoverage} = $1; + } elsif (/^Calls executed:(.*)%\s*of\s*(\d+)\s*$/) { + $coverage{$type}->{$name}->{calls} = $2; + $coverage{$type}->{$name}->{callsCoverage} = $1; + } elsif (/^No branches$/) { + $coverage{$type}->{$name}->{branches} = 0; + $coverage{$type}->{$name}->{branchesCoverage} = "100.00"; + $coverage{$type}->{$name}->{conds} = 0; + $coverage{$type}->{$name}->{condsCoverage} = "100.00"; + } elsif (/^No calls$/) { + $coverage{$type}->{$name}->{calls} = 0; + $coverage{$type}->{$name}->{callsCoverage} = "100.00"; + } elsif (/^\s*(.*):creating '(.*)'\s*$/) { + $filemap{$1} = $2; + } elsif (/^\s*$/) { + # nada + } else { + warn "Shit [$_]\n"; + } +} + +my %summary; +foreach my $type ("function", "file") { + $summary{$type} = {}; + foreach my $m ("lines", "branches", "conds", "calls") { + my $totalGot = 0; + my $totalMiss = 0; + my $count = 0; + foreach my $func (keys %{$coverage{function}}) { + $count++; + my $got = $coverage{function}->{$func}->{$m}; + $totalGot += $got; + my $miss = $got * $coverage{function}->{$func}->{$m ."Coverage"} / 100; + $totalMiss += $miss; + } + $summary{$type}->{$m} = sprintf("%d", $totalGot); + $summary{$type}->{$m . "Coverage"} = sprintf("%.2f", $totalMiss / $totalGot * 100); + } +} + + + +print "<coverage>\n"; + +foreach my $type ("function", "file") { + printf "<%ss>\n", $type; + foreach my $name (sort { $a cmp $b } keys %{$coverage{$type}}) { + my $rec = $coverage{$type}->{$name}; + printf " <entry name=\"%s\" details=\"%s\">\n", $name, ($type eq "file" ? $filemap{$name} : $filemap{$rec->{file}}); + printf " <lines count=\"%s\" coverage=\"%s\"/>\n", $rec->{lines}, $rec->{linesCoverage}; + if (exists $rec->{branches}) { + printf " <branches count=\"%s\" coverage=\"%s\"/>\n", $rec->{branches}, $rec->{branchesCoverage}; + } + if (exists $rec->{conds}) { + printf " <conditions count=\"%s\" coverage=\"%s\"/>\n", $rec->{conds}, $rec->{condsCoverage}; + } + if (exists $rec->{calls}) { + printf " <calls count=\"%s\" coverage=\"%s\"/>\n", $rec->{calls}, $rec->{callsCoverage}; + } + print " </entry>\n"; + } + + printf " <summary>\n"; + printf " <lines count=\"%s\" coverage=\"%s\"/>\n", $summary{$type}->{lines}, $summary{$type}->{linesCoverage}; + printf " <branches count=\"%s\" coverage=\"%s\"/>\n", $summary{$type}->{branches}, $summary{$type}->{branchesCoverage}; + printf " <conditions count=\"%s\" coverage=\"%s\"/>\n", $summary{$type}->{conds}, $summary{$type}->{condsCoverage}; + printf " <calls count=\"%s\" coverage=\"%s\"/>\n", $summary{$type}->{calls}, $summary{$type}->{callsCoverage}; + printf " </summary>\n"; + printf "</%ss>\n", $type; +} + +print "</coverage>\n"; diff --git a/common/coverage/coverage-report.xsl b/common/coverage/coverage-report.xsl new file mode 100755 index 0000000..b19ebb6 --- /dev/null +++ b/common/coverage/coverage-report.xsl @@ -0,0 +1,235 @@ +<?xml version="1.0" encoding="utf-8"?>
+<!--
+#
+# Copyright (C) 2006 Daniel Berrange
+#
+# 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
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+ <xsl:output method="html"/>
+
+ <xsl:template match="coverage">
+ <html>
+ <head>
+ <title>Coverage report</title>
+ <style type="text/css">
+ tbody tr.odd td.label {
+ border-top: 1px solid rgb(128,128,128);
+ border-bottom: 1px solid rgb(128,128,128);
+ }
+ tbody tr.odd td.label {
+ background: rgb(200,200,200);
+ }
+
+ thead, tfoot {
+ background: rgb(60,60,60);
+ color: white;
+ font-weight: bold;
+ }
+
+ tr td.perfect {
+ background: rgb(0,255,0);
+ color: black;
+ }
+ tr td.excellant {
+ background: rgb(140,255,140);
+ color: black;
+ }
+ tr td.good {
+ background: rgb(160,255,0);
+ color: black;
+ }
+ tr td.poor {
+ background: rgb(255,160,0);
+ color: black;
+ }
+ tr td.bad {
+ background: rgb(255,140,140);
+ color: black;
+ }
+ tr td.terrible {
+ background: rgb(255,0,0);
+ color: black;
+ }
+ </style>
+ </head>
+ <body>
+ <h1>Coverage report</h1>
+ <xsl:apply-templates/>
+ </body>
+ </html>
+ </xsl:template>
+
+ <xsl:template match="functions">
+ <h2>Function coverage</h2>
+ <xsl:call-template name="content">
+ <xsl:with-param name="type" select="'function'"/>
+ </xsl:call-template>
+ </xsl:template>
+
+
+ <xsl:template match="files">
+ <h2>File coverage</h2>
+ <xsl:call-template name="content">
+ <xsl:with-param name="type" select="'file'"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template name="content">
+ <xsl:param name="type"/>
+ <table>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Lines</th>
+ <th>Branches</th>
+ <th>Conditions</th>
+ <th>Calls</th>
+ </tr>
+ </thead>
+ <tbody>
+ <xsl:for-each select="entry">
+ <xsl:call-template name="entry">
+ <xsl:with-param name="type" select="$type"/>
+ <xsl:with-param name="class">
+ <xsl:choose>
+ <xsl:when test="position() mod 2">
+ <xsl:text>odd</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>even</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:for-each>
+ </tbody>
+ <tfoot>
+ <xsl:for-each select="summary">
+ <xsl:call-template name="entry">
+ <xsl:with-param name="type" select="'summary'"/>
+ <xsl:with-param name="class">
+ <xsl:choose>
+ <xsl:when test="position() mod 2">
+ <xsl:text>odd</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>even</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:for-each>
+ </tfoot>
+ </table>
+ </xsl:template>
+
+ <xsl:template name="entry">
+ <xsl:param name="type"/>
+ <xsl:param name="class"/>
+ <tr class="{$class}">
+ <xsl:choose>
+ <xsl:when test="$type = 'function'">
+ <td class="label"><a href="{@details}.html#{@name}"><xsl:value-of select="@name"/></a></td>
+ </xsl:when>
+ <xsl:when test="$type = 'file'">
+ <td class="label"><a href="{@details}.html"><xsl:value-of select="@name"/></a></td>
+ </xsl:when>
+ <xsl:otherwise>
+ <td class="label">Summary</td>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:if test="count(lines)">
+ <xsl:apply-templates select="lines"/>
+ </xsl:if>
+ <xsl:if test="not(count(lines))">
+ <xsl:call-template name="missing"/>
+ </xsl:if>
+
+ <xsl:if test="count(branches)">
+ <xsl:apply-templates select="branches"/>
+ </xsl:if>
+ <xsl:if test="not(count(branches))">
+ <xsl:call-template name="missing"/>
+ </xsl:if>
+
+ <xsl:if test="count(conditions)">
+ <xsl:apply-templates select="conditions"/>
+ </xsl:if>
+ <xsl:if test="not(count(conditions))">
+ <xsl:call-template name="missing"/>
+ </xsl:if>
+
+ <xsl:if test="count(calls)">
+ <xsl:apply-templates select="calls"/>
+ </xsl:if>
+ <xsl:if test="not(count(calls))">
+ <xsl:call-template name="missing"/>
+ </xsl:if>
+
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="lines">
+ <xsl:call-template name="row"/>
+ </xsl:template>
+
+ <xsl:template match="branches">
+ <xsl:call-template name="row"/>
+ </xsl:template>
+
+ <xsl:template match="conditions">
+ <xsl:call-template name="row"/>
+ </xsl:template>
+
+ <xsl:template match="calls">
+ <xsl:call-template name="row"/>
+ </xsl:template>
+
+ <xsl:template name="missing">
+ <td></td>
+ </xsl:template>
+
+ <xsl:template name="row">
+ <xsl:variable name="quality">
+ <xsl:choose>
+ <xsl:when test="@coverage = 100">
+ <xsl:text>perfect</xsl:text>
+ </xsl:when>
+ <xsl:when test="@coverage >= 80.0">
+ <xsl:text>excellant</xsl:text>
+ </xsl:when>
+ <xsl:when test="@coverage >= 60.0">
+ <xsl:text>good</xsl:text>
+ </xsl:when>
+ <xsl:when test="@coverage >= 40.0">
+ <xsl:text>poor</xsl:text>
+ </xsl:when>
+ <xsl:when test="@coverage >= 20.0">
+ <xsl:text>bad</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>terrible</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <td class="{$quality}"><xsl:value-of select="@coverage"/>% of <xsl:value-of select="@count"/></td>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/common/coverage/lcov.mak b/common/coverage/lcov.mak new file mode 100755 index 0000000..0ca9456 --- /dev/null +++ b/common/coverage/lcov.mak @@ -0,0 +1,42 @@ +## .PHONY so it always rebuilds it +.PHONY: lcov-reset lcov lcov-run lcov-report lcov-upload + +# run lcov from scratch, always +lcov-reset: + $(MAKE) lcov-run + $(MAKE) lcov-report + +# run lcov from scratch if the dir is not there +lcov: + $(MAKE) lcov-reset + +if GST_GCOV_ENABLED +# reset run coverage tests +lcov-run: + @-rm -rf lcov + lcov --directory . --zerocounters + -if test -d tests/check; then $(MAKE) -C tests/check inspect; fi + -$(MAKE) check + +# generate report based on current coverage data +lcov-report: + mkdir lcov + lcov --compat-libtool --directory . --capture --output-file lcov/lcov.info + lcov -l lcov/lcov.info | grep -v "`cd $(top_srcdir) && pwd`" | cut -d: -f1 > lcov/remove + lcov -l lcov/lcov.info | grep "tests/check/" | cut -d: -f1 >> lcov/remove + lcov -r lcov/lcov.info `cat lcov/remove` > lcov/lcov.cleaned.info + rm lcov/remove + mv lcov/lcov.cleaned.info lcov/lcov.info + genhtml -t "$(PACKAGE_STRING)" -o lcov --num-spaces 2 lcov/lcov.info + +lcov-upload: lcov + rsync -rvz -e ssh --delete lcov/* gstreamer.freedesktop.org:/srv/gstreamer.freedesktop.org/www/data/coverage/lcov/$(PACKAGE) + +else +lcov-run: + echo "Need to reconfigure with --enable-gcov" + +lcov-report: + echo "Need to reconfigure with --enable-gcov" +endif + diff --git a/common/gettext.patch b/common/gettext.patch new file mode 100755 index 0000000..659718e --- /dev/null +++ b/common/gettext.patch @@ -0,0 +1,23 @@ +--- po/Makefile.in.in.orig 2006-01-07 12:03:45.000000000 +0100 ++++ po/Makefile.in.in 2006-01-07 12:04:23.000000000 +0100 +@@ -11,6 +11,9 @@ + PACKAGE = @PACKAGE@ + VERSION = @VERSION@ + ++# thomas: add GETTEXT_PACKAGE substitution as used in Makevars ++GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ ++ + SHELL = /bin/sh + @SET_MAKE@ + +@@ -305,7 +308,9 @@ + update-gmo: Makefile $(GMOFILES) + @: + +-Makefile: Makefile.in.in $(top_builddir)/config.status POTFILES.in ++# thomas: add LINGUAS as a dependency so that the Makefile gets rebuilt ++# properly when we add languages ++Makefile: Makefile.in.in $(top_builddir)/config.status POTFILES.in LINGUAS + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \ + $(SHELL) ./config.status diff --git a/common/glib-gen.mak b/common/glib-gen.mak new file mode 100755 index 0000000..f9027da --- /dev/null +++ b/common/glib-gen.mak @@ -0,0 +1,44 @@ +# these are the variables your Makefile.am should set +# the example is based on the colorbalance interface + +#glib_enum_headers=$(colorbalance_headers) +#glib_enum_define=GST_COLOR_BALANCE +#glib_enum_prefix=gst_color_balance + +enum_headers=$(foreach h,$(glib_enum_headers),\n\#include \"$(h)\") + +# these are all the rules generating the relevant files +%-marshal.h: %-marshal.list + glib-genmarshal --header --prefix=$(glib_enum_prefix)_marshal $^ > $*-marshal.h.tmp + mv $*-marshal.h.tmp $*-marshal.h + +%-marshal.c: %-marshal.list + echo "#include \"$*-marshal.h\"" >> $*-marshal.c.tmp + glib-genmarshal --body --prefix=$(glib_enum_prefix)_marshal $^ >> $*-marshal.c.tmp + mv $*-marshal.c.tmp $*-marshal.c + +%-enumtypes.h: $(glib_enum_headers) + glib-mkenums \ + --fhead "#ifndef __$(glib_enum_define)_ENUM_TYPES_H__\n#define __$(glib_enum_define)_ENUM_TYPES_H__\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n" \ + --fprod "\n/* enumerations from \"@filename@\" */\n" \ + --vhead "GType @enum_name@_get_type (void);\n#define GST_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \ + --ftail "G_END_DECLS\n\n#endif /* __$(glib_enum_define)_ENUM_TYPES_H__ */" \ + $^ > $@ + +%-enumtypes.c: $(glib_enum_headers) + @if test "x$(glib_enum_headers)" == "x"; then echo "ERROR: glib_enum_headers is empty, please fix Makefile"; exit 1; fi + glib-mkenums \ + --fhead "#include \"$*-enumtypes.h\"\n$(enum_headers)" \ + --fprod "\n/* enumerations from \"@filename@\" */" \ + --vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \ + --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \ + --vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (\"@EnumName@\", values);\n }\n return etype;\n}\n" \ + $^ > $@ + +# a hack rule to make sure .Plo files exist because they get include'd +# from Makefile's +.deps/%-marshal.Plo: + touch $@ + +.deps/%-enumtypes.Plo: + touch $@ diff --git a/common/gst-autogen.sh b/common/gst-autogen.sh new file mode 100755 index 0000000..ae60f7e --- /dev/null +++ b/common/gst-autogen.sh @@ -0,0 +1,294 @@ +# a silly hack that generates autoregen.sh but it's handy +# Remove the old autoregen.sh first to create a new file, +# as the current one may be being read by the shell executing +# this script. +if [ -f "autoregen.sh" ]; then + rm autoregen.sh +fi +echo "#!/bin/sh" > autoregen.sh +echo "./autogen.sh $@ \$@" >> autoregen.sh +chmod +x autoregen.sh + +# helper functions for autogen.sh + +debug () +# print out a debug message if DEBUG is a defined variable +{ + if test ! -z "$DEBUG" + then + echo "DEBUG: $1" + fi +} + +version_check () +# check the version of a package +# first argument : package name (executable) +# second argument : optional path where to look for it instead +# third argument : source download url +# rest of arguments : major, minor, micro version +# all consecutive ones : suggestions for binaries to use +# (if not specified in second argument) +{ + PACKAGE=$1 + PKG_PATH=$2 + URL=$3 + MAJOR=$4 + MINOR=$5 + MICRO=$6 + + # for backwards compatibility, we let PKG_PATH=PACKAGE when PKG_PATH null + if test -z "$PKG_PATH"; then PKG_PATH=$PACKAGE; fi + debug "major $MAJOR minor $MINOR micro $MICRO" + VERSION=$MAJOR + if test ! -z "$MINOR"; then VERSION=$VERSION.$MINOR; else MINOR=0; fi + if test ! -z "$MICRO"; then VERSION=$VERSION.$MICRO; else MICRO=0; fi + + debug "major $MAJOR minor $MINOR micro $MICRO" + + for SUGGESTION in $PKG_PATH; do + COMMAND="$SUGGESTION" + + # don't check if asked not to + test -z "$NOCHECK" && { + echo -n " checking for $COMMAND >= $VERSION ... " + } || { + # we set a var with the same name as the package, but stripped of + # unwanted chars + VAR=`echo $PACKAGE | sed 's/-//g'` + debug "setting $VAR" + eval $VAR="$COMMAND" + return 0 + } + + debug "checking version with $COMMAND" + ($COMMAND --version) < /dev/null > /dev/null 2>&1 || + { + echo "not found." + continue + } + # strip everything that's not a digit, then use cut to get the first field + pkg_version=`$COMMAND --version|head -n 1|sed 's/^.*)[^0-9]*//'|cut -d' ' -f1` + debug "pkg_version $pkg_version" + # remove any non-digit characters from the version numbers to permit numeric + # comparison + pkg_major=`echo $pkg_version | cut -d. -f1 | sed s/[a-zA-Z\-].*//g` + pkg_minor=`echo $pkg_version | cut -d. -f2 | sed s/[a-zA-Z\-].*//g` + pkg_micro=`echo $pkg_version | cut -d. -f3 | sed s/[a-zA-Z\-].*//g` + test -z "$pkg_major" && pkg_major=0 + test -z "$pkg_minor" && pkg_minor=0 + test -z "$pkg_micro" && pkg_micro=0 + debug "found major $pkg_major minor $pkg_minor micro $pkg_micro" + + #start checking the version + debug "version check" + + # reset check + WRONG= + + if [ ! "$pkg_major" -gt "$MAJOR" ]; then + debug "major: $pkg_major <= $MAJOR" + if [ "$pkg_major" -lt "$MAJOR" ]; then + debug "major: $pkg_major < $MAJOR" + WRONG=1 + elif [ ! "$pkg_minor" -gt "$MINOR" ]; then + debug "minor: $pkg_minor <= $MINOR" + if [ "$pkg_minor" -lt "$MINOR" ]; then + debug "minor: $pkg_minor < $MINOR" + WRONG=1 + elif [ "$pkg_micro" -lt "$MICRO" ]; then + debug "micro: $pkg_micro < $MICRO" + WRONG=1 + fi + fi + fi + + if test ! -z "$WRONG"; then + echo "found $pkg_version, not ok !" + continue + else + echo "found $pkg_version, ok." + # we set a var with the same name as the package, but stripped of + # unwanted chars + VAR=`echo $PACKAGE | sed 's/-//g'` + debug "setting $VAR" + eval $VAR="$COMMAND" + return 0 + fi + done + + echo "not found !" + echo "You must have $PACKAGE installed to compile $package." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at $URL" + return 1; +} + +aclocal_check () +{ + # normally aclocal is part of automake + # so we expect it to be in the same place as automake + # so if a different automake is supplied, we need to adapt as well + # so how's about replacing automake with aclocal in the set var, + # and saving that in $aclocal ? + # note, this will fail if the actual automake isn't called automake* + # or if part of the path before it contains it + if [ -z "$automake" ]; then + echo "Error: no automake variable set !" + return 1 + else + aclocal=`echo $automake | sed s/automake/aclocal/` + debug "aclocal: $aclocal" + if [ "$aclocal" != "aclocal" ]; + then + CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-aclocal=$aclocal" + fi + if [ ! -x `which $aclocal` ]; then + echo "Error: cannot execute $aclocal !" + return 1 + fi + fi +} + +autoheader_check () +{ + # same here - autoheader is part of autoconf + # use the same voodoo + if [ -z "$autoconf" ]; then + echo "Error: no autoconf variable set !" + return 1 + else + autoheader=`echo $autoconf | sed s/autoconf/autoheader/` + debug "autoheader: $autoheader" + if [ "$autoheader" != "autoheader" ]; + then + CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-autoheader=$autoheader" + fi + if [ ! -x `which $autoheader` ]; then + echo "Error: cannot execute $autoheader !" + return 1 + fi + fi + +} +autoconf_2_52d_check () +{ + # autoconf 2.52d has a weird issue involving a yes:no error + # so don't allow it's use + test -z "$NOCHECK" && { + ac_version=`$autoconf --version|head -n 1|sed 's/^[a-zA-Z\.\ ()]*//;s/ .*$//'` + if test "$ac_version" = "2.52d"; then + echo "autoconf 2.52d has an issue with our current build." + echo "We don't know who's to blame however. So until we do, get a" + echo "regular version. RPM's of a working version are on the gstreamer site." + exit 1 + fi + } + return 0 +} + +die_check () +{ + # call with $DIE + # if set to 1, we need to print something helpful then die + DIE=$1 + if test "x$DIE" = "x1"; + then + echo + echo "- Please get the right tools before proceeding." + echo "- Alternatively, if you're sure we're wrong, run with --nocheck." + exit 1 + fi +} + +autogen_options () +{ + if test "x$1" = "x"; then + return 0 + fi + + while test "x$1" != "x" ; do + optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + case "$1" in + --noconfigure) + NOCONFIGURE=defined + AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --noconfigure" + echo "+ configure run disabled" + shift + ;; + --nocheck) + AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --nocheck" + NOCHECK=defined + echo "+ autotools version check disabled" + shift + ;; + --debug) + DEBUG=defined + AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --debug" + echo "+ debug output enabled" + shift + ;; + -h|--help) + echo "autogen.sh (autogen options) -- (configure options)" + echo "autogen.sh help options: " + echo " --noconfigure don't run the configure script" + echo " --nocheck don't do version checks" + echo " --debug debug the autogen process" + echo + echo " --with-autoconf PATH use autoconf in PATH" + echo " --with-automake PATH use automake in PATH" + echo + echo "Any argument either not in the above list or after a '--' will be " + echo "passed to ./configure." + exit 1 + ;; + --with-automake=*) + AUTOMAKE=$optarg + echo "+ using alternate automake in $optarg" + CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-automake=$AUTOMAKE" + shift + ;; + --with-autoconf=*) + AUTOCONF=$optarg + echo "+ using alternate autoconf in $optarg" + CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-autoconf=$AUTOCONF" + shift + ;; + --) shift ; break ;; + *) + echo "+ passing argument $1 to configure" + CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT $1" + shift + ;; + esac + done + + for arg do CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT $arg"; done + if test ! -z "$CONFIGURE_EXT_OPT" + then + echo "+ options passed to configure: $CONFIGURE_EXT_OPT" + fi +} + +toplevel_check () +{ + srcfile=$1 + test -f $srcfile || { + echo "You must run this script in the top-level $package directory" + exit 1 + } +} + + +tool_run () +{ + tool=$1 + options=$2 + run_if_fail=$3 + echo "+ running $tool $options..." + $tool $options || { + echo + echo $tool failed + eval $run_if_fail + exit 1 + } +} diff --git a/common/gst-xmlinspect.py b/common/gst-xmlinspect.py new file mode 100755 index 0000000..0d7f696 --- /dev/null +++ b/common/gst-xmlinspect.py @@ -0,0 +1,168 @@ +# -*- Mode: Python -*- +# vi:si:et:sw=4:sts=4:ts=4 + +""" +examine all plugins and elements and output xml documentation for them +used as part of the plugin documentation build +""" + +import sys +import os +import pygst +pygst.require('0.10') +import gst + +INDENT_SIZE = 2 + +# all templates + +PAD_TEMPLATE = """<caps> + <name>%(name)s</name> + <direction>%(direction)s</direction> + <presence>%(presence)s</presence> + <details>%(details)s</details> +</caps>""" + +ELEMENT_TEMPLATE = """<element> + <name>%(name)s</name> + <longname>%(longname)s</longname> + <class>%(class)s</class> + <description>%(description)s</description> + <author>%(author)s</author> + <pads> +%(pads)s + </pads> +</element>""" + +PLUGIN_TEMPLATE = """<plugin> + <name>%(name)s</name> + <description>%(description)s</description> + <filename>%(filename)s</filename> + <basename>%(basename)s</basename> + <version>%(version)s</version> + <license>%(license)s</license> + <source>%(source)s</source> + <package>%(package)s</package> + <origin>%(origin)s</origin> + <elements> +%(elements)s + </elements> +</plugin>""" + +def xmlencode(line): + """ + Replace &, <, and > + """ + line = "&".join(line.split("&")) + line = "<".join(line.split("<")) + line = ">".join(line.split(">")) + return line + +def get_offset(indent): + return " " * INDENT_SIZE * indent + +def output_pad_template(pt, indent=0): + print "PAD TEMPLATE", pt.name_template + paddir = ("unknown","source","sink") + padpres = ("always","sometimes","request") + + d = { + 'name': xmlencode(pt.name_template), + 'direction': xmlencode(paddir[pt.direction]), + 'presence': xmlencode(padpres[pt.presence]), + 'details': xmlencode(pt.static_caps.string), + } + block = PAD_TEMPLATE % d + + offset = get_offset(indent) + return offset + ("\n" + offset).join(block.split("\n")) + +def output_element_factory(elf, indent=0): + print "ELEMENT", elf.get_name() + + padsoutput = [] + padtemplates = elf.get_static_pad_templates() + for padtemplate in padtemplates: + padsoutput.append(output_pad_template(padtemplate, indent)) + + d = { + 'name': xmlencode(elf.get_name()), + 'longname': xmlencode(elf.get_longname()), + 'class': xmlencode(elf.get_klass()), + 'description': xmlencode(elf.get_description()), + 'author': xmlencode(elf.get_author()), + 'pads': "\n".join(padsoutput), + } + block = ELEMENT_TEMPLATE % d + + offset = get_offset(indent) + return offset + ("\n" + offset).join(block.split("\n")) + +def output_plugin(plugin, indent=0): + print "PLUGIN", plugin.get_name() + version = plugin.get_version() + + elements = {} + gst.debug('getting features for plugin %s' % plugin.get_name()) + registry = gst.registry_get_default() + features = registry.get_feature_list_by_plugin(plugin.get_name()) + gst.debug('plugin %s has %d features' % (plugin.get_name(), len(features))) + for feature in features: + if isinstance(feature, gst.ElementFactory): + elements[feature.get_name()] = feature + #gst.debug("got features") + + elementsoutput = [] + keys = elements.keys() + keys.sort() + for name in keys: + feature = elements[name] + elementsoutput.append(output_element_factory(feature, indent + 2)) + + filename = plugin.get_filename() + basename = filename + if basename: + basename = os.path.basename(basename) + d = { + 'name': xmlencode(plugin.get_name()), + 'description': xmlencode(plugin.get_description()), + 'filename': filename, + 'basename': basename, + 'version': version, + 'license': xmlencode(plugin.get_license()), + 'source': xmlencode(plugin.get_source()), + 'package': xmlencode(plugin.get_package()), + 'origin': xmlencode(plugin.get_origin()), + 'elements': "\n".join(elementsoutput), + } + block = PLUGIN_TEMPLATE % d + + offset = get_offset(indent) + return offset + ("\n" + offset).join(block.split("\n")) + +def main(): + if len(sys.argv) == 1: + sys.stderr.write("Please specify a source module to inspect") + sys.exit(1) + source = sys.argv[1] + + if len(sys.argv) > 2: + os.chdir(sys.argv[2]) + + registry = gst.registry_get_default() + all = registry.get_plugin_list() + for plugin in all: + gst.debug("inspecting plugin %s from source %s" % ( + plugin.get_name(), plugin.get_source())) + # this skips gstcoreelements, with bin and pipeline + if plugin.get_filename() is None: + continue + if plugin.get_source() != source: + continue + + filename = "plugin-%s.xml" % plugin.get_name() + handle = open(filename, "w") + handle.write(output_plugin(plugin)) + handle.close() + +main() diff --git a/common/gst.supp b/common/gst.supp new file mode 100755 index 0000000..9b2a3a2 --- /dev/null +++ b/common/gst.supp @@ -0,0 +1,1988 @@ +### this file contains suppressions for valgrind when running +### the gstreamer unit tests +### it might be useful for wider use as well + +### syscall suppressions + +{ + <clone on Wim's Debian> + Memcheck:Param + clone(parent_tidptr) + fun:clone + fun:clone +} + +{ + <clone on Wim's Debian> + Memcheck:Param + clone(child_tidptr) + fun:clone + fun:clone +} + +{ + <clone on Wim's Debian> + Memcheck:Param + clone(tlsinfo) + fun:clone + fun:clone +} + +### glibc suppressions + +{ + <conditional jump on wim's debian 2/2/06> + Memcheck:Cond + obj:/lib/ld-2.3.*.so + fun:dl_open_worker + obj:/lib/ld-2.3.*.so + fun:_dl_open + fun:dlopen_doit + obj:/lib/ld-2.3.*.so + fun:_dlerror_run + fun:dlopen@@GLIBC_2.1 + fun:g_module_open + fun:gst_plugin_load_file +} + +# glibc does not deallocate thread-local storage + +{ + <tls> + Memcheck:Leak + fun:calloc + fun:_dl_allocate_tls + fun:pthread_create@@* +} + +# I get an extra stack entry on x86/dapper +{ + <tls> + Memcheck:Leak + fun:calloc + obj:/lib/ld-2.3.*.so + fun:_dl_allocate_tls + fun:pthread_create@@* +} + + +{ + <pthread strstr> + Memcheck:Cond + fun:strstr + fun:__pthread_initialize_minimal + obj:/lib/libpthread-*.so + obj:/lib/libpthread-*.so + fun:call_init + fun:_dl_init + obj:/lib/ld-*.so +} + +# a thread-related free problem in glibc from Edgard +{ + __libc_freeres_rw_acess + Memcheck:Addr4 + obj:* + obj:* + obj:* + obj:* + obj:* + fun:__libc_freeres +} + +{ + <a conditional jump on wim's debian> + Memcheck:Cond + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so +} + +# g_module_open-related problems +{ + <started showing up on fc4-quick> + Memcheck:Addr2 + fun:memcpy + fun:_dl_map_object_deps + fun:dl_open_worker + fun:_dl_catch_error + fun:_dl_open + fun:dlopen_doit + fun:_dl_catch_error + fun:_dlerror_run + fun:dlopen@@GLIBC_2.1 + fun:g_module_open + fun:gst_plugin_load_file + fun:gst_registry_scan_path_level + fun:gst_registry_scan_path_level + fun:gst_registry_scan_path_level + fun:init_post + fun:g_option_context_parse + fun:gst_init_check + fun:gst_init + fun:gst_check_init + fun:main +} + +{ + <started showing up on fc4-quick> + Memcheck:Addr4 + fun:memcpy + fun:_dl_map_object_deps + fun:dl_open_worker + fun:_dl_catch_error + fun:_dl_open + fun:dlopen_doit + fun:_dl_catch_error + fun:_dlerror_run + fun:dlopen@@GLIBC_2.1 + fun:g_module_open + fun:gst_plugin_load_file + fun:gst_registry_scan_path_level + fun:gst_registry_scan_path_level + fun:gst_registry_scan_path_level + fun:init_post + fun:g_option_context_parse + fun:gst_init_check + fun:gst_init + fun:gst_check_init + fun:main +} + +{ + <g_module_open on wim's debian> + Memcheck:Cond + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + fun:do_sym + fun:_dl_sym + fun:dlsym_doit + obj:/lib/ld-2.3.*.so + fun:_dlerror_run + fun:dlsym + fun:g_module_symbol + fun:g_module_open + fun:gst_plugin_load_file +} + +{ + <g_module_open on wim's debian> + Memcheck:Cond + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + fun:dl_open_worker + obj:/lib/ld-2.3.*.so + fun:_dl_open + fun:dlopen_doit + obj:/lib/ld-2.3.*.so + fun:_dlerror_run + fun:dlopen@@GLIBC_2.1 + fun:g_module_open + fun:gst_plugin_load_file +} +{ + <g_module_open on wim's debian> + Memcheck:Cond + obj:/lib/ld-2.3.*.so + fun:dl_open_worker + obj:/lib/ld-2.3.*.so + fun:_dl_open + fun:dlopen_doit + obj:/lib/ld-2.3.*.so + fun:_dlerror_run + fun:dlopen@@GLIBC_2.1 + fun:g_module_open + fun:gst_plugin_load_file + fun:gst_plugin_load_by_name + fun:gst_plugin_feature_load +} + +{ + <leak on wim's debian in g_module_open> + Memcheck:Leak + fun:malloc + obj:/lib/ld-2.3.*.so + fun:dl_open_worker + obj:/lib/ld-2.3.*.so + fun:_dl_open + fun:dlopen_doit + obj:/lib/ld-2.3.*.so + fun:_dlerror_run + fun:dlopen@@GLIBC_2.1 + fun:g_module_open + fun:gst_plugin_load_file + fun:gst_plugin_load_by_name +} + +{ + <invalid read on wim's debian> + Memcheck:Addr4 + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + fun:dl_open_worker + obj:/lib/ld-2.3.*.so + fun:_dl_open + fun:dlopen_doit + obj:/lib/ld-2.3.*.so +} + +{ + <invalid read on wim's debian> + Memcheck:Addr4 + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + fun:dl_open_worker + obj:/lib/ld-2.3.*.so + fun:_dl_open + fun:dlopen_doit + obj:/lib/ld-2.3.*.so + fun:_dlerror_run +} + +{ + <invalid read on wim's debian - 2006-02-02> + Memcheck:Addr4 + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + fun:dl_open_worker + obj:/lib/ld-2.3.*.so + fun:_dl_open + fun:dlopen_doit + obj:/lib/ld-2.3.*.so + fun:_dlerror_run + fun:dlopen@@GLIBC_2.1 + fun:g_module_open +} + +{ + <invalid read on wim's debian - 2006-02-02> + Memcheck:Addr4 + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + fun:dl_open_worker + obj:/lib/ld-2.3.*.so + fun:_dl_open + fun:dlopen_doit + obj:/lib/ld-2.3.*.so + fun:_dlerror_run + fun:dlopen@@GLIBC_2.1 + fun:g_module_open +} + +{ + <invalid read on wim's debian - 2006-02-02> + Memcheck:Addr4 + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + fun:do_sym + fun:_dl_sym + fun:dlsym_doit + obj:/lib/ld-2.3.*.so + fun:_dlerror_run + fun:dlsym + fun:g_module_symbol + fun:g_module_open +} + +{ + <futex on Andy's 64-bit ubuntu> + Memcheck:Param + futex(uaddr2) + fun:pthread_once + obj:/lib/libc-2.3.*.so + obj:/lib/libc-2.3.*.so + fun:mbsnrtowcs + fun:vfprintf + fun:vsprintf + fun:sprintf + obj:/lib/libc-2.3.*.so + fun:tmpfile + fun:setup_pipe + fun:setup_messaging_with_key + fun:setup_messaging +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Addr4 + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlopen + fun:g_module_open +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Addr4 + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libc-2.7.so + fun:_dl_sym + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlsym + fun:g_module_symbol + fun:g_module_open +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Addr4 + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlopen + fun:g_module_open +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Addr4 + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlopen + fun:g_module_open +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Addr4 + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlopen + fun:g_module_open +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Addr4 + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libc-2.7.so + obj:/lib/ld-2.7.so + fun:__libc_dlopen_mode +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Addr4 + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libc-2.7.so + obj:/lib/ld-2.7.so + fun:__libc_dlopen_mode +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Addr4 + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libc-2.7.so + obj:/lib/ld-2.7.so + fun:__libc_dlopen_mode + obj:/lib/i686/cmov/libc-2.7.so + obj:/lib/i686/cmov/libc-2.7.so + obj:/lib/i686/cmov/libc-2.7.so + obj:/lib/i686/cmov/libc-2.7.so + obj:/lib/i686/cmov/libc-2.7.so + fun:iconv_open +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Addr4 + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libc-2.7.so + obj:/lib/ld-2.7.so + fun:__libc_dlopen_mode + obj:/lib/i686/cmov/libc-2.7.so + obj:/lib/i686/cmov/libc-2.7.so + obj:/lib/i686/cmov/libc-2.7.so + obj:/lib/i686/cmov/libc-2.7.so + obj:/lib/i686/cmov/libc-2.7.so + fun:iconv_open +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Addr4 + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlopen +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Addr4 + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlopen +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Cond + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlopen +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Cond + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlopen +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Addr4 + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlopen +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Addr4 + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlopen +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Cond + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlopen +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Cond + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlopen +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Addr4 + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlopen +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Addr4 + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlopen +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Cond + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlopen +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Cond + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlopen +} + +{ + <suppression for glibc 2.7 on debian> + Memcheck:Addr4 + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + obj:/lib/ld-2.7.so + obj:/lib/i686/cmov/libdl-2.7.so + fun:dlopen +} + +# suppression for a glibc bug: +# http://valgrind.org/docs/manual/faq.html#faq.exit_errors> +{ + <Workaround for a glibc bug> + Memcheck:Free + fun:free + obj:*libc-*.so + fun:__libc_freeres + fun:* + fun:_Exit +} + +# valgrind doesn't allow me to specify a suppression for Addr1, Addr2, Addr4 +# as Addr*, so 3 copies for that; and then 2 of each for that pesky memcpy +{ + <Invalid read of size 1, 2, 4 on thomas's FC4> + Memcheck:Addr1 + fun:_dl_signal_error + fun:_dl_map_object_deps + fun:dl_open_worker + fun:_dl_catch_error + fun:_dl_open + fun:dlopen_doit + fun:_dl_catch_error + fun:_dlerror_run + fun:dlopen@@GLIBC_2.1 + fun:g_module_open +} + +{ + <Invalid read of size 1, 2, 4 on thomas's FC4> + Memcheck:Addr2 + fun:_dl_signal_error + fun:_dl_map_object_deps + fun:dl_open_worker + fun:_dl_catch_error + fun:_dl_open + fun:dlopen_doit + fun:_dl_catch_error + fun:_dlerror_run + fun:dlopen@@GLIBC_2.1 + fun:g_module_open +} +{ + <Invalid read of size 1, 2, 4 on thomas's FC4> + Memcheck:Addr4 + fun:_dl_signal_error + fun:_dl_map_object_deps + fun:dl_open_worker + fun:_dl_catch_error + fun:_dl_open + fun:dlopen_doit + fun:_dl_catch_error + fun:_dlerror_run + fun:dlopen@@GLIBC_2.1 + fun:g_module_open +} + +{ + <Invalid read of size 1, 2, 4 on thomas's FC4> + Memcheck:Addr1 + fun:memcpy + fun:_dl_signal_error + fun:_dl_map_object_deps + fun:dl_open_worker + fun:_dl_catch_error + fun:_dl_open + fun:dlopen_doit + fun:_dl_catch_error + fun:_dlerror_run + fun:dlopen@@GLIBC_2.1 + fun:g_module_open +} + +{ + <Invalid read of size 1, 2, 4 on thomas's FC4> + Memcheck:Addr2 + fun:memcpy + fun:_dl_signal_error + fun:_dl_map_object_deps + fun:dl_open_worker + fun:_dl_catch_error + fun:_dl_open + fun:dlopen_doit + fun:_dl_catch_error + fun:_dlerror_run + fun:dlopen@@GLIBC_2.1 + fun:g_module_open +} +{ + <Invalid read of size 1, 2, 4 on thomas's FC4> + Memcheck:Addr4 + fun:memcpy + fun:_dl_signal_error + fun:_dl_map_object_deps + fun:dl_open_worker + fun:_dl_catch_error + fun:_dl_open + fun:dlopen_doit + fun:_dl_catch_error + fun:_dlerror_run + fun:dlopen@@GLIBC_2.1 + fun:g_module_open +} + +{ + <Addr8 on Andy's AMD64 ubuntu in dl_open> + Memcheck:Addr8 + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/libc-2.3.*.so + obj:/lib/ld-2.3.*.so + fun:_dl_open + obj:/lib/libdl-2.3.*.so + obj:/lib/ld-2.3.*.so +} + +{ + <Conditional jump on Andy's AMD64 ubuntu> + Memcheck:Cond + obj:/lib/ld-2.3.*.so + obj:/lib/libc-2.3.*.so + obj:/lib/ld-2.3.*.so + fun:_dl_open + obj:/lib/libdl-2.3.*.so + obj:/lib/ld-2.3.*.so + obj:/lib/libdl-2.3.*.so + fun:dlopen + fun:g_module_open + fun:gst_plugin_load_file + fun:gst_plugin_load_by_name + fun:gst_plugin_feature_load +} + +{ + <Mike's x86 dapper> + Memcheck:Addr4 + obj:/lib/ld-2.3.6.so + obj:/lib/ld-2.3.6.so + obj:/lib/tls/i686/cmov/libc-2.3.6.so + obj:/lib/ld-2.3.6.so + fun:_dl_open + obj:/lib/tls/i686/cmov/libdl-2.3.6.so + obj:/lib/ld-2.3.6.so + obj:/lib/tls/i686/cmov/libdl-2.3.6.so + fun:dlopen +} + +{ + <Mike's x86 dapper> + Memcheck:Cond + obj:/lib/ld-2.3.6.so + obj:/lib/tls/i686/cmov/libc-2.3.6.so + obj:/lib/ld-2.3.6.so + fun:_dl_open + obj:/lib/tls/i686/cmov/libdl-2.3.6.so + obj:/lib/ld-2.3.6.so + obj:/lib/tls/i686/cmov/libdl-2.3.6.so + fun:dlopen +} + +{ + <Another dapper one> + Memcheck:Cond + obj:/lib/ld-2.3.6.so + obj:/lib/ld-2.3.6.so + obj:/lib/ld-2.3.6.so + obj:/lib/tls/i686/cmov/libc-2.3.6.so + obj:/lib/ld-2.3.6.so + fun:_dl_open + obj:/lib/tls/i686/cmov/libdl-2.3.6.so + obj:/lib/ld-2.3.6.so + obj:/lib/tls/i686/cmov/libdl-2.3.6.so + fun:dlopen +} + +### glib suppressions +{ + <g_parse_debug_string> + Memcheck:Cond + fun:g_parse_debug_string + obj:/usr/lib*/libglib-2.0.so.* + fun:g_slice_alloc + fun:g_slice_alloc0 +} + +{ + <g_type_init malloc> + Memcheck:Leak + fun:malloc + fun:g_malloc + fun:g_strdup + fun:g_quark_from_string + obj:* + obj:* + fun:g_type_register_fundamental + obj:* + fun:g_type_init_with_debug_flags + fun:g_type_init + fun:init_pre +} + +{ + <g_type_init calloc> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + obj:* + obj:* + fun:g_type_register_fundamental +} + +{ + <g_type_init calloc 2> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + obj:* + obj:* + fun:g_type_init_with_debug_flags +} + +{ + <g_type_init calloc 3, GSlice version> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:g_slice_alloc + obj:* + obj:* + fun:g_type_init_with_debug_flags +} + +#pthread memleaks + +{ + Thread creation leak + Memcheck:Leak + fun:calloc + fun:allocate_dtv + fun:_dl_allocate* + fun:_dl_allocate* + fun:__pthread_initialize_minimal +} + +{ + Thread management leak + Memcheck:Leak + fun:calloc + fun:allocate_dtv + fun:_dl_allocate* + fun:_dl_allocate* + fun:__pthread_* +} + +{ + Thread management leak 2 + Memcheck:Leak + fun:memalign + fun:_dl_allocate* + fun:_dl_allocate* + fun:__pthread_* +} + +{ + pthread_create Syscall param write(buf) points to uninitialised byte(s) + Memcheck:Param + write(buf) + fun:pthread_create@@GLIBC_2.2.5 + fun:g_thread_create* + +} + +# nss_parse_* memleak (used by g_option_context_parse) +{ + nss_parse_* memleak + Memcheck:Leak + fun:malloc + fun:nss_parse_service_list + fun:__nss_database_lookup +} + +# liboil suppressions +{ + <liboil cpu_fault_check_try> + Memcheck:Value8 + obj:/usr/lib/liboil-0.3.so.0.1.0 + obj:/usr/lib/liboil-0.3.so.0.1.0 + obj:/usr/lib/liboil-0.3.so.0.1.0 + fun:oil_cpu_fault_check_try + fun:oil_test_check_impl + fun:oil_class_optimize + fun:oil_optimize_all + fun:oil_init +} + +{ + <annoying read error inside dlopen stuff on Ubuntu Dapper x86_64> + Memcheck:Addr8 + obj:/lib/ld-2.3.6.so +} + +{ + <Ubuntu Dapper x86_64> + Memcheck:Param + futex(uaddr2) + fun:pthread_once + obj:/lib/libc-2.3.6.so + obj:/lib/libc-2.3.6.so + fun:setlocale + fun:init_pre + fun:g_option_context_parse + fun:gst_init_check + fun:gst_init + fun:gst_check_init + fun:main +} + +{ + <Ubuntu Dapper x86_64 dlopen stuff again> + Memcheck:Cond + obj:/lib/ld-2.3.6.so + obj:/lib/ld-2.3.6.so + fun:_dl_open + obj:/lib/libdl-2.3.6.so + obj:/lib/ld-2.3.6.so + obj:/lib/libdl-2.3.6.so + fun:dlopen + fun:g_module_open + fun:gst_plugin_load_file +} +# this exists in a bunch of different variations, hence the short tail/trace +{ + <dlopen invalid read of size 4 suppression on tpm's Ubuntu edgy/x86> + Memcheck:Addr4 + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so +} +{ + <and the same for 64bit systems> + Memcheck:Addr8 + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so +} + +# More edgy suppressions (Mike) +{ + <dlopen Condition jump suppressions for Ubuntu Edgy/x86> + Memcheck:Cond + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so + fun:dlopen_doit + obj:/lib/ld-2.4.so + fun:_dlerror_run + fun:dlopen@@GLIBC_2.1 +} + +{ + <dlopen Condition jump suppressions for Ubuntu Edgy/x86> + Memcheck:Cond + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so + fun:dlopen_doit + obj:/lib/ld-2.4.so + fun:_dlerror_run + fun:dlopen@@GLIBC_2.1 +} + +{ + <dlopen Condition jump suppressions for Ubuntu Edgy/x86> + Memcheck:Cond + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so + fun:do_sym + fun:_dl_sym +} + +# This one's overly general, but there's zero other information in the stack +# trace - just these five lines! +{ + <dlopen Condition jump suppressions for Ubuntu Edgy/x86> + Memcheck:Cond + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so +} + +{ + <tls leaks on Edgy/x86> + Memcheck:Leak + fun:calloc + obj:/lib/ld-2.4.so + fun:_dl_allocate_tls + fun:pthread_create@@GLIBC_2.1 +} + +# TLS leaks for feisty/x86 +{ + <tls leaks on Feisty/x86> + Memcheck:Leak + fun:calloc + fun:allocate_dtv + fun:_dl_allocate_tls + fun:pthread_create@@GLIBC_2.1 +} + +{ + <libcdio 0.76 leak> + Memcheck:Leak + fun:calloc + obj:/usr/lib/libcdio.so.6.0.1 + fun:cdio_open_am_linux + obj:/usr/lib/libcdio.so.6.0.1 + fun:cdio_open_am +} + +{ + <Addr8 on Jan's AMD64 ubuntu Feisty in dl_open> + Memcheck:Addr8 + obj:/lib/ld-2.5.so +} + +{ + <First of many Alsa errors> + Memcheck:Cond + fun:snd_pcm_direct_shm_create_or_connect + fun:snd_pcm_dsnoop_open + fun:_snd_pcm_dsnoop_open + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_pcm_open_slave + fun:_snd_pcm_plug_open + obj:/*lib/libasound.so.2.0.0 + fun:snd_pcm_open_slave + fun:_snd_pcm_asym_open + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 +} + +{ + <alsa error> + Memcheck:Cond + fun:snd_pcm_hw_param_set_near + fun:set_hwparams +} + +{ + <alsa error> + Memcheck:Cond + fun:_snd_pcm_hw_param_set_min + fun:snd_pcm_hw_param_set_min + fun:snd_pcm_hw_param_set_near + fun:set_hwparams +} + +{ + <alsa error> + Memcheck:Cond + fun:_snd_pcm_hw_param_set_min + fun:snd_pcm_hw_param_set_min + fun:snd_pcm_hw_param_set_near + fun:set_hwparams +} + +{ + <alsa error> + Memcheck:Cond + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_pcm_hw_param_set_near + fun:set_hwparams +} +{ + <alsa error> + Memcheck:Cond + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_pcm_close + obj:/*lib/libasound.so.2.0.0 +} +{ + <alsa error> + Memcheck:Cond + fun:snd_pcm_direct_shm_create_or_connect + fun:snd_pcm_dmix_open + fun:_snd_pcm_dmix_open + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_pcm_open_slave + fun:_snd_pcm_softvol_open + obj:/*lib/libasound.so.2.0.0 + fun:snd_pcm_open_slave + fun:_snd_pcm_plug_open + obj:/*lib/libasound.so.2.0.0 + fun:snd_pcm_open_slave + fun:_snd_pcm_asym_open + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 +} +{ + <alsa error> + Memcheck:Leak + fun:malloc + fun:strdup + fun:snd_dlobj_cache_add + obj:/*lib/libasound.so.2.0.0 + fun:snd_pcm_open_slave + fun:snd_pcm_dsnoop_open + fun:_snd_pcm_dsnoop_open + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_pcm_open_slave + fun:_snd_pcm_plug_open + obj:/*lib/libasound.so.2.0.0 + fun:snd_pcm_open_slave + fun:_snd_pcm_asym_open + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 +} +# Catch about 15 variations on inserting info into an ALSA +# internal cache +{ + <alsa error> + Memcheck:Leak + fun:malloc + fun:snd_dlobj_cache_add + obj:/*lib/libasound.so.2.0.0 +} +{ + <this catches a bunch of very similar errors related to parsing the configs> + Memcheck:Leak + fun:malloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load +} +{ + <alsa error> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_searcha_hooks +} +{ + <alsa error - same as above with 6 libasound> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_searcha_hooks +} +{ + <alsa error - same as above with 7 libasound> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_searcha_hooks +} +{ + <alsa error - same as above with 10 libasound> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_searcha_hooks +} +{ + <alsa error - same as above with 11 libasound> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_searcha_hooks +} +{ + <alsa error> + Memcheck:Leak + fun:malloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load + fun:snd_config_hook_load_for_all_cards + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_searcha_hooks + fun:snd_config_search_alias_hooks + fun:snd_config_search_definition +} +{ + <alsa error - same as above, but using calloc> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load + fun:snd_config_hook_load_for_all_cards + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_searcha_hooks + fun:snd_config_search_alias_hooks + fun:snd_config_search_definition +} +{ + <alsa error - same as above, but with only 9 libasounds> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_searcha_hooks + fun:snd_config_search_alias_hooks + fun:snd_config_search_definition +} +{ + <alsa error> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_update_r + fun:snd_config_update +} +{ + <alsa error - same as above, with 7 libasound repeats> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_update_r + fun:snd_config_update +} +{ + <alsa error - same as above, with 6 libasound repeats> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_update_r + fun:snd_config_update +} +{ + <alsa error> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_update_r + fun:snd_config_update +} +{ + <alsa error - same as above, with 6 libasound repeats> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_update_r + fun:snd_config_update +} +{ + <alsa error - same as above, with 7 libasound repeats> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_update_r + fun:snd_config_update +} +{ + <alsa error - same as above, with 8 libasound repeats> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_update_r + fun:snd_config_update +} +{ + <alsa error - same as above, with 9 libasound repeats> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_update_r + fun:snd_config_update +} +{ + <alsa error - same as above, with 10 libasound repeats> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_update_r + fun:snd_config_update +} +{ + <alsa error - same as above, with 11 libasound repeats> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_update_r + fun:snd_config_update +} +{ + <alsa error> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_searcha_hooks + fun:snd_config_search_alias_hooks + fun:snd_config_search_definition + obj:/*lib/libasound.so.2.0.0 +} +{ + <alsa error> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_searcha_hooks + fun:snd_config_search_alias_hooks + fun:snd_config_search_definition + obj:/*lib/libasound.so.2.0.0 +} +{ + <alsa error> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load + fun:snd_config_hook_load_for_all_cards + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_searcha_hooks + fun:snd_config_search_alias_hooks + fun:snd_config_search_definition + obj:/*lib/libasound.so.2.0.0 +} +{ + <alsa error - same as above, but with 8 libasound in the stack> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load + fun:snd_config_hook_load_for_all_cards + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_searcha_hooks + fun:snd_config_search_alias_hooks + fun:snd_config_search_definition + obj:/*lib/libasound.so.2.0.0 +} +{ + <alsa error - same as above, but with 7 libasound in the stack> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load + fun:snd_config_hook_load_for_all_cards + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_searcha_hooks + fun:snd_config_search_alias_hooks + fun:snd_config_search_definition + obj:/*lib/libasound.so.2.0.0 +} +{ + <alsa error - same as above, but with 6 libasound in the stack> + Memcheck:Leak + fun:calloc + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_hook_load + fun:snd_config_hook_load_for_all_cards + obj:/*lib/libasound.so.2.0.0 + fun:snd_config_searcha_hooks + fun:snd_config_search_alias_hooks + fun:snd_config_search_definition + obj:/*lib/libasound.so.2.0.0 +} +{ + <nss lookup within ALSA> + Memcheck:Leak + fun:malloc + obj:/lib/libc*.so + fun:__nss_database_lookup + obj:* + obj:* + fun:getgrnam_r + fun:getgrnam + fun:snd_pcm_direct_parse_open_conf +} + +{ + <libxcb leak on Ubuntu Feisty> + Memcheck:Leak + fun:calloc + fun:_XCBInitDisplayLock + fun:XOpenDisplay +} + +# GConf internal initialisations related to getting the default client. +{ + <Orbit something or other> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:ORBit_alloc_tcval + obj:/usr/lib/libORBit-2.so.* + fun:ORBit_demarshal_IOR + fun:ORBit_demarshal_object + fun:CORBA_ORB_string_to_object + obj:/usr/lib/libgconf-2.so.* + fun:gconf_get_current_lock_holder + fun:gconf_activate_server + obj:/usr/lib/libgconf-2.so.* + obj:/usr/lib/libgconf-2.so.* + fun:gconf_engine_get_default +} +{ + <gconf internal leak> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:ORBit_alloc_tcval + obj:/usr/lib/libORBit-2.so.* + fun:PortableServer_POA_servant_to_reference + obj:/usr/lib/libgconf-2.so.* + obj:/usr/lib/libgconf-2.so.* + obj:/usr/lib/libgconf-2.so.* + fun:gconf_engine_get_default +} +{ + <gconf internal leak> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:ORBit_alloc_tcval + obj:/usr/lib/libORBit-2.so.* + fun:ORBit_demarshal_IOR + fun:ORBit_demarshal_object + fun:CORBA_ORB_string_to_object + obj:/usr/lib/libgconf-2.so.* + fun:gconf_get_current_lock_holder + fun:gconf_activate_server + obj:/usr/lib/libgconf-2.so.* + obj:/usr/lib/libgconf-2.so.* + fun:gconf_engine_get_default +} +{ + <gconf internal initialisation> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:ORBit_alloc* + obj:/usr/lib/libORBit-2.so.* + fun:ORBit_demarshal_IOR + fun:ORBit_demarshal_object + fun:ORBit_demarshal_value + obj:/usr/lib/libORBit-2.so.* + fun:ORBit_small_invoke_stub + fun:ConfigServer_get_default_database + obj:/usr/lib/libgconf-2.so.* + fun:gconf_engine_get_default +} +{ + <gconf internal init> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:ORBit_alloc* + obj:/usr/lib/libORBit-2.so.* + fun:IOP_generate_profiles + fun:ORBit_marshal_object + fun:ORBit_marshal_value + obj:/usr/lib/libORBit-2.so.* + fun:ORBit_small_invoke_stub + fun:ConfigServer_add_client + obj:/usr/lib/libgconf-2.so.* + obj:/usr/lib/libgconf-2.so.* + fun:gconf_engine_get_default +} +{ + <gconf internal init> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:ORBit_alloc_by_tc + obj:/usr/lib/libORBit-2.so.* + fun:PortableServer_POA_servant_to_reference + obj:/usr/lib/libgconf-2.so.* + obj:/usr/lib/libgconf-2.so.* + obj:/usr/lib/libgconf-2.so.* + fun:gconf_engine_get_default +} +{ + <gconf internal init> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:ORBit_alloc_by_tc + obj:/usr/lib/libORBit-2.so.* + fun:ORBit_demarshal_IOR + fun:ORBit_demarshal_object + fun:CORBA_ORB_string_to_object + obj:/usr/lib/libgconf-2.so.* + fun:gconf_get_current_lock_holder + fun:gconf_activate_server + obj:/usr/lib/libgconf-2.so.* + obj:/usr/lib/libgconf-2.so.* + fun:gconf_engine_get_default +} + +# Some libORBit/bonobo initialisation stuff +{ + <bonobo init> + Memcheck:Leak + fun:malloc + fun:g_malloc + fun:ORBit_alloc_string + fun:CORBA_string_dup + fun:Bonobo_ActivationEnvValue_set + fun:bonobo_activation_init_activation_env + fun:bonobo_activation_orb_init + fun:bonobo_activation_init +} +{ + <bonobo init> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:ORBit_alloc* + fun:ORBit_small_alloc* + obj:/usr/lib/libORBit-2.so* + fun:PortableServer_POA_servant_to_reference + obj:/usr/lib/libbonobo-2.so* +} +{ + <bonobo init> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:ORBit_alloc_tcval + fun:ORBit_small_allocbuf + fun:ORBit_adaptor_setup + obj:/usr/lib/libORBit-2.so* + fun:ORBit_POA_setup_root + fun:ORBit_init_internals + fun:CORBA_ORB_init +} +{ + <bonobo init - more recent variant of above> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:ORBit_alloc_tcval + fun:ORBit_adaptor_setup + obj:/usr/lib/libORBit-2.so* + fun:ORBit_POA_setup_root + fun:ORBit_init_internals + fun:CORBA_ORB_init +} +{ + <bonobo init> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:ORBit_alloc* + fun:ORBit_small_allocbuf + fun:bonobo_activation_init_activation_env + fun:bonobo_activation_orb_init + fun:bonobo_activation_init +} + +# More GConf stuff from the FC5 buildbot, mostly variations on the +# above stack traces +{ + <incompletely initialised ORBit buffer> + Memcheck:Param + writev(vector[...]) + fun:writev + obj:/usr/lib/libORBit-2.so* + fun:link_connection_writev + fun:giop_send_buffer_write + obj:/usr/lib/libORBit-2.so* + fun:ORBit_small_invoke_stub + fun:ORBit_small_invoke_stub_n + fun:ORBit_c_stub_invoke + fun:ConfigServer_ping + fun:gconf_activate_server + obj:/usr/lib/libgconf-2.so* + obj:/usr/lib/libgconf-2.so* + fun:gconf_engine_get_default +} +{ + <gconf init> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:ORBit_alloc* + fun:ORBit_small_alloc* + obj:/usr/lib/libORBit-2.so* + fun:PortableServer_POA_servant_to_reference + obj:/usr/lib/libgconf-2.so* + obj:/usr/lib/libgconf-2.so* + obj:/usr/lib/libgconf-2.so* + fun:gconf_engine_get_default +} +{ + <gconf init> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:ORBit_alloc* + fun:ORBit_small_alloc + obj:/usr/lib/libORBit-2.so* + fun:ORBit_demarshal_IOR + fun:ORBit_demarshal_object + fun:CORBA_ORB_string_to_object + obj:/usr/lib/libgconf-2.so* + fun:gconf_get_current_lock_holder + fun:gconf_activate_server + obj:/usr/lib/libgconf-2.so* + obj:/usr/lib/libgconf-2.so* + fun:gconf_engine_get_default +} +{ + <gconf init> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:ORBit_alloc* + fun:ORBit_small_alloc* + obj:/usr/lib/libORBit-2.so* + fun:ORBit_demarshal_IOR + fun:ORBit_demarshal_object + fun:CORBA_ORB_string_to_object + obj:/usr/lib/libgconf-2.so* + fun:gconf_get_current_lock_holder + fun:gconf_activate_server + obj:/usr/lib/libgconf-2.so* + obj:/usr/lib/libgconf-2.so* + fun:gconf_engine_get_default +} +{ + <bonobo init> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:ORBit_alloc* + fun:ORBit_small_alloc* + obj:/usr/lib/libORBit-2.so* + fun:ORBit_demarshal_IOR + fun:ORBit_demarshal_object + fun:ORBit_demarshal_value + obj:/usr/lib/libORBit-2.so* + fun:ORBit_small_invoke_stub + fun:ORBit_small_invoke_stub_n + fun:ORBit_c_stub_invoke + fun:ConfigServer_get_default_database + obj:/usr/lib/libgconf-2.so* + fun:gconf_engine_get_default +} +{ + <gconf init> + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:ORBit_alloc* + fun:ORBit_small_alloc* + obj:/usr/lib/libORBit-2.so* + fun:ORBit_OAObject_object_to_objkey + fun:IOP_generate_profiles + fun:ORBit_marshal_object + fun:ORBit_marshal_value + obj:/usr/lib/libORBit-2.so* + fun:ORBit_small_invoke_stub + fun:ORBit_small_invoke_stub_n + fun:ORBit_c_stub_invoke + fun:ConfigServer_add_client + obj:/usr/lib/libgconf-2.so* + obj:/usr/lib/libgconf-2.so* + fun:gconf_engine_get_default +} +{ + <GLib caching the home dir> + Memcheck:Leak + fun:malloc + obj:*libc-*.so + fun:__nss_database_lookup + obj:* + obj:* + fun:getpwnam_r + obj:/usr/lib*/libglib-2.0.so.* + fun:g_get_home_dir +} +{ + <GLib caching the user name> + Memcheck:Leak + fun:malloc + obj:*libc-*.so + fun:__nss_database_lookup + obj:* + obj:* + fun:getpwnam_r + obj:/usr/lib*/libglib-2.0.so.* + fun:g_get_user_name +} +{ + <GLib caching the tmp dir> + Memcheck:Leak + fun:malloc + obj:*libc-*.so + fun:__nss_database_lookup + obj:* + obj:* + fun:getpwnam_r + obj:/usr/lib*/libglib-2.0.so.* + fun:g_get_tmp_dir +} + +{ + <GLib caching the host name> + Memcheck:Leak + fun:malloc + obj:*libc-*.so + fun:__nss_database_lookup + obj:* + obj:* + fun:getpwnam_r + obj:/usr/lib*/libglib-2.0.so.0.* + fun:g_get_host_name +} + + +## Some Fontconfig errors. +{ + <First time load of a font - feisty x86_64> + Memcheck:Leak + fun:malloc + fun:FcPatternObjectInsertElt + fun:FcPatternObjectAddWithBinding + fun:FcPatternAppend + fun:FcEndElement + obj:/usr/lib/libexpat.so.1.0.0 + obj:/usr/lib/libexpat.so.1.0.0 + obj:/usr/lib/libexpat.so.1.0.0 + obj:/usr/lib/libexpat.so.1.0.0 + fun:XML_ParseBuffer + fun:FcConfigParseAndLoad + fun:FcConfigParseAndLoad + fun:FcParseInclude + fun:FcEndElement + obj:/usr/lib/libexpat.so.1.0.0 + obj:/usr/lib/libexpat.so.1.0.0 + obj:/usr/lib/libexpat.so.1.0.0 + obj:/usr/lib/libexpat.so.1.0.0 + fun:XML_ParseBuffer + fun:FcConfigParseAndLoad +} +{ + <First time load of a font - feisty x86_64> + Memcheck:Leak + fun:malloc + fun:FcStrCopy + fun:FcEndElement + obj:/usr/lib/libexpat.so.1.0.0 + obj:/usr/lib/libexpat.so.1.0.0 + obj:/usr/lib/libexpat.so.1.0.0 + obj:/usr/lib/libexpat.so.1.0.0 + fun:XML_ParseBuffer + fun:FcConfigParseAndLoad + fun:FcConfigParseAndLoad + fun:FcParseInclude + fun:FcEndElement + obj:/usr/lib/libexpat.so.1.0.0 + obj:/usr/lib/libexpat.so.1.0.0 + obj:/usr/lib/libexpat.so.1.0.0 + obj:/usr/lib/libexpat.so.1.0.0 + fun:XML_ParseBuffer + fun:FcConfigParseAndLoad + fun:FcInitLoadConfig + fun:FcInitLoadConfigAndFonts +} + diff --git a/common/gstdoc-scangobj b/common/gstdoc-scangobj new file mode 100755 index 0000000..90ba889 --- /dev/null +++ b/common/gstdoc-scangobj @@ -0,0 +1,1607 @@ +#!/usr/bin/perl -w +# -*- cperl -*- +# +# gtk-doc - GTK DocBook documentation generator. +# Copyright (C) 1998 Damon Chaplin +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +# +# This gets information about object heirarchies and signals +# by compiling a small C program. CFLAGS and LDFLAGS must be +# set appropriately before running this script. +# +# NOTE: the lookup_signal_arg_names() function contains the argument names of +# standard GTK signal handlers. This may need to be updated for new +# GTK signals or Gnome widget signals. + +use Getopt::Long; + +unshift @INC, '/usr/share/gtk-doc/data'; +require "gtkdoc-common.pl"; + +# Options + +# name of documentation module +my $MODULE; +my $OUTPUT_DIR; +my $PRINT_VERSION; +my $PRINT_HELP; +my $TYPE_INIT_FUNC="g_type_init ()"; + +# --nogtkinit is deprecated, as it is the default now anyway. +%optctl = (module => \$MODULE, + source => \$SOURCE, + types => \$TYPES_FILE, + nogtkinit => \$NO_GTK_INIT, + 'type-init-func' => \$TYPE_INIT_FUNC, + 'output-dir' => \$OUTPUT_DIR, + 'version' => \$PRINT_VERSION, + 'help' => \$PRINT_HELP); + +GetOptions(\%optctl, "module=s", "source=s", "types:s", "output-dir:s", "nogtkinit", "type-init-func:s", "version", "help"); + +if ($NO_GTK_INIT) { + # Do nothing. This just avoids a warning. +} + +if ($PRINT_VERSION) { + print "1.5\n"; + exit 0; +} + +if (!$MODULE) { + $PRINT_HELP = 1; +} + +if ($PRINT_HELP) { + print "gstdoc-scangobj version 1.5\n"; + print "\n--module=MODULE_NAME Name of the doc module being parsed"; + print "\n--source=SOURCE_NAME Name of the source module for plugins"; + print "\n--types=FILE The name of the file to store the types in"; + print "\n--type-init-func=FUNC The init function to call instead of g_type_init ()"; + print "\n--output-dir=DIRNAME The directory where the results are stored"; + print "\n--version Print the version of this program"; + print "\n--help Print this help\n"; + exit 0; +} + +$OUTPUT_DIR = $OUTPUT_DIR ? $OUTPUT_DIR : "."; + +# THOMAS: dynamic types; only use types file for headers + $TYPES_FILE = $TYPES_FILE ? $TYPES_FILE : "$OUTPUT_DIR/$MODULE.types"; + +open (TYPES, $TYPES_FILE) || die "Cannot open $TYPES_FILE: $!\n"; +open (OUTPUT, ">$MODULE-scan.c") || die "Cannot open $MODULE-scan.c: $!\n"; + +my $old_signals_filename = "$OUTPUT_DIR/$MODULE.signals"; +my $new_signals_filename = "$OUTPUT_DIR/$MODULE.signals.new"; +my $old_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy"; +my $new_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy.new"; +my $old_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces"; +my $new_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces.new"; +my $old_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites"; +my $new_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites.new"; +my $old_args_filename = "$OUTPUT_DIR/$MODULE.args"; +my $new_args_filename = "$OUTPUT_DIR/$MODULE.args.new"; + +# write a C program to scan the types + +$includes = ""; +#@types = (); + +for (<TYPES>) { + if (/^#include/) { + $includes .= $_; +# } elsif (/^%/) { +# next; +# } elsif (/^\s*$/) { +# next; +# } else { +# chomp; +# push @types, $_; + } +} + +#$ntypes = @types + 1; + +print OUTPUT <<EOT; +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> + +$includes +#ifdef GTK_IS_WIDGET_CLASS +#include <gtk/gtkversion.h> +#endif +GType *object_types = NULL; + +static GType * +get_object_types (void) +{ + GList *plugins = NULL; + GList *factories = NULL; + GList *l; + GstElementFactory *factory = NULL; + + gint i = 0; + + /* get a list of features from plugins in our source module */ + plugins = gst_registry_get_plugin_list (gst_registry_get_default()); + + while (plugins) { + GList *features; + GstPlugin *plugin; + const gchar *source; + + plugin = (GstPlugin *) (plugins->data); + plugins = g_list_next (plugins); + source = gst_plugin_get_source (plugin); + /*g_print ("plugin: %s source: %s\\n", plugin->desc.name, source);*/ + if (!source || strcmp (source, "$SOURCE") != 0) { + continue; + } + g_print ("plugin: %s source: %s\\n", plugin->desc.name, source); + + features = + gst_registry_get_feature_list_by_plugin (gst_registry_get_default (), + plugin->desc.name); + while (features) { + GstPluginFeature *feature; + feature = GST_PLUGIN_FEATURE (features->data); + feature = gst_plugin_feature_load (feature); + if (!feature) { + g_warning ("Could not load plugin feature %s", + gst_plugin_feature_get_name (feature)); + } + + if (GST_IS_ELEMENT_FACTORY (feature)) { + factory = GST_ELEMENT_FACTORY (feature); + factories = g_list_prepend (factories, factory); + } + features = g_list_next (features); + } + } + + g_message ("number of element factories: %d", g_list_length (factories)); + + /* allocate the object_types array to hold them */ + object_types = g_new0 (GType, g_list_length (factories)+1); + + l = factories; + i = 0; + + /* fill it */ + while (l) { + GType type; + factory = GST_ELEMENT_FACTORY (l->data); + type = gst_element_factory_get_element_type (factory); + g_message ("adding type %p for factory %s", (void *) type, gst_element_factory_get_longname (factory)); + object_types[i] = type; + i++; + l = g_list_next (l); + } + object_types[i] = 0; +EOT + +print OUTPUT <<EOT; + + /* Need to make sure all the types are loaded in and initialize + * their signals and properties. + */ + for (i=0; object_types[i]; i++) { + if (G_TYPE_IS_CLASSED (object_types[i])) + g_type_class_ref (object_types[i]); + else { + g_warning ("not reffing type: %s", g_type_name (object_types[i])); + } + } + + return object_types; +} + +/* + * This uses GObject type functions to output signal prototypes and the object + * hierarchy. + */ + +/* The output files */ +const gchar *signals_filename = "$new_signals_filename"; +const gchar *hierarchy_filename = "$new_hierarchy_filename"; +const gchar *interfaces_filename = "$new_interfaces_filename"; +const gchar *prerequisites_filename = "$new_prerequisites_filename"; +const gchar *args_filename = "$new_args_filename"; + + +static void output_signals (void); +static void output_object_signals (FILE *fp, + GType object_type); +static void output_object_signal (FILE *fp, + const gchar *object_class_name, + guint signal_id); +static const gchar * get_type_name (GType type, + gboolean * is_pointer); +static const gchar * get_gdk_event (const gchar * signal_name); +static const gchar ** lookup_signal_arg_names (const gchar * type, + const gchar * signal_name); + +static void output_object_hierarchy (void); +static void output_hierarchy (FILE *fp, + GType type, + guint level); + +static void output_object_interfaces (void); +static void output_interfaces (FILE *fp, + GType type); + +static void output_interface_prerequisites (void); +static void output_prerequisites (FILE *fp, + GType type); + +static void output_args (void); +static void output_object_args (FILE *fp, GType object_type); + +int +main (int argc, char *argv[]) +{ + /* Silence the compiler: */ + if (argv != argv) argc = argc; + + $TYPE_INIT_FUNC; + + get_object_types (); + + output_signals (); + output_object_hierarchy (); + output_object_interfaces (); + output_interface_prerequisites (); + output_args (); + + return 0; +} + + +static void +output_signals (void) +{ + FILE *fp; + gint i; + + fp = fopen (signals_filename, "w"); + if (fp == NULL) + { + g_warning ("Couldn't open output file: %s : %s", signals_filename, strerror(errno)); + return; + } + + for (i = 0; object_types[i]; i++) + output_object_signals (fp, object_types[i]); + + fclose (fp); +} + +static gint +compare_signals (const void *a, const void *b) +{ + const guint *signal_a = a; + const guint *signal_b = b; + + return strcmp (g_signal_name (*signal_a), g_signal_name (*signal_b)); +} + +/* This outputs all the signals of one object. */ +static void +output_object_signals (FILE *fp, GType object_type) +{ + const gchar *object_class_name; + guint *signals, n_signals; + guint sig; + + if (G_TYPE_IS_INSTANTIATABLE (object_type) || + G_TYPE_IS_INTERFACE (object_type)) + { + + object_class_name = g_type_name (object_type); + + signals = g_signal_list_ids (object_type, &n_signals); + qsort (signals, n_signals, sizeof (guint), compare_signals); + + for (sig = 0; sig < n_signals; sig++) + { + output_object_signal (fp, object_class_name, signals[sig]); + } + g_free (signals); + } +} + + +/* This outputs one signal. */ +static void +output_object_signal (FILE *fp, + const gchar *object_name, + guint signal_id) +{ + GSignalQuery query_info; + const gchar *type_name, *ret_type, *object_arg, *arg_name; + gchar *pos, *object_arg_lower; + gboolean is_pointer; + gchar ret_type_buffer[1024], buffer[1024]; + guint i, param; + const gchar **arg_names; + gint param_num, widget_num, event_num, callback_num; + gint *arg_num; + gchar signal_name[128]; + gchar flags[16]; + + /* g_print ("Object: %s Signal: %u\\n", object_name, signal_id);*/ + + param_num = 1; + widget_num = event_num = callback_num = 0; + + g_signal_query (signal_id, &query_info); + + /* Output the return type and function name. */ + ret_type = get_type_name (query_info.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer); + sprintf (ret_type_buffer, "%s%s", ret_type, is_pointer ? "*" : ""); + + /* Output the signal object type and the argument name. We assume the + type is a pointer - I think that is OK. We remove "Gtk" or "Gnome" and + convert to lower case for the argument name. */ + pos = buffer; + sprintf (pos, "%s ", object_name); + pos += strlen (pos); + + if (!strncmp (object_name, "Gtk", 3)) + object_arg = object_name + 3; + else if (!strncmp (object_name, "Gnome", 5)) + object_arg = object_name + 5; + else + object_arg = object_name; + + object_arg_lower = g_ascii_strdown (object_arg, -1); + sprintf (pos, "*%s\\n", object_arg_lower); + pos += strlen (pos); + if (!strncmp (object_arg_lower, "widget", 6)) + widget_num = 2; + g_free(object_arg_lower); + + /* Convert signal name to use underscores rather than dashes '-'. */ + strcpy (signal_name, query_info.signal_name); + for (i = 0; signal_name[i]; i++) + { + if (signal_name[i] == '-') + signal_name[i] = '_'; + } + + /* Output the signal parameters. */ + arg_names = lookup_signal_arg_names (object_name, signal_name); + + for (param = 0; param < query_info.n_params; param++) + { + if (arg_names) + { + sprintf (pos, "%s\\n", arg_names[param]); + pos += strlen (pos); + } + else + { + type_name = get_type_name (query_info.param_types[param] & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer); + + /* Most arguments to the callback are called "arg1", "arg2", etc. + GdkWidgets are called "widget", "widget2", ... + GdkEvents are called "event", "event2", ... + GtkCallbacks are called "callback", "callback2", ... */ + if (!strcmp (type_name, "GtkWidget")) + { + arg_name = "widget"; + arg_num = &widget_num; + } + else if (!strcmp (type_name, "GdkEvent")) + { + type_name = get_gdk_event (signal_name); + arg_name = "event"; + arg_num = &event_num; + is_pointer = TRUE; + } + else if (!strcmp (type_name, "GtkCallback") + || !strcmp (type_name, "GtkCCallback")) + { + arg_name = "callback"; + arg_num = &callback_num; + } + else + { + arg_name = "arg"; + arg_num = ¶m_num; + } + sprintf (pos, "%s ", type_name); + pos += strlen (pos); + + if (!arg_num || *arg_num == 0) + sprintf (pos, "%s%s\\n", is_pointer ? "*" : " ", arg_name); + else + sprintf (pos, "%s%s%i\\n", is_pointer ? "*" : " ", arg_name, + *arg_num); + pos += strlen (pos); + + if (arg_num) + { + if (*arg_num == 0) + *arg_num = 2; + else + *arg_num += 1; + } + } + } + + pos = flags; + /* We use one-character flags for simplicity. */ + if (query_info.signal_flags & G_SIGNAL_RUN_FIRST) + *pos++ = 'f'; + if (query_info.signal_flags & G_SIGNAL_RUN_LAST) + *pos++ = 'l'; + if (query_info.signal_flags & G_SIGNAL_RUN_CLEANUP) + *pos++ = 'c'; + if (query_info.signal_flags & G_SIGNAL_NO_RECURSE) + *pos++ = 'r'; + if (query_info.signal_flags & G_SIGNAL_DETAILED) + *pos++ = 'd'; + if (query_info.signal_flags & G_SIGNAL_ACTION) + *pos++ = 'a'; + if (query_info.signal_flags & G_SIGNAL_NO_HOOKS) + *pos++ = 'h'; + *pos = 0; + + fprintf (fp, + "<SIGNAL>\\n<NAME>%s::%s</NAME>\\n<RETURNS>%s</RETURNS>\\n<FLAGS>%s</FLAGS>\\n%s</SIGNAL>\\n\\n", + object_name, query_info.signal_name, ret_type_buffer, flags, buffer); +} + + +/* Returns the type name to use for a signal argument or return value, given + the GtkType from the signal info. It also sets is_pointer to TRUE if the + argument needs a '*' since it is a pointer. */ +static const gchar * +get_type_name (GType type, gboolean * is_pointer) +{ + const gchar *type_name; + + *is_pointer = FALSE; + type_name = g_type_name (type); + + switch (type) { + case G_TYPE_NONE: + case G_TYPE_CHAR: + case G_TYPE_UCHAR: + case G_TYPE_BOOLEAN: + case G_TYPE_INT: + case G_TYPE_UINT: + case G_TYPE_LONG: + case G_TYPE_ULONG: + case G_TYPE_FLOAT: + case G_TYPE_DOUBLE: + case G_TYPE_POINTER: + /* These all have normal C type names so they are OK. */ + return type_name; + + case G_TYPE_STRING: + /* A GtkString is really a gchar*. */ + *is_pointer = TRUE; + return "gchar"; + + case G_TYPE_ENUM: + case G_TYPE_FLAGS: + /* We use a gint for both of these. Hopefully a subtype with a decent + name will be registered and used instead, as GTK+ does itself. */ + return "gint"; + + case G_TYPE_BOXED: + /* The boxed type shouldn't be used itself, only subtypes. Though we + return 'gpointer' just in case. */ + return "gpointer"; + + case G_TYPE_PARAM: + /* A GParam is really a GParamSpec*. */ + *is_pointer = TRUE; + return "GParamSpec"; + + default: + break; + } + + /* For all GObject subclasses we can use the class name with a "*", + e.g. 'GtkWidget *'. */ + if (g_type_is_a (type, G_TYPE_OBJECT)) + *is_pointer = TRUE; + + if (G_TYPE_IS_CLASSED (type)) + *is_pointer = TRUE; + + /* All boxed subtypes will be pointers as well. */ + if (g_type_is_a (type, G_TYPE_BOXED)) + *is_pointer = TRUE; + + /* All pointer subtypes will be pointers as well. */ + if (g_type_is_a (type, G_TYPE_POINTER)) + *is_pointer = TRUE; + + /* But enums are not */ + if (g_type_is_a (type, G_TYPE_ENUM) || + g_type_is_a (type, G_TYPE_FLAGS)) + *is_pointer = FALSE; + + return type_name; +} + + +static const gchar * +get_gdk_event (const gchar * signal_name) +{ + static const gchar *GbGDKEvents[] = + { + "button_press_event", "GdkEventButton", + "button_release_event", "GdkEventButton", + "motion_notify_event", "GdkEventMotion", + "delete_event", "GdkEvent", + "destroy_event", "GdkEvent", + "expose_event", "GdkEventExpose", + "key_press_event", "GdkEventKey", + "key_release_event", "GdkEventKey", + "enter_notify_event", "GdkEventCrossing", + "leave_notify_event", "GdkEventCrossing", + "configure_event", "GdkEventConfigure", + "focus_in_event", "GdkEventFocus", + "focus_out_event", "GdkEventFocus", + "map_event", "GdkEvent", + "unmap_event", "GdkEvent", + "property_notify_event", "GdkEventProperty", + "selection_clear_event", "GdkEventSelection", + "selection_request_event", "GdkEventSelection", + "selection_notify_event", "GdkEventSelection", + "proximity_in_event", "GdkEventProximity", + "proximity_out_event", "GdkEventProximity", + "drag_begin_event", "GdkEventDragBegin", + "drag_request_event", "GdkEventDragRequest", + "drag_end_event", "GdkEventDragRequest", + "drop_enter_event", "GdkEventDropEnter", + "drop_leave_event", "GdkEventDropLeave", + "drop_data_available_event", "GdkEventDropDataAvailable", + "other_event", "GdkEventOther", + "client_event", "GdkEventClient", + "no_expose_event", "GdkEventNoExpose", + "visibility_notify_event", "GdkEventVisibility", + "window_state_event", "GdkEventWindowState", + "scroll_event", "GdkEventScroll", + NULL + }; + + gint i; + + for (i = 0; GbGDKEvents[i]; i += 2) + { + if (!strcmp (signal_name, GbGDKEvents[i])) + return GbGDKEvents[i + 1]; + } + return "GdkEvent"; +} + + +/* This returns argument names to use for some known GTK signals. + It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g. + 'select_row' and it returns a pointer to an array of argument types and + names. */ +static const gchar ** +lookup_signal_arg_names (const gchar * type, const gchar * signal_name) +{ + /* Each arg array starts with the object type name and the signal name, + and then signal arguments follow. */ + static const gchar *GbArgTable[][16] = + { + {"GtkCList", "select_row", + "gint row", + "gint column", + "GdkEventButton *event"}, + {"GtkCList", "unselect_row", + "gint row", + "gint column", + "GdkEventButton *event"}, + {"GtkCList", "click_column", + "gint column"}, + + {"GtkCList", "resize_column", + "gint column", + "gint width"}, + + {"GtkCList", "extend_selection", + "GtkScrollType scroll_type", + "gfloat position", + "gboolean auto_start_selection"}, + {"GtkCList", "scroll_vertical", + "GtkScrollType scroll_type", + "gfloat position"}, + {"GtkCList", "scroll_horizontal", + "GtkScrollType scroll_type", + "gfloat position"}, + + {"GtkCTree", "tree_select_row", + "GtkCTreeNode *node", + "gint column"}, + {"GtkCTree", "tree_unselect_row", + "GtkCTreeNode *node", + "gint column"}, + {"GtkCTree", "tree_expand", + "GtkCTreeNode *node"}, + {"GtkCTree", "tree_collapse", + "GtkCTreeNode *node"}, + {"GtkCTree", "tree_move", + "GtkCTreeNode *node", + "GtkCTreeNode *new_parent", + "GtkCTreeNode *new_sibling"}, + {"GtkCTree", "change_focus_row_expansion", + "GtkCTreeExpansionType expansion"}, + + {"GtkEditable", "insert_text", + "gchar *new_text", + "gint new_text_length", + "gint *position"}, + {"GtkEditable", "delete_text", + "gint start_pos", + "gint end_pos"}, + {"GtkEditable", "set_editable", + "gboolean is_editable"}, + {"GtkEditable", "move_cursor", + "gint x", + "gint y"}, + {"GtkEditable", "move_word", + "gint num_words"}, + {"GtkEditable", "move_page", + "gint x", + "gint y"}, + {"GtkEditable", "move_to_row", + "gint row"}, + {"GtkEditable", "move_to_column", + "gint column"}, + + {"GtkEditable", "kill_char", + "gint direction"}, + {"GtkEditable", "kill_word", + "gint direction"}, + {"GtkEditable", "kill_line", + "gint direction"}, + + + {"GtkInputDialog", "enable_device", + "GdkDevice *deviceid"}, + {"GtkInputDialog", "disable_device", + "GdkDevice *deviceid"}, + + {"GtkListItem", "extend_selection", + "GtkScrollType scroll_type", + "gfloat position", + "gboolean auto_start_selection"}, + {"GtkListItem", "scroll_vertical", + "GtkScrollType scroll_type", + "gfloat position"}, + {"GtkListItem", "scroll_horizontal", + "GtkScrollType scroll_type", + "gfloat position"}, + + {"GtkMenuShell", "move_current", + "GtkMenuDirectionType direction"}, + {"GtkMenuShell", "activate_current", + "gboolean force_hide"}, + + + {"GtkNotebook", "switch_page", + "GtkNotebookPage *page", + "guint page_num"}, + {"GtkStatusbar", "text_pushed", + "guint context_id", + "gchar *text"}, + {"GtkStatusbar", "text_popped", + "guint context_id", + "gchar *text"}, + {"GtkTipsQuery", "widget_entered", + "GtkWidget *widget", + "gchar *tip_text", + "gchar *tip_private"}, + {"GtkTipsQuery", "widget_selected", + "GtkWidget *widget", + "gchar *tip_text", + "gchar *tip_private", + "GdkEventButton *event"}, + {"GtkToolbar", "orientation_changed", + "GtkOrientation orientation"}, + {"GtkToolbar", "style_changed", + "GtkToolbarStyle style"}, + {"GtkWidget", "draw", + "GdkRectangle *area"}, + {"GtkWidget", "size_request", + "GtkRequisition *requisition"}, + {"GtkWidget", "size_allocate", + "GtkAllocation *allocation"}, + {"GtkWidget", "state_changed", + "GtkStateType state"}, + {"GtkWidget", "style_set", + "GtkStyle *previous_style"}, + + {"GtkWidget", "install_accelerator", + "gchar *signal_name", + "gchar key", + "gint modifiers"}, + + {"GtkWidget", "add_accelerator", + "guint accel_signal_id", + "GtkAccelGroup *accel_group", + "guint accel_key", + "GdkModifierType accel_mods", + "GtkAccelFlags accel_flags"}, + + {"GtkWidget", "parent_set", + "GtkObject *old_parent"}, + + {"GtkWidget", "remove_accelerator", + "GtkAccelGroup *accel_group", + "guint accel_key", + "GdkModifierType accel_mods"}, + {"GtkWidget", "debug_msg", + "gchar *message"}, + {"GtkWindow", "move_resize", + "gint *x", + "gint *y", + "gint width", + "gint height"}, + {"GtkWindow", "set_focus", + "GtkWidget *widget"}, + + {"GtkWidget", "selection_get", + "GtkSelectionData *data", + "guint info", + "guint time"}, + {"GtkWidget", "selection_received", + "GtkSelectionData *data", + "guint time"}, + + {"GtkWidget", "drag_begin", + "GdkDragContext *drag_context"}, + {"GtkWidget", "drag_end", + "GdkDragContext *drag_context"}, + {"GtkWidget", "drag_data_delete", + "GdkDragContext *drag_context"}, + {"GtkWidget", "drag_leave", + "GdkDragContext *drag_context", + "guint time"}, + {"GtkWidget", "drag_motion", + "GdkDragContext *drag_context", + "gint x", + "gint y", + "guint time"}, + {"GtkWidget", "drag_drop", + "GdkDragContext *drag_context", + "gint x", + "gint y", + "guint time"}, + {"GtkWidget", "drag_data_get", + "GdkDragContext *drag_context", + "GtkSelectionData *data", + "guint info", + "guint time"}, + {"GtkWidget", "drag_data_received", + "GdkDragContext *drag_context", + "gint x", + "gint y", + "GtkSelectionData *data", + "guint info", + "guint time"}, + + {NULL} + }; + + gint i; + + for (i = 0; GbArgTable[i][0]; i++) + { +#if 1 + if (!strcmp (type, GbArgTable[i][0]) + && !strcmp (signal_name, GbArgTable[i][1])) + return &GbArgTable[i][2]; +#endif + } + return NULL; +} + +/* This outputs the hierarchy of all objects which have been initialized, + i.e. by calling their XXX_get_type() initialization function. */ +static void +output_object_hierarchy (void) +{ + FILE *fp; + gint i; + + fp = fopen (hierarchy_filename, "w"); + if (fp == NULL) + { + g_warning ("Couldn't open output file: %s : %s", hierarchy_filename, strerror(errno)); + return; + } + output_hierarchy (fp, G_TYPE_OBJECT, 0); + output_hierarchy (fp, G_TYPE_INTERFACE, 0); + + for (i=0; object_types[i]; i++) { + if (!g_type_parent (object_types[i]) && + (object_types[i] != G_TYPE_NONE) && + (object_types[i] != G_TYPE_OBJECT) && + (object_types[i] != G_TYPE_INTERFACE) + ) { + g_warning ("printing hierarchy for root type: %s", + g_type_name (object_types[i])); + output_hierarchy (fp, object_types[i], 0); + } + } + /* for debugging + for (i=0; object_types[i]; i++) { + if(object_types[i] != G_TYPE_NONE) { + g_print ("type has not been added to hierarchy: %s\\n", + g_type_name (object_types[i])); + } + } + for debugging */ + + fclose (fp); +} + +/* This is called recursively to output the hierarchy of a widget. */ +static void +output_hierarchy (FILE *fp, + GType type, + guint level) +{ + guint i; + GType *children; + guint n_children; + + if (!type) + return; + + /* for debugging + for (i=0; object_types[i]; i++) { + if(object_types[i] == type) { + g_print ("added type to hierarchy (level %d): %s\\n", + level, g_type_name (type)); + object_types[i] = G_TYPE_NONE; + break; + } + } + for debugging */ + + for (i = 0; i < level; i++) + fprintf (fp, " "); + fprintf (fp, g_type_name (type)); + fprintf (fp, "\\n"); + + children = g_type_children (type, &n_children); + + for (i=0; i < n_children; i++) { + output_hierarchy (fp, children[i], level + 1); + } + + g_free (children); +} + +static void output_object_interfaces (void) +{ + guint i; + FILE *fp; + + fp = fopen (interfaces_filename, "w"); + if (fp == NULL) + { + g_warning ("Couldn't open output file: %s : %s", interfaces_filename, strerror(errno)); + return; + } + output_interfaces (fp, G_TYPE_OBJECT); + + for (i = 0; object_types[i]; i++) + { + if (!g_type_parent (object_types[i]) && + (object_types[i] != G_TYPE_OBJECT) && + G_TYPE_IS_INSTANTIATABLE (object_types[i])) + { + output_interfaces (fp, object_types[i]); + } + } + fclose (fp); +} + +static void +output_interfaces (FILE *fp, + GType type) +{ + guint i; + GType *children, *interfaces; + guint n_children, n_interfaces; + + if (!type) + return; + + interfaces = g_type_interfaces (type, &n_interfaces); + + if (n_interfaces > 0) + { + fprintf (fp, g_type_name (type)); + for (i=0; i < n_interfaces; i++) + fprintf (fp, " %s", g_type_name (interfaces[i])); + fprintf (fp, "\\n"); + } + g_free (interfaces); + + children = g_type_children (type, &n_children); + + for (i=0; i < n_children; i++) + output_interfaces (fp, children[i]); + + g_free (children); +} + +static void output_interface_prerequisites (void) +{ + FILE *fp; + + fp = fopen (prerequisites_filename, "w"); + if (fp == NULL) + { + g_warning ("Couldn't open output file: %s : %s", prerequisites_filename, strerror(errno)); + return; + } + output_prerequisites (fp, G_TYPE_INTERFACE); + fclose (fp); +} + +static void +output_prerequisites (FILE *fp, + GType type) +{ +#if GLIB_CHECK_VERSION(2,1,0) + guint i; + GType *children, *prerequisites; + guint n_children, n_prerequisites; + + if (!type) + return; + + prerequisites = g_type_interface_prerequisites (type, &n_prerequisites); + + if (n_prerequisites > 0) + { + fprintf (fp, g_type_name (type)); + for (i=0; i < n_prerequisites; i++) + fprintf (fp, " %s", g_type_name (prerequisites[i])); + fprintf (fp, "\\n"); + } + g_free (prerequisites); + + children = g_type_children (type, &n_children); + + for (i=0; i < n_children; i++) + output_prerequisites (fp, children[i]); + + g_free (children); +#endif +} + +static void +output_args (void) +{ + FILE *fp; + gint i; + + fp = fopen (args_filename, "w"); + if (fp == NULL) + { + g_warning ("Couldn't open output file: %s : %s", args_filename, strerror(errno)); + return; + } + + for (i = 0; object_types[i]; i++) { + output_object_args (fp, object_types[i]); + } + + fclose (fp); +} + +static gint +compare_param_specs (const void *a, const void *b) +{ + GParamSpec *spec_a = *(GParamSpec **)a; + GParamSpec *spec_b = *(GParamSpec **)b; + + return strcmp (g_param_spec_get_name (spec_a), g_param_spec_get_name (spec_b)); +} + +/* Its common to have unsigned properties restricted + * to the signed range. Therefore we make this look + * a bit nicer by spelling out the max constants. + */ + +/* Don't use "==" with floats, it might trigger a gcc warning. */ +#define GTKDOC_COMPARE_FLOAT(x, y) (x <= y && x >= y) + +static gchar* +describe_double_constant (gdouble value) +{ + gchar *desc; + + if (GTKDOC_COMPARE_FLOAT (value, G_MAXDOUBLE)) + desc = g_strdup ("G_MAXDOUBLE"); + else if (GTKDOC_COMPARE_FLOAT (value, G_MINDOUBLE)) + desc = g_strdup ("G_MINDOUBLE"); + else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXDOUBLE)) + desc = g_strdup ("-G_MAXDOUBLE"); + else if (GTKDOC_COMPARE_FLOAT (value, G_MAXFLOAT)) + desc = g_strdup ("G_MAXFLOAT"); + else if (GTKDOC_COMPARE_FLOAT (value, G_MINFLOAT)) + desc = g_strdup ("G_MINFLOAT"); + else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXFLOAT)) + desc = g_strdup ("-G_MAXFLOAT"); + else + desc = g_strdup_printf ("%lg", value); + + return desc; +} + +static gchar* +describe_signed_constant (gint64 value) +{ + gchar *desc; + + if (value == G_MAXINT) + desc = g_strdup ("G_MAXINT"); + else if (value == G_MININT) + desc = g_strdup ("G_MININT"); + else if (value == G_MAXUINT) + desc = g_strdup ("G_MAXUINT"); + else if (value == G_MAXLONG) + desc = g_strdup ("G_MAXLONG"); + else if (value == G_MINLONG) + desc = g_strdup ("G_MINLONG"); + else if (value == G_MAXULONG) + desc = g_strdup ("G_MAXULONG"); + else if (value == G_MAXINT64) + desc = g_strdup ("G_MAXINT64"); + else if (value == G_MININT64) + desc = g_strdup ("G_MININT64"); + else + desc = g_strdup_printf ("%" G_GINT64_FORMAT, value); + + return desc; +} + +static gchar* +describe_unsigned_constant (guint64 value) +{ + gchar *desc; + + if (value == G_MAXINT) + desc = g_strdup ("G_MAXINT"); + else if (value == G_MININT) + desc = g_strdup ("G_MININT"); + else if (value == G_MAXUINT) + desc = g_strdup ("G_MAXUINT"); + else if (value == G_MAXLONG) + desc = g_strdup ("G_MAXLONG"); + else if (value == G_MINLONG) + desc = g_strdup ("G_MINLONG"); + else if (value == G_MAXULONG) + desc = g_strdup ("G_MAXULONG"); + else if (value == G_MAXINT64) + desc = g_strdup ("G_MAXINT64"); + else if (value == G_MININT64) + desc = g_strdup ("G_MININT64"); + else if (value == G_MAXUINT64) + desc = g_strdup ("G_MAXUINT64"); + else + desc = g_strdup_printf ("%" G_GUINT64_FORMAT, value); + + return desc; +} + +static gchar* +describe_type (GParamSpec *spec) +{ + gchar *desc; + gchar *lower; + gchar *upper; + + if (G_IS_PARAM_SPEC_CHAR (spec)) + { + GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec); + + lower = describe_signed_constant (pspec->minimum); + upper = describe_signed_constant (pspec->maximum); + if (pspec->minimum == G_MININT8 && pspec->maximum == G_MAXINT8) + desc = g_strdup (""); + else if (pspec->minimum == G_MININT8) + desc = g_strdup_printf ("<= %s", upper); + else if (pspec->maximum == G_MAXINT8) + desc = g_strdup_printf (">= %s", lower); + else + desc = g_strdup_printf ("[%s,%s]", lower, upper); + g_free (lower); + g_free (upper); + } + else if (G_IS_PARAM_SPEC_UCHAR (spec)) + { + GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec); + + lower = describe_unsigned_constant (pspec->minimum); + upper = describe_unsigned_constant (pspec->maximum); + if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT8) + desc = g_strdup (""); + else if (pspec->minimum == 0) + desc = g_strdup_printf ("<= %s", upper); + else if (pspec->maximum == G_MAXUINT8) + desc = g_strdup_printf (">= %s", lower); + else + desc = g_strdup_printf ("[%s,%s]", lower, upper); + g_free (lower); + g_free (upper); + } + else if (G_IS_PARAM_SPEC_INT (spec)) + { + GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec); + + lower = describe_signed_constant (pspec->minimum); + upper = describe_signed_constant (pspec->maximum); + if (pspec->minimum == G_MININT && pspec->maximum == G_MAXINT) + desc = g_strdup (""); + else if (pspec->minimum == G_MININT) + desc = g_strdup_printf ("<= %s", upper); + else if (pspec->maximum == G_MAXINT) + desc = g_strdup_printf (">= %s", lower); + else + desc = g_strdup_printf ("[%s,%s]", lower, upper); + g_free (lower); + g_free (upper); + } + else if (G_IS_PARAM_SPEC_UINT (spec)) + { + GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec); + + lower = describe_unsigned_constant (pspec->minimum); + upper = describe_unsigned_constant (pspec->maximum); + if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT) + desc = g_strdup (""); + else if (pspec->minimum == 0) + desc = g_strdup_printf ("<= %s", upper); + else if (pspec->maximum == G_MAXUINT) + desc = g_strdup_printf (">= %s", lower); + else + desc = g_strdup_printf ("[%s,%s]", lower, upper); + g_free (lower); + g_free (upper); + } + else if (G_IS_PARAM_SPEC_LONG (spec)) + { + GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec); + + lower = describe_signed_constant (pspec->minimum); + upper = describe_signed_constant (pspec->maximum); + if (pspec->minimum == G_MINLONG && pspec->maximum == G_MAXLONG) + desc = g_strdup (""); + else if (pspec->minimum == G_MINLONG) + desc = g_strdup_printf ("<= %s", upper); + else if (pspec->maximum == G_MAXLONG) + desc = g_strdup_printf (">= %s", lower); + else + desc = g_strdup_printf ("[%s,%s]", lower, upper); + g_free (lower); + g_free (upper); + } + else if (G_IS_PARAM_SPEC_ULONG (spec)) + { + GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec); + gchar *upper; + + lower = describe_unsigned_constant (pspec->minimum); + upper = describe_unsigned_constant (pspec->maximum); + if (pspec->minimum == 0 && pspec->maximum == G_MAXULONG) + desc = g_strdup (""); + else if (pspec->minimum == 0) + desc = g_strdup_printf ("<= %s", upper); + else if (pspec->maximum == G_MAXULONG) + desc = g_strdup_printf (">= %s", lower); + else + desc = g_strdup_printf ("[%s,%s]", lower, upper); + g_free (lower); + g_free (upper); + } + else if (G_IS_PARAM_SPEC_INT64 (spec)) + { + GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec); + + lower = describe_signed_constant (pspec->minimum); + upper = describe_signed_constant (pspec->maximum); + if (pspec->minimum == G_MININT64 && pspec->maximum == G_MAXINT64) + desc = g_strdup (""); + else if (pspec->minimum == G_MININT64) + desc = g_strdup_printf ("<= %s", upper); + else if (pspec->maximum == G_MAXINT64) + desc = g_strdup_printf (">= %s", lower); + else + desc = g_strdup_printf ("[%s,%s]", lower, upper); + g_free (lower); + g_free (upper); + } + else if (G_IS_PARAM_SPEC_UINT64 (spec)) + { + GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec); + + lower = describe_unsigned_constant (pspec->minimum); + upper = describe_unsigned_constant (pspec->maximum); + if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT64) + desc = g_strdup (""); + else if (pspec->minimum == 0) + desc = g_strdup_printf ("<= %s", upper); + else if (pspec->maximum == G_MAXUINT64) + desc = g_strdup_printf (">= %s", lower); + else + desc = g_strdup_printf ("[%s,%s]", lower, upper); + g_free (lower); + g_free (upper); + } + else if (G_IS_PARAM_SPEC_FLOAT (spec)) + { + GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec); + + lower = describe_double_constant (pspec->minimum); + upper = describe_double_constant (pspec->maximum); + if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXFLOAT)) + { + if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT)) + desc = g_strdup (""); + else + desc = g_strdup_printf ("<= %s", upper); + } + else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT)) + desc = g_strdup_printf (">= %s", lower); + else + desc = g_strdup_printf ("[%s,%s]", lower, upper); + g_free (lower); + g_free (upper); + } + else if (G_IS_PARAM_SPEC_DOUBLE (spec)) + { + GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec); + + lower = describe_double_constant (pspec->minimum); + upper = describe_double_constant (pspec->maximum); + if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXDOUBLE)) + { + if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE)) + desc = g_strdup (""); + else + desc = g_strdup_printf ("<= %s", upper); + } + else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE)) + desc = g_strdup_printf (">= %s", lower); + else + desc = g_strdup_printf ("[%s,%s]", lower, upper); + g_free (lower); + g_free (upper); + } + else + { + desc = g_strdup (""); + } + + return desc; +} + +static gchar* +describe_default (GParamSpec *spec) +{ + gchar *desc; + + if (G_IS_PARAM_SPEC_CHAR (spec)) + { + GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec); + + desc = g_strdup_printf ("%d", pspec->default_value); + } + else if (G_IS_PARAM_SPEC_UCHAR (spec)) + { + GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec); + + desc = g_strdup_printf ("%u", pspec->default_value); + } + else if (G_IS_PARAM_SPEC_BOOLEAN (spec)) + { + GParamSpecBoolean *pspec = G_PARAM_SPEC_BOOLEAN (spec); + + desc = g_strdup_printf ("%s", pspec->default_value ? "TRUE" : "FALSE"); + } + else if (G_IS_PARAM_SPEC_INT (spec)) + { + GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec); + + desc = g_strdup_printf ("%d", pspec->default_value); + } + else if (G_IS_PARAM_SPEC_UINT (spec)) + { + GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec); + + desc = g_strdup_printf ("%u", pspec->default_value); + } + else if (G_IS_PARAM_SPEC_LONG (spec)) + { + GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec); + + desc = g_strdup_printf ("%ld", pspec->default_value); + } + else if (G_IS_PARAM_SPEC_LONG (spec)) + { + GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec); + + desc = g_strdup_printf ("%lu", pspec->default_value); + } + else if (G_IS_PARAM_SPEC_INT64 (spec)) + { + GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec); + + desc = g_strdup_printf ("%" G_GINT64_FORMAT, pspec->default_value); + } + else if (G_IS_PARAM_SPEC_UINT64 (spec)) + { + GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec); + + desc = g_strdup_printf ("%" G_GUINT64_FORMAT, pspec->default_value); + } + else if (G_IS_PARAM_SPEC_UNICHAR (spec)) + { + GParamSpecUnichar *pspec = G_PARAM_SPEC_UNICHAR (spec); + + if (g_unichar_isprint (pspec->default_value)) + desc = g_strdup_printf ("'%c'", pspec->default_value); + else + desc = g_strdup_printf ("%u", pspec->default_value); + } + else if (G_IS_PARAM_SPEC_ENUM (spec)) + { + GParamSpecEnum *pspec = G_PARAM_SPEC_ENUM (spec); + + GEnumValue *value = g_enum_get_value (pspec->enum_class, pspec->default_value); + if (value) + desc = g_strdup_printf ("%s", value->value_name); + else + desc = g_strdup_printf ("%d", pspec->default_value); + } + else if (G_IS_PARAM_SPEC_FLAGS (spec)) + { + GParamSpecFlags *pspec = G_PARAM_SPEC_FLAGS (spec); + guint default_value; + GString *acc; + + default_value = pspec->default_value; + acc = g_string_new (""); + + while (default_value) + { + GFlagsValue *value = g_flags_get_first_value (pspec->flags_class, default_value); + + if (!value) + break; + + if (acc->len > 0) + g_string_append (acc, "|"); + g_string_append (acc, value->value_name); + + default_value &= ~value->value; + } + + if (default_value == 0) + desc = g_string_free (acc, FALSE); + else + { + desc = g_strdup_printf ("%d", pspec->default_value); + g_string_free (acc, TRUE); + } + } + else if (G_IS_PARAM_SPEC_FLOAT (spec)) + { + GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec); + + desc = g_strdup_printf ("%g", pspec->default_value); + } + else if (G_IS_PARAM_SPEC_DOUBLE (spec)) + { + GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec); + + desc = g_strdup_printf ("%lg", pspec->default_value); + } + else if (G_IS_PARAM_SPEC_STRING (spec)) + { + GParamSpecString *pspec = G_PARAM_SPEC_STRING (spec); + + if (pspec->default_value) + { + gchar *esc = g_strescape (pspec->default_value, NULL); + + desc = g_strdup_printf ("\\"%s\\"", esc); + + g_free (esc); + } + else + desc = g_strdup_printf ("NULL"); + } + else + { + desc = g_strdup (""); + } + + return desc; +} + + +static void +output_object_args (FILE *fp, GType object_type) +{ + gpointer class; + const gchar *object_class_name; + guint arg; + gchar flags[16], *pos; + GParamSpec **properties; + guint n_properties; + gboolean child_prop; + gboolean style_prop; + gboolean is_pointer; + const gchar *type_name; + gchar *type_desc; + gchar *default_value; + + if (G_TYPE_IS_OBJECT (object_type)) + { + class = g_type_class_peek (object_type); + if (!class) + return; + + properties = g_object_class_list_properties (class, &n_properties); + } +#if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 3) + else if (G_TYPE_IS_INTERFACE (object_type)) + { + class = g_type_default_interface_ref (object_type); + + if (!class) + return; + + properties = g_object_interface_list_properties (class, &n_properties); + } +#endif + else + return; + + object_class_name = g_type_name (object_type); + + child_prop = FALSE; + style_prop = FALSE; + + while (TRUE) { + qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs); + for (arg = 0; arg < n_properties; arg++) + { + GParamSpec *spec = properties[arg]; + const gchar *nick, *blurb, *dot; + + if (spec->owner_type != object_type) + continue; + + pos = flags; + /* We use one-character flags for simplicity. */ + if (child_prop && !style_prop) + *pos++ = 'c'; + if (style_prop) + *pos++ = 's'; + if (spec->flags & G_PARAM_READABLE) + *pos++ = 'r'; + if (spec->flags & G_PARAM_WRITABLE) + *pos++ = 'w'; + if (spec->flags & G_PARAM_CONSTRUCT) + *pos++ = 'x'; + if (spec->flags & G_PARAM_CONSTRUCT_ONLY) + *pos++ = 'X'; + *pos = 0; + + nick = g_param_spec_get_nick (spec); + blurb = g_param_spec_get_blurb (spec); + + dot = ""; + if (blurb) { + int str_len = strlen (blurb); + if (str_len > 0 && blurb[str_len - 1] != '.') + dot = "."; + } + + type_desc = describe_type (spec); + default_value = describe_default (spec); + type_name = get_type_name (spec->value_type, &is_pointer); + fprintf (fp, "<ARG>\\n<NAME>%s::%s</NAME>\\n<TYPE>%s%s</TYPE>\\n<RANGE>%s</RANGE>\\n<FLAGS>%s</FLAGS>\\n<NICK>%s</NICK>\\n<BLURB>%s%s</BLURB>\\n<DEFAULT>%s</DEFAULT>\\n</ARG>\\n\\n", + object_class_name, g_param_spec_get_name (spec), type_name, is_pointer ? "*" : "", type_desc, flags, nick ? nick : "(null)", blurb ? blurb : "(null)", dot, default_value); + g_free (type_desc); + g_free (default_value); + } + + g_free (properties); + +#ifdef GTK_IS_CONTAINER_CLASS + if (!child_prop && GTK_IS_CONTAINER_CLASS (class)) { + properties = gtk_container_class_list_child_properties (class, &n_properties); + child_prop = TRUE; + continue; + } +#endif + +#ifdef GTK_IS_WIDGET_CLASS +#if GTK_CHECK_VERSION(2,1,0) + if (!style_prop && GTK_IS_WIDGET_CLASS (class)) { + properties = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (class), &n_properties); + style_prop = TRUE; + continue; + } +#endif +#endif + + break; + } +} +EOT + +close OUTPUT; + +# Compile and run our file + +$CC = $ENV{CC} ? $ENV{CC} : "gcc"; +$LD = $ENV{LD} ? $ENV{LD} : $CC; +$CFLAGS = $ENV{CFLAGS} ? "$ENV{CFLAGS} -Wall -g" : "-Wall -g"; +$LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : ""; + +my $o_file; +if ($CC =~ /libtool/) { + $o_file = "$MODULE-scan.lo" +} else { + $o_file = "$MODULE-scan.o" +} + +print "gtk-doc: Compiling scanner\n"; +$command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c"; +system($command) == 0 or die "Compilation of scanner failed: $!\n"; + +print "gtk-doc: Linking scanner\n"; +$command = "$LD -o $MODULE-scan $o_file $LDFLAGS"; +system($command) == 0 or die "Linking of scanner failed: $!\n"; + +print "gtk-doc: Running scanner $MODULE-scan\n"; +system("sh -c ./$MODULE-scan") == 0 or die "Scan failed: $!\n"; + +unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan"; + +#&UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0); +&UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0); +&UpdateFileIfChanged ($old_interfaces_filename, $new_interfaces_filename, 0); +&UpdateFileIfChanged ($old_prerequisites_filename, $new_prerequisites_filename, 0); +#&UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0); + + diff --git a/common/gtk-doc-plugins.mak b/common/gtk-doc-plugins.mak new file mode 100755 index 0000000..71f60ba --- /dev/null +++ b/common/gtk-doc-plugins.mak @@ -0,0 +1,397 @@ +# This is an include file specifically tuned for building documentation +# for GStreamer plug-ins + +help: + @echo + @echo "If you are a doc maintainer, run 'make update' to update" + @echo "the documentation files maintained in CVS" + @echo + @echo Other useful make targets: + @echo + @echo check-inspected-versions: make sure the inspected plugin info + @echo is up to date before a release + @echo + +# update the stuff maintained by doc maintainers +update: + $(MAKE) inspect-update + $(MAKE) scanobj-update + +# We set GPATH here; this gives us semantics for GNU make +# which are more like other make's VPATH, when it comes to +# whether a source that is a target of one rule is then +# searched for in VPATH/GPATH. +# +GPATH = $(srcdir) + +# thomas: make docs parallel installable +TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@ + +EXTRA_DIST = \ + scanobj-build.stamp \ + $(srcdir)/inspect/*.xml \ + inspect.stamp \ + inspect-build.stamp \ + $(SCANOBJ_FILES) \ + $(content_files) \ + $(extra_files) \ + $(HTML_IMAGES) \ + $(DOC_MAIN_SGML_FILE) \ + $(DOC_OVERRIDES) \ + $(DOC_MODULE)-sections.txt + +MAINTAINER_DOC_STAMPS = \ + scanobj-build.stamp \ + inspect-build.stamp \ + inspect.stamp + +# we don't add inspect-build.stamp and scanobj-build.stamp here since they are +# built manually by docs maintainers and result is commited to CVS +DOC_STAMPS = \ + scan-build.stamp \ + tmpl-build.stamp \ + sgml-build.stamp \ + html-build.stamp \ + scan.stamp \ + tmpl.stamp \ + sgml.stamp \ + html.stamp + +# files generated/updated by gtkdoc-scangobj +SCANOBJ_FILES = \ + $(DOC_MODULE).signals \ + $(DOC_MODULE).hierarchy \ + $(DOC_MODULE).interfaces \ + $(DOC_MODULE).prerequisites \ + $(DOC_MODULE).types \ + $(DOC_MODULE).args + +SCANOBJ_FILES_O = \ + .libs/$(DOC_MODULE)-scan.o + +# files generated/updated by gtkdoc-scan +SCAN_FILES = \ + $(DOC_MODULE)-sections.txt \ + $(DOC_MODULE)-overrides.txt \ + $(DOC_MODULE)-undocumented.txt \ + $(DOC_MODULE)-decl.txt \ + $(DOC_MODULE)-decl-list.txt + + +REPORT_FILES = \ + $(DOC_MODULE)-undocumented.txt \ + $(DOC_MODULE)-undeclared.txt \ + $(DOC_MODULE)-unused.txt + +# FC3 seems to need -scan.c to be part of CLEANFILES for distcheck +# no idea why FC4 can do without +CLEANFILES = \ + $(SCANOBJ_FILES_O) \ + $(DOC_MODULE)-scan.c \ + $(REPORT_FILES) \ + $(DOC_STAMPS) \ + inspect-registry.xml + + +if ENABLE_GTK_DOC +all-local: html-build.stamp + +#### scan gobjects; done by documentation maintainer #### +scanobj-update: + -rm scanobj-build.stamp + $(MAKE) scanobj-build.stamp + +# in the case of non-srcdir builds, the built gst directory gets added +# to gtk-doc scanning; but only then, to avoid duplicates +# FIXME: since we don't have the scan step as part of the build anymore, +# we could remove that +# TODO: finish elite script that updates the output files of this step +# instead of rewriting them, so that multiple maintainers can generate +# a collective set of args and signals +scanobj-build.stamp: $(SCANOBJ_DEPS) $(basefiles) + @echo '*** Scanning GObjects ***' + if test x"$(srcdir)" != x. ; then \ + for f in $(SCANOBJ_FILES); \ + do \ + cp $(srcdir)/$$f . ; \ + done; \ + else \ + $(INSPECT_ENVIRONMENT) \ + CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" \ + CFLAGS="-g $(GTKDOC_CFLAGS)" LDFLAGS="$(GTKDOC_LIBS)" \ + $(GST_DOC_SCANOBJ) --type-init-func="gst_init(NULL,NULL)" \ + --module=$(DOC_MODULE) --source=$(PACKAGE) && \ + $(PYTHON) \ + $(top_srcdir)/common/scangobj-merge.py $(DOC_MODULE); \ + fi + touch scanobj-build.stamp + +$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(SCANOBJ_FILES_O): scan-build.stamp + @true + +### inspect GStreamer plug-ins; done by documentation maintainer ### + +# only look at the plugins in this module when building inspect .xml stuff +INSPECT_REGISTRY=$(top_builddir)/docs/plugins/inspect-registry.xml +INSPECT_ENVIRONMENT=\ + GST_PLUGIN_SYSTEM_PATH= \ + GST_PLUGIN_PATH=$(top_builddir)/gst:$(top_builddir)/sys:$(top_builddir)/ext:$(top_builddir)/plugins:$(top_builddir)/src \ + GST_REGISTRY=$(INSPECT_REGISTRY) + +# update the element and plugin XML descriptions; store in inspect/ +inspect: + mkdir inspect + +inspect-update: inspect + -rm $(INSPECT_REGISTRY) + -rm inspect-build.stamp + $(MAKE) inspect-build.stamp + +# FIXME: inspect.stamp should be written to by gst-xmlinspect.py +# IF the output changed; see gtkdoc-mktmpl +inspect-build.stamp: + @echo '*** Rebuilding plugin inspection files ***' + if test x"$(srcdir)" != x. ; then \ + cp $(srcdir)/inspect.stamp . ; \ + cp $(srcdir)/inspect-build.stamp . ; \ + else \ + $(INSPECT_ENVIRONMENT) $(PYTHON) \ + $(top_srcdir)/common/gst-xmlinspect.py $(PACKAGE) inspect && \ + echo -n "timestamp" > inspect.stamp && \ + touch inspect-build.stamp; \ + fi + +### scan headers; done on every build ### +scan-build.stamp: $(HFILE_GLOB) $(EXTRA_HFILES) $(basefiles) scanobj-build.stamp inspect-build.stamp + if test "x$(top_srcdir)" != "x$(top_builddir)" && \ + test -d "$(top_builddir)/gst"; \ + then \ + export BUILT_OPTIONS="--source-dir=$(top_builddir)/gst"; \ + fi; \ + gtkdoc-scan \ + $(SCAN_OPTIONS) $(EXTRA_HFILES) \ + --module=$(DOC_MODULE) \ + $$BUILT_OPTIONS \ + --ignore-headers="$(IGNORE_HFILES)"; \ + touch scan-build.stamp + +#### update templates; done on every build #### + +### FIXME: make this error out again when docs are fixed for 0.9 +# in a non-srcdir build, we need to copy files from the previous step +# and the files from previous runs of this step +tmpl-build.stamp: $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_OVERRIDES) + @echo '*** Rebuilding template files ***' + if test x"$(srcdir)" != x. ; then \ + for f in $(SCANOBJ_FILES) $(SCAN_FILES); \ + do \ + if test -e $(srcdir)/$$f; then cp $(srcdir)/$$f . ; fi; \ + done; \ + fi + gtkdoc-mktmpl --module=$(DOC_MODULE) | tee tmpl-build.log + $(PYTHON) \ + $(top_srcdir)/common/mangle-tmpl.py $(srcdir)/inspect tmpl + @cat $(DOC_MODULE)-unused.txt + rm -f tmpl-build.log + touch tmpl-build.stamp + +tmpl.stamp: tmpl-build.stamp + @true + +#### build xml; done on every build #### + +### FIXME: make this error out again when docs are fixed for 0.9 +sgml-build.stamp: tmpl.stamp inspect.stamp $(CFILE_GLOB) $(top_srcdir)/common/plugins.xsl + @echo '*** Building XML ***' + @-mkdir -p xml + @for a in $(srcdir)/inspect/*.xml; do \ + xsltproc --stringparam module $(MODULE) \ + $(top_srcdir)/common/plugins.xsl $$a > xml/`basename $$a`; done + @for f in $(EXAMPLE_CFILES); do \ + $(PYTHON) $(top_srcdir)/common/c-to-xml.py $$f > xml/element-`basename $$f .c`.xml; done + gtkdoc-mkdb \ + --module=$(DOC_MODULE) \ + --source-dir=$(DOC_SOURCE_DIR) \ + --main-sgml-file=$(srcdir)/$(DOC_MAIN_SGML_FILE) \ + --output-format=xml \ + --ignore-files="$(IGNORE_HFILES) $(IGNORE_CFILES)" \ + $(MKDB_OPTIONS) \ + | tee sgml-build.log + @if grep "WARNING:" sgml-build.log > /dev/null; then true; fi # exit 1; fi + cp ../version.entities xml + rm sgml-build.log + touch sgml-build.stamp + +sgml.stamp: sgml-build.stamp + @true + +#### build html; done on every step #### + +html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) + @echo '*** Building HTML ***' + if test -d html; then rm -rf html; fi + mkdir html + cp $(srcdir)/$(DOC_MAIN_SGML_FILE) html + @for f in $(content_files); do cp $(srcdir)/$$f html; done + cp -pr xml html + cp ../version.entities html + cd html && gtkdoc-mkhtml $(DOC_MODULE) $(DOC_MAIN_SGML_FILE) \ + 2>&1 | tee ../html-build.log + @if grep "warning:" html-build.log > /dev/null; then \ + echo "ERROR"; grep "warning:" html-build.log; exit 1; fi + @rm html-build.log + mv html/index.sgml html/index.sgml.bak + $(SED) "s/ href=\"$(DOC_MODULE)\// href=\"$(DOC_MODULE)-@GST_MAJORMINOR@\//g" html/index.sgml.bak >html/index.sgml + rm -f html/index.sgml.bak + rm -f html/$(DOC_MAIN_SGML_FILE) + rm -rf html/xml + rm -f html/version.entities + test "x$(HTML_IMAGES)" = "x" || for i in "" $(HTML_IMAGES) ; do \ + if test "$$i" != ""; then cp $(srcdir)/$$i html ; fi; done + @echo '-- Fixing Crossreferences' + gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS) + touch html-build.stamp +else +all-local: +endif + +# FIXME: these rules need a little cleaning up +clean-local: + rm -f *~ *.bak + rm -rf .libs +# clean files generated for tmpl build + -rm -rf tmpl +# clean files copied/generated for nonsrcdir tmpl build + if test x"$(srcdir)" != x. ; then \ + rm -rf $(SCANOBJ_FILES) $(SCAN_FILES); \ + fi +# clean files generated for xml build + -rm -rf xml +# clean files generate for html build + -rm -rf html + +distclean-local: clean + rm -rf tmpl/*.sgml.bak + rm -f *.stamp || true + rm -rf *.o + +# thomas: make docs parallel installable; devhelp requires majorminor too +install-data-local: + $(mkinstalldirs) $(DESTDIR)$(TARGET_DIR) + (installfiles=`echo ./html/*.html`; \ + if test "$$installfiles" = './html/*.html'; \ + then echo '-- Nothing to install' ; \ + else \ + for i in $$installfiles; do \ + echo '-- Installing '$$i ; \ + $(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \ + done; \ + pngfiles=`echo ./html/*.png`; \ + if test "$$pngfiles" != './html/*.png'; then \ + for i in $$pngfiles; do \ + echo '-- Installing '$$i ; \ + $(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \ + done; \ + fi; \ + echo '-- Installing $(srcdir)/html/$(DOC_MODULE).devhelp' ; \ + $(INSTALL_DATA) $(srcdir)/html/$(DOC_MODULE).devhelp \ + $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp; \ + if test -e $(srcdir)/html/$(DOC_MODULE).devhelp2; then \ + $(INSTALL_DATA) $(srcdir)/html/$(DOC_MODULE).devhelp2 \ + $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp2; \ + fi; \ + echo '-- Installing $(srcdir)/html/index.sgml' ; \ + $(INSTALL_DATA) $(srcdir)/html/index.sgml $(DESTDIR)$(TARGET_DIR); \ + if test -e $(srcdir)/html/style.css; then \ + echo '-- Installing $(srcdir)/html/style.css' ; \ + $(INSTALL_DATA) $(srcdir)/html/style.css $(DESTDIR)$(TARGET_DIR); \ + fi; \ + fi) +uninstall-local: + (installfiles=`echo ./html/*.html`; \ + if test "$$installfiles" = './html/*.html'; \ + then echo '-- Nothing to uninstall' ; \ + else \ + for i in $$installfiles; do \ + rmfile=`basename $$i` ; \ + echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/'$$rmfile ; \ + rm -f $(DESTDIR)$(TARGET_DIR)/$$rmfile; \ + done; \ + pngfiles=`echo ./html/*.png`; \ + if test "$$pngfiles" != './html/*.png'; then \ + for i in $$pngfiles; do \ + rmfile=`basename $$i` ; \ + echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/'$$rmfile ; \ + rm -f $(DESTDIR)$(TARGET_DIR)/$$rmfile; \ + done; \ + fi; \ + echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE).devhelp' ; \ + rm -f $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp; \ + if test -e $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp2; then \ + rm -f $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp2; \ + fi; \ + echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/index.sgml' ; \ + rm -f $(DESTDIR)$(TARGET_DIR)/index.sgml; \ + if test -e $(DESTDIR)$(TARGET_DIR)/style.css; then \ + echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/style.css' ; \ + rm -f $(DESTDIR)$(TARGET_DIR)/style.css; \ + fi; \ + fi) + if test -d $(DESTDIR)$(TARGET_DIR); then rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(TARGET_DIR) 2>/dev/null; fi; true + +# +# Checks +# +check-hierarchy: $(DOC_MODULE).hierarchy + @if grep ' ' $(DOC_MODULE).hierarchy; then \ + echo "$(DOC_MODULE).hierarchy contains tabs, please fix"; \ + /bin/false; \ + fi + +check: check-hierarchy + +# wildcard is apparently not portable to other makes, hence the use of find +inspect_files = $(shell find $(top_srcdir)/docs/plugins/inspect -name '*.xml') + +check-inspected-versions: + @echo Checking plugin versions of inspected plugin data ...; \ + fail=0 ; \ + for each in $(inspect_files) ; do \ + if (grep -H '<version>' $$each | grep -v '<version>$(VERSION)'); then \ + echo $$each should be fixed to say version $(VERSION) or be removed ; \ + echo "sed -i -e 's/<version.*version>/<version>$(VERSION)<\/version>/'" $$each; \ + echo ; \ + fail=1; \ + fi ; \ + done ; \ + exit $$fail + +# +# Require gtk-doc when making dist +# +if ENABLE_GTK_DOC +dist-check-gtkdoc: +else +dist-check-gtkdoc: + @echo "*** gtk-doc must be installed and enabled in order to make dist" + @false +endif + +# FIXME: decide whether we want to dist generated html or not +dist-hook: dist-check-gtkdoc dist-hook-local + mkdir $(distdir)/tmpl + mkdir $(distdir)/xml + mkdir $(distdir)/html + -cp $(srcdir)/tmpl/*.sgml $(distdir)/tmpl + -cp $(srcdir)/sgml/*.xml $(distdir)/xml + -cp $(srcdir)/html/index.sgml $(distdir)/html + -cp $(srcdir)/html/*.html $(srcdir)/html/*.css $(distdir)/html + -cp $(srcdir)/html/$(DOC_MODULE).devhelp* $(distdir)/html + + images=$(HTML_IMAGES) ; \ + for i in "" $$images ; do \ + if test "$$i" != ""; then cp $(srcdir)/$$i $(distdir)/html ; fi; \ + done + +.PHONY : dist-hook-local + diff --git a/common/gtk-doc.mak b/common/gtk-doc.mak new file mode 100755 index 0000000..1c9ece1 --- /dev/null +++ b/common/gtk-doc.mak @@ -0,0 +1,267 @@ +########################################################################### +# Everything below here is generic and you shouldn't need to change it. +########################################################################### +# thomas: except of course that we did + +# thomas: copied from glib-2 +# We set GPATH here; this gives us semantics for GNU make +# which are more like other make's VPATH, when it comes to +# whether a source that is a target of one rule is then +# searched for in VPATH/GPATH. +# +GPATH = $(srcdir) + +# thomas: make docs parallel installable +TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@ + +EXTRA_DIST = \ + $(content_files) \ + $(extra_files) \ + $(HTML_IMAGES) \ + $(DOC_MAIN_SGML_FILE) \ + $(DOC_MODULE).types \ + $(DOC_OVERRIDES) \ + $(DOC_MODULE)-sections.txt + +DOC_STAMPS = \ + scan-build.stamp \ + tmpl-build.stamp \ + sgml-build.stamp \ + html-build.stamp \ + $(srcdir)/tmpl.stamp \ + $(srcdir)/sgml.stamp \ + $(srcdir)/html.stamp + +SCANOBJ_FILES = \ + $(DOC_MODULE).args \ + $(DOC_MODULE).hierarchy \ + $(DOC_MODULE).interfaces \ + $(DOC_MODULE).prerequisites \ + .libs/$(DOC_MODULE)-scan.o \ + $(DOC_MODULE).signals + +REPORT_FILES = \ + $(DOC_MODULE)-undocumented.txt \ + $(DOC_MODULE)-undeclared.txt \ + $(DOC_MODULE)-unused.txt + +CLEANFILES = $(SCANOBJ_FILES) $(REPORT_FILES) $(DOC_STAMPS) + +if ENABLE_GTK_DOC +all-local: html-build.stamp + +#### scan #### + +# in the case of non-srcdir builds, the built gst directory gets added +# to gtk-doc scanning; but only then, to avoid duplicates +scan-build.stamp: $(HFILE_GLOB) $(SCANOBJ_DEPS) $(basefiles) + @echo '*** Scanning header files ***' + if grep -l '^..*$$' $(srcdir)/$(DOC_MODULE).types > /dev/null; \ + then \ + if test x"$(srcdir)" != x. ; then \ + cp $(srcdir)/$(DOC_MODULE).types . ; \ + chmod u+w $(DOC_MODULE).types ; \ + fi ; \ + GST_PLUGIN_SYSTEM_PATH=`cd $(top_builddir) && pwd` \ + GST_PLUGIN_PATH= \ + CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" \ + CFLAGS="$(GTKDOC_CFLAGS)" LDFLAGS="$(GTKDOC_LIBS)" \ + gtkdoc-scangobj --type-init-func="gst_init(NULL,NULL)" \ + --module=$(DOC_MODULE) ; \ + else \ + cd $(srcdir) ; \ + for i in $(SCANOBJ_FILES) ; do \ + test -f $$i || touch $$i ; \ + done \ + fi + if test "x$(top_srcdir)" != "x$(top_builddir)"; \ + then \ + export BUILT_OPTIONS="--source-dir=$(DOC_BUILD_DIR)"; \ + fi; \ + gtkdoc-scan \ + $(SCAN_OPTIONS) $(EXTRA_HFILES) \ + --module=$(DOC_MODULE) \ + --source-dir=$(DOC_SOURCE_DIR) \ + $$BUILT_OPTIONS \ + --ignore-headers="$(IGNORE_HFILES)" + touch scan-build.stamp + +$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES): scan-build.stamp + @true + +#### templates #### + +tmpl-build.stamp: $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_OVERRIDES) + @echo '*** Rebuilding template files ***' + if test x"$(srcdir)" != x. ; then \ + cp $(srcdir)/$(DOC_MODULE)-sections.txt . ; \ + touch $(DOC_MODULE)-decl.txt ; \ + fi + gtkdoc-mktmpl --module=$(DOC_MODULE) | tee tmpl-build.log + @if test -s $(DOC_MODULE)-unused.txt; then \ + exit $(if $(DOCS_ARE_INCOMPLETE_PLEASE_FIXME),0,1); fi + rm -f tmpl-build.log + touch tmpl-build.stamp + +tmpl.stamp: tmpl-build.stamp + @true + +#### xml #### + +### FIXME: make this error out again when docs are complete +sgml-build.stamp: tmpl.stamp $(CFILE_GLOB) + @echo '*** Building XML ***' + gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --main-sgml-file=$(srcdir)/$(DOC_MAIN_SGML_FILE) --output-format=xml $(MKDB_OPTIONS) | tee sgml-build.log + @if grep "WARNING:" sgml-build.log > /dev/null; then true; fi # exit 1; fi + rm sgml-build.log + touch sgml-build.stamp + +sgml.stamp: sgml-build.stamp + @true + +#### html #### + +html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) + @echo '*** Building HTML ***' + if test -d html; then rm -rf html; fi + mkdir html + cp $(srcdir)/$(DOC_MAIN_SGML_FILE) html + @for f in $(content_files); do cp $(srcdir)/$$f html; done + cp -pr xml html + cp ../version.entities html + cd html && gtkdoc-mkhtml $(DOC_MODULE) $(DOC_MAIN_SGML_FILE) + mv html/index.sgml html/index.sgml.bak + $(SED) "s/ href=\"$(DOC_MODULE)\// href=\"$(DOC_MODULE)-@GST_MAJORMINOR@\//g" html/index.sgml.bak >html/index.sgml + rm -f html/index.sgml.bak + rm -f html/$(DOC_MAIN_SGML_FILE) + rm -rf html/xml + rm -f html/version.entities + test "x$(HTML_IMAGES)" = "x" || for i in "" $(HTML_IMAGES) ; do \ + if test "$$i" != ""; then cp $(srcdir)/$$i html ; fi; done + @echo '-- Fixing Crossreferences' + gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS) + touch html-build.stamp +else +all-local: +endif + +clean-local: + rm -f *~ *.bak + rm -rf xml html + rm -rf .libs + +maintainer-clean-local: clean + cd $(srcdir) && rm -rf xml html $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt + +# company: don't delete .sgml and -sections.txt as they're in CVS +# FIXME : thomas added all sgml files and some other things to make +# make distcheck work +distclean-local: clean + rm -f $(DOC_MODULE)-decl-list.txt + rm -f $(DOC_MODULE)-decl.txt + rm -f $(REPORT_FILES) + rm -rf tmpl/*.sgml.bak + rm -f $(DOC_MODULE).hierarchy + rm -f *.stamp || true + if test x"$(srcdir)" != x. ; then \ + rm -f $(DOC_MODULE)-docs.sgml ; \ + rm -f $(DOC_MODULE).types ; \ + rm -f $(DOC_MODULE).interfaces ; \ + rm -f $(DOC_MODULE)-overrides.txt ; \ + rm -f $(DOC_MODULE).prerequisites ; \ + rm -f $(DOC_MODULE)-sections.txt ; \ + rm -rf tmpl/*.sgml ; \ + fi + rm -rf *.o + +# thomas: make docs parallel installable; devhelp requires majorminor too +install-data-local: + $(mkinstalldirs) $(DESTDIR)$(TARGET_DIR) + (installfiles=`echo ./html/*.html`; \ + if test "$$installfiles" = './html/*.html'; \ + then echo '-- Nothing to install' ; \ + else \ + for i in $$installfiles; do \ + echo '-- Installing '$$i ; \ + $(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \ + done; \ + pngfiles=`echo ./html/*.png`; \ + if test "$$pngfiles" != './html/*.png'; then \ + for i in $$pngfiles; do \ + echo '-- Installing '$$i ; \ + $(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \ + done; \ + fi; \ + echo '-- Installing $(srcdir)/html/$(DOC_MODULE).devhelp' ; \ + $(INSTALL_DATA) $(srcdir)/html/$(DOC_MODULE).devhelp \ + $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp; \ + if test -e $(srcdir)/html/$(DOC_MODULE).devhelp2; then \ + $(INSTALL_DATA) $(srcdir)/html/$(DOC_MODULE).devhelp2 \ + $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp2; \ + fi; \ + echo '-- Installing $(srcdir)/html/index.sgml' ; \ + $(INSTALL_DATA) $(srcdir)/html/index.sgml $(DESTDIR)$(TARGET_DIR); \ + if test -e $(srcdir)/html/style.css; then \ + echo '-- Installing $(srcdir)/html/style.css' ; \ + $(INSTALL_DATA) $(srcdir)/html/style.css $(DESTDIR)$(TARGET_DIR); \ + fi; \ + fi) +uninstall-local: + (installfiles=`echo ./html/*.html`; \ + if test "$$installfiles" = './html/*.html'; \ + then echo '-- Nothing to uninstall' ; \ + else \ + for i in $$installfiles; do \ + rmfile=`basename $$i` ; \ + echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/'$$rmfile ; \ + rm -f $(DESTDIR)$(TARGET_DIR)/$$rmfile; \ + done; \ + pngfiles=`echo ./html/*.png`; \ + if test "$$pngfiles" != './html/*.png'; then \ + for i in $$pngfiles; do \ + rmfile=`basename $$i` ; \ + echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/'$$rmfile ; \ + rm -f $(DESTDIR)$(TARGET_DIR)/$$rmfile; \ + done; \ + fi; \ + echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE).devhelp' ; \ + rm -f $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp; \ + if test -e $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp2; then \ + rm -f $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp2; \ + fi; \ + echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/index.sgml' ; \ + rm -f $(DESTDIR)$(TARGET_DIR)/index.sgml; \ + if test -e $(DESTDIR)$(TARGET_DIR)/style.css; then \ + echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/style.css' ; \ + rm -f $(DESTDIR)$(TARGET_DIR)/style.css; \ + fi; \ + fi) + if test -d $(DESTDIR)$(TARGET_DIR); then rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(TARGET_DIR) 2>/dev/null; fi; true + +# +# Require gtk-doc when making dist +# +if ENABLE_GTK_DOC +dist-check-gtkdoc: +else +dist-check-gtkdoc: + @echo "*** gtk-doc must be installed and enabled in order to make dist" + @false +endif + +dist-hook: dist-check-gtkdoc dist-hook-local + mkdir $(distdir)/tmpl + mkdir $(distdir)/xml + mkdir $(distdir)/html + -cp $(srcdir)/tmpl/*.sgml $(distdir)/tmpl + -cp $(srcdir)/sgml/*.xml $(distdir)/xml + -cp $(srcdir)/html/index.sgml $(distdir)/html + -cp $(srcdir)/html/*.html $(srcdir)/html/*.css $(distdir)/html + -cp $(srcdir)/html/$(DOC_MODULE).devhelp* $(distdir)/html + + images=$(HTML_IMAGES) ; \ + for i in "" $$images ; do \ + if test "$$i" != ""; then cp $(srcdir)/$$i $(distdir)/html ; fi; \ + done + +.PHONY : dist-hook-local diff --git a/common/m4/Makefile.am b/common/m4/Makefile.am new file mode 100755 index 0000000..99ead5c --- /dev/null +++ b/common/m4/Makefile.am @@ -0,0 +1,29 @@ +EXTRA_DIST = \ + README \ + as-ac-expand.m4 \ + as-auto-alt.m4 \ + as-compiler-flag.m4 \ + as-compiler.m4 \ + as-docbook.m4 \ + as-gcc-inline-assembly.m4 \ + as-libtool.m4 \ + as-libtool-tags.m4 \ + as-python.m4 \ + as-scrub-include.m4 \ + as-version.m4 \ + ax_create_stdint_h.m4 \ + glib-gettext.m4 \ + gst-arch.m4 \ + gst-args.m4 \ + gst-check.m4 \ + gst-debuginfo.m4 \ + gst-default.m4 \ + gst-doc.m4 \ + gst-feature.m4 \ + gst-function.m4 \ + gst-gettext.m4 \ + gst-glib2.m4 \ + gst-libxml2.m4 \ + gst-plugindir.m4 \ + gst-valgrind.m4 \ + pkg.m4 diff --git a/common/m4/README b/common/m4/README new file mode 100755 index 0000000..f044598 --- /dev/null +++ b/common/m4/README @@ -0,0 +1,3 @@ +All aclocal .m4 files we need are put here and cat'd to acinclude.m4 in +the source root. Official ones (taken from the relevant devel packages) +are named as-is, unofficial ones (or changed ones) get a gst-prefix. diff --git a/common/m4/as-ac-expand.m4 b/common/m4/as-ac-expand.m4 new file mode 100755 index 0000000..d6c9e33 --- /dev/null +++ b/common/m4/as-ac-expand.m4 @@ -0,0 +1,43 @@ +dnl as-ac-expand.m4 0.2.0 +dnl autostars m4 macro for expanding directories using configure's prefix +dnl thomas@apestaart.org + +dnl AS_AC_EXPAND(VAR, CONFIGURE_VAR) +dnl example +dnl AS_AC_EXPAND(SYSCONFDIR, $sysconfdir) +dnl will set SYSCONFDIR to /usr/local/etc if prefix=/usr/local + +AC_DEFUN([AS_AC_EXPAND], +[ + EXP_VAR=[$1] + FROM_VAR=[$2] + + dnl first expand prefix and exec_prefix if necessary + prefix_save=$prefix + exec_prefix_save=$exec_prefix + + dnl if no prefix given, then use /usr/local, the default prefix + if test "x$prefix" = "xNONE"; then + prefix="$ac_default_prefix" + fi + dnl if no exec_prefix given, then use prefix + if test "x$exec_prefix" = "xNONE"; then + exec_prefix=$prefix + fi + + full_var="$FROM_VAR" + dnl loop until it doesn't change anymore + while true; do + new_full_var="`eval echo $full_var`" + if test "x$new_full_var" = "x$full_var"; then break; fi + full_var=$new_full_var + done + + dnl clean up + full_var=$new_full_var + AC_SUBST([$1], "$full_var") + + dnl restore prefix and exec_prefix + prefix=$prefix_save + exec_prefix=$exec_prefix_save +]) diff --git a/common/m4/as-auto-alt.m4 b/common/m4/as-auto-alt.m4 new file mode 100755 index 0000000..3f7920d --- /dev/null +++ b/common/m4/as-auto-alt.m4 @@ -0,0 +1,50 @@ +dnl as-auto-alt.m4 0.0.2 +dnl autostars m4 macro for supplying alternate autotools versions to configure +dnl thomas@apestaart.org +dnl +dnl AS_AUTOTOOLS_ALTERNATE() +dnl +dnl supplies --with arguments for autoconf, autoheader, automake, aclocal + +AC_DEFUN([AS_AUTOTOOLS_ALTERNATE], +[ + dnl allow for different autoconf version + AC_ARG_WITH(autoconf, + AC_HELP_STRING([--with-autoconf], + [use a different autoconf for regeneration of Makefiles]), + [ + unset AUTOCONF + AM_MISSING_PROG(AUTOCONF, ${withval}) + AC_MSG_NOTICE([Using $AUTOCONF as autoconf]) + ]) + + dnl allow for different autoheader version + AC_ARG_WITH(autoheader, + AC_HELP_STRING([--with-autoheader], + [use a different autoheader for regeneration of Makefiles]), + [ + unset AUTOHEADER + AM_MISSING_PROG(AUTOHEADER, ${withval}) + AC_MSG_NOTICE([Using $AUTOHEADER as autoheader]) + ]) + + dnl allow for different automake version + AC_ARG_WITH(automake, + AC_HELP_STRING([--with-automake], + [use a different automake for regeneration of Makefiles]), + [ + unset AUTOMAKE + AM_MISSING_PROG(AUTOMAKE, ${withval}) + AC_MSG_NOTICE([Using $AUTOMAKE as automake]) + ]) + + dnl allow for different aclocal version + AC_ARG_WITH(aclocal, + AC_HELP_STRING([--with-aclocal], + [use a different aclocal for regeneration of Makefiles]), + [ + unset ACLOCAL + AM_MISSING_PROG(ACLOCAL, ${withval}) + AC_MSG_NOTICE([Using $ACLOCAL as aclocal]) + ]) +]) diff --git a/common/m4/as-compiler-flag.m4 b/common/m4/as-compiler-flag.m4 new file mode 100755 index 0000000..882a4c7 --- /dev/null +++ b/common/m4/as-compiler-flag.m4 @@ -0,0 +1,64 @@ +dnl as-compiler-flag.m4 0.1.0 + +dnl autostars m4 macro for detection of compiler flags + +dnl David Schleef <ds@schleef.org> +dnl Tim-Philipp Müller <tim centricular net> + +dnl AS_COMPILER_FLAG(CFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED]) +dnl Tries to compile with the given CFLAGS. +dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags, +dnl and ACTION-IF-NOT-ACCEPTED otherwise. + +AC_DEFUN([AS_COMPILER_FLAG], +[ + AC_MSG_CHECKING([to see if compiler understands $1]) + + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $1" + + AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no]) + CFLAGS="$save_CFLAGS" + + if test "X$flag_ok" = Xyes ; then + $2 + true + else + $3 + true + fi + AC_MSG_RESULT([$flag_ok]) +]) + +dnl AS_CXX_COMPILER_FLAG(CPPFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED]) +dnl Tries to compile with the given CPPFLAGS. +dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags, +dnl and ACTION-IF-NOT-ACCEPTED otherwise. + +AC_DEFUN([AS_CXX_COMPILER_FLAG], +[ + AC_REQUIRE([AC_PROG_CXX]) + + AC_MSG_CHECKING([to see if c++ compiler understands $1]) + + save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $1" + + AC_LANG_PUSH(C++) + + AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no]) + CPPFLAGS="$save_CPPFLAGS" + + if test "X$flag_ok" = Xyes ; then + $2 + true + else + $3 + true + fi + + AC_LANG_POP(C++) + + AC_MSG_RESULT([$flag_ok]) +]) + diff --git a/common/m4/as-compiler.m4 b/common/m4/as-compiler.m4 new file mode 100755 index 0000000..233a719 --- /dev/null +++ b/common/m4/as-compiler.m4 @@ -0,0 +1,44 @@ +dnl as-compiler.m4 0.1.0 + +dnl autostars m4 macro for detection of compiler flavor + +dnl Thomas Vander Stichele <thomas at apestaart dot org> + +dnl $Id: as-compiler.m4,v 1.4 2004/06/01 09:33:45 thomasvs Exp $ + +dnl AS_COMPILER(COMPILER) +dnl will set variable COMPILER to +dnl - gcc +dnl - forte +dnl - (empty) if no guess could be made + +AC_DEFUN([AS_COMPILER], +[ + as_compiler= + AC_MSG_CHECKING(for compiler flavour) + + dnl is it gcc ? + if test "x$GCC" = "xyes"; then + as_compiler="gcc" + fi + + dnl is it forte ? + AC_TRY_RUN([ +int main +(int argc, char *argv[]) +{ +#ifdef __sun + return 0; +#else + return 1; +#endif +} + ], as_compiler="forte", ,) + + if test "x$as_compiler" = "x"; then + AC_MSG_RESULT([unknown !]) + else + AC_MSG_RESULT($as_compiler) + fi + [$1]=$as_compiler +]) diff --git a/common/m4/as-docbook.m4 b/common/m4/as-docbook.m4 new file mode 100755 index 0000000..8a1b32a --- /dev/null +++ b/common/m4/as-docbook.m4 @@ -0,0 +1,66 @@ +dnl AS_DOCBOOK([, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl checks if xsltproc can build docbook documentation +dnl (which is possible if the catalog is set up properly +dnl I also tried checking for a specific version and type of docbook +dnl but xsltproc seemed to happily run anyway, so we can't check for that +dnl and version +dnl this macro takes inspiration from +dnl http://www.movement.uklinux.net/docs/docbook-autotools/configure.html +AC_DEFUN([AS_DOCBOOK], +[ + XSLTPROC_FLAGS=--nonet + DOCBOOK_ROOT= + TYPE_LC=xml + TYPE_UC=XML + DOCBOOK_VERSION=4.1.2 + + if test ! -f /etc/xml/catalog; then + for i in /usr/share/sgml/docbook/stylesheet/xsl/nwalsh /usr/share/sgml/docbook/xsl-stylesheets/ /usr/local/share/xsl/docbook ; + do + if test -d "$i"; then + DOCBOOK_ROOT=$i + fi + done + else + XML_CATALOG=/etc/xml/catalog + CAT_ENTRY_START='<!--' + CAT_ENTRY_END='-->' + fi + + dnl We need xsltproc to process the test + AC_CHECK_PROG(XSLTPROC,xsltproc,xsltproc,) + XSLTPROC_WORKS=no + if test -n "$XSLTPROC"; then + AC_MSG_CHECKING([whether xsltproc docbook processing works]) + + if test -n "$XML_CATALOG"; then + DB_FILE="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl" + else + DB_FILE="$DOCBOOK_ROOT/xhtml/docbook.xsl" + fi + $XSLTPROC $XSLTPROC_FLAGS $DB_FILE >/dev/null 2>&1 << END +<?xml version="1.0" encoding='ISO-8859-1'?> +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook $TYPE_UC V$DOCBOOK_VERSION//EN" "http://www.oasis-open.org/docbook/$TYPE_LC/$DOCBOOK_VERSION/docbookx.dtd"> +<book id="test"> +</book> +END + if test "$?" = 0; then + XSLTPROC_WORKS=yes + fi + AC_MSG_RESULT($XSLTPROC_WORKS) + fi + + if test "x$XSLTPROC_WORKS" = "xyes"; then + dnl execute ACTION-IF-FOUND + ifelse([$1], , :, [$1]) + else + dnl execute ACTION-IF-NOT-FOUND + ifelse([$2], , :, [$2]) + fi + + AC_SUBST(XML_CATALOG) + AC_SUBST(XSLTPROC_FLAGS) + AC_SUBST(DOCBOOK_ROOT) + AC_SUBST(CAT_ENTRY_START) + AC_SUBST(CAT_ENTRY_END) +]) diff --git a/common/m4/as-gcc-inline-assembly.m4 b/common/m4/as-gcc-inline-assembly.m4 new file mode 100755 index 0000000..799e80e --- /dev/null +++ b/common/m4/as-gcc-inline-assembly.m4 @@ -0,0 +1,52 @@ +dnl as-gcc-inline-assembly.m4 0.1.0 + +dnl autostars m4 macro for detection of gcc inline assembly + +dnl David Schleef <ds@schleef.org> + +dnl $Id: as-gcc-inline-assembly.m4,v 1.1 2008-02-26 09:38:00 thaytan Exp $ + +dnl AS_COMPILER_FLAG(ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED]) +dnl Tries to compile with the given CFLAGS. +dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags, +dnl and ACTION-IF-NOT-ACCEPTED otherwise. + +AC_DEFUN([AS_GCC_INLINE_ASSEMBLY], +[ + AC_MSG_CHECKING([if compiler supports gcc-style inline assembly]) + + AC_TRY_COMPILE([], [ +#ifdef __GNUC_MINOR__ +#if (__GNUC__ * 1000 + __GNUC_MINOR__) < 3004 +#error GCC before 3.4 has critical bugs compiling inline assembly +#endif +#endif +__asm__ (""::) ], [flag_ok=yes], [flag_ok=no]) + + if test "X$flag_ok" = Xyes ; then + $1 + true + else + $2 + true + fi + AC_MSG_RESULT([$flag_ok]) +]) + + +AC_DEFUN([AS_GCC_ASM_POWERPC_FPU], +[ + AC_MSG_CHECKING([if compiler supports FPU instructions on PowerPC]) + + AC_TRY_COMPILE([], [__asm__ ("fadd 0,0,0"::) ], [flag_ok=yes], [flag_ok=no]) + + if test "X$flag_ok" = Xyes ; then + $1 + true + else + $2 + true + fi + AC_MSG_RESULT([$flag_ok]) +]) + diff --git a/common/m4/as-libtool-tags.m4 b/common/m4/as-libtool-tags.m4 new file mode 100755 index 0000000..c522ff2 --- /dev/null +++ b/common/m4/as-libtool-tags.m4 @@ -0,0 +1,83 @@ +dnl as-libtool-tags.m4 0.1.4 + +dnl autostars m4 macro for selecting libtool "tags" (languages) + +dnl Andy Wingo does not claim credit for this macro +dnl backported from libtool 1.6 by Paolo Bonzini +dnl see http://lists.gnu.org/archive/html/libtool/2003-12/msg00007.html + +dnl $Id: as-libtool-tags.m4,v 1.3 2006-04-01 15:30:56 thomasvs Exp $ + +dnl AS_LIBTOOL_TAGS([tags...]) + +dnl example +dnl AS_LIBTOOL_TAGS([]) for only C (no fortran, etc) + +dnl When AC_LIBTOOL_TAGS is used, I redefine _LT_AC_TAGCONFIG +dnl to be more similar to the libtool 1.6 implementation, which +dnl uses an m4 loop and m4 case instead of a shell loop. This +dnl way the CXX/GCJ/F77/RC tests are not always expanded. + +dnl AS_LIBTOOL_TAGS +dnl --------------- +dnl tags to enable +AC_DEFUN([AS_LIBTOOL_TAGS], +[m4_define([_LT_TAGS],[$1]) +m4_define([_LT_AC_TAGCONFIG], [ + # redefined LT AC TAGCONFIG + if test -f "$ltmain"; then + if test ! -f "${ofile}"; then + AC_MSG_WARN([output file `$ofile' does not exist]) + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) + else + AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) + fi + fi + + AC_FOREACH([_LT_TAG], _LT_TAGS, + echo THOMAS: tag _LT_TAG + [m4_case(_LT_TAG, + [CXX], [ + if test -n "$CXX" && test "X$CXX" != "Xno"; then + echo "THOMAS: YAY CXX" + AC_LIBTOOL_LANG_CXX_CONFIG + available_tags="$available_tags _LT_TAG" + fi], + [F77], [ + if test -n "$F77" && test "X$F77" != "Xno"; then + AC_LIBTOOL_LANG_F77_CONFIG + available_tags="$available_tags _LT_TAG" + fi], + [GCJ], [ + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + AC_LIBTOOL_LANG_GCJ_CONFIG + available_tags="$available_tags _LT_TAG" + fi], + [RC], [ + if test -n "$RC" && test "X$RC" != "Xno"; then + AC_LIBTOOL_LANG_RC_CONFIG + available_tags="$available_tags _LT_TAG" + fi], + [m4_errprintn(m4_location[: error: invalid tag name: ]"_LT_TAG") + m4_exit(1)]) + ]) + echo THOMAS: available tags: $available_tags + fi + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + AC_MSG_NOTICE([updated available libtool tags with $available_tags.]) + else + rm -f "${ofile}T" + AC_MSG_ERROR([unable to update list of available tagged configurations.]) + + fi + +])dnl _LT_AC_TAG_CONFIG +]) diff --git a/common/m4/as-libtool.m4 b/common/m4/as-libtool.m4 new file mode 100755 index 0000000..73dec1f --- /dev/null +++ b/common/m4/as-libtool.m4 @@ -0,0 +1,45 @@ +dnl as-libtool.m4 0.1.4 + +dnl autostars m4 macro for libtool versioning + +dnl Thomas Vander Stichele <thomas at apestaart dot org> + +dnl $Id: as-libtool.m4,v 1.6 2004/06/01 10:04:44 thomasvs Exp $ + +dnl AS_LIBTOOL(PREFIX, CURRENT, REVISION, AGE, [RELEASE]) + +dnl example +dnl AS_LIBTOOL(GST, 2, 0, 0) + +dnl this macro +dnl - defines [$PREFIX]_CURRENT, REVISION and AGE +dnl - defines [$PREFIX]_LIBVERSION +dnl - defines [$PREFIX]_LT_LDFLAGS to set versioning +dnl - AC_SUBST's them all + +dnl if RELEASE is given, then add a -release option to the LDFLAGS +dnl with the given release version +dnl then use [$PREFIX]_LT_LDFLAGS in the relevant Makefile.am's + +dnl call AM_PROG_LIBTOOL after this call + +AC_DEFUN([AS_LIBTOOL], +[ + [$1]_CURRENT=[$2] + [$1]_REVISION=[$3] + [$1]_AGE=[$4] + [$1]_LIBVERSION=[$2]:[$3]:[$4] + AC_SUBST([$1]_CURRENT) + AC_SUBST([$1]_REVISION) + AC_SUBST([$1]_AGE) + AC_SUBST([$1]_LIBVERSION) + + [$1]_LT_LDFLAGS="$[$1]_LT_LDFLAGS -version-info $[$1]_LIBVERSION" + if test ! -z "[$5]" + then + [$1]_LT_LDFLAGS="$[$1]_LT_LDFLAGS -release [$5]" + fi + AC_SUBST([$1]_LT_LDFLAGS) + + AC_LIBTOOL_DLOPEN +]) diff --git a/common/m4/as-python.m4 b/common/m4/as-python.m4 new file mode 100755 index 0000000..eb9b175 --- /dev/null +++ b/common/m4/as-python.m4 @@ -0,0 +1,152 @@ +## ------------------------ +## Python file handling +## From Andrew Dalke +## Updated by James Henstridge +## Updated by Andy Wingo to loop through possible pythons +## ------------------------ + +# AS_PATH_PYTHON([MINIMUM-VERSION]) + +# Adds support for distributing Python modules and packages. To +# install modules, copy them to $(pythondir), using the python_PYTHON +# automake variable. To install a package with the same name as the +# automake package, install to $(pkgpythondir), or use the +# pkgpython_PYTHON automake variable. + +# The variables $(pyexecdir) and $(pkgpyexecdir) are provided as +# locations to install python extension modules (shared libraries). +# Another macro is required to find the appropriate flags to compile +# extension modules. + +# If your package is configured with a different prefix to python, +# users will have to add the install directory to the PYTHONPATH +# environment variable, or create a .pth file (see the python +# documentation for details). + +# If the MINIMUM-VERSION argument is passed, AS_PATH_PYTHON will +# cause an error if the version of python installed on the system +# doesn't meet the requirement. MINIMUM-VERSION should consist of +# numbers and dots only. + +# Updated to loop over all possible python binaries by Andy Wingo +# <wingo@pobox.com> +# Updated to only warn and unset PYTHON if no good one is found + +AC_DEFUN([AS_PATH_PYTHON], + [ + dnl Find a version of Python. I could check for python versions 1.4 + dnl or earlier, but the default installation locations changed from + dnl $prefix/lib/site-python in 1.4 to $prefix/lib/python1.5/site-packages + dnl in 1.5, and I don't want to maintain that logic. + + dnl should we do the version check? + PYTHON_CANDIDATES="python python2.2 python2.1 python2.0 python2 \ + python1.6 python1.5" + ifelse([$1],[], + [AC_PATH_PROG(PYTHON, $PYTHON_CANDIDATES)], + [ + AC_MSG_NOTICE(Looking for Python version >= $1) + changequote(<<, >>)dnl + prog=" +import sys, string +minver = '$1' +# split string by '.' and convert to numeric +minver_info = map(string.atoi, string.split(minver, '.')) +# we can now do comparisons on the two lists: +if sys.version_info >= tuple(minver_info): + sys.exit(0) +else: + sys.exit(1)" + changequote([, ])dnl + + python_good=false + for python_candidate in $PYTHON_CANDIDATES; do + unset PYTHON + AC_PATH_PROG(PYTHON, $python_candidate) 1> /dev/null 2> /dev/null + + if test "x$PYTHON" = "x"; then continue; fi + + if $PYTHON -c "$prog" 1>&AC_FD_CC 2>&AC_FD_CC; then + AC_MSG_CHECKING(["$PYTHON":]) + AC_MSG_RESULT([okay]) + python_good=true + break; + else + dnl clear the cache val + unset ac_cv_path_PYTHON + fi + done + ]) + + if test "$python_good" != "true"; then + AC_MSG_WARN([No suitable version of python found]) + PYTHON= + else + + AC_MSG_CHECKING([local Python configuration]) + + dnl Query Python for its version number. Getting [:3] seems to be + dnl the best way to do this; it's what "site.py" does in the standard + dnl library. Need to change quote character because of [:3] + + AC_SUBST(PYTHON_VERSION) + changequote(<<, >>)dnl + PYTHON_VERSION=`$PYTHON -c "import sys; print sys.version[:3]"` + changequote([, ])dnl + + + dnl Use the values of $prefix and $exec_prefix for the corresponding + dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made + dnl distinct variables so they can be overridden if need be. However, + dnl general consensus is that you shouldn't need this ability. + + AC_SUBST(PYTHON_PREFIX) + PYTHON_PREFIX='${prefix}' + + AC_SUBST(PYTHON_EXEC_PREFIX) + PYTHON_EXEC_PREFIX='${exec_prefix}' + + dnl At times (like when building shared libraries) you may want + dnl to know which OS platform Python thinks this is. + + AC_SUBST(PYTHON_PLATFORM) + PYTHON_PLATFORM=`$PYTHON -c "import sys; print sys.platform"` + + + dnl Set up 4 directories: + + dnl pythondir -- where to install python scripts. This is the + dnl site-packages directory, not the python standard library + dnl directory like in previous automake betas. This behaviour + dnl is more consistent with lispdir.m4 for example. + dnl + dnl Also, if the package prefix isn't the same as python's prefix, + dnl then the old $(pythondir) was pretty useless. + + AC_SUBST(pythondir) + pythondir=$PYTHON_PREFIX"/lib/python"$PYTHON_VERSION/site-packages + + dnl pkgpythondir -- $PACKAGE directory under pythondir. Was + dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is + dnl more consistent with the rest of automake. + dnl Maybe this should be put in python.am? + + AC_SUBST(pkgpythondir) + pkgpythondir=\${pythondir}/$PACKAGE + + dnl pyexecdir -- directory for installing python extension modules + dnl (shared libraries) Was PYTHON_SITE_EXEC in previous betas. + + AC_SUBST(pyexecdir) + pyexecdir=$PYTHON_EXEC_PREFIX"/lib/python"$PYTHON_VERSION/site-packages + + dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE) + dnl Maybe this should be put in python.am? + + AC_SUBST(pkgpyexecdir) + pkgpyexecdir=\${pyexecdir}/$PACKAGE + + AC_MSG_RESULT([looks good]) + + fi +]) diff --git a/common/m4/as-scrub-include.m4 b/common/m4/as-scrub-include.m4 new file mode 100755 index 0000000..96dfb8f --- /dev/null +++ b/common/m4/as-scrub-include.m4 @@ -0,0 +1,36 @@ +dnl as-scrub-include.m4 0.0.4 + +dnl autostars m4 macro for scrubbing CFLAGS of system include dirs +dnl because gcc 3.x complains about including system including dirs + +dnl Thomas Vander Stichele <thomas at apestaart dot org> + +dnl $Id: as-scrub-include.m4,v 1.5 2004/06/12 08:19:09 thomasvs Exp $ + +dnl This macro uses output of cpp -v and expects it to contain text that +dnl looks a little bit like this: +dnl #include <...> search starts here: +dnl /usr/local/include +dnl /usr/lib/gcc-lib/i386-redhat-linux/3.2/include +dnl /usr/include +dnl End of search list. + +dnl AS_SCRUB_INCLUDE(VAR) +dnl example +dnl AS_SCRUB_INCLUDE(CFLAGS) +dnl will remove all system include dirs from the given CFLAGS + +AC_DEFUN([AS_SCRUB_INCLUDE], +[ + GIVEN_CFLAGS=$[$1] + INCLUDE_DIRS=`echo | cpp -v 2>&1` + + dnl remove everything from this output between the "starts here" and "End of" + dnl line + INCLUDE_DIRS=`echo $INCLUDE_DIRS | sed -e 's/.*<...> search starts here://' | sed -e 's/End of search list.*//'` + for dir in $INCLUDE_DIRS; do + dnl use "" as the sed script so $dir gets expanded + GIVEN_CFLAGS=`echo $GIVEN_CFLAGS | sed -e "s#-I$dir ##"` + done + [$1]=$GIVEN_CFLAGS +]) diff --git a/common/m4/as-version.m4 b/common/m4/as-version.m4 new file mode 100755 index 0000000..a5b4399 --- /dev/null +++ b/common/m4/as-version.m4 @@ -0,0 +1,71 @@ +dnl as-version.m4 0.2.0 + +dnl autostars m4 macro for versioning + +dnl Thomas Vander Stichele <thomas at apestaart dot org> + +dnl $Id: as-version.m4,v 1.4 2004/06/01 09:40:05 thomasvs Exp $ + +dnl AS_VERSION + +dnl example +dnl AS_VERSION + +dnl this macro +dnl - AC_SUBST's PACKAGE_VERSION_MAJOR, _MINOR, _MICRO +dnl - AC_SUBST's PACKAGE_VERSION_RELEASE, +dnl which can be used for rpm release fields +dnl - doesn't call AM_INIT_AUTOMAKE anymore because it prevents +dnl maintainer mode from running correctly +dnl +dnl don't forget to put #undef PACKAGE_VERSION_RELEASE in acconfig.h +dnl if you use acconfig.h + +AC_DEFUN([AS_VERSION], +[ + PACKAGE_VERSION_MAJOR=$(echo AC_PACKAGE_VERSION | cut -d'.' -f1) + PACKAGE_VERSION_MINOR=$(echo AC_PACKAGE_VERSION | cut -d'.' -f2) + PACKAGE_VERSION_MICRO=$(echo AC_PACKAGE_VERSION | cut -d'.' -f3) + + AC_SUBST(PACKAGE_VERSION_MAJOR) + AC_SUBST(PACKAGE_VERSION_MINOR) + AC_SUBST(PACKAGE_VERSION_MICRO) +]) + +dnl AS_NANO(ACTION-IF-NO-NANO, [ACTION-IF-NANO]) + +dnl requires AC_INIT to be called before +dnl For projects using a fourth or nano number in your versioning to indicate +dnl development or prerelease snapshots, this macro allows the build to be +dnl set up differently accordingly. + +dnl this macro: +dnl - parses AC_PACKAGE_VERSION, set by AC_INIT, and extracts the nano number +dnl - sets the variable PACKAGE_VERSION_NANO +dnl - sets the variable PACKAGE_VERSION_RELEASE, which can be used +dnl for rpm release fields +dnl - executes ACTION-IF-NO-NANO or ACTION-IF-NANO + +dnl example: +dnl AS_NANO(RELEASE="yes", RELEASE="no") + +AC_DEFUN([AS_NANO], +[ + AC_MSG_CHECKING(nano version) + + NANO=$(echo AC_PACKAGE_VERSION | cut -d'.' -f4) + + if test x"$NANO" = x || test "x$NANO" = "x0" ; then + AC_MSG_RESULT([0 (release)]) + NANO=0 + PACKAGE_VERSION_RELEASE=1 + ifelse([$1], , :, [$1]) + else + AC_MSG_RESULT($NANO) + PACKAGE_VERSION_RELEASE=0.`date +%Y%m%d.%H%M%S` + ifelse([$2], , :, [$2]) + fi + PACKAGE_VERSION_NANO=$NANO + AC_SUBST(PACKAGE_VERSION_NANO) + AC_SUBST(PACKAGE_VERSION_RELEASE) +]) diff --git a/common/m4/ax_create_stdint_h.m4 b/common/m4/ax_create_stdint_h.m4 new file mode 100755 index 0000000..13bf699 --- /dev/null +++ b/common/m4/ax_create_stdint_h.m4 @@ -0,0 +1,734 @@ +##### http://autoconf-archive.cryp.to/ax_create_stdint_h.html +# +# SYNOPSIS +# +# AX_CREATE_STDINT_H [( HEADER-TO-GENERATE [, HEDERS-TO-CHECK])] +# +# DESCRIPTION +# +# the "ISO C9X: 7.18 Integer types <stdint.h>" section requires the +# existence of an include file <stdint.h> that defines a set of +# typedefs, especially uint8_t,int32_t,uintptr_t. Many older +# installations will not provide this file, but some will have the +# very same definitions in <inttypes.h>. In other enviroments we can +# use the inet-types in <sys/types.h> which would define the typedefs +# int8_t and u_int8_t respectivly. +# +# This macros will create a local "_stdint.h" or the headerfile given +# as an argument. In many cases that file will just "#include +# <stdint.h>" or "#include <inttypes.h>", while in other environments +# it will provide the set of basic 'stdint's definitions/typedefs: +# +# int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,intptr_t,uintptr_t +# int_least32_t.. int_fast32_t.. intmax_t +# +# which may or may not rely on the definitions of other files, or +# using the AC_CHECK_SIZEOF macro to determine the actual sizeof each +# type. +# +# if your header files require the stdint-types you will want to +# create an installable file mylib-int.h that all your other +# installable header may include. So if you have a library package +# named "mylib", just use +# +# AX_CREATE_STDINT_H(mylib-int.h) +# +# in configure.ac and go to install that very header file in +# Makefile.am along with the other headers (mylib.h) - and the +# mylib-specific headers can simply use "#include <mylib-int.h>" to +# obtain the stdint-types. +# +# Remember, if the system already had a valid <stdint.h>, the +# generated file will include it directly. No need for fuzzy +# HAVE_STDINT_H things... (oops, GCC 4.2.x has deliberatly disabled +# its stdint.h for non-c99 compilation and the c99-mode is not the +# default. Therefore this macro will not use the compiler's stdint.h +# - please complain to the GCC developers). +# +# LAST MODIFICATION +# +# 2007-06-27 +# +# COPYLEFT +# +# Copyright (c) 2007 Guido U. Draheim <guidod@gmx.de> +# +# 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. +# +# As a special exception, the respective Autoconf Macro's copyright +# owner gives unlimited permission to copy, distribute and modify the +# configure scripts that are the output of Autoconf when processing +# the Macro. You need not follow the terms of the GNU General Public +# License when using or distributing such scripts, even though +# portions of the text of the Macro appear in them. The GNU General +# Public License (GPL) does govern all other use of the material that +# constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the +# Autoconf Macro released by the Autoconf Macro Archive. When you +# make and distribute a modified version of the Autoconf Macro, you +# may extend this special exception to the GPL to apply to your +# modified version as well. + +AC_DEFUN([AX_CHECK_DATA_MODEL],[ + AC_CHECK_SIZEOF(char) + AC_CHECK_SIZEOF(short) + AC_CHECK_SIZEOF(int) + AC_CHECK_SIZEOF(long) + AC_CHECK_SIZEOF(void*) + ac_cv_char_data_model="" + ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_char" + ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_short" + ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_int" + ac_cv_long_data_model="" + ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_int" + ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_long" + ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_voidp" + AC_MSG_CHECKING([data model]) + case "$ac_cv_char_data_model/$ac_cv_long_data_model" in + 122/242) ac_cv_data_model="IP16" ; n="standard 16bit machine" ;; + 122/244) ac_cv_data_model="LP32" ; n="standard 32bit machine" ;; + 122/*) ac_cv_data_model="i16" ; n="unusual int16 model" ;; + 124/444) ac_cv_data_model="ILP32" ; n="standard 32bit unixish" ;; + 124/488) ac_cv_data_model="LP64" ; n="standard 64bit unixish" ;; + 124/448) ac_cv_data_model="LLP64" ; n="unusual 64bit unixish" ;; + 124/*) ac_cv_data_model="i32" ; n="unusual int32 model" ;; + 128/888) ac_cv_data_model="ILP64" ; n="unusual 64bit numeric" ;; + 128/*) ac_cv_data_model="i64" ; n="unusual int64 model" ;; + 222/*2) ac_cv_data_model="DSP16" ; n="strict 16bit dsptype" ;; + 333/*3) ac_cv_data_model="DSP24" ; n="strict 24bit dsptype" ;; + 444/*4) ac_cv_data_model="DSP32" ; n="strict 32bit dsptype" ;; + 666/*6) ac_cv_data_model="DSP48" ; n="strict 48bit dsptype" ;; + 888/*8) ac_cv_data_model="DSP64" ; n="strict 64bit dsptype" ;; + 222/*|333/*|444/*|666/*|888/*) : + ac_cv_data_model="iDSP" ; n="unusual dsptype" ;; + *) ac_cv_data_model="none" ; n="very unusual model" ;; + esac + AC_MSG_RESULT([$ac_cv_data_model ($ac_cv_long_data_model, $n)]) +]) + +dnl AX_CHECK_HEADER_STDINT_X([HEADERLIST][,ACTION-IF]) +AC_DEFUN([AX_CHECK_HEADER_STDINT_X],[ +AC_CACHE_CHECK([for stdint uintptr_t], [ac_cv_header_stdint_x],[ + ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h) + AC_MSG_RESULT([(..)]) + for i in m4_ifval([$1],[$1],[stdint.h inttypes.h sys/inttypes.h sys/types.h]) + do + unset ac_cv_type_uintptr_t + unset ac_cv_type_uint64_t + AC_CHECK_TYPE(uintptr_t,[ac_cv_header_stdint_x=$i],continue,[#include <$i>]) + AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>]) + m4_ifvaln([$2],[$2]) break + done + AC_MSG_CHECKING([for stdint uintptr_t]) + ]) +]) + +AC_DEFUN([AX_CHECK_HEADER_STDINT_O],[ +AC_CACHE_CHECK([for stdint uint32_t], [ac_cv_header_stdint_o],[ + ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h) + AC_MSG_RESULT([(..)]) + for i in m4_ifval([$1],[$1],[inttypes.h sys/inttypes.h sys/types.h stdint.h]) + do + unset ac_cv_type_uint32_t + unset ac_cv_type_uint64_t + AC_CHECK_TYPE(uint32_t,[ac_cv_header_stdint_o=$i],continue,[#include <$i>]) + AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>]) + m4_ifvaln([$2],[$2]) break + break; + done + AC_MSG_CHECKING([for stdint uint32_t]) + ]) +]) + +AC_DEFUN([AX_CHECK_HEADER_STDINT_U],[ +AC_CACHE_CHECK([for stdint u_int32_t], [ac_cv_header_stdint_u],[ + ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h) + AC_MSG_RESULT([(..)]) + for i in m4_ifval([$1],[$1],[sys/types.h inttypes.h sys/inttypes.h]) ; do + unset ac_cv_type_u_int32_t + unset ac_cv_type_u_int64_t + AC_CHECK_TYPE(u_int32_t,[ac_cv_header_stdint_u=$i],continue,[#include <$i>]) + AC_CHECK_TYPE(u_int64_t,[and64="/u_int64_t"],[and64=""],[#include<$i>]) + m4_ifvaln([$2],[$2]) break + break; + done + AC_MSG_CHECKING([for stdint u_int32_t]) + ]) +]) + +AC_DEFUN([AX_CREATE_STDINT_H], +[# ------ AX CREATE STDINT H ------------------------------------- +AC_MSG_CHECKING([for stdint types]) +ac_stdint_h=`echo ifelse($1, , _stdint.h, $1)` +# try to shortcircuit - if the default include path of the compiler +# can find a "stdint.h" header then we assume that all compilers can. +AC_CACHE_VAL([ac_cv_header_stdint_t],[ +old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS="" +old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS="" +old_CFLAGS="$CFLAGS" ; CFLAGS="" +AC_TRY_COMPILE([#include <stdint.h>],[int_least32_t v = 0;], +[ac_cv_stdint_result="(assuming C99 compatible system)" + ac_cv_header_stdint_t="stdint.h"; ], +[ac_cv_header_stdint_t=""]) +if test "$GCC" = "yes" && test ".$ac_cv_header_stdint_t" = "."; then +CFLAGS="-std=c99" +AC_TRY_COMPILE([#include <stdint.h>],[int_least32_t v = 0;], +[AC_MSG_WARN(your GCC compiler has a defunct stdint.h for its default-mode)]) +fi +CXXFLAGS="$old_CXXFLAGS" +CPPFLAGS="$old_CPPFLAGS" +CFLAGS="$old_CFLAGS" ]) + +v="... $ac_cv_header_stdint_h" +if test "$ac_stdint_h" = "stdint.h" ; then + AC_MSG_RESULT([(are you sure you want them in ./stdint.h?)]) +elif test "$ac_stdint_h" = "inttypes.h" ; then + AC_MSG_RESULT([(are you sure you want them in ./inttypes.h?)]) +elif test "_$ac_cv_header_stdint_t" = "_" ; then + AC_MSG_RESULT([(putting them into $ac_stdint_h)$v]) +else + ac_cv_header_stdint="$ac_cv_header_stdint_t" + AC_MSG_RESULT([$ac_cv_header_stdint (shortcircuit)]) +fi + +if test "_$ac_cv_header_stdint_t" = "_" ; then # can not shortcircuit.. + +dnl .....intro message done, now do a few system checks..... +dnl btw, all old CHECK_TYPE macros do automatically "DEFINE" a type, +dnl therefore we use the autoconf implementation detail CHECK_TYPE_NEW +dnl instead that is triggered with 3 or more arguments (see types.m4) + +inttype_headers=`echo $2 | sed -e 's/,/ /g'` + +ac_cv_stdint_result="(no helpful system typedefs seen)" +AX_CHECK_HEADER_STDINT_X(dnl + stdint.h inttypes.h sys/inttypes.h $inttype_headers, + ac_cv_stdint_result="(seen uintptr_t$and64 in $i)") + +if test "_$ac_cv_header_stdint_x" = "_" ; then +AX_CHECK_HEADER_STDINT_O(dnl, + inttypes.h sys/inttypes.h stdint.h $inttype_headers, + ac_cv_stdint_result="(seen uint32_t$and64 in $i)") +fi + +if test "_$ac_cv_header_stdint_x" = "_" ; then +if test "_$ac_cv_header_stdint_o" = "_" ; then +AX_CHECK_HEADER_STDINT_U(dnl, + sys/types.h inttypes.h sys/inttypes.h $inttype_headers, + ac_cv_stdint_result="(seen u_int32_t$and64 in $i)") +fi fi + +dnl if there was no good C99 header file, do some typedef checks... +if test "_$ac_cv_header_stdint_x" = "_" ; then + AC_MSG_CHECKING([for stdint datatype model]) + AC_MSG_RESULT([(..)]) + AX_CHECK_DATA_MODEL +fi + +if test "_$ac_cv_header_stdint_x" != "_" ; then + ac_cv_header_stdint="$ac_cv_header_stdint_x" +elif test "_$ac_cv_header_stdint_o" != "_" ; then + ac_cv_header_stdint="$ac_cv_header_stdint_o" +elif test "_$ac_cv_header_stdint_u" != "_" ; then + ac_cv_header_stdint="$ac_cv_header_stdint_u" +else + ac_cv_header_stdint="stddef.h" +fi + +AC_MSG_CHECKING([for extra inttypes in chosen header]) +AC_MSG_RESULT([($ac_cv_header_stdint)]) +dnl see if int_least and int_fast types are present in _this_ header. +unset ac_cv_type_int_least32_t +unset ac_cv_type_int_fast32_t +AC_CHECK_TYPE(int_least32_t,,,[#include <$ac_cv_header_stdint>]) +AC_CHECK_TYPE(int_fast32_t,,,[#include<$ac_cv_header_stdint>]) +AC_CHECK_TYPE(intmax_t,,,[#include <$ac_cv_header_stdint>]) + +fi # shortcircut to system "stdint.h" +# ------------------ PREPARE VARIABLES ------------------------------ +if test "$GCC" = "yes" ; then +ac_cv_stdint_message="using gnu compiler "`$CC --version | head -1` +else +ac_cv_stdint_message="using $CC" +fi + +AC_MSG_RESULT([make use of $ac_cv_header_stdint in $ac_stdint_h dnl +$ac_cv_stdint_result]) + +dnl ----------------------------------------------------------------- +# ----------------- DONE inttypes.h checks START header ------------- +AC_CONFIG_COMMANDS([$ac_stdint_h],[ +AC_MSG_NOTICE(creating $ac_stdint_h : $_ac_stdint_h) +ac_stdint=$tmp/_stdint.h + +echo "#ifndef" $_ac_stdint_h >$ac_stdint +echo "#define" $_ac_stdint_h "1" >>$ac_stdint +echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint +echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint +echo "/* generated $ac_cv_stdint_message */" >>$ac_stdint +if test "_$ac_cv_header_stdint_t" != "_" ; then +echo "#define _STDINT_HAVE_STDINT_H" "1" >>$ac_stdint +echo "#include <stdint.h>" >>$ac_stdint +echo "#endif" >>$ac_stdint +echo "#endif" >>$ac_stdint +else + +cat >>$ac_stdint <<STDINT_EOF + +/* ................... shortcircuit part ........................... */ + +#if defined HAVE_STDINT_H || defined _STDINT_HAVE_STDINT_H +#include <stdint.h> +#else +#include <stddef.h> + +/* .................... configured part ............................ */ + +STDINT_EOF + +echo "/* whether we have a C99 compatible stdint header file */" >>$ac_stdint +if test "_$ac_cv_header_stdint_x" != "_" ; then + ac_header="$ac_cv_header_stdint_x" + echo "#define _STDINT_HEADER_INTPTR" '"'"$ac_header"'"' >>$ac_stdint +else + echo "/* #undef _STDINT_HEADER_INTPTR */" >>$ac_stdint +fi + +echo "/* whether we have a C96 compatible inttypes header file */" >>$ac_stdint +if test "_$ac_cv_header_stdint_o" != "_" ; then + ac_header="$ac_cv_header_stdint_o" + echo "#define _STDINT_HEADER_UINT32" '"'"$ac_header"'"' >>$ac_stdint +else + echo "/* #undef _STDINT_HEADER_UINT32 */" >>$ac_stdint +fi + +echo "/* whether we have a BSD compatible inet types header */" >>$ac_stdint +if test "_$ac_cv_header_stdint_u" != "_" ; then + ac_header="$ac_cv_header_stdint_u" + echo "#define _STDINT_HEADER_U_INT32" '"'"$ac_header"'"' >>$ac_stdint +else + echo "/* #undef _STDINT_HEADER_U_INT32 */" >>$ac_stdint +fi + +echo "" >>$ac_stdint + +if test "_$ac_header" != "_" ; then if test "$ac_header" != "stddef.h" ; then + echo "#include <$ac_header>" >>$ac_stdint + echo "" >>$ac_stdint +fi fi + +echo "/* which 64bit typedef has been found */" >>$ac_stdint +if test "$ac_cv_type_uint64_t" = "yes" ; then +echo "#define _STDINT_HAVE_UINT64_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_UINT64_T */" >>$ac_stdint +fi +if test "$ac_cv_type_u_int64_t" = "yes" ; then +echo "#define _STDINT_HAVE_U_INT64_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_U_INT64_T */" >>$ac_stdint +fi +echo "" >>$ac_stdint + +echo "/* which type model has been detected */" >>$ac_stdint +if test "_$ac_cv_char_data_model" != "_" ; then +echo "#define _STDINT_CHAR_MODEL" "$ac_cv_char_data_model" >>$ac_stdint +echo "#define _STDINT_LONG_MODEL" "$ac_cv_long_data_model" >>$ac_stdint +else +echo "/* #undef _STDINT_CHAR_MODEL // skipped */" >>$ac_stdint +echo "/* #undef _STDINT_LONG_MODEL // skipped */" >>$ac_stdint +fi +echo "" >>$ac_stdint + +echo "/* whether int_least types were detected */" >>$ac_stdint +if test "$ac_cv_type_int_least32_t" = "yes"; then +echo "#define _STDINT_HAVE_INT_LEAST32_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_INT_LEAST32_T */" >>$ac_stdint +fi +echo "/* whether int_fast types were detected */" >>$ac_stdint +if test "$ac_cv_type_int_fast32_t" = "yes"; then +echo "#define _STDINT_HAVE_INT_FAST32_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_INT_FAST32_T */" >>$ac_stdint +fi +echo "/* whether intmax_t type was detected */" >>$ac_stdint +if test "$ac_cv_type_intmax_t" = "yes"; then +echo "#define _STDINT_HAVE_INTMAX_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_INTMAX_T */" >>$ac_stdint +fi +echo "" >>$ac_stdint + + cat >>$ac_stdint <<STDINT_EOF +/* .................... detections part ............................ */ + +/* whether we need to define bitspecific types from compiler base types */ +#ifndef _STDINT_HEADER_INTPTR +#ifndef _STDINT_HEADER_UINT32 +#ifndef _STDINT_HEADER_U_INT32 +#define _STDINT_NEED_INT_MODEL_T +#else +#define _STDINT_HAVE_U_INT_TYPES +#endif +#endif +#endif + +#ifdef _STDINT_HAVE_U_INT_TYPES +#undef _STDINT_NEED_INT_MODEL_T +#endif + +#ifdef _STDINT_CHAR_MODEL +#if _STDINT_CHAR_MODEL+0 == 122 || _STDINT_CHAR_MODEL+0 == 124 +#ifndef _STDINT_BYTE_MODEL +#define _STDINT_BYTE_MODEL 12 +#endif +#endif +#endif + +#ifndef _STDINT_HAVE_INT_LEAST32_T +#define _STDINT_NEED_INT_LEAST_T +#endif + +#ifndef _STDINT_HAVE_INT_FAST32_T +#define _STDINT_NEED_INT_FAST_T +#endif + +#ifndef _STDINT_HEADER_INTPTR +#define _STDINT_NEED_INTPTR_T +#ifndef _STDINT_HAVE_INTMAX_T +#define _STDINT_NEED_INTMAX_T +#endif +#endif + + +/* .................... definition part ............................ */ + +/* some system headers have good uint64_t */ +#ifndef _HAVE_UINT64_T +#if defined _STDINT_HAVE_UINT64_T || defined HAVE_UINT64_T +#define _HAVE_UINT64_T +#elif defined _STDINT_HAVE_U_INT64_T || defined HAVE_U_INT64_T +#define _HAVE_UINT64_T +typedef u_int64_t uint64_t; +#endif +#endif + +#ifndef _HAVE_UINT64_T +/* .. here are some common heuristics using compiler runtime specifics */ +#if defined __STDC_VERSION__ && defined __STDC_VERSION__ >= 199901L +#define _HAVE_UINT64_T +#define _HAVE_LONGLONG_UINT64_T +typedef long long int64_t; +typedef unsigned long long uint64_t; + +#elif !defined __STRICT_ANSI__ +#if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__ +#define _HAVE_UINT64_T +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; + +#elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__ +/* note: all ELF-systems seem to have loff-support which needs 64-bit */ +#if !defined _NO_LONGLONG +#define _HAVE_UINT64_T +#define _HAVE_LONGLONG_UINT64_T +typedef long long int64_t; +typedef unsigned long long uint64_t; +#endif + +#elif defined __alpha || (defined __mips && defined _ABIN32) +#if !defined _NO_LONGLONG +typedef long int64_t; +typedef unsigned long uint64_t; +#endif + /* compiler/cpu type to define int64_t */ +#endif +#endif +#endif + +#if defined _STDINT_HAVE_U_INT_TYPES +/* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */ +typedef u_int8_t uint8_t; +typedef u_int16_t uint16_t; +typedef u_int32_t uint32_t; + +/* glibc compatibility */ +#ifndef __int8_t_defined +#define __int8_t_defined +#endif +#endif + +#ifdef _STDINT_NEED_INT_MODEL_T +/* we must guess all the basic types. Apart from byte-adressable system, */ +/* there a few 32-bit-only dsp-systems that we guard with BYTE_MODEL 8-} */ +/* (btw, those nibble-addressable systems are way off, or so we assume) */ + +dnl /* have a look at "64bit and data size neutrality" at */ +dnl /* http://unix.org/version2/whatsnew/login_64bit.html */ +dnl /* (the shorthand "ILP" types always have a "P" part) */ + +#if defined _STDINT_BYTE_MODEL +#if _STDINT_LONG_MODEL+0 == 242 +/* 2:4:2 = IP16 = a normal 16-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef long int32_t; +#endif +#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL == 444 +/* 2:4:4 = LP32 = a 32-bit system derived from a 16-bit */ +/* 4:4:4 = ILP32 = a normal 32-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef int int32_t; +#endif +#elif _STDINT_LONG_MODEL+0 == 484 || _STDINT_LONG_MODEL+0 == 488 +/* 4:8:4 = IP32 = a 32-bit system prepared for 64-bit */ +/* 4:8:8 = LP64 = a normal 64-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef int int32_t; +#endif +/* this system has a "long" of 64bit */ +#ifndef _HAVE_UINT64_T +#define _HAVE_UINT64_T +typedef unsigned long uint64_t; +typedef long int64_t; +#endif +#elif _STDINT_LONG_MODEL+0 == 448 +/* LLP64 a 64-bit system derived from a 32-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef int int32_t; +#endif +/* assuming the system has a "long long" */ +#ifndef _HAVE_UINT64_T +#define _HAVE_UINT64_T +#define _HAVE_LONGLONG_UINT64_T +typedef unsigned long long uint64_t; +typedef long long int64_t; +#endif +#else +#define _STDINT_NO_INT32_T +#endif +#else +#define _STDINT_NO_INT8_T +#define _STDINT_NO_INT32_T +#endif +#endif + +/* + * quote from SunOS-5.8 sys/inttypes.h: + * Use at your own risk. As of February 1996, the committee is squarely + * behind the fixed sized types; the "least" and "fast" types are still being + * discussed. The probability that the "fast" types may be removed before + * the standard is finalized is high enough that they are not currently + * implemented. + */ + +#if defined _STDINT_NEED_INT_LEAST_T +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +#ifdef _HAVE_UINT64_T +typedef int64_t int_least64_t; +#endif + +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +#ifdef _HAVE_UINT64_T +typedef uint64_t uint_least64_t; +#endif + /* least types */ +#endif + +#if defined _STDINT_NEED_INT_FAST_T +typedef int8_t int_fast8_t; +typedef int int_fast16_t; +typedef int32_t int_fast32_t; +#ifdef _HAVE_UINT64_T +typedef int64_t int_fast64_t; +#endif + +typedef uint8_t uint_fast8_t; +typedef unsigned uint_fast16_t; +typedef uint32_t uint_fast32_t; +#ifdef _HAVE_UINT64_T +typedef uint64_t uint_fast64_t; +#endif + /* fast types */ +#endif + +#ifdef _STDINT_NEED_INTMAX_T +#ifdef _HAVE_UINT64_T +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; +#else +typedef long intmax_t; +typedef unsigned long uintmax_t; +#endif +#endif + +#ifdef _STDINT_NEED_INTPTR_T +#ifndef __intptr_t_defined +#define __intptr_t_defined +/* we encourage using "long" to store pointer values, never use "int" ! */ +#if _STDINT_LONG_MODEL+0 == 242 || _STDINT_LONG_MODEL+0 == 484 +typedef unsigned int uintptr_t; +typedef int intptr_t; +#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL+0 == 444 +typedef unsigned long uintptr_t; +typedef long intptr_t; +#elif _STDINT_LONG_MODEL+0 == 448 && defined _HAVE_UINT64_T +typedef uint64_t uintptr_t; +typedef int64_t intptr_t; +#else /* matches typical system types ILP32 and LP64 - but not IP16 or LLP64 */ +typedef unsigned long uintptr_t; +typedef long intptr_t; +#endif +#endif +#endif + +/* The ISO C99 standard specifies that in C++ implementations these + should only be defined if explicitly requested. */ +#if !defined __cplusplus || defined __STDC_CONSTANT_MACROS +#ifndef UINT32_C + +/* Signed. */ +# define INT8_C(c) c +# define INT16_C(c) c +# define INT32_C(c) c +# ifdef _HAVE_LONGLONG_UINT64_T +# define INT64_C(c) c ## L +# else +# define INT64_C(c) c ## LL +# endif + +/* Unsigned. */ +# define UINT8_C(c) c ## U +# define UINT16_C(c) c ## U +# define UINT32_C(c) c ## U +# ifdef _HAVE_LONGLONG_UINT64_T +# define UINT64_C(c) c ## UL +# else +# define UINT64_C(c) c ## ULL +# endif + +/* Maximal type. */ +# ifdef _HAVE_LONGLONG_UINT64_T +# define INTMAX_C(c) c ## L +# define UINTMAX_C(c) c ## UL +# else +# define INTMAX_C(c) c ## LL +# define UINTMAX_C(c) c ## ULL +# endif + + /* literalnumbers */ +#endif +#endif + +/* These limits are merily those of a two complement byte-oriented system */ + +/* Minimum of signed integral types. */ +# define INT8_MIN (-128) +# define INT16_MIN (-32767-1) +# define INT32_MIN (-2147483647-1) +# define INT64_MIN (-__INT64_C(9223372036854775807)-1) +/* Maximum of signed integral types. */ +# define INT8_MAX (127) +# define INT16_MAX (32767) +# define INT32_MAX (2147483647) +# define INT64_MAX (__INT64_C(9223372036854775807)) + +/* Maximum of unsigned integral types. */ +# define UINT8_MAX (255) +# define UINT16_MAX (65535) +# define UINT32_MAX (4294967295U) +# define UINT64_MAX (__UINT64_C(18446744073709551615)) + +/* Minimum of signed integral types having a minimum size. */ +# define INT_LEAST8_MIN INT8_MIN +# define INT_LEAST16_MIN INT16_MIN +# define INT_LEAST32_MIN INT32_MIN +# define INT_LEAST64_MIN INT64_MIN +/* Maximum of signed integral types having a minimum size. */ +# define INT_LEAST8_MAX INT8_MAX +# define INT_LEAST16_MAX INT16_MAX +# define INT_LEAST32_MAX INT32_MAX +# define INT_LEAST64_MAX INT64_MAX + +/* Maximum of unsigned integral types having a minimum size. */ +# define UINT_LEAST8_MAX UINT8_MAX +# define UINT_LEAST16_MAX UINT16_MAX +# define UINT_LEAST32_MAX UINT32_MAX +# define UINT_LEAST64_MAX UINT64_MAX + + /* shortcircuit*/ +#endif + /* once */ +#endif +#endif +STDINT_EOF +fi + if cmp -s $ac_stdint_h $ac_stdint 2>/dev/null; then + AC_MSG_NOTICE([$ac_stdint_h is unchanged]) + else + ac_dir=`AS_DIRNAME(["$ac_stdint_h"])` + AS_MKDIR_P(["$ac_dir"]) + rm -f $ac_stdint_h + mv $ac_stdint $ac_stdint_h + fi +],[# variables for create stdint.h replacement +PACKAGE="$PACKAGE" +VERSION="$VERSION" +ac_stdint_h="$ac_stdint_h" +_ac_stdint_h=AS_TR_CPP(_$PACKAGE-$ac_stdint_h) +ac_cv_stdint_message="$ac_cv_stdint_message" +ac_cv_header_stdint_t="$ac_cv_header_stdint_t" +ac_cv_header_stdint_x="$ac_cv_header_stdint_x" +ac_cv_header_stdint_o="$ac_cv_header_stdint_o" +ac_cv_header_stdint_u="$ac_cv_header_stdint_u" +ac_cv_type_uint64_t="$ac_cv_type_uint64_t" +ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t" +ac_cv_char_data_model="$ac_cv_char_data_model" +ac_cv_long_data_model="$ac_cv_long_data_model" +ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t" +ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t" +ac_cv_type_intmax_t="$ac_cv_type_intmax_t" +]) +]) diff --git a/common/m4/check.m4 b/common/m4/check.m4 new file mode 100755 index 0000000..19784ae --- /dev/null +++ b/common/m4/check.m4 @@ -0,0 +1,181 @@ +dnl _AM_TRY_CHECK(MINIMUM-VERSION, EXTRA-CFLAGS, EXTRA-LIBS, CHECK-LIB-NAME +dnl [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl Test for check, and define CHECK_CFLAGS and CHECK_LIBS +dnl Done this way because of the brokenness that is +dnl https://launchpad.net/distros/ubuntu/+source/check/+bug/5840 +dnl + +AC_DEFUN([_AM_TRY_CHECK], +[ + min_check_version=$1 + extra_cflags=$2 + extra_libs=$3 + check_lib_name=$4 + + CHECK_CFLAGS="$extra_cflags" + CHECK_LIBS="$extra_libs -l$check_lib_name" + + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + + CFLAGS="$CFLAGS $CHECK_CFLAGS" + LIBS="$CHECK_LIBS $LIBS" + + AC_MSG_CHECKING(for check named $check_lib_name - version >= $min_check_version) + + rm -f conf.check-test + dnl unset no_check, since in our second run it would have been set to yes + dnl before + no_check= + AC_TRY_RUN([ +#include <stdio.h> +#include <stdlib.h> + +#include <check.h> + +int main () +{ + int major, minor, micro; + char *tmp_version; + + system ("touch conf.check-test"); + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = strdup("$min_check_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_check_version"); + return 1; + } + + if ((CHECK_MAJOR_VERSION != check_major_version) || + (CHECK_MINOR_VERSION != check_minor_version) || + (CHECK_MICRO_VERSION != check_micro_version)) + { + printf("\n*** The check header file (version %d.%d.%d) does not match\n", + CHECK_MAJOR_VERSION, CHECK_MINOR_VERSION, CHECK_MICRO_VERSION); + printf("*** the check library (version %d.%d.%d).\n", + check_major_version, check_minor_version, check_micro_version); + return 1; + } + + if ((check_major_version > major) || + ((check_major_version == major) && (check_minor_version > minor)) || + ((check_major_version == major) && (check_minor_version == minor) && (check_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** An old version of check (%d.%d.%d) was found.\n", + check_major_version, check_minor_version, check_micro_version); + printf("*** You need a version of check being at least %d.%d.%d.\n", major, minor, micro); + printf("***\n"); + printf("*** If you have already installed a sufficiently new version, this error\n"); + printf("*** probably means that the wrong copy of the check library and header\n"); + printf("*** file is being found. Rerun configure with the --with-check=PATH option\n"); + printf("*** to specify the prefix where the correct version was installed.\n"); + } + + return 1; +} +],, no_check=yes, [echo $ac_n "cross compiling; assumed OK... $ac_c"]) + + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + + if test "x$no_check" = x ; then + AC_MSG_RESULT(yes) + ifelse([$5], , :, [$5]) + else + AC_MSG_RESULT(no) + if test -f conf.check-test ; then + : + else + echo "*** Could not run check test program, checking why..." + CFLAGS="$CFLAGS $CHECK_CFLAGS" + LIBS="$CHECK_LIBS $LIBS" + AC_TRY_LINK([ +#include <stdio.h> +#include <stdlib.h> + +#include <check.h> +], , [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding check. You'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], + [ echo "*** The test program failed to compile or link. See the file config.log for" + echo "*** the exact error that occured." ]) + + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + + CHECK_CFLAGS="" + CHECK_LIBS="" + + rm -f conf.check-test + ifelse([$6], , AC_MSG_ERROR([check not found]), [$6]) + fi +]) + + +dnl AM_PATH_CHECK([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for check, and define CHECK_CFLAGS and CHECK_LIBS +dnl + +AC_DEFUN([AM_PATH_CHECK], +[ + AC_ARG_WITH(check, + [ --with-check=PATH prefix where check is installed [default=auto]]) + + AC_ARG_WITH(checklibname, + AC_HELP_STRING([--with-check-lib-name=NAME], + [name of the PIC check library (default=check)])) + + min_check_version=ifelse([$1], ,0.8.2,$1) + + if test x$with_check = xno; then + AC_MSG_RESULT(disabled) + ifelse([$3], , AC_MSG_ERROR([disabling check is not supported]), [$3]) + else + if test "x$with_check" != x; then + CHECK_EXTRA_CFLAGS="-I$with_check/include" + CHECK_EXTRA_LIBS="-L$with_check/lib" + else + CHECK_EXTRA_CFLAGS="" + CHECK_EXTRA_LIBS="" + fi + + if test x$with_checklibname = x; then + _AM_TRY_CHECK($min_check_version, $CHECK_EXTRA_CFLAGS, $CHECK_EXTRA_LIBS, + check_pic, [have_check=true], [have_check=false]) + if test x$have_check = xtrue; then + ifelse([$2], , :, [$2]) + else + _AM_TRY_CHECK($min_check_version, $CHECK_EXTRA_CFLAGS, $CHECK_EXTRA_LIBS, + check, [have_check=true], [have_check=false]) + if test x$have_check = xtrue; then + ifelse([$2], , :, [$2]) + else + ifelse([$3], , AC_MSG_ERROR([check not found]), [$3]) + fi + fi + else + _AM_TRY_CHECK($min_check_version, $CHECK_EXTRA_CFLAGS, $CHECK_EXTRA_LIBS, + $with_checklibname, [have_check=true], [have_check=false]) + if test x$have_check = xtrue; then + ifelse([$2], , :, [$2]) + else + ifelse([$3], , AC_MSG_ERROR([check not found]), [$3]) + fi + fi + + AC_SUBST(CHECK_CFLAGS) + AC_SUBST(CHECK_LIBS) + rm -f conf.check-test + fi +]) diff --git a/common/m4/gettext.m4 b/common/m4/gettext.m4 new file mode 100755 index 0000000..45cad85 --- /dev/null +++ b/common/m4/gettext.m4 @@ -0,0 +1,587 @@ +# gettext.m4 serial 17 (gettext-0.11.5) +dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. +dnl Bruno Haible <haible@clisp.cons.org>, 2000-2002. + +dnl Macro to add for using GNU gettext. + +dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). +dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The +dnl default (if it is not specified or empty) is 'no-libtool'. +dnl INTLSYMBOL should be 'external' for packages with no intl directory, +dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. +dnl If INTLSYMBOL is 'use-libtool', then a libtool library +dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, +dnl depending on --{enable,disable}-{shared,static} and on the presence of +dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library +dnl $(top_builddir)/intl/libintl.a will be created. +dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext +dnl implementations (in libc or libintl) without the ngettext() function +dnl will be ignored. If NEEDSYMBOL is specified and is +dnl 'need-formatstring-macros', then GNU gettext implementations that don't +dnl support the ISO C 99 <inttypes.h> formatstring macros will be ignored. +dnl INTLDIR is used to find the intl libraries. If empty, +dnl the value `$(top_builddir)/intl/' is used. +dnl +dnl The result of the configuration is one of three cases: +dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled +dnl and used. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 2) GNU gettext has been found in the system's C library. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 3) No internationalization, always use English msgid. +dnl Catalog format: none +dnl Catalog extension: none +dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. +dnl The use of .gmo is historical (it was needed to avoid overwriting the +dnl GNU format catalogs when building on a platform with an X/Open gettext), +dnl but we keep it in order not to force irrelevant filename changes on the +dnl maintainers. +dnl +AC_DEFUN([AM_GNU_GETTEXT], +[ + dnl Argument checking. + ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , + [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT +])])])])]) + ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , + [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT +])])])]) + define(gt_included_intl, ifelse([$1], [external], [no], [yes])) + define(gt_libtool_suffix_prefix, ifelse([$1], [use-libtool], [l], [])) + + AC_REQUIRE([AM_PO_SUBDIRS])dnl + ifelse(gt_included_intl, yes, [ + AC_REQUIRE([AM_INTL_SUBDIR])dnl + ]) + + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Sometimes libintl requires libiconv, so first search for libiconv. + dnl Ideally we would do this search only after the + dnl if test "$USE_NLS" = "yes"; then + dnl if test "$gt_cv_func_gnugettext_libc" != "yes"; then + dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT + dnl the configure script would need to contain the same shell code + dnl again, outside any 'if'. There are two solutions: + dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. + dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. + dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not + dnl documented, we avoid it. + ifelse(gt_included_intl, yes, , [ + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + ]) + + AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE(nls, + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT($USE_NLS) + AC_SUBST(USE_NLS) + + ifelse(gt_included_intl, yes, [ + BUILD_INCLUDED_LIBINTL=no + USE_INCLUDED_LIBINTL=no + ]) + LIBINTL= + LTLIBINTL= + POSUB= + + dnl If we use NLS figure out what method + if test "$USE_NLS" = "yes"; then + gt_use_preinstalled_gnugettext=no + ifelse(gt_included_intl, yes, [ + AC_MSG_CHECKING([whether included gettext is requested]) + AC_ARG_WITH(included-gettext, + [ --with-included-gettext use the GNU gettext library included here], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) + AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + ]) + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If GNU gettext is available we use this. Else we have + dnl to fall back to GNU NLS library. + + dnl Add a version number to the cache macros. + define([gt_api_version], ifelse([$2], [need-formatstring-macros], 3, ifelse([$2], [need-ngettext], 2, 1))) + define([gt_cv_func_gnugettext_libc], [gt_cv_func_gnugettext]gt_api_version[_libc]) + define([gt_cv_func_gnugettext_libintl], [gt_cv_func_gnugettext]gt_api_version[_libintl]) + + AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc, + [AC_TRY_LINK([#include <libintl.h> +]ifelse([$2], [need-formatstring-macros], +[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +], [])[extern int _nl_msg_cat_cntr; +extern int *_nl_domain_bindings;], + [bindtextdomain ("", ""); +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings], + gt_cv_func_gnugettext_libc=yes, + gt_cv_func_gnugettext_libc=no)]) + + if test "$gt_cv_func_gnugettext_libc" != "yes"; then + dnl Sometimes libintl requires libiconv, so first search for libiconv. + ifelse(gt_included_intl, yes, , [ + AM_ICONV_LINK + ]) + dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL + dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) + dnl because that would add "-liconv" to LIBINTL and LTLIBINTL + dnl even if libiconv doesn't exist. + AC_LIB_LINKFLAGS_BODY([intl]) + AC_CACHE_CHECK([for GNU gettext in libintl], + gt_cv_func_gnugettext_libintl, + [gt_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCINTL" + gt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBINTL" + dnl Now see whether libintl exists and does not depend on libiconv. + AC_TRY_LINK([#include <libintl.h> +]ifelse([$2], [need-formatstring-macros], +[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +], [])[extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias ();], + [bindtextdomain ("", ""); +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], + gt_cv_func_gnugettext_libintl=yes, + gt_cv_func_gnugettext_libintl=no) + dnl Now see whether libintl exists and depends on libiconv. + if test "$gt_cv_func_gnugettext_libintl" != yes && test -n "$LIBICONV"; then + LIBS="$LIBS $LIBICONV" + AC_TRY_LINK([#include <libintl.h> +]ifelse([$2], [need-formatstring-macros], +[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +], [])[extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias ();], + [bindtextdomain ("", ""); +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], + [LIBINTL="$LIBINTL $LIBICONV" + LTLIBINTL="$LTLIBINTL $LTLIBICONV" + gt_cv_func_gnugettext_libintl=yes + ]) + fi + CPPFLAGS="$gt_save_CPPFLAGS" + LIBS="$gt_save_LIBS"]) + fi + + dnl If an already present or preinstalled GNU gettext() is found, + dnl use it. But if this macro is used in GNU gettext, and GNU + dnl gettext is already preinstalled in libintl, we update this + dnl libintl. (Cf. the install rule in intl/Makefile.in.) + if test "$gt_cv_func_gnugettext_libc" = "yes" \ + || { test "$gt_cv_func_gnugettext_libintl" = "yes" \ + && test "$PACKAGE" != gettext; }; then + gt_use_preinstalled_gnugettext=yes + else + dnl Reset the values set by searching for libintl. + LIBINTL= + LTLIBINTL= + INCINTL= + fi + + ifelse(gt_included_intl, yes, [ + if test "$gt_use_preinstalled_gnugettext" != "yes"; then + dnl GNU gettext is not found in the C library. + dnl Fall back on included GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions used to generate GNU NLS library. + INTLOBJS="\$(GETTOBJS)" + BUILD_INCLUDED_LIBINTL=yes + USE_INCLUDED_LIBINTL=yes + LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV" + LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV" + LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` + fi + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions to use GNU gettext tools. + CATOBJEXT=.gmo + fi + ]) + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + AC_DEFINE(ENABLE_NLS, 1, + [Define to 1 if translation of program messages to the user's native language + is requested.]) + else + USE_NLS=no + fi + fi + + if test "$USE_NLS" = "yes"; then + + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if test "$gt_cv_func_gnugettext_libintl" = "yes"; then + AC_MSG_CHECKING([how to link with libintl]) + AC_MSG_RESULT([$LIBINTL]) + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) + fi + + dnl For backward compatibility. Some packages may be using this. + AC_DEFINE(HAVE_GETTEXT, 1, + [Define if the GNU gettext() function is already present or preinstalled.]) + AC_DEFINE(HAVE_DCGETTEXT, 1, + [Define if the GNU dcgettext() function is already present or preinstalled.]) + fi + + dnl We need to process the po/ directory. + POSUB=po + fi + + ifelse(gt_included_intl, yes, [ + dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL + dnl to 'yes' because some of the testsuite requires it. + if test "$PACKAGE" = gettext; then + BUILD_INCLUDED_LIBINTL=yes + fi + + dnl Make all variables we use known to autoconf. + AC_SUBST(BUILD_INCLUDED_LIBINTL) + AC_SUBST(USE_INCLUDED_LIBINTL) + AC_SUBST(CATOBJEXT) + AC_SUBST(INTLOBJS) + + dnl For backward compatibility. Some configure.ins may be using this. + nls_cv_header_intl= + nls_cv_header_libgt= + + dnl For backward compatibility. Some Makefiles may be using this. + DATADIRNAME=share + AC_SUBST(DATADIRNAME) + + dnl For backward compatibility. Some Makefiles may be using this. + INSTOBJEXT=.mo + AC_SUBST(INSTOBJEXT) + + dnl For backward compatibility. Some Makefiles may be using this. + GENCAT=gencat + AC_SUBST(GENCAT) + + dnl Enable libtool support if the surrounding package wishes it. + INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix + AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX) + ]) + + dnl For backward compatibility. Some Makefiles may be using this. + INTLLIBS="$LIBINTL" + AC_SUBST(INTLLIBS) + + dnl Make all documented variables known to autoconf. + AC_SUBST(LIBINTL) + AC_SUBST(LTLIBINTL) + AC_SUBST(POSUB) +]) + + +dnl Checks for all prerequisites of the po subdirectory, +dnl except for USE_NLS. +AC_DEFUN([AM_PO_SUBDIRS], +[ + AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AM_MKINSTALLDIRS])dnl + + dnl Perform the following tests also if --disable-nls has been given, + dnl because they are needed for "make dist" to work. + + dnl Search for GNU msgfmt in the PATH. + dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. + dnl The second test excludes FreeBSD msgfmt. + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 && + (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + + dnl Search for GNU xgettext 0.11 or newer in the PATH. + dnl The first test excludes Solaris xgettext and early GNU xgettext versions. + dnl The second test excludes FreeBSD xgettext. + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [$ac_dir/$ac_word --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && + (if $ac_dir/$ac_word --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + dnl Remove leftover from FreeBSD xgettext call. + rm -f messages.po + + dnl Search for GNU msgmerge 0.11 or newer in the PATH. + AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, + [$ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1], :) + + dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. + dnl Test whether we really found GNU msgfmt. + if test "$GMSGFMT" != ":"; then + dnl If it is no GNU msgfmt we define it as : so that the + dnl Makefiles still can work. + if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && + (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + : ; + else + GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` + AC_MSG_RESULT( + [found $GMSGFMT program is not GNU msgfmt; ignore it]) + GMSGFMT=":" + fi + fi + + dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is no GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && + (if $XGETTEXT --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + : ; + else + AC_MSG_RESULT( + [found xgettext program is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + dnl Remove leftover from FreeBSD xgettext call. + rm -f messages.po + fi + + AC_OUTPUT_COMMANDS([ + for ac_file in $CONFIG_FILES; do + # Support "outfile[:infile[:infile...]]" + case "$ac_file" in + *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + esac + # PO directories have a Makefile.in generated from Makefile.in.in. + case "$ac_file" in */Makefile.in) + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then + rm -f "$ac_dir/POTFILES" + test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" + cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" + # ALL_LINGUAS, POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES depend + # on $ac_dir but don't depend on user-specified configuration + # parameters. + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + if test -n "$ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"` + # Hide the ALL_LINGUAS assigment from automake. + eval 'ALL_LINGUAS''=$ALL_LINGUAS_' + fi + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + GMOFILES= + UPDATEPOFILES= + DUMMYPOFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + done + fi + test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" + sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" + for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do + if test -f "$f"; then + case "$f" in + *.orig | *.bak | *~) ;; + *) cat "$f" >> "$ac_dir/Makefile" ;; + esac + fi + done + fi + ;; + esac + done], + [# Capture the value of obsolete ALL_LINGUAS because we need it to compute + # POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES, CATALOGS. But hide it + # from automake. + eval 'ALL_LINGUAS''="$ALL_LINGUAS"' + # Capture the value of LINGUAS because we need it to compute CATALOGS. + LINGUAS="${LINGUAS-%UNSET%}" + ]) +]) + + +dnl Checks for all prerequisites of the intl subdirectory, +dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, +dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. +AC_DEFUN([AM_INTL_SUBDIR], +[ + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AM_MKINSTALLDIRS])dnl + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_CANONICAL_HOST])dnl + AC_REQUIRE([AC_PROG_RANLIB])dnl + AC_REQUIRE([AC_ISC_POSIX])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + AC_REQUIRE([AC_C_CONST])dnl + AC_REQUIRE([AC_C_INLINE])dnl + AC_REQUIRE([AC_TYPE_OFF_T])dnl + AC_REQUIRE([AC_TYPE_SIZE_T])dnl + AC_REQUIRE([AC_FUNC_ALLOCA])dnl + AC_REQUIRE([AC_FUNC_MMAP])dnl + AC_REQUIRE([jm_GLIBC21])dnl + AC_REQUIRE([gt_INTDIV0])dnl + AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])dnl + AC_REQUIRE([gt_HEADER_INTTYPES_H])dnl + AC_REQUIRE([gt_INTTYPES_PRI])dnl + + AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \ +stdlib.h string.h unistd.h sys/param.h]) + AC_CHECK_FUNCS([feof_unlocked fgets_unlocked getc_unlocked getcwd getegid \ +geteuid getgid getuid mempcpy munmap putenv setenv setlocale stpcpy \ +strcasecmp strdup strtoul tsearch __argz_count __argz_stringify __argz_next]) + + AM_ICONV + AM_LANGINFO_CODESET + if test $ac_cv_header_locale_h = yes; then + AM_LC_MESSAGES + fi + + dnl intl/plural.c is generated from intl/plural.y. It requires bison, + dnl because plural.y uses bison specific features. It requires at least + dnl bison-1.26 because earlier versions generate a plural.c that doesn't + dnl compile. + dnl bison is only needed for the maintainer (who touches plural.y). But in + dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put + dnl the rule in general Makefile. Now, some people carelessly touch the + dnl files or have a broken "make" program, hence the plural.c rule will + dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not + dnl present or too old. + AC_CHECK_PROGS([INTLBISON], [bison]) + if test -z "$INTLBISON"; then + ac_verc_fail=yes + else + dnl Found it, now check the version. + AC_MSG_CHECKING([version of bison]) +changequote(<<,>>)dnl + ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` + case $ac_prog_version in + '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; + 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) +changequote([,])dnl + ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; + *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; + esac + AC_MSG_RESULT([$ac_prog_version]) + fi + if test $ac_verc_fail = yes; then + INTLBISON=: + fi +]) + + +AC_DEFUN([AM_MKINSTALLDIRS], +[ + dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly + dnl find the mkinstalldirs script in another subdir but $(top_srcdir). + dnl Try to locate is. + MKINSTALLDIRS= + if test -n "$ac_aux_dir"; then + MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" + fi + if test -z "$MKINSTALLDIRS"; then + MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" + fi + AC_SUBST(MKINSTALLDIRS) +]) + + +dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) +AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) diff --git a/common/m4/glib-gettext.m4 b/common/m4/glib-gettext.m4 new file mode 100755 index 0000000..5a4ef28 --- /dev/null +++ b/common/m4/glib-gettext.m4 @@ -0,0 +1,380 @@ +# Copyright (C) 1995-2002 Free Software Foundation, Inc. +# Copyright (C) 2001-2003 Red Hat, Inc. +# +# This file is free software, distributed under the terms of the GNU +# General Public License. As a special exception to the GNU General +# Public License, this file may be distributed as part of a program +# that contains a configuration script generated by Autoconf, under +# the same distribution terms as the rest of that program. +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# +# Macro to add for using GNU gettext. +# Ulrich Drepper <drepper@cygnus.com>, 1995, 1996 +# +# Modified to never use included libintl. +# Owen Taylor <otaylor@redhat.com>, 12/15/1998 +# +# Major rework to remove unused code +# Owen Taylor <otaylor@redhat.com>, 12/11/2002 +# +# Added better handling of ALL_LINGUAS from GNU gettext version +# written by Bruno Haible, Owen Taylor <otaylor.redhat.com> 5/30/3002 + +# +# We need this here as well, since someone might use autoconf-2.5x +# to configure GLib then an older version to configure a package +# using AM_GLIB_GNU_GETTEXT +AC_PREREQ(2.53) + +dnl +dnl We go to great lengths to make sure that aclocal won't +dnl try to pull in the installed version of these macros +dnl when running aclocal in the glib directory. +dnl +m4_copy([AC_DEFUN],[glib_DEFUN]) +m4_copy([AC_REQUIRE],[glib_REQUIRE]) +dnl +dnl At the end, if we're not within glib, we'll define the public +dnl definitions in terms of our private definitions. +dnl + +# GLIB_LC_MESSAGES +#-------------------- +glib_DEFUN([GLIB_LC_MESSAGES], + [AC_CHECK_HEADERS([locale.h]) + if test $ac_cv_header_locale_h = yes; then + AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES], + am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) + if test $am_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES, 1, + [Define if your <locale.h> file defines LC_MESSAGES.]) + fi + fi]) + +# GLIB_PATH_PROG_WITH_TEST +#---------------------------- +dnl GLIB_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +glib_DEFUN([GLIB_PATH_PROG_WITH_TEST], +[# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + /*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in ifelse([$5], , $PATH, [$5]); do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) + +# GLIB_WITH_NLS +#----------------- +glib_DEFUN([GLIB_WITH_NLS], + dnl NLS is obligatory + [USE_NLS=yes + AC_SUBST(USE_NLS) + + gt_cv_have_gettext=no + + CATOBJEXT=NONE + XGETTEXT=: + INTLLIBS= + + AC_CHECK_HEADER(libintl.h, + [gt_cv_func_dgettext_libintl="no" + libintl_extra_libs="" + + # + # First check in libc + # + AC_CACHE_CHECK([for dgettext in libc], gt_cv_func_dgettext_libc, + [AC_TRY_LINK([ +#include <libintl.h> +], + [return (int) dgettext ("","")], + gt_cv_func_dgettext_libc=yes, + gt_cv_func_dgettext_libc=no) + ]) + + if test "$gt_cv_func_dgettext_libc" = "yes" ; then + AC_CHECK_FUNCS(bind_textdomain_codeset) + fi + + # + # If we don't have everything we want, check in libintl + # + if test "$gt_cv_func_dgettext_libc" != "yes" \ + || test "$ac_cv_func_bind_textdomain_codeset" != "yes" ; then + + AC_CHECK_LIB(intl, bindtextdomain, + [AC_CHECK_LIB(intl, dgettext, + gt_cv_func_dgettext_libintl=yes)]) + + if test "$gt_cv_func_dgettext_libintl" != "yes" ; then + AC_MSG_CHECKING([if -liconv is needed to use gettext]) + AC_MSG_RESULT([]) + AC_CHECK_LIB(intl, dcgettext, + [gt_cv_func_dgettext_libintl=yes + libintl_extra_libs=-liconv], + :,-liconv) + fi + + # + # If we found libintl, then check in it for bind_textdomain_codeset(); + # we'll prefer libc if neither have bind_textdomain_codeset(), + # and both have dgettext + # + if test "$gt_cv_func_dgettext_libintl" = "yes" ; then + glib_save_LIBS="$LIBS" + LIBS="$LIBS -lintl $libintl_extra_libs" + unset ac_cv_func_bind_textdomain_codeset + AC_CHECK_FUNCS(bind_textdomain_codeset) + LIBS="$glib_save_LIBS" + + if test "$ac_cv_func_bind_textdomain_codeset" = "yes" ; then + gt_cv_func_dgettext_libc=no + else + if test "$gt_cv_func_dgettext_libc" = "yes"; then + gt_cv_func_dgettext_libintl=no + fi + fi + fi + fi + + if test "$gt_cv_func_dgettext_libc" = "yes" \ + || test "$gt_cv_func_dgettext_libintl" = "yes"; then + gt_cv_have_gettext=yes + fi + + if test "$gt_cv_func_dgettext_libintl" = "yes"; then + INTLLIBS="-lintl $libintl_extra_libs" + fi + + if test "$gt_cv_have_gettext" = "yes"; then + AC_DEFINE(HAVE_GETTEXT,1, + [Define if the GNU gettext() function is already present or preinstalled.]) + GLIB_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl + if test "$MSGFMT" != "no"; then + glib_save_LIBS="$LIBS" + LIBS="$LIBS $INTLLIBS" + AC_CHECK_FUNCS(dcgettext) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + GLIB_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr], + [CATOBJEXT=.gmo + DATADIRNAME=share], + [case $host in + *-*-solaris*) + dnl On Solaris, if bind_textdomain_codeset is in libc, + dnl GNU format message catalog is always supported, + dnl since both are added to the libc all together. + dnl Hence, we'd like to go with DATADIRNAME=share and + dnl and CATOBJEXT=.gmo in this case. + AC_CHECK_FUNC(bind_textdomain_codeset, + [CATOBJEXT=.gmo + DATADIRNAME=share], + [CATOBJEXT=.mo + DATADIRNAME=lib]) + ;; + *) + CATOBJEXT=.mo + DATADIRNAME=lib + ;; + esac]) + LIBS="$glib_save_LIBS" + INSTOBJEXT=.mo + else + gt_cv_have_gettext=no + fi + fi + ]) + + if test "$gt_cv_have_gettext" = "yes" ; then + AC_DEFINE(ENABLE_NLS, 1, + [always defined to indicate that i18n is enabled]) + fi + + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is not GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext program is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + fi + + # We need to process the po/ directory. + POSUB=po + + AC_OUTPUT_COMMANDS( + [case "$CONFIG_FILES" in *po/Makefile.in*) + sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile + esac]) + + dnl These rules are solely for the distribution goal. While doing this + dnl we only have to keep exactly one list of the available catalogs + dnl in configure.in. + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + dnl Make all variables we use known to autoconf. + AC_SUBST(CATALOGS) + AC_SUBST(CATOBJEXT) + AC_SUBST(DATADIRNAME) + AC_SUBST(GMOFILES) + AC_SUBST(INSTOBJEXT) + AC_SUBST(INTLLIBS) + AC_SUBST(PO_IN_DATADIR_TRUE) + AC_SUBST(PO_IN_DATADIR_FALSE) + AC_SUBST(POFILES) + AC_SUBST(POSUB) + ]) + +# AM_GLIB_GNU_GETTEXT +# ------------------- +# Do checks necessary for use of gettext. If a suitable implementation +# of gettext is found in either in libintl or in the C library, +# it will set INTLLIBS to the libraries needed for use of gettext +# and AC_DEFINE() HAVE_GETTEXT and ENABLE_NLS. (The shell variable +# gt_cv_have_gettext will be set to "yes".) It will also call AC_SUBST() +# on various variables needed by the Makefile.in.in installed by +# glib-gettextize. +dnl +glib_DEFUN([GLIB_GNU_GETTEXT], + [AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + + GLIB_LC_MESSAGES + GLIB_WITH_NLS + + if test "$gt_cv_have_gettext" = "yes"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + AC_MSG_CHECKING(for catalogs to be installed) + NEW_LINGUAS= + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "${LINGUAS-%UNSET%}"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + NEW_LINGUAS="$NEW_LINGUAS $presentlang" + fi + done + LINGUAS=$NEW_LINGUAS + AC_MSG_RESULT($LINGUAS) + fi + + dnl Construct list of names of catalog files to be constructed. + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly + dnl find the mkinstalldirs script in another subdir but ($top_srcdir). + dnl Try to locate is. + MKINSTALLDIRS= + if test -n "$ac_aux_dir"; then + MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" + fi + if test -z "$MKINSTALLDIRS"; then + MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" + fi + AC_SUBST(MKINSTALLDIRS) + + dnl Generate list of files to be processed by xgettext which will + dnl be included in po/Makefile. + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + ]) + +# AM_GLIB_DEFINE_LOCALEDIR(VARIABLE) +# ------------------------------- +# Define VARIABLE to the location where catalog files will +# be installed by po/Makefile. +glib_DEFUN([GLIB_DEFINE_LOCALEDIR], +[glib_REQUIRE([GLIB_GNU_GETTEXT])dnl +glib_save_prefix="$prefix" +glib_save_exec_prefix="$exec_prefix" +test "x$prefix" = xNONE && prefix=$ac_default_prefix +test "x$exec_prefix" = xNONE && exec_prefix=$prefix +if test "x$CATOBJEXT" = "x.mo" ; then + localedir=`eval echo "${libdir}/locale"` +else + localedir=`eval echo "${datadir}/locale"` +fi +prefix="$glib_save_prefix" +exec_prefix="$glib_save_exec_prefix" +AC_DEFINE_UNQUOTED($1, "$localedir", + [Define the location where the catalogs will be installed]) +]) + +dnl +dnl Now the definitions that aclocal will find +dnl +ifdef(glib_configure_in,[],[ +AC_DEFUN([AM_GLIB_GNU_GETTEXT],[GLIB_GNU_GETTEXT($@)]) +AC_DEFUN([AM_GLIB_DEFINE_LOCALEDIR],[GLIB_DEFINE_LOCALEDIR($@)]) +])dnl diff --git a/common/m4/gst-arch.m4 b/common/m4/gst-arch.m4 new file mode 100755 index 0000000..8a32bd2 --- /dev/null +++ b/common/m4/gst-arch.m4 @@ -0,0 +1,123 @@ +dnl AG_GST_ARCH +dnl sets up defines and automake conditionals for host architecture +dnl checks endianness +dnl defines HOST_CPU + +AC_DEFUN([AG_GST_ARCH], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use host_ variables + + dnl Determine CPU + case "x${host_cpu}" in + xi?86 | xk? | xi?86_64) + HAVE_CPU_I386=yes + AC_DEFINE(HAVE_CPU_I386, 1, [Define if the host CPU is an x86]) + + dnl FIXME could use some better detection + dnl (ie CPUID) + case "x${host_cpu}" in + xi386 | xi486) ;; + *) + AC_DEFINE(HAVE_RDTSC, 1, [Define if RDTSC is available]) ;; + esac ;; + xpowerpc) + HAVE_CPU_PPC=yes + AC_DEFINE(HAVE_CPU_PPC, 1, [Define if the host CPU is a PowerPC]) ;; + xpowerpc64) + HAVE_CPU_PPC64=yes + AC_DEFINE(HAVE_CPU_PPC64, 1, [Define if the host CPU is a 64 bit PowerPC]) ;; + xalpha*) + HAVE_CPU_ALPHA=yes + AC_DEFINE(HAVE_CPU_ALPHA, 1, [Define if the host CPU is an Alpha]) ;; + xarm*) + HAVE_CPU_ARM=yes + AC_DEFINE(HAVE_CPU_ARM, 1, [Define if the host CPU is an ARM]) ;; + xsparc*) + HAVE_CPU_SPARC=yes + AC_DEFINE(HAVE_CPU_SPARC, 1, [Define if the host CPU is a SPARC]) ;; + xmips*) + HAVE_CPU_MIPS=yes + AC_DEFINE(HAVE_CPU_MIPS, 1, [Define if the host CPU is a MIPS]) ;; + xhppa*) + HAVE_CPU_HPPA=yes + AC_DEFINE(HAVE_CPU_HPPA, 1, [Define if the host CPU is a HPPA]) ;; + xs390*) + HAVE_CPU_S390=yes + AC_DEFINE(HAVE_CPU_S390, 1, [Define if the host CPU is a S390]) ;; + xia64*) + HAVE_CPU_IA64=yes + AC_DEFINE(HAVE_CPU_IA64, 1, [Define if the host CPU is a IA64]) ;; + xm68k*) + HAVE_CPU_M68K=yes + AC_DEFINE(HAVE_CPU_M68K, 1, [Define if the host CPU is a M68K]) ;; + xx86_64) + HAVE_CPU_X86_64=yes + AC_DEFINE(HAVE_CPU_X86_64, 1, [Define if the host CPU is a x86_64]) ;; + xcris) + HAVE_CPU_CRIS=yes + AC_DEFINE(HAVE_CPU_CRIS, 1, [Define if the host CPU is a CRIS]) ;; + xcrisv32) + HAVE_CPU_CRISV32=yes + AC_DEFINE(HAVE_CPU_CRISV32, 1, [Define if the host CPU is a CRISv32]) ;; + esac + + dnl Determine endianness + AC_C_BIGENDIAN + + AM_CONDITIONAL(HAVE_CPU_I386, test "x$HAVE_CPU_I386" = "xyes") + AM_CONDITIONAL(HAVE_CPU_PPC, test "x$HAVE_CPU_PPC" = "xyes") + AM_CONDITIONAL(HAVE_CPU_PPC64, test "x$HAVE_CPU_PPC64" = "xyes") + AM_CONDITIONAL(HAVE_CPU_ALPHA, test "x$HAVE_CPU_ALPHA" = "xyes") + AM_CONDITIONAL(HAVE_CPU_ARM, test "x$HAVE_CPU_ARM" = "xyes") + AM_CONDITIONAL(HAVE_CPU_SPARC, test "x$HAVE_CPU_SPARC" = "xyes") + AM_CONDITIONAL(HAVE_CPU_HPPA, test "x$HAVE_CPU_HPPA" = "xyes") + AM_CONDITIONAL(HAVE_CPU_MIPS, test "x$HAVE_CPU_MIPS" = "xyes") + AM_CONDITIONAL(HAVE_CPU_S390, test "x$HAVE_CPU_S390" = "xyes") + AM_CONDITIONAL(HAVE_CPU_IA64, test "x$HAVE_CPU_IA64" = "xyes") + AM_CONDITIONAL(HAVE_CPU_M68K, test "x$HAVE_CPU_M68K" = "xyes") + AM_CONDITIONAL(HAVE_CPU_X86_64, test "x$HAVE_CPU_X86_64" = "xyes") + AM_CONDITIONAL(HAVE_CPU_CRIS, test "x$HAVE_CPU_CRIS" = "xyes") + AM_CONDITIONAL(HAVE_CPU_CRISV32, test "x$HAVE_CPU_CRISV32" = "xyes") + + AC_DEFINE_UNQUOTED(HOST_CPU, "$host_cpu", [the host CPU]) +]) + +dnl check if unaligned memory access works correctly +AC_DEFUN([AG_GST_UNALIGNED_ACCESS], [ + AC_MSG_CHECKING([if unaligned memory access works correctly]) + if test x"$as_cv_unaligned_access" = x ; then + case $host in + alpha*|arm*|hp*|mips*|sh*|sparc*|ia64*) + _AS_ECHO_N([(blacklisted) ]) + as_cv_unaligned_access=no + ;; + i?86*|powerpc*|m68k*|cris*) + _AS_ECHO_N([(whitelisted) ]) + as_cv_unaligned_access=yes + ;; + esac + else + _AS_ECHO_N([(cached) ]) + fi + if test x"$as_cv_unaligned_access" = x ; then + AC_TRY_RUN([ +int main(int argc, char **argv) +{ + char array[] = "ABCDEFGH"; + unsigned int iarray[2]; + memcpy(iarray,array,8); +#define GET(x) (*(unsigned int *)((char *)iarray + (x))) + if(GET(0) != 0x41424344 && GET(0) != 0x44434241) return 1; + if(GET(1) != 0x42434445 && GET(1) != 0x45444342) return 1; + if(GET(2) != 0x43444546 && GET(2) != 0x46454443) return 1; + if(GET(3) != 0x44454647 && GET(3) != 0x47464544) return 1; + return 0; +} + ], as_cv_unaligned_access="yes", as_cv_unaligned_access="no") + fi + AC_MSG_RESULT($as_cv_unaligned_access) + if test "$as_cv_unaligned_access" = "yes"; then + AC_DEFINE_UNQUOTED(HAVE_UNALIGNED_ACCESS, 1, + [defined if unaligned memory access works correctly]) + fi +]) diff --git a/common/m4/gst-args.m4 b/common/m4/gst-args.m4 new file mode 100755 index 0000000..1781af4 --- /dev/null +++ b/common/m4/gst-args.m4 @@ -0,0 +1,302 @@ +dnl configure-time options shared among gstreamer modules + +dnl AG_GST_ARG_DEBUG +dnl AG_GST_ARG_PROFILING +dnl AG_GST_ARG_VALGRIND +dnl AG_GST_ARG_GCOV + +dnl AG_GST_ARG_EXAMPLES + +dnl AG_GST_ARG_WITH_PKG_CONFIG_PATH +dnl AG_GST_ARG_WITH_PACKAGE_NAME +dnl AG_GST_ARG_WITH_PACKAGE_ORIGIN + +dnl AG_GST_ARG_WITH_PLUGINS +dnl AG_GST_CHECK_PLUGIN +dnl AG_GST_DISABLE_PLUGIN + +dnl AG_GST_ARG_ENABLE_EXTERNAL +dnl AG_GST_ARG_ENABLE_EXPERIMENTAL +dnl AG_GST_ARG_ENABLE_BROKEN + +AC_DEFUN([AG_GST_ARG_DEBUG], +[ + dnl debugging stuff + AC_ARG_ENABLE(debug, + AC_HELP_STRING([--disable-debug],[disable addition of -g debugging info]), + [ + case "${enableval}" in + yes) USE_DEBUG=yes ;; + no) USE_DEBUG=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;; + esac + ], + [USE_DEBUG=yes]) dnl Default value +]) + +AC_DEFUN([AG_GST_ARG_PROFILING], +[ + AC_ARG_ENABLE(profiling, + AC_HELP_STRING([--enable-profiling], + [adds -pg to compiler commandline, for profiling]), + [ + case "${enableval}" in + yes) USE_PROFILING=yes ;; + no) USE_PROFILING=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-profiling) ;; + esac + ], + [USE_PROFILING=no]) dnl Default value +]) + +AC_DEFUN([AG_GST_ARG_VALGRIND], +[ + dnl valgrind inclusion + AC_ARG_ENABLE(valgrind, + AC_HELP_STRING([--disable-valgrind],[disable run-time valgrind detection]), + [ + case "${enableval}" in + yes) USE_VALGRIND="$USE_DEBUG" ;; + no) USE_VALGRIND=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-valgrind) ;; + esac + ], + [USE_VALGRIND="$USE_DEBUG"]) dnl Default value + VALGRIND_REQ="2.1" + if test "x$USE_VALGRIND" = xyes; then + PKG_CHECK_MODULES(VALGRIND, valgrind > $VALGRIND_REQ, + USE_VALGRIND="yes", + [ + USE_VALGRIND="no" + AC_MSG_RESULT([no]) + ]) + fi + if test "x$USE_VALGRIND" = xyes; then + AC_DEFINE(HAVE_VALGRIND, 1, [Define if valgrind should be used]) + AC_MSG_NOTICE(Using extra code paths for valgrind) + fi +]) + +AC_DEFUN([AG_GST_ARG_GCOV], +[ + AC_ARG_ENABLE(gcov, + AC_HELP_STRING([--enable-gcov], + [compile with coverage profiling instrumentation (gcc only)]), + enable_gcov=$enableval, + enable_gcov=no) + if test x$enable_gcov = xyes ; then + if test "x$GCC" != "xyes" + then + AC_MSG_ERROR([gcov only works if gcc is used]) + fi + + AS_COMPILER_FLAG(["-fprofile-arcs"], + [GCOV_CFLAGS="$GCOV_CFLAGS -fprofile-arcs"], + true) + AS_COMPILER_FLAG(["-ftest-coverage"], + [GCOV_CFLAGS="$GCOV_CFLAGS -ftest-coverage"], + true) + dnl remove any -O flags - FIXME: is this needed ? + GCOV_CFLAGS=`echo "$GCOV_CFLAGS" | sed -e 's/-O[[0-9]]*//g'` + dnl libtool 1.5.22 and lower strip -fprofile-arcs from the flags + dnl passed to the linker, which is a bug; -fprofile-arcs implicitly + dnl links in -lgcov, so we do it explicitly here for the same effect + GCOV_LIBS=-lgcov + AC_SUBST(GCOV_CFLAGS) + AC_SUBST(GCOV_LIBS) + GCOV=`echo $CC | sed s/gcc/gcov/g` + AC_SUBST(GCOV) + + GST_GCOV_ENABLED=yes + AC_DEFINE_UNQUOTED(GST_GCOV_ENABLED, 1, + [Defined if gcov is enabled to force a rebuild due to config.h changing]) + dnl if gcov is used, we do not want default -O2 CFLAGS + if test "x$GST_GCOV_ENABLED" = "xyes" + then + CFLAGS="-O0" + AC_SUBST(CFLAGS) + CXXFLAGS="-O0" + AC_SUBST(CXXFLAGS) + FFLAGS="-O0" + AC_SUBST(FFLAGS) + CCASFLAGS="-O0" + AC_SUBST(CCASFLAGS) + AC_MSG_NOTICE([gcov enabled, setting CFLAGS and friends to $CFLAGS]) + fi + fi + AM_CONDITIONAL(GST_GCOV_ENABLED, test x$enable_gcov = xyes) +]) + +AC_DEFUN([AG_GST_ARG_EXAMPLES], +[ + AC_ARG_ENABLE(examples, + AC_HELP_STRING([--disable-examples], [disable building examples]), + [ + case "${enableval}" in + yes) BUILD_EXAMPLES=yes ;; + no) BUILD_EXAMPLES=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-examples) ;; + esac + ], + [BUILD_EXAMPLES=yes]) dnl Default value + AM_CONDITIONAL(BUILD_EXAMPLES, test "x$BUILD_EXAMPLES" = "xyes") +]) + +AC_DEFUN([AG_GST_ARG_WITH_PKG_CONFIG_PATH], +[ + dnl possibly modify pkg-config path + AC_ARG_WITH(pkg-config-path, + AC_HELP_STRING([--with-pkg-config-path], + [colon-separated list of pkg-config(1) dirs]), + [ + export PKG_CONFIG_PATH=${withval} + AC_MSG_NOTICE(Set PKG_CONFIG_PATH to $PKG_CONFIG_PATH) + ]) +]) + + +dnl This macro requires that GST_CVS is set to yes or no (release) +AC_DEFUN([AG_GST_ARG_WITH_PACKAGE_NAME], +[ + dnl package name in plugins + AC_ARG_WITH(package-name, + AC_HELP_STRING([--with-package-name], + [specify package name to use in plugins]), + [ + case "${withval}" in + yes) AC_MSG_ERROR(bad value ${withval} for --with-package-name) ;; + no) AC_MSG_ERROR(bad value ${withval} for --with-package-name) ;; + *) GST_PACKAGE_NAME="${withval}" ;; + esac + ], + [ + P=$1 + if test "x$P" = "x" + then + P=$PACKAGE_NAME + fi + + dnl default value + if test "x$GST_CVS" = "xyes" + then + dnl nano >= 1 + GST_PACKAGE_NAME="$P CVS/prerelease" + else + GST_PACKAGE_NAME="$P source release" + fi + ] + ) + AC_MSG_NOTICE(Using $GST_PACKAGE_NAME as package name) + AC_DEFINE_UNQUOTED(GST_PACKAGE_NAME, "$GST_PACKAGE_NAME", + [package name in plugins]) + AC_SUBST(GST_PACKAGE_NAME) +]) + +AC_DEFUN([AG_GST_ARG_WITH_PACKAGE_ORIGIN], +[ + dnl package origin URL + AC_ARG_WITH(package-origin, + AC_HELP_STRING([--with-package-origin], + [specify package origin URL to use in plugins]), + [ + case "${withval}" in + yes) AC_MSG_ERROR(bad value ${withval} for --with-package-origin) ;; + no) AC_MSG_ERROR(bad value ${withval} for --with-package-origin) ;; + *) GST_PACKAGE_ORIGIN="${withval}" ;; + esac + ], + [GST_PACKAGE_ORIGIN="[Unknown package origin]"] dnl Default value + ) + AC_MSG_NOTICE(Using $GST_PACKAGE_ORIGIN as package origin) + AC_DEFINE_UNQUOTED(GST_PACKAGE_ORIGIN, "$GST_PACKAGE_ORIGIN", + [package origin]) + AC_SUBST(GST_PACKAGE_ORIGIN) +]) + +dnl sets WITH_PLUGINS to the list of plug-ins given as an argument +dnl also clears GST_PLUGINS_ALL and GST_PLUGINS_SELECTED +AC_DEFUN([AG_GST_ARG_WITH_PLUGINS], +[ + AC_ARG_WITH(plugins, + AC_HELP_STRING([--with-plugins], + [comma-separated list of dependencyless plug-ins to compile]), + [WITH_PLUGINS=$withval], + [WITH_PLUGINS=]) + + GST_PLUGINS_ALL="" + GST_PLUGINS_SELECTED="" + + AC_SUBST(GST_PLUGINS_ALL) + AC_SUBST(GST_PLUGINS_SELECTED) +]) + +dnl AG_GST_CHECK_PLUGIN(PLUGIN-NAME) +dnl +dnl This macro adds the plug-in <PLUGIN-NAME> to GST_PLUGINS_ALL. Then it +dnl checks if the plug-in is present in WITH_PLUGINS, and if so adds it to +dnl GST_PLUGINS_SELECTED. +dnl +dnl The macro will call AM_CONDITIONAL(USE_PLUGIN_<PLUGIN-NAME>, ...) to allow +dnl control of what is built in Makefile.ams. +AC_DEFUN([AG_GST_CHECK_PLUGIN], +[ + GST_PLUGINS_ALL="$GST_PLUGINS_ALL [$1]" + if [[ -z "$WITH_PLUGINS" ]] || echo " [$WITH_PLUGINS] " | tr , ' ' | grep -i " [$1] " > /dev/null; then + GST_PLUGINS_SELECTED="$GST_PLUGINS_SELECTED [$1]" + fi + AM_CONDITIONAL([USE_PLUGIN_]translit([$1], a-z, A-Z), echo " $GST_PLUGINS_SELECTED " | grep -i " [$1] " > /dev/null) +]) + +dnl AG_GST_DISABLE_PLUGIN(PLUGIN-NAME) +dnl +dnl This macro disables the plug-in <PLUGIN-NAME> by removing it from +dnl GST_PLUGINS_SELECTED. +AC_DEFUN([AG_GST_DISABLE_PLUGIN], +[ + GST_PLUGINS_SELECTED=`echo " $GST_PLUGINS_SELECTED " | $SED -e 's/ [$1] / /'` + AM_CONDITIONAL([USE_PLUGIN_]translit([$1], a-z, A-Z), false) +]) + +AC_DEFUN([AG_GST_ARG_ENABLE_EXTERNAL], +[ + AG_GST_CHECK_FEATURE(EXTERNAL, [building of plug-ins with external deps],, + HAVE_EXTERNAL=yes, enabled, + [ + AC_MSG_NOTICE(building external plug-ins) + BUILD_EXTERNAL="yes" + ],[ + AC_MSG_WARN(all plug-ins with external dependencies will not be built) + BUILD_EXTERNAL="no" + ]) + # make BUILD_EXTERNAL available to Makefile.am + AM_CONDITIONAL(BUILD_EXTERNAL, test "x$BUILD_EXTERNAL" = "xyes") +]) + +dnl experimental plug-ins; stuff that hasn't had the dust settle yet +dnl read 'builds, but might not work' +AC_DEFUN([AG_GST_ARG_ENABLE_EXPERIMENTAL], +[ + AG_GST_CHECK_FEATURE(EXPERIMENTAL, [building of experimental plug-ins],, + HAVE_EXPERIMENTAL=yes, disabled, + [ + AC_MSG_WARN(building experimental plug-ins) + BUILD_EXPERIMENTAL="yes" + ],[ + AC_MSG_NOTICE(not building experimental plug-ins) + BUILD_EXPERIMENTAL="no" + ]) + # make BUILD_EXPERIMENTAL available to Makefile.am + AM_CONDITIONAL(BUILD_EXPERIMENTAL, test "x$BUILD_EXPERIMENTAL" = "xyes") +]) + +dnl broken plug-ins; stuff that doesn't seem to build at the moment +AC_DEFUN([AG_GST_ARG_ENABLE_BROKEN], +[ + AG_GST_CHECK_FEATURE(BROKEN, [building of broken plug-ins],, + HAVE_BROKEN=yes, disabled, + [ + AC_MSG_WARN([building broken plug-ins -- no bug reports on these, only patches ...]) + ],[ + AC_MSG_NOTICE([not building broken plug-ins]) + ]) +]) diff --git a/common/m4/gst-check.m4 b/common/m4/gst-check.m4 new file mode 100755 index 0000000..3f6b8ff --- /dev/null +++ b/common/m4/gst-check.m4 @@ -0,0 +1,138 @@ +dnl pkg-config-based checks for GStreamer modules and dependency modules + +dnl generic: +dnl AG_GST_PKG_CHECK_MODULES([PREFIX], [WHICH], [REQUIRED]) +dnl sets HAVE_[$PREFIX], [$PREFIX]_* +dnl AG_GST_CHECK_MODULES([PREFIX], [MODULE], [MINVER], [NAME], [REQUIRED]) +dnl sets HAVE_[$PREFIX], [$PREFIX]_* + +dnl specific: +dnl AG_GST_CHECK_GST([MAJMIN], [MINVER], [REQUIRED]) +dnl also sets/ACSUBSTs GST_TOOLS_DIR and GST_PLUGINS_DIR +dnl AG_GST_CHECK_GST_BASE([MAJMIN], [MINVER], [REQUIRED]) +dnl AG_GST_CHECK_GST_GDP([MAJMIN], [MINVER], [REQUIRED]) +dnl AG_GST_CHECK_GST_CONTROLLER([MAJMIN], [MINVER], [REQUIRED]) +dnl AG_GST_CHECK_GST_CHECK([MAJMIN], [MINVER], [REQUIRED]) +dnl AG_GST_CHECK_GST_PLUGINS_BASE([MAJMIN], [MINVER], [REQUIRED]) +dnl also sets/ACSUBSTs GSTPB_PLUGINS_DIR + +AC_DEFUN([AG_GST_PKG_CHECK_MODULES], +[ + which="[$2]" + dnl not required by default, since we use this mostly for plugin deps + required=ifelse([$3], , "no", [$3]) + + PKG_CHECK_MODULES([$1], $which, + [ + HAVE_[$1]="yes" + ], + [ + HAVE_[$1]="no" + AC_MSG_RESULT(no) + if test "x$required" = "xyes"; then + AC_MSG_ERROR($[$1]_PKG_ERRORS) + else + AC_MSG_NOTICE($[$1]_PKG_ERRORS) + fi + ]) + + dnl AC_SUBST of CFLAGS and LIBS was not done before automake 1.7 + dnl It gets done automatically in automake >= 1.7, which we now require +])) + +AC_DEFUN([AG_GST_CHECK_MODULES], +[ + module=[$2] + minver=[$3] + name="[$4]" + required=ifelse([$5], , "yes", [$5]) dnl required by default + + PKG_CHECK_MODULES([$1], $module >= $minver, + [ + HAVE_[$1]="yes" + ], + [ + HAVE_[$1]="no" + AC_MSG_RESULT(no) + AC_MSG_NOTICE($[$1]_PKG_ERRORS) + if test "x$required" = "xyes"; then + AC_MSG_ERROR([no $module >= $minver ($name) found]) + else + AC_MSG_NOTICE([no $module >= $minver ($name) found]) + fi + ]) + + dnl AC_SUBST of CFLAGS and LIBS was not done before automake 1.7 + dnl It gets done automatically in automake >= 1.7, which we now require +])) + +AC_DEFUN([AG_GST_CHECK_GST], +[ + AG_GST_CHECK_MODULES(GST, gstreamer-[$1], [$2], [GStreamer], [$3]) + dnl allow setting before calling this macro to override + if test -z $GST_TOOLS_DIR; then + GST_TOOLS_DIR=`$PKG_CONFIG --variable=toolsdir gstreamer-[$1]` + if test -z $GST_TOOLS_DIR; then + AC_MSG_ERROR( + [no tools dir set in GStreamer pkg-config file, core upgrade needed.]) + fi + fi + AC_MSG_NOTICE([using GStreamer tools in $GST_TOOLS_DIR]) + AC_SUBST(GST_TOOLS_DIR) + + dnl check for where core plug-ins got installed + dnl this is used for unit tests + dnl allow setting before calling this macro to override + if test -z $GST_PLUGINS_DIR; then + GST_PLUGINS_DIR=`$PKG_CONFIG --variable=pluginsdir gstreamer-[$1]` + if test -z $GST_PLUGINS_DIR; then + AC_MSG_ERROR( + [no pluginsdir set in GStreamer pkg-config file, core upgrade needed.]) + fi + fi + AC_MSG_NOTICE([using GStreamer plug-ins in $GST_PLUGINS_DIR]) + AC_SUBST(GST_PLUGINS_DIR) +]) + +AC_DEFUN([AG_GST_CHECK_GST_BASE], +[ + AG_GST_CHECK_MODULES(GST_BASE, gstreamer-base-[$1], [$2], + [GStreamer Base Libraries], [$3]) +]) + +AC_DEFUN([AG_GST_CHECK_GST_GDP], +[ + AG_GST_CHECK_MODULES(GST_GDP, gstreamer-dataprotocol-[$1], [$2], + [GStreamer Data Protocol Library], [$3]) +]) + +AC_DEFUN([AG_GST_CHECK_GST_CONTROLLER], +[ + AG_GST_CHECK_MODULES(GST_CONTROLLER, gstreamer-controller-[$1], [$2], + [GStreamer Controller Library], [$3]) +]) + +AC_DEFUN([AG_GST_CHECK_GST_CHECK], +[ + AG_GST_CHECK_MODULES(GST_CHECK, gstreamer-check-[$1], [$2], + [GStreamer Check unittest Library], [$3]) +]) + +AC_DEFUN([AG_GST_CHECK_GST_PLUGINS_BASE], +[ + AG_GST_CHECK_MODULES(GST_PLUGINS_BASE, gstreamer-plugins-base-[$1], [$2], + [GStreamer Base Plug-ins Library], [$3]) + + dnl check for where base plug-ins got installed + dnl this is used for unit tests + dnl allow setting before calling this macro to override + if test -z $GSTPB_PLUGINS_DIR; then + GSTPB_PLUGINS_DIR=`$PKG_CONFIG --variable=pluginsdir gstreamer-plugins-base-[$1]` + if test -z $GSTPB_PLUGINS_DIR; then + AC_MSG_ERROR( + [no pluginsdir set in GStreamer Base Plug-ins pkg-config file]) + fi + fi + AC_MSG_NOTICE([using GStreamer Base Plug-ins in $GSTPB_PLUGINS_DIR]) + AC_SUBST(GSTPB_PLUGINS_DIR) +]) diff --git a/common/m4/gst-debuginfo.m4 b/common/m4/gst-debuginfo.m4 new file mode 100755 index 0000000..b48854d --- /dev/null +++ b/common/m4/gst-debuginfo.m4 @@ -0,0 +1,46 @@ +AC_DEFUN([AG_GST_DEBUGINFO], [ +AC_ARG_ENABLE(debug, +AC_HELP_STRING([--disable-debug],[disable addition of -g debugging info]), +[case "${enableval}" in + yes) USE_DEBUG=yes ;; + no) USE_DEBUG=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;; +esac], +[USE_DEBUG=yes]) dnl Default value + +AC_ARG_ENABLE(DEBUG, +AC_HELP_STRING([--disable-DEBUG],[disables compilation of debugging messages]), +[case "${enableval}" in + yes) ENABLE_DEBUG=yes ;; + no) ENABLE_DEBUG=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-DEBUG) ;; +esac], +[ENABLE_DEBUG=yes]) dnl Default value +if test x$ENABLE_DEBUG = xyes; then + AC_DEFINE(GST_DEBUG_ENABLED, 1, [Define if DEBUG statements should be compiled in]) +fi + +AC_ARG_ENABLE(INFO, +AC_HELP_STRING([--disable-INFO],[disables compilation of informational messages]), +[case "${enableval}" in + yes) ENABLE_INFO=yes ;; + no) ENABLE_INFO=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-INFO) ;; +esac], +[ENABLE_INFO=yes]) dnl Default value +if test x$ENABLE_INFO = xyes; then + AC_DEFINE(GST_INFO_ENABLED, 1, [Define if INFO statements should be compiled in]) +fi + +AC_ARG_ENABLE(debug-color, +AC_HELP_STRING([--disable-debug-color],[disables color output of DEBUG and INFO output]), +[case "${enableval}" in + yes) ENABLE_DEBUG_COLOR=yes ;; + no) ENABLE_DEBUG_COLOR=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-debug-color) ;; +esac], +[ENABLE_DEBUG_COLOR=yes]) dnl Default value +if test "x$ENABLE_DEBUG_COLOR" = xyes; then + AC_DEFINE(GST_DEBUG_COLOR, 1, [Define if debugging messages should be colorized]) +fi +]) diff --git a/common/m4/gst-default.m4 b/common/m4/gst-default.m4 new file mode 100755 index 0000000..da1a81c --- /dev/null +++ b/common/m4/gst-default.m4 @@ -0,0 +1,45 @@ +dnl default elements used for tests and such + +dnl AG_GST_DEFAULT_ELEMENTS + +AC_DEFUN([AG_GST_DEFAULT_ELEMENTS], +[ + dnl decide on default elements + dnl FIXME: provide configure-time options for this + dnl FIXME: describe where exactly this gets used + dnl FIXME: decide if it's a problem that this could point to sinks from + dnl depending plugin modules + DEFAULT_AUDIOSINK="autoaudiosink" + DEFAULT_VIDEOSINK="autovideosink" + DEFAULT_AUDIOSRC="alsasrc" + DEFAULT_VIDEOSRC="v4lsrc" + DEFAULT_VISUALIZER="goom" + case "$host" in + *-sun-* | *pc-solaris* ) + DEFAULT_AUDIOSINK="sunaudiosink" + DEFAULT_VIDEOSINK="ximagesink" + DEFAULT_AUDIOSRC="sunaudiosrc" + ;; + *-darwin* ) + DEFAULT_AUDIOSINK="osxaudiosink" + DEFAULT_AUDIOSRC="osxaudiosrc" + DEFAULT_VIDEOSINK="osxvideosink" + ;; + esac + + AC_SUBST(DEFAULT_AUDIOSINK) + AC_DEFINE_UNQUOTED(DEFAULT_AUDIOSINK, "$DEFAULT_AUDIOSINK", + [Default audio sink]) + AC_SUBST(DEFAULT_AUDIOSRC) + AC_DEFINE_UNQUOTED(DEFAULT_AUDIOSRC, "$DEFAULT_AUDIOSRC", + [Default audio source]) + AC_SUBST(DEFAULT_VIDEOSINK) + AC_DEFINE_UNQUOTED(DEFAULT_VIDEOSINK, "$DEFAULT_VIDEOSINK", + [Default video sink]) + AC_SUBST(DEFAULT_VIDEOSRC) + AC_DEFINE_UNQUOTED(DEFAULT_VIDEOSRC, "$DEFAULT_VIDEOSRC", + [Default video source]) + AC_SUBST(DEFAULT_VISUALIZER) + AC_DEFINE_UNQUOTED(DEFAULT_VISUALIZER, "$DEFAULT_VISUALIZER", + [Default visualizer]) +]) diff --git a/common/m4/gst-doc.m4 b/common/m4/gst-doc.m4 new file mode 100755 index 0000000..7000c17 --- /dev/null +++ b/common/m4/gst-doc.m4 @@ -0,0 +1,148 @@ +AC_DEFUN([AG_GST_DOCBOOK_CHECK], +[ + dnl choose a location to install docbook docs in + if test "x$PACKAGE_TARNAME" = "x" + then + AC_MSG_ERROR([Internal error - PACKAGE_TARNAME not set]) + fi + docdir="\$(datadir)/doc/$PACKAGE_TARNAME-$GST_MAJORMINOR" + + dnl enable/disable docbook documentation building + AC_ARG_ENABLE(docbook, + AC_HELP_STRING([--enable-docbook], + [use docbook to build documentation [default=no]]),, + enable_docbook=no) + + have_docbook=no + + if test x$enable_docbook = xyes; then + dnl check if we actually have everything we need + + dnl check for docbook tools + AC_CHECK_PROG(HAVE_DOCBOOK2PS, docbook2ps, yes, no) + AC_CHECK_PROG(HAVE_DOCBOOK2HTML, docbook2html, yes, no) + AC_CHECK_PROG(HAVE_JADETEX, jadetex, yes, no) + AC_CHECK_PROG(HAVE_PS2PDF, ps2pdf, yes, no) + + # -V option appeared in 0.6.10 + docbook2html_min_version=0.6.10 + if test "x$HAVE_DOCBOOK2HTML" != "xno"; then + docbook2html_version=`docbook2html --version` + AC_MSG_CHECKING([docbook2html version ($docbook2html_version) >= $docbook2html_min_version]) + if perl -w <<EOF + (\$min_version_major, \$min_version_minor, \$min_version_micro ) = "$docbook2html_min_version" =~ /(\d+)\.(\d+)\.(\d+)/; + (\$docbook2html_version_major, \$docbook2html_version_minor, \$docbook2html_version_micro ) = "$docbook2html_version" =~ /(\d+)\.(\d+)\.(\d+)/; + exit (((\$docbook2html_version_major > \$min_version_major) || + ((\$docbook2html_version_major == \$min_version_major) && + (\$docbook2html_version_minor >= \$min_version_minor)) || + ((\$docbook2html_version_major == \$min_version_major) && + (\$docbook2html_version_minor >= \$min_version_minor) && + (\$docbook2html_version_micro >= \$min_version_micro))) + ? 0 : 1); +EOF + then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + HAVE_DOCBOOK2HTML=no + fi + fi + + dnl check if we can process docbook stuff + AS_DOCBOOK(have_docbook=yes, have_docbook=no) + + dnl check for extra tools + AC_CHECK_PROG(HAVE_DVIPS, dvips, yes, no) + AC_CHECK_PROG(HAVE_XMLLINT, xmllint, yes, no) + + dnl check for image conversion tools + AC_CHECK_PROG(HAVE_FIG2DEV, fig2dev, yes, no) + if test "x$HAVE_FIG2DEV" = "xno" ; then + AC_MSG_WARN([Did not find fig2dev (from xfig), images will not be generated.]) + fi + + dnl The following is a hack: if fig2dev doesn't display an error message + dnl for the desired type, we assume it supports it. + HAVE_FIG2DEV_EPS=no + if test "x$HAVE_FIG2DEV" = "xyes" ; then + fig2dev_quiet=`fig2dev -L eps </dev/null 2>&1 >/dev/null` + if test "x$fig2dev_quiet" = "x" ; then + HAVE_FIG2DEV_EPS=yes + fi + fi + HAVE_FIG2DEV_PNG=no + if test "x$HAVE_FIG2DEV" = "xyes" ; then + fig2dev_quiet=`fig2dev -L png </dev/null 2>&1 >/dev/null` + if test "x$fig2dev_quiet" = "x" ; then + HAVE_FIG2DEV_PNG=yes + fi + fi + HAVE_FIG2DEV_PDF=no + if test "x$HAVE_FIG2DEV" = "xyes" ; then + fig2dev_quiet=`fig2dev -L pdf </dev/null 2>&1 >/dev/null` + if test "x$fig2dev_quiet" = "x" ; then + HAVE_FIG2DEV_PDF=yes + fi + fi + + AC_CHECK_PROG(HAVE_PNGTOPNM, pngtopnm, yes, no) + AC_CHECK_PROG(HAVE_PNMTOPS, pnmtops, yes, no) + AC_CHECK_PROG(HAVE_EPSTOPDF, epstopdf, yes, no) + + dnl check if we can generate HTML + if test "x$HAVE_DOCBOOK2HTML" = "xyes" && \ + test "x$enable_docbook" = "xyes" && \ + test "x$HAVE_XMLLINT" = "xyes" && \ + test "x$HAVE_FIG2DEV_PNG" = "xyes"; then + DOC_HTML=yes + AC_MSG_NOTICE(Will output HTML documentation) + else + DOC_HTML=no + AC_MSG_NOTICE(Will not output HTML documentation) + fi + + dnl check if we can generate PS + if test "x$HAVE_DOCBOOK2PS" = "xyes" && \ + test "x$enable_docbook" = "xyes" && \ + test "x$HAVE_XMLLINT" = "xyes" && \ + test "x$HAVE_JADETEX" = "xyes" && \ + test "x$HAVE_FIG2DEV_EPS" = "xyes" && \ + test "x$HAVE_DVIPS" = "xyes" && \ + test "x$HAVE_PNGTOPNM" = "xyes" && \ + test "x$HAVE_PNMTOPS" = "xyes"; then + DOC_PS=yes + AC_MSG_NOTICE(Will output PS documentation) + else + DOC_PS=no + AC_MSG_NOTICE(Will not output PS documentation) + fi + + dnl check if we can generate PDF - using only ps2pdf + if test "x$DOC_PS" = "xyes" && \ + test "x$enable_docbook" = "xyes" && \ + test "x$HAVE_XMLLINT" = "xyes" && \ + test "x$HAVE_PS2PDF" = "xyes"; then + DOC_PDF=yes + AC_MSG_NOTICE(Will output PDF documentation) + else + DOC_PDF=no + AC_MSG_NOTICE(Will not output PDF documentation) + fi + + dnl if we don't have everything, we should disable + if test "x$have_docbook" != "xyes"; then + enable_docbook=no + fi + fi + + dnl if we're going to install documentation, tell us where + if test "x$have_docbook" = "xyes"; then + AC_MSG_NOTICE(Installing documentation in $docdir) + AC_SUBST(docdir) + fi + + AM_CONDITIONAL(ENABLE_DOCBOOK, test x$enable_docbook = xyes) + AM_CONDITIONAL(DOC_HTML, test x$DOC_HTML = xyes) + AM_CONDITIONAL(DOC_PDF, test x$DOC_PDF = xyes) + AM_CONDITIONAL(DOC_PS, test x$DOC_PS = xyes) +]) diff --git a/common/m4/gst-error.m4 b/common/m4/gst-error.m4 new file mode 100755 index 0000000..f97f9a6 --- /dev/null +++ b/common/m4/gst-error.m4 @@ -0,0 +1,145 @@ +Dnl handle various error-related things + +dnl Thomas Vander Stichele <thomas@apestaart.org> +dnl Tim-Philipp Müller <tim centricular net> + +dnl Last modification: 2008-02-18 + +dnl AG_GST_SET_ERROR_CFLAGS([ADD-WERROR]) +dnl AG_GST_SET_ERROR_CXXFLAGS([ADD-WERROR]) +dnl AG_GST_SET_LEVEL_DEFAULT([IS-CVS-VERSION]) + + +dnl Sets ERROR_CFLAGS to something the compiler will accept. +dnl AC_SUBST them so they are available in Makefile + +dnl -Wall is added if it is supported +dnl -Werror is added if ADD-WERROR is not "no" + +dnl These flags can be overridden at make time: +dnl make ERROR_CFLAGS= +AC_DEFUN([AG_GST_SET_ERROR_CFLAGS], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AS_COMPILER_FLAG]) + + + dnl if we support -Wall, set it unconditionally + AS_COMPILER_FLAG(-Wall, + ERROR_CFLAGS="-Wall", + ERROR_CFLAGS="") + + dnl if asked for, add -Werror if supported + if test "x$1" != "xno" + then + AS_COMPILER_FLAG(-Werror, ERROR_CFLAGS="$ERROR_CFLAGS -Werror") + + dnl if -Werror isn't suported, try -errwarn=%all (Sun Forte case) + if test "x$ERROR_CFLAGS" == "x" + then + AS_COMPILER_FLAG([-errwarn=%all], [ + ERROR_CFLAGS="-errwarn=%all" + dnl try -errwarn=%all,no%E_EMPTY_DECLARATION, + dnl no%E_STATEMENT_NOT_REACHED,no%E_ARGUEMENT_MISMATCH, + dnl no%E_MACRO_REDEFINED (Sun Forte case) + dnl For Forte we need disable "empty declaration" warning produced by un-needed semicolon + dnl "statement not reached" disabled because there is g_assert_not_reached () in some places + dnl "macro redefined" because of gst/gettext.h + dnl FIXME: is it really supposed to be 'ARGUEMENT' and not 'ARGUMENT'? + for f in 'no%E_EMPTY_DECLARATION' \ + 'no%E_STATEMENT_NOT_REACHED' \ + 'no%E_ARGUEMENT_MISMATCH' \ + 'no%E_MACRO_REDEFINED' + do + AS_COMPILER_FLAG([-errwarn=%all,$f], [ + ERROR_CFLAGS="$ERROR_CFLAGS,$f" + ]) + done + ]) + fi + fi + + AC_SUBST(ERROR_CFLAGS) + AC_MSG_NOTICE([set ERROR_CFLAGS to $ERROR_CFLAGS]) +]) + +dnl Sets ERROR_CXXFLAGS to something the compiler will accept. +dnl AC_SUBST them so they are available in Makefile + +dnl -Wall is added if it is supported +dnl -Werror is added if ADD-WERROR is not "no" + +dnl These flags can be overridden at make time: +dnl make ERROR_CXXFLAGS= +AC_DEFUN([AG_GST_SET_ERROR_CXXFLAGS], +[ + AC_REQUIRE([AC_PROG_CXX]) + AC_REQUIRE([AS_CXX_COMPILER_FLAG]) + + + dnl if we support -Wall, set it unconditionally + AS_CXX_COMPILER_FLAG(-Wall, [ + ERROR_CXXFLAGS="-Wall" + ], [ + ERROR_CXXFLAGS="" + ]) + + dnl if asked for, add -Werror if supported + if test "x$1" != "xno" + then + AS_CXX_COMPILER_FLAG(-Werror, werror_supported=yes, werror_supported=no) + + if test "x$werror_supported" = "xyes"; then + ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror" + + dnl add exceptions + for f in '-Wno-non-virtual-dtor' + do + AS_CXX_COMPILER_FLAG([$f], ERROR_CXXFLAGS="$ERROR_CXXFLAGS $f") + done + else + dnl if -Werror isn't suported, try -errwarn=%all + AS_CXX_COMPILER_FLAG([-errwarn=%all], errwarnall=yes, errwarnall=no) + if test "x$errwarnall" = "xyes"; then + ERROR_CXXFLAGS="-errwarn=%all" + dnl try -errwarn=%all,no%E_EMPTY_DECLARATION, + dnl no%E_STATEMENT_NOT_REACHED,no%E_ARGUEMENT_MISMATCH, + dnl no%E_MACRO_REDEFINED (Sun Forte case) + dnl For Forte we need disable "empty declaration" warning produced by un-needed semicolon + dnl "statement not reached" disabled because there is g_assert_not_reached () in some places + dnl "macro redefined" because of gst/gettext.h + dnl FIXME: is it really supposed to be 'ARGUEMENT' and not 'ARGUMENT'? + dnl FIXME: do any of these work with the c++ compiler? if not, why + dnl do we check at all? + for f in 'no%E_EMPTY_DECLARATION' \ + 'no%E_STATEMENT_NOT_REACHED' \ + 'no%E_ARGUEMENT_MISMATCH' \ + 'no%E_MACRO_REDEFINED' + do + AS_CXX_COMPILER_FLAG([-errwarn=%all,$f], [ + ERROR_CXXFLAGS="$ERROR_CXXFLAGS,$f" + ]) + done + fi + fi + fi + + AC_SUBST(ERROR_CXXFLAGS) + AC_MSG_NOTICE([set ERROR_CXXFLAGS to $ERROR_CXXFLAGS]) +]) + +dnl Sets the default error level for debugging messages +AC_DEFUN([AG_GST_SET_LEVEL_DEFAULT], +[ + dnl define correct errorlevel for debugging messages. We want to have + dnl GST_ERROR messages printed when running cvs builds + if test "x[$1]" = "xyes"; then + GST_LEVEL_DEFAULT=GST_LEVEL_ERROR + else + GST_LEVEL_DEFAULT=GST_LEVEL_NONE + fi + AC_DEFINE_UNQUOTED(GST_LEVEL_DEFAULT, $GST_LEVEL_DEFAULT, + [Default errorlevel to use]) + dnl AC_SUBST so we can use it for win32/common/config.h + AC_SUBST(GST_LEVEL_DEFAULT) +]) diff --git a/common/m4/gst-feature.m4 b/common/m4/gst-feature.m4 new file mode 100755 index 0000000..6777029 --- /dev/null +++ b/common/m4/gst-feature.m4 @@ -0,0 +1,286 @@ +dnl Perform a check for a feature for GStreamer +dnl Richard Boulton <richard-alsa@tartarus.org> +dnl Thomas Vander Stichele <thomas@apestaart.org> added useful stuff +dnl Last modification: 25/06/2001 +dnl +dnl AG_GST_CHECK_FEATURE(FEATURE-NAME, FEATURE-DESCRIPTION, +dnl DEPENDENT-PLUGINS, TEST-FOR-FEATURE, +dnl DISABLE-BY-DEFAULT, ACTION-IF-USE, ACTION-IF-NOTUSE) +dnl +dnl This macro adds a command line argument to allow the user to enable +dnl or disable a feature, and if the feature is enabled, performs a supplied +dnl test to check if the feature is available. +dnl +dnl The test should define HAVE_<FEATURE-NAME> to "yes" or "no" depending +dnl on whether the feature is available. +dnl +dnl The macro will set USE_<FEATURE-NAME> to "yes" or "no" depending on +dnl whether the feature is to be used. +dnl Thomas changed this, so that when USE_<FEATURE-NAME> was already set +dnl to no, then it stays that way. +dnl +dnl The macro will call AM_CONDITIONAL(USE_<FEATURE-NAME>, ...) to allow +dnl the feature to control what is built in Makefile.ams. If you want +dnl additional actions resulting from the test, you can add them with the +dnl ACTION-IF-USE and ACTION-IF-NOTUSE parameters. +dnl +dnl FEATURE-NAME is the name of the feature, and should be in +dnl purely upper case characters. +dnl FEATURE-DESCRIPTION is used to describe the feature in help text for +dnl the command line argument. +dnl DEPENDENT-PLUGINS lists any plug-ins which depend on this feature. +dnl TEST-FOR-FEATURE is a test which sets HAVE_<FEATURE-NAME> to "yes" +dnl or "no" depending on whether the feature is +dnl available. +dnl DISABLE-BY-DEFAULT if "disabled", the feature is disabled by default, +dnl if any other value, the feature is enabled by default. +dnl ACTION-IF-USE any extra actions to perform if the feature is to be +dnl used. +dnl ACTION-IF-NOTUSE any extra actions to perform if the feature is not to +dnl be used. +dnl +dnl +dnl thomas : +dnl we also added a history. +dnl GST_PLUGINS_YES will contain all plugins to be built +dnl that were checked through AG_GST_CHECK_FEATURE +dnl GST_PLUGINS_NO will contain those that won't be built + +AC_DEFUN([AG_GST_CHECK_FEATURE], +[echo +AC_MSG_NOTICE(*** checking feature: [$2] ***) +if test "x[$3]" != "x" +then + AC_MSG_NOTICE(*** for plug-ins: [$3] ***) +fi +dnl +builtin(define, [gst_endisable], ifelse($5, [disabled], [enable], [disable]))dnl +dnl if it is set to NO, then don't even consider it for building +NOUSE= +if test "x$USE_[$1]" = "xno"; then + NOUSE="yes" +fi +AC_ARG_ENABLE(translit([$1], A-Z, a-z), + [ ]builtin(format, --%-26s gst_endisable %s, gst_endisable-translit([$1], A-Z, a-z), [$2]ifelse([$3],,,: [$3])), + [ case "${enableval}" in + yes) USE_[$1]=yes;; + no) USE_[$1]=no;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-translit([$1], A-Z, a-z)) ;; + esac], + [ USE_$1=]ifelse($5, [disabled], [no], [yes])) dnl DEFAULT + +dnl *** set it back to no if it was preset to no +if test "x$NOUSE" = "xyes"; then + USE_[$1]="no" + AC_MSG_WARN(*** $3 pre-configured not to be built) +fi +NOUSE= + +dnl *** If it's enabled + +if test x$USE_[$1] = xyes; then + dnl save compile variables before the test + + gst_check_save_LIBS=$LIBS + gst_check_save_LDFLAGS=$LDFLAGS + gst_check_save_CFLAGS=$CFLAGS + gst_check_save_CPPFLAGS=$CPPFLAGS + gst_check_save_CXXFLAGS=$CXXFLAGS + + HAVE_[$1]=no + dnl TEST_FOR_FEATURE + $4 + + LIBS=$gst_check_save_LIBS + LDFLAGS=$gst_check_save_LDFLAGS + CFLAGS=$gst_check_save_CFLAGS + CPPFLAGS=$gst_check_save_CPPFLAGS + CXXFLAGS=$gst_check_save_CXXFLAGS + + dnl If it isn't found, unset USE_[$1] + if test x$HAVE_[$1] = xno; then + USE_[$1]=no + else + ifelse([$3], , :, [AC_MSG_NOTICE(*** These plugins will be built: [$3])]) + fi +fi +dnl *** Warn if it's disabled or not found +if test x$USE_[$1] = xyes; then + ifelse([$6], , :, [$6]) + if test "x$3" != "x"; then + GST_PLUGINS_YES="\t[$3]\n$GST_PLUGINS_YES" + fi + AC_DEFINE(HAVE_[$1], , [Define to enable $2]ifelse($3,,, [ (used by $3)]).) +else + ifelse([$3], , :, [AC_MSG_NOTICE(*** These plugins will not be built: [$3])]) + if test "x$3" != "x"; then + GST_PLUGINS_NO="\t[$3]\n$GST_PLUGINS_NO" + fi + ifelse([$7], , :, [$7]) +fi +dnl *** Define the conditional as appropriate +AM_CONDITIONAL(USE_[$1], test x$USE_[$1] = xyes) +]) + +dnl Use a -config program which accepts --cflags and --libs parameters +dnl to set *_CFLAGS and *_LIBS and check existence of a feature. +dnl Richard Boulton <richard-alsa@tartarus.org> +dnl Last modification: 26/06/2001 +dnl AG_GST_CHECK_CONFIGPROG(FEATURE-NAME, CONFIG-PROG-FILENAME, MODULES) +dnl +dnl This check was written for GStreamer: it should be renamed and checked +dnl for portability if you decide to use it elsewhere. +dnl +AC_DEFUN([AG_GST_CHECK_CONFIGPROG], +[ + AC_PATH_PROG([$1]_CONFIG, [$2], no) + if test x$[$1]_CONFIG = xno; then + [$1]_LIBS= + [$1]_CFLAGS= + HAVE_[$1]=no + else + if [$2] --plugin-libs [$3] &> /dev/null; then + [$1]_LIBS=`[$2] --plugin-libs [$3]` + else + [$1]_LIBS=`[$2] --libs [$3]` + fi + [$1]_CFLAGS=`[$2] --cflags [$3]` + HAVE_[$1]=yes + fi + AC_SUBST([$1]_LIBS) + AC_SUBST([$1]_CFLAGS) +]) + +dnl Use AC_CHECK_LIB and AC_CHECK_HEADER to do both tests at once +dnl sets HAVE_module if we have it +dnl Richard Boulton <richard-alsa@tartarus.org> +dnl Last modification: 26/06/2001 +dnl AG_GST_CHECK_LIBHEADER(FEATURE-NAME, LIB NAME, LIB FUNCTION, EXTRA LD FLAGS, +dnl HEADER NAME, ACTION-IF-FOUND, ACTION-IF-NOT-FOUND) +dnl +dnl This check was written for GStreamer: it should be renamed and checked +dnl for portability if you decide to use it elsewhere. +dnl +AC_DEFUN([AG_GST_CHECK_LIBHEADER], +[ + AC_CHECK_LIB([$2], [$3], HAVE_[$1]=yes, HAVE_[$1]=no,[$4]) + if test "x$HAVE_[$1]" = "xyes"; then + AC_CHECK_HEADER([$5], :, HAVE_[$1]=no) + if test "x$HAVE_[$1]" = "xyes"; then + dnl execute what needs to be + ifelse([$6], , :, [$6]) + else + ifelse([$7], , :, [$7]) + fi + else + ifelse([$7], , :, [$7]) + fi + AC_SUBST(HAVE_[$1]) +] +) + +dnl 2004-02-14 Thomas - changed to get set properly and use proper output +dnl 2003-06-27 Benjamin Otte - changed to make this work with gstconfig.h +dnl +dnl Add a subsystem --disable flag and all the necessary symbols and substitions +dnl +dnl AG_GST_CHECK_SUBSYSTEM_DISABLE(SYSNAME, [subsystem name]) +dnl +AC_DEFUN([AG_GST_CHECK_SUBSYSTEM_DISABLE], +[ + dnl this define will replace each literal subsys_def occurrence with + dnl the lowercase hyphen-separated subsystem + dnl e.g. if $1 is GST_DEBUG then subsys_def will be a macro with gst-debug + define([subsys_def],translit([$1], _A-Z, -a-z)) + + AC_ARG_ENABLE(subsys_def, + AC_HELP_STRING(--disable-subsys_def, [disable $2]), + [ + case "${enableval}" in + yes) GST_DISABLE_[$1]=no ;; + no) GST_DISABLE_[$1]=yes ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-subsys_def]) ;; + esac + ], + [GST_DISABLE_[$1]=no]) dnl Default value + + if test x$GST_DISABLE_[$1] = xyes; then + AC_MSG_NOTICE([disabled subsystem [$2]]) + GST_DISABLE_[$1]_DEFINE="#define GST_DISABLE_$1 1" + else + GST_DISABLE_[$1]_DEFINE="/* #undef GST_DISABLE_$1 */" + fi + AC_SUBST(GST_DISABLE_[$1]_DEFINE) + undefine([subsys_def]) +]) + + +dnl Parse gstconfig.h for feature and defines add the symbols and substitions +dnl +dnl AG_GST_PARSE_SUBSYSTEM_DISABLE(GST_CONFIGPATH, FEATURE) +dnl +AC_DEFUN([AG_GST_PARSE_SUBSYSTEM_DISABLE], +[ + grep >/dev/null "#undef GST_DISABLE_$2" $1 + if test $? = 0; then + GST_DISABLE_[$2]=0 + else + GST_DISABLE_[$2]=1 + fi + AC_SUBST(GST_DISABLE_[$2]) +]) + +dnl Parse gstconfig.h and defines add the symbols and substitions +dnl +dnl GST_CONFIGPATH=`$PKG_CONFIG --variable=includedir gstreamer-0.10`"/gst/gstconfig.h" +dnl AG_GST_PARSE_SUBSYSTEM_DISABLES(GST_CONFIGPATH) +dnl +AC_DEFUN([AG_GST_PARSE_SUBSYSTEM_DISABLES], +[ + AG_GST_PARSE_SUBSYSTEM_DISABLE($1,GST_DEBUG) + AG_GST_PARSE_SUBSYSTEM_DISABLE($1,LOADSAVE) + AG_GST_PARSE_SUBSYSTEM_DISABLE($1,PARSE) + AG_GST_PARSE_SUBSYSTEM_DISABLE($1,TRACE) + AG_GST_PARSE_SUBSYSTEM_DISABLE($1,ALLOC_TRACE) + AG_GST_PARSE_SUBSYSTEM_DISABLE($1,REGISTRY) + AG_GST_PARSE_SUBSYSTEM_DISABLE($1,ENUMTYPES) + AG_GST_PARSE_SUBSYSTEM_DISABLE($1,INDEX) + AG_GST_PARSE_SUBSYSTEM_DISABLE($1,PLUGIN) + AG_GST_PARSE_SUBSYSTEM_DISABLE($1,URI) + AG_GST_PARSE_SUBSYSTEM_DISABLE($1,XML) +]) + + + +dnl relies on GST_PLUGINS_ALL, GST_PLUGINS_SELECTED, GST_PLUGINS_YES, +dnl GST_PLUGINS_NO, and BUILD_EXTERNAL +AC_DEFUN([AG_GST_OUTPUT_PLUGINS], [ + +printf "configure: *** Plug-ins without external dependencies that will be built:\n" +( for i in $GST_PLUGINS_SELECTED; do printf '\t'$i'\n'; done ) | sort +printf "\n" + +printf "configure: *** Plug-ins without external dependencies that will NOT be built:\n" +( for i in $GST_PLUGINS_ALL; do + case $GST_PLUGINS_SELECTED in + *$i*) + ;; + *) + printf '\t'$i'\n' + ;; + esac + done ) | sort +printf "\n" + +if test "x$BUILD_EXTERNAL" = "xno"; then + printf "configure: *** No plug-ins with external dependencies will be built\n" +else + printf "configure: *** Plug-ins with dependencies that will be built:" + printf "$GST_PLUGINS_YES\n" | sort + printf "\n" + printf "configure: *** Plug-ins with dependencies that will NOT be built:" + printf "$GST_PLUGINS_NO\n" | sort + printf "\n" +fi +]) + diff --git a/common/m4/gst-function.m4 b/common/m4/gst-function.m4 new file mode 100755 index 0000000..1216621 --- /dev/null +++ b/common/m4/gst-function.m4 @@ -0,0 +1,63 @@ +dnl +dnl Check for compiler mechanism to show functions in debugging +dnl copied from an Ali patch floating on the internet +dnl +AC_DEFUN([AG_GST_CHECK_FUNCTION],[ + dnl #1: __PRETTY_FUNCTION__ + AC_MSG_CHECKING(whether $CC implements __PRETTY_FUNCTION__) + AC_CACHE_VAL(have_pretty_function,[ + AC_TRY_LINK([#include <stdio.h>], + [printf("%s", __PRETTY_FUNCTION__);], + have_pretty_function=yes, + have_pretty_function=no) + ]) + AC_MSG_RESULT($have_pretty_function) + if test "$have_pretty_function" = yes; then + AC_DEFINE(HAVE_PRETTY_FUNCTION, 1, + [defined if the compiler implements __PRETTY_FUNCTION__]) + fi + +dnl #2: __FUNCTION__ + AC_MSG_CHECKING(whether $CC implements __FUNCTION__) + AC_CACHE_VAL(have_function,[ + AC_TRY_LINK([#include <stdio.h>], + [printf("%s", __FUNCTION__);], + have_function=yes, + have_function=no) + ]) + AC_MSG_RESULT($have_function) + if test "$have_function" = yes; then + AC_DEFINE(HAVE_FUNCTION, 1, + [defined if the compiler implements __FUNCTION__]) + fi + +dnl #3: __func__ + AC_MSG_CHECKING(whether $CC implements __func__) + AC_CACHE_VAL(have_func,[ + AC_TRY_LINK([#include <stdio.h>], + [printf("%s", __func__);], + have_func=yes, + have_func=no) + ]) + AC_MSG_RESULT($have_func) + if test "$have_func" = yes; then + AC_DEFINE(HAVE_FUNC, 1, + [defined if the compiler implements __func__]) + fi + +dnl now define FUNCTION to whatever works, and fallback to "" + if test "$have_pretty_function" = yes; then + function=__PRETTY_FUNCTION__ + else + if test "$have_function" = yes; then + function=__FUNCTION__ + else + if test "$have_func" = yes; then + function=__func__ + else + function=\"\" + fi + fi + fi + AC_DEFINE_UNQUOTED(GST_FUNCTION, $function, [macro to use to show function name]) +]) diff --git a/common/m4/gst-gettext.m4 b/common/m4/gst-gettext.m4 new file mode 100755 index 0000000..a63651b --- /dev/null +++ b/common/m4/gst-gettext.m4 @@ -0,0 +1,21 @@ +dnl gettext setup + +dnl AG_GST_GETTEXT([gettext-package]) +dnl defines GETTEXT_PACKAGE and LOCALEDIR + +AC_DEFUN([AG_GST_GETTEXT], +[ + if test "$USE_NLS" = "yes"; then + GETTEXT_PACKAGE=[$1] + else + GETTEXT_PACKAGE=[NULL] + fi + AC_SUBST(GETTEXT_PACKAGE) + AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], "$GETTEXT_PACKAGE", + [gettext package name]) + + dnl define LOCALEDIR in config.h + AS_AC_EXPAND(LOCALEDIR, $datadir/locale) + AC_DEFINE_UNQUOTED([LOCALEDIR], "$LOCALEDIR", + [gettext locale dir]) +]) diff --git a/common/m4/gst-glib2.m4 b/common/m4/gst-glib2.m4 new file mode 100755 index 0000000..3060e5e --- /dev/null +++ b/common/m4/gst-glib2.m4 @@ -0,0 +1,25 @@ +dnl check for a minimum version of GLib + +dnl AG_GST_GLIB_CHECK([minimum-version-required]) + +AC_DEFUN([AG_GST_GLIB_CHECK], +[ + dnl Minimum required version of GLib + GLIB_REQ=[$1] + if test "x$GLIB_REQ" = "x" + then + AC_MSG_ERROR([Please specify a required version for GLib 2.0]) + fi + AC_SUBST(GLIB_REQ) + + dnl Check for glib with everything + AG_GST_PKG_CHECK_MODULES(GLIB, + glib-2.0 >= $GLIB_REQ gobject-2.0 gthread-2.0 gmodule-no-export-2.0) + + if test "x$HAVE_GLIB" = "xno"; then + AC_MSG_ERROR([This package requires GLib >= $GLIB_REQ to compile.]) + fi + + dnl for the poor souls who for example have glib in /usr/local + AS_SCRUB_INCLUDE(GLIB_CFLAGS) +]) diff --git a/common/m4/gst-libxml2.m4 b/common/m4/gst-libxml2.m4 new file mode 100755 index 0000000..7d978d3 --- /dev/null +++ b/common/m4/gst-libxml2.m4 @@ -0,0 +1,46 @@ +dnl call this macro with the minimum required version as an argument +dnl this macro sets and AC_SUBSTs XML_CFLAGS and XML_LIBS +dnl it also sets LIBXML_PKG, used for the pkg-config file + +AC_DEFUN([AG_GST_LIBXML2_CHECK], +[ + dnl Minimum required version of libxml2 + dnl default to 2.4.9 if not specified + LIBXML2_REQ=ifelse([$1],,2.4.9,[$1]) + AC_SUBST(LIBXML2_REQ) + + dnl check for libxml2 + PKG_CHECK_MODULES(XML, libxml-2.0 >= $LIBXML2_REQ, + HAVE_LIBXML2=yes, [ + AC_MSG_RESULT(no) + HAVE_LIBXML2=no + ]) + if test "x$HAVE_LIBXML2" = "xyes"; then + AC_DEFINE(HAVE_LIBXML2, 1, [Define if libxml2 is available]) + else + AC_MSG_ERROR([Need libxml2 for glib2 builds -- you should be able to do without it -- this needs fixing]) + fi + dnl this is for the .pc file + LIBXML_PKG=', libxml-2.0' + AC_SUBST(LIBXML_PKG) + AC_SUBST(XML_LIBS) + AC_SUBST(XML_CFLAGS) + + dnl XML_LIBS might pull in -lz without zlib actually being on the system, so + dnl try linking with these LIBS and CFLAGS + ac_save_CFLAGS=$CFLAGS + ac_save_LIBS=$LIBS + CFLAGS="$CFLAGS $XML_CFLAGS" + LIBS="$LIBS $XML_LIBS" + AC_TRY_LINK([ +#include <libxml/tree.h> +#include <stdio.h> +],[ +/* function body */ +], + AC_MSG_NOTICE([Test xml2 program linked]), + AC_MSG_ERROR([Could not link libxml2 test program. Check if you have the necessary dependencies.]) + ) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" +]) diff --git a/common/m4/gst-parser.m4 b/common/m4/gst-parser.m4 new file mode 100755 index 0000000..9cc0981 --- /dev/null +++ b/common/m4/gst-parser.m4 @@ -0,0 +1,63 @@ +AC_DEFUN([AG_GST_BISON_CHECK], +[ + dnl FIXME: check if AC_PROG_YACC is suitable here + dnl FIXME: make precious + AC_PATH_PROG(BISON_PATH, bison, no) + if test x$BISON_PATH = xno; then + AC_MSG_ERROR(Could not find bison) + fi + + dnl check bison version + dnl FIXME 0.11: we need version >= 1.875 for the reentrancy support + dnl in the parser. If an older version is installed pre-generated + dnl sources are used. This should become a hard dependency for 0.11! + bison_min_version=1.875 + bison_version=`$BISON_PATH --version | head -n 1 | sed 's/^.*) //' | sed 's/[[a-zA-Z]]*$//' | cut -d' ' -f1` + AC_MSG_CHECKING([bison version $bison_version >= $bison_min_version]) + + if perl -w <<EOF + exit ($bison_version < $bison_min_version) ? 0 : 1; +EOF + then + AC_MSG_RESULT([yes]) + AM_CONDITIONAL(GENERATE_PARSER, test -z $GENERATE_PARSER_TRUE) + else + AC_MSG_RESULT([no, using pre-generated parser sources]) + AM_CONDITIONAL(GENERATE_PARSER, false) + fi +]) + +AC_DEFUN([AG_GST_FLEX_CHECK], +[ + dnl we require flex for building the parser + AC_PATH_PROG(FLEX_PATH, flex, no) + if test x$FLEX_PATH = xno; then + AC_MSG_ERROR(Could not find flex) + fi + + dnl check flex version + dnl FIXME 0.11: we need version >= 2.5.31 for the reentrancy support + dnl in the parser. If an older version is installed pre-generated + dnl sources are used. This should become a hard dependency for 0.11! + flex_min_version=2.5.31 + flex_version=`$FLEX_PATH --version | head -n 1 | sed 's/^.* //' | sed 's/[[a-zA-Z]]*$//' | cut -d' ' -f1` + AC_MSG_CHECKING([flex version $flex_version >= $flex_min_version]) + if perl -w <<EOF + (\$min_version_major, \$min_version_minor, \$min_version_micro ) = "$flex_min_version" =~ /(\d+)\.(\d+)\.(\d+)/; + (\$flex_version_major, \$flex_version_minor, \$flex_version_micro ) = "$flex_version" =~ /(\d+)\.(\d+)\.(\d+)/; + exit (((\$flex_version_major > \$min_version_major) || + ((\$flex_version_major == \$min_version_major) && + (\$flex_version_minor > \$min_version_minor)) || + ((\$flex_version_major == \$min_version_major) && + (\$flex_version_minor == \$min_version_minor) && + (\$flex_version_micro >= \$min_version_micro))) + ? 0 : 1); +EOF + then + AC_MSG_RESULT(yes) + AM_CONDITIONAL(GENERATE_PARSER, test -z $GENERATE_PARSER_TRUE) + else + AC_MSG_RESULT([no, using pre-generated parser sources]) + AM_CONDITIONAL(GENERATE_PARSER, false) + fi +]) diff --git a/common/m4/gst-plugin-docs.m4 b/common/m4/gst-plugin-docs.m4 new file mode 100755 index 0000000..29ebbd6 --- /dev/null +++ b/common/m4/gst-plugin-docs.m4 @@ -0,0 +1,47 @@ +dnl AG_GST_PYXML_CHECK([MINIMUM-PYTHON-VERSION]) + +AC_DEFUN([AG_GST_PYXML_CHECK], +[ + AC_BEFORE([AS_PATH_PYTHON],[$0])dnl find python first + + have_pyxml=no + if test "x$PYTHON" != x; then + AC_MSG_CHECKING([pyxml]) + if $PYTHON -c "from xml.dom.ext.reader import Sax2" 2>/dev/null \ + && $PYTHON -c "from xml.dom.NodeFilter import NodeFilter" 2>/dev/null; then + AC_MSG_RESULT(yes) + have_pyxml=yes + else + AC_MSG_RESULT(no) + fi + fi +]) + +dnl AG_GST_PLUGIN_DOCS([MINIMUM-GTK-DOC-VERSION],[MINIMUM-PYTHON-VERSION]) +dnl +dnl checks for prerequisites for the common/mangle-tmpl.py script +dnl used when building the plugin documentation + +AC_DEFUN([AG_GST_PLUGIN_DOCS], +[ + AC_BEFORE([GTK_DOC_CHECK],[$0])dnl check for gtk-doc first + + if test x$enable_gtk_doc = xyes -a x$have_gtk_doc = xyes; then + AG_GST_PYXML_CHECK([$1]) + fi + + build_plugin_docs=no + AC_MSG_CHECKING([whether to build plugin documentation]) + if test x$enable_gtk_doc = xyes -a x$have_gtk_doc = xyes; then + if test "x$have_pyxml" != xyes; then + AC_MSG_RESULT([no (pyxml not installed)]) + else + build_plugin_docs=yes + AC_MSG_RESULT([yes]) + fi + else + AC_MSG_RESULT([no (gtk-doc disabled or not available)]) + fi + + AM_CONDITIONAL(ENABLE_PLUGIN_DOCS, test x$build_plugin_docs = xyes) +]) diff --git a/common/m4/gst-plugindir.m4 b/common/m4/gst-plugindir.m4 new file mode 100755 index 0000000..09989d0 --- /dev/null +++ b/common/m4/gst-plugindir.m4 @@ -0,0 +1,17 @@ +dnl AG_GST_SET_PLUGINDIR + +dnl AC_DEFINE PLUGINDIR to the full location where plug-ins will be installed +dnl AC_SUBST plugindir, to be used in Makefile.am's + +AC_DEFUN([AG_GST_SET_PLUGINDIR], +[ + dnl define location of plugin directory + AS_AC_EXPAND(PLUGINDIR, ${libdir}/gstreamer-$GST_MAJORMINOR) + AC_DEFINE_UNQUOTED(PLUGINDIR, "$PLUGINDIR", + [directory where plugins are located]) + AC_MSG_NOTICE([Using $PLUGINDIR as the plugin install location]) + + dnl plugin directory configure-time variable for use in Makefile.am + plugindir="\$(libdir)/gstreamer-$GST_MAJORMINOR" + AC_SUBST(plugindir) +]) diff --git a/common/m4/gst-valgrind.m4 b/common/m4/gst-valgrind.m4 new file mode 100755 index 0000000..93c2635 --- /dev/null +++ b/common/m4/gst-valgrind.m4 @@ -0,0 +1,35 @@ +AC_DEFUN([AG_GST_VALGRIND_CHECK], +[ + dnl valgrind inclusion + AC_ARG_ENABLE(valgrind, + AC_HELP_STRING([--disable-valgrind], [disable run-time valgrind detection]), + [ + case "${enableval}" in + yes) USE_VALGRIND="$USE_DEBUG" ;; + no) USE_VALGRIND=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-valgrind) ;; + esac], + [ + USE_VALGRIND="$USE_DEBUG" + ]) dnl Default value + + VALGRIND_REQ="2.1" + if test "x$USE_VALGRIND" = xyes; then + PKG_CHECK_MODULES(VALGRIND, valgrind > $VALGRIND_REQ, + USE_VALGRIND="yes", + [ + USE_VALGRIND="no" + AC_MSG_RESULT([no]) + ]) + fi + + if test "x$USE_VALGRIND" = xyes; then + AC_DEFINE(HAVE_VALGRIND, 1, [Define if valgrind should be used]) + AC_MSG_NOTICE(Using extra code paths for valgrind) + fi + AC_SUBST(VALGRIND_CFLAGS) + AC_SUBST(VALGRIND_LIBS) + + AC_PATH_PROG(VALGRIND_PATH, valgrind, no) + AM_CONDITIONAL(HAVE_VALGRIND, test ! "x$VALGRIND_PATH" = "xno") +]) diff --git a/common/m4/gst.m4 b/common/m4/gst.m4 new file mode 100755 index 0000000..04b466f --- /dev/null +++ b/common/m4/gst.m4 @@ -0,0 +1,10 @@ +dnl AG_GST_INIT +dnl sets up use of GStreamer configure.ac macros +dnl all GStreamer autoconf macros are prefixed +dnl with AG_GST_ for public macros +dnl with _AG_GST_ for private macros + +AC_DEFUN([AG_GST_INIT], +[ + m4_pattern_forbid(^_?AG_GST_) +]) diff --git a/common/m4/gtk-doc.m4 b/common/m4/gtk-doc.m4 new file mode 100755 index 0000000..57040aa --- /dev/null +++ b/common/m4/gtk-doc.m4 @@ -0,0 +1,56 @@ +dnl -*- mode: autoconf -*- + +# serial 1 + +dnl Usage: +dnl GTK_DOC_CHECK([minimum-gtk-doc-version]) +AC_DEFUN([GTK_DOC_CHECK], +[ + AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first + AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first + dnl for overriding the documentation installation directory + AC_ARG_WITH(html-dir, + AC_HELP_STRING([--with-html-dir=PATH], [path to installed docs]),, + [with_html_dir='${datadir}/gtk-doc/html']) + HTML_DIR="$with_html_dir" + AC_SUBST(HTML_DIR) + + dnl enable/disable documentation building + AC_ARG_ENABLE(gtk-doc, + AC_HELP_STRING([--enable-gtk-doc], + [use gtk-doc to build documentation [default=no]]),, + enable_gtk_doc=no) + + have_gtk_doc=no + if test x$enable_gtk_doc = xyes; then + if test -z "$PKG_CONFIG"; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + fi + if test "$PKG_CONFIG" != "no" && $PKG_CONFIG --exists gtk-doc; then + have_gtk_doc=yes + fi + if test -z "$SED"; then + AC_PROG_SED + fi + +dnl do we want to do a version check? +ifelse([$1],[],, + [gtk_doc_min_version=$1 + if test "$have_gtk_doc" = yes; then + AC_MSG_CHECKING([gtk-doc version >= $gtk_doc_min_version]) + if $PKG_CONFIG --atleast-version $gtk_doc_min_version gtk-doc; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + have_gtk_doc=no + fi + fi +]) + if test "$have_gtk_doc" != yes; then + enable_gtk_doc=no + fi + fi + + AM_CONDITIONAL(ENABLE_GTK_DOC, test x$enable_gtk_doc = xyes) + AM_CONDITIONAL(GTK_DOC_USE_LIBTOOL, test -n "$LIBTOOL") +]) diff --git a/common/m4/iconv.m4 b/common/m4/iconv.m4 new file mode 100755 index 0000000..c5f3579 --- /dev/null +++ b/common/m4/iconv.m4 @@ -0,0 +1,103 @@ +# iconv.m4 serial AM4 (gettext-0.11.3) +dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], +[ + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([iconv]) +]) + +AC_DEFUN([AM_ICONV_LINK], +[ + dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and + dnl those with the standalone portable GNU libiconv installed). + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + + dnl Add $INCICONV to CPPFLAGS before performing the following checks, + dnl because if the user has installed libiconv and not disabled its use + dnl via --without-libiconv-prefix, he wants to use it. The first + dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. + am_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) + + AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + AC_TRY_LINK([#include <stdlib.h> +#include <iconv.h>], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_func_iconv=yes) + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + AC_TRY_LINK([#include <stdlib.h> +#include <iconv.h>], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_lib_iconv=yes + am_cv_func_iconv=yes) + LIBS="$am_save_LIBS" + fi + ]) + if test "$am_cv_func_iconv" = yes; then + AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) + fi + if test "$am_cv_lib_iconv" = yes; then + AC_MSG_CHECKING([how to link with libiconv]) + AC_MSG_RESULT([$LIBICONV]) + else + dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV + dnl either. + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + AC_SUBST(LIBICONV) + AC_SUBST(LTLIBICONV) +]) + +AC_DEFUN([AM_ICONV], +[ + AM_ICONV_LINK + if test "$am_cv_func_iconv" = yes; then + AC_MSG_CHECKING([for iconv declaration]) + AC_CACHE_VAL(am_cv_proto_iconv, [ + AC_TRY_COMPILE([ +#include <stdlib.h> +#include <iconv.h> +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif +], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) + am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + AC_MSG_RESULT([$]{ac_t:- + }[$]am_cv_proto_iconv) + AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, + [Define as const if the declaration of iconv() needs const.]) + fi +]) diff --git a/common/m4/isc-posix.m4 b/common/m4/isc-posix.m4 new file mode 100755 index 0000000..1319dd1 --- /dev/null +++ b/common/m4/isc-posix.m4 @@ -0,0 +1,26 @@ +# isc-posix.m4 serial 2 (gettext-0.11.2) +dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +# This file is not needed with autoconf-2.53 and newer. Remove it in 2005. + +# This test replaces the one in autoconf. +# Currently this macro should have the same name as the autoconf macro +# because gettext's gettext.m4 (distributed in the automake package) +# still uses it. Otherwise, the use in gettext.m4 makes autoheader +# give these diagnostics: +# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX +# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX + +undefine([AC_ISC_POSIX]) + +AC_DEFUN([AC_ISC_POSIX], + [ + dnl This test replaces the obsolescent AC_ISC_POSIX kludge. + AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) + ] +) diff --git a/common/m4/lib-ld.m4 b/common/m4/lib-ld.m4 new file mode 100755 index 0000000..ddb5732 --- /dev/null +++ b/common/m4/lib-ld.m4 @@ -0,0 +1,97 @@ +# lib-ld.m4 serial 1 (gettext-0.11) +dnl Copyright (C) 1996-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl Subroutines of libtool.m4, +dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision +dnl with libtool.m4. + +dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. +AC_DEFUN([AC_LIB_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then + acl_cv_prog_gnu_ld=yes +else + acl_cv_prog_gnu_ld=no +fi]) +with_gnu_ld=$acl_cv_prog_gnu_ld +]) + +dnl From libtool-1.4. Sets the variable LD. +AC_DEFUN([AC_LIB_PROG_LD], +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]* | [A-Za-z]:[\\/]*)] + [re_direlt='/[^/][^/]*/\.\./'] + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(acl_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$acl_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + acl_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$acl_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_LIB_PROG_LD_GNU +]) diff --git a/common/m4/lib-link.m4 b/common/m4/lib-link.m4 new file mode 100755 index 0000000..6b94251 --- /dev/null +++ b/common/m4/lib-link.m4 @@ -0,0 +1,554 @@ +# lib-link.m4 serial 3 (gettext-0.11.3) +dnl Copyright (C) 2001-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and +dnl augments the CPPFLAGS variable. +AC_DEFUN([AC_LIB_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + define([Name],[translit([$1],[./-], [___])]) + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + ac_cv_lib[]Name[]_libs="$LIB[]NAME" + ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" + ac_cv_lib[]Name[]_cppflags="$INC[]NAME" + ]) + LIB[]NAME="$ac_cv_lib[]Name[]_libs" + LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" + INC[]NAME="$ac_cv_lib[]Name[]_cppflags" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the + dnl results of this search when this library appears as a dependency. + HAVE_LIB[]NAME=yes + undefine([Name]) + undefine([NAME]) +]) + +dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) +dnl searches for libname and the libraries corresponding to explicit and +dnl implicit dependencies, together with the specified include files and +dnl the ability to compile and link the specified testcode. If found, it +dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and +dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and +dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs +dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. +AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + define([Name],[translit([$1],[./-], [___])]) + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + + dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + + dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, + dnl because if the user has installed lib[]Name and not disabled its use + dnl via --without-lib[]Name-prefix, he wants to use it. + ac_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + + AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIB[]NAME" + AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) + LIBS="$ac_save_LIBS" + ]) + if test "$ac_cv_lib[]Name" = yes; then + HAVE_LIB[]NAME=yes + AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) + AC_MSG_CHECKING([how to link with lib[]$1]) + AC_MSG_RESULT([$LIB[]NAME]) + else + HAVE_LIB[]NAME=no + dnl If $LIB[]NAME didn't lead to a usable library, we don't need + dnl $INC[]NAME either. + CPPFLAGS="$ac_save_CPPFLAGS" + LIB[]NAME= + LTLIB[]NAME= + fi + AC_SUBST([HAVE_LIB]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + undefine([Name]) + undefine([NAME]) +]) + +dnl Determine the platform dependent parameters needed to use rpath: +dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator, +dnl hardcode_direct, hardcode_minus_L, +dnl sys_lib_search_path_spec, sys_lib_dlsearch_path_spec. +AC_DEFUN([AC_LIB_RPATH], +[ + AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS + AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld + AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host + AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir + AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + ]) + wl="$acl_cv_wl" + libext="$acl_cv_libext" + shlibext="$acl_cv_shlibext" + hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + hardcode_direct="$acl_cv_hardcode_direct" + hardcode_minus_L="$acl_cv_hardcode_minus_L" + sys_lib_search_path_spec="$acl_cv_sys_lib_search_path_spec" + sys_lib_dlsearch_path_spec="$acl_cv_sys_lib_dlsearch_path_spec" + dnl Determine whether the user wants rpath handling at all. + AC_ARG_ENABLE(rpath, + [ --disable-rpath do not hardcode runtime library paths], + :, enable_rpath=yes) +]) + +dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. +AC_DEFUN([AC_LIB_LINKFLAGS_BODY], +[ + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_ARG_WITH([lib$1-prefix], +[ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib + --without-lib$1-prefix don't search for lib$1 in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/lib" + fi + fi +]) + dnl Search the library and its dependencies in $additional_libdir and + dnl $LDFLAGS. Using breadth-first-seach. + LIB[]NAME= + LTLIB[]NAME= + INC[]NAME= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='$1 $2' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + dnl See if it was already located by an earlier AC_LIB_LINKFLAGS + dnl or AC_LIB_HAVE_LINKFLAGS call. + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" + else + dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined + dnl that this library doesn't exist. So just drop it. + : + fi + else + dnl Search the library lib$name in $additional_libdir and $LDFLAGS + dnl and the already constructed $LIBNAME/$LTLIBNAME. + found_dir= + found_la= + found_so= + found_a= + if test $use_additional = yes; then + if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then + found_dir="$additional_libdir" + found_so="$additional_libdir/lib$name.$shlibext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + else + if test -f "$additional_libdir/lib$name.$libext"; then + found_dir="$additional_libdir" + found_a="$additional_libdir/lib$name.$libext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then + found_dir="$dir" + found_so="$dir/lib$name.$shlibext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + else + if test -f "$dir/lib$name.$libext"; then + found_dir="$dir" + found_a="$dir/lib$name.$libext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + dnl Found the library. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + dnl Linking with a shared library. We attempt to hardcode its + dnl directory into the executable's runpath, unless it's the + dnl standard /usr/lib. + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then + dnl No hardcoding is needed. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + dnl The hardcoding into $LIBNAME is system dependent. + if test "$hardcode_direct" = yes; then + dnl Using DIR/libNAME.so during linking hardcodes DIR into the + dnl resulting binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + dnl Rely on "-L$found_dir". + dnl But don't add it if it's already contained in the LDFLAGS + dnl or the already constructed $LIBNAME + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" + fi + if test "$hardcode_minus_L" != no; then + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH + dnl here, because this doesn't fit in flags passed to the + dnl compiler. So give up. No hardcoding. This affects only + dnl very old systems. + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + dnl Linking with a static library. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" + else + dnl We shouldn't come here, but anyway it's good to have a + dnl fallback. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" + fi + fi + dnl Assume the include files are nearby. + additional_includedir= + case "$found_dir" in + */lib | */lib/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + dnl Potentially add $additional_includedir to $INCNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's /usr/local/include and we are using GCC on Linux, + dnl 3. if it's already present in $CPPFLAGS or the already + dnl constructed $INCNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INC[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $INCNAME. + INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + dnl Look for dependencies. + if test -n "$found_la"; then + dnl Read the .la file. It defines the variables + dnl dlname, library_names, old_library, dependency_libs, current, + dnl age, revision, installed, dlopen, dlpreopen, libdir. + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + dnl We use only dependency_libs. + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's /usr/local/lib and we are using GCC on Linux, + dnl 3. if it's already present in $LDFLAGS or the already + dnl constructed $LIBNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/lib"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/lib"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + dnl Handle this in the next round. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + dnl Handle this in the next round. Throw away the .la's + dnl directory; it is already contained in a preceding -L + dnl option. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + dnl Most likely an immediate library name. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" + ;; + esac + done + fi + else + dnl Didn't find the library; assume it is in the system directories + dnl known to the linker and runtime loader. (All the system + dnl directories known to the linker should also be known to the + dnl runtime loader, otherwise the system is severely misconfigured.) + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user must + dnl pass all path elements in one option. We can arrange that for a + dnl single library, but not when more than one $LIBNAMEs are used. + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" + done + dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl. + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + else + dnl The -rpath options are cumulative. + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + dnl When using libtool, the option that works for both libraries and + dnl executables is -R. The -R options are cumulative. + for found_dir in $ltrpathdirs; do + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" + done + fi +]) + +dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, +dnl unless already present in VAR. +dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes +dnl contains two or three consecutive elements that belong together. +AC_DEFUN([AC_LIB_APPENDTOVAR], +[ + for element in [$2]; do + haveit= + for x in $[$1]; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + [$1]="${[$1]}${[$1]:+ }$element" + fi + done +]) diff --git a/common/m4/lib-prefix.m4 b/common/m4/lib-prefix.m4 new file mode 100755 index 0000000..b8b79ab --- /dev/null +++ b/common/m4/lib-prefix.m4 @@ -0,0 +1,148 @@ +# lib-prefix.m4 serial 1 (gettext-0.11) +dnl Copyright (C) 2001-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed +dnl to access previously installed libraries. The basic assumption is that +dnl a user will want packages to use other packages he previously installed +dnl with the same --prefix option. +dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate +dnl libraries, but is otherwise very convenient. +AC_DEFUN([AC_LIB_PREFIX], +[ + AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_ARG_WITH([lib-prefix], +[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib + --without-lib-prefix don't search for libraries in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/lib" + fi + fi +]) + if test $use_additional = yes; then + dnl Potentially add $additional_includedir to $CPPFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's already present in $CPPFLAGS, + dnl 3. if it's /usr/local/include and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + for x in $CPPFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $CPPFLAGS. + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" + fi + fi + fi + fi + dnl Potentially add $additional_libdir to $LDFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's already present in $LDFLAGS, + dnl 3. if it's /usr/local/lib and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/lib"; then + haveit= + for x in $LDFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_libdir" = "X/usr/local/lib"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LDFLAGS. + LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" + fi + fi + fi + fi + fi +]) + +dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, +dnl acl_final_exec_prefix, containing the values to which $prefix and +dnl $exec_prefix will expand at the end of the configure script. +AC_DEFUN([AC_LIB_PREPARE_PREFIX], +[ + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the +dnl variables prefix and exec_prefix bound to the values they will have +dnl at the end of the configure script. +AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], +[ + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + $1 + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" +]) diff --git a/common/m4/lt~obsolete.m4 b/common/m4/lt~obsolete.m4 new file mode 100755 index 0000000..637bb20 --- /dev/null +++ b/common/m4/lt~obsolete.m4 @@ -0,0 +1,92 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 4 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) diff --git a/common/m4/pkg.m4 b/common/m4/pkg.m4 new file mode 100755 index 0000000..3c20213 --- /dev/null +++ b/common/m4/pkg.m4 @@ -0,0 +1,135 @@ +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# +# Copyright © 2004 Scott James Remnant <scott@netsplit.com>. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_ifval([$1], [$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi + +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# +# Similar to PKG_CHECK_MODULES, make sure that the first instance of +# this or PKG_CHECK_MODULES is called, or make sure to call +# PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_ifval([$2], [$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$PKG_CONFIG"; then + if test -n "$$1"; then + pkg_cv_[]$1="$$1" + else + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], + [pkg_failed=yes]) + fi +else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +if test $pkg_failed = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" 1>&AS_MESSAGE_LOG_FD + + ifelse([$4], , [AC_MSG_ERROR(dnl +[Package requirements ($2) were not met. +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively you may set the $1_CFLAGS and $1_LIBS environment variables +to avoid the need to call pkg-config. See the pkg-config man page for +more details.])], + [$4]) +elif test $pkg_failed = untried; then + ifelse([$4], , [AC_MSG_FAILURE(dnl +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively you may set the $1_CFLAGS and $1_LIBS environment variables +to avoid the need to call pkg-config. See the pkg-config man page for +more details. + +To get pkg-config, see <http://www.freedesktop.org/software/pkgconfig>.])], + [$4]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + ifelse([$3], , :, [$3]) +fi[]dnl +])# PKG_CHECK_MODULES diff --git a/common/m4/progtest.m4 b/common/m4/progtest.m4 new file mode 100755 index 0000000..443c8e3 --- /dev/null +++ b/common/m4/progtest.m4 @@ -0,0 +1,59 @@ +# progtest.m4 serial 2 (gettext-0.10.40) +dnl Copyright (C) 1996-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper <drepper@cygnus.com>, 1996. + +# Search path for a program which passes the given test. + +dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN([AM_PATH_PROG_WITH_TEST], +[# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + /*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in ifelse([$5], , $PATH, [$5]); do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) diff --git a/common/mangle-tmpl.py b/common/mangle-tmpl.py new file mode 100755 index 0000000..d319040 --- /dev/null +++ b/common/mangle-tmpl.py @@ -0,0 +1,155 @@ +# -*- Mode: Python -*- +# vi:si:et:sw=4:sts=4:ts=4 + +""" +use the output from gst-xmlinspect.py to mangle tmpl/*.sgml and +insert/overwrite Short Description and Long Description +""" + +# FIXME: right now it uses pygst and scans on its own; +# we really should use inspect/*.xml instead since the result of +# gst-xmlinspect.py is commited by the docs maintainer, who can be +# expected to have pygst, but this step should be done for every docs build, +# so no pygst allowed + +# read in inspect/*.xml +# for every tmpl/element-(name).xml: mangle with details from element + +import glob +import re +import sys +import os + +class Tmpl: + def __init__(self, filename): + self.filename = filename + self._sectionids = [] + self._sections = {} + + def read(self): + """ + Read and parse the sections from the given file. + """ + lines = open(self.filename).readlines() + matcher = re.compile("<!-- ##### SECTION (\S+) ##### -->\n") + id = None + + for line in lines: + match = matcher.search(line) + if match: + id = match.expand("\\1") + self._sectionids.append(id) + self._sections[id] = [] + else: + if not id: + sys.stderr.write( + "WARNING: line before a SECTION header: %s" % line) + else: + self._sections[id].append(line) + + def get_section(self, id): + """ + Get the content from the given section. + """ + return self._sections[id] + + def set_section(self, id, content): + """ + Replace the given section id with the given content. + """ + self._sections[id] = content + + def output(self): + """ + Return the output of the current template in the tmpl/*.sgml format. + """ + lines = [] + for id in self._sectionids: + lines.append("<!-- ##### SECTION %s ##### -->\n" % id) + for line in self._sections[id]: + lines.append(line) + + return "".join(lines) + + def write(self, backup=False): + """ + Write out the template file again, backing up the previous one. + """ + if backup: + target = self.filename + ".mangle.bak" + os.rename(self.filename, target) + + handle = open(self.filename, "w") + handle.write(self.output()) + handle.close() + +from xml.dom.ext.reader import Sax2 +from xml.dom.NodeFilter import NodeFilter + +def get_elements(file): + elements = {} + handle = open(file) + reader = Sax2.Reader() + doc = reader.fromStream(handle) + handle.close() + + walker = doc.createTreeWalker(doc.documentElement, + NodeFilter.SHOW_ELEMENT, None, 0) + while walker.currentNode and walker.currentNode.tagName != 'elements': + walker.nextNode() + + # we're at elements now + el = walker.firstChild() + while walker.currentNode: + element = walker.firstChild() + # loop over children of <element> + name = None + description = None + while walker.currentNode: + if walker.currentNode.tagName == 'name': + name = walker.currentNode.firstChild.data.encode('UTF-8') + if walker.currentNode.tagName == 'description': + description = walker.currentNode.firstChild.data.encode('UTF-8') + if not walker.nextSibling(): break + # back up to <element> + walker.parentNode() + elements[name] = {'description': description} + + if not walker.nextSibling(): break + + return elements + + +def main(): + if not len(sys.argv) == 3: + sys.stderr.write('Please specify the inspect/ dir and the tmpl/ dir') + sys.exit(1) + + inspectdir = sys.argv[1] + tmpldir = sys.argv[2] + + # parse all .xml files; build map of element name -> short desc + #for file in glob.glob("inspect/plugin-*.xml"): + elements = {} + for file in glob.glob("%s/plugin-*.xml" % inspectdir): + elements.update(get_elements(file)) + + for file in glob.glob("%s/element-*.sgml" % tmpldir): + base = os.path.basename(file) + element = base[len("element-"):-len(".sgml")] + tmpl = Tmpl(file) + tmpl.read() + if element in elements.keys(): + description = elements[element]['description'] + tmpl.set_section("Short_Description", "%s\n\n" % description) + + # put in an include if not yet there + line = '<include xmlns="http://www.w3.org/2003/XInclude" href="' + \ + 'element-' + element + '-details.xml" />\n' + section = tmpl.get_section("Long_Description") + if not section[0] == line: + section.insert(0, line) + tmpl.set_section("Long_Description", section) + tmpl.write() + +main() diff --git a/common/plugins.xsl b/common/plugins.xsl new file mode 100755 index 0000000..150087f --- /dev/null +++ b/common/plugins.xsl @@ -0,0 +1,200 @@ +<?xml version='1.0'?> <!--*- mode: xml -*--> + +<xsl:stylesheet + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:exsl="http://exslt.org/common" + extension-element-prefixes="exsl" + version="1.0"> +<xsl:output method="xml" indent="yes" + doctype-public ="-//OASIS//DTD DocBook XML V4.1.2//EN" + doctype-system = "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"/> + +<xsl:param name="module" /> + + <xsl:template match="element"> + <xsl:element name="varlistentry"> + <xsl:element name="term"> + <xsl:element name="link"> + <xsl:attribute name="linkend"><xsl:value-of select="$module" />-plugins-<xsl:value-of select="name"/></xsl:attribute> + <xsl:value-of select="name" /> + </xsl:element> + </xsl:element> + <xsl:element name="listitem"> + <xsl:element name="simpara"><xsl:value-of select="description" /></xsl:element> + </xsl:element> + </xsl:element> + <xsl:variable name="name"><xsl:copy-of select="name"/></xsl:variable> + <!-- here we write an element-(name)-details.xml file for the element --> + <exsl:document href="{concat ('xml/element-', $name, '-details.xml')}" method="xml" indent="yes"> + + <xsl:element name="refsect2"> + <xsl:element name="title">Element Information</xsl:element> + <xsl:element name="variablelist"> + + <!-- plugin name and link --> + <xsl:element name="varlistentry"> + <xsl:element name="term">plugin</xsl:element> + <xsl:element name="listitem"> + <xsl:element name="simpara"> + <xsl:element name="link"> + <xsl:attribute name="linkend">plugin-<xsl:value-of select="../../name"/></xsl:attribute> + <xsl:value-of select="../../name" /> + </xsl:element> + </xsl:element> + </xsl:element> + </xsl:element> + + <xsl:element name="varlistentry"> + <xsl:element name="term">author</xsl:element> + <xsl:element name="listitem"> + <xsl:element name="simpara"><xsl:value-of select="author" /></xsl:element> + </xsl:element> + </xsl:element> + + <xsl:element name="varlistentry"> + <xsl:element name="term">class</xsl:element> + <xsl:element name="listitem"> + <xsl:element name="simpara"><xsl:value-of select="class" /></xsl:element> + </xsl:element> + </xsl:element> + + </xsl:element> <!-- variablelist --> + + <xsl:element name="title">Element Pads</xsl:element> + <!-- process all caps --> + <xsl:for-each select="pads/caps"> + <xsl:element name="variablelist"> + <xsl:element name="varlistentry"> + <xsl:element name="term">name</xsl:element> + <xsl:element name="listitem"> + <xsl:element name="simpara"><xsl:value-of select="name" /></xsl:element> + </xsl:element> + </xsl:element> + + <xsl:element name="varlistentry"> + <xsl:element name="term">direction</xsl:element> + <xsl:element name="listitem"> + <xsl:element name="simpara"><xsl:value-of select="direction" /></xsl:element> + </xsl:element> + </xsl:element> + + <xsl:element name="varlistentry"> + <xsl:element name="term">presence</xsl:element> + <xsl:element name="listitem"> + <xsl:element name="simpara"><xsl:value-of select="presence" /></xsl:element> + </xsl:element> + </xsl:element> + + <xsl:element name="varlistentry"> + <xsl:element name="term">details</xsl:element> + <xsl:element name="listitem"> + <xsl:element name="simpara"><xsl:value-of select="details" /></xsl:element> + </xsl:element> + </xsl:element> + + </xsl:element> <!-- variablelist --> + + <!--xsl:element name="programlisting"><xsl:value-of select="details" /></xsl:element--> + + </xsl:for-each> + </xsl:element> + + </exsl:document> + </xsl:template> + + <xsl:template match="plugin"> + <xsl:element name="refentry"> + <xsl:attribute name="id"><xsl:value-of select="$module" />-plugins-plugin-<xsl:value-of select="name"/></xsl:attribute> + + <xsl:element name="refmeta"> + <xsl:element name="refentrytitle"> + <xsl:value-of select="name"/> + </xsl:element> + <xsl:element name="manvolnum">3</xsl:element> + <xsl:element name="refmiscinfo">FIXME Library</xsl:element> + </xsl:element> <!-- refmeta --> + + <xsl:element name="refnamediv"> + <xsl:element name="refname"> + <xsl:element name="anchor"> + <xsl:attribute name="id">plugin-<xsl:value-of select="name"/></xsl:attribute> + <xsl:value-of select="name"/> + </xsl:element> + </xsl:element> + + <xsl:element name="refpurpose"> + <xsl:value-of select="description"/> + </xsl:element> + </xsl:element> + + <xsl:element name="refsect1"> + <xsl:element name="title">Plugin Information</xsl:element> + <xsl:element name="variablelist"> + + <xsl:element name="varlistentry"> + <xsl:element name="term">filename</xsl:element> + <xsl:element name="listitem"> + <xsl:element name="simpara"><xsl:value-of select="basename" /></xsl:element> + </xsl:element> + </xsl:element> + + <xsl:element name="varlistentry"> + <xsl:element name="term">version</xsl:element> + <xsl:element name="listitem"> + <xsl:element name="simpara"><xsl:value-of select="version" /></xsl:element> + </xsl:element> + </xsl:element> + + <xsl:element name="varlistentry"> + <xsl:element name="term">run-time license</xsl:element> + <xsl:element name="listitem"> + <xsl:element name="simpara"><xsl:value-of select="license" /></xsl:element> + </xsl:element> + </xsl:element> + + <xsl:element name="varlistentry"> + <xsl:element name="term">package</xsl:element> + <xsl:element name="listitem"> + <xsl:element name="simpara"><xsl:value-of select="package" /></xsl:element> + </xsl:element> + </xsl:element> + + <xsl:element name="varlistentry"> + <xsl:element name="term">origin</xsl:element> + <xsl:element name="listitem"> + <xsl:element name="simpara"> + <!-- only show origin as link if it starts with http --> + <xsl:choose> + <xsl:when test="substring(@href, 1, 4) = 'http'"> + <xsl:element name="ulink"> + <xsl:attribute name="url"><xsl:value-of select="origin" /></xsl:attribute> + <xsl:value-of select="origin" /> + </xsl:element> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="origin" /> + </xsl:otherwise> + </xsl:choose> + </xsl:element> + </xsl:element> + </xsl:element> + + </xsl:element> + </xsl:element> + + <xsl:element name="refsect1"> + <xsl:element name="title">Elements</xsl:element> + <!-- process all elements --> + <xsl:element name="variablelist"> + <xsl:apply-templates select="elements"/> + </xsl:element> + </xsl:element> + + </xsl:element> + + </xsl:template> + + <!-- ignore --> + <xsl:template match="gst-plugin-paths" /> + +</xsl:stylesheet> diff --git a/common/po.mak b/common/po.mak new file mode 100755 index 0000000..e019fac --- /dev/null +++ b/common/po.mak @@ -0,0 +1,4 @@ +# rule to download the latest .po files +download-po: $(top_srcdir)/common/download-translations + $(top_srcdir)/common/download-translations $(PACKAGE) + diff --git a/common/release.mak b/common/release.mak new file mode 100755 index 0000000..afb0c8c --- /dev/null +++ b/common/release.mak @@ -0,0 +1,25 @@ +# include this snippet to add a common release: target by using +# include $(top_srcdir)/common/release.mak + +# make bz2 as well +AUTOMAKE_OPTIONS = dist-bzip2 + +release: dist + $(MAKE) $(PACKAGE)-$(VERSION).tar.gz.md5 + $(MAKE) $(PACKAGE)-$(VERSION).tar.bz2.md5 + +# generate md5 sum files +%.md5: % + md5sum $< > $@ + +# check that no marshal or enumtypes files are included +# this in turn ensures that distcheck fails for missing .list files which is currently +# shadowed when the corresponding .c and .h files are included. +distcheck-hook: + @test "x" = "x`find $(distdir) -name \*-enumtypes.[ch] | grep -v win32`" && \ + test "x" = "x`find $(distdir) -name \*-marshal.[ch]`" || \ + ( $(ECHO) "*** Leftover enumtypes or marshal files in the tarball." && \ + $(ECHO) "*** Make sure the following files are not disted:" && \ + find $(distdir) -name \*-enumtypes.[ch] | grep -v win32 && \ + find $(distdir) -name \*-marshal.[ch] && \ + false ) diff --git a/common/scangobj-merge.py b/common/scangobj-merge.py new file mode 100755 index 0000000..4917255 --- /dev/null +++ b/common/scangobj-merge.py @@ -0,0 +1,226 @@ +#!/usr/bin/python +# -*- Mode: Python -*- +# vi:si:et:sw=4:sts=4:ts=4 + +""" +parse, update and write .signals and .args files +""" + +from twisted.python import util + +import sys +import os + +def debug(*args): + pass + +class Object: + def __init__(self, name): + self._signals = util.OrderedDict() + self._args = util.OrderedDict() + self.name = name + + def __repr__(self): + return "<Object %s>" % self.name + + def add_signal(self, signal, overwrite=True): + if not overwrite and self._signals.has_key(signal.name): + raise IndexError, "signal %s already in %r" % (signal.name, self) + self._signals[signal.name] = signal + + def add_arg(self, arg, overwrite=True): + if not overwrite and self._args.has_key(arg.name): + raise IndexError, "arg %s already in %r" % (arg.name, self) + self._args[arg.name] = arg + +class Docable: + def __init__(self, **kwargs): + for key in self.attrs: + setattr(self, key, kwargs[key]) + self.dict = kwargs + + def __repr__(self): + return "<%r %s>" % (str(self.__class__), self.name) + +class Signal(Docable): + attrs = ['name', 'returns', 'args'] + +class Arg(Docable): + attrs = ['name', 'type', 'range', 'flags', 'nick', 'blurb', 'default'] + +class GDoc: + def load_file(self, filename): + try: + lines = open(filename).readlines() + self.load_data("".join(lines)) + except IOError: + print "WARNING - could not read from %s" % filename + + def save_file(self, filename, backup=False): + """ + Save the signals information to the given .signals file if the + file content changed. + """ + olddata = None + try: + lines = open(filename).readlines() + olddata = "".join(lines) + except IOError: + print "WARNING - could not read from %s" % filename + newdata = self.get_data() + if olddata and olddata == newdata: + return + + if olddata: + if backup: + os.rename(filename, filename + '.bak') + + handle = open(filename, "w") + handle.write(newdata) + handle.close() + +class Signals(GDoc): + def __init__(self): + self._objects = util.OrderedDict() + + def load_data(self, data): + """ + Load the .signals lines, creating our list of objects and signals. + """ + import re + smatcher = re.compile( + '(?s)' # make . match \n + '<SIGNAL>\n(.*?)</SIGNAL>\n' + ) + nmatcher = re.compile( + '<NAME>' + '(?P<object>\S*)' # store object + '::' + '(?P<signal>\S*)' # store signal + '</NAME>' + ) + rmatcher = re.compile( + '(?s)' # make . match \n + '<RETURNS>(?P<returns>\S*)</RETURNS>\n' # store returns + '(?P<args>.*)' # store args + ) + for block in smatcher.findall(data): + nmatch = nmatcher.search(block) + if nmatch: + o = nmatch.group('object') + debug("Found object", o) + debug("Found signal", nmatch.group('signal')) + if not self._objects.has_key(o): + object = Object(o) + self._objects[o] = object + + rmatch = rmatcher.search(block) + if rmatch: + dict = rmatch.groupdict().copy() + dict['name'] = nmatch.group('signal') + signal = Signal(**dict) + self._objects[o].add_signal(signal) + + def get_data(self): + lines = [] + for o in self._objects.values(): + for s in o._signals.values(): + block = """<SIGNAL> +<NAME>%(object)s::%(name)s</NAME> +<RETURNS>%(returns)s</RETURNS> +%(args)s</SIGNAL> +""" + d = s.dict.copy() + d['object'] = o.name + lines.append(block % d) + + return "\n".join(lines) + '\n' + +class Args(GDoc): + def __init__(self): + self._objects = util.OrderedDict() + + def load_data(self, data): + """ + Load the .args lines, creating our list of objects and args. + """ + import re + amatcher = re.compile( + '(?s)' # make . match \n + '<ARG>\n(.*?)</ARG>\n' + ) + nmatcher = re.compile( + '<NAME>' + '(?P<object>\S*)' # store object + '::' + '(?P<arg>\S*)' # store arg + '</NAME>' + ) + rmatcher = re.compile( + '(?s)' # make . match \n + '<TYPE>(?P<type>\S*)</TYPE>\n' # store type + '<RANGE>(?P<range>.*?)</RANGE>\n' # store range + '<FLAGS>(?P<flags>\S*)</FLAGS>\n' # store flags + '<NICK>(?P<nick>.*?)</NICK>\n' # store nick + '<BLURB>(?P<blurb>.*?)</BLURB>\n' # store blurb + '<DEFAULT>(?P<default>.*?)</DEFAULT>\n' # store default + ) + for block in amatcher.findall(data): + nmatch = nmatcher.search(block) + if nmatch: + o = nmatch.group('object') + debug("Found object", o) + debug("Found arg", nmatch.group('arg')) + if not self._objects.has_key(o): + object = Object(o) + self._objects[o] = object + + rmatch = rmatcher.search(block) + if rmatch: + dict = rmatch.groupdict().copy() + dict['name'] = nmatch.group('arg') + arg = Arg(**dict) + self._objects[o].add_arg(arg) + else: + print "ERROR: could not match arg from block %s" % block + + def get_data(self): + lines = [] + for o in self._objects.values(): + for a in o._args.values(): + block = """<ARG> +<NAME>%(object)s::%(name)s</NAME> +<TYPE>%(type)s</TYPE> +<RANGE>%(range)s</RANGE> +<FLAGS>%(flags)s</FLAGS> +<NICK>%(nick)s</NICK> +<BLURB>%(blurb)s</BLURB> +<DEFAULT>%(default)s</DEFAULT> +</ARG> +""" + d = a.dict.copy() + d['object'] = o.name + lines.append(block % d) + + return "\n".join(lines) + '\n' + +def main(argv): + modulename = None + try: + modulename = argv[1] + except IndexError: + sys.stderr.write('Pleae provide a documentation module name\n') + sys.exit(1) + + print "Merging scangobj output for %s" % modulename + signals = Signals() + signals.load_file(modulename + '.signals') + signals.load_file(modulename + '.signals.new') + signals.save_file(modulename + '.signals', backup=True) + + args = Args() + args.load_file(modulename + '.args') + args.load_file(modulename + '.args.new') + args.save_file(modulename + '.args', backup=True) + +main(sys.argv) diff --git a/common/upload.mak b/common/upload.mak new file mode 100755 index 0000000..60731e5 --- /dev/null +++ b/common/upload.mak @@ -0,0 +1,33 @@ +# this snippet is to be included by both our docbook manuals +# and gtk-doc API references + +# it adds an upload target to each of these dir's Makefiles + +# each Makefile.am should define the following variables: +# - DOC: the base name of the documentation +# (faq, manual, pwg, gstreamer, gstreamer-libs) +# - FORMATS: the formats in which DOC is output +# (html ps pdf) + +# if you want to use it, make sure your $HOME/.ssh/config file contains the +# correct User entry for the Host entry for the DOC_SERVER + +# these variables define the location of the online docs +DOC_SERVER = gstreamer.freedesktop.org +DOC_BASE = /srv/gstreamer.freedesktop.org/www/data/doc +DOC_URL = $(DOC_SERVER):$(DOC_BASE) + +upload: $(FORMATS) + @if test "x$(PACKAGE_VERSION_NANO)" = x0; then \ + export DOCVERSION=$(VERSION); \ + else export DOCVERSION=head; \ + fi; \ + export DIR=$(DOC_BASE)/gstreamer/$$DOCVERSION/$(DOC); \ + ssh $(DOC_SERVER) mkdir -p $$DIR; \ + if echo $(FORMATS) | grep html > /dev/null; then export SRC="$$SRC html"; fi; \ + if echo $(FORMATS) | grep ps > /dev/null; then export SRC="$$SRC $(DOC).ps"; fi; \ + if echo $(FORMATS) | grep pdf > /dev/null; then export SRC="$$SRC $(DOC).pdf"; fi; \ + echo Uploading $$SRC to $(DOC_SERVER):$$DIR; \ + rsync -rv -e ssh --delete $$SRC $(DOC_SERVER):$$DIR; \ + ssh $(DOC_SERVER) chmod -R g+w $$DIR; \ + echo Done diff --git a/common/win32.mak b/common/win32.mak new file mode 100755 index 0000000..63b1310 --- /dev/null +++ b/common/win32.mak @@ -0,0 +1,54 @@ +# various tests to make sure we dist the win32 stuff (for MSVC builds) right + +# the MANIFEST contains all win32 related files that should be disted +win32 = $(shell cat $(top_srcdir)/win32/MANIFEST) + +# wildcard is apparently not portable to other makes, hence the use of find +# these are library .def files with the symbols to export +win32defs = $(shell find $(top_srcdir)/win32/common -name '*.def') + +# wildcard is apparently not portable to other makes, hence the use of find +# these are files that need to be disted with CRLF line endings: +win32crlf = $(shell find $(top_srcdir)/win32 -name '*.dsw' -o -name '*.dsp') + +win32-debug: + @echo; \ + echo win32 = $(win32); \ + echo; \ + echo win32defs = $(win32defs); \ + echo; \ + echo win32crlf = $(win32crlf); \ + echo + +win32-check-crlf: + @echo Checking win32 files for CR LF line endings ...; \ + fail=0 ; \ + for each in $(win32crlf) ; do \ + if ! (file $$each | grep CRLF >/dev/null) ; then \ + echo $$each must be fixed to have CRLF line endings ; \ + fail=1; \ + fi ; \ + done ; \ + exit $$fail + +# make sure all symbols we export on linux are defined in the win32 .def too +# (don't care about other unixes for now, it's enough if it works on one of +# the linux build bots; we assume .so ) +check-exports: + fail=0 ; \ + for l in $(win32defs); do \ + libbase=`basename "$$l" ".def"`; \ + libso=`find "$(top_builddir)" -name "$$libbase-@GST_MAJORMINOR@.so"`; \ + libdef="$(top_srcdir)/win32/common/$$libbase.def"; \ + if test "x$$libso" != "x"; then \ + echo Checking symbols in $$libso; \ + if ! ($(top_srcdir)/common/check-exports $$libdef $$libso) ; then \ + fail=1; \ + fi; \ + fi; \ + done + + +dist-hook: check-exports win32-check-crlf + + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..b6f33aa --- /dev/null +++ b/configure.ac @@ -0,0 +1,199 @@ +dnl Copyright (c) 2006 Software Laboratory, SAMSUNG Electronics, Inc. +dnl All rights reserved. +dnl +dnl This software is the confidential and proprietary information of +dnl SAMSUNG Electronics, Inc. ("Confidential Information"). +dnl You shall not disclose such Confidential Information and shall use it +dnl only in accordance with the terms of the license agreement you entered into +dnl with SAMSUNG Electronics. +dnl +dnl Orignal by Jeechul jeon <heechul.jeon@samsung.com> + +AC_INIT(gst-plugins-s5pc210, 1.0) + +dnl versions of gstreamer and plugins-base +GST_MAJORMINOR=0.10 +GST_REQUIRED=0.10.0 +GSTPB_REQUIRED=0.10.0 +AC_SUBST(GST_MAJORMINOR) + +dnl fill in your package name and version here +dnl the fourth (nano) number should be 0 for a release, 1 for CVS, +dnl and 2... for a prerelease + +dnl when going to/from release please set the nano correctly ! +dnl releases only do Wall, cvs and prerelease does Werror too +AS_VERSION(gst-plugin, GST_PLUGIN_VERSION, 0, 10, 0, 1, + GST_PLUGIN_CVS="no", GST_PLUGIN_CVS="yes") + +dnl AM_MAINTAINER_MODE provides the option to enable maintainer mode +AM_MAINTAINER_MODE + +#AM_INIT_AUTOMAKE($PACKAGE, $VERSION) +AM_INIT_AUTOMAKE + +#AC_CONFIG_MACRO_DIR([m4]) + +dnl make aclocal work in maintainer mode +dnl AC_SUBST(ACLOCAL_AMFLAGS, "-I m4") + +dnl Add parameters for aclocal +AC_SUBST(ACLOCAL_AMFLAGS, "-I m4 -I common/m4") + +AM_CONFIG_HEADER(config.h) + +dnl check for tools +AC_PROG_CC +AC_PROG_CXX +AC_PROG_LIBTOOL + +AC_ARG_ENABLE(aquila, AC_HELP_STRING([--enable-aquila], [using enable-aquila]), + [ + case "${enableval}" in + yes) IS_AQUILA=yes ;; + no) IS_AQUILA=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-aquila) ;; + esac + ], + [IS_AQUILA=yes]) +AM_CONDITIONAL([IS_AQUILA], [test "x$IS_AQUILA" = "xyes"]) + +AC_ARG_ENABLE(sdk, AC_HELP_STRING([--enable-sdk], [sdk build]), + [ + case "${enableval}" in + yes) IS_SDK=yes ;; + no) IS_SDK=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-sdk) ;; + esac + ] + [IS_SDK=no]) +AM_CONDITIONAL([IS_SDK], [test "x$IS_SDK" = "xyes"]) + +dnl decide on error flags +AS_COMPILER_FLAG(-Wall, GST_WALL="yes", GST_WALL="no") + +if test "x$GST_WALL" = "xyes"; then + GST_ERROR="$GST_ERROR -Wall" + +# if test "x$GST_PLUGIN_CVS" = "xyes"; then +# AS_COMPILER_FLAG(-Werror,GST_ERROR="$GST_ERROR -Werror",GST_ERROR="$GST_ERROR") +# fi +fi + +dnl Check for pkgconfig first +AC_CHECK_PROG(HAVE_PKGCONFIG, pkg-config, yes, no) + +dnl Give error and exit if we don't have pkgconfig +if test "x$HAVE_PKGCONFIG" = "xno"; then + AC_MSG_ERROR(you need to have pkgconfig installed !) +fi + +dnl Now we're ready to ask for gstreamer libs and cflags +dnl And we can also ask for the right version of gstreamer +PKG_CHECK_MODULES(GST, \ + gstreamer-$GST_MAJORMINOR >= $GST_REQUIRED, + HAVE_GST=yes,HAVE_GST=no) + +dnl Give error and exit if we don't have gstreamer +if test "x$HAVE_GST" = "xno"; then + AC_MSG_ERROR(you need gstreamer development packages installed !) +fi + +dnl append GST_ERROR cflags to GST_CFLAGS +GST_CFLAGS="$GST_CFLAGS $GST_ERROR" + +dnl make GST_CFLAGS and GST_LIBS available +PKG_CHECK_MODULES(GST, gstreamer-0.10 >= 0.10) +AC_SUBST(GST_CFLAGS) +AC_SUBST(GST_LIBS) + +dnl make GST_MAJORMINOR available in Makefile.am +AC_SUBST(GST_MAJORMINOR) + +dnl If we need them, we can also use the base class libraries +PKG_CHECK_MODULES(GST_BASE, gstreamer-base-$GST_MAJORMINOR >= $GST_REQUIRED, + HAVE_GST_BASE=yes, HAVE_GST_BASE=no) + +dnl Give a warning if we don't have gstreamer libs +dnl you can turn this into an error if you need them +if test "x$HAVE_GST_BASE" = "xno"; then + AC_MSG_NOTICE(no GStreamer base class libraries found (gstreamer-base-$GST_MAJORMINOR)) +fi + +dnl make _CFLAGS and _LIBS available +AC_SUBST(GST_BASE_CFLAGS) +AC_SUBST(GST_BASE_LIBS) + +dnl If we need them, we can also use the gstreamer-plugins-base libraries +PKG_CHECK_MODULES(GSTPB_BASE, + gstreamer-plugins-base-$GST_MAJORMINOR >= $GSTPB_REQUIRED, + HAVE_GSTPB_BASE=yes, HAVE_GSTPB_BASE=no) + +dnl Give a warning if we don't have gstreamer libs +dnl you can turn this into an error if you need them +if test "x$HAVE_GSTPB_BASE" = "xno"; then + AC_MSG_NOTICE(no GStreamer Plugins Base libraries found (gstreamer-plugins-base-$GST_MAJORMINOR)) +fi + +dnl make _CFLAGS and _LIBS available +AC_SUBST(GSTPB_BASE_CFLAGS) +AC_SUBST(GSTPB_BASE_LIBS) + +dnl If we need them, we can also use the gstreamer-controller libraries +PKG_CHECK_MODULES(GSTCTRL, + gstreamer-controller-$GST_MAJORMINOR >= $GSTPB_REQUIRED, + HAVE_GSTCTRL=yes, HAVE_GSTCTRL=no) + +dnl Give a warning if we don't have gstreamer-controller +dnl you can turn this into an error if you need them +if test "x$HAVE_GSTCTRL" = "xno"; then + AC_MSG_NOTICE(no GStreamer Controller libraries found (gstreamer-controller-$GST_MAJORMINOR)) +fi + +dnl make _CFLAGS and _LIBS available +AC_SUBST(GSTCTRL_CFLAGS) +AC_SUBST(GSTCTRL_LIBS) + +dnl set the plugindir where plugins should be installed +if test "x${prefix}" = "x$HOME"; then + plugindir="$HOME/.gstreamer-$GST_MAJORMINOR/plugins" +else + plugindir="\$(libdir)/gstreamer-$GST_MAJORMINOR" +fi +AC_SUBST(plugindir) + +dnl set proper LDFLAGS for plugins +GST_PLUGIN_LDFLAGS='-module -avoid-version -export-symbols-regex [_]*\(gst_\|Gst\|GST_\).*' +AC_SUBST(GST_PLUGIN_LDFLAGS) + +PKG_CHECK_MODULES(GST_AUDIO, gstreamer-audio-$GST_MAJORMINOR >= $GST_REQUIRED ) + + +dnl make _CFLAGS and _LIBS available +AC_SUBST(GST_AUDIO_CFLAGS) +AC_SUBST(GST_AUDIO_LIBS) + +PKG_CHECK_MODULES(GST_VIDEO, gstreamer-video-$GST_MAJORMINOR >= $GST_REQUIRED) + +dnl make _CFLAGS and _LIBS available +AC_SUBST(GST_VIDEO_CFLAGS) +AC_SUBST(GST_VIDEO_LIBS) + +dnl gstreamer interface for camerasrc plugin +PKG_CHECK_MODULES(GST_INTERFACES, gstreamer-interfaces-$GST_MAJORMINOR >= $GST_REQUIRED) +AC_SUBST(GST_INTERFACES_CFLAGS) +AC_SUBST(GST_INTERFACES_LIBS) + +dnl use time analysis module +PKG_CHECK_MODULES(MMTA, mm-ta) +AC_SUBST(MMTA_CFLAGS) +AC_SUBST(MMTA_LIBS) + +AC_OUTPUT( +Makefile +common/Makefile +common/m4/Makefile +camerasrc/Makefile +camerasrc/src/Makefile +) + diff --git a/control.in b/control.in new file mode 100755 index 0000000..bd7685e --- /dev/null +++ b/control.in @@ -0,0 +1,11 @@ +Package: gst-plugins-c110-@MACHINE@ +Priority: optional +Version: @VERSION@ +Section: middleware +Architecture: @ARCH@ +Maintainer: Haejeong Kim <backto.kim@samsung.com> +Source: Samsung Linux Platform +Depends: +Description: Gstreamer package for multimedia framework middleware package + +: @@ -0,0 +1,530 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2005-07-09.11 + +# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to <bug-automake@gnu.org>. +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + stat=$? + + if test -f "$tmpdepfile"; then : + else + stripped=`echo "$stripped" | sed 's,^.*/,,'` + tmpdepfile="$stripped.u" + fi + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + outname="$stripped.o" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mecanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..4d4a951 --- /dev/null +++ b/install-sh @@ -0,0 +1,323 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2005-05-14.22 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +chmodcmd="$chmodprog 0755" +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + *) # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + test -n "$dir_arg$dstarg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + mkdircmd=: + chmodcmd= + else + mkdircmd=$mkdirprog + fi + else + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dst=$dst/`basename "$src"` + fi + fi + + # This sed command emulates the dirname command. + dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + + # Skip lots of stat calls in the usual case. + if test ! -d "$dstdir"; then + defaultIFS=' + ' + IFS="${IFS-$defaultIFS}" + + oIFS=$IFS + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` + shift + IFS=$oIFS + + pathcomp= + + while test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" + # mkdir can fail with a `File exist' error in case several + # install-sh are creating the directory concurrently. This + # is OK. + test -d "$pathcomp" || exit + fi + pathcomp=$pathcomp/ + done + fi + + if test -n "$dir_arg"; then + $doit $mkdircmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + + else + dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Copy the file name to the temp name. + $doit $cpprog "$src" "$dsttmp" && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + } + } + fi || { (exit 1); exit 1; } +done + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit 0 +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/m4/Makefile.am b/m4/Makefile.am new file mode 100755 index 0000000..5fa63aa --- /dev/null +++ b/m4/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST = as-version.m4 as-compiler-flag.m4
diff --git a/m4/as-compiler-flag.m4 b/m4/as-compiler-flag.m4 new file mode 100755 index 0000000..4134857 --- /dev/null +++ b/m4/as-compiler-flag.m4 @@ -0,0 +1,25 @@ +dnl as-compiler-flag.m4 0.0.1
+dnl autostars m4 macro for detection of compiler flags
+dnl
+dnl ds@schleef.org
+
+AC_DEFUN([AS_COMPILER_FLAG],
+[
+ AC_MSG_CHECKING([to see if compiler understands $1])
+
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $1"
+
+ AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no])
+ CFLAGS="$save_CFLAGS"
+
+ if test "X$flag_ok" = Xyes ; then
+ $2
+ true
+ else
+ $3
+ true
+ fi
+ AC_MSG_RESULT([$flag_ok])
+])
+
diff --git a/m4/as-version.m4 b/m4/as-version.m4 new file mode 100755 index 0000000..249102b --- /dev/null +++ b/m4/as-version.m4 @@ -0,0 +1,66 @@ +dnl as-version.m4 0.1.0
+
+dnl autostars m4 macro for versioning
+
+dnl Thomas Vander Stichele <thomas at apestaart dot org>
+
+dnl $Id: as-version.m4,v 1.2 2004-09-17 22:18:03 leroutier Exp $
+
+dnl AS_VERSION(PACKAGE, PREFIX, MAJOR, MINOR, MICRO, NANO,
+dnl ACTION-IF-NO-NANO, [ACTION-IF-NANO])
+
+dnl example
+dnl AS_VERSION(gstreamer, GST_VERSION, 0, 3, 2,)
+dnl for a 0.3.2 release version
+
+dnl this macro
+dnl - defines [$PREFIX]_MAJOR, MINOR and MICRO
+dnl - if NANO is empty, then we're in release mode, else in cvs/dev mode
+dnl - defines [$PREFIX], VERSION, and [$PREFIX]_RELEASE
+dnl - executes the relevant action
+dnl - AC_SUBST's PACKAGE, VERSION, [$PREFIX] and [$PREFIX]_RELEASE
+dnl as well as the little ones
+dnl - doesn't call AM_INIT_AUTOMAKE anymore because it prevents
+dnl maintainer mode from running ok
+dnl
+dnl don't forget to put #undef [$2] and [$2]_RELEASE in acconfig.h
+dnl if you use acconfig.h
+
+AC_DEFUN([AS_VERSION],
+[
+ PACKAGE=[$1]
+ [$2]_MAJOR=[$3]
+ [$2]_MINOR=[$4]
+ [$2]_MICRO=[$5]
+ NANO=[$6]
+ [$2]_NANO=$NANO
+ if test "x$NANO" = "x" || test "x$NANO" = "x0";
+ then
+ AC_MSG_NOTICE(configuring [$1] for release)
+ VERSION=[$3].[$4].[$5]
+ [$2]_RELEASE=1
+ dnl execute action
+ ifelse([$7], , :, [$7])
+ else
+ AC_MSG_NOTICE(configuring [$1] for development with nano $NANO)
+ VERSION=[$3].[$4].[$5].$NANO
+ [$2]_RELEASE=0.`date +%Y%m%d.%H%M%S`
+ dnl execute action
+ ifelse([$8], , :, [$8])
+ fi
+
+ [$2]=$VERSION
+ AC_DEFINE_UNQUOTED([$2], "$[$2]", [Define the version])
+ AC_SUBST([$2])
+ AC_DEFINE_UNQUOTED([$2]_RELEASE, "$[$2]_RELEASE", [Define the release version])
+ AC_SUBST([$2]_RELEASE)
+
+ AC_SUBST([$2]_MAJOR)
+ AC_SUBST([$2]_MINOR)
+ AC_SUBST([$2]_MICRO)
+ AC_SUBST([$2]_NANO)
+ AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Define the package name])
+ AC_SUBST(PACKAGE)
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Define the version])
+ AC_SUBST(VERSION)
+])
diff --git a/m4/lt~obsolete.m4 b/m4/lt~obsolete.m4 new file mode 100644 index 0000000..637bb20 --- /dev/null +++ b/m4/lt~obsolete.m4 @@ -0,0 +1,92 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 4 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) @@ -0,0 +1,360 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2005-06-08.21 + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Send bug reports to <bug-automake@gnu.org>." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). +case "$1" in + lex|yacc) + # Not GNU programs, they don't have --version. + ;; + + tar) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/packaging/gst-plugins-s5pc2xx.spec b/packaging/gst-plugins-s5pc2xx.spec new file mode 100644 index 0000000..f81f16a --- /dev/null +++ b/packaging/gst-plugins-s5pc2xx.spec @@ -0,0 +1,35 @@ +Name: gst-plugins-s5pc2xx +Summary: Gstreamer codec plugins package for S5PC2XX series +Version: 0.3.14 +Release: 0 +Group: libs +License: LGPLv2+ +Source0: %{name}-%{version}.tar.gz +ExclusiveArch: %arm +BuildRequires: pkgconfig(gstreamer-plugins-base-0.10) +BuildRequires: pkgconfig(mm-ta) +BuildRequires: gstreamer-devel +BuildRequires: autoconf +BuildRequires: kernel-headers + +%description +Gstreamer codec plugins package for S5PC2XX series + GStreamer is a streaming media framework, based on graphs of filters + which operate on media data. Multimedia Framework using this plugins + library can encode and decode video, audio, and speech.. + +%prep +%setup -q + +%build +sh ./autogen.sh +%configure --disable-static +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + +%files +%defattr(-,root,root,-) +%{_libdir}/gstreamer-0.10/lib*.so* |