mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 14:26:43 +00:00
Merging gstreamer-vaapi
This commit is contained in:
commit
f21e6cdab9
282 changed files with 147735 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
*~
|
1
.gitlab-ci.yml
Normal file
1
.gitlab-ci.yml
Normal file
|
@ -0,0 +1 @@
|
|||
include: "https://gitlab.freedesktop.org/gstreamer/gst-ci/raw/master/gitlab/ci_template.yml"
|
45
AUTHORS
Normal file
45
AUTHORS
Normal file
|
@ -0,0 +1,45 @@
|
|||
Maintainers:
|
||||
|
||||
Gwenole Beauchesne - Lead developer
|
||||
Sreerenj Balachandran - Lead developer
|
||||
Halley Zhao - MPEG-4:2 decoder
|
||||
|
||||
This project is maintained by Intel Corporation.
|
||||
|
||||
Contributors (sorted by first name):
|
||||
|
||||
Adrian Cox
|
||||
Alban Browaeys
|
||||
Changzhi Wei
|
||||
Cong Zhong
|
||||
Emilio Lopez
|
||||
Fabrice Bellet
|
||||
Feng Yuan
|
||||
Guangxin Xu
|
||||
Haihao Xiang
|
||||
Holger Kaelberer
|
||||
Jacobo Aragunde Pérez
|
||||
Jan Schmidt
|
||||
Javier Jardon
|
||||
Julien Isorce
|
||||
Junfeng Xu
|
||||
Kristian Hogsberg
|
||||
Lim Siew Hoon
|
||||
Lionel Landwerlin
|
||||
Mark Nauwelaerts
|
||||
Martin Sherburn
|
||||
Matthew Waters
|
||||
Matthieu Bouron
|
||||
Michael Olbrich
|
||||
Nicolas Dufresne
|
||||
Olivier Crete
|
||||
Philip Lorenz
|
||||
Robert Bradford
|
||||
Ross Burton
|
||||
Sebastian Dröge
|
||||
Simon Farnsworth
|
||||
Thibault Saunier
|
||||
Victor Manuel Jaquez Leal
|
||||
Warly
|
||||
Xiaowei Li
|
||||
Yan Yin
|
502
COPYING.LIB
Normal file
502
COPYING.LIB
Normal file
|
@ -0,0 +1,502 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
299
NEWS
Normal file
299
NEWS
Normal file
|
@ -0,0 +1,299 @@
|
|||
GStreamer 1.20 Release Notes
|
||||
|
||||
GStreamer 1.20 has not been released yet. It is scheduled for release
|
||||
around October/November 2021.
|
||||
|
||||
1.19.x is the unstable development version that is being developed in
|
||||
the git main branch and which will eventually result in 1.20, and 1.19.2
|
||||
is the current development release in that series
|
||||
|
||||
It is expected that feature freeze will be in early October 2021,
|
||||
followed by one or two 1.19.9x pre-releases and the new 1.20 stable
|
||||
release around October/November 2021.
|
||||
|
||||
1.20 will be backwards-compatible to the stable 1.18, 1.16, 1.14, 1.12,
|
||||
1.10, 1.8, 1.6,, 1.4, 1.2 and 1.0 release series.
|
||||
|
||||
See https://gstreamer.freedesktop.org/releases/1.20/ for the latest
|
||||
version of this document.
|
||||
|
||||
Last updated: Wednesday 22 September 2021, 18:00 UTC (log)
|
||||
|
||||
Introduction
|
||||
|
||||
The GStreamer team is proud to announce a new major feature release in
|
||||
the stable 1.x API series of your favourite cross-platform multimedia
|
||||
framework!
|
||||
|
||||
As always, this release is again packed with many new features, bug
|
||||
fixes and other improvements.
|
||||
|
||||
Highlights
|
||||
|
||||
- this section will be completed in due course
|
||||
|
||||
Major new features and changes
|
||||
|
||||
Noteworthy new features and API
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
New elements
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
New element features and additions
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
Plugin and library moves
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
- There were no plugin moves or library moves in this cycle.
|
||||
|
||||
Plugin removals
|
||||
|
||||
The following elements or plugins have been removed:
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
Miscellaneous API additions
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
Miscellaneous performance, latency and memory optimisations
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
Miscellaneous other changes and enhancements
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
Tracing framework and debugging improvements
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
Tools
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
GStreamer RTSP server
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
GStreamer VAAPI
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
GStreamer OMX
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
GStreamer Editing Services and NLE
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
GStreamer validate
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
GStreamer Python Bindings
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
GStreamer C# Bindings
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
GStreamer Rust Bindings and Rust Plugins
|
||||
|
||||
The GStreamer Rust bindings are released separately with a different
|
||||
release cadence that’s tied to gtk-rs, but the latest release has
|
||||
already been updated for the upcoming new GStreamer 1.20 API.
|
||||
|
||||
gst-plugins-rs, the module containing GStreamer plugins written in Rust,
|
||||
has also seen lots of activity with many new elements and plugins.
|
||||
|
||||
What follows is a list of elements and plugins available in
|
||||
gst-plugins-rs, so people don’t miss out on all those potentially useful
|
||||
elements that have no C equivalent.
|
||||
|
||||
- FIXME: add new elements
|
||||
|
||||
Rust audio plugins
|
||||
|
||||
- audiornnoise: New element for audio denoising which implements the
|
||||
noise removal algorithm of the Xiph RNNoise library, in Rust
|
||||
- rsaudioecho: Port of the audioecho element from gst-plugins-good
|
||||
rsaudioloudnorm: Live audio loudness normalization element based on
|
||||
the FFmpeg af_loudnorm filter
|
||||
- claxondec: FLAC lossless audio codec decoder element based on the
|
||||
pure-Rust claxon implementation
|
||||
- csoundfilter: Audio filter that can use any filter defined via the
|
||||
Csound audio programming language
|
||||
- lewtondec: Vorbis audio decoder element based on the pure-Rust
|
||||
lewton implementation
|
||||
|
||||
Rust video plugins
|
||||
|
||||
- cdgdec/cdgparse: Decoder and parser for the CD+G video codec based
|
||||
on a pure-Rust CD+G implementation, used for example by karaoke CDs
|
||||
- cea608overlay: CEA-608 Closed Captions overlay element
|
||||
- cea608tott: CEA-608 Closed Captions to timed-text (e.g. VTT or SRT
|
||||
subtitles) converter
|
||||
- tttocea608: CEA-608 Closed Captions from timed-text converter
|
||||
- mccenc/mccparse: MacCaption Closed Caption format encoder and parser
|
||||
- sccenc/sccparse: Scenarist Closed Caption format encoder and parser
|
||||
- dav1dec: AV1 video decoder based on the dav1d decoder implementation
|
||||
by the VLC project
|
||||
- rav1enc: AV1 video encoder based on the fast and pure-Rust rav1e
|
||||
encoder implementation
|
||||
- rsflvdemux: Alternative to the flvdemux FLV demuxer element from
|
||||
gst-plugins-good, not feature-equivalent yet
|
||||
- rsgifenc/rspngenc: GIF/PNG encoder elements based on the pure-Rust
|
||||
implementations by the image-rs project
|
||||
|
||||
Rust text plugins
|
||||
|
||||
- textwrap: Element for line-wrapping timed text (e.g. subtitles) for
|
||||
better screen-fitting, including hyphenation support for some
|
||||
languages
|
||||
|
||||
Rust network plugins
|
||||
|
||||
- reqwesthttpsrc: HTTP(S) source element based on the Rust
|
||||
reqwest/hyper HTTP implementations and almost feature-equivalent
|
||||
with the main GStreamer HTTP source souphttpsrc
|
||||
- s3src/s3sink: Source/sink element for the Amazon S3 cloud storage
|
||||
- awstranscriber: Live audio to timed text transcription element using
|
||||
the Amazon AWS Transcribe API
|
||||
|
||||
Generic Rust plugins
|
||||
|
||||
- sodiumencrypter/sodiumdecrypter: Encryption/decryption element based
|
||||
on libsodium/NaCl
|
||||
- togglerecord: Recording element that allows to pause/resume
|
||||
recordings easily and considers keyframe boundaries
|
||||
- fallbackswitch/fallbacksrc: Elements for handling potentially
|
||||
failing (network) sources, restarting them on errors/timeout and
|
||||
showing a fallback stream instead
|
||||
- threadshare: Set of elements that provide alternatives for various
|
||||
existing GStreamer elements but allow to share the streaming threads
|
||||
between each other to reduce the number of threads
|
||||
- rsfilesrc/rsfilesink: File source/sink elements as replacements for
|
||||
the existing filesrc/filesink elements
|
||||
|
||||
Build and Dependencies
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
gst-build
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
Cerbero
|
||||
|
||||
Cerbero is a meta build system used to build GStreamer plus dependencies
|
||||
on platforms where dependencies are not readily available, such as
|
||||
Windows, Android, iOS and macOS.
|
||||
|
||||
General improvements
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
macOS / iOS
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
Windows
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
Windows MSI installer
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
Linux
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
Android
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
Platform-specific changes and improvements
|
||||
|
||||
Android
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
macOS and iOS
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
Windows
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
Linux
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
Documentation improvements
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
Possibly Breaking Changes
|
||||
|
||||
- this section will be filled in in due course
|
||||
- MPEG-TS SCTE-35 API changes (FIXME: flesh out)
|
||||
- gst_parse_launch() and friends now error out on non-existing
|
||||
properties on top-level bins where they would silently fail and
|
||||
ignore those before.
|
||||
|
||||
Known Issues
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
- There are a couple of known WebRTC-related regressions/blockers:
|
||||
|
||||
- webrtc: DTLS setup with Chrome is broken
|
||||
- webrtcbin: First keyframe is usually lost
|
||||
|
||||
Contributors
|
||||
|
||||
- this section will be filled in in due course
|
||||
|
||||
… and many others who have contributed bug reports, translations, sent
|
||||
suggestions or helped testing.
|
||||
|
||||
Stable 1.20 branch
|
||||
|
||||
After the 1.20.0 release there will be several 1.20.x bug-fix releases
|
||||
which will contain bug fixes which have been deemed suitable for a
|
||||
stable branch, but no new features or intrusive changes will be added to
|
||||
a bug-fix release usually. The 1.20.x bug-fix releases will be made from
|
||||
the git 1.20 branch, which will be a stable branch.
|
||||
|
||||
1.20.0
|
||||
|
||||
1.20.0 is scheduled to be released around October/November 2021.
|
||||
|
||||
Schedule for 1.22
|
||||
|
||||
Our next major feature release will be 1.22, and 1.21 will be the
|
||||
unstable development version leading up to the stable 1.22 release. The
|
||||
development of 1.21/1.22 will happen in the git main branch.
|
||||
|
||||
The plan for the 1.22 development cycle is yet to be confirmed.
|
||||
|
||||
1.22 will be backwards-compatible to the stable 1.20, 1.18, 1.16, 1.14,
|
||||
1.12, 1.10, 1.8, 1.6, 1.4, 1.2 and 1.0 release series.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
These release notes have been prepared by Tim-Philipp Müller with
|
||||
contributions from …
|
||||
|
||||
License: CC BY-SA 4.0
|
133
README
Normal file
133
README
Normal file
|
@ -0,0 +1,133 @@
|
|||
|
||||
gstreamer-vaapi
|
||||
VA-API support to GStreamer
|
||||
|
||||
Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
Copyright (C) 2011-2020 Intel Corporation
|
||||
Copyright (C) 2011 Collabora Ltd.
|
||||
Copyright (C) 2015-2020 Igalia, S.L.
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
gstreamer-vaapi helper libraries and plugin elements are available
|
||||
under the terms of the GNU Lesser General Public License v2.1+
|
||||
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
gstreamer-vaapi consists in a collection of VA-API based plugins for
|
||||
GStreamer and helper libraries.
|
||||
|
||||
* `vaapi<CODEC>dec' is used to decode JPEG, MPEG-2, MPEG-4:2, H.264
|
||||
AVC, H.264 MVC, VP8, VP9, VC-1, WMV3, HEVC videos to VA surfaces,
|
||||
depending on the actual value of <CODEC> and the underlying
|
||||
hardware capabilities. This plugin is also able to implicitly
|
||||
download the decoded surface to raw YUV buffers.
|
||||
|
||||
* `vaapi<CODEC>enc' is used to encode into MPEG-2, H.264 AVC, H.264
|
||||
MVC, JPEG, VP8, VP9, HEVC videos, depending on the actual value of
|
||||
<CODEC> (mpeg2, h264, etc.) and the hardware capabilities. By
|
||||
default, raw format bitstreams are generated, so the result may be
|
||||
piped to a muxer, e.g. qtmux for MP4 containers.
|
||||
|
||||
* `vaapipostproc' is used to filter VA surfaces, for e.g. scaling,
|
||||
deinterlacing (bob, motion-adaptive, motion-compensated), noise
|
||||
reduction or sharpening. This plugin is also used to upload raw
|
||||
YUV pixels into VA surfaces.
|
||||
|
||||
* `vaapisink' is used to render VA surfaces to an X11 or Wayland
|
||||
display. This plugin also features a "headless" mode (DRM) more
|
||||
suited to remote transcode scenarios, with faster throughput.
|
||||
|
||||
* `vaapioverlay` is a accelerated compositor that blends or
|
||||
composite different video streams.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* VA-API support from 0.39
|
||||
* JPEG, MPEG-2, MPEG-4, H.264 AVC, H.264 MVC, VP8, VC-1, HEVC and
|
||||
VP9 ad-hoc decoders
|
||||
* MPEG-2, H.264 AVC,H.264 MVC, JPEG, VP8, VP9 and HEVC ad-hoc
|
||||
encoders
|
||||
* OpenGL rendering through VA/GLX or GLX texture-from-pixmap + FBO
|
||||
* Support for EGL backend
|
||||
* Support for the Wayland display server
|
||||
* Support for headless decode pipelines with VA/DRM
|
||||
* Support for major HW video decoding solutions on Linux (AMD,
|
||||
Intel, NVIDIA)
|
||||
* Support for HW video encoding on Intel HD Graphics hardware
|
||||
* Support for VA Video Processing APIs (VA/VPP)
|
||||
- Scaling and color conversion
|
||||
- Image enhancement filters: Sharpening, Noise Reductio, Color
|
||||
Balance, Skin-Tone-Enhancement
|
||||
- Advanced deinterlacing: Motion-Adaptive, Motion-Compensated
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
Hardware requirements
|
||||
|
||||
* Hardware supported by i965 driver or iHD, such as
|
||||
- Intel Ironlake, Sandybridge, Ivybridge, Haswell, Broadwell,
|
||||
Skylake, etc. (HD Graphics)
|
||||
- Intel BayTrail, Braswell
|
||||
- Intel Poulsbo (US15W)
|
||||
- Intel Medfield or Cedar Trail
|
||||
* Hardware supported by AMD Radeonsi driver, such as the list below
|
||||
- AMD Carrizo, Bristol Ridge, Raven Ridge, Picasso, Renoir
|
||||
- AMD Tonga, Fiji, Polaris XX, Vega XX, Navi 1X
|
||||
* Other hardware supported by Mesa VA gallium state-tracker
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
VA elements are automatically plugged into GStreamer pipelines. So,
|
||||
using playbin should work as is.
|
||||
However, here are a few alternate pipelines that could be manually
|
||||
constructed.
|
||||
|
||||
* Play an H.264 video with an MP4 container in fullscreen mode
|
||||
$ gst-launch-1.0 -v filesrc location=/path/to/video.mp4 ! \
|
||||
qtdemux ! vaapidecodebin ! vaapisink fullscreen=true
|
||||
|
||||
* Play a raw MPEG-2 interlaced stream
|
||||
$ gst-launch-1.0 -v filesrc location=/path/to/mpeg2.bits ! \
|
||||
mpegvideoparse ! vaapimpeg2dec ! vaapipostproc ! vaapisink
|
||||
|
||||
* Convert from one pixel format to another, while also downscaling
|
||||
$ gst-launch-1.0 -v filesrc location=/path/to/raw_video.yuv ! \
|
||||
videoparse format=yuy2 width=1280 height=720 ! \
|
||||
vaapipostproc format=nv12 height=480 ! vaapisink
|
||||
|
||||
* Encode a 1080p stream in raw I420 format into H.264
|
||||
$ gst-launch-1.0 -v filesrc location=/path/to/raw_video.yuv ! \
|
||||
videoparse format=i420 width=1920 height=1080 framerate=30/1 ! \
|
||||
vaapih264enc rate-control=cbr tune=high-compression ! \
|
||||
qtmux ! filesink location=/path/to/encoded_video.mp4
|
||||
|
||||
|
||||
Sources
|
||||
-------
|
||||
|
||||
gstreamer-vaapi is Open Source software, so updates to this
|
||||
framework are really easy to get.
|
||||
|
||||
Stable source code releases can be found at:
|
||||
<https://gstreamer.freedesktop.org/src/gstreamer-vaapi/>
|
||||
|
||||
GitLab repository for work-in-progress changes is available at:
|
||||
<https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi>
|
||||
|
||||
|
||||
Reporting Bugs
|
||||
--------------
|
||||
|
||||
Bugs can be reported in the GStreamer's GitLab system at:
|
||||
<https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues>
|
96
RELEASE
Normal file
96
RELEASE
Normal file
|
@ -0,0 +1,96 @@
|
|||
This is GStreamer gstreamer-vaapi 1.19.2.
|
||||
|
||||
GStreamer 1.19 is the development branch leading up to the next major
|
||||
stable version which will be 1.20.
|
||||
|
||||
The 1.19 development series adds new features on top of the 1.18 series and is
|
||||
part of the API and ABI-stable 1.x release series of the GStreamer multimedia
|
||||
framework.
|
||||
|
||||
Full release notes will one day be found at:
|
||||
|
||||
https://gstreamer.freedesktop.org/releases/1.20/
|
||||
|
||||
Binaries for Android, iOS, Mac OS X and Windows will usually be provided
|
||||
shortly after the release.
|
||||
|
||||
This module will not be very useful by itself and should be used in conjunction
|
||||
with other GStreamer modules for a complete multimedia experience.
|
||||
|
||||
- gstreamer: provides the core GStreamer libraries and some generic plugins
|
||||
|
||||
- gst-plugins-base: a basic set of well-supported plugins and additional
|
||||
media-specific GStreamer helper libraries for audio,
|
||||
video, rtsp, rtp, tags, OpenGL, etc.
|
||||
|
||||
- gst-plugins-good: a set of well-supported plugins under our preferred
|
||||
license
|
||||
|
||||
- gst-plugins-ugly: a set of well-supported plugins which might pose
|
||||
problems for distributors
|
||||
|
||||
- gst-plugins-bad: a set of plugins of varying quality that have not made
|
||||
their way into one of core/base/good/ugly yet, for one
|
||||
reason or another. Many of these are are production quality
|
||||
elements, but may still be missing documentation or unit
|
||||
tests; others haven't passed the rigorous quality testing
|
||||
we expect yet.
|
||||
|
||||
- gst-libav: a set of codecs plugins based on the ffmpeg library. This is
|
||||
where you can find audio and video decoders and encoders
|
||||
for a wide variety of formats including H.264, AAC, etc.
|
||||
|
||||
- gstreamer-vaapi: hardware-accelerated video decoding and encoding using
|
||||
VA-API on Linux. Primarily for Intel graphics hardware.
|
||||
|
||||
- gst-omx: hardware-accelerated video decoding and encoding, primarily for
|
||||
embedded Linux systems that provide an OpenMax
|
||||
implementation layer such as the Raspberry Pi.
|
||||
|
||||
- gst-rtsp-server: library to serve files or streaming pipelines via RTSP
|
||||
|
||||
- gst-editing-services: library an plugins for non-linear editing
|
||||
|
||||
==== Download ====
|
||||
|
||||
You can find source releases of gstreamer in the download
|
||||
directory: https://gstreamer.freedesktop.org/src/gstreamer/
|
||||
|
||||
The git repository and details how to clone it can be found at
|
||||
https://gitlab.freedesktop.org/gstreamer/
|
||||
|
||||
==== Homepage ====
|
||||
|
||||
The project's website is https://gstreamer.freedesktop.org/
|
||||
|
||||
==== Support and Bugs ====
|
||||
|
||||
We have recently moved from GNOME Bugzilla to GitLab on freedesktop.org
|
||||
for bug reports and feature requests:
|
||||
|
||||
https://gitlab.freedesktop.org/gstreamer
|
||||
|
||||
Please submit patches via GitLab as well, in form of Merge Requests. See
|
||||
|
||||
https://gstreamer.freedesktop.org/documentation/contribute/
|
||||
|
||||
for more details.
|
||||
|
||||
For help and support, please subscribe to and send questions to the
|
||||
gstreamer-devel mailing list (see below for details).
|
||||
|
||||
There is also a #gstreamer IRC channel on the Freenode IRC network.
|
||||
|
||||
==== Developers ====
|
||||
|
||||
GStreamer source code repositories can be found on GitLab on freedesktop.org:
|
||||
|
||||
https://gitlab.freedesktop.org/gstreamer
|
||||
|
||||
and can also be cloned from there and this is also where you can submit
|
||||
Merge Requests or file issues for bugs or feature requests.
|
||||
|
||||
Interested developers of the core library, plugins, and applications should
|
||||
subscribe to the gstreamer-devel list:
|
||||
|
||||
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
|
2018
docs/gst_plugins_cache.json
Normal file
2018
docs/gst_plugins_cache.json
Normal file
File diff suppressed because it is too large
Load diff
34
docs/index.md
Normal file
34
docs/index.md
Normal file
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
short-description: GStreamer plugins from gstreamer-vaapi
|
||||
...
|
||||
|
||||
# VAAPI Plugin
|
||||
|
||||
## Environment variables
|
||||
|
||||
GStreamer-VAAPI inspects a few of environment variables to define it
|
||||
usage.
|
||||
|
||||
**GST_VAAPI_ALL_DRIVERS.**
|
||||
|
||||
This environment variable can be set, independently of its value, to
|
||||
disable the drivers white list. By default only intel and mesa va
|
||||
drivers are loaded if they are available. The rest are ignored. With
|
||||
this environment variable defined, all the available va drivers are
|
||||
loaded, even if they are deprecated.
|
||||
|
||||
**LIBVA_DRIVER_NAME.**
|
||||
|
||||
This environment variable can be set with the drivers name to load. For
|
||||
example, intel's driver is `i915`, meanwhile mesa is `gallium`.
|
||||
|
||||
**LIBVA_DRIVERS_PATH.**
|
||||
|
||||
This environment variable can be set to a colon-separated list of paths
|
||||
(or a semicolon-separated list on Windows). libva will scan these paths
|
||||
for va drivers.
|
||||
|
||||
**GST_VAAPI_DRM_DEVICE.**
|
||||
This environment variable can be set to a specified DRM device when DRM
|
||||
display is used, it is ignored when other types of displays are used.
|
||||
By default /dev/dri/renderD128 is used for DRM display.
|
74
docs/meson.build
Normal file
74
docs/meson.build
Normal file
|
@ -0,0 +1,74 @@
|
|||
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 it while cross building is not supported yet.')
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
required_hotdoc_extensions = ['gi-extension', 'gst-extension']
|
||||
if gst_dep.type_name() == 'internal'
|
||||
gst_proj = subproject('gstreamer')
|
||||
plugins_cache_generator = gst_proj.get_variable('plugins_cache_generator')
|
||||
else
|
||||
plugins_cache_generator = find_program(join_paths(gst_dep.get_pkgconfig_variable('libexecdir'), 'gstreamer-' + api_version, 'gst-plugins-doc-cache-generator'),
|
||||
required: false)
|
||||
endif
|
||||
|
||||
plugins_cache = join_paths(meson.current_source_dir(), 'gst_plugins_cache.json')
|
||||
if plugins_cache_generator.found()
|
||||
plugins_doc_dep = custom_target('vaapi-plugins-doc-cache',
|
||||
command: [plugins_cache_generator, plugins_cache, '@OUTPUT@', '@INPUT@'],
|
||||
input: plugins,
|
||||
output: 'gst_plugins_cache.json',
|
||||
build_always_stale: true,
|
||||
)
|
||||
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
|
||||
|
||||
hotdoc_req = '>= 0.11.0'
|
||||
hotdoc_version = run_command(hotdoc_p, '--version').stdout()
|
||||
if not hotdoc_version.version_compare(hotdoc_req)
|
||||
if get_option('doc').enabled()
|
||||
error('Hotdoc version @0@ not found, got @1@'.format(hotdoc_req, hotdoc_version))
|
||||
else
|
||||
message('Hotdoc version @0@ not found, got @1@'.format(hotdoc_req, hotdoc_version))
|
||||
subdir_done()
|
||||
endif
|
||||
endif
|
||||
|
||||
build_hotdoc = true
|
||||
hotdoc = import('hotdoc')
|
||||
if not hotdoc.has_extensions(required_hotdoc_extensions)
|
||||
if get_option('doc').enabled()
|
||||
error('Documentation enabled but gi-extension missing')
|
||||
endif
|
||||
|
||||
message('@0@ extensions not found, not building documentation'.format(required_hotdoc_extensions))
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
message('Plugins: @0@'.format(plugins))
|
||||
libs_doc = []
|
||||
plugins_doc = [hotdoc.generate_doc('vaapi',
|
||||
project_version: api_version,
|
||||
sitemap: 'sitemap.txt',
|
||||
index: 'index.md',
|
||||
gst_index: 'index.md',
|
||||
gst_smart_index: true,
|
||||
gst_c_sources: ['../gst/*/*.[ch]',],
|
||||
gst_cache_file: plugins_cache,
|
||||
gst_plugin_name: 'vaapi',
|
||||
dependencies: [gstbase_dep, gstvideo_dep, gstallocators_dep, gstpbutils_dep,
|
||||
libva_dep, gstlibvaapi_dep, gstgl_dep, libm] + plugins,
|
||||
)]
|
1
docs/sitemap.txt
Normal file
1
docs/sitemap.txt
Normal file
|
@ -0,0 +1 @@
|
|||
gst-index
|
1
gst-libs/gst/meson.build
Normal file
1
gst-libs/gst/meson.build
Normal file
|
@ -0,0 +1 @@
|
|||
subdir('vaapi')
|
39
gst-libs/gst/vaapi/egl_compat.h
Normal file
39
gst-libs/gst/vaapi/egl_compat.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* egl_compat.h - EGL compatiliby layer
|
||||
*
|
||||
* Copyright (C) 2014 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef EGL_COMPAT_H
|
||||
#define EGL_COMPAT_H
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include "ogl_compat.h"
|
||||
|
||||
#ifndef GL_OES_EGL_image
|
||||
#define GL_OES_EGL_image 1
|
||||
typedef void *GLeglImageOES;
|
||||
typedef void (*PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)(GLenum target,
|
||||
GLeglImageOES image);
|
||||
typedef void (*PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC)(GLenum target,
|
||||
GLeglImageOES image);
|
||||
#endif /* GL_OES_EGL_image */
|
||||
|
||||
#endif /* EGL_COMPAT_H */
|
806
gst-libs/gst/vaapi/egl_vtable.h
Normal file
806
gst-libs/gst/vaapi/egl_vtable.h
Normal file
|
@ -0,0 +1,806 @@
|
|||
/*
|
||||
* egl_vtable.h - EGL function definitions
|
||||
*
|
||||
* Copyright (C) 2014 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// Generate strings
|
||||
|
||||
#define GL_PROTO_GEN_STRING(x) \
|
||||
GL_PROTO_GEN_STRING_I(x)
|
||||
#define GL_PROTO_GEN_STRING_I(x) \
|
||||
#x
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// Concatenate arguments
|
||||
|
||||
#define GL_PROTO_GEN_CONCAT(a1, a2) \
|
||||
GL_PROTO_GEN_CONCAT2_I(a1, a2)
|
||||
#define GL_PROTO_GEN_CONCAT2(a1, a2) \
|
||||
GL_PROTO_GEN_CONCAT2_I(a1, a2)
|
||||
#define GL_PROTO_GEN_CONCAT2_I(a1, a2) \
|
||||
a1 ## a2
|
||||
|
||||
#define GL_PROTO_GEN_CONCAT3(a1, a2, a3) \
|
||||
GL_PROTO_GEN_CONCAT3_I(a1, a2, a3)
|
||||
#define GL_PROTO_GEN_CONCAT3_I(a1, a2, a3) \
|
||||
a1 ## a2 ## a3
|
||||
|
||||
#define GL_PROTO_GEN_CONCAT4(a1, a2, a3, a4) \
|
||||
GL_PROTO_GEN_CONCAT4_I(a1, a2, a3, a4)
|
||||
#define GL_PROTO_GEN_CONCAT4_I(a1, a2, a3, a4) \
|
||||
a1 ## a2 ## a3 ## a4
|
||||
|
||||
#define GL_PROTO_GEN_CONCAT5(a1, a2, a3, a4, a5) \
|
||||
GL_PROTO_GEN_CONCAT5_I(a1, a2, a3, a4, a5)
|
||||
#define GL_PROTO_GEN_CONCAT5_I(a1, a2, a3, a4, a5) \
|
||||
a1 ## a2 ## a3 ## a4 ## a5
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// Default macros
|
||||
|
||||
#ifndef EGL_PROTO_BEGIN
|
||||
#define EGL_PROTO_BEGIN(NAME, TYPE, EXTENSION)
|
||||
#endif
|
||||
#ifndef EGL_PROTO_ARG_LIST
|
||||
#define EGL_PROTO_ARG_LIST(...) GL_PROTO_ARG_LIST(__VA_ARGS__)
|
||||
#endif
|
||||
#ifndef EGL_PROTO_ARG
|
||||
#define EGL_PROTO_ARG(NAME, TYPE) GL_PROTO_ARG(NAME, TYPE)
|
||||
#endif
|
||||
#ifndef EGL_PROTO_INVOKE
|
||||
#define EGL_PROTO_INVOKE(NAME, TYPE, ARGS)
|
||||
#endif
|
||||
#ifndef EGL_PROTO_END
|
||||
#define EGL_PROTO_END()
|
||||
#endif
|
||||
#ifndef EGL_DEFINE_EXTENSION
|
||||
#define EGL_DEFINE_EXTENSION(EXTENSION)
|
||||
#endif
|
||||
|
||||
#ifndef GL_PROTO_BEGIN
|
||||
#define GL_PROTO_BEGIN(NAME, TYPE, EXTENSION)
|
||||
#endif
|
||||
#ifndef GL_PROTO_ARG_LIST
|
||||
#define GL_PROTO_ARG_LIST(...)
|
||||
#endif
|
||||
#ifndef GL_PROTO_ARG
|
||||
#define GL_PROTO_ARG(NAME, TYPE)
|
||||
#endif
|
||||
#ifndef GL_PROTO_INVOKE
|
||||
#define GL_PROTO_INVOKE(NAME, TYPE, ARGS)
|
||||
#endif
|
||||
#ifndef GL_PROTO_END
|
||||
#define GL_PROTO_END()
|
||||
#endif
|
||||
#ifndef GL_DEFINE_EXTENSION
|
||||
#define GL_DEFINE_EXTENSION(EXTENSION)
|
||||
#endif
|
||||
|
||||
/* NOTE: this is auto-generated code -- do not edit! */
|
||||
|
||||
EGL_PROTO_BEGIN(CreateImageKHR, EGLImageKHR, KHR_image_base)
|
||||
EGL_PROTO_ARG_LIST(
|
||||
EGL_PROTO_ARG(dpy, EGLDisplay),
|
||||
EGL_PROTO_ARG(ctx, EGLContext),
|
||||
EGL_PROTO_ARG(target, EGLenum),
|
||||
EGL_PROTO_ARG(buffer, EGLClientBuffer),
|
||||
EGL_PROTO_ARG(attrib_list, const EGLint *))
|
||||
EGL_PROTO_INVOKE(CreateImageKHR, EGLImageKHR, (dpy, ctx, target, buffer, attrib_list))
|
||||
EGL_PROTO_END()
|
||||
|
||||
EGL_PROTO_BEGIN(DestroyImageKHR, EGLImageKHR, KHR_image_base)
|
||||
EGL_PROTO_ARG_LIST(
|
||||
EGL_PROTO_ARG(dpy, EGLDisplay),
|
||||
EGL_PROTO_ARG(image, EGLImageKHR))
|
||||
EGL_PROTO_INVOKE(DestroyImageKHR, EGLImageKHR, (dpy, image))
|
||||
EGL_PROTO_END()
|
||||
|
||||
EGL_PROTO_BEGIN(CreateDRMImageMESA, EGLImageKHR, MESA_drm_image)
|
||||
EGL_PROTO_ARG_LIST(
|
||||
EGL_PROTO_ARG(dpy, EGLDisplay),
|
||||
EGL_PROTO_ARG(attrib_list, const EGLint *))
|
||||
EGL_PROTO_INVOKE(CreateDRMImageMESA, EGLImageKHR, (dpy, attrib_list))
|
||||
EGL_PROTO_END()
|
||||
|
||||
EGL_PROTO_BEGIN(ExportDRMImageMESA, EGLImageKHR, MESA_drm_image)
|
||||
EGL_PROTO_ARG_LIST(
|
||||
EGL_PROTO_ARG(dpy, EGLDisplay),
|
||||
EGL_PROTO_ARG(image, EGLImageKHR),
|
||||
EGL_PROTO_ARG(name, EGLint *),
|
||||
EGL_PROTO_ARG(handle, EGLint *),
|
||||
EGL_PROTO_ARG(stride, EGLint *))
|
||||
EGL_PROTO_INVOKE(ExportDRMImageMESA, EGLImageKHR, (dpy, image, name, handle, stride))
|
||||
EGL_PROTO_END()
|
||||
|
||||
EGL_PROTO_BEGIN(ExportDMABUFImageMESA, EGLBoolean, MESA_image_dma_buf_export)
|
||||
EGL_PROTO_ARG_LIST(
|
||||
EGL_PROTO_ARG(dpy, EGLDisplay),
|
||||
EGL_PROTO_ARG(image, EGLImageKHR),
|
||||
EGL_PROTO_ARG(fds, int *),
|
||||
EGL_PROTO_ARG(strides, EGLint *),
|
||||
EGL_PROTO_ARG(offsets, EGLint *))
|
||||
EGL_PROTO_INVOKE(ExportDMABUFImageMESA, EGLBoolean, (dpy, image, fds, strides, offsets))
|
||||
EGL_PROTO_END()
|
||||
|
||||
EGL_PROTO_BEGIN(ExportDMABUFImageQueryMESA, EGLBoolean, MESA_image_dma_buf_export)
|
||||
EGL_PROTO_ARG_LIST(
|
||||
EGL_PROTO_ARG(dpy, EGLDisplay),
|
||||
EGL_PROTO_ARG(image, EGLImageKHR),
|
||||
EGL_PROTO_ARG(fourcc, int *),
|
||||
EGL_PROTO_ARG(num_planes, int *),
|
||||
EGL_PROTO_ARG(modifiers, EGLuint64KHR *))
|
||||
EGL_PROTO_INVOKE(ExportDMABUFImageQueryMESA, EGLBoolean, (dpy, image, fourcc, num_planes, modifiers))
|
||||
EGL_PROTO_END()
|
||||
|
||||
EGL_DEFINE_EXTENSION(EXT_image_dma_buf_import)
|
||||
EGL_DEFINE_EXTENSION(KHR_create_context)
|
||||
EGL_DEFINE_EXTENSION(KHR_gl_texture_2D_image)
|
||||
EGL_DEFINE_EXTENSION(KHR_image_base)
|
||||
EGL_DEFINE_EXTENSION(KHR_surfaceless_context)
|
||||
EGL_DEFINE_EXTENSION(MESA_configless_context)
|
||||
EGL_DEFINE_EXTENSION(MESA_drm_image)
|
||||
EGL_DEFINE_EXTENSION(MESA_image_dma_buf_export)
|
||||
|
||||
GL_PROTO_BEGIN(GetError, GLenum, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST()
|
||||
GL_PROTO_INVOKE(GetError, GLenum, ())
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(GetString, const GLubyte *, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(name, GLenum))
|
||||
GL_PROTO_INVOKE(GetString, const GLubyte *, (name))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(GetIntegerv, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(pname, GLenum),
|
||||
GL_PROTO_ARG(params, GLint *))
|
||||
GL_PROTO_INVOKE(GetIntegerv, void, (pname, params))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Enable, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(cap, GLenum))
|
||||
GL_PROTO_INVOKE(Enable, void, (cap))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Disable, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(cap, GLenum))
|
||||
GL_PROTO_INVOKE(Disable, void, (cap))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(IsEnabled, GLboolean, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(cap, GLenum))
|
||||
GL_PROTO_INVOKE(IsEnabled, GLboolean, (cap))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Finish, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST()
|
||||
GL_PROTO_INVOKE(Finish, void, ())
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Flush, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST()
|
||||
GL_PROTO_INVOKE(Flush, void, ())
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Begin, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(mode, GLenum))
|
||||
GL_PROTO_INVOKE(Begin, void, (mode))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(End, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST()
|
||||
GL_PROTO_INVOKE(End, void, ())
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Color4f, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(red, GLfloat),
|
||||
GL_PROTO_ARG(green, GLfloat),
|
||||
GL_PROTO_ARG(blue, GLfloat),
|
||||
GL_PROTO_ARG(alpha, GLfloat))
|
||||
GL_PROTO_INVOKE(Color4f, void, (red, green, blue, alpha))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Clear, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(mask, GLbitfield))
|
||||
GL_PROTO_INVOKE(Clear, void, (mask))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(ClearColor, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(red, GLclampf),
|
||||
GL_PROTO_ARG(green, GLclampf),
|
||||
GL_PROTO_ARG(blue, GLclampf),
|
||||
GL_PROTO_ARG(alpha, GLclampf))
|
||||
GL_PROTO_INVOKE(ClearColor, void, (red, green, blue, alpha))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(PushMatrix, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST()
|
||||
GL_PROTO_INVOKE(PushMatrix, void, ())
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(PopMatrix, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST()
|
||||
GL_PROTO_INVOKE(PopMatrix, void, ())
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(LoadIdentity, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST()
|
||||
GL_PROTO_INVOKE(LoadIdentity, void, ())
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(MatrixMode, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(mode, GLenum))
|
||||
GL_PROTO_INVOKE(MatrixMode, void, (mode))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(PushAttrib, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(mask, GLbitfield))
|
||||
GL_PROTO_INVOKE(PushAttrib, void, (mask))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(PopAttrib, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST()
|
||||
GL_PROTO_INVOKE(PopAttrib, void, ())
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Viewport, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(x, GLint),
|
||||
GL_PROTO_ARG(y, GLint),
|
||||
GL_PROTO_ARG(width, GLsizei),
|
||||
GL_PROTO_ARG(height, GLsizei))
|
||||
GL_PROTO_INVOKE(Viewport, void, (x, y, width, height))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Frustum, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(left, GLdouble),
|
||||
GL_PROTO_ARG(right, GLdouble),
|
||||
GL_PROTO_ARG(bottom, GLdouble),
|
||||
GL_PROTO_ARG(top, GLdouble),
|
||||
GL_PROTO_ARG(zNear, GLdouble),
|
||||
GL_PROTO_ARG(zFar, GLdouble))
|
||||
GL_PROTO_INVOKE(Frustum, void, (left, right, bottom, top, zNear, zFar))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Scalef, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(x, GLfloat),
|
||||
GL_PROTO_ARG(y, GLfloat),
|
||||
GL_PROTO_ARG(z, GLfloat))
|
||||
GL_PROTO_INVOKE(Scalef, void, (x, y, z))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Translatef, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(x, GLfloat),
|
||||
GL_PROTO_ARG(y, GLfloat),
|
||||
GL_PROTO_ARG(z, GLfloat))
|
||||
GL_PROTO_INVOKE(Translatef, void, (x, y, z))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(EnableClientState, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(array, GLenum))
|
||||
GL_PROTO_INVOKE(EnableClientState, void, (array))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(DisableClientState, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(array, GLenum))
|
||||
GL_PROTO_INVOKE(DisableClientState, void, (array))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(TexCoordPointer, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(size, GLint),
|
||||
GL_PROTO_ARG(type, GLenum),
|
||||
GL_PROTO_ARG(stride, GLsizei),
|
||||
GL_PROTO_ARG(pointer, const GLvoid *))
|
||||
GL_PROTO_INVOKE(TexCoordPointer, void, (size, type, stride, pointer))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(VertexPointer, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(size, GLint),
|
||||
GL_PROTO_ARG(type, GLenum),
|
||||
GL_PROTO_ARG(stride, GLsizei),
|
||||
GL_PROTO_ARG(pointer, const GLvoid *))
|
||||
GL_PROTO_INVOKE(VertexPointer, void, (size, type, stride, pointer))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(EnableVertexAttribArray, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(index, GLuint))
|
||||
GL_PROTO_INVOKE(EnableVertexAttribArray, void, (index))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(DisableVertexAttribArray, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(index, GLuint))
|
||||
GL_PROTO_INVOKE(DisableVertexAttribArray, void, (index))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(GetVertexAttribPointerv, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(index, GLuint),
|
||||
GL_PROTO_ARG(pname, GLenum),
|
||||
GL_PROTO_ARG(pointer, GLvoid **))
|
||||
GL_PROTO_INVOKE(GetVertexAttribPointerv, void, (index, pname, pointer))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(VertexAttribPointer, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(index, GLuint),
|
||||
GL_PROTO_ARG(size, GLint),
|
||||
GL_PROTO_ARG(type, GLenum),
|
||||
GL_PROTO_ARG(normalized, GLboolean),
|
||||
GL_PROTO_ARG(stride, GLsizei),
|
||||
GL_PROTO_ARG(pointer, const GLvoid *))
|
||||
GL_PROTO_INVOKE(VertexAttribPointer, void, (index, size, type, normalized, stride, pointer))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(DrawArrays, void, CORE_1_1)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(mode, GLenum),
|
||||
GL_PROTO_ARG(first, GLint),
|
||||
GL_PROTO_ARG(count, GLsizei))
|
||||
GL_PROTO_INVOKE(DrawArrays, void, (mode, first, count))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(GenTextures, void, CORE_1_1)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(n, GLsizei),
|
||||
GL_PROTO_ARG(textures, GLuint *))
|
||||
GL_PROTO_INVOKE(GenTextures, void, (n, textures))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(DeleteTextures, void, CORE_1_1)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(n, GLsizei),
|
||||
GL_PROTO_ARG(textures, const GLuint *))
|
||||
GL_PROTO_INVOKE(DeleteTextures, void, (n, textures))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(BindTexture, void, CORE_1_1)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(target, GLenum),
|
||||
GL_PROTO_ARG(texture, GLuint))
|
||||
GL_PROTO_INVOKE(BindTexture, void, (target, texture))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(ActiveTexture, void, CORE_1_3)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(texture, GLenum))
|
||||
GL_PROTO_INVOKE(ActiveTexture, void, (texture))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(GetTexLevelParameteriv, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(target, GLenum),
|
||||
GL_PROTO_ARG(level, GLint),
|
||||
GL_PROTO_ARG(pname, GLenum),
|
||||
GL_PROTO_ARG(params, GLint *))
|
||||
GL_PROTO_INVOKE(GetTexLevelParameteriv, void, (target, level, pname, params))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(TexParameterf, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(target, GLenum),
|
||||
GL_PROTO_ARG(pname, GLenum),
|
||||
GL_PROTO_ARG(param, GLfloat))
|
||||
GL_PROTO_INVOKE(TexParameterf, void, (target, pname, param))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(TexParameterfv, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(target, GLenum),
|
||||
GL_PROTO_ARG(pname, GLenum),
|
||||
GL_PROTO_ARG(params, const GLfloat *))
|
||||
GL_PROTO_INVOKE(TexParameterfv, void, (target, pname, params))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(TexParameteri, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(target, GLenum),
|
||||
GL_PROTO_ARG(pname, GLenum),
|
||||
GL_PROTO_ARG(param, GLint))
|
||||
GL_PROTO_INVOKE(TexParameteri, void, (target, pname, param))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(TexParameteriv, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(target, GLenum),
|
||||
GL_PROTO_ARG(pname, GLenum),
|
||||
GL_PROTO_ARG(params, const GLint *))
|
||||
GL_PROTO_INVOKE(TexParameteriv, void, (target, pname, params))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(TexImage2D, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(target, GLenum),
|
||||
GL_PROTO_ARG(level, GLint),
|
||||
GL_PROTO_ARG(internalformat, GLint),
|
||||
GL_PROTO_ARG(width, GLsizei),
|
||||
GL_PROTO_ARG(height, GLsizei),
|
||||
GL_PROTO_ARG(border, GLint),
|
||||
GL_PROTO_ARG(format, GLenum),
|
||||
GL_PROTO_ARG(type, GLenum),
|
||||
GL_PROTO_ARG(pixels, const GLvoid *))
|
||||
GL_PROTO_INVOKE(TexImage2D, void, (target, level, internalformat, width, height, border, format, type, pixels))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(TexSubImage2D, void, CORE_1_1)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(target, GLenum),
|
||||
GL_PROTO_ARG(level, GLint),
|
||||
GL_PROTO_ARG(xoffset, GLint),
|
||||
GL_PROTO_ARG(yoffset, GLint),
|
||||
GL_PROTO_ARG(width, GLsizei),
|
||||
GL_PROTO_ARG(height, GLsizei),
|
||||
GL_PROTO_ARG(format, GLenum),
|
||||
GL_PROTO_ARG(type, GLenum),
|
||||
GL_PROTO_ARG(UNUSED, GLuint),
|
||||
GL_PROTO_ARG(pixels, const GLvoid *))
|
||||
GL_PROTO_INVOKE(TexSubImage2D, void, (target, level, xoffset, yoffset, width, height, format, type, UNUSED, pixels))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(PixelStoref, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(pname, GLenum),
|
||||
GL_PROTO_ARG(param, GLfloat))
|
||||
GL_PROTO_INVOKE(PixelStoref, void, (pname, param))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(PixelStorei, void, CORE_1_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(pname, GLenum),
|
||||
GL_PROTO_ARG(param, GLint))
|
||||
GL_PROTO_INVOKE(PixelStorei, void, (pname, param))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(CreateShader, GLuint, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(type, GLenum))
|
||||
GL_PROTO_INVOKE(CreateShader, GLuint, (type))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(DeleteShader, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(program, GLuint))
|
||||
GL_PROTO_INVOKE(DeleteShader, void, (program))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(ShaderSource, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(shader, GLuint),
|
||||
GL_PROTO_ARG(count, GLsizei),
|
||||
GL_PROTO_ARG(string, const GLchar * const *),
|
||||
GL_PROTO_ARG(length, const GLint *))
|
||||
GL_PROTO_INVOKE(ShaderSource, void, (shader, count, string, length))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(CompileShader, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(shader, GLuint))
|
||||
GL_PROTO_INVOKE(CompileShader, void, (shader))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(GetShaderiv, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(shader, GLuint),
|
||||
GL_PROTO_ARG(pname, GLenum),
|
||||
GL_PROTO_ARG(params, GLint *))
|
||||
GL_PROTO_INVOKE(GetShaderiv, void, (shader, pname, params))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(GetShaderInfoLog, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(shader, GLuint),
|
||||
GL_PROTO_ARG(bufSize, GLsizei),
|
||||
GL_PROTO_ARG(length, GLsizei *),
|
||||
GL_PROTO_ARG(infoLog, GLchar *))
|
||||
GL_PROTO_INVOKE(GetShaderInfoLog, void, (shader, bufSize, length, infoLog))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(CreateProgram, GLuint, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST()
|
||||
GL_PROTO_INVOKE(CreateProgram, GLuint, ())
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(DeleteProgram, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(program, GLuint))
|
||||
GL_PROTO_INVOKE(DeleteProgram, void, (program))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(AttachShader, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(program, GLuint),
|
||||
GL_PROTO_ARG(shader, GLuint))
|
||||
GL_PROTO_INVOKE(AttachShader, void, (program, shader))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(LinkProgram, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(program, GLuint))
|
||||
GL_PROTO_INVOKE(LinkProgram, void, (program))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(UseProgram, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(program, GLuint))
|
||||
GL_PROTO_INVOKE(UseProgram, void, (program))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(GetProgramiv, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(program, GLuint),
|
||||
GL_PROTO_ARG(pname, GLenum),
|
||||
GL_PROTO_ARG(params, GLint *))
|
||||
GL_PROTO_INVOKE(GetProgramiv, void, (program, pname, params))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(GetProgramInfoLog, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(program, GLuint),
|
||||
GL_PROTO_ARG(bufSize, GLsizei),
|
||||
GL_PROTO_ARG(length, GLsizei *),
|
||||
GL_PROTO_ARG(infoLog, GLchar *))
|
||||
GL_PROTO_INVOKE(GetProgramInfoLog, void, (program, bufSize, length, infoLog))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(BindAttribLocation, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(program, GLuint),
|
||||
GL_PROTO_ARG(index, GLuint),
|
||||
GL_PROTO_ARG(name, const GLchar *))
|
||||
GL_PROTO_INVOKE(BindAttribLocation, void, (program, index, name))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(GetUniformLocation, GLint, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(program, GLuint),
|
||||
GL_PROTO_ARG(name, const GLchar *))
|
||||
GL_PROTO_INVOKE(GetUniformLocation, GLint, (program, name))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Uniform1f, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(v0, GLfloat))
|
||||
GL_PROTO_INVOKE(Uniform1f, void, (location, v0))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Uniform1fv, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(count, GLsizei),
|
||||
GL_PROTO_ARG(value, const GLfloat *))
|
||||
GL_PROTO_INVOKE(Uniform1fv, void, (location, count, value))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Uniform1i, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(v0, GLint))
|
||||
GL_PROTO_INVOKE(Uniform1i, void, (location, v0))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Uniform1iv, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(count, GLsizei),
|
||||
GL_PROTO_ARG(value, const GLint *))
|
||||
GL_PROTO_INVOKE(Uniform1iv, void, (location, count, value))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Uniform2f, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(v0, GLfloat),
|
||||
GL_PROTO_ARG(v1, GLfloat))
|
||||
GL_PROTO_INVOKE(Uniform2f, void, (location, v0, v1))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Uniform2fv, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(count, GLsizei),
|
||||
GL_PROTO_ARG(value, const GLfloat *))
|
||||
GL_PROTO_INVOKE(Uniform2fv, void, (location, count, value))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Uniform2i, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(v0, GLint),
|
||||
GL_PROTO_ARG(v1, GLint))
|
||||
GL_PROTO_INVOKE(Uniform2i, void, (location, v0, v1))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Uniform2iv, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(count, GLsizei),
|
||||
GL_PROTO_ARG(value, const GLint *))
|
||||
GL_PROTO_INVOKE(Uniform2iv, void, (location, count, value))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Uniform3f, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(v0, GLfloat),
|
||||
GL_PROTO_ARG(v1, GLfloat),
|
||||
GL_PROTO_ARG(v2, GLfloat))
|
||||
GL_PROTO_INVOKE(Uniform3f, void, (location, v0, v1, v2))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Uniform3fv, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(count, GLsizei),
|
||||
GL_PROTO_ARG(value, const GLfloat *))
|
||||
GL_PROTO_INVOKE(Uniform3fv, void, (location, count, value))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Uniform3i, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(v0, GLint),
|
||||
GL_PROTO_ARG(v1, GLint),
|
||||
GL_PROTO_ARG(v2, GLint))
|
||||
GL_PROTO_INVOKE(Uniform3i, void, (location, v0, v1, v2))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Uniform3iv, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(count, GLsizei),
|
||||
GL_PROTO_ARG(value, const GLint *))
|
||||
GL_PROTO_INVOKE(Uniform3iv, void, (location, count, value))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Uniform4f, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(v0, GLfloat),
|
||||
GL_PROTO_ARG(v1, GLfloat),
|
||||
GL_PROTO_ARG(v2, GLfloat),
|
||||
GL_PROTO_ARG(v3, GLfloat))
|
||||
GL_PROTO_INVOKE(Uniform4f, void, (location, v0, v1, v2, v3))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Uniform4fv, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(count, GLsizei),
|
||||
GL_PROTO_ARG(value, const GLfloat *))
|
||||
GL_PROTO_INVOKE(Uniform4fv, void, (location, count, value))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Uniform4i, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(v0, GLint),
|
||||
GL_PROTO_ARG(v1, GLint),
|
||||
GL_PROTO_ARG(v2, GLint),
|
||||
GL_PROTO_ARG(v3, GLint))
|
||||
GL_PROTO_INVOKE(Uniform4i, void, (location, v0, v1, v2, v3))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(Uniform4iv, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(count, GLsizei),
|
||||
GL_PROTO_ARG(value, const GLint *))
|
||||
GL_PROTO_INVOKE(Uniform4iv, void, (location, count, value))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(UniformMatrix2fv, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(count, GLsizei),
|
||||
GL_PROTO_ARG(transpose, GLboolean),
|
||||
GL_PROTO_ARG(value, const GLfloat *))
|
||||
GL_PROTO_INVOKE(UniformMatrix2fv, void, (location, count, transpose, value))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(UniformMatrix3fv, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(count, GLsizei),
|
||||
GL_PROTO_ARG(transpose, GLboolean),
|
||||
GL_PROTO_ARG(value, const GLfloat *))
|
||||
GL_PROTO_INVOKE(UniformMatrix3fv, void, (location, count, transpose, value))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(UniformMatrix4fv, void, CORE_2_0)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(location, GLint),
|
||||
GL_PROTO_ARG(count, GLsizei),
|
||||
GL_PROTO_ARG(transpose, GLboolean),
|
||||
GL_PROTO_ARG(value, const GLfloat *))
|
||||
GL_PROTO_INVOKE(UniformMatrix4fv, void, (location, count, transpose, value))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(EGLImageTargetTexture2DOES, void, OES_EGL_image)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(target, GLenum),
|
||||
GL_PROTO_ARG(image, void *))
|
||||
GL_PROTO_INVOKE(EGLImageTargetTexture2DOES, void, (target, image))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_PROTO_BEGIN(EGLImageTargetRenderbufferStorageOES, void, OES_EGL_image)
|
||||
GL_PROTO_ARG_LIST(
|
||||
GL_PROTO_ARG(target, GLenum),
|
||||
GL_PROTO_ARG(image, void *))
|
||||
GL_PROTO_INVOKE(EGLImageTargetRenderbufferStorageOES, void, (target, image))
|
||||
GL_PROTO_END()
|
||||
|
||||
GL_DEFINE_EXTENSION(CORE_1_0)
|
||||
GL_DEFINE_EXTENSION(CORE_1_1)
|
||||
GL_DEFINE_EXTENSION(CORE_1_3)
|
||||
GL_DEFINE_EXTENSION(CORE_2_0)
|
||||
GL_DEFINE_EXTENSION(OES_EGL_image)
|
||||
|
||||
#undef EGL_PROTO_BEGIN
|
||||
#undef EGL_PROTO_BEGIN_I
|
||||
#undef EGL_PROTO_ARG_LIST
|
||||
#undef EGL_PROTO_ARG
|
||||
#undef EGL_PROTO_INVOKE
|
||||
#undef EGL_PROTO_INVOKE_I
|
||||
#undef EGL_PROTO_END
|
||||
#undef EGL_DEFINE_EXTENSION
|
||||
#undef EGL_DEFINE_EXTENSION_I
|
||||
|
||||
#undef GL_PROTO_BEGIN
|
||||
#undef GL_PROTO_BEGIN_I
|
||||
#undef GL_PROTO_ARG_LIST
|
||||
#undef GL_PROTO_ARG
|
||||
#undef GL_PROTO_INVOKE
|
||||
#undef GL_PROTO_INVOKE_I
|
||||
#undef GL_PROTO_END
|
||||
#undef GL_DEFINE_EXTENSION
|
||||
#undef GL_DEFINE_EXTENSION_I
|
||||
|
||||
#undef GL_PROTO_GEN_CONCAT5
|
||||
#undef GL_PROTO_GEN_CONCAT5_I
|
||||
#undef GL_PROTO_GEN_CONCAT4
|
||||
#undef GL_PROTO_GEN_CONCAT4_I
|
||||
#undef GL_PROTO_GEN_CONCAT3
|
||||
#undef GL_PROTO_GEN_CONCAT3_I
|
||||
#undef GL_PROTO_GEN_CONCAT2
|
||||
#undef GL_PROTO_GEN_CONCAT2_I
|
||||
#undef GL_PROTO_GEN_CONCAT
|
||||
#undef GL_PROTO_GEN_STRING
|
||||
#undef GL_PROTO_GEN_STRING_I
|
326
gst-libs/gst/vaapi/gstvaapiblend.c
Normal file
326
gst-libs/gst/vaapi/gstvaapiblend.c
Normal file
|
@ -0,0 +1,326 @@
|
|||
/*
|
||||
* gstvaapiblend.c - Video processing blend
|
||||
*
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Author: U. Artie Eoff <ullysses.a.eoff@intel.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; 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "gstvaapicompat.h"
|
||||
#include "gstvaapiblend.h"
|
||||
#include "gstvaapiutils.h"
|
||||
#include "gstvaapivalue.h"
|
||||
#include "gstvaapidisplay_priv.h"
|
||||
#include "gstvaapisurface_priv.h"
|
||||
|
||||
struct _GstVaapiBlend
|
||||
{
|
||||
GstObject parent_instance;
|
||||
|
||||
GstVaapiDisplay *display;
|
||||
|
||||
VAConfigID va_config;
|
||||
VAContextID va_context;
|
||||
|
||||
guint32 flags;
|
||||
};
|
||||
|
||||
typedef struct _GstVaapiBlendClass GstVaapiBlendClass;
|
||||
struct _GstVaapiBlendClass
|
||||
{
|
||||
GstObjectClass parent_class;
|
||||
};
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapi_blend);
|
||||
#ifndef GST_DISABLE_GST_DEBUG
|
||||
#define GST_CAT_DEFAULT gst_debug_vaapi_blend
|
||||
#else
|
||||
#define GST_CAT_DEFAULT NULL
|
||||
#endif
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GstVaapiBlend, gst_vaapi_blend, GST_TYPE_OBJECT,
|
||||
GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi_blend, "vaapiblend", 0,
|
||||
"VA-API Blend"));
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_DISPLAY = 1,
|
||||
};
|
||||
|
||||
static void
|
||||
gst_vaapi_blend_set_property (GObject * object, guint property_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstVaapiBlend *const blend = GST_VAAPI_BLEND (object);
|
||||
|
||||
switch (property_id) {
|
||||
case PROP_DISPLAY:{
|
||||
GstVaapiDisplay *display = g_value_get_object (value);;
|
||||
if (display) {
|
||||
if (GST_VAAPI_DISPLAY_HAS_VPP (display)) {
|
||||
blend->display = gst_object_ref (display);
|
||||
} else {
|
||||
GST_WARNING_OBJECT (blend, "GstVaapiDisplay doesn't support VPP");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_blend_get_property (GObject * object, guint property_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstVaapiBlend *const blend = GST_VAAPI_BLEND (object);
|
||||
|
||||
switch (property_id) {
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_object (value, blend->display);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_blend_finalize (GObject * object)
|
||||
{
|
||||
GstVaapiBlend *const blend = GST_VAAPI_BLEND (object);
|
||||
|
||||
if (!blend->display)
|
||||
goto bail;
|
||||
|
||||
GST_VAAPI_DISPLAY_LOCK (blend->display);
|
||||
|
||||
if (blend->va_context != VA_INVALID_ID) {
|
||||
vaDestroyContext (GST_VAAPI_DISPLAY_VADISPLAY (blend->display),
|
||||
blend->va_context);
|
||||
blend->va_context = VA_INVALID_ID;
|
||||
}
|
||||
|
||||
if (blend->va_config != VA_INVALID_ID) {
|
||||
vaDestroyConfig (GST_VAAPI_DISPLAY_VADISPLAY (blend->display),
|
||||
blend->va_config);
|
||||
blend->va_config = VA_INVALID_ID;
|
||||
}
|
||||
|
||||
GST_VAAPI_DISPLAY_UNLOCK (blend->display);
|
||||
|
||||
gst_vaapi_display_replace (&blend->display, NULL);
|
||||
|
||||
bail:
|
||||
G_OBJECT_CLASS (gst_vaapi_blend_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_blend_class_init (GstVaapiBlendClass * klass)
|
||||
{
|
||||
GObjectClass *const object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->set_property = gst_vaapi_blend_set_property;
|
||||
object_class->get_property = gst_vaapi_blend_get_property;
|
||||
object_class->finalize = gst_vaapi_blend_finalize;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_DISPLAY,
|
||||
g_param_spec_object ("display", "Gst VA-API Display",
|
||||
"The VA-API display object to use", GST_TYPE_VAAPI_DISPLAY,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_blend_init (GstVaapiBlend * blend)
|
||||
{
|
||||
blend->display = NULL;
|
||||
blend->va_config = VA_INVALID_ID;
|
||||
blend->va_context = VA_INVALID_ID;
|
||||
blend->flags = 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_blend_initialize (GstVaapiBlend * blend)
|
||||
{
|
||||
VAStatus status;
|
||||
VAProcPipelineCaps pipeline_caps = { 0, };
|
||||
|
||||
if (!blend->display)
|
||||
return FALSE;
|
||||
|
||||
status = vaCreateConfig (GST_VAAPI_DISPLAY_VADISPLAY (blend->display),
|
||||
VAProfileNone, VAEntrypointVideoProc, NULL, 0, &blend->va_config);
|
||||
if (!vaapi_check_status (status, "vaCreateConfig() [VPP]"))
|
||||
return FALSE;
|
||||
|
||||
status = vaCreateContext (GST_VAAPI_DISPLAY_VADISPLAY (blend->display),
|
||||
blend->va_config, 0, 0, 0, NULL, 0, &blend->va_context);
|
||||
if (!vaapi_check_status (status, "vaCreateContext() [VPP]"))
|
||||
return FALSE;
|
||||
|
||||
#if VA_CHECK_VERSION(1,1,0)
|
||||
status =
|
||||
vaQueryVideoProcPipelineCaps (GST_VAAPI_DISPLAY_VADISPLAY
|
||||
(blend->display), blend->va_context, NULL, 0, &pipeline_caps);
|
||||
if (vaapi_check_status (status, "vaQueryVideoProcPipelineCaps()"))
|
||||
blend->flags = pipeline_caps.blend_flags;
|
||||
|
||||
if (!(blend->flags & VA_BLEND_GLOBAL_ALPHA)) {
|
||||
GST_WARNING_OBJECT (blend, "VPP does not support global alpha blending");
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstVaapiBlend *
|
||||
gst_vaapi_blend_new (GstVaapiDisplay * display)
|
||||
{
|
||||
GstVaapiBlend *blend = g_object_new (GST_TYPE_VAAPI_BLEND,
|
||||
"display", display, NULL);
|
||||
|
||||
if (!gst_vaapi_blend_initialize (blend)) {
|
||||
gst_object_unref (blend);
|
||||
blend = NULL;
|
||||
}
|
||||
|
||||
return blend;
|
||||
}
|
||||
|
||||
void
|
||||
gst_vaapi_blend_replace (GstVaapiBlend ** old_blend_ptr,
|
||||
GstVaapiBlend * new_blend)
|
||||
{
|
||||
g_return_if_fail (old_blend_ptr != NULL);
|
||||
|
||||
gst_object_replace ((GstObject **) old_blend_ptr, GST_OBJECT (new_blend));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_blend_process_unlocked (GstVaapiBlend * blend,
|
||||
GstVaapiSurface * output, GstVaapiBlendSurfaceNextFunc next,
|
||||
gpointer user_data)
|
||||
{
|
||||
VAStatus va_status;
|
||||
VADisplay va_display;
|
||||
GstVaapiBlendSurface *current;
|
||||
|
||||
va_display = GST_VAAPI_DISPLAY_VADISPLAY (blend->display);
|
||||
|
||||
va_status = vaBeginPicture (va_display, blend->va_context,
|
||||
GST_VAAPI_SURFACE_ID (output));
|
||||
if (!vaapi_check_status (va_status, "vaBeginPicture()"))
|
||||
return FALSE;
|
||||
|
||||
current = next (user_data);
|
||||
for (; current; current = next (user_data)) {
|
||||
VAProcPipelineParameterBuffer *param = NULL;
|
||||
VABufferID id = VA_INVALID_ID;
|
||||
VARectangle src_rect = { 0, };
|
||||
VARectangle dst_rect = { 0, };
|
||||
#if VA_CHECK_VERSION(1,1,0)
|
||||
VABlendState blend_state;
|
||||
#endif
|
||||
|
||||
if (!current->surface)
|
||||
return FALSE;
|
||||
|
||||
/* Build surface region (source) */
|
||||
src_rect.width = GST_VAAPI_SURFACE_WIDTH (current->surface);
|
||||
src_rect.height = GST_VAAPI_SURFACE_HEIGHT (current->surface);
|
||||
if (current->crop) {
|
||||
if ((current->crop->x + current->crop->width > src_rect.width) ||
|
||||
(current->crop->y + current->crop->height > src_rect.height))
|
||||
return FALSE;
|
||||
src_rect.x = current->crop->x;
|
||||
src_rect.y = current->crop->y;
|
||||
src_rect.width = current->crop->width;
|
||||
src_rect.height = current->crop->height;
|
||||
}
|
||||
|
||||
/* Build output region (target) */
|
||||
dst_rect.x = current->target.x;
|
||||
dst_rect.y = current->target.y;
|
||||
dst_rect.width = current->target.width;
|
||||
dst_rect.height = current->target.height;
|
||||
|
||||
if (!vaapi_create_buffer (va_display, blend->va_context,
|
||||
VAProcPipelineParameterBufferType, sizeof (*param), NULL, &id,
|
||||
(gpointer *) & param))
|
||||
return FALSE;
|
||||
|
||||
memset (param, 0, sizeof (*param));
|
||||
|
||||
param->surface = GST_VAAPI_SURFACE_ID (current->surface);
|
||||
param->surface_region = &src_rect;
|
||||
param->output_region = &dst_rect;
|
||||
param->output_background_color = 0xff000000;
|
||||
|
||||
#if VA_CHECK_VERSION(1,1,0)
|
||||
blend_state.flags = VA_BLEND_GLOBAL_ALPHA;
|
||||
blend_state.global_alpha = current->alpha;
|
||||
param->blend_state = &blend_state;
|
||||
#endif
|
||||
|
||||
vaapi_unmap_buffer (va_display, id, NULL);
|
||||
|
||||
va_status = vaRenderPicture (va_display, blend->va_context, &id, 1);
|
||||
vaapi_destroy_buffer (va_display, &id);
|
||||
if (!vaapi_check_status (va_status, "vaRenderPicture()"))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
va_status = vaEndPicture (va_display, blend->va_context);
|
||||
if (!vaapi_check_status (va_status, "vaEndPicture()"))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_blend_process:
|
||||
* @blend: a #GstVaapiBlend instance.
|
||||
* @output: a #GstVaapiSurface to be composed.
|
||||
* @next: a function to fetch the next #GstVaapiBlendSurface to
|
||||
* process.
|
||||
* @data: state storage for @next.
|
||||
*
|
||||
* This function will process all the input surfaces defined through
|
||||
* #GstVaapiBlendSurface and will blend them onto the @output surface.
|
||||
*
|
||||
* Returns: %TRUE if the blend process succeed; otherwise %FALSE.
|
||||
**/
|
||||
gboolean
|
||||
gst_vaapi_blend_process (GstVaapiBlend * blend, GstVaapiSurface * output,
|
||||
GstVaapiBlendSurfaceNextFunc next, gpointer user_data)
|
||||
{
|
||||
gboolean result;
|
||||
|
||||
g_return_val_if_fail (blend != NULL, FALSE);
|
||||
g_return_val_if_fail (output != NULL, FALSE);
|
||||
g_return_val_if_fail (next != NULL, FALSE);
|
||||
|
||||
GST_VAAPI_DISPLAY_LOCK (blend->display);
|
||||
result = gst_vaapi_blend_process_unlocked (blend, output, next, user_data);
|
||||
GST_VAAPI_DISPLAY_UNLOCK (blend->display);
|
||||
|
||||
return result;
|
||||
}
|
68
gst-libs/gst/vaapi/gstvaapiblend.h
Normal file
68
gst-libs/gst/vaapi/gstvaapiblend.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* gstvaapiblend.h - Video processing blend
|
||||
*
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Author: U. Artie Eoff <ullysses.a.eoff@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_BLEND_H
|
||||
#define GST_VAAPI_BLEND_H
|
||||
|
||||
#include <gst/vaapi/gstvaapisurface.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_BLEND \
|
||||
(gst_vaapi_blend_get_type ())
|
||||
#define GST_VAAPI_BLEND(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_BLEND, GstVaapiBlend))
|
||||
#define GST_IS_VAAPI_BLEND(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_BLEND))
|
||||
|
||||
typedef struct _GstVaapiBlend GstVaapiBlend;
|
||||
typedef struct _GstVaapiBlendSurface GstVaapiBlendSurface;
|
||||
|
||||
struct _GstVaapiBlendSurface
|
||||
{
|
||||
GstVaapiSurface const *surface;
|
||||
const GstVaapiRectangle *crop;
|
||||
GstVaapiRectangle target;
|
||||
gdouble alpha;
|
||||
};
|
||||
|
||||
typedef GstVaapiBlendSurface* (*GstVaapiBlendSurfaceNextFunc)(gpointer data);
|
||||
|
||||
GstVaapiBlend *
|
||||
gst_vaapi_blend_new (GstVaapiDisplay * display);
|
||||
|
||||
void
|
||||
gst_vaapi_blend_replace (GstVaapiBlend ** old_blend_ptr,
|
||||
GstVaapiBlend * new_blend);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_blend_process (GstVaapiBlend * blend, GstVaapiSurface * output,
|
||||
GstVaapiBlendSurfaceNextFunc next, gpointer user_data);
|
||||
|
||||
GType
|
||||
gst_vaapi_blend_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiBlend, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_FILTER_H */
|
297
gst-libs/gst/vaapi/gstvaapibufferproxy.c
Normal file
297
gst-libs/gst/vaapi/gstvaapibufferproxy.c
Normal file
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
* gstvaapibufferproxy.c - Buffer proxy abstraction
|
||||
*
|
||||
* Copyright (C) 2014 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "gstvaapicompat.h"
|
||||
#include "gstvaapibufferproxy.h"
|
||||
#include "gstvaapibufferproxy_priv.h"
|
||||
#include "gstvaapisurface_priv.h"
|
||||
#include "gstvaapiutils.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_buffer_proxy_acquire_handle (GstVaapiBufferProxy * proxy)
|
||||
{
|
||||
GstVaapiDisplay *display;
|
||||
const guint mem_type = proxy->va_info.mem_type;
|
||||
VAStatus va_status;
|
||||
|
||||
if (proxy->va_info.handle)
|
||||
return TRUE;
|
||||
|
||||
if (!proxy->surface || proxy->va_buf == VA_INVALID_ID)
|
||||
return FALSE;
|
||||
|
||||
display = GST_VAAPI_SURFACE_DISPLAY (GST_VAAPI_SURFACE (proxy->surface));
|
||||
|
||||
GST_VAAPI_DISPLAY_LOCK (display);
|
||||
va_status = vaAcquireBufferHandle (GST_VAAPI_DISPLAY_VADISPLAY (display),
|
||||
proxy->va_buf, &proxy->va_info);
|
||||
GST_VAAPI_DISPLAY_UNLOCK (display);
|
||||
if (!vaapi_check_status (va_status, "vaAcquireBufferHandle()"))
|
||||
return FALSE;
|
||||
if (proxy->va_info.mem_type != mem_type)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_buffer_proxy_release_handle (GstVaapiBufferProxy * proxy)
|
||||
{
|
||||
GstVaapiDisplay *display;
|
||||
VAStatus va_status;
|
||||
|
||||
if (!proxy->va_info.handle)
|
||||
return TRUE;
|
||||
|
||||
if (!proxy->surface || proxy->va_buf == VA_INVALID_ID)
|
||||
return FALSE;
|
||||
|
||||
display = GST_VAAPI_SURFACE_DISPLAY (GST_VAAPI_SURFACE (proxy->surface));
|
||||
|
||||
GST_VAAPI_DISPLAY_LOCK (display);
|
||||
va_status = vaReleaseBufferHandle (GST_VAAPI_DISPLAY_VADISPLAY (display),
|
||||
proxy->va_buf);
|
||||
GST_VAAPI_DISPLAY_UNLOCK (display);
|
||||
if (!vaapi_check_status (va_status, "vaReleaseBufferHandle()"))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_buffer_proxy_finalize (GstVaapiBufferProxy * proxy)
|
||||
{
|
||||
gst_vaapi_buffer_proxy_release_handle (proxy);
|
||||
|
||||
/* Notify the user function that the object is now destroyed */
|
||||
if (proxy->destroy_func)
|
||||
proxy->destroy_func (proxy->destroy_data);
|
||||
|
||||
proxy->surface = NULL;
|
||||
}
|
||||
|
||||
static inline const GstVaapiMiniObjectClass *
|
||||
gst_vaapi_buffer_proxy_class (void)
|
||||
{
|
||||
static const GstVaapiMiniObjectClass GstVaapiBufferProxyClass = {
|
||||
sizeof (GstVaapiBufferProxy),
|
||||
(GDestroyNotify) gst_vaapi_buffer_proxy_finalize
|
||||
};
|
||||
return &GstVaapiBufferProxyClass;
|
||||
}
|
||||
|
||||
GstVaapiBufferProxy *
|
||||
gst_vaapi_buffer_proxy_new (guintptr handle, guint type, gsize size,
|
||||
GDestroyNotify destroy_func, gpointer user_data)
|
||||
{
|
||||
GstVaapiBufferProxy *proxy;
|
||||
|
||||
g_return_val_if_fail (handle != 0, NULL);
|
||||
g_return_val_if_fail (size > 0, NULL);
|
||||
|
||||
proxy = (GstVaapiBufferProxy *)
|
||||
gst_vaapi_mini_object_new (gst_vaapi_buffer_proxy_class ());
|
||||
if (!proxy)
|
||||
return NULL;
|
||||
|
||||
proxy->surface = NULL;
|
||||
proxy->destroy_func = destroy_func;
|
||||
proxy->destroy_data = user_data;
|
||||
proxy->type = type;
|
||||
proxy->va_buf = VA_INVALID_ID;
|
||||
proxy->va_info.handle = handle;
|
||||
proxy->va_info.type = VAImageBufferType;
|
||||
proxy->va_info.mem_type = from_GstVaapiBufferMemoryType (proxy->type);
|
||||
proxy->va_info.mem_size = size;
|
||||
if (!proxy->va_info.mem_type)
|
||||
goto error_unsupported_mem_type;
|
||||
return proxy;
|
||||
|
||||
/* ERRORS */
|
||||
error_unsupported_mem_type:
|
||||
{
|
||||
GST_ERROR ("unsupported buffer type (%d)", proxy->type);
|
||||
gst_vaapi_buffer_proxy_unref (proxy);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
GstVaapiBufferProxy *
|
||||
gst_vaapi_buffer_proxy_new_from_surface (GstMiniObject * surface,
|
||||
VABufferID buf_id, guint type, GDestroyNotify destroy_func, gpointer data)
|
||||
{
|
||||
GstVaapiBufferProxy *proxy;
|
||||
|
||||
g_return_val_if_fail (surface != NULL, NULL);
|
||||
|
||||
proxy = (GstVaapiBufferProxy *)
|
||||
gst_vaapi_mini_object_new (gst_vaapi_buffer_proxy_class ());
|
||||
if (!proxy)
|
||||
return NULL;
|
||||
|
||||
proxy->surface = surface;
|
||||
proxy->destroy_func = destroy_func;
|
||||
proxy->destroy_data = data;
|
||||
proxy->type = type;
|
||||
proxy->va_buf = buf_id;
|
||||
memset (&proxy->va_info, 0, sizeof (proxy->va_info));
|
||||
proxy->va_info.mem_type = from_GstVaapiBufferMemoryType (proxy->type);
|
||||
if (!proxy->va_info.mem_type)
|
||||
goto error_unsupported_mem_type;
|
||||
if (!gst_vaapi_buffer_proxy_acquire_handle (proxy))
|
||||
goto error_acquire_handle;
|
||||
return proxy;
|
||||
|
||||
/* ERRORS */
|
||||
error_unsupported_mem_type:
|
||||
{
|
||||
GST_ERROR ("unsupported buffer type (%d)", proxy->type);
|
||||
gst_vaapi_buffer_proxy_unref (proxy);
|
||||
return NULL;
|
||||
}
|
||||
error_acquire_handle:
|
||||
{
|
||||
GST_ERROR ("failed to acquire the underlying VA buffer handle");
|
||||
gst_vaapi_buffer_proxy_unref (proxy);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_buffer_proxy_ref:
|
||||
* @proxy: a #GstVaapiBufferProxy
|
||||
*
|
||||
* Atomically increases the reference count of the given @proxy by one.
|
||||
*
|
||||
* Returns: The same @proxy argument
|
||||
*/
|
||||
GstVaapiBufferProxy *
|
||||
gst_vaapi_buffer_proxy_ref (GstVaapiBufferProxy * proxy)
|
||||
{
|
||||
g_return_val_if_fail (proxy != NULL, NULL);
|
||||
|
||||
return (GstVaapiBufferProxy *)
|
||||
gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (proxy));
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_buffer_proxy_unref:
|
||||
* @proxy: a #GstVaapiBufferProxy
|
||||
*
|
||||
* Atomically decreases the reference count of the @proxy by one. If
|
||||
* the reference count reaches zero, the object will be free'd.
|
||||
*/
|
||||
void
|
||||
gst_vaapi_buffer_proxy_unref (GstVaapiBufferProxy * proxy)
|
||||
{
|
||||
g_return_if_fail (proxy != NULL);
|
||||
|
||||
gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (proxy));
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_buffer_proxy_replace:
|
||||
* @old_proxy_ptr: a pointer to a #GstVaapiBufferProxy
|
||||
* @new_proxy: a #GstVaapiBufferProxy
|
||||
*
|
||||
* Atomically replaces the proxy object held in @old_proxy_ptr with
|
||||
* @new_proxy. This means that @old_proxy_ptr shall reference a valid
|
||||
* object. However, @new_proxy can be NULL.
|
||||
*/
|
||||
void
|
||||
gst_vaapi_buffer_proxy_replace (GstVaapiBufferProxy ** old_proxy_ptr,
|
||||
GstVaapiBufferProxy * new_proxy)
|
||||
{
|
||||
g_return_if_fail (old_proxy_ptr != NULL);
|
||||
|
||||
gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (old_proxy_ptr),
|
||||
GST_VAAPI_MINI_OBJECT (new_proxy));
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_buffer_proxy_get_type:
|
||||
* @proxy: a #GstVaapiBufferProxy
|
||||
*
|
||||
* Returns the underlying VA buffer memory type.
|
||||
*
|
||||
* Return value: the buffer memory type
|
||||
*/
|
||||
guint
|
||||
gst_vaapi_buffer_proxy_get_type (GstVaapiBufferProxy * proxy)
|
||||
{
|
||||
g_return_val_if_fail (proxy != NULL, 0);
|
||||
|
||||
return GST_VAAPI_BUFFER_PROXY_TYPE (proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_buffer_proxy_get_handle:
|
||||
* @proxy: a #GstVaapiBufferProxy
|
||||
*
|
||||
* Returns the underlying VA buffer handle stored in the @proxy.
|
||||
*
|
||||
* Return value: the buffer handle
|
||||
*/
|
||||
guintptr
|
||||
gst_vaapi_buffer_proxy_get_handle (GstVaapiBufferProxy * proxy)
|
||||
{
|
||||
g_return_val_if_fail (proxy != NULL, 0);
|
||||
|
||||
return GST_VAAPI_BUFFER_PROXY_HANDLE (proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_buffer_proxy_get_size:
|
||||
* @proxy: a #GstVaapiBufferProxy
|
||||
*
|
||||
* Returns the underlying VA buffer memory size in bytes.
|
||||
*
|
||||
* Return value: the buffer size in bytes
|
||||
*/
|
||||
gsize
|
||||
gst_vaapi_buffer_proxy_get_size (GstVaapiBufferProxy * proxy)
|
||||
{
|
||||
g_return_val_if_fail (proxy != NULL, 0);
|
||||
|
||||
return GST_VAAPI_BUFFER_PROXY_SIZE (proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_buffer_proxy_release_data:
|
||||
* @proxy: a #GstVaapiBufferProxy
|
||||
*
|
||||
* Notifies the user to destroy the user's data, though the @proxy is
|
||||
* not going to be destroyed.
|
||||
**/
|
||||
void
|
||||
gst_vaapi_buffer_proxy_release_data (GstVaapiBufferProxy * proxy)
|
||||
{
|
||||
g_return_if_fail (proxy != NULL);
|
||||
|
||||
if (proxy->destroy_func) {
|
||||
proxy->destroy_func (proxy->destroy_data);
|
||||
proxy->destroy_func = NULL;
|
||||
proxy->destroy_data = NULL;
|
||||
}
|
||||
}
|
106
gst-libs/gst/vaapi/gstvaapibufferproxy.h
Normal file
106
gst-libs/gst/vaapi/gstvaapibufferproxy.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* gstvaapibufferproxy.h - Buffer proxy abstraction
|
||||
*
|
||||
* Copyright (C) 2014 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_BUFFER_PROXY_H
|
||||
#define GST_VAAPI_BUFFER_PROXY_H
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_BUFFER_PROXY(obj) \
|
||||
((GstVaapiBufferProxy *)(obj))
|
||||
|
||||
/**
|
||||
* GST_VAAPI_BUFFER_PROXY_TYPE:
|
||||
* @buf: a #GstVaapiBufferProxy
|
||||
*
|
||||
* Macro that evaluates to the type of the underlying VA buffer @buf
|
||||
*/
|
||||
#define GST_VAAPI_BUFFER_PROXY_TYPE(buf) \
|
||||
gst_vaapi_buffer_proxy_get_type (GST_VAAPI_BUFFER_PROXY (buf))
|
||||
|
||||
/**
|
||||
* GST_VAAPI_BUFFER_PROXY_HANDLE:
|
||||
* @buf: a #GstVaapiBufferProxy
|
||||
*
|
||||
* Macro that evaluates to the handle of the underlying VA buffer @buf
|
||||
*/
|
||||
#define GST_VAAPI_BUFFER_PROXY_HANDLE(buf) \
|
||||
gst_vaapi_buffer_proxy_get_handle (GST_VAAPI_BUFFER_PROXY (buf))
|
||||
|
||||
/**
|
||||
* GST_VAAPI_BUFFER_PROXY_SIZE:
|
||||
* @buf: a #GstVaapiBufferProxy
|
||||
*
|
||||
* Macro that evaluates to the size of the underlying VA buffer @buf
|
||||
*/
|
||||
#define GST_VAAPI_BUFFER_PROXY_SIZE(buf) \
|
||||
gst_vaapi_buffer_proxy_get_size (GST_VAAPI_BUFFER_PROXY (buf))
|
||||
|
||||
typedef struct _GstVaapiBufferProxy GstVaapiBufferProxy;
|
||||
|
||||
/**
|
||||
* GstVaapiBufferMemoryType:
|
||||
* @GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF: DRM PRIME buffer memory type (old version).
|
||||
* @GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF2: DRM PRIME buffer memory type.
|
||||
* @GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF: Kernel DRM buffer memory type.
|
||||
* @GST_VAAPI_BUFFER_MEMORY_TYPE_V4L2: V4L2 buffer memory type.
|
||||
* @GST_VAAPI_BUFFER_MEMORY_TYPE_USER_PTR: User pointer memory type.
|
||||
*
|
||||
* Set of underlying VA buffer memory types.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF = 1,
|
||||
GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF2,
|
||||
GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF,
|
||||
GST_VAAPI_BUFFER_MEMORY_TYPE_V4L2,
|
||||
GST_VAAPI_BUFFER_MEMORY_TYPE_USER_PTR,
|
||||
} GstVaapiBufferMemoryType;
|
||||
|
||||
GstVaapiBufferProxy *
|
||||
gst_vaapi_buffer_proxy_new (guintptr handle, guint type, gsize size,
|
||||
GDestroyNotify destroy_func, gpointer user_data);
|
||||
|
||||
GstVaapiBufferProxy *
|
||||
gst_vaapi_buffer_proxy_ref (GstVaapiBufferProxy * proxy);
|
||||
|
||||
void
|
||||
gst_vaapi_buffer_proxy_unref (GstVaapiBufferProxy * proxy);
|
||||
|
||||
void
|
||||
gst_vaapi_buffer_proxy_replace (GstVaapiBufferProxy ** old_proxy_ptr,
|
||||
GstVaapiBufferProxy * new_proxy);
|
||||
|
||||
guint
|
||||
gst_vaapi_buffer_proxy_get_type (GstVaapiBufferProxy * proxy);
|
||||
|
||||
guintptr
|
||||
gst_vaapi_buffer_proxy_get_handle (GstVaapiBufferProxy * proxy);
|
||||
|
||||
gsize
|
||||
gst_vaapi_buffer_proxy_get_size (GstVaapiBufferProxy * proxy);
|
||||
|
||||
void
|
||||
gst_vaapi_buffer_proxy_release_data (GstVaapiBufferProxy * proxy);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_BUFFER_PROXY_H */
|
88
gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h
Normal file
88
gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* gstvaapibufferproxy_priv.h - Buffer proxy abstraction (private definitions)
|
||||
*
|
||||
* Copyright (C) 2014 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_BUFFER_PROXY_PRIV_H
|
||||
#define GST_VAAPI_BUFFER_PROXY_PRIV_H
|
||||
|
||||
#include "gstvaapibufferproxy.h"
|
||||
#include "gstvaapiminiobject.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* GST_VAAPI_BUFFER_PROXY_TYPE:
|
||||
* @buf: a #GstVaapiBufferProxy
|
||||
*
|
||||
* Macro that evaluates to the type of the underlying VA buffer @buf
|
||||
*/
|
||||
#undef GST_VAAPI_BUFFER_PROXY_TYPE
|
||||
#define GST_VAAPI_BUFFER_PROXY_TYPE(buf) \
|
||||
(GST_VAAPI_BUFFER_PROXY (buf)->type)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_BUFFER_PROXY_HANDLE:
|
||||
* @buf: a #GstVaapiBufferProxy
|
||||
*
|
||||
* Macro that evaluates to the handle of the underlying VA buffer @buf
|
||||
*/
|
||||
#undef GST_VAAPI_BUFFER_PROXY_HANDLE
|
||||
#define GST_VAAPI_BUFFER_PROXY_HANDLE(buf) \
|
||||
(GST_VAAPI_BUFFER_PROXY (buf)->va_info.handle)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_BUFFER_PROXY_SIZE:
|
||||
* @buf: a #GstVaapiBufferProxy
|
||||
*
|
||||
* Macro that evaluates to the size of the underlying VA buffer @buf
|
||||
*/
|
||||
#undef GST_VAAPI_BUFFER_PROXY_SIZE
|
||||
#define GST_VAAPI_BUFFER_PROXY_SIZE(buf) \
|
||||
(GST_VAAPI_BUFFER_PROXY (buf)->va_info.mem_size)
|
||||
|
||||
struct _GstVaapiBufferProxy {
|
||||
/*< private >*/
|
||||
GstVaapiMiniObject parent_instance;
|
||||
GstMiniObject *surface;
|
||||
|
||||
GDestroyNotify destroy_func;
|
||||
gpointer destroy_data;
|
||||
guint type;
|
||||
VABufferID va_buf;
|
||||
VABufferInfo va_info;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiBufferProxy *
|
||||
gst_vaapi_buffer_proxy_new_from_surface (GstMiniObject * surface,
|
||||
VABufferID buf_id, guint type, GDestroyNotify destroy_func, gpointer data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
guint
|
||||
from_GstVaapiBufferMemoryType (guint type);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
guint
|
||||
to_GstVaapiBufferMemoryType (guint va_type);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_BUFFER_PROXY_PRIV_H */
|
255
gst-libs/gst/vaapi/gstvaapicodec_objects.c
Normal file
255
gst-libs/gst/vaapi/gstvaapicodec_objects.c
Normal file
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* gstvaapicodec_objects.c - VA codec objects abstraction
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||
* Copyright (C) 2011-2014 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include <gst/vaapi/gstvaapicontext.h>
|
||||
#include "gstvaapicodec_objects.h"
|
||||
#include "gstvaapidecoder_priv.h"
|
||||
#include "gstvaapicompat.h"
|
||||
#include "gstvaapiutils.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Base Codec Object --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_CODEC_OBJECT_GET_CLASS(object) \
|
||||
gst_vaapi_codec_object_get_class(object)
|
||||
|
||||
const GstVaapiCodecObjectClass *
|
||||
gst_vaapi_codec_object_get_class (GstVaapiCodecObject * object)
|
||||
{
|
||||
return (const GstVaapiCodecObjectClass *)
|
||||
GST_VAAPI_MINI_OBJECT_GET_CLASS (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_codec_object_create (GstVaapiCodecObject * object,
|
||||
const GstVaapiCodecObjectConstructorArgs * args)
|
||||
{
|
||||
const GstVaapiCodecObjectClass *klass;
|
||||
|
||||
g_return_val_if_fail (args->param_size > 0, FALSE);
|
||||
|
||||
if (GST_VAAPI_MINI_OBJECT_FLAG_IS_SET (object,
|
||||
GST_VAAPI_CODEC_OBJECT_FLAG_CONSTRUCTED))
|
||||
return TRUE;
|
||||
|
||||
klass = GST_VAAPI_CODEC_OBJECT_GET_CLASS (object);
|
||||
if (!klass->create || !klass->create (object, args))
|
||||
return FALSE;
|
||||
|
||||
GST_VAAPI_MINI_OBJECT_FLAG_SET (object,
|
||||
GST_VAAPI_CODEC_OBJECT_FLAG_CONSTRUCTED);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstVaapiCodecObject *
|
||||
gst_vaapi_codec_object_new_with_param_num (const GstVaapiCodecObjectClass *
|
||||
object_class, GstVaapiCodecBase * codec, gconstpointer param,
|
||||
guint param_size, guint param_num, gconstpointer data,
|
||||
guint data_size, guint flags)
|
||||
{
|
||||
GstVaapiCodecObject *obj;
|
||||
GstVaapiCodecObjectConstructorArgs args;
|
||||
|
||||
obj = (GstVaapiCodecObject *)
|
||||
gst_vaapi_mini_object_new0 (GST_VAAPI_MINI_OBJECT_CLASS (object_class));
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
obj = GST_VAAPI_CODEC_OBJECT (obj);
|
||||
obj->codec = codec;
|
||||
|
||||
args.param = param;
|
||||
args.param_size = param_size;
|
||||
args.param_num = param_num;
|
||||
args.data = data;
|
||||
args.data_size = data_size;
|
||||
args.flags = flags;
|
||||
|
||||
if (gst_vaapi_codec_object_create (obj, &args))
|
||||
return obj;
|
||||
|
||||
gst_vaapi_codec_object_unref (obj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GstVaapiCodecObject *
|
||||
gst_vaapi_codec_object_new (const GstVaapiCodecObjectClass * object_class,
|
||||
GstVaapiCodecBase * codec, gconstpointer param, guint param_size,
|
||||
gconstpointer data, guint data_size, guint flags)
|
||||
{
|
||||
return gst_vaapi_codec_object_new_with_param_num (object_class, codec, param,
|
||||
param_size, 1, data, data_size, flags);
|
||||
}
|
||||
|
||||
#define GET_DECODER(obj) GST_VAAPI_DECODER_CAST((obj)->parent_instance.codec)
|
||||
#define GET_VA_DISPLAY(obj) GET_DECODER(obj)->va_display
|
||||
#define GET_VA_CONTEXT(obj) GET_DECODER(obj)->va_context
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Inverse Quantization Matrices --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiIqMatrix, gst_vaapi_iq_matrix);
|
||||
|
||||
void
|
||||
gst_vaapi_iq_matrix_destroy (GstVaapiIqMatrix * iq_matrix)
|
||||
{
|
||||
vaapi_destroy_buffer (GET_VA_DISPLAY (iq_matrix), &iq_matrix->param_id);
|
||||
iq_matrix->param = NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_iq_matrix_create (GstVaapiIqMatrix * iq_matrix,
|
||||
const GstVaapiCodecObjectConstructorArgs * args)
|
||||
{
|
||||
iq_matrix->param_id = VA_INVALID_ID;
|
||||
return vaapi_create_buffer (GET_VA_DISPLAY (iq_matrix),
|
||||
GET_VA_CONTEXT (iq_matrix), VAIQMatrixBufferType,
|
||||
args->param_size, args->param, &iq_matrix->param_id, &iq_matrix->param);
|
||||
}
|
||||
|
||||
GstVaapiIqMatrix *
|
||||
gst_vaapi_iq_matrix_new (GstVaapiDecoder * decoder,
|
||||
gconstpointer param, guint param_size)
|
||||
{
|
||||
GstVaapiCodecObject *object;
|
||||
|
||||
object = gst_vaapi_codec_object_new (&GstVaapiIqMatrixClass,
|
||||
GST_VAAPI_CODEC_BASE (decoder), param, param_size, NULL, 0, 0);
|
||||
if (!object)
|
||||
return NULL;
|
||||
return GST_VAAPI_IQ_MATRIX_CAST (object);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- VC-1 Bit Planes --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiBitPlane, gst_vaapi_bitplane);
|
||||
|
||||
void
|
||||
gst_vaapi_bitplane_destroy (GstVaapiBitPlane * bitplane)
|
||||
{
|
||||
vaapi_destroy_buffer (GET_VA_DISPLAY (bitplane), &bitplane->data_id);
|
||||
bitplane->data = NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_bitplane_create (GstVaapiBitPlane * bitplane,
|
||||
const GstVaapiCodecObjectConstructorArgs * args)
|
||||
{
|
||||
bitplane->data_id = VA_INVALID_ID;
|
||||
return vaapi_create_buffer (GET_VA_DISPLAY (bitplane),
|
||||
GET_VA_CONTEXT (bitplane), VABitPlaneBufferType, args->param_size,
|
||||
args->param, &bitplane->data_id, (void **) &bitplane->data);
|
||||
}
|
||||
|
||||
|
||||
GstVaapiBitPlane *
|
||||
gst_vaapi_bitplane_new (GstVaapiDecoder * decoder, guint8 * data,
|
||||
guint data_size)
|
||||
{
|
||||
GstVaapiCodecObject *object;
|
||||
|
||||
object = gst_vaapi_codec_object_new (&GstVaapiBitPlaneClass,
|
||||
GST_VAAPI_CODEC_BASE (decoder), data, data_size, NULL, 0, 0);
|
||||
if (!object)
|
||||
return NULL;
|
||||
return GST_VAAPI_BITPLANE_CAST (object);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- JPEG Huffman Tables --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiHuffmanTable, gst_vaapi_huffman_table);
|
||||
|
||||
void
|
||||
gst_vaapi_huffman_table_destroy (GstVaapiHuffmanTable * huf_table)
|
||||
{
|
||||
vaapi_destroy_buffer (GET_VA_DISPLAY (huf_table), &huf_table->param_id);
|
||||
huf_table->param = NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_huffman_table_create (GstVaapiHuffmanTable * huf_table,
|
||||
const GstVaapiCodecObjectConstructorArgs * args)
|
||||
{
|
||||
huf_table->param_id = VA_INVALID_ID;
|
||||
return vaapi_create_buffer (GET_VA_DISPLAY (huf_table),
|
||||
GET_VA_CONTEXT (huf_table), VAHuffmanTableBufferType, args->param_size,
|
||||
args->param, &huf_table->param_id, (void **) &huf_table->param);
|
||||
}
|
||||
|
||||
GstVaapiHuffmanTable *
|
||||
gst_vaapi_huffman_table_new (GstVaapiDecoder * decoder,
|
||||
guint8 * data, guint data_size)
|
||||
{
|
||||
GstVaapiCodecObject *object;
|
||||
|
||||
object = gst_vaapi_codec_object_new (&GstVaapiHuffmanTableClass,
|
||||
GST_VAAPI_CODEC_BASE (decoder), data, data_size, NULL, 0, 0);
|
||||
if (!object)
|
||||
return NULL;
|
||||
return GST_VAAPI_HUFFMAN_TABLE_CAST (object);
|
||||
}
|
||||
|
||||
GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiProbabilityTable,
|
||||
gst_vaapi_probability_table);
|
||||
|
||||
void
|
||||
gst_vaapi_probability_table_destroy (GstVaapiProbabilityTable * prob_table)
|
||||
{
|
||||
vaapi_destroy_buffer (GET_VA_DISPLAY (prob_table), &prob_table->param_id);
|
||||
prob_table->param = NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_probability_table_create (GstVaapiProbabilityTable * prob_table,
|
||||
const GstVaapiCodecObjectConstructorArgs * args)
|
||||
{
|
||||
prob_table->param_id = VA_INVALID_ID;
|
||||
return vaapi_create_buffer (GET_VA_DISPLAY (prob_table),
|
||||
GET_VA_CONTEXT (prob_table),
|
||||
VAProbabilityBufferType,
|
||||
args->param_size, args->param, &prob_table->param_id, &prob_table->param);
|
||||
}
|
||||
|
||||
GstVaapiProbabilityTable *
|
||||
gst_vaapi_probability_table_new (GstVaapiDecoder * decoder,
|
||||
gconstpointer param, guint param_size)
|
||||
{
|
||||
GstVaapiCodecObject *object;
|
||||
|
||||
object = gst_vaapi_codec_object_new (&GstVaapiProbabilityTableClass,
|
||||
GST_VAAPI_CODEC_BASE (decoder), param, param_size, NULL, 0, 0);
|
||||
if (!object)
|
||||
return NULL;
|
||||
return GST_VAAPI_PROBABILITY_TABLE_CAST (object);
|
||||
}
|
275
gst-libs/gst/vaapi/gstvaapicodec_objects.h
Normal file
275
gst-libs/gst/vaapi/gstvaapicodec_objects.h
Normal file
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
* gstvaapicodec_objects.h - VA codec objects abstraction
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||
* Copyright (C) 2011-2014 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_CODEC_COMMON_H
|
||||
#define GST_VAAPI_CODEC_COMMON_H
|
||||
|
||||
#include <gst/vaapi/gstvaapiminiobject.h>
|
||||
#include <gst/vaapi/gstvaapidecoder.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef gpointer GstVaapiCodecBase;
|
||||
typedef struct _GstVaapiCodecObject GstVaapiCodecObject;
|
||||
typedef struct _GstVaapiCodecObjectClass GstVaapiCodecObjectClass;
|
||||
typedef struct _GstVaapiIqMatrix GstVaapiIqMatrix;
|
||||
typedef struct _GstVaapiBitPlane GstVaapiBitPlane;
|
||||
typedef struct _GstVaapiHuffmanTable GstVaapiHuffmanTable;
|
||||
typedef struct _GstVaapiProbabilityTable GstVaapiProbabilityTable;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Base Codec Object --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* XXX: remove when a common base class for decoder and encoder is available */
|
||||
#define GST_VAAPI_CODEC_BASE(obj) \
|
||||
((GstVaapiCodecBase *) (obj))
|
||||
|
||||
#define GST_VAAPI_CODEC_OBJECT(obj) \
|
||||
((GstVaapiCodecObject *) (obj))
|
||||
|
||||
enum
|
||||
{
|
||||
GST_VAAPI_CODEC_OBJECT_FLAG_CONSTRUCTED = (1 << 0),
|
||||
GST_VAAPI_CODEC_OBJECT_FLAG_LAST = (1 << 1)
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gconstpointer param;
|
||||
guint param_size;
|
||||
guint param_num;
|
||||
gconstpointer data;
|
||||
guint data_size;
|
||||
guint flags;
|
||||
} GstVaapiCodecObjectConstructorArgs;
|
||||
|
||||
typedef gboolean
|
||||
(*GstVaapiCodecObjectCreateFunc)(GstVaapiCodecObject * object,
|
||||
const GstVaapiCodecObjectConstructorArgs * args);
|
||||
|
||||
typedef GDestroyNotify GstVaapiCodecObjectDestroyFunc;
|
||||
|
||||
/**
|
||||
* GstVaapiCodecObject:
|
||||
*
|
||||
* A #GstVaapiMiniObject holding the base codec object data
|
||||
*/
|
||||
struct _GstVaapiCodecObject
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiMiniObject parent_instance;
|
||||
GstVaapiCodecBase *codec;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiCodecObjectClass:
|
||||
*
|
||||
* The #GstVaapiCodecObject base class.
|
||||
*/
|
||||
struct _GstVaapiCodecObjectClass
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiMiniObjectClass parent_class;
|
||||
|
||||
GstVaapiCodecObjectCreateFunc create;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
const GstVaapiCodecObjectClass *
|
||||
gst_vaapi_codec_object_get_class (GstVaapiCodecObject * object) G_GNUC_CONST;
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiCodecObject *
|
||||
gst_vaapi_codec_object_new (const GstVaapiCodecObjectClass * object_class,
|
||||
GstVaapiCodecBase * codec, gconstpointer param, guint param_size,
|
||||
gconstpointer data, guint data_size, guint flags);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiCodecObject *
|
||||
gst_vaapi_codec_object_new_with_param_num (const GstVaapiCodecObjectClass *
|
||||
object_class, GstVaapiCodecBase * codec, gconstpointer param,
|
||||
guint param_size, guint param_num, gconstpointer data,
|
||||
guint data_size, guint flags);
|
||||
|
||||
#define gst_vaapi_codec_object_ref(object) \
|
||||
((gpointer) gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (object)))
|
||||
|
||||
#define gst_vaapi_codec_object_unref(object) \
|
||||
gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (object))
|
||||
|
||||
#define gst_vaapi_codec_object_replace(old_object_ptr, new_object) \
|
||||
gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (old_object_ptr), \
|
||||
GST_VAAPI_MINI_OBJECT (new_object))
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Inverse Quantization Matrices --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_IQ_MATRIX_CAST(obj) \
|
||||
((GstVaapiIqMatrix *) (obj))
|
||||
|
||||
/**
|
||||
* GstVaapiIqMatrix:
|
||||
*
|
||||
* A #GstVaapiCodecObject holding an inverse quantization matrix parameter.
|
||||
*/
|
||||
struct _GstVaapiIqMatrix
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiCodecObject parent_instance;
|
||||
VABufferID param_id;
|
||||
|
||||
/*< public >*/
|
||||
gpointer param;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiIqMatrix *
|
||||
gst_vaapi_iq_matrix_new (GstVaapiDecoder * decoder, gconstpointer param,
|
||||
guint param_size);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- VC-1 Bit Planes --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_BITPLANE_CAST(obj) \
|
||||
((GstVaapiBitPlane *) (obj))
|
||||
|
||||
/**
|
||||
* GstVaapiBitPlane:
|
||||
*
|
||||
* A #GstVaapiCodecObject holding a VC-1 bit plane parameter.
|
||||
*/
|
||||
struct _GstVaapiBitPlane
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiCodecObject parent_instance;
|
||||
VABufferID data_id;
|
||||
|
||||
/*< public >*/
|
||||
guint8 *data;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiBitPlane *
|
||||
gst_vaapi_bitplane_new (GstVaapiDecoder * decoder, guint8 * data,
|
||||
guint data_size);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- JPEG Huffman Tables --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_HUFFMAN_TABLE_CAST(obj) \
|
||||
((GstVaapiHuffmanTable *) (obj))
|
||||
|
||||
/**
|
||||
* GstVaapiHuffmanTable:
|
||||
*
|
||||
* A #GstVaapiCodecObject holding huffman table.
|
||||
*/
|
||||
struct _GstVaapiHuffmanTable
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiCodecObject parent_instance;
|
||||
VABufferID param_id;
|
||||
|
||||
/*< public >*/
|
||||
gpointer param;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiHuffmanTable *
|
||||
gst_vaapi_huffman_table_new (GstVaapiDecoder * decoder, guint8 * data,
|
||||
guint data_size);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Probability (Update) Table --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_PROBABILITY_TABLE_CAST(obj) \
|
||||
((GstVaapiProbabilityTable *)(obj))
|
||||
|
||||
/**
|
||||
* GstVaapiProbabilityTable:
|
||||
*
|
||||
* A #GstVaapiCodecObject holding an Probability (Update) Table for RAC decoding
|
||||
*/
|
||||
struct _GstVaapiProbabilityTable
|
||||
{
|
||||
/*< private > */
|
||||
GstVaapiCodecObject parent_instance;
|
||||
VABufferID param_id;
|
||||
|
||||
/*< public > */
|
||||
gpointer param;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiProbabilityTable *
|
||||
gst_vaapi_probability_table_new (GstVaapiDecoder * decoder,
|
||||
gconstpointer param, guint param_size);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Helpers to create codec-dependent objects --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_CODEC_DEFINE_TYPE(type, prefix) \
|
||||
G_GNUC_INTERNAL \
|
||||
void \
|
||||
G_PASTE (prefix, _destroy) (type *); \
|
||||
\
|
||||
G_GNUC_INTERNAL \
|
||||
gboolean \
|
||||
G_PASTE (prefix, _create) (type *, \
|
||||
const GstVaapiCodecObjectConstructorArgs * args); \
|
||||
\
|
||||
static const GstVaapiCodecObjectClass G_PASTE (type, Class) = { \
|
||||
.parent_class = { \
|
||||
.size = sizeof (type), \
|
||||
.finalize = (GstVaapiCodecObjectDestroyFunc) \
|
||||
G_PASTE (prefix, _destroy) \
|
||||
}, \
|
||||
.create = (GstVaapiCodecObjectCreateFunc) \
|
||||
G_PASTE (prefix, _create), \
|
||||
}
|
||||
|
||||
#define GST_VAAPI_IQ_MATRIX_NEW(codec, decoder) \
|
||||
gst_vaapi_iq_matrix_new (GST_VAAPI_DECODER_CAST (decoder), \
|
||||
NULL, sizeof (G_PASTE (VAIQMatrixBuffer, codec)))
|
||||
|
||||
#define GST_VAAPI_BITPLANE_NEW(decoder, size) \
|
||||
gst_vaapi_bitplane_new (GST_VAAPI_DECODER_CAST (decoder), NULL, size)
|
||||
|
||||
#define GST_VAAPI_HUFFMAN_TABLE_NEW(codec, decoder) \
|
||||
gst_vaapi_huffman_table_new (GST_VAAPI_DECODER_CAST (decoder), \
|
||||
NULL, sizeof (G_PASTE (VAHuffmanTableBuffer, codec)))
|
||||
|
||||
#define GST_VAAPI_PROBABILITY_TABLE_NEW(codec, decoder) \
|
||||
gst_vaapi_probability_table_new (GST_VAAPI_DECODER_CAST (decoder), \
|
||||
NULL, sizeof (G_PASTE (VAProbabilityDataBuffer, codec)))
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_CODEC_OBJECTS_H */
|
251
gst-libs/gst/vaapi/gstvaapicodedbuffer.c
Normal file
251
gst-libs/gst/vaapi/gstvaapicodedbuffer.c
Normal file
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* gstvaapicodedbuffer.c - VA coded buffer abstraction
|
||||
*
|
||||
* Copyright (C) 2013 Intel Corporation
|
||||
* Author: Wind Yuan <feng.yuan@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "gstvaapicodedbuffer.h"
|
||||
#include "gstvaapicodedbuffer_priv.h"
|
||||
#include "gstvaapiencoder_priv.h"
|
||||
#include "gstvaapiutils.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
static gboolean
|
||||
coded_buffer_create (GstVaapiCodedBuffer * buf, guint buf_size,
|
||||
GstVaapiContext * context)
|
||||
{
|
||||
GstVaapiDisplay *const display = GST_VAAPI_CODED_BUFFER_DISPLAY (buf);
|
||||
VABufferID buf_id;
|
||||
gboolean success;
|
||||
|
||||
GST_VAAPI_DISPLAY_LOCK (display);
|
||||
success = vaapi_create_buffer (GST_VAAPI_DISPLAY_VADISPLAY (display),
|
||||
GST_VAAPI_CONTEXT_ID (context), VAEncCodedBufferType, buf_size,
|
||||
NULL, &buf_id, NULL);
|
||||
GST_VAAPI_DISPLAY_UNLOCK (display);
|
||||
if (!success)
|
||||
return FALSE;
|
||||
|
||||
GST_DEBUG ("coded buffer %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (buf_id));
|
||||
GST_VAAPI_CODED_BUFFER_ID (buf) = buf_id;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
coded_buffer_free (GstVaapiCodedBuffer * buf)
|
||||
{
|
||||
GstVaapiDisplay *const display = GST_VAAPI_CODED_BUFFER_DISPLAY (buf);
|
||||
VABufferID buf_id;
|
||||
|
||||
buf_id = GST_VAAPI_CODED_BUFFER_ID (buf);
|
||||
GST_DEBUG ("coded buffer %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (buf_id));
|
||||
|
||||
if (buf_id != VA_INVALID_ID) {
|
||||
GST_VAAPI_DISPLAY_LOCK (display);
|
||||
vaapi_destroy_buffer (GST_VAAPI_DISPLAY_VADISPLAY (display), &buf_id);
|
||||
GST_VAAPI_DISPLAY_UNLOCK (display);
|
||||
GST_VAAPI_CODED_BUFFER_ID (buf) = VA_INVALID_ID;
|
||||
}
|
||||
|
||||
gst_vaapi_display_replace (&GST_VAAPI_CODED_BUFFER_DISPLAY (buf), NULL);
|
||||
|
||||
g_slice_free1 (sizeof (GstVaapiCodedBuffer), buf);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
coded_buffer_map (GstVaapiCodedBuffer * buf)
|
||||
{
|
||||
GstVaapiDisplay *const display = GST_VAAPI_CODED_BUFFER_DISPLAY (buf);
|
||||
|
||||
if (buf->segment_list)
|
||||
return TRUE;
|
||||
|
||||
GST_VAAPI_DISPLAY_LOCK (display);
|
||||
buf->segment_list =
|
||||
vaapi_map_buffer (GST_VAAPI_DISPLAY_VADISPLAY (display),
|
||||
GST_VAAPI_CODED_BUFFER_ID (buf));
|
||||
GST_VAAPI_DISPLAY_UNLOCK (display);
|
||||
return buf->segment_list != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
coded_buffer_unmap (GstVaapiCodedBuffer * buf)
|
||||
{
|
||||
GstVaapiDisplay *const display = GST_VAAPI_CODED_BUFFER_DISPLAY (buf);
|
||||
|
||||
if (!buf->segment_list)
|
||||
return;
|
||||
|
||||
GST_VAAPI_DISPLAY_LOCK (display);
|
||||
vaapi_unmap_buffer (GST_VAAPI_DISPLAY_VADISPLAY (display),
|
||||
GST_VAAPI_CODED_BUFFER_ID (buf), (void **) &buf->segment_list);
|
||||
GST_VAAPI_DISPLAY_UNLOCK (display);
|
||||
}
|
||||
|
||||
GST_DEFINE_MINI_OBJECT_TYPE (GstVaapiCodedBuffer, gst_vaapi_coded_buffer);
|
||||
|
||||
/*
|
||||
* gst_vaapi_coded_buffer_new:
|
||||
* @context: the parent #GstVaapiContext object
|
||||
* @buf_size: the buffer size in bytes
|
||||
*
|
||||
* Creates a new VA coded buffer bound to the supplied @context.
|
||||
*
|
||||
* Return value: the newly allocated #GstVaapiCodedBuffer object, or
|
||||
* %NULL if an error occurred
|
||||
*/
|
||||
GstVaapiCodedBuffer *
|
||||
gst_vaapi_coded_buffer_new (GstVaapiContext * context, guint buf_size)
|
||||
{
|
||||
GstVaapiCodedBuffer *buf;
|
||||
GstVaapiDisplay *display;
|
||||
|
||||
g_return_val_if_fail (context != NULL, NULL);
|
||||
g_return_val_if_fail (buf_size > 0, NULL);
|
||||
|
||||
display = GST_VAAPI_CONTEXT_DISPLAY (context);
|
||||
g_return_val_if_fail (display != NULL, NULL);
|
||||
|
||||
buf = g_slice_new (GstVaapiCodedBuffer);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
gst_mini_object_init (GST_MINI_OBJECT_CAST (buf), 0,
|
||||
GST_TYPE_VAAPI_CODED_BUFFER, NULL, NULL,
|
||||
(GstMiniObjectFreeFunction) coded_buffer_free);
|
||||
|
||||
GST_VAAPI_CODED_BUFFER_DISPLAY (buf) = gst_object_ref (display);
|
||||
GST_VAAPI_CODED_BUFFER_ID (buf) = VA_INVALID_ID;
|
||||
buf->segment_list = NULL;
|
||||
|
||||
if (!coded_buffer_create (buf, buf_size, context))
|
||||
goto error;
|
||||
return buf;
|
||||
|
||||
/* ERRORS */
|
||||
error:
|
||||
{
|
||||
gst_vaapi_coded_buffer_unref (buf);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* gst_vaapi_coded_buffer_map:
|
||||
* @buf: a #GstVaapiCodedBuffer
|
||||
* @data: pointer to the mapped buffer data (VACodedBufferSegment)
|
||||
*
|
||||
* Maps the VA coded buffer and returns the data pointer into @data.
|
||||
*
|
||||
* Return value: %TRUE if successful, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
gst_vaapi_coded_buffer_map (GstVaapiCodedBuffer * buf,
|
||||
VACodedBufferSegment ** out_segment_list_ptr)
|
||||
{
|
||||
g_return_val_if_fail (buf != NULL, FALSE);
|
||||
g_return_val_if_fail (out_segment_list_ptr != NULL, FALSE);
|
||||
|
||||
if (!coded_buffer_map (buf))
|
||||
return FALSE;
|
||||
|
||||
*out_segment_list_ptr = buf->segment_list;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* gst_vaapi_coded_buffer_unmap:
|
||||
* @buf: a #GstVaapiCodedBuffer
|
||||
*
|
||||
* Unamps the VA coded buffer.
|
||||
*/
|
||||
void
|
||||
gst_vaapi_coded_buffer_unmap (GstVaapiCodedBuffer * buf)
|
||||
{
|
||||
g_return_if_fail (buf != NULL);
|
||||
|
||||
coded_buffer_unmap (buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_coded_buffer_get_size:
|
||||
* @buf: a #GstVaapiCodedBuffer
|
||||
*
|
||||
* Returns the VA coded buffer size in bytes. That represents the
|
||||
* exact buffer size, as filled in so far, not the size of the
|
||||
* allocated buffer.
|
||||
*
|
||||
* Return value: the size of the VA coded buffer, or -1 on error
|
||||
*/
|
||||
gssize
|
||||
gst_vaapi_coded_buffer_get_size (GstVaapiCodedBuffer * buf)
|
||||
{
|
||||
VACodedBufferSegment *segment;
|
||||
gssize size;
|
||||
|
||||
g_return_val_if_fail (buf != NULL, -1);
|
||||
|
||||
if (!coded_buffer_map (buf))
|
||||
return -1;
|
||||
|
||||
size = 0;
|
||||
for (segment = buf->segment_list; segment != NULL; segment = segment->next)
|
||||
size += segment->size;
|
||||
|
||||
coded_buffer_unmap (buf);
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_coded_buffer_copy_into:
|
||||
* @dest: the destination #GstBuffer
|
||||
* @src: the source #GstVaapiCodedBuffer
|
||||
*
|
||||
* Copies the coded buffer data from @src into the regular buffer @dest.
|
||||
*
|
||||
* Return value: %TRUE if successful, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
gst_vaapi_coded_buffer_copy_into (GstBuffer * dest, GstVaapiCodedBuffer * src)
|
||||
{
|
||||
VACodedBufferSegment *segment;
|
||||
goffset offset;
|
||||
gsize size;
|
||||
|
||||
g_return_val_if_fail (src != NULL, FALSE);
|
||||
g_return_val_if_fail (dest != NULL, FALSE);
|
||||
|
||||
if (!coded_buffer_map (src))
|
||||
return FALSE;
|
||||
|
||||
offset = 0;
|
||||
for (segment = src->segment_list; segment != NULL; segment = segment->next) {
|
||||
size = gst_buffer_fill (dest, offset, segment->buf, segment->size);
|
||||
if (size != segment->size)
|
||||
break;
|
||||
offset += segment->size;
|
||||
}
|
||||
|
||||
coded_buffer_unmap (src);
|
||||
return segment == NULL;
|
||||
}
|
73
gst-libs/gst/vaapi/gstvaapicodedbuffer.h
Normal file
73
gst-libs/gst/vaapi/gstvaapicodedbuffer.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* gstvaapicodedbuffer.h - VA coded buffer abstraction
|
||||
*
|
||||
* Copyright (C) 2013 Intel Corporation
|
||||
* Author: Wind Yuan <feng.yuan@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_CODED_BUFFER_H
|
||||
#define GST_VAAPI_CODED_BUFFER_H
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_CODED_BUFFER(obj) \
|
||||
((GstVaapiCodedBuffer *)(obj))
|
||||
|
||||
/**
|
||||
* GST_VAAPI_CODED_BUFFER_SIZE:
|
||||
* @buf: a #GstVaapiCodedBuffer
|
||||
*
|
||||
* Macro that evaluates to the size of the underlying VA coded buffer @buf
|
||||
*/
|
||||
#define GST_VAAPI_CODED_BUFFER_SIZE(buf) \
|
||||
gst_vaapi_coded_buffer_get_size (GST_VAAPI_CODED_BUFFER(buf))
|
||||
|
||||
typedef struct _GstVaapiCodedBuffer GstVaapiCodedBuffer;
|
||||
typedef struct _GstVaapiCodedBufferProxy GstVaapiCodedBufferProxy;
|
||||
typedef struct _GstVaapiCodedBufferPool GstVaapiCodedBufferPool;
|
||||
|
||||
#define GST_TYPE_VAAPI_CODED_BUFFER (gst_vaapi_coded_buffer_get_type ())
|
||||
|
||||
GType
|
||||
gst_vaapi_coded_buffer_get_type (void) G_GNUC_CONST;
|
||||
|
||||
/**
|
||||
* gst_vaapi_coded_buffer_unref: (skip)
|
||||
* @buf: (transfer full): a #GstVaapiCodedBuffer.
|
||||
*
|
||||
* Decreases the refcount of @buf. If the refcount reaches 0, the
|
||||
* @buf will be freed.
|
||||
*/
|
||||
static inline void
|
||||
gst_vaapi_coded_buffer_unref (GstVaapiCodedBuffer * buf)
|
||||
{
|
||||
gst_mini_object_unref (GST_MINI_OBJECT_CAST (buf));
|
||||
}
|
||||
|
||||
gssize
|
||||
gst_vaapi_coded_buffer_get_size (GstVaapiCodedBuffer * buf);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_coded_buffer_copy_into (GstBuffer * dest, GstVaapiCodedBuffer * src);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiCodedBuffer, gst_vaapi_coded_buffer_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_CODED_BUFFER_H */
|
84
gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h
Normal file
84
gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* gstvaapicodedbuffer_priv.h - VA coded buffer abstraction (private defs)
|
||||
*
|
||||
* Copyright (C) 2013 Intel Corporation
|
||||
* Author: Wind Yuan <feng.yuan@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_CODED_BUFFER_PRIV_H
|
||||
#define GST_VAAPI_CODED_BUFFER_PRIV_H
|
||||
|
||||
#include <gst/vaapi/gstvaapicontext.h>
|
||||
#include "gstvaapicodedbuffer.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_CODED_BUFFER_CAST(obj) \
|
||||
((GstVaapiCodedBuffer *)(obj))
|
||||
|
||||
/**
|
||||
* GstVaapiCodedBuffer:
|
||||
*
|
||||
* A VA coded buffer object wrapper.
|
||||
*/
|
||||
struct _GstVaapiCodedBuffer
|
||||
{
|
||||
/*< private >*/
|
||||
GstMiniObject mini_object;
|
||||
GstVaapiDisplay *display;
|
||||
GstVaapiID object_id;
|
||||
|
||||
/*< public >*/
|
||||
VACodedBufferSegment *segment_list;
|
||||
};
|
||||
|
||||
/**
|
||||
* GST_VAAPI_CODED_BUFFER_DISPLAY:
|
||||
* @buf: a #GstVaapiCodedBuffer
|
||||
*
|
||||
* Macro that evaluates to the #GstVaapiDisplay of @buf
|
||||
*/
|
||||
#undef GST_VAAPI_CODED_BUFFER_DISPLAY
|
||||
#define GST_VAAPI_CODED_BUFFER_DISPLAY(buf) (GST_VAAPI_CODED_BUFFER (buf)->display)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_CODED_BUFFER_ID:
|
||||
* @buf: a #GstVaapiCodedBuffer
|
||||
*
|
||||
* Macro that evaluates to the object ID of @buf
|
||||
*/
|
||||
#undef GST_VAAPI_CODED_BUFFER_ID
|
||||
#define GST_VAAPI_CODED_BUFFER_ID(buf) (GST_VAAPI_CODED_BUFFER (buf)->object_id)
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiCodedBuffer *
|
||||
gst_vaapi_coded_buffer_new (GstVaapiContext * context, guint buf_size);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_coded_buffer_map (GstVaapiCodedBuffer * buf,
|
||||
VACodedBufferSegment ** out_segment_list_ptr);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_coded_buffer_unmap (GstVaapiCodedBuffer * buf);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_CODED_BUFFER_PRIV_H */
|
132
gst-libs/gst/vaapi/gstvaapicodedbufferpool.c
Normal file
132
gst-libs/gst/vaapi/gstvaapicodedbufferpool.c
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* gstvaapicodedbufferpool.c - VA coded buffer pool
|
||||
*
|
||||
* Copyright (C) 2013-2014 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "gstvaapicodedbufferpool.h"
|
||||
#include "gstvaapicodedbuffer_priv.h"
|
||||
#include "gstvaapivideopool_priv.h"
|
||||
#include "gstvaapiencoder_priv.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
/**
|
||||
* GstVaapiCodedBufferPool:
|
||||
*
|
||||
* A pool of lazily allocated #GstVaapiCodedBuffer objects.
|
||||
*/
|
||||
struct _GstVaapiCodedBufferPool
|
||||
{
|
||||
/*< private > */
|
||||
GstVaapiVideoPool parent_instance;
|
||||
|
||||
GstVaapiContext *context;
|
||||
gsize buf_size;
|
||||
};
|
||||
|
||||
static void
|
||||
coded_buffer_pool_init (GstVaapiCodedBufferPool * pool,
|
||||
GstVaapiContext * context, gsize buf_size)
|
||||
{
|
||||
pool->context = gst_vaapi_context_ref (context);
|
||||
pool->buf_size = buf_size;
|
||||
}
|
||||
|
||||
static void
|
||||
coded_buffer_pool_finalize (GstVaapiCodedBufferPool * pool)
|
||||
{
|
||||
gst_vaapi_video_pool_finalize (GST_VAAPI_VIDEO_POOL (pool));
|
||||
gst_vaapi_context_unref (pool->context);
|
||||
pool->context = NULL;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
coded_buffer_pool_alloc_object (GstVaapiVideoPool * base_pool)
|
||||
{
|
||||
GstVaapiCodedBufferPool *const pool = GST_VAAPI_CODED_BUFFER_POOL (base_pool);
|
||||
|
||||
return gst_vaapi_coded_buffer_new (pool->context, pool->buf_size);
|
||||
}
|
||||
|
||||
static inline const GstVaapiMiniObjectClass *
|
||||
gst_vaapi_coded_buffer_pool_class (void)
|
||||
{
|
||||
static const GstVaapiVideoPoolClass GstVaapiCodedBufferPoolClass = {
|
||||
{sizeof (GstVaapiCodedBufferPool),
|
||||
(GDestroyNotify) coded_buffer_pool_finalize}
|
||||
,
|
||||
.alloc_object = coded_buffer_pool_alloc_object
|
||||
};
|
||||
return GST_VAAPI_MINI_OBJECT_CLASS (&GstVaapiCodedBufferPoolClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_coded_buffer_pool_new:
|
||||
* @encoder: a #GstVaapiEncoder
|
||||
* @buf_size: the max size of #GstVaapiCodedBuffer objects, in bytes
|
||||
*
|
||||
* Creates a new #GstVaapiVideoPool of #GstVaapiCodedBuffer objects
|
||||
* with the supplied maximum size in bytes, and bound to the specified
|
||||
* @encoder object.
|
||||
*
|
||||
* Return value: the newly allocated #GstVaapiVideoPool
|
||||
*/
|
||||
GstVaapiVideoPool *
|
||||
gst_vaapi_coded_buffer_pool_new (GstVaapiEncoder * encoder, gsize buf_size)
|
||||
{
|
||||
GstVaapiVideoPool *pool;
|
||||
GstVaapiContext *context;
|
||||
|
||||
g_return_val_if_fail (encoder != NULL, NULL);
|
||||
g_return_val_if_fail (buf_size > 0, NULL);
|
||||
|
||||
context = GST_VAAPI_ENCODER_CONTEXT (encoder);
|
||||
g_return_val_if_fail (context != NULL, NULL);
|
||||
|
||||
pool = (GstVaapiVideoPool *)
|
||||
gst_vaapi_mini_object_new (gst_vaapi_coded_buffer_pool_class ());
|
||||
if (!pool)
|
||||
return NULL;
|
||||
|
||||
gst_vaapi_video_pool_init (pool, GST_VAAPI_CONTEXT_DISPLAY (context),
|
||||
GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_CODED_BUFFER);
|
||||
coded_buffer_pool_init (GST_VAAPI_CODED_BUFFER_POOL (pool),
|
||||
context, buf_size);
|
||||
return pool;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_coded_buffer_pool_get_buffer_size:
|
||||
* @pool: a #GstVaapiCodedBufferPool
|
||||
*
|
||||
* Determines the maximum size of each #GstVaapiCodedBuffer held in
|
||||
* the @pool.
|
||||
*
|
||||
* Return value: size of a #GstVaapiCodedBuffer in @pool
|
||||
*/
|
||||
gsize
|
||||
gst_vaapi_coded_buffer_pool_get_buffer_size (GstVaapiCodedBufferPool * pool)
|
||||
{
|
||||
g_return_val_if_fail (pool != NULL, 0);
|
||||
|
||||
return pool->buf_size;
|
||||
}
|
45
gst-libs/gst/vaapi/gstvaapicodedbufferpool.h
Normal file
45
gst-libs/gst/vaapi/gstvaapicodedbufferpool.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* gstvaapicodedbufferpool.h - VA coded buffer pool
|
||||
*
|
||||
* Copyright (C) 2013-2014 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_CODED_BUFFER_POOL_H
|
||||
#define GST_VAAPI_CODED_BUFFER_POOL_H
|
||||
|
||||
#include <gst/vaapi/gstvaapivideopool.h>
|
||||
#include <gst/vaapi/gstvaapiencoder.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_CODED_BUFFER_POOL(obj) \
|
||||
((GstVaapiCodedBufferPool *)(obj))
|
||||
|
||||
struct _GstVaapiEncoder;
|
||||
|
||||
GstVaapiVideoPool *
|
||||
gst_vaapi_coded_buffer_pool_new (struct _GstVaapiEncoder * encoder,
|
||||
gsize buf_size);
|
||||
|
||||
gsize
|
||||
gst_vaapi_coded_buffer_pool_get_buffer_size (GstVaapiCodedBufferPool * pool);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_CODED_BUFFER_POOL_H */
|
256
gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c
Normal file
256
gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c
Normal file
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* gstvaapicodedbufferproxy.c - VA coded buffer proxy
|
||||
*
|
||||
* Copyright (C) 2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "gstvaapicodedbufferproxy.h"
|
||||
#include "gstvaapicodedbufferproxy_priv.h"
|
||||
#include "gstvaapivideopool_priv.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
static void
|
||||
coded_buffer_proxy_set_user_data (GstVaapiCodedBufferProxy * proxy,
|
||||
gpointer user_data, GDestroyNotify destroy_func)
|
||||
{
|
||||
if (proxy->user_data_destroy)
|
||||
proxy->user_data_destroy (proxy->user_data);
|
||||
|
||||
proxy->user_data = user_data;
|
||||
proxy->user_data_destroy = destroy_func;
|
||||
}
|
||||
|
||||
static void
|
||||
coded_buffer_proxy_finalize (GstVaapiCodedBufferProxy * proxy)
|
||||
{
|
||||
if (proxy->buffer) {
|
||||
if (proxy->pool)
|
||||
gst_vaapi_video_pool_put_object (proxy->pool, proxy->buffer);
|
||||
gst_vaapi_coded_buffer_unref (proxy->buffer);
|
||||
proxy->buffer = NULL;
|
||||
}
|
||||
gst_vaapi_video_pool_replace (&proxy->pool, NULL);
|
||||
coded_buffer_proxy_set_user_data (proxy, NULL, NULL);
|
||||
|
||||
/* Notify the user function that the object is now destroyed */
|
||||
if (proxy->destroy_func)
|
||||
proxy->destroy_func (proxy->destroy_data);
|
||||
}
|
||||
|
||||
static inline const GstVaapiMiniObjectClass *
|
||||
gst_vaapi_coded_buffer_proxy_class (void)
|
||||
{
|
||||
static const GstVaapiMiniObjectClass GstVaapiCodedBufferProxyClass = {
|
||||
sizeof (GstVaapiCodedBufferProxy),
|
||||
(GDestroyNotify) coded_buffer_proxy_finalize
|
||||
};
|
||||
return &GstVaapiCodedBufferProxyClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_coded_buffer_proxy_new_from_pool:
|
||||
* @pool: a #GstVaapiCodedBufferPool
|
||||
*
|
||||
* Allocates a new coded buffer from the supplied @pool and creates
|
||||
* the wrapped coded buffer proxy object from it. When the last
|
||||
* reference to the proxy object is released, then the underlying VA
|
||||
* coded buffer is pushed back to its parent pool.
|
||||
*
|
||||
* Returns: The same newly allocated @proxy object, or %NULL on error
|
||||
*/
|
||||
GstVaapiCodedBufferProxy *
|
||||
gst_vaapi_coded_buffer_proxy_new_from_pool (GstVaapiCodedBufferPool * pool)
|
||||
{
|
||||
GstVaapiCodedBufferProxy *proxy;
|
||||
|
||||
g_return_val_if_fail (pool != NULL, NULL);
|
||||
g_return_val_if_fail (GST_VAAPI_VIDEO_POOL (pool)->object_type ==
|
||||
GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_CODED_BUFFER, NULL);
|
||||
|
||||
proxy = (GstVaapiCodedBufferProxy *)
|
||||
gst_vaapi_mini_object_new (gst_vaapi_coded_buffer_proxy_class ());
|
||||
if (!proxy)
|
||||
return NULL;
|
||||
|
||||
proxy->destroy_func = NULL;
|
||||
proxy->user_data_destroy = NULL;
|
||||
proxy->pool = gst_vaapi_video_pool_ref (GST_VAAPI_VIDEO_POOL (pool));
|
||||
proxy->buffer = gst_vaapi_video_pool_get_object (proxy->pool);
|
||||
if (!proxy->buffer)
|
||||
goto error;
|
||||
gst_mini_object_ref (GST_MINI_OBJECT_CAST (proxy->buffer));
|
||||
return proxy;
|
||||
|
||||
/* ERRORS */
|
||||
error:
|
||||
{
|
||||
gst_vaapi_coded_buffer_proxy_unref (proxy);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_coded_buffer_proxy_ref:
|
||||
* @proxy: a #GstVaapiCodedBufferProxy
|
||||
*
|
||||
* Atomically increases the reference count of the given @proxy by one.
|
||||
*
|
||||
* Returns: The same @proxy argument
|
||||
*/
|
||||
GstVaapiCodedBufferProxy *
|
||||
gst_vaapi_coded_buffer_proxy_ref (GstVaapiCodedBufferProxy * proxy)
|
||||
{
|
||||
g_return_val_if_fail (proxy != NULL, NULL);
|
||||
|
||||
return GST_VAAPI_CODED_BUFFER_PROXY (gst_vaapi_mini_object_ref
|
||||
(GST_VAAPI_MINI_OBJECT (proxy)));
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_coded_buffer_proxy_unref:
|
||||
* @proxy: a #GstVaapiCodedBufferProxy
|
||||
*
|
||||
* Atomically decreases the reference count of the @proxy by one. If
|
||||
* the reference count reaches zero, the object will be free'd.
|
||||
*/
|
||||
void
|
||||
gst_vaapi_coded_buffer_proxy_unref (GstVaapiCodedBufferProxy * proxy)
|
||||
{
|
||||
g_return_if_fail (proxy != NULL);
|
||||
|
||||
gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (proxy));
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_coded_buffer_proxy_replace:
|
||||
* @old_proxy_ptr: a pointer to a #GstVaapiCodedBufferProxy
|
||||
* @new_proxy: a #GstVaapiCodedBufferProxy
|
||||
*
|
||||
* Atomically replaces the proxy object held in @old_proxy_ptr with
|
||||
* @new_proxy. This means that @old_proxy_ptr shall reference a valid
|
||||
* object. However, @new_proxy can be NULL.
|
||||
*/
|
||||
void
|
||||
gst_vaapi_coded_buffer_proxy_replace (GstVaapiCodedBufferProxy ** old_proxy_ptr,
|
||||
GstVaapiCodedBufferProxy * new_proxy)
|
||||
{
|
||||
g_return_if_fail (old_proxy_ptr != NULL);
|
||||
|
||||
gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) old_proxy_ptr,
|
||||
GST_VAAPI_MINI_OBJECT (new_proxy));
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_coded_buffer_proxy_get_buffer:
|
||||
* @proxy: a #GstVaapiCodedBufferProxy
|
||||
*
|
||||
* Returns the #GstVaapiCodedBuffer stored in the @proxy.
|
||||
*
|
||||
* Return value: the #GstVaapiCodedBuffer, or %NULL if an error occurred
|
||||
*/
|
||||
GstVaapiCodedBuffer *
|
||||
gst_vaapi_coded_buffer_proxy_get_buffer (GstVaapiCodedBufferProxy * proxy)
|
||||
{
|
||||
g_return_val_if_fail (proxy != NULL, NULL);
|
||||
|
||||
return GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_coded_buffer_proxy_get_buffer_size:
|
||||
* @proxy: a #GstVaapiCodedBufferProxy
|
||||
*
|
||||
* Returns the size of the underlying #GstVaapiCodedBuffer object
|
||||
* stored in the @proxy.
|
||||
*
|
||||
* Return value: the underlying #GstVaapiCodedBuffer size, or -1 if an
|
||||
* error occurred
|
||||
*/
|
||||
gssize
|
||||
gst_vaapi_coded_buffer_proxy_get_buffer_size (GstVaapiCodedBufferProxy * proxy)
|
||||
{
|
||||
g_return_val_if_fail (proxy != NULL, -1);
|
||||
|
||||
return GST_VAAPI_CODED_BUFFER_PROXY_BUFFER_SIZE (proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_coded_buffer_proxy_set_destroy_notify:
|
||||
* @proxy: a @GstVaapiCodedBufferProxy
|
||||
* @destroy_func: a #GDestroyNotify function
|
||||
* @user_data: some extra data to pass to the @destroy_func function
|
||||
*
|
||||
* Sets @destroy_func as the function to call when the coded buffer
|
||||
* @proxy was released. At this point, the proxy object is considered
|
||||
* released, i.e. the underlying data storage is no longer valid and
|
||||
* the callback function shall not expect anything from that.
|
||||
*/
|
||||
void
|
||||
gst_vaapi_coded_buffer_proxy_set_destroy_notify (GstVaapiCodedBufferProxy *
|
||||
proxy, GDestroyNotify destroy_func, gpointer user_data)
|
||||
{
|
||||
g_return_if_fail (proxy != NULL);
|
||||
|
||||
proxy->destroy_func = destroy_func;
|
||||
proxy->destroy_data = user_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_coded_buffer_proxy_get_user_data:
|
||||
* @proxy: a #GstVaapiCodedBufferProxy
|
||||
*
|
||||
* Gets private data previously set on the VA coded buffer proxy
|
||||
* object through the gst_vaapi_coded_buffer_proxy_set_user_data()
|
||||
* function.
|
||||
*
|
||||
* Return value: the previously set user-data
|
||||
*/
|
||||
gpointer
|
||||
gst_vaapi_coded_buffer_proxy_get_user_data (GstVaapiCodedBufferProxy * proxy)
|
||||
{
|
||||
g_return_val_if_fail (proxy != NULL, NULL);
|
||||
|
||||
return proxy->user_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_coded_buffer_proxy_set_user_data:
|
||||
* @proxy: a #GstVaapiCodedBufferProxy
|
||||
* @user_data: user-defined data
|
||||
* @destroy_func: a #GDestroyNotify
|
||||
*
|
||||
* Sets @user_data on the VA coded buffer proxy object and the
|
||||
* #GDestroyNotify function that will be called when the coded buffer
|
||||
* proxy object is released.
|
||||
*
|
||||
* If a @user_data was previously set, then the previously set
|
||||
* @destroy_func function, if any, will be called before the
|
||||
* @user_data is replaced.
|
||||
*/
|
||||
void
|
||||
gst_vaapi_coded_buffer_proxy_set_user_data (GstVaapiCodedBufferProxy * proxy,
|
||||
gpointer user_data, GDestroyNotify destroy_func)
|
||||
{
|
||||
g_return_if_fail (proxy != NULL);
|
||||
|
||||
coded_buffer_proxy_set_user_data (proxy, user_data, destroy_func);
|
||||
}
|
82
gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h
Normal file
82
gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* gstvaapicodedbufferproxy_priv.h - VA coded buffer proxy
|
||||
*
|
||||
* Copyright (C) 2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_CODED_BUFFER_PROXY_H
|
||||
#define GST_VAAPI_CODED_BUFFER_PROXY_H
|
||||
|
||||
#include <gst/vaapi/gstvaapicodedbuffer.h>
|
||||
#include <gst/vaapi/gstvaapicodedbufferpool.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* GST_VAAPI_CODED_BUFFER_PROXY_BUFFER:
|
||||
* @proxy: a #GstVaapiCodedBufferProxy
|
||||
*
|
||||
* Macro that evaluated to the underlying #GstVaapiCodedBuffer of @proxy.
|
||||
*/
|
||||
#define GST_VAAPI_CODED_BUFFER_PROXY_BUFFER(proxy) \
|
||||
gst_vaapi_coded_buffer_proxy_get_buffer(proxy)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_CODED_BUFFER_PROXY_BUFFER_SIZE:
|
||||
* @proxy: a #GstVaapiCodedBufferProxy
|
||||
*
|
||||
* Macro that evaluated to the underlying #GstVaapiCodedBuffer size of
|
||||
* @proxy.
|
||||
*/
|
||||
#define GST_VAAPI_CODED_BUFFER_PROXY_BUFFER_SIZE(proxy) \
|
||||
gst_vaapi_coded_buffer_proxy_get_buffer_size(proxy)
|
||||
|
||||
GstVaapiCodedBufferProxy *
|
||||
gst_vaapi_coded_buffer_proxy_new_from_pool (GstVaapiCodedBufferPool * pool);
|
||||
|
||||
GstVaapiCodedBufferProxy *
|
||||
gst_vaapi_coded_buffer_proxy_ref (GstVaapiCodedBufferProxy * proxy);
|
||||
|
||||
void
|
||||
gst_vaapi_coded_buffer_proxy_unref (GstVaapiCodedBufferProxy * proxy);
|
||||
|
||||
void
|
||||
gst_vaapi_coded_buffer_proxy_replace (GstVaapiCodedBufferProxy ** old_proxy_ptr,
|
||||
GstVaapiCodedBufferProxy * new_proxy);
|
||||
|
||||
GstVaapiCodedBuffer *
|
||||
gst_vaapi_coded_buffer_proxy_get_buffer (GstVaapiCodedBufferProxy * proxy);
|
||||
|
||||
gssize
|
||||
gst_vaapi_coded_buffer_proxy_get_buffer_size (GstVaapiCodedBufferProxy * proxy);
|
||||
|
||||
void
|
||||
gst_vaapi_coded_buffer_proxy_set_destroy_notify (GstVaapiCodedBufferProxy *
|
||||
proxy, GDestroyNotify destroy_func, gpointer user_data);
|
||||
|
||||
gpointer
|
||||
gst_vaapi_coded_buffer_proxy_get_user_data (GstVaapiCodedBufferProxy * proxy);
|
||||
|
||||
void
|
||||
gst_vaapi_coded_buffer_proxy_set_user_data (GstVaapiCodedBufferProxy * proxy,
|
||||
gpointer user_data, GDestroyNotify destroy_func);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_CODED_BUFFER_PROXY_H */
|
70
gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h
Normal file
70
gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* gstvaapicodedbufferproxy_priv.h - VA coded buffer proxy (private defs)
|
||||
*
|
||||
* Copyright (C) 2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_CODED_BUFFER_PROXY_PRIV_H
|
||||
#define GST_VAAPI_CODED_BUFFER_PROXY_PRIV_H
|
||||
|
||||
#include "gstvaapicodedbuffer_priv.h"
|
||||
#include "gstvaapiminiobject.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_CODED_BUFFER_PROXY(proxy) \
|
||||
((GstVaapiCodedBufferProxy *)(proxy))
|
||||
|
||||
struct _GstVaapiCodedBufferProxy
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiMiniObject parent_instance;
|
||||
|
||||
GstVaapiVideoPool *pool;
|
||||
GstVaapiCodedBuffer *buffer;
|
||||
GDestroyNotify destroy_func;
|
||||
gpointer destroy_data;
|
||||
GDestroyNotify user_data_destroy;
|
||||
gpointer user_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* GST_VAAPI_CODED_BUFFER_PROXY_BUFFER:
|
||||
* @proxy: a #GstVaapiCodedBufferProxy
|
||||
*
|
||||
* Macro that evaluated to the underlying #GstVaapiCodedBuffer of @proxy.
|
||||
*/
|
||||
#undef GST_VAAPI_CODED_BUFFER_PROXY_BUFFER
|
||||
#define GST_VAAPI_CODED_BUFFER_PROXY_BUFFER(proxy) \
|
||||
GST_VAAPI_CODED_BUFFER_PROXY(proxy)->buffer
|
||||
|
||||
/**
|
||||
* GST_VAAPI_CODED_BUFFER_PROXY_BUFFER_SIZE:
|
||||
* @proxy: a #GstVaapiCodedBufferProxy
|
||||
*
|
||||
* Macro that evaluated to the underlying #GstVaapiCodedBuffer size of
|
||||
* @proxy.
|
||||
*/
|
||||
#undef GST_VAAPI_CODED_BUFFER_PROXY_BUFFER_SIZE
|
||||
#define GST_VAAPI_CODED_BUFFER_PROXY_BUFFER_SIZE(proxy) \
|
||||
GST_VAAPI_CODED_BUFFER_SIZE(GST_VAAPI_CODED_BUFFER_PROXY_BUFFER(proxy))
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_CODED_BUFFER_PROXY_PRIV_H */
|
41
gst-libs/gst/vaapi/gstvaapicompat.h
Normal file
41
gst-libs/gst/vaapi/gstvaapicompat.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* gstvapicompat.h - VA-API compatibility glue
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||
* Copyright (C) 2012 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_COMPAT_H
|
||||
#define GST_VAAPI_COMPAT_H
|
||||
|
||||
#include <va/va.h>
|
||||
|
||||
#if VA_CHECK_VERSION(1,0,0)
|
||||
#define VA_ROI_RC_QP_DELTA_SUPPORT(x) x->bits.roi_rc_qp_delta_support
|
||||
#define VA_ENC_PACKED_HEADER_H264_SEI VAEncPackedHeaderRawData
|
||||
#else
|
||||
#define VA_ROI_RC_QP_DELTA_SUPPORT(x) x->bits.roi_rc_qp_delat_support
|
||||
#define VA_ENC_PACKED_HEADER_H264_SEI VAEncPackedHeaderH264_SEI
|
||||
#endif
|
||||
|
||||
#include <va/va_compat.h>
|
||||
#include <va/va_drmcommon.h>
|
||||
|
||||
#endif /* GST_VAAPI_COMPAT_H */
|
788
gst-libs/gst/vaapi/gstvaapicontext.c
Normal file
788
gst-libs/gst/vaapi/gstvaapicontext.c
Normal file
|
@ -0,0 +1,788 @@
|
|||
/*
|
||||
* gstvaapicontext.c - VA context abstraction
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||
* Copyright (C) 2011-2014 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstvaapicontext
|
||||
* @short_description: VA context abstraction
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "gstvaapicompat.h"
|
||||
#include "gstvaapicontext.h"
|
||||
#include "gstvaapidisplay_priv.h"
|
||||
#include "gstvaapisurface_priv.h"
|
||||
#include "gstvaapisurfacepool.h"
|
||||
#include "gstvaapisurfaceproxy.h"
|
||||
#include "gstvaapivideopool_priv.h"
|
||||
#include "gstvaapiutils.h"
|
||||
|
||||
/* Define default VA surface chroma format to YUV 4:2:0 */
|
||||
#define DEFAULT_CHROMA_TYPE (GST_VAAPI_CHROMA_TYPE_YUV420)
|
||||
|
||||
/* Number of scratch surfaces beyond those used as reference */
|
||||
#define SCRATCH_SURFACES_COUNT (4)
|
||||
|
||||
/* Debug category for GstVaapiContext */
|
||||
GST_DEBUG_CATEGORY (gst_debug_vaapi_context);
|
||||
#define GST_CAT_DEFAULT gst_debug_vaapi_context
|
||||
|
||||
static void
|
||||
_init_vaapi_context_debug (void)
|
||||
{
|
||||
#ifndef GST_DISABLE_GST_DEBUG
|
||||
static gsize _init = 0;
|
||||
|
||||
if (g_once_init_enter (&_init)) {
|
||||
GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi_context, "vaapicontext", 0,
|
||||
"VA-API context");
|
||||
g_once_init_leave (&_init, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
_context_is_broken_jpeg_decoder (GstVaapiContext * context)
|
||||
{
|
||||
GstVaapiDisplay *const display = GST_VAAPI_CONTEXT_DISPLAY (context);
|
||||
|
||||
return (context->info.profile == GST_VAAPI_PROFILE_JPEG_BASELINE
|
||||
&& context->info.entrypoint == GST_VAAPI_ENTRYPOINT_VLD
|
||||
&& gst_vaapi_display_has_driver_quirks (display,
|
||||
GST_VAAPI_DRIVER_QUIRK_JPEG_DEC_BROKEN_FORMATS));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_attributes (GstVaapiContext * context)
|
||||
{
|
||||
if (G_LIKELY (context->attribs))
|
||||
return TRUE;
|
||||
|
||||
context->attribs =
|
||||
gst_vaapi_config_surface_attributes_get (GST_VAAPI_CONTEXT_DISPLAY
|
||||
(context), context->va_config);
|
||||
|
||||
if (!context->attribs)
|
||||
return FALSE;
|
||||
|
||||
if (_context_is_broken_jpeg_decoder (context)) {
|
||||
GstVideoFormat fmt = GST_VIDEO_FORMAT_NV12;
|
||||
g_array_prepend_val (context->attribs->formats, fmt);
|
||||
|
||||
context->attribs->mem_types &= ~VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* XXX(victor): verify the preferred video format concords with the
|
||||
* chroma type; otherwise it is changed for the (very arbritrary)
|
||||
* preferred format from the requested context chroma type, in the
|
||||
* context attributes */
|
||||
static void
|
||||
ensure_preferred_format (GstVaapiContext * context)
|
||||
{
|
||||
const GstVaapiContextInfo *const cip = &context->info;
|
||||
GArray *formats;
|
||||
guint i;
|
||||
|
||||
if (context->preferred_format != GST_VIDEO_FORMAT_UNKNOWN)
|
||||
return;
|
||||
|
||||
if (_context_is_broken_jpeg_decoder (context))
|
||||
return;
|
||||
|
||||
if (!ensure_attributes (context) || !context->attribs->formats)
|
||||
return;
|
||||
|
||||
formats = context->attribs->formats;
|
||||
for (i = 0; i < formats->len; i++) {
|
||||
GstVideoFormat format = g_array_index (formats, GstVideoFormat, i);
|
||||
if (format == gst_vaapi_video_format_from_chroma (cip->chroma_type)) {
|
||||
context->preferred_format = format;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
context_get_attribute (GstVaapiContext * context, VAConfigAttribType type,
|
||||
guint * out_value_ptr)
|
||||
{
|
||||
return gst_vaapi_get_config_attribute (GST_VAAPI_CONTEXT_DISPLAY (context),
|
||||
context->va_profile, context->va_entrypoint, type, out_value_ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
context_destroy_surfaces (GstVaapiContext * context)
|
||||
{
|
||||
if (context->surfaces) {
|
||||
g_ptr_array_unref (context->surfaces);
|
||||
context->surfaces = NULL;
|
||||
}
|
||||
|
||||
context->preferred_format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
|
||||
gst_vaapi_video_pool_replace (&context->surfaces_pool, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
context_destroy (GstVaapiContext * context)
|
||||
{
|
||||
GstVaapiDisplay *const display = GST_VAAPI_CONTEXT_DISPLAY (context);
|
||||
VAContextID context_id;
|
||||
VAStatus status;
|
||||
|
||||
context_id = GST_VAAPI_CONTEXT_ID (context);
|
||||
GST_DEBUG ("context 0x%08x / config 0x%08x", context_id, context->va_config);
|
||||
|
||||
if (context_id != VA_INVALID_ID) {
|
||||
GST_VAAPI_DISPLAY_LOCK (display);
|
||||
status = vaDestroyContext (GST_VAAPI_DISPLAY_VADISPLAY (display),
|
||||
context_id);
|
||||
GST_VAAPI_DISPLAY_UNLOCK (display);
|
||||
if (!vaapi_check_status (status, "vaDestroyContext()"))
|
||||
GST_WARNING ("failed to destroy context 0x%08x", context_id);
|
||||
GST_VAAPI_CONTEXT_ID (context) = VA_INVALID_ID;
|
||||
}
|
||||
|
||||
if (context->va_config != VA_INVALID_ID) {
|
||||
GST_VAAPI_DISPLAY_LOCK (display);
|
||||
status = vaDestroyConfig (GST_VAAPI_DISPLAY_VADISPLAY (display),
|
||||
context->va_config);
|
||||
GST_VAAPI_DISPLAY_UNLOCK (display);
|
||||
if (!vaapi_check_status (status, "vaDestroyConfig()"))
|
||||
GST_WARNING ("failed to destroy config 0x%08x", context->va_config);
|
||||
context->va_config = VA_INVALID_ID;
|
||||
}
|
||||
|
||||
if (context->attribs) {
|
||||
gst_vaapi_config_surface_attributes_free (context->attribs);
|
||||
context->attribs = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
context_ensure_surfaces (GstVaapiContext * context)
|
||||
{
|
||||
GstVaapiDisplay *display = GST_VAAPI_CONTEXT_DISPLAY (context);
|
||||
const GstVaapiContextInfo *const cip = &context->info;
|
||||
const guint num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT;
|
||||
GstVaapiSurface *surface;
|
||||
GstVideoFormat format;
|
||||
guint i, capacity;
|
||||
|
||||
ensure_preferred_format (context);
|
||||
format = context->preferred_format;
|
||||
for (i = context->surfaces->len; i < num_surfaces; i++) {
|
||||
if (format != GST_VIDEO_FORMAT_UNKNOWN) {
|
||||
surface = gst_vaapi_surface_new_with_format (display, format, cip->width,
|
||||
cip->height, 0);
|
||||
} else {
|
||||
surface = gst_vaapi_surface_new (display, cip->chroma_type, cip->width,
|
||||
cip->height);
|
||||
}
|
||||
if (!surface)
|
||||
return FALSE;
|
||||
g_ptr_array_add (context->surfaces, surface);
|
||||
if (!gst_vaapi_video_pool_add_object (context->surfaces_pool, surface))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
capacity = cip->usage == GST_VAAPI_CONTEXT_USAGE_DECODE ? 0 : num_surfaces;
|
||||
gst_vaapi_video_pool_set_capacity (context->surfaces_pool, capacity);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
context_create_surfaces (GstVaapiContext * context)
|
||||
{
|
||||
const GstVaapiContextInfo *const cip = &context->info;
|
||||
GstVaapiDisplay *const display = GST_VAAPI_CONTEXT_DISPLAY (context);
|
||||
guint num_surfaces;
|
||||
|
||||
num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT;
|
||||
if (!context->surfaces) {
|
||||
context->surfaces = g_ptr_array_new_full (num_surfaces,
|
||||
(GDestroyNotify) gst_mini_object_unref);
|
||||
if (!context->surfaces)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!context->surfaces_pool) {
|
||||
context->surfaces_pool =
|
||||
gst_vaapi_surface_pool_new_with_chroma_type (display, cip->chroma_type,
|
||||
cip->width, cip->height, 0);
|
||||
|
||||
if (!context->surfaces_pool)
|
||||
return FALSE;
|
||||
}
|
||||
return context_ensure_surfaces (context);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
context_create (GstVaapiContext * context)
|
||||
{
|
||||
const GstVaapiContextInfo *const cip = &context->info;
|
||||
GstVaapiDisplay *const display = GST_VAAPI_CONTEXT_DISPLAY (context);
|
||||
VAContextID context_id;
|
||||
VASurfaceID surface_id;
|
||||
VASurfaceID *surfaces_data = NULL;
|
||||
VAStatus status;
|
||||
GArray *surfaces = NULL;
|
||||
gboolean success = FALSE;
|
||||
guint i;
|
||||
gint num_surfaces = 0;
|
||||
|
||||
if (!context->surfaces && !context_create_surfaces (context))
|
||||
goto cleanup;
|
||||
|
||||
/* Create VA surfaces list for vaCreateContext() */
|
||||
surfaces = g_array_sized_new (FALSE,
|
||||
FALSE, sizeof (VASurfaceID), context->surfaces->len);
|
||||
if (!surfaces)
|
||||
goto cleanup;
|
||||
|
||||
for (i = 0; i < context->surfaces->len; i++) {
|
||||
GstVaapiSurface *const surface = g_ptr_array_index (context->surfaces, i);
|
||||
if (!surface)
|
||||
goto cleanup;
|
||||
surface_id = GST_VAAPI_SURFACE_ID (surface);
|
||||
g_array_append_val (surfaces, surface_id);
|
||||
}
|
||||
|
||||
g_assert (surfaces->len == context->surfaces->len);
|
||||
|
||||
/* vaCreateContext() doesn't really need an array of VASurfaceIDs (see
|
||||
* https://lists.01.org/pipermail/intel-vaapi-media/2017-July/000052.html and
|
||||
* https://github.com/intel/libva/issues/251); pass a dummy list of valid
|
||||
* (non-null) IDs until the signature gets updated. */
|
||||
if (cip->usage != GST_VAAPI_CONTEXT_USAGE_DECODE) {
|
||||
surfaces_data = (VASurfaceID *) surfaces->data;
|
||||
num_surfaces = surfaces->len;
|
||||
}
|
||||
|
||||
GST_VAAPI_DISPLAY_LOCK (display);
|
||||
status = vaCreateContext (GST_VAAPI_DISPLAY_VADISPLAY (display),
|
||||
context->va_config, cip->width, cip->height, VA_PROGRESSIVE,
|
||||
surfaces_data, num_surfaces, &context_id);
|
||||
GST_VAAPI_DISPLAY_UNLOCK (display);
|
||||
if (!vaapi_check_status (status, "vaCreateContext()"))
|
||||
goto cleanup;
|
||||
|
||||
GST_VAAPI_CONTEXT_ID (context) = context_id;
|
||||
success = TRUE;
|
||||
|
||||
cleanup:
|
||||
if (surfaces)
|
||||
g_array_unref (surfaces);
|
||||
return success;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
config_create (GstVaapiContext * context)
|
||||
{
|
||||
const GstVaapiContextInfo *const cip = &context->info;
|
||||
GstVaapiDisplay *const display = GST_VAAPI_CONTEXT_DISPLAY (context);
|
||||
VAConfigAttrib attribs[7], *attrib;
|
||||
VAStatus status;
|
||||
guint value, va_chroma_format, attrib_index;
|
||||
|
||||
/* Reset profile and entrypoint */
|
||||
if (cip->profile == GST_VAAPI_PROFILE_UNKNOWN
|
||||
|| cip->entrypoint == GST_VAAPI_ENTRYPOINT_INVALID)
|
||||
goto cleanup;
|
||||
context->va_profile = gst_vaapi_profile_get_va_profile (cip->profile);
|
||||
context->va_entrypoint =
|
||||
gst_vaapi_entrypoint_get_va_entrypoint (cip->entrypoint);
|
||||
|
||||
attrib_index = 0;
|
||||
attrib = &attribs[attrib_index];
|
||||
g_assert (attrib_index < G_N_ELEMENTS (attribs));
|
||||
|
||||
/* Validate VA surface format */
|
||||
va_chroma_format = from_GstVaapiChromaType (cip->chroma_type);
|
||||
if (!va_chroma_format)
|
||||
goto cleanup;
|
||||
attrib->type = VAConfigAttribRTFormat;
|
||||
if (!context_get_attribute (context, attrib->type, &value))
|
||||
goto cleanup;
|
||||
if (!(value & va_chroma_format)) {
|
||||
GST_ERROR ("unsupported chroma format (%s)",
|
||||
string_of_va_chroma_format (va_chroma_format));
|
||||
goto cleanup;
|
||||
}
|
||||
attrib->value = va_chroma_format;
|
||||
attrib = &attribs[++attrib_index];
|
||||
g_assert (attrib_index < G_N_ELEMENTS (attribs));
|
||||
|
||||
switch (cip->usage) {
|
||||
#if USE_ENCODERS
|
||||
case GST_VAAPI_CONTEXT_USAGE_ENCODE:
|
||||
{
|
||||
const GstVaapiConfigInfoEncoder *const config = &cip->config.encoder;
|
||||
guint va_rate_control;
|
||||
|
||||
/* Rate control */
|
||||
va_rate_control = from_GstVaapiRateControl (config->rc_mode);
|
||||
if (va_rate_control != VA_RC_NONE) {
|
||||
attrib->type = VAConfigAttribRateControl;
|
||||
if (!context_get_attribute (context, attrib->type, &value))
|
||||
goto cleanup;
|
||||
|
||||
if ((value & va_rate_control) != va_rate_control) {
|
||||
GST_ERROR ("unsupported %s rate control",
|
||||
string_of_VARateControl (va_rate_control));
|
||||
goto cleanup;
|
||||
}
|
||||
attrib->value = va_rate_control;
|
||||
attrib = &attribs[++attrib_index];
|
||||
g_assert (attrib_index < G_N_ELEMENTS (attribs));
|
||||
}
|
||||
/* Packed headers */
|
||||
if (config->packed_headers) {
|
||||
attrib->type = VAConfigAttribEncPackedHeaders;
|
||||
if (!context_get_attribute (context, attrib->type, &value))
|
||||
goto cleanup;
|
||||
|
||||
if ((value & config->packed_headers) != config->packed_headers) {
|
||||
GST_ERROR ("unsupported packed headers 0x%08x",
|
||||
config->packed_headers & ~(value & config->packed_headers));
|
||||
goto cleanup;
|
||||
}
|
||||
attrib->value = config->packed_headers;
|
||||
attrib = &attribs[++attrib_index];
|
||||
g_assert (attrib_index < G_N_ELEMENTS (attribs));
|
||||
}
|
||||
if (cip->profile == GST_VAAPI_PROFILE_JPEG_BASELINE) {
|
||||
attrib->type = VAConfigAttribEncJPEG;
|
||||
if (!context_get_attribute (context, attrib->type, &value))
|
||||
goto cleanup;
|
||||
attrib->value = value;
|
||||
attrib = &attribs[++attrib_index];
|
||||
g_assert (attrib_index < G_N_ELEMENTS (attribs));
|
||||
}
|
||||
#if VA_CHECK_VERSION(0,39,1)
|
||||
if (config->roi_capability) {
|
||||
VAConfigAttribValEncROI *roi_config;
|
||||
|
||||
attrib->type = VAConfigAttribEncROI;
|
||||
if (!context_get_attribute (context, attrib->type, &value))
|
||||
goto cleanup;
|
||||
roi_config = (VAConfigAttribValEncROI *) & value;
|
||||
if (roi_config->bits.num_roi_regions != config->roi_num_supported) {
|
||||
GST_ERROR ("Mismatched ROI support: number of regions supported: %d",
|
||||
roi_config->bits.num_roi_regions);
|
||||
goto cleanup;
|
||||
}
|
||||
if (config->rc_mode != GST_VAAPI_RATECONTROL_CQP
|
||||
&& VA_ROI_RC_QP_DELTA_SUPPORT (roi_config) == 0) {
|
||||
GST_ERROR ("Mismatched ROI support: ROI delta QP: %d",
|
||||
VA_ROI_RC_QP_DELTA_SUPPORT (roi_config));
|
||||
goto cleanup;
|
||||
}
|
||||
attrib->value = value;
|
||||
attrib = &attribs[++attrib_index];
|
||||
g_assert (attrib_index < G_N_ELEMENTS (attribs));
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
GST_VAAPI_DISPLAY_LOCK (display);
|
||||
status = vaCreateConfig (GST_VAAPI_DISPLAY_VADISPLAY (display),
|
||||
context->va_profile, context->va_entrypoint, attribs, attrib_index,
|
||||
&context->va_config);
|
||||
GST_VAAPI_DISPLAY_UNLOCK (display);
|
||||
if (!vaapi_check_status (status, "vaCreateConfig()"))
|
||||
goto cleanup;
|
||||
|
||||
return TRUE;
|
||||
cleanup:
|
||||
GST_WARNING ("Failed to create vaConfig");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/** Updates config for encoding. Returns %TRUE if config changed */
|
||||
static gboolean
|
||||
context_update_config_encoder (GstVaapiContext * context,
|
||||
const GstVaapiConfigInfoEncoder * new_config)
|
||||
{
|
||||
GstVaapiConfigInfoEncoder *const config = &context->info.config.encoder;
|
||||
gboolean config_changed = FALSE;
|
||||
|
||||
g_assert (context->info.usage == GST_VAAPI_CONTEXT_USAGE_ENCODE);
|
||||
|
||||
if (config->rc_mode != new_config->rc_mode) {
|
||||
config->rc_mode = new_config->rc_mode;
|
||||
config_changed = TRUE;
|
||||
}
|
||||
|
||||
if (config->packed_headers != new_config->packed_headers) {
|
||||
config->packed_headers = new_config->packed_headers;
|
||||
config_changed = TRUE;
|
||||
}
|
||||
|
||||
if (config->roi_capability != new_config->roi_capability ||
|
||||
config->roi_num_supported != new_config->roi_num_supported) {
|
||||
config->roi_capability = new_config->roi_capability;
|
||||
config->roi_num_supported = new_config->roi_num_supported;
|
||||
config_changed = TRUE;
|
||||
}
|
||||
|
||||
return config_changed;
|
||||
}
|
||||
|
||||
static inline void
|
||||
gst_vaapi_context_init (GstVaapiContext * context,
|
||||
const GstVaapiContextInfo * new_cip)
|
||||
{
|
||||
GstVaapiContextInfo *const cip = &context->info;
|
||||
|
||||
*cip = *new_cip;
|
||||
if (!cip->chroma_type)
|
||||
cip->chroma_type = DEFAULT_CHROMA_TYPE;
|
||||
|
||||
context->va_config = VA_INVALID_ID;
|
||||
context->reset_on_resize = TRUE;
|
||||
|
||||
context->attribs = NULL;
|
||||
context->preferred_format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_new:
|
||||
* @display: a #GstVaapiDisplay
|
||||
* @cip: a pointer to the #GstVaapiContextInfo
|
||||
*
|
||||
* Creates a new #GstVaapiContext with the configuration specified by
|
||||
* @cip, thus including profile, entry-point, encoded size and maximum
|
||||
* number of reference frames reported by the bitstream.
|
||||
*
|
||||
* Return value: the newly allocated #GstVaapiContext object
|
||||
*/
|
||||
GstVaapiContext *
|
||||
gst_vaapi_context_new (GstVaapiDisplay * display,
|
||||
const GstVaapiContextInfo * cip)
|
||||
{
|
||||
GstVaapiContext *context;
|
||||
|
||||
g_return_val_if_fail (display, NULL);
|
||||
|
||||
_init_vaapi_context_debug ();
|
||||
|
||||
if (cip->profile == GST_VAAPI_PROFILE_UNKNOWN
|
||||
|| cip->entrypoint == GST_VAAPI_ENTRYPOINT_INVALID)
|
||||
return NULL;
|
||||
|
||||
context = g_slice_new (GstVaapiContext);
|
||||
if (!context)
|
||||
return NULL;
|
||||
|
||||
GST_VAAPI_CONTEXT_DISPLAY (context) = gst_object_ref (display);
|
||||
GST_VAAPI_CONTEXT_ID (context) = VA_INVALID_ID;
|
||||
g_atomic_int_set (&context->ref_count, 1);
|
||||
context->surfaces = NULL;
|
||||
context->surfaces_pool = NULL;
|
||||
|
||||
gst_vaapi_context_init (context, cip);
|
||||
|
||||
if (!config_create (context))
|
||||
goto error;
|
||||
|
||||
/* this means we don't want to create a VAcontext */
|
||||
if (cip->width == 0 && cip->height == 0)
|
||||
goto done;
|
||||
|
||||
/* this is not valid */
|
||||
if (cip->width == 0 || cip->height == 0)
|
||||
goto error;
|
||||
|
||||
if (!context_create (context))
|
||||
goto error;
|
||||
|
||||
done:
|
||||
GST_DEBUG ("context 0x%08" G_GSIZE_MODIFIER "x / config 0x%08x",
|
||||
GST_VAAPI_CONTEXT_ID (context), context->va_config);
|
||||
return context;
|
||||
|
||||
/* ERRORS */
|
||||
error:
|
||||
{
|
||||
gst_vaapi_context_unref (context);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_reset:
|
||||
* @context: a #GstVaapiContext
|
||||
* @new_cip: a pointer to the new #GstVaapiContextInfo details
|
||||
*
|
||||
* Resets @context to the configuration specified by @new_cip, thus
|
||||
* including profile, entry-point, encoded size and maximum number of
|
||||
* reference frames reported by the bitstream.
|
||||
*
|
||||
* Return value: %TRUE on success
|
||||
*/
|
||||
gboolean
|
||||
gst_vaapi_context_reset (GstVaapiContext * context,
|
||||
const GstVaapiContextInfo * new_cip)
|
||||
{
|
||||
GstVaapiContextInfo *const cip = &context->info;
|
||||
gboolean reset_surfaces = FALSE, reset_config = FALSE;
|
||||
gboolean grow_surfaces = FALSE;
|
||||
GstVaapiChromaType chroma_type;
|
||||
|
||||
if (new_cip->profile == GST_VAAPI_PROFILE_UNKNOWN
|
||||
|| new_cip->entrypoint == GST_VAAPI_ENTRYPOINT_INVALID)
|
||||
return FALSE;
|
||||
|
||||
chroma_type = new_cip->chroma_type ? new_cip->chroma_type :
|
||||
DEFAULT_CHROMA_TYPE;
|
||||
if (cip->chroma_type != chroma_type) {
|
||||
cip->chroma_type = chroma_type;
|
||||
reset_surfaces = TRUE;
|
||||
}
|
||||
|
||||
if (cip->width != new_cip->width || cip->height != new_cip->height) {
|
||||
cip->width = new_cip->width;
|
||||
cip->height = new_cip->height;
|
||||
reset_surfaces = TRUE;
|
||||
}
|
||||
|
||||
if (cip->profile != new_cip->profile ||
|
||||
cip->entrypoint != new_cip->entrypoint) {
|
||||
cip->profile = new_cip->profile;
|
||||
cip->entrypoint = new_cip->entrypoint;
|
||||
reset_config = TRUE;
|
||||
}
|
||||
|
||||
if (cip->ref_frames < new_cip->ref_frames) {
|
||||
cip->ref_frames = new_cip->ref_frames;
|
||||
grow_surfaces = TRUE;
|
||||
}
|
||||
|
||||
if (cip->usage != new_cip->usage) {
|
||||
cip->usage = new_cip->usage;
|
||||
reset_config = TRUE;
|
||||
memcpy (&cip->config, &new_cip->config, sizeof (cip->config));
|
||||
} else if (new_cip->usage == GST_VAAPI_CONTEXT_USAGE_ENCODE) {
|
||||
if (context_update_config_encoder (context, &new_cip->config.encoder))
|
||||
reset_config = TRUE;
|
||||
} else if (new_cip->usage == GST_VAAPI_CONTEXT_USAGE_DECODE) {
|
||||
if ((reset_surfaces && context->reset_on_resize) || grow_surfaces)
|
||||
reset_config = TRUE;
|
||||
}
|
||||
|
||||
if (reset_surfaces)
|
||||
context_destroy_surfaces (context);
|
||||
if (reset_config)
|
||||
context_destroy (context);
|
||||
|
||||
if (reset_config && !(config_create (context) && context_create (context)))
|
||||
return FALSE;
|
||||
if (reset_surfaces && !context_create_surfaces (context))
|
||||
return FALSE;
|
||||
else if (grow_surfaces && !context_ensure_surfaces (context))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_get_id:
|
||||
* @context: a #GstVaapiContext
|
||||
*
|
||||
* Returns the underlying VAContextID of the @context.
|
||||
*
|
||||
* Return value: the underlying VA context id
|
||||
*/
|
||||
GstVaapiID
|
||||
gst_vaapi_context_get_id (GstVaapiContext * context)
|
||||
{
|
||||
g_return_val_if_fail (context != NULL, VA_INVALID_ID);
|
||||
|
||||
return GST_VAAPI_CONTEXT_ID (context);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_get_surface_proxy:
|
||||
* @context: a #GstVaapiContext
|
||||
*
|
||||
* Acquires a free surface, wrapped into a #GstVaapiSurfaceProxy. The
|
||||
* returned surface will be automatically released when the proxy is
|
||||
* destroyed. So, it is enough to call gst_vaapi_surface_proxy_unref()
|
||||
* after usage.
|
||||
*
|
||||
* This function returns %NULL if there is no free surface available
|
||||
* in the pool. The surfaces are pre-allocated during context creation
|
||||
* though.
|
||||
*
|
||||
* Return value: a free surface, or %NULL if none is available
|
||||
*/
|
||||
GstVaapiSurfaceProxy *
|
||||
gst_vaapi_context_get_surface_proxy (GstVaapiContext * context)
|
||||
{
|
||||
g_return_val_if_fail (context != NULL, NULL);
|
||||
|
||||
return
|
||||
gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL
|
||||
(context->surfaces_pool));
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_get_surface_count:
|
||||
* @context: a #GstVaapiContext
|
||||
*
|
||||
* Retrieves the number of free surfaces left in the pool.
|
||||
*
|
||||
* Return value: the number of free surfaces available in the pool
|
||||
*/
|
||||
guint
|
||||
gst_vaapi_context_get_surface_count (GstVaapiContext * context)
|
||||
{
|
||||
g_return_val_if_fail (context != NULL, 0);
|
||||
|
||||
if (gst_vaapi_video_pool_get_capacity (context->surfaces_pool) == 0)
|
||||
return G_MAXUINT;
|
||||
return gst_vaapi_video_pool_get_size (context->surfaces_pool);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_reset_on_resize:
|
||||
* @context: a #GstVaapiContext
|
||||
* @reset_on_resize: Should the context be reset on size change
|
||||
*
|
||||
* Sets whether the underlying context should be reset when a size change
|
||||
* happens. The proper setting for this is codec dependent.
|
||||
*/
|
||||
void
|
||||
gst_vaapi_context_reset_on_resize (GstVaapiContext * context,
|
||||
gboolean reset_on_resize)
|
||||
{
|
||||
g_return_if_fail (context != NULL);
|
||||
|
||||
context->reset_on_resize = reset_on_resize;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_get_surface_formats:
|
||||
* @context: a #GstVaapiContext
|
||||
*
|
||||
* Determines the set of supported formats by the surfaces associated
|
||||
* to @context. The caller owns an extra reference of the resulting
|
||||
* array of #GstVideoFormat elements, so it shall be released with
|
||||
* g_array_unref after usage.
|
||||
*
|
||||
* Return value: (transfer full): the set of target formats supported
|
||||
* by the surfaces in @context.
|
||||
*/
|
||||
GArray *
|
||||
gst_vaapi_context_get_surface_formats (GstVaapiContext * context)
|
||||
{
|
||||
g_return_val_if_fail (context, NULL);
|
||||
|
||||
if (!ensure_attributes (context))
|
||||
return NULL;
|
||||
|
||||
if (context->attribs->formats)
|
||||
return g_array_ref (context->attribs->formats);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_get_surface_attributes:
|
||||
* @context: a #GstVaapiContext
|
||||
* @out_attribs: an allocated #GstVaapiConfigSurfaceAttributes
|
||||
*
|
||||
* Copy context's surface restrictions to @out_attribs, EXCEPT the
|
||||
* color formats. Use gst_vaapi_context_get_surface_formats() to get
|
||||
* them.
|
||||
*
|
||||
* Returns: %TRUE if the attributes were extracted and copied; %FALSE,
|
||||
* otherwise
|
||||
**/
|
||||
gboolean
|
||||
gst_vaapi_context_get_surface_attributes (GstVaapiContext * context,
|
||||
GstVaapiConfigSurfaceAttributes * out_attribs)
|
||||
{
|
||||
g_return_val_if_fail (context, FALSE);
|
||||
|
||||
if (!ensure_attributes (context))
|
||||
return FALSE;
|
||||
|
||||
if (out_attribs) {
|
||||
out_attribs->min_width = context->attribs->min_width;
|
||||
out_attribs->min_height = context->attribs->min_height;
|
||||
out_attribs->max_width = context->attribs->max_width;
|
||||
out_attribs->max_height = context->attribs->max_height;
|
||||
out_attribs->mem_types = context->attribs->mem_types;
|
||||
out_attribs->formats = NULL;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_ref:
|
||||
* @context: a #GstVaapiContext
|
||||
*
|
||||
* Atomically increases the reference count of the given @context by one.
|
||||
*
|
||||
* Returns: The same @context argument
|
||||
*/
|
||||
GstVaapiContext *
|
||||
gst_vaapi_context_ref (GstVaapiContext * context)
|
||||
{
|
||||
g_return_val_if_fail (context != NULL, NULL);
|
||||
|
||||
g_atomic_int_inc (&context->ref_count);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_unref:
|
||||
* @context: a #GstVaapiContext
|
||||
*
|
||||
* Atomically decreases the reference count of the @context by one. If
|
||||
* the reference count reaches zero, the object will be free'd.
|
||||
*/
|
||||
void
|
||||
gst_vaapi_context_unref (GstVaapiContext * context)
|
||||
{
|
||||
g_return_if_fail (context != NULL);
|
||||
g_return_if_fail (context->ref_count > 0);
|
||||
|
||||
if (g_atomic_int_dec_and_test (&context->ref_count)) {
|
||||
context_destroy (context);
|
||||
context_destroy_surfaces (context);
|
||||
gst_vaapi_display_replace (&context->display, NULL);
|
||||
g_slice_free (GstVaapiContext, context);
|
||||
}
|
||||
}
|
170
gst-libs/gst/vaapi/gstvaapicontext.h
Normal file
170
gst-libs/gst/vaapi/gstvaapicontext.h
Normal file
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* gstvaapicontext.h - VA context abstraction (private)
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||
* Copyright (C) 2011-2014 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_CONTEXT_H
|
||||
#define GST_VAAPI_CONTEXT_H
|
||||
|
||||
#include "gstvaapiprofile.h"
|
||||
#include "gstvaapidisplay.h"
|
||||
#include "gstvaapisurface.h"
|
||||
#include "gstvaapiutils_core.h"
|
||||
#include "gstvaapivideopool.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_CONTEXT(obj) \
|
||||
((GstVaapiContext *) (obj))
|
||||
|
||||
typedef struct _GstVaapiConfigInfoEncoder GstVaapiConfigInfoEncoder;
|
||||
typedef struct _GstVaapiContextInfo GstVaapiContextInfo;
|
||||
typedef struct _GstVaapiContext GstVaapiContext;
|
||||
|
||||
/**
|
||||
* GstVaapiContextUsage:
|
||||
* @GST_VAAPI_CONTEXT_MODE_DECODE: context used for decoding.
|
||||
* @GST_VAAPI_CONTEXT_MODE_ENCODE: context used for encoding.
|
||||
* @GST_VAAPI_CONTEXT_MODE_VPP: context used for video processing.
|
||||
*
|
||||
* The set of supported VA context usages.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VAAPI_CONTEXT_USAGE_DECODE = 1,
|
||||
GST_VAAPI_CONTEXT_USAGE_ENCODE,
|
||||
GST_VAAPI_CONTEXT_USAGE_VPP,
|
||||
} GstVaapiContextUsage;
|
||||
|
||||
/**
|
||||
* GstVaapiConfigInfoEncoder:
|
||||
* @rc_mode: rate-control mode (#GstVaapiRateControl).
|
||||
* @packed_headers: notify encoder that packed headers are submitted (mask).
|
||||
* @roi_capability: if encoder supports regions-of-interest.
|
||||
* @roi_num_supported: The number of regions-of-interest supported.
|
||||
*
|
||||
* Extra configuration for encoding.
|
||||
*/
|
||||
struct _GstVaapiConfigInfoEncoder
|
||||
{
|
||||
GstVaapiRateControl rc_mode;
|
||||
guint packed_headers;
|
||||
gboolean roi_capability;
|
||||
guint roi_num_supported;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiContextInfo:
|
||||
*
|
||||
* Structure holding VA context info like encoded size, decoder
|
||||
* profile and entry-point to use, and maximum number of reference
|
||||
* frames reported by the bitstream.
|
||||
*/
|
||||
struct _GstVaapiContextInfo
|
||||
{
|
||||
GstVaapiContextUsage usage;
|
||||
GstVaapiProfile profile;
|
||||
GstVaapiEntrypoint entrypoint;
|
||||
GstVaapiChromaType chroma_type;
|
||||
guint width;
|
||||
guint height;
|
||||
guint ref_frames;
|
||||
union _GstVaapiConfigInfo {
|
||||
GstVaapiConfigInfoEncoder encoder;
|
||||
} config;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiContext:
|
||||
*
|
||||
* A VA context wrapper.
|
||||
*/
|
||||
struct _GstVaapiContext
|
||||
{
|
||||
/*< private >*/
|
||||
gint ref_count;
|
||||
GstVaapiDisplay *display;
|
||||
GstVaapiID object_id;
|
||||
|
||||
/*< public >*/
|
||||
GstVaapiContextInfo info;
|
||||
VAProfile va_profile;
|
||||
VAEntrypoint va_entrypoint;
|
||||
VAConfigID va_config;
|
||||
GPtrArray *surfaces;
|
||||
GstVaapiVideoPool *surfaces_pool;
|
||||
gboolean reset_on_resize;
|
||||
GstVaapiConfigSurfaceAttributes *attribs;
|
||||
GstVideoFormat preferred_format;
|
||||
};
|
||||
|
||||
#define GST_VAAPI_CONTEXT_ID(context) (((GstVaapiContext *)(context))->object_id)
|
||||
#define GST_VAAPI_CONTEXT_DISPLAY(context) (((GstVaapiContext *)(context))->display)
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiContext *
|
||||
gst_vaapi_context_new (GstVaapiDisplay * display,
|
||||
const GstVaapiContextInfo * cip);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_context_reset (GstVaapiContext * context,
|
||||
const GstVaapiContextInfo * new_cip);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiID
|
||||
gst_vaapi_context_get_id (GstVaapiContext * context);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiSurfaceProxy *
|
||||
gst_vaapi_context_get_surface_proxy (GstVaapiContext * context);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
guint
|
||||
gst_vaapi_context_get_surface_count (GstVaapiContext * context);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_context_reset_on_resize (GstVaapiContext * context,
|
||||
gboolean reset_on_resize);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GArray *
|
||||
gst_vaapi_context_get_surface_formats (GstVaapiContext * context);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_context_get_surface_attributes (GstVaapiContext * context,
|
||||
GstVaapiConfigSurfaceAttributes * out_attribs);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiContext *
|
||||
gst_vaapi_context_ref (GstVaapiContext * context);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_context_unref (GstVaapiContext * context);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiContext, gst_vaapi_context_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_CONTEXT_H */
|
38
gst-libs/gst/vaapi/gstvaapidebug.h
Normal file
38
gst-libs/gst/vaapi/gstvaapidebug.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* gstvaapidebug.h - VA-API debugging utilities
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DEBUG_H
|
||||
#define GST_VAAPI_DEBUG_H
|
||||
|
||||
#include <gst/gstinfo.h>
|
||||
|
||||
#if DEBUG
|
||||
GST_DEBUG_CATEGORY_EXTERN(gst_debug_vaapi);
|
||||
#define GST_CAT_DEFAULT gst_debug_vaapi
|
||||
#endif
|
||||
|
||||
#if DEBUG_VAAPI_DISPLAY
|
||||
GST_DEBUG_CATEGORY_EXTERN(gst_debug_vaapi_display);
|
||||
#define GST_CAT_DEFAULT gst_debug_vaapi_display
|
||||
#endif
|
||||
|
||||
#endif /* GST_VAAPI_DEBUG_H */
|
1213
gst-libs/gst/vaapi/gstvaapidecoder.c
Normal file
1213
gst-libs/gst/vaapi/gstvaapidecoder.c
Normal file
File diff suppressed because it is too large
Load diff
148
gst-libs/gst/vaapi/gstvaapidecoder.h
Normal file
148
gst-libs/gst/vaapi/gstvaapidecoder.h
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* gstvaapidecoder.h - VA decoder abstraction
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||
* Copyright (C) 2011-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DECODER_H
|
||||
#define GST_VAAPI_DECODER_H
|
||||
|
||||
#include <gst/gstbuffer.h>
|
||||
#include <gst/base/gstadapter.h>
|
||||
#include <gst/vaapi/gstvaapisurfaceproxy.h>
|
||||
#include <gst/video/gstvideoutils.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_DECODER \
|
||||
(gst_vaapi_decoder_get_type ())
|
||||
#define GST_VAAPI_DECODER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DECODER, GstVaapiDecoder))
|
||||
#define GST_VAAPI_IS_DECODER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_DECODER))
|
||||
|
||||
typedef struct _GstVaapiDecoder GstVaapiDecoder;
|
||||
typedef void (*GstVaapiDecoderStateChangedFunc) (GstVaapiDecoder * decoder,
|
||||
const GstVideoCodecState * codec_state, gpointer user_data);
|
||||
|
||||
/**
|
||||
* GstVaapiDecoderStatus:
|
||||
* @GST_VAAPI_DECODER_STATUS_SUCCESS: Success.
|
||||
* @GST_VAAPI_DECODER_STATUS_END_OF_STREAM: End-Of-Stream.
|
||||
* @GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED: No memory left.
|
||||
* @GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED: Decoder initialization failure.
|
||||
* @GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC: Unsupported codec.
|
||||
* @GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: Not enough input data to decode.
|
||||
* @GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE: No surface left to hold the decoded picture.
|
||||
* @GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE: Invalid surface.
|
||||
* @GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER: Invalid or unsupported bitstream data.
|
||||
* @GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE: Unsupported codec profile.
|
||||
* @GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT: Unsupported chroma format.
|
||||
* @GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER: Unsupported parameter.
|
||||
* @GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN: Unknown error.
|
||||
*
|
||||
* Decoder status for gst_vaapi_decoder_get_surface().
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VAAPI_DECODER_STATUS_SUCCESS = 0,
|
||||
GST_VAAPI_DECODER_STATUS_END_OF_STREAM,
|
||||
GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED,
|
||||
GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED,
|
||||
GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC,
|
||||
GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA,
|
||||
GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE,
|
||||
GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE,
|
||||
GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER,
|
||||
GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE,
|
||||
GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT,
|
||||
GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER,
|
||||
GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN = -1
|
||||
} GstVaapiDecoderStatus;
|
||||
|
||||
GType
|
||||
gst_vaapi_decoder_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void
|
||||
gst_vaapi_decoder_replace (GstVaapiDecoder ** old_decoder_ptr,
|
||||
GstVaapiDecoder * new_decoder);
|
||||
|
||||
gpointer
|
||||
gst_vaapi_decoder_get_user_data (GstVaapiDecoder * decoder);
|
||||
|
||||
void
|
||||
gst_vaapi_decoder_set_user_data (GstVaapiDecoder * decoder, gpointer user_data);
|
||||
|
||||
GstVaapiCodec
|
||||
gst_vaapi_decoder_get_codec (GstVaapiDecoder * decoder);
|
||||
|
||||
GstVideoCodecState *
|
||||
gst_vaapi_decoder_get_codec_state (GstVaapiDecoder * decoder);
|
||||
|
||||
void
|
||||
gst_vaapi_decoder_set_codec_state_changed_func (GstVaapiDecoder * decoder,
|
||||
GstVaapiDecoderStateChangedFunc func, gpointer user_data);
|
||||
|
||||
GstCaps *
|
||||
gst_vaapi_decoder_get_caps (GstVaapiDecoder * decoder);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_decoder_put_buffer (GstVaapiDecoder * decoder, GstBuffer * buf);
|
||||
|
||||
GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_get_surface (GstVaapiDecoder * decoder,
|
||||
GstVaapiSurfaceProxy ** out_proxy_ptr);
|
||||
|
||||
GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_get_frame (GstVaapiDecoder * decoder,
|
||||
GstVideoCodecFrame ** out_frame_ptr);
|
||||
|
||||
GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_get_frame_with_timeout (GstVaapiDecoder * decoder,
|
||||
GstVideoCodecFrame ** out_frame_ptr, guint64 timeout);
|
||||
|
||||
GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_parse (GstVaapiDecoder * decoder,
|
||||
GstVideoCodecFrame * frame, GstAdapter * adapter, gboolean at_eos,
|
||||
guint * got_unit_size_ptr, gboolean * got_frame_ptr);
|
||||
|
||||
GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_decode (GstVaapiDecoder * decoder,
|
||||
GstVideoCodecFrame * frame);
|
||||
|
||||
GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_flush (GstVaapiDecoder * decoder);
|
||||
|
||||
GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_reset (GstVaapiDecoder * decoder);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_decoder_update_caps (GstVaapiDecoder * decoder, GstCaps * caps);
|
||||
|
||||
GArray *
|
||||
gst_vaapi_decoder_get_surface_attributes (GstVaapiDecoder * decoder,
|
||||
gint * min_width, gint * min_height, gint * max_width, gint * max_height,
|
||||
guint * mem_types);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDecoder, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DECODER_H */
|
1288
gst-libs/gst/vaapi/gstvaapidecoder_av1.c
Normal file
1288
gst-libs/gst/vaapi/gstvaapidecoder_av1.c
Normal file
File diff suppressed because it is too large
Load diff
47
gst-libs/gst/vaapi/gstvaapidecoder_av1.h
Normal file
47
gst-libs/gst/vaapi/gstvaapidecoder_av1.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* gstvaapidecoder_av1.h - AV1 decoder
|
||||
*
|
||||
* Copyright (C) 2019-2020 Intel Corporation
|
||||
* Author: Junyan He <junyan.he@hotmail.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DECODER_AV1_H
|
||||
#define GST_VAAPI_DECODER_AV1_H
|
||||
|
||||
#include <gst/vaapi/gstvaapidecoder.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_DECODER_AV1 \
|
||||
(gst_vaapi_decoder_av1_get_type ())
|
||||
#define GST_VAAPI_DECODER_AV1(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DECODER_AV1, GstVaapiDecoderAV1))
|
||||
#define GST_VAAPI_IS_DECODER_AV1(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_DECODER_AV1))
|
||||
|
||||
typedef struct _GstVaapiDecoderAV1 GstVaapiDecoderAV1;
|
||||
|
||||
GType
|
||||
gst_vaapi_decoder_av1_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GstVaapiDecoder *
|
||||
gst_vaapi_decoder_av1_new (GstVaapiDisplay * display, GstCaps * caps);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DECODER_AV1_H */
|
421
gst-libs/gst/vaapi/gstvaapidecoder_dpb.c
Normal file
421
gst-libs/gst/vaapi/gstvaapidecoder_dpb.c
Normal file
|
@ -0,0 +1,421 @@
|
|||
/*
|
||||
* gstvaapidecoder_dpb.c - Decoded Picture Buffer
|
||||
*
|
||||
* Copyright (C) 2012-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "gstvaapidecoder_dpb.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
#define GST_VAAPI_DPB_CLASS(klass) \
|
||||
((GstVaapiDpbClass *)(klass))
|
||||
|
||||
#define GST_VAAPI_DPB_GET_CLASS(obj) \
|
||||
GST_VAAPI_DPB_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj))
|
||||
|
||||
/**
|
||||
* GstVaapiDpb:
|
||||
*
|
||||
* A decoded picture buffer (DPB) object.
|
||||
*/
|
||||
struct _GstVaapiDpb
|
||||
{
|
||||
/*< private > */
|
||||
GstVaapiMiniObject parent_instance;
|
||||
|
||||
/*< protected > */
|
||||
GstVaapiPicture **pictures;
|
||||
guint num_pictures;
|
||||
guint max_pictures;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDpbClass:
|
||||
*
|
||||
* The #GstVaapiDpb base class.
|
||||
*/
|
||||
struct _GstVaapiDpbClass
|
||||
{
|
||||
/*< private > */
|
||||
GstVaapiMiniObjectClass parent_class;
|
||||
|
||||
/*< protected > */
|
||||
void (*flush) (GstVaapiDpb * dpb);
|
||||
gboolean (*add) (GstVaapiDpb * dpb, GstVaapiPicture * picture);
|
||||
void (*get_neighbours) (GstVaapiDpb * dpb, GstVaapiPicture * picture,
|
||||
GstVaapiPicture ** prev_picture_ptr, GstVaapiPicture ** next_picture_ptr);
|
||||
};
|
||||
|
||||
static const GstVaapiMiniObjectClass *gst_vaapi_dpb_class (void);
|
||||
|
||||
static const GstVaapiMiniObjectClass *gst_vaapi_dpb2_class (void);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Common utilities --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static inline GstVaapiDpb *
|
||||
dpb_new (guint max_pictures)
|
||||
{
|
||||
GstVaapiDpb *dpb;
|
||||
|
||||
g_return_val_if_fail (max_pictures > 0, NULL);
|
||||
|
||||
dpb =
|
||||
(GstVaapiDpb *) gst_vaapi_mini_object_new (max_pictures ==
|
||||
2 ? gst_vaapi_dpb2_class () : gst_vaapi_dpb_class ());
|
||||
if (!dpb)
|
||||
return NULL;
|
||||
|
||||
dpb->num_pictures = 0;
|
||||
dpb->max_pictures = max_pictures;
|
||||
|
||||
dpb->pictures = g_new0 (GstVaapiPicture *, max_pictures);
|
||||
if (!dpb->pictures)
|
||||
goto error;
|
||||
return dpb;
|
||||
|
||||
/* ERRORS */
|
||||
error:
|
||||
{
|
||||
gst_vaapi_dpb_unref (dpb);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
dpb_get_oldest (GstVaapiDpb * dpb, gboolean output)
|
||||
{
|
||||
gint i, lowest_pts_index;
|
||||
|
||||
for (i = 0; i < dpb->num_pictures; i++) {
|
||||
if ((GST_VAAPI_PICTURE_IS_OUTPUT (dpb->pictures[i]) ^ output) == 0)
|
||||
break;
|
||||
}
|
||||
if (i == dpb->num_pictures)
|
||||
return -1;
|
||||
|
||||
lowest_pts_index = i++;
|
||||
for (; i < dpb->num_pictures; i++) {
|
||||
GstVaapiPicture *const picture = dpb->pictures[i];
|
||||
if ((GST_VAAPI_PICTURE_IS_OUTPUT (picture) ^ output) != 0)
|
||||
continue;
|
||||
if (picture->poc < dpb->pictures[lowest_pts_index]->poc)
|
||||
lowest_pts_index = i;
|
||||
}
|
||||
return lowest_pts_index;
|
||||
}
|
||||
|
||||
static void
|
||||
dpb_remove_index (GstVaapiDpb * dpb, guint index)
|
||||
{
|
||||
GstVaapiPicture **const pictures = dpb->pictures;
|
||||
guint num_pictures = --dpb->num_pictures;
|
||||
|
||||
if (index != num_pictures)
|
||||
gst_vaapi_picture_replace (&pictures[index], pictures[num_pictures]);
|
||||
gst_vaapi_picture_replace (&pictures[num_pictures], NULL);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
dpb_output (GstVaapiDpb * dpb, GstVaapiPicture * picture)
|
||||
{
|
||||
return gst_vaapi_picture_output (picture);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dpb_bump (GstVaapiDpb * dpb)
|
||||
{
|
||||
gint index;
|
||||
gboolean success;
|
||||
|
||||
index = dpb_get_oldest (dpb, FALSE);
|
||||
if (index < 0)
|
||||
return FALSE;
|
||||
|
||||
success = dpb_output (dpb, dpb->pictures[index]);
|
||||
if (!GST_VAAPI_PICTURE_IS_REFERENCE (dpb->pictures[index]))
|
||||
dpb_remove_index (dpb, index);
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
dpb_clear (GstVaapiDpb * dpb)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < dpb->num_pictures; i++)
|
||||
gst_vaapi_picture_replace (&dpb->pictures[i], NULL);
|
||||
dpb->num_pictures = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
dpb_flush (GstVaapiDpb * dpb)
|
||||
{
|
||||
while (dpb_bump (dpb));
|
||||
dpb_clear (dpb);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Generic implementation --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static gboolean
|
||||
dpb_add (GstVaapiDpb * dpb, GstVaapiPicture * picture)
|
||||
{
|
||||
guint i;
|
||||
|
||||
// Remove all unused pictures
|
||||
i = 0;
|
||||
while (i < dpb->num_pictures) {
|
||||
GstVaapiPicture *const picture = dpb->pictures[i];
|
||||
if (GST_VAAPI_PICTURE_IS_OUTPUT (picture) &&
|
||||
!GST_VAAPI_PICTURE_IS_REFERENCE (picture))
|
||||
dpb_remove_index (dpb, i);
|
||||
else
|
||||
i++;
|
||||
}
|
||||
|
||||
// Store reference decoded picture into the DPB
|
||||
if (GST_VAAPI_PICTURE_IS_REFERENCE (picture)) {
|
||||
while (dpb->num_pictures == dpb->max_pictures) {
|
||||
if (!dpb_bump (dpb))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
// Store non-reference decoded picture into the DPB
|
||||
else {
|
||||
if (GST_VAAPI_PICTURE_IS_SKIPPED (picture))
|
||||
return TRUE;
|
||||
while (dpb->num_pictures == dpb->max_pictures) {
|
||||
for (i = 0; i < dpb->num_pictures; i++) {
|
||||
if (!GST_VAAPI_PICTURE_IS_OUTPUT (picture) &&
|
||||
dpb->pictures[i]->poc < picture->poc)
|
||||
break;
|
||||
}
|
||||
if (i == dpb->num_pictures)
|
||||
return dpb_output (dpb, picture);
|
||||
if (!dpb_bump (dpb))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
gst_vaapi_picture_replace (&dpb->pictures[dpb->num_pictures++], picture);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
dpb_get_neighbours (GstVaapiDpb * dpb, GstVaapiPicture * picture,
|
||||
GstVaapiPicture ** prev_picture_ptr, GstVaapiPicture ** next_picture_ptr)
|
||||
{
|
||||
GstVaapiPicture *prev_picture = NULL;
|
||||
GstVaapiPicture *next_picture = NULL;
|
||||
guint i;
|
||||
|
||||
/* Find the first picture with POC > specified picture POC */
|
||||
for (i = 0; i < dpb->num_pictures; i++) {
|
||||
GstVaapiPicture *const ref_picture = dpb->pictures[i];
|
||||
if (ref_picture->poc == picture->poc) {
|
||||
if (i > 0)
|
||||
prev_picture = dpb->pictures[i - 1];
|
||||
if (i + 1 < dpb->num_pictures)
|
||||
next_picture = dpb->pictures[i + 1];
|
||||
break;
|
||||
} else if (ref_picture->poc > picture->poc) {
|
||||
next_picture = ref_picture;
|
||||
if (i > 0)
|
||||
prev_picture = dpb->pictures[i - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_assert (next_picture ? next_picture->poc > picture->poc : TRUE);
|
||||
g_assert (prev_picture ? prev_picture->poc < picture->poc : TRUE);
|
||||
|
||||
if (prev_picture_ptr)
|
||||
*prev_picture_ptr = prev_picture;
|
||||
if (next_picture_ptr)
|
||||
*next_picture_ptr = next_picture;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Optimized implementation for 2 reference pictures --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static gboolean
|
||||
dpb2_add (GstVaapiDpb * dpb, GstVaapiPicture * picture)
|
||||
{
|
||||
GstVaapiPicture *ref_picture;
|
||||
gint index = -1;
|
||||
|
||||
g_return_val_if_fail (GST_VAAPI_IS_DPB (dpb), FALSE);
|
||||
g_return_val_if_fail (dpb->max_pictures == 2, FALSE);
|
||||
|
||||
/*
|
||||
* Purpose: only store reference decoded pictures into the DPB
|
||||
*
|
||||
* This means:
|
||||
* - non-reference decoded pictures are output immediately
|
||||
* - ... thus causing older reference pictures to be output, if not already
|
||||
* - the oldest reference picture is replaced with the new reference picture
|
||||
*/
|
||||
if (G_LIKELY (dpb->num_pictures == 2)) {
|
||||
index = (dpb->pictures[0]->poc > dpb->pictures[1]->poc);
|
||||
ref_picture = dpb->pictures[index];
|
||||
if (!GST_VAAPI_PICTURE_IS_OUTPUT (ref_picture)) {
|
||||
if (!dpb_output (dpb, ref_picture))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!GST_VAAPI_PICTURE_IS_REFERENCE (picture))
|
||||
return dpb_output (dpb, picture);
|
||||
|
||||
if (index < 0)
|
||||
index = dpb->num_pictures++;
|
||||
gst_vaapi_picture_replace (&dpb->pictures[index], picture);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
dpb2_get_neighbours (GstVaapiDpb * dpb, GstVaapiPicture * picture,
|
||||
GstVaapiPicture ** prev_picture_ptr, GstVaapiPicture ** next_picture_ptr)
|
||||
{
|
||||
GstVaapiPicture *ref_picture, *ref_pictures[2];
|
||||
GstVaapiPicture **picture_ptr;
|
||||
guint i, index;
|
||||
|
||||
g_return_if_fail (GST_VAAPI_IS_DPB (dpb));
|
||||
g_return_if_fail (dpb->max_pictures == 2);
|
||||
g_return_if_fail (GST_VAAPI_IS_PICTURE (picture));
|
||||
|
||||
ref_pictures[0] = NULL;
|
||||
ref_pictures[1] = NULL;
|
||||
for (i = 0; i < dpb->num_pictures; i++) {
|
||||
ref_picture = dpb->pictures[i];
|
||||
index = ref_picture->poc > picture->poc;
|
||||
picture_ptr = &ref_pictures[index];
|
||||
if (!*picture_ptr || ((*picture_ptr)->poc > ref_picture->poc) == index)
|
||||
*picture_ptr = ref_picture;
|
||||
}
|
||||
|
||||
if (prev_picture_ptr)
|
||||
*prev_picture_ptr = ref_pictures[0];
|
||||
if (next_picture_ptr)
|
||||
*next_picture_ptr = ref_pictures[1];
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Interface --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
gst_vaapi_dpb_finalize (GstVaapiDpb * dpb)
|
||||
{
|
||||
dpb_clear (dpb);
|
||||
g_free (dpb->pictures);
|
||||
}
|
||||
|
||||
static const GstVaapiMiniObjectClass *
|
||||
gst_vaapi_dpb_class (void)
|
||||
{
|
||||
static const GstVaapiDpbClass GstVaapiDpbClass = {
|
||||
{sizeof (GstVaapiDpb),
|
||||
(GDestroyNotify) gst_vaapi_dpb_finalize}
|
||||
,
|
||||
|
||||
dpb_flush,
|
||||
dpb_add,
|
||||
dpb_get_neighbours
|
||||
};
|
||||
return &GstVaapiDpbClass.parent_class;
|
||||
}
|
||||
|
||||
static const GstVaapiMiniObjectClass *
|
||||
gst_vaapi_dpb2_class (void)
|
||||
{
|
||||
static const GstVaapiDpbClass GstVaapiDpb2Class = {
|
||||
{sizeof (GstVaapiDpb),
|
||||
(GDestroyNotify) gst_vaapi_dpb_finalize}
|
||||
,
|
||||
|
||||
dpb_flush,
|
||||
dpb2_add,
|
||||
dpb2_get_neighbours
|
||||
};
|
||||
return &GstVaapiDpb2Class.parent_class;
|
||||
}
|
||||
|
||||
GstVaapiDpb *
|
||||
gst_vaapi_dpb_new (guint max_pictures)
|
||||
{
|
||||
return dpb_new (max_pictures);
|
||||
}
|
||||
|
||||
void
|
||||
gst_vaapi_dpb_flush (GstVaapiDpb * dpb)
|
||||
{
|
||||
const GstVaapiDpbClass *klass;
|
||||
|
||||
g_return_if_fail (GST_VAAPI_IS_DPB (dpb));
|
||||
|
||||
klass = GST_VAAPI_DPB_GET_CLASS (dpb);
|
||||
if (G_UNLIKELY (!klass || !klass->add))
|
||||
return;
|
||||
klass->flush (dpb);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_dpb_add (GstVaapiDpb * dpb, GstVaapiPicture * picture)
|
||||
{
|
||||
const GstVaapiDpbClass *klass;
|
||||
|
||||
g_return_val_if_fail (GST_VAAPI_IS_DPB (dpb), FALSE);
|
||||
g_return_val_if_fail (GST_VAAPI_IS_PICTURE (picture), FALSE);
|
||||
|
||||
klass = GST_VAAPI_DPB_GET_CLASS (dpb);
|
||||
if (G_UNLIKELY (!klass || !klass->add))
|
||||
return FALSE;
|
||||
return klass->add (dpb, picture);
|
||||
}
|
||||
|
||||
guint
|
||||
gst_vaapi_dpb_size (GstVaapiDpb * dpb)
|
||||
{
|
||||
g_return_val_if_fail (GST_VAAPI_IS_DPB (dpb), 0);
|
||||
|
||||
return dpb->num_pictures;
|
||||
}
|
||||
|
||||
void
|
||||
gst_vaapi_dpb_get_neighbours (GstVaapiDpb * dpb, GstVaapiPicture * picture,
|
||||
GstVaapiPicture ** prev_picture_ptr, GstVaapiPicture ** next_picture_ptr)
|
||||
{
|
||||
const GstVaapiDpbClass *klass;
|
||||
|
||||
g_return_if_fail (GST_VAAPI_IS_DPB (dpb));
|
||||
g_return_if_fail (GST_VAAPI_IS_PICTURE (picture));
|
||||
|
||||
klass = GST_VAAPI_DPB_GET_CLASS (dpb);
|
||||
if (G_UNLIKELY (!klass || !klass->get_neighbours))
|
||||
return;
|
||||
klass->get_neighbours (dpb, picture, prev_picture_ptr, next_picture_ptr);
|
||||
}
|
80
gst-libs/gst/vaapi/gstvaapidecoder_dpb.h
Normal file
80
gst-libs/gst/vaapi/gstvaapidecoder_dpb.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* gstvaapidecoder_dpb.h - Decoded Picture Buffer
|
||||
*
|
||||
* Copyright (C) 2012-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DECODER_DPB_H
|
||||
#define GST_VAAPI_DECODER_DPB_H
|
||||
|
||||
#include <gst/vaapi/gstvaapidecoder_objects.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstVaapiDpb GstVaapiDpb;
|
||||
typedef struct _GstVaapiDpbClass GstVaapiDpbClass;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Decoded Picture Buffer --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_DPB(obj) \
|
||||
((GstVaapiDpb *)(obj))
|
||||
|
||||
#define GST_VAAPI_IS_DPB(obj) \
|
||||
(GST_VAAPI_DPB(obj) != NULL)
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiDpb *
|
||||
gst_vaapi_dpb_new(guint max_pictures);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_dpb_flush(GstVaapiDpb *dpb);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_dpb_add(GstVaapiDpb *dpb, GstVaapiPicture *picture);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
guint
|
||||
gst_vaapi_dpb_size(GstVaapiDpb *dpb);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_dpb_get_neighbours(
|
||||
GstVaapiDpb *dpb,
|
||||
GstVaapiPicture *picture,
|
||||
GstVaapiPicture **prev_picture_ptr,
|
||||
GstVaapiPicture **next_picture_ptr
|
||||
);
|
||||
|
||||
#define gst_vaapi_dpb_ref(dpb) \
|
||||
gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(dpb))
|
||||
|
||||
#define gst_vaapi_dpb_unref(dpb) \
|
||||
gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(dpb))
|
||||
|
||||
#define gst_vaapi_dpb_replace(old_dpb_ptr, new_dpb) \
|
||||
gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_dpb_ptr), \
|
||||
(GstVaapiMiniObject *)(new_dpb))
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DECODER_DPB */
|
5018
gst-libs/gst/vaapi/gstvaapidecoder_h264.c
Normal file
5018
gst-libs/gst/vaapi/gstvaapidecoder_h264.c
Normal file
File diff suppressed because it is too large
Load diff
80
gst-libs/gst/vaapi/gstvaapidecoder_h264.h
Normal file
80
gst-libs/gst/vaapi/gstvaapidecoder_h264.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* gstvaapidecoder_h264.h - H.264 decoder
|
||||
*
|
||||
* Copyright (C) 2011-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DECODER_H264_H
|
||||
#define GST_VAAPI_DECODER_H264_H
|
||||
|
||||
#include <gst/vaapi/gstvaapidecoder.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_DECODER_H264 \
|
||||
(gst_vaapi_decoder_h264_get_type ())
|
||||
#define GST_VAAPI_DECODER_H264(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DECODER_H264, GstVaapiDecoderH264))
|
||||
#define GST_VAAPI_IS_DECODER_H264(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_DECODER_H264))
|
||||
|
||||
typedef struct _GstVaapiDecoderH264 GstVaapiDecoderH264;
|
||||
|
||||
/**
|
||||
* GstVaapiStreamAlignH264:
|
||||
* @GST_VAAPI_STREAM_ALIGN_H264_NONE: Generic H.264 stream buffers
|
||||
* @GST_VAAPI_STREAM_ALIGN_H264_NALU: H.264 stream buffers aligned NAL
|
||||
* unit boundaries
|
||||
* @GST_VAAPI_STREAM_ALIGN_H264_AU: H.264 stream buffers aligned on
|
||||
* access unit boundaries
|
||||
*
|
||||
* Set of possible buffer alignments for H.264 streams.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VAAPI_STREAM_ALIGN_H264_NONE,
|
||||
GST_VAAPI_STREAM_ALIGN_H264_NALU,
|
||||
GST_VAAPI_STREAM_ALIGN_H264_AU
|
||||
} GstVaapiStreamAlignH264;
|
||||
|
||||
GType
|
||||
gst_vaapi_decoder_h264_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GstVaapiDecoder *
|
||||
gst_vaapi_decoder_h264_new (GstVaapiDisplay *display, GstCaps *caps);
|
||||
|
||||
void
|
||||
gst_vaapi_decoder_h264_set_alignment(GstVaapiDecoderH264 *decoder,
|
||||
GstVaapiStreamAlignH264 alignment);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_decoder_h264_get_low_latency(GstVaapiDecoderH264 * decoder);
|
||||
|
||||
void
|
||||
gst_vaapi_decoder_h264_set_low_latency(GstVaapiDecoderH264 * decoder,
|
||||
gboolean force_low_latency);
|
||||
|
||||
void
|
||||
gst_vaapi_decoder_h264_set_base_only(GstVaapiDecoderH264 * decoder,
|
||||
gboolean base_only);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDecoderH264, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DECODER_H264_H */
|
3408
gst-libs/gst/vaapi/gstvaapidecoder_h265.c
Normal file
3408
gst-libs/gst/vaapi/gstvaapidecoder_h265.c
Normal file
File diff suppressed because it is too large
Load diff
70
gst-libs/gst/vaapi/gstvaapidecoder_h265.h
Normal file
70
gst-libs/gst/vaapi/gstvaapidecoder_h265.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* gstvaapidecoder_h265.h - H.265 decoder
|
||||
*
|
||||
* Copyright (C) 2015 Intel Corporation
|
||||
* Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DECODER_H265_H
|
||||
#define GST_VAAPI_DECODER_H265_H
|
||||
|
||||
#include <gst/vaapi/gstvaapidecoder.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_DECODER_H265 \
|
||||
(gst_vaapi_decoder_h265_get_type ())
|
||||
#define GST_VAAPI_DECODER_H265(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DECODER_H265, GstVaapiDecoderH265))
|
||||
#define GST_VAAPI_IS_DECODER_H265(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_DECODER_H265))
|
||||
|
||||
typedef struct _GstVaapiDecoderH265 GstVaapiDecoderH265;
|
||||
|
||||
/**
|
||||
* GstVaapiStreamAlignH265:
|
||||
* @GST_VAAPI_STREAM_ALIGN_H265_NONE: Generic H.265 stream buffers
|
||||
* @GST_VAAPI_STREAM_ALIGN_H265_NALU: H.265 stream buffers aligned NAL
|
||||
* unit boundaries
|
||||
* @GST_VAAPI_STREAM_ALIGN_H265_AU: H.265 stream buffers aligned on
|
||||
* access unit boundaries
|
||||
*
|
||||
* Set of possible buffer alignments for H.265 streams.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VAAPI_STREAM_ALIGN_H265_NONE,
|
||||
GST_VAAPI_STREAM_ALIGN_H265_NALU,
|
||||
GST_VAAPI_STREAM_ALIGN_H265_AU
|
||||
} GstVaapiStreamAlignH265;
|
||||
|
||||
GType
|
||||
gst_vaapi_decoder_h265_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GstVaapiDecoder *
|
||||
gst_vaapi_decoder_h265_new (GstVaapiDisplay *display, GstCaps *caps);
|
||||
|
||||
void
|
||||
gst_vaapi_decoder_h265_set_alignment (GstVaapiDecoderH265 *decoder,
|
||||
GstVaapiStreamAlignH265 alignment);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDecoderH265, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DECODER_H265_H */
|
964
gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c
Normal file
964
gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c
Normal file
|
@ -0,0 +1,964 @@
|
|||
/*
|
||||
* gstvaapidecoder_jpeg.c - JPEG decoder
|
||||
*
|
||||
* Copyright (C) 2011-2013 Intel Corporation
|
||||
* Author: Wind Yuan <feng.yuan@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstvaapidecoder_jpeg
|
||||
* @short_description: JPEG decoder
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include <gst/codecparsers/gstjpegparser.h>
|
||||
#include "gstvaapicompat.h"
|
||||
#include "gstvaapidecoder_jpeg.h"
|
||||
#include "gstvaapidecoder_objects.h"
|
||||
#include "gstvaapidecoder_priv.h"
|
||||
#include "gstvaapidisplay_priv.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
#define GST_VAAPI_DECODER_JPEG_CAST(decoder) \
|
||||
((GstVaapiDecoderJpeg *)(decoder))
|
||||
|
||||
typedef struct _GstVaapiDecoderJpegPrivate GstVaapiDecoderJpegPrivate;
|
||||
typedef struct _GstVaapiDecoderJpegClass GstVaapiDecoderJpegClass;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GST_JPEG_VIDEO_STATE_GOT_SOI = 1 << 0,
|
||||
GST_JPEG_VIDEO_STATE_GOT_SOF = 1 << 1,
|
||||
GST_JPEG_VIDEO_STATE_GOT_SOS = 1 << 2,
|
||||
GST_JPEG_VIDEO_STATE_GOT_HUF_TABLE = 1 << 3,
|
||||
GST_JPEG_VIDEO_STATE_GOT_IQ_TABLE = 1 << 4,
|
||||
|
||||
GST_JPEG_VIDEO_STATE_VALID_PICTURE = (GST_JPEG_VIDEO_STATE_GOT_SOI |
|
||||
GST_JPEG_VIDEO_STATE_GOT_SOF | GST_JPEG_VIDEO_STATE_GOT_SOS),
|
||||
} GstJpegVideoState;
|
||||
|
||||
struct _GstVaapiDecoderJpegPrivate
|
||||
{
|
||||
GstVaapiProfile profile;
|
||||
guint width;
|
||||
guint height;
|
||||
GstVaapiPicture *current_picture;
|
||||
GstJpegFrameHdr frame_hdr;
|
||||
GstJpegHuffmanTables huf_tables;
|
||||
GstJpegQuantTables quant_tables;
|
||||
guint mcu_restart;
|
||||
guint parser_state;
|
||||
guint decoder_state;
|
||||
guint is_opened:1;
|
||||
guint profile_changed:1;
|
||||
guint size_changed:1;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDecoderJpeg:
|
||||
*
|
||||
* A decoder based on Jpeg.
|
||||
*/
|
||||
struct _GstVaapiDecoderJpeg
|
||||
{
|
||||
/*< private > */
|
||||
GstVaapiDecoder parent_instance;
|
||||
GstVaapiDecoderJpegPrivate priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDecoderJpegClass:
|
||||
*
|
||||
* A decoder class based on Jpeg.
|
||||
*/
|
||||
struct _GstVaapiDecoderJpegClass
|
||||
{
|
||||
/*< private > */
|
||||
GstVaapiDecoderClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GstVaapiDecoderJpeg, gst_vaapi_decoder_jpeg,
|
||||
GST_TYPE_VAAPI_DECODER);
|
||||
|
||||
static inline void
|
||||
unit_set_marker_code (GstVaapiDecoderUnit * unit, GstJpegMarker marker)
|
||||
{
|
||||
unit->parsed_info = GSIZE_TO_POINTER (marker);
|
||||
}
|
||||
|
||||
static inline GstJpegMarker
|
||||
unit_get_marker_code (GstVaapiDecoderUnit * unit)
|
||||
{
|
||||
return GPOINTER_TO_SIZE (unit->parsed_info);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_jpeg_close (GstVaapiDecoderJpeg * decoder)
|
||||
{
|
||||
GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
|
||||
|
||||
gst_vaapi_picture_replace (&priv->current_picture, NULL);
|
||||
|
||||
/* Reset all */
|
||||
priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE;
|
||||
priv->width = 0;
|
||||
priv->height = 0;
|
||||
priv->is_opened = FALSE;
|
||||
priv->profile_changed = TRUE;
|
||||
priv->size_changed = TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_decoder_jpeg_open (GstVaapiDecoderJpeg * decoder)
|
||||
{
|
||||
GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
|
||||
|
||||
gst_vaapi_decoder_jpeg_close (decoder);
|
||||
|
||||
priv->parser_state = 0;
|
||||
priv->decoder_state = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_jpeg_destroy (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
GstVaapiDecoderJpeg *const decoder =
|
||||
GST_VAAPI_DECODER_JPEG_CAST (base_decoder);
|
||||
|
||||
gst_vaapi_decoder_jpeg_close (decoder);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_decoder_jpeg_create (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
GstVaapiDecoderJpeg *const decoder =
|
||||
GST_VAAPI_DECODER_JPEG_CAST (base_decoder);
|
||||
GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
|
||||
|
||||
priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE;
|
||||
priv->profile_changed = TRUE;
|
||||
priv->size_changed = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_jpeg_reset (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
gst_vaapi_decoder_jpeg_destroy (base_decoder);
|
||||
gst_vaapi_decoder_jpeg_create (base_decoder);
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_chroma_type (GstJpegFrameHdr * frame_hdr, GstVaapiChromaType * chroma_type)
|
||||
{
|
||||
int h0 = frame_hdr->components[0].horizontal_factor;
|
||||
int h1 = frame_hdr->components[1].horizontal_factor;
|
||||
int h2 = frame_hdr->components[2].horizontal_factor;
|
||||
int v0 = frame_hdr->components[0].vertical_factor;
|
||||
int v1 = frame_hdr->components[1].vertical_factor;
|
||||
int v2 = frame_hdr->components[2].vertical_factor;
|
||||
|
||||
if (frame_hdr->num_components == 1) {
|
||||
*chroma_type = GST_VAAPI_CHROMA_TYPE_YUV400;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (h1 != h2 || v1 != v2)
|
||||
return FALSE;
|
||||
|
||||
if (h0 == h1) {
|
||||
if (v0 == v1)
|
||||
*chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444;
|
||||
else if (v0 == 2 * v1)
|
||||
*chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422;
|
||||
else
|
||||
return FALSE;
|
||||
} else if (h0 == 2 * h1) {
|
||||
if (v0 == v1)
|
||||
*chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422;
|
||||
else if (v0 == 2 * v1)
|
||||
*chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
|
||||
else
|
||||
return FALSE;
|
||||
} else if (h0 == 4 * h1) {
|
||||
if (v0 == v1)
|
||||
*chroma_type = GST_VAAPI_CHROMA_TYPE_YUV411;
|
||||
else
|
||||
return FALSE;
|
||||
} else
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
ensure_context (GstVaapiDecoderJpeg * decoder)
|
||||
{
|
||||
GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
|
||||
GstJpegFrameHdr *const frame_hdr = &priv->frame_hdr;
|
||||
GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
|
||||
GstVaapiProfile profiles[2];
|
||||
GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
|
||||
guint i, n_profiles = 0;
|
||||
gboolean reset_context = FALSE;
|
||||
|
||||
if (priv->profile_changed) {
|
||||
GST_DEBUG ("profile changed");
|
||||
priv->profile_changed = FALSE;
|
||||
reset_context = TRUE;
|
||||
|
||||
profiles[n_profiles++] = priv->profile;
|
||||
//if (priv->profile == GST_VAAPI_PROFILE_JPEG_EXTENDED)
|
||||
// profiles[n_profiles++] = GST_VAAPI_PROFILE_JPEG_BASELINE;
|
||||
|
||||
for (i = 0; i < n_profiles; i++) {
|
||||
if (gst_vaapi_display_has_decoder (GST_VAAPI_DECODER_DISPLAY (decoder),
|
||||
profiles[i], entrypoint))
|
||||
break;
|
||||
}
|
||||
if (i == n_profiles)
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
|
||||
priv->profile = profiles[i];
|
||||
}
|
||||
|
||||
if (priv->size_changed) {
|
||||
GST_DEBUG ("size changed");
|
||||
priv->size_changed = FALSE;
|
||||
reset_context = TRUE;
|
||||
}
|
||||
|
||||
if (reset_context) {
|
||||
GstVaapiContextInfo info;
|
||||
|
||||
info.profile = priv->profile;
|
||||
info.entrypoint = entrypoint;
|
||||
info.width = priv->width;
|
||||
info.height = priv->height;
|
||||
info.ref_frames = 2;
|
||||
if (!get_chroma_type (frame_hdr, &chroma_type))
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
|
||||
info.chroma_type = chroma_type;
|
||||
|
||||
reset_context =
|
||||
gst_vaapi_decoder_ensure_context (GST_VAAPI_DECODER (decoder), &info);
|
||||
if (!reset_context)
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
is_valid_state (guint state, guint ref_state)
|
||||
{
|
||||
return (state & ref_state) == ref_state;
|
||||
}
|
||||
|
||||
#define VALID_STATE(TYPE, STATE) \
|
||||
is_valid_state(priv->G_PASTE(TYPE,_state), \
|
||||
G_PASTE(GST_JPEG_VIDEO_STATE_,STATE))
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_current_picture (GstVaapiDecoderJpeg * decoder)
|
||||
{
|
||||
GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
|
||||
GstVaapiPicture *const picture = priv->current_picture;
|
||||
|
||||
if (!VALID_STATE (decoder, VALID_PICTURE))
|
||||
goto drop_frame;
|
||||
priv->decoder_state = 0;
|
||||
|
||||
if (!picture)
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
|
||||
if (!gst_vaapi_picture_decode (picture))
|
||||
goto error;
|
||||
if (!gst_vaapi_picture_output (picture))
|
||||
goto error;
|
||||
gst_vaapi_picture_replace (&priv->current_picture, NULL);
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
|
||||
/* ERRORS */
|
||||
error:
|
||||
{
|
||||
gst_vaapi_picture_replace (&priv->current_picture, NULL);
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
drop_frame:
|
||||
{
|
||||
priv->decoder_state = 0;
|
||||
return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fill_picture (GstVaapiDecoderJpeg * decoder,
|
||||
GstVaapiPicture * picture, GstJpegFrameHdr * frame_hdr)
|
||||
{
|
||||
VAPictureParameterBufferJPEGBaseline *const pic_param = picture->param;
|
||||
guint i;
|
||||
|
||||
memset (pic_param, 0, sizeof (VAPictureParameterBufferJPEGBaseline));
|
||||
pic_param->picture_width = frame_hdr->width;
|
||||
pic_param->picture_height = frame_hdr->height;
|
||||
|
||||
pic_param->num_components = frame_hdr->num_components;
|
||||
if (frame_hdr->num_components > 4)
|
||||
return FALSE;
|
||||
for (i = 0; i < pic_param->num_components; i++) {
|
||||
pic_param->components[i].component_id = frame_hdr->components[i].identifier;
|
||||
pic_param->components[i].h_sampling_factor =
|
||||
frame_hdr->components[i].horizontal_factor;
|
||||
pic_param->components[i].v_sampling_factor =
|
||||
frame_hdr->components[i].vertical_factor;
|
||||
pic_param->components[i].quantiser_table_selector =
|
||||
frame_hdr->components[i].quant_table_selector;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
fill_quantization_table (GstVaapiDecoderJpeg * decoder,
|
||||
GstVaapiPicture * picture)
|
||||
{
|
||||
GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
|
||||
VAIQMatrixBufferJPEGBaseline *iq_matrix;
|
||||
guint i, j, num_tables;
|
||||
|
||||
if (!VALID_STATE (decoder, GOT_IQ_TABLE))
|
||||
gst_jpeg_get_default_quantization_tables (&priv->quant_tables);
|
||||
|
||||
picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW (JPEGBaseline, decoder);
|
||||
if (!picture->iq_matrix) {
|
||||
GST_ERROR ("failed to allocate quantiser table");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
iq_matrix = picture->iq_matrix->param;
|
||||
|
||||
num_tables = MIN (G_N_ELEMENTS (iq_matrix->quantiser_table),
|
||||
GST_JPEG_MAX_QUANT_ELEMENTS);
|
||||
|
||||
for (i = 0; i < num_tables; i++) {
|
||||
GstJpegQuantTable *const quant_table = &priv->quant_tables.quant_tables[i];
|
||||
|
||||
iq_matrix->load_quantiser_table[i] = quant_table->valid;
|
||||
if (!iq_matrix->load_quantiser_table[i])
|
||||
continue;
|
||||
|
||||
if (quant_table->quant_precision != 0) {
|
||||
// Only Baseline profile is supported, thus 8-bit Qk values
|
||||
GST_ERROR ("unsupported quantization table element precision");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
|
||||
}
|
||||
|
||||
for (j = 0; j < GST_JPEG_MAX_QUANT_ELEMENTS; j++)
|
||||
iq_matrix->quantiser_table[i][j] = quant_table->quant_table[j];
|
||||
iq_matrix->load_quantiser_table[i] = 1;
|
||||
quant_table->valid = FALSE;
|
||||
}
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
huffman_tables_updated (const GstJpegHuffmanTables * huf_tables)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (huf_tables->dc_tables); i++)
|
||||
if (huf_tables->dc_tables[i].valid)
|
||||
return TRUE;
|
||||
for (i = 0; i < G_N_ELEMENTS (huf_tables->ac_tables); i++)
|
||||
if (huf_tables->ac_tables[i].valid)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
huffman_tables_reset (GstJpegHuffmanTables * huf_tables)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (huf_tables->dc_tables); i++)
|
||||
huf_tables->dc_tables[i].valid = FALSE;
|
||||
for (i = 0; i < G_N_ELEMENTS (huf_tables->ac_tables); i++)
|
||||
huf_tables->ac_tables[i].valid = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
fill_huffman_table (GstVaapiHuffmanTable * huf_table,
|
||||
const GstJpegHuffmanTables * huf_tables)
|
||||
{
|
||||
VAHuffmanTableBufferJPEGBaseline *const huffman_table = huf_table->param;
|
||||
guint i, num_tables;
|
||||
|
||||
num_tables = MIN (G_N_ELEMENTS (huffman_table->huffman_table),
|
||||
GST_JPEG_MAX_SCAN_COMPONENTS);
|
||||
|
||||
for (i = 0; i < num_tables; i++) {
|
||||
huffman_table->load_huffman_table[i] =
|
||||
huf_tables->dc_tables[i].valid && huf_tables->ac_tables[i].valid;
|
||||
if (!huffman_table->load_huffman_table[i])
|
||||
continue;
|
||||
|
||||
memcpy (huffman_table->huffman_table[i].num_dc_codes,
|
||||
huf_tables->dc_tables[i].huf_bits,
|
||||
sizeof (huffman_table->huffman_table[i].num_dc_codes));
|
||||
memcpy (huffman_table->huffman_table[i].dc_values,
|
||||
huf_tables->dc_tables[i].huf_values,
|
||||
sizeof (huffman_table->huffman_table[i].dc_values));
|
||||
memcpy (huffman_table->huffman_table[i].num_ac_codes,
|
||||
huf_tables->ac_tables[i].huf_bits,
|
||||
sizeof (huffman_table->huffman_table[i].num_ac_codes));
|
||||
memcpy (huffman_table->huffman_table[i].ac_values,
|
||||
huf_tables->ac_tables[i].huf_values,
|
||||
sizeof (huffman_table->huffman_table[i].ac_values));
|
||||
memset (huffman_table->huffman_table[i].pad,
|
||||
0, sizeof (huffman_table->huffman_table[i].pad));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_max_sampling_factors (const GstJpegFrameHdr * frame_hdr,
|
||||
guint * h_max_ptr, guint * v_max_ptr)
|
||||
{
|
||||
guint h_max = frame_hdr->components[0].horizontal_factor;
|
||||
guint v_max = frame_hdr->components[0].vertical_factor;
|
||||
guint i;
|
||||
|
||||
for (i = 1; i < frame_hdr->num_components; i++) {
|
||||
const GstJpegFrameComponent *const fcp = &frame_hdr->components[i];
|
||||
if (h_max < fcp->horizontal_factor)
|
||||
h_max = fcp->horizontal_factor;
|
||||
if (v_max < fcp->vertical_factor)
|
||||
v_max = fcp->vertical_factor;
|
||||
}
|
||||
|
||||
if (h_max_ptr)
|
||||
*h_max_ptr = h_max;
|
||||
if (v_max_ptr)
|
||||
*v_max_ptr = v_max;
|
||||
}
|
||||
|
||||
static const GstJpegFrameComponent *
|
||||
get_component (const GstJpegFrameHdr * frame_hdr, guint selector)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < frame_hdr->num_components; i++) {
|
||||
const GstJpegFrameComponent *const fcp = &frame_hdr->components[i];
|
||||
if (fcp->identifier == selector)
|
||||
return fcp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_picture (GstVaapiDecoderJpeg * decoder, GstJpegSegment * seg)
|
||||
{
|
||||
GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
|
||||
GstJpegFrameHdr *const frame_hdr = &priv->frame_hdr;
|
||||
|
||||
if (!VALID_STATE (decoder, GOT_SOI))
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
|
||||
switch (seg->marker) {
|
||||
case GST_JPEG_MARKER_SOF_MIN:
|
||||
priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE;
|
||||
break;
|
||||
default:
|
||||
GST_ERROR ("unsupported profile %d", seg->marker);
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
|
||||
}
|
||||
|
||||
memset (frame_hdr, 0, sizeof (*frame_hdr));
|
||||
if (!gst_jpeg_segment_parse_frame_header (seg, frame_hdr)) {
|
||||
GST_ERROR ("failed to parse image");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
|
||||
}
|
||||
|
||||
if (priv->height != frame_hdr->height || priv->width != frame_hdr->width)
|
||||
priv->size_changed = TRUE;
|
||||
|
||||
priv->height = frame_hdr->height;
|
||||
priv->width = frame_hdr->width;
|
||||
|
||||
priv->decoder_state |= GST_JPEG_VIDEO_STATE_GOT_SOF;
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_huffman_table (GstVaapiDecoderJpeg * decoder, GstJpegSegment * seg)
|
||||
{
|
||||
GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
|
||||
|
||||
if (!VALID_STATE (decoder, GOT_SOI))
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
|
||||
if (!gst_jpeg_segment_parse_huffman_table (seg, &priv->huf_tables)) {
|
||||
GST_ERROR ("failed to parse Huffman table");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
|
||||
}
|
||||
|
||||
priv->decoder_state |= GST_JPEG_VIDEO_STATE_GOT_HUF_TABLE;
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_quant_table (GstVaapiDecoderJpeg * decoder, GstJpegSegment * seg)
|
||||
{
|
||||
GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
|
||||
|
||||
if (!VALID_STATE (decoder, GOT_SOI))
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
|
||||
if (!gst_jpeg_segment_parse_quantization_table (seg, &priv->quant_tables)) {
|
||||
GST_ERROR ("failed to parse quantization table");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
|
||||
}
|
||||
|
||||
priv->decoder_state |= GST_JPEG_VIDEO_STATE_GOT_IQ_TABLE;
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_restart_interval (GstVaapiDecoderJpeg * decoder, GstJpegSegment * seg)
|
||||
{
|
||||
GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
|
||||
|
||||
if (!VALID_STATE (decoder, GOT_SOI))
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
|
||||
if (!gst_jpeg_segment_parse_restart_interval (seg, &priv->mcu_restart)) {
|
||||
GST_ERROR ("failed to parse restart interval");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
|
||||
}
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_scan (GstVaapiDecoderJpeg * decoder, GstJpegSegment * seg)
|
||||
{
|
||||
GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
|
||||
GstVaapiPicture *const picture = priv->current_picture;
|
||||
GstVaapiSlice *slice;
|
||||
VASliceParameterBufferJPEGBaseline *slice_param;
|
||||
GstJpegScanHdr scan_hdr;
|
||||
guint scan_hdr_size, scan_data_size;
|
||||
guint i, h_max, v_max, mcu_width, mcu_height;
|
||||
|
||||
if (!VALID_STATE (decoder, GOT_SOF))
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
|
||||
scan_hdr_size = (seg->data[seg->offset] << 8) | seg->data[seg->offset + 1];
|
||||
scan_data_size = seg->size - scan_hdr_size;
|
||||
|
||||
memset (&scan_hdr, 0, sizeof (scan_hdr));
|
||||
if (!gst_jpeg_segment_parse_scan_header (seg, &scan_hdr)) {
|
||||
GST_ERROR ("failed to parse scan header");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
|
||||
}
|
||||
|
||||
slice = GST_VAAPI_SLICE_NEW (JPEGBaseline, decoder,
|
||||
seg->data + seg->offset + scan_hdr_size, scan_data_size);
|
||||
if (!slice) {
|
||||
GST_ERROR ("failed to allocate slice");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
gst_vaapi_picture_add_slice (picture, slice);
|
||||
|
||||
if (!VALID_STATE (decoder, GOT_HUF_TABLE))
|
||||
gst_jpeg_get_default_huffman_tables (&priv->huf_tables);
|
||||
|
||||
// Update VA Huffman table if it changed for this scan
|
||||
if (huffman_tables_updated (&priv->huf_tables)) {
|
||||
slice->huf_table = GST_VAAPI_HUFFMAN_TABLE_NEW (JPEGBaseline, decoder);
|
||||
if (!slice->huf_table) {
|
||||
GST_ERROR ("failed to allocate Huffman tables");
|
||||
huffman_tables_reset (&priv->huf_tables);
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
fill_huffman_table (slice->huf_table, &priv->huf_tables);
|
||||
huffman_tables_reset (&priv->huf_tables);
|
||||
}
|
||||
|
||||
slice_param = slice->param;
|
||||
slice_param->num_components = scan_hdr.num_components;
|
||||
for (i = 0; i < scan_hdr.num_components; i++) {
|
||||
slice_param->components[i].component_selector =
|
||||
scan_hdr.components[i].component_selector;
|
||||
slice_param->components[i].dc_table_selector =
|
||||
scan_hdr.components[i].dc_selector;
|
||||
slice_param->components[i].ac_table_selector =
|
||||
scan_hdr.components[i].ac_selector;
|
||||
}
|
||||
slice_param->restart_interval = priv->mcu_restart;
|
||||
slice_param->slice_horizontal_position = 0;
|
||||
slice_param->slice_vertical_position = 0;
|
||||
|
||||
get_max_sampling_factors (&priv->frame_hdr, &h_max, &v_max);
|
||||
mcu_width = 8 * h_max;
|
||||
mcu_height = 8 * v_max;
|
||||
|
||||
if (scan_hdr.num_components == 1) { // Non-interleaved
|
||||
const guint Csj = slice_param->components[0].component_selector;
|
||||
const GstJpegFrameComponent *const fcp =
|
||||
get_component (&priv->frame_hdr, Csj);
|
||||
|
||||
if (!fcp || fcp->horizontal_factor == 0 || fcp->vertical_factor == 0) {
|
||||
GST_ERROR ("failed to validate image component %u", Csj);
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
mcu_width /= fcp->horizontal_factor;
|
||||
mcu_height /= fcp->vertical_factor;
|
||||
}
|
||||
slice_param->num_mcus =
|
||||
((priv->frame_hdr.width + mcu_width - 1) / mcu_width) *
|
||||
((priv->frame_hdr.height + mcu_height - 1) / mcu_height);
|
||||
|
||||
priv->decoder_state |= GST_JPEG_VIDEO_STATE_GOT_SOS;
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_segment (GstVaapiDecoderJpeg * decoder, GstJpegSegment * seg)
|
||||
{
|
||||
GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
|
||||
GstVaapiDecoderStatus status;
|
||||
|
||||
// Decode segment
|
||||
status = GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
switch (seg->marker) {
|
||||
case GST_JPEG_MARKER_SOI:
|
||||
priv->mcu_restart = 0;
|
||||
priv->decoder_state |= GST_JPEG_VIDEO_STATE_GOT_SOI;
|
||||
break;
|
||||
case GST_JPEG_MARKER_EOI:
|
||||
priv->decoder_state = 0;
|
||||
break;
|
||||
case GST_JPEG_MARKER_DAC:
|
||||
GST_ERROR ("unsupported arithmetic coding mode");
|
||||
status = GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
|
||||
break;
|
||||
case GST_JPEG_MARKER_DHT:
|
||||
status = decode_huffman_table (decoder, seg);
|
||||
break;
|
||||
case GST_JPEG_MARKER_DQT:
|
||||
status = decode_quant_table (decoder, seg);
|
||||
break;
|
||||
case GST_JPEG_MARKER_DRI:
|
||||
status = decode_restart_interval (decoder, seg);
|
||||
break;
|
||||
case GST_JPEG_MARKER_SOS:
|
||||
status = decode_scan (decoder, seg);
|
||||
break;
|
||||
default:
|
||||
// SOFn segments
|
||||
if (seg->marker >= GST_JPEG_MARKER_SOF_MIN &&
|
||||
seg->marker <= GST_JPEG_MARKER_SOF_MAX)
|
||||
status = decode_picture (decoder, seg);
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
ensure_decoder (GstVaapiDecoderJpeg * decoder)
|
||||
{
|
||||
GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
|
||||
|
||||
if (!priv->is_opened) {
|
||||
priv->is_opened = gst_vaapi_decoder_jpeg_open (decoder);
|
||||
if (!priv->is_opened)
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
|
||||
}
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_scan_complete (GstJpegMarker marker)
|
||||
{
|
||||
// Scan is assumed to be complete when the new segment is not RSTi
|
||||
return marker < GST_JPEG_MARKER_RST_MIN || marker > GST_JPEG_MARKER_RST_MAX;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_jpeg_parse (GstVaapiDecoder * base_decoder,
|
||||
GstAdapter * adapter, gboolean at_eos, GstVaapiDecoderUnit * unit)
|
||||
{
|
||||
GstVaapiDecoderJpeg *const decoder =
|
||||
GST_VAAPI_DECODER_JPEG_CAST (base_decoder);
|
||||
GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
|
||||
GstVaapiParserState *const ps = GST_VAAPI_PARSER_STATE (base_decoder);
|
||||
GstVaapiDecoderStatus status;
|
||||
GstJpegMarker marker;
|
||||
GstJpegSegment seg;
|
||||
const guchar *buf;
|
||||
guint buf_size, flags;
|
||||
gint ofs1, ofs2;
|
||||
|
||||
status = ensure_decoder (decoder);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
/* Expect at least 2 bytes for the marker */
|
||||
buf_size = gst_adapter_available (adapter);
|
||||
if (buf_size < 2)
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
|
||||
|
||||
buf = gst_adapter_map (adapter, buf_size);
|
||||
if (!buf)
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
|
||||
|
||||
ofs1 = ps->input_offset1 - 2;
|
||||
if (ofs1 < 0)
|
||||
ofs1 = 0;
|
||||
|
||||
for (;;) {
|
||||
// Skip any garbage until we reach SOI, if needed
|
||||
if (!gst_jpeg_parse (&seg, buf, buf_size, ofs1)) {
|
||||
gst_adapter_unmap (adapter);
|
||||
ps->input_offset1 = buf_size;
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
|
||||
}
|
||||
ofs1 = seg.offset;
|
||||
|
||||
marker = seg.marker;
|
||||
if (!VALID_STATE (parser, GOT_SOI) && marker != GST_JPEG_MARKER_SOI)
|
||||
continue;
|
||||
if (marker == GST_JPEG_MARKER_SOS) {
|
||||
ofs2 = ps->input_offset2 - 2;
|
||||
if (ofs2 < ofs1 + seg.size)
|
||||
ofs2 = ofs1 + seg.size;
|
||||
|
||||
// Parse the whole scan + ECSs, including RSTi
|
||||
for (;;) {
|
||||
if (!gst_jpeg_parse (&seg, buf, buf_size, ofs2)) {
|
||||
gst_adapter_unmap (adapter);
|
||||
ps->input_offset1 = ofs1;
|
||||
ps->input_offset2 = buf_size;
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
|
||||
}
|
||||
|
||||
if (is_scan_complete (seg.marker))
|
||||
break;
|
||||
ofs2 = seg.offset + seg.size;
|
||||
}
|
||||
ofs2 = seg.offset - 2;
|
||||
} else {
|
||||
// Check that the whole segment is actually available (in buffer)
|
||||
ofs2 = ofs1 + seg.size;
|
||||
if (ofs2 > buf_size) {
|
||||
gst_adapter_unmap (adapter);
|
||||
ps->input_offset1 = ofs1;
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
gst_adapter_unmap (adapter);
|
||||
|
||||
unit->size = ofs2 - ofs1;
|
||||
unit_set_marker_code (unit, marker);
|
||||
gst_adapter_flush (adapter, ofs1);
|
||||
ps->input_offset1 = 2;
|
||||
ps->input_offset2 = 2;
|
||||
|
||||
flags = 0;
|
||||
switch (marker) {
|
||||
case GST_JPEG_MARKER_SOI:
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
|
||||
priv->parser_state |= GST_JPEG_VIDEO_STATE_GOT_SOI;
|
||||
break;
|
||||
case GST_JPEG_MARKER_EOI:
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END;
|
||||
priv->parser_state = 0;
|
||||
break;
|
||||
case GST_JPEG_MARKER_SOS:
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
|
||||
priv->parser_state |= GST_JPEG_VIDEO_STATE_GOT_SOS;
|
||||
break;
|
||||
case GST_JPEG_MARKER_DAC:
|
||||
case GST_JPEG_MARKER_DHT:
|
||||
case GST_JPEG_MARKER_DQT:
|
||||
if (priv->parser_state & GST_JPEG_VIDEO_STATE_GOT_SOF)
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
|
||||
break;
|
||||
case GST_JPEG_MARKER_DRI:
|
||||
if (priv->parser_state & GST_JPEG_VIDEO_STATE_GOT_SOS)
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
|
||||
break;
|
||||
case GST_JPEG_MARKER_DNL:
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
|
||||
break;
|
||||
case GST_JPEG_MARKER_COM:
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
|
||||
break;
|
||||
default:
|
||||
/* SOFn segments */
|
||||
if (marker >= GST_JPEG_MARKER_SOF_MIN &&
|
||||
marker <= GST_JPEG_MARKER_SOF_MAX)
|
||||
priv->parser_state |= GST_JPEG_VIDEO_STATE_GOT_SOF;
|
||||
|
||||
/* Application segments */
|
||||
else if (marker >= GST_JPEG_MARKER_APP_MIN &&
|
||||
marker <= GST_JPEG_MARKER_APP_MAX)
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
|
||||
|
||||
/* Reserved */
|
||||
else if (marker >= 0x02 && marker <= 0xbf)
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
|
||||
break;
|
||||
}
|
||||
GST_VAAPI_DECODER_UNIT_FLAG_SET (unit, flags);
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_jpeg_decode (GstVaapiDecoder * base_decoder,
|
||||
GstVaapiDecoderUnit * unit)
|
||||
{
|
||||
GstVaapiDecoderJpeg *const decoder =
|
||||
GST_VAAPI_DECODER_JPEG_CAST (base_decoder);
|
||||
GstVaapiDecoderStatus status;
|
||||
GstJpegSegment seg;
|
||||
GstBuffer *const buffer =
|
||||
GST_VAAPI_DECODER_CODEC_FRAME (decoder)->input_buffer;
|
||||
GstMapInfo map_info;
|
||||
|
||||
status = ensure_decoder (decoder);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) {
|
||||
GST_ERROR ("failed to map buffer");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
seg.marker = unit_get_marker_code (unit);
|
||||
seg.data = map_info.data;
|
||||
seg.offset = unit->offset;
|
||||
seg.size = unit->size;
|
||||
|
||||
status = decode_segment (decoder, &seg);
|
||||
gst_buffer_unmap (buffer, &map_info);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_jpeg_start_frame (GstVaapiDecoder * base_decoder,
|
||||
GstVaapiDecoderUnit * base_unit)
|
||||
{
|
||||
GstVaapiDecoderJpeg *const decoder =
|
||||
GST_VAAPI_DECODER_JPEG_CAST (base_decoder);
|
||||
GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
|
||||
GstVaapiPicture *picture;
|
||||
GstVaapiDecoderStatus status;
|
||||
|
||||
if (!VALID_STATE (decoder, GOT_SOF))
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
|
||||
status = ensure_context (decoder);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
|
||||
GST_ERROR ("failed to reset context");
|
||||
return status;
|
||||
}
|
||||
|
||||
picture = GST_VAAPI_PICTURE_NEW (JPEGBaseline, decoder);
|
||||
if (!picture) {
|
||||
GST_ERROR ("failed to allocate picture");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
gst_vaapi_picture_replace (&priv->current_picture, picture);
|
||||
gst_vaapi_picture_unref (picture);
|
||||
|
||||
if (!fill_picture (decoder, picture, &priv->frame_hdr))
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
|
||||
status = fill_quantization_table (decoder, picture);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
/* Update presentation time */
|
||||
picture->pts = GST_VAAPI_DECODER_CODEC_FRAME (decoder)->pts;
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_jpeg_end_frame (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
GstVaapiDecoderJpeg *const decoder =
|
||||
GST_VAAPI_DECODER_JPEG_CAST (base_decoder);
|
||||
|
||||
return decode_current_picture (decoder);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_jpeg_finalize (GObject * object)
|
||||
{
|
||||
GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (object);
|
||||
|
||||
gst_vaapi_decoder_jpeg_destroy (base_decoder);
|
||||
G_OBJECT_CLASS (gst_vaapi_decoder_jpeg_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_jpeg_class_init (GstVaapiDecoderJpegClass * klass)
|
||||
{
|
||||
GObjectClass *const object_class = G_OBJECT_CLASS (klass);
|
||||
GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass);
|
||||
|
||||
object_class->finalize = gst_vaapi_decoder_jpeg_finalize;
|
||||
|
||||
decoder_class->reset = gst_vaapi_decoder_jpeg_reset;
|
||||
decoder_class->parse = gst_vaapi_decoder_jpeg_parse;
|
||||
decoder_class->decode = gst_vaapi_decoder_jpeg_decode;
|
||||
decoder_class->start_frame = gst_vaapi_decoder_jpeg_start_frame;
|
||||
decoder_class->end_frame = gst_vaapi_decoder_jpeg_end_frame;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_jpeg_init (GstVaapiDecoderJpeg * decoder)
|
||||
{
|
||||
GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder);
|
||||
|
||||
gst_vaapi_decoder_jpeg_create (base_decoder);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_decoder_jpeg_new:
|
||||
* @display: a #GstVaapiDisplay
|
||||
* @caps: a #GstCaps holding codec information
|
||||
*
|
||||
* Creates a new #GstVaapiDecoder for JPEG decoding. The @caps can
|
||||
* hold extra information like codec-data and pictured coded size.
|
||||
*
|
||||
* Return value: the newly allocated #GstVaapiDecoder object
|
||||
*/
|
||||
GstVaapiDecoder *
|
||||
gst_vaapi_decoder_jpeg_new (GstVaapiDisplay * display, GstCaps * caps)
|
||||
{
|
||||
return g_object_new (GST_TYPE_VAAPI_DECODER_JPEG, "display", display,
|
||||
"caps", caps, NULL);
|
||||
}
|
51
gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h
Normal file
51
gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* gstvaapidecoder_jpeg.h - JPEG decoder
|
||||
*
|
||||
* Copyright (C) 2011-2013 Intel Corporation
|
||||
* Author: Wind Yuan <feng.yuan@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DECODER_JPEG_H
|
||||
#define GST_VAAPI_DECODER_JPEG_H
|
||||
|
||||
#include <gst/vaapi/gstvaapidecoder.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_DECODER_JPEG \
|
||||
(gst_vaapi_decoder_jpeg_get_type ())
|
||||
#define GST_VAAPI_DECODER_JPEG(decoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DECODER_JPEG, GstVaapiDecoderJpeg))
|
||||
#define GST_VAAPI_IS_DECODER_JPEG(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_DECODER_JPEG))
|
||||
|
||||
typedef struct _GstVaapiDecoderJpeg GstVaapiDecoderJpeg;
|
||||
|
||||
GType
|
||||
gst_vaapi_decoder_jpeg_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GstVaapiDecoder *
|
||||
gst_vaapi_decoder_jpeg_new (GstVaapiDisplay *display, GstCaps *caps);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDecoderJpeg, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DECODER_JPEG_H */
|
||||
|
1624
gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c
Normal file
1624
gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c
Normal file
File diff suppressed because it is too large
Load diff
50
gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h
Normal file
50
gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* gstvaapidecoder_mpeg2.h - MPEG-2 decoder
|
||||
*
|
||||
* Copyright (C) 2011-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DECODER_MPEG2_H
|
||||
#define GST_VAAPI_DECODER_MPEG2_H
|
||||
|
||||
#include <gst/vaapi/gstvaapidecoder.h>
|
||||
#include <gst/base/gstadapter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_DECODER_MPEG2 \
|
||||
(gst_vaapi_decoder_mpeg2_get_type ())
|
||||
#define GST_VAAPI_DECODER_MPEG2(decoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DECODER_MPEG2, GstVaapiDecoderMpeg2))
|
||||
#define GST_VAAPI_IS_DECODER_MPEG2(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_DECODER_MPEG2))
|
||||
|
||||
typedef struct _GstVaapiDecoderMpeg2 GstVaapiDecoderMpeg2;
|
||||
|
||||
GType
|
||||
gst_vaapi_decoder_mpeg2_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GstVaapiDecoder *
|
||||
gst_vaapi_decoder_mpeg2_new (GstVaapiDisplay *display, GstCaps *caps);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDecoderMpeg2, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DECODER_MPEG2_H */
|
1215
gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c
Normal file
1215
gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c
Normal file
File diff suppressed because it is too large
Load diff
49
gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h
Normal file
49
gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* gstvaapidecoder_mpeg4.h - MPEG-4 decoder
|
||||
*
|
||||
* Copyright (C) 2011-2013 Intel Corporation
|
||||
* Author: Halley Zhao <halley.zhao@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DECODER_MPEG4_H
|
||||
#define GST_VAAPI_DECODER_MPEG4_H
|
||||
|
||||
#include <gst/vaapi/gstvaapidecoder.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_DECODER_MPEG4 \
|
||||
(gst_vaapi_decoder_mpeg4_get_type ())
|
||||
#define GST_VAAPI_DECODER_MPEG4(decoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DECODER_MPEG4, GstVaapiDecoderMpeg4))
|
||||
#define GST_VAAPI_IS_DECODER_MPEG4(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_DECODER_MPEG4))
|
||||
|
||||
typedef struct _GstVaapiDecoderMpeg4 GstVaapiDecoderMpeg4;
|
||||
|
||||
GType
|
||||
gst_vaapi_decoder_mpeg4_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GstVaapiDecoder *
|
||||
gst_vaapi_decoder_mpeg4_new (GstVaapiDisplay *display, GstCaps *caps);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDecoderMpeg4, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DECODER_MPEG4_H */
|
507
gst-libs/gst/vaapi/gstvaapidecoder_objects.c
Normal file
507
gst-libs/gst/vaapi/gstvaapidecoder_objects.c
Normal file
|
@ -0,0 +1,507 @@
|
|||
/*
|
||||
* gstvaapidecoder_objects.c - VA decoder objects helpers
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||
* Copyright (C) 2011-2014 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include <gst/vaapi/gstvaapicontext.h>
|
||||
#include "gstvaapidecoder_objects.h"
|
||||
#include "gstvaapidecoder_priv.h"
|
||||
#include "gstvaapisurfaceproxy_priv.h"
|
||||
#include "gstvaapicompat.h"
|
||||
#include "gstvaapiutils.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
#define GET_DECODER(obj) GST_VAAPI_DECODER_CAST((obj)->parent_instance.codec)
|
||||
#define GET_CONTEXT(obj) GET_DECODER(obj)->context
|
||||
#define GET_VA_DISPLAY(obj) GET_DECODER(obj)->va_display
|
||||
#define GET_VA_CONTEXT(obj) GET_DECODER(obj)->va_context
|
||||
|
||||
static inline void
|
||||
gst_video_codec_frame_clear (GstVideoCodecFrame ** frame_ptr)
|
||||
{
|
||||
if (!*frame_ptr)
|
||||
return;
|
||||
gst_video_codec_frame_unref (*frame_ptr);
|
||||
*frame_ptr = NULL;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Pictures --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiPicture, gst_vaapi_picture);
|
||||
|
||||
enum
|
||||
{
|
||||
GST_VAAPI_CREATE_PICTURE_FLAG_CLONE = 1 << 0,
|
||||
GST_VAAPI_CREATE_PICTURE_FLAG_FIELD = 1 << 1,
|
||||
};
|
||||
|
||||
void
|
||||
gst_vaapi_picture_destroy (GstVaapiPicture * picture)
|
||||
{
|
||||
if (picture->slices) {
|
||||
g_ptr_array_unref (picture->slices);
|
||||
picture->slices = NULL;
|
||||
}
|
||||
|
||||
gst_vaapi_codec_object_replace (&picture->iq_matrix, NULL);
|
||||
gst_vaapi_codec_object_replace (&picture->huf_table, NULL);
|
||||
gst_vaapi_codec_object_replace (&picture->bitplane, NULL);
|
||||
gst_vaapi_codec_object_replace (&picture->prob_table, NULL);
|
||||
|
||||
if (picture->proxy) {
|
||||
gst_vaapi_surface_proxy_unref (picture->proxy);
|
||||
picture->proxy = NULL;
|
||||
}
|
||||
picture->surface_id = VA_INVALID_ID;
|
||||
picture->surface = NULL;
|
||||
|
||||
vaapi_destroy_buffer (GET_VA_DISPLAY (picture), &picture->param_id);
|
||||
picture->param = NULL;
|
||||
|
||||
gst_video_codec_frame_clear (&picture->frame);
|
||||
gst_vaapi_picture_replace (&picture->parent_picture, NULL);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_picture_create (GstVaapiPicture * picture,
|
||||
const GstVaapiCodecObjectConstructorArgs * args)
|
||||
{
|
||||
gboolean success;
|
||||
|
||||
picture->param_id = VA_INVALID_ID;
|
||||
|
||||
if (args->flags & GST_VAAPI_CREATE_PICTURE_FLAG_CLONE) {
|
||||
GstVaapiPicture *const parent_picture = GST_VAAPI_PICTURE (args->data);
|
||||
|
||||
picture->parent_picture = gst_vaapi_picture_ref (parent_picture);
|
||||
|
||||
picture->proxy = gst_vaapi_surface_proxy_ref (parent_picture->proxy);
|
||||
picture->type = parent_picture->type;
|
||||
picture->pts = parent_picture->pts;
|
||||
picture->poc = parent_picture->poc;
|
||||
picture->voc = parent_picture->voc;
|
||||
picture->view_id = parent_picture->view_id;
|
||||
|
||||
// Copy all picture flags but "output"
|
||||
GST_VAAPI_PICTURE_FLAG_SET (picture,
|
||||
GST_VAAPI_PICTURE_FLAGS (parent_picture) &
|
||||
(GST_VAAPI_PICTURE_FLAG_SKIPPED |
|
||||
GST_VAAPI_PICTURE_FLAG_REFERENCE |
|
||||
GST_VAAPI_PICTURE_FLAG_INTERLACED |
|
||||
GST_VAAPI_PICTURE_FLAG_FF | GST_VAAPI_PICTURE_FLAG_TFF |
|
||||
GST_VAAPI_PICTURE_FLAG_ONEFIELD |
|
||||
GST_VAAPI_PICTURE_FLAG_RFF | GST_VAAPI_PICTURE_FLAG_MVC));
|
||||
|
||||
// Propagate "corrupted" flag while not presuming that the second
|
||||
// field is itself corrupted if the first one was marked as such
|
||||
if (GST_VAAPI_PICTURE_IS_CORRUPTED (parent_picture) &&
|
||||
!(args->flags & GST_VAAPI_CREATE_PICTURE_FLAG_FIELD))
|
||||
GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_CORRUPTED);
|
||||
|
||||
picture->structure = parent_picture->structure;
|
||||
if ((args->flags & GST_VAAPI_CREATE_PICTURE_FLAG_FIELD) &&
|
||||
GST_VAAPI_PICTURE_IS_INTERLACED (picture)) {
|
||||
switch (picture->structure) {
|
||||
case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
|
||||
picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
|
||||
break;
|
||||
case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
|
||||
picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
|
||||
break;
|
||||
}
|
||||
GST_VAAPI_PICTURE_FLAG_UNSET (picture, GST_VAAPI_PICTURE_FLAG_FF);
|
||||
}
|
||||
|
||||
if (parent_picture->has_crop_rect) {
|
||||
picture->has_crop_rect = TRUE;
|
||||
picture->crop_rect = parent_picture->crop_rect;
|
||||
}
|
||||
} else {
|
||||
picture->type = GST_VAAPI_PICTURE_TYPE_NONE;
|
||||
picture->pts = GST_CLOCK_TIME_NONE;
|
||||
|
||||
picture->proxy =
|
||||
gst_vaapi_context_get_surface_proxy (GET_CONTEXT (picture));
|
||||
if (!picture->proxy)
|
||||
return FALSE;
|
||||
|
||||
picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
|
||||
GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_FF);
|
||||
}
|
||||
picture->surface = GST_VAAPI_SURFACE_PROXY_SURFACE (picture->proxy);
|
||||
picture->surface_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (picture->proxy);
|
||||
|
||||
success = vaapi_create_buffer (GET_VA_DISPLAY (picture),
|
||||
GET_VA_CONTEXT (picture), VAPictureParameterBufferType,
|
||||
args->param_size, args->param, &picture->param_id, &picture->param);
|
||||
if (!success)
|
||||
return FALSE;
|
||||
picture->param_size = args->param_size;
|
||||
|
||||
picture->slices = g_ptr_array_new_with_free_func ((GDestroyNotify)
|
||||
gst_vaapi_mini_object_unref);
|
||||
if (!picture->slices)
|
||||
return FALSE;
|
||||
|
||||
picture->frame =
|
||||
gst_video_codec_frame_ref (GST_VAAPI_DECODER_CODEC_FRAME (GET_DECODER
|
||||
(picture)));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstVaapiPicture *
|
||||
gst_vaapi_picture_new (GstVaapiDecoder * decoder,
|
||||
gconstpointer param, guint param_size)
|
||||
{
|
||||
GstVaapiCodecObject *object;
|
||||
|
||||
object = gst_vaapi_codec_object_new (&GstVaapiPictureClass,
|
||||
GST_VAAPI_CODEC_BASE (decoder), param, param_size, NULL, 0, 0);
|
||||
if (!object)
|
||||
return NULL;
|
||||
return GST_VAAPI_PICTURE_CAST (object);
|
||||
}
|
||||
|
||||
GstVaapiPicture *
|
||||
gst_vaapi_picture_new_field (GstVaapiPicture * picture)
|
||||
{
|
||||
GstVaapiDecoder *const decoder = GET_DECODER (picture);
|
||||
GstVaapiCodecObject *object;
|
||||
|
||||
object = gst_vaapi_codec_object_new (gst_vaapi_codec_object_get_class
|
||||
(&picture->parent_instance), GST_VAAPI_CODEC_BASE (decoder), NULL,
|
||||
picture->param_size, picture, 0,
|
||||
(GST_VAAPI_CREATE_PICTURE_FLAG_CLONE |
|
||||
GST_VAAPI_CREATE_PICTURE_FLAG_FIELD));
|
||||
if (!object)
|
||||
return NULL;
|
||||
return GST_VAAPI_PICTURE_CAST (object);
|
||||
}
|
||||
|
||||
GstVaapiPicture *
|
||||
gst_vaapi_picture_new_clone (GstVaapiPicture * picture)
|
||||
{
|
||||
GstVaapiDecoder *const decoder = GET_DECODER (picture);
|
||||
GstVaapiCodecObject *object;
|
||||
|
||||
object = gst_vaapi_codec_object_new (gst_vaapi_codec_object_get_class
|
||||
(&picture->parent_instance), GST_VAAPI_CODEC_BASE (decoder), NULL,
|
||||
picture->param_size, picture, 0, GST_VAAPI_CREATE_PICTURE_FLAG_CLONE);
|
||||
if (!object)
|
||||
return NULL;
|
||||
return GST_VAAPI_PICTURE_CAST (object);
|
||||
}
|
||||
|
||||
void
|
||||
gst_vaapi_picture_add_slice (GstVaapiPicture * picture, GstVaapiSlice * slice)
|
||||
{
|
||||
g_return_if_fail (GST_VAAPI_IS_PICTURE (picture));
|
||||
g_return_if_fail (GST_VAAPI_IS_SLICE (slice));
|
||||
|
||||
g_ptr_array_add (picture->slices, slice);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
do_decode (VADisplay dpy, VAContextID ctx, VABufferID * buf_id, void **buf_ptr)
|
||||
{
|
||||
VAStatus status;
|
||||
|
||||
vaapi_unmap_buffer (dpy, *buf_id, buf_ptr);
|
||||
|
||||
status = vaRenderPicture (dpy, ctx, buf_id, 1);
|
||||
if (!vaapi_check_status (status, "vaRenderPicture()"))
|
||||
return FALSE;
|
||||
|
||||
/* XXX: vaRenderPicture() is meant to destroy the VA buffer implicitly */
|
||||
vaapi_destroy_buffer (dpy, buf_id);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_picture_decode_with_surface_id (GstVaapiPicture * picture,
|
||||
VASurfaceID surface_id)
|
||||
{
|
||||
GstVaapiIqMatrix *iq_matrix;
|
||||
GstVaapiBitPlane *bitplane;
|
||||
GstVaapiHuffmanTable *huf_table;
|
||||
GstVaapiProbabilityTable *prob_table;
|
||||
VADisplay va_display;
|
||||
VAContextID va_context;
|
||||
VAStatus status;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (GST_VAAPI_IS_PICTURE (picture), FALSE);
|
||||
g_return_val_if_fail (surface_id != VA_INVALID_SURFACE, FALSE);
|
||||
|
||||
va_display = GET_VA_DISPLAY (picture);
|
||||
va_context = GET_VA_CONTEXT (picture);
|
||||
|
||||
GST_DEBUG ("decode picture 0x%08x", surface_id);
|
||||
|
||||
status = vaBeginPicture (va_display, va_context, surface_id);
|
||||
if (!vaapi_check_status (status, "vaBeginPicture()"))
|
||||
return FALSE;
|
||||
|
||||
if (!do_decode (va_display, va_context, &picture->param_id, &picture->param))
|
||||
return FALSE;
|
||||
|
||||
iq_matrix = picture->iq_matrix;
|
||||
if (iq_matrix && !do_decode (va_display, va_context,
|
||||
&iq_matrix->param_id, &iq_matrix->param))
|
||||
return FALSE;
|
||||
|
||||
bitplane = picture->bitplane;
|
||||
if (bitplane && !do_decode (va_display, va_context,
|
||||
&bitplane->data_id, (void **) &bitplane->data))
|
||||
return FALSE;
|
||||
|
||||
huf_table = picture->huf_table;
|
||||
if (huf_table && !do_decode (va_display, va_context,
|
||||
&huf_table->param_id, (void **) &huf_table->param))
|
||||
return FALSE;
|
||||
|
||||
prob_table = picture->prob_table;
|
||||
if (prob_table && !do_decode (va_display, va_context,
|
||||
&prob_table->param_id, (void **) &prob_table->param))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < picture->slices->len; i++) {
|
||||
GstVaapiSlice *const slice = g_ptr_array_index (picture->slices, i);
|
||||
VABufferID va_buffers[2];
|
||||
|
||||
huf_table = slice->huf_table;
|
||||
if (huf_table && !do_decode (va_display, va_context,
|
||||
&huf_table->param_id, (void **) &huf_table->param))
|
||||
return FALSE;
|
||||
|
||||
vaapi_unmap_buffer (va_display, slice->param_id, NULL);
|
||||
va_buffers[0] = slice->param_id;
|
||||
va_buffers[1] = slice->data_id;
|
||||
|
||||
status = vaRenderPicture (va_display, va_context, va_buffers, 2);
|
||||
if (!vaapi_check_status (status, "vaRenderPicture()"))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
status = vaEndPicture (va_display, va_context);
|
||||
|
||||
for (i = 0; i < picture->slices->len; i++) {
|
||||
GstVaapiSlice *const slice = g_ptr_array_index (picture->slices, i);
|
||||
|
||||
vaapi_destroy_buffer (va_display, &slice->param_id);
|
||||
vaapi_destroy_buffer (va_display, &slice->data_id);
|
||||
}
|
||||
|
||||
if (!vaapi_check_status (status, "vaEndPicture()"))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_picture_decode (GstVaapiPicture * picture)
|
||||
{
|
||||
g_return_val_if_fail (GST_VAAPI_IS_PICTURE (picture), FALSE);
|
||||
|
||||
return gst_vaapi_picture_decode_with_surface_id (picture,
|
||||
picture->surface_id);
|
||||
}
|
||||
|
||||
/* Mark picture as output for internal purposes only. Don't push frame out */
|
||||
static void
|
||||
do_output_internal (GstVaapiPicture * picture)
|
||||
{
|
||||
if (GST_VAAPI_PICTURE_IS_OUTPUT (picture))
|
||||
return;
|
||||
|
||||
gst_video_codec_frame_clear (&picture->frame);
|
||||
GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_OUTPUT);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
do_output (GstVaapiPicture * picture)
|
||||
{
|
||||
GstVideoCodecFrame *const out_frame = picture->frame;
|
||||
GstVaapiSurfaceProxy *proxy;
|
||||
guint flags = 0;
|
||||
|
||||
if (GST_VAAPI_PICTURE_IS_OUTPUT (picture))
|
||||
return TRUE;
|
||||
|
||||
if (!picture->proxy)
|
||||
return FALSE;
|
||||
|
||||
proxy = gst_vaapi_surface_proxy_ref (picture->proxy);
|
||||
|
||||
if (picture->has_crop_rect)
|
||||
gst_vaapi_surface_proxy_set_crop_rect (proxy, &picture->crop_rect);
|
||||
|
||||
gst_video_codec_frame_set_user_data (out_frame,
|
||||
proxy, (GDestroyNotify) gst_vaapi_mini_object_unref);
|
||||
|
||||
out_frame->pts = picture->pts;
|
||||
|
||||
if (GST_VAAPI_PICTURE_IS_SKIPPED (picture))
|
||||
GST_VIDEO_CODEC_FRAME_FLAG_SET (out_frame,
|
||||
GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY);
|
||||
|
||||
if (GST_VAAPI_PICTURE_IS_CORRUPTED (picture))
|
||||
flags |= GST_VAAPI_SURFACE_PROXY_FLAG_CORRUPTED;
|
||||
|
||||
if (GST_VAAPI_PICTURE_IS_MVC (picture)) {
|
||||
if (picture->voc == 0)
|
||||
flags |= GST_VAAPI_SURFACE_PROXY_FLAG_FFB;
|
||||
GST_VAAPI_SURFACE_PROXY_VIEW_ID (proxy) = picture->view_id;
|
||||
}
|
||||
|
||||
if (GST_VAAPI_PICTURE_IS_INTERLACED (picture)) {
|
||||
flags |= GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED;
|
||||
if (GST_VAAPI_PICTURE_IS_TFF (picture))
|
||||
flags |= GST_VAAPI_SURFACE_PROXY_FLAG_TFF;
|
||||
if (GST_VAAPI_PICTURE_IS_RFF (picture))
|
||||
flags |= GST_VAAPI_SURFACE_PROXY_FLAG_RFF;
|
||||
if (GST_VAAPI_PICTURE_IS_ONEFIELD (picture))
|
||||
flags |= GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD;
|
||||
}
|
||||
GST_VAAPI_SURFACE_PROXY_FLAG_SET (proxy, flags);
|
||||
|
||||
gst_vaapi_decoder_push_frame (GET_DECODER (picture), out_frame);
|
||||
gst_video_codec_frame_clear (&picture->frame);
|
||||
|
||||
GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_OUTPUT);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_picture_output (GstVaapiPicture * picture)
|
||||
{
|
||||
g_return_val_if_fail (GST_VAAPI_IS_PICTURE (picture), FALSE);
|
||||
|
||||
if (G_UNLIKELY (picture->parent_picture)) {
|
||||
/* Emit the first field to GstVideoDecoder so that to release
|
||||
the underlying GstVideoCodecFrame. However, mark this
|
||||
picture as skipped so that to not display it */
|
||||
GstVaapiPicture *const parent_picture = picture->parent_picture;
|
||||
do {
|
||||
if (!GST_VAAPI_PICTURE_IS_INTERLACED (parent_picture))
|
||||
break;
|
||||
if (!GST_VAAPI_PICTURE_IS_FIRST_FIELD (parent_picture))
|
||||
break;
|
||||
if (parent_picture->frame == picture->frame)
|
||||
do_output_internal (parent_picture);
|
||||
else {
|
||||
GST_VAAPI_PICTURE_FLAG_SET (parent_picture,
|
||||
GST_VAAPI_PICTURE_FLAG_SKIPPED);
|
||||
if (!do_output (parent_picture))
|
||||
return FALSE;
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
return do_output (picture);
|
||||
}
|
||||
|
||||
void
|
||||
gst_vaapi_picture_set_crop_rect (GstVaapiPicture * picture,
|
||||
const GstVaapiRectangle * crop_rect)
|
||||
{
|
||||
g_return_if_fail (GST_VAAPI_IS_PICTURE (picture));
|
||||
|
||||
picture->has_crop_rect = crop_rect != NULL;
|
||||
if (picture->has_crop_rect)
|
||||
picture->crop_rect = *crop_rect;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Slices --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiSlice, gst_vaapi_slice);
|
||||
|
||||
void
|
||||
gst_vaapi_slice_destroy (GstVaapiSlice * slice)
|
||||
{
|
||||
VADisplay const va_display = GET_VA_DISPLAY (slice);
|
||||
|
||||
gst_vaapi_codec_object_replace (&slice->huf_table, NULL);
|
||||
|
||||
vaapi_destroy_buffer (va_display, &slice->data_id);
|
||||
vaapi_destroy_buffer (va_display, &slice->param_id);
|
||||
slice->param = NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_slice_create (GstVaapiSlice * slice,
|
||||
const GstVaapiCodecObjectConstructorArgs * args)
|
||||
{
|
||||
VASliceParameterBufferBase *slice_param;
|
||||
gboolean success;
|
||||
|
||||
slice->param_id = VA_INVALID_ID;
|
||||
slice->data_id = VA_INVALID_ID;
|
||||
|
||||
success = vaapi_create_buffer (GET_VA_DISPLAY (slice), GET_VA_CONTEXT (slice),
|
||||
VASliceDataBufferType, args->data_size, args->data, &slice->data_id,
|
||||
NULL);
|
||||
if (!success)
|
||||
return FALSE;
|
||||
|
||||
g_assert (args->param_num >= 1);
|
||||
success = vaapi_create_n_elements_buffer (GET_VA_DISPLAY (slice),
|
||||
GET_VA_CONTEXT (slice), VASliceParameterBufferType, args->param_size,
|
||||
args->param, &slice->param_id, &slice->param, args->param_num);
|
||||
if (!success)
|
||||
return FALSE;
|
||||
|
||||
slice_param = slice->param;
|
||||
slice_param->slice_data_size = args->data_size;
|
||||
slice_param->slice_data_offset = 0;
|
||||
slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstVaapiSlice *
|
||||
gst_vaapi_slice_new (GstVaapiDecoder * decoder,
|
||||
gconstpointer param, guint param_size, const guchar * data, guint data_size)
|
||||
{
|
||||
GstVaapiCodecObject *object;
|
||||
|
||||
object = gst_vaapi_codec_object_new (&GstVaapiSliceClass,
|
||||
GST_VAAPI_CODEC_BASE (decoder), param, param_size, data, data_size, 0);
|
||||
return GST_VAAPI_SLICE_CAST (object);
|
||||
}
|
||||
|
||||
GstVaapiSlice *
|
||||
gst_vaapi_slice_new_n_params (GstVaapiDecoder * decoder,
|
||||
gconstpointer param, guint param_size, guint param_num, const guchar * data,
|
||||
guint data_size)
|
||||
{
|
||||
GstVaapiCodecObject *object;
|
||||
|
||||
object = gst_vaapi_codec_object_new_with_param_num (&GstVaapiSliceClass,
|
||||
GST_VAAPI_CODEC_BASE (decoder), param, param_size, param_num, data,
|
||||
data_size, 0);
|
||||
return GST_VAAPI_SLICE_CAST (object);
|
||||
}
|
294
gst-libs/gst/vaapi/gstvaapidecoder_objects.h
Normal file
294
gst-libs/gst/vaapi/gstvaapidecoder_objects.h
Normal file
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
* gstvaapidecoder_objects.h - VA decoder objects
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||
* Copyright (C) 2011-2014 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DECODER_OBJECTS_H
|
||||
#define GST_VAAPI_DECODER_OBJECTS_H
|
||||
|
||||
#include <gst/vaapi/gstvaapicodec_objects.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstVaapiPicture GstVaapiPicture;
|
||||
typedef struct _GstVaapiSlice GstVaapiSlice;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Pictures --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_PICTURE_CAST(obj) \
|
||||
((GstVaapiPicture *) (obj))
|
||||
|
||||
#define GST_VAAPI_PICTURE(obj) \
|
||||
GST_VAAPI_PICTURE_CAST (obj)
|
||||
|
||||
#define GST_VAAPI_IS_PICTURE(obj) \
|
||||
(GST_VAAPI_PICTURE (obj) != NULL)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GST_VAAPI_PICTURE_TYPE_NONE = 0, // Undefined
|
||||
GST_VAAPI_PICTURE_TYPE_I, // Intra
|
||||
GST_VAAPI_PICTURE_TYPE_P, // Predicted
|
||||
GST_VAAPI_PICTURE_TYPE_B, // Bi-directional predicted
|
||||
GST_VAAPI_PICTURE_TYPE_S, // S(GMC)-VOP (MPEG-4)
|
||||
GST_VAAPI_PICTURE_TYPE_SI, // Switching Intra
|
||||
GST_VAAPI_PICTURE_TYPE_SP, // Switching Predicted
|
||||
GST_VAAPI_PICTURE_TYPE_BI, // BI type (VC-1)
|
||||
} GstVaapiPictureType;
|
||||
|
||||
/**
|
||||
* GstVaapiPictureFlags:
|
||||
* @GST_VAAPI_PICTURE_FLAG_SKIPPED: skipped frame
|
||||
* @GST_VAAPI_PICTURE_FLAG_REFERENCE: reference frame
|
||||
* @GST_VAAPI_PICTURE_FLAG_OUTPUT: frame was output
|
||||
* @GST_VAAPI_PICTURE_FLAG_INTERLACED: interlaced frame
|
||||
* @GST_VAAPI_PICTURE_FLAG_FF: first-field
|
||||
* @GST_VAAPI_PICTURE_FLAG_TFF: top-field-first
|
||||
* @GST_VAAPI_PICTURE_FLAG_ONEFIELD: only one field is valid
|
||||
* @GST_VAAPI_PICTURE_FLAG_MVC: multiview component
|
||||
* @GST_VAAPI_PICTURE_FLAG_RFF: repeat-first-field
|
||||
* @GST_VAAPI_PICTURE_FLAG_CORRUPTED: picture was reconstructed from
|
||||
* corrupted references
|
||||
* @GST_VAAPI_PICTURE_FLAG_LAST: first flag that can be used by subclasses
|
||||
*
|
||||
* Enum values used for #GstVaapiPicture flags.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GST_VAAPI_PICTURE_FLAG_SKIPPED = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 0),
|
||||
GST_VAAPI_PICTURE_FLAG_REFERENCE = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 1),
|
||||
GST_VAAPI_PICTURE_FLAG_OUTPUT = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 2),
|
||||
GST_VAAPI_PICTURE_FLAG_INTERLACED = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 3),
|
||||
GST_VAAPI_PICTURE_FLAG_FF = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 4),
|
||||
GST_VAAPI_PICTURE_FLAG_TFF = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 5),
|
||||
GST_VAAPI_PICTURE_FLAG_ONEFIELD = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 6),
|
||||
GST_VAAPI_PICTURE_FLAG_MVC = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 7),
|
||||
GST_VAAPI_PICTURE_FLAG_RFF = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 8),
|
||||
GST_VAAPI_PICTURE_FLAG_CORRUPTED = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 9),
|
||||
GST_VAAPI_PICTURE_FLAG_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 10),
|
||||
} GstVaapiPictureFlags;
|
||||
|
||||
#define GST_VAAPI_PICTURE_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS
|
||||
#define GST_VAAPI_PICTURE_FLAG_IS_SET GST_VAAPI_MINI_OBJECT_FLAG_IS_SET
|
||||
#define GST_VAAPI_PICTURE_FLAG_SET GST_VAAPI_MINI_OBJECT_FLAG_SET
|
||||
#define GST_VAAPI_PICTURE_FLAG_UNSET GST_VAAPI_MINI_OBJECT_FLAG_UNSET
|
||||
|
||||
#define GST_VAAPI_PICTURE_IS_SKIPPED(picture) \
|
||||
GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_SKIPPED)
|
||||
|
||||
#define GST_VAAPI_PICTURE_IS_REFERENCE(picture) \
|
||||
GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_REFERENCE)
|
||||
|
||||
#define GST_VAAPI_PICTURE_IS_OUTPUT(picture) \
|
||||
GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_OUTPUT)
|
||||
|
||||
#define GST_VAAPI_PICTURE_IS_INTERLACED(picture) \
|
||||
GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_INTERLACED)
|
||||
|
||||
#define GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture) \
|
||||
GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_FF)
|
||||
|
||||
#define GST_VAAPI_PICTURE_IS_TFF(picture) \
|
||||
GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_TFF)
|
||||
|
||||
#define GST_VAAPI_PICTURE_IS_RFF(picture) \
|
||||
GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_RFF)
|
||||
|
||||
#define GST_VAAPI_PICTURE_IS_ONEFIELD(picture) \
|
||||
GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_ONEFIELD)
|
||||
|
||||
#define GST_VAAPI_PICTURE_IS_FRAME(picture) \
|
||||
(GST_VAAPI_PICTURE (picture)->structure == GST_VAAPI_PICTURE_STRUCTURE_FRAME)
|
||||
|
||||
#define GST_VAAPI_PICTURE_IS_COMPLETE(picture) \
|
||||
(GST_VAAPI_PICTURE_IS_FRAME (picture) || \
|
||||
GST_VAAPI_PICTURE_IS_ONEFIELD (picture) || \
|
||||
!GST_VAAPI_PICTURE_IS_FIRST_FIELD (picture))
|
||||
|
||||
#define GST_VAAPI_PICTURE_IS_MVC(picture) \
|
||||
(GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_MVC))
|
||||
|
||||
#define GST_VAAPI_PICTURE_IS_CORRUPTED(picture) \
|
||||
(GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_CORRUPTED))
|
||||
|
||||
/**
|
||||
* GstVaapiPicture:
|
||||
*
|
||||
* A #GstVaapiCodecObject holding a picture parameter.
|
||||
*/
|
||||
struct _GstVaapiPicture
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiCodecObject parent_instance;
|
||||
GstVaapiPicture *parent_picture;
|
||||
GstVideoCodecFrame *frame;
|
||||
GstVaapiSurface *surface;
|
||||
GstVaapiSurfaceProxy *proxy;
|
||||
VABufferID param_id;
|
||||
guint param_size;
|
||||
|
||||
/*< public >*/
|
||||
GstVaapiPictureType type;
|
||||
VASurfaceID surface_id;
|
||||
gpointer param;
|
||||
GPtrArray *slices;
|
||||
GstVaapiIqMatrix *iq_matrix;
|
||||
GstVaapiHuffmanTable *huf_table;
|
||||
GstVaapiBitPlane *bitplane;
|
||||
GstVaapiProbabilityTable *prob_table;
|
||||
GstClockTime pts;
|
||||
gint32 poc;
|
||||
guint16 voc;
|
||||
guint16 view_id;
|
||||
guint structure;
|
||||
GstVaapiRectangle crop_rect;
|
||||
guint has_crop_rect:1;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_picture_destroy (GstVaapiPicture * picture);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_picture_create (GstVaapiPicture * picture,
|
||||
const GstVaapiCodecObjectConstructorArgs * args);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiPicture *
|
||||
gst_vaapi_picture_new (GstVaapiDecoder * decoder,
|
||||
gconstpointer param, guint param_size);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiPicture *
|
||||
gst_vaapi_picture_new_field (GstVaapiPicture * picture);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiPicture *
|
||||
gst_vaapi_picture_new_clone (GstVaapiPicture * picture);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_picture_add_slice (GstVaapiPicture * picture, GstVaapiSlice * slice);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_picture_decode (GstVaapiPicture * picture);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_picture_decode_with_surface_id (GstVaapiPicture * picture,
|
||||
VASurfaceID surface_id);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_picture_output (GstVaapiPicture * picture);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_picture_set_crop_rect (GstVaapiPicture * picture,
|
||||
const GstVaapiRectangle * crop_rect);
|
||||
|
||||
#define gst_vaapi_picture_ref(picture) \
|
||||
gst_vaapi_codec_object_ref (picture)
|
||||
|
||||
#define gst_vaapi_picture_unref(picture) \
|
||||
gst_vaapi_codec_object_unref (picture)
|
||||
|
||||
#define gst_vaapi_picture_replace(old_picture_ptr, new_picture) \
|
||||
gst_vaapi_codec_object_replace (old_picture_ptr, new_picture)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Slices --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_SLICE_CAST(obj) \
|
||||
((GstVaapiSlice *) (obj))
|
||||
|
||||
#define GST_VAAPI_SLICE(obj) \
|
||||
GST_VAAPI_SLICE_CAST (obj)
|
||||
|
||||
#define GST_VAAPI_IS_SLICE(obj) \
|
||||
(GST_VAAPI_SLICE (obj) != NULL)
|
||||
|
||||
/**
|
||||
* GstVaapiSlice:
|
||||
*
|
||||
* A #GstVaapiCodecObject holding a slice parameter.
|
||||
*/
|
||||
struct _GstVaapiSlice
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiCodecObject parent_instance;
|
||||
|
||||
/*< public >*/
|
||||
VABufferID param_id;
|
||||
VABufferID data_id;
|
||||
gpointer param;
|
||||
|
||||
/* Per-slice overrides */
|
||||
GstVaapiHuffmanTable *huf_table;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_slice_destroy (GstVaapiSlice * slice);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_slice_create (GstVaapiSlice * slice,
|
||||
const GstVaapiCodecObjectConstructorArgs * args);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiSlice *
|
||||
gst_vaapi_slice_new (GstVaapiDecoder * decoder, gconstpointer param,
|
||||
guint param_size, const guchar * data, guint data_size);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiSlice *
|
||||
gst_vaapi_slice_new_n_params (GstVaapiDecoder * decoder,
|
||||
gconstpointer param, guint param_size, guint param_num, const guchar * data,
|
||||
guint data_size);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Helpers to create codec-dependent objects --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_PICTURE_NEW(codec, decoder) \
|
||||
gst_vaapi_picture_new (GST_VAAPI_DECODER_CAST (decoder), \
|
||||
NULL, sizeof (G_PASTE (VAPictureParameterBuffer, codec)))
|
||||
|
||||
#define GST_VAAPI_SLICE_NEW(codec, decoder, buf, buf_size) \
|
||||
gst_vaapi_slice_new (GST_VAAPI_DECODER_CAST (decoder), \
|
||||
NULL, sizeof (G_PASTE (VASliceParameterBuffer, codec)), \
|
||||
buf, buf_size)
|
||||
|
||||
#define GST_VAAPI_SLICE_NEW_N_PARAMS(codec, decoder, buf, buf_size, n) \
|
||||
gst_vaapi_slice_new_n_params (GST_VAAPI_DECODER_CAST (decoder), \
|
||||
NULL, sizeof (G_PASTE (VASliceParameterBuffer, codec)), n, \
|
||||
buf, buf_size)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DECODER_OBJECTS_H */
|
275
gst-libs/gst/vaapi/gstvaapidecoder_priv.h
Normal file
275
gst-libs/gst/vaapi/gstvaapidecoder_priv.h
Normal file
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
* gstvaapidecoder_priv.h - VA decoder abstraction (private definitions)
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||
* Copyright (C) 2011-2014 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DECODER_PRIV_H
|
||||
#define GST_VAAPI_DECODER_PRIV_H
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include <gst/vaapi/gstvaapidecoder.h>
|
||||
#include <gst/vaapi/gstvaapidecoder_unit.h>
|
||||
#include <gst/vaapi/gstvaapicontext.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_DECODER_CAST(decoder) \
|
||||
((GstVaapiDecoder *)(decoder))
|
||||
|
||||
#define GST_VAAPI_DECODER_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_DECODER, GstVaapiDecoderClass))
|
||||
|
||||
#define GST_VAAPI_IS_DECODER_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_DECODER))
|
||||
|
||||
#define GST_VAAPI_DECODER_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_DECODER, GstVaapiDecoderClass))
|
||||
|
||||
typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass;
|
||||
|
||||
/**
|
||||
* GST_VAAPI_PARSER_STATE:
|
||||
* @decoder: a #GstVaapiDecoder
|
||||
*
|
||||
* Macro that evaluates to the #GstVaapiParserState of @decoder.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_PARSER_STATE
|
||||
#define GST_VAAPI_PARSER_STATE(decoder) \
|
||||
(&GST_VAAPI_DECODER_CAST(decoder)->parser_state)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DECODER_DISPLAY:
|
||||
* @decoder: a #GstVaapiDecoder
|
||||
*
|
||||
* Macro that evaluates to the #GstVaapiDisplay of @decoder.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_DECODER_DISPLAY
|
||||
#define GST_VAAPI_DECODER_DISPLAY(decoder) \
|
||||
GST_VAAPI_DECODER_CAST(decoder)->display
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DECODER_CONTEXT:
|
||||
* @decoder: a #GstVaapiDecoder
|
||||
*
|
||||
* Macro that evaluates to the #GstVaapiContext of @decoder.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_DECODER_CONTEXT
|
||||
#define GST_VAAPI_DECODER_CONTEXT(decoder) \
|
||||
GST_VAAPI_DECODER_CAST(decoder)->context
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DECODER_CODEC:
|
||||
* @decoder: a #GstVaapiDecoder
|
||||
*
|
||||
* Macro that evaluates to the #GstVaapiCodec of @decoder.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_DECODER_CODEC
|
||||
#define GST_VAAPI_DECODER_CODEC(decoder) \
|
||||
GST_VAAPI_DECODER_CAST(decoder)->codec
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DECODER_CODEC_STATE:
|
||||
* @decoder: a #GstVaapiDecoder
|
||||
*
|
||||
* Macro that evaluates to the #GstVideoCodecState holding codec state
|
||||
* for @decoder.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_DECODER_CODEC_STATE
|
||||
#define GST_VAAPI_DECODER_CODEC_STATE(decoder) \
|
||||
GST_VAAPI_DECODER_CAST(decoder)->codec_state
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DECODER_CODEC_DATA:
|
||||
* @decoder: a #GstVaapiDecoder
|
||||
*
|
||||
* Macro that evaluates to the #GstBuffer holding optional codec data
|
||||
* for @decoder.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_DECODER_CODEC_DATA
|
||||
#define GST_VAAPI_DECODER_CODEC_DATA(decoder) \
|
||||
GST_VAAPI_DECODER_CODEC_STATE(decoder)->codec_data
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DECODER_CODEC_FRAME:
|
||||
* @decoder: a #GstVaapiDecoder
|
||||
*
|
||||
* Macro that evaluates to the #GstVideoCodecFrame holding decoder
|
||||
* units for the current frame.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_DECODER_CODEC_FRAME
|
||||
#define GST_VAAPI_DECODER_CODEC_FRAME(decoder) \
|
||||
GST_VAAPI_PARSER_STATE(decoder)->current_frame
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DECODER_WIDTH:
|
||||
* @decoder: a #GstVaapiDecoder
|
||||
*
|
||||
* Macro that evaluates to the coded width of the picture
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_DECODER_WIDTH
|
||||
#define GST_VAAPI_DECODER_WIDTH(decoder) \
|
||||
GST_VAAPI_DECODER_CODEC_STATE(decoder)->info.width
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DECODER_HEIGHT:
|
||||
* @decoder: a #GstVaapiDecoder
|
||||
*
|
||||
* Macro that evaluates to the coded height of the picture
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_DECODER_HEIGHT
|
||||
#define GST_VAAPI_DECODER_HEIGHT(decoder) \
|
||||
GST_VAAPI_DECODER_CODEC_STATE(decoder)->info.height
|
||||
|
||||
/* End-of-Stream buffer */
|
||||
#define GST_BUFFER_FLAG_EOS (GST_BUFFER_FLAG_LAST + 0)
|
||||
|
||||
#define GST_BUFFER_IS_EOS(buffer) \
|
||||
GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_EOS)
|
||||
|
||||
#define GST_VAAPI_DECODER_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
|
||||
GST_VAAPI_TYPE_DECODER, \
|
||||
GstVaapiDecoderPrivate))
|
||||
|
||||
typedef enum {
|
||||
GST_VAAPI_DECODER_STATUS_DROP_FRAME = -2
|
||||
} GstVaapiDecoderStatusPrivate;
|
||||
|
||||
typedef struct _GstVaapiParserState GstVaapiParserState;
|
||||
struct _GstVaapiParserState
|
||||
{
|
||||
GstVideoCodecFrame *current_frame;
|
||||
guint32 current_frame_number;
|
||||
GstAdapter *current_adapter;
|
||||
GstAdapter *input_adapter;
|
||||
gint input_offset1;
|
||||
gint input_offset2;
|
||||
GstAdapter *output_adapter;
|
||||
GstVaapiDecoderUnit next_unit;
|
||||
guint next_unit_pending:1;
|
||||
guint at_eos:1;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDecoder:
|
||||
*
|
||||
* A VA decoder base instance.
|
||||
*/
|
||||
struct _GstVaapiDecoder
|
||||
{
|
||||
/*< private >*/
|
||||
GstObject parent_instance;
|
||||
|
||||
gpointer user_data;
|
||||
GstVaapiDisplay *display;
|
||||
VADisplay va_display;
|
||||
GstVaapiContext *context;
|
||||
VAContextID va_context;
|
||||
GstVaapiCodec codec;
|
||||
GstVideoCodecState *codec_state;
|
||||
GAsyncQueue *buffers;
|
||||
GAsyncQueue *frames;
|
||||
GstVaapiParserState parser_state;
|
||||
GstVaapiDecoderStateChangedFunc codec_state_changed_func;
|
||||
gpointer codec_state_changed_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDecoderClass:
|
||||
*
|
||||
* A VA decoder base class.
|
||||
*/
|
||||
struct _GstVaapiDecoderClass
|
||||
{
|
||||
/*< private >*/
|
||||
GstObjectClass parent_class;
|
||||
|
||||
GstVaapiDecoderStatus (*parse) (GstVaapiDecoder * decoder,
|
||||
GstAdapter * adapter, gboolean at_eos,
|
||||
struct _GstVaapiDecoderUnit * unit);
|
||||
GstVaapiDecoderStatus (*decode) (GstVaapiDecoder * decoder,
|
||||
struct _GstVaapiDecoderUnit * unit);
|
||||
GstVaapiDecoderStatus (*start_frame) (GstVaapiDecoder * decoder,
|
||||
struct _GstVaapiDecoderUnit * unit);
|
||||
GstVaapiDecoderStatus (*end_frame) (GstVaapiDecoder * decoder);
|
||||
GstVaapiDecoderStatus (*flush) (GstVaapiDecoder * decoder);
|
||||
GstVaapiDecoderStatus (*reset) (GstVaapiDecoder * decoder);
|
||||
GstVaapiDecoderStatus (*decode_codec_data) (GstVaapiDecoder * decoder,
|
||||
const guchar * buf, guint buf_size);
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_decoder_set_picture_size (GstVaapiDecoder * decoder,
|
||||
guint width, guint height);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_decoder_set_framerate (GstVaapiDecoder * decoder,
|
||||
guint fps_n, guint fps_d);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_decoder_set_pixel_aspect_ratio (GstVaapiDecoder * decoder,
|
||||
guint par_n, guint par_d);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_decoder_set_interlace_mode (GstVaapiDecoder * decoder,
|
||||
GstVideoInterlaceMode mode);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_decoder_set_interlaced (GstVaapiDecoder * decoder,
|
||||
gboolean interlaced);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_decoder_set_multiview_mode (GstVaapiDecoder * decoder,
|
||||
gint views, GstVideoMultiviewMode mv_mode, GstVideoMultiviewFlags mv_flags);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_decoder_ensure_context (GstVaapiDecoder * decoder,
|
||||
GstVaapiContextInfo * cip);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_decoder_push_frame (GstVaapiDecoder * decoder,
|
||||
GstVideoCodecFrame * frame);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_decode_codec_data (GstVaapiDecoder * decoder);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DECODER_PRIV_H */
|
89
gst-libs/gst/vaapi/gstvaapidecoder_unit.c
Normal file
89
gst-libs/gst/vaapi/gstvaapidecoder_unit.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* gstvaapidecoder_unit.c - VA decoder units
|
||||
*
|
||||
* Copyright (C) 2012-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstvaapidecoder_unit
|
||||
* @short_description: Decoder unit
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "gstvaapidecoder_unit.h"
|
||||
|
||||
/**
|
||||
* gst_vaapi_decoder_unit_init:
|
||||
* @unit: a #GstVaapiDecoderUnit
|
||||
*
|
||||
* Initializes internal resources bound to the supplied decoder @unit.
|
||||
*
|
||||
* @note This is an internal function used to implement lightweight
|
||||
* sub-classes.
|
||||
*/
|
||||
void
|
||||
gst_vaapi_decoder_unit_init (GstVaapiDecoderUnit * unit)
|
||||
{
|
||||
unit->flags = 0;
|
||||
unit->size = 0;
|
||||
unit->offset = 0;
|
||||
|
||||
unit->parsed_info = NULL;
|
||||
unit->parsed_info_destroy_notify = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_decoder_unit_clear:
|
||||
* @unit: a #GstVaapiDecoderUnit
|
||||
*
|
||||
* Deallocates any internal resources bound to the supplied decoder
|
||||
* @unit.
|
||||
*
|
||||
* @note This is an internal function used to implement lightweight
|
||||
* sub-classes.
|
||||
*/
|
||||
void
|
||||
gst_vaapi_decoder_unit_clear (GstVaapiDecoderUnit * unit)
|
||||
{
|
||||
gst_vaapi_decoder_unit_set_parsed_info (unit, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_decoder_unit_set_parsed_info:
|
||||
* @unit: a #GstVaapiDecoderUnit
|
||||
* @parsed_info: parser info
|
||||
* @destroy_notify: (closure parsed_info): a #GDestroyNotify
|
||||
*
|
||||
* Sets @parsed_info on the object and the #GDestroyNotify that will be
|
||||
* called when the data is freed.
|
||||
*
|
||||
* If some @parsed_info was previously set, then the former @destroy_notify
|
||||
* function will be called before the @parsed_info is replaced.
|
||||
*/
|
||||
void
|
||||
gst_vaapi_decoder_unit_set_parsed_info (GstVaapiDecoderUnit * unit,
|
||||
gpointer parsed_info, GDestroyNotify destroy_notify)
|
||||
{
|
||||
g_return_if_fail (GST_VAAPI_IS_DECODER_UNIT (unit));
|
||||
|
||||
if (unit->parsed_info && unit->parsed_info_destroy_notify)
|
||||
unit->parsed_info_destroy_notify (unit->parsed_info);
|
||||
unit->parsed_info = parsed_info;
|
||||
unit->parsed_info_destroy_notify = destroy_notify;
|
||||
}
|
189
gst-libs/gst/vaapi/gstvaapidecoder_unit.h
Normal file
189
gst-libs/gst/vaapi/gstvaapidecoder_unit.h
Normal file
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* gstvaapidecoder_unit.h - VA decoder units
|
||||
*
|
||||
* Copyright (C) 2012-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DECODER_UNIT_H
|
||||
#define GST_VAAPI_DECODER_UNIT_H
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstVaapiDecoderUnit GstVaapiDecoderUnit;
|
||||
|
||||
#define GST_VAAPI_DECODER_UNIT(unit) \
|
||||
((GstVaapiDecoderUnit *)(unit))
|
||||
|
||||
#define GST_VAAPI_IS_DECODER_UNIT(unit) \
|
||||
(GST_VAAPI_DECODER_UNIT(unit) != NULL)
|
||||
|
||||
/**
|
||||
* GstVaapiDecoderUnitFlags:
|
||||
* @GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START: marks the start of a frame.
|
||||
* @GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END: marks the end of a frame.
|
||||
* @GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END: marks the end of a stream.
|
||||
* @GST_VAAPI_DECODER_UNIT_FLAG_SLICE: the unit contains slice data.
|
||||
* @GST_VAAPI_DECODER_UNIT_FLAG_SKIP: marks the unit as unused/skipped.
|
||||
*
|
||||
* Flags for #GstVaapiDecoderUnit.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START = (1 << 0),
|
||||
GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END = (1 << 1),
|
||||
GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END = (1 << 2),
|
||||
GST_VAAPI_DECODER_UNIT_FLAG_SLICE = (1 << 3),
|
||||
GST_VAAPI_DECODER_UNIT_FLAG_SKIP = (1 << 4),
|
||||
GST_VAAPI_DECODER_UNIT_FLAG_LAST = (1 << 5)
|
||||
} GstVaapiDecoderUnitFlags;
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DECODER_UNIT_FLAGS:
|
||||
* @unit: a #GstVaapiDecoderUnit
|
||||
*
|
||||
* The entire set of flags for the @unit
|
||||
*/
|
||||
#define GST_VAAPI_DECODER_UNIT_FLAGS(unit) \
|
||||
((unit)->flags)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DECODER_UNIT_FLAG_IS_SET:
|
||||
* @unit: a #GstVaapiDecoderUnit
|
||||
* @flag: a flag to check for
|
||||
*
|
||||
* Checks whether the given @flag is set
|
||||
*/
|
||||
#define GST_VAAPI_DECODER_UNIT_FLAG_IS_SET(unit, flag) \
|
||||
((GST_VAAPI_DECODER_UNIT_FLAGS(unit) & (flag)) != 0)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DECODER_UNIT_FLAG_SET:
|
||||
* @unit: a #GstVaapiDecoderUnit
|
||||
* @flags: flags to set
|
||||
*
|
||||
* This macro sets the given bits
|
||||
*/
|
||||
#define GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags) \
|
||||
(GST_VAAPI_DECODER_UNIT_FLAGS(unit) |= (flags))
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DECODER_UNIT_FLAG_UNSET:
|
||||
* @unit: a #GstVaapiDecoderUnit
|
||||
* @flags: flags to unset
|
||||
*
|
||||
* This macro unsets the given bits.
|
||||
*/
|
||||
#define GST_VAAPI_DECODER_UNIT_FLAG_UNSET(unit, flags) \
|
||||
(GST_VAAPI_DECODER_UNIT_FLAGS(unit) &= ~(flags))
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DECODER_UNIT_IS_FRAME_START:
|
||||
* @unit: a #GstVaapiDecoderUnit
|
||||
*
|
||||
* Tests if the decoder unit marks the start of a frame.
|
||||
*
|
||||
* The start of a frame is codec dependent but it may include any new
|
||||
* sequence header.
|
||||
*/
|
||||
#define GST_VAAPI_DECODER_UNIT_IS_FRAME_START(unit) \
|
||||
(GST_VAAPI_DECODER_UNIT_FLAG_IS_SET(unit, \
|
||||
GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START))
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DECODER_UNIT_IS_FRAME_END:
|
||||
* @unit: a #GstVaapiDecoderUnit
|
||||
*
|
||||
* Tests if the decoder unit marks the end of a frame.
|
||||
*
|
||||
* The end of a frame is codec dependent but it is usually represented
|
||||
* by the last bitstream chunk that holds valid slice data.
|
||||
*/
|
||||
#define GST_VAAPI_DECODER_UNIT_IS_FRAME_END(unit) \
|
||||
(GST_VAAPI_DECODER_UNIT_FLAG_IS_SET(unit, \
|
||||
GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END))
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DECODER_UNIT_IS_STREAM_END:
|
||||
* @unit: a #GstVaapiDecoderUnit
|
||||
*
|
||||
* Tests if the decoder unit marks the end of the stream.
|
||||
*/
|
||||
#define GST_VAAPI_DECODER_UNIT_IS_STREAM_END(unit) \
|
||||
(GST_VAAPI_DECODER_UNIT_FLAG_IS_SET(unit, \
|
||||
GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END))
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DECODER_UNIT_IS_SLICE:
|
||||
* @unit: a #GstVaapiDecoderUnit
|
||||
*
|
||||
* Tests if the decoder unit contains slice data.
|
||||
*/
|
||||
#define GST_VAAPI_DECODER_UNIT_IS_SLICE(unit) \
|
||||
(GST_VAAPI_DECODER_UNIT_FLAG_IS_SET(unit, \
|
||||
GST_VAAPI_DECODER_UNIT_FLAG_SLICE))
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DECODER_UNIT_IS_SKIPPED:
|
||||
* @unit: a #GstVaapiDecoderUnit
|
||||
*
|
||||
* Tests if the decoder unit is not needed for decoding an can be skipped.
|
||||
* i.e. #GstVaapiDecoder sub-classes won't see this chunk of bitstream
|
||||
* data.
|
||||
*/
|
||||
#define GST_VAAPI_DECODER_UNIT_IS_SKIPPED(unit) \
|
||||
(GST_VAAPI_DECODER_UNIT_FLAG_IS_SET(unit, \
|
||||
GST_VAAPI_DECODER_UNIT_FLAG_SKIP))
|
||||
|
||||
/**
|
||||
* GstVaapiDecoderUnit:
|
||||
* @size: size in bytes of this bitstream unit
|
||||
* @offset: relative offset in bytes to bitstream unit within the
|
||||
* associated #GstVideoCodecFrame input_buffer
|
||||
* @parsed_info: parser-specific data (this is codec specific)
|
||||
* @parsed_info_destroy_notify: function used to release @parsed_info data
|
||||
*
|
||||
* A chunk of bitstream data that was parsed.
|
||||
*/
|
||||
struct _GstVaapiDecoderUnit {
|
||||
guint flags;
|
||||
guint size;
|
||||
guint offset;
|
||||
gpointer parsed_info;
|
||||
GDestroyNotify parsed_info_destroy_notify;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_decoder_unit_init(GstVaapiDecoderUnit *unit);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_decoder_unit_clear(GstVaapiDecoderUnit *unit);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiDecoderUnit *
|
||||
gst_vaapi_decoder_unit_new(void);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_decoder_unit_set_parsed_info(GstVaapiDecoderUnit *unit,
|
||||
gpointer parsed_info, GDestroyNotify destroy_notify);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DECODER_UNIT_H */
|
1484
gst-libs/gst/vaapi/gstvaapidecoder_vc1.c
Normal file
1484
gst-libs/gst/vaapi/gstvaapidecoder_vc1.c
Normal file
File diff suppressed because it is too large
Load diff
49
gst-libs/gst/vaapi/gstvaapidecoder_vc1.h
Normal file
49
gst-libs/gst/vaapi/gstvaapidecoder_vc1.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* gstvaapidecoder_vc1.h - VC-1 decoder
|
||||
*
|
||||
* Copyright (C) 2011-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DECODER_VC1_H
|
||||
#define GST_VAAPI_DECODER_VC1_H
|
||||
|
||||
#include <gst/vaapi/gstvaapidecoder.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_DECODER_VC1 \
|
||||
(gst_vaapi_decoder_vc1_get_type ())
|
||||
#define GST_VAAPI_DECODER_VC1(decoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DECODER_VC1, GstVaapiDecoderVC1))
|
||||
#define GST_VAAPI_IS_DECODER_VC1(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_DECODER_VC1))
|
||||
|
||||
typedef struct _GstVaapiDecoderVC1 GstVaapiDecoderVC1;
|
||||
|
||||
GType
|
||||
gst_vaapi_decoder_vc1_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GstVaapiDecoder *
|
||||
gst_vaapi_decoder_vc1_new (GstVaapiDisplay *display, GstCaps *caps);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDecoderVC1, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DECODER_VC1_H */
|
677
gst-libs/gst/vaapi/gstvaapidecoder_vp8.c
Normal file
677
gst-libs/gst/vaapi/gstvaapidecoder_vp8.c
Normal file
|
@ -0,0 +1,677 @@
|
|||
/*
|
||||
* gstvaapidecoder_vp8.c - VP8 decoder
|
||||
*
|
||||
* Copyright (C) 2013-2014 Intel Corporation
|
||||
* Author: Halley Zhao <halley.zhao@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstvaapidecoder_vp8
|
||||
* @short_description: VP8 decoder
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include <gst/codecparsers/gstvp8parser.h>
|
||||
#include "gstvaapidecoder_vp8.h"
|
||||
#include "gstvaapidecoder_objects.h"
|
||||
#include "gstvaapidecoder_priv.h"
|
||||
#include "gstvaapidisplay_priv.h"
|
||||
|
||||
#include "gstvaapicompat.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
#define GST_VAAPI_DECODER_VP8_CAST(decoder) \
|
||||
((GstVaapiDecoderVp8 *)(decoder))
|
||||
|
||||
typedef struct _GstVaapiDecoderVp8Private GstVaapiDecoderVp8Private;
|
||||
typedef struct _GstVaapiDecoderVp8Class GstVaapiDecoderVp8Class;
|
||||
|
||||
struct _GstVaapiDecoderVp8Private
|
||||
{
|
||||
GstVaapiProfile profile;
|
||||
guint width;
|
||||
guint height;
|
||||
GstVp8Parser parser;
|
||||
GstVp8FrameHdr frame_hdr;
|
||||
GstVaapiPicture *last_picture;
|
||||
GstVaapiPicture *golden_ref_picture;
|
||||
GstVaapiPicture *alt_ref_picture;
|
||||
GstVaapiPicture *current_picture;
|
||||
guint size_changed:1;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDecoderVp8:
|
||||
*
|
||||
* A decoder based on Vp8.
|
||||
*/
|
||||
struct _GstVaapiDecoderVp8
|
||||
{
|
||||
/*< private > */
|
||||
GstVaapiDecoder parent_instance;
|
||||
|
||||
GstVaapiDecoderVp8Private priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDecoderVp8Class:
|
||||
*
|
||||
* A decoder class based on Vp8.
|
||||
*/
|
||||
struct _GstVaapiDecoderVp8Class
|
||||
{
|
||||
/*< private > */
|
||||
GstVaapiDecoderClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GstVaapiDecoderVp8, gst_vaapi_decoder_vp8,
|
||||
GST_TYPE_VAAPI_DECODER);
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
get_status (GstVp8ParserResult result)
|
||||
{
|
||||
GstVaapiDecoderStatus status;
|
||||
|
||||
switch (result) {
|
||||
case GST_VP8_PARSER_OK:
|
||||
status = GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
break;
|
||||
case GST_VP8_PARSER_ERROR:
|
||||
status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
|
||||
break;
|
||||
default:
|
||||
status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_vp8_close (GstVaapiDecoderVp8 * decoder)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
|
||||
gst_vaapi_picture_replace (&priv->last_picture, NULL);
|
||||
gst_vaapi_picture_replace (&priv->golden_ref_picture, NULL);
|
||||
gst_vaapi_picture_replace (&priv->alt_ref_picture, NULL);
|
||||
gst_vaapi_picture_replace (&priv->current_picture, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_decoder_vp8_open (GstVaapiDecoderVp8 * decoder)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
|
||||
gst_vaapi_decoder_vp8_close (decoder);
|
||||
gst_vp8_parser_init (&priv->parser);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_vp8_destroy (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
GstVaapiDecoderVp8 *const decoder = GST_VAAPI_DECODER_VP8_CAST (base_decoder);
|
||||
|
||||
gst_vaapi_decoder_vp8_close (decoder);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_decoder_vp8_create (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
GstVaapiDecoderVp8 *const decoder = GST_VAAPI_DECODER_VP8_CAST (base_decoder);
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
|
||||
if (!gst_vaapi_decoder_vp8_open (decoder))
|
||||
return FALSE;
|
||||
|
||||
priv->profile = GST_VAAPI_PROFILE_UNKNOWN;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_vp8_reset (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
gst_vaapi_decoder_vp8_destroy (base_decoder);
|
||||
if (gst_vaapi_decoder_vp8_create (base_decoder))
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
ensure_context (GstVaapiDecoderVp8 * decoder)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
const GstVaapiProfile profile = GST_VAAPI_PROFILE_VP8;
|
||||
const GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
|
||||
gboolean reset_context = FALSE;
|
||||
|
||||
if (priv->profile != profile) {
|
||||
if (!gst_vaapi_display_has_decoder (GST_VAAPI_DECODER_DISPLAY (decoder),
|
||||
profile, entrypoint))
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
|
||||
|
||||
priv->profile = profile;
|
||||
reset_context = TRUE;
|
||||
}
|
||||
|
||||
if (priv->size_changed) {
|
||||
GST_DEBUG ("size changed");
|
||||
priv->size_changed = FALSE;
|
||||
reset_context = TRUE;
|
||||
}
|
||||
|
||||
if (reset_context) {
|
||||
GstVaapiContextInfo info;
|
||||
|
||||
info.profile = priv->profile;
|
||||
info.entrypoint = entrypoint;
|
||||
info.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
|
||||
info.width = priv->width;
|
||||
info.height = priv->height;
|
||||
info.ref_frames = 3;
|
||||
reset_context =
|
||||
gst_vaapi_decoder_ensure_context (GST_VAAPI_DECODER (decoder), &info);
|
||||
|
||||
if (!reset_context)
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
ensure_quant_matrix (GstVaapiDecoderVp8 * decoder, GstVaapiPicture * picture)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
GstVp8FrameHdr *const frame_hdr = &priv->frame_hdr;
|
||||
GstVp8Segmentation *const seg = &priv->parser.segmentation;
|
||||
VAIQMatrixBufferVP8 *iq_matrix;
|
||||
const gint8 QI_MAX = 127;
|
||||
gint8 qi, qi_base;
|
||||
gint i;
|
||||
|
||||
picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW (VP8, decoder);
|
||||
if (!picture->iq_matrix) {
|
||||
GST_ERROR ("failed to allocate IQ matrix");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
iq_matrix = picture->iq_matrix->param;
|
||||
|
||||
/* Fill in VAIQMatrixBufferVP8 */
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (seg->segmentation_enabled) {
|
||||
qi_base = seg->quantizer_update_value[i];
|
||||
if (!seg->segment_feature_mode) // 0 means delta update
|
||||
qi_base += frame_hdr->quant_indices.y_ac_qi;
|
||||
} else
|
||||
qi_base = frame_hdr->quant_indices.y_ac_qi;
|
||||
|
||||
qi = qi_base;
|
||||
iq_matrix->quantization_index[i][0] = CLAMP (qi, 0, QI_MAX);
|
||||
qi = qi_base + frame_hdr->quant_indices.y_dc_delta;
|
||||
iq_matrix->quantization_index[i][1] = CLAMP (qi, 0, QI_MAX);
|
||||
qi = qi_base + frame_hdr->quant_indices.y2_dc_delta;
|
||||
iq_matrix->quantization_index[i][2] = CLAMP (qi, 0, QI_MAX);
|
||||
qi = qi_base + frame_hdr->quant_indices.y2_ac_delta;
|
||||
iq_matrix->quantization_index[i][3] = CLAMP (qi, 0, QI_MAX);
|
||||
qi = qi_base + frame_hdr->quant_indices.uv_dc_delta;
|
||||
iq_matrix->quantization_index[i][4] = CLAMP (qi, 0, QI_MAX);
|
||||
qi = qi_base + frame_hdr->quant_indices.uv_ac_delta;
|
||||
iq_matrix->quantization_index[i][5] = CLAMP (qi, 0, QI_MAX);
|
||||
}
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
ensure_probability_table (GstVaapiDecoderVp8 * decoder,
|
||||
GstVaapiPicture * picture)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
GstVp8FrameHdr *const frame_hdr = &priv->frame_hdr;
|
||||
VAProbabilityDataBufferVP8 *prob_table;
|
||||
|
||||
picture->prob_table = GST_VAAPI_PROBABILITY_TABLE_NEW (VP8, decoder);
|
||||
if (!picture->prob_table) {
|
||||
GST_ERROR ("failed to allocate probality table");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
prob_table = picture->prob_table->param;
|
||||
|
||||
/* Fill in VAProbabilityDataBufferVP8 */
|
||||
memcpy (prob_table->dct_coeff_probs, frame_hdr->token_probs.prob,
|
||||
sizeof (frame_hdr->token_probs.prob));
|
||||
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
init_picture (GstVaapiDecoderVp8 * decoder, GstVaapiPicture * picture)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
GstVp8FrameHdr *const frame_hdr = &priv->frame_hdr;
|
||||
|
||||
picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
|
||||
picture->type = frame_hdr->key_frame ? GST_VAAPI_PICTURE_TYPE_I :
|
||||
GST_VAAPI_PICTURE_TYPE_P;
|
||||
picture->pts = GST_VAAPI_DECODER_CODEC_FRAME (decoder)->pts;
|
||||
|
||||
if (!frame_hdr->show_frame)
|
||||
GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_SKIPPED);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fill_picture (GstVaapiDecoderVp8 * decoder, GstVaapiPicture * picture)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
VAPictureParameterBufferVP8 *const pic_param = picture->param;
|
||||
GstVp8Parser *const parser = &priv->parser;
|
||||
GstVp8FrameHdr *const frame_hdr = &priv->frame_hdr;
|
||||
GstVp8Segmentation *const seg = &parser->segmentation;
|
||||
gint i;
|
||||
|
||||
/* Fill in VAPictureParameterBufferVP8 */
|
||||
pic_param->frame_width = priv->width;
|
||||
pic_param->frame_height = priv->height;
|
||||
|
||||
pic_param->last_ref_frame = VA_INVALID_SURFACE;
|
||||
pic_param->golden_ref_frame = VA_INVALID_SURFACE;
|
||||
pic_param->alt_ref_frame = VA_INVALID_SURFACE;
|
||||
if (!frame_hdr->key_frame) {
|
||||
if (priv->last_picture)
|
||||
pic_param->last_ref_frame = priv->last_picture->surface_id;
|
||||
if (priv->golden_ref_picture)
|
||||
pic_param->golden_ref_frame = priv->golden_ref_picture->surface_id;
|
||||
if (priv->alt_ref_picture)
|
||||
pic_param->alt_ref_frame = priv->alt_ref_picture->surface_id;
|
||||
}
|
||||
pic_param->out_of_loop_frame = VA_INVALID_SURFACE; // not used currently
|
||||
|
||||
pic_param->pic_fields.value = 0;
|
||||
pic_param->pic_fields.bits.key_frame = !frame_hdr->key_frame;
|
||||
pic_param->pic_fields.bits.version = frame_hdr->version;
|
||||
pic_param->pic_fields.bits.segmentation_enabled = seg->segmentation_enabled;
|
||||
pic_param->pic_fields.bits.update_mb_segmentation_map =
|
||||
seg->update_mb_segmentation_map;
|
||||
pic_param->pic_fields.bits.update_segment_feature_data =
|
||||
seg->update_segment_feature_data;
|
||||
pic_param->pic_fields.bits.filter_type = frame_hdr->filter_type;
|
||||
pic_param->pic_fields.bits.sharpness_level = frame_hdr->sharpness_level;
|
||||
pic_param->pic_fields.bits.loop_filter_adj_enable =
|
||||
parser->mb_lf_adjust.loop_filter_adj_enable;
|
||||
pic_param->pic_fields.bits.mode_ref_lf_delta_update =
|
||||
parser->mb_lf_adjust.mode_ref_lf_delta_update;
|
||||
pic_param->pic_fields.bits.sign_bias_golden = frame_hdr->sign_bias_golden;
|
||||
pic_param->pic_fields.bits.sign_bias_alternate =
|
||||
frame_hdr->sign_bias_alternate;
|
||||
pic_param->pic_fields.bits.mb_no_coeff_skip = frame_hdr->mb_no_skip_coeff;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
pic_param->mb_segment_tree_probs[i] = seg->segment_prob[i];
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
gint8 level;
|
||||
if (seg->segmentation_enabled) {
|
||||
level = seg->lf_update_value[i];
|
||||
if (!seg->segment_feature_mode) // 0 means delta update
|
||||
level += frame_hdr->loop_filter_level;
|
||||
} else
|
||||
level = frame_hdr->loop_filter_level;
|
||||
pic_param->loop_filter_level[i] = CLAMP (level, 0, 63);
|
||||
|
||||
pic_param->loop_filter_deltas_ref_frame[i] =
|
||||
parser->mb_lf_adjust.ref_frame_delta[i];
|
||||
pic_param->loop_filter_deltas_mode[i] =
|
||||
parser->mb_lf_adjust.mb_mode_delta[i];
|
||||
}
|
||||
|
||||
/* In decoding, the only loop filter settings that matter are those
|
||||
in the frame header (9.1) */
|
||||
pic_param->pic_fields.bits.loop_filter_disable =
|
||||
frame_hdr->loop_filter_level == 0;
|
||||
|
||||
pic_param->prob_skip_false = frame_hdr->prob_skip_false;
|
||||
pic_param->prob_intra = frame_hdr->prob_intra;
|
||||
pic_param->prob_last = frame_hdr->prob_last;
|
||||
pic_param->prob_gf = frame_hdr->prob_gf;
|
||||
|
||||
memcpy (pic_param->y_mode_probs, frame_hdr->mode_probs.y_prob,
|
||||
sizeof (frame_hdr->mode_probs.y_prob));
|
||||
memcpy (pic_param->uv_mode_probs, frame_hdr->mode_probs.uv_prob,
|
||||
sizeof (frame_hdr->mode_probs.uv_prob));
|
||||
memcpy (pic_param->mv_probs, frame_hdr->mv_probs.prob,
|
||||
sizeof (frame_hdr->mv_probs));
|
||||
|
||||
pic_param->bool_coder_ctx.range = frame_hdr->rd_range;
|
||||
pic_param->bool_coder_ctx.value = frame_hdr->rd_value;
|
||||
pic_param->bool_coder_ctx.count = frame_hdr->rd_count;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fill_slice (GstVaapiDecoderVp8 * decoder, GstVaapiSlice * slice)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
VASliceParameterBufferVP8 *const slice_param = slice->param;
|
||||
GstVp8FrameHdr *const frame_hdr = &priv->frame_hdr;
|
||||
gint i;
|
||||
|
||||
/* Fill in VASliceParameterBufferVP8 */
|
||||
slice_param->slice_data_offset = frame_hdr->data_chunk_size;
|
||||
slice_param->macroblock_offset = frame_hdr->header_size;
|
||||
slice_param->num_of_partitions =
|
||||
(1 << frame_hdr->log2_nbr_of_dct_partitions) + 1;
|
||||
|
||||
slice_param->partition_size[0] =
|
||||
frame_hdr->first_part_size - ((slice_param->macroblock_offset + 7) >> 3);
|
||||
for (i = 1; i < slice_param->num_of_partitions; i++)
|
||||
slice_param->partition_size[i] = frame_hdr->partition_size[i - 1];
|
||||
for (; i < G_N_ELEMENTS (slice_param->partition_size); i++)
|
||||
slice_param->partition_size[i] = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_slice (GstVaapiDecoderVp8 * decoder, GstVaapiPicture * picture,
|
||||
const guchar * buf, guint buf_size)
|
||||
{
|
||||
GstVaapiSlice *slice;
|
||||
|
||||
slice = GST_VAAPI_SLICE_NEW (VP8, decoder, buf, buf_size);
|
||||
if (!slice) {
|
||||
GST_ERROR ("failed to allocate slice");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
|
||||
if (!fill_slice (decoder, slice)) {
|
||||
gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (slice));
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
gst_vaapi_picture_add_slice (GST_VAAPI_PICTURE_CAST (picture), slice);
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_picture (GstVaapiDecoderVp8 * decoder, const guchar * buf,
|
||||
guint buf_size)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
GstVaapiPicture *picture;
|
||||
GstVaapiDecoderStatus status;
|
||||
|
||||
status = ensure_context (decoder);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
/* Create new picture */
|
||||
picture = GST_VAAPI_PICTURE_NEW (VP8, decoder);
|
||||
if (!picture) {
|
||||
GST_ERROR ("failed to allocate picture");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
gst_vaapi_picture_replace (&priv->current_picture, picture);
|
||||
gst_vaapi_picture_unref (picture);
|
||||
|
||||
status = ensure_quant_matrix (decoder, picture);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = ensure_probability_table (decoder, picture);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
init_picture (decoder, picture);
|
||||
if (!fill_picture (decoder, picture))
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
|
||||
return decode_slice (decoder, picture, buf, buf_size);
|
||||
}
|
||||
|
||||
static void
|
||||
update_ref_frames (GstVaapiDecoderVp8 * decoder)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
GstVaapiPicture *picture = priv->current_picture;
|
||||
GstVp8FrameHdr *const frame_hdr = &priv->frame_hdr;
|
||||
|
||||
// update picture reference
|
||||
if (frame_hdr->key_frame) {
|
||||
gst_vaapi_picture_replace (&priv->golden_ref_picture, picture);
|
||||
gst_vaapi_picture_replace (&priv->alt_ref_picture, picture);
|
||||
} else {
|
||||
// process refresh_alternate_frame/copy_buffer_to_alternate first
|
||||
if (frame_hdr->refresh_alternate_frame) {
|
||||
gst_vaapi_picture_replace (&priv->alt_ref_picture, picture);
|
||||
} else {
|
||||
switch (frame_hdr->copy_buffer_to_alternate) {
|
||||
case 0:
|
||||
// do nothing
|
||||
break;
|
||||
case 1:
|
||||
gst_vaapi_picture_replace (&priv->alt_ref_picture,
|
||||
priv->last_picture);
|
||||
break;
|
||||
case 2:
|
||||
gst_vaapi_picture_replace (&priv->alt_ref_picture,
|
||||
priv->golden_ref_picture);
|
||||
break;
|
||||
default:
|
||||
GST_WARNING
|
||||
("WARNING: VP8 decoder: unrecognized copy_buffer_to_alternate");
|
||||
}
|
||||
}
|
||||
|
||||
if (frame_hdr->refresh_golden_frame) {
|
||||
gst_vaapi_picture_replace (&priv->golden_ref_picture, picture);
|
||||
} else {
|
||||
switch (frame_hdr->copy_buffer_to_golden) {
|
||||
case 0:
|
||||
// do nothing
|
||||
break;
|
||||
case 1:
|
||||
gst_vaapi_picture_replace (&priv->golden_ref_picture,
|
||||
priv->last_picture);
|
||||
break;
|
||||
case 2:
|
||||
gst_vaapi_picture_replace (&priv->golden_ref_picture,
|
||||
priv->alt_ref_picture);
|
||||
break;
|
||||
default:
|
||||
GST_WARNING
|
||||
("WARNING: VP8 decoder: unrecognized copy_buffer_to_golden");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (frame_hdr->key_frame || frame_hdr->refresh_last)
|
||||
gst_vaapi_picture_replace (&priv->last_picture, picture);
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_current_picture (GstVaapiDecoderVp8 * decoder)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
GstVaapiPicture *const picture = priv->current_picture;
|
||||
|
||||
if (!picture)
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
|
||||
update_ref_frames (decoder);
|
||||
if (!gst_vaapi_picture_decode (picture))
|
||||
goto error;
|
||||
if (!gst_vaapi_picture_output (picture))
|
||||
goto error;
|
||||
gst_vaapi_picture_replace (&priv->current_picture, NULL);
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
|
||||
/* ERRORS */
|
||||
error:
|
||||
{
|
||||
/* XXX: fix for cases where first field failed to be decoded */
|
||||
gst_vaapi_picture_replace (&priv->current_picture, NULL);
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
parse_frame_header (GstVaapiDecoderVp8 * decoder, const guchar * buf,
|
||||
guint buf_size, GstVp8FrameHdr * frame_hdr)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
GstVp8ParserResult result;
|
||||
|
||||
memset (frame_hdr, 0, sizeof (*frame_hdr));
|
||||
result = gst_vp8_parser_parse_frame_header (&priv->parser, frame_hdr,
|
||||
buf, buf_size);
|
||||
if (result != GST_VP8_PARSER_OK)
|
||||
return get_status (result);
|
||||
|
||||
if (frame_hdr->key_frame &&
|
||||
(frame_hdr->width != priv->width || frame_hdr->height != priv->height)) {
|
||||
priv->width = frame_hdr->width;
|
||||
priv->height = frame_hdr->height;
|
||||
priv->size_changed = TRUE;
|
||||
}
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_vp8_parse (GstVaapiDecoder * base_decoder,
|
||||
GstAdapter * adapter, gboolean at_eos, GstVaapiDecoderUnit * unit)
|
||||
{
|
||||
guint flags = 0;
|
||||
|
||||
unit->size = gst_adapter_available (adapter);
|
||||
|
||||
/* The whole frame is available */
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END;
|
||||
GST_VAAPI_DECODER_UNIT_FLAG_SET (unit, flags);
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_buffer (GstVaapiDecoderVp8 * decoder, const guchar * buf, guint buf_size)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
GstVaapiDecoderStatus status;
|
||||
|
||||
status = parse_frame_header (decoder, buf, buf_size, &priv->frame_hdr);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return decode_picture (decoder, buf, buf_size);
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_vp8_decode (GstVaapiDecoder * base_decoder,
|
||||
GstVaapiDecoderUnit * unit)
|
||||
{
|
||||
GstVaapiDecoderVp8 *const decoder = GST_VAAPI_DECODER_VP8_CAST (base_decoder);
|
||||
GstVaapiDecoderStatus status;
|
||||
GstBuffer *const buffer =
|
||||
GST_VAAPI_DECODER_CODEC_FRAME (decoder)->input_buffer;
|
||||
GstMapInfo map_info;
|
||||
|
||||
if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) {
|
||||
GST_ERROR ("failed to map buffer");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
status = decode_buffer (decoder, map_info.data + unit->offset, unit->size);
|
||||
gst_buffer_unmap (buffer, &map_info);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_vp8_start_frame (GstVaapiDecoder * base_decoder,
|
||||
GstVaapiDecoderUnit * base_unit)
|
||||
{
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_vp8_end_frame (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
GstVaapiDecoderVp8 *const decoder = GST_VAAPI_DECODER_VP8_CAST (base_decoder);
|
||||
|
||||
return decode_current_picture (decoder);
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_vp8_flush (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_vp8_finalize (GObject * object)
|
||||
{
|
||||
GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (object);
|
||||
|
||||
gst_vaapi_decoder_vp8_destroy (base_decoder);
|
||||
G_OBJECT_CLASS (gst_vaapi_decoder_vp8_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_vp8_class_init (GstVaapiDecoderVp8Class * klass)
|
||||
{
|
||||
GObjectClass *const object_class = G_OBJECT_CLASS (klass);
|
||||
GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass);
|
||||
|
||||
object_class->finalize = gst_vaapi_decoder_vp8_finalize;
|
||||
|
||||
decoder_class->reset = gst_vaapi_decoder_vp8_reset;
|
||||
decoder_class->parse = gst_vaapi_decoder_vp8_parse;
|
||||
decoder_class->decode = gst_vaapi_decoder_vp8_decode;
|
||||
decoder_class->start_frame = gst_vaapi_decoder_vp8_start_frame;
|
||||
decoder_class->end_frame = gst_vaapi_decoder_vp8_end_frame;
|
||||
decoder_class->flush = gst_vaapi_decoder_vp8_flush;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_vp8_init (GstVaapiDecoderVp8 * decoder)
|
||||
{
|
||||
GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder);
|
||||
|
||||
gst_vaapi_decoder_vp8_create (base_decoder);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_decoder_vp8_new:
|
||||
* @display: a #GstVaapiDisplay
|
||||
* @caps: a #GstCaps holding codec information
|
||||
*
|
||||
* Creates a new #GstVaapiDecoder for VP8 decoding. The @caps can
|
||||
* hold extra information like codec-data and pictured coded size.
|
||||
*
|
||||
* Return value: the newly allocated #GstVaapiDecoder object
|
||||
*/
|
||||
GstVaapiDecoder *
|
||||
gst_vaapi_decoder_vp8_new (GstVaapiDisplay * display, GstCaps * caps)
|
||||
{
|
||||
return g_object_new (GST_TYPE_VAAPI_DECODER_VP8, "display", display,
|
||||
"caps", caps, NULL);
|
||||
}
|
50
gst-libs/gst/vaapi/gstvaapidecoder_vp8.h
Normal file
50
gst-libs/gst/vaapi/gstvaapidecoder_vp8.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* gstvaapidecoder_vp8.h - VP8 decoder
|
||||
*
|
||||
* Copyright (C) 2013-2014 Intel Corporation
|
||||
* Author: Halley Zhao <halley.zhao@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DECODER_VP8_H
|
||||
#define GST_VAAPI_DECODER_VP8_H
|
||||
|
||||
#include <gst/vaapi/gstvaapidecoder.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_DECODER_VP8 \
|
||||
(gst_vaapi_decoder_vp8_get_type ())
|
||||
#define GST_VAAPI_DECODER_VP8(decoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DECODER_VP8, GstVaapiDecoderVp8))
|
||||
#define GST_VAAPI_IS_DECODER_VP8(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_DECODER_VP8))
|
||||
|
||||
typedef struct _GstVaapiDecoderVp8 GstVaapiDecoderVp8;
|
||||
|
||||
GType
|
||||
gst_vaapi_decoder_vp8_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GstVaapiDecoder *
|
||||
gst_vaapi_decoder_vp8_new (GstVaapiDisplay * display, GstCaps * caps);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDecoderVp8, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DECODER_VP8_H */
|
833
gst-libs/gst/vaapi/gstvaapidecoder_vp9.c
Normal file
833
gst-libs/gst/vaapi/gstvaapidecoder_vp9.c
Normal file
|
@ -0,0 +1,833 @@
|
|||
/*
|
||||
* gstvaapidecoder_vp9.c - VP9 decoder
|
||||
*
|
||||
* Copyright (C) 2014-2015 Intel Corporation
|
||||
* Author: Sreerenj Balachandran <sreerenj.balachandran@intel.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; 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstvaapidecoder_vp9
|
||||
* @short_description: VP9 decoder
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include <gst/codecparsers/gstvp9parser.h>
|
||||
#include "gstvaapidecoder_vp9.h"
|
||||
#include "gstvaapidecoder_objects.h"
|
||||
#include "gstvaapidecoder_priv.h"
|
||||
#include "gstvaapidisplay_priv.h"
|
||||
|
||||
#include "gstvaapicompat.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
#define GST_VAAPI_DECODER_VP9_CAST(decoder) \
|
||||
((GstVaapiDecoderVp9 *)(decoder))
|
||||
|
||||
typedef struct _GstVaapiDecoderVp9Private GstVaapiDecoderVp9Private;
|
||||
typedef struct _GstVaapiDecoderVp9Class GstVaapiDecoderVp9Class;
|
||||
|
||||
struct _GstVaapiDecoderVp9Private
|
||||
{
|
||||
GstVaapiProfile profile;
|
||||
guint width;
|
||||
guint height;
|
||||
GstVp9Parser *parser;
|
||||
GstVp9FrameHdr frame_hdr;
|
||||
GstVaapiPicture *current_picture;
|
||||
GstVaapiPicture *ref_frames[GST_VP9_REF_FRAMES]; /* reference frames in ref_slots[max_ref] */
|
||||
|
||||
guint num_frames; /* number of frames in a super frame */
|
||||
guint frame_sizes[8]; /* size of frames in a super frame */
|
||||
guint frame_cnt; /* frame count variable for super frame */
|
||||
guint total_idx_size; /* super frame index size (full block size) */
|
||||
guint had_superframe_hdr:1; /* indicate the presense of super frame */
|
||||
|
||||
guint size_changed:1;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDecoderVp9:
|
||||
*
|
||||
* A decoder based on Vp9.
|
||||
*/
|
||||
struct _GstVaapiDecoderVp9
|
||||
{
|
||||
/*< private > */
|
||||
GstVaapiDecoder parent_instance;
|
||||
|
||||
GstVaapiDecoderVp9Private priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDecoderVp9Class:
|
||||
*
|
||||
* A decoder class based on Vp9.
|
||||
*/
|
||||
struct _GstVaapiDecoderVp9Class
|
||||
{
|
||||
/*< private > */
|
||||
GstVaapiDecoderClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GstVaapiDecoderVp9, gst_vaapi_decoder_vp9,
|
||||
GST_TYPE_VAAPI_DECODER);
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
get_status (GstVp9ParserResult result)
|
||||
{
|
||||
GstVaapiDecoderStatus status;
|
||||
|
||||
switch (result) {
|
||||
case GST_VP9_PARSER_OK:
|
||||
status = GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
break;
|
||||
case GST_VP9_PARSER_ERROR:
|
||||
status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
|
||||
break;
|
||||
default:
|
||||
status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_vp9_close (GstVaapiDecoderVp9 * decoder)
|
||||
{
|
||||
GstVaapiDecoderVp9Private *const priv = &decoder->priv;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < GST_VP9_REF_FRAMES; i++)
|
||||
gst_vaapi_picture_replace (&priv->ref_frames[i], NULL);
|
||||
|
||||
g_clear_pointer (&priv->parser, gst_vp9_parser_free);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_decoder_vp9_open (GstVaapiDecoderVp9 * decoder)
|
||||
{
|
||||
GstVaapiDecoderVp9Private *const priv = &decoder->priv;
|
||||
|
||||
gst_vaapi_decoder_vp9_close (decoder);
|
||||
priv->parser = gst_vp9_parser_new ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_vp9_destroy (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
GstVaapiDecoderVp9 *const decoder = GST_VAAPI_DECODER_VP9_CAST (base_decoder);
|
||||
|
||||
gst_vaapi_decoder_vp9_close (decoder);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_decoder_vp9_create (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
GstVaapiDecoderVp9 *const decoder = GST_VAAPI_DECODER_VP9_CAST (base_decoder);
|
||||
GstVaapiDecoderVp9Private *const priv = &decoder->priv;
|
||||
|
||||
if (!gst_vaapi_decoder_vp9_open (decoder))
|
||||
return FALSE;
|
||||
|
||||
priv->profile = GST_VAAPI_PROFILE_UNKNOWN;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_vp9_reset (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
gst_vaapi_decoder_vp9_destroy (base_decoder);
|
||||
if (gst_vaapi_decoder_vp9_create (base_decoder))
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Returns GstVaapiProfile from VP9 frame_hdr profile value */
|
||||
static GstVaapiProfile
|
||||
get_profile (guint profile_idc)
|
||||
{
|
||||
GstVaapiProfile profile;
|
||||
|
||||
switch (profile_idc) {
|
||||
case GST_VP9_PROFILE_0:
|
||||
profile = GST_VAAPI_PROFILE_VP9_0;
|
||||
break;
|
||||
case GST_VP9_PROFILE_1:
|
||||
profile = GST_VAAPI_PROFILE_VP9_1;
|
||||
break;
|
||||
case GST_VP9_PROFILE_2:
|
||||
profile = GST_VAAPI_PROFILE_VP9_2;
|
||||
break;
|
||||
case GST_VP9_PROFILE_3:
|
||||
profile = GST_VAAPI_PROFILE_VP9_3;
|
||||
break;
|
||||
default:
|
||||
GST_DEBUG ("unsupported profile_idc value");
|
||||
profile = GST_VAAPI_PROFILE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_chroma_type (GstVp9FrameHdr * frame_hdr, GstVp9Parser * parser,
|
||||
GstVaapiContextInfo * info)
|
||||
{
|
||||
switch (frame_hdr->profile) {
|
||||
case GST_VP9_PROFILE_0:
|
||||
info->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
|
||||
break;
|
||||
case GST_VP9_PROFILE_1:
|
||||
if (parser->subsampling_x == 1 && parser->subsampling_y == 0)
|
||||
info->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422;
|
||||
else if (parser->subsampling_x == 0 && parser->subsampling_y == 0)
|
||||
info->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444;
|
||||
else
|
||||
return FALSE;
|
||||
break;
|
||||
case GST_VP9_PROFILE_2:
|
||||
if (parser->bit_depth == 10)
|
||||
info->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_10BPP;
|
||||
else
|
||||
info->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_12BPP;
|
||||
break;
|
||||
case GST_VP9_PROFILE_3:
|
||||
if (parser->subsampling_x == 1 && parser->subsampling_y == 0) {
|
||||
if (parser->bit_depth == 10)
|
||||
info->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422_10BPP;
|
||||
else
|
||||
info->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422_12BPP;
|
||||
} else if (parser->subsampling_x == 0 && parser->subsampling_y == 0) {
|
||||
if (parser->bit_depth == 10)
|
||||
info->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444_10BPP;
|
||||
else
|
||||
info->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444_12BPP;
|
||||
} else
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
ensure_context (GstVaapiDecoderVp9 * decoder)
|
||||
{
|
||||
GstVaapiDecoderVp9Private *const priv = &decoder->priv;
|
||||
GstVp9FrameHdr *frame_hdr = &priv->frame_hdr;
|
||||
GstVp9Parser *parser = priv->parser;
|
||||
GstVaapiProfile profile;
|
||||
const GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
|
||||
gboolean reset_context = FALSE;
|
||||
|
||||
profile = get_profile (frame_hdr->profile);
|
||||
|
||||
if (priv->profile != profile) {
|
||||
if (!gst_vaapi_display_has_decoder (GST_VAAPI_DECODER_DISPLAY (decoder),
|
||||
profile, entrypoint))
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
|
||||
|
||||
priv->profile = profile;
|
||||
reset_context = TRUE;
|
||||
}
|
||||
|
||||
if (priv->size_changed) {
|
||||
GST_DEBUG ("size changed");
|
||||
priv->size_changed = FALSE;
|
||||
reset_context = TRUE;
|
||||
}
|
||||
|
||||
if (reset_context) {
|
||||
GstVaapiContextInfo info;
|
||||
|
||||
info.profile = priv->profile;
|
||||
info.entrypoint = entrypoint;
|
||||
info.width = priv->width;
|
||||
info.height = priv->height;
|
||||
info.ref_frames = 8;
|
||||
if (!get_chroma_type (frame_hdr, parser, &info))
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
|
||||
|
||||
reset_context =
|
||||
gst_vaapi_decoder_ensure_context (GST_VAAPI_DECODER (decoder), &info);
|
||||
|
||||
if (!reset_context)
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
|
||||
gst_vaapi_context_reset_on_resize (GST_VAAPI_DECODER_CONTEXT (decoder),
|
||||
FALSE);
|
||||
}
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
init_picture (GstVaapiDecoderVp9 * decoder, GstVaapiPicture * picture)
|
||||
{
|
||||
GstVaapiDecoderVp9Private *const priv = &decoder->priv;
|
||||
GstVp9FrameHdr *const frame_hdr = &priv->frame_hdr;
|
||||
|
||||
picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
|
||||
picture->type =
|
||||
(frame_hdr->frame_type ==
|
||||
GST_VP9_KEY_FRAME) ? GST_VAAPI_PICTURE_TYPE_I : GST_VAAPI_PICTURE_TYPE_P;
|
||||
picture->pts = GST_VAAPI_DECODER_CODEC_FRAME (decoder)->pts;
|
||||
|
||||
if (!frame_hdr->show_frame)
|
||||
GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_SKIPPED);
|
||||
}
|
||||
|
||||
static void
|
||||
vaapi_fill_ref_frames (GstVaapiDecoderVp9 * decoder, GstVaapiPicture * picture,
|
||||
GstVp9FrameHdr * frame_hdr, VADecPictureParameterBufferVP9 * pic_param)
|
||||
{
|
||||
GstVaapiDecoderVp9Private *const priv = &decoder->priv;
|
||||
guint i;
|
||||
|
||||
if (frame_hdr->frame_type != GST_VP9_KEY_FRAME) {
|
||||
pic_param->pic_fields.bits.last_ref_frame =
|
||||
frame_hdr->ref_frame_indices[GST_VP9_REF_FRAME_LAST - 1];
|
||||
pic_param->pic_fields.bits.last_ref_frame_sign_bias =
|
||||
frame_hdr->ref_frame_sign_bias[GST_VP9_REF_FRAME_LAST - 1];
|
||||
pic_param->pic_fields.bits.golden_ref_frame =
|
||||
frame_hdr->ref_frame_indices[GST_VP9_REF_FRAME_GOLDEN - 1];
|
||||
pic_param->pic_fields.bits.golden_ref_frame_sign_bias =
|
||||
frame_hdr->ref_frame_sign_bias[GST_VP9_REF_FRAME_GOLDEN - 1];
|
||||
pic_param->pic_fields.bits.alt_ref_frame =
|
||||
frame_hdr->ref_frame_indices[GST_VP9_REF_FRAME_ALTREF - 1];
|
||||
pic_param->pic_fields.bits.alt_ref_frame_sign_bias =
|
||||
frame_hdr->ref_frame_sign_bias[GST_VP9_REF_FRAME_ALTREF - 1];
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (priv->ref_frames); i++) {
|
||||
pic_param->reference_frames[i] = priv->ref_frames[i] ?
|
||||
priv->ref_frames[i]->surface_id : VA_INVALID_SURFACE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fill_picture (GstVaapiDecoderVp9 * decoder, GstVaapiPicture * picture)
|
||||
{
|
||||
GstVaapiDecoderVp9Private *priv = &decoder->priv;
|
||||
VADecPictureParameterBufferVP9 *pic_param = picture->param;
|
||||
GstVp9Parser *parser = priv->parser;
|
||||
GstVp9FrameHdr *frame_hdr = &priv->frame_hdr;
|
||||
|
||||
/* Fill in VAPictureParameterBufferVP9 */
|
||||
pic_param->frame_width = frame_hdr->width;
|
||||
pic_param->frame_height = frame_hdr->height;
|
||||
|
||||
/* Fill in ReferenceFrames */
|
||||
vaapi_fill_ref_frames (decoder, picture, frame_hdr, pic_param);
|
||||
|
||||
#define COPY_FIELD(s, f) \
|
||||
pic_param->f = (s)->f
|
||||
#define COPY_BFM(a, s, f) \
|
||||
pic_param->a.bits.f = (s)->f
|
||||
|
||||
COPY_BFM (pic_fields, parser, subsampling_x);
|
||||
COPY_BFM (pic_fields, parser, subsampling_y);
|
||||
COPY_BFM (pic_fields, frame_hdr, frame_type);
|
||||
COPY_BFM (pic_fields, frame_hdr, show_frame);
|
||||
COPY_BFM (pic_fields, frame_hdr, error_resilient_mode);
|
||||
COPY_BFM (pic_fields, frame_hdr, intra_only);
|
||||
COPY_BFM (pic_fields, frame_hdr, allow_high_precision_mv);
|
||||
COPY_BFM (pic_fields, frame_hdr, mcomp_filter_type);
|
||||
COPY_BFM (pic_fields, frame_hdr, frame_parallel_decoding_mode);
|
||||
COPY_BFM (pic_fields, frame_hdr, reset_frame_context);
|
||||
COPY_BFM (pic_fields, frame_hdr, refresh_frame_context);
|
||||
COPY_BFM (pic_fields, frame_hdr, frame_context_idx);
|
||||
COPY_BFM (pic_fields, frame_hdr, lossless_flag);
|
||||
|
||||
pic_param->pic_fields.bits.segmentation_enabled =
|
||||
frame_hdr->segmentation.enabled;
|
||||
pic_param->pic_fields.bits.segmentation_temporal_update =
|
||||
frame_hdr->segmentation.temporal_update;
|
||||
pic_param->pic_fields.bits.segmentation_update_map =
|
||||
frame_hdr->segmentation.update_map;
|
||||
|
||||
COPY_FIELD (&frame_hdr->loopfilter, filter_level);
|
||||
COPY_FIELD (&frame_hdr->loopfilter, sharpness_level);
|
||||
COPY_FIELD (frame_hdr, log2_tile_rows);
|
||||
COPY_FIELD (frame_hdr, log2_tile_columns);
|
||||
COPY_FIELD (frame_hdr, frame_header_length_in_bytes);
|
||||
COPY_FIELD (frame_hdr, first_partition_size);
|
||||
COPY_FIELD (frame_hdr, profile);
|
||||
#if VA_CHECK_VERSION (0, 39, 0)
|
||||
COPY_FIELD (parser, bit_depth);
|
||||
#endif
|
||||
|
||||
g_assert (G_N_ELEMENTS (pic_param->mb_segment_tree_probs) ==
|
||||
G_N_ELEMENTS (parser->mb_segment_tree_probs));
|
||||
g_assert (G_N_ELEMENTS (pic_param->segment_pred_probs) ==
|
||||
G_N_ELEMENTS (parser->segment_pred_probs));
|
||||
|
||||
memcpy (pic_param->mb_segment_tree_probs, parser->mb_segment_tree_probs,
|
||||
sizeof (parser->mb_segment_tree_probs));
|
||||
|
||||
if (frame_hdr->segmentation.temporal_update) {
|
||||
memcpy (pic_param->segment_pred_probs, parser->segment_pred_probs,
|
||||
sizeof (parser->segment_pred_probs));
|
||||
} else {
|
||||
memset (pic_param->segment_pred_probs, 255,
|
||||
sizeof (pic_param->segment_pred_probs));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fill_slice (GstVaapiDecoderVp9 * decoder, GstVaapiSlice * slice)
|
||||
{
|
||||
GstVaapiDecoderVp9Private *const priv = &decoder->priv;
|
||||
GstVp9Parser *parser = priv->parser;
|
||||
VASliceParameterBufferVP9 *const slice_param = slice->param;
|
||||
guint i;
|
||||
|
||||
#define COPY_SEG_FIELD(s, f) \
|
||||
seg_param->f = (s)->f
|
||||
|
||||
/* Fill in VASliceParameterBufferVP9 */
|
||||
for (i = 0; i < GST_VP9_MAX_SEGMENTS; i++) {
|
||||
VASegmentParameterVP9 *seg_param = &slice_param->seg_param[i];
|
||||
GstVp9Segmentation *seg = &parser->segmentation[i];
|
||||
|
||||
memcpy (seg_param->filter_level, seg->filter_level,
|
||||
sizeof (seg->filter_level));
|
||||
COPY_SEG_FIELD (seg, luma_ac_quant_scale);
|
||||
COPY_SEG_FIELD (seg, luma_dc_quant_scale);
|
||||
COPY_SEG_FIELD (seg, chroma_ac_quant_scale);
|
||||
COPY_SEG_FIELD (seg, chroma_dc_quant_scale);
|
||||
|
||||
seg_param->segment_flags.fields.segment_reference_skipped =
|
||||
seg->reference_skip;
|
||||
seg_param->segment_flags.fields.segment_reference_enabled =
|
||||
seg->reference_frame_enabled;
|
||||
seg_param->segment_flags.fields.segment_reference = seg->reference_frame;
|
||||
|
||||
}
|
||||
/* Fixme: When segmentation is disabled, only seg_param[0] has valid values,
|
||||
* all other entries should be populated with 0 ? */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_slice (GstVaapiDecoderVp9 * decoder, GstVaapiPicture * picture,
|
||||
const guchar * buf, guint buf_size)
|
||||
{
|
||||
GstVaapiSlice *slice;
|
||||
|
||||
slice = GST_VAAPI_SLICE_NEW (VP9, decoder, buf, buf_size);
|
||||
if (!slice) {
|
||||
GST_ERROR ("failed to allocate slice");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
|
||||
if (!fill_slice (decoder, slice)) {
|
||||
gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (slice));
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
gst_vaapi_picture_add_slice (GST_VAAPI_PICTURE_CAST (picture), slice);
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
update_ref_frames (GstVaapiDecoderVp9 * decoder)
|
||||
{
|
||||
GstVaapiDecoderVp9Private *const priv = &decoder->priv;
|
||||
GstVaapiPicture *picture = priv->current_picture;
|
||||
GstVp9FrameHdr *const frame_hdr = &priv->frame_hdr;
|
||||
guint8 refresh_frame_flags, mask, i = 0;
|
||||
|
||||
if (frame_hdr->frame_type == GST_VP9_KEY_FRAME)
|
||||
refresh_frame_flags = (1 << GST_VP9_REF_FRAMES) - 1;
|
||||
else
|
||||
refresh_frame_flags = frame_hdr->refresh_frame_flags;
|
||||
|
||||
for (mask = refresh_frame_flags; mask; mask >>= 1, ++i) {
|
||||
if (mask & 1)
|
||||
gst_vaapi_picture_replace (&priv->ref_frames[i], picture);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GST_VAAPI_PICTURE_NEW
|
||||
#undef GST_VAAPI_PICTURE_NEW
|
||||
#endif
|
||||
|
||||
#define GST_VAAPI_PICTURE_NEW(codec, decoder) \
|
||||
gst_vaapi_picture_new (GST_VAAPI_DECODER_CAST (decoder), \
|
||||
NULL, sizeof (G_PASTE (VADecPictureParameterBuffer, codec)))
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_picture (GstVaapiDecoderVp9 * decoder, const guchar * buf,
|
||||
guint buf_size)
|
||||
{
|
||||
GstVaapiDecoderVp9Private *const priv = &decoder->priv;
|
||||
GstVp9FrameHdr *frame_hdr = &priv->frame_hdr;
|
||||
GstVaapiPicture *picture;
|
||||
GstVaapiDecoderStatus status;
|
||||
guint crop_width = 0, crop_height = 0;
|
||||
gboolean is_clone_pic = FALSE;
|
||||
|
||||
status = ensure_context (decoder);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
/* if show_exising_frame flag is true, we just need to return
|
||||
* the existing frame in ref frame array, so creating a clone
|
||||
* of already decoded frame */
|
||||
if (frame_hdr->show_existing_frame) {
|
||||
GstVaapiPicture *existing_frame =
|
||||
priv->ref_frames[frame_hdr->frame_to_show];
|
||||
|
||||
if (!existing_frame) {
|
||||
GST_ERROR ("Failed to get the existing frame from dpb");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
picture = gst_vaapi_picture_new_clone (existing_frame);
|
||||
if (!picture) {
|
||||
GST_ERROR ("Failed to create clone picture");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
is_clone_pic = TRUE;
|
||||
|
||||
/* for cloned picture we should always unset the skip flag since
|
||||
* the previously decoded frame might be decode-only but repeat-frame
|
||||
* should make it ready for display */
|
||||
GST_VAAPI_PICTURE_FLAG_UNSET (picture, GST_VAAPI_PICTURE_FLAG_SKIPPED);
|
||||
|
||||
/* reset picture pts with whatever set in VideoCodecFrame */
|
||||
picture->pts = GST_VAAPI_DECODER_CODEC_FRAME (decoder)->pts;
|
||||
} else {
|
||||
/* Create new picture */
|
||||
picture = GST_VAAPI_PICTURE_NEW (VP9, decoder);
|
||||
if (!picture) {
|
||||
GST_ERROR ("failed to allocate picture");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
}
|
||||
gst_vaapi_picture_replace (&priv->current_picture, picture);
|
||||
gst_vaapi_picture_unref (picture);
|
||||
|
||||
if (is_clone_pic)
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
|
||||
if (priv->width > frame_hdr->width || priv->height > frame_hdr->height) {
|
||||
crop_width = frame_hdr->width;
|
||||
crop_height = frame_hdr->height;
|
||||
}
|
||||
if (crop_width || crop_height) {
|
||||
GstVaapiRectangle crop_rect;
|
||||
crop_rect.x = 0;
|
||||
crop_rect.y = 0;
|
||||
crop_rect.width = crop_width;
|
||||
crop_rect.height = crop_height;
|
||||
gst_vaapi_picture_set_crop_rect (picture, &crop_rect);
|
||||
}
|
||||
|
||||
init_picture (decoder, picture);
|
||||
if (!fill_picture (decoder, picture))
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
|
||||
return decode_slice (decoder, picture, buf, buf_size);
|
||||
}
|
||||
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_current_picture (GstVaapiDecoderVp9 * decoder)
|
||||
{
|
||||
GstVaapiDecoderVp9Private *const priv = &decoder->priv;
|
||||
GstVaapiPicture *const picture = priv->current_picture;
|
||||
GstVp9FrameHdr *const frame_hdr = &priv->frame_hdr;
|
||||
|
||||
if (!picture)
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
|
||||
if (frame_hdr->show_existing_frame)
|
||||
goto ret;
|
||||
|
||||
if (!gst_vaapi_picture_decode (picture))
|
||||
goto error;
|
||||
|
||||
update_ref_frames (decoder);
|
||||
|
||||
ret:
|
||||
if (!gst_vaapi_picture_output (picture))
|
||||
goto error;
|
||||
|
||||
gst_vaapi_picture_replace (&priv->current_picture, NULL);
|
||||
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
|
||||
/* ERRORS */
|
||||
error:
|
||||
{
|
||||
/* XXX: fix for cases where first field failed to be decoded */
|
||||
gst_vaapi_picture_replace (&priv->current_picture, NULL);
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_super_frame (const guchar * data, guint data_size,
|
||||
guint * frame_sizes, guint * frame_count, guint * total_idx_size)
|
||||
{
|
||||
guint8 marker;
|
||||
guint32 num_frames = 1, frame_size_length, total_index_size;
|
||||
guint i, j;
|
||||
|
||||
if (data_size <= 0)
|
||||
return FALSE;
|
||||
|
||||
marker = data[data_size - 1];
|
||||
|
||||
if ((marker & 0xe0) == 0xc0) {
|
||||
|
||||
GST_DEBUG ("Got VP9-Super Frame, size %d", data_size);
|
||||
|
||||
num_frames = (marker & 0x7) + 1;
|
||||
frame_size_length = ((marker >> 3) & 0x3) + 1;
|
||||
total_index_size = 2 + num_frames * frame_size_length;
|
||||
|
||||
if ((data_size >= total_index_size)
|
||||
&& (data[data_size - total_index_size] == marker)) {
|
||||
const guint8 *x = &data[data_size - total_index_size + 1];
|
||||
|
||||
for (i = 0; i < num_frames; i++) {
|
||||
guint32 cur_frame_size = 0;
|
||||
|
||||
for (j = 0; j < frame_size_length; j++)
|
||||
cur_frame_size |= (*x++) << (j * 8);
|
||||
|
||||
frame_sizes[i] = cur_frame_size;
|
||||
}
|
||||
|
||||
*frame_count = num_frames;
|
||||
*total_idx_size = total_index_size;
|
||||
} else {
|
||||
GST_ERROR ("Failed to parse Super-frame");
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
*frame_count = num_frames;
|
||||
frame_sizes[0] = data_size;
|
||||
*total_idx_size = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
parse_frame_header (GstVaapiDecoderVp9 * decoder, const guchar * buf,
|
||||
guint buf_size, GstVp9FrameHdr * frame_hdr)
|
||||
{
|
||||
GstVaapiDecoderVp9Private *const priv = &decoder->priv;
|
||||
GstVp9ParserResult result;
|
||||
guint width, height;
|
||||
|
||||
result = gst_vp9_parser_parse_frame_header (priv->parser, frame_hdr,
|
||||
buf, buf_size);
|
||||
if (result != GST_VP9_PARSER_OK)
|
||||
return get_status (result);
|
||||
|
||||
/* Unlike other decoders, vp9 decoder doesn't need to reset the
|
||||
* whole context and surfaces for each resolution change. Calling
|
||||
* ensure_context() again is only needed if the resolution of any frame
|
||||
* is greater than what was previously configured, so that new, larger
|
||||
* surfaces can be allocated. There are streams where a bigger
|
||||
* resolution set in ivf header or webm header but actual resolution
|
||||
* of all frames are less. Also it is possible to have inter-prediction
|
||||
* between these multi resolution frames */
|
||||
width = GST_VAAPI_DECODER_WIDTH (decoder);
|
||||
height = GST_VAAPI_DECODER_HEIGHT (decoder);
|
||||
if (priv->width < width || priv->height < height) {
|
||||
priv->width = GST_VAAPI_DECODER_WIDTH (decoder);
|
||||
priv->height = GST_VAAPI_DECODER_HEIGHT (decoder);
|
||||
priv->size_changed = TRUE;
|
||||
}
|
||||
if ((frame_hdr->width > priv->width || frame_hdr->height > priv->height)) {
|
||||
priv->width = frame_hdr->width;
|
||||
priv->height = frame_hdr->height;
|
||||
priv->size_changed = TRUE;
|
||||
}
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_vp9_parse (GstVaapiDecoder * base_decoder,
|
||||
GstAdapter * adapter, gboolean at_eos, GstVaapiDecoderUnit * unit)
|
||||
{
|
||||
GstVaapiDecoderVp9 *const decoder = GST_VAAPI_DECODER_VP9_CAST (base_decoder);
|
||||
GstVaapiDecoderVp9Private *const priv = &decoder->priv;
|
||||
guchar *buf;
|
||||
guint buf_size, flags = 0;
|
||||
|
||||
buf_size = gst_adapter_available (adapter);
|
||||
if (!buf_size)
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
|
||||
buf = (guchar *) gst_adapter_map (adapter, buf_size);
|
||||
if (!buf)
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
|
||||
|
||||
if (!priv->had_superframe_hdr) {
|
||||
if (!parse_super_frame (buf, buf_size, priv->frame_sizes, &priv->num_frames,
|
||||
&priv->total_idx_size))
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
|
||||
|
||||
if (priv->num_frames > 1)
|
||||
priv->had_superframe_hdr = TRUE;
|
||||
}
|
||||
|
||||
unit->size = priv->frame_sizes[priv->frame_cnt++];
|
||||
|
||||
if (priv->frame_cnt == priv->num_frames) {
|
||||
priv->num_frames = 0;
|
||||
priv->frame_cnt = 0;
|
||||
priv->had_superframe_hdr = FALSE;
|
||||
unit->size += priv->total_idx_size;
|
||||
}
|
||||
|
||||
/* The whole frame is available */
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END;
|
||||
|
||||
GST_VAAPI_DECODER_UNIT_FLAG_SET (unit, flags);
|
||||
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_buffer (GstVaapiDecoderVp9 * decoder, const guchar * buf, guint buf_size)
|
||||
{
|
||||
GstVaapiDecoderVp9Private *const priv = &decoder->priv;
|
||||
GstVaapiDecoderStatus status;
|
||||
guint size = buf_size;
|
||||
|
||||
if (priv->total_idx_size && !priv->had_superframe_hdr) {
|
||||
size -= priv->total_idx_size;
|
||||
priv->total_idx_size = 0;
|
||||
}
|
||||
|
||||
status = parse_frame_header (decoder, buf, size, &priv->frame_hdr);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return decode_picture (decoder, buf, size);
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_vp9_decode (GstVaapiDecoder * base_decoder,
|
||||
GstVaapiDecoderUnit * unit)
|
||||
{
|
||||
GstVaapiDecoderVp9 *const decoder = GST_VAAPI_DECODER_VP9_CAST (base_decoder);
|
||||
GstVaapiDecoderStatus status;
|
||||
GstBuffer *const buffer =
|
||||
GST_VAAPI_DECODER_CODEC_FRAME (decoder)->input_buffer;
|
||||
GstMapInfo map_info;
|
||||
|
||||
if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) {
|
||||
GST_ERROR ("failed to map buffer");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
status = decode_buffer (decoder, map_info.data + unit->offset, unit->size);
|
||||
gst_buffer_unmap (buffer, &map_info);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_vp9_start_frame (GstVaapiDecoder * base_decoder,
|
||||
GstVaapiDecoderUnit * base_unit)
|
||||
{
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_vp9_end_frame (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
GstVaapiDecoderVp9 *const decoder = GST_VAAPI_DECODER_VP9_CAST (base_decoder);
|
||||
|
||||
return decode_current_picture (decoder);
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_vp9_flush (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_vp9_finalize (GObject * object)
|
||||
{
|
||||
GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (object);
|
||||
|
||||
gst_vaapi_decoder_vp9_destroy (base_decoder);
|
||||
G_OBJECT_CLASS (gst_vaapi_decoder_vp9_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_vp9_class_init (GstVaapiDecoderVp9Class * klass)
|
||||
{
|
||||
GObjectClass *const object_class = G_OBJECT_CLASS (klass);
|
||||
GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass);
|
||||
|
||||
object_class->finalize = gst_vaapi_decoder_vp9_finalize;
|
||||
|
||||
decoder_class->reset = gst_vaapi_decoder_vp9_reset;
|
||||
decoder_class->parse = gst_vaapi_decoder_vp9_parse;
|
||||
decoder_class->decode = gst_vaapi_decoder_vp9_decode;
|
||||
decoder_class->start_frame = gst_vaapi_decoder_vp9_start_frame;
|
||||
decoder_class->end_frame = gst_vaapi_decoder_vp9_end_frame;
|
||||
decoder_class->flush = gst_vaapi_decoder_vp9_flush;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_vp9_init (GstVaapiDecoderVp9 * decoder)
|
||||
{
|
||||
GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder);
|
||||
|
||||
gst_vaapi_decoder_vp9_create (base_decoder);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_decoder_vp9_new:
|
||||
* @display: a #GstVaapiDisplay
|
||||
* @caps: a #GstCaps holding codec information
|
||||
*
|
||||
* Creates a new #GstVaapiDecoder for VP9 decoding. The @caps can
|
||||
* hold extra information like codec-data and pictured coded size.
|
||||
*
|
||||
* Return value: the newly allocated #GstVaapiDecoder object
|
||||
*/
|
||||
GstVaapiDecoder *
|
||||
gst_vaapi_decoder_vp9_new (GstVaapiDisplay * display, GstCaps * caps)
|
||||
{
|
||||
return g_object_new (GST_TYPE_VAAPI_DECODER_VP9, "display", display,
|
||||
"caps", caps, NULL);
|
||||
}
|
49
gst-libs/gst/vaapi/gstvaapidecoder_vp9.h
Normal file
49
gst-libs/gst/vaapi/gstvaapidecoder_vp9.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* gstvaapidecoder_vp9.h - VP9 decoder
|
||||
*
|
||||
* Copyright (C) 2015-2016 Intel Corporation
|
||||
* Author: Sreerenj Balachandran <sreerenj.balachandran@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DECODER_VP9_H
|
||||
#define GST_VAAPI_DECODER_VP9_H
|
||||
|
||||
#include <gst/vaapi/gstvaapidecoder.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_DECODER_VP9 \
|
||||
(gst_vaapi_decoder_vp9_get_type ())
|
||||
#define GST_VAAPI_DECODER_VP9(decoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DECODER_VP9, GstVaapiDecoderVp9))
|
||||
#define GST_VAAPI_IS_DECODER_VP9(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_DECODER_VP9))
|
||||
|
||||
typedef struct _GstVaapiDecoderVp9 GstVaapiDecoderVp9;
|
||||
|
||||
GType
|
||||
gst_vaapi_decoder_vp9_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GstVaapiDecoder *
|
||||
gst_vaapi_decoder_vp9_new (GstVaapiDisplay * display, GstCaps * caps);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDecoderVp9, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DECODER_VP9_H */
|
2185
gst-libs/gst/vaapi/gstvaapidisplay.c
Normal file
2185
gst-libs/gst/vaapi/gstvaapidisplay.c
Normal file
File diff suppressed because it is too large
Load diff
293
gst-libs/gst/vaapi/gstvaapidisplay.h
Normal file
293
gst-libs/gst/vaapi/gstvaapidisplay.h
Normal file
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
* gstvaapidisplay.h - VA display abstraction
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||
* Copyright (C) 2011-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DISPLAY_H
|
||||
#define GST_VAAPI_DISPLAY_H
|
||||
|
||||
#include <va/va.h>
|
||||
#include <gst/gst.h>
|
||||
#include <gst/vaapi/gstvaapitypes.h>
|
||||
#include <gst/vaapi/gstvaapiprofile.h>
|
||||
#include <gst/vaapi/video-format.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_DISPLAY (gst_vaapi_display_get_type ())
|
||||
#define GST_VAAPI_DISPLAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DISPLAY, GstVaapiDisplay))
|
||||
#define GST_VAAPI_IS_DISPLAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_DISPLAY))
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DISPLAY_GET_CLASS_TYPE:
|
||||
* @display: a #GstVaapiDisplay
|
||||
*
|
||||
* Returns the #display class type
|
||||
*/
|
||||
#define GST_VAAPI_DISPLAY_GET_CLASS_TYPE(display) \
|
||||
gst_vaapi_display_get_class_type (GST_VAAPI_DISPLAY (display))
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DISPLAY_VADISPLAY_TYPE:
|
||||
* @display: a #GstVaapiDisplay
|
||||
*
|
||||
* Returns the underlying VADisplay @display type.
|
||||
*/
|
||||
#define GST_VAAPI_DISPLAY_VADISPLAY_TYPE(display) \
|
||||
gst_vaapi_display_get_display_type (GST_VAAPI_DISPLAY (display))
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DISPLAY_VADISPLAY:
|
||||
* @display_: a #GstVaapiDisplay
|
||||
*
|
||||
* Macro that evaluates to the #VADisplay of @display.
|
||||
*/
|
||||
#define GST_VAAPI_DISPLAY_VADISPLAY(display) \
|
||||
gst_vaapi_display_get_display (GST_VAAPI_DISPLAY (display))
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DISPLAY_LOCK:
|
||||
* @display: a #GstVaapiDisplay
|
||||
*
|
||||
* Locks @display
|
||||
*/
|
||||
#define GST_VAAPI_DISPLAY_LOCK(display) \
|
||||
gst_vaapi_display_lock (GST_VAAPI_DISPLAY (display))
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DISPLAY_UNLOCK:
|
||||
* @display: a #GstVaapiDisplay
|
||||
*
|
||||
* Unlocks @display
|
||||
*/
|
||||
#define GST_VAAPI_DISPLAY_UNLOCK(display) \
|
||||
gst_vaapi_display_unlock (GST_VAAPI_DISPLAY (display))
|
||||
|
||||
typedef struct _GstVaapiDisplayInfo GstVaapiDisplayInfo;
|
||||
typedef struct _GstVaapiDisplay GstVaapiDisplay;
|
||||
|
||||
/**
|
||||
* GstVaapiDriverQuirks:
|
||||
* @GST_VAAPI_DRIVER_QUIRK_NO_CHECK_SURFACE_PUT_IMAGE: if driver
|
||||
* crashes when try to put an image in a reused surface.
|
||||
* https://gitlab.freedesktop.org/mesa/mesa/merge_requests/2016
|
||||
* @GST_VAAPI_DRIVER_QUIRK_NO_CHECK_VPP_COLOR_STD: if driver does not
|
||||
* properly report supported vpp color standards.
|
||||
* @GST_VAAPI_DRIVER_QUIRK_MISSING_RGBA_IMAGE_FORMAT: i965 driver doesn't
|
||||
* report to support ARGB format, but if it's forced to create a RGBA
|
||||
* surface, it works. Driver issue:
|
||||
* https://github.com/intel/intel-vaapi-driver/issues/500
|
||||
* @GST_VAAPI_DRIVER_QUIRK_JPEG_ENC_SHIFT_VALUE_BY_50: if the driver shifts
|
||||
* the value by 50 when calculating quantization from quality level
|
||||
* @GST_VAAPI_DRIVER_QUIRK_HEVC_ENC_SLICE_NOT_SPAN_TILE: The requirement
|
||||
* that one slice should not span tiles when tile is enabled.
|
||||
* @GST_VAAPI_DRIVER_QUIRK_JPEG_DEC_BROKEN_FORMATS: i965 driver does not
|
||||
* report all the handled formats for JPEG decoding.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GST_VAAPI_DRIVER_QUIRK_NO_CHECK_SURFACE_PUT_IMAGE = (1U << 0),
|
||||
GST_VAAPI_DRIVER_QUIRK_NO_CHECK_VPP_COLOR_STD = (1U << 1),
|
||||
GST_VAAPI_DRIVER_QUIRK_MISSING_RGBA_IMAGE_FORMAT = (1U << 3),
|
||||
GST_VAAPI_DRIVER_QUIRK_JPEG_ENC_SHIFT_VALUE_BY_50 = (1U << 4),
|
||||
GST_VAAPI_DRIVER_QUIRK_HEVC_ENC_SLICE_NOT_SPAN_TILE = (1U << 5),
|
||||
GST_VAAPI_DRIVER_QUIRK_JPEG_DEC_BROKEN_FORMATS = (1U << 6),
|
||||
} GstVaapiDriverQuirks;
|
||||
|
||||
/**
|
||||
* GstVaapiDisplayType:
|
||||
* @GST_VAAPI_DISPLAY_TYPE_ANY: Automatic detection of the display type.
|
||||
* @GST_VAAPI_DISPLAY_TYPE_X11: VA/X11 display.
|
||||
* @GST_VAAPI_DISPLAY_TYPE_GLX: VA/GLX display.
|
||||
* @GST_VAAPI_DISPLAY_TYPE_WAYLAND: VA/Wayland display.
|
||||
* @GST_VAAPI_DISPLAY_TYPE_DRM: VA/DRM display.
|
||||
* @GST_VAAPI_DISPLAY_TYPE_EGL: VA/EGL display.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GST_VAAPI_DISPLAY_TYPE_ANY = 0,
|
||||
GST_VAAPI_DISPLAY_TYPE_X11,
|
||||
GST_VAAPI_DISPLAY_TYPE_GLX,
|
||||
GST_VAAPI_DISPLAY_TYPE_WAYLAND,
|
||||
GST_VAAPI_DISPLAY_TYPE_DRM,
|
||||
GST_VAAPI_DISPLAY_TYPE_EGL,
|
||||
} GstVaapiDisplayType;
|
||||
|
||||
#define GST_VAAPI_TYPE_DISPLAY_TYPE \
|
||||
(gst_vaapi_display_type_get_type())
|
||||
|
||||
GType
|
||||
gst_vaapi_display_type_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GType
|
||||
gst_vaapi_display_get_type (void) G_GNUC_CONST;
|
||||
|
||||
gboolean
|
||||
gst_vaapi_display_type_is_compatible (GstVaapiDisplayType type1,
|
||||
GstVaapiDisplayType type2);
|
||||
|
||||
/**
|
||||
* GstVaapiDisplayInfo:
|
||||
*
|
||||
* Generic class to retrieve VA display info
|
||||
*/
|
||||
struct _GstVaapiDisplayInfo
|
||||
{
|
||||
GstVaapiDisplay *display;
|
||||
gchar *display_name;
|
||||
VADisplay va_display;
|
||||
gpointer native_display;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDisplayProperties:
|
||||
* @GST_VAAPI_DISPLAY_PROP_RENDER_MODE: rendering mode (#GstVaapiRenderMode).
|
||||
* @GST_VAAPI_DISPLAY_PROP_ROTATION: rotation angle (#GstVaapiRotation).
|
||||
* @GST_VAAPI_DISPLAY_PROP_HUE: hue (float: [-180 ; 180], default: 0).
|
||||
* @GST_VAAPI_DISPLAY_PROP_SATURATION: saturation (float: [0 ; 2], default: 1).
|
||||
* @GST_VAAPI_DISPLAY_PROP_BRIGHTNESS: brightness (float: [-1 ; 1], default: 0).
|
||||
* @GST_VAAPI_DISPLAY_PROP_CONTRAST: contrast (float: [0 ; 2], default: 1).
|
||||
*/
|
||||
#define GST_VAAPI_DISPLAY_PROP_RENDER_MODE "render-mode"
|
||||
#define GST_VAAPI_DISPLAY_PROP_ROTATION "rotation"
|
||||
#define GST_VAAPI_DISPLAY_PROP_HUE "hue"
|
||||
#define GST_VAAPI_DISPLAY_PROP_SATURATION "saturation"
|
||||
#define GST_VAAPI_DISPLAY_PROP_BRIGHTNESS "brightness"
|
||||
#define GST_VAAPI_DISPLAY_PROP_CONTRAST "contrast"
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_new_with_display (VADisplay va_display);
|
||||
|
||||
void
|
||||
gst_vaapi_display_replace (GstVaapiDisplay ** old_display_ptr,
|
||||
GstVaapiDisplay * new_display);
|
||||
|
||||
void
|
||||
gst_vaapi_display_lock (GstVaapiDisplay * display);
|
||||
|
||||
void
|
||||
gst_vaapi_display_unlock (GstVaapiDisplay * display);
|
||||
|
||||
void
|
||||
gst_vaapi_display_sync (GstVaapiDisplay * display);
|
||||
|
||||
void
|
||||
gst_vaapi_display_flush (GstVaapiDisplay * display);
|
||||
|
||||
GstVaapiDisplayType
|
||||
gst_vaapi_display_get_class_type (GstVaapiDisplay * display);
|
||||
|
||||
GstVaapiDisplayType
|
||||
gst_vaapi_display_get_display_type (GstVaapiDisplay * display);
|
||||
|
||||
const gchar *
|
||||
gst_vaapi_display_get_display_name (GstVaapiDisplay * display);
|
||||
|
||||
VADisplay
|
||||
gst_vaapi_display_get_display (GstVaapiDisplay * display);
|
||||
|
||||
guint
|
||||
gst_vaapi_display_get_width (GstVaapiDisplay * display);
|
||||
|
||||
guint
|
||||
gst_vaapi_display_get_height (GstVaapiDisplay * display);
|
||||
|
||||
void
|
||||
gst_vaapi_display_get_size (GstVaapiDisplay * display, guint * pwidth,
|
||||
guint * pheight);
|
||||
|
||||
void
|
||||
gst_vaapi_display_get_pixel_aspect_ratio (GstVaapiDisplay * display,
|
||||
guint * par_n, guint * par_d);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_display_has_video_processing (GstVaapiDisplay * display);
|
||||
|
||||
GArray *
|
||||
gst_vaapi_display_get_decode_profiles (GstVaapiDisplay * display);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_display_has_decoder (GstVaapiDisplay * display,
|
||||
GstVaapiProfile profile, GstVaapiEntrypoint entrypoint);
|
||||
|
||||
GArray *
|
||||
gst_vaapi_display_get_encode_profiles (GstVaapiDisplay * display);
|
||||
|
||||
GArray *
|
||||
gst_vaapi_display_get_encode_profiles_by_codec (GstVaapiDisplay * display,
|
||||
GstVaapiCodec codec);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_display_has_encoder (GstVaapiDisplay * display,
|
||||
GstVaapiProfile profile, GstVaapiEntrypoint entrypoint);
|
||||
|
||||
GArray *
|
||||
gst_vaapi_display_get_image_formats (GstVaapiDisplay * display);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_display_has_image_format (GstVaapiDisplay * display,
|
||||
GstVideoFormat format);
|
||||
|
||||
GArray *
|
||||
gst_vaapi_display_get_subpicture_formats (GstVaapiDisplay * display);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_display_has_subpicture_format (GstVaapiDisplay * display,
|
||||
GstVideoFormat format, guint * flags_ptr);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_display_has_property (GstVaapiDisplay * display, const gchar * name);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_display_get_render_mode (GstVaapiDisplay * display,
|
||||
GstVaapiRenderMode * pmode);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_display_set_render_mode (GstVaapiDisplay * display,
|
||||
GstVaapiRenderMode mode);
|
||||
|
||||
GstVaapiRotation
|
||||
gst_vaapi_display_get_rotation (GstVaapiDisplay * display);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_display_set_rotation (GstVaapiDisplay * display,
|
||||
GstVaapiRotation rotation);
|
||||
|
||||
const gchar *
|
||||
gst_vaapi_display_get_vendor_string (GstVaapiDisplay * display);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_display_has_opengl (GstVaapiDisplay * display);
|
||||
|
||||
void
|
||||
gst_vaapi_display_reset_texture_map (GstVaapiDisplay * display);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_display_has_driver_quirks (GstVaapiDisplay * display, guint quirks);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDisplay, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DISPLAY_H */
|
470
gst-libs/gst/vaapi/gstvaapidisplay_drm.c
Normal file
470
gst-libs/gst/vaapi/gstvaapidisplay_drm.c
Normal file
|
@ -0,0 +1,470 @@
|
|||
/*
|
||||
* gstvaapidisplay_drm.c - VA/DRM display abstraction
|
||||
*
|
||||
* Copyright (C) 2012-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstvaapidisplay_drm
|
||||
* @short_description: VA/DRM display abstraction
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "sysdeps.h"
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <libudev.h>
|
||||
#include <xf86drm.h>
|
||||
#include <va/va_drm.h>
|
||||
#include "gstvaapiutils.h"
|
||||
#include "gstvaapidisplay_priv.h"
|
||||
#include "gstvaapidisplay_drm.h"
|
||||
#include "gstvaapidisplay_drm_priv.h"
|
||||
#include "gstvaapiwindow_drm.h"
|
||||
|
||||
#define DEBUG_VAAPI_DISPLAY 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
#ifndef MAXPATHLEN
|
||||
#if defined(PATH_MAX)
|
||||
#define MAXPATHLEN PATH_MAX
|
||||
#elif defined(_PC_PATH_MAX)
|
||||
#define MAXPATHLEN sysconf(_PC_PATH_MAX)
|
||||
#else
|
||||
#define MAXPATHLEN 2048
|
||||
#endif
|
||||
#endif
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GstVaapiDisplayDRM, gst_vaapi_display_drm,
|
||||
GST_TYPE_VAAPI_DISPLAY);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DRM_DEVICE_LEGACY = 1,
|
||||
DRM_DEVICE_RENDERNODES,
|
||||
} DRMDeviceType;
|
||||
|
||||
static DRMDeviceType g_drm_device_type;
|
||||
static GMutex g_drm_device_type_lock;
|
||||
static const gchar *allowed_subsystems[] = { "pci", "platform", NULL };
|
||||
|
||||
static gboolean
|
||||
supports_vaapi (int fd)
|
||||
{
|
||||
gboolean ret;
|
||||
VADisplay va_dpy;
|
||||
|
||||
va_dpy = vaGetDisplayDRM (fd);
|
||||
if (!va_dpy)
|
||||
return FALSE;
|
||||
|
||||
ret = vaapi_initialize (va_dpy);
|
||||
vaTerminate (va_dpy);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get default device path. Actually, the first match in the DRM subsystem */
|
||||
static const gchar *
|
||||
get_default_device_path (GstVaapiDisplay * display)
|
||||
{
|
||||
GstVaapiDisplayDRMPrivate *const priv =
|
||||
GST_VAAPI_DISPLAY_DRM_PRIVATE (display);
|
||||
const gchar *syspath, *devpath;
|
||||
struct udev *udev = NULL;
|
||||
struct udev_device *device, *parent;
|
||||
struct udev_enumerate *e = NULL;
|
||||
struct udev_list_entry *l;
|
||||
gint i;
|
||||
int fd;
|
||||
|
||||
if (!priv->device_path_default) {
|
||||
udev = udev_new ();
|
||||
if (!udev)
|
||||
goto end;
|
||||
|
||||
e = udev_enumerate_new (udev);
|
||||
if (!e)
|
||||
goto end;
|
||||
|
||||
udev_enumerate_add_match_subsystem (e, "drm");
|
||||
switch (g_drm_device_type) {
|
||||
case DRM_DEVICE_LEGACY:
|
||||
udev_enumerate_add_match_sysname (e, "card[0-9]*");
|
||||
break;
|
||||
case DRM_DEVICE_RENDERNODES:
|
||||
udev_enumerate_add_match_sysname (e, "renderD[0-9]*");
|
||||
break;
|
||||
default:
|
||||
GST_ERROR ("unknown drm device type (%d)", g_drm_device_type);
|
||||
goto end;
|
||||
}
|
||||
udev_enumerate_scan_devices (e);
|
||||
udev_list_entry_foreach (l, udev_enumerate_get_list_entry (e)) {
|
||||
syspath = udev_list_entry_get_name (l);
|
||||
device = udev_device_new_from_syspath (udev, syspath);
|
||||
parent = udev_device_get_parent (device);
|
||||
|
||||
for (i = 0; allowed_subsystems[i] != NULL; i++)
|
||||
if (g_strcmp0 (udev_device_get_subsystem (parent),
|
||||
allowed_subsystems[i]) == 0)
|
||||
break;
|
||||
|
||||
if (allowed_subsystems[i] == NULL) {
|
||||
udev_device_unref (device);
|
||||
continue;
|
||||
}
|
||||
|
||||
devpath = udev_device_get_devnode (device);
|
||||
fd = open (devpath, O_RDWR | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
udev_device_unref (device);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (supports_vaapi (fd))
|
||||
priv->device_path_default = g_strdup (devpath);
|
||||
close (fd);
|
||||
udev_device_unref (device);
|
||||
if (priv->device_path_default)
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
if (e)
|
||||
udev_enumerate_unref (e);
|
||||
if (udev)
|
||||
udev_unref (udev);
|
||||
}
|
||||
return priv->device_path_default;
|
||||
}
|
||||
|
||||
/* Reconstruct a device path without our prefix */
|
||||
static const gchar *
|
||||
get_device_path (GstVaapiDisplay * display)
|
||||
{
|
||||
GstVaapiDisplayDRMPrivate *const priv =
|
||||
GST_VAAPI_DISPLAY_DRM_PRIVATE (display);
|
||||
const gchar *device_path = priv->device_path;
|
||||
|
||||
if (!device_path || *device_path == '\0')
|
||||
return NULL;
|
||||
return device_path;
|
||||
}
|
||||
|
||||
/* Mangle device path with our prefix */
|
||||
static gboolean
|
||||
set_device_path (GstVaapiDisplay * display, const gchar * device_path)
|
||||
{
|
||||
GstVaapiDisplayDRMPrivate *const priv =
|
||||
GST_VAAPI_DISPLAY_DRM_PRIVATE (display);
|
||||
|
||||
g_free (priv->device_path);
|
||||
priv->device_path = NULL;
|
||||
|
||||
if (!device_path) {
|
||||
device_path = get_default_device_path (display);
|
||||
if (!device_path)
|
||||
return FALSE;
|
||||
}
|
||||
priv->device_path = g_strdup (device_path);
|
||||
return priv->device_path != NULL;
|
||||
}
|
||||
|
||||
/* Set device path from file descriptor */
|
||||
static gboolean
|
||||
set_device_path_from_fd (GstVaapiDisplay * display, gint drm_device)
|
||||
{
|
||||
GstVaapiDisplayDRMPrivate *const priv =
|
||||
GST_VAAPI_DISPLAY_DRM_PRIVATE (display);
|
||||
gboolean success = FALSE;
|
||||
gchar fd_name[MAXPATHLEN];
|
||||
GError *error = NULL;
|
||||
|
||||
g_free (priv->device_path);
|
||||
priv->device_path = NULL;
|
||||
|
||||
if (drm_device < 0)
|
||||
goto end;
|
||||
|
||||
sprintf (fd_name, "/proc/%d/fd/%d", getpid (), drm_device);
|
||||
priv->device_path = g_file_read_link (fd_name, &error);
|
||||
|
||||
if (error) {
|
||||
g_error_free (error);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (g_str_has_prefix (priv->device_path, "/dev/dri/card") ||
|
||||
g_str_has_prefix (priv->device_path, "/dev/dri/renderD"))
|
||||
success = TRUE;
|
||||
else {
|
||||
g_free (priv->device_path);
|
||||
priv->device_path = NULL;
|
||||
}
|
||||
|
||||
end:
|
||||
return success;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_display_drm_bind_display (GstVaapiDisplay * display,
|
||||
gpointer native_display)
|
||||
{
|
||||
GstVaapiDisplayDRMPrivate *const priv =
|
||||
GST_VAAPI_DISPLAY_DRM_PRIVATE (display);
|
||||
|
||||
priv->drm_device = GPOINTER_TO_INT (native_display);
|
||||
priv->use_foreign_display = TRUE;
|
||||
|
||||
if (!set_device_path_from_fd (display, priv->drm_device))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_display_drm_open_display (GstVaapiDisplay * display,
|
||||
const gchar * name)
|
||||
{
|
||||
GstVaapiDisplayDRMPrivate *const priv =
|
||||
GST_VAAPI_DISPLAY_DRM_PRIVATE (display);
|
||||
|
||||
if (!set_device_path (display, name))
|
||||
return FALSE;
|
||||
|
||||
priv->drm_device = open (get_device_path (display), O_RDWR | O_CLOEXEC);
|
||||
if (priv->drm_device < 0)
|
||||
return FALSE;
|
||||
priv->use_foreign_display = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_drm_close_display (GstVaapiDisplay * display)
|
||||
{
|
||||
GstVaapiDisplayDRMPrivate *const priv =
|
||||
GST_VAAPI_DISPLAY_DRM_PRIVATE (display);
|
||||
|
||||
if (priv->drm_device >= 0) {
|
||||
if (!priv->use_foreign_display)
|
||||
close (priv->drm_device);
|
||||
priv->drm_device = -1;
|
||||
}
|
||||
|
||||
g_clear_pointer (&priv->device_path, g_free);
|
||||
g_clear_pointer (&priv->device_path_default, g_free);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_display_drm_get_display_info (GstVaapiDisplay * display,
|
||||
GstVaapiDisplayInfo * info)
|
||||
{
|
||||
GstVaapiDisplayDRMPrivate *const priv =
|
||||
GST_VAAPI_DISPLAY_DRM_PRIVATE (display);
|
||||
|
||||
info->native_display = GINT_TO_POINTER (priv->drm_device);
|
||||
info->display_name = priv->device_path;
|
||||
if (!info->va_display) {
|
||||
info->va_display = vaGetDisplayDRM (priv->drm_device);
|
||||
if (!info->va_display)
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstVaapiWindow *
|
||||
gst_vaapi_display_drm_create_window (GstVaapiDisplay * display, GstVaapiID id,
|
||||
guint width, guint height)
|
||||
{
|
||||
return id != GST_VAAPI_ID_INVALID ?
|
||||
NULL : gst_vaapi_window_drm_new (display, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_drm_init (GstVaapiDisplayDRM * display)
|
||||
{
|
||||
GstVaapiDisplayDRMPrivate *const priv =
|
||||
gst_vaapi_display_drm_get_instance_private (display);
|
||||
|
||||
display->priv = priv;
|
||||
priv->drm_device = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_drm_class_init (GstVaapiDisplayDRMClass * klass)
|
||||
{
|
||||
GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass);
|
||||
|
||||
dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_DRM;
|
||||
dpy_class->bind_display = gst_vaapi_display_drm_bind_display;
|
||||
dpy_class->open_display = gst_vaapi_display_drm_open_display;
|
||||
dpy_class->close_display = gst_vaapi_display_drm_close_display;
|
||||
dpy_class->get_display = gst_vaapi_display_drm_get_display_info;
|
||||
dpy_class->create_window = gst_vaapi_display_drm_create_window;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_drm_new:
|
||||
* @device_path: the DRM device path
|
||||
*
|
||||
* Opens an DRM file descriptor using @device_path and returns a newly
|
||||
* allocated #GstVaapiDisplay object. The DRM display will be cloed
|
||||
* when the reference count of the object reaches zero.
|
||||
*
|
||||
* If @device_path is NULL, the DRM device path will be automatically
|
||||
* determined as the first positive match in the list of available DRM
|
||||
* devices.
|
||||
*
|
||||
* Return value: a newly allocated #GstVaapiDisplay object
|
||||
*/
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_drm_new (const gchar * device_path)
|
||||
{
|
||||
GstVaapiDisplay *display;
|
||||
guint types[3], i, num_types = 0;
|
||||
gpointer device_paths[3];
|
||||
|
||||
g_mutex_lock (&g_drm_device_type_lock);
|
||||
if (device_path) {
|
||||
device_paths[num_types] = (gpointer) device_path;
|
||||
types[num_types++] = 0;
|
||||
} else if (g_drm_device_type) {
|
||||
device_paths[num_types] = (gpointer) device_path;
|
||||
types[num_types++] = g_drm_device_type;
|
||||
} else {
|
||||
const gchar *user_choice = g_getenv ("GST_VAAPI_DRM_DEVICE");
|
||||
|
||||
if (user_choice) {
|
||||
device_paths[num_types] = (gpointer) user_choice;
|
||||
types[num_types++] = 0;
|
||||
} else {
|
||||
device_paths[num_types] = (gpointer) device_path;
|
||||
types[num_types++] = DRM_DEVICE_RENDERNODES;
|
||||
device_paths[num_types] = (gpointer) device_path;
|
||||
types[num_types++] = DRM_DEVICE_LEGACY;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < num_types; i++) {
|
||||
g_drm_device_type = types[i];
|
||||
display = g_object_new (GST_TYPE_VAAPI_DISPLAY_DRM, NULL);
|
||||
display = gst_vaapi_display_config (display,
|
||||
GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, device_paths[i]);
|
||||
if (display || device_path)
|
||||
break;
|
||||
}
|
||||
g_mutex_unlock (&g_drm_device_type_lock);
|
||||
return display;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_drm_new_with_device:
|
||||
* @device: an open DRM device (file descriptor)
|
||||
*
|
||||
* Creates a #GstVaapiDisplay based on the open DRM @device. The
|
||||
* caller still owns the device file descriptor and must call close()
|
||||
* when all #GstVaapiDisplay references are released. Doing so too
|
||||
* early can yield undefined behaviour.
|
||||
*
|
||||
* Return value: a newly allocated #GstVaapiDisplay object
|
||||
*/
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_drm_new_with_device (gint device)
|
||||
{
|
||||
GstVaapiDisplay *display;
|
||||
|
||||
g_return_val_if_fail (device >= 0, NULL);
|
||||
|
||||
display = g_object_new (GST_TYPE_VAAPI_DISPLAY_DRM, NULL);
|
||||
return gst_vaapi_display_config (display,
|
||||
GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, GINT_TO_POINTER (device));
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_drm_new_with_va_display:
|
||||
* @va_display: a VADisplay #va_display
|
||||
* @fd: an open DRM device (file descriptor) #fd
|
||||
*
|
||||
* Creates a #GstVaapiDisplay based on the VADisplay @va_display and
|
||||
* the open DRM device @fd.
|
||||
* The caller still owns the device file descriptor and must call close()
|
||||
* when all #GstVaapiDisplay references are released.
|
||||
*
|
||||
* Return value: a newly allocated #GstVaapiDisplay object
|
||||
*/
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_drm_new_with_va_display (VADisplay va_display, gint fd)
|
||||
{
|
||||
GstVaapiDisplay *display;
|
||||
GstVaapiDisplayInfo info = {
|
||||
.va_display = va_display,
|
||||
.native_display = GINT_TO_POINTER (fd),
|
||||
};
|
||||
|
||||
g_return_val_if_fail (fd >= 0, NULL);
|
||||
|
||||
display = g_object_new (GST_TYPE_VAAPI_DISPLAY_DRM, NULL);
|
||||
if (!gst_vaapi_display_config (display,
|
||||
GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, &info)) {
|
||||
gst_object_unref (display);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_drm_get_device:
|
||||
* @display: a #GstVaapiDisplayDRM
|
||||
*
|
||||
* Returns the underlying DRM device file descriptor that was created
|
||||
* by gst_vaapi_display_drm_new() or that was bound from
|
||||
* gst_vaapi_display_drm_new_with_device().
|
||||
*
|
||||
* Return value: the DRM file descriptor attached to @display
|
||||
*/
|
||||
gint
|
||||
gst_vaapi_display_drm_get_device (GstVaapiDisplayDRM * display)
|
||||
{
|
||||
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_DRM (display), -1);
|
||||
|
||||
return GST_VAAPI_DISPLAY_DRM_DEVICE (display);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_drm_get_device_path:
|
||||
* @display: a #GstVaapiDisplayDRM
|
||||
*
|
||||
* Returns the underlying DRM device path name was created by
|
||||
* gst_vaapi_display_drm_new() or that was bound from
|
||||
* gst_vaapi_display_drm_new_with_device().
|
||||
*
|
||||
* Note: the #GstVaapiDisplayDRM object owns the resulting string, so
|
||||
* it shall not be deallocated.
|
||||
*
|
||||
* Return value: the DRM device path name attached to @display
|
||||
*/
|
||||
const gchar *
|
||||
gst_vaapi_display_drm_get_device_path (GstVaapiDisplayDRM * display)
|
||||
{
|
||||
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_DRM (display), NULL);
|
||||
|
||||
return get_device_path (GST_VAAPI_DISPLAY_CAST (display));
|
||||
}
|
59
gst-libs/gst/vaapi/gstvaapidisplay_drm.h
Normal file
59
gst-libs/gst/vaapi/gstvaapidisplay_drm.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* gstvaapidisplay_drm.h - VA/DRM display abstraction
|
||||
*
|
||||
* Copyright (C) 2012-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DISPLAY_DRM_H
|
||||
#define GST_VAAPI_DISPLAY_DRM_H
|
||||
|
||||
#include <gst/vaapi/gstvaapidisplay.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_DISPLAY_DRM (gst_vaapi_display_drm_get_type ())
|
||||
#define GST_VAAPI_DISPLAY_DRM(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DISPLAY_DRM, GstVaapiDisplayDRM))
|
||||
|
||||
typedef struct _GstVaapiDisplayDRM GstVaapiDisplayDRM;
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_drm_new (const gchar * device_path);
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_drm_new_with_device (gint device);
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_drm_new_with_va_display (VADisplay va_display, gint fd);
|
||||
|
||||
gint
|
||||
gst_vaapi_display_drm_get_device (GstVaapiDisplayDRM * display);
|
||||
|
||||
const gchar *
|
||||
gst_vaapi_display_drm_get_device_path (GstVaapiDisplayDRM *
|
||||
display);
|
||||
|
||||
GType
|
||||
gst_vaapi_display_drm_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDisplayDRM, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DISPLAY_DRM_H */
|
90
gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h
Normal file
90
gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* gstvaapidisplay_drm_priv.h - Internal VA/DRM interface
|
||||
*
|
||||
* Copyright (C) 2012-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DISPLAY_DRM_PRIV_H
|
||||
#define GST_VAAPI_DISPLAY_DRM_PRIV_H
|
||||
|
||||
#include <gst/vaapi/gstvaapidisplay_drm.h>
|
||||
#include "gstvaapidisplay_priv.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_IS_DISPLAY_DRM(display) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((display), GST_TYPE_VAAPI_DISPLAY_DRM))
|
||||
|
||||
#define GST_VAAPI_DISPLAY_DRM_CAST(display) \
|
||||
((GstVaapiDisplayDRM *)(display))
|
||||
|
||||
#define GST_VAAPI_DISPLAY_DRM_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_DISPLAY_DRM, GstVaapiDisplayDRMClass))
|
||||
|
||||
#define GST_VAAPI_DISPLAY_DRM_PRIVATE(display) \
|
||||
(GST_VAAPI_DISPLAY_DRM_CAST(display)->priv)
|
||||
|
||||
typedef struct _GstVaapiDisplayDRMPrivate GstVaapiDisplayDRMPrivate;
|
||||
typedef struct _GstVaapiDisplayDRMClass GstVaapiDisplayDRMClass;
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DISPLAY_DRM_DEVICE:
|
||||
* @display: a #GstVaapiDisplay
|
||||
*
|
||||
* Macro that evaluates to the underlying DRM file descriptor of @display
|
||||
*/
|
||||
#undef GST_VAAPI_DISPLAY_DRM_DEVICE
|
||||
#define GST_VAAPI_DISPLAY_DRM_DEVICE(display) \
|
||||
GST_VAAPI_DISPLAY_DRM_PRIVATE(display)->drm_device
|
||||
|
||||
struct _GstVaapiDisplayDRMPrivate
|
||||
{
|
||||
gchar *device_path_default;
|
||||
gchar *device_path;
|
||||
gint drm_device;
|
||||
guint use_foreign_display:1; // Foreign native_display?
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDisplayDRM:
|
||||
*
|
||||
* VA/DRM display wrapper.
|
||||
*/
|
||||
struct _GstVaapiDisplayDRM
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiDisplay parent_instance;
|
||||
|
||||
GstVaapiDisplayDRMPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDisplayDRMClass:
|
||||
*
|
||||
* VA/DRM display wrapper clas.
|
||||
*/
|
||||
struct _GstVaapiDisplayDRMClass
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiDisplayClass parent_class;
|
||||
};
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DISPLAY_DRM_PRIV_H */
|
471
gst-libs/gst/vaapi/gstvaapidisplay_egl.c
Normal file
471
gst-libs/gst/vaapi/gstvaapidisplay_egl.c
Normal file
|
@ -0,0 +1,471 @@
|
|||
/*
|
||||
* gstvaapidisplay_egl.c - VA/EGL display abstraction
|
||||
*
|
||||
* Copyright (C) 2014 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "gstvaapidisplay_egl.h"
|
||||
#include "gstvaapidisplay_egl_priv.h"
|
||||
#include "gstvaapiwindow.h"
|
||||
#include "gstvaapiwindow_egl.h"
|
||||
#include "gstvaapiwindow_priv.h"
|
||||
#include "gstvaapitexture_egl.h"
|
||||
|
||||
#if USE_X11
|
||||
#include "gstvaapidisplay_x11.h"
|
||||
#endif
|
||||
#if USE_WAYLAND
|
||||
#include "gstvaapidisplay_wayland.h"
|
||||
#endif
|
||||
|
||||
#define DEBUG_VAAPI_DISPLAY 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
G_DEFINE_TYPE (GstVaapiDisplayEGL, gst_vaapi_display_egl,
|
||||
GST_TYPE_VAAPI_DISPLAY);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- EGL backend implementation --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gpointer display;
|
||||
guint display_type;
|
||||
guint gles_version;
|
||||
gpointer gl_display;
|
||||
} InitParams;
|
||||
|
||||
static gboolean
|
||||
reset_context (GstVaapiDisplayEGL * display, EGLContext gl_context)
|
||||
{
|
||||
EglConfig *config;
|
||||
EglContext *ctx;
|
||||
|
||||
egl_object_replace (&display->egl_context, NULL);
|
||||
|
||||
if (gl_context != EGL_NO_CONTEXT)
|
||||
ctx = egl_context_new_wrapped (display->egl_display, gl_context);
|
||||
else {
|
||||
config = egl_config_new (display->egl_display, display->gles_version,
|
||||
GST_VIDEO_FORMAT_RGB);
|
||||
if (!config)
|
||||
return FALSE;
|
||||
|
||||
ctx = egl_context_new (display->egl_display, config, NULL);
|
||||
egl_object_unref (config);
|
||||
}
|
||||
if (!ctx)
|
||||
return FALSE;
|
||||
|
||||
egl_object_replace (&display->egl_context, ctx);
|
||||
egl_object_unref (ctx);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
ensure_context (GstVaapiDisplayEGL * display)
|
||||
{
|
||||
return display->egl_context || reset_context (display, EGL_NO_CONTEXT);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
ensure_context_is_wrapped (GstVaapiDisplayEGL * display, EGLContext gl_context)
|
||||
{
|
||||
return (display->egl_context &&
|
||||
display->egl_context->base.handle.p == gl_context) ||
|
||||
reset_context (display, gl_context);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_display_egl_bind_display (GstVaapiDisplay * base_display,
|
||||
gpointer native_params)
|
||||
{
|
||||
GstVaapiDisplay *native_vaapi_display;
|
||||
GstVaapiDisplayEGL *display = GST_VAAPI_DISPLAY_EGL (base_display);
|
||||
EglDisplay *egl_display;
|
||||
EGLDisplay *native_egl_display;
|
||||
guint gl_platform = EGL_PLATFORM_UNKNOWN;
|
||||
const InitParams *params = (InitParams *) native_params;
|
||||
GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
|
||||
|
||||
native_vaapi_display = params->display;
|
||||
native_egl_display = params->gl_display;
|
||||
|
||||
if (!native_vaapi_display) {
|
||||
#if USE_X11
|
||||
if (params->display_type == GST_VAAPI_DISPLAY_TYPE_ANY
|
||||
|| params->display_type == GST_VAAPI_DISPLAY_TYPE_X11
|
||||
|| params->display_type == GST_VAAPI_DISPLAY_TYPE_EGL)
|
||||
native_vaapi_display = gst_vaapi_display_x11_new (NULL);
|
||||
#endif
|
||||
#if USE_WAYLAND
|
||||
if (!native_vaapi_display)
|
||||
native_vaapi_display = gst_vaapi_display_wayland_new (NULL);
|
||||
#endif
|
||||
} else {
|
||||
/* thus it could be assigned to parent */
|
||||
gst_object_ref (native_vaapi_display);
|
||||
}
|
||||
if (!native_vaapi_display)
|
||||
return FALSE;
|
||||
|
||||
gst_vaapi_display_replace (&display->display, native_vaapi_display);
|
||||
priv->parent = native_vaapi_display;
|
||||
|
||||
switch (GST_VAAPI_DISPLAY_GET_CLASS_TYPE (display->display)) {
|
||||
case GST_VAAPI_DISPLAY_TYPE_X11:
|
||||
gl_platform = EGL_PLATFORM_X11;
|
||||
break;
|
||||
case GST_VAAPI_DISPLAY_TYPE_WAYLAND:
|
||||
gl_platform = EGL_PLATFORM_WAYLAND;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (native_egl_display) {
|
||||
egl_display = egl_display_new_wrapped (native_egl_display);
|
||||
} else {
|
||||
egl_display = egl_display_new (GST_VAAPI_DISPLAY_NATIVE (display->display),
|
||||
gl_platform);
|
||||
}
|
||||
if (!egl_display)
|
||||
return FALSE;
|
||||
|
||||
egl_object_replace (&display->egl_display, egl_display);
|
||||
egl_object_unref (egl_display);
|
||||
display->gles_version = params->gles_version;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_egl_close_display (GstVaapiDisplay * base_display)
|
||||
{
|
||||
GstVaapiDisplayEGL *display = GST_VAAPI_DISPLAY_EGL (base_display);
|
||||
gst_vaapi_display_replace (&display->display, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_egl_lock (GstVaapiDisplay * base_display)
|
||||
{
|
||||
GstVaapiDisplayEGL *display = GST_VAAPI_DISPLAY_EGL (base_display);
|
||||
GstVaapiDisplayClass *const klass =
|
||||
GST_VAAPI_DISPLAY_GET_CLASS (display->display);
|
||||
|
||||
if (klass->lock)
|
||||
klass->lock (display->display);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_egl_unlock (GstVaapiDisplay * base_display)
|
||||
{
|
||||
GstVaapiDisplayEGL *display = GST_VAAPI_DISPLAY_EGL (base_display);
|
||||
GstVaapiDisplayClass *const klass =
|
||||
GST_VAAPI_DISPLAY_GET_CLASS (display->display);
|
||||
|
||||
if (klass->unlock)
|
||||
klass->unlock (display->display);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_egl_sync (GstVaapiDisplay * base_display)
|
||||
{
|
||||
GstVaapiDisplayEGL *display = GST_VAAPI_DISPLAY_EGL (base_display);
|
||||
GstVaapiDisplayClass *const klass =
|
||||
GST_VAAPI_DISPLAY_GET_CLASS (display->display);
|
||||
|
||||
if (klass->sync)
|
||||
klass->sync (display->display);
|
||||
else if (klass->flush)
|
||||
klass->flush (display->display);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_egl_flush (GstVaapiDisplay * base_display)
|
||||
{
|
||||
GstVaapiDisplayEGL *display = GST_VAAPI_DISPLAY_EGL (base_display);
|
||||
GstVaapiDisplayClass *const klass =
|
||||
GST_VAAPI_DISPLAY_GET_CLASS (display->display);
|
||||
|
||||
if (klass->flush)
|
||||
klass->flush (display->display);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_display_egl_get_display_info (GstVaapiDisplay * base_display,
|
||||
GstVaapiDisplayInfo * info)
|
||||
{
|
||||
GstVaapiDisplayEGL *display = GST_VAAPI_DISPLAY_EGL (base_display);
|
||||
GstVaapiDisplayClass *const klass =
|
||||
GST_VAAPI_DISPLAY_GET_CLASS (display->display);
|
||||
|
||||
info->va_display = GST_VAAPI_DISPLAY_VADISPLAY (display->display);
|
||||
|
||||
if (klass->get_display && !klass->get_display (display->display, info))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_egl_get_size (GstVaapiDisplay * base_display,
|
||||
guint * width_ptr, guint * height_ptr)
|
||||
{
|
||||
GstVaapiDisplayEGL *display = GST_VAAPI_DISPLAY_EGL (base_display);
|
||||
GstVaapiDisplayClass *const klass =
|
||||
GST_VAAPI_DISPLAY_GET_CLASS (display->display);
|
||||
|
||||
if (klass->get_size)
|
||||
klass->get_size (display->display, width_ptr, height_ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_egl_get_size_mm (GstVaapiDisplay * base_display,
|
||||
guint * width_ptr, guint * height_ptr)
|
||||
{
|
||||
GstVaapiDisplayEGL *display = GST_VAAPI_DISPLAY_EGL (base_display);
|
||||
GstVaapiDisplayClass *const klass =
|
||||
GST_VAAPI_DISPLAY_GET_CLASS (display->display);
|
||||
|
||||
if (klass->get_size_mm)
|
||||
klass->get_size_mm (display->display, width_ptr, height_ptr);
|
||||
}
|
||||
|
||||
static guintptr
|
||||
gst_vaapi_display_egl_get_visual_id (GstVaapiDisplay * base_display,
|
||||
GstVaapiWindow * window)
|
||||
{
|
||||
GstVaapiDisplayEGL *display = GST_VAAPI_DISPLAY_EGL (base_display);
|
||||
if (!ensure_context (display))
|
||||
return 0;
|
||||
return display->egl_context->config->visual_id;
|
||||
}
|
||||
|
||||
static GstVaapiWindow *
|
||||
gst_vaapi_display_egl_create_window (GstVaapiDisplay * display, GstVaapiID id,
|
||||
guint width, guint height)
|
||||
{
|
||||
if (id != GST_VAAPI_ID_INVALID)
|
||||
return NULL;
|
||||
return gst_vaapi_window_egl_new (display, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_texture_map (GstVaapiDisplayEGL * display)
|
||||
{
|
||||
if (!display->texture_map)
|
||||
display->texture_map = gst_vaapi_texture_map_new ();
|
||||
}
|
||||
|
||||
static GstVaapiTexture *
|
||||
gst_vaapi_display_egl_create_texture (GstVaapiDisplay * display, GstVaapiID id,
|
||||
guint target, guint format, guint width, guint height)
|
||||
{
|
||||
GstVaapiDisplayEGL *dpy = GST_VAAPI_DISPLAY_EGL (display);
|
||||
GstVaapiTexture *texture;
|
||||
|
||||
if (id == GST_VAAPI_ID_INVALID)
|
||||
return gst_vaapi_texture_egl_new (display, target, format, width, height);
|
||||
|
||||
ensure_texture_map (dpy);
|
||||
if (!(texture = gst_vaapi_texture_map_lookup (dpy->texture_map, id))) {
|
||||
if ((texture =
|
||||
gst_vaapi_texture_egl_new_wrapped (display, id, target, format,
|
||||
width, height))) {
|
||||
gst_vaapi_texture_map_add (dpy->texture_map, texture, id);
|
||||
}
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static GstVaapiTextureMap *
|
||||
gst_vaapi_display_egl_get_texture_map (GstVaapiDisplay * display)
|
||||
{
|
||||
return GST_VAAPI_DISPLAY_EGL (display)->texture_map;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_egl_finalize (GObject * object)
|
||||
{
|
||||
GstVaapiDisplayEGL *dpy = GST_VAAPI_DISPLAY_EGL (object);
|
||||
|
||||
if (dpy->texture_map)
|
||||
gst_object_unref (dpy->texture_map);
|
||||
|
||||
/* HACK to avoid to call twice vaTerminate() since this and the
|
||||
* proxied display share the same vaDisplay */
|
||||
GST_VAAPI_DISPLAY_VADISPLAY (object) = NULL;
|
||||
|
||||
egl_object_replace (&dpy->egl_display, NULL);
|
||||
egl_object_replace (&dpy->egl_context, NULL);
|
||||
|
||||
gst_vaapi_display_replace (&dpy->display, NULL);
|
||||
|
||||
G_OBJECT_CLASS (gst_vaapi_display_egl_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_egl_init (GstVaapiDisplayEGL * display)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_egl_class_init (GstVaapiDisplayEGLClass * klass)
|
||||
{
|
||||
GObjectClass *const object_class = G_OBJECT_CLASS (klass);
|
||||
GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass);
|
||||
|
||||
object_class->finalize = gst_vaapi_display_egl_finalize;
|
||||
dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_EGL;
|
||||
dpy_class->bind_display = gst_vaapi_display_egl_bind_display;
|
||||
dpy_class->close_display = gst_vaapi_display_egl_close_display;
|
||||
dpy_class->lock = gst_vaapi_display_egl_lock;
|
||||
dpy_class->unlock = gst_vaapi_display_egl_unlock;
|
||||
dpy_class->sync = gst_vaapi_display_egl_sync;
|
||||
dpy_class->flush = gst_vaapi_display_egl_flush;
|
||||
dpy_class->get_display = gst_vaapi_display_egl_get_display_info;
|
||||
dpy_class->get_size = gst_vaapi_display_egl_get_size;
|
||||
dpy_class->get_size_mm = gst_vaapi_display_egl_get_size_mm;
|
||||
dpy_class->get_visual_id = gst_vaapi_display_egl_get_visual_id;
|
||||
dpy_class->create_window = gst_vaapi_display_egl_create_window;
|
||||
dpy_class->create_texture = gst_vaapi_display_egl_create_texture;
|
||||
dpy_class->get_texture_map = gst_vaapi_display_egl_get_texture_map;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_egl_new:
|
||||
* @display: a #GstVaapiDisplay, or %NULL to pick any one
|
||||
* @gles_version: the OpenGL ES version API to use
|
||||
*
|
||||
* Creates a new #GstVaapiDisplay object suitable in EGL context. If
|
||||
* the native @display is %NULL, then any type of display is picked,
|
||||
* i.e. one that can be successfully opened. The @gles_version will
|
||||
* further ensure the OpenGL ES API to use, or zero to indicate
|
||||
* "desktop" OpenGL.
|
||||
*
|
||||
* Return value: a newly allocated #GstVaapiDisplay object
|
||||
*/
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_egl_new (GstVaapiDisplay * display, guint gles_version)
|
||||
{
|
||||
GstVaapiDisplay *wrapper_display;
|
||||
InitParams params = {
|
||||
.gles_version = gles_version,
|
||||
};
|
||||
|
||||
if (display) {
|
||||
params.display = display;
|
||||
params.display_type = GST_VAAPI_DISPLAY_VADISPLAY_TYPE (display);
|
||||
}
|
||||
|
||||
wrapper_display = g_object_new (GST_TYPE_VAAPI_DISPLAY_EGL, NULL);
|
||||
return gst_vaapi_display_config (wrapper_display,
|
||||
GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, ¶ms);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_egl_new_with_native_display:
|
||||
* @native_display: an EGLDisplay object
|
||||
* @display_type: the display type of @native_display
|
||||
* @gles_version: the OpenGL ES version API to use
|
||||
*
|
||||
* Creates a #GstVaapiDisplay based on the native display supplied in
|
||||
* as @native_display. The caller still owns the display and must call
|
||||
* native display close function when all #GstVaapiDisplay references
|
||||
* are released. Doing so too early can yield undefined behaviour.
|
||||
*
|
||||
* The @gles_version will further ensure the OpenGL ES API to use, or
|
||||
* zero to indicate "desktop" OpenGL.
|
||||
*
|
||||
* Return value: a newly allocated #GstVaapiDisplay object
|
||||
*/
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_egl_new_with_native_display (gpointer native_display,
|
||||
GstVaapiDisplayType display_type, guint gles_version)
|
||||
{
|
||||
GstVaapiDisplay *display;
|
||||
InitParams params = {
|
||||
.display_type = display_type,
|
||||
.gl_display = native_display,
|
||||
.gles_version = gles_version,
|
||||
};
|
||||
|
||||
g_return_val_if_fail (native_display != NULL, NULL);
|
||||
|
||||
display = g_object_new (GST_TYPE_VAAPI_DISPLAY_EGL, NULL);
|
||||
return gst_vaapi_display_config (display,
|
||||
GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, ¶ms);
|
||||
}
|
||||
|
||||
EglContext *
|
||||
gst_vaapi_display_egl_get_context (GstVaapiDisplayEGL * display)
|
||||
{
|
||||
return ensure_context (display) ? display->egl_context : NULL;
|
||||
}
|
||||
|
||||
EGLDisplay
|
||||
gst_vaapi_display_egl_get_gl_display (GstVaapiDisplayEGL * display)
|
||||
{
|
||||
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (display), EGL_NO_DISPLAY);
|
||||
|
||||
return display->egl_display->base.handle.p;
|
||||
}
|
||||
|
||||
EGLContext
|
||||
gst_vaapi_display_egl_get_gl_context (GstVaapiDisplayEGL * display)
|
||||
{
|
||||
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (display), EGL_NO_CONTEXT);
|
||||
|
||||
return ensure_context (display) ? display->egl_context->base.handle.p :
|
||||
EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_display_egl_set_gl_context (GstVaapiDisplayEGL * display,
|
||||
EGLContext gl_context)
|
||||
{
|
||||
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (display), FALSE);
|
||||
|
||||
return ensure_context_is_wrapped (display, gl_context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_display_egl_set_current_display (GstVaapiDisplayEGL * display)
|
||||
{
|
||||
EglDisplay *egl_display;
|
||||
|
||||
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (display), FALSE);
|
||||
|
||||
if (G_UNLIKELY (eglGetCurrentDisplay () == EGL_NO_DISPLAY))
|
||||
return TRUE;
|
||||
if (G_LIKELY (display->egl_display->base.handle.p == eglGetCurrentDisplay ()))
|
||||
return TRUE;
|
||||
|
||||
egl_display = egl_display_new_wrapped (eglGetCurrentDisplay ());
|
||||
if (!egl_display)
|
||||
return FALSE;
|
||||
egl_object_replace (&display->egl_display, egl_display);
|
||||
egl_object_unref (egl_display);
|
||||
if (!gst_vaapi_display_egl_set_gl_context (display, eglGetCurrentContext ()))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
64
gst-libs/gst/vaapi/gstvaapidisplay_egl.h
Normal file
64
gst-libs/gst/vaapi/gstvaapidisplay_egl.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* gstvaapidisplay_egl.h - VA/EGL display abstraction
|
||||
*
|
||||
* Copyright (C) 2014 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; either version 2.1
|
||||
* of the License, or (at your option) egl later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT EGL 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_VAAPI_DISPLAY_EGL_H
|
||||
#define GST_VAAPI_DISPLAY_EGL_H
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <gst/vaapi/gstvaapidisplay.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstVaapiDisplayEGL GstVaapiDisplayEGL;
|
||||
|
||||
#define GST_TYPE_VAAPI_DISPLAY_EGL (gst_vaapi_display_egl_get_type ())
|
||||
#define GST_VAAPI_DISPLAY_EGL(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DISPLAY_EGL, GstVaapiDisplayEGL))
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_egl_new (GstVaapiDisplay * display, guint gles_version);
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_egl_new_with_native_display (gpointer native_display,
|
||||
GstVaapiDisplayType display_type, guint gles_version);
|
||||
|
||||
EGLDisplay
|
||||
gst_vaapi_display_egl_get_gl_display (GstVaapiDisplayEGL * display);
|
||||
|
||||
EGLContext
|
||||
gst_vaapi_display_egl_get_gl_context (GstVaapiDisplayEGL * display);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_display_egl_set_gl_context (GstVaapiDisplayEGL * display,
|
||||
EGLContext gl_context);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_display_egl_set_current_display (GstVaapiDisplayEGL * display);
|
||||
|
||||
GType
|
||||
gst_vaapi_display_egl_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDisplayEGL, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DISPLAY_EGL_H */
|
105
gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h
Normal file
105
gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* gstvaapidisplay_egl_priv.h - Internal VA/EGL interface
|
||||
*
|
||||
* Copyright (C) 2014 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DISPLAY_EGL_PRIV_H
|
||||
#define GST_VAAPI_DISPLAY_EGL_PRIV_H
|
||||
|
||||
#include <gst/vaapi/gstvaapiwindow.h>
|
||||
#include <gst/vaapi/gstvaapitexturemap.h>
|
||||
#include "gstvaapidisplay_egl.h"
|
||||
#include "gstvaapidisplay_priv.h"
|
||||
#include "gstvaapiutils_egl.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_IS_DISPLAY_EGL(display) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((display), GST_TYPE_VAAPI_DISPLAY_EGL))
|
||||
|
||||
#define GST_VAAPI_DISPLAY_EGL_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_DISPLAY_EGL, GstVaapiDisplayEGLClass))
|
||||
|
||||
#define GST_VAAPI_DISPLAY_EGL_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_DISPLAY_EGL, GstVaapiDisplayEGLClass))
|
||||
|
||||
#define GST_VAAPI_DISPLAY_EGL_CAST(obj) \
|
||||
((GstVaapiDisplayEGL *)(obj))
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DISPLAY_EGL_DISPLAY:
|
||||
* @display: a #GstVaapiDisplay
|
||||
*
|
||||
* Macro that evaluates to #EglDisplay wrapper for @display.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_DISPLAY_EGL_DISPLAY
|
||||
#define GST_VAAPI_DISPLAY_EGL_DISPLAY(display) \
|
||||
(GST_VAAPI_DISPLAY_EGL_CAST (display)->egl_display)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DISPLAY_EGL_CONTEXT:
|
||||
* @display: a #GstVaapiDisplay
|
||||
*
|
||||
* Macro that evaluates to #EglContext wrapper for @display.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_DISPLAY_EGL_CONTEXT
|
||||
#define GST_VAAPI_DISPLAY_EGL_CONTEXT(display) \
|
||||
gst_vaapi_display_egl_get_context (GST_VAAPI_DISPLAY_EGL (display))
|
||||
|
||||
typedef struct _GstVaapiDisplayEGLClass GstVaapiDisplayEGLClass;
|
||||
|
||||
/**
|
||||
* GstVaapiDisplayEGL:
|
||||
*
|
||||
* VA/EGL display wrapper.
|
||||
*/
|
||||
struct _GstVaapiDisplayEGL
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiDisplay parent_instance;
|
||||
|
||||
gpointer loader;
|
||||
GstVaapiDisplay *display;
|
||||
EglDisplay *egl_display;
|
||||
EglContext *egl_context;
|
||||
guint gles_version;
|
||||
GstVaapiTextureMap *texture_map;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDisplayEGLClass:
|
||||
*
|
||||
* VA/EGL display wrapper clas.
|
||||
*/
|
||||
struct _GstVaapiDisplayEGLClass
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiDisplayClass parent_class;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
EglContext *
|
||||
gst_vaapi_display_egl_get_context (GstVaapiDisplayEGL * display);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DISPLAY_EGL_PRIV_H */
|
159
gst-libs/gst/vaapi/gstvaapidisplay_glx.c
Normal file
159
gst-libs/gst/vaapi/gstvaapidisplay_glx.c
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* gstvaapidisplay_glx.c - VA/GLX display abstraction
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||
* Copyright (C) 2011-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstvaapidisplay_glx
|
||||
* @short_description: VA/GLX display abstraction
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "gstvaapicompat.h"
|
||||
#include "gstvaapiutils.h"
|
||||
#include "gstvaapiutils_glx.h"
|
||||
#include "gstvaapidisplay_priv.h"
|
||||
#include "gstvaapidisplay_x11_priv.h"
|
||||
#include "gstvaapidisplay_glx.h"
|
||||
#include "gstvaapidisplay_glx_priv.h"
|
||||
#include "gstvaapiwindow_glx.h"
|
||||
#include "gstvaapitexture_glx.h"
|
||||
|
||||
#define DEBUG_VAAPI_DISPLAY 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
G_DEFINE_TYPE (GstVaapiDisplayGLX, gst_vaapi_display_glx,
|
||||
GST_TYPE_VAAPI_DISPLAY_X11);
|
||||
|
||||
static GstVaapiWindow *
|
||||
gst_vaapi_display_glx_create_window (GstVaapiDisplay * display, GstVaapiID id,
|
||||
guint width, guint height)
|
||||
{
|
||||
return id != GST_VAAPI_ID_INVALID ?
|
||||
gst_vaapi_window_glx_new_with_xid (display, id) :
|
||||
gst_vaapi_window_glx_new (display, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_texture_map (GstVaapiDisplayGLX * display)
|
||||
{
|
||||
if (!display->texture_map)
|
||||
display->texture_map = gst_vaapi_texture_map_new ();
|
||||
}
|
||||
|
||||
static GstVaapiTexture *
|
||||
gst_vaapi_display_glx_create_texture (GstVaapiDisplay * display, GstVaapiID id,
|
||||
guint target, guint format, guint width, guint height)
|
||||
{
|
||||
GstVaapiTexture *texture;
|
||||
GstVaapiDisplayGLX *dpy = GST_VAAPI_DISPLAY_GLX (display);
|
||||
|
||||
if (id == GST_VAAPI_ID_INVALID)
|
||||
return gst_vaapi_texture_glx_new (display, target, format, width, height);
|
||||
|
||||
ensure_texture_map (dpy);
|
||||
if (!(texture = gst_vaapi_texture_map_lookup (dpy->texture_map, id))) {
|
||||
if ((texture =
|
||||
gst_vaapi_texture_glx_new_wrapped (display, id, target, format))) {
|
||||
gst_vaapi_texture_map_add (dpy->texture_map, texture, id);
|
||||
}
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static GstVaapiTextureMap *
|
||||
gst_vaapi_display_glx_get_texture_map (GstVaapiDisplay * display)
|
||||
{
|
||||
return GST_VAAPI_DISPLAY_GLX (display)->texture_map;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_glx_finalize (GObject * object)
|
||||
{
|
||||
GstVaapiDisplayGLX *dpy = GST_VAAPI_DISPLAY_GLX (object);
|
||||
|
||||
if (dpy->texture_map)
|
||||
gst_object_unref (dpy->texture_map);
|
||||
G_OBJECT_CLASS (gst_vaapi_display_glx_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_glx_init (GstVaapiDisplayGLX * display)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_glx_class_init (GstVaapiDisplayGLXClass * klass)
|
||||
{
|
||||
GObjectClass *const object_class = G_OBJECT_CLASS (klass);
|
||||
GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass);
|
||||
|
||||
object_class->finalize = gst_vaapi_display_glx_finalize;
|
||||
dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_GLX;
|
||||
dpy_class->create_window = gst_vaapi_display_glx_create_window;
|
||||
dpy_class->create_texture = gst_vaapi_display_glx_create_texture;
|
||||
dpy_class->get_texture_map = gst_vaapi_display_glx_get_texture_map;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_glx_new:
|
||||
* @display_name: the X11 display name
|
||||
*
|
||||
* Opens an X11 #Display using @display_name and returns a newly
|
||||
* allocated #GstVaapiDisplay object. The X11 display will be cloed
|
||||
* when the reference count of the object reaches zero.
|
||||
*
|
||||
* Return value: a newly allocated #GstVaapiDisplay object
|
||||
*/
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_glx_new (const gchar * display_name)
|
||||
{
|
||||
GstVaapiDisplay *display;
|
||||
|
||||
display = g_object_new (GST_TYPE_VAAPI_DISPLAY_GLX, NULL);
|
||||
return gst_vaapi_display_config (display,
|
||||
GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer) display_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_glx_new_with_display:
|
||||
* @x11_display: an X11 #Display
|
||||
*
|
||||
* Creates a #GstVaapiDisplay based on the X11 @x11_display
|
||||
* display. The caller still owns the display and must call
|
||||
* XCloseDisplay() when all #GstVaapiDisplay references are
|
||||
* released. Doing so too early can yield undefined behaviour.
|
||||
*
|
||||
* Return value: a newly allocated #GstVaapiDisplay object
|
||||
*/
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_glx_new_with_display (Display * x11_display)
|
||||
{
|
||||
GstVaapiDisplay *display;
|
||||
|
||||
g_return_val_if_fail (x11_display != NULL, NULL);
|
||||
|
||||
display = g_object_new (GST_TYPE_VAAPI_DISPLAY_GLX, NULL);
|
||||
return gst_vaapi_display_config (display,
|
||||
GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, x11_display);
|
||||
}
|
51
gst-libs/gst/vaapi/gstvaapidisplay_glx.h
Normal file
51
gst-libs/gst/vaapi/gstvaapidisplay_glx.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* gstvaapidisplay_glx.h - VA/GLX display abstraction
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||
* Copyright (C) 2012-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DISPLAY_GLX_H
|
||||
#define GST_VAAPI_DISPLAY_GLX_H
|
||||
|
||||
#include <gst/vaapi/gstvaapidisplay_x11.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_DISPLAY_GLX (gst_vaapi_display_glx_get_type ())
|
||||
#define GST_VAAPI_DISPLAY_GLX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DISPLAY_GLX, GstVaapiDisplayGLX))
|
||||
|
||||
typedef struct _GstVaapiDisplayGLX GstVaapiDisplayGLX;
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_glx_new (const gchar * display_name);
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_glx_new_with_display (Display * x11_display);
|
||||
|
||||
GType
|
||||
gst_vaapi_display_glx_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDisplayGLX, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DISPLAY_GLX_H */
|
72
gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h
Normal file
72
gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* gstvaapidisplay_glx_priv.h - Internal VA/GLX interface
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DISPLAY_GLX_PRIV_H
|
||||
#define GST_VAAPI_DISPLAY_GLX_PRIV_H
|
||||
|
||||
#include <gst/vaapi/gstvaapiutils_glx.h>
|
||||
#include <gst/vaapi/gstvaapidisplay_glx.h>
|
||||
#include <gst/vaapi/gstvaapitexturemap.h>
|
||||
#include "gstvaapidisplay_x11_priv.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_IS_DISPLAY_GLX(display) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((display), GST_TYPE_VAAPI_DISPLAY_GLX))
|
||||
|
||||
#define GST_VAAPI_DISPLAY_GLX_CAST(display) \
|
||||
((GstVaapiDisplayGLX *)(display))
|
||||
|
||||
#define GST_VAAPI_DISPLAY_GLX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_DISPLAY_GLX, GstVaapiDisplayGLXClass))
|
||||
|
||||
#define GST_VAAPI_DISPLAY_GLX_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_DISPLAY_GLX, GstVaapiDisplayGLXClass))
|
||||
|
||||
typedef struct _GstVaapiDisplayGLXClass GstVaapiDisplayGLXClass;
|
||||
|
||||
/**
|
||||
* GstVaapiDisplayGLX:
|
||||
*
|
||||
* VA/GLX display wrapper.
|
||||
*/
|
||||
struct _GstVaapiDisplayGLX
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiDisplayX11 parent_instance;
|
||||
GstVaapiTextureMap *texture_map;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDisplayGLXClass:
|
||||
*
|
||||
* VA/GLX display wrapper clas.
|
||||
*/
|
||||
struct _GstVaapiDisplayGLXClass
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiDisplayX11Class parent_class;
|
||||
};
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DISPLAY_GLX_PRIV_H */
|
211
gst-libs/gst/vaapi/gstvaapidisplay_priv.h
Normal file
211
gst-libs/gst/vaapi/gstvaapidisplay_priv.h
Normal file
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* gstvaapidisplay_priv.h - Base VA display (private definitions)
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||
* Copyright (C) 2011-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DISPLAY_PRIV_H
|
||||
#define GST_VAAPI_DISPLAY_PRIV_H
|
||||
|
||||
#include <gst/vaapi/gstvaapidisplay.h>
|
||||
#include <gst/vaapi/gstvaapiwindow.h>
|
||||
#include <gst/vaapi/gstvaapitexture.h>
|
||||
#include <gst/vaapi/gstvaapitexturemap.h>
|
||||
#include "gstvaapiminiobject.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_DISPLAY_CAST(display) \
|
||||
((GstVaapiDisplay *)(display))
|
||||
|
||||
#define GST_VAAPI_DISPLAY_GET_PRIVATE(display) \
|
||||
(GST_VAAPI_DISPLAY_CAST (display)->priv)
|
||||
|
||||
#define GST_VAAPI_DISPLAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_DISPLAY, GstVaapiDisplayClass))
|
||||
|
||||
#define GST_VAAPI_IS_DISPLAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_DISPLAY))
|
||||
|
||||
#define GST_VAAPI_DISPLAY_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_DISPLAY, GstVaapiDisplayClass))
|
||||
|
||||
typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate;
|
||||
typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass;
|
||||
typedef enum _GstVaapiDisplayInitType GstVaapiDisplayInitType;
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DISPLAY_GET_CLASS_TYPE:
|
||||
* @display: a #GstVaapiDisplay
|
||||
*
|
||||
* Returns the #display class type
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_DISPLAY_GET_CLASS_TYPE
|
||||
#define GST_VAAPI_DISPLAY_GET_CLASS_TYPE(display) \
|
||||
(GST_VAAPI_DISPLAY_GET_CLASS (display)->display_type)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DISPLAY_NATIVE:
|
||||
* @display: a #GstVaapiDisplay
|
||||
*
|
||||
* Macro that evaluates to the native display of @display.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_DISPLAY_NATIVE
|
||||
#define GST_VAAPI_DISPLAY_NATIVE(display) \
|
||||
(GST_VAAPI_DISPLAY_GET_PRIVATE (display)->native_display)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DISPLAY_VADISPLAY:
|
||||
* @display_: a #GstVaapiDisplay
|
||||
*
|
||||
* Macro that evaluates to the #VADisplay of @display_.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_DISPLAY_VADISPLAY
|
||||
#define GST_VAAPI_DISPLAY_VADISPLAY(display_) \
|
||||
(GST_VAAPI_DISPLAY_GET_PRIVATE (display_)->display)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DISPLAY_VADISPLAY_TYPE:
|
||||
* @display: a #GstVaapiDisplay
|
||||
*
|
||||
* Returns the underlying VADisplay @display type
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_DISPLAY_VADISPLAY_TYPE
|
||||
#define GST_VAAPI_DISPLAY_VADISPLAY_TYPE(display) \
|
||||
(GST_VAAPI_DISPLAY_GET_CLASS (display)->display_type)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DISPLAY_HAS_VPP:
|
||||
* @display: a @GstVaapiDisplay
|
||||
*
|
||||
* Returns whether the @display supports video processing (VA/VPP)
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_DISPLAY_HAS_VPP
|
||||
#define GST_VAAPI_DISPLAY_HAS_VPP(display) \
|
||||
gst_vaapi_display_has_video_processing (GST_VAAPI_DISPLAY_CAST (display))
|
||||
|
||||
struct _GstVaapiDisplayPrivate
|
||||
{
|
||||
GstVaapiDisplay *parent;
|
||||
GRecMutex mutex;
|
||||
gchar *display_name;
|
||||
VADisplay display;
|
||||
gpointer native_display;
|
||||
guint width;
|
||||
guint height;
|
||||
guint width_mm;
|
||||
guint height_mm;
|
||||
guint par_n;
|
||||
guint par_d;
|
||||
GPtrArray *decoders; /* ref element in codecs */
|
||||
GPtrArray *encoders; /* ref element in codecs */
|
||||
GArray *codecs;
|
||||
GArray *image_formats;
|
||||
GArray *subpicture_formats;
|
||||
GArray *properties;
|
||||
gchar *vendor_string;
|
||||
guint use_foreign_display:1;
|
||||
guint has_vpp:1;
|
||||
guint has_profiles:1;
|
||||
guint got_scrres:1;
|
||||
guint driver_quirks;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDisplay:
|
||||
*
|
||||
* Base class for VA displays.
|
||||
*/
|
||||
struct _GstVaapiDisplay
|
||||
{
|
||||
/*< private >*/
|
||||
GstObject parent_instance;
|
||||
|
||||
GstVaapiDisplayPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDisplayClass:
|
||||
* @open_display: virtual function to open a display
|
||||
* @close_display: virtual function to close a display
|
||||
* @lock: (optional) virtual function to lock a display
|
||||
* @unlock: (optional) virtual function to unlock a display
|
||||
* @sync: (optional) virtual function to sync a display
|
||||
* @flush: (optional) virtual function to flush pending requests of a display
|
||||
* @get_display: virtual function to retrieve the #GstVaapiDisplayInfo
|
||||
* @get_size: virtual function to retrieve the display dimensions, in pixels
|
||||
* @get_size_mm: virtual function to retrieve the display dimensions, in millimeters
|
||||
* @get_visual_id: (optional) virtual function to retrieve the window visual id
|
||||
* @get_colormap: (optional) virtual function to retrieve the window colormap
|
||||
* @create_window: (optional) virtual function to create a window
|
||||
* @create_texture: (optional) virtual function to create a texture
|
||||
* @get_texture_map: (optional) virtual function to get texture map
|
||||
*
|
||||
* Base class for VA displays.
|
||||
*/
|
||||
struct _GstVaapiDisplayClass
|
||||
{
|
||||
/*< private >*/
|
||||
GstObjectClass parent_class;
|
||||
|
||||
/*< protected >*/
|
||||
guint display_type;
|
||||
|
||||
/*< public >*/
|
||||
void (*init) (GstVaapiDisplay * display);
|
||||
gboolean (*bind_display) (GstVaapiDisplay * display, gpointer native_dpy);
|
||||
gboolean (*open_display) (GstVaapiDisplay * display, const gchar * name);
|
||||
void (*close_display) (GstVaapiDisplay * display);
|
||||
void (*lock) (GstVaapiDisplay * display);
|
||||
void (*unlock) (GstVaapiDisplay * display);
|
||||
void (*sync) (GstVaapiDisplay * display);
|
||||
void (*flush) (GstVaapiDisplay * display);
|
||||
gboolean (*get_display) (GstVaapiDisplay * display, GstVaapiDisplayInfo * info);
|
||||
void (*get_size) (GstVaapiDisplay * display, guint * pwidth, guint * pheight);
|
||||
void (*get_size_mm) (GstVaapiDisplay * display, guint * pwidth, guint * pheight);
|
||||
guintptr (*get_visual_id) (GstVaapiDisplay * display, GstVaapiWindow * window);
|
||||
guintptr (*get_colormap) (GstVaapiDisplay * display, GstVaapiWindow * window);
|
||||
GstVaapiWindow *(*create_window) (GstVaapiDisplay * display, GstVaapiID id, guint width, guint height);
|
||||
GstVaapiTexture *(*create_texture) (GstVaapiDisplay * display, GstVaapiID id, guint target, guint format,
|
||||
guint width, guint height);
|
||||
GstVaapiTextureMap *(*get_texture_map) (GstVaapiDisplay * display);
|
||||
};
|
||||
|
||||
/* Initialization types */
|
||||
enum _GstVaapiDisplayInitType
|
||||
{
|
||||
GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME = 1,
|
||||
GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY,
|
||||
GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY
|
||||
};
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_config (GstVaapiDisplay * display,
|
||||
GstVaapiDisplayInitType init_type, gpointer init_value);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DISPLAY_PRIV_H */
|
457
gst-libs/gst/vaapi/gstvaapidisplay_wayland.c
Normal file
457
gst-libs/gst/vaapi/gstvaapidisplay_wayland.c
Normal file
|
@ -0,0 +1,457 @@
|
|||
/*
|
||||
* gstvaapidisplay_wayland.c - VA/Wayland display abstraction
|
||||
*
|
||||
* Copyright (C) 2012-2013 Intel Corporation
|
||||
* Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstvaapidisplay_wayland
|
||||
* @short_description: VA/Wayland display abstraction
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "gstvaapidisplay_priv.h"
|
||||
#include "gstvaapidisplay_wayland.h"
|
||||
#include "gstvaapidisplay_wayland_priv.h"
|
||||
#include "gstvaapiwindow_wayland.h"
|
||||
|
||||
#define DEBUG_VAAPI_DISPLAY 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GstVaapiDisplayWayland, gst_vaapi_display_wayland,
|
||||
GST_TYPE_VAAPI_DISPLAY);
|
||||
|
||||
static inline const gchar *
|
||||
get_default_display_name (void)
|
||||
{
|
||||
static const gchar *g_display_name;
|
||||
|
||||
if (!g_display_name)
|
||||
g_display_name = getenv ("WAYLAND_DISPLAY");
|
||||
return g_display_name;
|
||||
}
|
||||
|
||||
/* Mangle display name with our prefix */
|
||||
static gboolean
|
||||
set_display_name (GstVaapiDisplay * display, const gchar * display_name)
|
||||
{
|
||||
GstVaapiDisplayWaylandPrivate *const priv =
|
||||
GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display);
|
||||
|
||||
g_free (priv->display_name);
|
||||
|
||||
if (!display_name) {
|
||||
display_name = get_default_display_name ();
|
||||
if (!display_name)
|
||||
display_name = "";
|
||||
}
|
||||
priv->display_name = g_strdup (display_name);
|
||||
return priv->display_name != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
output_handle_geometry (void *data, struct wl_output *output,
|
||||
int x, int y, int physical_width, int physical_height,
|
||||
int subpixel, const char *make, const char *model, int transform)
|
||||
{
|
||||
GstVaapiDisplayWaylandPrivate *const priv = data;
|
||||
|
||||
priv->phys_width = physical_width;
|
||||
priv->phys_height = physical_height;
|
||||
}
|
||||
|
||||
static void
|
||||
output_handle_mode (void *data, struct wl_output *wl_output,
|
||||
uint32_t flags, int width, int height, int refresh)
|
||||
{
|
||||
GstVaapiDisplayWaylandPrivate *const priv = data;
|
||||
|
||||
if (flags & WL_OUTPUT_MODE_CURRENT) {
|
||||
priv->width = width;
|
||||
priv->height = height;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_output_listener output_listener = {
|
||||
output_handle_geometry,
|
||||
output_handle_mode,
|
||||
};
|
||||
|
||||
static void
|
||||
handle_xdg_wm_base_ping (void *user_data, struct xdg_wm_base *xdg_wm_base,
|
||||
uint32_t serial)
|
||||
{
|
||||
xdg_wm_base_pong (xdg_wm_base, serial);
|
||||
}
|
||||
|
||||
static const struct xdg_wm_base_listener xdg_wm_base_listener = {
|
||||
handle_xdg_wm_base_ping
|
||||
};
|
||||
|
||||
static void
|
||||
dmabuf_format (void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf,
|
||||
uint32_t format)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
dmabuf_modifier (void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf,
|
||||
uint32_t format, uint32_t modifier_hi, uint32_t modifier_lo)
|
||||
{
|
||||
GstVaapiDisplayWaylandPrivate *const priv = data;
|
||||
GstDRMFormat drm_format = {
|
||||
.format = format,
|
||||
.modifier = (guint64) modifier_hi << 32 | modifier_lo
|
||||
};
|
||||
|
||||
if (gst_vaapi_video_format_from_drm_format (format) ==
|
||||
GST_VIDEO_FORMAT_UNKNOWN) {
|
||||
GST_LOG ("ignoring unknown format 0x%x with modifier 0x%" G_GINT64_MODIFIER
|
||||
"x", format, drm_format.modifier);
|
||||
return;
|
||||
}
|
||||
|
||||
GST_LOG ("got format 0x%x (%s) with modifier 0x%" G_GINT64_MODIFIER "x",
|
||||
format, gst_video_format_to_string (gst_vaapi_video_format_from_drm_format
|
||||
(format)), drm_format.modifier);
|
||||
|
||||
g_array_append_val (priv->dmabuf_formats, drm_format);
|
||||
}
|
||||
|
||||
static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = {
|
||||
dmabuf_format,
|
||||
dmabuf_modifier,
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
registry_handle_global (void *data,
|
||||
struct wl_registry *registry,
|
||||
uint32_t id, const char *interface, uint32_t version)
|
||||
{
|
||||
GstVaapiDisplayWaylandPrivate *const priv = data;
|
||||
|
||||
if (strcmp (interface, "wl_compositor") == 0)
|
||||
priv->compositor =
|
||||
wl_registry_bind (registry, id, &wl_compositor_interface, 1);
|
||||
else if (strcmp (interface, "wl_subcompositor") == 0)
|
||||
priv->subcompositor =
|
||||
wl_registry_bind (registry, id, &wl_subcompositor_interface, 1);
|
||||
else if (strcmp (interface, "wl_shell") == 0)
|
||||
priv->wl_shell = wl_registry_bind (registry, id, &wl_shell_interface, 1);
|
||||
else if (strcmp (interface, "xdg_wm_base") == 0) {
|
||||
priv->xdg_wm_base =
|
||||
wl_registry_bind (registry, id, &xdg_wm_base_interface, 1);
|
||||
xdg_wm_base_add_listener (priv->xdg_wm_base, &xdg_wm_base_listener, priv);
|
||||
} else if (strcmp (interface, "wl_output") == 0) {
|
||||
if (!priv->output) {
|
||||
priv->output = wl_registry_bind (registry, id, &wl_output_interface, 1);
|
||||
wl_output_add_listener (priv->output, &output_listener, priv);
|
||||
}
|
||||
} else if (strcmp (interface, "zwp_linux_dmabuf_v1") == 0) {
|
||||
priv->dmabuf =
|
||||
wl_registry_bind (registry, id, &zwp_linux_dmabuf_v1_interface, 3);
|
||||
zwp_linux_dmabuf_v1_add_listener (priv->dmabuf, &dmabuf_listener, priv);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
registry_handle_global,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_display_wayland_setup (GstVaapiDisplay * display)
|
||||
{
|
||||
GstVaapiDisplayWaylandPrivate *const priv =
|
||||
GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display);
|
||||
|
||||
wl_display_set_user_data (priv->wl_display, priv);
|
||||
priv->registry = wl_display_get_registry (priv->wl_display);
|
||||
wl_registry_add_listener (priv->registry, ®istry_listener, priv);
|
||||
priv->event_fd = wl_display_get_fd (priv->wl_display);
|
||||
wl_display_roundtrip (priv->wl_display);
|
||||
|
||||
if (!priv->width || !priv->height) {
|
||||
wl_display_roundtrip (priv->wl_display);
|
||||
if (!priv->width || !priv->height) {
|
||||
GST_ERROR ("failed to determine the display size");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!priv->compositor) {
|
||||
GST_ERROR ("failed to bind compositor interface");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (priv->xdg_wm_base)
|
||||
return TRUE;
|
||||
|
||||
if (!priv->wl_shell) {
|
||||
GST_ERROR ("failed to bind wl_shell interface");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_display_wayland_bind_display (GstVaapiDisplay * display,
|
||||
gpointer native_display)
|
||||
{
|
||||
GstVaapiDisplayWaylandPrivate *const priv =
|
||||
GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display);
|
||||
|
||||
priv->wl_display = native_display;
|
||||
priv->use_foreign_display = TRUE;
|
||||
|
||||
/* XXX: how to get socket/display name? */
|
||||
GST_WARNING ("wayland: get display name");
|
||||
set_display_name (display, NULL);
|
||||
|
||||
return gst_vaapi_display_wayland_setup (display);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_display_wayland_open_display (GstVaapiDisplay * display,
|
||||
const gchar * name)
|
||||
{
|
||||
GstVaapiDisplayWaylandPrivate *const priv =
|
||||
GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display);
|
||||
|
||||
if (!set_display_name (display, name))
|
||||
return FALSE;
|
||||
|
||||
priv->wl_display = wl_display_connect (name);
|
||||
if (!priv->wl_display)
|
||||
return FALSE;
|
||||
priv->use_foreign_display = FALSE;
|
||||
|
||||
return gst_vaapi_display_wayland_setup (display);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_wayland_close_display (GstVaapiDisplay * display)
|
||||
{
|
||||
GstVaapiDisplayWaylandPrivate *const priv =
|
||||
GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display);
|
||||
|
||||
g_clear_pointer (&priv->output, wl_output_destroy);
|
||||
g_clear_pointer (&priv->wl_shell, wl_shell_destroy);
|
||||
g_clear_pointer (&priv->xdg_wm_base, xdg_wm_base_destroy);
|
||||
g_clear_pointer (&priv->subcompositor, wl_subcompositor_destroy);
|
||||
g_clear_pointer (&priv->compositor, wl_compositor_destroy);
|
||||
g_clear_pointer (&priv->registry, wl_registry_destroy);
|
||||
|
||||
g_array_unref (priv->dmabuf_formats);
|
||||
|
||||
if (priv->wl_display) {
|
||||
if (!priv->use_foreign_display)
|
||||
wl_display_disconnect (priv->wl_display);
|
||||
priv->wl_display = NULL;
|
||||
}
|
||||
|
||||
g_clear_pointer (&priv->display_name, g_free);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_display_wayland_get_display_info (GstVaapiDisplay * display,
|
||||
GstVaapiDisplayInfo * info)
|
||||
{
|
||||
GstVaapiDisplayWaylandPrivate *const priv =
|
||||
GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display);
|
||||
|
||||
info->native_display = priv->wl_display;
|
||||
info->display_name = priv->display_name;
|
||||
if (!info->va_display) {
|
||||
info->va_display = vaGetDisplayWl (priv->wl_display);
|
||||
if (!info->va_display)
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_wayland_get_size (GstVaapiDisplay * display,
|
||||
guint * pwidth, guint * pheight)
|
||||
{
|
||||
GstVaapiDisplayWaylandPrivate *const priv =
|
||||
GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display);
|
||||
|
||||
if (!priv->output)
|
||||
return;
|
||||
|
||||
if (pwidth)
|
||||
*pwidth = priv->width;
|
||||
|
||||
if (pheight)
|
||||
*pheight = priv->height;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_wayland_get_size_mm (GstVaapiDisplay * display,
|
||||
guint * pwidth, guint * pheight)
|
||||
{
|
||||
GstVaapiDisplayWaylandPrivate *const priv =
|
||||
GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display);
|
||||
|
||||
if (!priv->output)
|
||||
return;
|
||||
|
||||
if (pwidth)
|
||||
*pwidth = priv->phys_width;
|
||||
|
||||
if (pheight)
|
||||
*pheight = priv->phys_height;
|
||||
}
|
||||
|
||||
static GstVaapiWindow *
|
||||
gst_vaapi_display_wayland_create_window (GstVaapiDisplay * display,
|
||||
GstVaapiID id, guint width, guint height)
|
||||
{
|
||||
if (id != GST_VAAPI_ID_INVALID)
|
||||
return NULL;
|
||||
return gst_vaapi_window_wayland_new (display, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_wayland_init (GstVaapiDisplayWayland * display)
|
||||
{
|
||||
GstVaapiDisplayWaylandPrivate *const priv =
|
||||
gst_vaapi_display_wayland_get_instance_private (display);
|
||||
|
||||
display->priv = priv;
|
||||
priv->event_fd = -1;
|
||||
priv->dmabuf_formats = g_array_new (FALSE, FALSE, sizeof (GstDRMFormat));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_wayland_class_init (GstVaapiDisplayWaylandClass * klass)
|
||||
{
|
||||
GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass);
|
||||
|
||||
dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND;
|
||||
|
||||
dpy_class->bind_display = gst_vaapi_display_wayland_bind_display;
|
||||
dpy_class->open_display = gst_vaapi_display_wayland_open_display;
|
||||
dpy_class->close_display = gst_vaapi_display_wayland_close_display;
|
||||
dpy_class->get_display = gst_vaapi_display_wayland_get_display_info;
|
||||
dpy_class->get_size = gst_vaapi_display_wayland_get_size;
|
||||
dpy_class->get_size_mm = gst_vaapi_display_wayland_get_size_mm;
|
||||
dpy_class->create_window = gst_vaapi_display_wayland_create_window;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_wayland_new:
|
||||
* @display_name: the Wayland display name
|
||||
*
|
||||
* Opens an Wayland #wl_display using @display_name and returns a
|
||||
* newly allocated #GstVaapiDisplay object. The Wayland display will
|
||||
* be cloed when the reference count of the object reaches zero.
|
||||
*
|
||||
* Return value: a newly allocated #GstVaapiDisplay object
|
||||
*/
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_wayland_new (const gchar * display_name)
|
||||
{
|
||||
GstVaapiDisplay *display;
|
||||
|
||||
display = g_object_new (GST_TYPE_VAAPI_DISPLAY_WAYLAND, NULL);
|
||||
return gst_vaapi_display_config (display,
|
||||
GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer) display_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_wayland_new_with_display:
|
||||
* @wl_display: an Wayland #wl_display
|
||||
*
|
||||
* Creates a #GstVaapiDisplay based on the Wayland @wl_display
|
||||
* display. The caller still owns the display and must call
|
||||
* wl_display_disconnect() when all #GstVaapiDisplay references are
|
||||
* released. Doing so too early can yield undefined behaviour.
|
||||
*
|
||||
* Return value: a newly allocated #GstVaapiDisplay object
|
||||
*/
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_wayland_new_with_display (struct wl_display * wl_display)
|
||||
{
|
||||
GstVaapiDisplay *display;
|
||||
|
||||
g_return_val_if_fail (wl_display, NULL);
|
||||
|
||||
display = g_object_new (GST_TYPE_VAAPI_DISPLAY_WAYLAND, NULL);
|
||||
return gst_vaapi_display_config (display,
|
||||
GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, wl_display);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_wayland_new_with_va_display:
|
||||
* @va_display: a VADisplay #va_display
|
||||
* @wl_display: an Wayland #wl_display
|
||||
*
|
||||
* Creates a #GstVaapiDisplay based on the VADisplay @va_display and
|
||||
* the Wayland @wl_display display.
|
||||
* The caller still owns the display and must call
|
||||
* wl_display_disconnect() when all #GstVaapiDisplay references are
|
||||
* released.
|
||||
*
|
||||
* Return value: a newly allocated #GstVaapiDisplay object
|
||||
*/
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_wayland_new_with_va_display (VADisplay va_display,
|
||||
struct wl_display * wl_display)
|
||||
{
|
||||
GstVaapiDisplay *display;
|
||||
GstVaapiDisplayInfo info = {
|
||||
.va_display = va_display,
|
||||
.native_display = wl_display,
|
||||
};
|
||||
|
||||
g_return_val_if_fail (wl_display, NULL);
|
||||
|
||||
display = g_object_new (GST_TYPE_VAAPI_DISPLAY_WAYLAND, NULL);
|
||||
if (!gst_vaapi_display_config (display,
|
||||
GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, &info)) {
|
||||
gst_object_unref (display);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_wayland_get_display:
|
||||
* @display: a #GstVaapiDisplayWayland
|
||||
*
|
||||
* Returns the underlying Wayland #wl_display that was created by
|
||||
* gst_vaapi_display_wayland_new() or that was bound from
|
||||
* gst_vaapi_display_wayland_new_with_display().
|
||||
*
|
||||
* Return value: the Wayland #wl_display attached to @display
|
||||
*/
|
||||
struct wl_display *
|
||||
gst_vaapi_display_wayland_get_display (GstVaapiDisplayWayland * display)
|
||||
{
|
||||
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_WAYLAND (display), NULL);
|
||||
|
||||
return GST_VAAPI_DISPLAY_WL_DISPLAY (display);
|
||||
}
|
58
gst-libs/gst/vaapi/gstvaapidisplay_wayland.h
Normal file
58
gst-libs/gst/vaapi/gstvaapidisplay_wayland.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* gstvaapidisplay_wayland.h - VA/Wayland display abstraction
|
||||
*
|
||||
* Copyright (C) 2012-2013 Intel Corporation
|
||||
* Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DISPLAY_WAYLAND_H
|
||||
#define GST_VAAPI_DISPLAY_WAYLAND_H
|
||||
|
||||
#include <va/va_wayland.h>
|
||||
#include <gst/vaapi/gstvaapidisplay.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_DISPLAY_WAYLAND (gst_vaapi_display_wayland_get_type ())
|
||||
#define GST_VAAPI_DISPLAY_WAYLAND(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DISPLAY_WAYLAND, GstVaapiDisplayWayland))
|
||||
|
||||
typedef struct _GstVaapiDisplayWayland GstVaapiDisplayWayland;
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_wayland_new (const gchar * display_name);
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_wayland_new_with_display (struct wl_display * wl_display);
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_wayland_new_with_va_display (VADisplay va_display,
|
||||
struct wl_display * wl_display);
|
||||
|
||||
struct wl_display *
|
||||
gst_vaapi_display_wayland_get_display (GstVaapiDisplayWayland * display);
|
||||
|
||||
GType
|
||||
gst_vaapi_display_wayland_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDisplayWayland, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DISPLAY_WAYLAND_H */
|
114
gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h
Normal file
114
gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* gstvaapidisplay_wayland_priv.h - Internal VA/Wayland interface
|
||||
*
|
||||
* Copyright (C) 2012-2013 Intel Corporation
|
||||
* Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DISPLAY_WAYLAND_PRIV_H
|
||||
#define GST_VAAPI_DISPLAY_WAYLAND_PRIV_H
|
||||
|
||||
#include "xdg-shell-client-protocol.h"
|
||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||
|
||||
#include <gst/vaapi/gstvaapidisplay_wayland.h>
|
||||
#include "gstvaapidisplay_priv.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_IS_DISPLAY_WAYLAND(display) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((display), GST_TYPE_VAAPI_DISPLAY_WAYLAND))
|
||||
|
||||
#define GST_VAAPI_DISPLAY_WAYLAND_CAST(display) \
|
||||
((GstVaapiDisplayWayland *)(display))
|
||||
|
||||
#define GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display) \
|
||||
(GST_VAAPI_DISPLAY_WAYLAND_CAST(display)->priv)
|
||||
|
||||
#define GST_VAAPI_DISPLAY_WAYLAND_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_DISPLAY_WAYLAND, GstVaapiDisplayWaylandClass))
|
||||
|
||||
typedef struct _GstVaapiDisplayWaylandPrivate GstVaapiDisplayWaylandPrivate;
|
||||
typedef struct _GstVaapiDisplayWaylandClass GstVaapiDisplayWaylandClass;
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DISPLAY_WL_DISPLAY:
|
||||
* @display: a #GstVaapiDisplay
|
||||
*
|
||||
* Macro that evaluates to the underlying Wayland #wl_display object
|
||||
* of @display
|
||||
*/
|
||||
#undef GST_VAAPI_DISPLAY_WL_DISPLAY
|
||||
#define GST_VAAPI_DISPLAY_WL_DISPLAY(display) \
|
||||
GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display)->wl_display
|
||||
|
||||
typedef struct _GstDRMFormat GstDRMFormat;
|
||||
|
||||
struct _GstDRMFormat {
|
||||
guint format;
|
||||
guint64 modifier;
|
||||
};
|
||||
|
||||
struct _GstVaapiDisplayWaylandPrivate
|
||||
{
|
||||
gchar *display_name;
|
||||
struct wl_display *wl_display;
|
||||
struct wl_compositor *compositor;
|
||||
struct wl_shell *wl_shell;
|
||||
struct xdg_wm_base *xdg_wm_base;
|
||||
struct wl_subcompositor *subcompositor;
|
||||
struct wl_output *output;
|
||||
struct zwp_linux_dmabuf_v1 *dmabuf;
|
||||
struct wl_registry *registry;
|
||||
GArray *dmabuf_formats;
|
||||
guint width;
|
||||
guint height;
|
||||
guint phys_width;
|
||||
guint phys_height;
|
||||
gint event_fd;
|
||||
guint use_foreign_display:1;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDisplayWayland:
|
||||
*
|
||||
* VA/Wayland display wrapper.
|
||||
*/
|
||||
struct _GstVaapiDisplayWayland
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiDisplay parent_instance;
|
||||
|
||||
GstVaapiDisplayWaylandPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDisplayWaylandClass:
|
||||
*
|
||||
* VA/Wayland display wrapper clas.
|
||||
*/
|
||||
struct _GstVaapiDisplayWaylandClass
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiDisplayClass parent_class;
|
||||
};
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DISPLAY_WAYLAND_PRIV_H */
|
545
gst-libs/gst/vaapi/gstvaapidisplay_x11.c
Normal file
545
gst-libs/gst/vaapi/gstvaapidisplay_x11.c
Normal file
|
@ -0,0 +1,545 @@
|
|||
/*
|
||||
* gstvaapidisplay_x11.c - VA/X11 display abstraction
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||
* Copyright (C) 2011-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstvaapidisplay_x11
|
||||
* @short_description: VA/X11 display abstraction
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "gstvaapiutils.h"
|
||||
#include "gstvaapidisplay_priv.h"
|
||||
#include "gstvaapidisplay_x11.h"
|
||||
#include "gstvaapidisplay_x11_priv.h"
|
||||
#include "gstvaapiwindow_x11.h"
|
||||
|
||||
#if HAVE_XRANDR
|
||||
# include <X11/extensions/Xrandr.h>
|
||||
#endif
|
||||
|
||||
#define DEBUG_VAAPI_DISPLAY 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GstVaapiDisplayX11, gst_vaapi_display_x11,
|
||||
GST_TYPE_VAAPI_DISPLAY);
|
||||
|
||||
static inline const gchar *
|
||||
get_default_display_name (void)
|
||||
{
|
||||
static const gchar *g_display_name;
|
||||
|
||||
if (!g_display_name)
|
||||
g_display_name = getenv ("DISPLAY");
|
||||
return g_display_name;
|
||||
}
|
||||
|
||||
/* Reconstruct a display name without our prefix */
|
||||
static const gchar *
|
||||
get_display_name (GstVaapiDisplayX11 * display)
|
||||
{
|
||||
GstVaapiDisplayX11Private *const priv = display->priv;
|
||||
const gchar *display_name = priv->display_name;
|
||||
|
||||
if (!display_name || *display_name == '\0')
|
||||
return NULL;
|
||||
return display_name;
|
||||
}
|
||||
|
||||
/* Mangle display name with our prefix */
|
||||
static gboolean
|
||||
set_display_name (GstVaapiDisplayX11 * display, const gchar * display_name)
|
||||
{
|
||||
GstVaapiDisplayX11Private *const priv = display->priv;
|
||||
|
||||
g_free (priv->display_name);
|
||||
|
||||
if (!display_name) {
|
||||
display_name = get_default_display_name ();
|
||||
if (!display_name)
|
||||
display_name = "";
|
||||
}
|
||||
priv->display_name = g_strdup (display_name);
|
||||
return priv->display_name != NULL;
|
||||
}
|
||||
|
||||
/* Set synchronous behavious on the underlying X11 display */
|
||||
static void
|
||||
set_synchronous (GstVaapiDisplayX11 * display, gboolean synchronous)
|
||||
{
|
||||
GstVaapiDisplayX11Private *const priv = display->priv;
|
||||
|
||||
if (priv->synchronous != synchronous) {
|
||||
priv->synchronous = synchronous;
|
||||
if (priv->x11_display) {
|
||||
GST_VAAPI_DISPLAY_LOCK (display);
|
||||
XSynchronize (priv->x11_display, synchronous);
|
||||
GST_VAAPI_DISPLAY_UNLOCK (display);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for display server extensions */
|
||||
static void
|
||||
check_extensions (GstVaapiDisplayX11 * display)
|
||||
{
|
||||
GstVaapiDisplayX11Private *const priv = display->priv;
|
||||
int evt_base, err_base;
|
||||
|
||||
#if HAVE_XRANDR
|
||||
priv->use_xrandr = XRRQueryExtension (priv->x11_display,
|
||||
&evt_base, &err_base);
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_display_x11_bind_display (GstVaapiDisplay * base_display,
|
||||
gpointer native_display)
|
||||
{
|
||||
GstVaapiDisplayX11 *const display = GST_VAAPI_DISPLAY_X11_CAST (base_display);
|
||||
GstVaapiDisplayX11Private *const priv = display->priv;
|
||||
|
||||
priv->x11_display = native_display;
|
||||
priv->x11_screen = DefaultScreen (native_display);
|
||||
priv->use_foreign_display = TRUE;
|
||||
|
||||
check_extensions (display);
|
||||
if (!set_display_name (display, XDisplayString (priv->x11_display)))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_display_x11_open_display (GstVaapiDisplay * base_display,
|
||||
const gchar * name)
|
||||
{
|
||||
GstVaapiDisplayX11 *const display = GST_VAAPI_DISPLAY_X11_CAST (base_display);
|
||||
GstVaapiDisplayX11Private *const priv = display->priv;
|
||||
|
||||
if (!set_display_name (display, name))
|
||||
return FALSE;
|
||||
|
||||
priv->x11_display = XOpenDisplay (get_display_name (display));
|
||||
if (!priv->x11_display)
|
||||
return FALSE;
|
||||
priv->use_foreign_display = FALSE;
|
||||
|
||||
priv->x11_screen = DefaultScreen (priv->x11_display);
|
||||
|
||||
check_extensions (display);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_x11_close_display (GstVaapiDisplay * display)
|
||||
{
|
||||
GstVaapiDisplayX11Private *const priv =
|
||||
GST_VAAPI_DISPLAY_X11_PRIVATE (display);
|
||||
|
||||
g_clear_pointer (&priv->pixmap_formats, g_array_unref);
|
||||
|
||||
if (priv->x11_display) {
|
||||
if (!priv->use_foreign_display)
|
||||
XCloseDisplay (priv->x11_display);
|
||||
priv->x11_display = NULL;
|
||||
}
|
||||
|
||||
g_clear_pointer (&priv->display_name, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_x11_sync (GstVaapiDisplay * display)
|
||||
{
|
||||
GstVaapiDisplayX11Private *const priv =
|
||||
GST_VAAPI_DISPLAY_X11_PRIVATE (display);
|
||||
|
||||
if (priv->x11_display) {
|
||||
GST_VAAPI_DISPLAY_LOCK (display);
|
||||
XSync (priv->x11_display, False);
|
||||
GST_VAAPI_DISPLAY_UNLOCK (display);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_x11_flush (GstVaapiDisplay * display)
|
||||
{
|
||||
GstVaapiDisplayX11Private *const priv =
|
||||
GST_VAAPI_DISPLAY_X11_PRIVATE (display);
|
||||
|
||||
if (priv->x11_display) {
|
||||
GST_VAAPI_DISPLAY_LOCK (display);
|
||||
XFlush (priv->x11_display);
|
||||
GST_VAAPI_DISPLAY_UNLOCK (display);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_display_x11_get_display_info (GstVaapiDisplay * display,
|
||||
GstVaapiDisplayInfo * info)
|
||||
{
|
||||
GstVaapiDisplayX11Private *const priv =
|
||||
GST_VAAPI_DISPLAY_X11_PRIVATE (display);
|
||||
|
||||
info->native_display = priv->x11_display;
|
||||
info->display_name = priv->display_name;
|
||||
if (!info->va_display) {
|
||||
info->va_display = vaGetDisplay (priv->x11_display);
|
||||
if (!info->va_display)
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_x11_get_size (GstVaapiDisplay * display,
|
||||
guint * pwidth, guint * pheight)
|
||||
{
|
||||
GstVaapiDisplayX11Private *const priv =
|
||||
GST_VAAPI_DISPLAY_X11_PRIVATE (display);
|
||||
|
||||
if (!priv->x11_display)
|
||||
return;
|
||||
|
||||
if (pwidth)
|
||||
*pwidth = DisplayWidth (priv->x11_display, priv->x11_screen);
|
||||
|
||||
if (pheight)
|
||||
*pheight = DisplayHeight (priv->x11_display, priv->x11_screen);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_x11_get_size_mm (GstVaapiDisplay * display,
|
||||
guint * pwidth, guint * pheight)
|
||||
{
|
||||
GstVaapiDisplayX11Private *const priv =
|
||||
GST_VAAPI_DISPLAY_X11_PRIVATE (display);
|
||||
guint width_mm, height_mm;
|
||||
|
||||
if (!priv->x11_display)
|
||||
return;
|
||||
|
||||
width_mm = DisplayWidthMM (priv->x11_display, priv->x11_screen);
|
||||
height_mm = DisplayHeightMM (priv->x11_display, priv->x11_screen);
|
||||
|
||||
#if HAVE_XRANDR
|
||||
/* XXX: fix up physical size if the display is rotated */
|
||||
if (priv->use_xrandr) {
|
||||
XRRScreenConfiguration *xrr_config = NULL;
|
||||
XRRScreenSize *xrr_sizes;
|
||||
Window win;
|
||||
int num_xrr_sizes, size_id, screen;
|
||||
Rotation rotation;
|
||||
|
||||
do {
|
||||
win = DefaultRootWindow (priv->x11_display);
|
||||
screen = XRRRootToScreen (priv->x11_display, win);
|
||||
|
||||
xrr_config = XRRGetScreenInfo (priv->x11_display, win);
|
||||
if (!xrr_config)
|
||||
break;
|
||||
|
||||
size_id = XRRConfigCurrentConfiguration (xrr_config, &rotation);
|
||||
if (rotation == RR_Rotate_0 || rotation == RR_Rotate_180)
|
||||
break;
|
||||
|
||||
xrr_sizes = XRRSizes (priv->x11_display, screen, &num_xrr_sizes);
|
||||
if (!xrr_sizes || size_id >= num_xrr_sizes)
|
||||
break;
|
||||
|
||||
width_mm = xrr_sizes[size_id].mheight;
|
||||
height_mm = xrr_sizes[size_id].mwidth;
|
||||
} while (0);
|
||||
if (xrr_config)
|
||||
XRRFreeScreenConfigInfo (xrr_config);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pwidth)
|
||||
*pwidth = width_mm;
|
||||
|
||||
if (pheight)
|
||||
*pheight = height_mm;
|
||||
}
|
||||
|
||||
static GstVaapiWindow *
|
||||
gst_vaapi_display_x11_create_window (GstVaapiDisplay * display, GstVaapiID id,
|
||||
guint width, guint height)
|
||||
{
|
||||
return id != GST_VAAPI_ID_INVALID ?
|
||||
gst_vaapi_window_x11_new_with_xid (display, id) :
|
||||
gst_vaapi_window_x11_new (display, width, height);
|
||||
}
|
||||
|
||||
void
|
||||
gst_vaapi_display_x11_class_init (GstVaapiDisplayX11Class * klass)
|
||||
{
|
||||
GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass);
|
||||
|
||||
dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_X11;
|
||||
dpy_class->bind_display = gst_vaapi_display_x11_bind_display;
|
||||
dpy_class->open_display = gst_vaapi_display_x11_open_display;
|
||||
dpy_class->close_display = gst_vaapi_display_x11_close_display;
|
||||
dpy_class->sync = gst_vaapi_display_x11_sync;
|
||||
dpy_class->flush = gst_vaapi_display_x11_flush;
|
||||
dpy_class->get_display = gst_vaapi_display_x11_get_display_info;
|
||||
dpy_class->get_size = gst_vaapi_display_x11_get_size;
|
||||
dpy_class->get_size_mm = gst_vaapi_display_x11_get_size_mm;
|
||||
dpy_class->create_window = gst_vaapi_display_x11_create_window;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_x11_init (GstVaapiDisplayX11 * display)
|
||||
{
|
||||
GstVaapiDisplayX11Private *const priv =
|
||||
gst_vaapi_display_x11_get_instance_private (display);
|
||||
|
||||
display->priv = priv;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_x11_new:
|
||||
* @display_name: the X11 display name
|
||||
*
|
||||
* Opens an X11 #Display using @display_name and returns a newly
|
||||
* allocated #GstVaapiDisplay object. The X11 display will be cloed
|
||||
* when the reference count of the object reaches zero.
|
||||
*
|
||||
* Return value: a newly allocated #GstVaapiDisplay object
|
||||
*/
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_x11_new (const gchar * display_name)
|
||||
{
|
||||
GstVaapiDisplay *display;
|
||||
|
||||
display = g_object_new (GST_TYPE_VAAPI_DISPLAY_X11, NULL);
|
||||
return gst_vaapi_display_config (display,
|
||||
GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer) display_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_x11_new_with_display:
|
||||
* @x11_display: an X11 #Display
|
||||
*
|
||||
* Creates a #GstVaapiDisplay based on the X11 @x11_display
|
||||
* display. The caller still owns the display and must call
|
||||
* XCloseDisplay() when all #GstVaapiDisplay references are
|
||||
* released. Doing so too early can yield undefined behaviour.
|
||||
*
|
||||
* Return value: a newly allocated #GstVaapiDisplay object
|
||||
*/
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_x11_new_with_display (Display * x11_display)
|
||||
{
|
||||
GstVaapiDisplay *display;
|
||||
|
||||
g_return_val_if_fail (x11_display, NULL);
|
||||
|
||||
display = g_object_new (GST_TYPE_VAAPI_DISPLAY_X11, NULL);
|
||||
return gst_vaapi_display_config (display,
|
||||
GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, x11_display);
|
||||
}
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_x11_new_with_va_display (VADisplay va_display,
|
||||
Display * x11_display)
|
||||
{
|
||||
GstVaapiDisplay *display;
|
||||
GstVaapiDisplayInfo info = {
|
||||
.va_display = va_display,
|
||||
.native_display = x11_display,
|
||||
};
|
||||
|
||||
g_return_val_if_fail (x11_display, NULL);
|
||||
|
||||
display = g_object_new (GST_TYPE_VAAPI_DISPLAY_X11, NULL);
|
||||
return gst_vaapi_display_config (display,
|
||||
GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, &info);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_x11_get_display:
|
||||
* @display: a #GstVaapiDisplayX11
|
||||
*
|
||||
* Returns the underlying X11 #Display that was created by
|
||||
* gst_vaapi_display_x11_new() or that was bound from
|
||||
* gst_vaapi_display_x11_new_with_display().
|
||||
*
|
||||
* Return value: the X11 #Display attached to @display
|
||||
*/
|
||||
Display *
|
||||
gst_vaapi_display_x11_get_display (GstVaapiDisplayX11 * display)
|
||||
{
|
||||
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), NULL);
|
||||
|
||||
return GST_VAAPI_DISPLAY_XDISPLAY (display);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_x11_get_screen:
|
||||
* @display: a #GstVaapiDisplayX11
|
||||
*
|
||||
* Returns the default X11 screen that was created by
|
||||
* gst_vaapi_display_x11_new() or that was bound from
|
||||
* gst_vaapi_display_x11_new_with_display().
|
||||
*
|
||||
* Return value: the X11 #Display attached to @display
|
||||
*/
|
||||
int
|
||||
gst_vaapi_display_x11_get_screen (GstVaapiDisplayX11 * display)
|
||||
{
|
||||
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), -1);
|
||||
|
||||
return GST_VAAPI_DISPLAY_XSCREEN (display);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_x11_set_synchronous:
|
||||
* @display: a #GstVaapiDisplayX11
|
||||
* @synchronous: boolean value that indicates whether to enable or
|
||||
* disable synchronization
|
||||
*
|
||||
* If @synchronous is %TRUE, gst_vaapi_display_x11_set_synchronous()
|
||||
* turns on synchronous behaviour on the underlying X11
|
||||
* display. Otherwise, synchronous behaviour is disabled if
|
||||
* @synchronous is %FALSE.
|
||||
*/
|
||||
void
|
||||
gst_vaapi_display_x11_set_synchronous (GstVaapiDisplayX11 * display,
|
||||
gboolean synchronous)
|
||||
{
|
||||
g_return_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display));
|
||||
|
||||
set_synchronous (display, synchronous);
|
||||
}
|
||||
|
||||
typedef struct _GstVaapiPixmapFormatX11 GstVaapiPixmapFormatX11;
|
||||
struct _GstVaapiPixmapFormatX11
|
||||
{
|
||||
GstVideoFormat format;
|
||||
gint depth;
|
||||
gint bpp;
|
||||
};
|
||||
|
||||
static GstVideoFormat
|
||||
pix_fmt_to_video_format (gint depth, gint bpp)
|
||||
{
|
||||
GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
|
||||
switch (bpp) {
|
||||
case 16:
|
||||
if (depth == 15)
|
||||
format = GST_VIDEO_FORMAT_RGB15;
|
||||
else if (depth == 16)
|
||||
format = GST_VIDEO_FORMAT_RGB16;
|
||||
break;
|
||||
case 24:
|
||||
if (depth == 24)
|
||||
format = GST_VIDEO_FORMAT_RGB;
|
||||
break;
|
||||
case 32:
|
||||
if (depth == 24 || depth == 32)
|
||||
format = GST_VIDEO_FORMAT_xRGB;
|
||||
break;
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_pix_fmts (GstVaapiDisplayX11 * display)
|
||||
{
|
||||
GstVaapiDisplayX11Private *const priv =
|
||||
GST_VAAPI_DISPLAY_X11_PRIVATE (display);
|
||||
XPixmapFormatValues *pix_fmts;
|
||||
int i, n, num_pix_fmts;
|
||||
|
||||
if (priv->pixmap_formats)
|
||||
return TRUE;
|
||||
|
||||
GST_VAAPI_DISPLAY_LOCK (display);
|
||||
pix_fmts = XListPixmapFormats (GST_VAAPI_DISPLAY_XDISPLAY (display),
|
||||
&num_pix_fmts);
|
||||
GST_VAAPI_DISPLAY_UNLOCK (display);
|
||||
if (!pix_fmts)
|
||||
return FALSE;
|
||||
|
||||
priv->pixmap_formats = g_array_sized_new (FALSE, FALSE,
|
||||
sizeof (GstVaapiPixmapFormatX11), num_pix_fmts);
|
||||
if (!priv->pixmap_formats) {
|
||||
XFree (pix_fmts);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0, n = 0; i < num_pix_fmts; i++) {
|
||||
GstVaapiPixmapFormatX11 *const pix_fmt =
|
||||
&g_array_index (priv->pixmap_formats, GstVaapiPixmapFormatX11, n);
|
||||
|
||||
pix_fmt->depth = pix_fmts[i].depth;
|
||||
pix_fmt->bpp = pix_fmts[i].bits_per_pixel;
|
||||
pix_fmt->format = pix_fmt_to_video_format (pix_fmt->depth, pix_fmt->bpp);
|
||||
if (pix_fmt->format != GST_VIDEO_FORMAT_UNKNOWN)
|
||||
n++;
|
||||
}
|
||||
priv->pixmap_formats->len = n;
|
||||
XFree (pix_fmts);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Determine the GstVideoFormat based on a supported Pixmap depth */
|
||||
GstVideoFormat
|
||||
gst_vaapi_display_x11_get_pixmap_format (GstVaapiDisplayX11 * display,
|
||||
guint depth)
|
||||
{
|
||||
if (ensure_pix_fmts (display)) {
|
||||
GstVaapiDisplayX11Private *const priv =
|
||||
GST_VAAPI_DISPLAY_X11_PRIVATE (display);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < priv->pixmap_formats->len; i++) {
|
||||
GstVaapiPixmapFormatX11 *const pix_fmt =
|
||||
&g_array_index (priv->pixmap_formats, GstVaapiPixmapFormatX11, i);
|
||||
if (pix_fmt->depth == depth)
|
||||
return pix_fmt->format;
|
||||
}
|
||||
}
|
||||
return GST_VIDEO_FORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Determine the Pixmap depth based on a GstVideoFormat */
|
||||
guint
|
||||
gst_vaapi_display_x11_get_pixmap_depth (GstVaapiDisplayX11 * display,
|
||||
GstVideoFormat format)
|
||||
{
|
||||
if (ensure_pix_fmts (display)) {
|
||||
GstVaapiDisplayX11Private *const priv =
|
||||
GST_VAAPI_DISPLAY_X11_PRIVATE (display);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < priv->pixmap_formats->len; i++) {
|
||||
GstVaapiPixmapFormatX11 *const pix_fmt =
|
||||
&g_array_index (priv->pixmap_formats, GstVaapiPixmapFormatX11, i);
|
||||
if (pix_fmt->format == format)
|
||||
return pix_fmt->depth;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
65
gst-libs/gst/vaapi/gstvaapidisplay_x11.h
Normal file
65
gst-libs/gst/vaapi/gstvaapidisplay_x11.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* gstvaapidisplay_x11.h - VA/X11 display abstraction
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||
* Copyright (C) 2012-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DISPLAY_X11_H
|
||||
#define GST_VAAPI_DISPLAY_X11_H
|
||||
|
||||
#include <va/va_x11.h>
|
||||
#include <gst/vaapi/gstvaapidisplay.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_DISPLAY_X11 (gst_vaapi_display_x11_get_type ())
|
||||
#define GST_VAAPI_DISPLAY_X11(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DISPLAY_X11, GstVaapiDisplayX11))
|
||||
|
||||
typedef struct _GstVaapiDisplayX11 GstVaapiDisplayX11;
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_x11_new (const gchar * display_name);
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_x11_new_with_display (Display * x11_display);
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_x11_new_with_va_display (VADisplay va_display, Display * x11_display);
|
||||
|
||||
Display *
|
||||
gst_vaapi_display_x11_get_display (GstVaapiDisplayX11 * display);
|
||||
|
||||
int
|
||||
gst_vaapi_display_x11_get_screen (GstVaapiDisplayX11 * display);
|
||||
|
||||
void
|
||||
gst_vaapi_display_x11_set_synchronous (GstVaapiDisplayX11 * display,
|
||||
gboolean synchronous);
|
||||
|
||||
GType
|
||||
gst_vaapi_display_x11_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDisplayX11, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DISPLAY_X11_H */
|
116
gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h
Normal file
116
gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* gstvaapidisplay_x11_priv.h - Internal VA/X11 interface
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
||||
* Copyright (C) 2012-2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DISPLAY_X11_PRIV_H
|
||||
#define GST_VAAPI_DISPLAY_X11_PRIV_H
|
||||
|
||||
#include <gst/vaapi/gstvaapiutils_x11.h>
|
||||
#include <gst/vaapi/gstvaapidisplay_x11.h>
|
||||
#include "gstvaapidisplay_priv.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_IS_DISPLAY_X11(display) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((display), GST_TYPE_VAAPI_DISPLAY_X11))
|
||||
|
||||
#define GST_VAAPI_DISPLAY_X11_CAST(display) \
|
||||
((GstVaapiDisplayX11 *)(display))
|
||||
|
||||
#define GST_VAAPI_DISPLAY_X11_PRIVATE(display) \
|
||||
(GST_VAAPI_DISPLAY_X11_CAST (display)->priv)
|
||||
|
||||
#define GST_VAAPI_DISPLAY_X11_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_DISPLAY_X11, GstVaapiDisplayX11Class))
|
||||
|
||||
typedef struct _GstVaapiDisplayX11Private GstVaapiDisplayX11Private;
|
||||
typedef struct _GstVaapiDisplayX11Class GstVaapiDisplayX11Class;
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DISPLAY_XDISPLAY:
|
||||
* @display: a #GstVaapiDisplay
|
||||
*
|
||||
* Macro that evaluates to the underlying X11 #Display of @display
|
||||
*/
|
||||
#undef GST_VAAPI_DISPLAY_XDISPLAY
|
||||
#define GST_VAAPI_DISPLAY_XDISPLAY(display) \
|
||||
GST_VAAPI_DISPLAY_X11_PRIVATE(display)->x11_display
|
||||
|
||||
/**
|
||||
* GST_VAAPI_DISPLAY_XSCREEN:
|
||||
* @display: a #GstVaapiDisplay
|
||||
*
|
||||
* Macro that evaluates to the underlying X11 screen of @display
|
||||
*/
|
||||
#undef GST_VAAPI_DISPLAY_XSCREEN
|
||||
#define GST_VAAPI_DISPLAY_XSCREEN(display) \
|
||||
GST_VAAPI_DISPLAY_X11_PRIVATE(display)->x11_screen
|
||||
|
||||
struct _GstVaapiDisplayX11Private
|
||||
{
|
||||
gchar *display_name;
|
||||
Display *x11_display;
|
||||
int x11_screen;
|
||||
GArray *pixmap_formats;
|
||||
guint use_foreign_display:1; // Foreign native_display?
|
||||
guint use_xrandr:1;
|
||||
guint synchronous:1;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDisplayX11:
|
||||
*
|
||||
* VA/X11 display wrapper.
|
||||
*/
|
||||
struct _GstVaapiDisplayX11
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiDisplay parent_instance;
|
||||
|
||||
GstVaapiDisplayX11Private *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDisplayX11Class:
|
||||
*
|
||||
* VA/X11 display wrapper class.
|
||||
*/
|
||||
struct _GstVaapiDisplayX11Class
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiDisplayClass parent_class;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVideoFormat
|
||||
gst_vaapi_display_x11_get_pixmap_format (GstVaapiDisplayX11 * display,
|
||||
guint depth);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
guint
|
||||
gst_vaapi_display_x11_get_pixmap_depth (GstVaapiDisplayX11 * display,
|
||||
GstVideoFormat format);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DISPLAY_X11_PRIV_H */
|
1873
gst-libs/gst/vaapi/gstvaapiencoder.c
Normal file
1873
gst-libs/gst/vaapi/gstvaapiencoder.c
Normal file
File diff suppressed because it is too large
Load diff
202
gst-libs/gst/vaapi/gstvaapiencoder.h
Normal file
202
gst-libs/gst/vaapi/gstvaapiencoder.h
Normal file
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* gstvaapiencoder.h - VA encoder abstraction
|
||||
*
|
||||
* Copyright (C) 2013-2014 Intel Corporation
|
||||
* Author: Wind Yuan <feng.yuan@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_ENCODER_H
|
||||
#define GST_VAAPI_ENCODER_H
|
||||
|
||||
#include <gst/video/gstvideoutils.h>
|
||||
#include <gst/vaapi/gstvaapicodedbufferproxy.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_ENCODER \
|
||||
(gst_vaapi_encoder_get_type ())
|
||||
#define GST_VAAPI_ENCODER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_ENCODER, GstVaapiEncoder))
|
||||
#define GST_VAAPI_IS_ENCODER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_ENCODER))
|
||||
|
||||
typedef struct _GstVaapiEncoder GstVaapiEncoder;
|
||||
|
||||
GType
|
||||
gst_vaapi_encoder_get_type (void) G_GNUC_CONST;
|
||||
|
||||
/**
|
||||
* GST_VAAPI_PARAM_ENCODER_EXPOSURE: (value 65536)
|
||||
*
|
||||
* This user defined flag is added when the internal encoder class
|
||||
* wants to expose its property gparam spec to the according encode
|
||||
* class. */
|
||||
#define GST_VAAPI_PARAM_ENCODER_EXPOSURE GST_PARAM_USER_SHIFT
|
||||
|
||||
/**
|
||||
* GstVaapiEncoderStatus:
|
||||
* @GST_VAAPI_ENCODER_STATUS_SUCCESS: Success.
|
||||
* @GST_VAAPI_ENCODER_STATUS_NO_SURFACE: No surface left to encode.
|
||||
* @GST_VAAPI_ENCODER_STATUS_NO_BUFFER: No coded buffer left to hold
|
||||
* the encoded picture.
|
||||
* @GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN: Unknown error.
|
||||
* @GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED: No memory left.
|
||||
* @GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED: The requested
|
||||
* operation failed to execute properly. e.g. invalid point in time to
|
||||
* execute the operation.
|
||||
* @GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_RATE_CONTROL:
|
||||
* Unsupported rate control value.
|
||||
* @GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE: Unsupported profile.
|
||||
* @GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER: Invalid parameter.
|
||||
* @GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_BUFFER: Invalid buffer.
|
||||
* @GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_SURFACE: Invalid surface.
|
||||
* @GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER: Invalid header.
|
||||
*
|
||||
* Set of #GstVaapiEncoder status codes.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GST_VAAPI_ENCODER_STATUS_SUCCESS = 0,
|
||||
GST_VAAPI_ENCODER_STATUS_NO_SURFACE = 1,
|
||||
GST_VAAPI_ENCODER_STATUS_NO_BUFFER = 2,
|
||||
|
||||
GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN = -1,
|
||||
GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED = -2,
|
||||
GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED = -3,
|
||||
GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_RATE_CONTROL = -4,
|
||||
GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE = -5,
|
||||
GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER = -100,
|
||||
GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_BUFFER = -101,
|
||||
GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_SURFACE = -102,
|
||||
GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER = -103,
|
||||
} GstVaapiEncoderStatus;
|
||||
|
||||
/**
|
||||
* GstVaapiEncoderTune:
|
||||
* @GST_VAAPI_ENCODER_TUNE_NONE: No tuning option set.
|
||||
* @GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION: Tune for higher compression
|
||||
* ratios, at the expense of lower compatibility at decoding time.
|
||||
* @GST_VAAPI_ENCODER_TUNE_LOW_LATENCY: Tune for low latency decoding.
|
||||
* @GST_VAAPI_ENCODER_TUNE_LOW_POWER: Tune encoder for low power /
|
||||
* resources conditions. This can affect compression ratio or visual
|
||||
* quality to match low power conditions.
|
||||
*
|
||||
* The set of tuning options for a #GstVaapiEncoder. By default,
|
||||
* maximum compatibility for decoding is preferred, so the lowest
|
||||
* coding tools are enabled.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VAAPI_ENCODER_TUNE_NONE = 0,
|
||||
GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION,
|
||||
GST_VAAPI_ENCODER_TUNE_LOW_LATENCY,
|
||||
GST_VAAPI_ENCODER_TUNE_LOW_POWER,
|
||||
} GstVaapiEncoderTune;
|
||||
|
||||
/**
|
||||
* GstVaapiEncoderMbbrc:
|
||||
* @GST_VAAPI_ENCODER_MBBRC_AUTO: bitrate control auto
|
||||
* @GST_VAAPI_ENCODER_MBBRC_ON: bitrate control on
|
||||
* @GST_VAAPI_ENCODER_MBBRC_OFF: bitrate control off
|
||||
*
|
||||
* Values for the macroblock level bitrate control.
|
||||
*
|
||||
* This property values are only available for H264 and H265 (HEVC)
|
||||
* encoders, when rate control is not Constant QP.
|
||||
**/
|
||||
typedef enum {
|
||||
GST_VAAPI_ENCODER_MBBRC_AUTO = 0,
|
||||
GST_VAAPI_ENCODER_MBBRC_ON = 1,
|
||||
GST_VAAPI_ENCODER_MBBRC_OFF = 2,
|
||||
} GstVaapiEncoderMbbrc;
|
||||
|
||||
GType
|
||||
gst_vaapi_encoder_tune_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GType
|
||||
gst_vaapi_encoder_mbbrc_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void
|
||||
gst_vaapi_encoder_replace (GstVaapiEncoder ** old_encoder_ptr,
|
||||
GstVaapiEncoder * new_encoder);
|
||||
|
||||
GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_get_codec_data (GstVaapiEncoder * encoder,
|
||||
GstBuffer ** out_codec_data_ptr);
|
||||
|
||||
GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_set_codec_state (GstVaapiEncoder * encoder,
|
||||
GstVideoCodecState * state);
|
||||
|
||||
GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_set_rate_control (GstVaapiEncoder * encoder,
|
||||
GstVaapiRateControl rate_control);
|
||||
|
||||
GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_set_bitrate (GstVaapiEncoder * encoder, guint bitrate);
|
||||
|
||||
GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_set_target_percentage (GstVaapiEncoder * encoder,
|
||||
guint target_percentage);
|
||||
|
||||
GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_put_frame (GstVaapiEncoder * encoder,
|
||||
GstVideoCodecFrame * frame);
|
||||
|
||||
GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_set_keyframe_period (GstVaapiEncoder * encoder,
|
||||
guint keyframe_period);
|
||||
|
||||
GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_set_tuning (GstVaapiEncoder * encoder,
|
||||
GstVaapiEncoderTune tuning);
|
||||
|
||||
GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_set_quality_level (GstVaapiEncoder * encoder,
|
||||
guint quality_level);
|
||||
|
||||
GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_set_trellis (GstVaapiEncoder * encoder, gboolean trellis);
|
||||
|
||||
GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_get_buffer_with_timeout (GstVaapiEncoder * encoder,
|
||||
GstVaapiCodedBufferProxy ** out_codedbuf_proxy_ptr, guint64 timeout);
|
||||
|
||||
GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_flush (GstVaapiEncoder * encoder);
|
||||
|
||||
GArray *
|
||||
gst_vaapi_encoder_get_surface_attributes (GstVaapiEncoder * encoder,
|
||||
GArray * profiles, gint * min_width, gint * min_height,
|
||||
gint * max_width, gint * max_height, guint * mem_types);
|
||||
|
||||
GstVaapiProfile
|
||||
gst_vaapi_encoder_get_profile (GstVaapiEncoder * encoder);
|
||||
|
||||
GstVaapiEntrypoint
|
||||
gst_vaapi_encoder_get_entrypoint (GstVaapiEncoder * encoder,
|
||||
GstVaapiProfile profile);
|
||||
|
||||
GArray *
|
||||
gst_vaapi_encoder_get_available_profiles (GstVaapiEncoder * encoder);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiEncoder, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_ENCODER_H */
|
4166
gst-libs/gst/vaapi/gstvaapiencoder_h264.c
Normal file
4166
gst-libs/gst/vaapi/gstvaapiencoder_h264.c
Normal file
File diff suppressed because it is too large
Load diff
63
gst-libs/gst/vaapi/gstvaapiencoder_h264.h
Normal file
63
gst-libs/gst/vaapi/gstvaapiencoder_h264.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* gstvaapiencoder_h264.h - H.264 encoder
|
||||
*
|
||||
* Copyright (C) 2011-2014 Intel Corporation
|
||||
* Author: Wind Yuan <feng.yuan@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_ENCODER_H264_H
|
||||
#define GST_VAAPI_ENCODER_H264_H
|
||||
|
||||
#include <gst/vaapi/gstvaapiencoder.h>
|
||||
#include <gst/vaapi/gstvaapiutils_h264.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_ENCODER_H264 \
|
||||
(gst_vaapi_encoder_h264_get_type ())
|
||||
#define GST_VAAPI_ENCODER_H264(encoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((encoder), GST_TYPE_VAAPI_ENCODER_H264, GstVaapiEncoderH264))
|
||||
#define GST_IS_VAAPI_ENCODER_H264(encoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((encoder), GST_TYPE_VAAPI_ENCODER_H264))
|
||||
|
||||
typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264;
|
||||
typedef struct _GstVaapiEncoderH264Class GstVaapiEncoderH264Class;
|
||||
|
||||
GType
|
||||
gst_vaapi_encoder_h264_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GstVaapiEncoder *
|
||||
gst_vaapi_encoder_h264_new (GstVaapiDisplay * display);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_encoder_h264_set_max_profile (GstVaapiEncoderH264 * encoder,
|
||||
GstVaapiProfile profile);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_encoder_h264_get_profile_and_level (GstVaapiEncoderH264 * encoder,
|
||||
GstVaapiProfile * out_profile_ptr, GstVaapiLevelH264 * out_level_ptr);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_encoder_h264_supports_avc (GstVaapiEncoderH264 * encoder);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiEncoderH264, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /*GST_VAAPI_ENCODER_H264_H */
|
4004
gst-libs/gst/vaapi/gstvaapiencoder_h265.c
Normal file
4004
gst-libs/gst/vaapi/gstvaapiencoder_h265.c
Normal file
File diff suppressed because it is too large
Load diff
59
gst-libs/gst/vaapi/gstvaapiencoder_h265.h
Normal file
59
gst-libs/gst/vaapi/gstvaapiencoder_h265.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* gstvaapiencoder_h265.h - H.265 encoder
|
||||
*
|
||||
* Copyright (C) 2015 Intel Corporation
|
||||
* Author: Sreerenj Balachandran <sreerenj.balachandran@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_ENCODER_H265_H
|
||||
#define GST_VAAPI_ENCODER_H265_H
|
||||
|
||||
#include <gst/vaapi/gstvaapiencoder.h>
|
||||
#include <gst/vaapi/gstvaapiutils_h265.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_ENCODER_H265 \
|
||||
(gst_vaapi_encoder_h265_get_type ())
|
||||
#define GST_VAAPI_ENCODER_H265(encoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((encoder), GST_TYPE_VAAPI_ENCODER_H265, GstVaapiEncoderH265))
|
||||
#define GST_IS_VAAPI_ENCODER_H265(encoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((encoder), GST_TYPE_VAAPI_ENCODER_H265))
|
||||
|
||||
typedef struct _GstVaapiEncoderH265 GstVaapiEncoderH265;
|
||||
typedef struct _GstVaapiEncoderH265Class GstVaapiEncoderH265Class;
|
||||
|
||||
GType
|
||||
gst_vaapi_encoder_h265_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GstVaapiEncoder *
|
||||
gst_vaapi_encoder_h265_new (GstVaapiDisplay * display);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_encoder_h265_set_allowed_profiles (GstVaapiEncoderH265 * encoder,
|
||||
GArray * profiles);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_encoder_h265_get_profile_tier_level (GstVaapiEncoderH265 * encoder,
|
||||
GstVaapiProfile * out_profile_ptr, GstVaapiTierH265 *out_tier_ptr, GstVaapiLevelH265 * out_level_ptr);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiEncoderH265, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /*GST_VAAPI_ENCODER_H265_H */
|
914
gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c
Normal file
914
gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c
Normal file
|
@ -0,0 +1,914 @@
|
|||
/*
|
||||
* gstvaapiencoder_jpeg.c - JPEG encoder
|
||||
*
|
||||
* Copyright (C) 2015 Intel Corporation
|
||||
* Author: Sreerenj Balachandran <sreerenj.balachandran@intel.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; 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include <gst/base/gstbitwriter.h>
|
||||
#include <gst/codecparsers/gstjpegparser.h>
|
||||
#include "gstvaapicompat.h"
|
||||
#include "gstvaapiencoder_priv.h"
|
||||
#include "gstvaapiencoder_jpeg.h"
|
||||
#include "gstvaapicodedbufferproxy_priv.h"
|
||||
#include "gstvaapisurface.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
/* Define default rate control mode ("constant-qp") */
|
||||
#define DEFAULT_RATECONTROL GST_VAAPI_RATECONTROL_NONE
|
||||
|
||||
/* Supported set of VA rate controls, within this implementation */
|
||||
#define SUPPORTED_RATECONTROLS \
|
||||
(GST_VAAPI_RATECONTROL_MASK (NONE))
|
||||
|
||||
/* Supported set of tuning options, within this implementation */
|
||||
#define SUPPORTED_TUNE_OPTIONS \
|
||||
(GST_VAAPI_ENCODER_TUNE_MASK (NONE))
|
||||
|
||||
/* Supported set of VA packed headers, within this implementation */
|
||||
#define SUPPORTED_PACKED_HEADERS \
|
||||
(VA_ENC_PACKED_HEADER_RAW_DATA)
|
||||
|
||||
#define NUM_DC_RUN_SIZE_BITS 16
|
||||
#define NUM_AC_RUN_SIZE_BITS 16
|
||||
#define NUM_AC_CODE_WORDS_HUFFVAL 162
|
||||
#define NUM_DC_CODE_WORDS_HUFFVAL 12
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- JPEG Encoder --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
struct _GstVaapiEncoderJpeg
|
||||
{
|
||||
GstVaapiEncoder parent_instance;
|
||||
GstVaapiProfile profile;
|
||||
guint quality;
|
||||
GstJpegQuantTables quant_tables;
|
||||
GstJpegQuantTables scaled_quant_tables;
|
||||
gboolean has_quant_tables;
|
||||
GstJpegHuffmanTables huff_tables;
|
||||
gboolean has_huff_tables;
|
||||
gint cwidth[GST_VIDEO_MAX_COMPONENTS];
|
||||
gint cheight[GST_VIDEO_MAX_COMPONENTS];
|
||||
gint h_samp[GST_VIDEO_MAX_COMPONENTS];
|
||||
gint v_samp[GST_VIDEO_MAX_COMPONENTS];
|
||||
gint h_max_samp;
|
||||
gint v_max_samp;
|
||||
guint n_components;
|
||||
};
|
||||
|
||||
/* based on upstream gst-plugins-good jpegencoder */
|
||||
static void
|
||||
generate_sampling_factors (GstVaapiEncoderJpeg * encoder)
|
||||
{
|
||||
GstVideoInfo *vinfo;
|
||||
gint i;
|
||||
|
||||
vinfo = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
|
||||
|
||||
if (GST_VIDEO_INFO_FORMAT (vinfo) == GST_VIDEO_FORMAT_ENCODED) {
|
||||
/* Use native I420 format */
|
||||
encoder->n_components = 3;
|
||||
for (i = 0; i < encoder->n_components; ++i) {
|
||||
if (i == 0)
|
||||
encoder->h_samp[i] = encoder->v_samp[i] = 2;
|
||||
else
|
||||
encoder->h_samp[i] = encoder->v_samp[i] = 1;
|
||||
GST_DEBUG ("sampling factors: %d %d", encoder->h_samp[i],
|
||||
encoder->v_samp[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
encoder->n_components = GST_VIDEO_INFO_N_COMPONENTS (vinfo);
|
||||
|
||||
encoder->h_max_samp = 0;
|
||||
encoder->v_max_samp = 0;
|
||||
for (i = 0; i < encoder->n_components; ++i) {
|
||||
encoder->cwidth[i] = GST_VIDEO_INFO_COMP_WIDTH (vinfo, i);
|
||||
encoder->cheight[i] = GST_VIDEO_INFO_COMP_HEIGHT (vinfo, i);
|
||||
encoder->h_samp[i] =
|
||||
GST_ROUND_UP_4 (GST_VIDEO_INFO_WIDTH (vinfo)) / encoder->cwidth[i];
|
||||
encoder->h_max_samp = MAX (encoder->h_max_samp, encoder->h_samp[i]);
|
||||
encoder->v_samp[i] =
|
||||
GST_ROUND_UP_4 (GST_VIDEO_INFO_HEIGHT (vinfo)) / encoder->cheight[i];
|
||||
encoder->v_max_samp = MAX (encoder->v_max_samp, encoder->v_samp[i]);
|
||||
}
|
||||
/* samp should only be 1, 2 or 4 */
|
||||
g_assert (encoder->h_max_samp <= 4);
|
||||
g_assert (encoder->v_max_samp <= 4);
|
||||
|
||||
/* now invert */
|
||||
/* maximum is invariant, as one of the components should have samp 1 */
|
||||
for (i = 0; i < encoder->n_components; ++i) {
|
||||
encoder->h_samp[i] = encoder->h_max_samp / encoder->h_samp[i];
|
||||
encoder->v_samp[i] = encoder->v_max_samp / encoder->v_samp[i];
|
||||
GST_DEBUG ("sampling factors: %d %d", encoder->h_samp[i],
|
||||
encoder->v_samp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Derives the profile that suits best to the configuration */
|
||||
static GstVaapiEncoderStatus
|
||||
ensure_profile (GstVaapiEncoderJpeg * encoder)
|
||||
{
|
||||
/* Always start from "simple" profile for maximum compatibility */
|
||||
encoder->profile = GST_VAAPI_PROFILE_JPEG_BASELINE;
|
||||
|
||||
return GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Derives the profile supported by the underlying hardware */
|
||||
static gboolean
|
||||
ensure_hw_profile (GstVaapiEncoderJpeg * encoder)
|
||||
{
|
||||
GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
|
||||
GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE;
|
||||
GstVaapiProfile profile, profiles[2];
|
||||
guint i, num_profiles = 0;
|
||||
|
||||
profiles[num_profiles++] = encoder->profile;
|
||||
|
||||
profile = GST_VAAPI_PROFILE_UNKNOWN;
|
||||
for (i = 0; i < num_profiles; i++) {
|
||||
if (gst_vaapi_display_has_encoder (display, profiles[i], entrypoint)) {
|
||||
profile = profiles[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (profile == GST_VAAPI_PROFILE_UNKNOWN)
|
||||
goto error_unsupported_profile;
|
||||
|
||||
GST_VAAPI_ENCODER_CAST (encoder)->profile = profile;
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
error_unsupported_profile:
|
||||
{
|
||||
GST_ERROR ("unsupported HW profile %s",
|
||||
gst_vaapi_profile_get_va_name (encoder->profile));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static GstVaapiEncoderStatus
|
||||
set_context_info (GstVaapiEncoder * base_encoder)
|
||||
{
|
||||
GstVaapiEncoderJpeg *encoder = GST_VAAPI_ENCODER_JPEG (base_encoder);
|
||||
GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
|
||||
|
||||
/* Maximum sizes for common headers (in bytes) */
|
||||
enum
|
||||
{
|
||||
MAX_APP_HDR_SIZE = 20,
|
||||
MAX_FRAME_HDR_SIZE = 19,
|
||||
MAX_QUANT_TABLE_SIZE = 138,
|
||||
MAX_HUFFMAN_TABLE_SIZE = 432,
|
||||
MAX_SCAN_HDR_SIZE = 14
|
||||
};
|
||||
|
||||
if (!ensure_hw_profile (encoder))
|
||||
return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
|
||||
|
||||
base_encoder->num_ref_frames = 0;
|
||||
|
||||
/* Only YUV 4:2:0 formats are supported for now. */
|
||||
base_encoder->codedbuf_size = GST_ROUND_UP_16 (vip->width) *
|
||||
GST_ROUND_UP_16 (vip->height) * 3 / 2;
|
||||
|
||||
base_encoder->codedbuf_size += MAX_APP_HDR_SIZE + MAX_FRAME_HDR_SIZE +
|
||||
MAX_QUANT_TABLE_SIZE + MAX_HUFFMAN_TABLE_SIZE + MAX_SCAN_HDR_SIZE;
|
||||
|
||||
base_encoder->context_info.profile = base_encoder->profile;
|
||||
base_encoder->context_info.entrypoint = GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE;
|
||||
|
||||
return GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fill_picture (GstVaapiEncoderJpeg * encoder,
|
||||
GstVaapiEncPicture * picture,
|
||||
GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
|
||||
{
|
||||
guint i;
|
||||
VAEncPictureParameterBufferJPEG *const pic_param = picture->param;
|
||||
|
||||
memset (pic_param, 0, sizeof (VAEncPictureParameterBufferJPEG));
|
||||
|
||||
pic_param->reconstructed_picture =
|
||||
GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
|
||||
pic_param->picture_width = GST_VAAPI_ENCODER_WIDTH (encoder);
|
||||
pic_param->picture_height = GST_VAAPI_ENCODER_HEIGHT (encoder);
|
||||
pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf);
|
||||
|
||||
pic_param->pic_flags.bits.profile = 0; /* Profile = Baseline */
|
||||
pic_param->pic_flags.bits.progressive = 0; /* Sequential encoding */
|
||||
pic_param->pic_flags.bits.huffman = 1; /* Uses Huffman coding */
|
||||
pic_param->pic_flags.bits.interleaved = 0; /* Input format is non interleaved (YUV) */
|
||||
pic_param->pic_flags.bits.differential = 0; /* non-Differential Encoding */
|
||||
pic_param->sample_bit_depth = 8;
|
||||
pic_param->num_scan = 1;
|
||||
pic_param->num_components = encoder->n_components;
|
||||
pic_param->quality = encoder->quality;
|
||||
for (i = 0; i < pic_param->num_components; i++) {
|
||||
pic_param->component_id[i] = i + 1;
|
||||
if (i != 0)
|
||||
pic_param->quantiser_table_selector[i] = 1;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_picture (GstVaapiEncoderJpeg * encoder, GstVaapiEncPicture * picture,
|
||||
GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
|
||||
{
|
||||
GstVaapiCodedBuffer *const codedbuf =
|
||||
GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
|
||||
|
||||
if (!fill_picture (encoder, picture, codedbuf, surface))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* This is a work-around: Normalize the quality factor and scale QM
|
||||
* values similar to what VA-Intel driver is doing. Otherwise the
|
||||
* generated packed headers will be wrong, since the driver itself
|
||||
* is scaling the QM values using the normalized quality factor */
|
||||
static void
|
||||
generate_scaled_qm (GstJpegQuantTables * quant_tables,
|
||||
GstJpegQuantTables * scaled_quant_tables, guint quality, guint shift)
|
||||
{
|
||||
guint qt_val, nm_quality, i;
|
||||
nm_quality = quality == 0 ? 1 : quality;
|
||||
nm_quality =
|
||||
(nm_quality < 50) ? (5000 / nm_quality) : (200 - (nm_quality * 2));
|
||||
|
||||
g_assert (quant_tables != NULL);
|
||||
g_assert (scaled_quant_tables != NULL);
|
||||
|
||||
for (i = 0; i < GST_JPEG_MAX_QUANT_ELEMENTS; i++) {
|
||||
/* Luma QM */
|
||||
qt_val =
|
||||
(quant_tables->quant_tables[0].quant_table[i] * nm_quality +
|
||||
shift) / 100;
|
||||
scaled_quant_tables->quant_tables[0].quant_table[i] =
|
||||
CLAMP (qt_val, 1, 255);
|
||||
/* Chroma QM */
|
||||
qt_val =
|
||||
(quant_tables->quant_tables[1].quant_table[i] * nm_quality +
|
||||
shift) / 100;
|
||||
scaled_quant_tables->quant_tables[1].quant_table[i] =
|
||||
CLAMP (qt_val, 1, 255);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fill_quantization_table (GstVaapiEncoderJpeg * encoder,
|
||||
GstVaapiEncPicture * picture)
|
||||
{
|
||||
VAQMatrixBufferJPEG *q_matrix;
|
||||
int i;
|
||||
|
||||
g_assert (picture);
|
||||
|
||||
picture->q_matrix = GST_VAAPI_ENC_Q_MATRIX_NEW (JPEG, encoder);
|
||||
if (!picture->q_matrix) {
|
||||
GST_ERROR ("failed to allocate quantiser table");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
q_matrix = picture->q_matrix->param;
|
||||
|
||||
if (!encoder->has_quant_tables) {
|
||||
GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
|
||||
guint shift = 0;
|
||||
|
||||
if (gst_vaapi_display_has_driver_quirks (display,
|
||||
GST_VAAPI_DRIVER_QUIRK_JPEG_ENC_SHIFT_VALUE_BY_50))
|
||||
shift = 50;
|
||||
|
||||
gst_jpeg_get_default_quantization_tables (&encoder->quant_tables);
|
||||
encoder->has_quant_tables = TRUE;
|
||||
generate_scaled_qm (&encoder->quant_tables, &encoder->scaled_quant_tables,
|
||||
encoder->quality, shift);
|
||||
}
|
||||
q_matrix->load_lum_quantiser_matrix = 1;
|
||||
for (i = 0; i < GST_JPEG_MAX_QUANT_ELEMENTS; i++) {
|
||||
q_matrix->lum_quantiser_matrix[i] =
|
||||
encoder->quant_tables.quant_tables[0].quant_table[i];
|
||||
}
|
||||
|
||||
q_matrix->load_chroma_quantiser_matrix = 1;
|
||||
for (i = 0; i < GST_JPEG_MAX_QUANT_ELEMENTS; i++) {
|
||||
q_matrix->chroma_quantiser_matrix[i] =
|
||||
encoder->quant_tables.quant_tables[1].quant_table[i];
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_quantization_table (GstVaapiEncoderJpeg * encoder,
|
||||
GstVaapiEncPicture * picture)
|
||||
{
|
||||
g_assert (picture);
|
||||
|
||||
if (!fill_quantization_table (encoder, picture))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fill_huffman_table (GstVaapiEncoderJpeg * encoder, GstVaapiEncPicture * picture)
|
||||
{
|
||||
VAHuffmanTableBufferJPEGBaseline *huffman_table;
|
||||
guint i, num_tables;
|
||||
|
||||
g_assert (picture);
|
||||
|
||||
picture->huf_table = GST_VAAPI_ENC_HUFFMAN_TABLE_NEW (JPEGBaseline, encoder);
|
||||
if (!picture->huf_table) {
|
||||
GST_ERROR ("failed to allocate Huffman tables");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
huffman_table = picture->huf_table->param;
|
||||
|
||||
num_tables = MIN (G_N_ELEMENTS (huffman_table->huffman_table),
|
||||
GST_JPEG_MAX_SCAN_COMPONENTS);
|
||||
|
||||
if (!encoder->has_huff_tables) {
|
||||
gst_jpeg_get_default_huffman_tables (&encoder->huff_tables);
|
||||
encoder->has_huff_tables = TRUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_tables; i++) {
|
||||
huffman_table->load_huffman_table[i] =
|
||||
encoder->huff_tables.dc_tables[i].valid
|
||||
&& encoder->huff_tables.ac_tables[i].valid;
|
||||
if (!huffman_table->load_huffman_table[i])
|
||||
continue;
|
||||
|
||||
memcpy (huffman_table->huffman_table[i].num_dc_codes,
|
||||
encoder->huff_tables.dc_tables[i].huf_bits,
|
||||
sizeof (huffman_table->huffman_table[i].num_dc_codes));
|
||||
memcpy (huffman_table->huffman_table[i].dc_values,
|
||||
encoder->huff_tables.dc_tables[i].huf_values,
|
||||
sizeof (huffman_table->huffman_table[i].dc_values));
|
||||
memcpy (huffman_table->huffman_table[i].num_ac_codes,
|
||||
encoder->huff_tables.ac_tables[i].huf_bits,
|
||||
sizeof (huffman_table->huffman_table[i].num_ac_codes));
|
||||
memcpy (huffman_table->huffman_table[i].ac_values,
|
||||
encoder->huff_tables.ac_tables[i].huf_values,
|
||||
sizeof (huffman_table->huffman_table[i].ac_values));
|
||||
memset (huffman_table->huffman_table[i].pad,
|
||||
0, sizeof (huffman_table->huffman_table[i].pad));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_huffman_table (GstVaapiEncoderJpeg * encoder,
|
||||
GstVaapiEncPicture * picture)
|
||||
{
|
||||
g_assert (picture);
|
||||
|
||||
if (!fill_huffman_table (encoder, picture))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fill_slices (GstVaapiEncoderJpeg * encoder, GstVaapiEncPicture * picture)
|
||||
{
|
||||
VAEncSliceParameterBufferJPEG *slice_param;
|
||||
GstVaapiEncSlice *slice;
|
||||
VAEncPictureParameterBufferJPEG *const pic_param = picture->param;
|
||||
|
||||
slice = GST_VAAPI_ENC_SLICE_NEW (JPEG, encoder);
|
||||
g_assert (slice && slice->param_id != VA_INVALID_ID);
|
||||
slice_param = slice->param;
|
||||
|
||||
memset (slice_param, 0, sizeof (VAEncSliceParameterBufferJPEG));
|
||||
|
||||
slice_param->restart_interval = 0;
|
||||
slice_param->num_components = pic_param->num_components;
|
||||
|
||||
slice_param->components[0].component_selector = 1;
|
||||
slice_param->components[0].dc_table_selector = 0;
|
||||
slice_param->components[0].ac_table_selector = 0;
|
||||
|
||||
slice_param->components[1].component_selector = 2;
|
||||
slice_param->components[1].dc_table_selector = 1;
|
||||
slice_param->components[1].ac_table_selector = 1;
|
||||
|
||||
slice_param->components[2].component_selector = 3;
|
||||
slice_param->components[2].dc_table_selector = 1;
|
||||
slice_param->components[2].ac_table_selector = 1;
|
||||
|
||||
gst_vaapi_enc_picture_add_slice (picture, slice);
|
||||
gst_vaapi_codec_object_replace (&slice, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_slices (GstVaapiEncoderJpeg * encoder, GstVaapiEncPicture * picture)
|
||||
{
|
||||
g_assert (picture);
|
||||
|
||||
if (!fill_slices (encoder, picture))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
generate_frame_hdr (GstJpegFrameHdr * frame_hdr, GstVaapiEncoderJpeg * encoder,
|
||||
GstVaapiEncPicture * picture)
|
||||
{
|
||||
VAEncPictureParameterBufferJPEG *const pic_param = picture->param;
|
||||
guint i;
|
||||
|
||||
memset (frame_hdr, 0, sizeof (GstJpegFrameHdr));
|
||||
frame_hdr->sample_precision = 8;
|
||||
frame_hdr->width = pic_param->picture_width;
|
||||
frame_hdr->height = pic_param->picture_height;
|
||||
frame_hdr->num_components = pic_param->num_components;
|
||||
|
||||
for (i = 0; i < frame_hdr->num_components; i++) {
|
||||
frame_hdr->components[i].identifier = pic_param->component_id[i];
|
||||
frame_hdr->components[i].horizontal_factor = encoder->h_samp[i];
|
||||
frame_hdr->components[i].vertical_factor = encoder->v_samp[i];
|
||||
frame_hdr->components[i].quant_table_selector =
|
||||
pic_param->quantiser_table_selector[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
generate_scan_hdr (GstJpegScanHdr * scan_hdr, GstVaapiEncPicture * picture)
|
||||
{
|
||||
|
||||
VAEncPictureParameterBufferJPEG *const pic_param = picture->param;
|
||||
|
||||
memset (scan_hdr, 0, sizeof (GstJpegScanHdr));
|
||||
scan_hdr->num_components = pic_param->num_components;
|
||||
//Y Component
|
||||
scan_hdr->components[0].component_selector = 1;
|
||||
scan_hdr->components[0].dc_selector = 0;
|
||||
scan_hdr->components[0].ac_selector = 0;
|
||||
|
||||
|
||||
//U Component
|
||||
scan_hdr->components[1].component_selector = 2;
|
||||
scan_hdr->components[1].dc_selector = 1;
|
||||
scan_hdr->components[1].ac_selector = 1;
|
||||
|
||||
//V Component
|
||||
scan_hdr->components[2].component_selector = 3;
|
||||
scan_hdr->components[2].dc_selector = 1;
|
||||
scan_hdr->components[2].ac_selector = 1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
bs_write_jpeg_header (GstBitWriter * bs, GstVaapiEncoderJpeg * encoder,
|
||||
GstVaapiEncPicture * picture)
|
||||
{
|
||||
GstJpegFrameHdr frame_hdr;
|
||||
GstJpegScanHdr scan_hdr;
|
||||
guint i, j;
|
||||
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0xFF, 8);
|
||||
gst_bit_writer_put_bits_uint8 (bs, GST_JPEG_MARKER_SOI, 8);
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0xFF, 8);
|
||||
gst_bit_writer_put_bits_uint8 (bs, GST_JPEG_MARKER_APP_MIN, 8);
|
||||
gst_bit_writer_put_bits_uint16 (bs, 16, 16);
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0x4A, 8); //J
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0x46, 8); //F
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0x49, 8); //I
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0x46, 8); //F
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0x00, 8); //0
|
||||
gst_bit_writer_put_bits_uint8 (bs, 1, 8); //Major Version
|
||||
gst_bit_writer_put_bits_uint8 (bs, 1, 8); //Minor Version
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0, 8); //Density units 0:no units, 1:pixels per inch, 2: pixels per cm
|
||||
gst_bit_writer_put_bits_uint16 (bs, 1, 16); //X density (pixel-aspect-ratio)
|
||||
gst_bit_writer_put_bits_uint16 (bs, 1, 16); //Y density (pixel-aspect-ratio)
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0, 8); //Thumbnail width
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0, 8); //Thumbnail height
|
||||
|
||||
/* Add quantization table */
|
||||
if (!encoder->has_quant_tables) {
|
||||
GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
|
||||
guint shift = 0;
|
||||
|
||||
if (gst_vaapi_display_has_driver_quirks (display,
|
||||
GST_VAAPI_DRIVER_QUIRK_JPEG_ENC_SHIFT_VALUE_BY_50))
|
||||
shift = 50;
|
||||
|
||||
gst_jpeg_get_default_quantization_tables (&encoder->quant_tables);
|
||||
generate_scaled_qm (&encoder->quant_tables, &encoder->scaled_quant_tables,
|
||||
encoder->quality, shift);
|
||||
encoder->has_quant_tables = TRUE;
|
||||
}
|
||||
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0xFF, 8);
|
||||
gst_bit_writer_put_bits_uint8 (bs, GST_JPEG_MARKER_DQT, 8);
|
||||
gst_bit_writer_put_bits_uint16 (bs, 3 + GST_JPEG_MAX_QUANT_ELEMENTS, 16); //Lq
|
||||
gst_bit_writer_put_bits_uint8 (bs, encoder->quant_tables.quant_tables[0].quant_precision, 4); //Pq
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0, 4); //Tq
|
||||
for (i = 0; i < GST_JPEG_MAX_QUANT_ELEMENTS; i++) {
|
||||
gst_bit_writer_put_bits_uint16 (bs,
|
||||
encoder->scaled_quant_tables.quant_tables[0].quant_table[i], 8);
|
||||
}
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0xFF, 8);
|
||||
gst_bit_writer_put_bits_uint8 (bs, GST_JPEG_MARKER_DQT, 8);
|
||||
gst_bit_writer_put_bits_uint16 (bs, 3 + GST_JPEG_MAX_QUANT_ELEMENTS, 16); //Lq
|
||||
gst_bit_writer_put_bits_uint8 (bs, encoder->quant_tables.quant_tables[1].quant_precision, 4); //Pq
|
||||
gst_bit_writer_put_bits_uint8 (bs, 1, 4); //Tq
|
||||
for (i = 0; i < GST_JPEG_MAX_QUANT_ELEMENTS; i++) {
|
||||
gst_bit_writer_put_bits_uint16 (bs,
|
||||
encoder->scaled_quant_tables.quant_tables[1].quant_table[i], 8);
|
||||
}
|
||||
|
||||
/*Add frame header */
|
||||
generate_frame_hdr (&frame_hdr, encoder, picture);
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0xFF, 8);
|
||||
gst_bit_writer_put_bits_uint8 (bs, GST_JPEG_MARKER_SOF_MIN, 8);
|
||||
gst_bit_writer_put_bits_uint16 (bs, 8 + (3 * 3), 16); //lf, Size of FrameHeader in bytes without the Marker SOF
|
||||
gst_bit_writer_put_bits_uint8 (bs, frame_hdr.sample_precision, 8);
|
||||
gst_bit_writer_put_bits_uint16 (bs, frame_hdr.height, 16);
|
||||
gst_bit_writer_put_bits_uint16 (bs, frame_hdr.width, 16);
|
||||
gst_bit_writer_put_bits_uint8 (bs, frame_hdr.num_components, 8);
|
||||
for (i = 0; i < frame_hdr.num_components; i++) {
|
||||
gst_bit_writer_put_bits_uint8 (bs, frame_hdr.components[i].identifier, 8);
|
||||
gst_bit_writer_put_bits_uint8 (bs,
|
||||
frame_hdr.components[i].horizontal_factor, 4);
|
||||
gst_bit_writer_put_bits_uint8 (bs, frame_hdr.components[i].vertical_factor,
|
||||
4);
|
||||
gst_bit_writer_put_bits_uint8 (bs,
|
||||
frame_hdr.components[i].quant_table_selector, 8);
|
||||
}
|
||||
|
||||
/* Add Huffman table */
|
||||
if (!encoder->has_huff_tables) {
|
||||
gst_jpeg_get_default_huffman_tables (&encoder->huff_tables);
|
||||
encoder->has_huff_tables = TRUE;
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0xFF, 8);
|
||||
gst_bit_writer_put_bits_uint8 (bs, GST_JPEG_MARKER_DHT, 8);
|
||||
gst_bit_writer_put_bits_uint16 (bs, 0x1F, 16); //length of table
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0, 4);
|
||||
gst_bit_writer_put_bits_uint8 (bs, i, 4);
|
||||
for (j = 0; j < NUM_DC_RUN_SIZE_BITS; j++) {
|
||||
gst_bit_writer_put_bits_uint8 (bs,
|
||||
encoder->huff_tables.dc_tables[i].huf_bits[j], 8);
|
||||
}
|
||||
|
||||
for (j = 0; j < NUM_DC_CODE_WORDS_HUFFVAL; j++) {
|
||||
gst_bit_writer_put_bits_uint8 (bs,
|
||||
encoder->huff_tables.dc_tables[i].huf_values[j], 8);
|
||||
}
|
||||
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0xFF, 8);
|
||||
gst_bit_writer_put_bits_uint8 (bs, GST_JPEG_MARKER_DHT, 8);
|
||||
gst_bit_writer_put_bits_uint16 (bs, 0xB5, 16); //length of table
|
||||
gst_bit_writer_put_bits_uint8 (bs, 1, 4);
|
||||
gst_bit_writer_put_bits_uint8 (bs, i, 4);
|
||||
for (j = 0; j < NUM_AC_RUN_SIZE_BITS; j++) {
|
||||
gst_bit_writer_put_bits_uint8 (bs,
|
||||
encoder->huff_tables.ac_tables[i].huf_bits[j], 8);
|
||||
}
|
||||
|
||||
for (j = 0; j < NUM_AC_CODE_WORDS_HUFFVAL; j++) {
|
||||
gst_bit_writer_put_bits_uint8 (bs,
|
||||
encoder->huff_tables.ac_tables[i].huf_values[j], 8);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add ScanHeader */
|
||||
generate_scan_hdr (&scan_hdr, picture);
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0xFF, 8);
|
||||
gst_bit_writer_put_bits_uint8 (bs, GST_JPEG_MARKER_SOS, 8);
|
||||
gst_bit_writer_put_bits_uint16 (bs, 12, 16); //Length of Scan
|
||||
gst_bit_writer_put_bits_uint8 (bs, scan_hdr.num_components, 8);
|
||||
|
||||
for (i = 0; i < scan_hdr.num_components; i++) {
|
||||
gst_bit_writer_put_bits_uint8 (bs,
|
||||
scan_hdr.components[i].component_selector, 8);
|
||||
gst_bit_writer_put_bits_uint8 (bs, scan_hdr.components[i].dc_selector, 4);
|
||||
gst_bit_writer_put_bits_uint8 (bs, scan_hdr.components[i].ac_selector, 4);
|
||||
}
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0, 8); //0 for Baseline
|
||||
gst_bit_writer_put_bits_uint8 (bs, 63, 8); //63 for Baseline
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0, 4); //0 for Baseline
|
||||
gst_bit_writer_put_bits_uint8 (bs, 0, 4); //0 for Baseline
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
add_packed_header (GstVaapiEncoderJpeg * encoder, GstVaapiEncPicture * picture)
|
||||
{
|
||||
GstVaapiEncPackedHeader *packed_raw_data_hdr;
|
||||
GstBitWriter bs;
|
||||
VAEncPackedHeaderParameterBuffer packed_raw_data_hdr_param = { 0 };
|
||||
guint32 data_bit_size;
|
||||
guint8 *data;
|
||||
|
||||
gst_bit_writer_init_with_size (&bs, 128, FALSE);
|
||||
bs_write_jpeg_header (&bs, encoder, picture);
|
||||
data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
|
||||
data = GST_BIT_WRITER_DATA (&bs);
|
||||
|
||||
packed_raw_data_hdr_param.type = VAEncPackedHeaderRawData;
|
||||
packed_raw_data_hdr_param.bit_length = data_bit_size;
|
||||
packed_raw_data_hdr_param.has_emulation_bytes = 0;
|
||||
|
||||
packed_raw_data_hdr =
|
||||
gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
|
||||
&packed_raw_data_hdr_param, sizeof (packed_raw_data_hdr_param), data,
|
||||
(data_bit_size + 7) / 8);
|
||||
g_assert (packed_raw_data_hdr);
|
||||
|
||||
gst_vaapi_enc_picture_add_packed_header (picture, packed_raw_data_hdr);
|
||||
gst_vaapi_codec_object_replace (&packed_raw_data_hdr, NULL);
|
||||
|
||||
gst_bit_writer_reset (&bs);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_packed_headers (GstVaapiEncoderJpeg * encoder,
|
||||
GstVaapiEncPicture * picture)
|
||||
{
|
||||
g_assert (picture);
|
||||
|
||||
if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
|
||||
VA_ENC_PACKED_HEADER_RAW_DATA)
|
||||
&& !add_packed_header (encoder, picture))
|
||||
goto error_create_packed_hdr;
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
error_create_packed_hdr:
|
||||
{
|
||||
GST_ERROR ("failed to create packed raw data header buffer");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_jpeg_encode (GstVaapiEncoder * base_encoder,
|
||||
GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
|
||||
{
|
||||
GstVaapiEncoderJpeg *const encoder = GST_VAAPI_ENCODER_JPEG (base_encoder);
|
||||
GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
|
||||
GstVaapiSurfaceProxy *reconstruct = NULL;
|
||||
|
||||
reconstruct = gst_vaapi_encoder_create_surface (base_encoder);
|
||||
|
||||
g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
|
||||
|
||||
if (!ensure_picture (encoder, picture, codedbuf, reconstruct))
|
||||
goto error;
|
||||
if (!ensure_quantization_table (encoder, picture))
|
||||
goto error;
|
||||
if (!ensure_huffman_table (encoder, picture))
|
||||
goto error;
|
||||
if (!ensure_slices (encoder, picture))
|
||||
goto error;
|
||||
if (!ensure_packed_headers (encoder, picture))
|
||||
goto error;
|
||||
if (!gst_vaapi_enc_picture_encode (picture))
|
||||
goto error;
|
||||
if (reconstruct)
|
||||
gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
|
||||
reconstruct);
|
||||
|
||||
return GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
|
||||
/* ERRORS */
|
||||
error:
|
||||
{
|
||||
if (reconstruct)
|
||||
gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
|
||||
reconstruct);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
static GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_jpeg_flush (GstVaapiEncoder * base_encoder)
|
||||
{
|
||||
return GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_jpeg_reordering (GstVaapiEncoder * base_encoder,
|
||||
GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
|
||||
{
|
||||
GstVaapiEncoderJpeg *const encoder = GST_VAAPI_ENCODER_JPEG (base_encoder);
|
||||
GstVaapiEncPicture *picture = NULL;
|
||||
GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
|
||||
if (!frame)
|
||||
return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
|
||||
|
||||
picture = GST_VAAPI_ENC_PICTURE_NEW (JPEG, encoder, frame);
|
||||
if (!picture) {
|
||||
GST_WARNING ("create JPEG picture failed, frame timestamp:%"
|
||||
GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
|
||||
return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
|
||||
*output = picture;
|
||||
return status;
|
||||
}
|
||||
|
||||
static GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_jpeg_reconfigure (GstVaapiEncoder * base_encoder)
|
||||
{
|
||||
GstVaapiEncoderJpeg *const encoder = GST_VAAPI_ENCODER_JPEG (base_encoder);
|
||||
GstVaapiEncoderStatus status;
|
||||
|
||||
status = ensure_profile (encoder);
|
||||
if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
/* generate sampling factors (A.1.1) */
|
||||
generate_sampling_factors (encoder);
|
||||
|
||||
return set_context_info (base_encoder);
|
||||
}
|
||||
|
||||
struct _GstVaapiEncoderJpegClass
|
||||
{
|
||||
GstVaapiEncoderClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GstVaapiEncoderJpeg, gst_vaapi_encoder_jpeg,
|
||||
GST_TYPE_VAAPI_ENCODER);
|
||||
|
||||
static void
|
||||
gst_vaapi_encoder_jpeg_init (GstVaapiEncoderJpeg * encoder)
|
||||
{
|
||||
encoder->has_quant_tables = FALSE;
|
||||
memset (&encoder->quant_tables, 0, sizeof (encoder->quant_tables));
|
||||
memset (&encoder->scaled_quant_tables, 0,
|
||||
sizeof (encoder->scaled_quant_tables));
|
||||
encoder->has_huff_tables = FALSE;
|
||||
memset (&encoder->huff_tables, 0, sizeof (encoder->huff_tables));
|
||||
}
|
||||
|
||||
/**
|
||||
* @ENCODER_JPEG_PROP_RATECONTROL: Rate control (#GstVaapiRateControl).
|
||||
* @ENCODER_JPEG_PROP_TUNE: The tuning options (#GstVaapiEncoderTune).
|
||||
* @ENCODER_JPEG_PROP_QUALITY: Quality Factor value (uint).
|
||||
*
|
||||
* The set of JPEG encoder specific configurable properties.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
ENCODER_JPEG_PROP_RATECONTROL = 1,
|
||||
ENCODER_JPEG_PROP_TUNE,
|
||||
ENCODER_JPEG_PROP_QUALITY,
|
||||
ENCODER_JPEG_N_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[ENCODER_JPEG_N_PROPERTIES];
|
||||
|
||||
static void
|
||||
gst_vaapi_encoder_jpeg_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object);
|
||||
GstVaapiEncoderJpeg *const encoder = GST_VAAPI_ENCODER_JPEG (object);
|
||||
|
||||
if (base_encoder->num_codedbuf_queued > 0) {
|
||||
GST_ERROR_OBJECT (object,
|
||||
"failed to set any property after encoding started");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (prop_id) {
|
||||
case ENCODER_JPEG_PROP_RATECONTROL:
|
||||
gst_vaapi_encoder_set_rate_control (base_encoder,
|
||||
g_value_get_enum (value));
|
||||
break;
|
||||
case ENCODER_JPEG_PROP_TUNE:
|
||||
gst_vaapi_encoder_set_tuning (base_encoder, g_value_get_enum (value));
|
||||
break;
|
||||
case ENCODER_JPEG_PROP_QUALITY:
|
||||
encoder->quality = g_value_get_uint (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_encoder_jpeg_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstVaapiEncoderJpeg *const encoder = GST_VAAPI_ENCODER_JPEG (object);
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ENCODER_JPEG_PROP_RATECONTROL:
|
||||
g_value_set_enum (value, base_encoder->rate_control);
|
||||
break;
|
||||
case ENCODER_JPEG_PROP_TUNE:
|
||||
g_value_set_enum (value, base_encoder->tune);
|
||||
break;
|
||||
case ENCODER_JPEG_PROP_QUALITY:
|
||||
g_value_set_uint (value, encoder->quality);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (JPEG);
|
||||
|
||||
static void
|
||||
gst_vaapi_encoder_jpeg_class_init (GstVaapiEncoderJpegClass * klass)
|
||||
{
|
||||
GObjectClass *const object_class = G_OBJECT_CLASS (klass);
|
||||
GstVaapiEncoderClass *const encoder_class = GST_VAAPI_ENCODER_CLASS (klass);
|
||||
|
||||
encoder_class->class_data = &g_class_data;
|
||||
encoder_class->reconfigure = gst_vaapi_encoder_jpeg_reconfigure;
|
||||
encoder_class->reordering = gst_vaapi_encoder_jpeg_reordering;
|
||||
encoder_class->encode = gst_vaapi_encoder_jpeg_encode;
|
||||
encoder_class->flush = gst_vaapi_encoder_jpeg_flush;
|
||||
|
||||
object_class->set_property = gst_vaapi_encoder_jpeg_set_property;
|
||||
object_class->get_property = gst_vaapi_encoder_jpeg_get_property;
|
||||
|
||||
properties[ENCODER_JPEG_PROP_RATECONTROL] =
|
||||
g_param_spec_enum ("rate-control",
|
||||
"Rate Control", "Rate control mode",
|
||||
g_class_data.rate_control_get_type (),
|
||||
g_class_data.default_rate_control,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
|
||||
GST_VAAPI_PARAM_ENCODER_EXPOSURE);
|
||||
|
||||
properties[ENCODER_JPEG_PROP_TUNE] =
|
||||
g_param_spec_enum ("tune",
|
||||
"Encoder Tuning",
|
||||
"Encoder tuning option",
|
||||
g_class_data.encoder_tune_get_type (),
|
||||
g_class_data.default_encoder_tune,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
|
||||
GST_VAAPI_PARAM_ENCODER_EXPOSURE);
|
||||
|
||||
properties[ENCODER_JPEG_PROP_QUALITY] =
|
||||
g_param_spec_uint ("quality",
|
||||
"Quality factor",
|
||||
"Quality factor", 0, 100, 50,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
|
||||
GST_VAAPI_PARAM_ENCODER_EXPOSURE);
|
||||
|
||||
g_object_class_install_properties (object_class, ENCODER_JPEG_N_PROPERTIES,
|
||||
properties);
|
||||
|
||||
gst_type_mark_as_plugin_api (g_class_data.rate_control_get_type (), 0);
|
||||
gst_type_mark_as_plugin_api (g_class_data.encoder_tune_get_type (), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_encoder_jpeg_new:
|
||||
* @display: a #GstVaapiDisplay
|
||||
*
|
||||
* Creates a new #GstVaapiEncoder for JPEG encoding.
|
||||
*
|
||||
* Return value: the newly allocated #GstVaapiEncoder object
|
||||
*/
|
||||
GstVaapiEncoder *
|
||||
gst_vaapi_encoder_jpeg_new (GstVaapiDisplay * display)
|
||||
{
|
||||
return g_object_new (GST_TYPE_VAAPI_ENCODER_JPEG, "display", display, NULL);
|
||||
}
|
50
gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h
Normal file
50
gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* gstvaapiencoder_jpeg.h JPEGG encoder
|
||||
*
|
||||
* Copyright (C) 2015 Intel Corporation
|
||||
* Author: Sreerenj Balachandran <sreerenj.balachandran@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_ENCODER_JPEG_H
|
||||
#define GST_VAAPI_ENCODER_JPEG_H
|
||||
|
||||
#include <gst/vaapi/gstvaapiencoder.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_ENCODER_JPEG \
|
||||
(gst_vaapi_encoder_jpeg_get_type ())
|
||||
#define GST_VAAPI_ENCODER_JPEG(encoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((encoder), GST_TYPE_VAAPI_ENCODER_JPEG, GstVaapiEncoderJpeg))
|
||||
#define GST_IS_VAAPI_ENCODER_JPEG(encoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((encoder), GST_TYPE_VAAPI_ENCODER_JPEG))
|
||||
|
||||
typedef struct _GstVaapiEncoderJpeg GstVaapiEncoderJpeg;
|
||||
typedef struct _GstVaapiEncoderJpegClass GstVaapiEncoderJpegClass;
|
||||
|
||||
GType
|
||||
gst_vaapi_encoder_jpeg_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GstVaapiEncoder *
|
||||
gst_vaapi_encoder_jpeg_new (GstVaapiDisplay * display);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiEncoderJpeg, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /*GST_VAAPI_ENCODER_JPEG_H */
|
1098
gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c
Normal file
1098
gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c
Normal file
File diff suppressed because it is too large
Load diff
51
gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h
Normal file
51
gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* gstvaapiencoder_mpeg2.h - MPEG-2 encoder
|
||||
*
|
||||
* Copyright (C) 2011-2014 Intel Corporation
|
||||
* Author: Guangxin Xu <guangxin.xu@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_ENCODER_MPEG2_H
|
||||
#define GST_VAAPI_ENCODER_MPEG2_H
|
||||
|
||||
#include <gst/vaapi/gstvaapiencoder.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_ENCODER_MPEG2 \
|
||||
(gst_vaapi_encoder_mpeg2_get_type ())
|
||||
#define GST_VAAPI_ENCODER_MPEG2(encoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((encoder), GST_TYPE_VAAPI_ENCODER_MPEG2, GstVaapiEncoderMpeg2))
|
||||
#define GST_IS_VAAPI_ENCODER_MPEG2(encoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((encoder), GST_TYPE_VAAPI_ENCODER_MPEG2))
|
||||
|
||||
typedef struct _GstVaapiEncoderMpeg2 GstVaapiEncoderMpeg2;
|
||||
typedef struct _GstVaapiEncoderMpeg2Class GstVaapiEncoderMpeg2Class;
|
||||
|
||||
GType
|
||||
gst_vaapi_encoder_mpeg2_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GstVaapiEncoder *
|
||||
gst_vaapi_encoder_mpeg2_new (GstVaapiDisplay * display);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiEncoderMpeg2, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_ENCODER_MPEG2_H */
|
66
gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h
Normal file
66
gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* gstvaapiencoder_mpeg2_priv.h - MPEG-2 encoder (private definitions)
|
||||
*
|
||||
* Copyright (C) 2013-2014 Intel Corporation
|
||||
* Author: Guangxin Xu <guangxin.xu@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_ENCODER_MPEG2_PRIV_H
|
||||
#define GST_VAAPI_ENCODER_MPEG2_PRIV_H
|
||||
|
||||
#include "gstvaapiencoder_priv.h"
|
||||
#include "gstvaapiutils_mpeg2.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_ENCODER_MPEG2_CAST(encoder) \
|
||||
((GstVaapiEncoderMpeg2 *) (encoder))
|
||||
|
||||
#define START_CODE_PICUTRE 0x00000100
|
||||
#define START_CODE_SLICE 0x00000101
|
||||
#define START_CODE_USER 0x000001B2
|
||||
#define START_CODE_SEQ 0x000001B3
|
||||
#define START_CODE_EXT 0x000001B5
|
||||
#define START_CODE_GOP 0x000001B8
|
||||
|
||||
struct _GstVaapiEncoderMpeg2
|
||||
{
|
||||
GstVaapiEncoder parent_instance;
|
||||
|
||||
GstVaapiProfile profile;
|
||||
GstVaapiLevelMPEG2 level;
|
||||
guint8 profile_idc;
|
||||
guint8 level_idc;
|
||||
guint32 cqp; /* quantizer value for CQP mode */
|
||||
guint32 ip_period;
|
||||
|
||||
/* re-ordering */
|
||||
GQueue b_frames;
|
||||
gboolean dump_frames;
|
||||
gboolean new_gop;
|
||||
|
||||
/* reference list */
|
||||
GstVaapiSurfaceProxy *forward;
|
||||
GstVaapiSurfaceProxy *backward;
|
||||
guint32 frame_num; /* same value picture header, but it's not mod by 1024 */
|
||||
};
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_ENCODER_MPEG2_PRIV_H */
|
583
gst-libs/gst/vaapi/gstvaapiencoder_objects.c
Normal file
583
gst-libs/gst/vaapi/gstvaapiencoder_objects.c
Normal file
|
@ -0,0 +1,583 @@
|
|||
/*
|
||||
* gstvaapiencoder_objects.c - VA encoder objects abstraction
|
||||
*
|
||||
* Copyright (C) 2013-2014 Intel Corporation
|
||||
* Author: Wind Yuan <feng.yuan@intel.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; 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "gstvaapiencoder_objects.h"
|
||||
#include "gstvaapiencoder_priv.h"
|
||||
#include "gstvaapisurfaceproxy_priv.h"
|
||||
#include "gstvaapicompat.h"
|
||||
#include "gstvaapiutils.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
#define GET_ENCODER(obj) GST_VAAPI_ENCODER_CAST((obj)->parent_instance.codec)
|
||||
#define GET_VA_DISPLAY(obj) GET_ENCODER(obj)->va_display
|
||||
#define GET_VA_CONTEXT(obj) GET_ENCODER(obj)->va_context
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Encoder Packed Header --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncPackedHeader,
|
||||
gst_vaapi_enc_packed_header);
|
||||
|
||||
void
|
||||
gst_vaapi_enc_packed_header_destroy (GstVaapiEncPackedHeader * header)
|
||||
{
|
||||
vaapi_destroy_buffer (GET_VA_DISPLAY (header), &header->param_id);
|
||||
vaapi_destroy_buffer (GET_VA_DISPLAY (header), &header->data_id);
|
||||
header->param = NULL;
|
||||
header->data = NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_enc_packed_header_create (GstVaapiEncPackedHeader * header,
|
||||
const GstVaapiCodecObjectConstructorArgs * args)
|
||||
{
|
||||
gboolean success;
|
||||
|
||||
header->param_id = VA_INVALID_ID;
|
||||
header->data_id = VA_INVALID_ID;
|
||||
|
||||
success = vaapi_create_buffer (GET_VA_DISPLAY (header),
|
||||
GET_VA_CONTEXT (header),
|
||||
VAEncPackedHeaderParameterBufferType,
|
||||
args->param_size, args->param, &header->param_id, &header->param);
|
||||
if (!success)
|
||||
return FALSE;
|
||||
|
||||
if (!args->data_size)
|
||||
return TRUE;
|
||||
|
||||
success = vaapi_create_buffer (GET_VA_DISPLAY (header),
|
||||
GET_VA_CONTEXT (header),
|
||||
VAEncPackedHeaderDataBufferType,
|
||||
args->data_size, args->data, &header->data_id, &header->data);
|
||||
if (!success)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstVaapiEncPackedHeader *
|
||||
gst_vaapi_enc_packed_header_new (GstVaapiEncoder * encoder,
|
||||
gconstpointer param, guint param_size, gconstpointer data, guint data_size)
|
||||
{
|
||||
GstVaapiCodecObject *object;
|
||||
|
||||
object = gst_vaapi_codec_object_new (&GstVaapiEncPackedHeaderClass,
|
||||
GST_VAAPI_CODEC_BASE (encoder), param, param_size, data, data_size, 0);
|
||||
return GST_VAAPI_ENC_PACKED_HEADER (object);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_enc_packed_header_set_data (GstVaapiEncPackedHeader * header,
|
||||
gconstpointer data, guint data_size)
|
||||
{
|
||||
gboolean success;
|
||||
|
||||
vaapi_destroy_buffer (GET_VA_DISPLAY (header), &header->data_id);
|
||||
header->data = NULL;
|
||||
|
||||
success = vaapi_create_buffer (GET_VA_DISPLAY (header),
|
||||
GET_VA_CONTEXT (header),
|
||||
VAEncPackedHeaderDataBufferType,
|
||||
data_size, data, &header->data_id, &header->data);
|
||||
if (!success)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Encoder Sequence --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncSequence, gst_vaapi_enc_sequence);
|
||||
|
||||
void
|
||||
gst_vaapi_enc_sequence_destroy (GstVaapiEncSequence * sequence)
|
||||
{
|
||||
vaapi_destroy_buffer (GET_VA_DISPLAY (sequence), &sequence->param_id);
|
||||
sequence->param = NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_enc_sequence_create (GstVaapiEncSequence * sequence,
|
||||
const GstVaapiCodecObjectConstructorArgs * args)
|
||||
{
|
||||
gboolean success;
|
||||
|
||||
sequence->param_id = VA_INVALID_ID;
|
||||
success = vaapi_create_buffer (GET_VA_DISPLAY (sequence),
|
||||
GET_VA_CONTEXT (sequence),
|
||||
VAEncSequenceParameterBufferType,
|
||||
args->param_size, args->param, &sequence->param_id, &sequence->param);
|
||||
if (!success)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstVaapiEncSequence *
|
||||
gst_vaapi_enc_sequence_new (GstVaapiEncoder * encoder,
|
||||
gconstpointer param, guint param_size)
|
||||
{
|
||||
GstVaapiCodecObject *object;
|
||||
|
||||
object = gst_vaapi_codec_object_new (&GstVaapiEncSequenceClass,
|
||||
GST_VAAPI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0);
|
||||
return GST_VAAPI_ENC_SEQUENCE (object);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Encoder Slice --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncSlice, gst_vaapi_enc_slice);
|
||||
|
||||
void
|
||||
gst_vaapi_enc_slice_destroy (GstVaapiEncSlice * slice)
|
||||
{
|
||||
if (slice->packed_headers) {
|
||||
g_ptr_array_unref (slice->packed_headers);
|
||||
slice->packed_headers = NULL;
|
||||
}
|
||||
|
||||
vaapi_destroy_buffer (GET_VA_DISPLAY (slice), &slice->param_id);
|
||||
slice->param = NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_enc_slice_create (GstVaapiEncSlice * slice,
|
||||
const GstVaapiCodecObjectConstructorArgs * args)
|
||||
{
|
||||
gboolean success;
|
||||
|
||||
slice->param_id = VA_INVALID_ID;
|
||||
success = vaapi_create_buffer (GET_VA_DISPLAY (slice),
|
||||
GET_VA_CONTEXT (slice),
|
||||
VAEncSliceParameterBufferType,
|
||||
args->param_size, args->param, &slice->param_id, &slice->param);
|
||||
if (!success)
|
||||
return FALSE;
|
||||
|
||||
slice->packed_headers = g_ptr_array_new_with_free_func ((GDestroyNotify)
|
||||
gst_vaapi_mini_object_unref);
|
||||
if (!slice->packed_headers)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstVaapiEncSlice *
|
||||
gst_vaapi_enc_slice_new (GstVaapiEncoder * encoder,
|
||||
gconstpointer param, guint param_size)
|
||||
{
|
||||
GstVaapiCodecObject *object;
|
||||
|
||||
object = gst_vaapi_codec_object_new (&GstVaapiEncSliceClass,
|
||||
GST_VAAPI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0);
|
||||
return GST_VAAPI_ENC_SLICE (object);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Encoder Misc Parameter Buffer --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncMiscParam, gst_vaapi_enc_misc_param);
|
||||
|
||||
void
|
||||
gst_vaapi_enc_misc_param_destroy (GstVaapiEncMiscParam * misc)
|
||||
{
|
||||
vaapi_destroy_buffer (GET_VA_DISPLAY (misc), &misc->param_id);
|
||||
misc->param = NULL;
|
||||
misc->data = NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_enc_misc_param_create (GstVaapiEncMiscParam * misc,
|
||||
const GstVaapiCodecObjectConstructorArgs * args)
|
||||
{
|
||||
gboolean success;
|
||||
|
||||
misc->param_id = VA_INVALID_ID;
|
||||
success = vaapi_create_buffer (GET_VA_DISPLAY (misc),
|
||||
GET_VA_CONTEXT (misc),
|
||||
VAEncMiscParameterBufferType,
|
||||
args->param_size, args->param, &misc->param_id, &misc->param);
|
||||
if (!success)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstVaapiEncMiscParam *
|
||||
gst_vaapi_enc_misc_param_new (GstVaapiEncoder * encoder,
|
||||
VAEncMiscParameterType type, guint data_size)
|
||||
{
|
||||
GstVaapiCodecObject *object;
|
||||
GstVaapiEncMiscParam *misc;
|
||||
VAEncMiscParameterBuffer *va_misc;
|
||||
|
||||
object = gst_vaapi_codec_object_new (&GstVaapiEncMiscParamClass,
|
||||
GST_VAAPI_CODEC_BASE (encoder),
|
||||
NULL, sizeof (VAEncMiscParameterBuffer) + data_size, NULL, 0, 0);
|
||||
if (!object)
|
||||
return NULL;
|
||||
|
||||
misc = GST_VAAPI_ENC_MISC_PARAM (object);
|
||||
va_misc = misc->param;
|
||||
va_misc->type = type;
|
||||
misc->data = va_misc->data;
|
||||
return misc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Quantization Matrices --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncQMatrix, gst_vaapi_enc_q_matrix);
|
||||
|
||||
void
|
||||
gst_vaapi_enc_q_matrix_destroy (GstVaapiEncQMatrix * q_matrix)
|
||||
{
|
||||
vaapi_destroy_buffer (GET_VA_DISPLAY (q_matrix), &q_matrix->param_id);
|
||||
q_matrix->param = NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_enc_q_matrix_create (GstVaapiEncQMatrix * q_matrix,
|
||||
const GstVaapiCodecObjectConstructorArgs * args)
|
||||
{
|
||||
q_matrix->param_id = VA_INVALID_ID;
|
||||
return vaapi_create_buffer (GET_VA_DISPLAY (q_matrix),
|
||||
GET_VA_CONTEXT (q_matrix), VAQMatrixBufferType,
|
||||
args->param_size, args->param, &q_matrix->param_id, &q_matrix->param);
|
||||
}
|
||||
|
||||
GstVaapiEncQMatrix *
|
||||
gst_vaapi_enc_q_matrix_new (GstVaapiEncoder * encoder,
|
||||
gconstpointer param, guint param_size)
|
||||
{
|
||||
GstVaapiCodecObject *object;
|
||||
|
||||
object = gst_vaapi_codec_object_new (&GstVaapiEncQMatrixClass,
|
||||
GST_VAAPI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0);
|
||||
if (!object)
|
||||
return NULL;
|
||||
return GST_VAAPI_ENC_Q_MATRIX_CAST (object);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- JPEG Huffman Tables --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncHuffmanTable,
|
||||
gst_vaapi_enc_huffman_table);
|
||||
|
||||
void
|
||||
gst_vaapi_enc_huffman_table_destroy (GstVaapiEncHuffmanTable * huf_table)
|
||||
{
|
||||
vaapi_destroy_buffer (GET_VA_DISPLAY (huf_table), &huf_table->param_id);
|
||||
huf_table->param = NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_enc_huffman_table_create (GstVaapiEncHuffmanTable * huf_table,
|
||||
const GstVaapiCodecObjectConstructorArgs * args)
|
||||
{
|
||||
huf_table->param_id = VA_INVALID_ID;
|
||||
return vaapi_create_buffer (GET_VA_DISPLAY (huf_table),
|
||||
GET_VA_CONTEXT (huf_table), VAHuffmanTableBufferType, args->param_size,
|
||||
args->param, &huf_table->param_id, (void **) &huf_table->param);
|
||||
}
|
||||
|
||||
GstVaapiEncHuffmanTable *
|
||||
gst_vaapi_enc_huffman_table_new (GstVaapiEncoder * encoder,
|
||||
guint8 * data, guint data_size)
|
||||
{
|
||||
GstVaapiCodecObject *object;
|
||||
|
||||
object = gst_vaapi_codec_object_new (&GstVaapiEncHuffmanTableClass,
|
||||
GST_VAAPI_CODEC_BASE (encoder), data, data_size, NULL, 0, 0);
|
||||
if (!object)
|
||||
return NULL;
|
||||
return GST_VAAPI_ENC_HUFFMAN_TABLE_CAST (object);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Encoder Picture --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncPicture, gst_vaapi_enc_picture);
|
||||
|
||||
void
|
||||
gst_vaapi_enc_picture_destroy (GstVaapiEncPicture * picture)
|
||||
{
|
||||
if (picture->packed_headers) {
|
||||
g_ptr_array_unref (picture->packed_headers);
|
||||
picture->packed_headers = NULL;
|
||||
}
|
||||
if (picture->misc_params) {
|
||||
g_ptr_array_unref (picture->misc_params);
|
||||
picture->misc_params = NULL;
|
||||
}
|
||||
if (picture->slices) {
|
||||
g_ptr_array_unref (picture->slices);
|
||||
picture->slices = NULL;
|
||||
}
|
||||
|
||||
gst_vaapi_codec_object_replace (&picture->q_matrix, NULL);
|
||||
gst_vaapi_codec_object_replace (&picture->huf_table, NULL);
|
||||
|
||||
gst_vaapi_codec_object_replace (&picture->sequence, NULL);
|
||||
|
||||
gst_vaapi_surface_proxy_replace (&picture->proxy, NULL);
|
||||
picture->surface_id = VA_INVALID_ID;
|
||||
picture->surface = NULL;
|
||||
|
||||
vaapi_destroy_buffer (GET_VA_DISPLAY (picture), &picture->param_id);
|
||||
picture->param = NULL;
|
||||
|
||||
if (picture->frame) {
|
||||
gst_video_codec_frame_unref (picture->frame);
|
||||
picture->frame = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_enc_picture_create (GstVaapiEncPicture * picture,
|
||||
const GstVaapiCodecObjectConstructorArgs * args)
|
||||
{
|
||||
GstVideoCodecFrame *const frame = (GstVideoCodecFrame *) args->data;
|
||||
gboolean success;
|
||||
|
||||
picture->proxy = gst_video_codec_frame_get_user_data (frame);
|
||||
if (!gst_vaapi_surface_proxy_ref (picture->proxy))
|
||||
return FALSE;
|
||||
|
||||
picture->surface = GST_VAAPI_SURFACE_PROXY_SURFACE (picture->proxy);
|
||||
if (!picture->surface)
|
||||
return FALSE;
|
||||
|
||||
picture->surface_id = GST_VAAPI_SURFACE_ID (picture->surface);
|
||||
if (picture->surface_id == VA_INVALID_ID)
|
||||
return FALSE;
|
||||
|
||||
picture->type = GST_VAAPI_PICTURE_TYPE_NONE;
|
||||
picture->pts = GST_CLOCK_TIME_NONE;
|
||||
picture->frame_num = 0;
|
||||
picture->poc = 0;
|
||||
|
||||
picture->param_id = VA_INVALID_ID;
|
||||
picture->param_size = args->param_size;
|
||||
success = vaapi_create_buffer (GET_VA_DISPLAY (picture),
|
||||
GET_VA_CONTEXT (picture),
|
||||
VAEncPictureParameterBufferType,
|
||||
args->param_size, args->param, &picture->param_id, &picture->param);
|
||||
if (!success)
|
||||
return FALSE;
|
||||
picture->param_size = args->param_size;
|
||||
|
||||
picture->packed_headers = g_ptr_array_new_with_free_func ((GDestroyNotify)
|
||||
gst_vaapi_mini_object_unref);
|
||||
if (!picture->packed_headers)
|
||||
return FALSE;
|
||||
|
||||
picture->misc_params = g_ptr_array_new_with_free_func ((GDestroyNotify)
|
||||
gst_vaapi_mini_object_unref);
|
||||
if (!picture->misc_params)
|
||||
return FALSE;
|
||||
|
||||
picture->slices = g_ptr_array_new_with_free_func ((GDestroyNotify)
|
||||
gst_vaapi_mini_object_unref);
|
||||
if (!picture->slices)
|
||||
return FALSE;
|
||||
|
||||
picture->frame = gst_video_codec_frame_ref (frame);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstVaapiEncPicture *
|
||||
gst_vaapi_enc_picture_new (GstVaapiEncoder * encoder,
|
||||
gconstpointer param, guint param_size, GstVideoCodecFrame * frame)
|
||||
{
|
||||
GstVaapiCodecObject *object;
|
||||
|
||||
g_return_val_if_fail (frame != NULL, NULL);
|
||||
|
||||
object = gst_vaapi_codec_object_new (&GstVaapiEncPictureClass,
|
||||
GST_VAAPI_CODEC_BASE (encoder), param, param_size, frame, 0, 0);
|
||||
return GST_VAAPI_ENC_PICTURE (object);
|
||||
}
|
||||
|
||||
void
|
||||
gst_vaapi_enc_picture_set_sequence (GstVaapiEncPicture * picture,
|
||||
GstVaapiEncSequence * sequence)
|
||||
{
|
||||
g_return_if_fail (picture != NULL);
|
||||
g_return_if_fail (sequence != NULL);
|
||||
|
||||
gst_vaapi_codec_object_replace (&picture->sequence, sequence);
|
||||
}
|
||||
|
||||
void
|
||||
gst_vaapi_enc_picture_add_packed_header (GstVaapiEncPicture * picture,
|
||||
GstVaapiEncPackedHeader * header)
|
||||
{
|
||||
g_return_if_fail (picture != NULL);
|
||||
g_return_if_fail (header != NULL);
|
||||
|
||||
g_ptr_array_add (picture->packed_headers,
|
||||
gst_vaapi_codec_object_ref (header));
|
||||
}
|
||||
|
||||
void
|
||||
gst_vaapi_enc_picture_add_misc_param (GstVaapiEncPicture * picture,
|
||||
GstVaapiEncMiscParam * misc)
|
||||
{
|
||||
g_return_if_fail (picture != NULL);
|
||||
g_return_if_fail (misc != NULL);
|
||||
|
||||
g_ptr_array_add (picture->misc_params, gst_vaapi_codec_object_ref (misc));
|
||||
}
|
||||
|
||||
void
|
||||
gst_vaapi_enc_picture_add_slice (GstVaapiEncPicture * picture,
|
||||
GstVaapiEncSlice * slice)
|
||||
{
|
||||
g_return_if_fail (picture != NULL);
|
||||
g_return_if_fail (slice != NULL);
|
||||
|
||||
g_ptr_array_add (picture->slices, gst_vaapi_codec_object_ref (slice));
|
||||
}
|
||||
|
||||
void
|
||||
gst_vaapi_enc_slice_add_packed_header (GstVaapiEncSlice * slice,
|
||||
GstVaapiEncPackedHeader * header)
|
||||
{
|
||||
g_return_if_fail (slice != NULL);
|
||||
g_return_if_fail (header != NULL);
|
||||
|
||||
g_ptr_array_add (slice->packed_headers, gst_vaapi_codec_object_ref (header));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
do_encode (VADisplay dpy, VAContextID ctx, VABufferID * buf_id, void **buf_ptr)
|
||||
{
|
||||
VAStatus status;
|
||||
|
||||
vaapi_unmap_buffer (dpy, *buf_id, buf_ptr);
|
||||
|
||||
status = vaRenderPicture (dpy, ctx, buf_id, 1);
|
||||
if (!vaapi_check_status (status, "vaRenderPicture()"))
|
||||
return FALSE;
|
||||
|
||||
/* XXX: vaRenderPicture() is meant to destroy the VA buffer implicitly */
|
||||
vaapi_destroy_buffer (dpy, buf_id);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture)
|
||||
{
|
||||
GstVaapiEncSequence *sequence;
|
||||
GstVaapiEncQMatrix *q_matrix;
|
||||
GstVaapiEncHuffmanTable *huf_table;
|
||||
VADisplay va_display;
|
||||
VAContextID va_context;
|
||||
VAStatus status;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (picture != NULL, FALSE);
|
||||
g_return_val_if_fail (picture->surface_id != VA_INVALID_SURFACE, FALSE);
|
||||
|
||||
va_display = GET_VA_DISPLAY (picture);
|
||||
va_context = GET_VA_CONTEXT (picture);
|
||||
|
||||
GST_DEBUG ("encode picture 0x%08x", picture->surface_id);
|
||||
|
||||
status = vaBeginPicture (va_display, va_context, picture->surface_id);
|
||||
if (!vaapi_check_status (status, "vaBeginPicture()"))
|
||||
return FALSE;
|
||||
|
||||
/* Submit Sequence parameter */
|
||||
sequence = picture->sequence;
|
||||
if (sequence && !do_encode (va_display, va_context,
|
||||
&sequence->param_id, &sequence->param))
|
||||
return FALSE;
|
||||
|
||||
/* Submit Quantization matrix */
|
||||
q_matrix = picture->q_matrix;
|
||||
if (q_matrix && !do_encode (va_display, va_context,
|
||||
&q_matrix->param_id, &q_matrix->param))
|
||||
return FALSE;
|
||||
|
||||
/* Submit huffman table */
|
||||
huf_table = picture->huf_table;
|
||||
if (huf_table && !do_encode (va_display, va_context,
|
||||
&huf_table->param_id, (void **) &huf_table->param))
|
||||
return FALSE;
|
||||
|
||||
/* Submit Packed Headers */
|
||||
for (i = 0; i < picture->packed_headers->len; i++) {
|
||||
GstVaapiEncPackedHeader *const header =
|
||||
g_ptr_array_index (picture->packed_headers, i);
|
||||
if (!do_encode (va_display, va_context,
|
||||
&header->param_id, &header->param) ||
|
||||
!do_encode (va_display, va_context, &header->data_id, &header->data))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Submit Picture parameter */
|
||||
if (!do_encode (va_display, va_context, &picture->param_id, &picture->param))
|
||||
return FALSE;
|
||||
|
||||
/* Submit Misc Params */
|
||||
for (i = 0; i < picture->misc_params->len; i++) {
|
||||
GstVaapiEncMiscParam *const misc =
|
||||
g_ptr_array_index (picture->misc_params, i);
|
||||
if (!do_encode (va_display, va_context, &misc->param_id, &misc->param))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Submit Slice parameters */
|
||||
for (i = 0; i < picture->slices->len; i++) {
|
||||
GstVaapiEncSlice *const slice = g_ptr_array_index (picture->slices, i);
|
||||
guint j;
|
||||
|
||||
/* Submit packed_slice_header and packed_raw_data */
|
||||
for (j = 0; j < slice->packed_headers->len; j++) {
|
||||
GstVaapiEncPackedHeader *const header =
|
||||
g_ptr_array_index (slice->packed_headers, j);
|
||||
if (!do_encode (va_display, va_context,
|
||||
&header->param_id, &header->param) ||
|
||||
!do_encode (va_display, va_context, &header->data_id, &header->data))
|
||||
return FALSE;
|
||||
}
|
||||
if (!do_encode (va_display, va_context, &slice->param_id, &slice->param))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
status = vaEndPicture (va_display, va_context);
|
||||
if (!vaapi_check_status (status, "vaEndPicture()"))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
362
gst-libs/gst/vaapi/gstvaapiencoder_objects.h
Normal file
362
gst-libs/gst/vaapi/gstvaapiencoder_objects.h
Normal file
|
@ -0,0 +1,362 @@
|
|||
/*
|
||||
* gstvaapiencoder_objects.h - VA encoder objects abstraction
|
||||
*
|
||||
* Copyright (C) 2013-2014 Intel Corporation
|
||||
* Author: Wind Yuan <feng.yuan@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_ENCODER_OBJECTS_H
|
||||
#define GST_VAAPI_ENCODER_OBJECTS_H
|
||||
|
||||
#include <gst/vaapi/gstvaapicodec_objects.h>
|
||||
#include <gst/vaapi/gstvaapidecoder_objects.h>
|
||||
#include <gst/vaapi/gstvaapiencoder.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstVaapiEncPicture GstVaapiEncPicture;
|
||||
typedef struct _GstVaapiEncSequence GstVaapiEncSequence;
|
||||
typedef struct _GstVaapiEncMiscParam GstVaapiEncMiscParam;
|
||||
typedef struct _GstVaapiEncSlice GstVaapiEncSlice;
|
||||
typedef struct _GstVaapiEncQMatrix GstVaapiEncQMatrix;
|
||||
typedef struct _GstVaapiEncHuffmanTable GstVaapiEncHuffmanTable;
|
||||
typedef struct _GstVaapiEncPackedHeader GstVaapiEncPackedHeader;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Encoder Packed Header --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_ENC_PACKED_HEADER(obj) \
|
||||
((GstVaapiEncPackedHeader *) (obj))
|
||||
|
||||
/**
|
||||
* GstVaapiEncPackedHeader:
|
||||
*
|
||||
* A #GstVaapiCodecObject holding a packed header (param/data) for the
|
||||
* encoder.
|
||||
*/
|
||||
struct _GstVaapiEncPackedHeader
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiCodecObject parent_instance;
|
||||
|
||||
/*< public >*/
|
||||
VABufferID param_id;
|
||||
gpointer param;
|
||||
VABufferID data_id;
|
||||
gpointer data;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiEncPackedHeader *
|
||||
gst_vaapi_enc_packed_header_new (GstVaapiEncoder * encoder,
|
||||
gconstpointer param, guint param_size, gconstpointer data, guint data_size);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_enc_packed_header_set_data (GstVaapiEncPackedHeader * header,
|
||||
gconstpointer data, guint data_size);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Encoder Sequence --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_ENC_SEQUENCE(obj) \
|
||||
((GstVaapiEncSequence *) (obj))
|
||||
|
||||
/**
|
||||
* GstVaapiEncSequence:
|
||||
*
|
||||
* A #GstVaapiCodecObject holding a sequence parameter for encoding.
|
||||
*/
|
||||
struct _GstVaapiEncSequence
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiCodecObject parent_instance;
|
||||
|
||||
/*< public >*/
|
||||
VABufferID param_id;
|
||||
gpointer param;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiEncSequence *
|
||||
gst_vaapi_enc_sequence_new (GstVaapiEncoder * encoder,
|
||||
gconstpointer param, guint param_size);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Encoder Slice --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_ENC_SLICE(obj) \
|
||||
((GstVaapiEncSlice *) (obj))
|
||||
|
||||
/**
|
||||
* GstVaapiEncSlice:
|
||||
*
|
||||
* A #GstVaapiCodecObject holding a slice parameter used for encoding.
|
||||
*/
|
||||
struct _GstVaapiEncSlice
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiCodecObject parent_instance;
|
||||
|
||||
/*< public >*/
|
||||
VABufferID param_id;
|
||||
gpointer param;
|
||||
GPtrArray *packed_headers;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiEncSlice *
|
||||
gst_vaapi_enc_slice_new (GstVaapiEncoder * encoder,
|
||||
gconstpointer param, guint param_size);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Encoder Misc Parameter Buffer --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_ENC_MISC_PARAM(obj) \
|
||||
((GstVaapiEncMiscParam *) (obj))
|
||||
|
||||
/**
|
||||
* GstVaapiEncMiscParam:
|
||||
*
|
||||
* A #GstVaapiCodecObject holding a misc parameter and associated data
|
||||
* used for controlling the encoder dynamically.
|
||||
*/
|
||||
struct _GstVaapiEncMiscParam
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiCodecObject parent_instance;
|
||||
gpointer param;
|
||||
|
||||
/*< public >*/
|
||||
VABufferID param_id;
|
||||
gpointer data;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiEncMiscParam *
|
||||
gst_vaapi_enc_misc_param_new (GstVaapiEncoder * encoder,
|
||||
VAEncMiscParameterType type, guint data_size);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Quantization Matrices --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_ENC_Q_MATRIX_CAST(obj) \
|
||||
((GstVaapiEncQMatrix *) (obj))
|
||||
|
||||
/**
|
||||
* GstVaapiEncQMatrix:
|
||||
*
|
||||
* A #GstVaapiCodecObject holding a quantization matrix parameter.
|
||||
*/
|
||||
struct _GstVaapiEncQMatrix
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiCodecObject parent_instance;
|
||||
VABufferID param_id;
|
||||
|
||||
/*< public >*/
|
||||
gpointer param;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiEncQMatrix *
|
||||
gst_vaapi_enc_q_matrix_new (GstVaapiEncoder * encoder, gconstpointer param,
|
||||
guint param_size);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- JPEG Huffman Tables --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_ENC_HUFFMAN_TABLE_CAST(obj) \
|
||||
((GstVaapiEncHuffmanTable *) (obj))
|
||||
|
||||
/**
|
||||
* GstVaapiEncHuffmanTable:
|
||||
*
|
||||
* A #GstVaapiCodecObject holding huffman table.
|
||||
*/
|
||||
struct _GstVaapiEncHuffmanTable
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiCodecObject parent_instance;
|
||||
VABufferID param_id;
|
||||
|
||||
/*< public >*/
|
||||
gpointer param;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiEncHuffmanTable *
|
||||
gst_vaapi_enc_huffman_table_new (GstVaapiEncoder * encoder, guint8 * data,
|
||||
guint data_size);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Encoder Picture --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_ENC_PICTURE(obj) \
|
||||
((GstVaapiEncPicture *) (obj))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GST_VAAPI_ENC_PICTURE_FLAG_IDR = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 0),
|
||||
GST_VAAPI_ENC_PICTURE_FLAG_REFERENCE = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 1),
|
||||
GST_VAAPI_ENC_PICTURE_FLAG_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 2),
|
||||
} GstVaapiEncPictureFlags;
|
||||
|
||||
#define GST_VAAPI_ENC_PICTURE_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS
|
||||
#define GST_VAAPI_ENC_PICTURE_FLAG_IS_SET GST_VAAPI_MINI_OBJECT_FLAG_IS_SET
|
||||
#define GST_VAAPI_ENC_PICTURE_FLAG_SET GST_VAAPI_MINI_OBJECT_FLAG_SET
|
||||
#define GST_VAAPI_ENC_PICTURE_FLAG_UNSET GST_VAAPI_MINI_OBJECT_FLAG_UNSET
|
||||
|
||||
#define GST_VAAPI_ENC_PICTURE_IS_IDR(picture) \
|
||||
GST_VAAPI_ENC_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_ENC_PICTURE_FLAG_IDR)
|
||||
|
||||
#define GST_VAAPI_ENC_PICTURE_IS_REFRENCE(picture) \
|
||||
GST_VAAPI_ENC_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_ENC_PICTURE_FLAG_REFERENCE)
|
||||
|
||||
/**
|
||||
* GstVaapiEncPicture:
|
||||
*
|
||||
* A #GstVaapiCodecObject holding a picture parameter for encoding.
|
||||
*/
|
||||
struct _GstVaapiEncPicture
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiCodecObject parent_instance;
|
||||
GstVideoCodecFrame *frame;
|
||||
GstVaapiSurfaceProxy *proxy;
|
||||
GstVaapiSurface *surface;
|
||||
VABufferID param_id;
|
||||
guint param_size;
|
||||
|
||||
/* Additional data to pass down */
|
||||
GstVaapiEncSequence *sequence;
|
||||
GPtrArray *packed_headers;
|
||||
GPtrArray *misc_params;
|
||||
|
||||
/*< public >*/
|
||||
GstVaapiPictureType type;
|
||||
VASurfaceID surface_id;
|
||||
gpointer param;
|
||||
GPtrArray *slices;
|
||||
GstVaapiEncQMatrix *q_matrix;
|
||||
GstVaapiEncHuffmanTable *huf_table;
|
||||
GstClockTime pts;
|
||||
guint frame_num;
|
||||
guint poc;
|
||||
guint temporal_id;
|
||||
gboolean has_roi;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiEncPicture *
|
||||
gst_vaapi_enc_picture_new (GstVaapiEncoder * encoder,
|
||||
gconstpointer param, guint param_size, GstVideoCodecFrame * frame);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_enc_picture_set_sequence (GstVaapiEncPicture * picture,
|
||||
GstVaapiEncSequence * sequence);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_enc_picture_add_packed_header (GstVaapiEncPicture * picture,
|
||||
GstVaapiEncPackedHeader * header);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_enc_picture_add_misc_param (GstVaapiEncPicture * picture,
|
||||
GstVaapiEncMiscParam * misc);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_enc_picture_add_slice (GstVaapiEncPicture * picture,
|
||||
GstVaapiEncSlice * slice);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_vaapi_enc_slice_add_packed_header (GstVaapiEncSlice *slice,
|
||||
GstVaapiEncPackedHeader * header);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture);
|
||||
|
||||
#define gst_vaapi_enc_picture_ref(picture) \
|
||||
gst_vaapi_codec_object_ref (picture)
|
||||
#define gst_vaapi_enc_picture_unref(picture) \
|
||||
gst_vaapi_codec_object_unref (picture)
|
||||
#define gst_vaapi_enc_picture_replace(old_picture_ptr, new_picture) \
|
||||
gst_vaapi_codec_object_replace (old_picture_ptr, new_picture)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Helpers to create codec-dependent objects --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* GstVaapiEncSequence */
|
||||
#define GST_VAAPI_ENC_SEQUENCE_NEW(codec, encoder) \
|
||||
gst_vaapi_enc_sequence_new (GST_VAAPI_ENCODER_CAST (encoder), \
|
||||
NULL, sizeof (G_PASTE (VAEncSequenceParameterBuffer, codec)))
|
||||
|
||||
/* GstVaapiEncMiscParam */
|
||||
#define GST_VAAPI_ENC_MISC_PARAM_NEW(type, encoder) \
|
||||
gst_vaapi_enc_misc_param_new (GST_VAAPI_ENCODER_CAST (encoder), \
|
||||
G_PASTE (VAEncMiscParameterType, type), \
|
||||
sizeof (G_PASTE (VAEncMiscParameter, type)))
|
||||
|
||||
/* GstVaapiEncQualityLevelMiscParam */
|
||||
#define GST_VAAPI_ENC_QUALITY_LEVEL_MISC_PARAM_NEW(encoder) \
|
||||
gst_vaapi_enc_misc_param_new (GST_VAAPI_ENCODER_CAST (encoder), \
|
||||
VAEncMiscParameterTypeQualityLevel, \
|
||||
sizeof (VAEncMiscParameterBufferQualityLevel))
|
||||
|
||||
/* GstVaapiEncQuantizationMiscParam */
|
||||
#define GST_VAAPI_ENC_QUANTIZATION_MISC_PARAM_NEW(encoder) \
|
||||
gst_vaapi_enc_misc_param_new (GST_VAAPI_ENCODER_CAST (encoder), \
|
||||
VAEncMiscParameterTypeQuantization, \
|
||||
sizeof (VAEncMiscParameterQuantization))
|
||||
|
||||
/* GstVaapiEncPicture */
|
||||
#define GST_VAAPI_ENC_PICTURE_NEW(codec, encoder, frame) \
|
||||
gst_vaapi_enc_picture_new (GST_VAAPI_ENCODER_CAST (encoder), \
|
||||
NULL, sizeof (G_PASTE (VAEncPictureParameterBuffer, codec)), frame)
|
||||
|
||||
/* GstVaapiEncSlice */
|
||||
#define GST_VAAPI_ENC_SLICE_NEW(codec, encoder) \
|
||||
gst_vaapi_enc_slice_new (GST_VAAPI_ENCODER_CAST (encoder), \
|
||||
NULL, sizeof(G_PASTE (VAEncSliceParameterBuffer, codec)))
|
||||
|
||||
/* GstVaapiEncQuantMatrix */
|
||||
#define GST_VAAPI_ENC_Q_MATRIX_NEW(codec, encoder) \
|
||||
gst_vaapi_enc_q_matrix_new (GST_VAAPI_ENCODER_CAST (encoder), \
|
||||
NULL, sizeof (G_PASTE (VAQMatrixBuffer, codec)))
|
||||
|
||||
/* GstVaapiEncHuffmanTable */
|
||||
#define GST_VAAPI_ENC_HUFFMAN_TABLE_NEW(codec, encoder) \
|
||||
gst_vaapi_enc_huffman_table_new (GST_VAAPI_ENCODER_CAST (encoder), \
|
||||
NULL, sizeof (G_PASTE (VAHuffmanTableBuffer, codec)))
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_ENCODER_OBJECTS_H */
|
394
gst-libs/gst/vaapi/gstvaapiencoder_priv.h
Normal file
394
gst-libs/gst/vaapi/gstvaapiencoder_priv.h
Normal file
|
@ -0,0 +1,394 @@
|
|||
/*
|
||||
* gstvaapiencoder_priv.h - VA encoder abstraction (private definitions)
|
||||
*
|
||||
* Copyright (C) 2013-2014 Intel Corporation
|
||||
* Author: Wind Yuan <feng.yuan@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_ENCODER_PRIV_H
|
||||
#define GST_VAAPI_ENCODER_PRIV_H
|
||||
|
||||
#include <gst/vaapi/gstvaapiencoder.h>
|
||||
#include <gst/vaapi/gstvaapiencoder_objects.h>
|
||||
#include <gst/vaapi/gstvaapicontext.h>
|
||||
#include <gst/vaapi/gstvaapivideopool.h>
|
||||
#include <gst/video/gstvideoutils.h>
|
||||
#include <gst/vaapi/gstvaapivalue.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_ENCODER_CAST(encoder) \
|
||||
((GstVaapiEncoder *)(encoder))
|
||||
|
||||
#define GST_VAAPI_ENCODER_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_ENCODER, GstVaapiEncoderClass))
|
||||
|
||||
#define GST_VAAPI_ENCODER_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_ENCODER, GstVaapiEncoderClass))
|
||||
|
||||
/**
|
||||
* GST_VAAPI_ENCODER_PACKED_HEADERS:
|
||||
* @encoder: a #GstVaapiEncoder
|
||||
*
|
||||
* Macro that evaluates to the required set of VA packed headers that
|
||||
* need to be submitted along with the corresponding param buffers.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_ENCODER_PACKED_HEADERS
|
||||
#define GST_VAAPI_ENCODER_PACKED_HEADERS(encoder) \
|
||||
GST_VAAPI_ENCODER_CAST(encoder)->packed_headers
|
||||
|
||||
/**
|
||||
* GST_VAAPI_ENCODER_DISPLAY:
|
||||
* @encoder: a #GstVaapiEncoder
|
||||
*
|
||||
* Macro that evaluates to the #GstVaapiDisplay of @encoder.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_ENCODER_DISPLAY
|
||||
#define GST_VAAPI_ENCODER_DISPLAY(encoder) \
|
||||
GST_VAAPI_ENCODER_CAST(encoder)->display
|
||||
|
||||
/**
|
||||
* GST_VAAPI_ENCODER_CONTEXT:
|
||||
* @encoder: a #GstVaapiEncoder
|
||||
*
|
||||
* Macro that evaluates to the #GstVaapiContext of @encoder.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_ENCODER_CONTEXT
|
||||
#define GST_VAAPI_ENCODER_CONTEXT(encoder) \
|
||||
GST_VAAPI_ENCODER_CAST(encoder)->context
|
||||
|
||||
/**
|
||||
* GST_VAAPI_ENCODER_VIDEO_INFO:
|
||||
* @encoder: a #GstVaapiEncoder
|
||||
*
|
||||
* Macro that evaluates to the #GstVideoInfo of @encoder.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_ENCODER_VIDEO_INFO
|
||||
#define GST_VAAPI_ENCODER_VIDEO_INFO(encoder) \
|
||||
(&GST_VAAPI_ENCODER_CAST (encoder)->video_info)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_ENCODER_WIDTH:
|
||||
* @encoder: a #GstVaapiEncoder
|
||||
*
|
||||
* Macro that evaluates to the coded width of the picture.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_ENCODER_WIDTH
|
||||
#define GST_VAAPI_ENCODER_WIDTH(encoder) \
|
||||
(GST_VAAPI_ENCODER_VIDEO_INFO (encoder)->width)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_ENCODER_HEIGHT:
|
||||
* @encoder: a #GstVaapiEncoder
|
||||
*
|
||||
* Macro that evaluates to the coded height of the picture.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_ENCODER_HEIGHT
|
||||
#define GST_VAAPI_ENCODER_HEIGHT(encoder) \
|
||||
(GST_VAAPI_ENCODER_VIDEO_INFO (encoder)->height)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_ENCODER_FPS_N:
|
||||
* @encoder: a #GstVaapiEncoder
|
||||
*
|
||||
* Macro that evaluates to the coded framerate numerator.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_ENCODER_FPS_N
|
||||
#define GST_VAAPI_ENCODER_FPS_N(encoder) \
|
||||
(GST_VAAPI_ENCODER_VIDEO_INFO (encoder)->fps_n)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_ENCODER_FPS_D:
|
||||
* @encoder: a #GstVaapiEncoder
|
||||
*
|
||||
* Macro that evaluates to the coded framerate denominator.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_ENCODER_FPS_D
|
||||
#define GST_VAAPI_ENCODER_FPS_D(encoder) \
|
||||
(GST_VAAPI_ENCODER_VIDEO_INFO (encoder)->fps_d)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_ENCODER_RATE_CONTROL:
|
||||
* @encoder: a #GstVaapiEncoder
|
||||
*
|
||||
* Macro that evaluates to the rate control.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_ENCODER_RATE_CONTROL
|
||||
#define GST_VAAPI_ENCODER_RATE_CONTROL(encoder) \
|
||||
(GST_VAAPI_ENCODER_CAST (encoder)->rate_control)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_ENCODER_KEYFRAME_PERIOD:
|
||||
* @encoder: a #GstVaapiEncoder
|
||||
*
|
||||
* Macro that evaluates to the keyframe period.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_ENCODER_KEYFRAME_PERIOD
|
||||
#define GST_VAAPI_ENCODER_KEYFRAME_PERIOD(encoder) \
|
||||
(GST_VAAPI_ENCODER_CAST (encoder)->keyframe_period)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_ENCODER_TUNE:
|
||||
* @encoder: a #GstVaapiEncoder
|
||||
*
|
||||
* Macro that evaluates to the tuning option.
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_ENCODER_TUNE
|
||||
#define GST_VAAPI_ENCODER_TUNE(encoder) \
|
||||
(GST_VAAPI_ENCODER_CAST (encoder)->tune)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_ENCODER_QUALITY_LEVEL:
|
||||
* @encoder: a #GstVaapiEncoder
|
||||
*
|
||||
* Macro that evaluates to the quality level
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_ENCODER_QUALITY_LEVEL
|
||||
#define GST_VAAPI_ENCODER_QUALITY_LEVEL(encoder) \
|
||||
(GST_VAAPI_ENCODER_CAST (encoder)->va_quality_level.quality_level)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_ENCODER_VA_RATE_CONTROL:
|
||||
* @encoder: a #GstVaapiEncoder
|
||||
*
|
||||
* Macro that evaluates to #VAEncMiscParameterRateControl
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_ENCODER_VA_RATE_CONTROL
|
||||
#define GST_VAAPI_ENCODER_VA_RATE_CONTROL(encoder) \
|
||||
(GST_VAAPI_ENCODER_CAST (encoder)->va_ratecontrol)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_ENCODER_VA_FRAME_RATE:
|
||||
* @encoder: a #GstVaapiEncoder
|
||||
*
|
||||
* Macro that evaluates to #VAEncMiscParameterFrameRate
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_ENCODER_VA_FRAME_RATE
|
||||
#define GST_VAAPI_ENCODER_VA_FRAME_RATE(encoder) \
|
||||
(GST_VAAPI_ENCODER_CAST (encoder)->va_framerate)
|
||||
|
||||
/**
|
||||
* GST_VAAPI_ENCODER_VA_HRD:
|
||||
* @encoder: a #GstVaapiEncoder
|
||||
*
|
||||
* Macro that evaluates to #VAEncMiscParameterHRD
|
||||
* This is an internal macro that does not do any run-time type check.
|
||||
*/
|
||||
#undef GST_VAAPI_ENCODER_VA_HRD
|
||||
#define GST_VAAPI_ENCODER_VA_HRD(encoder) \
|
||||
(GST_VAAPI_ENCODER_CAST (encoder)->va_hrd)
|
||||
|
||||
/* Generate a mask for the supplied tuning option (internal) */
|
||||
#define GST_VAAPI_ENCODER_TUNE_MASK(TUNE) \
|
||||
(1U << G_PASTE (GST_VAAPI_ENCODER_TUNE_, TUNE))
|
||||
|
||||
#define GST_VAAPI_TYPE_ENCODER_TUNE \
|
||||
(gst_vaapi_encoder_tune_get_type ())
|
||||
|
||||
#define GST_VAAPI_TYPE_ENCODER_MBBRC \
|
||||
(gst_vaapi_encoder_mbbrc_get_type ())
|
||||
|
||||
typedef struct _GstVaapiEncoderClass GstVaapiEncoderClass;
|
||||
typedef struct _GstVaapiEncoderClassData GstVaapiEncoderClassData;
|
||||
|
||||
struct _GstVaapiEncoder
|
||||
{
|
||||
/*< private >*/
|
||||
GstObject parent_instance;
|
||||
|
||||
GPtrArray *properties;
|
||||
GstVaapiDisplay *display;
|
||||
GstVaapiContext *context;
|
||||
GstVaapiContextInfo context_info;
|
||||
GstVaapiEncoderTune tune;
|
||||
guint packed_headers;
|
||||
|
||||
VADisplay va_display;
|
||||
VAContextID va_context;
|
||||
GstVideoInfo video_info;
|
||||
GstVaapiProfile profile;
|
||||
guint num_ref_frames;
|
||||
GstVaapiRateControl rate_control;
|
||||
guint32 rate_control_mask;
|
||||
guint bitrate; /* kbps */
|
||||
guint target_percentage;
|
||||
guint keyframe_period;
|
||||
|
||||
/* Maximum number of reference frames supported
|
||||
* for the reference picture list 0 and list 2 */
|
||||
guint max_num_ref_frames_0;
|
||||
guint max_num_ref_frames_1;
|
||||
|
||||
/* parameters */
|
||||
VAEncMiscParameterBufferQualityLevel va_quality_level;
|
||||
|
||||
GMutex mutex;
|
||||
GCond surface_free;
|
||||
GCond codedbuf_free;
|
||||
guint codedbuf_size;
|
||||
GstVaapiVideoPool *codedbuf_pool;
|
||||
GAsyncQueue *codedbuf_queue;
|
||||
guint32 num_codedbuf_queued;
|
||||
|
||||
guint got_packed_headers:1;
|
||||
guint got_rate_control_mask:1;
|
||||
|
||||
/* miscellaneous buffer parameters */
|
||||
VAEncMiscParameterRateControl va_ratecontrol;
|
||||
VAEncMiscParameterFrameRate va_framerate;
|
||||
VAEncMiscParameterHRD va_hrd;
|
||||
|
||||
gint8 default_roi_value;
|
||||
|
||||
/* trellis quantization */
|
||||
gboolean trellis;
|
||||
};
|
||||
|
||||
struct _GstVaapiEncoderClassData
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiCodec codec;
|
||||
guint32 packed_headers;
|
||||
|
||||
GType (*rate_control_get_type)(void);
|
||||
GstVaapiRateControl default_rate_control;
|
||||
guint32 rate_control_mask;
|
||||
|
||||
GType (*encoder_tune_get_type)(void);
|
||||
GstVaapiEncoderTune default_encoder_tune;
|
||||
guint32 encoder_tune_mask;
|
||||
};
|
||||
|
||||
#define GST_VAAPI_ENCODER_DEFINE_CLASS_DATA(CODEC) \
|
||||
GST_VAAPI_TYPE_DEFINE_ENUM_SUBSET_FROM_MASK( \
|
||||
G_PASTE (GstVaapiRateControl, CODEC), \
|
||||
G_PASTE (gst_vaapi_rate_control_, CODEC), \
|
||||
GST_VAAPI_TYPE_RATE_CONTROL, SUPPORTED_RATECONTROLS); \
|
||||
\
|
||||
GST_VAAPI_TYPE_DEFINE_ENUM_SUBSET_FROM_MASK( \
|
||||
G_PASTE (GstVaapiEncoderTune, CODEC), \
|
||||
G_PASTE (gst_vaapi_encoder_tune_, CODEC), \
|
||||
GST_VAAPI_TYPE_ENCODER_TUNE, SUPPORTED_TUNE_OPTIONS); \
|
||||
\
|
||||
static const GstVaapiEncoderClassData g_class_data = { \
|
||||
.codec = G_PASTE (GST_VAAPI_CODEC_, CODEC), \
|
||||
.packed_headers = SUPPORTED_PACKED_HEADERS, \
|
||||
.rate_control_get_type = \
|
||||
G_PASTE (G_PASTE (gst_vaapi_rate_control_, CODEC), _get_type), \
|
||||
.default_rate_control = DEFAULT_RATECONTROL, \
|
||||
.rate_control_mask = SUPPORTED_RATECONTROLS, \
|
||||
.encoder_tune_get_type = \
|
||||
G_PASTE (G_PASTE (gst_vaapi_encoder_tune_, CODEC), _get_type), \
|
||||
.default_encoder_tune = GST_VAAPI_ENCODER_TUNE_NONE, \
|
||||
.encoder_tune_mask = SUPPORTED_TUNE_OPTIONS, \
|
||||
}
|
||||
|
||||
struct _GstVaapiEncoderClass
|
||||
{
|
||||
/*< private >*/
|
||||
GstObjectClass parent_class;
|
||||
|
||||
const GstVaapiEncoderClassData *class_data;
|
||||
|
||||
GstVaapiEncoderStatus (*reconfigure) (GstVaapiEncoder * encoder);
|
||||
GstVaapiEncoderStatus (*reordering) (GstVaapiEncoder * encoder,
|
||||
GstVideoCodecFrame * in,
|
||||
GstVaapiEncPicture ** out);
|
||||
GstVaapiEncoderStatus (*encode) (GstVaapiEncoder * encoder,
|
||||
GstVaapiEncPicture * picture,
|
||||
GstVaapiCodedBufferProxy * codedbuf);
|
||||
|
||||
GstVaapiEncoderStatus (*flush) (GstVaapiEncoder * encoder);
|
||||
|
||||
/* get_codec_data can be NULL */
|
||||
GstVaapiEncoderStatus (*get_codec_data) (GstVaapiEncoder * encoder,
|
||||
GstBuffer ** codec_data);
|
||||
|
||||
/* Iterator that retrieves the pending pictures in the reordered
|
||||
* list */
|
||||
gboolean (*get_pending_reordered) (GstVaapiEncoder * encoder,
|
||||
GstVaapiEncPicture ** picture,
|
||||
gpointer * state);
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiSurfaceProxy *
|
||||
gst_vaapi_encoder_create_surface (GstVaapiEncoder *
|
||||
encoder);
|
||||
|
||||
static inline void
|
||||
gst_vaapi_encoder_release_surface (GstVaapiEncoder * encoder,
|
||||
GstVaapiSurfaceProxy * proxy)
|
||||
{
|
||||
gst_vaapi_surface_proxy_unref (proxy);
|
||||
}
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_encoder_ensure_param_quality_level (GstVaapiEncoder * encoder,
|
||||
GstVaapiEncPicture * picture);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_encoder_ensure_param_control_rate (GstVaapiEncoder * encoder,
|
||||
GstVaapiEncPicture * picture);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_encoder_ensure_param_roi_regions (GstVaapiEncoder * encoder,
|
||||
GstVaapiEncPicture * picture);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_encoder_ensure_param_trellis (GstVaapiEncoder * encoder,
|
||||
GstVaapiEncPicture * picture);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_encoder_ensure_num_slices (GstVaapiEncoder * encoder,
|
||||
GstVaapiProfile profile, GstVaapiEntrypoint entrypoint,
|
||||
guint media_max_slices, guint * num_slices);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_encoder_ensure_max_num_ref_frames (GstVaapiEncoder * encoder,
|
||||
GstVaapiProfile profile, GstVaapiEntrypoint entrypoint);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_encoder_ensure_tile_support (GstVaapiEncoder * encoder,
|
||||
GstVaapiProfile profile, GstVaapiEntrypoint entrypoint);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_ENCODER_PRIV_H */
|
701
gst-libs/gst/vaapi/gstvaapiencoder_vp8.c
Normal file
701
gst-libs/gst/vaapi/gstvaapiencoder_vp8.c
Normal file
|
@ -0,0 +1,701 @@
|
|||
/*
|
||||
* gstvaapiencoder_vp8.c - VP8 encoder
|
||||
*
|
||||
* Copyright (C) 2015 Intel Corporation
|
||||
* Author: Sreerenj Balachandran <sreerenj.balachandran@intel.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; 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include <gst/base/gstbitwriter.h>
|
||||
#include <gst/codecparsers/gstvp8parser.h>
|
||||
#include "gstvaapicompat.h"
|
||||
#include "gstvaapiencoder_priv.h"
|
||||
#include "gstvaapiencoder_vp8.h"
|
||||
#include "gstvaapicodedbufferproxy_priv.h"
|
||||
#include "gstvaapisurface.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
/* Define default rate control mode ("constant-qp") */
|
||||
#define DEFAULT_RATECONTROL GST_VAAPI_RATECONTROL_CQP
|
||||
|
||||
/* Supported set of VA rate controls, within this implementation */
|
||||
#define SUPPORTED_RATECONTROLS \
|
||||
(GST_VAAPI_RATECONTROL_MASK (CQP) | \
|
||||
GST_VAAPI_RATECONTROL_MASK (CBR) | \
|
||||
GST_VAAPI_RATECONTROL_MASK (VBR))
|
||||
|
||||
/* Supported set of tuning options, within this implementation */
|
||||
#define SUPPORTED_TUNE_OPTIONS \
|
||||
(GST_VAAPI_ENCODER_TUNE_MASK (NONE))
|
||||
|
||||
/* Supported set of VA packed headers, within this implementation */
|
||||
#define SUPPORTED_PACKED_HEADERS \
|
||||
(VA_ENC_PACKED_HEADER_NONE)
|
||||
|
||||
#define DEFAULT_LOOP_FILTER_LEVEL 0
|
||||
#define DEFAULT_SHARPNESS_LEVEL 0
|
||||
#define DEFAULT_YAC_QI 40
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- VP8 Encoder --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
struct _GstVaapiEncoderVP8
|
||||
{
|
||||
GstVaapiEncoder parent_instance;
|
||||
GstVaapiProfile profile;
|
||||
guint loop_filter_level;
|
||||
guint sharpness_level;
|
||||
guint yac_qi;
|
||||
guint frame_num;
|
||||
/* reference list */
|
||||
GstVaapiSurfaceProxy *last_ref;
|
||||
GstVaapiSurfaceProxy *golden_ref;
|
||||
GstVaapiSurfaceProxy *alt_ref;
|
||||
};
|
||||
|
||||
/* Derives the profile that suits best to the configuration */
|
||||
static GstVaapiEncoderStatus
|
||||
ensure_profile (GstVaapiEncoderVP8 * encoder)
|
||||
{
|
||||
/* Always start from "simple" profile for maximum compatibility */
|
||||
encoder->profile = GST_VAAPI_PROFILE_VP8;
|
||||
|
||||
return GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Derives the profile supported by the underlying hardware */
|
||||
static gboolean
|
||||
ensure_hw_profile (GstVaapiEncoderVP8 * encoder)
|
||||
{
|
||||
GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
|
||||
GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
|
||||
GstVaapiProfile profile, profiles[2];
|
||||
guint i, num_profiles = 0;
|
||||
|
||||
profiles[num_profiles++] = encoder->profile;
|
||||
|
||||
profile = GST_VAAPI_PROFILE_UNKNOWN;
|
||||
for (i = 0; i < num_profiles; i++) {
|
||||
if (gst_vaapi_display_has_encoder (display, profiles[i], entrypoint)) {
|
||||
profile = profiles[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (profile == GST_VAAPI_PROFILE_UNKNOWN)
|
||||
goto error_unsupported_profile;
|
||||
|
||||
GST_VAAPI_ENCODER_CAST (encoder)->profile = profile;
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
error_unsupported_profile:
|
||||
{
|
||||
GST_ERROR ("unsupported HW profile %s",
|
||||
gst_vaapi_profile_get_va_name (encoder->profile));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_bitrate (GstVaapiEncoderVP8 * encoder)
|
||||
{
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
|
||||
|
||||
/* Default compression: 64 bits per macroblock */
|
||||
switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
|
||||
case GST_VAAPI_RATECONTROL_CBR:
|
||||
case GST_VAAPI_RATECONTROL_VBR:
|
||||
if (!base_encoder->bitrate) {
|
||||
base_encoder->bitrate =
|
||||
gst_util_uint64_scale (GST_VAAPI_ENCODER_WIDTH (encoder) *
|
||||
GST_VAAPI_ENCODER_HEIGHT (encoder),
|
||||
GST_VAAPI_ENCODER_FPS_N (encoder),
|
||||
GST_VAAPI_ENCODER_FPS_D (encoder)) / (4 * 1000);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
base_encoder->bitrate = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstVaapiEncoderStatus
|
||||
set_context_info (GstVaapiEncoder * base_encoder)
|
||||
{
|
||||
GstVaapiEncoderVP8 *encoder = GST_VAAPI_ENCODER_VP8 (base_encoder);
|
||||
GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
|
||||
|
||||
/* Maximum sizes for common headers (in bytes) */
|
||||
enum
|
||||
{
|
||||
MAX_FRAME_TAG_SIZE = 10,
|
||||
MAX_UPDATE_SEGMENTATION_SIZE = 13,
|
||||
MAX_MB_LF_ADJUSTMENTS_SIZE = 9,
|
||||
MAX_QUANT_INDICES_SIZE = 5,
|
||||
MAX_TOKEN_PROB_UPDATE_SIZE = 1188,
|
||||
MAX_MV_PROBE_UPDATE_SIZE = 38,
|
||||
MAX_REST_OF_FRAME_HDR_SIZE = 15
|
||||
};
|
||||
|
||||
if (!ensure_hw_profile (encoder))
|
||||
return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
|
||||
|
||||
base_encoder->num_ref_frames = 3;
|
||||
|
||||
/* Only YUV 4:2:0 formats are supported for now. */
|
||||
/* Assumig 4 times compression ratio */
|
||||
base_encoder->codedbuf_size = GST_ROUND_UP_16 (vip->width) *
|
||||
GST_ROUND_UP_16 (vip->height) * 12 / 4;
|
||||
|
||||
base_encoder->codedbuf_size +=
|
||||
MAX_FRAME_TAG_SIZE + MAX_UPDATE_SEGMENTATION_SIZE +
|
||||
MAX_MB_LF_ADJUSTMENTS_SIZE + MAX_QUANT_INDICES_SIZE +
|
||||
MAX_TOKEN_PROB_UPDATE_SIZE + MAX_MV_PROBE_UPDATE_SIZE +
|
||||
MAX_REST_OF_FRAME_HDR_SIZE;
|
||||
|
||||
base_encoder->context_info.profile = base_encoder->profile;
|
||||
base_encoder->context_info.entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
|
||||
|
||||
return GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_ref (GstVaapiEncoderVP8 * encoder, GstVaapiSurfaceProxy ** ref)
|
||||
{
|
||||
if (*ref) {
|
||||
gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), *ref);
|
||||
*ref = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clear_references (GstVaapiEncoderVP8 * encoder)
|
||||
{
|
||||
clear_ref (encoder, &encoder->last_ref);
|
||||
clear_ref (encoder, &encoder->golden_ref);
|
||||
clear_ref (encoder, &encoder->alt_ref);
|
||||
}
|
||||
|
||||
static void
|
||||
push_reference (GstVaapiEncoderVP8 * encoder, GstVaapiSurfaceProxy * ref)
|
||||
{
|
||||
if (encoder->last_ref == NULL) {
|
||||
encoder->golden_ref = gst_vaapi_surface_proxy_ref (ref);
|
||||
encoder->alt_ref = gst_vaapi_surface_proxy_ref (ref);
|
||||
} else {
|
||||
clear_ref (encoder, &encoder->alt_ref);
|
||||
encoder->alt_ref = encoder->golden_ref;
|
||||
encoder->golden_ref = encoder->last_ref;
|
||||
}
|
||||
encoder->last_ref = ref;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fill_sequence (GstVaapiEncoderVP8 * encoder, GstVaapiEncSequence * sequence)
|
||||
{
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
|
||||
VAEncSequenceParameterBufferVP8 *const seq_param = sequence->param;
|
||||
|
||||
memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferVP8));
|
||||
|
||||
seq_param->frame_width = GST_VAAPI_ENCODER_WIDTH (encoder);
|
||||
seq_param->frame_height = GST_VAAPI_ENCODER_HEIGHT (encoder);
|
||||
|
||||
if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR ||
|
||||
GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR)
|
||||
seq_param->bits_per_second = base_encoder->bitrate * 1000;
|
||||
|
||||
seq_param->intra_period = base_encoder->keyframe_period;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_sequence (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture)
|
||||
{
|
||||
GstVaapiEncSequence *sequence;
|
||||
|
||||
g_assert (picture);
|
||||
|
||||
if (picture->type != GST_VAAPI_PICTURE_TYPE_I)
|
||||
return TRUE;
|
||||
|
||||
sequence = GST_VAAPI_ENC_SEQUENCE_NEW (VP8, encoder);
|
||||
if (!sequence)
|
||||
goto error;
|
||||
|
||||
if (!fill_sequence (encoder, sequence))
|
||||
goto error;
|
||||
|
||||
gst_vaapi_enc_picture_set_sequence (picture, sequence);
|
||||
gst_vaapi_codec_object_replace (&sequence, NULL);
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
error:
|
||||
{
|
||||
gst_vaapi_codec_object_replace (&sequence, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_control_rate_params (GstVaapiEncoderVP8 * encoder)
|
||||
{
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
|
||||
|
||||
if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP)
|
||||
return TRUE;
|
||||
|
||||
/* RateControl params */
|
||||
GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->yac_qi;
|
||||
GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = 1;
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
/* HRD params */
|
||||
GST_VAAPI_ENCODER_VA_HRD (encoder) = (VAEncMiscParameterHRD) {
|
||||
.buffer_size = base_encoder->bitrate * 1000 * 2,
|
||||
.initial_buffer_fullness = base_encoder->bitrate * 1000,
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_misc_params (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture)
|
||||
{
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
|
||||
|
||||
if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fill_picture (GstVaapiEncoderVP8 * encoder,
|
||||
GstVaapiEncPicture * picture,
|
||||
GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
|
||||
{
|
||||
VAEncPictureParameterBufferVP8 *const pic_param = picture->param;
|
||||
int i;
|
||||
|
||||
memset (pic_param, 0, sizeof (VAEncPictureParameterBufferVP8));
|
||||
|
||||
pic_param->reconstructed_frame = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
|
||||
pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf);
|
||||
|
||||
if (picture->type == GST_VAAPI_PICTURE_TYPE_P) {
|
||||
pic_param->pic_flags.bits.frame_type = 1;
|
||||
pic_param->ref_arf_frame =
|
||||
GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->alt_ref);
|
||||
pic_param->ref_gf_frame =
|
||||
GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->golden_ref);
|
||||
pic_param->ref_last_frame =
|
||||
GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->last_ref);
|
||||
pic_param->pic_flags.bits.refresh_last = 1;
|
||||
pic_param->pic_flags.bits.refresh_golden_frame = 0;
|
||||
pic_param->pic_flags.bits.copy_buffer_to_golden = 1;
|
||||
pic_param->pic_flags.bits.refresh_alternate_frame = 0;
|
||||
pic_param->pic_flags.bits.copy_buffer_to_alternate = 2;
|
||||
} else {
|
||||
pic_param->ref_last_frame = VA_INVALID_SURFACE;
|
||||
pic_param->ref_gf_frame = VA_INVALID_SURFACE;
|
||||
pic_param->ref_arf_frame = VA_INVALID_SURFACE;
|
||||
pic_param->pic_flags.bits.refresh_last = 1;
|
||||
pic_param->pic_flags.bits.refresh_golden_frame = 1;
|
||||
pic_param->pic_flags.bits.refresh_alternate_frame = 1;
|
||||
}
|
||||
|
||||
pic_param->pic_flags.bits.show_frame = 1;
|
||||
|
||||
if (encoder->loop_filter_level) {
|
||||
pic_param->pic_flags.bits.version = 1;
|
||||
pic_param->pic_flags.bits.loop_filter_type = 1; /* Enable simple loop filter */
|
||||
/* Disabled segmentation, so what matters is only loop_filter_level[0] */
|
||||
for (i = 0; i < 4; i++)
|
||||
pic_param->loop_filter_level[i] = encoder->loop_filter_level;
|
||||
}
|
||||
|
||||
pic_param->sharpness_level = encoder->sharpness_level;
|
||||
|
||||
/* Used for CBR */
|
||||
pic_param->clamp_qindex_low = 0;
|
||||
pic_param->clamp_qindex_high = 127;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_picture (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture,
|
||||
GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
|
||||
{
|
||||
GstVaapiCodedBuffer *const codedbuf =
|
||||
GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
|
||||
|
||||
if (!fill_picture (encoder, picture, codedbuf, surface))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fill_quantization_table (GstVaapiEncoderVP8 * encoder,
|
||||
GstVaapiEncPicture * picture, GstVaapiEncQMatrix * q_matrix)
|
||||
{
|
||||
VAQMatrixBufferVP8 *const qmatrix_param = q_matrix->param;
|
||||
int i;
|
||||
|
||||
memset (qmatrix_param, 0, sizeof (VAQMatrixBufferVP8));
|
||||
|
||||
/* DefaultYacQantVal = 8 for I frame, which is ac_qlookup[4] and
|
||||
* DefaultYacQantVAl = 44 for P frame, which is ac_qllookup[40] */
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (encoder->yac_qi == DEFAULT_YAC_QI) {
|
||||
if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
|
||||
qmatrix_param->quantization_index[i] = 4;
|
||||
else
|
||||
qmatrix_param->quantization_index[i] = 40;
|
||||
} else
|
||||
qmatrix_param->quantization_index[i] = encoder->yac_qi;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_quantization_table (GstVaapiEncoderVP8 * encoder,
|
||||
GstVaapiEncPicture * picture)
|
||||
{
|
||||
g_assert (picture);
|
||||
|
||||
picture->q_matrix = GST_VAAPI_ENC_Q_MATRIX_NEW (VP8, encoder);
|
||||
if (!picture->q_matrix) {
|
||||
GST_ERROR ("failed to allocate quantiser table");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
|
||||
if (!fill_quantization_table (encoder, picture, picture->q_matrix))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_vp8_encode (GstVaapiEncoder * base_encoder,
|
||||
GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
|
||||
{
|
||||
GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder);
|
||||
GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
|
||||
GstVaapiSurfaceProxy *reconstruct = NULL;
|
||||
|
||||
reconstruct = gst_vaapi_encoder_create_surface (base_encoder);
|
||||
|
||||
g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
|
||||
|
||||
if (!ensure_sequence (encoder, picture))
|
||||
goto error;
|
||||
if (!ensure_misc_params (encoder, picture))
|
||||
goto error;
|
||||
if (!ensure_picture (encoder, picture, codedbuf, reconstruct))
|
||||
goto error;
|
||||
if (!ensure_quantization_table (encoder, picture))
|
||||
goto error;
|
||||
if (!gst_vaapi_enc_picture_encode (picture))
|
||||
goto error;
|
||||
if (reconstruct) {
|
||||
if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
|
||||
clear_references (encoder);
|
||||
push_reference (encoder, reconstruct);
|
||||
}
|
||||
|
||||
return GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
|
||||
/* ERRORS */
|
||||
error:
|
||||
{
|
||||
if (reconstruct)
|
||||
gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
|
||||
reconstruct);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
static GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_vp8_flush (GstVaapiEncoder * base_encoder)
|
||||
{
|
||||
GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder);
|
||||
|
||||
encoder->frame_num = 0;
|
||||
clear_references (encoder);
|
||||
|
||||
return GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_vp8_reordering (GstVaapiEncoder * base_encoder,
|
||||
GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
|
||||
{
|
||||
GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder);
|
||||
GstVaapiEncPicture *picture = NULL;
|
||||
GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
|
||||
if (!frame)
|
||||
return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
|
||||
|
||||
picture = GST_VAAPI_ENC_PICTURE_NEW (VP8, encoder, frame);
|
||||
if (!picture) {
|
||||
GST_WARNING ("create VP8 picture failed, frame timestamp:%"
|
||||
GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
|
||||
return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
|
||||
if (encoder->frame_num >= base_encoder->keyframe_period) {
|
||||
encoder->frame_num = 0;
|
||||
clear_references (encoder);
|
||||
}
|
||||
if (encoder->frame_num == 0) {
|
||||
picture->type = GST_VAAPI_PICTURE_TYPE_I;
|
||||
GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
|
||||
} else {
|
||||
picture->type = GST_VAAPI_PICTURE_TYPE_P;
|
||||
}
|
||||
|
||||
encoder->frame_num++;
|
||||
*output = picture;
|
||||
return status;
|
||||
}
|
||||
|
||||
static GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_vp8_reconfigure (GstVaapiEncoder * base_encoder)
|
||||
{
|
||||
GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder);
|
||||
GstVaapiEncoderStatus status;
|
||||
|
||||
status = ensure_profile (encoder);
|
||||
if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
if (!ensure_bitrate (encoder))
|
||||
goto error;
|
||||
|
||||
ensure_control_rate_params (encoder);
|
||||
return set_context_info (base_encoder);
|
||||
|
||||
/* ERRORS */
|
||||
error:
|
||||
{
|
||||
return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
struct _GstVaapiEncoderVP8Class
|
||||
{
|
||||
GstVaapiEncoderClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GstVaapiEncoderVP8, gst_vaapi_encoder_vp8,
|
||||
GST_TYPE_VAAPI_ENCODER);
|
||||
|
||||
static void
|
||||
gst_vaapi_encoder_vp8_init (GstVaapiEncoderVP8 * encoder)
|
||||
{
|
||||
encoder->frame_num = 0;
|
||||
encoder->last_ref = NULL;
|
||||
encoder->golden_ref = NULL;
|
||||
encoder->alt_ref = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_encoder_vp8_finalize (GObject * object)
|
||||
{
|
||||
GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (object);
|
||||
clear_references (encoder);
|
||||
G_OBJECT_CLASS (gst_vaapi_encoder_vp8_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ENCODER_VP8_PROP_RATECONTROL: Rate control (#GstVaapiRateControl).
|
||||
* @ENCODER_VP8_PROP_TUNE: The tuning options (#GstVaapiEncoderTune).
|
||||
* @ENCODER_VP8_PROP_LOOP_FILTER_LEVEL: Loop Filter Level(uint).
|
||||
* @ENCODER_VP8_PROP_LOOP_SHARPNESS_LEVEL: Sharpness Level(uint).
|
||||
* @ENCODER_VP8_PROP_YAC_Q_INDEX: Quantization table index for luma AC(uint).
|
||||
*
|
||||
* The set of VP8 encoder specific configurable properties.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
ENCODER_VP8_PROP_RATECONTROL = 1,
|
||||
ENCODER_VP8_PROP_TUNE,
|
||||
ENCODER_VP8_PROP_LOOP_FILTER_LEVEL,
|
||||
ENCODER_VP8_PROP_SHARPNESS_LEVEL,
|
||||
ENCODER_VP8_PROP_YAC_Q_INDEX,
|
||||
ENCODER_VP8_N_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[ENCODER_VP8_N_PROPERTIES];
|
||||
|
||||
static void
|
||||
gst_vaapi_encoder_vp8_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object);
|
||||
GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (object);
|
||||
|
||||
if (base_encoder->num_codedbuf_queued > 0) {
|
||||
GST_ERROR_OBJECT (object,
|
||||
"failed to set any property after encoding started");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (prop_id) {
|
||||
case ENCODER_VP8_PROP_RATECONTROL:
|
||||
gst_vaapi_encoder_set_rate_control (base_encoder,
|
||||
g_value_get_enum (value));
|
||||
break;
|
||||
case ENCODER_VP8_PROP_TUNE:
|
||||
gst_vaapi_encoder_set_tuning (base_encoder, g_value_get_enum (value));
|
||||
break;
|
||||
case ENCODER_VP8_PROP_LOOP_FILTER_LEVEL:
|
||||
encoder->loop_filter_level = g_value_get_uint (value);
|
||||
break;
|
||||
case ENCODER_VP8_PROP_SHARPNESS_LEVEL:
|
||||
encoder->sharpness_level = g_value_get_uint (value);
|
||||
break;
|
||||
case ENCODER_VP8_PROP_YAC_Q_INDEX:
|
||||
encoder->yac_qi = g_value_get_uint (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_encoder_vp8_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (object);
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ENCODER_VP8_PROP_RATECONTROL:
|
||||
g_value_set_enum (value, base_encoder->rate_control);
|
||||
break;
|
||||
case ENCODER_VP8_PROP_TUNE:
|
||||
g_value_set_enum (value, base_encoder->tune);
|
||||
break;
|
||||
case ENCODER_VP8_PROP_LOOP_FILTER_LEVEL:
|
||||
g_value_set_uint (value, encoder->loop_filter_level);
|
||||
break;
|
||||
case ENCODER_VP8_PROP_SHARPNESS_LEVEL:
|
||||
g_value_set_uint (value, encoder->sharpness_level);
|
||||
break;
|
||||
case ENCODER_VP8_PROP_YAC_Q_INDEX:
|
||||
g_value_set_uint (value, encoder->yac_qi);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (VP8);
|
||||
|
||||
static void
|
||||
gst_vaapi_encoder_vp8_class_init (GstVaapiEncoderVP8Class * klass)
|
||||
{
|
||||
GObjectClass *const object_class = G_OBJECT_CLASS (klass);
|
||||
GstVaapiEncoderClass *const encoder_class = GST_VAAPI_ENCODER_CLASS (klass);
|
||||
|
||||
encoder_class->class_data = &g_class_data;
|
||||
encoder_class->reconfigure = gst_vaapi_encoder_vp8_reconfigure;
|
||||
encoder_class->reordering = gst_vaapi_encoder_vp8_reordering;
|
||||
encoder_class->encode = gst_vaapi_encoder_vp8_encode;
|
||||
encoder_class->flush = gst_vaapi_encoder_vp8_flush;
|
||||
|
||||
object_class->set_property = gst_vaapi_encoder_vp8_set_property;
|
||||
object_class->get_property = gst_vaapi_encoder_vp8_get_property;
|
||||
object_class->finalize = gst_vaapi_encoder_vp8_finalize;
|
||||
|
||||
properties[ENCODER_VP8_PROP_RATECONTROL] =
|
||||
g_param_spec_enum ("rate-control",
|
||||
"Rate Control", "Rate control mode",
|
||||
g_class_data.rate_control_get_type (),
|
||||
g_class_data.default_rate_control,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
|
||||
GST_VAAPI_PARAM_ENCODER_EXPOSURE);
|
||||
|
||||
properties[ENCODER_VP8_PROP_TUNE] =
|
||||
g_param_spec_enum ("tune", "Encoder Tuning", "Encoder tuning option",
|
||||
g_class_data.encoder_tune_get_type (),
|
||||
g_class_data.default_encoder_tune,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
|
||||
GST_VAAPI_PARAM_ENCODER_EXPOSURE);
|
||||
|
||||
properties[ENCODER_VP8_PROP_LOOP_FILTER_LEVEL] =
|
||||
g_param_spec_uint ("loop-filter-level", "Loop Filter Level",
|
||||
"Controls the deblocking filter strength", 0, 63,
|
||||
DEFAULT_LOOP_FILTER_LEVEL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
|
||||
GST_VAAPI_PARAM_ENCODER_EXPOSURE);
|
||||
|
||||
properties[ENCODER_VP8_PROP_SHARPNESS_LEVEL] =
|
||||
g_param_spec_uint ("sharpness-level", "Sharpness Level",
|
||||
"Controls the deblocking filter sensitivity", 0, 7,
|
||||
DEFAULT_SHARPNESS_LEVEL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
|
||||
GST_VAAPI_PARAM_ENCODER_EXPOSURE);
|
||||
|
||||
properties[ENCODER_VP8_PROP_YAC_Q_INDEX] =
|
||||
g_param_spec_uint ("yac-qi",
|
||||
"Luma AC Quant Table index",
|
||||
"Quantization Table index for Luma AC Coefficients,"
|
||||
" (in default case, yac_qi=4 for key frames and yac_qi=40"
|
||||
" for P frames)",
|
||||
0, 127, DEFAULT_YAC_QI,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
|
||||
GST_VAAPI_PARAM_ENCODER_EXPOSURE);
|
||||
|
||||
g_object_class_install_properties (object_class, ENCODER_VP8_N_PROPERTIES,
|
||||
properties);
|
||||
|
||||
gst_type_mark_as_plugin_api (g_class_data.rate_control_get_type (), 0);
|
||||
gst_type_mark_as_plugin_api (g_class_data.encoder_tune_get_type (), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_encoder_vp8_new:
|
||||
* @display: a #GstVaapiDisplay
|
||||
*
|
||||
* Creates a new #GstVaapiEncoder for VP8 encoding.
|
||||
*
|
||||
* Return value: the newly allocated #GstVaapiEncoder object
|
||||
*/
|
||||
GstVaapiEncoder *
|
||||
gst_vaapi_encoder_vp8_new (GstVaapiDisplay * display)
|
||||
{
|
||||
return g_object_new (GST_TYPE_VAAPI_ENCODER_VP8, "display", display, NULL);
|
||||
}
|
49
gst-libs/gst/vaapi/gstvaapiencoder_vp8.h
Normal file
49
gst-libs/gst/vaapi/gstvaapiencoder_vp8.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* gstvaapiencoder_vp8.h VP8G encoder
|
||||
*
|
||||
* Copyright (C) 2015 Intel Corporation
|
||||
* Author: Sreerenj Balachandran <sreerenj.balachandran@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_ENCODER_VP8_H
|
||||
#define GST_VAAPI_ENCODER_VP8_H
|
||||
|
||||
#include <gst/vaapi/gstvaapiencoder.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_ENCODER_VP8 \
|
||||
(gst_vaapi_encoder_vp8_get_type ())
|
||||
#define GST_VAAPI_ENCODER_VP8(encoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((encoder), GST_TYPE_VAAPI_ENCODER_VP8, GstVaapiEncoderVP8))
|
||||
#define GST_IS_VAAPI_ENCODER_VP8(encoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((encoder), GST_TYPE_VAAPI_ENCODER_VP8))
|
||||
|
||||
typedef struct _GstVaapiEncoderVP8 GstVaapiEncoderVP8;
|
||||
typedef struct _GstVaapiEncoderVP8Class GstVaapiEncoderVP8Class;
|
||||
|
||||
GType
|
||||
gst_vaapi_encoder_vp8_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GstVaapiEncoder *
|
||||
gst_vaapi_encoder_vp8_new (GstVaapiDisplay * display);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiEncoderVP8, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
#endif /*GST_VAAPI_ENCODER_VP8_H */
|
824
gst-libs/gst/vaapi/gstvaapiencoder_vp9.c
Normal file
824
gst-libs/gst/vaapi/gstvaapiencoder_vp9.c
Normal file
|
@ -0,0 +1,824 @@
|
|||
/*
|
||||
* gstvaapiencoder_vp9.c - VP9 encoder
|
||||
*
|
||||
* Copyright (C) 2016 Intel Corporation
|
||||
* Author: Sreerenj Balachandran <sreerenj.balachandran@intel.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; 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include <gst/base/gstbitwriter.h>
|
||||
#include <gst/codecparsers/gstvp9parser.h>
|
||||
#include "gstvaapicompat.h"
|
||||
#include "gstvaapiencoder_priv.h"
|
||||
#include "gstvaapiencoder_vp9.h"
|
||||
#include "gstvaapicodedbufferproxy_priv.h"
|
||||
#include "gstvaapisurface.h"
|
||||
#include "gstvaapiutils_vpx.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
#define MAX_TILE_WIDTH_B64 64
|
||||
|
||||
/* Define default rate control mode ("constant-qp") */
|
||||
#define DEFAULT_RATECONTROL GST_VAAPI_RATECONTROL_CQP
|
||||
|
||||
/* Supported set of VA rate controls, within this implementation */
|
||||
#define SUPPORTED_RATECONTROLS \
|
||||
(GST_VAAPI_RATECONTROL_MASK (CQP) | \
|
||||
GST_VAAPI_RATECONTROL_MASK (CBR) | \
|
||||
GST_VAAPI_RATECONTROL_MASK (VBR))
|
||||
|
||||
/* Supported set of tuning options, within this implementation */
|
||||
#define SUPPORTED_TUNE_OPTIONS \
|
||||
(GST_VAAPI_ENCODER_TUNE_MASK (NONE) | \
|
||||
GST_VAAPI_ENCODER_TUNE_MASK (LOW_POWER))
|
||||
|
||||
/* Supported set of VA packed headers, within this implementation */
|
||||
#define SUPPORTED_PACKED_HEADERS \
|
||||
(VA_ENC_PACKED_HEADER_NONE)
|
||||
|
||||
#define DEFAULT_LOOP_FILTER_LEVEL 10
|
||||
#define DEFAULT_SHARPNESS_LEVEL 0
|
||||
#define DEFAULT_YAC_QINDEX 60
|
||||
|
||||
#define MAX_FRAME_WIDTH 4096
|
||||
#define MAX_FRAME_HEIGHT 4096
|
||||
|
||||
/* Default CPB length (in milliseconds) */
|
||||
#define DEFAULT_CPB_LENGTH 1500
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GST_VAAPI_ENCODER_VP9_REF_PIC_MODE_0 = 0,
|
||||
GST_VAAPI_ENCODER_VP9_REF_PIC_MODE_1 = 1
|
||||
} GstVaapiEnoderVP9RefPicMode;
|
||||
|
||||
static GType
|
||||
gst_vaapi_encoder_vp9_ref_pic_mode_type (void)
|
||||
{
|
||||
static GType gtype = 0;
|
||||
|
||||
if (gtype == 0) {
|
||||
static const GEnumValue values[] = {
|
||||
{GST_VAAPI_ENCODER_VP9_REF_PIC_MODE_0,
|
||||
"Use Keyframe(Alt & Gold) and Previousframe(Last) for prediction ",
|
||||
"mode-0"},
|
||||
{GST_VAAPI_ENCODER_VP9_REF_PIC_MODE_1,
|
||||
"Use last three frames for prediction (n:Last n-1:Gold n-2:Alt)",
|
||||
"mode-1"},
|
||||
{0, NULL, NULL},
|
||||
};
|
||||
|
||||
gtype = g_enum_register_static ("GstVaapiEncoderVP9RefPicMode", values);
|
||||
}
|
||||
return gtype;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- VP9 Encoder --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
struct _GstVaapiEncoderVP9
|
||||
{
|
||||
GstVaapiEncoder parent_instance;
|
||||
GstVaapiProfile profile;
|
||||
guint loop_filter_level;
|
||||
guint sharpness_level;
|
||||
guint yac_qi;
|
||||
guint ref_pic_mode;
|
||||
guint frame_num;
|
||||
GstVaapiSurfaceProxy *ref_list[GST_VP9_REF_FRAMES]; /* reference list */
|
||||
guint ref_list_idx; /* next free slot in ref_list */
|
||||
GstVaapiEntrypoint entrypoint;
|
||||
GArray *allowed_profiles;
|
||||
|
||||
/* Bitrate contral parameters, CPB = Coded Picture Buffer */
|
||||
guint bitrate_bits; /* bitrate (bits) */
|
||||
guint cpb_length; /* length of CPB buffer (ms) */
|
||||
};
|
||||
|
||||
/* Estimates a good enough bitrate if none was supplied */
|
||||
static void
|
||||
ensure_bitrate (GstVaapiEncoderVP9 * encoder)
|
||||
{
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
|
||||
guint bitrate;
|
||||
|
||||
switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
|
||||
case GST_VAAPI_RATECONTROL_CBR:
|
||||
case GST_VAAPI_RATECONTROL_VBR:
|
||||
if (!base_encoder->bitrate) {
|
||||
/* FIXME: Provide better estimation */
|
||||
/* Using a 1/6 compression ratio */
|
||||
/* 12 bits per pixel fro yuv420 */
|
||||
base_encoder->bitrate =
|
||||
(GST_VAAPI_ENCODER_WIDTH (encoder) *
|
||||
GST_VAAPI_ENCODER_HEIGHT (encoder) * 12 / 6) *
|
||||
GST_VAAPI_ENCODER_FPS_N (encoder) /
|
||||
GST_VAAPI_ENCODER_FPS_D (encoder) / 1000;
|
||||
GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate);
|
||||
}
|
||||
|
||||
bitrate = (base_encoder->bitrate * 1000);
|
||||
if (bitrate != encoder->bitrate_bits) {
|
||||
GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate);
|
||||
encoder->bitrate_bits = bitrate;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
base_encoder->bitrate = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_profile_allowed (GstVaapiEncoderVP9 * encoder, GstVaapiProfile profile)
|
||||
{
|
||||
guint i;
|
||||
|
||||
if (encoder->allowed_profiles == NULL)
|
||||
return TRUE;
|
||||
|
||||
for (i = 0; i < encoder->allowed_profiles->len; i++)
|
||||
if (profile ==
|
||||
g_array_index (encoder->allowed_profiles, GstVaapiProfile, i))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Derives the profile that suits best to the configuration */
|
||||
static GstVaapiEncoderStatus
|
||||
ensure_profile (GstVaapiEncoderVP9 * encoder)
|
||||
{
|
||||
const GstVideoFormat format =
|
||||
GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder));
|
||||
guint depth, chrome;
|
||||
|
||||
if (!GST_VIDEO_FORMAT_INFO_IS_YUV (gst_video_format_get_info (format)))
|
||||
return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
|
||||
|
||||
depth = GST_VIDEO_FORMAT_INFO_DEPTH (gst_video_format_get_info (format), 0);
|
||||
chrome = gst_vaapi_utils_vp9_get_chroma_format_idc
|
||||
(gst_vaapi_video_format_get_chroma_type
|
||||
(GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder))));
|
||||
|
||||
encoder->profile = GST_VAAPI_PROFILE_UNKNOWN;
|
||||
/*
|
||||
Profile Color | Depth Chroma | Subsampling
|
||||
0 | 8 bit/sample | 4:2:0
|
||||
1 | 8 bit | 4:2:2, 4:4:4
|
||||
2 | 10 or 12 bit | 4:2:0
|
||||
3 | 10 or 12 bit | 4:2:2, 4:4:4 */
|
||||
if (chrome == 3 || chrome == 2) {
|
||||
/* 4:4:4 and 4:2:2 */
|
||||
if (depth == 8) {
|
||||
encoder->profile = GST_VAAPI_PROFILE_VP9_1;
|
||||
} else if (depth == 10 || depth == 12) {
|
||||
encoder->profile = GST_VAAPI_PROFILE_VP9_3;
|
||||
}
|
||||
} else if (chrome == 1) {
|
||||
/* 4:2:0 */
|
||||
if (depth == 8) {
|
||||
encoder->profile = GST_VAAPI_PROFILE_VP9_0;
|
||||
} else if (depth == 10 || depth == 12) {
|
||||
encoder->profile = GST_VAAPI_PROFILE_VP9_2;
|
||||
}
|
||||
}
|
||||
|
||||
if (encoder->profile == GST_VAAPI_PROFILE_UNKNOWN) {
|
||||
GST_WARNING ("Failed to decide VP9 profile");
|
||||
return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
|
||||
}
|
||||
|
||||
if (!is_profile_allowed (encoder, encoder->profile)) {
|
||||
GST_WARNING ("Failed to find an allowed VP9 profile");
|
||||
return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
|
||||
}
|
||||
|
||||
/* Ensure bitrate if not set already */
|
||||
ensure_bitrate (encoder);
|
||||
return GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiEncoderStatus
|
||||
set_context_info (GstVaapiEncoder * base_encoder)
|
||||
{
|
||||
GstVaapiEncoderVP9 *encoder = GST_VAAPI_ENCODER_VP9 (base_encoder);
|
||||
GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
|
||||
const guint DEFAULT_SURFACES_COUNT = 2;
|
||||
|
||||
/* FIXME: Maximum sizes for common headers (in bytes) */
|
||||
|
||||
GST_VAAPI_ENCODER_CAST (encoder)->profile = encoder->profile;
|
||||
|
||||
base_encoder->num_ref_frames = 3 + DEFAULT_SURFACES_COUNT;
|
||||
|
||||
/* Only YUV 4:2:0 formats are supported for now. */
|
||||
base_encoder->codedbuf_size = GST_ROUND_UP_16 (vip->width) *
|
||||
GST_ROUND_UP_16 (vip->height) * 3 / 2;
|
||||
|
||||
base_encoder->context_info.profile = base_encoder->profile;
|
||||
base_encoder->context_info.entrypoint = encoder->entrypoint;
|
||||
|
||||
return GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fill_sequence (GstVaapiEncoderVP9 * encoder, GstVaapiEncSequence * sequence)
|
||||
{
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
|
||||
VAEncSequenceParameterBufferVP9 *const seq_param = sequence->param;
|
||||
|
||||
memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferVP9));
|
||||
|
||||
seq_param->max_frame_width = MAX_FRAME_WIDTH;
|
||||
seq_param->max_frame_height = MAX_FRAME_HEIGHT;
|
||||
|
||||
/* keyframe minimum interval */
|
||||
seq_param->kf_min_dist = 1;
|
||||
/* keyframe maximum interval */
|
||||
seq_param->kf_max_dist = base_encoder->keyframe_period;
|
||||
seq_param->intra_period = base_encoder->keyframe_period;
|
||||
seq_param->bits_per_second = encoder->bitrate_bits;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_sequence (GstVaapiEncoderVP9 * encoder, GstVaapiEncPicture * picture)
|
||||
{
|
||||
GstVaapiEncSequence *sequence;
|
||||
|
||||
g_assert (picture);
|
||||
|
||||
if (picture->type != GST_VAAPI_PICTURE_TYPE_I)
|
||||
return TRUE;
|
||||
|
||||
sequence = GST_VAAPI_ENC_SEQUENCE_NEW (VP9, encoder);
|
||||
if (!sequence)
|
||||
goto error;
|
||||
|
||||
if (!fill_sequence (encoder, sequence))
|
||||
goto error;
|
||||
|
||||
gst_vaapi_enc_picture_set_sequence (picture, sequence);
|
||||
gst_vaapi_codec_object_replace (&sequence, NULL);
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
error:
|
||||
{
|
||||
gst_vaapi_codec_object_replace (&sequence, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_control_rate_params (GstVaapiEncoderVP9 * encoder)
|
||||
{
|
||||
if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP)
|
||||
return TRUE;
|
||||
|
||||
/* RateControl params */
|
||||
GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).bits_per_second =
|
||||
encoder->bitrate_bits;
|
||||
GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).window_size = encoder->cpb_length;
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
/* HRD params */
|
||||
GST_VAAPI_ENCODER_VA_HRD (encoder) = (VAEncMiscParameterHRD) {
|
||||
.buffer_size = encoder->bitrate_bits * 2,
|
||||
.initial_buffer_fullness = encoder->bitrate_bits,
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_misc_params (GstVaapiEncoderVP9 * encoder, GstVaapiEncPicture * picture)
|
||||
{
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
|
||||
|
||||
if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture))
|
||||
return FALSE;
|
||||
if (!gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
get_ref_indices (guint ref_pic_mode, guint ref_list_idx, guint * last_idx,
|
||||
guint * gf_idx, guint * arf_idx, guint8 * refresh_frame_flags)
|
||||
{
|
||||
if (ref_pic_mode == GST_VAAPI_ENCODER_VP9_REF_PIC_MODE_0) {
|
||||
*last_idx = ref_list_idx - 1;
|
||||
*gf_idx = 1;
|
||||
*arf_idx = 2;
|
||||
*refresh_frame_flags = 0x01;
|
||||
} else if (ref_pic_mode == GST_VAAPI_ENCODER_VP9_REF_PIC_MODE_1) {
|
||||
gint last_filled_idx = (ref_list_idx - 1) & (GST_VP9_REF_FRAMES - 1);
|
||||
|
||||
*last_idx = last_filled_idx;
|
||||
*gf_idx = (last_filled_idx - 1) & (GST_VP9_REF_FRAMES - 1);
|
||||
*arf_idx = (last_filled_idx - 2) & (GST_VP9_REF_FRAMES - 1);
|
||||
|
||||
*refresh_frame_flags = 1 << ((*last_idx + 1) % GST_VP9_REF_FRAMES);
|
||||
}
|
||||
|
||||
GST_LOG
|
||||
("last_ref_idx:%d gold_ref_idx:%d alt_reff_idx:%d refesh_frame_flag:%x",
|
||||
*last_idx, *gf_idx, *arf_idx, *refresh_frame_flags);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fill_picture (GstVaapiEncoderVP9 * encoder,
|
||||
GstVaapiEncPicture * picture,
|
||||
GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
|
||||
{
|
||||
VAEncPictureParameterBufferVP9 *const pic_param = picture->param;
|
||||
guint i, last_idx = 0, gf_idx = 0, arf_idx = 0;
|
||||
guint8 refresh_frame_flags = 0;
|
||||
gint sb_cols = 0, min_log2_tile_columns = 0;
|
||||
|
||||
memset (pic_param, 0, sizeof (VAEncPictureParameterBufferVP9));
|
||||
|
||||
pic_param->reconstructed_frame = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
|
||||
pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf);
|
||||
|
||||
/* Update Reference Frame list */
|
||||
if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
|
||||
memset (pic_param->reference_frames, 0xFF,
|
||||
sizeof (pic_param->reference_frames));
|
||||
else {
|
||||
for (i = 0; i < G_N_ELEMENTS (pic_param->reference_frames); i++) {
|
||||
pic_param->reference_frames[i] =
|
||||
GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->ref_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* It is possible to have dynamic scaling with gpu by providing
|
||||
* src and destination resoltuion. For now we are just using
|
||||
* default encoder width and height */
|
||||
pic_param->frame_width_src = GST_VAAPI_ENCODER_WIDTH (encoder);
|
||||
pic_param->frame_height_src = GST_VAAPI_ENCODER_HEIGHT (encoder);
|
||||
pic_param->frame_width_dst = GST_VAAPI_ENCODER_WIDTH (encoder);
|
||||
pic_param->frame_height_dst = GST_VAAPI_ENCODER_HEIGHT (encoder);
|
||||
|
||||
pic_param->pic_flags.bits.show_frame = 1;
|
||||
|
||||
if (picture->type == GST_VAAPI_PICTURE_TYPE_P) {
|
||||
pic_param->pic_flags.bits.frame_type = GST_VP9_INTER_FRAME;
|
||||
|
||||
/* use three of the reference frames (last, golden and altref)
|
||||
* for prediction */
|
||||
pic_param->ref_flags.bits.ref_frame_ctrl_l0 = 0x7;
|
||||
|
||||
get_ref_indices (encoder->ref_pic_mode, encoder->ref_list_idx, &last_idx,
|
||||
&gf_idx, &arf_idx, &refresh_frame_flags);
|
||||
|
||||
pic_param->ref_flags.bits.ref_last_idx = last_idx;
|
||||
pic_param->ref_flags.bits.ref_gf_idx = gf_idx;
|
||||
pic_param->ref_flags.bits.ref_arf_idx = arf_idx;
|
||||
pic_param->refresh_frame_flags = refresh_frame_flags;
|
||||
}
|
||||
|
||||
/* Maximum width of a tile in units of superblocks is MAX_TILE_WIDTH_B64(64).
|
||||
* When the width is enough to partition more than MAX_TILE_WIDTH_B64(64) superblocks,
|
||||
* we need multi tiles to handle it.*/
|
||||
sb_cols = (pic_param->frame_width_src + 63) / 64;
|
||||
while ((MAX_TILE_WIDTH_B64 << min_log2_tile_columns) < sb_cols)
|
||||
++min_log2_tile_columns;
|
||||
pic_param->log2_tile_columns = min_log2_tile_columns;
|
||||
|
||||
pic_param->luma_ac_qindex = encoder->yac_qi;
|
||||
pic_param->luma_dc_qindex_delta = 1;
|
||||
pic_param->chroma_ac_qindex_delta = 1;
|
||||
pic_param->chroma_dc_qindex_delta = 1;
|
||||
pic_param->filter_level = encoder->loop_filter_level;
|
||||
pic_param->sharpness_level = encoder->sharpness_level;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_picture (GstVaapiEncoderVP9 * encoder, GstVaapiEncPicture * picture,
|
||||
GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
|
||||
{
|
||||
GstVaapiCodedBuffer *const codedbuf =
|
||||
GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
|
||||
|
||||
if (!fill_picture (encoder, picture, codedbuf, surface))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
update_ref_list (GstVaapiEncoderVP9 * encoder, GstVaapiEncPicture * picture,
|
||||
GstVaapiSurfaceProxy * ref)
|
||||
{
|
||||
guint i;
|
||||
|
||||
if (picture->type == GST_VAAPI_PICTURE_TYPE_I) {
|
||||
for (i = 0; i < G_N_ELEMENTS (encoder->ref_list); i++)
|
||||
gst_vaapi_surface_proxy_replace (&encoder->ref_list[i], ref);
|
||||
gst_vaapi_surface_proxy_unref (ref);
|
||||
/* set next free slot index */
|
||||
encoder->ref_list_idx = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (encoder->ref_pic_mode) {
|
||||
case GST_VAAPI_ENCODER_VP9_REF_PIC_MODE_0:
|
||||
gst_vaapi_surface_proxy_replace (&encoder->ref_list[0], ref);
|
||||
gst_vaapi_surface_proxy_unref (ref);
|
||||
break;
|
||||
case GST_VAAPI_ENCODER_VP9_REF_PIC_MODE_1:
|
||||
i = encoder->ref_list_idx;
|
||||
gst_vaapi_surface_proxy_replace (&encoder->ref_list[i], ref);
|
||||
gst_vaapi_surface_proxy_unref (ref);
|
||||
encoder->ref_list_idx = (encoder->ref_list_idx + 1) % GST_VP9_REF_FRAMES;
|
||||
break;
|
||||
default:
|
||||
g_assert ("Code shouldn't reach here");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_vp9_encode (GstVaapiEncoder * base_encoder,
|
||||
GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
|
||||
{
|
||||
GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9 (base_encoder);
|
||||
GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
|
||||
GstVaapiSurfaceProxy *reconstruct = NULL;
|
||||
|
||||
reconstruct = gst_vaapi_encoder_create_surface (base_encoder);
|
||||
|
||||
g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
|
||||
|
||||
if (!ensure_sequence (encoder, picture))
|
||||
goto error;
|
||||
if (!ensure_misc_params (encoder, picture))
|
||||
goto error;
|
||||
if (!ensure_picture (encoder, picture, codedbuf, reconstruct))
|
||||
goto error;
|
||||
if (!gst_vaapi_enc_picture_encode (picture))
|
||||
goto error;
|
||||
|
||||
update_ref_list (encoder, picture, reconstruct);
|
||||
|
||||
return GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
|
||||
/* ERRORS */
|
||||
error:
|
||||
{
|
||||
if (reconstruct)
|
||||
gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
|
||||
reconstruct);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
static GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_vp9_flush (GstVaapiEncoder * base_encoder)
|
||||
{
|
||||
GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9 (base_encoder);
|
||||
|
||||
encoder->frame_num = 0;
|
||||
|
||||
return GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_vp9_reordering (GstVaapiEncoder * base_encoder,
|
||||
GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
|
||||
{
|
||||
GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9 (base_encoder);
|
||||
GstVaapiEncPicture *picture = NULL;
|
||||
GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
|
||||
if (!frame)
|
||||
return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
|
||||
|
||||
picture = GST_VAAPI_ENC_PICTURE_NEW (VP9, encoder, frame);
|
||||
if (!picture) {
|
||||
GST_WARNING ("create VP9 picture failed, frame timestamp:%"
|
||||
GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
|
||||
return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
|
||||
if (encoder->frame_num >= base_encoder->keyframe_period) {
|
||||
encoder->frame_num = 0;
|
||||
}
|
||||
if (encoder->frame_num == 0) {
|
||||
picture->type = GST_VAAPI_PICTURE_TYPE_I;
|
||||
GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
|
||||
} else {
|
||||
picture->type = GST_VAAPI_PICTURE_TYPE_P;
|
||||
}
|
||||
|
||||
encoder->frame_num++;
|
||||
*output = picture;
|
||||
return status;
|
||||
}
|
||||
|
||||
static GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_vp9_reconfigure (GstVaapiEncoder * base_encoder)
|
||||
{
|
||||
GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9 (base_encoder);
|
||||
GstVaapiEncoderStatus status;
|
||||
|
||||
status = ensure_profile (encoder);
|
||||
if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
encoder->entrypoint =
|
||||
gst_vaapi_encoder_get_entrypoint (base_encoder, encoder->profile);
|
||||
if (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_INVALID) {
|
||||
GST_WARNING ("Cannot find valid profile/entrypoint pair");
|
||||
return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
|
||||
}
|
||||
|
||||
ensure_control_rate_params (encoder);
|
||||
return set_context_info (base_encoder);
|
||||
}
|
||||
|
||||
|
||||
struct _GstVaapiEncoderVP9Class
|
||||
{
|
||||
GstVaapiEncoderClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GstVaapiEncoderVP9, gst_vaapi_encoder_vp9,
|
||||
GST_TYPE_VAAPI_ENCODER);
|
||||
|
||||
static void
|
||||
gst_vaapi_encoder_vp9_init (GstVaapiEncoderVP9 * encoder)
|
||||
{
|
||||
encoder->frame_num = 0;
|
||||
encoder->loop_filter_level = DEFAULT_LOOP_FILTER_LEVEL;
|
||||
encoder->sharpness_level = DEFAULT_SHARPNESS_LEVEL;
|
||||
encoder->yac_qi = DEFAULT_YAC_QINDEX;
|
||||
encoder->cpb_length = DEFAULT_CPB_LENGTH;
|
||||
encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
|
||||
|
||||
memset (encoder->ref_list, 0,
|
||||
G_N_ELEMENTS (encoder->ref_list) * sizeof (encoder->ref_list[0]));
|
||||
encoder->ref_list_idx = 0;
|
||||
|
||||
encoder->allowed_profiles = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_encoder_vp9_finalize (GObject * object)
|
||||
{
|
||||
GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9 (object);
|
||||
|
||||
if (encoder->allowed_profiles)
|
||||
g_array_unref (encoder->allowed_profiles);
|
||||
|
||||
G_OBJECT_CLASS (gst_vaapi_encoder_vp9_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ENCODER_VP9_PROP_RATECONTROL: Rate control (#GstVaapiRateControl).
|
||||
* @ENCODER_VP9_PROP_TUNE: The tuning options (#GstVaapiEncoderTune).
|
||||
* @ENCODER_VP9_PROP_LOOP_FILTER_LEVEL: Loop Filter Level(uint).
|
||||
* @ENCODER_VP9_PROP_LOOP_SHARPNESS_LEVEL: Sharpness Level(uint).
|
||||
* @ENCODER_VP9_PROP_YAC_Q_INDEX: Quantization table index for luma AC
|
||||
* @ENCODER_VP9_PROP_REF_PIC_MODE: Reference picute selection modes
|
||||
* @ENCODER_VP9_PROP_CPB_LENGTH:Length of CPB buffer in milliseconds
|
||||
*
|
||||
* The set of VP9 encoder specific configurable properties.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
ENCODER_VP9_PROP_RATECONTROL = 1,
|
||||
ENCODER_VP9_PROP_TUNE,
|
||||
ENCODER_VP9_PROP_LOOP_FILTER_LEVEL,
|
||||
ENCODER_VP9_PROP_SHARPNESS_LEVEL,
|
||||
ENCODER_VP9_PROP_YAC_Q_INDEX,
|
||||
ENCODER_VP9_PROP_REF_PIC_MODE,
|
||||
ENCODER_VP9_PROP_CPB_LENGTH,
|
||||
ENCODER_VP9_N_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[ENCODER_VP9_N_PROPERTIES];
|
||||
|
||||
static void
|
||||
gst_vaapi_encoder_vp9_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object);
|
||||
GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9 (object);
|
||||
|
||||
if (base_encoder->num_codedbuf_queued > 0) {
|
||||
GST_ERROR_OBJECT (object,
|
||||
"failed to set any property after encoding started");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (prop_id) {
|
||||
case ENCODER_VP9_PROP_RATECONTROL:
|
||||
gst_vaapi_encoder_set_rate_control (base_encoder,
|
||||
g_value_get_enum (value));
|
||||
break;
|
||||
case ENCODER_VP9_PROP_TUNE:
|
||||
gst_vaapi_encoder_set_tuning (base_encoder, g_value_get_enum (value));
|
||||
break;
|
||||
case ENCODER_VP9_PROP_LOOP_FILTER_LEVEL:
|
||||
encoder->loop_filter_level = g_value_get_uint (value);
|
||||
break;
|
||||
case ENCODER_VP9_PROP_SHARPNESS_LEVEL:
|
||||
encoder->sharpness_level = g_value_get_uint (value);
|
||||
break;
|
||||
case ENCODER_VP9_PROP_YAC_Q_INDEX:
|
||||
encoder->yac_qi = g_value_get_uint (value);
|
||||
break;
|
||||
case ENCODER_VP9_PROP_REF_PIC_MODE:
|
||||
encoder->ref_pic_mode = g_value_get_enum (value);
|
||||
break;
|
||||
case ENCODER_VP9_PROP_CPB_LENGTH:
|
||||
encoder->cpb_length = g_value_get_uint (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_encoder_vp9_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9 (object);
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ENCODER_VP9_PROP_RATECONTROL:
|
||||
g_value_set_enum (value, base_encoder->rate_control);
|
||||
break;
|
||||
case ENCODER_VP9_PROP_TUNE:
|
||||
g_value_set_enum (value, base_encoder->tune);
|
||||
break;
|
||||
case ENCODER_VP9_PROP_LOOP_FILTER_LEVEL:
|
||||
g_value_set_uint (value, encoder->loop_filter_level);
|
||||
break;
|
||||
case ENCODER_VP9_PROP_SHARPNESS_LEVEL:
|
||||
g_value_set_uint (value, encoder->sharpness_level);
|
||||
break;
|
||||
case ENCODER_VP9_PROP_YAC_Q_INDEX:
|
||||
g_value_set_uint (value, encoder->yac_qi);
|
||||
break;
|
||||
case ENCODER_VP9_PROP_REF_PIC_MODE:
|
||||
g_value_set_enum (value, encoder->ref_pic_mode);
|
||||
break;
|
||||
case ENCODER_VP9_PROP_CPB_LENGTH:
|
||||
g_value_set_uint (value, encoder->cpb_length);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (VP9);
|
||||
|
||||
static void
|
||||
gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass)
|
||||
{
|
||||
GObjectClass *const object_class = G_OBJECT_CLASS (klass);
|
||||
GstVaapiEncoderClass *const encoder_class = GST_VAAPI_ENCODER_CLASS (klass);
|
||||
|
||||
encoder_class->class_data = &g_class_data;
|
||||
encoder_class->reconfigure = gst_vaapi_encoder_vp9_reconfigure;
|
||||
encoder_class->reordering = gst_vaapi_encoder_vp9_reordering;
|
||||
encoder_class->encode = gst_vaapi_encoder_vp9_encode;
|
||||
encoder_class->flush = gst_vaapi_encoder_vp9_flush;
|
||||
|
||||
object_class->set_property = gst_vaapi_encoder_vp9_set_property;
|
||||
object_class->get_property = gst_vaapi_encoder_vp9_get_property;
|
||||
object_class->finalize = gst_vaapi_encoder_vp9_finalize;
|
||||
|
||||
properties[ENCODER_VP9_PROP_RATECONTROL] =
|
||||
g_param_spec_enum ("rate-control",
|
||||
"Rate Control", "Rate control mode",
|
||||
g_class_data.rate_control_get_type (),
|
||||
g_class_data.default_rate_control,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
|
||||
GST_VAAPI_PARAM_ENCODER_EXPOSURE);
|
||||
|
||||
properties[ENCODER_VP9_PROP_TUNE] =
|
||||
g_param_spec_enum ("tune",
|
||||
"Encoder Tuning",
|
||||
"Encoder tuning option",
|
||||
g_class_data.encoder_tune_get_type (),
|
||||
g_class_data.default_encoder_tune,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
|
||||
GST_VAAPI_PARAM_ENCODER_EXPOSURE);
|
||||
|
||||
properties[ENCODER_VP9_PROP_LOOP_FILTER_LEVEL] =
|
||||
g_param_spec_uint ("loop-filter-level",
|
||||
"Loop Filter Level",
|
||||
"Controls the deblocking filter strength",
|
||||
0, 63, DEFAULT_LOOP_FILTER_LEVEL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
|
||||
GST_VAAPI_PARAM_ENCODER_EXPOSURE);
|
||||
|
||||
properties[ENCODER_VP9_PROP_SHARPNESS_LEVEL] =
|
||||
g_param_spec_uint ("sharpness-level",
|
||||
"Sharpness Level",
|
||||
"Controls the deblocking filter sensitivity",
|
||||
0, 7, DEFAULT_SHARPNESS_LEVEL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
|
||||
GST_VAAPI_PARAM_ENCODER_EXPOSURE);
|
||||
|
||||
properties[ENCODER_VP9_PROP_YAC_Q_INDEX] =
|
||||
g_param_spec_uint ("yac-qi",
|
||||
"Luma AC Quant Table index",
|
||||
"Quantization Table index for Luma AC Coefficients",
|
||||
0, 255, DEFAULT_YAC_QINDEX,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
|
||||
GST_VAAPI_PARAM_ENCODER_EXPOSURE);
|
||||
|
||||
properties[ENCODER_VP9_PROP_REF_PIC_MODE] =
|
||||
g_param_spec_enum ("ref-pic-mode",
|
||||
"RefPic Selection",
|
||||
"Reference Picture Selection Modes",
|
||||
gst_vaapi_encoder_vp9_ref_pic_mode_type (),
|
||||
GST_VAAPI_ENCODER_VP9_REF_PIC_MODE_0,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
|
||||
GST_VAAPI_PARAM_ENCODER_EXPOSURE);
|
||||
|
||||
/**
|
||||
* GstVaapiEncoderVP9:cpb-length:
|
||||
*
|
||||
* The size of the Coded Picture Buffer , which means
|
||||
* the window size in milliseconds.
|
||||
*
|
||||
*/
|
||||
properties[ENCODER_VP9_PROP_CPB_LENGTH] =
|
||||
g_param_spec_uint ("cpb-length",
|
||||
"CPB Length", "Length of the CPB_buffer/window_size in milliseconds",
|
||||
1, 10000, DEFAULT_CPB_LENGTH,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
|
||||
GST_VAAPI_PARAM_ENCODER_EXPOSURE);
|
||||
|
||||
g_object_class_install_properties (object_class, ENCODER_VP9_N_PROPERTIES,
|
||||
properties);
|
||||
|
||||
gst_type_mark_as_plugin_api (g_class_data.rate_control_get_type (), 0);
|
||||
gst_type_mark_as_plugin_api (g_class_data.encoder_tune_get_type (), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_encoder_vp9_new:
|
||||
* @display: a #GstVaapiDisplay
|
||||
*
|
||||
* Creates a new #GstVaapiEncoder for VP9 encoding.
|
||||
*
|
||||
* Return value: the newly allocated #GstVaapiEncoder object
|
||||
*/
|
||||
GstVaapiEncoder *
|
||||
gst_vaapi_encoder_vp9_new (GstVaapiDisplay * display)
|
||||
{
|
||||
return g_object_new (GST_TYPE_VAAPI_ENCODER_VP9, "display", display, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_encoder_vp9_set_allowed_profiles:
|
||||
* @encoder: a #GstVaapiEncoderVP9
|
||||
* @profiles: a #GArray of all allowed #GstVaapiProfile.
|
||||
*
|
||||
* Set the all allowed profiles for the encoder.
|
||||
*
|
||||
* Return value: %TRUE on success
|
||||
*/
|
||||
gboolean
|
||||
gst_vaapi_encoder_vp9_set_allowed_profiles (GstVaapiEncoderVP9 * encoder,
|
||||
GArray * profiles)
|
||||
{
|
||||
g_return_val_if_fail (profiles != 0, FALSE);
|
||||
|
||||
encoder->allowed_profiles = g_array_ref (profiles);
|
||||
return TRUE;
|
||||
}
|
53
gst-libs/gst/vaapi/gstvaapiencoder_vp9.h
Normal file
53
gst-libs/gst/vaapi/gstvaapiencoder_vp9.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* gstvaapiencoder_vp9.h VP9 encoder
|
||||
*
|
||||
* Copyright (C) 2016 Intel Corporation
|
||||
* Author: Sreerenj Balachandran <sreerenj.balachandran@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_ENCODER_VP9_H
|
||||
#define GST_VAAPI_ENCODER_VP9_H
|
||||
|
||||
#include <gst/vaapi/gstvaapiencoder.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_ENCODER_VP9 \
|
||||
(gst_vaapi_encoder_vp9_get_type ())
|
||||
#define GST_VAAPI_ENCODER_VP9(encoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((encoder), GST_TYPE_VAAPI_ENCODER_VP9, GstVaapiEncoderVP9))
|
||||
#define GST_IS_VAAPI_ENCODER_VP9(encoder) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((encoder), GST_TYPE_VAAPI_ENCODER_VP9))
|
||||
|
||||
typedef struct _GstVaapiEncoderVP9 GstVaapiEncoderVP9;
|
||||
typedef struct _GstVaapiEncoderVP9Class GstVaapiEncoderVP9Class;
|
||||
|
||||
GType
|
||||
gst_vaapi_encoder_vp9_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GstVaapiEncoder *
|
||||
gst_vaapi_encoder_vp9_new (GstVaapiDisplay * display);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_encoder_vp9_set_allowed_profiles (GstVaapiEncoderVP9 * encoder,
|
||||
GArray * profiles);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiEncoderVP9, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
#endif /*GST_VAAPI_ENCODER_VP9_H */
|
2527
gst-libs/gst/vaapi/gstvaapifilter.c
Normal file
2527
gst-libs/gst/vaapi/gstvaapifilter.c
Normal file
File diff suppressed because it is too large
Load diff
325
gst-libs/gst/vaapi/gstvaapifilter.h
Normal file
325
gst-libs/gst/vaapi/gstvaapifilter.h
Normal file
|
@ -0,0 +1,325 @@
|
|||
/*
|
||||
* gstvaapifilter.h - Video processing abstraction
|
||||
*
|
||||
* Copyright (C) 2013 Intel Corporation
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.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; 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
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_FILTER_H
|
||||
#define GST_VAAPI_FILTER_H
|
||||
|
||||
#include <gst/vaapi/gstvaapisurface.h>
|
||||
#include <gst/vaapi/video-format.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VAAPI_FILTER \
|
||||
(gst_vaapi_filter_get_type ())
|
||||
#define GST_VAAPI_FILTER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_FILTER, GstVaapiFilter))
|
||||
#define GST_VAAPI_IS_FILTER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_FILTER))
|
||||
|
||||
typedef struct _GstVaapiFilter GstVaapiFilter;
|
||||
typedef struct _GstVaapiFilterOpInfo GstVaapiFilterOpInfo;
|
||||
|
||||
/**
|
||||
* @GST_VAAPI_FILTER_OP_FORMAT: Force output pixel format (#GstVideoFormat).
|
||||
* @GST_VAAPI_FILTER_OP_CROP: Crop source surface (#GstVaapiRectangle).
|
||||
* @GST_VAAPI_FILTER_OP_DENOISE: Noise reduction (float).
|
||||
* @GST_VAAPI_FILTER_OP_SHARPEN: Sharpening (float).
|
||||
* @GST_VAAPI_FILTER_OP_HUE: Change color hue (float).
|
||||
* @GST_VAAPI_FILTER_OP_SATURATION: Change saturation (float).
|
||||
* @GST_VAAPI_FILTER_OP_BRIGHTNESS: Change brightness (float).
|
||||
* @GST_VAAPI_FILTER_OP_CONTRAST: Change contrast (float).
|
||||
* @GST_VAAPI_FILTER_OP_SCALING: Change scaling method (#GstVaapiScaleMethod).
|
||||
* @GST_VAAPI_FILTER_OP_VIDEO_DIRECTION: Change video direction
|
||||
* (#GstVideoOrientationMethod).
|
||||
* @GST_VAAPI_FILTER_OP_HDR_TONE_MAP: HDR tone mapping (bool).
|
||||
* @GST_VAAPI_FILTER_OP_SKINTONE: Skin tone enhancement (bool).
|
||||
* @GST_VAAPI_FILTER_OP_SKINTONE_LEVEL: Skin tone enhancement (uint).
|
||||
*
|
||||
* The set of operations that could be applied to the filter.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VAAPI_FILTER_OP_FORMAT = 1,
|
||||
GST_VAAPI_FILTER_OP_CROP,
|
||||
GST_VAAPI_FILTER_OP_DENOISE,
|
||||
GST_VAAPI_FILTER_OP_SHARPEN,
|
||||
GST_VAAPI_FILTER_OP_HUE,
|
||||
GST_VAAPI_FILTER_OP_SATURATION,
|
||||
GST_VAAPI_FILTER_OP_BRIGHTNESS,
|
||||
GST_VAAPI_FILTER_OP_CONTRAST,
|
||||
GST_VAAPI_FILTER_OP_DEINTERLACING,
|
||||
GST_VAAPI_FILTER_OP_SCALING,
|
||||
GST_VAAPI_FILTER_OP_VIDEO_DIRECTION,
|
||||
GST_VAAPI_FILTER_OP_HDR_TONE_MAP,
|
||||
#ifndef GST_REMOVE_DEPRECATED
|
||||
GST_VAAPI_FILTER_OP_SKINTONE,
|
||||
#endif
|
||||
GST_VAAPI_FILTER_OP_SKINTONE_LEVEL,
|
||||
} GstVaapiFilterOp;
|
||||
|
||||
/**
|
||||
* GstVaapiFilterOpInfo:
|
||||
* @operation: the #GstVaapiFilterOp
|
||||
* @pspec: the #GParamSpec describing the associated configurable value
|
||||
*
|
||||
* A #GstVaapiFilterOp descriptor.
|
||||
*/
|
||||
struct _GstVaapiFilterOpInfo
|
||||
{
|
||||
const GstVaapiFilterOp op;
|
||||
GParamSpec *const pspec;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiFilterStatus:
|
||||
* @GST_VAAPI_FILTER_STATUS_SUCCESS: Success.
|
||||
* @GST_VAAPI_FILTER_STATUS_ERROR_ALLOCATION_FAILED: No memory left.
|
||||
* @GST_VAAPI_FILTER_STATUS_ERROR_OPERATION_FAILED: Operation failed.
|
||||
* @GST_VAAPI_FILTER_STATUS_ERROR_INVALID_PARAMETER: Invalid parameter.
|
||||
* @GST_VAAPI_FILTER_STATUS_ERROR_UNSUPPORTED_OPERATION: Unsupported operation.
|
||||
* @GST_VAAPI_FILTER_STATUS_ERROR_UNSUPPORTED_FORMAT: Unsupported target format.
|
||||
*
|
||||
* Video processing status for gst_vaapi_filter_process().
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VAAPI_FILTER_STATUS_SUCCESS = 0,
|
||||
GST_VAAPI_FILTER_STATUS_ERROR_ALLOCATION_FAILED,
|
||||
GST_VAAPI_FILTER_STATUS_ERROR_OPERATION_FAILED,
|
||||
GST_VAAPI_FILTER_STATUS_ERROR_INVALID_PARAMETER,
|
||||
GST_VAAPI_FILTER_STATUS_ERROR_UNSUPPORTED_OPERATION,
|
||||
GST_VAAPI_FILTER_STATUS_ERROR_UNSUPPORTED_FORMAT,
|
||||
} GstVaapiFilterStatus;
|
||||
|
||||
/**
|
||||
* GstVaapiScaleMethod:
|
||||
* @GST_VAAPI_SCALE_METHOD_DEFAULT: Default scaling mode.
|
||||
* @GST_VAAPI_SCALE_METHOD_FAST: Fast scaling mode, at the expense of quality.
|
||||
* @GST_VAAPI_SCALE_METHOD_HQ: High quality scaling mode, at the
|
||||
* expense of speed.
|
||||
*
|
||||
* Scaling algorithms.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VAAPI_SCALE_METHOD_DEFAULT,
|
||||
GST_VAAPI_SCALE_METHOD_FAST,
|
||||
GST_VAAPI_SCALE_METHOD_HQ,
|
||||
} GstVaapiScaleMethod;
|
||||
|
||||
/**
|
||||
* GstVaapiDeinterlaceMethod:
|
||||
* @GST_VAAPI_DEINTERLACE_METHOD_NONE: No deinterlacing.
|
||||
* @GST_VAAPI_DEINTERLACE_METHOD_BOB: Basic bob deinterlacing algorithm.
|
||||
* @GST_VAAPI_DEINTERLACE_METHOD_WEAVE: Weave deinterlacing algorithm.
|
||||
* @GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE: Motion adaptive
|
||||
* deinterlacing algorithm.
|
||||
* @GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED: Motion compensated
|
||||
* deinterlacing algorithm.
|
||||
*
|
||||
* Deinterlacing algorithms.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VAAPI_DEINTERLACE_METHOD_NONE,
|
||||
GST_VAAPI_DEINTERLACE_METHOD_BOB,
|
||||
GST_VAAPI_DEINTERLACE_METHOD_WEAVE,
|
||||
GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE,
|
||||
GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED,
|
||||
} GstVaapiDeinterlaceMethod;
|
||||
|
||||
/**
|
||||
* GstVaapiDeinterlaceFlags:
|
||||
* @GST_VAAPI_DEINTERLACE_FLAG_TFF: Top-field first. If this flag is
|
||||
* not set, then bottom-field first order is assumed. Note: this
|
||||
* only affects the way reference frames are organized for advanced
|
||||
* deinterlacing modes.
|
||||
* @GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD: The input frame represents a
|
||||
* single field. If this flag is not set, then the whole frame holds
|
||||
* two interleaved fields.
|
||||
* @GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD: The top field of the input
|
||||
* frame is to be used for deinterlacing. Otherwise, if this flag is
|
||||
* not set, then the bottom field of the input frame will be used
|
||||
* for deinterlacing.
|
||||
*
|
||||
* The set of gst_vaapi_filter_set_deinterlacing() flags.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VAAPI_DEINTERLACE_FLAG_TFF = 1 << 31,
|
||||
GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD = 1 << 30,
|
||||
GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD = 1 << 29,
|
||||
} GstVaapiDeinterlaceFlags;
|
||||
|
||||
#define GST_VAAPI_TYPE_SCALE_METHOD \
|
||||
gst_vaapi_scale_method_get_type()
|
||||
|
||||
#define GST_VAAPI_TYPE_DEINTERLACE_METHOD \
|
||||
gst_vaapi_deinterlace_method_get_type()
|
||||
|
||||
#define GST_VAAPI_TYPE_DEINTERLACE_FLAGS \
|
||||
gst_vaapi_deinterlace_flags_get_type()
|
||||
|
||||
GType
|
||||
gst_vaapiscale_method_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GType
|
||||
gst_vaapi_deinterlace_method_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GType
|
||||
gst_vaapi_deinterlace_flags_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GType
|
||||
gst_vaapi_filter_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GstVaapiFilter *
|
||||
gst_vaapi_filter_new (GstVaapiDisplay * display);
|
||||
|
||||
void
|
||||
gst_vaapi_filter_replace (GstVaapiFilter ** old_filter_ptr,
|
||||
GstVaapiFilter * new_filter);
|
||||
|
||||
GPtrArray *
|
||||
gst_vaapi_filter_get_operations (GstVaapiFilter * filter);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_has_operation (GstVaapiFilter * filter, GstVaapiFilterOp op);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_use_operation (GstVaapiFilter * filter, GstVaapiFilterOp op);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op,
|
||||
const GValue * value);
|
||||
|
||||
GstVaapiFilterStatus
|
||||
gst_vaapi_filter_process (GstVaapiFilter * filter,
|
||||
GstVaapiSurface * src_surface, GstVaapiSurface * dst_surface, guint flags);
|
||||
|
||||
GArray *
|
||||
gst_vaapi_filter_get_formats (GstVaapiFilter * filter);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_format (GstVaapiFilter * filter, GstVideoFormat format);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_append_caps (GstVaapiFilter * filter, GstStructure * structure);
|
||||
|
||||
guint
|
||||
gst_vaapi_filter_get_memory_types (GstVaapiFilter * filter);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_cropping_rectangle (GstVaapiFilter * filter,
|
||||
const GstVaapiRectangle * rect);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_target_rectangle (GstVaapiFilter * filter,
|
||||
const GstVaapiRectangle * rect);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_denoising_level (GstVaapiFilter * filter, gfloat level);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_sharpening_level (GstVaapiFilter * filter, gfloat level);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_hue (GstVaapiFilter * filter, gfloat value);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_saturation (GstVaapiFilter * filter, gfloat value);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_brightness (GstVaapiFilter * filter, gfloat value);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_contrast (GstVaapiFilter * filter, gfloat value);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_deinterlacing (GstVaapiFilter * filter,
|
||||
GstVaapiDeinterlaceMethod method, guint flags);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_deinterlacing_references (GstVaapiFilter * filter,
|
||||
GstVaapiSurface ** forward_references, guint num_forward_references,
|
||||
GstVaapiSurface ** backward_references, guint num_backward_references);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_scaling (GstVaapiFilter * filter,
|
||||
GstVaapiScaleMethod method);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_video_direction (GstVaapiFilter * filter,
|
||||
GstVideoOrientationMethod method);
|
||||
|
||||
GstVideoOrientationMethod
|
||||
gst_vaapi_filter_get_video_direction (GstVaapiFilter * filter);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_hdr_tone_map (GstVaapiFilter * filter, gboolean value);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_hdr_tone_map_meta (GstVaapiFilter * filter,
|
||||
GstVideoMasteringDisplayInfo * minfo, GstVideoContentLightLevel * linfo);
|
||||
|
||||
#ifndef GST_REMOVE_DEPRECATED
|
||||
gboolean
|
||||
gst_vaapi_filter_set_skintone (GstVaapiFilter * filter,
|
||||
gboolean enhance);
|
||||
#endif
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_skintone_level (GstVaapiFilter * filter, guint value);
|
||||
|
||||
gfloat
|
||||
gst_vaapi_filter_get_denoising_level_default (GstVaapiFilter * filter);
|
||||
|
||||
gfloat
|
||||
gst_vaapi_filter_get_sharpening_level_default (GstVaapiFilter * filter);
|
||||
|
||||
gfloat
|
||||
gst_vaapi_filter_get_hue_default (GstVaapiFilter * filter);
|
||||
|
||||
gfloat
|
||||
gst_vaapi_filter_get_saturation_default (GstVaapiFilter * filter);
|
||||
|
||||
gfloat
|
||||
gst_vaapi_filter_get_brightness_default (GstVaapiFilter * filter);
|
||||
|
||||
gfloat
|
||||
gst_vaapi_filter_get_contrast_default (GstVaapiFilter * filter);
|
||||
|
||||
GstVaapiScaleMethod
|
||||
gst_vaapi_filter_get_scaling_default (GstVaapiFilter * filter);
|
||||
|
||||
GstVideoOrientationMethod
|
||||
gst_vaapi_filter_get_video_direction_default (GstVaapiFilter * filter);
|
||||
|
||||
#ifndef GST_REMOVE_DEPRECATED
|
||||
gboolean
|
||||
gst_vaapi_filter_get_skintone_default (GstVaapiFilter * filter);
|
||||
#endif
|
||||
|
||||
guint
|
||||
gst_vaapi_filter_get_skintone_level_default (GstVaapiFilter * filter);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_colorimetry (GstVaapiFilter * filter,
|
||||
GstVideoColorimetry * input, GstVideoColorimetry * output);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiFilter, gst_object_unref)
|
||||
|
||||
#endif /* GST_VAAPI_FILTER_H */
|
1072
gst-libs/gst/vaapi/gstvaapiimage.c
Normal file
1072
gst-libs/gst/vaapi/gstvaapiimage.c
Normal file
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue