Merging gst-omx

This commit is contained in:
Thibault Saunier 2021-09-24 16:14:59 -03:00
commit f627a5c2ed
112 changed files with 44438 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
*~
*.bak
*.swp

1
.gitlab-ci.yml Normal file
View file

@ -0,0 +1 @@
include: "https://gitlab.freedesktop.org/gstreamer/gst-ci/raw/master/gitlab/ci_template.yml"

2
AUTHORS Normal file
View file

@ -0,0 +1,2 @@
Sebastian Dröge <sebastian.droege@collabora.co.uk>

502
COPYING Normal file
View file

@ -0,0 +1,502 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

8029
ChangeLog Normal file

File diff suppressed because it is too large Load diff

299
NEWS Normal file
View file

@ -0,0 +1,299 @@
GStreamer 1.20 Release Notes
GStreamer 1.20 has not been released yet. It is scheduled for release
around October/November 2021.
1.19.x is the unstable development version that is being developed in
the git main branch and which will eventually result in 1.20, and 1.19.2
is the current development release in that series
It is expected that feature freeze will be in early October 2021,
followed by one or two 1.19.9x pre-releases and the new 1.20 stable
release around October/November 2021.
1.20 will be backwards-compatible to the stable 1.18, 1.16, 1.14, 1.12,
1.10, 1.8, 1.6,, 1.4, 1.2 and 1.0 release series.
See https://gstreamer.freedesktop.org/releases/1.20/ for the latest
version of this document.
Last updated: Wednesday 22 September 2021, 18:00 UTC (log)
Introduction
The GStreamer team is proud to announce a new major feature release in
the stable 1.x API series of your favourite cross-platform multimedia
framework!
As always, this release is again packed with many new features, bug
fixes and other improvements.
Highlights
- this section will be completed in due course
Major new features and changes
Noteworthy new features and API
- this section will be filled in in due course
New elements
- this section will be filled in in due course
New element features and additions
- this section will be filled in in due course
Plugin and library moves
- this section will be filled in in due course
- There were no plugin moves or library moves in this cycle.
Plugin removals
The following elements or plugins have been removed:
- this section will be filled in in due course
Miscellaneous API additions
- this section will be filled in in due course
Miscellaneous performance, latency and memory optimisations
- this section will be filled in in due course
Miscellaneous other changes and enhancements
- this section will be filled in in due course
Tracing framework and debugging improvements
- this section will be filled in in due course
Tools
- this section will be filled in in due course
GStreamer RTSP server
- this section will be filled in in due course
GStreamer VAAPI
- this section will be filled in in due course
GStreamer OMX
- this section will be filled in in due course
GStreamer Editing Services and NLE
- this section will be filled in in due course
GStreamer validate
- this section will be filled in in due course
GStreamer Python Bindings
- this section will be filled in in due course
GStreamer C# Bindings
- this section will be filled in in due course
GStreamer Rust Bindings and Rust Plugins
The GStreamer Rust bindings are released separately with a different
release cadence thats tied to gtk-rs, but the latest release has
already been updated for the upcoming new GStreamer 1.20 API.
gst-plugins-rs, the module containing GStreamer plugins written in Rust,
has also seen lots of activity with many new elements and plugins.
What follows is a list of elements and plugins available in
gst-plugins-rs, so people dont miss out on all those potentially useful
elements that have no C equivalent.
- FIXME: add new elements
Rust audio plugins
- audiornnoise: New element for audio denoising which implements the
noise removal algorithm of the Xiph RNNoise library, in Rust
- rsaudioecho: Port of the audioecho element from gst-plugins-good
rsaudioloudnorm: Live audio loudness normalization element based on
the FFmpeg af_loudnorm filter
- claxondec: FLAC lossless audio codec decoder element based on the
pure-Rust claxon implementation
- csoundfilter: Audio filter that can use any filter defined via the
Csound audio programming language
- lewtondec: Vorbis audio decoder element based on the pure-Rust
lewton implementation
Rust video plugins
- cdgdec/cdgparse: Decoder and parser for the CD+G video codec based
on a pure-Rust CD+G implementation, used for example by karaoke CDs
- cea608overlay: CEA-608 Closed Captions overlay element
- cea608tott: CEA-608 Closed Captions to timed-text (e.g. VTT or SRT
subtitles) converter
- tttocea608: CEA-608 Closed Captions from timed-text converter
- mccenc/mccparse: MacCaption Closed Caption format encoder and parser
- sccenc/sccparse: Scenarist Closed Caption format encoder and parser
- dav1dec: AV1 video decoder based on the dav1d decoder implementation
by the VLC project
- rav1enc: AV1 video encoder based on the fast and pure-Rust rav1e
encoder implementation
- rsflvdemux: Alternative to the flvdemux FLV demuxer element from
gst-plugins-good, not feature-equivalent yet
- rsgifenc/rspngenc: GIF/PNG encoder elements based on the pure-Rust
implementations by the image-rs project
Rust text plugins
- textwrap: Element for line-wrapping timed text (e.g. subtitles) for
better screen-fitting, including hyphenation support for some
languages
Rust network plugins
- reqwesthttpsrc: HTTP(S) source element based on the Rust
reqwest/hyper HTTP implementations and almost feature-equivalent
with the main GStreamer HTTP source souphttpsrc
- s3src/s3sink: Source/sink element for the Amazon S3 cloud storage
- awstranscriber: Live audio to timed text transcription element using
the Amazon AWS Transcribe API
Generic Rust plugins
- sodiumencrypter/sodiumdecrypter: Encryption/decryption element based
on libsodium/NaCl
- togglerecord: Recording element that allows to pause/resume
recordings easily and considers keyframe boundaries
- fallbackswitch/fallbacksrc: Elements for handling potentially
failing (network) sources, restarting them on errors/timeout and
showing a fallback stream instead
- threadshare: Set of elements that provide alternatives for various
existing GStreamer elements but allow to share the streaming threads
between each other to reduce the number of threads
- rsfilesrc/rsfilesink: File source/sink elements as replacements for
the existing filesrc/filesink elements
Build and Dependencies
- this section will be filled in in due course
gst-build
- this section will be filled in in due course
Cerbero
Cerbero is a meta build system used to build GStreamer plus dependencies
on platforms where dependencies are not readily available, such as
Windows, Android, iOS and macOS.
General improvements
- this section will be filled in in due course
macOS / iOS
- this section will be filled in in due course
Windows
- this section will be filled in in due course
Windows MSI installer
- this section will be filled in in due course
Linux
- this section will be filled in in due course
Android
- this section will be filled in in due course
Platform-specific changes and improvements
Android
- this section will be filled in in due course
macOS and iOS
- this section will be filled in in due course
Windows
- this section will be filled in in due course
Linux
- this section will be filled in in due course
Documentation improvements
- this section will be filled in in due course
Possibly Breaking Changes
- this section will be filled in in due course
- MPEG-TS SCTE-35 API changes (FIXME: flesh out)
- gst_parse_launch() and friends now error out on non-existing
properties on top-level bins where they would silently fail and
ignore those before.
Known Issues
- this section will be filled in in due course
- There are a couple of known WebRTC-related regressions/blockers:
- webrtc: DTLS setup with Chrome is broken
- webrtcbin: First keyframe is usually lost
Contributors
- this section will be filled in in due course
… and many others who have contributed bug reports, translations, sent
suggestions or helped testing.
Stable 1.20 branch
After the 1.20.0 release there will be several 1.20.x bug-fix releases
which will contain bug fixes which have been deemed suitable for a
stable branch, but no new features or intrusive changes will be added to
a bug-fix release usually. The 1.20.x bug-fix releases will be made from
the git 1.20 branch, which will be a stable branch.
1.20.0
1.20.0 is scheduled to be released around October/November 2021.
Schedule for 1.22
Our next major feature release will be 1.22, and 1.21 will be the
unstable development version leading up to the stable 1.22 release. The
development of 1.21/1.22 will happen in the git main branch.
The plan for the 1.22 development cycle is yet to be confirmed.
1.22 will be backwards-compatible to the stable 1.20, 1.18, 1.16, 1.14,
1.12, 1.10, 1.8, 1.6, 1.4, 1.2 and 1.0 release series.
------------------------------------------------------------------------
These release notes have been prepared by Tim-Philipp Müller with
contributions from …
License: CC BY-SA 4.0

17
README Normal file
View file

@ -0,0 +1,17 @@
GStreamer OpenMAX IL wrapper plugin
--------------------------
This plugin wraps available OpenMAX IL components and makes
them available as standard GStreamer elements.
License:
--------
This package and its contents are licensend under the GNU Lesser General
Public License (LGPL).
Dependencies:
-------------
* GStreamer core
* gst-plugins-base

96
RELEASE Normal file
View file

@ -0,0 +1,96 @@
This is GStreamer gst-omx 1.19.2.
GStreamer 1.19 is the development branch leading up to the next major
stable version which will be 1.20.
The 1.19 development series adds new features on top of the 1.18 series and is
part of the API and ABI-stable 1.x release series of the GStreamer multimedia
framework.
Full release notes will one day be found at:
https://gstreamer.freedesktop.org/releases/1.20/
Binaries for Android, iOS, Mac OS X and Windows will usually be provided
shortly after the release.
This module will not be very useful by itself and should be used in conjunction
with other GStreamer modules for a complete multimedia experience.
- gstreamer: provides the core GStreamer libraries and some generic plugins
- gst-plugins-base: a basic set of well-supported plugins and additional
media-specific GStreamer helper libraries for audio,
video, rtsp, rtp, tags, OpenGL, etc.
- gst-plugins-good: a set of well-supported plugins under our preferred
license
- gst-plugins-ugly: a set of well-supported plugins which might pose
problems for distributors
- gst-plugins-bad: a set of plugins of varying quality that have not made
their way into one of core/base/good/ugly yet, for one
reason or another. Many of these are are production quality
elements, but may still be missing documentation or unit
tests; others haven't passed the rigorous quality testing
we expect yet.
- gst-libav: a set of codecs plugins based on the ffmpeg library. This is
where you can find audio and video decoders and encoders
for a wide variety of formats including H.264, AAC, etc.
- gstreamer-vaapi: hardware-accelerated video decoding and encoding using
VA-API on Linux. Primarily for Intel graphics hardware.
- gst-omx: hardware-accelerated video decoding and encoding, primarily for
embedded Linux systems that provide an OpenMax
implementation layer such as the Raspberry Pi.
- gst-rtsp-server: library to serve files or streaming pipelines via RTSP
- gst-editing-services: library an plugins for non-linear editing
==== Download ====
You can find source releases of gstreamer in the download
directory: https://gstreamer.freedesktop.org/src/gstreamer/
The git repository and details how to clone it can be found at
https://gitlab.freedesktop.org/gstreamer/
==== Homepage ====
The project's website is https://gstreamer.freedesktop.org/
==== Support and Bugs ====
We have recently moved from GNOME Bugzilla to GitLab on freedesktop.org
for bug reports and feature requests:
https://gitlab.freedesktop.org/gstreamer
Please submit patches via GitLab as well, in form of Merge Requests. See
https://gstreamer.freedesktop.org/documentation/contribute/
for more details.
For help and support, please subscribe to and send questions to the
gstreamer-devel mailing list (see below for details).
There is also a #gstreamer IRC channel on the Freenode IRC network.
==== Developers ====
GStreamer source code repositories can be found on GitLab on freedesktop.org:
https://gitlab.freedesktop.org/gstreamer
and can also be cloned from there and this is also where you can submit
Merge Requests or file issues for bugs or feature requests.
Interested developers of the core library, plugins, and applications should
subscribe to the gstreamer-devel list:
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

View file

@ -0,0 +1,60 @@
[omxmpeg4videodec]
type-name=GstOMXMPEG4VideoDec
core-name=/usr/local/lib/libomxil-bellagio.so.0
component-name=OMX.st.video_decoder.mpeg4
rank=257
in-port-index=0
out-port-index=1
hacks=event-port-settings-changed-ndata-parameter-swap;event-port-settings-changed-port-0-to-1
[omxh264dec]
type-name=GstOMXH264Dec
core-name=/usr/local/lib/libomxil-bellagio.so.0
component-name=OMX.st.video_decoder.avc
rank=257
in-port-index=0
out-port-index=1
hacks=event-port-settings-changed-ndata-parameter-swap;event-port-settings-changed-port-0-to-1
[omxmpeg4videoenc]
type-name=GstOMXMPEG4VideoEnc
core-name=/usr/local/lib/libomxil-bellagio.so.0
component-name=OMX.st.video_encoder.mpeg4
rank=0
in-port-index=0
out-port-index=1
hacks=event-port-settings-changed-ndata-parameter-swap;video-framerate-integer;syncframe-flag-not-used
[omxaacenc]
type-name=GstOMXAACEnc
core-name=/usr/local/lib/libomxil-bellagio.so.0
component-name=OMX.st.audio_encoder.aac
rank=0
in-port-index=0
out-port-index=1
hacks=event-port-settings-changed-ndata-parameter-swap
[omxmp3dec]
type-name=GstOMXMP3Dec
core-name=/usr/lib/libomxil-bellagio.so.0
component-name=OMX.st.audio_decoder.mp3.mad
rank=0
in-port-index=0
out-port-index=1
hacks=event-port-settings-changed-ndata-parameter-swap;no-component-role;no-disable-outport;drain-may-not-return
[omxh264dec]
type-name=GstOMXH264Dec
core-name=/usr/lib/libomxil-bellagio.so.0
component-name=OMX.mesa.video_decoder.avc
rank=0
in-port-index=0
out-port-index=1
[omxmpeg2dec]
type-name=GstOMXMPEG2VideoDec
core-name=/usr/lib/libomxil-bellagio.so.0
component-name=OMX.mesa.video_decoder.mpeg2
rank=0
in-port-index=0
out-port-index=1

View file

@ -0,0 +1 @@
install_data (['gstomx.conf'], install_dir : omx_conf_dir)

20
config/meson.build Normal file
View file

@ -0,0 +1,20 @@
if omx_target == 'rpi'
sub = 'rpi'
elif omx_target == 'bellagio'
sub = 'bellagio'
elif omx_target == 'zynqultrascaleplus'
sub = 'zynqultrascaleplus'
elif omx_target == 'tizonia'
sub = 'tizonia'
else
# No config file defined for the 'generic' target
sub = ''
endif
if sub != ''
subdir (sub)
# Used by tests to load the proper conf file
omx_config_dir = join_paths (meson.current_source_dir(), sub)
else
omx_config_dir = ''
endif

102
config/rpi/gstomx.conf Normal file
View file

@ -0,0 +1,102 @@
[omxmpeg2videodec]
type-name=GstOMXMPEG2VideoDec
core-name=/opt/vc/lib/libopenmaxil.so
component-name=OMX.broadcom.video_decode
rank=257
in-port-index=130
out-port-index=131
hacks=no-component-role
[omxmpeg4videodec]
type-name=GstOMXMPEG4VideoDec
core-name=/opt/vc/lib/libopenmaxil.so
component-name=OMX.broadcom.video_decode
rank=257
in-port-index=130
out-port-index=131
hacks=no-component-role
[omxh263dec]
type-name=GstOMXH263Dec
core-name=/opt/vc/lib/libopenmaxil.so
component-name=OMX.broadcom.video_decode
rank=257
in-port-index=130
out-port-index=131
hacks=no-component-role
[omxh264dec]
type-name=GstOMXH264Dec
core-name=/opt/vc/lib/libopenmaxil.so
component-name=OMX.broadcom.video_decode
rank=257
in-port-index=130
out-port-index=131
hacks=no-component-role;signals-premature-eos
[omxtheoradec]
type-name=GstOMXTheoraDec
core-name=/opt/vc/lib/libopenmaxil.so
component-name=OMX.broadcom.video_decode
rank=257
in-port-index=130
out-port-index=131
hacks=no-component-role
[omxvp8dec]
type-name=GstOMXVP8Dec
core-name=/opt/vc/lib/libopenmaxil.so
component-name=OMX.broadcom.video_decode
rank=257
in-port-index=130
out-port-index=131
hacks=no-component-role
[omxmjpegdec]
type-name=GstOMXMJPEGDec
core-name=/opt/vc/lib/libopenmaxil.so
component-name=OMX.broadcom.video_decode
rank=257
in-port-index=130
out-port-index=131
hacks=no-component-role
[omxvc1dec]
type-name=GstOMXWMVDec
core-name=/opt/vc/lib/libopenmaxil.so
component-name=OMX.broadcom.video_decode
rank=257
in-port-index=130
out-port-index=131
hacks=no-component-role
sink-template-caps=video/x-wmv,wmvversion=(int)3,format=(string){WMV3,WVC1},width=(int)[1,MAX],height=(int)[1,MAX]
[omxh264enc]
type-name=GstOMXH264Enc
core-name=/opt/vc/lib/libopenmaxil.so
component-name=OMX.broadcom.video_encode
rank=257
in-port-index=200
out-port-index=201
hacks=no-component-role;no-component-reconfigure
[omxanalogaudiosink]
type-name=GstOMXAnalogAudioSink
core-name=/opt/vc/lib/libopenmaxil.so
component-name=OMX.broadcom.audio_render
rank=257
in-port-index=100
out-port-index=101
hacks=no-component-role
sink-template-caps=audio/x-raw,format=(string){S16LE,S32LE},layout=(string)interleaved,rate=(int){8000,11025,16000,22050,24000,32000,44100,48000,88200,96000,176400,192000},channels=(int)[1,2]
[omxhdmiaudiosink]
type-name=GstOMXHdmiAudioSink
core-name=/opt/vc/lib/libopenmaxil.so
component-name=OMX.broadcom.audio_render
rank=258
in-port-index=100
out-port-index=101
hacks=no-component-role
sink-template-caps=audio/x-raw,format=(string){S16LE,S32LE},layout=(string)interleaved,rate=(int){8000,11025,16000,22050,24000,32000,44100,48000,88200,96000,176400,192000},channels=(int)[1,8];audio/x-ac3,framed=(boolean)true;audio/x-dts,framed=(boolean)true,block-size=(int){512,1024,2048}

1
config/rpi/meson.build Normal file
View file

@ -0,0 +1 @@
install_data (['gstomx.conf'], install_dir : omx_conf_dir)

View file

@ -0,0 +1,49 @@
[omxmp3dec]
type-name=GstOMXMP3Dec
core-name=@TIZONIA_LIBDIR@/libtizcore.so
component-name=OMX.Aratelia.audio_decoder.mp3
rank=0
in-port-index=0
out-port-index=1
[omxmp3enc]
type-name=GstOMXMP3Enc
core-name=@TIZONIA_LIBDIR@/libtizcore.so
component-name=OMX.Aratelia.audio_encoder.mp3
rank=0
in-port-index=0
out-port-index=1
[omxaacdec]
type-name=GstOMXAACDec
core-name=@TIZONIA_LIBDIR@/libtizcore.so
component-name=OMX.Aratelia.audio_decoder.aac
rank=0
in-port-index=0
out-port-index=1
[omxvp8dec]
type-name=GstOMXVP8Dec
core-name=@TIZONIA_LIBDIR@/libtizcore.so
component-name=OMX.Aratelia.video_decoder.vp8
rank=0
in-port-index=0
out-port-index=1
[omxh264dec]
type-name=GstOMXH264Dec
core-name=@TIZONIA_LIBDIR@/libtizcore.so
component-name=OMX.mesa.video.all
component-role=video_decoder.avc
rank=0
in-port-index=0
out-port-index=1
[omxh264enc]
type-name=GstOMXH264Enc
core-name=@TIZONIA_LIBDIR@/libtizcore.so
component-name=OMX.mesa.video.all
component-role=video_encoder.avc
rank=0
in-port-index=0
out-port-index=1

View file

@ -0,0 +1,5 @@
tizonia_cdata = cdata
configure_file(input : 'gstomx.conf.in',
output : 'gstomx.conf',
configuration : tizonia_cdata,
install_dir : omx_conf_dir)

View file

@ -0,0 +1,35 @@
[omxh264enc]
type-name=GstOMXH264Enc
core-name=/usr/lib/libOMX.allegro.core.so.1
component-name=OMX.allegro.h264.encoder
in-port-index=0
out-port-index=1
rank=257
hacks=ensure-buffer-count-actual
[omxh264dec]
type-name=GstOMXH264Dec
core-name=/usr/lib/libOMX.allegro.core.so.1
component-name=OMX.allegro.h264.decoder
in-port-index=0
out-port-index=1
rank=257
hacks=pass-profile-to-decoder;pass-color-format-to-decoder;ensure-buffer-count-actual
[omxh265enc]
type-name=GstOMXH265Enc
core-name=/usr/lib/libOMX.allegro.core.so.1
component-name=OMX.allegro.h265.encoder
in-port-index=0
out-port-index=1
rank=257
hacks=ensure-buffer-count-actual
[omxh265dec]
type-name=GstOMXH265Dec
core-name=/usr/lib/libOMX.allegro.core.so.1
component-name=OMX.allegro.h265.decoder
in-port-index=0
out-port-index=1
rank=257
hacks=pass-profile-to-decoder;pass-color-format-to-decoder;ensure-buffer-count-actual

View file

@ -0,0 +1 @@
install_data (['gstomx.conf'], install_dir : omx_conf_dir)

View file

@ -0,0 +1,13 @@
{
"omx": {
"description": "GStreamer OpenMAX Plug-ins",
"elements": {},
"filename": "gstomx",
"license": "LGPL",
"other-types": {},
"package": "GStreamer OpenMAX Plug-ins",
"source": "gst-omx",
"tracers": {},
"url": "Unknown package origin"
}
}

3
docs/index.md Normal file
View file

@ -0,0 +1,3 @@
---
short-description: GStreamer plugins from OpenMax
...

62
docs/meson.build Normal file
View file

@ -0,0 +1,62 @@
build_hotdoc = false
if meson.is_cross_build()
if get_option('doc').enabled()
error('Documentation enabled but building the doc while cross building is not supported yet.')
endif
message('Documentation not built as building the docmentation while cross building is not supported yet.')
subdir_done()
endif
required_hotdoc_extensions = ['gst-extension']
if gst_dep.type_name() == 'internal'
gst_proj = subproject('gstreamer')
plugins_cache_generator = gst_proj.get_variable('plugins_cache_generator')
else
required_hotdoc_extensions += ['gst-extension']
plugins_cache_generator = find_program(join_paths(gst_dep.get_pkgconfig_variable('libexecdir'), 'gstreamer-' + api_version, 'gst-plugins-doc-cache-generator'),
required: false)
endif
plugins_cache = join_paths(meson.current_source_dir(), 'gst_plugins_cache.json')
if plugins_cache_generator.found()
plugins_doc_dep = custom_target('omx-plugins-doc-cache',
command: [plugins_cache_generator, plugins_cache, '@OUTPUT@', '@INPUT@'],
input: plugins,
output: 'gst_plugins_cache.json',
)
else
warning('GStreamer plugin inspector for documentation not found, can\'t update the cache')
endif
hotdoc_p = find_program('hotdoc', required: get_option('doc'))
if not hotdoc_p.found()
message('Hotdoc not found, not building the documentation')
subdir_done()
endif
build_hotdoc = true
hotdoc = import('hotdoc')
if not hotdoc.has_extensions(required_hotdoc_extensions)
if get_option('doc').enabled()
error('Documentation enabled but gi-extension missing')
endif
message('@0@ extensions not found, not building documentation'.format(required_hotdoc_extensions))
subdir_done()
endif
message('Plugins: @0@'.format(plugins))
libs_doc = []
plugins_doc = [hotdoc.generate_doc('omx',
project_version: api_version,
sitemap: 'sitemap.txt',
index: 'index.md',
gst_index: 'index.md',
gst_smart_index: true,
gst_c_sources: ['../gst/*/*.[ch]',],
gst_cache_file: plugins_cache,
gst_plugin_name: 'omx',
dependencies: [gstomx],
)]

1
docs/sitemap.txt Normal file
View file

@ -0,0 +1 @@
gst-index

View file

@ -0,0 +1,100 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Spatial coordinates for the cube
static const GLfloat quadx[6*4*3] = {
/* FRONT */
-1.f, -1.f, 1.f,
1.f, -1.f, 1.f,
-1.f, 1.f, 1.f,
1.f, 1.f, 1.f,
/* BACK */
-1.f, -1.f, -1.f,
-1.f, 1.f, -1.f,
1.f, -1.f, -1.f,
1.f, 1.f, -1.f,
/* LEFT */
-1.f, -1.f, 1.f,
-1.f, 1.f, 1.f,
-1.f, -1.f, -1.f,
-1.f, 1.f, -1.f,
/* RIGHT */
1.f, -1.f, -1.f,
1.f, 1.f, -1.f,
1.f, -1.f, 1.f,
1.f, 1.f, 1.f,
/* TOP */
-1.f, 1.f, 1.f,
1.f, 1.f, 1.f,
-1.f, 1.f, -1.f,
1.f, 1.f, -1.f,
/* BOTTOM */
-1.f, -1.f, 1.f,
-1.f, -1.f, -1.f,
1.f, -1.f, 1.f,
1.f, -1.f, -1.f,
};
/** Texture coordinates for the quad. */
static const GLfloat texCoords[6 * 4 * 2] = {
0.f, 0.f,
1.f, 0.f,
0.f, 1.f,
1.f, 1.f,
0.f, 0.f,
1.f, 0.f,
0.f, 1.f,
1.f, 1.f,
0.f, 0.f,
1.f, 0.f,
0.f, 1.f,
1.f, 1.f,
0.f, 0.f,
1.f, 0.f,
0.f, 1.f,
1.f, 1.f,
0.f, 0.f,
1.f, 0.f,
0.f, 1.f,
1.f, 1.f,
0.f, 0.f,
1.f, 0.f,
0.f, 1.f,
1.f, 1.f,
};

31
examples/egl/meson.build Normal file
View file

@ -0,0 +1,31 @@
optional_deps = []
if x11_dep.found()
optional_deps += x11_dep
endif
if x11_dep.found() or omx_target == 'rpi'
egl_sources = ['testegl.c']
egl_dep = dependency('egl', required : false)
if not egl_dep.found()
egl_dep = cc.find_library ('EGL')
endif
gles2_dep = dependency('glesv2', required : false)
if not gles2_dep.found()
gles2_dep = cc.find_library ('GLESv2')
endif
if omx_target == 'rpi'
brcmegl_dep = dependency('brcmegl', required : true)
optional_deps += brcmegl_dep
endif
executable ('testegl',
sources : egl_sources,
c_args : gst_omx_args,
include_directories : [configinc],
dependencies : [libm, gst_dep, gstvideo_dep, gstgl_dep, egl_dep,
gles2_dep] + optional_deps
)
endif

1611
examples/egl/testegl.c Normal file

File diff suppressed because it is too large Load diff

3
examples/meson.build Normal file
View file

@ -0,0 +1,3 @@
if gstgl_dep.found()
subdir('egl')
endif

332
gst-omx.doap Normal file
View file

@ -0,0 +1,332 @@
<Project
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns="http://usefulinc.com/ns/doap#"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:admin="http://webns.net/mvcb/">
<name>GStreamer OpenMAX IL wrapper plugin</name>
<shortname>gst-omx</shortname>
<homepage rdf:resource="http://gstreamer.freedesktop.org/modules/gst-omx.html" />
<created>2005-06-17</created>
<shortdesc xml:lang="en">
a basic collection of elements
</shortdesc>
<description xml:lang="en">
This plugin wraps available OpenMAX IL components and makes
them available as standard GStreamer elements.
</description>
<category></category>
<bug-database rdf:resource="https://gitlab.freedesktop.org/gstreamer/gst-omx/issues/" />
<screenshots></screenshots>
<mailing-list rdf:resource="http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel" />
<programming-language>C</programming-language>
<license rdf:resource="http://usefulinc.com/doap/licenses/lgpl"/>
<download-page rdf:resource="http://gstreamer.freedesktop.org/download/" />
<repository>
<GitRepository>
<location rdf:resource="git://gitlab.freedesktop.org/gstreamer/gst-omx"/>
<browse rdf:resource="http://gitlab.freedesktop.org/gstreamer/gst-omx"/>
</GitRepository>
</repository>
<release>
<Version>
<revision>1.19.2</revision>
<branch>master</branch>
<name></name>
<created>2021-09-23</created>
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.19.2.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.19.1</revision>
<branch>master</branch>
<name></name>
<created>2021-06-01</created>
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.19.1.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.18.0</revision>
<branch>master</branch>
<name></name>
<created>2020-09-08</created>
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.18.0.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.17.90</revision>
<branch>master</branch>
<name></name>
<created>2020-08-20</created>
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.17.90.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.17.2</revision>
<branch>master</branch>
<name></name>
<created>2020-07-03</created>
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.17.2.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.17.1</revision>
<branch>master</branch>
<name></name>
<created>2020-06-19</created>
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.17.1.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.16.0</revision>
<branch>master</branch>
<name></name>
<created>2019-04-19</created>
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.16.0.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.15.90</revision>
<branch>master</branch>
<name></name>
<created>2019-04-11</created>
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.15.90.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.15.2</revision>
<branch>master</branch>
<name></name>
<created>2019-02-26</created>
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.15.2.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.15.1</revision>
<branch>master</branch>
<name></name>
<created>2019-01-17</created>
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.15.1.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.14.0</revision>
<branch>master</branch>
<name></name>
<created>2018-03-19</created>
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.14.0.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.13.91</revision>
<branch>master</branch>
<name></name>
<created>2018-03-13</created>
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.13.91.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.13.90</revision>
<branch>master</branch>
<name></name>
<created>2018-03-03</created>
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.13.90.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.13.1</revision>
<branch>master</branch>
<name></name>
<created>2018-02-15</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.13.1.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.12.4</revision>
<branch>1.12</branch>
<name></name>
<created>2017-12-07</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.12.4.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.12.3</revision>
<branch>1.12</branch>
<name></name>
<created>2017-09-18</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.12.3.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.12.2</revision>
<branch>1.12</branch>
<name></name>
<created>2017-07-14</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.12.2.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.12.1</revision>
<branch>1.12</branch>
<name></name>
<created>2017-06-20</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.12.1.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.12.0</revision>
<branch>master</branch>
<name></name>
<created>2017-05-04</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.12.0.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.11.91</revision>
<branch>master</branch>
<name></name>
<created>2017-04-27</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.11.91.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.11.90</revision>
<branch>master</branch>
<name></name>
<created>2017-04-07</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.11.90.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.11.2</revision>
<branch>master</branch>
<name></name>
<created>2017-02-24</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.11.2.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.11.1</revision>
<branch>master</branch>
<name></name>
<created>2017-01-12</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.11.1.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.10.0</revision>
<branch>master</branch>
<name></name>
<created>2016-11-01</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.10.0.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.9.90</revision>
<branch>master</branch>
<name></name>
<created>2016-09-30</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.9.90.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.9.2</revision>
<branch>master</branch>
<name></name>
<created>2016-09-01</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.9.2.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.9.1</revision>
<branch>master</branch>
<name></name>
<created>2016-06-06</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.9.1.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.2.0</revision>
<branch>1.2</branch>
<name></name>
<created>2014-07-23</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.2.0.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.0.0</revision>
<branch>1.0</branch>
<name></name>
<created>2013-03-22</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.0.0.tar.xz" />
</Version>
</release>
<maintainer>
<foaf:Person>
<foaf:name>Sebastian Dröge</foaf:name>
<foaf:mbox_sha1sum>7c1069ea873ef7751e4eca5f1a42744b0e9a3a0a</foaf:mbox_sha1sum>
</foaf:Person>
</maintainer>
</Project>

83
hooks/pre-commit.hook Executable file
View file

@ -0,0 +1,83 @@
#!/bin/sh
#
# Check that the code follows a consistant code style
#
# Check for existence of indent, and error out if not present.
# On some *bsd systems the binary seems to be called gnunindent,
# so check for that first.
version=`gnuindent --version 2>/dev/null`
if test "x$version" = "x"; then
version=`gindent --version 2>/dev/null`
if test "x$version" = "x"; then
version=`indent --version 2>/dev/null`
if test "x$version" = "x"; then
echo "GStreamer git pre-commit hook:"
echo "Did not find GNU indent, please install it before continuing."
exit 1
else
INDENT=indent
fi
else
INDENT=gindent
fi
else
INDENT=gnuindent
fi
case `$INDENT --version` in
GNU*)
;;
default)
echo "GStreamer git pre-commit hook:"
echo "Did not find GNU indent, please install it before continuing."
echo "(Found $INDENT, but it doesn't seem to be GNU indent)"
exit 1
;;
esac
INDENT_PARAMETERS="--braces-on-if-line \
--case-brace-indentation0 \
--case-indentation2 \
--braces-after-struct-decl-line \
--line-length80 \
--no-tabs \
--cuddle-else \
--dont-line-up-parentheses \
--continuation-indentation4 \
--honour-newlines \
--tab-size8 \
--indent-level2 \
--leave-preprocessor-space"
echo "--Checking style--"
for file in `git diff-index --cached --name-only HEAD --diff-filter=ACMR| grep "\.c$"` ; do
# nf is the temporary checkout. This makes sure we check against the
# revision in the index (and not the checked out version).
nf=`git checkout-index --temp ${file} | cut -f 1`
newfile=`mktemp /tmp/${nf}.XXXXXX` || exit 1
$INDENT ${INDENT_PARAMETERS} \
$nf -o $newfile 2>> /dev/null
# FIXME: Call indent twice as it tends to do line-breaks
# different for every second call.
$INDENT ${INDENT_PARAMETERS} \
$newfile 2>> /dev/null
diff -u -p "${nf}" "${newfile}"
r=$?
rm "${newfile}"
rm "${nf}"
if [ $r != 0 ] ; then
echo "================================================================================================="
echo " Code style error in: $file "
echo " "
echo " Please fix before committing. Don't forget to run git add before trying to commit again. "
echo " If the whole file is to be committed, this should work (run from the top-level directory): "
echo " "
echo " gst-indent $file; git add $file; git commit"
echo " "
echo "================================================================================================="
exit 1
fi
done
echo "--Checking style pass--"

432
meson.build Normal file
View file

@ -0,0 +1,432 @@
project('gst-omx', 'c',
version : '1.19.2',
meson_version : '>= 0.54',
default_options : [ 'warning_level=1',
'buildtype=debugoptimized' ])
gst_version = meson.project_version()
version_arr = gst_version.split('.')
gst_version_major = version_arr[0].to_int()
gst_version_minor = version_arr[1].to_int()
gst_version_micro = version_arr[2].to_int()
if version_arr.length() == 4
gst_version_nano = version_arr[3].to_int()
else
gst_version_nano = 0
endif
glib_req = '>= 2.56.0'
gst_req = '>= @0@.@1@.0'.format(gst_version_major, gst_version_minor)
tizil_req = '>= 0.19.0'
api_version = '1.0'
plugins_install_dir = '@0@/gstreamer-1.0'.format(get_option('libdir'))
cc = meson.get_compiler('c')
if cc.get_id() == 'msvc'
msvc_args = [
# Ignore several spurious warnings for things gstreamer does very commonly
# If a warning is completely useless and spammy, use '/wdXXXX' to suppress it
# If a warning is harmless but hard to fix, use '/woXXXX' so it's shown once
# NOTE: Only add warnings here if you are sure they're spurious
'/wd4018', # implicit signed/unsigned conversion
'/wd4146', # unary minus on unsigned (beware INT_MIN)
'/wd4244', # lossy type conversion (e.g. double -> int)
'/wd4305', # truncating type conversion (e.g. double -> float)
cc.get_supported_arguments(['/utf-8']), # set the input encoding to utf-8
# Enable some warnings on MSVC to match GCC/Clang behaviour
'/w14062', # enumerator 'identifier' in switch of enum 'enumeration' is not handled
'/w14101', # 'identifier' : unreferenced local variable
'/w14189', # 'identifier' : local variable is initialized but not referenced
]
add_project_arguments(msvc_args, language: 'c')
# Disable SAFESEH with MSVC for plugins and libs that use external deps that
# are built with MinGW
noseh_link_args = ['/SAFESEH:NO']
else
noseh_link_args = []
endif
cdata = configuration_data()
check_headers = [
# ['HAVE_DLFCN_H', 'dlfcn.h'],
# ['HAVE_FCNTL_H', 'fcntl.h'],
# ['HAVE_INTTYPES_H', 'inttypes.h'],
# ['HAVE_MEMORY_H', 'memory.h'],
# ['HAVE_MSACM_H', 'msacm.h'],
# ['HAVE_PTHREAD_H', 'pthread.h'],
# ['HAVE_STDINT_H', 'stdint.h'],
# ['HAVE_STDLIB_H', 'stdlib.h'],
# ['HAVE_STRINGS_H', 'strings.h'],
# ['HAVE_STRING_H', 'string.h'],
# ['HAVE_SYS_PARAM_H', 'sys/param.h'],
# ['HAVE_SYS_SOCKET_H', 'sys/socket.h'],
# ['HAVE_SYS_STAT_H', 'sys/stat.h'],
# ['HAVE_SYS_TIME_H', 'sys/time.h'],
# ['HAVE_SYS_TYPES_H', 'sys/types.h'],
# ['HAVE_SYS_UTSNAME_H', 'sys/utsname.h'],
# ['HAVE_UNISTD_H', 'unistd.h'],
]
foreach h : check_headers
if cc.has_header(h.get(1))
cdata.set(h.get(0), 1)
endif
endforeach
check_functions = [
# check token HAVE_CPU_ALPHA
# check token HAVE_CPU_ARM
# check token HAVE_CPU_CRIS
# check token HAVE_CPU_CRISV32
# check token HAVE_CPU_HPPA
# check token HAVE_CPU_I386
# check token HAVE_CPU_IA64
# check token HAVE_CPU_M68K
# check token HAVE_CPU_MIPS
# check token HAVE_CPU_PPC
# check token HAVE_CPU_PPC64
# check token HAVE_CPU_S390
# check token HAVE_CPU_SPARC
# check token HAVE_CPU_X86_64
# ['HAVE_DCGETTEXT', 'dcgettext'],
# check token HAVE_EXPERIMENTAL
# check token HAVE_EXTERNAL
# ['HAVE_GETPAGESIZE', 'getpagesize'],
# check token HAVE_GETTEXT
]
foreach f : check_functions
if cc.has_function(f.get(1))
cdata.set(f.get(0), 1)
endif
endforeach
#cdata.set('SIZEOF_CHAR', cc.sizeof('char'))
#cdata.set('SIZEOF_INT', cc.sizeof('int'))
#cdata.set('SIZEOF_LONG', cc.sizeof('long'))
#cdata.set('SIZEOF_SHORT', cc.sizeof('short'))
#cdata.set('SIZEOF_VOIDP', cc.sizeof('void*'))
cdata.set('VERSION', '"@0@"'.format(gst_version))
cdata.set('PACKAGE', '"gst-omx"')
cdata.set('PACKAGE_VERSION', '"@0@"'.format(gst_version))
cdata.set('PACKAGE_BUGREPORT', '"https://gitlab.freedesktop.org/gstreamer/gst-omx/issues/new"')
cdata.set('PACKAGE_NAME', '"GStreamer OMX Plugins"')
cdata.set('GETTEXT_PACKAGE', '"gst-omx-1.0"')
cdata.set('GST_API_VERSION', '"@0@"'.format(api_version))
cdata.set('GST_PACKAGE_NAME', '"GStreamer OpenMAX Plug-ins"')
cdata.set('GST_PACKAGE_ORIGIN', '"Unknown package origin"')
cdata.set('GST_LICENSE', '"LGPL"')
cdata.set('LIBDIR', '"@0@"'.format(get_option('libdir')))
# FIXME: This should be exposed as a configuration option
host_system = host_machine.system()
if host_system == 'linux'
cdata.set('DEFAULT_VIDEOSRC', '"v4l2src"')
elif host_system == 'osx'
cdata.set('DEFAULT_VIDEOSRC', '"avfvideosrc"')
else
cdata.set('DEFAULT_VIDEOSRC', '"videotestsrc"')
endif
# Mandatory GST deps
gst_dep = dependency('gstreamer-1.0', version : gst_req,
fallback : ['gstreamer', 'gst_dep'])
gstbase_dep = dependency('gstreamer-base-1.0', version : gst_req,
fallback : ['gstreamer', 'gst_base_dep'])
gstcontroller_dep = dependency('gstreamer-controller-1.0', version : gst_req,
fallback : ['gstreamer', 'gst_controller_dep'])
gstallocators_dep = dependency('gstreamer-allocators-1.0', version : gst_req,
fallback : ['gst-plugins-base', 'allocators_dep'])
gstpbutils_dep = dependency('gstreamer-pbutils-1.0', version : gst_req,
fallback : ['gst-plugins-base', 'pbutils_dep'])
gstaudio_dep = dependency('gstreamer-audio-1.0', version : gst_req,
fallback : ['gst-plugins-base', 'audio_dep'])
gstfft_dep = dependency('gstreamer-fft-1.0', version : gst_req,
fallback : ['gst-plugins-base', 'fft_dep'])
gsttag_dep = dependency('gstreamer-tag-1.0', version : gst_req,
fallback : ['gst-plugins-base', 'tag_dep'])
gstvideo_dep = dependency('gstreamer-video-1.0', version : gst_req,
fallback : ['gst-plugins-base', 'video_dep'])
gstgl_dep = dependency('gstreamer-gl-1.0', version : gst_req,
fallback : ['gst-plugins-base', 'gstgl_dep'], required : false)
x11_dep = dependency('x11', required : false)
gstcheck_dep = dependency('gstreamer-check-1.0', version : gst_req,
required : get_option('tests'),
fallback : ['gstreamer', 'gst_check_dep'])
libm = cc.find_library('m', required : false)
glib_dep = dependency('glib-2.0', version : glib_req, fallback: ['glib', 'libglib_dep'])
gio_dep = dependency('gio-2.0', version : glib_req, fallback: ['glib', 'libgio_dep'] )
gmodule_dep = dependency('gmodule-2.0', version : glib_req, fallback: ['glib', 'libgmodule_dep'])
gst_omx_args = ['-DHAVE_CONFIG_H']
configinc = include_directories('.')
omx_header_path = get_option('header_path')
if omx_header_path != ''
omx_inc = []
gst_omx_args += ['-I' + omx_header_path]
else
omx_inc = include_directories (join_paths ('omx', 'openmax'))
endif
default_omx_struct_packing = 0
omx_target = get_option ('target')
if omx_target == 'generic'
cdata.set('USE_OMX_TARGET_GENERIC', 1)
elif omx_target == 'rpi'
cdata.set('USE_OMX_TARGET_RPI', 1)
cdata.set('OMX_SKIP64BIT', 1)
default_omx_struct_packing = 4
if gstgl_dep.found()
if gstgl_dep.type_name() == 'pkgconfig'
gl_winsys = gstgl_dep.get_pkgconfig_variable('gl_winsys').split(' ')
gl_platforms = gstgl_dep.get_pkgconfig_variable('gl_platforms').split(' ')
elif gstgl_dep.type_name() == 'internal'
# XXX assume gst-plugins-base was built with dispmanx and egl support
gl_winsys = ['dispmanx']
gl_platforms = ['egl']
else
error ('unreachable dependency type')
endif
if not gl_winsys.contains('dispmanx') or not gl_platforms.contains ('egl')
gstgl_dep = dependency('', required : false)
endif
endif
elif omx_target == 'bellagio'
cdata.set('USE_OMX_TARGET_BELLAGIO', 1)
elif omx_target == 'zynqultrascaleplus'
cdata.set('USE_OMX_TARGET_ZYNQ_USCALE_PLUS', 1)
have_allegro_header = cc.has_header (
'OMX_Allegro.h',
args : gst_omx_args,
include_directories : [omx_inc])
if not have_allegro_header
error ('Need Allegro OMX headers to build for Zynq UltraScale+. Use -Dheader_path option to specify the path of those headers.')
endif
elif omx_target == 'tizonia'
if omx_header_path != ''
warning('Ignoring -Dheader_path because path is in tizilheaders.pc')
endif
cdata.set('USE_OMX_TARGET_TIZONIA', 1)
tizil_dep = dependency('tizilheaders', version : tizil_req)
cdata.set('TIZONIA_LIBDIR', tizil_dep.get_pkgconfig_variable('libdir'))
tizil_includedir = tizil_dep.get_pkgconfig_variable('includedir')
gst_omx_args += ['-I' + tizil_includedir + '/tizonia']
omx_inc = []
else
error ('Unsupported omx target specified. Use the -Dtarget option')
endif
message ('OMX target: ' + omx_target)
extra_video_headers = ''
# Check for optional OpenMAX extension headers
if cc.has_header (
'OMX_VideoExt.h',
args : gst_omx_args,
include_directories : [omx_inc])
extra_video_headers += '''
#include <OMX_VideoExt.h>'''
cdata.set ('HAVE_VIDEO_EXT', 1)
endif
if cc.has_header (
'OMX_IndexExt.h',
args : gst_omx_args,
include_directories : [omx_inc])
cdata.set ('HAVE_INDEX_EXT', 1)
endif
if cc.has_header (
'OMX_ComponentExt.h',
args : gst_omx_args,
include_directories : [omx_inc])
cdata.set ('HAVE_COMPONENT_EXT', 1)
endif
if cc.has_header (
'OMX_CoreExt.h',
args : gst_omx_args)
cdata.set ('HAVE_CORE_EXT', 1)
endif
if cc.has_header (
'OMX_AudioExt.h',
args : gst_omx_args)
cdata.set ('HAVE_AUDIO_EXT', 1)
endif
if cc.has_header (
'OMX_IVCommonExt.h',
args : gst_omx_args)
cdata.set ('HAVE_IV_COMMON_EXT', 1)
endif
if cc.has_header (
'OMX_ImageExt.h',
args : gst_omx_args)
cdata.set ('HAVE_IMAGE_EXT', 1)
endif
if cc.has_header (
'OMX_OtherExt.h',
args : gst_omx_args)
cdata.set ('HAVE_OTHER_EXT', 1)
endif
have_omx_vp8 = cc.has_header_symbol(
'OMX_Video.h',
'OMX_VIDEO_CodingVP8',
prefix : extra_video_headers,
args : gst_omx_args,
include_directories : [omx_inc])
if have_omx_vp8
cdata.set('HAVE_VP8', 1)
endif
have_omx_theora = cc.has_header_symbol(
'OMX_Video.h',
'OMX_VIDEO_CodingTheora',
prefix : extra_video_headers,
args : gst_omx_args,
include_directories : [omx_inc])
if have_omx_theora
cdata.set('HAVE_THEORA', 1)
endif
have_omx_hevc = cc.has_header_symbol(
'OMX_Video.h',
'OMX_VIDEO_CodingHEVC',
prefix : extra_video_headers,
args : gst_omx_args,
include_directories : [omx_inc])
if have_omx_hevc
cdata.set('HAVE_HEVC', 1)
endif
if gstgl_dep.found()
cdata.set ('HAVE_GST_GL', 1)
endif
if x11_dep.found()
cdata.set ('HAVE_X11', 1)
endif
omx_struct_packing = get_option ('struct_packing').to_int()
if omx_struct_packing == 0
omx_struct_packing = default_omx_struct_packing
endif
if omx_struct_packing != 0
cdata.set('GST_OMX_STRUCT_PACKING', omx_struct_packing)
endif
omx_conf_dir = join_paths (get_option ('prefix'), get_option ('sysconfdir'), 'xdg')
cdata.set_quoted('GST_OMX_CONFIG_DIR', omx_conf_dir)
warning_flags = [
'-Wmissing-declarations',
'-Wredundant-decls',
'-Wwrite-strings',
'-Winit-self',
'-Wmissing-include-dirs',
'-Wno-multichar',
'-Wvla',
'-Wpointer-arith',
'-Wundef',
]
warning_c_flags = [
'-Wmissing-prototypes',
'-Wdeclaration-after-statement',
'-Wold-style-definition',
'-Waggregate-return',
]
have_cxx = add_languages('cpp', required : false)
if have_cxx
cxx = meson.get_compiler('cpp')
endif
foreach extra_arg : warning_flags
if cc.has_argument (extra_arg)
add_project_arguments([extra_arg], language: 'c')
endif
if have_cxx and cxx.has_argument (extra_arg)
add_project_arguments([extra_arg], language: 'cpp')
endif
endforeach
foreach extra_arg : warning_c_flags
if cc.has_argument (extra_arg)
add_project_arguments([extra_arg], language: 'c')
endif
endforeach
# Disable compiler warnings for unused variables and args if gst debug system is disabled
if gst_dep.type_name() == 'internal'
gst_debug_disabled = not subproject('gstreamer').get_variable('gst_debug')
else
# We can't check that in the case of subprojects as we won't
# be able to build against an internal dependency (which is not built yet)
gst_debug_disabled = cc.has_header_symbol('gst/gstconfig.h', 'GST_DISABLE_GST_DEBUG', dependencies: gst_dep)
endif
if gst_debug_disabled
message('GStreamer debug system is disabled')
if cc.has_argument('-Wno-unused')
add_project_arguments('-Wno-unused', language: 'c')
endif
if have_cxx and cxx.has_argument ('-Wno-unused')
add_project_arguments('-Wno-unused', language: 'cpp')
endif
else
message('GStreamer debug system is enabled')
endif
subdir('config')
if not get_option('examples').disabled()
subdir('examples')
endif
subdir('omx')
if not get_option('tools').disabled()
subdir('tools')
endif
if not get_option('tests').disabled() and gstcheck_dep.found()
subdir('tests')
endif
subdir('docs')
# Set release date
if gst_version_nano == 0
extract_release_date = find_program('scripts/extract-release-date-from-doap-file.py')
run_result = run_command(extract_release_date, gst_version, files('gst-omx.doap'))
if run_result.returncode() == 0
release_date = run_result.stdout().strip()
cdata.set_quoted('GST_PACKAGE_RELEASE_DATETIME', release_date)
message('Package release date: ' + release_date)
else
# Error out if our release can't be found in the .doap file
error(run_result.stderr())
endif
endif
configure_file(output: 'config.h', configuration: cdata)
python3 = find_program('python3')
run_command(python3, '-c', 'import shutil; shutil.copy("hooks/pre-commit.hook", ".git/hooks/pre-commit")')

14
meson_options.txt Normal file
View file

@ -0,0 +1,14 @@
option('header_path', type : 'string', value : '',
description : 'An extra include directory to find the OpenMax headers')
option('target', type : 'combo',
choices : ['none', 'generic', 'rpi', 'bellagio', 'tizonia', 'zynqultrascaleplus'], value : 'none',
description : 'The OMX platform to target')
option('struct_packing', type : 'combo',
choices : ['0', '1', '2', '4', '8'], value : '0',
description : 'Force OpenMAX struct packing')
# Common feature options
option('examples', type : 'feature', value : 'auto', yield : true)
option('tests', type : 'feature', value : 'auto', yield : true)
option('tools', type : 'feature', value : 'auto', yield : true)
option('doc', type : 'feature', value : 'auto', yield : true)

4179
omx/gstomx.c Normal file

File diff suppressed because it is too large Load diff

493
omx/gstomx.h Normal file
View file

@ -0,0 +1,493 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
* Copyright (C) 2013, Collabora Ltd.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_H__
#define __GST_OMX_H__
#include <gmodule.h>
#include <gst/gst.h>
#include <gst/video/video.h>
#include <string.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef GST_OMX_STRUCT_PACKING
# if GST_OMX_STRUCT_PACKING == 1
# pragma pack(1)
# elif GST_OMX_STRUCT_PACKING == 2
# pragma pack(2)
# elif GST_OMX_STRUCT_PACKING == 4
# pragma pack(4)
# elif GST_OMX_STRUCT_PACKING == 8
# pragma pack(8)
# else
# error "Unsupported struct packing value"
# endif
#endif
/* If the component may signal EOS before it has finished pushing
* out all of its buffers. Happens with egl_render on the rpi.
*/
#define GST_OMX_HACK_SIGNALS_PREMATURE_EOS G_GUINT64_CONSTANT (0x0000000000000400)
#include <OMX_Core.h>
#include <OMX_Component.h>
#ifdef USE_OMX_TARGET_RPI
#include <OMX_Broadcom.h>
#endif
#ifdef HAVE_VIDEO_EXT
#include <OMX_VideoExt.h>
#endif
#ifdef HAVE_INDEX_EXT
#include <OMX_IndexExt.h>
#endif
#ifdef HAVE_COMPONENT_EXT
#include <OMX_ComponentExt.h>
#endif
#ifdef HAVE_CORE_EXT
#include <OMX_CoreExt.h>
#endif
#ifdef HAVE_AUDIO_EXT
#include <OMX_AudioExt.h>
#endif
#ifdef HAVE_IV_COMMON_EXT
#include <OMX_IVCommonExt.h>
#endif
#ifdef HAVE_IMAGE_EXT
#include <OMX_ImageExt.h>
#endif
#ifdef HAVE_OTHER_EXT
#include <OMX_OtherExt.h>
#endif
#ifdef GST_OMX_STRUCT_PACKING
#pragma pack()
#endif
G_BEGIN_DECLS
#define GST_OMX_INIT_STRUCT(st) G_STMT_START { \
memset ((st), 0, sizeof (*(st))); \
(st)->nSize = sizeof (*(st)); \
(st)->nVersion.s.nVersionMajor = OMX_VERSION_MAJOR; \
(st)->nVersion.s.nVersionMinor = OMX_VERSION_MINOR; \
(st)->nVersion.s.nRevision = OMX_VERSION_REVISION; \
(st)->nVersion.s.nStep = OMX_VERSION_STEP; \
} G_STMT_END
#ifdef OMX_SKIP64BIT
#define GST_OMX_GET_TICKS(ticks) ((((guint64) (ticks).nHighPart) << 32) | ((ticks).nLowPart))
#define GST_OMX_SET_TICKS(ticks, i) G_STMT_START { \
ticks.nLowPart = ((guint64) (i)) & 0xffffffff; \
ticks.nHighPart = ((guint64) (i)) >> 32; \
} G_STMT_END
#else
#define GST_OMX_GET_TICKS(ticks) (ticks)
#define GST_OMX_SET_TICKS(ticks, i) G_STMT_START { \
ticks = i; \
} G_STMT_END
#endif
/* If set on an element property means "use the OMX default value".
* If set on a default_* variable means that the default values hasn't been
* retrieved from OMX yet. */
#define GST_OMX_PROP_OMX_DEFAULT G_MAXUINT32
/* OMX_StateInvalid does not exist in 1.2.0 spec. The initial state is now
* StateLoaded. Problem is that gst-omx still needs an initial state different
* than StateLoaded. Otherwise gst_omx_component_set_state(StateLoaded) will
* early return because it will think it is already in StateLoaded. Also note
* that there is no call to gst_omx_component_set_state(StateInvalid) so this
* also shows that StateInvalid is used as a helper in gst-omx.
*/
#if OMX_VERSION_MINOR == 2
#define OMX_StateInvalid OMX_StateReserved_0x00000000
#endif
/* Different hacks that are required to work around
* bugs in different OpenMAX implementations
*/
/* In the EventSettingsChanged callback use nData2 instead of nData1 for
* the port index. Happens with Bellagio.
*/
#define GST_OMX_HACK_EVENT_PORT_SETTINGS_CHANGED_NDATA_PARAMETER_SWAP G_GUINT64_CONSTANT (0x0000000000000001)
/* In the EventSettingsChanged callback assume that port index 0 really
* means port index 1. Happens with the Bellagio ffmpegdist video decoder.
*/
#define GST_OMX_HACK_EVENT_PORT_SETTINGS_CHANGED_PORT_0_TO_1 G_GUINT64_CONSTANT (0x0000000000000002)
/* If the video framerate is not specified as fraction (Q.16) but as
* integer number. Happens with the Bellagio ffmpegdist video encoder.
*/
#define GST_OMX_HACK_VIDEO_FRAMERATE_INTEGER G_GUINT64_CONSTANT (0x0000000000000004)
/* If the SYNCFRAME flag on encoder output buffers is not used and we
* have to assume that all frames are sync frames.
* Happens with the Bellagio ffmpegdist video encoder.
*/
#define GST_OMX_HACK_SYNCFRAME_FLAG_NOT_USED G_GUINT64_CONSTANT (0x0000000000000008)
/* If the component needs to be re-created if the caps change.
* Happens with Qualcomm's OpenMAX implementation.
*/
#define GST_OMX_HACK_NO_COMPONENT_RECONFIGURE G_GUINT64_CONSTANT (0x0000000000000010)
/* If the component does not accept empty EOS buffers.
* Happens with Qualcomm's OpenMAX implementation.
*/
#define GST_OMX_HACK_NO_EMPTY_EOS_BUFFER G_GUINT64_CONSTANT (0x0000000000000020)
/* If the component might not acknowledge a drain.
* Happens with TI's Ducati OpenMAX implementation.
*/
#define GST_OMX_HACK_DRAIN_MAY_NOT_RETURN G_GUINT64_CONSTANT (0x0000000000000040)
/* If the component doesn't allow any component role to be set.
* Happens with Broadcom's OpenMAX implementation.
*/
#define GST_OMX_HACK_NO_COMPONENT_ROLE G_GUINT64_CONSTANT (0x0000000000000080)
/* If the component doesn't allow disabling the outport while
* when setting the format until the output format is known.
*/
#define GST_OMX_HACK_NO_DISABLE_OUTPORT G_GUINT64_CONSTANT (0x0000000000000100)
/* If the encoder requires input buffers that have a height
* which is a multiple of 16 pixels
*/
#define GST_OMX_HACK_HEIGHT_MULTIPLE_16 G_GUINT64_CONSTANT (0x0000000000000200)
/* If we should pass the profile/level information from upstream to the
* OMX decoder. This is a violation of the OMX spec as
* OMX_IndexParamVideoProfileLevelCurrent is supposed to be r-o so
* do it as a platform specific hack.
*/
#define GST_OMX_HACK_PASS_PROFILE_TO_DECODER G_GUINT64_CONSTANT (0x0000000000000800)
/* If we should pass the color format information from upstream to the
* OMX decoder input. This is a violation of the OMX spec as
* the eColorFormat field is supposed to only be used if eCompressionFormat is
* set to OMX_IMAGE_CodingUnused.
* Do this as a platform specific hack for OMX implementation which may use
* this information to pre-allocate internal buffers for example.
*/
#define GST_OMX_HACK_PASS_COLOR_FORMAT_TO_DECODER G_GUINT64_CONSTANT (0x0000000000001000)
/* If set, automatically update nBufferCountActual to nBufferCountMin before
* allocating buffers. This can be used on OMX implementation decreasing
* nBufferCountMin depending of the format and so can reduce the number
* of allocated buffers.
*/
#define GST_OMX_HACK_ENSURE_BUFFER_COUNT_ACTUAL G_GUINT64_CONSTANT (0x0000000000002000)
typedef struct _GstOMXCore GstOMXCore;
typedef struct _GstOMXPort GstOMXPort;
typedef enum _GstOMXPortDirection GstOMXPortDirection;
typedef struct _GstOMXComponent GstOMXComponent;
typedef struct _GstOMXBuffer GstOMXBuffer;
typedef struct _GstOMXClassData GstOMXClassData;
typedef struct _GstOMXMessage GstOMXMessage;
typedef enum {
/* Everything good and the buffer is valid */
GST_OMX_ACQUIRE_BUFFER_OK = 0,
/* The port is flushing, exit ASAP */
GST_OMX_ACQUIRE_BUFFER_FLUSHING,
/* The port must be reconfigured */
GST_OMX_ACQUIRE_BUFFER_RECONFIGURE,
/* The port is EOS */
GST_OMX_ACQUIRE_BUFFER_EOS,
/* A fatal error happened */
GST_OMX_ACQUIRE_BUFFER_ERROR,
/* No buffer is currently available (used when calling gst_omx_port_acquire_buffer() in not waiting mode) */
GST_OMX_ACQUIRE_BUFFER_NO_AVAILABLE,
} GstOMXAcquireBufferReturn;
struct _GstOMXCore {
/* Handle to the OpenMAX IL core shared library */
GModule *module;
/* Current number of users, transitions from/to 0
* call init/deinit */
GMutex lock;
gint user_count; /* LOCK */
/* OpenMAX core library functions, protected with LOCK */
OMX_ERRORTYPE (*init) (void);
OMX_ERRORTYPE (*deinit) (void);
OMX_ERRORTYPE (*get_handle) (OMX_HANDLETYPE * handle,
OMX_STRING name, OMX_PTR data, OMX_CALLBACKTYPE * callbacks);
OMX_ERRORTYPE (*free_handle) (OMX_HANDLETYPE handle);
OMX_ERRORTYPE (*setup_tunnel) (OMX_HANDLETYPE output, OMX_U32 outport, OMX_HANDLETYPE input, OMX_U32 inport);
};
typedef enum {
GST_OMX_MESSAGE_STATE_SET,
GST_OMX_MESSAGE_FLUSH,
GST_OMX_MESSAGE_ERROR,
GST_OMX_MESSAGE_PORT_ENABLE,
GST_OMX_MESSAGE_PORT_SETTINGS_CHANGED,
GST_OMX_MESSAGE_BUFFER_FLAG,
GST_OMX_MESSAGE_BUFFER_DONE,
} GstOMXMessageType;
typedef enum {
GST_OMX_COMPONENT_TYPE_SINK,
GST_OMX_COMPONENT_TYPE_SOURCE,
GST_OMX_COMPONENT_TYPE_FILTER
} GstOmxComponentType;
/* How the port's buffers are allocated */
typedef enum {
GST_OMX_BUFFER_ALLOCATION_ALLOCATE_BUFFER,
GST_OMX_BUFFER_ALLOCATION_USE_BUFFER,
GST_OMX_BUFFER_ALLOCATION_USE_BUFFER_DYNAMIC, /* Only supported by OMX 1.2.0 */
} GstOMXBufferAllocation;
typedef enum {
GST_OMX_WAIT,
GST_OMX_DONT_WAIT,
} GstOMXWait;
struct _GstOMXMessage {
GstOMXMessageType type;
union {
struct {
OMX_STATETYPE state;
} state_set;
struct {
OMX_U32 port;
} flush;
struct {
OMX_ERRORTYPE error;
} error;
struct {
OMX_U32 port;
OMX_BOOL enable;
} port_enable;
struct {
OMX_U32 port;
} port_settings_changed;
struct {
OMX_U32 port;
OMX_U32 flags;
} buffer_flag;
struct {
OMX_HANDLETYPE component;
OMX_PTR app_data;
OMX_BUFFERHEADERTYPE *buffer;
OMX_BOOL empty;
} buffer_done;
} content;
};
struct _GstOMXPort {
GstOMXComponent *comp;
guint32 index;
gboolean tunneled;
OMX_PARAM_PORTDEFINITIONTYPE port_def;
GPtrArray *buffers; /* Contains GstOMXBuffer* */
GQueue pending_buffers; /* Contains GstOMXBuffer* */
gboolean flushing;
gboolean flushed; /* TRUE after OMX_CommandFlush was done */
gboolean enabled_pending; /* TRUE after OMX_Command{En,Dis}able */
gboolean disabled_pending; /* was done until it took effect */
gboolean eos; /* TRUE after a buffer with EOS flag was received */
GstOMXBufferAllocation allocation;
gboolean using_pool; /* TRUE if the buffers of this port are managed by a pool */
/* Increased whenever the settings of these port change.
* If settings_cookie != configured_settings_cookie
* the port has to be reconfigured.
*/
gint settings_cookie;
gint configured_settings_cookie;
};
struct _GstOMXComponent {
GstMiniObject mini_object;
GstObject *parent;
gchar *name; /* for debugging mostly */
OMX_HANDLETYPE handle;
GstOMXCore *core;
guint64 hacks; /* Flags, GST_OMX_HACK_* */
/* Added once, never changed. No locks necessary */
GPtrArray *ports; /* Contains GstOMXPort* */
gint n_in_ports, n_out_ports;
/* Locking order: lock -> messages_lock
*
* Never hold lock while waiting for messages_cond
* Always check that messages is empty before waiting */
GMutex lock;
GQueue messages; /* Queue of GstOMXMessages */
GMutex messages_lock;
GCond messages_cond;
OMX_STATETYPE state;
/* OMX_StateInvalid if no pending state */
OMX_STATETYPE pending_state;
/* OMX_ErrorNone usually, if different nothing will work */
OMX_ERRORTYPE last_error;
GList *pending_reconfigure_outports;
};
struct _GstOMXBuffer {
GstOMXPort *port;
OMX_BUFFERHEADERTYPE *omx_buf;
/* TRUE if the buffer is used by the port, i.e.
* between {Empty,Fill}ThisBuffer and the callback
*/
gboolean used;
/* Cookie of the settings when this buffer was allocated */
gint settings_cookie;
/* TRUE if this is an EGLImage */
gboolean eglimage;
/* Used in dynamic buffer mode to keep track of the mapped content while it's
* being processed by the OMX component. */
GstVideoFrame input_frame;
gboolean input_frame_mapped; /* TRUE if input_frame is valid */
GstMemory *input_mem;
GstBuffer *input_buffer;
gboolean input_buffer_mapped;
GstMapInfo map;
};
struct _GstOMXClassData {
const gchar *core_name;
const gchar *component_name;
const gchar *component_role;
const gchar *default_src_template_caps;
const gchar *default_sink_template_caps;
guint32 in_port_index, out_port_index;
guint64 hacks;
GstOmxComponentType type;
};
GKeyFile * gst_omx_get_configuration (void);
const gchar * gst_omx_error_to_string (OMX_ERRORTYPE err);
const gchar * gst_omx_state_to_string (OMX_STATETYPE state);
const gchar * gst_omx_command_to_string (OMX_COMMANDTYPE cmd);
const gchar * gst_omx_buffer_flags_to_string (guint32 flags);
guint64 gst_omx_parse_hacks (gchar ** hacks);
GstOMXCore * gst_omx_core_acquire (const gchar * filename);
void gst_omx_core_release (GstOMXCore * core);
GType gst_omx_component_get_type (void);
GstOMXComponent * gst_omx_component_new (GstObject * parent, const gchar *core_name, const gchar *component_name, const gchar * component_role, guint64 hacks);
GstOMXComponent * gst_omx_component_ref (GstOMXComponent * comp);
void gst_omx_component_unref (GstOMXComponent * comp);
OMX_ERRORTYPE gst_omx_component_set_state (GstOMXComponent * comp, OMX_STATETYPE state);
OMX_STATETYPE gst_omx_component_get_state (GstOMXComponent * comp, GstClockTime timeout);
OMX_ERRORTYPE gst_omx_component_get_last_error (GstOMXComponent * comp);
const gchar * gst_omx_component_get_last_error_string (GstOMXComponent * comp);
GstOMXPort * gst_omx_component_add_port (GstOMXComponent * comp, guint32 index);
GstOMXPort * gst_omx_component_get_port (GstOMXComponent * comp, guint32 index);
OMX_ERRORTYPE gst_omx_component_get_parameter (GstOMXComponent * comp, OMX_INDEXTYPE index, gpointer param);
OMX_ERRORTYPE gst_omx_component_set_parameter (GstOMXComponent * comp, OMX_INDEXTYPE index, gpointer param);
OMX_ERRORTYPE gst_omx_component_get_config (GstOMXComponent * comp, OMX_INDEXTYPE index, gpointer config);
OMX_ERRORTYPE gst_omx_component_set_config (GstOMXComponent * comp, OMX_INDEXTYPE index, gpointer config);
OMX_ERRORTYPE gst_omx_setup_tunnel (GstOMXPort * port1, GstOMXPort * port2);
OMX_ERRORTYPE gst_omx_close_tunnel (GstOMXPort * port1, GstOMXPort * port2);
OMX_ERRORTYPE gst_omx_port_get_port_definition (GstOMXPort * port, OMX_PARAM_PORTDEFINITIONTYPE * port_def);
OMX_ERRORTYPE gst_omx_port_update_port_definition (GstOMXPort *port, OMX_PARAM_PORTDEFINITIONTYPE *port_definition);
GstOMXAcquireBufferReturn gst_omx_port_acquire_buffer (GstOMXPort *port, GstOMXBuffer **buf, GstOMXWait wait);
OMX_ERRORTYPE gst_omx_port_release_buffer (GstOMXPort *port, GstOMXBuffer *buf);
OMX_ERRORTYPE gst_omx_port_set_flushing (GstOMXPort *port, GstClockTime timeout, gboolean flush);
gboolean gst_omx_port_is_flushing (GstOMXPort *port);
OMX_ERRORTYPE gst_omx_port_allocate_buffers (GstOMXPort *port);
OMX_ERRORTYPE gst_omx_port_use_buffers (GstOMXPort *port, const GList *buffers);
OMX_ERRORTYPE gst_omx_port_use_eglimages (GstOMXPort *port, const GList *images);
OMX_ERRORTYPE gst_omx_port_deallocate_buffers (GstOMXPort *port);
OMX_ERRORTYPE gst_omx_port_populate (GstOMXPort *port);
OMX_ERRORTYPE gst_omx_port_wait_buffers_released (GstOMXPort * port, GstClockTime timeout);
void gst_omx_port_requeue_buffer (GstOMXPort * port, GstOMXBuffer * buf);
OMX_ERRORTYPE gst_omx_port_mark_reconfigured (GstOMXPort * port);
OMX_ERRORTYPE gst_omx_port_set_enabled (GstOMXPort * port, gboolean enabled);
OMX_ERRORTYPE gst_omx_port_wait_enabled (GstOMXPort * port, GstClockTime timeout);
gboolean gst_omx_port_is_enabled (GstOMXPort * port);
gboolean gst_omx_port_ensure_buffer_count_actual (GstOMXPort * port, guint extra);
gboolean gst_omx_port_update_buffer_count_actual (GstOMXPort * port, guint nb);
gboolean gst_omx_port_set_dmabuf (GstOMXPort * port, gboolean dmabuf);
gboolean gst_omx_port_set_subframe (GstOMXPort * port, gboolean enabled);
gboolean gst_omx_port_get_subframe (GstOMXPort * port);
/* OMX 1.2.0 dynamic allocation mode */
gboolean gst_omx_is_dynamic_allocation_supported (void);
OMX_ERRORTYPE gst_omx_port_use_dynamic_buffers (GstOMXPort * port);
gboolean gst_omx_buffer_map_frame (GstOMXBuffer * buffer, GstBuffer * input, GstVideoInfo * info);
gboolean gst_omx_buffer_map_memory (GstOMXBuffer * buffer, GstMemory * mem);
gboolean gst_omx_buffer_map_buffer (GstOMXBuffer * buffer, GstBuffer * input);
gboolean gst_omx_buffer_import_fd (GstOMXBuffer * buffer, GstBuffer * input);
void gst_omx_set_default_role (GstOMXClassData *class_data, const gchar *default_role);
/* refered by plugin_init */
GST_DEBUG_CATEGORY_EXTERN (gst_omx_video_debug_category);
G_END_DECLS
#endif /* __GST_OMX_H__ */

296
omx/gstomxaacdec.c Normal file
View file

@ -0,0 +1,296 @@
/*
* Copyright (C) 2014, Sebastian Dröge <sebastian@centricular.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxaacdec.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_aac_dec_debug_category);
#define GST_CAT_DEFAULT gst_omx_aac_dec_debug_category
/* prototypes */
static gboolean gst_omx_aac_dec_set_format (GstOMXAudioDec * dec,
GstOMXPort * port, GstCaps * caps);
static gboolean gst_omx_aac_dec_is_format_change (GstOMXAudioDec * dec,
GstOMXPort * port, GstCaps * caps);
static gint gst_omx_aac_dec_get_samples_per_frame (GstOMXAudioDec * dec,
GstOMXPort * port);
static gboolean gst_omx_aac_dec_get_channel_positions (GstOMXAudioDec * dec,
GstOMXPort * port, GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS]);
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_aac_dec_debug_category, "omxaacdec", 0, \
"debug category for gst-omx aac audio decoder");
G_DEFINE_TYPE_WITH_CODE (GstOMXAACDec, gst_omx_aac_dec,
GST_TYPE_OMX_AUDIO_DEC, DEBUG_INIT);
static void
gst_omx_aac_dec_class_init (GstOMXAACDecClass * klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstOMXAudioDecClass *audiodec_class = GST_OMX_AUDIO_DEC_CLASS (klass);
audiodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_aac_dec_set_format);
audiodec_class->is_format_change =
GST_DEBUG_FUNCPTR (gst_omx_aac_dec_is_format_change);
audiodec_class->get_samples_per_frame =
GST_DEBUG_FUNCPTR (gst_omx_aac_dec_get_samples_per_frame);
audiodec_class->get_channel_positions =
GST_DEBUG_FUNCPTR (gst_omx_aac_dec_get_channel_positions);
audiodec_class->cdata.default_sink_template_caps = "audio/mpeg, "
"mpegversion=(int){2, 4}, "
"stream-format=(string) { raw, adts, adif, loas }, "
"rate=(int)[8000,48000], "
"channels=(int)[1,9], " "framed=(boolean) true";
gst_element_class_set_static_metadata (element_class,
"OpenMAX AAC Audio Decoder",
"Codec/Decoder/Audio/Hardware",
"Decode AAC audio streams",
"Sebastian Dröge <sebastian@centricular.com>");
gst_omx_set_default_role (&audiodec_class->cdata, "audio_decoder.aac");
}
static void
gst_omx_aac_dec_init (GstOMXAACDec * self)
{
/* FIXME: Other values exist too! */
self->spf = 1024;
}
static gboolean
gst_omx_aac_dec_set_format (GstOMXAudioDec * dec, GstOMXPort * port,
GstCaps * caps)
{
GstOMXAACDec *self = GST_OMX_AAC_DEC (dec);
OMX_PARAM_PORTDEFINITIONTYPE port_def;
OMX_AUDIO_PARAM_AACPROFILETYPE aac_param;
OMX_ERRORTYPE err;
GstStructure *s;
gint rate, channels, mpegversion;
const gchar *stream_format;
gst_omx_port_get_port_definition (port, &port_def);
port_def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
err = gst_omx_port_update_port_definition (port, &port_def);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Failed to set AAC format on component: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
GST_OMX_INIT_STRUCT (&aac_param);
aac_param.nPortIndex = port->index;
err =
gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioAac,
&aac_param);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Failed to get AAC parameters from component: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
s = gst_caps_get_structure (caps, 0);
if (!gst_structure_get_int (s, "mpegversion", &mpegversion) ||
!gst_structure_get_int (s, "rate", &rate) ||
!gst_structure_get_int (s, "channels", &channels)) {
GST_ERROR_OBJECT (self, "Incomplete caps");
return FALSE;
}
stream_format = gst_structure_get_string (s, "stream-format");
if (!stream_format) {
GST_ERROR_OBJECT (self, "Incomplete caps");
return FALSE;
}
aac_param.nChannels = channels;
aac_param.nSampleRate = rate;
aac_param.nBitRate = 0; /* unknown */
aac_param.nAudioBandWidth = 0; /* decoder decision */
aac_param.eChannelMode = 0; /* FIXME */
if (mpegversion == 2)
aac_param.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP2ADTS;
else if (strcmp (stream_format, "adts") == 0)
aac_param.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
else if (strcmp (stream_format, "loas") == 0)
aac_param.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4LOAS;
else if (strcmp (stream_format, "adif") == 0)
aac_param.eAACStreamFormat = OMX_AUDIO_AACStreamFormatADIF;
else if (strcmp (stream_format, "raw") == 0)
aac_param.eAACStreamFormat = OMX_AUDIO_AACStreamFormatRAW;
else {
GST_ERROR_OBJECT (self, "Unexpected format: %s", stream_format);
return FALSE;
}
err =
gst_omx_component_set_parameter (dec->dec, OMX_IndexParamAudioAac,
&aac_param);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self, "Error setting AAC parameters: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
return TRUE;
}
static gboolean
gst_omx_aac_dec_is_format_change (GstOMXAudioDec * dec, GstOMXPort * port,
GstCaps * caps)
{
GstOMXAACDec *self = GST_OMX_AAC_DEC (dec);
OMX_AUDIO_PARAM_AACPROFILETYPE aac_param;
OMX_ERRORTYPE err;
GstStructure *s;
gint rate, channels, mpegversion;
const gchar *stream_format;
GST_OMX_INIT_STRUCT (&aac_param);
aac_param.nPortIndex = port->index;
err =
gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioAac,
&aac_param);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Failed to get AAC parameters from component: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
s = gst_caps_get_structure (caps, 0);
if (!gst_structure_get_int (s, "mpegversion", &mpegversion) ||
!gst_structure_get_int (s, "rate", &rate) ||
!gst_structure_get_int (s, "channels", &channels)) {
GST_ERROR_OBJECT (self, "Incomplete caps");
return FALSE;
}
stream_format = gst_structure_get_string (s, "stream-format");
if (!stream_format) {
GST_ERROR_OBJECT (self, "Incomplete caps");
return FALSE;
}
if (aac_param.nChannels != channels)
return TRUE;
if (aac_param.nSampleRate != rate)
return TRUE;
if (mpegversion == 2
&& aac_param.eAACStreamFormat != OMX_AUDIO_AACStreamFormatMP2ADTS)
return TRUE;
if (aac_param.eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4ADTS &&
strcmp (stream_format, "adts") != 0)
return TRUE;
if (aac_param.eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4LOAS &&
strcmp (stream_format, "loas") != 0)
return TRUE;
if (aac_param.eAACStreamFormat == OMX_AUDIO_AACStreamFormatADIF &&
strcmp (stream_format, "adif") != 0)
return TRUE;
if (aac_param.eAACStreamFormat == OMX_AUDIO_AACStreamFormatRAW &&
strcmp (stream_format, "raw") != 0)
return TRUE;
return FALSE;
}
static gint
gst_omx_aac_dec_get_samples_per_frame (GstOMXAudioDec * dec, GstOMXPort * port)
{
return GST_OMX_AAC_DEC (dec)->spf;
}
static gboolean
gst_omx_aac_dec_get_channel_positions (GstOMXAudioDec * dec,
GstOMXPort * port, GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS])
{
OMX_AUDIO_PARAM_PCMMODETYPE pcm_param;
OMX_ERRORTYPE err;
GST_OMX_INIT_STRUCT (&pcm_param);
pcm_param.nPortIndex = port->index;
err =
gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioPcm,
&pcm_param);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (dec, "Failed to get PCM parameters: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
/* FIXME: Rather arbitrary values here, based on what we do in gstfaac.c */
switch (pcm_param.nChannels) {
case 1:
position[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
break;
case 2:
position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
break;
case 3:
position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
position[2] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
break;
case 4:
position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
position[2] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
position[3] = GST_AUDIO_CHANNEL_POSITION_REAR_CENTER;
break;
case 5:
position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
position[2] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
position[3] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
position[4] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT;
break;
case 6:
position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
position[2] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
position[3] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
position[4] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT;
position[5] = GST_AUDIO_CHANNEL_POSITION_LFE1;
break;
default:
return FALSE;
}
return TRUE;
}

60
omx/gstomxaacdec.h Normal file
View file

@ -0,0 +1,60 @@
/*
* Copyright (C) 2014, Sebastian Dröge <sebastian@centricular.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_AAC_DEC_H__
#define __GST_OMX_AAC_DEC_H__
#include <gst/gst.h>
#include "gstomxaudiodec.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_AAC_DEC \
(gst_omx_aac_dec_get_type())
#define GST_OMX_AAC_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_AAC_DEC,GstOMXAACDec))
#define GST_OMX_AAC_DEC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_AAC_DEC,GstOMXAACDecClass))
#define GST_OMX_AAC_DEC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_AAC_DEC,GstOMXAACDecClass))
#define GST_IS_OMX_AAC_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_AAC_DEC))
#define GST_IS_OMX_AAC_DEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_AAC_DEC))
typedef struct _GstOMXAACDec GstOMXAACDec;
typedef struct _GstOMXAACDecClass GstOMXAACDecClass;
struct _GstOMXAACDec
{
GstOMXAudioDec parent;
gint spf;
};
struct _GstOMXAACDecClass
{
GstOMXAudioDecClass parent_class;
};
GType gst_omx_aac_dec_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_AAC_DEC_H__ */

511
omx/gstomxaacenc.c Normal file
View file

@ -0,0 +1,511 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxaacenc.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_aac_enc_debug_category);
#define GST_CAT_DEFAULT gst_omx_aac_enc_debug_category
/* prototypes */
static void gst_omx_aac_enc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_omx_aac_enc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static gboolean gst_omx_aac_enc_set_format (GstOMXAudioEnc * enc,
GstOMXPort * port, GstAudioInfo * info);
static GstCaps *gst_omx_aac_enc_get_caps (GstOMXAudioEnc * enc,
GstOMXPort * port, GstAudioInfo * info);
static guint gst_omx_aac_enc_get_num_samples (GstOMXAudioEnc * enc,
GstOMXPort * port, GstAudioInfo * info, GstOMXBuffer * buf);
enum
{
PROP_0,
PROP_BITRATE,
PROP_AAC_TOOLS,
PROP_AAC_ERROR_RESILIENCE_TOOLS
};
#define DEFAULT_BITRATE (128000)
#define DEFAULT_AAC_TOOLS (OMX_AUDIO_AACToolMS | OMX_AUDIO_AACToolIS | OMX_AUDIO_AACToolTNS | OMX_AUDIO_AACToolPNS | OMX_AUDIO_AACToolLTP)
#define DEFAULT_AAC_ER_TOOLS (OMX_AUDIO_AACERNone)
#define GST_TYPE_OMX_AAC_TOOLS (gst_omx_aac_tools_get_type ())
static GType
gst_omx_aac_tools_get_type (void)
{
static gsize id = 0;
static const GFlagsValue values[] = {
{OMX_AUDIO_AACToolMS, "Mid/side joint coding", "ms"},
{OMX_AUDIO_AACToolIS, "Intensity stereo", "is"},
{OMX_AUDIO_AACToolTNS, "Temporal noise shaping", "tns"},
{OMX_AUDIO_AACToolPNS, "Perceptual noise substitution", "pns"},
{OMX_AUDIO_AACToolLTP, "Long term prediction", "ltp"},
{0, NULL, NULL}
};
if (g_once_init_enter (&id)) {
GType tmp = g_flags_register_static ("GstOMXAACTools", values);
g_once_init_leave (&id, tmp);
}
return (GType) id;
}
#define GST_TYPE_OMX_AAC_ER_TOOLS (gst_omx_aac_er_tools_get_type ())
static GType
gst_omx_aac_er_tools_get_type (void)
{
static gsize id = 0;
static const GFlagsValue values[] = {
{OMX_AUDIO_AACERVCB11, "Virtual code books", "vcb11"},
{OMX_AUDIO_AACERRVLC, "Reversible variable length coding", "rvlc"},
{OMX_AUDIO_AACERHCR, "Huffman codeword reordering", "hcr"},
{0, NULL, NULL}
};
if (g_once_init_enter (&id)) {
GType tmp = g_flags_register_static ("GstOMXAACERTools", values);
g_once_init_leave (&id, tmp);
}
return (GType) id;
}
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_aac_enc_debug_category, "omxaacenc", 0, \
"debug category for gst-omx audio encoder base class");
G_DEFINE_TYPE_WITH_CODE (GstOMXAACEnc, gst_omx_aac_enc,
GST_TYPE_OMX_AUDIO_ENC, DEBUG_INIT);
static void
gst_omx_aac_enc_class_init (GstOMXAACEncClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstOMXAudioEncClass *audioenc_class = GST_OMX_AUDIO_ENC_CLASS (klass);
gobject_class->set_property = gst_omx_aac_enc_set_property;
gobject_class->get_property = gst_omx_aac_enc_get_property;
g_object_class_install_property (gobject_class, PROP_BITRATE,
g_param_spec_uint ("bitrate", "Bitrate",
"Bitrate",
0, G_MAXUINT, DEFAULT_BITRATE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
g_object_class_install_property (gobject_class, PROP_AAC_TOOLS,
g_param_spec_flags ("aac-tools", "AAC Tools",
"Allowed AAC tools",
GST_TYPE_OMX_AAC_TOOLS,
DEFAULT_AAC_TOOLS,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
g_object_class_install_property (gobject_class,
PROP_AAC_ERROR_RESILIENCE_TOOLS,
g_param_spec_flags ("aac-error-resilience-tools",
"AAC Error Resilience Tools", "Allowed AAC error resilience tools",
GST_TYPE_OMX_AAC_ER_TOOLS, DEFAULT_AAC_ER_TOOLS,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
audioenc_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_aac_enc_set_format);
audioenc_class->get_caps = GST_DEBUG_FUNCPTR (gst_omx_aac_enc_get_caps);
audioenc_class->get_num_samples =
GST_DEBUG_FUNCPTR (gst_omx_aac_enc_get_num_samples);
audioenc_class->cdata.default_src_template_caps = "audio/mpeg, "
"mpegversion=(int){2, 4}, "
"stream-format=(string){raw, adts, adif, loas, latm}";
gst_element_class_set_static_metadata (element_class,
"OpenMAX AAC Audio Encoder",
"Codec/Encoder/Audio/Hardware",
"Encode AAC audio streams",
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
gst_omx_set_default_role (&audioenc_class->cdata, "audio_encoder.aac");
}
static void
gst_omx_aac_enc_init (GstOMXAACEnc * self)
{
self->bitrate = DEFAULT_BITRATE;
self->aac_tools = DEFAULT_AAC_TOOLS;
self->aac_er_tools = DEFAULT_AAC_ER_TOOLS;
}
static void
gst_omx_aac_enc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstOMXAACEnc *self = GST_OMX_AAC_ENC (object);
switch (prop_id) {
case PROP_BITRATE:
self->bitrate = g_value_get_uint (value);
break;
case PROP_AAC_TOOLS:
self->aac_tools = g_value_get_flags (value);
break;
case PROP_AAC_ERROR_RESILIENCE_TOOLS:
self->aac_er_tools = g_value_get_flags (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_omx_aac_enc_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstOMXAACEnc *self = GST_OMX_AAC_ENC (object);
switch (prop_id) {
case PROP_BITRATE:
g_value_set_uint (value, self->bitrate);
break;
case PROP_AAC_TOOLS:
g_value_set_flags (value, self->aac_tools);
break;
case PROP_AAC_ERROR_RESILIENCE_TOOLS:
g_value_set_flags (value, self->aac_er_tools);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static gboolean
gst_omx_aac_enc_set_format (GstOMXAudioEnc * enc, GstOMXPort * port,
GstAudioInfo * info)
{
GstOMXAACEnc *self = GST_OMX_AAC_ENC (enc);
OMX_AUDIO_PARAM_AACPROFILETYPE aac_profile;
GstCaps *peercaps;
OMX_ERRORTYPE err;
GST_OMX_INIT_STRUCT (&aac_profile);
aac_profile.nPortIndex = enc->enc_out_port->index;
err =
gst_omx_component_get_parameter (enc->enc, OMX_IndexParamAudioAac,
&aac_profile);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Failed to get AAC parameters from component: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
peercaps = gst_pad_peer_query_caps (GST_AUDIO_ENCODER_SRC_PAD (self),
gst_pad_get_pad_template_caps (GST_AUDIO_ENCODER_SRC_PAD (self)));
if (peercaps) {
GstStructure *s;
gint mpegversion = 0;
const gchar *profile_string, *stream_format_string;
if (gst_caps_is_empty (peercaps)) {
gst_caps_unref (peercaps);
GST_ERROR_OBJECT (self, "Empty caps");
return FALSE;
}
s = gst_caps_get_structure (peercaps, 0);
if (gst_structure_get_int (s, "mpegversion", &mpegversion)) {
profile_string =
gst_structure_get_string (s,
((mpegversion == 2) ? "profile" : "base-profile"));
if (profile_string) {
if (g_str_equal (profile_string, "main")) {
aac_profile.eAACProfile = OMX_AUDIO_AACObjectMain;
} else if (g_str_equal (profile_string, "lc")) {
aac_profile.eAACProfile = OMX_AUDIO_AACObjectLC;
} else if (g_str_equal (profile_string, "ssr")) {
aac_profile.eAACProfile = OMX_AUDIO_AACObjectSSR;
} else if (g_str_equal (profile_string, "ltp")) {
aac_profile.eAACProfile = OMX_AUDIO_AACObjectLTP;
} else {
GST_ERROR_OBJECT (self, "Unsupported profile '%s'", profile_string);
gst_caps_unref (peercaps);
return FALSE;
}
}
}
stream_format_string = gst_structure_get_string (s, "stream-format");
if (stream_format_string) {
if (g_str_equal (stream_format_string, "raw")) {
aac_profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatRAW;
} else if (g_str_equal (stream_format_string, "adts")) {
if (mpegversion == 2) {
aac_profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP2ADTS;
} else {
aac_profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
}
} else if (g_str_equal (stream_format_string, "loas")) {
aac_profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4LOAS;
} else if (g_str_equal (stream_format_string, "latm")) {
aac_profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4LATM;
} else if (g_str_equal (stream_format_string, "adif")) {
aac_profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatADIF;
} else {
GST_ERROR_OBJECT (self, "Unsupported stream-format '%s'",
stream_format_string);
gst_caps_unref (peercaps);
return FALSE;
}
}
gst_caps_unref (peercaps);
aac_profile.nSampleRate = info->rate;
aac_profile.nChannels = info->channels;
}
aac_profile.nAACtools = self->aac_tools;
aac_profile.nAACERtools = self->aac_er_tools;
aac_profile.nBitRate = self->bitrate;
err =
gst_omx_component_set_parameter (enc->enc, OMX_IndexParamAudioAac,
&aac_profile);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self, "Error setting AAC parameters: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
return TRUE;
}
typedef enum adts_sample_index__
{
ADTS_SAMPLE_INDEX_96000 = 0x0,
ADTS_SAMPLE_INDEX_88200,
ADTS_SAMPLE_INDEX_64000,
ADTS_SAMPLE_INDEX_48000,
ADTS_SAMPLE_INDEX_44100,
ADTS_SAMPLE_INDEX_32000,
ADTS_SAMPLE_INDEX_24000,
ADTS_SAMPLE_INDEX_22050,
ADTS_SAMPLE_INDEX_16000,
ADTS_SAMPLE_INDEX_12000,
ADTS_SAMPLE_INDEX_11025,
ADTS_SAMPLE_INDEX_8000,
ADTS_SAMPLE_INDEX_7350,
ADTS_SAMPLE_INDEX_MAX
} adts_sample_index;
static adts_sample_index
map_adts_sample_index (guint32 srate)
{
adts_sample_index ret;
switch (srate) {
case 96000:
ret = ADTS_SAMPLE_INDEX_96000;
break;
case 88200:
ret = ADTS_SAMPLE_INDEX_88200;
break;
case 64000:
ret = ADTS_SAMPLE_INDEX_64000;
break;
case 48000:
ret = ADTS_SAMPLE_INDEX_48000;
break;
case 44100:
ret = ADTS_SAMPLE_INDEX_44100;
break;
case 32000:
ret = ADTS_SAMPLE_INDEX_32000;
break;
case 24000:
ret = ADTS_SAMPLE_INDEX_24000;
break;
case 22050:
ret = ADTS_SAMPLE_INDEX_22050;
break;
case 16000:
ret = ADTS_SAMPLE_INDEX_16000;
break;
case 12000:
ret = ADTS_SAMPLE_INDEX_12000;
break;
case 11025:
ret = ADTS_SAMPLE_INDEX_11025;
break;
case 8000:
ret = ADTS_SAMPLE_INDEX_8000;
break;
case 7350:
ret = ADTS_SAMPLE_INDEX_7350;
break;
default:
ret = ADTS_SAMPLE_INDEX_44100;
break;
}
return ret;
}
static GstCaps *
gst_omx_aac_enc_get_caps (GstOMXAudioEnc * enc, GstOMXPort * port,
GstAudioInfo * info)
{
GstCaps *caps;
OMX_ERRORTYPE err;
OMX_AUDIO_PARAM_AACPROFILETYPE aac_profile;
gint mpegversion = 4;
const gchar *stream_format = NULL, *profile = NULL;
GST_OMX_INIT_STRUCT (&aac_profile);
aac_profile.nPortIndex = enc->enc_out_port->index;
err =
gst_omx_component_get_parameter (enc->enc, OMX_IndexParamAudioAac,
&aac_profile);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (enc,
"Failed to get AAC parameters from component: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return NULL;
}
switch (aac_profile.eAACProfile) {
case OMX_AUDIO_AACObjectMain:
profile = "main";
break;
case OMX_AUDIO_AACObjectLC:
profile = "lc";
break;
case OMX_AUDIO_AACObjectSSR:
profile = "ssr";
break;
case OMX_AUDIO_AACObjectLTP:
profile = "ltp";
break;
case OMX_AUDIO_AACObjectHE:
case OMX_AUDIO_AACObjectScalable:
case OMX_AUDIO_AACObjectERLC:
case OMX_AUDIO_AACObjectLD:
case OMX_AUDIO_AACObjectHE_PS:
default:
GST_ERROR_OBJECT (enc, "Unsupported profile %d", aac_profile.eAACProfile);
break;
}
switch (aac_profile.eAACStreamFormat) {
case OMX_AUDIO_AACStreamFormatMP2ADTS:
mpegversion = 2;
stream_format = "adts";
break;
case OMX_AUDIO_AACStreamFormatMP4ADTS:
mpegversion = 4;
stream_format = "adts";
break;
case OMX_AUDIO_AACStreamFormatMP4LOAS:
mpegversion = 4;
stream_format = "loas";
break;
case OMX_AUDIO_AACStreamFormatMP4LATM:
mpegversion = 4;
stream_format = "latm";
break;
case OMX_AUDIO_AACStreamFormatADIF:
mpegversion = 4;
stream_format = "adif";
break;
case OMX_AUDIO_AACStreamFormatRAW:
mpegversion = 4;
stream_format = "raw";
break;
case OMX_AUDIO_AACStreamFormatMP4FF:
default:
GST_ERROR_OBJECT (enc, "Unsupported stream-format %u",
aac_profile.eAACStreamFormat);
break;
}
caps = gst_caps_new_empty_simple ("audio/mpeg");
if (mpegversion != 0)
gst_caps_set_simple (caps, "mpegversion", G_TYPE_INT, mpegversion,
"stream-format", G_TYPE_STRING, stream_format, NULL);
if (profile != NULL && (mpegversion == 2 || mpegversion == 4))
gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
if (profile != NULL && mpegversion == 4)
gst_caps_set_simple (caps, "base-profile", G_TYPE_STRING, profile, NULL);
if (aac_profile.nChannels != 0)
gst_caps_set_simple (caps, "channels", G_TYPE_INT, aac_profile.nChannels,
NULL);
if (aac_profile.nSampleRate != 0)
gst_caps_set_simple (caps, "rate", G_TYPE_INT, aac_profile.nSampleRate,
NULL);
if (aac_profile.eAACStreamFormat == OMX_AUDIO_AACStreamFormatRAW) {
GstBuffer *codec_data;
adts_sample_index sr_idx;
GstMapInfo map = GST_MAP_INFO_INIT;
codec_data = gst_buffer_new_and_alloc (2);
gst_buffer_map (codec_data, &map, GST_MAP_WRITE);
sr_idx = map_adts_sample_index (aac_profile.nSampleRate);
map.data[0] = ((aac_profile.eAACProfile & 0x1F) << 3) |
((sr_idx & 0xE) >> 1);
map.data[1] = ((sr_idx & 0x1) << 7) | ((aac_profile.nChannels & 0xF) << 3);
gst_buffer_unmap (codec_data, &map);
GST_DEBUG_OBJECT (enc, "setting new codec_data");
gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, codec_data, NULL);
gst_buffer_unref (codec_data);
}
return caps;
}
static guint
gst_omx_aac_enc_get_num_samples (GstOMXAudioEnc * enc, GstOMXPort * port,
GstAudioInfo * info, GstOMXBuffer * buf)
{
/* FIXME: Depends on the profile at least */
return 1024;
}

65
omx/gstomxaacenc.h Normal file
View file

@ -0,0 +1,65 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_AAC_ENC_H__
#define __GST_OMX_AAC_ENC_H__
#include <gst/gst.h>
#include "gstomxaudioenc.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_AAC_ENC \
(gst_omx_aac_enc_get_type())
#define GST_OMX_AAC_ENC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_AAC_ENC,GstOMXAACEnc))
#define GST_OMX_AAC_ENC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_AAC_ENC,GstOMXAACEncClass))
#define GST_OMX_AAC_ENC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_AAC_ENC,GstOMXAACEncClass))
#define GST_IS_OMX_AAC_ENC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_AAC_ENC))
#define GST_IS_OMX_AAC_ENC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_AAC_ENC))
typedef struct _GstOMXAACEnc GstOMXAACEnc;
typedef struct _GstOMXAACEncClass GstOMXAACEncClass;
struct _GstOMXAACEnc
{
GstOMXAudioEnc parent;
/* properties */
guint bitrate;
guint aac_tools;
guint aac_er_tools;
};
struct _GstOMXAACEncClass
{
GstOMXAudioEncClass parent_class;
};
GType gst_omx_aac_enc_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_AAC_ENC_H__ */

554
omx/gstomxallocator.c Normal file
View file

@ -0,0 +1,554 @@
/*
* Copyright (C) 2019, Collabora Ltd.
* Author: George Kiagiadakis <george.kiagiadakis@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstomxallocator.h"
#include <gst/allocators/gstdmabuf.h>
GST_DEBUG_CATEGORY_STATIC (gst_omx_allocator_debug_category);
#define GST_CAT_DEFAULT gst_omx_allocator_debug_category
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_allocator_debug_category, "omxallocator", 0, \
"debug category for gst-omx allocator class");
G_DEFINE_TYPE_WITH_CODE (GstOMXAllocator, gst_omx_allocator, GST_TYPE_ALLOCATOR,
DEBUG_INIT);
enum
{
SIG_OMXBUF_RELEASED,
SIG_FOREIGN_MEM_RELEASED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
/* Custom allocator for memory associated with OpenMAX buffers
*
* The main purpose of this allocator is to track memory that is associated
* with OpenMAX buffers, so that we know when the buffers can be released
* back to OpenMAX.
*
* This allocator looks and behaves more like a buffer pool. It allocates
* the memory objects before starting and sets a miniobject dispose function
* on them, which allows them to return when their last ref count is dropped.
*
* The type of memory that this allocator manages is GstOMXMemory. However, it
* is possible to manage a different type of memory, in which case the
* GstOMXMemory object is used only internally. There are two supported cases:
* - Allocate memory from the dmabuf allocator
* - Take memory that was allocated externally and manage it here
*
* In both cases, this allocator will replace the miniobject dispose function
* of these memory objects, so if they were acquired from here, they will also
* return here on their last unref.
*
* The caller initially needs to configure how many memory objects will be
* managed here by calling configure(). After that it needs to call
* set_active(TRUE) and finally allocate() for each memory. Allocation is done
* like this to facilitate calling allocate() from the alloc() function of
* the buffer pool for each OMX buffer on the port.
*
* After the allocator has been activated and all buffers have been allocated,
* the acquire() method can be called to retrieve a memory object. acquire() can
* be given an OMX buffer index or pointer to locate and return the memory
* object that corresponds to this OMX buffer. If the buffer is already
* acquired, this will result in a GST_FLOW_ERROR.
*
* When the last reference count is dropped on a memory that was acquired from
* here, its dispose function will ref it again and allow it to be acquired
* again. In addition, the omxbuf-released signal is fired to let the caller
* know that it can return this OMX buffer to the port, as it is no longer
* used outside this allocator.
*/
/******************/
/** GstOMXMemory **/
/******************/
#define GST_OMX_MEMORY_TYPE "openmax"
GQuark
gst_omx_memory_quark (void)
{
static GQuark quark = 0;
if (quark == 0)
quark = g_quark_from_static_string ("GstOMXMemory");
return quark;
}
static GstOMXMemory *
gst_omx_memory_new (GstOMXAllocator * allocator, GstOMXBuffer * omx_buf,
GstMemoryFlags flags, GstMemory * parent, gssize offset, gssize size)
{
GstOMXMemory *mem;
gint align;
gsize maxsize;
/* GStreamer uses a bitmask for the alignment while
* OMX uses the alignment itself. So we have to convert
* here */
align = allocator->port->port_def.nBufferAlignment;
if (align > 0)
align -= 1;
if (((align + 1) & align) != 0) {
GST_WARNING ("Invalid alignment that is not a power of two: %u",
(guint) allocator->port->port_def.nBufferAlignment);
align = 0;
}
maxsize = omx_buf->omx_buf->nAllocLen;
if (size == -1) {
size = maxsize - offset;
}
mem = g_slice_new0 (GstOMXMemory);
gst_memory_init (GST_MEMORY_CAST (mem), flags, (GstAllocator *) allocator,
parent, maxsize, align, offset, size);
mem->buf = omx_buf;
return mem;
}
static gpointer
gst_omx_memory_map (GstMemory * mem, gsize maxsize, GstMapFlags flags)
{
GstOMXMemory *omem = (GstOMXMemory *) mem;
/* if we are using foreign_mem, the GstOMXMemory should never appear
* anywhere outside this allocator, therefore it should never be mapped */
g_return_val_if_fail (!omem->foreign_mem, NULL);
return omem->buf->omx_buf->pBuffer;
}
static void
gst_omx_memory_unmap (GstMemory * mem)
{
}
static GstMemory *
gst_omx_memory_share (GstMemory * mem, gssize offset, gssize size)
{
GstOMXMemory *omem = (GstOMXMemory *) mem;
GstOMXMemory *sub;
GstMemory *parent;
/* find the real parent */
if ((parent = mem->parent) == NULL)
parent = mem;
if (size == -1)
size = mem->size - offset;
/* the shared memory is always readonly */
sub = gst_omx_memory_new ((GstOMXAllocator *) mem->allocator, omem->buf,
GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY,
parent, offset, size);
return (GstMemory *) sub;
}
GstOMXBuffer *
gst_omx_memory_get_omx_buf (GstMemory * mem)
{
GstOMXMemory *omx_mem;
if (GST_IS_OMX_ALLOCATOR (mem->allocator))
omx_mem = (GstOMXMemory *) mem;
else
omx_mem = gst_mini_object_get_qdata (GST_MINI_OBJECT (mem),
GST_OMX_MEMORY_QUARK);
if (!omx_mem)
return NULL;
return omx_mem->buf;
}
/*********************/
/** GstOMXAllocator **/
/*********************/
static void
gst_omx_allocator_init (GstOMXAllocator * allocator)
{
GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
alloc->mem_type = GST_OMX_MEMORY_TYPE;
alloc->mem_map = gst_omx_memory_map;
alloc->mem_unmap = gst_omx_memory_unmap;
alloc->mem_share = gst_omx_memory_share;
/* default copy & is_span */
GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
g_mutex_init (&allocator->lock);
g_cond_init (&allocator->cond);
}
GstOMXAllocator *
gst_omx_allocator_new (GstOMXComponent * component, GstOMXPort * port)
{
GstOMXAllocator *allocator;
allocator = g_object_new (gst_omx_allocator_get_type (), NULL);
allocator->component = gst_omx_component_ref (component);
allocator->port = port;
return allocator;
}
static void
gst_omx_allocator_finalize (GObject * object)
{
GstOMXAllocator *allocator = GST_OMX_ALLOCATOR (object);
gst_omx_component_unref (allocator->component);
g_mutex_clear (&allocator->lock);
g_cond_clear (&allocator->cond);
G_OBJECT_CLASS (gst_omx_allocator_parent_class)->finalize (object);
}
gboolean
gst_omx_allocator_configure (GstOMXAllocator * allocator, guint count,
GstOMXAllocatorForeignMemMode mode)
{
/* check if already configured */
if (allocator->n_memories > 0)
return FALSE;
allocator->n_memories = count;
allocator->foreign_mode = mode;
if (mode == GST_OMX_ALLOCATOR_FOREIGN_MEM_DMABUF)
allocator->foreign_allocator = gst_dmabuf_allocator_new ();
return TRUE;
}
/* must be protected with allocator->lock */
static void
gst_omx_allocator_dealloc (GstOMXAllocator * allocator)
{
/* might be called more than once */
if (!allocator->memories)
return;
/* return foreign memory back to whoever lended it to us.
* the signal handler is expected to increase the ref count of foreign_mem */
if (allocator->foreign_mode == GST_OMX_ALLOCATOR_FOREIGN_MEM_OTHER_POOL) {
gint i;
GstOMXMemory *m;
for (i = 0; i < allocator->memories->len; i++) {
m = g_ptr_array_index (allocator->memories, i);
/* this should not happen, but let's not crash for this */
if (!m->foreign_mem) {
GST_WARNING_OBJECT (allocator, "no foreign_mem to release");
continue;
}
/* restore the original dispose function */
GST_MINI_OBJECT_CAST (m->foreign_mem)->dispose =
(GstMiniObjectDisposeFunction) m->foreign_dispose;
g_signal_emit (allocator, signals[SIG_FOREIGN_MEM_RELEASED], 0, i,
m->foreign_mem);
}
}
g_ptr_array_foreach (allocator->memories, (GFunc) gst_memory_unref, NULL);
g_ptr_array_free (allocator->memories, TRUE);
allocator->memories = NULL;
allocator->n_memories = 0;
allocator->foreign_mode = GST_OMX_ALLOCATOR_FOREIGN_MEM_NONE;
if (allocator->foreign_allocator) {
g_object_unref (allocator->foreign_allocator);
allocator->foreign_allocator = NULL;
}
g_cond_broadcast (&allocator->cond);
}
gboolean
gst_omx_allocator_set_active (GstOMXAllocator * allocator, gboolean active)
{
gboolean changed = FALSE;
/* on activation, _configure() must be called first */
g_return_val_if_fail (!active || allocator->n_memories > 0, FALSE);
g_mutex_lock (&allocator->lock);
if (allocator->active != active)
changed = TRUE;
if (changed) {
if (active) {
allocator->memories = g_ptr_array_sized_new (allocator->n_memories);
g_ptr_array_set_size (allocator->memories, allocator->n_memories);
} else {
if (g_atomic_int_get (&allocator->n_outstanding) == 0)
gst_omx_allocator_dealloc (allocator);
}
}
allocator->active = active;
g_mutex_unlock (&allocator->lock);
return changed;
}
void
gst_omx_allocator_wait_inactive (GstOMXAllocator * allocator)
{
g_mutex_lock (&allocator->lock);
while (allocator->memories)
g_cond_wait (&allocator->cond, &allocator->lock);
g_mutex_unlock (&allocator->lock);
}
static inline void
dec_outstanding (GstOMXAllocator * allocator)
{
if (g_atomic_int_dec_and_test (&allocator->n_outstanding)) {
/* keep a ref to the allocator because _dealloc() will free
* all the memories and the memories might be the only thing holding
* a reference to the allocator; we need to keep it alive until the
* end of this function call */
g_object_ref (allocator);
/* take the lock so that _set_active() is not run concurrently */
g_mutex_lock (&allocator->lock);
/* now that we have the lock, check if we have been de-activated with
* outstanding buffers */
if (!allocator->active)
gst_omx_allocator_dealloc (allocator);
g_mutex_unlock (&allocator->lock);
g_object_unref (allocator);
}
}
GstFlowReturn
gst_omx_allocator_acquire (GstOMXAllocator * allocator, GstMemory ** memory,
gint index, GstOMXBuffer * omx_buf)
{
GstFlowReturn ret = GST_FLOW_OK;
GstOMXMemory *omx_mem = NULL;
/* ensure memories are not going to disappear concurrently */
g_atomic_int_inc (&allocator->n_outstanding);
if (!allocator->active) {
ret = GST_FLOW_FLUSHING;
goto beach;
}
if (index >= 0 && index < allocator->n_memories)
omx_mem = g_ptr_array_index (allocator->memories, index);
else if (omx_buf) {
for (index = 0; index < allocator->n_memories; index++) {
omx_mem = g_ptr_array_index (allocator->memories, index);
if (omx_mem->buf == omx_buf)
break;
}
}
if (G_UNLIKELY (!omx_mem || index >= allocator->n_memories)) {
GST_ERROR_OBJECT (allocator, "Failed to find OMX memory");
ret = GST_FLOW_ERROR;
goto beach;
}
if (G_UNLIKELY (omx_mem->buf->used)) {
GST_ERROR_OBJECT (allocator,
"Trying to acquire a buffer that is being used by the OMX port");
ret = GST_FLOW_ERROR;
goto beach;
}
omx_mem->acquired = TRUE;
if (omx_mem->foreign_mem)
*memory = omx_mem->foreign_mem;
else
*memory = GST_MEMORY_CAST (omx_mem);
beach:
if (ret != GST_FLOW_OK)
dec_outstanding (allocator);
return ret;
}
/* installed as the GstMiniObject::dispose function of the acquired GstMemory */
static gboolean
gst_omx_allocator_memory_dispose (GstMemory * mem)
{
GstOMXMemory *omx_mem;
GstOMXAllocator *allocator;
/* memory may be from our allocator, but
* may as well be from the dmabuf allocator */
if (GST_IS_OMX_ALLOCATOR (mem->allocator))
omx_mem = (GstOMXMemory *) mem;
else
omx_mem = gst_mini_object_get_qdata (GST_MINI_OBJECT (mem),
GST_OMX_MEMORY_QUARK);
if (omx_mem->acquired) {
/* keep the memory alive */
gst_memory_ref (mem);
omx_mem->acquired = FALSE;
allocator = GST_OMX_ALLOCATOR (GST_MEMORY_CAST (omx_mem)->allocator);
/* inform the upper layer that we are no longer using this GstOMXBuffer */
g_signal_emit (allocator, signals[SIG_OMXBUF_RELEASED], 0, omx_mem->buf);
dec_outstanding (allocator);
/* be careful here, both the memory and the allocator
* may have been free'd as part of the call to dec_outstanding() */
return FALSE;
}
/* if the foreign memory had a dispose function, let that one decide
* the fate of this memory. We are no longer going to be using it here */
if (omx_mem->foreign_dispose)
return omx_mem->foreign_dispose (GST_MINI_OBJECT_CAST (mem));
return TRUE;
}
static inline void
install_mem_dispose (GstOMXMemory * mem)
{
GstMemory *managed_mem = (GstMemory *) mem;
if (mem->foreign_mem) {
managed_mem = mem->foreign_mem;
mem->foreign_dispose = GST_MINI_OBJECT_CAST (managed_mem)->dispose;
}
GST_MINI_OBJECT_CAST (managed_mem)->dispose =
(GstMiniObjectDisposeFunction) gst_omx_allocator_memory_dispose;
}
/* the returned memory is transfer:none, ref still belongs to the allocator */
GstMemory *
gst_omx_allocator_allocate (GstOMXAllocator * allocator, gint index,
GstMemory * foreign_mem)
{
GstOMXMemory *mem;
GstOMXBuffer *omx_buf;
g_return_val_if_fail (allocator->port->buffers, NULL);
g_return_val_if_fail (allocator->memories, NULL);
g_return_val_if_fail (index >= 0 && index < allocator->n_memories, NULL);
g_return_val_if_fail ((foreign_mem == NULL &&
allocator->foreign_mode != GST_OMX_ALLOCATOR_FOREIGN_MEM_OTHER_POOL)
|| (foreign_mem != NULL
&& allocator->foreign_mode ==
GST_OMX_ALLOCATOR_FOREIGN_MEM_OTHER_POOL), NULL);
omx_buf = g_ptr_array_index (allocator->port->buffers, index);
g_return_val_if_fail (omx_buf != NULL, NULL);
mem = gst_omx_memory_new (allocator, omx_buf, 0, NULL, 0, -1);
switch (allocator->foreign_mode) {
case GST_OMX_ALLOCATOR_FOREIGN_MEM_NONE:
install_mem_dispose (mem);
break;
case GST_OMX_ALLOCATOR_FOREIGN_MEM_DMABUF:
{
gint fd = GPOINTER_TO_INT (omx_buf->omx_buf->pBuffer);
mem->foreign_mem =
gst_dmabuf_allocator_alloc (allocator->foreign_allocator, fd,
omx_buf->omx_buf->nAllocLen);
gst_mini_object_set_qdata (GST_MINI_OBJECT (mem->foreign_mem),
GST_OMX_MEMORY_QUARK, mem, NULL);
install_mem_dispose (mem);
break;
}
case GST_OMX_ALLOCATOR_FOREIGN_MEM_OTHER_POOL:
mem->foreign_mem = foreign_mem;
gst_mini_object_set_qdata (GST_MINI_OBJECT (mem->foreign_mem),
GST_OMX_MEMORY_QUARK, mem, NULL);
install_mem_dispose (mem);
break;
default:
g_assert_not_reached ();
break;
}
g_ptr_array_index (allocator->memories, index) = mem;
return mem->foreign_mem ? mem->foreign_mem : (GstMemory *) mem;
}
static void
gst_omx_allocator_free (GstAllocator * allocator, GstMemory * mem)
{
GstOMXMemory *omem = (GstOMXMemory *) mem;
g_warn_if_fail (!omem->acquired);
if (omem->foreign_mem)
gst_memory_unref (omem->foreign_mem);
g_slice_free (GstOMXMemory, omem);
}
static void
gst_omx_allocator_class_init (GstOMXAllocatorClass * klass)
{
GObjectClass *object_class;
GstAllocatorClass *allocator_class;
object_class = (GObjectClass *) klass;
allocator_class = (GstAllocatorClass *) klass;
object_class->finalize = gst_omx_allocator_finalize;
allocator_class->alloc = NULL;
allocator_class->free = gst_omx_allocator_free;
signals[SIG_OMXBUF_RELEASED] = g_signal_new ("omxbuf-released",
G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0,
NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_POINTER);
signals[SIG_FOREIGN_MEM_RELEASED] = g_signal_new ("foreign-mem-released",
G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0,
NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_POINTER);
}

114
omx/gstomxallocator.h Normal file
View file

@ -0,0 +1,114 @@
/*
* Copyright (C) 2019, Collabora Ltd.
* Author: George Kiagiadakis <george.kiagiadakis@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_ALLOCATOR_H__
#define __GST_OMX_ALLOCATOR_H__
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomx.h"
G_BEGIN_DECLS
#define GST_OMX_MEMORY_QUARK gst_omx_memory_quark ()
#define GST_TYPE_OMX_ALLOCATOR (gst_omx_allocator_get_type())
#define GST_IS_OMX_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_OMX_ALLOCATOR))
#define GST_OMX_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_OMX_ALLOCATOR, GstOMXAllocator))
typedef struct _GstOMXMemory GstOMXMemory;
typedef struct _GstOMXAllocator GstOMXAllocator;
typedef struct _GstOMXAllocatorClass GstOMXAllocatorClass;
typedef enum {
GST_OMX_ALLOCATOR_FOREIGN_MEM_NONE,
GST_OMX_ALLOCATOR_FOREIGN_MEM_DMABUF,
GST_OMX_ALLOCATOR_FOREIGN_MEM_OTHER_POOL,
} GstOMXAllocatorForeignMemMode;
struct _GstOMXMemory
{
GstMemory mem;
GstOMXBuffer *buf;
/* TRUE if the memory is in use outside the allocator */
gboolean acquired;
/* memory allocated from the foreign_allocator
* or planted externally when using a foreign buffer pool */
GstMemory *foreign_mem;
/* the original dispose function of foreign_mem */
GstMiniObjectDisposeFunction foreign_dispose;
};
struct _GstOMXAllocator
{
GstAllocator parent;
GstOMXComponent *component;
GstOMXPort *port;
GstOMXAllocatorForeignMemMode foreign_mode;
GstAllocator *foreign_allocator;
/* array of GstOMXMemory */
GPtrArray *memories;
guint n_memories;
guint n_outstanding;
gboolean active;
GMutex lock;
GCond cond;
};
struct _GstOMXAllocatorClass
{
GstAllocatorClass parent_class;
};
GType gst_omx_allocator_get_type (void);
GQuark gst_omx_memory_quark (void);
GstOMXBuffer * gst_omx_memory_get_omx_buf (GstMemory * mem);
GstOMXAllocator * gst_omx_allocator_new (GstOMXComponent * component,
GstOMXPort * port);
gboolean gst_omx_allocator_configure (GstOMXAllocator * allocator, guint count,
GstOMXAllocatorForeignMemMode mode);
gboolean gst_omx_allocator_set_active (GstOMXAllocator * allocator,
gboolean active);
void gst_omx_allocator_wait_inactive (GstOMXAllocator * allocator);
GstFlowReturn gst_omx_allocator_acquire (GstOMXAllocator * allocator,
GstMemory ** memory, gint index, GstOMXBuffer * omx_buf);
GstMemory * gst_omx_allocator_allocate (GstOMXAllocator * allocator, gint index,
GstMemory * foreign_mem);
G_END_DECLS
#endif

220
omx/gstomxamrdec.c Normal file
View file

@ -0,0 +1,220 @@
/*
* Copyright (C) 2014, Sebastian Dröge <sebastian@centricular.com>
* Copyright (C) 2014, LG Electronics, Inc. <jun.ji@lge.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxamrdec.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_amr_dec_debug_category);
#define GST_CAT_DEFAULT gst_omx_amr_dec_debug_category
/* prototypes */
static gboolean gst_omx_amr_dec_set_format (GstOMXAudioDec * dec,
GstOMXPort * port, GstCaps * caps);
static gboolean gst_omx_amr_dec_is_format_change (GstOMXAudioDec * dec,
GstOMXPort * port, GstCaps * caps);
static gint gst_omx_amr_dec_get_samples_per_frame (GstOMXAudioDec * dec,
GstOMXPort * port);
static gboolean gst_omx_amr_dec_get_channel_positions (GstOMXAudioDec * dec,
GstOMXPort * port, GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS]);
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_amr_dec_debug_category, "omxamrdec", 0, \
"debug category for gst-omx amr audio decoder");
G_DEFINE_TYPE_WITH_CODE (GstOMXAMRDec, gst_omx_amr_dec,
GST_TYPE_OMX_AUDIO_DEC, DEBUG_INIT);
static void
gst_omx_amr_dec_class_init (GstOMXAMRDecClass * klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstOMXAudioDecClass *audiodec_class = GST_OMX_AUDIO_DEC_CLASS (klass);
audiodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_amr_dec_set_format);
audiodec_class->is_format_change =
GST_DEBUG_FUNCPTR (gst_omx_amr_dec_is_format_change);
audiodec_class->get_samples_per_frame =
GST_DEBUG_FUNCPTR (gst_omx_amr_dec_get_samples_per_frame);
audiodec_class->get_channel_positions =
GST_DEBUG_FUNCPTR (gst_omx_amr_dec_get_channel_positions);
audiodec_class->cdata.default_sink_template_caps =
"audio/AMR, rate=(int)8000, channels=(int)1; "
"audio/AMR-WB, rate=(int)16000, channels=(int)1";
gst_element_class_set_static_metadata (element_class,
"OpenMAX AMR Audio Decoder",
"Codec/Decoder/Audio/Hardware",
"Decode AMR audio streams",
"Sebastian Dröge <sebastian@centricular.com>");
gst_omx_set_default_role (&audiodec_class->cdata, "audio_decoder.amrnb");
}
static void
gst_omx_amr_dec_init (GstOMXAMRDec * self)
{
self->spf = -1;
}
static gboolean
gst_omx_amr_dec_set_format (GstOMXAudioDec * dec, GstOMXPort * port,
GstCaps * caps)
{
GstOMXAMRDec *self = GST_OMX_AMR_DEC (dec);
OMX_PARAM_PORTDEFINITIONTYPE port_def;
OMX_AUDIO_PARAM_AMRTYPE amr_param;
OMX_ERRORTYPE err;
GstStructure *s;
gint rate, channels;
gst_omx_port_get_port_definition (port, &port_def);
port_def.format.audio.eEncoding = OMX_AUDIO_CodingAMR; /* not tested for AMRWB */
err = gst_omx_port_update_port_definition (port, &port_def);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Failed to set AMR format on component: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
GST_OMX_INIT_STRUCT (&amr_param);
amr_param.nPortIndex = port->index;
err =
gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioAmr,
&amr_param);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Failed to get AMR parameters from component: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
s = gst_caps_get_structure (caps, 0);
if (!gst_structure_get_int (s, "rate", &rate) ||
!gst_structure_get_int (s, "channels", &channels)) {
GST_ERROR_OBJECT (self, "Incomplete caps");
return FALSE;
}
self->rate = rate;
if (rate == 8000)
self->spf = 160; /* (8000/50) */
else if (rate == 16000)
self->spf = 320; /* (16000/50) */
amr_param.nChannels = channels;
amr_param.eAMRBandMode = 0; /*FIXME: It may require a specific value */
amr_param.eAMRDTXMode = 0;
amr_param.eAMRFrameFormat = 0;
err =
gst_omx_component_set_parameter (dec->dec, OMX_IndexParamAudioAmr,
&amr_param);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self, "Error setting AMR parameters: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
return TRUE;
}
static gboolean
gst_omx_amr_dec_is_format_change (GstOMXAudioDec * dec, GstOMXPort * port,
GstCaps * caps)
{
GstOMXAMRDec *self = GST_OMX_AMR_DEC (dec);
OMX_AUDIO_PARAM_AMRTYPE amr_param;
OMX_ERRORTYPE err;
GstStructure *s;
gint rate, channels;
GST_OMX_INIT_STRUCT (&amr_param);
amr_param.nPortIndex = port->index;
err =
gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioAmr,
&amr_param);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Failed to get AMR parameters from component: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
s = gst_caps_get_structure (caps, 0);
if (!gst_structure_get_int (s, "rate", &rate) ||
!gst_structure_get_int (s, "channels", &channels)) {
GST_ERROR_OBJECT (self, "Incomplete caps");
return FALSE;
}
if (self->rate != rate)
return TRUE;
if (amr_param.nChannels != channels)
return TRUE;
return FALSE;
}
static gint
gst_omx_amr_dec_get_samples_per_frame (GstOMXAudioDec * dec, GstOMXPort * port)
{
return GST_OMX_AMR_DEC (dec)->spf;
}
static gboolean
gst_omx_amr_dec_get_channel_positions (GstOMXAudioDec * dec,
GstOMXPort * port, GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS])
{
OMX_AUDIO_PARAM_PCMMODETYPE pcm_param;
OMX_ERRORTYPE err;
GST_OMX_INIT_STRUCT (&pcm_param);
pcm_param.nPortIndex = port->index;
err =
gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioPcm,
&pcm_param);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (dec, "Failed to get PCM parameters: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
g_return_val_if_fail (pcm_param.nChannels == 1, FALSE); /* AMR supports only mono */
position[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
return TRUE;
}

61
omx/gstomxamrdec.h Normal file
View file

@ -0,0 +1,61 @@
/*
* Copyright (C) 2014, Sebastian Dröge <sebastian@centricular.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_AMR_DEC_H__
#define __GST_OMX_AMR_DEC_H__
#include <gst/gst.h>
#include "gstomxaudiodec.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_AMR_DEC \
(gst_omx_amr_dec_get_type())
#define GST_OMX_AMR_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_AMR_DEC,GstOMXAMRDec))
#define GST_OMX_AMR_DEC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_AMR_DEC,GstOMXAMRDecClass))
#define GST_OMX_AMR_DEC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_AMR_DEC,GstOMXAMRDecClass))
#define GST_IS_OMX_AMR_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_AMR_DEC))
#define GST_IS_OMX_AMR_DEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_AMR_DEC))
typedef struct _GstOMXAMRDec GstOMXAMRDec;
typedef struct _GstOMXAMRDecClass GstOMXAMRDecClass;
struct _GstOMXAMRDec
{
GstOMXAudioDec parent;
gint spf;
gint rate;
};
struct _GstOMXAMRDecClass
{
GstOMXAudioDecClass parent_class;
};
GType gst_omx_amr_dec_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_AMR_DEC_H__ */

View file

@ -0,0 +1,64 @@
/*
* Copyright (C) 2014, Fluendo, S.A.
* Copyright (C) 2014, Metrological Media Innovations B.V.
* Author: Josep Torra <josep@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxanalogaudiosink.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_analog_audio_sink_debug_category);
#define GST_CAT_DEFAULT gst_omx_analog_audio_sink_debug_category
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_analog_audio_sink_debug_category, \
"omxanalogaudiosink", 0, "debug category for gst-omx analog audio sink");
G_DEFINE_TYPE_WITH_CODE (GstOMXAnalogAudioSink, gst_omx_analog_audio_sink,
GST_TYPE_OMX_AUDIO_SINK, DEBUG_INIT);
static void
gst_omx_analog_audio_sink_class_init (GstOMXAnalogAudioSinkClass * klass)
{
GstOMXAudioSinkClass *audiosink_class = GST_OMX_AUDIO_SINK_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
audiosink_class->cdata.default_sink_template_caps = "audio/x-raw, "
"format = (string) " GST_AUDIO_FORMATS_ALL ", "
"layout = (string) interleaved, "
"rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ] ";
audiosink_class->destination = "local";
gst_element_class_set_static_metadata (element_class,
"OpenMAX Analog Audio Sink",
"Sink/Audio", "Output analog audio", "Josep Torra <josep@fluendo.com>");
gst_omx_set_default_role (&audiosink_class->cdata, "audio_render.local");
}
static void
gst_omx_analog_audio_sink_init (GstOMXAnalogAudioSink * self)
{
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (C) 2014, Fluendo, S.A.
* Copyright (C) 2014, Metrological Media Innovations B.V.
* Author: Josep Torra <josep@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_ANALOG_AUDIO_SINK_H__
#define __GST_OMX_ANALOG_AUDIO_SINK_H__
#include <gst/gst.h>
#include "gstomxaudiosink.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_ANALOG_AUDIO_SINK \
(gst_omx_analog_audio_sink_get_type())
#define GST_OMX_ANALOG_AUDIO_SINK(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_ANALOG_AUDIO_SINK,GstOMXAnalogAudioSink))
#define GST_OMX_ANALOG_AUDIO_SINK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_ANALOG_AUDIO_SINK,GstOMXAnalogAudioSinkClass))
#define GST_OMX_ANALOG_AUDIO_SINK_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_ANALOG_AUDIO_SINK,GstOMXAnalogAudioSinkClass))
#define GST_IS_OMX_ANALOG_AUDIO_SINK(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_ANALOG_AUDIO_SINK))
#define GST_IS_OMX_ANALOG_AUDIO_SINK_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_ANALOG_AUDIO_SINK))
typedef struct _GstOMXAnalogAudioSink GstOMXAnalogAudioSink;
typedef struct _GstOMXAnalogAudioSinkClass GstOMXAnalogAudioSinkClass;
struct _GstOMXAnalogAudioSink
{
GstOMXAudioSink parent;
};
struct _GstOMXAnalogAudioSinkClass
{
GstOMXAudioSinkClass parent_class;
};
GType gst_omx_analog_audio_sink_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_ANALOG_AUDIO_SINK_H__ */

1404
omx/gstomxaudiodec.c Normal file

File diff suppressed because it is too large Load diff

100
omx/gstomxaudiodec.h Normal file
View file

@ -0,0 +1,100 @@
/*
* Copyright (C) 2014, Sebastian Dröge <sebastian@centricular.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_AUDIO_DEC_H__
#define __GST_OMX_AUDIO_DEC_H__
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include <gst/audio/audio.h>
#include <gst/audio/gstaudiodecoder.h>
#include "gstomx.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_AUDIO_DEC \
(gst_omx_audio_dec_get_type())
#define GST_OMX_AUDIO_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_AUDIO_DEC,GstOMXAudioDec))
#define GST_OMX_AUDIO_DEC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_AUDIO_DEC,GstOMXAudioDecClass))
#define GST_OMX_AUDIO_DEC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_AUDIO_DEC,GstOMXAudioDecClass))
#define GST_IS_OMX_AUDIO_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_AUDIO_DEC))
#define GST_IS_OMX_AUDIO_DEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_AUDIO_DEC))
typedef struct _GstOMXAudioDec GstOMXAudioDec;
typedef struct _GstOMXAudioDecClass GstOMXAudioDecClass;
struct _GstOMXAudioDec
{
GstAudioDecoder parent;
/* < protected > */
GstOMXComponent *dec;
GstOMXPort *dec_in_port, *dec_out_port;
GstBufferPool *in_port_pool, *out_port_pool;
/* < private > */
GstAudioInfo info;
GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS];
gint reorder_map[OMX_AUDIO_MAXCHANNELS];
gboolean needs_reorder;
GstBuffer *codec_data;
/* TRUE if the component is configured and saw
* the first buffer */
gboolean started;
GstClockTime last_upstream_ts;
/* Draining state */
GMutex drain_lock;
GCond drain_cond;
/* TRUE if EOS buffers shouldn't be forwarded */
gboolean draining;
GstAdapter *output_adapter;
GstFlowReturn downstream_flow_ret;
};
struct _GstOMXAudioDecClass
{
GstAudioDecoderClass parent_class;
GstOMXClassData cdata;
gboolean (*is_format_change) (GstOMXAudioDec * self, GstOMXPort * port, GstCaps * caps);
gboolean (*set_format) (GstOMXAudioDec * self, GstOMXPort * port, GstCaps * caps);
gint (*get_samples_per_frame) (GstOMXAudioDec * self, GstOMXPort * port);
gboolean (*get_channel_positions) (GstOMXAudioDec * self, GstOMXPort * port, GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS]);
};
GType gst_omx_audio_dec_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_AUDIO_DEC_H__ */

1181
omx/gstomxaudioenc.c Normal file

File diff suppressed because it is too large Load diff

87
omx/gstomxaudioenc.h Normal file
View file

@ -0,0 +1,87 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_AUDIO_ENC_H__
#define __GST_OMX_AUDIO_ENC_H__
#include <gst/gst.h>
#include <gst/audio/audio.h>
#include <gst/audio/gstaudioencoder.h>
#include "gstomx.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_AUDIO_ENC \
(gst_omx_audio_enc_get_type())
#define GST_OMX_AUDIO_ENC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_AUDIO_ENC,GstOMXAudioEnc))
#define GST_OMX_AUDIO_ENC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_AUDIO_ENC,GstOMXAudioEncClass))
#define GST_OMX_AUDIO_ENC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_AUDIO_ENC,GstOMXAudioEncClass))
#define GST_IS_OMX_AUDIO_ENC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_AUDIO_ENC))
#define GST_IS_OMX_AUDIO_ENC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_AUDIO_ENC))
typedef struct _GstOMXAudioEnc GstOMXAudioEnc;
typedef struct _GstOMXAudioEncClass GstOMXAudioEncClass;
struct _GstOMXAudioEnc
{
GstAudioEncoder parent;
/* < protected > */
GstOMXComponent *enc;
GstOMXPort *enc_in_port, *enc_out_port;
/* < private > */
/* TRUE if the component is configured and saw
* the first buffer */
gboolean started;
GstClockTime last_upstream_ts;
/* Draining state */
GMutex drain_lock;
GCond drain_cond;
/* TRUE if EOS buffers shouldn't be forwarded */
gboolean draining;
GstFlowReturn downstream_flow_ret;
};
struct _GstOMXAudioEncClass
{
GstAudioEncoderClass parent_class;
GstOMXClassData cdata;
gboolean (*set_format) (GstOMXAudioEnc * self, GstOMXPort * port, GstAudioInfo * info);
GstCaps *(*get_caps) (GstOMXAudioEnc * self, GstOMXPort * port, GstAudioInfo * info);
guint (*get_num_samples) (GstOMXAudioEnc * self, GstOMXPort * port, GstAudioInfo * info, GstOMXBuffer * buffer);
};
GType gst_omx_audio_enc_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_AUDIO_ENC_H__ */

1228
omx/gstomxaudiosink.c Normal file

File diff suppressed because it is too large Load diff

103
omx/gstomxaudiosink.h Normal file
View file

@ -0,0 +1,103 @@
/*
* Copyright (C) 2014, Fluendo, S.A.
* Copyright (C) 2014, Metrological Media Innovations B.V.
* Author: Josep Torra <josep@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_AUDIO_SINK_H__
#define __GST_OMX_AUDIO_SINK_H__
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include <gst/audio/audio.h>
#include "gstomx.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_AUDIO_SINK \
(gst_omx_audio_sink_get_type())
#define GST_OMX_AUDIO_SINK(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_AUDIO_SINK,GstOMXAudioSink))
#define GST_OMX_AUDIO_SINK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_AUDIO_SINK,GstOMXAudioSinkClass))
#define GST_OMX_AUDIO_SINK_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_AUDIO_SINK,GstOMXAudioSinkClass))
#define GST_IS_OMX_AUDIO_SINK(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_AUDIO_SINK))
#define GST_IS_OMX_AUDIO_SINK_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_AUDIO_SINK))
#define GST_OMX_AUDIO_SINK_CAST(obj) ((GstOMXAudioSink *) (obj))
#define GST_OMX_AUDIO_SINK_GET_LOCK(obj) (&GST_OMX_AUDIO_SINK_CAST (obj)->lock)
#define GST_OMX_AUDIO_SINK_LOCK(obj) (g_mutex_lock (GST_OMX_AUDIO_SINK_GET_LOCK (obj)))
#define GST_OMX_AUDIO_SINK_UNLOCK(obj) (g_mutex_unlock (GST_OMX_AUDIO_SINK_GET_LOCK (obj)))
#define PASSTHROUGH_CAPS \
"audio/x-ac3, framed = (boolean) true;" \
"audio/x-eac3, framed = (boolean) true; " \
"audio/x-dts, framed = (boolean) true, " \
"block-size = (int) { 512, 1024, 2048 }; " \
"audio/mpeg, mpegversion = (int) 1, " \
"mpegaudioversion = (int) [ 1, 2 ], parsed = (boolean) true;"
typedef struct _GstOMXAudioSink GstOMXAudioSink;
typedef struct _GstOMXAudioSinkClass GstOMXAudioSinkClass;
struct _GstOMXAudioSink
{
GstAudioSink parent;
/* < protected > */
GstOMXComponent *comp;
GstOMXPort *in_port, *out_port;
gboolean mute;
gdouble volume;
gboolean iec61937;
guint endianness;
guint rate;
guint channels;
guint width;
gboolean is_signed;
gboolean is_float;
guint buffer_size;
guint samples;
GMutex lock;
};
struct _GstOMXAudioSinkClass
{
GstAudioSinkClass parent_class;
GstOMXClassData cdata;
const gchar * destination;
};
GType gst_omx_audio_sink_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_AUDIO_SINK_H__ */

674
omx/gstomxbufferpool.c Normal file
View file

@ -0,0 +1,674 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
* Copyright (C) 2013-2019, Collabora Ltd.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
* George Kiagiadakis <george.kiagiadakis@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstomxbufferpool.h"
#include "gstomxvideo.h"
#include <gst/allocators/gstdmabuf.h>
GST_DEBUG_CATEGORY_STATIC (gst_omx_buffer_pool_debug_category);
#define GST_CAT_DEFAULT gst_omx_buffer_pool_debug_category
enum
{
SIG_ALLOCATE,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
/* Buffer pool for the buffers of an OpenMAX port.
*
* This pool is only used if we either passed buffers from another
* pool to the OMX port or provide the OMX buffers directly to other
* elements.
*
* An output buffer is in the pool if it is currently owned by the port,
* i.e. after OMX_FillThisBuffer(). An output buffer is outside
* the pool after it was taken from the port after it was handled
* by the port, i.e. FillBufferDone.
*
* An input buffer is in the pool if it is currently available to be filled
* upstream. It will be put back into the pool when it has been processed by
* OMX, (EmptyBufferDone).
*
* Buffers can be allocated by us (OMX_AllocateBuffer()) or allocated
* by someone else and (temporarily) passed to this pool
* (OMX_UseBuffer(), OMX_UseEGLImage()). In the latter case the pool of
* the buffer will be overriden, and restored in free_buffer(). Other
* buffers are just freed there.
*
* The pool always has a fixed number of minimum and maximum buffers
* and these are allocated while starting the pool and released afterwards.
* They correspond 1:1 to the OMX buffers of the port, which are allocated
* before the pool is started.
*
* Acquiring an output buffer from this pool happens after the OMX buffer has
* been acquired from the port. gst_buffer_pool_acquire_buffer() is
* supposed to return the buffer that corresponds to the OMX buffer.
*
* For buffers provided to upstream, the buffer will be passed to
* the component manually when it arrives and then unreffed. If the
* buffer is released before reaching the component it will be just put
* back into the pool as if EmptyBufferDone has happened. If it was
* passed to the component, it will be back into the pool when it was
* released and EmptyBufferDone has happened.
*
* For buffers provided to downstream, the buffer will be returned
* back to the component (OMX_FillThisBuffer()) when it is released.
*
* This pool uses a special allocator object, GstOMXAllocator. The main purpose
* of this allocator is to track GstMemory objects in the same way that a
* GstBufferPool tracks buffers. When a buffer is inserted into this pool
* (either because it was just allocated or because it was released back to
* the pool), its memory is ripped off and is tracked separately by the
* allocator. When a buffer is then acquired, we acquire the corresponding
* GstMemory from the allocator and put it back in the buffer.
*
* This allocator mechanism allows us to track memory that has been shared
* with buffers that are not part of this pool. When a memory is shared, then
* its ref count is > 1, which means it will not be released to the allocator
* until the sub-memory is destroyed.
*
* When a memory returns to the allocator, the allocator fires the
* omxbuf-released signal, which is handled by the buffer pool to return the
* omx buffer to the port or the queue.
*/
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_buffer_pool_debug_category, "omxbufferpool", 0, \
"debug category for gst-omx buffer pool base class");
G_DEFINE_TYPE_WITH_CODE (GstOMXBufferPool, gst_omx_buffer_pool,
GST_TYPE_BUFFER_POOL, DEBUG_INIT);
static void gst_omx_buffer_pool_free_buffer (GstBufferPool * bpool,
GstBuffer * buffer);
static gboolean
gst_omx_buffer_pool_start (GstBufferPool * bpool)
{
GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
gboolean has_buffers;
GstStructure *config;
guint min, max;
GstOMXAllocatorForeignMemMode mode;
/* Only allow to start the pool if we still are attached
* to a component and port */
GST_OBJECT_LOCK (pool);
if (!pool->component || !pool->port) {
GST_OBJECT_UNLOCK (pool);
return FALSE;
}
pool->port->using_pool = TRUE;
has_buffers = (pool->port->buffers != NULL);
GST_OBJECT_UNLOCK (pool);
config = gst_buffer_pool_get_config (bpool);
gst_buffer_pool_config_get_params (config, NULL, NULL, &min, &max);
gst_structure_free (config);
if (max > min) {
GST_WARNING_OBJECT (bpool,
"max (%d) cannot be higher than min (%d) as pool cannot allocate buffers on the fly",
max, min);
return FALSE;
}
if (!has_buffers) {
gboolean result = FALSE;
GST_DEBUG_OBJECT (bpool, "Buffers not yet allocated on port %d of %s",
pool->port->index, pool->component->name);
g_signal_emit (pool, signals[SIG_ALLOCATE], 0, &result);
if (!result) {
GST_WARNING_OBJECT (bpool,
"Element failed to allocate buffers, can't start pool");
return FALSE;
}
}
g_assert (pool->port->buffers);
if (pool->other_pool)
/* Importing buffers from downstream, either normal or dmabuf ones */
mode = GST_OMX_ALLOCATOR_FOREIGN_MEM_OTHER_POOL;
else if (pool->output_mode == GST_OMX_BUFFER_MODE_DMABUF)
/* Exporting dmabuf */
mode = GST_OMX_ALLOCATOR_FOREIGN_MEM_DMABUF;
else
/* Exporting normal buffers */
mode = GST_OMX_ALLOCATOR_FOREIGN_MEM_NONE;
if (!gst_omx_allocator_configure (pool->allocator, min, mode))
return FALSE;
if (!gst_omx_allocator_set_active (pool->allocator, TRUE))
return FALSE;
return
GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->start (bpool);
}
static gboolean
gst_omx_buffer_pool_stop (GstBufferPool * bpool)
{
GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
/* Remove any buffers that are there */
g_ptr_array_set_size (pool->buffers, 0);
GST_DEBUG_OBJECT (pool, "deactivating OMX allocator");
gst_omx_allocator_set_active (pool->allocator, FALSE);
/* ensure all memories have been deallocated;
* this may take a while if some memories are being shared
* and therefore are in use somewhere else in the pipeline */
gst_omx_allocator_wait_inactive (pool->allocator);
GST_DEBUG_OBJECT (pool, "deallocate OMX buffers");
gst_omx_port_deallocate_buffers (pool->port);
if (pool->caps)
gst_caps_unref (pool->caps);
pool->caps = NULL;
pool->add_videometa = FALSE;
pool->deactivated = TRUE;
pool->port->using_pool = TRUE;
return GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->stop (bpool);
}
static const gchar **
gst_omx_buffer_pool_get_options (GstBufferPool * bpool)
{
static const gchar *raw_video_options[] =
{ GST_BUFFER_POOL_OPTION_VIDEO_META, NULL };
static const gchar *options[] = { NULL };
GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
GST_OBJECT_LOCK (pool);
if (pool->port && pool->port->port_def.eDomain == OMX_PortDomainVideo
&& pool->port->port_def.format.video.eCompressionFormat ==
OMX_VIDEO_CodingUnused) {
GST_OBJECT_UNLOCK (pool);
return raw_video_options;
}
GST_OBJECT_UNLOCK (pool);
return options;
}
static gboolean
gst_omx_buffer_pool_set_config (GstBufferPool * bpool, GstStructure * config)
{
GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
GstCaps *caps;
guint size, min;
GstStructure *fake_config;
gboolean ret;
GST_OBJECT_LOCK (pool);
if (!gst_buffer_pool_config_get_params (config, &caps, &size, &min, NULL))
goto wrong_config;
if (caps == NULL)
goto no_caps;
if (pool->port && pool->port->port_def.eDomain == OMX_PortDomainVideo
&& pool->port->port_def.format.video.eCompressionFormat ==
OMX_VIDEO_CodingUnused) {
GstVideoInfo info;
/* now parse the caps from the config */
if (!gst_video_info_from_caps (&info, caps))
goto wrong_video_caps;
/* enable metadata based on config of the pool */
pool->add_videometa =
gst_buffer_pool_config_has_option (config,
GST_BUFFER_POOL_OPTION_VIDEO_META);
pool->video_info = info;
}
if (pool->caps)
gst_caps_unref (pool->caps);
pool->caps = gst_caps_ref (caps);
/* Ensure max=min as the pool won't be able to allocate more buffers while active */
gst_buffer_pool_config_set_params (config, caps, size, min, min);
GST_OBJECT_UNLOCK (pool);
/* give a fake config to the parent default_set_config() with size == 0
* this prevents default_release_buffer() from free'ing the buffers, since
* we release them with no memory */
fake_config = gst_structure_copy (config);
gst_buffer_pool_config_set_params (fake_config, caps, 0, min, min);
ret = GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->set_config
(bpool, fake_config);
gst_structure_free (fake_config);
return ret;
/* ERRORS */
wrong_config:
{
GST_OBJECT_UNLOCK (pool);
GST_WARNING_OBJECT (pool, "invalid config");
return FALSE;
}
no_caps:
{
GST_OBJECT_UNLOCK (pool);
GST_WARNING_OBJECT (pool, "no caps in config");
return FALSE;
}
wrong_video_caps:
{
GST_OBJECT_UNLOCK (pool);
GST_WARNING_OBJECT (pool,
"failed getting geometry from caps %" GST_PTR_FORMAT, caps);
return FALSE;
}
}
static GstFlowReturn
gst_omx_buffer_pool_alloc_buffer (GstBufferPool * bpool,
GstBuffer ** buffer, GstBufferPoolAcquireParams * params)
{
GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
GstBuffer *buf;
GstMemory *mem;
GstMemory *foreign_mem = NULL;
if (pool->other_pool) {
guint n;
buf = g_ptr_array_index (pool->buffers, pool->current_buffer_index);
g_assert (pool->other_pool == buf->pool);
gst_object_replace ((GstObject **) & buf->pool, NULL);
n = gst_buffer_n_memory (buf);
g_return_val_if_fail (n == 1, GST_FLOW_ERROR);
/* rip the memory out of the buffer;
* we like to keep them separate in this pool */
foreign_mem = gst_buffer_get_memory (buf, 0);
gst_buffer_remove_all_memory (buf);
if (pool->add_videometa) {
GstVideoMeta *meta;
meta = gst_buffer_get_video_meta (buf);
if (!meta) {
gst_buffer_add_video_meta (buf, GST_VIDEO_FRAME_FLAG_NONE,
GST_VIDEO_INFO_FORMAT (&pool->video_info),
GST_VIDEO_INFO_WIDTH (&pool->video_info),
GST_VIDEO_INFO_HEIGHT (&pool->video_info));
}
}
pool->need_copy = FALSE;
} else {
const guint nstride = pool->port->port_def.format.video.nStride;
const guint nslice = pool->port->port_def.format.video.nSliceHeight;
gsize offset[GST_VIDEO_MAX_PLANES] = { 0, };
gint stride[GST_VIDEO_MAX_PLANES] = { nstride, 0, };
buf = gst_buffer_new ();
switch (GST_VIDEO_INFO_FORMAT (&pool->video_info)) {
case GST_VIDEO_FORMAT_ABGR:
case GST_VIDEO_FORMAT_ARGB:
case GST_VIDEO_FORMAT_RGB16:
case GST_VIDEO_FORMAT_BGR16:
case GST_VIDEO_FORMAT_YUY2:
case GST_VIDEO_FORMAT_UYVY:
case GST_VIDEO_FORMAT_YVYU:
case GST_VIDEO_FORMAT_GRAY8:
break;
case GST_VIDEO_FORMAT_I420:
stride[1] = nstride / 2;
offset[1] = offset[0] + stride[0] * nslice;
stride[2] = nstride / 2;
offset[2] = offset[1] + (stride[1] * nslice / 2);
break;
case GST_VIDEO_FORMAT_NV12:
case GST_VIDEO_FORMAT_NV12_10LE32:
case GST_VIDEO_FORMAT_NV16:
case GST_VIDEO_FORMAT_NV16_10LE32:
stride[1] = nstride;
offset[1] = offset[0] + stride[0] * nslice;
break;
default:
g_assert_not_reached ();
break;
}
if (pool->add_videometa) {
pool->need_copy = FALSE;
} else {
GstVideoInfo info;
gboolean need_copy = FALSE;
gint i;
gst_video_info_init (&info);
gst_video_info_set_format (&info,
GST_VIDEO_INFO_FORMAT (&pool->video_info),
GST_VIDEO_INFO_WIDTH (&pool->video_info),
GST_VIDEO_INFO_HEIGHT (&pool->video_info));
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&pool->video_info); i++) {
if (info.stride[i] != stride[i] || info.offset[i] != offset[i]) {
GST_DEBUG_OBJECT (pool,
"Need to copy output frames because of stride/offset mismatch: plane %d stride %d (expected: %d) offset %"
G_GSIZE_FORMAT " (expected: %" G_GSIZE_FORMAT
") nStride: %d nSliceHeight: %d ", i, stride[i], info.stride[i],
offset[i], info.offset[i], nstride, nslice);
need_copy = TRUE;
break;
}
}
pool->need_copy = need_copy;
}
if (pool->need_copy || pool->add_videometa) {
/* We always add the videometa. It's the job of the user
* to copy the buffer if pool->need_copy is TRUE
*/
GstVideoMeta *meta;
GstVideoAlignment align;
meta = gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE,
GST_VIDEO_INFO_FORMAT (&pool->video_info),
GST_VIDEO_INFO_WIDTH (&pool->video_info),
GST_VIDEO_INFO_HEIGHT (&pool->video_info),
GST_VIDEO_INFO_N_PLANES (&pool->video_info), offset, stride);
if (gst_omx_video_get_port_padding (pool->port, &pool->video_info,
&align))
gst_video_meta_set_alignment (meta, align);
}
}
mem = gst_omx_allocator_allocate (pool->allocator, pool->current_buffer_index,
foreign_mem);
if (!mem)
return GST_FLOW_ERROR;
if (pool->output_mode == GST_OMX_BUFFER_MODE_DMABUF) {
GstMapInfo map;
if (!gst_caps_features_contains (gst_caps_get_features (pool->caps, 0),
GST_CAPS_FEATURE_MEMORY_DMABUF)) {
/* Check if the memory is actually mappable */
if (!gst_memory_map (mem, &map, GST_MAP_READWRITE)) {
GST_ERROR_OBJECT (pool,
"dmabuf memory is not mappable but caps does not have the 'memory:DMABuf' feature");
gst_memory_unref (mem);
return GST_FLOW_ERROR;
}
gst_memory_unmap (mem, &map);
}
}
/* mem still belongs to the allocator; do not add it in the buffer just yet */
*buffer = buf;
pool->current_buffer_index++;
return GST_FLOW_OK;
}
/* called by the allocator when we are using other_pool in order
* to restore the foreign GstMemory back to its original GstBuffer */
static void
on_allocator_foreign_mem_released (GstOMXAllocator * allocator,
gint index, GstMemory * mem, GstOMXBufferPool * pool)
{
GstBuffer *buf;
buf = g_ptr_array_index (pool->buffers, index);
gst_buffer_append_memory (buf, mem);
/* the buffer consumed the passed reference.
* we still need one more reference for the allocator */
gst_memory_ref (mem);
}
static void
gst_omx_buffer_pool_free_buffer (GstBufferPool * bpool, GstBuffer * buffer)
{
GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
/* If the buffers belong to another pool, restore them now */
GST_OBJECT_LOCK (pool);
if (pool->other_pool) {
gst_object_replace ((GstObject **) & buffer->pool,
(GstObject *) pool->other_pool);
}
GST_OBJECT_UNLOCK (pool);
GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->free_buffer (bpool,
buffer);
}
static GstFlowReturn
gst_omx_buffer_pool_acquire_buffer (GstBufferPool * bpool,
GstBuffer ** buffer, GstBufferPoolAcquireParams * params)
{
GstFlowReturn ret;
GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
GstMemory *mem;
if (pool->port->port_def.eDir == OMX_DirOutput) {
g_return_val_if_fail (pool->current_buffer_index != -1, GST_FLOW_ERROR);
ret = gst_omx_allocator_acquire (pool->allocator, &mem,
pool->current_buffer_index, NULL);
if (ret != GST_FLOW_OK)
return ret;
/* If it's our own memory we have to set the sizes */
if (!pool->other_pool) {
GstOMXBuffer *omx_buf = gst_omx_memory_get_omx_buf (mem);
mem->size = omx_buf->omx_buf->nFilledLen;
mem->offset = omx_buf->omx_buf->nOffset;
}
} else {
/* Acquire any buffer that is available to be filled by upstream */
GstOMXBuffer *omx_buf;
GstOMXAcquireBufferReturn r;
GstOMXWait wait = GST_OMX_WAIT;
if (params && (params->flags & GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT))
wait = GST_OMX_DONT_WAIT;
r = gst_omx_port_acquire_buffer (pool->port, &omx_buf, wait);
if (r == GST_OMX_ACQUIRE_BUFFER_OK) {
ret = gst_omx_allocator_acquire (pool->allocator, &mem, -1, omx_buf);
if (ret != GST_FLOW_OK)
return ret;
} else if (r == GST_OMX_ACQUIRE_BUFFER_FLUSHING) {
return GST_FLOW_FLUSHING;
} else {
return GST_FLOW_ERROR;
}
}
/* get some GstBuffer available in this pool */
ret = GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->acquire_buffer
(bpool, buffer, params);
if (ret == GST_FLOW_OK) {
/* attach the acquired memory on it */
gst_buffer_append_memory (*buffer, mem);
} else {
gst_memory_unref (mem);
}
return ret;
}
static void
gst_omx_buffer_pool_reset_buffer (GstBufferPool * bpool, GstBuffer * buffer)
{
GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
guint n;
n = gst_buffer_n_memory (buffer);
if (G_UNLIKELY (n != 1)) {
GST_ERROR_OBJECT (pool, "Released buffer does not have 1 memory... "
"(n = %u) something went terribly wrong", n);
}
/* rip the memory out of the buffer;
* we like to keep them separate in this pool.
* if this was the last ref count of the memory, it will be returned
* to the allocator, otherwise it will be returned later */
gst_buffer_remove_all_memory (buffer);
/* reset before removing the TAG_MEMORY flag so that the parent impl
* doesn't try to restore the original buffer size */
GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->reset_buffer
(bpool, buffer);
/* pretend nothing happened to the memory to avoid discarding the buffer */
GST_MINI_OBJECT_FLAG_UNSET (buffer, GST_BUFFER_FLAG_TAG_MEMORY);
}
static void
on_allocator_omxbuf_released (GstOMXAllocator * allocator,
GstOMXBuffer * omx_buf, GstOMXBufferPool * pool)
{
OMX_ERRORTYPE err;
if (pool->port->port_def.eDir == OMX_DirOutput && !omx_buf->used &&
!pool->deactivated) {
/* Release back to the port, can be filled again */
err = gst_omx_port_release_buffer (pool->port, omx_buf);
if (err != OMX_ErrorNone) {
GST_ELEMENT_ERROR (pool->element, LIBRARY, SETTINGS, (NULL),
("Failed to relase output buffer to component: %s (0x%08x)",
gst_omx_error_to_string (err), err));
}
} else if (pool->port->port_def.eDir == OMX_DirInput) {
gst_omx_port_requeue_buffer (pool->port, omx_buf);
}
}
static void
gst_omx_buffer_pool_finalize (GObject * object)
{
GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (object);
if (pool->element)
gst_object_unref (pool->element);
pool->element = NULL;
if (pool->buffers)
g_ptr_array_unref (pool->buffers);
pool->buffers = NULL;
if (pool->other_pool)
gst_object_unref (pool->other_pool);
pool->other_pool = NULL;
if (pool->allocator)
gst_object_unref (pool->allocator);
pool->allocator = NULL;
if (pool->caps)
gst_caps_unref (pool->caps);
pool->caps = NULL;
g_clear_pointer (&pool->component, gst_omx_component_unref);
G_OBJECT_CLASS (gst_omx_buffer_pool_parent_class)->finalize (object);
}
static void
gst_omx_buffer_pool_class_init (GstOMXBufferPoolClass * klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
GstBufferPoolClass *gstbufferpool_class = (GstBufferPoolClass *) klass;
gobject_class->finalize = gst_omx_buffer_pool_finalize;
gstbufferpool_class->start = gst_omx_buffer_pool_start;
gstbufferpool_class->stop = gst_omx_buffer_pool_stop;
gstbufferpool_class->get_options = gst_omx_buffer_pool_get_options;
gstbufferpool_class->set_config = gst_omx_buffer_pool_set_config;
gstbufferpool_class->alloc_buffer = gst_omx_buffer_pool_alloc_buffer;
gstbufferpool_class->free_buffer = gst_omx_buffer_pool_free_buffer;
gstbufferpool_class->acquire_buffer = gst_omx_buffer_pool_acquire_buffer;
gstbufferpool_class->reset_buffer = gst_omx_buffer_pool_reset_buffer;
signals[SIG_ALLOCATE] = g_signal_new ("allocate",
G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
G_TYPE_BOOLEAN, 0);
}
static void
gst_omx_buffer_pool_init (GstOMXBufferPool * pool)
{
pool->buffers = g_ptr_array_new ();
}
GstBufferPool *
gst_omx_buffer_pool_new (GstElement * element, GstOMXComponent * component,
GstOMXPort * port, GstOMXBufferMode output_mode)
{
GstOMXBufferPool *pool;
pool = g_object_new (gst_omx_buffer_pool_get_type (), NULL);
pool->element = gst_object_ref (element);
pool->component = gst_omx_component_ref (component);
pool->port = port;
pool->output_mode = output_mode;
pool->allocator = gst_omx_allocator_new (component, port);
g_signal_connect_object (pool->allocator, "omxbuf-released",
(GCallback) on_allocator_omxbuf_released, pool, 0);
g_signal_connect_object (pool->allocator, "foreign-mem-released",
(GCallback) on_allocator_foreign_mem_released, pool, 0);
return GST_BUFFER_POOL (pool);
}

101
omx/gstomxbufferpool.h Normal file
View file

@ -0,0 +1,101 @@
/*
* Copyright 2014 Advanced Micro Devices, Inc.
* Author: Christian König <christian.koenig@amd.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_BUFFER_POOL_H__
#define __GST_OMX_BUFFER_POOL_H__
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include <gst/video/gstvideometa.h>
#include <gst/video/gstvideopool.h>
#include "gstomx.h"
#include "gstomxallocator.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_BUFFER_POOL \
(gst_omx_buffer_pool_get_type())
#define GST_OMX_BUFFER_POOL(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_BUFFER_POOL,GstOMXBufferPool))
#define GST_IS_OMX_BUFFER_POOL(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_BUFFER_POOL))
typedef struct _GstOMXBufferPool GstOMXBufferPool;
typedef struct _GstOMXBufferPoolClass GstOMXBufferPoolClass;
typedef enum {
GST_OMX_BUFFER_MODE_SYSTEM_MEMORY,
GST_OMX_BUFFER_MODE_DMABUF,
} GstOMXBufferMode;
struct _GstOMXBufferPool
{
GstVideoBufferPool parent;
GstElement *element;
GstCaps *caps;
gboolean add_videometa;
gboolean need_copy;
GstVideoInfo video_info;
/* Owned by element, element has to stop this pool before
* it destroys component or port */
GstOMXComponent *component;
GstOMXPort *port;
/* For handling OpenMAX allocated memory */
GstOMXAllocator *allocator;
/* Set from outside this pool */
/* TRUE if the pool is not used anymore */
gboolean deactivated;
/* For populating the pool from another one */
GstBufferPool *other_pool;
GPtrArray *buffers;
/* Used during acquire for output ports to
* specify which buffer has to be retrieved
* and during alloc, which buffer has to be
* wrapped
*/
gint current_buffer_index;
/* The type of buffers produced by the decoder */
GstOMXBufferMode output_mode;
};
struct _GstOMXBufferPoolClass
{
GstVideoBufferPoolClass parent_class;
};
GType gst_omx_buffer_pool_get_type (void);
GstBufferPool *gst_omx_buffer_pool_new (GstElement * element, GstOMXComponent * component, GstOMXPort * port, GstOMXBufferMode output_mode);
G_END_DECLS
#endif /* __GST_OMX_BUFFER_POOL_H__ */

99
omx/gstomxh263dec.c Normal file
View file

@ -0,0 +1,99 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxh263dec.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_h263_dec_debug_category);
#define GST_CAT_DEFAULT gst_omx_h263_dec_debug_category
/* prototypes */
static gboolean gst_omx_h263_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
static gboolean gst_omx_h263_dec_set_format (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
enum
{
PROP_0
};
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_h263_dec_debug_category, "omxh263dec", 0, \
"debug category for gst-omx video decoder base class");
G_DEFINE_TYPE_WITH_CODE (GstOMXH263Dec, gst_omx_h263_dec,
GST_TYPE_OMX_VIDEO_DEC, DEBUG_INIT);
static void
gst_omx_h263_dec_class_init (GstOMXH263DecClass * klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstOMXVideoDecClass *videodec_class = GST_OMX_VIDEO_DEC_CLASS (klass);
videodec_class->is_format_change =
GST_DEBUG_FUNCPTR (gst_omx_h263_dec_is_format_change);
videodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_h263_dec_set_format);
videodec_class->cdata.default_sink_template_caps = "video/x-h263, "
"variant=(string) itu, "
"parsed=(boolean) true, " "width=(int) [1,MAX], " "height=(int) [1,MAX]";
gst_element_class_set_static_metadata (element_class,
"OpenMAX H.263 Video Decoder",
"Codec/Decoder/Video/Hardware",
"Decode H.263 video streams",
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
gst_omx_set_default_role (&videodec_class->cdata, "video_decoder.h263");
}
static void
gst_omx_h263_dec_init (GstOMXH263Dec * self)
{
}
static gboolean
gst_omx_h263_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state)
{
return FALSE;
}
static gboolean
gst_omx_h263_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port,
GstVideoCodecState * state)
{
gboolean ret;
OMX_PARAM_PORTDEFINITIONTYPE port_def;
gst_omx_port_get_port_definition (port, &port_def);
port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
ret = gst_omx_port_update_port_definition (port, &port_def) == OMX_ErrorNone;
return ret;
}

60
omx/gstomxh263dec.h Normal file
View file

@ -0,0 +1,60 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_H263_DEC_H__
#define __GST_OMX_H263_DEC_H__
#include <gst/gst.h>
#include "gstomxvideodec.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_H263_DEC \
(gst_omx_h263_dec_get_type())
#define GST_OMX_H263_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_H263_DEC,GstOMXH263Dec))
#define GST_OMX_H263_DEC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_H263_DEC,GstOMXH263DecClass))
#define GST_OMX_H263_DEC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_H263_DEC,GstOMXH263DecClass))
#define GST_IS_OMX_H263_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_H263_DEC))
#define GST_IS_OMX_H263_DEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_H263_DEC))
typedef struct _GstOMXH263Dec GstOMXH263Dec;
typedef struct _GstOMXH263DecClass GstOMXH263DecClass;
struct _GstOMXH263Dec
{
GstOMXVideoDec parent;
};
struct _GstOMXH263DecClass
{
GstOMXVideoDecClass parent_class;
};
GType gst_omx_h263_dec_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_H263_DEC_H__ */

302
omx/gstomxh263enc.c Normal file
View file

@ -0,0 +1,302 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxh263enc.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_h263_enc_debug_category);
#define GST_CAT_DEFAULT gst_omx_h263_enc_debug_category
/* prototypes */
static gboolean gst_omx_h263_enc_set_format (GstOMXVideoEnc * enc,
GstOMXPort * port, GstVideoCodecState * state);
static GstCaps *gst_omx_h263_enc_get_caps (GstOMXVideoEnc * enc,
GstOMXPort * port, GstVideoCodecState * state);
enum
{
PROP_0
};
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_h263_enc_debug_category, "omxh263enc", 0, \
"debug category for gst-omx video encoder base class");
G_DEFINE_TYPE_WITH_CODE (GstOMXH263Enc, gst_omx_h263_enc,
GST_TYPE_OMX_VIDEO_ENC, DEBUG_INIT);
static void
gst_omx_h263_enc_class_init (GstOMXH263EncClass * klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstOMXVideoEncClass *videoenc_class = GST_OMX_VIDEO_ENC_CLASS (klass);
videoenc_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_h263_enc_set_format);
videoenc_class->get_caps = GST_DEBUG_FUNCPTR (gst_omx_h263_enc_get_caps);
videoenc_class->cdata.default_src_template_caps = "video/x-h263, "
"width=(int) [ 16, 4096 ], " "height=(int) [ 16, 4096 ]";
gst_element_class_set_static_metadata (element_class,
"OpenMAX H.263 Video Encoder",
"Codec/Encoder/Video/Hardware",
"Encode H.263 video streams",
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
gst_omx_set_default_role (&videoenc_class->cdata, "video_encoder.h263");
}
static void
gst_omx_h263_enc_init (GstOMXH263Enc * self)
{
}
static gboolean
gst_omx_h263_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port,
GstVideoCodecState * state)
{
GstOMXH263Enc *self = GST_OMX_H263_ENC (enc);
GstCaps *peercaps;
OMX_PARAM_PORTDEFINITIONTYPE port_def;
OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
OMX_ERRORTYPE err;
guint profile_id, level_id;
gst_omx_port_get_port_definition (GST_OMX_VIDEO_ENC (self)->enc_out_port,
&port_def);
port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
err =
gst_omx_port_update_port_definition (GST_OMX_VIDEO_ENC
(self)->enc_out_port, &port_def);
if (err != OMX_ErrorNone)
return FALSE;
GST_OMX_INIT_STRUCT (&param);
param.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
err =
gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexParamVideoProfileLevelCurrent, &param);
if (err != OMX_ErrorNone) {
GST_WARNING_OBJECT (self,
"Getting profile/level not supported by component");
return TRUE;
}
peercaps = gst_pad_peer_query_caps (GST_VIDEO_ENCODER_SRC_PAD (enc),
gst_pad_get_pad_template_caps (GST_VIDEO_ENCODER_SRC_PAD (enc)));
if (peercaps) {
GstStructure *s;
if (gst_caps_is_empty (peercaps)) {
gst_caps_unref (peercaps);
GST_ERROR_OBJECT (self, "Empty caps");
return FALSE;
}
s = gst_caps_get_structure (peercaps, 0);
if (gst_structure_get_uint (s, "profile", &profile_id)) {
switch (profile_id) {
case 0:
param.eProfile = OMX_VIDEO_H263ProfileBaseline;
break;
case 1:
param.eProfile = OMX_VIDEO_H263ProfileH320Coding;
break;
case 2:
param.eProfile = OMX_VIDEO_H263ProfileBackwardCompatible;
break;
case 3:
param.eProfile = OMX_VIDEO_H263ProfileISWV2;
break;
case 4:
param.eProfile = OMX_VIDEO_H263ProfileISWV3;
break;
case 5:
param.eProfile = OMX_VIDEO_H263ProfileHighCompression;
break;
case 6:
param.eProfile = OMX_VIDEO_H263ProfileInternet;
break;
case 7:
param.eProfile = OMX_VIDEO_H263ProfileInterlace;
break;
case 8:
param.eProfile = OMX_VIDEO_H263ProfileHighLatency;
break;
default:
goto unsupported_profile;
}
}
if (gst_structure_get_uint (s, "level", &level_id)) {
switch (level_id) {
case 10:
param.eLevel = OMX_VIDEO_H263Level10;
break;
case 20:
param.eLevel = OMX_VIDEO_H263Level20;
break;
case 30:
param.eLevel = OMX_VIDEO_H263Level30;
break;
case 40:
param.eLevel = OMX_VIDEO_H263Level40;
break;
case 50:
param.eLevel = OMX_VIDEO_H263Level50;
break;
case 60:
param.eLevel = OMX_VIDEO_H263Level60;
break;
case 70:
param.eLevel = OMX_VIDEO_H263Level70;
break;
default:
goto unsupported_level;
}
}
gst_caps_unref (peercaps);
}
err =
gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexParamVideoProfileLevelCurrent, &param);
if (err == OMX_ErrorUnsupportedIndex) {
GST_WARNING_OBJECT (self,
"Setting profile/level not supported by component");
} else if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Error setting profile %u and level %u: %s (0x%08x)",
(guint) param.eProfile, (guint) param.eLevel,
gst_omx_error_to_string (err), err);
return FALSE;
}
return TRUE;
unsupported_profile:
GST_ERROR_OBJECT (self, "Unsupported profile %u", profile_id);
gst_caps_unref (peercaps);
return FALSE;
unsupported_level:
GST_ERROR_OBJECT (self, "Unsupported level %u", level_id);
gst_caps_unref (peercaps);
return FALSE;
}
static GstCaps *
gst_omx_h263_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port,
GstVideoCodecState * state)
{
GstOMXH263Enc *self = GST_OMX_H263_ENC (enc);
GstCaps *caps;
OMX_ERRORTYPE err;
OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
guint profile, level;
caps = gst_caps_new_empty_simple ("video/x-h263");
GST_OMX_INIT_STRUCT (&param);
param.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
err =
gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexParamVideoProfileLevelCurrent, &param);
if (err != OMX_ErrorNone && err != OMX_ErrorUnsupportedIndex) {
gst_caps_unref (caps);
return NULL;
}
if (err == OMX_ErrorNone) {
switch (param.eProfile) {
case OMX_VIDEO_H263ProfileBaseline:
profile = 0;
break;
case OMX_VIDEO_H263ProfileH320Coding:
profile = 1;
break;
case OMX_VIDEO_H263ProfileBackwardCompatible:
profile = 2;
break;
case OMX_VIDEO_H263ProfileISWV2:
profile = 3;
break;
case OMX_VIDEO_H263ProfileISWV3:
profile = 4;
break;
case OMX_VIDEO_H263ProfileHighCompression:
profile = 5;
break;
case OMX_VIDEO_H263ProfileInternet:
profile = 6;
break;
case OMX_VIDEO_H263ProfileInterlace:
profile = 7;
break;
case OMX_VIDEO_H263ProfileHighLatency:
profile = 8;
break;
default:
g_assert_not_reached ();
gst_caps_unref (caps);
return NULL;
}
switch (param.eLevel) {
case OMX_VIDEO_H263Level10:
level = 10;
break;
case OMX_VIDEO_H263Level20:
level = 20;
break;
case OMX_VIDEO_H263Level30:
level = 30;
break;
case OMX_VIDEO_H263Level40:
level = 40;
break;
case OMX_VIDEO_H263Level50:
level = 50;
break;
case OMX_VIDEO_H263Level60:
level = 60;
break;
case OMX_VIDEO_H263Level70:
level = 70;
break;
default:
g_assert_not_reached ();
gst_caps_unref (caps);
return NULL;
}
gst_caps_set_simple (caps,
"profile", G_TYPE_UINT, profile, "level", G_TYPE_UINT, level, NULL);
}
return caps;
}

60
omx/gstomxh263enc.h Normal file
View file

@ -0,0 +1,60 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_H263_ENC_H__
#define __GST_OMX_H263_ENC_H__
#include <gst/gst.h>
#include "gstomxvideoenc.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_H263_ENC \
(gst_omx_h263_enc_get_type())
#define GST_OMX_H263_ENC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_H263_ENC,GstOMXH263Enc))
#define GST_OMX_H263_ENC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_H263_ENC,GstOMXH263EncClass))
#define GST_OMX_H263_ENC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_H263_ENC,GstOMXH263EncClass))
#define GST_IS_OMX_H263_ENC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_H263_ENC))
#define GST_IS_OMX_H263_ENC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_H263_ENC))
typedef struct _GstOMXH263Enc GstOMXH263Enc;
typedef struct _GstOMXH263EncClass GstOMXH263EncClass;
struct _GstOMXH263Enc
{
GstOMXVideoEnc parent;
};
struct _GstOMXH263EncClass
{
GstOMXVideoEncClass parent_class;
};
GType gst_omx_h263_enc_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_H263_ENC_H__ */

216
omx/gstomxh264dec.c Normal file
View file

@ -0,0 +1,216 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxh264dec.h"
#include "gstomxh264utils.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_h264_dec_debug_category);
#define GST_CAT_DEFAULT gst_omx_h264_dec_debug_category
/* prototypes */
static gboolean gst_omx_h264_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
static gboolean gst_omx_h264_dec_set_format (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
enum
{
PROP_0
};
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_h264_dec_debug_category, "omxh264dec", 0, \
"debug category for gst-omx video decoder base class");
G_DEFINE_TYPE_WITH_CODE (GstOMXH264Dec, gst_omx_h264_dec,
GST_TYPE_OMX_VIDEO_DEC, DEBUG_INIT);
#define MAKE_CAPS(alignment) \
"video/x-h264, " \
"alignment=(string) " alignment ", " \
"stream-format=(string) byte-stream, " \
"width=(int) [1,MAX], height=(int) [1,MAX]"
/* The Zynq supports decoding subframes, though we want "au" to be the
* default, so we keep it prepended. This is the only way that it works with
* rtph264depay. */
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
#define SINK_CAPS MAKE_CAPS ("au") ";" MAKE_CAPS ("nal")
#else
#define SINK_CAPS MAKE_CAPS ("au")
#endif
static void
gst_omx_h264_dec_class_init (GstOMXH264DecClass * klass)
{
GstOMXVideoDecClass *videodec_class = GST_OMX_VIDEO_DEC_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
videodec_class->is_format_change =
GST_DEBUG_FUNCPTR (gst_omx_h264_dec_is_format_change);
videodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_h264_dec_set_format);
videodec_class->cdata.default_sink_template_caps = SINK_CAPS;
gst_element_class_set_static_metadata (element_class,
"OpenMAX H.264 Video Decoder",
"Codec/Decoder/Video/Hardware",
"Decode H.264 video streams",
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
gst_omx_set_default_role (&videodec_class->cdata, "video_decoder.avc");
}
static void
gst_omx_h264_dec_init (GstOMXH264Dec * self)
{
}
static gboolean
gst_omx_h264_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state)
{
GstCaps *old_caps = NULL;
GstCaps *new_caps = state->caps;
GstStructure *old_structure, *new_structure;
const gchar *old_profile, *old_level, *old_alignment, *new_profile,
*new_level, *new_alignment;
if (dec->input_state) {
old_caps = dec->input_state->caps;
}
if (!old_caps) {
return FALSE;
}
old_structure = gst_caps_get_structure (old_caps, 0);
new_structure = gst_caps_get_structure (new_caps, 0);
old_profile = gst_structure_get_string (old_structure, "profile");
old_level = gst_structure_get_string (old_structure, "level");
old_alignment = gst_structure_get_string (old_structure, "alignment");
new_profile = gst_structure_get_string (new_structure, "profile");
new_level = gst_structure_get_string (new_structure, "level");
new_alignment = gst_structure_get_string (new_structure, "alignment");
if (g_strcmp0 (old_profile, new_profile) != 0
|| g_strcmp0 (old_level, new_level) != 0
|| g_strcmp0 (old_alignment, new_alignment) != 0) {
return TRUE;
}
return FALSE;
}
static gboolean
set_profile_and_level (GstOMXH264Dec * self, GstVideoCodecState * state)
{
OMX_ERRORTYPE err;
OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
const gchar *profile_string, *level_string;
GstStructure *s;
GST_OMX_INIT_STRUCT (&param);
param.nPortIndex = GST_OMX_VIDEO_DEC (self)->dec_in_port->index;
/* Pass profile and level to the decoder if we have both info from the
* caps. */
s = gst_caps_get_structure (state->caps, 0);
profile_string = gst_structure_get_string (s, "profile");
if (!profile_string)
return TRUE;
param.eProfile = gst_omx_h264_utils_get_profile_from_str (profile_string);
if (param.eProfile == OMX_VIDEO_AVCProfileMax)
goto unsupported_profile;
level_string = gst_structure_get_string (s, "level");
if (!level_string)
return TRUE;
param.eLevel = gst_omx_h264_utils_get_level_from_str (level_string);
if (param.eLevel == OMX_VIDEO_AVCLevelMax)
goto unsupported_level;
GST_DEBUG_OBJECT (self, "Set profile (%s) and level (%s) on decoder",
profile_string, level_string);
err =
gst_omx_component_set_parameter (GST_OMX_VIDEO_DEC (self)->dec,
OMX_IndexParamVideoProfileLevelCurrent, &param);
if (err == OMX_ErrorUnsupportedIndex) {
GST_WARNING_OBJECT (self,
"Setting profile/level not supported by component");
} else if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Error setting profile %u and level %u: %s (0x%08x)",
(guint) param.eProfile, (guint) param.eLevel,
gst_omx_error_to_string (err), err);
return FALSE;
}
return TRUE;
unsupported_profile:
GST_ERROR_OBJECT (self, "Unsupported profile %s", profile_string);
return FALSE;
unsupported_level:
GST_ERROR_OBJECT (self, "Unsupported level %s", level_string);
return FALSE;
}
static gboolean
gst_omx_h264_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port,
GstVideoCodecState * state)
{
GstOMXVideoDecClass *klass = GST_OMX_VIDEO_DEC_GET_CLASS (dec);
OMX_PARAM_PORTDEFINITIONTYPE port_def;
OMX_ERRORTYPE err;
const GstStructure *s;
gst_omx_port_get_port_definition (port, &port_def);
port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
err = gst_omx_port_update_port_definition (port, &port_def);
if (err != OMX_ErrorNone)
return FALSE;
if (klass->cdata.hacks & GST_OMX_HACK_PASS_PROFILE_TO_DECODER) {
if (!set_profile_and_level (GST_OMX_H264_DEC (dec), state))
return FALSE;
}
/* Enable subframe mode if NAL aligned */
s = gst_caps_get_structure (state->caps, 0);
if (!g_strcmp0 (gst_structure_get_string (s, "alignment"), "nal")
&& gst_omx_port_set_subframe (dec->dec_in_port, TRUE)) {
gst_video_decoder_set_subframe_mode (GST_VIDEO_DECODER (dec), TRUE);
}
return TRUE;
}

60
omx/gstomxh264dec.h Normal file
View file

@ -0,0 +1,60 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_H264_DEC_H__
#define __GST_OMX_H264_DEC_H__
#include <gst/gst.h>
#include "gstomxvideodec.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_H264_DEC \
(gst_omx_h264_dec_get_type())
#define GST_OMX_H264_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_H264_DEC,GstOMXH264Dec))
#define GST_OMX_H264_DEC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_H264_DEC,GstOMXH264DecClass))
#define GST_OMX_H264_DEC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_H264_DEC,GstOMXH264DecClass))
#define GST_IS_OMX_H264_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_H264_DEC))
#define GST_IS_OMX_H264_DEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_H264_DEC))
typedef struct _GstOMXH264Dec GstOMXH264Dec;
typedef struct _GstOMXH264DecClass GstOMXH264DecClass;
struct _GstOMXH264Dec
{
GstOMXVideoDec parent;
};
struct _GstOMXH264DecClass
{
GstOMXVideoDecClass parent_class;
};
GType gst_omx_h264_dec_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_H264_DEC_H__ */

894
omx/gstomxh264enc.c Normal file
View file

@ -0,0 +1,894 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxh264enc.h"
#include "gstomxh264utils.h"
#ifdef USE_OMX_TARGET_RPI
#include <OMX_Broadcom.h>
#include <OMX_Index.h>
#endif
GST_DEBUG_CATEGORY_STATIC (gst_omx_h264_enc_debug_category);
#define GST_CAT_DEFAULT gst_omx_h264_enc_debug_category
/* prototypes */
static gboolean gst_omx_h264_enc_set_format (GstOMXVideoEnc * enc,
GstOMXPort * port, GstVideoCodecState * state);
static GstCaps *gst_omx_h264_enc_get_caps (GstOMXVideoEnc * enc,
GstOMXPort * port, GstVideoCodecState * state);
static GstFlowReturn gst_omx_h264_enc_handle_output_frame (GstOMXVideoEnc *
self, GstOMXPort * port, GstOMXBuffer * buf, GstVideoCodecFrame * frame);
static gboolean gst_omx_h264_enc_flush (GstVideoEncoder * enc);
static gboolean gst_omx_h264_enc_stop (GstVideoEncoder * enc);
static void gst_omx_h264_enc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_omx_h264_enc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
enum
{
PROP_0,
#ifdef USE_OMX_TARGET_RPI
PROP_INLINESPSPPSHEADERS,
#endif
PROP_PERIODICITYOFIDRFRAMES,
PROP_PERIODICITYOFIDRFRAMES_COMPAT,
PROP_INTERVALOFCODINGINTRAFRAMES,
PROP_B_FRAMES,
PROP_ENTROPY_MODE,
PROP_CONSTRAINED_INTRA_PREDICTION,
PROP_LOOP_FILTER_MODE,
PROP_REF_FRAMES
};
#ifdef USE_OMX_TARGET_RPI
#define GST_OMX_H264_VIDEO_ENC_INLINE_SPS_PPS_HEADERS_DEFAULT TRUE
#endif
#define GST_OMX_H264_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT (0xffffffff)
#define GST_OMX_H264_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT (0xffffffff)
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
#define GST_OMX_H264_VIDEO_ENC_B_FRAMES_DEFAULT (0)
#define ALIGNMENT "{ au, nal }"
#else
#define GST_OMX_H264_VIDEO_ENC_B_FRAMES_DEFAULT (0xffffffff)
#define ALIGNMENT "au"
#endif
#define GST_OMX_H264_VIDEO_ENC_ENTROPY_MODE_DEFAULT (0xffffffff)
#define GST_OMX_H264_VIDEO_ENC_CONSTRAINED_INTRA_PREDICTION_DEFAULT (FALSE)
#define GST_OMX_H264_VIDEO_ENC_LOOP_FILTER_MODE_DEFAULT (0xffffffff)
#define GST_OMX_H264_VIDEO_ENC_REF_FRAMES_DEFAULT 0
#define GST_OMX_H264_VIDEO_ENC_REF_FRAMES_MIN 0
#define GST_OMX_H264_VIDEO_ENC_REF_FRAMES_MAX 16
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_h264_enc_debug_category, "omxh264enc", 0, \
"debug category for gst-omx video encoder base class");
#define parent_class gst_omx_h264_enc_parent_class
G_DEFINE_TYPE_WITH_CODE (GstOMXH264Enc, gst_omx_h264_enc,
GST_TYPE_OMX_VIDEO_ENC, DEBUG_INIT);
#define GST_TYPE_OMX_H264_ENC_ENTROPY_MODE (gst_omx_h264_enc_entropy_mode_get_type ())
static GType
gst_omx_h264_enc_entropy_mode_get_type (void)
{
static GType qtype = 0;
if (qtype == 0) {
static const GEnumValue values[] = {
{FALSE, "CAVLC entropy mode", "CAVLC"},
{TRUE, "CABAC entropy mode", "CABAC"},
{0xffffffff, "Component Default", "default"},
{0, NULL, NULL}
};
qtype = g_enum_register_static ("GstOMXH264EncEntropyMode", values);
}
return qtype;
}
#define GST_TYPE_OMX_H264_ENC_LOOP_FILTER_MODE (gst_omx_h264_enc_loop_filter_mode_get_type ())
static GType
gst_omx_h264_enc_loop_filter_mode_get_type (void)
{
static GType qtype = 0;
if (qtype == 0) {
static const GEnumValue values[] = {
{OMX_VIDEO_AVCLoopFilterEnable, "Enable deblocking filter", "enable"},
{OMX_VIDEO_AVCLoopFilterDisable, "Disable deblocking filter", "disable"},
{OMX_VIDEO_AVCLoopFilterDisableSliceBoundary,
"Disables deblocking filter on slice boundary",
"disable-slice-boundary"},
{0xffffffff, "Component Default", "default"},
{0, NULL, NULL}
};
qtype = g_enum_register_static ("GstOMXH264EncLoopFilter", values);
}
return qtype;
}
static void
gst_omx_h264_enc_class_init (GstOMXH264EncClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstVideoEncoderClass *basevideoenc_class = GST_VIDEO_ENCODER_CLASS (klass);
GstOMXVideoEncClass *videoenc_class = GST_OMX_VIDEO_ENC_CLASS (klass);
videoenc_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_h264_enc_set_format);
videoenc_class->get_caps = GST_DEBUG_FUNCPTR (gst_omx_h264_enc_get_caps);
gobject_class->set_property = gst_omx_h264_enc_set_property;
gobject_class->get_property = gst_omx_h264_enc_get_property;
#ifdef USE_OMX_TARGET_RPI
g_object_class_install_property (gobject_class, PROP_INLINESPSPPSHEADERS,
g_param_spec_boolean ("inline-header",
"Inline SPS/PPS headers before IDR",
"Inline SPS/PPS header before IDR",
GST_OMX_H264_VIDEO_ENC_INLINE_SPS_PPS_HEADERS_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
#endif
g_object_class_install_property (gobject_class, PROP_PERIODICITYOFIDRFRAMES,
g_param_spec_uint ("periodicity-idr", "IDR periodicity",
"Periodicity of IDR frames (0xffffffff=component default)",
0, G_MAXUINT,
GST_OMX_H264_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
g_object_class_install_property (gobject_class,
PROP_PERIODICITYOFIDRFRAMES_COMPAT, g_param_spec_uint ("periodicty-idr",
"IDR periodicity",
"Periodicity of IDR frames (0xffffffff=component default) DEPRECATED - only for backwards compat",
0, G_MAXUINT,
GST_OMX_H264_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
g_object_class_install_property (gobject_class,
PROP_INTERVALOFCODINGINTRAFRAMES,
g_param_spec_uint ("interval-intraframes",
"Interval of coding Intra frames",
"Interval of coding Intra frames (0xffffffff=component default)", 0,
G_MAXUINT,
GST_OMX_H264_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
g_object_class_install_property (gobject_class, PROP_B_FRAMES,
g_param_spec_uint ("b-frames", "Number of B-frames",
"Number of B-frames between two consecutive I-frames (0xffffffff=component default)",
0, G_MAXUINT, GST_OMX_H264_VIDEO_ENC_B_FRAMES_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
g_object_class_install_property (gobject_class, PROP_ENTROPY_MODE,
g_param_spec_enum ("entropy-mode", "Entropy Mode",
"Entropy mode for encoding process",
GST_TYPE_OMX_H264_ENC_ENTROPY_MODE,
GST_OMX_H264_VIDEO_ENC_ENTROPY_MODE_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
g_object_class_install_property (gobject_class,
PROP_CONSTRAINED_INTRA_PREDICTION,
g_param_spec_boolean ("constrained-intra-prediction",
"Constrained Intra Prediction",
"If enabled, prediction only uses residual data and decoded samples "
"from neighbouring coding blocks coded using intra prediction modes",
GST_OMX_H264_VIDEO_ENC_CONSTRAINED_INTRA_PREDICTION_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
g_object_class_install_property (gobject_class, PROP_LOOP_FILTER_MODE,
g_param_spec_enum ("loop-filter-mode", "Loop Filter mode",
"Enable or disable the deblocking filter (0xffffffff=component default)",
GST_TYPE_OMX_H264_ENC_LOOP_FILTER_MODE,
GST_OMX_H264_VIDEO_ENC_LOOP_FILTER_MODE_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
g_object_class_install_property (gobject_class, PROP_REF_FRAMES,
g_param_spec_uchar ("ref-frames", "Reference frames",
"Number of reference frames used for inter-motion search (0=component default)",
GST_OMX_H264_VIDEO_ENC_REF_FRAMES_MIN,
GST_OMX_H264_VIDEO_ENC_REF_FRAMES_MAX,
GST_OMX_H264_VIDEO_ENC_REF_FRAMES_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
basevideoenc_class->flush = gst_omx_h264_enc_flush;
basevideoenc_class->stop = gst_omx_h264_enc_stop;
videoenc_class->cdata.default_src_template_caps = "video/x-h264, "
"width = (int) [ 16, 4096 ], height = (int) [ 16, 4096 ], "
"framerate = (fraction) [0, MAX], stream-format=(string) byte-stream, "
"alignment = (string) " ALIGNMENT;
videoenc_class->handle_output_frame =
GST_DEBUG_FUNCPTR (gst_omx_h264_enc_handle_output_frame);
gst_element_class_set_static_metadata (element_class,
"OpenMAX H.264 Video Encoder",
"Codec/Encoder/Video/Hardware",
"Encode H.264 video streams",
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
gst_omx_set_default_role (&videoenc_class->cdata, "video_encoder.avc");
}
static void
gst_omx_h264_enc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstOMXH264Enc *self = GST_OMX_H264_ENC (object);
switch (prop_id) {
#ifdef USE_OMX_TARGET_RPI
case PROP_INLINESPSPPSHEADERS:
self->inline_sps_pps_headers = g_value_get_boolean (value);
break;
#endif
case PROP_PERIODICITYOFIDRFRAMES:
case PROP_PERIODICITYOFIDRFRAMES_COMPAT:
self->periodicty_idr = g_value_get_uint (value);
break;
case PROP_INTERVALOFCODINGINTRAFRAMES:
self->interval_intraframes = g_value_get_uint (value);
break;
case PROP_B_FRAMES:
self->b_frames = g_value_get_uint (value);
break;
case PROP_ENTROPY_MODE:
self->entropy_mode = g_value_get_enum (value);
break;
case PROP_CONSTRAINED_INTRA_PREDICTION:
self->constrained_intra_prediction = g_value_get_boolean (value);
break;
case PROP_LOOP_FILTER_MODE:
self->loop_filter_mode = g_value_get_enum (value);
break;
case PROP_REF_FRAMES:
self->ref_frames = g_value_get_uchar (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_omx_h264_enc_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstOMXH264Enc *self = GST_OMX_H264_ENC (object);
switch (prop_id) {
#ifdef USE_OMX_TARGET_RPI
case PROP_INLINESPSPPSHEADERS:
g_value_set_boolean (value, self->inline_sps_pps_headers);
break;
#endif
case PROP_PERIODICITYOFIDRFRAMES:
case PROP_PERIODICITYOFIDRFRAMES_COMPAT:
g_value_set_uint (value, self->periodicty_idr);
break;
case PROP_INTERVALOFCODINGINTRAFRAMES:
g_value_set_uint (value, self->interval_intraframes);
break;
case PROP_B_FRAMES:
g_value_set_uint (value, self->b_frames);
break;
case PROP_ENTROPY_MODE:
g_value_set_enum (value, self->entropy_mode);
break;
case PROP_CONSTRAINED_INTRA_PREDICTION:
g_value_set_boolean (value, self->constrained_intra_prediction);
break;
case PROP_LOOP_FILTER_MODE:
g_value_set_enum (value, self->loop_filter_mode);
break;
case PROP_REF_FRAMES:
g_value_set_uchar (value, self->ref_frames);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_omx_h264_enc_init (GstOMXH264Enc * self)
{
#ifdef USE_OMX_TARGET_RPI
self->inline_sps_pps_headers =
GST_OMX_H264_VIDEO_ENC_INLINE_SPS_PPS_HEADERS_DEFAULT;
#endif
self->periodicty_idr =
GST_OMX_H264_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT;
self->interval_intraframes =
GST_OMX_H264_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT;
self->b_frames = GST_OMX_H264_VIDEO_ENC_B_FRAMES_DEFAULT;
self->entropy_mode = GST_OMX_H264_VIDEO_ENC_ENTROPY_MODE_DEFAULT;
self->constrained_intra_prediction =
GST_OMX_H264_VIDEO_ENC_CONSTRAINED_INTRA_PREDICTION_DEFAULT;
self->loop_filter_mode = GST_OMX_H264_VIDEO_ENC_LOOP_FILTER_MODE_DEFAULT;
self->ref_frames = GST_OMX_H264_VIDEO_ENC_REF_FRAMES_DEFAULT;
}
static gboolean
gst_omx_h264_enc_flush (GstVideoEncoder * enc)
{
GstOMXH264Enc *self = GST_OMX_H264_ENC (enc);
g_list_free_full (self->headers, (GDestroyNotify) gst_buffer_unref);
self->headers = NULL;
return GST_VIDEO_ENCODER_CLASS (parent_class)->flush (enc);
}
static gboolean
gst_omx_h264_enc_stop (GstVideoEncoder * enc)
{
GstOMXH264Enc *self = GST_OMX_H264_ENC (enc);
g_list_free_full (self->headers, (GDestroyNotify) gst_buffer_unref);
self->headers = NULL;
return GST_VIDEO_ENCODER_CLASS (parent_class)->stop (enc);
}
/* Update OMX_VIDEO_PARAM_PROFILELEVELTYPE.{eProfile,eLevel}
*
* Returns TRUE if succeeded or if not supported, FALSE if failed */
static gboolean
update_param_profile_level (GstOMXH264Enc * self,
OMX_VIDEO_AVCPROFILETYPE profile, OMX_VIDEO_AVCLEVELTYPE level)
{
OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
OMX_ERRORTYPE err;
GST_OMX_INIT_STRUCT (&param);
param.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
err =
gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexParamVideoProfileLevelCurrent, &param);
if (err != OMX_ErrorNone) {
GST_WARNING_OBJECT (self,
"Getting OMX_IndexParamVideoProfileLevelCurrent not supported by component");
return TRUE;
}
if (profile != OMX_VIDEO_AVCProfileMax)
param.eProfile = profile;
if (level != OMX_VIDEO_AVCLevelMax)
param.eLevel = level;
err =
gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexParamVideoProfileLevelCurrent, &param);
if (err == OMX_ErrorUnsupportedIndex) {
GST_WARNING_OBJECT (self,
"Setting OMX_IndexParamVideoProfileLevelCurrent not supported by component");
return TRUE;
} else if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Error setting profile %u and level %u: %s (0x%08x)",
(guint) param.eProfile, (guint) param.eLevel,
gst_omx_error_to_string (err), err);
return FALSE;
}
return TRUE;
}
/* Update OMX_VIDEO_PARAM_AVCTYPE
*
* Returns TRUE if succeeded or if not supported, FALSE if failed */
static gboolean
update_param_avc (GstOMXH264Enc * self,
OMX_VIDEO_AVCPROFILETYPE profile, OMX_VIDEO_AVCLEVELTYPE level)
{
OMX_VIDEO_PARAM_AVCTYPE param;
OMX_ERRORTYPE err;
GST_OMX_INIT_STRUCT (&param);
param.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
/* On Android the param struct is initialized manually with default
* settings rather than using GetParameter() to retrieve them.
* We should probably do the same when we'll add Android as target.
* See bgo#783862 for details. */
err =
gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexParamVideoAvc, &param);
if (err != OMX_ErrorNone) {
GST_WARNING_OBJECT (self,
"Getting OMX_IndexParamVideoAvc not supported by component");
return TRUE;
}
if (profile != OMX_VIDEO_AVCProfileMax)
param.eProfile = profile;
if (level != OMX_VIDEO_AVCLevelMax)
param.eLevel = level;
/* GOP pattern */
if (self->interval_intraframes !=
GST_OMX_H264_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT) {
param.nPFrames = self->interval_intraframes;
/* If user specified a specific number of B-frames, reduce the number of
* P-frames by this amount. If not ensure there is no B-frame to have the
* requested GOP length. */
if (self->b_frames != GST_OMX_H264_VIDEO_ENC_B_FRAMES_DEFAULT) {
if (self->b_frames > self->interval_intraframes) {
GST_ERROR_OBJECT (self,
"The interval_intraframes perdiod (%u) needs to be higher than the number of B-frames (%u)",
self->interval_intraframes, self->b_frames);
return FALSE;
}
param.nPFrames -= self->b_frames;
} else {
param.nBFrames = 0;
}
}
if (self->b_frames != GST_OMX_H264_VIDEO_ENC_B_FRAMES_DEFAULT) {
if (profile == OMX_VIDEO_AVCProfileBaseline && self->b_frames > 0) {
GST_ERROR_OBJECT (self,
"Baseline profile doesn't support B-frames (%u requested)",
self->b_frames);
return FALSE;
}
param.nBFrames = self->b_frames;
}
if (self->ref_frames != GST_OMX_H264_VIDEO_ENC_REF_FRAMES_DEFAULT)
param.nRefFrames = self->ref_frames;
if (self->entropy_mode != GST_OMX_H264_VIDEO_ENC_ENTROPY_MODE_DEFAULT) {
param.bEntropyCodingCABAC = self->entropy_mode;
}
param.bconstIpred = self->constrained_intra_prediction;
if (self->loop_filter_mode != GST_OMX_H264_VIDEO_ENC_LOOP_FILTER_MODE_DEFAULT) {
param.eLoopFilterMode = self->loop_filter_mode;
}
err =
gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexParamVideoAvc, &param);
if (err == OMX_ErrorUnsupportedIndex) {
GST_WARNING_OBJECT (self,
"Setting OMX_IndexParamVideoAvc not supported by component");
return TRUE;
} else if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Error setting AVC settings (profile %u and level %u): %s (0x%08x)",
(guint) param.eProfile, (guint) param.eLevel,
gst_omx_error_to_string (err), err);
return FALSE;
}
return TRUE;
}
static gboolean
set_avc_intra_period (GstOMXH264Enc * self)
{
OMX_VIDEO_CONFIG_AVCINTRAPERIOD config_avcintraperiod;
OMX_ERRORTYPE err;
GST_OMX_INIT_STRUCT (&config_avcintraperiod);
config_avcintraperiod.nPortIndex =
GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
err =
gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexConfigVideoAVCIntraPeriod, &config_avcintraperiod);
if (err == OMX_ErrorUnsupportedIndex) {
GST_WARNING_OBJECT (self,
"OMX_IndexConfigVideoAVCIntraPeriod not supported by component");
return TRUE;
} else if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"can't get OMX_IndexConfigVideoAVCIntraPeriod %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
GST_DEBUG_OBJECT (self, "default nPFrames:%u, nIDRPeriod:%u",
(guint) config_avcintraperiod.nPFrames,
(guint) config_avcintraperiod.nIDRPeriod);
if (self->periodicty_idr !=
GST_OMX_H264_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT) {
config_avcintraperiod.nIDRPeriod = self->periodicty_idr;
}
if (self->interval_intraframes !=
GST_OMX_H264_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT) {
/* This OMX API doesn't allow us to specify the number of B-frames.
* So if user requested one we have to rely on update_param_avc()
* to configure the intraframes interval so it can take the
* B-frames into account. */
if (self->b_frames == GST_OMX_H264_VIDEO_ENC_B_FRAMES_DEFAULT)
config_avcintraperiod.nPFrames = self->interval_intraframes;
}
err =
gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexConfigVideoAVCIntraPeriod, &config_avcintraperiod);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"can't set OMX_IndexConfigVideoAVCIntraPeriod %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
return TRUE;
}
#ifdef USE_OMX_TARGET_RPI
static gboolean
set_brcm_video_intra_period (GstOMXH264Enc * self)
{
OMX_PARAM_U32TYPE intra_period;
OMX_ERRORTYPE err;
GST_OMX_INIT_STRUCT (&intra_period);
intra_period.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
err =
gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexConfigBrcmVideoIntraPeriod, &intra_period);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"can't get OMX_IndexConfigBrcmVideoIntraPeriod %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
GST_DEBUG_OBJECT (self, "default OMX_IndexConfigBrcmVideoIntraPeriod: %u",
(guint) intra_period.nU32);
if (self->interval_intraframes ==
GST_OMX_H264_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT)
return TRUE;
intra_period.nU32 = self->interval_intraframes;
err =
gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexConfigBrcmVideoIntraPeriod, &intra_period);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"can't set OMX_IndexConfigBrcmVideoIntraPeriod %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
GST_DEBUG_OBJECT (self, "OMX_IndexConfigBrcmVideoIntraPeriod set to %u",
(guint) intra_period.nU32);
return TRUE;
}
#endif
static gboolean
gst_omx_h264_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port,
GstVideoCodecState * state)
{
GstOMXH264Enc *self = GST_OMX_H264_ENC (enc);
GstCaps *peercaps;
OMX_PARAM_PORTDEFINITIONTYPE port_def;
#ifdef USE_OMX_TARGET_RPI
OMX_CONFIG_PORTBOOLEANTYPE config_inline_header;
#endif
OMX_ERRORTYPE err;
const gchar *profile_string, *level_string;
OMX_VIDEO_AVCPROFILETYPE profile = OMX_VIDEO_AVCProfileMax;
OMX_VIDEO_AVCLEVELTYPE level = OMX_VIDEO_AVCLevelMax;
gboolean enable_subframe = FALSE;
#ifdef USE_OMX_TARGET_RPI
GST_OMX_INIT_STRUCT (&config_inline_header);
config_inline_header.nPortIndex =
GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
err =
gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexParamBrcmVideoAVCInlineHeaderEnable, &config_inline_header);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"can't get OMX_IndexParamBrcmVideoAVCInlineHeaderEnable %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
if (self->inline_sps_pps_headers) {
config_inline_header.bEnabled = OMX_TRUE;
} else {
config_inline_header.bEnabled = OMX_FALSE;
}
err =
gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexParamBrcmVideoAVCInlineHeaderEnable, &config_inline_header);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"can't set OMX_IndexParamBrcmVideoAVCInlineHeaderEnable %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
#endif
/* Configure GOP pattern */
if (self->periodicty_idr !=
GST_OMX_H264_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT
|| self->interval_intraframes !=
GST_OMX_H264_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT) {
set_avc_intra_period (self);
}
#ifdef USE_OMX_TARGET_RPI
/* The Pi uses a specific OMX setting to configure the intra period */
if (self->interval_intraframes)
set_brcm_video_intra_period (self);
#endif
gst_omx_port_get_port_definition (GST_OMX_VIDEO_ENC (self)->enc_out_port,
&port_def);
port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
err =
gst_omx_port_update_port_definition (GST_OMX_VIDEO_ENC
(self)->enc_out_port, &port_def);
if (err != OMX_ErrorNone)
return FALSE;
/* Set profile and level */
peercaps = gst_pad_peer_query_caps (GST_VIDEO_ENCODER_SRC_PAD (enc),
gst_pad_get_pad_template_caps (GST_VIDEO_ENCODER_SRC_PAD (enc)));
if (peercaps) {
GstStructure *s;
const gchar *alignment_string;
if (gst_caps_is_empty (peercaps)) {
gst_caps_unref (peercaps);
GST_ERROR_OBJECT (self, "Empty caps");
return FALSE;
}
s = gst_caps_get_structure (peercaps, 0);
profile_string = gst_structure_get_string (s, "profile");
if (profile_string) {
profile = gst_omx_h264_utils_get_profile_from_str (profile_string);
if (profile == OMX_VIDEO_AVCProfileMax)
goto unsupported_profile;
}
level_string = gst_structure_get_string (s, "level");
if (level_string) {
level = gst_omx_h264_utils_get_level_from_str (level_string);
if (level == OMX_VIDEO_AVCLevelMax)
goto unsupported_level;
}
alignment_string = gst_structure_get_string (s, "alignment");
if (alignment_string && g_str_equal (alignment_string, "nal"))
enable_subframe = TRUE;
gst_caps_unref (peercaps);
}
if (profile != OMX_VIDEO_AVCProfileMax || level != OMX_VIDEO_AVCLevelMax) {
/* OMX provides 2 API to set the profile and level. We try using the
* generic one here and the H264 specific when calling
* update_param_avc() */
if (!update_param_profile_level (self, profile, level))
return FALSE;
}
gst_omx_port_set_subframe (GST_OMX_VIDEO_ENC (self)->enc_out_port,
enable_subframe);
if (!update_param_avc (self, profile, level))
return FALSE;
return TRUE;
unsupported_profile:
GST_ERROR_OBJECT (self, "Unsupported profile %s", profile_string);
gst_caps_unref (peercaps);
return FALSE;
unsupported_level:
GST_ERROR_OBJECT (self, "Unsupported level %s", level_string);
gst_caps_unref (peercaps);
return FALSE;
}
static GstCaps *
gst_omx_h264_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port,
GstVideoCodecState * state)
{
GstOMXH264Enc *self = GST_OMX_H264_ENC (enc);
GstCaps *caps;
OMX_ERRORTYPE err;
OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
const gchar *profile, *level, *alignment;
GST_OMX_INIT_STRUCT (&param);
param.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
err =
gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexParamVideoProfileLevelCurrent, &param);
if (err != OMX_ErrorNone && err != OMX_ErrorUnsupportedIndex)
return NULL;
if (gst_omx_port_get_subframe (GST_OMX_VIDEO_ENC (self)->enc_out_port))
alignment = "nal";
else
alignment = "au";
caps = gst_caps_new_simple ("video/x-h264",
"stream-format", G_TYPE_STRING, "byte-stream",
"alignment", G_TYPE_STRING, alignment, NULL);
if (err == OMX_ErrorNone) {
profile = gst_omx_h264_utils_get_profile_from_enum (param.eProfile);
if (!profile) {
g_assert_not_reached ();
gst_caps_unref (caps);
return NULL;
}
switch (param.eLevel) {
case OMX_VIDEO_AVCLevel1:
level = "1";
break;
case OMX_VIDEO_AVCLevel1b:
level = "1b";
break;
case OMX_VIDEO_AVCLevel11:
level = "1.1";
break;
case OMX_VIDEO_AVCLevel12:
level = "1.2";
break;
case OMX_VIDEO_AVCLevel13:
level = "1.3";
break;
case OMX_VIDEO_AVCLevel2:
level = "2";
break;
case OMX_VIDEO_AVCLevel21:
level = "2.1";
break;
case OMX_VIDEO_AVCLevel22:
level = "2.2";
break;
case OMX_VIDEO_AVCLevel3:
level = "3";
break;
case OMX_VIDEO_AVCLevel31:
level = "3.1";
break;
case OMX_VIDEO_AVCLevel32:
level = "3.2";
break;
case OMX_VIDEO_AVCLevel4:
level = "4";
break;
case OMX_VIDEO_AVCLevel41:
level = "4.1";
break;
case OMX_VIDEO_AVCLevel42:
level = "4.2";
break;
case OMX_VIDEO_AVCLevel5:
level = "5";
break;
case OMX_VIDEO_AVCLevel51:
level = "5.1";
break;
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
case OMX_ALG_VIDEO_AVCLevel52:
level = "5.2";
break;
case OMX_ALG_VIDEO_AVCLevel60:
level = "6.0";
break;
case OMX_ALG_VIDEO_AVCLevel61:
level = "6.1";
break;
case OMX_ALG_VIDEO_AVCLevel62:
level = "6.2";
break;
#endif
default:
g_assert_not_reached ();
gst_caps_unref (caps);
return NULL;
}
gst_caps_set_simple (caps,
"profile", G_TYPE_STRING, profile, "level", G_TYPE_STRING, level, NULL);
}
return caps;
}
static GstFlowReturn
gst_omx_h264_enc_handle_output_frame (GstOMXVideoEnc * enc, GstOMXPort * port,
GstOMXBuffer * buf, GstVideoCodecFrame * frame)
{
GstOMXH264Enc *self = GST_OMX_H264_ENC (enc);
if (buf->omx_buf->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
/* The codec data is SPS/PPS but our output is stream-format=byte-stream.
* For bytestream stream format the SPS/PPS is only in-stream and not
* in the caps!
*/
GstBuffer *hdrs;
GstMapInfo map = GST_MAP_INFO_INIT;
GstFlowReturn flow_ret;
GST_DEBUG_OBJECT (self, "got codecconfig in byte-stream format");
hdrs = gst_buffer_new_and_alloc (buf->omx_buf->nFilledLen);
GST_BUFFER_FLAG_SET (hdrs, GST_BUFFER_FLAG_HEADER);
gst_buffer_map (hdrs, &map, GST_MAP_WRITE);
memcpy (map.data,
buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
buf->omx_buf->nFilledLen);
gst_buffer_unmap (hdrs, &map);
self->headers = g_list_append (self->headers, gst_buffer_ref (hdrs));
frame->output_buffer = hdrs;
flow_ret =
gst_video_encoder_finish_subframe (GST_VIDEO_ENCODER (self), frame);
gst_video_codec_frame_unref (frame);
return flow_ret;
} else if (self->headers) {
gst_video_encoder_set_headers (GST_VIDEO_ENCODER (self), self->headers);
self->headers = NULL;
}
return
GST_OMX_VIDEO_ENC_CLASS
(gst_omx_h264_enc_parent_class)->handle_output_frame (enc, port, buf,
frame);
}

73
omx/gstomxh264enc.h Normal file
View file

@ -0,0 +1,73 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_H264_ENC_H__
#define __GST_OMX_H264_ENC_H__
#include <gst/gst.h>
#include "gstomxvideoenc.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_H264_ENC \
(gst_omx_h264_enc_get_type())
#define GST_OMX_H264_ENC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_H264_ENC,GstOMXH264Enc))
#define GST_OMX_H264_ENC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_H264_ENC,GstOMXH264EncClass))
#define GST_OMX_H264_ENC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_H264_ENC,GstOMXH264EncClass))
#define GST_IS_OMX_H264_ENC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_H264_ENC))
#define GST_IS_OMX_H264_ENC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_H264_ENC))
typedef struct _GstOMXH264Enc GstOMXH264Enc;
typedef struct _GstOMXH264EncClass GstOMXH264EncClass;
struct _GstOMXH264Enc
{
GstOMXVideoEnc parent;
#ifdef USE_OMX_TARGET_RPI
gboolean inline_sps_pps_headers;
#endif
guint32 periodicty_idr;
guint32 interval_intraframes;
guint32 b_frames;
guint32 entropy_mode;
gboolean constrained_intra_prediction;
guint32 loop_filter_mode;
guint8 ref_frames;
GList *headers;
};
struct _GstOMXH264EncClass
{
GstOMXVideoEncClass parent_class;
};
GType gst_omx_h264_enc_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_H264_ENC_H__ */

131
omx/gstomxh264utils.c Normal file
View file

@ -0,0 +1,131 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstomxh264utils.h"
typedef struct
{
const gchar *profile;
OMX_VIDEO_AVCPROFILETYPE e;
} H264ProfileMapping;
static const H264ProfileMapping h264_profiles[] = {
{"baseline", OMX_VIDEO_AVCProfileBaseline},
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
{"constrained-baseline",
(OMX_VIDEO_AVCPROFILETYPE) OMX_ALG_VIDEO_AVCProfileConstrainedBaseline},
#else
{"constrained-baseline", OMX_VIDEO_AVCProfileBaseline},
#endif
{"main", OMX_VIDEO_AVCProfileMain},
{"high", OMX_VIDEO_AVCProfileHigh},
{"high-10", OMX_VIDEO_AVCProfileHigh10},
{"high-4:2:2", OMX_VIDEO_AVCProfileHigh422},
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
{"progressive-high",
(OMX_VIDEO_AVCPROFILETYPE) OMX_ALG_VIDEO_AVCProfileProgressiveHigh},
{"constrained-high",
(OMX_VIDEO_AVCPROFILETYPE) OMX_ALG_VIDEO_AVCProfileConstrainedHigh},
{"high-10-intra",
(OMX_VIDEO_AVCPROFILETYPE) OMX_ALG_VIDEO_AVCProfileHigh10_Intra},
{"high-4:2:2-intra",
(OMX_VIDEO_AVCPROFILETYPE) OMX_ALG_VIDEO_AVCProfileHigh422_Intra},
#endif
};
OMX_VIDEO_AVCPROFILETYPE
gst_omx_h264_utils_get_profile_from_str (const gchar * profile)
{
guint i;
for (i = 0; i < G_N_ELEMENTS (h264_profiles); i++) {
if (g_str_equal (profile, h264_profiles[i].profile))
return h264_profiles[i].e;
}
return OMX_VIDEO_AVCProfileMax;
}
const gchar *
gst_omx_h264_utils_get_profile_from_enum (OMX_VIDEO_AVCPROFILETYPE e)
{
guint i;
for (i = 0; i < G_N_ELEMENTS (h264_profiles); i++) {
if (e == h264_profiles[i].e)
return h264_profiles[i].profile;
}
return NULL;
}
OMX_VIDEO_AVCLEVELTYPE
gst_omx_h264_utils_get_level_from_str (const gchar * level)
{
if (g_str_equal (level, "1")) {
return OMX_VIDEO_AVCLevel1;
} else if (g_str_equal (level, "1b")) {
return OMX_VIDEO_AVCLevel1b;
} else if (g_str_equal (level, "1.1")) {
return OMX_VIDEO_AVCLevel11;
} else if (g_str_equal (level, "1.2")) {
return OMX_VIDEO_AVCLevel12;
} else if (g_str_equal (level, "1.3")) {
return OMX_VIDEO_AVCLevel13;
} else if (g_str_equal (level, "2")) {
return OMX_VIDEO_AVCLevel2;
} else if (g_str_equal (level, "2.1")) {
return OMX_VIDEO_AVCLevel21;
} else if (g_str_equal (level, "2.2")) {
return OMX_VIDEO_AVCLevel22;
} else if (g_str_equal (level, "3")) {
return OMX_VIDEO_AVCLevel3;
} else if (g_str_equal (level, "3.1")) {
return OMX_VIDEO_AVCLevel31;
} else if (g_str_equal (level, "3.2")) {
return OMX_VIDEO_AVCLevel32;
} else if (g_str_equal (level, "4")) {
return OMX_VIDEO_AVCLevel4;
} else if (g_str_equal (level, "4.1")) {
return OMX_VIDEO_AVCLevel41;
} else if (g_str_equal (level, "4.2")) {
return OMX_VIDEO_AVCLevel42;
} else if (g_str_equal (level, "5")) {
return OMX_VIDEO_AVCLevel5;
} else if (g_str_equal (level, "5.1")) {
return OMX_VIDEO_AVCLevel51;
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
} else if (g_str_equal (level, "5.2")) {
return (OMX_VIDEO_AVCLEVELTYPE) OMX_ALG_VIDEO_AVCLevel52;
} else if (g_str_equal (level, "6.0")) {
return (OMX_VIDEO_AVCLEVELTYPE) OMX_ALG_VIDEO_AVCLevel60;
} else if (g_str_equal (level, "6.1")) {
return (OMX_VIDEO_AVCLEVELTYPE) OMX_ALG_VIDEO_AVCLevel61;
} else if (g_str_equal (level, "6.2")) {
return (OMX_VIDEO_AVCLEVELTYPE) OMX_ALG_VIDEO_AVCLevel62;
#endif
}
return OMX_VIDEO_AVCLevelMax;
}

36
omx/gstomxh264utils.h Normal file
View file

@ -0,0 +1,36 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_H264_UTILS_H__
#define __GST_OMX_H264_UTILS_H__
#include "gstomx.h"
G_BEGIN_DECLS
OMX_VIDEO_AVCPROFILETYPE gst_omx_h264_utils_get_profile_from_str (const
gchar * profile);
OMX_VIDEO_AVCLEVELTYPE gst_omx_h264_utils_get_level_from_str (const gchar *
level);
const gchar * gst_omx_h264_utils_get_profile_from_enum (OMX_VIDEO_AVCPROFILETYPE e);
G_END_DECLS
#endif /* __GST_OMX_H264_UTILS_H__ */

224
omx/gstomxh265dec.c Normal file
View file

@ -0,0 +1,224 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Copyright (C) 2017 Xilinx, Inc.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxh265dec.h"
#include "gstomxh265utils.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_h265_dec_debug_category);
#define GST_CAT_DEFAULT gst_omx_h265_dec_debug_category
/* prototypes */
static gboolean gst_omx_h265_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
static gboolean gst_omx_h265_dec_set_format (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
enum
{
PROP_0
};
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_h265_dec_debug_category, "omxh265dec", 0, \
"debug category for gst-omx H265 video decoder");
G_DEFINE_TYPE_WITH_CODE (GstOMXH265Dec, gst_omx_h265_dec,
GST_TYPE_OMX_VIDEO_DEC, DEBUG_INIT);
#define MAKE_CAPS(alignment) \
"video/x-h265, " \
"alignment=(string) " alignment ", " \
"stream-format=(string) byte-stream, " \
"width=(int) [1,MAX], height=(int) [1,MAX]"
/* The Zynq MPSoC supports decoding subframes though we want "au" to be the
* default, so we keep it prepended. This is the only way that it works with
* rtph265depay. */
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
#define SINK_CAPS MAKE_CAPS ("au") ";" MAKE_CAPS ("nal");
#else
#define SINK_CAPS MAKE_CAPS ("au")
#endif
static void
gst_omx_h265_dec_class_init (GstOMXH265DecClass * klass)
{
GstOMXVideoDecClass *videodec_class = GST_OMX_VIDEO_DEC_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
videodec_class->is_format_change =
GST_DEBUG_FUNCPTR (gst_omx_h265_dec_is_format_change);
videodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_h265_dec_set_format);
videodec_class->cdata.default_sink_template_caps = SINK_CAPS;
gst_element_class_set_static_metadata (element_class,
"OpenMAX H.265 Video Decoder",
"Codec/Decoder/Video/Hardware",
"Decode H.265 video streams",
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
gst_omx_set_default_role (&videodec_class->cdata, "video_decoder.hevc");
}
static void
gst_omx_h265_dec_init (GstOMXH265Dec * self)
{
}
static gboolean
gst_omx_h265_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state)
{
GstCaps *old_caps = NULL;
GstCaps *new_caps = state->caps;
GstStructure *old_structure, *new_structure;
const gchar *old_profile, *old_level, *old_tier, *old_alignment,
*new_profile, *new_level, *new_tier, *new_alignment;
if (dec->input_state) {
old_caps = dec->input_state->caps;
}
if (!old_caps) {
return FALSE;
}
old_structure = gst_caps_get_structure (old_caps, 0);
new_structure = gst_caps_get_structure (new_caps, 0);
old_profile = gst_structure_get_string (old_structure, "profile");
old_level = gst_structure_get_string (old_structure, "level");
old_tier = gst_structure_get_string (old_structure, "tier");
old_alignment = gst_structure_get_string (old_structure, "alignment");
new_profile = gst_structure_get_string (new_structure, "profile");
new_level = gst_structure_get_string (new_structure, "level");
new_tier = gst_structure_get_string (new_structure, "tier");
new_alignment = gst_structure_get_string (new_structure, "alignment");
if (g_strcmp0 (old_profile, new_profile) != 0
|| g_strcmp0 (old_level, new_level) != 0
|| g_strcmp0 (old_tier, new_tier) != 0
|| g_strcmp0 (old_alignment, new_alignment) != 0) {
return TRUE;
}
return FALSE;
}
static gboolean
set_profile_and_level (GstOMXH265Dec * self, GstVideoCodecState * state)
{
OMX_ERRORTYPE err;
OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
const gchar *profile_string, *level_string, *tier_string;
GstStructure *s;
GST_OMX_INIT_STRUCT (&param);
param.nPortIndex = GST_OMX_VIDEO_DEC (self)->dec_in_port->index;
/* Pass profile, level and tier to the decoder if we have all info from the
* caps. */
s = gst_caps_get_structure (state->caps, 0);
profile_string = gst_structure_get_string (s, "profile");
if (!profile_string)
return TRUE;
param.eProfile = gst_omx_h265_utils_get_profile_from_str (profile_string);
if (param.eProfile == OMX_VIDEO_HEVCProfileUnknown)
goto unsupported_profile;
level_string = gst_structure_get_string (s, "level");
tier_string = gst_structure_get_string (s, "tier");
if (!level_string || !tier_string)
return TRUE;
param.eLevel =
gst_omx_h265_utils_get_level_from_str (level_string, tier_string);
if (param.eLevel == OMX_VIDEO_HEVCLevelUnknown)
goto unsupported_level;
GST_DEBUG_OBJECT (self,
"Set profile (%s) level (%s) and tier (%s) on decoder", profile_string,
level_string, tier_string);
err =
gst_omx_component_set_parameter (GST_OMX_VIDEO_DEC (self)->dec,
OMX_IndexParamVideoProfileLevelCurrent, &param);
if (err == OMX_ErrorUnsupportedIndex) {
GST_WARNING_OBJECT (self,
"Setting profile/level not supported by component");
} else if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Error setting profile %u and level %u: %s (0x%08x)",
(guint) param.eProfile, (guint) param.eLevel,
gst_omx_error_to_string (err), err);
return FALSE;
}
return TRUE;
unsupported_profile:
GST_ERROR_OBJECT (self, "Unsupported profile %s", profile_string);
return FALSE;
unsupported_level:
GST_ERROR_OBJECT (self, "Unsupported level %s", level_string);
return FALSE;
}
static gboolean
gst_omx_h265_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port,
GstVideoCodecState * state)
{
GstOMXVideoDecClass *klass = GST_OMX_VIDEO_DEC_GET_CLASS (dec);
OMX_PARAM_PORTDEFINITIONTYPE port_def;
OMX_ERRORTYPE err;
const GstStructure *s;
gst_omx_port_get_port_definition (port, &port_def);
port_def.format.video.eCompressionFormat =
(OMX_VIDEO_CODINGTYPE) OMX_VIDEO_CodingHEVC;
err = gst_omx_port_update_port_definition (port, &port_def);
if (err != OMX_ErrorNone)
return FALSE;
if (klass->cdata.hacks & GST_OMX_HACK_PASS_PROFILE_TO_DECODER) {
if (!set_profile_and_level (GST_OMX_H265_DEC (dec), state))
return FALSE;
}
/* Enable subframe mode if NAL aligned */
s = gst_caps_get_structure (state->caps, 0);
if (!g_strcmp0 (gst_structure_get_string (s, "alignment"), "nal")
&& gst_omx_port_set_subframe (dec->dec_in_port, TRUE)) {
gst_video_decoder_set_subframe_mode (GST_VIDEO_DECODER (dec), TRUE);
}
return TRUE;
}

61
omx/gstomxh265dec.h Normal file
View file

@ -0,0 +1,61 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Copyright (C) 2017 Xilinx, Inc.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_H265_DEC_H__
#define __GST_OMX_H265_DEC_H__
#include <gst/gst.h>
#include "gstomxvideodec.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_H265_DEC \
(gst_omx_h265_dec_get_type())
#define GST_OMX_H265_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_H265_DEC,GstOMXH265Dec))
#define GST_OMX_H265_DEC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_H265_DEC,GstOMXH265DecClass))
#define GST_OMX_H265_DEC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_H265_DEC,GstOMXH265DecClass))
#define GST_IS_OMX_H265_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_H265_DEC))
#define GST_IS_OMX_H265_DEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_H265_DEC))
typedef struct _GstOMXH265Dec GstOMXH265Dec;
typedef struct _GstOMXH265DecClass GstOMXH265DecClass;
struct _GstOMXH265Dec
{
GstOMXVideoDec parent;
};
struct _GstOMXH265DecClass
{
GstOMXVideoDecClass parent_class;
};
GType gst_omx_h265_dec_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_H265_DEC_H__ */

748
omx/gstomxh265enc.c Normal file
View file

@ -0,0 +1,748 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Copyright (C) 2017 Xilinx, Inc.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxh265enc.h"
#include "gstomxh265utils.h"
#include "gstomxvideo.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_h265_enc_debug_category);
#define GST_CAT_DEFAULT gst_omx_h265_enc_debug_category
/* prototypes */
static gboolean gst_omx_h265_enc_set_format (GstOMXVideoEnc * enc,
GstOMXPort * port, GstVideoCodecState * state);
static GstCaps *gst_omx_h265_enc_get_caps (GstOMXVideoEnc * enc,
GstOMXPort * port, GstVideoCodecState * state);
static void gst_omx_h265_enc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_omx_h265_enc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstFlowReturn gst_omx_h265_enc_handle_output_frame (GstOMXVideoEnc *
self, GstOMXPort * port, GstOMXBuffer * buf, GstVideoCodecFrame * frame);
enum
{
PROP_0,
PROP_PERIODICITYOFIDRFRAMES,
PROP_INTERVALOFCODINGINTRAFRAMES,
PROP_B_FRAMES,
PROP_CONSTRAINED_INTRA_PREDICTION,
PROP_LOOP_FILTER_MODE,
};
#define GST_OMX_H265_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT (0xffffffff)
#define GST_OMX_H265_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT (0xffffffff)
#define GST_OMX_H265_VIDEO_ENC_B_FRAMES_DEFAULT (0xffffffff)
#define GST_OMX_H265_VIDEO_ENC_CONSTRAINED_INTRA_PREDICTION_DEFAULT (FALSE)
#define GST_OMX_H265_VIDEO_ENC_LOOP_FILTER_MODE_DEFAULT (0xffffffff)
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
/* zynqultrascaleplus's OMX uses a param struct different of Android's one */
#define INDEX_PARAM_VIDEO_HEVC OMX_ALG_IndexParamVideoHevc
#define ALIGNMENT "{ au, nal }"
#else
#define INDEX_PARAM_VIDEO_HEVC OMX_IndexParamVideoHevc
#define ALIGNMENT "au"
#endif
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_h265_enc_debug_category, "omxh265enc", 0, \
"debug category for gst-omx H265 video encoder");
#define parent_class gst_omx_h265_enc_parent_class
G_DEFINE_TYPE_WITH_CODE (GstOMXH265Enc, gst_omx_h265_enc,
GST_TYPE_OMX_VIDEO_ENC, DEBUG_INIT);
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
#define GST_TYPE_OMX_H265_ENC_LOOP_FILTER_MODE (gst_omx_h265_enc_loop_filter_mode_get_type ())
static GType
gst_omx_h265_enc_loop_filter_mode_get_type (void)
{
static GType qtype = 0;
if (qtype == 0) {
static const GEnumValue values[] = {
{OMX_ALG_VIDEO_HEVCLoopFilterEnable, "Enable deblocking filter",
"enable"},
{OMX_ALG_VIDEO_HEVCLoopFilterDisable, "Disable deblocking filter",
"disable"},
{OMX_ALG_VIDEO_HEVCLoopFilterDisableCrossSlice,
"Disable deblocking filter on slice boundary", "disable-cross-slice"},
{OMX_ALG_VIDEO_HEVCLoopFilterDisableCrossTile,
"Disable deblocking filter on tile boundary", "disable-cross-tile"},
{OMX_ALG_VIDEO_HEVCLoopFilterDisableCrossSliceAndTile,
"Disable deblocking filter on slice and tile boundary",
"disable-slice-and-tile"},
{0xffffffff, "Component Default", "default"},
{0, NULL, NULL}
};
qtype = g_enum_register_static ("GstOMXH265EncLoopFilter", values);
}
return qtype;
}
#endif
static gboolean
gst_omx_h265_enc_flush (GstVideoEncoder * enc)
{
GstOMXH265Enc *self = GST_OMX_H265_ENC (enc);
g_list_free_full (self->headers, (GDestroyNotify) gst_buffer_unref);
self->headers = NULL;
return GST_VIDEO_ENCODER_CLASS (parent_class)->flush (enc);
}
static gboolean
gst_omx_h265_enc_stop (GstVideoEncoder * enc)
{
GstOMXH265Enc *self = GST_OMX_H265_ENC (enc);
g_list_free_full (self->headers, (GDestroyNotify) gst_buffer_unref);
self->headers = NULL;
return GST_VIDEO_ENCODER_CLASS (parent_class)->stop (enc);
}
static void
gst_omx_h265_enc_class_init (GstOMXH265EncClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstVideoEncoderClass *basevideoenc_class = GST_VIDEO_ENCODER_CLASS (klass);
GstOMXVideoEncClass *videoenc_class = GST_OMX_VIDEO_ENC_CLASS (klass);
videoenc_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_h265_enc_set_format);
videoenc_class->get_caps = GST_DEBUG_FUNCPTR (gst_omx_h265_enc_get_caps);
videoenc_class->handle_output_frame =
GST_DEBUG_FUNCPTR (gst_omx_h265_enc_handle_output_frame);
basevideoenc_class->flush = gst_omx_h265_enc_flush;
basevideoenc_class->stop = gst_omx_h265_enc_stop;
gobject_class->set_property = gst_omx_h265_enc_set_property;
gobject_class->get_property = gst_omx_h265_enc_get_property;
g_object_class_install_property (gobject_class,
PROP_INTERVALOFCODINGINTRAFRAMES,
g_param_spec_uint ("interval-intraframes",
"Interval of coding Intra frames",
"Interval of coding Intra frames (0xffffffff=component default)", 0,
G_MAXUINT,
GST_OMX_H265_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
g_object_class_install_property (gobject_class, PROP_PERIODICITYOFIDRFRAMES,
g_param_spec_uint ("periodicity-idr", "IDR periodicity",
"Periodicity of IDR frames (0xffffffff=component default)",
0, G_MAXUINT,
GST_OMX_H265_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
g_object_class_install_property (gobject_class, PROP_B_FRAMES,
g_param_spec_uint ("b-frames", "Number of B-frames",
"Number of B-frames between two consecutive I-frames (0xffffffff=component default)",
0, G_MAXUINT, GST_OMX_H265_VIDEO_ENC_B_FRAMES_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
g_object_class_install_property (gobject_class,
PROP_CONSTRAINED_INTRA_PREDICTION,
g_param_spec_boolean ("constrained-intra-prediction",
"Constrained Intra Prediction",
"If enabled, prediction only uses residual data and decoded samples "
"from neighbouring coding blocks coded using intra prediction modes",
GST_OMX_H265_VIDEO_ENC_CONSTRAINED_INTRA_PREDICTION_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
g_object_class_install_property (gobject_class, PROP_LOOP_FILTER_MODE,
g_param_spec_enum ("loop-filter-mode", "Loop Filter mode",
"Enable or disable the deblocking filter (0xffffffff=component default)",
GST_TYPE_OMX_H265_ENC_LOOP_FILTER_MODE,
GST_OMX_H265_VIDEO_ENC_LOOP_FILTER_MODE_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
#endif
videoenc_class->cdata.default_sink_template_caps =
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_FORMAT_INTERLACED,
GST_OMX_VIDEO_ENC_SUPPORTED_FORMATS)
", interlace-mode = (string) alternate ; "
#endif
GST_VIDEO_CAPS_MAKE (GST_OMX_VIDEO_ENC_SUPPORTED_FORMATS);
videoenc_class->cdata.default_src_template_caps = "video/x-h265, "
"width=(int) [ 1, MAX ], " "height=(int) [ 1, MAX ], "
"framerate = (fraction) [0, MAX], stream-format=(string) byte-stream, "
"aligmment = (string) " ALIGNMENT;
gst_element_class_set_static_metadata (element_class,
"OpenMAX H.265 Video Encoder",
"Codec/Encoder/Video/Hardware",
"Encode H.265 video streams",
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
gst_omx_set_default_role (&videoenc_class->cdata, "video_encoder.hevc");
}
static void
gst_omx_h265_enc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstOMXH265Enc *self = GST_OMX_H265_ENC (object);
switch (prop_id) {
case PROP_INTERVALOFCODINGINTRAFRAMES:
self->interval_intraframes = g_value_get_uint (value);
break;
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
case PROP_PERIODICITYOFIDRFRAMES:
self->periodicity_idr = g_value_get_uint (value);
break;
case PROP_B_FRAMES:
self->b_frames = g_value_get_uint (value);
break;
case PROP_CONSTRAINED_INTRA_PREDICTION:
self->constrained_intra_prediction = g_value_get_boolean (value);
break;
case PROP_LOOP_FILTER_MODE:
self->loop_filter_mode = g_value_get_enum (value);
break;
#endif
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_omx_h265_enc_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstOMXH265Enc *self = GST_OMX_H265_ENC (object);
switch (prop_id) {
case PROP_INTERVALOFCODINGINTRAFRAMES:
g_value_set_uint (value, self->interval_intraframes);
break;
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
case PROP_PERIODICITYOFIDRFRAMES:
g_value_set_uint (value, self->periodicity_idr);
break;
case PROP_B_FRAMES:
g_value_set_uint (value, self->b_frames);
break;
case PROP_CONSTRAINED_INTRA_PREDICTION:
g_value_set_boolean (value, self->constrained_intra_prediction);
break;
case PROP_LOOP_FILTER_MODE:
g_value_set_enum (value, self->loop_filter_mode);
break;
#endif
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_omx_h265_enc_init (GstOMXH265Enc * self)
{
self->interval_intraframes =
GST_OMX_H265_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT;
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
self->periodicity_idr =
GST_OMX_H265_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT;
self->b_frames = GST_OMX_H265_VIDEO_ENC_B_FRAMES_DEFAULT;
self->constrained_intra_prediction =
GST_OMX_H265_VIDEO_ENC_CONSTRAINED_INTRA_PREDICTION_DEFAULT;
self->loop_filter_mode = GST_OMX_H265_VIDEO_ENC_LOOP_FILTER_MODE_DEFAULT;
#endif
}
/* Update OMX_VIDEO_PARAM_PROFILELEVELTYPE.{eProfile,eLevel}
*
* Returns TRUE if succeeded or if not supported, FALSE if failed */
static gboolean
update_param_profile_level (GstOMXH265Enc * self,
OMX_VIDEO_HEVCPROFILETYPE profile, OMX_VIDEO_HEVCLEVELTYPE level)
{
OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
OMX_ERRORTYPE err;
GST_OMX_INIT_STRUCT (&param);
param.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
err =
gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexParamVideoProfileLevelCurrent, &param);
if (err != OMX_ErrorNone) {
GST_WARNING_OBJECT (self,
"Getting OMX_IndexParamVideoProfileLevelCurrent not supported by component");
return TRUE;
}
if (profile != OMX_VIDEO_HEVCProfileUnknown)
param.eProfile = profile;
if (level != OMX_VIDEO_HEVCLevelUnknown)
param.eLevel = level;
err =
gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexParamVideoProfileLevelCurrent, &param);
if (err == OMX_ErrorUnsupportedIndex) {
GST_WARNING_OBJECT (self,
"Setting OMX_IndexParamVideoProfileLevelCurrent not supported by component");
return TRUE;
} else if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Error setting profile %u and level %u: %s (0x%08x)",
(guint) param.eProfile, (guint) param.eLevel,
gst_omx_error_to_string (err), err);
return FALSE;
}
return TRUE;
}
/* Update OMX_ALG_VIDEO_PARAM_HEVCTYPE
*
* Returns TRUE if succeeded or if not supported, FALSE if failed */
static gboolean
update_param_hevc (GstOMXH265Enc * self,
OMX_VIDEO_HEVCPROFILETYPE profile, OMX_VIDEO_HEVCLEVELTYPE level)
{
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
OMX_ALG_VIDEO_PARAM_HEVCTYPE param;
#else
OMX_VIDEO_PARAM_HEVCTYPE param;
#endif
OMX_ERRORTYPE err;
GST_OMX_INIT_STRUCT (&param);
param.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
/* On Android the param struct is initialized manually with default
* settings rather than using GetParameter() to retrieve them.
* We should probably do the same when we'll add Android as target.
* See bgo#783862 for details. */
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
param.bConstIpred = self->constrained_intra_prediction;
if (self->loop_filter_mode != GST_OMX_H265_VIDEO_ENC_LOOP_FILTER_MODE_DEFAULT)
param.eLoopFilterMode = self->loop_filter_mode;
err =
gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
(OMX_INDEXTYPE) OMX_ALG_IndexParamVideoHevc, &param);
#else
err =
gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
(OMX_INDEXTYPE) OMX_IndexParamVideoHevc, &param);
#endif
if (err != OMX_ErrorNone) {
GST_WARNING_OBJECT (self,
"Getting OMX_ALG_IndexParamVideoHevc not supported by component");
return TRUE;
}
if (profile != OMX_VIDEO_HEVCProfileUnknown)
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
param.eProfile = (OMX_ALG_VIDEO_HEVCPROFILETYPE) profile;
#else
param.eProfile = profile;
#endif
if (level != OMX_VIDEO_HEVCLevelUnknown)
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
param.eLevel = (OMX_ALG_VIDEO_HEVCLEVELTYPE) level;
#else
param.eLevel = level;
#endif
/* GOP pattern */
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
/* The zynqultrascaleplus uses another PARAM_HEVCTYPE API allowing users to
* define the number of P and B frames while Android's API only expose the
* former. */
if (self->interval_intraframes !=
GST_OMX_H265_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT) {
param.nPFrames = self->interval_intraframes;
/* If user specified a specific number of B-frames, reduce the number of
* P-frames by this amount. If not ensure there is no B-frame to have the
* requested GOP length. */
if (self->b_frames != GST_OMX_H265_VIDEO_ENC_B_FRAMES_DEFAULT) {
if (self->b_frames > self->interval_intraframes) {
GST_ERROR_OBJECT (self,
"The interval_intraframes perdiod (%u) needs to be higher than the number of B-frames (%u)",
self->interval_intraframes, self->b_frames);
return FALSE;
}
param.nPFrames -= self->b_frames;
} else {
param.nBFrames = 0;
}
}
if (self->b_frames != GST_OMX_H265_VIDEO_ENC_B_FRAMES_DEFAULT)
param.nBFrames = self->b_frames;
#else
if (self->interval_intraframes !=
GST_OMX_H265_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT)
param.nKeyFrameInterval = self->interval_intraframes;
#endif
err =
gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
(OMX_INDEXTYPE) INDEX_PARAM_VIDEO_HEVC, &param);
if (err == OMX_ErrorUnsupportedIndex) {
GST_WARNING_OBJECT (self,
"Setting IndexParamVideoHevc not supported by component");
return TRUE;
} else if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Error setting HEVC settings (profile %u and level %u): %s (0x%08x)",
(guint) param.eProfile, (guint) param.eLevel,
gst_omx_error_to_string (err), err);
return FALSE;
}
return TRUE;
}
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
static gboolean
set_intra_period (GstOMXH265Enc * self)
{
OMX_ALG_VIDEO_PARAM_INSTANTANEOUS_DECODING_REFRESH config_idr;
OMX_ERRORTYPE err;
GST_OMX_INIT_STRUCT (&config_idr);
config_idr.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
GST_DEBUG_OBJECT (self, "nIDRPeriod:%u",
(guint) config_idr.nInstantaneousDecodingRefreshFrequency);
config_idr.nInstantaneousDecodingRefreshFrequency = self->periodicity_idr;
err =
gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
(OMX_INDEXTYPE) OMX_ALG_IndexParamVideoInstantaneousDecodingRefresh,
&config_idr);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"can't set OMX_IndexConfigVideoAVCIntraPeriod %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
return TRUE;
}
#endif
static gboolean
gst_omx_h265_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port,
GstVideoCodecState * state)
{
GstOMXH265Enc *self = GST_OMX_H265_ENC (enc);
GstCaps *peercaps;
OMX_PARAM_PORTDEFINITIONTYPE port_def;
OMX_ERRORTYPE err;
const gchar *profile_string, *level_string, *tier_string;
OMX_VIDEO_HEVCPROFILETYPE profile = OMX_VIDEO_HEVCProfileUnknown;
OMX_VIDEO_HEVCLEVELTYPE level = OMX_VIDEO_HEVCLevelUnknown;
gboolean enable_subframe = FALSE;
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
if (self->periodicity_idr !=
GST_OMX_H265_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT)
set_intra_period (self);
#endif
gst_omx_port_get_port_definition (GST_OMX_VIDEO_ENC (self)->enc_out_port,
&port_def);
port_def.format.video.eCompressionFormat =
(OMX_VIDEO_CODINGTYPE) OMX_VIDEO_CodingHEVC;
err =
gst_omx_port_update_port_definition (GST_OMX_VIDEO_ENC
(self)->enc_out_port, &port_def);
if (err != OMX_ErrorNone)
return FALSE;
/* Set profile and level */
peercaps = gst_pad_peer_query_caps (GST_VIDEO_ENCODER_SRC_PAD (enc),
gst_pad_get_pad_template_caps (GST_VIDEO_ENCODER_SRC_PAD (enc)));
if (peercaps) {
GstStructure *s;
const gchar *alignment_string;
if (gst_caps_is_empty (peercaps)) {
gst_caps_unref (peercaps);
GST_ERROR_OBJECT (self, "Empty caps");
return FALSE;
}
s = gst_caps_get_structure (peercaps, 0);
profile_string = gst_structure_get_string (s, "profile");
if (profile_string) {
profile = gst_omx_h265_utils_get_profile_from_str (profile_string);
if (profile == OMX_VIDEO_HEVCProfileUnknown)
goto unsupported_profile;
}
level_string = gst_structure_get_string (s, "level");
tier_string = gst_structure_get_string (s, "tier");
if (level_string && tier_string) {
level = gst_omx_h265_utils_get_level_from_str (level_string, tier_string);
if (level == OMX_VIDEO_HEVCLevelUnknown)
goto unsupported_level;
}
alignment_string = gst_structure_get_string (s, "alignment");
if (alignment_string && g_str_equal (alignment_string, "nal"))
enable_subframe = TRUE;
gst_caps_unref (peercaps);
}
if (profile != OMX_VIDEO_HEVCProfileUnknown
|| level != OMX_VIDEO_HEVCLevelUnknown) {
/* OMX provides 2 API to set the profile and level. We try using the
* generic one here and the H265 specific when calling
* update_param_hevc() */
if (!update_param_profile_level (self, profile, level))
return FALSE;
}
if (!update_param_hevc (self, profile, level))
return FALSE;
gst_omx_port_set_subframe (GST_OMX_VIDEO_ENC (self)->enc_out_port,
enable_subframe);
return TRUE;
unsupported_profile:
GST_ERROR_OBJECT (self, "Unsupported profile %s", profile_string);
gst_caps_unref (peercaps);
return FALSE;
unsupported_level:
GST_ERROR_OBJECT (self, "Unsupported level %s", level_string);
gst_caps_unref (peercaps);
return FALSE;
}
static GstCaps *
gst_omx_h265_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port,
GstVideoCodecState * state)
{
GstOMXH265Enc *self = GST_OMX_H265_ENC (enc);
GstCaps *caps;
OMX_ERRORTYPE err;
OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
const gchar *profile, *level, *tier, *alignment;
GST_OMX_INIT_STRUCT (&param);
param.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
err =
gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexParamVideoProfileLevelCurrent, &param);
if (err != OMX_ErrorNone && err != OMX_ErrorUnsupportedIndex)
return NULL;
if (gst_omx_port_get_subframe (GST_OMX_VIDEO_ENC (self)->enc_out_port))
alignment = "nal";
else
alignment = "au";
caps = gst_caps_new_simple ("video/x-h265",
"stream-format", G_TYPE_STRING, "byte-stream",
"alignment", G_TYPE_STRING, alignment, NULL);
if (err == OMX_ErrorNone) {
profile = gst_omx_h265_utils_get_profile_from_enum (param.eProfile);
if (!profile) {
g_assert_not_reached ();
gst_caps_unref (caps);
return NULL;
}
switch (param.eLevel) {
case OMX_VIDEO_HEVCMainTierLevel1:
tier = "main";
level = "1";
break;
case OMX_VIDEO_HEVCMainTierLevel2:
tier = "main";
level = "2";
break;
case OMX_VIDEO_HEVCMainTierLevel21:
tier = "main";
level = "2.1";
break;
case OMX_VIDEO_HEVCMainTierLevel3:
tier = "main";
level = "3";
break;
case OMX_VIDEO_HEVCMainTierLevel31:
tier = "main";
level = "3.1";
break;
case OMX_VIDEO_HEVCMainTierLevel4:
tier = "main";
level = "4";
break;
case OMX_VIDEO_HEVCMainTierLevel41:
tier = "main";
level = "4.1";
break;
case OMX_VIDEO_HEVCMainTierLevel5:
tier = "main";
level = "5";
break;
case OMX_VIDEO_HEVCMainTierLevel51:
tier = "main";
level = "5.1";
break;
case OMX_VIDEO_HEVCMainTierLevel52:
tier = "main";
level = "5.2";
break;
case OMX_VIDEO_HEVCMainTierLevel6:
tier = "main";
level = "6";
break;
case OMX_VIDEO_HEVCMainTierLevel61:
tier = "main";
level = "6.1";
break;
case OMX_VIDEO_HEVCMainTierLevel62:
tier = "main";
level = "6.2";
break;
case OMX_VIDEO_HEVCHighTierLevel4:
tier = "high";
level = "4";
break;
case OMX_VIDEO_HEVCHighTierLevel41:
tier = "high";
level = "4.1";
break;
case OMX_VIDEO_HEVCHighTierLevel5:
tier = "high";
level = "5";
break;
case OMX_VIDEO_HEVCHighTierLevel51:
tier = "high";
level = "5.1";
break;
case OMX_VIDEO_HEVCHighTierLevel52:
tier = "high";
level = "5.2";
break;
case OMX_VIDEO_HEVCHighTierLevel6:
tier = "high";
level = "6";
break;
case OMX_VIDEO_HEVCHighTierLevel61:
tier = "high";
level = "6.1";
break;
case OMX_VIDEO_HEVCHighTierLevel62:
tier = "high";
level = "6.2";
break;
default:
g_assert_not_reached ();
gst_caps_unref (caps);
return NULL;
}
gst_caps_set_simple (caps,
"profile", G_TYPE_STRING, profile, "level", G_TYPE_STRING, level,
"tier", G_TYPE_STRING, tier, NULL);
}
return caps;
}
static GstFlowReturn
gst_omx_h265_enc_handle_output_frame (GstOMXVideoEnc * enc, GstOMXPort * port,
GstOMXBuffer * buf, GstVideoCodecFrame * frame)
{
GstOMXH265Enc *self = GST_OMX_H265_ENC (enc);
if (buf->omx_buf->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
/* The codec data is SPS/PPS but our output is stream-format=byte-stream.
* For bytestream stream format the SPS/PPS is only in-stream and not
* in the caps!
*/
GstBuffer *hdrs;
GstMapInfo map = GST_MAP_INFO_INIT;
GstFlowReturn flow_ret;
GST_DEBUG_OBJECT (self, "got codecconfig in byte-stream format");
hdrs = gst_buffer_new_and_alloc (buf->omx_buf->nFilledLen);
GST_BUFFER_FLAG_SET (hdrs, GST_BUFFER_FLAG_HEADER);
gst_buffer_map (hdrs, &map, GST_MAP_WRITE);
memcpy (map.data,
buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
buf->omx_buf->nFilledLen);
gst_buffer_unmap (hdrs, &map);
self->headers = g_list_append (self->headers, gst_buffer_ref (hdrs));
frame->output_buffer = hdrs;
flow_ret =
gst_video_encoder_finish_subframe (GST_VIDEO_ENCODER (self), frame);
gst_video_codec_frame_unref (frame);
return flow_ret;
} else if (self->headers) {
gst_video_encoder_set_headers (GST_VIDEO_ENCODER (self), self->headers);
self->headers = NULL;
}
return
GST_OMX_VIDEO_ENC_CLASS
(gst_omx_h265_enc_parent_class)->handle_output_frame (enc, port, buf,
frame);
}

72
omx/gstomxh265enc.h Normal file
View file

@ -0,0 +1,72 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Copyright (C) 2017 Xilinx, Inc.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_H265_ENC_H__
#define __GST_OMX_H265_ENC_H__
#include <gst/gst.h>
#include "gstomxvideoenc.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_H265_ENC \
(gst_omx_h265_enc_get_type())
#define GST_OMX_H265_ENC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_H265_ENC,GstOMXH265Enc))
#define GST_OMX_H265_ENC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_H265_ENC,GstOMXH265EncClass))
#define GST_OMX_H265_ENC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_H265_ENC,GstOMXH265EncClass))
#define GST_IS_OMX_H265_ENC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_H265_ENC))
#define GST_IS_OMX_H265_ENC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_H265_ENC))
typedef struct _GstOMXH265Enc GstOMXH265Enc;
typedef struct _GstOMXH265EncClass GstOMXH265EncClass;
struct _GstOMXH265Enc
{
GstOMXVideoEnc parent;
/* properties */
guint32 interval_intraframes;
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
guint32 periodicity_idr;
guint32 b_frames;
gboolean constrained_intra_prediction;
guint32 loop_filter_mode;
#endif
GList *headers;
};
struct _GstOMXH265EncClass
{
GstOMXVideoEncClass parent_class;
};
GType gst_omx_h265_enc_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_H265_ENC_H__ */

138
omx/gstomxh265utils.c Normal file
View file

@ -0,0 +1,138 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Copyright (C) 2017 Xilinx, Inc.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstomxh265utils.h"
typedef struct
{
const gchar *profile;
OMX_VIDEO_HEVCPROFILETYPE e;
} H265ProfileMapping;
static const H265ProfileMapping h265_profiles[] = {
{"main", OMX_VIDEO_HEVCProfileMain},
{"main-10", OMX_VIDEO_HEVCProfileMain10},
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
{"main-still-picture",
(OMX_VIDEO_HEVCPROFILETYPE) OMX_ALG_VIDEO_HEVCProfileMainStill},
/* Format range extensions profiles (A.3.5) */
{"monochrome",
(OMX_VIDEO_HEVCPROFILETYPE) OMX_ALG_VIDEO_HEVCProfileMonochrome},
/* Not standard: 10 bits variation of monochrome-12 */
{"monochrome-10",
(OMX_VIDEO_HEVCPROFILETYPE) OMX_ALG_VIDEO_HEVCProfileMonochrome10},
/* Not standard: 8 bits variation of main-422-10 */
{"main-422", (OMX_VIDEO_HEVCPROFILETYPE) OMX_ALG_VIDEO_HEVCProfileMain422},
{"main-422-10",
(OMX_VIDEO_HEVCPROFILETYPE) OMX_ALG_VIDEO_HEVCProfileMain422_10},
{"main-intra",
(OMX_VIDEO_HEVCPROFILETYPE) OMX_ALG_VIDEO_HEVCProfileMain_Intra},
{"main-10-intra",
(OMX_VIDEO_HEVCPROFILETYPE) OMX_ALG_VIDEO_HEVCProfileMain10_Intra},
/* Not standard: intra variation of main-422 */
{"main-422-intra",
(OMX_VIDEO_HEVCPROFILETYPE) OMX_ALG_VIDEO_HEVCProfileMain422_Intra},
{"main-422-10-intra",
(OMX_VIDEO_HEVCPROFILETYPE) OMX_ALG_VIDEO_HEVCProfileMain422_10_Intra},
#endif
};
OMX_VIDEO_HEVCPROFILETYPE
gst_omx_h265_utils_get_profile_from_str (const gchar * profile)
{
guint i;
for (i = 0; i < G_N_ELEMENTS (h265_profiles); i++) {
if (g_str_equal (profile, h265_profiles[i].profile))
return h265_profiles[i].e;
}
return OMX_VIDEO_HEVCProfileUnknown;
}
const gchar *
gst_omx_h265_utils_get_profile_from_enum (OMX_VIDEO_HEVCPROFILETYPE e)
{
guint i;
for (i = 0; i < G_N_ELEMENTS (h265_profiles); i++) {
if (e == h265_profiles[i].e)
return h265_profiles[i].profile;
}
return NULL;
}
OMX_VIDEO_HEVCLEVELTYPE
gst_omx_h265_utils_get_level_from_str (const gchar * level, const gchar * tier)
{
if (g_str_equal (tier, "main")) {
if (g_str_equal (level, "1"))
return OMX_VIDEO_HEVCMainTierLevel1;
else if (g_str_equal (level, "2"))
return OMX_VIDEO_HEVCMainTierLevel2;
else if (g_str_equal (level, "2.1"))
return OMX_VIDEO_HEVCMainTierLevel21;
else if (g_str_equal (level, "3"))
return OMX_VIDEO_HEVCMainTierLevel3;
else if (g_str_equal (level, "3.1"))
return OMX_VIDEO_HEVCMainTierLevel31;
else if (g_str_equal (level, "4"))
return OMX_VIDEO_HEVCMainTierLevel4;
else if (g_str_equal (level, "4.1"))
return OMX_VIDEO_HEVCMainTierLevel41;
else if (g_str_equal (level, "5"))
return OMX_VIDEO_HEVCMainTierLevel5;
else if (g_str_equal (level, "5.1"))
return OMX_VIDEO_HEVCMainTierLevel51;
else if (g_str_equal (level, "5.2"))
return OMX_VIDEO_HEVCMainTierLevel52;
else if (g_str_equal (level, "6"))
return OMX_VIDEO_HEVCMainTierLevel6;
else if (g_str_equal (level, "6.1"))
return OMX_VIDEO_HEVCMainTierLevel61;
else if (g_str_equal (level, "6.2"))
return OMX_VIDEO_HEVCMainTierLevel62;
} else if (g_str_equal (tier, "high")) {
if (g_str_equal (level, "4"))
return OMX_VIDEO_HEVCHighTierLevel4;
else if (g_str_equal (level, "4.1"))
return OMX_VIDEO_HEVCHighTierLevel41;
else if (g_str_equal (level, "5"))
return OMX_VIDEO_HEVCHighTierLevel5;
else if (g_str_equal (level, "5.1"))
return OMX_VIDEO_HEVCHighTierLevel51;
else if (g_str_equal (level, "5.2"))
return OMX_VIDEO_HEVCHighTierLevel52;
else if (g_str_equal (level, "6"))
return OMX_VIDEO_HEVCHighTierLevel6;
else if (g_str_equal (level, "6.1"))
return OMX_VIDEO_HEVCHighTierLevel61;
else if (g_str_equal (level, "6.2"))
return OMX_VIDEO_HEVCHighTierLevel62;
}
return OMX_VIDEO_HEVCLevelUnknown;
}

37
omx/gstomxh265utils.h Normal file
View file

@ -0,0 +1,37 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Copyright (C) 2017 Xilinx, Inc.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_H265_UTILS_H__
#define __GST_OMX_H265_UTILS_H__
#include "gstomx.h"
G_BEGIN_DECLS
OMX_VIDEO_HEVCPROFILETYPE gst_omx_h265_utils_get_profile_from_str (const
gchar * profile);
OMX_VIDEO_HEVCLEVELTYPE gst_omx_h265_utils_get_level_from_str (const gchar *
level, const gchar * tier);
const gchar * gst_omx_h265_utils_get_profile_from_enum (OMX_VIDEO_HEVCPROFILETYPE e);
G_END_DECLS
#endif /* __GST_OMX_H265_UTILS_H__ */

66
omx/gstomxhdmiaudiosink.c Normal file
View file

@ -0,0 +1,66 @@
/*
* Copyright (C) 2014, Fluendo, S.A.
* Copyright (C) 2014, Metrological Media Innovations B.V.
* Author: Josep Torra <josep@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxhdmiaudiosink.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_hdmi_audio_sink_debug_category);
#define GST_CAT_DEFAULT gst_omx_hdmi_audio_sink_debug_category
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_hdmi_audio_sink_debug_category, \
"omxhdmiaudiosink", 0, "debug category for gst-omx hdmi audio sink");
G_DEFINE_TYPE_WITH_CODE (GstOMXHdmiAudioSink, gst_omx_hdmi_audio_sink,
GST_TYPE_OMX_AUDIO_SINK, DEBUG_INIT);
static void
gst_omx_hdmi_audio_sink_class_init (GstOMXHdmiAudioSinkClass * klass)
{
GstOMXAudioSinkClass *audiosink_class = GST_OMX_AUDIO_SINK_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
audiosink_class->cdata.default_sink_template_caps = "audio/x-raw, "
"format = (string) " GST_AUDIO_FORMATS_ALL ", "
"layout = (string) interleaved, "
"rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]; "
PASSTHROUGH_CAPS;
audiosink_class->destination = "hdmi";
gst_element_class_set_static_metadata (element_class,
"OpenMAX HDMI Audio Sink",
"Sink/Audio",
"Output audio through HDMI", "Josep Torra <josep@fluendo.com>");
gst_omx_set_default_role (&audiosink_class->cdata, "audio_render.hdmi");
}
static void
gst_omx_hdmi_audio_sink_init (GstOMXHdmiAudioSink * self)
{
}

61
omx/gstomxhdmiaudiosink.h Normal file
View file

@ -0,0 +1,61 @@
/*
* Copyright (C) 2014, Fluendo, S.A.
* Copyright (C) 2014, Metrological Media Innovations B.V.
* Author: Josep Torra <josep@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_HDMI_AUDIO_SINK_H__
#define __GST_OMX_HDMI_AUDIO_SINK_H__
#include <gst/gst.h>
#include "gstomxaudiosink.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_HDMI_AUDIO_SINK \
(gst_omx_hdmi_audio_sink_get_type())
#define GST_OMX_HDMI_AUDIO_SINK(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_HDMI_AUDIO_SINK,GstOMXHdmiAudioSink))
#define GST_OMX_HDMI_AUDIO_SINK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_HDMI_AUDIO_SINK,GstOMXHdmiAudioSinkClass))
#define GST_OMX_HDMI_AUDIO_SINK_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_HDMI_AUDIO_SINK,GstOMXHdmiAudioSinkClass))
#define GST_IS_OMX_HDMI_AUDIO_SINK(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_HDMI_AUDIO_SINK))
#define GST_IS_OMX_HDMI_AUDIO_SINK_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_HDMI_AUDIO_SINK))
typedef struct _GstOMXHdmiAudioSink GstOMXHdmiAudioSink;
typedef struct _GstOMXHdmiAudioSinkClass GstOMXHdmiAudioSinkClass;
struct _GstOMXHdmiAudioSink
{
GstOMXAudioSink parent;
};
struct _GstOMXHdmiAudioSinkClass
{
GstOMXAudioSinkClass parent_class;
};
GType gst_omx_hdmi_audio_sink_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_HDMI_AUDIO_SINK_H__ */

98
omx/gstomxmjpegdec.c Normal file
View file

@ -0,0 +1,98 @@
/*
* Copyright (C) 2013, Collabora Ltd.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxmjpegdec.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_mjpeg_dec_debug_category);
#define GST_CAT_DEFAULT gst_omx_mjpeg_dec_debug_category
/* prototypes */
static gboolean gst_omx_mjpeg_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
static gboolean gst_omx_mjpeg_dec_set_format (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
enum
{
PROP_0
};
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_mjpeg_dec_debug_category, "omxmjpegdec", 0, \
"debug category for gst-omx video decoder base class");
G_DEFINE_TYPE_WITH_CODE (GstOMXMJPEGDec, gst_omx_mjpeg_dec,
GST_TYPE_OMX_VIDEO_DEC, DEBUG_INIT);
static void
gst_omx_mjpeg_dec_class_init (GstOMXMJPEGDecClass * klass)
{
GstOMXVideoDecClass *videodec_class = GST_OMX_VIDEO_DEC_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
videodec_class->is_format_change =
GST_DEBUG_FUNCPTR (gst_omx_mjpeg_dec_is_format_change);
videodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_mjpeg_dec_set_format);
videodec_class->cdata.default_sink_template_caps = "image/jpeg, "
"width=(int) [1,MAX], " "height=(int) [1,MAX]";
gst_element_class_set_static_metadata (element_class,
"OpenMAX MJPEG Video Decoder",
"Codec/Decoder/Video/Hardware",
"Decode MJPEG video streams",
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
gst_omx_set_default_role (&videodec_class->cdata, "video_decoder.mjpeg");
}
static void
gst_omx_mjpeg_dec_init (GstOMXMJPEGDec * self)
{
}
static gboolean
gst_omx_mjpeg_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state)
{
return FALSE;
}
static gboolean
gst_omx_mjpeg_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port,
GstVideoCodecState * state)
{
gboolean ret;
OMX_PARAM_PORTDEFINITIONTYPE port_def;
gst_omx_port_get_port_definition (port, &port_def);
port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingMJPEG;
ret = gst_omx_port_update_port_definition (port, &port_def) == OMX_ErrorNone;
return ret;
}

60
omx/gstomxmjpegdec.h Normal file
View file

@ -0,0 +1,60 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_MJPEG_DEC_H__
#define __GST_OMX_MJPEG_DEC_H__
#include <gst/gst.h>
#include "gstomxvideodec.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_MJPEG_DEC \
(gst_omx_mjpeg_dec_get_type())
#define GST_OMX_MJPEG_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_MJPEG_DEC,GstOMXMJPEGDec))
#define GST_OMX_MJPEG_DEC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_MJPEG_DEC,GstOMXMJPEGDecClass))
#define GST_OMX_MJPEG_DEC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_MJPEG_DEC,GstOMXMJPEGDecClass))
#define GST_IS_OMX_MJPEG_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_MJPEG_DEC))
#define GST_IS_OMX_MJPEG_DEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_MJPEG_DEC))
typedef struct _GstOMXMJPEGDec GstOMXMJPEGDec;
typedef struct _GstOMXMJPEGDecClass GstOMXMJPEGDecClass;
struct _GstOMXMJPEGDec
{
GstOMXVideoDec parent;
};
struct _GstOMXMJPEGDecClass
{
GstOMXVideoDecClass parent_class;
};
GType gst_omx_mjpeg_dec_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_MJPEG_DEC_H__ */

246
omx/gstomxmp3dec.c Normal file
View file

@ -0,0 +1,246 @@
/*
* Copyright (C) 2014, Sebastian Dröge <sebastian@centricular.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxmp3dec.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_mp3_dec_debug_category);
#define GST_CAT_DEFAULT gst_omx_mp3_dec_debug_category
/* prototypes */
static gboolean gst_omx_mp3_dec_set_format (GstOMXAudioDec * dec,
GstOMXPort * port, GstCaps * caps);
static gboolean gst_omx_mp3_dec_is_format_change (GstOMXAudioDec * dec,
GstOMXPort * port, GstCaps * caps);
static gint gst_omx_mp3_dec_get_samples_per_frame (GstOMXAudioDec * dec,
GstOMXPort * port);
static gboolean gst_omx_mp3_dec_get_channel_positions (GstOMXAudioDec * dec,
GstOMXPort * port, GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS]);
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_mp3_dec_debug_category, "omxmp3dec", 0, \
"debug category for gst-omx mp3 audio decoder");
G_DEFINE_TYPE_WITH_CODE (GstOMXMP3Dec, gst_omx_mp3_dec,
GST_TYPE_OMX_AUDIO_DEC, DEBUG_INIT);
static void
gst_omx_mp3_dec_class_init (GstOMXMP3DecClass * klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstOMXAudioDecClass *audiodec_class = GST_OMX_AUDIO_DEC_CLASS (klass);
audiodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_mp3_dec_set_format);
audiodec_class->is_format_change =
GST_DEBUG_FUNCPTR (gst_omx_mp3_dec_is_format_change);
audiodec_class->get_samples_per_frame =
GST_DEBUG_FUNCPTR (gst_omx_mp3_dec_get_samples_per_frame);
audiodec_class->get_channel_positions =
GST_DEBUG_FUNCPTR (gst_omx_mp3_dec_get_channel_positions);
audiodec_class->cdata.default_sink_template_caps = "audio/mpeg, "
"mpegversion=(int)1, "
"layer=(int)3, "
"mpegaudioversion=(int)[1,3], "
"rate=(int)[8000,48000], "
"channels=(int)[1,2], " "parsed=(boolean) true";
gst_element_class_set_static_metadata (element_class,
"OpenMAX MP3 Audio Decoder",
"Codec/Decoder/Audio/Hardware",
"Decode MP3 audio streams",
"Sebastian Dröge <sebastian@centricular.com>");
gst_omx_set_default_role (&audiodec_class->cdata, "audio_decoder.mp3");
}
static void
gst_omx_mp3_dec_init (GstOMXMP3Dec * self)
{
self->spf = -1;
}
static gboolean
gst_omx_mp3_dec_set_format (GstOMXAudioDec * dec, GstOMXPort * port,
GstCaps * caps)
{
GstOMXMP3Dec *self = GST_OMX_MP3_DEC (dec);
OMX_PARAM_PORTDEFINITIONTYPE port_def;
OMX_AUDIO_PARAM_MP3TYPE mp3_param;
OMX_ERRORTYPE err;
GstStructure *s;
gint rate, channels, layer, mpegaudioversion;
gst_omx_port_get_port_definition (port, &port_def);
port_def.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
err = gst_omx_port_update_port_definition (port, &port_def);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Failed to set MP3 format on component: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
GST_OMX_INIT_STRUCT (&mp3_param);
mp3_param.nPortIndex = port->index;
err =
gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioMp3,
&mp3_param);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Failed to get MP3 parameters from component: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
s = gst_caps_get_structure (caps, 0);
if (!gst_structure_get_int (s, "mpegaudioversion", &mpegaudioversion) ||
!gst_structure_get_int (s, "layer", &layer) ||
!gst_structure_get_int (s, "rate", &rate) ||
!gst_structure_get_int (s, "channels", &channels)) {
GST_ERROR_OBJECT (self, "Incomplete caps");
return FALSE;
}
self->spf = (mpegaudioversion == 1 ? 1152 : 576);
mp3_param.nChannels = channels;
mp3_param.nBitRate = 0; /* unknown */
mp3_param.nSampleRate = rate;
mp3_param.nAudioBandWidth = 0; /* decoder decision */
mp3_param.eChannelMode = 0; /* FIXME */
if (mpegaudioversion == 1)
mp3_param.eFormat = OMX_AUDIO_MP3StreamFormatMP1Layer3;
else if (mpegaudioversion == 2)
mp3_param.eFormat = OMX_AUDIO_MP3StreamFormatMP2Layer3;
else
mp3_param.eFormat = OMX_AUDIO_MP3StreamFormatMP2_5Layer3;
err =
gst_omx_component_set_parameter (dec->dec, OMX_IndexParamAudioMp3,
&mp3_param);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self, "Error setting MP3 parameters: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
return TRUE;
}
static gboolean
gst_omx_mp3_dec_is_format_change (GstOMXAudioDec * dec, GstOMXPort * port,
GstCaps * caps)
{
GstOMXMP3Dec *self = GST_OMX_MP3_DEC (dec);
OMX_AUDIO_PARAM_MP3TYPE mp3_param;
OMX_ERRORTYPE err;
GstStructure *s;
gint rate, channels, layer, mpegaudioversion;
GST_OMX_INIT_STRUCT (&mp3_param);
mp3_param.nPortIndex = port->index;
err =
gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioMp3,
&mp3_param);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Failed to get MP3 parameters from component: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
s = gst_caps_get_structure (caps, 0);
if (!gst_structure_get_int (s, "mpegaudioversion", &mpegaudioversion) ||
!gst_structure_get_int (s, "layer", &layer) ||
!gst_structure_get_int (s, "rate", &rate) ||
!gst_structure_get_int (s, "channels", &channels)) {
GST_ERROR_OBJECT (self, "Incomplete caps");
return FALSE;
}
if (mp3_param.nChannels != channels)
return TRUE;
if (mp3_param.nSampleRate != rate)
return TRUE;
if (mpegaudioversion == 1
&& mp3_param.eFormat != OMX_AUDIO_MP3StreamFormatMP1Layer3)
return TRUE;
if (mpegaudioversion == 2
&& mp3_param.eFormat != OMX_AUDIO_MP3StreamFormatMP2Layer3)
return TRUE;
if (mpegaudioversion == 3
&& mp3_param.eFormat != OMX_AUDIO_MP3StreamFormatMP2_5Layer3)
return TRUE;
return FALSE;
}
static gint
gst_omx_mp3_dec_get_samples_per_frame (GstOMXAudioDec * dec, GstOMXPort * port)
{
return GST_OMX_MP3_DEC (dec)->spf;
}
static gboolean
gst_omx_mp3_dec_get_channel_positions (GstOMXAudioDec * dec,
GstOMXPort * port, GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS])
{
OMX_AUDIO_PARAM_PCMMODETYPE pcm_param;
OMX_ERRORTYPE err;
GST_OMX_INIT_STRUCT (&pcm_param);
pcm_param.nPortIndex = port->index;
err =
gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioPcm,
&pcm_param);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (dec, "Failed to get PCM parameters: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
switch (pcm_param.nChannels) {
case 1:
position[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
break;
case 2:
position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
break;
default:
return FALSE;
}
return TRUE;
}

60
omx/gstomxmp3dec.h Normal file
View file

@ -0,0 +1,60 @@
/*
* Copyright (C) 2014, Sebastian Dröge <sebastian@centricular.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_MP3_DEC_H__
#define __GST_OMX_MP3_DEC_H__
#include <gst/gst.h>
#include "gstomxaudiodec.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_MP3_DEC \
(gst_omx_mp3_dec_get_type())
#define GST_OMX_MP3_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_MP3_DEC,GstOMXMP3Dec))
#define GST_OMX_MP3_DEC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_MP3_DEC,GstOMXMP3DecClass))
#define GST_OMX_MP3_DEC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_MP3_DEC,GstOMXMP3DecClass))
#define GST_IS_OMX_MP3_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_MP3_DEC))
#define GST_IS_OMX_MP3_DEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_MP3_DEC))
typedef struct _GstOMXMP3Dec GstOMXMP3Dec;
typedef struct _GstOMXMP3DecClass GstOMXMP3DecClass;
struct _GstOMXMP3Dec
{
GstOMXAudioDec parent;
gint spf;
};
struct _GstOMXMP3DecClass
{
GstOMXAudioDecClass parent_class;
};
GType gst_omx_mp3_dec_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_MP3_DEC_H__ */

278
omx/gstomxmp3enc.c Normal file
View file

@ -0,0 +1,278 @@
/*
* Copyright (C) 2017
* Author: Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxmp3enc.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_mp3_enc_debug_category);
#define GST_CAT_DEFAULT gst_omx_mp3_enc_debug_category
/* prototypes */
static void gst_omx_mp3_enc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_omx_mp3_enc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static gboolean gst_omx_mp3_enc_set_format (GstOMXAudioEnc * enc,
GstOMXPort * port, GstAudioInfo * info);
static GstCaps *gst_omx_mp3_enc_get_caps (GstOMXAudioEnc * enc,
GstOMXPort * port, GstAudioInfo * info);
static guint gst_omx_mp3_enc_get_num_samples (GstOMXAudioEnc * enc,
GstOMXPort * port, GstAudioInfo * info, GstOMXBuffer * buf);
enum
{
PROP_0,
PROP_BITRATE
};
#define DEFAULT_BITRATE (128)
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_mp3_enc_debug_category, "omxmp3enc", 0, \
"debug category for gst-omx audio encoder base class");
G_DEFINE_TYPE_WITH_CODE (GstOMXMP3Enc, gst_omx_mp3_enc,
GST_TYPE_OMX_AUDIO_ENC, DEBUG_INIT);
static void
gst_omx_mp3_enc_class_init (GstOMXMP3EncClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstOMXAudioEncClass *audioenc_class = GST_OMX_AUDIO_ENC_CLASS (klass);
gobject_class->set_property = gst_omx_mp3_enc_set_property;
gobject_class->get_property = gst_omx_mp3_enc_get_property;
g_object_class_install_property (gobject_class, PROP_BITRATE,
g_param_spec_uint ("bitrate", "Bitrate (kb/s)",
"Bitrate in kbit/sec",
0, G_MAXUINT, DEFAULT_BITRATE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
audioenc_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_mp3_enc_set_format);
audioenc_class->get_caps = GST_DEBUG_FUNCPTR (gst_omx_mp3_enc_get_caps);
audioenc_class->get_num_samples =
GST_DEBUG_FUNCPTR (gst_omx_mp3_enc_get_num_samples);
audioenc_class->cdata.default_src_template_caps = "audio/mpeg, "
"mpegversion=(int)1, "
"layer=(int)3, "
"mpegaudioversion=(int)[1,3], "
"rate=(int)[8000,48000], " "channels=(int)[1,2]";
gst_element_class_set_static_metadata (element_class,
"OpenMAX MP3 Audio Encoder",
"Codec/Encoder/Audio/Hardware",
"Encode AAC audio streams", "Julien Isorce <julien.isorce@gmail.com>");
gst_omx_set_default_role (&audioenc_class->cdata, "audio_encoder.mp3");
}
static void
gst_omx_mp3_enc_init (GstOMXMP3Enc * self)
{
self->mpegaudioversion = 1;
self->bitrate = DEFAULT_BITRATE;
}
static void
gst_omx_mp3_enc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstOMXMP3Enc *self = GST_OMX_MP3_ENC (object);
switch (prop_id) {
case PROP_BITRATE:
self->bitrate = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_omx_mp3_enc_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstOMXMP3Enc *self = GST_OMX_MP3_ENC (object);
switch (prop_id) {
case PROP_BITRATE:
g_value_set_uint (value, self->bitrate);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static gboolean
gst_omx_mp3_enc_set_format (GstOMXAudioEnc * enc, GstOMXPort * port,
GstAudioInfo * info)
{
GstOMXMP3Enc *self = GST_OMX_MP3_ENC (enc);
OMX_AUDIO_PARAM_MP3TYPE mp3_param;
GstCaps *peercaps;
OMX_ERRORTYPE err;
GST_OMX_INIT_STRUCT (&mp3_param);
mp3_param.nPortIndex = enc->enc_out_port->index;
err =
gst_omx_component_get_parameter (enc->enc, OMX_IndexParamAudioMp3,
&mp3_param);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Failed to get MP# parameters from component: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
peercaps = gst_pad_peer_query_caps (GST_AUDIO_ENCODER_SRC_PAD (self),
gst_pad_get_pad_template_caps (GST_AUDIO_ENCODER_SRC_PAD (self)));
if (peercaps) {
GstStructure *s;
gint mpegaudioversion = 0;
if (gst_caps_is_empty (peercaps)) {
gst_caps_unref (peercaps);
GST_ERROR_OBJECT (self, "Empty caps");
return FALSE;
}
s = gst_caps_get_structure (peercaps, 0);
if (gst_structure_get_int (s, "mpegaudioversion", &mpegaudioversion)) {
switch (mpegaudioversion) {
case 1:
mp3_param.eFormat = OMX_AUDIO_MP3StreamFormatMP1Layer3;
break;
case 2:
mp3_param.eFormat = OMX_AUDIO_MP3StreamFormatMP2Layer3;
break;
case 3:
mp3_param.eFormat = OMX_AUDIO_MP3StreamFormatMP2_5Layer3;
break;
default:
GST_ERROR_OBJECT (self, "Unsupported mpegaudioversion '%d'",
mpegaudioversion);
gst_caps_unref (peercaps);
return FALSE;
}
self->mpegaudioversion = mpegaudioversion;
}
gst_caps_unref (peercaps);
mp3_param.nSampleRate = info->rate;
mp3_param.nChannels = info->channels;
mp3_param.eChannelMode =
info->channels ==
1 ? OMX_AUDIO_ChannelModeMono : OMX_AUDIO_ChannelModeStereo;
}
mp3_param.nBitRate = self->bitrate;
err =
gst_omx_component_set_parameter (enc->enc, OMX_IndexParamAudioMp3,
&mp3_param);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self, "Error setting MP3 parameters: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return FALSE;
}
return TRUE;
}
static GstCaps *
gst_omx_mp3_enc_get_caps (GstOMXAudioEnc * enc, GstOMXPort * port,
GstAudioInfo * info)
{
GstCaps *caps;
OMX_ERRORTYPE err;
OMX_AUDIO_PARAM_MP3TYPE mp3_param;
gint mpegaudioversion = 0;
GST_OMX_INIT_STRUCT (&mp3_param);
mp3_param.nPortIndex = enc->enc_out_port->index;
err =
gst_omx_component_get_parameter (enc->enc, OMX_IndexParamAudioMp3,
&mp3_param);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (enc,
"Failed to get MP3 parameters from component: %s (0x%08x)",
gst_omx_error_to_string (err), err);
return NULL;
}
switch (mp3_param.eFormat) {
case OMX_AUDIO_MP3StreamFormatMP1Layer3:
mpegaudioversion = 1;
break;
case OMX_AUDIO_MP3StreamFormatMP2Layer3:
mpegaudioversion = 2;
break;
case OMX_AUDIO_MP3StreamFormatMP2_5Layer3:
mpegaudioversion = 3;
break;
default:
GST_ERROR_OBJECT (enc, "Unsupported mpegaudioversion %d",
mp3_param.eFormat);
break;
}
caps =
gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 1, "layer",
G_TYPE_INT, 3, NULL);
if (mpegaudioversion != 0)
gst_caps_set_simple (caps, "mpegaudioversion", G_TYPE_INT, mpegaudioversion,
NULL);
if (mp3_param.nChannels != 0)
gst_caps_set_simple (caps, "channels", G_TYPE_INT, mp3_param.nChannels,
NULL);
if (mp3_param.nSampleRate != 0)
gst_caps_set_simple (caps, "rate", G_TYPE_INT, mp3_param.nSampleRate, NULL);
return caps;
}
static guint
gst_omx_mp3_enc_get_num_samples (GstOMXAudioEnc * enc, GstOMXPort * port,
GstAudioInfo * info, GstOMXBuffer * buf)
{
GstOMXMP3Enc *self = GST_OMX_MP3_ENC (enc);
return (self->mpegaudioversion == 1) ? 1152 : 576;
}

65
omx/gstomxmp3enc.h Normal file
View file

@ -0,0 +1,65 @@
/*
* Copyright (C) 2017
* Author: Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_MP3_ENC_H__
#define __GST_OMX_MP3_ENC_H__
#include <gst/gst.h>
#include "gstomxaudioenc.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_MP3_ENC \
(gst_omx_mp3_enc_get_type())
#define GST_OMX_MP3_ENC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_MP3_ENC,GstOMXMP3Enc))
#define GST_OMX_MP3_ENC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_MP3_ENC,GstOMXMP3EncClass))
#define GST_OMX_MP3_ENC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_MP3_ENC,GstOMXMP3EncClass))
#define GST_IS_OMX_MP3_ENC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_MP3_ENC))
#define GST_IS_OMX_MP3_ENC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_MP3_ENC))
typedef struct _GstOMXMP3Enc GstOMXMP3Enc;
typedef struct _GstOMXMP3EncClass GstOMXMP3EncClass;
struct _GstOMXMP3Enc
{
GstOMXAudioEnc parent;
guint mpegaudioversion;
/* properties */
guint bitrate;
};
struct _GstOMXMP3EncClass
{
GstOMXAudioEncClass parent_class;
};
GType gst_omx_mp3_enc_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_MP3_ENC_H__ */

101
omx/gstomxmpeg2videodec.c Normal file
View file

@ -0,0 +1,101 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxmpeg2videodec.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_mpeg2_video_dec_debug_category);
#define GST_CAT_DEFAULT gst_omx_mpeg2_video_dec_debug_category
/* prototypes */
static gboolean gst_omx_mpeg2_video_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
static gboolean gst_omx_mpeg2_video_dec_set_format (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
enum
{
PROP_0
};
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_mpeg2_video_dec_debug_category, "omxmpeg2dec", 0, \
"debug category for gst-omx video decoder base class");
G_DEFINE_TYPE_WITH_CODE (GstOMXMPEG2VideoDec, gst_omx_mpeg2_video_dec,
GST_TYPE_OMX_VIDEO_DEC, DEBUG_INIT);
static void
gst_omx_mpeg2_video_dec_class_init (GstOMXMPEG2VideoDecClass * klass)
{
GstOMXVideoDecClass *videodec_class = GST_OMX_VIDEO_DEC_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
videodec_class->is_format_change =
GST_DEBUG_FUNCPTR (gst_omx_mpeg2_video_dec_is_format_change);
videodec_class->set_format =
GST_DEBUG_FUNCPTR (gst_omx_mpeg2_video_dec_set_format);
videodec_class->cdata.default_sink_template_caps = "video/mpeg, "
"mpegversion=(int) [1, 2], "
"systemstream=(boolean) false, "
"parsed=(boolean) true, " "width=(int) [1,MAX], " "height=(int) [1,MAX]";
gst_element_class_set_static_metadata (element_class,
"OpenMAX MPEG2 Video Decoder",
"Codec/Decoder/Video/Hardware",
"Decode MPEG2 video streams",
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
gst_omx_set_default_role (&videodec_class->cdata, "video_decoder.mpeg2");
}
static void
gst_omx_mpeg2_video_dec_init (GstOMXMPEG2VideoDec * self)
{
}
static gboolean
gst_omx_mpeg2_video_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state)
{
return FALSE;
}
static gboolean
gst_omx_mpeg2_video_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port,
GstVideoCodecState * state)
{
gboolean ret;
OMX_PARAM_PORTDEFINITIONTYPE port_def;
gst_omx_port_get_port_definition (port, &port_def);
port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG2;
ret = gst_omx_port_update_port_definition (port, &port_def) == OMX_ErrorNone;
return ret;
}

59
omx/gstomxmpeg2videodec.h Normal file
View file

@ -0,0 +1,59 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_MPEG2_VIDEO_DEC_H__
#define __GST_OMX_MPEG2_VIDEO_DEC_H__
#include <gst/gst.h>
#include "gstomxvideodec.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_MPEG2_VIDEO_DEC \
(gst_omx_mpeg2_video_get_type())
#define GST_OMX_MPEG2_VIDEO_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_MPEG2_VIDEO_DEC,GstOMXMPEG2VideoDec))
#define GST_OMX_MPEG2_VIDEO_DEC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_MPEG2_VIDEO_DEC,GstOMXMPEG2VideoDecClass))
#define GST_OMX_MPEG2_VIDEO_DEC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_MPEG2_VIDEO_DEC,GstOMXMPEG2VideoDecClass))
#define GST_IS_OMX_MPEG2_VIDEO_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_MPEG2_VIDEO_DEC))
#define GST_IS_OMX_MPEG2_VIDEO_DEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_MPEG2_VIDEO_DEC))
typedef struct _GstOMXMPEG2VideoDec GstOMXMPEG2VideoDec;
typedef struct _GstOMXMPEG2VideoDecClass GstOMXMPEG2VideoDecClass;
struct _GstOMXMPEG2VideoDec
{
GstOMXVideoDec parent;
};
struct _GstOMXMPEG2VideoDecClass
{
GstOMXVideoDecClass parent_class;
};
GType gst_omx_mpeg2_video_dec_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_MPEG2_VIDEO_DEC_H__ */

102
omx/gstomxmpeg4videodec.c Normal file
View file

@ -0,0 +1,102 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxmpeg4videodec.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_mpeg4_video_dec_debug_category);
#define GST_CAT_DEFAULT gst_omx_mpeg4_video_dec_debug_category
/* prototypes */
static gboolean gst_omx_mpeg4_video_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
static gboolean gst_omx_mpeg4_video_dec_set_format (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
enum
{
PROP_0
};
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_mpeg4_video_dec_debug_category, "omxmpeg4videodec", 0, \
"debug category for gst-omx video decoder base class");
G_DEFINE_TYPE_WITH_CODE (GstOMXMPEG4VideoDec, gst_omx_mpeg4_video_dec,
GST_TYPE_OMX_VIDEO_DEC, DEBUG_INIT);
static void
gst_omx_mpeg4_video_dec_class_init (GstOMXMPEG4VideoDecClass * klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstOMXVideoDecClass *videodec_class = GST_OMX_VIDEO_DEC_CLASS (klass);
videodec_class->is_format_change =
GST_DEBUG_FUNCPTR (gst_omx_mpeg4_video_dec_is_format_change);
videodec_class->set_format =
GST_DEBUG_FUNCPTR (gst_omx_mpeg4_video_dec_set_format);
videodec_class->cdata.default_sink_template_caps = "video/mpeg, "
"mpegversion=(int) 4, "
"systemstream=(boolean) false, "
"parsed=(boolean) true, " "width=(int) [1,MAX], " "height=(int) [1,MAX]";
gst_element_class_set_static_metadata (element_class,
"OpenMAX MPEG4 Video Decoder",
"Codec/Decoder/Video/Hardware",
"Decode MPEG4 video streams",
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
gst_omx_set_default_role (&videodec_class->cdata, "video_decoder.mpeg4");
}
static void
gst_omx_mpeg4_video_dec_init (GstOMXMPEG4VideoDec * self)
{
}
static gboolean
gst_omx_mpeg4_video_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state)
{
return FALSE;
}
static gboolean
gst_omx_mpeg4_video_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port,
GstVideoCodecState * state)
{
gboolean ret;
OMX_PARAM_PORTDEFINITIONTYPE port_def;
gst_omx_port_get_port_definition (port, &port_def);
port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
ret = gst_omx_port_update_port_definition (port, &port_def) == OMX_ErrorNone;
return ret;
}

60
omx/gstomxmpeg4videodec.h Normal file
View file

@ -0,0 +1,60 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_MPEG4_VIDEO_DEC_H__
#define __GST_OMX_MPEG4_VIDEO_DEC_H__
#include <gst/gst.h>
#include "gstomxvideodec.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_MPEG4_VIDEO_DEC \
(gst_omx_mpeg4_video_dec_get_type())
#define GST_OMX_MPEG4_VIDEO_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_MPEG4_VIDEO_DEC,GstOMXMPEG4VideoDec))
#define GST_OMX_MPEG4_VIDEO_DEC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_MPEG4_VIDEO_DEC,GstOMXMPEG4VideoDecClass))
#define GST_OMX_MPEG4_VIDEO_DEC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_MPEG4_VIDEO_DEC,GstOMXMPEG4VideoDecClass))
#define GST_IS_OMX_MPEG4_VIDEO_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_MPEG4_VIDEO_DEC))
#define GST_IS_OMX_MPEG4_VIDEO_DEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_MPEG4_VIDEO_DEC))
typedef struct _GstOMXMPEG4VideoDec GstOMXMPEG4VideoDec;
typedef struct _GstOMXMPEG4VideoDecClass GstOMXMPEG4VideoDecClass;
struct _GstOMXMPEG4VideoDec
{
GstOMXVideoDec parent;
};
struct _GstOMXMPEG4VideoDecClass
{
GstOMXVideoDecClass parent_class;
};
GType gst_omx_mpeg4_video_dec_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_MPEG4_VIDEO_DEC_H__ */

336
omx/gstomxmpeg4videoenc.c Normal file
View file

@ -0,0 +1,336 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxmpeg4videoenc.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_mpeg4_video_enc_debug_category);
#define GST_CAT_DEFAULT gst_omx_mpeg4_video_enc_debug_category
/* prototypes */
static gboolean gst_omx_mpeg4_video_enc_set_format (GstOMXVideoEnc * enc,
GstOMXPort * port, GstVideoCodecState * state);
static GstCaps *gst_omx_mpeg4_video_enc_get_caps (GstOMXVideoEnc * enc,
GstOMXPort * port, GstVideoCodecState * state);
enum
{
PROP_0
};
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_mpeg4_video_enc_debug_category, "omxmpeg4videoenc", 0, \
"debug category for gst-omx video encoder base class");
G_DEFINE_TYPE_WITH_CODE (GstOMXMPEG4VideoEnc, gst_omx_mpeg4_video_enc,
GST_TYPE_OMX_VIDEO_ENC, DEBUG_INIT);
static void
gst_omx_mpeg4_video_enc_class_init (GstOMXMPEG4VideoEncClass * klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstOMXVideoEncClass *videoenc_class = GST_OMX_VIDEO_ENC_CLASS (klass);
videoenc_class->set_format =
GST_DEBUG_FUNCPTR (gst_omx_mpeg4_video_enc_set_format);
videoenc_class->get_caps =
GST_DEBUG_FUNCPTR (gst_omx_mpeg4_video_enc_get_caps);
videoenc_class->cdata.default_src_template_caps = "video/mpeg, "
"mpegversion=(int) 4, "
"systemstream=(boolean) false, "
"width=(int) [ 16, 4096 ], " "height=(int) [ 16, 4096 ]";
gst_element_class_set_static_metadata (element_class,
"OpenMAX MPEG4 Video Encoder",
"Codec/Encoder/Video/Hardware",
"Encode MPEG4 video streams",
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
gst_omx_set_default_role (&videoenc_class->cdata, "video_encoder.mpeg4");
}
static void
gst_omx_mpeg4_video_enc_init (GstOMXMPEG4VideoEnc * self)
{
}
static gboolean
gst_omx_mpeg4_video_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port,
GstVideoCodecState * state)
{
GstOMXMPEG4VideoEnc *self = GST_OMX_MPEG4_VIDEO_ENC (enc);
GstCaps *peercaps, *intersection;
OMX_PARAM_PORTDEFINITIONTYPE port_def;
OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
OMX_ERRORTYPE err;
const gchar *profile_string, *level_string;
gst_omx_port_get_port_definition (GST_OMX_VIDEO_ENC (self)->enc_out_port,
&port_def);
port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
err =
gst_omx_port_update_port_definition (GST_OMX_VIDEO_ENC
(self)->enc_out_port, &port_def);
if (err != OMX_ErrorNone)
return FALSE;
GST_OMX_INIT_STRUCT (&param);
param.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
err =
gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexParamVideoProfileLevelCurrent, &param);
if (err != OMX_ErrorNone) {
GST_WARNING_OBJECT (self,
"Getting profile/level not supported by component");
return FALSE;
}
peercaps = gst_pad_peer_query_caps (GST_VIDEO_ENCODER_SRC_PAD (enc), NULL);
if (peercaps) {
GstStructure *s;
intersection =
gst_caps_intersect (peercaps,
gst_pad_get_pad_template_caps (GST_VIDEO_ENCODER_SRC_PAD (enc)));
gst_caps_unref (peercaps);
if (gst_caps_is_empty (intersection)) {
gst_caps_unref (intersection);
GST_ERROR_OBJECT (self, "Empty caps");
return FALSE;
}
s = gst_caps_get_structure (intersection, 0);
profile_string = gst_structure_get_string (s, "profile");
if (profile_string) {
if (g_str_equal (profile_string, "simple")) {
param.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
} else if (g_str_equal (profile_string, "simple-scalable")) {
param.eProfile = OMX_VIDEO_MPEG4ProfileSimpleScalable;
} else if (g_str_equal (profile_string, "core")) {
param.eProfile = OMX_VIDEO_MPEG4ProfileCore;
} else if (g_str_equal (profile_string, "main")) {
param.eProfile = OMX_VIDEO_MPEG4ProfileMain;
} else if (g_str_equal (profile_string, "n-bit")) {
param.eProfile = OMX_VIDEO_MPEG4ProfileNbit;
} else if (g_str_equal (profile_string, "scalable")) {
param.eProfile = OMX_VIDEO_MPEG4ProfileScalableTexture;
} else if (g_str_equal (profile_string, "simple-face")) {
param.eProfile = OMX_VIDEO_MPEG4ProfileSimpleFace;
} else if (g_str_equal (profile_string, "simple-fba")) {
param.eProfile = OMX_VIDEO_MPEG4ProfileSimpleFBA;
} else if (g_str_equal (profile_string, "basic-animated-texture")) {
param.eProfile = OMX_VIDEO_MPEG4ProfileBasicAnimated;
} else if (g_str_equal (profile_string, "hybrid")) {
param.eProfile = OMX_VIDEO_MPEG4ProfileHybrid;
} else if (g_str_equal (profile_string, "advanced-real-time-simple")) {
param.eProfile = OMX_VIDEO_MPEG4ProfileAdvancedRealTime;
} else if (g_str_equal (profile_string, "core-scalable")) {
param.eProfile = OMX_VIDEO_MPEG4ProfileCoreScalable;
} else if (g_str_equal (profile_string, "advanced-coding-efficiency")) {
param.eProfile = OMX_VIDEO_MPEG4ProfileAdvancedCoding;
} else if (g_str_equal (profile_string, "advanced-core")) {
param.eProfile = OMX_VIDEO_MPEG4ProfileAdvancedCore;
} else if (g_str_equal (profile_string, "advanced-scalable-texture")) {
param.eProfile = OMX_VIDEO_MPEG4ProfileAdvancedScalable;
} else if (g_str_equal (profile_string, "advanced-simple")) {
param.eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
} else {
goto unsupported_profile;
}
}
level_string = gst_structure_get_string (s, "level");
if (level_string) {
if (g_str_equal (level_string, "0")) {
param.eLevel = OMX_VIDEO_MPEG4Level0;
} else if (g_str_equal (level_string, "0b")) {
param.eLevel = OMX_VIDEO_MPEG4Level0b;
} else if (g_str_equal (level_string, "1")) {
param.eLevel = OMX_VIDEO_MPEG4Level1;
} else if (g_str_equal (level_string, "2")) {
param.eLevel = OMX_VIDEO_MPEG4Level2;
} else if (g_str_equal (level_string, "3")) {
param.eLevel = OMX_VIDEO_MPEG4Level3;
} else if (g_str_equal (level_string, "4")) {
param.eLevel = OMX_VIDEO_MPEG4Level4;
} else if (g_str_equal (level_string, "4a")) {
param.eLevel = OMX_VIDEO_MPEG4Level4a;
} else if (g_str_equal (level_string, "5")) {
param.eLevel = OMX_VIDEO_MPEG4Level5;
} else {
goto unsupported_level;
}
}
gst_caps_unref (intersection);
}
err =
gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexParamVideoProfileLevelCurrent, &param);
if (err == OMX_ErrorUnsupportedIndex) {
GST_WARNING_OBJECT (self,
"Setting profile/level not supported by component");
} else if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self,
"Error setting profile %u and level %u: %s (0x%08x)",
(guint) param.eProfile, (guint) param.eLevel,
gst_omx_error_to_string (err), err);
return FALSE;
}
return TRUE;
unsupported_profile:
GST_ERROR_OBJECT (self, "Unsupported profile %s", profile_string);
gst_caps_unref (intersection);
return FALSE;
unsupported_level:
GST_ERROR_OBJECT (self, "Unsupported level %s", level_string);
gst_caps_unref (intersection);
return FALSE;
}
static GstCaps *
gst_omx_mpeg4_video_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port,
GstVideoCodecState * state)
{
GstOMXMPEG4VideoEnc *self = GST_OMX_MPEG4_VIDEO_ENC (enc);
GstCaps *caps;
OMX_ERRORTYPE err;
OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
const gchar *profile, *level;
caps =
gst_caps_new_simple ("video/mpeg", "mpegversion", G_TYPE_INT, 4,
"systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
GST_OMX_INIT_STRUCT (&param);
param.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
err =
gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
OMX_IndexParamVideoProfileLevelCurrent, &param);
if (err != OMX_ErrorNone && err != OMX_ErrorUnsupportedIndex) {
gst_caps_unref (caps);
return NULL;
}
if (err == OMX_ErrorNone) {
switch (param.eProfile) {
case OMX_VIDEO_MPEG4ProfileSimple:
profile = "simple";
break;
case OMX_VIDEO_MPEG4ProfileSimpleScalable:
profile = "simple-scalable";
break;
case OMX_VIDEO_MPEG4ProfileCore:
profile = "core";
break;
case OMX_VIDEO_MPEG4ProfileMain:
profile = "main";
break;
case OMX_VIDEO_MPEG4ProfileNbit:
profile = "n-bit";
break;
case OMX_VIDEO_MPEG4ProfileScalableTexture:
profile = "scalable";
break;
case OMX_VIDEO_MPEG4ProfileSimpleFace:
profile = "simple-face";
break;
case OMX_VIDEO_MPEG4ProfileSimpleFBA:
profile = "simple-fba";
break;
case OMX_VIDEO_MPEG4ProfileBasicAnimated:
profile = "basic-animated-texture";
break;
case OMX_VIDEO_MPEG4ProfileHybrid:
profile = "hybrid";
break;
case OMX_VIDEO_MPEG4ProfileAdvancedRealTime:
profile = "advanced-real-time-simple";
break;
case OMX_VIDEO_MPEG4ProfileCoreScalable:
profile = "core-scalable";
break;
case OMX_VIDEO_MPEG4ProfileAdvancedCoding:
profile = "advanced-coding-efficiency";
break;
case OMX_VIDEO_MPEG4ProfileAdvancedCore:
profile = "advanced-core";
break;
case OMX_VIDEO_MPEG4ProfileAdvancedScalable:
profile = "advanced-scalable-texture";
break;
case OMX_VIDEO_MPEG4ProfileAdvancedSimple:
profile = "advanced-simple";
break;
default:
g_assert_not_reached ();
return NULL;
}
switch (param.eLevel) {
case OMX_VIDEO_MPEG4Level0:
level = "0";
break;
case OMX_VIDEO_MPEG4Level0b:
level = "0b";
break;
case OMX_VIDEO_MPEG4Level1:
level = "1";
break;
case OMX_VIDEO_MPEG4Level2:
level = "2";
break;
case OMX_VIDEO_MPEG4Level3:
level = "3";
break;
case OMX_VIDEO_MPEG4Level4:
level = "4";
break;
case OMX_VIDEO_MPEG4Level4a:
level = "4a";
break;
case OMX_VIDEO_MPEG4Level5:
level = "5";
break;
default:
g_assert_not_reached ();
return NULL;
}
gst_caps_set_simple (caps,
"profile", G_TYPE_STRING, profile, "level", G_TYPE_STRING, level, NULL);
}
return caps;
}

60
omx/gstomxmpeg4videoenc.h Normal file
View file

@ -0,0 +1,60 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_MPEG4_VIDEO_ENC_H__
#define __GST_OMX_MPEG4_VIDEO_ENC_H__
#include <gst/gst.h>
#include "gstomxvideoenc.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_MPEG4_VIDEO_ENC \
(gst_omx_mpeg4_video_enc_get_type())
#define GST_OMX_MPEG4_VIDEO_ENC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_MPEG4_VIDEO_ENC,GstOMXMPEG4VideoEnc))
#define GST_OMX_MPEG4_VIDEO_ENC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_MPEG4_VIDEO_ENC,GstOMXMPEG4VideoEncClass))
#define GST_OMX_MPEG4_VIDEO_ENC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_MPEG4_VIDEO_ENC,GstOMXMPEG4VideoEncClass))
#define GST_IS_OMX_MPEG4_VIDEO_ENC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_MPEG4_VIDEO_ENC))
#define GST_IS_OMX_MPEG4_VIDEO_ENC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_MPEG4_VIDEO_ENC))
typedef struct _GstOMXMPEG4VideoEnc GstOMXMPEG4VideoEnc;
typedef struct _GstOMXMPEG4VideoEncClass GstOMXMPEG4VideoEncClass;
struct _GstOMXMPEG4VideoEnc
{
GstOMXVideoEnc parent;
};
struct _GstOMXMPEG4VideoEncClass
{
GstOMXVideoEncClass parent_class;
};
GType gst_omx_mpeg4_video_enc_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_MPEG4_VIDEO_ENC_H__ */

157
omx/gstomxtheoradec.c Normal file
View file

@ -0,0 +1,157 @@
/*
* Copyright (C) 2013, Collabora Ltd.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxtheoradec.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_theora_dec_debug_category);
#define GST_CAT_DEFAULT gst_omx_theora_dec_debug_category
/* prototypes */
static gboolean gst_omx_theora_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
static gboolean gst_omx_theora_dec_set_format (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
static GstFlowReturn gst_omx_theora_dec_handle_frame (GstVideoDecoder * decoder,
GstVideoCodecFrame * frame);
static gboolean gst_omx_theora_dec_stop (GstVideoDecoder * decoder);
enum
{
PROP_0
};
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_theora_dec_debug_category, "omxtheoradec", 0, \
"debug category for gst-omx video decoder base class");
G_DEFINE_TYPE_WITH_CODE (GstOMXTheoraDec, gst_omx_theora_dec,
GST_TYPE_OMX_VIDEO_DEC, DEBUG_INIT);
static void
gst_omx_theora_dec_class_init (GstOMXTheoraDecClass * klass)
{
GstVideoDecoderClass *gstvideodec_class = GST_VIDEO_DECODER_CLASS (klass);
GstOMXVideoDecClass *videodec_class = GST_OMX_VIDEO_DEC_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
videodec_class->is_format_change =
GST_DEBUG_FUNCPTR (gst_omx_theora_dec_is_format_change);
videodec_class->set_format =
GST_DEBUG_FUNCPTR (gst_omx_theora_dec_set_format);
videodec_class->cdata.default_sink_template_caps = "video/x-theora, "
"width=(int) [1,MAX], " "height=(int) [1,MAX]";
gstvideodec_class->handle_frame = gst_omx_theora_dec_handle_frame;
gstvideodec_class->stop = gst_omx_theora_dec_stop;
gst_element_class_set_static_metadata (element_class,
"OpenMAX Theora Video Decoder",
"Codec/Decoder/Video/Hardware",
"Decode Theora video streams",
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
gst_omx_set_default_role (&videodec_class->cdata, "video_decoder.theora");
}
static void
gst_omx_theora_dec_init (GstOMXTheoraDec * self)
{
}
static gboolean
gst_omx_theora_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state)
{
return FALSE;
}
static gboolean
gst_omx_theora_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port,
GstVideoCodecState * state)
{
gboolean ret;
OMX_PARAM_PORTDEFINITIONTYPE port_def;
gst_omx_port_get_port_definition (port, &port_def);
port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingTheora;
ret = gst_omx_port_update_port_definition (port, &port_def) == OMX_ErrorNone;
return ret;
}
static GstFlowReturn
gst_omx_theora_dec_handle_frame (GstVideoDecoder * decoder,
GstVideoCodecFrame * frame)
{
GstOMXTheoraDec *self = GST_OMX_THEORA_DEC (decoder);
if (GST_BUFFER_FLAG_IS_SET (frame->input_buffer, GST_BUFFER_FLAG_HEADER)) {
guint16 size;
GstBuffer *sbuf;
if (!self->header) {
self->header = gst_buffer_new ();
gst_buffer_copy_into (self->header, frame->input_buffer,
GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
}
size = gst_buffer_get_size (frame->input_buffer);
size = GUINT16_TO_BE (size);
sbuf = gst_buffer_new_and_alloc (2);
gst_buffer_fill (sbuf, 0, &size, 2);
self->header = gst_buffer_append (self->header, sbuf);
self->header =
gst_buffer_append (self->header, gst_buffer_ref (frame->input_buffer));
gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
return GST_FLOW_OK;
}
if (self->header) {
gst_buffer_replace (&GST_OMX_VIDEO_DEC (self)->codec_data, self->header);
gst_buffer_unref (self->header);
self->header = NULL;
}
return
GST_VIDEO_DECODER_CLASS (gst_omx_theora_dec_parent_class)->handle_frame
(GST_VIDEO_DECODER (self), frame);
}
static gboolean
gst_omx_theora_dec_stop (GstVideoDecoder * decoder)
{
GstOMXTheoraDec *self = GST_OMX_THEORA_DEC (decoder);
gst_buffer_replace (&self->header, NULL);
return TRUE;
}

61
omx/gstomxtheoradec.h Normal file
View file

@ -0,0 +1,61 @@
/*
* Copyright (C) 2013, Collabora Ltd.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_THEORA_DEC_H__
#define __GST_OMX_THEORA_DEC_H__
#include <gst/gst.h>
#include "gstomxvideodec.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_THEORA_DEC \
(gst_omx_theora_dec_get_type())
#define GST_OMX_THEORA_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_THEORA_DEC,GstOMXTheoraDec))
#define GST_OMX_THEORA_DEC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_THEORA_DEC,GstOMXTheoraDecClass))
#define GST_OMX_THEORA_DEC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_THEORA_DEC,GstOMXTheoraDecClass))
#define GST_IS_OMX_THEORA_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_THEORA_DEC))
#define GST_IS_OMX_THEORA_DEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_THEORA_DEC))
typedef struct _GstOMXTheoraDec GstOMXTheoraDec;
typedef struct _GstOMXTheoraDecClass GstOMXTheoraDecClass;
struct _GstOMXTheoraDec
{
GstOMXVideoDec parent;
GstBuffer *header;
};
struct _GstOMXTheoraDecClass
{
GstOMXVideoDecClass parent_class;
};
GType gst_omx_theora_dec_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_THEORA_DEC_H__ */

356
omx/gstomxvideo.c Normal file
View file

@ -0,0 +1,356 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
* Copyright (C) 2013, Collabora Ltd.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> *
* Copyright 2014 Advanced Micro Devices, Inc.
* Author: Christian König <christian.koenig@amd.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstomxvideo.h"
#include <math.h>
GST_DEBUG_CATEGORY (gst_omx_video_debug_category);
#define GST_CAT_DEFAULT gst_omx_video_debug_category
/* Keep synced with GST_OMX_VIDEO_DEC_SUPPORTED_FORMATS */
GstVideoFormat
gst_omx_video_get_format_from_omx (OMX_COLOR_FORMATTYPE omx_colorformat)
{
GstVideoFormat format;
switch (omx_colorformat) {
case OMX_COLOR_FormatL8:
format = GST_VIDEO_FORMAT_GRAY8;
break;
case OMX_COLOR_FormatYUV420Planar:
case OMX_COLOR_FormatYUV420PackedPlanar:
format = GST_VIDEO_FORMAT_I420;
break;
case OMX_COLOR_FormatYUV420SemiPlanar:
case OMX_COLOR_FormatYUV420PackedSemiPlanar:
format = GST_VIDEO_FORMAT_NV12;
break;
case OMX_COLOR_FormatYUV422SemiPlanar:
format = GST_VIDEO_FORMAT_NV16;
break;
case OMX_COLOR_FormatYCbYCr:
format = GST_VIDEO_FORMAT_YUY2;
break;
case OMX_COLOR_FormatYCrYCb:
format = GST_VIDEO_FORMAT_YVYU;
break;
case OMX_COLOR_FormatCbYCrY:
format = GST_VIDEO_FORMAT_UYVY;
break;
case OMX_COLOR_Format32bitARGB8888:
/* There is a mismatch in omxil specification 4.2.1 between
* OMX_COLOR_Format32bitARGB8888 and its description
* Follow the description */
format = GST_VIDEO_FORMAT_ABGR;
break;
case OMX_COLOR_Format32bitBGRA8888:
/* Same issue as OMX_COLOR_Format32bitARGB8888 */
format = GST_VIDEO_FORMAT_ARGB;
break;
case OMX_COLOR_Format16bitRGB565:
format = GST_VIDEO_FORMAT_RGB16;
break;
case OMX_COLOR_Format16bitBGR565:
format = GST_VIDEO_FORMAT_BGR16;
break;
case OMX_COLOR_Format24bitBGR888:
format = GST_VIDEO_FORMAT_BGR;
break;
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
/* Formats defined in extensions have their own enum so disable to -Wswitch warning */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch"
case OMX_ALG_COLOR_FormatYUV420SemiPlanar10bitPacked:
format = GST_VIDEO_FORMAT_NV12_10LE32;
break;
case OMX_ALG_COLOR_FormatYUV422SemiPlanar10bitPacked:
format = GST_VIDEO_FORMAT_NV16_10LE32;
break;
#pragma GCC diagnostic pop
#endif
default:
format = GST_VIDEO_FORMAT_UNKNOWN;
break;
}
return format;
}
GList *
gst_omx_video_get_supported_colorformats (GstOMXPort * port,
GstVideoCodecState * state)
{
GstOMXComponent *comp = port->comp;
OMX_VIDEO_PARAM_PORTFORMATTYPE param;
OMX_ERRORTYPE err;
GList *negotiation_map = NULL;
gint old_index;
GstOMXVideoNegotiationMap *m;
GstVideoFormat f;
GST_OMX_INIT_STRUCT (&param);
param.nPortIndex = port->index;
param.nIndex = 0;
param.xFramerate =
state ? gst_omx_video_calculate_framerate_q16 (&state->info) : 0;
old_index = -1;
do {
err =
gst_omx_component_get_parameter (comp,
OMX_IndexParamVideoPortFormat, &param);
/* FIXME: Workaround for Bellagio that simply always
* returns the same value regardless of nIndex and
* never returns OMX_ErrorNoMore
*/
if (old_index == param.nIndex)
break;
if (err == OMX_ErrorNone || err == OMX_ErrorNoMore) {
f = gst_omx_video_get_format_from_omx (param.eColorFormat);
if (f != GST_VIDEO_FORMAT_UNKNOWN) {
m = g_slice_new (GstOMXVideoNegotiationMap);
m->format = f;
m->type = param.eColorFormat;
negotiation_map = g_list_append (negotiation_map, m);
GST_DEBUG_OBJECT (comp->parent,
"Component port %d supports %s (%d) at index %u", port->index,
gst_video_format_to_string (f), param.eColorFormat,
(guint) param.nIndex);
} else {
GST_DEBUG_OBJECT (comp->parent,
"Component port %d supports unsupported color format %d at index %u",
port->index, param.eColorFormat, (guint) param.nIndex);
}
}
old_index = param.nIndex++;
} while (err == OMX_ErrorNone);
return negotiation_map;
}
GstCaps *
gst_omx_video_get_caps_for_map (GList * map)
{
GstCaps *caps = gst_caps_new_empty ();
GList *l;
for (l = map; l; l = l->next) {
GstOMXVideoNegotiationMap *entry = l->data;
gst_caps_append_structure (caps,
gst_structure_new ("video/x-raw",
"format", G_TYPE_STRING,
gst_video_format_to_string (entry->format), NULL));
}
return caps;
}
void
gst_omx_video_negotiation_map_free (GstOMXVideoNegotiationMap * m)
{
g_slice_free (GstOMXVideoNegotiationMap, m);
}
GstVideoCodecFrame *
gst_omx_video_find_nearest_frame (GstElement * element, GstOMXBuffer * buf,
GList * frames)
{
GstVideoCodecFrame *best = NULL;
GstClockTimeDiff best_diff = G_MAXINT64;
GstClockTime timestamp;
GList *l;
timestamp =
gst_util_uint64_scale (GST_OMX_GET_TICKS (buf->omx_buf->nTimeStamp),
GST_SECOND, OMX_TICKS_PER_SECOND);
GST_LOG_OBJECT (element, "look for ts %" GST_TIME_FORMAT,
GST_TIME_ARGS (timestamp));
for (l = frames; l; l = l->next) {
GstVideoCodecFrame *tmp = l->data;
GstClockTimeDiff diff = ABS (GST_CLOCK_DIFF (timestamp, tmp->pts));
GST_LOG_OBJECT (element,
" frame %u diff %" G_GINT64_FORMAT " ts %" GST_TIME_FORMAT,
tmp->system_frame_number, diff, GST_TIME_ARGS (tmp->pts));
if (diff < best_diff) {
best = tmp;
best_diff = diff;
if (diff == 0)
break;
}
}
if (best) {
gst_video_codec_frame_ref (best);
/* OMX timestamps are in microseconds while gst ones are in nanoseconds.
* So if the difference between them is higher than 1 microsecond we likely
* picked the wrong frame. */
if (best_diff >= GST_USECOND)
GST_WARNING_OBJECT (element,
"Difference between ts (%" GST_TIME_FORMAT ") and frame %u (%"
GST_TIME_FORMAT ") seems too high (%" GST_TIME_FORMAT ")",
GST_TIME_ARGS (timestamp), best->system_frame_number,
GST_TIME_ARGS (best->pts), GST_TIME_ARGS (best_diff));
} else
GST_WARNING_OBJECT (element, "No best frame has been found");
g_list_foreach (frames, (GFunc) gst_video_codec_frame_unref, NULL);
g_list_free (frames);
return best;
}
OMX_U32
gst_omx_video_calculate_framerate_q16 (GstVideoInfo * info)
{
g_assert (info);
if (!info->fps_d)
return 0;
/* OMX API expects frame rate to actually be the field rate, so twice
* the frame rate in interlace mode. */
return gst_util_uint64_scale_int (1 << 16, GST_VIDEO_INFO_FIELD_RATE_N (info),
info->fps_d);
}
gboolean
gst_omx_video_is_equal_framerate_q16 (OMX_U32 q16_a, OMX_U32 q16_b)
{
/* If one of them is 0 use the classic comparison. The value 0 has a special
meaning and is used to indicate the frame rate is unknown, variable, or
is not needed. */
if (!q16_a || !q16_b)
return q16_a == q16_b;
/* If the 'percentage change' is less than 1% then consider it equal to avoid
* an unnecessary re-negotiation. */
return fabs (((gdouble) q16_a) - ((gdouble) q16_b)) / (gdouble) q16_b < 0.01;
}
gboolean
gst_omx_video_get_port_padding (GstOMXPort * port, GstVideoInfo * info_orig,
GstVideoAlignment * align)
{
guint nstride;
guint nslice_height;
GstVideoInfo info;
gsize plane_size[GST_VIDEO_MAX_PLANES];
gst_video_alignment_reset (align);
/* Create a copy of @info_orig without any offset/stride as we need a
* 'standard' version to compute the paddings. */
gst_video_info_init (&info);
gst_video_info_set_interlaced_format (&info,
GST_VIDEO_INFO_FORMAT (info_orig),
GST_VIDEO_INFO_INTERLACE_MODE (info_orig),
GST_VIDEO_INFO_WIDTH (info_orig), GST_VIDEO_INFO_HEIGHT (info_orig));
/* Retrieve the plane sizes */
if (!gst_video_info_align_full (&info, align, plane_size)) {
GST_WARNING_OBJECT (port->comp->parent, "Failed to retrieve plane sizes");
return FALSE;
}
nstride = port->port_def.format.video.nStride;
nslice_height = port->port_def.format.video.nSliceHeight;
if (nstride > GST_VIDEO_INFO_PLANE_STRIDE (&info, 0)) {
align->padding_right = nstride - GST_VIDEO_INFO_PLANE_STRIDE (&info, 0);
if (GST_VIDEO_FORMAT_INFO_IS_COMPLEX (info.finfo)) {
/* Stride is in bytes while padding is in pixels so we need to do manual
* conversions for complex formats. */
switch (GST_VIDEO_INFO_FORMAT (&info)) {
case GST_VIDEO_FORMAT_NV12_10LE32:
case GST_VIDEO_FORMAT_NV16_10LE32:
/* Need ((width + 2) / 3) 32-bits words to store one row,
* see unpack_NV12_10LE32 in -base.
*
* So let's say:
* - W = the width, in pixels
* - S = the stride, in bytes
* - P = the padding, in bytes
* - Δ = the padding, in pixels
*
* we then have:
* S = ((W+2)/3) * 4
* S+P = ((W+2+Δ)/3) * 4
*
* By solving this system we get:
* Δ = (3/4) * P
*/
align->padding_right *= 0.75;
break;
default:
GST_FIXME_OBJECT (port->comp->parent,
"Stride conversion is not supported for format %s",
GST_VIDEO_INFO_NAME (&info));
return FALSE;
}
}
GST_LOG_OBJECT (port->comp->parent,
"OMX stride (%d) is higher than standard (%d) for port %u; right padding: %d",
nstride, GST_VIDEO_INFO_PLANE_STRIDE (&info, 0), port->index,
align->padding_right);
}
if (nslice_height > GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size)) {
align->padding_bottom =
nslice_height - GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size);
if (GST_VIDEO_INFO_INTERLACE_MODE (&info) ==
GST_VIDEO_INTERLACE_MODE_ALTERNATE) {
/* GstVideoAlignment defines the alignment for the full frame while
* OMX gives us the slice height for a single field, so we have to
* double the vertical padding. */
GST_DEBUG_OBJECT (port->comp->parent,
"Double bottom padding because of alternate stream");
align->padding_bottom *= 2;
}
GST_LOG_OBJECT (port->comp->parent,
"OMX slice height (%d) is higher than standard (%" G_GSIZE_FORMAT
") for port %u; vertical padding: %d", nslice_height,
GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size), port->index,
align->padding_bottom);
}
return TRUE;
}

74
omx/gstomxvideo.h Normal file
View file

@ -0,0 +1,74 @@
/*
* Copyright 2014 Advanced Micro Devices, Inc.
* Author: Christian König <christian.koenig@amd.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_VIDEO_H__
#define __GST_OMX_VIDEO_H__
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/video/gstvideodecoder.h>
#include <gst/video/gstvideoencoder.h>
#include "gstomx.h"
G_BEGIN_DECLS
/* Keep synced with gst_omx_video_get_format_from_omx(). Sort by decreasing quality */
#define GST_OMX_VIDEO_DEC_SUPPORTED_FORMATS "{ NV16_10LE32, NV12_10LE32, " \
"NV16, YUY2, YVYU, UYVY, NV12, I420, RGB16, BGR16, ABGR, ARGB, GRAY8 }"
#define GST_OMX_VIDEO_ENC_SUPPORTED_FORMATS "{ NV16_10LE32, NV12_10LE32, " \
"NV16, NV12, I420, GRAY8 }"
typedef struct
{
GstVideoFormat format;
OMX_COLOR_FORMATTYPE type;
} GstOMXVideoNegotiationMap;
GstVideoFormat
gst_omx_video_get_format_from_omx (OMX_COLOR_FORMATTYPE omx_colorformat);
GList *
gst_omx_video_get_supported_colorformats (GstOMXPort * port,
GstVideoCodecState * state);
GstCaps * gst_omx_video_get_caps_for_map(GList * map);
void
gst_omx_video_negotiation_map_free (GstOMXVideoNegotiationMap * m);
GstVideoCodecFrame *
gst_omx_video_find_nearest_frame (GstElement * element, GstOMXBuffer * buf, GList * frames);
OMX_U32 gst_omx_video_calculate_framerate_q16 (GstVideoInfo * info);
gboolean gst_omx_video_is_equal_framerate_q16 (OMX_U32 q16_a, OMX_U32 q16_b);
gboolean gst_omx_video_get_port_padding (GstOMXPort * port, GstVideoInfo * info_orig,
GstVideoAlignment * align);
G_END_DECLS
#endif /* __GST_OMX_VIDEO_H__ */

3524
omx/gstomxvideodec.c Normal file

File diff suppressed because it is too large Load diff

119
omx/gstomxvideodec.h Normal file
View file

@ -0,0 +1,119 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_VIDEO_DEC_H__
#define __GST_OMX_VIDEO_DEC_H__
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/video/gstvideodecoder.h>
#include "gstomx.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_VIDEO_DEC \
(gst_omx_video_dec_get_type())
#define GST_OMX_VIDEO_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_VIDEO_DEC,GstOMXVideoDec))
#define GST_OMX_VIDEO_DEC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_VIDEO_DEC,GstOMXVideoDecClass))
#define GST_OMX_VIDEO_DEC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_VIDEO_DEC,GstOMXVideoDecClass))
#define GST_IS_OMX_VIDEO_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_VIDEO_DEC))
#define GST_IS_OMX_VIDEO_DEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_VIDEO_DEC))
typedef struct _GstOMXVideoDec GstOMXVideoDec;
typedef struct _GstOMXVideoDecClass GstOMXVideoDecClass;
struct _GstOMXVideoDec
{
GstVideoDecoder parent;
/* < protected > */
GstOMXComponent *dec;
GstOMXPort *dec_in_port, *dec_out_port;
GstBufferPool *in_port_pool, *out_port_pool;
/* < private > */
GstVideoCodecState *input_state;
GstBuffer *codec_data;
/* TRUE if the component is configured and saw
* the first buffer */
gboolean started;
/* TRUE if the ports where disabled after being activated the first time. */
gboolean disabled;
GstClockTime last_upstream_ts;
/* Draining state */
GMutex drain_lock;
GCond drain_cond;
/* TRUE if EOS buffers shouldn't be forwarded */
gboolean draining; /* protected by drain_lock */
GstFlowReturn downstream_flow_ret;
/* Initially FALSE. Switched to TRUE when all requirements
* are met to try setting up the decoder with OMX_UseBuffer.
* Switched to FALSE if this trial fails so that the decoder
* can fallback to OMX_AllocateBuffer. */
gboolean use_buffers;
#if defined (USE_OMX_TARGET_RPI)
GstOMXComponent *egl_render;
GstOMXPort *egl_in_port, *egl_out_port;
#endif
#if defined (HAVE_GST_GL)
gboolean eglimage;
#endif
/* TRUE if decoder is producing dmabuf */
gboolean dmabuf;
GstOMXBufferAllocation input_allocation;
/* properties */
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
guint32 internal_entropy_buffers;
#endif
};
struct _GstOMXVideoDecClass
{
GstVideoDecoderClass parent_class;
GstOMXClassData cdata;
gboolean (*is_format_change) (GstOMXVideoDec * self, GstOMXPort * port, GstVideoCodecState * state);
gboolean (*set_format) (GstOMXVideoDec * self, GstOMXPort * port, GstVideoCodecState * state);
};
GType gst_omx_video_dec_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_VIDEO_DEC_H__ */

3732
omx/gstomxvideoenc.c Normal file

File diff suppressed because it is too large Load diff

133
omx/gstomxvideoenc.h Normal file
View file

@ -0,0 +1,133 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_VIDEO_ENC_H__
#define __GST_OMX_VIDEO_ENC_H__
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/video/gstvideoencoder.h>
#include "gstomx.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_VIDEO_ENC \
(gst_omx_video_enc_get_type())
#define GST_OMX_VIDEO_ENC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_VIDEO_ENC,GstOMXVideoEnc))
#define GST_OMX_VIDEO_ENC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_VIDEO_ENC,GstOMXVideoEncClass))
#define GST_OMX_VIDEO_ENC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_VIDEO_ENC,GstOMXVideoEncClass))
#define GST_IS_OMX_VIDEO_ENC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_VIDEO_ENC))
#define GST_IS_OMX_VIDEO_ENC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_VIDEO_ENC))
typedef struct _GstOMXVideoEnc GstOMXVideoEnc;
typedef struct _GstOMXVideoEncClass GstOMXVideoEncClass;
struct _GstOMXVideoEnc
{
GstVideoEncoder parent;
/* < protected > */
GstOMXComponent *enc;
GstOMXPort *enc_in_port, *enc_out_port;
/* < private > */
GstVideoCodecState *input_state;
/* TRUE if the component is configured and saw
* the first buffer */
gboolean started;
/* TRUE if the ports where disabled after being activated the first time. */
gboolean disabled;
GstClockTime last_upstream_ts;
/* Draining state */
GMutex drain_lock;
GCond drain_cond;
/* TRUE if EOS buffers shouldn't be forwarded */
gboolean draining; /* protected by drain_lock */
/* properties */
guint32 control_rate;
guint32 target_bitrate; /* protected by object lock */
guint32 quant_i_frames;
guint32 quant_p_frames;
guint32 quant_b_frames;
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
guint32 qp_mode;
guint32 min_qp;
guint32 max_qp;
guint32 gop_mode;
guint32 gdr_mode;
guint32 initial_delay;
guint32 cpb_size;
guint32 scaling_list;
gboolean low_bandwidth;
guint32 max_bitrate;
guint32 aspect_ratio;
gboolean filler_data;
guint32 num_slices;
guint32 slice_size;
gboolean dependent_slice;
gint default_roi_quality;
gboolean long_term_ref;
guint32 long_term_freq;
guint32 look_ahead;
#endif
guint32 default_target_bitrate;
GstFlowReturn downstream_flow_ret;
GstOMXBufferAllocation input_allocation;
/* TRUE if encoder is passing dmabuf's fd directly to the OMX component */
gboolean input_dmabuf;
/* Number of buffers requested downstream */
guint nb_downstream_buffers;
/* TRUE if input buffers are from the pool we proposed to upstream */
gboolean in_pool_used;
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
GEnumClass *alg_roi_quality_enum_class;
#endif
};
struct _GstOMXVideoEncClass
{
GstVideoEncoderClass parent_class;
GstOMXClassData cdata;
gboolean (*set_format) (GstOMXVideoEnc * self, GstOMXPort * port, GstVideoCodecState * state);
GstCaps *(*get_caps) (GstOMXVideoEnc * self, GstOMXPort * port, GstVideoCodecState * state);
GstFlowReturn (*handle_output_frame) (GstOMXVideoEnc * self, GstOMXPort * port, GstOMXBuffer * buffer, GstVideoCodecFrame * frame);
};
GType gst_omx_video_enc_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_VIDEO_ENC_H__ */

99
omx/gstomxvp8dec.c Normal file
View file

@ -0,0 +1,99 @@
/*
* Copyright (C) 2013, Collabora Ltd.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxvp8dec.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_vp8_dec_debug_category);
#define GST_CAT_DEFAULT gst_omx_vp8_dec_debug_category
/* prototypes */
static gboolean gst_omx_vp8_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
static gboolean gst_omx_vp8_dec_set_format (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
enum
{
PROP_0
};
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_vp8_dec_debug_category, "omxvp8dec", 0, \
"debug category for gst-omx video decoder base class");
G_DEFINE_TYPE_WITH_CODE (GstOMXVP8Dec, gst_omx_vp8_dec,
GST_TYPE_OMX_VIDEO_DEC, DEBUG_INIT);
static void
gst_omx_vp8_dec_class_init (GstOMXVP8DecClass * klass)
{
GstOMXVideoDecClass *videodec_class = GST_OMX_VIDEO_DEC_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
videodec_class->is_format_change =
GST_DEBUG_FUNCPTR (gst_omx_vp8_dec_is_format_change);
videodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_vp8_dec_set_format);
videodec_class->cdata.default_sink_template_caps = "video/x-vp8, "
"width=(int) [1,MAX], " "height=(int) [1,MAX]";
gst_element_class_set_static_metadata (element_class,
"OpenMAX VP8 Video Decoder",
"Codec/Decoder/Video/Hardware",
"Decode VP8 video streams",
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
gst_omx_set_default_role (&videodec_class->cdata, "video_decoder.vp8");
}
static void
gst_omx_vp8_dec_init (GstOMXVP8Dec * self)
{
}
static gboolean
gst_omx_vp8_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state)
{
return FALSE;
}
static gboolean
gst_omx_vp8_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port,
GstVideoCodecState * state)
{
gboolean ret;
OMX_PARAM_PORTDEFINITIONTYPE port_def;
gst_omx_port_get_port_definition (port, &port_def);
port_def.format.video.eCompressionFormat =
(OMX_VIDEO_CODINGTYPE) OMX_VIDEO_CodingVP8;
ret = gst_omx_port_update_port_definition (port, &port_def) == OMX_ErrorNone;
return ret;
}

60
omx/gstomxvp8dec.h Normal file
View file

@ -0,0 +1,60 @@
/*
* Copyright (C) 2013, Collabora Ltd.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_VP8_DEC_H__
#define __GST_OMX_VP8_DEC_H__
#include <gst/gst.h>
#include "gstomxvideodec.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_VP8_DEC \
(gst_omx_vp8_dec_get_type())
#define GST_OMX_VP8_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_VP8_DEC,GstOMXVP8Dec))
#define GST_OMX_VP8_DEC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_VP8_DEC,GstOMXVP8DecClass))
#define GST_OMX_VP8_DEC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_VP8_DEC,GstOMXVP8DecClass))
#define GST_IS_OMX_VP8_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_VP8_DEC))
#define GST_IS_OMX_VP8_DEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_VP8_DEC))
typedef struct _GstOMXVP8Dec GstOMXVP8Dec;
typedef struct _GstOMXVP8DecClass GstOMXVP8DecClass;
struct _GstOMXVP8Dec
{
GstOMXVideoDec parent;
};
struct _GstOMXVP8DecClass
{
GstOMXVideoDecClass parent_class;
};
GType gst_omx_vp8_dec_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_VP8_DEC_H__ */

98
omx/gstomxwmvdec.c Normal file
View file

@ -0,0 +1,98 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstomxwmvdec.h"
GST_DEBUG_CATEGORY_STATIC (gst_omx_wmv_dec_debug_category);
#define GST_CAT_DEFAULT gst_omx_wmv_dec_debug_category
/* prototypes */
static gboolean gst_omx_wmv_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
static gboolean gst_omx_wmv_dec_set_format (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state);
enum
{
PROP_0
};
/* class initialization */
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_omx_wmv_dec_debug_category, "omxwmvdec", 0, \
"debug category for gst-omx video decoder base class");
G_DEFINE_TYPE_WITH_CODE (GstOMXWMVDec, gst_omx_wmv_dec,
GST_TYPE_OMX_VIDEO_DEC, DEBUG_INIT);
static void
gst_omx_wmv_dec_class_init (GstOMXWMVDecClass * klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstOMXVideoDecClass *videodec_class = GST_OMX_VIDEO_DEC_CLASS (klass);
videodec_class->is_format_change =
GST_DEBUG_FUNCPTR (gst_omx_wmv_dec_is_format_change);
videodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_wmv_dec_set_format);
videodec_class->cdata.default_sink_template_caps = "video/x-wmv, "
"width=(int) [1,MAX], " "height=(int) [1,MAX]";
gst_element_class_set_static_metadata (element_class,
"OpenMAX WMV Video Decoder",
"Codec/Decoder/Video/Hardware",
"Decode WMV video streams",
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
gst_omx_set_default_role (&videodec_class->cdata, "video_decoder.wmv");
}
static void
gst_omx_wmv_dec_init (GstOMXWMVDec * self)
{
}
static gboolean
gst_omx_wmv_dec_is_format_change (GstOMXVideoDec * dec,
GstOMXPort * port, GstVideoCodecState * state)
{
return FALSE;
}
static gboolean
gst_omx_wmv_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port,
GstVideoCodecState * state)
{
gboolean ret;
OMX_PARAM_PORTDEFINITIONTYPE port_def;
gst_omx_port_get_port_definition (port, &port_def);
port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV;
ret = gst_omx_port_update_port_definition (port, &port_def) == OMX_ErrorNone;
return ret;
}

60
omx/gstomxwmvdec.h Normal file
View file

@ -0,0 +1,60 @@
/*
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_OMX_WMV_DEC_H__
#define __GST_OMX_WMV_DEC_H__
#include <gst/gst.h>
#include "gstomxvideodec.h"
G_BEGIN_DECLS
#define GST_TYPE_OMX_WMV_DEC \
(gst_omx_wmv_dec_get_type())
#define GST_OMX_WMV_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_WMV_DEC,GstOMXWMVDec))
#define GST_OMX_WMV_DEC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_WMV_DEC,GstOMXWMVDecClass))
#define GST_OMX_WMV_DEC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_WMV_DEC,GstOMXWMVDecClass))
#define GST_IS_OMX_WMV_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_WMV_DEC))
#define GST_IS_OMX_WMV_DEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_WMV_DEC))
typedef struct _GstOMXWMVDec GstOMXWMVDec;
typedef struct _GstOMXWMVDecClass GstOMXWMVDecClass;
struct _GstOMXWMVDec
{
GstOMXVideoDec parent;
};
struct _GstOMXWMVDecClass
{
GstOMXVideoDecClass parent_class;
};
GType gst_omx_wmv_dec_get_type (void);
G_END_DECLS
#endif /* __GST_OMX_WMV_DEC_H__ */

63
omx/meson.build Normal file
View file

@ -0,0 +1,63 @@
omx_sources = [
'gstomx.c',
'gstomxallocator.c',
'gstomxbufferpool.c',
'gstomxvideo.c',
'gstomxvideodec.c',
'gstomxvideoenc.c',
'gstomxaudiodec.c',
'gstomxaudioenc.c',
'gstomxmjpegdec.c',
'gstomxmpeg4videodec.c',
'gstomxmpeg2videodec.c',
'gstomxh264dec.c',
'gstomxh264utils.c',
'gstomxh263dec.c',
'gstomxwmvdec.c',
'gstomxmpeg4videoenc.c',
'gstomxh264enc.c',
'gstomxh263enc.c',
'gstomxaacdec.c',
'gstomxmp3dec.c',
'gstomxaacenc.c',
'gstomxamrdec.c',
'gstomxaudiosink.c',
'gstomxanalogaudiosink.c',
'gstomxhdmiaudiosink.c',
'gstomxmp3enc.c',
]
extra_c_args = []
if have_omx_vp8
omx_sources += 'gstomxvp8dec.c'
endif
if have_omx_theora
omx_sources += 'gstomxtheoradec.c'
endif
if have_omx_hevc
omx_sources += 'gstomxh265utils.c'
omx_sources += 'gstomxh265enc.c'
omx_sources += 'gstomxh265dec.c'
endif
optional_deps = []
if gstgl_dep.found()
optional_deps += gstgl_dep
extra_c_args += ['-DGST_USE_UNSTABLE_API']
endif
gstomx = library('gstomx',
omx_sources,
c_args : gst_omx_args + extra_c_args,
# link_args : noseh_link_args,
include_directories : [configinc, omx_inc],
dependencies : [gstvideo_dep, gstaudio_dep, gstbase_dep, gstcontroller_dep,
libm, gmodule_dep, gstallocators_dep] + optional_deps,
install : true,
install_dir : plugins_install_dir,
)
plugins = [gstomx]

1311
omx/openmax/OMX_Audio.h Normal file

File diff suppressed because it is too large Load diff

579
omx/openmax/OMX_Component.h Normal file
View file

@ -0,0 +1,579 @@
/*
* Copyright (c) 2008 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
/** OMX_Component.h - OpenMax IL version 1.1.2
* The OMX_Component header file contains the definitions used to define
* the public interface of a component. This header file is intended to
* be used by both the application and the component.
*/
#ifndef OMX_Component_h
#define OMX_Component_h
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Each OMX header must include all required header files to allow the
* header to compile without errors. The includes below are required
* for this header file to compile successfully
*/
#include <OMX_Audio.h>
#include <OMX_Video.h>
#include <OMX_Image.h>
#include <OMX_Other.h>
/** @ingroup comp */
typedef enum OMX_PORTDOMAINTYPE {
OMX_PortDomainAudio,
OMX_PortDomainVideo,
OMX_PortDomainImage,
OMX_PortDomainOther,
OMX_PortDomainKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_PortDomainVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_PortDomainMax = 0x7ffffff
} OMX_PORTDOMAINTYPE;
/** @ingroup comp */
typedef struct OMX_PARAM_PORTDEFINITIONTYPE {
OMX_U32 nSize; /**< Size of the structure in bytes */
OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
OMX_U32 nPortIndex; /**< Port number the structure applies to */
OMX_DIRTYPE eDir; /**< Direction (input or output) of this port */
OMX_U32 nBufferCountActual; /**< The actual number of buffers allocated on this port */
OMX_U32 nBufferCountMin; /**< The minimum number of buffers this port requires */
OMX_U32 nBufferSize; /**< Size, in bytes, for buffers to be used for this channel */
OMX_BOOL bEnabled; /**< Ports default to enabled and are enabled/disabled by
OMX_CommandPortEnable/OMX_CommandPortDisable.
When disabled a port is unpopulated. A disabled port
is not populated with buffers on a transition to IDLE. */
OMX_BOOL bPopulated; /**< Port is populated with all of its buffers as indicated by
nBufferCountActual. A disabled port is always unpopulated.
An enabled port is populated on a transition to OMX_StateIdle
and unpopulated on a transition to loaded. */
OMX_PORTDOMAINTYPE eDomain; /**< Domain of the port. Determines the contents of metadata below. */
union {
OMX_AUDIO_PORTDEFINITIONTYPE audio;
OMX_VIDEO_PORTDEFINITIONTYPE video;
OMX_IMAGE_PORTDEFINITIONTYPE image;
OMX_OTHER_PORTDEFINITIONTYPE other;
} format;
OMX_BOOL bBuffersContiguous;
OMX_U32 nBufferAlignment;
} OMX_PARAM_PORTDEFINITIONTYPE;
/** @ingroup comp */
typedef struct OMX_PARAM_U32TYPE {
OMX_U32 nSize; /**< Size of this structure, in Bytes */
OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
OMX_U32 nPortIndex; /**< port that this structure applies to */
OMX_U32 nU32; /**< U32 value */
} OMX_PARAM_U32TYPE;
/** @ingroup rpm */
typedef enum OMX_SUSPENSIONPOLICYTYPE {
OMX_SuspensionDisabled, /**< No suspension; v1.0 behavior */
OMX_SuspensionEnabled, /**< Suspension allowed */
OMX_SuspensionPolicyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_SuspensionPolicyStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_SuspensionPolicyMax = 0x7fffffff
} OMX_SUSPENSIONPOLICYTYPE;
/** @ingroup rpm */
typedef struct OMX_PARAM_SUSPENSIONPOLICYTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_SUSPENSIONPOLICYTYPE ePolicy;
} OMX_PARAM_SUSPENSIONPOLICYTYPE;
/** @ingroup rpm */
typedef enum OMX_SUSPENSIONTYPE {
OMX_NotSuspended, /**< component is not suspended */
OMX_Suspended, /**< component is suspended */
OMX_SuspensionKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_SuspensionVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_SuspendMax = 0x7FFFFFFF
} OMX_SUSPENSIONTYPE;
/** @ingroup rpm */
typedef struct OMX_PARAM_SUSPENSIONTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_SUSPENSIONTYPE eType;
} OMX_PARAM_SUSPENSIONTYPE ;
typedef struct OMX_CONFIG_BOOLEANTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_BOOL bEnabled;
} OMX_CONFIG_BOOLEANTYPE;
/* Parameter specifying the content uri to use. */
/** @ingroup cp */
typedef struct OMX_PARAM_CONTENTURITYPE
{
OMX_U32 nSize; /**< size of the structure in bytes, including
actual URI name */
OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
OMX_U8 contentURI[1]; /**< The URI name */
} OMX_PARAM_CONTENTURITYPE;
/* Parameter specifying the pipe to use. */
/** @ingroup cp */
typedef struct OMX_PARAM_CONTENTPIPETYPE
{
OMX_U32 nSize; /**< size of the structure in bytes */
OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
OMX_HANDLETYPE hPipe; /**< The pipe handle*/
} OMX_PARAM_CONTENTPIPETYPE;
/** @ingroup rpm */
typedef struct OMX_RESOURCECONCEALMENTTYPE {
OMX_U32 nSize; /**< size of the structure in bytes */
OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
OMX_BOOL bResourceConcealmentForbidden; /**< disallow the use of resource concealment
methods (like degrading algorithm quality to
lower resource consumption or functional bypass)
on a component as a resolution to resource conflicts. */
} OMX_RESOURCECONCEALMENTTYPE;
/** @ingroup metadata */
typedef enum OMX_METADATACHARSETTYPE {
OMX_MetadataCharsetUnknown = 0,
OMX_MetadataCharsetASCII,
OMX_MetadataCharsetBinary,
OMX_MetadataCharsetCodePage1252,
OMX_MetadataCharsetUTF8,
OMX_MetadataCharsetJavaConformantUTF8,
OMX_MetadataCharsetUTF7,
OMX_MetadataCharsetImapUTF7,
OMX_MetadataCharsetUTF16LE,
OMX_MetadataCharsetUTF16BE,
OMX_MetadataCharsetGB12345,
OMX_MetadataCharsetHZGB2312,
OMX_MetadataCharsetGB2312,
OMX_MetadataCharsetGB18030,
OMX_MetadataCharsetGBK,
OMX_MetadataCharsetBig5,
OMX_MetadataCharsetISO88591,
OMX_MetadataCharsetISO88592,
OMX_MetadataCharsetISO88593,
OMX_MetadataCharsetISO88594,
OMX_MetadataCharsetISO88595,
OMX_MetadataCharsetISO88596,
OMX_MetadataCharsetISO88597,
OMX_MetadataCharsetISO88598,
OMX_MetadataCharsetISO88599,
OMX_MetadataCharsetISO885910,
OMX_MetadataCharsetISO885913,
OMX_MetadataCharsetISO885914,
OMX_MetadataCharsetISO885915,
OMX_MetadataCharsetShiftJIS,
OMX_MetadataCharsetISO2022JP,
OMX_MetadataCharsetISO2022JP1,
OMX_MetadataCharsetISOEUCJP,
OMX_MetadataCharsetSMS7Bit,
OMX_MetadataCharsetKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_MetadataCharsetVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_MetadataCharsetTypeMax= 0x7FFFFFFF
} OMX_METADATACHARSETTYPE;
/** @ingroup metadata */
typedef enum OMX_METADATASCOPETYPE
{
OMX_MetadataScopeAllLevels,
OMX_MetadataScopeTopLevel,
OMX_MetadataScopePortLevel,
OMX_MetadataScopeNodeLevel,
OMX_MetadataScopeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_MetadataScopeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_MetadataScopeTypeMax = 0x7fffffff
} OMX_METADATASCOPETYPE;
/** @ingroup metadata */
typedef enum OMX_METADATASEARCHMODETYPE
{
OMX_MetadataSearchValueSizeByIndex,
OMX_MetadataSearchItemByIndex,
OMX_MetadataSearchNextItemByKey,
OMX_MetadataSearchKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_MetadataSearchVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_MetadataSearchTypeMax = 0x7fffffff
} OMX_METADATASEARCHMODETYPE;
/** @ingroup metadata */
typedef struct OMX_CONFIG_METADATAITEMCOUNTTYPE
{
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_METADATASCOPETYPE eScopeMode;
OMX_U32 nScopeSpecifier;
OMX_U32 nMetadataItemCount;
} OMX_CONFIG_METADATAITEMCOUNTTYPE;
/** @ingroup metadata */
typedef struct OMX_CONFIG_METADATAITEMTYPE
{
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_METADATASCOPETYPE eScopeMode;
OMX_U32 nScopeSpecifier;
OMX_U32 nMetadataItemIndex;
OMX_METADATASEARCHMODETYPE eSearchMode;
OMX_METADATACHARSETTYPE eKeyCharset;
OMX_U8 nKeySizeUsed;
OMX_U8 nKey[128];
OMX_METADATACHARSETTYPE eValueCharset;
OMX_STRING sLanguageCountry;
OMX_U32 nValueMaxSize;
OMX_U32 nValueSizeUsed;
OMX_U8 nValue[1];
} OMX_CONFIG_METADATAITEMTYPE;
/* @ingroup metadata */
typedef struct OMX_CONFIG_CONTAINERNODECOUNTTYPE
{
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_BOOL bAllKeys;
OMX_U32 nParentNodeID;
OMX_U32 nNumNodes;
} OMX_CONFIG_CONTAINERNODECOUNTTYPE;
/** @ingroup metadata */
typedef struct OMX_CONFIG_CONTAINERNODEIDTYPE
{
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_BOOL bAllKeys;
OMX_U32 nParentNodeID;
OMX_U32 nNodeIndex;
OMX_U32 nNodeID;
OMX_STRING cNodeName;
OMX_BOOL bIsLeafType;
} OMX_CONFIG_CONTAINERNODEIDTYPE;
/** @ingroup metadata */
typedef struct OMX_PARAM_METADATAFILTERTYPE
{
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_BOOL bAllKeys; /* if true then this structure refers to all keys and
* the three key fields below are ignored */
OMX_METADATACHARSETTYPE eKeyCharset;
OMX_U32 nKeySizeUsed;
OMX_U8 nKey [128];
OMX_U32 nLanguageCountrySizeUsed;
OMX_U8 nLanguageCountry[128];
OMX_BOOL bEnabled; /* if true then key is part of filter (e.g.
* retained for query later). If false then
* key is not part of filter */
} OMX_PARAM_METADATAFILTERTYPE;
/** The OMX_HANDLETYPE structure defines the component handle. The component
* handle is used to access all of the component's public methods and also
* contains pointers to the component's private data area. The component
* handle is initialized by the OMX core (with help from the component)
* during the process of loading the component. After the component is
* successfully loaded, the application can safely access any of the
* component's public functions (although some may return an error because
* the state is inappropriate for the access).
*
* @ingroup comp
*/
typedef struct OMX_COMPONENTTYPE
{
/** The size of this structure, in bytes. It is the responsibility
of the allocator of this structure to fill in this value. Since
this structure is allocated by the GetHandle function, this
function will fill in this value. */
OMX_U32 nSize;
/** nVersion is the version of the OMX specification that the structure
is built against. It is the responsibility of the creator of this
structure to initialize this value and every user of this structure
should verify that it knows how to use the exact version of
this structure found herein. */
OMX_VERSIONTYPE nVersion;
/** pComponentPrivate is a pointer to the component private data area.
This member is allocated and initialized by the component when the
component is first loaded. The application should not access this
data area. */
OMX_PTR pComponentPrivate;
/** pApplicationPrivate is a pointer that is a parameter to the
OMX_GetHandle method, and contains an application private value
provided by the IL client. This application private data is
returned to the IL Client by OMX in all callbacks */
OMX_PTR pApplicationPrivate;
/** refer to OMX_GetComponentVersion in OMX_core.h or the OMX IL
specification for details on the GetComponentVersion method.
*/
OMX_ERRORTYPE (*GetComponentVersion)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_OUT OMX_STRING pComponentName,
OMX_OUT OMX_VERSIONTYPE* pComponentVersion,
OMX_OUT OMX_VERSIONTYPE* pSpecVersion,
OMX_OUT OMX_UUIDTYPE* pComponentUUID);
/** refer to OMX_SendCommand in OMX_core.h or the OMX IL
specification for details on the SendCommand method.
*/
OMX_ERRORTYPE (*SendCommand)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_COMMANDTYPE Cmd,
OMX_IN OMX_U32 nParam1,
OMX_IN OMX_PTR pCmdData);
/** refer to OMX_GetParameter in OMX_core.h or the OMX IL
specification for details on the GetParameter method.
*/
OMX_ERRORTYPE (*GetParameter)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nParamIndex,
OMX_INOUT OMX_PTR pComponentParameterStructure);
/** refer to OMX_SetParameter in OMX_core.h or the OMX IL
specification for details on the SetParameter method.
*/
OMX_ERRORTYPE (*SetParameter)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_IN OMX_PTR pComponentParameterStructure);
/** refer to OMX_GetConfig in OMX_core.h or the OMX IL
specification for details on the GetConfig method.
*/
OMX_ERRORTYPE (*GetConfig)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_INOUT OMX_PTR pComponentConfigStructure);
/** refer to OMX_SetConfig in OMX_core.h or the OMX IL
specification for details on the SetConfig method.
*/
OMX_ERRORTYPE (*SetConfig)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_IN OMX_PTR pComponentConfigStructure);
/** refer to OMX_GetExtensionIndex in OMX_core.h or the OMX IL
specification for details on the GetExtensionIndex method.
*/
OMX_ERRORTYPE (*GetExtensionIndex)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_STRING cParameterName,
OMX_OUT OMX_INDEXTYPE* pIndexType);
/** refer to OMX_GetState in OMX_core.h or the OMX IL
specification for details on the GetState method.
*/
OMX_ERRORTYPE (*GetState)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_OUT OMX_STATETYPE* pState);
/** The ComponentTunnelRequest method will interact with another OMX
component to determine if tunneling is possible and to setup the
tunneling. The return codes for this method can be used to
determine if tunneling is not possible, or if tunneling is not
supported.
Base profile components (i.e. non-interop) do not support this
method and should return OMX_ErrorNotImplemented
The interop profile component MUST support tunneling to another
interop profile component with a compatible port parameters.
A component may also support proprietary communication.
If proprietary communication is supported the negotiation of
proprietary communication is done outside of OMX in a vendor
specific way. It is only required that the proper result be
returned and the details of how the setup is done is left
to the component implementation.
When this method is invoked when nPort in an output port, the
component will:
1. Populate the pTunnelSetup structure with the output port's
requirements and constraints for the tunnel.
When this method is invoked when nPort in an input port, the
component will:
1. Query the necessary parameters from the output port to
determine if the ports are compatible for tunneling
2. If the ports are compatible, the component should store
the tunnel step provided by the output port
3. Determine which port (either input or output) is the buffer
supplier, and call OMX_SetParameter on the output port to
indicate this selection.
The component will return from this call within 5 msec.
@param [in] hComp
Handle of the component to be accessed. This is the component
handle returned by the call to the OMX_GetHandle method.
@param [in] nPort
nPort is used to select the port on the component to be used
for tunneling.
@param [in] hTunneledComp
Handle of the component to tunnel with. This is the component
handle returned by the call to the OMX_GetHandle method. When
this parameter is 0x0 the component should setup the port for
communication with the application / IL Client.
@param [in] nPortOutput
nPortOutput is used indicate the port the component should
tunnel with.
@param [in] pTunnelSetup
Pointer to the tunnel setup structure. When nPort is an output port
the component should populate the fields of this structure. When
When nPort is an input port the component should review the setup
provided by the component with the output port.
@return OMX_ERRORTYPE
If the command successfully executes, the return code will be
OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
@ingroup tun
*/
OMX_ERRORTYPE (*ComponentTunnelRequest)(
OMX_IN OMX_HANDLETYPE hComp,
OMX_IN OMX_U32 nPort,
OMX_IN OMX_HANDLETYPE hTunneledComp,
OMX_IN OMX_U32 nTunneledPort,
OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup);
/** refer to OMX_UseBuffer in OMX_core.h or the OMX IL
specification for details on the UseBuffer method.
@ingroup buf
*/
OMX_ERRORTYPE (*UseBuffer)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
OMX_IN OMX_U32 nPortIndex,
OMX_IN OMX_PTR pAppPrivate,
OMX_IN OMX_U32 nSizeBytes,
OMX_IN OMX_U8* pBuffer);
/** refer to OMX_AllocateBuffer in OMX_core.h or the OMX IL
specification for details on the AllocateBuffer method.
@ingroup buf
*/
OMX_ERRORTYPE (*AllocateBuffer)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer,
OMX_IN OMX_U32 nPortIndex,
OMX_IN OMX_PTR pAppPrivate,
OMX_IN OMX_U32 nSizeBytes);
/** refer to OMX_FreeBuffer in OMX_core.h or the OMX IL
specification for details on the FreeBuffer method.
@ingroup buf
*/
OMX_ERRORTYPE (*FreeBuffer)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_U32 nPortIndex,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
/** refer to OMX_EmptyThisBuffer in OMX_core.h or the OMX IL
specification for details on the EmptyThisBuffer method.
@ingroup buf
*/
OMX_ERRORTYPE (*EmptyThisBuffer)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
/** refer to OMX_FillThisBuffer in OMX_core.h or the OMX IL
specification for details on the FillThisBuffer method.
@ingroup buf
*/
OMX_ERRORTYPE (*FillThisBuffer)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
/** The SetCallbacks method is used by the core to specify the callback
structure from the application to the component. This is a blocking
call. The component will return from this call within 5 msec.
@param [in] hComponent
Handle of the component to be accessed. This is the component
handle returned by the call to the GetHandle function.
@param [in] pCallbacks
pointer to an OMX_CALLBACKTYPE structure used to provide the
callback information to the component
@param [in] pAppData
pointer to an application defined value. It is anticipated that
the application will pass a pointer to a data structure or a "this
pointer" in this area to allow the callback (in the application)
to determine the context of the call
@return OMX_ERRORTYPE
If the command successfully executes, the return code will be
OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
*/
OMX_ERRORTYPE (*SetCallbacks)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_CALLBACKTYPE* pCallbacks,
OMX_IN OMX_PTR pAppData);
/** ComponentDeInit method is used to deinitialize the component
providing a means to free any resources allocated at component
initialization. NOTE: After this call the component handle is
not valid for further use.
@param [in] hComponent
Handle of the component to be accessed. This is the component
handle returned by the call to the GetHandle function.
@return OMX_ERRORTYPE
If the command successfully executes, the return code will be
OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
*/
OMX_ERRORTYPE (*ComponentDeInit)(
OMX_IN OMX_HANDLETYPE hComponent);
/** @ingroup buf */
OMX_ERRORTYPE (*UseEGLImage)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
OMX_IN OMX_U32 nPortIndex,
OMX_IN OMX_PTR pAppPrivate,
OMX_IN void* eglImage);
OMX_ERRORTYPE (*ComponentRoleEnum)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_OUT OMX_U8 *cRole,
OMX_IN OMX_U32 nIndex);
} OMX_COMPONENTTYPE;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
/* File EOF */

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2010 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
/** OMX_ComponentExt.h - OpenMax IL version 1.1.2
* The OMX_ComponentExt header file contains extensions to the definitions used
* by both the application and the component to access common items.
*/
#ifndef OMX_ComponentExt_h
#define OMX_ComponentExt_h
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Each OMX header must include all required header files to allow the
* header to compile without errors. The includes below are required
* for this header file to compile successfully
*/
#include <OMX_Types.h>
/** Set/query the commit mode */
typedef struct OMX_CONFIG_COMMITMODETYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_BOOL bDeferred;
} OMX_CONFIG_COMMITMODETYPE;
/** Explicit commit */
typedef struct OMX_CONFIG_COMMITTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
} OMX_CONFIG_COMMITTYPE;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* OMX_ComponentExt_h */

View file

@ -0,0 +1,195 @@
/*
* Copyright (c) 2008 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
/** OMX_ContentPipe.h - OpenMax IL version 1.1.2
* The OMX_ContentPipe header file contains the definitions used to define
* the public interface for content piples. This header file is intended to
* be used by the component.
*/
#ifndef OMX_CONTENTPIPE_H
#define OMX_CONTENTPIPE_H
#ifndef KD_EACCES
/* OpenKODE error codes. CPResult values may be zero (indicating success
or one of the following values) */
#define KD_EACCES (1)
#define KD_EADDRINUSE (2)
#define KD_EAGAIN (5)
#define KD_EBADF (7)
#define KD_EBUSY (8)
#define KD_ECONNREFUSED (9)
#define KD_ECONNRESET (10)
#define KD_EDEADLK (11)
#define KD_EDESTADDRREQ (12)
#define KD_ERANGE (35)
#define KD_EEXIST (13)
#define KD_EFBIG (14)
#define KD_EHOSTUNREACH (15)
#define KD_EINVAL (17)
#define KD_EIO (18)
#define KD_EISCONN (20)
#define KD_EISDIR (21)
#define KD_EMFILE (22)
#define KD_ENAMETOOLONG (23)
#define KD_ENOENT (24)
#define KD_ENOMEM (25)
#define KD_ENOSPC (26)
#define KD_ENOSYS (27)
#define KD_ENOTCONN (28)
#define KD_EPERM (33)
#define KD_ETIMEDOUT (36)
#define KD_EILSEQ (19)
#endif
/** Map types from OMX standard types only here so interface is as generic as possible. */
typedef OMX_U32 CPresult;
typedef char * CPstring;
typedef void * CPhandle;
typedef OMX_U32 CPuint;
typedef OMX_S32 CPint;
typedef char CPbyte;
typedef OMX_BOOL CPbool;
/** enumeration of origin types used in the CP_PIPETYPE's Seek function
* @ingroup cp
*/
typedef enum CP_ORIGINTYPE {
CP_OriginBegin,
CP_OriginCur,
CP_OriginEnd,
CP_OriginKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
CP_OriginVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
CP_OriginMax = 0X7FFFFFFF
} CP_ORIGINTYPE;
/** enumeration of contact access types used in the CP_PIPETYPE's Open function
* @ingroup cp
*/
typedef enum CP_ACCESSTYPE {
CP_AccessRead,
CP_AccessWrite,
CP_AccessReadWrite ,
CP_AccessKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
CP_AccessVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
CP_AccessMax = 0X7FFFFFFF
} CP_ACCESSTYPE;
/** enumeration of results returned by the CP_PIPETYPE's CheckAvailableBytes function
* @ingroup cp
*/
typedef enum CP_CHECKBYTESRESULTTYPE
{
CP_CheckBytesOk, /**< There are at least the request number
of bytes available */
CP_CheckBytesNotReady, /**< The pipe is still retrieving bytes
and presently lacks sufficient bytes.
Client will be called when they are
sufficient bytes are available. */
CP_CheckBytesInsufficientBytes , /**< The pipe has retrieved all bytes
but those available are less than those
requested */
CP_CheckBytesAtEndOfStream, /**< The pipe has reached the end of stream
and no more bytes are available. */
CP_CheckBytesOutOfBuffers, /**< All read/write buffers are currently in use. */
CP_CheckBytesKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
CP_CheckBytesVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
CP_CheckBytesMax = 0X7FFFFFFF
} CP_CHECKBYTESRESULTTYPE;
/** enumeration of content pipe events sent to the client callback.
* @ingroup cp
*/
typedef enum CP_EVENTTYPE{
CP_BytesAvailable, /** bytes requested in a CheckAvailableBytes call are now available*/
CP_Overflow, /** enumeration of content pipe events sent to the client callback*/
CP_PipeDisconnected , /** enumeration of content pipe events sent to the client callback*/
CP_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
CP_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
CP_EventMax = 0X7FFFFFFF
} CP_EVENTTYPE;
/** content pipe definition
* @ingroup cp
*/
typedef struct CP_PIPETYPE
{
/** Open a content stream for reading or writing. */
CPresult (*Open)( CPhandle* hContent, CPstring szURI, CP_ACCESSTYPE eAccess );
/** Close a content stream. */
CPresult (*Close)( CPhandle hContent );
/** Create a content source and open it for writing. */
CPresult (*Create)( CPhandle *hContent, CPstring szURI );
/** Check the that specified number of bytes are available for reading or writing (depending on access type).*/
CPresult (*CheckAvailableBytes)( CPhandle hContent, CPuint nBytesRequested, CP_CHECKBYTESRESULTTYPE *eResult );
/** Seek to certain position in the content relative to the specified origin. */
CPresult (*SetPosition)( CPhandle hContent, CPint nOffset, CP_ORIGINTYPE eOrigin);
/** Retrieve the current position relative to the start of the content. */
CPresult (*GetPosition)( CPhandle hContent, CPuint *pPosition);
/** Retrieve data of the specified size from the content stream (advance content pointer by size of data).
Note: pipe client provides pointer. This function is appropriate for small high frequency reads. */
CPresult (*Read)( CPhandle hContent, CPbyte *pData, CPuint nSize);
/** Retrieve a buffer allocated by the pipe that contains the requested number of bytes.
Buffer contains the next block of bytes, as specified by nSize, of the content. nSize also
returns the size of the block actually read. Content pointer advances the by the returned size.
Note: pipe provides pointer. This function is appropriate for large reads. The client must call
ReleaseReadBuffer when done with buffer.
In some cases the requested block may not reside in contiguous memory within the
pipe implementation. For instance if the pipe leverages a circular buffer then the requested
block may straddle the boundary of the circular buffer. By default a pipe implementation
performs a copy in this case to provide the block to the pipe client in one contiguous buffer.
If, however, the client sets bForbidCopy, then the pipe returns only those bytes preceding the memory
boundary. Here the client may retrieve the data in segments over successive calls. */
CPresult (*ReadBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint *nSize, CPbool bForbidCopy);
/** Release a buffer obtained by ReadBuffer back to the pipe. */
CPresult (*ReleaseReadBuffer)(CPhandle hContent, CPbyte *pBuffer);
/** Write data of the specified size to the content (advance content pointer by size of data).
Note: pipe client provides pointer. This function is appropriate for small high frequency writes. */
CPresult (*Write)( CPhandle hContent, CPbyte *data, CPuint nSize);
/** Retrieve a buffer allocated by the pipe used to write data to the content.
Client will fill buffer with output data. Note: pipe provides pointer. This function is appropriate
for large writes. The client must call WriteBuffer when done it has filled the buffer with data.*/
CPresult (*GetWriteBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint nSize);
/** Deliver a buffer obtained via GetWriteBuffer to the pipe. Pipe will write the
the contents of the buffer to content and advance content pointer by the size of the buffer */
CPresult (*WriteBuffer)( CPhandle hContent, CPbyte *pBuffer, CPuint nFilledSize);
/** Register a per-handle client callback with the content pipe. */
CPresult (*RegisterCallback)( CPhandle hContent, CPresult (*ClientCallback)(CP_EVENTTYPE eEvent, CPuint iParam));
} CP_PIPETYPE;
#endif

1431
omx/openmax/OMX_Core.h Normal file

File diff suppressed because it is too large Load diff

73
omx/openmax/OMX_CoreExt.h Normal file
View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2010 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
/** OMX_CoreExt.h - OpenMax IL version 1.1.2
* The OMX_CoreExt header file contains extensions to the definitions used
* by both the application and the component to access common items.
*/
#ifndef OMX_CoreExt_h
#define OMX_CoreExt_h
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Each OMX header shall include all required header files to allow the
* header to compile without errors. The includes below are required
* for this header file to compile successfully
*/
#include <OMX_Core.h>
/** Extensions to the standard IL errors. */
typedef enum OMX_ERROREXTTYPE
{
OMX_ErrorInvalidMode = (OMX_S32) (OMX_ErrorKhronosExtensions + 0x00000001),
OMX_ErrorExtMax = 0x7FFFFFFF
} OMX_ERROREXTTYPE;
/** Event type extensions. */
typedef enum OMX_EVENTEXTTYPE
{
OMX_EventIndexSettingChanged = OMX_EventKhronosExtensions, /**< component signals the IL client of a change
in a param, config, or extension */
OMX_EventExtMax = 0x7FFFFFFF
} OMX_EVENTEXTTYPE;
/** Enable or disable a callback event. */
typedef struct OMX_CONFIG_CALLBACKREQUESTTYPE {
OMX_U32 nSize; /**< size of the structure in bytes */
OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
OMX_U32 nPortIndex; /**< port that this structure applies to */
OMX_INDEXTYPE nIndex; /**< the index the callback is requested for */
OMX_BOOL bEnable; /**< enable (OMX_TRUE) or disable (OMX_FALSE) the callback */
} OMX_CONFIG_CALLBACKREQUESTTYPE;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* OMX_CoreExt_h */
/* File EOF */

920
omx/openmax/OMX_IVCommon.h Normal file
View file

@ -0,0 +1,920 @@
/**
* Copyright (c) 2008 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
/**
* @file OMX_IVCommon.h - OpenMax IL version 1.1.2
* The structures needed by Video and Image components to exchange
* parameters and configuration data with the components.
*/
#ifndef OMX_IVCommon_h
#define OMX_IVCommon_h
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* Each OMX header must include all required header files to allow the header
* to compile without errors. The includes below are required for this header
* file to compile successfully
*/
#include <OMX_Core.h>
/** @defgroup iv OpenMAX IL Imaging and Video Domain
* Common structures for OpenMAX IL Imaging and Video domains
* @{
*/
/**
* Enumeration defining possible uncompressed image/video formats.
*
* ENUMS:
* Unused : Placeholder value when format is N/A
* Monochrome : black and white
* 8bitRGB332 : Red 7:5, Green 4:2, Blue 1:0
* 12bitRGB444 : Red 11:8, Green 7:4, Blue 3:0
* 16bitARGB4444 : Alpha 15:12, Red 11:8, Green 7:4, Blue 3:0
* 16bitARGB1555 : Alpha 15, Red 14:10, Green 9:5, Blue 4:0
* 16bitRGB565 : Red 15:11, Green 10:5, Blue 4:0
* 16bitBGR565 : Blue 15:11, Green 10:5, Red 4:0
* 18bitRGB666 : Red 17:12, Green 11:6, Blue 5:0
* 18bitARGB1665 : Alpha 17, Red 16:11, Green 10:5, Blue 4:0
* 19bitARGB1666 : Alpha 18, Red 17:12, Green 11:6, Blue 5:0
* 24bitRGB888 : Red 24:16, Green 15:8, Blue 7:0
* 24bitBGR888 : Blue 24:16, Green 15:8, Red 7:0
* 24bitARGB1887 : Alpha 23, Red 22:15, Green 14:7, Blue 6:0
* 25bitARGB1888 : Alpha 24, Red 23:16, Green 15:8, Blue 7:0
* 32bitBGRA8888 : Blue 31:24, Green 23:16, Red 15:8, Alpha 7:0
* 32bitARGB8888 : Alpha 31:24, Red 23:16, Green 15:8, Blue 7:0
* YUV411Planar : U,Y are subsampled by a factor of 4 horizontally
* YUV411PackedPlanar : packed per payload in planar slices
* YUV420Planar : Three arrays Y,U,V.
* YUV420PackedPlanar : packed per payload in planar slices
* YUV420SemiPlanar : Two arrays, one is all Y, the other is U and V
* YUV422Planar : Three arrays Y,U,V.
* YUV422PackedPlanar : packed per payload in planar slices
* YUV422SemiPlanar : Two arrays, one is all Y, the other is U and V
* YCbYCr : Organized as 16bit YUYV (i.e. YCbYCr)
* YCrYCb : Organized as 16bit YVYU (i.e. YCrYCb)
* CbYCrY : Organized as 16bit UYVY (i.e. CbYCrY)
* CrYCbY : Organized as 16bit VYUY (i.e. CrYCbY)
* YUV444Interleaved : Each pixel contains equal parts YUV
* RawBayer8bit : SMIA camera output format
* RawBayer10bit : SMIA camera output format
* RawBayer8bitcompressed : SMIA camera output format
*/
typedef enum OMX_COLOR_FORMATTYPE {
OMX_COLOR_FormatUnused,
OMX_COLOR_FormatMonochrome,
OMX_COLOR_Format8bitRGB332,
OMX_COLOR_Format12bitRGB444,
OMX_COLOR_Format16bitARGB4444,
OMX_COLOR_Format16bitARGB1555,
OMX_COLOR_Format16bitRGB565,
OMX_COLOR_Format16bitBGR565,
OMX_COLOR_Format18bitRGB666,
OMX_COLOR_Format18bitARGB1665,
OMX_COLOR_Format19bitARGB1666,
OMX_COLOR_Format24bitRGB888,
OMX_COLOR_Format24bitBGR888,
OMX_COLOR_Format24bitARGB1887,
OMX_COLOR_Format25bitARGB1888,
OMX_COLOR_Format32bitBGRA8888,
OMX_COLOR_Format32bitARGB8888,
OMX_COLOR_FormatYUV411Planar,
OMX_COLOR_FormatYUV411PackedPlanar,
OMX_COLOR_FormatYUV420Planar,
OMX_COLOR_FormatYUV420PackedPlanar,
OMX_COLOR_FormatYUV420SemiPlanar,
OMX_COLOR_FormatYUV422Planar,
OMX_COLOR_FormatYUV422PackedPlanar,
OMX_COLOR_FormatYUV422SemiPlanar,
OMX_COLOR_FormatYCbYCr,
OMX_COLOR_FormatYCrYCb,
OMX_COLOR_FormatCbYCrY,
OMX_COLOR_FormatCrYCbY,
OMX_COLOR_FormatYUV444Interleaved,
OMX_COLOR_FormatRawBayer8bit,
OMX_COLOR_FormatRawBayer10bit,
OMX_COLOR_FormatRawBayer8bitcompressed,
OMX_COLOR_FormatL2,
OMX_COLOR_FormatL4,
OMX_COLOR_FormatL8,
OMX_COLOR_FormatL16,
OMX_COLOR_FormatL24,
OMX_COLOR_FormatL32,
OMX_COLOR_FormatYUV420PackedSemiPlanar,
OMX_COLOR_FormatYUV422PackedSemiPlanar,
OMX_COLOR_Format18BitBGR666,
OMX_COLOR_Format24BitARGB6666,
OMX_COLOR_Format24BitABGR6666,
OMX_COLOR_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_COLOR_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_COLOR_FormatMax = 0x7FFFFFFF
} OMX_COLOR_FORMATTYPE;
/**
* Defines the matrix for conversion from RGB to YUV or vice versa.
* iColorMatrix should be initialized with the fixed point values
* used in converting between formats.
*/
typedef struct OMX_CONFIG_COLORCONVERSIONTYPE {
OMX_U32 nSize; /**< Size of the structure in bytes */
OMX_VERSIONTYPE nVersion; /**< OMX specification version info */
OMX_U32 nPortIndex; /**< Port that this struct applies to */
OMX_S32 xColorMatrix[3][3]; /**< Stored in signed Q16 format */
OMX_S32 xColorOffset[4]; /**< Stored in signed Q16 format */
}OMX_CONFIG_COLORCONVERSIONTYPE;
/**
* Structure defining percent to scale each frame dimension. For example:
* To make the width 50% larger, use fWidth = 1.5 and to make the width
* 1/2 the original size, use fWidth = 0.5
*/
typedef struct OMX_CONFIG_SCALEFACTORTYPE {
OMX_U32 nSize; /**< Size of the structure in bytes */
OMX_VERSIONTYPE nVersion; /**< OMX specification version info */
OMX_U32 nPortIndex; /**< Port that this struct applies to */
OMX_S32 xWidth; /**< Fixed point value stored as Q16 */
OMX_S32 xHeight; /**< Fixed point value stored as Q16 */
}OMX_CONFIG_SCALEFACTORTYPE;
/**
* Enumeration of possible image filter types
*/
typedef enum OMX_IMAGEFILTERTYPE {
OMX_ImageFilterNone,
OMX_ImageFilterNoise,
OMX_ImageFilterEmboss,
OMX_ImageFilterNegative,
OMX_ImageFilterSketch,
OMX_ImageFilterOilPaint,
OMX_ImageFilterHatch,
OMX_ImageFilterGpen,
OMX_ImageFilterAntialias,
OMX_ImageFilterDeRing,
OMX_ImageFilterSolarize,
OMX_ImageFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_ImageFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_ImageFilterMax = 0x7FFFFFFF
} OMX_IMAGEFILTERTYPE;
/**
* Image filter configuration
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* eImageFilter : Image filter type enumeration
*/
typedef struct OMX_CONFIG_IMAGEFILTERTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_IMAGEFILTERTYPE eImageFilter;
} OMX_CONFIG_IMAGEFILTERTYPE;
/**
* Customized U and V for color enhancement
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* bColorEnhancement : Enable/disable color enhancement
* nCustomizedU : Practical values: 16-240, range: 0-255, value set for
* U component
* nCustomizedV : Practical values: 16-240, range: 0-255, value set for
* V component
*/
typedef struct OMX_CONFIG_COLORENHANCEMENTTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_BOOL bColorEnhancement;
OMX_U8 nCustomizedU;
OMX_U8 nCustomizedV;
} OMX_CONFIG_COLORENHANCEMENTTYPE;
/**
* Define color key and color key mask
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nARGBColor : 32bit Alpha, Red, Green, Blue Color
* nARGBMask : 32bit Mask for Alpha, Red, Green, Blue channels
*/
typedef struct OMX_CONFIG_COLORKEYTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_U32 nARGBColor;
OMX_U32 nARGBMask;
} OMX_CONFIG_COLORKEYTYPE;
/**
* List of color blend types for pre/post processing
*
* ENUMS:
* None : No color blending present
* AlphaConstant : Function is (alpha_constant * src) +
* (1 - alpha_constant) * dst)
* AlphaPerPixel : Function is (alpha * src) + (1 - alpha) * dst)
* Alternate : Function is alternating pixels from src and dst
* And : Function is (src & dst)
* Or : Function is (src | dst)
* Invert : Function is ~src
*/
typedef enum OMX_COLORBLENDTYPE {
OMX_ColorBlendNone,
OMX_ColorBlendAlphaConstant,
OMX_ColorBlendAlphaPerPixel,
OMX_ColorBlendAlternate,
OMX_ColorBlendAnd,
OMX_ColorBlendOr,
OMX_ColorBlendInvert,
OMX_ColorBlendKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_ColorBlendVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_ColorBlendMax = 0x7FFFFFFF
} OMX_COLORBLENDTYPE;
/**
* Color blend configuration
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nRGBAlphaConstant : Constant global alpha values when global alpha is used
* eColorBlend : Color blend type enumeration
*/
typedef struct OMX_CONFIG_COLORBLENDTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_U32 nRGBAlphaConstant;
OMX_COLORBLENDTYPE eColorBlend;
} OMX_CONFIG_COLORBLENDTYPE;
/**
* Hold frame dimension
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nWidth : Frame width in pixels
* nHeight : Frame height in pixels
*/
typedef struct OMX_FRAMESIZETYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_U32 nWidth;
OMX_U32 nHeight;
} OMX_FRAMESIZETYPE;
/**
* Rotation configuration
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nRotation : +/- integer rotation value
*/
typedef struct OMX_CONFIG_ROTATIONTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_S32 nRotation;
} OMX_CONFIG_ROTATIONTYPE;
/**
* Possible mirroring directions for pre/post processing
*
* ENUMS:
* None : No mirroring
* Vertical : Vertical mirroring, flip on X axis
* Horizontal : Horizontal mirroring, flip on Y axis
* Both : Both vertical and horizontal mirroring
*/
typedef enum OMX_MIRRORTYPE {
OMX_MirrorNone = 0,
OMX_MirrorVertical,
OMX_MirrorHorizontal,
OMX_MirrorBoth,
OMX_MirrorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_MirrorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_MirrorMax = 0x7FFFFFFF
} OMX_MIRRORTYPE;
/**
* Mirroring configuration
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* eMirror : Mirror type enumeration
*/
typedef struct OMX_CONFIG_MIRRORTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_MIRRORTYPE eMirror;
} OMX_CONFIG_MIRRORTYPE;
/**
* Position information only
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nX : X coordinate for the point
* nY : Y coordinate for the point
*/
typedef struct OMX_CONFIG_POINTTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_S32 nX;
OMX_S32 nY;
} OMX_CONFIG_POINTTYPE;
/**
* Frame size plus position
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nLeft : X Coordinate of the top left corner of the rectangle
* nTop : Y Coordinate of the top left corner of the rectangle
* nWidth : Width of the rectangle
* nHeight : Height of the rectangle
*/
typedef struct OMX_CONFIG_RECTTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_S32 nLeft;
OMX_S32 nTop;
OMX_U32 nWidth;
OMX_U32 nHeight;
} OMX_CONFIG_RECTTYPE;
/**
* Deblocking state; it is required to be set up before starting the codec
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* bDeblocking : Enable/disable deblocking mode
*/
typedef struct OMX_PARAM_DEBLOCKINGTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_BOOL bDeblocking;
} OMX_PARAM_DEBLOCKINGTYPE;
/**
* Stabilization state
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* bStab : Enable/disable frame stabilization state
*/
typedef struct OMX_CONFIG_FRAMESTABTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_BOOL bStab;
} OMX_CONFIG_FRAMESTABTYPE;
/**
* White Balance control type
*
* STRUCT MEMBERS:
* SunLight : Referenced in JSR-234
* Flash : Optimal for device's integrated flash
*/
typedef enum OMX_WHITEBALCONTROLTYPE {
OMX_WhiteBalControlOff = 0,
OMX_WhiteBalControlAuto,
OMX_WhiteBalControlSunLight,
OMX_WhiteBalControlCloudy,
OMX_WhiteBalControlShade,
OMX_WhiteBalControlTungsten,
OMX_WhiteBalControlFluorescent,
OMX_WhiteBalControlIncandescent,
OMX_WhiteBalControlFlash,
OMX_WhiteBalControlHorizon,
OMX_WhiteBalControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_WhiteBalControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_WhiteBalControlMax = 0x7FFFFFFF
} OMX_WHITEBALCONTROLTYPE;
/**
* White Balance control configuration
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* eWhiteBalControl : White balance enumeration
*/
typedef struct OMX_CONFIG_WHITEBALCONTROLTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_WHITEBALCONTROLTYPE eWhiteBalControl;
} OMX_CONFIG_WHITEBALCONTROLTYPE;
/**
* Exposure control type
*/
typedef enum OMX_EXPOSURECONTROLTYPE {
OMX_ExposureControlOff = 0,
OMX_ExposureControlAuto,
OMX_ExposureControlNight,
OMX_ExposureControlBackLight,
OMX_ExposureControlSpotLight,
OMX_ExposureControlSports,
OMX_ExposureControlSnow,
OMX_ExposureControlBeach,
OMX_ExposureControlLargeAperture,
OMX_ExposureControlSmallApperture,
OMX_ExposureControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_ExposureControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_ExposureControlMax = 0x7FFFFFFF
} OMX_EXPOSURECONTROLTYPE;
/**
* White Balance control configuration
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* eExposureControl : Exposure control enumeration
*/
typedef struct OMX_CONFIG_EXPOSURECONTROLTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_EXPOSURECONTROLTYPE eExposureControl;
} OMX_CONFIG_EXPOSURECONTROLTYPE;
/**
* Defines sensor supported mode.
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nFrameRate : Single shot mode is indicated by a 0
* bOneShot : Enable for single shot, disable for streaming
* sFrameSize : Framesize
*/
typedef struct OMX_PARAM_SENSORMODETYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_U32 nFrameRate;
OMX_BOOL bOneShot;
OMX_FRAMESIZETYPE sFrameSize;
} OMX_PARAM_SENSORMODETYPE;
/**
* Defines contrast level
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nContrast : Values allowed for contrast -100 to 100, zero means no change
*/
typedef struct OMX_CONFIG_CONTRASTTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_S32 nContrast;
} OMX_CONFIG_CONTRASTTYPE;
/**
* Defines brightness level
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nBrightness : 0-100%
*/
typedef struct OMX_CONFIG_BRIGHTNESSTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_U32 nBrightness;
} OMX_CONFIG_BRIGHTNESSTYPE;
/**
* Defines backlight level configuration for a video sink, e.g. LCD panel
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nBacklight : Values allowed for backlight 0-100%
* nTimeout : Number of milliseconds before backlight automatically turns
* off. A value of 0x0 disables backight timeout
*/
typedef struct OMX_CONFIG_BACKLIGHTTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_U32 nBacklight;
OMX_U32 nTimeout;
} OMX_CONFIG_BACKLIGHTTYPE;
/**
* Defines setting for Gamma
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nGamma : Values allowed for gamma -100 to 100, zero means no change
*/
typedef struct OMX_CONFIG_GAMMATYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_S32 nGamma;
} OMX_CONFIG_GAMMATYPE;
/**
* Define for setting saturation
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nSaturation : Values allowed for saturation -100 to 100, zero means
* no change
*/
typedef struct OMX_CONFIG_SATURATIONTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_S32 nSaturation;
} OMX_CONFIG_SATURATIONTYPE;
/**
* Define for setting Lightness
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nLightness : Values allowed for lightness -100 to 100, zero means no
* change
*/
typedef struct OMX_CONFIG_LIGHTNESSTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_S32 nLightness;
} OMX_CONFIG_LIGHTNESSTYPE;
/**
* Plane blend configuration
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Index of input port associated with the plane.
* nDepth : Depth of the plane in relation to the screen. Higher
* numbered depths are "behind" lower number depths.
* This number defaults to the Port Index number.
* nAlpha : Transparency blending component for the entire plane.
* See blending modes for more detail.
*/
typedef struct OMX_CONFIG_PLANEBLENDTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_U32 nDepth;
OMX_U32 nAlpha;
} OMX_CONFIG_PLANEBLENDTYPE;
/**
* Define interlace type
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* bEnable : Enable control variable for this functionality
* (see below)
* nInterleavePortIndex : Index of input or output port associated with
* the interleaved plane.
* pPlanarPortIndexes[4] : Index of input or output planar ports.
*/
typedef struct OMX_PARAM_INTERLEAVETYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_BOOL bEnable;
OMX_U32 nInterleavePortIndex;
} OMX_PARAM_INTERLEAVETYPE;
/**
* Defines the picture effect used for an input picture
*/
typedef enum OMX_TRANSITIONEFFECTTYPE {
OMX_EffectNone,
OMX_EffectFadeFromBlack,
OMX_EffectFadeToBlack,
OMX_EffectUnspecifiedThroughConstantColor,
OMX_EffectDissolve,
OMX_EffectWipe,
OMX_EffectUnspecifiedMixOfTwoScenes,
OMX_EffectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_EffectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_EffectMax = 0x7FFFFFFF
} OMX_TRANSITIONEFFECTTYPE;
/**
* Structure used to configure current transition effect
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* eEffect : Effect to enable
*/
typedef struct OMX_CONFIG_TRANSITIONEFFECTTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_TRANSITIONEFFECTTYPE eEffect;
} OMX_CONFIG_TRANSITIONEFFECTTYPE;
/**
* Defines possible data unit types for encoded video data. The data unit
* types are used both for encoded video input for playback as well as
* encoded video output from recording.
*/
typedef enum OMX_DATAUNITTYPE {
OMX_DataUnitCodedPicture,
OMX_DataUnitVideoSegment,
OMX_DataUnitSeveralSegments,
OMX_DataUnitArbitraryStreamSection,
OMX_DataUnitKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_DataUnitVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_DataUnitMax = 0x7FFFFFFF
} OMX_DATAUNITTYPE;
/**
* Defines possible encapsulation types for coded video data unit. The
* encapsulation information is used both for encoded video input for
* playback as well as encoded video output from recording.
*/
typedef enum OMX_DATAUNITENCAPSULATIONTYPE {
OMX_DataEncapsulationElementaryStream,
OMX_DataEncapsulationGenericPayload,
OMX_DataEncapsulationRtpPayload,
OMX_DataEncapsulationKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_DataEncapsulationVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_DataEncapsulationMax = 0x7FFFFFFF
} OMX_DATAUNITENCAPSULATIONTYPE;
/**
* Structure used to configure the type of being decoded/encoded
*/
typedef struct OMX_PARAM_DATAUNITTYPE {
OMX_U32 nSize; /**< Size of the structure in bytes */
OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
OMX_U32 nPortIndex; /**< Port that this structure applies to */
OMX_DATAUNITTYPE eUnitType;
OMX_DATAUNITENCAPSULATIONTYPE eEncapsulationType;
} OMX_PARAM_DATAUNITTYPE;
/**
* Defines dither types
*/
typedef enum OMX_DITHERTYPE {
OMX_DitherNone,
OMX_DitherOrdered,
OMX_DitherErrorDiffusion,
OMX_DitherOther,
OMX_DitherKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_DitherVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_DitherMax = 0x7FFFFFFF
} OMX_DITHERTYPE;
/**
* Structure used to configure current type of dithering
*/
typedef struct OMX_CONFIG_DITHERTYPE {
OMX_U32 nSize; /**< Size of the structure in bytes */
OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
OMX_U32 nPortIndex; /**< Port that this structure applies to */
OMX_DITHERTYPE eDither; /**< Type of dithering to use */
} OMX_CONFIG_DITHERTYPE;
typedef struct OMX_CONFIG_CAPTUREMODETYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex; /**< Port that this structure applies to */
OMX_BOOL bContinuous; /**< If true then ignore frame rate and emit capture
* data as fast as possible (otherwise obey port's frame rate). */
OMX_BOOL bFrameLimited; /**< If true then terminate capture after the port emits the
* specified number of frames (otherwise the port does not
* terminate the capture until instructed to do so by the client).
* Even if set, the client may manually terminate the capture prior
* to reaching the limit. */
OMX_U32 nFrameLimit; /**< Limit on number of frames emitted during a capture (only
* valid if bFrameLimited is set). */
} OMX_CONFIG_CAPTUREMODETYPE;
typedef enum OMX_METERINGTYPE {
OMX_MeteringModeAverage, /**< Center-weighted average metering. */
OMX_MeteringModeSpot, /**< Spot (partial) metering. */
OMX_MeteringModeMatrix, /**< Matrix or evaluative metering. */
OMX_MeteringKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_MeteringVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_EVModeMax = 0x7fffffff
} OMX_METERINGTYPE;
typedef struct OMX_CONFIG_EXPOSUREVALUETYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_METERINGTYPE eMetering;
OMX_S32 xEVCompensation; /**< Fixed point value stored as Q16 */
OMX_U32 nApertureFNumber; /**< e.g. nApertureFNumber = 2 implies "f/2" - Q16 format */
OMX_BOOL bAutoAperture; /**< Whether aperture number is defined automatically */
OMX_U32 nShutterSpeedMsec; /**< Shutterspeed in milliseconds */
OMX_BOOL bAutoShutterSpeed; /**< Whether shutter speed is defined automatically */
OMX_U32 nSensitivity; /**< e.g. nSensitivity = 100 implies "ISO 100" */
OMX_BOOL bAutoSensitivity; /**< Whether sensitivity is defined automatically */
} OMX_CONFIG_EXPOSUREVALUETYPE;
/**
* Focus region configuration
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* bCenter : Use center region as focus region of interest
* bLeft : Use left region as focus region of interest
* bRight : Use right region as focus region of interest
* bTop : Use top region as focus region of interest
* bBottom : Use bottom region as focus region of interest
* bTopLeft : Use top left region as focus region of interest
* bTopRight : Use top right region as focus region of interest
* bBottomLeft : Use bottom left region as focus region of interest
* bBottomRight : Use bottom right region as focus region of interest
*/
typedef struct OMX_CONFIG_FOCUSREGIONTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_BOOL bCenter;
OMX_BOOL bLeft;
OMX_BOOL bRight;
OMX_BOOL bTop;
OMX_BOOL bBottom;
OMX_BOOL bTopLeft;
OMX_BOOL bTopRight;
OMX_BOOL bBottomLeft;
OMX_BOOL bBottomRight;
} OMX_CONFIG_FOCUSREGIONTYPE;
/**
* Focus Status type
*/
typedef enum OMX_FOCUSSTATUSTYPE {
OMX_FocusStatusOff = 0,
OMX_FocusStatusRequest,
OMX_FocusStatusReached,
OMX_FocusStatusUnableToReach,
OMX_FocusStatusLost,
OMX_FocusStatusKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_FocusStatusVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_FocusStatusMax = 0x7FFFFFFF
} OMX_FOCUSSTATUSTYPE;
/**
* Focus status configuration
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* eFocusStatus : Specifies the focus status
* bCenterStatus : Use center region as focus region of interest
* bLeftStatus : Use left region as focus region of interest
* bRightStatus : Use right region as focus region of interest
* bTopStatus : Use top region as focus region of interest
* bBottomStatus : Use bottom region as focus region of interest
* bTopLeftStatus : Use top left region as focus region of interest
* bTopRightStatus : Use top right region as focus region of interest
* bBottomLeftStatus : Use bottom left region as focus region of interest
* bBottomRightStatus : Use bottom right region as focus region of interest
*/
typedef struct OMX_PARAM_FOCUSSTATUSTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_FOCUSSTATUSTYPE eFocusStatus;
OMX_BOOL bCenterStatus;
OMX_BOOL bLeftStatus;
OMX_BOOL bRightStatus;
OMX_BOOL bTopStatus;
OMX_BOOL bBottomStatus;
OMX_BOOL bTopLeftStatus;
OMX_BOOL bTopRightStatus;
OMX_BOOL bBottomLeftStatus;
OMX_BOOL bBottomRightStatus;
} OMX_PARAM_FOCUSSTATUSTYPE;
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
/* File EOF */

328
omx/openmax/OMX_Image.h Normal file
View file

@ -0,0 +1,328 @@
/**
* Copyright (c) 2008 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* @file OMX_Image.h - OpenMax IL version 1.1.2
* The structures needed by Image components to exchange parameters and
* configuration data with the components.
*/
#ifndef OMX_Image_h
#define OMX_Image_h
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* Each OMX header must include all required header files to allow the
* header to compile without errors. The includes below are required
* for this header file to compile successfully
*/
#include <OMX_IVCommon.h>
/** @defgroup imaging OpenMAX IL Imaging Domain
* @ingroup iv
* Structures for OpenMAX IL Imaging domain
* @{
*/
/**
* Enumeration used to define the possible image compression coding.
*/
typedef enum OMX_IMAGE_CODINGTYPE {
OMX_IMAGE_CodingUnused, /**< Value when format is N/A */
OMX_IMAGE_CodingAutoDetect, /**< Auto detection of image format */
OMX_IMAGE_CodingJPEG, /**< JPEG/JFIF image format */
OMX_IMAGE_CodingJPEG2K, /**< JPEG 2000 image format */
OMX_IMAGE_CodingEXIF, /**< EXIF image format */
OMX_IMAGE_CodingTIFF, /**< TIFF image format */
OMX_IMAGE_CodingGIF, /**< Graphics image format */
OMX_IMAGE_CodingPNG, /**< PNG image format */
OMX_IMAGE_CodingLZW, /**< LZW image format */
OMX_IMAGE_CodingBMP, /**< Windows Bitmap format */
OMX_IMAGE_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_IMAGE_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_IMAGE_CodingMax = 0x7FFFFFFF
} OMX_IMAGE_CODINGTYPE;
/**
* Data structure used to define an image path. The number of image paths
* for input and output will vary by type of the image component.
*
* Input (aka Source) : Zero Inputs, one Output,
* Splitter : One Input, 2 or more Outputs,
* Processing Element : One Input, one output,
* Mixer : 2 or more inputs, one output,
* Output (aka Sink) : One Input, zero outputs.
*
* The PortDefinition structure is used to define all of the parameters
* necessary for the compliant component to setup an input or an output
* image path. If additional vendor specific data is required, it should
* be transmitted to the component using the CustomCommand function.
* Compliant components will prepopulate this structure with optimal
* values during the OMX_GetParameter() command.
*
* STRUCT MEMBERS:
* cMIMEType : MIME type of data for the port
* pNativeRender : Platform specific reference for a display if a
* sync, otherwise this field is 0
* nFrameWidth : Width of frame to be used on port if
* uncompressed format is used. Use 0 for
* unknown, don't care or variable
* nFrameHeight : Height of frame to be used on port if
* uncompressed format is used. Use 0 for
* unknown, don't care or variable
* nStride : Number of bytes per span of an image (i.e.
* indicates the number of bytes to get from
* span N to span N+1, where negative stride
* indicates the image is bottom up
* nSliceHeight : Height used when encoding in slices
* bFlagErrorConcealment : Turns on error concealment if it is supported by
* the OMX component
* eCompressionFormat : Compression format used in this instance of
* the component. When OMX_IMAGE_CodingUnused is
* specified, eColorFormat is valid
* eColorFormat : Decompressed format used by this component
* pNativeWindow : Platform specific reference for a window object if a
* display sink , otherwise this field is 0x0.
*/
typedef struct OMX_IMAGE_PORTDEFINITIONTYPE {
OMX_STRING cMIMEType;
OMX_NATIVE_DEVICETYPE pNativeRender;
OMX_U32 nFrameWidth;
OMX_U32 nFrameHeight;
OMX_S32 nStride;
OMX_U32 nSliceHeight;
OMX_BOOL bFlagErrorConcealment;
OMX_IMAGE_CODINGTYPE eCompressionFormat;
OMX_COLOR_FORMATTYPE eColorFormat;
OMX_NATIVE_WINDOWTYPE pNativeWindow;
} OMX_IMAGE_PORTDEFINITIONTYPE;
/**
* Port format parameter. This structure is used to enumerate the various
* data input/output format supported by the port.
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Indicates which port to set
* nIndex : Indicates the enumeration index for the format from
* 0x0 to N-1
* eCompressionFormat : Compression format used in this instance of the
* component. When OMX_IMAGE_CodingUnused is specified,
* eColorFormat is valid
* eColorFormat : Decompressed format used by this component
*/
typedef struct OMX_IMAGE_PARAM_PORTFORMATTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_U32 nIndex;
OMX_IMAGE_CODINGTYPE eCompressionFormat;
OMX_COLOR_FORMATTYPE eColorFormat;
} OMX_IMAGE_PARAM_PORTFORMATTYPE;
/**
* Flash control type
*
* ENUMS
* Torch : Flash forced constantly on
*/
typedef enum OMX_IMAGE_FLASHCONTROLTYPE {
OMX_IMAGE_FlashControlOn = 0,
OMX_IMAGE_FlashControlOff,
OMX_IMAGE_FlashControlAuto,
OMX_IMAGE_FlashControlRedEyeReduction,
OMX_IMAGE_FlashControlFillin,
OMX_IMAGE_FlashControlTorch,
OMX_IMAGE_FlashControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_IMAGE_FlashControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_IMAGE_FlashControlMax = 0x7FFFFFFF
} OMX_IMAGE_FLASHCONTROLTYPE;
/**
* Flash control configuration
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* eFlashControl : Flash control type
*/
typedef struct OMX_IMAGE_PARAM_FLASHCONTROLTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_IMAGE_FLASHCONTROLTYPE eFlashControl;
} OMX_IMAGE_PARAM_FLASHCONTROLTYPE;
/**
* Focus control type
*/
typedef enum OMX_IMAGE_FOCUSCONTROLTYPE {
OMX_IMAGE_FocusControlOn = 0,
OMX_IMAGE_FocusControlOff,
OMX_IMAGE_FocusControlAuto,
OMX_IMAGE_FocusControlAutoLock,
OMX_IMAGE_FocusControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_IMAGE_FocusControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_IMAGE_FocusControlMax = 0x7FFFFFFF
} OMX_IMAGE_FOCUSCONTROLTYPE;
/**
* Focus control configuration
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* eFocusControl : Focus control
* nFocusSteps : Focus can take on values from 0 mm to infinity.
* Interest is only in number of steps over this range.
* nFocusStepIndex : Current focus step index
*/
typedef struct OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_IMAGE_FOCUSCONTROLTYPE eFocusControl;
OMX_U32 nFocusSteps;
OMX_U32 nFocusStepIndex;
} OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE;
/**
* Q Factor for JPEG compression, which controls the tradeoff between image
* quality and size. Q Factor provides a more simple means of controlling
* JPEG compression quality, without directly programming Quantization
* tables for chroma and luma
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nQFactor : JPEG Q factor value in the range of 1-100. A factor of 1
* produces the smallest, worst quality images, and a factor
* of 100 produces the largest, best quality images. A
* typical default is 75 for small good quality images
*/
typedef struct OMX_IMAGE_PARAM_QFACTORTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_U32 nQFactor;
} OMX_IMAGE_PARAM_QFACTORTYPE;
/**
* Quantization table type
*/
typedef enum OMX_IMAGE_QUANTIZATIONTABLETYPE {
OMX_IMAGE_QuantizationTableLuma = 0,
OMX_IMAGE_QuantizationTableChroma,
OMX_IMAGE_QuantizationTableChromaCb,
OMX_IMAGE_QuantizationTableChromaCr,
OMX_IMAGE_QuantizationTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_IMAGE_QuantizationTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_IMAGE_QuantizationTableMax = 0x7FFFFFFF
} OMX_IMAGE_QUANTIZATIONTABLETYPE;
/**
* JPEG quantization tables are used to determine DCT compression for
* YUV data, as an alternative to specifying Q factor, providing exact
* control of compression
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* eQuantizationTable : Quantization table type
* nQuantizationMatrix[64] : JPEG quantization table of coefficients stored
* in increasing columns then by rows of data (i.e.
* row 1, ... row 8). Quantization values are in
* the range 0-255 and stored in linear order
* (i.e. the component will zig-zag the
* quantization table data if required internally)
*/
typedef struct OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_IMAGE_QUANTIZATIONTABLETYPE eQuantizationTable;
OMX_U8 nQuantizationMatrix[64];
} OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE;
/**
* Huffman table type, the same Huffman table is applied for chroma and
* luma component
*/
typedef enum OMX_IMAGE_HUFFMANTABLETYPE {
OMX_IMAGE_HuffmanTableAC = 0,
OMX_IMAGE_HuffmanTableDC,
OMX_IMAGE_HuffmanTableACLuma,
OMX_IMAGE_HuffmanTableACChroma,
OMX_IMAGE_HuffmanTableDCLuma,
OMX_IMAGE_HuffmanTableDCChroma,
OMX_IMAGE_HuffmanTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_IMAGE_HuffmanTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_IMAGE_HuffmanTableMax = 0x7FFFFFFF
} OMX_IMAGE_HUFFMANTABLETYPE;
/**
* JPEG Huffman table
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* eHuffmanTable : Huffman table type
* nNumberOfHuffmanCodeOfLength[16] : 0-16, number of Huffman codes of each
* possible length
* nHuffmanTable[256] : 0-255, the size used for AC and DC
* HuffmanTable are 16 and 162
*/
typedef struct OMX_IMAGE_PARAM_HUFFMANTTABLETYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_IMAGE_HUFFMANTABLETYPE eHuffmanTable;
OMX_U8 nNumberOfHuffmanCodeOfLength[16];
OMX_U8 nHuffmanTable[256];
}OMX_IMAGE_PARAM_HUFFMANTTABLETYPE;
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
/* File EOF */

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