Initial import

This commit is contained in:
Wim Taymans 2008-10-09 13:29:12 +01:00 committed by Simon McVittie
commit 5029c85a46
81 changed files with 14004 additions and 0 deletions

1
AUTHORS Normal file
View file

@ -0,0 +1 @@
Wim Taymans <wim.taymans@collabora.co.uk>

481
COPYING Normal file
View file

@ -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.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU 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.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

481
COPYING.LIB Normal file
View file

@ -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.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU 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.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

0
ChangeLog Normal file
View file

32
Makefile.am Normal file
View file

@ -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

1
NEWS Normal file
View file

@ -0,0 +1 @@
This is GstRTSP

18
README Normal file
View file

@ -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

0
RELEASE Normal file
View file

3
REQUIREMENTS Normal file
View file

@ -0,0 +1,3 @@
You need to have GStreamer. You can use an installed version of
GStreamer or from its build dir.

4
TODO Normal file
View file

@ -0,0 +1,4 @@
- implement multicast and TCP transports
- use a config file to configure the server
- error recovery

103
autogen.sh Executable file
View file

@ -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
}

1041
common/ChangeLog Normal file

File diff suppressed because it is too large Load diff

15
common/Makefile.am Normal file
View file

@ -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

34
common/c-to-xml.py Normal file
View file

@ -0,0 +1,34 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
"""
Convert a C program to valid XML to be included in docbook
"""
import sys
import os
from xml.sax import saxutils
def main():
if len(sys.argv) == 1:
sys.stderr.write("Please specify a source file to convert")
sys.exit(1)
source = sys.argv[1]
if not os.path.exists(source):
sys.stderr.write("%s does not exist.\n" % source)
sys.exit(1)
content = open(source, "r").read()
# print header
print '<?xml version="1.0"?>'
print '<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">'
print
print '<programlisting>'
# print content
print saxutils.escape(content).encode('UTF-8')
print '</programlisting>'
main()

149
common/check.mak Normal file
View file

@ -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"

View file

@ -0,0 +1,70 @@
#!/usr/bin/perl
#
# Copyright (C) 2006 Daniel Berrange
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
print <<EOF;
<html>
<head>
<title>Coverage report for $ARGV[0]</title>
<style type="text/css">
span.perfect {
background: rgb(0,255,0);
}
span.terrible {
background: rgb(255,0,0);
}
</style>
</head>
<body>
<h1>Coverage report for $ARGV[0]</h1>
<pre>
EOF
while (<>) {
s/&/&amp;/g;
s/</&lt;/g;
s/>/&gt;/g;
if (/^\s*function (\S+) called (\d+) returned \d+% blocks executed \d+%/) {
my $class = $2 > 0 ? "perfect" : "terrible";
$_ = "<span class=\"$class\" id=\"" . $1 . "\">$_</span>";
} elsif (/^\s*branch\s+\d+\s+taken\s+(\d+)%\s+.*$/) {
my $class = $1 > 0 ? "perfect" : "terrible";
$_ = "<span class=\"$class\">$_</span>";
} elsif (/^\s*branch\s+\d+\s+never executed.*$/) {
my $class = "terrible";
$_ = "<span class=\"$class\">$_</span>";
} elsif (/^\s*call\s+\d+\s+never executed.*$/) {
my $class = "terrible";
$_ = "<span class=\"$class\">$_</span>";
} elsif (/^\s*call\s+\d+\s+returned\s+(\d+)%.*$/) {
my $class = $1 > 0 ? "perfect" : "terrible";
$_ = "<span class=\"$class\">$_</span>";
}
print;
}
print <<EOF;
</pre>
</body>
</html>
EOF

View file

@ -0,0 +1,125 @@
#!/usr/bin/perl
#
# Copyright (C) 2006 Daniel Berrange
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
use warnings;
use strict;
my %coverage = ( functions => {}, files => {} );
my %filemap;
my $type;
my $name;
my @functions;
while (<>) {
if (/^Function '(.*)'\s*$/) {
$type = "function";
$name = $1;
$coverage{$type}->{$name} = {};
push @functions, $name;
} elsif (/^File '(.*?)'\s*$/) {
$type = "file";
$name = $1;
$coverage{$type}->{$name} = {};
foreach my $func (@functions) {
$coverage{"function"}->{$func}->{file} = $name;
}
@functions = ();
} elsif (/^Lines executed:(.*)%\s*of\s*(\d+)\s*$/) {
$coverage{$type}->{$name}->{lines} = $2;
$coverage{$type}->{$name}->{linesCoverage} = $1;
} elsif (/^Branches executed:(.*)%\s*of\s*(\d+)\s*$/) {
$coverage{$type}->{$name}->{branches} = $2;
$coverage{$type}->{$name}->{branchesCoverage} = $1;
} elsif (/^Taken at least once:(.*)%\s*of\s*(\d+)\s*$/) {
$coverage{$type}->{$name}->{conds} = $2;
$coverage{$type}->{$name}->{condsCoverage} = $1;
} elsif (/^Calls executed:(.*)%\s*of\s*(\d+)\s*$/) {
$coverage{$type}->{$name}->{calls} = $2;
$coverage{$type}->{$name}->{callsCoverage} = $1;
} elsif (/^No branches$/) {
$coverage{$type}->{$name}->{branches} = 0;
$coverage{$type}->{$name}->{branchesCoverage} = "100.00";
$coverage{$type}->{$name}->{conds} = 0;
$coverage{$type}->{$name}->{condsCoverage} = "100.00";
} elsif (/^No calls$/) {
$coverage{$type}->{$name}->{calls} = 0;
$coverage{$type}->{$name}->{callsCoverage} = "100.00";
} elsif (/^\s*(.*):creating '(.*)'\s*$/) {
$filemap{$1} = $2;
} elsif (/^\s*$/) {
# nada
} else {
warn "Shit [$_]\n";
}
}
my %summary;
foreach my $type ("function", "file") {
$summary{$type} = {};
foreach my $m ("lines", "branches", "conds", "calls") {
my $totalGot = 0;
my $totalMiss = 0;
my $count = 0;
foreach my $func (keys %{$coverage{function}}) {
$count++;
my $got = $coverage{function}->{$func}->{$m};
$totalGot += $got;
my $miss = $got * $coverage{function}->{$func}->{$m ."Coverage"} / 100;
$totalMiss += $miss;
}
$summary{$type}->{$m} = sprintf("%d", $totalGot);
$summary{$type}->{$m . "Coverage"} = sprintf("%.2f", $totalMiss / $totalGot * 100);
}
}
print "<coverage>\n";
foreach my $type ("function", "file") {
printf "<%ss>\n", $type;
foreach my $name (sort { $a cmp $b } keys %{$coverage{$type}}) {
my $rec = $coverage{$type}->{$name};
printf " <entry name=\"%s\" details=\"%s\">\n", $name, ($type eq "file" ? $filemap{$name} : $filemap{$rec->{file}});
printf " <lines count=\"%s\" coverage=\"%s\"/>\n", $rec->{lines}, $rec->{linesCoverage};
if (exists $rec->{branches}) {
printf " <branches count=\"%s\" coverage=\"%s\"/>\n", $rec->{branches}, $rec->{branchesCoverage};
}
if (exists $rec->{conds}) {
printf " <conditions count=\"%s\" coverage=\"%s\"/>\n", $rec->{conds}, $rec->{condsCoverage};
}
if (exists $rec->{calls}) {
printf " <calls count=\"%s\" coverage=\"%s\"/>\n", $rec->{calls}, $rec->{callsCoverage};
}
print " </entry>\n";
}
printf " <summary>\n";
printf " <lines count=\"%s\" coverage=\"%s\"/>\n", $summary{$type}->{lines}, $summary{$type}->{linesCoverage};
printf " <branches count=\"%s\" coverage=\"%s\"/>\n", $summary{$type}->{branches}, $summary{$type}->{branchesCoverage};
printf " <conditions count=\"%s\" coverage=\"%s\"/>\n", $summary{$type}->{conds}, $summary{$type}->{condsCoverage};
printf " <calls count=\"%s\" coverage=\"%s\"/>\n", $summary{$type}->{calls}, $summary{$type}->{callsCoverage};
printf " </summary>\n";
printf "</%ss>\n", $type;
}
print "</coverage>\n";

View file

@ -0,0 +1,235 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
#
# Copyright (C) 2006 Daniel Berrange
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html"/>
<xsl:template match="coverage">
<html>
<head>
<title>Coverage report</title>
<style type="text/css">
tbody tr.odd td.label {
border-top: 1px solid rgb(128,128,128);
border-bottom: 1px solid rgb(128,128,128);
}
tbody tr.odd td.label {
background: rgb(200,200,200);
}
thead, tfoot {
background: rgb(60,60,60);
color: white;
font-weight: bold;
}
tr td.perfect {
background: rgb(0,255,0);
color: black;
}
tr td.excellant {
background: rgb(140,255,140);
color: black;
}
tr td.good {
background: rgb(160,255,0);
color: black;
}
tr td.poor {
background: rgb(255,160,0);
color: black;
}
tr td.bad {
background: rgb(255,140,140);
color: black;
}
tr td.terrible {
background: rgb(255,0,0);
color: black;
}
</style>
</head>
<body>
<h1>Coverage report</h1>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="functions">
<h2>Function coverage</h2>
<xsl:call-template name="content">
<xsl:with-param name="type" select="'function'"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="files">
<h2>File coverage</h2>
<xsl:call-template name="content">
<xsl:with-param name="type" select="'file'"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="content">
<xsl:param name="type"/>
<table>
<thead>
<tr>
<th>Name</th>
<th>Lines</th>
<th>Branches</th>
<th>Conditions</th>
<th>Calls</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="entry">
<xsl:call-template name="entry">
<xsl:with-param name="type" select="$type"/>
<xsl:with-param name="class">
<xsl:choose>
<xsl:when test="position() mod 2">
<xsl:text>odd</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>even</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</tbody>
<tfoot>
<xsl:for-each select="summary">
<xsl:call-template name="entry">
<xsl:with-param name="type" select="'summary'"/>
<xsl:with-param name="class">
<xsl:choose>
<xsl:when test="position() mod 2">
<xsl:text>odd</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>even</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</tfoot>
</table>
</xsl:template>
<xsl:template name="entry">
<xsl:param name="type"/>
<xsl:param name="class"/>
<tr class="{$class}">
<xsl:choose>
<xsl:when test="$type = 'function'">
<td class="label"><a href="{@details}.html#{@name}"><xsl:value-of select="@name"/></a></td>
</xsl:when>
<xsl:when test="$type = 'file'">
<td class="label"><a href="{@details}.html"><xsl:value-of select="@name"/></a></td>
</xsl:when>
<xsl:otherwise>
<td class="label">Summary</td>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="count(lines)">
<xsl:apply-templates select="lines"/>
</xsl:if>
<xsl:if test="not(count(lines))">
<xsl:call-template name="missing"/>
</xsl:if>
<xsl:if test="count(branches)">
<xsl:apply-templates select="branches"/>
</xsl:if>
<xsl:if test="not(count(branches))">
<xsl:call-template name="missing"/>
</xsl:if>
<xsl:if test="count(conditions)">
<xsl:apply-templates select="conditions"/>
</xsl:if>
<xsl:if test="not(count(conditions))">
<xsl:call-template name="missing"/>
</xsl:if>
<xsl:if test="count(calls)">
<xsl:apply-templates select="calls"/>
</xsl:if>
<xsl:if test="not(count(calls))">
<xsl:call-template name="missing"/>
</xsl:if>
</tr>
</xsl:template>
<xsl:template match="lines">
<xsl:call-template name="row"/>
</xsl:template>
<xsl:template match="branches">
<xsl:call-template name="row"/>
</xsl:template>
<xsl:template match="conditions">
<xsl:call-template name="row"/>
</xsl:template>
<xsl:template match="calls">
<xsl:call-template name="row"/>
</xsl:template>
<xsl:template name="missing">
<td></td>
</xsl:template>
<xsl:template name="row">
<xsl:variable name="quality">
<xsl:choose>
<xsl:when test="@coverage = 100">
<xsl:text>perfect</xsl:text>
</xsl:when>
<xsl:when test="@coverage >= 80.0">
<xsl:text>excellant</xsl:text>
</xsl:when>
<xsl:when test="@coverage >= 60.0">
<xsl:text>good</xsl:text>
</xsl:when>
<xsl:when test="@coverage >= 40.0">
<xsl:text>poor</xsl:text>
</xsl:when>
<xsl:when test="@coverage >= 20.0">
<xsl:text>bad</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>terrible</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<td class="{$quality}"><xsl:value-of select="@coverage"/>% of <xsl:value-of select="@count"/></td>
</xsl:template>
</xsl:stylesheet>

29
common/coverage/lcov.mak Normal file
View file

@ -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)

23
common/gettext.patch Normal file
View file

@ -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

42
common/glib-gen.mak Normal file
View file

@ -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 <glib-object.h>\n\nG_BEGIN_DECLS\n" \
--fprod "\n/* enumerations from \"@filename@\" */\n" \
--vhead "GType @enum_name@_get_type (void);\n#define GST_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \
--ftail "G_END_DECLS\n\n#endif /* __$(glib_enum_define)_ENUM_TYPES_H__ */" \
$^ > $@
%-enumtypes.c: $(glib_enum_headers)
@if test "x$(glib_enum_headers)" == "x"; then echo "ERROR: glib_enum_headers is empty, please fix Makefile"; exit 1; fi
glib-mkenums \
--fhead "#include <$*.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 $@

308
common/gst-autogen.sh Normal file
View file

@ -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
}
}

168
common/gst-xmlinspect.py Normal file
View file

@ -0,0 +1,168 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
"""
examine all plugins and elements and output xml documentation for them
used as part of the plugin documentation build
"""
import sys
import os
import pygst
pygst.require('0.10')
import gst
INDENT_SIZE = 2
# all templates
PAD_TEMPLATE = """<caps>
<name>%(name)s</name>
<direction>%(direction)s</direction>
<presence>%(presence)s</presence>
<details>%(details)s</details>
</caps>"""
ELEMENT_TEMPLATE = """<element>
<name>%(name)s</name>
<longname>%(longname)s</longname>
<class>%(class)s</class>
<description>%(description)s</description>
<author>%(author)s</author>
<pads>
%(pads)s
</pads>
</element>"""
PLUGIN_TEMPLATE = """<plugin>
<name>%(name)s</name>
<description>%(description)s</description>
<filename>%(filename)s</filename>
<basename>%(basename)s</basename>
<version>%(version)s</version>
<license>%(license)s</license>
<source>%(source)s</source>
<package>%(package)s</package>
<origin>%(origin)s</origin>
<elements>
%(elements)s
</elements>
</plugin>"""
def xmlencode(line):
"""
Replace &, <, and >
"""
line = "&amp;".join(line.split("&"))
line = "&lt;".join(line.split("<"))
line = "&gt;".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()

1660
common/gst.supp Normal file

File diff suppressed because it is too large Load diff

1562
common/gstdoc-scangobj Executable file

File diff suppressed because it is too large Load diff

358
common/gtk-doc-plugins.mak Normal file
View file

@ -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

260
common/gtk-doc.mak Normal file
View file

@ -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

28
common/m4/Makefile.am Normal file
View file

@ -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

3
common/m4/README Normal file
View file

@ -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.

43
common/m4/as-ac-expand.m4 Normal file
View file

@ -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
])

50
common/m4/as-auto-alt.m4 Normal file
View file

@ -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])
])
])

View file

@ -0,0 +1,33 @@
dnl as-compiler-flag.m4 0.1.0
dnl autostars m4 macro for detection of compiler flags
dnl David Schleef <ds@schleef.org>
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])
])

44
common/m4/as-compiler.m4 Normal file
View file

@ -0,0 +1,44 @@
dnl as-compiler.m4 0.1.0
dnl autostars m4 macro for detection of compiler flavor
dnl Thomas Vander Stichele <thomas at apestaart dot org>
dnl $Id: as-compiler.m4,v 1.4 2004/06/01 09:33:45 thomasvs Exp $
dnl AS_COMPILER(COMPILER)
dnl will set variable COMPILER to
dnl - gcc
dnl - forte
dnl - (empty) if no guess could be made
AC_DEFUN([AS_COMPILER],
[
as_compiler=
AC_MSG_CHECKING(for compiler flavour)
dnl is it gcc ?
if test "x$GCC" = "xyes"; then
as_compiler="gcc"
fi
dnl is it forte ?
AC_TRY_RUN([
int main
(int argc, char *argv[])
{
#ifdef __sun
return 0;
#else
return 1;
#endif
}
], as_compiler="forte", ,)
if test "x$as_compiler" = "x"; then
AC_MSG_RESULT([unknown !])
else
AC_MSG_RESULT($as_compiler)
fi
[$1]=$as_compiler
])

66
common/m4/as-docbook.m4 Normal file
View file

@ -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='<!--'
CAT_ENTRY_END='-->'
fi
dnl We need xsltproc to process the test
AC_CHECK_PROG(XSLTPROC,xsltproc,xsltproc,)
XSLTPROC_WORKS=no
if test -n "$XSLTPROC"; then
AC_MSG_CHECKING([whether xsltproc docbook processing works])
if test -n "$XML_CATALOG"; then
DB_FILE="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"
else
DB_FILE="$DOCBOOK_ROOT/docbook.xsl"
fi
$XSLTPROC $XSLTPROC_FLAGS $DB_FILE >/dev/null 2>&1 << END
<?xml version="1.0" encoding='ISO-8859-1'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook $TYPE_UC V$DOCBOOK_VERSION//EN" "http://www.oasis-open.org/docbook/$TYPE_LC/$DOCBOOK_VERSION/docbookx.dtd">
<book id="test">
</book>
END
if test "$?" = 0; then
XSLTPROC_WORKS=yes
fi
AC_MSG_RESULT($XSLTPROC_WORKS)
fi
if test "x$XSLTPROC_WORKS" = "xyes"; then
dnl execute ACTION-IF-FOUND
ifelse([$1], , :, [$1])
else
dnl execute ACTION-IF-NOT-FOUND
ifelse([$2], , :, [$2])
fi
AC_SUBST(XML_CATALOG)
AC_SUBST(XSLTPROC_FLAGS)
AC_SUBST(DOCBOOK_ROOT)
AC_SUBST(CAT_ENTRY_START)
AC_SUBST(CAT_ENTRY_END)
])

View file

@ -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
])

45
common/m4/as-libtool.m4 Normal file
View file

@ -0,0 +1,45 @@
dnl as-libtool.m4 0.1.4
dnl autostars m4 macro for libtool versioning
dnl Thomas Vander Stichele <thomas at apestaart dot org>
dnl $Id: as-libtool.m4,v 1.6 2004/06/01 10:04:44 thomasvs Exp $
dnl AS_LIBTOOL(PREFIX, CURRENT, REVISION, AGE, [RELEASE])
dnl example
dnl AS_LIBTOOL(GST, 2, 0, 0)
dnl this macro
dnl - defines [$PREFIX]_CURRENT, REVISION and AGE
dnl - defines [$PREFIX]_LIBVERSION
dnl - defines [$PREFIX]_LT_LDFLAGS to set versioning
dnl - AC_SUBST's them all
dnl if RELEASE is given, then add a -release option to the LDFLAGS
dnl with the given release version
dnl then use [$PREFIX]_LT_LDFLAGS in the relevant Makefile.am's
dnl call AM_PROG_LIBTOOL after this call
AC_DEFUN([AS_LIBTOOL],
[
[$1]_CURRENT=[$2]
[$1]_REVISION=[$3]
[$1]_AGE=[$4]
[$1]_LIBVERSION=[$2]:[$3]:[$4]
AC_SUBST([$1]_CURRENT)
AC_SUBST([$1]_REVISION)
AC_SUBST([$1]_AGE)
AC_SUBST([$1]_LIBVERSION)
[$1]_LT_LDFLAGS="$[$1]_LT_LDFLAGS -version-info $[$1]_LIBVERSION"
if test ! -z "[$5]"
then
[$1]_LT_LDFLAGS="$[$1]_LT_LDFLAGS -release [$5]"
fi
AC_SUBST([$1]_LT_LDFLAGS)
AC_LIBTOOL_DLOPEN
])

152
common/m4/as-python.m4 Normal file
View file

@ -0,0 +1,152 @@
## ------------------------
## Python file handling
## From Andrew Dalke
## Updated by James Henstridge
## Updated by Andy Wingo to loop through possible pythons
## ------------------------
# AS_PATH_PYTHON([MINIMUM-VERSION])
# Adds support for distributing Python modules and packages. To
# install modules, copy them to $(pythondir), using the python_PYTHON
# automake variable. To install a package with the same name as the
# automake package, install to $(pkgpythondir), or use the
# pkgpython_PYTHON automake variable.
# The variables $(pyexecdir) and $(pkgpyexecdir) are provided as
# locations to install python extension modules (shared libraries).
# Another macro is required to find the appropriate flags to compile
# extension modules.
# If your package is configured with a different prefix to python,
# users will have to add the install directory to the PYTHONPATH
# environment variable, or create a .pth file (see the python
# documentation for details).
# If the MINIMUM-VERSION argument is passed, AS_PATH_PYTHON will
# cause an error if the version of python installed on the system
# doesn't meet the requirement. MINIMUM-VERSION should consist of
# numbers and dots only.
# Updated to loop over all possible python binaries by Andy Wingo
# <wingo@pobox.com>
# Updated to only warn and unset PYTHON if no good one is found
AC_DEFUN([AS_PATH_PYTHON],
[
dnl Find a version of Python. I could check for python versions 1.4
dnl or earlier, but the default installation locations changed from
dnl $prefix/lib/site-python in 1.4 to $prefix/lib/python1.5/site-packages
dnl in 1.5, and I don't want to maintain that logic.
dnl should we do the version check?
PYTHON_CANDIDATES="python python2.2 python2.1 python2.0 python2 \
python1.6 python1.5"
ifelse([$1],[],
[AC_PATH_PROG(PYTHON, $PYTHON_CANDIDATES)],
[
AC_MSG_NOTICE(Looking for Python version >= $1)
changequote(<<, >>)dnl
prog="
import sys, string
minver = '$1'
# split string by '.' and convert to numeric
minver_info = map(string.atoi, string.split(minver, '.'))
# we can now do comparisons on the two lists:
if sys.version_info >= tuple(minver_info):
sys.exit(0)
else:
sys.exit(1)"
changequote([, ])dnl
python_good=false
for python_candidate in $PYTHON_CANDIDATES; do
unset PYTHON
AC_PATH_PROG(PYTHON, $python_candidate) 1> /dev/null 2> /dev/null
if test "x$PYTHON" = "x"; then continue; fi
if $PYTHON -c "$prog" 1>&AC_FD_CC 2>&AC_FD_CC; then
AC_MSG_CHECKING(["$PYTHON":])
AC_MSG_RESULT([okay])
python_good=true
break;
else
dnl clear the cache val
unset ac_cv_path_PYTHON
fi
done
])
if test "$python_good" != "true"; then
AC_MSG_WARN([No suitable version of python found])
PYTHON=
else
AC_MSG_CHECKING([local Python configuration])
dnl Query Python for its version number. Getting [:3] seems to be
dnl the best way to do this; it's what "site.py" does in the standard
dnl library. Need to change quote character because of [:3]
AC_SUBST(PYTHON_VERSION)
changequote(<<, >>)dnl
PYTHON_VERSION=`$PYTHON -c "import sys; print sys.version[:3]"`
changequote([, ])dnl
dnl Use the values of $prefix and $exec_prefix for the corresponding
dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made
dnl distinct variables so they can be overridden if need be. However,
dnl general consensus is that you shouldn't need this ability.
AC_SUBST(PYTHON_PREFIX)
PYTHON_PREFIX='${prefix}'
AC_SUBST(PYTHON_EXEC_PREFIX)
PYTHON_EXEC_PREFIX='${exec_prefix}'
dnl At times (like when building shared libraries) you may want
dnl to know which OS platform Python thinks this is.
AC_SUBST(PYTHON_PLATFORM)
PYTHON_PLATFORM=`$PYTHON -c "import sys; print sys.platform"`
dnl Set up 4 directories:
dnl pythondir -- where to install python scripts. This is the
dnl site-packages directory, not the python standard library
dnl directory like in previous automake betas. This behaviour
dnl is more consistent with lispdir.m4 for example.
dnl
dnl Also, if the package prefix isn't the same as python's prefix,
dnl then the old $(pythondir) was pretty useless.
AC_SUBST(pythondir)
pythondir=$PYTHON_PREFIX"/lib/python"$PYTHON_VERSION/site-packages
dnl pkgpythondir -- $PACKAGE directory under pythondir. Was
dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is
dnl more consistent with the rest of automake.
dnl Maybe this should be put in python.am?
AC_SUBST(pkgpythondir)
pkgpythondir=\${pythondir}/$PACKAGE
dnl pyexecdir -- directory for installing python extension modules
dnl (shared libraries) Was PYTHON_SITE_EXEC in previous betas.
AC_SUBST(pyexecdir)
pyexecdir=$PYTHON_EXEC_PREFIX"/lib/python"$PYTHON_VERSION/site-packages
dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE)
dnl Maybe this should be put in python.am?
AC_SUBST(pkgpyexecdir)
pkgpyexecdir=\${pyexecdir}/$PACKAGE
AC_MSG_RESULT([looks good])
fi
])

View file

@ -0,0 +1,36 @@
dnl as-scrub-include.m4 0.0.4
dnl autostars m4 macro for scrubbing CFLAGS of system include dirs
dnl because gcc 3.x complains about including system including dirs
dnl Thomas Vander Stichele <thomas at apestaart dot org>
dnl $Id: as-scrub-include.m4,v 1.5 2004/06/12 08:19:09 thomasvs Exp $
dnl This macro uses output of cpp -v and expects it to contain text that
dnl looks a little bit like this:
dnl #include <...> search starts here:
dnl /usr/local/include
dnl /usr/lib/gcc-lib/i386-redhat-linux/3.2/include
dnl /usr/include
dnl End of search list.
dnl AS_SCRUB_INCLUDE(VAR)
dnl example
dnl AS_SCRUB_INCLUDE(CFLAGS)
dnl will remove all system include dirs from the given CFLAGS
AC_DEFUN([AS_SCRUB_INCLUDE],
[
GIVEN_CFLAGS=$[$1]
INCLUDE_DIRS=`echo | cpp -v 2>&1`
dnl remove everything from this output between the "starts here" and "End of"
dnl line
INCLUDE_DIRS=`echo $INCLUDE_DIRS | sed -e 's/.*<...> search starts here://' | sed -e 's/End of search list.*//'`
for dir in $INCLUDE_DIRS; do
dnl use "" as the sed script so $dir gets expanded
GIVEN_CFLAGS=`echo $GIVEN_CFLAGS | sed -e "s#-I$dir ##"`
done
[$1]=$GIVEN_CFLAGS
])

71
common/m4/as-version.m4 Normal file
View file

@ -0,0 +1,71 @@
dnl as-version.m4 0.2.0
dnl autostars m4 macro for versioning
dnl Thomas Vander Stichele <thomas at apestaart dot org>
dnl $Id: as-version.m4,v 1.4 2004/06/01 09:40:05 thomasvs Exp $
dnl AS_VERSION
dnl example
dnl AS_VERSION
dnl this macro
dnl - AC_SUBST's PACKAGE_VERSION_MAJOR, _MINOR, _MICRO
dnl - AC_SUBST's PACKAGE_VERSION_RELEASE,
dnl which can be used for rpm release fields
dnl - doesn't call AM_INIT_AUTOMAKE anymore because it prevents
dnl maintainer mode from running correctly
dnl
dnl don't forget to put #undef PACKAGE_VERSION_RELEASE in acconfig.h
dnl if you use acconfig.h
AC_DEFUN([AS_VERSION],
[
PACKAGE_VERSION_MAJOR=$(echo AC_PACKAGE_VERSION | cut -d'.' -f1)
PACKAGE_VERSION_MINOR=$(echo AC_PACKAGE_VERSION | cut -d'.' -f2)
PACKAGE_VERSION_MICRO=$(echo AC_PACKAGE_VERSION | cut -d'.' -f3)
AC_SUBST(PACKAGE_VERSION_MAJOR)
AC_SUBST(PACKAGE_VERSION_MINOR)
AC_SUBST(PACKAGE_VERSION_MICRO)
])
dnl AS_NANO(ACTION-IF-NO-NANO, [ACTION-IF-NANO])
dnl requires AC_INIT to be called before
dnl For projects using a fourth or nano number in your versioning to indicate
dnl development or prerelease snapshots, this macro allows the build to be
dnl set up differently accordingly.
dnl this macro:
dnl - parses AC_PACKAGE_VERSION, set by AC_INIT, and extracts the nano number
dnl - sets the variable PACKAGE_VERSION_NANO
dnl - sets the variable PACKAGE_VERSION_RELEASE, which can be used
dnl for rpm release fields
dnl - executes ACTION-IF-NO-NANO or ACTION-IF-NANO
dnl example:
dnl AS_NANO(RELEASE="yes", RELEASE="no")
AC_DEFUN([AS_NANO],
[
AC_MSG_CHECKING(nano version)
NANO=$(echo AC_PACKAGE_VERSION | cut -d'.' -f4)
if test x"$NANO" = x || test "x$NANO" = "x0" ; then
AC_MSG_RESULT([0 (release)])
NANO=0
PACKAGE_VERSION_RELEASE=1
ifelse([$1], , :, [$1])
else
AC_MSG_RESULT($NANO)
PACKAGE_VERSION_RELEASE=0.`date +%Y%m%d.%H%M%S`
ifelse([$2], , :, [$2])
fi
PACKAGE_VERSION_NANO=$NANO
AC_SUBST(PACKAGE_VERSION_NANO)
AC_SUBST(PACKAGE_VERSION_RELEASE)
])

View file

@ -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 <stdint.h>" section requires the
dnl existence of an include file <stdint.h> 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 <inttypes.h>. In other enviroments
dnl we can use the inet-types in <sys/types.h> 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 <stdint.h>"
dnl or "#include <inttypes.h>", 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 <mylib-int.h>" to obtain the stdint-types.
dnl
dnl Remember, if the system already had a valid <stdint.h>, 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 <guidod@gmx.de>
AC_DEFUN([AX_CREATE_STDINT_H],
[# ------ AX CREATE STDINT H -------------------------------------
AC_MSG_CHECKING([for stdint types])
ac_stdint_h=`echo ifelse($1, , _stdint.h, $1)`
# try to shortcircuit - if the default include path of the compiler
# can find a "stdint.h" header then we assume that all compilers can.
AC_CACHE_VAL([ac_cv_header_stdint_t],[
old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS=""
old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS=""
old_CFLAGS="$CFLAGS" ; CFLAGS=""
AC_TRY_COMPILE([#include <stdint.h>],[int_least32_t v = 0;],
[ac_cv_stdint_result="(assuming C99 compatible system)"
ac_cv_header_stdint_t="stdint.h"; ],
[ac_cv_header_stdint_t=""])
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 <<STDINT_EOF
/* ................... shortcircuit part ........................... */
#if defined HAVE_STDINT_H || defined _STDINT_HAVE_STDINT_H
#include <stdint.h>
#else
#include <stddef.h>
/* .................... configured part ............................ */
STDINT_EOF
echo "/* whether we have a C99 compatible stdint header file */" >>$ac_stdint
if test "_$ac_cv_header_stdint_x" != "_" ; then
ac_header="$ac_cv_header_stdint_x"
echo "#define _STDINT_HEADER_INTPTR" '"'"$ac_header"'"' >>$ac_stdint
else
echo "/* #undef _STDINT_HEADER_INTPTR */" >>$ac_stdint
fi
echo "/* whether we have a C96 compatible inttypes header file */" >>$ac_stdint
if test "_$ac_cv_header_stdint_o" != "_" ; then
ac_header="$ac_cv_header_stdint_o"
echo "#define _STDINT_HEADER_UINT32" '"'"$ac_header"'"' >>$ac_stdint
else
echo "/* #undef _STDINT_HEADER_UINT32 */" >>$ac_stdint
fi
echo "/* whether we have a BSD compatible inet types header */" >>$ac_stdint
if test "_$ac_cv_header_stdint_u" != "_" ; then
ac_header="$ac_cv_header_stdint_u"
echo "#define _STDINT_HEADER_U_INT32" '"'"$ac_header"'"' >>$ac_stdint
else
echo "/* #undef _STDINT_HEADER_U_INT32 */" >>$ac_stdint
fi
echo "" >>$ac_stdint
if test "_$ac_header" != "_" ; then if test "$ac_header" != "stddef.h" ; then
echo "#include <$ac_header>" >>$ac_stdint
echo "" >>$ac_stdint
fi fi
echo "/* which 64bit typedef has been found */" >>$ac_stdint
if test "$ac_cv_type_uint64_t" = "yes" ; then
echo "#define _STDINT_HAVE_UINT64_T" "1" >>$ac_stdint
else
echo "/* #undef _STDINT_HAVE_UINT64_T */" >>$ac_stdint
fi
if test "$ac_cv_type_u_int64_t" = "yes" ; then
echo "#define _STDINT_HAVE_U_INT64_T" "1" >>$ac_stdint
else
echo "/* #undef _STDINT_HAVE_U_INT64_T */" >>$ac_stdint
fi
echo "" >>$ac_stdint
echo "/* which type model has been detected */" >>$ac_stdint
if test "_$ac_cv_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 <<STDINT_EOF
/* .................... detections part ............................ */
/* whether we need to define bitspecific types from compiler base types */
#ifndef _STDINT_HEADER_INTPTR
#ifndef _STDINT_HEADER_UINT32
#ifndef _STDINT_HEADER_U_INT32
#define _STDINT_NEED_INT_MODEL_T
#else
#define _STDINT_HAVE_U_INT_TYPES
#endif
#endif
#endif
#ifdef _STDINT_HAVE_U_INT_TYPES
#undef _STDINT_NEED_INT_MODEL_T
#endif
#ifdef _STDINT_CHAR_MODEL
#if _STDINT_CHAR_MODEL+0 == 122 || _STDINT_CHAR_MODEL+0 == 124
#ifndef _STDINT_BYTE_MODEL
#define _STDINT_BYTE_MODEL 12
#endif
#endif
#endif
#ifndef _STDINT_HAVE_INT_LEAST32_T
#define _STDINT_NEED_INT_LEAST_T
#endif
#ifndef _STDINT_HAVE_INT_FAST32_T
#define _STDINT_NEED_INT_FAST_T
#endif
#ifndef _STDINT_HEADER_INTPTR
#define _STDINT_NEED_INTPTR_T
#ifndef _STDINT_HAVE_INTMAX_T
#define _STDINT_NEED_INTMAX_T
#endif
#endif
/* .................... definition part ............................ */
/* some system headers have good uint64_t */
#ifndef _HAVE_UINT64_T
#if defined _STDINT_HAVE_UINT64_T || defined HAVE_UINT64_T
#define _HAVE_UINT64_T
#elif defined _STDINT_HAVE_U_INT64_T || defined HAVE_U_INT64_T
#define _HAVE_UINT64_T
typedef u_int64_t uint64_t;
#endif
#endif
#ifndef _HAVE_UINT64_T
/* .. here are some common heuristics using compiler runtime specifics */
#if defined __STDC_VERSION__ && defined __STDC_VERSION__ >= 199901L
#define _HAVE_UINT64_T
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"
])
])

181
common/m4/check.m4 Normal file
View file

@ -0,0 +1,181 @@
dnl _AM_TRY_CHECK(MINIMUM-VERSION, EXTRA-CFLAGS, EXTRA-LIBS, CHECK-LIB-NAME
dnl [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
dnl Test for check, and define CHECK_CFLAGS and CHECK_LIBS
dnl Done this way because of the brokenness that is
dnl https://launchpad.net/distros/ubuntu/+source/check/+bug/5840
dnl
AC_DEFUN([_AM_TRY_CHECK],
[
min_check_version=$1
extra_cflags=$2
extra_libs=$3
check_lib_name=$4
CHECK_CFLAGS="$extra_cflags"
CHECK_LIBS="$extra_libs -l$check_lib_name"
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $CHECK_CFLAGS"
LIBS="$CHECK_LIBS $LIBS"
AC_MSG_CHECKING(for check named $check_lib_name - version >= $min_check_version)
rm -f conf.check-test
dnl unset no_check, since in our second run it would have been set to yes
dnl before
no_check=
AC_TRY_RUN([
#include <stdio.h>
#include <stdlib.h>
#include <check.h>
int main ()
{
int major, minor, micro;
char *tmp_version;
system ("touch conf.check-test");
/* HP/UX 9 (%@#!) writes to sscanf strings */
tmp_version = strdup("$min_check_version");
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
printf("%s, bad version string\n", "$min_check_version");
return 1;
}
if ((CHECK_MAJOR_VERSION != check_major_version) ||
(CHECK_MINOR_VERSION != check_minor_version) ||
(CHECK_MICRO_VERSION != check_micro_version))
{
printf("\n*** The check header file (version %d.%d.%d) does not match\n",
CHECK_MAJOR_VERSION, CHECK_MINOR_VERSION, CHECK_MICRO_VERSION);
printf("*** the check library (version %d.%d.%d).\n",
check_major_version, check_minor_version, check_micro_version);
return 1;
}
if ((check_major_version > major) ||
((check_major_version == major) && (check_minor_version > minor)) ||
((check_major_version == major) && (check_minor_version == minor) && (check_micro_version >= micro)))
{
return 0;
}
else
{
printf("\n*** An old version of check (%d.%d.%d) was found.\n",
check_major_version, check_minor_version, check_micro_version);
printf("*** You need a version of check being at least %d.%d.%d.\n", major, minor, micro);
printf("***\n");
printf("*** If you have already installed a sufficiently new version, this error\n");
printf("*** probably means that the wrong copy of the check library and header\n");
printf("*** file is being found. Rerun configure with the --with-check=PATH option\n");
printf("*** to specify the prefix where the correct version was installed.\n");
}
return 1;
}
],, no_check=yes, [echo $ac_n "cross compiling; assumed OK... $ac_c"])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
if test "x$no_check" = x ; then
AC_MSG_RESULT(yes)
ifelse([$5], , :, [$5])
else
AC_MSG_RESULT(no)
if test -f conf.check-test ; then
:
else
echo "*** Could not run check test program, checking why..."
CFLAGS="$CFLAGS $CHECK_CFLAGS"
LIBS="$CHECK_LIBS $LIBS"
AC_TRY_LINK([
#include <stdio.h>
#include <stdlib.h>
#include <check.h>
], , [ echo "*** The test program compiled, but did not run. This usually means"
echo "*** that the run-time linker is not finding check. You'll need to set your"
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
echo "*** to the installed location Also, make sure you have run ldconfig if that"
echo "*** is required on your system"
echo "***"
echo "*** If you have an old version installed, it is best to remove it, although"
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
[ echo "*** The test program failed to compile or link. See the file config.log for"
echo "*** the exact error that occured." ])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
CHECK_CFLAGS=""
CHECK_LIBS=""
rm -f conf.check-test
ifelse([$6], , AC_MSG_ERROR([check not found]), [$6])
fi
])
dnl AM_PATH_CHECK([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
dnl Test for check, and define CHECK_CFLAGS and CHECK_LIBS
dnl
AC_DEFUN([AM_PATH_CHECK],
[
AC_ARG_WITH(check,
[ --with-check=PATH prefix where check is installed [default=auto]])
AC_ARG_WITH(checklibname,
AC_HELP_STRING([--with-check-lib-name=NAME],
[name of the PIC check library (default=check)]))
min_check_version=ifelse([$1], ,0.8.2,$1)
if test x$with_check = xno; then
AC_MSG_RESULT(disabled)
ifelse([$3], , AC_MSG_ERROR([disabling check is not supported]), [$3])
else
if test "x$with_check" != x; then
CHECK_EXTRA_CFLAGS="-I$with_check/include"
CHECK_EXTRA_LIBS="-L$with_check/lib"
else
CHECK_EXTRA_CFLAGS=""
CHECK_EXTRA_LIBS=""
fi
if test x$with_checklibname = x; then
_AM_TRY_CHECK($min_check_version, $CHECK_EXTRA_CFLAGS, $CHECK_EXTRA_LIBS,
check_pic, [have_check=true], [have_check=false])
if test x$have_check = xtrue; then
ifelse([$2], , :, [$2])
else
_AM_TRY_CHECK($min_check_version, $CHECK_EXTRA_CFLAGS, $CHECK_EXTRA_LIBS,
check, [have_check=true], [have_check=false])
if test x$have_check = xtrue; then
ifelse([$2], , :, [$2])
else
ifelse([$3], , AC_MSG_ERROR([check not found]), [$3])
fi
fi
else
_AM_TRY_CHECK($min_check_version, $CHECK_EXTRA_CFLAGS, $CHECK_EXTRA_LIBS,
$with_checklibname, [have_check=true], [have_check=false])
if test x$have_check = xtrue; then
ifelse([$2], , :, [$2])
else
ifelse([$3], , AC_MSG_ERROR([check not found]), [$3])
fi
fi
AC_SUBST(CHECK_CFLAGS)
AC_SUBST(CHECK_LIBS)
rm -f conf.check-test
fi
])

380
common/m4/glib-gettext.m4 Normal file
View file

@ -0,0 +1,380 @@
# Copyright (C) 1995-2002 Free Software Foundation, Inc.
# Copyright (C) 2001-2003 Red Hat, Inc.
#
# This file is free software, distributed under the terms of the GNU
# General Public License. As a special exception to the GNU General
# Public License, this file may be distributed as part of a program
# that contains a configuration script generated by Autoconf, under
# the same distribution terms as the rest of that program.
#
# This file can be copied and used freely without restrictions. It can
# be used in projects which are not available under the GNU Public License
# but which still want to provide support for the GNU gettext functionality.
#
# Macro to add for using GNU gettext.
# Ulrich Drepper <drepper@cygnus.com>, 1995, 1996
#
# Modified to never use included libintl.
# Owen Taylor <otaylor@redhat.com>, 12/15/1998
#
# Major rework to remove unused code
# Owen Taylor <otaylor@redhat.com>, 12/11/2002
#
# Added better handling of ALL_LINGUAS from GNU gettext version
# written by Bruno Haible, Owen Taylor <otaylor.redhat.com> 5/30/3002
#
# We need this here as well, since someone might use autoconf-2.5x
# to configure GLib then an older version to configure a package
# using AM_GLIB_GNU_GETTEXT
AC_PREREQ(2.53)
dnl
dnl We go to great lengths to make sure that aclocal won't
dnl try to pull in the installed version of these macros
dnl when running aclocal in the glib directory.
dnl
m4_copy([AC_DEFUN],[glib_DEFUN])
m4_copy([AC_REQUIRE],[glib_REQUIRE])
dnl
dnl At the end, if we're not within glib, we'll define the public
dnl definitions in terms of our private definitions.
dnl
# GLIB_LC_MESSAGES
#--------------------
glib_DEFUN([GLIB_LC_MESSAGES],
[AC_CHECK_HEADERS([locale.h])
if test $ac_cv_header_locale_h = yes; then
AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
[AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
if test $am_cv_val_LC_MESSAGES = yes; then
AC_DEFINE(HAVE_LC_MESSAGES, 1,
[Define if your <locale.h> file defines LC_MESSAGES.])
fi
fi])
# GLIB_PATH_PROG_WITH_TEST
#----------------------------
dnl GLIB_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
glib_DEFUN([GLIB_PATH_PROG_WITH_TEST],
[# Extract the first word of "$2", so it can be a program name with args.
set dummy $2; ac_word=[$]2
AC_MSG_CHECKING([for $ac_word])
AC_CACHE_VAL(ac_cv_path_$1,
[case "[$]$1" in
/*)
ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
;;
*)
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
for ac_dir in ifelse([$5], , $PATH, [$5]); do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
if [$3]; then
ac_cv_path_$1="$ac_dir/$ac_word"
break
fi
fi
done
IFS="$ac_save_ifs"
dnl If no 4th arg is given, leave the cache variable unset,
dnl so AC_PATH_PROGS will keep looking.
ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
])dnl
;;
esac])dnl
$1="$ac_cv_path_$1"
if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
AC_MSG_RESULT([$]$1)
else
AC_MSG_RESULT(no)
fi
AC_SUBST($1)dnl
])
# GLIB_WITH_NLS
#-----------------
glib_DEFUN([GLIB_WITH_NLS],
dnl NLS is obligatory
[USE_NLS=yes
AC_SUBST(USE_NLS)
gt_cv_have_gettext=no
CATOBJEXT=NONE
XGETTEXT=:
INTLLIBS=
AC_CHECK_HEADER(libintl.h,
[gt_cv_func_dgettext_libintl="no"
libintl_extra_libs=""
#
# First check in libc
#
AC_CACHE_CHECK([for dgettext in libc], gt_cv_func_dgettext_libc,
[AC_TRY_LINK([
#include <libintl.h>
],
[return (int) dgettext ("","")],
gt_cv_func_dgettext_libc=yes,
gt_cv_func_dgettext_libc=no)
])
if test "$gt_cv_func_dgettext_libc" = "yes" ; then
AC_CHECK_FUNCS(bind_textdomain_codeset)
fi
#
# If we don't have everything we want, check in libintl
#
if test "$gt_cv_func_dgettext_libc" != "yes" \
|| test "$ac_cv_func_bind_textdomain_codeset" != "yes" ; then
AC_CHECK_LIB(intl, bindtextdomain,
[AC_CHECK_LIB(intl, dgettext,
gt_cv_func_dgettext_libintl=yes)])
if test "$gt_cv_func_dgettext_libintl" != "yes" ; then
AC_MSG_CHECKING([if -liconv is needed to use gettext])
AC_MSG_RESULT([])
AC_CHECK_LIB(intl, dcgettext,
[gt_cv_func_dgettext_libintl=yes
libintl_extra_libs=-liconv],
:,-liconv)
fi
#
# If we found libintl, then check in it for bind_textdomain_codeset();
# we'll prefer libc if neither have bind_textdomain_codeset(),
# and both have dgettext
#
if test "$gt_cv_func_dgettext_libintl" = "yes" ; then
glib_save_LIBS="$LIBS"
LIBS="$LIBS -lintl $libintl_extra_libs"
unset ac_cv_func_bind_textdomain_codeset
AC_CHECK_FUNCS(bind_textdomain_codeset)
LIBS="$glib_save_LIBS"
if test "$ac_cv_func_bind_textdomain_codeset" = "yes" ; then
gt_cv_func_dgettext_libc=no
else
if test "$gt_cv_func_dgettext_libc" = "yes"; then
gt_cv_func_dgettext_libintl=no
fi
fi
fi
fi
if test "$gt_cv_func_dgettext_libc" = "yes" \
|| test "$gt_cv_func_dgettext_libintl" = "yes"; then
gt_cv_have_gettext=yes
fi
if test "$gt_cv_func_dgettext_libintl" = "yes"; then
INTLLIBS="-lintl $libintl_extra_libs"
fi
if test "$gt_cv_have_gettext" = "yes"; then
AC_DEFINE(HAVE_GETTEXT,1,
[Define if the GNU gettext() function is already present or preinstalled.])
GLIB_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
[test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
if test "$MSGFMT" != "no"; then
glib_save_LIBS="$LIBS"
LIBS="$LIBS $INTLLIBS"
AC_CHECK_FUNCS(dcgettext)
AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
GLIB_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
[test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
return _nl_msg_cat_cntr],
[CATOBJEXT=.gmo
DATADIRNAME=share],
[case $host in
*-*-solaris*)
dnl On Solaris, if bind_textdomain_codeset is in libc,
dnl GNU format message catalog is always supported,
dnl since both are added to the libc all together.
dnl Hence, we'd like to go with DATADIRNAME=share and
dnl and CATOBJEXT=.gmo in this case.
AC_CHECK_FUNC(bind_textdomain_codeset,
[CATOBJEXT=.gmo
DATADIRNAME=share],
[CATOBJEXT=.mo
DATADIRNAME=lib])
;;
*)
CATOBJEXT=.mo
DATADIRNAME=lib
;;
esac])
LIBS="$glib_save_LIBS"
INSTOBJEXT=.mo
else
gt_cv_have_gettext=no
fi
fi
])
if test "$gt_cv_have_gettext" = "yes" ; then
AC_DEFINE(ENABLE_NLS, 1,
[always defined to indicate that i18n is enabled])
fi
dnl Test whether we really found GNU xgettext.
if test "$XGETTEXT" != ":"; then
dnl If it is not GNU xgettext we define it as : so that the
dnl Makefiles still can work.
if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
: ;
else
AC_MSG_RESULT(
[found xgettext program is not GNU xgettext; ignore it])
XGETTEXT=":"
fi
fi
# We need to process the po/ directory.
POSUB=po
AC_OUTPUT_COMMANDS(
[case "$CONFIG_FILES" in *po/Makefile.in*)
sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
esac])
dnl These rules are solely for the distribution goal. While doing this
dnl we only have to keep exactly one list of the available catalogs
dnl in configure.in.
for lang in $ALL_LINGUAS; do
GMOFILES="$GMOFILES $lang.gmo"
POFILES="$POFILES $lang.po"
done
dnl Make all variables we use known to autoconf.
AC_SUBST(CATALOGS)
AC_SUBST(CATOBJEXT)
AC_SUBST(DATADIRNAME)
AC_SUBST(GMOFILES)
AC_SUBST(INSTOBJEXT)
AC_SUBST(INTLLIBS)
AC_SUBST(PO_IN_DATADIR_TRUE)
AC_SUBST(PO_IN_DATADIR_FALSE)
AC_SUBST(POFILES)
AC_SUBST(POSUB)
])
# AM_GLIB_GNU_GETTEXT
# -------------------
# Do checks necessary for use of gettext. If a suitable implementation
# of gettext is found in either in libintl or in the C library,
# it will set INTLLIBS to the libraries needed for use of gettext
# and AC_DEFINE() HAVE_GETTEXT and ENABLE_NLS. (The shell variable
# gt_cv_have_gettext will be set to "yes".) It will also call AC_SUBST()
# on various variables needed by the Makefile.in.in installed by
# glib-gettextize.
dnl
glib_DEFUN([GLIB_GNU_GETTEXT],
[AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_HEADER_STDC])dnl
GLIB_LC_MESSAGES
GLIB_WITH_NLS
if test "$gt_cv_have_gettext" = "yes"; then
if test "x$ALL_LINGUAS" = "x"; then
LINGUAS=
else
AC_MSG_CHECKING(for catalogs to be installed)
NEW_LINGUAS=
for presentlang in $ALL_LINGUAS; do
useit=no
if test "%UNSET%" != "${LINGUAS-%UNSET%}"; then
desiredlanguages="$LINGUAS"
else
desiredlanguages="$ALL_LINGUAS"
fi
for desiredlang in $desiredlanguages; do
# Use the presentlang catalog if desiredlang is
# a. equal to presentlang, or
# b. a variant of presentlang (because in this case,
# presentlang can be used as a fallback for messages
# which are not translated in the desiredlang catalog).
case "$desiredlang" in
"$presentlang"*) useit=yes;;
esac
done
if test $useit = yes; then
NEW_LINGUAS="$NEW_LINGUAS $presentlang"
fi
done
LINGUAS=$NEW_LINGUAS
AC_MSG_RESULT($LINGUAS)
fi
dnl Construct list of names of catalog files to be constructed.
if test -n "$LINGUAS"; then
for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
fi
fi
dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly
dnl find the mkinstalldirs script in another subdir but ($top_srcdir).
dnl Try to locate is.
MKINSTALLDIRS=
if test -n "$ac_aux_dir"; then
MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs"
fi
if test -z "$MKINSTALLDIRS"; then
MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
fi
AC_SUBST(MKINSTALLDIRS)
dnl Generate list of files to be processed by xgettext which will
dnl be included in po/Makefile.
test -d po || mkdir po
if test "x$srcdir" != "x."; then
if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
posrcprefix="$srcdir/"
else
posrcprefix="../$srcdir/"
fi
else
posrcprefix="../"
fi
rm -f po/POTFILES
sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
< $srcdir/po/POTFILES.in > po/POTFILES
])
# AM_GLIB_DEFINE_LOCALEDIR(VARIABLE)
# -------------------------------
# Define VARIABLE to the location where catalog files will
# be installed by po/Makefile.
glib_DEFUN([GLIB_DEFINE_LOCALEDIR],
[glib_REQUIRE([GLIB_GNU_GETTEXT])dnl
glib_save_prefix="$prefix"
glib_save_exec_prefix="$exec_prefix"
test "x$prefix" = xNONE && prefix=$ac_default_prefix
test "x$exec_prefix" = xNONE && exec_prefix=$prefix
if test "x$CATOBJEXT" = "x.mo" ; then
localedir=`eval echo "${libdir}/locale"`
else
localedir=`eval echo "${datadir}/locale"`
fi
prefix="$glib_save_prefix"
exec_prefix="$glib_save_exec_prefix"
AC_DEFINE_UNQUOTED($1, "$localedir",
[Define the location where the catalogs will be installed])
])
dnl
dnl Now the definitions that aclocal will find
dnl
ifdef(glib_configure_in,[],[
AC_DEFUN([AM_GLIB_GNU_GETTEXT],[GLIB_GNU_GETTEXT($@)])
AC_DEFUN([AM_GLIB_DEFINE_LOCALEDIR],[GLIB_DEFINE_LOCALEDIR($@)])
])dnl

123
common/m4/gst-arch.m4 Normal file
View file

@ -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
])

276
common/m4/gst-args.m4 Normal file
View file

@ -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])
])
])

138
common/m4/gst-check.m4 Normal file
View file

@ -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)
])

View file

@ -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
])

45
common/m4/gst-default.m4 Normal file
View file

@ -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])
])

148
common/m4/gst-doc.m4 Normal file
View file

@ -0,0 +1,148 @@
AC_DEFUN([AG_GST_DOCBOOK_CHECK],
[
dnl choose a location to install docbook docs in
if test "x$PACKAGE_TARNAME" = "x"
then
AC_MSG_ERROR([Internal error - PACKAGE_TARNAME not set])
fi
docdir="\$(datadir)/doc/$PACKAGE_TARNAME-$GST_MAJORMINOR"
dnl enable/disable docbook documentation building
AC_ARG_ENABLE(docbook,
AC_HELP_STRING([--enable-docbook],
[use docbook to build documentation [default=no]]),,
enable_docbook=no)
have_docbook=no
if test x$enable_docbook = xyes; then
dnl check if we actually have everything we need
dnl check for docbook tools
AC_CHECK_PROG(HAVE_DOCBOOK2PS, docbook2ps, yes, no)
AC_CHECK_PROG(HAVE_DOCBOOK2HTML, docbook2html, yes, no)
AC_CHECK_PROG(HAVE_JADETEX, jadetex, yes, no)
AC_CHECK_PROG(HAVE_PS2PDF, ps2pdf, yes, no)
# -V option appeared in 0.6.10
docbook2html_min_version=0.6.10
if test "x$HAVE_DOCBOOK2HTML" != "xno"; then
docbook2html_version=`docbook2html --version`
AC_MSG_CHECKING([docbook2html version ($docbook2html_version) >= $docbook2html_min_version])
if perl -w <<EOF
(\$min_version_major, \$min_version_minor, \$min_version_micro ) = "$docbook2html_min_version" =~ /(\d+)\.(\d+)\.(\d+)/;
(\$docbook2html_version_major, \$docbook2html_version_minor, \$docbook2html_version_micro ) = "$docbook2html_version" =~ /(\d+)\.(\d+)\.(\d+)/;
exit (((\$docbook2html_version_major > \$min_version_major) ||
((\$docbook2html_version_major == \$min_version_major) &&
(\$docbook2html_version_minor >= \$min_version_minor)) ||
((\$docbook2html_version_major == \$min_version_major) &&
(\$docbook2html_version_minor >= \$min_version_minor) &&
(\$docbook2html_version_micro >= \$min_version_micro)))
? 0 : 1);
EOF
then
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
HAVE_DOCBOOK2HTML=no
fi
fi
dnl check if we can process docbook stuff
AS_DOCBOOK(have_docbook=yes, have_docbook=no)
dnl check for extra tools
AC_CHECK_PROG(HAVE_DVIPS, dvips, yes, no)
AC_CHECK_PROG(HAVE_XMLLINT, xmllint, yes, no)
dnl check for image conversion tools
AC_CHECK_PROG(HAVE_FIG2DEV, fig2dev, yes, no)
if test "x$HAVE_FIG2DEV" = "xno" ; then
AC_MSG_WARN([Did not find fig2dev (from xfig), images will not be generated.])
fi
dnl The following is a hack: if fig2dev doesn't display an error message
dnl for the desired type, we assume it supports it.
HAVE_FIG2DEV_EPS=no
if test "x$HAVE_FIG2DEV" = "xyes" ; then
fig2dev_quiet=`fig2dev -L eps </dev/null 2>&1 >/dev/null`
if test "x$fig2dev_quiet" = "x" ; then
HAVE_FIG2DEV_EPS=yes
fi
fi
HAVE_FIG2DEV_PNG=no
if test "x$HAVE_FIG2DEV" = "xyes" ; then
fig2dev_quiet=`fig2dev -L png </dev/null 2>&1 >/dev/null`
if test "x$fig2dev_quiet" = "x" ; then
HAVE_FIG2DEV_PNG=yes
fi
fi
HAVE_FIG2DEV_PDF=no
if test "x$HAVE_FIG2DEV" = "xyes" ; then
fig2dev_quiet=`fig2dev -L pdf </dev/null 2>&1 >/dev/null`
if test "x$fig2dev_quiet" = "x" ; then
HAVE_FIG2DEV_PDF=yes
fi
fi
AC_CHECK_PROG(HAVE_PNGTOPNM, pngtopnm, yes, no)
AC_CHECK_PROG(HAVE_PNMTOPS, pnmtops, yes, no)
AC_CHECK_PROG(HAVE_EPSTOPDF, epstopdf, yes, no)
dnl check if we can generate HTML
if test "x$HAVE_DOCBOOK2HTML" = "xyes" && \
test "x$enable_docbook" = "xyes" && \
test "x$HAVE_XMLLINT" = "xyes" && \
test "x$HAVE_FIG2DEV_PNG" = "xyes"; then
DOC_HTML=yes
AC_MSG_NOTICE(Will output HTML documentation)
else
DOC_HTML=no
AC_MSG_NOTICE(Will not output HTML documentation)
fi
dnl check if we can generate PS
if test "x$HAVE_DOCBOOK2PS" = "xyes" && \
test "x$enable_docbook" = "xyes" && \
test "x$HAVE_XMLLINT" = "xyes" && \
test "x$HAVE_JADETEX" = "xyes" && \
test "x$HAVE_FIG2DEV_EPS" = "xyes" && \
test "x$HAVE_DVIPS" = "xyes" && \
test "x$HAVE_PNGTOPNM" = "xyes" && \
test "x$HAVE_PNMTOPS" = "xyes"; then
DOC_PS=yes
AC_MSG_NOTICE(Will output PS documentation)
else
DOC_PS=no
AC_MSG_NOTICE(Will not output PS documentation)
fi
dnl check if we can generate PDF - using only ps2pdf
if test "x$DOC_PS" = "xyes" && \
test "x$enable_docbook" = "xyes" && \
test "x$HAVE_XMLLINT" = "xyes" && \
test "x$HAVE_PS2PDF" = "xyes"; then
DOC_PDF=yes
AC_MSG_NOTICE(Will output PDF documentation)
else
DOC_PDF=no
AC_MSG_NOTICE(Will not output PDF documentation)
fi
dnl if we don't have everything, we should disable
if test "x$have_docbook" != "xyes"; then
enable_docbook=no
fi
fi
dnl if we're going to install documentation, tell us where
if test "x$have_docbook" = "xyes"; then
AC_MSG_NOTICE(Installing documentation in $docdir)
AC_SUBST(docdir)
fi
AM_CONDITIONAL(ENABLE_DOCBOOK, test x$enable_docbook = xyes)
AM_CONDITIONAL(DOC_HTML, test x$DOC_HTML = xyes)
AM_CONDITIONAL(DOC_PDF, test x$DOC_PDF = xyes)
AM_CONDITIONAL(DOC_PS, test x$DOC_PS = xyes)
])

71
common/m4/gst-error.m4 Normal file
View file

@ -0,0 +1,71 @@
dnl handle various error-related things
dnl Thomas Vander Stichele <thomas@apestaart.org>
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)
])

285
common/m4/gst-feature.m4 Normal file
View file

@ -0,0 +1,285 @@
dnl Perform a check for a feature for GStreamer
dnl Richard Boulton <richard-alsa@tartarus.org>
dnl Thomas Vander Stichele <thomas@apestaart.org> added useful stuff
dnl Last modification: 25/06/2001
dnl AG_GST_CHECK_FEATURE(FEATURE-NAME, FEATURE-DESCRIPTION,
dnl DEPENDENT-PLUGINS, TEST-FOR-FEATURE,
dnl DISABLE-BY-DEFAULT, ACTION-IF-USE, ACTION-IF-NOTUSE)
dnl
dnl This macro adds a command line argument to allow the user to enable
dnl or disable a feature, and if the feature is enabled, performs a supplied
dnl test to check if the feature is available.
dnl
dnl The test should define HAVE_<FEATURE-NAME> to "yes" or "no" depending
dnl on whether the feature is available.
dnl
dnl The macro will set USE_<FEATURE-NAME> to "yes" or "no" depending on
dnl whether the feature is to be used.
dnl Thomas changed this, so that when USE_<FEATURE-NAME> was already set
dnl to no, then it stays that way.
dnl
dnl The macro will call AM_CONDITIONAL(USE_<<FEATURE-NAME>, ...) to allow
dnl the feature to control what is built in Makefile.ams. If you want
dnl additional actions resulting from the test, you can add them with the
dnl ACTION-IF-USE and ACTION-IF-NOTUSE parameters.
dnl
dnl FEATURE-NAME is the name of the feature, and should be in
dnl purely upper case characters.
dnl FEATURE-DESCRIPTION is used to describe the feature in help text for
dnl the command line argument.
dnl DEPENDENT-PLUGINS lists any plug-ins which depend on this feature.
dnl TEST-FOR-FEATURE is a test which sets HAVE_<FEATURE-NAME> to "yes"
dnl or "no" depending on whether the feature is
dnl available.
dnl DISABLE-BY-DEFAULT if "disabled", the feature is disabled by default,
dnl if any other value, the feature is enabled by default.
dnl ACTION-IF-USE any extra actions to perform if the feature is to be
dnl used.
dnl ACTION-IF-NOTUSE any extra actions to perform if the feature is not to
dnl be used.
dnl
dnl
dnl thomas :
dnl we also added a history.
dnl GST_PLUGINS_YES will contain all plugins to be built
dnl that were checked through AG_GST_CHECK_FEATURE
dnl GST_PLUGINS_NO will contain those that won't be built
AC_DEFUN([AG_GST_CHECK_FEATURE],
[echo
AC_MSG_NOTICE(*** checking feature: [$2] ***)
if test "x[$3]" != "x"
then
AC_MSG_NOTICE(*** for plug-ins: [$3] ***)
fi
dnl
builtin(define, [gst_endisable], ifelse($5, [disabled], [enable], [disable]))dnl
dnl if it is set to NO, then don't even consider it for building
NOUSE=
if test "x$USE_[$1]" = "xno"; then
NOUSE="yes"
fi
AC_ARG_ENABLE(translit([$1], A-Z, a-z),
[ ]builtin(format, --%-26s gst_endisable %s, gst_endisable-translit([$1], A-Z, a-z), [$2]ifelse([$3],,,: [$3])),
[ case "${enableval}" in
yes) USE_[$1]=yes;;
no) USE_[$1]=no;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-translit([$1], A-Z, a-z)) ;;
esac],
[ USE_$1=]ifelse($5, [disabled], [no], [yes])) dnl DEFAULT
dnl *** set it back to no if it was preset to no
if test "x$NOUSE" = "xyes"; then
USE_[$1]="no"
AC_MSG_WARN(*** $3 pre-configured not to be built)
fi
NOUSE=
dnl *** If it's enabled
if test x$USE_[$1] = xyes; then
dnl save compile variables before the test
gst_check_save_LIBS=$LIBS
gst_check_save_LDFLAGS=$LDFLAGS
gst_check_save_CFLAGS=$CFLAGS
gst_check_save_CPPFLAGS=$CPPFLAGS
gst_check_save_CXXFLAGS=$CXXFLAGS
HAVE_[$1]=no
dnl TEST_FOR_FEATURE
$4
LIBS=$gst_check_save_LIBS
LDFLAGS=$gst_check_save_LDFLAGS
CFLAGS=$gst_check_save_CFLAGS
CPPFLAGS=$gst_check_save_CPPFLAGS
CXXFLAGS=$gst_check_save_CXXFLAGS
dnl If it isn't found, unset USE_[$1]
if test x$HAVE_[$1] = xno; then
USE_[$1]=no
else
ifelse([$3], , :, [AC_MSG_NOTICE(*** These plugins will be built: [$3])])
fi
fi
dnl *** Warn if it's disabled or not found
if test x$USE_[$1] = xyes; then
ifelse([$6], , :, [$6])
if test "x$3" != "x"; then
GST_PLUGINS_YES="\t[$3]\n$GST_PLUGINS_YES"
fi
AC_DEFINE(HAVE_[$1], , [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 <richard-alsa@tartarus.org>
dnl Last modification: 26/06/2001
dnl AG_GST_CHECK_CONFIGPROG(FEATURE-NAME, CONFIG-PROG-FILENAME, MODULES)
dnl
dnl This check was written for GStreamer: it should be renamed and checked
dnl for portability if you decide to use it elsewhere.
dnl
AC_DEFUN([AG_GST_CHECK_CONFIGPROG],
[
AC_PATH_PROG([$1]_CONFIG, [$2], no)
if test x$[$1]_CONFIG = xno; then
[$1]_LIBS=
[$1]_CFLAGS=
HAVE_[$1]=no
else
if [$2] --plugin-libs [$3] &> /dev/null; then
[$1]_LIBS=`[$2] --plugin-libs [$3]`
else
[$1]_LIBS=`[$2] --libs [$3]`
fi
[$1]_CFLAGS=`[$2] --cflags [$3]`
HAVE_[$1]=yes
fi
AC_SUBST([$1]_LIBS)
AC_SUBST([$1]_CFLAGS)
])
dnl Use AC_CHECK_LIB and AC_CHECK_HEADER to do both tests at once
dnl sets HAVE_module if we have it
dnl Richard Boulton <richard-alsa@tartarus.org>
dnl Last modification: 26/06/2001
dnl AG_GST_CHECK_LIBHEADER(FEATURE-NAME, LIB NAME, LIB FUNCTION, EXTRA LD FLAGS,
dnl HEADER NAME, ACTION-IF-FOUND, ACTION-IF-NOT-FOUND)
dnl
dnl This check was written for GStreamer: it should be renamed and checked
dnl for portability if you decide to use it elsewhere.
dnl
AC_DEFUN([AG_GST_CHECK_LIBHEADER],
[
AC_CHECK_LIB([$2], [$3], HAVE_[$1]=yes, HAVE_[$1]=no,[$4])
if test "x$HAVE_[$1]" = "xyes"; then
AC_CHECK_HEADER([$5], :, HAVE_[$1]=no)
if test "x$HAVE_[$1]" = "xyes"; then
dnl execute what needs to be
ifelse([$6], , :, [$6])
else
ifelse([$7], , :, [$7])
fi
else
ifelse([$7], , :, [$7])
fi
AC_SUBST(HAVE_[$1])
]
)
dnl 2004-02-14 Thomas - changed to get set properly and use proper output
dnl 2003-06-27 Benjamin Otte - changed to make this work with gstconfig.h
dnl
dnl Add a subsystem --disable flag and all the necessary symbols and substitions
dnl
dnl AG_GST_CHECK_SUBSYSTEM_DISABLE(SYSNAME, [subsystem name])
dnl
AC_DEFUN([AG_GST_CHECK_SUBSYSTEM_DISABLE],
[
dnl this define will replace each literal subsys_def occurrence with
dnl the lowercase hyphen-separated subsystem
dnl e.g. if $1 is GST_DEBUG then subsys_def will be a macro with gst-debug
define([subsys_def],translit([$1], _A-Z, -a-z))
AC_ARG_ENABLE(subsys_def,
AC_HELP_STRING(--disable-subsys_def, [disable $2]),
[
case "${enableval}" in
yes) GST_DISABLE_[$1]=no ;;
no) GST_DISABLE_[$1]=yes ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-subsys_def]) ;;
esac
],
[GST_DISABLE_[$1]=no]) dnl Default value
if test x$GST_DISABLE_[$1] = xyes; then
AC_MSG_NOTICE([disabled subsystem [$2]])
GST_DISABLE_[$1]_DEFINE="#define GST_DISABLE_$1 1"
else
GST_DISABLE_[$1]_DEFINE="/* #undef GST_DISABLE_$1 */"
fi
AC_SUBST(GST_DISABLE_[$1]_DEFINE)
undefine([subsys_def])
])
dnl Parse gstconfig.h for feature and defines add the symbols and substitions
dnl
dnl AG_GST_PARSE_SUBSYSTEM_DISABLE(GST_CONFIGPATH, FEATURE)
dnl
AC_DEFUN([AG_GST_PARSE_SUBSYSTEM_DISABLE],
[
grep >/dev/null "#undef GST_DISABLE_$2" $1
if test $? = 0; then
GST_DISABLE_[$2]=0
else
GST_DISABLE_[$2]=1
fi
AC_SUBST(GST_DISABLE_[$2])
])
dnl Parse gstconfig.h and defines add the symbols and substitions
dnl
dnl GST_CONFIGPATH=`$PKG_CONFIG --variable=includedir gstreamer-0.10`"/gst/gstconfig.h"
dnl AG_GST_PARSE_SUBSYSTEM_DISABLES(GST_CONFIGPATH)
dnl
AC_DEFUN([AG_GST_PARSE_SUBSYSTEM_DISABLES],
[
AG_GST_PARSE_SUBSYSTEM_DISABLE($1,GST_DEBUG)
AG_GST_PARSE_SUBSYSTEM_DISABLE($1,LOADSAVE)
AG_GST_PARSE_SUBSYSTEM_DISABLE($1,PARSE)
AG_GST_PARSE_SUBSYSTEM_DISABLE($1,TRACE)
AG_GST_PARSE_SUBSYSTEM_DISABLE($1,ALLOC_TRACE)
AG_GST_PARSE_SUBSYSTEM_DISABLE($1,REGISTRY)
AG_GST_PARSE_SUBSYSTEM_DISABLE($1,ENUMTYPES)
AG_GST_PARSE_SUBSYSTEM_DISABLE($1,INDEX)
AG_GST_PARSE_SUBSYSTEM_DISABLE($1,PLUGIN)
AG_GST_PARSE_SUBSYSTEM_DISABLE($1,URI)
AG_GST_PARSE_SUBSYSTEM_DISABLE($1,XML)
])
dnl relies on GST_PLUGINS_ALL, GST_PLUGINS_SELECTED, GST_PLUGINS_YES,
dnl GST_PLUGINS_NO, and BUILD_EXTERNAL
AC_DEFUN([AG_GST_OUTPUT_PLUGINS], [
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
])

63
common/m4/gst-function.m4 Normal file
View file

@ -0,0 +1,63 @@
dnl
dnl Check for compiler mechanism to show functions in debugging
dnl copied from an Ali patch floating on the internet
dnl
AC_DEFUN([AG_GST_CHECK_FUNCTION],[
dnl #1: __PRETTY_FUNCTION__
AC_MSG_CHECKING(whether $CC implements __PRETTY_FUNCTION__)
AC_CACHE_VAL(have_pretty_function,[
AC_TRY_LINK([#include <stdio.h>],
[printf("%s", __PRETTY_FUNCTION__);],
have_pretty_function=yes,
have_pretty_function=no)
])
AC_MSG_RESULT($have_pretty_function)
if test "$have_pretty_function" = yes; then
AC_DEFINE(HAVE_PRETTY_FUNCTION, 1,
[defined if the compiler implements __PRETTY_FUNCTION__])
fi
dnl #2: __FUNCTION__
AC_MSG_CHECKING(whether $CC implements __FUNCTION__)
AC_CACHE_VAL(have_function,[
AC_TRY_LINK([#include <stdio.h>],
[printf("%s", __FUNCTION__);],
have_function=yes,
have_function=no)
])
AC_MSG_RESULT($have_function)
if test "$have_function" = yes; then
AC_DEFINE(HAVE_FUNCTION, 1,
[defined if the compiler implements __FUNCTION__])
fi
dnl #3: __func__
AC_MSG_CHECKING(whether $CC implements __func__)
AC_CACHE_VAL(have_func,[
AC_TRY_LINK([#include <stdio.h>],
[printf("%s", __func__);],
have_func=yes,
have_func=no)
])
AC_MSG_RESULT($have_func)
if test "$have_func" = yes; then
AC_DEFINE(HAVE_FUNC, 1,
[defined if the compiler implements __func__])
fi
dnl now define FUNCTION to whatever works, and fallback to ""
if test "$have_pretty_function" = yes; then
function=__PRETTY_FUNCTION__
else
if test "$have_function" = yes; then
function=__FUNCTION__
else
if test "$have_func" = yes; then
function=__func__
else
function=\"\"
fi
fi
fi
AC_DEFINE_UNQUOTED(GST_FUNCTION, $function, [macro to use to show function name])
])

21
common/m4/gst-gettext.m4 Normal file
View file

@ -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])
])

26
common/m4/gst-glib2.m4 Normal file
View file

@ -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)
])

43
common/m4/gst-libxml2.m4 Normal file
View file

@ -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 <libxml/tree.h>
#include <stdio.h>
],[
/* function body */
],
AC_MSG_NOTICE([Test xml2 program linked]),
AC_MSG_ERROR([Could not link libxml2 test program. Check if you have the necessary dependencies.])
)
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
])

View file

@ -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)
])

35
common/m4/gst-valgrind.m4 Normal file
View file

@ -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")
])

53
common/m4/gtk-doc.m4 Normal file
View file

@ -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")
])

131
common/m4/pkg.m4 Normal file
View file

@ -0,0 +1,131 @@
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
#
# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# PKG_PROG_PKG_CONFIG([MIN-VERSION])
# ----------------------------------
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
fi
if test -n "$PKG_CONFIG"; then
_pkg_min_version=m4_ifval([$1], [$1], [0.9.0])
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
PKG_CONFIG=""
fi
fi[]dnl
])# PKG_PROG_PKG_CONFIG
# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
#
# Check to see whether a particular set of modules exists. Similar
# to PKG_CHECK_MODULES(), but does not set variables or print errors.
#
#
# Similar to PKG_CHECK_MODULES, make sure that the first instance of
# this or PKG_CHECK_MODULES is called, or make sure to call
# PKG_CHECK_EXISTS manually
# --------------------------------------------------------------
AC_DEFUN([PKG_CHECK_EXISTS],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
if test -n "$PKG_CONFIG" && \
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
m4_ifval([$2], [$2], [:])
m4_ifvaln([$3], [else
$3])dnl
fi])
# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
# ---------------------------------------------
m4_define([_PKG_CONFIG],
[if test -n "$PKG_CONFIG"; then
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 <http://www.freedesktop.org/software/pkgconfig>.])],
[$4])
else
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
AC_MSG_RESULT([yes])
ifelse([$3], , :, [$3])
fi[]dnl
])# PKG_CHECK_MODULES

155
common/mangle-tmpl.py Normal file
View file

@ -0,0 +1,155 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
"""
use the output from gst-xmlinspect.py to mangle tmpl/*.sgml and
insert/overwrite Short Description and Long Description
"""
# FIXME: right now it uses pygst and scans on its own;
# we really should use inspect/*.xml instead since the result of
# gst-xmlinspect.py is commited by the docs maintainer, who can be
# expected to have pygst, but this step should be done for every docs build,
# so no pygst allowed
# read in inspect/*.xml
# for every tmpl/element-(name).xml: mangle with details from element
import glob
import re
import sys
import os
class Tmpl:
def __init__(self, filename):
self.filename = filename
self._sectionids = []
self._sections = {}
def read(self):
"""
Read and parse the sections from the given file.
"""
lines = open(self.filename).readlines()
matcher = re.compile("<!-- ##### SECTION (\S+) ##### -->\n")
id = None
for line in lines:
match = matcher.search(line)
if match:
id = match.expand("\\1")
self._sectionids.append(id)
self._sections[id] = []
else:
if not id:
sys.stderr.write(
"WARNING: line before a SECTION header: %s" % line)
else:
self._sections[id].append(line)
def get_section(self, id):
"""
Get the content from the given section.
"""
return self._sections[id]
def set_section(self, id, content):
"""
Replace the given section id with the given content.
"""
self._sections[id] = content
def output(self):
"""
Return the output of the current template in the tmpl/*.sgml format.
"""
lines = []
for id in self._sectionids:
lines.append("<!-- ##### SECTION %s ##### -->\n" % id)
for line in self._sections[id]:
lines.append(line)
return "".join(lines)
def write(self, backup=False):
"""
Write out the template file again, backing up the previous one.
"""
if backup:
target = self.filename + ".mangle.bak"
os.rename(self.filename, target)
handle = open(self.filename, "w")
handle.write(self.output())
handle.close()
from xml.dom.ext.reader import Sax2
from xml.dom.NodeFilter import NodeFilter
def get_elements(file):
elements = {}
handle = open(file)
reader = Sax2.Reader()
doc = reader.fromStream(handle)
handle.close()
walker = doc.createTreeWalker(doc.documentElement,
NodeFilter.SHOW_ELEMENT, None, 0)
while walker.currentNode and walker.currentNode.tagName != 'elements':
walker.nextNode()
# we're at elements now
el = walker.firstChild()
while walker.currentNode:
element = walker.firstChild()
# loop over children of <element>
name = None
description = None
while walker.currentNode:
if walker.currentNode.tagName == 'name':
name = walker.currentNode.firstChild.data.encode('UTF-8')
if walker.currentNode.tagName == 'description':
description = walker.currentNode.firstChild.data.encode('UTF-8')
if not walker.nextSibling(): break
# back up to <element>
walker.parentNode()
elements[name] = {'description': description}
if not walker.nextSibling(): break
return elements
def main():
if not len(sys.argv) == 3:
sys.stderr.write('Please specify the inspect/ dir and the tmpl/ dir')
sys.exit(1)
inspectdir = sys.argv[1]
tmpldir = sys.argv[2]
# parse all .xml files; build map of element name -> short desc
#for file in glob.glob("inspect/plugin-*.xml"):
elements = {}
for file in glob.glob("%s/plugin-*.xml" % inspectdir):
elements.update(get_elements(file))
for file in glob.glob("%s/element-*.sgml" % tmpldir):
base = os.path.basename(file)
element = base[len("element-"):-len(".sgml")]
tmpl = Tmpl(file)
tmpl.read()
if element in elements.keys():
description = elements[element]['description']
tmpl.set_section("Short_Description", "%s\n\n" % description)
# put in an include if not yet there
line = '<include xmlns="http://www.w3.org/2003/XInclude" href="' + \
'element-' + element + '-details.xml" />\n'
section = tmpl.get_section("Long_Description")
if not section[0] == line:
section.insert(0, line)
tmpl.set_section("Long_Description", section)
tmpl.write()
main()

200
common/plugins.xsl Normal file
View file

@ -0,0 +1,200 @@
<?xml version='1.0'?> <!--*- mode: xml -*-->
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl"
version="1.0">
<xsl:output method="xml" indent="yes"
doctype-public ="-//OASIS//DTD DocBook XML V4.1.2//EN"
doctype-system = "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"/>
<xsl:param name="module" />
<xsl:template match="element">
<xsl:element name="varlistentry">
<xsl:element name="term">
<xsl:element name="link">
<xsl:attribute name="linkend"><xsl:value-of select="$module" />-plugins-<xsl:value-of select="name"/></xsl:attribute>
<xsl:value-of select="name" />
</xsl:element>
</xsl:element>
<xsl:element name="listitem">
<xsl:element name="simpara"><xsl:value-of select="description" /></xsl:element>
</xsl:element>
</xsl:element>
<xsl:variable name="name"><xsl:copy-of select="name"/></xsl:variable>
<!-- here we write an element-(name)-details.xml file for the element -->
<exsl:document href="{concat ('xml/element-', $name, '-details.xml')}" method="xml" indent="yes">
<xsl:element name="refsect2">
<xsl:element name="title">Element Information</xsl:element>
<xsl:element name="variablelist">
<!-- plugin name and link -->
<xsl:element name="varlistentry">
<xsl:element name="term">plugin</xsl:element>
<xsl:element name="listitem">
<xsl:element name="simpara">
<xsl:element name="link">
<xsl:attribute name="linkend">plugin-<xsl:value-of select="../../name"/></xsl:attribute>
<xsl:value-of select="../../name" />
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="varlistentry">
<xsl:element name="term">author</xsl:element>
<xsl:element name="listitem">
<xsl:element name="simpara"><xsl:value-of select="author" /></xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="varlistentry">
<xsl:element name="term">class</xsl:element>
<xsl:element name="listitem">
<xsl:element name="simpara"><xsl:value-of select="class" /></xsl:element>
</xsl:element>
</xsl:element>
</xsl:element> <!-- variablelist -->
<xsl:element name="title">Element Pads</xsl:element>
<!-- process all caps -->
<xsl:for-each select="pads/caps">
<xsl:element name="variablelist">
<xsl:element name="varlistentry">
<xsl:element name="term">name</xsl:element>
<xsl:element name="listitem">
<xsl:element name="simpara"><xsl:value-of select="name" /></xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="varlistentry">
<xsl:element name="term">direction</xsl:element>
<xsl:element name="listitem">
<xsl:element name="simpara"><xsl:value-of select="direction" /></xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="varlistentry">
<xsl:element name="term">presence</xsl:element>
<xsl:element name="listitem">
<xsl:element name="simpara"><xsl:value-of select="presence" /></xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="varlistentry">
<xsl:element name="term">details</xsl:element>
<xsl:element name="listitem">
<xsl:element name="simpara"><xsl:value-of select="details" /></xsl:element>
</xsl:element>
</xsl:element>
</xsl:element> <!-- variablelist -->
<!--xsl:element name="programlisting"><xsl:value-of select="details" /></xsl:element-->
</xsl:for-each>
</xsl:element>
</exsl:document>
</xsl:template>
<xsl:template match="plugin">
<xsl:element name="refentry">
<xsl:attribute name="id"><xsl:value-of select="$module" />-plugins-plugin-<xsl:value-of select="name"/></xsl:attribute>
<xsl:element name="refmeta">
<xsl:element name="refentrytitle">
<xsl:value-of select="name"/>
</xsl:element>
<xsl:element name="manvolnum">3</xsl:element>
<xsl:element name="refmiscinfo">FIXME Library</xsl:element>
</xsl:element> <!-- refmeta -->
<xsl:element name="refnamediv">
<xsl:element name="refname">
<xsl:element name="anchor">
<xsl:attribute name="id">plugin-<xsl:value-of select="name"/></xsl:attribute>
<xsl:value-of select="name"/>
</xsl:element>
</xsl:element>
<xsl:element name="refpurpose">
<xsl:value-of select="description"/>
</xsl:element>
</xsl:element>
<xsl:element name="refsect1">
<xsl:element name="title">Plugin Information</xsl:element>
<xsl:element name="variablelist">
<xsl:element name="varlistentry">
<xsl:element name="term">filename</xsl:element>
<xsl:element name="listitem">
<xsl:element name="simpara"><xsl:value-of select="basename" /></xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="varlistentry">
<xsl:element name="term">version</xsl:element>
<xsl:element name="listitem">
<xsl:element name="simpara"><xsl:value-of select="version" /></xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="varlistentry">
<xsl:element name="term">run-time license</xsl:element>
<xsl:element name="listitem">
<xsl:element name="simpara"><xsl:value-of select="license" /></xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="varlistentry">
<xsl:element name="term">package</xsl:element>
<xsl:element name="listitem">
<xsl:element name="simpara"><xsl:value-of select="package" /></xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="varlistentry">
<xsl:element name="term">origin</xsl:element>
<xsl:element name="listitem">
<xsl:element name="simpara">
<!-- only show origin as link if it starts with http -->
<xsl:choose>
<xsl:when test="substring(@href, 1, 4) = 'http'">
<xsl:element name="ulink">
<xsl:attribute name="url"><xsl:value-of select="origin" /></xsl:attribute>
<xsl:value-of select="origin" />
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="origin" />
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="refsect1">
<xsl:element name="title">Elements</xsl:element>
<!-- process all elements -->
<xsl:element name="variablelist">
<xsl:apply-templates select="elements"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:template>
<!-- ignore -->
<xsl:template match="gst-plugin-paths" />
</xsl:stylesheet>

4
common/po.mak Normal file
View file

@ -0,0 +1,4 @@
# rule to download the latest .po files
download-po: $(top_srcdir)/common/download-translations
$(top_srcdir)/common/download-translations $(PACKAGE)

25
common/release.mak Normal file
View file

@ -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 )

226
common/scangobj-merge.py Executable file
View file

@ -0,0 +1,226 @@
#!/usr/bin/python
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
"""
parse, update and write .signals and .args files
"""
from twisted.python import util
import sys
import os
def debug(*args):
pass
class Object:
def __init__(self, name):
self._signals = util.OrderedDict()
self._args = util.OrderedDict()
self.name = name
def __repr__(self):
return "<Object %s>" % self.name
def add_signal(self, signal, overwrite=True):
if not overwrite and self._signals.has_key(signal.name):
raise IndexError, "signal %s already in %r" % (signal.name, self)
self._signals[signal.name] = signal
def add_arg(self, arg, overwrite=True):
if not overwrite and self._args.has_key(arg.name):
raise IndexError, "arg %s already in %r" % (arg.name, self)
self._args[arg.name] = arg
class Docable:
def __init__(self, **kwargs):
for key in self.attrs:
setattr(self, key, kwargs[key])
self.dict = kwargs
def __repr__(self):
return "<%r %s>" % (str(self.__class__), self.name)
class Signal(Docable):
attrs = ['name', 'returns', 'args']
class Arg(Docable):
attrs = ['name', 'type', 'range', 'flags', 'nick', 'blurb', 'default']
class GDoc:
def load_file(self, filename):
try:
lines = open(filename).readlines()
self.load_data("".join(lines))
except IOError:
print "WARNING - could not read from %s" % filename
def save_file(self, filename, backup=False):
"""
Save the signals information to the given .signals file if the
file content changed.
"""
olddata = None
try:
lines = open(filename).readlines()
olddata = "".join(lines)
except IOError:
print "WARNING - could not read from %s" % filename
newdata = self.get_data()
if olddata and olddata == newdata:
return
if olddata:
if backup:
os.rename(filename, filename + '.bak')
handle = open(filename, "w")
handle.write(newdata)
handle.close()
class Signals(GDoc):
def __init__(self):
self._objects = util.OrderedDict()
def load_data(self, data):
"""
Load the .signals lines, creating our list of objects and signals.
"""
import re
smatcher = re.compile(
'(?s)' # make . match \n
'<SIGNAL>\n(.*?)</SIGNAL>\n'
)
nmatcher = re.compile(
'<NAME>'
'(?P<object>\S*)' # store object
'::'
'(?P<signal>\S*)' # store signal
'</NAME>'
)
rmatcher = re.compile(
'(?s)' # make . match \n
'<RETURNS>(?P<returns>\S*)</RETURNS>\n' # store returns
'(?P<args>.*)' # store args
)
for block in smatcher.findall(data):
nmatch = nmatcher.search(block)
if nmatch:
o = nmatch.group('object')
debug("Found object", o)
debug("Found signal", nmatch.group('signal'))
if not self._objects.has_key(o):
object = Object(o)
self._objects[o] = object
rmatch = rmatcher.search(block)
if rmatch:
dict = rmatch.groupdict().copy()
dict['name'] = nmatch.group('signal')
signal = Signal(**dict)
self._objects[o].add_signal(signal)
def get_data(self):
lines = []
for o in self._objects.values():
for s in o._signals.values():
block = """<SIGNAL>
<NAME>%(object)s::%(name)s</NAME>
<RETURNS>%(returns)s</RETURNS>
%(args)s</SIGNAL>
"""
d = s.dict.copy()
d['object'] = o.name
lines.append(block % d)
return "\n".join(lines) + '\n'
class Args(GDoc):
def __init__(self):
self._objects = util.OrderedDict()
def load_data(self, data):
"""
Load the .args lines, creating our list of objects and args.
"""
import re
amatcher = re.compile(
'(?s)' # make . match \n
'<ARG>\n(.*?)</ARG>\n'
)
nmatcher = re.compile(
'<NAME>'
'(?P<object>\S*)' # store object
'::'
'(?P<arg>\S*)' # store arg
'</NAME>'
)
rmatcher = re.compile(
'(?s)' # make . match \n
'<TYPE>(?P<type>\S*)</TYPE>\n' # store type
'<RANGE>(?P<range>.*?)</RANGE>\n' # store range
'<FLAGS>(?P<flags>\S*)</FLAGS>\n' # store flags
'<NICK>(?P<nick>.*?)</NICK>\n' # store nick
'<BLURB>(?P<blurb>.*?)</BLURB>\n' # store blurb
'<DEFAULT>(?P<default>.*?)</DEFAULT>\n' # store default
)
for block in amatcher.findall(data):
nmatch = nmatcher.search(block)
if nmatch:
o = nmatch.group('object')
debug("Found object", o)
debug("Found arg", nmatch.group('arg'))
if not self._objects.has_key(o):
object = Object(o)
self._objects[o] = object
rmatch = rmatcher.search(block)
if rmatch:
dict = rmatch.groupdict().copy()
dict['name'] = nmatch.group('arg')
arg = Arg(**dict)
self._objects[o].add_arg(arg)
else:
print "ERROR: could not match arg from block %s" % block
def get_data(self):
lines = []
for o in self._objects.values():
for a in o._args.values():
block = """<ARG>
<NAME>%(object)s::%(name)s</NAME>
<TYPE>%(type)s</TYPE>
<RANGE>%(range)s</RANGE>
<FLAGS>%(flags)s</FLAGS>
<NICK>%(nick)s</NICK>
<BLURB>%(blurb)s</BLURB>
<DEFAULT>%(default)s</DEFAULT>
</ARG>
"""
d = a.dict.copy()
d['object'] = o.name
lines.append(block % d)
return "\n".join(lines) + '\n'
def main(argv):
modulename = None
try:
modulename = argv[1]
except IndexError:
sys.stderr.write('Pleae provide a documentation module name\n')
sys.exit(1)
print "Merging scangobj output for %s" % modulename
signals = Signals()
signals.load_file(modulename + '.signals')
signals.load_file(modulename + '.signals.new')
signals.save_file(modulename + '.signals', backup=True)
args = Args()
args.load_file(modulename + '.args')
args.load_file(modulename + '.args.new')
args.save_file(modulename + '.args', backup=True)
main(sys.argv)

33
common/upload.mak Normal file
View file

@ -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

222
configure.ac Normal file
View file

@ -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."

View file

@ -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.

54
gst-rtsp.spec.in Normal file
View file

@ -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 <christian.schaller@collabora.co.uk>
- First spec file

18
m4/Makefile.am Normal file
View file

@ -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

23
m4/codeset.m4 Normal file
View file

@ -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 <langinfo.h>],
[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 <langinfo.h> and nl_langinfo(CODESET).])
fi
])

20
src/Makefile.am Normal file
View file

@ -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

43
src/main.c Normal file
View file

@ -0,0 +1,43 @@
/* GStreamer
* Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
*
* 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 <gst/gst.h>
#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;
}

811
src/rtsp-client.c Normal file
View file

@ -0,0 +1,811 @@
/* GStreamer
* Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
*
* 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 <sys/ioctl.h>
#include <gst/sdp/gstsdpmessage.h>
#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", &timestamp, 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;
}
}

89
src/rtsp-client.h Normal file
View file

@ -0,0 +1,89 @@
/* GStreamer
* Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
*
* 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <gst/gst.h>
#include <gst/rtsp/gstrtspconnection.h>
#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__ */

266
src/rtsp-media.c Normal file
View file

@ -0,0 +1,266 @@
/* GStreamer
* Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
*
* 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;
}

79
src/rtsp-media.h Normal file
View file

@ -0,0 +1,79 @@
/* GStreamer
* Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
*
* 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 <gst/gst.h>
#include <gst/rtsp/gstrtspurl.h>
#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__ */

232
src/rtsp-server.c Normal file
View file

@ -0,0 +1,232 @@
/* GStreamer
* Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
*
* 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 <sys/ioctl.h>
#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;
}
}

86
src/rtsp-server.h Normal file
View file

@ -0,0 +1,86 @@
/* GStreamer
* Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
*
* 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <gst/gst.h>
#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__ */

165
src/rtsp-session-pool.c Normal file
View file

@ -0,0 +1,165 @@
/* GStreamer
* Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
*
* 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);
}
}

69
src/rtsp-session-pool.h Normal file
View file

@ -0,0 +1,69 @@
/* GStreamer
* Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
*
* 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 <gst/gst.h>
#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__ */

503
src/rtsp-session.c Normal file
View file

@ -0,0 +1,503 @@
/* GStreamer
* Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
*
* 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;
}

138
src/rtsp-session.h Normal file
View file

@ -0,0 +1,138 @@
/* GStreamer
* Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
*
* 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 <gst/gst.h>
#include <gst/rtsp/gstrtsptransport.h>
#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__ */