mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-22 01:31:03 +00:00
gst-omx: Retire the whole package
The OpenMAX standard is long dead and even the Raspberry Pi OS no longer supports it. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4976>
This commit is contained in:
parent
62d3e8fc32
commit
48c43e5b7f
136 changed files with 0 additions and 37670 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -22,7 +22,6 @@ prefix/
|
|||
/gst-integration-testsuites
|
||||
/gst-editing-services
|
||||
/gstreamer-vaapi
|
||||
/gst-omx
|
||||
/gstreamer-sharp
|
||||
/pygobject
|
||||
/gst-python
|
||||
|
@ -47,7 +46,6 @@ subprojects/*/
|
|||
!subprojects/gst-examples
|
||||
!subprojects/gst-integration-testsuites
|
||||
!subprojects/gst-libav
|
||||
!subprojects/gst-omx
|
||||
!subprojects/gst-plugins-bad
|
||||
!subprojects/gst-plugins-base
|
||||
!subprojects/gst-plugins-good
|
||||
|
|
|
@ -61,8 +61,6 @@ variables:
|
|||
SIMPLE_BUILD: >-
|
||||
${DEFAULT_MESON_ARGS}
|
||||
-Dsharp=enabled
|
||||
-Domx=enabled
|
||||
-Dgst-omx:target=generic
|
||||
-Ddoc=disabled
|
||||
|
||||
workflow:
|
||||
|
@ -287,7 +285,6 @@ commitlint:
|
|||
- subprojects/gst-editing-services/**/*
|
||||
- subprojects/gst-integration-testsuites/**/*
|
||||
- subprojects/gst-libav/**/*
|
||||
- subprojects/gst-omx/**/*
|
||||
- subprojects/gst-plugins-bad/**/*
|
||||
- subprojects/gst-plugins-base/**/*
|
||||
- subprojects/gst-plugins-good/**/*
|
||||
|
@ -598,7 +595,6 @@ integration testsuites fedora:
|
|||
variables:
|
||||
MESON_ARGS: >-
|
||||
${SIMPLE_BUILD}
|
||||
-Domx=disabled
|
||||
-Dsharp=disabled
|
||||
-Dvaapi=disabled
|
||||
-Dexamples=disabled
|
||||
|
@ -845,7 +841,6 @@ build documentation:
|
|||
- subprojects/gst-devtools/**/*
|
||||
- subprojects/gst-editing-services/**/*
|
||||
- subprojects/gst-libav/**/*
|
||||
- subprojects/gst-omx/**/*
|
||||
- subprojects/gst-plugins-bad/**/*
|
||||
- subprojects/gst-plugins-base/**/*
|
||||
- subprojects/gst-plugins-good/**/*
|
||||
|
|
|
@ -105,7 +105,6 @@ dnf install -y \
|
|||
valgrind \
|
||||
vulkan \
|
||||
vulkan-devel \
|
||||
mesa-omx-drivers \
|
||||
mesa-libGL \
|
||||
mesa-libGL-devel \
|
||||
mesa-libGLU \
|
||||
|
|
|
@ -84,7 +84,6 @@ meson \
|
|||
-Dbad=disabled \
|
||||
-Dlibav=disabled \
|
||||
-Dges=disabled \
|
||||
-Domx=disabled \
|
||||
-Dvaapi=disabled \
|
||||
-Dsharp=disabled \
|
||||
-Drs=disabled \
|
||||
|
|
|
@ -28,9 +28,6 @@ werror = true
|
|||
[gst-docs:built-in options]
|
||||
werror = true
|
||||
|
||||
[gst-omx:built-in options]
|
||||
werror = true
|
||||
|
||||
[gst-devtools:built-in options]
|
||||
werror = true
|
||||
|
||||
|
|
|
@ -453,10 +453,6 @@ def get_subprocess_env(options, gst_version):
|
|||
encoding_targets.add(
|
||||
os.path.abspath(os.path.join(os.path.dirname(path), '..')))
|
||||
|
||||
if path.endswith('gstomx.conf'):
|
||||
prepend_env_var(env, 'GST_OMX_CONFIG_DIR', os.path.dirname(path),
|
||||
options.sysroot)
|
||||
|
||||
for p in sorted(presets):
|
||||
prepend_env_var(env, 'GST_PRESET_PATH', p, options.sysroot)
|
||||
|
||||
|
|
|
@ -105,7 +105,6 @@ subprojects = [
|
|||
['gst-integration-testsuites', { 'option': get_option('devtools') }],
|
||||
['gst-editing-services', { 'option': get_option('ges'), 'build-hotdoc': true}],
|
||||
['gstreamer-vaapi', { 'option': get_option('vaapi'), 'build-hotdoc': true}],
|
||||
['gst-omx', { 'option': get_option('omx'), 'build-hotdoc': true}],
|
||||
['gstreamer-sharp', { 'option': get_option('sharp') }],
|
||||
['pygobject', { 'option': get_option('python'), 'match_gst_version': false, 'sysdep': 'pygobject-3.0', 'sysdep_version': '>= 3.8' }],
|
||||
['gst-python', { 'option': get_option('python')}],
|
||||
|
|
|
@ -8,7 +8,6 @@ option('devtools', type : 'feature', value : 'enabled')
|
|||
option('ges', type : 'feature', value : 'enabled')
|
||||
option('rtsp_server', type : 'feature', value : 'enabled')
|
||||
option('rs', type : 'feature', value : 'disabled')
|
||||
option('omx', type : 'feature', value : 'disabled')
|
||||
option('vaapi', type : 'feature', value : 'disabled')
|
||||
option('gst-examples', type : 'feature', value : 'auto', description : 'Build gst-examples subproject')
|
||||
# Bindings
|
||||
|
|
|
@ -29,7 +29,6 @@ changelog_starts = {
|
|||
'gst-editing-services': 'ee8bf88ebf131cf7c7161356540efc20bf411e14',
|
||||
'gst-python': 'b3e564eff577e2f577d795051bbcca85d47c89dc',
|
||||
'gstreamer-vaapi': 'c89e9afc5d43837c498a55f8f13ddf235442b83b',
|
||||
'gst-omx': 'd2463b017f222e678978582544a9c9a80edfd330',
|
||||
'gst-devtools': 'da962d096af9460502843e41b7d25fdece7ff1c2',
|
||||
'gstreamer-sharp': 'b94528f8e7979df49fedf137dfa228d8fe475e1b',
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ release_modules = [
|
|||
'gst-devtools',
|
||||
'gst-python',
|
||||
'gstreamer-vaapi',
|
||||
'gst-omx',
|
||||
'gst-docs',
|
||||
'gstreamer-sharp',
|
||||
]
|
||||
|
|
|
@ -101,7 +101,6 @@ GST_PROJECTS = [
|
|||
'gstreamer-vaapi',
|
||||
'gstreamer-sharp',
|
||||
'gst-python',
|
||||
'gst-omx',
|
||||
'gst-editing-services',
|
||||
'gst-devtools',
|
||||
'gst-docs',
|
||||
|
@ -120,7 +119,6 @@ GST_PROJECTS_ID = {
|
|||
'gst-plugins-good': 1353,
|
||||
'gst-plugins-base': 1352,
|
||||
'gst-plugins-bad': 1351,
|
||||
'gst-omx': 1350,
|
||||
'gst-libav': 1349,
|
||||
'gst-integration-testsuites': 1348,
|
||||
'gst-examples': 1347,
|
||||
|
|
|
@ -29,7 +29,6 @@ changelog_starts = {
|
|||
'gst-editing-services': 'ee8bf88ebf131cf7c7161356540efc20bf411e14',
|
||||
'gst-python': 'b3e564eff577e2f577d795051bbcca85d47c89dc',
|
||||
'gstreamer-vaapi': 'c89e9afc5d43837c498a55f8f13ddf235442b83b',
|
||||
'gst-omx': 'd2463b017f222e678978582544a9c9a80edfd330',
|
||||
'gst-devtools': 'da962d096af9460502843e41b7d25fdece7ff1c2',
|
||||
'gstreamer-sharp': 'b94528f8e7979df49fedf137dfa228d8fe475e1b',
|
||||
}
|
||||
|
|
|
@ -43,14 +43,6 @@ Technologies](http://en.wikipedia.org/wiki/Imagination_Technologies) or
|
|||
[S3 Graphics](http://en.wikipedia.org/wiki/S3_Graphics). Accessible to
|
||||
GStreamer through the [gstreamer-vaapi](https://gitlab.freedesktop.org/gstreamer/gstreamer/-/tree/main/subprojects/gstreamer-vaapi/) package.
|
||||
|
||||
- [OpenMAX](http://en.wikipedia.org/wiki/OpenMAX) (*Open Media
|
||||
Acceleration*): Managed by the non-profit technology consortium [Khronos
|
||||
Group](http://en.wikipedia.org/wiki/Khronos_Group "Khronos Group"),
|
||||
it is a "royalty-free, cross-platform set of C-language programming
|
||||
interfaces that provides abstractions for routines especially useful for
|
||||
audio, video, and still images". Accessible to GStreamer through
|
||||
the [gst-omx](http://git.freedesktop.org/gstreamer/gst-omx) plugin.
|
||||
|
||||
- [OVD](http://developer.amd.com/sdks/AMDAPPSDK/assets/OpenVideo_Decode_API.PDF)
|
||||
(*Open Video Decode*): Another API from [AMD
|
||||
Graphics](http://en.wikipedia.org/wiki/AMD_Graphics), designed to be a
|
||||
|
|
|
@ -29,7 +29,6 @@ changelog_starts = {
|
|||
'gst-editing-services': 'ee8bf88ebf131cf7c7161356540efc20bf411e14',
|
||||
'gst-python': 'b3e564eff577e2f577d795051bbcca85d47c89dc',
|
||||
'gstreamer-vaapi': 'c89e9afc5d43837c498a55f8f13ddf235442b83b',
|
||||
'gst-omx': 'd2463b017f222e678978582544a9c9a80edfd330',
|
||||
'gst-devtools': 'da962d096af9460502843e41b7d25fdece7ff1c2',
|
||||
'gstreamer-sharp': 'b94528f8e7979df49fedf137dfa228d8fe475e1b',
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ changelog_starts = {
|
|||
'gst-editing-services': 'ee8bf88ebf131cf7c7161356540efc20bf411e14',
|
||||
'gst-python': 'b3e564eff577e2f577d795051bbcca85d47c89dc',
|
||||
'gstreamer-vaapi': 'c89e9afc5d43837c498a55f8f13ddf235442b83b',
|
||||
'gst-omx': 'd2463b017f222e678978582544a9c9a80edfd330',
|
||||
'gst-devtools': 'da962d096af9460502843e41b7d25fdece7ff1c2',
|
||||
'gstreamer-sharp': 'b94528f8e7979df49fedf137dfa228d8fe475e1b',
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ changelog_starts = {
|
|||
'gst-editing-services': 'ee8bf88ebf131cf7c7161356540efc20bf411e14',
|
||||
'gst-python': 'b3e564eff577e2f577d795051bbcca85d47c89dc',
|
||||
'gstreamer-vaapi': 'c89e9afc5d43837c498a55f8f13ddf235442b83b',
|
||||
'gst-omx': 'd2463b017f222e678978582544a9c9a80edfd330',
|
||||
'gst-devtools': 'da962d096af9460502843e41b7d25fdece7ff1c2',
|
||||
'gstreamer-sharp': 'b94528f8e7979df49fedf137dfa228d8fe475e1b',
|
||||
}
|
||||
|
|
3
subprojects/gst-omx/.gitignore
vendored
3
subprojects/gst-omx/.gitignore
vendored
|
@ -1,3 +0,0 @@
|
|||
*~
|
||||
*.bak
|
||||
*.swp
|
|
@ -1,2 +0,0 @@
|
|||
Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||
|
|
@ -1,502 +0,0 @@
|
|||
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!
|
File diff suppressed because it is too large
Load diff
|
@ -1,17 +0,0 @@
|
|||
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
|
|
@ -1,104 +0,0 @@
|
|||
This is GStreamer gst-omx 1.22.0.
|
||||
|
||||
The GStreamer team is thrilled to announce a new major feature release
|
||||
of your favourite cross-platform multimedia framework!
|
||||
|
||||
As always, this release is again packed with new features, bug fixes and
|
||||
other improvements.
|
||||
|
||||
The 1.22 release series adds new features on top of the 1.20 series and is
|
||||
part of the API and ABI-stable 1.x release series.
|
||||
|
||||
Full release notes can be found at:
|
||||
|
||||
https://gstreamer.freedesktop.org/releases/1.22/
|
||||
|
||||
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
|
||||
|
||||
- gst-plugins-rs: an exciting collection of well-maintained plugins written
|
||||
in the Rust programming language (usable from any language)
|
||||
|
||||
==== 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/gstreamer/
|
||||
|
||||
==== Homepage ====
|
||||
|
||||
The project's website is https://gstreamer.freedesktop.org/
|
||||
|
||||
==== Support and Bugs ====
|
||||
|
||||
We track bugs and feature requests in GitLab:
|
||||
|
||||
https://gitlab.freedesktop.org/gstreamer/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 OFTC IRC network, which is
|
||||
also bridged into the Matrix network.
|
||||
|
||||
Please do not submit support requests in GitLab, we only use it
|
||||
for bug tracking and merge requests review.
|
||||
|
||||
==== Developers ====
|
||||
|
||||
The GStreamer source code repository can be found on GitLab on freedesktop.org:
|
||||
|
||||
https://gitlab.freedesktop.org/gstreamer/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
|
|
@ -1,60 +0,0 @@
|
|||
[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
|
|
@ -1 +0,0 @@
|
|||
install_data (['gstomx.conf'], install_dir : omx_conf_dir)
|
|
@ -1,21 +0,0 @@
|
|||
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)
|
||||
meson.add_devenv({'GST_OMX_CONFIG_DIR': omx_config_dir})
|
||||
else
|
||||
omx_config_dir = ''
|
||||
endif
|
|
@ -1,102 +0,0 @@
|
|||
[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 +0,0 @@
|
|||
install_data (['gstomx.conf'], install_dir : omx_conf_dir)
|
|
@ -1,49 +0,0 @@
|
|||
[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
|
|
@ -1,5 +0,0 @@
|
|||
tizonia_cdata = cdata
|
||||
configure_file(input : 'gstomx.conf.in',
|
||||
output : 'gstomx.conf',
|
||||
configuration : tizonia_cdata,
|
||||
install_dir : omx_conf_dir)
|
|
@ -1,35 +0,0 @@
|
|||
[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
|
|
@ -1 +0,0 @@
|
|||
install_data (['gstomx.conf'], install_dir : omx_conf_dir)
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"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"
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
---
|
||||
short-description: GStreamer plugins from OpenMax
|
||||
...
|
|
@ -1,69 +0,0 @@
|
|||
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_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()
|
||||
gst_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))
|
||||
if host_machine.system() == 'windows'
|
||||
pathsep = ';'
|
||||
else
|
||||
pathsep = ':'
|
||||
endif
|
||||
cdir = meson.current_source_dir()
|
||||
gst_plugins_doc = run_command(
|
||||
plugins_cache_generator,
|
||||
'hotdoc-config',
|
||||
'--builddir', meson.current_build_dir(),
|
||||
'--project_version', api_version,
|
||||
'--sitemap', cdir / 'sitemap.txt',
|
||||
'--index', cdir / 'index.md',
|
||||
'--gst_index', cdir / 'index.md',
|
||||
'--gst_c_sources', cdir / '../gst/*/*.[ch]',
|
||||
'--gst_cache_file', cdir / plugins_cache,
|
||||
check: true,
|
||||
).stdout().split(pathsep)
|
||||
|
|
@ -1 +0,0 @@
|
|||
gst-index
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
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,
|
||||
};
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
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
|
File diff suppressed because it is too large
Load diff
|
@ -1,7 +0,0 @@
|
|||
if get_option('examples').disabled() or static_build or host_machine.system() == 'windows'
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
if gstgl_dep.found()
|
||||
subdir('egl')
|
||||
endif
|
|
@ -1,412 +0,0 @@
|
|||
<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.22.0</revision>
|
||||
<branch>main</branch>
|
||||
<name></name>
|
||||
<created>2023-01-23</created>
|
||||
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.22.0.tar.xz" />
|
||||
</Version>
|
||||
</release>
|
||||
|
||||
<release>
|
||||
<Version>
|
||||
<revision>1.21.90</revision>
|
||||
<branch>main</branch>
|
||||
<name></name>
|
||||
<created>2023-01-13</created>
|
||||
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.21.90.tar.xz" />
|
||||
</Version>
|
||||
</release>
|
||||
|
||||
<release>
|
||||
<Version>
|
||||
<revision>1.21.3</revision>
|
||||
<branch>main</branch>
|
||||
<name></name>
|
||||
<created>2022-12-05</created>
|
||||
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.21.3.tar.xz" />
|
||||
</Version>
|
||||
</release>
|
||||
|
||||
<release>
|
||||
<Version>
|
||||
<revision>1.21.2</revision>
|
||||
<branch>main</branch>
|
||||
<name></name>
|
||||
<created>2022-11-07</created>
|
||||
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.21.2.tar.xz" />
|
||||
</Version>
|
||||
</release>
|
||||
|
||||
<release>
|
||||
<Version>
|
||||
<revision>1.21.1</revision>
|
||||
<branch>main</branch>
|
||||
<name></name>
|
||||
<created>2022-10-04</created>
|
||||
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.21.1.tar.xz" />
|
||||
</Version>
|
||||
</release>
|
||||
|
||||
<release>
|
||||
<Version>
|
||||
<revision>1.20.0</revision>
|
||||
<branch>main</branch>
|
||||
<name></name>
|
||||
<created>2022-02-03</created>
|
||||
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.20.0.tar.xz" />
|
||||
</Version>
|
||||
</release>
|
||||
|
||||
<release>
|
||||
<Version>
|
||||
<revision>1.19.90</revision>
|
||||
<branch>main</branch>
|
||||
<name></name>
|
||||
<created>2022-01-28</created>
|
||||
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.19.90.tar.xz" />
|
||||
</Version>
|
||||
</release>
|
||||
|
||||
<release>
|
||||
<Version>
|
||||
<revision>1.19.3</revision>
|
||||
<branch>main</branch>
|
||||
<name></name>
|
||||
<created>2021-11-03</created>
|
||||
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-omx/gst-omx-1.19.3.tar.xz" />
|
||||
</Version>
|
||||
</release>
|
||||
|
||||
<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>
|
|
@ -1,430 +0,0 @@
|
|||
project('gst-omx', 'c',
|
||||
version : '1.23.0.1',
|
||||
meson_version : '>= 0.62',
|
||||
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.62.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')
|
||||
static_build = get_option('default_library') == 'static'
|
||||
|
||||
|
||||
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
|
||||
|
||||
# glib doesn't support unloading, which means that unloading and reloading
|
||||
# any library that registers static types will fail
|
||||
if cc.has_link_argument('-Wl,-z,nodelete')
|
||||
add_project_link_arguments('-Wl,-z,nodelete', language: 'c')
|
||||
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)
|
||||
gmodule_dep = dependency('gmodule-no-export-2.0', version: glib_req)
|
||||
|
||||
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_variable('gl_winsys').split(' ')
|
||||
gl_platforms = gstgl_dep.get_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_variable('libdir'))
|
||||
tizil_includedir = tizil_dep.get_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',
|
||||
'-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
|
||||
|
||||
subdir('tests')
|
||||
|
||||
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'), check: true)
|
||||
release_date = run_result.stdout().strip()
|
||||
cdata.set_quoted('GST_PACKAGE_RELEASE_DATETIME', release_date)
|
||||
message('Package release date: ' + release_date)
|
||||
endif
|
||||
|
||||
configure_file(output: 'config.h', configuration: cdata)
|
||||
|
||||
meson.add_dist_script('scripts/gen-changelog.py', meson.project_name(), '1.20.0', meson.project_version())
|
|
@ -1,14 +0,0 @@
|
|||
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)
|
File diff suppressed because it is too large
Load diff
|
@ -1,493 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
|
@ -1,296 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
|
@ -1,511 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
|
@ -1,554 +0,0 @@
|
|||
/*
|
||||
* 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_new0 (GstOMXMemory, 1);
|
||||
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_free (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);
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
/*
|
||||
* 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
|
|
@ -1,220 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* 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)
|
||||
{
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
File diff suppressed because it is too large
Load diff
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
File diff suppressed because it is too large
Load diff
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
|
@ -1,674 +0,0 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
|
@ -1,302 +0,0 @@
|
|||
/*
|
||||
* 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 (¶m);
|
||||
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, ¶m);
|
||||
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, ¶m);
|
||||
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 (¶m);
|
||||
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, ¶m);
|
||||
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;
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
|
@ -1,216 +0,0 @@
|
|||
/*
|
||||
* 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 (¶m);
|
||||
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, ¶m);
|
||||
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;
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
|
@ -1,894 +0,0 @@
|
|||
/*
|
||||
* 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 (¶m);
|
||||
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, ¶m);
|
||||
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, ¶m);
|
||||
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 (¶m);
|
||||
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, ¶m);
|
||||
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, ¶m);
|
||||
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 (¶m);
|
||||
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, ¶m);
|
||||
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);
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
|
@ -1,224 +0,0 @@
|
|||
/*
|
||||
* 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 (¶m);
|
||||
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, ¶m);
|
||||
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;
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
|
@ -1,748 +0,0 @@
|
|||
/*
|
||||
* 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 (¶m);
|
||||
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, ¶m);
|
||||
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, ¶m);
|
||||
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 (¶m);
|
||||
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, ¶m);
|
||||
#else
|
||||
err =
|
||||
gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
|
||||
(OMX_INDEXTYPE) OMX_IndexParamVideoHevc, ¶m);
|
||||
#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, ¶m);
|
||||
|
||||
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 (¶m);
|
||||
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, ¶m);
|
||||
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);
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* 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)
|
||||
{
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
|
@ -1,246 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
|
@ -1,278 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
|
@ -1,336 +0,0 @@
|
|||
/*
|
||||
* 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 (¶m);
|
||||
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, ¶m);
|
||||
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, ¶m);
|
||||
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 (¶m);
|
||||
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, ¶m);
|
||||
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;
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
|
@ -1,157 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
||||
|
|
@ -1,356 +0,0 @@
|
|||
/*
|
||||
* 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 (¶m);
|
||||
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, ¶m);
|
||||
|
||||
/* 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_new (GstOMXVideoNegotiationMap, 1);
|
||||
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_free (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;
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
File diff suppressed because it is too large
Load diff
|
@ -1,119 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
File diff suppressed because it is too large
Load diff
|
@ -1,133 +0,0 @@
|
|||
/*
|
||||
* 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__ */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue