initial checkin

Original commit message from CVS:
initial checkin
This commit is contained in:
Erik Walthinsen 2000-01-30 09:03:00 +00:00
commit 1762dfbf98
124 changed files with 15477 additions and 0 deletions

1
AUTHORS Normal file
View file

@ -0,0 +1 @@
Erik Walthinsen <omega@cse.ogi.edu>

340
COPYING Normal file
View file

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

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

182
INSTALL Normal file
View file

@ -0,0 +1,182 @@
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.

1
Makefile.am Normal file
View file

@ -0,0 +1 @@
SUBDIRS = gst plugins test editor tools docs

0
NEWS Normal file
View file

7
README Normal file
View file

@ -0,0 +1,7 @@
This is gnome-streamer, a framework for streaming media in GNOME. The
fundamental design comes from the video pipeline at Oregon Graduate
Institute, as well as some ideas from DirectX. It's based on plug-ins
that will provide the various codec and other functionality. The
interface hopefully is generic enough for various companies (ahem, Apple)
to release binary codecs for Linux, until such time as they get a clue and
release the source.

11
acconfig.h Normal file
View file

@ -0,0 +1,11 @@
#undef PLUGINS_DIR
#undef PLUGINS_SRCDIR
#undef PLUGINS_USE_SRCDIR
#undef HAVE_LIBGHTTP
#undef HAVE_LIBXML
#undef HAVE_LIBMMX
#undef HAVE_ATOMIC_H
#undef DEBUG_ENABLED

67
autogen.sh Executable file
View file

@ -0,0 +1,67 @@
#!/bin/sh
# Run this to generate all the initial makefiles, etc.
DIE=0
package=gstreamer
srcfile=gst/gstobject.h
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have autoconf installed to compile $package."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
(libtool --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have libtool installed to compile $package."
echo "Get ftp://alpha.gnu.org/gnu/libtool-1.2.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
}
(automake --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have automake installed to compile $package."
echo "Get ftp://ftp.cygnus.com/pub/home/tromey/automake-1.2d.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
}
if test "$DIE" -eq 1; then
exit 1
fi
test -f $srcfile || {
echo "You must run this script in the top-level $package directory"
exit 1
}
if test -z "$*"; then
echo "I am going to run ./configure with no arguments - if you wish "
echo "to pass any to it, please specify them on the $0 command line."
fi
libtoolize --copy --force
aclocal $ACLOCAL_FLAGS
automake --add-missing
autoconf
autoheader
if [ "x$1" = "x--autogen-recurse" ];then
exit # the rest will happen later
fi
for dir in `find * -name autogen.sh -print | grep -v '^autogen.sh$' | \
sed 's/autogen.sh$//'`;do
echo "Recursively running autogen.sh in $dir"
pushd $dir > /dev/null
./autogen.sh --autogen-recurse "$@"
popd > /dev/null
done
./configure --enable-maintainer-mode "$@"
echo
echo "Now type 'make' to compile $package."

29
config.h.in Normal file
View file

@ -0,0 +1,29 @@
/* config.h.in. Generated automatically from configure.in by autoheader. */
/* Define if you need to in order for stat and other things to work. */
#undef _POSIX_SOURCE
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
#undef PLUGINS_DIR
#undef PLUGINS_SRCDIR
#undef PLUGINS_USE_SRCDIR
#undef HAVE_LIBGHTTP
#undef HAVE_LIBXML
#undef HAVE_LIBMMX
#undef HAVE_ATOMIC_H
#undef DEBUG_ENABLED
/* Define if you have the <asm/atomic.h> header file. */
#undef HAVE_ASM_ATOMIC_H
/* Name of package */
#undef PACKAGE
/* Version number of package */
#undef VERSION

145
configure.in Normal file
View file

@ -0,0 +1,145 @@
AC_INIT(gst/gstobject.h)
AM_CONFIG_HEADER(config.h)
STREAMER_MAJOR_VERSION=0
STREAMER_MINOR_VERSION=0
STREAMER_MICRO_VERSION=9.2
STREAMER_VERSION=$STREAMER_MAJOR_VERSION.$STREAMER_MINOR_VERSION.$STREAMER_MICRO_VERSION
dnl libtool
STREAMER_CURRENT=0
STREAMER_REVISION=0
STREAMER_AGE=0
AM_INIT_AUTOMAKE(gstreamer, $STREAMER_VERSION)
AC_SUBST(STREAMER_MAJOR_VERSION)
AC_SUBST(STREAMER_MINOR_VERSION)
AC_SUBST(STREAMER_MICRO_VERSION)
AC_SUBST(STREAMER_VERSION)
AC_SUBST(STREAMER_CURRENT)
AC_SUBST(STREAMER_REVISION)
AC_SUBST(STREAMER_AGE)
AM_MAINTAINER_MODE
AC_ISC_POSIX
AC_PROG_CC
AC_STDC_HEADERS
AC_ARG_PROGRAM
AM_DISABLE_STATIC
AC_LIBTOOL_DLOPEN
AM_PROG_LIBTOOL
AM_PATH_GLIB(1.2.0,
[LIBS="$LIBS $GLIB_LIBS" CFLAGS="$CFLAGS $GLIB_CFLAGS"],
AC_MSG_ERROR(Cannot find glib: Is glib-config in path?),
glib gmodule gthread)
AM_PATH_GTK(1.2.0)
dnl Check for libghttp
AC_CHECK_LIB(ghttp,ghttp_request_new,
[LIBS="$LIBS -lghttp" HAVE_LIBGHTTP="yes"],
AC_MSG_WARN(Cannot find libghttp: can't build gsthttpsrc),
$LIBS)
AC_DEFINE(HAVE_LIBGHTTP)
AM_CONDITIONAL(HAVE_LIBGHTTP, test "x$HAVE_LIBGHTTP" = "xyes")
AC_CHECK_HEADERS(asm/atomic.h, AC_DEFINE(HAVE_ATOMIC_H))
AC_PATH_PROG(XML_CONFIG,xml-config,no)
if test x$XML_CONFIG = xno;then
AC_MSG_ERROR(Couldn't find xml-config)
fi
XML_LIBS=`xml-config --libs`
XML_CFLAGS=`xml-config --cflags`
AC_SUBST(XML_LIBS)
AC_SUBST(XML_CFLAGS)
AC_DEFINE(HAVE_LIBXML)
AM_CONDITIONAL(HAVE_LIBXML, test "x$HAVE_LIBXML" = "xyes")
AC_CHECK_HEADER(mmx.h,[HAVE_LIBMMX=yes],)
AC_DEFINE(HAVE_LIBMMX)
AM_CONDITIONAL(HAVE_LIBMMX, test "x$HAVE_LIBMMX" = "xyes")
PLUGINS_DIR=${libdir}/plugins
AC_DEFINE_UNQUOTED(PLUGINS_DIR,"$PLUGINS_DIR")
AC_SUBST(PLUGINS_DIR)
PLUGINS_SRCDIR=`pwd`/$srcdir
AC_DEFINE_UNQUOTED(PLUGINS_SRCDIR,"$PLUGINS_SRCDIR")
AC_SUBST(PLUGINS_SRCDIR)
AC_ARG_ENABLE(plugin-srcdir,
[ --enable-plugin-srcdir allow tests/demos to use non-installed plugins ],
[AC_DEFINE(PLUGINS_USE_SRCDIR)])
AC_DEFINE(PLUGINS_USE_SRCDIR)
AC_ARG_ENABLE(debug,
[ --enable-debug spews lots of useless info at runtime],
[AC_DEFINE(DEBUG_ENABLED)])
AC_ARG_ENABLE(profiling,
[ --enable-profiling adds -pg to compiler commandline, for profiling],
[CFLAGS="$CFLAGS -pg"])
AC_SUBST(CFLAGS)
AC_SUBST(CPPFLAGS)
AC_SUBST(LDFLAGS)
AC_CHECK_PROG(GTKDOC, gtkdoc-mkdb, true, false)
AM_CONDITIONAL(HAVE_GTK_DOC, $GTKDOC)
AC_CONFIG_SUBDIRS(gist)
AC_CONFIG_SUBDIRS(plugins/mp3decode/xing/libxing)
AC_OUTPUT([Makefile
gst/Makefile
gst/types/Makefile
gst/meta/Makefile
gst/elements/Makefile
gst/xml/Makefile
plugins/Makefile
plugins/au/Makefile
plugins/wav/Makefile
plugins/mp3decode/Makefile
plugins/mp3decode/xa/Makefile
plugins/mp3decode/xing/Makefile
plugins/mp3decode/mpg123/Makefile
plugins/mp3decode/parse/Makefile
plugins/mpeg2/Makefile
plugins/mpeg2/parse/Makefile
plugins/mpeg2/ac3parse/Makefile
plugins/mpeg2/ac3dec/Makefile
plugins/mpeg1/Makefile
plugins/mpeg1/parse/Makefile
plugins/effects/Makefile
plugins/effects/stereo/Makefile
plugins/effects/volume/Makefile
plugins/visualization/Makefile
plugins/visualization/spectrum/Makefile
plugins/visualization/vumeter/Makefile
plugins/visualization/synaesthesia/Makefile
plugins/visualization/smoothwave/Makefile
plugins/dvdsrc/Makefile
plugins/vcdsrc/Makefile
plugins/cobin/Makefile
test/Makefile
test/xml/Makefile
test/bindings/Makefile
test/cothreads/Makefile
editor/Makefile
tools/Makefile
docs/Makefile
stamp.h])

61
gst/Makefile.am Normal file
View file

@ -0,0 +1,61 @@
# cheap trick to build . first...
SUBDIRS = . types meta elements xml
lib_LTLIBRARIES = libgst.la
GSTOBJECT_SRCS = \
gstobject.c
GSTOBJECT_INCLUDES = \
gstobject.h
libgst_la_SOURCES = \
gst.c \
$(GSTOBJECT_SRCS) \
gstpad.c \
gstbuffer.c \
gstelement.c \
gstelementfactory.c \
gstbin.c \
gstpipeline.c \
gstthread.c \
gstsrc.c \
gstfilter.c \
gstsink.c \
gstconnection.c \
gsttype.c \
gstplugin.c \
gstutils.c \
gsttrace.c \
gstmeta.c \
gsttee.c \
gstxml.c \
cothreads.c
libgstincludedir = $(includedir)/gst
libgstinclude_HEADERS = \
gst.h \
gstlog.h \
$(GSTOBJECT_INCLUDES) \
gstpad.h \
gstbuffer.h \
gstelement.h \
gstbin.h \
gstpipeline.h \
gstthread.h \
gstsrc.h \
gstfilter.h \
gstsink.h \
gstconnection.h \
gsttype.h \
gstplugin.h \
gstutils.h \
gsttrace.h \
gstmeta.h \
gsttee.h \
gstxml.h \
cothreads.h
libgst_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(XML_LIBS)
libgst_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE)
EXTRA_DIST = ROADMAP

143
gst/cothreads.c Normal file
View file

@ -0,0 +1,143 @@
#include <sys/time.h>
#include <linux/linkage.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <setjmp.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/mman.h>
#include "cothreads.h"
pthread_key_t _cothread_key = -1;
cothread_state *cothread_create(cothread_context *ctx) {
cothread_state *s;
if (pthread_self() == 0) {
s = (cothread_state *)malloc(sizeof(int) * COTHREAD_STACKSIZE);
} else {
char *sp = CURRENT_STACK_FRAME;
unsigned long *stack_end = (unsigned long *)((unsigned long)sp &
~(STACK_SIZE - 1));
s = (cothread_state *)(stack_end + ((ctx->nthreads - 1) *
COTHREAD_STACKSIZE));
if (mmap((char *)s,COTHREAD_STACKSIZE*(sizeof(int)),
PROT_READ|PROT_WRITE|PROT_EXEC,MAP_PRIVATE|MAP_ANONYMOUS,
-1,0) < 0) {
perror("mmap'ing cothread stack space");
return NULL;
}
}
s->ctx = ctx;
s->threadnum = ctx->nthreads;
s->flags = 0;
s->sp = (int *)(s + COTHREAD_STACKSIZE);
ctx->threads[ctx->nthreads++] = s;
// printf("created cothread at %p\n",s);
return s;
}
void cothread_setfunc(cothread_state *thread,cothread_func func,int argc,char **argv) {
thread->func = func;
thread->argc = argc;
thread->argv = argv;
thread->pc = (int *)func;
}
cothread_context *cothread_init() {
cothread_context *ctx = (cothread_context *)malloc(sizeof(cothread_context));
if (_cothread_key == -1) {
if (pthread_key_create(&_cothread_key,NULL) != 0) {
perror("pthread_key_create");
return;
}
}
pthread_setspecific(_cothread_key,ctx);
memset(ctx->threads,0,sizeof(ctx->threads));
ctx->threads[0] = (cothread_state *)malloc(sizeof(cothread_state));
ctx->threads[0]->ctx = ctx;
ctx->threads[0]->threadnum = 0;
ctx->threads[0]->func = NULL;
ctx->threads[0]->argc = 0;
ctx->threads[0]->argv = NULL;
ctx->threads[0]->flags = COTHREAD_STARTED;
ctx->threads[0]->sp = CURRENT_STACK_FRAME;
ctx->threads[0]->pc = 0;
// fprintf(stderr,"0th thread is at %p\n",ctx->threads[0]);
// we consider the initiating process to be cothread 0
ctx->nthreads = 1;
ctx->current = 0;
return ctx;
}
cothread_state *cothread_main(cothread_context *ctx) {
// fprintf(stderr,"returning %p, the 0th cothread\n",ctx->threads[0]);
return ctx->threads[0];
}
void cothread_stub() {
cothread_context *ctx = pthread_getspecific(_cothread_key);
register cothread_state *thread = ctx->threads[ctx->current];
thread->flags |= COTHREAD_STARTED;
thread->func(thread->argc,thread->argv);
thread->flags &= ~COTHREAD_STARTED;
thread->pc = 0;
// printf("uh, yeah, we shouldn't be here, but we should deal anyway\n");
}
void cothread_switch(cothread_state *thread) {
cothread_context *ctx;
cothread_state *current;
int enter = 0;
// int i;
if (thread == NULL)
return;
ctx = thread->ctx;
current = ctx->threads[ctx->current];
if (current == NULL) {
fprintf(stderr,"there's no current thread, help!\n");
exit(2);
}
if (current == thread) {
fprintf(stderr,"trying to switch to same thread, legal but not necessary\n");
return;
}
// find the number of the thread to switch to
ctx->current = thread->threadnum;
// fprintf(stderr,"about to switch to thread #%d\n",ctx->current);
/* save the current stack pointer, frame pointer, and pc */
__asm__("movl %%esp, %0" : "=m"(current->sp) : : "esp", "ebp");
enter = setjmp(current->jmp);
if (enter != 0)
return;
enter = 1;
/* restore stack pointer and other stuff of new cothread */
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
if (thread->flags & COTHREAD_STARTED) {
// switch to it
longjmp(thread->jmp,1);
} else {
// start it
__asm__("jmp " SYMBOL_NAME_STR(cothread_stub));
}
}

48
gst/cothreads.h Normal file
View file

@ -0,0 +1,48 @@
#ifndef __COTHREADS_H__
#define __COTHREADS_H__
#include <setjmp.h>
#include <pthread.h>
#define COTHREAD_STACKSIZE 8192
#define COTHREAD_MAXTHREADS 16
#define STACK_SIZE 0x200000
#ifndef CURRENT_STACK_FRAME
#define CURRENT_STACK_FRAME ({ char __csf; &__csf; })
#endif /* CURRENT_STACK_FRAME */
typedef struct _cothread_state cothread_state;
typedef struct _cothread_context cothread_context;
typedef int (*cothread_func)(int argc,char **argv);
#define COTHREAD_STARTED 0x01
struct _cothread_state {
cothread_context *ctx;
int threadnum;
cothread_func func;
int argc;
char **argv;
int flags;
int *sp;
int *pc;
jmp_buf jmp;
};
struct _cothread_context {
cothread_state *threads[COTHREAD_MAXTHREADS];
int nthreads;
int current;
};
cothread_context *cothread_init();
cothread_state *cothread_create(cothread_context *ctx);
void cothread_setfunc(cothread_state *thread,cothread_func func,int argc,char **argv);
void cothread_switch(cothread_state *thread);
cothread_state *cothread_main(cothread_context *ctx);
#endif /* __COTHREAD_H__ */

35
gst/elements/Makefile.am Normal file
View file

@ -0,0 +1,35 @@
lib_LTLIBRARIES = libgstelements.la
libgstelements_la_DEPENDENCIES = ../libgst.la
libgstelements_la_SOURCES = \
gstelements.c \
gstfakesrc.c \
gstidentity.c \
gstfakesink.c \
gstdisksrc.c \
gstasyncdisksrc.c \
gstfdsrc.c \
gsthttpsrc.c \
gstaudiosink.c \
gstaudiosrc.c \
gstfdsink.c \
gstqueue.c \
gstsinesrc.c
noinst_HEADERS = \
gstfakesrc.h \
gstidentity.h \
gstfakesink.h \
gstdisksrc.h \
gstasyncdisksrc.h \
gstfdsrc.h \
gsthttpsrc.h \
gstaudiosink.h \
gstaudiosrc.h \
gstfdsink.h \
gstqueue.h \
gstsinesrc.h
libgstelements_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) \
$(top_srcdir)/gst/libgst.la
libgstelements_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE)

View file

@ -0,0 +1,346 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <gstasyncdisksrc.h>
GstElementDetails gst_asyncdisksrc_details = {
"Asynchronous Disk Source",
"Source/File",
"Read from arbitrary point in a file",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
/* AsyncDiskSrc signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
ARG_LOCATION,
ARG_BYTESPERREAD,
ARG_LENGTH,
ARG_OFFSET,
};
static void gst_asyncdisksrc_class_init(GstAsyncDiskSrcClass *klass);
static void gst_asyncdisksrc_init(GstAsyncDiskSrc *asyncdisksrc);
static void gst_asyncdisksrc_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_asyncdisksrc_get_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_asyncdisksrc_push(GstSrc *src);
static void gst_asyncdisksrc_push_region(GstSrc *src,gulong offset,
gulong size);
static gboolean gst_asyncdisksrc_change_state(GstElement *element,
GstElementState state);
static GstSrcClass *parent_class = NULL;
static guint gst_asyncdisksrc_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_asyncdisksrc_get_type(void) {
static GtkType asyncdisksrc_type = 0;
if (!asyncdisksrc_type) {
static const GtkTypeInfo asyncdisksrc_info = {
"GstAsyncDiskSrc",
sizeof(GstAsyncDiskSrc),
sizeof(GstAsyncDiskSrcClass),
(GtkClassInitFunc)gst_asyncdisksrc_class_init,
(GtkObjectInitFunc)gst_asyncdisksrc_init,
(GtkArgSetFunc)gst_asyncdisksrc_set_arg,
(GtkArgGetFunc)gst_asyncdisksrc_get_arg,
(GtkClassInitFunc)NULL,
};
asyncdisksrc_type = gtk_type_unique(GST_TYPE_SRC,&asyncdisksrc_info);
}
return asyncdisksrc_type;
}
static void
gst_asyncdisksrc_class_init(GstAsyncDiskSrcClass *klass) {
GtkObjectClass *gtkobject_class;
GstElementClass *gstelement_class;
GstSrcClass *gstsrc_class;
gtkobject_class = (GtkObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
gstsrc_class = (GstSrcClass*)klass;
parent_class = gtk_type_class(GST_TYPE_SRC);
gtk_object_add_arg_type("GstAsyncDiskSrc::location", GTK_TYPE_STRING,
GTK_ARG_READWRITE, ARG_LOCATION);
gtk_object_add_arg_type("GstAsyncDiskSrc::bytesperread", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_BYTESPERREAD);
gtk_object_add_arg_type("GstAsyncDiskSrc::length", GTK_TYPE_LONG,
GTK_ARG_READABLE, ARG_LENGTH);
gtk_object_add_arg_type("GstAsyncDiskSrc::offset", GTK_TYPE_LONG,
GTK_ARG_READWRITE, ARG_OFFSET);
gtkobject_class->set_arg = gst_asyncdisksrc_set_arg;
gtkobject_class->get_arg = gst_asyncdisksrc_get_arg;
gstelement_class->change_state = gst_asyncdisksrc_change_state;
gstsrc_class->push = gst_asyncdisksrc_push;
gstsrc_class->push_region = gst_asyncdisksrc_push_region;
}
static void gst_asyncdisksrc_init(GstAsyncDiskSrc *asyncdisksrc) {
GST_SRC_SET_FLAGS(asyncdisksrc,GST_SRC_ASYNC);
asyncdisksrc->srcpad = gst_pad_new("src",GST_PAD_SRC);
gst_element_add_pad(GST_ELEMENT(asyncdisksrc),asyncdisksrc->srcpad);
asyncdisksrc->filename = NULL;
asyncdisksrc->fd = 0;
asyncdisksrc->size = 0;
asyncdisksrc->map = NULL;
asyncdisksrc->curoffset = 0;
asyncdisksrc->bytes_per_read = 4096;
asyncdisksrc->seq = 0;
}
static void gst_asyncdisksrc_set_arg(GtkObject *object,GtkArg *arg,guint id) {
GstAsyncDiskSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_ASYNCDISKSRC(object));
src = GST_ASYNCDISKSRC(object);
switch(id) {
case ARG_LOCATION:
/* the element must be stopped in order to do this */
g_return_if_fail(!GST_FLAG_IS_SET(src,GST_STATE_RUNNING));
if (src->filename) g_free(src->filename);
/* clear the filename if we get a NULL (is that possible?) */
if (GTK_VALUE_STRING(*arg) == NULL) {
src->filename = NULL;
gst_element_set_state(GST_ELEMENT(object),~GST_STATE_COMPLETE);
/* otherwise set the new filename */
} else {
src->filename = g_strdup(GTK_VALUE_STRING(*arg));
gst_element_set_state(GST_ELEMENT(object),GST_STATE_COMPLETE);
}
break;
case ARG_BYTESPERREAD:
src->bytes_per_read = GTK_VALUE_INT(*arg);
break;
case ARG_OFFSET:
src->curoffset = GTK_VALUE_LONG(*arg);
break;
default:
break;
}
}
static void gst_asyncdisksrc_get_arg(GtkObject *object,GtkArg *arg,guint id) {
GstAsyncDiskSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_ASYNCDISKSRC(object));
src = GST_ASYNCDISKSRC(object);
switch (id) {
case ARG_LOCATION:
GTK_VALUE_STRING(*arg) = src->filename;
break;
case ARG_BYTESPERREAD:
GTK_VALUE_INT(*arg) = src->bytes_per_read;
break;
case ARG_LENGTH:
GTK_VALUE_LONG(*arg) = src->size;
break;
case ARG_OFFSET:
GTK_VALUE_LONG(*arg) = src->curoffset;
break;
default:
arg->type = GTK_TYPE_INVALID;
break;
}
}
/**
* gst_asyncdisksrc_push:
* @src: #GstSrc to push a buffer from
*
* Push a new buffer from the asyncdisksrc at the current offset.
*/
void gst_asyncdisksrc_push(GstSrc *src) {
GstAsyncDiskSrc *asyncdisksrc;
GstBuffer *buf;
g_return_if_fail(src != NULL);
g_return_if_fail(GST_IS_ASYNCDISKSRC(src));
g_return_if_fail(GST_FLAG_IS_SET(src,GST_ASYNCDISKSRC_OPEN));
asyncdisksrc = GST_ASYNCDISKSRC(src);
/* deal with EOF state */
if (asyncdisksrc->curoffset >= asyncdisksrc->size) {
gst_src_signal_eos(GST_SRC(asyncdisksrc));
return;
}
/* create the buffer */
// FIXME: should eventually use a bufferpool for this
buf = GST_BUFFER(gst_buffer_new());
g_return_if_fail(buf != NULL);
/* simply set the buffer to point to the correct region of the file */
GST_BUFFER_DATA(buf) = asyncdisksrc->map + asyncdisksrc->curoffset;
GST_BUFFER_OFFSET(buf) = asyncdisksrc->curoffset;
if ((asyncdisksrc->curoffset + asyncdisksrc->bytes_per_read) >
asyncdisksrc->size) {
GST_BUFFER_SIZE(buf) = asyncdisksrc->size - asyncdisksrc->curoffset;
// FIXME: set the buffer's EOF bit here
} else
GST_BUFFER_SIZE(buf) = asyncdisksrc->bytes_per_read;
asyncdisksrc->curoffset += GST_BUFFER_SIZE(buf);
/* we're done, push the buffer off now */
gst_pad_push(asyncdisksrc->srcpad,buf);
}
/**
* gst_asyncdisksrc_push_region:
* @src: #GstSrc to push a buffer from
* @offset: offset in file
* @size: number of bytes
*
* Push a new buffer from the asyncdisksrc of given size at given offset.
*/
void gst_asyncdisksrc_push_region(GstSrc *src,gulong offset,gulong size) {
GstAsyncDiskSrc *asyncdisksrc;
GstBuffer *buf;
g_return_if_fail(src != NULL);
g_return_if_fail(GST_IS_ASYNCDISKSRC(src));
g_return_if_fail(GST_FLAG_IS_SET(src,GST_STATE_RUNNING));
asyncdisksrc = GST_ASYNCDISKSRC(src);
/* deal with EOF state */
if (offset >= asyncdisksrc->size) {
gst_src_signal_eos(GST_SRC(asyncdisksrc));
return;
}
/* create the buffer */
// FIXME: should eventually use a bufferpool for this
buf = gst_buffer_new();
g_return_if_fail(buf);
/* simply set the buffer to point to the correct region of the file */
GST_BUFFER_DATA(buf) = asyncdisksrc->map + offset;
GST_BUFFER_OFFSET(buf) = asyncdisksrc->curoffset;
if ((offset + size) > asyncdisksrc->size) {
GST_BUFFER_SIZE(buf) = asyncdisksrc->size - offset;
// FIXME: set the buffer's EOF bit here
} else
GST_BUFFER_SIZE(buf) = size;
asyncdisksrc->curoffset += GST_BUFFER_SIZE(buf);
/* we're done, push the buffer off now */
gst_pad_push(asyncdisksrc->srcpad,buf);
}
/* open the file and mmap it, necessary to go to RUNNING state */
static gboolean gst_asyncdisksrc_open_file(GstAsyncDiskSrc *src) {
g_return_if_fail(!GST_FLAG_IS_SET(src,GST_ASYNCDISKSRC_OPEN));
/* open the file */
src->fd = open(src->filename,O_RDONLY);
if (src->fd < 0) {
gst_element_error(GST_ELEMENT(src),"opening file");
return FALSE;
} else {
/* find the file length */
src->size = lseek(src->fd,0,SEEK_END);
lseek(src->fd,0,SEEK_SET);
/* map the file into memory */
src->map = mmap(NULL,src->size,PROT_READ,MAP_SHARED,src->fd,0);
/* collapse state if that failed */
if (src->map == NULL) {
close(src->fd);
gst_element_error(GST_ELEMENT(src),"mmapping file");
return FALSE;
}
GST_FLAG_SET(src,GST_ASYNCDISKSRC_OPEN);
}
return TRUE;
}
/* unmap and close the file */
static void gst_asyncdisksrc_close_file(GstAsyncDiskSrc *src) {
g_return_if_fail(GST_FLAG_IS_SET(src,GST_ASYNCDISKSRC_OPEN));
/* unmap the file from memory */
munmap(src->map,src->size);
/* close the file */
close(src->fd);
/* zero out a lot of our state */
src->fd = 0;
src->size = 0;
src->map = NULL;
src->curoffset = 0;
src->seq = 0;
GST_FLAG_UNSET(src,GST_ASYNCDISKSRC_OPEN);
}
static gboolean gst_asyncdisksrc_change_state(GstElement *element,
GstElementState state) {
g_return_if_fail(GST_IS_ASYNCDISKSRC(element));
switch (state) {
case GST_STATE_RUNNING:
if (!gst_asyncdisksrc_open_file(GST_ASYNCDISKSRC(element)))
return FALSE;
break;
case ~GST_STATE_RUNNING:
gst_asyncdisksrc_close_file(GST_ASYNCDISKSRC(element));
break;
default:
break;
}
if (GST_ELEMENT_CLASS(parent_class)->change_state)
return GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
return TRUE;
}

View file

@ -0,0 +1,88 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_ASYNCDISKSRC_H__
#define __GST_ASYNCDISKSRC_H__
#include <config.h>
#include <gst/gst.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_asyncdisksrc_details;
#define GST_TYPE_ASYNCDISKSRC \
(gst_asyncdisksrc_get_type())
#define GST_ASYNCDISKSRC(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_ASYNCDISKSRC,GstAsyncDiskSrc))
#define GST_ASYNCDISKSRC_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_ASYNCDISKSRC,GstAsyncDiskSrcClass))
#define GST_IS_ASYNCDISKSRC(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_ASYNCDISKSRC))
#define GST_IS_ASYNCDISKSRC_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_ASYNCDISKSRC)))
// NOTE: per-element flags start with 16 for now
typedef enum {
GST_ASYNCDISKSRC_OPEN = (1 << 16),
} GstAsyncDiskSrcFlags;
typedef struct _GstAsyncDiskSrc GstAsyncDiskSrc;
typedef struct _GstAsyncDiskSrcClass GstAsyncDiskSrcClass;
struct _GstAsyncDiskSrc {
GstSrc src;
/* pads */
GstPad *srcpad;
/* filename */
gchar *filename;
/* fd */
gint fd;
/* mapping parameters */
gulong size; /* how long is the file? */
guchar *map; /* where the file is mapped to */
/* details for fallback synchronous read */
gulong curoffset; /* current offset in file */
gulong bytes_per_read; /* bytes per read */
gulong seq; /* buffer sequence number */
};
struct _GstAsyncDiskSrcClass {
GstSrcClass parent_class;
};
GtkType gst_asyncdisksrc_get_type(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_ASYNCDISKSRC_H__ */

291
gst/elements/gstaudiosink.c Normal file
View file

@ -0,0 +1,291 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/soundcard.h>
#include <gstaudiosink.h>
#include <gst/meta/audioraw.h>
GstElementDetails gst_audiosink_details = {
"Audio Sink (OSS)",
"Sink/Audio",
"Output to a sound card via OSS",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
static gboolean gst_audiosink_open_audio(GstAudioSink *sink);
static void gst_audiosink_close_audio(GstAudioSink *sink);
static gboolean gst_audiosink_start(GstElement *element,
GstElementState state);
static gboolean gst_audiosink_stop(GstElement *element);
static gboolean gst_audiosink_change_state(GstElement *element,
GstElementState state);
/* AudioSink signals and args */
enum {
HANDOFF,
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
static void gst_audiosink_class_init(GstAudioSinkClass *klass);
static void gst_audiosink_init(GstAudioSink *audiosink);
static GstFilterClass *parent_class = NULL;
static guint gst_audiosink_signals[LAST_SIGNAL] = { 0 };
static guint16 gst_audiosink_type_audio = 0;
GtkType
gst_audiosink_get_type(void) {
static GtkType audiosink_type = 0;
if (!audiosink_type) {
static const GtkTypeInfo audiosink_info = {
"GstAudioSink",
sizeof(GstAudioSink),
sizeof(GstAudioSinkClass),
(GtkClassInitFunc)gst_audiosink_class_init,
(GtkObjectInitFunc)gst_audiosink_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
audiosink_type = gtk_type_unique(GST_TYPE_FILTER,&audiosink_info);
}
if (!gst_audiosink_type_audio)
gst_audiosink_type_audio = gst_type_find_by_mime("audio/raw");
return audiosink_type;
}
static void
gst_audiosink_class_init(GstAudioSinkClass *klass) {
GtkObjectClass *gtkobject_class;
GstElementClass *gstelement_class;
gtkobject_class = (GtkObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
parent_class = gtk_type_class(GST_TYPE_FILTER);
gst_audiosink_signals[HANDOFF] =
gtk_signal_new("handoff",GTK_RUN_LAST,gtkobject_class->type,
GTK_SIGNAL_OFFSET(GstAudioSinkClass,handoff),
gtk_marshal_NONE__POINTER_POINTER,GTK_TYPE_NONE,2,
GTK_TYPE_POINTER,GTK_TYPE_POINTER);
gtk_object_class_add_signals(gtkobject_class,gst_audiosink_signals,
LAST_SIGNAL);
gstelement_class->start = gst_audiosink_start;
gstelement_class->stop = gst_audiosink_stop;
gstelement_class->change_state = gst_audiosink_change_state;
}
static void gst_audiosink_init(GstAudioSink *audiosink) {
audiosink->sinkpad = gst_pad_new("sink",GST_PAD_SINK);
gst_element_add_pad(GST_ELEMENT(audiosink),audiosink->sinkpad);
if (!gst_audiosink_type_audio)
gst_audiosink_type_audio = gst_type_find_by_mime("audio/raw");
gst_pad_set_type_id(audiosink->sinkpad,gst_audiosink_type_audio);
gst_pad_set_chain_function(audiosink->sinkpad,gst_audiosink_chain);
audiosink->fd = -1;
gst_element_set_state(GST_ELEMENT(audiosink),GST_STATE_COMPLETE);
}
void gst_audiosink_sync_parms(GstAudioSink *audiosink) {
audio_buf_info ospace;
g_return_if_fail(audiosink != NULL);
g_return_if_fail(GST_IS_AUDIOSINK(audiosink));
g_return_if_fail(audiosink->fd > 0);
ioctl(audiosink->fd,SNDCTL_DSP_RESET,0);
ioctl(audiosink->fd,SNDCTL_DSP_SETFMT,&audiosink->format);
ioctl(audiosink->fd,SNDCTL_DSP_CHANNELS,&audiosink->channels);
ioctl(audiosink->fd,SNDCTL_DSP_SPEED,&audiosink->frequency);
ioctl(audiosink->fd,SNDCTL_DSP_GETOSPACE,&ospace);
g_print("setting sound card to %dKHz %d bit %s (%d bytes buffer)\n",
audiosink->frequency,audiosink->format,
(audiosink->channels == 2) ? "stereo" : "mono",ospace.bytes);
}
GstElement *gst_audiosink_new(gchar *name) {
GstElement *audiosink = GST_ELEMENT(gtk_type_new(GST_TYPE_AUDIOSINK));
gst_element_set_name(GST_ELEMENT(audiosink),name);
return audiosink;
}
void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) {
GstAudioSink *audiosink;
MetaAudioRaw *meta;
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail(buf != NULL);
/* this has to be an audio buffer */
// g_return_if_fail(((GstMeta *)buf->meta)->type !=
//gst_audiosink_type_audio);
audiosink = GST_AUDIOSINK(pad->parent);
// g_return_if_fail(GST_FLAG_IS_SET(audiosink,GST_STATE_RUNNING));
meta = (MetaAudioRaw *)gst_buffer_get_first_meta(buf);
if (meta != NULL) {
if ((meta->format != audiosink->format) ||
(meta->channels != audiosink->channels) ||
(meta->frequency != audiosink->frequency)) {
audiosink->format = meta->format;
audiosink->channels = meta->channels;
audiosink->frequency = meta->frequency;
gst_audiosink_sync_parms(audiosink);
g_print("sound device set to format %d, %d channels, %dHz\n",
audiosink->format,audiosink->channels,audiosink->frequency);
}
}
gtk_signal_emit(GTK_OBJECT(audiosink),gst_audiosink_signals[HANDOFF],
audiosink);
if (GST_BUFFER_DATA(buf) != NULL) {
gst_trace_add_entry(NULL,0,buf,"audiosink: writing to soundcard");
if (audiosink->fd > 2)
write(audiosink->fd,GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf));
}
gst_buffer_unref(buf);
// g_print("a");
}
void gst_audiosink_set_format(GstAudioSink *audiosink,gint format) {
g_return_if_fail(audiosink != NULL);
g_return_if_fail(GST_IS_AUDIOSINK(audiosink));
audiosink->format = format;
gst_audiosink_sync_parms(audiosink);
}
void gst_audiosink_set_channels(GstAudioSink *audiosink,gint channels) {
g_return_if_fail(audiosink != NULL);
g_return_if_fail(GST_IS_AUDIOSINK(audiosink));
audiosink->channels = channels;
gst_audiosink_sync_parms(audiosink);
}
void gst_audiosink_set_frequency(GstAudioSink *audiosink,gint frequency) {
g_return_if_fail(audiosink != NULL);
g_return_if_fail(GST_IS_AUDIOSINK(audiosink));
audiosink->frequency = frequency;
gst_audiosink_sync_parms(audiosink);
}
static gboolean gst_audiosink_open_audio(GstAudioSink *sink) {
g_return_if_fail(sink->fd == -1);
g_print("attempting to open sound device\n");
/* first try to open the sound card */
sink->fd = open("/dev/dsp",O_RDWR);
/* if we have it, set the default parameters and go have fun */
if (sink->fd > 0) {
/* set card state */
sink->format = AFMT_S16_LE;
sink->channels = 2; /* stereo */
sink->frequency = 44100;
gst_audiosink_sync_parms(sink);
g_print("opened audio\n");
return TRUE;
}
return FALSE;
}
static void gst_audiosink_close_audio(GstAudioSink *sink) {
if (sink->fd < 0) return;
close(sink->fd);
sink->fd = -1;
g_print("closed sound device\n");
}
static gboolean gst_audiosink_start(GstElement *element,
GstElementState state) {
g_return_if_fail(GST_IS_AUDIOSINK(element));
if (gst_audiosink_open_audio(GST_AUDIOSINK(element)) == TRUE) {
gst_element_set_state(element,GST_STATE_RUNNING | state);
return TRUE;
}
return FALSE;
}
static gboolean gst_audiosink_stop(GstElement *element) {
g_return_if_fail(GST_IS_AUDIOSINK(element));
gst_audiosink_close_audio(GST_AUDIOSINK(element));
gst_element_set_state(element,~GST_STATE_RUNNING);
return TRUE;
}
static gboolean gst_audiosink_change_state(GstElement *element,
GstElementState state) {
g_return_if_fail(GST_IS_AUDIOSINK(element));
switch (state) {
case GST_STATE_RUNNING:
if (!gst_audiosink_open_audio(GST_AUDIOSINK(element)))
return FALSE;
break;
case ~GST_STATE_RUNNING:
gst_audiosink_close_audio(GST_AUDIOSINK(element));
break;
default:
break;
}
if (GST_ELEMENT_CLASS(parent_class)->change_state)
return GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
return TRUE;
}

View file

@ -0,0 +1,85 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_AUDIOSINK_H__
#define __GST_AUDIOSINK_H__
#include <config.h>
#include <gst/gst.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_audiosink_details;
#define GST_TYPE_AUDIOSINK \
(gst_audiosink_get_type())
#define GST_AUDIOSINK(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_AUDIOSINK,GstAudioSink))
#define GST_AUDIOSINK_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIOSINK,GstAudioSinkClass))
#define GST_IS_AUDIOSINK(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_AUDIOSINK))
#define GST_IS_AUDIOSINK_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOSINK)))
typedef struct _GstAudioSink GstAudioSink;
typedef struct _GstAudioSinkClass GstAudioSinkClass;
struct _GstAudioSink {
GstFilter filter;
GstPad *sinkpad;
/* soundcard state */
int fd;
gint format;
gint channels;
gint frequency;
};
struct _GstAudioSinkClass {
GstFilterClass parent_class;
/* signals */
void (*handoff) (GstElement *element,GstPad *pad);
};
GtkType gst_audiosink_get_type(void);
GstElement *gst_audiosink_new(gchar *name);
void gst_audiosink_chain(GstPad *pad,GstBuffer *buf);
void gst_audiosink_sync_parms(GstAudioSink *audiosink);
void gst_audiosink_set_format(GstAudioSink *audiosink,gint format);
void gst_audiosink_set_channels(GstAudioSink *audiosink,gint channels);
void gst_audiosink_set_frequency(GstAudioSink *audiosink,gint frequency);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_AUDIOSINK_H__ */

319
gst/elements/gstaudiosrc.c Normal file
View file

@ -0,0 +1,319 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/soundcard.h>
#include <gstaudiosrc.h>
GstElementDetails gst_audiosrc_details = {
"Audio (OSS) Source",
"Source/Audio",
"Read from the sound card",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
/* AudioSrc signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
ARG_LOCATION,
ARG_BYTESPERREAD,
ARG_CUROFFSET,
ARG_FORMAT,
ARG_CHANNELS,
ARG_FREQUENCY,
};
static void gst_audiosrc_class_init(GstAudioSrcClass *klass);
static void gst_audiosrc_init(GstAudioSrc *audiosrc);
static void gst_audiosrc_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_audiosrc_get_arg(GtkObject *object,GtkArg *arg,guint id);
static gboolean gst_audiosrc_change_state(GstElement *element,
GstElementState state);
static void gst_audiosrc_close_audio(GstAudioSrc *src);
static gboolean gst_audiosrc_open_audio(GstAudioSrc *src);
void gst_audiosrc_sync_parms(GstAudioSrc *audiosrc);
static GstSrcClass *parent_class = NULL;
static guint gst_audiosrc_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_audiosrc_get_type(void) {
static GtkType audiosrc_type = 0;
if (!audiosrc_type) {
static const GtkTypeInfo audiosrc_info = {
"GstAudioSrc",
sizeof(GstAudioSrc),
sizeof(GstAudioSrcClass),
(GtkClassInitFunc)gst_audiosrc_class_init,
(GtkObjectInitFunc)gst_audiosrc_init,
(GtkArgSetFunc)gst_audiosrc_set_arg,
(GtkArgGetFunc)gst_audiosrc_get_arg,
(GtkClassInitFunc)NULL,
};
audiosrc_type = gtk_type_unique(GST_TYPE_SRC,&audiosrc_info);
}
return audiosrc_type;
}
static void
gst_audiosrc_class_init(GstAudioSrcClass *klass) {
GtkObjectClass *gtkobject_class;
GstElementClass *gstelement_class;
GstSrcClass *gstsrc_class;
gtkobject_class = (GtkObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
gstsrc_class = (GstSrcClass*)klass;
parent_class = gtk_type_class(GST_TYPE_SRC);
gtk_object_add_arg_type("GstAudioSrc::location", GTK_TYPE_STRING,
GTK_ARG_READWRITE, ARG_LOCATION);
gtk_object_add_arg_type("GstAudioSrc::bytes_per_read", GTK_TYPE_ULONG,
GTK_ARG_READWRITE, ARG_BYTESPERREAD);
gtk_object_add_arg_type("GstAudioSrc::curoffset", GTK_TYPE_ULONG,
GTK_ARG_READABLE, ARG_CUROFFSET);
gtk_object_add_arg_type("GstAudioSrc::format", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_FORMAT);
gtk_object_add_arg_type("GstAudioSrc::channels", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_CHANNELS);
gtk_object_add_arg_type("GstAudioSrc::frequency", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_FREQUENCY);
gtkobject_class->set_arg = gst_audiosrc_set_arg;
gtkobject_class->get_arg = gst_audiosrc_get_arg;
gstelement_class->change_state = gst_audiosrc_change_state;
gstsrc_class->push = gst_audiosrc_push;
}
static void gst_audiosrc_init(GstAudioSrc *audiosrc) {
audiosrc->srcpad = gst_pad_new("src",GST_PAD_SRC);
gst_element_add_pad(GST_ELEMENT(audiosrc),audiosrc->srcpad);
audiosrc->filename = g_strdup("/dev/dsp");
audiosrc->fd = -1;
// audiosrc->meta = (MetaAudioRaw *)gst_meta_new();
// audiosrc->meta->format = AFMT_S16_LE;
// audiosrc->meta->channels = 2;
// audiosrc->meta->frequency = 44100;
// audiosrc->meta->bps = 4;
audiosrc->bytes_per_read = 4096;
audiosrc->curoffset = 0;
audiosrc->seq = 0;
}
GstElement *gst_audiosrc_new(gchar *name) {
GstElement *audiosrc = GST_ELEMENT(gtk_type_new(GST_TYPE_AUDIOSRC));
gst_element_set_name(GST_ELEMENT(audiosrc),name);
return audiosrc;
}
GstElement *gst_audiosrc_new_with_fd(gchar *name,gchar *filename) {
GstElement *audiosrc = gst_audiosrc_new(name);
gtk_object_set(GTK_OBJECT(audiosrc),"location",filename,NULL);
return audiosrc;
}
void gst_audiosrc_push(GstSrc *src) {
GstAudioSrc *audiosrc;
GstBuffer *buf;
glong readbytes;
g_return_if_fail(src != NULL);
g_return_if_fail(GST_IS_AUDIOSRC(src));
audiosrc = GST_AUDIOSRC(src);
// g_print("attempting to read something from soundcard\n");
buf = gst_buffer_new();
g_return_if_fail(buf);
GST_BUFFER_DATA(buf) = (gpointer)g_malloc(audiosrc->bytes_per_read);
readbytes = read(audiosrc->fd,GST_BUFFER_DATA(buf),
audiosrc->bytes_per_read);
if (readbytes == 0) {
gst_src_signal_eos(GST_SRC(audiosrc));
return;
}
GST_BUFFER_SIZE(buf) = readbytes;
GST_BUFFER_OFFSET(buf) = audiosrc->curoffset;
audiosrc->curoffset += readbytes;
// gst_buffer_add_meta(buf,GST_META(newmeta));
gst_pad_push(audiosrc->srcpad,buf);
// g_print("pushed buffer from soundcard of %d bytes\n",readbytes);
}
static void gst_audiosrc_set_arg(GtkObject *object,GtkArg *arg,guint id) {
GstAudioSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_AUDIOSRC(object));
src = GST_AUDIOSRC(object);
switch (id) {
case ARG_LOCATION:
if (src->filename) g_free(src->filename);
if (GTK_VALUE_STRING(*arg) == NULL) {
src->filename = NULL;
gst_element_set_state(GST_ELEMENT(object),~GST_STATE_COMPLETE);
} else {
src->filename = g_strdup(GTK_VALUE_STRING(*arg));
gst_element_set_state(GST_ELEMENT(object),GST_STATE_COMPLETE);
}
break;
case ARG_BYTESPERREAD:
src->bytes_per_read = GTK_VALUE_INT(*arg);
break;
case ARG_FORMAT:
src->format = GTK_VALUE_INT(*arg);
break;
case ARG_CHANNELS:
src->channels = GTK_VALUE_INT(*arg);
break;
case ARG_FREQUENCY:
src->frequency = GTK_VALUE_INT(*arg);
break;
default:
break;
}
}
static void gst_audiosrc_get_arg(GtkObject *object,GtkArg *arg,guint id) {
GstAudioSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_AUDIOSRC(object));
src = GST_AUDIOSRC(object);
switch (id) {
case ARG_LOCATION:
GTK_VALUE_STRING(*arg) = g_strdup(src->filename);
break;
case ARG_BYTESPERREAD:
GTK_VALUE_INT(*arg) = src->bytes_per_read;
break;
case ARG_FORMAT:
GTK_VALUE_INT(*arg) = src->format;
break;
case ARG_CHANNELS:
GTK_VALUE_INT(*arg) = src->channels;
break;
case ARG_FREQUENCY:
GTK_VALUE_INT(*arg) = src->frequency;
break;
default:
arg->type = GTK_TYPE_INVALID;
break;
}
}
static gboolean gst_audiosrc_change_state(GstElement *element,
GstElementState state) {
g_return_if_fail(GST_IS_AUDIOSRC(element));
switch (state) {
case GST_STATE_RUNNING:
if (!gst_audiosrc_open_audio(GST_AUDIOSRC(element)))
return FALSE;
break;
case ~GST_STATE_RUNNING:
gst_audiosrc_close_audio(GST_AUDIOSRC(element));
break;
default:
break;
}
if (GST_ELEMENT_CLASS(parent_class)->change_state)
return GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
return TRUE;
}
static gboolean gst_audiosrc_open_audio(GstAudioSrc *src) {
g_return_if_fail(src->fd == -1);
/* first try to open the sound card */
src->fd = open("/dev/dsp",O_RDONLY);
/* if we have it, set the default parameters and go have fun */
if (src->fd > 0) {
int arg = 0x7fff0006;
if (ioctl(src->fd, SNDCTL_DSP_SETFRAGMENT, &arg)) perror("uh");
/* set card state */
gst_audiosrc_sync_parms(src);
DEBUG("opened audio\n");
return TRUE;
}
return FALSE;
}
static void gst_audiosrc_close_audio(GstAudioSrc *src) {
g_return_if_fail(src->fd >= 0);
close(src->fd);
src->fd = -1;
}
void gst_audiosrc_sync_parms(GstAudioSrc *audiosrc) {
audio_buf_info ospace;
g_return_if_fail(audiosrc != NULL);
g_return_if_fail(GST_IS_AUDIOSRC(audiosrc));
g_return_if_fail(audiosrc->fd > 0);
ioctl(audiosrc->fd,SNDCTL_DSP_RESET,0);
ioctl(audiosrc->fd,SNDCTL_DSP_SETFMT,&audiosrc->format);
ioctl(audiosrc->fd,SNDCTL_DSP_CHANNELS,&audiosrc->channels);
ioctl(audiosrc->fd,SNDCTL_DSP_SPEED,&audiosrc->frequency);
ioctl(audiosrc->fd,SNDCTL_DSP_GETOSPACE,&ospace);
g_print("setting sound card to %dKHz %d bit %s (%d bytes buffer)\n",
audiosrc->frequency,audiosrc->format,
(audiosrc->channels == 2) ? "stereo" : "mono",ospace.bytes);
// audiosrc->meta.format = audiosrc->format;
// audiosrc->meta.channels = audiosrc->channels;
// audiosrc->meta.frequency = audiosrc->frequency;
// audiosrc->sentmeta = FALSE;
}

View file

@ -0,0 +1,90 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_AUDIOSRC_H__
#define __GST_AUDIOSRC_H__
#include <config.h>
#include <gst/gst.h>
#include <gst/meta/audioraw.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_audiosrc_details;
#define GST_TYPE_AUDIOSRC \
(gst_audiosrc_get_type())
#define GST_AUDIOSRC(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_AUDIOSRC,GstAudioSrc))
#define GST_AUDIOSRC_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIOSRC,GstAudioSrcClass))
#define GST_IS_AUDIOSRC(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_AUDIOSRC))
#define GST_IS_AUDIOSRC_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOSRC)))
typedef struct _GstAudioSrc GstAudioSrc;
typedef struct _GstAudioSrcClass GstAudioSrcClass;
struct _GstAudioSrc {
GstSrc src;
/* pads */
GstPad *srcpad;
/* sound card */
gchar *filename;
gint fd;
/* audio parameters */
gint format;
gint channels;
gint frequency;
/* blocking */
gulong curoffset;
gulong bytes_per_read;
gulong seq;
MetaAudioRaw *meta;
};
struct _GstAudioSrcClass {
GstSrcClass parent_class;
};
GtkType gst_audiosrc_get_type(void);
GstElement *gst_audiosrc_new(gchar *name);
void gst_audiosrc_push(GstSrc *src);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_AUDIOSRC_H__ */

267
gst/elements/gstdisksrc.c Normal file
View file

@ -0,0 +1,267 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <gstdisksrc.h>
GstElementDetails gst_disksrc_details = {
"Disk Source",
"Source/File",
"Synchronous read from a file",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
/* DiskSrc signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
ARG_LOCATION,
ARG_BYTESPERREAD,
ARG_OFFSET,
};
static void gst_disksrc_class_init(GstDiskSrcClass *klass);
static void gst_disksrc_init(GstDiskSrc *disksrc);
static void gst_disksrc_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_disksrc_get_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_disksrc_push(GstSrc *src);
static void gst_disksrc_push_region(GstSrc *src,gulong offset,gulong size);
static gboolean gst_disksrc_change_state(GstElement *element,
GstElementState state);
static GstSrcClass *parent_class = NULL;
static guint gst_disksrc_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_disksrc_get_type(void) {
static GtkType disksrc_type = 0;
if (!disksrc_type) {
static const GtkTypeInfo disksrc_info = {
"GstDiskSrc",
sizeof(GstDiskSrc),
sizeof(GstDiskSrcClass),
(GtkClassInitFunc)gst_disksrc_class_init,
(GtkObjectInitFunc)gst_disksrc_init,
(GtkArgSetFunc)gst_disksrc_set_arg,
(GtkArgGetFunc)gst_disksrc_get_arg,
(GtkClassInitFunc)NULL,
};
disksrc_type = gtk_type_unique(GST_TYPE_SRC,&disksrc_info);
}
return disksrc_type;
}
static void
gst_disksrc_class_init(GstDiskSrcClass *klass) {
GtkObjectClass *gtkobject_class;
GstElementClass *gstelement_class;
GstSrcClass *gstsrc_class;
gtkobject_class = (GtkObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
gstsrc_class = (GstSrcClass*)klass;
parent_class = gtk_type_class(GST_TYPE_SRC);
gtk_object_add_arg_type("GstDiskSrc::location", GTK_TYPE_STRING,
GTK_ARG_READWRITE, ARG_LOCATION);
gtk_object_add_arg_type("GstDiskSrc::bytesperread", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_BYTESPERREAD);
gtk_object_add_arg_type("GstDiskSrc::offset", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_OFFSET);
gtkobject_class->set_arg = gst_disksrc_set_arg;
gtkobject_class->get_arg = gst_disksrc_get_arg;
gstelement_class->change_state = gst_disksrc_change_state;
gstsrc_class->push = gst_disksrc_push;
/* we nominally can't (won't) do async */
gstsrc_class->push_region = NULL;
}
static void gst_disksrc_init(GstDiskSrc *disksrc) {
disksrc->srcpad = gst_pad_new("src",GST_PAD_SRC);
gst_element_add_pad(GST_ELEMENT(disksrc),disksrc->srcpad);
disksrc->filename = NULL;
disksrc->fd = 0;
disksrc->curoffset = 0;
disksrc->bytes_per_read = 4096;
disksrc->seq = 0;
}
static void gst_disksrc_set_arg(GtkObject *object,GtkArg *arg,guint id) {
GstDiskSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_DISKSRC(object));
src = GST_DISKSRC(object);
switch(id) {
case ARG_LOCATION:
/* the element must be stopped in order to do this */
// g_return_if_fail(!GST_FLAG_IS_SET(src,GST_STATE_RUNNING));
if (src->filename) g_free(src->filename);
/* clear the filename if we get a NULL (is that possible?) */
if (GTK_VALUE_STRING(*arg) == NULL) {
src->filename = NULL;
gst_element_set_state(GST_ELEMENT(object),~GST_STATE_COMPLETE);
/* otherwise set the new filename */
} else {
src->filename = g_strdup(GTK_VALUE_STRING(*arg));
gst_element_set_state(GST_ELEMENT(object),GST_STATE_COMPLETE);
}
break;
case ARG_BYTESPERREAD:
src->bytes_per_read = GTK_VALUE_INT(*arg);
break;
default:
break;
}
}
static void gst_disksrc_get_arg(GtkObject *object,GtkArg *arg,guint id) {
GstDiskSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_DISKSRC(object));
src = GST_DISKSRC(object);
switch (id) {
case ARG_LOCATION:
GTK_VALUE_STRING(*arg) = src->filename;
break;
case ARG_BYTESPERREAD:
GTK_VALUE_INT(*arg) = src->bytes_per_read;
break;
case ARG_OFFSET:
GTK_VALUE_INT(*arg) = src->curoffset;
break;
default:
arg->type = GTK_TYPE_INVALID;
break;
}
}
void gst_disksrc_push(GstSrc *src) {
GstDiskSrc *disksrc;
GstBuffer *buf;
glong readbytes;
g_return_if_fail(src != NULL);
g_return_if_fail(GST_IS_DISKSRC(src));
g_return_if_fail(GST_FLAG_IS_SET(src,GST_DISKSRC_OPEN));
disksrc = GST_DISKSRC(src);
/* create the buffer */
// FIXME: should eventually use a bufferpool for this
buf = gst_buffer_new();
g_return_if_fail(buf);
/* allocate the space for the buffer data */
GST_BUFFER_DATA(buf) = g_malloc(disksrc->bytes_per_read);
g_return_if_fail(GST_BUFFER_DATA(buf) != NULL);
/* read it in from the file */
readbytes = read(disksrc->fd,GST_BUFFER_DATA(buf),disksrc->bytes_per_read);
if (readbytes == 0) {
gst_src_signal_eos(GST_SRC(disksrc));
return;
}
/* if we didn't get as many bytes as we asked for, we're at EOF */
if (readbytes < disksrc->bytes_per_read)
GST_BUFFER_FLAG_SET(buf,GST_BUFFER_EOS);
GST_BUFFER_OFFSET(buf) = disksrc->curoffset;
GST_BUFFER_SIZE(buf) = readbytes;
disksrc->curoffset += readbytes;
/* we're done, push the buffer off now */
gst_pad_push(disksrc->srcpad,buf);
}
/* open the file, necessary to go to RUNNING state */
static gboolean gst_disksrc_open_file(GstDiskSrc *src) {
g_return_if_fail(!GST_FLAG_IS_SET(src,GST_DISKSRC_OPEN));
/* open the file */
src->fd = open(src->filename,O_RDONLY);
if (src->fd < 0) {
perror("open()");
gst_element_error(GST_ELEMENT(src),"opening file");
return FALSE;
}
GST_FLAG_SET(src,GST_DISKSRC_OPEN);
return TRUE;
}
/* close the file */
static void gst_disksrc_close_file(GstDiskSrc *src) {
g_return_if_fail(GST_FLAG_IS_SET(src,GST_DISKSRC_OPEN));
/* close the file */
close(src->fd);
/* zero out a lot of our state */
src->fd = 0;
src->curoffset = 0;
src->seq = 0;
GST_FLAG_UNSET(src,GST_DISKSRC_OPEN);
}
static gboolean gst_disksrc_change_state(GstElement *element,
GstElementState state) {
g_return_if_fail(GST_IS_DISKSRC(element));
switch (state) {
case GST_STATE_RUNNING:
if (!gst_disksrc_open_file(GST_DISKSRC(element)))
return FALSE;
break;
case ~GST_STATE_RUNNING:
gst_disksrc_close_file(GST_DISKSRC(element));
break;
default:
break;
}
if (GST_ELEMENT_CLASS(parent_class)->change_state)
return GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
return TRUE;
}

83
gst/elements/gstdisksrc.h Normal file
View file

@ -0,0 +1,83 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_DISKSRC_H__
#define __GST_DISKSRC_H__
#include <config.h>
#include <gst/gst.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_disksrc_details;
#define GST_TYPE_DISKSRC \
(gst_disksrc_get_type())
#define GST_DISKSRC(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_DISKSRC,GstDiskSrc))
#define GST_DISKSRC_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_DISKSRC,GstDiskSrcClass))
#define GST_IS_DISKSRC(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_DISKSRC))
#define GST_IS_DISKSRC_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_DISKSRC)))
// NOTE: per-element flags start with 16 for now
typedef enum {
GST_DISKSRC_OPEN = (1 << 16),
} GstDiskSrcFlags;
typedef struct _GstDiskSrc GstDiskSrc;
typedef struct _GstDiskSrcClass GstDiskSrcClass;
struct _GstDiskSrc {
GstSrc src;
/* pads */
GstPad *srcpad;
/* filename */
gchar *filename;
/* fd */
gint fd;
gulong curoffset; /* current offset in file */
gulong bytes_per_read; /* bytes per read */
gulong seq; /* buffer sequence number */
};
struct _GstDiskSrcClass {
GstSrcClass parent_class;
};
GtkType gst_disksrc_get_type(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_DISKSRC_H__ */

View file

@ -0,0 +1,85 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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 <gstasyncdisksrc.h>
#include <gstaudiosink.h>
#include <gstaudiosrc.h>
#include <gstdisksrc.h>
#include <gstidentity.h>
#include <gstfakesink.h>
#include <gstfakesrc.h>
#include <gstfdsink.h>
#include <gstfdsrc.h>
#include <gsthttpsrc.h>
#include <gstqueue.h>
#include <gstsinesrc.h>
struct _elements_entry {
gchar *name;
GtkType (*type) (void);
GstElementDetails *details;
};
struct _elements_entry _elements[] = {
{ "asyncdisksrc", gst_asyncdisksrc_get_type, &gst_asyncdisksrc_details },
{ "audiosink", gst_audiosink_get_type, &gst_audiosink_details },
{ "audiosrc", gst_audiosrc_get_type, &gst_audiosrc_details },
{ "disksrc", gst_disksrc_get_type, &gst_disksrc_details },
{ "identity", gst_identity_get_type, &gst_identity_details },
{ "fakesink", gst_fakesink_get_type, &gst_fakesink_details },
{ "fakesrc", gst_fakesrc_get_type, &gst_fakesrc_details },
{ "fdsink", gst_fdsink_get_type, &gst_fdsink_details },
{ "fdsrc", gst_fdsrc_get_type, &gst_fdsrc_details },
{ "httpsrc", gst_httpsrc_get_type, &gst_httpsrc_details },
{ "queue", gst_queue_get_type, &gst_queue_details },
{ "sinesrc", gst_sinesrc_get_type, &gst_sinesrc_details },
{ NULL, 0 },
};
GstPlugin *plugin_init(GModule *module) {
GstPlugin *plugin;
GstElementFactory *factory;
int i = 0;
if (gst_plugin_find("gstelements") != NULL) return NULL;
plugin = gst_plugin_new("gstelements");
g_return_val_if_fail(plugin != NULL,NULL);
gst_plugin_set_longname(plugin,"Standard GST Elements");
while (_elements[i].name) {
factory = gst_elementfactory_new(_elements[i].name,
(_elements[i].type)(),
_elements[i].details);
if (factory != NULL) {
gst_plugin_add_factory(plugin,factory);
// DEBUG("added factory '%s'\n",_elements[i].name);
}
i++;
}
gst_info("gstelements: loaded %d standard elements\n",i);
return plugin;
}

View file

81
gst/elements/gstesdsink.h Normal file
View file

@ -0,0 +1,81 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_ESDSINK_H__
#define __GST_ESDSINK_H__
#include <gst/gstfilter.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GST_TYPE_ESDSINK \
(gst_esdsink_get_type())
#define GST_ESDSINK(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_ESDSINK,GstEsdSink))
#define GST_ESDSINK_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_ESDSINK,GstEsdSinkClass))
#define GST_IS_ESDSINK(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_ESDSINK))
#define GST_IS_ESDSINK_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_ESDSINK)))
typedef struct _GstEsdSink GstEsdSink;
typedef struct _GstEsdSinkClass GstEsdSinkClass;
struct _GstEsdSink {
GstFilter filter;
GstPad *sinkpad;
/* soundcard state */
int fd;
gint format;
gint channels;
gint frequency;
};
struct _GstEsdSinkClass {
GstFilterClass parent_class;
/* signals */
void (*handoff) (GstElement *element,GstPad *pad);
};
GtkType gst_esdsink_get_type(void);
GstElement *gst_esdsink_new(gchar *name);
void gst_esdsink_chain(GstPad *pad,GstBuffer *buf);
void gst_esdsink_sync_parms(GstEsdSink *esdsink);
void gst_esdsink_set_format(GstEsdSink *esdsink,gint format);
void gst_esdsink_set_channels(GstEsdSink *esdsink,gint channels);
void gst_esdsink_set_frequency(GstEsdSink *esdsink,gint frequency);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_ESDSINK_H__ */

109
gst/elements/gstfakesink.c Normal file
View file

@ -0,0 +1,109 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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 <gstfakesink.h>
GstElementDetails gst_fakesink_details = {
"Fake Sink",
"Sink",
"Black hole for data",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
/* FakeSink signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
static void gst_fakesink_class_init(GstFakeSinkClass *klass);
static void gst_fakesink_init(GstFakeSink *fakesink);
static GstSinkClass *parent_class = NULL;
static guint gst_fakesink_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_fakesink_get_type(void) {
static GtkType fakesink_type = 0;
if (!fakesink_type) {
static const GtkTypeInfo fakesink_info = {
"GstFakeSink",
sizeof(GstFakeSink),
sizeof(GstFakeSinkClass),
(GtkClassInitFunc)gst_fakesink_class_init,
(GtkObjectInitFunc)gst_fakesink_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
fakesink_type = gtk_type_unique(GST_TYPE_SINK,&fakesink_info);
}
return fakesink_type;
}
static void
gst_fakesink_class_init(GstFakeSinkClass *klass) {
GstSinkClass *gstsink_class;
gstsink_class = (GstSinkClass*)klass;
parent_class = gtk_type_class(GST_TYPE_SINK);
}
static void gst_fakesink_init(GstFakeSink *fakesink) {
fakesink->sinkpad = gst_pad_new("sink",GST_PAD_SINK);
gst_element_add_pad(GST_ELEMENT(fakesink),fakesink->sinkpad);
gst_pad_set_chain_function(fakesink->sinkpad,gst_fakesink_chain);
// we're already complete, since we don't have any args...
gst_element_set_state(GST_ELEMENT(fakesink),GST_STATE_COMPLETE);
}
GstElement *gst_fakesink_new(gchar *name) {
GstElement *fakesink = GST_ELEMENT(gtk_type_new(GST_TYPE_FAKESINK));
gst_element_set_name(GST_ELEMENT(fakesink),name);
return fakesink;
}
void gst_fakesink_chain(GstPad *pad,GstBuffer *buf) {
GstFakeSink *fakesink;
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail(buf != NULL);
fakesink = GST_FAKESINK(pad->parent);
// g_print("gst_fakesink_chain: got buffer of %d bytes in '%s'\n",
// buf->datasize,gst_element_get_name(GST_ELEMENT(fakesink)));
g_print("<");
gst_buffer_unref(buf);
}

View file

@ -0,0 +1,71 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_FAKESINK_H__
#define __GST_FAKESINK_H__
#include <config.h>
#include <gst/gst.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_fakesink_details;
#define GST_TYPE_FAKESINK \
(gst_fakesink_get_type())
#define GST_FAKESINK(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_FAKESINK,GstFakeSink))
#define GST_FAKESINK_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_FAKESINK,GstFakeSinkClass))
#define GST_IS_FAKESINK(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_FAKESINK))
#define GST_IS_FAKESINK_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_FAKESINK)))
typedef struct _GstFakeSink GstFakeSink;
typedef struct _GstFakeSinkClass GstFakeSinkClass;
struct _GstFakeSink {
GstSink sink;
GstPad *sinkpad;
};
struct _GstFakeSinkClass {
GstSinkClass parent_class;
};
GtkType gst_fakesink_get_type(void);
GstElement *gst_fakesink_new(gchar *name);
void gst_fakesink_chain(GstPad *pad,GstBuffer *buf);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_FAKESINK_H__ */

112
gst/elements/gstfakesrc.c Normal file
View file

@ -0,0 +1,112 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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 <gstfakesrc.h>
GstElementDetails gst_fakesrc_details = {
"Fake Source",
"Source",
"Push empty (no data) buffers around",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
/* FakeSrc signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
static void gst_fakesrc_class_init(GstFakeSrcClass *klass);
static void gst_fakesrc_init(GstFakeSrc *fakesrc);
static GstSrcClass *parent_class = NULL;
static guint gst_fakesrc_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_fakesrc_get_type(void) {
static GtkType fakesrc_type = 0;
if (!fakesrc_type) {
static const GtkTypeInfo fakesrc_info = {
"GstFakeSrc",
sizeof(GstFakeSrc),
sizeof(GstFakeSrcClass),
(GtkClassInitFunc)gst_fakesrc_class_init,
(GtkObjectInitFunc)gst_fakesrc_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
fakesrc_type = gtk_type_unique(GST_TYPE_SRC,&fakesrc_info);
}
return fakesrc_type;
}
static void
gst_fakesrc_class_init(GstFakeSrcClass *klass) {
GstSrcClass *gstsrc_class;
gstsrc_class = (GstSrcClass*)klass;
parent_class = gtk_type_class(GST_TYPE_SRC);
gstsrc_class->push = gst_fakesrc_push;
gstsrc_class->push_region = NULL;
}
static void gst_fakesrc_init(GstFakeSrc *fakesrc) {
fakesrc->srcpad = gst_pad_new("src",GST_PAD_SRC);
gst_element_add_pad(GST_ELEMENT(fakesrc),fakesrc->srcpad);
// we're already complete, since we don't have any args...
gst_element_set_state(GST_ELEMENT(fakesrc),GST_STATE_COMPLETE);
}
GstElement *gst_fakesrc_new(gchar *name) {
GstElement *fakesrc = GST_ELEMENT(gtk_type_new(GST_TYPE_FAKESRC));
gst_element_set_name(GST_ELEMENT(fakesrc),name);
return fakesrc;
}
void gst_fakesrc_push(GstSrc *src) {
GstFakeSrc *fakesrc;
GstBuffer *buf;
g_return_if_fail(src != NULL);
g_return_if_fail(GST_IS_FAKESRC(src));
fakesrc = GST_FAKESRC(src);
// g_print("gst_fakesrc_push(): pushing fake buffer from '%s'\n",
// gst_element_get_name(GST_ELEMENT(fakesrc)));
g_print(">");
buf = gst_buffer_new();
gst_pad_push(fakesrc->srcpad,buf);
}

70
gst/elements/gstfakesrc.h Normal file
View file

@ -0,0 +1,70 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_FAKESRC_H__
#define __GST_FAKESRC_H__
#include <config.h>
#include <gst/gst.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_fakesrc_details;
#define GST_TYPE_FAKESRC \
(gst_fakesrc_get_type())
#define GST_FAKESRC(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_FAKESRC,GstFakeSrc))
#define GST_FAKESRC_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_FAKESRC,GstFakeSrcClass))
#define GST_IS_FAKESRC(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_FAKESRC))
#define GST_IS_FAKESRC_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_FAKESRC)))
typedef struct _GstFakeSrc GstFakeSrc;
typedef struct _GstFakeSrcClass GstFakeSrcClass;
struct _GstFakeSrc {
GstSrc src;
GstPad *srcpad;
};
struct _GstFakeSrcClass {
GstSrcClass parent_class;
};
GtkType gst_fakesrc_get_type(void);
GstElement *gst_fakesrc_new(gchar *name);
void gst_fakesrc_push(GstSrc *src);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_FAKESRC_H__ */

155
gst/elements/gstfdsink.c Normal file
View file

@ -0,0 +1,155 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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 <gstfdsink.h>
GstElementDetails gst_fdsink_details = {
"Filedescriptor Sink",
"Sink",
"Write data to a file descriptor",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
/* FdSink signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
ARG_FD
};
static void gst_fdsink_class_init(GstFdSinkClass *klass);
static void gst_fdsink_init(GstFdSink *fdsink);
static void gst_fdsink_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_fdsink_get_arg(GtkObject *object,GtkArg *arg,guint id);
static GstSinkClass *parent_class = NULL;
static guint gst_fdsink_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_fdsink_get_type(void) {
static GtkType fdsink_type = 0;
if (!fdsink_type) {
static const GtkTypeInfo fdsink_info = {
"GstFdSink",
sizeof(GstFdSink),
sizeof(GstFdSinkClass),
(GtkClassInitFunc)gst_fdsink_class_init,
(GtkObjectInitFunc)gst_fdsink_init,
(GtkArgSetFunc)gst_fdsink_set_arg,
(GtkArgGetFunc)gst_fdsink_get_arg,
(GtkClassInitFunc)NULL,
};
fdsink_type = gtk_type_unique(GST_TYPE_SINK,&fdsink_info);
}
return fdsink_type;
}
static void
gst_fdsink_class_init(GstFdSinkClass *klass) {
GtkObjectClass *gtkobject_class;
GstSinkClass *gstsink_class;
gtkobject_class = (GtkObjectClass*)klass;
gstsink_class = (GstSinkClass*)klass;
parent_class = gtk_type_class(GST_TYPE_SINK);
gtk_object_add_arg_type("GstFdSink::fd", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_FD);
gtkobject_class->set_arg = gst_fdsink_set_arg;
gtkobject_class->get_arg = gst_fdsink_get_arg;
}
static void gst_fdsink_init(GstFdSink *fdsink) {
fdsink->sinkpad = gst_pad_new("sink",GST_PAD_SINK);
gst_element_add_pad(GST_ELEMENT(fdsink),fdsink->sinkpad);
gst_pad_set_chain_function(fdsink->sinkpad,gst_fdsink_chain);
fdsink->fd = 1;
}
GstElement *gst_fdsink_new(gchar *name) {
GstElement *fdsink = GST_ELEMENT(gtk_type_new(GST_TYPE_FDSINK));
gst_element_set_name(GST_ELEMENT(fdsink),name);
return fdsink;
}
GstElement *gst_fdsink_new_with_fd(gchar *name,gint fd) {
GstElement *fdsink = gst_fdsink_new(name);
gtk_object_set(GTK_OBJECT(fdsink),"fd",fd,NULL);
return fdsink;
}
void gst_fdsink_chain(GstPad *pad,GstBuffer *buf) {
GstFdSink *fdsink;
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail(buf != NULL);
fdsink = GST_FDSINK(pad->parent);
g_return_if_fail(fdsink->fd >= 0);
if (GST_BUFFER_DATA(buf))
write(fdsink->fd,GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf));
gst_buffer_unref(buf);
}
static void gst_fdsink_set_arg(GtkObject *object,GtkArg *arg,guint id) {
GstFdSink *fdsink;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_FDSINK(object));
fdsink = GST_FDSINK(object);
switch(id) {
case ARG_FD:
fdsink->fd = GTK_VALUE_INT(*arg);
break;
default:
break;
}
}
static void gst_fdsink_get_arg(GtkObject *object,GtkArg *arg,guint id) {
GstFdSink *fdsink;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_FDSINK(object));
fdsink = GST_FDSINK(object);
switch(id) {
case ARG_FD:
GTK_VALUE_INT(*arg) = fdsink->fd;
break;
default:
break;
}
}

74
gst/elements/gstfdsink.h Normal file
View file

@ -0,0 +1,74 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_FDSINK_H__
#define __GST_FDSINK_H__
#include <config.h>
#include <gst/gst.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_fdsink_details;
#define GST_TYPE_FDSINK \
(gst_fdsink_get_type())
#define GST_FDSINK(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_FDSINK,GstFdSink))
#define GST_FDSINK_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_FDSINK,GstFdSinkClass))
#define GST_IS_FDSINK(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_FDSINK))
#define GST_IS_FDSINK_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_FDSINK)))
typedef struct _GstFdSink GstFdSink;
typedef struct _GstFdSinkClass GstFdSinkClass;
struct _GstFdSink {
GstSink sink;
GstPad *sinkpad;
int fd;
};
struct _GstFdSinkClass {
GstSinkClass parent_class;
};
GtkType gst_fdsink_get_type(void);
GstElement *gst_fdsink_new(gchar *name);
GstElement *gst_fdsink_new_with_fd(gchar *name,gint fd);
void gst_fdsink_chain(GstPad *pad,GstBuffer *buf);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_FDSINK_H__ */

206
gst/elements/gstfdsrc.c Normal file
View file

@ -0,0 +1,206 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <gstfdsrc.h>
GstElementDetails gst_fdsrc_details = {
"Disk Source",
"Source/File",
"Synchronous read from a file",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
/* FdSrc signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
ARG_LOCATION,
ARG_BYTESPERREAD,
ARG_OFFSET,
};
static void gst_fdsrc_class_init(GstFdSrcClass *klass);
static void gst_fdsrc_init(GstFdSrc *fdsrc);
static void gst_fdsrc_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_fdsrc_get_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_fdsrc_push(GstSrc *src);
static void gst_fdsrc_push_region(GstSrc *src,gulong offset,gulong size);
static GstSrcClass *parent_class = NULL;
static guint gst_fdsrc_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_fdsrc_get_type(void) {
static GtkType fdsrc_type = 0;
if (!fdsrc_type) {
static const GtkTypeInfo fdsrc_info = {
"GstFdSrc",
sizeof(GstFdSrc),
sizeof(GstFdSrcClass),
(GtkClassInitFunc)gst_fdsrc_class_init,
(GtkObjectInitFunc)gst_fdsrc_init,
(GtkArgSetFunc)gst_fdsrc_set_arg,
(GtkArgGetFunc)gst_fdsrc_get_arg,
(GtkClassInitFunc)NULL,
};
fdsrc_type = gtk_type_unique(GST_TYPE_SRC,&fdsrc_info);
}
return fdsrc_type;
}
static void
gst_fdsrc_class_init(GstFdSrcClass *klass) {
GtkObjectClass *gtkobject_class;
GstSrcClass *gstsrc_class;
gtkobject_class = (GtkObjectClass*)klass;
gstsrc_class = (GstSrcClass*)klass;
parent_class = gtk_type_class(GST_TYPE_SRC);
gtk_object_add_arg_type("GstFdSrc::location", GTK_TYPE_STRING,
GTK_ARG_WRITABLE, ARG_LOCATION);
gtk_object_add_arg_type("GstFdSrc::bytesperread", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_BYTESPERREAD);
gtk_object_add_arg_type("GstFdSrc::offset", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_OFFSET);
gtkobject_class->set_arg = gst_fdsrc_set_arg;
gtkobject_class->get_arg = gst_fdsrc_get_arg;
gstsrc_class->push = gst_fdsrc_push;
/* we nominally can't (won't) do async */
gstsrc_class->push_region = NULL;
}
static void gst_fdsrc_init(GstFdSrc *fdsrc) {
fdsrc->srcpad = gst_pad_new("src",GST_PAD_SRC);
gst_element_add_pad(GST_ELEMENT(fdsrc),fdsrc->srcpad);
fdsrc->fd = 0;
fdsrc->curoffset = 0;
fdsrc->bytes_per_read = 4096;
fdsrc->seq = 0;
}
static void gst_fdsrc_set_arg(GtkObject *object,GtkArg *arg,guint id) {
GstFdSrc *src;
int fd;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_FDSRC(object));
src = GST_FDSRC(object);
switch(id) {
case ARG_LOCATION:
/* the element must be stopped in order to do this */
g_return_if_fail(!GST_FLAG_IS_SET(src,GST_STATE_RUNNING));
/* if we get a NULL, consider it to be a fd of 0 */
if (GTK_VALUE_STRING(*arg) == NULL) {
src->fd = 0;
gst_element_set_state(GST_ELEMENT(object),~GST_STATE_COMPLETE);
/* otherwise set the new filename */
} else {
if (sscanf(GTK_VALUE_STRING(*arg),"%d",&fd))
src->fd = fd;
gst_element_set_state(GST_ELEMENT(object),GST_STATE_COMPLETE);
}
break;
case ARG_BYTESPERREAD:
src->bytes_per_read = GTK_VALUE_INT(*arg);
break;
default:
break;
}
}
static void gst_fdsrc_get_arg(GtkObject *object,GtkArg *arg,guint id) {
GstFdSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_FDSRC(object));
src = GST_FDSRC(object);
switch (id) {
case ARG_BYTESPERREAD:
GTK_VALUE_INT(*arg) = src->bytes_per_read;
break;
case ARG_OFFSET:
GTK_VALUE_INT(*arg) = src->curoffset;
break;
default:
arg->type = GTK_TYPE_INVALID;
break;
}
}
void gst_fdsrc_push(GstSrc *src) {
GstFdSrc *fdsrc;
GstBuffer *buf;
glong readbytes;
g_return_if_fail(src != NULL);
g_return_if_fail(GST_IS_FDSRC(src));
fdsrc = GST_FDSRC(src);
/* create the buffer */
// FIXME: should eventually use a bufferpool for this
buf = gst_buffer_new();
g_return_if_fail(buf);
/* allocate the space for the buffer data */
GST_BUFFER_DATA(buf) = g_malloc(fdsrc->bytes_per_read);
g_return_if_fail(GST_BUFFER_DATA(buf) != NULL);
/* read it in from the file */
readbytes = read(fdsrc->fd,GST_BUFFER_DATA(buf),fdsrc->bytes_per_read);
if (readbytes == 0) {
gst_src_signal_eos(GST_SRC(fdsrc));
return;
}
/* if we didn't get as many bytes as we asked for, we're at EOF */
if (readbytes < fdsrc->bytes_per_read) {
// FIXME: set the buffer's EOF bit here
}
GST_BUFFER_OFFSET(buf) = fdsrc->curoffset;
GST_BUFFER_SIZE(buf) = readbytes;
fdsrc->curoffset += readbytes;
/* we're done, push the buffer off now */
gst_pad_push(fdsrc->srcpad,buf);
}

77
gst/elements/gstfdsrc.h Normal file
View file

@ -0,0 +1,77 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_FDSRC_H__
#define __GST_FDSRC_H__
#include <config.h>
#include <gst/gst.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_fdsrc_details;
#define GST_TYPE_FDSRC \
(gst_fdsrc_get_type())
#define GST_FDSRC(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_FDSRC,GstFdSrc))
#define GST_FDSRC_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_FDSRC,GstFdSrcClass))
#define GST_IS_FDSRC(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_FDSRC))
#define GST_IS_FDSRC_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_FDSRC)))
typedef struct _GstFdSrc GstFdSrc;
typedef struct _GstFdSrcClass GstFdSrcClass;
struct _GstFdSrc {
GstSrc src;
/* pads */
GstPad *srcpad;
/* fd */
gint fd;
gulong curoffset; /* current offset in file */
gulong bytes_per_read; /* bytes per read */
gulong seq; /* buffer sequence number */
};
struct _GstFdSrcClass {
GstSrcClass parent_class;
};
GtkType gst_fdsrc_get_type(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_FDSRC_H__ */

258
gst/elements/gsthttpsrc.c Normal file
View file

@ -0,0 +1,258 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <gsthttpsrc.h>
GstElementDetails gst_httpsrc_details = {
"HTTP Source",
"Source/Network",
"Read data from an HTTP stream",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
static void gst_httpsrc_push(GstSrc *src);
static gboolean gst_httpsrc_open_url(GstHttpSrc *src);
static void gst_httpsrc_close_url(GstHttpSrc *src);
static gboolean gst_httpsrc_change_state(GstElement *element,
GstElementState state);
/* HttpSrc signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
ARG_LOCATION,
ARG_BYTESPERREAD,
ARG_OFFSET
};
static void gst_httpsrc_class_init(GstHttpSrcClass *klass);
static void gst_httpsrc_init(GstHttpSrc *httpsrc);
static void gst_httpsrc_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_httpsrc_get_arg(GtkObject *object,GtkArg *arg,guint id);
static GstSrcClass *parent_class = NULL;
static guint gst_httpsrc_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_httpsrc_get_type(void) {
static GtkType httpsrc_type = 0;
if (!httpsrc_type) {
static const GtkTypeInfo httpsrc_info = {
"GstHttpSrc",
sizeof(GstHttpSrc),
sizeof(GstHttpSrcClass),
(GtkClassInitFunc)gst_httpsrc_class_init,
(GtkObjectInitFunc)gst_httpsrc_init,
(GtkArgSetFunc)gst_httpsrc_set_arg,
(GtkArgGetFunc)gst_httpsrc_get_arg,
(GtkClassInitFunc)NULL,
};
httpsrc_type = gtk_type_unique(GST_TYPE_SRC,&httpsrc_info);
}
return httpsrc_type;
}
static void
gst_httpsrc_class_init(GstHttpSrcClass *klass) {
GtkObjectClass *gtkobject_class;
GstElementClass *gstelement_class;
GstSrcClass *gstsrc_class;
gtkobject_class = (GtkObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
gstsrc_class = (GstSrcClass*)klass;
parent_class = gtk_type_class(GST_TYPE_SRC);
gtk_object_add_arg_type("GstHttpSrc::location", GTK_TYPE_STRING,
GTK_ARG_READWRITE, ARG_LOCATION);
gtk_object_add_arg_type("GstHttpSrc::bytesperread", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_BYTESPERREAD);
gtkobject_class->set_arg = gst_httpsrc_set_arg;
gtkobject_class->get_arg = gst_httpsrc_get_arg;
gstelement_class->change_state = gst_httpsrc_change_state;
gstsrc_class->push = gst_httpsrc_push;
gstsrc_class->push_region = NULL;
}
static void gst_httpsrc_init(GstHttpSrc *httpsrc) {
httpsrc->srcpad = gst_pad_new("src",GST_PAD_SRC);
gst_element_add_pad(GST_ELEMENT(httpsrc),httpsrc->srcpad);
httpsrc->url = NULL;
httpsrc->request = NULL;
httpsrc->fd = 0;
httpsrc->curoffset = 0;
httpsrc->bytes_per_read = 4096;
}
static void gst_httpsrc_push(GstSrc *src) {
GstHttpSrc *httpsrc;
GstBuffer *buf;
glong readbytes;
g_return_if_fail(src != NULL);
g_return_if_fail(GST_IS_HTTPSRC(src));
// g_return_if_fail(GST_FLAG_IS_SET(src,GST_));
httpsrc = GST_HTTPSRC(src);
buf = gst_buffer_new();
GST_BUFFER_DATA(buf) = (gpointer)malloc(httpsrc->bytes_per_read);
readbytes = read(httpsrc->fd,GST_BUFFER_DATA(buf),httpsrc->bytes_per_read);
if (readbytes == 0) {
gst_src_signal_eos(GST_SRC(httpsrc));
return;
}
if (readbytes < httpsrc->bytes_per_read) {
// FIXME: set the buffer's EOF bit here
}
GST_BUFFER_OFFSET(buf) = httpsrc->curoffset;
GST_BUFFER_SIZE(buf) = readbytes;
httpsrc->curoffset += readbytes;
gst_pad_push(httpsrc->srcpad,buf);
}
static gboolean gst_httpsrc_open_url(GstHttpSrc *httpsrc) {
gint status;
g_return_if_fail(httpsrc != NULL);
g_return_if_fail(GST_IS_HTTPSRC(httpsrc));
g_return_if_fail(httpsrc->url != NULL);
httpsrc->request = ghttp_request_new();
ghttp_set_uri(httpsrc->request,httpsrc->url);
ghttp_set_sync(httpsrc->request,ghttp_async);
ghttp_set_header(httpsrc->request,"User-Agent","GstHttpSrc");
ghttp_prepare(httpsrc->request);
/* process everything up to the actual data stream */
/* FIXME: should be in preroll, but hey */
status = 0;
while ((ghttp_get_status(httpsrc->request).proc != ghttp_proc_response)
&& (status >= 0)) {
status = ghttp_process(httpsrc->request);
}
/* get the fd so we can read data ourselves */
httpsrc->fd = ghttp_get_socket(httpsrc->request);
return TRUE;
}
/* unmap and close the file */
static void gst_httpsrc_close_url(GstHttpSrc *src) {
g_return_if_fail(src->fd > 0);
close(src->fd);
src->fd = 0;
}
static void gst_httpsrc_set_arg(GtkObject *object,GtkArg *arg,guint id) {
GstHttpSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_HTTPSRC(object));
src = GST_HTTPSRC(object);
switch(id) {
case ARG_LOCATION:
/* the element must be stopped in order to do this */
g_return_if_fail(!GST_FLAG_IS_SET(src,GST_STATE_RUNNING));
if (src->url) g_free(src->url);
/* clear the url if we get a NULL (is that possible?) */
if (GTK_VALUE_STRING(*arg) == NULL) {
src->url = NULL;
gst_element_set_state(GST_ELEMENT(object),~GST_STATE_COMPLETE);
/* otherwise set the new url */
} else {
src->url = g_strdup(GTK_VALUE_STRING(*arg));
gst_element_set_state(GST_ELEMENT(object),GST_STATE_COMPLETE);
}
break;
case ARG_BYTESPERREAD:
src->bytes_per_read = GTK_VALUE_INT(*arg);
break;
default:
break;
}
}
static void gst_httpsrc_get_arg(GtkObject *object,GtkArg *arg,guint id) {
GstHttpSrc *httpsrc;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_HTTPSRC(object));
httpsrc = GST_HTTPSRC(object);
switch (id) {
case ARG_LOCATION:
GTK_VALUE_STRING(*arg) = httpsrc->url;
break;
case ARG_BYTESPERREAD:
GTK_VALUE_INT(*arg) = httpsrc->bytes_per_read;
break;
default:
arg->type = GTK_TYPE_INVALID;
break;
}
}
static gboolean gst_httpsrc_change_state(GstElement *element,
GstElementState state) {
g_return_if_fail(GST_IS_HTTPSRC(element));
switch (state) {
case GST_STATE_RUNNING:
if (!gst_httpsrc_open_url(GST_HTTPSRC(element)))
return FALSE;
break;
case ~GST_STATE_RUNNING:
gst_httpsrc_close_url(GST_HTTPSRC(element));
break;
default:
break;
}
if (GST_ELEMENT_CLASS(parent_class)->change_state)
return GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
return TRUE;
}

77
gst/elements/gsthttpsrc.h Normal file
View file

@ -0,0 +1,77 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_HTTPSRC_H__
#define __GST_HTTPSRC_H__
#include <config.h>
#include <gst/gst.h>
#include <ghttp.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_httpsrc_details;
#define GST_TYPE_HTTPSRC \
(gst_httpsrc_get_type())
#define GST_HTTPSRC(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_HTTPSRC,GstHttpSrc))
#define GST_HTTPSRC_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_HTTPSRC,GstHttpSrcClass))
#define GST_IS_HTTPSRC(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_HTTPSRC))
#define GST_IS_HTTPSRC_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_HTTPSRC)))
typedef struct _GstHttpSrc GstHttpSrc;
typedef struct _GstHttpSrcClass GstHttpSrcClass;
struct _GstHttpSrc {
GstSrc src;
/* pads */
GstPad *srcpad;
gchar *url;
ghttp_request *request;
int fd;
gulong curoffset; /* current offset in file */
gulong bytes_per_read; /* bytes per read */
};
struct _GstHttpSrcClass {
GstSrcClass parent_class;
};
GtkType gst_httpsrc_get_type(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_HTTPSRC_H__ */

152
gst/elements/gstidentity.c Normal file
View file

@ -0,0 +1,152 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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 <gstidentity.h>
GstElementDetails gst_identity_details = {
"Identity",
"Filter",
"Pass data without modification",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
/* Identity signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
ARG_CONTROL
};
static void gst_identity_class_init(GstIdentityClass *klass);
static void gst_identity_init(GstIdentity *identity);
static void gst_identity_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_identity_get_arg(GtkObject *object,GtkArg *arg,guint id);
static GstFilterClass *parent_class = NULL;
static guint gst_identity_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_identity_get_type(void) {
static GtkType identity_type = 0;
if (!identity_type) {
static const GtkTypeInfo identity_info = {
"GstIdentity",
sizeof(GstIdentity),
sizeof(GstIdentityClass),
(GtkClassInitFunc)gst_identity_class_init,
(GtkObjectInitFunc)gst_identity_init,
(GtkArgSetFunc)gst_identity_set_arg,
(GtkArgGetFunc)gst_identity_get_arg,
(GtkClassInitFunc)NULL,
};
identity_type = gtk_type_unique(GST_TYPE_FILTER,&identity_info);
}
return identity_type;
}
static void gst_identity_class_init(GstIdentityClass *klass) {
GtkObjectClass *gtkobject_class;
GstFilterClass *gstfilter_class;
gtkobject_class = (GtkObjectClass*)klass;
gstfilter_class = (GstFilterClass*)klass;
parent_class = gtk_type_class(GST_TYPE_FILTER);
gtk_object_add_arg_type("GstIdentity::control", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_CONTROL);
gtkobject_class->set_arg = gst_identity_set_arg;
gtkobject_class->get_arg = gst_identity_get_arg;
}
static void gst_identity_init(GstIdentity *identity) {
identity->sinkpad = gst_pad_new("sink",GST_PAD_SINK);
gst_element_add_pad(GST_ELEMENT(identity),identity->sinkpad);
gst_pad_set_chain_function(identity->sinkpad,gst_identity_chain);
identity->srcpad = gst_pad_new("src",GST_PAD_SRC);
gst_element_add_pad(GST_ELEMENT(identity),identity->srcpad);
identity->control = 0;
}
GstElement *gst_identity_new(gchar *name) {
GstElement *identity = GST_ELEMENT(gtk_type_new(GST_TYPE_IDENTITY));
gst_element_set_name(GST_ELEMENT(identity),name);
return identity;
}
void gst_identity_chain(GstPad *pad,GstBuffer *buf) {
GstIdentity *identity;
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail(buf != NULL);
identity = GST_IDENTITY(pad->parent);
// g_print("gst_identity_chain: got buffer in '%s'\n",
// gst_element_get_name(GST_ELEMENT(identity)));
g_print("i");
gst_pad_push(identity->srcpad,buf);
}
static void gst_identity_set_arg(GtkObject *object,GtkArg *arg,guint id) {
GstIdentity *identity;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_IDENTITY(object));
identity = GST_IDENTITY(object);
switch(id) {
case ARG_CONTROL:
identity->control = GTK_VALUE_INT(*arg);
break;
default:
break;
}
}
static void gst_identity_get_arg(GtkObject *object,GtkArg *arg,guint id) {
GstIdentity *identity;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_IDENTITY(object));
identity = GST_IDENTITY(object);
switch (id) {
case ARG_CONTROL:
GTK_VALUE_INT(*arg) = identity->control;
break;
default:
arg->type = GTK_TYPE_INVALID;
break;
}
}

View file

@ -0,0 +1,74 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_IDENTITY_H__
#define __GST_IDENTITY_H__
#include <config.h>
#include <gst/gst.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_identity_details;
#define GST_TYPE_IDENTITY \
(gst_identity_get_type())
#define GST_IDENTITY(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_IDENTITY,GstIdentity))
#define GST_IDENTITY_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_IDENTITY,GstIdentityClass))
#define GST_IS_IDENTITY(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_IDENTITY))
#define GST_IS_IDENTITY_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_IDENTITY)))
typedef struct _GstIdentity GstIdentity;
typedef struct _GstIdentityClass GstIdentityClass;
struct _GstIdentity {
GstFilter filter;
GstPad *sinkpad;
GstPad *srcpad;
gint control;
};
struct _GstIdentityClass {
GstFilterClass parent_class;
};
GtkType gst_identity_get_type(void);
GstElement *gst_identity_new(gchar *name);
void gst_identity_chain(GstPad *pad,GstBuffer *buf);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_IDENTITY_H__ */

216
gst/elements/gstqueue.c Normal file
View file

@ -0,0 +1,216 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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 <gstqueue.h>
GstElementDetails gst_queue_details = {
"Queue",
"Connection",
"Simple data queue",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
/* Queue signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
ARG_LEVEL,
};
static void gst_queue_class_init(GstQueueClass *klass);
static void gst_queue_init(GstQueue *queue);
static void gst_queue_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_queue_get_arg(GtkObject *object,GtkArg *arg,guint id);
static GstConnectionClass *parent_class = NULL;
static guint gst_queue_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_queue_get_type(void) {
static GtkType queue_type = 0;
if (!queue_type) {
static const GtkTypeInfo queue_info = {
"GstQueue",
sizeof(GstQueue),
sizeof(GstQueueClass),
(GtkClassInitFunc)gst_queue_class_init,
(GtkObjectInitFunc)gst_queue_init,
(GtkArgSetFunc)gst_queue_set_arg,
(GtkArgGetFunc)gst_queue_get_arg,
(GtkClassInitFunc)NULL,
};
queue_type = gtk_type_unique(GST_TYPE_CONNECTION,&queue_info);
}
return queue_type;
}
static void gst_queue_class_init(GstQueueClass *klass) {
GtkObjectClass *gtkobject_class;
GstConnectionClass *gstconnection_class;
gtkobject_class = (GtkObjectClass*)klass;
gstconnection_class = (GstConnectionClass*)klass;
parent_class = gtk_type_class(GST_TYPE_CONNECTION);
gtk_object_add_arg_type("GstQueue::level", GTK_TYPE_INT,
GTK_ARG_READABLE, ARG_LEVEL);
gstconnection_class->push = gst_queue_push;
gtkobject_class->set_arg = gst_queue_set_arg;
gtkobject_class->get_arg = gst_queue_get_arg;
}
static void gst_queue_init(GstQueue *queue) {
queue->sinkpad = gst_pad_new("sink",GST_PAD_SINK);
gst_element_add_pad(GST_ELEMENT(queue),queue->sinkpad);
gst_pad_set_chain_function(queue->sinkpad,gst_queue_chain);
queue->srcpad = gst_pad_new("src",GST_PAD_SRC);
gst_element_add_pad(GST_ELEMENT(queue),queue->srcpad);
queue->queue = NULL;
queue->tail = NULL;
queue->level_buffers = 0;
queue->level_bytes = 0;
queue->size_buffers = 0;
queue->size_bytes = 0;
queue->waiterlock = g_mutex_new();
queue->waitercond = g_cond_new();
}
GstElement *gst_queue_new(gchar *name) {
GstElement *queue = GST_ELEMENT(gtk_type_new(GST_TYPE_QUEUE));
gst_element_set_name(GST_ELEMENT(queue),name);
return queue;
}
void gst_queue_chain(GstPad *pad,GstBuffer *buf) {
GstQueue *queue;
gboolean tosignal = FALSE;
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail(buf != NULL);
queue = GST_QUEUE(pad->parent);
/* we have to lock the queue since we span threads */
GST_LOCK(queue);
/* put the buffer on the head of the list */
/* if the queue is NULL, start a new list and make this the tail */
if (!queue->queue) {
queue->queue = g_list_prepend(queue->queue,buf);
// queue->tail = queue->queue;
/* otherwise append to the end of the list */
} else {
// queue->tail = g_list_append(queue->tail,buf);
// queue->tail = g_list_next(queue->tail);
queue->queue = g_list_append(queue->queue,buf);
}
// g_print("+");
/* if we were empty, but aren't any more, signal a condition */
tosignal = (queue->level_buffers++ == 0);
/* we can unlock now */
GST_UNLOCK(queue);
if (tosignal) {
g_mutex_lock(queue->waiterlock);
g_cond_signal(queue->waitercond);
g_mutex_unlock(queue->waiterlock);
// g_print(">");
}
}
void gst_queue_push(GstConnection *connection) {
GstQueue *queue = GST_QUEUE(connection);
GstBuffer *buf = NULL;
GList *front;
/* have to lock for thread-safety */
GST_LOCK(queue);
if (!queue->level_buffers) {
GST_UNLOCK(queue);
while (!queue->level_buffers) {
g_mutex_lock(queue->waiterlock);
// g_print("0");
g_cond_wait(queue->waitercond,queue->waiterlock);
g_mutex_unlock(queue->waiterlock);
}
GST_LOCK(queue);
}
front = queue->queue;
buf = (GstBuffer *)(front->data);
queue->queue = g_list_remove_link(queue->queue,front);
gst_pad_push(queue->srcpad,buf);
queue->level_buffers--;
// g_print("-");
/* unlock now */
GST_UNLOCK(queue);
}
static void gst_queue_set_arg(GtkObject *object,GtkArg *arg,guint id) {
GstQueue *queue;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_QUEUE(object));
queue = GST_QUEUE(object);
switch(id) {
default:
break;
}
}
static void gst_queue_get_arg(GtkObject *object,GtkArg *arg,guint id) {
GstQueue *queue;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_QUEUE(object));
queue = GST_QUEUE(object);
switch (id) {
case ARG_LEVEL:
GTK_VALUE_INT(*arg) = queue->level_buffers;
break;
default:
arg->type = GTK_TYPE_INVALID;
break;
}
}

84
gst/elements/gstqueue.h Normal file
View file

@ -0,0 +1,84 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_QUEUE_H__
#define __GST_QUEUE_H__
#include <config.h>
#include <gst/gst.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_queue_details;
#define GST_TYPE_QUEUE \
(gst_queue_get_type())
#define GST_QUEUE(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_QUEUE,GstQueue))
#define GST_QUEUE_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_QUEUE,GstQueueClass))
#define GST_IS_QUEUE(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_QUEUE))
#define GST_IS_QUEUE_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_QUEUE)))
typedef struct _GstQueue GstQueue;
typedef struct _GstQueueClass GstQueueClass;
struct _GstQueue {
GstConnection Connection;
GstPad *sinkpad;
GstPad *srcpad;
/* the queue of buffers we're keeping our grubby hands on */
GList *queue;
GList *tail; /* have to keep track of this myself */
gint level_buffers; /* number of buffers queued here */
gint level_bytes; /* number of bytes queued here */
gint size_buffers; /* size of queue in buffers */
gint size_bytes; /* size of queue in bytes */
GMutex *waiterlock; /* used when the queue is empty */
GCond *waitercond;
};
struct _GstQueueClass {
GstConnectionClass parent_class;
};
GtkType gst_queue_get_type(void);
GstElement *gst_queue_new(gchar *name);
void gst_queue_chain(GstPad *pad,GstBuffer *buf);
void gst_queue_push(GstConnection *connection);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_QUEUE_H__ */

269
gst/elements/gstsinesrc.c Normal file
View file

@ -0,0 +1,269 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/soundcard.h>
#include <math.h>
#include <gstsinesrc.h>
GstElementDetails gst_sinesrc_details = {
"Sine-wave src",
"Source/Audio",
"Create a sine wave of a given frequency and volume",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
/* SineSrc signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
ARG_VOLUME,
ARG_FREQ,
ARG_FORMAT,
ARG_CHANNELS,
ARG_FREQUENCY,
};
static void gst_sinesrc_class_init(GstSineSrcClass *klass);
static void gst_sinesrc_init(GstSineSrc *sinesrc);
static void gst_sinesrc_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_sinesrc_get_arg(GtkObject *object,GtkArg *arg,guint id);
//static gboolean gst_sinesrc_change_state(GstElement *element,
// GstElementState state);
static void gst_sinesrc_close_audio(GstSineSrc *src);
static gboolean gst_sinesrc_open_audio(GstSineSrc *src);
void gst_sinesrc_sync_parms(GstSineSrc *sinesrc);
static GstSrcClass *parent_class = NULL;
static guint gst_sinesrc_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_sinesrc_get_type(void) {
static GtkType sinesrc_type = 0;
if (!sinesrc_type) {
static const GtkTypeInfo sinesrc_info = {
"GstSineSrc",
sizeof(GstSineSrc),
sizeof(GstSineSrcClass),
(GtkClassInitFunc)gst_sinesrc_class_init,
(GtkObjectInitFunc)gst_sinesrc_init,
(GtkArgSetFunc)gst_sinesrc_set_arg,
(GtkArgGetFunc)gst_sinesrc_get_arg,
(GtkClassInitFunc)NULL,
};
sinesrc_type = gtk_type_unique(GST_TYPE_SRC,&sinesrc_info);
}
return sinesrc_type;
}
static void
gst_sinesrc_class_init(GstSineSrcClass *klass) {
GtkObjectClass *gtkobject_class;
GstElementClass *gstelement_class;
GstSrcClass *gstsrc_class;
gtkobject_class = (GtkObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
gstsrc_class = (GstSrcClass*)klass;
parent_class = gtk_type_class(GST_TYPE_SRC);
gtk_object_add_arg_type("GstSineSrc::volume", GTK_TYPE_DOUBLE,
GTK_ARG_READWRITE, ARG_VOLUME);
gtk_object_add_arg_type("GstSineSrc::freq", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_FREQ);
gtk_object_add_arg_type("GstSineSrc::format", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_FORMAT);
gtk_object_add_arg_type("GstSineSrc::channels", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_CHANNELS);
gtk_object_add_arg_type("GstSineSrc::frequency", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_FREQUENCY);
gtkobject_class->set_arg = gst_sinesrc_set_arg;
gtkobject_class->get_arg = gst_sinesrc_get_arg;
// gstelement_class->change_state = gst_sinesrc_change_state;
gstsrc_class->push = gst_sinesrc_push;
}
static void gst_sinesrc_init(GstSineSrc *sinesrc) {
sinesrc->srcpad = gst_pad_new("src",GST_PAD_SRC);
gst_element_add_pad(GST_ELEMENT(sinesrc),sinesrc->srcpad);
sinesrc->volume = 1.0;
sinesrc->freq = 512;
sinesrc->format = AFMT_S16_LE;
sinesrc->channels = 2;
sinesrc->frequency = 44100;
sinesrc->seq = 0;
sinesrc->sentmeta = FALSE;
}
GstElement *gst_sinesrc_new(gchar *name) {
GstElement *sinesrc = GST_ELEMENT(gtk_type_new(GST_TYPE_SINESRC));
gst_element_set_name(GST_ELEMENT(sinesrc),name);
return sinesrc;
}
GstElement *gst_sinesrc_new_with_fd(gchar *name,gchar *filename) {
GstElement *sinesrc = gst_sinesrc_new(name);
gtk_object_set(GTK_OBJECT(sinesrc),"location",filename,NULL);
return sinesrc;
}
void gst_sinesrc_push(GstSrc *src) {
GstSineSrc *sinesrc;
GstBuffer *buf;
gint16 *samples;
gint i;
gint volume;
gdouble val;
g_return_if_fail(src != NULL);
g_return_if_fail(GST_IS_SINESRC(src));
sinesrc = GST_SINESRC(src);
buf = gst_buffer_new();
g_return_if_fail(buf);
GST_BUFFER_DATA(buf) = (gpointer)malloc(4096);
samples = (gint16*)GST_BUFFER_DATA(buf);
GST_BUFFER_DATA(buf) = 4096;
volume = 65535 * sinesrc->volume;
for (i=0;i<1024;i++) {
val = sin((gdouble)i/sinesrc->frequency);
samples[i] = val * volume;
samples[i+1] = samples[i];
}
if (!sinesrc->sentmeta) {
MetaAudioRaw *newmeta = g_new(MetaAudioRaw,1);
memcpy(newmeta,&sinesrc->meta,sizeof(MetaAudioRaw));
gst_buffer_add_meta(buf,GST_META(newmeta));
sinesrc->sentmeta = TRUE;
}
gst_pad_push(sinesrc->srcpad,buf);
g_print(">");
}
static void gst_sinesrc_set_arg(GtkObject *object,GtkArg *arg,guint id) {
GstSineSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_SINESRC(object));
src = GST_SINESRC(object);
switch (id) {
case ARG_VOLUME:
src->volume = GTK_VALUE_DOUBLE(*arg);
break;
case ARG_FREQ:
src->freq = GTK_VALUE_INT(*arg);
break;
case ARG_FORMAT:
src->format = GTK_VALUE_INT(*arg);
break;
case ARG_CHANNELS:
src->channels = GTK_VALUE_INT(*arg);
break;
case ARG_FREQUENCY:
src->frequency = GTK_VALUE_INT(*arg);
break;
default:
break;
}
}
static void gst_sinesrc_get_arg(GtkObject *object,GtkArg *arg,guint id) {
GstSineSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_SINESRC(object));
src = GST_SINESRC(object);
switch (id) {
case ARG_VOLUME:
GTK_VALUE_DOUBLE(*arg) = src->volume;
break;
case ARG_FREQ:
GTK_VALUE_INT(*arg) = src->freq;
break;
case ARG_FORMAT:
GTK_VALUE_INT(*arg) = src->format;
break;
case ARG_CHANNELS:
GTK_VALUE_INT(*arg) = src->channels;
break;
case ARG_FREQUENCY:
GTK_VALUE_INT(*arg) = src->frequency;
break;
default:
arg->type = GTK_TYPE_INVALID;
break;
}
}
/*
static gboolean gst_sinesrc_change_state(GstElement *element,
GstElementState state) {
g_return_if_fail(GST_IS_SINESRC(element));
switch (state) {
case GST_STATE_RUNNING:
if (!gst_sinesrc_open_audio(GST_SINESRC(element)))
return FALSE;
break;
case ~GST_STATE_RUNNING:
gst_sinesrc_close_audio(GST_SINESRC(element));
break;
default:
break;
}
if (GST_ELEMENT_CLASS(parent_class)->change_state)
return GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
return TRUE;
}
*/
void gst_sinesrc_sync_parms(GstSineSrc *sinesrc) {
sinesrc->meta.format = sinesrc->format;
sinesrc->meta.channels = sinesrc->channels;
sinesrc->meta.frequency = sinesrc->frequency;
sinesrc->sentmeta = FALSE;
}

87
gst/elements/gstsinesrc.h Normal file
View file

@ -0,0 +1,87 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_SINESRC_H__
#define __GST_SINESRC_H__
#include <config.h>
#include <gst/gst.h>
#include <gst/meta/audioraw.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_sinesrc_details;
#define GST_TYPE_SINESRC \
(gst_sinesrc_get_type())
#define GST_SINESRC(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_SINESRC,GstSineSrc))
#define GST_SINESRC_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_SINESRC,GstSineSrcClass))
#define GST_IS_SINESRC(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_SINESRC))
#define GST_IS_SINESRC_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_SINESRC)))
typedef struct _GstSineSrc GstSineSrc;
typedef struct _GstSineSrcClass GstSineSrcClass;
struct _GstSineSrc {
GstSrc src;
/* pads */
GstPad *srcpad;
/* parameters */
gdouble volume;
gint freq;
/* audio parameters */
gint format;
gint channels;
gint frequency;
gulong seq;
MetaAudioRaw meta;
gboolean sentmeta;
};
struct _GstSineSrcClass {
GstSrcClass parent_class;
};
GtkType gst_sinesrc_get_type(void);
GstElement *gst_sinesrc_new(gchar *name);
void gst_sinesrc_push(GstSrc *src);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_SINESRC_H__ */

60
gst/gst.c Normal file
View file

@ -0,0 +1,60 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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>
extern gint _gst_trace_on;
/**
* gst_init:
* @argc: pointer to application's argc
* @argv: pointer to application's argv
*
* Initializes the GStreamer system, setting up internal lists and loading
* standard plugins.
*/
void gst_init(int *argc,char **argv[]) {
GstTrace *gst_trace;
GstElementFactory *factory;
gtk_init(argc,argv);
if (!g_thread_supported()) g_thread_init (NULL);
_gst_type_initialize();
_gst_plugin_initialize();
_gst_buffer_initialize();
/* register some standard builtin types */
gst_elementfactory_register(gst_elementfactory_new(
"bin",gst_bin_get_type(),&gst_bin_details));
gst_elementfactory_register(gst_elementfactory_new(
"pipeline",gst_pipeline_get_type(),&gst_pipeline_details));
gst_elementfactory_register(gst_elementfactory_new(
"thread",gst_thread_get_type(),&gst_thread_details));
gst_plugin_load("libgsttypes.so");
gst_plugin_load("libgstelements.so");
_gst_trace_on = 0;
if (_gst_trace_on) {
gst_trace = gst_trace_new("gst.trace",1024);
gst_trace_set_default(gst_trace);
}
}

60
gst/gst.h Normal file
View file

@ -0,0 +1,60 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_H__
#define __GST_H__
#include <gtk/gtk.h>
#include <gst/gstlog.h>
#include <gst/gstobject.h>
#include <gst/gstpad.h>
#include <gst/gstbuffer.h>
#include <gst/gstelement.h>
#include <gst/gstbin.h>
#include <gst/gstpipeline.h>
#include <gst/gstthread.h>
#include <gst/gstsrc.h>
#include <gst/gstfilter.h>
#include <gst/gstsink.h>
#include <gst/gstconnection.h>
#include <gst/gsttype.h>
#include <gst/gstplugin.h>
#include <gst/gstutils.h>
#include <gst/gsttrace.h>
#include <gst/gstxml.h>
#include <gst/gsttee.h>
/* initialize GST */
void gst_init(int *argc,char **argv[]);
/* debugging */
#ifndef DEBUG
#ifdef DEBUG_ENABLED
#define DEBUG(format,args...) g_print("DEBUG: " format, ##args)
#else
#define DEBUG(format,args...)
#endif
#endif
#endif /* __GST_H__ */

449
gst/gstbin.c Normal file
View file

@ -0,0 +1,449 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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>
GstElementDetails gst_bin_details = {
"Generic bin",
"Bin",
"Simple container object",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
void gst_bin_real_destroy(GtkObject *object);
static gboolean gst_bin_change_state(GstElement *element,
GstElementState state);
static gboolean gst_bin_change_state_type(GstBin *bin,
GstElementState state,
GtkType type);
static gboolean gst_bin_change_state_norecurse(GstElement *element,
GstElementState state);
static void gst_bin_create_plan_func(GstBin *bin);
static void gst_bin_iterate_func(GstBin *bin);
static xmlNodePtr gst_bin_save_thyself(GstElement *element,xmlNodePtr parent);
/* Bin signals and args */
enum {
OBJECT_ADDED,
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
static void gst_bin_class_init(GstBinClass *klass);
static void gst_bin_init(GstBin *bin);
static GstElementClass *parent_class = NULL;
static guint gst_bin_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_bin_get_type(void) {
static GtkType bin_type = 0;
if (!bin_type) {
static const GtkTypeInfo bin_info = {
"GstBin",
sizeof(GstBin),
sizeof(GstBinClass),
(GtkClassInitFunc)gst_bin_class_init,
(GtkObjectInitFunc)gst_bin_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
bin_type = gtk_type_unique(GST_TYPE_ELEMENT,&bin_info);
}
return bin_type;
}
static void
gst_bin_class_init(GstBinClass *klass) {
GtkObjectClass *gtkobject_class;
GstElementClass *gstelement_class;
gtkobject_class = (GtkObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
parent_class = gtk_type_class(GST_TYPE_ELEMENT);
gst_bin_signals[OBJECT_ADDED] =
gtk_signal_new("object_added",GTK_RUN_FIRST,gtkobject_class->type,
GTK_SIGNAL_OFFSET(GstBinClass,object_added),
gtk_marshal_NONE__POINTER,GTK_TYPE_NONE,1,
GTK_TYPE_POINTER);
gtk_object_class_add_signals(gtkobject_class,gst_bin_signals,LAST_SIGNAL);
klass->change_state_type = gst_bin_change_state_type;
klass->create_plan = gst_bin_create_plan_func;
klass->iterate = gst_bin_iterate_func;
gstelement_class->change_state = gst_bin_change_state;
gstelement_class->save_thyself = gst_bin_save_thyself;
gtkobject_class->destroy = gst_bin_real_destroy;
}
static void gst_bin_init(GstBin *bin) {
bin->numchildren = 0;
bin->children = NULL;
}
/**
* gst_bin_new:
* @name: name of new bin
*
* Create a new bin with given name.
*
* Returns: new bin
*/
GstElement *gst_bin_new(gchar *name) {
GstElement *bin = GST_ELEMENT(gtk_type_new(GST_TYPE_BIN));
gst_element_set_name(GST_ELEMENT(bin),name);
return bin;
}
/**
* gst_bin_add:
* @bin: #GstBin to add element to
* @element: #GstElement to add to bin
*
* Add the given element to the bin. Set the elements parent, and thus
* add a reference.
*/
void gst_bin_add(GstBin *bin,GstElement *element) {
g_return_if_fail(bin != NULL);
g_return_if_fail(GST_IS_BIN(bin));
g_return_if_fail(element != NULL);
g_return_if_fail(GST_IS_ELEMENT(element));
bin->children = g_list_append(bin->children,element);
bin->numchildren++;
gst_object_set_parent(GST_OBJECT(element),GST_OBJECT(bin));
if (GST_STATE_IS_SET(element,GST_STATE_COMPLETE)) {
if (!GST_STATE_IS_SET(bin,GST_STATE_COMPLETE))
gst_bin_change_state_norecurse(GST_ELEMENT(bin),GST_STATE_COMPLETE);
} else
gst_bin_change_state_norecurse(GST_ELEMENT(bin),~GST_STATE_COMPLETE);
gtk_signal_emit(GTK_OBJECT(bin),gst_bin_signals[OBJECT_ADDED],element);
}
/**
* gst_bin_remove:
* @bin: #Gstbin to remove element from
* @element: #GstElement to remove
*
* Remove the element from its associated bin, unparenting as well.
*/
void gst_bin_remove(GstBin *bin,GstElement *element) {
g_return_if_fail(bin != NULL);
g_return_if_fail(GST_IS_BIN(bin));
g_return_if_fail(element != NULL);
g_return_if_fail(GST_IS_ELEMENT(element));
g_return_if_fail(bin->children != NULL);
gst_object_unparent(GST_OBJECT(element));
bin->children = g_list_remove(bin->children,element);
bin->numchildren--;
}
static gboolean gst_bin_change_state(GstElement *element,
GstElementState state) {
GstBin *bin;
GList *children;
GstElement *child;
// g_print("gst_bin_change_state(\"%s\",%d);\n",
// gst_object_get_name(GST_OBJECT(bin)),state);
g_return_if_fail(GST_IS_BIN(element));
bin = GST_BIN(element);
g_return_if_fail(bin->numchildren != 0);
// g_print("-->\n");
children = bin->children;
while (children) {
child = GST_ELEMENT(children->data);
// g_print("gst_bin_change_state setting state on \"%s\"\n",
// gst_object_get_name(GST_OBJECT(child)));
if (!gst_element_set_state(child,state)) {
g_print("child %p failed to set state 0x%08x\n",child,state);
return FALSE;
}
// g_print("\n");
children = g_list_next(children);
}
// g_print("<-- \"%s\"\n",gst_object_get_name(GST_OBJECT(bin)));
if (GST_ELEMENT_CLASS(parent_class)->change_state)
return GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
return TRUE;
}
static gboolean gst_bin_change_state_norecurse(GstElement *element,
GstElementState state) {
GstBin *bin;
g_return_if_fail(GST_IS_BIN(element));
bin = GST_BIN(element);
g_return_if_fail(bin->numchildren != 0);
if (GST_ELEMENT_CLASS(parent_class)->change_state)
return GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
return TRUE;
}
static gboolean gst_bin_change_state_type(GstBin *bin,
GstElementState state,
GtkType type) {
GList *children;
GstElement *child;
// g_print("gst_bin_change_state_type(\"%s\",%d,%d);\n",
// gst_object_get_name(GST_OBJECT(bin)),state,type);
g_return_if_fail(GST_IS_BIN(bin));
g_return_if_fail(bin->numchildren != 0);
// g_print("-->\n");
children = bin->children;
while (children) {
child = GST_ELEMENT(children->data);
if (GST_IS_BIN(child)) {
if (!gst_bin_set_state_type(GST_BIN(child),state,type))
return FALSE;
} else if (GTK_CHECK_TYPE(child,type)) {
if (!gst_element_set_state(child,state))
return FALSE;
}
// g_print("\n");
children = g_list_next(children);
}
// g_print("<-- \"%s\"\n",gst_object_get_name(GST_OBJECT(bin)));
if (type == GST_TYPE_BIN)
gst_element_change_state(GST_ELEMENT(bin),state);
return TRUE;
}
gboolean gst_bin_set_state_type(GstBin *bin,
GstElementState state,
GtkType type) {
GstBinClass *oclass;
// g_print("gst_bin_set_state_type(\"%s\",%d,%d)\n",
// gst_object_get_name(GST_OBJECT(bin)),state,type);
g_return_if_fail(bin != NULL);
g_return_if_fail(GST_IS_BIN(bin));
oclass = GST_BIN_CLASS(GTK_OBJECT(bin)->klass);
if (oclass->change_state_type)
(oclass->change_state_type)(bin,state,type);
}
void gst_bin_real_destroy(GtkObject *object) {
GstBin *bin = GST_BIN(object);
GList *children;
GstElement *child;
// g_print("in gst_bin_real_destroy()\n");
children = bin->children;
while (children) {
child = GST_ELEMENT(children->data);
gst_element_destroy(child);
children = g_list_next(children);
}
g_list_free(bin->children);
}
GstElement *gst_bin_get_by_name(GstBin *bin,gchar *name) {
GList *children;
GstElement *child;
g_return_if_fail(bin != NULL);
g_return_if_fail(GST_IS_BIN(bin));
g_return_if_fail(name != NULL);
children = bin->children;
while (children) {
child = GST_ELEMENT(children->data);
if (!strcmp(child->name,name))
return child;
children = g_list_next(children);
}
return NULL;
}
GList *gst_bin_get_list(GstBin *bin) {
g_return_if_fail(bin != NULL);
g_return_if_fail(GST_IS_BIN(bin));
return bin->children;
}
static xmlNodePtr gst_bin_save_thyself(GstElement *element,xmlNodePtr parent) {
GstBin *bin = GST_BIN(element);
xmlNodePtr childlist;
GList *children;
GstElement *child;
if (GST_ELEMENT_CLASS(parent_class)->save_thyself)
GST_ELEMENT_CLASS(parent_class)->save_thyself(GST_ELEMENT(bin),parent);
childlist = xmlNewChild(parent,NULL,"children",NULL);
children = bin->children;
while (children) {
child = GST_ELEMENT(children->data);
gst_element_save_thyself(child,childlist);
children = g_list_next(children);
}
}
void gst_bin_iterate(GstBin *bin) {
GstBinClass *oclass;
oclass = GST_BIN_CLASS(GTK_OBJECT(bin)->klass);
if (oclass->iterate)
(oclass->iterate)(bin);
}
void gst_bin_create_plan(GstBin *bin) {
GstBinClass *oclass;
oclass = GST_BIN_CLASS(GTK_OBJECT(bin)->klass);
if (oclass->create_plan)
(oclass->create_plan)(bin);
}
static void gst_bin_create_plan_func(GstBin *bin) {
GList *elements;
GstElement *element;
GList *pads;
GstPad *pad, *peer;
GstElement *outside;
bin->numentries = 0;
g_print("attempting to create a plan for bin %p\n",bin);
/* walk through all the elements to figure out all kinds of things */
elements = GST_BIN(bin)->children;
while (elements) {
element = GST_ELEMENT(elements->data);
// have to use cothreads if any elements use loop functions
if (element->loopfunc != NULL) {
if (bin->threadcontext == NULL) {
g_print("initializing cothread context\n");
bin->threadcontext = cothread_init();
}
if (element->threadstate == NULL) {
g_print("creating thread state for element\n");
element->threadstate = cothread_create(bin->threadcontext);
cothread_setfunc(element->threadstate,gst_element_loopfunc_wrapper,
0,element);
}
}
/* we need to find all the entry points into the bin */
if (GST_IS_SRC(element)) {
g_print("element '%s' is a source entry point for the bin\n",
gst_element_get_name(GST_ELEMENT(element)));
bin->entries = g_list_prepend(bin->entries,element);
bin->numentries++;
} else {
/* go through the list of pads to see if there's a Connection */
pads = gst_element_get_pad_list(element);
while (pads) {
pad = GST_PAD(pads->data);
/* we only worry about sink pads */
if (gst_pad_get_direction(pad) == GST_PAD_SINK) {
/* get the pad's peer */
peer = gst_pad_get_peer(pad);
if (!peer) break;
/* get the parent of the peer of the pad */
outside = GST_ELEMENT(gst_pad_get_parent(peer));
if (!outside) break;
/* if it's a connection and it's not ours... */
if (GST_IS_CONNECTION(outside) &&
(gst_object_get_parent(GST_OBJECT(outside)) != GST_OBJECT(bin))) {
g_print("element '%s' is the external source Connection \
for internal element '%s'\n",
gst_element_get_name(GST_ELEMENT(outside)),
gst_element_get_name(GST_ELEMENT(element)));
bin->entries = g_list_prepend(bin->entries,outside);
bin->numentries++;
}
}
pads = g_list_next(pads);
}
}
elements = g_list_next(elements);
}
g_print("have %d entries into bin\n",bin->numentries);
}
void gst_bin_iterate_func(GstBin *bin) {
GList *entries;
GstElement *entry;
g_return_if_fail(bin != NULL);
g_return_if_fail(GST_IS_BIN(bin));
// g_return_if_fail(GST_FLAG_IS_SET(thread,GST_STATE_RUNNING));
g_return_if_fail(bin->numentries > 0);
entries = bin->entries;
g_print("iterating\n");
while (entries) {
entry = GST_ELEMENT(entries->data);
if (GST_IS_SRC(entry))
gst_src_push(GST_SRC(entry));
else if (GST_IS_CONNECTION(entry))
gst_connection_push(GST_CONNECTION(entry));
else
g_assert_not_reached();
entries = g_list_next(entries);
}
// g_print(",");
}

106
gst/gstbin.h Normal file
View file

@ -0,0 +1,106 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_BIN_H__
#define __GST_BIN_H__
#include <gst/gstelement.h>
#include <gst/gstsrc.h>
#include <gst/gstconnection.h>
#include <gst/cothreads.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_bin_details;
#define GST_TYPE_BIN \
(gst_bin_get_type())
#define GST_BIN(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_BIN,GstBin))
#define GST_BIN_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_BIN,GstBinClass))
#define GST_IS_BIN(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_BIN))
#define GST_IS_BIN_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_BIN)))
typedef struct _GstBin GstBin;
typedef struct _GstBinClass GstBinClass;
struct _GstBin {
GstElement element;
gint numchildren;
GList *children;
GList *entries;
gint numentries;
cothread_context *threadcontext;
};
struct _GstBinClass {
GstElementClass parent_class;
void (*object_added) (GstObject *object,GstObject *child);
/* change the state of elements of the given type */
gboolean (*change_state_type) (GstBin *bin,
GstElementState state,
GtkType type);
/* create a plan for the execution of the bin */
void (*create_plan) (GstBin *bin);
/* run a full iteration of operation */
void (*iterate) (GstBin *bin);
};
GtkType gst_bin_get_type(void);
GstElement *gst_bin_new(gchar *name);
/* add and remove elements from the bin */
void gst_bin_add(GstBin *bin,GstElement *element);
void gst_bin_remove(GstBin *bin,GstElement *element);
/* retrieve a single element or the while list of children */
GstElement *gst_bin_get_by_name(GstBin *bin,gchar *name);
GList *gst_bin_get_list(GstBin *bin);
/* set the state for only elements of the given type */
gboolean gst_bin_set_state_type(GstBin *bin,
GstElementState state,
GtkType type);
void gst_bin_iterate(GstBin *bin);
void gst_bin_create_plan(GstBin *bin);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_BIN_H__ */

241
gst/gstbuffer.c Normal file
View file

@ -0,0 +1,241 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/gstbuffer.h>
//#define DEBUG(format,args...) g_print("DEBUG: " format, ##args)
#define DEBUG(format,args...)
GMemChunk *_gst_buffer_chunk;
void _gst_buffer_initialize() {
_gst_buffer_chunk = g_mem_chunk_new("GstBuffer",sizeof(GstBuffer),
sizeof(GstBuffer)*16,G_ALLOC_AND_FREE);
}
/**
* gst_buffer_new:
*
* Create a new buffer.
*
* Returns: new buffer
*/
GstBuffer *gst_buffer_new() {
GstBuffer *buffer;
buffer = g_mem_chunk_alloc(_gst_buffer_chunk);
DEBUG("BUF: allocating new buffer %p\n",buffer);
// g_print("allocating new mutex\n");
buffer->lock = g_mutex_new();
#ifdef HAVE_ATOMIC_H
atomic_set(&buffer->refcount,1);
#else
buffer->refcount = 1;
#endif
buffer->flags = 0;
buffer->type = 0;
buffer->data = NULL;
buffer->size = 0;
buffer->maxsize = 0;
buffer->offset = 0;
buffer->timestamp = 0;
buffer->metas = NULL;
buffer->parent = NULL;
return buffer;
}
/**
* gst_buffer_create_sub:
* @parent: parent buffer
* @offset: offset into parent buffer
* @size: size of new subbuffer
*
* Creates a sub-buffer from the parent at a given offset.
*
* Returns: new buffer
*/
GstBuffer *gst_buffer_create_sub(GstBuffer *parent,guint32 offset,guint32 size) {
GstBuffer *buffer;
g_return_if_fail(parent != NULL);
g_return_if_fail(size > 0);
g_return_if_fail((offset+size) <= parent->size);
buffer = g_mem_chunk_alloc(_gst_buffer_chunk);
DEBUG("BUF: allocating new subbuffer %p, parent %p\n",buffer,parent);
buffer->lock = g_mutex_new();
#ifdef HAVE_ATOMIC_H
atomic_set(&buffer->refcount,1);
#else
buffer->refcount = 1;
#endif
// copy flags and type from parent, for lack of better
buffer->flags = parent->flags;
buffer->type = parent->type;
// set the data pointer, size, offset, and maxsize
buffer->data = parent->data + offset;
buffer->size = size;
buffer->offset = offset;
buffer->maxsize = parent->size - offset;
// again, for lack of better, copy parent's timestamp
buffer->timestamp = parent->timestamp;
// no metas, this is sane I think
buffer->metas = NULL;
// set parentage and reference the parent
buffer->parent = parent;
gst_buffer_ref(parent);
// return the new subbuffer
return buffer;
}
void gst_buffer_destroy(GstBuffer *buffer) {
GSList *metas;
g_return_if_fail(buffer != NULL);
if (buffer->parent != NULL)
DEBUG("BUF: freeing subbuffer %p\n",buffer);
else
DEBUG("BUF: freeing buffer %p\n",buffer);
// free the data only if there is some, DONTFREE isn't set, and not sub
if (GST_BUFFER_DATA(buffer) &&
!GST_BUFFER_FLAG_IS_SET(buffer,GST_BUFFER_DONTFREE) &&
(buffer->parent == NULL)) {
g_free(GST_BUFFER_DATA(buffer));
// g_print("freed data in buffer\n");
}
// unreference any metadata attached to this buffer
metas = buffer->metas;
while (metas) {
gst_meta_unref((GstMeta *)(metas->data));
metas = g_slist_next(metas);
}
g_slist_free(buffer->metas);
// unreference the parent if there is one
if (buffer->parent != NULL)
gst_buffer_unref(buffer->parent);
g_mutex_free(buffer->lock);
// g_print("freed mutex\n");
// remove it entirely from memory
g_mem_chunk_free(_gst_buffer_chunk,buffer);
}
void gst_buffer_ref(GstBuffer *buffer) {
g_return_if_fail(buffer != NULL);
DEBUG("BUF: referencing buffer %p\n",buffer);
#ifdef HAVE_ATOMIC_H
g_return_if_fail(atomic_read(&(buffer->refcount)) > 0);
atomic_inc(&(buffer->refcount))
#else
g_return_if_fail(buffer->refcount > 0);
GST_BUFFER_LOCK(buffer);
buffer->refcount++;
GST_BUFFER_UNLOCK(buffer);
#endif
}
void gst_buffer_ref_by_count(GstBuffer *buffer,int count) {
g_return_if_fail(buffer != NULL);
g_return_if_fail(count > 0);
#ifdef HAVE_ATOMIC_H
g_return_if_fail(atomic_read(&(buffer->refcount)) > 0);
atomic_add(count,&(buffer->refcount))
#else
g_return_if_fail(buffer->refcount > 0);
GST_BUFFER_LOCK(buffer);
buffer->refcount += count;
GST_BUFFER_UNLOCK(buffer);
#endif
}
void gst_buffer_unref(GstBuffer *buffer) {
int zero;
g_return_if_fail(buffer != NULL);
DEBUG("BUF: unreferencing buffer %p\n",buffer);
#ifdef HAVE_ATOMIC_H
g_return_if_fail(atomic_read(&(buffer->refcount)) > 0);
zero = atomic_dec_and_test(&(buffer->refcount))
#else
g_return_if_fail(buffer->refcount > 0);
GST_BUFFER_LOCK(buffer);
buffer->refcount--;
zero = (buffer->refcount == 0);
GST_BUFFER_UNLOCK(buffer);
#endif
/* if we ended up with the refcount at zero, destroy the buffer */
if (zero)
gst_buffer_destroy(buffer);
}
void gst_buffer_add_meta(GstBuffer *buffer,GstMeta *meta) {
g_return_if_fail(buffer != NULL);
g_return_if_fail(meta != NULL);
gst_meta_ref(meta);
buffer->metas = g_slist_append(buffer->metas,meta);
}
GSList *gst_buffer_get_metas(GstBuffer *buffer) {
g_return_if_fail(buffer != NULL);
return buffer->metas;
}
GstMeta *gst_buffer_get_first_meta(GstBuffer *buffer) {
g_return_if_fail(buffer != NULL);
if (buffer->metas == NULL)
return NULL;
return GST_META(buffer->metas->data);
}
void gst_buffer_remove_meta(GstBuffer *buffer,GstMeta *meta) {
g_return_if_fail(buffer != NULL);
g_return_if_fail(meta != NULL);
buffer->metas = g_slist_remove(buffer->metas,meta);
gst_meta_unref(meta);
}

128
gst/gstbuffer.h Normal file
View file

@ -0,0 +1,128 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_BUFFER_H__
#define __GST_BUFFER_H__
#include <gst/gstmeta.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GST_BUFFER(buf) ((GstBuffer *)(buf))
#define GST_BUFFER_FLAGS(buf) \
(GST_BUFFER(buf)->flags)
#define GST_BUFFER_FLAG_IS_SET(buf,flag) \
(GST_BUFFER_FLAGS(buf) & (flag))
#define GST_BUFFER_FLAG_SET(buf,flag) \
G_STMT_START{ (GST_BUFFER_FLAGS(buf) |= (flag)); }G_STMT_END
#define GST_BUFFER_FLAG_UNSET(buf,flag) \
G_STMT_START{ (GST_BUFFER_FLAGS(buf) &= ~(flag)); }G_STMT_END
#define GST_BUFFER_TYPE(buf) (GST_BUFFER(buf)->type)
#define GST_BUFFER_DATA(buf) (GST_BUFFER(buf)->data)
#define GST_BUFFER_SIZE(buf) (GST_BUFFER(buf)->size)
#define GST_BUFFER_OFFSET(buf) (GST_BUFFER(buf)->offset)
#define GST_BUFFER_MAXSIZE(buf) (GST_BUFFER(buf)->maxsize)
#define GST_BUFFER_TIMESTAMP(buf) (GST_BUFFER(buf)->timestamp)
#define GST_BUFFER_LOCK(buf) (g_mutex_lock(GST_BUFFER(buf)->lock))
#define GST_BUFFER_TRYLOCK(buf) (g_mutex_trylock(GST_BUFFER(buf)->lock))
#define GST_BUFFER_UNLOCK(buf) (g_mutex_unlock(GST_BUFFER(buf)->lock))
typedef enum {
GST_BUFFER_READONLY = (1 << 0),
GST_BUFFER_EOS = (1 << 1),
GST_BUFFER_ORIGINAL = (1 << 2),
GST_BUFFER_DONTFREE = (1 << 3),
} GstBufferFlags;
typedef struct _GstBuffer GstBuffer;
struct _GstBuffer {
/* locking */
GMutex *lock;
/* refcounting */
#ifdef HAVE_ATOMIC_H
atomic_t refcount;
#else
int refcount;
#endif
/* data type of this buffer */
guint16 type;
/* flags */
guint16 flags;
/* pointer to data, its size, and offset in original source if known */
guchar *data;
guint32 size;
guint32 maxsize;
guint32 offset;
/* timestamp */
guint64 timestamp;
/* max age */
guint64 maxage;
/* pointer to metadata, is really lame right now */
GSList *metas;
/* subbuffer support, who's my parent? */
GstBuffer *parent;
};
/* creating a new buffer from scratch */
GstBuffer *gst_buffer_new();
/* creating a subbuffer */
GstBuffer *gst_buffer_create_sub(GstBuffer *parent,guint32 offset,guint32 size);
/* refcounting */
void gst_buffer_ref(GstBuffer *buffer);
void gst_buffer_ref_by_count(GstBuffer *buffer,int count);
void gst_buffer_unref(GstBuffer *buffer);
/* destroying the buffer */
void gst_buffer_destroy(GstBuffer *buffer);
/* add, retrieve, and remove metadata from the buffer */
void gst_buffer_add_meta(GstBuffer *buffer,GstMeta *meta);
GstMeta *gst_buffer_get_first_meta(GstBuffer *buffer);
GSList *gst_buffer_get_metas(GstBuffer *buffer);
void gst_buffer_remove_meta(GstBuffer *buffer,GstMeta *meta);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_BUFFER_H__ */

99
gst/gstconnection.c Normal file
View file

@ -0,0 +1,99 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/gstconnection.h>
/* Connection signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
static void gst_connection_class_init(GstConnectionClass *klass);
static void gst_connection_init(GstConnection *connection);
static GstElementClass *parent_class = NULL;
static guint gst_connection_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_connection_get_type(void) {
static GtkType connection_type = 0;
if (!connection_type) {
static const GtkTypeInfo connection_info = {
"GstConnection",
sizeof(GstConnection),
sizeof(GstConnectionClass),
(GtkClassInitFunc)gst_connection_class_init,
(GtkObjectInitFunc)gst_connection_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
connection_type = gtk_type_unique(GST_TYPE_ELEMENT,&connection_info);
}
return connection_type;
}
static void
gst_connection_class_init(GstConnectionClass *klass) {
GtkObjectClass *gtkobject_class;
gtkobject_class = (GtkObjectClass*)klass;
parent_class = gtk_type_class(GST_TYPE_ELEMENT);
}
static void gst_connection_init(GstConnection *connection) {
}
/**
* gst_connection_new:
* @name: name of new connection
*
* Create a new connection with given name.
*
* Returns: new connection
*/
GstElement *gst_connection_new(gchar *name) {
GstElement *connection = GST_ELEMENT(gtk_type_new(gst_connection_get_type()));
gst_element_set_name(GST_ELEMENT(connection),name);
return connection;
}
void gst_connection_push(GstConnection *connection) {
GstConnectionClass *oclass;
g_return_if_fail(connection != NULL);
g_return_if_fail(GST_IS_CONNECTION(connection));
oclass = (GstConnectionClass *)(GTK_OBJECT(connection)->klass);
g_return_if_fail(oclass->push != NULL);
(oclass->push)(connection);
}

69
gst/gstconnection.h Normal file
View file

@ -0,0 +1,69 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_CONNECTION_H__
#define __GST_CONNECTION_H__
#include <gst/gstelement.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GST_TYPE_CONNECTION \
(gst_connection_get_type())
#define GST_CONNECTION(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_CONNECTION,GstConnection))
#define GST_CONNECTION_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_CONNECTION,GstConnectionClass))
#define GST_IS_CONNECTION(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_CONNECTION))
#define GST_IS_CONNECTION_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_CONNECTION)))
typedef struct _GstConnection GstConnection;
typedef struct _GstConnectionClass GstConnectionClass;
struct _GstConnection {
GstElement element;
};
struct _GstConnectionClass {
GstElementClass parent_class;
/* push function */
void (*push) (GstConnection *connection);
};
GtkType gst_connection_get_type(void);
GstElement *gst_connection_new(gchar *name);
void gst_connection_push(GstConnection *connection);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_CONNECTION_H__ */

507
gst/gstelement.c Normal file
View file

@ -0,0 +1,507 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/gstelement.h>
/* Element signals and args */
enum {
STATE_CHANGE,
NEW_PAD,
NEW_GHOST_PAD,
ERROR,
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
static void gst_element_class_init(GstElementClass *klass);
static void gst_element_init(GstElement *element);
static void gst_element_real_destroy(GtkObject *object);
static GstObjectClass *parent_class = NULL;
static guint gst_element_signals[LAST_SIGNAL] = { 0 };
GtkType gst_element_get_type(void) {
static GtkType element_type = 0;
if (!element_type) {
static const GtkTypeInfo element_info = {
"GstElement",
sizeof(GstElement),
sizeof(GstElementClass),
(GtkClassInitFunc)gst_element_class_init,
(GtkObjectInitFunc)gst_element_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
element_type = gtk_type_unique(GST_TYPE_OBJECT,&element_info);
}
return element_type;
}
static void gst_element_class_init(GstElementClass *klass) {
GtkObjectClass *gtkobject_class;
gtkobject_class = (GtkObjectClass*)klass;
parent_class = gtk_type_class(GST_TYPE_OBJECT);
gst_element_signals[STATE_CHANGE] =
gtk_signal_new("state_change",GTK_RUN_LAST,gtkobject_class->type,
GTK_SIGNAL_OFFSET(GstElementClass,state_change),
gtk_marshal_NONE__INT,GTK_TYPE_NONE,1,
GTK_TYPE_INT);
gst_element_signals[NEW_PAD] =
gtk_signal_new("new_pad",GTK_RUN_LAST,gtkobject_class->type,
GTK_SIGNAL_OFFSET(GstElementClass,new_pad),
gtk_marshal_NONE__POINTER,GTK_TYPE_NONE,1,
GTK_TYPE_POINTER);
gst_element_signals[NEW_GHOST_PAD] =
gtk_signal_new("new_ghost_pad",GTK_RUN_LAST,gtkobject_class->type,
GTK_SIGNAL_OFFSET(GstElementClass,new_ghost_pad),
gtk_marshal_NONE__POINTER,GTK_TYPE_NONE,1,
GTK_TYPE_POINTER);
gst_element_signals[ERROR] =
gtk_signal_new("error",GTK_RUN_LAST,gtkobject_class->type,
GTK_SIGNAL_OFFSET(GstElementClass,error),
gtk_marshal_NONE__POINTER,GTK_TYPE_NONE,1,
GTK_TYPE_POINTER);
gtk_object_class_add_signals(gtkobject_class,gst_element_signals,LAST_SIGNAL);
klass->start = NULL;
klass->stop = NULL;
klass->change_state = gst_element_change_state;
gtkobject_class->destroy = gst_element_real_destroy;
}
static void gst_element_init(GstElement *element) {
element->state = 0;
element->numpads = 0;
element->pads = NULL;
element->loopfunc = NULL;
}
/**
* gst_element_new:
*
* Create a new element.
*
* Returns: new element
*/
GstElement *gst_element_new() {
return GST_ELEMENT(gtk_type_new(GST_TYPE_ELEMENT));
}
/**
* gst_element_add_pad:
* @element: element to add pad to
* @pad: pad to add
*
* Add a pad (connection point) to the element, setting the parent of the
* pad to the element (and thus adding a reference).
*/
void gst_element_add_pad(GstElement *element,GstPad *pad) {
g_return_if_fail(element != NULL);
g_return_if_fail(GST_IS_ELEMENT(element));
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
/* set the pad's parent */
gst_pad_set_parent(pad,GST_OBJECT(element));
/* add it to the list */
element->pads = g_list_append(element->pads,pad);
element->numpads++;
/* emit the NEW_PAD signal */
// g_print("emitting NEW_PAD signal, \"%s\"!\n",gst_pad_get_name(pad));
gtk_signal_emit(GTK_OBJECT(element),gst_element_signals[NEW_PAD],pad);
}
/**
* gst_element_add_ghost_pad:
* @element: element to add ghost pad to
* @pad: ghost pad to add
*
* Add a ghost pad to the element, setting the ghost parent of the pad to
* the element (and thus adding a reference).
*/
void gst_element_add_ghost_pad(GstElement *element,GstPad *pad) {
g_return_if_fail(element != NULL);
g_return_if_fail(GST_IS_ELEMENT(element));
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
/* set the pad's parent */
gst_pad_add_ghost_parent(pad,GST_OBJECT(element));
/* add it to the list */
element->pads = g_list_append(element->pads,pad);
element->numpads++;
/* emit the NEW_PAD signal */
gtk_signal_emit(GTK_OBJECT(element),gst_element_signals[NEW_GHOST_PAD],pad);
}
/**
* gst_element_get_pad:
* @element: element to find pad of
* @name: name of pad to retrieve
*
* Retrieve a pad from the element by name.
*
* Returns: requested pad if found, otherwise NULL.
*/
GstPad *gst_element_get_pad(GstElement *element,gchar *name) {
GList *walk;
g_return_if_fail(element != NULL);
g_return_if_fail(GST_IS_ELEMENT(element));
if (name == NULL)
return NULL;
if (!element->numpads)
return NULL;
walk = element->pads;
while (walk) {
if (!strcmp(((GstPad *)(walk->data))->name,name))
return (GstPad *)(walk->data);
walk = g_list_next(walk);
}
return NULL;
}
/**
* gst_element_get_pad_list:
* @element: element to get pads of
*
* Retrieve a list of the pads associated with the element.
*
* Returns: <type>GList</type> of pads
*/
GList *gst_element_get_pad_list(GstElement *element) {
g_return_if_fail(element != NULL);
g_return_if_fail(GST_IS_ELEMENT(element));
return element->pads;
}
/**
* gst_element_connect:
* @src: element containing source pad
* @srcpadname: name of pad in source element
* @dest: element containing destination pad
* @destpadname: name of pad in destination element
*
* Connect the two named pads of the source and destination elements.
* Side effect is that if one of the pads has no parent, it becomes a
* child of the parent of the other element. If they have different
* parents, the connection fails.
*/
void gst_element_connect(GstElement *src,gchar *srcpadname,
GstElement *dest,gchar *destpadname) {
GstPad *srcpad,*destpad;
GstObject *srcparent,*destparent;
g_return_if_fail(src != NULL);
g_return_if_fail(GST_IS_ELEMENT(src));
g_return_if_fail(srcpadname != NULL);
g_return_if_fail(dest != NULL);
g_return_if_fail(GST_IS_ELEMENT(dest));
g_return_if_fail(destpadname != NULL);
srcpad = gst_element_get_pad(src,srcpadname);
destpad = gst_element_get_pad(dest,destpadname);
g_return_if_fail(srcpad != NULL);
g_return_if_fail(destpad != NULL);
srcparent = gst_object_get_parent(GST_OBJECT(src));
destparent = gst_object_get_parent(GST_OBJECT(dest));
/* we can't do anything if neither have parents */
if ((srcparent == NULL) && (destparent == NULL))
return;
/* and we have to make sure that they have the same parents... */
if ((srcparent == NULL) && (destparent == NULL)) {
if (srcparent != destparent)
return;
}
}
void gst_element_error(GstElement *element,gchar *error) {
g_error("error in element '%s': %s\n",element->name,error);
gtk_signal_emit(GTK_OBJECT(element),gst_element_signals[ERROR],error);
}
/**
* gst_element_set_state:
* @element: element to change state of
* @state: new element state
*
* Sets the state of the element, but more importantly fires off a signal
* indicating the new state. You can clear state by simply prefixing the
* GstElementState value with ~, it will be detected and used to turn off
* that bit.
*
* Returns: whether or not the state was successfully set.
*/
gboolean gst_element_set_state(GstElement *element,GstElementState state) {
GstElementClass *oclass;
gboolean stateset = FALSE;
// g_print("gst_element_set_state(\"%s\",%08lx)\n",
// element->name,state);
g_return_if_fail(element != NULL);
g_return_if_fail(GST_IS_ELEMENT(element));
oclass = GST_ELEMENT_CLASS(GTK_OBJECT(element)->klass);
if (oclass->change_state)
stateset = (oclass->change_state)(element,state);
/* if a state *set* failed, unset it immediately */
/*
if (!(state & GST_STATE_MAX) && !stateset) {
g_print("set state failed miserably, forcing unset\n");
if (oclass->change_state)
stateset = (oclass->change_state)(element,~state);
return FALSE;
}*/
return stateset;
}
/* class function to set the state of a simple element */
gboolean gst_element_change_state(GstElement *element,
GstElementState state) {
g_return_if_fail(element != NULL);
g_return_if_fail(GST_IS_ELEMENT(element));
// g_print("gst_element_change_state(\"%s\",%d)\n",
// element->name,state);
/* deal with the inverted state */
// g_print("changing element state, was %08lx",GST_STATE(element));
if (state & GST_STATE_MAX)
GST_STATE_UNSET(element,~state);
else
GST_STATE_SET(element,state);
// g_print(", is now %08lx\n",GST_STATE(element));
gtk_signal_emit(GTK_OBJECT(element),gst_element_signals[STATE_CHANGE],
state);
}
/**
* gst_element_set_name:
* @element: GstElement to set name of
* @name: new name of element
*
* Set the name of the element, getting rid of the old name if there was
* one.
*/
void gst_element_set_name(GstElement *element,gchar *name) {
g_return_if_fail(element != NULL);
g_return_if_fail(GST_IS_ELEMENT(element));
g_return_if_fail(name != NULL);
if (element->name != NULL)
g_free(element->name);
element->name = g_strdup(name);
}
/**
* gst_element_get_name:
* @element: GstElement to set name of
*
* Get the name of the element.
*
* Returns: name of the element
*/
gchar *gst_element_get_name(GstElement *element) {
g_return_if_fail(element != NULL);
g_return_if_fail(GST_IS_ELEMENT(element));
return element->name;
}
static void gst_element_real_destroy(GtkObject *object) {
GstElement *element = GST_ELEMENT(object);
GList *pads;
GstPad *pad;
// g_print("in gst_element_real_destroy()\n");
if (element->name)
g_free(element->name);
pads = element->pads;
while (pads) {
pad = GST_PAD(pads->data);
gst_pad_destroy(pad);
pads = g_list_next(pads);
}
g_list_free(element->pads);
}
static gchar *_gst_element_type_names[] = {
"invalid",
"none",
"char",
"uchar",
"bool",
"int",
"uint",
"long",
"ulong",
"float",
"double",
"string",
};
xmlNodePtr gst_element_save_thyself(GstElement *element,xmlNodePtr parent) {
xmlNodePtr self, arglist;
GList *pads;
GstPad *pad;
GstElementClass *oclass;
GstElementFactory *factory;
GtkType type;
oclass = GST_ELEMENT_CLASS(GTK_OBJECT(element)->klass);
self = xmlNewChild(parent,NULL,"element",NULL);
xmlNewChild(self,NULL,"name",element->name);
if (oclass->elementfactory != NULL) {
factory = (GstElementFactory *)oclass->elementfactory;
xmlNewChild(self,NULL,"type",factory->name);
xmlNewChild(self,NULL,"version",factory->details->version);
}
pads = element->pads;
while (pads) {
pad = GST_PAD(pads->data);
// figure out if it's a direct pad or a ghostpad
if (pad->parent == element)
gst_pad_save_thyself(pad,self);
pads = g_list_next(pads);
}
// output all args to the element
arglist = xmlNewChild(self,NULL,"args",NULL);
type = GTK_OBJECT_TYPE(element);
while (type != GTK_TYPE_INVALID) {
GtkArg *args;
guint32 *flags;
guint num_args,i;
args = gtk_object_query_args(type,&flags,&num_args);
for (i=0;i<num_args;i++) {
if ((args[i].type > GTK_TYPE_NONE) &&
(args[i].type <= GTK_TYPE_STRING) &&
(flags && GTK_ARG_READABLE)) {
xmlNodePtr arg;
gtk_object_getv(GTK_OBJECT(element),1,&args[i]);
arg = xmlNewChild(arglist,NULL,"arg",NULL);
xmlNewChild(arg,NULL,"name",args[i].name);
switch (args[i].type) {
case GTK_TYPE_CHAR:
xmlNewChild(arg,NULL,"value",
g_strdup_printf("%c",GTK_VALUE_CHAR(args[i])));
break;
case GTK_TYPE_UCHAR:
xmlNewChild(arg,NULL,"value",
g_strdup_printf("%d",GTK_VALUE_UCHAR(args[i])));
break;
case GTK_TYPE_BOOL:
xmlNewChild(arg,NULL,"value",
GTK_VALUE_BOOL(args[1])?"true":"false");
break;
case GTK_TYPE_INT:
xmlNewChild(arg,NULL,"value",
g_strdup_printf("%d",GTK_VALUE_INT(args[i])));
break;
case GTK_TYPE_LONG:
xmlNewChild(arg,NULL,"value",
g_strdup_printf("%ld",GTK_VALUE_LONG(args[i])));
break;
case GTK_TYPE_ULONG:
xmlNewChild(arg,NULL,"value",
g_strdup_printf("%ld",GTK_VALUE_ULONG(args[i])));
break;
case GTK_TYPE_FLOAT:
xmlNewChild(arg,NULL,"value",
g_strdup_printf("%f",GTK_VALUE_FLOAT(args[i])));
break;
case GTK_TYPE_DOUBLE:
xmlNewChild(arg,NULL,"value",
g_strdup_printf("%lf",GTK_VALUE_DOUBLE(args[i])));
break;
case GTK_TYPE_STRING:
xmlNewChild(arg,NULL,"value",GTK_VALUE_STRING(args[i]));
break;
}
}
}
type = gtk_type_parent(type);
}
if (oclass->save_thyself)
(oclass->save_thyself)(element,self);
return self;
}
void gst_element_set_manager(GstElement *element,GstElement *manager) {
element->manager = manager;
}
GstElement *gst_element_get_manager(GstElement *element) {
return element->manager;
}
// note that this casts a char ** to a GstElement *. Ick.
int gst_element_loopfunc_wrapper(int argc,char **argv) {
GstElement *element = GST_ELEMENT(argv);
element->loopfunc(element);
}
void gst_element_set_loop_function(GstElement *element,
GstElementLoopFunction loop) {
element->loopfunc = loop;
if (element->threadstate != NULL)
cothread_setfunc(element->threadstate,gst_element_loopfunc_wrapper,
0,element);
}

194
gst/gstelement.h Normal file
View file

@ -0,0 +1,194 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_ELEMENT_H__
#define __GST_ELEMENT_H__
#include <gnome-xml/parser.h>
#include <gst/gstlog.h>
#include <gst/gstobject.h>
#include <gst/gstpad.h>
#include <gst/gstbuffer.h>
#include <gst/cothreads.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef enum {
GST_STATE_COMPLETE = (1 << 0),
GST_STATE_RUNNING = (1 << 1),
GST_STATE_DISCOVERY = (1 << 2),
GST_STATE_PREROLL = (1 << 3),
GST_STATE_PLAYING = (1 << 4),
GST_STATE_PAUSED = (1 << 5),
GST_STATE_MAX = (1 << 15),
} GstElementState;
#define GST_STATE(obj) (GST_ELEMENT(obj)->state)
#define GST_STATE_IS_SET(obj,flag) (GST_STATE (obj) & (flag))
#define GST_STATE_SET(obj,flag) \
G_STMT_START{ (GST_STATE (obj) |= (flag)); \
gst_info("set '%s' state %d\n",gst_element_get_name(obj),flag); \
}G_STMT_END
#define GST_STATE_UNSET(obj,flag) \
G_STMT_START{ (GST_STATE (obj) &= ~(flag)); \
gst_info("unset '%s' state %d\n",gst_element_get_name(obj),flag); \
}G_STMT_END
#define GST_TYPE_ELEMENT \
(gst_element_get_type())
#define GST_ELEMENT(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_ELEMENT,GstElement))
#define GST_ELEMENT_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_ELEMENT,GstElementClass))
#define GST_IS_ELEMENT(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_ELEMENT))
#define GST_IS_ELEMENT_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_ELEMENT)))
typedef struct _GstElement GstElement;
typedef struct _GstElementClass GstElementClass;
typedef struct _GstElementDetails GstElementDetails;
typedef struct _GstElementFactory GstElementFactory;
typedef void (*GstElementLoopFunction) (GstElement *element);
struct _GstElement {
GstObject object;
gchar *name;
guint16 state;
GstElementLoopFunction loopfunc;
cothread_state *threadstate;
guint16 numpads;
GList *pads;
GstElement *manager;
};
struct _GstElementClass {
GstObjectClass parent_class;
/* the elementfactory that created us */
GstElementFactory *elementfactory;
/* signal callbacks */
void (*state_change) (GstElement *element,GstElementState state);
void (*new_pad) (GstElement *element,GstPad *pad);
void (*new_ghost_pad) (GstElement *element,GstPad *pad);
void (*error) (GstElement *element,gchar *error);
/* events */
gboolean (*start) (GstElement *element,GstElementState state);
gboolean (*stop) (GstElement *element);
/* change the element state */
gboolean (*change_state) (GstElement *element,GstElementState state);
/* create or read XML representation of self */
xmlNodePtr (*save_thyself)(GstElement *element,xmlNodePtr parent);
void (*restore_thyself)(GstElement *element,xmlNodePtr *self);
};
struct _GstElementDetails {
gchar *longname; /* long, english name */
gchar *class; /* type of element, kinda */
gchar *description; /* insights of one form or another */
gchar *version; /* version of the element */
gchar *author; /* who wrote this thing? */
gchar *copyright; /* copyright details (year, etc.) */
};
struct _GstElementFactory {
gchar *name;
GtkType type;
GstElementDetails *details;
};
GtkType gst_element_get_type(void);
GstElement *gst_element_new(void);
void gst_element_set_loop_function(GstElement *element,
GstElementLoopFunction loop);
void gst_element_set_name(GstElement *element,gchar *name);
gchar *gst_element_get_name(GstElement *element);
void gst_element_set_manager(GstElement *element,GstElement *manager);
GstElement *gst_element_get_manager(GstElement *element);
void gst_element_add_pad(GstElement *element,GstPad *pad);
void gst_element_add_ghost_pad(GstElement *element,GstPad *pad);
GstPad *gst_element_get_pad(GstElement *element,gchar *name);
GList *gst_element_get_pad_list(GstElement *element);
void gst_element_connect(GstElement *src,gchar *srcpadname,
GstElement *dest,gchar *destpadname);
/* called by the app to set the state of the element */
gboolean gst_element_set_state(GstElement *element,GstElementState state);
void gst_element_error(GstElement *element,gchar *error);
/* callback to actually set the state */
gboolean gst_element_change_state(GstElement *element,
GstElementState state);
#define gst_element_destroy(element) gst_object_destroy(GST_OBJECT(element))
/* XML write and read */
xmlNodePtr gst_element_save_thyself(GstElement *element,xmlNodePtr parent);
GstElementFactory *gst_elementfactory_new(gchar *name,GtkType type,
GstElementDetails *details);
void gst_elementfactory_register(GstElementFactory *elementfactory);
GstElementFactory *gst_elementfactory_find(gchar *name);
GList *gst_elementfactory_get_list();
GstElement *gst_elementfactory_create(GstElementFactory *factory,
gchar *name);
// FIXME this name is wrong, probably so is the one above it
GstElement *gst_elementfactory_make(gchar *factoryname,gchar *name);
int gst_element_loopfunc_wrapper(int argc,char **argv);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_ELEMENT_H__ */

138
gst/gstelementfactory.c Normal file
View file

@ -0,0 +1,138 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/gstelement.h>
/* global list of registered elementfactories */
GList* _gst_elementfactories;
void _gst_elementfactory_initialize() {
_gst_elementfactories = NULL;
}
/**
* gst_elementfactory_register:
* @elementfactory: factory to register
*
* Adds the elementfactory to the global list, so it can be retrieved by
* name.
*/
void gst_elementfactory_register(GstElementFactory *elementfactory) {
g_return_if_fail(elementfactory != NULL);
_gst_elementfactories = g_list_prepend(_gst_elementfactories,elementfactory);
}
/**
* gst_elementfactory_find:
* @name: name of factory to find
*
* Search for an elementfactory of the given name.
*
* Returns: #GstElementFactory if found, NULL otherwise
*/
GstElementFactory *gst_elementfactory_find(gchar *name) {
GList *walk = _gst_elementfactories;
GstElementFactory *factory;
while (walk) {
factory = (GstElementFactory *)(walk->data);
if (!strcmp(name,factory->name))
return factory;
walk = g_list_next(walk);
}
return NULL;
}
/**
* gst_elementfactory_get_list:
*
* Get the global list of elementfactories.
*
* Returns: <type>GList</type> of type #GstElementFactory
*/
GList *gst_elementfactory_get_list() {
return _gst_elementfactories;
}
/**
* gst_elementfactory_new:
* @name: name of new elementfactory
* @type: GtkType of new element
* @details: #GstElementDetails structure with element details
*
* Create a new elementfactory capable of insantiating objects of the
* given type.
*
* Returns: new elementfactory
*/
GstElementFactory *gst_elementfactory_new(gchar *name,GtkType type,
GstElementDetails *details) {
GstElementFactory *factory = g_new0(GstElementFactory, 1);
factory->name = g_strdup(name);
factory->type = type;
factory->details = details;
return factory;
}
/**
* gst_elementfactory_create:
* @factory: factory to instantiate
* @name: name of new element
*
* Create a new element of the type defined by the given elementfactory.
* It wll be given the name supplied, since all elements require a name as
* their first argument.
*
* Returns: new #GstElement
*/
GstElement *gst_elementfactory_create(GstElementFactory *factory,
gchar *name) {
GstElement *element;
GstElementClass *oclass;
g_return_if_fail(factory != NULL);
g_return_if_fail(factory->type != 0);
// create an instance of the element
element = GST_ELEMENT(gtk_type_new(factory->type));
g_assert(element != NULL);
// attempt to set the elemenfactory class pointer if necessary
oclass = GST_ELEMENT_CLASS(GTK_OBJECT(element)->klass);
if (oclass->elementfactory == NULL)
oclass->elementfactory = factory;
gst_element_set_name(GST_ELEMENT(element),name);
return element;
}
GstElement *gst_elementfactory_make(gchar *factoryname,gchar *name) {
GstElementFactory *factory;
GstElement *element;
factory = gst_elementfactory_find(factoryname);
if (factory == NULL) return NULL;
element = gst_elementfactory_create(factory,name);
return element;
}

86
gst/gstfilter.c Normal file
View file

@ -0,0 +1,86 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/gstfilter.h>
/* Filter signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
static void gst_filter_class_init(GstFilterClass *klass);
static void gst_filter_init(GstFilter *filter);
static GstElementClass *parent_class = NULL;
static guint gst_filter_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_filter_get_type(void) {
static GtkType filter_type = 0;
if (!filter_type) {
static const GtkTypeInfo filter_info = {
"GstFilter",
sizeof(GstFilter),
sizeof(GstFilterClass),
(GtkClassInitFunc)gst_filter_class_init,
(GtkObjectInitFunc)gst_filter_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
filter_type = gtk_type_unique(GST_TYPE_ELEMENT,&filter_info);
}
return filter_type;
}
static void
gst_filter_class_init(GstFilterClass *klass) {
GtkObjectClass *gtkobject_class;
gtkobject_class = (GtkObjectClass*)klass;
parent_class = gtk_type_class(GST_TYPE_ELEMENT);
}
static void gst_filter_init(GstFilter *filter) {
}
/**
* gst_filter_new:
* @name: name of new filter
*
* Create a new filter with given name.
*
* Returns: new filter
*/
GstElement *gst_filter_new(gchar *name) {
GstElement *filter = GST_ELEMENT(gtk_type_new(gst_filter_get_type()));
gst_element_set_name(GST_ELEMENT(filter),name);
return filter;
}

63
gst/gstfilter.h Normal file
View file

@ -0,0 +1,63 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_FILTER_H__
#define __GST_FILTER_H__
#include <gst/gstelement.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GST_TYPE_FILTER \
(gst_filter_get_type())
#define GST_FILTER(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_FILTER,GstFilter))
#define GST_FILTER_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_FILTER,GstFilterClass))
#define GST_IS_FILTER(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_FILTER))
#define GST_IS_FILTER_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_FILTER)))
typedef struct _GstFilter GstFilter;
typedef struct _GstFilterClass GstFilterClass;
struct _GstFilter {
GstElement element;
};
struct _GstFilterClass {
GstElementClass parent_class;
};
GtkType gst_filter_get_type(void);
GstElement *gst_filter_new(gchar *name);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_FILTER_H__ */

31
gst/gstlog.h Normal file
View file

@ -0,0 +1,31 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_LOG_H__
#define __GST_LOG_H__
/* information messages */
#define GST_SHOW_INFO
#ifdef GST_SHOW_INFO
#define gst_info(format,args...) fprintf(stderr,format,##args)
#else
#define gst_info(format,args...)
#endif
#endif /* __GST_LOG_H__ */

57
gst/gstmeta.c Normal file
View file

@ -0,0 +1,57 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/gstmeta.h>
#include <gst/gsttrace.h>
GstMeta *gst_meta_new_size(gint size) {
GstMeta *meta;
meta = g_malloc(size);
gst_meta_ref(meta);
return meta;
}
void gst_meta_ref(GstMeta *meta) {
g_return_if_fail(meta != NULL);
gst_trace_add_entry(NULL,0,meta,"ref meta");
meta->refcount++;
}
void gst_meta_unref(GstMeta *meta) {
g_return_if_fail(meta != NULL);
gst_trace_add_entry(NULL,0,meta,"unref meta");
meta->refcount--;
if (meta->refcount == 0) {
// gst_trace_add_entry(NULL,0,meta,"destroy meta");
g_free(meta);
g_print("freeing metadata\n");
}
}
GstMeta *gst_meta_cow(GstMeta *meta) {
g_return_if_fail(meta != NULL);
}

85
gst/gstmeta.h Normal file
View file

@ -0,0 +1,85 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_META_H__
#define __GST_META_H__
#include <glib.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GST_META(meta) ((GstMeta *)(meta))
#define GST_META_FLAGS(buf) \
(GST_META(buf)->flags)
#define GST_META_FLAG_IS_SET(meta,flag) \
(GST_META_FLAGS(meta) & (flag))
#define GST_META_FLAG_SET(meta,flag) \
G_STMT_START{ (GST_META_FLAGS(meta) |= (flag)); }G_STMT_END
#define GST_META_FLAG_UNSET(meta,flag) \
G_STMT_START{ (GST_META_FLAGS(meta) &= ~(flag)); }G_STMT_END
typedef enum {
GST_META_FREEABLE = 1 << 0,
} GstMetaFlags;
typedef struct _GstMeta GstMeta;
struct _GstMeta {
/* locking */
GMutex *lock;
/* refcounting */
#ifdef HAVE_ATOMIC_H
atomic_t refcount;
#else
int refcount;
#endif
guint16 type;
guint16 flags;
void *data;
guint16 size;
};
GstMeta *gst_meta_new_size(gint size);
#define gst_meta_new(type) (type *)gst_meta_new_size(sizeof(type))
/* refcounting */
void gst_meta_ref(GstMeta *meta);
void gst_meta_unref(GstMeta *meta);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_BUFFER_H__ */

223
gst/gstobject.c Normal file
View file

@ -0,0 +1,223 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/gstobject.h>
#include <gst/gstbin.h>
/* Object signals and args */
enum {
PARENT_SET,
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
static void gst_object_class_init(GstObjectClass *klass);
static void gst_object_init(GstObject *object);
static GtkObjectClass *parent_class = NULL;
static guint gst_object_signals[LAST_SIGNAL] = { 0 };
GtkType gst_object_get_type(void) {
static GtkType object_type = 0;
if (!object_type) {
static const GtkTypeInfo object_info = {
"GstObject",
sizeof(GstObject),
sizeof(GstObjectClass),
(GtkClassInitFunc)gst_object_class_init,
(GtkObjectInitFunc)gst_object_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
object_type = gtk_type_unique(gtk_object_get_type(),&object_info);
}
return object_type;
}
static void gst_object_class_init(GstObjectClass *klass) {
GtkObjectClass *gtkobject_class;
gtkobject_class = (GtkObjectClass*)klass;
parent_class = gtk_type_class(gtk_object_get_type());
gst_object_signals[PARENT_SET] =
gtk_signal_new("parent_set",GTK_RUN_LAST,gtkobject_class->type,
GTK_SIGNAL_OFFSET(GstObjectClass,parent_set),
gtk_marshal_NONE__POINTER,GTK_TYPE_NONE,1,
GTK_TYPE_POINTER);
gtk_object_class_add_signals(gtkobject_class,gst_object_signals,LAST_SIGNAL);
}
static void gst_object_init(GstObject *object) {
object->lock = g_mutex_new();
#ifdef HAVE_ATOMIC_H
atomic_set(&(object->refcount),1);
#else
object->refcount++;
#endif
object->parent = NULL;
}
/**
* gst_object_new:
*
* Create a new object with
*
* Returns: new object
*/
GstObject *gst_object_new() {
return GST_OBJECT(gtk_type_new(gst_object_get_type()));
}
/**
* gst_object_set_parent:
* @object: GstObject to set parent of
* @parent: new parent of object
*
* Set the parent of the object. The object's reference count is
* incremented.
*/
void gst_object_set_parent(GstObject *object,GstObject *parent) {
g_return_if_fail(object != NULL);
g_return_if_fail(GST_IS_OBJECT(object));
g_return_if_fail(object->parent == NULL);
g_return_if_fail(parent != NULL);
g_return_if_fail(GST_IS_OBJECT(parent));
g_return_if_fail(object != parent);
gst_object_ref(object);
gst_object_sink(object);
object->parent = parent;
gtk_signal_emit(GTK_OBJECT(object),gst_object_signals[PARENT_SET],parent);
}
/**
* gst_object_get_parent:
* @object: GstObject to get parent of
*
* Return the parent of the object.
*
* Returns: parent of the object
*/
GstObject *gst_object_get_parent(GstObject *object) {
g_return_if_fail(object != NULL);
g_return_if_fail(GST_IS_OBJECT(object));
return object->parent;
}
/**
* gst_object_unparent:
* @object: GstObject to unparent
*
* Clear the parent of the object, removing the associated reference.
*/
void gst_object_unparent(GstObject *object) {
g_return_if_fail(object != NULL);
g_return_if_fail(GST_IS_OBJECT(object));
if (object->parent == NULL)
return;
object->parent = NULL;
gst_object_unref(object);
}
#ifndef gst_object_ref
void gst_object_ref (GstObject *object) {
g_return_if_fail(object != NULL);
g_return_if_fail(GST_IS_OBJECT(object));
#ifdef HAVE_ATOMIC_H
g_return_if_fail(atomic_read(&(object->refcount)) > 0);
atomic_inc(&(object->refcount))
#else
g_return_if_fail(object->refcount > 0);
GST_LOCK(object);
object->refcount++;
GST_UNLOCK(object);
#endif
}
#endif /* gst_object_ref */
#ifndef gst_object_unref
void gst_object_unref (GstObject *object) {
int reftest;
g_return_if_fail(object != NULL);
g_return_if_fail(GST_IS_OBJECT(object));
#ifdef HAVE_ATOMIC_H
g_return_if_fail(atomic_read(&(object->refcount)) > 0);
reftest = atomic_dec_and_test(&(object->refcount))
#else
g_return_if_fail(object->refcount > 0);
GST_LOCK(object);
object->refcount--;
reftest = (object->refcount == 0);
GST_UNLOCK(object);
#endif
/* if we ended up with the refcount at zero */
if (reftest) {
/* get the count to 1 for gtk_object_destroy() */
#ifdef HAVE_ATOMIC_T
atomic_set(&(object->refcount),1);
#else
object->refcount = 1;
#endif
/* destroy it */
gtk_object_destroy(GTK_OBJECT(object));
/* drop the refcount back to zero */
#ifdef HAVE_ATOMIC_T
atomic_set(&(object->refcount),0);
#else
object->refcount = 0;
#endif
/* finalize the object */
// FIXME this is an evil hack that should be killed
// FIXMEFIXMEFIXMEFIXME
// gtk_object_finalize(GTK_OBJECT(object));
}
}
#endif /* gst_object_unref */
#ifndef gst_object_sink
void gst_object_sink(GstObject *object) {
g_return_if_fail(object != NULL);
g_return_if_fail(GST_IS_OBJECT(object));
if (GTK_OBJECT_FLOATING(object)) {
GTK_OBJECT_UNSET_FLAGS(object, GTK_FLOATING);
gst_object_unref(object);
}
}
#endif /* gst_object_sink */

117
gst/gstobject.h Normal file
View file

@ -0,0 +1,117 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_OBJECT_H__
#define __GST_OBJECT_H__
#include <gtk/gtk.h>
#include <gst/gsttrace.h>
#include "config.h"
#ifdef HAVE_ATOMIC_H
#include <asm/atomic.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GST_TYPE_OBJECT \
(gst_object_get_type())
#define GST_OBJECT(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_OBJECT,GstObject))
#define GST_OBJECT_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_OBJECT,GstObjectClass))
#define GST_IS_OBJECT(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_OBJECT))
#define GST_IS_OBJECT_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_OBJECT)))
typedef struct _GstObject GstObject;
typedef struct _GstObjectClass GstObjectClass;
struct _GstObject {
GtkObject object;
/* have to have a refcount for the object */
#ifdef HAVE_ATOMIC_H
atomic_t refcount;
#else
int refcount;
#endif
/* locking for all sorts of things (like the refcount) */
GMutex *lock;
/* this objects parent */
GstObject *parent;
};
struct _GstObjectClass {
GtkObjectClass parent_class;
/* signals */
void (*parent_set) (GstObject *object,GstObject *parent);
/* functions go here */
};
#define GST_FLAGS(obj) GTK_OBJECT_FLAGS(obj)
#define GST_FLAG_IS_SET(obj,flag) (GST_FLAGS (obj) & (flag))
#define GST_FLAG_SET(obj,flag) G_STMT_START{ (GST_FLAGS (obj) |= (flag)); }G_STMT_END
#define GST_FLAG_UNSET(obj,flag) G_STMT_START{ (GST_FLAGS (obj) &= ~(flag)); }G_STMT_END
#define GST_LOCK(obj) (g_mutex_lock(GST_OBJECT(obj)->lock))
#define GST_TRYLOCK(obj) (g_mutex_trylock(GST_OBJECT(obj)->lock))
#define GST_UNLOCK(obj) (g_mutex_unlock(GST_OBJECT(obj)->lock))
/* normal GtkObject stuff */
GtkType gst_object_get_type(void);
GstObject* gst_object_new(void);
/* parentage routines */
void gst_object_set_parent(GstObject *object,GstObject *parent);
GstObject *gst_object_get_parent(GstObject *object);
void gst_object_unparent(GstObject *object);
/* refcounting */
//void gst_object_ref(GstObject *object);
#define gst_object_ref(obj) gtk_object_ref(GTK_OBJECT(obj));
//void gst_object_unref(GstObject *object);
#define gst_object_unref(obj) gtk_object_unref(GTK_OBJECT(obj));
//void gst_object_sink(GstObject *object);
#define gst_object_sink(obj) gtk_object_sink(GTK_OBJECT(obj));
/* destroying an object */
#define gst_object_destroy(obj) gtk_object_destroy(GTK_OBJECT(obj))
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_OBJECT_H__ */

340
gst/gstpad.c Normal file
View file

@ -0,0 +1,340 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/gstpad.h>
#include <gst/gstelement.h>
#include <gst/gsttype.h>
/* Pad signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
static void gst_pad_class_init(GstPadClass *klass);
static void gst_pad_init(GstPad *pad);
static void gst_pad_real_destroy(GtkObject *object);
static GstObject *parent_class = NULL;
static guint gst_pad_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_pad_get_type(void) {
static GtkType pad_type = 0;
if (!pad_type) {
static const GtkTypeInfo pad_info = {
"GstPad",
sizeof(GstPad),
sizeof(GstPadClass),
(GtkClassInitFunc)gst_pad_class_init,
(GtkObjectInitFunc)gst_pad_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
pad_type = gtk_type_unique(GST_TYPE_OBJECT,&pad_info);
}
return pad_type;
}
static void
gst_pad_class_init(GstPadClass *klass) {
GtkObjectClass *gtkobject_class;
gtkobject_class = (GtkObjectClass*)klass;
parent_class = gtk_type_class(GST_TYPE_OBJECT);
gtkobject_class->destroy = gst_pad_real_destroy;
}
static void gst_pad_init(GstPad *pad) {
pad->type = 0;
pad->direction = GST_PAD_UNKNOWN;
pad->peer = NULL;
pad->chain = NULL;
pad->parent = NULL;
pad->ghostparents = NULL;
}
/**
* gst_pad_new:
* @name: name of new pad
* @direction: either GST_PAD_SRC or GST_PAD_SINK
*
* Create a new pad with given name.
*
* Returns: new pad
*/
GstPad *gst_pad_new(gchar *name,GstPadDirection direction) {
GstPad *pad;
g_return_if_fail(name != NULL);
g_return_if_fail(direction != GST_PAD_UNKNOWN);
pad = GST_PAD(gtk_type_new(gst_pad_get_type()));
pad->name = g_strdup(name);
pad->direction = direction;
return pad;
}
GstPadDirection gst_pad_get_direction(GstPad *pad) {
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
return pad->direction;
}
void gst_pad_set_name(GstPad *pad,gchar *name) {
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
if (pad->name != NULL)
g_free(pad->name);
pad->name = g_strdup(name);
}
gchar *gst_pad_get_name(GstPad *pad) {
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
return pad->name;
}
void gst_pad_set_chain_function(GstPad *pad,GstPadChainFunction chain) {
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
pad->chain = chain;
}
void gst_pad_push(GstPad *pad,GstBuffer *buffer) {
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail(buffer != NULL);
gst_trace_add_entry(NULL,0,buffer,"push buffer");
// if the chain function exists for the pad, call it directly
if (pad->chain)
(pad->chain)(pad->peer,buffer);
// else we're likely going to have to coroutine it
else {
pad->peer->bufpen = buffer;
g_print("would switch to a coroutine here...\n");
if (!GST_IS_ELEMENT(pad->peer->parent))
g_print("eek, this isn't an element!\n");
if (GST_ELEMENT(pad->peer->parent)->threadstate != NULL)
cothread_switch(GST_ELEMENT(pad->peer->parent)->threadstate);
}
}
GstBuffer *gst_pad_pull(GstPad *pad) {
GstBuffer *buf;
GstElement *peerparent;
cothread_state *state;
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
if (pad->bufpen == NULL) {
g_print("no buffer available, will have to do something about it\n");
peerparent = GST_ELEMENT(pad->peer->parent);
// if they're a cothread too, we can just switch to them
if (peerparent->threadstate != NULL) {
cothread_switch(peerparent->threadstate);
// otherwise we have to switch to the main thread
} else {
state = cothread_main(GST_ELEMENT(pad->parent)->threadstate->ctx);
g_print("switching to supposed 0th thread at %p\n",state);
cothread_switch(state);
}
} else {
g_print("buffer available, pulling\n");
buf = pad->bufpen;
pad->bufpen = NULL;
return buf;
}
}
void gst_pad_chain(GstPad *pad) {
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail(pad->peer != NULL);
g_return_if_fail(pad->chain != NULL);
if (pad->bufpen)
(pad->chain)(pad,pad->bufpen);
}
void gst_pad_connect(GstPad *srcpad,GstPad *sinkpad) {
GstPad *temppad;
/* generic checks */
g_return_if_fail(srcpad != NULL);
g_return_if_fail(GST_IS_PAD(srcpad));
g_return_if_fail(srcpad->peer == NULL);
g_return_if_fail(sinkpad != NULL);
g_return_if_fail(GST_IS_PAD(sinkpad));
g_return_if_fail(sinkpad->peer == NULL);
// g_return_if_fail(sinkpad->chain != NULL);
/* check for reversed directions and swap if necessary */
if ((srcpad->direction == GST_PAD_SINK) &&
(sinkpad->direction == GST_PAD_SRC)) {
temppad = srcpad;
srcpad = sinkpad;
sinkpad = temppad;
}
g_return_if_fail((srcpad->direction == GST_PAD_SRC) &&
(sinkpad->direction == GST_PAD_SINK));
/* first set peers */
srcpad->peer = sinkpad;
sinkpad->peer = srcpad;
/* now copy the chain pointer from sink to src */
srcpad->chain = sinkpad->chain;
/* set the connected flag */
/* FIXME: set connected flag */
}
void gst_pad_set_parent(GstPad *pad,GstObject *parent) {
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail(pad->parent == NULL);
g_return_if_fail(parent != NULL);
g_return_if_fail(GTK_IS_OBJECT(parent));
g_return_if_fail((gpointer)pad != (gpointer)parent);
pad->parent = parent;
}
void gst_pad_add_ghost_parent(GstPad *pad,GstObject *parent) {
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail(parent != NULL);
g_return_if_fail(GTK_IS_OBJECT(parent));
pad->ghostparents = g_list_prepend(pad->ghostparents,parent);
}
void gst_pad_remove_ghost_parent(GstPad *pad,GstObject *parent) {
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail(parent != NULL);
g_return_if_fail(GTK_IS_OBJECT(parent));
pad->ghostparents = g_list_remove(pad->ghostparents,parent);
}
GstObject *gst_pad_get_parent(GstPad *pad) {
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
return pad->parent;
}
GList *gst_pad_get_ghost_parents(GstPad *pad) {
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
return pad->ghostparents;
}
guint32 gst_pad_get_type_id(GstPad *pad) {
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
return pad->type;
}
void gst_pad_set_type_id(GstPad *pad,guint16 id) {
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail(gst_type_find_by_id(id) != NULL);
pad->type = id;
}
GstPad *gst_pad_get_peer(GstPad *pad) {
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
return pad->peer;
}
GstPadDirection gst_pad_get_directory(GstPad *pad) {
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
return pad->direction;
}
static void gst_pad_real_destroy(GtkObject *object) {
GstPad *pad = GST_PAD(object);
// g_print("in gst_pad_real_destroy()\n");
if (pad->name)
g_free(pad->name);
g_list_free(pad->ghostparents);
}
xmlNodePtr gst_pad_save_thyself(GstPad *pad,xmlNodePtr parent) {
xmlNodePtr self;
GstPad *peer;
self = xmlNewChild(parent,NULL,"pad",NULL);
xmlNewChild(self,NULL,"name",pad->name);
if (pad->peer != NULL) {
peer = pad->peer;
// first check to see if the peer's parent's parent is the same
if (pad->parent->parent == peer->parent->parent)
// we just save it off
xmlNewChild(self,NULL,"peer",g_strdup_printf("%s.%s",
GST_ELEMENT(peer->parent)->name,peer->name));
} else
xmlNewChild(self,NULL,"peer","");
return self;
}
xmlNodePtr gst_pad_ghost_save_thyself(GstPad *pad,GstElement *bin,xmlNodePtr parent) {
xmlNodePtr self;
GstPad *peer;
self = xmlNewChild(parent,NULL,"ghostpad",NULL);
xmlNewChild(self,NULL,"name",pad->name);
xmlNewChild(self,NULL,"parent",GST_ELEMENT(pad->parent)->name);
return self;
}

127
gst/gstpad.h Normal file
View file

@ -0,0 +1,127 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_PAD_H__
#define __GST_PAD_H__
#include <gnome-xml/parser.h>
#include <gst/gstobject.h>
#include <gst/gstbuffer.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GST_TYPE_PAD \
(gst_pad_get_type())
#define GST_PAD(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_PAD,GstPad))
#define GST_PAD_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_PAD,GstPadClass))
#define GST_IS_PAD(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_PAD))
#define GST_IS_PAD_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_PAD)))
// quick test to see if the pad is connected
#define GST_PAD_CONNECTED(pad) ((pad)->peer != NULL)
typedef struct _GstPad GstPad;
typedef struct _GstPadClass GstPadClass;
/* this defines the functions used to chain buffers
* pad is the sink pad (so the same chain function can be used for N pads)
* buf is the buffer being passed */
typedef void (*GstPadChainFunction) (GstPad *pad,GstBuffer *buf);
typedef void (*GstPadPushFunction) (GstPad *pad);
typedef enum {
GST_PAD_UNKNOWN,
GST_PAD_SRC,
GST_PAD_SINK,
} GstPadDirection;
//typedef enum {
//} GstPadFlags;
struct _GstPad {
GstObject object;
gchar *name;
guint16 type;
GstPadDirection direction;
GstPad *peer;
GstBuffer *bufpen;
GstPadChainFunction chain;
GstObject *parent;
GList *ghostparents;
};
struct _GstPadClass {
GstObjectClass parent_class;
};
GtkType gst_pad_get_type(void);
GstPad *gst_pad_new(gchar *name,GstPadDirection direction);
void gst_pad_destroy(GstPad *pad);
GstPadDirection gst_pad_get_direction(GstPad *pad);
void gst_pad_set_chain_function(GstPad *pad,GstPadChainFunction chain);
guint32 gst_pad_get_type_id(GstPad *pad);
void gst_pad_set_type_id(GstPad *pad,guint16 id);
void gst_pad_set_name(GstPad *pad,gchar *name);
gchar *gst_pad_get_name(GstPad *pad);
#define gst_pad_destroy(pad) gst_object_destroy(GST_OBJECT(pad))
GstPadDirection gst_pad_get_directory(GstPad *pad);
void gst_pad_set_parent(GstPad *pad,GstObject *parent);
void gst_pad_add_ghost_parent(GstPad *pad,GstObject *parent);
void gst_pad_remove_ghost_parent(GstPad *pad,GstObject *parent);
GstObject *gst_pad_get_parent(GstPad *pad);
GList *gst_pad_get_ghost_parents(GstPad *pad);
GstPad *gst_pad_get_peer(GstPad *pad);
void gst_pad_connect(GstPad *srcpad,GstPad *sinkpad);
void gst_pad_push(GstPad *pad,GstBuffer *buffer);
GstBuffer *gst_pad_pull(GstPad *pad);
xmlNodePtr gst_pad_save_thyself(GstPad *pad,xmlNodePtr parent);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_PAD_H__ */

134
gst/gstpipeline.c Normal file
View file

@ -0,0 +1,134 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/gstpipeline.h>
GstElementDetails gst_pipeline_details = {
"Pipeline object",
"Bin",
"Complete pipeline object",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
/* Pipeline signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
static void gst_pipeline_class_init(GstPipelineClass *klass);
static void gst_pipeline_init(GstPipeline *pipeline);
static gboolean gst_pipeline_change_state(GstElement *element,
GstElementState state);
static void gst_pipeline_prepare(GstPipeline *pipeline);
static GstBin *parent_class = NULL;
static guint gst_pipeline_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_pipeline_get_type(void) {
static GtkType pipeline_type = 0;
if (!pipeline_type) {
static const GtkTypeInfo pipeline_info = {
"GstPipeline",
sizeof(GstPipeline),
sizeof(GstPipelineClass),
(GtkClassInitFunc)gst_pipeline_class_init,
(GtkObjectInitFunc)gst_pipeline_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
pipeline_type = gtk_type_unique(gst_bin_get_type(),&pipeline_info);
}
return pipeline_type;
}
static void
gst_pipeline_class_init(GstPipelineClass *klass) {
GstElementClass *gstelement_class;
gstelement_class = (GstElementClass*)klass;
parent_class = gtk_type_class(gst_bin_get_type());
gstelement_class->change_state = gst_pipeline_change_state;
}
static void gst_pipeline_init(GstPipeline *pipeline) {
}
GstPipeline *gst_pipeline_new(guchar *name) {
GstPipeline *pipeline;
pipeline = gtk_type_new(gst_pipeline_get_type());
gst_element_set_name(GST_ELEMENT(pipeline),name);
return pipeline;
}
static void gst_pipeline_prepare(GstPipeline *pipeline) {
g_print("preparing pipeline for playing\n");
}
static gboolean gst_pipeline_change_state(GstElement *element,
GstElementState state) {
GstPipeline *pipeline;
g_return_if_fail(GST_IS_PIPELINE(element));
pipeline = GST_PIPELINE(element);
switch (state) {
case GST_STATE_RUNNING:
/* we need to set up internal state */
g_print("preparing pipeline \"%s\" for iterations:\n",
gst_element_get_name(GST_ELEMENT(element)));
gst_pipeline_prepare(pipeline);
break;
case ~GST_STATE_RUNNING:
/* tear down the internal state */
g_print("tearing down pipelines's iteration state\n");
break;
default:
break;
}
if (GST_ELEMENT_CLASS(parent_class)->change_state)
return GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
return TRUE;
}
void gst_pipeline_iterate(GstPipeline *pipeline) {
g_return_if_fail(pipeline != NULL);
g_return_if_fail(GST_IS_PIPELINE(pipeline));
}

69
gst/gstpipeline.h Normal file
View file

@ -0,0 +1,69 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_PIPELINE_H__
#define __GST_PIPELINE_H__
#include <gst/gstbin.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_pipeline_details;
#define GST_TYPE_PIPELINE \
(gst_pipeline_get_type())
#define GST_PIPELINE(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_PIPELINE,GstPipeline))
#define GST_PIPELINE_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_PIPELINE,GstPipelineClass))
#define GST_IS_PIPELINE(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_PIPELINE))
#define GST_IS_PIPELINE_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_PIPELINE)))
typedef struct _GstPipeline GstPipeline;
typedef struct _GstPipelineClass GstPipelineClass;
struct _GstPipeline {
GstBin bin;
};
struct _GstPipelineClass {
GstBinClass parent_class;
};
GtkType gst_pipeline_get_type(void);
GstPipeline *gst_pipeline_new(guchar *name);
#define gst_pipeline_destroy(pipeline) gst_object_destroy(GST_OBJECT(pipeline))
void gst_pipeline_iterate(GstPipeline *pipeline);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_PIPELINE_H__ */

297
gst/gstplugin.c Normal file
View file

@ -0,0 +1,297 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <gst/gstplugin.h>
/* list of loaded modules and its sequence number */
GList *_gst_modules;
gint _gst_modules_seqno;
/* global list of plugins and its sequence number */
GList *_gst_plugins;
gint _gst_plugins_seqno;
/* list of paths to check for plugins */
GList *_gst_plugin_paths;
/* whether or not to spew library load issues */
gboolean _gst_plugin_spew = FALSE;
void _gst_plugin_initialize() {
_gst_modules = NULL;
_gst_modules_seqno = 0;
_gst_plugins = NULL;
_gst_plugins_seqno = 0;
_gst_plugin_paths = NULL;
/* add the main (installed) library path */
_gst_plugin_paths = g_list_prepend(_gst_plugin_paths,PLUGINS_DIR);
/* if this is set, we add build-directory paths to the list */
#ifdef PLUGINS_USE_SRCDIR
/* the catch-all plugins directory */
_gst_plugin_paths = g_list_prepend(_gst_plugin_paths,
PLUGINS_SRCDIR "/plugins");
/* location libgstelements.so */
_gst_plugin_paths = g_list_prepend(_gst_plugin_paths,
PLUGINS_SRCDIR "/gst/elements");
_gst_plugin_paths = g_list_prepend(_gst_plugin_paths,
PLUGINS_SRCDIR "/gst/types");
#endif /* PLUGINS_USE_SRCDIR */
}
static gboolean gst_plugin_load_recurse(gchar *directory,gchar *name) {
DIR *dir;
struct dirent *dirent;
gboolean loaded = FALSE;
dir = opendir(directory);
if (dir) {
while (dirent = readdir(dir)) {
/* don't want to recurse in place or backwards */
if (strcmp(dirent->d_name,".") && strcmp(dirent->d_name,"..")) {
gst_plugin_load_recurse(g_strjoin("/",directory,dirent->d_name,
NULL),name);
}
}
closedir(dir);
} else {
if (strstr(directory,".so")) {
gchar *temp;
if (name) {
if ((temp = strstr(directory,name)) &&
(!strcmp(temp,name))) {
gst_plugin_load_absolute(directory);
return TRUE;
}
} else if ((temp = strstr(directory,".so")) &&
(!strcmp(temp,".so"))) {
gst_plugin_load_absolute(directory);
loaded = TRUE;
}
}
}
return loaded;
}
/**
* gst_plugin_load_all:
*
* Load all plugins in the path.
*/
void gst_plugin_load_all() {
GList *path;
path = _gst_plugin_paths;
while (path != NULL) {
gst_plugin_load_recurse(path->data,NULL);
path = g_list_next(path);
}
}
/**
* gst_plugin_load:
* @name: name of plugin to load
*
* Load the named plugin. Name should be given as
* &quot;libplugin.so&quot;.
*
* Returns: whether the plugin was loaded or not
*/
gboolean gst_plugin_load(gchar *name) {
GList *path;
gchar *libspath;
// g_print("attempting to load plugin '%s'\n",name);
path = _gst_plugin_paths;
while (path != NULL) {
if (gst_plugin_load_absolute(g_module_build_path(path->data,name)))
return TRUE;
libspath = g_strconcat(path->data,"/.libs",NULL);
// g_print("trying to load '%s'\n",g_module_build_path(libspath,name));
if (gst_plugin_load_absolute(g_module_build_path(libspath,name))) {
g_free(libspath);
return TRUE;
}
g_free(libspath);
// g_print("trying to load '%s' from '%s'\n",name,path->data);
if (gst_plugin_load_recurse(path->data,name)) {
return TRUE;
}
path = g_list_next(path);
}
return FALSE;
}
/**
* gst_plugin_load_absolute:
* @name: name of plugin to load
*
* Returns: whether or not the plugin loaded
*/
gboolean gst_plugin_load_absolute(gchar *name) {
GModule *module;
GstPluginInitFunc initfunc;
GstPlugin *plugin;
// g_print("trying to load '%s\n",name);
if (g_module_supported() == FALSE) {
g_print("wow, you built this on a platform without dynamic loading???\n");
return;
}
module = g_module_open(name,0);
if (module != NULL) {
if (g_module_symbol(module,"plugin_init",(gpointer *)&initfunc)) {
if (plugin = (initfunc)(module)) {
GList *factories;
plugin->filename = g_strdup(name);
_gst_modules = g_list_append(_gst_modules,module);
_gst_modules_seqno++;
_gst_plugins = g_list_append(_gst_plugins,plugin);
_gst_plugins_seqno++;
factories = plugin->elements;
while (factories) {
gst_elementfactory_register((GstElementFactory*)(factories->data));
factories = g_list_next(factories);
}
return TRUE;
}
}
} else if (_gst_plugin_spew) {
// if (strstr(g_module_error(),"No such") == NULL)
gst_info("error loading plugin: %s\n",g_module_error());
}
return FALSE;
}
/**
* gst_plugin_new:
* @name: name of new plugin
*
* Create a new plugin with given name.
*
* Returns: new plugin
*/
GstPlugin *gst_plugin_new(gchar *name) {
GstPlugin *plugin = (GstPlugin *)malloc(sizeof(GstPlugin));
plugin->name = g_strdup(name);
plugin->longname = NULL;
plugin->types = NULL;
plugin->elements = NULL;
return plugin;
}
/**
* gst_plugin_set_longname:
* @plugin: plugin to set long name of
* @longname: new long name
*
* Sets the long name (should be descriptive) of the plugin.
*/
void gst_plugin_set_longname(GstPlugin *plugin,gchar *longname) {
g_return_if_fail(plugin != NULL);
if (plugin->longname) g_free(plugin->longname);
plugin->longname = g_strdup(longname);
}
/**
* gst_plugin_find:
* @name: name of plugin to find
*
* Search the list of registered plugins for one of the given name
*
* Returns: pointer to the #GstPlugin if found, NULL otherwise
*/
GstPlugin *gst_plugin_find(gchar *name) {
GList *plugins = _gst_plugins;
g_return_if_fail(name != NULL);
while (plugins) {
GstPlugin *plugin = (GstPlugin *)plugins->data;
// g_print("plugin name is '%s'\n",plugin->name);
if (plugin->name) {
if (!strcmp(plugin->name,name))
return plugin;
}
plugins = g_list_next(plugins);
}
return NULL;
}
/**
* gst_plugin_find_elementfactory:
* @name: name of elementfactory to find
*
* Find a registered elementfactory by name.
*
* Returns: @GstElementFactory if found, NULL if not
*/
GstElementFactory *gst_plugin_find_elementfactory(gchar *name) {
GList *plugins, *factories;
GstElementFactory *factory;
g_return_if_fail(name != NULL);
plugins = _gst_plugins;
while (plugins) {
factories = ((GstPlugin *)(plugins->data))->elements;
while (factories) {
factory = (GstElementFactory*)(factories->data);
if (!strcmp(gst_element_get_name(GST_ELEMENT(factory)),name))
return (GstElementFactory*)(factory);
factories = g_list_next(factories);
}
plugins = g_list_next(plugins);
}
return NULL;
}
/**
* gst_plugin_add_factory:
* @plugin: plugin to add factory to
* @factory: factory to add
*
* Add factory to the list of those provided by the element.
*/
void gst_plugin_add_factory(GstPlugin *plugin,GstElementFactory *factory) {
g_return_if_fail(plugin != NULL);
g_return_if_fail(factory != NULL);
// g_print("adding factory to plugin\n");
plugin->elements = g_list_append(plugin->elements,factory);
}
GList *gst_plugin_get_list() {
return _gst_plugins;
}

63
gst/gstplugin.h Normal file
View file

@ -0,0 +1,63 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_PLUGIN_H__
#define __GST_PLUGIN_H__
#include <gmodule.h>
#include <gst/gsttype.h>
#include <gst/gstelement.h>
#include "config.h"
typedef struct _GstPlugin GstPlugin;
typedef struct _GstPluginElement GstPluginElement;
struct _GstPlugin {
gchar *name; /* name of the plugin */
gchar *longname; /* long name of plugin */
gchar *filename; /* filename it came from */
GList *types; /* list of types provided */
GList *elements; /* list of elements provided */
GList *identifiers; /* list of identifiers */
};
typedef GstPlugin * (*GstPluginInitFunc) (GModule *module);
GstPlugin *gst_plugin_new(gchar *name);
void gst_plugin_set_longname(GstPlugin *plugin,gchar *longname);
void gst_plugin_init();
void gst_plugin_load_all();
gboolean gst_plugin_load(gchar *name);
gboolean gst_plugin_load_absolute(gchar *name);
void gst_plugin_add_factory(GstPlugin *plugin,GstElementFactory *factory);
GstPlugin *gst_plugin_find(gchar *name);
GList *gst_plugin_get_list();
GstElementFactory *gst_plugin_find_elementfactory(gchar *name);
#endif /* __GST_PLUGIN_H__ */

79
gst/gstsink.c Normal file
View file

@ -0,0 +1,79 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/gstsink.h>
/* Sink signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
static void gst_sink_class_init(GstSinkClass *klass);
static void gst_sink_init(GstSink *sink);
static GstElementClass *parent_class = NULL;
static guint gst_sink_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_sink_get_type(void) {
static GtkType sink_type = 0;
if (!sink_type) {
static const GtkTypeInfo sink_info = {
"GstSink",
sizeof(GstSink),
sizeof(GstSinkClass),
(GtkClassInitFunc)gst_sink_class_init,
(GtkObjectInitFunc)gst_sink_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
sink_type = gtk_type_unique(GST_TYPE_ELEMENT,&sink_info);
}
return sink_type;
}
static void
gst_sink_class_init(GstSinkClass *klass) {
GtkObjectClass *gtkobject_class;
gtkobject_class = (GtkObjectClass*)klass;
parent_class = gtk_type_class(GST_TYPE_ELEMENT);
}
static void gst_sink_init(GstSink *sink) {
}
GstObject *gst_sink_new(gchar *name) {
GstObject *sink = GST_OBJECT(gtk_type_new(GST_TYPE_SINK));
gst_element_set_name(GST_ELEMENT(sink),name);
return sink;
}

64
gst/gstsink.h Normal file
View file

@ -0,0 +1,64 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_SINK_H__
#define __GST_SINK_H__
#include <gst/gstelement.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GST_TYPE_SINK \
(gst_sink_get_type())
#define GST_SINK(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_SINK,GstSink))
#define GST_SINK_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_SINK,GstSinkClass))
#define GST_IS_SINK(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_SINK))
#define GST_IS_SINK_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_SINK)))
typedef struct _GstSink GstSink;
typedef struct _GstSinkClass GstSinkClass;
struct _GstSink {
GstElement element;
};
struct _GstSinkClass {
GstElementClass parent_class;
};
GtkType gst_sink_get_type(void);
GstObject *gst_sink_new(gchar *name);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_SINK_H__ */

122
gst/gstsrc.c Normal file
View file

@ -0,0 +1,122 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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>
/* Src signals and args */
enum {
EOS,
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
static void gst_src_class_init(GstSrcClass *klass);
static void gst_src_init(GstSrc *src);
static GstElementClass *parent_class = NULL;
static guint gst_src_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_src_get_type(void) {
static GtkType src_type = 0;
if (!src_type) {
static const GtkTypeInfo src_info = {
"GstSrc",
sizeof(GstSrc),
sizeof(GstSrcClass),
(GtkClassInitFunc)gst_src_class_init,
(GtkObjectInitFunc)gst_src_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
src_type = gtk_type_unique(GST_TYPE_ELEMENT,&src_info);
}
return src_type;
}
static void
gst_src_class_init(GstSrcClass *klass) {
GtkObjectClass *gtkobject_class;
gtkobject_class = (GtkObjectClass*)klass;
parent_class = gtk_type_class(GST_TYPE_ELEMENT);
gst_src_signals[EOS] =
gtk_signal_new("eos",GTK_RUN_LAST,gtkobject_class->type,
GTK_SIGNAL_OFFSET(GstSrcClass,eos),
gtk_marshal_NONE__POINTER,GTK_TYPE_NONE,1,
GTK_TYPE_POINTER);
gtk_object_class_add_signals(gtkobject_class,gst_src_signals,LAST_SIGNAL);
}
static void gst_src_init(GstSrc *src) {
src->flags = 0;
}
void gst_src_signal_eos(GstSrc *src) {
g_return_if_fail(src != NULL);
g_return_if_fail(GST_IS_SRC(src));
gtk_signal_emit(GTK_OBJECT(src),gst_src_signals[EOS],src);
}
void gst_src_push(GstSrc *src) {
GstSrcClass *oclass;
g_return_if_fail(src != NULL);
g_return_if_fail(GST_IS_SRC(src));
oclass = (GstSrcClass *)(GTK_OBJECT(src)->klass);
g_return_if_fail(oclass->push != NULL);
(oclass->push)(src);
}
/**
* gst_src_push_region:
* @src: source to trigger the push of
* @offset: offset in source
* @size: number of bytes to push
*
* Push a buffer of a given size from the source.
*/
void gst_src_push_region(GstSrc *src,gulong offset,gulong size) {
GstSrcClass *oclass;
g_return_if_fail(src != NULL);
g_return_if_fail(GST_IS_SRC(src));
oclass = (GstSrcClass *)(GTK_OBJECT(src)->klass);
g_return_if_fail(oclass->push_region != NULL);
(oclass->push_region)(src,offset,size);
}

86
gst/gstsrc.h Normal file
View file

@ -0,0 +1,86 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_SRC_H__
#define __GST_SRC_H__
#include <gst/gstelement.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GST_TYPE_SRC \
(gst_src_get_type())
#define GST_SRC(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_SRC,GstSrc))
#define GST_SRC_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_SRC,GstSrcClass))
#define GST_IS_SRC(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_SRC))
#define GST_IS_SRC_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_SRC)))
typedef enum {
GST_SRC_ASYNC = 1 << 0,
} GstSrcFlags;
#define GST_SRC_FLAGS(obj) (GST_SRC(obj)->flags)
#define GST_SRC_ASYNC(obj) ((GST_SRC_FLAGS(obj) & GST_SRC_ASYNC)
typedef struct _GstSrc GstSrc;
typedef struct _GstSrcClass GstSrcClass;
struct _GstSrc {
GstElement element;
gint32 flags;
};
struct _GstSrcClass {
GstElementClass parent_class;
/* subclass functions */
void (*push) (GstSrc *src);
void (*push_region) (GstSrc *src,gulong offset,gulong size);
/* signals */
void (*eos) (GstSrc *src);
};
#define GST_SRC_SET_FLAGS(src,flag) G_STMT_START{ (GST_SRC_FLAGS (src) |= (flag)); }G_STMT_END
#define GST_SRC_UNSET_FLAGS(src,flag) G_STMT_START{ (GST_SRC_FLAGS (src) &= ~(flag)); }G_STMT_END
GtkType gst_src_get_type(void);
void gst_src_signal_eos(GstSrc *src);
void gst_src_push(GstSrc *src);
void gst_src_push_region(GstSrc *src,gulong offset,gulong size);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_SRC_H__ */

130
gst/gsttee.c Normal file
View file

@ -0,0 +1,130 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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 <gsttee.h>
GstElementDetails gst_tee_details = {
"Tee pipe fitting",
"Tee",
"1ot-N pipe fitting",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
/* Tee signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
static void gst_tee_class_init(GstTeeClass *klass);
static void gst_tee_init(GstTee *tee);
static xmlNodePtr gst_tee_save_thyself(GstElement *element,xmlNodePtr parent);
static GstFilterClass *parent_class = NULL;
static guint gst_tee_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_tee_get_type(void) {
static GtkType tee_type = 0;
if (!tee_type) {
static const GtkTypeInfo tee_info = {
"GstTee",
sizeof(GstTee),
sizeof(GstTeeClass),
(GtkClassInitFunc)gst_tee_class_init,
(GtkObjectInitFunc)gst_tee_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
tee_type = gtk_type_unique(GST_TYPE_FILTER,&tee_info);
}
return tee_type;
}
static void
gst_tee_class_init(GstTeeClass *klass) {
GstFilterClass *gstfilter_class;
gstfilter_class = (GstFilterClass*)klass;
parent_class = gtk_type_class(GST_TYPE_FILTER);
}
static void gst_tee_init(GstTee *tee) {
tee->sinkpad = gst_pad_new("sink",GST_PAD_SINK);
gst_element_add_pad(GST_ELEMENT(tee),tee->sinkpad);
gst_pad_set_chain_function(tee->sinkpad,gst_tee_chain);
tee->numsrcpads = 0;
tee->srcpads = NULL;
}
GstElement *gst_tee_new(gchar *name) {
GstElement *tee = GST_ELEMENT(gtk_type_new(GST_TYPE_TEE));
gst_element_set_name(GST_ELEMENT(tee),name);
return tee;
}
gchar *gst_tee_new_pad(GstTee *tee) {
gchar *name;
GstPad *srcpad;
g_return_if_fail(tee != NULL);
g_return_if_fail(GST_IS_TEE(tee));
name = g_strdup_printf("src%d",tee->numsrcpads);
srcpad = gst_pad_new(name,GST_PAD_SRC);
gst_element_add_pad(GST_ELEMENT(tee),srcpad);
tee->srcpads = g_slist_prepend(tee->srcpads,srcpad);
tee->numsrcpads++;
return name;
}
void gst_tee_chain(GstPad *pad,GstBuffer *buf) {
GstTee *tee;
GSList *srcpads;
int i;
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail(buf != NULL);
tee = GST_TEE(pad->parent);
gst_trace_add_entry(NULL,0,buf,"tee buffer");
for (i=0;i<tee->numsrcpads-1;i++)
gst_buffer_ref(buf);
srcpads = tee->srcpads;
while (srcpads) {
gst_pad_push(GST_PAD(srcpads->data),buf);
srcpads = g_slist_next(srcpads);
}
}

70
gst/gsttee.h Normal file
View file

@ -0,0 +1,70 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_TEE_H__
#define __GST_TEE_H__
#include <gst/gstfilter.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GST_TYPE_TEE \
(gst_tee_get_type())
#define GST_TEE(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_TEE,GstTee))
#define GST_TEE_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_TEE,GstTeeClass))
#define GST_IS_TEE(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_TEE))
#define GST_IS_TEE_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_TEE)))
typedef struct _GstTee GstTee;
typedef struct _GstTeeClass GstTeeClass;
struct _GstTee {
GstFilter filter;
GstPad *sinkpad;
gint numsrcpads;
GSList *srcpads;
};
struct _GstTeeClass {
GstFilterClass parent_class;
};
GtkType gst_tee_get_type(void);
GstElement *gst_tee_new(gchar *name);
void gst_tee_chain(GstPad *pad,GstBuffer *buf);
gchar *gst_tee_new_pad(GstTee *tee);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_TEE_H__ */

332
gst/gstthread.c Normal file
View file

@ -0,0 +1,332 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/gstthread.h>
GstElementDetails gst_thread_details = {
"Threaded container",
"Bin",
"Container that creates/manages a thread",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
/* Thread signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
ARG_CREATE_THREAD,
};
static void gst_thread_class_init(GstThreadClass *klass);
static void gst_thread_init(GstThread *thread);
static void gst_thread_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_thread_get_arg(GtkObject *object,GtkArg *arg,guint id);
static gboolean gst_thread_change_state(GstElement *element,
GstElementState state);
static xmlNodePtr gst_thread_save_thyself(GstElement *element,xmlNodePtr parent);
static void gst_thread_prepare(GstThread *thread);
static void gst_thread_signal_thread(GstThread *thread);
static GstBin *parent_class = NULL;
static guint gst_thread_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_thread_get_type(void) {
static GtkType thread_type = 0;
if (!thread_type) {
static const GtkTypeInfo thread_info = {
"GstThread",
sizeof(GstThread),
sizeof(GstThreadClass),
(GtkClassInitFunc)gst_thread_class_init,
(GtkObjectInitFunc)gst_thread_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
thread_type = gtk_type_unique(gst_bin_get_type(),&thread_info);
}
return thread_type;
}
static void
gst_thread_class_init(GstThreadClass *klass) {
GtkObjectClass *gtkobject_class;
GstObjectClass *gstobject_class;
GstElementClass *gstelement_class;
gtkobject_class = (GtkObjectClass*)klass;
gstobject_class = (GstObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
parent_class = gtk_type_class(gst_bin_get_type());
gtk_object_add_arg_type("GstThread::create_thread", GTK_TYPE_BOOL,
GTK_ARG_READWRITE, ARG_CREATE_THREAD);
gstelement_class->change_state = gst_thread_change_state;
// gstelement_class->save_thyself = gst_thread_save_thyself;
gtkobject_class->set_arg = gst_thread_set_arg;
gtkobject_class->get_arg = gst_thread_get_arg;
}
static void gst_thread_init(GstThread *thread) {
GST_FLAG_SET(thread,GST_THREAD_CREATE);
thread->entries = NULL;
thread->numentries = 0;
thread->lock = g_mutex_new();
thread->cond = g_cond_new();
}
static void gst_thread_set_arg(GtkObject *object,GtkArg *arg,guint id) {
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_THREAD(object));
switch(id) {
case ARG_CREATE_THREAD:
if (GTK_VALUE_BOOL(*arg)) {
gst_info("turning ON the creation of the thread\n");
GST_FLAG_SET(object,GST_THREAD_CREATE);
gst_info("flags are 0x%08x\n",GST_FLAGS(object));
} else {
gst_info("turning OFF the creation of the thread\n");
GST_FLAG_UNSET(object,GST_THREAD_CREATE);
gst_info("flags are 0x%08x\n",GST_FLAGS(object));
}
break;
default:
break;
}
}
static void gst_thread_get_arg(GtkObject *object,GtkArg *arg,guint id) {
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_THREAD(object));
switch(id) {
case ARG_CREATE_THREAD:
GTK_VALUE_BOOL(*arg) = GST_FLAG_IS_SET(object,GST_THREAD_CREATE);
break;
default:
break;
}
}
GstElement *gst_thread_new(guchar *name) {
GstThread *thread;
thread = gtk_type_new(gst_thread_get_type());
gst_element_set_name(GST_ELEMENT(thread),name);
return GST_ELEMENT(thread);
}
static void gst_thread_prepare(GstThread *thread) {
GList *elements;
GstElement *element;
GList *pads;
GstPad *pad, *peer;
GstElement *outside;
thread->numentries = 0;
/* first we need to find all the entry points into the thread */
elements = GST_BIN(thread)->children;
while (elements) {
element = GST_ELEMENT(elements->data);
if (GST_IS_SRC(element)) {
gst_info("element \"%s\" is a source entry point for the thread\n",
gst_element_get_name(GST_ELEMENT(element)));
thread->entries = g_list_prepend(thread->entries,element);
thread->numentries++;
} else {
/* go through the list of pads to see if there's a Connection */
pads = gst_element_get_pad_list(element);
while (pads) {
pad = GST_PAD(pads->data);
/* we only worry about sink pads */
if (gst_pad_get_direction(pad) == GST_PAD_SINK) {
/* get the pad's peer */
peer = gst_pad_get_peer(pad);
if (!peer) break;
/* get the parent of the peer of the pad */
outside = GST_ELEMENT(gst_pad_get_parent(peer));
if (!outside) break;
/* if it's a connection and it's not ours... */
if (GST_IS_CONNECTION(outside) &&
(gst_object_get_parent(GST_OBJECT(outside)) != GST_OBJECT(thread))) {
gst_info("element \"%s\" is the external source Connection \
for internal element \"%s\"\n",
gst_element_get_name(GST_ELEMENT(outside)),
gst_element_get_name(GST_ELEMENT(element)));
thread->entries = g_list_prepend(thread->entries,outside);
thread->numentries++;
}
}
pads = g_list_next(pads);
}
}
elements = g_list_next(elements);
}
gst_info("have %d entries into thread\n",thread->numentries);
}
static gboolean gst_thread_change_state(GstElement *element,
GstElementState state) {
GstThread *thread;
gboolean stateset = TRUE;
g_return_if_fail(GST_IS_THREAD(element));
thread = GST_THREAD(element);
if (GST_ELEMENT_CLASS(parent_class)->change_state)
stateset = GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
switch (state) {
case GST_STATE_RUNNING:
if (!stateset) return FALSE;
/* we want to prepare our internal state for doing the iterations */
gst_info("preparing thread \"%s\" for iterations:\n",
gst_element_get_name(GST_ELEMENT(element)));
gst_thread_prepare(thread);
if (thread->numentries == 0)
return FALSE;
/* set the state to idle */
GST_FLAG_UNSET(thread,GST_THREAD_STATE_SPINNING);
/* create the thread if that's what we're supposed to do */
gst_info("flags are 0x%08x\n",GST_FLAGS(thread));
if (GST_FLAG_IS_SET(thread,GST_THREAD_CREATE)) {
gst_info("starting thread \"%s\"\n",
gst_element_get_name(GST_ELEMENT(element)));
pthread_create(&thread->thread_id,NULL,
gst_thread_main_loop,thread);
} else {
gst_info("NOT starting thread \"%s\"\n",
gst_element_get_name(GST_ELEMENT(element)));
}
return TRUE;
break;
case ~GST_STATE_RUNNING:
/* stop, reap, and join the thread */
GST_FLAG_UNSET(thread,GST_THREAD_STATE_SPINNING);
GST_FLAG_SET(thread,GST_THREAD_STATE_REAPING);
gst_thread_signal_thread(thread);
pthread_join(thread->thread_id,0);
/* tear down the internal state */
gst_info("tearing down thread's iteration state\n");
/* FIXME do stuff */
break;
case GST_STATE_PLAYING:
if (!stateset) return FALSE;
gst_info("starting thread \"%s\"\n",
gst_element_get_name(GST_ELEMENT(element)));
GST_FLAG_SET(thread,GST_THREAD_STATE_SPINNING);
gst_thread_signal_thread(thread);
return TRUE;
break;
case ~GST_STATE_PLAYING:
gst_info("stopping thread \"%s\"\n",
gst_element_get_name(GST_ELEMENT(element)));
GST_FLAG_UNSET(thread,GST_THREAD_STATE_SPINNING);
gst_thread_signal_thread(thread);
break;
default:
break;
}
return stateset;
}
void *gst_thread_main_loop(void *arg) {
GstThread *thread = GST_THREAD(arg);
gst_info("HI, IN MAIN THREAD LOOP!\n");
while(!GST_FLAG_IS_SET(thread,GST_THREAD_STATE_REAPING)) {
if (GST_FLAG_IS_SET(thread,GST_THREAD_STATE_SPINNING))
gst_thread_iterate(thread);
else {
g_mutex_lock(thread->lock);
g_cond_wait(thread->cond,thread->lock);
g_mutex_unlock(thread->lock);
}
}
GST_FLAG_UNSET(thread,GST_THREAD_STATE_REAPING);
gst_info("GOODBYE, LEAVING MAIN THREAD LOOP!\n");
return NULL;
}
void gst_thread_iterate(GstThread *thread) {
GList *entries;
GstElement *entry;
g_return_if_fail(thread != NULL);
g_return_if_fail(GST_IS_THREAD(thread));
// g_return_if_fail(GST_FLAG_IS_SET(thread,GST_STATE_RUNNING));
g_return_if_fail(thread->numentries > 0);
entries = thread->entries;
while (entries) {
entry = GST_ELEMENT(entries->data);
if (GST_IS_SRC(entry))
gst_src_push(GST_SRC(entry));
else if (GST_IS_CONNECTION(entry))
gst_connection_push(GST_CONNECTION(entry));
else
g_assert_not_reached();
entries = g_list_next(entries);
}
// g_print(",");
}
static void gst_thread_signal_thread(GstThread *thread) {
g_mutex_lock(thread->lock);
g_cond_signal(thread->cond);
g_mutex_unlock(thread->lock);
}
static xmlNodePtr gst_thread_save_thyself(GstElement *element,xmlNodePtr parent) {
GstThread *thread = GST_THREAD(element);
xmlNewChild(parent,NULL,"type","thread");
if (GST_ELEMENT_CLASS(parent_class)->save_thyself)
GST_ELEMENT_CLASS(parent_class)->save_thyself(element,parent);
}

84
gst/gstthread.h Normal file
View file

@ -0,0 +1,84 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_THREAD_H__
#define __GST_THREAD_H__
#include <gst/gstbin.h>
#include <pthread.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_thread_details;
typedef enum {
GST_THREAD_CREATE = (1 << 16),
GST_THREAD_STATE_SPINNING = (1 << 17),
GST_THREAD_STATE_REAPING = (1 << 18),
} GstThreadState;
#define GST_TYPE_THREAD \
(gst_thread_get_type())
#define GST_THREAD(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_THREAD,GstThread))
#define GST_THREAD_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_THREAD,GstThreadClass))
#define GST_IS_THREAD(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_THREAD))
#define GST_IS_THREAD_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_THREAD)))
typedef struct _GstThread GstThread;
typedef struct _GstThreadClass GstThreadClass;
struct _GstThread {
GstBin bin;
GList *entries; /* used to determine iterate behavior */
gint numentries; /* number of above entry points */
pthread_t thread_id; /* id of the thread, if any */
GMutex *lock; /* thread lock/condititon pair... */
GCond *cond; /* used to control the thread */
};
struct _GstThreadClass {
GstBinClass parent_class;
};
GtkType gst_thread_get_type(void);
GstElement *gst_thread_new(guchar *name);
void *gst_thread_main_loop(void *arg);
void gst_thread_iterate(GstThread *thread);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_THREAD_H__ */

103
gst/gsttrace.c Normal file
View file

@ -0,0 +1,103 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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 <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <glib.h>
#include <gst/gsttrace.h>
__inline__ void read_tsc(guint64 *dst) {
__asm__ __volatile__
("rdtsc"
: "=a" (*(guint32 *)dst), "=d" (*(((guint32 *)dst) + 1))
:
: "eax", "edx");
}
void gst_trace_read_tsc(guint64 *dst) {
read_tsc(dst);
}
GstTrace *_gst_trace_default = NULL;
gint _gst_trace_on = 1;
GstTrace *gst_trace_new(guchar *filename,gint size) {
GstTrace *trace = g_malloc(sizeof(GstTrace));
g_return_val_if_fail(trace != NULL,NULL);
trace->filename = g_strdup(filename);
g_print("opening '%s'\n",trace->filename);
trace->fd = open(trace->filename,O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
perror("opening trace file");
g_return_val_if_fail(trace->fd > 0,NULL);
trace->buf = g_malloc(size * sizeof(GstTraceEntry));
g_return_val_if_fail(trace->buf != NULL,NULL);
trace->bufsize = size;
trace->bufoffset = 0;
return trace;
}
void gst_trace_destroy(GstTrace *trace) {
g_return_if_fail(trace != NULL);
g_return_if_fail(trace->buf != NULL);
if (gst_trace_get_remaining(trace) > 0)
gst_trace_flush(trace);
close(trace->fd);
g_free(trace->buf);
g_free(trace);
}
void gst_trace_flush(GstTrace *trace) {
if (!trace) {
trace = _gst_trace_default;
if (!trace ) return;
}
write(trace->fd,trace->buf,trace->bufoffset * sizeof(GstTraceEntry));
trace->bufoffset = 0;
}
void gst_trace_set_default(GstTrace *trace) {
g_return_if_fail(trace != NULL);
_gst_trace_default = trace;
}
void _gst_trace_add_entry(GstTrace *trace,guint32 seq,guint32 data,gchar *msg) {
GstTraceEntry *entry;
if (!trace) {
trace = _gst_trace_default;
if (!trace ) return;
}
entry = trace->buf + trace->bufoffset;
read_tsc(&(entry->timestamp));
entry->sequence = seq;
entry->data = data;
strncpy(entry->message,msg,112);
trace->bufoffset++;
gst_trace_flush(trace);
}

69
gst/gsttrace.h Normal file
View file

@ -0,0 +1,69 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_TRACE_H__
#define __GST_TRACE_H__
void gst_trace_read_tsc(guint64 *dst);
typedef struct _GstTrace GstTrace;
typedef struct _GstTraceEntry GstTraceEntry;
struct _GstTrace {
/* where this trace is going */
gchar *filename;
int fd;
/* current buffer, size, head offset */
GstTraceEntry *buf;
gint bufsize;
gint bufoffset;
};
struct _GstTraceEntry {
guint64 timestamp;
guint32 sequence;
guint32 data;
gchar message[112];
};
GstTrace *gst_trace_new(guchar *filename,gint size);
void gst_trace_destroy(GstTrace *trace);
void gst_trace_flush(GstTrace *trace);
#define gst_trace_get_size(trace) ((trace)->bufsize)
#define gst_trace_get_offset(trace) ((trace)->bufoffset)
#define gst_trace_get_remaining(trace) ((trace)->bufsize - (trace)->bufoffset)
void gst_trace_set_default(GstTrace *trace);
void _gst_trace_add_entry(GstTrace *trace,guint32 seq,guint32 data,gchar *msg);
#define TRACE_ENABLE
#ifdef TRACE_ENABLE
extern gint _gst_trace_on;
#define gst_trace_add_entry(trace,seq,data,msg) \
if (_gst_trace_on) { \
_gst_trace_add_entry(trace,(guint32)seq,(guint32)data,msg); \
}
#else
#define gst_trace_add_entry(trace,seq,data,msg)
#endif
#endif /* __GST_TRACE_H__ */

160
gst/gsttype.c Normal file
View file

@ -0,0 +1,160 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
/* TODO:
* probably should set up a hash table for the type id's, since currently
* it's a rather pathetic linear search. Eventually there may be dozens
* of id's, but in reality there are only so many instances of lookup, so
* I'm not overly worried yet...
*/
#include <gst/gst.h>
/* global list of registered types */
GList *_gst_types;
guint16 _gst_maxtype;
void _gst_type_initialize() {
_gst_types = NULL;
_gst_maxtype = 1; /* type 0 is undefined */
// gst_type_audio_register();
}
guint16 gst_type_register(GstTypeFactory *factory) {
guint16 id;
GstType *type;
g_return_if_fail(factory != NULL);
// id = gst_type_find_by_mime(factory->mime);
id = 0;
if (!id) {
type = (GstType *)malloc(sizeof(GstType));
type->id = _gst_maxtype++;
type->mime = factory->mime;
type->exts = factory->exts;
type->typefindfunc = factory->typefindfunc;
type->srcs = NULL;
type->sinks = NULL;
_gst_types = g_list_prepend(_gst_types,type);
id = type->id;
} else {
type = gst_type_find_by_id(id);
/* now we want to try to merge the types and return the original */
/* FIXME: do extension merging here, not that easy */
/* if there is no existing typefind function, try to use new one */
if (!type->typefindfunc && factory->typefindfunc)
type->typefindfunc = factory->typefindfunc;
}
return id;
}
guint16 gst_type_find_by_mime(gchar *mime) {
GList *walk = _gst_types;
GstType *type;
gint typelen,mimelen;
gchar *search, *found;
// DEBUG("searching for '%s'\n",mime);
mimelen = strlen(mime);
while (walk) {
type = (GstType *)walk->data;
search = type->mime;
// DEBUG("checking against '%s'\n",search);
typelen = strlen(search);
while ((search - type->mime) < typelen) {
found = strstr(search,mime);
/* if the requested mime is in the list */
if (found) {
if ((*(found + mimelen) == ' ') ||
(*(found + mimelen) == ',') ||
(*(found + mimelen) == '\0')) {
return type->id;
} else {
search = found + mimelen;
}
} else
search += mimelen;
}
walk = g_list_next(walk);
}
return 0;
}
GstType *gst_type_find_by_id(guint16 id) {
GList *walk = _gst_types;
GstType *type;
while (walk) {
type = (GstType *)walk->data;
if (type->id == id)
return type;
walk = g_list_next(walk);
}
return NULL;
}
void gst_type_add_src(guint16 id,GstElementFactory *src) {
GstType *type = gst_type_find_by_id(id);
g_return_if_fail(type != NULL);
g_return_if_fail(src != NULL);
type->srcs = g_list_prepend(type->srcs,src);
}
void gst_type_add_sink(guint16 id,GstElementFactory *sink) {
GstType *type = gst_type_find_by_id(id);
g_return_if_fail(type != NULL);
g_return_if_fail(sink != NULL);
type->sinks = g_list_prepend(type->sinks,sink);
}
GList *gst_type_get_srcs(guint16 id) {
GstType *type = gst_type_find_by_id(id);
g_return_if_fail(type != NULL);
return type->srcs;
}
GList *gst_type_get_sinks(guint16 id) {
GstType *type = gst_type_find_by_id(id);
g_return_if_fail(type != 0);
return type->sinks;
}
GList *gst_type_get_list() {
return _gst_types;
}

76
gst/gsttype.h Normal file
View file

@ -0,0 +1,76 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_TYPE_H__
#define __GST_TYPE_H__
#include <gst/gstbuffer.h>
#include <gst/gstelement.h>
/* type of function used to check a stream for equality with type */
typedef gboolean (*GstTypeFindFunc) (GstBuffer *buf,gpointer *private);
typedef struct _GstType GstType;
typedef struct _GstTypeFactory GstTypeFactory;
struct _GstType {
guint16 id; /* type id (assigned) */
gchar *mime; /* MIME type */
gchar *exts; /* space-delimited list of extensions */
GstTypeFindFunc typefindfunc; /* typefind function */
GList *srcs; /* list of src objects for this type */
GList *sinks; /* list of sink objects for type */
};
struct _GstTypeFactory {
gchar *mime;
gchar *exts;
GstTypeFindFunc typefindfunc;
};
/* initialize the subsystem */
void gst_type_initialize();
/* create a new type, or find/merge an existing one */
guint16 gst_type_register(GstTypeFactory *factory);
/* look up a type by mime or extension */
guint16 gst_type_find_by_mime(gchar *mime);
guint16 gst_type_find_by_ext(gchar *ext);
/* add src or sink object */
void gst_type_add_src(guint16 id,GstElementFactory *src);
void gst_type_add_sink(guint16 id,GstElementFactory *sink);
/* get list of src or sink objects */
GList *gst_type_get_srcs(guint16 id);
GList *gst_type_get_sinks(guint16 id);
/* get GstType by id */
GstType *gst_type_find_by_id(guint16 id);
/* get the list of registered types (returns list of GstType!) */
GList *gst_type_get_list();
#endif /* __GST_TYPE_H__ */

79
gst/gsttypefind.c Normal file
View file

@ -0,0 +1,79 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/gsttypefind.h>
/* TypeFind signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
static void gst_typefind_class_init(GstTypeFindClass *klass);
static void gst_typefind_init(GstTypeFind *typefind);
static GstElementClass *parent_class = NULL;
static guint gst_typefind_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_typefind_get_type(void) {
static GtkType typefind_type = 0;
if (!typefind_type) {
static const GtkTypeInfo typefind_info = {
"GstTypeFind",
sizeof(GstTypeFind),
sizeof(GstTypeFindClass),
(GtkClassInitFunc)gst_typefind_class_init,
(GtkObjectInitFunc)gst_typefind_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
typefind_type = gtk_type_unique(GST_TYPE_ELEMENT,&typefind_info);
}
return typefind_type;
}
static void
gst_typefind_class_init(GstTypeFindClass *klass) {
GtkObjectClass *gtkobject_class;
gtkobject_class = (GtkObjectClass*)klass;
parent_class = gtk_type_class(GST_TYPE_ELEMENT);
}
static void gst_typefind_init(GstTypeFind *typefind) {
}
GstObject *gst_typefind_new(gchar *name) {
GstObject *typefind = GST_OBJECT(gtk_type_new(GST_TYPE_TYPEFIND));
gst_element_set_name(GST_ELEMENT(typefind),name);
return typefind;
}

68
gst/gsttypefind.h Normal file
View file

@ -0,0 +1,68 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_TYPEFIND_H__
#define __GST_TYPEFIND_H__
#include <gst/gstelement.h>
#include <gst/gstpad.h>
#include <gst/gsttype.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GST_TYPE_TYPEFIND \
(gst_typefind_get_type())
#define GST_TYPEFIND(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_TYPEFIND,GstTypeFind))
#define GST_TYPEFIND_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_TYPEFIND,GstTypeFindClass))
#define GST_IS_TYPEFIND(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_TYPEFIND))
#define GST_IS_TYPEFIND_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_TYPEFIND)))
typedef struct _GstTypeFind GstTypeFind;
typedef struct _GstTypeFindClass GstTypeFindClass;
struct _GstTypeFind {
GstElement element;
GstPad *sinkpad;
};
struct _GstTypeFindClass {
GstElementClass parent_class;
};
GtkType gst_typefind_get_type(void);
GstObject *gst_typefind_new(gchar *name);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_TYPEFIND_H__ */

77
gst/gstutils.c Normal file
View file

@ -0,0 +1,77 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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 <gtk/gtk.h>
gint gst_util_get_int_arg(GtkObject *object,guchar *argname) {
GtkArg arg;
arg.name = argname;
gtk_object_getv(GTK_OBJECT(object),1,&arg);
return GTK_VALUE_INT(arg);
}
glong gst_util_get_long_arg(GtkObject *object,guchar *argname) {
GtkArg arg;
arg.name = argname;
gtk_object_getv(GTK_OBJECT(object),1,&arg);
return GTK_VALUE_LONG(arg);
}
gfloat gst_util_get_float_arg(GtkObject *object,guchar *argname) {
GtkArg arg;
arg.name = argname;
gtk_object_getv(GTK_OBJECT(object),1,&arg);
return GTK_VALUE_FLOAT(arg);
}
gdouble gst_util_get_double_arg(GtkObject *object,guchar *argname) {
GtkArg arg;
arg.name = argname;
gtk_object_getv(GTK_OBJECT(object),1,&arg);
return GTK_VALUE_DOUBLE(arg);
}
guchar *gst_util_get_string_arg(GtkObject *object,guchar *argname) {
GtkArg arg;
arg.name = argname;
gtk_object_getv(GTK_OBJECT(object),1,&arg);
return GTK_VALUE_STRING(arg);
}
gpointer gst_util_get_pointer_arg(GtkObject *object,guchar *argname) {
GtkArg arg;
arg.name = argname;
gtk_object_getv(GTK_OBJECT(object),1,&arg);
return GTK_VALUE_POINTER(arg);
}
GtkWidget *gst_util_get_widget_arg(GtkObject *object,guchar *argname) {
GtkArg arg;
arg.name = argname;
gtk_object_getv(GTK_OBJECT(object),1,&arg);
return GTK_WIDGET(GTK_VALUE_OBJECT(arg));
}

35
gst/gstutils.h Normal file
View file

@ -0,0 +1,35 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_UTILS_H__
#define __GST_UTILS_H__
#include <gtk/gtk.h>
gint gst_util_get_int_arg(GtkObject *object,guchar *argname);
glong gst_util_get_long_arg(GtkObject *object,guchar *argname);
gfloat gst_util_get_float_arg(GtkObject *object,guchar *argname);
gdouble gst_util_get_double_arg(GtkObject *object,guchar *argname);
guchar *gst_util_get_string_arg(GtkObject *object,guchar *argname);
gpointer gst_util_get_pointer_arg(GtkObject *object,guchar *argname);
GtkWidget *gst_util_get_widget_arg(GtkObject *object,guchar *argname);
#endif /* __GST_UTILS_H__ */

31
gst/gstxml.c Normal file
View file

@ -0,0 +1,31 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/gstxml.h>
xmlDocPtr gst_xml_write(GstElement *element) {
xmlDocPtr doc;
doc = xmlNewDoc("1.0");
doc->root = xmlNewDocNode(doc,NULL,"GST-Pipeline",NULL);
gst_element_save_thyself(element,doc->root);
return doc;
}

30
gst/gstxml.h Normal file
View file

@ -0,0 +1,30 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_XML_H__
#define __GST_XML_H__
#include <gst/gst.h>
#include <gnome-xml/parser.h>
/* create an XML document out of a pipeline */
xmlDocPtr gst_xml_write(GstElement *element);
#endif /* __GST_XML_H__ */

3
gst/meta/Makefile.am Normal file
View file

@ -0,0 +1,3 @@
metaincludedir = $(includedir)/gst/meta
metainclude_HEADERS = \
audioraw.h

40
gst/meta/audioraw.h Normal file
View file

@ -0,0 +1,40 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_META_AUDIORAW_H__
#define __GST_META_AUDIORAW_H__
#include <gst/gstmeta.h>
#include <sys/soundcard.h>
typedef struct _MetaAudioRaw MetaAudioRaw;
struct _MetaAudioRaw {
GstMeta meta;
/* formatting information */
gint format;
gint channels;
gint frequency;
gint bps;
};
#endif /* __GST_META_AUDIORAW_H__ */

38
gst/meta/spectrum.h Normal file
View file

@ -0,0 +1,38 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/gstmeta.h>
typedef struct _MetaAudioSpectrum MetaAudioSpectrum;
struct _MetaAudioSpectrum {
GstMeta meta;
/* data representation */
gint16 bands; /* how many bands are represented */
gint8 channels; /* how many audio channels are there? */
gboolean interleaved; /* are the channels interleaved? */
/* spectrum details */
gint16 lowfreq;
gint16 highfreq;
gint16 steps;
};

139
gst/plugin.c Normal file
View file

@ -0,0 +1,139 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
/* list of paths to check for plugins */
GList *_plugin_paths;
/* whether or not to spew library load issues */
gboolean _plugin_spew = FALSE;
void plugin_initialize() {
_plugin_paths = NULL;
/* add the main (installed) library path */
_plugin_paths = g_list_prepend(_plugin_paths,PLUGINS_DIR);
/* if this is set, we add build-directory paths to the list */
#ifdef PLUGINS_USE_SRCDIR
_plugin_paths = g_list_prepend(_plugin_paths,PLUGINS_SRCDIR);
#endif /* PLUGINS_USE_SRCDIR */
}
static GModule *plugin_load_recurse(gchar *directory,gchar *name) {
DIR *dir;
struct dirent *dirent;
GModule *mod;
dir = opendir(directory);
if (dir) {
while (dirent = readdir(dir)) {
/* don't want to recurse in place or backwards */
if (strcmp(dirent->d_name,".") && strcmp(dirent->d_name,"..")) {
mod = plugin_load_recurse(g_strjoin("/",directory,dirent->d_name,
NULL),name);
if (mod != NULL) {
closedir(dir);
return mod;
}
}
}
closedir(dir);
} else {
if (strstr(directory,".so")) {
gchar *temp;
if (name) {
if ((temp = strstr(directory,name)) &&
(!strcmp(temp,name))) {
mod = plugin_load_absolute(directory);
if (mod != NULL) return mod;
}
} else if ((temp = strstr(directory,".so")) &&
(!strcmp(temp,".so"))) {
mod = plugin_load_absolute(directory);
if (mod != NULL) return mod;
}
}
}
return NULL;
}
/**
* plugin_load_all:
*
* Load all plugins in the path.
*/
void plugin_load_all() {
GList *path;
path = _plugin_paths;
while (path != NULL) {
plugin_load_recurse(path->data,NULL);
path = g_list_next(path);
}
}
/**
* plugin_load:
* @name: name of plugin to load
*
* Load the named plugin. Name should be given as
* &quot;libplugin.so&quot;.
*
* Returns: whether the plugin was loaded or not
*/
GModule *plugin_load(gchar *name) {
GList *path;
gchar *libspath;
GModule *mod;
// g_print("attempting to load plugin '%s'\n",name);
path = _plugin_paths;
while (path != NULL) {
mod = plugin_load_absolute(g_module_build_path(path->data,name));
if (mod != NULL) return mod;
libspath = g_strconcat(path->data,"/.libs",NULL);
// g_print("trying to load '%s'\n",g_module_build_path(libspath,name));
mod = plugin_load_absolute(g_module_build_path(libspath,name));
if (mod != NULL) {
g_free(libspath);
return mod;
}
g_free(libspath);
// g_print("trying to load '%s' from '%s'\n",name,path->data);
mod = plugin_load_recurse(path->data,name);
if (mod != NULL) return mod;
path = g_list_next(path);
}
return NULL;
}
/**
* plugin_load_absolute:
* @name: name of plugin to load
*
* Returns: whether or not the plugin loaded
*/
GModule *plugin_load_absolute(gchar *name) {
GModule *mod;
// g_print("trying to load '%s\n",name);
if (g_module_supported() == FALSE) {
g_print("wow, you built this on a platform without dynamic loading???\n");
return;
}
mod = g_module_open(name,0);
if (mod != NULL) {
return mod;
} else if (_gst_plugin_spew) {
// if (strstr(g_module_error(),"No such") == NULL)
g_print("error loading plugin: %s\n",g_module_error());
}
return NULL;
}

4
gst/plugin.h Normal file
View file

@ -0,0 +1,4 @@
void plugin_initialize();
void plugin_load_all();
GModule *plugin_load(gchar *name);
GModule *plugin_load_absolute(gchar *name);

10
gst/types/Makefile.am Normal file
View file

@ -0,0 +1,10 @@
lib_LTLIBRARIES = libgsttypes.la
libgsttypes_la_DEPENDENCIES = ../libgst.la
libgsttypes_la_SOURCES = \
gsttypes.c
#noinst_HEADERS =
libgsttypes_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_srcdir)/gst/libgst.la
libgsttypes_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE)

85
gst/types/gsttypes.c Normal file
View file

@ -0,0 +1,85 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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 <gtk/gtk.h>
#include <gst/gst.h>
gint mp3_typefind(GstBuffer *buf,gpointer *private);
gint wav_typefind(GstBuffer *buf,gpointer *private);
GstTypeFactory _factories[] = {
{ "audio/raw", ".raw", NULL },
{ "audio/mpeg audio/mp3", ".mp2 .mp3 .mpa .mpega", mp3_typefind },
{ "audio/wav", ".wav", wav_typefind },
{ "audio/ac3", ".ac3", NULL },
{ NULL, NULL, NULL },
};
/* check to see if a buffer indicates the presence of an mp3 frame
* NOTE that this only checks for a potentially valid mp3 frame header
* and doesn't guarantee that it's a fully valid mp3 audio stream */
gboolean mp3_typefind(GstBuffer *buf,gpointer *private) {
gulong head = GULONG_FROM_BE(*((gulong *)GST_BUFFER_DATA(buf)));
if ((head & 0xffe00000) != 0xffe00000)
return FALSE;
if (!((head >> 17) & 3))
return FALSE;
if (((head >> 12) & 0xf) == 0xf)
return FALSE;
if (!((head >> 12) & 0xf))
return FALSE;
if (((head >> 10) & 0x3) == 0x3)
return FALSE;
return TRUE;
}
gboolean wav_typefind(GstBuffer *buf,gpointer *private) {
gulong *data = (gulong *)GST_BUFFER_DATA(buf);
if (data[0] != "RIFF") return FALSE;
if (data[2] != "WAVE") return FALSE;
return TRUE;
}
GstPlugin *plugin_init(GModule *module) {
GstPlugin *plugin;
int i = 0;
if (gst_plugin_find("gsttypes") != NULL)
return NULL;
plugin = gst_plugin_new("gsttypes");
g_return_val_if_fail(plugin != NULL,NULL);
while (_factories[i].mime) {
gst_type_register(&_factories[i]);
// DEBUG("added factory #%d '%s'\n",i,_factories[i].mime);
i++;
}
gst_info("gsttypes: loaded %d standard types\n",i);
return plugin;
}

251
install-sh Executable file
View file

@ -0,0 +1,251 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

190
missing Executable file
View file

@ -0,0 +1,190 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
case "$1" in
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing - GNU libit 0.0"
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
aclocal)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acinclude.m4' or \`configure.in'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`configure.in'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acconfig.h' or \`configure.in'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
makeinfo)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
fi
touch $file
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
system. You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequirements for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0

40
mkinstalldirs Executable file
View file

@ -0,0 +1,40 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
# $Id$
errstatus=0
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# mkinstalldirs ends here

View file

@ -0,0 +1,35 @@
lib_LTLIBRARIES = libgstelements.la
libgstelements_la_DEPENDENCIES = ../libgst.la
libgstelements_la_SOURCES = \
gstelements.c \
gstfakesrc.c \
gstidentity.c \
gstfakesink.c \
gstdisksrc.c \
gstasyncdisksrc.c \
gstfdsrc.c \
gsthttpsrc.c \
gstaudiosink.c \
gstaudiosrc.c \
gstfdsink.c \
gstqueue.c \
gstsinesrc.c
noinst_HEADERS = \
gstfakesrc.h \
gstidentity.h \
gstfakesink.h \
gstdisksrc.h \
gstasyncdisksrc.h \
gstfdsrc.h \
gsthttpsrc.h \
gstaudiosink.h \
gstaudiosrc.h \
gstfdsink.h \
gstqueue.h \
gstsinesrc.h
libgstelements_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) \
$(top_srcdir)/gst/libgst.la
libgstelements_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE)

View file

@ -0,0 +1,346 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <gstasyncdisksrc.h>
GstElementDetails gst_asyncdisksrc_details = {
"Asynchronous Disk Source",
"Source/File",
"Read from arbitrary point in a file",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
/* AsyncDiskSrc signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
ARG_LOCATION,
ARG_BYTESPERREAD,
ARG_LENGTH,
ARG_OFFSET,
};
static void gst_asyncdisksrc_class_init(GstAsyncDiskSrcClass *klass);
static void gst_asyncdisksrc_init(GstAsyncDiskSrc *asyncdisksrc);
static void gst_asyncdisksrc_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_asyncdisksrc_get_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_asyncdisksrc_push(GstSrc *src);
static void gst_asyncdisksrc_push_region(GstSrc *src,gulong offset,
gulong size);
static gboolean gst_asyncdisksrc_change_state(GstElement *element,
GstElementState state);
static GstSrcClass *parent_class = NULL;
static guint gst_asyncdisksrc_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_asyncdisksrc_get_type(void) {
static GtkType asyncdisksrc_type = 0;
if (!asyncdisksrc_type) {
static const GtkTypeInfo asyncdisksrc_info = {
"GstAsyncDiskSrc",
sizeof(GstAsyncDiskSrc),
sizeof(GstAsyncDiskSrcClass),
(GtkClassInitFunc)gst_asyncdisksrc_class_init,
(GtkObjectInitFunc)gst_asyncdisksrc_init,
(GtkArgSetFunc)gst_asyncdisksrc_set_arg,
(GtkArgGetFunc)gst_asyncdisksrc_get_arg,
(GtkClassInitFunc)NULL,
};
asyncdisksrc_type = gtk_type_unique(GST_TYPE_SRC,&asyncdisksrc_info);
}
return asyncdisksrc_type;
}
static void
gst_asyncdisksrc_class_init(GstAsyncDiskSrcClass *klass) {
GtkObjectClass *gtkobject_class;
GstElementClass *gstelement_class;
GstSrcClass *gstsrc_class;
gtkobject_class = (GtkObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
gstsrc_class = (GstSrcClass*)klass;
parent_class = gtk_type_class(GST_TYPE_SRC);
gtk_object_add_arg_type("GstAsyncDiskSrc::location", GTK_TYPE_STRING,
GTK_ARG_READWRITE, ARG_LOCATION);
gtk_object_add_arg_type("GstAsyncDiskSrc::bytesperread", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_BYTESPERREAD);
gtk_object_add_arg_type("GstAsyncDiskSrc::length", GTK_TYPE_LONG,
GTK_ARG_READABLE, ARG_LENGTH);
gtk_object_add_arg_type("GstAsyncDiskSrc::offset", GTK_TYPE_LONG,
GTK_ARG_READWRITE, ARG_OFFSET);
gtkobject_class->set_arg = gst_asyncdisksrc_set_arg;
gtkobject_class->get_arg = gst_asyncdisksrc_get_arg;
gstelement_class->change_state = gst_asyncdisksrc_change_state;
gstsrc_class->push = gst_asyncdisksrc_push;
gstsrc_class->push_region = gst_asyncdisksrc_push_region;
}
static void gst_asyncdisksrc_init(GstAsyncDiskSrc *asyncdisksrc) {
GST_SRC_SET_FLAGS(asyncdisksrc,GST_SRC_ASYNC);
asyncdisksrc->srcpad = gst_pad_new("src",GST_PAD_SRC);
gst_element_add_pad(GST_ELEMENT(asyncdisksrc),asyncdisksrc->srcpad);
asyncdisksrc->filename = NULL;
asyncdisksrc->fd = 0;
asyncdisksrc->size = 0;
asyncdisksrc->map = NULL;
asyncdisksrc->curoffset = 0;
asyncdisksrc->bytes_per_read = 4096;
asyncdisksrc->seq = 0;
}
static void gst_asyncdisksrc_set_arg(GtkObject *object,GtkArg *arg,guint id) {
GstAsyncDiskSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_ASYNCDISKSRC(object));
src = GST_ASYNCDISKSRC(object);
switch(id) {
case ARG_LOCATION:
/* the element must be stopped in order to do this */
g_return_if_fail(!GST_FLAG_IS_SET(src,GST_STATE_RUNNING));
if (src->filename) g_free(src->filename);
/* clear the filename if we get a NULL (is that possible?) */
if (GTK_VALUE_STRING(*arg) == NULL) {
src->filename = NULL;
gst_element_set_state(GST_ELEMENT(object),~GST_STATE_COMPLETE);
/* otherwise set the new filename */
} else {
src->filename = g_strdup(GTK_VALUE_STRING(*arg));
gst_element_set_state(GST_ELEMENT(object),GST_STATE_COMPLETE);
}
break;
case ARG_BYTESPERREAD:
src->bytes_per_read = GTK_VALUE_INT(*arg);
break;
case ARG_OFFSET:
src->curoffset = GTK_VALUE_LONG(*arg);
break;
default:
break;
}
}
static void gst_asyncdisksrc_get_arg(GtkObject *object,GtkArg *arg,guint id) {
GstAsyncDiskSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_ASYNCDISKSRC(object));
src = GST_ASYNCDISKSRC(object);
switch (id) {
case ARG_LOCATION:
GTK_VALUE_STRING(*arg) = src->filename;
break;
case ARG_BYTESPERREAD:
GTK_VALUE_INT(*arg) = src->bytes_per_read;
break;
case ARG_LENGTH:
GTK_VALUE_LONG(*arg) = src->size;
break;
case ARG_OFFSET:
GTK_VALUE_LONG(*arg) = src->curoffset;
break;
default:
arg->type = GTK_TYPE_INVALID;
break;
}
}
/**
* gst_asyncdisksrc_push:
* @src: #GstSrc to push a buffer from
*
* Push a new buffer from the asyncdisksrc at the current offset.
*/
void gst_asyncdisksrc_push(GstSrc *src) {
GstAsyncDiskSrc *asyncdisksrc;
GstBuffer *buf;
g_return_if_fail(src != NULL);
g_return_if_fail(GST_IS_ASYNCDISKSRC(src));
g_return_if_fail(GST_FLAG_IS_SET(src,GST_ASYNCDISKSRC_OPEN));
asyncdisksrc = GST_ASYNCDISKSRC(src);
/* deal with EOF state */
if (asyncdisksrc->curoffset >= asyncdisksrc->size) {
gst_src_signal_eos(GST_SRC(asyncdisksrc));
return;
}
/* create the buffer */
// FIXME: should eventually use a bufferpool for this
buf = GST_BUFFER(gst_buffer_new());
g_return_if_fail(buf != NULL);
/* simply set the buffer to point to the correct region of the file */
GST_BUFFER_DATA(buf) = asyncdisksrc->map + asyncdisksrc->curoffset;
GST_BUFFER_OFFSET(buf) = asyncdisksrc->curoffset;
if ((asyncdisksrc->curoffset + asyncdisksrc->bytes_per_read) >
asyncdisksrc->size) {
GST_BUFFER_SIZE(buf) = asyncdisksrc->size - asyncdisksrc->curoffset;
// FIXME: set the buffer's EOF bit here
} else
GST_BUFFER_SIZE(buf) = asyncdisksrc->bytes_per_read;
asyncdisksrc->curoffset += GST_BUFFER_SIZE(buf);
/* we're done, push the buffer off now */
gst_pad_push(asyncdisksrc->srcpad,buf);
}
/**
* gst_asyncdisksrc_push_region:
* @src: #GstSrc to push a buffer from
* @offset: offset in file
* @size: number of bytes
*
* Push a new buffer from the asyncdisksrc of given size at given offset.
*/
void gst_asyncdisksrc_push_region(GstSrc *src,gulong offset,gulong size) {
GstAsyncDiskSrc *asyncdisksrc;
GstBuffer *buf;
g_return_if_fail(src != NULL);
g_return_if_fail(GST_IS_ASYNCDISKSRC(src));
g_return_if_fail(GST_FLAG_IS_SET(src,GST_STATE_RUNNING));
asyncdisksrc = GST_ASYNCDISKSRC(src);
/* deal with EOF state */
if (offset >= asyncdisksrc->size) {
gst_src_signal_eos(GST_SRC(asyncdisksrc));
return;
}
/* create the buffer */
// FIXME: should eventually use a bufferpool for this
buf = gst_buffer_new();
g_return_if_fail(buf);
/* simply set the buffer to point to the correct region of the file */
GST_BUFFER_DATA(buf) = asyncdisksrc->map + offset;
GST_BUFFER_OFFSET(buf) = asyncdisksrc->curoffset;
if ((offset + size) > asyncdisksrc->size) {
GST_BUFFER_SIZE(buf) = asyncdisksrc->size - offset;
// FIXME: set the buffer's EOF bit here
} else
GST_BUFFER_SIZE(buf) = size;
asyncdisksrc->curoffset += GST_BUFFER_SIZE(buf);
/* we're done, push the buffer off now */
gst_pad_push(asyncdisksrc->srcpad,buf);
}
/* open the file and mmap it, necessary to go to RUNNING state */
static gboolean gst_asyncdisksrc_open_file(GstAsyncDiskSrc *src) {
g_return_if_fail(!GST_FLAG_IS_SET(src,GST_ASYNCDISKSRC_OPEN));
/* open the file */
src->fd = open(src->filename,O_RDONLY);
if (src->fd < 0) {
gst_element_error(GST_ELEMENT(src),"opening file");
return FALSE;
} else {
/* find the file length */
src->size = lseek(src->fd,0,SEEK_END);
lseek(src->fd,0,SEEK_SET);
/* map the file into memory */
src->map = mmap(NULL,src->size,PROT_READ,MAP_SHARED,src->fd,0);
/* collapse state if that failed */
if (src->map == NULL) {
close(src->fd);
gst_element_error(GST_ELEMENT(src),"mmapping file");
return FALSE;
}
GST_FLAG_SET(src,GST_ASYNCDISKSRC_OPEN);
}
return TRUE;
}
/* unmap and close the file */
static void gst_asyncdisksrc_close_file(GstAsyncDiskSrc *src) {
g_return_if_fail(GST_FLAG_IS_SET(src,GST_ASYNCDISKSRC_OPEN));
/* unmap the file from memory */
munmap(src->map,src->size);
/* close the file */
close(src->fd);
/* zero out a lot of our state */
src->fd = 0;
src->size = 0;
src->map = NULL;
src->curoffset = 0;
src->seq = 0;
GST_FLAG_UNSET(src,GST_ASYNCDISKSRC_OPEN);
}
static gboolean gst_asyncdisksrc_change_state(GstElement *element,
GstElementState state) {
g_return_if_fail(GST_IS_ASYNCDISKSRC(element));
switch (state) {
case GST_STATE_RUNNING:
if (!gst_asyncdisksrc_open_file(GST_ASYNCDISKSRC(element)))
return FALSE;
break;
case ~GST_STATE_RUNNING:
gst_asyncdisksrc_close_file(GST_ASYNCDISKSRC(element));
break;
default:
break;
}
if (GST_ELEMENT_CLASS(parent_class)->change_state)
return GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
return TRUE;
}

View file

@ -0,0 +1,88 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_ASYNCDISKSRC_H__
#define __GST_ASYNCDISKSRC_H__
#include <config.h>
#include <gst/gst.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_asyncdisksrc_details;
#define GST_TYPE_ASYNCDISKSRC \
(gst_asyncdisksrc_get_type())
#define GST_ASYNCDISKSRC(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_ASYNCDISKSRC,GstAsyncDiskSrc))
#define GST_ASYNCDISKSRC_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_ASYNCDISKSRC,GstAsyncDiskSrcClass))
#define GST_IS_ASYNCDISKSRC(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_ASYNCDISKSRC))
#define GST_IS_ASYNCDISKSRC_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_ASYNCDISKSRC)))
// NOTE: per-element flags start with 16 for now
typedef enum {
GST_ASYNCDISKSRC_OPEN = (1 << 16),
} GstAsyncDiskSrcFlags;
typedef struct _GstAsyncDiskSrc GstAsyncDiskSrc;
typedef struct _GstAsyncDiskSrcClass GstAsyncDiskSrcClass;
struct _GstAsyncDiskSrc {
GstSrc src;
/* pads */
GstPad *srcpad;
/* filename */
gchar *filename;
/* fd */
gint fd;
/* mapping parameters */
gulong size; /* how long is the file? */
guchar *map; /* where the file is mapped to */
/* details for fallback synchronous read */
gulong curoffset; /* current offset in file */
gulong bytes_per_read; /* bytes per read */
gulong seq; /* buffer sequence number */
};
struct _GstAsyncDiskSrcClass {
GstSrcClass parent_class;
};
GtkType gst_asyncdisksrc_get_type(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_ASYNCDISKSRC_H__ */

View file

@ -0,0 +1,291 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/soundcard.h>
#include <gstaudiosink.h>
#include <gst/meta/audioraw.h>
GstElementDetails gst_audiosink_details = {
"Audio Sink (OSS)",
"Sink/Audio",
"Output to a sound card via OSS",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999",
};
static gboolean gst_audiosink_open_audio(GstAudioSink *sink);
static void gst_audiosink_close_audio(GstAudioSink *sink);
static gboolean gst_audiosink_start(GstElement *element,
GstElementState state);
static gboolean gst_audiosink_stop(GstElement *element);
static gboolean gst_audiosink_change_state(GstElement *element,
GstElementState state);
/* AudioSink signals and args */
enum {
HANDOFF,
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
static void gst_audiosink_class_init(GstAudioSinkClass *klass);
static void gst_audiosink_init(GstAudioSink *audiosink);
static GstFilterClass *parent_class = NULL;
static guint gst_audiosink_signals[LAST_SIGNAL] = { 0 };
static guint16 gst_audiosink_type_audio = 0;
GtkType
gst_audiosink_get_type(void) {
static GtkType audiosink_type = 0;
if (!audiosink_type) {
static const GtkTypeInfo audiosink_info = {
"GstAudioSink",
sizeof(GstAudioSink),
sizeof(GstAudioSinkClass),
(GtkClassInitFunc)gst_audiosink_class_init,
(GtkObjectInitFunc)gst_audiosink_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
audiosink_type = gtk_type_unique(GST_TYPE_FILTER,&audiosink_info);
}
if (!gst_audiosink_type_audio)
gst_audiosink_type_audio = gst_type_find_by_mime("audio/raw");
return audiosink_type;
}
static void
gst_audiosink_class_init(GstAudioSinkClass *klass) {
GtkObjectClass *gtkobject_class;
GstElementClass *gstelement_class;
gtkobject_class = (GtkObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
parent_class = gtk_type_class(GST_TYPE_FILTER);
gst_audiosink_signals[HANDOFF] =
gtk_signal_new("handoff",GTK_RUN_LAST,gtkobject_class->type,
GTK_SIGNAL_OFFSET(GstAudioSinkClass,handoff),
gtk_marshal_NONE__POINTER_POINTER,GTK_TYPE_NONE,2,
GTK_TYPE_POINTER,GTK_TYPE_POINTER);
gtk_object_class_add_signals(gtkobject_class,gst_audiosink_signals,
LAST_SIGNAL);
gstelement_class->start = gst_audiosink_start;
gstelement_class->stop = gst_audiosink_stop;
gstelement_class->change_state = gst_audiosink_change_state;
}
static void gst_audiosink_init(GstAudioSink *audiosink) {
audiosink->sinkpad = gst_pad_new("sink",GST_PAD_SINK);
gst_element_add_pad(GST_ELEMENT(audiosink),audiosink->sinkpad);
if (!gst_audiosink_type_audio)
gst_audiosink_type_audio = gst_type_find_by_mime("audio/raw");
gst_pad_set_type_id(audiosink->sinkpad,gst_audiosink_type_audio);
gst_pad_set_chain_function(audiosink->sinkpad,gst_audiosink_chain);
audiosink->fd = -1;
gst_element_set_state(GST_ELEMENT(audiosink),GST_STATE_COMPLETE);
}
void gst_audiosink_sync_parms(GstAudioSink *audiosink) {
audio_buf_info ospace;
g_return_if_fail(audiosink != NULL);
g_return_if_fail(GST_IS_AUDIOSINK(audiosink));
g_return_if_fail(audiosink->fd > 0);
ioctl(audiosink->fd,SNDCTL_DSP_RESET,0);
ioctl(audiosink->fd,SNDCTL_DSP_SETFMT,&audiosink->format);
ioctl(audiosink->fd,SNDCTL_DSP_CHANNELS,&audiosink->channels);
ioctl(audiosink->fd,SNDCTL_DSP_SPEED,&audiosink->frequency);
ioctl(audiosink->fd,SNDCTL_DSP_GETOSPACE,&ospace);
g_print("setting sound card to %dKHz %d bit %s (%d bytes buffer)\n",
audiosink->frequency,audiosink->format,
(audiosink->channels == 2) ? "stereo" : "mono",ospace.bytes);
}
GstElement *gst_audiosink_new(gchar *name) {
GstElement *audiosink = GST_ELEMENT(gtk_type_new(GST_TYPE_AUDIOSINK));
gst_element_set_name(GST_ELEMENT(audiosink),name);
return audiosink;
}
void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) {
GstAudioSink *audiosink;
MetaAudioRaw *meta;
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail(buf != NULL);
/* this has to be an audio buffer */
// g_return_if_fail(((GstMeta *)buf->meta)->type !=
//gst_audiosink_type_audio);
audiosink = GST_AUDIOSINK(pad->parent);
// g_return_if_fail(GST_FLAG_IS_SET(audiosink,GST_STATE_RUNNING));
meta = (MetaAudioRaw *)gst_buffer_get_first_meta(buf);
if (meta != NULL) {
if ((meta->format != audiosink->format) ||
(meta->channels != audiosink->channels) ||
(meta->frequency != audiosink->frequency)) {
audiosink->format = meta->format;
audiosink->channels = meta->channels;
audiosink->frequency = meta->frequency;
gst_audiosink_sync_parms(audiosink);
g_print("sound device set to format %d, %d channels, %dHz\n",
audiosink->format,audiosink->channels,audiosink->frequency);
}
}
gtk_signal_emit(GTK_OBJECT(audiosink),gst_audiosink_signals[HANDOFF],
audiosink);
if (GST_BUFFER_DATA(buf) != NULL) {
gst_trace_add_entry(NULL,0,buf,"audiosink: writing to soundcard");
if (audiosink->fd > 2)
write(audiosink->fd,GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf));
}
gst_buffer_unref(buf);
// g_print("a");
}
void gst_audiosink_set_format(GstAudioSink *audiosink,gint format) {
g_return_if_fail(audiosink != NULL);
g_return_if_fail(GST_IS_AUDIOSINK(audiosink));
audiosink->format = format;
gst_audiosink_sync_parms(audiosink);
}
void gst_audiosink_set_channels(GstAudioSink *audiosink,gint channels) {
g_return_if_fail(audiosink != NULL);
g_return_if_fail(GST_IS_AUDIOSINK(audiosink));
audiosink->channels = channels;
gst_audiosink_sync_parms(audiosink);
}
void gst_audiosink_set_frequency(GstAudioSink *audiosink,gint frequency) {
g_return_if_fail(audiosink != NULL);
g_return_if_fail(GST_IS_AUDIOSINK(audiosink));
audiosink->frequency = frequency;
gst_audiosink_sync_parms(audiosink);
}
static gboolean gst_audiosink_open_audio(GstAudioSink *sink) {
g_return_if_fail(sink->fd == -1);
g_print("attempting to open sound device\n");
/* first try to open the sound card */
sink->fd = open("/dev/dsp",O_RDWR);
/* if we have it, set the default parameters and go have fun */
if (sink->fd > 0) {
/* set card state */
sink->format = AFMT_S16_LE;
sink->channels = 2; /* stereo */
sink->frequency = 44100;
gst_audiosink_sync_parms(sink);
g_print("opened audio\n");
return TRUE;
}
return FALSE;
}
static void gst_audiosink_close_audio(GstAudioSink *sink) {
if (sink->fd < 0) return;
close(sink->fd);
sink->fd = -1;
g_print("closed sound device\n");
}
static gboolean gst_audiosink_start(GstElement *element,
GstElementState state) {
g_return_if_fail(GST_IS_AUDIOSINK(element));
if (gst_audiosink_open_audio(GST_AUDIOSINK(element)) == TRUE) {
gst_element_set_state(element,GST_STATE_RUNNING | state);
return TRUE;
}
return FALSE;
}
static gboolean gst_audiosink_stop(GstElement *element) {
g_return_if_fail(GST_IS_AUDIOSINK(element));
gst_audiosink_close_audio(GST_AUDIOSINK(element));
gst_element_set_state(element,~GST_STATE_RUNNING);
return TRUE;
}
static gboolean gst_audiosink_change_state(GstElement *element,
GstElementState state) {
g_return_if_fail(GST_IS_AUDIOSINK(element));
switch (state) {
case GST_STATE_RUNNING:
if (!gst_audiosink_open_audio(GST_AUDIOSINK(element)))
return FALSE;
break;
case ~GST_STATE_RUNNING:
gst_audiosink_close_audio(GST_AUDIOSINK(element));
break;
default:
break;
}
if (GST_ELEMENT_CLASS(parent_class)->change_state)
return GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
return TRUE;
}

View file

@ -0,0 +1,85 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifndef __GST_AUDIOSINK_H__
#define __GST_AUDIOSINK_H__
#include <config.h>
#include <gst/gst.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_audiosink_details;
#define GST_TYPE_AUDIOSINK \
(gst_audiosink_get_type())
#define GST_AUDIOSINK(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_AUDIOSINK,GstAudioSink))
#define GST_AUDIOSINK_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIOSINK,GstAudioSinkClass))
#define GST_IS_AUDIOSINK(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_AUDIOSINK))
#define GST_IS_AUDIOSINK_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOSINK)))
typedef struct _GstAudioSink GstAudioSink;
typedef struct _GstAudioSinkClass GstAudioSinkClass;
struct _GstAudioSink {
GstFilter filter;
GstPad *sinkpad;
/* soundcard state */
int fd;
gint format;
gint channels;
gint frequency;
};
struct _GstAudioSinkClass {
GstFilterClass parent_class;
/* signals */
void (*handoff) (GstElement *element,GstPad *pad);
};
GtkType gst_audiosink_get_type(void);
GstElement *gst_audiosink_new(gchar *name);
void gst_audiosink_chain(GstPad *pad,GstBuffer *buf);
void gst_audiosink_sync_parms(GstAudioSink *audiosink);
void gst_audiosink_set_format(GstAudioSink *audiosink,gint format);
void gst_audiosink_set_channels(GstAudioSink *audiosink,gint channels);
void gst_audiosink_set_frequency(GstAudioSink *audiosink,gint frequency);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_AUDIOSINK_H__ */

Some files were not shown because too many files have changed in this diff Show more