From 5029c85a46a8c366c4bf272d503e22bbcd624ece Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 9 Oct 2008 13:29:12 +0100 Subject: [PATCH] Initial import --- AUTHORS | 1 + COPYING | 481 +++++++++ COPYING.LIB | 481 +++++++++ ChangeLog | 0 Makefile.am | 32 + NEWS | 1 + README | 18 + RELEASE | 0 REQUIREMENTS | 3 + TODO | 4 + autogen.sh | 103 ++ common/ChangeLog | 1041 +++++++++++++++++++ common/Makefile.am | 15 + common/c-to-xml.py | 34 + common/check.mak | 149 +++ common/coverage/coverage-report-entry.pl | 70 ++ common/coverage/coverage-report.pl | 125 +++ common/coverage/coverage-report.xsl | 235 +++++ common/coverage/lcov.mak | 29 + common/gettext.patch | 23 + common/glib-gen.mak | 42 + common/gst-autogen.sh | 308 ++++++ common/gst-xmlinspect.py | 168 +++ common/gst.supp | 1660 ++++++++++++++++++++++++++++++ common/gstdoc-scangobj | 1562 ++++++++++++++++++++++++++++ common/gtk-doc-plugins.mak | 358 +++++++ common/gtk-doc.mak | 260 +++++ common/m4/Makefile.am | 28 + common/m4/README | 3 + common/m4/as-ac-expand.m4 | 43 + common/m4/as-auto-alt.m4 | 50 + common/m4/as-compiler-flag.m4 | 33 + common/m4/as-compiler.m4 | 44 + common/m4/as-docbook.m4 | 66 ++ common/m4/as-libtool-tags.m4 | 83 ++ common/m4/as-libtool.m4 | 45 + common/m4/as-python.m4 | 152 +++ common/m4/as-scrub-include.m4 | 36 + common/m4/as-version.m4 | 71 ++ common/m4/ax_create_stdint_h.m4 | 569 ++++++++++ common/m4/check.m4 | 181 ++++ common/m4/glib-gettext.m4 | 380 +++++++ common/m4/gst-arch.m4 | 123 +++ common/m4/gst-args.m4 | 276 +++++ common/m4/gst-check.m4 | 138 +++ common/m4/gst-debuginfo.m4 | 46 + common/m4/gst-default.m4 | 45 + common/m4/gst-doc.m4 | 148 +++ common/m4/gst-error.m4 | 71 ++ common/m4/gst-feature.m4 | 285 +++++ common/m4/gst-function.m4 | 63 ++ common/m4/gst-gettext.m4 | 21 + common/m4/gst-glib2.m4 | 26 + common/m4/gst-libxml2.m4 | 43 + common/m4/gst-plugindir.m4 | 17 + common/m4/gst-valgrind.m4 | 35 + common/m4/gtk-doc.m4 | 53 + common/m4/pkg.m4 | 131 +++ common/mangle-tmpl.py | 155 +++ common/plugins.xsl | 200 ++++ common/po.mak | 4 + common/release.mak | 25 + common/scangobj-merge.py | 226 ++++ common/upload.mak | 33 + configure.ac | 222 ++++ docs/design/gst-rtp-server-design | 35 + gst-rtsp.spec.in | 54 + m4/Makefile.am | 18 + m4/codeset.m4 | 23 + src/Makefile.am | 20 + src/main.c | 43 + src/rtsp-client.c | 811 +++++++++++++++ src/rtsp-client.h | 89 ++ src/rtsp-media.c | 266 +++++ src/rtsp-media.h | 79 ++ src/rtsp-server.c | 232 +++++ src/rtsp-server.h | 86 ++ src/rtsp-session-pool.c | 165 +++ src/rtsp-session-pool.h | 69 ++ src/rtsp-session.c | 503 +++++++++ src/rtsp-session.h | 138 +++ 81 files changed, 14004 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 COPYING.LIB create mode 100644 ChangeLog create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100644 RELEASE create mode 100644 REQUIREMENTS create mode 100644 TODO create mode 100755 autogen.sh create mode 100644 common/ChangeLog create mode 100644 common/Makefile.am create mode 100644 common/c-to-xml.py create mode 100644 common/check.mak create mode 100644 common/coverage/coverage-report-entry.pl create mode 100644 common/coverage/coverage-report.pl create mode 100644 common/coverage/coverage-report.xsl create mode 100644 common/coverage/lcov.mak create mode 100644 common/gettext.patch create mode 100644 common/glib-gen.mak create mode 100644 common/gst-autogen.sh create mode 100644 common/gst-xmlinspect.py create mode 100644 common/gst.supp create mode 100755 common/gstdoc-scangobj create mode 100644 common/gtk-doc-plugins.mak create mode 100644 common/gtk-doc.mak create mode 100644 common/m4/Makefile.am create mode 100644 common/m4/README create mode 100644 common/m4/as-ac-expand.m4 create mode 100644 common/m4/as-auto-alt.m4 create mode 100644 common/m4/as-compiler-flag.m4 create mode 100644 common/m4/as-compiler.m4 create mode 100644 common/m4/as-docbook.m4 create mode 100644 common/m4/as-libtool-tags.m4 create mode 100644 common/m4/as-libtool.m4 create mode 100644 common/m4/as-python.m4 create mode 100644 common/m4/as-scrub-include.m4 create mode 100644 common/m4/as-version.m4 create mode 100644 common/m4/ax_create_stdint_h.m4 create mode 100644 common/m4/check.m4 create mode 100644 common/m4/glib-gettext.m4 create mode 100644 common/m4/gst-arch.m4 create mode 100644 common/m4/gst-args.m4 create mode 100644 common/m4/gst-check.m4 create mode 100644 common/m4/gst-debuginfo.m4 create mode 100644 common/m4/gst-default.m4 create mode 100644 common/m4/gst-doc.m4 create mode 100644 common/m4/gst-error.m4 create mode 100644 common/m4/gst-feature.m4 create mode 100644 common/m4/gst-function.m4 create mode 100644 common/m4/gst-gettext.m4 create mode 100644 common/m4/gst-glib2.m4 create mode 100644 common/m4/gst-libxml2.m4 create mode 100644 common/m4/gst-plugindir.m4 create mode 100644 common/m4/gst-valgrind.m4 create mode 100644 common/m4/gtk-doc.m4 create mode 100644 common/m4/pkg.m4 create mode 100644 common/mangle-tmpl.py create mode 100644 common/plugins.xsl create mode 100644 common/po.mak create mode 100644 common/release.mak create mode 100755 common/scangobj-merge.py create mode 100644 common/upload.mak create mode 100644 configure.ac create mode 100644 docs/design/gst-rtp-server-design create mode 100644 gst-rtsp.spec.in create mode 100644 m4/Makefile.am create mode 100644 m4/codeset.m4 create mode 100644 src/Makefile.am create mode 100644 src/main.c create mode 100644 src/rtsp-client.c create mode 100644 src/rtsp-client.h create mode 100644 src/rtsp-media.c create mode 100644 src/rtsp-media.h create mode 100644 src/rtsp-server.c create mode 100644 src/rtsp-server.h create mode 100644 src/rtsp-session-pool.c create mode 100644 src/rtsp-session-pool.h create mode 100644 src/rtsp-session.c create mode 100644 src/rtsp-session.h diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..ecef28e --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Wim Taymans diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..eb685a5 --- /dev/null +++ b/COPYING @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, 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 library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + 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 Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the 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 a program 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. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + 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, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +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 compile 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) 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. + + c) 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. + + d) 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 source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + 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 to +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 Library 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 + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 0000000..eb685a5 --- /dev/null +++ b/COPYING.LIB @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, 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 library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + 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 Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the 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 a program 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. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + 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, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +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 compile 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) 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. + + c) 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. + + d) 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 source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + 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 to +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 Library 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 + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..289f162 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,32 @@ +DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc + +SUBDIRS = \ + src \ + m4 \ + common + +DIST_SUBDIRS = $(SUBDIRS) + +EXTRA_DIST = \ + ChangeLog autogen.sh depcomp \ + AUTHORS COPYING NEWS README RELEASE REQUIREMENTS \ + gst-rtsp.spec docs/design/gst-rtp-server-design + +ACLOCAL_AMFLAGS = -I common/m4 -I m4 + +DISTCLEANFILES = _stdint.h gst-rtsp.spec + +include $(top_srcdir)/common/release.mak +include $(top_srcdir)/common/po.mak + +check-valgrind: + cd tests/check && make check-valgrind + +if HAVE_CHECK +check-torture: + cd tests/check && make torture +else +check-torture: + true +endif + diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..6abbfaa --- /dev/null +++ b/NEWS @@ -0,0 +1 @@ +This is GstRTSP diff --git a/README b/README new file mode 100644 index 0000000..a785c59 --- /dev/null +++ b/README @@ -0,0 +1,18 @@ +GstRTSP is an RTSP server built on top of GStreamer (http://gstreamer.net). + +Currently there is no configuration tools for this server so any streamed +files need to be hardcoded into the file: +src/rtsp-media.c + +Edit in your sources after the examples found under the section headlines by +* STREAMING CONFIGURATION + +Once the server is started you should be able to view the streams at: +rtsp://localhost:1554/@name_of_stream@ + +The replacement for @name_of_stream@ is from the rtsp-media.c editing you did above. + +You should be able to get the http proxy link working without any editing of the rtsp-media.c file as it points to an online http file: + +rtsp://localhost:1554/rtphttpproxy + diff --git a/RELEASE b/RELEASE new file mode 100644 index 0000000..e69de29 diff --git a/REQUIREMENTS b/REQUIREMENTS new file mode 100644 index 0000000..14e4172 --- /dev/null +++ b/REQUIREMENTS @@ -0,0 +1,3 @@ +You need to have GStreamer. You can use an installed version of +GStreamer or from its build dir. + diff --git a/TODO b/TODO new file mode 100644 index 0000000..1b28c23 --- /dev/null +++ b/TODO @@ -0,0 +1,4 @@ + + - implement multicast and TCP transports + - use a config file to configure the server + - error recovery diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..0a8c579 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,103 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. + +DIE=0 +package=gst-rtsp +srcfile=src/rtsp-server.c + +# a quick cvs co to ease the transition +if test ! -d common; +then + echo "+ getting common/ from cvs" + if test -e CVS/Tag + then + TAG="-r `tail -c +2 CVS/Tag`" + fi + cvs co $TAG common +fi + +# source helper functions +if test ! -f common/gst-autogen.sh; +then + echo There is something wrong with your source tree. + echo You are missing common/gst-autogen.sh + exit 1 +fi +. common/gst-autogen.sh + +CONFIGURE_DEF_OPT='--enable-maintainer-mode --enable-gtk-doc' + +autogen_options $@ + +echo -n "+ check for build tools" +if test ! -z "$NOCHECK"; then echo ": skipped version checks"; else echo; fi +version_check "autoconf" "$AUTOCONF autoconf autoconf259 autoconf257 autoconf-2.54 autoconf-2.53 autoconf253 autoconf-2.52 autoconf252" \ + "ftp://ftp.gnu.org/pub/gnu/autoconf/" 2 52 || DIE=1 +version_check "automake" "$AUTOMAKE automake automake-1.9 automake19 automake-1.8 automake18 automake-1.7 automake17 automake-1.6 automake16" \ + "ftp://ftp.gnu.org/pub/gnu/automake/" 1 7 || DIE=1 +version_check "autopoint" "autopoint" \ + "ftp://ftp.gnu.org/pub/gnu/gettext/" 0 11 5 || DIE=1 +version_check "libtoolize" "libtoolize libtoolize15 glibtoolize" \ + "ftp://ftp.gnu.org/pub/gnu/libtool/" 1 5 0 || DIE=1 +version_check "pkg-config" "" \ + "http://www.freedesktop.org/software/pkgconfig" 0 8 0 || DIE=1 + +die_check $DIE + +autoconf_2_52d_check || DIE=1 +aclocal_check || DIE=1 +autoheader_check || DIE=1 + +die_check $DIE + +# if no arguments specified then this will be printed +if test -z "$*"; then + echo "+ checking for autogen.sh options" + echo " This autogen script will automatically run ./configure as:" + echo " ./configure $CONFIGURE_DEF_OPT" + echo " To pass any additional options, please specify them on the $0" + echo " command line." +fi + +toplevel_check $srcfile + +tool_run "$aclocal" "-I m4 -I common/m4 $ACLOCAL_FLAGS" +tool_run "$libtoolize" "--copy --force" +tool_run "$autoheader" + +# touch the stamp-h.in build stamp so we don't re-run autoheader in maintainer mode -- wingo +echo timestamp > stamp-h.in 2> /dev/null + +tool_run "$autoconf" +tool_run "$automake" "-a -c" + +# if enable exists, add an -enable option for each of the lines in that file +if test -f enable; then + for a in `cat enable`; do + CONFIGURE_FILE_OPT="--enable-$a" + done +fi + +# if disable exists, add an -disable option for each of the lines in that file +if test -f disable; then + for a in `cat disable`; do + CONFIGURE_FILE_OPT="$CONFIGURE_FILE_OPT --disable-$a" + done +fi + +test -n "$NOCONFIGURE" && { + echo "+ skipping configure stage for package $package, as requested." + echo "+ autogen.sh done." + exit 0 +} + +echo "+ running configure ... " +test ! -z "$CONFIGURE_DEF_OPT" && echo " ./configure default flags: $CONFIGURE_DEF_OPT" +test ! -z "$CONFIGURE_EXT_OPT" && echo " ./configure external flags: $CONFIGURE_EXT_OPT" +test ! -z "$CONFIGURE_FILE_OPT" && echo " ./configure enable/disable flags: $CONFIGURE_FILE_OPT" +echo + +./configure $CONFIGURE_DEF_OPT $CONFIGURE_EXT_OPT $CONFIGURE_FILE_OPT || { + echo " configure failed" + exit 1 +} diff --git a/common/ChangeLog b/common/ChangeLog new file mode 100644 index 0000000..8f8b853 --- /dev/null +++ b/common/ChangeLog @@ -0,0 +1,1041 @@ +2007-09-21 Sebastian Dröge + + * 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 + + * gtk-doc-plugins.mak: + Just use the normal 'check' target and avoid a circular + dependency. + +2007-09-06 Tim-Philipp Müller + + * gtk-doc-plugins.mak: + Add rule to error out if .hierarchy file contains tabs. + +2007-08-20 Tim-Philipp Müller + + * download-translations: + * po.mak: + If there are new languages, they need to be added to po/LINGUAS. + +2007-08-20 Tim-Philipp Müller + + * 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 + + * gst.supp: + Add a suppression for GLib caching the tmp dir seen on an + Ubuntu Feisty system. + +2007-07-13 Jan Schmidt + + * 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 + + * 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 + + * gst-xmlinspect.py: + * plugins.xsl: + Also extract element caps for plugin-docs. Fixes parts of #117692. + +2007-06-21 Tim-Philipp Müller + + Patch by: Andreas Schwab + + * m4/gst-feature.m4: + Fix quoting (#449493). + +2007-06-10 Sebastian Dröge + + * 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 + + * gst.supp: + Suppression variant for our good friend the TLS leak, this time for + Ubuntu Feisty/x86. + +2007-05-09 Tim-Philipp Müller + + * gtk-doc-plugins.mak: + Fix make distcheck again; change some spaces to tabs in makefile. + +2007-04-29 Thomas Vander Stichele + + * gtk-doc-plugins.mak (-module): + Error out when the html build step gives warnings, so they get + fixed properly. + +2007-04-23 Stefan Kost + + * 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 + + Patch by: Vincent Torri + + * 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 + + * 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 + + * 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 + + * m4/gst-parser.m4: + Fix the flex version check. It ignored the micro version before. + +2007-03-09 Jan Schmidt + + * 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 + + * 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 + + * gst.supp: + add a suppression for this GConf flup on the FC5 buildbot. + +2007-03-06 Jan Schmidt + + * gst.supp: + Make the suppression a little more generic, to catch the FC5 + backtrace too. + +2007-03-06 Jan Schmidt + + * 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 + + * m4/gst-arch.m4: + Move a line that was in the wrong macro + +2007-02-28 Thomas Vander Stichele + + * 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 + + * 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 + + Patch by: Will Newton + + * 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 + + * 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 + + * 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 + + * 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 + + * gst.supp: + More suppressions for edgy. + +2006-09-28 Jan Schmidt + + * 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 + + * gst.supp: + Some suppressions for the more recent ld.so in ubuntu edgy. + +2006-08-23 Tim-Philipp Müller + + * gst.supp: + Shorten function trail so the suppression works on + my ubuntu dapper system with core cvs as well. + +2006-07-28 Jan Schmidt + + * gst.supp: + Extra suppressions from my Ubuntu x86_64 machine + +2006-07-24 Tim-Philipp Müller + + Patch by: Frederic Peters + + * 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 + + * 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 + + Patch by: Frederic Peters + + * m4/gst-parser.m4: + Fix bison detection (#348354) + +2006-07-21 Stefan Kost + + * m4/gst-parser.m4: + check for bison and flex + +2006-07-13 Thomas Vander Stichele + + * 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 + + * 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 + + * 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 + + * m4/gst-args.m4: + when building with gcov, reset CFLAGS and friends to O0 + +2006-07-02 Thomas Vander Stichele + + * 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 + + * 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 + + * 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 + + Patch by: Peter Kjellerstedt + + * 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 + + * 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 + + * 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 + + * m4/gst-arch.m4: + add PPC64 so we can have separate structure sizes for it + +2006-06-05 Edward Hervey + + * gtk-doc.mak: + Check for the proper .devhelp2 file to remove. + +2006-05-31 Thomas Vander Stichele + + * gtk-doc.mak: + allow a magic variable to suppress errors from docbuilding + +2006-05-30 Thomas Vander Stichele + + * gtk-doc.mak: + error out if gtkdoc-mktmpl finds unused declarations + +2006-05-28 Edward Hervey + + * gst.supp: + Reverting previous commit. That's good to know, Edward, but why ? + +2006-05-28 Edward Hervey + + * gst.supp: + Added suppresion for memleak in g_option_context_parse on fc5-64 + +2006-05-19 Thomas Vander Stichele + + * m4/gst-check.m4: + set GSTPB_PLUGINS_DIR just like GST_PLUGINS_DIR + +2006-05-18 Tim-Philipp Müller + + * 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 + + Patch by: Peter Kjellerstedt + + * m4/gst-arch.m4: + add support for CRIS and CRISv32. + +2006-05-17 Jan Schmidt + + * 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 + + * gtk-doc.mak: + Add uninstall rule to remove .devhelp2 files. + +2006-05-09 Edward Hervey + + * gst.supp: + Add suppression for GSlice version of + g_type_init calloc leak + +2006-04-05 Michael Smith + + * gst.supp: + Delete a bogus suppression for the registry code. + Generalise a suppression for a glib bug (see #337404) + +2006-04-04 Michael Smith + + * gst.supp: + Add a leak suppression: the existing glibc-doesn't-free-TLS one + wasn't triggering here. + +2006-04-04 Michael Smith + + * gst.supp: + Add some minimally-neccesary suppressions for my x86/dapper system. + +2006-04-01 Thomas Vander Stichele + + * plugins.xsl: + Do not display an origin link if origin does not start with http + See #323798 + +2006-04-01 Thomas Vander Stichele + + * m4/gst-args.m4: + * m4/gst-feature.m4: + add more macros + * m4/gst-x11.m4: + X11-related checks + +2006-04-01 Thomas Vander Stichele + + * 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 + + * gst.supp: + add a suppression for g_parse_debug_string + +2006-03-23 Stefan Kost + + * gstdoc-scangobj: + sync fully with gtkdoc-0.15 + +2006-03-23 Stefan Kost + + * gstdoc-scangobj: + * gtk-doc.mak: + sync a little with gtk-doc mainline + +2006-03-17 Wim Taymans + + * gst.supp: + add another clone suppression + change all glibc suppressions to match 2.3.* + +2006-03-09 Thomas Vander Stichele + + * 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 + + * check.mak: + Set G_SLICE=always-malloc when valgrinding tests + (closes #333272) + +2006-02-21 Jan Schmidt + + * m4/gst-glib2.m4: + Fix debug output when the GLib version prerequisite is not found + +2006-02-13 Andy Wingo + + * 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 + + * m4/gst-default.m4: + switch to auto* sinks for defaults + +2006-02-02 Wim Taymans + + * 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 + + * gtk-doc-plugins.mak: + only add srcdir/gst if it exists + +2006-01-30 Thomas Vander Stichele + + * release.mak: + don't complain about disted enums in win32 + +2006-01-20 Thomas Vander Stichele + + * 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 + + * 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 + + * m4/pkg.m4: + update with a more recent version + +2006-01-07 Thomas Vander Stichele + + * gettext.patch: + make Makefile depend on LINGUAS, so rebuilds work when adding + a language + +2006-01-03 Michael Smith + + * check.mak: + Clarify error message from valgrind test runs. + +2005-12-16 Thomas Vander Stichele + + * m4/gst-arch.m4: + define HOST_CPU + +2005-11-29 Thomas Vander Stichele + + * check.mak: + add a valgrind-forever target for tests + +2005-11-28 Thomas Vander Stichele + + * 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 + + * 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 + + * m4/gst-check.m4: + check for tools correctly + +2005-10-18 Thomas Vander Stichele + + * gtk-doc.mak: + only enable breaking on new API when make distcheck passes, + not before + +2005-10-18 Thomas Vander Stichele + + * m4/gst-check.m4: + Resurrect Julien's dead body and wipe his mind clean + +2005-10-18 Thomas Vander Stichele + + * m4/gst-check.m4: + Kill Julien + +2005-10-17 Julien MOUTTE + + * 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 + + * gtk-doc.mak: + make build break on new api that has not been added to the + sections file + +2005-10-17 Thomas Vander Stichele + + * 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 + + * m4/gst-glib2.m4: + update, warn in error cases + +2005-10-16 Thomas Vander Stichele + + * m4/gst-error.m4: + add GST_SET_DEFAULT_LEVEL + +2005-10-16 Thomas Vander Stichele + + * 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 + + * m4/Makefile.am: + * m4/gst-gettext.m4: + add macro for setting up gettext + +2005-10-15 Thomas Vander Stichele + + * m4/gst-args.m4: + add some .m4's for argument checking that can be shared among modules + +2005-10-15 Thomas Vander Stichele + + * m4/as-libtool.m4: + set _LT_LDFLAGS + * m4/gst-libxml2.m4: + document + +2005-10-15 Thomas Vander Stichele + + * m4/gst-arch.m4: + indent a little + add AC_REQUIRE + * m4/gst-error.m4: + clean up + +2005-10-12 Thomas Vander Stichele + + * gst-autogen.sh: + update version detection expression to catch stuff like + Libtool (libtool15) 1.5.0 + +2005-10-11 Thomas Vander Stichele + + * gst.supp: + commit 6 new suppressions related to g_module_open; can these + really not be folded into one ? + +2005-10-11 Edward Hervey + + * gst.supp: + made the suppression more generic + Added pthread memleak suppresions + Added nss_parse_* memleak suppresion (used by g_option_context_parse) + +2005-10-11 Thomas Vander Stichele + + * check.mak: + be more strict, more leak resolution + * gst.supp: + clean up the g_type_init suppressions + +2005-10-07 Thomas Vander Stichele + + * m4/Makefile.am: + * m4/gst-valgrind.m4: + put the valgrind detection in an .m4 + +2005-09-29 Thomas Vander Stichele + + * check.mak: + add some more targets, like "help", but also more intensive tests + +2005-09-23 Thomas Vander Stichele + + * gtk-doc.mak: + make certain doc warnings fatal so people maintain docs again + +2005-09-23 Thomas Vander Stichele + + * 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 + + * 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 + + * gst-xmlinspect.py: + * gstdoc-scangobj: + some fixes for new API + * gtk-doc-plugins.mak: + set environment properly + +2005-09-17 David Schleef + + * gtk-doc-plugins.mak: Use new environment variables. + +2005-09-16 Michael Smith + + * gstdoc-scangobj: + Make the scanobj code reflect registry/plugin API changes + +2005-09-15 Thomas Vander Stichele + + * 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 + + * 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 + + * 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 + + * gtk-doc-plugins.mak: + error out on inspect failure + +2005-09-14 Michael Smith + + * glib-gen.mak: + Don't call glib-mkenums with arguments that confuse/break MinGW, + fixes 316155. + +2005-09-03 Thomas Vander Stichele + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * m4/gst-doc.m4: + s/pdf/eps/ in test for whether we output EPS images (#309379). + +2005-07-18 Andy Wingo + + * 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 + + * m4/gst-error.m4: + add macro to set ERROR_CFLAGS + +2005-06-30 Jan Schmidt + + * 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 + + * m4/gtk-doc.m4: + added + +2005-06-03 Stefan Kost + + * gst-autogen.sh: create autoregen.sh *before* shifting the options + +2005-05-17 Thomas Vander Stichele + + * gst-autogen.sh: only update autoregen.sh on actual runs + +2005-03-11 Thomas Vander Stichele + + * m4/check.m4: m4 from the check unit test suite + +2004-12-14 David Schleef + + * m4/gst-arch.m4: remove MMX stuff, since it doesn't work and + isn't needed anywhere + +2004-12-08 Thomas Vander Stichele + + * gst-autogen.sh: + allow failure command to be run so we can clean upfrom autopoint + +2004-09-03 Zeeshan Ali Khattak + * m4/gst-feature.m4: Trying to correct the GST_CHECK_CONFIGPROG macro + +2004-07-21 Benjamin Otte + + * m4/.cvsignore: exciting updates for libtool m4 files + +2004-07-12 David Schleef + + * m4/as-objc.m4: Add a macro to test for objective C + +2004-06-12 Thomas Vander Stichele + + * m4/gst-feature.m4: + not all of them support --plugin-libs, so redirect stderr + +2004-06-12 Thomas Vander Stichele + + * m4/as-scrub-include.m4: + sync with upstream to 0.1.4. Fixes #132440 + +2004-06-07 Benjamin Otte + + * 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 + + * 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 + + * m4/as-scrub-include.m4: synced with upstream + +2004-05-03 Thomas Vander Stichele + + * po.mak: + snippet for updating .po files + +2004-03-18 Thomas Vander Stichele + + * Makefile.am: + * m4/Makefile.am: + integrate these with the dist + +2004-03-17 Thomas Vander Stichele + + * release.mak: add a release target + +2004-03-09 Thomas Vander Stichele + + patch by: Stephane Loeuillet + + * m4/ax_create_stdint_h.m4: + use head -n instead of head - (#136500) + +2004-03-05 Thomas Vander Stichele + + * m4/gst-doc.m4: don't build PS without dvips binary + +2004-02-22 Julio M. Merino Vidal + + reviewed by: Benjamin Otte + + * m4/as-docbook.m4: + don't use == operator with test(1) (fixes #135115) + +2004-02-16 Thomas Vander Stichele + + * common/m4/gst-arch.m4: x86_64 is x86 too (clue from Fedora 2 test) + +2004-02-13 Thomas Vander Stichele + + * 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 + + * m4/gst-libxml2.m4: + take required version as argument, and default to 2.4.9 if not + specified + +2004-02-12 Thomas Vander Stichele + + * m4/gst-feature.m4: + rename and fix up GST_CHECK_DISABLE_SUBSYSTEM + +2004-02-11 Thomas Vander Stichele + + * 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 + + * gst-autogen.sh: Use A-Z instead of A-z in sed expression to + avoid a warning + +2004-02-05 Thomas Vander Stichele + + * 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 + + * 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 + + * glib-gen.mak: added; used to generate enums and marshal code + +2004-01-13 Thomas Vander Stichele + + * 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 100644 index 0000000..ca8c029 --- /dev/null +++ b/common/Makefile.am @@ -0,0 +1,15 @@ +SUBDIRS = m4 + +EXTRA_DIST = \ + ChangeLog \ + gettext.patch \ + glib-gen.mak gtk-doc.mak upload.mak release.mak \ + gst-autogen.sh \ + 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 100644 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 '' + print '' + print + print '' + + # print content + print saxutils.escape(content).encode('UTF-8') + print '' + +main() diff --git a/common/check.mak b/common/check.mak new file mode 100644 index 0000000..9ac509d --- /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 100644 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 < + +Coverage report for $ARGV[0] + + + +

Coverage report for $ARGV[0]

+ +
+EOF
+
+
+while (<>) {
+    s/&/&/g;
+    s//>/g;
+
+    if (/^\s*function (\S+) called (\d+) returned \d+% blocks executed \d+%/) {
+	my $class = $2 > 0 ? "perfect" : "terrible";
+	$_ = "$_";
+    } elsif (/^\s*branch\s+\d+\s+taken\s+(\d+)%\s+.*$/) {
+	my $class = $1 > 0 ? "perfect" : "terrible";
+	$_ = "$_";
+    } elsif (/^\s*branch\s+\d+\s+never executed.*$/) {
+	my $class = "terrible";
+	$_ = "$_";
+    } elsif (/^\s*call\s+\d+\s+never executed.*$/) {
+	my $class = "terrible";
+	$_ = "$_";
+    } elsif (/^\s*call\s+\d+\s+returned\s+(\d+)%.*$/) {
+	my $class = $1 > 0 ? "perfect" : "terrible";
+	$_ = "$_";
+    }
+    
+
+    print;
+}
+
+print <
+
+
+EOF
diff --git a/common/coverage/coverage-report.pl b/common/coverage/coverage-report.pl
new file mode 100644
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 "\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 "  \n", $name, ($type eq "file" ? $filemap{$name} : $filemap{$rec->{file}});
+	printf "    \n", $rec->{lines}, $rec->{linesCoverage};
+	if (exists $rec->{branches}) {
+	    printf "    \n", $rec->{branches}, $rec->{branchesCoverage};
+	}
+	if (exists $rec->{conds}) {
+	    printf "    \n", $rec->{conds}, $rec->{condsCoverage};
+	}
+	if (exists $rec->{calls}) {
+	    printf "    \n", $rec->{calls}, $rec->{callsCoverage};
+	}
+	print  "  \n";
+    }
+    
+    printf "  \n";
+    printf "    \n", $summary{$type}->{lines}, $summary{$type}->{linesCoverage};
+    printf "    \n", $summary{$type}->{branches}, $summary{$type}->{branchesCoverage};
+    printf "    \n", $summary{$type}->{conds}, $summary{$type}->{condsCoverage};
+    printf "    \n", $summary{$type}->{calls}, $summary{$type}->{callsCoverage};
+    printf  "  \n";
+    printf "\n", $type;
+}
+
+print "\n";
diff --git a/common/coverage/coverage-report.xsl b/common/coverage/coverage-report.xsl
new file mode 100644
index 0000000..b19ebb6
--- /dev/null
+++ b/common/coverage/coverage-report.xsl
@@ -0,0 +1,235 @@
+
+
+
+
+  
+
+  
+    
+      
+        Coverage report
+        
+      
+      
+        

Coverage report

+ + + +
+ + +

Function coverage

+ + + +
+ + + +

File coverage

+ + + +
+ + + + + + + + + + + + + + + + + + + + + odd + + + even + + + + + + + + + + + + + + odd + + + even + + + + + + +
NameLinesBranchesConditionsCalls
+
+ + + + + + + + + + + + + + Summary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + perfect + + + excellant + + + good + + + poor + + + bad + + + terrible + + + + + % of + + +
diff --git a/common/coverage/lcov.mak b/common/coverage/lcov.mak new file mode 100644 index 0000000..6d848f5 --- /dev/null +++ b/common/coverage/lcov.mak @@ -0,0 +1,29 @@ +# 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 + +# reset run coverage tests +lcov-run: + @-rm -rf lcov + find . -name "*.gcda" -exec rm {} \; + 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 --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 lcov/lcov.info + +lcov-upload: lcov + rsync -rvz -e ssh --delete lcov/* gstreamer.freedesktop.org:/srv/gstreamer.freedesktop.org/www/data/coverage/lcov/$(PACKAGE) diff --git a/common/gettext.patch b/common/gettext.patch new file mode 100644 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 100644 index 0000000..eff4147 --- /dev/null +++ b/common/glib-gen.mak @@ -0,0 +1,42 @@ +# 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 + +# 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 \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 <$*.h>" \ + --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 100644 index 0000000..7b31212 --- /dev/null +++ b/common/gst-autogen.sh @@ -0,0 +1,308 @@ +# 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 + ;; + --prefix=*) + CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT --prefix=$optarg" + echo "+ passing --prefix=$optarg to configure" + shift + ;; + --prefix) + shift + echo "DEBUG: $1" + CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT --prefix=$1" + echo "+ passing --prefix=$1 to configure" + 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 " --prefix will be passed on to configure" + echo + echo " --with-autoconf PATH use autoconf in PATH" + echo " --with-automake PATH use automake in PATH" + echo + echo "to pass options to configure, put them as arguments after -- " + 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 + ;; + --disable*|--enable*|--with*) + echo "+ passing option $1 to configure" + CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT $1" + shift + ;; + --) shift ; break ;; + *) echo "- ignoring unknown autogen.sh argument $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 100644 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 = """ + %(name)s + %(direction)s + %(presence)s +
%(details)s
+
""" + +ELEMENT_TEMPLATE = """ + %(name)s + %(longname)s + %(class)s + %(description)s + %(author)s + +%(pads)s + +""" + +PLUGIN_TEMPLATE = """ + %(name)s + %(description)s + %(filename)s + %(basename)s + %(version)s + %(license)s + %(source)s + %(package)s + %(origin)s + +%(elements)s + +""" + +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 100644 index 0000000..ce0daa2 --- /dev/null +++ b/common/gst.supp @@ -0,0 +1,1660 @@ +### this file contains suppressions for valgrind when running +### the gstreamer unit tests +### it might be useful for wider use as well + +### syscall suppressions + +{ + + Memcheck:Param + clone(parent_tidptr) + fun:clone + fun:clone +} + +{ + + Memcheck:Param + clone(child_tidptr) + fun:clone + fun:clone +} + +{ + + Memcheck:Param + clone(tlsinfo) + fun:clone + fun:clone +} + +### glibc suppressions + +{ + + 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 + +{ + + Memcheck:Leak + fun:calloc + fun:_dl_allocate_tls + fun:pthread_create@@* +} + +# I get an extra stack entry on x86/dapper +{ + + Memcheck:Leak + fun:calloc + obj:/lib/ld-2.3.*.so + fun:_dl_allocate_tls + fun:pthread_create@@* +} + + +{ + + 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 +} + +{ + + 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 +{ + + 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 +} + +{ + + 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 +} + +{ + + 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 +} + +{ + + 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 +} +{ + + 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 +} + +{ + + 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 +} + +{ + + 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 +} + +{ + + 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 +} + +{ + + 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 +} + +{ + + 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 +} + +{ + + 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 +} + +{ + + 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 +} + +# 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 +{ + + 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 +} + +{ + + 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 +} +{ + + 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 +} + +{ + + 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 +} + +{ + + 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 +} +{ + + 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 +} + +{ + + 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 +} + +{ + + 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 +} + +{ + + 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 +} + +{ + + 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 +} + +{ + + 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 +{ + + Memcheck:Cond + fun:g_parse_debug_string + obj:/usr/lib*/libglib-2.0.so.* + fun:g_slice_alloc + fun:g_slice_alloc0 +} + +{ + + 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 +} + +{ + + Memcheck:Leak + fun:calloc + fun:g_malloc0 + obj:* + obj:* + fun:g_type_register_fundamental +} + +{ + + Memcheck:Leak + fun:calloc + fun:g_malloc0 + obj:* + obj:* + fun:g_type_init_with_debug_flags +} + +{ + + 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 +{ + + 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 +} + +{ + + Memcheck:Addr8 + obj:/lib/ld-2.3.6.so +} + +{ + + 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 +} + +{ + + 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 +{ + + Memcheck:Addr4 + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so +} +{ + + Memcheck:Addr8 + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so +} + +# More edgy suppressions (Mike) +{ + + 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 +} + +{ + + 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 +} + +{ + + 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! +{ + + 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 +} + +{ + + 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 +{ + + Memcheck:Leak + fun:calloc + fun:allocate_dtv + fun:_dl_allocate_tls + fun:pthread_create@@GLIBC_2.1 +} + +{ + + 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 +} + +{ + + Memcheck:Addr8 + obj:/lib/ld-2.5.so +} + +{ + + 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 +} + +{ + + Memcheck:Cond + fun:snd_pcm_hw_param_set_near + fun:set_hwparams +} + +{ + + 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 +} + +{ + + 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 +} + +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +{ + + Memcheck:Leak + fun:malloc + fun:snd_dlobj_cache_add + obj:/*lib/libasound.so.2.0.0 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} + +{ + + Memcheck:Leak + fun:calloc + fun:_XCBInitDisplayLock + fun:XOpenDisplay +} + +# GConf internal initialisations related to getting the default client. +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +{ + + 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 +} +{ + + 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* +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + 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 +} +{ + + Memcheck:Leak + fun:malloc + obj:/lib/libc-*.so + fun:__nss_database_lookup + obj:* + obj:* + fun:getpwnam_r + fun:g_get_any_init_do + fun:g_get_home_dir +} +{ + + Memcheck:Leak + fun:malloc + obj:/lib/libc-*.so + fun:__nss_database_lookup + obj:* + obj:* + fun:getpwnam_r + fun:g_get_any_init_do + fun:g_get_user_name +} +{ + + Memcheck:Leak + fun:malloc + obj:/lib/libc-*.so + fun:__nss_database_lookup + obj:* + obj:* + fun:getpwnam_r + obj:/usr/lib*/libglib-2.0.so.* + fun:g_get_tmp_dir +} + + +## Some Fontconfig errors. +{ + + 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 +} +{ + + 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..0ff1b54 --- /dev/null +++ b/common/gstdoc-scangobj @@ -0,0 +1,1562 @@ +#!/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 () { + if (/^#include/) { + $includes .= $_; +# } elsif (/^%/) { +# next; +# } elsif (/^\s*$/) { +# next; +# } else { +# chomp; +# push @types, $_; + } +} + +#$ntypes = @types + 1; + +print OUTPUT < +#include +#include +#include + +$includes +#ifdef GTK_IS_WIDGET_CLASS +#include +#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 ("source: %s\\n", source); + if (!source || strcmp (gst_plugin_get_source (plugin), "$SOURCE") != 0) { + continue; + } + + 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_append (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); + g_message ("adding type for factory %s", gst_element_factory_get_longname (factory)); + type = gst_element_factory_get_element_type (factory); + g_message ("adding type %p", (void *) type); + object_types[i] = type; + i++; + l = g_list_next (l); + } + object_types[i] = 0; +EOT + +print OUTPUT <\\n%s::%s\\n%s\\n%s\\n%s\\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; + + 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_OBJECT) && + (object_types[i] != G_TYPE_INTERFACE) + ) { + output_hierarchy (fp, object_types[i], 0); + } + } + + 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 (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) +{ + 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); + 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; + gchar *type_desc; + gchar *default_value; + + if (G_TYPE_IS_CLASSED (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); + fprintf (fp, "\\n%s::%s\\n%s\\n%s\\n%s\\n%s\\n%s%s\\n%s\\n\\n\\n", + object_class_name, g_param_spec_get_name (spec), g_type_name (spec->value_type), 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 100644 index 0000000..4bb57a4 --- /dev/null +++ b/common/gtk-doc-plugins.mak @@ -0,0 +1,358 @@ +# This is an include file specifically tuned for building documentation +# for GStreamer plug-ins + +help: + @echo "If you are a doc maintainer, run 'make update' to update" + @echo "the documentation files maintained in CVS" + +# 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_MODULE).types \ + $(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).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 + +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 +# IFF 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 + 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 + +# 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 \ + $(DOC_MODULE)-unused.txt \ + $(DOC_STAMPS) \ + inspect-registry.xml + +# 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; \ + 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; \ + 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 + + +# +# 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 100644 index 0000000..ea203d8 --- /dev/null +++ b/common/gtk-doc.mak @@ -0,0 +1,260 @@ +########################################################################### +# 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 + +CLEANFILES = $(SCANOBJ_FILES) $(DOC_MODULE)-unused.txt $(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 fixed for 0.9 +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) + 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 $(DOC_MODULE)-undocumented.txt + rm -f $(DOC_MODULE)-unused.txt + 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 100644 index 0000000..3bbf0e9 --- /dev/null +++ b/common/m4/Makefile.am @@ -0,0 +1,28 @@ +EXTRA_DIST = \ + README \ + as-ac-expand.m4 \ + as-auto-alt.m4 \ + as-compiler-flag.m4 \ + as-compiler.m4 \ + as-docbook.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 100644 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 100644 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 100644 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 100644 index 0000000..aba31b1 --- /dev/null +++ b/common/m4/as-compiler-flag.m4 @@ -0,0 +1,33 @@ +dnl as-compiler-flag.m4 0.1.0 + +dnl autostars m4 macro for detection of compiler flags + +dnl David Schleef + +dnl $Id: as-compiler-flag.m4,v 1.1 2004/06/01 09:33:45 thomasvs Exp $ + +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]) +]) + diff --git a/common/m4/as-compiler.m4 b/common/m4/as-compiler.m4 new file mode 100644 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 + +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 100644 index 0000000..6a2aa45 --- /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/; + do + if test -d "$i"; then + DOCBOOK_ROOT=$i + fi + done + else + XML_CATALOG=/etc/xml/catalog + CAT_ENTRY_START='' + 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/docbook.xsl" + fi + $XSLTPROC $XSLTPROC_FLAGS $DB_FILE >/dev/null 2>&1 << END + + + + +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-libtool-tags.m4 b/common/m4/as-libtool-tags.m4 new file mode 100644 index 0000000..69f775e --- /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 100644 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 + +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 100644 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 +# +# 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 100644 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 + +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 100644 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 + +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 100644 index 0000000..061619f --- /dev/null +++ b/common/m4/ax_create_stdint_h.m4 @@ -0,0 +1,569 @@ +dnl @synopsis AX_CREATE_STDINT_H [( HEADER-TO-GENERATE [, HEDERS-TO-CHECK])] +dnl +dnl the "ISO C9X: 7.18 Integer types " section requires the +dnl existence of an include file that defines a set of +dnl typedefs, especially uint8_t,int32_t,uintptr_t. +dnl Many older installations will not provide this file, but some will +dnl have the very same definitions in . In other enviroments +dnl we can use the inet-types in which would define the +dnl typedefs int8_t and u_int8_t respectivly. +dnl +dnl This macros will create a local "_stdint.h" or the headerfile given as +dnl an argument. In many cases that file will just "#include " +dnl or "#include ", while in other environments it will provide +dnl the set of basic 'stdint's definitions/typedefs: +dnl int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,intptr_t,uintptr_t +dnl int_least32_t.. int_fast32_t.. intmax_t +dnl which may or may not rely on the definitions of other files, +dnl or using the AC_CHECK_SIZEOF macro to determine the actual +dnl sizeof each type. +dnl +dnl if your header files require the stdint-types you will want to create an +dnl installable file mylib-int.h that all your other installable header +dnl may include. So if you have a library package named "mylib", just use +dnl AX_CREATE_STDINT_H(mylib-int.h) +dnl in configure.ac and go to install that very header file in Makefile.am +dnl along with the other headers (mylib.h) - and the mylib-specific headers +dnl can simply use "#include " to obtain the stdint-types. +dnl +dnl Remember, if the system already had a valid , the generated +dnl file will include it directly. No need for fuzzy HAVE_STDINT_H things... +dnl +dnl @, (status: used on new platforms) (see http://ac-archive.sf.net/gstdint/) +dnl @version $Id: ax_create_stdint_h.m4,v 1.2 2004/03/09 14:57:53 thomasvs Exp $ +dnl @author Guido Draheim + +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 ],[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=""]) +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 CHECK_TYPE macros do automatically "DEFINE" a type, therefore +dnl we use the autoconf implementation detail _AC CHECK_TYPE_NEW instead + +inttype_headers=`echo $2 | sed -e 's/,/ /g'` + +ac_cv_stdint_result="(no helpful system typedefs seen)" +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 stdint.h inttypes.h sys/inttypes.h $inttype_headers ; do + unset ac_cv_type_uintptr_t + unset ac_cv_type_uint64_t + _AC_CHECK_TYPE_NEW(uintptr_t,[ac_cv_header_stdint_x=$i],dnl + continue,[#include <$i>]) + AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>]) + ac_cv_stdint_result="(seen uintptr_t$and64 in $i)" + break; + done + AC_MSG_CHECKING([for stdint uintptr_t]) + ]) + +if test "_$ac_cv_header_stdint_x" = "_" ; then +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 inttypes.h sys/inttypes.h stdint.h $inttype_headers ; do + unset ac_cv_type_uint32_t + unset ac_cv_type_uint64_t + AC_CHECK_TYPE(uint32_t,[ac_cv_header_stdint_o=$i],dnl + continue,[#include <$i>]) + AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>]) + ac_cv_stdint_result="(seen uint32_t$and64 in $i)" + break; + done + AC_MSG_CHECKING([for stdint uint32_t]) + ]) +fi + +if test "_$ac_cv_header_stdint_x" = "_" ; then +if test "_$ac_cv_header_stdint_o" = "_" ; then +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 sys/types.h inttypes.h sys/inttypes.h $inttype_headers ; 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],dnl + continue,[#include <$i>]) + AC_CHECK_TYPE(u_int64_t,[and64="/u_int64_t"],[and64=""],[#include<$i>]) + ac_cv_stdint_result="(seen u_int32_t$and64 in $i)" + break; + done + AC_MSG_CHECKING([for stdint u_int32_t]) + ]) +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([(..)]) + AC_CHECK_SIZEOF(char) + AC_CHECK_SIZEOF(short) + AC_CHECK_SIZEOF(int) + AC_CHECK_SIZEOF(long) + AC_CHECK_SIZEOF(void*) + ac_cv_stdint_char_model="" + ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_char" + ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_short" + ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_int" + ac_cv_stdint_long_model="" + ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_int" + ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_long" + ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_voidp" + name="$ac_cv_stdint_long_model" + case "$ac_cv_stdint_char_model/$ac_cv_stdint_long_model" in + 122/242) name="$name, IP16 (standard 16bit machine)" ;; + 122/244) name="$name, LP32 (standard 32bit mac/win)" ;; + 122/*) name="$name (unusual int16 model)" ;; + 124/444) name="$name, ILP32 (standard 32bit unixish)" ;; + 124/488) name="$name, LP64 (standard 64bit unixish)" ;; + 124/448) name="$name, LLP64 (unusual 64bit unixish)" ;; + 124/*) name="$name (unusual int32 model)" ;; + 128/888) name="$name, ILP64 (unusual 64bit numeric)" ;; + 128/*) name="$name (unusual int64 model)" ;; + 222/*|444/*) name="$name (unusual dsptype)" ;; + *) name="$name (very unusal model)" ;; + esac + AC_MSG_RESULT([combined for stdint datatype model... $name]) +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 -n 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]) + +# ----------------- 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 +fi + +cat >>$ac_stdint < +#else +#include + +/* .................... 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_stdint_char_model" != "_" ; then +echo "#define _STDINT_CHAR_MODEL" "$ac_cv_stdint_char_model" >>$ac_stdint +echo "#define _STDINT_LONG_MODEL" "$ac_cv_stdint_long_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 <= 199901L +#define _HAVE_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 +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 +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 unsinged 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 + + /* shortcircuit*/ +#endif + /* once */ +#endif +#endif +STDINT_EOF + 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_stdint_char_model="$ac_cv_stdint_char_model" +ac_cv_stdint_long_model="$ac_cv_stdint_long_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 100644 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 +#include + +#include + +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 +#include + +#include +], , [ 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/glib-gettext.m4 b/common/m4/glib-gettext.m4 new file mode 100644 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 , 1995, 1996 +# +# Modified to never use included libintl. +# Owen Taylor , 12/15/1998 +# +# Major rework to remove unused code +# Owen Taylor , 12/11/2002 +# +# Added better handling of ALL_LINGUAS from GNU gettext version +# written by Bruno Haible, Owen Taylor 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 ], [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 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 +], + [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 100644 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 100644 index 0000000..a326f96 --- /dev/null +++ b/common/m4/gst-args.m4 @@ -0,0 +1,276 @@ +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_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 GST_PLUGINS_SELECTED to the list given as an argument, or to +dnl GST_PLUGINS_ALL +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]), + [ + for i in `echo $withval | tr , ' '`; do + if echo $GST_PLUGINS_ALL | grep $i > /dev/null + then + GST_PLUGINS_SELECTED="$GST_PLUGINS_SELECTED $i" + else + echo "plug-in $i not recognized, ignoring..." + fi + done], + [GST_PLUGINS_SELECTED=$GST_PLUGINS_ALL]) +]) + +AC_DEFUN([AG_GST_ARG_ENABLE_EXTERNAL], +[ + AG_GST_CHECK_FEATURE(EXTERNAL, [enable 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, [enable 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 100644 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 100644 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 100644 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 100644 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 < \$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 &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 &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 &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 100644 index 0000000..4c3f12c --- /dev/null +++ b/common/m4/gst-error.m4 @@ -0,0 +1,71 @@ +dnl handle various error-related things + +dnl Thomas Vander Stichele + +dnl Last modification: 2005-10-16 + +dnl AG_GST_SET_ERROR_CFLAGS([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 + if test "x$ERROR_CFLAGS" == "x" + then + dnl try -errwarn=%all,no%E_EMPTY_DECLARATION,no%E_STATEMENT_NOT_REACHED (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 + AS_COMPILER_FLAG([-errwarn=%all,no%E_EMPTY_DECLARATION,no%E_STATEMENT_NOT_REACHED], + [ERROR_CFLAGS="-errwarn=%all,no%E_EMPTY_DECLARATION,no%E_STATEMENT_NOT_REACHED"]) + + dnl if this also isn't suported, try only for -errwarn=%all + if test "x$ERROR_CFLAGS" == "x" + then + AS_COMPILER_FLAG(-errwarn=%all, + ERROR_CFLAGS="-errwarn=%all") + fi + fi + fi + + AC_SUBST(ERROR_CFLAGS) + AC_MSG_NOTICE([set ERROR_CFLAGS to $ERROR_CFLAGS]) +]) + +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 100644 index 0000000..510d228 --- /dev/null +++ b/common/m4/gst-feature.m4 @@ -0,0 +1,285 @@ +dnl Perform a check for a feature for GStreamer +dnl Richard Boulton +dnl Thomas Vander Stichele added useful stuff +dnl Last modification: 25/06/2001 +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_ to "yes" or "no" depending +dnl on whether the feature is available. +dnl +dnl The macro will set USE_ to "yes" or "no" depending on +dnl whether the feature is to be used. +dnl Thomas changed this, so that when USE_ was already set +dnl to no, then it stays that way. +dnl +dnl The macro will call AM_CONDITIONAL(USE_<, ...) 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_ 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], , [support for features: $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 +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 +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], [ + +echo "configure: *** Plug-ins without external dependencies that will be built:" +( for i in $GST_PLUGINS_SELECTED; do /bin/echo -e '\t'$i; done ) | sort +echo + +echo "configure: *** Plug-ins without external dependencies that will NOT be built:" +( for i in $GST_PLUGINS_ALL; do + case $GST_PLUGINS_SELECTED in + *$i*) + ;; + *) + /bin/echo -e '\t'$i + ;; + esac + done ) | sort +echo + +if test "x$BUILD_EXTERNAL" = "xno"; then + echo "configure: *** No plug-ins with external dependencies will be built" +else + /bin/echo -n "configure: *** Plug-ins with dependencies that will be built:" + /bin/echo -e "$GST_PLUGINS_YES" | sort + /bin/echo + /bin/echo -n "configure: *** Plug-ins with dependencies that will NOT be built:" + /bin/echo -e "$GST_PLUGINS_NO" | sort + /bin/echo +fi +]) + diff --git a/common/m4/gst-function.m4 b/common/m4/gst-function.m4 new file mode 100644 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 ], + [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 ], + [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 ], + [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 100644 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 100644 index 0000000..71e293b --- /dev/null +++ b/common/m4/gst-glib2.m4 @@ -0,0 +1,26 @@ +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 + PKG_CHECK_MODULES(GLIB, + glib-2.0 >= $GLIB_REQ gobject-2.0 gthread-2.0 gmodule-no-export-2.0, + HAVE_GLIB=yes,HAVE_GLIB=no) + + 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 100644 index 0000000..001d67b --- /dev/null +++ b/common/m4/gst-libxml2.m4 @@ -0,0 +1,43 @@ +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, 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 +#include +],[ +/* 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-plugindir.m4 b/common/m4/gst-plugindir.m4 new file mode 100644 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 100644 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/gtk-doc.m4 b/common/m4/gtk-doc.m4 new file mode 100644 index 0000000..af73800 --- /dev/null +++ b/common/m4/gtk-doc.m4 @@ -0,0 +1,53 @@ +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 + + 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/pkg.m4 b/common/m4/pkg.m4 new file mode 100644 index 0000000..6c35916 --- /dev/null +++ b/common/m4/pkg.m4 @@ -0,0 +1,131 @@ +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# +# Copyright © 2004 Scott James Remnant . +# +# 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 + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], + [pkg_failed=yes]) +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 .])], + [$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/mangle-tmpl.py b/common/mangle-tmpl.py new file mode 100644 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("\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("\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 + 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 + 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 = '\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 100644 index 0000000..150087f --- /dev/null +++ b/common/plugins.xsl @@ -0,0 +1,200 @@ + + + + + + + + + + + + -plugins- + + + + + + + + + + + + + Element Information + + + + + plugin + + + + plugin- + + + + + + + + author + + + + + + + class + + + + + + + + Element Pads + + + + + name + + + + + + + direction + + + + + + + presence + + + + + + + details + + + + + + + + + + + + + + + + + + -plugins-plugin- + + + + + + 3 + FIXME Library + + + + + + plugin- + + + + + + + + + + + Plugin Information + + + + filename + + + + + + + version + + + + + + + run-time license + + + + + + + package + + + + + + + origin + + + + + + + + + + + + + + + + + + + + + + + Elements + + + + + + + + + + + + + + diff --git a/common/po.mak b/common/po.mak new file mode 100644 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 100644 index 0000000..3731465 --- /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 "" % 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 + '\n(.*?)\n' + ) + nmatcher = re.compile( + '' + '(?P\S*)' # store object + '::' + '(?P\S*)' # store signal + '' + ) + rmatcher = re.compile( + '(?s)' # make . match \n + '(?P\S*)\n' # store returns + '(?P.*)' # 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 = """ +%(object)s::%(name)s +%(returns)s +%(args)s +""" + 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 + '\n(.*?)\n' + ) + nmatcher = re.compile( + '' + '(?P\S*)' # store object + '::' + '(?P\S*)' # store arg + '' + ) + rmatcher = re.compile( + '(?s)' # make . match \n + '(?P\S*)\n' # store type + '(?P.*?)\n' # store range + '(?P\S*)\n' # store flags + '(?P.*?)\n' # store nick + '(?P.*?)\n' # store blurb + '(?P.*?)\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 = """ +%(object)s::%(name)s +%(type)s +%(range)s +%(flags)s +%(nick)s +%(blurb)s +%(default)s + +""" + 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 100644 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/configure.ac b/configure.ac new file mode 100644 index 0000000..63a2231 --- /dev/null +++ b/configure.ac @@ -0,0 +1,222 @@ +AC_PREREQ(2.52) + +dnl initialize autoconf +dnl when going to/from release please set the nano (fourth number) right ! +dnl releases only do Wall, cvs and prerelease does Werror too +AC_INIT(Gst-RTSP, 0.10.0.1, + http://gstreamer.net/, + gst-rtsp) + +dnl initialize automake +AM_INIT_AUTOMAKE + +dnl define PACKAGE_VERSION_* variables +AS_VERSION + +dnl check if this is a release version +AS_NANO(GST_CVS="no", GST_CVS="yes") + +dnl can autoconf find the source ? +AC_CONFIG_SRCDIR([src/rtsp-server.c]) + +dnl define the output header for config +AM_CONFIG_HEADER([config.h]) + +dnl AM_MAINTAINER_MODE only provides the option to configure to enable it +AM_MAINTAINER_MODE + +dnl sets host_* variables +AC_CANONICAL_HOST + +dnl our libraries and install dirs use major.minor as a version +GST_MAJORMINOR=$PACKAGE_VERSION_MAJOR.$PACKAGE_VERSION_MINOR +dnl we override it here if we need to for the release candidate of new series +GST_MAJORMINOR=0.10 +AC_SUBST(GST_MAJORMINOR) + +AM_PROG_LIBTOOL + +dnl *** required versions of GStreamer stuff *** +GST_REQ=0.10.20 +GSTPB_REQ=0.10.20 + +dnl export for .pc files +AC_SUBST([GST_REQ]) +AC_SUBST([GSTPB_REQ]) + +dnl *** autotools stuff **** + +dnl allow for different autotools +AS_AUTOTOOLS_ALTERNATE + +dnl Add parameters for aclocal +AC_SUBST(ACLOCAL_AMFLAGS, "-I m4 -I common/m4") + +dnl *** check for arguments to configure *** + +AG_GST_ARG_DEBUG +AG_GST_ARG_VALGRIND +AG_GST_ARG_GCOV +AG_GST_ARG_WITH_PACKAGE_NAME +AG_GST_ARG_WITH_PACKAGE_ORIGIN + +dnl *** checks for platform *** + +dnl * hardware/architecture * + +dnl *** checks for programs *** + +dnl find a compiler +AC_PROG_CC + +AC_PATH_PROG(VALGRIND_PATH, valgrind, no) +AM_CONDITIONAL(HAVE_VALGRIND, test ! "x$VALGRIND_PATH" = "xno") + +dnl check for documentation tools +AG_GST_DOCBOOK_CHECK +GTK_DOC_CHECK([1.3]) + +dnl GTK is optional and used in examples +HAVE_GTK=NO +PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.8.0, HAVE_GTK=yes, HAVE_GTK=no) +AM_CONDITIONAL(HAVE_GTK, test "x$HAVE_GTK" = "xyes") + +dnl *** checks for libraries *** + +dnl *** checks for header files *** + +dnl *** checks for types/defines *** + +dnl *** checks for structures *** + +dnl *** checks for compiler characteristics *** + +dnl *** checks for library functions *** + +dnl *** checks for dependancy libraries *** + +dnl GLib is required (GStreamer is ok with GLib-2.8, but we want at least 2.10) +GLIB_REQ=2.10.0 +AC_SUBST([GLIB_REQ]) +AG_GST_GLIB_CHECK([$GLIB_REQ]) + +dnl checks for gstreamer +dnl uninstalled is selected preferentially -- see pkg-config(1) +AG_GST_CHECK_GST($GST_MAJORMINOR, [$GST_REQ]) + +GST_TOOLS_DIR=`$PKG_CONFIG --variable=toolsdir gstreamer-$GST_MAJORMINOR` +if test -z $GST_TOOLS_DIR; then + AC_MSG_ERROR([no tools dir defined in GStreamer pkg-config file; core upgrade needed.]) +fi +AC_SUBST(GST_TOOLS_DIR) + +GST_PLUGINS_DIR=`$PKG_CONFIG gstreamer-$GST_MAJORMINOR --variable pluginsdir` +AC_SUBST(GST_PLUGINS_DIR) +AC_MSG_NOTICE(Using GStreamer Core Plugins in $GST_PLUGINS_DIR) + +AG_GST_CHECK_GST_BASE($GST_MAJORMINOR, [$GST_REQ]) + +AG_GST_CHECK_GST_PLUGINS_BASE($GST_MAJORMINOR, [$GSTPB_REQ]) +GSTPB_PLUGINS_DIR=`$PKG_CONFIG gstreamer-plugins-base-$GST_MAJORMINOR --variable pluginsdir` +AC_SUBST(GSTPB_PLUGINS_DIR) +AC_MSG_NOTICE(Using GStreamer Base Plugins in $GSTPB_PLUGINS_DIR) + +AG_GST_CHECK_GST_CHECK($GST_MAJORMINOR, [$GST_REQ], no) + +dnl FIXME: get rid of this by making sure gstreamer-check brings it in +dnl check for "check", unit testing library/header +AM_PATH_CHECK(0.9.2, HAVE_CHECK=yes, HAVE_CHECK=no) +AM_CONDITIONAL(HAVE_CHECK, test "x$HAVE_CHECK" = "xyes") + +dnl *** set variables based on configure arguments *** + +dnl set license and copyright notice +GST_LICENSE="LGPL" +AC_DEFINE_UNQUOTED(GST_LICENSE, "$GST_LICENSE", [GStreamer license]) +AC_SUBST(GST_LICENSE) + +dnl set location of plugin directory +AG_GST_SET_PLUGINDIR + +dnl define an ERROR_CFLAGS Makefile variable +AG_GST_SET_ERROR_CFLAGS($GST_CVS) + +dnl define correct level for debugging messages +AG_GST_SET_LEVEL_DEFAULT($GST_CVS) + +dnl used in examples +AG_GST_DEFAULT_ELEMENTS + +dnl *** finalize CFLAGS, LDFLAGS, LIBS + +dnl Overview: +dnl GST_OPTION_CFLAGS: common flags for profiling, debugging, errors, ... +dnl GST_*: flags shared by built objects to link against GStreamer +dnl GST_ALL_LDFLAGS: linker flags shared by all +dnl GST_LIB_LDFLAGS: additional linker flags for all libaries +dnl GST_LT_LDFLAGS: library versioning of our libraries +dnl GST_PLUGIN_LDFLAGS: flags to be used for all plugins + +dnl GST_OPTION_CFLAGS +if test "x$USE_DEBUG" = xyes; then + PROFILE_CFLAGS="-g" +fi +AC_SUBST(PROFILE_CFLAGS) + +DEPRECATED_CFLAGS="-DGST_DISABLE_DEPRECATED" +AC_SUBST(DEPRECATED_CFLAGS) + +dnl every flag in GST_OPTION_CFLAGS can be overridden at make time +GST_OPTION_CFLAGS="\$(ERROR_CFLAGS) \$(DEBUG_CFLAGS) \$(PROFILE_CFLAGS) \$(GCOV_CFLAGS) \$(OPT_CFLAGS) \$(DEPRECATED_CFLAGS)" +AC_SUBST(GST_OPTION_CFLAGS) + +dnl FIXME: do we want to rename to GST_ALL_* ? +dnl prefer internal headers to already installed ones +dnl add GST_OPTION_CFLAGS, but overridable +GST_CFLAGS="$GST_CFLAGS \$(GST_OPTION_CFLAGS)" +AC_SUBST(GST_CFLAGS) +AC_SUBST(GST_LIBS) + +dnl GST_ALL_* +dnl vars common to for all internal objects (core libs, elements, applications) +dnl CFLAGS: +dnl - src and build dirs need to be added because every piece that gets built +dnl will need the GStreamer source and generated headers +GST_ALL_CFLAGS="-I\$(top_srcdir) -I\$(top_builddir) $GST_CFLAGS \$(GST_OPTION_CFLAGS)" +AC_SUBST([GST_ALL_CFLAGS]) + +dnl FIXME: check if LTLIBINTL is needed everywhere +dnl I presume it is given that it contains the symbols that _() stuff maps to +GST_ALL_LIBS="$GST_LIBS $LTLIBINTL \$(GCOV_LIBS)" +AC_SUBST([GST_ALL_LIBS]) + +dnl LDFLAGS really should only contain flags, not libs - they get added before +dnl whatevertarget_LIBS and -L flags here affect the rest of the linking +GST_ALL_LDFLAGS="-no-undefined" +AC_SUBST(GST_ALL_LDFLAGS) + +dnl GST_OBJ_* +dnl default vars for all internal objects built on libgstphonon +dnl includes GST_ALL_* +GST_OBJ_CFLAGS="\$(GST_ALL_CFLAGS)" +AC_SUBST([GST_OBJ_CFLAGS]) +GST_OBJ_LIBS="\$(top_builddir)/gst-phonon/libgstphonon.la \$(GST_ALL_LIBS)" +AC_SUBST([GST_OBJ_LIBS]) + +dnl this really should only contain flags, not libs - they get added before +dnl whatevertarget_LIBS and -L flags here affect the rest of the linking + +dnl *** output files *** + +dnl keep this alphabetic per directory, please +AC_CONFIG_FILES([ +Makefile +gst-rtsp.spec +common/Makefile +common/m4/Makefile +m4/Makefile +src/Makefile +]) +AC_OUTPUT + +echo "Gst-rtsp-server configured. Type 'make' to build." diff --git a/docs/design/gst-rtp-server-design b/docs/design/gst-rtp-server-design new file mode 100644 index 0000000..7da8283 --- /dev/null +++ b/docs/design/gst-rtp-server-design @@ -0,0 +1,35 @@ +RTSP server +----------- + +This directory contains an example RTSP server built with various GStreamer +components and libraries. It also uses GStreamer for all of the multimedia +procesing and RTP bits. The following features are implemented: + + - + +Server Design +------------- + +The toplevel component of the server is a GstRTSPServer object. This object +creates and binds on the server socket and attaches into the mainloop. + +For each request a new GstRTSPClient object is created that will accept the +request and a thread is started to handle further communication with the +client until the connection is closed. + +When a client issues a SETUP request we create a GstRTSPSession object, +identified with a sessionid, that will keep track of the state of a client. +The object is destroyed when a TEARDOWN request is made for that sessionid. + +We also maintain a pool of URL to media pipeline mappings. Each url is mapped to +an object that is able to provide a pipeline for that media. We provide +pipelines to stream live captured data, on-demand file streaming or on-demand +transcoding of a file or stream. + +A pool of currently active pipelines is also maintained. Usually the active +pipelines are in use by one or more GstRTSPSession objects. An active pipeline +becomes inactive when no more sessions refer to it. + +A client can choose to start a new pipeline or join a currently active pipeline. +Some active pipeline cannot be joined (such as on-demand streams) but a new +instance of that pipeline can be created. diff --git a/gst-rtsp.spec.in b/gst-rtsp.spec.in new file mode 100644 index 0000000..2c4eebc --- /dev/null +++ b/gst-rtsp.spec.in @@ -0,0 +1,54 @@ +%define gst_majorminor @GST_MAJORMINOR@ + +Name: gstreamer-rtsp-server +Version: @VERSION@ +Release: 1%{?dist} +Summary: GStreamer based RTSP server +Vendor: Collabora Multimedia +Group: Applications/Multimedia +License: LGPLv2+ +Source0: gst-rtsp-%{version}.tar.bz2 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + +BuildRequires: gstreamer-devel >= 0.10.11 + + +%description +This is a RTSP server using the GStreamer framework. + + +%prep +%setup -q -n gst-rtsp-%{version} + + +%build +%configure + +make + +%install +%makeinstall + +# Clean out files that should not be part of the rpm. +rm -f $RPM_BUILD_ROOT%{_libdir}/gstreamer-%{majorminor}/*.a +rm -f $RPM_BUILD_ROOT%{_libdir}/*.a +rm -f $RPM_BUILD_ROOT%{_libdir}/*.la + +%clean +rm -rf $RPM_BUILD_ROOT + + +%post -p /sbin/ldconfig + + +%postun -p /sbin/ldconfig + + +%files +%defattr(-,root,root,-) +%doc AUTHORS COPYING README INSTALL docs/design/gst-rtp-server-design +%{_bindir}/gst-rtsp-server + +%changelog +* Thu Oct 9 2008 Christian Schaller +- First spec file diff --git a/m4/Makefile.am b/m4/Makefile.am new file mode 100644 index 0000000..226cc47 --- /dev/null +++ b/m4/Makefile.am @@ -0,0 +1,18 @@ +EXTRA_DIST = \ + codeset.m4 + gettext.m4 + glibc21.m4 \ + iconv.m4 \ + intdiv0.m4 \ + inttypes-pri.m4 \ + nttypes.m4 \ + inttypes_h.m4 \ + isc-posix.m4 \ + lcmessage.m4 \ + lib-ld.m4 \ + lib-link.m4 \ + lib-prefix.m4 \ + progtest.m4 \ + stdint_h.m4 \ + uintmax_t.m4 \ + ulonglong.m4 diff --git a/m4/codeset.m4 b/m4/codeset.m4 new file mode 100644 index 0000000..59535eb --- /dev/null +++ b/m4/codeset.m4 @@ -0,0 +1,23 @@ +# codeset.m4 serial AM1 (gettext-0.10.40) +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_LANGINFO_CODESET], +[ + AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset, + [AC_TRY_LINK([#include ], + [char* cs = nl_langinfo(CODESET);], + am_cv_langinfo_codeset=yes, + am_cv_langinfo_codeset=no) + ]) + if test $am_cv_langinfo_codeset = yes; then + AC_DEFINE(HAVE_LANGINFO_CODESET, 1, + [Define if you have and nl_langinfo(CODESET).]) + fi +]) diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..82674fa --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,20 @@ +bin_PROGRAMS = gst-rtsp-server + +gst_rtsp_server_SOURCES = main.c \ + rtsp-server.c \ + rtsp-client.c \ + rtsp-media.c \ + rtsp-session-pool.c \ + rtsp-session.c + +gst_rtsp_server_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) +gst_rtsp_server_LDADD = $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) \ + -lgstrtp-@GST_MAJORMINOR@ -lgstrtsp-@GST_MAJORMINOR@ \ + -lgstsdp-@GST_MAJORMINOR@ $(GST_LIBS) $(LIBM) +gst_rtsp_server_LDFLAGS = $(GST_PLUGIN_LDFLAGS) + +noinst_HEADERS = rtsp-server.h \ + rtsp-client.h \ + rtsp-session.h \ + rtsp-session-pool.h \ + rtsp-media.h diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..70b1fdc --- /dev/null +++ b/src/main.c @@ -0,0 +1,43 @@ +/* GStreamer + * Copyright (C) 2008 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +#include "rtsp-server.h" + +int +main (int argc, char *argv[]) +{ + GMainLoop *loop; + GstRTSPServer *server; + + gst_init (&argc, &argv); + + loop = g_main_loop_new (NULL, FALSE); + + /* create a server instance */ + server = gst_rtsp_server_new (); + + /* attach the server to the default maincontext */ + gst_rtsp_server_attach (server, NULL); + + g_main_loop_run (loop); + + return 0; +} diff --git a/src/rtsp-client.c b/src/rtsp-client.c new file mode 100644 index 0000000..b4bcbc1 --- /dev/null +++ b/src/rtsp-client.c @@ -0,0 +1,811 @@ +/* GStreamer + * Copyright (C) 2008 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +#include + +#include "rtsp-client.h" + +#undef DEBUG + +G_DEFINE_TYPE (GstRTSPClient, gst_rtsp_client, G_TYPE_OBJECT); + +static void +gst_rtsp_client_class_init (GstRTSPClientClass * klass) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); +} + +static void +gst_rtsp_client_init (GstRTSPClient * client) +{ +} + +/** + * gst_rtsp_client_new: + * + * Create a new #GstRTSPClient instance. + */ +GstRTSPClient * +gst_rtsp_client_new (void) +{ + GstRTSPClient *result; + + result = g_object_new (GST_TYPE_RTSP_CLIENT, NULL); + + return result; +} + +static void +handle_generic_response (GstRTSPClient *client, GstRTSPStatusCode code, + GstRTSPMessage *request) +{ + GstRTSPMessage response = { 0 }; + + gst_rtsp_message_init_response (&response, code, + gst_rtsp_status_as_text (code), request); + + gst_rtsp_connection_send (client->connection, &response, NULL); +} + +static gboolean +handle_teardown_response (GstRTSPClient *client, const gchar *uri, GstRTSPMessage *request) +{ + GstRTSPResult res; + GstRTSPSessionMedia *media; + GstRTSPSession *session; + gchar *sessid; + GstRTSPMessage response = { 0 }; + GstRTSPStatusCode code; + + res = gst_rtsp_message_get_header (request, GST_RTSP_HDR_SESSION, &sessid, 0); + if (res == GST_RTSP_OK) { + /* we had a session in the request, find it again */ + if (!(session = gst_rtsp_session_pool_find (client->pool, sessid))) + goto session_not_found; + } + else + goto service_unavailable; + + /* get a handle to the configuration of the media in the session */ + media = gst_rtsp_session_get_media (session, client->media); + + gst_rtsp_session_media_stop (media); + + gst_rtsp_session_pool_remove (client->pool, session); + g_object_unref (session); + + /* remove the session id from the request, which will also remove it from the + * response */ + gst_rtsp_message_remove_header (request, GST_RTSP_HDR_SESSION, -1); + + /* construct the response now */ + code = GST_RTSP_STS_OK; + gst_rtsp_message_init_response (&response, code, gst_rtsp_status_as_text (code), request); + + gst_rtsp_connection_send (client->connection, &response, NULL); + + return FALSE; + + /* ERRORS */ +session_not_found: + { + handle_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, request); + return FALSE; + } +service_unavailable: + { + return FALSE; + } +} + +static gboolean +handle_pause_response (GstRTSPClient *client, const gchar *uri, GstRTSPMessage *request) +{ + GstRTSPResult res; + GstRTSPSessionMedia *media; + GstRTSPSession *session; + gchar *sessid; + GstRTSPMessage response = { 0 }; + GstRTSPStatusCode code; + + res = gst_rtsp_message_get_header (request, GST_RTSP_HDR_SESSION, &sessid, 0); + if (res == GST_RTSP_OK) { + /* we had a session in the request, find it again */ + if (!(session = gst_rtsp_session_pool_find (client->pool, sessid))) + goto session_not_found; + } + else + goto service_unavailable; + + /* get a handle to the configuration of the media in the session */ + media = gst_rtsp_session_get_media (session, client->media); + + gst_rtsp_session_media_pause (media); + g_object_unref (session); + + /* construct the response now */ + code = GST_RTSP_STS_OK; + gst_rtsp_message_init_response (&response, code, gst_rtsp_status_as_text (code), request); + + gst_rtsp_connection_send (client->connection, &response, NULL); + + return FALSE; + + /* ERRORS */ +session_not_found: + { + handle_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, request); + return FALSE; + } +service_unavailable: + { + return FALSE; + } +} + +static gboolean +handle_play_response (GstRTSPClient *client, const gchar *uri, GstRTSPMessage *request) +{ + GstRTSPResult res; + GstRTSPSessionMedia *media; + GstRTSPSession *session; + gchar *sessid; + GstRTSPMessage response = { 0 }; + GstRTSPStatusCode code; + GstStateChangeReturn ret; + GString *rtpinfo; + guint n_streams, i; + guint timestamp, seqnum; + + res = gst_rtsp_message_get_header (request, GST_RTSP_HDR_SESSION, &sessid, 0); + if (res == GST_RTSP_OK) { + /* we had a session in the request, find it again */ + if (!(session = gst_rtsp_session_pool_find (client->pool, sessid))) + goto session_not_found; + } + else + goto service_unavailable; + + /* get a handle to the configuration of the media in the session */ + media = gst_rtsp_session_get_media (session, client->media); + + /* wait for paused to get the caps */ + ret = gst_rtsp_session_media_pause (media); + switch (ret) { + case GST_STATE_CHANGE_NO_PREROLL: + break; + case GST_STATE_CHANGE_SUCCESS: + break; + case GST_STATE_CHANGE_FAILURE: + goto service_unavailable; + case GST_STATE_CHANGE_ASYNC: + ret = gst_element_get_state (media->pipeline, NULL, NULL, -1); + break; + } + + /* grab RTPInfo from the payloaders now */ + rtpinfo = g_string_new (""); + n_streams = gst_rtsp_media_n_streams (client->media); + for (i = 0; i < n_streams; i++) { + GstRTSPMediaStream *stream; + + stream = gst_rtsp_media_get_stream (client->media, i); + + g_object_get (G_OBJECT (stream->payloader), "seqnum", &seqnum, NULL); + g_object_get (G_OBJECT (stream->payloader), "timestamp", ×tamp, NULL); + + if (i > 0) + g_string_append (rtpinfo, ", "); + g_string_append_printf (rtpinfo, "url=%s/stream=%d;seq=%u;rtptime=%u", uri, i, seqnum, timestamp); + } + + /* construct the response now */ + code = GST_RTSP_STS_OK; + gst_rtsp_message_init_response (&response, code, gst_rtsp_status_as_text (code), request); + + /* add the RTP-Info header */ + gst_rtsp_message_add_header (&response, GST_RTSP_HDR_RTP_INFO, rtpinfo->str); + g_string_free (rtpinfo, TRUE); + + gst_rtsp_connection_send (client->connection, &response, NULL); + + /* start playing after sending the request */ + gst_rtsp_session_media_play (media); + g_object_unref (session); + + return FALSE; + + /* ERRORS */ +session_not_found: + { + handle_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, request); + return FALSE; + } +service_unavailable: + { + handle_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, request); + return FALSE; + } +} + +static gboolean +handle_setup_response (GstRTSPClient *client, const gchar *uri, GstRTSPMessage *request) +{ + GstRTSPResult res; + gchar *sessid; + gchar *transport; + gchar **transports; + gboolean have_transport; + GstRTSPTransport *ct, *st; + GstRTSPSession *session; + gint i; + GstRTSPLowerTrans supported; + GstRTSPMessage response = { 0 }; + GstRTSPStatusCode code; + GstRTSPSessionStream *stream; + gchar *trans_str, *pos; + guint streamid; + GstRTSPSessionMedia *media; + gboolean need_session; + + /* find the media associated with the uri */ + if (client->media == NULL) { + if ((client->media = gst_rtsp_media_new (uri)) == NULL) + goto not_found; + } + + /* parse the transport */ + res = gst_rtsp_message_get_header (request, GST_RTSP_HDR_TRANSPORT, &transport, 0); + if (res != GST_RTSP_OK) + goto unsupported_transports; + + transports = g_strsplit (transport, ",", 0); + gst_rtsp_transport_new (&ct); + + /* loop through the transports, try to parse */ + have_transport = FALSE; + for (i = 0; transports[i]; i++) { + + gst_rtsp_transport_init (ct); + res = gst_rtsp_transport_parse (transports[i], ct); + if (res == GST_RTSP_OK) { + have_transport = TRUE; + break; + } + } + g_strfreev (transports); + + /* we have not found anything usable, error out */ + if (!have_transport) { + gst_rtsp_transport_free (ct); + goto unsupported_transports; + } + + /* we have a valid transport, check if we can handle it */ + if (ct->trans != GST_RTSP_TRANS_RTP) + goto unsupported_transports; + if (ct->profile != GST_RTSP_PROFILE_AVP) + goto unsupported_transports; + supported = GST_RTSP_LOWER_TRANS_UDP | + GST_RTSP_LOWER_TRANS_UDP_MCAST | GST_RTSP_LOWER_TRANS_TCP; + if (!(ct->lower_transport & supported)) + goto unsupported_transports; + + /* a setup request creates a session for a client, check if the client already + * sent a session id to us */ + res = gst_rtsp_message_get_header (request, GST_RTSP_HDR_SESSION, &sessid, 0); + if (res == GST_RTSP_OK) { + /* we had a session in the request, find it again */ + if (!(session = gst_rtsp_session_pool_find (client->pool, sessid))) + goto session_not_found; + need_session = FALSE; + } + else { + /* create a session if this fails we probably reached our session limit or + * something. */ + if (!(session = gst_rtsp_session_pool_create (client->pool))) + goto service_unavailable; + need_session = TRUE; + } + + /* get a handle to the configuration of the media in the session */ + media = gst_rtsp_session_get_media (session, client->media); + + /* parse the stream we need to configure */ + if (!(pos = strstr (uri, "stream="))) + goto bad_request; + + pos += strlen ("stream="); + if (sscanf (pos, "%u", &streamid) != 1) + goto bad_request; + + /* get a handle to the stream in the media */ + stream = gst_rtsp_session_get_stream (media, streamid); + + /* setup the server transport from the client transport */ + st = gst_rtsp_session_stream_set_transport (stream, inet_ntoa (client->address.sin_addr), ct); + + /* serialize the server transport */ + trans_str = gst_rtsp_transport_as_text (st); + + /* construct the response now */ + code = GST_RTSP_STS_OK; + gst_rtsp_message_init_response (&response, code, gst_rtsp_status_as_text (code), request); + + if (need_session) + gst_rtsp_message_add_header (&response, GST_RTSP_HDR_SESSION, session->sessionid); + gst_rtsp_message_add_header (&response, GST_RTSP_HDR_TRANSPORT, trans_str); + g_free (trans_str); + g_object_unref (session); + + gst_rtsp_connection_send (client->connection, &response, NULL); + + return TRUE; + + /* ERRORS */ +not_found: + { + handle_generic_response (client, GST_RTSP_STS_NOT_FOUND, request); + return FALSE; + } +bad_request: + { + handle_generic_response (client, GST_RTSP_STS_BAD_REQUEST, request); + return FALSE; + } +session_not_found: + { + handle_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, request); + return FALSE; + } +unsupported_transports: + { + handle_generic_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, request); + return FALSE; + } +service_unavailable: + { + handle_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, request); + return FALSE; + } +} + +static gboolean +handle_describe_response (GstRTSPClient *client, const gchar *uri, GstRTSPMessage *request) +{ + GstRTSPMessage response = { 0 }; + GstSDPMessage *sdp; + guint n_streams, i; + gchar *sdptext; + GstRTSPMedia *media; + + /* check what kind of format is accepted */ + + + /* for the describe we must generate an SDP */ + if (!(media = gst_rtsp_media_new (uri))) + goto no_media; + + /* create a pipeline if we have to */ + if (client->pipeline == NULL) { + client->pipeline = gst_pipeline_new ("client-pipeline"); + } + + /* prepare the media into the pipeline */ + if (!gst_rtsp_media_prepare (media, GST_BIN (client->pipeline))) + goto no_media; + + /* link fakesink to all stream pads and set the pipeline to PLAYING */ + n_streams = gst_rtsp_media_n_streams (media); + for (i = 0; i < n_streams; i++) { + GstRTSPMediaStream *stream; + GstElement *sink; + GstPad *sinkpad; + + stream = gst_rtsp_media_get_stream (media, i); + + sink = gst_element_factory_make ("fakesink", NULL); + gst_bin_add (GST_BIN (client->pipeline), sink); + + sinkpad = gst_element_get_static_pad (sink, "sink"); + gst_pad_link (stream->srcpad, sinkpad); + gst_object_unref (sinkpad); + } + + /* now play and wait till we get the pads blocked. At that time the pipeline + * is prerolled and we have the caps on the streams too. */ + gst_element_set_state (client->pipeline, GST_STATE_PLAYING); + + /* wait for state change to complete */ + gst_element_get_state (client->pipeline, NULL, NULL, -1); + + /* we should now be able to construct the SDP message */ + gst_sdp_message_new (&sdp); + + /* some standard things first */ + gst_sdp_message_set_version (sdp, "0"); + gst_sdp_message_set_origin (sdp, "-", "1188340656180883", "1", "IN", "IP4", "127.0.0.1"); + gst_sdp_message_set_session_name (sdp, "Session streamed with GStreamer"); + gst_sdp_message_set_information (sdp, "rtsp-server"); + gst_sdp_message_add_time (sdp, "0", "0", NULL); + gst_sdp_message_add_attribute (sdp, "tool", "GStreamer"); + gst_sdp_message_add_attribute (sdp, "type", "broadcast"); + + for (i = 0; i < n_streams; i++) { + GstRTSPMediaStream *stream; + GstSDPMedia *smedia; + GstStructure *s; + const gchar *caps_str, *caps_enc, *caps_params; + gchar *tmp; + gint caps_pt, caps_rate; + guint n_fields, j; + gboolean first; + GString *fmtp; + + stream = gst_rtsp_media_get_stream (media, i); + gst_sdp_media_new (&smedia); + + s = gst_caps_get_structure (stream->caps, 0); + + /* get media type and payload for the m= line */ + caps_str = gst_structure_get_string (s, "media"); + gst_sdp_media_set_media (smedia, caps_str); + + gst_structure_get_int (s, "payload", &caps_pt); + tmp = g_strdup_printf ("%d", caps_pt); + gst_sdp_media_add_format (smedia, tmp); + g_free (tmp); + + gst_sdp_media_set_port_info (smedia, 0, 1); + gst_sdp_media_set_proto (smedia, "RTP/AVP"); + + /* for the c= line */ + gst_sdp_media_add_connection (smedia, "IN", "IP4", "127.0.0.1", 0, 0); + + /* get clock-rate, media type and params for the rtpmap attribute */ + gst_structure_get_int (s, "clock-rate", &caps_rate); + caps_enc = gst_structure_get_string (s, "encoding-name"); + caps_params = gst_structure_get_string (s, "encoding-params"); + + if (caps_params) + tmp = g_strdup_printf ("%d %s/%d/%s", caps_pt, caps_enc, caps_rate, + caps_params); + else + tmp = g_strdup_printf ("%d %s/%d", caps_pt, caps_enc, caps_rate); + + gst_sdp_media_add_attribute (smedia, "rtpmap", tmp); + g_free (tmp); + + /* the config uri */ + tmp = g_strdup_printf ("stream=%d", i); + gst_sdp_media_add_attribute (smedia, "control", tmp); + g_free (tmp); + + /* collect all other properties and add them to fmtp */ + fmtp = g_string_new (""); + g_string_append_printf (fmtp, "%d ", caps_pt); + first = TRUE; + n_fields = gst_structure_n_fields (s); + for (j = 0; j < n_fields; j++) { + const gchar *fname, *fval; + + fname = gst_structure_nth_field_name (s, j); + + /* filter out standard properties */ + if (!strcmp (fname, "media")) + continue; + if (!strcmp (fname, "payload")) + continue; + if (!strcmp (fname, "clock-rate")) + continue; + if (!strcmp (fname, "encoding-name")) + continue; + if (!strcmp (fname, "encoding-params")) + continue; + if (!strcmp (fname, "ssrc")) + continue; + if (!strcmp (fname, "clock-base")) + continue; + if (!strcmp (fname, "seqnum-base")) + continue; + + if ((fval = gst_structure_get_string (s, fname))) { + g_string_append_printf (fmtp, "%s%s=%s", first ? "":";", fname, fval); + first = FALSE; + } + } + if (!first) { + tmp = g_string_free (fmtp, FALSE); + gst_sdp_media_add_attribute (smedia, "fmtp", tmp); + g_free (tmp); + } + else { + g_string_free (fmtp, TRUE); + } + gst_sdp_message_add_media (sdp, smedia); + } + /* go back to NULL */ + gst_element_set_state (client->pipeline, GST_STATE_NULL); + + g_object_unref (media); + + gst_object_unref (client->pipeline); + client->pipeline = NULL; + + gst_rtsp_message_init_response (&response, GST_RTSP_STS_OK, + gst_rtsp_status_as_text (GST_RTSP_STS_OK), request); + + /* add SDP to the response body */ + sdptext = gst_sdp_message_as_text (sdp); + gst_rtsp_message_take_body (&response, (guint8 *)sdptext, strlen (sdptext)); + gst_sdp_message_free (sdp); + + gst_rtsp_connection_send (client->connection, &response, NULL); + + return TRUE; + + /* ERRORS */ +no_media: + { + handle_generic_response (client, GST_RTSP_STS_NOT_FOUND, request); + return FALSE; + } +} + +static void +handle_options_response (GstRTSPClient *client, const gchar *uri, GstRTSPMessage *request) +{ + GstRTSPMessage response = { 0 }; + GstRTSPMethod options; + GString *str; + + gst_rtsp_message_init_response (&response, GST_RTSP_STS_OK, + gst_rtsp_status_as_text (GST_RTSP_STS_OK), request); + + options = GST_RTSP_DESCRIBE | + GST_RTSP_OPTIONS | + // GST_RTSP_PAUSE | + GST_RTSP_PLAY | + GST_RTSP_SETUP | + GST_RTSP_TEARDOWN; + + /* always return options.. */ + str = g_string_new ("OPTIONS"); + + if (options & GST_RTSP_DESCRIBE) + g_string_append (str, ", DESCRIBE"); + if (options & GST_RTSP_ANNOUNCE) + g_string_append (str, ", ANNOUNCE"); + if (options & GST_RTSP_GET_PARAMETER) + g_string_append (str, ", GET_PARAMETER"); + if (options & GST_RTSP_PAUSE) + g_string_append (str, ", PAUSE"); + if (options & GST_RTSP_PLAY) + g_string_append (str, ", PLAY"); + if (options & GST_RTSP_RECORD) + g_string_append (str, ", RECORD"); + if (options & GST_RTSP_REDIRECT) + g_string_append (str, ", REDIRECT"); + if (options & GST_RTSP_SETUP) + g_string_append (str, ", SETUP"); + if (options & GST_RTSP_SET_PARAMETER) + g_string_append (str, ", SET_PARAMETER"); + if (options & GST_RTSP_TEARDOWN) + g_string_append (str, ", TEARDOWN"); + + gst_rtsp_message_add_header (&response, GST_RTSP_HDR_PUBLIC, str->str); + + g_string_free (str, TRUE); + + gst_rtsp_connection_send (client->connection, &response, NULL); +} + +/* this function runs in a client specific thread and handles all rtsp messages + * with the client */ +static gpointer +handle_client (GstRTSPClient *client) +{ + GstRTSPMessage request = { 0 }; + GstRTSPResult res; + GstRTSPMethod method; + const gchar *uri; + GstRTSPVersion version; + + while (TRUE) { + /* start by waiting for a message from the client */ + res = gst_rtsp_connection_receive (client->connection, &request, NULL); + if (res < 0) + goto receive_failed; + +#ifdef DEBUG + gst_rtsp_message_dump (&request); +#endif + + gst_rtsp_message_parse_request (&request, &method, &uri, &version); + + if (version != GST_RTSP_VERSION_1_0) { + /* we can only handle 1.0 requests */ + handle_generic_response (client, GST_RTSP_STS_RTSP_VERSION_NOT_SUPPORTED, &request); + continue; + } + + /* now see what is asked and dispatch to a dedicated handler */ + switch (method) { + case GST_RTSP_OPTIONS: + handle_options_response (client, uri, &request); + break; + case GST_RTSP_DESCRIBE: + handle_describe_response (client, uri, &request); + break; + case GST_RTSP_SETUP: + handle_setup_response (client, uri, &request); + break; + case GST_RTSP_PLAY: + handle_play_response (client, uri, &request); + break; + case GST_RTSP_PAUSE: + handle_pause_response (client, uri, &request); + break; + case GST_RTSP_TEARDOWN: + handle_teardown_response (client, uri, &request); + break; + case GST_RTSP_ANNOUNCE: + case GST_RTSP_GET_PARAMETER: + case GST_RTSP_RECORD: + case GST_RTSP_REDIRECT: + case GST_RTSP_SET_PARAMETER: + handle_generic_response (client, GST_RTSP_STS_NOT_IMPLEMENTED, &request); + break; + case GST_RTSP_INVALID: + default: + handle_generic_response (client, GST_RTSP_STS_BAD_REQUEST, &request); + break; + } + } + g_object_unref (client); + return NULL; + + /* ERRORS */ +receive_failed: + { + g_print ("receive failed, disconnect client %p\n", client); + gst_rtsp_connection_close (client->connection); + g_object_unref (client); + return NULL; + } +} + +/* called when we need to accept a new request from a client */ +static gboolean +client_accept (GstRTSPClient *client, GIOChannel *source) +{ + /* a new client connected. */ + int server_sock_fd; + unsigned int address_len; + GstRTSPConnection *conn; + + conn = client->connection; + + server_sock_fd = g_io_channel_unix_get_fd (source); + + address_len = sizeof (client->address); + memset (&client->address, 0, address_len); + + conn->fd.fd = accept (server_sock_fd, (struct sockaddr *) &client->address, + &address_len); + if (conn->fd.fd == -1) + goto accept_failed; + + g_print ("added new client %p ip %s with fd %d\n", client, + inet_ntoa (client->address.sin_addr), conn->fd.fd); + + /* FIXME some hackery, we need to have a connection method to accept server + * connections */ + gst_poll_add_fd (conn->fdset, &conn->fd); + + return TRUE; + + /* ERRORS */ +accept_failed: + { + g_error ("Could not accept client on server socket %d: %s (%d)", + server_sock_fd, g_strerror (errno), errno); + return FALSE; + } +} + +/** + * gst_rtsp_client_set_session_pool: + * @client: a #GstRTSPClient + * @pool: a #GstRTSPSessionPool + * + * Set @pool as the sessionpool for @client which it will use to find + * or allocate sessions. + */ +void +gst_rtsp_client_set_session_pool (GstRTSPClient *client, GstRTSPSessionPool *pool) +{ + GstRTSPSessionPool *old; + + old = client->pool; + if (pool) + g_object_ref (pool); + client->pool = pool; + if (old) + g_object_unref (old); +} + +/** + * gst_rtsp_client_get_session_pool: + * @client: a #GstRTSPClient + * + * Get the #GstRTSPSessionPool object that @client uses to manage its sessions. + * + * Returns: a #GstRTSPSessionPool, unref after usage. + */ +GstRTSPSessionPool * +gst_rtsp_client_get_session_pool (GstRTSPClient *client) +{ + GstRTSPSessionPool *result; + + if ((result = client->pool)) + g_object_ref (result); + + return result; +} + + +/** + * gst_rtsp_client_attach: + * @client: a #GstRTSPClient + * @context: a #GMainContext + * + * Attaches @client to @context. When the mainloop for @context is run, the + * client will be dispatched. + * + * This function should be called when the client properties and urls are fully + * configured and the client is ready to start. + * + * Returns: %TRUE if the client could be accepted. + */ +gboolean +gst_rtsp_client_accept (GstRTSPClient *client, GIOChannel *source) +{ + gst_rtsp_connection_create (NULL, &client->connection); + + if (!client_accept (client, source)) + goto accept_failed; + + /* client accepted, spawn a thread for the client */ + g_object_ref (client); + client->thread = g_thread_create ((GThreadFunc)handle_client, client, TRUE, NULL); + + return TRUE; + + /* ERRORS */ +accept_failed: + { + gst_rtsp_connection_close (client->connection); + return FALSE; + } +} diff --git a/src/rtsp-client.h b/src/rtsp-client.h new file mode 100644 index 0000000..a29e688 --- /dev/null +++ b/src/rtsp-client.h @@ -0,0 +1,89 @@ +/* GStreamer + * Copyright (C) 2008 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifndef __GST_RTSP_CLIENT_H__ +#define __GST_RTSP_CLIENT_H__ + +#include "rtsp-media.h" +#include "rtsp-session-pool.h" + +G_BEGIN_DECLS + +#define GST_TYPE_RTSP_CLIENT (gst_rtsp_client_get_type ()) +#define GST_IS_RTSP_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_RTSP_CLIENT)) +#define GST_IS_RTSP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_RTSP_CLIENT)) +#define GST_RTSP_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RTSP_CLIENT, GstRTSPClientClass)) +#define GST_RTSP_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_RTSP_CLIENT, GstRTSPClient)) +#define GST_RTSP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_RTSP_CLIENT, GstRTSPClientClass)) +#define GST_RTSP_CLIENT_CAST(obj) ((GstRTSPClient*)(obj)) +#define GST_RTSP_CLIENT_CLASS_CAST(klass) ((GstRTSPClientClass*)(klass)) + +typedef struct _GstRTSPClient GstRTSPClient; +typedef struct _GstRTSPClientClass GstRTSPClientClass; + +struct _GstRTSPClient { + GObject parent; + + GstRTSPConnection *connection; + struct sockaddr_in address; + + GstRTSPMedia *media; + GstElement *pipeline; + + GstRTSPSessionPool *pool; + GstRTSPSession *session; + + GThread *thread; +}; + +struct _GstRTSPClientClass { + GObjectClass parent_class; +}; + +GType gst_rtsp_client_get_type (void); + +GstRTSPClient * gst_rtsp_client_new (void); + +void gst_rtsp_client_set_session_pool (GstRTSPClient *client, + GstRTSPSessionPool *pool); +GstRTSPSessionPool * gst_rtsp_client_get_session_pool (GstRTSPClient *client); + +gboolean gst_rtsp_client_accept (GstRTSPClient *client, + GIOChannel *source); + +G_END_DECLS + +#endif /* __GST_RTSP_CLIENT_H__ */ diff --git a/src/rtsp-media.c b/src/rtsp-media.c new file mode 100644 index 0000000..c7e181d --- /dev/null +++ b/src/rtsp-media.c @@ -0,0 +1,266 @@ +/* GStreamer + * Copyright (C) 2008 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "rtsp-media.h" + +G_DEFINE_TYPE (GstRTSPMedia, gst_rtsp_media, G_TYPE_OBJECT); + +static void gst_rtsp_media_finalize (GObject * obj); + +static void +gst_rtsp_media_class_init (GstRTSPMediaClass * klass) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = gst_rtsp_media_finalize; +} + +static void +gst_rtsp_media_init (GstRTSPMedia * media) +{ + media->streams = g_array_new (FALSE, TRUE, sizeof (GstRTSPMediaStream *)); +} + +static void +gst_rtsp_media_stream_free (GstRTSPMediaStream *stream) +{ +} + +static void +gst_rtsp_media_finalize (GObject * obj) +{ + GstRTSPMedia *media; + guint i; + + media = GST_RTSP_MEDIA (obj); + + g_free (media->location); + gst_rtsp_url_free (media->url); + + for (i = 0; i < media->streams->len; i++) { + GstRTSPMediaStream *stream; + + stream = g_array_index (media->streams, GstRTSPMediaStream *, i); + + gst_rtsp_media_stream_free (stream); + } + g_array_free (media->streams, TRUE); + + G_OBJECT_CLASS (gst_rtsp_media_parent_class)->finalize (obj); +} + +/** + * gst_rtsp_media_new: + * @location: the URL of the media + * + * Create a new #GstRTSPMedia instance. + * + * Returns: a new #GstRTSPMedia object or %NULL when location did not contain a + * valid or understood URL. + */ +GstRTSPMedia * +gst_rtsp_media_new (const gchar *location) +{ + GstRTSPMedia *result; + GstRTSPUrl *url; + + url = NULL; + + if (gst_rtsp_url_parse (location, &url) != GST_RTSP_OK) + goto invalid_url; + + result = g_object_new (GST_TYPE_RTSP_MEDIA, NULL); + result->location = g_strdup (location); + result->url = url; + + return result; + + /* ERRORS */ +invalid_url: + { + return NULL; + } +} + +static void +caps_notify (GstPad * pad, GParamSpec * unused, GstRTSPMediaStream * stream) +{ + if (stream->caps) + gst_caps_unref (stream->caps); + if ((stream->caps = GST_PAD_CAPS (pad))) + gst_caps_ref (stream->caps); +} + +/** + * + * STREAMING CONFIGURATION + * + * gst_rtsp_media_prepare: + * @media: a #GstRTSPMedia + * @bin: the parent bin to create the elements in. + * + * Prepare the media object so that it creates its streams. Implementations + * should crate the needed gstreamer elements and add them to @bin. No state + * changes should be performed on them yet. + * + * One or more GstRTSPMediaStream objects should be added to @media with the + * srcpad member set to a source pad that produces buffer of type + * application/x-rtp. + * + * Returns: %TRUE if the media could be prepared. + */ +gboolean +gst_rtsp_media_prepare (GstRTSPMedia *media, GstBin *bin) +{ + GstRTSPMediaStream *stream; + GstElement *pay, *element; + GstPad * pad; + gint i; + + /* if we're already prepared we must exit */ + g_return_val_if_fail (media->prepared == FALSE, FALSE); + + g_print ("%s\n", media->url->abspath); + + if (g_str_has_prefix (media->url->abspath, "/camera")) { + /* live */ + element = gst_parse_launch ("( " + "v4l2src ! video/x-raw-yuv,width=352,height=288,framerate=15/1 ! " + "queue ! videorate ! ffmpegcolorspace ! " + "x264enc bitrate=300 ! rtph264pay name=pay0 " + "alsasrc ! audio/x-raw-int,rate=8000 ! queue ! " + "amrnbenc ! rtpamrpay name=pay1 " + ")", NULL); + } + else if (g_str_has_prefix (media->url->abspath, "/h264")) { + /* transcode h264 */ + element = gst_parse_launch ("( uridecodebin " + "uri=file:///home/cschalle/Videos/mi2.avi ! " + "x264enc bitrate=300 ! rtph264pay name=pay0 )", NULL); + } + else if (g_str_has_prefix (media->url->abspath, "/theora")) { + /* transcode theora */ + element = gst_parse_launch ("( uridecodebin " + "uri=file:///home/wim/data/mi2.avi ! " + "theoraenc ! rtptheorapay name=pay0 )", NULL); + } + else if (g_str_has_prefix (media->url->abspath, "/macpclinux")) { + /* theora/vorbis */ + element = gst_parse_launch ("( filesrc " + "location=/home/cschalle/Videos/mac_pc_linux_2.ogg ! oggdemux name=d ! " + "queue ! theoraparse ! rtptheorapay name=pay0 " + "d. ! queue ! vorbisparse ! rtpvorbispay name=pay1 )", NULL); + } + else if (g_str_has_prefix (media->url->abspath, "/rtspproxy")) { + /* proxy RTSP transcode */ + element = gst_parse_launch ("( uridecodebin " + "uri=rtsp://ia300135.us.archive.org:554/0/items/uncovered_interviews/uncovered_interviews_3_256kb.mp4 ! " + "x264enc bitrate=1800 ! rtph264pay name=pay0 )", NULL); + } + else if (g_str_has_prefix (media->url->abspath, "/httpproxy")) { + /* proxy HTTP transcode */ + element = gst_parse_launch ("( uridecodebin " + "uri=http://movies.apple.com/movies/fox/maxpayne/maxpayne-tlre_h480.mov name=d " + "d. ! queue ! x264enc bitrate=1800 ! rtph264pay name=pay0 " + "d. ! queue ! faac ! rtpmp4gpay name=pay1 )", NULL); + } + else + return FALSE; + + gst_bin_add (bin, element); + + for (i = 0; ; i++) { + gchar *name; + + name = g_strdup_printf ("pay%d", i); + + if (!(pay = gst_bin_get_by_name (GST_BIN (element), name))) { + g_free (name); + break; + } + + /* create the stream */ + stream = g_new0 (GstRTSPMediaStream, 1); + stream->media = media; + stream->element = element; + stream->payloader = pay; + stream->idx = media->streams->len; + + pad = gst_element_get_static_pad (pay, "src"); + + stream->srcpad = gst_ghost_pad_new (name, pad); + gst_element_add_pad (stream->element, stream->srcpad); + + stream->caps_sig = g_signal_connect (pad, "notify::caps", (GCallback) caps_notify, stream); + gst_object_unref (pad); + + /* add stream now */ + g_array_append_val (media->streams, stream); + gst_object_unref (pay); + + g_free (name); + } + + media->prepared = TRUE; + + return TRUE; +} + +/** + * gst_rtsp_media_n_streams: + * @media: a #GstRTSPMedia + * + * Get the number of streams in this media. + * + * Returns: The number of streams. + */ +guint +gst_rtsp_media_n_streams (GstRTSPMedia *media) +{ + g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), 0); + g_return_val_if_fail (media->prepared, 0); + + return media->streams->len; +} + +/** + * gst_rtsp_media_get_stream: + * @media: a #GstRTSPMedia + * @idx: the stream index + * + * Retrieve the stream with index @idx from @media. + * + * Returns: the #GstRTSPMediaStream at index @idx. + */ +GstRTSPMediaStream * +gst_rtsp_media_get_stream (GstRTSPMedia *media, guint idx) +{ + GstRTSPMediaStream *res; + + g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL); + g_return_val_if_fail (media->prepared, 0); + g_return_val_if_fail (idx < media->streams->len, NULL); + + res = g_array_index (media->streams, GstRTSPMediaStream *, idx); + + return res; +} + diff --git a/src/rtsp-media.h b/src/rtsp-media.h new file mode 100644 index 0000000..bf4bede --- /dev/null +++ b/src/rtsp-media.h @@ -0,0 +1,79 @@ +/* GStreamer + * Copyright (C) 2008 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + +#ifndef __GST_RTSP_MEDIA_H__ +#define __GST_RTSP_MEDIA_H__ + +G_BEGIN_DECLS + +#define GST_TYPE_RTSP_MEDIA (gst_rtsp_media_get_type ()) +#define GST_IS_RTSP_MEDIA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_RTSP_MEDIA)) +#define GST_IS_RTSP_MEDIA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_RTSP_MEDIA)) +#define GST_RTSP_MEDIA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RTSP_MEDIA, GstRTSPMediaClass)) +#define GST_RTSP_MEDIA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_RTSP_MEDIA, GstRTSPMedia)) +#define GST_RTSP_MEDIA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_RTSP_MEDIA, GstRTSPMediaClass)) +#define GST_RTSP_MEDIA_CAST(obj) ((GstRTSPMedia*)(obj)) +#define GST_RTSP_MEDIA_CLASS_CAST(klass) ((GstRTSPMediaClass*)(klass)) + +typedef struct _GstRTSPMedia GstRTSPMedia; +typedef struct _GstRTSPMediaStream GstRTSPMediaStream; +typedef struct _GstRTSPMediaClass GstRTSPMediaClass; + +struct _GstRTSPMediaStream { + GstRTSPMedia *media; + + guint idx; + gchar *name; + + GstElement *element; + GstPad *srcpad; + GstElement *payloader; + gulong caps_sig; + GstCaps *caps; +}; + +struct _GstRTSPMedia { + GObject parent; + + gchar *location; + GstRTSPUrl *url; + + gboolean prepared; + GArray *streams; +}; + +struct _GstRTSPMediaClass { + GObjectClass parent_class; +}; + +GType gst_rtsp_media_get_type (void); + +GstRTSPMedia * gst_rtsp_media_new (const gchar *name); + +gboolean gst_rtsp_media_prepare (GstRTSPMedia *media, GstBin *bin); + +guint gst_rtsp_media_n_streams (GstRTSPMedia *media); +GstRTSPMediaStream * gst_rtsp_media_get_stream (GstRTSPMedia *media, guint idx); + +G_END_DECLS + +#endif /* __GST_RTSP_MEDIA_H__ */ diff --git a/src/rtsp-server.c b/src/rtsp-server.c new file mode 100644 index 0000000..5242752 --- /dev/null +++ b/src/rtsp-server.c @@ -0,0 +1,232 @@ +/* GStreamer + * Copyright (C) 2008 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +#include "rtsp-server.h" +#include "rtsp-client.h" + +#define TCP_BACKLOG 5 +#define DEFAULT_PORT 1554 + +G_DEFINE_TYPE (GstRTSPServer, gst_rtsp_server, G_TYPE_OBJECT); + +static void +gst_rtsp_server_class_init (GstRTSPServerClass * klass) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); +} + +static void +gst_rtsp_server_init (GstRTSPServer * server) +{ + server->server_port = DEFAULT_PORT; + server->pool = gst_rtsp_session_pool_new (); +} + +/** + * gst_rtsp_server_new: + * + * Create a new #GstRTSPServer instance. + */ +GstRTSPServer * +gst_rtsp_server_new (void) +{ + GstRTSPServer *result; + + result = g_object_new (GST_TYPE_RTSP_SERVER, NULL); + + return result; +} + +static gboolean +gst_rtsp_server_sink_init_send (GstRTSPServer * server) +{ + int ret; + + /* create server socket */ + if ((server->server_sock.fd = socket (AF_INET, SOCK_STREAM, 0)) == -1) + goto no_socket; + + GST_DEBUG_OBJECT (server, "opened sending server socket with fd %d", + server->server_sock.fd); + + /* make address reusable */ + ret = 1; + if (setsockopt (server->server_sock.fd, SOL_SOCKET, SO_REUSEADDR, + (void *) &ret, sizeof (ret)) < 0) + goto reuse_failed; + + /* keep connection alive; avoids SIGPIPE during write */ + ret = 1; + if (setsockopt (server->server_sock.fd, SOL_SOCKET, SO_KEEPALIVE, + (void *) &ret, sizeof (ret)) < 0) + goto keepalive_failed; + + /* name the socket */ + memset (&server->server_sin, 0, sizeof (server->server_sin)); + server->server_sin.sin_family = AF_INET; /* network socket */ + server->server_sin.sin_port = htons (server->server_port); /* on port */ + server->server_sin.sin_addr.s_addr = htonl (INADDR_ANY); /* for hosts */ + + /* bind it */ + GST_DEBUG_OBJECT (server, "binding server socket to address"); + ret = bind (server->server_sock.fd, (struct sockaddr *) &server->server_sin, + sizeof (server->server_sin)); + if (ret) + goto bind_failed; + + /* set the server socket to nonblocking */ + fcntl (server->server_sock.fd, F_SETFL, O_NONBLOCK); + + GST_DEBUG_OBJECT (server, "listening on server socket %d with queue of %d", + server->server_sock.fd, TCP_BACKLOG); + if (listen (server->server_sock.fd, TCP_BACKLOG) == -1) + goto listen_failed; + + GST_DEBUG_OBJECT (server, + "listened on server socket %d, returning from connection setup", + server->server_sock.fd); + + return TRUE; + + /* ERRORS */ +no_socket: + { + GST_ERROR_OBJECT (server, "failed to create socket: %s", g_strerror (errno)); + return FALSE; + } +reuse_failed: + { + if (server->server_sock.fd >= 0) { + close (server->server_sock.fd); + server->server_sock.fd = -1; + } + GST_ERROR_OBJECT (server, "failed to reuse socket: %s", g_strerror (errno)); + return FALSE; + } +keepalive_failed: + { + if (server->server_sock.fd >= 0) { + close (server->server_sock.fd); + server->server_sock.fd = -1; + } + GST_ERROR_OBJECT (server, "failed to configure keepalive socket: %s", g_strerror (errno)); + return FALSE; + } +listen_failed: + { + if (server->server_sock.fd >= 0) { + close (server->server_sock.fd); + server->server_sock.fd = -1; + } + GST_ERROR_OBJECT (server, "failed to listen on socket: %s", g_strerror (errno)); + return FALSE; + } +bind_failed: + { + if (server->server_sock.fd >= 0) { + close (server->server_sock.fd); + server->server_sock.fd = -1; + } + GST_ERROR_OBJECT (server, "failed to bind on socket: %s", g_strerror (errno)); + return FALSE; + } +} + +/* called when an event is available on our server socket */ +static gboolean +server_dispatch (GIOChannel *source, GIOCondition condition, GstRTSPServer *server) +{ + if (condition & G_IO_IN) { + GstRTSPClient *client; + + /* a new client connected, create a session to handle the client. */ + client = gst_rtsp_client_new (); + + /* set the session pool that this client should use */ + gst_rtsp_client_set_session_pool (client, server->pool); + + /* accept connections for that client, this function returns after accepting + * the connection and will run the remainder of the communication with the + * client asyncronously. */ + if (!gst_rtsp_client_accept (client, source)) + goto accept_failed; + + /* can unref the client now, when the request is finished, it will be + * unreffed async. */ + gst_object_unref (client); + } + else { + g_print ("received unknown event %08x", condition); + } + return TRUE; + + /* ERRORS */ +accept_failed: + { + g_error ("Could not accept client on server socket %d: %s (%d)", + server->server_sock.fd, g_strerror (errno), errno); + return FALSE; + } +} + +/** + * gst_rtsp_server_attach: + * @server: a #GstRTSPServer + * @context: a #GMainContext + * + * Attaches @server to @context. When the mainloop for @context is run, the + * server will be dispatched. + * + * This function should be called when the server properties and urls are fully + * configured and the server is ready to start. + * + * Returns: the ID (greater than 0) for the source within the GMainContext. + */ +guint +gst_rtsp_server_attach (GstRTSPServer *server, GMainContext *context) +{ + guint res; + + if (!gst_rtsp_server_sink_init_send (server)) + goto init_failed; + + /* create IO channel for the socket */ + server->io_channel = g_io_channel_unix_new (server->server_sock.fd); + + /* create a watch for reads (new connections) and possible errors */ + server->io_watch = g_io_create_watch (server->io_channel, G_IO_IN | + G_IO_ERR | G_IO_HUP | G_IO_NVAL); + + /* configure the callback */ + g_source_set_callback (server->io_watch, (GSourceFunc) server_dispatch, server, NULL); + + res = g_source_attach (server->io_watch, context); + + return res; + + /* ERRORS */ +init_failed: + { + return 0; + } +} diff --git a/src/rtsp-server.h b/src/rtsp-server.h new file mode 100644 index 0000000..93bc820 --- /dev/null +++ b/src/rtsp-server.h @@ -0,0 +1,86 @@ +/* GStreamer + * Copyright (C) 2008 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "rtsp-session-pool.h" + +#ifndef __GST_RTSP_SERVER_H__ +#define __GST_RTSP_SERVER_H__ + +G_BEGIN_DECLS + +#define GST_TYPE_RTSP_SERVER (gst_rtsp_server_get_type ()) +#define GST_IS_RTSP_SERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_RTSP_SERVER)) +#define GST_IS_RTSP_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_RTSP_SERVER)) +#define GST_RTSP_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RTSP_SERVER, GstRTSPServerClass)) +#define GST_RTSP_SERVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_RTSP_SERVER, GstRTSPServer)) +#define GST_RTSP_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_RTSP_SERVER, GstRTSPServerClass)) +#define GST_RTSP_SERVER_CAST(obj) ((GstRTSPServer*)(obj)) +#define GST_RTSP_SERVER_CLASS_CAST(klass) ((GstRTSPServerClass*)(klass)) + +typedef struct _GstRTSPServer GstRTSPServer; +typedef struct _GstRTSPServerClass GstRTSPServerClass; + +struct _GstRTSPServer { + GObject parent; + + /* server information */ + int server_port; + gchar *host; + struct sockaddr_in server_sin; + + /* socket */ + GstPollFD server_sock; + + GIOChannel *io_channel; + GSource *io_watch; + + /* sessions on this server */ + GstRTSPSessionPool *pool; +}; + +struct _GstRTSPServerClass { + GObjectClass parent_class; +}; + +GType gst_rtsp_server_get_type (void); + +GstRTSPServer * gst_rtsp_server_new (void); + +guint gst_rtsp_server_attach (GstRTSPServer *server, + GMainContext *context); + +G_END_DECLS + +#endif /* __GST_RTSP_SERVER_H__ */ diff --git a/src/rtsp-session-pool.c b/src/rtsp-session-pool.c new file mode 100644 index 0000000..716e888 --- /dev/null +++ b/src/rtsp-session-pool.c @@ -0,0 +1,165 @@ +/* GStreamer + * Copyright (C) 2008 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "rtsp-session-pool.h" + +#undef DEBUG + +G_DEFINE_TYPE (GstRTSPSessionPool, gst_rtsp_session_pool, G_TYPE_OBJECT); + +static void +gst_rtsp_session_pool_class_init (GstRTSPSessionPoolClass * klass) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); +} + +static void +gst_rtsp_session_pool_init (GstRTSPSessionPool * pool) +{ + pool->lock = g_mutex_new (); + pool->sessions = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); +} + +/** + * gst_rtsp_session_pool_new: + * + * Create a new #GstRTSPSessionPool instance. + */ +GstRTSPSessionPool * +gst_rtsp_session_pool_new (void) +{ + GstRTSPSessionPool *result; + + result = g_object_new (GST_TYPE_RTSP_SESSION_POOL, NULL); + + return result; +} + +/** + * gst_rtsp_session_pool_find: + * @pool: the pool to search + * @sessionid: the session id + * + * Find the session with @sessionid in @pool. + * + * Returns: the #GstRTSPSession with @sessionid or %NULL when the session did + * not exist. g_object_unref() after usage. + */ +GstRTSPSession * +gst_rtsp_session_pool_find (GstRTSPSessionPool *pool, const gchar *sessionid) +{ + GstRTSPSession *result; + + g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), NULL); + g_return_val_if_fail (sessionid != NULL, NULL); + + g_mutex_lock (pool->lock); + result = g_hash_table_lookup (pool->sessions, sessionid); + if (result) + g_object_ref (result); + g_mutex_unlock (pool->lock); + + return result; +} + +static gchar * +create_session_id (void) +{ + gchar id[16]; + gint i; + + for (i = 0; i < 16; i++) { + id[i] = g_random_int_range ('a', 'z'); + } + + return g_strndup (id, 16); +} + +/** + * gst_rtsp_session_pool_create: + * @pool: a #GstRTSPSessionPool + * + * Create a new #GstRTSPSession object in @pool. + * + * Returns: a new #GstRTSPSession. + */ +GstRTSPSession * +gst_rtsp_session_pool_create (GstRTSPSessionPool *pool) +{ + GstRTSPSession *result = NULL; + gchar *id; + + g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), NULL); + + do { + /* start by creating a new random session id, we assume that this is random + * enough to not cause a collision, which we will check later */ + id = create_session_id (); + + g_mutex_lock (pool->lock); + /* check if the sessionid existed */ + result = g_hash_table_lookup (pool->sessions, id); + if (result) { + /* found, retry with a different session id*/ + result = NULL; + } + else { + /* not found, create session and insert it in the pool */ + result = gst_rtsp_session_new (id); + /* take additional ref for the pool */ + g_object_ref (result); + g_hash_table_insert (pool->sessions, result->sessionid, result); + } + g_mutex_unlock (pool->lock); + + g_free (id); + } while (result == NULL); + + return result; +} + +/** + * gst_rtsp_session_pool_remove: + * @pool: a #GstRTSPSessionPool + * @sess: a #GstRTSPSession + * + * Remove @sess from @pool and Clean it up. + * + * Returns: a new #GstRTSPSession. + */ +void +gst_rtsp_session_pool_remove (GstRTSPSessionPool *pool, GstRTSPSession *sess) +{ + gboolean found; + + g_return_if_fail (GST_IS_RTSP_SESSION_POOL (pool)); + g_return_if_fail (GST_IS_RTSP_SESSION (sess)); + + g_mutex_lock (pool->lock); + found = g_hash_table_remove (pool->sessions, sess); + g_mutex_unlock (pool->lock); + + if (found) { + g_object_unref (sess); + } +} + diff --git a/src/rtsp-session-pool.h b/src/rtsp-session-pool.h new file mode 100644 index 0000000..9336647 --- /dev/null +++ b/src/rtsp-session-pool.h @@ -0,0 +1,69 @@ +/* GStreamer + * Copyright (C) 2008 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +#ifndef __GST_RTSP_SESSION_POOL_H__ +#define __GST_RTSP_SESSION_POOL_H__ + +#include "rtsp-session.h" + +G_BEGIN_DECLS + +#define GST_TYPE_RTSP_SESSION_POOL (gst_rtsp_session_pool_get_type ()) +#define GST_IS_RTSP_SESSION_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_RTSP_SESSION_POOL)) +#define GST_IS_RTSP_SESSION_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_RTSP_SESSION_POOL)) +#define GST_RTSP_SESSION_POOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RTSP_SESSION_POOL, GstRTSPSessionPoolClass)) +#define GST_RTSP_SESSION_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_RTSP_SESSION_POOL, GstRTSPSessionPool)) +#define GST_RTSP_SESSION_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_RTSP_SESSION_POOL, GstRTSPSessionPoolClass)) +#define GST_RTSP_SESSION_POOL_CAST(obj) ((GstRTSPSessionPool*)(obj)) +#define GST_RTSP_SESSION_POOL_CLASS_CAST(klass) ((GstRTSPSessionPoolClass*)(klass)) + +typedef struct _GstRTSPSessionPool GstRTSPSessionPool; +typedef struct _GstRTSPSessionPoolClass GstRTSPSessionPoolClass; + +/** + * GstRTSPSessionPool: + * + * An object that keeps track of the active sessions. + */ +struct _GstRTSPSessionPool { + GObject parent; + + GMutex *lock; + GHashTable *sessions; +}; + +struct _GstRTSPSessionPoolClass { + GObjectClass parent_class; +}; + +GType gst_rtsp_session_pool_get_type (void); + +GstRTSPSessionPool * gst_rtsp_session_pool_new (void); + +GstRTSPSession * gst_rtsp_session_pool_find (GstRTSPSessionPool *pool, + const gchar *sessionid); +GstRTSPSession * gst_rtsp_session_pool_create (GstRTSPSessionPool *pool); +void gst_rtsp_session_pool_remove (GstRTSPSessionPool *pool, + GstRTSPSession *sess); + +G_END_DECLS + +#endif /* __GST_RTSP_SESSION_POOL_H__ */ diff --git a/src/rtsp-session.c b/src/rtsp-session.c new file mode 100644 index 0000000..7893632 --- /dev/null +++ b/src/rtsp-session.c @@ -0,0 +1,503 @@ +/* GStreamer + * Copyright (C) 2008 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "rtsp-session.h" + +#undef DEBUG + +static void gst_rtsp_session_finalize (GObject * obj); + +G_DEFINE_TYPE (GstRTSPSession, gst_rtsp_session, G_TYPE_OBJECT); + +static void +gst_rtsp_session_class_init (GstRTSPSessionClass * klass) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = gst_rtsp_session_finalize; +} + +static void +gst_rtsp_session_init (GstRTSPSession * session) +{ +} + +static void +gst_rtsp_session_free_stream (GstRTSPSessionStream *stream) +{ + if (stream->client_trans) + gst_rtsp_transport_free (stream->client_trans); + g_free (stream->destination); + if (stream->server_trans) + gst_rtsp_transport_free (stream->server_trans); + + if (stream->udpsrc[0]) + gst_object_unref (stream->udpsrc[0]); + + g_free (stream); +} + +static void +gst_rtsp_session_free_media (GstRTSPSessionMedia *media) +{ + GList *walk; + + gst_element_set_state (media->pipeline, GST_STATE_NULL); + + if (media->media) + g_object_unref (media->media); + + for (walk = media->streams; walk; walk = g_list_next (walk)) { + GstRTSPSessionStream *stream = (GstRTSPSessionStream *) walk->data; + + gst_rtsp_session_free_stream (stream); + } + if (media->pipeline) + gst_object_unref (media->pipeline); + g_list_free (media->streams); +} + +static void +gst_rtsp_session_finalize (GObject * obj) +{ + GstRTSPSession *session; + GList *walk; + + session = GST_RTSP_SESSION (obj); + + g_free (session->sessionid); + + for (walk = session->medias; walk; walk = g_list_next (walk)) { + GstRTSPSessionMedia *media = (GstRTSPSessionMedia *) walk->data; + + gst_rtsp_session_free_media (media); + } + g_list_free (session->medias); + + G_OBJECT_CLASS (gst_rtsp_session_parent_class)->finalize (obj); +} + +/** + * gst_rtsp_session_get_media: + * @sess: a #GstRTSPSession + * @media: a #GstRTSPSessionMedia + * + * Get or create the session information for @media. + * + * Returns: the configuration for @media in @sess. + */ +GstRTSPSessionMedia * +gst_rtsp_session_get_media (GstRTSPSession *sess, GstRTSPMedia *media) +{ + GstRTSPSessionMedia *result; + GList *walk; + + for (walk = sess->medias; walk; walk = g_list_next (walk)) { + result = (GstRTSPSessionMedia *) walk->data; + + if (result->media == media) + break; + + result = NULL; + } + if (result == NULL) { + result = g_new0 (GstRTSPSessionMedia, 1); + result->media = media; + result->pipeline = gst_pipeline_new ("pipeline"); + + /* prepare media into the pipeline */ + if (!gst_rtsp_media_prepare (media, GST_BIN (result->pipeline))) + goto no_media; + + result->rtpbin = gst_element_factory_make ("gstrtpbin", "rtpbin"); + + /* add stuf to the bin */ + gst_bin_add (GST_BIN (result->pipeline), result->rtpbin); + + gst_element_set_state (result->pipeline, GST_STATE_READY); + + sess->medias = g_list_prepend (sess->medias, result); + } + return result; + + /* ERRORS */ +no_media: + { + gst_rtsp_session_free_media (result); + return FALSE; + } +} + +/** + * gst_rtsp_session_get_stream: + * @media: a #GstRTSPSessionMedia + * @idx: the stream index + * + * Get a previously created or create a new #GstRTSPSessionStream at @idx. + * + * Returns: a #GstRTSPSessionStream that is valid until the session of @media + * is unreffed. + */ +GstRTSPSessionStream * +gst_rtsp_session_get_stream (GstRTSPSessionMedia *media, guint idx) +{ + GstRTSPSessionStream *result; + GList *walk; + + for (walk = media->streams; walk; walk = g_list_next (walk)) { + result = (GstRTSPSessionStream *) walk->data; + + if (result->idx == idx) + break; + + result = NULL; + } + if (result == NULL) { + result = g_new0 (GstRTSPSessionStream, 1); + result->idx = idx; + result->media = media; + result->media_stream = gst_rtsp_media_get_stream (media->media, idx); + + media->streams = g_list_prepend (media->streams, result); + } + return result; +} + +/** + * gst_rtsp_session_new: + * + * Create a new #GstRTSPSession instance. + */ +GstRTSPSession * +gst_rtsp_session_new (const gchar *sessionid) +{ + GstRTSPSession *result; + + result = g_object_new (GST_TYPE_RTSP_SESSION, NULL); + result->sessionid = g_strdup (sessionid); + + return result; +} + +static gboolean +alloc_udp_ports (GstRTSPSessionStream * stream) +{ + GstStateChangeReturn ret; + GstElement *udpsrc0, *udpsrc1; + GstElement *udpsink0, *udpsink1; + gint tmp_rtp, tmp_rtcp; + guint count; + gint rtpport, rtcpport, sockfd; + gchar *name; + + udpsrc0 = NULL; + udpsrc1 = NULL; + udpsink0 = NULL; + udpsink1 = NULL; + count = 0; + + /* Start with random port */ + tmp_rtp = 0; + + /* try to allocate 2 UDP ports, the RTP port should be an even + * number and the RTCP port should be the next (uneven) port */ +again: + udpsrc0 = gst_element_make_from_uri (GST_URI_SRC, "udp://0.0.0.0", NULL); + if (udpsrc0 == NULL) + goto no_udp_protocol; + g_object_set (G_OBJECT (udpsrc0), "port", tmp_rtp, NULL); + + ret = gst_element_set_state (udpsrc0, GST_STATE_PAUSED); + if (ret == GST_STATE_CHANGE_FAILURE) { + if (tmp_rtp != 0) { + tmp_rtp += 2; + if (++count > 20) + goto no_ports; + + gst_element_set_state (udpsrc0, GST_STATE_NULL); + gst_object_unref (udpsrc0); + + goto again; + } + goto no_udp_protocol; + } + + g_object_get (G_OBJECT (udpsrc0), "port", &tmp_rtp, NULL); + + /* check if port is even */ + if ((tmp_rtp & 1) != 0) { + /* port not even, close and allocate another */ + if (++count > 20) + goto no_ports; + + gst_element_set_state (udpsrc0, GST_STATE_NULL); + gst_object_unref (udpsrc0); + + tmp_rtp++; + goto again; + } + + /* allocate port+1 for RTCP now */ + udpsrc1 = gst_element_make_from_uri (GST_URI_SRC, "udp://0.0.0.0", NULL); + if (udpsrc1 == NULL) + goto no_udp_rtcp_protocol; + + /* set port */ + tmp_rtcp = tmp_rtp + 1; + g_object_set (G_OBJECT (udpsrc1), "port", tmp_rtcp, NULL); + + ret = gst_element_set_state (udpsrc1, GST_STATE_PAUSED); + /* tmp_rtcp port is busy already : retry to make rtp/rtcp pair */ + if (ret == GST_STATE_CHANGE_FAILURE) { + + if (++count > 20) + goto no_ports; + + gst_element_set_state (udpsrc0, GST_STATE_NULL); + gst_object_unref (udpsrc0); + + gst_element_set_state (udpsrc1, GST_STATE_NULL); + gst_object_unref (udpsrc1); + + tmp_rtp += 2; + goto again; + } + + /* all fine, do port check */ + g_object_get (G_OBJECT (udpsrc0), "port", &rtpport, NULL); + g_object_get (G_OBJECT (udpsrc1), "port", &rtcpport, NULL); + + /* this should not happen... */ + if (rtpport != tmp_rtp || rtcpport != tmp_rtcp) + goto port_error; + + name = g_strdup_printf ("udp://%s:%d", stream->destination, stream->client_trans->client_port.min); + udpsink0 = gst_element_make_from_uri (GST_URI_SINK, name, NULL); + g_free (name); + + if (!udpsink0) + goto no_udp_protocol; + + g_object_get (G_OBJECT (udpsrc0), "sock", &sockfd, NULL); + g_object_set (G_OBJECT (udpsink0), "sockfd", sockfd, NULL); + g_object_set (G_OBJECT (udpsink0), "closefd", FALSE, NULL); + + name = g_strdup_printf ("udp://%s:%d", stream->destination, stream->client_trans->client_port.max); + udpsink1 = gst_element_make_from_uri (GST_URI_SINK, name, NULL); + g_free (name); + + if (!udpsink1) + goto no_udp_protocol; + + g_object_get (G_OBJECT (udpsrc1), "sock", &sockfd, NULL); + g_object_set (G_OBJECT (udpsink1), "sockfd", sockfd, NULL); + g_object_set (G_OBJECT (udpsink1), "closefd", FALSE, NULL); + g_object_set (G_OBJECT (udpsink1), "sync", FALSE, NULL); + g_object_set (G_OBJECT (udpsink1), "async", FALSE, NULL); + + + /* we keep these elements, we configure all in configure_transport when the + * server told us to really use the UDP ports. */ + stream->udpsrc[0] = gst_object_ref (udpsrc0); + stream->udpsrc[1] = gst_object_ref (udpsrc1); + stream->udpsink[0] = gst_object_ref (udpsink0); + stream->udpsink[1] = gst_object_ref (udpsink1); + stream->server_trans->server_port.min = rtpport; + stream->server_trans->server_port.max = rtcpport; + + /* they are ours now */ + gst_object_sink (udpsrc0); + gst_object_sink (udpsrc1); + gst_object_sink (udpsink0); + gst_object_sink (udpsink1); + + return TRUE; + + /* ERRORS */ +no_udp_protocol: + { + goto cleanup; + } +no_ports: + { + goto cleanup; + } +no_udp_rtcp_protocol: + { + goto cleanup; + } +port_error: + { + goto cleanup; + } +cleanup: + { + if (udpsrc0) { + gst_element_set_state (udpsrc0, GST_STATE_NULL); + gst_object_unref (udpsrc0); + } + if (udpsrc1) { + gst_element_set_state (udpsrc1, GST_STATE_NULL); + gst_object_unref (udpsrc1); + } + if (udpsink0) { + gst_element_set_state (udpsink0, GST_STATE_NULL); + gst_object_unref (udpsink0); + } + if (udpsink1) { + gst_element_set_state (udpsink1, GST_STATE_NULL); + gst_object_unref (udpsink1); + } + return FALSE; + } +} + + +/** + * gst_rtsp_session_stream_init_udp: + * @stream: a #GstRTSPSessionStream + * @ct: a client #GstRTSPTransport + * + * Set @ct as the client transport and create and return a matching server + * transport. After this call the needed ports and elements will be created and + * initialized. + * + * Returns: a server transport or NULL if something went wrong. + */ +GstRTSPTransport * +gst_rtsp_session_stream_set_transport (GstRTSPSessionStream *stream, + const gchar *destination, GstRTSPTransport *ct) +{ + GstRTSPTransport *st; + GstPad *pad; + gchar *name; + GstRTSPSessionMedia *media; + + media = stream->media; + + /* prepare the server transport */ + gst_rtsp_transport_new (&st); + + st->trans = ct->trans; + st->profile = ct->profile; + st->lower_transport = ct->lower_transport; + st->client_port = ct->client_port; + + /* keep track of the transports */ + g_free (stream->destination); + stream->destination = g_strdup (destination); + if (stream->client_trans) + gst_rtsp_transport_free (stream->client_trans); + stream->client_trans = ct; + if (stream->server_trans) + gst_rtsp_transport_free (stream->server_trans); + stream->server_trans = st; + + alloc_udp_ports (stream); + + gst_bin_add (GST_BIN (media->pipeline), stream->udpsink[0]); + gst_bin_add (GST_BIN (media->pipeline), stream->udpsink[1]); + gst_bin_add (GST_BIN (media->pipeline), stream->udpsrc[1]); + + /* hook up the stream to the RTP session elements. */ + name = g_strdup_printf ("send_rtp_sink_%d", stream->idx); + stream->send_rtp_sink = gst_element_get_request_pad (media->rtpbin, name); + g_free (name); + name = g_strdup_printf ("send_rtp_src_%d", stream->idx); + stream->send_rtp_src = gst_element_get_static_pad (media->rtpbin, name); + g_free (name); + name = g_strdup_printf ("send_rtcp_src_%d", stream->idx); + stream->send_rtcp_src = gst_element_get_request_pad (media->rtpbin, name); + g_free (name); + name = g_strdup_printf ("recv_rtcp_sink_%d", stream->idx); + stream->recv_rtcp_sink = gst_element_get_request_pad (media->rtpbin, name); + g_free (name); + + gst_pad_link (stream->media_stream->srcpad, stream->send_rtp_sink); + pad = gst_element_get_static_pad (stream->udpsink[0], "sink"); + gst_pad_link (stream->send_rtp_src, pad); + gst_object_unref (pad); + pad = gst_element_get_static_pad (stream->udpsink[1], "sink"); + gst_pad_link (stream->send_rtcp_src, pad); + gst_object_unref (pad); + pad = gst_element_get_static_pad (stream->udpsrc[1], "src"); + gst_pad_link (pad, stream->recv_rtcp_sink); + gst_object_unref (pad); + + return st; +} + +/** + * gst_rtsp_session_media_play: + * @media: a #GstRTSPSessionMedia + * + * Tell the media object @media to start playing and streaming to the client. + * + * Returns: a #GstStateChangeReturn + */ +GstStateChangeReturn +gst_rtsp_session_media_play (GstRTSPSessionMedia *media) +{ + GstStateChangeReturn ret; + + ret = gst_element_set_state (media->pipeline, GST_STATE_PLAYING); + + return ret; +} + +/** + * gst_rtsp_session_media_pause: + * @media: a #GstRTSPSessionMedia + * + * Tell the media object @media to pause. + * + * Returns: a #GstStateChangeReturn + */ +GstStateChangeReturn +gst_rtsp_session_media_pause (GstRTSPSessionMedia *media) +{ + GstStateChangeReturn ret; + + ret = gst_element_set_state (media->pipeline, GST_STATE_PAUSED); + + return ret; +} + +/** + * gst_rtsp_session_media_stop: + * @media: a #GstRTSPSessionMedia + * + * Tell the media object @media to stop playing. After this call the media + * cannot be played or paused anymore + * + * Returns: a #GstStateChangeReturn + */ +GstStateChangeReturn +gst_rtsp_session_media_stop (GstRTSPSessionMedia *media) +{ + GstStateChangeReturn ret; + + ret = gst_element_set_state (media->pipeline, GST_STATE_NULL); + + return ret; +} + + diff --git a/src/rtsp-session.h b/src/rtsp-session.h new file mode 100644 index 0000000..5ad4b3b --- /dev/null +++ b/src/rtsp-session.h @@ -0,0 +1,138 @@ +/* GStreamer + * Copyright (C) 2008 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +#include + +#include "rtsp-media.h" + +#ifndef __GST_RTSP_SESSION_H__ +#define __GST_RTSP_SESSION_H__ + +G_BEGIN_DECLS + +#define GST_TYPE_RTSP_SESSION (gst_rtsp_session_get_type ()) +#define GST_IS_RTSP_SESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_RTSP_SESSION)) +#define GST_IS_RTSP_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_RTSP_SESSION)) +#define GST_RTSP_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RTSP_SESSION, GstRTSPSessionClass)) +#define GST_RTSP_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_RTSP_SESSION, GstRTSPSession)) +#define GST_RTSP_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_RTSP_SESSION, GstRTSPSessionClass)) +#define GST_RTSP_SESSION_CAST(obj) ((GstRTSPSession*)(obj)) +#define GST_RTSP_SESSION_CLASS_CAST(klass) ((GstRTSPSessionClass*)(klass)) + +typedef struct _GstRTSPSession GstRTSPSession; +typedef struct _GstRTSPSessionClass GstRTSPSessionClass; + +typedef struct _GstRTSPSessionStream GstRTSPSessionStream; +typedef struct _GstRTSPSessionMedia GstRTSPSessionMedia; + +/** + * GstRTSPSessionStream: + * + * Configuration of a stream. + */ +struct _GstRTSPSessionStream +{ + guint idx; + + /* the owner media */ + GstRTSPSessionMedia *media; + + GstRTSPMediaStream *media_stream; + + /* client and server transports */ + gchar *destination; + GstRTSPTransport *client_trans; + GstRTSPTransport *server_trans; + + /* pads on the rtpbin */ + GstPad *recv_rtcp_sink; + GstPad *send_rtp_sink; + GstPad *send_rtp_src; + GstPad *send_rtcp_src; + + /* sinks used for sending and receiving RTP and RTCP, they share sockets */ + GstElement *udpsrc[2]; + GstElement *udpsink[2]; +}; + +/** + * GstRTSPSessionMedia: + * + * State of a client session regarding a specific media. + */ +struct _GstRTSPSessionMedia +{ + /* the owner session */ + GstRTSPSession *session; + + /* the media we are handling */ + GstRTSPMedia *media; + + /* the pipeline for the media */ + GstElement *pipeline; + + /* RTP session manager */ + GstElement *rtpbin; + + /* for TCP transport */ + GstElement *fdsink; + + /* configuration for the different streams */ + GList *streams; +}; + +/** + * GstRTSPSession: + * + * Session information kept by the server for a specific client. + */ +struct _GstRTSPSession { + GObject parent; + + gchar *sessionid; + + GList *medias; +}; + +struct _GstRTSPSessionClass { + GObjectClass parent_class; +}; + +GType gst_rtsp_session_get_type (void); + +GstRTSPSession * gst_rtsp_session_new (const gchar *sessionid); + +GstRTSPSessionMedia * gst_rtsp_session_get_media (GstRTSPSession *sess, + GstRTSPMedia *media); +GstRTSPSessionStream * gst_rtsp_session_get_stream (GstRTSPSessionMedia *media, + guint idx); + +GstStateChangeReturn gst_rtsp_session_media_play (GstRTSPSessionMedia *media); +GstStateChangeReturn gst_rtsp_session_media_pause (GstRTSPSessionMedia *media); +GstStateChangeReturn gst_rtsp_session_media_stop (GstRTSPSessionMedia *media); + +GstRTSPTransport * gst_rtsp_session_stream_set_transport (GstRTSPSessionStream *stream, + const gchar *destination, + GstRTSPTransport *ct); + +G_END_DECLS + +#endif /* __GST_RTSP_SESSION_H__ */ -- 2.7.4